[3.8] bpo-35182: fix communicate() crash after child closes its pipes (GH-18117) (GH-18148)
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 <andriy.maletsky@gmail.com>.
(cherry picked from commit d3ae95e1e9
)
Co-authored-by: Alex Rebert <alex@forallsecure.com>
https://bugs.python.org/issue35182
This commit is contained in:
parent
5a2356be1a
commit
5654f83b97
|
@ -1848,9 +1848,9 @@ class Popen(object):
|
|||
with _PopenSelector() as selector:
|
||||
if self.stdin and input:
|
||||
selector.register(self.stdin, selectors.EVENT_WRITE)
|
||||
if self.stdout:
|
||||
if self.stdout and not self.stdout.closed:
|
||||
selector.register(self.stdout, selectors.EVENT_READ)
|
||||
if self.stderr:
|
||||
if self.stderr and not self.stderr.closed:
|
||||
selector.register(self.stderr, selectors.EVENT_READ)
|
||||
|
||||
while selector.get_map():
|
||||
|
|
|
@ -2910,6 +2910,17 @@ class POSIXProcessTestCase(BaseTestCase):
|
|||
|
||||
self.assertEqual(returncode, -3)
|
||||
|
||||
def test_communicate_repeated_call_after_stdout_close(self):
|
||||
proc = subprocess.Popen([sys.executable, '-c',
|
||||
'import os, time; os.close(1), time.sleep(2)'],
|
||||
stdout=subprocess.PIPE)
|
||||
while True:
|
||||
try:
|
||||
proc.communicate(timeout=0.1)
|
||||
return
|
||||
except subprocess.TimeoutExpired:
|
||||
pass
|
||||
|
||||
|
||||
@unittest.skipUnless(mswindows, "Windows specific tests")
|
||||
class Win32ProcessTestCase(BaseTestCase):
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
Fixed :func:`Popen.communicate` subsequent call crash when the child process
|
||||
has already closed any piped standard stream, but still continues to be
|
||||
running. Patch by Andriy Maletsky.
|
Loading…
Reference in New Issue