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_DETAIL_POSIX_FD_HPP 11 #define BOOST_PROCESS_DETAIL_POSIX_FD_HPP 12 13 #include <boost/process/detail/posix/handler.hpp> 14 #include <unistd.h> 15 #include <boost/process/detail/used_handles.hpp> 16 #include <array> 17 18 namespace boost { namespace process { namespace detail { namespace posix { 19 20 21 struct close_fd_ : handler_base_ext, ::boost::process::detail::uses_handles 22 { close_fd_boost::process::detail::posix::close_fd_23 close_fd_(int fd) : fd_(fd) {} 24 25 template <class PosixExecutor> on_exec_setupboost::process::detail::posix::close_fd_26 void on_exec_setup(PosixExecutor& e) const 27 { 28 if (::close(fd_) == -1) 29 e.set_error(::boost::process::detail::get_last_error(), "close() failed"); 30 } 31 get_used_handlesboost::process::detail::posix::close_fd_32 int get_used_handles() {return fd_;} 33 34 35 private: 36 int fd_; 37 }; 38 39 template <class Range> 40 struct close_fds_ : handler_base_ext, ::boost::process::detail::uses_handles 41 { 42 public: close_fds_boost::process::detail::posix::close_fds_43 close_fds_(const Range &fds) : fds_(fds) {} 44 45 template <class PosixExecutor> on_exec_setupboost::process::detail::posix::close_fds_46 void on_exec_setup(PosixExecutor& e) const 47 { 48 for (auto & fd_ : fds_) 49 if (::close(fd_) == -1) 50 { 51 e.set_error(::boost::process::detail::get_last_error(), "close() failed"); 52 break; 53 } 54 } 55 get_used_handlesboost::process::detail::posix::close_fds_56 Range& get_used_handles() {return fds_;} 57 58 private: 59 Range fds_; 60 }; 61 62 63 64 template <class FileDescriptor> 65 struct bind_fd_ : handler_base_ext, ::boost::process::detail::uses_handles 66 { 67 public: bind_fd_boost::process::detail::posix::bind_fd_68 bind_fd_(int id, const FileDescriptor &fd) : id_(id), fd_(fd) {} 69 70 template <class PosixExecutor> on_exec_setupboost::process::detail::posix::bind_fd_71 void on_exec_setup(PosixExecutor& e) const 72 { 73 if (::dup2(fd_, id_) == -1) 74 e.set_error(::boost::process::detail::get_last_error(), "dup2() failed"); 75 } 76 get_used_handlesboost::process::detail::posix::bind_fd_77 std::array<int, 2> get_used_handles() {return {id_, fd_};} 78 79 80 private: 81 int id_; 82 FileDescriptor fd_; 83 }; 84 85 86 struct fd_ 87 { fd_boost::process::detail::posix::fd_88 constexpr fd_() {}; closeboost::process::detail::posix::fd_89 close_fd_ close(int _fd) const {return close_fd_(_fd);} closeboost::process::detail::posix::fd_90 close_fds_<std::vector<int>> close(const std::initializer_list<int> & vec) const {return std::vector<int>(vec);} 91 template<typename Range> closeboost::process::detail::posix::fd_92 close_fds_<Range> close(const Range & r) const {return r;} 93 94 template <class FileDescriptor> bindboost::process::detail::posix::fd_95 bind_fd_<FileDescriptor> bind(int id, const FileDescriptor & fd) const {return {id, fd};} 96 97 }; 98 99 100 }}}} 101 102 #endif 103