LCOV - code coverage report
Current view: top level - Modules - signalmodule.c (source / functions) Hit Total Coverage
Test: CPython lcov report Lines: 439 527 83.3 %
Date: 2022-07-07 18:19:46 Functions: 48 53 90.6 %

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

Generated by: LCOV version 1.14