diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2018-05-08 04:48:50 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-05-08 04:48:50 (GMT) |
commit | d54cfb160c626626394e2f171d3ccfe03309f34e (patch) | |
tree | 7cadfc0541bd650485f4e8e1e9ee45252492f06e /Modules/posixmodule.c | |
parent | a3f19c3f52ddff85dd52eaa01b77b2d50cc9af3f (diff) | |
download | cpython-d54cfb160c626626394e2f171d3ccfe03309f34e.zip cpython-d54cfb160c626626394e2f171d3ccfe03309f34e.tar.gz cpython-d54cfb160c626626394e2f171d3ccfe03309f34e.tar.bz2 |
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/posixmodule.c')
-rw-r--r-- | Modules/posixmodule.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 4ac6e76..a9b3917 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -1267,6 +1267,65 @@ PyLong_FromPy_off_t(Py_off_t offset) #endif } +#ifdef HAVE_SIGSET_T +/* Convert an iterable of integers to a sigset. + Return 1 on success, return 0 and raise an exception on error. */ +int +_Py_Sigset_Converter(PyObject *obj, void *addr) +{ + sigset_t *mask = (sigset_t *)addr; + PyObject *iterator, *item; + long signum; + int overflow; + + if (sigemptyset(mask)) { + /* Probably only if mask == NULL. */ + PyErr_SetFromErrno(PyExc_OSError); + return 0; + } + + iterator = PyObject_GetIter(obj); + if (iterator == NULL) { + return 0; + } + + while ((item = PyIter_Next(iterator)) != NULL) { + signum = PyLong_AsLongAndOverflow(item, &overflow); + Py_DECREF(item); + if (signum <= 0 || signum >= NSIG) { + if (overflow || signum != -1 || !PyErr_Occurred()) { + PyErr_Format(PyExc_ValueError, + "signal number %ld out of range", signum); + } + goto error; + } + 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; + } + } + } + if (!PyErr_Occurred()) { + Py_DECREF(iterator); + return 1; + } + +error: + Py_DECREF(iterator); + return 0; +} +#endif /* HAVE_SIGSET_T */ + #ifdef MS_WINDOWS static int |