mirror of
https://github.com/python/cpython.git
synced 2025-08-02 08:02:56 +00:00
merge forward from the python 2.x branch
This commit is contained in:
parent
2aa3af4a16
commit
867c435460
7 changed files with 474 additions and 7 deletions
|
@ -13,9 +13,6 @@ rules for working with signals and their handlers:
|
||||||
underlying implementation), with the exception of the handler for
|
underlying implementation), with the exception of the handler for
|
||||||
:const:`SIGCHLD`, which follows the underlying implementation.
|
:const:`SIGCHLD`, which follows the underlying implementation.
|
||||||
|
|
||||||
* There is no way to "block" signals temporarily from critical sections (since
|
|
||||||
this is not supported by all Unix flavors).
|
|
||||||
|
|
||||||
* Although Python signal handlers are called asynchronously as far as the Python
|
* Although Python signal handlers are called asynchronously as far as the Python
|
||||||
user is concerned, they can only occur between the "atomic" instructions of the
|
user is concerned, they can only occur between the "atomic" instructions of the
|
||||||
Python interpreter. This means that signals arriving during long calculations
|
Python interpreter. This means that signals arriving during long calculations
|
||||||
|
@ -115,6 +112,46 @@ The variables defined in the :mod:`signal` module are:
|
||||||
in user and kernel space. SIGPROF is delivered upon expiration.
|
in user and kernel space. SIGPROF is delivered upon expiration.
|
||||||
|
|
||||||
|
|
||||||
|
.. data:: SIG_BLOCK
|
||||||
|
|
||||||
|
A possible value for the *how* parameter to :func:`sigprocmask`
|
||||||
|
indicating that signals are to be blocked.
|
||||||
|
|
||||||
|
.. versionadded:: 2.7
|
||||||
|
|
||||||
|
|
||||||
|
.. data:: SIG_UNBLOCK
|
||||||
|
|
||||||
|
A possible value for the *how* parameter to :func:`sigprocmask`
|
||||||
|
indicating that signals are to be unblocked.
|
||||||
|
|
||||||
|
.. versionadded:: 2.7
|
||||||
|
|
||||||
|
|
||||||
|
.. data:: SIG_SETMASK
|
||||||
|
|
||||||
|
A possible value for the *how* parameter to :func:`sigprocmask`
|
||||||
|
indicating that the signal mask is to be replaced.
|
||||||
|
|
||||||
|
.. versionadded:: 2.7
|
||||||
|
|
||||||
|
|
||||||
|
.. data:: SFD_CLOEXEC
|
||||||
|
|
||||||
|
A possible flag in the *flags* parameter to :func:`signalfd` which causes
|
||||||
|
the new file descriptor to be marked as close-on-exec.
|
||||||
|
|
||||||
|
.. versionadded:: 2.7
|
||||||
|
|
||||||
|
|
||||||
|
.. data:: SFD_NONBLOCK
|
||||||
|
|
||||||
|
A possible flag in the *flags* parameter to :func:`signalfd` which causes
|
||||||
|
the new file description to be set non-blocking.
|
||||||
|
|
||||||
|
.. versionadded:: 2.7
|
||||||
|
|
||||||
|
|
||||||
The :mod:`signal` module defines one exception:
|
The :mod:`signal` module defines one exception:
|
||||||
|
|
||||||
.. exception:: ItimerError
|
.. exception:: ItimerError
|
||||||
|
@ -227,6 +264,44 @@ The :mod:`signal` module defines the following functions:
|
||||||
attribute descriptions in the :mod:`inspect` module).
|
attribute descriptions in the :mod:`inspect` module).
|
||||||
|
|
||||||
|
|
||||||
|
.. function:: signalfd(fd, mask[, flags])
|
||||||
|
|
||||||
|
Create a new file descriptor on which to receive signals or modify the
|
||||||
|
mask of such a file descriptor previously created by this function.
|
||||||
|
Availability: Linux (See the manpage :manpage:`signalfd(2)` for further
|
||||||
|
information).
|
||||||
|
|
||||||
|
If *fd* is ``-1``, a new file descriptor will be created. Otherwise,
|
||||||
|
*fd* must be a file descriptor previously returned by this function.
|
||||||
|
|
||||||
|
*mask* is a list of signal numbers which will trigger data on this file
|
||||||
|
descriptor.
|
||||||
|
|
||||||
|
*flags* is a bit mask which may include any :const:`signal.SFD_*` flag.
|
||||||
|
|
||||||
|
.. versionadded:: 2.7
|
||||||
|
|
||||||
|
|
||||||
|
.. function:: sigprocmask(how, mask)
|
||||||
|
|
||||||
|
Set the signal mask for the process. The old signal mask is returned.
|
||||||
|
Availability: Unix (See the Unix man page :manpage:`sigprocmask(2)` and
|
||||||
|
:manpage:`pthread_sigmask(2)`.)
|
||||||
|
|
||||||
|
If *how* is :const:`signal.SIG_BLOCK`, the signals in the mask are added
|
||||||
|
to the set of blocked signals.
|
||||||
|
|
||||||
|
If *how* is :const:`signal.SIG_UNBLOCK`, the signals in the mask are
|
||||||
|
removed from the set of blocked signals.
|
||||||
|
|
||||||
|
If *how* is :const:`signal.SIG_SETMASK`, the signals in the mask are set
|
||||||
|
as blocked and the signals not in the mask are set as unblocked.
|
||||||
|
|
||||||
|
*mask* is a list of signal numbers (eg :const:`signal.SIGUSR1`).
|
||||||
|
|
||||||
|
.. versionadded:: 2.7
|
||||||
|
|
||||||
|
|
||||||
.. _signal-example:
|
.. _signal-example:
|
||||||
|
|
||||||
Example
|
Example
|
||||||
|
|
|
@ -462,9 +462,210 @@ class ItimerTest(unittest.TestCase):
|
||||||
# and the handler should have been called
|
# and the handler should have been called
|
||||||
self.assertEqual(self.hndl_called, True)
|
self.assertEqual(self.hndl_called, True)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class SomeException(Exception):
|
||||||
|
"""
|
||||||
|
A unique exception class to be raised by a signal handler to verify that the
|
||||||
|
signal handler was invoked.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def raiser(*args):
|
||||||
|
"""A signal handler which raises SomeException."""
|
||||||
|
raise SomeException()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class SigprocmaskTests(unittest.TestCase):
|
||||||
|
"""Tests for sigprocmask."""
|
||||||
|
def _handle_sigusr1(self):
|
||||||
|
old_handler = signal.signal(signal.SIGUSR1, raiser)
|
||||||
|
self.addCleanup(signal.signal, signal.SIGUSR1, old_handler)
|
||||||
|
|
||||||
|
|
||||||
|
def test_signature(self):
|
||||||
|
"""When invoked with other than two arguments, sigprocmask raises
|
||||||
|
TypeError.
|
||||||
|
"""
|
||||||
|
self.assertRaises(TypeError, signal.sigprocmask)
|
||||||
|
self.assertRaises(TypeError, signal.sigprocmask, 1)
|
||||||
|
self.assertRaises(TypeError, signal.sigprocmask, 1, 2, 3)
|
||||||
|
|
||||||
|
|
||||||
|
def test_invalid_how(self):
|
||||||
|
"""If a value other than SIG_BLOCK, SIG_UNBLOCK, or SIG_SETMASK is
|
||||||
|
passed for the how argument to sigprocmask, ValueError is raised.
|
||||||
|
"""
|
||||||
|
message = "value specified for how \(1700\) invalid"
|
||||||
|
with self.assertRaisesRegexp(ValueError, message):
|
||||||
|
signal.sigprocmask(1700, [])
|
||||||
|
|
||||||
|
|
||||||
|
def test_invalid_signal_iterable(self):
|
||||||
|
"""If iterating over the value passed for the signals parameter to
|
||||||
|
sigprocmask raises an exception, sigprocmask raises that exception.
|
||||||
|
"""
|
||||||
|
class BrokenIter(object):
|
||||||
|
def __iter__(self):
|
||||||
|
raise RuntimeError("my __iter__ is broken")
|
||||||
|
with self.assertRaisesRegexp(RuntimeError, "my __iter__ is broken"):
|
||||||
|
signal.sigprocmask(signal.SIG_BLOCK, BrokenIter())
|
||||||
|
|
||||||
|
|
||||||
|
def test_invalid_signal(self):
|
||||||
|
"""If an object in the iterable passed for the signals parameter to
|
||||||
|
sigprocmask isn't an integer, TypeError is raised."""
|
||||||
|
with self.assertRaisesRegexp(TypeError, "an integer is required"):
|
||||||
|
signal.sigprocmask(signal.SIG_BLOCK, [object()])
|
||||||
|
|
||||||
|
|
||||||
|
def test_return_previous_mask(self):
|
||||||
|
"""sigprocmask returns a list of the signals previously masked.
|
||||||
|
"""
|
||||||
|
previous = signal.sigprocmask(signal.SIG_BLOCK, [1, 3, 5])
|
||||||
|
result = signal.sigprocmask(signal.SIG_BLOCK, previous)
|
||||||
|
self.assertEquals(result, [1, 3, 5])
|
||||||
|
|
||||||
|
|
||||||
|
def test_block(self):
|
||||||
|
"""When invoked with SIG_BLOCK, sigprocmask blocks the signals in the
|
||||||
|
sigmask list.
|
||||||
|
"""
|
||||||
|
self._handle_sigusr1()
|
||||||
|
previous = signal.sigprocmask(signal.SIG_BLOCK, [signal.SIGUSR1])
|
||||||
|
os.kill(os.getpid(), signal.SIGUSR1)
|
||||||
|
with self.assertRaises(SomeException):
|
||||||
|
# Expect to receive SIGUSR1 after unblocking it.
|
||||||
|
signal.sigprocmask(signal.SIG_SETMASK, previous)
|
||||||
|
|
||||||
|
|
||||||
|
def test_unblock(self):
|
||||||
|
"""When invoked with SIG_UNBLOCK, sigprocmask unblocks the signals in
|
||||||
|
the sigmask list.
|
||||||
|
"""
|
||||||
|
self._handle_sigusr1()
|
||||||
|
previous = signal.sigprocmask(signal.SIG_BLOCK, [signal.SIGUSR1])
|
||||||
|
self.addCleanup(signal.sigprocmask, signal.SIG_SETMASK, previous)
|
||||||
|
signal.sigprocmask(signal.SIG_UNBLOCK, [signal.SIGUSR1])
|
||||||
|
|
||||||
|
with self.assertRaises(SomeException):
|
||||||
|
os.kill(os.getpid(), signal.SIGUSR1)
|
||||||
|
|
||||||
|
|
||||||
|
def test_long_signals(self):
|
||||||
|
"""sigprocmask accepts signal numbers as instances of long."""
|
||||||
|
previous = signal.sigprocmask(
|
||||||
|
signal.SIG_SETMASK, [long(signal.SIGUSR1), long(signal.SIGUSR2)])
|
||||||
|
masked = signal.sigprocmask(signal.SIG_SETMASK, previous)
|
||||||
|
self.assertEquals(masked, [signal.SIGUSR1, signal.SIGUSR2])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class SignalfdTests(unittest.TestCase):
|
||||||
|
"""
|
||||||
|
Tests for signal.signalfd.
|
||||||
|
"""
|
||||||
|
def test_signature(self):
|
||||||
|
"""When invoked with fewer than two arguments or more than three,
|
||||||
|
signalfd raises TypeError.
|
||||||
|
"""
|
||||||
|
self.assertRaises(TypeError, signal.signalfd)
|
||||||
|
self.assertRaises(TypeError, signal.signalfd, 1)
|
||||||
|
self.assertRaises(TypeError, signal.signalfd, 1, 2, 3, 4)
|
||||||
|
|
||||||
|
|
||||||
|
def test_create_signalfd(self):
|
||||||
|
"""When invoked with a file descriptor of -1, signalfd allocates a new
|
||||||
|
file descriptor for signal information delivery and returns it.
|
||||||
|
"""
|
||||||
|
fd = signal.signalfd(-1, [])
|
||||||
|
self.assertTrue(isinstance(fd, int))
|
||||||
|
os.close(fd)
|
||||||
|
|
||||||
|
|
||||||
|
def test_non_iterable_signals(self):
|
||||||
|
"""If an object which is not iterable is passed for the sigmask list
|
||||||
|
argument to signalfd, the exception raised by trying to iterate over
|
||||||
|
that object is raised.
|
||||||
|
"""
|
||||||
|
self.assertRaises(TypeError, signal.signalfd, -1, object())
|
||||||
|
|
||||||
|
|
||||||
|
def test_non_integer_signals(self):
|
||||||
|
"""If any non-integer values are included in the sigmask list argument
|
||||||
|
to signalfd, the exception raised by the attempt to convert them to an
|
||||||
|
integer is raised.
|
||||||
|
"""
|
||||||
|
self.assertRaises(TypeError, signal.signalfd, -1, [object()])
|
||||||
|
|
||||||
|
|
||||||
|
def test_out_of_range_signal(self):
|
||||||
|
"""If a signal number that is out of the valid range is included in the
|
||||||
|
sigmask list argument to signalfd, ValueError is raised.
|
||||||
|
"""
|
||||||
|
message = "signal number -2 out of range"
|
||||||
|
with self.assertRaisesRegexp(ValueError, message):
|
||||||
|
signal.signalfd(-1, [-2])
|
||||||
|
|
||||||
|
|
||||||
|
def test_handle_signals(self):
|
||||||
|
"""After signalfd is called, if a signal is received which was in the
|
||||||
|
sigmask list passed to that call, information about the signal can be
|
||||||
|
read from the fd returned by that call.
|
||||||
|
"""
|
||||||
|
fd = signal.signalfd(-1, [signal.SIGUSR2])
|
||||||
|
self.addCleanup(os.close, fd)
|
||||||
|
previous = signal.sigprocmask(signal.SIG_BLOCK, [signal.SIGUSR2])
|
||||||
|
self.addCleanup(signal.sigprocmask, signal.SIG_SETMASK, previous)
|
||||||
|
os.kill(os.getpid(), signal.SIGUSR2)
|
||||||
|
bytes = os.read(fd, 128)
|
||||||
|
self.assertTrue(bytes)
|
||||||
|
|
||||||
|
|
||||||
|
def test_close_on_exec(self):
|
||||||
|
"""If the bit mask passed as the 3rd argument to signalfd includes
|
||||||
|
SFD_CLOEXEC, the returned file descriptor has FD_CLOEXEC set on it.
|
||||||
|
"""
|
||||||
|
import fcntl
|
||||||
|
fd = signal.signalfd(-1, [], signal.SFD_CLOEXEC)
|
||||||
|
self.addCleanup(os.close, fd)
|
||||||
|
flags = fcntl.fcntl(fd, fcntl.F_GETFD)
|
||||||
|
self.assertTrue(flags & fcntl.FD_CLOEXEC)
|
||||||
|
|
||||||
|
|
||||||
|
def test_nonblocking(self):
|
||||||
|
"""If the bit mask passed as the 3rd argument to signalfd includes
|
||||||
|
SFD_NOBLOCK, the file description referenced by the returned file
|
||||||
|
descriptor has O_NONBLOCK set on it.
|
||||||
|
"""
|
||||||
|
import fcntl
|
||||||
|
fd = signal.signalfd(-1, [], signal.SFD_NONBLOCK)
|
||||||
|
self.addCleanup(os.close, fd)
|
||||||
|
flags = fcntl.fcntl(fd, fcntl.F_GETFL)
|
||||||
|
self.assertTrue(flags & os.O_NONBLOCK)
|
||||||
|
|
||||||
|
|
||||||
|
def test_default_flags(self):
|
||||||
|
"""If an empty bit mask is passed as the 3rd argument to signalfd,
|
||||||
|
neither FD_CLOEXEC nor O_NONBLOCK is set on the resulting file
|
||||||
|
descriptor/description.
|
||||||
|
"""
|
||||||
|
import fcntl
|
||||||
|
fd = signal.signalfd(-1, [])
|
||||||
|
self.addCleanup(os.close, fd)
|
||||||
|
flags = fcntl.fcntl(fd, fcntl.F_GETFD)
|
||||||
|
self.assertFalse(flags & fcntl.FD_CLOEXEC)
|
||||||
|
flags = fcntl.fcntl(fd, fcntl.F_GETFL)
|
||||||
|
self.assertFalse(flags & os.O_NONBLOCK)
|
||||||
|
|
||||||
|
|
||||||
def test_main():
|
def test_main():
|
||||||
support.run_unittest(BasicSignalTests, InterProcessSignalTests,
|
support.run_unittest(
|
||||||
WakeupSignalTests, SiginterruptTest, ItimerTest)
|
BasicSignalTests, InterProcessSignalTests,
|
||||||
|
WakeupSignalTests, SiginterruptTest, ItimerTest, SignalfdTests,
|
||||||
|
SigprocmaskTests)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
@ -1025,6 +1025,11 @@ Library
|
||||||
- Issue #5949: added check for correct lineends in input from IMAP server
|
- Issue #5949: added check for correct lineends in input from IMAP server
|
||||||
in imaplib.
|
in imaplib.
|
||||||
|
|
||||||
|
- Issue #8407: The signal module gains the ``signalfd()`` and
|
||||||
|
``sigprocmask(2)`` functions providing access to the signalfd(2) and
|
||||||
|
sigprocmask(2) system calls respectively on Linux systems which implement
|
||||||
|
them.
|
||||||
|
|
||||||
- Add count() and reverse() methods to collections.deque().
|
- Add count() and reverse() methods to collections.deque().
|
||||||
|
|
||||||
- Fix variations of extending deques: d.extend(d) d.extendleft(d) d+=d
|
- Fix variations of extending deques: d.extend(d) d.extendleft(d) d+=d
|
||||||
|
|
|
@ -22,6 +22,10 @@
|
||||||
#ifdef HAVE_SYS_TIME_H
|
#ifdef HAVE_SYS_TIME_H
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_SIGNALFD
|
||||||
|
#include <sys/signalfd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifndef SIG_ERR
|
#ifndef SIG_ERR
|
||||||
#define SIG_ERR ((PyOS_sighandler_t)(-1))
|
#define SIG_ERR ((PyOS_sighandler_t)(-1))
|
||||||
|
@ -464,6 +468,144 @@ Returns current value of given itimer.");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
_iterable_to_mask(PyObject *iterable, sigset_t *mask)
|
||||||
|
{
|
||||||
|
static const char* range_format = "signal number %d out of range";
|
||||||
|
char range_buffer[1024];
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
PyObject *item, *iterator = NULL;
|
||||||
|
|
||||||
|
sigemptyset(mask);
|
||||||
|
|
||||||
|
iterator = PyObject_GetIter(iterable);
|
||||||
|
if (iterator == NULL) {
|
||||||
|
result = -1;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((item = PyIter_Next(iterator))) {
|
||||||
|
int signum = PyInt_AsLong(item);
|
||||||
|
Py_DECREF(item);
|
||||||
|
if (signum == -1 && PyErr_Occurred()) {
|
||||||
|
result = -1;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (sigaddset(mask, signum) == -1) {
|
||||||
|
PyOS_snprintf(range_buffer, sizeof(range_buffer), range_format, signum);
|
||||||
|
PyErr_SetString(PyExc_ValueError, range_buffer);
|
||||||
|
result = -1;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
error:
|
||||||
|
Py_XDECREF(iterator);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
|
||||||
|
# define PY_SIGMASK pthread_sigmask
|
||||||
|
#elif defined(HAVE_SIGPROCMASK)
|
||||||
|
# define PY_SIGMASK sigprocmask
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PY_SIGMASK
|
||||||
|
static PyObject *
|
||||||
|
signal_sigprocmask(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
static const char* how_format = "value specified for how (%d) invalid";
|
||||||
|
char how_buffer[1024];
|
||||||
|
|
||||||
|
int how, sig;
|
||||||
|
PyObject *signals, *result, *signum;
|
||||||
|
sigset_t mask, previous;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "iO:sigprocmask", &how, &signals)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_iterable_to_mask(signals, &mask) == -1) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PY_SIGMASK(how, &mask, &previous) != 0) {
|
||||||
|
PyOS_snprintf(how_buffer, sizeof(how_buffer), how_format, how);
|
||||||
|
PyErr_SetString(PyExc_ValueError, how_buffer);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = PyList_New(0);
|
||||||
|
if (result == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (sig = 1; sig < NSIG; ++sig) {
|
||||||
|
if (sigismember(&previous, sig) == 1) {
|
||||||
|
/* Handle the case where it is a member by adding the signal to
|
||||||
|
the result list. Ignore the other cases because they mean the
|
||||||
|
signal isn't a member of the mask or the signal was invalid,
|
||||||
|
and an invalid signal must have been our fault in constructing
|
||||||
|
the loop boundaries. */
|
||||||
|
signum = PyInt_FromLong(sig);
|
||||||
|
if (signum == NULL) {
|
||||||
|
Py_DECREF(result);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (PyList_Append(result, signum) == -1) {
|
||||||
|
Py_DECREF(signum);
|
||||||
|
Py_DECREF(result);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
Py_DECREF(signum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyDoc_STRVAR(sigprocmask_doc,
|
||||||
|
"sigprocmask(how, mask) -> old mask\n\
|
||||||
|
\n\
|
||||||
|
Examine and change blocked signals.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_SIGNALFD
|
||||||
|
static PyObject *
|
||||||
|
signal_signalfd(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
int result, flags = 0;
|
||||||
|
sigset_t mask;
|
||||||
|
|
||||||
|
int fd;
|
||||||
|
PyObject *signals;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "iO|i:signalfd", &fd, &signals, &flags)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_iterable_to_mask(signals, &mask) == -1) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = signalfd(-1, &mask, flags);
|
||||||
|
|
||||||
|
if (result == -1) {
|
||||||
|
PyErr_SetFromErrno(PyExc_OSError);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PyInt_FromLong(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyDoc_STRVAR(signalfd_doc,
|
||||||
|
"signalfd(fd, mask, flags)\n\
|
||||||
|
\n\
|
||||||
|
Create a file descriptor for accepting signals.");
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* List of functions defined in the module */
|
/* List of functions defined in the module */
|
||||||
static PyMethodDef signal_methods[] = {
|
static PyMethodDef signal_methods[] = {
|
||||||
#ifdef HAVE_ALARM
|
#ifdef HAVE_ALARM
|
||||||
|
@ -478,6 +620,14 @@ static PyMethodDef signal_methods[] = {
|
||||||
{"signal", signal_signal, METH_VARARGS, signal_doc},
|
{"signal", signal_signal, METH_VARARGS, signal_doc},
|
||||||
{"getsignal", signal_getsignal, METH_VARARGS, getsignal_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 PY_SIGMASK
|
||||||
|
{"sigprocmask", signal_sigprocmask, METH_VARARGS, sigprocmask_doc},
|
||||||
|
/* It's no longer needed, so clean up the namespace. */
|
||||||
|
#undef PY_SIGMASK
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SIGNALFD
|
||||||
|
{"signalfd", signal_signalfd, METH_VARARGS, signalfd_doc},
|
||||||
|
#endif
|
||||||
#ifdef HAVE_SIGINTERRUPT
|
#ifdef HAVE_SIGINTERRUPT
|
||||||
{"siginterrupt", signal_siginterrupt, METH_VARARGS, siginterrupt_doc},
|
{"siginterrupt", signal_siginterrupt, METH_VARARGS, siginterrupt_doc},
|
||||||
#endif
|
#endif
|
||||||
|
@ -811,6 +961,36 @@ PyInit_signal(void)
|
||||||
PyDict_SetItemString(d, "ItimerError", ItimerError);
|
PyDict_SetItemString(d, "ItimerError", ItimerError);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef SIG_BLOCK
|
||||||
|
x = PyLong_FromLong(SIG_BLOCK);
|
||||||
|
PyDict_SetItemString(d, "SIG_BLOCK", x);
|
||||||
|
Py_DECREF(x);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SIG_UNBLOCK
|
||||||
|
x = PyLong_FromLong(SIG_UNBLOCK);
|
||||||
|
PyDict_SetItemString(d, "SIG_UNBLOCK", x);
|
||||||
|
Py_DECREF(x);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SIG_SETMASK
|
||||||
|
x = PyLong_FromLong(SIG_SETMASK);
|
||||||
|
PyDict_SetItemString(d, "SIG_SETMASK", x);
|
||||||
|
Py_DECREF(x);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SFD_CLOEXEC
|
||||||
|
x = PyLong_FromLong(SFD_CLOEXEC);
|
||||||
|
PyDict_SetItemString(d, "SFD_CLOEXEC", x);
|
||||||
|
Py_DECREF(x);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SFD_NONBLOCK
|
||||||
|
x = PyLong_FromLong(SFD_NONBLOCK);
|
||||||
|
PyDict_SetItemString(d, "SFD_NONBLOCK", x);
|
||||||
|
Py_DECREF(x);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CTRL_C_EVENT
|
#ifdef CTRL_C_EVENT
|
||||||
x = PyLong_FromLong(CTRL_C_EVENT);
|
x = PyLong_FromLong(CTRL_C_EVENT);
|
||||||
PyDict_SetItemString(d, "CTRL_C_EVENT", x);
|
PyDict_SetItemString(d, "CTRL_C_EVENT", x);
|
||||||
|
|
2
configure
vendored
2
configure
vendored
|
@ -9297,7 +9297,7 @@ for ac_func in alarm setitimer getitimer bind_textdomain_codeset chown \
|
||||||
select sem_open sem_timedwait sem_getvalue sem_unlink setegid seteuid \
|
select sem_open sem_timedwait sem_getvalue sem_unlink setegid seteuid \
|
||||||
setgid \
|
setgid \
|
||||||
setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setuid setvbuf \
|
setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setuid setvbuf \
|
||||||
sigaction siginterrupt sigrelse snprintf strftime strlcpy \
|
sigaction siginterrupt signalfd sigprocmask sigrelse snprintf strftime strlcpy \
|
||||||
sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \
|
sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \
|
||||||
truncate uname unsetenv utimes waitpid wait3 wait4 \
|
truncate uname unsetenv utimes waitpid wait3 wait4 \
|
||||||
wcscoll wcsftime wcsxfrm _getpty
|
wcscoll wcsftime wcsxfrm _getpty
|
||||||
|
|
|
@ -2580,7 +2580,7 @@ AC_CHECK_FUNCS(alarm setitimer getitimer bind_textdomain_codeset chown \
|
||||||
select sem_open sem_timedwait sem_getvalue sem_unlink setegid seteuid \
|
select sem_open sem_timedwait sem_getvalue sem_unlink setegid seteuid \
|
||||||
setgid \
|
setgid \
|
||||||
setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setuid setvbuf \
|
setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setuid setvbuf \
|
||||||
sigaction siginterrupt sigrelse snprintf strftime strlcpy \
|
sigaction siginterrupt signalfd sigprocmask sigrelse snprintf strftime strlcpy \
|
||||||
sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \
|
sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \
|
||||||
truncate uname unsetenv utimes waitpid wait3 wait4 \
|
truncate uname unsetenv utimes waitpid wait3 wait4 \
|
||||||
wcscoll wcsftime wcsxfrm _getpty)
|
wcscoll wcsftime wcsxfrm _getpty)
|
||||||
|
|
|
@ -620,6 +620,12 @@
|
||||||
/* Define to 1 if you have the <signal.h> header file. */
|
/* Define to 1 if you have the <signal.h> header file. */
|
||||||
#undef HAVE_SIGNAL_H
|
#undef HAVE_SIGNAL_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `signalfd' function. */
|
||||||
|
#undef HAVE_SIGNALFD
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `sigprocmask' function. */
|
||||||
|
#undef HAVE_SIGPROCMASK
|
||||||
|
|
||||||
/* Define to 1 if you have the `sigrelse' function. */
|
/* Define to 1 if you have the `sigrelse' function. */
|
||||||
#undef HAVE_SIGRELSE
|
#undef HAVE_SIGRELSE
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue