This source file includes following definitions.
- signal_nothrow
- ext_signal
- sigismember
- sigemptyset
- sigaddset
- sigdelset
- sigfillset
- blocked_handler
- sigpending
- sigprocmask
- rpl_signal
- _gl_raise_SIGPIPE
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 #include <config.h>
19
20
21 #include <signal.h>
22
23 #include <errno.h>
24 #include <stdint.h>
25 #include <stdlib.h>
26
27 #if HAVE_MSVC_INVALID_PARAMETER_HANDLER
28 # include "msvc-inval.h"
29 #endif
30
31
32
33
34
35
36
37
38
39 #undef signal
40
41
42
43 #ifndef SIGKILL
44 # define SIGKILL (-1)
45 #endif
46 #ifndef SIGSTOP
47 # define SIGSTOP (-1)
48 #endif
49
50
51
52
53 #if defined _WIN32 && ! defined __CYGWIN__
54 # undef SIGABRT_COMPAT
55 # define SIGABRT_COMPAT 6
56 #endif
57 #ifdef SIGABRT_COMPAT
58 # define SIGABRT_COMPAT_MASK (1U << SIGABRT_COMPAT)
59 #else
60 # define SIGABRT_COMPAT_MASK 0
61 #endif
62
63 typedef void (*handler_t) (int);
64
65 #if HAVE_MSVC_INVALID_PARAMETER_HANDLER
66 static handler_t
67 signal_nothrow (int sig, handler_t handler)
68 {
69 handler_t result;
70
71 TRY_MSVC_INVAL
72 {
73 result = signal (sig, handler);
74 }
75 CATCH_MSVC_INVAL
76 {
77 result = SIG_ERR;
78 errno = EINVAL;
79 }
80 DONE_MSVC_INVAL;
81
82 return result;
83 }
84 # define signal signal_nothrow
85 #endif
86
87
88
89 #if GNULIB_defined_SIGPIPE
90 static handler_t SIGPIPE_handler = SIG_DFL;
91 #endif
92
93 #if GNULIB_defined_SIGPIPE
94 static handler_t
95 ext_signal (int sig, handler_t handler)
96 {
97 switch (sig)
98 {
99 case SIGPIPE:
100 {
101 handler_t old_handler = SIGPIPE_handler;
102 SIGPIPE_handler = handler;
103 return old_handler;
104 }
105 default:
106 return signal (sig, handler);
107 }
108 }
109 # undef signal
110 # define signal ext_signal
111 #endif
112
113 int
114 sigismember (const sigset_t *set, int sig)
115 {
116 if (sig >= 0 && sig < NSIG)
117 {
118 #ifdef SIGABRT_COMPAT
119 if (sig == SIGABRT_COMPAT)
120 sig = SIGABRT;
121 #endif
122
123 return (*set >> sig) & 1;
124 }
125 else
126 return 0;
127 }
128
129 int
130 sigemptyset (sigset_t *set)
131 {
132 *set = 0;
133 return 0;
134 }
135
136 int
137 sigaddset (sigset_t *set, int sig)
138 {
139 if (sig >= 0 && sig < NSIG)
140 {
141 #ifdef SIGABRT_COMPAT
142 if (sig == SIGABRT_COMPAT)
143 sig = SIGABRT;
144 #endif
145
146 *set |= 1U << sig;
147 return 0;
148 }
149 else
150 {
151 errno = EINVAL;
152 return -1;
153 }
154 }
155
156 int
157 sigdelset (sigset_t *set, int sig)
158 {
159 if (sig >= 0 && sig < NSIG)
160 {
161 #ifdef SIGABRT_COMPAT
162 if (sig == SIGABRT_COMPAT)
163 sig = SIGABRT;
164 #endif
165
166 *set &= ~(1U << sig);
167 return 0;
168 }
169 else
170 {
171 errno = EINVAL;
172 return -1;
173 }
174 }
175
176
177 int
178 sigfillset (sigset_t *set)
179 {
180 *set = ((2U << (NSIG - 1)) - 1) & ~ SIGABRT_COMPAT_MASK;
181 return 0;
182 }
183
184
185 static volatile sigset_t blocked_set ;
186
187
188 static volatile sig_atomic_t pending_array[NSIG] ;
189
190
191 static void
192 blocked_handler (int sig)
193 {
194
195
196
197
198
199 signal (sig, blocked_handler);
200 if (sig >= 0 && sig < NSIG)
201 pending_array[sig] = 1;
202 }
203
204 int
205 sigpending (sigset_t *set)
206 {
207 sigset_t pending = 0;
208 int sig;
209
210 for (sig = 0; sig < NSIG; sig++)
211 if (pending_array[sig])
212 pending |= 1U << sig;
213 *set = pending;
214 return 0;
215 }
216
217
218
219 static volatile handler_t old_handlers[NSIG];
220
221 int
222 sigprocmask (int operation, const sigset_t *set, sigset_t *old_set)
223 {
224 if (old_set != NULL)
225 *old_set = blocked_set;
226
227 if (set != NULL)
228 {
229 sigset_t new_blocked_set;
230 sigset_t to_unblock;
231 sigset_t to_block;
232
233 switch (operation)
234 {
235 case SIG_BLOCK:
236 new_blocked_set = blocked_set | *set;
237 break;
238 case SIG_SETMASK:
239 new_blocked_set = *set;
240 break;
241 case SIG_UNBLOCK:
242 new_blocked_set = blocked_set & ~*set;
243 break;
244 default:
245 errno = EINVAL;
246 return -1;
247 }
248 to_unblock = blocked_set & ~new_blocked_set;
249 to_block = new_blocked_set & ~blocked_set;
250
251 if (to_block != 0)
252 {
253 int sig;
254
255 for (sig = 0; sig < NSIG; sig++)
256 if ((to_block >> sig) & 1)
257 {
258 pending_array[sig] = 0;
259 if ((old_handlers[sig] = signal (sig, blocked_handler)) != SIG_ERR)
260 blocked_set |= 1U << sig;
261 }
262 }
263
264 if (to_unblock != 0)
265 {
266 sig_atomic_t received[NSIG];
267 int sig;
268
269 for (sig = 0; sig < NSIG; sig++)
270 if ((to_unblock >> sig) & 1)
271 {
272 if (signal (sig, old_handlers[sig]) != blocked_handler)
273
274
275
276 abort ();
277 received[sig] = pending_array[sig];
278 blocked_set &= ~(1U << sig);
279 pending_array[sig] = 0;
280 }
281 else
282 received[sig] = 0;
283
284 for (sig = 0; sig < NSIG; sig++)
285 if (received[sig])
286 raise (sig);
287 }
288 }
289 return 0;
290 }
291
292
293
294 handler_t
295 rpl_signal (int sig, handler_t handler)
296 {
297
298
299 if (sig >= 0 && sig < NSIG && sig != SIGKILL && sig != SIGSTOP
300 && handler != SIG_ERR)
301 {
302 #ifdef SIGABRT_COMPAT
303 if (sig == SIGABRT_COMPAT)
304 sig = SIGABRT;
305 #endif
306
307 if (blocked_set & (1U << sig))
308 {
309
310
311
312
313
314
315
316
317
318 handler_t result = old_handlers[sig];
319 old_handlers[sig] = handler;
320 return result;
321 }
322 else
323 return signal (sig, handler);
324 }
325 else
326 {
327 errno = EINVAL;
328 return SIG_ERR;
329 }
330 }
331
332 #if GNULIB_defined_SIGPIPE
333
334 int
335 _gl_raise_SIGPIPE (void)
336 {
337 if (blocked_set & (1U << SIGPIPE))
338 pending_array[SIGPIPE] = 1;
339 else
340 {
341 handler_t handler = SIGPIPE_handler;
342 if (handler == SIG_DFL)
343 exit (128 + SIGPIPE);
344 else if (handler != SIG_IGN)
345 (*handler) (SIGPIPE);
346 }
347 return 0;
348 }
349 #endif