Merge 22417 via bpchild_closefds

This commit is contained in:
Luke Dashjr 2024-03-25 17:26:53 +00:00
commit f3b600f95c
4 changed files with 69 additions and 1 deletions

View File

@ -1616,11 +1616,25 @@ if test "$use_external_signer" != "no"; then
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#define BOOST_PROCESS_USE_STD_FS
#include <boost/process.hpp>
#ifdef BOOST_POSIX_API
# include <fcntl.h>
# ifdef FD_CLOEXEC
# include <boost/process/extend.hpp>
# endif
#endif
]],[[
namespace bp = boost::process;
bp::opstream stdin_stream;
bp::ipstream stdout_stream;
bp::child c("dummy", bp::std_out > stdout_stream, bp::std_err > stdout_stream, bp::std_in < stdin_stream);
#if defined(BOOST_POSIX_API) && defined(FD_CLOEXEC)
struct dummy_extension : boost::process::extend::handler {};
#endif
bp::child c("dummy", bp::std_out > stdout_stream, bp::std_err > stdout_stream, bp::std_in < stdin_stream
#if defined(BOOST_POSIX_API) && defined(FD_CLOEXEC)
, dummy_extension()
#endif
);
stdin_stream << std::string{"test"} << std::endl;
if (c.running()) c.terminate();
c.wait();

View File

@ -32,6 +32,9 @@ UniValue RunCommandParseJSON(const std::string& str_command, const std::string&
bp::std_out > stdout_stream,
bp::std_err > stderr_stream,
bp::std_in < stdin_stream
#ifdef HAVE_BPE_CLOSE_EXCESS_FDS
, bpe_close_excess_fds()
#endif
);
if (!str_std_in.empty()) {
stdin_stream << str_std_in << std::endl;

View File

@ -5,10 +5,60 @@
#ifndef BITCOIN_COMMON_RUN_COMMAND_H
#define BITCOIN_COMMON_RUN_COMMAND_H
#if defined(HAVE_CONFIG_H)
#include <config/bitcoin-config.h>
#endif
#include <util/fs.h>
#include <util/strencodings.h>
#include <string>
#if defined(ENABLE_EXTERNAL_SIGNER) && defined(BOOST_POSIX_API)
#include <fcntl.h>
#ifdef FD_CLOEXEC
#include <unistd.h>
#if defined(__GNUC__)
// Boost 1.78 requires the following workaround.
// See: https://github.com/boostorg/process/issues/235
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wnarrowing"
#endif
#include <boost/process.hpp>
#include <boost/process/extend.hpp>
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
#endif // FD_CLOEXEC
#endif // ENABLE_EXTERNAL_SIGNER && BOOST_POSIX_API
class UniValue;
#if defined(ENABLE_EXTERNAL_SIGNER) && defined(BOOST_POSIX_API) && defined(FD_CLOEXEC)
/**
* Ensure a boost::process::child has its non-std fds all closed when exec
* is called.
*/
struct bpe_close_excess_fds : boost::process::extend::handler
{
template<typename Executor>
void on_exec_setup(Executor&exec) const
{
try {
for (auto it : fs::directory_iterator("/dev/fd")) {
int64_t fd;
if (!ParseInt64(it.path().filename().native(), &fd)) continue;
if (fd <= 2) continue; // leave std{in,out,err} alone
::fcntl(fd, F_SETFD, ::fcntl(fd, F_GETFD) | FD_CLOEXEC);
}
} catch (...) {
// TODO: maybe log this - but we're in a child process, so maybe non-trivial!
}
}
};
#define HAVE_BPE_CLOSE_EXCESS_FDS
#endif
/**
* Execute a command which returns JSON, and parse the result.
*

View File

@ -31,6 +31,7 @@ EXPECTED_BOOST_INCLUDES = ["boost/date_time/posix_time/posix_time.hpp",
"boost/multi_index/tag.hpp",
"boost/multi_index_container.hpp",
"boost/process.hpp",
"boost/process/extend.hpp",
"boost/signals2/connection.hpp",
"boost/signals2/optional_last_value.hpp",
"boost/signals2/signal.hpp",