Skip to content

Commit d51f2b8

Browse files
committed
Fix ppaged crash on SIGKILL of pager
Ensure terminal settings and foreground process group are restored after the pager process exits. This prevents 'termios.error' crashes in prompt_toolkit when the pager is killed abnormally (e.g. SIGKILL), which can leave the terminal in an inconsistent state.
1 parent bb0d112 commit d51f2b8

File tree

1 file changed

+23
-0
lines changed

1 file changed

+23
-0
lines changed

cmd2/cmd2.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1611,6 +1611,29 @@ def ppaged(
16111611
)
16121612
pipe_proc.communicate(output_bytes)
16131613

1614+
# If the pager was killed (e.g. SIGKILL), the terminal might be in a bad state.
1615+
# Attempt to restore terminal settings and foreground process group.
1616+
if self.stdin.isatty():
1617+
try:
1618+
import signal
1619+
import termios
1620+
1621+
# Ensure we are in the foreground process group
1622+
if hasattr(os, 'tcsetpgrp') and hasattr(os, 'getpgrp'):
1623+
# Ignore SIGTTOU to avoid getting stopped when calling tcsetpgrp from background
1624+
old_handler = signal.signal(signal.SIGTTOU, signal.SIG_IGN)
1625+
try:
1626+
os.tcsetpgrp(self.stdin.fileno(), os.getpgrp())
1627+
finally:
1628+
signal.signal(signal.SIGTTOU, old_handler)
1629+
1630+
# Restore terminal attributes
1631+
if self._initial_termios_settings is not None:
1632+
termios.tcsetattr(self.stdin.fileno(), termios.TCSANOW, self._initial_termios_settings)
1633+
1634+
except (ImportError, OSError, termios.error):
1635+
pass
1636+
16141637
else:
16151638
self.poutput(
16161639
*objects,

0 commit comments

Comments
 (0)