]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
tty: handle misconfigured namespaces
authorPaul Eggert <eggert@cs.ucla.edu>
Wed, 5 Apr 2017 18:34:42 +0000 (11:34 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Wed, 5 Apr 2017 18:35:35 +0000 (11:35 -0700)
On some platforms, isatty succeeds but ttyname fails.
POSIX does not seem to allow this, but there it is.
Problem reported by Christian Brauner (Bug#26371).
While we’re at it, check for errors more carefully and return a
new exit status 4 if stdin is closed or a similar error occurs.
* doc/coreutils.texi (tty invocation): Document new behavior.
* init.cfg (stderr_fileno_):
Don't assume have_input_tty is not in the environment.
* src/tty.c (TTY_STDIN_ERROR): New constant.
(main): Exit with nonzero status if there is a usage error,
like other coreutils programs.
Check for error in getting stdin type.
* tests/misc/tty.sh: New file.
* tests/local.mk (all_tests): Add it.

doc/coreutils.texi
init.cfg
src/tty.c
tests/local.mk
tests/misc/tty.sh [new file with mode: 0755]

index c22e0761578095bed5d1e97e87dd556158fbbc9f..284e7e36b0389f595954ebffe7744cab6157ca2f 100644 (file)
@@ -15041,9 +15041,10 @@ Exit status:
 
 @display
 0 if standard input is a terminal
-1 if standard input is not a terminal
+1 if standard input is a non-terminal file
 2 if given incorrect arguments
 3 if a write error occurs
+4 if standard input is closed or its type cannot be determined
 @end display
 
 
index 2f747a349056a1583615a373691dc9f9596a4adf..af6b5817556e832d3da2d371caf18639c57cdd1a 100644 (file)
--- a/init.cfg
+++ b/init.cfg
@@ -293,6 +293,7 @@ require_setfacl_()
 # Require a controlling input 'terminal'.
 require_controlling_input_terminal_()
 {
+  have_input_tty=yes
   tty -s || have_input_tty=no
   test -t 0 || have_input_tty=no
   if test "$have_input_tty" = no; then
index c3fdabc85ea917c21969c3ac6e9649aed2ae3e6e..e908e7ec115cd02742cc277ecd2545f5b32c8c32 100644 (file)
--- a/src/tty.c
+++ b/src/tty.c
@@ -34,7 +34,8 @@
 enum
   {
     TTY_FAILURE = 2,
-    TTY_WRITE_ERROR = 3
+    TTY_WRITE_ERROR = 3,
+    TTY_STDIN_ERROR = 4
   };
 
 /* The official name of this program (e.g., no 'g' prefix).  */
@@ -77,7 +78,6 @@ Print the file name of the terminal connected to standard input.\n\
 int
 main (int argc, char **argv)
 {
-  char *tty;
   int optc;
 
   initialize_main (&argc, &argv);
@@ -109,16 +109,29 @@ main (int argc, char **argv)
     }
 
   if (optind < argc)
-    error (0, 0, _("extra operand %s"), quote (argv[optind]));
+    {
+      error (0, 0, _("extra operand %s"), quote (argv[optind]));
+      usage (TTY_FAILURE);
+    }
+
+  errno = ENOENT;
+
+  if (silent)
+    return (isatty (STDIN_FILENO) ? EXIT_SUCCESS
+            : errno == ENOTTY ? EXIT_FAILURE
+            : TTY_STDIN_ERROR);
+
+  int status = EXIT_SUCCESS;
+  char const *tty = ttyname (STDIN_FILENO);
 
-  tty = ttyname (STDIN_FILENO);
-  if (!silent)
+  if (! tty)
     {
-      if (tty)
-        puts (tty);
-      else
-        puts (_("not a tty"));
+      if (errno != ENOTTY)
+        error (TTY_STDIN_ERROR, errno, _("standard input"));
+      tty = _("not a tty");
+      status = EXIT_FAILURE;
     }
 
-  return isatty (STDIN_FILENO) ? EXIT_SUCCESS : EXIT_FAILURE;
+  puts (tty);
+  return status;
 }
index 9f1a853a855153174a1d29e4cd3b855215597452..3fe9ba8476ecc7e818afb83bec0cfaf81f7ac0c5 100644 (file)
@@ -415,6 +415,7 @@ all_tests =                                 \
   tests/misc/truncate-parameters.sh            \
   tests/misc/truncate-relative.sh              \
   tests/misc/tsort.pl                          \
+  tests/misc/tty.sh                            \
   tests/misc/unexpand.pl                       \
   tests/misc/uniq.pl                           \
   tests/misc/uniq-perf.sh                      \
diff --git a/tests/misc/tty.sh b/tests/misc/tty.sh
new file mode 100755 (executable)
index 0000000..5931350
--- /dev/null
@@ -0,0 +1,42 @@
+#!/bin/sh
+# Test 'tty'.
+
+# Copyright 2017 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Make sure there's a tty on stdin.
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ tty
+
+if test -t 0; then
+  tty || fail=1
+  tty -s || fail=1
+fi
+
+returns_ 1 tty </dev/null || fail=1
+returns_ 1 tty -s </dev/null || fail=1
+
+returns_ 2 tty a || fail=1
+returns_ 2 tty -s a || fail=1
+
+if test -w /dev/full && test -c /dev/full; then
+  returns_ 3 tty >/dev/full || fail=1
+  returns_ 3 tty </dev/null >/dev/full || fail=1
+fi
+
+returns_ 4 tty <&- 2>/dev/null || fail=1
+returns_ 4 tty -s <&- || fail=1
+
+Exit $fail