34std::string g_ignore_ctrl_c;
39 (void)!write(STDOUT_FILENO, g_ignore_ctrl_c.data(), g_ignore_ctrl_c.size());
43void IgnoreCtrlC(std::string message)
46 g_ignore_ctrl_c = std::move(message);
47 struct sigaction sa{};
48 sa.sa_handler = HandleCtrlC;
49 sigemptyset(&sa.sa_mask);
50 sa.sa_flags = SA_RESTART;
51 sigaction(SIGINT, &sa,
nullptr);
59 :
m_exe_name(exe_name), m_process_argv0(process_argv0), m_init(
init),
63 std::unique_ptr<interfaces::Init> spawnProcess(
const char* new_exe_name)
override
65 const auto [pid, socket] = m_process->spawn(new_exe_name, m_process_argv0);
66 LogDebug(::BCLog::IPC,
"Process %s pid %i launched\n", new_exe_name, pid);
67 auto init = m_protocol->connect(m_protocol->makeStream(socket));
68 Ipc::addCleanup(*
init, [
this, new_exe_name, pid] {
69 int status = m_process->waitSpawned(pid);
70 LogDebug(::BCLog::IPC,
"Process %s pid %i exited with status %i\n", new_exe_name, pid, status);
74 bool startSpawnedProcess(
int argc,
char* argv[],
int&
exit_status)
override
78 if (!m_process->checkSpawned(argc, argv, socket)) {
81 IgnoreCtrlC(
strprintf(
"[%s] SIGINT received — waiting for parent to shut down.\n",
m_exe_name));
82 m_protocol->serve(m_init, [&] {
return m_protocol->makeStream(socket); } );
86 std::unique_ptr<interfaces::Init> connectAddress(std::string& address)
override
88 if (address.empty() || address ==
"0")
return nullptr;
90 if (address ==
"auto") {
98 }
catch (
const std::system_error& e) {
100 if (e.code() == std::errc::connection_refused || e.code() == std::errc::no_such_file_or_directory || e.code() == std::errc::not_a_directory) {
104 }
catch (
const std::invalid_argument&) {
111 return m_protocol->connect(m_protocol->makeStream(fd));
113 void listenAddress(std::string& address)
override
116 m_protocol->listen(fd, m_init);
118 void disconnectIncoming()
override
120 m_protocol->disconnectIncoming();
122 void addCleanup(std::type_index type,
void* iface, std::function<
void()> cleanup)
override
124 m_protocol->addCleanup(type, iface, std::move(cleanup));
126 Context& context()
override {
return m_protocol->context(); }
128 const char* m_process_argv0;
130 std::unique_ptr<Protocol> m_protocol;
131 std::unique_ptr<Process> m_process;
137std::unique_ptr<Ipc>
MakeIpc(
const char* exe_name,
const char* process_argv0,
Init&
init)
139 return std::make_unique<ipc::IpcImpl>(exe_name, process_argv0,
init);
std::unique_ptr< interfaces::Init > init
fs::path GetDataDirNet() const EXCLUSIVE_LOCKS_REQUIRED(!cs_args)
Get data directory path with appended network identifier.
Initial interface created when a process is first started, and used to give and get access to other i...
Interface providing access to interprocess-communication (IPC) functionality.
#define LogDebug(category,...)
std::unique_ptr< Ipc > MakeIpc(const char *exe_name, const char *process_argv0, Init &init)
Return implementation of Ipc interface.
std::unique_ptr< Protocol > MakeCapnpProtocol(const char *exe_name)
std::unique_ptr< Process > MakeProcess()
Constructor for Process interface.
constexpr SocketId SocketError