aboutsummaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorCory Fields <cory-nospam-@coryfields.com>2022-10-04 18:15:53 +0000
committerCory Fields <cory-nospam-@coryfields.com>2022-10-04 21:21:05 +0000
commit43b8777dc3e63f4a1b20a3cb23e44c1b9e32862b (patch)
tree8e24f0c3bfcb8bd02029a761c08ceba6c3cc0ba3 /src/common
parent192325a77d593e404e74ef5e204aed8801b4e66f (diff)
downloadbitcoin-43b8777dc3e63f4a1b20a3cb23e44c1b9e32862b.tar.xz
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."
Diffstat (limited to 'src/common')
-rw-r--r--src/common/run_command.cpp64
-rw-r--r--src/common/run_command.h21
2 files changed, 85 insertions, 0 deletions
diff --git a/src/common/run_command.cpp b/src/common/run_command.cpp
new file mode 100644
index 0000000000..6ad9f75b5d
--- /dev/null
+++ b/src/common/run_command.cpp
@@ -0,0 +1,64 @@
+// 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
+}
diff --git a/src/common/run_command.h b/src/common/run_command.h
new file mode 100644
index 0000000000..2fbdc071ee
--- /dev/null
+++ b/src/common/run_command.h
@@ -0,0 +1,21 @@
+// 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
+
+#include <string>
+
+class UniValue;
+
+/**
+ * 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