[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 d3ae95e1e945ed20297e1c38ba43a18b7a868ab6)

Co-authored-by: Alex Rebert <alex@forallsecure.com>





https://bugs.python.org/issue35182
diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py
index b2afd12..80acb06 100644
--- a/Lib/test/test_subprocess.py
+++ b/Lib/test/test_subprocess.py
@@ -2910,6 +2910,17 @@
 
         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):