GNU bug report logs - #26371
[PATCH 0/1] tty: do not provide conflicting information

Previous Next

Package: coreutils;

Reported by: Christian Brauner <christian.brauner <at> ubuntu.com>

Date: Wed, 5 Apr 2017 15:27:02 UTC

Severity: normal

Tags: patch

Done: Paul Eggert <eggert <at> cs.ucla.edu>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 26371 in the body.
You can then email your comments to 26371 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-coreutils <at> gnu.org:
bug#26371; Package coreutils. (Wed, 05 Apr 2017 15:27:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Christian Brauner <christian.brauner <at> ubuntu.com>:
New bug report received and forwarded. Copy sent to bug-coreutils <at> gnu.org. (Wed, 05 Apr 2017 15:27:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Christian Brauner <christian.brauner <at> ubuntu.com>
To: coreutils <at> gnu.org, bug-coreutils <at> gnu.org, stgraber <at> ubuntu.com,
 serge <at> hallyn.com
Cc: Christian Brauner <christian.brauner <at> ubuntu.com>
Subject: [PATCH 0/1] tty: do not provide conflicting information
Date: Wed,  5 Apr 2017 16:44:40 +0200
Hi guys,

In case the current file descriptor is a tty but ttyname{_r}() fails to retrieve
the device path tty would falsely report "not a tty" but return EXIT_SUCCESS.
This is confusing. Instead, let's first check whether the fd refers to a tty and
if not report "not a tty" and exit with error. In all other cases, we should
report "is a tty but failed to determine the device path" and exit with success.
This is much clearer. Depending on the platform the user can then decide how to
proceed, e.g. by looking at /proc/self/fd/0 for Linux or somewhere else on other
platforms.

This becomes especially important when we deal with Linux namespaces where this
case can regularly happen should a new devpts instance be mounted in the
namespace but the fd still refers to a pts device from another devpts instance
in another mount namespace.

I added Signed-off-by line but I'm not completely sure if this is used in
cureutils. If not, just drop it. :)

Christian

Christian Brauner (1):
  tty: do not provide conflicting information

 src/tty.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

-- 
2.11.0





Information forwarded to bug-coreutils <at> gnu.org:
bug#26371; Package coreutils. (Wed, 05 Apr 2017 15:45:02 GMT) Full text and rfc822 format available.

Message #8 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Christian Brauner <christian.brauner <at> ubuntu.com>
To: coreutils <at> gnu.org, bug-coreutils <at> gnu.org, stgraber <at> ubuntu.com,
 serge <at> hallyn.com
Cc: Christian Brauner <christian.brauner <at> ubuntu.com>
Subject: [PATCH 1/1] tty: do not provide conflicting information
Date: Wed,  5 Apr 2017 16:44:41 +0200
In case the current file descriptor is a tty but ttyname{_r}() fails to retrieve
the device path tty would falsely report "not a tty" but return EXIT_SUCCESS.
This is confusing. Instead, let's first check whether the fd refers to a tty and
if not report "not a tty" and exit with error. In all other cases, we should
report "is a tty but failed to determine the device path" and exit with success.
This is much clearer. Depending on the platform the user can then decide how to
proceed, e.g. by looking at /proc/self/fd/0 for Linux or somewhere else on other
platforms.

Signed-off-by: Christian Brauner <christian.brauner <at> ubuntu.com>
---
 src/tty.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/tty.c b/src/tty.c
index c3fdabc85..fb21a995a 100644
--- a/src/tty.c
+++ b/src/tty.c
@@ -79,6 +79,7 @@ main (int argc, char **argv)
 {
   char *tty;
   int optc;
+  int is_tty;
 
   initialize_main (&argc, &argv);
   set_program_name (argv[0]);
@@ -111,14 +112,21 @@ main (int argc, char **argv)
   if (optind < argc)
     error (0, 0, _("extra operand %s"), quote (argv[optind]));
 
+  is_tty = isatty (STDIN_FILENO);
+  if (!is_tty)
+    {
+      puts (_("not a tty"));
+      return EXIT_FAILURE;
+    }
+
   tty = ttyname (STDIN_FILENO);
   if (!silent)
     {
       if (tty)
         puts (tty);
       else
-        puts (_("not a tty"));
+        puts (_("is a tty but failed to determine the device path"));
     }
 
-  return isatty (STDIN_FILENO) ? EXIT_SUCCESS : EXIT_FAILURE;
+  return EXIT_SUCCESS;
 }
