Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:50:05

0001 // Copyright (c) 2006, 2007 Julio M. Merino Vidal
0002 // Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
0003 // Copyright (c) 2009 Boris Schaeling
0004 // Copyright (c) 2010 Felipe Tanus, Boris Schaeling
0005 // Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling
0006 //
0007 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0009 
0010 #ifndef BOOST_PROCESS_DETAIL_POSIX_ASYNC_IN_HPP
0011 #define BOOST_PROCESS_DETAIL_POSIX_ASYNC_IN_HPP
0012 
0013 #include <boost/process/detail/handler_base.hpp>
0014 #include <boost/process/detail/posix/async_handler.hpp>
0015 #include <boost/asio/write.hpp>
0016 #include <boost/process/async_pipe.hpp>
0017 #include <memory>
0018 #include <future>
0019 #include <boost/process/detail/used_handles.hpp>
0020 #include <array>
0021 
0022 namespace boost { namespace process { namespace detail { namespace posix {
0023 
0024 
0025 template<typename Buffer>
0026 struct async_in_buffer : ::boost::process::detail::posix::handler_base_ext,
0027                          ::boost::process::detail::posix::require_io_context,
0028                          ::boost::process::detail::uses_handles
0029 {
0030     Buffer & buf;
0031 
0032     std::shared_ptr<std::promise<void>> promise;
0033     async_in_buffer operator>(std::future<void> & fut)
0034     {
0035         promise = std::make_shared<std::promise<void>>();
0036         fut = promise->get_future(); return std::move(*this);
0037     }
0038 
0039 
0040     std::shared_ptr<boost::process::async_pipe> pipe;
0041 
0042     async_in_buffer(Buffer & buf) : buf(buf)
0043     {
0044     }
0045     template <typename Executor>
0046     inline void on_success(Executor)
0047     {
0048         auto  pipe_              = this->pipe;
0049         if (this->promise)
0050         {
0051             auto promise_ = this->promise;
0052 
0053             boost::asio::async_write(*pipe_, buf,
0054                 [pipe_, promise_](const boost::system::error_code & ec, std::size_t)
0055                 {
0056                     if (ec && (ec.value() != EBADF) && (ec.value() != EPERM) && (ec.value() != ENOENT))
0057                     {
0058                         std::error_code e(ec.value(), std::system_category());
0059                         promise_->set_exception(std::make_exception_ptr(process_error(e)));
0060                     }
0061                     else
0062                         promise_->set_value();
0063                 });
0064         }
0065         else
0066             boost::asio::async_write(*pipe_, buf,
0067                 [pipe_](const boost::system::error_code&, std::size_t){});
0068 
0069         std::move(*pipe_).source().close();
0070 
0071         this->pipe = nullptr;
0072     }
0073 
0074     template<typename Executor>
0075     void on_error(Executor &, const std::error_code &) const
0076     {
0077         std::move(*pipe).source().close();
0078     }
0079 
0080     template<typename Executor>
0081     void on_setup(Executor & exec)
0082     {
0083         if (!pipe)
0084             pipe = std::make_shared<boost::process::async_pipe>(get_io_context(exec.seq));
0085     }
0086 
0087     std::array<int, 3> get_used_handles()
0088     {
0089         if (pipe)
0090             return {STDIN_FILENO, pipe->native_source(), pipe->native_sink()};
0091         else  //if pipe is not constructed, limit_ds is invoked before -> this also means on_exec_setup gets invoked before.
0092             return {STDIN_FILENO, STDIN_FILENO, STDIN_FILENO};
0093     }
0094 
0095 
0096     template <typename Executor>
0097     void on_exec_setup(Executor &exec)
0098     {
0099         if (::dup2(pipe->native_source(), STDIN_FILENO) == -1)
0100             exec.set_error(::boost::process::detail::get_last_error(), "dup2() failed");
0101 
0102         if (pipe->native_source() != STDIN_FILENO)
0103             ::close(pipe->native_source());
0104         ::close(pipe->native_sink());
0105     }
0106 };
0107 
0108 
0109 }}}}
0110 
0111 #endif