]>
Commit | Line | Data |
---|---|---|
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 | // Copyright (c) 2016 Klemens D. Morgenstern | |
7 | // | |
8 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | |
9 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
10 | ||
11 | #ifndef BOOST_PROCESS_DETAIL_POSIX_PIPE_OUT_HPP | |
12 | #define BOOST_PROCESS_DETAIL_POSIX_PIPE_OUT_HPP | |
13 | ||
14 | #include <boost/process/pipe.hpp> | |
15 | #include <boost/process/detail/posix/handler.hpp> | |
16 | #include <unistd.h> | |
17 | ||
18 | namespace boost { namespace process { namespace detail { namespace posix { | |
19 | ||
20 | template<int p1, int p2> | |
21 | struct pipe_out : handler_base_ext | |
22 | { | |
23 | int sink; | |
24 | int source; //opposite end | |
25 | ||
26 | pipe_out(int sink, int source) : sink(sink), source(source) {} | |
27 | ||
28 | template<typename T> | |
29 | pipe_out(T & p) : sink(p.native_sink()), source(p.native_source()) | |
30 | { | |
31 | p.assign_sink(-1); | |
32 | } | |
33 | ||
34 | template<typename Executor> | |
35 | void on_error(Executor &, const std::error_code &) const | |
36 | { | |
37 | ::close(sink); | |
38 | } | |
39 | ||
40 | template<typename Executor> | |
41 | void on_success(Executor &) const | |
42 | { | |
43 | ::close(sink); | |
44 | } | |
45 | ||
46 | template <typename Executor> | |
47 | void on_exec_setup(Executor &e) const; | |
48 | }; | |
49 | ||
50 | template<> | |
51 | template<typename Executor> | |
52 | void pipe_out<1,-1>::on_exec_setup(Executor &e) const | |
53 | { | |
54 | if (::dup2(sink, STDOUT_FILENO) == -1) | |
92f5a8d4 TL |
55 | e.set_error(::boost::process::detail::get_last_error(), "dup2() failed"); |
56 | ||
57 | if (sink != STDOUT_FILENO) | |
58 | ::close(sink); | |
b32b8144 FG |
59 | ::close(source); |
60 | } | |
61 | ||
62 | template<> | |
63 | template<typename Executor> | |
64 | void pipe_out<2,-1>::on_exec_setup(Executor &e) const | |
65 | { | |
66 | if (::dup2(sink, STDERR_FILENO) == -1) | |
67 | e.set_error(::boost::process::detail::get_last_error(), "dup2() failed"); | |
92f5a8d4 TL |
68 | |
69 | if (sink != STDOUT_FILENO) | |
70 | ::close(sink); | |
b32b8144 FG |
71 | ::close(source); |
72 | } | |
73 | ||
74 | template<> | |
75 | template<typename Executor> | |
76 | void pipe_out<1,2>::on_exec_setup(Executor &e) const | |
77 | { | |
78 | if (::dup2(sink, STDOUT_FILENO) == -1) | |
79 | e.set_error(::boost::process::detail::get_last_error(), "dup2() failed"); | |
80 | if (::dup2(sink, STDERR_FILENO) == -1) | |
81 | e.set_error(::boost::process::detail::get_last_error(), "dup2() failed"); | |
92f5a8d4 TL |
82 | if ((sink != STDOUT_FILENO) && (sink != STDERR_FILENO)) |
83 | ::close(sink); | |
b32b8144 FG |
84 | } |
85 | ||
86 | class async_pipe; | |
87 | ||
88 | template<int p1, int p2> | |
89 | struct async_pipe_out : public pipe_out<p1, p2> | |
90 | { | |
91 | async_pipe &pipe; | |
92 | template<typename AsyncPipe> | |
93 | async_pipe_out(AsyncPipe & p) : pipe_out<p1, p2>(p.native_sink(), p.native_source()), pipe(p) | |
94 | { | |
95 | } | |
96 | ||
97 | template<typename Pipe, typename Executor> | |
98 | static void close(Pipe & pipe, Executor &) | |
99 | { | |
100 | boost::system::error_code ec; | |
101 | std::move(pipe).sink().close(ec); | |
102 | } | |
103 | ||
104 | template<typename Executor> | |
105 | void on_error(Executor & exec, const std::error_code &) | |
106 | { | |
107 | close(pipe, exec); | |
108 | } | |
109 | ||
110 | template<typename Executor> | |
111 | void on_success(Executor &exec) | |
112 | { | |
113 | close(pipe, exec); | |
114 | } | |
115 | }; | |
116 | ||
117 | ||
118 | }}}} | |
119 | ||
120 | #endif |