LCOV - code coverage report
Current view: top level - libreoffice/workdir/unxlngi6.pro/UnpackedTarball/python3/Modules - signalmodule.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 163 490 33.3 %
Date: 2012-12-17 Functions: 3 34 8.8 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10