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