mirror of
https://github.com/python/cpython.git
synced 2024-11-24 02:15:30 +08:00
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.
This commit is contained in:
parent
3c3aa4516c
commit
7a51a7e19f
@ -1837,7 +1837,21 @@ class PtyTests(unittest.TestCase):
|
|||||||
"""Tests that use a pseudo terminal to guarantee stdin and stdout are
|
"""Tests that use a pseudo terminal to guarantee stdin and stdout are
|
||||||
terminals in the test environment"""
|
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):
|
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
|
r, w = os.pipe() # Pipe test results from child back to parent
|
||||||
try:
|
try:
|
||||||
pid, fd = pty.fork()
|
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"
|
self.fail("got %d lines in pipe but expected 2, child output was:\n%s"
|
||||||
% (len(lines), child_output))
|
% (len(lines), child_output))
|
||||||
|
|
||||||
# Wait until the child process completes before closing the PTY to
|
# bpo-40155: Close the PTY before waiting for the child process
|
||||||
# prevent sending SIGHUP to the child process.
|
# completion, otherwise the child process hangs on AIX.
|
||||||
support.wait_process(pid, exitcode=0)
|
|
||||||
|
|
||||||
# Close the PTY
|
|
||||||
os.close(fd)
|
os.close(fd)
|
||||||
|
|
||||||
|
support.wait_process(pid, exitcode=0)
|
||||||
|
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
def check_input_tty(self, prompt, terminal_input, stdio_encoding=None):
|
def check_input_tty(self, prompt, terminal_input, stdio_encoding=None):
|
||||||
|
@ -70,7 +70,7 @@ class PtyTest(unittest.TestCase):
|
|||||||
self.addCleanup(signal.signal, signal.SIGALRM, old_alarm)
|
self.addCleanup(signal.signal, signal.SIGALRM, old_alarm)
|
||||||
|
|
||||||
old_sighup = signal.signal(signal.SIGHUP, self.handle_sighup)
|
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
|
# isatty() and close() can hang on some platforms. Set an alarm
|
||||||
# before running the test to make sure we don't hang forever.
|
# before running the test to make sure we don't hang forever.
|
||||||
@ -81,8 +81,8 @@ class PtyTest(unittest.TestCase):
|
|||||||
self.fail("isatty hung")
|
self.fail("isatty hung")
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def handle_sighup(sig, frame):
|
def handle_sighup(signum, frame):
|
||||||
# if the process is the session leader, os.close(master_fd)
|
# bpo-38547: if the process is the session leader, os.close(master_fd)
|
||||||
# of "master_fd, slave_name = pty.master_open()" raises SIGHUP
|
# of "master_fd, slave_name = pty.master_open()" raises SIGHUP
|
||||||
# signal: just ignore the signal.
|
# signal: just ignore the signal.
|
||||||
pass
|
pass
|
||||||
|
Loading…
Reference in New Issue
Block a user