diff options
author | Devtools Arcadia <arcadia-devtools@yandex-team.ru> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /util/system/interrupt_signals.cpp | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'util/system/interrupt_signals.cpp')
-rw-r--r-- | util/system/interrupt_signals.cpp | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/util/system/interrupt_signals.cpp b/util/system/interrupt_signals.cpp new file mode 100644 index 0000000000..96b723f2b8 --- /dev/null +++ b/util/system/interrupt_signals.cpp @@ -0,0 +1,60 @@ +#include "interrupt_signals.h" + +#include "compiler.h" +#include "error.h" + +#include <util/generic/yexception.h> + +#include <csignal> + +static void (*InterruptSignalsHandler)(int signum) = nullptr; + +#ifdef _win_ + + #include <windows.h> + +static BOOL WINAPI WindowsSignalsHandler(_In_ DWORD dwCtrlType) { + if (!InterruptSignalsHandler) { + return FALSE; + } + + switch (dwCtrlType) { + case CTRL_C_EVENT: + InterruptSignalsHandler(SIGINT); + return TRUE; + case CTRL_BREAK_EVENT: + InterruptSignalsHandler(SIGTERM); + return TRUE; + case CTRL_CLOSE_EVENT: + InterruptSignalsHandler(SIGHUP); + return TRUE; + default: + return FALSE; + } + Y_UNREACHABLE(); +} + +#endif + +// separate function is to enforce 'extern "C"' linkage +extern "C" void CppSignalsHandler(int signum) { + if (InterruptSignalsHandler) { + InterruptSignalsHandler(signum); + } +} + +void SetInterruptSignalsHandler(void (*handler)(int signum)) { + InterruptSignalsHandler = handler; +#ifdef _win_ + if (!SetConsoleCtrlHandler(WindowsSignalsHandler, TRUE)) { + ythrow TSystemError() << "SetConsoleCtrlHandler failed: " << LastSystemErrorText(); + } + for (int signum : {SIGINT, SIGTERM}) { +#else + for (int signum : {SIGINT, SIGTERM, SIGHUP}) { +#endif + if (std::signal(signum, CppSignalsHandler) == SIG_ERR) { + ythrow TSystemError() << "std::signal failed to set handler for signal with id " << signum; + } + } +} |