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

Denys Vlasenko vda.linux at googlemail.com
Mon Jan 24 17:10:25 UTC 2011

On Mon, Jan 24, 2011 at 4:58 PM, Rob Landley <rob at landley.net> wrote:
> 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

Some Unixes call it VSWTCH. "Switch to other shell level" (was ist das??) char.
Ifdef looks like botched termios portability fix to me. fixing the fix.

> 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.)

Set up (serial) line, get login name, run /bin/login -- LOGINNAME

> 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.

Sure. Can be trivially done in shell. Then you can disable getty in .config.

BTW, I am thinking about deleting this in termios_final:

        /* Account for special characters seen in input */
        if (G.eol == '\r') {
                G.termios.c_iflag |= ICRNL;   /* map CR in input to NL */
                /* already done by termios_init */
                /* G.termios.c_oflag |= ONLCR; map NL in output to CR-NL */

and setting ICRNL unconditionally. I don't see why anyone would want
to ever not have it. This way G.eol will be removed too.

Does anyone see why that would be a bad idea?


More information about the busybox mailing list