This commit was manufactured by cvs2svn to create tag 'r23a1-fork'.
[python/dscho.git] / Modules / signalmodule.c
blob0f9574fe29b4f857b542c97c8ce2392fe11b6890
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 #ifndef SIG_ERR
16 #define SIG_ERR ((PyOS_sighandler_t)(-1))
17 #endif
19 #if defined(PYOS_OS2) && !defined(PYCC_GCC)
20 #define NSIG 12
21 #include <process.h>
22 #endif
24 #ifndef NSIG
25 # if defined(_NSIG)
26 # define NSIG _NSIG /* For BSD/SysV */
27 # elif defined(_SIGMAX)
28 # define NSIG (_SIGMAX + 1) /* For QNX */
29 # elif defined(SIGMAX)
30 # define NSIG (SIGMAX + 1) /* For djgpp */
31 # else
32 # define NSIG 64 /* Use a reasonable default value */
33 # endif
34 #endif
38 NOTES ON THE INTERACTION BETWEEN SIGNALS AND THREADS
40 When threads are supported, we want the following semantics:
42 - only the main thread can set a signal handler
43 - any thread can get a signal handler
44 - signals are only delivered to the main thread
46 I.e. we don't support "synchronous signals" like SIGFPE (catching
47 this doesn't make much sense in Python anyway) nor do we support
48 signals as a means of inter-thread communication, since not all
49 thread implementations support that (at least our thread library
50 doesn't).
52 We still have the problem that in some implementations signals
53 generated by the keyboard (e.g. SIGINT) are delivered to all
54 threads (e.g. SGI), while in others (e.g. Solaris) such signals are
55 delivered to one random thread (an intermediate possibility would
56 be to deliver it to the main thread -- POSIX?). For now, we have
57 a working implementation that works in all three cases -- the
58 handler ignores signals if getpid() isn't the same as in the main
59 thread. XXX This is a hack.
61 GNU pth is a user-space threading library, and as such, all threads
62 run within the same process. In this case, if the currently running
63 thread is not the main_thread, send the signal to the main_thread.
66 #ifdef WITH_THREAD
67 #include <sys/types.h> /* For pid_t */
68 #include "pythread.h"
69 static long main_thread;
70 static pid_t main_pid;
71 #endif
73 static struct {
74 int tripped;
75 PyObject *func;
76 } Handlers[NSIG];
78 static int is_tripped = 0; /* Speed up sigcheck() when none tripped */
80 static PyObject *DefaultHandler;
81 static PyObject *IgnoreHandler;
82 static PyObject *IntHandler;
84 /* On Solaris 8, gcc will produce a warning that the function
85 declaration is not a prototype. This is caused by the definition of
86 SIG_DFL as (void (*)())0; the correct declaration would have been
87 (void (*)(int))0. */
89 static PyOS_sighandler_t old_siginthandler = SIG_DFL;
92 static PyObject *
93 signal_default_int_handler(PyObject *self, PyObject *args)
95 PyErr_SetNone(PyExc_KeyboardInterrupt);
96 return NULL;
99 PyDoc_STRVAR(default_int_handler_doc,
100 "default_int_handler(...)\n\
102 The default handler for SIGINT instated by Python.\n\
103 It raises KeyboardInterrupt.");
106 static int
107 checksignals_witharg(void * unused)
109 return PyErr_CheckSignals();
112 static void
113 signal_handler(int sig_num)
115 #ifdef WITH_THREAD
116 #ifdef WITH_PTH
117 if (PyThread_get_thread_ident() != main_thread) {
118 pth_raise(*(pth_t *) main_thread, sig_num);
119 return;
121 #endif
122 /* See NOTES section above */
123 if (getpid() == main_pid) {
124 #endif
125 is_tripped++;
126 Handlers[sig_num].tripped = 1;
127 Py_AddPendingCall(checksignals_witharg, NULL);
128 #ifdef WITH_THREAD
130 #endif
131 #ifdef SIGCHLD
132 if (sig_num == SIGCHLD) {
133 /* To avoid infinite recursion, this signal remains
134 reset until explicit re-instated.
135 Don't clear the 'func' field as it is our pointer
136 to the Python handler... */
137 return;
139 #endif
140 #ifdef HAVE_SIGINTERRUPT
141 siginterrupt(sig_num, 1);
142 #endif
143 PyOS_setsig(sig_num, signal_handler);
147 #ifdef HAVE_ALARM
148 static PyObject *
149 signal_alarm(PyObject *self, PyObject *args)
151 int t;
152 if (!PyArg_ParseTuple(args, "i:alarm", &t))
153 return NULL;
154 /* alarm() returns the number of seconds remaining */
155 return PyInt_FromLong((long)alarm(t));
158 PyDoc_STRVAR(alarm_doc,
159 "alarm(seconds)\n\
161 Arrange for SIGALRM to arrive after the given number of seconds.");
162 #endif
164 #ifdef HAVE_PAUSE
165 static PyObject *
166 signal_pause(PyObject *self)
168 Py_BEGIN_ALLOW_THREADS
169 (void)pause();
170 Py_END_ALLOW_THREADS
171 /* make sure that any exceptions that got raised are propagated
172 * back into Python
174 if (PyErr_CheckSignals())
175 return NULL;
177 Py_INCREF(Py_None);
178 return Py_None;
180 PyDoc_STRVAR(pause_doc,
181 "pause()\n\
183 Wait until a signal arrives.");
185 #endif
188 static PyObject *
189 signal_signal(PyObject *self, PyObject *args)
191 PyObject *obj;
192 int sig_num;
193 PyObject *old_handler;
194 void (*func)(int);
195 if (!PyArg_ParseTuple(args, "iO:signal", &sig_num, &obj))
196 return NULL;
197 #ifdef WITH_THREAD
198 if (PyThread_get_thread_ident() != main_thread) {
199 PyErr_SetString(PyExc_ValueError,
200 "signal only works in main thread");
201 return NULL;
203 #endif
204 if (sig_num < 1 || sig_num >= NSIG) {
205 PyErr_SetString(PyExc_ValueError,
206 "signal number out of range");
207 return NULL;
209 if (obj == IgnoreHandler)
210 func = SIG_IGN;
211 else if (obj == DefaultHandler)
212 func = SIG_DFL;
213 else if (!PyCallable_Check(obj)) {
214 PyErr_SetString(PyExc_TypeError,
215 "signal handler must be signal.SIG_IGN, signal.SIG_DFL, or a callable object");
216 return NULL;
218 else
219 func = signal_handler;
220 #ifdef HAVE_SIGINTERRUPT
221 siginterrupt(sig_num, 1);
222 #endif
223 if (PyOS_setsig(sig_num, func) == SIG_ERR) {
224 PyErr_SetFromErrno(PyExc_RuntimeError);
225 return NULL;
227 old_handler = Handlers[sig_num].func;
228 Handlers[sig_num].tripped = 0;
229 Py_INCREF(obj);
230 Handlers[sig_num].func = obj;
231 return old_handler;
234 PyDoc_STRVAR(signal_doc,
235 "signal(sig, action) -> action\n\
237 Set the action for the given signal. The action can be SIG_DFL,\n\
238 SIG_IGN, or a callable Python object. The previous action is\n\
239 returned. See getsignal() for possible return values.\n\
241 *** IMPORTANT NOTICE ***\n\
242 A signal handler function is called with two arguments:\n\
243 the first is the signal number, the second is the interrupted stack frame.");
246 static PyObject *
247 signal_getsignal(PyObject *self, PyObject *args)
249 int sig_num;
250 PyObject *old_handler;
251 if (!PyArg_ParseTuple(args, "i:getsignal", &sig_num))
252 return NULL;
253 if (sig_num < 1 || sig_num >= NSIG) {
254 PyErr_SetString(PyExc_ValueError,
255 "signal number out of range");
256 return NULL;
258 old_handler = Handlers[sig_num].func;
259 Py_INCREF(old_handler);
260 return old_handler;
263 PyDoc_STRVAR(getsignal_doc,
264 "getsignal(sig) -> action\n\
266 Return the current action for the given signal. The return value can be:\n\
267 SIG_IGN -- if the signal is being ignored\n\
268 SIG_DFL -- if the default action for the signal is in effect\n\
269 None -- if an unknown handler is in effect\n\
270 anything else -- the callable Python object used as a handler");
272 #ifdef HAVE_SIGPROCMASK /* we assume that having SIGPROCMASK is enough
273 to guarantee full POSIX signal handling */
274 /* returns 0 for success, <0 for failure (with exception set) */
275 static int
276 _signal_list_to_sigset(PyObject* seq, sigset_t* set, char* mesg)
278 int i, len, val;
280 seq = PySequence_Fast(seq, mesg);
281 if (!seq)
282 return -1;
284 len = PySequence_Fast_GET_SIZE(seq);
286 sigemptyset(set);
288 for (i = 0; i < len; i++) {
289 val = PyInt_AsLong(PySequence_Fast_GET_ITEM(seq, i));
290 if (val == -1 && PyErr_Occurred()) {
291 Py_DECREF(seq);
292 return -1;
294 if (sigaddset(set, val) < 0) {
295 Py_DECREF(seq);
296 PyErr_SetFromErrno(PyExc_ValueError);
297 return -1;
301 Py_DECREF(seq);
302 return 0;
305 static PyObject*
306 _signal_sigset_to_list(sigset_t* set)
308 PyObject* ret;
309 PyObject* ob;
310 int i;
312 ret = PyList_New(0);
313 if (!ret)
314 return NULL;
316 for (i = 1; i < NSIG; i++) {
317 if (sigismember(set, i)) {
318 ob = PyInt_FromLong(i);
319 if (!ob) {
320 Py_DECREF(ret);
321 return NULL;
323 PyList_Append(ret, ob);
324 Py_DECREF(ob);
328 return ret;
331 static PyObject*
332 signal_sigprocmask(PyObject* self, PyObject* args)
334 int how;
335 sigset_t newset, oldset;
336 PyObject* seq;
338 if (!PyArg_ParseTuple(args, "iO", &how, &seq))
339 return NULL;
341 if (_signal_list_to_sigset(seq, &newset,
342 "sigprocmask requires a sequence") < 0)
343 return NULL;
345 if (sigprocmask(how, &newset, &oldset) < 0) {
346 return PyErr_SetFromErrno(PyExc_ValueError);
349 if (PyErr_CheckSignals())
350 return NULL;
352 return _signal_sigset_to_list(&oldset);
355 PyDoc_STRVAR(sigprocmask_doc,
356 "sigprocmask(how, sigset) -> sigset\n\
358 Change the list of currently blocked signals. The parameter how should be\n\
359 one of SIG_BLOCK, SIG_UNBLOCK or SIG_SETMASK and sigset should be a\n\
360 sequence of signal numbers. The behaviour of the call depends on the value\n\
361 of how:\n\
363 SIG_BLOCK\n\
364 The set of blocked signals is the union of the current set and the\n\
365 sigset argument.\n\
366 SIG_UNBLOCK\n\
367 The signals in sigset are removed from the current set of blocked\n\
368 signals. It is legal to attempt to unblock a signal which is not\n\
369 blocked.\n\
370 SIG_SETMASK\n\
371 The set of blocked signals is set to the argument set.\n\
373 A list contating the numbers of the previously blocked signals is returned.");
375 static PyObject*
376 signal_sigpending(PyObject* self)
378 sigset_t set;
380 if (sigpending(&set) < 0) {
381 return PyErr_SetFromErrno(PyExc_ValueError);
384 return _signal_sigset_to_list(&set);
387 PyDoc_STRVAR(sigpending_doc,
388 "sigpending() -> sigset\n\
390 Return the set of pending signals, i.e. a list containing the numbers of\n\
391 those signals that have been raised while blocked.");
393 static PyObject*
394 signal_sigsuspend(PyObject* self, PyObject* arg)
396 sigset_t set;
398 if (_signal_list_to_sigset(arg, &set,
399 "sigsuspend requires a sequence") < 0)
400 return NULL;
402 Py_BEGIN_ALLOW_THREADS
403 sigsuspend(&set);
404 Py_END_ALLOW_THREADS
406 if (PyErr_CheckSignals())
407 return NULL;
409 Py_INCREF(Py_None);
410 return Py_None;
413 PyDoc_STRVAR(sigsuspend_doc,
414 "sigsuspend(sigset) -> None\n\
416 Temporarily replace the signal mask with sigset (which should be a sequence\n\
417 of signal numbers) and suspend the process until a signal is received.");
418 #endif
420 /* List of functions defined in the module */
421 static PyMethodDef signal_methods[] = {
422 #ifdef HAVE_ALARM
423 {"alarm", signal_alarm, METH_VARARGS, alarm_doc},
424 #endif
425 {"signal", signal_signal, METH_VARARGS, signal_doc},
426 {"getsignal", signal_getsignal, METH_VARARGS, getsignal_doc},
427 #ifdef HAVE_PAUSE
428 {"pause", (PyCFunction)signal_pause,
429 METH_NOARGS,pause_doc},
430 #endif
431 {"default_int_handler", signal_default_int_handler,
432 METH_VARARGS, default_int_handler_doc},
433 #ifdef HAVE_SIGPROCMASK
434 {"sigprocmask", (PyCFunction)signal_sigprocmask,
435 METH_VARARGS, sigprocmask_doc},
436 {"sigpending", (PyCFunction)signal_sigpending,
437 METH_NOARGS, sigpending_doc},
438 {"sigsuspend", (PyCFunction)signal_sigsuspend,
439 METH_O, sigsuspend_doc},
440 #endif
441 {NULL, NULL} /* sentinel */
445 PyDoc_STRVAR(module_doc,
446 "This module provides mechanisms to use signal handlers in Python.\n\
448 Functions:\n\
450 alarm() -- cause SIGALRM after a specified time [Unix only]\n\
451 signal() -- set the action for a given signal\n\
452 getsignal() -- get the signal action for a given signal\n\
453 pause() -- wait until a signal arrives [Unix only]\n\
454 default_int_handler() -- default SIGINT handler\n\
456 sigpending() |\n\
457 sigprocmask() |-- posix signal mask handling [Unix only]\n\
458 sigsuspend() |\n\
460 Constants:\n\
462 SIG_DFL -- used to refer to the system default handler\n\
463 SIG_IGN -- used to ignore the signal\n\
464 NSIG -- number of defined signals\n\
466 SIGINT, SIGTERM, etc. -- signal numbers\n\
468 *** IMPORTANT NOTICE ***\n\
469 A signal handler function is called with two arguments:\n\
470 the first is the signal number, the second is the interrupted stack frame.");
472 PyMODINIT_FUNC
473 initsignal(void)
475 PyObject *m, *d, *x;
476 int i;
478 #ifdef WITH_THREAD
479 main_thread = PyThread_get_thread_ident();
480 main_pid = getpid();
481 #endif
483 /* Create the module and add the functions */
484 m = Py_InitModule3("signal", signal_methods, module_doc);
486 /* Add some symbolic constants to the module */
487 d = PyModule_GetDict(m);
489 x = DefaultHandler = PyLong_FromVoidPtr((void *)SIG_DFL);
490 if (!x || PyDict_SetItemString(d, "SIG_DFL", x) < 0)
491 goto finally;
493 x = IgnoreHandler = PyLong_FromVoidPtr((void *)SIG_IGN);
494 if (!x || PyDict_SetItemString(d, "SIG_IGN", x) < 0)
495 goto finally;
497 x = PyInt_FromLong((long)NSIG);
498 if (!x || PyDict_SetItemString(d, "NSIG", x) < 0)
499 goto finally;
500 Py_DECREF(x);
502 x = IntHandler = PyDict_GetItemString(d, "default_int_handler");
503 if (!x)
504 goto finally;
505 Py_INCREF(IntHandler);
507 Handlers[0].tripped = 0;
508 for (i = 1; i < NSIG; i++) {
509 void (*t)(int);
510 t = PyOS_getsig(i);
511 Handlers[i].tripped = 0;
512 if (t == SIG_DFL)
513 Handlers[i].func = DefaultHandler;
514 else if (t == SIG_IGN)
515 Handlers[i].func = IgnoreHandler;
516 else
517 Handlers[i].func = Py_None; /* None of our business */
518 Py_INCREF(Handlers[i].func);
520 if (Handlers[SIGINT].func == DefaultHandler) {
521 /* Install default int handler */
522 Py_INCREF(IntHandler);
523 Py_DECREF(Handlers[SIGINT].func);
524 Handlers[SIGINT].func = IntHandler;
525 old_siginthandler = PyOS_setsig(SIGINT, signal_handler);
528 #ifdef SIGHUP
529 x = PyInt_FromLong(SIGHUP);
530 PyDict_SetItemString(d, "SIGHUP", x);
531 Py_XDECREF(x);
532 #endif
533 #ifdef SIGINT
534 x = PyInt_FromLong(SIGINT);
535 PyDict_SetItemString(d, "SIGINT", x);
536 Py_XDECREF(x);
537 #endif
538 #ifdef SIGBREAK
539 x = PyInt_FromLong(SIGBREAK);
540 PyDict_SetItemString(d, "SIGBREAK", x);
541 Py_XDECREF(x);
542 #endif
543 #ifdef SIGQUIT
544 x = PyInt_FromLong(SIGQUIT);
545 PyDict_SetItemString(d, "SIGQUIT", x);
546 Py_XDECREF(x);
547 #endif
548 #ifdef SIGILL
549 x = PyInt_FromLong(SIGILL);
550 PyDict_SetItemString(d, "SIGILL", x);
551 Py_XDECREF(x);
552 #endif
553 #ifdef SIGTRAP
554 x = PyInt_FromLong(SIGTRAP);
555 PyDict_SetItemString(d, "SIGTRAP", x);
556 Py_XDECREF(x);
557 #endif
558 #ifdef SIGIOT
559 x = PyInt_FromLong(SIGIOT);
560 PyDict_SetItemString(d, "SIGIOT", x);
561 Py_XDECREF(x);
562 #endif
563 #ifdef SIGABRT
564 x = PyInt_FromLong(SIGABRT);
565 PyDict_SetItemString(d, "SIGABRT", x);
566 Py_XDECREF(x);
567 #endif
568 #ifdef SIGEMT
569 x = PyInt_FromLong(SIGEMT);
570 PyDict_SetItemString(d, "SIGEMT", x);
571 Py_XDECREF(x);
572 #endif
573 #ifdef SIGFPE
574 x = PyInt_FromLong(SIGFPE);
575 PyDict_SetItemString(d, "SIGFPE", x);
576 Py_XDECREF(x);
577 #endif
578 #ifdef SIGKILL
579 x = PyInt_FromLong(SIGKILL);
580 PyDict_SetItemString(d, "SIGKILL", x);
581 Py_XDECREF(x);
582 #endif
583 #ifdef SIGBUS
584 x = PyInt_FromLong(SIGBUS);
585 PyDict_SetItemString(d, "SIGBUS", x);
586 Py_XDECREF(x);
587 #endif
588 #ifdef SIGSEGV
589 x = PyInt_FromLong(SIGSEGV);
590 PyDict_SetItemString(d, "SIGSEGV", x);
591 Py_XDECREF(x);
592 #endif
593 #ifdef SIGSYS
594 x = PyInt_FromLong(SIGSYS);
595 PyDict_SetItemString(d, "SIGSYS", x);
596 Py_XDECREF(x);
597 #endif
598 #ifdef SIGPIPE
599 x = PyInt_FromLong(SIGPIPE);
600 PyDict_SetItemString(d, "SIGPIPE", x);
601 Py_XDECREF(x);
602 #endif
603 #ifdef SIGALRM
604 x = PyInt_FromLong(SIGALRM);
605 PyDict_SetItemString(d, "SIGALRM", x);
606 Py_XDECREF(x);
607 #endif
608 #ifdef SIGTERM
609 x = PyInt_FromLong(SIGTERM);
610 PyDict_SetItemString(d, "SIGTERM", x);
611 Py_XDECREF(x);
612 #endif
613 #ifdef SIGUSR1
614 x = PyInt_FromLong(SIGUSR1);
615 PyDict_SetItemString(d, "SIGUSR1", x);
616 Py_XDECREF(x);
617 #endif
618 #ifdef SIGUSR2
619 x = PyInt_FromLong(SIGUSR2);
620 PyDict_SetItemString(d, "SIGUSR2", x);
621 Py_XDECREF(x);
622 #endif
623 #ifdef SIGCLD
624 x = PyInt_FromLong(SIGCLD);
625 PyDict_SetItemString(d, "SIGCLD", x);
626 Py_XDECREF(x);
627 #endif
628 #ifdef SIGCHLD
629 x = PyInt_FromLong(SIGCHLD);
630 PyDict_SetItemString(d, "SIGCHLD", x);
631 Py_XDECREF(x);
632 #endif
633 #ifdef SIGPWR
634 x = PyInt_FromLong(SIGPWR);
635 PyDict_SetItemString(d, "SIGPWR", x);
636 Py_XDECREF(x);
637 #endif
638 #ifdef SIGIO
639 x = PyInt_FromLong(SIGIO);
640 PyDict_SetItemString(d, "SIGIO", x);
641 Py_XDECREF(x);
642 #endif
643 #ifdef SIGURG
644 x = PyInt_FromLong(SIGURG);
645 PyDict_SetItemString(d, "SIGURG", x);
646 Py_XDECREF(x);
647 #endif
648 #ifdef SIGWINCH
649 x = PyInt_FromLong(SIGWINCH);
650 PyDict_SetItemString(d, "SIGWINCH", x);
651 Py_XDECREF(x);
652 #endif
653 #ifdef SIGPOLL
654 x = PyInt_FromLong(SIGPOLL);
655 PyDict_SetItemString(d, "SIGPOLL", x);
656 Py_XDECREF(x);
657 #endif
658 #ifdef SIGSTOP
659 x = PyInt_FromLong(SIGSTOP);
660 PyDict_SetItemString(d, "SIGSTOP", x);
661 Py_XDECREF(x);
662 #endif
663 #ifdef SIGTSTP
664 x = PyInt_FromLong(SIGTSTP);
665 PyDict_SetItemString(d, "SIGTSTP", x);
666 Py_XDECREF(x);
667 #endif
668 #ifdef SIGCONT
669 x = PyInt_FromLong(SIGCONT);
670 PyDict_SetItemString(d, "SIGCONT", x);
671 Py_XDECREF(x);
672 #endif
673 #ifdef SIGTTIN
674 x = PyInt_FromLong(SIGTTIN);
675 PyDict_SetItemString(d, "SIGTTIN", x);
676 Py_XDECREF(x);
677 #endif
678 #ifdef SIGTTOU
679 x = PyInt_FromLong(SIGTTOU);
680 PyDict_SetItemString(d, "SIGTTOU", x);
681 Py_XDECREF(x);
682 #endif
683 #ifdef SIGVTALRM
684 x = PyInt_FromLong(SIGVTALRM);
685 PyDict_SetItemString(d, "SIGVTALRM", x);
686 Py_XDECREF(x);
687 #endif
688 #ifdef SIGPROF
689 x = PyInt_FromLong(SIGPROF);
690 PyDict_SetItemString(d, "SIGPROF", x);
691 Py_XDECREF(x);
692 #endif
693 #ifdef SIGXCPU
694 x = PyInt_FromLong(SIGXCPU);
695 PyDict_SetItemString(d, "SIGXCPU", x);
696 Py_XDECREF(x);
697 #endif
698 #ifdef SIGXFSZ
699 x = PyInt_FromLong(SIGXFSZ);
700 PyDict_SetItemString(d, "SIGXFSZ", x);
701 Py_XDECREF(x);
702 #endif
703 #ifdef SIGINFO
704 x = PyInt_FromLong(SIGINFO);
705 PyDict_SetItemString(d, "SIGINFO", x);
706 Py_XDECREF(x);
707 #endif
708 #ifdef HAVE_SIGPROCMASK
709 x = PyInt_FromLong(SIG_BLOCK);
710 PyDict_SetItemString(d, "SIG_BLOCK", x);
711 Py_XDECREF(x);
712 x = PyInt_FromLong(SIG_UNBLOCK);
713 PyDict_SetItemString(d, "SIG_UNBLOCK", x);
714 Py_XDECREF(x);
715 x = PyInt_FromLong(SIG_SETMASK);
716 PyDict_SetItemString(d, "SIG_SETMASK", x);
717 Py_XDECREF(x);
718 #endif
720 if (!PyErr_Occurred())
721 return;
723 /* Check for errors */
724 finally:
725 return;
728 static void
729 finisignal(void)
731 int i;
732 PyObject *func;
734 PyOS_setsig(SIGINT, old_siginthandler);
735 old_siginthandler = SIG_DFL;
737 for (i = 1; i < NSIG; i++) {
738 func = Handlers[i].func;
739 Handlers[i].tripped = 0;
740 Handlers[i].func = NULL;
741 if (i != SIGINT && func != NULL && func != Py_None &&
742 func != DefaultHandler && func != IgnoreHandler)
743 PyOS_setsig(i, SIG_DFL);
744 Py_XDECREF(func);
747 Py_XDECREF(IntHandler);
748 IntHandler = NULL;
749 Py_XDECREF(DefaultHandler);
750 DefaultHandler = NULL;
751 Py_XDECREF(IgnoreHandler);
752 IgnoreHandler = NULL;
756 /* Declared in pyerrors.h */
758 PyErr_CheckSignals(void)
760 int i;
761 PyObject *f;
763 if (!is_tripped)
764 return 0;
765 #ifdef WITH_THREAD
766 if (PyThread_get_thread_ident() != main_thread)
767 return 0;
768 #endif
769 if (!(f = PyEval_GetFrame()))
770 f = Py_None;
772 for (i = 1; i < NSIG; i++) {
773 if (Handlers[i].tripped) {
774 PyObject *result = NULL;
775 PyObject *arglist = Py_BuildValue("(iO)", i, f);
776 Handlers[i].tripped = 0;
778 if (arglist) {
779 result = PyEval_CallObject(Handlers[i].func,
780 arglist);
781 Py_DECREF(arglist);
783 if (!result)
784 return -1;
786 Py_DECREF(result);
789 is_tripped = 0;
790 return 0;
794 /* Replacements for intrcheck.c functionality
795 * Declared in pyerrors.h
797 void
798 PyErr_SetInterrupt(void)
800 is_tripped++;
801 Handlers[SIGINT].tripped = 1;
802 Py_AddPendingCall((int (*)(void *))PyErr_CheckSignals, NULL);
805 void
806 PyOS_InitInterrupts(void)
808 initsignal();
809 _PyImport_FixupExtension("signal", "signal");
812 void
813 PyOS_FiniInterrupts(void)
815 finisignal();
819 PyOS_InterruptOccurred(void)
821 if (Handlers[SIGINT].tripped) {
822 #ifdef WITH_THREAD
823 if (PyThread_get_thread_ident() != main_thread)
824 return 0;
825 #endif
826 Handlers[SIGINT].tripped = 0;
827 return 1;
829 return 0;
832 void
833 PyOS_AfterFork(void)
835 #ifdef WITH_THREAD
836 PyEval_ReInitThreads();
837 main_thread = PyThread_get_thread_ident();
838 main_pid = getpid();
839 #endif