diff options
Diffstat (limited to 'test/fs.py')
| -rw-r--r-- | test/fs.py | 42 |
1 files changed, 42 insertions, 0 deletions
@@ -4,6 +4,7 @@ import fcntl import json import os import shutil +import select import signal from pathlib import Path import subprocess @@ -1329,6 +1330,47 @@ def test(binary, quic=False): assert orphan.poll() is None assert orphan.wait(timeout=5) == 1 + # Killed with SIGTERM or SIGHUP, a tty editor puts its terminal + # back (main screen, cooked mode) before it dies: a nested one + # killed in a pane leaves that pane usable. + for sig in (signal.SIGTERM, signal.SIGHUP): + master, slave = os.openpty() + fcntl.ioctl(slave, termios.TIOCSWINSZ, struct.pack('HHHH', 24, 80, 0, 0)) + cooked = termios.tcgetattr(slave) + env = {k: v for k, v in os.environ.items() if not k.startswith('PARDES_')} + env.update(HOME=str(root), XDG_RUNTIME_DIR=str(root), TERM='xterm-256color', PARDES_NOTIME='1') + killed = subprocess.Popen([binary, '--tty', '--9p=killed', 'x.txt'], cwd=root, env=env, + stdin=slave, stdout=slave, stderr=subprocess.DEVNULL, + start_new_session=True, + preexec_fn=lambda: fcntl.ioctl(0, termios.TIOCSCTTY, 0)) + seen = b'' + try: + deadline = time.monotonic() + 10 + while b'\x1b[?1049h' not in seen: + assert time.monotonic() < deadline, seen[-200:] + if select.select([master], [], [], .1)[0]: + seen += os.read(master, 65536) + time.sleep(.3) + killed.send_signal(sig) + assert killed.wait(timeout=5) == -sig + while select.select([master], [], [], .2)[0]: + try: + chunk = os.read(master, 65536) + except OSError: + break + if not chunk: + break + seen += chunk + tail = seen[seen.rindex(b'\x1b[?1049h'):] + assert b'\x1b[?1049l' in tail, tail[-200:] + assert termios.tcgetattr(slave)[3] & termios.ICANON == cooked[3] & termios.ICANON + finally: + if killed.poll() is None: + killed.kill() + killed.wait() + os.close(master) + os.close(slave) + # A launch with no terminal to draw on (a pty that is no one's # controlling terminal) says so and exits 1, no error trace. master, slave = os.openpty() |
