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 #ifndef BOOST_PROCESS_POSIX_PIPE_IN_HPP 11 #define BOOST_PROCESS_POSIX_PIPE_IN_HPP 12 13 #include <boost/process/pipe.hpp> 14 #include <boost/process/detail/posix/handler.hpp> 15 #include <unistd.h> 16 #include <boost/process/detail/used_handles.hpp> 17 #include <array> 18 19 namespace boost { namespace process { namespace detail { namespace posix { 20 21 struct pipe_in : handler_base_ext, ::boost::process::detail::uses_handles 22 { 23 int source; 24 int sink; //opposite end 25 pipe_inboost::process::detail::posix::pipe_in26 pipe_in(int sink, int source) : source(source), sink(sink) {} 27 get_used_handlesboost::process::detail::posix::pipe_in28 std::array<int, 3> get_used_handles() 29 { 30 return {{STDIN_FILENO, source, sink}}; 31 } 32 33 34 template<typename T> pipe_inboost::process::detail::posix::pipe_in35 pipe_in(T & p) : source(p.native_source()), sink(p.native_sink()) 36 { 37 p.assign_source(-1); 38 } 39 40 template<typename Executor> on_errorboost::process::detail::posix::pipe_in41 void on_error(Executor &, const std::error_code &) const 42 { 43 ::close(source); 44 } 45 46 template<typename Executor> on_successboost::process::detail::posix::pipe_in47 void on_success(Executor &) const 48 { 49 ::close(source); 50 } 51 52 template <class Executor> on_exec_setupboost::process::detail::posix::pipe_in53 void on_exec_setup(Executor &e) const 54 { 55 if (::dup2(source, STDIN_FILENO) == -1) 56 e.set_error(::boost::process::detail::get_last_error(), "dup2() failed"); 57 if (source != STDIN_FILENO) 58 ::close(source); 59 60 ::close(sink); 61 } 62 63 }; 64 65 class async_pipe; 66 67 struct async_pipe_in : public pipe_in 68 { 69 async_pipe &pipe; 70 71 template<typename AsyncPipe> async_pipe_inboost::process::detail::posix::async_pipe_in72 async_pipe_in(AsyncPipe & p) : pipe_in(p.native_sink(), p.native_source()), pipe(p) 73 { 74 } 75 76 template<typename Pipe, typename Executor> closeboost::process::detail::posix::async_pipe_in77 static void close(Pipe & pipe, Executor &) 78 { 79 boost::system::error_code ec; 80 std::move(pipe).source().close(ec); 81 } 82 83 template<typename Executor> on_errorboost::process::detail::posix::async_pipe_in84 void on_error(Executor & exec, const std::error_code &) 85 { 86 close(pipe, exec); 87 } 88 89 template<typename Executor> on_successboost::process::detail::posix::async_pipe_in90 void on_success(Executor &exec) 91 { 92 close(pipe, exec); 93 } 94 }; 95 96 }}}} 97 98 #endif 99