summaryrefslogtreecommitdiff
path: root/Modules/signalmodule.c
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2018-05-08 07:48:50 +0300
committerGitHub <noreply@github.com>2018-05-08 07:48:50 +0300
commitd54cfb160c626626394e2f171d3ccfe03309f34e (patch)
tree7cadfc0541bd650485f4e8e1e9ee45252492f06e /Modules/signalmodule.c
parenta3f19c3f52ddff85dd52eaa01b77b2d50cc9af3f (diff)
downloadcpython-git-d54cfb160c626626394e2f171d3ccfe03309f34e.tar.gz
bpo-33441: Make the sigset_t converter available in other modules. (GH-6720)
* Expose the sigset_t converter via private API _Py_Sigset_Converter(). * Use Argument Clinic for parsing sigset_t in signalmodule.c. * Raise ValueError instead OverflowError for integers out of the C long range. Based on patch by Pablo Galindo Salgado.
Diffstat (limited to 'Modules/signalmodule.c')
-rw-r--r--Modules/signalmodule.c120
1 files changed, 25 insertions, 95 deletions
diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c
index 003bbb60e3..818df7d46e 100644
--- a/Modules/signalmodule.c
+++ b/Modules/signalmodule.c
@@ -59,6 +59,14 @@ module signal
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=b0301a3bde5fe9d3]*/
+/*[python input]
+
+class sigset_t_converter(CConverter):
+ type = 'sigset_t'
+ converter = '_Py_Sigset_Converter'
+
+[python start generated code]*/
+/*[python end generated code: output=da39a3ee5e6b4b0d input=b5689d14466b6823]*/
/*
NOTES ON THE INTERACTION BETWEEN SIGNALS AND THREADS
@@ -808,69 +816,6 @@ signal_getitimer_impl(PyObject *module, int which)
#endif
-#if defined(PYPTHREAD_SIGMASK) || defined(HAVE_SIGWAIT) || \
- defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT)
-/* Convert an iterable to a sigset.
- Return 0 on success, return -1 and raise an exception on error. */
-
-static int
-iterable_to_sigset(PyObject *iterable, sigset_t *mask)
-{
- int result = -1;
- PyObject *iterator, *item;
- long signum;
-
- sigemptyset(mask);
-
- iterator = PyObject_GetIter(iterable);
- if (iterator == NULL)
- goto error;
-
- while (1)
- {
- item = PyIter_Next(iterator);
- if (item == NULL) {
- if (PyErr_Occurred())
- goto error;
- else
- break;
- }
-
- signum = PyLong_AsLong(item);
- Py_DECREF(item);
- if (signum == -1 && PyErr_Occurred())
- goto error;
- if (0 < signum && signum < NSIG) {
- if (sigaddset(mask, (int)signum)) {
- if (errno != EINVAL) {
- /* Probably impossible */
- PyErr_SetFromErrno(PyExc_OSError);
- goto error;
- }
- /* For backwards compatibility, allow idioms such as
- * `range(1, NSIG)` but warn about invalid signal numbers
- */
- const char *msg =
- "invalid signal number %ld, please use valid_signals()";
- if (PyErr_WarnFormat(PyExc_RuntimeWarning, 1, msg, signum)) {
- goto error;
- }
- }
- }
- else {
- PyErr_Format(PyExc_ValueError,
- "signal number %ld out of range", signum);
- goto error;
- }
- }
- result = 0;
-
-error:
- Py_XDECREF(iterator);
- return result;
-}
-#endif
-
#if defined(PYPTHREAD_SIGMASK) || defined(HAVE_SIGPENDING)
static PyObject*
sigset_to_set(sigset_t mask)
@@ -913,23 +858,20 @@ sigset_to_set(sigset_t mask)
signal.pthread_sigmask
how: int
- mask: object
+ mask: sigset_t
/
Fetch and/or change the signal mask of the calling thread.
[clinic start generated code]*/
static PyObject *
-signal_pthread_sigmask_impl(PyObject *module, int how, PyObject *mask)
-/*[clinic end generated code: output=ff640fe092bc9181 input=f3b7d7a61b7b8283]*/
+signal_pthread_sigmask_impl(PyObject *module, int how, sigset_t mask)
+/*[clinic end generated code: output=0562c0fb192981a8 input=85bcebda442fa77f]*/
{
- sigset_t newmask, previous;
+ sigset_t previous;
int err;
- if (iterable_to_sigset(mask, &newmask))
- return NULL;
-
- err = pthread_sigmask(how, &newmask, &previous);
+ err = pthread_sigmask(how, &mask, &previous);
if (err != 0) {
errno = err;
PyErr_SetFromErrno(PyExc_OSError);
@@ -977,7 +919,7 @@ signal_sigpending_impl(PyObject *module)
/*[clinic input]
signal.sigwait
- sigset: object
+ sigset: sigset_t
/
Wait for a signal.
@@ -988,17 +930,13 @@ and returns the signal number.
[clinic start generated code]*/
static PyObject *
-signal_sigwait(PyObject *module, PyObject *sigset)
-/*[clinic end generated code: output=557173647424f6e4 input=11af2d82d83c2e94]*/
+signal_sigwait_impl(PyObject *module, sigset_t sigset)
+/*[clinic end generated code: output=f43770699d682f96 input=a6fbd47b1086d119]*/
{
- sigset_t set;
int err, signum;
- if (iterable_to_sigset(sigset, &set))
- return NULL;
-
Py_BEGIN_ALLOW_THREADS
- err = sigwait(&set, &signum);
+ err = sigwait(&sigset, &signum);
Py_END_ALLOW_THREADS
if (err) {
errno = err;
@@ -1113,7 +1051,7 @@ fill_siginfo(siginfo_t *si)
/*[clinic input]
signal.sigwaitinfo
- sigset: object
+ sigset: sigset_t
/
Wait synchronously until one of the signals in *sigset* is delivered.
@@ -1122,20 +1060,16 @@ Returns a struct_siginfo containing information about the signal.
[clinic start generated code]*/
static PyObject *
-signal_sigwaitinfo(PyObject *module, PyObject *sigset)
-/*[clinic end generated code: output=c40f27b269cd2309 input=f3779a74a991e171]*/
+signal_sigwaitinfo_impl(PyObject *module, sigset_t sigset)
+/*[clinic end generated code: output=1eb2f1fa236fdbca input=3d1a7e1f27fc664c]*/
{
- sigset_t set;
siginfo_t si;
int err;
int async_err = 0;
- if (iterable_to_sigset(sigset, &set))
- return NULL;
-
do {
Py_BEGIN_ALLOW_THREADS
- err = sigwaitinfo(&set, &si);
+ err = sigwaitinfo(&sigset, &si);
Py_END_ALLOW_THREADS
} while (err == -1
&& errno == EINTR && !(async_err = PyErr_CheckSignals()));
@@ -1152,7 +1086,7 @@ signal_sigwaitinfo(PyObject *module, PyObject *sigset)
/*[clinic input]
signal.sigtimedwait
- sigset: object
+ sigset: sigset_t
timeout as timeout_obj: object
/
@@ -1162,12 +1096,11 @@ The timeout is specified in seconds, with floating point numbers allowed.
[clinic start generated code]*/
static PyObject *
-signal_sigtimedwait_impl(PyObject *module, PyObject *sigset,
+signal_sigtimedwait_impl(PyObject *module, sigset_t sigset,
PyObject *timeout_obj)
-/*[clinic end generated code: output=f7eff31e679f4312 input=53fd4ea3e3724eb8]*/
+/*[clinic end generated code: output=59c8971e8ae18a64 input=87fd39237cf0b7ba]*/
{
struct timespec ts;
- sigset_t set;
siginfo_t si;
int res;
_PyTime_t timeout, deadline, monotonic;
@@ -1181,9 +1114,6 @@ signal_sigtimedwait_impl(PyObject *module, PyObject *sigset,
return NULL;
}
- if (iterable_to_sigset(sigset, &set))
- return NULL;
-
deadline = _PyTime_GetMonotonicClock() + timeout;
do {
@@ -1191,7 +1121,7 @@ signal_sigtimedwait_impl(PyObject *module, PyObject *sigset,
return NULL;
Py_BEGIN_ALLOW_THREADS
- res = sigtimedwait(&set, &si, &ts);
+ res = sigtimedwait(&sigset, &si, &ts);
Py_END_ALLOW_THREADS
if (res != -1)