Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date: Thu, 11 Apr 2024 10:24:56 -0400
From: Rich Felker <dalias@...c.org>
To: musl@...ts.openwall.com
Subject: making termios BOTHER speeds work

Since it's come up again, I'm looking at what it would take to get
support for custom baud rates in termios working. This topic is
something of a mess, as it involves discrepancies between our termios
structure and the kernel termios/termios2 structures.

Szabolcs Nagy did some of the initial research on the mismatched
definitions in 2016: https://www.openwall.com/lists/musl/2016/04/26/3

Basically, it looks like what happened was that we tried to match the
glibc generic ABI (an early goal of lots of stuff in musl) as long as
it lined up with the kernel termios (not termios2) ioctl structure,
but deviated when it wouldn't (powerpc had c_line and c_cc order
flipped and we followed kernel on that), and didn't do glibc
arch-specific mistakes (like mips omitting the __c_[io]speed fields).

If we had used the kernel value of NCCS everywhere, rather than the
inflated glibc value of 32, we could add BOTHER support just by
attempting TCSETS2 using the caller's termios structure, and only
falling back if it doesn't work. In theory we *could* change to do
this now. The __c_[io]speed members are not in the public namespace,
and NCCS could be reduced to accommodate them as long as the overall
struct size was preserved. This might be ~ugly~ for programs built
with the old NCCS of 32, which might copy c_cc past its new end, but
they'd just be moving stuff to/from the reserved speed fields they
couldn't yet be using. The worst part about this seems to be that we'd
be introducing more arch-specific versions of bits/termios.h, since
the "generic" definition we have now actually has different layout
depending on the arch's alignment requirements. I think this only
affects m68k (where it's 2 rather than 4 byte alignment for int), so
maybe it's not a big deal to add just one.

The alternative is to only use the caller-provided termios in-place in
the case where we can get by without termios2 interfaces: that is,
when either BOTHER is not set (classic POSIX baud flags), or TCSETS2
is not defined (plain termios already supports BOTHER for this arch).
Otherwise, translate to a kernel termios2 form, which really requires
nothing other than knowing an arch-defined offset for the speed
fields.

For going the other direction (tcgetattr) it's even easier: we're
allowed to clobber the caller buffer, so just try TCGETS2 and move the
speeds from their kernel offset into the libc member offsset.

I think this second approach is probably better, but I'm open to
reasons why it might not be.

Rich

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.