mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-01 09:35:52 -05:00
Merge ff198b5ce5
into 85f96b01b7
This commit is contained in:
commit
bc038aa849
2 changed files with 43 additions and 1 deletions
|
@ -24,7 +24,7 @@ UniValue RunCommandParseJSON(const std::string& str_command, const std::string&
|
|||
|
||||
if (str_command.empty()) return UniValue::VNULL;
|
||||
|
||||
auto c = sp::Popen(str_command, sp::input{sp::PIPE}, sp::output{sp::PIPE}, sp::error{sp::PIPE});
|
||||
auto c = sp::Popen(str_command, sp::input{sp::PIPE}, sp::output{sp::PIPE}, sp::error{sp::PIPE}, sp::close_fds{true});
|
||||
if (!str_std_in.empty()) {
|
||||
c.send(str_std_in);
|
||||
}
|
||||
|
|
|
@ -36,6 +36,8 @@ Documentation for C++ subprocessing library.
|
|||
#ifndef BITCOIN_UTIL_SUBPROCESS_H
|
||||
#define BITCOIN_UTIL_SUBPROCESS_H
|
||||
|
||||
#include <util/fs.h>
|
||||
#include <util/strencodings.h>
|
||||
#include <util/syserror.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
@ -520,6 +522,20 @@ namespace util
|
|||
* -------------------------------
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Option to close all file descriptors
|
||||
* when the child process is spawned.
|
||||
* The close fd list does not include
|
||||
* input/output/error if they are explicitly
|
||||
* set as part of the Popen arguments.
|
||||
*
|
||||
* Default value is false.
|
||||
*/
|
||||
struct close_fds {
|
||||
explicit close_fds(bool c): close_all(c) {}
|
||||
bool close_all = false;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Base class for all arguments involving string value.
|
||||
*/
|
||||
|
@ -717,6 +733,7 @@ struct ArgumentDeducer
|
|||
void set_option(input&& inp);
|
||||
void set_option(output&& out);
|
||||
void set_option(error&& err);
|
||||
void set_option(close_fds&& cfds);
|
||||
|
||||
private:
|
||||
Popen* popen_ = nullptr;
|
||||
|
@ -1004,6 +1021,8 @@ private:
|
|||
std::future<void> cleanup_future_;
|
||||
#endif
|
||||
|
||||
bool close_fds_ = false;
|
||||
|
||||
std::string exe_name_;
|
||||
|
||||
// Command in string format
|
||||
|
@ -1233,6 +1252,10 @@ namespace detail {
|
|||
if (err.rd_ch_ != -1) popen_->stream_.err_read_ = err.rd_ch_;
|
||||
}
|
||||
|
||||
inline void ArgumentDeducer::set_option(close_fds&& cfds) {
|
||||
popen_->close_fds_ = cfds.close_all;
|
||||
}
|
||||
|
||||
|
||||
inline void Child::execute_child() {
|
||||
#ifndef __USING_WINDOWS__
|
||||
|
@ -1279,6 +1302,25 @@ namespace detail {
|
|||
if (stream.err_write_ != -1 && stream.err_write_ > 2)
|
||||
close(stream.err_write_);
|
||||
|
||||
// Close all the inherited fd's except the error write pipe
|
||||
if (parent_->close_fds_) {
|
||||
try {
|
||||
std::vector<int> fds_to_close;
|
||||
for (const auto& it : fs::directory_iterator("/proc/self/fd")) {
|
||||
int64_t fd;
|
||||
if (!ParseInt64(it.path().filename().native(), &fd)) continue;
|
||||
if (fd <= 2) continue; // leave std{in,out,err} alone
|
||||
if (fd == err_wr_pipe_) continue;
|
||||
fds_to_close.push_back(fd);
|
||||
}
|
||||
for (const int fd : fds_to_close) {
|
||||
close(fd);
|
||||
}
|
||||
} catch (...) {
|
||||
// TODO: maybe log this - but we're in a child process, so maybe non-trivial!
|
||||
}
|
||||
}
|
||||
|
||||
// Replace the current image with the executable
|
||||
sys_ret = execvp(parent_->exe_name_.c_str(), parent_->cargv_.data());
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue