// Copyright (c) 2022 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_COMMON_RUN_COMMAND_H #define BITCOIN_COMMON_RUN_COMMAND_H #if defined(HAVE_CONFIG_H) #include #endif #include #include #include #if defined(ENABLE_EXTERNAL_SIGNER) && defined(BOOST_POSIX_API) #include #ifdef FD_CLOEXEC #include // Boost 1.77 requires the following workaround. // See: https://github.com/boostorg/process/issues/213 #include #if defined(WIN32) && !defined(__kernel_entry) // Boost 1.71-1.77 requires the following workaround for compatibility with mingw-w64 compiler. // See: https://github.com/bitcoin/bitcoin/pull/22348 #define __kernel_entry #endif #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 #include #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 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. * * @param str_command The command to execute, including any arguments * @param str_std_in string to pass to stdin * @return parsed JSON */ UniValue RunCommandParseJSON(const std::string& str_command, const std::string& str_std_in=""); #endif // BITCOIN_COMMON_RUN_COMMAND_H