less icon indicating copy to clipboard operation
less copied to clipboard

Use ttyname() instead of hardwired "/dev/tty".

Open Dale-M opened this issue 3 years ago • 8 comments

My system has trouble using /dev/tty as the terminal. Please consider applying this patch which fixes the problem for me, and probably will for some others, too.

Dale-M avatar Feb 06 '21 17:02 Dale-M

This seems like a good idea, however there are a couple of problems with this implementation. First, ttyname is not supported on all systems, so a check should be added to configure.ac and ttyname called only if HAVE_TTYNAME is defined. Second, ttyname(0) won't work if stdin is not the tty; for example if a file is piped into less. I guess it should call ttyname(2) instead. See if 4d4e6f467663a60778be6fd22aa5273e73afebff works for you.

gwsw avatar Feb 06 '21 17:02 gwsw

@Dale-M What was the specific reason for this? Does opening /dev/tty failed or did the content written to it not showed up? This change (just yet landed in Debian unstable) causes less (which is the default alternative on Debian for /usr/bin/pager) try to open the current pty (i.e. /dev/pts/1), which might not be allowed, for example when using SELinux.

Would trying to open /dev/tty first, and only on failure opening ttyname() be an valid alternative?

cgzones avatar Jan 04 '22 12:01 cgzones

It seems strange and rather useless for ttyname() to return a name that can't be opened. But anyway, currently if ttyname() fails to open, less uses stderr (fd 2). Does that not work on Debian? If a change is to be made, I'd be inclined to try to open ttyname() first and if that fails, open /dev/tty. Would that work? I'd also like to hear from @Dale-M as to what was the original problem. Did /dev/tty not open, or did it open but not work correctly?

gwsw avatar Jan 04 '22 16:01 gwsw

The problem I keep getting is that when I run less/bash/sudo/bash/ssh/bash/screen I find that less will display a page but is unresponsive to keyboard inputs, and the only thing I can do is ctrl-z and then kill the backgrounded process. Everything works fine with ttyname(). Of course, the irony is that root ought to be able to read/write anything, so it is hard to see why there is a problem, but it is only the pseudo-terminal which works properly.

As per above, I'd be happier if ttyname() were tried first, and then /dev/tty used as fallback.

Dale-M avatar Jan 04 '22 19:01 Dale-M

There doesn't seem to be any harm in making /dev/tty the backup if ttyname() returns an unopenable file, just as is currently done if ttyname() returns NULL. @Dale-M and @cgzones , can you both try 971471b6d826b832173846631dce7c3951d9bed5 and confirm whether it behaves correctly for you?

gwsw avatar Jan 04 '22 22:01 gwsw

This works very well for me.

Dale-M avatar Jan 05 '22 10:01 Dale-M

It seems to work. May I ask why less opens a new file descriptor in the first place? What's wrong with the inherited STDIN_FILENO (at least on Linux)?

cgzones avatar Jan 05 '22 20:01 cgzones

Using stdin would not work if a file is piped into less. In that case stdin refers to the input file, not the tty.

gwsw avatar Jan 06 '22 17:01 gwsw

To provide an additional data point: the bash shell attempts to open /dev/tty, with ttyname() as a fallback.

https://github.com/bminor/bash/blob/bash-5.2/general.c#L587

floppym avatar Nov 24 '22 20:11 floppym

Less currently sort of does the opposite: it tries ttyname(2) first, then /dev/tty that fails, then file descriptor 2 if both fail.

gwsw avatar Dec 29 '22 22:12 gwsw