Merged revisions 74356-74357 via svnmerge from
[python/dscho.git] / Modules / signalmodule.c
blob7464eae1dc500dcf296a76e81cae43994a95d88e
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 PyLong_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 static struct PyModuleDef signalmodule = {
520 PyModuleDef_HEAD_INIT,
521 "signal",
522 module_doc,
524 signal_methods,
525 NULL,
526 NULL,
527 NULL,
528 NULL
531 PyMODINIT_FUNC
532 PyInit_signal(void)
534 PyObject *m, *d, *x;
535 int i;
537 #ifdef WITH_THREAD
538 main_thread = PyThread_get_thread_ident();
539 main_pid = getpid();
540 #endif
542 /* Create the module and add the functions */
543 m = PyModule_Create(&signalmodule);
544 if (m == NULL)
545 return NULL;
547 /* Add some symbolic constants to the module */
548 d = PyModule_GetDict(m);
550 x = DefaultHandler = PyLong_FromVoidPtr((void *)SIG_DFL);
551 if (!x || PyDict_SetItemString(d, "SIG_DFL", x) < 0)
552 goto finally;
554 x = IgnoreHandler = PyLong_FromVoidPtr((void *)SIG_IGN);
555 if (!x || PyDict_SetItemString(d, "SIG_IGN", x) < 0)
556 goto finally;
558 x = PyLong_FromLong((long)NSIG);
559 if (!x || PyDict_SetItemString(d, "NSIG", x) < 0)
560 goto finally;
561 Py_DECREF(x);
563 x = IntHandler = PyDict_GetItemString(d, "default_int_handler");
564 if (!x)
565 goto finally;
566 Py_INCREF(IntHandler);
568 Handlers[0].tripped = 0;
569 for (i = 1; i < NSIG; i++) {
570 void (*t)(int);
571 t = PyOS_getsig(i);
572 Handlers[i].tripped = 0;
573 if (t == SIG_DFL)
574 Handlers[i].func = DefaultHandler;
575 else if (t == SIG_IGN)
576 Handlers[i].func = IgnoreHandler;
577 else
578 Handlers[i].func = Py_None; /* None of our business */
579 Py_INCREF(Handlers[i].func);
581 if (Handlers[SIGINT].func == DefaultHandler) {
582 /* Install default int handler */
583 Py_INCREF(IntHandler);
584 Py_DECREF(Handlers[SIGINT].func);
585 Handlers[SIGINT].func = IntHandler;
586 old_siginthandler = PyOS_setsig(SIGINT, signal_handler);
589 #ifdef SIGHUP
590 x = PyLong_FromLong(SIGHUP);
591 PyDict_SetItemString(d, "SIGHUP", x);
592 Py_XDECREF(x);
593 #endif
594 #ifdef SIGINT
595 x = PyLong_FromLong(SIGINT);
596 PyDict_SetItemString(d, "SIGINT", x);
597 Py_XDECREF(x);
598 #endif
599 #ifdef SIGBREAK
600 x = PyLong_FromLong(SIGBREAK);
601 PyDict_SetItemString(d, "SIGBREAK", x);
602 Py_XDECREF(x);
603 #endif
604 #ifdef SIGQUIT
605 x = PyLong_FromLong(SIGQUIT);
606 PyDict_SetItemString(d, "SIGQUIT", x);
607 Py_XDECREF(x);
608 #endif
609 #ifdef SIGILL
610 x = PyLong_FromLong(SIGILL);
611 PyDict_SetItemString(d, "SIGILL", x);
612 Py_XDECREF(x);
613 #endif
614 #ifdef SIGTRAP
615 x = PyLong_FromLong(SIGTRAP);
616 PyDict_SetItemString(d, "SIGTRAP", x);
617 Py_XDECREF(x);
618 #endif
619 #ifdef SIGIOT
620 x = PyLong_FromLong(SIGIOT);
621 PyDict_SetItemString(d, "SIGIOT", x);
622 Py_XDECREF(x);
623 #endif
624 #ifdef SIGABRT
625 x = PyLong_FromLong(SIGABRT);
626 PyDict_SetItemString(d, "SIGABRT", x);
627 Py_XDECREF(x);
628 #endif
629 #ifdef SIGEMT
630 x = PyLong_FromLong(SIGEMT);
631 PyDict_SetItemString(d, "SIGEMT", x);
632 Py_XDECREF(x);
633 #endif
634 #ifdef SIGFPE
635 x = PyLong_FromLong(SIGFPE);
636 PyDict_SetItemString(d, "SIGFPE", x);
637 Py_XDECREF(x);
638 #endif
639 #ifdef SIGKILL
640 x = PyLong_FromLong(SIGKILL);
641 PyDict_SetItemString(d, "SIGKILL", x);
642 Py_XDECREF(x);
643 #endif
644 #ifdef SIGBUS
645 x = PyLong_FromLong(SIGBUS);
646 PyDict_SetItemString(d, "SIGBUS", x);
647 Py_XDECREF(x);
648 #endif
649 #ifdef SIGSEGV
650 x = PyLong_FromLong(SIGSEGV);
651 PyDict_SetItemString(d, "SIGSEGV", x);
652 Py_XDECREF(x);
653 #endif
654 #ifdef SIGSYS
655 x = PyLong_FromLong(SIGSYS);
656 PyDict_SetItemString(d, "SIGSYS", x);
657 Py_XDECREF(x);
658 #endif
659 #ifdef SIGPIPE
660 x = PyLong_FromLong(SIGPIPE);
661 PyDict_SetItemString(d, "SIGPIPE", x);
662 Py_XDECREF(x);
663 #endif
664 #ifdef SIGALRM
665 x = PyLong_FromLong(SIGALRM);
666 PyDict_SetItemString(d, "SIGALRM", x);
667 Py_XDECREF(x);
668 #endif
669 #ifdef SIGTERM
670 x = PyLong_FromLong(SIGTERM);
671 PyDict_SetItemString(d, "SIGTERM", x);
672 Py_XDECREF(x);
673 #endif
674 #ifdef SIGUSR1
675 x = PyLong_FromLong(SIGUSR1);
676 PyDict_SetItemString(d, "SIGUSR1", x);
677 Py_XDECREF(x);
678 #endif
679 #ifdef SIGUSR2
680 x = PyLong_FromLong(SIGUSR2);
681 PyDict_SetItemString(d, "SIGUSR2", x);
682 Py_XDECREF(x);
683 #endif
684 #ifdef SIGCLD
685 x = PyLong_FromLong(SIGCLD);
686 PyDict_SetItemString(d, "SIGCLD", x);
687 Py_XDECREF(x);
688 #endif
689 #ifdef SIGCHLD
690 x = PyLong_FromLong(SIGCHLD);
691 PyDict_SetItemString(d, "SIGCHLD", x);
692 Py_XDECREF(x);
693 #endif
694 #ifdef SIGPWR
695 x = PyLong_FromLong(SIGPWR);
696 PyDict_SetItemString(d, "SIGPWR", x);
697 Py_XDECREF(x);
698 #endif
699 #ifdef SIGIO
700 x = PyLong_FromLong(SIGIO);
701 PyDict_SetItemString(d, "SIGIO", x);
702 Py_XDECREF(x);
703 #endif
704 #ifdef SIGURG
705 x = PyLong_FromLong(SIGURG);
706 PyDict_SetItemString(d, "SIGURG", x);
707 Py_XDECREF(x);
708 #endif
709 #ifdef SIGWINCH
710 x = PyLong_FromLong(SIGWINCH);
711 PyDict_SetItemString(d, "SIGWINCH", x);
712 Py_XDECREF(x);
713 #endif
714 #ifdef SIGPOLL
715 x = PyLong_FromLong(SIGPOLL);
716 PyDict_SetItemString(d, "SIGPOLL", x);
717 Py_XDECREF(x);
718 #endif
719 #ifdef SIGSTOP
720 x = PyLong_FromLong(SIGSTOP);
721 PyDict_SetItemString(d, "SIGSTOP", x);
722 Py_XDECREF(x);
723 #endif
724 #ifdef SIGTSTP
725 x = PyLong_FromLong(SIGTSTP);
726 PyDict_SetItemString(d, "SIGTSTP", x);
727 Py_XDECREF(x);
728 #endif
729 #ifdef SIGCONT
730 x = PyLong_FromLong(SIGCONT);
731 PyDict_SetItemString(d, "SIGCONT", x);
732 Py_XDECREF(x);
733 #endif
734 #ifdef SIGTTIN
735 x = PyLong_FromLong(SIGTTIN);
736 PyDict_SetItemString(d, "SIGTTIN", x);
737 Py_XDECREF(x);
738 #endif
739 #ifdef SIGTTOU
740 x = PyLong_FromLong(SIGTTOU);
741 PyDict_SetItemString(d, "SIGTTOU", x);
742 Py_XDECREF(x);
743 #endif
744 #ifdef SIGVTALRM
745 x = PyLong_FromLong(SIGVTALRM);
746 PyDict_SetItemString(d, "SIGVTALRM", x);
747 Py_XDECREF(x);
748 #endif
749 #ifdef SIGPROF
750 x = PyLong_FromLong(SIGPROF);
751 PyDict_SetItemString(d, "SIGPROF", x);
752 Py_XDECREF(x);
753 #endif
754 #ifdef SIGXCPU
755 x = PyLong_FromLong(SIGXCPU);
756 PyDict_SetItemString(d, "SIGXCPU", x);
757 Py_XDECREF(x);
758 #endif
759 #ifdef SIGXFSZ
760 x = PyLong_FromLong(SIGXFSZ);
761 PyDict_SetItemString(d, "SIGXFSZ", x);
762 Py_XDECREF(x);
763 #endif
764 #ifdef SIGRTMIN
765 x = PyLong_FromLong(SIGRTMIN);
766 PyDict_SetItemString(d, "SIGRTMIN", x);
767 Py_XDECREF(x);
768 #endif
769 #ifdef SIGRTMAX
770 x = PyLong_FromLong(SIGRTMAX);
771 PyDict_SetItemString(d, "SIGRTMAX", x);
772 Py_XDECREF(x);
773 #endif
774 #ifdef SIGINFO
775 x = PyLong_FromLong(SIGINFO);
776 PyDict_SetItemString(d, "SIGINFO", x);
777 Py_XDECREF(x);
778 #endif
780 #ifdef ITIMER_REAL
781 x = PyLong_FromLong(ITIMER_REAL);
782 PyDict_SetItemString(d, "ITIMER_REAL", x);
783 Py_DECREF(x);
784 #endif
785 #ifdef ITIMER_VIRTUAL
786 x = PyLong_FromLong(ITIMER_VIRTUAL);
787 PyDict_SetItemString(d, "ITIMER_VIRTUAL", x);
788 Py_DECREF(x);
789 #endif
790 #ifdef ITIMER_PROF
791 x = PyLong_FromLong(ITIMER_PROF);
792 PyDict_SetItemString(d, "ITIMER_PROF", x);
793 Py_DECREF(x);
794 #endif
796 #if defined (HAVE_SETITIMER) || defined (HAVE_GETITIMER)
797 ItimerError = PyErr_NewException("signal.ItimerError",
798 PyExc_IOError, NULL);
799 if (ItimerError != NULL)
800 PyDict_SetItemString(d, "ItimerError", ItimerError);
801 #endif
803 if (PyErr_Occurred()) {
804 Py_DECREF(m);
805 m = NULL;
808 finally:
809 return m;
812 static void
813 finisignal(void)
815 int i;
816 PyObject *func;
818 PyOS_setsig(SIGINT, old_siginthandler);
819 old_siginthandler = SIG_DFL;
821 for (i = 1; i < NSIG; i++) {
822 func = Handlers[i].func;
823 Handlers[i].tripped = 0;
824 Handlers[i].func = NULL;
825 if (i != SIGINT && func != NULL && func != Py_None &&
826 func != DefaultHandler && func != IgnoreHandler)
827 PyOS_setsig(i, SIG_DFL);
828 Py_XDECREF(func);
831 Py_XDECREF(IntHandler);
832 IntHandler = NULL;
833 Py_XDECREF(DefaultHandler);
834 DefaultHandler = NULL;
835 Py_XDECREF(IgnoreHandler);
836 IgnoreHandler = NULL;
840 /* Declared in pyerrors.h */
842 PyErr_CheckSignals(void)
844 int i;
845 PyObject *f;
847 if (!is_tripped)
848 return 0;
850 #ifdef WITH_THREAD
851 if (PyThread_get_thread_ident() != main_thread)
852 return 0;
853 #endif
856 * The is_stripped variable is meant to speed up the calls to
857 * PyErr_CheckSignals (both directly or via pending calls) when no
858 * signal has arrived. This variable is set to 1 when a signal arrives
859 * and it is set to 0 here, when we know some signals arrived. This way
860 * we can run the registered handlers with no signals blocked.
862 * NOTE: with this approach we can have a situation where is_tripped is
863 * 1 but we have no more signals to handle (Handlers[i].tripped
864 * is 0 for every signal i). This won't do us any harm (except
865 * we're gonna spent some cycles for nothing). This happens when
866 * we receive a signal i after we zero is_tripped and before we
867 * check Handlers[i].tripped.
869 is_tripped = 0;
871 if (!(f = (PyObject *)PyEval_GetFrame()))
872 f = Py_None;
874 for (i = 1; i < NSIG; i++) {
875 if (Handlers[i].tripped) {
876 PyObject *result = NULL;
877 PyObject *arglist = Py_BuildValue("(iO)", i, f);
878 Handlers[i].tripped = 0;
880 if (arglist) {
881 result = PyEval_CallObject(Handlers[i].func,
882 arglist);
883 Py_DECREF(arglist);
885 if (!result)
886 return -1;
888 Py_DECREF(result);
892 return 0;
896 /* Replacements for intrcheck.c functionality
897 * Declared in pyerrors.h
899 void
900 PyErr_SetInterrupt(void)
902 is_tripped = 1;
903 Handlers[SIGINT].tripped = 1;
904 Py_AddPendingCall((int (*)(void *))PyErr_CheckSignals, NULL);
907 void
908 PyOS_InitInterrupts(void)
910 PyObject *m = PyInit_signal();
911 if (m) {
912 _PyImport_FixupExtension(m, "signal", "signal");
913 Py_DECREF(m);
917 void
918 PyOS_FiniInterrupts(void)
920 finisignal();
924 PyOS_InterruptOccurred(void)
926 if (Handlers[SIGINT].tripped) {
927 #ifdef WITH_THREAD
928 if (PyThread_get_thread_ident() != main_thread)
929 return 0;
930 #endif
931 Handlers[SIGINT].tripped = 0;
932 return 1;
934 return 0;
937 void
938 PyOS_AfterFork(void)
940 #ifdef WITH_THREAD
941 PyEval_ReInitThreads();
942 main_thread = PyThread_get_thread_ident();
943 main_pid = getpid();
944 _PyImport_ReInitLock();
945 PyThread_ReInitTLS();
946 #endif