summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorMartin Panter <vadmium+py@gmail.com>2015-11-30 02:21:41 (GMT)
committerMartin Panter <vadmium+py@gmail.com>2015-11-30 02:21:41 (GMT)
commitafdd51343cafbc02443fa6f7a2166af951a67c64 (patch)
tree785c05f8dd519863ffc6f2c6ce1908387c5249f5 /Modules
parentc7217d7c2210008ba06e9bcb2a14439a451eef71 (diff)
downloadcpython-afdd51343cafbc02443fa6f7a2166af951a67c64.zip
cpython-afdd51343cafbc02443fa6f7a2166af951a67c64.tar.gz
cpython-afdd51343cafbc02443fa6f7a2166af951a67c64.tar.bz2
Issue #25764: Preserve subprocess fork exception when preexec_fn used
Also fix handling of failure to release the import lock.
Diffstat (limited to 'Modules')
-rw-r--r--Modules/_posixsubprocess.c35
1 files changed, 18 insertions, 17 deletions
diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c
index 452d592..1490223 100644
--- a/Modules/_posixsubprocess.c
+++ b/Modules/_posixsubprocess.c
@@ -47,17 +47,25 @@
#define POSIX_CALL(call) do { if ((call) == -1) goto error; } while (0)
-/* Given the gc module call gc.enable() and return 0 on success. */
+/* If gc was disabled, call gc.enable(). Return 0 on success. */
static int
-_enable_gc(PyObject *gc_module)
+_enable_gc(int need_to_reenable_gc, PyObject *gc_module)
{
PyObject *result;
_Py_IDENTIFIER(enable);
+ PyObject *exctype, *val, *tb;
- result = _PyObject_CallMethodId(gc_module, &PyId_enable, NULL);
- if (result == NULL)
- return 1;
- Py_DECREF(result);
+ if (need_to_reenable_gc) {
+ PyErr_Fetch(&exctype, &val, &tb);
+ result = _PyObject_CallMethodId(gc_module, &PyId_enable, NULL);
+ if (exctype != NULL) {
+ PyErr_Restore(exctype, val, tb);
+ }
+ if (result == NULL) {
+ return 1;
+ }
+ Py_DECREF(result);
+ }
return 0;
}
@@ -691,6 +699,7 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
_PyImport_ReleaseLock() < 0 && !PyErr_Occurred()) {
PyErr_SetString(PyExc_RuntimeError,
"not holding the import lock");
+ pid = -1;
}
import_lock_held = 0;
@@ -702,9 +711,8 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
_Py_FreeCharPArray(exec_array);
/* Reenable gc in the parent process (or if fork failed). */
- if (need_to_reenable_gc && _enable_gc(gc_module)) {
- Py_XDECREF(gc_module);
- return NULL;
+ if (_enable_gc(need_to_reenable_gc, gc_module)) {
+ pid = -1;
}
Py_XDECREF(preexec_fn_args_tuple);
Py_XDECREF(gc_module);
@@ -726,14 +734,7 @@ cleanup:
Py_XDECREF(converted_args);
Py_XDECREF(fast_args);
Py_XDECREF(preexec_fn_args_tuple);
-
- /* Reenable gc if it was disabled. */
- if (need_to_reenable_gc) {
- PyObject *exctype, *val, *tb;
- PyErr_Fetch(&exctype, &val, &tb);
- _enable_gc(gc_module);
- PyErr_Restore(exctype, val, tb);
- }
+ _enable_gc(need_to_reenable_gc, gc_module);
Py_XDECREF(gc_module);
return NULL;
}