From 2be720b6cc2a2049d6c697d5ed786db50768c1c6 Mon Sep 17 00:00:00 2001 From: Fabian Homborg Date: Thu, 11 Feb 2021 18:32:45 +0100 Subject: [PATCH] Set flow control settings also in the shell Since, unlike e.g. OPOST, this can sometimes be useful, just copy whatever flow control settings the terminal ends up with. We still *default* flow control to off (because it's an awful default and allows us to bind ctrl-s), but if the user decides to enable it so be it. Note that it's _possible_ flow control ends up enabled accidentally, I doubt this happens much and it won't render the shell unusable (and good terminals might even tell you you've stopped the app). Fixes #7704 --- src/reader.cpp | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/reader.cpp b/src/reader.cpp index e85c53306..48ea568a2 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -777,10 +777,6 @@ static void term_fix_modes(struct termios *modes) { modes->c_oflag |= ONLCR; // "translate newline to carriage return-newline" - without // you see staircase output. - // Disable flow control in the shell. We don't want to be stopped. - modes->c_iflag &= ~IXON; - modes->c_iflag &= ~IXOFF; - modes->c_cc[VMIN] = 1; modes->c_cc[VTIME] = 0; @@ -865,6 +861,19 @@ static void term_steal() { std::memcpy(&tty_modes_for_external_cmds, &modes, sizeof tty_modes_for_external_cmds); term_fix_external_modes(&tty_modes_for_external_cmds); + // Copy flow control settings to shell modes. + if (tty_modes_for_external_cmds.c_iflag & IXON) { + shell_modes.c_iflag |= IXON; + } else { + shell_modes.c_iflag &= ~IXON; + } + if (tty_modes_for_external_cmds.c_iflag & IXOFF) { + shell_modes.c_iflag |= IXOFF; + } else { + shell_modes.c_iflag &= ~IXOFF; + } + + while (true) { if (tcsetattr(STDIN_FILENO, TCSANOW, &shell_modes) == -1) { if (errno == EIO) redirect_tty_output(); @@ -1314,12 +1323,13 @@ void reader_init() { // Save the initial terminal mode. tcgetattr(STDIN_FILENO, &terminal_mode_on_startup); + // Disable flow control by default. + terminal_mode_on_startup.c_iflag &= ~IXON; + terminal_mode_on_startup.c_iflag &= ~IXOFF; + // Set the mode used for program execution, initialized to the current mode. std::memcpy(&tty_modes_for_external_cmds, &terminal_mode_on_startup, sizeof tty_modes_for_external_cmds); - // Disable flow control for external commands by default. - tty_modes_for_external_cmds.c_iflag &= ~IXON; - tty_modes_for_external_cmds.c_iflag &= ~IXOFF; term_fix_external_modes(&tty_modes_for_external_cmds); // Set the mode used for the terminal, initialized to the current mode.