5#include <winpr/atexit.h>
7#include <winpr/debug.h>
8#include <winpr/assert.h>
10#include <freerdp/log.h>
11#include <freerdp/utils/signal.h>
13#include "platform_signal.h"
15#define TAG FREERDP_TAG("utils.signal.posix")
18static INIT_ONCE signal_lock_init = INIT_ONCE_STATIC_INIT;
20static BOOL CALLBACK init_signal_lock(
PINIT_ONCE InitOnce, PVOID Parameter, PVOID* Context)
22 InitializeCriticalSection(&signal_lock);
28 InitOnceExecuteOnce(&signal_lock_init, init_signal_lock, NULL, NULL);
29 EnterCriticalSection(&signal_lock);
34 LeaveCriticalSection(&signal_lock);
37const char* strsignal(
int signum)
51 CASE_STR(SIGABRT_COMPAT);
56static void fatal_handler(
int signum)
58 static BOOL recursive = FALSE;
64 WLog_ERR(TAG,
"Caught signal '%s' [%d]", strsignal(signum), signum);
66 winpr_log_backtrace(TAG, WLOG_ERROR, 20);
72static const int term_signals[] = { SIGINT, SIGTERM };
74static const int fatal_signals[] = { SIGABRT, SIGFPE, SIGILL, SIGSEGV };
76static BOOL register_handlers(
const int* signals,
size_t count,
void (*handler)(
int))
78 WINPR_ASSERT(signals || (count == 0));
79 WINPR_ASSERT(handler);
81 for (
size_t x = 0; x < count; x++)
83 (void)signal(signals[x], handler);
89static void unregister_handlers(
const int* signals,
size_t count)
91 WINPR_ASSERT(signals || (count == 0));
93 for (
size_t x = 0; x < count; x++)
95 (void)signal(signals[x], SIG_IGN);
99static void unregister_all_handlers(
void)
101 unregister_handlers(fatal_signals, ARRAYSIZE(fatal_signals));
102 unregister_handlers(term_signals, ARRAYSIZE(term_signals));
103 DeleteCriticalSection(&signal_lock);
106int freerdp_handle_signals(
void)
111 WLog_DBG(TAG,
"Registering signal hook...");
113 (void)winpr_atexit(unregister_all_handlers);
114 if (!register_handlers(fatal_signals, ARRAYSIZE(fatal_signals), fatal_handler))
116 if (!register_handlers(term_signals, ARRAYSIZE(term_signals), fsig_term_handler))
119 fsig_handlers_registered =
true;