]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/process/pipe.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / process / pipe.hpp
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_PIPE_HPP
12 #define BOOST_PROCESS_PIPE_HPP
13
14 #include <boost/config.hpp>
15 #include <boost/process/detail/config.hpp>
16 #include <streambuf>
17 #include <istream>
18 #include <ostream>
19 #include <vector>
20
21 #if defined(BOOST_POSIX_API)
22 #include <boost/process/detail/posix/basic_pipe.hpp>
23 #elif defined(BOOST_WINDOWS_API)
24 #include <boost/process/detail/windows/basic_pipe.hpp>
25 #endif
26
27 namespace boost { namespace process {
28
29 using ::boost::process::detail::api::basic_pipe;
30
31 #if defined(BOOST_PROCESS_DOXYGEN)
32 /** Class implementation of a pipe.
33 *
34 */
35 template<class CharT, class Traits = std::char_traits<CharT>>
36 class basic_pipe
37 {
38 public:
39 typedef CharT char_type ;
40 typedef Traits traits_type;
41 typedef typename Traits::int_type int_type ;
42 typedef typename Traits::pos_type pos_type ;
43 typedef typename Traits::off_type off_type ;
44 typedef ::boost::detail::winapi::HANDLE_ native_handle;
45
46 /// Default construct the pipe. Will be opened.
47 basic_pipe();
48
49 ///Construct a named pipe.
50 inline explicit basic_pipe(const std::string & name);
51 /** Copy construct the pipe.
52 * \note Duplicated the handles.
53 */
54 inline basic_pipe(const basic_pipe& p);
55 /** Move construct the pipe. */
56 basic_pipe(basic_pipe&& lhs);
57 /** Copy assign the pipe.
58 * \note Duplicated the handles.
59 */
60 inline basic_pipe& operator=(const basic_pipe& p);
61 /** Move assign the pipe. */
62 basic_pipe& operator=(basic_pipe&& lhs);
63 /** Destructor closes the handles. */
64 ~basic_pipe();
65 /** Get the native handle of the source. */
66 native_handle native_source() const;
67 /** Get the native handle of the sink. */
68 native_handle native_sink () const;
69
70 /** Assign a new value to the source */
71 void assign_source(native_handle h);
72 /** Assign a new value to the sink */
73 void assign_sink (native_handle h);
74
75
76 ///Write data to the pipe.
77 int_type write(const char_type * data, int_type count);
78 ///Read data from the pipe.
79 int_type read(char_type * data, int_type count);
80 ///Check if the pipe is open.
81 bool is_open();
82 ///Close the pipe
83 void close();
84 };
85
86 #endif
87
88
89
90 typedef basic_pipe<char> pipe;
91 typedef basic_pipe<wchar_t> wpipe;
92
93
94 /** Implementation of the stream buffer for a pipe.
95 */
96 template<
97 class CharT,
98 class Traits = std::char_traits<CharT>
99 >
100 struct basic_pipebuf : std::basic_streambuf<CharT, Traits>
101 {
102 typedef basic_pipe<CharT, Traits> pipe_type;
103
104 typedef CharT char_type ;
105 typedef Traits traits_type;
106 typedef typename Traits::int_type int_type ;
107 typedef typename Traits::pos_type pos_type ;
108 typedef typename Traits::off_type off_type ;
109
110 constexpr static int default_buffer_size = BOOST_PROCESS_PIPE_SIZE;
111
112 ///Default constructor, will also construct the pipe.
113 basic_pipebuf() : _write(default_buffer_size), _read(default_buffer_size)
114 {
115 this->setg(_read.data(), _read.data()+ 128, _read.data() + 128);
116 this->setp(_write.data(), _write.data() + _write.size());
117 }
118 ///Copy Constructor.
119 basic_pipebuf(const basic_pipebuf & ) = default;
120 ///Move Constructor
121 basic_pipebuf(basic_pipebuf && ) = default;
122
123 ///Move construct from a pipe.
124 basic_pipebuf(pipe_type && p) : _pipe(std::move(p)),
125 _write(default_buffer_size),
126 _read(default_buffer_size)
127 {
128 this->setg(_read.data(), _read.data()+ 128, _read.data() + 128);
129 this->setp(_write.data(), _write.data() + _write.size());
130 }
131 ///Construct from a pipe.
132 basic_pipebuf(const pipe_type & p) : _pipe(p),
133 _write(default_buffer_size),
134 _read(default_buffer_size)
135 {
136 this->setg(_read.data(), _read.data()+ 128, _read.data() + 128);
137 this->setp(_write.data(), _write.data() + _write.size());
138 }
139 ///Copy assign.
140 basic_pipebuf& operator=(const basic_pipebuf & ) = delete;
141 ///Move assign.
142 basic_pipebuf& operator=(basic_pipebuf && ) = default;
143 ///Move assign a pipe.
144 basic_pipebuf& operator=(pipe_type && p)
145 {
146 _pipe = std::move(p);
147 return *this;
148 }
149 ///Copy assign a pipe.
150 basic_pipebuf& operator=(const pipe_type & p)
151 {
152 _pipe = p;
153 return *this;
154 }
155 ///Writes characters to the associated output sequence from the put area
156 int_type overflow(int_type ch = traits_type::eof()) override
157 {
158 if ((ch != traits_type::eof()) && _pipe.is_open())
159 {
160 if (this->pptr() == this->epptr())
161 {
162 bool wr = this->_write_impl();
163 *this->pptr() = ch;
164 this->pbump(1);
165 if (wr)
166 return ch;
167 }
168 else
169 {
170 *this->pptr() = ch;
171 this->pbump(1);
172 if (this->_write_impl())
173 return ch;
174 }
175 }
176 return traits_type::eof();
177 }
178 ///Synchronizes the buffers with the associated character sequence
179 int sync() override { return this->_write_impl() ? 0 : -1; }
180
181 ///Reads characters from the associated input sequence to the get area
182 int_type underflow() override
183 {
184 if (!_pipe.is_open())
185 return traits_type::eof();
186
187 if (this->egptr() == &_read.back()) //ok, so we're at the end of the buffer
188 this->setg(_read.data(), _read.data()+ 10, _read.data() + 10);
189
190
191 auto len = &_read.back() - this->egptr() ;
192 auto res = _pipe.read(
193 this->egptr(),
194 static_cast<typename pipe_type::int_type>(len));
195 if (res == 0)
196 return traits_type::eof();
197
198 this->setg(this->eback(), this->gptr(), this->egptr() + res);
199 auto val = *this->gptr();
200
201 return traits_type::to_int_type(val);
202 }
203
204
205 ///Set the pipe of the streambuf.
206 void pipe(pipe_type&& p) {_pipe = std::move(p); }
207 ///Set the pipe of the streambuf.
208 void pipe(const pipe_type& p) {_pipe = p; }
209 ///Get a reference to the pipe.
210 pipe_type & pipe() & {return _pipe;}
211 ///Get a const reference to the pipe.
212 const pipe_type &pipe() const & {return _pipe;}
213 ///Get a rvalue reference to the pipe. Qualified as rvalue.
214 pipe_type && pipe() && {return std::move(_pipe);}
215 private:
216 pipe_type _pipe;
217 std::vector<char_type> _write;
218 std::vector<char_type> _read;
219
220 bool _write_impl()
221 {
222 if (!_pipe.is_open())
223 return false;
224
225 auto base = this->pbase();
226 auto wrt = _pipe.write(base,
227 static_cast<typename pipe_type::int_type>(this->pptr() - base));
228 std::ptrdiff_t diff = this->pptr() - base;
229
230 if (wrt < diff)
231 std::move(base + wrt, base + diff, base);
232 else if (wrt == 0) //broken pipe
233 return false;
234
235 this->pbump(-wrt);
236
237 return true;
238 }
239 };
240
241 typedef basic_pipebuf<char> pipebuf;
242 typedef basic_pipebuf<wchar_t> wpipebuf;
243
244 /** Implementation of a reading pipe stream.
245 *
246 */
247 template<
248 class CharT,
249 class Traits = std::char_traits<CharT>
250 >
251 class basic_ipstream : public std::basic_istream<CharT, Traits>
252 {
253 basic_pipebuf<CharT, Traits> _buf;
254 public:
255
256 typedef basic_pipe<CharT, Traits> pipe_type;
257
258 typedef CharT char_type ;
259 typedef Traits traits_type;
260 typedef typename Traits::int_type int_type ;
261 typedef typename Traits::pos_type pos_type ;
262 typedef typename Traits::off_type off_type ;
263
264 ///Get access to the underlying stream_buf
265 basic_pipebuf<CharT, Traits>* rdbuf() {return &_buf;};
266
267 ///Default constructor.
268 basic_ipstream() : std::basic_istream<CharT, Traits>(nullptr)
269 {
270 std::basic_istream<CharT, Traits>::rdbuf(&_buf);
271 };
272 ///Copy constructor.
273 basic_ipstream(const basic_ipstream & ) = delete;
274 ///Move constructor.
275 basic_ipstream(basic_ipstream && ) = default;
276
277 ///Move construct from a pipe.
278 basic_ipstream(pipe_type && p) : std::basic_istream<CharT, Traits>(nullptr), _buf(std::move(p))
279 {
280 std::basic_istream<CharT, Traits>::rdbuf(&_buf);
281 }
282
283 ///Copy construct from a pipe.
284 basic_ipstream(const pipe_type & p) : std::basic_istream<CharT, Traits>(nullptr), _buf(p)
285 {
286 std::basic_istream<CharT, Traits>::rdbuf(&_buf);
287 }
288
289 ///Copy assignment.
290 basic_ipstream& operator=(const basic_ipstream & ) = delete;
291 ///Move assignment
292 basic_ipstream& operator=(basic_ipstream && ) = default;
293 ///Move assignment of a pipe.
294 basic_ipstream& operator=(pipe_type && p)
295 {
296 _buf = std::move(p);
297 return *this;
298 }
299 ///Copy assignment of a pipe.
300 basic_ipstream& operator=(const pipe_type & p)
301 {
302 _buf = p;
303 return *this;
304 }
305 ///Set the pipe of the streambuf.
306 void pipe(pipe_type&& p) {_buf.pipe(std::move(p)); }
307 ///Set the pipe of the streambuf.
308 void pipe(const pipe_type& p) {_buf.pipe(p); }
309 ///Get a reference to the pipe.
310 pipe_type & pipe() & {return _buf.pipe();}
311 ///Get a const reference to the pipe.
312 const pipe_type &pipe() const & {return _buf.pipe();}
313 ///Get a rvalue reference to the pipe. Qualified as rvalue.
314 pipe_type && pipe() && {return std::move(_buf).pipe();}
315 };
316
317 typedef basic_ipstream<char> ipstream;
318 typedef basic_ipstream<wchar_t> wipstream;
319
320 /** Implementation of a write pipe stream.
321 *
322 */
323 template<
324 class CharT,
325 class Traits = std::char_traits<CharT>
326 >
327 class basic_opstream : public std::basic_ostream<CharT, Traits>
328 {
329 basic_pipebuf<CharT, Traits> _buf;
330 public:
331 typedef basic_pipe<CharT, Traits> pipe_type;
332
333 typedef CharT char_type ;
334 typedef Traits traits_type;
335 typedef typename Traits::int_type int_type ;
336 typedef typename Traits::pos_type pos_type ;
337 typedef typename Traits::off_type off_type ;
338
339
340 ///Get access to the underlying stream_buf
341 basic_pipebuf<CharT, Traits>* rdbuf() const {return _buf;};
342
343 ///Default constructor.
344 basic_opstream() : std::basic_ostream<CharT, Traits>(nullptr)
345 {
346 std::basic_ostream<CharT, Traits>::rdbuf(&_buf);
347 };
348 ///Copy constructor.
349 basic_opstream(const basic_opstream & ) = delete;
350 ///Move constructor.
351 basic_opstream(basic_opstream && ) = default;
352
353 ///Move construct from a pipe.
354 basic_opstream(pipe_type && p) : std::basic_ostream<CharT, Traits>(nullptr), _buf(std::move(p))
355 {
356 std::basic_ostream<CharT, Traits>::rdbuf(&_buf);
357 };
358 ///Copy construct from a pipe.
359 basic_opstream(const pipe_type & p) : std::basic_ostream<CharT, Traits>(nullptr), _buf(p)
360 {
361 std::basic_ostream<CharT, Traits>::rdbuf(&_buf);
362 };
363 ///Copy assignment.
364 basic_opstream& operator=(const basic_opstream & ) = delete;
365 ///Move assignment
366 basic_opstream& operator=(basic_opstream && ) = default;
367 ///Move assignment of a pipe.
368 basic_opstream& operator=(pipe_type && p)
369 {
370 _buf = std::move(p);
371 return *this;
372 }
373 ///Copy assignment of a pipe.
374 basic_opstream& operator=(const pipe_type & p)
375 {
376 _buf = p;
377 return *this;
378 }
379 ///Set the pipe of the streambuf.
380 void pipe(pipe_type&& p) {_buf.pipe(std::move(p)); }
381 ///Set the pipe of the streambuf.
382 void pipe(const pipe_type& p) {_buf.pipe(p); }
383 ///Get a reference to the pipe.
384 pipe_type & pipe() & {return _buf.pipe();}
385 ///Get a const reference to the pipe.
386 const pipe_type &pipe() const & {return _buf.pipe();}
387 ///Get a rvalue reference to the pipe. Qualified as rvalue.
388 pipe_type && pipe() && {return std::move(_buf).pipe();}
389 };
390
391 typedef basic_opstream<char> opstream;
392 typedef basic_opstream<wchar_t> wopstream;
393
394
395 /** Implementation of a read-write pipe stream.
396 *
397 */
398 template<
399 class CharT,
400 class Traits = std::char_traits<CharT>
401 >
402 class basic_pstream : public std::basic_iostream<CharT, Traits>
403 {
404 basic_pipebuf<CharT, Traits> _buf;
405 public:
406 typedef basic_pipe<CharT, Traits> pipe_type;
407
408 typedef CharT char_type ;
409 typedef Traits traits_type;
410 typedef typename Traits::int_type int_type ;
411 typedef typename Traits::pos_type pos_type ;
412 typedef typename Traits::off_type off_type ;
413
414
415 ///Get access to the underlying stream_buf
416 basic_pipebuf<CharT, Traits>* rdbuf() const {return _buf;};
417
418 ///Default constructor.
419 basic_pstream() : std::basic_iostream<CharT, Traits>(nullptr)
420 {
421 std::basic_iostream<CharT, Traits>::rdbuf(&_buf);
422 };
423 ///Copy constructor.
424 basic_pstream(const basic_pstream & ) = delete;
425 ///Move constructor.
426 basic_pstream(basic_pstream && ) = default;
427
428 ///Move construct from a pipe.
429 basic_pstream(pipe_type && p) : std::basic_iostream<CharT, Traits>(nullptr), _buf(std::move(p))
430 {
431 std::basic_iostream<CharT, Traits>::rdbuf(&_buf);
432 };
433 ///Copy construct from a pipe.
434 basic_pstream(const pipe_type & p) : std::basic_iostream<CharT, Traits>(nullptr), _buf(p)
435 {
436 std::basic_iostream<CharT, Traits>::rdbuf(&_buf);
437 };
438 ///Copy assignment.
439 basic_pstream& operator=(const basic_pstream & ) = delete;
440 ///Move assignment
441 basic_pstream& operator=(basic_pstream && ) = default;
442 ///Move assignment of a pipe.
443 basic_pstream& operator=(pipe_type && p)
444 {
445 _buf = std::move(p);
446 return *this;
447 }
448 ///Copy assignment of a pipe.
449 basic_pstream& operator=(const pipe_type & p)
450 {
451 _buf = p;
452 return *this;
453 }
454 ///Set the pipe of the streambuf.
455 void pipe(pipe_type&& p) {_buf.pipe(std::move(p)); }
456 ///Set the pipe of the streambuf.
457 void pipe(const pipe_type& p) {_buf.pipe(p); }
458 ///Get a reference to the pipe.
459 pipe_type & pipe() & {return _buf.pipe();}
460 ///Get a const reference to the pipe.
461 const pipe_type &pipe() const & {return _buf.pipe();}
462 ///Get a rvalue reference to the pipe. Qualified as rvalue.
463 pipe_type && pipe() && {return std::move(_buf).pipe();}
464 };
465
466 typedef basic_pstream<char> pstream;
467 typedef basic_pstream<wchar_t> wpstream;
468
469
470
471 }}
472
473
474
475 #endif