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
This commit is contained in:
parent
1abba455d1
commit
a20b6adb5a
|
@ -0,0 +1,3 @@
|
|||
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.
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue