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]
58module 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"
91static long main_thread;
92static pid_t main_pid;
93#endif
94
95static 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
103static 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)
112static volatile sig_atomic_t wakeup_fd = -1;
113#endif
114
115/* Speed up sigcheck() when none tripped */
116static volatile sig_atomic_t is_tripped = 0;
117
118static PyObject *DefaultHandler;
119static PyObject *IgnoreHandler;
120static 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
127static PyOS_sighandler_t old_siginthandler = SIG_DFL;
128
129#ifdef MS_WINDOWS
130static HANDLE sigint_event = NULL;
131#endif
132
133#ifdef HAVE_GETITIMER
134static PyObject *ItimerError;
135
136/* auxiliary functions for setitimer/getitimer */
137static void
138timeval_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
144Py_LOCAL_INLINE(double)
145double_from_timeval(struct timeval *tv)
146{
147    return tv->tv_sec + (double)(tv->tv_usec / 1000000.0);
148}
149
150static PyObject *
151itimer_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
177static PyObject *
178signal_default_int_handler(PyObject *self, PyObject *args)
179{
180    PyErr_SetNone(PyExc_KeyboardInterrupt);
181    return NULL;
182}
183
184PyDoc_STRVAR(default_int_handler_doc,
185"default_int_handler(...)\n\
186\n\
187The default handler for SIGINT installed by Python.\n\
188It raises KeyboardInterrupt.");
189
190
191static int
192checksignals_witharg(void * unused)
193{
194    return PyErr_CheckSignals();
195}
196
197static int
198report_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
211static int
212report_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
238static void
239trip_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
293static void
294signal_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]
334signal.alarm -> long
335
336    seconds: int
337    /
338
339Arrange for SIGALRM to arrive after the given number of seconds.
340[clinic start generated code]*/
341
342static long
343signal_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]
355signal.pause
356
357Wait until a signal arrives.
358[clinic start generated code]*/
359
360static PyObject *
361signal_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]
380signal.signal
381
382    signalnum: int
383    handler:   object
384    /
385
386Set the action for the given signal.
387
388The action can be SIG_DFL, SIG_IGN, or a callable Python object.
389The previous action is returned.  See getsignal() for possible return values.
390
391*** IMPORTANT NOTICE ***
392A signal handler function is called with two arguments:
393the first is the signal number, the second is the interrupted stack frame.
394[clinic start generated code]*/
395
396static PyObject *
397signal_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]
460signal.getsignal
461
462    signalnum: int
463    /
464
465Return the current action for the given signal.
466
467The 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
474static PyObject *
475signal_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]
497signal.siginterrupt
498
499    signalnum: int
500    flag:      int
501    /
502
503Change system call restart behaviour.
504
505If flag is False, system calls will be restarted when interrupted by
506signal sig, else system calls will be interrupted.
507[clinic start generated code]*/
508
509static PyObject *
510signal_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
528static PyObject*
529signal_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
633PyDoc_STRVAR(set_wakeup_fd_doc,
634"set_wakeup_fd(fd) -> fd\n\
635\n\
636Sets the fd to be written to (with the signal number) when a signal\n\
637comes in.  A library can use this to wakeup select or poll.\n\
638The previous fd or -1 is returned.\n\
639\n\
640The fd must be non-blocking.");
641
642/* C API for the same, without all the error checking */
643int
644PySignal_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]
664signal.setitimer
665
666    which:    int
667    seconds:  double
668    interval: double = 0.0
669    /
670
671Sets given itimer (one of ITIMER_REAL, ITIMER_VIRTUAL or ITIMER_PROF).
672
673The timer will fire after value seconds and after that every interval seconds.
674The itimer can be cleared by setting seconds to zero.
675
676Returns old values as a tuple: (delay, interval).
677[clinic start generated code]*/
678
679static PyObject *
680signal_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]
703signal.getitimer
704
705    which:    int
706    /
707
708Returns current value of given itimer.
709[clinic start generated code]*/
710
711static PyObject *
712signal_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
732static int
733iterable_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
772error:
773    Py_XDECREF(iterator);
774    return result;
775}
776#endif
777
778#if defined(PYPTHREAD_SIGMASK) || defined(HAVE_SIGPENDING)
779static PyObject*
780sigset_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]
817signal.pthread_sigmask
818
819    how:  int
820    mask: object
821    /
822
823Fetch and/or change the signal mask of the calling thread.
824[clinic start generated code]*/
825
826static PyObject *
827signal_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]
856signal.sigpending
857
858Examine pending signals.
859
860Returns a set of signal numbers that are pending for delivery to
861the calling thread.
862[clinic start generated code]*/
863
864static PyObject *
865signal_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]
882signal.sigwait
883
884    sigset: object
885    /
886
887Wait for a signal.
888
889Suspend execution of the calling thread until the delivery of one of the
890signals specified in the signal set sigset.  The function accepts the signal
891and returns the signal number.
892[clinic start generated code]*/
893
894static PyObject *
895signal_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)
919static int initialized;
920static 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
931PyDoc_STRVAR(struct_siginfo__doc__,
932"struct_siginfo: Result from sigwaitinfo or sigtimedwait.\n\n\
933This 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\
935or via the attributes si_signo, si_code, and so on.");
936
937static 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
944static PyTypeObject SiginfoType;
945
946static PyObject *
947fill_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]
973signal.sigwaitinfo
974
975    sigset: object
976    /
977
978Wait synchronously until one of the signals in *sigset* is delivered.
979
980Returns a struct_siginfo containing information about the signal.
981[clinic start generated code]*/
982
983static PyObject *
984signal_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]
1012signal.sigtimedwait
1013
1014    sigset:  object
1015    timeout as timeout_obj: object
1016    /
1017
1018Like sigwaitinfo(), but with a timeout.
1019
1020The timeout is specified in seconds, with floating point numbers allowed.
1021[clinic start generated code]*/
1022
1023static PyObject *
1024signal_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]
1085signal.pthread_kill
1086
1087    thread_id:  long
1088    signalnum:  int
1089    /
1090
1091Send a signal to a thread.
1092[clinic start generated code]*/
1093
1094static PyObject *
1095signal_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. */
1120static 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
1140PyDoc_STRVAR(module_doc,
1141"This module provides mechanisms to use signal handlers in Python.\n\
1142\n\
1143Functions:\n\
1144\n\
1145alarm() -- cause SIGALRM after a specified time [Unix only]\n\
1146setitimer() -- cause a signal (described below) after a specified\n\
1147               float time and the timer may restart then [Unix only]\n\
1148getitimer() -- get current value of timer [Unix only]\n\
1149signal() -- set the action for a given signal\n\
1150getsignal() -- get the signal action for a given signal\n\
1151pause() -- wait until a signal arrives [Unix only]\n\
1152default_int_handler() -- default SIGINT handler\n\
1153\n\
1154signal constants:\n\
1155SIG_DFL -- used to refer to the system default handler\n\
1156SIG_IGN -- used to ignore the signal\n\
1157NSIG -- number of defined signals\n\
1158SIGINT, SIGTERM, etc. -- signal numbers\n\
1159\n\
1160itimer constants:\n\
1161ITIMER_REAL -- decrements in real time, and delivers SIGALRM upon\n\
1162               expiration\n\
1163ITIMER_VIRTUAL -- decrements only when the process is executing,\n\
1164               and delivers SIGVTALRM upon expiration\n\
1165ITIMER_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\
1173A signal handler function is called with two arguments:\n\
1174the first is the signal number, the second is the interrupted stack frame.");
1175
1176static 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
1188PyMODINIT_FUNC
1189PyInit__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
1465static void
1466finisignal(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 */
1491int
1492PyErr_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 */
1549void
1550PyErr_SetInterrupt(void)
1551{
1552    trip_signal(SIGINT);
1553}
1554
1555void
1556PyOS_InitInterrupts(void)
1557{
1558    PyObject *m = PyImport_ImportModule("_signal");
1559    if (m) {
1560        Py_DECREF(m);
1561    }
1562}
1563
1564void
1565PyOS_FiniInterrupts(void)
1566{
1567    finisignal();
1568}
1569
1570int
1571PyOS_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
1584static 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
1596void
1597PyOS_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
1615int
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
1626void *_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