diff -r 1638360eea41 Modules/signalmodule.c --- a/Modules/signalmodule.c Sat Jan 11 22:22:21 2014 -0800 +++ b/Modules/signalmodule.c Sun Jan 12 11:28:14 2014 +0100 @@ -49,6 +49,11 @@ # endif #endif +/*[clinic input] +module signal +[clinic start generated code]*/ +/*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ + /* NOTES ON THE INTERACTION BETWEEN SIGNALS AND THREADS @@ -244,25 +249,83 @@ signal_handler(int sig_num) #ifdef HAVE_ALARM + +/*[clinic input] +signal.alarm + + seconds: 'i' + / + +Arrange for SIGALRM to arrive after the given number of seconds. +[clinic start generated code]*/ + +PyDoc_STRVAR(signal_alarm__doc__, +"alarm(seconds)\n" +"Arrange for SIGALRM to arrive after the given number of seconds."); + +#define SIGNAL_ALARM_METHODDEF \ + {"alarm", (PyCFunction)signal_alarm, METH_VARARGS, signal_alarm__doc__}, + static PyObject * -signal_alarm(PyObject *self, PyObject *args) +signal_alarm_impl(PyModuleDef *module, int seconds); + +static PyObject * +signal_alarm(PyModuleDef *module, PyObject *args) { - int t; - if (!PyArg_ParseTuple(args, "i:alarm", &t)) - return NULL; - /* alarm() returns the number of seconds remaining */ - return PyLong_FromLong((long)alarm(t)); + PyObject *return_value = NULL; + int seconds; + + if (!PyArg_ParseTuple(args, + "i:alarm", + &seconds)) + goto exit; + return_value = signal_alarm_impl(module, seconds); + +exit: + return return_value; } -PyDoc_STRVAR(alarm_doc, -"alarm(seconds)\n\ -\n\ -Arrange for SIGALRM to arrive after the given number of seconds."); +static PyObject * +signal_alarm_impl(PyModuleDef *module, int seconds) +/*[clinic end generated code: checksum=a918bab7c47b47d42bce1fa4c2f6fa51aee05202]*/ +{ + /* alarm() returns the number of seconds remaining */ + return PyLong_FromLong((long)alarm(seconds)); +} + #endif #ifdef HAVE_PAUSE + +/*[clinic input] +signal.pause + +Wait until a signal arrives. +[clinic start generated code]*/ + +PyDoc_STRVAR(signal_pause__doc__, +"pause()\n" +"Wait until a signal arrives."); + +#define SIGNAL_PAUSE_METHODDEF \ + {"pause", (PyCFunction)signal_pause, METH_NOARGS, signal_pause__doc__}, + static PyObject * -signal_pause(PyObject *self) +signal_pause_impl(PyModuleDef *module); + +static PyObject * +signal_pause(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = signal_pause_impl(module); + + return return_value; +} + +static PyObject * +signal_pause_impl(PyModuleDef *module) +/*[clinic end generated code: checksum=a6089ea965131411e4a81b4f2e9e0aaf7579576b]*/ { Py_BEGIN_ALLOW_THREADS (void)pause(); @@ -273,29 +336,72 @@ signal_pause(PyObject *self) if (PyErr_CheckSignals()) return NULL; - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } -PyDoc_STRVAR(pause_doc, -"pause()\n\ -\n\ -Wait until a signal arrives."); #endif +/*[clinic input] +signal.signal + + signalnum: 'i' + handler: 'O' + / + +Set the action for the given signal. + +The action can be SIG_DFL, SIG_IGN, or a callable Python object. +The previous action is returned. See getsignal() for possible return values. + +*** IMPORTANT NOTICE *** +A signal handler function is called with two arguments: +the first is the signal number, the second is the interrupted stack frame. +[clinic start generated code]*/ + +PyDoc_STRVAR(signal_signal__doc__, +"signal(signalnum, handler)\n" +"Set the action for the given signal.\n" +"\n" +"The action can be SIG_DFL, SIG_IGN, or a callable Python object.\n" +"The previous action is returned. See getsignal() for possible return values.\n" +"\n" +"*** IMPORTANT NOTICE ***\n" +"A signal handler function is called with two arguments:\n" +"the first is the signal number, the second is the interrupted stack frame."); + +#define SIGNAL_SIGNAL_METHODDEF \ + {"signal", (PyCFunction)signal_signal, METH_VARARGS, signal_signal__doc__}, + static PyObject * -signal_signal(PyObject *self, PyObject *args) +signal_signal_impl(PyModuleDef *module, int signalnum, PyObject *handler); + +static PyObject * +signal_signal(PyModuleDef *module, PyObject *args) { - PyObject *obj; - int sig_num; + PyObject *return_value = NULL; + int signalnum; + PyObject *handler; + + if (!PyArg_ParseTuple(args, + "iO:signal", + &signalnum, &handler)) + goto exit; + return_value = signal_signal_impl(module, signalnum, handler); + +exit: + return return_value; +} + +static PyObject * +signal_signal_impl(PyModuleDef *module, int signalnum, PyObject *handler) +/*[clinic end generated code: checksum=b43f865ccbebe175258f516006cd5f358c88aae4]*/ +{ PyObject *old_handler; void (*func)(int); - if (!PyArg_ParseTuple(args, "iO:signal", &sig_num, &obj)) - return NULL; #ifdef MS_WINDOWS - /* Validate that sig_num is one of the allowable signals */ - switch (sig_num) { + /* Validate that signalnum is one of the allowable signals */ + switch (signalnum) { case SIGABRT: break; #ifdef SIGBREAK /* Issue #10003: SIGBREAK is not documented as permitted, but works @@ -319,61 +425,95 @@ signal_signal(PyObject *self, PyObject * return NULL; } #endif - if (sig_num < 1 || sig_num >= NSIG) { + if (signalnum < 1 || signalnum >= NSIG) { PyErr_SetString(PyExc_ValueError, "signal number out of range"); return NULL; } - if (obj == IgnoreHandler) + if (handler == IgnoreHandler) func = SIG_IGN; - else if (obj == DefaultHandler) + else if (handler == DefaultHandler) func = SIG_DFL; - else if (!PyCallable_Check(obj)) { + else if (!PyCallable_Check(handler)) { PyErr_SetString(PyExc_TypeError, "signal handler must be signal.SIG_IGN, signal.SIG_DFL, or a callable object"); return NULL; } else func = signal_handler; - if (PyOS_setsig(sig_num, func) == SIG_ERR) { + if (PyOS_setsig(signalnum, func) == SIG_ERR) { PyErr_SetFromErrno(PyExc_OSError); return NULL; } - old_handler = Handlers[sig_num].func; - Handlers[sig_num].tripped = 0; - Py_INCREF(obj); - Handlers[sig_num].func = obj; + old_handler = Handlers[signalnum].func; + Handlers[signalnum].tripped = 0; + Py_INCREF(handler); + Handlers[signalnum].func = handler; if (old_handler != NULL) return old_handler; else Py_RETURN_NONE; } -PyDoc_STRVAR(signal_doc, -"signal(sig, action) -> action\n\ -\n\ -Set the action for the given signal. The action can be SIG_DFL,\n\ -SIG_IGN, or a callable Python object. The previous action is\n\ -returned. See getsignal() for possible return values.\n\ -\n\ -*** IMPORTANT NOTICE ***\n\ -A signal handler function is called with two arguments:\n\ -the first is the signal number, the second is the interrupted stack frame."); +/*[clinic input] +signal.getsignal + + signalnum: 'i' + / + +Return the current action for the given signal. + +The return value can be: + SIG_IGN -- if the signal is being ignored + SIG_DFL -- if the default action for the signal is in effect + None -- if an unknown handler is in effect + anything else -- the callable Python object used as a handler +[clinic start generated code]*/ + +PyDoc_STRVAR(signal_getsignal__doc__, +"getsignal(signalnum)\n" +"Return the current action for the given signal.\n" +"\n" +"The return value can be:\n" +" SIG_IGN -- if the signal is being ignored\n" +" SIG_DFL -- if the default action for the signal is in effect\n" +" None -- if an unknown handler is in effect\n" +" anything else -- the callable Python object used as a handler"); + +#define SIGNAL_GETSIGNAL_METHODDEF \ + {"getsignal", (PyCFunction)signal_getsignal, METH_VARARGS, signal_getsignal__doc__}, static PyObject * -signal_getsignal(PyObject *self, PyObject *args) +signal_getsignal_impl(PyModuleDef *module, int signalnum); + +static PyObject * +signal_getsignal(PyModuleDef *module, PyObject *args) { - int sig_num; + PyObject *return_value = NULL; + int signalnum; + + if (!PyArg_ParseTuple(args, + "i:getsignal", + &signalnum)) + goto exit; + return_value = signal_getsignal_impl(module, signalnum); + +exit: + return return_value; +} + +static PyObject * +signal_getsignal_impl(PyModuleDef *module, int signalnum) +/*[clinic end generated code: checksum=91e362cf5cc41176293a9abf382ae3d8d01afab3]*/ +{ PyObject *old_handler; - if (!PyArg_ParseTuple(args, "i:getsignal", &sig_num)) - return NULL; - if (sig_num < 1 || sig_num >= NSIG) { + if (signalnum < 1 || signalnum >= NSIG) { PyErr_SetString(PyExc_ValueError, "signal number out of range"); return NULL; } - old_handler = Handlers[sig_num].func; + old_handler = Handlers[signalnum].func; if (old_handler != NULL) { Py_INCREF(old_handler); return old_handler; @@ -383,53 +523,120 @@ signal_getsignal(PyObject *self, PyObjec } } -PyDoc_STRVAR(getsignal_doc, -"getsignal(sig) -> action\n\ -\n\ -Return the current action for the given signal. The return value can be:\n\ -SIG_IGN -- if the signal is being ignored\n\ -SIG_DFL -- if the default action for the signal is in effect\n\ -None -- if an unknown handler is in effect\n\ -anything else -- the callable Python object used as a handler"); #ifdef HAVE_SIGINTERRUPT -PyDoc_STRVAR(siginterrupt_doc, -"siginterrupt(sig, flag) -> None\n\ -change system call restart behaviour: if flag is False, system calls\n\ -will be restarted when interrupted by signal sig, else system calls\n\ -will be interrupted."); + +/*[clinic input] +signal.siginterrupt + + signalnum: 'i' + flag: 'i' + / + +Change system call restart behaviour. + +If flag is False, system calls will be restarted when interrupted by +signal sig, else system calls will be interrupted. +[clinic start generated code]*/ + +PyDoc_STRVAR(signal_siginterrupt__doc__, +"siginterrupt(signalnum, flag)\n" +"Change system call restart behaviour.\n" +"\n" +"If flag is False, system calls will be restarted when interrupted by\n" +"signal sig, else system calls will be interrupted."); + +#define SIGNAL_SIGINTERRUPT_METHODDEF \ + {"siginterrupt", (PyCFunction)signal_siginterrupt, METH_VARARGS, signal_siginterrupt__doc__}, static PyObject * -signal_siginterrupt(PyObject *self, PyObject *args) +signal_siginterrupt_impl(PyModuleDef *module, int signalnum, int flag); + +static PyObject * +signal_siginterrupt(PyModuleDef *module, PyObject *args) { - int sig_num; + PyObject *return_value = NULL; + int signalnum; int flag; - if (!PyArg_ParseTuple(args, "ii:siginterrupt", &sig_num, &flag)) - return NULL; - if (sig_num < 1 || sig_num >= NSIG) { + if (!PyArg_ParseTuple(args, + "ii:siginterrupt", + &signalnum, &flag)) + goto exit; + return_value = signal_siginterrupt_impl(module, signalnum, flag); + +exit: + return return_value; +} + +static PyObject * +signal_siginterrupt_impl(PyModuleDef *module, int signalnum, int flag) +/*[clinic end generated code: checksum=2871cd4605fb5f7ca73c0f34a7be9df5e5e5b8d0]*/ +{ + if (signalnum < 1 || signalnum >= NSIG) { PyErr_SetString(PyExc_ValueError, "signal number out of range"); return NULL; } - if (siginterrupt(sig_num, flag)<0) { + if (siginterrupt(signalnum, flag)<0) { PyErr_SetFromErrno(PyExc_OSError); return NULL; } - - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } #endif + +/*[clinic input] +signal.set_wakeup_fd + + fd: 'i' + / + +Sets the fd to be written to (with '\0') when a signal comes in. + +A library can use this to wakeup select or poll. The previous fd is returned. + +The fd must be non-blocking. +[clinic start generated code]*/ + +PyDoc_STRVAR(signal_set_wakeup_fd__doc__, +"set_wakeup_fd(fd)\n" +"Sets the fd to be written to (with \'\0\') when a signal comes in.\n" +"\n" +"A library can use this to wakeup select or poll. The previous fd is returned.\n" +"\n" +"The fd must be non-blocking."); + +#define SIGNAL_SET_WAKEUP_FD_METHODDEF \ + {"set_wakeup_fd", (PyCFunction)signal_set_wakeup_fd, METH_VARARGS, signal_set_wakeup_fd__doc__}, + static PyObject * -signal_set_wakeup_fd(PyObject *self, PyObject *args) +signal_set_wakeup_fd_impl(PyModuleDef *module, int fd); + +static PyObject * +signal_set_wakeup_fd(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + + if (!PyArg_ParseTuple(args, + "i:set_wakeup_fd", + &fd)) + goto exit; + return_value = signal_set_wakeup_fd_impl(module, fd); + +exit: + return return_value; +} + +static PyObject * +signal_set_wakeup_fd_impl(PyModuleDef *module, int fd) +/*[clinic end generated code: checksum=dbd3a88d15c3ab4bb1bb101d2d9febf49a186021]*/ { struct stat buf; - int fd, old_fd; - if (!PyArg_ParseTuple(args, "i:set_wakeup_fd", &fd)) - return NULL; + int old_fd; #ifdef WITH_THREAD if (PyThread_get_thread_ident() != main_thread) { PyErr_SetString(PyExc_ValueError, @@ -446,14 +653,6 @@ signal_set_wakeup_fd(PyObject *self, PyO return PyLong_FromLong(old_fd); } -PyDoc_STRVAR(set_wakeup_fd_doc, -"set_wakeup_fd(fd) -> fd\n\ -\n\ -Sets the fd to be written to (with '\\0') when a signal\n\ -comes in. A library can use this to wakeup select or poll.\n\ -The previous fd is returned.\n\ -\n\ -The fd must be non-blocking."); /* C API for the same, without all the error checking */ int @@ -468,18 +667,63 @@ PySignal_SetWakeupFd(int fd) #ifdef HAVE_SETITIMER + +/*[clinic input] +signal.setitimer + + which: 'i' + seconds: 'd' + interval: 'd' = 0 + / + +Sets given itimer (one of ITIMER_REAL, ITIMER_VIRTUAL or ITIMER_PROF). + +The timer will fire after value seconds and after that every interval seconds. +The itimer can be cleared by setting seconds to zero. + +Returns old values as a tuple: (delay, interval). +[clinic start generated code]*/ + +PyDoc_STRVAR(signal_setitimer__doc__, +"setitimer(which, seconds, interval=0)\n" +"Sets given itimer (one of ITIMER_REAL, ITIMER_VIRTUAL or ITIMER_PROF).\n" +"\n" +"The timer will fire after value seconds and after that every interval seconds.\n" +"The itimer can be cleared by setting seconds to zero.\n" +"\n" +"Returns old values as a tuple: (delay, interval)."); + +#define SIGNAL_SETITIMER_METHODDEF \ + {"setitimer", (PyCFunction)signal_setitimer, METH_VARARGS, signal_setitimer__doc__}, + static PyObject * -signal_setitimer(PyObject *self, PyObject *args) +signal_setitimer_impl(PyModuleDef *module, int which, double seconds, double interval); + +static PyObject * +signal_setitimer(PyModuleDef *module, PyObject *args) { - double first; + PyObject *return_value = NULL; + int which; + double seconds; double interval = 0; - int which; + + if (!PyArg_ParseTuple(args, + "id|d:setitimer", + &which, &seconds, &interval)) + goto exit; + return_value = signal_setitimer_impl(module, which, seconds, interval); + +exit: + return return_value; +} + +static PyObject * +signal_setitimer_impl(PyModuleDef *module, int which, double seconds, double interval) +/*[clinic end generated code: checksum=f237216382497d2d88d6b0ee2ad1c2e439359a39]*/ +{ struct itimerval new, old; - if(!PyArg_ParseTuple(args, "id|d:setitimer", &which, &first, &interval)) - return NULL; - - timeval_from_double(first, &new.it_value); + timeval_from_double(seconds, &new.it_value); timeval_from_double(interval, &new.it_interval); /* Let OS check "which" value */ if (setitimer(which, &new, &old) != 0) { @@ -490,40 +734,60 @@ signal_setitimer(PyObject *self, PyObjec return itimer_retval(&old); } -PyDoc_STRVAR(setitimer_doc, -"setitimer(which, seconds[, interval])\n\ -\n\ -Sets given itimer (one of ITIMER_REAL, ITIMER_VIRTUAL\n\ -or ITIMER_PROF) to fire after value seconds and after\n\ -that every interval seconds.\n\ -The itimer can be cleared by setting seconds to zero.\n\ -\n\ -Returns old values as a tuple: (delay, interval)."); #endif #ifdef HAVE_GETITIMER + +/*[clinic input] +signal.getitimer + + which: 'i' + / + +Returns current value of given itimer. +[clinic start generated code]*/ + +PyDoc_STRVAR(signal_getitimer__doc__, +"getitimer(which)\n" +"Returns current value of given itimer."); + +#define SIGNAL_GETITIMER_METHODDEF \ + {"getitimer", (PyCFunction)signal_getitimer, METH_VARARGS, signal_getitimer__doc__}, + static PyObject * -signal_getitimer(PyObject *self, PyObject *args) +signal_getitimer_impl(PyModuleDef *module, int which); + +static PyObject * +signal_getitimer(PyModuleDef *module, PyObject *args) { + PyObject *return_value = NULL; int which; + + if (!PyArg_ParseTuple(args, + "i:getitimer", + &which)) + goto exit; + return_value = signal_getitimer_impl(module, which); + +exit: + return return_value; +} + +static PyObject * +signal_getitimer_impl(PyModuleDef *module, int which) +/*[clinic end generated code: checksum=a4047c6fa1319444723e8c6ccf33b6b53f49abbd]*/ +{ struct itimerval old; - if (!PyArg_ParseTuple(args, "i:getitimer", &which)) - return NULL; - if (getitimer(which, &old) != 0) { - PyErr_SetFromErrno(ItimerError); - return NULL; + PyErr_SetFromErrno(ItimerError); + return NULL; } return itimer_retval(&old); } -PyDoc_STRVAR(getitimer_doc, -"getitimer(which)\n\ -\n\ -Returns current value of given itimer."); #endif #if defined(PYPTHREAD_SIGMASK) || defined(HAVE_SIGWAIT) || \ @@ -614,21 +878,55 @@ sigset_to_set(sigset_t mask) #endif #ifdef PYPTHREAD_SIGMASK + +/*[clinic input] +signal.pthread_sigmask + + how: 'i' + mask: 'O' + / + +Fetch and/or change the signal mask of the calling thread. +[clinic start generated code]*/ + +PyDoc_STRVAR(signal_pthread_sigmask__doc__, +"pthread_sigmask(how, mask)\n" +"Fetch and/or change the signal mask of the calling thread."); + +#define SIGNAL_PTHREAD_SIGMASK_METHODDEF \ + {"pthread_sigmask", (PyCFunction)signal_pthread_sigmask, METH_VARARGS, signal_pthread_sigmask__doc__}, + static PyObject * -signal_pthread_sigmask(PyObject *self, PyObject *args) +signal_pthread_sigmask_impl(PyModuleDef *module, int how, PyObject *mask); + +static PyObject * +signal_pthread_sigmask(PyModuleDef *module, PyObject *args) { + PyObject *return_value = NULL; int how; - PyObject *signals; - sigset_t mask, previous; + PyObject *mask; + + if (!PyArg_ParseTuple(args, + "iO:pthread_sigmask", + &how, &mask)) + goto exit; + return_value = signal_pthread_sigmask_impl(module, how, mask); + +exit: + return return_value; +} + +static PyObject * +signal_pthread_sigmask_impl(PyModuleDef *module, int how, PyObject *mask) +/*[clinic end generated code: checksum=1d4864b53f38a85e127829cd26e547dc4ea13e8d]*/ +{ + sigset_t newmask, previous; int err; - if (!PyArg_ParseTuple(args, "iO:pthread_sigmask", &how, &signals)) + if (iterable_to_sigset(mask, &newmask)) return NULL; - if (iterable_to_sigset(signals, &mask)) - return NULL; - - err = pthread_sigmask(how, &mask, &previous); + err = pthread_sigmask(how, &newmask, &previous); if (err != 0) { errno = err; PyErr_SetFromErrno(PyExc_OSError); @@ -642,16 +940,46 @@ signal_pthread_sigmask(PyObject *self, P return sigset_to_set(previous); } -PyDoc_STRVAR(signal_pthread_sigmask_doc, -"pthread_sigmask(how, mask) -> old mask\n\ -\n\ -Fetch and/or change the signal mask of the calling thread."); #endif /* #ifdef PYPTHREAD_SIGMASK */ #ifdef HAVE_SIGPENDING + +/*[clinic input] +signal.sigpending + +Examine pending signals. + +Returns a set of signal numbers that are pending for delivery to +the calling thread. +[clinic start generated code]*/ + +PyDoc_STRVAR(signal_sigpending__doc__, +"sigpending()\n" +"Examine pending signals.\n" +"\n" +"Returns a set of signal numbers that are pending for delivery to\n" +"the calling thread."); + +#define SIGNAL_SIGPENDING_METHODDEF \ + {"sigpending", (PyCFunction)signal_sigpending, METH_NOARGS, signal_sigpending__doc__}, + static PyObject * -signal_sigpending(PyObject *self) +signal_sigpending_impl(PyModuleDef *module); + +static PyObject * +signal_sigpending(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = signal_sigpending_impl(module); + + return return_value; +} + +static PyObject * +signal_sigpending_impl(PyModuleDef *module) +/*[clinic end generated code: checksum=47aa01c5b3f92f3bb48f05b69941a0b8355b1865]*/ { int err; sigset_t mask; @@ -661,25 +989,43 @@ signal_sigpending(PyObject *self) return sigset_to_set(mask); } -PyDoc_STRVAR(signal_sigpending_doc, -"sigpending() -> list\n\ -\n\ -Examine pending signals."); #endif /* #ifdef HAVE_SIGPENDING */ #ifdef HAVE_SIGWAIT + +/*[clinic input] +signal.sigwait + + sigset: 'O' + / + +Wait for a signal. + +Suspend execution of the calling thread until the delivery of one of the +signals specified in the signal set sigset. The function accepts the signal +and returns the signal number. +[clinic start generated code]*/ + +PyDoc_STRVAR(signal_sigwait__doc__, +"sigwait(sigset)\n" +"Wait for a signal.\n" +"\n" +"Suspend execution of the calling thread until the delivery of one of the\n" +"signals specified in the signal set sigset. The function accepts the signal\n" +"and returns the signal number."); + +#define SIGNAL_SIGWAIT_METHODDEF \ + {"sigwait", (PyCFunction)signal_sigwait, METH_O, signal_sigwait__doc__}, + static PyObject * -signal_sigwait(PyObject *self, PyObject *args) +signal_sigwait(PyModuleDef *module, PyObject *sigset) +/*[clinic end generated code: checksum=ba626ba2b876050fffe53352e72a65ec27cdbde4]*/ { - PyObject *signals; sigset_t set; int err, signum; - if (!PyArg_ParseTuple(args, "O:sigwait", &signals)) - return NULL; - - if (iterable_to_sigset(signals, &set)) + if (iterable_to_sigset(sigset, &set)) return NULL; Py_BEGIN_ALLOW_THREADS @@ -693,10 +1039,6 @@ signal_sigwait(PyObject *self, PyObject return PyLong_FromLong(signum); } -PyDoc_STRVAR(signal_sigwait_doc, -"sigwait(sigset) -> signum\n\ -\n\ -Wait a signal."); #endif /* #ifdef HAVE_SIGPENDING */ #if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT) @@ -752,18 +1094,40 @@ fill_siginfo(siginfo_t *si) #endif #ifdef HAVE_SIGWAITINFO + +/*[clinic input] +signal.sigwaitinfo + + sigset: 'O' + / + +Wait for a signal and return extended info. + +Suspend execution of the calling thread until the delivery of one of the +signals specified in the signal set sigset. The function accepts the signal +and returns a struct_siginfo containing information about the signal. +[clinic start generated code]*/ + +PyDoc_STRVAR(signal_sigwaitinfo__doc__, +"sigwaitinfo(sigset)\n" +"Wait for a signal and return extended info.\n" +"\n" +"Suspend execution of the calling thread until the delivery of one of the\n" +"signals specified in the signal set sigset. The function accepts the signal\n" +"and returns a struct_siginfo containing information about the signal."); + +#define SIGNAL_SIGWAITINFO_METHODDEF \ + {"sigwaitinfo", (PyCFunction)signal_sigwaitinfo, METH_O, signal_sigwaitinfo__doc__}, + static PyObject * -signal_sigwaitinfo(PyObject *self, PyObject *args) +signal_sigwaitinfo(PyModuleDef *module, PyObject *sigset) +/*[clinic end generated code: checksum=78b37d155c7a238d619d531cd7674c386e372076]*/ { - PyObject *signals; sigset_t set; siginfo_t si; int err; - if (!PyArg_ParseTuple(args, "O:sigwaitinfo", &signals)) - return NULL; - - if (iterable_to_sigset(signals, &set)) + if (iterable_to_sigset(sigset, &set)) return NULL; Py_BEGIN_ALLOW_THREADS @@ -775,19 +1139,55 @@ signal_sigwaitinfo(PyObject *self, PyObj return fill_siginfo(&si); } -PyDoc_STRVAR(signal_sigwaitinfo_doc, -"sigwaitinfo(sigset) -> struct_siginfo\n\ -\n\ -Wait synchronously for a signal until one of the signals in *sigset* is\n\ -delivered.\n\ -Returns a struct_siginfo containing information about the signal."); #endif /* #ifdef HAVE_SIGWAITINFO */ #ifdef HAVE_SIGTIMEDWAIT + +/*[clinic input] +signal.sigtimedwait + + sigset: 'O' + timeout: 'O' + / + +Like sigwaitinfo(), but with a timeout. + +The timeout is specified in seconds, with floating point numbers allowed. +[clinic start generated code]*/ + +PyDoc_STRVAR(signal_sigtimedwait__doc__, +"sigtimedwait(sigset, timeout)\n" +"Like sigwaitinfo(), but with a timeout.\n" +"\n" +"The timeout is specified in seconds, with floating point numbers allowed."); + +#define SIGNAL_SIGTIMEDWAIT_METHODDEF \ + {"sigtimedwait", (PyCFunction)signal_sigtimedwait, METH_VARARGS, signal_sigtimedwait__doc__}, + static PyObject * -signal_sigtimedwait(PyObject *self, PyObject *args) +signal_sigtimedwait_impl(PyModuleDef *module, PyObject *sigset, PyObject *timeout); + +static PyObject * +signal_sigtimedwait(PyModuleDef *module, PyObject *args) { - PyObject *signals, *timeout; + PyObject *return_value = NULL; + PyObject *sigset; + PyObject *timeout; + + if (!PyArg_ParseTuple(args, + "OO:sigtimedwait", + &sigset, &timeout)) + goto exit; + return_value = signal_sigtimedwait_impl(module, sigset, timeout); + +exit: + return return_value; +} + +static PyObject * +signal_sigtimedwait_impl(PyModuleDef *module, PyObject *sigset, PyObject *timeout) +/*[clinic end generated code: checksum=b0028361934fccec477792e50e002309031b5aee]*/ +{ struct timespec buf; sigset_t set; siginfo_t si; @@ -795,10 +1195,6 @@ signal_sigtimedwait(PyObject *self, PyOb long tv_nsec; int err; - if (!PyArg_ParseTuple(args, "OO:sigtimedwait", - &signals, &timeout)) - return NULL; - if (_PyTime_ObjectToTimespec(timeout, &tv_sec, &tv_nsec) == -1) return NULL; buf.tv_sec = tv_sec; @@ -809,7 +1205,7 @@ signal_sigtimedwait(PyObject *self, PyOb return NULL; } - if (iterable_to_sigset(signals, &set)) + if (iterable_to_sigset(sigset, &set)) return NULL; Py_BEGIN_ALLOW_THREADS @@ -825,26 +1221,55 @@ signal_sigtimedwait(PyObject *self, PyOb return fill_siginfo(&si); } -PyDoc_STRVAR(signal_sigtimedwait_doc, -"sigtimedwait(sigset, (timeout_sec, timeout_nsec)) -> struct_siginfo\n\ -\n\ -Like sigwaitinfo(), but with a timeout specified as a tuple of (seconds,\n\ -nanoseconds)."); #endif /* #ifdef HAVE_SIGTIMEDWAIT */ #if defined(HAVE_PTHREAD_KILL) && defined(WITH_THREAD) + +/*[clinic input] +signal.pthread_kill + + thread_id: 'l' + signalnum: 'i' + / + +Send a signal to a thread. +[clinic start generated code]*/ + +PyDoc_STRVAR(signal_pthread_kill__doc__, +"pthread_kill(thread_id, signalnum)\n" +"Send a signal to a thread."); + +#define SIGNAL_PTHREAD_KILL_METHODDEF \ + {"pthread_kill", (PyCFunction)signal_pthread_kill, METH_VARARGS, signal_pthread_kill__doc__}, + static PyObject * -signal_pthread_kill(PyObject *self, PyObject *args) +signal_pthread_kill_impl(PyModuleDef *module, long thread_id, int signalnum); + +static PyObject * +signal_pthread_kill(PyModuleDef *module, PyObject *args) { - long tid; - int signum; + PyObject *return_value = NULL; + long thread_id; + int signalnum; + + if (!PyArg_ParseTuple(args, + "li:pthread_kill", + &thread_id, &signalnum)) + goto exit; + return_value = signal_pthread_kill_impl(module, thread_id, signalnum); + +exit: + return return_value; +} + +static PyObject * +signal_pthread_kill_impl(PyModuleDef *module, long thread_id, int signalnum) +/*[clinic end generated code: checksum=c54762f60f82fe1a9475c73e75004668c4142a7f]*/ +{ int err; - if (!PyArg_ParseTuple(args, "li:pthread_kill", &tid, &signum)) - return NULL; - - err = pthread_kill((pthread_t)tid, signum); + err = pthread_kill((pthread_t)thread_id, signalnum); if (err != 0) { errno = err; PyErr_SetFromErrno(PyExc_OSError); @@ -858,10 +1283,6 @@ signal_pthread_kill(PyObject *self, PyOb Py_RETURN_NONE; } -PyDoc_STRVAR(signal_pthread_kill_doc, -"pthread_kill(thread_id, signum)\n\ -\n\ -Send a signal to a thread."); #endif /* #if defined(HAVE_PTHREAD_KILL) && defined(WITH_THREAD) */ @@ -869,49 +1290,42 @@ Send a signal to a thread."); /* List of functions defined in the module */ static PyMethodDef signal_methods[] = { #ifdef HAVE_ALARM - {"alarm", signal_alarm, METH_VARARGS, alarm_doc}, + SIGNAL_ALARM_METHODDEF #endif #ifdef HAVE_SETITIMER - {"setitimer", signal_setitimer, METH_VARARGS, setitimer_doc}, + SIGNAL_SETITIMER_METHODDEF #endif #ifdef HAVE_GETITIMER - {"getitimer", signal_getitimer, METH_VARARGS, getitimer_doc}, + SIGNAL_GETITIMER_METHODDEF #endif - {"signal", signal_signal, METH_VARARGS, signal_doc}, - {"getsignal", signal_getsignal, METH_VARARGS, getsignal_doc}, - {"set_wakeup_fd", signal_set_wakeup_fd, METH_VARARGS, set_wakeup_fd_doc}, + SIGNAL_SIGNAL_METHODDEF + SIGNAL_GETSIGNAL_METHODDEF + SIGNAL_SET_WAKEUP_FD_METHODDEF #ifdef HAVE_SIGINTERRUPT - {"siginterrupt", signal_siginterrupt, METH_VARARGS, siginterrupt_doc}, + SIGNAL_SIGINTERRUPT_METHODDEF #endif #ifdef HAVE_PAUSE - {"pause", (PyCFunction)signal_pause, - METH_NOARGS, pause_doc}, + SIGNAL_PAUSE_METHODDEF #endif {"default_int_handler", signal_default_int_handler, METH_VARARGS, default_int_handler_doc}, #if defined(HAVE_PTHREAD_KILL) && defined(WITH_THREAD) - {"pthread_kill", (PyCFunction)signal_pthread_kill, - METH_VARARGS, signal_pthread_kill_doc}, + SIGNAL_PTHREAD_KILL_METHODDEF #endif #ifdef PYPTHREAD_SIGMASK - {"pthread_sigmask", (PyCFunction)signal_pthread_sigmask, - METH_VARARGS, signal_pthread_sigmask_doc}, + SIGNAL_PTHREAD_SIGMASK_METHODDEF #endif #ifdef HAVE_SIGPENDING - {"sigpending", (PyCFunction)signal_sigpending, - METH_NOARGS, signal_sigpending_doc}, + SIGNAL_SIGPENDING_METHODDEF #endif #ifdef HAVE_SIGWAIT - {"sigwait", (PyCFunction)signal_sigwait, - METH_VARARGS, signal_sigwait_doc}, + SIGNAL_SIGWAIT_METHODDEF #endif #ifdef HAVE_SIGWAITINFO - {"sigwaitinfo", (PyCFunction)signal_sigwaitinfo, - METH_VARARGS, signal_sigwaitinfo_doc}, + SIGNAL_SIGWAITINFO_METHODDEF #endif #ifdef HAVE_SIGTIMEDWAIT - {"sigtimedwait", (PyCFunction)signal_sigtimedwait, - METH_VARARGS, signal_sigtimedwait_doc}, + SIGNAL_SIGTIMEDWAIT_METHODDEF #endif {NULL, NULL} /* sentinel */ };