2 /* Signal module -- many thanks to Lance Ellinghaus */
4 /* XXX Signals should be recorded per thread, now we have thread state. */
16 #ifdef HAVE_SYS_TIME_H
21 #define SIG_ERR ((PyOS_sighandler_t)(-1))
24 #if defined(PYOS_OS2) && !defined(PYCC_GCC)
31 # define NSIG _NSIG /* For BSD/SysV */
32 # elif defined(_SIGMAX)
33 # define NSIG (_SIGMAX + 1) /* For QNX */
34 # elif defined(SIGMAX)
35 # define NSIG (SIGMAX + 1) /* For djgpp */
37 # define NSIG 64 /* Use a reasonable default value */
43 NOTES ON THE INTERACTION BETWEEN SIGNALS AND THREADS
45 When threads are supported, we want the following semantics:
47 - only the main thread can set a signal handler
48 - any thread can get a signal handler
49 - signals are only delivered to the main thread
51 I.e. we don't support "synchronous signals" like SIGFPE (catching
52 this doesn't make much sense in Python anyway) nor do we support
53 signals as a means of inter-thread communication, since not all
54 thread implementations support that (at least our thread library
57 We still have the problem that in some implementations signals
58 generated by the keyboard (e.g. SIGINT) are delivered to all
59 threads (e.g. SGI), while in others (e.g. Solaris) such signals are
60 delivered to one random thread (an intermediate possibility would
61 be to deliver it to the main thread -- POSIX?). For now, we have
62 a working implementation that works in all three cases -- the
63 handler ignores signals if getpid() isn't the same as in the main
64 thread. XXX This is a hack.
66 GNU pth is a user-space threading library, and as such, all threads
67 run within the same process. In this case, if the currently running
68 thread is not the main_thread, send the signal to the main_thread.
72 #include <sys/types.h> /* For pid_t */
74 static long main_thread
;
75 static pid_t main_pid
;
83 static sig_atomic_t wakeup_fd
= -1;
85 /* Speed up sigcheck() when none tripped */
86 static volatile sig_atomic_t is_tripped
= 0;
88 static PyObject
*DefaultHandler
;
89 static PyObject
*IgnoreHandler
;
90 static PyObject
*IntHandler
;
92 /* On Solaris 8, gcc will produce a warning that the function
93 declaration is not a prototype. This is caused by the definition of
94 SIG_DFL as (void (*)())0; the correct declaration would have been
97 static PyOS_sighandler_t old_siginthandler
= SIG_DFL
;
100 static PyObject
*ItimerError
;
102 /* auxiliary functions for setitimer/getitimer */
104 timeval_from_double(double d
, struct timeval
*tv
)
106 tv
->tv_sec
= floor(d
);
107 tv
->tv_usec
= fmod(d
, 1.0) * 1000000.0;
110 Py_LOCAL_INLINE(double)
111 double_from_timeval(struct timeval
*tv
)
113 return tv
->tv_sec
+ (double)(tv
->tv_usec
/ 1000000.0);
117 itimer_retval(struct itimerval
*iv
)
125 if(!(v
= PyFloat_FromDouble(double_from_timeval(&iv
->it_value
)))) {
130 PyTuple_SET_ITEM(r
, 0, v
);
132 if(!(v
= PyFloat_FromDouble(double_from_timeval(&iv
->it_interval
)))) {
137 PyTuple_SET_ITEM(r
, 1, v
);
144 signal_default_int_handler(PyObject
*self
, PyObject
*args
)
146 PyErr_SetNone(PyExc_KeyboardInterrupt
);
150 PyDoc_STRVAR(default_int_handler_doc
,
151 "default_int_handler(...)\n\
153 The default handler for SIGINT installed by Python.\n\
154 It raises KeyboardInterrupt.");
158 checksignals_witharg(void * unused
)
160 return PyErr_CheckSignals();
164 signal_handler(int sig_num
)
168 if (PyThread_get_thread_ident() != main_thread
) {
169 pth_raise(*(pth_t
*) main_thread
, sig_num
);
173 /* See NOTES section above */
174 if (getpid() == main_pid
) {
176 Handlers
[sig_num
].tripped
= 1;
177 /* Set is_tripped after setting .tripped, as it gets
178 cleared in PyErr_CheckSignals() before .tripped. */
180 Py_AddPendingCall(checksignals_witharg
, NULL
);
182 write(wakeup_fd
, "\0", 1);
187 if (sig_num
== SIGCHLD
) {
188 /* To avoid infinite recursion, this signal remains
189 reset until explicit re-instated.
190 Don't clear the 'func' field as it is our pointer
191 to the Python handler... */
195 PyOS_setsig(sig_num
, signal_handler
);
201 signal_alarm(PyObject
*self
, PyObject
*args
)
204 if (!PyArg_ParseTuple(args
, "i:alarm", &t
))
206 /* alarm() returns the number of seconds remaining */
207 return PyLong_FromLong((long)alarm(t
));
210 PyDoc_STRVAR(alarm_doc
,
213 Arrange for SIGALRM to arrive after the given number of seconds.");
218 signal_pause(PyObject
*self
)
220 Py_BEGIN_ALLOW_THREADS
223 /* make sure that any exceptions that got raised are propagated
226 if (PyErr_CheckSignals())
232 PyDoc_STRVAR(pause_doc
,
235 Wait until a signal arrives.");
241 signal_signal(PyObject
*self
, PyObject
*args
)
245 PyObject
*old_handler
;
247 if (!PyArg_ParseTuple(args
, "iO:signal", &sig_num
, &obj
))
250 if (PyThread_get_thread_ident() != main_thread
) {
251 PyErr_SetString(PyExc_ValueError
,
252 "signal only works in main thread");
256 if (sig_num
< 1 || sig_num
>= NSIG
) {
257 PyErr_SetString(PyExc_ValueError
,
258 "signal number out of range");
261 if (obj
== IgnoreHandler
)
263 else if (obj
== DefaultHandler
)
265 else if (!PyCallable_Check(obj
)) {
266 PyErr_SetString(PyExc_TypeError
,
267 "signal handler must be signal.SIG_IGN, signal.SIG_DFL, or a callable object");
271 func
= signal_handler
;
272 if (PyOS_setsig(sig_num
, func
) == SIG_ERR
) {
273 PyErr_SetFromErrno(PyExc_RuntimeError
);
276 old_handler
= Handlers
[sig_num
].func
;
277 Handlers
[sig_num
].tripped
= 0;
279 Handlers
[sig_num
].func
= obj
;
283 PyDoc_STRVAR(signal_doc
,
284 "signal(sig, action) -> action\n\
286 Set the action for the given signal. The action can be SIG_DFL,\n\
287 SIG_IGN, or a callable Python object. The previous action is\n\
288 returned. See getsignal() for possible return values.\n\
290 *** IMPORTANT NOTICE ***\n\
291 A signal handler function is called with two arguments:\n\
292 the first is the signal number, the second is the interrupted stack frame.");
296 signal_getsignal(PyObject
*self
, PyObject
*args
)
299 PyObject
*old_handler
;
300 if (!PyArg_ParseTuple(args
, "i:getsignal", &sig_num
))
302 if (sig_num
< 1 || sig_num
>= NSIG
) {
303 PyErr_SetString(PyExc_ValueError
,
304 "signal number out of range");
307 old_handler
= Handlers
[sig_num
].func
;
308 Py_INCREF(old_handler
);
312 PyDoc_STRVAR(getsignal_doc
,
313 "getsignal(sig) -> action\n\
315 Return the current action for the given signal. The return value can be:\n\
316 SIG_IGN -- if the signal is being ignored\n\
317 SIG_DFL -- if the default action for the signal is in effect\n\
318 None -- if an unknown handler is in effect\n\
319 anything else -- the callable Python object used as a handler");
321 #ifdef HAVE_SIGINTERRUPT
322 PyDoc_STRVAR(siginterrupt_doc
,
323 "siginterrupt(sig, flag) -> None\n\
324 change system call restart behaviour: if flag is False, system calls\n\
325 will be restarted when interrupted by signal sig, else system calls\n\
326 will be interrupted.");
329 signal_siginterrupt(PyObject
*self
, PyObject
*args
)
334 if (!PyArg_ParseTuple(args
, "ii:siginterrupt", &sig_num
, &flag
))
336 if (sig_num
< 1 || sig_num
>= NSIG
) {
337 PyErr_SetString(PyExc_ValueError
,
338 "signal number out of range");
341 if (siginterrupt(sig_num
, flag
)<0) {
342 PyErr_SetFromErrno(PyExc_RuntimeError
);
353 signal_set_wakeup_fd(PyObject
*self
, PyObject
*args
)
357 if (!PyArg_ParseTuple(args
, "i:set_wakeup_fd", &fd
))
360 if (PyThread_get_thread_ident() != main_thread
) {
361 PyErr_SetString(PyExc_ValueError
,
362 "set_wakeup_fd only works in main thread");
366 if (fd
!= -1 && fstat(fd
, &buf
) != 0) {
367 PyErr_SetString(PyExc_ValueError
, "invalid fd");
372 return PyLong_FromLong(old_fd
);
375 PyDoc_STRVAR(set_wakeup_fd_doc
,
376 "set_wakeup_fd(fd) -> fd\n\
378 Sets the fd to be written to (with '\\0') when a signal\n\
379 comes in. A library can use this to wakeup select or poll.\n\
380 The previous fd is returned.\n\
382 The fd must be non-blocking.");
384 /* C API for the same, without all the error checking */
386 PySignal_SetWakeupFd(int fd
)
388 int old_fd
= wakeup_fd
;
396 #ifdef HAVE_SETITIMER
398 signal_setitimer(PyObject
*self
, PyObject
*args
)
403 struct itimerval
new, old
;
405 if(!PyArg_ParseTuple(args
, "id|d:setitimer", &which
, &first
, &interval
))
408 timeval_from_double(first
, &new.it_value
);
409 timeval_from_double(interval
, &new.it_interval
);
410 /* Let OS check "which" value */
411 if (setitimer(which
, &new, &old
) != 0) {
412 PyErr_SetFromErrno(ItimerError
);
416 return itimer_retval(&old
);
419 PyDoc_STRVAR(setitimer_doc
,
420 "setitimer(which, seconds[, interval])\n\
422 Sets given itimer (one of ITIMER_REAL, ITIMER_VIRTUAL\n\
423 or ITIMER_PROF) to fire after value seconds and after\n\
424 that every interval seconds.\n\
425 The itimer can be cleared by setting seconds to zero.\n\
427 Returns old values as a tuple: (delay, interval).");
431 #ifdef HAVE_GETITIMER
433 signal_getitimer(PyObject
*self
, PyObject
*args
)
436 struct itimerval old
;
438 if (!PyArg_ParseTuple(args
, "i:getitimer", &which
))
441 if (getitimer(which
, &old
) != 0) {
442 PyErr_SetFromErrno(ItimerError
);
446 return itimer_retval(&old
);
449 PyDoc_STRVAR(getitimer_doc
,
452 Returns current value of given itimer.");
456 /* List of functions defined in the module */
457 static PyMethodDef signal_methods
[] = {
459 {"alarm", signal_alarm
, METH_VARARGS
, alarm_doc
},
461 #ifdef HAVE_SETITIMER
462 {"setitimer", signal_setitimer
, METH_VARARGS
, setitimer_doc
},
464 #ifdef HAVE_GETITIMER
465 {"getitimer", signal_getitimer
, METH_VARARGS
, getitimer_doc
},
467 {"signal", signal_signal
, METH_VARARGS
, signal_doc
},
468 {"getsignal", signal_getsignal
, METH_VARARGS
, getsignal_doc
},
469 {"set_wakeup_fd", signal_set_wakeup_fd
, METH_VARARGS
, set_wakeup_fd_doc
},
470 #ifdef HAVE_SIGINTERRUPT
471 {"siginterrupt", signal_siginterrupt
, METH_VARARGS
, siginterrupt_doc
},
474 {"pause", (PyCFunction
)signal_pause
,
475 METH_NOARGS
,pause_doc
},
477 {"default_int_handler", signal_default_int_handler
,
478 METH_VARARGS
, default_int_handler_doc
},
479 {NULL
, NULL
} /* sentinel */
483 PyDoc_STRVAR(module_doc
,
484 "This module provides mechanisms to use signal handlers in Python.\n\
488 alarm() -- cause SIGALRM after a specified time [Unix only]\n\
489 setitimer() -- cause a signal (described below) after a specified\n\
490 float time and the timer may restart then [Unix only]\n\
491 getitimer() -- get current value of timer [Unix only]\n\
492 signal() -- set the action for a given signal\n\
493 getsignal() -- get the signal action for a given signal\n\
494 pause() -- wait until a signal arrives [Unix only]\n\
495 default_int_handler() -- default SIGINT handler\n\
498 SIG_DFL -- used to refer to the system default handler\n\
499 SIG_IGN -- used to ignore the signal\n\
500 NSIG -- number of defined signals\n\
501 SIGINT, SIGTERM, etc. -- signal numbers\n\
504 ITIMER_REAL -- decrements in real time, and delivers SIGALRM upon\n\
506 ITIMER_VIRTUAL -- decrements only when the process is executing,\n\
507 and delivers SIGVTALRM upon expiration\n\
508 ITIMER_PROF -- decrements both when the process is executing and\n\
509 when the system is executing on behalf of the process.\n\
510 Coupled with ITIMER_VIRTUAL, this timer is usually\n\
511 used to profile the time spent by the application\n\
512 in user and kernel space. SIGPROF is delivered upon\n\
515 *** IMPORTANT NOTICE ***\n\
516 A signal handler function is called with two arguments:\n\
517 the first is the signal number, the second is the interrupted stack frame.");
519 static struct PyModuleDef signalmodule
= {
520 PyModuleDef_HEAD_INIT
,
538 main_thread
= PyThread_get_thread_ident();
542 /* Create the module and add the functions */
543 m
= PyModule_Create(&signalmodule
);
547 /* Add some symbolic constants to the module */
548 d
= PyModule_GetDict(m
);
550 x
= DefaultHandler
= PyLong_FromVoidPtr((void *)SIG_DFL
);
551 if (!x
|| PyDict_SetItemString(d
, "SIG_DFL", x
) < 0)
554 x
= IgnoreHandler
= PyLong_FromVoidPtr((void *)SIG_IGN
);
555 if (!x
|| PyDict_SetItemString(d
, "SIG_IGN", x
) < 0)
558 x
= PyLong_FromLong((long)NSIG
);
559 if (!x
|| PyDict_SetItemString(d
, "NSIG", x
) < 0)
563 x
= IntHandler
= PyDict_GetItemString(d
, "default_int_handler");
566 Py_INCREF(IntHandler
);
568 Handlers
[0].tripped
= 0;
569 for (i
= 1; i
< NSIG
; i
++) {
572 Handlers
[i
].tripped
= 0;
574 Handlers
[i
].func
= DefaultHandler
;
575 else if (t
== SIG_IGN
)
576 Handlers
[i
].func
= IgnoreHandler
;
578 Handlers
[i
].func
= Py_None
; /* None of our business */
579 Py_INCREF(Handlers
[i
].func
);
581 if (Handlers
[SIGINT
].func
== DefaultHandler
) {
582 /* Install default int handler */
583 Py_INCREF(IntHandler
);
584 Py_DECREF(Handlers
[SIGINT
].func
);
585 Handlers
[SIGINT
].func
= IntHandler
;
586 old_siginthandler
= PyOS_setsig(SIGINT
, signal_handler
);
590 x
= PyLong_FromLong(SIGHUP
);
591 PyDict_SetItemString(d
, "SIGHUP", x
);
595 x
= PyLong_FromLong(SIGINT
);
596 PyDict_SetItemString(d
, "SIGINT", x
);
600 x
= PyLong_FromLong(SIGBREAK
);
601 PyDict_SetItemString(d
, "SIGBREAK", x
);
605 x
= PyLong_FromLong(SIGQUIT
);
606 PyDict_SetItemString(d
, "SIGQUIT", x
);
610 x
= PyLong_FromLong(SIGILL
);
611 PyDict_SetItemString(d
, "SIGILL", x
);
615 x
= PyLong_FromLong(SIGTRAP
);
616 PyDict_SetItemString(d
, "SIGTRAP", x
);
620 x
= PyLong_FromLong(SIGIOT
);
621 PyDict_SetItemString(d
, "SIGIOT", x
);
625 x
= PyLong_FromLong(SIGABRT
);
626 PyDict_SetItemString(d
, "SIGABRT", x
);
630 x
= PyLong_FromLong(SIGEMT
);
631 PyDict_SetItemString(d
, "SIGEMT", x
);
635 x
= PyLong_FromLong(SIGFPE
);
636 PyDict_SetItemString(d
, "SIGFPE", x
);
640 x
= PyLong_FromLong(SIGKILL
);
641 PyDict_SetItemString(d
, "SIGKILL", x
);
645 x
= PyLong_FromLong(SIGBUS
);
646 PyDict_SetItemString(d
, "SIGBUS", x
);
650 x
= PyLong_FromLong(SIGSEGV
);
651 PyDict_SetItemString(d
, "SIGSEGV", x
);
655 x
= PyLong_FromLong(SIGSYS
);
656 PyDict_SetItemString(d
, "SIGSYS", x
);
660 x
= PyLong_FromLong(SIGPIPE
);
661 PyDict_SetItemString(d
, "SIGPIPE", x
);
665 x
= PyLong_FromLong(SIGALRM
);
666 PyDict_SetItemString(d
, "SIGALRM", x
);
670 x
= PyLong_FromLong(SIGTERM
);
671 PyDict_SetItemString(d
, "SIGTERM", x
);
675 x
= PyLong_FromLong(SIGUSR1
);
676 PyDict_SetItemString(d
, "SIGUSR1", x
);
680 x
= PyLong_FromLong(SIGUSR2
);
681 PyDict_SetItemString(d
, "SIGUSR2", x
);
685 x
= PyLong_FromLong(SIGCLD
);
686 PyDict_SetItemString(d
, "SIGCLD", x
);
690 x
= PyLong_FromLong(SIGCHLD
);
691 PyDict_SetItemString(d
, "SIGCHLD", x
);
695 x
= PyLong_FromLong(SIGPWR
);
696 PyDict_SetItemString(d
, "SIGPWR", x
);
700 x
= PyLong_FromLong(SIGIO
);
701 PyDict_SetItemString(d
, "SIGIO", x
);
705 x
= PyLong_FromLong(SIGURG
);
706 PyDict_SetItemString(d
, "SIGURG", x
);
710 x
= PyLong_FromLong(SIGWINCH
);
711 PyDict_SetItemString(d
, "SIGWINCH", x
);
715 x
= PyLong_FromLong(SIGPOLL
);
716 PyDict_SetItemString(d
, "SIGPOLL", x
);
720 x
= PyLong_FromLong(SIGSTOP
);
721 PyDict_SetItemString(d
, "SIGSTOP", x
);
725 x
= PyLong_FromLong(SIGTSTP
);
726 PyDict_SetItemString(d
, "SIGTSTP", x
);
730 x
= PyLong_FromLong(SIGCONT
);
731 PyDict_SetItemString(d
, "SIGCONT", x
);
735 x
= PyLong_FromLong(SIGTTIN
);
736 PyDict_SetItemString(d
, "SIGTTIN", x
);
740 x
= PyLong_FromLong(SIGTTOU
);
741 PyDict_SetItemString(d
, "SIGTTOU", x
);
745 x
= PyLong_FromLong(SIGVTALRM
);
746 PyDict_SetItemString(d
, "SIGVTALRM", x
);
750 x
= PyLong_FromLong(SIGPROF
);
751 PyDict_SetItemString(d
, "SIGPROF", x
);
755 x
= PyLong_FromLong(SIGXCPU
);
756 PyDict_SetItemString(d
, "SIGXCPU", x
);
760 x
= PyLong_FromLong(SIGXFSZ
);
761 PyDict_SetItemString(d
, "SIGXFSZ", x
);
765 x
= PyLong_FromLong(SIGRTMIN
);
766 PyDict_SetItemString(d
, "SIGRTMIN", x
);
770 x
= PyLong_FromLong(SIGRTMAX
);
771 PyDict_SetItemString(d
, "SIGRTMAX", x
);
775 x
= PyLong_FromLong(SIGINFO
);
776 PyDict_SetItemString(d
, "SIGINFO", x
);
781 x
= PyLong_FromLong(ITIMER_REAL
);
782 PyDict_SetItemString(d
, "ITIMER_REAL", x
);
785 #ifdef ITIMER_VIRTUAL
786 x
= PyLong_FromLong(ITIMER_VIRTUAL
);
787 PyDict_SetItemString(d
, "ITIMER_VIRTUAL", x
);
791 x
= PyLong_FromLong(ITIMER_PROF
);
792 PyDict_SetItemString(d
, "ITIMER_PROF", x
);
796 #if defined (HAVE_SETITIMER) || defined (HAVE_GETITIMER)
797 ItimerError
= PyErr_NewException("signal.ItimerError",
798 PyExc_IOError
, NULL
);
799 if (ItimerError
!= NULL
)
800 PyDict_SetItemString(d
, "ItimerError", ItimerError
);
803 if (PyErr_Occurred()) {
818 PyOS_setsig(SIGINT
, old_siginthandler
);
819 old_siginthandler
= SIG_DFL
;
821 for (i
= 1; i
< NSIG
; i
++) {
822 func
= Handlers
[i
].func
;
823 Handlers
[i
].tripped
= 0;
824 Handlers
[i
].func
= NULL
;
825 if (i
!= SIGINT
&& func
!= NULL
&& func
!= Py_None
&&
826 func
!= DefaultHandler
&& func
!= IgnoreHandler
)
827 PyOS_setsig(i
, SIG_DFL
);
831 Py_XDECREF(IntHandler
);
833 Py_XDECREF(DefaultHandler
);
834 DefaultHandler
= NULL
;
835 Py_XDECREF(IgnoreHandler
);
836 IgnoreHandler
= NULL
;
840 /* Declared in pyerrors.h */
842 PyErr_CheckSignals(void)
851 if (PyThread_get_thread_ident() != main_thread
)
856 * The is_tripped variable is meant to speed up the calls to
857 * PyErr_CheckSignals (both directly or via pending calls) when no
858 * signal has arrived. This variable is set to 1 when a signal arrives
859 * and it is set to 0 here, when we know some signals arrived. This way
860 * we can run the registered handlers with no signals blocked.
862 * NOTE: with this approach we can have a situation where is_tripped is
863 * 1 but we have no more signals to handle (Handlers[i].tripped
864 * is 0 for every signal i). This won't do us any harm (except
865 * we're gonna spent some cycles for nothing). This happens when
866 * we receive a signal i after we zero is_tripped and before we
867 * check Handlers[i].tripped.
871 if (!(f
= (PyObject
*)PyEval_GetFrame()))
874 for (i
= 1; i
< NSIG
; i
++) {
875 if (Handlers
[i
].tripped
) {
876 PyObject
*result
= NULL
;
877 PyObject
*arglist
= Py_BuildValue("(iO)", i
, f
);
878 Handlers
[i
].tripped
= 0;
881 result
= PyEval_CallObject(Handlers
[i
].func
,
896 /* Replacements for intrcheck.c functionality
897 * Declared in pyerrors.h
900 PyErr_SetInterrupt(void)
903 Handlers
[SIGINT
].tripped
= 1;
904 Py_AddPendingCall((int (*)(void *))PyErr_CheckSignals
, NULL
);
908 PyOS_InitInterrupts(void)
910 PyObject
*m
= PyInit_signal();
912 _PyImport_FixupExtension(m
, "signal", "signal");
918 PyOS_FiniInterrupts(void)
924 PyOS_InterruptOccurred(void)
926 if (Handlers
[SIGINT
].tripped
) {
928 if (PyThread_get_thread_ident() != main_thread
)
931 Handlers
[SIGINT
].tripped
= 0;
941 PyEval_ReInitThreads();
942 main_thread
= PyThread_get_thread_ident();
944 _PyImport_ReInitLock();
945 PyThread_ReInitTLS();