Using less in environment without controlling tty
Harald Becker
ralda at gmx.de
Fri Jul 26 21:42:57 UTC 2013
Hi all,
sorry for the delays of my work on the sleep/timeout applets.
I'm currently really busy due to activities of craftsmen here
and some public authority duties ... and I'm got stuck with a
frustrating problem:
I tried to use less as a startup message viewer from an init
script and had massive problems to get that working, as less
uses /dev/tty, which is not available in environments without a
controlling tty.
The situation is as following:
In process pid 1:
#!/bin/busybox sh
...
{
... do startup code here
} | console_buffer
Where console_buffer is a little application to buffer console
messages in a circular memory buffer. Those messages are flushed
(and never displayed) if the startup code succeeds without
errors. In case there are errors, console_buffer forks a command
and pipes all messages from it's buffer to that command. As
command I tried to use less, but resulted in a display like cat.
It took me a long time until I found the reason for this. Busybox
less opens /dev/tty to display the messages and control message
view. The open call of /dev/tty fails and there seams to be no
possibility to work around this.
The relevant code part of less seams to be (from less_main):
/* Another popular pager, most, detects when stdout
* is not a tty and turns into cat. This makes sense. */
if (!isatty(STDOUT_FILENO))
return bb_cat(argv);
if (!num_files) {
if (isatty(STDIN_FILENO)) {
/* Just "less"? No args and no
redirection? */ bb_error_msg("missing filename");
bb_show_usage();
}
} else {
filename = xstrdup(files[0]);
}
if (option_mask32 & FLAG_TILDE)
empty_line_marker = "";
kbd_fd = open(CURRENT_TTY, O_RDONLY); <-- open /dev/tty
if (kbd_fd < 0)
return bb_cat(argv);
ndelay_on(kbd_fd);
tcgetattr(kbd_fd, &term_orig);
term_less = term_orig;
term_less.c_lflag &= ~(ICANON | ECHO);
term_less.c_iflag &= ~(IXON | ICRNL);
/*term_less.c_oflag &= ~ONLCR;*/
term_less.c_cc[VMIN] = 1;
term_less.c_cc[VTIME] = 0;
My current (temporary) fix for this is, to patch Busybox to use
fd #2 (stderr) als kbd_fd (kbd_fd = 2;) then it is possible to
redirect output of less to any location you like:
... | less 2<>/dev/ttyN
This works fine in all tested cases, but needs patching of
Busybox. So I really like to get a fix for this in main stream.
... or are there any other suggestions on how to use less in
such a situation?
If this is going to be accepted, I can send a patch, but as it is
unclear how we shall handle this situation, I decided to ask for
suggestions ahead.
... and no, I can't use cttyhack for this, as I do not like to
make any tty the controlling tty for process 1. Output of pid 1
is redirected entirely to the console_buffer. I just want to be
able to invoke less, pipe the messages and display on a specific
virtual tty, when the startup fails in any way.
--
Harald
More information about the busybox
mailing list