Added section on passing contextual information to logging and documentation for...
[python.git] / Modules / signalmodule.c
blob9dec24f85e43c8a8081b5c9d15ff1e3bcfe18fd9
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>
17 #ifndef SIG_ERR
18 #define SIG_ERR ((PyOS_sighandler_t)(-1))
19 #endif
21 #if defined(PYOS_OS2) && !defined(PYCC_GCC)
22 #define NSIG 12
23 #include <process.h>
24 #endif
26 #ifndef NSIG
27 # if defined(_NSIG)
28 # define NSIG _NSIG /* For BSD/SysV */
29 # elif defined(_SIGMAX)
30 # define NSIG (_SIGMAX + 1) /* For QNX */
31 # elif defined(SIGMAX)
32 # define NSIG (SIGMAX + 1) /* For djgpp */
33 # else
34 # define NSIG 64 /* Use a reasonable default value */
35 # endif
36 #endif
40 NOTES ON THE INTERACTION BETWEEN SIGNALS AND THREADS
42 When threads are supported, we want the following semantics:
44 - only the main thread can set a signal handler
45 - any thread can get a signal handler
46 - signals are only delivered to the main thread
48 I.e. we don't support "synchronous signals" like SIGFPE (catching
49 this doesn't make much sense in Python anyway) nor do we support
50 signals as a means of inter-thread communication, since not all
51 thread implementations support that (at least our thread library
52 doesn't).
54 We still have the problem that in some implementations signals
55 generated by the keyboard (e.g. SIGINT) are delivered to all
56 threads (e.g. SGI), while in others (e.g. Solaris) such signals are
57 delivered to one random thread (an intermediate possibility would
58 be to deliver it to the main thread -- POSIX?). For now, we have
59 a working implementation that works in all three cases -- the
60 handler ignores signals if getpid() isn't the same as in the main
61 thread. XXX This is a hack.
63 GNU pth is a user-space threading library, and as such, all threads
64 run within the same process. In this case, if the currently running
65 thread is not the main_thread, send the signal to the main_thread.
68 #ifdef WITH_THREAD
69 #include <sys/types.h> /* For pid_t */
70 #include "pythread.h"
71 static long main_thread;
72 static pid_t main_pid;
73 #endif
75 static struct {
76 int tripped;
77 PyObject *func;
78 } Handlers[NSIG];
80 static sig_atomic_t wakeup_fd = -1;
82 /* Speed up sigcheck() when none tripped */
83 static volatile sig_atomic_t is_tripped = 0;
85 static PyObject *DefaultHandler;
86 static PyObject *IgnoreHandler;
87 static PyObject *IntHandler;
89 /* On Solaris 8, gcc will produce a warning that the function
90 declaration is not a prototype. This is caused by the definition of
91 SIG_DFL as (void (*)())0; the correct declaration would have been
92 (void (*)(int))0. */
94 static PyOS_sighandler_t old_siginthandler = SIG_DFL;
97 static PyObject *
98 signal_default_int_handler(PyObject *self, PyObject *args)
100 PyErr_SetNone(PyExc_KeyboardInterrupt);
101 return NULL;
104 PyDoc_STRVAR(default_int_handler_doc,
105 "default_int_handler(...)\n\
107 The default handler for SIGINT installed by Python.\n\
108 It raises KeyboardInterrupt.");
111 static int
112 checksignals_witharg(void * unused)
114 return PyErr_CheckSignals();
117 static void
118 signal_handler(int sig_num)
120 #ifdef WITH_THREAD
121 #ifdef WITH_PTH
122 if (PyThread_get_thread_ident() != main_thread) {
123 pth_raise(*(pth_t *) main_thread, sig_num);
124 return;
126 #endif
127 /* See NOTES section above */
128 if (getpid() == main_pid) {
129 #endif
130 Handlers[sig_num].tripped = 1;
131 /* Set is_tripped after setting .tripped, as it gets
132 cleared in PyErr_CheckSignals() before .tripped. */
133 is_tripped = 1;
134 Py_AddPendingCall(checksignals_witharg, NULL);
135 if (wakeup_fd != -1)
136 write(wakeup_fd, "\0", 1);
137 #ifdef WITH_THREAD
139 #endif
140 #ifdef SIGCHLD
141 if (sig_num == SIGCHLD) {
142 /* To avoid infinite recursion, this signal remains
143 reset until explicit re-instated.
144 Don't clear the 'func' field as it is our pointer
145 to the Python handler... */
146 return;
148 #endif
149 PyOS_setsig(sig_num, signal_handler);
153 #ifdef HAVE_ALARM
154 static PyObject *
155 signal_alarm(PyObject *self, PyObject *args)
157 int t;
158 if (!PyArg_ParseTuple(args, "i:alarm", &t))
159 return NULL;
160 /* alarm() returns the number of seconds remaining */
161 return PyInt_FromLong((long)alarm(t));
164 PyDoc_STRVAR(alarm_doc,
165 "alarm(seconds)\n\
167 Arrange for SIGALRM to arrive after the given number of seconds.");
168 #endif
170 #ifdef HAVE_PAUSE
171 static PyObject *
172 signal_pause(PyObject *self)
174 Py_BEGIN_ALLOW_THREADS
175 (void)pause();
176 Py_END_ALLOW_THREADS
177 /* make sure that any exceptions that got raised are propagated
178 * back into Python
180 if (PyErr_CheckSignals())
181 return NULL;
183 Py_INCREF(Py_None);
184 return Py_None;
186 PyDoc_STRVAR(pause_doc,
187 "pause()\n\
189 Wait until a signal arrives.");
191 #endif
194 static PyObject *
195 signal_signal(PyObject *self, PyObject *args)
197 PyObject *obj;
198 int sig_num;
199 PyObject *old_handler;
200 void (*func)(int);
201 if (!PyArg_ParseTuple(args, "iO:signal", &sig_num, &obj))
202 return NULL;
203 #ifdef WITH_THREAD
204 if (PyThread_get_thread_ident() != main_thread) {
205 PyErr_SetString(PyExc_ValueError,
206 "signal only works in main thread");
207 return NULL;
209 #endif
210 if (sig_num < 1 || sig_num >= NSIG) {
211 PyErr_SetString(PyExc_ValueError,
212 "signal number out of range");
213 return NULL;
215 if (obj == IgnoreHandler)
216 func = SIG_IGN;
217 else if (obj == DefaultHandler)
218 func = SIG_DFL;
219 else if (!PyCallable_Check(obj)) {
220 PyErr_SetString(PyExc_TypeError,
221 "signal handler must be signal.SIG_IGN, signal.SIG_DFL, or a callable object");
222 return NULL;
224 else
225 func = signal_handler;
226 if (PyOS_setsig(sig_num, func) == SIG_ERR) {
227 PyErr_SetFromErrno(PyExc_RuntimeError);
228 return NULL;
230 old_handler = Handlers[sig_num].func;
231 Handlers[sig_num].tripped = 0;
232 Py_INCREF(obj);
233 Handlers[sig_num].func = obj;
234 return old_handler;
237 PyDoc_STRVAR(signal_doc,
238 "signal(sig, action) -> action\n\
240 Set the action for the given signal. The action can be SIG_DFL,\n\
241 SIG_IGN, or a callable Python object. The previous action is\n\
242 returned. See getsignal() for possible return values.\n\
244 *** IMPORTANT NOTICE ***\n\
245 A signal handler function is called with two arguments:\n\
246 the first is the signal number, the second is the interrupted stack frame.");
249 static PyObject *
250 signal_getsignal(PyObject *self, PyObject *args)
252 int sig_num;
253 PyObject *old_handler;
254 if (!PyArg_ParseTuple(args, "i:getsignal", &sig_num))
255 return NULL;
256 if (sig_num < 1 || sig_num >= NSIG) {
257 PyErr_SetString(PyExc_ValueError,
258 "signal number out of range");
259 return NULL;
261 old_handler = Handlers[sig_num].func;
262 Py_INCREF(old_handler);
263 return old_handler;
266 PyDoc_STRVAR(getsignal_doc,
267 "getsignal(sig) -> action\n\
269 Return the current action for the given signal. The return value can be:\n\
270 SIG_IGN -- if the signal is being ignored\n\
271 SIG_DFL -- if the default action for the signal is in effect\n\
272 None -- if an unknown handler is in effect\n\
273 anything else -- the callable Python object used as a handler");
276 static PyObject *
277 signal_set_wakeup_fd(PyObject *self, PyObject *args)
279 struct stat buf;
280 int fd, old_fd;
281 if (!PyArg_ParseTuple(args, "i:set_wakeup_fd", &fd))
282 return NULL;
283 #ifdef WITH_THREAD
284 if (PyThread_get_thread_ident() != main_thread) {
285 PyErr_SetString(PyExc_ValueError,
286 "set_wakeup_fd only works in main thread");
287 return NULL;
289 #endif
290 if (fd != -1 && fstat(fd, &buf) != 0) {
291 PyErr_SetString(PyExc_ValueError, "invalid fd");
292 return NULL;
294 old_fd = wakeup_fd;
295 wakeup_fd = fd;
296 return PyLong_FromLong(old_fd);
299 PyDoc_STRVAR(set_wakeup_fd_doc,
300 "set_wakeup_fd(fd) -> fd\n\
302 Sets the fd to be written to (with '\\0') when a signal\n\
303 comes in. A library can use this to wakeup select or poll.\n\
304 The previous fd is returned.\n\
306 The fd must be non-blocking.");
308 /* C API for the same, without all the error checking */
310 PySignal_SetWakeupFd(int fd)
312 int old_fd = wakeup_fd;
313 if (fd < 0)
314 fd = -1;
315 wakeup_fd = fd;
316 return old_fd;
320 /* List of functions defined in the module */
321 static PyMethodDef signal_methods[] = {
322 #ifdef HAVE_ALARM
323 {"alarm", signal_alarm, METH_VARARGS, alarm_doc},
324 #endif
325 {"signal", signal_signal, METH_VARARGS, signal_doc},
326 {"getsignal", signal_getsignal, METH_VARARGS, getsignal_doc},
327 {"set_wakeup_fd", signal_set_wakeup_fd, METH_VARARGS, set_wakeup_fd_doc},
328 #ifdef HAVE_PAUSE
329 {"pause", (PyCFunction)signal_pause,
330 METH_NOARGS,pause_doc},
331 #endif
332 {"default_int_handler", signal_default_int_handler,
333 METH_VARARGS, default_int_handler_doc},
334 {NULL, NULL} /* sentinel */
338 PyDoc_STRVAR(module_doc,
339 "This module provides mechanisms to use signal handlers in Python.\n\
341 Functions:\n\
343 alarm() -- cause SIGALRM after a specified time [Unix only]\n\
344 signal() -- set the action for a given signal\n\
345 getsignal() -- get the signal action for a given signal\n\
346 pause() -- wait until a signal arrives [Unix only]\n\
347 default_int_handler() -- default SIGINT handler\n\
349 Constants:\n\
351 SIG_DFL -- used to refer to the system default handler\n\
352 SIG_IGN -- used to ignore the signal\n\
353 NSIG -- number of defined signals\n\
355 SIGINT, SIGTERM, etc. -- signal numbers\n\
357 *** IMPORTANT NOTICE ***\n\
358 A signal handler function is called with two arguments:\n\
359 the first is the signal number, the second is the interrupted stack frame.");
361 PyMODINIT_FUNC
362 initsignal(void)
364 PyObject *m, *d, *x;
365 int i;
367 #ifdef WITH_THREAD
368 main_thread = PyThread_get_thread_ident();
369 main_pid = getpid();
370 #endif
372 /* Create the module and add the functions */
373 m = Py_InitModule3("signal", signal_methods, module_doc);
374 if (m == NULL)
375 return;
377 /* Add some symbolic constants to the module */
378 d = PyModule_GetDict(m);
380 x = DefaultHandler = PyLong_FromVoidPtr((void *)SIG_DFL);
381 if (!x || PyDict_SetItemString(d, "SIG_DFL", x) < 0)
382 goto finally;
384 x = IgnoreHandler = PyLong_FromVoidPtr((void *)SIG_IGN);
385 if (!x || PyDict_SetItemString(d, "SIG_IGN", x) < 0)
386 goto finally;
388 x = PyInt_FromLong((long)NSIG);
389 if (!x || PyDict_SetItemString(d, "NSIG", x) < 0)
390 goto finally;
391 Py_DECREF(x);
393 x = IntHandler = PyDict_GetItemString(d, "default_int_handler");
394 if (!x)
395 goto finally;
396 Py_INCREF(IntHandler);
398 Handlers[0].tripped = 0;
399 for (i = 1; i < NSIG; i++) {
400 void (*t)(int);
401 t = PyOS_getsig(i);
402 Handlers[i].tripped = 0;
403 if (t == SIG_DFL)
404 Handlers[i].func = DefaultHandler;
405 else if (t == SIG_IGN)
406 Handlers[i].func = IgnoreHandler;
407 else
408 Handlers[i].func = Py_None; /* None of our business */
409 Py_INCREF(Handlers[i].func);
411 if (Handlers[SIGINT].func == DefaultHandler) {
412 /* Install default int handler */
413 Py_INCREF(IntHandler);
414 Py_DECREF(Handlers[SIGINT].func);
415 Handlers[SIGINT].func = IntHandler;
416 old_siginthandler = PyOS_setsig(SIGINT, signal_handler);
419 #ifdef SIGHUP
420 x = PyInt_FromLong(SIGHUP);
421 PyDict_SetItemString(d, "SIGHUP", x);
422 Py_XDECREF(x);
423 #endif
424 #ifdef SIGINT
425 x = PyInt_FromLong(SIGINT);
426 PyDict_SetItemString(d, "SIGINT", x);
427 Py_XDECREF(x);
428 #endif
429 #ifdef SIGBREAK
430 x = PyInt_FromLong(SIGBREAK);
431 PyDict_SetItemString(d, "SIGBREAK", x);
432 Py_XDECREF(x);
433 #endif
434 #ifdef SIGQUIT
435 x = PyInt_FromLong(SIGQUIT);
436 PyDict_SetItemString(d, "SIGQUIT", x);
437 Py_XDECREF(x);
438 #endif
439 #ifdef SIGILL
440 x = PyInt_FromLong(SIGILL);
441 PyDict_SetItemString(d, "SIGILL", x);
442 Py_XDECREF(x);
443 #endif
444 #ifdef SIGTRAP
445 x = PyInt_FromLong(SIGTRAP);
446 PyDict_SetItemString(d, "SIGTRAP", x);
447 Py_XDECREF(x);
448 #endif
449 #ifdef SIGIOT
450 x = PyInt_FromLong(SIGIOT);
451 PyDict_SetItemString(d, "SIGIOT", x);
452 Py_XDECREF(x);
453 #endif
454 #ifdef SIGABRT
455 x = PyInt_FromLong(SIGABRT);
456 PyDict_SetItemString(d, "SIGABRT", x);
457 Py_XDECREF(x);
458 #endif
459 #ifdef SIGEMT
460 x = PyInt_FromLong(SIGEMT);
461 PyDict_SetItemString(d, "SIGEMT", x);
462 Py_XDECREF(x);
463 #endif
464 #ifdef SIGFPE
465 x = PyInt_FromLong(SIGFPE);
466 PyDict_SetItemString(d, "SIGFPE", x);
467 Py_XDECREF(x);
468 #endif
469 #ifdef SIGKILL
470 x = PyInt_FromLong(SIGKILL);
471 PyDict_SetItemString(d, "SIGKILL", x);
472 Py_XDECREF(x);
473 #endif
474 #ifdef SIGBUS
475 x = PyInt_FromLong(SIGBUS);
476 PyDict_SetItemString(d, "SIGBUS", x);
477 Py_XDECREF(x);
478 #endif
479 #ifdef SIGSEGV
480 x = PyInt_FromLong(SIGSEGV);
481 PyDict_SetItemString(d, "SIGSEGV", x);
482 Py_XDECREF(x);
483 #endif
484 #ifdef SIGSYS
485 x = PyInt_FromLong(SIGSYS);
486 PyDict_SetItemString(d, "SIGSYS", x);
487 Py_XDECREF(x);
488 #endif
489 #ifdef SIGPIPE
490 x = PyInt_FromLong(SIGPIPE);
491 PyDict_SetItemString(d, "SIGPIPE", x);
492 Py_XDECREF(x);
493 #endif
494 #ifdef SIGALRM
495 x = PyInt_FromLong(SIGALRM);
496 PyDict_SetItemString(d, "SIGALRM", x);
497 Py_XDECREF(x);
498 #endif
499 #ifdef SIGTERM
500 x = PyInt_FromLong(SIGTERM);
501 PyDict_SetItemString(d, "SIGTERM", x);
502 Py_XDECREF(x);
503 #endif
504 #ifdef SIGUSR1
505 x = PyInt_FromLong(SIGUSR1);
506 PyDict_SetItemString(d, "SIGUSR1", x);
507 Py_XDECREF(x);
508 #endif
509 #ifdef SIGUSR2
510 x = PyInt_FromLong(SIGUSR2);
511 PyDict_SetItemString(d, "SIGUSR2", x);
512 Py_XDECREF(x);
513 #endif
514 #ifdef SIGCLD
515 x = PyInt_FromLong(SIGCLD);
516 PyDict_SetItemString(d, "SIGCLD", x);
517 Py_XDECREF(x);
518 #endif
519 #ifdef SIGCHLD
520 x = PyInt_FromLong(SIGCHLD);
521 PyDict_SetItemString(d, "SIGCHLD", x);
522 Py_XDECREF(x);
523 #endif
524 #ifdef SIGPWR
525 x = PyInt_FromLong(SIGPWR);
526 PyDict_SetItemString(d, "SIGPWR", x);
527 Py_XDECREF(x);
528 #endif
529 #ifdef SIGIO
530 x = PyInt_FromLong(SIGIO);
531 PyDict_SetItemString(d, "SIGIO", x);
532 Py_XDECREF(x);
533 #endif
534 #ifdef SIGURG
535 x = PyInt_FromLong(SIGURG);
536 PyDict_SetItemString(d, "SIGURG", x);
537 Py_XDECREF(x);
538 #endif
539 #ifdef SIGWINCH
540 x = PyInt_FromLong(SIGWINCH);
541 PyDict_SetItemString(d, "SIGWINCH", x);
542 Py_XDECREF(x);
543 #endif
544 #ifdef SIGPOLL
545 x = PyInt_FromLong(SIGPOLL);
546 PyDict_SetItemString(d, "SIGPOLL", x);
547 Py_XDECREF(x);
548 #endif
549 #ifdef SIGSTOP
550 x = PyInt_FromLong(SIGSTOP);
551 PyDict_SetItemString(d, "SIGSTOP", x);
552 Py_XDECREF(x);
553 #endif
554 #ifdef SIGTSTP
555 x = PyInt_FromLong(SIGTSTP);
556 PyDict_SetItemString(d, "SIGTSTP", x);
557 Py_XDECREF(x);
558 #endif
559 #ifdef SIGCONT
560 x = PyInt_FromLong(SIGCONT);
561 PyDict_SetItemString(d, "SIGCONT", x);
562 Py_XDECREF(x);
563 #endif
564 #ifdef SIGTTIN
565 x = PyInt_FromLong(SIGTTIN);
566 PyDict_SetItemString(d, "SIGTTIN", x);
567 Py_XDECREF(x);
568 #endif
569 #ifdef SIGTTOU
570 x = PyInt_FromLong(SIGTTOU);
571 PyDict_SetItemString(d, "SIGTTOU", x);
572 Py_XDECREF(x);
573 #endif
574 #ifdef SIGVTALRM
575 x = PyInt_FromLong(SIGVTALRM);
576 PyDict_SetItemString(d, "SIGVTALRM", x);
577 Py_XDECREF(x);
578 #endif
579 #ifdef SIGPROF
580 x = PyInt_FromLong(SIGPROF);
581 PyDict_SetItemString(d, "SIGPROF", x);
582 Py_XDECREF(x);
583 #endif
584 #ifdef SIGXCPU
585 x = PyInt_FromLong(SIGXCPU);
586 PyDict_SetItemString(d, "SIGXCPU", x);
587 Py_XDECREF(x);
588 #endif
589 #ifdef SIGXFSZ
590 x = PyInt_FromLong(SIGXFSZ);
591 PyDict_SetItemString(d, "SIGXFSZ", x);
592 Py_XDECREF(x);
593 #endif
594 #ifdef SIGRTMIN
595 x = PyInt_FromLong(SIGRTMIN);
596 PyDict_SetItemString(d, "SIGRTMIN", x);
597 Py_XDECREF(x);
598 #endif
599 #ifdef SIGRTMAX
600 x = PyInt_FromLong(SIGRTMAX);
601 PyDict_SetItemString(d, "SIGRTMAX", x);
602 Py_XDECREF(x);
603 #endif
604 #ifdef SIGINFO
605 x = PyInt_FromLong(SIGINFO);
606 PyDict_SetItemString(d, "SIGINFO", x);
607 Py_XDECREF(x);
608 #endif
609 if (!PyErr_Occurred())
610 return;
612 /* Check for errors */
613 finally:
614 return;
617 static void
618 finisignal(void)
620 int i;
621 PyObject *func;
623 PyOS_setsig(SIGINT, old_siginthandler);
624 old_siginthandler = SIG_DFL;
626 for (i = 1; i < NSIG; i++) {
627 func = Handlers[i].func;
628 Handlers[i].tripped = 0;
629 Handlers[i].func = NULL;
630 if (i != SIGINT && func != NULL && func != Py_None &&
631 func != DefaultHandler && func != IgnoreHandler)
632 PyOS_setsig(i, SIG_DFL);
633 Py_XDECREF(func);
636 Py_XDECREF(IntHandler);
637 IntHandler = NULL;
638 Py_XDECREF(DefaultHandler);
639 DefaultHandler = NULL;
640 Py_XDECREF(IgnoreHandler);
641 IgnoreHandler = NULL;
645 /* Declared in pyerrors.h */
647 PyErr_CheckSignals(void)
649 int i;
650 PyObject *f;
652 if (!is_tripped)
653 return 0;
655 #ifdef WITH_THREAD
656 if (PyThread_get_thread_ident() != main_thread)
657 return 0;
658 #endif
661 * The is_stripped variable is meant to speed up the calls to
662 * PyErr_CheckSignals (both directly or via pending calls) when no
663 * signal has arrived. This variable is set to 1 when a signal arrives
664 * and it is set to 0 here, when we know some signals arrived. This way
665 * we can run the registered handlers with no signals blocked.
667 * NOTE: with this approach we can have a situation where is_tripped is
668 * 1 but we have no more signals to handle (Handlers[i].tripped
669 * is 0 for every signal i). This won't do us any harm (except
670 * we're gonna spent some cycles for nothing). This happens when
671 * we receive a signal i after we zero is_tripped and before we
672 * check Handlers[i].tripped.
674 is_tripped = 0;
676 if (!(f = (PyObject *)PyEval_GetFrame()))
677 f = Py_None;
679 for (i = 1; i < NSIG; i++) {
680 if (Handlers[i].tripped) {
681 PyObject *result = NULL;
682 PyObject *arglist = Py_BuildValue("(iO)", i, f);
683 Handlers[i].tripped = 0;
685 if (arglist) {
686 result = PyEval_CallObject(Handlers[i].func,
687 arglist);
688 Py_DECREF(arglist);
690 if (!result)
691 return -1;
693 Py_DECREF(result);
697 return 0;
701 /* Replacements for intrcheck.c functionality
702 * Declared in pyerrors.h
704 void
705 PyErr_SetInterrupt(void)
707 is_tripped = 1;
708 Handlers[SIGINT].tripped = 1;
709 Py_AddPendingCall((int (*)(void *))PyErr_CheckSignals, NULL);
712 void
713 PyOS_InitInterrupts(void)
715 initsignal();
716 _PyImport_FixupExtension("signal", "signal");
719 void
720 PyOS_FiniInterrupts(void)
722 finisignal();
726 PyOS_InterruptOccurred(void)
728 if (Handlers[SIGINT].tripped) {
729 #ifdef WITH_THREAD
730 if (PyThread_get_thread_ident() != main_thread)
731 return 0;
732 #endif
733 Handlers[SIGINT].tripped = 0;
734 return 1;
736 return 0;
739 void
740 PyOS_AfterFork(void)
742 #ifdef WITH_THREAD
743 PyEval_ReInitThreads();
744 main_thread = PyThread_get_thread_ident();
745 main_pid = getpid();
746 _PyImport_ReInitLock();
747 #endif