Skip to content

Commit 7a51a7e

Browse files
authored
bpo-40140: test_builtin.PtyTests registers SIGHUP handler (GH-19314)
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.
1 parent 3c3aa45 commit 7a51a7e

File tree

2 files changed

+21
-8
lines changed

2 files changed

+21
-8
lines changed

Lib/test/test_builtin.py

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1837,7 +1837,21 @@ class PtyTests(unittest.TestCase):
18371837
"""Tests that use a pseudo terminal to guarantee stdin and stdout are
18381838
terminals in the test environment"""
18391839

1840+
@staticmethod
1841+
def handle_sighup(signum, frame):
1842+
# bpo-40140: if the process is the session leader, os.close(fd)
1843+
# of "pid, fd = pty.fork()" can raise SIGHUP signal:
1844+
# just ignore the signal.
1845+
pass
1846+
18401847
def run_child(self, child, terminal_input):
1848+
old_sighup = signal.signal(signal.SIGHUP, self.handle_sighup)
1849+
try:
1850+
return self._run_child(child, terminal_input)
1851+
finally:
1852+
signal.signal(signal.SIGHUP, old_sighup)
1853+
1854+
def _run_child(self, child, terminal_input):
18411855
r, w = os.pipe() # Pipe test results from child back to parent
18421856
try:
18431857
pid, fd = pty.fork()
@@ -1893,13 +1907,12 @@ def run_child(self, child, terminal_input):
18931907
self.fail("got %d lines in pipe but expected 2, child output was:\n%s"
18941908
% (len(lines), child_output))
18951909

1896-
# Wait until the child process completes before closing the PTY to
1897-
# prevent sending SIGHUP to the child process.
1898-
support.wait_process(pid, exitcode=0)
1899-
1900-
# Close the PTY
1910+
# bpo-40155: Close the PTY before waiting for the child process
1911+
# completion, otherwise the child process hangs on AIX.
19011912
os.close(fd)
19021913

1914+
support.wait_process(pid, exitcode=0)
1915+
19031916
return lines
19041917

19051918
def check_input_tty(self, prompt, terminal_input, stdio_encoding=None):

Lib/test/test_pty.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ def setUp(self):
7070
self.addCleanup(signal.signal, signal.SIGALRM, old_alarm)
7171

7272
old_sighup = signal.signal(signal.SIGHUP, self.handle_sighup)
73-
self.addCleanup(signal.signal, signal.SIGHUP, old_alarm)
73+
self.addCleanup(signal.signal, signal.SIGHUP, old_sighup)
7474

7575
# isatty() and close() can hang on some platforms. Set an alarm
7676
# before running the test to make sure we don't hang forever.
@@ -81,8 +81,8 @@ def handle_sig(self, sig, frame):
8181
self.fail("isatty hung")
8282

8383
@staticmethod
84-
def handle_sighup(sig, frame):
85-
# if the process is the session leader, os.close(master_fd)
84+
def handle_sighup(signum, frame):
85+
# bpo-38547: if the process is the session leader, os.close(master_fd)
8686
# of "master_fd, slave_name = pty.master_open()" raises SIGHUP
8787
# signal: just ignore the signal.
8888
pass

0 commit comments

Comments
 (0)