From db845b915fe885d8cc18a86a9ae0952fb5b09c20 Mon Sep 17 00:00:00 2001 From: Ryan Ofsky Date: Thu, 24 Apr 2025 15:15:08 -0400 Subject: [PATCH] ipc: Add Ctrl-C handler for spawned subprocesses This fixes an error reported by Antoine Poinsot in https://github.com/bitcoin-core/libmultiprocess/issues/123 that does not happen in master, but does happen with https://github.com/bitcoin/bitcoin/pull/10102 applied, where if Ctrl-C is pressed when `bitcoin-node` is started, it is handled by both `bitcoin-node` and `bitcoin-wallet` processes, causing the wallet to shutdown abruptly instead of waiting for the node and shutting down cleanly. This change fixes the problem by having the wallet process print to stdout when it receives a Ctrl-C signal but not otherwise react, letting the node shut everything down cleanly. --- src/ipc/interfaces.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/ipc/interfaces.cpp b/src/ipc/interfaces.cpp index 0c6d1d040a5..1db96c252bd 100644 --- a/src/ipc/interfaces.cpp +++ b/src/ipc/interfaces.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -26,6 +27,27 @@ namespace ipc { namespace { +#ifndef WIN32 +std::string g_ignore_ctrl_c; + +void HandleCtrlC(int) +{ + (void)write(STDOUT_FILENO, g_ignore_ctrl_c.data(), g_ignore_ctrl_c.size()); +} +#endif + +void IgnoreCtrlC(std::string message) +{ +#ifndef WIN32 + g_ignore_ctrl_c = std::move(message); + struct sigaction sa{}; + sa.sa_handler = HandleCtrlC; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_RESTART; + sigaction(SIGINT, &sa, nullptr); +#endif +} + class IpcImpl : public interfaces::Ipc { public: @@ -53,6 +75,7 @@ public: if (!m_process->checkSpawned(argc, argv, fd)) { return false; } + IgnoreCtrlC(strprintf("[%s] SIGINT received — waiting for parent to shut down.\n", m_exe_name)); m_protocol->serve(fd, m_exe_name, m_init); exit_status = EXIT_SUCCESS; return true;