From 3e5284aaf2af97649cafa456691967a9c7b0905f Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sat, 19 Mar 2022 14:53:43 -0700 Subject: [PATCH] Stop restoring tty modes when run non-interactively fish reads the tty modes at startup, and tries to restore them to the original values on exit, to be polite. However this causes problems when fish is run in a pipeline with another process which also messes with the tty modes. Example: fish -c 'echo foo' | vim - Here vim's manipulation of the tty would race with fish, and often vim would end up with broken modes. Only restore the tty if we are interactive. Fixes #8705. --- CHANGELOG.rst | 1 + src/fish.cpp | 2 +- src/reader.cpp | 7 ++++--- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 4a28773f9..b4ca5bbf4 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -20,6 +20,7 @@ Scripting improvements - ``read`` is now faster as the last process in a pipeline (:issue:`8552`). - ``string join`` gained a new ``--no-empty`` flag to skip empty arguments (:issue:`8774`, :issue:`8351`). - ``read`` now actually only triggers the ``fish_read`` event, not the ``fish_prompt`` event (:issue:`8797`). It was supposed to work this way since fish 3.2.0. +- The tty modes are no longer restored when non-interactive shells exit. This fixes wrong tty modes in pipelines with interactive commands. (:issue:`8705`). Interactive improvements ------------------------ diff --git a/src/fish.cpp b/src/fish.cpp index 74b32626a..4f364d8a7 100644 --- a/src/fish.cpp +++ b/src/fish.cpp @@ -517,7 +517,7 @@ int main(int argc, char **argv) { // If we have no config, we default to the default key bindings. parser.vars().set_one(L"fish_key_bindings", ENV_UNEXPORT, L"fish_default_key_bindings"); if (function_exists(L"fish_default_key_bindings", parser)) { - std::vector cmd {"fish_default_key_bindings"}; + std::vector cmd{"fish_default_key_bindings"}; run_command_list(parser, &cmd, {}); } } diff --git a/src/reader.cpp b/src/reader.cpp index f205bbd66..ed198114e 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -1416,10 +1416,11 @@ void reader_init() { termsize_container_t::shared().updating(parser); } -/// 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 the term mode if we own the terminal and are interactive (#8705). +/// It's important we do this before restore_foreground_process_group, +/// otherwise we won't think we own the terminal. void restore_term_mode() { - if (getpgrp() != tcgetpgrp(STDIN_FILENO)) return; + if (!is_interactive_session() || getpgrp() != tcgetpgrp(STDIN_FILENO)) return; if (tcsetattr(STDIN_FILENO, TCSANOW, &terminal_mode_on_startup) == -1 && errno == EIO) { redirect_tty_output();