]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/process/pipe.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / process / pipe.hpp
CommitLineData
b32b8144
FG
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
27namespace boost { namespace process {
28
29using ::boost::process::detail::api::basic_pipe;
30
31#if defined(BOOST_PROCESS_DOXYGEN)
32/** Class implementation of a pipe.
33 *
34 */
35template<class CharT, class Traits = std::char_traits<CharT>>
36class basic_pipe
37{
38public:
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
90typedef basic_pipe<char> pipe;
91typedef basic_pipe<wchar_t> wpipe;
92
93
94/** Implementation of the stream buffer for a pipe.
95 */
96template<
97 class CharT,
98 class Traits = std::char_traits<CharT>
99>
100struct 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
92f5a8d4
TL
123 ///Destructor -> writes the frest of the data
124 ~basic_pipebuf()
125 {
20effc67
TL
126 if (basic_pipebuf::is_open())
127 basic_pipebuf::overflow(Traits::eof());
92f5a8d4
TL
128 }
129
b32b8144
FG
130 ///Move construct from a pipe.
131 basic_pipebuf(pipe_type && p) : _pipe(std::move(p)),
132 _write(default_buffer_size),
133 _read(default_buffer_size)
134 {
135 this->setg(_read.data(), _read.data()+ 128, _read.data() + 128);
136 this->setp(_write.data(), _write.data() + _write.size());
137 }
138 ///Construct from a pipe.
139 basic_pipebuf(const pipe_type & p) : _pipe(p),
140 _write(default_buffer_size),
141 _read(default_buffer_size)
142 {
143 this->setg(_read.data(), _read.data()+ 128, _read.data() + 128);
144 this->setp(_write.data(), _write.data() + _write.size());
145 }
146 ///Copy assign.
147 basic_pipebuf& operator=(const basic_pipebuf & ) = delete;
148 ///Move assign.
149 basic_pipebuf& operator=(basic_pipebuf && ) = default;
150 ///Move assign a pipe.
151 basic_pipebuf& operator=(pipe_type && p)
152 {
153 _pipe = std::move(p);
154 return *this;
155 }
156 ///Copy assign a pipe.
157 basic_pipebuf& operator=(const pipe_type & p)
158 {
159 _pipe = p;
160 return *this;
161 }
162 ///Writes characters to the associated output sequence from the put area
163 int_type overflow(int_type ch = traits_type::eof()) override
164 {
92f5a8d4 165 if (_pipe.is_open() && (ch != traits_type::eof()))
b32b8144
FG
166 {
167 if (this->pptr() == this->epptr())
168 {
169 bool wr = this->_write_impl();
b32b8144 170 if (wr)
20effc67
TL
171 {
172 *this->pptr() = ch;
173 this->pbump(1);
b32b8144 174 return ch;
20effc67 175 }
b32b8144
FG
176 }
177 else
178 {
179 *this->pptr() = ch;
180 this->pbump(1);
181 if (this->_write_impl())
182 return ch;
183 }
184 }
92f5a8d4
TL
185 else if (ch == traits_type::eof())
186 this->sync();
187
b32b8144
FG
188 return traits_type::eof();
189 }
190 ///Synchronizes the buffers with the associated character sequence
191 int sync() override { return this->_write_impl() ? 0 : -1; }
192
193 ///Reads characters from the associated input sequence to the get area
194 int_type underflow() override
195 {
196 if (!_pipe.is_open())
197 return traits_type::eof();
198
199 if (this->egptr() == &_read.back()) //ok, so we're at the end of the buffer
200 this->setg(_read.data(), _read.data()+ 10, _read.data() + 10);
201
202
203 auto len = &_read.back() - this->egptr() ;
204 auto res = _pipe.read(
205 this->egptr(),
206 static_cast<typename pipe_type::int_type>(len));
207 if (res == 0)
208 return traits_type::eof();
209
210 this->setg(this->eback(), this->gptr(), this->egptr() + res);
211 auto val = *this->gptr();
212
213 return traits_type::to_int_type(val);
214 }
215
216
217 ///Set the pipe of the streambuf.
218 void pipe(pipe_type&& p) {_pipe = std::move(p); }
219 ///Set the pipe of the streambuf.
220 void pipe(const pipe_type& p) {_pipe = p; }
221 ///Get a reference to the pipe.
222 pipe_type & pipe() & {return _pipe;}
223 ///Get a const reference to the pipe.
224 const pipe_type &pipe() const & {return _pipe;}
225 ///Get a rvalue reference to the pipe. Qualified as rvalue.
226 pipe_type && pipe() && {return std::move(_pipe);}
92f5a8d4
TL
227
228 ///Check if the pipe is open
229 bool is_open() const {return _pipe.is_open(); }
230
231 ///Open a new pipe
232 basic_pipebuf<CharT, Traits>* open()
233 {
234 if (is_open())
235 return nullptr;
236 _pipe = pipe();
237 return this;
238 }
239
240 ///Open a new named pipe
241 basic_pipebuf<CharT, Traits>* open(const std::string & name)
242 {
243 if (is_open())
244 return nullptr;
245 _pipe = pipe(name);
246 return this;
247 }
248
249 ///Flush the buffer & close the pipe
250 basic_pipebuf<CharT, Traits>* close()
251 {
252 if (!is_open())
253 return nullptr;
254 overflow(Traits::eof());
255 return this;
256 }
b32b8144
FG
257private:
258 pipe_type _pipe;
259 std::vector<char_type> _write;
260 std::vector<char_type> _read;
261
262 bool _write_impl()
263 {
264 if (!_pipe.is_open())
265 return false;
266
267 auto base = this->pbase();
92f5a8d4
TL
268
269 if (base == this->pptr())
270 return true;
271
272 std::ptrdiff_t wrt = _pipe.write(base,
b32b8144 273 static_cast<typename pipe_type::int_type>(this->pptr() - base));
92f5a8d4 274
b32b8144
FG
275 std::ptrdiff_t diff = this->pptr() - base;
276
277 if (wrt < diff)
278 std::move(base + wrt, base + diff, base);
279 else if (wrt == 0) //broken pipe
280 return false;
281
1e59de90 282 this->pbump(static_cast<int>(-wrt));
b32b8144
FG
283
284 return true;
285 }
286};
287
288typedef basic_pipebuf<char> pipebuf;
289typedef basic_pipebuf<wchar_t> wpipebuf;
290
291/** Implementation of a reading pipe stream.
292 *
293 */
294template<
295 class CharT,
296 class Traits = std::char_traits<CharT>
297>
298class basic_ipstream : public std::basic_istream<CharT, Traits>
299{
92f5a8d4 300 mutable basic_pipebuf<CharT, Traits> _buf;
b32b8144
FG
301public:
302
303 typedef basic_pipe<CharT, Traits> pipe_type;
304
305 typedef CharT char_type ;
306 typedef Traits traits_type;
307 typedef typename Traits::int_type int_type ;
308 typedef typename Traits::pos_type pos_type ;
309 typedef typename Traits::off_type off_type ;
310
311 ///Get access to the underlying stream_buf
92f5a8d4 312 basic_pipebuf<CharT, Traits>* rdbuf() const {return &_buf;};
b32b8144
FG
313
314 ///Default constructor.
315 basic_ipstream() : std::basic_istream<CharT, Traits>(nullptr)
316 {
317 std::basic_istream<CharT, Traits>::rdbuf(&_buf);
318 };
319 ///Copy constructor.
320 basic_ipstream(const basic_ipstream & ) = delete;
321 ///Move constructor.
92f5a8d4
TL
322 basic_ipstream(basic_ipstream && lhs) : std::basic_istream<CharT, Traits>(nullptr), _buf(std::move(lhs._buf))
323 {
324 std::basic_istream<CharT, Traits>::rdbuf(&_buf);
325 }
b32b8144
FG
326
327 ///Move construct from a pipe.
328 basic_ipstream(pipe_type && p) : std::basic_istream<CharT, Traits>(nullptr), _buf(std::move(p))
329 {
330 std::basic_istream<CharT, Traits>::rdbuf(&_buf);
331 }
332
333 ///Copy construct from a pipe.
334 basic_ipstream(const pipe_type & p) : std::basic_istream<CharT, Traits>(nullptr), _buf(p)
335 {
336 std::basic_istream<CharT, Traits>::rdbuf(&_buf);
337 }
338
339 ///Copy assignment.
340 basic_ipstream& operator=(const basic_ipstream & ) = delete;
341 ///Move assignment
92f5a8d4
TL
342 basic_ipstream& operator=(basic_ipstream && lhs)
343 {
344 std::basic_istream<CharT, Traits>::operator=(std::move(lhs));
f67539c2 345 _buf = std::move(lhs._buf);
92f5a8d4 346 std::basic_istream<CharT, Traits>::rdbuf(&_buf);
f67539c2 347 return *this;
92f5a8d4 348 };
b32b8144
FG
349 ///Move assignment of a pipe.
350 basic_ipstream& operator=(pipe_type && p)
351 {
352 _buf = std::move(p);
353 return *this;
354 }
355 ///Copy assignment of a pipe.
356 basic_ipstream& operator=(const pipe_type & p)
357 {
358 _buf = p;
359 return *this;
360 }
361 ///Set the pipe of the streambuf.
362 void pipe(pipe_type&& p) {_buf.pipe(std::move(p)); }
363 ///Set the pipe of the streambuf.
364 void pipe(const pipe_type& p) {_buf.pipe(p); }
365 ///Get a reference to the pipe.
366 pipe_type & pipe() & {return _buf.pipe();}
367 ///Get a const reference to the pipe.
368 const pipe_type &pipe() const & {return _buf.pipe();}
369 ///Get a rvalue reference to the pipe. Qualified as rvalue.
370 pipe_type && pipe() && {return std::move(_buf).pipe();}
92f5a8d4 371 ///Check if the pipe is open
f67539c2 372 bool is_open() const {return _buf.is_open();}
92f5a8d4
TL
373
374 ///Open a new pipe
375 void open()
376 {
377 if (_buf.open() == nullptr)
378 this->setstate(std::ios_base::failbit);
379 else
380 this->clear();
381 }
382
383 ///Open a new named pipe
384 void open(const std::string & name)
385 {
386 if (_buf.open() == nullptr)
387 this->setstate(std::ios_base::failbit);
388 else
389 this->clear();
390 }
391
392 ///Flush the buffer & close the pipe
393 void close()
394 {
395 if (_buf.close() == nullptr)
396 this->setstate(std::ios_base::failbit);
397 }
b32b8144
FG
398};
399
400typedef basic_ipstream<char> ipstream;
401typedef basic_ipstream<wchar_t> wipstream;
402
403/** Implementation of a write pipe stream.
404 *
405 */
406template<
407 class CharT,
408 class Traits = std::char_traits<CharT>
409>
410class basic_opstream : public std::basic_ostream<CharT, Traits>
411{
92f5a8d4 412 mutable basic_pipebuf<CharT, Traits> _buf;
b32b8144
FG
413public:
414 typedef basic_pipe<CharT, Traits> pipe_type;
415
416 typedef CharT char_type ;
417 typedef Traits traits_type;
418 typedef typename Traits::int_type int_type ;
419 typedef typename Traits::pos_type pos_type ;
420 typedef typename Traits::off_type off_type ;
421
422
423 ///Get access to the underlying stream_buf
92f5a8d4 424 basic_pipebuf<CharT, Traits>* rdbuf() const {return &_buf;};
b32b8144
FG
425
426 ///Default constructor.
427 basic_opstream() : std::basic_ostream<CharT, Traits>(nullptr)
428 {
429 std::basic_ostream<CharT, Traits>::rdbuf(&_buf);
430 };
431 ///Copy constructor.
432 basic_opstream(const basic_opstream & ) = delete;
433 ///Move constructor.
92f5a8d4
TL
434 basic_opstream(basic_opstream && lhs) : std::basic_ostream<CharT, Traits>(nullptr), _buf(std::move(lhs._buf))
435 {
436 std::basic_ostream<CharT, Traits>::rdbuf(&_buf);
437 }
b32b8144
FG
438 ///Move construct from a pipe.
439 basic_opstream(pipe_type && p) : std::basic_ostream<CharT, Traits>(nullptr), _buf(std::move(p))
440 {
441 std::basic_ostream<CharT, Traits>::rdbuf(&_buf);
442 };
443 ///Copy construct from a pipe.
444 basic_opstream(const pipe_type & p) : std::basic_ostream<CharT, Traits>(nullptr), _buf(p)
445 {
446 std::basic_ostream<CharT, Traits>::rdbuf(&_buf);
447 };
448 ///Copy assignment.
449 basic_opstream& operator=(const basic_opstream & ) = delete;
450 ///Move assignment
92f5a8d4
TL
451 basic_opstream& operator=(basic_opstream && lhs)
452 {
453 std::basic_ostream<CharT, Traits>::operator=(std::move(lhs));
f67539c2 454 _buf = std::move(lhs._buf);
92f5a8d4 455 std::basic_ostream<CharT, Traits>::rdbuf(&_buf);
f67539c2 456 return *this;
92f5a8d4
TL
457 };
458
b32b8144
FG
459 ///Move assignment of a pipe.
460 basic_opstream& operator=(pipe_type && p)
461 {
462 _buf = std::move(p);
463 return *this;
464 }
465 ///Copy assignment of a pipe.
466 basic_opstream& operator=(const pipe_type & p)
467 {
468 _buf = p;
469 return *this;
470 }
471 ///Set the pipe of the streambuf.
472 void pipe(pipe_type&& p) {_buf.pipe(std::move(p)); }
473 ///Set the pipe of the streambuf.
474 void pipe(const pipe_type& p) {_buf.pipe(p); }
475 ///Get a reference to the pipe.
476 pipe_type & pipe() & {return _buf.pipe();}
477 ///Get a const reference to the pipe.
478 const pipe_type &pipe() const & {return _buf.pipe();}
479 ///Get a rvalue reference to the pipe. Qualified as rvalue.
480 pipe_type && pipe() && {return std::move(_buf).pipe();}
92f5a8d4
TL
481
482 ///Open a new pipe
483 void open()
484 {
485 if (_buf.open() == nullptr)
486 this->setstate(std::ios_base::failbit);
487 else
488 this->clear();
489 }
490
491 ///Open a new named pipe
492 void open(const std::string & name)
493 {
494 if (_buf.open() == nullptr)
495 this->setstate(std::ios_base::failbit);
496 else
497 this->clear();
498 }
499
500 ///Flush the buffer & close the pipe
501 void close()
502 {
503 if (_buf.close() == nullptr)
504 this->setstate(std::ios_base::failbit);
505 }
b32b8144
FG
506};
507
508typedef basic_opstream<char> opstream;
509typedef basic_opstream<wchar_t> wopstream;
510
511
512/** Implementation of a read-write pipe stream.
513 *
514 */
515template<
516 class CharT,
517 class Traits = std::char_traits<CharT>
518>
519class basic_pstream : public std::basic_iostream<CharT, Traits>
520{
92f5a8d4 521 mutable basic_pipebuf<CharT, Traits> _buf;
b32b8144
FG
522public:
523 typedef basic_pipe<CharT, Traits> pipe_type;
524
525 typedef CharT char_type ;
526 typedef Traits traits_type;
527 typedef typename Traits::int_type int_type ;
528 typedef typename Traits::pos_type pos_type ;
529 typedef typename Traits::off_type off_type ;
530
531
532 ///Get access to the underlying stream_buf
92f5a8d4 533 basic_pipebuf<CharT, Traits>* rdbuf() const {return &_buf;};
b32b8144
FG
534
535 ///Default constructor.
536 basic_pstream() : std::basic_iostream<CharT, Traits>(nullptr)
537 {
538 std::basic_iostream<CharT, Traits>::rdbuf(&_buf);
539 };
540 ///Copy constructor.
541 basic_pstream(const basic_pstream & ) = delete;
542 ///Move constructor.
92f5a8d4
TL
543 basic_pstream(basic_pstream && lhs) : std::basic_iostream<CharT, Traits>(nullptr), _buf(std::move(lhs._buf))
544 {
545 std::basic_iostream<CharT, Traits>::rdbuf(&_buf);
546 }
b32b8144
FG
547 ///Move construct from a pipe.
548 basic_pstream(pipe_type && p) : std::basic_iostream<CharT, Traits>(nullptr), _buf(std::move(p))
549 {
550 std::basic_iostream<CharT, Traits>::rdbuf(&_buf);
551 };
552 ///Copy construct from a pipe.
553 basic_pstream(const pipe_type & p) : std::basic_iostream<CharT, Traits>(nullptr), _buf(p)
554 {
555 std::basic_iostream<CharT, Traits>::rdbuf(&_buf);
556 };
557 ///Copy assignment.
558 basic_pstream& operator=(const basic_pstream & ) = delete;
559 ///Move assignment
92f5a8d4
TL
560 basic_pstream& operator=(basic_pstream && lhs)
561 {
562 std::basic_istream<CharT, Traits>::operator=(std::move(lhs));
f67539c2 563 _buf = std::move(lhs._buf);
92f5a8d4 564 std::basic_iostream<CharT, Traits>::rdbuf(&_buf);
f67539c2 565 return *this;
92f5a8d4 566 };
b32b8144
FG
567 ///Move assignment of a pipe.
568 basic_pstream& operator=(pipe_type && p)
569 {
570 _buf = std::move(p);
571 return *this;
572 }
573 ///Copy assignment of a pipe.
574 basic_pstream& operator=(const pipe_type & p)
575 {
576 _buf = p;
577 return *this;
578 }
579 ///Set the pipe of the streambuf.
580 void pipe(pipe_type&& p) {_buf.pipe(std::move(p)); }
581 ///Set the pipe of the streambuf.
582 void pipe(const pipe_type& p) {_buf.pipe(p); }
583 ///Get a reference to the pipe.
584 pipe_type & pipe() & {return _buf.pipe();}
585 ///Get a const reference to the pipe.
586 const pipe_type &pipe() const & {return _buf.pipe();}
587 ///Get a rvalue reference to the pipe. Qualified as rvalue.
588 pipe_type && pipe() && {return std::move(_buf).pipe();}
92f5a8d4
TL
589
590 ///Open a new pipe
591 void open()
592 {
593 if (_buf.open() == nullptr)
594 this->setstate(std::ios_base::failbit);
595 else
596 this->clear();
597 }
598
599 ///Open a new named pipe
600 void open(const std::string & name)
601 {
602 if (_buf.open() == nullptr)
603 this->setstate(std::ios_base::failbit);
604 else
605 this->clear();
606 }
607
608 ///Flush the buffer & close the pipe
609 void close()
610 {
611 if (_buf.close() == nullptr)
612 this->setstate(std::ios_base::failbit);
613 }
b32b8144
FG
614};
615
616typedef basic_pstream<char> pstream;
617typedef basic_pstream<wchar_t> wpstream;
618
619
620
621}}
622
623
624
625#endif