Skip to content

Commit 61b3484

Browse files
alpiremiss-islington
authored andcommitted
[3.7] bpo-35182: fix communicate() crash after child closes its pipes (GH-18117) (GH-18151)
When communicate() is called in a loop, it crashes when the child process has already closed any piped standard stream, but still continues to be running Co-authored-by: Andriy Maletsky <[email protected]>. (cherry picked from commit d3ae95e) Co-authored-by: Alex Rebert <[email protected]> https://bugs.python.org/issue35182 Automerge-Triggered-By: @gpshead
1 parent 0c12d70 commit 61b3484

File tree

3 files changed

+16
-2
lines changed

3 files changed

+16
-2
lines changed

Lib/subprocess.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1697,9 +1697,9 @@ def _communicate(self, input, endtime, orig_timeout):
16971697
with _PopenSelector() as selector:
16981698
if self.stdin and input:
16991699
selector.register(self.stdin, selectors.EVENT_WRITE)
1700-
if self.stdout:
1700+
if self.stdout and not self.stdout.closed:
17011701
selector.register(self.stdout, selectors.EVENT_READ)
1702-
if self.stderr:
1702+
if self.stderr and not self.stderr.closed:
17031703
selector.register(self.stderr, selectors.EVENT_READ)
17041704

17051705
while selector.get_map():

Lib/test/test_subprocess.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2848,6 +2848,17 @@ def test_stopped(self):
28482848

28492849
self.assertEqual(returncode, -3)
28502850

2851+
def test_communicate_repeated_call_after_stdout_close(self):
2852+
proc = subprocess.Popen([sys.executable, '-c',
2853+
'import os, time; os.close(1), time.sleep(2)'],
2854+
stdout=subprocess.PIPE)
2855+
while True:
2856+
try:
2857+
proc.communicate(timeout=0.1)
2858+
return
2859+
except subprocess.TimeoutExpired:
2860+
pass
2861+
28512862

28522863
@unittest.skipUnless(mswindows, "Windows specific tests")
28532864
class Win32ProcessTestCase(BaseTestCase):
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fixed :func:`Popen.communicate` subsequent call crash when the child process
2+
has already closed any piped standard stream, but still continues to be
3+
running. Patch by Andriy Maletsky.

0 commit comments

Comments
 (0)