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
This commit is contained in:
Fabian Homborg
2021-02-11 18:32:45 +01:00
parent c27fb9b802
commit 2be720b6cc

View File

@@ -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.