diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-08-04 16:46:17 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-08-04 16:46:17 +0200 |
commit | dd5a40246b91bd5d3d165998e6ac3cc4f7083f63 (patch) | |
tree | ffbd1f118040b36ae23f43d491bd8de097fd0843 /libbb | |
parent | 727948e585cb133c32c8d42570e5524c58190307 (diff) | |
download | busybox-w32-dd5a40246b91bd5d3d165998e6ac3cc4f7083f63.tar.gz busybox-w32-dd5a40246b91bd5d3d165998e6ac3cc4f7083f63.tar.bz2 busybox-w32-dd5a40246b91bd5d3d165998e6ac3cc4f7083f63.zip |
getopt32: move support for "always treat first arg as option" to users (tar/ar)
Now getopt() never leaks (and never performs) any xmalloc's.
function old new delta
ar_main 522 556 +34
tar_main 986 1014 +28
getopt32 1458 1350 -108
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/1 up/down: 62/-108) Total: -46 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'libbb')
-rw-r--r-- | libbb/getopt32.c | 36 |
1 files changed, 3 insertions, 33 deletions
diff --git a/libbb/getopt32.c b/libbb/getopt32.c index 129840cea..513415894 100644 --- a/libbb/getopt32.c +++ b/libbb/getopt32.c | |||
@@ -171,16 +171,6 @@ const char *opt_complementary | |||
171 | 171 | ||
172 | Special characters: | 172 | Special characters: |
173 | 173 | ||
174 | "--" A double dash at the beginning of opt_complementary means the | ||
175 | argv[1] string should always be treated as options, even if it isn't | ||
176 | prefixed with a "-". This is useful for special syntax in applets | ||
177 | such as "ar" and "tar": | ||
178 | tar xvf foo.tar | ||
179 | |||
180 | NB: getopt32() will leak a small amount of memory if you use | ||
181 | this option! Do not use it if there is a possibility of recursive | ||
182 | getopt32() calls. | ||
183 | |||
184 | "-N" A dash as the first char in a opt_complementary group followed | 174 | "-N" A dash as the first char in a opt_complementary group followed |
185 | by a single digit (0-9) means that at least N non-option | 175 | by a single digit (0-9) means that at least N non-option |
186 | arguments must be present on the command line | 176 | arguments must be present on the command line |
@@ -337,6 +327,8 @@ const char *applet_long_options; | |||
337 | 327 | ||
338 | uint32_t option_mask32; | 328 | uint32_t option_mask32; |
339 | 329 | ||
330 | /* Please keep getopt32 free from xmalloc */ | ||
331 | |||
340 | uint32_t FAST_FUNC | 332 | uint32_t FAST_FUNC |
341 | getopt32(char **argv, const char *applet_opts, ...) | 333 | getopt32(char **argv, const char *applet_opts, ...) |
342 | { | 334 | { |
@@ -354,12 +346,10 @@ getopt32(char **argv, const char *applet_opts, ...) | |||
354 | struct option *long_options = (struct option *) &bb_null_long_options; | 346 | struct option *long_options = (struct option *) &bb_null_long_options; |
355 | #endif | 347 | #endif |
356 | unsigned trigger; | 348 | unsigned trigger; |
357 | char **pargv; | ||
358 | int min_arg = 0; | 349 | int min_arg = 0; |
359 | int max_arg = -1; | 350 | int max_arg = -1; |
360 | 351 | ||
361 | #define SHOW_USAGE_IF_ERROR 1 | 352 | #define SHOW_USAGE_IF_ERROR 1 |
362 | #define FIRST_ARGV_IS_OPT 2 | ||
363 | 353 | ||
364 | int spec_flgs = 0; | 354 | int spec_flgs = 0; |
365 | 355 | ||
@@ -467,12 +457,7 @@ getopt32(char **argv, const char *applet_opts, ...) | |||
467 | continue; | 457 | continue; |
468 | } | 458 | } |
469 | if (*s == '-') { | 459 | if (*s == '-') { |
470 | if (c < '0' || c > '9') { | 460 | if (c >= '0' && c <= '9') { |
471 | if (c == '-') { | ||
472 | spec_flgs |= FIRST_ARGV_IS_OPT; | ||
473 | s++; | ||
474 | } | ||
475 | } else { | ||
476 | min_arg = c - '0'; | 461 | min_arg = c - '0'; |
477 | s++; | 462 | s++; |
478 | } | 463 | } |
@@ -535,21 +520,6 @@ getopt32(char **argv, const char *applet_opts, ...) | |||
535 | opt_complementary = NULL; | 520 | opt_complementary = NULL; |
536 | va_end(p); | 521 | va_end(p); |
537 | 522 | ||
538 | if (spec_flgs & FIRST_ARGV_IS_OPT) { | ||
539 | pargv = argv + 1; | ||
540 | if (*pargv) { | ||
541 | if (pargv[0][0] != '-' && pargv[0][0] != '\0') { | ||
542 | /* Can't use alloca: opts with params will | ||
543 | * return pointers to stack! | ||
544 | * NB: we leak these allocations... */ | ||
545 | char *pp = xmalloc(strlen(*pargv) + 2); | ||
546 | *pp = '-'; | ||
547 | strcpy(pp + 1, *pargv); | ||
548 | *pargv = pp; | ||
549 | } | ||
550 | } | ||
551 | } | ||
552 | |||
553 | /* In case getopt32 was already called: | 523 | /* In case getopt32 was already called: |
554 | * reset the libc getopt() function, which keeps internal state. | 524 | * reset the libc getopt() function, which keeps internal state. |
555 | * run_nofork_applet() does this, but we might end up here | 525 | * run_nofork_applet() does this, but we might end up here |