[PATCH] getty: Wait until all output written to stdout has been transmitted

Rob Landley rob at landley.net
Mon Jan 24 15:58:35 UTC 2011


On 01/23/2011 09:44 PM, Denys Vlasenko wrote:
> On Monday 24 January 2011 03:05, Rob Landley wrote:
>> Wow, what a horrible leftover from the 1970's.  You realize that actual
>> teletype hardware hasn't been connected to Linux machines in... um,
>> forever?  The login command prompts for login: what exactly is getty
>> supposed to be doing here?
> 
> From the code, getty is supposed to set termios parameters.
> login doesn't do that, it expects those param to be set.
> 
> Actually, other getties (mgetty IIRC) are much more advanced
> in this regard: they can set not only baud rate, but also
> 7/8 bits, and various kinds of parity, do expect/send handshake,
> and even receive faxes (!) :)

That's nice.  Does anybody have a test environment that actually uses
any of this functionality?

When I use a serial console, the kernel sets the baud rate for me.  You
can do so with "console=ttyS0,38400", see
Documentation/kernel-parameters.txt and search for "baud".  Default
claims to be 9600 but I doubt that's current, although since it doesn't
_matter_ for qemu I haven't looked into it recently.  (Yes, I'm aware
that for modems everything over 300 baud is actually 600, 1200, or 2400
baud with multitone signalling providing multiple parallel bitstreams.
I just don't care: serial _cables_ have one data channel and their bit
rate and baud rate are the same.)

Modems had already standardized on 8n1 with no stop bit when I got my
first modem for my commodore 64 christmas of 1982.

The "expect" program exists, even versions that aren't written in tcl.
(Heck, I wrote one in shell once via mkfifo.)  It might be nice if
busybox had one of those, but that's a separate issue.

>> More to the point, do modems actually get used anywhere anymore?
> 
> Modems probably no, serial lines yes.

Serial lines yay.  I use them too.  But serial lines do not say
"CONNECT" and require logic to parse this.

The original problem (flushing the serial buffer screws stuff up) was
something it was doing for _modems_, not for serial lines.  My question
was "do we still need to do that if nobody is using modems anymore".

Half the plumbing of getty is for modems, not for serial lines.  Look at
the auto_baud() function.  Explain to me why do_prompt() is a function.
 What's the all_is_upcase() thing for and can it ever happen in our
code?  Look at get_logname() and recoil in horror to see that it's
trying to autodetect whether or not the parity bit is set and what key
bindings to use for backspace/del/enter from what it sees typing the
login name...

Oh, and then there's this bit of fun:

/*
 * The following ioctl will fail if stdin is not a tty, but also when
 * there is noise on the modem control lines. In the latter case, the
 * common course of action is (1) fix your cables (2) give the modem more
 * time to properly reset after hanging up. SunOS users can achieve (2)
 * by patching the SunOS kernel variable "zsadtrlow" to a larger value;
 * 5 seconds seems to be a good value.
 */
if (tcgetattr(0, &termios) < 0)
    bb_perror_msg_and_die("tcgetattr");

The other half of the program seems to reimplement tset/reset/stty, and
we already have reset and stty commands in busybox.

>> Specifically, if somebody has a program listening to a modem line that's
>> going to be doing a +++ATH thing and answering a phone, can't it be
>> _that_ program's problem to flush the serial buffer if they really need
>> to?  Do we need to do this flush at all?
> 
>> Could somebody at least tell me WHY this is important for modems?  What
>> do the modems do if we don't call tcflush()?
> 
> From getty's POV, the tty may be in a "bad" state: serial line with
> RTS/CTS lines set to "don't send". Getty wants to avoid being
> blocked.

We have a stty command.  We can call one command from another, sometimes
even in nofork mode.

>> The program in question is
>> copyright 1989, and one of the first comments is about heuristics to
>> distinguish System V from SunOS 4.  Maybe, just MAYBE, some of what it's
>> doing is no longer relevant to modern hardware, even the embedded stuff.
> 
>> (Wandering through and seeing comments like "I doubt there are systems
>> which still need this", "Optionally detect the baud rate from the modem
>> status message"...  We have #undef HANDLE_ALLCAPS and then large #ifdef
>> chunks for HANDLE_ALLCAPS...)
> 
> I need to be bolder and just nuke that crap instead of #ifdef'ing it out.

I used to take commands like this, read through the thing and create a
notes file describing what it was actually _doing_, and then write a new
one from scratch.

It took a couple days per command.

>> Ok this chunk of the file needs to die:
>>
>> /* Optionally wait for CR or LF before writing /etc/issue */
>> if (option_mask32 & F_WAITCRLF) {
>>         char ch;
>>
>>         debug("waiting for cr-lf\n");
>>         while (safe_read(STDIN_FILENO, &ch, 1) == 1) {
>>                 debug("read %x\n", (unsigned char)ch);
>>                 ch &= 0x7f;                     /* strip "parity bit" */
>>                 if (ch == '\n' || ch == '\r')
>>                         break;
>>         }
>> }
>>
>> Strip parity bit?  Really?
> 
> I am deleting "ch &= 0x7f", but otherwise this fragment doesn't look wrong.

"debug("waiting for cr-lf\n")" looks ok to you?  Reinventing line
editing to the point where it's unsure about it?

>  
>> I'm going to stop before I have to start rewriting the thing myself...
> 
> Please pull and take a look at the simplified version I just committed.

Heh, I see much of this was already obvious to you. :)

DEF_ERASE is never used.  CR is 13, NL is 10, it goes through two layers
of macros to define ascii standard values...  I have no idea what VSWTC
is but apparently Red Hat 9 had it and Ubuntu still does so I'm not sure
the #ifdef is called for.

It's an improvement, but I'd still like to know what exactly this thing
is supposed to do.  (There's no getty in susv4, not that this means
much.  Mount and init aren't in there either.)

Part of the reason I tend to scrap old programs and write them over is
otherwise you wind up in the situation where the copyright attribution
and change log at the start of the file is three times longer than the
actual remaining program.  As far as I can tell, a proper version of
those program should not have any of the 1989 code still in it.  Call
stty to set the terminal parameters, wait for somebody to hit enter,
maybe "cat /etc/issue", then run the login command.

What else does it do?

Rob


More information about the busybox mailing list