diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index eaada1b504..9eb64dca4f 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -1847,58 +1847,77 @@ class PtyTests(unittest.TestCase): self.skipTest("pty.fork() raised {}".format(e)) raise + if pid != 0: + # Parent + os.close(w) + tty = open("/dev/pts/3", "a") + tty.write("\nI am parent:{} with child:{}".format(os.getpid(), pid)) + tty.write("fd:{} input:{}".format(fd, terminal_input)) + tty.close() + os.write(fd, terminal_input) + + # Get results from the pipe + with open(r, "r") as rpipe: + lines = [] + while True: + tty = open("/dev/pts/3", "a") + tty.write("\nI am parent:{} with lines:{}".format(os.getpid(), lines)) + tty.close() + line = rpipe.readline().strip() + if line == "": + # The other end was closed => the child exited + break + lines.append(line) + + # Check the result was got and corresponds to the user's terminal input + if len(lines) != 2: + # Something went wrong, try to get at stderr + # Beware of Linux raising EIO when the slave is closed + child_output = bytearray() + while True: + try: + chunk = os.read(fd, 3000) + except OSError: # Assume EIO + break + if not chunk: + break + child_output.extend(chunk) + os.close(fd) + child_output = child_output.decode("ascii", "ignore") + self.fail("got %d lines in pipe but expected 2, child output was:\n%s" + % (len(lines), child_output)) + + # Wait until the child process completes before closing the PTY to + # prevent sending SIGHUP to the child process. + tty = open("/dev/pts/3", "a") + tty.write("\nI am parent:{} starting wait_process({}, exitcode=0)".format(os.getpid(), pid)) + tty.close() + support.wait_process(pid, exitcode=0) + + # Close the PTY + os.close(fd) + if pid == 0: # Child + pid = os.getpid() # get my PID + tty = open("/dev/pts/3", "a") + tty.write("\nI am child - this is my PID:{}".format(pid)) + tty.close() try: # Make sure we don't get stuck if there's a problem - signal.alarm(2) + # signal.alarm(2) os.close(r) with open(w, "w") as wpipe: child(wpipe) except: traceback.print_exc() finally: + tty = open("/dev/pts/3", "a") + tty.write("\nI am child - exiting PID:{}".format(pid)) + tty.close() # We don't want to return to unittest... os._exit(0) - # Parent - os.close(w) - os.write(fd, terminal_input) - - # Get results from the pipe - with open(r, "r") as rpipe: - lines = [] - while True: - line = rpipe.readline().strip() - if line == "": - # The other end was closed => the child exited - break - lines.append(line) - - # Check the result was got and corresponds to the user's terminal input - if len(lines) != 2: - # Something went wrong, try to get at stderr - # Beware of Linux raising EIO when the slave is closed - child_output = bytearray() - while True: - try: - chunk = os.read(fd, 3000) - except OSError: # Assume EIO - break - if not chunk: - break - child_output.extend(chunk) - os.close(fd) - child_output = child_output.decode("ascii", "ignore") - self.fail("got %d lines in pipe but expected 2, child output was:\n%s" - % (len(lines), child_output)) - - # Wait until the child process completes before closing the PTY to - # prevent sending SIGHUP to the child process. - support.wait_process(pid, exitcode=0) - - # Close the PTY - os.close(fd) return lines