]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-40140: test_builtin.PtyTests registers SIGHUP handler (GH-19314) (GH-19316)
authorVictor Stinner <vstinner@python.org>
Fri, 3 Apr 2020 00:11:54 +0000 (02:11 +0200)
committerGitHub <noreply@github.com>
Fri, 3 Apr 2020 00:11:54 +0000 (02:11 +0200)
test_builtin.PtyTests now registers an handler for SIGHUP signal.
Closing the PTY file descriptor can emit a SIGHUP signal: just ignore
it.

run_child() now also closes the PTY file descriptor before waiting
for the process completition, otherwise the test hangs on AIX.

(cherry picked from commit 7a51a7e19f0143f75f8fc9ff68f93ed40937aec6)

Lib/test/test_builtin.py
Lib/test/test_pty.py

index f680e02fdf52044e831d97018c5e9c8b8991e338..48b0e33af59edce2bd4a4024d9425f1d7e21292d 100644 (file)
@@ -1790,7 +1790,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()
@@ -1841,6 +1855,9 @@ class PtyTests(unittest.TestCase):
             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))
+
+        # bpo-40155: Close the PTY before waiting for the child process
+        # completion, otherwise the child process hangs on AIX.
         os.close(fd)
 
         # Wait until the child process completes
index ce85f575a0830816749358ca857943928d4cb32d..dfb3a3fc32644a5aa9cc2eb26cf326e084919a59 100644 (file)
@@ -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