signalmodule.c 25 KB
Newer Older
1

2
/* Signal module -- many thanks to Lance Ellinghaus */
3

4 5
/* XXX Signals should be recorded per thread, now we have thread state. */

6
#include "Python.h"
7 8
#include "intrcheck.h"

9
#ifdef MS_WINDOWS
10
#include <Windows.h>
Benjamin Peterson's avatar
Benjamin Peterson committed
11
#ifdef HAVE_PROCESS_H
12 13
#include <process.h>
#endif
Benjamin Peterson's avatar
Benjamin Peterson committed
14
#endif
15

Benjamin Peterson's avatar
Benjamin Peterson committed
16
#ifdef HAVE_SIGNAL_H
17
#include <signal.h>
Benjamin Peterson's avatar
Benjamin Peterson committed
18 19
#endif
#ifdef HAVE_SYS_STAT_H
20
#include <sys/stat.h>
Benjamin Peterson's avatar
Benjamin Peterson committed
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 29
#endif

30
#if defined(PYOS_OS2) && !defined(PYCC_GCC)
31 32 33 34
#define NSIG 12
#include <process.h>
#endif

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 46 47
#endif


48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
/*
   NOTES ON THE INTERACTION BETWEEN SIGNALS AND THREADS

   When threads are supported, we want the following semantics:

   - only the main thread can set a signal handler
   - any thread can get a signal handler
   - signals are only delivered to the main thread

   I.e. we don't support "synchronous signals" like SIGFPE (catching
   this doesn't make much sense in Python anyway) nor do we support
   signals as a means of inter-thread communication, since not all
   thread implementations support that (at least our thread library
   doesn't).

   We still have the problem that in some implementations signals
   generated by the keyboard (e.g. SIGINT) are delivered to all
   threads (e.g. SGI), while in others (e.g. Solaris) such signals are
   delivered to one random thread (an intermediate possibility would
Guido van Rossum's avatar
Guido van Rossum committed
67
   be to deliver it to the main thread -- POSIX?).  For now, we have
68 69 70 71
   a working implementation that works in all three cases -- the
   handler ignores signals if getpid() isn't the same as in the main
   thread.  XXX This is a hack.

72 73 74
   GNU pth is a user-space threading library, and as such, all threads
   run within the same process. In this case, if the currently running
   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 81 82 83
static long main_thread;
static pid_t main_pid;
#endif

Barry Warsaw's avatar
Barry Warsaw committed
84
static struct {
85 86
    int tripped;
    PyObject *func;
Barry Warsaw's avatar
Barry Warsaw committed
87 88
} Handlers[NSIG];

89 90
static sig_atomic_t wakeup_fd = -1;

91 92
/* Speed up sigcheck() when none tripped */
static volatile sig_atomic_t is_tripped = 0;
93

Barry Warsaw's avatar
Barry Warsaw committed
94 95 96
static PyObject *DefaultHandler;
static PyObject *IgnoreHandler;
static PyObject *IntHandler;
97

98 99 100 101 102
/* On Solaris 8, gcc will produce a warning that the function
   declaration is not a prototype. This is caused by the definition of
   SIG_DFL as (void (*)())0; the correct declaration would have been
   (void (*)(int))0. */

103
static PyOS_sighandler_t old_siginthandler = SIG_DFL;
104

105 106 107 108 109 110 111 112 113 114 115
#ifdef HAVE_GETITIMER
static PyObject *ItimerError;

/* auxiliary functions for setitimer/getitimer */
static void
timeval_from_double(double d, struct timeval *tv)
{
    tv->tv_sec = floor(d);
    tv->tv_usec = fmod(d, 1.0) * 1000000.0;
}

116
Py_LOCAL_INLINE(double)
117 118 119 120 121 122 123 124 125 126 127 128
double_from_timeval(struct timeval *tv)
{
    return tv->tv_sec + (double)(tv->tv_usec / 1000000.0);
}

static PyObject *
itimer_retval(struct itimerval *iv)
{
    PyObject *r, *v;

    r = PyTuple_New(2);
    if (r == NULL)
129
    return NULL;
130 131

    if(!(v = PyFloat_FromDouble(double_from_timeval(&iv->it_value)))) {
132 133
    Py_DECREF(r);
    return NULL;
134 135 136 137 138
    }

    PyTuple_SET_ITEM(r, 0, v);

    if(!(v = PyFloat_FromDouble(double_from_timeval(&iv->it_interval)))) {
139 140
    Py_DECREF(r);
    return NULL;
141 142 143 144 145 146 147
    }

    PyTuple_SET_ITEM(r, 1, v);

    return r;
}
#endif
148

