5#include <winpr/wtypes.h>
6#include <winpr/atexit.h>
8#include <winpr/debug.h>
9#include <winpr/assert.h>
11#include <freerdp/log.h>
12#include <freerdp/utils/signal.h>
14#include "platform_signal.h"
16#define TAG FREERDP_TAG("utils.signal.posix")
19static INIT_ONCE signal_lock_init = INIT_ONCE_STATIC_INIT;
21static BOOL CALLBACK init_signal_lock(
PINIT_ONCE InitOnce, PVOID Parameter, PVOID* Context)
23 InitializeCriticalSection(&signal_lock);
29 InitOnceExecuteOnce(&signal_lock_init, init_signal_lock,
nullptr,
nullptr);
30 EnterCriticalSection(&signal_lock);
35 LeaveCriticalSection(&signal_lock);
38const char* strsignal(
int signum)
52 CASE_STR(SIGABRT_COMPAT);
57static void fatal_handler(
int signum)
59 static BOOL recursive = FALSE;
65 WLog_ERR(TAG,
"Caught signal '%s' [%d]", strsignal(signum), signum);
67 winpr_log_backtrace(TAG, WLOG_ERROR, 20);
73static const int term_signals[] = { SIGINT, SIGTERM };
75static const int fatal_signals[] = { SIGABRT, SIGFPE, SIGILL, SIGSEGV };
77static BOOL register_handlers(
const int* signals,
size_t count,
void (*handler)(
int))
79 WINPR_ASSERT(signals || (count == 0));
80 WINPR_ASSERT(handler);
82 for (
size_t x = 0; x < count; x++)
84 (void)signal(signals[x], handler);
90static void unregister_handlers(
const int* signals,
size_t count)
92 WINPR_ASSERT(signals || (count == 0));
94 for (
size_t x = 0; x < count; x++)
96 (void)signal(signals[x], SIG_IGN);
100static void unregister_all_handlers(
void)
102 unregister_handlers(fatal_signals, ARRAYSIZE(fatal_signals));
103 unregister_handlers(term_signals, ARRAYSIZE(term_signals));
104 DeleteCriticalSection(&signal_lock);
107int freerdp_handle_signals(
void)
112 WLog_DBG(TAG,
"Registering signal hook...");
114 (void)winpr_atexit(unregister_all_handlers);
115 if (!register_handlers(fatal_signals, ARRAYSIZE(fatal_signals), fatal_handler))
117 if (!register_handlers(term_signals, ARRAYSIZE(term_signals), fsig_term_handler))
120 fsig_handlers_registered =
true;