Branch data Line data Source code
1 : :
2 : : /* Signal module -- many thanks to Lance Ellinghaus */
3 : :
4 : : /* XXX Signals should be recorded per thread, now we have thread state. */
5 : :
6 : : #include "Python.h"
7 : : #include "pycore_atomic.h" // _Py_atomic_int
8 : : #include "pycore_call.h" // _PyObject_Call()
9 : : #include "pycore_ceval.h" // _PyEval_SignalReceived()
10 : : #include "pycore_emscripten_signal.h" // _Py_CHECK_EMSCRIPTEN_SIGNALS
11 : : #include "pycore_fileutils.h" // _Py_BEGIN_SUPPRESS_IPH
12 : : #include "pycore_frame.h" // _PyInterpreterFrame
13 : : #include "pycore_moduleobject.h" // _PyModule_GetState()
14 : : #include "pycore_pyerrors.h" // _PyErr_SetString()
15 : : #include "pycore_pystate.h" // _PyThreadState_GET()
16 : : #include "pycore_signal.h" // Py_NSIG
17 : :
18 : : #ifndef MS_WINDOWS
19 : : # include "posixmodule.h"
20 : : #endif
21 : : #ifdef MS_WINDOWS
22 : : # include "socketmodule.h" /* needed for SOCKET_T */
23 : : #endif
24 : :
25 : : #ifdef MS_WINDOWS
26 : : # include <windows.h>
27 : : # ifdef HAVE_PROCESS_H
28 : : # include <process.h>
29 : : # endif
30 : : #endif
31 : :
32 : : #ifdef HAVE_SIGNAL_H
33 : : # include <signal.h>
34 : : #endif
35 : : #ifdef HAVE_SYS_SYSCALL_H
36 : : # include <sys/syscall.h>
37 : : #endif
38 : : #ifdef HAVE_SYS_STAT_H
39 : : # include <sys/stat.h>
40 : : #endif
41 : : #ifdef HAVE_SYS_TIME_H
42 : : # include <sys/time.h>
43 : : #endif
44 : :
45 : : #if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
46 : : # define PYPTHREAD_SIGMASK
47 : : #endif
48 : :
49 : : #if defined(PYPTHREAD_SIGMASK) && defined(HAVE_PTHREAD_H)
50 : : # include <pthread.h>
51 : : #endif
52 : :
53 : : #ifndef SIG_ERR
54 : : # define SIG_ERR ((PyOS_sighandler_t)(-1))
55 : : #endif
56 : :
57 : : #include "clinic/signalmodule.c.h"
58 : :
59 : : /*[clinic input]
60 : : module signal
61 : : [clinic start generated code]*/
62 : : /*[clinic end generated code: output=da39a3ee5e6b4b0d input=b0301a3bde5fe9d3]*/
63 : :
64 : : #ifdef HAVE_SETSIG_T
65 : :
66 : : /*[python input]
67 : :
68 : : class sigset_t_converter(CConverter):
69 : : type = 'sigset_t'
70 : : converter = '_Py_Sigset_Converter'
71 : :
72 : : [python start generated code]*/
73 : : /*[python end generated code: output=da39a3ee5e6b4b0d input=b5689d14466b6823]*/
74 : : #endif
75 : :
76 : : /*
77 : : NOTES ON THE INTERACTION BETWEEN SIGNALS AND THREADS
78 : :
79 : : We want the following semantics:
80 : :
81 : : - only the main thread can set a signal handler
82 : : - only the main thread runs the signal handler
83 : : - signals can be delivered to any thread
84 : : - any thread can get a signal handler
85 : :
86 : : I.e. we don't support "synchronous signals" like SIGFPE (catching
87 : : this doesn't make much sense in Python anyway) nor do we support
88 : : signals as a means of inter-thread communication, since not all
89 : : thread implementations support that (at least our thread library
90 : : doesn't).
91 : :
92 : : We still have the problem that in some implementations signals
93 : : generated by the keyboard (e.g. SIGINT) are delivered to all
94 : : threads (e.g. SGI), while in others (e.g. Solaris) such signals are
95 : : delivered to one random thread. On Linux, signals are delivered to
96 : : the main thread (unless the main thread is blocking the signal, for
97 : : example because it's already handling the same signal). Since we
98 : : allow signals to be delivered to any thread, this works fine. The
99 : : only oddity is that the thread executing the Python signal handler
100 : : may not be the thread that received the signal.
101 : : */
102 : :
103 : : static volatile struct {
104 : : _Py_atomic_int tripped;
105 : : /* func is atomic to ensure that PyErr_SetInterrupt is async-signal-safe
106 : : * (even though it would probably be otherwise, anyway).
107 : : */
108 : : _Py_atomic_address func;
109 : : } Handlers[Py_NSIG];
110 : :
111 : : #ifdef MS_WINDOWS
112 : : #define INVALID_FD ((SOCKET_T)-1)
113 : :
114 : : static volatile struct {
115 : : SOCKET_T fd;
116 : : int warn_on_full_buffer;
117 : : int use_send;
118 : : } wakeup = {.fd = INVALID_FD, .warn_on_full_buffer = 1, .use_send = 0};
119 : : #else
120 : : #define INVALID_FD (-1)
121 : : static volatile struct {
122 : : #ifdef __VXWORKS__
123 : : int fd;
124 : : #else
125 : : sig_atomic_t fd;
126 : : #endif
127 : : int warn_on_full_buffer;
128 : : } wakeup = {.fd = INVALID_FD, .warn_on_full_buffer = 1};
129 : : #endif
130 : :
131 : : /* Speed up sigcheck() when none tripped */
132 : : static _Py_atomic_int is_tripped;
133 : :
134 : : typedef struct {
135 : : PyObject *default_handler;
136 : : PyObject *ignore_handler;
137 : : #ifdef MS_WINDOWS
138 : : HANDLE sigint_event;
139 : : #endif
140 : : } signal_state_t;
141 : :
142 : : // State shared by all Python interpreters
143 : : static signal_state_t signal_global_state = {0};
144 : :
145 : : #if defined(HAVE_GETITIMER) || defined(HAVE_SETITIMER)
146 : : # define PYHAVE_ITIMER_ERROR
147 : : #endif
148 : :
149 : : typedef struct {
150 : : PyObject *default_handler; // borrowed ref (signal_global_state)
151 : : PyObject *ignore_handler; // borrowed ref (signal_global_state)
152 : : #ifdef PYHAVE_ITIMER_ERROR
153 : : PyObject *itimer_error;
154 : : #endif
155 : : PyTypeObject *siginfo_type;
156 : : } _signal_module_state;
157 : :
158 : :
159 : : Py_LOCAL_INLINE(PyObject *)
160 : 465320 : get_handler(int i)
161 : : {
162 : 465320 : return (PyObject *)_Py_atomic_load(&Handlers[i].func);
163 : : }
164 : :
165 : : Py_LOCAL_INLINE(void)
166 : 427525 : set_handler(int i, PyObject* func)
167 : : {
168 : 427525 : _Py_atomic_store(&Handlers[i].func, (uintptr_t)func);
169 : 427525 : }
170 : :
171 : :
172 : : static inline _signal_module_state*
173 : 150724 : get_signal_state(PyObject *module)
174 : : {
175 : 150724 : void *state = _PyModule_GetState(module);
176 : : assert(state != NULL);
177 : 150724 : return (_signal_module_state *)state;
178 : : }
179 : :
180 : :
181 : : static inline int
182 : 276254 : compare_handler(PyObject *func, PyObject *dfl_ign_handler)
183 : : {
184 : : assert(PyLong_CheckExact(dfl_ign_handler));
185 [ + + ]: 276254 : if (!PyLong_CheckExact(func)) {
186 : 68276 : return 0;
187 : : }
188 : : // Assume that comparison of two PyLong objects will never fail.
189 : 207978 : return PyObject_RichCompareBool(func, dfl_ign_handler, Py_EQ) == 1;
190 : : }
191 : :
192 : : #ifdef HAVE_SETITIMER
193 : : /* auxiliary function for setitimer */
194 : : static int
195 : 50952 : timeval_from_double(PyObject *obj, struct timeval *tv)
196 : : {
197 [ + + ]: 50952 : if (obj == NULL) {
198 : 25418 : tv->tv_sec = 0;
199 : 25418 : tv->tv_usec = 0;
200 : 25418 : return 0;
201 : : }
202 : :
203 : : _PyTime_t t;
204 [ - + ]: 25534 : if (_PyTime_FromSecondsObject(&t, obj, _PyTime_ROUND_CEILING) < 0) {
205 : 0 : return -1;
206 : : }
207 : 25534 : return _PyTime_AsTimeval(t, tv, _PyTime_ROUND_CEILING);
208 : : }
209 : : #endif
210 : :
211 : : #if defined(HAVE_SETITIMER) || defined(HAVE_GETITIMER)
212 : : /* auxiliary functions for get/setitimer */
213 : : Py_LOCAL_INLINE(double)
214 : 90558 : double_from_timeval(struct timeval *tv)
215 : : {
216 : 90558 : return tv->tv_sec + (double)(tv->tv_usec / 1000000.0);
217 : : }
218 : :
219 : : static PyObject *
220 : 45279 : itimer_retval(struct itimerval *iv)
221 : : {
222 : : PyObject *r, *v;
223 : :
224 : 45279 : r = PyTuple_New(2);
225 [ - + ]: 45279 : if (r == NULL)
226 : 0 : return NULL;
227 : :
228 [ - + ]: 45279 : if(!(v = PyFloat_FromDouble(double_from_timeval(&iv->it_value)))) {
229 : 0 : Py_DECREF(r);
230 : 0 : return NULL;
231 : : }
232 : :
233 : 45279 : PyTuple_SET_ITEM(r, 0, v);
234 : :
235 [ - + ]: 45279 : if(!(v = PyFloat_FromDouble(double_from_timeval(&iv->it_interval)))) {
236 : 0 : Py_DECREF(r);
237 : 0 : return NULL;
238 : : }
239 : :
240 : 45279 : PyTuple_SET_ITEM(r, 1, v);
241 : :
242 : 45279 : return r;
243 : : }
244 : : #endif
245 : :
246 : : /*[clinic input]
247 : : signal.default_int_handler
248 : : signalnum: int
249 : : frame: object
250 : : /
251 : :
252 : : The default handler for SIGINT installed by Python.
253 : :
254 : : It raises KeyboardInterrupt.
255 : : [clinic start generated code]*/
256 : :
257 : : static PyObject *
258 : 105 : signal_default_int_handler_impl(PyObject *module, int signalnum,
259 : : PyObject *frame)
260 : : /*[clinic end generated code: output=bb11c2eb115ace4e input=efcd4a56a207acfd]*/
261 : : {
262 : 105 : PyErr_SetNone(PyExc_KeyboardInterrupt);
263 : 105 : return NULL;
264 : : }
265 : :
266 : :
267 : : static int
268 : 5 : report_wakeup_write_error(void *data)
269 : : {
270 : : PyObject *exc, *val, *tb;
271 : 5 : int save_errno = errno;
272 : 5 : errno = (int) (intptr_t) data;
273 : 5 : PyErr_Fetch(&exc, &val, &tb);
274 : 5 : PyErr_SetFromErrno(PyExc_OSError);
275 : 5 : PySys_WriteStderr("Exception ignored when trying to write to the "
276 : : "signal wakeup fd:\n");
277 : 5 : PyErr_WriteUnraisable(NULL);
278 : 5 : PyErr_Restore(exc, val, tb);
279 : 5 : errno = save_errno;
280 : 5 : return 0;
281 : : }
282 : :
283 : : #ifdef MS_WINDOWS
284 : : static int
285 : : report_wakeup_send_error(void* data)
286 : : {
287 : : PyObject *exc, *val, *tb;
288 : : PyErr_Fetch(&exc, &val, &tb);
289 : : /* PyErr_SetExcFromWindowsErr() invokes FormatMessage() which
290 : : recognizes the error codes used by both GetLastError() and
291 : : WSAGetLastError */
292 : : PyErr_SetExcFromWindowsErr(PyExc_OSError, (int) (intptr_t) data);
293 : : PySys_WriteStderr("Exception ignored when trying to send to the "
294 : : "signal wakeup fd:\n");
295 : : PyErr_WriteUnraisable(NULL);
296 : : PyErr_Restore(exc, val, tb);
297 : : return 0;
298 : : }
299 : : #endif /* MS_WINDOWS */
300 : :
301 : : static void
302 : 140662 : trip_signal(int sig_num)
303 : : {
304 : 140662 : _Py_atomic_store_relaxed(&Handlers[sig_num].tripped, 1);
305 : :
306 : : /* Set is_tripped after setting .tripped, as it gets
307 : : cleared in PyErr_CheckSignals() before .tripped. */
308 : 140662 : _Py_atomic_store(&is_tripped, 1);
309 : :
310 : : /* Signals are always handled by the main interpreter */
311 : 140662 : PyInterpreterState *interp = _PyInterpreterState_Main();
312 : :
313 : : /* Notify ceval.c */
314 : 140662 : _PyEval_SignalReceived(interp);
315 : :
316 : : /* And then write to the wakeup fd *after* setting all the globals and
317 : : doing the _PyEval_SignalReceived. We used to write to the wakeup fd
318 : : and then set the flag, but this allowed the following sequence of events
319 : : (especially on windows, where trip_signal may run in a new thread):
320 : :
321 : : - main thread blocks on select([wakeup.fd], ...)
322 : : - signal arrives
323 : : - trip_signal writes to the wakeup fd
324 : : - the main thread wakes up
325 : : - the main thread checks the signal flags, sees that they're unset
326 : : - the main thread empties the wakeup fd
327 : : - the main thread goes back to sleep
328 : : - trip_signal sets the flags to request the Python-level signal handler
329 : : be run
330 : : - the main thread doesn't notice, because it's asleep
331 : :
332 : : See bpo-30038 for more details.
333 : : */
334 : :
335 : : int fd;
336 : : #ifdef MS_WINDOWS
337 : : fd = Py_SAFE_DOWNCAST(wakeup.fd, SOCKET_T, int);
338 : : #else
339 : 140662 : fd = wakeup.fd;
340 : : #endif
341 : :
342 [ + + ]: 140662 : if (fd != INVALID_FD) {
343 : 519 : unsigned char byte = (unsigned char)sig_num;
344 : : #ifdef MS_WINDOWS
345 : : if (wakeup.use_send) {
346 : : Py_ssize_t rc = send(fd, &byte, 1, 0);
347 : :
348 : : if (rc < 0) {
349 : : int last_error = GetLastError();
350 : : if (wakeup.warn_on_full_buffer ||
351 : : last_error != WSAEWOULDBLOCK)
352 : : {
353 : : /* _PyEval_AddPendingCall() isn't signal-safe, but we
354 : : still use it for this exceptional case. */
355 : : _PyEval_AddPendingCall(interp,
356 : : report_wakeup_send_error,
357 : : (void *)(intptr_t) last_error);
358 : : }
359 : : }
360 : : }
361 : : else
362 : : #endif
363 : : {
364 : : /* _Py_write_noraise() retries write() if write() is interrupted by
365 : : a signal (fails with EINTR). */
366 : 519 : Py_ssize_t rc = _Py_write_noraise(fd, &byte, 1);
367 : :
368 [ + + ]: 519 : if (rc < 0) {
369 [ + + ]: 6 : if (wakeup.warn_on_full_buffer ||
370 [ - + - - ]: 1 : (errno != EWOULDBLOCK && errno != EAGAIN))
371 : : {
372 : : /* _PyEval_AddPendingCall() isn't signal-safe, but we
373 : : still use it for this exceptional case. */
374 : 5 : _PyEval_AddPendingCall(interp,
375 : : report_wakeup_write_error,
376 : 5 : (void *)(intptr_t)errno);
377 : : }
378 : : }
379 : : }
380 : : }
381 : 140662 : }
382 : :
383 : : static void
384 : 140655 : signal_handler(int sig_num)
385 : : {
386 : 140655 : int save_errno = errno;
387 : :
388 : 140655 : trip_signal(sig_num);
389 : :
390 : : #ifndef HAVE_SIGACTION
391 : : #ifdef SIGCHLD
392 : : /* To avoid infinite recursion, this signal remains
393 : : reset until explicit re-instated.
394 : : Don't clear the 'func' field as it is our pointer
395 : : to the Python handler... */
396 : : if (sig_num != SIGCHLD)
397 : : #endif
398 : : /* If the handler was not set up with sigaction, reinstall it. See
399 : : * Python/pylifecycle.c for the implementation of PyOS_setsig which
400 : : * makes this true. See also issue8354. */
401 : : PyOS_setsig(sig_num, signal_handler);
402 : : #endif
403 : :
404 : : /* Issue #10311: asynchronously executing signal handlers should not
405 : : mutate errno under the feet of unsuspecting C code. */
406 : 140655 : errno = save_errno;
407 : :
408 : : #ifdef MS_WINDOWS
409 : : if (sig_num == SIGINT) {
410 : : signal_state_t *state = &signal_global_state;
411 : : SetEvent(state->sigint_event);
412 : : }
413 : : #endif
414 : 140655 : }
415 : :
416 : :
417 : : #ifdef HAVE_ALARM
418 : :
419 : : /*[clinic input]
420 : : signal.alarm -> long
421 : :
422 : : seconds: int
423 : : /
424 : :
425 : : Arrange for SIGALRM to arrive after the given number of seconds.
426 : : [clinic start generated code]*/
427 : :
428 : : static long
429 : 126 : signal_alarm_impl(PyObject *module, int seconds)
430 : : /*[clinic end generated code: output=144232290814c298 input=0d5e97e0e6f39e86]*/
431 : : {
432 : : /* alarm() returns the number of seconds remaining */
433 : 126 : return (long)alarm(seconds);
434 : : }
435 : :
436 : : #endif
437 : :
438 : : #ifdef HAVE_PAUSE
439 : :
440 : : /*[clinic input]
441 : : signal.pause
442 : :
443 : : Wait until a signal arrives.
444 : : [clinic start generated code]*/
445 : :
446 : : static PyObject *
447 : 2 : signal_pause_impl(PyObject *module)
448 : : /*[clinic end generated code: output=391656788b3c3929 input=f03de0f875752062]*/
449 : : {
450 : 2 : Py_BEGIN_ALLOW_THREADS
451 : 2 : (void)pause();
452 : 2 : Py_END_ALLOW_THREADS
453 : : /* make sure that any exceptions that got raised are propagated
454 : : * back into Python
455 : : */
456 [ + + ]: 2 : if (PyErr_CheckSignals())
457 : 1 : return NULL;
458 : :
459 : 1 : Py_RETURN_NONE;
460 : : }
461 : :
462 : : #endif
463 : :
464 : : /*[clinic input]
465 : : signal.raise_signal
466 : :
467 : : signalnum: int
468 : : /
469 : :
470 : : Send a signal to the executing process.
471 : : [clinic start generated code]*/
472 : :
473 : : static PyObject *
474 : 512843 : signal_raise_signal_impl(PyObject *module, int signalnum)
475 : : /*[clinic end generated code: output=e2b014220aa6111d input=e90c0f9a42358de6]*/
476 : : {
477 : : int err;
478 : 512843 : Py_BEGIN_ALLOW_THREADS
479 : : _Py_BEGIN_SUPPRESS_IPH
480 : 512843 : err = raise(signalnum);
481 : : _Py_END_SUPPRESS_IPH
482 : 512843 : Py_END_ALLOW_THREADS
483 : :
484 [ - + ]: 512843 : if (err) {
485 : 0 : return PyErr_SetFromErrno(PyExc_OSError);
486 : : }
487 : :
488 : : // If the current thread can handle signals, handle immediately
489 : : // the raised signal.
490 [ + + ]: 512843 : if (PyErr_CheckSignals()) {
491 : 5 : return NULL;
492 : : }
493 : :
494 : 512838 : Py_RETURN_NONE;
495 : : }
496 : :
497 : : /*[clinic input]
498 : : signal.signal
499 : :
500 : : signalnum: int
501 : : handler: object
502 : : /
503 : :
504 : : Set the action for the given signal.
505 : :
506 : : The action can be SIG_DFL, SIG_IGN, or a callable Python object.
507 : : The previous action is returned. See getsignal() for possible return values.
508 : :
509 : : *** IMPORTANT NOTICE ***
510 : : A signal handler function is called with two arguments:
511 : : the first is the signal number, the second is the interrupted stack frame.
512 : : [clinic start generated code]*/
513 : :
514 : : static PyObject *
515 : 47321 : signal_signal_impl(PyObject *module, int signalnum, PyObject *handler)
516 : : /*[clinic end generated code: output=b44cfda43780f3a1 input=deee84af5fa0432c]*/
517 : : {
518 : 47321 : _signal_module_state *modstate = get_signal_state(module);
519 : : PyObject *old_handler;
520 : : void (*func)(int);
521 : : #ifdef MS_WINDOWS
522 : : /* Validate that signalnum is one of the allowable signals */
523 : : switch (signalnum) {
524 : : case SIGABRT: break;
525 : : #ifdef SIGBREAK
526 : : /* Issue #10003: SIGBREAK is not documented as permitted, but works
527 : : and corresponds to CTRL_BREAK_EVENT. */
528 : : case SIGBREAK: break;
529 : : #endif
530 : : case SIGFPE: break;
531 : : case SIGILL: break;
532 : : case SIGINT: break;
533 : : case SIGSEGV: break;
534 : : case SIGTERM: break;
535 : : default:
536 : : PyErr_SetString(PyExc_ValueError, "invalid signal value");
537 : : return NULL;
538 : : }
539 : : #endif
540 : :
541 : 47321 : PyThreadState *tstate = _PyThreadState_GET();
542 [ + + ]: 47321 : if (!_Py_ThreadCanHandleSignals(tstate->interp)) {
543 : 3 : _PyErr_SetString(tstate, PyExc_ValueError,
544 : : "signal only works in main thread "
545 : : "of the main interpreter");
546 : 3 : return NULL;
547 : : }
548 [ + - + + ]: 47318 : if (signalnum < 1 || signalnum >= Py_NSIG) {
549 : 1 : _PyErr_SetString(tstate, PyExc_ValueError,
550 : : "signal number out of range");
551 : 1 : return NULL;
552 : : }
553 [ + + ]: 47317 : if (PyCallable_Check(handler)) {
554 : 22895 : func = signal_handler;
555 [ + + ]: 24422 : } else if (compare_handler(handler, modstate->ignore_handler)) {
556 : 20360 : func = SIG_IGN;
557 [ + + ]: 4062 : } else if (compare_handler(handler, modstate->default_handler)) {
558 : 4061 : func = SIG_DFL;
559 : : } else {
560 : 1 : _PyErr_SetString(tstate, PyExc_TypeError,
561 : : "signal handler must be signal.SIG_IGN, "
562 : : "signal.SIG_DFL, or a callable object");
563 : 1 : return NULL;
564 : : }
565 : :
566 : : /* Check for pending signals before changing signal handler */
567 [ - + ]: 47316 : if (_PyErr_CheckSignalsTstate(tstate)) {
568 : 0 : return NULL;
569 : : }
570 [ + + ]: 47316 : if (PyOS_setsig(signalnum, func) == SIG_ERR) {
571 : 3 : PyErr_SetFromErrno(PyExc_OSError);
572 : 3 : return NULL;
573 : : }
574 : :
575 : 47313 : old_handler = get_handler(signalnum);
576 : 47313 : set_handler(signalnum, Py_NewRef(handler));
577 : :
578 [ + - ]: 47313 : if (old_handler != NULL) {
579 : 47313 : return old_handler;
580 : : }
581 : : else {
582 : 0 : Py_RETURN_NONE;
583 : : }
584 : : }
585 : :
586 : :
587 : : /*[clinic input]
588 : : signal.getsignal
589 : :
590 : : signalnum: int
591 : : /
592 : :
593 : : Return the current action for the given signal.
594 : :
595 : : The return value can be:
596 : : SIG_IGN -- if the signal is being ignored
597 : : SIG_DFL -- if the default action for the signal is in effect
598 : : None -- if an unknown handler is in effect
599 : : anything else -- the callable Python object used as a handler
600 : : [clinic start generated code]*/
601 : :
602 : : static PyObject *
603 : 6491 : signal_getsignal_impl(PyObject *module, int signalnum)
604 : : /*[clinic end generated code: output=35b3e0e796fd555e input=ac23a00f19dfa509]*/
605 : : {
606 : : PyObject *old_handler;
607 [ + - + + ]: 6491 : if (signalnum < 1 || signalnum >= Py_NSIG) {
608 : 1 : PyErr_SetString(PyExc_ValueError,
609 : : "signal number out of range");
610 : 1 : return NULL;
611 : : }
612 : 6490 : old_handler = get_handler(signalnum);
613 [ + - ]: 6490 : if (old_handler != NULL) {
614 : 6490 : return Py_NewRef(old_handler);
615 : : }
616 : : else {
617 : 0 : Py_RETURN_NONE;
618 : : }
619 : : }
620 : :
621 : :
622 : : /*[clinic input]
623 : : signal.strsignal
624 : :
625 : : signalnum: int
626 : : /
627 : :
628 : : Return the system description of the given signal.
629 : :
630 : : The return values can be such as "Interrupt", "Segmentation fault", etc.
631 : : Returns None if the signal is not recognized.
632 : : [clinic start generated code]*/
633 : :
634 : : static PyObject *
635 : 4 : signal_strsignal_impl(PyObject *module, int signalnum)
636 : : /*[clinic end generated code: output=44e12e1e3b666261 input=b77914b03f856c74]*/
637 : : {
638 : : const char *res;
639 : :
640 [ + - + + ]: 4 : if (signalnum < 1 || signalnum >= Py_NSIG) {
641 : 1 : PyErr_SetString(PyExc_ValueError,
642 : : "signal number out of range");
643 : 1 : return NULL;
644 : : }
645 : :
646 : : #ifndef HAVE_STRSIGNAL
647 : : switch (signalnum) {
648 : : /* Though being a UNIX, HP-UX does not provide strsignal(3). */
649 : : #ifndef MS_WINDOWS
650 : : case SIGHUP:
651 : : res = "Hangup";
652 : : break;
653 : : case SIGALRM:
654 : : res = "Alarm clock";
655 : : break;
656 : : case SIGPIPE:
657 : : res = "Broken pipe";
658 : : break;
659 : : case SIGQUIT:
660 : : res = "Quit";
661 : : break;
662 : : case SIGCHLD:
663 : : res = "Child exited";
664 : : break;
665 : : #endif
666 : : /* Custom redefinition of POSIX signals allowed on Windows. */
667 : : case SIGINT:
668 : : res = "Interrupt";
669 : : break;
670 : : case SIGILL:
671 : : res = "Illegal instruction";
672 : : break;
673 : : case SIGABRT:
674 : : res = "Aborted";
675 : : break;
676 : : case SIGFPE:
677 : : res = "Floating point exception";
678 : : break;
679 : : case SIGSEGV:
680 : : res = "Segmentation fault";
681 : : break;
682 : : case SIGTERM:
683 : : res = "Terminated";
684 : : break;
685 : : default:
686 : : Py_RETURN_NONE;
687 : : }
688 : : #else
689 : 3 : errno = 0;
690 : 3 : res = strsignal(signalnum);
691 : :
692 [ + - + - : 3 : if (errno || res == NULL || strstr(res, "Unknown signal") != NULL)
- + ]
693 : 0 : Py_RETURN_NONE;
694 : : #endif
695 : :
696 : 3 : return Py_BuildValue("s", res);
697 : : }
698 : :
699 : : #ifdef HAVE_SIGINTERRUPT
700 : :
701 : : /*[clinic input]
702 : : signal.siginterrupt
703 : :
704 : : signalnum: int
705 : : flag: int
706 : : /
707 : :
708 : : Change system call restart behaviour.
709 : :
710 : : If flag is False, system calls will be restarted when interrupted by
711 : : signal sig, else system calls will be interrupted.
712 : : [clinic start generated code]*/
713 : :
714 : : static PyObject *
715 : 284 : signal_siginterrupt_impl(PyObject *module, int signalnum, int flag)
716 : : /*[clinic end generated code: output=063816243d85dd19 input=4160acacca3e2099]*/
717 : : {
718 [ + - - + ]: 284 : if (signalnum < 1 || signalnum >= Py_NSIG) {
719 : 0 : PyErr_SetString(PyExc_ValueError,
720 : : "signal number out of range");
721 : 0 : return NULL;
722 : : }
723 : : #ifdef HAVE_SIGACTION
724 : : struct sigaction act;
725 : 284 : (void) sigaction(signalnum, NULL, &act);
726 [ + + ]: 284 : if (flag) {
727 : 1 : act.sa_flags &= ~SA_RESTART;
728 : : }
729 : : else {
730 : 283 : act.sa_flags |= SA_RESTART;
731 : : }
732 [ - + ]: 284 : if (sigaction(signalnum, &act, NULL) < 0) {
733 : : #else
734 : : if (siginterrupt(signalnum, flag) < 0) {
735 : : #endif
736 : 0 : PyErr_SetFromErrno(PyExc_OSError);
737 : 0 : return NULL;
738 : : }
739 : 284 : Py_RETURN_NONE;
740 : : }
741 : :
742 : : #endif
743 : :
744 : :
745 : : static PyObject*
746 : 641 : signal_set_wakeup_fd(PyObject *self, PyObject *args, PyObject *kwds)
747 : : {
748 : : struct _Py_stat_struct status;
749 : : static char *kwlist[] = {
750 : : "", "warn_on_full_buffer", NULL,
751 : : };
752 : 641 : int warn_on_full_buffer = 1;
753 : : #ifdef MS_WINDOWS
754 : : PyObject *fdobj;
755 : : SOCKET_T sockfd, old_sockfd;
756 : : int res;
757 : : int res_size = sizeof res;
758 : : PyObject *mod;
759 : : int is_socket;
760 : :
761 : : if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|$p:set_wakeup_fd", kwlist,
762 : : &fdobj, &warn_on_full_buffer))
763 : : return NULL;
764 : :
765 : : sockfd = PyLong_AsSocket_t(fdobj);
766 : : if (sockfd == (SOCKET_T)(-1) && PyErr_Occurred())
767 : : return NULL;
768 : : #else
769 : : int fd;
770 : :
771 [ + + ]: 641 : if (!PyArg_ParseTupleAndKeywords(args, kwds, "i|$p:set_wakeup_fd", kwlist,
772 : : &fd, &warn_on_full_buffer))
773 : 2 : return NULL;
774 : : #endif
775 : :
776 : 639 : PyThreadState *tstate = _PyThreadState_GET();
777 [ - + ]: 639 : if (!_Py_ThreadCanHandleSignals(tstate->interp)) {
778 : 0 : _PyErr_SetString(tstate, PyExc_ValueError,
779 : : "set_wakeup_fd only works in main thread "
780 : : "of the main interpreter");
781 : 0 : return NULL;
782 : : }
783 : :
784 : : #ifdef MS_WINDOWS
785 : : is_socket = 0;
786 : : if (sockfd != INVALID_FD) {
787 : : /* Import the _socket module to call WSAStartup() */
788 : : mod = PyImport_ImportModule("_socket");
789 : : if (mod == NULL)
790 : : return NULL;
791 : : Py_DECREF(mod);
792 : :
793 : : /* test the socket */
794 : : if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR,
795 : : (char *)&res, &res_size) != 0) {
796 : : int fd, err;
797 : :
798 : : err = WSAGetLastError();
799 : : if (err != WSAENOTSOCK) {
800 : : PyErr_SetExcFromWindowsErr(PyExc_OSError, err);
801 : : return NULL;
802 : : }
803 : :
804 : : fd = (int)sockfd;
805 : : if ((SOCKET_T)fd != sockfd) {
806 : : _PyErr_SetString(tstate, PyExc_ValueError, "invalid fd");
807 : : return NULL;
808 : : }
809 : :
810 : : if (_Py_fstat(fd, &status) != 0) {
811 : : return NULL;
812 : : }
813 : :
814 : : /* on Windows, a file cannot be set to non-blocking mode */
815 : : }
816 : : else {
817 : : is_socket = 1;
818 : :
819 : : /* Windows does not provide a function to test if a socket
820 : : is in non-blocking mode */
821 : : }
822 : : }
823 : :
824 : : old_sockfd = wakeup.fd;
825 : : wakeup.fd = sockfd;
826 : : wakeup.warn_on_full_buffer = warn_on_full_buffer;
827 : : wakeup.use_send = is_socket;
828 : :
829 : : if (old_sockfd != INVALID_FD)
830 : : return PyLong_FromSocket_t(old_sockfd);
831 : : else
832 : : return PyLong_FromLong(-1);
833 : : #else
834 [ + + ]: 639 : if (fd != -1) {
835 : : int blocking;
836 : :
837 [ + + ]: 338 : if (_Py_fstat(fd, &status) != 0)
838 : 2 : return NULL;
839 : :
840 : 336 : blocking = _Py_get_blocking(fd);
841 [ - + ]: 336 : if (blocking < 0)
842 : 0 : return NULL;
843 [ + + ]: 336 : if (blocking) {
844 : 1 : _PyErr_Format(tstate, PyExc_ValueError,
845 : : "the fd %i must be in non-blocking mode",
846 : : fd);
847 : 1 : return NULL;
848 : : }
849 : : }
850 : :
851 : 636 : int old_fd = wakeup.fd;
852 : 636 : wakeup.fd = fd;
853 : 636 : wakeup.warn_on_full_buffer = warn_on_full_buffer;
854 : :
855 : 636 : return PyLong_FromLong(old_fd);
856 : : #endif
857 : : }
858 : :
859 : : PyDoc_STRVAR(set_wakeup_fd_doc,
860 : : "set_wakeup_fd(fd, *, warn_on_full_buffer=True) -> fd\n\
861 : : \n\
862 : : Sets the fd to be written to (with the signal number) when a signal\n\
863 : : comes in. A library can use this to wakeup select or poll.\n\
864 : : The previous fd or -1 is returned.\n\
865 : : \n\
866 : : The fd must be non-blocking.");
867 : :
868 : : /* C API for the same, without all the error checking */
869 : : int
870 : 0 : PySignal_SetWakeupFd(int fd)
871 : : {
872 [ # # ]: 0 : if (fd < 0) {
873 : 0 : fd = -1;
874 : : }
875 : :
876 : : #ifdef MS_WINDOWS
877 : : int old_fd = Py_SAFE_DOWNCAST(wakeup.fd, SOCKET_T, int);
878 : : #else
879 : 0 : int old_fd = wakeup.fd;
880 : : #endif
881 : 0 : wakeup.fd = fd;
882 : 0 : wakeup.warn_on_full_buffer = 1;
883 : 0 : return old_fd;
884 : : }
885 : :
886 : :
887 : : #ifdef HAVE_SETITIMER
888 : : /*[clinic input]
889 : : signal.setitimer
890 : :
891 : : which: int
892 : : seconds: object
893 : : interval: object(c_default="NULL") = 0.0
894 : : /
895 : :
896 : : Sets given itimer (one of ITIMER_REAL, ITIMER_VIRTUAL or ITIMER_PROF).
897 : :
898 : : The timer will fire after value seconds and after that every interval seconds.
899 : : The itimer can be cleared by setting seconds to zero.
900 : :
901 : : Returns old values as a tuple: (delay, interval).
902 : : [clinic start generated code]*/
903 : :
904 : : static PyObject *
905 : 25476 : signal_setitimer_impl(PyObject *module, int which, PyObject *seconds,
906 : : PyObject *interval)
907 : : /*[clinic end generated code: output=65f9dcbddc35527b input=de43daf194e6f66f]*/
908 : : {
909 : 25476 : _signal_module_state *modstate = get_signal_state(module);
910 : :
911 : : struct itimerval new;
912 [ - + ]: 25476 : if (timeval_from_double(seconds, &new.it_value) < 0) {
913 : 0 : return NULL;
914 : : }
915 [ - + ]: 25476 : if (timeval_from_double(interval, &new.it_interval) < 0) {
916 : 0 : return NULL;
917 : : }
918 : :
919 : : /* Let OS check "which" value */
920 : : struct itimerval old;
921 [ + + ]: 25476 : if (setitimer(which, &new, &old) != 0) {
922 : 1 : PyErr_SetFromErrno(modstate->itimer_error);
923 : 1 : return NULL;
924 : : }
925 : :
926 : 25475 : return itimer_retval(&old);
927 : : }
928 : : #endif // HAVE_SETITIMER
929 : :
930 : :
931 : : #ifdef HAVE_GETITIMER
932 : : /*[clinic input]
933 : : signal.getitimer
934 : :
935 : : which: int
936 : : /
937 : :
938 : : Returns current value of given itimer.
939 : : [clinic start generated code]*/
940 : :
941 : : static PyObject *
942 : 19804 : signal_getitimer_impl(PyObject *module, int which)
943 : : /*[clinic end generated code: output=9e053175d517db40 input=f7d21d38f3490627]*/
944 : : {
945 : 19804 : _signal_module_state *modstate = get_signal_state(module);
946 : :
947 : : struct itimerval old;
948 [ - + ]: 19804 : if (getitimer(which, &old) != 0) {
949 : 0 : PyErr_SetFromErrno(modstate->itimer_error);
950 : 0 : return NULL;
951 : : }
952 : :
953 : 19804 : return itimer_retval(&old);
954 : : }
955 : : #endif // HAVE_GETITIMER
956 : :
957 : :
958 : : #ifdef HAVE_SIGSET_T
959 : : #if defined(PYPTHREAD_SIGMASK) || defined(HAVE_SIGPENDING)
960 : : static PyObject*
961 : 909 : sigset_to_set(sigset_t mask)
962 : : {
963 : : PyObject *signum, *result;
964 : : int sig;
965 : :
966 : 909 : result = PySet_New(0);
967 [ - + ]: 909 : if (result == NULL)
968 : 0 : return NULL;
969 : :
970 [ + + ]: 59085 : for (sig = 1; sig < Py_NSIG; sig++) {
971 [ + + ]: 58176 : if (sigismember(&mask, sig) != 1)
972 : 14662 : continue;
973 : :
974 : : /* Handle the case where it is a member by adding the signal to
975 : : the result list. Ignore the other cases because they mean the
976 : : signal isn't a member of the mask or the signal was invalid,
977 : : and an invalid signal must have been our fault in constructing
978 : : the loop boundaries. */
979 : 43514 : signum = PyLong_FromLong(sig);
980 [ - + ]: 43514 : if (signum == NULL) {
981 : 0 : Py_DECREF(result);
982 : 0 : return NULL;
983 : : }
984 [ - + ]: 43514 : if (PySet_Add(result, signum) == -1) {
985 : 0 : Py_DECREF(signum);
986 : 0 : Py_DECREF(result);
987 : 0 : return NULL;
988 : : }
989 : 43514 : Py_DECREF(signum);
990 : : }
991 : 909 : return result;
992 : : }
993 : : #endif
994 : :
995 : : #ifdef PYPTHREAD_SIGMASK
996 : :
997 : : /*[clinic input]
998 : : signal.pthread_sigmask
999 : :
1000 : : how: int
1001 : : mask: sigset_t
1002 : : /
1003 : :
1004 : : Fetch and/or change the signal mask of the calling thread.
1005 : : [clinic start generated code]*/
1006 : :
1007 : : static PyObject *
1008 : 213 : signal_pthread_sigmask_impl(PyObject *module, int how, sigset_t mask)
1009 : : /*[clinic end generated code: output=0562c0fb192981a8 input=85bcebda442fa77f]*/
1010 : : {
1011 : : sigset_t previous;
1012 : : int err;
1013 : :
1014 : 213 : err = pthread_sigmask(how, &mask, &previous);
1015 [ + + ]: 213 : if (err != 0) {
1016 : 1 : errno = err;
1017 : 1 : PyErr_SetFromErrno(PyExc_OSError);
1018 : 1 : return NULL;
1019 : : }
1020 : :
1021 : : /* if signals was unblocked, signal handlers have been called */
1022 [ + + ]: 212 : if (PyErr_CheckSignals())
1023 : 2 : return NULL;
1024 : :
1025 : 210 : return sigset_to_set(previous);
1026 : : }
1027 : :
1028 : : #endif /* #ifdef PYPTHREAD_SIGMASK */
1029 : :
1030 : :
1031 : : #ifdef HAVE_SIGPENDING
1032 : :
1033 : : /*[clinic input]
1034 : : signal.sigpending
1035 : :
1036 : : Examine pending signals.
1037 : :
1038 : : Returns a set of signal numbers that are pending for delivery to
1039 : : the calling thread.
1040 : : [clinic start generated code]*/
1041 : :
1042 : : static PyObject *
1043 : 2 : signal_sigpending_impl(PyObject *module)
1044 : : /*[clinic end generated code: output=53375ffe89325022 input=e0036c016f874e29]*/
1045 : : {
1046 : : int err;
1047 : : sigset_t mask;
1048 : 2 : err = sigpending(&mask);
1049 [ - + ]: 2 : if (err)
1050 : 0 : return PyErr_SetFromErrno(PyExc_OSError);
1051 : 2 : return sigset_to_set(mask);
1052 : : }
1053 : :
1054 : : #endif /* #ifdef HAVE_SIGPENDING */
1055 : :
1056 : :
1057 : : #ifdef HAVE_SIGWAIT
1058 : :
1059 : : /*[clinic input]
1060 : : signal.sigwait
1061 : :
1062 : : sigset: sigset_t
1063 : : /
1064 : :
1065 : : Wait for a signal.
1066 : :
1067 : : Suspend execution of the calling thread until the delivery of one of the
1068 : : signals specified in the signal set sigset. The function accepts the signal
1069 : : and returns the signal number.
1070 : : [clinic start generated code]*/
1071 : :
1072 : : static PyObject *
1073 : 2 : signal_sigwait_impl(PyObject *module, sigset_t sigset)
1074 : : /*[clinic end generated code: output=f43770699d682f96 input=a6fbd47b1086d119]*/
1075 : : {
1076 : : int err, signum;
1077 : :
1078 : 2 : Py_BEGIN_ALLOW_THREADS
1079 : 2 : err = sigwait(&sigset, &signum);
1080 : 2 : Py_END_ALLOW_THREADS
1081 [ - + ]: 2 : if (err) {
1082 : 0 : errno = err;
1083 : 0 : return PyErr_SetFromErrno(PyExc_OSError);
1084 : : }
1085 : :
1086 : 2 : return PyLong_FromLong(signum);
1087 : : }
1088 : :
1089 : : #endif /* #ifdef HAVE_SIGWAIT */
1090 : : #endif /* #ifdef HAVE_SIGSET_T */
1091 : :
1092 : : #if (defined(HAVE_SIGFILLSET) && defined(HAVE_SIGSET_T)) || defined(MS_WINDOWS)
1093 : :
1094 : : /*[clinic input]
1095 : : signal.valid_signals
1096 : :
1097 : : Return a set of valid signal numbers on this platform.
1098 : :
1099 : : The signal numbers returned by this function can be safely passed to
1100 : : functions like `pthread_sigmask`.
1101 : : [clinic start generated code]*/
1102 : :
1103 : : static PyObject *
1104 : 697 : signal_valid_signals_impl(PyObject *module)
1105 : : /*[clinic end generated code: output=1609cffbcfcf1314 input=86a3717ff25288f2]*/
1106 : : {
1107 : : #ifdef MS_WINDOWS
1108 : : #ifdef SIGBREAK
1109 : : PyObject *tup = Py_BuildValue("(iiiiiii)", SIGABRT, SIGBREAK, SIGFPE,
1110 : : SIGILL, SIGINT, SIGSEGV, SIGTERM);
1111 : : #else
1112 : : PyObject *tup = Py_BuildValue("(iiiiii)", SIGABRT, SIGFPE, SIGILL,
1113 : : SIGINT, SIGSEGV, SIGTERM);
1114 : : #endif
1115 : : if (tup == NULL) {
1116 : : return NULL;
1117 : : }
1118 : : PyObject *set = PySet_New(tup);
1119 : : Py_DECREF(tup);
1120 : : return set;
1121 : : #else
1122 : : sigset_t mask;
1123 [ + - - + ]: 697 : if (sigemptyset(&mask) || sigfillset(&mask)) {
1124 : 0 : return PyErr_SetFromErrno(PyExc_OSError);
1125 : : }
1126 : 697 : return sigset_to_set(mask);
1127 : : #endif
1128 : : }
1129 : :
1130 : : #endif /* #if (defined(HAVE_SIGFILLSET) && defined(HAVE_SIGSET_T)) || defined(MS_WINDOWS) */
1131 : :
1132 : :
1133 : :
1134 : : #if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT)
1135 : : static PyStructSequence_Field struct_siginfo_fields[] = {
1136 : : {"si_signo", "signal number"},
1137 : : {"si_code", "signal code"},
1138 : : {"si_errno", "errno associated with this signal"},
1139 : : {"si_pid", "sending process ID"},
1140 : : {"si_uid", "real user ID of sending process"},
1141 : : {"si_status", "exit value or signal"},
1142 : : {"si_band", "band event for SIGPOLL"},
1143 : : {0}
1144 : : };
1145 : :
1146 : : PyDoc_STRVAR(struct_siginfo__doc__,
1147 : : "struct_siginfo: Result from sigwaitinfo or sigtimedwait.\n\n\
1148 : : This object may be accessed either as a tuple of\n\
1149 : : (si_signo, si_code, si_errno, si_pid, si_uid, si_status, si_band),\n\
1150 : : or via the attributes si_signo, si_code, and so on.");
1151 : :
1152 : : static PyStructSequence_Desc struct_siginfo_desc = {
1153 : : "signal.struct_siginfo", /* name */
1154 : : struct_siginfo__doc__, /* doc */
1155 : : struct_siginfo_fields, /* fields */
1156 : : 7 /* n_in_sequence */
1157 : : };
1158 : :
1159 : :
1160 : : static PyObject *
1161 : 5 : fill_siginfo(_signal_module_state *state, siginfo_t *si)
1162 : : {
1163 : 5 : PyObject *result = PyStructSequence_New(state->siginfo_type);
1164 [ - + ]: 5 : if (!result)
1165 : 0 : return NULL;
1166 : :
1167 : 5 : PyStructSequence_SET_ITEM(result, 0, PyLong_FromLong((long)(si->si_signo)));
1168 : 5 : PyStructSequence_SET_ITEM(result, 1, PyLong_FromLong((long)(si->si_code)));
1169 : : #ifdef __VXWORKS__
1170 : : PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong(0L));
1171 : : PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong(0L));
1172 : : PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong(0L));
1173 : : PyStructSequence_SET_ITEM(result, 5, PyLong_FromLong(0L));
1174 : : #else
1175 : 5 : PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si->si_errno)));
1176 : 5 : PyStructSequence_SET_ITEM(result, 3, PyLong_FromPid(si->si_pid));
1177 : 5 : PyStructSequence_SET_ITEM(result, 4, _PyLong_FromUid(si->si_uid));
1178 : 5 : PyStructSequence_SET_ITEM(result, 5,
1179 : : PyLong_FromLong((long)(si->si_status)));
1180 : : #endif
1181 : : #ifdef HAVE_SIGINFO_T_SI_BAND
1182 : 5 : PyStructSequence_SET_ITEM(result, 6, PyLong_FromLong(si->si_band));
1183 : : #else
1184 : : PyStructSequence_SET_ITEM(result, 6, PyLong_FromLong(0L));
1185 : : #endif
1186 [ - + ]: 5 : if (PyErr_Occurred()) {
1187 : 0 : Py_DECREF(result);
1188 : 0 : return NULL;
1189 : : }
1190 : :
1191 : 5 : return result;
1192 : : }
1193 : : #endif
1194 : :
1195 : : #ifdef HAVE_SIGSET_T
1196 : : #ifdef HAVE_SIGWAITINFO
1197 : :
1198 : : /*[clinic input]
1199 : : signal.sigwaitinfo
1200 : :
1201 : : sigset: sigset_t
1202 : : /
1203 : :
1204 : : Wait synchronously until one of the signals in *sigset* is delivered.
1205 : :
1206 : : Returns a struct_siginfo containing information about the signal.
1207 : : [clinic start generated code]*/
1208 : :
1209 : : static PyObject *
1210 : 2 : signal_sigwaitinfo_impl(PyObject *module, sigset_t sigset)
1211 : : /*[clinic end generated code: output=1eb2f1fa236fdbca input=3d1a7e1f27fc664c]*/
1212 : : {
1213 : : siginfo_t si;
1214 : : int err;
1215 : 2 : int async_err = 0;
1216 : :
1217 : : do {
1218 : 5 : Py_BEGIN_ALLOW_THREADS
1219 : 5 : err = sigwaitinfo(&sigset, &si);
1220 : 5 : Py_END_ALLOW_THREADS
1221 : : } while (err == -1
1222 [ + + + - : 5 : && errno == EINTR && !(async_err = PyErr_CheckSignals()));
+ - ]
1223 [ - + ]: 2 : if (err == -1)
1224 [ # # ]: 0 : return (!async_err) ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
1225 : :
1226 : 2 : _signal_module_state *state = get_signal_state(module);
1227 : 2 : return fill_siginfo(state, &si);
1228 : : }
1229 : :
1230 : : #endif /* #ifdef HAVE_SIGWAITINFO */
1231 : :
1232 : : #ifdef HAVE_SIGTIMEDWAIT
1233 : :
1234 : : /*[clinic input]
1235 : : signal.sigtimedwait
1236 : :
1237 : : sigset: sigset_t
1238 : : timeout as timeout_obj: object
1239 : : /
1240 : :
1241 : : Like sigwaitinfo(), but with a timeout.
1242 : :
1243 : : The timeout is specified in seconds, with floating point numbers allowed.
1244 : : [clinic start generated code]*/
1245 : :
1246 : : static PyObject *
1247 : 5 : signal_sigtimedwait_impl(PyObject *module, sigset_t sigset,
1248 : : PyObject *timeout_obj)
1249 : : /*[clinic end generated code: output=59c8971e8ae18a64 input=87fd39237cf0b7ba]*/
1250 : : {
1251 : : _PyTime_t timeout;
1252 [ - + ]: 5 : if (_PyTime_FromSecondsObject(&timeout,
1253 : : timeout_obj, _PyTime_ROUND_CEILING) < 0)
1254 : 0 : return NULL;
1255 : :
1256 [ + + ]: 5 : if (timeout < 0) {
1257 : 1 : PyErr_SetString(PyExc_ValueError, "timeout must be non-negative");
1258 : 1 : return NULL;
1259 : : }
1260 : :
1261 : 4 : _PyTime_t deadline = _PyDeadline_Init(timeout);
1262 : : siginfo_t si;
1263 : :
1264 : 3 : do {
1265 : : struct timespec ts;
1266 [ - + ]: 7 : if (_PyTime_AsTimespec(timeout, &ts) < 0) {
1267 : 1 : return NULL;
1268 : : }
1269 : :
1270 : : int res;
1271 : 7 : Py_BEGIN_ALLOW_THREADS
1272 : 7 : res = sigtimedwait(&sigset, &si, &ts);
1273 : 7 : Py_END_ALLOW_THREADS
1274 : :
1275 [ + + ]: 7 : if (res != -1)
1276 : 3 : break;
1277 : :
1278 [ + + ]: 4 : if (errno != EINTR) {
1279 [ + - ]: 1 : if (errno == EAGAIN)
1280 : 1 : Py_RETURN_NONE;
1281 : : else
1282 : 0 : return PyErr_SetFromErrno(PyExc_OSError);
1283 : : }
1284 : :
1285 : : /* sigtimedwait() was interrupted by a signal (EINTR) */
1286 [ - + ]: 3 : if (PyErr_CheckSignals())
1287 : 0 : return NULL;
1288 : :
1289 : 3 : timeout = _PyDeadline_Get(deadline);
1290 [ - + ]: 3 : if (timeout < 0) {
1291 : 0 : break;
1292 : : }
1293 : : } while (1);
1294 : :
1295 : 3 : _signal_module_state *state = get_signal_state(module);
1296 : 3 : return fill_siginfo(state, &si);
1297 : : }
1298 : :
1299 : : #endif /* #ifdef HAVE_SIGTIMEDWAIT */
1300 : : #endif /* #ifdef HAVE_SIGSET_T */
1301 : :
1302 : :
1303 : : #if defined(HAVE_PTHREAD_KILL)
1304 : :
1305 : : /*[clinic input]
1306 : : signal.pthread_kill
1307 : :
1308 : : thread_id: unsigned_long(bitwise=True)
1309 : : signalnum: int
1310 : : /
1311 : :
1312 : : Send a signal to a thread.
1313 : : [clinic start generated code]*/
1314 : :
1315 : : static PyObject *
1316 : 4 : signal_pthread_kill_impl(PyObject *module, unsigned long thread_id,
1317 : : int signalnum)
1318 : : /*[clinic end generated code: output=7629919b791bc27f input=1d901f2c7bb544ff]*/
1319 : : {
1320 : : int err;
1321 : :
1322 [ - + ]: 4 : if (PySys_Audit("signal.pthread_kill", "ki", thread_id, signalnum) < 0) {
1323 : 0 : return NULL;
1324 : : }
1325 : :
1326 : 4 : err = pthread_kill((pthread_t)thread_id, signalnum);
1327 [ - + ]: 4 : if (err != 0) {
1328 : 0 : errno = err;
1329 : 0 : PyErr_SetFromErrno(PyExc_OSError);
1330 : 0 : return NULL;
1331 : : }
1332 : :
1333 : : /* the signal may have been send to the current thread */
1334 [ + + ]: 4 : if (PyErr_CheckSignals())
1335 : 2 : return NULL;
1336 : :
1337 : 2 : Py_RETURN_NONE;
1338 : : }
1339 : :
1340 : : #endif /* #if defined(HAVE_PTHREAD_KILL) */
1341 : :
1342 : :
1343 : : #if defined(__linux__) && defined(__NR_pidfd_send_signal)
1344 : : /*[clinic input]
1345 : : signal.pidfd_send_signal
1346 : :
1347 : : pidfd: int
1348 : : signalnum: int
1349 : : siginfo: object = None
1350 : : flags: int = 0
1351 : : /
1352 : :
1353 : : Send a signal to a process referred to by a pid file descriptor.
1354 : : [clinic start generated code]*/
1355 : :
1356 : : static PyObject *
1357 : 3 : signal_pidfd_send_signal_impl(PyObject *module, int pidfd, int signalnum,
1358 : : PyObject *siginfo, int flags)
1359 : : /*[clinic end generated code: output=2d59f04a75d9cbdf input=2a6543a1f4ac2000]*/
1360 : :
1361 : : {
1362 [ + + ]: 3 : if (siginfo != Py_None) {
1363 : 1 : PyErr_SetString(PyExc_TypeError, "siginfo must be None");
1364 : 1 : return NULL;
1365 : : }
1366 [ + + ]: 2 : if (syscall(__NR_pidfd_send_signal, pidfd, signalnum, NULL, flags) < 0) {
1367 : 1 : PyErr_SetFromErrno(PyExc_OSError);
1368 : 1 : return NULL;
1369 : : }
1370 : 1 : Py_RETURN_NONE;
1371 : : }
1372 : : #endif
1373 : :
1374 : :
1375 : :
1376 : : /* List of functions defined in the module -- some of the methoddefs are
1377 : : defined to nothing if the corresponding C function is not available. */
1378 : : static PyMethodDef signal_methods[] = {
1379 : : SIGNAL_DEFAULT_INT_HANDLER_METHODDEF
1380 : : SIGNAL_ALARM_METHODDEF
1381 : : SIGNAL_SETITIMER_METHODDEF
1382 : : SIGNAL_GETITIMER_METHODDEF
1383 : : SIGNAL_SIGNAL_METHODDEF
1384 : : SIGNAL_RAISE_SIGNAL_METHODDEF
1385 : : SIGNAL_STRSIGNAL_METHODDEF
1386 : : SIGNAL_GETSIGNAL_METHODDEF
1387 : : {"set_wakeup_fd", _PyCFunction_CAST(signal_set_wakeup_fd), METH_VARARGS | METH_KEYWORDS, set_wakeup_fd_doc},
1388 : : SIGNAL_SIGINTERRUPT_METHODDEF
1389 : : SIGNAL_PAUSE_METHODDEF
1390 : : SIGNAL_PIDFD_SEND_SIGNAL_METHODDEF
1391 : : SIGNAL_PTHREAD_KILL_METHODDEF
1392 : : SIGNAL_PTHREAD_SIGMASK_METHODDEF
1393 : : SIGNAL_SIGPENDING_METHODDEF
1394 : : SIGNAL_SIGWAIT_METHODDEF
1395 : : SIGNAL_SIGWAITINFO_METHODDEF
1396 : : SIGNAL_SIGTIMEDWAIT_METHODDEF
1397 : : #if defined(HAVE_SIGFILLSET) || defined(MS_WINDOWS)
1398 : : SIGNAL_VALID_SIGNALS_METHODDEF
1399 : : #endif
1400 : : {NULL, NULL} /* sentinel */
1401 : : };
1402 : :
1403 : :
1404 : : PyDoc_STRVAR(module_doc,
1405 : : "This module provides mechanisms to use signal handlers in Python.\n\
1406 : : \n\
1407 : : Functions:\n\
1408 : : \n\
1409 : : alarm() -- cause SIGALRM after a specified time [Unix only]\n\
1410 : : setitimer() -- cause a signal (described below) after a specified\n\
1411 : : float time and the timer may restart then [Unix only]\n\
1412 : : getitimer() -- get current value of timer [Unix only]\n\
1413 : : signal() -- set the action for a given signal\n\
1414 : : getsignal() -- get the signal action for a given signal\n\
1415 : : pause() -- wait until a signal arrives [Unix only]\n\
1416 : : default_int_handler() -- default SIGINT handler\n\
1417 : : \n\
1418 : : signal constants:\n\
1419 : : SIG_DFL -- used to refer to the system default handler\n\
1420 : : SIG_IGN -- used to ignore the signal\n\
1421 : : NSIG -- number of defined signals\n\
1422 : : SIGINT, SIGTERM, etc. -- signal numbers\n\
1423 : : \n\
1424 : : itimer constants:\n\
1425 : : ITIMER_REAL -- decrements in real time, and delivers SIGALRM upon\n\
1426 : : expiration\n\
1427 : : ITIMER_VIRTUAL -- decrements only when the process is executing,\n\
1428 : : and delivers SIGVTALRM upon expiration\n\
1429 : : ITIMER_PROF -- decrements both when the process is executing and\n\
1430 : : when the system is executing on behalf of the process.\n\
1431 : : Coupled with ITIMER_VIRTUAL, this timer is usually\n\
1432 : : used to profile the time spent by the application\n\
1433 : : in user and kernel space. SIGPROF is delivered upon\n\
1434 : : expiration.\n\
1435 : : \n\n\
1436 : : *** IMPORTANT NOTICE ***\n\
1437 : : A signal handler function is called with two arguments:\n\
1438 : : the first is the signal number, the second is the interrupted stack frame.");
1439 : :
1440 : :
1441 : :
1442 : : static int
1443 : 2944 : signal_add_constants(PyObject *module)
1444 : : {
1445 [ - + ]: 2944 : if (PyModule_AddIntConstant(module, "NSIG", Py_NSIG) < 0) {
1446 : 0 : return -1;
1447 : : }
1448 : :
1449 : : #define ADD_INT_MACRO(macro) \
1450 : : if (PyModule_AddIntConstant(module, #macro, macro) < 0) { \
1451 : : return -1; \
1452 : : }
1453 : :
1454 : : // SIG_xxx pthread_sigmask() constants
1455 : : #ifdef SIG_BLOCK
1456 [ - + ]: 2944 : ADD_INT_MACRO(SIG_BLOCK);
1457 : : #endif
1458 : : #ifdef SIG_UNBLOCK
1459 [ - + ]: 2944 : ADD_INT_MACRO(SIG_UNBLOCK);
1460 : : #endif
1461 : : #ifdef SIG_SETMASK
1462 [ - + ]: 2944 : ADD_INT_MACRO(SIG_SETMASK);
1463 : : #endif
1464 : :
1465 : : // SIGxxx signal number constants
1466 : : #ifdef SIGHUP
1467 [ - + ]: 2944 : ADD_INT_MACRO(SIGHUP);
1468 : : #endif
1469 : : #ifdef SIGINT
1470 [ - + ]: 2944 : ADD_INT_MACRO(SIGINT);
1471 : : #endif
1472 : : #ifdef SIGBREAK
1473 : : ADD_INT_MACRO(SIGBREAK);
1474 : : #endif
1475 : : #ifdef SIGQUIT
1476 [ - + ]: 2944 : ADD_INT_MACRO(SIGQUIT);
1477 : : #endif
1478 : : #ifdef SIGILL
1479 [ - + ]: 2944 : ADD_INT_MACRO(SIGILL);
1480 : : #endif
1481 : : #ifdef SIGTRAP
1482 [ - + ]: 2944 : ADD_INT_MACRO(SIGTRAP);
1483 : : #endif
1484 : : #ifdef SIGIOT
1485 [ - + ]: 2944 : ADD_INT_MACRO(SIGIOT);
1486 : : #endif
1487 : : #ifdef SIGABRT
1488 [ - + ]: 2944 : ADD_INT_MACRO(SIGABRT);
1489 : : #endif
1490 : : #ifdef SIGEMT
1491 : : ADD_INT_MACRO(SIGEMT);
1492 : : #endif
1493 : : #ifdef SIGFPE
1494 [ - + ]: 2944 : ADD_INT_MACRO(SIGFPE);
1495 : : #endif
1496 : : #ifdef SIGKILL
1497 [ - + ]: 2944 : ADD_INT_MACRO(SIGKILL);
1498 : : #endif
1499 : : #ifdef SIGBUS
1500 [ - + ]: 2944 : ADD_INT_MACRO(SIGBUS);
1501 : : #endif
1502 : : #ifdef SIGSEGV
1503 [ - + ]: 2944 : ADD_INT_MACRO(SIGSEGV);
1504 : : #endif
1505 : : #ifdef SIGSYS
1506 [ - + ]: 2944 : ADD_INT_MACRO(SIGSYS);
1507 : : #endif
1508 : : #ifdef SIGPIPE
1509 [ - + ]: 2944 : ADD_INT_MACRO(SIGPIPE);
1510 : : #endif
1511 : : #ifdef SIGALRM
1512 [ - + ]: 2944 : ADD_INT_MACRO(SIGALRM);
1513 : : #endif
1514 : : #ifdef SIGTERM
1515 [ - + ]: 2944 : ADD_INT_MACRO(SIGTERM);
1516 : : #endif
1517 : : #ifdef SIGUSR1
1518 [ - + ]: 2944 : ADD_INT_MACRO(SIGUSR1);
1519 : : #endif
1520 : : #ifdef SIGUSR2
1521 [ - + ]: 2944 : ADD_INT_MACRO(SIGUSR2);
1522 : : #endif
1523 : : #ifdef SIGCLD
1524 [ - + ]: 2944 : ADD_INT_MACRO(SIGCLD);
1525 : : #endif
1526 : : #ifdef SIGCHLD
1527 [ - + ]: 2944 : ADD_INT_MACRO(SIGCHLD);
1528 : : #endif
1529 : : #ifdef SIGPWR
1530 [ - + ]: 2944 : ADD_INT_MACRO(SIGPWR);
1531 : : #endif
1532 : : #ifdef SIGIO
1533 [ - + ]: 2944 : ADD_INT_MACRO(SIGIO);
1534 : : #endif
1535 : : #ifdef SIGURG
1536 [ - + ]: 2944 : ADD_INT_MACRO(SIGURG);
1537 : : #endif
1538 : : #ifdef SIGWINCH
1539 [ - + ]: 2944 : ADD_INT_MACRO(SIGWINCH);
1540 : : #endif
1541 : : #ifdef SIGPOLL
1542 [ - + ]: 2944 : ADD_INT_MACRO(SIGPOLL);
1543 : : #endif
1544 : : #ifdef SIGSTOP
1545 [ - + ]: 2944 : ADD_INT_MACRO(SIGSTOP);
1546 : : #endif
1547 : : #ifdef SIGTSTP
1548 [ - + ]: 2944 : ADD_INT_MACRO(SIGTSTP);
1549 : : #endif
1550 : : #ifdef SIGCONT
1551 [ - + ]: 2944 : ADD_INT_MACRO(SIGCONT);
1552 : : #endif
1553 : : #ifdef SIGTTIN
1554 [ - + ]: 2944 : ADD_INT_MACRO(SIGTTIN);
1555 : : #endif
1556 : : #ifdef SIGTTOU
1557 [ - + ]: 2944 : ADD_INT_MACRO(SIGTTOU);
1558 : : #endif
1559 : : #ifdef SIGVTALRM
1560 [ - + ]: 2944 : ADD_INT_MACRO(SIGVTALRM);
1561 : : #endif
1562 : : #ifdef SIGPROF
1563 [ - + ]: 2944 : ADD_INT_MACRO(SIGPROF);
1564 : : #endif
1565 : : #ifdef SIGXCPU
1566 [ - + ]: 2944 : ADD_INT_MACRO(SIGXCPU);
1567 : : #endif
1568 : : #ifdef SIGXFSZ
1569 [ - + ]: 2944 : ADD_INT_MACRO(SIGXFSZ);
1570 : : #endif
1571 : : #ifdef SIGRTMIN
1572 [ - + ]: 2944 : ADD_INT_MACRO(SIGRTMIN);
1573 : : #endif
1574 : : #ifdef SIGRTMAX
1575 [ - + ]: 2944 : ADD_INT_MACRO(SIGRTMAX);
1576 : : #endif
1577 : : #ifdef SIGINFO
1578 : : ADD_INT_MACRO(SIGINFO);
1579 : : #endif
1580 : : #ifdef SIGSTKFLT
1581 [ - + ]: 2944 : ADD_INT_MACRO(SIGSTKFLT);
1582 : : #endif
1583 : :
1584 : : // ITIMER_xxx constants
1585 : : #ifdef ITIMER_REAL
1586 [ - + ]: 2944 : ADD_INT_MACRO(ITIMER_REAL);
1587 : : #endif
1588 : : #ifdef ITIMER_VIRTUAL
1589 [ - + ]: 2944 : ADD_INT_MACRO(ITIMER_VIRTUAL);
1590 : : #endif
1591 : : #ifdef ITIMER_PROF
1592 [ - + ]: 2944 : ADD_INT_MACRO(ITIMER_PROF);
1593 : : #endif
1594 : :
1595 : : // CTRL_xxx Windows signals
1596 : : #ifdef CTRL_C_EVENT
1597 : : ADD_INT_MACRO(CTRL_C_EVENT);
1598 : : #endif
1599 : : #ifdef CTRL_BREAK_EVENT
1600 : : ADD_INT_MACRO(CTRL_BREAK_EVENT);
1601 : : #endif
1602 : :
1603 : 2944 : return 0;
1604 : :
1605 : : #undef ADD_INT_MACRO
1606 : : }
1607 : :
1608 : :
1609 : : static int
1610 : 2938 : signal_get_set_handlers(signal_state_t *state, PyObject *mod_dict)
1611 : : {
1612 : : // Get signal handlers
1613 [ + + ]: 190970 : for (int signum = 1; signum < Py_NSIG; signum++) {
1614 : 188032 : void (*c_handler)(int) = PyOS_getsig(signum);
1615 : : PyObject *func;
1616 [ + + ]: 188032 : if (c_handler == SIG_DFL) {
1617 : 170804 : func = state->default_handler;
1618 : : }
1619 [ + + ]: 17228 : else if (c_handler == SIG_IGN) {
1620 : 5886 : func = state->ignore_handler;
1621 : : }
1622 : : else {
1623 : 11342 : func = Py_None; // None of our business
1624 : : }
1625 : : // If signal_module_exec() is called more than one, we must
1626 : : // clear the strong reference to the previous function.
1627 : 188032 : PyObject* old_func = get_handler(signum);
1628 : 188032 : set_handler(signum, Py_NewRef(func));
1629 : 188032 : Py_XDECREF(old_func);
1630 : : }
1631 : :
1632 : : // Install Python SIGINT handler which raises KeyboardInterrupt
1633 : 2938 : PyObject* sigint_func = get_handler(SIGINT);
1634 [ + + ]: 2938 : if (sigint_func == state->default_handler) {
1635 : 2932 : PyObject *int_handler = PyMapping_GetItemString(mod_dict,
1636 : : "default_int_handler");
1637 [ - + ]: 2932 : if (!int_handler) {
1638 : 0 : return -1;
1639 : : }
1640 : :
1641 : 2932 : set_handler(SIGINT, int_handler);
1642 : 2932 : Py_DECREF(sigint_func);
1643 : 2932 : PyOS_setsig(SIGINT, signal_handler);
1644 : : }
1645 : 2938 : return 0;
1646 : : }
1647 : :
1648 : :
1649 : : static int
1650 : 2944 : signal_module_exec(PyObject *m)
1651 : : {
1652 : : assert(!PyErr_Occurred());
1653 : :
1654 : 2944 : signal_state_t *state = &signal_global_state;
1655 : 2944 : _signal_module_state *modstate = get_signal_state(m);
1656 : :
1657 : 2944 : modstate->default_handler = state->default_handler; // borrowed ref
1658 : 2944 : modstate->ignore_handler = state->ignore_handler; // borrowed ref
1659 : :
1660 : : #ifdef PYHAVE_ITIMER_ERROR
1661 : 2944 : modstate->itimer_error = PyErr_NewException("signal.itimer_error",
1662 : : PyExc_OSError, NULL);
1663 [ - + ]: 2944 : if (modstate->itimer_error == NULL) {
1664 : 0 : return -1;
1665 : : }
1666 : : #endif
1667 : :
1668 [ - + ]: 2944 : if (signal_add_constants(m) < 0) {
1669 : 0 : return -1;
1670 : : }
1671 : :
1672 : : /* Add some symbolic constants to the module */
1673 : 2944 : PyObject *d = PyModule_GetDict(m);
1674 [ - + ]: 2944 : if (PyDict_SetItemString(d, "SIG_DFL", state->default_handler) < 0) {
1675 : 0 : return -1;
1676 : : }
1677 [ - + ]: 2944 : if (PyDict_SetItemString(d, "SIG_IGN", state->ignore_handler) < 0) {
1678 : 0 : return -1;
1679 : : }
1680 : : #ifdef PYHAVE_ITIMER_ERROR
1681 [ - + ]: 2944 : if (PyDict_SetItemString(d, "ItimerError", modstate->itimer_error) < 0) {
1682 : 0 : return -1;
1683 : : }
1684 : : #endif
1685 : :
1686 : : #if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT)
1687 : 2944 : modstate->siginfo_type = PyStructSequence_NewType(&struct_siginfo_desc);
1688 [ - + ]: 2944 : if (modstate->siginfo_type == NULL) {
1689 : 0 : return -1;
1690 : : }
1691 : : #endif
1692 : : #if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT)
1693 [ - + ]: 2944 : if (PyModule_AddType(m, modstate->siginfo_type) < 0) {
1694 : 0 : return -1;
1695 : : }
1696 : : #endif
1697 : :
1698 : 2944 : PyThreadState *tstate = _PyThreadState_GET();
1699 [ + + ]: 2944 : if (_Py_IsMainInterpreter(tstate->interp)) {
1700 [ - + ]: 2938 : if (signal_get_set_handlers(state, d) < 0) {
1701 : 0 : return -1;
1702 : : }
1703 : : }
1704 : :
1705 : : assert(!PyErr_Occurred());
1706 : 2944 : return 0;
1707 : : }
1708 : :
1709 : :
1710 : : #ifdef PYHAVE_ITIMER_ERROR
1711 : : static int
1712 : 50306 : _signal_module_traverse(PyObject *module, visitproc visit, void *arg)
1713 : : {
1714 : 50306 : _signal_module_state *state = get_signal_state(module);
1715 [ + - - + ]: 50306 : Py_VISIT(state->itimer_error);
1716 [ + - - + ]: 50306 : Py_VISIT(state->siginfo_type);
1717 : 50306 : return 0;
1718 : : }
1719 : :
1720 : : static int
1721 : 4868 : _signal_module_clear(PyObject *module)
1722 : : {
1723 : 4868 : _signal_module_state *state = get_signal_state(module);
1724 [ + + ]: 4868 : Py_CLEAR(state->itimer_error);
1725 [ + + ]: 4868 : Py_CLEAR(state->siginfo_type);
1726 : 4868 : return 0;
1727 : : }
1728 : :
1729 : : static void
1730 : 2936 : _signal_module_free(void *module)
1731 : : {
1732 : 2936 : _signal_module_clear((PyObject *)module);
1733 : 2936 : }
1734 : : #endif // PYHAVE_ITIMER_ERROR
1735 : :
1736 : :
1737 : : static PyModuleDef_Slot signal_slots[] = {
1738 : : {Py_mod_exec, signal_module_exec},
1739 : : {0, NULL}
1740 : : };
1741 : :
1742 : : static struct PyModuleDef signal_module = {
1743 : : PyModuleDef_HEAD_INIT,
1744 : : "_signal",
1745 : : .m_doc = module_doc,
1746 : : .m_size = sizeof(_signal_module_state),
1747 : : .m_methods = signal_methods,
1748 : : .m_slots = signal_slots,
1749 : : #ifdef PYHAVE_ITIMER_ERROR
1750 : : .m_traverse = _signal_module_traverse,
1751 : : .m_clear = _signal_module_clear,
1752 : : .m_free = _signal_module_free,
1753 : : #endif
1754 : : };
1755 : :
1756 : :
1757 : : PyMODINIT_FUNC
1758 : 2944 : PyInit__signal(void)
1759 : : {
1760 : 2944 : return PyModuleDef_Init(&signal_module);
1761 : : }
1762 : :
1763 : :
1764 : : void
1765 : 2957 : _PySignal_Fini(void)
1766 : : {
1767 : 2957 : signal_state_t *state = &signal_global_state;
1768 : :
1769 : : // Restore default signals and clear handlers
1770 [ + + ]: 192205 : for (int signum = 1; signum < Py_NSIG; signum++) {
1771 : 189248 : PyObject *func = get_handler(signum);
1772 : 189248 : _Py_atomic_store_relaxed(&Handlers[signum].tripped, 0);
1773 : 189248 : set_handler(signum, NULL);
1774 [ + + ]: 189248 : if (func != NULL
1775 [ + + ]: 187584 : && func != Py_None
1776 [ + + ]: 176276 : && !compare_handler(func, state->default_handler)
1777 [ + + ]: 8913 : && !compare_handler(func, state->ignore_handler))
1778 : : {
1779 : 2857 : PyOS_setsig(signum, SIG_DFL);
1780 : : }
1781 : 189248 : Py_XDECREF(func);
1782 : : }
1783 : :
1784 : : #ifdef MS_WINDOWS
1785 : : if (state->sigint_event != NULL) {
1786 : : CloseHandle(state->sigint_event);
1787 : : state->sigint_event = NULL;
1788 : : }
1789 : : #endif
1790 : :
1791 [ + - ]: 2957 : Py_CLEAR(state->default_handler);
1792 [ + - ]: 2957 : Py_CLEAR(state->ignore_handler);
1793 : 2957 : }
1794 : :
1795 : :
1796 : : /* Declared in pyerrors.h */
1797 : : int
1798 : 50167667 : PyErr_CheckSignals(void)
1799 : : {
1800 : 50167667 : PyThreadState *tstate = _PyThreadState_GET();
1801 [ + + ]: 50167667 : if (!_Py_ThreadCanHandleSignals(tstate->interp)) {
1802 : 1102250 : return 0;
1803 : : }
1804 : :
1805 : 49065417 : return _PyErr_CheckSignalsTstate(tstate);
1806 : : }
1807 : :
1808 : :
1809 : : /* Declared in cpython/pyerrors.h */
1810 : : int
1811 : 49144399 : _PyErr_CheckSignalsTstate(PyThreadState *tstate)
1812 : : {
1813 : : _Py_CHECK_EMSCRIPTEN_SIGNALS();
1814 [ + + ]: 49144399 : if (!_Py_atomic_load(&is_tripped)) {
1815 : 49112974 : return 0;
1816 : : }
1817 : :
1818 : : /*
1819 : : * The is_tripped variable is meant to speed up the calls to
1820 : : * PyErr_CheckSignals (both directly or via pending calls) when no
1821 : : * signal has arrived. This variable is set to 1 when a signal arrives
1822 : : * and it is set to 0 here, when we know some signals arrived. This way
1823 : : * we can run the registered handlers with no signals blocked.
1824 : : *
1825 : : * NOTE: with this approach we can have a situation where is_tripped is
1826 : : * 1 but we have no more signals to handle (Handlers[i].tripped
1827 : : * is 0 for every signal i). This won't do us any harm (except
1828 : : * we're gonna spent some cycles for nothing). This happens when
1829 : : * we receive a signal i after we zero is_tripped and before we
1830 : : * check Handlers[i].tripped.
1831 : : */
1832 : 31425 : _Py_atomic_store(&is_tripped, 0);
1833 : :
1834 : 31425 : _PyInterpreterFrame *frame = tstate->cframe->current_frame;
1835 : 31425 : signal_state_t *state = &signal_global_state;
1836 [ + + ]: 2033828 : for (int i = 1; i < Py_NSIG; i++) {
1837 [ + + ]: 2002550 : if (!_Py_atomic_load_relaxed(&Handlers[i].tripped)) {
1838 : 1971262 : continue;
1839 : : }
1840 : 31288 : _Py_atomic_store_relaxed(&Handlers[i].tripped, 0);
1841 : :
1842 : : /* Signal handlers can be modified while a signal is received,
1843 : : * and therefore the fact that trip_signal() or PyErr_SetInterrupt()
1844 : : * was called doesn't guarantee that there is still a Python
1845 : : * signal handler for it by the time PyErr_CheckSignals() is called
1846 : : * (see bpo-43406).
1847 : : */
1848 : 31288 : PyObject *func = get_handler(i);
1849 [ + - + - : 62576 : if (func == NULL || func == Py_None ||
+ + ]
1850 [ - + ]: 62561 : compare_handler(func, state->ignore_handler) ||
1851 : 31273 : compare_handler(func, state->default_handler)) {
1852 : : /* No Python signal handler due to aforementioned race condition.
1853 : : * We can't call raise() as it would break the assumption
1854 : : * that PyErr_SetInterrupt() only *simulates* an incoming
1855 : : * signal (i.e. it will never kill the process).
1856 : : * We also don't want to interrupt user code with a cryptic
1857 : : * asynchronous exception, so instead just write out an
1858 : : * unraisable error.
1859 : : */
1860 : 15 : PyErr_Format(PyExc_OSError,
1861 : : "Signal %i ignored due to race condition",
1862 : : i);
1863 : 15 : PyErr_WriteUnraisable(Py_None);
1864 : 15 : continue;
1865 : : }
1866 : 31273 : PyObject *arglist = NULL;
1867 [ - + ]: 31273 : if (frame == NULL) {
1868 : 0 : arglist = Py_BuildValue("(iO)", i, Py_None);
1869 : : }
1870 : : else {
1871 : 31273 : PyFrameObject *f = _PyFrame_GetFrameObject(frame);
1872 [ + - ]: 31273 : if (f != NULL) {
1873 : 31273 : arglist = Py_BuildValue("(iO)", i, f);
1874 : : }
1875 : : }
1876 : : PyObject *result;
1877 [ + - ]: 31273 : if (arglist) {
1878 : 31273 : result = _PyObject_Call(tstate, func, arglist, NULL);
1879 : 31273 : Py_DECREF(arglist);
1880 : : }
1881 : : else {
1882 : 0 : result = NULL;
1883 : : }
1884 [ + + ]: 31273 : if (!result) {
1885 : : /* On error, re-schedule a call to _PyErr_CheckSignalsTstate() */
1886 : 147 : _Py_atomic_store(&is_tripped, 1);
1887 : 147 : return -1;
1888 : : }
1889 : :
1890 : 31126 : Py_DECREF(result);
1891 : : }
1892 : :
1893 : 31278 : return 0;
1894 : : }
1895 : :
1896 : :
1897 : :
1898 : : int
1899 : 0 : _PyErr_CheckSignals(void)
1900 : : {
1901 : 0 : PyThreadState *tstate = _PyThreadState_GET();
1902 : 0 : return _PyErr_CheckSignalsTstate(tstate);
1903 : : }
1904 : :
1905 : :
1906 : : /* Simulate the effect of a signal arriving. The next time PyErr_CheckSignals
1907 : : is called, the corresponding Python signal handler will be raised.
1908 : :
1909 : : Missing signal handler for the given signal number is silently ignored. */
1910 : : int
1911 : 14 : PyErr_SetInterruptEx(int signum)
1912 : : {
1913 [ + + + + ]: 14 : if (signum < 1 || signum >= Py_NSIG) {
1914 : 3 : return -1;
1915 : : }
1916 : :
1917 : 11 : signal_state_t *state = &signal_global_state;
1918 : 11 : PyObject *func = get_handler(signum);
1919 [ + + ]: 11 : if (!compare_handler(func, state->ignore_handler)
1920 [ + + ]: 9 : && !compare_handler(func, state->default_handler)) {
1921 : 7 : trip_signal(signum);
1922 : : }
1923 : 11 : return 0;
1924 : : }
1925 : :
1926 : : void
1927 : 0 : PyErr_SetInterrupt(void)
1928 : : {
1929 : 0 : (void) PyErr_SetInterruptEx(SIGINT);
1930 : 0 : }
1931 : :
1932 : : static int
1933 : 2937 : signal_install_handlers(void)
1934 : : {
1935 : : #ifdef SIGPIPE
1936 : 2937 : PyOS_setsig(SIGPIPE, SIG_IGN);
1937 : : #endif
1938 : : #ifdef SIGXFZ
1939 : : PyOS_setsig(SIGXFZ, SIG_IGN);
1940 : : #endif
1941 : : #ifdef SIGXFSZ
1942 : 2937 : PyOS_setsig(SIGXFSZ, SIG_IGN);
1943 : : #endif
1944 : :
1945 : : // Import _signal to install the Python SIGINT handler
1946 : 2937 : PyObject *module = PyImport_ImportModule("_signal");
1947 [ - + ]: 2937 : if (!module) {
1948 : 0 : return -1;
1949 : : }
1950 : 2937 : Py_DECREF(module);
1951 : :
1952 : 2937 : return 0;
1953 : : }
1954 : :
1955 : :
1956 : : /* Restore signals that the interpreter has called SIG_IGN on to SIG_DFL.
1957 : : *
1958 : : * All of the code in this function must only use async-signal-safe functions,
1959 : : * listed at `man 7 signal` or
1960 : : * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html.
1961 : : *
1962 : : * If this function is updated, update also _posix_spawn() of subprocess.py.
1963 : : */
1964 : : void
1965 : 4929 : _Py_RestoreSignals(void)
1966 : : {
1967 : : #ifdef SIGPIPE
1968 : 4929 : PyOS_setsig(SIGPIPE, SIG_DFL);
1969 : : #endif
1970 : : #ifdef SIGXFZ
1971 : : PyOS_setsig(SIGXFZ, SIG_DFL);
1972 : : #endif
1973 : : #ifdef SIGXFSZ
1974 : 4929 : PyOS_setsig(SIGXFSZ, SIG_DFL);
1975 : : #endif
1976 : 4929 : }
1977 : :
1978 : :
1979 : : int
1980 : 2963 : _PySignal_Init(int install_signal_handlers)
1981 : : {
1982 : 2963 : signal_state_t *state = &signal_global_state;
1983 : :
1984 : 2963 : state->default_handler = PyLong_FromVoidPtr((void *)SIG_DFL);
1985 [ - + ]: 2963 : if (state->default_handler == NULL) {
1986 : 0 : return -1;
1987 : : }
1988 : :
1989 : 2963 : state->ignore_handler = PyLong_FromVoidPtr((void *)SIG_IGN);
1990 [ - + ]: 2963 : if (state->ignore_handler == NULL) {
1991 : 0 : return -1;
1992 : : }
1993 : :
1994 : : #ifdef MS_WINDOWS
1995 : : /* Create manual-reset event, initially unset */
1996 : : state->sigint_event = CreateEvent(NULL, TRUE, FALSE, FALSE);
1997 : : if (state->sigint_event == NULL) {
1998 : : PyErr_SetFromWindowsErr(0);
1999 : : return -1;
2000 : : }
2001 : : #endif
2002 : :
2003 [ + + ]: 192595 : for (int signum = 1; signum < Py_NSIG; signum++) {
2004 : 189632 : _Py_atomic_store_relaxed(&Handlers[signum].tripped, 0);
2005 : : }
2006 : :
2007 [ + + ]: 2963 : if (install_signal_handlers) {
2008 [ - + ]: 2937 : if (signal_install_handlers() < 0) {
2009 : 0 : return -1;
2010 : : }
2011 : : }
2012 : :
2013 : 2963 : return 0;
2014 : : }
2015 : :
2016 : :
2017 : : // The caller doesn't have to hold the GIL
2018 : : int
2019 : 1 : _PyOS_InterruptOccurred(PyThreadState *tstate)
2020 : : {
2021 : 1 : _Py_EnsureTstateNotNULL(tstate);
2022 [ - + ]: 1 : if (!_Py_ThreadCanHandleSignals(tstate->interp)) {
2023 : 0 : return 0;
2024 : : }
2025 : :
2026 [ + - ]: 1 : if (!_Py_atomic_load_relaxed(&Handlers[SIGINT].tripped)) {
2027 : 1 : return 0;
2028 : : }
2029 : :
2030 : 0 : _Py_atomic_store_relaxed(&Handlers[SIGINT].tripped, 0);
2031 : 0 : return 1;
2032 : : }
2033 : :
2034 : :
2035 : : // The caller must to hold the GIL
2036 : : int
2037 : 0 : PyOS_InterruptOccurred(void)
2038 : : {
2039 : 0 : PyThreadState *tstate = _PyThreadState_GET();
2040 : 0 : return _PyOS_InterruptOccurred(tstate);
2041 : : }
2042 : :
2043 : :
2044 : : #ifdef HAVE_FORK
2045 : : static void
2046 : 8 : _clear_pending_signals(void)
2047 : : {
2048 [ + - ]: 8 : if (!_Py_atomic_load(&is_tripped)) {
2049 : 8 : return;
2050 : : }
2051 : :
2052 : 0 : _Py_atomic_store(&is_tripped, 0);
2053 [ # # ]: 0 : for (int i = 1; i < Py_NSIG; ++i) {
2054 : 0 : _Py_atomic_store_relaxed(&Handlers[i].tripped, 0);
2055 : : }
2056 : : }
2057 : :
2058 : : void
2059 : 8 : _PySignal_AfterFork(void)
2060 : : {
2061 : : /* Clear the signal flags after forking so that they aren't handled
2062 : : * in both processes if they came in just before the fork() but before
2063 : : * the interpreter had an opportunity to call the handlers. issue9535. */
2064 : 8 : _clear_pending_signals();
2065 : 8 : }
2066 : : #endif /* HAVE_FORK */
2067 : :
2068 : :
2069 : : int
2070 : 0 : _PyOS_IsMainThread(void)
2071 : : {
2072 : 0 : PyInterpreterState *interp = _PyInterpreterState_GET();
2073 : 0 : return _Py_ThreadCanHandleSignals(interp);
2074 : : }
2075 : :
2076 : : #ifdef MS_WINDOWS
2077 : : /* Returns a manual-reset event which gets tripped whenever
2078 : : SIGINT is received.
2079 : :
2080 : : Python.h does not include windows.h so we do cannot use HANDLE
2081 : : as the return type of this function. We use void* instead. */
2082 : : void *_PyOS_SigintEvent(void)
2083 : : {
2084 : : signal_state_t *state = &signal_global_state;
2085 : : return state->sigint_event;
2086 : : }
2087 : : #endif
|