summaryrefslogtreecommitdiffstats
path: root/Modules/_posixsubprocess.c
diff options
context:
space:
mode:
authorAlexey Izbyshev <izbyshev@ispras.ru>2020-10-24 17:47:38 (GMT)
committerGitHub <noreply@github.com>2020-10-24 17:47:38 (GMT)
commit473db47747bb8bc986d88ad81799bcbd88153ac5 (patch)
tree5db1f6a73c60f506944081915d92082de9f35265 /Modules/_posixsubprocess.c
parente01e442125bbc98e6dab66f38ecc6c45f69e6587 (diff)
downloadcpython-473db47747bb8bc986d88ad81799bcbd88153ac5.zip
cpython-473db47747bb8bc986d88ad81799bcbd88153ac5.tar.gz
cpython-473db47747bb8bc986d88ad81799bcbd88153ac5.tar.bz2
bpo-35823: subprocess: Fix handling of pthread_sigmask() errors (GH-22944)
Using POSIX_CALL() is incorrect since pthread_sigmask() returns the error number instead of setting errno. Also handle failure of the first call to pthread_sigmask() in the parent process, and explain why we don't handle failure of the second call in a comment.
Diffstat (limited to 'Modules/_posixsubprocess.c')
-rw-r--r--Modules/_posixsubprocess.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c
index ed49857..b7cba30 100644
--- a/Modules/_posixsubprocess.c
+++ b/Modules/_posixsubprocess.c
@@ -581,7 +581,9 @@ child_exec(char *const exec_array[],
#ifdef VFORK_USABLE
if (child_sigmask) {
reset_signal_handlers(child_sigmask);
- POSIX_CALL(pthread_sigmask(SIG_SETMASK, child_sigmask, NULL));
+ if ((errno = pthread_sigmask(SIG_SETMASK, child_sigmask, NULL))) {
+ goto error;
+ }
}
#endif
@@ -1007,7 +1009,11 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
*/
sigset_t all_sigs;
sigfillset(&all_sigs);
- pthread_sigmask(SIG_BLOCK, &all_sigs, &old_sigs);
+ if ((saved_errno = pthread_sigmask(SIG_BLOCK, &all_sigs, &old_sigs))) {
+ errno = saved_errno;
+ PyErr_SetFromErrno(PyExc_OSError);
+ goto cleanup;
+ }
old_sigmask = &old_sigs;
}
#endif
@@ -1034,8 +1040,13 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
* Note that in environments where vfork() is implemented as fork(),
* such as QEMU user-mode emulation, the parent won't be blocked,
* but it won't share the address space with the child,
- * so it's still safe to unblock the signals. */
- pthread_sigmask(SIG_SETMASK, old_sigmask, NULL);
+ * so it's still safe to unblock the signals.
+ *
+ * We don't handle errors here because this call can't fail
+ * if valid arguments are given, and because there is no good
+ * way for the caller to deal with a failure to restore
+ * the thread signal mask. */
+ (void) pthread_sigmask(SIG_SETMASK, old_sigmask, NULL);
}
#endif