Using less in environment without controlling tty

Harald Becker ralda at gmx.de
Mon Aug 5 21:08:53 UTC 2013


Hi Denys !

>Will giving it a ctty create any problems? I think not.

We are having a big discussion about using ctty, where I just
wanted to have a minimal change to less, allowing other usage for
those who like, but don't break things for others.

Can we please go back to the main question? ... using less to
display messages on a selectable tty.

Your initial complain was about directly using stdout with
O_NONBLOCK. This is ok, because it may create unexpected trouble.

So I stepped ahead and added in a function to open a new fd on
same tty as used on stdout (which is already tested to be a tty).
This opens a new fd as you did before, so doesn't change things,
except that we do not use the fixed /dev/tty, but are now using
same tty as on stdout (not duplicating fd). This alone enables
several use cases without breaking anything.

In addition there is a case, where /proc & /sys is not available,
so we need a reasonable fallback, which I've chosen to be stdout
(as it is already tested to be a tty). Current version of less
(460) uses stderr, without checking it to be a tty (which I found
more error prone). The question here is: Is stdout ok as FALLBACK
or do you want to use stderr (as standard less does)?

And furthermore, I adapted your suggestion to add an option to
'less --tty=DEVICE' to specifiy a different tty. As i did not
want to throw in another long option, I just checked if one has
assigned a tty on fd 3, and if so this fd is used for message
display. So you can do "less 3<>ANY_TTY" and or reassign fd 3 as
you like to overwrite the tty less uses. This is an addition of
mine to add further possibilities to less. As long as you do
not fiddle with fd 3 of less or do not assign a tty, this
doesn't change anything. The question is: Are you willing to
accept this addition or not?


>The point is, you are trying to use a tool (less) in a
>non-standard way. No one ever imposed a requirement on pagers to
>be able to use one tty for output and input while ctty is absent,
>or is on another tty. Therefore, expecting that a pager
>will be able to do it is unreasonable. It may, by chance,
>able to pull it off, and another pager (or another version
>of the same pager) may fail to do so.

I have use cases to do so, and consider them legal. In the past I
used standard less for this up to versions of around 390, or
other special application viewers. I accept if you do not wan't
to do this, but a simple change/addition in less allows to do
many additional things easily, without breaking the topics of
your original complain (using O_NONBLOCK on stdout). So with
a simple change we can have extra functionality without breaking
usage on ctty case. The overhead of my change is just another
call to ttyname, which shall not produce much of extra code, as
this function is already linked into Busybox. So we are
discussion about a few extra bytes, allowing for easy use cases
of extra functionality.

... or are you really keen to do philosophical discusssions on
using ctty or not. I'm not, I'm no native English speaker and
need much time for translation on this. So I do not like to
continue this kind of diskussion.

>An another example would be to expect that e.g. shell
>is able to work on a tty with non-standard attributes.
>Say, with "stty eol \t" setting.
>Can fdisk be made to work in this case? Sure, why not.
>It should query terminal attributes, notice the eol
>character, and correctly use TAB as line termination
>in its line editing routine.
>But does it make sense to implement that? No.

No one asked to do this, and I will never do, as I do not need
this. fdisk or shell will never run directly on tty used for
message output and will not be controlled from this tty. You are
mixing cases!

>The code to do that adds complexity, will bit rot,
>and will not be used by vast majority of people.
>The answer for such a feature request would be
>"stop messing around, run the programs in a way
>they are supposed to be used".

Here we would go to add extra complexity. My request is just to
allow less to display messages on a tty that is different
from /dev/tty and adds in a minimum of overhead (not complexity)
without changing other things.

>> use it like:
>>
>> { echo "Any output"
>>   ...
>>   echo -e "\0377\0376\0020>|less\0"
>
>You can run sedsid in the line above: replace "|less"
>with "setsid sh -c 'exec less </dev/ttyFOO >/dev/ttyFOO 2>&1'"

No, you are wrong. Won't work that way. setsid can't be called
before sh -c is invoked.

You miss the echo output is not going to less, it is to
console_buffer, which uses the | to indicate piping to a command.
Anything between the bar and the terminating zero byte is the
COMMAND which gets substituted in:

output of console_buffer | sh -c 'COMMAND'

That is, you can't add a setsid before sh -c is invoked, and
afterwards it will not work.

>setsid creates a new session and therefore loses ctty (if any),
>then it execs sh, sh opens /dev/ttyFOO,

Sure, as long as you do setsid after fork before sh -c is
called, but the console_buffer program is considered to be
general purpose and shall not run it's subprocesses in a
seperate session, so it forks and calls sh -c (without a
setsid).

>and since sh is a session leader w/o ctty, it becomes its ctty.
>Then sh execs less. That's it.

If you write a special program to invoke less here, yes ... but I
won't add another program which is nearly same than current
console_buffer, only to have a setsid to let less grab the right
tty.

Beside this, having setsid creates a new session for less so it
will no more receive signals for the original process group,
which means less does not terminate if console_buffer is signaled
to terminate.

>You don't have to change console_buffer. You need to change
>less invocation, as shown above.

Won't work, without changing console_buffer. Look carefully, the
echo output (including specification of the less command) goes
into stdin of console_buffer. console_buffer forks and exec sh
-c 'COMMAND', without a setsid. Only the part between the bar and
the trailing zero is passed as COMMAND (here just less) to the
shell. So how would you change the less invocation?

>I am telling you how you can make ANY interactive program to run
>on another tty *correctly*. No code hacks are necessary.
>Adding code to support this use in *all* programs is just not
>feasible.

I really know how to run programs on different controlling ctty's
but there are case you do not want to become a tty the
controlling tty. That's it.

>I already added code which make "less 1<>/dev/ttyFOO" work
>as you requested. Please try current git.

Denys, your version is totally bloated and does nothing better
than my suggestion, and it misses a useable fallback when /proc
and /sys are not available. Why can't you accept my suggestion?

You add bloat where it's not required, and miss the fallback case.

--
Harald


More information about the busybox mailing list