From e3637236d8b3dcff9abe8de4447c1d0fbad0148c Mon Sep 17 00:00:00 2001 From: Jonas Rembser Date: Thu, 6 Aug 2026 13:11:02 +0000 Subject: [PATCH] [textinput] Only force tty output when stdout is redirected MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ec7998ac107 made the display claim tty mode whenever /dev/tty could be opened, instead of only when stdout is not a terminal. The prompt was then printed even when IsInteractive() said otherwise, which broke roottest-root-rint-TabCom: its pty has no session leader, so the display is not interactive, but the "root [N]" prompts leaked into the output. /dev/tty is the controlling terminal of the process, which is unrelated to the pty the test writes to. The test therefore only failed when ctest was run from a terminal, and the CI stayed green. Restore the original condition, and query stdout for the terminal size whenever it is a terminal. 🤖 Done with the help of AI. --- .../src/textinput/TerminalDisplayUnix.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/core/textinput/src/textinput/TerminalDisplayUnix.cpp b/core/textinput/src/textinput/TerminalDisplayUnix.cpp index 448a8fef5f65e..d3cef34e6b9c9 100644 --- a/core/textinput/src/textinput/TerminalDisplayUnix.cpp +++ b/core/textinput/src/textinput/TerminalDisplayUnix.cpp @@ -117,7 +117,13 @@ namespace textinput { // redirected, so only the output of the executed code follows the // redirection, as expected. fTTYOutputID = ::open("/dev/tty", O_WRONLY); - if (fTTYOutputID != -1) + // Only force tty-mode output when stdout is not a terminal itself, i.e. + // when it was already redirected at startup (e.g. "root | tee"). If + // stdout is a terminal, whether we drive it interactively is decided by + // IsInteractive() alone, as before: the mere existence of a controlling + // terminal says nothing about the terminal stdout points to, which may + // well be a pty we are not the foreground process group of. + if (fTTYOutputID != -1 && !::isatty(STDOUT_FILENO)) SetIsTTY(true); } @@ -149,9 +155,10 @@ namespace textinput { TerminalDisplayUnix::HandleResizeSignal() { #ifdef TIOCGWINSZ struct winsize sz; - // Query the terminal for its size: use the controlling terminal if we have - // it, as stdout may be redirected to a file (which has no window size). - int sizeFD = (fTTYOutputID != -1) ? fTTYOutputID : STDOUT_FILENO; + // Query the terminal we actually write to for its size. That is stdout + // whenever it is a terminal; only once it is redirected (e.g. to a file, + // which has no window size) fall back to the controlling terminal. + int sizeFD = ::isatty(STDOUT_FILENO) ? STDOUT_FILENO : (fTTYOutputID != -1 ? fTTYOutputID : STDOUT_FILENO); int ret = ioctl(sizeFD, TIOCGWINSZ, (char*)&sz); if (!ret && sz.ws_col) { SetWidth(sz.ws_col);