-- 
2.11.0





Reply sent to Paul Eggert <eggert <at> cs.ucla.edu>:
You have taken responsibility. (Wed, 05 Apr 2017 18:41:01 GMT) Full text and rfc822 format available.

Notification sent to Christian Brauner <christian.brauner <at> ubuntu.com>:
bug acknowledged by developer. (Wed, 05 Apr 2017 18:41:02 GMT) Full text and rfc822 format available.

Message #13 received at 26371-done <at> debbugs.gnu.org (full text, mbox):

From: Paul Eggert <eggert <at> cs.ucla.edu>
To: Christian Brauner <christian.brauner <at> ubuntu.com>, coreutils <at> gnu.org,
 26371-done <at> debbugs.gnu.org, stgraber <at> ubuntu.com, serge <at> hallyn.com
Subject: Re: bug#26371: [PATCH 0/1] tty: do not provide conflicting information
Date: Wed, 5 Apr 2017 11:40:15 -0700
[Message part 1 (text/plain, inline)]
Thanks for the bug report. The situation you describe seems to be a 
platform that does not conform to POSIX, since POSIX doesn't allow for 
isatty to succeed but ttyname to fail. So I expect you'll run into 
problems other than with the tty program, as other software will make 
the same assumptions that tty is making.

That being said, tty could do a better job about the situation. I 
installed the attached somewhat-more-ambitious patch, so that tty will 
do more-extensive checking of the results of isatty and/or ttyname (and 
so that it never needs to call both functions and worry about whether 
their results are consistent :-). Please give it a try on your platform.
[0001-tty-handle-misconfigured-namespaces.patch (application/x-patch, attachment)]

Information forwarded to bug-coreutils <at> gnu.org:
bug#26371; Package coreutils. (Wed, 05 Apr 2017 20:37:02 GMT) Full text and rfc822 format available.

Message #16 received at 26371-done <at> debbugs.gnu.org (full text, mbox):

From: Christian Brauner <christian.brauner <at> canonical.com>
To: Paul Eggert <eggert <at> cs.ucla.edu>
Cc: Christian Brauner <christian.brauner <at> ubuntu.com>, serge <at> hallyn.com,
 26371-done <at> debbugs.gnu.org, coreutils <at> gnu.org, stgraber <at> ubuntu.com
Subject: Re: bug#26371: [PATCH 0/1] tty: do not provide conflicting information
Date: Wed, 5 Apr 2017 22:17:18 +0200
Hi Paul,

Thanks for the quick response. :)

On Wed, Apr 05, 2017 at 11:40:15AM -0700, Paul Eggert wrote:
> Thanks for the bug report. The situation you describe seems to be a platform
> that does not conform to POSIX, since POSIX doesn't allow for isatty to
> succeed but ttyname to fail. So I expect you'll run into problems other than

Oh, where can that information be gathered from? I looked up isatty() and
ttyname{_r}() in:

The Open Group Base Specifications Issue 7
IEEE Std 1003.1-2008, 2016 Edition
Copyright © 2001-2016 The IEEE and The Open Group

but couldn't find any such requirement that forces an alignment between isatty()
and ttyname{_r}().

> with the tty program, as other software will make the same assumptions that
> tty is making.
> 
> That being said, tty could do a better job about the situation. I installed
> the attached somewhat-more-ambitious patch, so that tty will do
> more-extensive checking of the results of isatty and/or ttyname (and so that
> it never needs to call both functions and worry about whether their results
> are consistent :-). Please give it a try on your platform.

