diff options
Diffstat (limited to 'boost/process/detail/windows/async_pipe.hpp')
-rw-r--r-- | boost/process/detail/windows/async_pipe.hpp | 105 |
1 files changed, 77 insertions, 28 deletions
diff --git a/boost/process/detail/windows/async_pipe.hpp b/boost/process/detail/windows/async_pipe.hpp index f06653962a..06d5f2d854 100644 --- a/boost/process/detail/windows/async_pipe.hpp +++ b/boost/process/detail/windows/async_pipe.hpp @@ -40,23 +40,30 @@ class async_pipe { ::boost::asio::windows::stream_handle _source; ::boost::asio::windows::stream_handle _sink ; + + inline async_pipe(boost::asio::io_context & ios_source, + boost::asio::io_context & ios_sink, + const std::string & name, bool private_); + public: typedef ::boost::winapi::HANDLE_ native_handle_type; typedef ::boost::asio::windows::stream_handle handle_type; - inline async_pipe(boost::asio::io_context & ios, - const std::string & name = make_pipe_name()) - : async_pipe(ios, ios, name) {} + async_pipe(boost::asio::io_context & ios) : async_pipe(ios, ios, make_pipe_name(), true) {} + async_pipe(boost::asio::io_context & ios_source, boost::asio::io_context & ios_sink) + : async_pipe(ios_source, ios_sink, make_pipe_name(), true) {} + + async_pipe(boost::asio::io_context & ios, const std::string & name) + : async_pipe(ios, ios, name, false) {} + + async_pipe(boost::asio::io_context & ios_source, boost::asio::io_context & ios_sink, const std::string & name) + : async_pipe(ios_source, ios_sink, name, false) {} + - inline async_pipe(boost::asio::io_context & ios_source, - boost::asio::io_context & ios_sink, - const std::string & name = make_pipe_name()); inline async_pipe(const async_pipe& rhs); async_pipe(async_pipe&& rhs) : _source(std::move(rhs._source)), _sink(std::move(rhs._sink)) { - rhs._source.assign (::boost::winapi::INVALID_HANDLE_VALUE_); - rhs._sink .assign (::boost::winapi::INVALID_HANDLE_VALUE_); } template<class CharT, class Traits = std::char_traits<CharT>> explicit async_pipe(::boost::asio::io_context & ios_source, @@ -191,13 +198,15 @@ public: handle_type source(::boost::asio::io_context& ios) && { ::boost::asio::windows::stream_handle stolen(ios.get_executor(), _source.native_handle()); - _source.assign(::boost::winapi::INVALID_HANDLE_VALUE_); + boost::system::error_code ec; + _source.assign(::boost::winapi::INVALID_HANDLE_VALUE_, ec); return stolen; } handle_type sink (::boost::asio::io_context& ios) && { ::boost::asio::windows::stream_handle stolen(ios.get_executor(), _sink.native_handle()); - _sink.assign(::boost::winapi::INVALID_HANDLE_VALUE_); + boost::system::error_code ec; + _sink.assign(::boost::winapi::INVALID_HANDLE_VALUE_, ec); return stolen; } @@ -235,12 +244,11 @@ public: } }; - - async_pipe::async_pipe(const async_pipe& p) : _source(const_cast<handle_type&>(p._source).get_executor()), _sink (const_cast<handle_type&>(p._sink).get_executor()) { + auto proc = ::boost::winapi::GetCurrentProcess(); ::boost::winapi::HANDLE_ source; @@ -266,14 +274,16 @@ async_pipe::async_pipe(const async_pipe& p) : ::boost::winapi::DUPLICATE_SAME_ACCESS_)) throw_last_error("Duplicate Pipe Failed"); - _source.assign(source); - _sink. assign(sink); + if (source != ::boost::winapi::INVALID_HANDLE_VALUE_) + _source.assign(source); + if (sink != ::boost::winapi::INVALID_HANDLE_VALUE_) + _sink. assign(sink); } async_pipe::async_pipe(boost::asio::io_context & ios_source, boost::asio::io_context & ios_sink, - const std::string & name) : _source(ios_source), _sink(ios_sink) + const std::string & name, bool private_) : _source(ios_source), _sink(ios_sink) { static constexpr int FILE_FLAG_OVERLAPPED_ = 0x40000000; //temporary @@ -285,7 +295,7 @@ async_pipe::async_pipe(boost::asio::io_context & ios_source, #endif ::boost::winapi::PIPE_ACCESS_INBOUND_ | FILE_FLAG_OVERLAPPED_, //write flag - 0, 1, 8192, 8192, 0, nullptr); + 0, private_ ? 1 : ::boost::winapi::PIPE_UNLIMITED_INSTANCES_, 8192, 8192, 0, nullptr); if (source == boost::winapi::INVALID_HANDLE_VALUE_) @@ -310,6 +320,44 @@ async_pipe::async_pipe(boost::asio::io_context & ios_source, _sink.assign(sink); } +template<class CharT, class Traits> +async_pipe& async_pipe::operator=(const basic_pipe<CharT, Traits> & p) +{ + auto proc = ::boost::winapi::GetCurrentProcess(); + + ::boost::winapi::HANDLE_ source; + ::boost::winapi::HANDLE_ sink; + + //cannot get the handle from a const object. + auto source_in = p.native_source(); + auto sink_in = p.native_sink(); + + if (source_in == ::boost::winapi::INVALID_HANDLE_VALUE_) + source = ::boost::winapi::INVALID_HANDLE_VALUE_; + else if (!::boost::winapi::DuplicateHandle( + proc, source_in.native_handle(), proc, &source, 0, + static_cast<::boost::winapi::BOOL_>(true), + ::boost::winapi::DUPLICATE_SAME_ACCESS_)) + throw_last_error("Duplicate Pipe Failed"); + + if (sink_in == ::boost::winapi::INVALID_HANDLE_VALUE_) + sink = ::boost::winapi::INVALID_HANDLE_VALUE_; + else if (!::boost::winapi::DuplicateHandle( + proc, sink_in.native_handle(), proc, &sink, 0, + static_cast<::boost::winapi::BOOL_>(true), + ::boost::winapi::DUPLICATE_SAME_ACCESS_)) + throw_last_error("Duplicate Pipe Failed"); + + //so we also assign the io_context + if (source != ::boost::winapi::INVALID_HANDLE_VALUE_) + _source.assign(source); + + if (sink != ::boost::winapi::INVALID_HANDLE_VALUE_) + _sink.assign(sink); + + return *this; +} + async_pipe& async_pipe::operator=(const async_pipe & p) { auto proc = ::boost::winapi::GetCurrentProcess(); @@ -321,6 +369,8 @@ async_pipe& async_pipe::operator=(const async_pipe & p) auto &source_in = const_cast<::boost::asio::windows::stream_handle &>(p._source); auto &sink_in = const_cast<::boost::asio::windows::stream_handle &>(p._sink); + source_in.get_executor(); + if (source_in.native_handle() == ::boost::winapi::INVALID_HANDLE_VALUE_) source = ::boost::winapi::INVALID_HANDLE_VALUE_; else if (!::boost::winapi::DuplicateHandle( @@ -338,24 +388,23 @@ async_pipe& async_pipe::operator=(const async_pipe & p) throw_last_error("Duplicate Pipe Failed"); //so we also assign the io_context - _source = ::boost::asio::windows::stream_handle(source_in.get_executor(), source); - _sink = ::boost::asio::windows::stream_handle(source_in.get_executor(), sink); + if (source != ::boost::winapi::INVALID_HANDLE_VALUE_) + _source = ::boost::asio::windows::stream_handle(source_in.get_executor(), source); + else + _source = ::boost::asio::windows::stream_handle(source_in.get_executor()); + + if (sink != ::boost::winapi::INVALID_HANDLE_VALUE_) + _sink = ::boost::asio::windows::stream_handle(source_in.get_executor(), sink); + else + _sink = ::boost::asio::windows::stream_handle(source_in.get_executor()); return *this; } async_pipe& async_pipe::operator=(async_pipe && rhs) { - if (_source.native_handle() != ::boost::winapi::INVALID_HANDLE_VALUE_) - ::boost::winapi::CloseHandle(_source.native_handle()); - - if (_sink.native_handle() != ::boost::winapi::INVALID_HANDLE_VALUE_) - ::boost::winapi::CloseHandle(_sink.native_handle()); - - _source.assign(rhs._source.native_handle()); - _sink .assign(rhs._sink .native_handle()); - rhs._source.assign(::boost::winapi::INVALID_HANDLE_VALUE_); - rhs._sink .assign(::boost::winapi::INVALID_HANDLE_VALUE_); + _source = std::move(rhs._source); + _sink = std::move(rhs._sink); return *this; } |