From 25a3864541dc9259a3bfd36b195cbb764f8e2d56 Mon Sep 17 00:00:00 2001 From: Barry Warsaw Date: Fri, 13 Apr 2007 18:47:14 +0000 Subject: [PATCH] Port r54805 from python25-maint branch: Add code to read from master_fd in the parent, breaking when we get an OSError (EIO can occur on Linux) or there's no more data to read. Without this, test_pty.py can hang on the waitpid() because the child is blocking on the stdout write. This will definitely happen on Mac OS X and could potentially happen on other platforms. See the comment for details. --- Lib/test/test_pty.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/Lib/test/test_pty.py b/Lib/test/test_pty.py index bfa624fdfd2..11fff3483e7 100644 --- a/Lib/test/test_pty.py +++ b/Lib/test/test_pty.py @@ -1,5 +1,6 @@ import pty import os +import sys import signal from test.test_support import verbose, TestSkipped, run_unittest import unittest @@ -120,6 +121,25 @@ class PtyTest(unittest.TestCase): os._exit(4) else: debug("Waiting for child (%d) to finish." % pid) + # In verbose mode, we have to consume the debug output from the + # child or the child will block, causing this test to hang in the + # parent's waitpid() call. The child blocks after a + # platform-dependent amount of data is written to its fd. On + # Linux 2.6, it's 4000 bytes and the child won't block, but on OS + # X even the small writes in the child above will block it. Also + # on Linux, the read() will throw an OSError (input/output error) + # when it tries to read past the end of the buffer but the child's + # already exited, so catch and discard those exceptions. It's not + # worth checking for EIO. + while True: + try: + data = os.read(master_fd, 80) + except OSError: + break + if not data: + break + sys.stdout.write(data.replace('\r\n', '\n')) + ##line = os.read(master_fd, 80) ##lines = line.replace('\r\n', '\n').split('\n') ##if False and lines != ['In child, calling os.setsid()',