Skip to content
Bitcoin Roots

v29.4-roots.1 · Commit 2: [PATCH 02/13] runtime: preserve shared operator controls

src/util/subprocess.h

Before: src/util/subprocess.h · After: src/util/subprocess.h

File metadata
index 3449fa3b1bacce60422267110b27e54b13b19458..7cabd1baf27c5366aea0fed3a6b6bbb4ded01475 100644

Download original patch · Release notes

Diff rows 401–478 of 478. Line numbers refer to the original before/after files.

+ Added− RemovedUnmarked lines are context.

Scroll the code area horizontally to read long lines. Before is on the left; after is on the right. Unified view fits narrow screens more easily.

src/util/subprocess.h CHANGED
@@ -1156,36 +1285,40 @@ inline void Popen::execute_process() noexcept(false) (continued)
1175
  else
1176
  {
1177
- close (err_wr_pipe);// close child side of pipe, else get stuck in read below
1178
 
1179
  stream_.close_child_fds();
1180
 
1181
  try {
1182
  char err_buf[SP_MAX_ERR_BUF_SIZ] = {0,};
1183
 
1184
- int read_bytes = util::read_atmost_n(
1185
- fdopen(err_rd_pipe, "r"),
1186
- err_buf,
1187
- SP_MAX_ERR_BUF_SIZ);
1188
- close(err_rd_pipe);
 
 
1189
 
1190
  if (read_bytes || strlen(err_buf)) {
1191
  // Call waitpid to reap the child process
@@ -1233,6 +1366,14 @@ namespace detail {
1233
  if (err.rd_ch_ != -1) popen_->stream_.err_read_ = err.rd_ch_;
1234
  }
1235
 
 
 
 
 
 
 
 
 
1236
 
1237
  inline void Child::execute_child() {
1238
  #ifndef __USING_WINDOWS__
@@ -1271,13 +1412,18 @@ namespace detail {
1271
 
1272
  // Close the duped descriptors
1273
  if (stream.read_from_parent_ != -1 && stream.read_from_parent_ > 2)
1274
- close(stream.read_from_parent_);
1275
 
1276
  if (stream.write_to_parent_ != -1 && stream.write_to_parent_ > 2)
1277
- close(stream.write_to_parent_);
1278
 
1279
  if (stream.err_write_ != -1 && stream.err_write_ > 2)
1280
- close(stream.err_write_);
 
 
 
 
 
1281
 
1282
  // Replace the current image with the executable
1283
  sys_ret = execvp(parent_->exe_name_.c_str(), parent_->cargv_.data());
@@ -1304,15 +1450,15 @@ namespace detail {
1304
  #ifdef __USING_WINDOWS__
1305
  util::configure_pipe(&this->g_hChildStd_IN_Rd, &this->g_hChildStd_IN_Wr, &this->g_hChildStd_IN_Wr);
1306
  this->input(util::file_from_handle(this->g_hChildStd_IN_Wr, "w"));
1307
- this->write_to_child_ = _fileno(this->input());
1308
 
1309
  util::configure_pipe(&this->g_hChildStd_OUT_Rd, &this->g_hChildStd_OUT_Wr, &this->g_hChildStd_OUT_Rd);
1310
  this->output(util::file_from_handle(this->g_hChildStd_OUT_Rd, "r"));
1311
- this->read_from_child_ = _fileno(this->output());
1312
 
1313
  util::configure_pipe(&this->g_hChildStd_ERR_Rd, &this->g_hChildStd_ERR_Wr, &this->g_hChildStd_ERR_Rd);
1314
  this->error(util::file_from_handle(this->g_hChildStd_ERR_Rd, "r"));
1315
- this->err_read_ = _fileno(this->error());
1316
  #else
1317
 
1318
  if (write_to_child_ != -1) input(fdopen(write_to_child_, "wb"));
 
1306
  else
1307
  {
1308
+ subprocess_close(err_wr_pipe);// close child side of pipe, else get stuck in read below
1309
 
1310
  stream_.close_child_fds();
1311
 
1312
  try {
1313
  char err_buf[SP_MAX_ERR_BUF_SIZ] = {0,};
1314
 
1315
+ FILE* err_fp = fdopen(err_rd_pipe, "r");
1316
+ if (!err_fp) {
1317
+ subprocess_close(err_rd_pipe);
1318
+ throw OSError("fdopen failed", errno);
1319
+ }
1320
+ int read_bytes = util::read_atmost_n(err_fp, err_buf, SP_MAX_ERR_BUF_SIZ);
1321
+ fclose(err_fp);
1322
 
1323
  if (read_bytes || strlen(err_buf)) {
1324
  // Call waitpid to reap the child process
 
1366
  if (err.rd_ch_ != -1) popen_->stream_.err_read_ = err.rd_ch_;
1367
  }
1368
 
1369
+ inline void ArgumentDeducer::set_option(close_fds&& cfds) {
1370
+ popen_->close_fds_ = cfds.close_all;
1371
+ }
1372
+
1373
+ #ifndef __USING_WINDOWS__
1374
+ void subprocess_close_all_fds(int except_fd);
1375
+ #endif
1376
+
1377
 
1378
  inline void Child::execute_child() {
1379
  #ifndef __USING_WINDOWS__
 
1412
 
1413
  // Close the duped descriptors
1414
  if (stream.read_from_parent_ != -1 && stream.read_from_parent_ > 2)
1415
+ subprocess_close(stream.read_from_parent_);
1416
 
1417
  if (stream.write_to_parent_ != -1 && stream.write_to_parent_ > 2)
1418
+ subprocess_close(stream.write_to_parent_);
1419
 
1420
  if (stream.err_write_ != -1 && stream.err_write_ > 2)
1421
+ subprocess_close(stream.err_write_);
1422
+
1423
+ // Close all the inherited fd's except the error write pipe
1424
+ if (parent_->close_fds_) {
1425
+ subprocess_close_all_fds(/*except_fd=*/ err_wr_pipe_);
1426
+ }
1427
 
1428
  // Replace the current image with the executable
1429
  sys_ret = execvp(parent_->exe_name_.c_str(), parent_->cargv_.data());
 
1450
  #ifdef __USING_WINDOWS__
1451
  util::configure_pipe(&this->g_hChildStd_IN_Rd, &this->g_hChildStd_IN_Wr, &this->g_hChildStd_IN_Wr);
1452
  this->input(util::file_from_handle(this->g_hChildStd_IN_Wr, "w"));
1453
+ this->write_to_child_ = subprocess_fileno(this->input());
1454
 
1455
  util::configure_pipe(&this->g_hChildStd_OUT_Rd, &this->g_hChildStd_OUT_Wr, &this->g_hChildStd_OUT_Rd);
1456
  this->output(util::file_from_handle(this->g_hChildStd_OUT_Rd, "r"));
1457
+ this->read_from_child_ = subprocess_fileno(this->output());
1458
 
1459
  util::configure_pipe(&this->g_hChildStd_ERR_Rd, &this->g_hChildStd_ERR_Wr, &this->g_hChildStd_ERR_Rd);
1460
  this->error(util::file_from_handle(this->g_hChildStd_ERR_Rd, "r"));
1461
+ this->err_read_ = subprocess_fileno(this->error());
1462
  #else
1463
 
1464
  if (write_to_child_ != -1) input(fdopen(write_to_child_, "wb"));