diff options
Diffstat (limited to 'libbb')
-rw-r--r-- | libbb/Kbuild | 1 | ||||
-rw-r--r-- | libbb/appletlib.c | 42 | ||||
-rw-r--r-- | libbb/error_msg_and_die.c | 27 | ||||
-rw-r--r-- | libbb/getopt32.c | 17 |
4 files changed, 55 insertions, 32 deletions
diff --git a/libbb/Kbuild b/libbb/Kbuild index 5740d9247..11ae10d7d 100644 --- a/libbb/Kbuild +++ b/libbb/Kbuild | |||
@@ -101,6 +101,7 @@ lib-y += wfopen_input.o | |||
101 | lib-y += xatonum.o | 101 | lib-y += xatonum.o |
102 | lib-y += xconnect.o | 102 | lib-y += xconnect.o |
103 | lib-y += xfuncs.o | 103 | lib-y += xfuncs.o |
104 | lib-y += xfunc_die.o | ||
104 | lib-y += xgetcwd.o | 105 | lib-y += xgetcwd.o |
105 | lib-y += xgethostbyname.o | 106 | lib-y += xgethostbyname.o |
106 | lib-y += xreadlink.o | 107 | lib-y += xreadlink.o |
diff --git a/libbb/appletlib.c b/libbb/appletlib.c index e2bb37868..a48a26003 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c | |||
@@ -36,6 +36,13 @@ static const char usage_messages[] ALIGN1 = "" | |||
36 | 36 | ||
37 | /* Include generated applet names, pointers to <applet>_main, etc */ | 37 | /* Include generated applet names, pointers to <applet>_main, etc */ |
38 | #include "applet_tables.h" | 38 | #include "applet_tables.h" |
39 | /* ...and if applet_tables generator says we have only one applet... */ | ||
40 | #ifdef SINGLE_APPLET_MAIN | ||
41 | #undef ENABLE_FEATURE_INDIVIDUAL | ||
42 | #define ENABLE_FEATURE_INDIVIDUAL 1 | ||
43 | #undef USE_FEATURE_INDIVIDUAL | ||
44 | #define USE_FEATURE_INDIVIDUAL(...) __VA_ARGS__ | ||
45 | #endif | ||
39 | 46 | ||
40 | 47 | ||
41 | #if ENABLE_FEATURE_COMPRESS_USAGE | 48 | #if ENABLE_FEATURE_COMPRESS_USAGE |
@@ -77,6 +84,23 @@ static const char *unpack_usage_messages(void) | |||
77 | void bb_show_usage(void) | 84 | void bb_show_usage(void) |
78 | { | 85 | { |
79 | if (ENABLE_SHOW_USAGE) { | 86 | if (ENABLE_SHOW_USAGE) { |
87 | #ifdef SINGLE_APPLET_STR | ||
88 | /* Imagine that this applet is "true". Dont suck in printf! */ | ||
89 | const char *p; | ||
90 | const char *usage_string = p = unpack_usage_messages(); | ||
91 | |||
92 | if (*p == '\b') { | ||
93 | write(2, "\nNo help available.\n\n", | ||
94 | sizeof("\nNo help available.\n\n") - 1); | ||
95 | } else { | ||
96 | write(2, "\nUsage: "SINGLE_APPLET_STR" ", | ||
97 | sizeof("\nUsage: "SINGLE_APPLET_STR" ") - 1); | ||
98 | write(2, p, strlen(p)); | ||
99 | write(2, "\n\n", 2); | ||
100 | } | ||
101 | dealloc_usage_messages((char*)usage_string); | ||
102 | #else | ||
103 | // TODO: in this case, stdio is sucked in by busybox_main() anyway... | ||
80 | const char *format_string; | 104 | const char *format_string; |
81 | const char *p; | 105 | const char *p; |
82 | const char *usage_string = p = unpack_usage_messages(); | 106 | const char *usage_string = p = unpack_usage_messages(); |
@@ -84,18 +108,17 @@ void bb_show_usage(void) | |||
84 | 108 | ||
85 | if (ap < 0) /* never happens, paranoia */ | 109 | if (ap < 0) /* never happens, paranoia */ |
86 | xfunc_die(); | 110 | xfunc_die(); |
87 | |||
88 | while (ap) { | 111 | while (ap) { |
89 | while (*p++) continue; | 112 | while (*p++) continue; |
90 | ap--; | 113 | ap--; |
91 | } | 114 | } |
92 | |||
93 | fprintf(stderr, "%s multi-call binary\n", bb_banner); | 115 | fprintf(stderr, "%s multi-call binary\n", bb_banner); |
94 | format_string = "\nUsage: %s %s\n\n"; | 116 | format_string = "\nUsage: %s %s\n\n"; |
95 | if (*p == '\b') | 117 | if (*p == '\b') |
96 | format_string = "\nNo help available.\n\n"; | 118 | format_string = "\nNo help available.\n\n"; |
97 | fprintf(stderr, format_string, applet_name, p); | 119 | fprintf(stderr, format_string, applet_name, p); |
98 | dealloc_usage_messages((char*)usage_string); | 120 | dealloc_usage_messages((char*)usage_string); |
121 | #endif | ||
99 | } | 122 | } |
100 | xfunc_die(); | 123 | xfunc_die(); |
101 | } | 124 | } |
@@ -125,6 +148,9 @@ int *const bb_errno __attribute__ ((section (".data"))); | |||
125 | 148 | ||
126 | void lbb_prepare(const char *applet | 149 | void lbb_prepare(const char *applet |
127 | USE_FEATURE_INDIVIDUAL(, char **argv)) | 150 | USE_FEATURE_INDIVIDUAL(, char **argv)) |
151 | MAIN_EXTERNALLY_VISIBLE; | ||
152 | void lbb_prepare(const char *applet | ||
153 | USE_FEATURE_INDIVIDUAL(, char **argv)) | ||
128 | { | 154 | { |
129 | #ifdef __GLIBC__ | 155 | #ifdef __GLIBC__ |
130 | (*(int **)&bb_errno) = __errno_location(); | 156 | (*(int **)&bb_errno) = __errno_location(); |
@@ -158,6 +184,9 @@ const char *applet_name; | |||
158 | bool re_execed; | 184 | bool re_execed; |
159 | #endif | 185 | #endif |
160 | 186 | ||
187 | |||
188 | #if !ENABLE_FEATURE_INDIVIDUAL | ||
189 | |||
161 | USE_FEATURE_SUID(static uid_t ruid;) /* real uid */ | 190 | USE_FEATURE_SUID(static uid_t ruid;) /* real uid */ |
162 | 191 | ||
163 | #if ENABLE_FEATURE_SUID_CONFIG | 192 | #if ENABLE_FEATURE_SUID_CONFIG |
@@ -660,6 +689,9 @@ void run_applet_and_exit(const char *name, char **argv) | |||
660 | exit(busybox_main(argv)); | 689 | exit(busybox_main(argv)); |
661 | } | 690 | } |
662 | 691 | ||
692 | #endif /* !ENABLE_FEATURE_INDIVIDUAL */ | ||
693 | |||
694 | |||
663 | 695 | ||
664 | #if ENABLE_BUILD_LIBBUSYBOX | 696 | #if ENABLE_BUILD_LIBBUSYBOX |
665 | int lbb_main(char **argv) | 697 | int lbb_main(char **argv) |
@@ -667,6 +699,11 @@ int lbb_main(char **argv) | |||
667 | int main(int argc ATTRIBUTE_UNUSED, char **argv) | 699 | int main(int argc ATTRIBUTE_UNUSED, char **argv) |
668 | #endif | 700 | #endif |
669 | { | 701 | { |
702 | #if ENABLE_FEATURE_INDIVIDUAL | ||
703 | /* Only one applet is selected by the user! */ | ||
704 | lbb_prepare(SINGLE_APPLET_STR USE_FEATURE_INDIVIDUAL(, argv)); | ||
705 | return SINGLE_APPLET_MAIN(argc, argv); | ||
706 | #else | ||
670 | lbb_prepare("busybox" USE_FEATURE_INDIVIDUAL(, argv)); | 707 | lbb_prepare("busybox" USE_FEATURE_INDIVIDUAL(, argv)); |
671 | 708 | ||
672 | #if !BB_MMU | 709 | #if !BB_MMU |
@@ -685,4 +722,5 @@ int main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
685 | 722 | ||
686 | run_applet_and_exit(applet_name, argv); | 723 | run_applet_and_exit(applet_name, argv); |
687 | bb_error_msg_and_die("applet not found"); | 724 | bb_error_msg_and_die("applet not found"); |
725 | #endif | ||
688 | } | 726 | } |
diff --git a/libbb/error_msg_and_die.c b/libbb/error_msg_and_die.c index 0e99a03cf..addd818b7 100644 --- a/libbb/error_msg_and_die.c +++ b/libbb/error_msg_and_die.c | |||
@@ -9,33 +9,6 @@ | |||
9 | 9 | ||
10 | #include "libbb.h" | 10 | #include "libbb.h" |
11 | 11 | ||
12 | int die_sleep; | ||
13 | #if ENABLE_FEATURE_PREFER_APPLETS || ENABLE_HUSH | ||
14 | jmp_buf die_jmp; | ||
15 | #endif | ||
16 | |||
17 | void xfunc_die(void) | ||
18 | { | ||
19 | if (die_sleep) { | ||
20 | if ((ENABLE_FEATURE_PREFER_APPLETS || ENABLE_HUSH) | ||
21 | && die_sleep < 0 | ||
22 | ) { | ||
23 | /* Special case. We arrive here if NOFORK applet | ||
24 | * calls xfunc, which then decides to die. | ||
25 | * We don't die, but jump instead back to caller. | ||
26 | * NOFORK applets still cannot carelessly call xfuncs: | ||
27 | * p = xmalloc(10); | ||
28 | * q = xmalloc(10); // BUG! if this dies, we leak p! | ||
29 | */ | ||
30 | /* -2222 means "zero" (longjmp can't pass 0) | ||
31 | * run_nofork_applet() catches -2222. */ | ||
32 | longjmp(die_jmp, xfunc_error_retval ? xfunc_error_retval : -2222); | ||
33 | } | ||
34 | sleep(die_sleep); | ||
35 | } | ||
36 | exit(xfunc_error_retval); | ||
37 | } | ||
38 | |||
39 | void bb_error_msg_and_die(const char *s, ...) | 12 | void bb_error_msg_and_die(const char *s, ...) |
40 | { | 13 | { |
41 | va_list p; | 14 | va_list p; |
diff --git a/libbb/getopt32.c b/libbb/getopt32.c index 51e030653..c0d885603 100644 --- a/libbb/getopt32.c +++ b/libbb/getopt32.c | |||
@@ -285,6 +285,10 @@ const char *const bb_argv_dash[] = { "-", NULL }; | |||
285 | 285 | ||
286 | const char *opt_complementary; | 286 | const char *opt_complementary; |
287 | 287 | ||
288 | /* Many small applets don't want to suck in stdio.h only because | ||
289 | * they need to parse options by calling us */ | ||
290 | #define DONT_USE_PRINTF 1 | ||
291 | |||
288 | enum { | 292 | enum { |
289 | PARAM_STRING, | 293 | PARAM_STRING, |
290 | PARAM_LIST, | 294 | PARAM_LIST, |
@@ -335,7 +339,8 @@ getopt32(char **argv, const char *applet_opts, ...) | |||
335 | #define SHOW_USAGE_IF_ERROR 1 | 339 | #define SHOW_USAGE_IF_ERROR 1 |
336 | #define ALL_ARGV_IS_OPTS 2 | 340 | #define ALL_ARGV_IS_OPTS 2 |
337 | #define FIRST_ARGV_IS_OPT 4 | 341 | #define FIRST_ARGV_IS_OPT 4 |
338 | #define FREE_FIRST_ARGV_IS_OPT 8 | 342 | #define FREE_FIRST_ARGV_IS_OPT (8 * !DONT_USE_PRINTF) |
343 | |||
339 | int spec_flgs = 0; | 344 | int spec_flgs = 0; |
340 | 345 | ||
341 | argc = 0; | 346 | argc = 0; |
@@ -489,10 +494,16 @@ getopt32(char **argv, const char *applet_opts, ...) | |||
489 | va_end(p); | 494 | va_end(p); |
490 | 495 | ||
491 | if (spec_flgs & FIRST_ARGV_IS_OPT) { | 496 | if (spec_flgs & FIRST_ARGV_IS_OPT) { |
492 | if (argv[1] && argv[1][0] != '-' && argv[1][0] != '\0') { | 497 | if (argv[1] && argv[1][0] != '-' && argv[1][1] != '\0') { |
498 | #if DONT_USE_PRINTF | ||
499 | char *pp = alloca(strlen(argv[1]) + 2); | ||
500 | *pp++ = '-'; | ||
501 | argv[1] = strcpy(pp, argv[1]); | ||
502 | #else | ||
493 | argv[1] = xasprintf("-%s", argv[1]); | 503 | argv[1] = xasprintf("-%s", argv[1]); |
494 | if (ENABLE_FEATURE_CLEAN_UP) | 504 | if (ENABLE_FEATURE_CLEAN_UP) |
495 | spec_flgs |= FREE_FIRST_ARGV_IS_OPT; | 505 | spec_flgs |= FREE_FIRST_ARGV_IS_OPT; |
506 | #endif | ||
496 | } | 507 | } |
497 | } | 508 | } |
498 | 509 | ||
@@ -573,7 +584,7 @@ getopt32(char **argv, const char *applet_opts, ...) | |||
573 | } | 584 | } |
574 | } | 585 | } |
575 | 586 | ||
576 | #if (ENABLE_AR || ENABLE_TAR) && ENABLE_FEATURE_CLEAN_UP | 587 | #if ENABLE_FEATURE_CLEAN_UP |
577 | if (spec_flgs & FREE_FIRST_ARGV_IS_OPT) | 588 | if (spec_flgs & FREE_FIRST_ARGV_IS_OPT) |
578 | free(argv[1]); | 589 | free(argv[1]); |
579 | #endif | 590 | #endif |