mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
Issue #20182: converted the signal module to use Argument Clinic
This commit is contained in:
parent
97fceee3b9
commit
c7027b7904
3 changed files with 684 additions and 221 deletions
|
@ -219,21 +219,21 @@ The :mod:`signal` module defines the following functions:
|
||||||
:func:`sigpending`.
|
:func:`sigpending`.
|
||||||
|
|
||||||
|
|
||||||
.. function:: pthread_kill(thread_id, signum)
|
.. function:: pthread_kill(thread_id, signalnum)
|
||||||
|
|
||||||
Send the signal *signum* to the thread *thread_id*, another thread in the
|
Send the signal *signalnum* to the thread *thread_id*, another thread in the
|
||||||
same process as the caller. The target thread can be executing any code
|
same process as the caller. The target thread can be executing any code
|
||||||
(Python or not). However, if the target thread is executing the Python
|
(Python or not). However, if the target thread is executing the Python
|
||||||
interpreter, the Python signal handlers will be :ref:`executed by the main
|
interpreter, the Python signal handlers will be :ref:`executed by the main
|
||||||
thread <signals-and-threads>`. Therefore, the only point of sending a signal to a particular
|
thread <signals-and-threads>`. Therefore, the only point of sending a
|
||||||
Python thread would be to force a running system call to fail with
|
signal to a particular Python thread would be to force a running system call
|
||||||
:exc:`InterruptedError`.
|
to fail with :exc:`InterruptedError`.
|
||||||
|
|
||||||
Use :func:`threading.get_ident()` or the :attr:`~threading.Thread.ident`
|
Use :func:`threading.get_ident()` or the :attr:`~threading.Thread.ident`
|
||||||
attribute of :class:`threading.Thread` objects to get a suitable value
|
attribute of :class:`threading.Thread` objects to get a suitable value
|
||||||
for *thread_id*.
|
for *thread_id*.
|
||||||
|
|
||||||
If *signum* is 0, then no signal is sent, but error checking is still
|
If *signalnum* is 0, then no signal is sent, but error checking is still
|
||||||
performed; this can be used to check if the target thread is still running.
|
performed; this can be used to check if the target thread is still running.
|
||||||
|
|
||||||
Availability: Unix (see the man page :manpage:`pthread_kill(3)` for further
|
Availability: Unix (see the man page :manpage:`pthread_kill(3)` for further
|
||||||
|
|
432
Modules/clinic/signalmodule.c.h
Normal file
432
Modules/clinic/signalmodule.c.h
Normal file
|
@ -0,0 +1,432 @@
|
||||||
|
/*[clinic input]
|
||||||
|
preserve
|
||||||
|
[clinic start generated code]*/
|
||||||
|
|
||||||
|
#if defined(HAVE_ALARM)
|
||||||
|
|
||||||
|
PyDoc_STRVAR(signal_alarm__doc__,
|
||||||
|
"alarm($module, seconds, /)\n"
|
||||||
|
"--\n"
|
||||||
|
"\n"
|
||||||
|
"Arrange for SIGALRM to arrive after the given number of seconds.");
|
||||||
|
|
||||||
|
#define SIGNAL_ALARM_METHODDEF \
|
||||||
|
{"alarm", (PyCFunction)signal_alarm, METH_O, signal_alarm__doc__},
|
||||||
|
|
||||||
|
static long
|
||||||
|
signal_alarm_impl(PyModuleDef *module, int seconds);
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
signal_alarm(PyModuleDef *module, PyObject *arg)
|
||||||
|
{
|
||||||
|
PyObject *return_value = NULL;
|
||||||
|
int seconds;
|
||||||
|
long _return_value;
|
||||||
|
|
||||||
|
if (!PyArg_Parse(arg, "i:alarm", &seconds))
|
||||||
|
goto exit;
|
||||||
|
_return_value = signal_alarm_impl(module, seconds);
|
||||||
|
if ((_return_value == -1) && PyErr_Occurred())
|
||||||
|
goto exit;
|
||||||
|
return_value = PyLong_FromLong(_return_value);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return return_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* defined(HAVE_ALARM) */
|
||||||
|
|
||||||
|
#if defined(HAVE_PAUSE)
|
||||||
|
|
||||||
|
PyDoc_STRVAR(signal_pause__doc__,
|
||||||
|
"pause($module, /)\n"
|
||||||
|
"--\n"
|
||||||
|
"\n"
|
||||||
|
"Wait until a signal arrives.");
|
||||||
|
|
||||||
|
#define SIGNAL_PAUSE_METHODDEF \
|
||||||
|
{"pause", (PyCFunction)signal_pause, METH_NOARGS, signal_pause__doc__},
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
signal_pause_impl(PyModuleDef *module);
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
signal_pause(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
|
||||||
|
{
|
||||||
|
return signal_pause_impl(module);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* defined(HAVE_PAUSE) */
|
||||||
|
|
||||||
|
PyDoc_STRVAR(signal_signal__doc__,
|
||||||
|
"signal($module, signalnum, handler, /)\n"
|
||||||
|
"--\n"
|
||||||
|
"\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_impl(PyModuleDef *module, int signalnum, PyObject *handler);
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
signal_signal(PyModuleDef *module, PyObject *args)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyDoc_STRVAR(signal_getsignal__doc__,
|
||||||
|
"getsignal($module, signalnum, /)\n"
|
||||||
|
"--\n"
|
||||||
|
"\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_O, signal_getsignal__doc__},
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
signal_getsignal_impl(PyModuleDef *module, int signalnum);
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
signal_getsignal(PyModuleDef *module, PyObject *arg)
|
||||||
|
{
|
||||||
|
PyObject *return_value = NULL;
|
||||||
|
int signalnum;
|
||||||
|
|
||||||
|
if (!PyArg_Parse(arg, "i:getsignal", &signalnum))
|
||||||
|
goto exit;
|
||||||
|
return_value = signal_getsignal_impl(module, signalnum);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return return_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(HAVE_SIGINTERRUPT)
|
||||||
|
|
||||||
|
PyDoc_STRVAR(signal_siginterrupt__doc__,
|
||||||
|
"siginterrupt($module, signalnum, flag, /)\n"
|
||||||
|
"--\n"
|
||||||
|
"\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_impl(PyModuleDef *module, int signalnum, int flag);
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
signal_siginterrupt(PyModuleDef *module, PyObject *args)
|
||||||
|
{
|
||||||
|
PyObject *return_value = NULL;
|
||||||
|
int signalnum;
|
||||||
|
int flag;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "ii:siginterrupt",
|
||||||
|
&signalnum, &flag))
|
||||||
|
goto exit;
|
||||||
|
return_value = signal_siginterrupt_impl(module, signalnum, flag);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return return_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* defined(HAVE_SIGINTERRUPT) */
|
||||||
|
|
||||||
|
#if defined(HAVE_SETITIMER)
|
||||||
|
|
||||||
|
PyDoc_STRVAR(signal_setitimer__doc__,
|
||||||
|
"setitimer($module, which, seconds, interval=0.0, /)\n"
|
||||||
|
"--\n"
|
||||||
|
"\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_impl(PyModuleDef *module, int which, double seconds,
|
||||||
|
double interval);
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
signal_setitimer(PyModuleDef *module, PyObject *args)
|
||||||
|
{
|
||||||
|
PyObject *return_value = NULL;
|
||||||
|
int which;
|
||||||
|
double seconds;
|
||||||
|
double interval = 0.0;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* defined(HAVE_SETITIMER) */
|
||||||
|
|
||||||
|
#if defined(HAVE_GETITIMER)
|
||||||
|
|
||||||
|
PyDoc_STRVAR(signal_getitimer__doc__,
|
||||||
|
"getitimer($module, which, /)\n"
|
||||||
|
"--\n"
|
||||||
|
"\n"
|
||||||
|
"Returns current value of given itimer.");
|
||||||
|
|
||||||
|
#define SIGNAL_GETITIMER_METHODDEF \
|
||||||
|
{"getitimer", (PyCFunction)signal_getitimer, METH_O, signal_getitimer__doc__},
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
signal_getitimer_impl(PyModuleDef *module, int which);
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
signal_getitimer(PyModuleDef *module, PyObject *arg)
|
||||||
|
{
|
||||||
|
PyObject *return_value = NULL;
|
||||||
|
int which;
|
||||||
|
|
||||||
|
if (!PyArg_Parse(arg, "i:getitimer", &which))
|
||||||
|
goto exit;
|
||||||
|
return_value = signal_getitimer_impl(module, which);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return return_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* defined(HAVE_GETITIMER) */
|
||||||
|
|
||||||
|
#if defined(PYPTHREAD_SIGMASK)
|
||||||
|
|
||||||
|
PyDoc_STRVAR(signal_pthread_sigmask__doc__,
|
||||||
|
"pthread_sigmask($module, how, mask, /)\n"
|
||||||
|
"--\n"
|
||||||
|
"\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_impl(PyModuleDef *module, int how, PyObject *mask);
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
signal_pthread_sigmask(PyModuleDef *module, PyObject *args)
|
||||||
|
{
|
||||||
|
PyObject *return_value = NULL;
|
||||||
|
int how;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* defined(PYPTHREAD_SIGMASK) */
|
||||||
|
|
||||||
|
#if defined(HAVE_SIGPENDING)
|
||||||
|
|
||||||
|
PyDoc_STRVAR(signal_sigpending__doc__,
|
||||||
|
"sigpending($module, /)\n"
|
||||||
|
"--\n"
|
||||||
|
"\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_impl(PyModuleDef *module);
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
signal_sigpending(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
|
||||||
|
{
|
||||||
|
return signal_sigpending_impl(module);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* defined(HAVE_SIGPENDING) */
|
||||||
|
|
||||||
|
#if defined(HAVE_SIGWAIT)
|
||||||
|
|
||||||
|
PyDoc_STRVAR(signal_sigwait__doc__,
|
||||||
|
"sigwait($module, sigset, /)\n"
|
||||||
|
"--\n"
|
||||||
|
"\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__},
|
||||||
|
|
||||||
|
#endif /* defined(HAVE_SIGWAIT) */
|
||||||
|
|
||||||
|
#if defined(HAVE_SIGWAITINFO)
|
||||||
|
|
||||||
|
PyDoc_STRVAR(signal_sigwaitinfo__doc__,
|
||||||
|
"sigwaitinfo($module, sigset, /)\n"
|
||||||
|
"--\n"
|
||||||
|
"\n"
|
||||||
|
"Wait synchronously until one of the signals in *sigset* is delivered.\n"
|
||||||
|
"\n"
|
||||||
|
"Returns a struct_siginfo containing information about the signal.");
|
||||||
|
|
||||||
|
#define SIGNAL_SIGWAITINFO_METHODDEF \
|
||||||
|
{"sigwaitinfo", (PyCFunction)signal_sigwaitinfo, METH_O, signal_sigwaitinfo__doc__},
|
||||||
|
|
||||||
|
#endif /* defined(HAVE_SIGWAITINFO) */
|
||||||
|
|
||||||
|
#if defined(HAVE_SIGTIMEDWAIT)
|
||||||
|
|
||||||
|
PyDoc_STRVAR(signal_sigtimedwait__doc__,
|
||||||
|
"sigtimedwait($module, sigset, timeout, /)\n"
|
||||||
|
"--\n"
|
||||||
|
"\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_impl(PyModuleDef *module, PyObject *sigset,
|
||||||
|
PyObject *timeout);
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
signal_sigtimedwait(PyModuleDef *module, PyObject *args)
|
||||||
|
{
|
||||||
|
PyObject *return_value = NULL;
|
||||||
|
PyObject *sigset;
|
||||||
|
PyObject *timeout;
|
||||||
|
|
||||||
|
if (!PyArg_UnpackTuple(args, "sigtimedwait",
|
||||||
|
2, 2,
|
||||||
|
&sigset, &timeout))
|
||||||
|
goto exit;
|
||||||
|
return_value = signal_sigtimedwait_impl(module, sigset, timeout);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return return_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* defined(HAVE_SIGTIMEDWAIT) */
|
||||||
|
|
||||||
|
#if (defined(HAVE_PTHREAD_KILL) && defined(WITH_THREAD))
|
||||||
|
|
||||||
|
PyDoc_STRVAR(signal_pthread_kill__doc__,
|
||||||
|
"pthread_kill($module, thread_id, signalnum, /)\n"
|
||||||
|
"--\n"
|
||||||
|
"\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_impl(PyModuleDef *module, long thread_id, int signalnum);
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
signal_pthread_kill(PyModuleDef *module, PyObject *args)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* (defined(HAVE_PTHREAD_KILL) && defined(WITH_THREAD)) */
|
||||||
|
|
||||||
|
#ifndef SIGNAL_ALARM_METHODDEF
|
||||||
|
#define SIGNAL_ALARM_METHODDEF
|
||||||
|
#endif /* !defined(SIGNAL_ALARM_METHODDEF) */
|
||||||
|
|
||||||
|
#ifndef SIGNAL_PAUSE_METHODDEF
|
||||||
|
#define SIGNAL_PAUSE_METHODDEF
|
||||||
|
#endif /* !defined(SIGNAL_PAUSE_METHODDEF) */
|
||||||
|
|
||||||
|
#ifndef SIGNAL_SIGINTERRUPT_METHODDEF
|
||||||
|
#define SIGNAL_SIGINTERRUPT_METHODDEF
|
||||||
|
#endif /* !defined(SIGNAL_SIGINTERRUPT_METHODDEF) */
|
||||||
|
|
||||||
|
#ifndef SIGNAL_SETITIMER_METHODDEF
|
||||||
|
#define SIGNAL_SETITIMER_METHODDEF
|
||||||
|
#endif /* !defined(SIGNAL_SETITIMER_METHODDEF) */
|
||||||
|
|
||||||
|
#ifndef SIGNAL_GETITIMER_METHODDEF
|
||||||
|
#define SIGNAL_GETITIMER_METHODDEF
|
||||||
|
#endif /* !defined(SIGNAL_GETITIMER_METHODDEF) */
|
||||||
|
|
||||||
|
#ifndef SIGNAL_PTHREAD_SIGMASK_METHODDEF
|
||||||
|
#define SIGNAL_PTHREAD_SIGMASK_METHODDEF
|
||||||
|
#endif /* !defined(SIGNAL_PTHREAD_SIGMASK_METHODDEF) */
|
||||||
|
|
||||||
|
#ifndef SIGNAL_SIGPENDING_METHODDEF
|
||||||
|
#define SIGNAL_SIGPENDING_METHODDEF
|
||||||
|
#endif /* !defined(SIGNAL_SIGPENDING_METHODDEF) */
|
||||||
|
|
||||||
|
#ifndef SIGNAL_SIGWAIT_METHODDEF
|
||||||
|
#define SIGNAL_SIGWAIT_METHODDEF
|
||||||
|
#endif /* !defined(SIGNAL_SIGWAIT_METHODDEF) */
|
||||||
|
|
||||||
|
#ifndef SIGNAL_SIGWAITINFO_METHODDEF
|
||||||
|
#define SIGNAL_SIGWAITINFO_METHODDEF
|
||||||
|
#endif /* !defined(SIGNAL_SIGWAITINFO_METHODDEF) */
|
||||||
|
|
||||||
|
#ifndef SIGNAL_SIGTIMEDWAIT_METHODDEF
|
||||||
|
#define SIGNAL_SIGTIMEDWAIT_METHODDEF
|
||||||
|
#endif /* !defined(SIGNAL_SIGTIMEDWAIT_METHODDEF) */
|
||||||
|
|
||||||
|
#ifndef SIGNAL_PTHREAD_KILL_METHODDEF
|
||||||
|
#define SIGNAL_PTHREAD_KILL_METHODDEF
|
||||||
|
#endif /* !defined(SIGNAL_PTHREAD_KILL_METHODDEF) */
|
||||||
|
/*[clinic end generated code: output=65ca7b83632eda99 input=a9049054013a1b77]*/
|
|
@ -52,6 +52,13 @@
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "clinic/signalmodule.c.h"
|
||||||
|
|
||||||
|
/*[clinic input]
|
||||||
|
module signal
|
||||||
|
[clinic start generated code]*/
|
||||||
|
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=b0301a3bde5fe9d3]*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
NOTES ON THE INTERACTION BETWEEN SIGNALS AND THREADS
|
NOTES ON THE INTERACTION BETWEEN SIGNALS AND THREADS
|
||||||
|
@ -322,25 +329,37 @@ signal_handler(int sig_num)
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_ALARM
|
#ifdef HAVE_ALARM
|
||||||
static PyObject *
|
|
||||||
signal_alarm(PyObject *self, PyObject *args)
|
/*[clinic input]
|
||||||
|
signal.alarm -> long
|
||||||
|
|
||||||
|
seconds: int
|
||||||
|
/
|
||||||
|
|
||||||
|
Arrange for SIGALRM to arrive after the given number of seconds.
|
||||||
|
[clinic start generated code]*/
|
||||||
|
|
||||||
|
static long
|
||||||
|
signal_alarm_impl(PyModuleDef *module, int seconds)
|
||||||
|
/*[clinic end generated code: output=f5f9badaab25d3e7 input=0d5e97e0e6f39e86]*/
|
||||||
{
|
{
|
||||||
int t;
|
|
||||||
if (!PyArg_ParseTuple(args, "i:alarm", &t))
|
|
||||||
return NULL;
|
|
||||||
/* alarm() returns the number of seconds remaining */
|
/* alarm() returns the number of seconds remaining */
|
||||||
return PyLong_FromLong((long)alarm(t));
|
return (long)alarm(seconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(alarm_doc,
|
|
||||||
"alarm(seconds)\n\
|
|
||||||
\n\
|
|
||||||
Arrange for SIGALRM to arrive after the given number of seconds.");
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_PAUSE
|
#ifdef HAVE_PAUSE
|
||||||
|
|
||||||
|
/*[clinic input]
|
||||||
|
signal.pause
|
||||||
|
|
||||||
|
Wait until a signal arrives.
|
||||||
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
signal_pause(PyObject *self)
|
signal_pause_impl(PyModuleDef *module)
|
||||||
|
/*[clinic end generated code: output=9245704caa63bbe9 input=f03de0f875752062]*/
|
||||||
{
|
{
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
(void)pause();
|
(void)pause();
|
||||||
|
@ -351,29 +370,38 @@ signal_pause(PyObject *self)
|
||||||
if (PyErr_CheckSignals())
|
if (PyErr_CheckSignals())
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
PyDoc_STRVAR(pause_doc,
|
|
||||||
"pause()\n\
|
|
||||||
\n\
|
|
||||||
Wait until a signal arrives.");
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*[clinic input]
|
||||||
|
signal.signal
|
||||||
|
|
||||||
|
signalnum: int
|
||||||
|
handler: object
|
||||||
|
/
|
||||||
|
|
||||||
|
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]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
signal_signal(PyObject *self, PyObject *args)
|
signal_signal_impl(PyModuleDef *module, int signalnum, PyObject *handler)
|
||||||
|
/*[clinic end generated code: output=622d7d0beebea546 input=deee84af5fa0432c]*/
|
||||||
{
|
{
|
||||||
PyObject *obj;
|
|
||||||
int sig_num;
|
|
||||||
PyObject *old_handler;
|
PyObject *old_handler;
|
||||||
void (*func)(int);
|
void (*func)(int);
|
||||||
if (!PyArg_ParseTuple(args, "iO:signal", &sig_num, &obj))
|
|
||||||
return NULL;
|
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
/* Validate that sig_num is one of the allowable signals */
|
/* Validate that signalnum is one of the allowable signals */
|
||||||
switch (sig_num) {
|
switch (signalnum) {
|
||||||
case SIGABRT: break;
|
case SIGABRT: break;
|
||||||
#ifdef SIGBREAK
|
#ifdef SIGBREAK
|
||||||
/* Issue #10003: SIGBREAK is not documented as permitted, but works
|
/* Issue #10003: SIGBREAK is not documented as permitted, but works
|
||||||
|
@ -397,61 +425,63 @@ signal_signal(PyObject *self, PyObject *args)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (sig_num < 1 || sig_num >= NSIG) {
|
if (signalnum < 1 || signalnum >= NSIG) {
|
||||||
PyErr_SetString(PyExc_ValueError,
|
PyErr_SetString(PyExc_ValueError,
|
||||||
"signal number out of range");
|
"signal number out of range");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (obj == IgnoreHandler)
|
if (handler == IgnoreHandler)
|
||||||
func = SIG_IGN;
|
func = SIG_IGN;
|
||||||
else if (obj == DefaultHandler)
|
else if (handler == DefaultHandler)
|
||||||
func = SIG_DFL;
|
func = SIG_DFL;
|
||||||
else if (!PyCallable_Check(obj)) {
|
else if (!PyCallable_Check(handler)) {
|
||||||
PyErr_SetString(PyExc_TypeError,
|
PyErr_SetString(PyExc_TypeError,
|
||||||
"signal handler must be signal.SIG_IGN, signal.SIG_DFL, or a callable object");
|
"signal handler must be signal.SIG_IGN, signal.SIG_DFL, or a callable object");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
func = signal_handler;
|
func = signal_handler;
|
||||||
if (PyOS_setsig(sig_num, func) == SIG_ERR) {
|
if (PyOS_setsig(signalnum, func) == SIG_ERR) {
|
||||||
PyErr_SetFromErrno(PyExc_OSError);
|
PyErr_SetFromErrno(PyExc_OSError);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
old_handler = Handlers[sig_num].func;
|
old_handler = Handlers[signalnum].func;
|
||||||
Handlers[sig_num].tripped = 0;
|
Handlers[signalnum].tripped = 0;
|
||||||
Py_INCREF(obj);
|
Py_INCREF(handler);
|
||||||
Handlers[sig_num].func = obj;
|
Handlers[signalnum].func = handler;
|
||||||
if (old_handler != NULL)
|
if (old_handler != NULL)
|
||||||
return old_handler;
|
return old_handler;
|
||||||
else
|
else
|
||||||
Py_RETURN_NONE;
|
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: int
|
||||||
|
/
|
||||||
|
|
||||||
|
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]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
signal_getsignal(PyObject *self, PyObject *args)
|
signal_getsignal_impl(PyModuleDef *module, int signalnum)
|
||||||
|
/*[clinic end generated code: output=d50ec355757e360c input=ac23a00f19dfa509]*/
|
||||||
{
|
{
|
||||||
int sig_num;
|
|
||||||
PyObject *old_handler;
|
PyObject *old_handler;
|
||||||
if (!PyArg_ParseTuple(args, "i:getsignal", &sig_num))
|
if (signalnum < 1 || signalnum >= NSIG) {
|
||||||
return NULL;
|
|
||||||
if (sig_num < 1 || sig_num >= NSIG) {
|
|
||||||
PyErr_SetString(PyExc_ValueError,
|
PyErr_SetString(PyExc_ValueError,
|
||||||
"signal number out of range");
|
"signal number out of range");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
old_handler = Handlers[sig_num].func;
|
old_handler = Handlers[signalnum].func;
|
||||||
if (old_handler != NULL) {
|
if (old_handler != NULL) {
|
||||||
Py_INCREF(old_handler);
|
Py_INCREF(old_handler);
|
||||||
return old_handler;
|
return old_handler;
|
||||||
|
@ -461,47 +491,41 @@ signal_getsignal(PyObject *self, PyObject *args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
#ifdef HAVE_SIGINTERRUPT
|
||||||
PyDoc_STRVAR(siginterrupt_doc,
|
|
||||||
"siginterrupt(sig, flag) -> None\n\
|
/*[clinic input]
|
||||||
change system call restart behaviour: if flag is False, system calls\n\
|
signal.siginterrupt
|
||||||
will be restarted when interrupted by signal sig, else system calls\n\
|
|
||||||
will be interrupted.");
|
signalnum: int
|
||||||
|
flag: int
|
||||||
|
/
|
||||||
|
|
||||||
|
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]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
signal_siginterrupt(PyObject *self, PyObject *args)
|
signal_siginterrupt_impl(PyModuleDef *module, int signalnum, int flag)
|
||||||
|
/*[clinic end generated code: output=5dcf8b031b0e8044 input=4160acacca3e2099]*/
|
||||||
{
|
{
|
||||||
int sig_num;
|
if (signalnum < 1 || signalnum >= NSIG) {
|
||||||
int flag;
|
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "ii:siginterrupt", &sig_num, &flag))
|
|
||||||
return NULL;
|
|
||||||
if (sig_num < 1 || sig_num >= NSIG) {
|
|
||||||
PyErr_SetString(PyExc_ValueError,
|
PyErr_SetString(PyExc_ValueError,
|
||||||
"signal number out of range");
|
"signal number out of range");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (siginterrupt(sig_num, flag)<0) {
|
if (siginterrupt(signalnum, flag)<0) {
|
||||||
PyErr_SetFromErrno(PyExc_OSError);
|
PyErr_SetFromErrno(PyExc_OSError);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
Py_RETURN_NONE;
|
||||||
Py_INCREF(Py_None);
|
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
|
static PyObject*
|
||||||
signal_set_wakeup_fd(PyObject *self, PyObject *args)
|
signal_set_wakeup_fd(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
struct _Py_stat_struct status;
|
struct _Py_stat_struct status;
|
||||||
|
@ -640,62 +664,69 @@ PySignal_SetWakeupFd(int fd)
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_SETITIMER
|
#ifdef HAVE_SETITIMER
|
||||||
|
|
||||||
|
/*[clinic input]
|
||||||
|
signal.setitimer
|
||||||
|
|
||||||
|
which: int
|
||||||
|
seconds: double
|
||||||
|
interval: double = 0.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]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
signal_setitimer(PyObject *self, PyObject *args)
|
signal_setitimer_impl(PyModuleDef *module, int which, double seconds,
|
||||||
|
double interval)
|
||||||
|
/*[clinic end generated code: output=9a9227a27bd05988 input=0d27d417cfcbd51a]*/
|
||||||
{
|
{
|
||||||
double first;
|
|
||||||
double interval = 0;
|
|
||||||
int which;
|
|
||||||
struct itimerval new, old;
|
struct itimerval new, old;
|
||||||
|
|
||||||
if(!PyArg_ParseTuple(args, "id|d:setitimer", &which, &first, &interval))
|
timeval_from_double(seconds, &new.it_value);
|
||||||
return NULL;
|
|
||||||
|
|
||||||
timeval_from_double(first, &new.it_value);
|
|
||||||
timeval_from_double(interval, &new.it_interval);
|
timeval_from_double(interval, &new.it_interval);
|
||||||
/* Let OS check "which" value */
|
/* Let OS check "which" value */
|
||||||
if (setitimer(which, &new, &old) != 0) {
|
if (setitimer(which, &new, &old) != 0) {
|
||||||
PyErr_SetFromErrno(ItimerError);
|
PyErr_SetFromErrno(ItimerError);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return itimer_retval(&old);
|
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
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_GETITIMER
|
#ifdef HAVE_GETITIMER
|
||||||
|
|
||||||
|
/*[clinic input]
|
||||||
|
signal.getitimer
|
||||||
|
|
||||||
|
which: int
|
||||||
|
/
|
||||||
|
|
||||||
|
Returns current value of given itimer.
|
||||||
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
signal_getitimer(PyObject *self, PyObject *args)
|
signal_getitimer_impl(PyModuleDef *module, int which)
|
||||||
|
/*[clinic end generated code: output=d1349ab18aadc569 input=f7d21d38f3490627]*/
|
||||||
{
|
{
|
||||||
int which;
|
|
||||||
struct itimerval old;
|
struct itimerval old;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "i:getitimer", &which))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (getitimer(which, &old) != 0) {
|
if (getitimer(which, &old) != 0) {
|
||||||
PyErr_SetFromErrno(ItimerError);
|
PyErr_SetFromErrno(ItimerError);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return itimer_retval(&old);
|
return itimer_retval(&old);
|
||||||
}
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(getitimer_doc,
|
|
||||||
"getitimer(which)\n\
|
|
||||||
\n\
|
|
||||||
Returns current value of given itimer.");
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PYPTHREAD_SIGMASK) || defined(HAVE_SIGWAIT) || \
|
#if defined(PYPTHREAD_SIGMASK) || defined(HAVE_SIGWAIT) || \
|
||||||
|
@ -786,21 +817,28 @@ sigset_to_set(sigset_t mask)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef PYPTHREAD_SIGMASK
|
#ifdef PYPTHREAD_SIGMASK
|
||||||
|
|
||||||
|
/*[clinic input]
|
||||||
|
signal.pthread_sigmask
|
||||||
|
|
||||||
|
how: int
|
||||||
|
mask: object
|
||||||
|
/
|
||||||
|
|
||||||
|
Fetch and/or change the signal mask of the calling thread.
|
||||||
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
signal_pthread_sigmask(PyObject *self, PyObject *args)
|
signal_pthread_sigmask_impl(PyModuleDef *module, int how, PyObject *mask)
|
||||||
|
/*[clinic end generated code: output=b043a9f0eeb1e075 input=f3b7d7a61b7b8283]*/
|
||||||
{
|
{
|
||||||
int how;
|
sigset_t newmask, previous;
|
||||||
PyObject *signals;
|
|
||||||
sigset_t mask, previous;
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "iO:pthread_sigmask", &how, &signals))
|
if (iterable_to_sigset(mask, &newmask))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (iterable_to_sigset(signals, &mask))
|
err = pthread_sigmask(how, &newmask, &previous);
|
||||||
return NULL;
|
|
||||||
|
|
||||||
err = pthread_sigmask(how, &mask, &previous);
|
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
errno = err;
|
errno = err;
|
||||||
PyErr_SetFromErrno(PyExc_OSError);
|
PyErr_SetFromErrno(PyExc_OSError);
|
||||||
|
@ -814,16 +852,23 @@ signal_pthread_sigmask(PyObject *self, PyObject *args)
|
||||||
return sigset_to_set(previous);
|
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 */
|
#endif /* #ifdef PYPTHREAD_SIGMASK */
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_SIGPENDING
|
#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]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
signal_sigpending(PyObject *self)
|
signal_sigpending_impl(PyModuleDef *module)
|
||||||
|
/*[clinic end generated code: output=bf4ced803e7e51dd input=e0036c016f874e29]*/
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
sigset_t mask;
|
sigset_t mask;
|
||||||
|
@ -833,25 +878,32 @@ signal_sigpending(PyObject *self)
|
||||||
return sigset_to_set(mask);
|
return sigset_to_set(mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(signal_sigpending_doc,
|
|
||||||
"sigpending() -> list\n\
|
|
||||||
\n\
|
|
||||||
Examine pending signals.");
|
|
||||||
#endif /* #ifdef HAVE_SIGPENDING */
|
#endif /* #ifdef HAVE_SIGPENDING */
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_SIGWAIT
|
#ifdef HAVE_SIGWAIT
|
||||||
|
|
||||||
|
/*[clinic input]
|
||||||
|
signal.sigwait
|
||||||
|
|
||||||
|
sigset: object
|
||||||
|
/
|
||||||
|
|
||||||
|
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]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
signal_sigwait(PyObject *self, PyObject *args)
|
signal_sigwait(PyModuleDef *module, PyObject *sigset)
|
||||||
|
/*[clinic end generated code: output=dae53048b0336a5c input=11af2d82d83c2e94]*/
|
||||||
{
|
{
|
||||||
PyObject *signals;
|
|
||||||
sigset_t set;
|
sigset_t set;
|
||||||
int err, signum;
|
int err, signum;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "O:sigwait", &signals))
|
if (iterable_to_sigset(sigset, &set))
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (iterable_to_sigset(signals, &set))
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
|
@ -865,11 +917,8 @@ signal_sigwait(PyObject *self, PyObject *args)
|
||||||
return PyLong_FromLong(signum);
|
return PyLong_FromLong(signum);
|
||||||
}
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(signal_sigwait_doc,
|
#endif /* #ifdef HAVE_SIGWAIT */
|
||||||
"sigwait(sigset) -> signum\n\
|
|
||||||
\n\
|
|
||||||
Wait a signal.");
|
|
||||||
#endif /* #ifdef HAVE_SIGPENDING */
|
|
||||||
|
|
||||||
#if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT)
|
#if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT)
|
||||||
static int initialized;
|
static int initialized;
|
||||||
|
@ -924,19 +973,28 @@ fill_siginfo(siginfo_t *si)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_SIGWAITINFO
|
#ifdef HAVE_SIGWAITINFO
|
||||||
|
|
||||||
|
/*[clinic input]
|
||||||
|
signal.sigwaitinfo
|
||||||
|
|
||||||
|
sigset: object
|
||||||
|
/
|
||||||
|
|
||||||
|
Wait synchronously until one of the signals in *sigset* is delivered.
|
||||||
|
|
||||||
|
Returns a struct_siginfo containing information about the signal.
|
||||||
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
signal_sigwaitinfo(PyObject *self, PyObject *args)
|
signal_sigwaitinfo(PyModuleDef *module, PyObject *sigset)
|
||||||
|
/*[clinic end generated code: output=0bb53b07e5e926b5 input=f3779a74a991e171]*/
|
||||||
{
|
{
|
||||||
PyObject *signals;
|
|
||||||
sigset_t set;
|
sigset_t set;
|
||||||
siginfo_t si;
|
siginfo_t si;
|
||||||
int err;
|
int err;
|
||||||
int async_err = 0;
|
int async_err = 0;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "O:sigwaitinfo", &signals))
|
if (iterable_to_sigset(sigset, &set))
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (iterable_to_sigset(signals, &set))
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
@ -951,29 +1009,33 @@ signal_sigwaitinfo(PyObject *self, PyObject *args)
|
||||||
return fill_siginfo(&si);
|
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 */
|
#endif /* #ifdef HAVE_SIGWAITINFO */
|
||||||
|
|
||||||
#ifdef HAVE_SIGTIMEDWAIT
|
#ifdef HAVE_SIGTIMEDWAIT
|
||||||
|
|
||||||
|
/*[clinic input]
|
||||||
|
signal.sigtimedwait
|
||||||
|
|
||||||
|
sigset: object
|
||||||
|
timeout: object
|
||||||
|
/
|
||||||
|
|
||||||
|
Like sigwaitinfo(), but with a timeout.
|
||||||
|
|
||||||
|
The timeout is specified in seconds, with floating point numbers allowed.
|
||||||
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
signal_sigtimedwait(PyObject *self, PyObject *args)
|
signal_sigtimedwait_impl(PyModuleDef *module, PyObject *sigset,
|
||||||
|
PyObject *timeout)
|
||||||
|
/*[clinic end generated code: output=e6e049f2bddea688 input=036bbab9b15cb8de]*/
|
||||||
{
|
{
|
||||||
PyObject *signals, *timeout_obj;
|
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
sigset_t set;
|
sigset_t set;
|
||||||
siginfo_t si;
|
siginfo_t si;
|
||||||
int res;
|
int res;
|
||||||
_PyTime_t timeout, deadline, monotonic;
|
_PyTime_t timeout, deadline, monotonic;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "OO:sigtimedwait",
|
|
||||||
&signals, &timeout_obj))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (_PyTime_FromSecondsObject(&timeout,
|
if (_PyTime_FromSecondsObject(&timeout,
|
||||||
timeout_obj, _PyTime_ROUND_CEILING) < 0)
|
timeout_obj, _PyTime_ROUND_CEILING) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -983,7 +1045,7 @@ signal_sigtimedwait(PyObject *self, PyObject *args)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iterable_to_sigset(signals, &set))
|
if (iterable_to_sigset(sigset, &set))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
deadline = _PyTime_GetMonotonicClock() + timeout;
|
deadline = _PyTime_GetMonotonicClock() + timeout;
|
||||||
|
@ -1019,26 +1081,28 @@ signal_sigtimedwait(PyObject *self, PyObject *args)
|
||||||
return fill_siginfo(&si);
|
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 */
|
#endif /* #ifdef HAVE_SIGTIMEDWAIT */
|
||||||
|
|
||||||
|
|
||||||
#if defined(HAVE_PTHREAD_KILL) && defined(WITH_THREAD)
|
#if defined(HAVE_PTHREAD_KILL) && defined(WITH_THREAD)
|
||||||
|
|
||||||
|
/*[clinic input]
|
||||||
|
signal.pthread_kill
|
||||||
|
|
||||||
|
thread_id: long
|
||||||
|
signalnum: int
|
||||||
|
/
|
||||||
|
|
||||||
|
Send a signal to a thread.
|
||||||
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
signal_pthread_kill(PyObject *self, PyObject *args)
|
signal_pthread_kill_impl(PyModuleDef *module, long thread_id, int signalnum)
|
||||||
|
/*[clinic end generated code: output=35aed2713c756d7a input=77ed6a3b6f2a8122]*/
|
||||||
{
|
{
|
||||||
long tid;
|
|
||||||
int signum;
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "li:pthread_kill", &tid, &signum))
|
err = pthread_kill((pthread_t)thread_id, signalnum);
|
||||||
return NULL;
|
|
||||||
|
|
||||||
err = pthread_kill((pthread_t)tid, signum);
|
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
errno = err;
|
errno = err;
|
||||||
PyErr_SetFromErrno(PyExc_OSError);
|
PyErr_SetFromErrno(PyExc_OSError);
|
||||||
|
@ -1052,62 +1116,29 @@ signal_pthread_kill(PyObject *self, PyObject *args)
|
||||||
Py_RETURN_NONE;
|
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) */
|
#endif /* #if defined(HAVE_PTHREAD_KILL) && defined(WITH_THREAD) */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* List of functions defined in the module */
|
/* List of functions defined in the module -- some of the methoddefs are
|
||||||
|
defined to nothing if the corresponding C function is not available. */
|
||||||
static PyMethodDef signal_methods[] = {
|
static PyMethodDef signal_methods[] = {
|
||||||
#ifdef HAVE_ALARM
|
{"default_int_handler", signal_default_int_handler, METH_VARARGS, default_int_handler_doc},
|
||||||
{"alarm", signal_alarm, METH_VARARGS, alarm_doc},
|
SIGNAL_ALARM_METHODDEF
|
||||||
#endif
|
SIGNAL_SETITIMER_METHODDEF
|
||||||
#ifdef HAVE_SETITIMER
|
SIGNAL_GETITIMER_METHODDEF
|
||||||
{"setitimer", signal_setitimer, METH_VARARGS, setitimer_doc},
|
SIGNAL_SIGNAL_METHODDEF
|
||||||
#endif
|
SIGNAL_GETSIGNAL_METHODDEF
|
||||||
#ifdef HAVE_GETITIMER
|
|
||||||
{"getitimer", signal_getitimer, METH_VARARGS, getitimer_doc},
|
|
||||||
#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},
|
{"set_wakeup_fd", signal_set_wakeup_fd, METH_VARARGS, set_wakeup_fd_doc},
|
||||||
#ifdef HAVE_SIGINTERRUPT
|
SIGNAL_SIGINTERRUPT_METHODDEF
|
||||||
{"siginterrupt", signal_siginterrupt, METH_VARARGS, siginterrupt_doc},
|
SIGNAL_PAUSE_METHODDEF
|
||||||
#endif
|
SIGNAL_PTHREAD_KILL_METHODDEF
|
||||||
#ifdef HAVE_PAUSE
|
SIGNAL_PTHREAD_SIGMASK_METHODDEF
|
||||||
{"pause", (PyCFunction)signal_pause,
|
SIGNAL_SIGPENDING_METHODDEF
|
||||||
METH_NOARGS, pause_doc},
|
SIGNAL_SIGWAIT_METHODDEF
|
||||||
#endif
|
SIGNAL_SIGWAITINFO_METHODDEF
|
||||||
{"default_int_handler", signal_default_int_handler,
|
SIGNAL_SIGTIMEDWAIT_METHODDEF
|
||||||
METH_VARARGS, default_int_handler_doc},
|
{NULL, NULL} /* sentinel */
|
||||||
#if defined(HAVE_PTHREAD_KILL) && defined(WITH_THREAD)
|
|
||||||
{"pthread_kill", (PyCFunction)signal_pthread_kill,
|
|
||||||
METH_VARARGS, signal_pthread_kill_doc},
|
|
||||||
#endif
|
|
||||||
#ifdef PYPTHREAD_SIGMASK
|
|
||||||
{"pthread_sigmask", (PyCFunction)signal_pthread_sigmask,
|
|
||||||
METH_VARARGS, signal_pthread_sigmask_doc},
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SIGPENDING
|
|
||||||
{"sigpending", (PyCFunction)signal_sigpending,
|
|
||||||
METH_NOARGS, signal_sigpending_doc},
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SIGWAIT
|
|
||||||
{"sigwait", (PyCFunction)signal_sigwait,
|
|
||||||
METH_VARARGS, signal_sigwait_doc},
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SIGWAITINFO
|
|
||||||
{"sigwaitinfo", (PyCFunction)signal_sigwaitinfo,
|
|
||||||
METH_VARARGS, signal_sigwaitinfo_doc},
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SIGTIMEDWAIT
|
|
||||||
{"sigtimedwait", (PyCFunction)signal_sigtimedwait,
|
|
||||||
METH_VARARGS, signal_sigtimedwait_doc},
|
|
||||||
#endif
|
|
||||||
{NULL, NULL} /* sentinel */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue