mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-27 21:33:09 +00:00
another attempt to workaround a glibc bug
This is another attempt to fix issue #3644 that we believe is due to issue https://sourceware.org/bugzilla/show_bug.cgi?id=20632.
This commit is contained in:
parent
2e9a349dd0
commit
56e05dab02
3 changed files with 34 additions and 17 deletions
|
@ -1710,7 +1710,9 @@ void restore_term_foreground_process_group(void) {
|
||||||
if (initial_fg_process_group != -1) {
|
if (initial_fg_process_group != -1) {
|
||||||
// This is called during shutdown and from a signal handler. We don't bother to complain on
|
// This is called during shutdown and from a signal handler. We don't bother to complain on
|
||||||
// failure.
|
// failure.
|
||||||
tcsetpgrp(STDIN_FILENO, initial_fg_process_group);
|
if (tcsetpgrp(STDIN_FILENO, initial_fg_process_group) == -1 && errno == ENOTTY) {
|
||||||
|
redirect_tty_output();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1943,13 +1945,13 @@ bool fish_reserved_codepoint(wchar_t c) {
|
||||||
(c >= INPUT_COMMON_BASE && c < INPUT_COMMON_END);
|
(c >= INPUT_COMMON_BASE && c < INPUT_COMMON_END);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reopen stdout and/or stderr on /dev/null. This is invoked when we find that our tty has become
|
/// Reopen stdin, stdout and/or stderr on /dev/null. This is invoked when we find that our tty has
|
||||||
/// invalid.
|
/// become invalid.
|
||||||
void redirect_tty_output() {
|
void redirect_tty_output() {
|
||||||
struct termios t;
|
struct termios t;
|
||||||
int fd = open("/dev/null", O_WRONLY);
|
int fd = open("/dev/null", O_WRONLY);
|
||||||
if (tcgetattr(STDIN_FILENO, &t) == -1) dup2(fd, STDIN_FILENO);
|
if (tcgetattr(STDIN_FILENO, &t) == -1 && errno == EIO) dup2(fd, STDIN_FILENO);
|
||||||
if (tcgetattr(STDOUT_FILENO, &t) == -1) dup2(fd, STDOUT_FILENO);
|
if (tcgetattr(STDOUT_FILENO, &t) == -1 && errno == EIO) dup2(fd, STDOUT_FILENO);
|
||||||
if (tcgetattr(STDERR_FILENO, &t) == -1) dup2(fd, STDERR_FILENO);
|
if (tcgetattr(STDERR_FILENO, &t) == -1 && errno == EIO) dup2(fd, STDERR_FILENO);
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
|
@ -820,7 +820,7 @@ static int terminal_return_from_job(job_t *j) {
|
||||||
|
|
||||||
// Save jobs terminal modes.
|
// Save jobs terminal modes.
|
||||||
if (tcgetattr(STDIN_FILENO, &j->tmodes)) {
|
if (tcgetattr(STDIN_FILENO, &j->tmodes)) {
|
||||||
if (errno == ENOTTY) redirect_tty_output();
|
if (errno == EIO) redirect_tty_output();
|
||||||
debug(1, _(L"Could not return shell to foreground"));
|
debug(1, _(L"Could not return shell to foreground"));
|
||||||
wperror(L"tcgetattr");
|
wperror(L"tcgetattr");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -832,7 +832,8 @@ static int terminal_return_from_job(job_t *j) {
|
||||||
// https://github.com/fish-shell/fish-shell/issues/121
|
// https://github.com/fish-shell/fish-shell/issues/121
|
||||||
#if 0
|
#if 0
|
||||||
// Restore the shell's terminal modes.
|
// Restore the shell's terminal modes.
|
||||||
if (tcsetattr(STDIN_FILENO, TCSADRAIN, &shell_modes)) {
|
if (tcsetattr(STDIN_FILENO, TCSADRAIN, &shell_modes) == -1) {
|
||||||
|
if (errno == EIO) redirect_tty_output();
|
||||||
debug(1, _(L"Could not return shell to foreground"));
|
debug(1, _(L"Could not return shell to foreground"));
|
||||||
wperror(L"tcsetattr");
|
wperror(L"tcsetattr");
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -318,7 +318,7 @@ static void term_donate() {
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (tcsetattr(STDIN_FILENO, TCSANOW, &tty_modes_for_external_cmds) == -1) {
|
if (tcsetattr(STDIN_FILENO, TCSANOW, &tty_modes_for_external_cmds) == -1) {
|
||||||
if (errno == ENOTTY) redirect_tty_output();
|
if (errno == EIO) redirect_tty_output();
|
||||||
if (errno != EINTR) {
|
if (errno != EINTR) {
|
||||||
debug(1, _(L"Could not set terminal mode for new job"));
|
debug(1, _(L"Could not set terminal mode for new job"));
|
||||||
wperror(L"tcsetattr");
|
wperror(L"tcsetattr");
|
||||||
|
@ -347,7 +347,7 @@ static void update_buff_pos(editable_line_t *el, size_t buff_pos) {
|
||||||
static void term_steal() {
|
static void term_steal() {
|
||||||
while (1) {
|
while (1) {
|
||||||
if (tcsetattr(STDIN_FILENO, TCSANOW, &shell_modes) == -1) {
|
if (tcsetattr(STDIN_FILENO, TCSANOW, &shell_modes) == -1) {
|
||||||
if (errno == ENOTTY) redirect_tty_output();
|
if (errno == EIO) redirect_tty_output();
|
||||||
if (errno != EINTR) {
|
if (errno != EINTR) {
|
||||||
debug(1, _(L"Could not set terminal mode for shell"));
|
debug(1, _(L"Could not set terminal mode for shell"));
|
||||||
perror("tcsetattr");
|
perror("tcsetattr");
|
||||||
|
@ -794,7 +794,7 @@ void restore_term_mode() {
|
||||||
// Restore the term mode if we own the terminal. It's important we do this before
|
// Restore the term mode if we own the terminal. It's important we do this before
|
||||||
// restore_foreground_process_group, otherwise we won't think we own the terminal.
|
// restore_foreground_process_group, otherwise we won't think we own the terminal.
|
||||||
if (getpid() == tcgetpgrp(STDIN_FILENO)) {
|
if (getpid() == tcgetpgrp(STDIN_FILENO)) {
|
||||||
if (tcsetattr(STDIN_FILENO, TCSANOW, &terminal_mode_on_startup) == -1 && errno == ENOTTY) {
|
if (tcsetattr(STDIN_FILENO, TCSANOW, &terminal_mode_on_startup) == -1 && errno == EIO) {
|
||||||
redirect_tty_output();
|
redirect_tty_output();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1590,8 +1590,9 @@ static void reader_interactive_init() {
|
||||||
for (unsigned long loop_count = 0;; loop_count++) {
|
for (unsigned long loop_count = 0;; loop_count++) {
|
||||||
pid_t owner = tcgetpgrp(STDIN_FILENO);
|
pid_t owner = tcgetpgrp(STDIN_FILENO);
|
||||||
shell_pgid = getpgrp();
|
shell_pgid = getpgrp();
|
||||||
if (owner < 0 && errno == ENOTTY) {
|
if (owner == -1 && errno == ENOTTY) {
|
||||||
// No TTY, cannot be interactive?
|
// No TTY, cannot be interactive?
|
||||||
|
redirect_tty_output();
|
||||||
debug(1, _(L"No TTY for interactive shell (tcgetpgrp failed)"));
|
debug(1, _(L"No TTY for interactive shell (tcgetpgrp failed)"));
|
||||||
wperror(L"setpgid");
|
wperror(L"setpgid");
|
||||||
exit_without_destructors(1);
|
exit_without_destructors(1);
|
||||||
|
@ -1643,7 +1644,7 @@ static void reader_interactive_init() {
|
||||||
|
|
||||||
// Set the new modes.
|
// Set the new modes.
|
||||||
if (tcsetattr(0, TCSANOW, &shell_modes) == -1) {
|
if (tcsetattr(0, TCSANOW, &shell_modes) == -1) {
|
||||||
if (errno == ENOTTY) redirect_tty_output();
|
if (errno == EIO) redirect_tty_output();
|
||||||
wperror(L"tcsetattr");
|
wperror(L"tcsetattr");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2383,10 +2384,10 @@ const wchar_t *reader_readline(int nchars) {
|
||||||
reader_repaint();
|
reader_repaint();
|
||||||
|
|
||||||
// Get the current terminal modes. These will be restored when the function returns.
|
// Get the current terminal modes. These will be restored when the function returns.
|
||||||
tcgetattr(STDIN_FILENO, &old_modes);
|
if (tcgetattr(STDIN_FILENO, &old_modes) == -1 && errno == EIO) redirect_tty_output();
|
||||||
// Set the new modes.
|
// Set the new modes.
|
||||||
if (tcsetattr(0, TCSANOW, &shell_modes) == -1) {
|
if (tcsetattr(0, TCSANOW, &shell_modes) == -1) {
|
||||||
if (errno == ENOTTY) redirect_tty_output();
|
if (errno == EIO) redirect_tty_output();
|
||||||
wperror(L"tcsetattr");
|
wperror(L"tcsetattr");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3253,7 +3254,7 @@ const wchar_t *reader_readline(int nchars) {
|
||||||
|
|
||||||
if (!reader_exit_forced()) {
|
if (!reader_exit_forced()) {
|
||||||
if (tcsetattr(0, TCSANOW, &old_modes) == -1) {
|
if (tcsetattr(0, TCSANOW, &old_modes) == -1) {
|
||||||
if (errno == ENOTTY) redirect_tty_output();
|
if (errno == EIO) redirect_tty_output();
|
||||||
wperror(L"tcsetattr"); // return to previous mode
|
wperror(L"tcsetattr"); // return to previous mode
|
||||||
}
|
}
|
||||||
set_color(rgb_color_t::reset(), rgb_color_t::reset());
|
set_color(rgb_color_t::reset(), rgb_color_t::reset());
|
||||||
|
@ -3359,7 +3360,20 @@ int reader_read(int fd, const io_chain_t &io) {
|
||||||
// If reader_read is called recursively through the '.' builtin, we need to preserve
|
// If reader_read is called recursively through the '.' builtin, we need to preserve
|
||||||
// is_interactive. This, and signal handler setup is handled by
|
// is_interactive. This, and signal handler setup is handled by
|
||||||
// proc_push_interactive/proc_pop_interactive.
|
// proc_push_interactive/proc_pop_interactive.
|
||||||
int inter = ((fd == STDIN_FILENO) && isatty(STDIN_FILENO));
|
int inter = 0;
|
||||||
|
// This block is a hack to work around https://sourceware.org/bugzilla/show_bug.cgi?id=20632.
|
||||||
|
// See also, commit 396bf12. Without the need for this workaround we would just write:
|
||||||
|
// int inter = ((fd == STDIN_FILENO) && isatty(STDIN_FILENO));
|
||||||
|
if (fd == STDIN_FILENO) {
|
||||||
|
struct termios t;
|
||||||
|
int a_tty = isatty(STDIN_FILENO);
|
||||||
|
if (a_tty) {
|
||||||
|
inter = 1;
|
||||||
|
} else if (tcgetattr(STDIN_FILENO, &t) == -1 && errno == EIO) {
|
||||||
|
redirect_tty_output();
|
||||||
|
inter = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
proc_push_interactive(inter);
|
proc_push_interactive(inter);
|
||||||
|
|
||||||
res = shell_is_interactive() ? read_i() : read_ni(fd, io);
|
res = shell_is_interactive() ? read_i() : read_ni(fd, io);
|
||||||
|
|
Loading…
Reference in a new issue