// // Created by sozonov on 18.10.2021. // #include "CreatePipes.h" #include #include #include "boost/process/pipe.hpp" /*! Создание в операционной системе именнованого канала, заданого имени и заданого направления.
* Обеспечена кросплатформенность данной функции (Windows/Linux). * @param path Назавние именновоного канала. * @param mode Направление работы именнованного канала:
std::ios_base::in / std::ios_base::out * @return Именнованый канал, привязаный к библиотеке boost. */ boost::process::pipe build_named_io_pipe( std::filesystem::path path, std::ios_base::openmode mode ); std::tuple< std::unique_ptr< std::istream >, std::unique_ptr< std::ostream > > itr::create_pipes( std::filesystem::path input_path, std::filesystem::path output_path, std::ostream & info ) { //todo: перед созданием пайпов проверять валидность пути и выводить инфу в поток &info info << "Create pipes: " << input_path << ", " << output_path << "..." << std::endl; auto ostream = std::make_unique<::boost::process::opstream>( std::move( build_named_io_pipe( output_path, std::ios_base::out ) ) ); auto istream = std::make_unique<::boost::process::ipstream>( std::move( build_named_io_pipe( input_path, std::ios_base::in ) ) ); #if (defined (_WIN32) || defined (_WIN64)) ::boost::winapi::ConnectNamedPipe( istream->pipe().native_source(), nullptr ); ::boost::winapi::ConnectNamedPipe( ostream->pipe().native_sink(), nullptr ); #endif info << "Pipes " << input_path << " and " << output_path << " are connected!" << std::endl; return { std::move(istream), std::move(ostream) }; }; boost::process::pipe build_named_io_pipe( std::filesystem::path path, std::ios_base::openmode mode ) { #if (defined (_WIN32) || defined (_WIN64)) if( mode == std::ios_base::in ) { boost::winapi::HANDLE_ input_source = boost::winapi::create_named_pipe( path.string().c_str(), boost::winapi::PIPE_ACCESS_INBOUND_, //write flag boost::winapi::PIPE_TYPE_BYTE_ | boost::winapi::PIPE_READMODE_BYTE_ | boost::winapi::PIPE_WAIT_ , 4, 8192, 8192, 0, nullptr ); return boost::process::pipe( input_source, boost::winapi::INVALID_HANDLE_VALUE_ ); } if( mode == std::ios_base::out ) { boost::winapi::HANDLE_ output_source = boost::winapi::create_named_pipe( path.string().c_str(), boost::winapi::PIPE_ACCESS_OUTBOUND_, //write flag boost::winapi::PIPE_TYPE_BYTE_ | ::boost::winapi::PIPE_READMODE_BYTE_ | boost::winapi::PIPE_WAIT_, 4, 8192, 8192, 0, nullptr); return boost::process::pipe( boost::winapi::INVALID_HANDLE_VALUE_ , output_source); } return boost::process::pipe( boost::winapi::INVALID_HANDLE_VALUE_ ,boost::winapi::INVALID_HANDLE_VALUE_ ); #elif (defined (LINUX) || defined (__linux__)) if( mode == std::ios_base::in ) { if( not std::filesystem::exists(path) ) { auto fifo = mkfifo(path.c_str(), 0666 ); if (fifo != 0) boost::process::detail::throw_last_error("mkfifo() failed"); std::cout << "Input fifo created: " << path << std::endl; } else { std::cout << "Input fifo exists: " << path << std::endl; } int read_fd = open(path.c_str(), O_RDONLY ); if( read_fd == -1 ) boost::process::detail::throw_last_error(); return boost::process::pipe( read_fd, -1 ); } if( mode == std::ios_base::out ) { if( not std::filesystem::exists(path) ) { auto fifo = mkfifo(path.c_str(), 0666 ); if (fifo != 0) boost::process::detail::throw_last_error("mkfifo() failed"); std::cout << "Output fifo created: " << path << std::endl; } else { std::cout << "Output fifo exists: " << path << std::endl; } int write_fd = open(path.c_str(), O_WRONLY ); if (write_fd == -1) boost::process::detail::throw_last_error(); return boost::process::pipe( -1, write_fd ); } return boost::process::pipe( -1, -1 ); #endif };