Claim the tty unconditionally in reader_data_t::readline

When fish runs with job control enabled, it transfers ownership of the
tty to a child process, and then reclaims the tty after the process
exits. If job control is disabled then fish does not transfer or reclaim
the tty.

It may happen that the child process creates a pgroup and then transfers
the tty to it. In that case fish will not attempt to reclaim the tty, as
fish did not transfer it. Then when fish reads from stdin it will
receive SIGTTIN instead of data.

Fix this by unconditionally claiming the tty in readline().

Fixes #9181
This commit is contained in:
ridiculousfish
2022-09-08 16:47:43 -07:00
parent 331bb9024b
commit 5cf0778207
4 changed files with 41 additions and 0 deletions

View File

@@ -4278,6 +4278,11 @@ maybe_t<wcstring> reader_data_t::readline(int nchars_or_0) {
history_search.reset();
// It may happen that a command we ran when job control was disabled nevertheless stole the tty
// from us. In that case when we read from our fd, it will trigger SIGTTIN. So just
// unconditionally reclaim the tty. See #9181.
(void)tcsetpgrp(conf.in, getpgrp());
// Get the current terminal modes. These will be restored when the function returns.
struct termios old_modes {};
if (tcgetattr(conf.in, &old_modes) == -1 && errno == EIO) redirect_tty_output();