149
static PyObject *
Peter Schneider-Kamp's avatar
Peter Schneider-Kamp committed
150
signal_default_int_handler(PyObject *self, PyObject *args)
151
{
152 153
    PyErr_SetNone(PyExc_KeyboardInterrupt);
    return NULL;
154 155
}

156
PyDoc_STRVAR(default_int_handler_doc,
Guido van Rossum's avatar
Guido van Rossum committed
157 158
"default_int_handler(...)\n\
\n\
Michael W. Hudson's avatar
Michael W. Hudson committed
159
The default handler for SIGINT installed by Python.\n\
160
It raises KeyboardInterrupt.");
Guido van Rossum's avatar
Guido van Rossum committed
161

162 163 164 165

static int
checksignals_witharg(void * unused)
{
166
    return PyErr_CheckSignals();
167 168
}

169
static void
Peter Schneider-Kamp's avatar
Peter Schneider-Kamp committed
170
signal_handler(int sig_num)
171
{
172 173 174
    int save_errno = errno;

#if defined(WITH_THREAD) && defined(WITH_PTH)
175 176 177
    if (PyThread_get_thread_ident() != main_thread) {
        pth_raise(*(pth_t *) main_thread, sig_num);
    }
178
    else
179
#endif
180 181
    {
#ifdef WITH_THREAD
182
    /* See NOTES section above */
183
    if (getpid() == main_pid)
184
#endif
185
    {
186 187 188 189 190 191 192 193
        Handlers[sig_num].tripped = 1;
        /* Set is_tripped after setting .tripped, as it gets
           cleared in PyErr_CheckSignals() before .tripped. */
        is_tripped = 1;
        Py_AddPendingCall(checksignals_witharg, NULL);
        if (wakeup_fd != -1)
            write(wakeup_fd, "\0", 1);
    }
194 195

#ifndef HAVE_SIGACTION
196
#ifdef SIGCHLD
197 198 199 200 201
    /* To avoid infinite recursion, this signal remains
       reset until explicit re-instated.
       Don't clear the 'func' field as it is our pointer
       to the Python handler... */
    if (sig_num != SIGCHLD)
202
#endif
203 204 205 206
    /* If the handler was not set up with sigaction, reinstall it.  See
     * Python/pythonrun.c for the implementation of PyOS_setsig which
     * makes this true.  See also issue8354. */
    PyOS_setsig(sig_num, signal_handler);
207
#endif
208 209 210 211 212
    }

    /* Issue #10311: asynchronously executing signal handlers should not
       mutate errno under the feet of unsuspecting C code. */
    errno = save_errno;
213
}
214

215

216
#ifdef HAVE_ALARM
217
static PyObject *
Peter Schneider-Kamp's avatar
Peter Schneider-Kamp committed
218
signal_alarm(PyObject *self, PyObject *args)
219
{
220 221 222 223 224
    int t;
    if (!PyArg_ParseTuple(args, "i:alarm", &t))
        return NULL;
    /* alarm() returns the number of seconds remaining */
    return PyLong_FromLong((long)alarm(t));
225
}
Guido van Rossum's avatar
Guido van Rossum committed
226

227
PyDoc_STRVAR(alarm_doc,
Guido van Rossum's avatar
Guido van Rossum committed
228 229
"alarm(seconds)\n\
\n\
230
Arrange for SIGALRM to arrive after the given number of seconds.");
231
#endif
232

233
#ifdef HAVE_PAUSE
234
static PyObject *
235
signal_pause(PyObject *self)
236
{
237 238 239 240 241 242 243 244 245 246 247
    Py_BEGIN_ALLOW_THREADS
    (void)pause();
    Py_END_ALLOW_THREADS
    /* make sure that any exceptions that got raised are propagated
     * back into Python
     */
    if (PyErr_CheckSignals())
        return NULL;

    Py_INCREF(Py_None);
    return Py_None;
248
}
249
PyDoc_STRVAR(pause_doc,
250 251
"pause()\n\
\n\
252
Wait until a signal arrives.");
Guido van Rossum's avatar
Guido van Rossum committed
253

254
#endif
255

256

257
static PyObject *
Peter Schneider-Kamp's avatar
Peter Schneider-Kamp committed
258
signal_signal(PyObject *self, PyObject *args)
259
{
260 261 262 263 264 265
    PyObject *obj;
    int sig_num;
    PyObject *old_handler;
    void (*func)(int);
    if (!PyArg_ParseTuple(args, "iO:signal", &sig_num, &obj))
        return NULL;
266 267
#ifdef MS_WINDOWS
    /* Validate that sig_num is one of the allowable signals */
268 269
    switch (sig_num) {
        case SIGABRT: break;
270 271 272 273 274
#ifdef SIGBREAK
        /* Issue #10003: SIGBREAK is not documented as permitted, but works
           and corresponds to CTRL_BREAK_EVENT. */
        case SIGBREAK: break;
#endif
275 276 277 278 279 280 281 282
        case SIGFPE: break;
        case SIGILL: break;
        case SIGINT: break;
        case SIGSEGV: break;
        case SIGTERM: break;
        default:
            PyErr_SetString(PyExc_ValueError, "invalid signal value");
            return NULL;
283 284
    }
#endif
285
#ifdef WITH_THREAD
286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302
    if (PyThread_get_thread_ident() != main_thread) {
        PyErr_SetString(PyExc_ValueError,
                        "signal only works in main thread");
        return NULL;
    }
#endif
    if (sig_num < 1 || sig_num >= NSIG) {
        PyErr_SetString(PyExc_ValueError,
                        "signal number out of range");
        return NULL;
    }
    if (obj == IgnoreHandler)
        func = SIG_IGN;
    else if (obj == DefaultHandler)
        func = SIG_DFL;
    else if (!PyCallable_Check(obj)) {
        PyErr_SetString(PyExc_TypeError,
303
"signal handler must be signal.SIG_IGN, signal.SIG_DFL, or a callable object");
304 305 306 307 308 309 310 311 312 313 314 315 316
                return NULL;
    }
    else
        func = signal_handler;
    if (PyOS_setsig(sig_num, func) == SIG_ERR) {
        PyErr_SetFromErrno(PyExc_RuntimeError);
        return NULL;
    }
    old_handler = Handlers[sig_num].func;
    Handlers[sig_num].tripped = 0;
    Py_INCREF(obj);
    Handlers[sig_num].func = obj;
    return old_handler;
317 318
}

319
PyDoc_STRVAR(signal_doc,
Guido van Rossum's avatar
Guido van Rossum committed
320 321 322 323 324 325 326 327
"signal(sig, action) -> action\n\
\n\
Set the action for the given signal.  The action can be SIG_DFL,\n\
SIG_IGN, or a callable Python object.  The previous action is\n\
returned.  See getsignal() for possible return values.\n\
\n\
*** IMPORTANT NOTICE ***\n\
A signal handler function is called with two arguments:\n\
328
the first is the signal number, the second is the interrupted stack frame.");
Guido van Rossum's avatar
Guido van Rossum committed
329

330

331
static PyObject *
Peter Schneider-Kamp's avatar
Peter Schneider-Kamp committed
332
signal_getsignal(PyObject *self, PyObject *args)
333
{
334 335 336 337 338 339 340 341 342 343 344 345
    int sig_num;
    PyObject *old_handler;
    if (!PyArg_ParseTuple(args, "i:getsignal", &sig_num))
        return NULL;
    if (sig_num < 1 || sig_num >= NSIG) {
        PyErr_SetString(PyExc_ValueError,
                        "signal number out of range");
        return NULL;
    }
    old_handler = Handlers[sig_num].func;
    Py_INCREF(old_handler);
    return old_handler;
346 347
}

348
PyDoc_STRVAR(getsignal_doc,
Guido van Rossum's avatar
Guido van Rossum committed
349 350 351 352 353 354
"getsignal(sig) -> action\n\
\n\
Return the current action for the given signal.  The return value can be:\n\
SIG_IGN -- if the signal is being ignored\n\
SIG_DFL -- if the default action for the signal is in effect\n\
None -- if an unknown handler is in effect\n\
355
anything else -- the callable Python object used as a handler");
356

Christian Heimes's avatar
Christian Heimes committed
357 358 359 360 361 362 363 364 365 366
#ifdef HAVE_SIGINTERRUPT
PyDoc_STRVAR(siginterrupt_doc,
"siginterrupt(sig, flag) -> None\n\
change system call restart behaviour: if flag is False, system calls\n\
will be restarted when interrupted by signal sig, else system calls\n\
will be interrupted.");

static PyObject *
signal_siginterrupt(PyObject *self, PyObject *args)
{
367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383
    int sig_num;
    int flag;

    if (!PyArg_ParseTuple(args, "ii:siginterrupt", &sig_num, &flag))
        return NULL;
    if (sig_num < 1 || sig_num >= NSIG) {
        PyErr_SetString(PyExc_ValueError,
                        "signal number out of range");
        return NULL;
    }
    if (siginterrupt(sig_num, flag)<0) {
        PyErr_SetFromErrno(PyExc_RuntimeError);
        return NULL;
    }

    Py_INCREF(Py_None);
    return Py_None;
Christian Heimes's avatar
Christian Heimes committed
384 385 386
}

#endif
387

388 389 390
static PyObject *
signal_set_wakeup_fd(PyObject *self, PyObject *args)
{
391 392 393 394
    struct stat buf;
    int fd, old_fd;
    if (!PyArg_ParseTuple(args, "i:set_wakeup_fd", &fd))
        return NULL;
395
#ifdef WITH_THREAD
396 397 398 399 400 401 402 403 404 405 406 407 408
    if (PyThread_get_thread_ident() != main_thread) {
        PyErr_SetString(PyExc_ValueError,
                        "set_wakeup_fd only works in main thread");
        return NULL;
    }
#endif
    if (fd != -1 && fstat(fd, &buf) != 0) {
        PyErr_SetString(PyExc_ValueError, "invalid fd");
        return NULL;
    }
    old_fd = wakeup_fd;
    wakeup_fd = fd;
    return PyLong_FromLong(old_fd);
409 410 411 412 413 414 415 416 417 418 419 420 421 422 423
}

PyDoc_STRVAR(set_wakeup_fd_doc,
"set_wakeup_fd(fd) -> fd\n\
\n\
Sets the fd to be written to (with '\\0') when a signal\n\
comes in.  A library can use this to wakeup select or poll.\n\
The previous fd is returned.\n\
\n\
The fd must be non-blocking.");

/* C API for the same, without all the error checking */
int
PySignal_SetWakeupFd(int fd)
{
424 425 426 427 428
    int old_fd = wakeup_fd;
    if (fd < 0)
        fd = -1;
    wakeup_fd = fd;
    return old_fd;
429 430 431
}


432 433 434 435 436 437 438 439 440 441
#ifdef HAVE_SETITIMER
static PyObject *
signal_setitimer(PyObject *self, PyObject *args)
{
    double first;
    double interval = 0;
    int which;
    struct itimerval new, old;

    if(!PyArg_ParseTuple(args, "id|d:setitimer", &which, &first, &interval))
442
    return NULL;
443 444 445 446 447

    timeval_from_double(first, &new.it_value);
    timeval_from_double(interval, &new.it_interval);
    /* Let OS check "which" value */
    if (setitimer(which, &new, &old) != 0) {
448 449
    PyErr_SetFromErrno(ItimerError);
    return NULL;
450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474
    }

    return itimer_retval(&old);
}

PyDoc_STRVAR(setitimer_doc,
"setitimer(which, seconds[, interval])\n\
\n\
Sets given itimer (one of ITIMER_REAL, ITIMER_VIRTUAL\n\
or ITIMER_PROF) to fire after value seconds and after\n\
that every interval seconds.\n\
The itimer can be cleared by setting seconds to zero.\n\
\n\
Returns old values as a tuple: (delay, interval).");
#endif


#ifdef HAVE_GETITIMER
static PyObject *
signal_getitimer(PyObject *self, PyObject *args)
{
    int which;
    struct itimerval old;

    if (!PyArg_ParseTuple(args, "i:getitimer", &which))
475
    return NULL;
476 477

    if (getitimer(which, &old) != 0) {
478 479
    PyErr_SetFromErrno(ItimerError);
    return NULL;
480 481 482 483 484 485 486 487 488 489 490 491
    }

    return itimer_retval(&old);
}

PyDoc_STRVAR(getitimer_doc,
"getitimer(which)\n\
\n\
Returns current value of given itimer.");
#endif


492
/* List of functions defined in the module */
Barry Warsaw's avatar
Barry Warsaw committed
493
static PyMethodDef signal_methods[] = {
494
#ifdef HAVE_ALARM
495
    {"alarm",                   signal_alarm, METH_VARARGS, alarm_doc},
496 497 498 499 500
#endif
#ifdef HAVE_SETITIMER
    {"setitimer",       signal_setitimer, METH_VARARGS, setitimer_doc},
#endif
#ifdef HAVE_GETITIMER
501
    {"getitimer",       signal_getitimer, METH_VARARGS, getitimer_doc},
502
#endif
503 504 505
    {"signal",                  signal_signal, METH_VARARGS, signal_doc},
    {"getsignal",               signal_getsignal, METH_VARARGS, getsignal_doc},
    {"set_wakeup_fd",           signal_set_wakeup_fd, METH_VARARGS, set_wakeup_fd_doc},
Christian Heimes's avatar
Christian Heimes committed
506
#ifdef HAVE_SIGINTERRUPT
507
    {"siginterrupt",            signal_siginterrupt, METH_VARARGS, siginterrupt_doc},
Christian Heimes's avatar
Christian Heimes committed
508
#endif
509
#ifdef HAVE_PAUSE
510 511
    {"pause",                   (PyCFunction)signal_pause,
     METH_NOARGS,pause_doc},
512
#endif
513 514 515
    {"default_int_handler", signal_default_int_handler,
     METH_VARARGS, default_int_handler_doc},
    {NULL,                      NULL}           /* sentinel */
516 517
};

Barry Warsaw's avatar
Barry Warsaw committed
518

519
PyDoc_STRVAR(module_doc,
Guido van Rossum's avatar
Guido van Rossum committed
520 521 522 523 524
"This module provides mechanisms to use signal handlers in Python.\n\
\n\
Functions:\n\
\n\
alarm() -- cause SIGALRM after a specified time [Unix only]\n\
525 526 527
setitimer() -- cause a signal (described below) after a specified\n\
               float time and the timer may restart then [Unix only]\n\
getitimer() -- get current value of timer [Unix only]\n\
Guido van Rossum's avatar
Guido van Rossum committed
528 529 530 531 532
signal() -- set the action for a given signal\n\
getsignal() -- get the signal action for a given signal\n\
pause() -- wait until a signal arrives [Unix only]\n\
default_int_handler() -- default SIGINT handler\n\
\n\
533
signal constants:\n\
Guido van Rossum's avatar
Guido van Rossum committed
534 535 536 537 538
SIG_DFL -- used to refer to the system default handler\n\
SIG_IGN -- used to ignore the signal\n\
NSIG -- number of defined signals\n\
SIGINT, SIGTERM, etc. -- signal numbers\n\
\n\
539 540 541 542 543 544 545 546 547 548 549 550
itimer constants:\n\
ITIMER_REAL -- decrements in real time, and delivers SIGALRM upon\n\
               expiration\n\
ITIMER_VIRTUAL -- decrements only when the process is executing,\n\
               and delivers SIGVTALRM upon expiration\n\
ITIMER_PROF -- decrements both when the process is executing and\n\
               when the system is executing on behalf of the process.\n\
               Coupled with ITIMER_VIRTUAL, this timer is usually\n\
               used to profile the time spent by the application\n\
               in user and kernel space. SIGPROF is delivered upon\n\
               expiration.\n\
\n\n\
Guido van Rossum's avatar
Guido van Rossum committed
551 552
*** IMPORTANT NOTICE ***\n\
A signal handler function is called with two arguments:\n\
553
the first is the signal number, the second is the interrupted stack frame.");
Guido van Rossum's avatar
Guido van Rossum committed
554

555
static struct PyModuleDef signalmodule = {
556 557 558 559 560 561 562 563 564
    PyModuleDef_HEAD_INIT,
    "signal",
    module_doc,
    -1,
    signal_methods,
    NULL,
    NULL,
    NULL,
    NULL
565 566
};

567
PyMODINIT_FUNC
568
PyInit_signal(void)
569
{
570 571
    PyObject *m, *d, *x;
    int i;
572 573

#ifdef WITH_THREAD
574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623
    main_thread = PyThread_get_thread_ident();
    main_pid = getpid();
#endif

    /* Create the module and add the functions */
    m = PyModule_Create(&signalmodule);
    if (m == NULL)
        return NULL;

    /* Add some symbolic constants to the module */
    d = PyModule_GetDict(m);

    x = DefaultHandler = PyLong_FromVoidPtr((void *)SIG_DFL);
    if (!x || PyDict_SetItemString(d, "SIG_DFL", x) < 0)
        goto finally;

    x = IgnoreHandler = PyLong_FromVoidPtr((void *)SIG_IGN);
    if (!x || PyDict_SetItemString(d, "SIG_IGN", x) < 0)
        goto finally;

    x = PyLong_FromLong((long)NSIG);
    if (!x || PyDict_SetItemString(d, "NSIG", x) < 0)
        goto finally;
    Py_DECREF(x);

    x = IntHandler = PyDict_GetItemString(d, "default_int_handler");
    if (!x)
        goto finally;
    Py_INCREF(IntHandler);

    Handlers[0].tripped = 0;
    for (i = 1; i < NSIG; i++) {
        void (*t)(int);
        t = PyOS_getsig(i);
        Handlers[i].tripped = 0;
        if (t == SIG_DFL)
            Handlers[i].func = DefaultHandler;
        else if (t == SIG_IGN)
            Handlers[i].func = IgnoreHandler;
        else
            Handlers[i].func = Py_None; /* None of our business */
        Py_INCREF(Handlers[i].func);
    }
    if (Handlers[SIGINT].func == DefaultHandler) {
        /* Install default int handler */
        Py_INCREF(IntHandler);
        Py_DECREF(Handlers[SIGINT].func);
        Handlers[SIGINT].func = IntHandler;
        old_siginthandler = PyOS_setsig(SIGINT, signal_handler);
    }
624 625

#ifdef SIGHUP
626 627 628
    x = PyLong_FromLong(SIGHUP);
    PyDict_SetItemString(d, "SIGHUP", x);
    Py_XDECREF(x);
629 630
#endif
#ifdef SIGINT
631 632 633
    x = PyLong_FromLong(SIGINT);
    PyDict_SetItemString(d, "SIGINT", x);
    Py_XDECREF(x);
634
#endif
635
#ifdef SIGBREAK
636 637 638
    x = PyLong_FromLong(SIGBREAK);
    PyDict_SetItemString(d, "SIGBREAK", x);
    Py_XDECREF(x);
639
#endif
640
#ifdef SIGQUIT
641 642 643
    x = PyLong_FromLong(SIGQUIT);
    PyDict_SetItemString(d, "SIGQUIT", x);
    Py_XDECREF(x);
644 645
#endif
#ifdef SIGILL
646 647 648
    x = PyLong_FromLong(SIGILL);
    PyDict_SetItemString(d, "SIGILL", x);
    Py_XDECREF(x);
649 650
#endif
#ifdef SIGTRAP
651 652 653
    x = PyLong_FromLong(SIGTRAP);
    PyDict_SetItemString(d, "SIGTRAP", x);
    Py_XDECREF(x);
654 655
#endif
#ifdef SIGIOT
656 657 658
    x = PyLong_FromLong(SIGIOT);
    PyDict_SetItemString(d, "SIGIOT", x);
    Py_XDECREF(x);
659 660
#endif
#ifdef SIGABRT
661 662 663
    x = PyLong_FromLong(SIGABRT);
    PyDict_SetItemString(d, "SIGABRT", x);
    Py_XDECREF(x);
664 665
#endif
#ifdef SIGEMT
666 667 668
    x = PyLong_FromLong(SIGEMT);
    PyDict_SetItemString(d, "SIGEMT", x);
    Py_XDECREF(x);
669 670
#endif
#ifdef SIGFPE
671 672 673
    x = PyLong_FromLong(SIGFPE);
    PyDict_SetItemString(d, "SIGFPE", x);
    Py_XDECREF(x);
674 675
#endif
#ifdef SIGKILL
676 677 678
    x = PyLong_FromLong(SIGKILL);
    PyDict_SetItemString(d, "SIGKILL", x);
    Py_XDECREF(x);
679 680
#endif
#ifdef SIGBUS
681 682 683
    x = PyLong_FromLong(SIGBUS);
    PyDict_SetItemString(d, "SIGBUS", x);
    Py_XDECREF(x);
684 685
#endif
#ifdef SIGSEGV
686 687 688
    x = PyLong_FromLong(SIGSEGV);
    PyDict_SetItemString(d, "SIGSEGV", x);
    Py_XDECREF(x);
689 690
#endif
#ifdef SIGSYS
691 692 693
    x = PyLong_FromLong(SIGSYS);
    PyDict_SetItemString(d, "SIGSYS", x);
    Py_XDECREF(x);
694 695
#endif
#ifdef SIGPIPE
696 697 698
    x = PyLong_FromLong(SIGPIPE);
    PyDict_SetItemString(d, "SIGPIPE", x);
    Py_XDECREF(x);
699 700
#endif
#ifdef SIGALRM
701 702 703
    x = PyLong_FromLong(SIGALRM);
    PyDict_SetItemString(d, "SIGALRM", x);
    Py_XDECREF(x);
704 705
#endif
#ifdef SIGTERM
706 707 708
    x = PyLong_FromLong(SIGTERM);
    PyDict_SetItemString(d, "SIGTERM", x);
    Py_XDECREF(x);
709 710
#endif
#ifdef SIGUSR1
711 712 713
    x = PyLong_FromLong(SIGUSR1);
    PyDict_SetItemString(d, "SIGUSR1", x);
    Py_XDECREF(x);
714 715
#endif
#ifdef SIGUSR2
716 717 718
    x = PyLong_FromLong(SIGUSR2);
    PyDict_SetItemString(d, "SIGUSR2", x);
    Py_XDECREF(x);
719 720
#endif
#ifdef SIGCLD
721 722 723
    x = PyLong_FromLong(SIGCLD);
    PyDict_SetItemString(d, "SIGCLD", x);
    Py_XDECREF(x);
724 725
#endif
#ifdef SIGCHLD
726 727 728
    x = PyLong_FromLong(SIGCHLD);
    PyDict_SetItemString(d, "SIGCHLD", x);
    Py_XDECREF(x);
729 730
#endif
#ifdef SIGPWR
731 732 733
    x = PyLong_FromLong(SIGPWR);
    PyDict_SetItemString(d, "SIGPWR", x);
    Py_XDECREF(x);
734 735
#endif
#ifdef SIGIO
736 737 738
    x = PyLong_FromLong(SIGIO);
    PyDict_SetItemString(d, "SIGIO", x);
    Py_XDECREF(x);
739 740
#endif
#ifdef SIGURG
741 742 743
    x = PyLong_FromLong(SIGURG);
    PyDict_SetItemString(d, "SIGURG", x);
    Py_XDECREF(x);
744 745
#endif
#ifdef SIGWINCH
746 747 748
    x = PyLong_FromLong(SIGWINCH);
    PyDict_SetItemString(d, "SIGWINCH", x);
    Py_XDECREF(x);
749 750
#endif
#ifdef SIGPOLL
751 752 753
    x = PyLong_FromLong(SIGPOLL);
    PyDict_SetItemString(d, "SIGPOLL", x);
    Py_XDECREF(x);
754 755
#endif
#ifdef SIGSTOP
756 757 758
    x = PyLong_FromLong(SIGSTOP);
    PyDict_SetItemString(d, "SIGSTOP", x);
    Py_XDECREF(x);
759 760
#endif
#ifdef SIGTSTP
761 762 763
    x = PyLong_FromLong(SIGTSTP);
    PyDict_SetItemString(d, "SIGTSTP", x);
    Py_XDECREF(x);
764 765
#endif
#ifdef SIGCONT
766 767 768
    x = PyLong_FromLong(SIGCONT);
    PyDict_SetItemString(d, "SIGCONT", x);
    Py_XDECREF(x);
769 770
#endif
#ifdef SIGTTIN
771 772 773
    x = PyLong_FromLong(SIGTTIN);
    PyDict_SetItemString(d, "SIGTTIN", x);
    Py_XDECREF(x);
774 775
#endif
#ifdef SIGTTOU
776 777 778
    x = PyLong_FromLong(SIGTTOU);
    PyDict_SetItemString(d, "SIGTTOU", x);
    Py_XDECREF(x);
779 780
#endif
#ifdef SIGVTALRM
781 782 783
    x = PyLong_FromLong(SIGVTALRM);
    PyDict_SetItemString(d, "SIGVTALRM", x);
    Py_XDECREF(x);
784 785
#endif
#ifdef SIGPROF
786 787 788
    x = PyLong_FromLong(SIGPROF);
    PyDict_SetItemString(d, "SIGPROF", x);
    Py_XDECREF(x);
789
#endif
790
#ifdef SIGXCPU
791 792 793
    x = PyLong_FromLong(SIGXCPU);
    PyDict_SetItemString(d, "SIGXCPU", x);
    Py_XDECREF(x);
794 795
#endif
#ifdef SIGXFSZ
796 797 798
    x = PyLong_FromLong(SIGXFSZ);
    PyDict_SetItemString(d, "SIGXFSZ", x);
    Py_XDECREF(x);
799
#endif
800
#ifdef SIGRTMIN
801 802 803
    x = PyLong_FromLong(SIGRTMIN);
    PyDict_SetItemString(d, "SIGRTMIN", x);
    Py_XDECREF(x);
804 805
#endif
#ifdef SIGRTMAX
806 807 808
    x = PyLong_FromLong(SIGRTMAX);
    PyDict_SetItemString(d, "SIGRTMAX", x);
    Py_XDECREF(x);
809
#endif
810
#ifdef SIGINFO
811 812 813
    x = PyLong_FromLong(SIGINFO);
    PyDict_SetItemString(d, "SIGINFO", x);
    Py_XDECREF(x);
814
#endif
815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832

#ifdef ITIMER_REAL
    x = PyLong_FromLong(ITIMER_REAL);
    PyDict_SetItemString(d, "ITIMER_REAL", x);
    Py_DECREF(x);
#endif
#ifdef ITIMER_VIRTUAL
    x = PyLong_FromLong(ITIMER_VIRTUAL);
    PyDict_SetItemString(d, "ITIMER_VIRTUAL", x);
    Py_DECREF(x);
#endif
#ifdef ITIMER_PROF
    x = PyLong_FromLong(ITIMER_PROF);
    PyDict_SetItemString(d, "ITIMER_PROF", x);
    Py_DECREF(x);
#endif

#if defined (HAVE_SETITIMER) || defined (HAVE_GETITIMER)
833 834
    ItimerError = PyErr_NewException("signal.ItimerError",
     PyExc_IOError, NULL);
835
    if (ItimerError != NULL)
836
    PyDict_SetItemString(d, "ItimerError", ItimerError);
837 838
#endif

839 840 841 842 843 844 845 846 847 848 849 850
#ifdef CTRL_C_EVENT
    x = PyLong_FromLong(CTRL_C_EVENT);
    PyDict_SetItemString(d, "CTRL_C_EVENT", x);
    Py_DECREF(x);
#endif

#ifdef CTRL_BREAK_EVENT
    x = PyLong_FromLong(CTRL_BREAK_EVENT);
    PyDict_SetItemString(d, "CTRL_BREAK_EVENT", x);
    Py_DECREF(x);
#endif

851
    if (PyErr_Occurred()) {
852 853
        Py_DECREF(m);
        m = NULL;
854
    }
Barry Warsaw's avatar
Barry Warsaw committed
855 856

  finally:
857
    return m;
858 859 860
}

static void
861
finisignal(void)
862
{
863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884
    int i;
    PyObject *func;

    PyOS_setsig(SIGINT, old_siginthandler);
    old_siginthandler = SIG_DFL;

    for (i = 1; i < NSIG; i++) {
        func = Handlers[i].func;
        Handlers[i].tripped = 0;
        Handlers[i].func = NULL;
        if (i != SIGINT && func != NULL && func != Py_None &&
            func != DefaultHandler && func != IgnoreHandler)
            PyOS_setsig(i, SIG_DFL);
        Py_XDECREF(func);
    }

    Py_XDECREF(IntHandler);
    IntHandler = NULL;
    Py_XDECREF(DefaultHandler);
    DefaultHandler = NULL;
    Py_XDECREF(IgnoreHandler);
    IgnoreHandler = NULL;
885 886
}

Barry Warsaw's avatar
Barry Warsaw committed
887 888

/* Declared in pyerrors.h */
889
int
890
PyErr_CheckSignals(void)
891
{
892 893
    int i;
    PyObject *f;
Barry Warsaw's avatar
Barry Warsaw committed
894

895 896
    if (!is_tripped)
        return 0;
897

898
#ifdef WITH_THREAD
899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940
    if (PyThread_get_thread_ident() != main_thread)
        return 0;
#endif

    /*
     * The is_tripped variable is meant to speed up the calls to
     * PyErr_CheckSignals (both directly or via pending calls) when no
     * signal has arrived. This variable is set to 1 when a signal arrives
     * and it is set to 0 here, when we know some signals arrived. This way
     * we can run the registered handlers with no signals blocked.
     *
     * NOTE: with this approach we can have a situation where is_tripped is
     *       1 but we have no more signals to handle (Handlers[i].tripped
     *       is 0 for every signal i). This won't do us any harm (except
     *       we're gonna spent some cycles for nothing). This happens when
     *       we receive a signal i after we zero is_tripped and before we
     *       check Handlers[i].tripped.
     */
    is_tripped = 0;

    if (!(f = (PyObject *)PyEval_GetFrame()))
        f = Py_None;

    for (i = 1; i < NSIG; i++) {
        if (Handlers[i].tripped) {
            PyObject *result = NULL;
            PyObject *arglist = Py_BuildValue("(iO)", i, f);
            Handlers[i].tripped = 0;

            if (arglist) {
                result = PyEval_CallObject(Handlers[i].func,
                                           arglist);
                Py_DECREF(arglist);
            }
            if (!result)
                return -1;

            Py_DECREF(result);
        }
    }

    return 0;
941 942
}

943

Barry Warsaw's avatar
Barry Warsaw committed
944 945 946 947
/* Replacements for intrcheck.c functionality
 * Declared in pyerrors.h
 */
void
948
PyErr_SetInterrupt(void)
Barry Warsaw's avatar
Barry Warsaw committed
949
{
950 951 952
    is_tripped = 1;
    Handlers[SIGINT].tripped = 1;
    Py_AddPendingCall((int (*)(void *))PyErr_CheckSignals, NULL);
Barry Warsaw's avatar
Barry Warsaw committed
953
}
954 955

void
956
PyOS_InitInterrupts(void)
957
{
958 959
    PyObject *m = PyInit_signal();
    if (m) {
960
        _PyImport_FixupBuiltin(m, "signal");
961 962
        Py_DECREF(m);
    }
963 964 965
}

void
966
PyOS_FiniInterrupts(void)
967
{
968
    finisignal();
969 970 971
}

int
972
PyOS_InterruptOccurred(void)
973
{
974
    if (Handlers[SIGINT].tripped) {
975
#ifdef WITH_THREAD
976 977
        if (PyThread_get_thread_ident() != main_thread)
            return 0;
978
#endif
979 980 981 982
        Handlers[SIGINT].tripped = 0;
        return 1;
    }
    return 0;
983
}
984 985

void
986
PyOS_AfterFork(void)
987 988
{
#ifdef WITH_THREAD
989 990 991 992 993
    PyEval_ReInitThreads();
    main_thread = PyThread_get_thread_ident();
    main_pid = getpid();
    _PyImport_ReInitLock();
    PyThread_ReInitTLS();
994 995
#endif
}