Minor fix for currentframe (SF #1652788).
[python.git] / Modules / signalmodule.c
bloba729604a316bf4cb27376d880e54b12e32518c56
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 installed 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 PyOS_setsig(sig_num, signal_handler);
144 #ifdef HAVE_ALARM
145 static PyObject *
146 signal_alarm(PyObject *self, PyObject *args)
148 int t;
149 if (!PyArg_ParseTuple(args, "i:alarm", &t))
150 return NULL;
151 /* alarm() returns the number of seconds remaining */
152 return PyInt_FromLong((long)alarm(t));
155 PyDoc_STRVAR(alarm_doc,
156 "alarm(seconds)\n\
158 Arrange for SIGALRM to arrive after the given number of seconds.");
159 #endif
161 #ifdef HAVE_PAUSE
162 static PyObject *
163 signal_pause(PyObject *self)
165 Py_BEGIN_ALLOW_THREADS
166 (void)pause();
167 Py_END_ALLOW_THREADS
168 /* make sure that any exceptions that got raised are propagated
169 * back into Python
171 if (PyErr_CheckSignals())
172 return NULL;
174 Py_INCREF(Py_None);
175 return Py_None;
177 PyDoc_STRVAR(pause_doc,
178 "pause()\n\
180 Wait until a signal arrives.");
182 #endif
185 static PyObject *
186 signal_signal(PyObject *self, PyObject *args)
188 PyObject *obj;
189 int sig_num;
190 PyObject *old_handler;
191 void (*func)(int);
192 if (!PyArg_ParseTuple(args, "iO:signal", &sig_num, &obj))
193 return NULL;
194 #ifdef WITH_THREAD
195 if (PyThread_get_thread_ident() != main_thread) {
196 PyErr_SetString(PyExc_ValueError,
197 "signal only works in main thread");
198 return NULL;
200 #endif
201 if (sig_num < 1 || sig_num >= NSIG) {
202 PyErr_SetString(PyExc_ValueError,
203 "signal number out of range");
204 return NULL;
206 if (obj == IgnoreHandler)
207 func = SIG_IGN;
208 else if (obj == DefaultHandler)
209 func = SIG_DFL;
210 else if (!PyCallable_Check(obj)) {
211 PyErr_SetString(PyExc_TypeError,
212 "signal handler must be signal.SIG_IGN, signal.SIG_DFL, or a callable object");
213 return NULL;
215 else
216 func = signal_handler;
217 if (PyOS_setsig(sig_num, func) == SIG_ERR) {
218 PyErr_SetFromErrno(PyExc_RuntimeError);
219 return NULL;
221 old_handler = Handlers[sig_num].func;
222 Handlers[sig_num].tripped = 0;
223 Py_INCREF(obj);
224 Handlers[sig_num].func = obj;
225 return old_handler;
228 PyDoc_STRVAR(signal_doc,
229 "signal(sig, action) -> action\n\
231 Set the action for the given signal. The action can be SIG_DFL,\n\
232 SIG_IGN, or a callable Python object. The previous action is\n\
233 returned. See getsignal() for possible return values.\n\
235 *** IMPORTANT NOTICE ***\n\
236 A signal handler function is called with two arguments:\n\
237 the first is the signal number, the second is the interrupted stack frame.");
240 static PyObject *
241 signal_getsignal(PyObject *self, PyObject *args)
243 int sig_num;
244 PyObject *old_handler;
245 if (!PyArg_ParseTuple(args, "i:getsignal", &sig_num))
246 return NULL;
247 if (sig_num < 1 || sig_num >= NSIG) {
248 PyErr_SetString(PyExc_ValueError,
249 "signal number out of range");
250 return NULL;
252 old_handler = Handlers[sig_num].func;
253 Py_INCREF(old_handler);
254 return old_handler;
257 PyDoc_STRVAR(getsignal_doc,
258 "getsignal(sig) -> action\n\
260 Return the current action for the given signal. The return value can be:\n\
261 SIG_IGN -- if the signal is being ignored\n\
262 SIG_DFL -- if the default action for the signal is in effect\n\
263 None -- if an unknown handler is in effect\n\
264 anything else -- the callable Python object used as a handler");
267 /* List of functions defined in the module */
268 static PyMethodDef signal_methods[] = {
269 #ifdef HAVE_ALARM
270 {"alarm", signal_alarm, METH_VARARGS, alarm_doc},
271 #endif
272 {"signal", signal_signal, METH_VARARGS, signal_doc},
273 {"getsignal", signal_getsignal, METH_VARARGS, getsignal_doc},
274 #ifdef HAVE_PAUSE
275 {"pause", (PyCFunction)signal_pause,
276 METH_NOARGS,pause_doc},
277 #endif
278 {"default_int_handler", signal_default_int_handler,
279 METH_VARARGS, default_int_handler_doc},
280 {NULL, NULL} /* sentinel */
284 PyDoc_STRVAR(module_doc,
285 "This module provides mechanisms to use signal handlers in Python.\n\
287 Functions:\n\
289 alarm() -- cause SIGALRM after a specified time [Unix only]\n\
290 signal() -- set the action for a given signal\n\
291 getsignal() -- get the signal action for a given signal\n\
292 pause() -- wait until a signal arrives [Unix only]\n\
293 default_int_handler() -- default SIGINT handler\n\
295 Constants:\n\
297 SIG_DFL -- used to refer to the system default handler\n\
298 SIG_IGN -- used to ignore the signal\n\
299 NSIG -- number of defined signals\n\
301 SIGINT, SIGTERM, etc. -- signal numbers\n\
303 *** IMPORTANT NOTICE ***\n\
304 A signal handler function is called with two arguments:\n\
305 the first is the signal number, the second is the interrupted stack frame.");
307 PyMODINIT_FUNC
308 initsignal(void)
310 PyObject *m, *d, *x;
311 int i;
313 #ifdef WITH_THREAD
314 main_thread = PyThread_get_thread_ident();
315 main_pid = getpid();
316 #endif
318 /* Create the module and add the functions */
319 m = Py_InitModule3("signal", signal_methods, module_doc);
320 if (m == NULL)
321 return;
323 /* Add some symbolic constants to the module */
324 d = PyModule_GetDict(m);
326 x = DefaultHandler = PyLong_FromVoidPtr((void *)SIG_DFL);
327 if (!x || PyDict_SetItemString(d, "SIG_DFL", x) < 0)
328 goto finally;
330 x = IgnoreHandler = PyLong_FromVoidPtr((void *)SIG_IGN);
331 if (!x || PyDict_SetItemString(d, "SIG_IGN", x) < 0)
332 goto finally;
334 x = PyInt_FromLong((long)NSIG);
335 if (!x || PyDict_SetItemString(d, "NSIG", x) < 0)
336 goto finally;
337 Py_DECREF(x);
339 x = IntHandler = PyDict_GetItemString(d, "default_int_handler");
340 if (!x)
341 goto finally;
342 Py_INCREF(IntHandler);
344 Handlers[0].tripped = 0;
345 for (i = 1; i < NSIG; i++) {
346 void (*t)(int);
347 t = PyOS_getsig(i);
348 Handlers[i].tripped = 0;
349 if (t == SIG_DFL)
350 Handlers[i].func = DefaultHandler;
351 else if (t == SIG_IGN)
352 Handlers[i].func = IgnoreHandler;
353 else
354 Handlers[i].func = Py_None; /* None of our business */
355 Py_INCREF(Handlers[i].func);
357 if (Handlers[SIGINT].func == DefaultHandler) {
358 /* Install default int handler */
359 Py_INCREF(IntHandler);
360 Py_DECREF(Handlers[SIGINT].func);
361 Handlers[SIGINT].func = IntHandler;
362 old_siginthandler = PyOS_setsig(SIGINT, signal_handler);
365 #ifdef SIGHUP
366 x = PyInt_FromLong(SIGHUP);
367 PyDict_SetItemString(d, "SIGHUP", x);
368 Py_XDECREF(x);
369 #endif
370 #ifdef SIGINT
371 x = PyInt_FromLong(SIGINT);
372 PyDict_SetItemString(d, "SIGINT", x);
373 Py_XDECREF(x);
374 #endif
375 #ifdef SIGBREAK
376 x = PyInt_FromLong(SIGBREAK);
377 PyDict_SetItemString(d, "SIGBREAK", x);
378 Py_XDECREF(x);
379 #endif
380 #ifdef SIGQUIT
381 x = PyInt_FromLong(SIGQUIT);
382 PyDict_SetItemString(d, "SIGQUIT", x);
383 Py_XDECREF(x);
384 #endif
385 #ifdef SIGILL
386 x = PyInt_FromLong(SIGILL);
387 PyDict_SetItemString(d, "SIGILL", x);
388 Py_XDECREF(x);
389 #endif
390 #ifdef SIGTRAP
391 x = PyInt_FromLong(SIGTRAP);
392 PyDict_SetItemString(d, "SIGTRAP", x);
393 Py_XDECREF(x);
394 #endif
395 #ifdef SIGIOT
396 x = PyInt_FromLong(SIGIOT);
397 PyDict_SetItemString(d, "SIGIOT", x);
398 Py_XDECREF(x);
399 #endif
400 #ifdef SIGABRT
401 x = PyInt_FromLong(SIGABRT);
402 PyDict_SetItemString(d, "SIGABRT", x);
403 Py_XDECREF(x);
404 #endif
405 #ifdef SIGEMT
406 x = PyInt_FromLong(SIGEMT);
407 PyDict_SetItemString(d, "SIGEMT", x);
408 Py_XDECREF(x);
409 #endif
410 #ifdef SIGFPE
411 x = PyInt_FromLong(SIGFPE);
412 PyDict_SetItemString(d, "SIGFPE", x);
413 Py_XDECREF(x);
414 #endif
415 #ifdef SIGKILL
416 x = PyInt_FromLong(SIGKILL);
417 PyDict_SetItemString(d, "SIGKILL", x);
418 Py_XDECREF(x);
419 #endif
420 #ifdef SIGBUS
421 x = PyInt_FromLong(SIGBUS);
422 PyDict_SetItemString(d, "SIGBUS", x);
423 Py_XDECREF(x);
424 #endif
425 #ifdef SIGSEGV
426 x = PyInt_FromLong(SIGSEGV);
427 PyDict_SetItemString(d, "SIGSEGV", x);
428 Py_XDECREF(x);
429 #endif
430 #ifdef SIGSYS
431 x = PyInt_FromLong(SIGSYS);
432 PyDict_SetItemString(d, "SIGSYS", x);
433 Py_XDECREF(x);
434 #endif
435 #ifdef SIGPIPE
436 x = PyInt_FromLong(SIGPIPE);
437 PyDict_SetItemString(d, "SIGPIPE", x);
438 Py_XDECREF(x);
439 #endif
440 #ifdef SIGALRM
441 x = PyInt_FromLong(SIGALRM);
442 PyDict_SetItemString(d, "SIGALRM", x);
443 Py_XDECREF(x);
444 #endif
445 #ifdef SIGTERM
446 x = PyInt_FromLong(SIGTERM);
447 PyDict_SetItemString(d, "SIGTERM", x);
448 Py_XDECREF(x);
449 #endif
450 #ifdef SIGUSR1
451 x = PyInt_FromLong(SIGUSR1);
452 PyDict_SetItemString(d, "SIGUSR1", x);
453 Py_XDECREF(x);
454 #endif
455 #ifdef SIGUSR2
456 x = PyInt_FromLong(SIGUSR2);
457 PyDict_SetItemString(d, "SIGUSR2", x);
458 Py_XDECREF(x);
459 #endif
460 #ifdef SIGCLD
461 x = PyInt_FromLong(SIGCLD);
462 PyDict_SetItemString(d, "SIGCLD", x);
463 Py_XDECREF(x);
464 #endif
465 #ifdef SIGCHLD
466 x = PyInt_FromLong(SIGCHLD);
467 PyDict_SetItemString(d, "SIGCHLD", x);
468 Py_XDECREF(x);
469 #endif
470 #ifdef SIGPWR
471 x = PyInt_FromLong(SIGPWR);
472 PyDict_SetItemString(d, "SIGPWR", x);
473 Py_XDECREF(x);
474 #endif
475 #ifdef SIGIO
476 x = PyInt_FromLong(SIGIO);
477 PyDict_SetItemString(d, "SIGIO", x);
478 Py_XDECREF(x);
479 #endif
480 #ifdef SIGURG
481 x = PyInt_FromLong(SIGURG);
482 PyDict_SetItemString(d, "SIGURG", x);
483 Py_XDECREF(x);
484 #endif
485 #ifdef SIGWINCH
486 x = PyInt_FromLong(SIGWINCH);
487 PyDict_SetItemString(d, "SIGWINCH", x);
488 Py_XDECREF(x);
489 #endif
490 #ifdef SIGPOLL
491 x = PyInt_FromLong(SIGPOLL);
492 PyDict_SetItemString(d, "SIGPOLL", x);
493 Py_XDECREF(x);
494 #endif
495 #ifdef SIGSTOP
496 x = PyInt_FromLong(SIGSTOP);
497 PyDict_SetItemString(d, "SIGSTOP", x);
498 Py_XDECREF(x);
499 #endif
500 #ifdef SIGTSTP
501 x = PyInt_FromLong(SIGTSTP);
502 PyDict_SetItemString(d, "SIGTSTP", x);
503 Py_XDECREF(x);
504 #endif
505 #ifdef SIGCONT
506 x = PyInt_FromLong(SIGCONT);
507 PyDict_SetItemString(d, "SIGCONT", x);
508 Py_XDECREF(x);
509 #endif
510 #ifdef SIGTTIN
511 x = PyInt_FromLong(SIGTTIN);
512 PyDict_SetItemString(d, "SIGTTIN", x);
513 Py_XDECREF(x);
514 #endif
515 #ifdef SIGTTOU
516 x = PyInt_FromLong(SIGTTOU);
517 PyDict_SetItemString(d, "SIGTTOU", x);
518 Py_XDECREF(x);
519 #endif
520 #ifdef SIGVTALRM
521 x = PyInt_FromLong(SIGVTALRM);
522 PyDict_SetItemString(d, "SIGVTALRM", x);
523 Py_XDECREF(x);
524 #endif
525 #ifdef SIGPROF
526 x = PyInt_FromLong(SIGPROF);
527 PyDict_SetItemString(d, "SIGPROF", x);
528 Py_XDECREF(x);
529 #endif
530 #ifdef SIGXCPU
531 x = PyInt_FromLong(SIGXCPU);
532 PyDict_SetItemString(d, "SIGXCPU", x);
533 Py_XDECREF(x);
534 #endif
535 #ifdef SIGXFSZ
536 x = PyInt_FromLong(SIGXFSZ);
537 PyDict_SetItemString(d, "SIGXFSZ", x);
538 Py_XDECREF(x);
539 #endif
540 #ifdef SIGRTMIN
541 x = PyInt_FromLong(SIGRTMIN);
542 PyDict_SetItemString(d, "SIGRTMIN", x);
543 Py_XDECREF(x);
544 #endif
545 #ifdef SIGRTMAX
546 x = PyInt_FromLong(SIGRTMAX);
547 PyDict_SetItemString(d, "SIGRTMAX", x);
548 Py_XDECREF(x);
549 #endif
550 #ifdef SIGINFO
551 x = PyInt_FromLong(SIGINFO);
552 PyDict_SetItemString(d, "SIGINFO", x);
553 Py_XDECREF(x);
554 #endif
555 if (!PyErr_Occurred())
556 return;
558 /* Check for errors */
559 finally:
560 return;
563 static void
564 finisignal(void)
566 int i;
567 PyObject *func;
569 PyOS_setsig(SIGINT, old_siginthandler);
570 old_siginthandler = SIG_DFL;
572 for (i = 1; i < NSIG; i++) {
573 func = Handlers[i].func;
574 Handlers[i].tripped = 0;
575 Handlers[i].func = NULL;
576 if (i != SIGINT && func != NULL && func != Py_None &&
577 func != DefaultHandler && func != IgnoreHandler)
578 PyOS_setsig(i, SIG_DFL);
579 Py_XDECREF(func);
582 Py_XDECREF(IntHandler);
583 IntHandler = NULL;
584 Py_XDECREF(DefaultHandler);
585 DefaultHandler = NULL;
586 Py_XDECREF(IgnoreHandler);
587 IgnoreHandler = NULL;
591 /* Declared in pyerrors.h */
593 PyErr_CheckSignals(void)
595 int i;
596 PyObject *f;
598 if (!is_tripped)
599 return 0;
600 #ifdef WITH_THREAD
601 if (PyThread_get_thread_ident() != main_thread)
602 return 0;
603 #endif
604 if (!(f = (PyObject *)PyEval_GetFrame()))
605 f = Py_None;
607 for (i = 1; i < NSIG; i++) {
608 if (Handlers[i].tripped) {
609 PyObject *result = NULL;
610 PyObject *arglist = Py_BuildValue("(iO)", i, f);
611 Handlers[i].tripped = 0;
613 if (arglist) {
614 result = PyEval_CallObject(Handlers[i].func,
615 arglist);
616 Py_DECREF(arglist);
618 if (!result)
619 return -1;
621 Py_DECREF(result);
624 is_tripped = 0;
625 return 0;
629 /* Replacements for intrcheck.c functionality
630 * Declared in pyerrors.h
632 void
633 PyErr_SetInterrupt(void)
635 is_tripped++;
636 Handlers[SIGINT].tripped = 1;
637 Py_AddPendingCall((int (*)(void *))PyErr_CheckSignals, NULL);
640 void
641 PyOS_InitInterrupts(void)
643 initsignal();
644 _PyImport_FixupExtension("signal", "signal");
647 void
648 PyOS_FiniInterrupts(void)
650 finisignal();
654 PyOS_InterruptOccurred(void)
656 if (Handlers[SIGINT].tripped) {
657 #ifdef WITH_THREAD
658 if (PyThread_get_thread_ident() != main_thread)
659 return 0;
660 #endif
661 Handlers[SIGINT].tripped = 0;
662 return 1;
664 return 0;
667 void
668 PyOS_AfterFork(void)
670 #ifdef WITH_THREAD
671 PyEval_ReInitThreads();
672 main_thread = PyThread_get_thread_ident();
673 main_pid = getpid();
674 _PyImport_ReInitLock();
675 #endif