bcli: add synchronous `run_bitcoin_cli` for future refactor
What changed, and why it matters
This commit adds a new internal helper function that runs the bitcoin-cli command synchronously (waiting for it to finish before continuing). It is marked UNNEEDED, meaning it is not currently used anywhere. The change appears to be a pure code-structure refactor with no active security behavior introduced.
No security action required. Treat as normal refactoring. If reviewing the future refactor that uses this helper, verify that synchronous blocking does not introduce denial-of-service or timeout issues, and that output length limits are enforced.
Security signals we found
No security-relevant behavioral change: only new unused helper code added
Synchronous child-process execution helper added, but not invoked
RPC password handling mirrors existing pattern (sent via stdin when configured)
No input validation, buffer-size, or privilege changes
Evidence from the diff
The patch introduces run_bitcoin_cli/run_bitcoin_cliv in plugins/bcli.c, a synchronous wrapper around pipecmdarr, write_all, grab_fd_str, and waitpid. It mirrors existing asynchronous bitcoin-cli execution logic but blocks until the child exits. The functions are annotated UNNEEDED and LAST_ARG_NULL, indicating they are preparatory scaffolding for a future refactor and not yet wired into any call path. No existing logic is modified.
Changed components
plugins/bcli.cInspect captured patch +72 / −0
diff --git a/plugins/bcli.c b/plugins/bcli.c
index cb99763e..b774d3d0 100644
--- a/plugins/bcli.c
+++ b/plugins/bcli.c
@@ -91,6 +91,13 @@ struct bitcoin_cli {
void *stash;
};
+/* Result of a synchronous bitcoin-cli call */
+struct bcli_result {
+ char *output;
+ size_t output_len;
+ int exitstatus;
+};
+
/* Add the n'th arg to *args, incrementing n and keeping args of size n+1 */
static void add_arg(const char ***args, const char *arg TAKES)
{
@@ -204,6 +211,71 @@ static char *args_string(const tal_t *ctx, const char **args, const char **stdin
return ret;
}
+/* Synchronous execution of bitcoin-cli.
+ * Returns result with output and exit status. */
+static UNNEEDED struct bcli_result *
+run_bitcoin_cliv(const tal_t *ctx,
+ struct plugin *plugin,
+ const char *method,
+ va_list ap)
+{
+ int in, from, status;
+ pid_t child;
+ const char **stdinargs;
+ const char **cmd;
+ struct bcli_result *res;
+
+ stdinargs = tal_arr(ctx, const char *, 0);
+ cmd = gather_argsv(ctx, &stdinargs, method, ap);
+
+ child = pipecmdarr(&in, &from, &from, cast_const2(char **, cmd));
+ if (child < 0)
+ plugin_err(plugin, "%s exec failed: %s", cmd[0], strerror(errno));
+
+ /* Send rpcpass via stdin if configured */
+ if (bitcoind->rpcpass) {
+ write_all(in, bitcoind->rpcpass, strlen(bitcoind->rpcpass));
+ write_all(in, "\n", 1);
+ }
+ /* Send any additional stdin args */
+ for (size_t i = 0; i < tal_count(stdinargs); i++) {
+ write_all(in, stdinargs[i], strlen(stdinargs[i]));
+ write_all(in, "\n", 1);
+ }
+ close(in);
+
+ /* Read all output until EOF */
+ res = tal(ctx, struct bcli_result);
+ res->output = grab_fd_str(res, from);
+ res->output_len = strlen(res->output);
+
+ /* Wait for child to exit */
+ while (waitpid(child, &status, 0) < 0 && errno == EINTR);
+
+ if (!WIFEXITED(status))
+ plugin_err(plugin, "%s died with signal %i",
+ args_string(tmpctx, cmd, stdinargs), WTERMSIG(status));
+
+ res->exitstatus = WEXITSTATUS(status);
+
+ return res;
+}
+
+static UNNEEDED LAST_ARG_NULL struct bcli_result *
+run_bitcoin_cli(const tal_t *ctx,
+ struct plugin *plugin,
+ const char *method, ...)
+{
+ va_list ap;
+ struct bcli_result *res;
+
+ va_start(ap, method);
+ res = run_bitcoin_cliv(ctx, plugin, method, ap);
+ va_end(ap);
+
+ return res;
+}
+
static char *bcli_args(const tal_t *ctx, struct bitcoin_cli *bcli)
{
return args_string(ctx, bcli->args, bcli->stdinargs);
Why this scored 13/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.