FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Issue #25764: Merge subprocess fix from 3.4 into 3.5 · python/cpython@6a77c2d · GitHub

Repository navigation

Commit 6a77c2d

Browse files
committed
Issue #25764: Merge subprocess fix from 3.4 into 3.5
2 parents ccddbb1 + afdd513 commit 6a77c2d

3 files changed

Lines changed: 37 additions & 17 deletions

File tree

‎Lib/test/test_subprocess.py‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1512,6 +1512,22 @@ def raise_runtime_error():
15121512
if not enabled:
15131513
gc.disable()
15141514

1515+
def test_preexec_fork_failure(self):
1516+
# The internal code did not preserve the previous exception when
1517+
# re-enabling garbage collection
1518+
try:
1519+
from resource import getrlimit, setrlimit, RLIMIT_NPROC
1520+
except ImportError as err:
1521+
self.skipTest(err) # RLIMIT_NPROC is specific to Linux and BSD
1522+
limits = getrlimit(RLIMIT_NPROC)
1523+
[_, hard] = limits
1524+
setrlimit(RLIMIT_NPROC, (0, hard))
1525+
self.addCleanup(setrlimit, RLIMIT_NPROC, limits)
1526+
# Forking should raise EAGAIN, translated to BlockingIOError
1527+
with self.assertRaises(BlockingIOError):
1528+
subprocess.call([sys.executable, '-c', ''],
1529+
preexec_fn=lambda: None)
1530+
15151531
def test_args_string(self):
15161532
# args is a string
15171533
fd, fname = tempfile.mkstemp()

‎Misc/NEWS‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ Core and Builtins
2222
Library
2323
-------
2424

25+
- Issue #25764: In the subprocess module, preserve any exception caused by
26+
fork() failure when preexec_fn is used.
27+
2528
- Issue #6478: _strptime's regexp cache now is reset after changing timezone
2629
with time.tzset().
2730

‎Modules/_posixsubprocess.c‎

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -47,17 +47,25 @@
4747
#define POSIX_CALL(call) do { if ((call) == -1) goto error; } while (0)
4848

4949

50-
/* Given the gc module call gc.enable() and return 0 on success. */
50+
/* If gc was disabled, call gc.enable(). Return 0 on success. */
5151
static int
52-
_enable_gc(PyObject *gc_module)
52+
_enable_gc(int need_to_reenable_gc, PyObject *gc_module)
5353
{
5454
PyObject *result;
5555
_Py_IDENTIFIER(enable);
56+
PyObject *exctype, *val, *tb;
5657

57-
result = _PyObject_CallMethodId(gc_module, &PyId_enable, NULL);
58-
if (result == NULL)
59-
return 1;
60-
Py_DECREF(result);
58+
if (need_to_reenable_gc) {
59+
PyErr_Fetch(&exctype, &val, &tb);
60+
result = _PyObject_CallMethodId(gc_module, &PyId_enable, NULL);
61+
if (exctype != NULL) {
62+
PyErr_Restore(exctype, val, tb);
63+
}
64+
if (result == NULL) {
65+
return 1;
66+
}
67+
Py_DECREF(result);
68+
}
6169
return 0;
6270
}
6371

@@ -698,6 +706,7 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
698706
&& _PyImport_ReleaseLock() < 0 && !PyErr_Occurred()) {
699707
PyErr_SetString(PyExc_RuntimeError,
700708
"not holding the import lock");
709+
pid = -1;
701710
}
702711
import_lock_held = 0;
703712
#endif
@@ -710,9 +719,8 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
710719
_Py_FreeCharPArray(exec_array);
711720

712721
/* Reenable gc in the parent process (or if fork failed). */
713-
if (need_to_reenable_gc && _enable_gc(gc_module)) {
714-
Py_XDECREF(gc_module);
715-
return NULL;
722+
if (_enable_gc(need_to_reenable_gc, gc_module)) {
723+
pid = -1;
716724
}
717725
Py_XDECREF(preexec_fn_args_tuple);
718726
Py_XDECREF(gc_module);
@@ -736,14 +744,7 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
736744
Py_XDECREF(converted_args);
737745
Py_XDECREF(fast_args);
738746
Py_XDECREF(preexec_fn_args_tuple);
739-
740-
/* Reenable gc if it was disabled. */
741-
if (need_to_reenable_gc) {
742-
PyObject *exctype, *val, *tb;
743-
PyErr_Fetch(&exctype, &val, &tb);
744-
_enable_gc(gc_module);
745-
PyErr_Restore(exctype, val, tb);
746-
}
747+
_enable_gc(need_to_reenable_gc, gc_module);
747748
Py_XDECREF(gc_module);
748749
return NULL;
749750
}

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL