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