Form a purely technical perspective it just seems to make a lot more sense to
exit with success if the file descriptor actually refers to a terminal. The name
of the device it refers to just seems syntactical sugar. :)

Thanks again!
Christian




Information forwarded to bug-coreutils <at> gnu.org:
bug#26371; Package coreutils. (Wed, 05 Apr 2017 21:28:02 GMT) Full text and rfc822 format available.

Message #19 received at 26371-done <at> debbugs.gnu.org (full text, mbox):

From: Paul Eggert <eggert <at> cs.ucla.edu>
To: Christian Brauner <christian.brauner <at> canonical.com>
Cc: Christian Brauner <christian.brauner <at> ubuntu.com>, serge <at> hallyn.com,
 26371-done <at> debbugs.gnu.org, stgraber <at> ubuntu.com, coreutils <at> gnu.org
Subject: Re: bug#26371: [PATCH 0/1] tty: do not provide conflicting information
Date: Wed, 5 Apr 2017 14:27:12 -0700
On 04/05/2017 01:17 PM, Christian Brauner wrote:
> Oh, where can that information be gathered from? I looked up isatty() and
> ttyname{_r}() in:
>
> The Open Group Base Specifications Issue 7
> IEEE Std 1003.1-2008, 2016 Edition
> Copyright © 2001-2016 The IEEE and The Open Group
>
> but couldn't find any such requirement
I inferred it from the similar wording used for both functions. isatty 
"shall return 1 if fildes is associated with a terminal", and ttyname 
"shall return a pointer to a string containing a null-terminated 
pathname of the terminal associated with file descriptor fildes". 
Although in theory POSIX allows either function to fail with a weird 
error number whenever it pleases, clearly the intent is that the two 
functions be consistent, many programs assume that they are consistent, 
and any implementation where isatty succeeds but ttyname fails is an 
implementation that is asking for trouble.

> Form a purely technical perspective it just seems to make a lot more sense to
> exit with success if the file descriptor actually refers to a terminal. The name
> of the device it refers to just seems syntactical sugar.
That's what 'tty -s' does. Perhaps if we were designing things from 
scratch, 'tty' would behave like 'tty -s'. But longstanding practice is 
for 'tty' (without arguments) to output the terminal's name, and 
programs expect that behavior.

Really, the underlying platform should get fixed. In the meantime I 
suppose that the best plain 'tty' can do is report the configuration 
error and exit.

Did you try the patch I installed? That is, does ttyname have a 
reasonable errno value when it returns NULL on your platform?




Information forwarded to bug-coreutils <at> gnu.org:
bug#26371; Package coreutils. (Wed, 05 Apr 2017 21:50:02 GMT) Full text and rfc822 format available.

Message #22 received at 26371-done <at> debbugs.gnu.org (full text, mbox):

From: Christian Brauner <christian.brauner <at> canonical.com>
To: Paul Eggert <eggert <at> cs.ucla.edu>
Cc: Christian Brauner <christian.brauner <at> ubuntu.com>, serge <at> hallyn.com,
 26371-done <at> debbugs.gnu.org, stgraber <at> ubuntu.com, coreutils <at> gnu.org
Subject: Re: bug#26371: [PATCH 0/1] tty: do not provide conflicting information
Date: Wed, 5 Apr 2017 23:49:12 +0200
On Wed, Apr 05, 2017 at 02:27:12PM -0700, Paul Eggert wrote:
> On 04/05/2017 01:17 PM, Christian Brauner wrote:
> > Oh, where can that information be gathered from? I looked up isatty() and
> > ttyname{_r}() in:
> > 
> > The Open Group Base Specifications Issue 7
> > IEEE Std 1003.1-2008, 2016 Edition
> > Copyright © 2001-2016 The IEEE and The Open Group
> > 
> > but couldn't find any such requirement
> I inferred it from the similar wording used for both functions. isatty
> "shall return 1 if fildes is associated with a terminal", and ttyname "shall
> return a pointer to a string containing a null-terminated pathname of the
> terminal associated with file descriptor fildes". Although in theory POSIX
> allows either function to fail with a weird error number whenever it
> pleases, clearly the intent is that the two functions be consistent, many
> programs assume that they are consistent, and any implementation where
> isatty succeeds but ttyname fails is an implementation that is asking for
> trouble.

