diff --git a/src/util/scoped_ctrl_c.cpp b/src/util/scoped_ctrl_c.cpp index a3f5ee772..f7f0bc351 100644 --- a/src/util/scoped_ctrl_c.cpp +++ b/src/util/scoped_ctrl_c.cpp @@ -21,37 +21,48 @@ Revision History: static scoped_ctrl_c * g_obj = nullptr; +static void (*signal_sigint(void (*eh)(int)))(int) { + void (*old_eh)(int); + struct sigaction action; + sigaction(SIGINT, NULL, &action); + old_eh = action.sa_handler; + action.sa_handler = eh; + action.sa_flags |= SA_ONSTACK; + sigaction(SIGINT, &action, NULL); + return old_eh; +} + static void on_ctrl_c(int) { if (g_obj->m_first) { g_obj->m_cancel_eh(CTRL_C_EH_CALLER); if (g_obj->m_once) { g_obj->m_first = false; - signal(SIGINT, on_ctrl_c); // re-install the handler + signal_sigint(on_ctrl_c); // re-install the handler } } else { - signal(SIGINT, g_obj->m_old_handler); + signal_sigint(g_obj->m_old_handler); raise(SIGINT); } } scoped_ctrl_c::scoped_ctrl_c(event_handler & eh, bool once, bool enabled): - m_cancel_eh(eh), + m_cancel_eh(eh), m_first(true), m_once(once), m_enabled(enabled), m_old_scoped_ctrl_c(g_obj) { if (m_enabled) { g_obj = this; - m_old_handler = signal(SIGINT, on_ctrl_c); + m_old_handler = signal_sigint(on_ctrl_c); } } -scoped_ctrl_c::~scoped_ctrl_c() { +scoped_ctrl_c::~scoped_ctrl_c() { if (m_enabled) { g_obj = m_old_scoped_ctrl_c; if (m_old_handler != SIG_ERR) { - signal(SIGINT, m_old_handler); + signal_sigint(m_old_handler); } } }