138 lines
4.9 KiB
C++
138 lines
4.9 KiB
C++
//
|
|
// Created by sozonov on 18.10.2021.
|
|
//
|
|
|
|
#include "CreatePipes.h"
|
|
|
|
#include <iostream>
|
|
#include <memory>
|
|
|
|
#include "boost/process/pipe.hpp"
|
|
|
|
|
|
/*! Создание в операционной системе именнованого канала, заданого имени и заданого направления.<br>
|
|
* Обеспечена кросплатформенность данной функции (Windows/Linux).
|
|
* @param path Назавние именновоного канала.
|
|
* @param mode Направление работы именнованного канала: <br> 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
|
|
};
|