diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-01-28 22:57:10 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-01-28 22:57:10 +0000 |
commit | 9772816570f0a63ac301f1885292b064e23f5310 (patch) | |
tree | a8e9c2947cd4dbc718989d508dfc742840a16e81 /libbb/getopt32.c | |
parent | 73032ca04be49c096f745f0873d67d9c831642bd (diff) | |
download | busybox-w32-9772816570f0a63ac301f1885292b064e23f5310.tar.gz busybox-w32-9772816570f0a63ac301f1885292b064e23f5310.tar.bz2 busybox-w32-9772816570f0a63ac301f1885292b064e23f5310.zip |
*: move getopt reset code to better place(s)
Diffstat (limited to 'libbb/getopt32.c')
-rw-r--r-- | libbb/getopt32.c | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/libbb/getopt32.c b/libbb/getopt32.c index 2452eb0a5..80d5d2822 100644 --- a/libbb/getopt32.c +++ b/libbb/getopt32.c | |||
@@ -473,11 +473,30 @@ getopt32(char **argv, const char *applet_opts, ...) | |||
473 | } | 473 | } |
474 | } | 474 | } |
475 | 475 | ||
476 | /* In case getopt32 was already called, reinit some state */ | 476 | /* In case getopt32 was already called: |
477 | * reset the libc getopt() function, which keeps internal state. | ||
478 | * | ||
479 | * BSD-derived getopt() functions require that optind be set to 1 in | ||
480 | * order to reset getopt() state. This used to be generally accepted | ||
481 | * way of resetting getopt(). However, glibc's getopt() | ||
482 | * has additional getopt() state beyond optind, and requires that | ||
483 | * optind be set to zero to reset its state. So the unfortunate state of | ||
484 | * affairs is that BSD-derived versions of getopt() misbehave if | ||
485 | * optind is set to 0 in order to reset getopt(), and glibc's getopt() | ||
486 | * will core dump if optind is set 1 in order to reset getopt(). | ||
487 | * | ||
488 | * More modern versions of BSD require that optreset be set to 1 in | ||
489 | * order to reset getopt(). Sigh. Standards, anyone? | ||
490 | */ | ||
491 | #ifdef __GLIBC__ | ||
492 | optind = 0; | ||
493 | #else /* BSD style */ | ||
477 | optind = 1; | 494 | optind = 1; |
478 | /* optarg = NULL; opterr = 0; optopt = 0; ?? */ | 495 | /* optreset = 1; */ |
496 | #endif | ||
497 | /* optarg = NULL; opterr = 0; optopt = 0; - do we need this?? */ | ||
479 | 498 | ||
480 | /* Note: just "getopt() <= 0" will not work good for | 499 | /* Note: just "getopt() <= 0" will not work well for |
481 | * "fake" short options, like this one: | 500 | * "fake" short options, like this one: |
482 | * wget $'-\203' "Test: test" http://kernel.org/ | 501 | * wget $'-\203' "Test: test" http://kernel.org/ |
483 | * (supposed to act as --header, but doesn't) */ | 502 | * (supposed to act as --header, but doesn't) */ |
@@ -487,7 +506,7 @@ getopt32(char **argv, const char *applet_opts, ...) | |||
487 | #else | 506 | #else |
488 | while ((c = getopt(argc, argv, applet_opts)) != -1) { | 507 | while ((c = getopt(argc, argv, applet_opts)) != -1) { |
489 | #endif | 508 | #endif |
490 | c &= 0xff; /* fight libc's sign extends */ | 509 | c &= 0xff; /* fight libc's sign extension */ |
491 | loop_arg_is_opt: | 510 | loop_arg_is_opt: |
492 | for (on_off = complementary; on_off->opt != c; on_off++) { | 511 | for (on_off = complementary; on_off->opt != c; on_off++) { |
493 | /* c==0 if long opt have non NULL flag */ | 512 | /* c==0 if long opt have non NULL flag */ |