From 216099591632dc8a57cc1a3b1ad08e909f8c73cc 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 | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/ipc/interfaces.cpp b/src/ipc/interfaces.cpp index 50cef794aa5..d6b078e61b0 100644 --- a/src/ipc/interfaces.cpp +++ b/src/ipc/interfaces.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -26,6 +27,28 @@ namespace ipc { namespace { +#ifndef WIN32 +std::string g_ignore_ctrl_c; + +void HandleCtrlC(int) +{ + // (void)! needed to suppress -Wunused-result warning from GCC + (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 +76,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;