getopt32 must remain NOFORK-safe (no mallocs!). Using alloca and pretending

stack is infinite. Unfortunately, +79 bytes.
This commit is contained in:
Denis Vlasenko 2007-07-23 17:40:35 +00:00
parent bdc88fdc68
commit 5bfcb4d5ae

View File

@ -307,7 +307,7 @@ getopt32(int argc, char **argv, const char *applet_opts, ...)
va_list p; va_list p;
#if ENABLE_GETOPT_LONG #if ENABLE_GETOPT_LONG
const struct option *l_o; const struct option *l_o;
struct option *long_options = NULL; struct option *long_options = (struct option *) &bb_null_long_options;
#endif #endif
unsigned trigger; unsigned trigger;
char **pargv = NULL; char **pargv = NULL;
@ -350,11 +350,11 @@ getopt32(int argc, char **argv, const char *applet_opts, ...)
count = 1; count = 1;
optstr = applet_long_options; optstr = applet_long_options;
while (optstr[0]) { while (optstr[0]) {
optstr += strlen(optstr) + 3; /* skip \0, has_arg, val */ optstr += strlen(optstr) + 3; /* skip NUL, has_arg, val */
count++; count++;
} }
/* count == no. of longopts + 1 */ /* count == no. of longopts + 1 */
long_options = xzalloc(count * sizeof(*long_options)); long_options = alloca(count * sizeof(*long_options));
i = 0; i = 0;
optstr = applet_long_options; optstr = applet_long_options;
while (--count) { while (--count) {
@ -476,7 +476,7 @@ getopt32(int argc, char **argv, const char *applet_opts, ...)
* (supposed to act as --header, but doesn't) */ * (supposed to act as --header, but doesn't) */
#if ENABLE_GETOPT_LONG #if ENABLE_GETOPT_LONG
while ((c = getopt_long(argc, argv, applet_opts, while ((c = getopt_long(argc, argv, applet_opts,
long_options ? long_options : bb_null_long_options, NULL)) != -1) { long_options, NULL)) != -1) {
#else #else
while ((c = getopt(argc, argv, applet_opts)) != -1) { while ((c = getopt(argc, argv, applet_opts)) != -1) {
#endif #endif
@ -535,9 +535,6 @@ getopt32(int argc, char **argv, const char *applet_opts, ...)
if (argc < min_arg || (max_arg >= 0 && argc > max_arg)) if (argc < min_arg || (max_arg >= 0 && argc > max_arg))
bb_show_usage(); bb_show_usage();
#if ENABLE_GETOPT_LONG
free(long_options);
#endif
option_mask32 = flags; option_mask32 = flags;
return flags; return flags;
} }