]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
tty: better fix for Bug#26371
authorPaul Eggert <eggert@cs.ucla.edu>
Fri, 20 Jun 2025 18:53:21 +0000 (11:53 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Fri, 20 Jun 2025 19:15:27 +0000 (12:15 -0700)
* src/tty.c (TTY_USAGE): Rename from TTY_FAILURE, since this
is used only for usage failures.  All uses changed.
(TTY_TTYNAME_FAILURE): New constant.
(main): Remove no-longer-needed assignment of ENOENT to errno.
Make status-setting clearer too.
Report an error if ttyname fails even though stdin is a terminal,
instead of silently pretending that stdin is not a terminal.
* tests/tty/tty.sh: Test for this issue.  This should fix Bug#78244.

NEWS
THANKS.in
doc/coreutils.texi
src/tty.c
tests/tty/tty.sh

diff --git a/NEWS b/NEWS
index 8f9ac26d06bc85d7092bbb84ad5263a65e7e0f93..50f27cd87a886ce0d19e0e0d876f9750d7901714 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -17,6 +17,11 @@ GNU coreutils NEWS                                    -*- outline -*-
   'sort +0.18446744073709551615R input' on 64 bit systems.
   [bug introduced in coreutils-7.2]
 
+  tty now exits with status 4 with a special diagnostic if ttyname
+  fails even though standard input is a tty.  Formerly it quietly
+  pretended that standard input was not a tty.
+  [This bug was present in "the beginning".]
+
 ** Improvements
 
   stty supports setting arbitrary baud rates on supported systems,
index 57ace387e0a1b5d3fdab94a73e2bac3a6be1f9d9..8c97a81388bdf053c3962a76feee02f41607639e 100644 (file)
--- a/THANKS.in
+++ b/THANKS.in
@@ -120,6 +120,7 @@ Chris Lesniewski                    ctl@mit.edu
 Chris Sylvain                       csylvain@umm.edu
 Chris Yeo                           cyeo@biking.org
 Christi Alice Scarborough           christi@chiark.greenend.org.uk
+Christian Brauner                   christian.brauner@canonical.com
 Christian Harkort                   christian.harkort@web.de
 Christian Jullien                   eligis@orange.fr
 Christian Krackowizer               ckrackowiz@std.schuler-ag.com
index 7556571d7d83d9660b068cb4e72f536273f63344..fc62c6d8d66133b24565081949ad3ec12d061374 100644 (file)
@@ -16020,6 +16020,7 @@ Exit status:
 1 if standard input is a non-terminal file
 2 if given incorrect arguments
 3 if a write error occurs
+4 if the terminal's name cannot be determined
 @end display
 
 
index b01f1a207a53b3977b8b1b7ac59ec5a6f6af8a8d..d5dea5200bbd1b38ff77daaca83d027b25144c38 100644 (file)
--- a/src/tty.c
+++ b/src/tty.c
@@ -33,8 +33,9 @@
 enum
   {
     TTY_STDIN_NOTTY = 1,
-    TTY_FAILURE = 2,
-    TTY_WRITE_ERROR = 3
+    TTY_USAGE = 2,
+    TTY_WRITE_ERROR = 3,
+    TTY_TTYNAME_FAILURE = 4
   };
 
 /* The official name of this program (e.g., no 'g' prefix).  */
@@ -103,26 +104,29 @@ main (int argc, char **argv)
         case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
 
         default:
-          usage (TTY_FAILURE);
+          usage (TTY_USAGE);
         }
     }
 
   if (optind < argc)
     {
       error (0, 0, _("extra operand %s"), quote (argv[optind]));
-      usage (TTY_FAILURE);
+      usage (TTY_USAGE);
     }
 
-  errno = ENOENT;
-
   if (silent)
     return isatty (STDIN_FILENO) ? EXIT_SUCCESS : TTY_STDIN_NOTTY;
 
-  int status = EXIT_SUCCESS;
+  int status;
   char const *tty = ttyname (STDIN_FILENO);
 
-  if (! tty)
+  if (tty)
+    status = EXIT_SUCCESS;
+  else
     {
+      int ttyname_err = errno;
+      if (isatty (STDIN_FILENO))
+        error (TTY_TTYNAME_FAILURE, ttyname_err, "ttyname");
       tty = _("not a tty");
       status = TTY_STDIN_NOTTY;
     }
index 8201b42ebd5caa8688c3b68fad14115e59eca263..b2b8aa25ad700b36713f1f1a9a5ccb5a10e866f5 100755 (executable)
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ tty
 
+tty_works_on_stdin=false
+
 if test -t 0; then
-  tty || fail=1
+  if tty; then
+    tty_works_on_stdin=true
+  else
+    test $? -eq 4 || fail=1
+  fi
   tty -s || fail=1
 fi
 
@@ -34,7 +40,7 @@ returns_ 2 tty a || fail=1
 returns_ 2 tty -s a || fail=1
 
 if test -w /dev/full && test -c /dev/full; then
-  if test -t 0; then
+  if $tty_works_on_stdin; then
     returns_ 3 tty >/dev/full || fail=1
   fi
   returns_ 3 tty </dev/null >/dev/full || fail=1