diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index eaada1b5043..290ba2cad8e 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -1837,7 +1837,21 @@ class PtyTests(unittest.TestCase): """Tests that use a pseudo terminal to guarantee stdin and stdout are terminals in the test environment""" + @staticmethod + def handle_sighup(signum, frame): + # bpo-40140: if the process is the session leader, os.close(fd) + # of "pid, fd = pty.fork()" can raise SIGHUP signal: + # just ignore the signal. + pass + def run_child(self, child, terminal_input): + old_sighup = signal.signal(signal.SIGHUP, self.handle_sighup) + try: + return self._run_child(child, terminal_input) + finally: + signal.signal(signal.SIGHUP, old_sighup) + + def _run_child(self, child, terminal_input): r, w = os.pipe() # Pipe test results from child back to parent try: pid, fd = pty.fork() @@ -1893,13 +1907,12 @@ class PtyTests(unittest.TestCase): 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 + # bpo-40155: Close the PTY before waiting for the child process + # completion, otherwise the child process hangs on AIX. os.close(fd) + support.wait_process(pid, exitcode=0) + return lines def check_input_tty(self, prompt, terminal_input, stdio_encoding=None): diff --git a/Lib/test/test_pty.py b/Lib/test/test_pty.py index aa5c68790f7..9c32467cbbd 100644 --- a/Lib/test/test_pty.py +++ b/Lib/test/test_pty.py @@ -70,7 +70,7 @@ class PtyTest(unittest.TestCase): self.addCleanup(signal.signal, signal.SIGALRM, old_alarm) old_sighup = signal.signal(signal.SIGHUP, self.handle_sighup) - self.addCleanup(signal.signal, signal.SIGHUP, old_alarm) + self.addCleanup(signal.signal, signal.SIGHUP, old_sighup) # isatty() and close() can hang on some platforms. Set an alarm # before running the test to make sure we don't hang forever. @@ -81,8 +81,8 @@ class PtyTest(unittest.TestCase): self.fail("isatty hung") @staticmethod - def handle_sighup(sig, frame): - # if the process is the session leader, os.close(master_fd) + def handle_sighup(signum, frame): + # bpo-38547: if the process is the session leader, os.close(master_fd) # of "master_fd, slave_name = pty.master_open()" raises SIGHUP # signal: just ignore the signal. pass