Files
bitcoin/src/common/run_command.cpp
Cory Fields 43b8777dc3 refactor: move run_command from util to common
Quoting ryanofsky: "util can be the library for things included in the kernel
which the kernel can depend on, and common can be the library for other code
that needs to be shared internally, but should not be part of the kernel or
shared externally."
2022-10-04 21:21:05 +00:00

65 lines
1.9 KiB
C++

// 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.
#if defined(HAVE_CONFIG_H)
#include <config/bitcoin-config.h>
#endif
#include <common/run_command.h>
#include <tinyformat.h>
#include <univalue.h>
#ifdef ENABLE_EXTERNAL_SIGNER
#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>
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
#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;
UniValue result_json;
bp::opstream stdin_stream;
bp::ipstream stdout_stream;
bp::ipstream 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
);
if (!str_std_in.empty()) {
stdin_stream << str_std_in << std::endl;
}
stdin_stream.pipe().close();
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();
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);
return result_json;
#else
throw std::runtime_error("Compiled without external signing support (required for external signing).");
#endif // ENABLE_EXTERNAL_SIGNER
}