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