summaryrefslogtreecommitdiff
path: root/boost/process/pipe.hpp
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2017-09-13 11:08:07 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2017-09-13 11:09:00 +0900
commitb5c87084afaef42b2d058f68091be31988a6a874 (patch)
treeadef9a65870a41181687e11d57fdf98e7629de3c /boost/process/pipe.hpp
parent34bd32e225e2a8a94104489b31c42e5801cc1f4a (diff)
downloadboost-b5c87084afaef42b2d058f68091be31988a6a874.tar.gz
boost-b5c87084afaef42b2d058f68091be31988a6a874.tar.bz2
boost-b5c87084afaef42b2d058f68091be31988a6a874.zip
Imported Upstream version 1.64.0upstream/1.64.0
Change-Id: Id9212edd016dd55f21172c427aa7894d1d24148b Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
Diffstat (limited to 'boost/process/pipe.hpp')
-rw-r--r--boost/process/pipe.hpp475
1 files changed, 475 insertions, 0 deletions
diff --git a/boost/process/pipe.hpp b/boost/process/pipe.hpp
new file mode 100644
index 0000000000..8af776f966
--- /dev/null
+++ b/boost/process/pipe.hpp
@@ -0,0 +1,475 @@
+// Copyright (c) 2006, 2007 Julio M. Merino Vidal
+// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
+// Copyright (c) 2009 Boris Schaeling
+// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
+// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_PROCESS_PIPE_HPP
+#define BOOST_PROCESS_PIPE_HPP
+
+#include <boost/config.hpp>
+#include <boost/process/detail/config.hpp>
+#include <streambuf>
+#include <istream>
+#include <ostream>
+#include <vector>
+
+#if defined(BOOST_POSIX_API)
+#include <boost/process/detail/posix/basic_pipe.hpp>
+#elif defined(BOOST_WINDOWS_API)
+#include <boost/process/detail/windows/basic_pipe.hpp>
+#endif
+
+namespace boost { namespace process {
+
+using ::boost::process::detail::api::basic_pipe;
+
+#if defined(BOOST_PROCESS_DOXYGEN)
+/** Class implementation of a pipe.
+ *
+ */
+template<class CharT, class Traits = std::char_traits<CharT>>
+class basic_pipe
+{
+public:
+ typedef CharT char_type ;
+ typedef Traits traits_type;
+ typedef typename Traits::int_type int_type ;
+ typedef typename Traits::pos_type pos_type ;
+ typedef typename Traits::off_type off_type ;
+ typedef ::boost::detail::winapi::HANDLE_ native_handle;
+
+ /// Default construct the pipe. Will be opened.
+ basic_pipe();
+
+ ///Construct a named pipe.
+ inline explicit basic_pipe(const std::string & name);
+ /** Copy construct the pipe.
+ * \note Duplicated the handles.
+ */
+ inline basic_pipe(const basic_pipe& p);
+ /** Move construct the pipe. */
+ basic_pipe(basic_pipe&& lhs);
+ /** Copy assign the pipe.
+ * \note Duplicated the handles.
+ */
+ inline basic_pipe& operator=(const basic_pipe& p);
+ /** Move assign the pipe. */
+ basic_pipe& operator=(basic_pipe&& lhs);
+ /** Destructor closes the handles. */
+ ~basic_pipe();
+ /** Get the native handle of the source. */
+ native_handle native_source() const;
+ /** Get the native handle of the sink. */
+ native_handle native_sink () const;
+
+ /** Assign a new value to the source */
+ void assign_source(native_handle h);
+ /** Assign a new value to the sink */
+ void assign_sink (native_handle h);
+
+
+ ///Write data to the pipe.
+ int_type write(const char_type * data, int_type count);
+ ///Read data from the pipe.
+ int_type read(char_type * data, int_type count);
+ ///Check if the pipe is open.
+ bool is_open();
+ ///Close the pipe
+ void close();
+};
+
+#endif
+
+
+
+typedef basic_pipe<char> pipe;
+typedef basic_pipe<wchar_t> wpipe;
+
+
+/** Implementation of the stream buffer for a pipe.
+ */
+template<
+ class CharT,
+ class Traits = std::char_traits<CharT>
+>
+struct basic_pipebuf : std::basic_streambuf<CharT, Traits>
+{
+ typedef basic_pipe<CharT, Traits> pipe_type;
+
+ typedef CharT char_type ;
+ typedef Traits traits_type;
+ typedef typename Traits::int_type int_type ;
+ typedef typename Traits::pos_type pos_type ;
+ typedef typename Traits::off_type off_type ;
+
+ constexpr static int default_buffer_size = BOOST_PROCESS_PIPE_SIZE;
+
+ ///Default constructor, will also construct the pipe.
+ basic_pipebuf() : _write(default_buffer_size), _read(default_buffer_size)
+ {
+ this->setg(_read.data(), _read.data()+ 128, _read.data() + 128);
+ this->setp(_write.data(), _write.data() + _write.size());
+ }
+ ///Copy Constructor.
+ basic_pipebuf(const basic_pipebuf & ) = default;
+ ///Move Constructor
+ basic_pipebuf(basic_pipebuf && ) = default;
+
+ ///Move construct from a pipe.
+ basic_pipebuf(pipe_type && p) : _pipe(std::move(p)),
+ _write(default_buffer_size),
+ _read(default_buffer_size)
+ {
+ this->setg(_read.data(), _read.data()+ 128, _read.data() + 128);
+ this->setp(_write.data(), _write.data() + _write.size());
+ }
+ ///Construct from a pipe.
+ basic_pipebuf(const pipe_type & p) : _pipe(p),
+ _write(default_buffer_size),
+ _read(default_buffer_size)
+ {
+ this->setg(_read.data(), _read.data()+ 128, _read.data() + 128);
+ this->setp(_write.data(), _write.data() + _write.size());
+ }
+ ///Copy assign.
+ basic_pipebuf& operator=(const basic_pipebuf & ) = delete;
+ ///Move assign.
+ basic_pipebuf& operator=(basic_pipebuf && ) = default;
+ ///Move assign a pipe.
+ basic_pipebuf& operator=(pipe_type && p)
+ {
+ _pipe = std::move(p);
+ return *this;
+ }
+ ///Copy assign a pipe.
+ basic_pipebuf& operator=(const pipe_type & p)
+ {
+ _pipe = p;
+ return *this;
+ }
+ ///Writes characters to the associated output sequence from the put area
+ int_type overflow(int_type ch = traits_type::eof()) override
+ {
+ if ((ch != traits_type::eof()) && _pipe.is_open())
+ {
+ if (this->pptr() == this->epptr())
+ {
+ bool wr = this->_write_impl();
+ *this->pptr() = ch;
+ this->pbump(1);
+ if (wr)
+ return ch;
+ }
+ else
+ {
+ *this->pptr() = ch;
+ this->pbump(1);
+ if (this->_write_impl())
+ return ch;
+ }
+ }
+ return traits_type::eof();
+ }
+ ///Synchronizes the buffers with the associated character sequence
+ int sync() override { return this->_write_impl() ? 0 : -1; }
+
+ ///Reads characters from the associated input sequence to the get area
+ int_type underflow() override
+ {
+ if (!_pipe.is_open())
+ return traits_type::eof();
+
+ if (this->egptr() == &_read.back()) //ok, so we're at the end of the buffer
+ this->setg(_read.data(), _read.data()+ 10, _read.data() + 10);
+
+
+ auto len = &_read.back() - this->egptr() ;
+ auto res = _pipe.read(
+ this->egptr(),
+ static_cast<typename pipe_type::int_type>(len));
+ if (res == 0)
+ return traits_type::eof();
+
+ this->setg(this->eback(), this->gptr(), this->egptr() + res);
+ auto val = *this->gptr();
+
+ return traits_type::to_int_type(val);
+ }
+
+
+ ///Set the pipe of the streambuf.
+ void pipe(pipe_type&& p) {_pipe = std::move(p); }
+ ///Set the pipe of the streambuf.
+ void pipe(const pipe_type& p) {_pipe = p; }
+ ///Get a reference to the pipe.
+ pipe_type & pipe() & {return _pipe;}
+ ///Get a const reference to the pipe.
+ const pipe_type &pipe() const & {return _pipe;}
+ ///Get a rvalue reference to the pipe. Qualified as rvalue.
+ pipe_type && pipe() && {return std::move(_pipe);}
+private:
+ pipe_type _pipe;
+ std::vector<char_type> _write;
+ std::vector<char_type> _read;
+
+ bool _write_impl()
+ {
+ if (!_pipe.is_open())
+ return false;
+
+ auto base = this->pbase();
+ auto wrt = _pipe.write(base,
+ static_cast<typename pipe_type::int_type>(this->pptr() - base));
+ std::ptrdiff_t diff = this->pptr() - base;
+
+ if (wrt < diff)
+ std::move(base + wrt, base + diff, base);
+ else if (wrt == 0) //broken pipe
+ return false;
+
+ this->pbump(-wrt);
+
+ return true;
+ }
+};
+
+typedef basic_pipebuf<char> pipebuf;
+typedef basic_pipebuf<wchar_t> wpipebuf;
+
+/** Implementation of a reading pipe stream.
+ *
+ */
+template<
+ class CharT,
+ class Traits = std::char_traits<CharT>
+>
+class basic_ipstream : public std::basic_istream<CharT, Traits>
+{
+ basic_pipebuf<CharT, Traits> _buf;
+public:
+
+ typedef basic_pipe<CharT, Traits> pipe_type;
+
+ typedef CharT char_type ;
+ typedef Traits traits_type;
+ typedef typename Traits::int_type int_type ;
+ typedef typename Traits::pos_type pos_type ;
+ typedef typename Traits::off_type off_type ;
+
+ ///Get access to the underlying stream_buf
+ basic_pipebuf<CharT, Traits>* rdbuf() const {return _buf;};
+
+ ///Default constructor.
+ basic_ipstream() : std::basic_istream<CharT, Traits>(nullptr)
+ {
+ std::basic_istream<CharT, Traits>::rdbuf(&_buf);
+ };
+ ///Copy constructor.
+ basic_ipstream(const basic_ipstream & ) = delete;
+ ///Move constructor.
+ basic_ipstream(basic_ipstream && ) = default;
+
+ ///Move construct from a pipe.
+ basic_ipstream(pipe_type && p) : std::basic_istream<CharT, Traits>(nullptr), _buf(std::move(p))
+ {
+ std::basic_istream<CharT, Traits>::rdbuf(&_buf);
+ }
+
+ ///Copy construct from a pipe.
+ basic_ipstream(const pipe_type & p) : std::basic_istream<CharT, Traits>(nullptr), _buf(p)
+ {
+ std::basic_istream<CharT, Traits>::rdbuf(&_buf);
+ }
+
+ ///Copy assignment.
+ basic_ipstream& operator=(const basic_ipstream & ) = delete;
+ ///Move assignment
+ basic_ipstream& operator=(basic_ipstream && ) = default;
+ ///Move assignment of a pipe.
+ basic_ipstream& operator=(pipe_type && p)
+ {
+ _buf = std::move(p);
+ return *this;
+ }
+ ///Copy assignment of a pipe.
+ basic_ipstream& operator=(const pipe_type & p)
+ {
+ _buf = p;
+ return *this;
+ }
+ ///Set the pipe of the streambuf.
+ void pipe(pipe_type&& p) {_buf.pipe(std::move(p)); }
+ ///Set the pipe of the streambuf.
+ void pipe(const pipe_type& p) {_buf.pipe(p); }
+ ///Get a reference to the pipe.
+ pipe_type & pipe() & {return _buf.pipe();}
+ ///Get a const reference to the pipe.
+ const pipe_type &pipe() const & {return _buf.pipe();}
+ ///Get a rvalue reference to the pipe. Qualified as rvalue.
+ pipe_type && pipe() && {return std::move(_buf).pipe();}
+};
+
+typedef basic_ipstream<char> ipstream;
+typedef basic_ipstream<wchar_t> wipstream;
+
+/** Implementation of a write pipe stream.
+ *
+ */
+template<
+ class CharT,
+ class Traits = std::char_traits<CharT>
+>
+class basic_opstream : public std::basic_ostream<CharT, Traits>
+{
+ basic_pipebuf<CharT, Traits> _buf;
+public:
+ typedef basic_pipe<CharT, Traits> pipe_type;
+
+ typedef CharT char_type ;
+ typedef Traits traits_type;
+ typedef typename Traits::int_type int_type ;
+ typedef typename Traits::pos_type pos_type ;
+ typedef typename Traits::off_type off_type ;
+
+
+ ///Get access to the underlying stream_buf
+ basic_pipebuf<CharT, Traits>* rdbuf() const {return _buf;};
+
+ ///Default constructor.
+ basic_opstream() : std::basic_ostream<CharT, Traits>(nullptr)
+ {
+ std::basic_ostream<CharT, Traits>::rdbuf(&_buf);
+ };
+ ///Copy constructor.
+ basic_opstream(const basic_opstream & ) = delete;
+ ///Move constructor.
+ basic_opstream(basic_opstream && ) = default;
+
+ ///Move construct from a pipe.
+ basic_opstream(pipe_type && p) : std::basic_ostream<CharT, Traits>(nullptr), _buf(std::move(p))
+ {
+ std::basic_ostream<CharT, Traits>::rdbuf(&_buf);
+ };
+ ///Copy construct from a pipe.
+ basic_opstream(const pipe_type & p) : std::basic_ostream<CharT, Traits>(nullptr), _buf(p)
+ {
+ std::basic_ostream<CharT, Traits>::rdbuf(&_buf);
+ };
+ ///Copy assignment.
+ basic_opstream& operator=(const basic_opstream & ) = delete;
+ ///Move assignment
+ basic_opstream& operator=(basic_opstream && ) = default;
+ ///Move assignment of a pipe.
+ basic_opstream& operator=(pipe_type && p)
+ {
+ _buf = std::move(p);
+ return *this;
+ }
+ ///Copy assignment of a pipe.
+ basic_opstream& operator=(const pipe_type & p)
+ {
+ _buf = p;
+ return *this;
+ }
+ ///Set the pipe of the streambuf.
+ void pipe(pipe_type&& p) {_buf.pipe(std::move(p)); }
+ ///Set the pipe of the streambuf.
+ void pipe(const pipe_type& p) {_buf.pipe(p); }
+ ///Get a reference to the pipe.
+ pipe_type & pipe() & {return _buf.pipe();}
+ ///Get a const reference to the pipe.
+ const pipe_type &pipe() const & {return _buf.pipe();}
+ ///Get a rvalue reference to the pipe. Qualified as rvalue.
+ pipe_type && pipe() && {return std::move(_buf).pipe();}
+};
+
+typedef basic_opstream<char> opstream;
+typedef basic_opstream<wchar_t> wopstream;
+
+
+/** Implementation of a read-write pipe stream.
+ *
+ */
+template<
+ class CharT,
+ class Traits = std::char_traits<CharT>
+>
+class basic_pstream : public std::basic_iostream<CharT, Traits>
+{
+ basic_pipebuf<CharT, Traits> _buf;
+public:
+ typedef basic_pipe<CharT, Traits> pipe_type;
+
+ typedef CharT char_type ;
+ typedef Traits traits_type;
+ typedef typename Traits::int_type int_type ;
+ typedef typename Traits::pos_type pos_type ;
+ typedef typename Traits::off_type off_type ;
+
+
+ ///Get access to the underlying stream_buf
+ basic_pipebuf<CharT, Traits>* rdbuf() const {return _buf;};
+
+ ///Default constructor.
+ basic_pstream() : std::basic_iostream<CharT, Traits>(nullptr)
+ {
+ std::basic_iostream<CharT, Traits>::rdbuf(&_buf);
+ };
+ ///Copy constructor.
+ basic_pstream(const basic_pstream & ) = delete;
+ ///Move constructor.
+ basic_pstream(basic_pstream && ) = default;
+
+ ///Move construct from a pipe.
+ basic_pstream(pipe_type && p) : std::basic_iostream<CharT, Traits>(nullptr), _buf(std::move(p))
+ {
+ std::basic_iostream<CharT, Traits>::rdbuf(&_buf);
+ };
+ ///Copy construct from a pipe.
+ basic_pstream(const pipe_type & p) : std::basic_iostream<CharT, Traits>(nullptr), _buf(p)
+ {
+ std::basic_iostream<CharT, Traits>::rdbuf(&_buf);
+ };
+ ///Copy assignment.
+ basic_pstream& operator=(const basic_pstream & ) = delete;
+ ///Move assignment
+ basic_pstream& operator=(basic_pstream && ) = default;
+ ///Move assignment of a pipe.
+ basic_pstream& operator=(pipe_type && p)
+ {
+ _buf = std::move(p);
+ return *this;
+ }
+ ///Copy assignment of a pipe.
+ basic_pstream& operator=(const pipe_type & p)
+ {
+ _buf = p;
+ return *this;
+ }
+ ///Set the pipe of the streambuf.
+ void pipe(pipe_type&& p) {_buf.pipe(std::move(p)); }
+ ///Set the pipe of the streambuf.
+ void pipe(const pipe_type& p) {_buf.pipe(p); }
+ ///Get a reference to the pipe.
+ pipe_type & pipe() & {return _buf.pipe();}
+ ///Get a const reference to the pipe.
+ const pipe_type &pipe() const & {return _buf.pipe();}
+ ///Get a rvalue reference to the pipe. Qualified as rvalue.
+ pipe_type && pipe() && {return std::move(_buf).pipe();}
+};
+
+typedef basic_pstream<char> pstream;
+typedef basic_pstream<wchar_t> wpstream;
+
+
+
+}}
+
+
+
+#endif