Re-read terminal modes after config.fish

Before now, we would be getting the terminal modes before config.fish,
then running config.fish without any of the term "stealing" and modes
copying. This meant that changes made to the terminal modes in there
were simply lost.

So, what we do is simply set the modes before config and then copy
them after, once.

Note that this does *not* turn off flow control again - if you turn it
on in config.fish that should work.

Fixes #7783.
This commit is contained in:
Fabian Homborg 2021-03-06 09:24:54 +01:00
parent c7c9ff9a4a
commit dbb74f87ba
3 changed files with 19 additions and 7 deletions

View file

@ -491,6 +491,9 @@ int main(int argc, char **argv) {
if (!opts.no_exec) {
read_init(parser, paths);
}
// Re-read the terminal modes after config, it might have changed them.
term_copy_modes();
// Stomp the exit status of any initialization commands (issue #635).
parser.set_last_statuses(statuses_t::just(STATUS_CMD_OK));

View file

@ -839,13 +839,15 @@ static void redirect_tty_after_sighup() {
}
/// Give up control of terminal.
static void term_donate() {
static void term_donate(bool quiet = false) {
while (true) {
if (tcsetattr(STDIN_FILENO, TCSANOW, &tty_modes_for_external_cmds) == -1) {
if (errno == EIO) redirect_tty_output();
if (errno != EINTR) {
FLOGF(warning, _(L"Could not set terminal mode for new job"));
wperror(L"tcsetattr");
if (!quiet) {
FLOGF(warning, _(L"Could not set terminal mode for new job"));
wperror(L"tcsetattr");
}
break;
}
} else
@ -853,9 +855,8 @@ static void term_donate() {
}
}
/// Grab control of terminal.
static void term_steal() {
// Copy the (potentially changed) terminal modes and use them from now on.
/// Copy the (potentially changed) terminal modes and use them from now on.
void term_copy_modes() {
struct termios modes;
tcgetattr(STDIN_FILENO, &modes);
std::memcpy(&tty_modes_for_external_cmds, &modes, sizeof tty_modes_for_external_cmds);
@ -872,8 +873,11 @@ static void term_steal() {
} else {
shell_modes.c_iflag &= ~IXOFF;
}
}
/// Grab control of terminal.
void term_steal() {
term_copy_modes();
while (true) {
if (tcsetattr(STDIN_FILENO, TCSANOW, &shell_modes) == -1) {
if (errno == EIO) redirect_tty_output();
@ -1336,6 +1340,10 @@ void reader_init() {
term_fix_modes(&shell_modes);
// Set up our fixed terminal modes once,
// so we don't get flow control just because we inherited it.
term_donate(/* quiet */ true);
// We do this not because we actually need the window size but for its side-effect of correctly
// setting the COLUMNS and LINES env vars.
termsize_container_t::shared().updating(parser);

View file

@ -141,6 +141,7 @@ void reader_sighup();
/// Initialize the reader.
void reader_init();
void term_copy_modes();
/// Restore the term mode at startup.
void restore_term_mode();