Fixes issue #15798: subprocess.Popen() no longer fails if file
descriptor 0, 1 or 2 is closed. (correct fix for 3.4 this time)
This commit is contained in:
parent
5a63aa62ca
commit
53dd8167ff
|
@ -1341,6 +1341,13 @@ class Popen(object):
|
||||||
# Data format: "exception name:hex errno:description"
|
# Data format: "exception name:hex errno:description"
|
||||||
# Pickle is not used; it is complex and involves memory allocation.
|
# Pickle is not used; it is complex and involves memory allocation.
|
||||||
errpipe_read, errpipe_write = os.pipe()
|
errpipe_read, errpipe_write = os.pipe()
|
||||||
|
# errpipe_write must not be in the standard io 0, 1, or 2 fd range.
|
||||||
|
low_fds_to_close = []
|
||||||
|
while errpipe_write < 3:
|
||||||
|
low_fds_to_close.append(errpipe_write)
|
||||||
|
errpipe_write = os.dup(errpipe_write)
|
||||||
|
for low_fd in low_fds_to_close:
|
||||||
|
os.close(low_fd)
|
||||||
try:
|
try:
|
||||||
try:
|
try:
|
||||||
# We must avoid complex work that could involve
|
# We must avoid complex work that could involve
|
||||||
|
|
|
@ -1559,6 +1559,27 @@ class POSIXProcessTestCase(BaseTestCase):
|
||||||
# all standard fds closed.
|
# all standard fds closed.
|
||||||
self.check_close_std_fds([0, 1, 2])
|
self.check_close_std_fds([0, 1, 2])
|
||||||
|
|
||||||
|
def test_small_errpipe_write_fd(self):
|
||||||
|
"""Issue #15798: Popen should work when stdio fds are available."""
|
||||||
|
new_stdin = os.dup(0)
|
||||||
|
new_stdout = os.dup(1)
|
||||||
|
try:
|
||||||
|
os.close(0)
|
||||||
|
os.close(1)
|
||||||
|
|
||||||
|
# Side test: if errpipe_write fails to have its CLOEXEC
|
||||||
|
# flag set this should cause the parent to think the exec
|
||||||
|
# failed. Extremely unlikely: everyone supports CLOEXEC.
|
||||||
|
subprocess.Popen([
|
||||||
|
sys.executable, "-c",
|
||||||
|
"print('AssertionError:0:CLOEXEC failure.')"]).wait()
|
||||||
|
finally:
|
||||||
|
# Restore original stdin and stdout
|
||||||
|
os.dup2(new_stdin, 0)
|
||||||
|
os.dup2(new_stdout, 1)
|
||||||
|
os.close(new_stdin)
|
||||||
|
os.close(new_stdout)
|
||||||
|
|
||||||
def test_remapping_std_fds(self):
|
def test_remapping_std_fds(self):
|
||||||
# open up some temporary files
|
# open up some temporary files
|
||||||
temps = [mkstemp() for i in range(3)]
|
temps = [mkstemp() for i in range(3)]
|
||||||
|
|
|
@ -18,6 +18,9 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #15798: Fixed subprocess.Popen() to no longer fail if file
|
||||||
|
descriptor 0, 1 or 2 is closed.
|
||||||
|
|
||||||
- Issue #17897: Optimized unpickle prefetching.
|
- Issue #17897: Optimized unpickle prefetching.
|
||||||
|
|
||||||
- Issue #3693: Make the error message more helpful when the array.array()
|
- Issue #3693: Make the error message more helpful when the array.array()
|
||||||
|
|
Loading…
Reference in New Issue