File indexing completed on 2025-01-18 09:50:07
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_PROCESS_WINDOWS_INITIALIZERS_ASYNC_IN_HPP
0011 #define BOOST_PROCESS_WINDOWS_INITIALIZERS_ASYNC_IN_HPP
0012
0013 #include <boost/winapi/process.hpp>
0014 #include <boost/winapi/handles.hpp>
0015 #include <boost/winapi/handle_info.hpp>
0016 #include <boost/winapi/error_codes.hpp>
0017
0018 #include <boost/asio/write.hpp>
0019 #include <boost/process/detail/handler_base.hpp>
0020 #include <boost/process/detail/used_handles.hpp>
0021 #include <boost/process/detail/windows/async_handler.hpp>
0022 #include <boost/process/detail/windows/asio_fwd.hpp>
0023 #include <boost/process/async_pipe.hpp>
0024 #include <memory>
0025 #include <future>
0026
0027 namespace boost { namespace process { namespace detail { namespace windows {
0028
0029
0030 template<typename Buffer>
0031 struct async_in_buffer : ::boost::process::detail::windows::handler_base_ext,
0032 ::boost::process::detail::windows::require_io_context,
0033 ::boost::process::detail::uses_handles
0034 {
0035 Buffer & buf;
0036
0037 std::shared_ptr<std::promise<void>> promise;
0038 async_in_buffer operator>(std::future<void> & fut)
0039 {
0040 promise = std::make_shared<std::promise<void>>();
0041 fut = promise->get_future(); return std::move(*this);
0042 }
0043
0044 std::shared_ptr<boost::process::async_pipe> pipe;
0045
0046 ::boost::winapi::HANDLE_ get_used_handles() const
0047 {
0048 return std::move(*pipe).source().native_handle();
0049 }
0050
0051 async_in_buffer(Buffer & buf) : buf(buf)
0052 {
0053 }
0054 template <typename Executor>
0055 inline void on_success(Executor&)
0056 {
0057 auto pipe_ = this->pipe;
0058
0059 if (this->promise)
0060 {
0061 auto promise_ = this->promise;
0062
0063 boost::asio::async_write(*pipe_, buf,
0064 [promise_](const boost::system::error_code & ec, std::size_t)
0065 {
0066 if (ec && (ec.value() != ::boost::winapi::ERROR_BROKEN_PIPE_))
0067 {
0068 std::error_code e(ec.value(), std::system_category());
0069 promise_->set_exception(std::make_exception_ptr(process_error(e)));
0070 }
0071 promise_->set_value();
0072 });
0073 }
0074 else
0075 boost::asio::async_write(*pipe_, buf,
0076 [pipe_](const boost::system::error_code&, std::size_t){});
0077
0078 std::move(*pipe_).source().close();
0079
0080
0081 this->pipe = nullptr;
0082 }
0083
0084 template<typename Executor>
0085 void on_error(Executor &, const std::error_code &) const
0086 {
0087 ::boost::winapi::CloseHandle(pipe->native_source());
0088 }
0089
0090 template <typename WindowsExecutor>
0091 void on_setup(WindowsExecutor &exec)
0092 {
0093 if (!pipe)
0094 pipe = std::make_shared<boost::process::async_pipe>(get_io_context(exec.seq));
0095
0096 ::boost::winapi::HANDLE_ source_handle = std::move(*pipe).source().native_handle();
0097
0098 boost::winapi::SetHandleInformation(source_handle,
0099 boost::winapi::HANDLE_FLAG_INHERIT_,
0100 boost::winapi::HANDLE_FLAG_INHERIT_);
0101
0102 exec.startup_info.hStdInput = source_handle;
0103 exec.startup_info.dwFlags |= boost::winapi::STARTF_USESTDHANDLES_;
0104 exec.inherit_handles = true;
0105 }
0106 };
0107
0108
0109 }}}}
0110
0111 #endif