[Toybox] Shell Compatibility Reports from Oils - ~800 tests passing
Rob Landley
rob at landley.net
Tue Jul 8 15:04:26 PDT 2025
On 7/8/25 14:32, enh wrote:
> On Tue, Jul 1, 2025 at 1:52 PM Rob Landley <rob at landley.net> wrote:
>> That's not exactly how AOSP upstream does it, but was provably
>> equivalent. :)
Ahem, how LFS upstream did it...
>> separate issue. The above phone (not even one the cheap chinese ones) is
>> faster than my laptop and I do real work on it. (Although I did upgrade
>> my laptop's ram to 16tb, because I could.)
Ahem, 16gb.
(You can tell how sleep deprived I am sometimes. But at least I wasn't
saying busybox when I meant toybox and vice versa...)
>>>>> And between that, c11's __has_include(), and features.h you can
>>>>
>>>> it's been implemented by clang/gcc for a long time, but if you're
>>>> going to be a standards lawyer about it, __has_include() is c++17 and
>>>> c23.
>>
>> Sigh. Did one of the standards finally include gcc's empty ? : middle
>> argument? (Which I use all the time...)
>
> c23 does not include this, and i don't think i've seen a proposal to
> standardize it. +Alejandro Colomar pays more attention to wg14 though,
> so he might know better...
This is the problem I have with standards. In the GOOD ones things that
seem really obvious aren't included (posix still hasn't got mount and
refuses to acknowledge that removing "tar" was a mistake), and the bad
ones are full of things that clearly shouldn't be there. (LSB died
because Red Hat paying the Linux Foundation to mandate RPM cost it every
non-RPM distro from Debian to Arch.)
I first noticed the Linux kernel depending on "a ? : b" over 20 years
ago (and it wasn't new then, that's just when I noticed it), in part
because other compiler projects called it out as something they had to
add to get their non-gcc compiler to build and run Linux. (Generally one
of the easier things to add since it had just calculated the value and
had it right there, but still.)
In 2004 tccboot built linux 2.4.26 with tinycc
(https://bellard.org/tcc/tccboot_readme.html), Intel's ICC built Linux
somewhere around the same time (I miss when Google could find stuff:
https://lwn.net/Articles/320795/ is from 2009 but the comments are full
of people saying this is 5 years old, and I mentioned it as one of the
three known-to-work compilers in my 2008 BOF talk from ottawa linux
symposium a year earlier and I _think_ ICC got Linux running before
tinycc?), and LLVM built a working Linux kernel 2.6.36 at least by 2010
(https://lwn.net/Articles/411654).
All of that was before C11 came out in 2011, which is probably why I
assumed they were _aware_ of "a ? : b" existing and being necessary to
build Linux. Let alone C23.
This isn't even the kind of falling between the cracks of the "how do I
ask a FILE * how much readahead data is waiting in its buffer so I can
grab it without sucking more input from a potentially unseekable
filehandle I'm going to hand off to a syscall" problem, where posix said
"we don't have the concept of FILE * we're only filehandles" and the C
standards committee said "we don't have the concept of filehandles we're
only FILE *" and each side pointed fingers at the other to produce
conversion functions. Which is the main reason I haven't tackled "read"
in toysh yet:
$ echo $'one\ntwo\nthree\nfour\nfive' > seekable
$ { read i; echo a=$i; head -n 2; } < seekable
a=one
two
three
$ echo $'one\ntwo\nthree\nfour\nfive' | { read i; echo b=$i; head -n 2;}
b=one
two
three
If getline() sucks extra data into the FILE * buffer but I can't
fseek(ftell()) to rewind the underlying filehandle before doing an
exec("head") because the input is a pipe, how does the child command NOT
skip starting input? Bash is apparently getting this right, without
doing single byte reads to implement "read". Alas strace output on bash
is so thoroughly chaffed (thanks glibc) I haven't a clue how it's doing
that. I think I _did_ ask Chet and he said to do the fseek(ftell) thing,
except my notes say fseeko() and ftello() because large files... but how
does that work on a PIPE? Did the kernel do something REALLY WEIRD when
I wasn't looking? (Please tell me the parent process isn't SPINNING
READING the FILE * and writing to a second pipe. Urgh, now I've gotta
dig through my old notes and see where I left off on this, I thought
"support doing it right for seekable and drop data for pipes" was the
compromise bash was using but the test I just ran above contradicts
that, which may be because I'm misremembering and may be because it's a
newer bash version that changed its behavior...)
>> Sadly, standards remain a frame of reference to diverge from...
Grumble grumble...
For toybox the systems "real" enough to be worth supporting are
Linux/Android and FreeBSD/MacOS, plus stuff like QNX has done its own
support. But it doesn't matter how "posix" aix or solaris are (let alone
the kind of "posix" support S/390 and Windows NT once had) if they can't
keep up with the group. There is a de-facto standard going on, which
would be really nice if it was explicit, but isn't. (And when you look
closely the edges are all blurry judgement calls about "should" and
shift over time because they're not written down and everybody has
different opinions and implementing ps or route just sucks.)
The C compiler world is kind of the same, which is sad but not
surprising. (Did you know https://github.com/PortableCC/pcc moved to
github recently?) I've kinda been doing the same thing with busybox and
toybox vs util-linux and friends (and Rich has been doing with musl):
figure out what a critical mass of things actually use, support what you
can't come up with good workarounds for, and eventually if your
implementation gets widely used enough third parties start pushing sharp
edge removals out into the larger ecosystem with a convincing "this is a
big enough section of the potential userbase to care about".
Some years back I was eyeing man7.org as vaguely standard shaped, but it
fell into the "include everything" trap SO hard that right now
https://man7.org/linux/man-pages/dir_section_1.html reads along the top:
abicompat (funky obscure gnuism), gitweb (not part of ANY "base os"
definition), and pmdaoracle (for a proprietary database). The
interesting commands are drowned out in noise, and what's in even the
commands also often errs on the side of "kitchen sink".
As I said, "grumble". I would LOVE to conform to standards more, but
*gestures wildly above*. And I would love to PRODUCE something
standard-shaped, but that's a full time job just to do it wrong and a
red queen's race to stay merely out of date.
Rob
More information about the Toybox
mailing list