1 // Copyright (c) 2006, 2007 Julio M. Merino Vidal
2 // Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
3 // Copyright (c) 2009 Boris Schaeling
4 // Copyright (c) 2010 Felipe Tanus, Boris Schaeling
5 // Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 
10 
11 #ifndef BOOST_PROCESS_ASYNC_PIPE_HPP
12 #define BOOST_PROCESS_ASYNC_PIPE_HPP
13 
14 #include <boost/config.hpp>
15 #include <boost/process/detail/config.hpp>
16 
17 #if defined(BOOST_POSIX_API)
18 #include <boost/process/detail/posix/async_pipe.hpp>
19 #elif defined(BOOST_WINDOWS_API)
20 #include <boost/process/detail/windows/async_pipe.hpp>
21 #endif
22 
23 namespace boost { namespace process {
24 
25 
26 #if defined(BOOST_PROCESS_DOXYGEN)
27 
28 
29 /** Class implementing and asnychronous I/O-Object for use with boost.asio.
30  *  It is based on the corresponding I/O Object, that is either boost::asio::windows::stream_handle or
31  *  boost::asio::posix::stream_descriptor.
32  *
33  *  It can be used directly with boost::asio::async_read or async_write.
34  *
35  * \note The object is copyable, but that does invoke a handle duplicate.
36  */
37 class async_pipe
38 {
39 public:
40     /** Typedef for the native handle representation.
41      * \note This is the handle on the system, not the boost.asio class.
42      *
43      */
44     typedef platform_specific native_handle_type;
45     /** Typedef for the handle representation of boost.asio.
46      *
47      */
48     typedef platform_specific handle_type;
49 
50     typedef typename handle_type::executor_type executor_type;
51 
52     /** Construct a new async_pipe, does automatically open the pipe.
53      * Initializes source and sink with the same io_context.
54      * @note Windows creates a named pipe here, where the name is automatically generated.
55      */
56     inline async_pipe(boost::asio::io_context & ios);
57 
58     /** Construct a new async_pipe, does automatically open the pipe.
59      * @note Windows creates a named pipe here, where the name is automatically generated.
60      */
61     inline async_pipe(boost::asio::io_context & ios_source,
62                       boost::asio::io_context & ios_sink);
63 
64     /** Construct a new async_pipe, does automatically open.
65      * Initializes source and sink with the same io_context.
66      *
67      * @note Windows restricts possible names.
68      */
69     inline async_pipe(boost::asio::io_context & ios, const std::string & name);
70 
71 
72     /** Construct a new async_pipe, does automatically open.
73      *
74      * @note Windows restricts possible names.
75      */
76     inline async_pipe(boost::asio::io_context & ios_source,
77                       boost::asio::io_context & ios_sink, const std::string & name);
78 
79     /** Copy-Constructor of the async pipe.
80      * @note Windows requires a named pipe for this, if a the wrong type is used an exception is thrown.
81      *
82      */
83     async_pipe(const async_pipe& lhs);
84 
85     /** Move-Constructor of the async pipe.
86      */
87     async_pipe(async_pipe&& lhs);
88 
89     /** Construct the async-pipe from a pipe.
90      * @note Windows requires a named pipe for this, if a the wrong type is used an exception is thrown.
91      *
92      */
93     template<class CharT, class Traits = std::char_traits<CharT>>
94     explicit async_pipe(boost::asio::io_context & ios, const basic_pipe<CharT, Traits> & p);
95 
96     /** Construct the async-pipe from a pipe, with two different io_context objects.
97      * @note Windows requires a named pipe for this, if a the wrong type is used an exception is thrown.
98      *
99      */
100     template<class CharT, class Traits = std::char_traits<CharT>>
101     explicit async_pipe(boost::asio::io_context & ios_source,
102                         boost::asio::io_context & ios_sink,
103                         const basic_pipe<CharT, Traits> & p);
104 
105 
106     /** Assign a basic_pipe.
107      * @note Windows requires a named pipe for this, if a the wrong type is used an exception is thrown.
108      *
109      */
110     template<class CharT, class Traits = std::char_traits<CharT>>
111     inline async_pipe& operator=(const basic_pipe<CharT, Traits>& p);
112 
113     /** Copy Assign a pipe.
114      * @note Duplicates the handles.
115      */
116     async_pipe& operator=(const async_pipe& lhs);
117     /** Move assign a pipe */
118     async_pipe& operator=(async_pipe&& lhs);
119 
120     /** Destructor. Closes the pipe handles. */
121     ~async_pipe();
122 
123     /** Explicit cast to basic_pipe.  */
124     template<class CharT, class Traits = std::char_traits<CharT>>
125     inline explicit operator basic_pipe<CharT, Traits>() const;
126 
127     /** Cancel the current asynchronous operations. */
128     void cancel();
129     /** Close the pipe handles. */
130     void close();
131     /** Close the pipe handles. While passing an error_code
132      *
133      */
134     void close(std::error_code & ec);
135 
136     /** Check if the pipes are open. */
137     bool is_open() const;
138 
139     /** Async close, i.e. close after current operation is completed.
140      *
141      *  \note There is no guarantee that this will indeed read the entire pipe-buffer
142      */
143     void async_close();
144 
145     /** Read some data from the handle.
146 
147      * See the boost.asio documentation for more details.
148      */
149     template<typename MutableBufferSequence>
150     std::size_t read_some(const MutableBufferSequence & buffers);
151 
152     /** Write some data to the handle.
153 
154      * See the boost.asio documentation for more details.
155      */
156     template<typename MutableBufferSequence>
157     std::size_t write_some(const MutableBufferSequence & buffers);
158 
159     /** Get the native handle of the source. */
native_source() const160     native_handle native_source() const {return const_cast<boost::asio::windows::stream_handle&>(_source).native();}
161     /** Get the native handle of the sink. */
native_sink() const162     native_handle native_sink  () const {return const_cast<boost::asio::windows::stream_handle&>(_sink  ).native();}
163 
164     /** Start an asynchronous read.
165      *
166      * See the [boost.asio documentation](http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/AsyncReadStream.html) for more details.
167      */
168     template<typename MutableBufferSequence,
169              typename ReadHandler>
170     detail::dummy async_read_some(
171         const MutableBufferSequence & buffers,
172               ReadHandler &&handler);
173 
174     /** Start an asynchronous write.
175 
176      * See the [boost.asio documentation](http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/AsyncWriteStream.html) for more details.
177      */
178     template<typename ConstBufferSequence,
179              typename WriteHandler>
180     detail::dummy async_write_some(
181         const ConstBufferSequence & buffers,
182         WriteHandler && handler);
183 
184     ///Get the asio handle of the pipe sink.
185     const handle_type & sink  () const &;
186     ///Get the asio handle of the pipe source.
187     const handle_type & source() const &;
188 
189     ///Get the asio handle of the pipe sink. Qualified as rvalue
190     handle_type && sink  () &&;
191     ///Get the asio handle of the pipe source. Qualified as rvalue
192     handle_type && source() &&;
193 
194     /// Move the source out of this class and change the io_context. Qualified as rvalue. \attention Will always move.
195     handle_type source(::boost::asio::io_context& ios) &&;
196     /// Move the sink out of this class and change the io_context. Qualified as rvalue. \attention Will always move
197     handle_type sink  (::boost::asio::io_context& ios) &&;
198 
199     /// Copy the source out of this class and change the io_context. \attention Will always copy.
200     handle_type source(::boost::asio::io_context& ios) const &;
201     /// Copy the sink out of this class and change the io_context. \attention Will always copy
202     handle_type sink  (::boost::asio::io_context& ios) const &;
203 
204 
205 
206 };
207 
208 #else
209 using ::boost::process::detail::api::async_pipe;
210 #endif
211 
212 
213 }}
214 
215 
216 
217 #endif
218