552 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			552 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| 
								 | 
							
								// Copyright (c) 2016 Klemens D. Morgenstern
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// 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_IO_HPP_
							 | 
						||
| 
								 | 
							
								#define BOOST_PROCESS_IO_HPP_
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <iosfwd>
							 | 
						||
| 
								 | 
							
								#include <cstdio>
							 | 
						||
| 
								 | 
							
								#include <functional>
							 | 
						||
| 
								 | 
							
								#include <utility>
							 | 
						||
| 
								 | 
							
								#include <boost/process/detail/config.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/process/pipe.hpp>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <future>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if defined(BOOST_POSIX_API)
							 | 
						||
| 
								 | 
							
								#include <boost/process/detail/posix/asio_fwd.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/process/detail/posix/close_in.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/process/detail/posix/close_out.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/process/detail/posix/null_in.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/process/detail/posix/null_out.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/process/detail/posix/file_in.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/process/detail/posix/file_out.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/process/detail/posix/pipe_in.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/process/detail/posix/pipe_out.hpp>
							 | 
						||
| 
								 | 
							
								#elif defined(BOOST_WINDOWS_API)
							 | 
						||
| 
								 | 
							
								#include <boost/process/detail/windows/asio_fwd.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/process/detail/windows/close_in.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/process/detail/windows/close_out.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/process/detail/windows/null_in.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/process/detail/windows/null_out.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/process/detail/windows/file_in.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/process/detail/windows/file_out.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/process/detail/windows/pipe_in.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/process/detail/windows/pipe_out.hpp>
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/** \file boost/process/io.hpp
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 *    Header which provides the io properties. It provides the following properties:
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								\xmlonly
							 | 
						||
| 
								 | 
							
								<programlisting>
							 | 
						||
| 
								 | 
							
								namespace boost {
							 | 
						||
| 
								 | 
							
								  namespace process {
							 | 
						||
| 
								 | 
							
								    <emphasis>unspecified</emphasis> <globalname alt="boost::process::close">close</globalname>;
							 | 
						||
| 
								 | 
							
								    <emphasis>unspecified</emphasis> <globalname alt="boost::process::null">null</globalname>;
							 | 
						||
| 
								 | 
							
								    <emphasis>unspecified</emphasis> <globalname alt="boost::process::std_in">std_in</globalname>;
							 | 
						||
| 
								 | 
							
								    <emphasis>unspecified</emphasis> <globalname alt="boost::process::std_out">std_out</globalname>;
							 | 
						||
| 
								 | 
							
								    <emphasis>unspecified</emphasis> <globalname alt="boost::process::std_err">std_err</globalname>;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								</programlisting>
							 | 
						||
| 
								 | 
							
								\endxmlonly
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\par File I/O
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The library allows full redirection of streams to files as shown below.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\code{.cpp}
							 | 
						||
| 
								 | 
							
								boost::filesystem::path log    = "my_log_file.txt";
							 | 
						||
| 
								 | 
							
								boost::filesystem::path input  = "input.txt";
							 | 
						||
| 
								 | 
							
								boost::filesystem::path output = "output.txt";
							 | 
						||
| 
								 | 
							
								system("my_prog", std_out>output, std_in<input, std_err>log);
							 | 
						||
| 
								 | 
							
								\endcode
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\par Synchronous Pipe I/O
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Another way is to communicate through pipes.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\code{.cpp}
							 | 
						||
| 
								 | 
							
								pstream str;
							 | 
						||
| 
								 | 
							
								child c("my_prog", std_out > str);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int i;
							 | 
						||
| 
								 | 
							
								str >> i;
							 | 
						||
| 
								 | 
							
								\endcode
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Note that the pipe may also be used between several processes, like this:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\code{.cpp}
							 | 
						||
| 
								 | 
							
								pipe p;
							 | 
						||
| 
								 | 
							
								child c1("nm", "a.out", std_out>p);
							 | 
						||
| 
								 | 
							
								child c2("c++filt", std_in<p);
							 | 
						||
| 
								 | 
							
								\endcode
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\par Asynchronous I/O
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Utilizing `boost.asio` asynchronous I/O is provided.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\code
							 | 
						||
| 
								 | 
							
								boost::asio::io_context ios;
							 | 
						||
| 
								 | 
							
								std::future<std::string> output;
							 | 
						||
| 
								 | 
							
								system("ls", std_out > output, ios);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								auto res = fut.get();
							 | 
						||
| 
								 | 
							
								\endcode
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\note `boost/process/async.hpp` must also be included for this to work.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\par Closing
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Stream can be closed, so nothing can be read or written.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\code{.cpp}
							 | 
						||
| 
								 | 
							
								system("foo", std_in.close());
							 | 
						||
| 
								 | 
							
								\endcode
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\par Null
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Streams can be redirected to null, which means, that written date will be
							 | 
						||
| 
								 | 
							
								discarded and read data will only contain `EOF`.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\code{.cpp}
							 | 
						||
| 
								 | 
							
								system("b2", std_out > null);
							 | 
						||
| 
								 | 
							
								\endcode
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace boost { namespace process { namespace detail {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template<typename T> using is_streambuf    = typename std::is_same<T, boost::asio::streambuf>::type;
							 | 
						||
| 
								 | 
							
								template<typename T> using is_const_buffer =
							 | 
						||
| 
								 | 
							
								        std::integral_constant<bool,
							 | 
						||
| 
								 | 
							
								            std::is_same<   boost::asio::const_buffer, T>::value |
							 | 
						||
| 
								 | 
							
								            std::is_base_of<boost::asio::const_buffer, T>::value
							 | 
						||
| 
								 | 
							
								        >;
							 | 
						||
| 
								 | 
							
								template<typename T> using is_mutable_buffer =
							 | 
						||
| 
								 | 
							
								        std::integral_constant<bool,
							 | 
						||
| 
								 | 
							
								            std::is_same<   boost::asio::mutable_buffer, T>::value |
							 | 
						||
| 
								 | 
							
								            std::is_base_of<boost::asio::mutable_buffer, T>::value
							 | 
						||
| 
								 | 
							
								        >;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								struct null_t  {constexpr null_t() = default;};
							 | 
						||
| 
								 | 
							
								struct close_t;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template<class>
							 | 
						||
| 
								 | 
							
								struct std_in_
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    constexpr std_in_() = default;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    api::close_in close() const {return api::close_in(); }
							 | 
						||
| 
								 | 
							
								    api::close_in operator=(const close_t &) const {return api::close_in();}
							 | 
						||
| 
								 | 
							
								    api::close_in operator<(const close_t &) const {return api::close_in();}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    api::null_in null() const {return api::null_in();}
							 | 
						||
| 
								 | 
							
								    api::null_in operator=(const null_t &) const {return api::null_in();}
							 | 
						||
| 
								 | 
							
								    api::null_in operator<(const null_t &) const {return api::null_in();}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    api::file_in operator=(const boost::filesystem::path &p) const {return p;}
							 | 
						||
| 
								 | 
							
								    api::file_in operator=(const std::string & p)            const {return p;}
							 | 
						||
| 
								 | 
							
								    api::file_in operator=(const std::wstring &p)            const {return p;}
							 | 
						||
| 
								 | 
							
								    api::file_in operator=(const char * p)                   const {return p;}
							 | 
						||
| 
								 | 
							
								    api::file_in operator=(const wchar_t * p)                const {return p;}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    api::file_in operator<(const boost::filesystem::path &p) const {return p;}
							 | 
						||
| 
								 | 
							
								    api::file_in operator<(const std::string &p)             const {return p;}
							 | 
						||
| 
								 | 
							
								    api::file_in operator<(const std::wstring &p)            const {return p;}
							 | 
						||
| 
								 | 
							
								    api::file_in operator<(const char*p)                     const {return p;}
							 | 
						||
| 
								 | 
							
								    api::file_in operator<(const wchar_t * p)                const {return p;}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    api::file_in operator=(FILE * f)                         const {return f;}
							 | 
						||
| 
								 | 
							
								    api::file_in operator<(FILE * f)                         const {return f;}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    template<typename Char, typename Traits> api::pipe_in operator=(basic_pipe<Char, Traits> & p)      const {return p;}
							 | 
						||
| 
								 | 
							
								    template<typename Char, typename Traits> api::pipe_in operator<(basic_pipe<Char, Traits> & p)      const {return p;}
							 | 
						||
| 
								 | 
							
								    template<typename Char, typename Traits> api::pipe_in operator=(basic_opstream<Char, Traits> & p)  const {return p.pipe();}
							 | 
						||
| 
								 | 
							
								    template<typename Char, typename Traits> api::pipe_in operator<(basic_opstream<Char, Traits> & p)  const {return p.pipe();}
							 | 
						||
| 
								 | 
							
								    template<typename Char, typename Traits> api::pipe_in operator=(basic_pstream <Char, Traits> & p)  const {return p.pipe();}
							 | 
						||
| 
								 | 
							
								    template<typename Char, typename Traits> api::pipe_in operator<(basic_pstream <Char, Traits> & p)  const {return p.pipe();}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    api::async_pipe_in operator=(async_pipe & p) const {return p;}
							 | 
						||
| 
								 | 
							
								    api::async_pipe_in operator<(async_pipe & p) const {return p;}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    template<typename T, typename = typename std::enable_if<
							 | 
						||
| 
								 | 
							
								            is_const_buffer<T>::value || is_mutable_buffer<T>::value
							 | 
						||
| 
								 | 
							
								            >::type>
							 | 
						||
| 
								 | 
							
								    api::async_in_buffer<const T> operator=(const T & buf) const {return buf;}
							 | 
						||
| 
								 | 
							
								    template<typename T, typename = typename std::enable_if<is_streambuf<T>::value>::type >
							 | 
						||
| 
								 | 
							
								    api::async_in_buffer<T>       operator=(T       & buf) const {return buf;}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    template<typename T, typename = typename std::enable_if<
							 | 
						||
| 
								 | 
							
								            is_const_buffer<T>::value || is_mutable_buffer<T>::value
							 | 
						||
| 
								 | 
							
								            >::type>
							 | 
						||
| 
								 | 
							
								    api::async_in_buffer<const T> operator<(const T & buf) const {return buf;}
							 | 
						||
| 
								 | 
							
								    template<typename T, typename = typename std::enable_if<is_streambuf<T>::value>::type >
							 | 
						||
| 
								 | 
							
								    api::async_in_buffer<T>       operator<(T       & buf) const {return buf;}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//-1 == empty.
							 | 
						||
| 
								 | 
							
								//1 == stdout
							 | 
						||
| 
								 | 
							
								//2 == stderr
							 | 
						||
| 
								 | 
							
								template<int p1, int p2 = -1>
							 | 
						||
| 
								 | 
							
								struct std_out_
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    constexpr std_out_() = default;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    api::close_out<p1,p2> close() const {return api::close_out<p1,p2>(); }
							 | 
						||
| 
								 | 
							
								    api::close_out<p1,p2> operator=(const close_t &) const {return api::close_out<p1,p2>();}
							 | 
						||
| 
								 | 
							
								    api::close_out<p1,p2> operator>(const close_t &) const {return api::close_out<p1,p2>();}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    api::null_out<p1,p2> null() const {return api::null_out<p1,p2>();}
							 | 
						||
| 
								 | 
							
								    api::null_out<p1,p2> operator=(const null_t &) const {return api::null_out<p1,p2>();}
							 | 
						||
| 
								 | 
							
								    api::null_out<p1,p2> operator>(const null_t &) const {return api::null_out<p1,p2>();}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    api::file_out<p1,p2> operator=(const boost::filesystem::path &p) const {return api::file_out<p1,p2>(p);}
							 | 
						||
| 
								 | 
							
								    api::file_out<p1,p2> operator=(const std::string &p)             const {return api::file_out<p1,p2>(p);}
							 | 
						||
| 
								 | 
							
								    api::file_out<p1,p2> operator=(const std::wstring &p)            const {return api::file_out<p1,p2>(p);}
							 | 
						||
| 
								 | 
							
								    api::file_out<p1,p2> operator=(const char * p)                   const {return api::file_out<p1,p2>(p);}
							 | 
						||
| 
								 | 
							
								    api::file_out<p1,p2> operator=(const wchar_t * p)                const {return api::file_out<p1,p2>(p);}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    api::file_out<p1,p2> operator>(const boost::filesystem::path &p) const {return api::file_out<p1,p2>(p);}
							 | 
						||
| 
								 | 
							
								    api::file_out<p1,p2> operator>(const std::string &p)             const {return api::file_out<p1,p2>(p);}
							 | 
						||
| 
								 | 
							
								    api::file_out<p1,p2> operator>(const std::wstring &p)            const {return api::file_out<p1,p2>(p);}
							 | 
						||
| 
								 | 
							
								    api::file_out<p1,p2> operator>(const char * p)                   const {return api::file_out<p1,p2>(p);}
							 | 
						||
| 
								 | 
							
								    api::file_out<p1,p2> operator>(const wchar_t * p)                const {return api::file_out<p1,p2>(p);}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    api::file_out<p1,p2> operator=(FILE * f)  const {return f;}
							 | 
						||
| 
								 | 
							
								    api::file_out<p1,p2> operator>(FILE * f)  const {return f;}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    template<typename Char, typename Traits> api::pipe_out<p1,p2> operator=(basic_pipe<Char, Traits> & p)      const {return p;}
							 | 
						||
| 
								 | 
							
								    template<typename Char, typename Traits> api::pipe_out<p1,p2> operator>(basic_pipe<Char, Traits> & p)      const {return p;}
							 | 
						||
| 
								 | 
							
								    template<typename Char, typename Traits> api::pipe_out<p1,p2> operator=(basic_ipstream<Char, Traits> & p)  const {return p.pipe();}
							 | 
						||
| 
								 | 
							
								    template<typename Char, typename Traits> api::pipe_out<p1,p2> operator>(basic_ipstream<Char, Traits> & p)  const {return p.pipe();}
							 | 
						||
| 
								 | 
							
								    template<typename Char, typename Traits> api::pipe_out<p1,p2> operator=(basic_pstream <Char, Traits> & p)  const {return p.pipe();}
							 | 
						||
| 
								 | 
							
								    template<typename Char, typename Traits> api::pipe_out<p1,p2> operator>(basic_pstream <Char, Traits> & p)  const {return p.pipe();}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    api::async_pipe_out<p1, p2> operator=(async_pipe & p) const {return p;}
							 | 
						||
| 
								 | 
							
								    api::async_pipe_out<p1, p2> operator>(async_pipe & p) const {return p;}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    api::async_out_buffer<p1, p2, const asio::mutable_buffer>     operator=(const asio::mutable_buffer & buf)     const {return buf;}
							 | 
						||
| 
								 | 
							
								    api::async_out_buffer<p1, p2, const asio::mutable_buffers_1> operator=(const asio::mutable_buffers_1 & buf) const {return buf;}
							 | 
						||
| 
								 | 
							
								    api::async_out_buffer<p1, p2, asio::streambuf>               operator=(asio::streambuf & os)                   const {return os ;}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    api::async_out_buffer<p1, p2, const asio::mutable_buffer>     operator>(const asio::mutable_buffer & buf)     const {return buf;}
							 | 
						||
| 
								 | 
							
								    api::async_out_buffer<p1, p2, const asio::mutable_buffers_1> operator>(const asio::mutable_buffers_1 & buf) const {return buf;}
							 | 
						||
| 
								 | 
							
								    api::async_out_buffer<p1, p2, asio::streambuf>               operator>(asio::streambuf & os)                   const {return os ;}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    api::async_out_future<p1,p2, std::string>       operator=(std::future<std::string> & fut)       const { return fut;}
							 | 
						||
| 
								 | 
							
								    api::async_out_future<p1,p2, std::string>       operator>(std::future<std::string> & fut)       const { return fut;}
							 | 
						||
| 
								 | 
							
								    api::async_out_future<p1,p2, std::vector<char>> operator=(std::future<std::vector<char>> & fut) const { return fut;}
							 | 
						||
| 
								 | 
							
								    api::async_out_future<p1,p2, std::vector<char>> operator>(std::future<std::vector<char>> & fut) const { return fut;}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    template<int pin, typename = typename std::enable_if<
							 | 
						||
| 
								 | 
							
								            (((p1 == 1) && (pin == 2)) ||
							 | 
						||
| 
								 | 
							
								             ((p1 == 2) && (pin == 1)))
							 | 
						||
| 
								 | 
							
								             && (p2 == -1)>::type>
							 | 
						||
| 
								 | 
							
								    constexpr std_out_<1, 2> operator& (const std_out_<pin>&) const
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return std_out_<1, 2> ();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								struct close_t
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    constexpr close_t() = default;
							 | 
						||
| 
								 | 
							
								    template<int T, int U>
							 | 
						||
| 
								 | 
							
								    api::close_out<T,U> operator()(std_out_<T,U>) {return api::close_out<T,U>();}
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								///This constant is a utility to allow syntax like `std_out > close` for closing I/O streams.
							 | 
						||
| 
								 | 
							
								constexpr boost::process::detail::close_t close;
							 | 
						||
| 
								 | 
							
								///This constant is a utility to redirect streams to the null-device.
							 | 
						||
| 
								 | 
							
								constexpr boost::process::detail::null_t  null;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								This property allows to set the input stream for the child process.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\section stdin_details Details
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\subsection stdin_file File Input
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The file I/O simple redirects the stream to a file, for which the possible types are
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								 - `boost::filesystem::path`
							 | 
						||
| 
								 | 
							
								 - `std::basic_string<char_type>`
							 | 
						||
| 
								 | 
							
								 - `const char_type*`
							 | 
						||
| 
								 | 
							
								 - `FILE*`
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								with `char_type` being either `char` or `wchar_t`.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								FILE* is explicitly added, so the process can easily redirect the output stream
							 | 
						||
| 
								 | 
							
								of the child to another output stream of the process. That is:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\code{.cpp}
							 | 
						||
| 
								 | 
							
								system("ls", std_in < stdin);
							 | 
						||
| 
								 | 
							
								\endcode
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\warning If the launching and the child process use the input, this leads to undefined behaviour.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								A syntax like `system("ls", std_out > std::cerr)` is not possible, due to the C++
							 | 
						||
| 
								 | 
							
								implementation not providing access to the handle.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The valid expressions for this property are
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\code{.cpp}
							 | 
						||
| 
								 | 
							
								std_in < file;
							 | 
						||
| 
								 | 
							
								std_in = file;
							 | 
						||
| 
								 | 
							
								\endcode
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\subsection stdin_pipe Pipe Input
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								As explained in the corresponding section, the boost.process library provides a
							 | 
						||
| 
								 | 
							
								@ref boost::process::async_pipe "async_pipe" class which can be
							 | 
						||
| 
								 | 
							
								used to communicate with child processes.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\note Technically the @ref boost::process::async_pipe "async_pipe"
							 | 
						||
| 
								 | 
							
								works synchronous here, since no asio implementation is used by the library here.
							 | 
						||
| 
								 | 
							
								The async-operation will then however not end if the process is finished, since
							 | 
						||
| 
								 | 
							
								the pipe remains open. You can use the async_close function with on_exit to fix that.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Valid expressions with pipes are these:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\code{.cpp}
							 | 
						||
| 
								 | 
							
								std_in < pipe;
							 | 
						||
| 
								 | 
							
								std_in = pipe;
							 | 
						||
| 
								 | 
							
								\endcode
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Where the valid types for `pipe` are the following:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								 - `basic_pipe`
							 | 
						||
| 
								 | 
							
								 - `async_pipe`
							 | 
						||
| 
								 | 
							
								 - `basic_opstream`
							 | 
						||
| 
								 | 
							
								 - `basic_pstream`
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Note that the pipe may also be used between several processes, like this:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\code{.cpp}
							 | 
						||
| 
								 | 
							
								pipe p;
							 | 
						||
| 
								 | 
							
								child c1("nm", "a.out", std_out>p);
							 | 
						||
| 
								 | 
							
								child c2("c++filt", std_in<p);
							 | 
						||
| 
								 | 
							
								\endcode
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\subsection stdin_async_pipe Asynchronous Pipe Input
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Asynchronous Pipe I/O classifies communication which has automatically handling
							 | 
						||
| 
								 | 
							
								of the asynchronous operations by the process library. This means, that a pipe will be
							 | 
						||
| 
								 | 
							
								constructed, the async_read/-write will be automatically started, and that the
							 | 
						||
| 
								 | 
							
								end of the child process will also close the pipe.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Valid types for pipe I/O are the following:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								 - `boost::asio::const_buffer`   \xmlonly <footnote><para> Constructed with <code>boost::asio::buffer</code></para></footnote> \endxmlonly
							 | 
						||
| 
								 | 
							
								 - `boost::asio::mutable_buffer` \xmlonly <footnote><para> Constructed with <code>boost::asio::buffer</code></para></footnote> \endxmlonly
							 | 
						||
| 
								 | 
							
								 - `boost::asio::streambuf`
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Valid expressions with pipes are these:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\code{.cpp}
							 | 
						||
| 
								 | 
							
								std_in < buffer;
							 | 
						||
| 
								 | 
							
								std_in = buffer;
							 | 
						||
| 
								 | 
							
								std_out > buffer;
							 | 
						||
| 
								 | 
							
								std_out = buffer;
							 | 
						||
| 
								 | 
							
								std_err > buffer;
							 | 
						||
| 
								 | 
							
								std_err = buffer;
							 | 
						||
| 
								 | 
							
								(std_out & std_err) > buffer;
							 | 
						||
| 
								 | 
							
								(std_out & std_err) = buffer;
							 | 
						||
| 
								 | 
							
								\endcode
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\note  It is also possible to get a future for std_in, by chaining another `std::future<void>` onto it,
							 | 
						||
| 
								 | 
							
								so you can wait for the input to be completed. It looks like this:
							 | 
						||
| 
								 | 
							
								\code{.cpp}
							 | 
						||
| 
								 | 
							
								std::future<void> fut;
							 | 
						||
| 
								 | 
							
								boost::asio::io_context ios;
							 | 
						||
| 
								 | 
							
								std::string data;
							 | 
						||
| 
								 | 
							
								child c("prog", std_in < buffer(data) >  fut, ios);
							 | 
						||
| 
								 | 
							
								fut.get();
							 | 
						||
| 
								 | 
							
								\endcode
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\note `boost::asio::buffer` is also available in the `boost::process` namespace.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\warning This feature requires `boost/process/async.hpp` to be included and a reference to `boost::asio::io_context` to be passed to the launching function.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\subsection stdin_close Close
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The input stream can be closed, so it cannot be read from. This will lead to an error when attempted.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This can be achieved by the following syntax.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\code{.cpp}
							 | 
						||
| 
								 | 
							
								std_in < close;
							 | 
						||
| 
								 | 
							
								std_in = close;
							 | 
						||
| 
								 | 
							
								std_in.close();
							 | 
						||
| 
								 | 
							
								\endcode
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\subsection stdin_null Null
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The input stream can be redirected to read from the null-device, which means that only `EOF` is read.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The syntax to achieve that has the following variants:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\code{.cpp}
							 | 
						||
| 
								 | 
							
								std_in < null;
							 | 
						||
| 
								 | 
							
								std_in = null;
							 | 
						||
| 
								 | 
							
								std_in.null();
							 | 
						||
| 
								 | 
							
								\endcode
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								constexpr boost::process::detail::std_in_<void>   std_in;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								This property allows to set the output stream for the child process.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\note The Semantic is the same as for \xmlonly <globalname alt="boost::process::std_err">std_err</globalname> \endxmlonly
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\note `std_err` and `std_out` can be combined into one stream, with the `operator &`, i.e. `std_out & std_err`.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\section stdout_details Details
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\subsection stdout_file File Input
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The file I/O simple redirects the stream to a file, for which the possible types are
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								 - `boost::filesystem::path`
							 | 
						||
| 
								 | 
							
								 - `std::basic_string<char_type>`
							 | 
						||
| 
								 | 
							
								 - `const char_type*`
							 | 
						||
| 
								 | 
							
								 - `FILE*`
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								with `char_type` being either `char` or `wchar_t`.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								FILE* is explicitly added, so the process can easily redirect the output stream
							 | 
						||
| 
								 | 
							
								of the child to another output stream of the process. That is:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\code{.cpp}
							 | 
						||
| 
								 | 
							
								system("ls", std_out < stdin);
							 | 
						||
| 
								 | 
							
								\endcode
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\warning If the launching and the child process use the input, this leads to undefined behaviour.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								A syntax like `system("ls", std_out > std::cerr)` is not possible, due to the C++
							 | 
						||
| 
								 | 
							
								implementation not providing access to the handle.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The valid expressions for this property are
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\code{.cpp}
							 | 
						||
| 
								 | 
							
								std_out < file;
							 | 
						||
| 
								 | 
							
								std_out = file;
							 | 
						||
| 
								 | 
							
								\endcode
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\subsection stdout_pipe Pipe Output
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								As explained in the corresponding section, the boost.process library provides a
							 | 
						||
| 
								 | 
							
								@ref boost::process::async_pipe "async_pipe" class which can be
							 | 
						||
| 
								 | 
							
								used to communicate with child processes.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\note Technically the @ref boost::process::async_pipe "async_pipe"
							 | 
						||
| 
								 | 
							
								works like a synchronous pipe here, since no asio implementation is used by the library here.
							 | 
						||
| 
								 | 
							
								The asynchronous operation will then however not end if the process is finished, since
							 | 
						||
| 
								 | 
							
								the pipe remains open. You can use the async_close function with on_exit to fix that.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Valid expressions with pipes are these:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\code{.cpp}
							 | 
						||
| 
								 | 
							
								std_out > pipe;
							 | 
						||
| 
								 | 
							
								std_out = pipe;
							 | 
						||
| 
								 | 
							
								\endcode
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Where the valid types for `pipe` are the following:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								 - `basic_pipe`
							 | 
						||
| 
								 | 
							
								 - `async_pipe`
							 | 
						||
| 
								 | 
							
								 - `basic_ipstream`
							 | 
						||
| 
								 | 
							
								 - `basic_pstream`
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Note that the pipe may also be used between several processes, like this:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\code{.cpp}
							 | 
						||
| 
								 | 
							
								pipe p;
							 | 
						||
| 
								 | 
							
								child c1("nm", "a.out", std_out>p);
							 | 
						||
| 
								 | 
							
								child c2("c++filt", std_in<p);
							 | 
						||
| 
								 | 
							
								\endcode
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\subsection stdout_async_pipe Asynchronous Pipe Output
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Asynchronous Pipe I/O classifies communication which has automatically handling
							 | 
						||
| 
								 | 
							
								of the async operations by the process library. This means, that a pipe will be
							 | 
						||
| 
								 | 
							
								constructed, the async_read/-write will be automatically started, and that the
							 | 
						||
| 
								 | 
							
								end of the child process will also close the pipe.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Valid types for pipe I/O are the following:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								 - `boost::asio::mutable_buffer` \xmlonly <footnote><para> Constructed with <code>boost::asio::buffer</code></para></footnote> \endxmlonly
							 | 
						||
| 
								 | 
							
								 - `boost::asio::streambuf`
							 | 
						||
| 
								 | 
							
								 - `std::future<std::vector<char>>`
							 | 
						||
| 
								 | 
							
								 - `std::future<std::string>`
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Valid expressions with pipes are these:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\code{.cpp}
							 | 
						||
| 
								 | 
							
								std_out > buffer;
							 | 
						||
| 
								 | 
							
								std_out = buffer;
							 | 
						||
| 
								 | 
							
								std_err > buffer;
							 | 
						||
| 
								 | 
							
								std_err = buffer;
							 | 
						||
| 
								 | 
							
								(std_out & std_err) > buffer;
							 | 
						||
| 
								 | 
							
								(std_out & std_err) = buffer;
							 | 
						||
| 
								 | 
							
								\endcode
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\note `boost::asio::buffer` is also available in the `boost::process` namespace.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\warning This feature requires `boost/process/async.hpp` to be included and a reference to `boost::asio::io_context` to be passed to the launching function.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\subsection stdout_close Close
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The out stream can be closed, so it cannot be write from.
							 | 
						||
| 
								 | 
							
								This will lead to an error when attempted.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This can be achieved by the following syntax.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\code{.cpp}
							 | 
						||
| 
								 | 
							
								std_out > close;
							 | 
						||
| 
								 | 
							
								std_out = close;
							 | 
						||
| 
								 | 
							
								std_out.close();
							 | 
						||
| 
								 | 
							
								\endcode
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\subsection stdout_null Null
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The output stream can be redirected to write to the null-device,
							 | 
						||
| 
								 | 
							
								which means that all output is discarded.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The syntax to achieve that has the following variants:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								\code{.cpp}
							 | 
						||
| 
								 | 
							
								std_out > null;
							 | 
						||
| 
								 | 
							
								std_out = null;
							 | 
						||
| 
								 | 
							
								std_out.null();
							 | 
						||
| 
								 | 
							
								\endcode
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								constexpr boost::process::detail::std_out_<1> std_out;
							 | 
						||
| 
								 | 
							
								/**This property allows setting the `stderr` stream. The semantic and syntax is the same as for
							 | 
						||
| 
								 | 
							
								 * \xmlonly <globalname alt="boost::process::std_out">std_out</globalname> \endxmlonly .
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								constexpr boost::process::detail::std_out_<2> std_err;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}}
							 | 
						||
| 
								 | 
							
								#endif /* INCLUDE_BOOST_PROCESS_IO_HPP_ */
							 |