diff options
| author | Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | 2018-09-13 10:11:00 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-09-13 10:11:00 -0700 |
| commit | b2ff9a9f9298761985aa85aa3f42421ce6effb9e (patch) | |
| tree | 73f5275d80996b9dfd45662b93f0063d0d89c0fd /Modules/_posixsubprocess.c | |
| parent | 35c94c765bf46e93a0d84e39dbc6eaaba40b1f36 (diff) | |
| download | cpython-git-b2ff9a9f9298761985aa85aa3f42421ce6effb9e.tar.gz | |
bpo-34658: Fix rare subprocess prexec_fn fork error. (GH-9255)
[bpo-34658](https://www.bugs.python.org/issue34658): Fix a rare interpreter unhandled exception state SystemError only
seen when using subprocess with a preexec_fn while an after_parent handler has
been registered with os.register_at_fork and the fork system call fails.
https://bugs.python.org/issue34658
(cherry picked from commit a20b6adb5a5880fd22c099961eb9f9787739cefe)
Co-authored-by: Gregory P. Smith <greg@krypto.org>
Diffstat (limited to 'Modules/_posixsubprocess.c')
| -rw-r--r-- | Modules/_posixsubprocess.c | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c index aeb10f9ecf..dd69b9eb1f 100644 --- a/Modules/_posixsubprocess.c +++ b/Modules/_posixsubprocess.c @@ -564,6 +564,7 @@ subprocess_fork_exec(PyObject* self, PyObject *args) char *const *exec_array, *const *argv = NULL, *const *envp = NULL; Py_ssize_t arg_num; int need_after_fork = 0; + int saved_errno = 0; if (!PyArg_ParseTuple( args, "OOpO!OOiiiiiiiiiiO:fork_exec", @@ -700,14 +701,14 @@ subprocess_fork_exec(PyObject* self, PyObject *args) _exit(255); return NULL; /* Dead code to avoid a potential compiler warning. */ } - Py_XDECREF(cwd_obj2); - + /* Parent (original) process */ if (pid == -1) { - /* Capture the errno exception before errno can be clobbered. */ - PyErr_SetFromErrno(PyExc_OSError); + /* Capture errno for the exception. */ + saved_errno = errno; } - /* Parent process */ + Py_XDECREF(cwd_obj2); + if (need_after_fork) PyOS_AfterFork_Parent(); if (envp) @@ -723,8 +724,13 @@ subprocess_fork_exec(PyObject* self, PyObject *args) Py_XDECREF(preexec_fn_args_tuple); Py_XDECREF(gc_module); - if (pid == -1) - return NULL; /* fork() failed. Exception set earlier. */ + if (pid == -1) { + errno = saved_errno; + /* We can't call this above as PyOS_AfterFork_Parent() calls back + * into Python code which would see the unreturned error. */ + PyErr_SetFromErrno(PyExc_OSError); + return NULL; /* fork() failed. */ + } return PyLong_FromPid(pid); |
