diff options
author | Marc Hoersken <info@marc-hoersken.de> | 2020-04-11 23:31:55 +0200 |
---|---|---|
committer | Marc Hoersken <info@marc-hoersken.de> | 2020-04-12 15:55:22 +0200 |
commit | 30c8ef7d636ea060e690b4959280d05f2587d882 (patch) | |
tree | 21cbcb96fdcf03cd0de91a26495fd18885d19332 | |
parent | 9869f6dc5af85caf2e0fd4c56713a7f2049ecfff (diff) |
tests/server: add CTRL event handler for Win32 consoles
Forward CTRL events as signals to existing signal event handler.
-rw-r--r-- | tests/server/util.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/tests/server/util.c b/tests/server/util.c index 5dd4e0a7f..c8bc32945 100644 --- a/tests/server/util.c +++ b/tests/server/util.c @@ -567,6 +567,47 @@ static RETSIGTYPE exit_signal_handler(int signum) errno = old_errno; } +#ifdef WIN32 +/* CTRL event handler for Windows Console applications to simulate + * SIGINT, SIGTERM and SIGBREAK on CTRL events and trigger signal handler. + * + * Background information from MSDN: + * SIGINT is not supported for any Win32 application. When a CTRL+C + * interrupt occurs, Win32 operating systems generate a new thread + * to specifically handle that interrupt. This can cause a single-thread + * application, such as one in UNIX, to become multithreaded and cause + * unexpected behavior. + * [...] + * The SIGILL and SIGTERM signals are not generated under Windows. + * They are included for ANSI compatibility. Therefore, you can set + * signal handlers for these signals by using signal, and you can also + * explicitly generate these signals by calling raise. Source: + * https://docs.microsoft.com/de-de/cpp/c-runtime-library/reference/signal + */ +static BOOL WINAPI ctrl_event_handler(DWORD dwCtrlType) +{ + int signum = 0; + logmsg("ctrl_event_handler: %d", dwCtrlType); + switch(dwCtrlType) { +#ifdef SIGINT + case CTRL_C_EVENT: signum = SIGINT; break; +#endif +#ifdef SIGTERM + case CTRL_CLOSE_EVENT: signum = SIGTERM; break; +#endif +#ifdef SIGBREAK + case CTRL_BREAK_EVENT: signum = SIGBREAK; break; +#endif + default: return FALSE; + } + if(signum) { + logmsg("ctrl_event_handler: %d -> %d", dwCtrlType, signum); + exit_signal_handler(signum); + } + return TRUE; +} +#endif + void install_signal_handlers(bool keep_sigalrm) { #ifdef SIGHUP @@ -615,6 +656,10 @@ void install_signal_handlers(bool keep_sigalrm) else siginterrupt(SIGBREAK, 1); #endif +#ifdef WIN32 + if(!SetConsoleCtrlHandler(ctrl_event_handler, TRUE)) + logmsg("cannot install CTRL event handler"); +#endif } void restore_signal_handlers(bool keep_sigalrm) @@ -647,4 +692,7 @@ void restore_signal_handlers(bool keep_sigalrm) if(SIG_ERR != old_sigbreak_handler) (void)signal(SIGBREAK, old_sigbreak_handler); #endif +#ifdef WIN32 + (void)SetConsoleCtrlHandler(ctrl_event_handler, FALSE); +#endif } |