@@ -520,6 +520,20 @@ namespace util
520
520
* -------------------------------
521
521
*/
522
522
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
+
523
537
/* !
524
538
* Base class for all arguments involving string value.
525
539
*/
@@ -717,6 +731,7 @@ struct ArgumentDeducer
717
731
void set_option (input&& inp);
718
732
void set_option (output&& out);
719
733
void set_option (error&& err);
734
+ void set_option (close_fds&& cfds);
720
735
721
736
private:
722
737
Popen* popen_ = nullptr ;
@@ -1004,6 +1019,8 @@ class Popen
1004
1019
std::future<void > cleanup_future_;
1005
1020
#endif
1006
1021
1022
+ bool close_fds_ = false ;
1023
+
1007
1024
std::string exe_name_;
1008
1025
1009
1026
// Command in string format
@@ -1233,6 +1250,10 @@ namespace detail {
1233
1250
if (err.rd_ch_ != -1 ) popen_->stream_ .err_read_ = err.rd_ch_ ;
1234
1251
}
1235
1252
1253
+ inline void ArgumentDeducer::set_option (close_fds&& cfds) {
1254
+ popen_->close_fds_ = cfds.close_all ;
1255
+ }
1256
+
1236
1257
1237
1258
inline void Child::execute_child () {
1238
1259
#ifndef __USING_WINDOWS__
@@ -1279,6 +1300,17 @@ namespace detail {
1279
1300
if (stream.err_write_ != -1 && stream.err_write_ > 2 )
1280
1301
close (stream.err_write_ );
1281
1302
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
+
1282
1314
// Replace the current image with the executable
1283
1315
sys_ret = execvp (parent_->exe_name_ .c_str (), parent_->cargv_ .data ());
1284
1316
0 commit comments