[Toybox] bug: commands with no options silently allow all options

Rob Landley rob at landley.net
Thu Mar 23 10:33:22 PDT 2017


On 03/22/2017 05:07 PM, enh wrote:
> On Tue, Mar 21, 2017 at 2:35 PM, Rob Landley <rob at landley.net> wrote:
>>> you could argue that you'll still get a _feature request_,
>>
>> Indeed. It'll not do what you want in a slightly different way. Both
>> ways seem obvious to me, but I may be too close to the problem.
> 
> i guess the useful example i've seen was that we eased the transition
> between toolbox and toybox ps because folks can try "ps -A || ps", but
> as the TL;DR version of your response would probably go "there aren't
> many useful commands that don't actually have any arguments". there
> are certainly a lot more that have weird ad-hoc argument parsing!

Eh, lots of 'em just want their argument list without checking for
flags. (Initially I just had it in argv[] so it was clear that argument
parsing hadn't been done, but that confused people so I changed it to
assign argv+1 to optc when the optstring is null (commit 4521f416ba84).)

And while I'm proud of my argument parsing logic and think it's a lot
more useful than getopt(), I can't make it do _everything_ without
making it turing complete. Even when it's used there's stuff like this
(from netcat_main) all oer the place:

  // The argument parsing logic can't make "<2" conditional on other
  // arguments like -f and -l, so we do it by hand here.
  if ((toys.optflags&FLAG_f) ? toys.optc :
      (!(toys.optflags&(FLAG_l|FLAG_L)) && toys.optc!=2))
        help_exit("bad argument count");

And then there's stuff like comma_args() (which is in lib/getmountlist.c
for historical reasons but probably shouldn't be) that's a separate
layer of generic option parsing logic, indepenent of lib/getargs.c.

What find.c is doing is weird and ad-hoc though. No way around it I
could spot. :P

Argument parsing is hard. And "xargs -1 ls" != "xargs ls -1" let alone
"xargs -n 3 ls -l"... And I still need to go back and add the bsd-style
unprefixed options to "ps", in part because I type "ps ax" by reflex and
it doesn't work. I just haven't added a way to distinguish the prefixed
from unprefixed flags yet, getting "tar xvzfC blah dir" working right
was one of my initial goals for lib/args.c back in 2007 (busybox thought
the argument to "f" was "C", maybe they've fixed it since, haven't
checked), but it doesn't report a _difference_ for "tar -xvzf blah -C
dir" because they don't mean something _different_. I suppose now that
optflags is 64 bit I could have 1<<63 mean that? Hmmm...

>> Anyway, new infrastructure to do what you asked for.
> 
> looking at the list, i think you're probably right that uptime was in
> a very small set of special cases.

Something like:

  ascii hello reset test_scankey clear false lsusb true w

Although the list of ones that don't care about _extra_ arguments is
probably much longer. (Well it wasn't hurting anything...)

>> --help always working is a much newer thing than unknown options
>> producing help output. :)
>>
>> But I can change it if you feel strongly about it.  Pretty much just a
>> global search and replace of help_exit with error_exit in lib/args.c.

I changed it.

>>> i _reduced_ the verbosity of adb's --help output... to 143 lines :-/
>>
>> Woo!
>>
>> Writing concise but informative help text is #*(%&# hard. For things
>> like "sed --help" I want the help to be standalone: you shouldn't need
>> to look at the posix spec or somebody else's man page to learn how to
>> use the command. But it's _tough_. I need to do another pass over "ps",
>> I don't think it includes all the -o options yet...
> 
> very occasionally i consider writing an apropos. but it feels weird
> somehow. even though i do sometimes find myself doing "grep -r" in the
> source. it seems like busybox never had one, so it's probably not
> useful enough?

The main problem with apropos is the conventional one consumes the
output of "updatedb", which is a horrible thing that does some sort of
find / on the whole system every night from cron, which meant that for
years every time you resumed a laptop it would start grinding the hard
drive for 15 minutes (or else it had run overnight and swapped
everything out so when you started up again it was really slow).

This made a lot of people just learn to live without it, because the
first thing you did on such a system was find and delete the updatedb
binary out of the $PATH.

The other problem is that nobody born after about 1970 ever learned
"tr", so busybox didn't have proper man page format handling for the
longest time. These days it has a wrapper calling out to other commands
(basically "zcat | tbl | nroff | less"), but I only just noticed that now.

(Mostly I just look at Michael Kerrisk's html versions on man7.org.)


>> I) It doesn't, it's already option parsing for --all so will reject
>> --walrus, it's just not doing ">0" in its option string.
>>
>> 2) I'm sort of amazed a command line option to do "X=$(((nproc)-24); [
>> $X -lt 1 ] && X=1" exists, but sure. (Does df have a similar --ignore
>> option to make filesystems look smaller?)
> 
> i think roughly 0 people know how to do arithmetic using just the
> shell...

I taught intro to unix at the local community college many moons ago,
those students knew it. :)

> and most of them have been involved in the development of at
> least one shell.

The $(( )) operator is posix. (There used to be $[ ] but then posix
standardized something other than what bash had been doing for years
because posix. Oh well.)

echo $((1+2<<3/4)) is a quite nice built in calculator, but I still fire
up python when I need floating point. I may do floating point in toysh's
version, not sure yet. (Pretty sure that's why it's not more widely used.)

Rob


More information about the Toybox mailing list