[Toybox] [PATCH] Fix more to a non-tty.

Rob Landley rob at landley.net
Sat Apr 23 12:39:31 PDT 2016


On 04/21/2016 07:42 PM, enh wrote:
> And add a test.
> ---
>  toys/pending/more.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Applied, but I don't see the test?

Sigh: I wanted "more" and "less" to share code, but they really don't do
the same thing (random example: "ls --color | more" vs "ls --color | less").

I was vaguely going "yeah, but I need even MORE smarts than that to
implement screen, and if less can share that code and parse ansi escape
sequences the way screen needs to, then it can also act like more!" but
just because I CAN do that doesn't mean I SHOULD. The point of "more" is
to be fairly simple.

So, cleaning up more, let's see:

  FILE *fp, *cin;

  if (!isatty(1) || !(cin = fopen("/dev/tty", "r"))) {
    loopfiles(toys.optargs, do_cat_operation);
    return;
  }

  TT.cin_fd = fileno(cin);

If we know stdout is a tty, and we _REQUIRE_ stdout to be a tty, why are
we opening /dev/tty? (Because stdout may be a _different_ tty than the
one controlling stdin? Is that a real concern?)

Yes, apparently! Ctrl-alt-f1, login as root (otherwise you can't write
to terminals you don't own), more README > /dev/tty3, and the output
goes there (as well as the prompts!) but the input

That's INSANE. Can I read from stdout? (Did they open it write-only? I
can almost always write to stdin...)

Gee, wouldn't it be nice if posix covered ANY of this? Let's go read the
posix more spec again...

> If standard output is not a terminal device, all input files shall be
> copied to standard output in their entirety, without modification,
> except as specified for the -s option.

Modulo inserting :::: headers between them?

> If standard output is a terminal, standard error shall be used to
? read commands from the user. If standard output is a terminal,
> standard error is not readable, and command input is needed, more may
> attempt to obtain user commands from the controlling terminal (for
> example, /dev/tty);

So I can read from stderr? But I'm NOT to read from stdout, even when
the above redirection exercise makes stdout the only place connected to
the terminal the output is actually going to?

> If standard output is not a terminal, no error shall result if
> standard error cannot be opened for reading.

How do you OPEN standard error? It's file descriptor 2! What, do you
expect /dev/stderr or /proc/self/fd/2 to reliably exist and have
meaning? That's portable? What are these people smoking?

Sigh. Where does it define stdin/stdout/stderr? Hmmm...

http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_05

Not it...

http://pubs.opengroup.org/onlinepubs/9699919799/functions/stderr.html

Defers to the ISO C standard. Of course. It does hardwire STDIN_FILENO
to 0 and so on, but doesn't say which are readable and writeable. I'm
pretty sure shell redirection
(file:///home/landley/reading/SUSv4/utilities/V3_chap02.html#tag_18_07)
opening files "for reading" and "for writing" are limiting these...

Meanwhile, another design question: is resetting the terminal to the
current state (vs a known state) useful? In lib/interestingtimes.c I
have set_terminal() which sets the terminal to either raw or cooked
mode, but does so by setting all the flags a known state. (Because it's
2016, there haven't been 'terminal devices' in a while: the state
"reset" puts the terminal into is the one it should probably be in when
it's not in raw mode.)

While it can save the old terminfo so you can put it back with
tcsetattr(), the only user that actually _does_ that is read_password()
in lib/passwd.c, which was grandfathered in submitted code and still not
quite fully cleaned up.

So the question is: would set_terminal(fd, raw) be reasonable, so you
just set_terminal(1, 1) on the way in and set_terminal(1, 0) on the way
out? In theory this can lose the previous terminal state, but I'm
unaware of that causing a _problem_ these days?

Dunno. It does have the advantage of encapsulating all the tty setting
logic into one place, except that there's a THIRD state, which is "don't
echo input back, but don't screw up output either". Where

(You wonder why it takes me so long to clean stuff up? This is why. This
is MAYBE the first 10% of the _research_ to do the cleanup...)

Rob

(There is no WAY I'm having a release ready tomorrow. Grrr. Let's see
what I can get done on the plane...)



More information about the Toybox mailing list