diff options
author | Alexey Izbyshev <izbyshev@ispras.ru> | 2020-10-24 17:47:38 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-24 17:47:38 (GMT) |
commit | 473db47747bb8bc986d88ad81799bcbd88153ac5 (patch) | |
tree | 5db1f6a73c60f506944081915d92082de9f35265 /Modules/_posixsubprocess.c | |
parent | e01e442125bbc98e6dab66f38ecc6c45f69e6587 (diff) | |
download | cpython-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.c | 19 |
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 |