summaryrefslogtreecommitdiff
path: root/Modules/_posixsubprocess.c
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2018-09-13 10:11:00 -0700
committerGitHub <noreply@github.com>2018-09-13 10:11:00 -0700
commitb2ff9a9f9298761985aa85aa3f42421ce6effb9e (patch)
tree73f5275d80996b9dfd45662b93f0063d0d89c0fd /Modules/_posixsubprocess.c
parent35c94c765bf46e93a0d84e39dbc6eaaba40b1f36 (diff)
downloadcpython-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.c20
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);