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