Warning, file /include/boost/process/v1/detail/posix/pipe_out.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_PROCESS_DETAIL_POSIX_PIPE_OUT_HPP
0012 #define BOOST_PROCESS_DETAIL_POSIX_PIPE_OUT_HPP
0013
0014 #include <boost/process/v1/pipe.hpp>
0015 #include <boost/process/v1/detail/posix/handler.hpp>
0016 #include <unistd.h>
0017 #include <array>
0018 #include <boost/process/v1/detail/used_handles.hpp>
0019
0020 namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace posix {
0021
0022 template<int p1, int p2>
0023 struct pipe_out : handler_base_ext, ::boost::process::v1::detail::uses_handles
0024 {
0025 int sink;
0026 int source;
0027
0028 std::array<int, 4> get_used_handles()
0029 {
0030 const auto pp1 = p1 != -1 ? p1 : p2;
0031 const auto pp2 = p2 != -1 ? p2 : p1;
0032
0033 return {source, sink, pp1, pp2};
0034 }
0035
0036 pipe_out(int sink, int source) : sink(sink), source(source) {}
0037
0038 template<typename T>
0039 pipe_out(T & p) : sink(p.native_sink()), source(p.native_source())
0040 {
0041 p.assign_sink(-1);
0042 }
0043
0044 template<typename Executor>
0045 void on_error(Executor &, const std::error_code &) const
0046 {
0047 ::close(sink);
0048 }
0049
0050 template<typename Executor>
0051 void on_success(Executor &) const
0052 {
0053 ::close(sink);
0054 }
0055
0056 template <typename Executor>
0057 void on_exec_setup(Executor &e) const;
0058 };
0059
0060 template<>
0061 template<typename Executor>
0062 void pipe_out<1,-1>::on_exec_setup(Executor &e) const
0063 {
0064 if (::dup2(sink, STDOUT_FILENO) == -1)
0065 e.set_error(::boost::process::v1::detail::get_last_error(), "dup2() failed");
0066
0067 if (sink != STDOUT_FILENO)
0068 ::close(sink);
0069 ::close(source);
0070 }
0071
0072 template<>
0073 template<typename Executor>
0074 void pipe_out<2,-1>::on_exec_setup(Executor &e) const
0075 {
0076 if (::dup2(sink, STDERR_FILENO) == -1)
0077 e.set_error(::boost::process::v1::detail::get_last_error(), "dup2() failed");
0078
0079 if (sink != STDOUT_FILENO)
0080 ::close(sink);
0081 ::close(source);
0082 }
0083
0084 template<>
0085 template<typename Executor>
0086 void pipe_out<1,2>::on_exec_setup(Executor &e) const
0087 {
0088 if (::dup2(sink, STDOUT_FILENO) == -1)
0089 e.set_error(::boost::process::v1::detail::get_last_error(), "dup2() failed");
0090 if (::dup2(sink, STDERR_FILENO) == -1)
0091 e.set_error(::boost::process::v1::detail::get_last_error(), "dup2() failed");
0092 if ((sink != STDOUT_FILENO) && (sink != STDERR_FILENO))
0093 ::close(sink);
0094 ::close(source);
0095 }
0096
0097 class async_pipe;
0098
0099 template<int p1, int p2>
0100 struct async_pipe_out : public pipe_out<p1, p2>
0101 {
0102 async_pipe &pipe;
0103 template<typename AsyncPipe>
0104 async_pipe_out(AsyncPipe & p) : pipe_out<p1, p2>(p.native_sink(), p.native_source()), pipe(p)
0105 {
0106 }
0107
0108 template<typename Pipe, typename Executor>
0109 static void close(Pipe & pipe, Executor &)
0110 {
0111 boost::system::error_code ec;
0112 std::move(pipe).sink().close(ec);
0113 }
0114
0115 template<typename Executor>
0116 void on_error(Executor & exec, const std::error_code &)
0117 {
0118 close(pipe, exec);
0119 }
0120
0121 template<typename Executor>
0122 void on_success(Executor &exec)
0123 {
0124 close(pipe, exec);
0125 }
0126 };
0127
0128
0129 }}}}}
0130
0131 #endif