bpo-40140: test_builtin.PtyTests registers SIGHUP handler (GH-19314) (GH-19316) (GH-19318)

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 7a51a7e19f)
(cherry picked from commit 745bd91bab)
This commit is contained in:
Victor Stinner 2020-04-03 14:09:02 +02:00 committed by GitHub
parent 00c779fd9c
commit 0961dbdea2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 20 additions and 3 deletions

View File

@ -1639,7 +1639,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()
@ -1690,6 +1704,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

View 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