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 416956 : get_handler(int i)
161 : {
162 416956 : return (PyObject *)_Py_atomic_load(&Handlers[i].func);
163 : }
164 :
165 : Py_LOCAL_INLINE(void)
166 383087 : set_handler(int i, PyObject* func)
167 : {
168 383087 : _Py_atomic_store(&Handlers[i].func, (uintptr_t)func);
169 383087 : }
170 :
171 :
172 : static inline _signal_module_state*
173 98581 : get_signal_state(PyObject *module)
174 : {
175 98581 : void *state = _PyModule_GetState(module);
176 98581 : assert(state != NULL);
177 98581 : return (_signal_module_state *)state;
178 : }
179 :
180 :
181 : static inline int
182 248273 : compare_handler(PyObject *func, PyObject *dfl_ign_handler)
183 : {
184 248273 : assert(PyLong_CheckExact(dfl_ign_handler));
185 248273 : if (!PyLong_CheckExact(func)) {
186 68038 : return 0;
187 : }
188 : // Assume that comparison of two PyLong objects will never fail.
189 180235 : 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 69364 : double_from_timeval(struct timeval *tv)
215 : {
216 69364 : return tv->tv_sec + (double)(tv->tv_usec / 1000000.0);
217 : }
218 :
219 : static PyObject *
220 34682 : itimer_retval(struct itimerval *iv)
221 : {
222 : PyObject *r, *v;
223 :
224 34682 : r = PyTuple_New(2);
225 34682 : if (r == NULL)
226 0 : return NULL;
227 :
228 34682 : if(!(v = PyFloat_FromDouble(double_from_timeval(&iv->it_value)))) {
229 0 : Py_DECREF(r);
230 0 : return NULL;
231 : }
232 :
233 34682 : PyTuple_SET_ITEM(r, 0, v);
234 :
235 34682 : if(!(v = PyFloat_FromDouble(double_from_timeval(&iv->it_interval)))) {
236 0 : Py_DECREF(r);
237 0 : return NULL;
238 : }
239 :
240 34682 : PyTuple_SET_ITEM(r, 1, v);
241 :
242 34682 : 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 31454 : trip_signal(int sig_num)
303 : {
304 31454 : _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 31454 : _Py_atomic_store(&is_tripped, 1);
309 :
310 : /* Signals are always handled by the main interpreter */
311 31454 : PyInterpreterState *interp = _PyInterpreterState_Main();
312 :
313 : /* Notify ceval.c */
314 31454 : _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 31454 : fd = wakeup.fd;
340 : #endif
341 :
342 31454 : if (fd != INVALID_FD) {
343 459 : 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 459 : Py_ssize_t rc = _Py_write_noraise(fd, &byte, 1);
367 :
368 459 : 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 31454 : }
382 :
383 : static void
384 31447 : signal_handler(int sig_num)
385 : {
386 31447 : int save_errno = errno;
387 :
388 31447 : 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 31447 : 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 31447 : }
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 317 : signal_raise_signal_impl(PyObject *module, int signalnum)
475 : /*[clinic end generated code: output=e2b014220aa6111d input=e90c0f9a42358de6]*/
476 : {
477 : int err;
478 317 : Py_BEGIN_ALLOW_THREADS
479 : _Py_BEGIN_SUPPRESS_IPH
480 317 : err = raise(signalnum);
481 : _Py_END_SUPPRESS_IPH
482 317 : Py_END_ALLOW_THREADS
483 :
484 317 : 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 317 : if (PyErr_CheckSignals()) {
491 5 : return NULL;
492 : }
493 :
494 312 : 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 3527 : signal_signal_impl(PyObject *module, int signalnum, PyObject *handler)
516 : /*[clinic end generated code: output=b44cfda43780f3a1 input=deee84af5fa0432c]*/
517 : {
518 3527 : _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 3527 : PyThreadState *tstate = _PyThreadState_GET();
542 3527 : 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 3524 : 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 3523 : if (PyCallable_Check(handler)) {
554 2819 : func = signal_handler;
555 704 : } else if (compare_handler(handler, modstate->ignore_handler)) {
556 233 : func = SIG_IGN;
557 471 : } else if (compare_handler(handler, modstate->default_handler)) {
558 470 : 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 3522 : if (_PyErr_CheckSignalsTstate(tstate)) {
568 0 : return NULL;
569 : }
570 3522 : if (PyOS_setsig(signalnum, func) == SIG_ERR) {
571 3 : PyErr_SetFromErrno(PyExc_OSError);
572 3 : return NULL;
573 : }
574 :
575 3519 : old_handler = get_handler(signalnum);
576 3519 : set_handler(signalnum, Py_NewRef(handler));
577 :
578 3519 : if (old_handler != NULL) {
579 3519 : 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 2699 : signal_getsignal_impl(PyObject *module, int signalnum)
604 : /*[clinic end generated code: output=35b3e0e796fd555e input=ac23a00f19dfa509]*/
605 : {
606 : PyObject *old_handler;
607 2699 : if (signalnum < 1 || signalnum >= Py_NSIG) {
608 1 : PyErr_SetString(PyExc_ValueError,
609 : "signal number out of range");
610 1 : return NULL;
611 : }
612 2698 : old_handler = get_handler(signalnum);
613 2698 : if (old_handler != NULL) {
614 2698 : 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 642 : 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 642 : 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 642 : 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 640 : PyThreadState *tstate = _PyThreadState_GET();
777 640 : 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 640 : if (fd != -1) {
835 : int blocking;
836 :
837 339 : if (_Py_fstat(fd, &status) != 0)
838 2 : return NULL;
839 :
840 337 : blocking = _Py_get_blocking(fd);
841 337 : if (blocking < 0)
842 0 : return NULL;
843 337 : 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 637 : int old_fd = wakeup.fd;
852 637 : wakeup.fd = fd;
853 637 : wakeup.warn_on_full_buffer = warn_on_full_buffer;
854 :
855 637 : 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 9207 : signal_getitimer_impl(PyObject *module, int which)
943 : /*[clinic end generated code: output=9e053175d517db40 input=f7d21d38f3490627]*/
944 : {
945 9207 : _signal_module_state *modstate = get_signal_state(module);
946 :
947 : struct itimerval old;
948 9207 : if (getitimer(which, &old) != 0) {
949 0 : PyErr_SetFromErrno(modstate->itimer_error);
950 0 : return NULL;
951 : }
952 :
953 9207 : 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 849 : sigset_to_set(sigset_t mask)
962 : {
963 : PyObject *signum, *result;
964 : int sig;
965 :
966 849 : result = PySet_New(0);
967 849 : if (result == NULL)
968 0 : return NULL;
969 :
970 55185 : for (sig = 1; sig < Py_NSIG; sig++) {
971 54336 : if (sigismember(&mask, sig) != 1)
972 14724 : 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 39612 : signum = PyLong_FromLong(sig);
980 39612 : if (signum == NULL) {
981 0 : Py_DECREF(result);
982 0 : return NULL;
983 : }
984 39612 : if (PySet_Add(result, signum) == -1) {
985 0 : Py_DECREF(signum);
986 0 : Py_DECREF(result);
987 0 : return NULL;
988 : }
989 39612 : Py_DECREF(signum);
990 : }
991 849 : 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 216 : 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 216 : err = pthread_sigmask(how, &mask, &previous);
1015 216 : 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 215 : if (PyErr_CheckSignals())
1023 2 : return NULL;
1024 :
1025 213 : 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 634 : 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 634 : if (sigemptyset(&mask) || sigfillset(&mask)) {
1124 0 : return PyErr_SetFromErrno(PyExc_OSError);
1125 : }
1126 634 : 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 8 : Py_BEGIN_ALLOW_THREADS
1219 8 : err = sigwaitinfo(&sigset, &si);
1220 8 : Py_END_ALLOW_THREADS
1221 : } while (err == -1
1222 8 : && 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 6 : do {
1265 : struct timespec ts;
1266 10 : if (_PyTime_AsTimespec(timeout, &ts) < 0) {
1267 1 : return NULL;
1268 : }
1269 :
1270 : int res;
1271 10 : Py_BEGIN_ALLOW_THREADS
1272 10 : res = sigtimedwait(&sigset, &si, &ts);
1273 10 : Py_END_ALLOW_THREADS
1274 :
1275 10 : if (res != -1)
1276 3 : break;
1277 :
1278 7 : 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 6 : if (PyErr_CheckSignals())
1287 0 : return NULL;
1288 :
1289 6 : timeout = _PyDeadline_Get(deadline);
1290 6 : 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 2939 : signal_add_constants(PyObject *module)
1444 : {
1445 2939 : 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 2939 : ADD_INT_MACRO(SIG_BLOCK);
1457 : #endif
1458 : #ifdef SIG_UNBLOCK
1459 2939 : ADD_INT_MACRO(SIG_UNBLOCK);
1460 : #endif
1461 : #ifdef SIG_SETMASK
1462 2939 : ADD_INT_MACRO(SIG_SETMASK);
1463 : #endif
1464 :
1465 : // SIGxxx signal number constants
1466 : #ifdef SIGHUP
1467 2939 : ADD_INT_MACRO(SIGHUP);
1468 : #endif
1469 : #ifdef SIGINT
1470 2939 : ADD_INT_MACRO(SIGINT);
1471 : #endif
1472 : #ifdef SIGBREAK
1473 : ADD_INT_MACRO(SIGBREAK);
1474 : #endif
1475 : #ifdef SIGQUIT
1476 2939 : ADD_INT_MACRO(SIGQUIT);
1477 : #endif
1478 : #ifdef SIGILL
1479 2939 : ADD_INT_MACRO(SIGILL);
1480 : #endif
1481 : #ifdef SIGTRAP
1482 2939 : ADD_INT_MACRO(SIGTRAP);
1483 : #endif
1484 : #ifdef SIGIOT
1485 2939 : ADD_INT_MACRO(SIGIOT);
1486 : #endif
1487 : #ifdef SIGABRT
1488 2939 : ADD_INT_MACRO(SIGABRT);
1489 : #endif
1490 : #ifdef SIGEMT
1491 : ADD_INT_MACRO(SIGEMT);
1492 : #endif
1493 : #ifdef SIGFPE
1494 2939 : ADD_INT_MACRO(SIGFPE);
1495 : #endif
1496 : #ifdef SIGKILL
1497 2939 : ADD_INT_MACRO(SIGKILL);
1498 : #endif
1499 : #ifdef SIGBUS
1500 2939 : ADD_INT_MACRO(SIGBUS);
1501 : #endif
1502 : #ifdef SIGSEGV
1503 2939 : ADD_INT_MACRO(SIGSEGV);
1504 : #endif
1505 : #ifdef SIGSYS
1506 2939 : ADD_INT_MACRO(SIGSYS);
1507 : #endif
1508 : #ifdef SIGPIPE
1509 2939 : ADD_INT_MACRO(SIGPIPE);
1510 : #endif
1511 : #ifdef SIGALRM
1512 2939 : ADD_INT_MACRO(SIGALRM);
1513 : #endif
1514 : #ifdef SIGTERM
1515 2939 : ADD_INT_MACRO(SIGTERM);
1516 : #endif
1517 : #ifdef SIGUSR1
1518 2939 : ADD_INT_MACRO(SIGUSR1);
1519 : #endif
1520 : #ifdef SIGUSR2
1521 2939 : ADD_INT_MACRO(SIGUSR2);
1522 : #endif
1523 : #ifdef SIGCLD
1524 2939 : ADD_INT_MACRO(SIGCLD);
1525 : #endif
1526 : #ifdef SIGCHLD
1527 2939 : ADD_INT_MACRO(SIGCHLD);
1528 : #endif
1529 : #ifdef SIGPWR
1530 2939 : ADD_INT_MACRO(SIGPWR);
1531 : #endif
1532 : #ifdef SIGIO
1533 2939 : ADD_INT_MACRO(SIGIO);
1534 : #endif
1535 : #ifdef SIGURG
1536 2939 : ADD_INT_MACRO(SIGURG);
1537 : #endif
1538 : #ifdef SIGWINCH
1539 2939 : ADD_INT_MACRO(SIGWINCH);
1540 : #endif
1541 : #ifdef SIGPOLL
1542 2939 : ADD_INT_MACRO(SIGPOLL);
1543 : #endif
1544 : #ifdef SIGSTOP
1545 2939 : ADD_INT_MACRO(SIGSTOP);
1546 : #endif
1547 : #ifdef SIGTSTP
1548 2939 : ADD_INT_MACRO(SIGTSTP);
1549 : #endif
1550 : #ifdef SIGCONT
1551 2939 : ADD_INT_MACRO(SIGCONT);
1552 : #endif
1553 : #ifdef SIGTTIN
1554 2939 : ADD_INT_MACRO(SIGTTIN);
1555 : #endif
1556 : #ifdef SIGTTOU
1557 2939 : ADD_INT_MACRO(SIGTTOU);
1558 : #endif
1559 : #ifdef SIGVTALRM
1560 2939 : ADD_INT_MACRO(SIGVTALRM);
1561 : #endif
1562 : #ifdef SIGPROF
1563 2939 : ADD_INT_MACRO(SIGPROF);
1564 : #endif
1565 : #ifdef SIGXCPU
1566 2939 : ADD_INT_MACRO(SIGXCPU);
1567 : #endif
1568 : #ifdef SIGXFSZ
1569 2939 : ADD_INT_MACRO(SIGXFSZ);
1570 : #endif
1571 : #ifdef SIGRTMIN
1572 2939 : ADD_INT_MACRO(SIGRTMIN);
1573 : #endif
1574 : #ifdef SIGRTMAX
1575 2939 : ADD_INT_MACRO(SIGRTMAX);
1576 : #endif
1577 : #ifdef SIGINFO
1578 : ADD_INT_MACRO(SIGINFO);
1579 : #endif
1580 : #ifdef SIGSTKFLT
1581 2939 : ADD_INT_MACRO(SIGSTKFLT);
1582 : #endif
1583 :
1584 : // ITIMER_xxx constants
1585 : #ifdef ITIMER_REAL
1586 2939 : ADD_INT_MACRO(ITIMER_REAL);
1587 : #endif
1588 : #ifdef ITIMER_VIRTUAL
1589 2939 : ADD_INT_MACRO(ITIMER_VIRTUAL);
1590 : #endif
1591 : #ifdef ITIMER_PROF
1592 2939 : 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 2939 : return 0;
1604 :
1605 : #undef ADD_INT_MACRO
1606 : }
1607 :
1608 :
1609 : static int
1610 2933 : signal_get_set_handlers(signal_state_t *state, PyObject *mod_dict)
1611 : {
1612 : // Get signal handlers
1613 190645 : for (int signum = 1; signum < Py_NSIG; signum++) {
1614 187712 : void (*c_handler)(int) = PyOS_getsig(signum);
1615 : PyObject *func;
1616 187712 : if (c_handler == SIG_DFL) {
1617 170405 : func = state->default_handler;
1618 : }
1619 17307 : else if (c_handler == SIG_IGN) {
1620 5876 : func = state->ignore_handler;
1621 : }
1622 : else {
1623 11431 : 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 187712 : PyObject* old_func = get_handler(signum);
1628 187712 : set_handler(signum, Py_NewRef(func));
1629 187712 : Py_XDECREF(old_func);
1630 : }
1631 :
1632 : // Install Python SIGINT handler which raises KeyboardInterrupt
1633 2933 : PyObject* sigint_func = get_handler(SIGINT);
1634 2933 : if (sigint_func == state->default_handler) {
1635 2928 : PyObject *int_handler = PyMapping_GetItemString(mod_dict,
1636 : "default_int_handler");
1637 2928 : if (!int_handler) {
1638 0 : return -1;
1639 : }
1640 :
1641 2928 : set_handler(SIGINT, int_handler);
1642 2928 : Py_DECREF(sigint_func);
1643 2928 : PyOS_setsig(SIGINT, signal_handler);
1644 : }
1645 2933 : return 0;
1646 : }
1647 :
1648 :
1649 : static int
1650 2939 : signal_module_exec(PyObject *m)
1651 : {
1652 2939 : assert(!PyErr_Occurred());
1653 :
1654 2939 : signal_state_t *state = &signal_global_state;
1655 2939 : _signal_module_state *modstate = get_signal_state(m);
1656 :
1657 2939 : modstate->default_handler = state->default_handler; // borrowed ref
1658 2939 : modstate->ignore_handler = state->ignore_handler; // borrowed ref
1659 :
1660 : #ifdef PYHAVE_ITIMER_ERROR
1661 2939 : modstate->itimer_error = PyErr_NewException("signal.itimer_error",
1662 : PyExc_OSError, NULL);
1663 2939 : if (modstate->itimer_error == NULL) {
1664 0 : return -1;
1665 : }
1666 : #endif
1667 :
1668 2939 : if (signal_add_constants(m) < 0) {
1669 0 : return -1;
1670 : }
1671 :
1672 : /* Add some symbolic constants to the module */
1673 2939 : PyObject *d = PyModule_GetDict(m);
1674 2939 : if (PyDict_SetItemString(d, "SIG_DFL", state->default_handler) < 0) {
1675 0 : return -1;
1676 : }
1677 2939 : if (PyDict_SetItemString(d, "SIG_IGN", state->ignore_handler) < 0) {
1678 0 : return -1;
1679 : }
1680 : #ifdef PYHAVE_ITIMER_ERROR
1681 2939 : 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 2939 : modstate->siginfo_type = PyStructSequence_NewType(&struct_siginfo_desc);
1688 2939 : if (modstate->siginfo_type == NULL) {
1689 0 : return -1;
1690 : }
1691 : #endif
1692 : #if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT)
1693 2939 : if (PyModule_AddType(m, modstate->siginfo_type) < 0) {
1694 0 : return -1;
1695 : }
1696 : #endif
1697 :
1698 2939 : PyThreadState *tstate = _PyThreadState_GET();
1699 2939 : if (_Py_IsMainInterpreter(tstate->interp)) {
1700 2933 : if (signal_get_set_handlers(state, d) < 0) {
1701 0 : return -1;
1702 : }
1703 : }
1704 :
1705 2939 : assert(!PyErr_Occurred());
1706 2939 : return 0;
1707 : }
1708 :
1709 :
1710 : #ifdef PYHAVE_ITIMER_ERROR
1711 : static int
1712 52574 : _signal_module_traverse(PyObject *module, visitproc visit, void *arg)
1713 : {
1714 52574 : _signal_module_state *state = get_signal_state(module);
1715 52574 : Py_VISIT(state->itimer_error);
1716 52574 : Py_VISIT(state->siginfo_type);
1717 52574 : return 0;
1718 : }
1719 :
1720 : static int
1721 4853 : _signal_module_clear(PyObject *module)
1722 : {
1723 4853 : _signal_module_state *state = get_signal_state(module);
1724 4853 : Py_CLEAR(state->itimer_error);
1725 4853 : Py_CLEAR(state->siginfo_type);
1726 4853 : return 0;
1727 : }
1728 :
1729 : static void
1730 2930 : _signal_module_free(void *module)
1731 : {
1732 2930 : _signal_module_clear((PyObject *)module);
1733 2930 : }
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 2939 : PyInit__signal(void)
1759 : {
1760 2939 : return PyModuleDef_Init(&signal_module);
1761 : }
1762 :
1763 :
1764 : void
1765 2952 : _PySignal_Fini(void)
1766 : {
1767 2952 : signal_state_t *state = &signal_global_state;
1768 :
1769 : // Restore default signals and clear handlers
1770 191880 : for (int signum = 1; signum < Py_NSIG; signum++) {
1771 188928 : PyObject *func = get_handler(signum);
1772 188928 : _Py_atomic_store_relaxed(&Handlers[signum].tripped, 0);
1773 188928 : set_handler(signum, NULL);
1774 188928 : if (func != NULL
1775 187264 : && func != Py_None
1776 175867 : && !compare_handler(func, state->default_handler)
1777 8901 : && !compare_handler(func, state->ignore_handler))
1778 : {
1779 2856 : PyOS_setsig(signum, SIG_DFL);
1780 : }
1781 188928 : 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 2952 : Py_CLEAR(state->default_handler);
1792 2952 : Py_CLEAR(state->ignore_handler);
1793 2952 : }
1794 :
1795 :
1796 : /* Declared in pyerrors.h */
1797 : int
1798 44663300 : PyErr_CheckSignals(void)
1799 : {
1800 44663300 : PyThreadState *tstate = _PyThreadState_GET();
1801 44663300 : if (!_Py_ThreadCanHandleSignals(tstate->interp)) {
1802 395992 : return 0;
1803 : }
1804 :
1805 44267300 : return _PyErr_CheckSignalsTstate(tstate);
1806 : }
1807 :
1808 :
1809 : /* Declared in cpython/pyerrors.h */
1810 : int
1811 44302400 : _PyErr_CheckSignalsTstate(PyThreadState *tstate)
1812 : {
1813 : _Py_CHECK_EMSCRIPTEN_SIGNALS();
1814 44302400 : if (!_Py_atomic_load(&is_tripped)) {
1815 44271100 : 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 31292 : _Py_atomic_store(&is_tripped, 0);
1833 :
1834 31292 : _PyInterpreterFrame *frame = tstate->cframe->current_frame;
1835 31292 : signal_state_t *state = &signal_global_state;
1836 2025180 : for (int i = 1; i < Py_NSIG; i++) {
1837 1994040 : if (!_Py_atomic_load_relaxed(&Handlers[i].tripped)) {
1838 1962880 : continue;
1839 : }
1840 31155 : _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 31155 : PyObject *func = get_handler(i);
1849 62310 : if (func == NULL || func == Py_None ||
1850 62310 : compare_handler(func, state->ignore_handler) ||
1851 31155 : 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 0 : PyErr_Format(PyExc_OSError,
1861 : "Signal %i ignored due to race condition",
1862 : i);
1863 0 : PyErr_WriteUnraisable(Py_None);
1864 0 : continue;
1865 : }
1866 31155 : PyObject *arglist = NULL;
1867 31155 : if (frame == NULL) {
1868 0 : arglist = Py_BuildValue("(iO)", i, Py_None);
1869 : }
1870 : else {
1871 31155 : PyFrameObject *f = _PyFrame_GetFrameObject(frame);
1872 31155 : if (f != NULL) {
1873 31155 : arglist = Py_BuildValue("(iO)", i, f);
1874 : }
1875 : }
1876 : PyObject *result;
1877 31155 : if (arglist) {
1878 31155 : result = _PyObject_Call(tstate, func, arglist, NULL);
1879 31155 : Py_DECREF(arglist);
1880 : }
1881 : else {
1882 0 : result = NULL;
1883 : }
1884 31155 : 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 31008 : Py_DECREF(result);
1891 : }
1892 :
1893 31145 : 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 2933 : signal_install_handlers(void)
1934 : {
1935 : #ifdef SIGPIPE
1936 2933 : PyOS_setsig(SIGPIPE, SIG_IGN);
1937 : #endif
1938 : #ifdef SIGXFZ
1939 : PyOS_setsig(SIGXFZ, SIG_IGN);
1940 : #endif
1941 : #ifdef SIGXFSZ
1942 2933 : PyOS_setsig(SIGXFSZ, SIG_IGN);
1943 : #endif
1944 :
1945 : // Import _signal to install the Python SIGINT handler
1946 2933 : PyObject *module = PyImport_ImportModule("_signal");
1947 2933 : if (!module) {
1948 0 : return -1;
1949 : }
1950 2933 : Py_DECREF(module);
1951 :
1952 2933 : 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 4997 : _Py_RestoreSignals(void)
1966 : {
1967 : #ifdef SIGPIPE
1968 4997 : PyOS_setsig(SIGPIPE, SIG_DFL);
1969 : #endif
1970 : #ifdef SIGXFZ
1971 : PyOS_setsig(SIGXFZ, SIG_DFL);
1972 : #endif
1973 : #ifdef SIGXFSZ
1974 4997 : PyOS_setsig(SIGXFSZ, SIG_DFL);
1975 : #endif
1976 4997 : }
1977 :
1978 :
1979 : int
1980 2959 : _PySignal_Init(int install_signal_handlers)
1981 : {
1982 2959 : signal_state_t *state = &signal_global_state;
1983 :
1984 2959 : state->default_handler = PyLong_FromVoidPtr((void *)SIG_DFL);
1985 2959 : if (state->default_handler == NULL) {
1986 0 : return -1;
1987 : }
1988 :
1989 2959 : state->ignore_handler = PyLong_FromVoidPtr((void *)SIG_IGN);
1990 2959 : 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 192335 : for (int signum = 1; signum < Py_NSIG; signum++) {
2004 189376 : _Py_atomic_store_relaxed(&Handlers[signum].tripped, 0);
2005 : }
2006 :
2007 2959 : if (install_signal_handlers) {
2008 2933 : if (signal_install_handlers() < 0) {
2009 0 : return -1;
2010 : }
2011 : }
2012 :
2013 2959 : 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
|