Last night I examined how getopt() is used.
Pseudo code would look something like this:
1) initialize optind to 0
2) run c = getopt_long() in a loop until c == -1
3) for every c set the relevant flags or execute a function, depending
on the value of c
That's perfectly fine, but when we pass, say, "-h" or "--help", most
commands don't loop until c == -1 in step 2, but simply stop the command
execution in step 3, before the next getopt() call.
Not letting getopt() reach -1 should also be fine, because optind is
used to store the state, and it is initialized in step 1, right?
Well, not quite. HelenOS ported getopt from BSD (and the rest of libc?).
There's a difference between POSIX and BSD implementation in getopt.
From the BSD getopt docs:
"In order to use getopt() to evaluate multiple sets of arguments, or to
evaluate a single set of arguments multiple times, the variable optreset
must be set to 1 before the second and each additional set of calls to
getopt(), and the variable optind must be reinitialized."
And later:
"The optreset variable was added to make itpossible to call the
getopt() function multiple times. This is an extension to the IEEE Std
1003.2 ('POSIX.2') specification."
Finally, possible solutions are:
a) Use getopt() like the docs suggest, and set optreset=1 in step 1,
along with optind=0.
b) Call getopt() until c==-1 in every case, without the "early" returns
when handling c.
c) Make optind==0 toggle an optreset=1 in getopt.c
d) Suggestions welcome!
a) and b) require changes in most bdsh commands, but a) is "the right"
thing to do, I think. c) requires change in one file, but is a "hack".
P.S. I wasn't sure where to post this, in the mailing list or the ticket
#506 comment. I was afraid that if I posted it in the comment, not all
people with the relevant experience might see it, so I could've
proceeded with a "bad" a)b)c) option.
_______________________________________________
HelenOS-devel mailing list
[email protected]
http://lists.modry.cz/listinfo/helenos-devel