Fixed bug in time-to-midnight calculation.
[python.git] / Modules / signalmodule.c
blobbec27293e9e6bc9ce5f64d00681a0162a8a8cec9
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);
321 /* Add some symbolic constants to the module */
322 d = PyModule_GetDict(m);
324 x = DefaultHandler = PyLong_FromVoidPtr((void *)SIG_DFL);
325 if (!x || PyDict_SetItemString(d, "SIG_DFL", x) < 0)
326 goto finally;
328 x = IgnoreHandler = PyLong_FromVoidPtr((void *)SIG_IGN);
329 if (!x || PyDict_SetItemString(d, "SIG_IGN", x) < 0)
330 goto finally;
332 x = PyInt_FromLong((long)NSIG);
333 if (!x || PyDict_SetItemString(d, "NSIG", x) < 0)
334 goto finally;
335 Py_DECREF(x);
337 x = IntHandler = PyDict_GetItemString(d, "default_int_handler");
338 if (!x)
339 goto finally;
340 Py_INCREF(IntHandler);
342 Handlers[0].tripped = 0;
343 for (i = 1; i < NSIG; i++) {
344 void (*t)(int);
345 t = PyOS_getsig(i);
346 Handlers[i].tripped = 0;
347 if (t == SIG_DFL)
348 Handlers[i].func = DefaultHandler;
349 else if (t == SIG_IGN)
350 Handlers[i].func = IgnoreHandler;
351 else
352 Handlers[i].func = Py_None; /* None of our business */
353 Py_INCREF(Handlers[i].func);
355 if (Handlers[SIGINT].func == DefaultHandler) {
356 /* Install default int handler */
357 Py_INCREF(IntHandler);
358 Py_DECREF(Handlers[SIGINT].func);
359 Handlers[SIGINT].func = IntHandler;
360 old_siginthandler = PyOS_setsig(SIGINT, signal_handler);
363 #ifdef SIGHUP
364 x = PyInt_FromLong(SIGHUP);
365 PyDict_SetItemString(d, "SIGHUP", x);
366 Py_XDECREF(x);
367 #endif
368 #ifdef SIGINT
369 x = PyInt_FromLong(SIGINT);
370 PyDict_SetItemString(d, "SIGINT", x);
371 Py_XDECREF(x);
372 #endif
373 #ifdef SIGBREAK
374 x = PyInt_FromLong(SIGBREAK);
375 PyDict_SetItemString(d, "SIGBREAK", x);
376 Py_XDECREF(x);
377 #endif
378 #ifdef SIGQUIT
379 x = PyInt_FromLong(SIGQUIT);
380 PyDict_SetItemString(d, "SIGQUIT", x);
381 Py_XDECREF(x);
382 #endif
383 #ifdef SIGILL
384 x = PyInt_FromLong(SIGILL);
385 PyDict_SetItemString(d, "SIGILL", x);
386 Py_XDECREF(x);
387 #endif
388 #ifdef SIGTRAP
389 x = PyInt_FromLong(SIGTRAP);
390 PyDict_SetItemString(d, "SIGTRAP", x);
391 Py_XDECREF(x);
392 #endif
393 #ifdef SIGIOT
394 x = PyInt_FromLong(SIGIOT);
395 PyDict_SetItemString(d, "SIGIOT", x);
396 Py_XDECREF(x);
397 #endif
398 #ifdef SIGABRT
399 x = PyInt_FromLong(SIGABRT);
400 PyDict_SetItemString(d, "SIGABRT", x);
401 Py_XDECREF(x);
402 #endif
403 #ifdef SIGEMT
404 x = PyInt_FromLong(SIGEMT);
405 PyDict_SetItemString(d, "SIGEMT", x);
406 Py_XDECREF(x);
407 #endif
408 #ifdef SIGFPE
409 x = PyInt_FromLong(SIGFPE);
410 PyDict_SetItemString(d, "SIGFPE", x);
411 Py_XDECREF(x);
412 #endif
413 #ifdef SIGKILL
414 x = PyInt_FromLong(SIGKILL);
415 PyDict_SetItemString(d, "SIGKILL", x);
416 Py_XDECREF(x);
417 #endif
418 #ifdef SIGBUS
419 x = PyInt_FromLong(SIGBUS);
420 PyDict_SetItemString(d, "SIGBUS", x);
421 Py_XDECREF(x);
422 #endif
423 #ifdef SIGSEGV
424 x = PyInt_FromLong(SIGSEGV);
425 PyDict_SetItemString(d, "SIGSEGV", x);
426 Py_XDECREF(x);
427 #endif
428 #ifdef SIGSYS
429 x = PyInt_FromLong(SIGSYS);
430 PyDict_SetItemString(d, "SIGSYS", x);
431 Py_XDECREF(x);
432 #endif
433 #ifdef SIGPIPE
434 x = PyInt_FromLong(SIGPIPE);
435 PyDict_SetItemString(d, "SIGPIPE", x);
436 Py_XDECREF(x);
437 #endif
438 #ifdef SIGALRM
439 x = PyInt_FromLong(SIGALRM);
440 PyDict_SetItemString(d, "SIGALRM", x);
441 Py_XDECREF(x);
442 #endif
443 #ifdef SIGTERM
444 x = PyInt_FromLong(SIGTERM);
445 PyDict_SetItemString(d, "SIGTERM", x);
446 Py_XDECREF(x);
447 #endif
448 #ifdef SIGUSR1
449 x = PyInt_FromLong(SIGUSR1);
450 PyDict_SetItemString(d, "SIGUSR1", x);
451 Py_XDECREF(x);
452 #endif
453 #ifdef SIGUSR2
454 x = PyInt_FromLong(SIGUSR2);
455 PyDict_SetItemString(d, "SIGUSR2", x);
456 Py_XDECREF(x);
457 #endif
458 #ifdef SIGCLD
459 x = PyInt_FromLong(SIGCLD);
460 PyDict_SetItemString(d, "SIGCLD", x);
461 Py_XDECREF(x);
462 #endif
463 #ifdef SIGCHLD
464 x = PyInt_FromLong(SIGCHLD);
465 PyDict_SetItemString(d, "SIGCHLD", x);
466 Py_XDECREF(x);
467 #endif
468 #ifdef SIGPWR
469 x = PyInt_FromLong(SIGPWR);
470 PyDict_SetItemString(d, "SIGPWR", x);
471 Py_XDECREF(x);
472 #endif
473 #ifdef SIGIO
474 x = PyInt_FromLong(SIGIO);
475 PyDict_SetItemString(d, "SIGIO", x);
476 Py_XDECREF(x);
477 #endif
478 #ifdef SIGURG
479 x = PyInt_FromLong(SIGURG);
480 PyDict_SetItemString(d, "SIGURG", x);
481 Py_XDECREF(x);
482 #endif
483 #ifdef SIGWINCH
484 x = PyInt_FromLong(SIGWINCH);
485 PyDict_SetItemString(d, "SIGWINCH", x);
486 Py_XDECREF(x);
487 #endif
488 #ifdef SIGPOLL
489 x = PyInt_FromLong(SIGPOLL);
490 PyDict_SetItemString(d, "SIGPOLL", x);
491 Py_XDECREF(x);
492 #endif
493 #ifdef SIGSTOP
494 x = PyInt_FromLong(SIGSTOP);
495 PyDict_SetItemString(d, "SIGSTOP", x);
496 Py_XDECREF(x);
497 #endif
498 #ifdef SIGTSTP
499 x = PyInt_FromLong(SIGTSTP);
500 PyDict_SetItemString(d, "SIGTSTP", x);
501 Py_XDECREF(x);
502 #endif
503 #ifdef SIGCONT
504 x = PyInt_FromLong(SIGCONT);
505 PyDict_SetItemString(d, "SIGCONT", x);
506 Py_XDECREF(x);
507 #endif
508 #ifdef SIGTTIN
509 x = PyInt_FromLong(SIGTTIN);
510 PyDict_SetItemString(d, "SIGTTIN", x);
511 Py_XDECREF(x);
512 #endif
513 #ifdef SIGTTOU
514 x = PyInt_FromLong(SIGTTOU);
515 PyDict_SetItemString(d, "SIGTTOU", x);
516 Py_XDECREF(x);
517 #endif
518 #ifdef SIGVTALRM
519 x = PyInt_FromLong(SIGVTALRM);
520 PyDict_SetItemString(d, "SIGVTALRM", x);
521 Py_XDECREF(x);
522 #endif
523 #ifdef SIGPROF
524 x = PyInt_FromLong(SIGPROF);
525 PyDict_SetItemString(d, "SIGPROF", x);
526 Py_XDECREF(x);
527 #endif
528 #ifdef SIGXCPU
529 x = PyInt_FromLong(SIGXCPU);
530 PyDict_SetItemString(d, "SIGXCPU", x);
531 Py_XDECREF(x);
532 #endif
533 #ifdef SIGXFSZ
534 x = PyInt_FromLong(SIGXFSZ);
535 PyDict_SetItemString(d, "SIGXFSZ", x);
536 Py_XDECREF(x);
537 #endif
538 #ifdef SIGRTMIN
539 x = PyInt_FromLong(SIGRTMIN);
540 PyDict_SetItemString(d, "SIGRTMIN", x);
541 Py_XDECREF(x);
542 #endif
543 #ifdef SIGRTMAX
544 x = PyInt_FromLong(SIGRTMAX);
545 PyDict_SetItemString(d, "SIGRTMAX", x);
546 Py_XDECREF(x);
547 #endif
548 #ifdef SIGINFO
549 x = PyInt_FromLong(SIGINFO);
550 PyDict_SetItemString(d, "SIGINFO", x);
551 Py_XDECREF(x);
552 #endif
553 if (!PyErr_Occurred())
554 return;
556 /* Check for errors */
557 finally:
558 return;
561 static void
562 finisignal(void)
564 int i;
565 PyObject *func;
567 PyOS_setsig(SIGINT, old_siginthandler);
568 old_siginthandler = SIG_DFL;
570 for (i = 1; i < NSIG; i++) {
571 func = Handlers[i].func;
572 Handlers[i].tripped = 0;
573 Handlers[i].func = NULL;
574 if (i != SIGINT && func != NULL && func != Py_None &&
575 func != DefaultHandler && func != IgnoreHandler)
576 PyOS_setsig(i, SIG_DFL);
577 Py_XDECREF(func);
580 Py_XDECREF(IntHandler);
581 IntHandler = NULL;
582 Py_XDECREF(DefaultHandler);
583 DefaultHandler = NULL;
584 Py_XDECREF(IgnoreHandler);
585 IgnoreHandler = NULL;
589 /* Declared in pyerrors.h */
591 PyErr_CheckSignals(void)
593 int i;
594 PyObject *f;
596 if (!is_tripped)
597 return 0;
598 #ifdef WITH_THREAD
599 if (PyThread_get_thread_ident() != main_thread)
600 return 0;
601 #endif
602 if (!(f = (PyObject *)PyEval_GetFrame()))
603 f = Py_None;
605 for (i = 1; i < NSIG; i++) {
606 if (Handlers[i].tripped) {
607 PyObject *result = NULL;
608 PyObject *arglist = Py_BuildValue("(iO)", i, f);
609 Handlers[i].tripped = 0;
611 if (arglist) {
612 result = PyEval_CallObject(Handlers[i].func,
613 arglist);
614 Py_DECREF(arglist);
616 if (!result)
617 return -1;
619 Py_DECREF(result);
622 is_tripped = 0;
623 return 0;
627 /* Replacements for intrcheck.c functionality
628 * Declared in pyerrors.h
630 void
631 PyErr_SetInterrupt(void)
633 is_tripped++;
634 Handlers[SIGINT].tripped = 1;
635 Py_AddPendingCall((int (*)(void *))PyErr_CheckSignals, NULL);
638 void
639 PyOS_InitInterrupts(void)
641 initsignal();
642 _PyImport_FixupExtension("signal", "signal");
645 void
646 PyOS_FiniInterrupts(void)
648 finisignal();
652 PyOS_InterruptOccurred(void)
654 if (Handlers[SIGINT].tripped) {
655 #ifdef WITH_THREAD
656 if (PyThread_get_thread_ident() != main_thread)
657 return 0;
658 #endif
659 Handlers[SIGINT].tripped = 0;
660 return 1;
662 return 0;
665 void
666 PyOS_AfterFork(void)
668 #ifdef WITH_THREAD
669 PyEval_ReInitThreads();
670 main_thread = PyThread_get_thread_ident();
671 main_pid = getpid();
672 _PyImport_ReInitLock();
673 #endif