FreeRDP
Loading...
Searching...
No Matches
signal.c
1
20#include <freerdp/config.h>
21
22#include <string.h>
23
24#include <winpr/crt.h>
25#include <winpr/debug.h>
26
27#include <freerdp/utils/signal.h>
28#include <freerdp/log.h>
29
30#include "platform_signal.h"
31
32#define TAG FREERDP_TAG("utils.signal")
33
34#if defined(_WIN32)
35const char* strsignal(int signum);
36#endif
37
38BOOL fsig_handlers_registered = FALSE;
39
40typedef struct
41{
42 void* context;
43 freerdp_signal_handler_t handler;
44} cleanup_handler_t;
45
46static size_t cleanup_handler_count = 0;
47static cleanup_handler_t cleanup_handlers[20] = WINPR_C_ARRAY_INIT;
48
49void fsig_term_handler(int signum)
50{
51 static BOOL recursive = FALSE;
52
53 if (!recursive)
54 {
55 recursive = TRUE;
56 // NOLINTNEXTLINE(concurrency-mt-unsafe)
57 WLog_ERR(TAG, "Caught signal '%s' [%d]", strsignal(signum), signum);
58 }
59
60 fsig_lock();
61 for (size_t x = 0; x < cleanup_handler_count; x++)
62 {
63 const cleanup_handler_t empty = WINPR_C_ARRAY_INIT;
64 cleanup_handler_t* cur = &cleanup_handlers[x];
65 if (cur->handler)
66 {
67 // NOLINTNEXTLINE(concurrency-mt-unsafe)
68 cur->handler(signum, strsignal(signum), cur->context);
69 }
70 *cur = empty;
71 }
72 cleanup_handler_count = 0;
73 fsig_unlock();
74}
75
76BOOL freerdp_add_signal_cleanup_handler(void* context, freerdp_signal_handler_t handler)
77{
78 BOOL rc = FALSE;
79 fsig_lock();
80 if (fsig_handlers_registered)
81 {
82 if (cleanup_handler_count < ARRAYSIZE(cleanup_handlers))
83 {
84 cleanup_handler_t* cur = &cleanup_handlers[cleanup_handler_count++];
85 cur->context = context;
86 cur->handler = handler;
87 }
88 else
89 WLog_WARN(TAG, "Failed to register cleanup handler, only %" PRIuz " handlers supported",
90 ARRAYSIZE(cleanup_handlers));
91 }
92 rc = TRUE;
93 fsig_unlock();
94 return rc;
95}
96
97BOOL freerdp_del_signal_cleanup_handler(void* context, freerdp_signal_handler_t handler)
98{
99 BOOL rc = FALSE;
100 fsig_lock();
101 if (fsig_handlers_registered)
102 {
103 for (size_t x = 0; x < cleanup_handler_count; x++)
104 {
105 cleanup_handler_t* cur = &cleanup_handlers[x];
106 if ((cur->context == context) && (cur->handler == handler))
107 {
108 const cleanup_handler_t empty = WINPR_C_ARRAY_INIT;
109 for (size_t y = x + 1; y < cleanup_handler_count - 1; y++)
110 {
111 *cur++ = cleanup_handlers[y];
112 }
113
114 *cur = empty;
115 cleanup_handler_count--;
116 break;
117 }
118 }
119 }
120 rc = TRUE;
121 fsig_unlock();
122 return rc;
123}