@@ -520,6 +520,20 @@ namespace util
520520 * -------------------------------
521521 */
522522
523+ /* !
524+ * Option to close all file descriptors
525+ * when the child process is spawned.
526+ * The close fd list does not include
527+ * input/output/error if they are explicitly
528+ * set as part of the Popen arguments.
529+ *
530+ * Default value is false.
531+ */
532+ struct close_fds {
533+ explicit close_fds (bool c): close_all(c) {}
534+ bool close_all = false ;
535+ };
536+
523537/* !
524538 * Base class for all arguments involving string value.
525539 */
@@ -717,6 +731,7 @@ struct ArgumentDeducer
717731 void set_option (input&& inp);
718732 void set_option (output&& out);
719733 void set_option (error&& err);
734+ void set_option (close_fds&& cfds);
720735
721736private:
722737 Popen* popen_ = nullptr ;
@@ -1004,6 +1019,8 @@ class Popen
10041019 std::future<void > cleanup_future_;
10051020#endif
10061021
1022+ bool close_fds_ = false ;
1023+
10071024 std::string exe_name_;
10081025
10091026 // Command in string format
@@ -1233,6 +1250,10 @@ namespace detail {
12331250 if (err.rd_ch_ != -1 ) popen_->stream_ .err_read_ = err.rd_ch_ ;
12341251 }
12351252
1253+ inline void ArgumentDeducer::set_option (close_fds&& cfds) {
1254+ popen_->close_fds_ = cfds.close_all ;
1255+ }
1256+
12361257
12371258 inline void Child::execute_child () {
12381259#ifndef __USING_WINDOWS__
@@ -1279,6 +1300,17 @@ namespace detail {
12791300 if (stream.err_write_ != -1 && stream.err_write_ > 2 )
12801301 close (stream.err_write_ );
12811302
1303+ // Close all the inherited fd's except the error write pipe
1304+ if (parent_->close_fds_ ) {
1305+ int max_fd = sysconf (_SC_OPEN_MAX);
1306+ if (max_fd == -1 ) throw OSError (" sysconf failed" , errno);
1307+
1308+ for (int i = 3 ; i < max_fd; i++) {
1309+ if (i == err_wr_pipe_) continue ;
1310+ close (i);
1311+ }
1312+ }
1313+
12821314 // Replace the current image with the executable
12831315 sys_ret = execvp (parent_->exe_name_ .c_str (), parent_->cargv_ .data ());
12841316
0 commit comments