summaryrefslogtreecommitdiff
path: root/boost/process/detail/windows/async_pipe.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/process/detail/windows/async_pipe.hpp')
-rw-r--r--boost/process/detail/windows/async_pipe.hpp105
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;
}