signalmodule.c revision b42a21df1102a4ca833cf50d7caeda9391a8a54a
1 2/* Signal module -- many thanks to Lance Ellinghaus */ 3 4/* XXX Signals should be recorded per thread, now we have thread state. */ 5 6#include "Python.h" 7#include "intrcheck.h" 8 9#ifdef MS_WINDOWS 10#include <Windows.h> 11#ifdef HAVE_PROCESS_H 12#include <process.h> 13#endif 14#endif 15 16#include <signal.h> 17 18#include <sys/stat.h> 19#ifdef HAVE_SYS_TIME_H 20#include <sys/time.h> 21#endif 22 23#ifndef SIG_ERR 24#define SIG_ERR ((PyOS_sighandler_t)(-1)) 25#endif 26 27#if defined(PYOS_OS2) && !defined(PYCC_GCC) 28#define NSIG 12 29#include <process.h> 30#endif 31 32#ifndef NSIG 33# if defined(_NSIG) 34# define NSIG _NSIG /* For BSD/SysV */ 35# elif defined(_SIGMAX) 36# define NSIG (_SIGMAX + 1) /* For QNX */ 37# elif defined(SIGMAX) 38# define NSIG (SIGMAX + 1) /* For djgpp */ 39# else 40# define NSIG 64 /* Use a reasonable default value */ 41# endif 42#endif 43 44 45/* 46 NOTES ON THE INTERACTION BETWEEN SIGNALS AND THREADS 47 48 When threads are supported, we want the following semantics: 49 50 - only the main thread can set a signal handler 51 - any thread can get a signal handler 52 - signals are only delivered to the main thread 53 54 I.e. we don't support "synchronous signals" like SIGFPE (catching 55 this doesn't make much sense in Python anyway) nor do we support 56 signals as a means of inter-thread communication, since not all 57 thread implementations support that (at least our thread library 58 doesn't). 59 60 We still have the problem that in some implementations signals 61 generated by the keyboard (e.g. SIGINT) are delivered to all 62 threads (e.g. SGI), while in others (e.g. Solaris) such signals are 63 delivered to one random thread (an intermediate possibility would 64 be to deliver it to the main thread -- POSIX?). For now, we have 65 a working implementation that works in all three cases -- the 66 handler ignores signals if getpid() isn't the same as in the main 67 thread. XXX This is a hack. 68 69 GNU pth is a user-space threading library, and as such, all threads 70 run within the same process. In this case, if the currently running 71 thread is not the main_thread, send the signal to the main_thread. 72*/ 73 74#ifdef WITH_THREAD 75#include <sys/types.h> /* For pid_t */ 76#include "pythread.h" 77static long main_thread; 78static pid_t main_pid; 79#endif 80 81static struct { 82 int tripped; 83 PyObject *func; 84} Handlers[NSIG]; 85 86static sig_atomic_t wakeup_fd = -1; 87 88/* Speed up sigcheck() when none tripped */ 89static volatile sig_atomic_t is_tripped = 0; 90 91static PyObject *DefaultHandler; 92static PyObject *IgnoreHandler; 93static PyObject *IntHandler; 94 95/* On Solaris 8, gcc will produce a warning that the function 96 declaration is not a prototype. This is caused by the definition of 97 SIG_DFL as (void (*)())0; the correct declaration would have been 98 (void (*)(int))0. */ 99 100static PyOS_sighandler_t old_siginthandler = SIG_DFL; 101 102#ifdef HAVE_GETITIMER 103static PyObject *ItimerError; 104 105/* auxiliary functions for setitimer/getitimer */ 106static void 107timeval_from_double(double d, struct timeval *tv) 108{ 109 tv->tv_sec = floor(d); 110 tv->tv_usec = fmod(d, 1.0) * 1000000.0; 111} 112 113Py_LOCAL_INLINE(double) 114double_from_timeval(struct timeval *tv) 115{ 116 return tv->tv_sec + (double)(tv->tv_usec / 1000000.0); 117} 118 119static PyObject * 120itimer_retval(struct itimerval *iv) 121{ 122 PyObject *r, *v; 123 124 r = PyTuple_New(2); 125 if (r == NULL) 126 return NULL; 127 128 if(!(v = PyFloat_FromDouble(double_from_timeval(&iv->it_value)))) { 129 Py_DECREF(r); 130 return NULL; 131 } 132 133 PyTuple_SET_ITEM(r, 0, v); 134 135 if(!(v = PyFloat_FromDouble(double_from_timeval(&iv->it_interval)))) { 136 Py_DECREF(r); 137 return NULL; 138 } 139 140 PyTuple_SET_ITEM(r, 1, v); 141 142 return r; 143} 144#endif 145 146static PyObject * 147signal_default_int_handler(PyObject *self, PyObject *args) 148{ 149 PyErr_SetNone(PyExc_KeyboardInterrupt); 150 return NULL; 151} 152 153PyDoc_STRVAR(default_int_handler_doc, 154"default_int_handler(...)\n\ 155\n\ 156The default handler for SIGINT installed by Python.\n\ 157It raises KeyboardInterrupt."); 158 159 160static int 161checksignals_witharg(void * unused) 162{ 163 return PyErr_CheckSignals(); 164} 165 166static void 167signal_handler(int sig_num) 168{ 169#ifdef WITH_THREAD 170#ifdef WITH_PTH 171 if (PyThread_get_thread_ident() != main_thread) { 172 pth_raise(*(pth_t *) main_thread, sig_num); 173 return; 174 } 175#endif 176 /* See NOTES section above */ 177 if (getpid() == main_pid) { 178#endif 179 Handlers[sig_num].tripped = 1; 180 /* Set is_tripped after setting .tripped, as it gets 181 cleared in PyErr_CheckSignals() before .tripped. */ 182 is_tripped = 1; 183 Py_AddPendingCall(checksignals_witharg, NULL); 184 if (wakeup_fd != -1) 185 write(wakeup_fd, "\0", 1); 186#ifdef WITH_THREAD 187 } 188#endif 189#ifdef SIGCHLD 190 if (sig_num == SIGCHLD) { 191 /* To avoid infinite recursion, this signal remains 192 reset until explicit re-instated. 193 Don't clear the 'func' field as it is our pointer 194 to the Python handler... */ 195 return; 196 } 197#endif 198#ifndef HAVE_SIGACTION 199 /* If the handler was not set up with sigaction, reinstall it. See 200 * Python/pythonrun.c for the implementation of PyOS_setsig which 201 * makes this true. See also issue8354. */ 202 PyOS_setsig(sig_num, signal_handler); 203#endif 204} 205 206 207#ifdef HAVE_ALARM 208static PyObject * 209signal_alarm(PyObject *self, PyObject *args) 210{ 211 int t; 212 if (!PyArg_ParseTuple(args, "i:alarm", &t)) 213 return NULL; 214 /* alarm() returns the number of seconds remaining */ 215 return PyLong_FromLong((long)alarm(t)); 216} 217 218PyDoc_STRVAR(alarm_doc, 219"alarm(seconds)\n\ 220\n\ 221Arrange for SIGALRM to arrive after the given number of seconds."); 222#endif 223 224#ifdef HAVE_PAUSE 225static PyObject * 226signal_pause(PyObject *self) 227{ 228 Py_BEGIN_ALLOW_THREADS 229 (void)pause(); 230 Py_END_ALLOW_THREADS 231 /* make sure that any exceptions that got raised are propagated 232 * back into Python 233 */ 234 if (PyErr_CheckSignals()) 235 return NULL; 236 237 Py_INCREF(Py_None); 238 return Py_None; 239} 240PyDoc_STRVAR(pause_doc, 241"pause()\n\ 242\n\ 243Wait until a signal arrives."); 244 245#endif 246 247 248static PyObject * 249signal_signal(PyObject *self, PyObject *args) 250{ 251 PyObject *obj; 252 int sig_num; 253 PyObject *old_handler; 254 void (*func)(int); 255#ifdef MS_WINDOWS 256 int cur_sig, num_valid_sigs = 6; 257 static int valid_sigs[] = {SIGABRT, SIGFPE, SIGILL, SIGINT, 258 SIGSEGV, SIGTERM}; 259 BOOL valid_sig = FALSE; 260#endif 261 if (!PyArg_ParseTuple(args, "iO:signal", &sig_num, &obj)) 262 return NULL; 263#ifdef MS_WINDOWS 264 /* Validate that sig_num is one of the allowable signals */ 265 for (cur_sig = 0; cur_sig < num_valid_sigs; cur_sig++) 266 valid_sig |= (sig_num == valid_sigs[cur_sig]); 267 if (!valid_sig) { 268 PyErr_SetString(PyExc_ValueError, "signal number out of range"); 269 return NULL; 270 } 271#endif 272#ifdef WITH_THREAD 273 if (PyThread_get_thread_ident() != main_thread) { 274 PyErr_SetString(PyExc_ValueError, 275 "signal only works in main thread"); 276 return NULL; 277 } 278#endif 279 if (sig_num < 1 || sig_num >= NSIG) { 280 PyErr_SetString(PyExc_ValueError, 281 "signal number out of range"); 282 return NULL; 283 } 284 if (obj == IgnoreHandler) 285 func = SIG_IGN; 286 else if (obj == DefaultHandler) 287 func = SIG_DFL; 288 else if (!PyCallable_Check(obj)) { 289 PyErr_SetString(PyExc_TypeError, 290"signal handler must be signal.SIG_IGN, signal.SIG_DFL, or a callable object"); 291 return NULL; 292 } 293 else 294 func = signal_handler; 295 if (PyOS_setsig(sig_num, func) == SIG_ERR) { 296 PyErr_SetFromErrno(PyExc_RuntimeError); 297 return NULL; 298 } 299 old_handler = Handlers[sig_num].func; 300 Handlers[sig_num].tripped = 0; 301 Py_INCREF(obj); 302 Handlers[sig_num].func = obj; 303 return old_handler; 304} 305 306PyDoc_STRVAR(signal_doc, 307"signal(sig, action) -> action\n\ 308\n\ 309Set the action for the given signal. The action can be SIG_DFL,\n\ 310SIG_IGN, or a callable Python object. The previous action is\n\ 311returned. See getsignal() for possible return values.\n\ 312\n\ 313*** IMPORTANT NOTICE ***\n\ 314A signal handler function is called with two arguments:\n\ 315the first is the signal number, the second is the interrupted stack frame."); 316 317 318static PyObject * 319signal_getsignal(PyObject *self, PyObject *args) 320{ 321 int sig_num; 322 PyObject *old_handler; 323 if (!PyArg_ParseTuple(args, "i:getsignal", &sig_num)) 324 return NULL; 325 if (sig_num < 1 || sig_num >= NSIG) { 326 PyErr_SetString(PyExc_ValueError, 327 "signal number out of range"); 328 return NULL; 329 } 330 old_handler = Handlers[sig_num].func; 331 Py_INCREF(old_handler); 332 return old_handler; 333} 334 335PyDoc_STRVAR(getsignal_doc, 336"getsignal(sig) -> action\n\ 337\n\ 338Return the current action for the given signal. The return value can be:\n\ 339SIG_IGN -- if the signal is being ignored\n\ 340SIG_DFL -- if the default action for the signal is in effect\n\ 341None -- if an unknown handler is in effect\n\ 342anything else -- the callable Python object used as a handler"); 343 344#ifdef HAVE_SIGINTERRUPT 345PyDoc_STRVAR(siginterrupt_doc, 346"siginterrupt(sig, flag) -> None\n\ 347change system call restart behaviour: if flag is False, system calls\n\ 348will be restarted when interrupted by signal sig, else system calls\n\ 349will be interrupted."); 350 351static PyObject * 352signal_siginterrupt(PyObject *self, PyObject *args) 353{ 354 int sig_num; 355 int flag; 356 357 if (!PyArg_ParseTuple(args, "ii:siginterrupt", &sig_num, &flag)) 358 return NULL; 359 if (sig_num < 1 || sig_num >= NSIG) { 360 PyErr_SetString(PyExc_ValueError, 361 "signal number out of range"); 362 return NULL; 363 } 364 if (siginterrupt(sig_num, flag)<0) { 365 PyErr_SetFromErrno(PyExc_RuntimeError); 366 return NULL; 367 } 368 369 Py_INCREF(Py_None); 370 return Py_None; 371} 372 373#endif 374 375static PyObject * 376signal_set_wakeup_fd(PyObject *self, PyObject *args) 377{ 378 struct stat buf; 379 int fd, old_fd; 380 if (!PyArg_ParseTuple(args, "i:set_wakeup_fd", &fd)) 381 return NULL; 382#ifdef WITH_THREAD 383 if (PyThread_get_thread_ident() != main_thread) { 384 PyErr_SetString(PyExc_ValueError, 385 "set_wakeup_fd only works in main thread"); 386 return NULL; 387 } 388#endif 389 if (fd != -1 && fstat(fd, &buf) != 0) { 390 PyErr_SetString(PyExc_ValueError, "invalid fd"); 391 return NULL; 392 } 393 old_fd = wakeup_fd; 394 wakeup_fd = fd; 395 return PyLong_FromLong(old_fd); 396} 397 398PyDoc_STRVAR(set_wakeup_fd_doc, 399"set_wakeup_fd(fd) -> fd\n\ 400\n\ 401Sets the fd to be written to (with '\\0') when a signal\n\ 402comes in. A library can use this to wakeup select or poll.\n\ 403The previous fd is returned.\n\ 404\n\ 405The fd must be non-blocking."); 406 407/* C API for the same, without all the error checking */ 408int 409PySignal_SetWakeupFd(int fd) 410{ 411 int old_fd = wakeup_fd; 412 if (fd < 0) 413 fd = -1; 414 wakeup_fd = fd; 415 return old_fd; 416} 417 418 419#ifdef HAVE_SETITIMER 420static PyObject * 421signal_setitimer(PyObject *self, PyObject *args) 422{ 423 double first; 424 double interval = 0; 425 int which; 426 struct itimerval new, old; 427 428 if(!PyArg_ParseTuple(args, "id|d:setitimer", &which, &first, &interval)) 429 return NULL; 430 431 timeval_from_double(first, &new.it_value); 432 timeval_from_double(interval, &new.it_interval); 433 /* Let OS check "which" value */ 434 if (setitimer(which, &new, &old) != 0) { 435 PyErr_SetFromErrno(ItimerError); 436 return NULL; 437 } 438 439 return itimer_retval(&old); 440} 441 442PyDoc_STRVAR(setitimer_doc, 443"setitimer(which, seconds[, interval])\n\ 444\n\ 445Sets given itimer (one of ITIMER_REAL, ITIMER_VIRTUAL\n\ 446or ITIMER_PROF) to fire after value seconds and after\n\ 447that every interval seconds.\n\ 448The itimer can be cleared by setting seconds to zero.\n\ 449\n\ 450Returns old values as a tuple: (delay, interval)."); 451#endif 452 453 454#ifdef HAVE_GETITIMER 455static PyObject * 456signal_getitimer(PyObject *self, PyObject *args) 457{ 458 int which; 459 struct itimerval old; 460 461 if (!PyArg_ParseTuple(args, "i:getitimer", &which)) 462 return NULL; 463 464 if (getitimer(which, &old) != 0) { 465 PyErr_SetFromErrno(ItimerError); 466 return NULL; 467 } 468 469 return itimer_retval(&old); 470} 471 472PyDoc_STRVAR(getitimer_doc, 473"getitimer(which)\n\ 474\n\ 475Returns current value of given itimer."); 476#endif 477 478 479/* List of functions defined in the module */ 480static PyMethodDef signal_methods[] = { 481#ifdef HAVE_ALARM 482 {"alarm", signal_alarm, METH_VARARGS, alarm_doc}, 483#endif 484#ifdef HAVE_SETITIMER 485 {"setitimer", signal_setitimer, METH_VARARGS, setitimer_doc}, 486#endif 487#ifdef HAVE_GETITIMER 488 {"getitimer", signal_getitimer, METH_VARARGS, getitimer_doc}, 489#endif 490 {"signal", signal_signal, METH_VARARGS, signal_doc}, 491 {"getsignal", signal_getsignal, METH_VARARGS, getsignal_doc}, 492 {"set_wakeup_fd", signal_set_wakeup_fd, METH_VARARGS, set_wakeup_fd_doc}, 493#ifdef HAVE_SIGINTERRUPT 494 {"siginterrupt", signal_siginterrupt, METH_VARARGS, siginterrupt_doc}, 495#endif 496#ifdef HAVE_PAUSE 497 {"pause", (PyCFunction)signal_pause, 498 METH_NOARGS,pause_doc}, 499#endif 500 {"default_int_handler", signal_default_int_handler, 501 METH_VARARGS, default_int_handler_doc}, 502 {NULL, NULL} /* sentinel */ 503}; 504 505 506PyDoc_STRVAR(module_doc, 507"This module provides mechanisms to use signal handlers in Python.\n\ 508\n\ 509Functions:\n\ 510\n\ 511alarm() -- cause SIGALRM after a specified time [Unix only]\n\ 512setitimer() -- cause a signal (described below) after a specified\n\ 513 float time and the timer may restart then [Unix only]\n\ 514getitimer() -- get current value of timer [Unix only]\n\ 515signal() -- set the action for a given signal\n\ 516getsignal() -- get the signal action for a given signal\n\ 517pause() -- wait until a signal arrives [Unix only]\n\ 518default_int_handler() -- default SIGINT handler\n\ 519\n\ 520signal constants:\n\ 521SIG_DFL -- used to refer to the system default handler\n\ 522SIG_IGN -- used to ignore the signal\n\ 523NSIG -- number of defined signals\n\ 524SIGINT, SIGTERM, etc. -- signal numbers\n\ 525\n\ 526itimer constants:\n\ 527ITIMER_REAL -- decrements in real time, and delivers SIGALRM upon\n\ 528 expiration\n\ 529ITIMER_VIRTUAL -- decrements only when the process is executing,\n\ 530 and delivers SIGVTALRM upon expiration\n\ 531ITIMER_PROF -- decrements both when the process is executing and\n\ 532 when the system is executing on behalf of the process.\n\ 533 Coupled with ITIMER_VIRTUAL, this timer is usually\n\ 534 used to profile the time spent by the application\n\ 535 in user and kernel space. SIGPROF is delivered upon\n\ 536 expiration.\n\ 537\n\n\ 538*** IMPORTANT NOTICE ***\n\ 539A signal handler function is called with two arguments:\n\ 540the first is the signal number, the second is the interrupted stack frame."); 541 542static struct PyModuleDef signalmodule = { 543 PyModuleDef_HEAD_INIT, 544 "signal", 545 module_doc, 546 -1, 547 signal_methods, 548 NULL, 549 NULL, 550 NULL, 551 NULL 552}; 553 554PyMODINIT_FUNC 555PyInit_signal(void) 556{ 557 PyObject *m, *d, *x; 558 int i; 559 560#ifdef WITH_THREAD 561 main_thread = PyThread_get_thread_ident(); 562 main_pid = getpid(); 563#endif 564 565 /* Create the module and add the functions */ 566 m = PyModule_Create(&signalmodule); 567 if (m == NULL) 568 return NULL; 569 570 /* Add some symbolic constants to the module */ 571 d = PyModule_GetDict(m); 572 573 x = DefaultHandler = PyLong_FromVoidPtr((void *)SIG_DFL); 574 if (!x || PyDict_SetItemString(d, "SIG_DFL", x) < 0) 575 goto finally; 576 577 x = IgnoreHandler = PyLong_FromVoidPtr((void *)SIG_IGN); 578 if (!x || PyDict_SetItemString(d, "SIG_IGN", x) < 0) 579 goto finally; 580 581 x = PyLong_FromLong((long)NSIG); 582 if (!x || PyDict_SetItemString(d, "NSIG", x) < 0) 583 goto finally; 584 Py_DECREF(x); 585 586 x = IntHandler = PyDict_GetItemString(d, "default_int_handler"); 587 if (!x) 588 goto finally; 589 Py_INCREF(IntHandler); 590 591 Handlers[0].tripped = 0; 592 for (i = 1; i < NSIG; i++) { 593 void (*t)(int); 594 t = PyOS_getsig(i); 595 Handlers[i].tripped = 0; 596 if (t == SIG_DFL) 597 Handlers[i].func = DefaultHandler; 598 else if (t == SIG_IGN) 599 Handlers[i].func = IgnoreHandler; 600 else 601 Handlers[i].func = Py_None; /* None of our business */ 602 Py_INCREF(Handlers[i].func); 603 } 604 if (Handlers[SIGINT].func == DefaultHandler) { 605 /* Install default int handler */ 606 Py_INCREF(IntHandler); 607 Py_DECREF(Handlers[SIGINT].func); 608 Handlers[SIGINT].func = IntHandler; 609 old_siginthandler = PyOS_setsig(SIGINT, signal_handler); 610 } 611 612#ifdef SIGHUP 613 x = PyLong_FromLong(SIGHUP); 614 PyDict_SetItemString(d, "SIGHUP", x); 615 Py_XDECREF(x); 616#endif 617#ifdef SIGINT 618 x = PyLong_FromLong(SIGINT); 619 PyDict_SetItemString(d, "SIGINT", x); 620 Py_XDECREF(x); 621#endif 622#ifdef SIGBREAK 623 x = PyLong_FromLong(SIGBREAK); 624 PyDict_SetItemString(d, "SIGBREAK", x); 625 Py_XDECREF(x); 626#endif 627#ifdef SIGQUIT 628 x = PyLong_FromLong(SIGQUIT); 629 PyDict_SetItemString(d, "SIGQUIT", x); 630 Py_XDECREF(x); 631#endif 632#ifdef SIGILL 633 x = PyLong_FromLong(SIGILL); 634 PyDict_SetItemString(d, "SIGILL", x); 635 Py_XDECREF(x); 636#endif 637#ifdef SIGTRAP 638 x = PyLong_FromLong(SIGTRAP); 639 PyDict_SetItemString(d, "SIGTRAP", x); 640 Py_XDECREF(x); 641#endif 642#ifdef SIGIOT 643 x = PyLong_FromLong(SIGIOT); 644 PyDict_SetItemString(d, "SIGIOT", x); 645 Py_XDECREF(x); 646#endif 647#ifdef SIGABRT 648 x = PyLong_FromLong(SIGABRT); 649 PyDict_SetItemString(d, "SIGABRT", x); 650 Py_XDECREF(x); 651#endif 652#ifdef SIGEMT 653 x = PyLong_FromLong(SIGEMT); 654 PyDict_SetItemString(d, "SIGEMT", x); 655 Py_XDECREF(x); 656#endif 657#ifdef SIGFPE 658 x = PyLong_FromLong(SIGFPE); 659 PyDict_SetItemString(d, "SIGFPE", x); 660 Py_XDECREF(x); 661#endif 662#ifdef SIGKILL 663 x = PyLong_FromLong(SIGKILL); 664 PyDict_SetItemString(d, "SIGKILL", x); 665 Py_XDECREF(x); 666#endif 667#ifdef SIGBUS 668 x = PyLong_FromLong(SIGBUS); 669 PyDict_SetItemString(d, "SIGBUS", x); 670 Py_XDECREF(x); 671#endif 672#ifdef SIGSEGV 673 x = PyLong_FromLong(SIGSEGV); 674 PyDict_SetItemString(d, "SIGSEGV", x); 675 Py_XDECREF(x); 676#endif 677#ifdef SIGSYS 678 x = PyLong_FromLong(SIGSYS); 679 PyDict_SetItemString(d, "SIGSYS", x); 680 Py_XDECREF(x); 681#endif 682#ifdef SIGPIPE 683 x = PyLong_FromLong(SIGPIPE); 684 PyDict_SetItemString(d, "SIGPIPE", x); 685 Py_XDECREF(x); 686#endif 687#ifdef SIGALRM 688 x = PyLong_FromLong(SIGALRM); 689 PyDict_SetItemString(d, "SIGALRM", x); 690 Py_XDECREF(x); 691#endif 692#ifdef SIGTERM 693 x = PyLong_FromLong(SIGTERM); 694 PyDict_SetItemString(d, "SIGTERM", x); 695 Py_XDECREF(x); 696#endif 697#ifdef SIGUSR1 698 x = PyLong_FromLong(SIGUSR1); 699 PyDict_SetItemString(d, "SIGUSR1", x); 700 Py_XDECREF(x); 701#endif 702#ifdef SIGUSR2 703 x = PyLong_FromLong(SIGUSR2); 704 PyDict_SetItemString(d, "SIGUSR2", x); 705 Py_XDECREF(x); 706#endif 707#ifdef SIGCLD 708 x = PyLong_FromLong(SIGCLD); 709 PyDict_SetItemString(d, "SIGCLD", x); 710 Py_XDECREF(x); 711#endif 712#ifdef SIGCHLD 713 x = PyLong_FromLong(SIGCHLD); 714 PyDict_SetItemString(d, "SIGCHLD", x); 715 Py_XDECREF(x); 716#endif 717#ifdef SIGPWR 718 x = PyLong_FromLong(SIGPWR); 719 PyDict_SetItemString(d, "SIGPWR", x); 720 Py_XDECREF(x); 721#endif 722#ifdef SIGIO 723 x = PyLong_FromLong(SIGIO); 724 PyDict_SetItemString(d, "SIGIO", x); 725 Py_XDECREF(x); 726#endif 727#ifdef SIGURG 728 x = PyLong_FromLong(SIGURG); 729 PyDict_SetItemString(d, "SIGURG", x); 730 Py_XDECREF(x); 731#endif 732#ifdef SIGWINCH 733 x = PyLong_FromLong(SIGWINCH); 734 PyDict_SetItemString(d, "SIGWINCH", x); 735 Py_XDECREF(x); 736#endif 737#ifdef SIGPOLL 738 x = PyLong_FromLong(SIGPOLL); 739 PyDict_SetItemString(d, "SIGPOLL", x); 740 Py_XDECREF(x); 741#endif 742#ifdef SIGSTOP 743 x = PyLong_FromLong(SIGSTOP); 744 PyDict_SetItemString(d, "SIGSTOP", x); 745 Py_XDECREF(x); 746#endif 747#ifdef SIGTSTP 748 x = PyLong_FromLong(SIGTSTP); 749 PyDict_SetItemString(d, "SIGTSTP", x); 750 Py_XDECREF(x); 751#endif 752#ifdef SIGCONT 753 x = PyLong_FromLong(SIGCONT); 754 PyDict_SetItemString(d, "SIGCONT", x); 755 Py_XDECREF(x); 756#endif 757#ifdef SIGTTIN 758 x = PyLong_FromLong(SIGTTIN); 759 PyDict_SetItemString(d, "SIGTTIN", x); 760 Py_XDECREF(x); 761#endif 762#ifdef SIGTTOU 763 x = PyLong_FromLong(SIGTTOU); 764 PyDict_SetItemString(d, "SIGTTOU", x); 765 Py_XDECREF(x); 766#endif 767#ifdef SIGVTALRM 768 x = PyLong_FromLong(SIGVTALRM); 769 PyDict_SetItemString(d, "SIGVTALRM", x); 770 Py_XDECREF(x); 771#endif 772#ifdef SIGPROF 773 x = PyLong_FromLong(SIGPROF); 774 PyDict_SetItemString(d, "SIGPROF", x); 775 Py_XDECREF(x); 776#endif 777#ifdef SIGXCPU 778 x = PyLong_FromLong(SIGXCPU); 779 PyDict_SetItemString(d, "SIGXCPU", x); 780 Py_XDECREF(x); 781#endif 782#ifdef SIGXFSZ 783 x = PyLong_FromLong(SIGXFSZ); 784 PyDict_SetItemString(d, "SIGXFSZ", x); 785 Py_XDECREF(x); 786#endif 787#ifdef SIGRTMIN 788 x = PyLong_FromLong(SIGRTMIN); 789 PyDict_SetItemString(d, "SIGRTMIN", x); 790 Py_XDECREF(x); 791#endif 792#ifdef SIGRTMAX 793 x = PyLong_FromLong(SIGRTMAX); 794 PyDict_SetItemString(d, "SIGRTMAX", x); 795 Py_XDECREF(x); 796#endif 797#ifdef SIGINFO 798 x = PyLong_FromLong(SIGINFO); 799 PyDict_SetItemString(d, "SIGINFO", x); 800 Py_XDECREF(x); 801#endif 802 803#ifdef ITIMER_REAL 804 x = PyLong_FromLong(ITIMER_REAL); 805 PyDict_SetItemString(d, "ITIMER_REAL", x); 806 Py_DECREF(x); 807#endif 808#ifdef ITIMER_VIRTUAL 809 x = PyLong_FromLong(ITIMER_VIRTUAL); 810 PyDict_SetItemString(d, "ITIMER_VIRTUAL", x); 811 Py_DECREF(x); 812#endif 813#ifdef ITIMER_PROF 814 x = PyLong_FromLong(ITIMER_PROF); 815 PyDict_SetItemString(d, "ITIMER_PROF", x); 816 Py_DECREF(x); 817#endif 818 819#if defined (HAVE_SETITIMER) || defined (HAVE_GETITIMER) 820 ItimerError = PyErr_NewException("signal.ItimerError", 821 PyExc_IOError, NULL); 822 if (ItimerError != NULL) 823 PyDict_SetItemString(d, "ItimerError", ItimerError); 824#endif 825 826 if (PyErr_Occurred()) { 827 Py_DECREF(m); 828 m = NULL; 829 } 830 831 finally: 832 return m; 833} 834 835static void 836finisignal(void) 837{ 838 int i; 839 PyObject *func; 840 841 PyOS_setsig(SIGINT, old_siginthandler); 842 old_siginthandler = SIG_DFL; 843 844 for (i = 1; i < NSIG; i++) { 845 func = Handlers[i].func; 846 Handlers[i].tripped = 0; 847 Handlers[i].func = NULL; 848 if (i != SIGINT && func != NULL && func != Py_None && 849 func != DefaultHandler && func != IgnoreHandler) 850 PyOS_setsig(i, SIG_DFL); 851 Py_XDECREF(func); 852 } 853 854 Py_XDECREF(IntHandler); 855 IntHandler = NULL; 856 Py_XDECREF(DefaultHandler); 857 DefaultHandler = NULL; 858 Py_XDECREF(IgnoreHandler); 859 IgnoreHandler = NULL; 860} 861 862 863/* Declared in pyerrors.h */ 864int 865PyErr_CheckSignals(void) 866{ 867 int i; 868 PyObject *f; 869 870 if (!is_tripped) 871 return 0; 872 873#ifdef WITH_THREAD 874 if (PyThread_get_thread_ident() != main_thread) 875 return 0; 876#endif 877 878 /* 879 * The is_tripped variable is meant to speed up the calls to 880 * PyErr_CheckSignals (both directly or via pending calls) when no 881 * signal has arrived. This variable is set to 1 when a signal arrives 882 * and it is set to 0 here, when we know some signals arrived. This way 883 * we can run the registered handlers with no signals blocked. 884 * 885 * NOTE: with this approach we can have a situation where is_tripped is 886 * 1 but we have no more signals to handle (Handlers[i].tripped 887 * is 0 for every signal i). This won't do us any harm (except 888 * we're gonna spent some cycles for nothing). This happens when 889 * we receive a signal i after we zero is_tripped and before we 890 * check Handlers[i].tripped. 891 */ 892 is_tripped = 0; 893 894 if (!(f = (PyObject *)PyEval_GetFrame())) 895 f = Py_None; 896 897 for (i = 1; i < NSIG; i++) { 898 if (Handlers[i].tripped) { 899 PyObject *result = NULL; 900 PyObject *arglist = Py_BuildValue("(iO)", i, f); 901 Handlers[i].tripped = 0; 902 903 if (arglist) { 904 result = PyEval_CallObject(Handlers[i].func, 905 arglist); 906 Py_DECREF(arglist); 907 } 908 if (!result) 909 return -1; 910 911 Py_DECREF(result); 912 } 913 } 914 915 return 0; 916} 917 918 919/* Replacements for intrcheck.c functionality 920 * Declared in pyerrors.h 921 */ 922void 923PyErr_SetInterrupt(void) 924{ 925 is_tripped = 1; 926 Handlers[SIGINT].tripped = 1; 927 Py_AddPendingCall((int (*)(void *))PyErr_CheckSignals, NULL); 928} 929 930void 931PyOS_InitInterrupts(void) 932{ 933 PyObject *m = PyInit_signal(); 934 if (m) { 935 _PyImport_FixupExtension(m, "signal", "signal"); 936 Py_DECREF(m); 937 } 938} 939 940void 941PyOS_FiniInterrupts(void) 942{ 943 finisignal(); 944} 945 946int 947PyOS_InterruptOccurred(void) 948{ 949 if (Handlers[SIGINT].tripped) { 950#ifdef WITH_THREAD 951 if (PyThread_get_thread_ident() != main_thread) 952 return 0; 953#endif 954 Handlers[SIGINT].tripped = 0; 955 return 1; 956 } 957 return 0; 958} 959 960void 961PyOS_AfterFork(void) 962{ 963#ifdef WITH_THREAD 964 PyEval_ReInitThreads(); 965 main_thread = PyThread_get_thread_ident(); 966 main_pid = getpid(); 967 _PyImport_ReInitLock(); 968 PyThread_ReInitTLS(); 969#endif 970} 971