Maybe, but it doesn't sound obvious to me especially in the presence of e.g.
mount namespaces on Linux. But this isn't even platform specific! If you somehow
mask the device path (overmounting or think of any other reason) the file
descriptor refers to then ttyname{_r}() _will fail to retrieve it_. I don't know
if most platforms will even set an errno in this case and so your patch will
likely be just another version of reporting misleading information. If errno is
not set then now instead of reporting "not a tty" but exiting with success you
will now report ./tty: standard input: Success! but exit with an error.

> 
> > Form a purely technical perspective it just seems to make a lot more sense to
> > exit with success if the file descriptor actually refers to a terminal. The name
> > of the device it refers to just seems syntactical sugar.
> That's what 'tty -s' does. Perhaps if we were designing things from scratch,
> 'tty' would behave like 'tty -s'. But longstanding practice is for 'tty'
> (without arguments) to output the terminal's name, and programs expect that
> behavior.
> 
> Really, the underlying platform should get fixed. In the meantime I suppose

Maybe, but it's not really an explicit POSIX requirement according to what I've
gathered from the above paragraph. For glibc, Serge and I have taken care that
errno is set to ENODEV in this case which seemed to everyone involved in this
discussion to be the most natural way of handling this scenario.

> that the best plain 'tty' can do is report the configuration error and exit.
> 
> Did you try the patch I installed? That is, does ttyname have a reasonable
> errno value when it returns NULL on your platform?

Yes, as I said at least for glibc you'd get:

root <at> zest1:~/dummy/coreutils/src# ./tty
./tty: standard input: No such device

Which is not necessarily an improvement since the fd _is_ actually a tty.

Thanks for hearing me rant! :)
Christian




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Thu, 04 May 2017 11:24:04 GMT) Full text and rfc822 format available.

bug unarchived. Request was from Paul Eggert <eggert <at> cs.ucla.edu> to control <at> debbugs.gnu.org. (Fri, 20 Jun 2025 18:57:02 GMT) Full text and rfc822 format available.

Information forwarded to bug-coreutils <at> gnu.org:
bug#26371; Package coreutils. (Fri, 20 Jun 2025 19:21:01 GMT) Full text and rfc822 format available.

Message #29 received at 26371 <at> debbugs.gnu.org (full text, mbox):

From: Paul Eggert <eggert <at> cs.ucla.edu>
To: Christian Brauner <christian.brauner <at> canonical.com>
Cc: Christian Brauner <christian.brauner <at> ubuntu.com>, serge <at> hallyn.com,
 26371 <at> debbugs.gnu.org, stgraber <at> ubuntu.com, coreutils <at> gnu.org
Subject: Re: bug#26371: [PATCH 0/1] tty: do not provide conflicting information
Date: Fri, 20 Jun 2025 12:19:56 -0700
On 2017-04-05 14:27, Paul Eggert wrote:
> In the meantime I suppose that the best plain 'tty' can do is report the 
> configuration error and exit.

After seeing a more-recent bug report <https://bugs.gnu.org/78244> about 
this I came up with what I think is a better patch for Bug#26371, and 
installed it into Savannah coreutils here:

https://cgit.git.savannah.gnu.org/cgit/coreutils.git/commit/?id=aec89a3e7dfaed1545b2dcaa8525df21cf61a37e

Thanks again for reporting this (8 years ago!).




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Sat, 19 Jul 2025 11:24:10 GMT) Full text and rfc822 format available.

This bug report was last modified 48 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.