Remove a ?? in the description of Mac OS support.
[python/dscho.git] / Modules / signalmodule.c
blobb9f7963f8df2774a50f75cc2ab1f58c1883135b2
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 static PyOS_sighandler_t old_siginthandler = SIG_DFL;
91 static PyObject *
92 signal_default_int_handler(PyObject *self, PyObject *args)
94 PyErr_SetNone(PyExc_KeyboardInterrupt);
95 return NULL;
98 static char default_int_handler_doc[] =
99 "default_int_handler(...)\n\
101 The default handler for SIGINT instated by Python.\n\
102 It raises KeyboardInterrupt.";
105 static int
106 checksignals_witharg(void * unused)
108 return PyErr_CheckSignals();
111 static void
112 signal_handler(int sig_num)
114 #ifdef WITH_THREAD
115 #ifdef WITH_PTH
116 if (PyThread_get_thread_ident() != main_thread) {
117 pth_raise(*(pth_t *) main_thread, sig_num);
118 return;
120 #endif
121 /* See NOTES section above */
122 if (getpid() == main_pid) {
123 #endif
124 is_tripped++;
125 Handlers[sig_num].tripped = 1;
126 Py_AddPendingCall(checksignals_witharg, NULL);
127 #ifdef WITH_THREAD
129 #endif
130 #ifdef SIGCHLD
131 if (sig_num == SIGCHLD) {
132 /* To avoid infinite recursion, this signal remains
133 reset until explicit re-instated.
134 Don't clear the 'func' field as it is our pointer
135 to the Python handler... */
136 return;
138 #endif
139 #ifdef HAVE_SIGINTERRUPT
140 siginterrupt(sig_num, 1);
141 #endif
142 PyOS_setsig(sig_num, signal_handler);
146 #ifdef HAVE_ALARM
147 static PyObject *
148 signal_alarm(PyObject *self, PyObject *args)
150 int t;
151 if (!PyArg_Parse(args, "i", &t))
152 return NULL;
153 /* alarm() returns the number of seconds remaining */
154 return PyInt_FromLong(alarm(t));
157 static char alarm_doc[] =
158 "alarm(seconds)\n\
160 Arrange for SIGALRM to arrive after the given number of seconds.";
161 #endif
163 #ifdef HAVE_PAUSE
164 static PyObject *
165 signal_pause(PyObject *self, PyObject *args)
167 if (!PyArg_NoArgs(args))
168 return NULL;
170 Py_BEGIN_ALLOW_THREADS
171 (void)pause();
172 Py_END_ALLOW_THREADS
173 /* make sure that any exceptions that got raised are propagated
174 * back into Python
176 if (PyErr_CheckSignals())
177 return NULL;
179 Py_INCREF(Py_None);
180 return Py_None;
182 static char pause_doc[] =
183 "pause()\n\
185 Wait until a signal arrives.";
187 #endif
190 static PyObject *
191 signal_signal(PyObject *self, PyObject *args)
193 PyObject *obj;
194 int sig_num;
195 PyObject *old_handler;
196 void (*func)(int);
197 if (!PyArg_Parse(args, "(iO)", &sig_num, &obj))
198 return NULL;
199 #ifdef WITH_THREAD
200 if (PyThread_get_thread_ident() != main_thread) {
201 PyErr_SetString(PyExc_ValueError,
202 "signal only works in main thread");
203 return NULL;
205 #endif
206 if (sig_num < 1 || sig_num >= NSIG) {
207 PyErr_SetString(PyExc_ValueError,
208 "signal number out of range");
209 return NULL;
211 if (obj == IgnoreHandler)
212 func = SIG_IGN;
213 else if (obj == DefaultHandler)
214 func = SIG_DFL;
215 else if (!PyCallable_Check(obj)) {
216 PyErr_SetString(PyExc_TypeError,
217 "signal handler must be signal.SIG_IGN, signal.SIG_DFL, or a callable object");
218 return NULL;
220 else
221 func = signal_handler;
222 #ifdef HAVE_SIGINTERRUPT
223 siginterrupt(sig_num, 1);
224 #endif
225 if (PyOS_setsig(sig_num, func) == SIG_ERR) {
226 PyErr_SetFromErrno(PyExc_RuntimeError);
227 return NULL;
229 old_handler = Handlers[sig_num].func;
230 Handlers[sig_num].tripped = 0;
231 Py_INCREF(obj);
232 Handlers[sig_num].func = obj;
233 return old_handler;
236 static char signal_doc[] =
237 "signal(sig, action) -> action\n\
239 Set the action for the given signal. The action can be SIG_DFL,\n\
240 SIG_IGN, or a callable Python object. The previous action is\n\
241 returned. See getsignal() for possible return values.\n\
243 *** IMPORTANT NOTICE ***\n\
244 A signal handler function is called with two arguments:\n\
245 the first is the signal number, the second is the interrupted stack frame.";
248 static PyObject *
249 signal_getsignal(PyObject *self, PyObject *args)
251 int sig_num;
252 PyObject *old_handler;
253 if (!PyArg_Parse(args, "i", &sig_num))
254 return NULL;
255 if (sig_num < 1 || sig_num >= NSIG) {
256 PyErr_SetString(PyExc_ValueError,
257 "signal number out of range");
258 return NULL;
260 old_handler = Handlers[sig_num].func;
261 Py_INCREF(old_handler);
262 return old_handler;
265 static char getsignal_doc[] =
266 "getsignal(sig) -> action\n\
268 Return the current action for the given signal. The return value can be:\n\
269 SIG_IGN -- if the signal is being ignored\n\
270 SIG_DFL -- if the default action for the signal is in effect\n\
271 None -- if an unknown handler is in effect\n\
272 anything else -- the callable Python object used as a handler\n\
276 /* List of functions defined in the module */
277 static PyMethodDef signal_methods[] = {
278 #ifdef HAVE_ALARM
279 {"alarm", signal_alarm, METH_OLDARGS, alarm_doc},
280 #endif
281 {"signal", signal_signal, METH_OLDARGS, signal_doc},
282 {"getsignal", signal_getsignal, METH_OLDARGS, getsignal_doc},
283 #ifdef HAVE_PAUSE
284 {"pause", signal_pause, METH_OLDARGS, pause_doc},
285 #endif
286 {"default_int_handler", signal_default_int_handler,
287 METH_OLDARGS, default_int_handler_doc},
288 {NULL, NULL} /* sentinel */
292 static char module_doc[] =
293 "This module provides mechanisms to use signal handlers in Python.\n\
295 Functions:\n\
297 alarm() -- cause SIGALRM after a specified time [Unix only]\n\
298 signal() -- set the action for a given signal\n\
299 getsignal() -- get the signal action for a given signal\n\
300 pause() -- wait until a signal arrives [Unix only]\n\
301 default_int_handler() -- default SIGINT handler\n\
303 Constants:\n\
305 SIG_DFL -- used to refer to the system default handler\n\
306 SIG_IGN -- used to ignore the signal\n\
307 NSIG -- number of defined signals\n\
309 SIGINT, SIGTERM, etc. -- signal numbers\n\
311 *** IMPORTANT NOTICE ***\n\
312 A signal handler function is called with two arguments:\n\
313 the first is the signal number, the second is the interrupted stack frame.";
315 DL_EXPORT(void)
316 initsignal(void)
318 PyObject *m, *d, *x;
319 int i;
321 #ifdef WITH_THREAD
322 main_thread = PyThread_get_thread_ident();
323 main_pid = getpid();
324 #endif
326 /* Create the module and add the functions */
327 m = Py_InitModule3("signal", signal_methods, module_doc);
329 /* Add some symbolic constants to the module */
330 d = PyModule_GetDict(m);
332 x = DefaultHandler = PyLong_FromVoidPtr((void *)SIG_DFL);
333 if (!x || PyDict_SetItemString(d, "SIG_DFL", x) < 0)
334 goto finally;
336 x = IgnoreHandler = PyLong_FromVoidPtr((void *)SIG_IGN);
337 if (!x || PyDict_SetItemString(d, "SIG_IGN", x) < 0)
338 goto finally;
340 x = PyInt_FromLong((long)NSIG);
341 if (!x || PyDict_SetItemString(d, "NSIG", x) < 0)
342 goto finally;
343 Py_DECREF(x);
345 x = IntHandler = PyDict_GetItemString(d, "default_int_handler");
346 if (!x)
347 goto finally;
348 Py_INCREF(IntHandler);
350 Handlers[0].tripped = 0;
351 for (i = 1; i < NSIG; i++) {
352 void (*t)(int);
353 t = PyOS_getsig(i);
354 Handlers[i].tripped = 0;
355 if (t == SIG_DFL)
356 Handlers[i].func = DefaultHandler;
357 else if (t == SIG_IGN)
358 Handlers[i].func = IgnoreHandler;
359 else
360 Handlers[i].func = Py_None; /* None of our business */
361 Py_INCREF(Handlers[i].func);
363 if (Handlers[SIGINT].func == DefaultHandler) {
364 /* Install default int handler */
365 Py_INCREF(IntHandler);
366 Py_DECREF(Handlers[SIGINT].func);
367 Handlers[SIGINT].func = IntHandler;
368 old_siginthandler = PyOS_setsig(SIGINT, &signal_handler);
371 #ifdef SIGHUP
372 x = PyInt_FromLong(SIGHUP);
373 PyDict_SetItemString(d, "SIGHUP", x);
374 Py_XDECREF(x);
375 #endif
376 #ifdef SIGINT
377 x = PyInt_FromLong(SIGINT);
378 PyDict_SetItemString(d, "SIGINT", x);
379 Py_XDECREF(x);
380 #endif
381 #ifdef SIGQUIT
382 x = PyInt_FromLong(SIGQUIT);
383 PyDict_SetItemString(d, "SIGQUIT", x);
384 Py_XDECREF(x);
385 #endif
386 #ifdef SIGILL
387 x = PyInt_FromLong(SIGILL);
388 PyDict_SetItemString(d, "SIGILL", x);
389 Py_XDECREF(x);
390 #endif
391 #ifdef SIGTRAP
392 x = PyInt_FromLong(SIGTRAP);
393 PyDict_SetItemString(d, "SIGTRAP", x);
394 Py_XDECREF(x);
395 #endif
396 #ifdef SIGIOT
397 x = PyInt_FromLong(SIGIOT);
398 PyDict_SetItemString(d, "SIGIOT", x);
399 Py_XDECREF(x);
400 #endif
401 #ifdef SIGABRT
402 x = PyInt_FromLong(SIGABRT);
403 PyDict_SetItemString(d, "SIGABRT", x);
404 Py_XDECREF(x);
405 #endif
406 #ifdef SIGEMT
407 x = PyInt_FromLong(SIGEMT);
408 PyDict_SetItemString(d, "SIGEMT", x);
409 Py_XDECREF(x);
410 #endif
411 #ifdef SIGFPE
412 x = PyInt_FromLong(SIGFPE);
413 PyDict_SetItemString(d, "SIGFPE", x);
414 Py_XDECREF(x);
415 #endif
416 #ifdef SIGKILL
417 x = PyInt_FromLong(SIGKILL);
418 PyDict_SetItemString(d, "SIGKILL", x);
419 Py_XDECREF(x);
420 #endif
421 #ifdef SIGBUS
422 x = PyInt_FromLong(SIGBUS);
423 PyDict_SetItemString(d, "SIGBUS", x);
424 Py_XDECREF(x);
425 #endif
426 #ifdef SIGSEGV
427 x = PyInt_FromLong(SIGSEGV);
428 PyDict_SetItemString(d, "SIGSEGV", x);
429 Py_XDECREF(x);
430 #endif
431 #ifdef SIGSYS
432 x = PyInt_FromLong(SIGSYS);
433 PyDict_SetItemString(d, "SIGSYS", x);
434 Py_XDECREF(x);
435 #endif
436 #ifdef SIGPIPE
437 x = PyInt_FromLong(SIGPIPE);
438 PyDict_SetItemString(d, "SIGPIPE", x);
439 Py_XDECREF(x);
440 #endif
441 #ifdef SIGALRM
442 x = PyInt_FromLong(SIGALRM);
443 PyDict_SetItemString(d, "SIGALRM", x);
444 Py_XDECREF(x);
445 #endif
446 #ifdef SIGTERM
447 x = PyInt_FromLong(SIGTERM);
448 PyDict_SetItemString(d, "SIGTERM", x);
449 Py_XDECREF(x);
450 #endif
451 #ifdef SIGUSR1
452 x = PyInt_FromLong(SIGUSR1);
453 PyDict_SetItemString(d, "SIGUSR1", x);
454 Py_XDECREF(x);
455 #endif
456 #ifdef SIGUSR2
457 x = PyInt_FromLong(SIGUSR2);
458 PyDict_SetItemString(d, "SIGUSR2", x);
459 Py_XDECREF(x);
460 #endif
461 #ifdef SIGCLD
462 x = PyInt_FromLong(SIGCLD);
463 PyDict_SetItemString(d, "SIGCLD", x);
464 Py_XDECREF(x);
465 #endif
466 #ifdef SIGCHLD
467 x = PyInt_FromLong(SIGCHLD);
468 PyDict_SetItemString(d, "SIGCHLD", x);
469 Py_XDECREF(x);
470 #endif
471 #ifdef SIGPWR
472 x = PyInt_FromLong(SIGPWR);
473 PyDict_SetItemString(d, "SIGPWR", x);
474 Py_XDECREF(x);
475 #endif
476 #ifdef SIGIO
477 x = PyInt_FromLong(SIGIO);
478 PyDict_SetItemString(d, "SIGIO", x);
479 Py_XDECREF(x);
480 #endif
481 #ifdef SIGURG
482 x = PyInt_FromLong(SIGURG);
483 PyDict_SetItemString(d, "SIGURG", x);
484 Py_XDECREF(x);
485 #endif
486 #ifdef SIGWINCH
487 x = PyInt_FromLong(SIGWINCH);
488 PyDict_SetItemString(d, "SIGWINCH", x);
489 Py_XDECREF(x);
490 #endif
491 #ifdef SIGPOLL
492 x = PyInt_FromLong(SIGPOLL);
493 PyDict_SetItemString(d, "SIGPOLL", x);
494 Py_XDECREF(x);
495 #endif
496 #ifdef SIGSTOP
497 x = PyInt_FromLong(SIGSTOP);
498 PyDict_SetItemString(d, "SIGSTOP", x);
499 Py_XDECREF(x);
500 #endif
501 #ifdef SIGTSTP
502 x = PyInt_FromLong(SIGTSTP);
503 PyDict_SetItemString(d, "SIGTSTP", x);
504 Py_XDECREF(x);
505 #endif
506 #ifdef SIGCONT
507 x = PyInt_FromLong(SIGCONT);
508 PyDict_SetItemString(d, "SIGCONT", x);
509 Py_XDECREF(x);
510 #endif
511 #ifdef SIGTTIN
512 x = PyInt_FromLong(SIGTTIN);
513 PyDict_SetItemString(d, "SIGTTIN", x);
514 Py_XDECREF(x);
515 #endif
516 #ifdef SIGTTOU
517 x = PyInt_FromLong(SIGTTOU);
518 PyDict_SetItemString(d, "SIGTTOU", x);
519 Py_XDECREF(x);
520 #endif
521 #ifdef SIGVTALRM
522 x = PyInt_FromLong(SIGVTALRM);
523 PyDict_SetItemString(d, "SIGVTALRM", x);
524 Py_XDECREF(x);
525 #endif
526 #ifdef SIGPROF
527 x = PyInt_FromLong(SIGPROF);
528 PyDict_SetItemString(d, "SIGPROF", x);
529 Py_XDECREF(x);
530 #endif
531 #ifdef SIGXCPU
532 x = PyInt_FromLong(SIGXCPU);
533 PyDict_SetItemString(d, "SIGXCPU", x);
534 Py_XDECREF(x);
535 #endif
536 #ifdef SIGXFSZ
537 x = PyInt_FromLong(SIGXFSZ);
538 PyDict_SetItemString(d, "SIGXFSZ", x);
539 Py_XDECREF(x);
540 #endif
541 if (!PyErr_Occurred())
542 return;
544 /* Check for errors */
545 finally:
546 return;
549 static void
550 finisignal(void)
552 int i;
553 PyObject *func;
555 PyOS_setsig(SIGINT, old_siginthandler);
556 old_siginthandler = SIG_DFL;
558 for (i = 1; i < NSIG; i++) {
559 func = Handlers[i].func;
560 Handlers[i].tripped = 0;
561 Handlers[i].func = NULL;
562 if (i != SIGINT && func != NULL && func != Py_None &&
563 func != DefaultHandler && func != IgnoreHandler)
564 PyOS_setsig(i, SIG_DFL);
565 Py_XDECREF(func);
568 Py_XDECREF(IntHandler);
569 IntHandler = NULL;
570 Py_XDECREF(DefaultHandler);
571 DefaultHandler = NULL;
572 Py_XDECREF(IgnoreHandler);
573 IgnoreHandler = NULL;
577 /* Declared in pyerrors.h */
579 PyErr_CheckSignals(void)
581 int i;
582 PyObject *f;
584 if (!is_tripped)
585 return 0;
586 #ifdef WITH_THREAD
587 if (PyThread_get_thread_ident() != main_thread)
588 return 0;
589 #endif
590 if (!(f = PyEval_GetFrame()))
591 f = Py_None;
593 for (i = 1; i < NSIG; i++) {
594 if (Handlers[i].tripped) {
595 PyObject *result = NULL;
596 PyObject *arglist = Py_BuildValue("(iO)", i, f);
597 Handlers[i].tripped = 0;
599 if (arglist) {
600 result = PyEval_CallObject(Handlers[i].func,
601 arglist);
602 Py_DECREF(arglist);
604 if (!result)
605 return -1;
607 Py_DECREF(result);
610 is_tripped = 0;
611 return 0;
615 /* Replacements for intrcheck.c functionality
616 * Declared in pyerrors.h
618 void
619 PyErr_SetInterrupt(void)
621 is_tripped++;
622 Handlers[SIGINT].tripped = 1;
623 Py_AddPendingCall((int (*)(void *))PyErr_CheckSignals, NULL);
626 void
627 PyOS_InitInterrupts(void)
629 initsignal();
630 _PyImport_FixupExtension("signal", "signal");
633 void
634 PyOS_FiniInterrupts(void)
636 finisignal();
640 PyOS_InterruptOccurred(void)
642 if (Handlers[SIGINT].tripped) {
643 #ifdef WITH_THREAD
644 if (PyThread_get_thread_ident() != main_thread)
645 return 0;
646 #endif
647 Handlers[SIGINT].tripped = 0;
648 return 1;
650 return 0;
653 void
654 PyOS_AfterFork(void)
656 #ifdef WITH_THREAD
657 PyEval_ReInitThreads();
658 main_thread = PyThread_get_thread_ident();
659 main_pid = getpid();
660 #endif