summaryrefslogtreecommitdiffstats
path: root/Modules/posixmodule.c
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2018-05-08 04:48:50 (GMT)
committerGitHub <noreply@github.com>2018-05-08 04:48:50 (GMT)
commitd54cfb160c626626394e2f171d3ccfe03309f34e (patch)
tree7cadfc0541bd650485f4e8e1e9ee45252492f06e /Modules/posixmodule.c
parenta3f19c3f52ddff85dd52eaa01b77b2d50cc9af3f (diff)
downloadcpython-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.c59
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