ProfinetConnector/profinet_test/sample_app_echo/CreatePipes.cpp

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
};