Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:50:11

0001 // Copyright (c) 2022 Klemens D. Morgenstern
0002 //
0003 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0004 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0005 #ifndef BOOST_PROCESS_V2_POSIX_BIND_FD_HPP
0006 #define BOOST_PROCESS_V2_POSIX_BIND_FD_HPP
0007 
0008 #include <boost/process/v2/detail/config.hpp>
0009 #include <boost/process/v2/default_launcher.hpp>
0010 
0011 #include <fcntl.h>
0012 
0013 BOOST_PROCESS_V2_BEGIN_NAMESPACE
0014 
0015 namespace posix
0016 {
0017 
0018 /// Utility class to bind a file descriptor to an explicit file descriptor for the child process.
0019 struct bind_fd
0020 {
0021     int target;
0022     int fd;
0023     bool fd_needs_closing{false};
0024 
0025     ~bind_fd()
0026     {
0027         if (fd_needs_closing)
0028             ::close(fd);
0029     }
0030 
0031     bind_fd() = delete;
0032     /// Inherit file descriptor with the same value.
0033     /**
0034      * This will pass descriptor 42 as 42 to the child process:
0035      * @code
0036      * process p{"test", {},  posix::bind_fd(42)};
0037      * @endcode
0038      */
0039     bind_fd(int target) : target(target), fd(target) {}
0040 
0041     /// Inherit an asio io-object as a given file descriptor to the child process.
0042     /**
0043      * This will pass the tcp::socket, as 42 to the child process:
0044      * @code
0045      * extern tcp::socket sock; 
0046      * process p{"test", {},  posix::bind_fd(42, sock)};
0047      * @endcode
0048      */
0049 
0050     template<typename Stream>
0051     bind_fd(int target, Stream && str, decltype(std::declval<Stream>().native_handle()) = -1)
0052         : bind_fd(target, str.native_handle())
0053     {}
0054 
0055     /// Inherit a `FILE` as a given file descriptor to the child process.
0056     /**
0057      * This will pass the given `FILE*`, as 42 to the child process:
0058      * @code
0059      * process p{"test", {},  posix::bind_fd(42, stderr)};
0060      * @endcode
0061      */
0062     bind_fd(int target, FILE * f) : bind_fd(target, fileno(f)) {}
0063     
0064     /// Inherit a file descriptor with as a different value.
0065     /**
0066      * This will pass 24 as 42 to the child process:
0067      * @code
0068      * process p{"test", {},  posix::bind_fd(42, 24)};
0069      * @endcode
0070      */
0071     bind_fd(int target, int fd) : target(target), fd(fd) {}
0072     
0073     /// Inherit a null device as a set descriptor.
0074     /**
0075      * This will pass 24 as 42 to the child process:
0076      * @code
0077      * process p{"test", {},  posix::bind_fd(42, nullptr)};
0078      * @endcode
0079      */
0080     bind_fd(int target, std::nullptr_t) : bind_fd(target, filesystem::path("/dev/null")) {}
0081 
0082     /// Inherit a newly opened-file as a set descriptor.
0083     /**
0084      * This will pass 24 as 42 to the child process:
0085      * @code
0086      * process p{"test", {},  posix::bind_fd(42, "extra-output.txt")};
0087      * @endcode
0088      */
0089     bind_fd(int target, const filesystem::path & pth, int flags = O_RDWR | O_CREAT)
0090             : target(target), fd(::open(pth.c_str(), flags, 0660)), fd_needs_closing(true)
0091     {
0092     }
0093 
0094     error_code on_setup(posix::default_launcher & launcher, const filesystem::path &, const char * const *)
0095     {
0096         launcher.fd_whitelist.push_back(target);
0097         return {};
0098     }
0099 
0100     /// Implementation of the initialization function.
0101     error_code on_exec_setup(posix::default_launcher & launcher, const filesystem::path &, const char * const *)
0102     {
0103         if (::dup2(fd, target) == -1)
0104             return error_code(errno, system_category());
0105         return error_code ();
0106     }
0107 };
0108 
0109 }
0110 
0111 BOOST_PROCESS_V2_END_NAMESPACE
0112 
0113 #endif //BOOST_PROCESS_V2_POSIX_BIND_FD_HPP