diff options
-rw-r--r-- | src/Makefile.am | 1 | ||||
-rw-r--r-- | src/common/run_command.cpp | 25 | ||||
-rw-r--r-- | src/external_signer.cpp | 8 | ||||
-rw-r--r-- | src/test/system_tests.cpp | 14 | ||||
-rwxr-xr-x | test/lint/lint-includes.py | 1 |
5 files changed, 20 insertions, 29 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 0328dfc2cd..558975cd82 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -323,6 +323,7 @@ BITCOIN_CORE_H = \ util/sock.h \ util/spanparsing.h \ util/string.h \ + util/subprocess.hpp \ util/syserror.h \ util/task_runner.h \ util/thread.h \ diff --git a/src/common/run_command.cpp b/src/common/run_command.cpp index 8bd5febd53..e5356490ef 100644 --- a/src/common/run_command.cpp +++ b/src/common/run_command.cpp @@ -12,39 +12,34 @@ #include <univalue.h> #ifdef ENABLE_EXTERNAL_SIGNER -#include <boost/process.hpp> +#include <util/subprocess.hpp> #endif // ENABLE_EXTERNAL_SIGNER UniValue RunCommandParseJSON(const std::string& str_command, const std::string& str_std_in) { #ifdef ENABLE_EXTERNAL_SIGNER - namespace bp = boost::process; + namespace sp = subprocess; UniValue result_json; - bp::opstream stdin_stream; - bp::ipstream stdout_stream; - bp::ipstream stderr_stream; + std::istringstream stdout_stream; + std::istringstream stderr_stream; if (str_command.empty()) return UniValue::VNULL; - bp::child c( - str_command, - bp::std_out > stdout_stream, - bp::std_err > stderr_stream, - bp::std_in < stdin_stream - ); + auto c = sp::Popen(str_command, sp::input{sp::PIPE}, sp::output{sp::PIPE}, sp::error{sp::PIPE}); if (!str_std_in.empty()) { - stdin_stream << str_std_in << std::endl; + c.send(str_std_in); } - stdin_stream.pipe().close(); + auto [out_res, err_res] = c.communicate(); + stdout_stream.str(std::string{out_res.buf.begin(), out_res.buf.end()}); + stderr_stream.str(std::string{err_res.buf.begin(), err_res.buf.end()}); std::string result; std::string error; std::getline(stdout_stream, result); std::getline(stderr_stream, error); - c.wait(); - const int n_error = c.exit_code(); + const int n_error = c.retcode(); if (n_error) throw std::runtime_error(strprintf("RunCommandParseJSON error: process(%s) returned %d: %s\n", str_command, n_error, error)); if (!result_json.read(result)) throw std::runtime_error("Unable to parse JSON: " + result); diff --git a/src/external_signer.cpp b/src/external_signer.cpp index 749bb5f74f..ff159a2aa5 100644 --- a/src/external_signer.cpp +++ b/src/external_signer.cpp @@ -62,12 +62,12 @@ bool ExternalSigner::Enumerate(const std::string& command, std::vector<ExternalS UniValue ExternalSigner::DisplayAddress(const std::string& descriptor) const { - return RunCommandParseJSON(m_command + " --fingerprint \"" + m_fingerprint + "\"" + NetworkArg() + " displayaddress --desc \"" + descriptor + "\""); + return RunCommandParseJSON(m_command + " --fingerprint " + m_fingerprint + NetworkArg() + " displayaddress --desc " + descriptor); } UniValue ExternalSigner::GetDescriptors(const int account) { - return RunCommandParseJSON(m_command + " --fingerprint \"" + m_fingerprint + "\"" + NetworkArg() + " getdescriptors --account " + strprintf("%d", account)); + return RunCommandParseJSON(m_command + " --fingerprint " + m_fingerprint + NetworkArg() + " getdescriptors --account " + strprintf("%d", account)); } bool ExternalSigner::SignTransaction(PartiallySignedTransaction& psbtx, std::string& error) @@ -93,8 +93,8 @@ bool ExternalSigner::SignTransaction(PartiallySignedTransaction& psbtx, std::str return false; } - const std::string command = m_command + " --stdin --fingerprint \"" + m_fingerprint + "\"" + NetworkArg(); - const std::string stdinStr = "signtx \"" + EncodeBase64(ssTx.str()) + "\""; + const std::string command = m_command + " --stdin --fingerprint " + m_fingerprint + NetworkArg(); + const std::string stdinStr = "signtx " + EncodeBase64(ssTx.str()); const UniValue signer_result = RunCommandParseJSON(command, stdinStr); diff --git a/src/test/system_tests.cpp b/src/test/system_tests.cpp index 90fce9adf9..8aab2b565c 100644 --- a/src/test/system_tests.cpp +++ b/src/test/system_tests.cpp @@ -11,7 +11,7 @@ #include <univalue.h> #ifdef ENABLE_EXTERNAL_SIGNER -#include <boost/process.hpp> +#include <util/subprocess.hpp> #endif // ENABLE_EXTERNAL_SIGNER #include <boost/test/unit_test.hpp> @@ -34,20 +34,16 @@ BOOST_AUTO_TEST_CASE(run_command) BOOST_CHECK(result.isNull()); } { - const UniValue result = RunCommandParseJSON("echo \"{\"success\": true}\""); + const UniValue result = RunCommandParseJSON("echo {\"success\": true}"); BOOST_CHECK(result.isObject()); const UniValue& success = result.find_value("success"); BOOST_CHECK(!success.isNull()); BOOST_CHECK_EQUAL(success.get_bool(), true); } { - // An invalid command is handled by Boost - const int expected_error{2}; - BOOST_CHECK_EXCEPTION(RunCommandParseJSON("invalid_command"), boost::process::process_error, [&](const boost::process::process_error& e) { - BOOST_CHECK(std::string(e.what()).find("RunCommandParseJSON error:") == std::string::npos); - BOOST_CHECK_EQUAL(e.code().value(), expected_error); - return true; - }); + // An invalid command is handled by cpp-subprocess + const std::string expected{"execve failed: "}; + BOOST_CHECK_EXCEPTION(RunCommandParseJSON("invalid_command"), subprocess::CalledProcessError, HasReason(expected)); } { // Return non-zero exit code, no output to stderr diff --git a/test/lint/lint-includes.py b/test/lint/lint-includes.py index 81ed4c0840..90884299d5 100755 --- a/test/lint/lint-includes.py +++ b/test/lint/lint-includes.py @@ -30,7 +30,6 @@ EXPECTED_BOOST_INCLUDES = ["boost/date_time/posix_time/posix_time.hpp", "boost/multi_index/tag.hpp", "boost/multi_index_container.hpp", "boost/operators.hpp", - "boost/process.hpp", "boost/signals2/connection.hpp", "boost/signals2/optional_last_value.hpp", "boost/signals2/signal.hpp", |