Updated for 2.1b2 distribution.
[python/dscho.git] / Modules / signalmodule.c
blob0ce755f2fae2f70e2090b8c959a3813265097ee9
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_WIN32
10 #include <process.h>
11 #endif
13 #ifdef HAVE_UNISTD_H
14 #include <unistd.h>
15 #endif
17 #include <signal.h>
19 #ifndef SIG_ERR
20 #define SIG_ERR ((PyOS_sighandler_t)(-1))
21 #endif
23 #if defined(PYOS_OS2)
24 #define NSIG 12
25 #include <process.h>
26 #endif
28 #ifndef NSIG
29 # if defined(_NSIG)
30 # define NSIG _NSIG /* For BSD/SysV */
31 # elif defined(_SIGMAX)
32 # define NSIG (_SIGMAX + 1) /* For QNX */
33 # elif defined(SIGMAX)
34 # define NSIG (SIGMAX + 1) /* For djgpp */
35 # else
36 # define NSIG 64 /* Use a reasonable default value */
37 # endif
38 #endif
42 NOTES ON THE INTERACTION BETWEEN SIGNALS AND THREADS
44 When threads are supported, we want the following semantics:
46 - only the main thread can set a signal handler
47 - any thread can get a signal handler
48 - signals are only delivered to the main thread
50 I.e. we don't support "synchronous signals" like SIGFPE (catching
51 this doesn't make much sense in Python anyway) nor do we support
52 signals as a means of inter-thread communication, since not all
53 thread implementations support that (at least our thread library
54 doesn't).
56 We still have the problem that in some implementations signals
57 generated by the keyboard (e.g. SIGINT) are delivered to all
58 threads (e.g. SGI), while in others (e.g. Solaris) such signals are
59 delivered to one random thread (an intermediate possibility would
60 be to deliver it to the main thread -- POSIX?). For now, we have
61 a working implementation that works in all three cases -- the
62 handler ignores signals if getpid() isn't the same as in the main
63 thread. XXX This is a hack.
65 GNU pth is a user-space threading library, and as such, all threads
66 run within the same process. In this case, if the currently running
67 thread is not the main_thread, send the signal to the main_thread.
70 #ifdef WITH_THREAD
71 #include <sys/types.h> /* For pid_t */
72 #include "pythread.h"
73 static long main_thread;
74 static pid_t main_pid;
75 #endif
77 static struct {
78 int tripped;
79 PyObject *func;
80 } Handlers[NSIG];
82 static int is_tripped = 0; /* Speed up sigcheck() when none tripped */
84 static PyObject *DefaultHandler;
85 static PyObject *IgnoreHandler;
86 static PyObject *IntHandler;
88 /* On Solaris 8, gcc will produce a warning that the function
89 declaration is not a prototype. This is caused by the definition of
90 SIG_DFL as (void (*)())0; the correct declaration would have been
91 (void (*)(int))0. */
93 static PyOS_sighandler_t old_siginthandler = SIG_DFL;
96 static PyObject *
97 signal_default_int_handler(PyObject *self, PyObject *args)
99 PyErr_SetNone(PyExc_KeyboardInterrupt);
100 return NULL;
103 static char default_int_handler_doc[] =
104 "default_int_handler(...)\n\
106 The default handler for SIGINT instated by Python.\n\
107 It raises KeyboardInterrupt.";
110 static int
111 checksignals_witharg(void * unused)
113 return PyErr_CheckSignals();
116 static void
117 signal_handler(int sig_num)
119 #ifdef WITH_THREAD
120 #ifdef WITH_PTH
121 if (PyThread_get_thread_ident() != main_thread) {
122 pth_raise(*(pth_t *) main_thread, sig_num);
123 return;
125 #endif
126 /* See NOTES section above */
127 if (getpid() == main_pid) {
128 #endif
129 is_tripped++;
130 Handlers[sig_num].tripped = 1;
131 Py_AddPendingCall(checksignals_witharg, NULL);
132 #ifdef WITH_THREAD
134 #endif
135 #ifdef SIGCHLD
136 if (sig_num == SIGCHLD) {
137 /* To avoid infinite recursion, this signal remains
138 reset until explicit re-instated.
139 Don't clear the 'func' field as it is our pointer
140 to the Python handler... */
141 return;
143 #endif
144 #ifdef HAVE_SIGINTERRUPT
145 siginterrupt(sig_num, 1);
146 #endif
147 PyOS_setsig(sig_num, signal_handler);
151 #ifdef HAVE_ALARM
152 static PyObject *
153 signal_alarm(PyObject *self, PyObject *args)
155 int t;
156 if (!PyArg_Parse(args, "i", &t))
157 return NULL;
158 /* alarm() returns the number of seconds remaining */
159 return PyInt_FromLong(alarm(t));
162 static char alarm_doc[] =
163 "alarm(seconds)\n\
165 Arrange for SIGALRM to arrive after the given number of seconds.";
166 #endif
168 #ifdef HAVE_PAUSE
169 static PyObject *
170 signal_pause(PyObject *self, PyObject *args)
172 if (!PyArg_NoArgs(args))
173 return NULL;
175 Py_BEGIN_ALLOW_THREADS
176 (void)pause();
177 Py_END_ALLOW_THREADS
178 /* make sure that any exceptions that got raised are propagated
179 * back into Python
181 if (PyErr_CheckSignals())
182 return NULL;
184 Py_INCREF(Py_None);
185 return Py_None;
187 static char pause_doc[] =
188 "pause()\n\
190 Wait until a signal arrives.";
192 #endif
195 static PyObject *
196 signal_signal(PyObject *self, PyObject *args)
198 PyObject *obj;
199 int sig_num;
200 PyObject *old_handler;
201 void (*func)(int);
202 if (!PyArg_Parse(args, "(iO)", &sig_num, &obj))
203 return NULL;
204 #ifdef WITH_THREAD
205 if (PyThread_get_thread_ident() != main_thread) {
206 PyErr_SetString(PyExc_ValueError,
207 "signal only works in main thread");
208 return NULL;
210 #endif
211 if (sig_num < 1 || sig_num >= NSIG) {
212 PyErr_SetString(PyExc_ValueError,
213 "signal number out of range");
214 return NULL;
216 if (obj == IgnoreHandler)
217 func = SIG_IGN;
218 else if (obj == DefaultHandler)
219 func = SIG_DFL;
220 else if (!PyCallable_Check(obj)) {
221 PyErr_SetString(PyExc_TypeError,
222 "signal handler must be signal.SIG_IGN, signal.SIG_DFL, or a callable object");
223 return NULL;
225 else
226 func = signal_handler;
227 #ifdef HAVE_SIGINTERRUPT
228 siginterrupt(sig_num, 1);
229 #endif
230 if (PyOS_setsig(sig_num, func) == SIG_ERR) {
231 PyErr_SetFromErrno(PyExc_RuntimeError);
232 return NULL;
234 old_handler = Handlers[sig_num].func;
235 Handlers[sig_num].tripped = 0;
236 Py_INCREF(obj);
237 Handlers[sig_num].func = obj;
238 return old_handler;
241 static char signal_doc[] =
242 "signal(sig, action) -> action\n\
244 Set the action for the given signal. The action can be SIG_DFL,\n\
245 SIG_IGN, or a callable Python object. The previous action is\n\
246 returned. See getsignal() for possible return values.\n\
248 *** IMPORTANT NOTICE ***\n\
249 A signal handler function is called with two arguments:\n\
250 the first is the signal number, the second is the interrupted stack frame.";
253 static PyObject *
254 signal_getsignal(PyObject *self, PyObject *args)
256 int sig_num;
257 PyObject *old_handler;
258 if (!PyArg_Parse(args, "i", &sig_num))
259 return NULL;
260 if (sig_num < 1 || sig_num >= NSIG) {
261 PyErr_SetString(PyExc_ValueError,
262 "signal number out of range");
263 return NULL;
265 old_handler = Handlers[sig_num].func;
266 Py_INCREF(old_handler);
267 return old_handler;
270 static char getsignal_doc[] =
271 "getsignal(sig) -> action\n\
273 Return the current action for the given signal. The return value can be:\n\
274 SIG_IGN -- if the signal is being ignored\n\
275 SIG_DFL -- if the default action for the signal is in effect\n\
276 None -- if an unknown handler is in effect\n\
277 anything else -- the callable Python object used as a handler\n\
281 /* List of functions defined in the module */
282 static PyMethodDef signal_methods[] = {
283 #ifdef HAVE_ALARM
284 {"alarm", signal_alarm, METH_OLDARGS, alarm_doc},
285 #endif
286 {"signal", signal_signal, METH_OLDARGS, signal_doc},
287 {"getsignal", signal_getsignal, METH_OLDARGS, getsignal_doc},
288 #ifdef HAVE_PAUSE
289 {"pause", signal_pause, METH_OLDARGS, pause_doc},
290 #endif
291 {"default_int_handler", signal_default_int_handler,
292 METH_OLDARGS, default_int_handler_doc},
293 {NULL, NULL} /* sentinel */
297 static char module_doc[] =
298 "This module provides mechanisms to use signal handlers in Python.\n\
300 Functions:\n\
302 alarm() -- cause SIGALRM after a specified time [Unix only]\n\
303 signal() -- set the action for a given signal\n\
304 getsignal() -- get the signal action for a given signal\n\
305 pause() -- wait until a signal arrives [Unix only]\n\
306 default_int_handler() -- default SIGINT handler\n\
308 Constants:\n\
310 SIG_DFL -- used to refer to the system default handler\n\
311 SIG_IGN -- used to ignore the signal\n\
312 NSIG -- number of defined signals\n\
314 SIGINT, SIGTERM, etc. -- signal numbers\n\
316 *** IMPORTANT NOTICE ***\n\
317 A signal handler function is called with two arguments:\n\
318 the first is the signal number, the second is the interrupted stack frame.";
320 DL_EXPORT(void)
321 initsignal(void)
323 PyObject *m, *d, *x;
324 int i;
326 #ifdef WITH_THREAD
327 main_thread = PyThread_get_thread_ident();
328 main_pid = getpid();
329 #endif
331 /* Create the module and add the functions */
332 m = Py_InitModule3("signal", signal_methods, module_doc);
334 /* Add some symbolic constants to the module */
335 d = PyModule_GetDict(m);
337 x = DefaultHandler = PyLong_FromVoidPtr((void *)SIG_DFL);
338 if (!x || PyDict_SetItemString(d, "SIG_DFL", x) < 0)
339 goto finally;
341 x = IgnoreHandler = PyLong_FromVoidPtr((void *)SIG_IGN);
342 if (!x || PyDict_SetItemString(d, "SIG_IGN", x) < 0)
343 goto finally;
345 x = PyInt_FromLong((long)NSIG);
346 if (!x || PyDict_SetItemString(d, "NSIG", x) < 0)
347 goto finally;
348 Py_DECREF(x);
350 x = IntHandler = PyDict_GetItemString(d, "default_int_handler");
351 if (!x)
352 goto finally;
353 Py_INCREF(IntHandler);
355 Handlers[0].tripped = 0;
356 for (i = 1; i < NSIG; i++) {
357 void (*t)(int);
358 t = PyOS_getsig(i);
359 Handlers[i].tripped = 0;
360 if (t == SIG_DFL)
361 Handlers[i].func = DefaultHandler;
362 else if (t == SIG_IGN)
363 Handlers[i].func = IgnoreHandler;
364 else
365 Handlers[i].func = Py_None; /* None of our business */
366 Py_INCREF(Handlers[i].func);
368 if (Handlers[SIGINT].func == DefaultHandler) {
369 /* Install default int handler */
370 Py_INCREF(IntHandler);
371 Py_DECREF(Handlers[SIGINT].func);
372 Handlers[SIGINT].func = IntHandler;
373 old_siginthandler = PyOS_setsig(SIGINT, &signal_handler);
376 #ifdef SIGHUP
377 x = PyInt_FromLong(SIGHUP);
378 PyDict_SetItemString(d, "SIGHUP", x);
379 Py_XDECREF(x);
380 #endif
381 #ifdef SIGINT
382 x = PyInt_FromLong(SIGINT);
383 PyDict_SetItemString(d, "SIGINT", x);
384 Py_XDECREF(x);
385 #endif
386 #ifdef SIGQUIT
387 x = PyInt_FromLong(SIGQUIT);
388 PyDict_SetItemString(d, "SIGQUIT", x);
389 Py_XDECREF(x);
390 #endif
391 #ifdef SIGILL
392 x = PyInt_FromLong(SIGILL);
393 PyDict_SetItemString(d, "SIGILL", x);
394 Py_XDECREF(x);
395 #endif
396 #ifdef SIGTRAP
397 x = PyInt_FromLong(SIGTRAP);
398 PyDict_SetItemString(d, "SIGTRAP", x);
399 Py_XDECREF(x);
400 #endif
401 #ifdef SIGIOT
402 x = PyInt_FromLong(SIGIOT);
403 PyDict_SetItemString(d, "SIGIOT", x);
404 Py_XDECREF(x);
405 #endif
406 #ifdef SIGABRT
407 x = PyInt_FromLong(SIGABRT);
408 PyDict_SetItemString(d, "SIGABRT", x);
409 Py_XDECREF(x);
410 #endif
411 #ifdef SIGEMT
412 x = PyInt_FromLong(SIGEMT);
413 PyDict_SetItemString(d, "SIGEMT", x);
414 Py_XDECREF(x);
415 #endif
416 #ifdef SIGFPE
417 x = PyInt_FromLong(SIGFPE);
418 PyDict_SetItemString(d, "SIGFPE", x);
419 Py_XDECREF(x);
420 #endif
421 #ifdef SIGKILL
422 x = PyInt_FromLong(SIGKILL);
423 PyDict_SetItemString(d, "SIGKILL", x);
424 Py_XDECREF(x);
425 #endif
426 #ifdef SIGBUS
427 x = PyInt_FromLong(SIGBUS);
428 PyDict_SetItemString(d, "SIGBUS", x);
429 Py_XDECREF(x);
430 #endif
431 #ifdef SIGSEGV
432 x = PyInt_FromLong(SIGSEGV);
433 PyDict_SetItemString(d, "SIGSEGV", x);
434 Py_XDECREF(x);
435 #endif
436 #ifdef SIGSYS
437 x = PyInt_FromLong(SIGSYS);
438 PyDict_SetItemString(d, "SIGSYS", x);
439 Py_XDECREF(x);
440 #endif
441 #ifdef SIGPIPE
442 x = PyInt_FromLong(SIGPIPE);
443 PyDict_SetItemString(d, "SIGPIPE", x);
444 Py_XDECREF(x);
445 #endif
446 #ifdef SIGALRM
447 x = PyInt_FromLong(SIGALRM);
448 PyDict_SetItemString(d, "SIGALRM", x);
449 Py_XDECREF(x);
450 #endif
451 #ifdef SIGTERM
452 x = PyInt_FromLong(SIGTERM);
453 PyDict_SetItemString(d, "SIGTERM", x);
454 Py_XDECREF(x);
455 #endif
456 #ifdef SIGUSR1
457 x = PyInt_FromLong(SIGUSR1);
458 PyDict_SetItemString(d, "SIGUSR1", x);
459 Py_XDECREF(x);
460 #endif
461 #ifdef SIGUSR2
462 x = PyInt_FromLong(SIGUSR2);
463 PyDict_SetItemString(d, "SIGUSR2", x);
464 Py_XDECREF(x);
465 #endif
466 #ifdef SIGCLD
467 x = PyInt_FromLong(SIGCLD);
468 PyDict_SetItemString(d, "SIGCLD", x);
469 Py_XDECREF(x);
470 #endif
471 #ifdef SIGCHLD
472 x = PyInt_FromLong(SIGCHLD);
473 PyDict_SetItemString(d, "SIGCHLD", x);
474 Py_XDECREF(x);
475 #endif
476 #ifdef SIGPWR
477 x = PyInt_FromLong(SIGPWR);
478 PyDict_SetItemString(d, "SIGPWR", x);
479 Py_XDECREF(x);
480 #endif
481 #ifdef SIGIO
482 x = PyInt_FromLong(SIGIO);
483 PyDict_SetItemString(d, "SIGIO", x);
484 Py_XDECREF(x);
485 #endif
486 #ifdef SIGURG
487 x = PyInt_FromLong(SIGURG);
488 PyDict_SetItemString(d, "SIGURG", x);
489 Py_XDECREF(x);
490 #endif
491 #ifdef SIGWINCH
492 x = PyInt_FromLong(SIGWINCH);
493 PyDict_SetItemString(d, "SIGWINCH", x);
494 Py_XDECREF(x);
495 #endif
496 #ifdef SIGPOLL
497 x = PyInt_FromLong(SIGPOLL);
498 PyDict_SetItemString(d, "SIGPOLL", x);
499 Py_XDECREF(x);
500 #endif
501 #ifdef SIGSTOP
502 x = PyInt_FromLong(SIGSTOP);
503 PyDict_SetItemString(d, "SIGSTOP", x);
504 Py_XDECREF(x);
505 #endif
506 #ifdef SIGTSTP
507 x = PyInt_FromLong(SIGTSTP);
508 PyDict_SetItemString(d, "SIGTSTP", x);
509 Py_XDECREF(x);
510 #endif
511 #ifdef SIGCONT
512 x = PyInt_FromLong(SIGCONT);
513 PyDict_SetItemString(d, "SIGCONT", x);
514 Py_XDECREF(x);
515 #endif
516 #ifdef SIGTTIN
517 x = PyInt_FromLong(SIGTTIN);
518 PyDict_SetItemString(d, "SIGTTIN", x);
519 Py_XDECREF(x);
520 #endif
521 #ifdef SIGTTOU
522 x = PyInt_FromLong(SIGTTOU);
523 PyDict_SetItemString(d, "SIGTTOU", x);
524 Py_XDECREF(x);
525 #endif
526 #ifdef SIGVTALRM
527 x = PyInt_FromLong(SIGVTALRM);
528 PyDict_SetItemString(d, "SIGVTALRM", x);
529 Py_XDECREF(x);
530 #endif
531 #ifdef SIGPROF
532 x = PyInt_FromLong(SIGPROF);
533 PyDict_SetItemString(d, "SIGPROF", x);
534 Py_XDECREF(x);
535 #endif
536 #ifdef SIGXCPU
537 x = PyInt_FromLong(SIGXCPU);
538 PyDict_SetItemString(d, "SIGXCPU", x);
539 Py_XDECREF(x);
540 #endif
541 #ifdef SIGXFSZ
542 x = PyInt_FromLong(SIGXFSZ);
543 PyDict_SetItemString(d, "SIGXFSZ", x);
544 Py_XDECREF(x);
545 #endif
546 if (!PyErr_Occurred())
547 return;
549 /* Check for errors */
550 finally:
551 return;
554 static void
555 finisignal(void)
557 int i;
558 PyObject *func;
560 PyOS_setsig(SIGINT, old_siginthandler);
561 old_siginthandler = SIG_DFL;
563 for (i = 1; i < NSIG; i++) {
564 func = Handlers[i].func;
565 Handlers[i].tripped = 0;
566 Handlers[i].func = NULL;
567 if (i != SIGINT && func != NULL && func != Py_None &&
568 func != DefaultHandler && func != IgnoreHandler)
569 PyOS_setsig(i, SIG_DFL);
570 Py_XDECREF(func);
573 Py_XDECREF(IntHandler);
574 IntHandler = NULL;
575 Py_XDECREF(DefaultHandler);
576 DefaultHandler = NULL;
577 Py_XDECREF(IgnoreHandler);
578 IgnoreHandler = NULL;
582 /* Declared in pyerrors.h */
584 PyErr_CheckSignals(void)
586 int i;
587 PyObject *f;
589 if (!is_tripped)
590 return 0;
591 #ifdef WITH_THREAD
592 if (PyThread_get_thread_ident() != main_thread)
593 return 0;
594 #endif
595 if (!(f = PyEval_GetFrame()))
596 f = Py_None;
598 for (i = 1; i < NSIG; i++) {
599 if (Handlers[i].tripped) {
600 PyObject *result = NULL;
601 PyObject *arglist = Py_BuildValue("(iO)", i, f);
602 Handlers[i].tripped = 0;
604 if (arglist) {
605 result = PyEval_CallObject(Handlers[i].func,
606 arglist);
607 Py_DECREF(arglist);
609 if (!result)
610 return -1;
612 Py_DECREF(result);
615 is_tripped = 0;
616 return 0;
620 /* Replacements for intrcheck.c functionality
621 * Declared in pyerrors.h
623 void
624 PyErr_SetInterrupt(void)
626 is_tripped++;
627 Handlers[SIGINT].tripped = 1;
628 Py_AddPendingCall((int (*)(void *))PyErr_CheckSignals, NULL);
631 void
632 PyOS_InitInterrupts(void)
634 initsignal();
635 _PyImport_FixupExtension("signal", "signal");
638 void
639 PyOS_FiniInterrupts(void)
641 finisignal();
645 PyOS_InterruptOccurred(void)
647 if (Handlers[SIGINT].tripped) {
648 #ifdef WITH_THREAD
649 if (PyThread_get_thread_ident() != main_thread)
650 return 0;
651 #endif
652 Handlers[SIGINT].tripped = 0;
653 return 1;
655 return 0;
658 void
659 PyOS_AfterFork(void)
661 #ifdef WITH_THREAD
662 PyEval_ReInitThreads();
663 main_thread = PyThread_get_thread_ident();
664 main_pid = getpid();
665 #endif