[Toybox] [PATCH] getty: ensure utmp is updated.

Rob Landley rob at landley.net
Sun Aug 16 02:04:53 PDT 2020


On 8/15/20 6:43 AM, Ariadne Conill wrote:> On 2020-08-15 05:43, Rob Landley wrote:
>> On 8/13/20 10:02 AM, Rob Landley wrote:
>>> On 8/11/20 2:25 PM, enh via Toybox wrote:
>>>> The key issues here turned out to be that getty is responsible for
>>>> creating the file if it doesn't exist, and that the -H flag doesn't
>>>> control whether utmp is updated, but whether or not to override the
>>>> hostname within the utmp entry.
>>>>
>>>> While I'm here switch to the more modern utx APIs that all the non-pending
>>>> parts of toybox use, and remove the duplication.
>>>
>>> Applied and pushed, but this reminds me I should really clean this up and
>>> promote it.
>>>
>>> The reason I haven't is I don't really have a test environment for it? (This
>>> waits for a modem to dial in to a serial port, adjusts the baud rate, and calls
>>> login. I got my first broadband connection in 2001 and haven't owned a modem
>>> since.)
>>
>> Do you have the FOGGIEST idea why:
>>
>>      xopen_stdio(TT.tty_name, O_RDWR|O_NDELAY|O_CLOEXEC);
>>      fcntl(0, F_SETFL, fcntl(0, F_GETFL) & ~O_NONBLOCK); // Block read
>>
>> O_NDELAY == O_NONBLOCK so it opens the tty nonblock and then immediately
>> switches off the nonblock. What (if anything) does that DO? Why is it here? Is
>> this something BSD 2.x needed in 1983 because of certain defective ASR-33
>> teletype variants when plugged into one of the HP minicomputers with the "zero
>> and add packed" instruction?
>>
>> The man page is unenlightening, and the kernel source has 373 _files_ with
>> O_NONBLOCK in them...
> 
> In traditional SysV (with streams), O_NDELAY does not behave the same as
> O_NONBLOCK.

Linux explicitly rejected supporting "streams" 22 years ago:

  https://lkml.org/lkml/1998/6/28/138

One Linux one of those symbols is #defined to the other:

  glibc: /usr/include/asm-generic/fcntl.h:#define O_NDELAY	O_NONBLOCK
  musl: arch/x86_64/bits/fcntl.h:#define O_NDELAY O_NONBLOCK
  bionic: libc/kernel/uapi/asm-generic/fcntl.h:#define O_NDELAY O_NONBLOCK

And that's been true since 0.0.1:

  ~/linux/linux$ git checkout v0.0.1
  Previous HEAD position was a068026b4a06... Linux 1.0
  HEAD is now at cff5a6fb6676... Linux-0.01 (September 17, 1991)
  ~/linux/linux$ grep -r O_NDELAY include
  include/fcntl.h:#define O_NDELAY	O_NONBLOCK

(Yes, I have a git tree back to 0.0.1, http://landley.net/kdocs/fullhist/)

I'm trying to figure out if modern Linux needs those two lines of code I posted.

> In SysV, O_NDELAY means that a read from a file descriptor that does not have
> any data (or a write which would extend the sendq length above the kernel
> watermark) would immediately return 0 and not set an errno.

Did I mention that computer history is a hobby of mine? :)

Although Linus used the printed Solaris manuals in his university library to
implement the second round of Linux system calls in 1991 (because he couldn't
afford a copy of the posix spec and nobody would give him one when he asked
https://www.kclug.org/old_archives/linux-activists/1992/jul/4/0335.shtml so he
used what was available), and that did give Linux 0.0.1 a "System V flavor"
several people at the time commented on (since the switch from SunOS to Solaris
was AT&T lawyers convincing Sun to rebase from BSD to System V for licensing
reasons, as detailed in Robert Young's book "Under the Radar"), that's the
extent of Linux's System V connection.

Linux was a fresh from-scratch implementation written under Minix and using the
Minix filesystem format the summer after Linus took a unix internals course
using Andrew Tanenbaum's Minix textbook and initially posted to comp.os.minix
and recruiting existing minix developers from there who maintained minix patch
stacks that could never go upstream for licensing reasons.

But it's not a minix clone either: Torvalds rejected Minix's microkernel
approach and did a new monolithic kernel, a design the author of Minix strongly
and publicly disapproved of:

  https://www.oreilly.com/openbook/opensources/book/appa.html

It's entirely possible that this getty is blindly copying a procedure that dates
back to systemv, but proving a negative is a slightly higher bar than that. :(

> BSD also added O_NDELAY, which sets errno to EWOULDBLOCK and returns -1.  POSIX
> standardized the BSD implementation, adding the O_NONBLOCK flag for it.

I'm confused, "30 years ago O_NDELAY did not behave the same as O_NONBLOCK" and
"POSIX standardized the BSD implementation, adding the O_NONBLOCK flag for it"?

The oldest version of posix that's online seems to be
https://pubs.opengroup.org/onlinepubs/009695399/functions/open.html from 2001
(which still doesn't provide useful information about WHEN you'd need this flag,
under what circumstances does a SERIAL device block for nontrivial amounts of
time, what flow control? In open()? The Data Terminal Ready line?)

The Open Group doesn't host earlier versions, as explained in Q8 of their FAQ:

  http://www.opengroup.org/austin/papers/posix_faq.html

> So, in SysV, this would give you a file descriptor that has "blocking" reads but
> where the program itself does the blocking.

The code I posted fed the nonblock to open() and then immediately took it off
the resulting file descriptor, so only the behavior change to open itself would
be relevant.

I was wondering A) what the open() behavior change actually was, B) if the
behavior change was purely historic (either not applying to current kernels, or
not applying to any drivers still in modern use), which is why I was trying to
read the kernel source for where this flag is used internally (and finding too
many occurrences in too many drivers to wade through just then).

Next post I tracked down at least some commentary on what the open() behavior
change was (open itself on serial devices can indeed block, still not sure under
which circumstances) and this turns that into an error return instead. And
either it's not needed because minicom doesn't do it, or minicom should probably
also do it.

Implementation-wise this flag mostly just gets passed to drivers which act upon
it, I need to audit the Linux tty path (which I read a couple files into
yesterday to see what the SIGHUP was about, it's sent from
drivers/tty/tty_jobctrl.c function disassociate_ctty() by the way) and also
audit the current set of serial drivers, and THEN maybe I'd have proved a
negative. (Modulo https://landley.net/toybox/faq.html#support_horizon which is
currently... linux v3.10.)

But for the moment I'm probably just keeping that code with a TODO comment on it
about maybe not being of modern relevance? If I was just adding it I'd leave it
off and see who complained, but Elliott is sending me bugfixes for the version
in pending which implies somebody is using it?

It's not one of the special 'tread lightly' pending entries AOSP is already
using (all of which i should get cleaned up and promoted after sh.c and route.c):

  $ sed -n 's at .*pending/\([^.]*\).*@\1 at p' android/toybox/Android.bp | xargs
  dd diff expr getopt tr getfattr lsof modprobe more readelf stty traceroute vi

But it's not quite "rip the unexplained code out and hope for the best" either...

> Ariadne

Rob


More information about the Toybox mailing list