Skip to content
Bitcoin Roots

v31.1-roots.1 · Commit 6: [PATCH 06/17] feat(wallet): preserve Roots signing and spend controls on v31

src/util/subprocess.h

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

File metadata
index 8b9171308dd9c4f5defe854d8b544b12f070b6e3..f6cddf8fef9a976579dc03c1b7cf654d20f60854 100644

Download original patch · Release notes

Diff rows 1–57 of 57. 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
@@ -713,6 +713,12 @@ class Popen;
713
  *---------------------------------------------------
714
  */
715
 
 
 
 
 
 
 
716
  namespace detail {
717
  /*!
718
  * A helper class to Popen class for setting
@@ -729,6 +735,7 @@ struct ArgumentDeducer
729
  void set_option(input&& inp);
730
  void set_option(output&& out);
731
  void set_option(error&& err);
 
732
 
733
  private:
734
  Popen* popen_ = nullptr;
@@ -1014,6 +1021,8 @@ private:
1014
  int child_pid_ = -1;
1015
  #endif
1016
 
 
 
1017
  std::string exe_name_;
1018
 
1019
  // Command provided as sequence
@@ -1258,7 +1267,13 @@ namespace detail {
1258
  }
1259
 
1260
 
 
 
 
 
1261
  #ifndef WIN32
 
 
1262
  inline void Child::execute_child() {
1263
  int sys_ret = -1;
1264
  auto& stream = parent_->stream_;
@@ -1303,6 +1318,17 @@ namespace detail {
1303
  if (stream.err_write_ != -1 && stream.err_write_ > 2)
1304
  subprocess_close(stream.err_write_);
1305
 
 
 
 
 
 
 
 
 
 
 
 
1306
  // Replace the current image with the executable
1307
  sys_ret = execvp(parent_->exe_name_.c_str(), parent_->cargv_.data());
1308
 
 
713
  *---------------------------------------------------
714
  */
715
 
716
+ // Close inherited descriptors after redirecting the child standard streams.
717
+ struct close_fds {
718
+ explicit close_fds(bool c): close_all(c) {}
719
+ bool close_all = false;
720
+ };
721
+
722
  namespace detail {
723
  /*!
724
  * A helper class to Popen class for setting
 
735
  void set_option(input&& inp);
736
  void set_option(output&& out);
737
  void set_option(error&& err);
738
+ void set_option(close_fds&& cfds);
739
 
740
  private:
741
  Popen* popen_ = nullptr;
 
1021
  int child_pid_ = -1;
1022
  #endif
1023
 
1024
+ bool close_fds_ = false;
1025
+
1026
  std::string exe_name_;
1027
 
1028
  // Command provided as sequence
 
1267
  }
1268
 
1269
 
1270
+ inline void ArgumentDeducer::set_option(close_fds&& cfds) {
1271
+ popen_->close_fds_ = cfds.close_all;
1272
+ }
1273
+
1274
  #ifndef WIN32
1275
+ bool subprocess_close_all_fds(int& except_fd, bool force_fallback = false) noexcept;
1276
+
1277
  inline void Child::execute_child() {
1278
  int sys_ret = -1;
1279
  auto& stream = parent_->stream_;
 
1318
  if (stream.err_write_ != -1 && stream.err_write_ > 2)
1319
  subprocess_close(stream.err_write_);
1320
 
1321
+ // Close inherited descriptors except the exec error pipe and redirected standard streams.
1322
+ if (parent_->close_fds_) {
1323
+ if (!subprocess_close_all_fds(err_wr_pipe_)) {
1324
+ // Avoid exception/string allocation in the post-fork failure path.
1325
+ constexpr char error[] = "Unable to close inherited signer descriptors";
1326
+ const auto written = ::write(err_wr_pipe_, error, sizeof(error) - 1);
1327
+ (void)written;
1328
+ _exit(EXIT_FAILURE);
1329
+ }
1330
+ }
1331
+
1332
  // Replace the current image with the executable
1333
  sys_ret = execvp(parent_->exe_name_.c_str(), parent_->cargv_.data());
1334