LCOV - code coverage report
Current view: top level - Modules - signalmodule.c (source / functions) Hit Total Coverage
Test: CPython lcov report Lines: 174 335 51.9 %
Date: 2017-04-19 Functions: 5 25 20.0 %

          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 "intrcheck.h"
       8             : 
       9             : #ifdef MS_WINDOWS
      10             : #include <Windows.h>
      11             : #ifdef HAVE_PROCESS_H
      12             : #include <process.h>
      13             : #endif
      14             : #endif
      15             : 
      16             : #ifdef HAVE_SIGNAL_H
      17             : #include <signal.h>
      18             : #endif
      19             : #ifdef HAVE_SYS_STAT_H
      20             : #include <sys/stat.h>
      21             : #endif
      22             : #ifdef HAVE_SYS_TIME_H
      23             : #include <sys/time.h>
      24             : #endif
      25             : 
      26             : #ifndef SIG_ERR
      27             : #define SIG_ERR ((PyOS_sighandler_t)(-1))
      28             : #endif
      29             : 
      30             : #if defined(PYOS_OS2) && !defined(PYCC_GCC)
      31             : #define NSIG 12
      32             : #include <process.h>
      33             : #endif
      34             : 
      35             : #ifndef NSIG
      36             : # if defined(_NSIG)
      37             : #  define NSIG _NSIG            /* For BSD/SysV */
      38             : # elif defined(_SIGMAX)
      39             : #  define NSIG (_SIGMAX + 1)    /* For QNX */
      40             : # elif defined(SIGMAX)
      41             : #  define NSIG (SIGMAX + 1)     /* For djgpp */
      42             : # else
      43             : #  define NSIG 64               /* Use a reasonable default value */
      44             : # endif
      45             : #endif
      46             : 
      47             : 
      48             : /*
      49             :    NOTES ON THE INTERACTION BETWEEN SIGNALS AND THREADS
      50             : 
      51             :    When threads are supported, we want the following semantics:
      52             : 
      53             :    - only the main thread can set a signal handler
      54             :    - any thread can get a signal handler
      55             :    - signals are only delivered to the main thread
      56             : 
      57             :    I.e. we don't support "synchronous signals" like SIGFPE (catching
      58             :    this doesn't make much sense in Python anyway) nor do we support
      59             :    signals as a means of inter-thread communication, since not all
      60             :    thread implementations support that (at least our thread library
      61             :    doesn't).
      62             : 
      63             :    We still have the problem that in some implementations signals
      64             :    generated by the keyboard (e.g. SIGINT) are delivered to all
      65             :    threads (e.g. SGI), while in others (e.g. Solaris) such signals are
      66             :    delivered to one random thread (an intermediate possibility would
      67             :    be to deliver it to the main thread -- POSIX?).  For now, we have
      68             :    a working implementation that works in all three cases -- the
      69             :    handler ignores signals if getpid() isn't the same as in the main
      70             :    thread.  XXX This is a hack.
      71             : 
      72             :    GNU pth is a user-space threading library, and as such, all threads
      73             :    run within the same process. In this case, if the currently running
      74             :    thread is not the main_thread, send the signal to the main_thread.
      75             : */
      76             : 
      77             : #ifdef WITH_THREAD
      78             : #include <sys/types.h> /* For pid_t */
      79             : #include "pythread.h"
      80             : static long main_thread;
      81             : static pid_t main_pid;
      82             : #endif
      83             : 
      84             : static struct {
      85             :     int tripped;
      86             :     PyObject *func;
      87             : } Handlers[NSIG];
      88             : 
      89             : static sig_atomic_t wakeup_fd = -1;
      90             : 
      91             : /* Speed up sigcheck() when none tripped */
      92             : static volatile sig_atomic_t is_tripped = 0;
      93             : 
      94             : static PyObject *DefaultHandler;
      95             : static PyObject *IgnoreHandler;
      96             : static PyObject *IntHandler;
      97             : 
      98             : /* On Solaris 8, gcc will produce a warning that the function
      99             :    declaration is not a prototype. This is caused by the definition of
     100             :    SIG_DFL as (void (*)())0; the correct declaration would have been
     101             :    (void (*)(int))0. */
     102             : 
     103             : static PyOS_sighandler_t old_siginthandler = SIG_DFL;
     104             : 
     105             : #ifdef HAVE_GETITIMER
     106             : static PyObject *ItimerError;
     107             : 
     108             : /* auxiliary functions for setitimer/getitimer */
     109             : static void
     110           0 : timeval_from_double(double d, struct timeval *tv)
     111             : {
     112           0 :     tv->tv_sec = floor(d);
     113           0 :     tv->tv_usec = fmod(d, 1.0) * 1000000.0;
     114           0 : }
     115             : 
     116             : Py_LOCAL_INLINE(double)
     117           0 : double_from_timeval(struct timeval *tv)
     118             : {
     119           0 :     return tv->tv_sec + (double)(tv->tv_usec / 1000000.0);
     120             : }
     121             : 
     122             : static PyObject *
     123           0 : itimer_retval(struct itimerval *iv)
     124             : {
     125             :     PyObject *r, *v;
     126             : 
     127           0 :     r = PyTuple_New(2);
     128           0 :     if (r == NULL)
     129           0 :         return NULL;
     130             : 
     131           0 :     if(!(v = PyFloat_FromDouble(double_from_timeval(&iv->it_value)))) {
     132           0 :         Py_DECREF(r);
     133           0 :         return NULL;
     134             :     }
     135             : 
     136           0 :     PyTuple_SET_ITEM(r, 0, v);
     137             : 
     138           0 :     if(!(v = PyFloat_FromDouble(double_from_timeval(&iv->it_interval)))) {
     139           0 :         Py_DECREF(r);
     140           0 :         return NULL;
     141             :     }
     142             : 
     143           0 :     PyTuple_SET_ITEM(r, 1, v);
     144             : 
     145           0 :     return r;
     146             : }
     147             : #endif
     148             : 
     149             : static PyObject *
     150           0 : signal_default_int_handler(PyObject *self, PyObject *args)
     151             : {
     152           0 :     PyErr_SetNone(PyExc_KeyboardInterrupt);
     153           0 :     return NULL;
     154             : }
     155             : 
     156             : PyDoc_STRVAR(default_int_handler_doc,
     157             : "default_int_handler(...)\n\
     158             : \n\
     159             : The default handler for SIGINT installed by Python.\n\
     160             : It raises KeyboardInterrupt.");
     161             : 
     162             : 
     163             : static int
     164           0 : checksignals_witharg(void * unused)
     165             : {
     166           0 :     return PyErr_CheckSignals();
     167             : }
     168             : 
     169             : static void
     170           0 : trip_signal(int sig_num)
     171             : {
     172           0 :     Handlers[sig_num].tripped = 1;
     173           0 :     if (is_tripped)
     174           0 :         return;
     175             :     /* Set is_tripped after setting .tripped, as it gets
     176             :        cleared in PyErr_CheckSignals() before .tripped. */
     177           0 :     is_tripped = 1;
     178           0 :     Py_AddPendingCall(checksignals_witharg, NULL);
     179           0 :     if (wakeup_fd != -1)
     180           0 :         write(wakeup_fd, "\0", 1);
     181             : }
     182             : 
     183             : static void
     184           0 : signal_handler(int sig_num)
     185             : {
     186           0 :     int save_errno = errno;
     187             : 
     188             : #if defined(WITH_THREAD) && defined(WITH_PTH)
     189             :     if (PyThread_get_thread_ident() != main_thread) {
     190             :         pth_raise(*(pth_t *) main_thread, sig_num);
     191             :     }
     192             :     else
     193             : #endif
     194             :     {
     195             : #ifdef WITH_THREAD
     196             :     /* See NOTES section above */
     197             :     if (getpid() == main_pid)
     198             : #endif
     199             :     {
     200           0 :         trip_signal(sig_num);
     201             :     }
     202             : 
     203             : #ifndef HAVE_SIGACTION
     204             : #ifdef SIGCHLD
     205             :     /* To avoid infinite recursion, this signal remains
     206             :        reset until explicit re-instated.
     207             :        Don't clear the 'func' field as it is our pointer
     208             :        to the Python handler... */
     209             :     if (sig_num != SIGCHLD)
     210             : #endif
     211             :     /* If the handler was not set up with sigaction, reinstall it.  See
     212             :      * Python/pythonrun.c for the implementation of PyOS_setsig which
     213             :      * makes this true.  See also issue8354. */
     214             :     PyOS_setsig(sig_num, signal_handler);
     215             : #endif
     216             :     }
     217             : 
     218             :     /* Issue #10311: asynchronously executing signal handlers should not
     219             :        mutate errno under the feet of unsuspecting C code. */
     220           0 :     errno = save_errno;
     221           0 : }
     222             : 
     223             : 
     224             : #ifdef HAVE_ALARM
     225             : static PyObject *
     226           0 : signal_alarm(PyObject *self, PyObject *args)
     227             : {
     228             :     int t;
     229           0 :     if (!PyArg_ParseTuple(args, "i:alarm", &t))
     230           0 :         return NULL;
     231             :     /* alarm() returns the number of seconds remaining */
     232           0 :     return PyInt_FromLong((long)alarm(t));
     233             : }
     234             : 
     235             : PyDoc_STRVAR(alarm_doc,
     236             : "alarm(seconds)\n\
     237             : \n\
     238             : Arrange for SIGALRM to arrive after the given number of seconds.");
     239             : #endif
     240             : 
     241             : #ifdef HAVE_PAUSE
     242             : static PyObject *
     243           0 : signal_pause(PyObject *self)
     244             : {
     245             :     Py_BEGIN_ALLOW_THREADS
     246           0 :     (void)pause();
     247             :     Py_END_ALLOW_THREADS
     248             :     /* make sure that any exceptions that got raised are propagated
     249             :      * back into Python
     250             :      */
     251           0 :     if (PyErr_CheckSignals())
     252           0 :         return NULL;
     253             : 
     254           0 :     Py_INCREF(Py_None);
     255           0 :     return Py_None;
     256             : }
     257             : PyDoc_STRVAR(pause_doc,
     258             : "pause()\n\
     259             : \n\
     260             : Wait until a signal arrives.");
     261             : 
     262             : #endif
     263             : 
     264             : 
     265             : static PyObject *
     266           0 : signal_signal(PyObject *self, PyObject *args)
     267             : {
     268             :     PyObject *obj;
     269             :     int sig_num;
     270             :     PyObject *old_handler;
     271             :     void (*func)(int);
     272           0 :     if (!PyArg_ParseTuple(args, "iO:signal", &sig_num, &obj))
     273           0 :         return NULL;
     274             : #ifdef MS_WINDOWS
     275             :     /* Validate that sig_num is one of the allowable signals */
     276             :     switch (sig_num) {
     277             :         case SIGABRT: break;
     278             : #ifdef SIGBREAK
     279             :         /* Issue #10003: SIGBREAK is not documented as permitted, but works
     280             :            and corresponds to CTRL_BREAK_EVENT. */
     281             :         case SIGBREAK: break;
     282             : #endif
     283             :         case SIGFPE: break;
     284             :         case SIGILL: break;
     285             :         case SIGINT: break;
     286             :         case SIGSEGV: break;
     287             :         case SIGTERM: break;
     288             :         default:
     289             :             PyErr_SetString(PyExc_ValueError, "invalid signal value");
     290             :             return NULL;
     291             :     }
     292             : #endif
     293             : #ifdef WITH_THREAD
     294             :     if (PyThread_get_thread_ident() != main_thread) {
     295             :         PyErr_SetString(PyExc_ValueError,
     296             :                         "signal only works in main thread");
     297             :         return NULL;
     298             :     }
     299             : #endif
     300           0 :     if (sig_num < 1 || sig_num >= NSIG) {
     301           0 :         PyErr_SetString(PyExc_ValueError,
     302             :                         "signal number out of range");
     303           0 :         return NULL;
     304             :     }
     305           0 :     if (obj == IgnoreHandler)
     306           0 :         func = SIG_IGN;
     307           0 :     else if (obj == DefaultHandler)
     308           0 :         func = SIG_DFL;
     309           0 :     else if (!PyCallable_Check(obj)) {
     310           0 :         PyErr_SetString(PyExc_TypeError,
     311             : "signal handler must be signal.SIG_IGN, signal.SIG_DFL, or a callable object");
     312           0 :                 return NULL;
     313             :     }
     314             :     else
     315           0 :         func = signal_handler;
     316           0 :     if (PyOS_setsig(sig_num, func) == SIG_ERR) {
     317           0 :         PyErr_SetFromErrno(PyExc_RuntimeError);
     318           0 :         return NULL;
     319             :     }
     320           0 :     old_handler = Handlers[sig_num].func;
     321           0 :     Handlers[sig_num].tripped = 0;
     322           0 :     Py_INCREF(obj);
     323           0 :     Handlers[sig_num].func = obj;
     324           0 :     if (old_handler != NULL)
     325           0 :         return old_handler;
     326             :     else
     327           0 :         Py_RETURN_NONE;
     328             : }
     329             : 
     330             : PyDoc_STRVAR(signal_doc,
     331             : "signal(sig, action) -> action\n\
     332             : \n\
     333             : Set the action for the given signal.  The action can be SIG_DFL,\n\
     334             : SIG_IGN, or a callable Python object.  The previous action is\n\
     335             : returned.  See getsignal() for possible return values.\n\
     336             : \n\
     337             : *** IMPORTANT NOTICE ***\n\
     338             : A signal handler function is called with two arguments:\n\
     339             : the first is the signal number, the second is the interrupted stack frame.");
     340             : 
     341             : 
     342             : static PyObject *
     343           0 : signal_getsignal(PyObject *self, PyObject *args)
     344             : {
     345             :     int sig_num;
     346             :     PyObject *old_handler;
     347           0 :     if (!PyArg_ParseTuple(args, "i:getsignal", &sig_num))
     348           0 :         return NULL;
     349           0 :     if (sig_num < 1 || sig_num >= NSIG) {
     350           0 :         PyErr_SetString(PyExc_ValueError,
     351             :                         "signal number out of range");
     352           0 :         return NULL;
     353             :     }
     354           0 :     old_handler = Handlers[sig_num].func;
     355           0 :     if (old_handler != NULL) {
     356           0 :         Py_INCREF(old_handler);
     357           0 :         return old_handler;
     358             :     }
     359             :     else {
     360           0 :         Py_RETURN_NONE;
     361             :     }
     362             : }
     363             : 
     364             : PyDoc_STRVAR(getsignal_doc,
     365             : "getsignal(sig) -> action\n\
     366             : \n\
     367             : Return the current action for the given signal.  The return value can be:\n\
     368             : SIG_IGN -- if the signal is being ignored\n\
     369             : SIG_DFL -- if the default action for the signal is in effect\n\
     370             : None -- if an unknown handler is in effect\n\
     371             : anything else -- the callable Python object used as a handler");
     372             : 
     373             : #ifdef HAVE_SIGINTERRUPT
     374             : PyDoc_STRVAR(siginterrupt_doc,
     375             : "siginterrupt(sig, flag) -> None\n\
     376             : change system call restart behaviour: if flag is False, system calls\n\
     377             : will be restarted when interrupted by signal sig, else system calls\n\
     378             : will be interrupted.");
     379             : 
     380             : static PyObject *
     381           0 : signal_siginterrupt(PyObject *self, PyObject *args)
     382             : {
     383             :     int sig_num;
     384             :     int flag;
     385             : 
     386           0 :     if (!PyArg_ParseTuple(args, "ii:siginterrupt", &sig_num, &flag))
     387           0 :         return NULL;
     388           0 :     if (sig_num < 1 || sig_num >= NSIG) {
     389           0 :         PyErr_SetString(PyExc_ValueError,
     390             :                         "signal number out of range");
     391           0 :         return NULL;
     392             :     }
     393           0 :     if (siginterrupt(sig_num, flag)<0) {
     394           0 :         PyErr_SetFromErrno(PyExc_RuntimeError);
     395           0 :         return NULL;
     396             :     }
     397             : 
     398           0 :     Py_INCREF(Py_None);
     399           0 :     return Py_None;
     400             : }
     401             : 
     402             : #endif
     403             : 
     404             : static PyObject *
     405           0 : signal_set_wakeup_fd(PyObject *self, PyObject *args)
     406             : {
     407             :     struct stat buf;
     408             :     int fd, old_fd;
     409           0 :     if (!PyArg_ParseTuple(args, "i:set_wakeup_fd", &fd))
     410           0 :         return NULL;
     411             : #ifdef WITH_THREAD
     412             :     if (PyThread_get_thread_ident() != main_thread) {
     413             :         PyErr_SetString(PyExc_ValueError,
     414             :                         "set_wakeup_fd only works in main thread");
     415             :         return NULL;
     416             :     }
     417             : #endif
     418           0 :     if (fd != -1 && (!_PyVerify_fd(fd) || fstat(fd, &buf) != 0)) {
     419           0 :         PyErr_SetString(PyExc_ValueError, "invalid fd");
     420           0 :         return NULL;
     421             :     }
     422           0 :     old_fd = wakeup_fd;
     423           0 :     wakeup_fd = fd;
     424           0 :     return PyLong_FromLong(old_fd);
     425             : }
     426             : 
     427             : PyDoc_STRVAR(set_wakeup_fd_doc,
     428             : "set_wakeup_fd(fd) -> fd\n\
     429             : \n\
     430             : Sets the fd to be written to (with '\\0') when a signal\n\
     431             : comes in.  A library can use this to wakeup select or poll.\n\
     432             : The previous fd is returned.\n\
     433             : \n\
     434             : The fd must be non-blocking.");
     435             : 
     436             : /* C API for the same, without all the error checking */
     437             : int
     438           0 : PySignal_SetWakeupFd(int fd)
     439             : {
     440           0 :     int old_fd = wakeup_fd;
     441           0 :     if (fd < 0)
     442           0 :         fd = -1;
     443           0 :     wakeup_fd = fd;
     444           0 :     return old_fd;
     445             : }
     446             : 
     447             : 
     448             : #ifdef HAVE_SETITIMER
     449             : static PyObject *
     450           0 : signal_setitimer(PyObject *self, PyObject *args)
     451             : {
     452             :     double first;
     453           0 :     double interval = 0;
     454             :     int which;
     455             :     struct itimerval new, old;
     456             : 
     457           0 :     if(!PyArg_ParseTuple(args, "id|d:setitimer", &which, &first, &interval))
     458           0 :         return NULL;
     459             : 
     460           0 :     timeval_from_double(first, &new.it_value);
     461           0 :     timeval_from_double(interval, &new.it_interval);
     462             :     /* Let OS check "which" value */
     463           0 :     if (setitimer(which, &new, &old) != 0) {
     464           0 :         PyErr_SetFromErrno(ItimerError);
     465           0 :         return NULL;
     466             :     }
     467             : 
     468           0 :     return itimer_retval(&old);
     469             : }
     470             : 
     471             : PyDoc_STRVAR(setitimer_doc,
     472             : "setitimer(which, seconds[, interval])\n\
     473             : \n\
     474             : Sets given itimer (one of ITIMER_REAL, ITIMER_VIRTUAL\n\
     475             : or ITIMER_PROF) to fire after value seconds and after\n\
     476             : that every interval seconds.\n\
     477             : The itimer can be cleared by setting seconds to zero.\n\
     478             : \n\
     479             : Returns old values as a tuple: (delay, interval).");
     480             : #endif
     481             : 
     482             : 
     483             : #ifdef HAVE_GETITIMER
     484             : static PyObject *
     485           0 : signal_getitimer(PyObject *self, PyObject *args)
     486             : {
     487             :     int which;
     488             :     struct itimerval old;
     489             : 
     490           0 :     if (!PyArg_ParseTuple(args, "i:getitimer", &which))
     491           0 :         return NULL;
     492             : 
     493           0 :     if (getitimer(which, &old) != 0) {
     494           0 :         PyErr_SetFromErrno(ItimerError);
     495           0 :         return NULL;
     496             :     }
     497             : 
     498           0 :     return itimer_retval(&old);
     499             : }
     500             : 
     501             : PyDoc_STRVAR(getitimer_doc,
     502             : "getitimer(which)\n\
     503             : \n\
     504             : Returns current value of given itimer.");
     505             : #endif
     506             : 
     507             : 
     508             : /* List of functions defined in the module */
     509             : static PyMethodDef signal_methods[] = {
     510             : #ifdef HAVE_ALARM
     511             :     {"alarm",                   signal_alarm, METH_VARARGS, alarm_doc},
     512             : #endif
     513             : #ifdef HAVE_SETITIMER
     514             :     {"setitimer",       signal_setitimer, METH_VARARGS, setitimer_doc},
     515             : #endif
     516             : #ifdef HAVE_GETITIMER
     517             :     {"getitimer",       signal_getitimer, METH_VARARGS, getitimer_doc},
     518             : #endif
     519             :     {"signal",                  signal_signal, METH_VARARGS, signal_doc},
     520             :     {"getsignal",               signal_getsignal, METH_VARARGS, getsignal_doc},
     521             :     {"set_wakeup_fd",           signal_set_wakeup_fd, METH_VARARGS, set_wakeup_fd_doc},
     522             : #ifdef HAVE_SIGINTERRUPT
     523             :     {"siginterrupt",            signal_siginterrupt, METH_VARARGS, siginterrupt_doc},
     524             : #endif
     525             : #ifdef HAVE_PAUSE
     526             :     {"pause",                   (PyCFunction)signal_pause,
     527             :      METH_NOARGS,pause_doc},
     528             : #endif
     529             :     {"default_int_handler", signal_default_int_handler,
     530             :      METH_VARARGS, default_int_handler_doc},
     531             :     {NULL,                      NULL}           /* sentinel */
     532             : };
     533             : 
     534             : 
     535             : PyDoc_STRVAR(module_doc,
     536             : "This module provides mechanisms to use signal handlers in Python.\n\
     537             : \n\
     538             : Functions:\n\
     539             : \n\
     540             : alarm() -- cause SIGALRM after a specified time [Unix only]\n\
     541             : setitimer() -- cause a signal (described below) after a specified\n\
     542             :                float time and the timer may restart then [Unix only]\n\
     543             : getitimer() -- get current value of timer [Unix only]\n\
     544             : signal() -- set the action for a given signal\n\
     545             : getsignal() -- get the signal action for a given signal\n\
     546             : pause() -- wait until a signal arrives [Unix only]\n\
     547             : default_int_handler() -- default SIGINT handler\n\
     548             : \n\
     549             : signal constants:\n\
     550             : SIG_DFL -- used to refer to the system default handler\n\
     551             : SIG_IGN -- used to ignore the signal\n\
     552             : NSIG -- number of defined signals\n\
     553             : SIGINT, SIGTERM, etc. -- signal numbers\n\
     554             : \n\
     555             : itimer constants:\n\
     556             : ITIMER_REAL -- decrements in real time, and delivers SIGALRM upon\n\
     557             :                expiration\n\
     558             : ITIMER_VIRTUAL -- decrements only when the process is executing,\n\
     559             :                and delivers SIGVTALRM upon expiration\n\
     560             : ITIMER_PROF -- decrements both when the process is executing and\n\
     561             :                when the system is executing on behalf of the process.\n\
     562             :                Coupled with ITIMER_VIRTUAL, this timer is usually\n\
     563             :                used to profile the time spent by the application\n\
     564             :                in user and kernel space. SIGPROF is delivered upon\n\
     565             :                expiration.\n\
     566             : \n\n\
     567             : *** IMPORTANT NOTICE ***\n\
     568             : A signal handler function is called with two arguments:\n\
     569             : the first is the signal number, the second is the interrupted stack frame.");
     570             : 
     571             : PyMODINIT_FUNC
     572           3 : initsignal(void)
     573             : {
     574             :     PyObject *m, *d, *x;
     575             :     int i;
     576             : 
     577             : #ifdef WITH_THREAD
     578             :     main_thread = PyThread_get_thread_ident();
     579             :     main_pid = getpid();
     580             : #endif
     581             : 
     582             :     /* Create the module and add the functions */
     583           3 :     m = Py_InitModule3("signal", signal_methods, module_doc);
     584           3 :     if (m == NULL)
     585           0 :         return;
     586             : 
     587             :     /* Add some symbolic constants to the module */
     588           3 :     d = PyModule_GetDict(m);
     589             : 
     590           3 :     x = DefaultHandler = PyLong_FromVoidPtr((void *)SIG_DFL);
     591           3 :     if (!x || PyDict_SetItemString(d, "SIG_DFL", x) < 0)
     592             :         goto finally;
     593             : 
     594           3 :     x = IgnoreHandler = PyLong_FromVoidPtr((void *)SIG_IGN);
     595           3 :     if (!x || PyDict_SetItemString(d, "SIG_IGN", x) < 0)
     596             :         goto finally;
     597             : 
     598           3 :     x = PyInt_FromLong((long)NSIG);
     599           3 :     if (!x || PyDict_SetItemString(d, "NSIG", x) < 0)
     600             :         goto finally;
     601           3 :     Py_DECREF(x);
     602             : 
     603           3 :     x = IntHandler = PyDict_GetItemString(d, "default_int_handler");
     604           3 :     if (!x)
     605           0 :         goto finally;
     606           3 :     Py_INCREF(IntHandler);
     607             : 
     608           3 :     Handlers[0].tripped = 0;
     609         195 :     for (i = 1; i < NSIG; i++) {
     610             :         void (*t)(int);
     611         192 :         t = PyOS_getsig(i);
     612         192 :         Handlers[i].tripped = 0;
     613         192 :         if (t == SIG_DFL)
     614         180 :             Handlers[i].func = DefaultHandler;
     615          12 :         else if (t == SIG_IGN)
     616           6 :             Handlers[i].func = IgnoreHandler;
     617             :         else
     618           6 :             Handlers[i].func = Py_None; /* None of our business */
     619         192 :         Py_INCREF(Handlers[i].func);
     620             :     }
     621           3 :     if (Handlers[SIGINT].func == DefaultHandler) {
     622             :         /* Install default int handler */
     623           3 :         Py_INCREF(IntHandler);
     624           3 :         Py_SETREF(Handlers[SIGINT].func, IntHandler);
     625           3 :         old_siginthandler = PyOS_setsig(SIGINT, signal_handler);
     626             :     }
     627             : 
     628             : #ifdef SIGHUP
     629           3 :     x = PyInt_FromLong(SIGHUP);
     630           3 :     PyDict_SetItemString(d, "SIGHUP", x);
     631           3 :     Py_XDECREF(x);
     632             : #endif
     633             : #ifdef SIGINT
     634           3 :     x = PyInt_FromLong(SIGINT);
     635           3 :     PyDict_SetItemString(d, "SIGINT", x);
     636           3 :     Py_XDECREF(x);
     637             : #endif
     638             : #ifdef SIGBREAK
     639             :     x = PyInt_FromLong(SIGBREAK);
     640             :     PyDict_SetItemString(d, "SIGBREAK", x);
     641             :     Py_XDECREF(x);
     642             : #endif
     643             : #ifdef SIGQUIT
     644           3 :     x = PyInt_FromLong(SIGQUIT);
     645           3 :     PyDict_SetItemString(d, "SIGQUIT", x);
     646           3 :     Py_XDECREF(x);
     647             : #endif
     648             : #ifdef SIGILL
     649           3 :     x = PyInt_FromLong(SIGILL);
     650           3 :     PyDict_SetItemString(d, "SIGILL", x);
     651           3 :     Py_XDECREF(x);
     652             : #endif
     653             : #ifdef SIGTRAP
     654           3 :     x = PyInt_FromLong(SIGTRAP);
     655           3 :     PyDict_SetItemString(d, "SIGTRAP", x);
     656           3 :     Py_XDECREF(x);
     657             : #endif
     658             : #ifdef SIGIOT
     659           3 :     x = PyInt_FromLong(SIGIOT);
     660           3 :     PyDict_SetItemString(d, "SIGIOT", x);
     661           3 :     Py_XDECREF(x);
     662             : #endif
     663             : #ifdef SIGABRT
     664           3 :     x = PyInt_FromLong(SIGABRT);
     665           3 :     PyDict_SetItemString(d, "SIGABRT", x);
     666           3 :     Py_XDECREF(x);
     667             : #endif
     668             : #ifdef SIGEMT
     669             :     x = PyInt_FromLong(SIGEMT);
     670             :     PyDict_SetItemString(d, "SIGEMT", x);
     671             :     Py_XDECREF(x);
     672             : #endif
     673             : #ifdef SIGFPE
     674           3 :     x = PyInt_FromLong(SIGFPE);
     675           3 :     PyDict_SetItemString(d, "SIGFPE", x);
     676           3 :     Py_XDECREF(x);
     677             : #endif
     678             : #ifdef SIGKILL
     679           3 :     x = PyInt_FromLong(SIGKILL);
     680           3 :     PyDict_SetItemString(d, "SIGKILL", x);
     681           3 :     Py_XDECREF(x);
     682             : #endif
     683             : #ifdef SIGBUS
     684           3 :     x = PyInt_FromLong(SIGBUS);
     685           3 :     PyDict_SetItemString(d, "SIGBUS", x);
     686           3 :     Py_XDECREF(x);
     687             : #endif
     688             : #ifdef SIGSEGV
     689           3 :     x = PyInt_FromLong(SIGSEGV);
     690           3 :     PyDict_SetItemString(d, "SIGSEGV", x);
     691           3 :     Py_XDECREF(x);
     692             : #endif
     693             : #ifdef SIGSYS
     694           3 :     x = PyInt_FromLong(SIGSYS);
     695           3 :     PyDict_SetItemString(d, "SIGSYS", x);
     696           3 :     Py_XDECREF(x);
     697             : #endif
     698             : #ifdef SIGPIPE
     699           3 :     x = PyInt_FromLong(SIGPIPE);
     700           3 :     PyDict_SetItemString(d, "SIGPIPE", x);
     701           3 :     Py_XDECREF(x);
     702             : #endif
     703             : #ifdef SIGALRM
     704           3 :     x = PyInt_FromLong(SIGALRM);
     705           3 :     PyDict_SetItemString(d, "SIGALRM", x);
     706           3 :     Py_XDECREF(x);
     707             : #endif
     708             : #ifdef SIGTERM
     709           3 :     x = PyInt_FromLong(SIGTERM);
     710           3 :     PyDict_SetItemString(d, "SIGTERM", x);
     711           3 :     Py_XDECREF(x);
     712             : #endif
     713             : #ifdef SIGUSR1
     714           3 :     x = PyInt_FromLong(SIGUSR1);
     715           3 :     PyDict_SetItemString(d, "SIGUSR1", x);
     716           3 :     Py_XDECREF(x);
     717             : #endif
     718             : #ifdef SIGUSR2
     719           3 :     x = PyInt_FromLong(SIGUSR2);
     720           3 :     PyDict_SetItemString(d, "SIGUSR2", x);
     721           3 :     Py_XDECREF(x);
     722             : #endif
     723             : #ifdef SIGCLD
     724           3 :     x = PyInt_FromLong(SIGCLD);
     725           3 :     PyDict_SetItemString(d, "SIGCLD", x);
     726           3 :     Py_XDECREF(x);
     727             : #endif
     728             : #ifdef SIGCHLD
     729           3 :     x = PyInt_FromLong(SIGCHLD);
     730           3 :     PyDict_SetItemString(d, "SIGCHLD", x);
     731           3 :     Py_XDECREF(x);
     732             : #endif
     733             : #ifdef SIGPWR
     734           3 :     x = PyInt_FromLong(SIGPWR);
     735           3 :     PyDict_SetItemString(d, "SIGPWR", x);
     736           3 :     Py_XDECREF(x);
     737             : #endif
     738             : #ifdef SIGIO
     739           3 :     x = PyInt_FromLong(SIGIO);
     740           3 :     PyDict_SetItemString(d, "SIGIO", x);
     741           3 :     Py_XDECREF(x);
     742             : #endif
     743             : #ifdef SIGURG
     744           3 :     x = PyInt_FromLong(SIGURG);
     745           3 :     PyDict_SetItemString(d, "SIGURG", x);
     746           3 :     Py_XDECREF(x);
     747             : #endif
     748             : #ifdef SIGWINCH
     749           3 :     x = PyInt_FromLong(SIGWINCH);
     750           3 :     PyDict_SetItemString(d, "SIGWINCH", x);
     751           3 :     Py_XDECREF(x);
     752             : #endif
     753             : #ifdef SIGPOLL
     754           3 :     x = PyInt_FromLong(SIGPOLL);
     755           3 :     PyDict_SetItemString(d, "SIGPOLL", x);
     756           3 :     Py_XDECREF(x);
     757             : #endif
     758             : #ifdef SIGSTOP
     759           3 :     x = PyInt_FromLong(SIGSTOP);
     760           3 :     PyDict_SetItemString(d, "SIGSTOP", x);
     761           3 :     Py_XDECREF(x);
     762             : #endif
     763             : #ifdef SIGTSTP
     764           3 :     x = PyInt_FromLong(SIGTSTP);
     765           3 :     PyDict_SetItemString(d, "SIGTSTP", x);
     766           3 :     Py_XDECREF(x);
     767             : #endif
     768             : #ifdef SIGCONT
     769           3 :     x = PyInt_FromLong(SIGCONT);
     770           3 :     PyDict_SetItemString(d, "SIGCONT", x);
     771           3 :     Py_XDECREF(x);
     772             : #endif
     773             : #ifdef SIGTTIN
     774           3 :     x = PyInt_FromLong(SIGTTIN);
     775           3 :     PyDict_SetItemString(d, "SIGTTIN", x);
     776           3 :     Py_XDECREF(x);
     777             : #endif
     778             : #ifdef SIGTTOU
     779           3 :     x = PyInt_FromLong(SIGTTOU);
     780           3 :     PyDict_SetItemString(d, "SIGTTOU", x);
     781           3 :     Py_XDECREF(x);
     782             : #endif
     783             : #ifdef SIGVTALRM
     784           3 :     x = PyInt_FromLong(SIGVTALRM);
     785           3 :     PyDict_SetItemString(d, "SIGVTALRM", x);
     786           3 :     Py_XDECREF(x);
     787             : #endif
     788             : #ifdef SIGPROF
     789           3 :     x = PyInt_FromLong(SIGPROF);
     790           3 :     PyDict_SetItemString(d, "SIGPROF", x);
     791           3 :     Py_XDECREF(x);
     792             : #endif
     793             : #ifdef SIGXCPU
     794           3 :     x = PyInt_FromLong(SIGXCPU);
     795           3 :     PyDict_SetItemString(d, "SIGXCPU", x);
     796           3 :     Py_XDECREF(x);
     797             : #endif
     798             : #ifdef SIGXFSZ
     799           3 :     x = PyInt_FromLong(SIGXFSZ);
     800           3 :     PyDict_SetItemString(d, "SIGXFSZ", x);
     801           3 :     Py_XDECREF(x);
     802             : #endif
     803             : #ifdef SIGRTMIN
     804           3 :     x = PyInt_FromLong(SIGRTMIN);
     805           3 :     PyDict_SetItemString(d, "SIGRTMIN", x);
     806           3 :     Py_XDECREF(x);
     807             : #endif
     808             : #ifdef SIGRTMAX
     809           3 :     x = PyInt_FromLong(SIGRTMAX);
     810           3 :     PyDict_SetItemString(d, "SIGRTMAX", x);
     811           3 :     Py_XDECREF(x);
     812             : #endif
     813             : #ifdef SIGINFO
     814             :     x = PyInt_FromLong(SIGINFO);
     815             :     PyDict_SetItemString(d, "SIGINFO", x);
     816             :     Py_XDECREF(x);
     817             : #endif
     818             : 
     819             : #ifdef ITIMER_REAL
     820           3 :     x = PyLong_FromLong(ITIMER_REAL);
     821           3 :     PyDict_SetItemString(d, "ITIMER_REAL", x);
     822           3 :     Py_DECREF(x);
     823             : #endif
     824             : #ifdef ITIMER_VIRTUAL
     825           3 :     x = PyLong_FromLong(ITIMER_VIRTUAL);
     826           3 :     PyDict_SetItemString(d, "ITIMER_VIRTUAL", x);
     827           3 :     Py_DECREF(x);
     828             : #endif
     829             : #ifdef ITIMER_PROF
     830           3 :     x = PyLong_FromLong(ITIMER_PROF);
     831           3 :     PyDict_SetItemString(d, "ITIMER_PROF", x);
     832           3 :     Py_DECREF(x);
     833             : #endif
     834             : 
     835             : #if defined (HAVE_SETITIMER) || defined (HAVE_GETITIMER)
     836           3 :     ItimerError = PyErr_NewException("signal.ItimerError",
     837             :             PyExc_IOError, NULL);
     838           3 :     if (ItimerError != NULL)
     839           3 :         PyDict_SetItemString(d, "ItimerError", ItimerError);
     840             : #endif
     841             : 
     842             : #ifdef CTRL_C_EVENT
     843             :     x = PyInt_FromLong(CTRL_C_EVENT);
     844             :     PyDict_SetItemString(d, "CTRL_C_EVENT", x);
     845             :     Py_DECREF(x);
     846             : #endif
     847             : 
     848             : #ifdef CTRL_BREAK_EVENT
     849             :     x = PyInt_FromLong(CTRL_BREAK_EVENT);
     850             :     PyDict_SetItemString(d, "CTRL_BREAK_EVENT", x);
     851             :     Py_DECREF(x);
     852             : #endif
     853             : 
     854           3 :     if (!PyErr_Occurred())
     855           3 :         return;
     856             : 
     857             :     /* Check for errors */
     858             :   finally:
     859           0 :     return;
     860             : }
     861             : 
     862             : static void
     863           3 : finisignal(void)
     864             : {
     865             :     int i;
     866             :     PyObject *func;
     867             : 
     868           3 :     PyOS_setsig(SIGINT, old_siginthandler);
     869           3 :     old_siginthandler = SIG_DFL;
     870             : 
     871         195 :     for (i = 1; i < NSIG; i++) {
     872         192 :         func = Handlers[i].func;
     873         192 :         Handlers[i].tripped = 0;
     874         192 :         Handlers[i].func = NULL;
     875         375 :         if (i != SIGINT && func != NULL && func != Py_None &&
     876         189 :             func != DefaultHandler && func != IgnoreHandler)
     877           0 :             PyOS_setsig(i, SIG_DFL);
     878         192 :         Py_XDECREF(func);
     879             :     }
     880             : 
     881           3 :     Py_XDECREF(IntHandler);
     882           3 :     IntHandler = NULL;
     883           3 :     Py_XDECREF(DefaultHandler);
     884           3 :     DefaultHandler = NULL;
     885           3 :     Py_XDECREF(IgnoreHandler);
     886           3 :     IgnoreHandler = NULL;
     887           3 : }
     888             : 
     889             : 
     890             : /* Declared in pyerrors.h */
     891             : int
     892        1194 : PyErr_CheckSignals(void)
     893             : {
     894             :     int i;
     895             :     PyObject *f;
     896             : 
     897        1194 :     if (!is_tripped)
     898        1194 :         return 0;
     899             : 
     900             : #ifdef WITH_THREAD
     901             :     if (PyThread_get_thread_ident() != main_thread)
     902             :         return 0;
     903             : #endif
     904             : 
     905             :     /*
     906             :      * The is_tripped variable is meant to speed up the calls to
     907             :      * PyErr_CheckSignals (both directly or via pending calls) when no
     908             :      * signal has arrived. This variable is set to 1 when a signal arrives
     909             :      * and it is set to 0 here, when we know some signals arrived. This way
     910             :      * we can run the registered handlers with no signals blocked.
     911             :      *
     912             :      * NOTE: with this approach we can have a situation where is_tripped is
     913             :      *       1 but we have no more signals to handle (Handlers[i].tripped
     914             :      *       is 0 for every signal i). This won't do us any harm (except
     915             :      *       we're gonna spent some cycles for nothing). This happens when
     916             :      *       we receive a signal i after we zero is_tripped and before we
     917             :      *       check Handlers[i].tripped.
     918             :      */
     919           0 :     is_tripped = 0;
     920             : 
     921           0 :     if (!(f = (PyObject *)PyEval_GetFrame()))
     922           0 :         f = Py_None;
     923             : 
     924           0 :     for (i = 1; i < NSIG; i++) {
     925           0 :         if (Handlers[i].tripped) {
     926           0 :             PyObject *result = NULL;
     927           0 :             PyObject *arglist = Py_BuildValue("(iO)", i, f);
     928           0 :             Handlers[i].tripped = 0;
     929             : 
     930           0 :             if (arglist) {
     931           0 :                 result = PyEval_CallObject(Handlers[i].func,
     932             :                                            arglist);
     933           0 :                 Py_DECREF(arglist);
     934             :             }
     935           0 :             if (!result)
     936           0 :                 return -1;
     937             : 
     938           0 :             Py_DECREF(result);
     939             :         }
     940             :     }
     941             : 
     942           0 :     return 0;
     943             : }
     944             : 
     945             : 
     946             : /* Replacements for intrcheck.c functionality
     947             :  * Declared in pyerrors.h
     948             :  */
     949             : void
     950           0 : PyErr_SetInterrupt(void)
     951             : {
     952           0 :     trip_signal(SIGINT);
     953           0 : }
     954             : 
     955             : void
     956           3 : PyOS_InitInterrupts(void)
     957             : {
     958           3 :     initsignal();
     959           3 :     _PyImport_FixupExtension("signal", "signal");
     960           3 : }
     961             : 
     962             : void
     963           3 : PyOS_FiniInterrupts(void)
     964             : {
     965           3 :     finisignal();
     966           3 : }
     967             : 
     968             : int
     969           0 : PyOS_InterruptOccurred(void)
     970             : {
     971           0 :     if (Handlers[SIGINT].tripped) {
     972             : #ifdef WITH_THREAD
     973             :         if (PyThread_get_thread_ident() != main_thread)
     974             :             return 0;
     975             : #endif
     976           0 :         Handlers[SIGINT].tripped = 0;
     977           0 :         return 1;
     978             :     }
     979           0 :     return 0;
     980             : }
     981             : 
     982             : static void
     983           0 : _clear_pending_signals(void)
     984             : {
     985             :     int i;
     986           0 :     if (!is_tripped)
     987           0 :         return;
     988           0 :     is_tripped = 0;
     989           0 :     for (i = 1; i < NSIG; ++i) {
     990           0 :         Handlers[i].tripped = 0;
     991             :     }
     992             : }
     993             : 
     994             : void
     995           0 : PyOS_AfterFork(void)
     996             : {
     997             :     /* Clear the signal flags after forking so that they aren't handled
     998             :      * in both processes if they came in just before the fork() but before
     999             :      * the interpreter had an opportunity to call the handlers.  issue9535. */
    1000           0 :     _clear_pending_signals();
    1001             : #ifdef WITH_THREAD
    1002             :     /* PyThread_ReInitTLS() must be called early, to make sure that the TLS API
    1003             :      * can be called safely. */
    1004             :     PyThread_ReInitTLS();
    1005             :     PyEval_ReInitThreads();
    1006             :     main_thread = PyThread_get_thread_ident();
    1007             :     main_pid = getpid();
    1008             :     _PyImport_ReInitLock();
    1009             : #endif
    1010           0 : }

Generated by: LCOV version 1.10