Properly reset getopt in each invocation of getopt32() on BSD-type systems, including GNO and OS X.

Also, fix issue where callers of getopt32() weren't properly detecting errors on GNO due to a size mismatch.

This avoids strange behavior when commands using getopt32 (like export) are invoked multiple times, sometimes with invalid arguments.
This commit is contained in:
Stephen Heumann 2014-12-02 15:31:50 -06:00
parent 1ac41557b2
commit 52c59f6da1
2 changed files with 11 additions and 5 deletions

View File

@ -18,6 +18,10 @@
#endif #endif
#include "libbb.h" #include "libbb.h"
#ifdef __GNO__
extern int optreset; /* exists on GNO, but isn't in the header files */
#endif
/* Documentation /* Documentation
uint32_t uint32_t
@ -553,7 +557,9 @@ getopt32(char **argv, const char *applet_opts, ...)
optind = 0; optind = 0;
#else /* BSD style */ #else /* BSD style */
optind = 1; optind = 1;
/* optreset = 1; */ # ifdef BSD /* includes OS X and GNO */
optreset = 1;
# endif
#endif #endif
/* optarg = NULL; opterr = 0; optopt = 0; - do we need this?? */ /* optarg = NULL; opterr = 0; optopt = 0; - do we need this?? */

View File

@ -8886,7 +8886,7 @@ static void helper_export_local(char **argv, int exp, int lvl)
static int FAST_FUNC builtin_export(char **argv) static int FAST_FUNC builtin_export(char **argv)
{ {
unsigned opt_unexport; uint32_t opt_unexport;
#if ENABLE_HUSH_EXPORT_N #if ENABLE_HUSH_EXPORT_N
/* "!": do not abort on errors */ /* "!": do not abort on errors */
@ -9256,7 +9256,7 @@ static int FAST_FUNC builtin_read(char **argv)
char *opt_t = NULL; char *opt_t = NULL;
char *opt_u = NULL; char *opt_u = NULL;
const char *ifs; const char *ifs;
int read_flags; uint32_t read_flags;
/* "!": do not abort on errors. /* "!": do not abort on errors.
* Option string must start with "sr" to match BUILTIN_READ_xxx * Option string must start with "sr" to match BUILTIN_READ_xxx
@ -9484,12 +9484,12 @@ static int FAST_FUNC builtin_umask(char **argv)
static int FAST_FUNC builtin_unset(char **argv) static int FAST_FUNC builtin_unset(char **argv)
{ {
int ret; int ret;
unsigned opts; uint32_t opts;
/* "!": do not abort on errors */ /* "!": do not abort on errors */
/* "+": stop at 1st non-option */ /* "+": stop at 1st non-option */
opts = getopt32(argv, "!+vf"); opts = getopt32(argv, "!+vf");
if (opts == (unsigned)-1) if (opts == (uint32_t)-1)
return EXIT_FAILURE; return EXIT_FAILURE;
if (opts == 3) { if (opts == 3) {
bb_error_msg("unset: -v and -f are exclusive"); bb_error_msg("unset: -v and -f are exclusive");