• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef MS_WINDOWS
8 #include "posixmodule.h"
9 #endif
10 #ifdef MS_WINDOWS
11 #include "socketmodule.h"   /* needed for SOCKET_T */
12 #endif
13 
14 #ifdef MS_WINDOWS
15 #include <windows.h>
16 #ifdef HAVE_PROCESS_H
17 #include <process.h>
18 #endif
19 #endif
20 
21 #ifdef HAVE_SIGNAL_H
22 #include <signal.h>
23 #endif
24 #ifdef HAVE_SYS_STAT_H
25 #include <sys/stat.h>
26 #endif
27 #ifdef HAVE_SYS_TIME_H
28 #include <sys/time.h>
29 #endif
30 
31 #if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
32 #  define PYPTHREAD_SIGMASK
33 #endif
34 
35 #if defined(PYPTHREAD_SIGMASK) && defined(HAVE_PTHREAD_H)
36 #  include <pthread.h>
37 #endif
38 
39 #ifndef SIG_ERR
40 #define SIG_ERR ((PyOS_sighandler_t)(-1))
41 #endif
42 
43 #ifndef NSIG
44 # if defined(_NSIG)
45 #  define NSIG _NSIG            /* For BSD/SysV */
46 # elif defined(_SIGMAX)
47 #  define NSIG (_SIGMAX + 1)    /* For QNX */
48 # elif defined(SIGMAX)
49 #  define NSIG (SIGMAX + 1)     /* For djgpp */
50 # else
51 #  define NSIG 64               /* Use a reasonable default value */
52 # endif
53 #endif
54 
55 #include "clinic/signalmodule.c.h"
56 
57 /*[clinic input]
58 module signal
59 [clinic start generated code]*/
60 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=b0301a3bde5fe9d3]*/
61 
62 
63 /*
64    NOTES ON THE INTERACTION BETWEEN SIGNALS AND THREADS
65 
66    When threads are supported, we want the following semantics:
67 
68    - only the main thread can set a signal handler
69    - any thread can get a signal handler
70    - signals are only delivered to the main thread
71 
72    I.e. we don't support "synchronous signals" like SIGFPE (catching
73    this doesn't make much sense in Python anyway) nor do we support
74    signals as a means of inter-thread communication, since not all
75    thread implementations support that (at least our thread library
76    doesn't).
77 
78    We still have the problem that in some implementations signals
79    generated by the keyboard (e.g. SIGINT) are delivered to all
80    threads (e.g. SGI), while in others (e.g. Solaris) such signals are
81    delivered to one random thread (an intermediate possibility would
82    be to deliver it to the main thread -- POSIX?).  For now, we have
83    a working implementation that works in all three cases -- the
84    handler ignores signals if getpid() isn't the same as in the main
85    thread.  XXX This is a hack.
86 */
87 
88 #include <sys/types.h> /* For pid_t */
89 #include "pythread.h"
90 static unsigned long main_thread;
91 static pid_t main_pid;
92 
93 static volatile struct {
94     _Py_atomic_int tripped;
95     PyObject *func;
96 } Handlers[NSIG];
97 
98 #ifdef MS_WINDOWS
99 #define INVALID_FD ((SOCKET_T)-1)
100 
101 static volatile struct {
102     SOCKET_T fd;
103     int warn_on_full_buffer;
104     int use_send;
105 } wakeup = {.fd = INVALID_FD, .warn_on_full_buffer = 1, .use_send = 0};
106 #else
107 #define INVALID_FD (-1)
108 static volatile struct {
109     sig_atomic_t fd;
110     int warn_on_full_buffer;
111 } wakeup = {.fd = INVALID_FD, .warn_on_full_buffer = 1};
112 #endif
113 
114 /* Speed up sigcheck() when none tripped */
115 static _Py_atomic_int is_tripped;
116 
117 static PyObject *DefaultHandler;
118 static PyObject *IgnoreHandler;
119 static PyObject *IntHandler;
120 
121 #ifdef MS_WINDOWS
122 static HANDLE sigint_event = NULL;
123 #endif
124 
125 #ifdef HAVE_GETITIMER
126 static PyObject *ItimerError;
127 
128 /* auxiliary functions for setitimer */
129 static int
timeval_from_double(PyObject * obj,struct timeval * tv)130 timeval_from_double(PyObject *obj, struct timeval *tv)
131 {
132     if (obj == NULL) {
133         tv->tv_sec = 0;
134         tv->tv_usec = 0;
135         return 0;
136     }
137 
138     _PyTime_t t;
139     if (_PyTime_FromSecondsObject(&t, obj, _PyTime_ROUND_CEILING) < 0) {
140         return -1;
141     }
142     return _PyTime_AsTimeval(t, tv, _PyTime_ROUND_CEILING);
143 }
144 
145 Py_LOCAL_INLINE(double)
double_from_timeval(struct timeval * tv)146 double_from_timeval(struct timeval *tv)
147 {
148     return tv->tv_sec + (double)(tv->tv_usec / 1000000.0);
149 }
150 
151 static PyObject *
itimer_retval(struct itimerval * iv)152 itimer_retval(struct itimerval *iv)
153 {
154     PyObject *r, *v;
155 
156     r = PyTuple_New(2);
157     if (r == NULL)
158         return NULL;
159 
160     if(!(v = PyFloat_FromDouble(double_from_timeval(&iv->it_value)))) {
161         Py_DECREF(r);
162         return NULL;
163     }
164 
165     PyTuple_SET_ITEM(r, 0, v);
166 
167     if(!(v = PyFloat_FromDouble(double_from_timeval(&iv->it_interval)))) {
168         Py_DECREF(r);
169         return NULL;
170     }
171 
172     PyTuple_SET_ITEM(r, 1, v);
173 
174     return r;
175 }
176 #endif
177 
178 static PyObject *
signal_default_int_handler(PyObject * self,PyObject * args)179 signal_default_int_handler(PyObject *self, PyObject *args)
180 {
181     PyErr_SetNone(PyExc_KeyboardInterrupt);
182     return NULL;
183 }
184 
185 PyDoc_STRVAR(default_int_handler_doc,
186 "default_int_handler(...)\n\
187 \n\
188 The default handler for SIGINT installed by Python.\n\
189 It raises KeyboardInterrupt.");
190 
191 
192 static int
report_wakeup_write_error(void * data)193 report_wakeup_write_error(void *data)
194 {
195     int save_errno = errno;
196     errno = (int) (intptr_t) data;
197     PyErr_SetFromErrno(PyExc_OSError);
198     PySys_WriteStderr("Exception ignored when trying to write to the "
199                       "signal wakeup fd:\n");
200     PyErr_WriteUnraisable(NULL);
201     errno = save_errno;
202     return 0;
203 }
204 
205 #ifdef MS_WINDOWS
206 static int
report_wakeup_send_error(void * data)207 report_wakeup_send_error(void* data)
208 {
209     /* PyErr_SetExcFromWindowsErr() invokes FormatMessage() which
210        recognizes the error codes used by both GetLastError() and
211        WSAGetLastError */
212     PyErr_SetExcFromWindowsErr(PyExc_OSError, (int) (intptr_t) data);
213     PySys_WriteStderr("Exception ignored when trying to send to the "
214                       "signal wakeup fd:\n");
215     PyErr_WriteUnraisable(NULL);
216     return 0;
217 }
218 #endif   /* MS_WINDOWS */
219 
220 static void
trip_signal(int sig_num)221 trip_signal(int sig_num)
222 {
223     unsigned char byte;
224     int fd;
225     Py_ssize_t rc;
226 
227     _Py_atomic_store_relaxed(&Handlers[sig_num].tripped, 1);
228 
229     /* Set is_tripped after setting .tripped, as it gets
230        cleared in PyErr_CheckSignals() before .tripped. */
231     _Py_atomic_store(&is_tripped, 1);
232 
233     /* Notify ceval.c */
234     _PyEval_SignalReceived();
235 
236     /* And then write to the wakeup fd *after* setting all the globals and
237        doing the _PyEval_SignalReceived. We used to write to the wakeup fd
238        and then set the flag, but this allowed the following sequence of events
239        (especially on windows, where trip_signal may run in a new thread):
240 
241        - main thread blocks on select([wakeup.fd], ...)
242        - signal arrives
243        - trip_signal writes to the wakeup fd
244        - the main thread wakes up
245        - the main thread checks the signal flags, sees that they're unset
246        - the main thread empties the wakeup fd
247        - the main thread goes back to sleep
248        - trip_signal sets the flags to request the Python-level signal handler
249          be run
250        - the main thread doesn't notice, because it's asleep
251 
252        See bpo-30038 for more details.
253     */
254 
255 #ifdef MS_WINDOWS
256     fd = Py_SAFE_DOWNCAST(wakeup.fd, SOCKET_T, int);
257 #else
258     fd = wakeup.fd;
259 #endif
260 
261     if (fd != INVALID_FD) {
262         byte = (unsigned char)sig_num;
263 #ifdef MS_WINDOWS
264         if (wakeup.use_send) {
265             rc = send(fd, &byte, 1, 0);
266 
267             if (rc < 0) {
268                 int last_error = GetLastError();
269                 if (wakeup.warn_on_full_buffer ||
270                     last_error != WSAEWOULDBLOCK)
271                 {
272                     /* Py_AddPendingCall() isn't signal-safe, but we
273                        still use it for this exceptional case. */
274                     Py_AddPendingCall(report_wakeup_send_error,
275                                       (void *)(intptr_t) last_error);
276                 }
277             }
278         }
279         else
280 #endif
281         {
282             /* _Py_write_noraise() retries write() if write() is interrupted by
283                a signal (fails with EINTR). */
284             rc = _Py_write_noraise(fd, &byte, 1);
285 
286             if (rc < 0) {
287                 if (wakeup.warn_on_full_buffer ||
288                     (errno != EWOULDBLOCK && errno != EAGAIN))
289                 {
290                     /* Py_AddPendingCall() isn't signal-safe, but we
291                        still use it for this exceptional case. */
292                     Py_AddPendingCall(report_wakeup_write_error,
293                                       (void *)(intptr_t)errno);
294                 }
295             }
296         }
297     }
298 }
299 
300 static void
signal_handler(int sig_num)301 signal_handler(int sig_num)
302 {
303     int save_errno = errno;
304 
305     /* See NOTES section above */
306     if (getpid() == main_pid)
307     {
308         trip_signal(sig_num);
309     }
310 
311 #ifndef HAVE_SIGACTION
312 #ifdef SIGCHLD
313     /* To avoid infinite recursion, this signal remains
314        reset until explicit re-instated.
315        Don't clear the 'func' field as it is our pointer
316        to the Python handler... */
317     if (sig_num != SIGCHLD)
318 #endif
319     /* If the handler was not set up with sigaction, reinstall it.  See
320      * Python/pylifecycle.c for the implementation of PyOS_setsig which
321      * makes this true.  See also issue8354. */
322     PyOS_setsig(sig_num, signal_handler);
323 #endif
324 
325     /* Issue #10311: asynchronously executing signal handlers should not
326        mutate errno under the feet of unsuspecting C code. */
327     errno = save_errno;
328 
329 #ifdef MS_WINDOWS
330     if (sig_num == SIGINT)
331         SetEvent(sigint_event);
332 #endif
333 }
334 
335 
336 #ifdef HAVE_ALARM
337 
338 /*[clinic input]
339 signal.alarm -> long
340 
341     seconds: int
342     /
343 
344 Arrange for SIGALRM to arrive after the given number of seconds.
345 [clinic start generated code]*/
346 
347 static long
signal_alarm_impl(PyObject * module,int seconds)348 signal_alarm_impl(PyObject *module, int seconds)
349 /*[clinic end generated code: output=144232290814c298 input=0d5e97e0e6f39e86]*/
350 {
351     /* alarm() returns the number of seconds remaining */
352     return (long)alarm(seconds);
353 }
354 
355 #endif
356 
357 #ifdef HAVE_PAUSE
358 
359 /*[clinic input]
360 signal.pause
361 
362 Wait until a signal arrives.
363 [clinic start generated code]*/
364 
365 static PyObject *
signal_pause_impl(PyObject * module)366 signal_pause_impl(PyObject *module)
367 /*[clinic end generated code: output=391656788b3c3929 input=f03de0f875752062]*/
368 {
369     Py_BEGIN_ALLOW_THREADS
370     (void)pause();
371     Py_END_ALLOW_THREADS
372     /* make sure that any exceptions that got raised are propagated
373      * back into Python
374      */
375     if (PyErr_CheckSignals())
376         return NULL;
377 
378     Py_RETURN_NONE;
379 }
380 
381 #endif
382 
383 
384 /*[clinic input]
385 signal.signal
386 
387     signalnum: int
388     handler:   object
389     /
390 
391 Set the action for the given signal.
392 
393 The action can be SIG_DFL, SIG_IGN, or a callable Python object.
394 The previous action is returned.  See getsignal() for possible return values.
395 
396 *** IMPORTANT NOTICE ***
397 A signal handler function is called with two arguments:
398 the first is the signal number, the second is the interrupted stack frame.
399 [clinic start generated code]*/
400 
401 static PyObject *
signal_signal_impl(PyObject * module,int signalnum,PyObject * handler)402 signal_signal_impl(PyObject *module, int signalnum, PyObject *handler)
403 /*[clinic end generated code: output=b44cfda43780f3a1 input=deee84af5fa0432c]*/
404 {
405     PyObject *old_handler;
406     void (*func)(int);
407 #ifdef MS_WINDOWS
408     /* Validate that signalnum is one of the allowable signals */
409     switch (signalnum) {
410         case SIGABRT: break;
411 #ifdef SIGBREAK
412         /* Issue #10003: SIGBREAK is not documented as permitted, but works
413            and corresponds to CTRL_BREAK_EVENT. */
414         case SIGBREAK: break;
415 #endif
416         case SIGFPE: break;
417         case SIGILL: break;
418         case SIGINT: break;
419         case SIGSEGV: break;
420         case SIGTERM: break;
421         default:
422             PyErr_SetString(PyExc_ValueError, "invalid signal value");
423             return NULL;
424     }
425 #endif
426     if (PyThread_get_thread_ident() != main_thread) {
427         PyErr_SetString(PyExc_ValueError,
428                         "signal only works in main thread");
429         return NULL;
430     }
431     if (signalnum < 1 || signalnum >= NSIG) {
432         PyErr_SetString(PyExc_ValueError,
433                         "signal number out of range");
434         return NULL;
435     }
436     if (handler == IgnoreHandler)
437         func = SIG_IGN;
438     else if (handler == DefaultHandler)
439         func = SIG_DFL;
440     else if (!PyCallable_Check(handler)) {
441         PyErr_SetString(PyExc_TypeError,
442 "signal handler must be signal.SIG_IGN, signal.SIG_DFL, or a callable object");
443                 return NULL;
444     }
445     else
446         func = signal_handler;
447     /* Check for pending signals before changing signal handler */
448     if (PyErr_CheckSignals()) {
449         return NULL;
450     }
451     if (PyOS_setsig(signalnum, func) == SIG_ERR) {
452         PyErr_SetFromErrno(PyExc_OSError);
453         return NULL;
454     }
455     old_handler = Handlers[signalnum].func;
456     Py_INCREF(handler);
457     Handlers[signalnum].func = handler;
458     if (old_handler != NULL)
459         return old_handler;
460     else
461         Py_RETURN_NONE;
462 }
463 
464 
465 /*[clinic input]
466 signal.getsignal
467 
468     signalnum: int
469     /
470 
471 Return the current action for the given signal.
472 
473 The return value can be:
474   SIG_IGN -- if the signal is being ignored
475   SIG_DFL -- if the default action for the signal is in effect
476   None    -- if an unknown handler is in effect
477   anything else -- the callable Python object used as a handler
478 [clinic start generated code]*/
479 
480 static PyObject *
signal_getsignal_impl(PyObject * module,int signalnum)481 signal_getsignal_impl(PyObject *module, int signalnum)
482 /*[clinic end generated code: output=35b3e0e796fd555e input=ac23a00f19dfa509]*/
483 {
484     PyObject *old_handler;
485     if (signalnum < 1 || signalnum >= NSIG) {
486         PyErr_SetString(PyExc_ValueError,
487                         "signal number out of range");
488         return NULL;
489     }
490     old_handler = Handlers[signalnum].func;
491     if (old_handler != NULL) {
492         Py_INCREF(old_handler);
493         return old_handler;
494     }
495     else {
496         Py_RETURN_NONE;
497     }
498 }
499 
500 #ifdef HAVE_SIGINTERRUPT
501 
502 /*[clinic input]
503 signal.siginterrupt
504 
505     signalnum: int
506     flag:      int
507     /
508 
509 Change system call restart behaviour.
510 
511 If flag is False, system calls will be restarted when interrupted by
512 signal sig, else system calls will be interrupted.
513 [clinic start generated code]*/
514 
515 static PyObject *
signal_siginterrupt_impl(PyObject * module,int signalnum,int flag)516 signal_siginterrupt_impl(PyObject *module, int signalnum, int flag)
517 /*[clinic end generated code: output=063816243d85dd19 input=4160acacca3e2099]*/
518 {
519     if (signalnum < 1 || signalnum >= NSIG) {
520         PyErr_SetString(PyExc_ValueError,
521                         "signal number out of range");
522         return NULL;
523     }
524     if (siginterrupt(signalnum, flag)<0) {
525         PyErr_SetFromErrno(PyExc_OSError);
526         return NULL;
527     }
528     Py_RETURN_NONE;
529 }
530 
531 #endif
532 
533 
534 static PyObject*
signal_set_wakeup_fd(PyObject * self,PyObject * args,PyObject * kwds)535 signal_set_wakeup_fd(PyObject *self, PyObject *args, PyObject *kwds)
536 {
537     struct _Py_stat_struct status;
538     static char *kwlist[] = {
539         "", "warn_on_full_buffer", NULL,
540     };
541     int warn_on_full_buffer = 1;
542 #ifdef MS_WINDOWS
543     PyObject *fdobj;
544     SOCKET_T sockfd, old_sockfd;
545     int res;
546     int res_size = sizeof res;
547     PyObject *mod;
548     int is_socket;
549 
550     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|$p:set_wakeup_fd", kwlist,
551                                      &fdobj, &warn_on_full_buffer))
552         return NULL;
553 
554     sockfd = PyLong_AsSocket_t(fdobj);
555     if (sockfd == (SOCKET_T)(-1) && PyErr_Occurred())
556         return NULL;
557 #else
558     int fd, old_fd;
559 
560     if (!PyArg_ParseTupleAndKeywords(args, kwds, "i|$p:set_wakeup_fd", kwlist,
561                                      &fd, &warn_on_full_buffer))
562         return NULL;
563 #endif
564 
565     if (PyThread_get_thread_ident() != main_thread) {
566         PyErr_SetString(PyExc_ValueError,
567                         "set_wakeup_fd only works in main thread");
568         return NULL;
569     }
570 
571 #ifdef MS_WINDOWS
572     is_socket = 0;
573     if (sockfd != INVALID_FD) {
574         /* Import the _socket module to call WSAStartup() */
575         mod = PyImport_ImportModuleNoBlock("_socket");
576         if (mod == NULL)
577             return NULL;
578         Py_DECREF(mod);
579 
580         /* test the socket */
581         if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR,
582                        (char *)&res, &res_size) != 0) {
583             int fd, err;
584 
585             err = WSAGetLastError();
586             if (err != WSAENOTSOCK) {
587                 PyErr_SetExcFromWindowsErr(PyExc_OSError, err);
588                 return NULL;
589             }
590 
591             fd = (int)sockfd;
592             if ((SOCKET_T)fd != sockfd) {
593                 PyErr_SetString(PyExc_ValueError, "invalid fd");
594                 return NULL;
595             }
596 
597             if (_Py_fstat(fd, &status) != 0)
598                 return NULL;
599 
600             /* on Windows, a file cannot be set to non-blocking mode */
601         }
602         else {
603             is_socket = 1;
604 
605             /* Windows does not provide a function to test if a socket
606                is in non-blocking mode */
607         }
608     }
609 
610     old_sockfd = wakeup.fd;
611     wakeup.fd = sockfd;
612     wakeup.warn_on_full_buffer = warn_on_full_buffer;
613     wakeup.use_send = is_socket;
614 
615     if (old_sockfd != INVALID_FD)
616         return PyLong_FromSocket_t(old_sockfd);
617     else
618         return PyLong_FromLong(-1);
619 #else
620     if (fd != -1) {
621         int blocking;
622 
623         if (_Py_fstat(fd, &status) != 0)
624             return NULL;
625 
626         blocking = _Py_get_blocking(fd);
627         if (blocking < 0)
628             return NULL;
629         if (blocking) {
630             PyErr_Format(PyExc_ValueError,
631                          "the fd %i must be in non-blocking mode",
632                          fd);
633             return NULL;
634         }
635     }
636 
637     old_fd = wakeup.fd;
638     wakeup.fd = fd;
639     wakeup.warn_on_full_buffer = warn_on_full_buffer;
640 
641     return PyLong_FromLong(old_fd);
642 #endif
643 }
644 
645 PyDoc_STRVAR(set_wakeup_fd_doc,
646 "set_wakeup_fd(fd, *, warn_on_full_buffer=True) -> fd\n\
647 \n\
648 Sets the fd to be written to (with the signal number) when a signal\n\
649 comes in.  A library can use this to wakeup select or poll.\n\
650 The previous fd or -1 is returned.\n\
651 \n\
652 The fd must be non-blocking.");
653 
654 /* C API for the same, without all the error checking */
655 int
PySignal_SetWakeupFd(int fd)656 PySignal_SetWakeupFd(int fd)
657 {
658     int old_fd;
659     if (fd < 0)
660         fd = -1;
661 
662 #ifdef MS_WINDOWS
663     old_fd = Py_SAFE_DOWNCAST(wakeup.fd, SOCKET_T, int);
664 #else
665     old_fd = wakeup.fd;
666 #endif
667     wakeup.fd = fd;
668     wakeup.warn_on_full_buffer = 1;
669     return old_fd;
670 }
671 
672 
673 #ifdef HAVE_SETITIMER
674 
675 /*[clinic input]
676 signal.setitimer
677 
678     which:    int
679     seconds:  object
680     interval: object(c_default="NULL") = 0.0
681     /
682 
683 Sets given itimer (one of ITIMER_REAL, ITIMER_VIRTUAL or ITIMER_PROF).
684 
685 The timer will fire after value seconds and after that every interval seconds.
686 The itimer can be cleared by setting seconds to zero.
687 
688 Returns old values as a tuple: (delay, interval).
689 [clinic start generated code]*/
690 
691 static PyObject *
signal_setitimer_impl(PyObject * module,int which,PyObject * seconds,PyObject * interval)692 signal_setitimer_impl(PyObject *module, int which, PyObject *seconds,
693                       PyObject *interval)
694 /*[clinic end generated code: output=65f9dcbddc35527b input=de43daf194e6f66f]*/
695 {
696     struct itimerval new, old;
697 
698     if (timeval_from_double(seconds, &new.it_value) < 0) {
699         return NULL;
700     }
701     if (timeval_from_double(interval, &new.it_interval) < 0) {
702         return NULL;
703     }
704 
705     /* Let OS check "which" value */
706     if (setitimer(which, &new, &old) != 0) {
707         PyErr_SetFromErrno(ItimerError);
708         return NULL;
709     }
710 
711     return itimer_retval(&old);
712 }
713 
714 #endif
715 
716 
717 #ifdef HAVE_GETITIMER
718 
719 /*[clinic input]
720 signal.getitimer
721 
722     which:    int
723     /
724 
725 Returns current value of given itimer.
726 [clinic start generated code]*/
727 
728 static PyObject *
signal_getitimer_impl(PyObject * module,int which)729 signal_getitimer_impl(PyObject *module, int which)
730 /*[clinic end generated code: output=9e053175d517db40 input=f7d21d38f3490627]*/
731 {
732     struct itimerval old;
733 
734     if (getitimer(which, &old) != 0) {
735         PyErr_SetFromErrno(ItimerError);
736         return NULL;
737     }
738 
739     return itimer_retval(&old);
740 }
741 
742 #endif
743 
744 #if defined(PYPTHREAD_SIGMASK) || defined(HAVE_SIGWAIT) || \
745         defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT)
746 /* Convert an iterable to a sigset.
747    Return 0 on success, return -1 and raise an exception on error. */
748 
749 static int
iterable_to_sigset(PyObject * iterable,sigset_t * mask)750 iterable_to_sigset(PyObject *iterable, sigset_t *mask)
751 {
752     int result = -1;
753     PyObject *iterator, *item;
754     long signum;
755 
756     sigemptyset(mask);
757 
758     iterator = PyObject_GetIter(iterable);
759     if (iterator == NULL)
760         goto error;
761 
762     while (1)
763     {
764         item = PyIter_Next(iterator);
765         if (item == NULL) {
766             if (PyErr_Occurred())
767                 goto error;
768             else
769                 break;
770         }
771 
772         signum = PyLong_AsLong(item);
773         Py_DECREF(item);
774         if (signum == -1 && PyErr_Occurred())
775             goto error;
776         if (0 < signum && signum < NSIG) {
777             /* bpo-33329: ignore sigaddset() return value as it can fail
778              * for some reserved signals, but we want the `range(1, NSIG)`
779              * idiom to allow selecting all valid signals.
780              */
781             (void) sigaddset(mask, (int)signum);
782         }
783         else {
784             PyErr_Format(PyExc_ValueError,
785                          "signal number %ld out of range", signum);
786             goto error;
787         }
788     }
789     result = 0;
790 
791 error:
792     Py_XDECREF(iterator);
793     return result;
794 }
795 #endif
796 
797 #if defined(PYPTHREAD_SIGMASK) || defined(HAVE_SIGPENDING)
798 static PyObject*
sigset_to_set(sigset_t mask)799 sigset_to_set(sigset_t mask)
800 {
801     PyObject *signum, *result;
802     int sig;
803 
804     result = PySet_New(0);
805     if (result == NULL)
806         return NULL;
807 
808     for (sig = 1; sig < NSIG; sig++) {
809         if (sigismember(&mask, sig) != 1)
810             continue;
811 
812         /* Handle the case where it is a member by adding the signal to
813            the result list.  Ignore the other cases because they mean the
814            signal isn't a member of the mask or the signal was invalid,
815            and an invalid signal must have been our fault in constructing
816            the loop boundaries. */
817         signum = PyLong_FromLong(sig);
818         if (signum == NULL) {
819             Py_DECREF(result);
820             return NULL;
821         }
822         if (PySet_Add(result, signum) == -1) {
823             Py_DECREF(signum);
824             Py_DECREF(result);
825             return NULL;
826         }
827         Py_DECREF(signum);
828     }
829     return result;
830 }
831 #endif
832 
833 #ifdef PYPTHREAD_SIGMASK
834 
835 /*[clinic input]
836 signal.pthread_sigmask
837 
838     how:  int
839     mask: object
840     /
841 
842 Fetch and/or change the signal mask of the calling thread.
843 [clinic start generated code]*/
844 
845 static PyObject *
signal_pthread_sigmask_impl(PyObject * module,int how,PyObject * mask)846 signal_pthread_sigmask_impl(PyObject *module, int how, PyObject *mask)
847 /*[clinic end generated code: output=ff640fe092bc9181 input=f3b7d7a61b7b8283]*/
848 {
849     sigset_t newmask, previous;
850     int err;
851 
852     if (iterable_to_sigset(mask, &newmask))
853         return NULL;
854 
855     err = pthread_sigmask(how, &newmask, &previous);
856     if (err != 0) {
857         errno = err;
858         PyErr_SetFromErrno(PyExc_OSError);
859         return NULL;
860     }
861 
862     /* if signals was unblocked, signal handlers have been called */
863     if (PyErr_CheckSignals())
864         return NULL;
865 
866     return sigset_to_set(previous);
867 }
868 
869 #endif   /* #ifdef PYPTHREAD_SIGMASK */
870 
871 
872 #ifdef HAVE_SIGPENDING
873 
874 /*[clinic input]
875 signal.sigpending
876 
877 Examine pending signals.
878 
879 Returns a set of signal numbers that are pending for delivery to
880 the calling thread.
881 [clinic start generated code]*/
882 
883 static PyObject *
signal_sigpending_impl(PyObject * module)884 signal_sigpending_impl(PyObject *module)
885 /*[clinic end generated code: output=53375ffe89325022 input=e0036c016f874e29]*/
886 {
887     int err;
888     sigset_t mask;
889     err = sigpending(&mask);
890     if (err)
891         return PyErr_SetFromErrno(PyExc_OSError);
892     return sigset_to_set(mask);
893 }
894 
895 #endif   /* #ifdef HAVE_SIGPENDING */
896 
897 
898 #ifdef HAVE_SIGWAIT
899 
900 /*[clinic input]
901 signal.sigwait
902 
903     sigset: object
904     /
905 
906 Wait for a signal.
907 
908 Suspend execution of the calling thread until the delivery of one of the
909 signals specified in the signal set sigset.  The function accepts the signal
910 and returns the signal number.
911 [clinic start generated code]*/
912 
913 static PyObject *
signal_sigwait(PyObject * module,PyObject * sigset)914 signal_sigwait(PyObject *module, PyObject *sigset)
915 /*[clinic end generated code: output=557173647424f6e4 input=11af2d82d83c2e94]*/
916 {
917     sigset_t set;
918     int err, signum;
919 
920     if (iterable_to_sigset(sigset, &set))
921         return NULL;
922 
923     Py_BEGIN_ALLOW_THREADS
924     err = sigwait(&set, &signum);
925     Py_END_ALLOW_THREADS
926     if (err) {
927         errno = err;
928         return PyErr_SetFromErrno(PyExc_OSError);
929     }
930 
931     return PyLong_FromLong(signum);
932 }
933 
934 #endif   /* #ifdef HAVE_SIGWAIT */
935 
936 
937 #if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT)
938 static int initialized;
939 static PyStructSequence_Field struct_siginfo_fields[] = {
940     {"si_signo",        "signal number"},
941     {"si_code",         "signal code"},
942     {"si_errno",        "errno associated with this signal"},
943     {"si_pid",          "sending process ID"},
944     {"si_uid",          "real user ID of sending process"},
945     {"si_status",       "exit value or signal"},
946     {"si_band",         "band event for SIGPOLL"},
947     {0}
948 };
949 
950 PyDoc_STRVAR(struct_siginfo__doc__,
951 "struct_siginfo: Result from sigwaitinfo or sigtimedwait.\n\n\
952 This object may be accessed either as a tuple of\n\
953 (si_signo, si_code, si_errno, si_pid, si_uid, si_status, si_band),\n\
954 or via the attributes si_signo, si_code, and so on.");
955 
956 static PyStructSequence_Desc struct_siginfo_desc = {
957     "signal.struct_siginfo",           /* name */
958     struct_siginfo__doc__,       /* doc */
959     struct_siginfo_fields,       /* fields */
960     7          /* n_in_sequence */
961 };
962 
963 static PyTypeObject SiginfoType;
964 
965 static PyObject *
fill_siginfo(siginfo_t * si)966 fill_siginfo(siginfo_t *si)
967 {
968     PyObject *result = PyStructSequence_New(&SiginfoType);
969     if (!result)
970         return NULL;
971 
972     PyStructSequence_SET_ITEM(result, 0, PyLong_FromLong((long)(si->si_signo)));
973     PyStructSequence_SET_ITEM(result, 1, PyLong_FromLong((long)(si->si_code)));
974     PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si->si_errno)));
975     PyStructSequence_SET_ITEM(result, 3, PyLong_FromPid(si->si_pid));
976     PyStructSequence_SET_ITEM(result, 4, _PyLong_FromUid(si->si_uid));
977     PyStructSequence_SET_ITEM(result, 5,
978                                 PyLong_FromLong((long)(si->si_status)));
979 #ifdef HAVE_SIGINFO_T_SI_BAND
980     PyStructSequence_SET_ITEM(result, 6, PyLong_FromLong(si->si_band));
981 #else
982     PyStructSequence_SET_ITEM(result, 6, PyLong_FromLong(0L));
983 #endif
984     if (PyErr_Occurred()) {
985         Py_DECREF(result);
986         return NULL;
987     }
988 
989     return result;
990 }
991 #endif
992 
993 #ifdef HAVE_SIGWAITINFO
994 
995 /*[clinic input]
996 signal.sigwaitinfo
997 
998     sigset: object
999     /
1000 
1001 Wait synchronously until one of the signals in *sigset* is delivered.
1002 
1003 Returns a struct_siginfo containing information about the signal.
1004 [clinic start generated code]*/
1005 
1006 static PyObject *
signal_sigwaitinfo(PyObject * module,PyObject * sigset)1007 signal_sigwaitinfo(PyObject *module, PyObject *sigset)
1008 /*[clinic end generated code: output=c40f27b269cd2309 input=f3779a74a991e171]*/
1009 {
1010     sigset_t set;
1011     siginfo_t si;
1012     int err;
1013     int async_err = 0;
1014 
1015     if (iterable_to_sigset(sigset, &set))
1016         return NULL;
1017 
1018     do {
1019         Py_BEGIN_ALLOW_THREADS
1020         err = sigwaitinfo(&set, &si);
1021         Py_END_ALLOW_THREADS
1022     } while (err == -1
1023              && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1024     if (err == -1)
1025         return (!async_err) ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
1026 
1027     return fill_siginfo(&si);
1028 }
1029 
1030 #endif   /* #ifdef HAVE_SIGWAITINFO */
1031 
1032 #ifdef HAVE_SIGTIMEDWAIT
1033 
1034 /*[clinic input]
1035 signal.sigtimedwait
1036 
1037     sigset:  object
1038     timeout as timeout_obj: object
1039     /
1040 
1041 Like sigwaitinfo(), but with a timeout.
1042 
1043 The timeout is specified in seconds, with floating point numbers allowed.
1044 [clinic start generated code]*/
1045 
1046 static PyObject *
signal_sigtimedwait_impl(PyObject * module,PyObject * sigset,PyObject * timeout_obj)1047 signal_sigtimedwait_impl(PyObject *module, PyObject *sigset,
1048                          PyObject *timeout_obj)
1049 /*[clinic end generated code: output=f7eff31e679f4312 input=53fd4ea3e3724eb8]*/
1050 {
1051     struct timespec ts;
1052     sigset_t set;
1053     siginfo_t si;
1054     int res;
1055     _PyTime_t timeout, deadline, monotonic;
1056 
1057     if (_PyTime_FromSecondsObject(&timeout,
1058                                   timeout_obj, _PyTime_ROUND_CEILING) < 0)
1059         return NULL;
1060 
1061     if (timeout < 0) {
1062         PyErr_SetString(PyExc_ValueError, "timeout must be non-negative");
1063         return NULL;
1064     }
1065 
1066     if (iterable_to_sigset(sigset, &set))
1067         return NULL;
1068 
1069     deadline = _PyTime_GetMonotonicClock() + timeout;
1070 
1071     do {
1072         if (_PyTime_AsTimespec(timeout, &ts) < 0)
1073             return NULL;
1074 
1075         Py_BEGIN_ALLOW_THREADS
1076         res = sigtimedwait(&set, &si, &ts);
1077         Py_END_ALLOW_THREADS
1078 
1079         if (res != -1)
1080             break;
1081 
1082         if (errno != EINTR) {
1083             if (errno == EAGAIN)
1084                 Py_RETURN_NONE;
1085             else
1086                 return PyErr_SetFromErrno(PyExc_OSError);
1087         }
1088 
1089         /* sigtimedwait() was interrupted by a signal (EINTR) */
1090         if (PyErr_CheckSignals())
1091             return NULL;
1092 
1093         monotonic = _PyTime_GetMonotonicClock();
1094         timeout = deadline - monotonic;
1095         if (timeout < 0)
1096             break;
1097     } while (1);
1098 
1099     return fill_siginfo(&si);
1100 }
1101 
1102 #endif   /* #ifdef HAVE_SIGTIMEDWAIT */
1103 
1104 
1105 #if defined(HAVE_PTHREAD_KILL)
1106 
1107 /*[clinic input]
1108 signal.pthread_kill
1109 
1110     thread_id:  unsigned_long(bitwise=True)
1111     signalnum:  int
1112     /
1113 
1114 Send a signal to a thread.
1115 [clinic start generated code]*/
1116 
1117 static PyObject *
signal_pthread_kill_impl(PyObject * module,unsigned long thread_id,int signalnum)1118 signal_pthread_kill_impl(PyObject *module, unsigned long thread_id,
1119                          int signalnum)
1120 /*[clinic end generated code: output=7629919b791bc27f input=1d901f2c7bb544ff]*/
1121 {
1122     int err;
1123 
1124     err = pthread_kill((pthread_t)thread_id, signalnum);
1125     if (err != 0) {
1126         errno = err;
1127         PyErr_SetFromErrno(PyExc_OSError);
1128         return NULL;
1129     }
1130 
1131     /* the signal may have been send to the current thread */
1132     if (PyErr_CheckSignals())
1133         return NULL;
1134 
1135     Py_RETURN_NONE;
1136 }
1137 
1138 #endif   /* #if defined(HAVE_PTHREAD_KILL) */
1139 
1140 
1141 
1142 /* List of functions defined in the module -- some of the methoddefs are
1143    defined to nothing if the corresponding C function is not available. */
1144 static PyMethodDef signal_methods[] = {
1145     {"default_int_handler", signal_default_int_handler, METH_VARARGS, default_int_handler_doc},
1146     SIGNAL_ALARM_METHODDEF
1147     SIGNAL_SETITIMER_METHODDEF
1148     SIGNAL_GETITIMER_METHODDEF
1149     SIGNAL_SIGNAL_METHODDEF
1150     SIGNAL_GETSIGNAL_METHODDEF
1151     {"set_wakeup_fd", (PyCFunction)signal_set_wakeup_fd, METH_VARARGS | METH_KEYWORDS, set_wakeup_fd_doc},
1152     SIGNAL_SIGINTERRUPT_METHODDEF
1153     SIGNAL_PAUSE_METHODDEF
1154     SIGNAL_PTHREAD_KILL_METHODDEF
1155     SIGNAL_PTHREAD_SIGMASK_METHODDEF
1156     SIGNAL_SIGPENDING_METHODDEF
1157     SIGNAL_SIGWAIT_METHODDEF
1158     SIGNAL_SIGWAITINFO_METHODDEF
1159     SIGNAL_SIGTIMEDWAIT_METHODDEF
1160     {NULL, NULL}           /* sentinel */
1161 };
1162 
1163 
1164 PyDoc_STRVAR(module_doc,
1165 "This module provides mechanisms to use signal handlers in Python.\n\
1166 \n\
1167 Functions:\n\
1168 \n\
1169 alarm() -- cause SIGALRM after a specified time [Unix only]\n\
1170 setitimer() -- cause a signal (described below) after a specified\n\
1171                float time and the timer may restart then [Unix only]\n\
1172 getitimer() -- get current value of timer [Unix only]\n\
1173 signal() -- set the action for a given signal\n\
1174 getsignal() -- get the signal action for a given signal\n\
1175 pause() -- wait until a signal arrives [Unix only]\n\
1176 default_int_handler() -- default SIGINT handler\n\
1177 \n\
1178 signal constants:\n\
1179 SIG_DFL -- used to refer to the system default handler\n\
1180 SIG_IGN -- used to ignore the signal\n\
1181 NSIG -- number of defined signals\n\
1182 SIGINT, SIGTERM, etc. -- signal numbers\n\
1183 \n\
1184 itimer constants:\n\
1185 ITIMER_REAL -- decrements in real time, and delivers SIGALRM upon\n\
1186                expiration\n\
1187 ITIMER_VIRTUAL -- decrements only when the process is executing,\n\
1188                and delivers SIGVTALRM upon expiration\n\
1189 ITIMER_PROF -- decrements both when the process is executing and\n\
1190                when the system is executing on behalf of the process.\n\
1191                Coupled with ITIMER_VIRTUAL, this timer is usually\n\
1192                used to profile the time spent by the application\n\
1193                in user and kernel space. SIGPROF is delivered upon\n\
1194                expiration.\n\
1195 \n\n\
1196 *** IMPORTANT NOTICE ***\n\
1197 A signal handler function is called with two arguments:\n\
1198 the first is the signal number, the second is the interrupted stack frame.");
1199 
1200 static struct PyModuleDef signalmodule = {
1201     PyModuleDef_HEAD_INIT,
1202     "_signal",
1203     module_doc,
1204     -1,
1205     signal_methods,
1206     NULL,
1207     NULL,
1208     NULL,
1209     NULL
1210 };
1211 
1212 PyMODINIT_FUNC
PyInit__signal(void)1213 PyInit__signal(void)
1214 {
1215     PyObject *m, *d, *x;
1216     int i;
1217 
1218     main_thread = PyThread_get_thread_ident();
1219     main_pid = getpid();
1220 
1221     /* Create the module and add the functions */
1222     m = PyModule_Create(&signalmodule);
1223     if (m == NULL)
1224         return NULL;
1225 
1226 #if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT)
1227     if (!initialized) {
1228         if (PyStructSequence_InitType2(&SiginfoType, &struct_siginfo_desc) < 0)
1229             return NULL;
1230     }
1231     Py_INCREF((PyObject*) &SiginfoType);
1232     PyModule_AddObject(m, "struct_siginfo", (PyObject*) &SiginfoType);
1233     initialized = 1;
1234 #endif
1235 
1236     /* Add some symbolic constants to the module */
1237     d = PyModule_GetDict(m);
1238 
1239     x = DefaultHandler = PyLong_FromVoidPtr((void *)SIG_DFL);
1240     if (!x || PyDict_SetItemString(d, "SIG_DFL", x) < 0)
1241         goto finally;
1242 
1243     x = IgnoreHandler = PyLong_FromVoidPtr((void *)SIG_IGN);
1244     if (!x || PyDict_SetItemString(d, "SIG_IGN", x) < 0)
1245         goto finally;
1246 
1247     x = PyLong_FromLong((long)NSIG);
1248     if (!x || PyDict_SetItemString(d, "NSIG", x) < 0)
1249         goto finally;
1250     Py_DECREF(x);
1251 
1252 #ifdef SIG_BLOCK
1253     if (PyModule_AddIntMacro(m, SIG_BLOCK))
1254          goto finally;
1255 #endif
1256 #ifdef SIG_UNBLOCK
1257     if (PyModule_AddIntMacro(m, SIG_UNBLOCK))
1258          goto finally;
1259 #endif
1260 #ifdef SIG_SETMASK
1261     if (PyModule_AddIntMacro(m, SIG_SETMASK))
1262          goto finally;
1263 #endif
1264 
1265     x = IntHandler = PyDict_GetItemString(d, "default_int_handler");
1266     if (!x)
1267         goto finally;
1268     Py_INCREF(IntHandler);
1269 
1270     _Py_atomic_store_relaxed(&Handlers[0].tripped, 0);
1271     for (i = 1; i < NSIG; i++) {
1272         void (*t)(int);
1273         t = PyOS_getsig(i);
1274         _Py_atomic_store_relaxed(&Handlers[i].tripped, 0);
1275         if (t == SIG_DFL)
1276             Handlers[i].func = DefaultHandler;
1277         else if (t == SIG_IGN)
1278             Handlers[i].func = IgnoreHandler;
1279         else
1280             Handlers[i].func = Py_None; /* None of our business */
1281         Py_INCREF(Handlers[i].func);
1282     }
1283     if (Handlers[SIGINT].func == DefaultHandler) {
1284         /* Install default int handler */
1285         Py_INCREF(IntHandler);
1286         Py_SETREF(Handlers[SIGINT].func, IntHandler);
1287         PyOS_setsig(SIGINT, signal_handler);
1288     }
1289 
1290 #ifdef SIGHUP
1291     if (PyModule_AddIntMacro(m, SIGHUP))
1292          goto finally;
1293 #endif
1294 #ifdef SIGINT
1295     if (PyModule_AddIntMacro(m, SIGINT))
1296          goto finally;
1297 #endif
1298 #ifdef SIGBREAK
1299     if (PyModule_AddIntMacro(m, SIGBREAK))
1300          goto finally;
1301 #endif
1302 #ifdef SIGQUIT
1303     if (PyModule_AddIntMacro(m, SIGQUIT))
1304          goto finally;
1305 #endif
1306 #ifdef SIGILL
1307     if (PyModule_AddIntMacro(m, SIGILL))
1308          goto finally;
1309 #endif
1310 #ifdef SIGTRAP
1311     if (PyModule_AddIntMacro(m, SIGTRAP))
1312          goto finally;
1313 #endif
1314 #ifdef SIGIOT
1315     if (PyModule_AddIntMacro(m, SIGIOT))
1316          goto finally;
1317 #endif
1318 #ifdef SIGABRT
1319     if (PyModule_AddIntMacro(m, SIGABRT))
1320          goto finally;
1321 #endif
1322 #ifdef SIGEMT
1323     if (PyModule_AddIntMacro(m, SIGEMT))
1324          goto finally;
1325 #endif
1326 #ifdef SIGFPE
1327     if (PyModule_AddIntMacro(m, SIGFPE))
1328          goto finally;
1329 #endif
1330 #ifdef SIGKILL
1331     if (PyModule_AddIntMacro(m, SIGKILL))
1332          goto finally;
1333 #endif
1334 #ifdef SIGBUS
1335     if (PyModule_AddIntMacro(m, SIGBUS))
1336          goto finally;
1337 #endif
1338 #ifdef SIGSEGV
1339     if (PyModule_AddIntMacro(m, SIGSEGV))
1340          goto finally;
1341 #endif
1342 #ifdef SIGSYS
1343     if (PyModule_AddIntMacro(m, SIGSYS))
1344          goto finally;
1345 #endif
1346 #ifdef SIGPIPE
1347     if (PyModule_AddIntMacro(m, SIGPIPE))
1348          goto finally;
1349 #endif
1350 #ifdef SIGALRM
1351     if (PyModule_AddIntMacro(m, SIGALRM))
1352          goto finally;
1353 #endif
1354 #ifdef SIGTERM
1355     if (PyModule_AddIntMacro(m, SIGTERM))
1356          goto finally;
1357 #endif
1358 #ifdef SIGUSR1
1359     if (PyModule_AddIntMacro(m, SIGUSR1))
1360          goto finally;
1361 #endif
1362 #ifdef SIGUSR2
1363     if (PyModule_AddIntMacro(m, SIGUSR2))
1364          goto finally;
1365 #endif
1366 #ifdef SIGCLD
1367     if (PyModule_AddIntMacro(m, SIGCLD))
1368          goto finally;
1369 #endif
1370 #ifdef SIGCHLD
1371     if (PyModule_AddIntMacro(m, SIGCHLD))
1372          goto finally;
1373 #endif
1374 #ifdef SIGPWR
1375     if (PyModule_AddIntMacro(m, SIGPWR))
1376          goto finally;
1377 #endif
1378 #ifdef SIGIO
1379     if (PyModule_AddIntMacro(m, SIGIO))
1380          goto finally;
1381 #endif
1382 #ifdef SIGURG
1383     if (PyModule_AddIntMacro(m, SIGURG))
1384          goto finally;
1385 #endif
1386 #ifdef SIGWINCH
1387     if (PyModule_AddIntMacro(m, SIGWINCH))
1388          goto finally;
1389 #endif
1390 #ifdef SIGPOLL
1391     if (PyModule_AddIntMacro(m, SIGPOLL))
1392          goto finally;
1393 #endif
1394 #ifdef SIGSTOP
1395     if (PyModule_AddIntMacro(m, SIGSTOP))
1396          goto finally;
1397 #endif
1398 #ifdef SIGTSTP
1399     if (PyModule_AddIntMacro(m, SIGTSTP))
1400          goto finally;
1401 #endif
1402 #ifdef SIGCONT
1403     if (PyModule_AddIntMacro(m, SIGCONT))
1404          goto finally;
1405 #endif
1406 #ifdef SIGTTIN
1407     if (PyModule_AddIntMacro(m, SIGTTIN))
1408          goto finally;
1409 #endif
1410 #ifdef SIGTTOU
1411     if (PyModule_AddIntMacro(m, SIGTTOU))
1412          goto finally;
1413 #endif
1414 #ifdef SIGVTALRM
1415     if (PyModule_AddIntMacro(m, SIGVTALRM))
1416          goto finally;
1417 #endif
1418 #ifdef SIGPROF
1419     if (PyModule_AddIntMacro(m, SIGPROF))
1420          goto finally;
1421 #endif
1422 #ifdef SIGXCPU
1423     if (PyModule_AddIntMacro(m, SIGXCPU))
1424          goto finally;
1425 #endif
1426 #ifdef SIGXFSZ
1427     if (PyModule_AddIntMacro(m, SIGXFSZ))
1428          goto finally;
1429 #endif
1430 #ifdef SIGRTMIN
1431     if (PyModule_AddIntMacro(m, SIGRTMIN))
1432          goto finally;
1433 #endif
1434 #ifdef SIGRTMAX
1435     if (PyModule_AddIntMacro(m, SIGRTMAX))
1436          goto finally;
1437 #endif
1438 #ifdef SIGINFO
1439     if (PyModule_AddIntMacro(m, SIGINFO))
1440          goto finally;
1441 #endif
1442 
1443 #ifdef ITIMER_REAL
1444     if (PyModule_AddIntMacro(m, ITIMER_REAL))
1445          goto finally;
1446 #endif
1447 #ifdef ITIMER_VIRTUAL
1448     if (PyModule_AddIntMacro(m, ITIMER_VIRTUAL))
1449          goto finally;
1450 #endif
1451 #ifdef ITIMER_PROF
1452     if (PyModule_AddIntMacro(m, ITIMER_PROF))
1453          goto finally;
1454 #endif
1455 
1456 #if defined (HAVE_SETITIMER) || defined (HAVE_GETITIMER)
1457     ItimerError = PyErr_NewException("signal.ItimerError",
1458             PyExc_OSError, NULL);
1459     if (ItimerError != NULL)
1460         PyDict_SetItemString(d, "ItimerError", ItimerError);
1461 #endif
1462 
1463 #ifdef CTRL_C_EVENT
1464     if (PyModule_AddIntMacro(m, CTRL_C_EVENT))
1465          goto finally;
1466 #endif
1467 
1468 #ifdef CTRL_BREAK_EVENT
1469     if (PyModule_AddIntMacro(m, CTRL_BREAK_EVENT))
1470          goto finally;
1471 #endif
1472 
1473 #ifdef MS_WINDOWS
1474     /* Create manual-reset event, initially unset */
1475     sigint_event = CreateEvent(NULL, TRUE, FALSE, FALSE);
1476 #endif
1477 
1478     if (PyErr_Occurred()) {
1479         Py_DECREF(m);
1480         m = NULL;
1481     }
1482 
1483   finally:
1484     return m;
1485 }
1486 
1487 static void
finisignal(void)1488 finisignal(void)
1489 {
1490     int i;
1491     PyObject *func;
1492 
1493     for (i = 1; i < NSIG; i++) {
1494         func = Handlers[i].func;
1495         _Py_atomic_store_relaxed(&Handlers[i].tripped, 0);
1496         Handlers[i].func = NULL;
1497         if (func != NULL && func != Py_None &&
1498             func != DefaultHandler && func != IgnoreHandler)
1499             PyOS_setsig(i, SIG_DFL);
1500         Py_XDECREF(func);
1501     }
1502 
1503     Py_CLEAR(IntHandler);
1504     Py_CLEAR(DefaultHandler);
1505     Py_CLEAR(IgnoreHandler);
1506 }
1507 
1508 
1509 /* Declared in pyerrors.h */
1510 int
PyErr_CheckSignals(void)1511 PyErr_CheckSignals(void)
1512 {
1513     int i;
1514     PyObject *f;
1515 
1516     if (!_Py_atomic_load(&is_tripped))
1517         return 0;
1518 
1519     if (PyThread_get_thread_ident() != main_thread)
1520         return 0;
1521 
1522     /*
1523      * The is_tripped variable is meant to speed up the calls to
1524      * PyErr_CheckSignals (both directly or via pending calls) when no
1525      * signal has arrived. This variable is set to 1 when a signal arrives
1526      * and it is set to 0 here, when we know some signals arrived. This way
1527      * we can run the registered handlers with no signals blocked.
1528      *
1529      * NOTE: with this approach we can have a situation where is_tripped is
1530      *       1 but we have no more signals to handle (Handlers[i].tripped
1531      *       is 0 for every signal i). This won't do us any harm (except
1532      *       we're gonna spent some cycles for nothing). This happens when
1533      *       we receive a signal i after we zero is_tripped and before we
1534      *       check Handlers[i].tripped.
1535      */
1536     _Py_atomic_store(&is_tripped, 0);
1537 
1538     if (!(f = (PyObject *)PyEval_GetFrame()))
1539         f = Py_None;
1540 
1541     for (i = 1; i < NSIG; i++) {
1542         if (_Py_atomic_load_relaxed(&Handlers[i].tripped)) {
1543             PyObject *result = NULL;
1544             PyObject *arglist = Py_BuildValue("(iO)", i, f);
1545             _Py_atomic_store_relaxed(&Handlers[i].tripped, 0);
1546 
1547             if (arglist) {
1548                 result = PyEval_CallObject(Handlers[i].func,
1549                                            arglist);
1550                 Py_DECREF(arglist);
1551             }
1552             if (!result) {
1553                 _Py_atomic_store(&is_tripped, 1);
1554                 return -1;
1555             }
1556 
1557             Py_DECREF(result);
1558         }
1559     }
1560 
1561     return 0;
1562 }
1563 
1564 
1565 /* Replacements for intrcheck.c functionality
1566  * Declared in pyerrors.h
1567  */
1568 void
PyErr_SetInterrupt(void)1569 PyErr_SetInterrupt(void)
1570 {
1571     trip_signal(SIGINT);
1572 }
1573 
1574 void
PyOS_InitInterrupts(void)1575 PyOS_InitInterrupts(void)
1576 {
1577     PyObject *m = PyImport_ImportModule("_signal");
1578     if (m) {
1579         Py_DECREF(m);
1580     }
1581 }
1582 
1583 void
PyOS_FiniInterrupts(void)1584 PyOS_FiniInterrupts(void)
1585 {
1586     finisignal();
1587 }
1588 
1589 int
PyOS_InterruptOccurred(void)1590 PyOS_InterruptOccurred(void)
1591 {
1592     if (_Py_atomic_load_relaxed(&Handlers[SIGINT].tripped)) {
1593         if (PyThread_get_thread_ident() != main_thread)
1594             return 0;
1595         _Py_atomic_store_relaxed(&Handlers[SIGINT].tripped, 0);
1596         return 1;
1597     }
1598     return 0;
1599 }
1600 
1601 static void
_clear_pending_signals(void)1602 _clear_pending_signals(void)
1603 {
1604     int i;
1605     if (!_Py_atomic_load(&is_tripped))
1606         return;
1607     _Py_atomic_store(&is_tripped, 0);
1608     for (i = 1; i < NSIG; ++i) {
1609         _Py_atomic_store_relaxed(&Handlers[i].tripped, 0);
1610     }
1611 }
1612 
1613 void
_PySignal_AfterFork(void)1614 _PySignal_AfterFork(void)
1615 {
1616     /* Clear the signal flags after forking so that they aren't handled
1617      * in both processes if they came in just before the fork() but before
1618      * the interpreter had an opportunity to call the handlers.  issue9535. */
1619     _clear_pending_signals();
1620     main_thread = PyThread_get_thread_ident();
1621     main_pid = getpid();
1622 }
1623 
1624 int
_PyOS_IsMainThread(void)1625 _PyOS_IsMainThread(void)
1626 {
1627     return PyThread_get_thread_ident() == main_thread;
1628 }
1629 
1630 #ifdef MS_WINDOWS
_PyOS_SigintEvent(void)1631 void *_PyOS_SigintEvent(void)
1632 {
1633     /* Returns a manual-reset event which gets tripped whenever
1634        SIGINT is received.
1635 
1636        Python.h does not include windows.h so we do cannot use HANDLE
1637        as the return type of this function.  We use void* instead. */
1638     return sigint_event;
1639 }
1640 #endif
1641