Skip to content

Commit

Permalink
Only perform the SIGTOU test if we're hooked up to a tty
Browse files Browse the repository at this point in the history
Fixes Textualize#4104

Co-authored-by: Pablo Galindo <[email protected]>
  • Loading branch information
davep and pablogsal committed Feb 2, 2024
1 parent 8ae0b27 commit 8c2b5d2
Showing 1 changed file with 27 additions and 22 deletions.
49 changes: 27 additions & 22 deletions src/textual/drivers/linux_driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,28 +156,33 @@ def _stop_again(*_) -> None:
"""Signal handler that will put the application back to sleep."""
os.kill(os.getpid(), signal.SIGSTOP)

# Set up handlers to ensure that, if there's a SIGTTOU or a SIGTTIN,
# we go back to sleep.
signal.signal(signal.SIGTTOU, _stop_again)
signal.signal(signal.SIGTTIN, _stop_again)
try:
# Here we perform a NOP tcsetattr. The reason for this is that,
# if we're suspended and the user has performed a `bg` in the
# shell, we'll SIGCONT *but* we won't be allowed to do terminal
# output; so rather than get into the business of spinning up
# application mode again and then finding out, we perform a
# no-consequence change and detect the problem right away.
termios.tcsetattr(
self.fileno, termios.TCSANOW, termios.tcgetattr(self.fileno)
)
except termios.error:
# There was an error doing the tcsetattr; there is no sense in
# carrying on because we'll be doing a SIGSTOP (see above).
return
finally:
# We don't need to be hooking SIGTTOU or SIGTTIN any more.
signal.signal(signal.SIGTTOU, signal.SIG_DFL)
signal.signal(signal.SIGTTIN, signal.SIG_DFL)
# If we're working with an actual tty...
# https://github.com/Textualize/textual/issues/4104
if os.isatty(self.fileno):
# Set up handlers to ensure that, if there's a SIGTTOU or a SIGTTIN,
# we go back to sleep.
signal.signal(signal.SIGTTOU, _stop_again)
signal.signal(signal.SIGTTIN, _stop_again)
try:
# Here we perform a NOP tcsetattr. The reason for this is
# that, if we're suspended and the user has performed a `bg`
# in the shell, we'll SIGCONT *but* we won't be allowed to
# do terminal output; so rather than get into the business
# of spinning up application mode again and then finding
# out, we perform a no-consequence change and detect the
# problem right away.
termios.tcsetattr(
self.fileno, termios.TCSANOW, termios.tcgetattr(self.fileno)
)
except termios.error:
# There was an error doing the tcsetattr; there is no sense
# in carrying on because we'll be doing a SIGSTOP (see
# above).
return
finally:
# We don't need to be hooking SIGTTOU or SIGTTIN any more.
signal.signal(signal.SIGTTOU, signal.SIG_DFL)
signal.signal(signal.SIGTTIN, signal.SIG_DFL)

loop = asyncio.get_running_loop()

Expand Down

0 comments on commit 8c2b5d2

Please sign in to comment.