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

Rob Landley rob at landley.net
Mon Aug 17 01:16:18 PDT 2020


On 8/16/20 6:03 AM, Ariadne Conill wrote:
>> (Yes, I have a git tree back to 0.0.1, http://landley.net/kdocs/fullhist/)
> 
> Right.  Mainline Linux has never implemented streams.  I was just discussing why
> O_NONBLOCK is a thing to begin with, verses just using O_NDELAY in all cases. 

If posix called it O_NONBLOCK then it would be O_NONBLOCK in call cases.
O_NDELAY is exclusively pre-y2k legacy. Looks like pre-posix legacy, and
considering posix 1 came out in 1988 that's 32 years ago now.

I needed O_NONBLOCK in eject.c so it wouldn't wait to spin up the CDROM, the
horrible new dmesg api we switched to a couple years back needs it, modprobe and
rmmod use it... Having it makes sense, it's the using it for open then taking it
immediately off the resulting filehandle that's icky. Doing something then
immediately UNDOING it is weird.

> There is, however, a third-party implementation of streams for Linux that is
> used for some telecom software.
> 
>> I'm trying to figure out if modern Linux needs those two lines of code I posted.
> 
> It doesn't.

I'm not convinced yet. Speaking of microcom also needing it, turns out microcom
is already _doing_ it:

toys/net/microcom.c:  // Open with O_NDELAY, but switch back to blocking for reads.
toys/net/microcom.c:  TT.fd = xopen(*toys.optargs, O_RDWR | O_NOCTTY | O_NDELAY);
toys/net/microcom.c:  if (-1==(i = fcntl(TT.fd, F_GETFL, 0)) || fcntl(TT.fd,
F_SETFL, i&~O_NDELAY))

Just with a better comment, and using one name consistently rather than mixing
the two names for the same thing leading me to go "huh"?

That's the only other place in the tree using O_NDELAY, which says this was
samizdat cargo culting down to modern code without anybody ever questioning why
it's there. If it was intentional, they'd have said O_NONBLOCK.

>>> 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.
> 
> That is an interesting anecdote, I never knew that Linus used the Solaris manuals.

The book "just for fun" isn't exactly ghostwritten, it's a professional author
hanging out with Linus asking him about his history for a week or so, and then
writing the result up as a book which Linus then reviewed and approved as "his
story".

>> 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. :(
> 
> This is basically where I was going with this.  Most likely, that is the
> intention here: to get an O_NONBLOCK that behaves like legacy SysV O_NDELAY on
> SysV systems.

"This open should not block" isn't confusing, the confusing part is "why would
this open ever block? It is a serial port."

And it looks like "to fiddle with the dtr/dts rts/cts signals, which doesn't
time out sanely in some drivers if the modem on the other end is not responding
right" is why:

https://github.com/torvalds/linux/commit/4175f3e31cc7

Which... does anyone still own a modem? Anyone? I still have some ISA cards in a
box but not a computer they'd plug into.

> It is possible (likely, even) that early Linux contributors copied procedures
> that would have been appropriate on Solaris but in reality were a no-op on Linux
> due to following BSD semantics for O_NDELAY.

The userspace package porters were blindly copying, sure. Especially for
something like getty which very few linux systems ever actually used in a
nontrivial way.

The point of getty is to accept a login from a serial port on headless
minicomputers (usually shared between multiple people), but Linux was written
for PC which had screen and keyboard built in, logins were overwhelmingly local
(no local login mechanism connects to a serial port) and overwhelmingly single user.

You'd run daemons under other users, but those connected to the TCP/IP stack.
The big driver for Linux installs was running early webservers, where you must
have a network connection and can thus telnet in. Linux was first connected to
the internet in 1992 via a port of the KA9Q package:

  https://www.kclug.org/old_archives/linux-activists/1992/mar/2/0083.shtml
  https://www.kclug.org/old_archives/linux-activists/1992/mar/2/0014.shtml

But that was client only, linux didn't route yet. So linux was dialing _out_ to
do that...

After 1993 a few Linux machines were used in dialup ISPs, but most of that
plumbing was BSD or proprietary unix for the first few years, because if you're
spending $50/month per landline you can spring for money for a box to connect it
to. So there was maybe a 5 year window of relevance for getty in the ISP niche
between "linux is mature enough to get used for this" and DSL and cable modems
starting widespread deployment in 2000.

The OTHER reason that getty was useless after 1995 everybody had 9600 or 14.4k
modems with built-in data compression that you'd set your serial connect to at
38.4k or 57.6k respectively and LEAVE it there while the modem buffers the data
internally. So again, getty was irrelevant because you'd just use stty and the
connect straight to the port. So "rise of linux" and "availability of modem
hardware where what getty did was relevant in a context where anyone would be
logging into a linux machine via variable speed serial connection" was maybe a 3
year period around 1993-1996?

People continued to install getty out of historical inertia, but as far as I can
tell all it really does in 99.9% of deployments is prevent the login command
from timing out and cycling. And you could just as easily modify login to not
start a timeout until it gets some input.

>>> 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"?
> 
> So, basically during the UNIX wars,

You might want to read the historical appendices I wrote 15 years ago in:

  http://www.catb.org/~esr/halloween/halloween9.html#decline_and_fall

See also our response to paragraphs 43 (on the 86open project) and 47 (on the
Intel Binary Compatibility Standard):

  http://www.catb.org/~esr/halloween/halloween9.html#id2854686

Alas, you have to use archive.org to fish up http://www.telly.org/86open/ these
days.

I.E. I have great interest in computer history. I do not understand how what you
are saying is relevant in this context.

> both the BSD camp and AT&T implemented
> O_NDELAY, but differently.  POSIX standardized the BSD behavior and EWOULDBLOCK
> with it as O_NONBLOCK to solve the symbol collision.

Posix 1 came out in 1988. Linux came out in 1991. I am asking what Linux does.

> There is also the FIONBIO ioctl that is still around because of this, in SysV,
> FIONBIO worked on file descriptors that were not backed by a stream, while
> O_NDELAY was used with streams.  POSIX of course ensured that O_NONBLOCK worked
> for *all* cases.

The code I posted is using F_GETFL and F_SETFL to modify the file descriptor
flags. Linux has never had streams, and explicitly rejected an implementation of
them when it was offered many years ago.

>> 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.
> 
> On a system where O_NDELAY and O_NONBLOCK are the same,

Linux 0.0.1 and newer.

> the behavior change of
> course results in the file descriptor becoming blocking.

I did not ask about O_NDELAY. I always assumed it's a synonym for O_NONBLOCK
because the last time it was anything else I was still using I was using a
commodore amiga.

>> 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).
> 
> On Linux, as previously mentioned you just wind up with a non-blocking FD as you
> already know.

Yes. I was asking about Linux. This is a Linux project.

And on LINUX a non-blocking open of a serial port prevents waiting for hardware
flow control signals to be acknowledged before returning the file descriptor,
which can happen if the serial port has been unplugged leading to the open()
blocking until the modem is plugged back in.

However, while https://linux.die.net/man/1/stty (describing a coreutils version
copyright 2010) lists -cdtrdsr the current debian stty man page (coreutils 8.26
copyright 2016) does NOT, which implies the feature was removed or configured
out from modern distros. I haven't bisected the coreutils repo to see what
happened yet, I'm more interested in the drivers and the tty layer.

It MIGHT also involve the "exclusivity" stuff from the stackoverload link I
posted, haven't tested yet...

> On SysV though,

Not the question I'm asking.

> If I were to guess, this was a workaround for some bug in the SysV kernel and

Not the question I'm asking.

>> But it's not quite "rip the unexplained code out and hope for the best" either...
> 
> I would say it is likely safe to rip out the code.  But as you mention, it is
> probably best to verify that the tty subsystem is behaving sanely first.

Ok.

> Ariadne

Rob


More information about the Toybox mailing list