aboutsummaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
Diffstat (limited to 'libbb')
-rw-r--r--libbb/Kbuild1
-rw-r--r--libbb/appletlib.c42
-rw-r--r--libbb/error_msg_and_die.c27
-rw-r--r--libbb/getopt32.c17
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
101lib-y += xatonum.o 101lib-y += xatonum.o
102lib-y += xconnect.o 102lib-y += xconnect.o
103lib-y += xfuncs.o 103lib-y += xfuncs.o
104lib-y += xfunc_die.o
104lib-y += xgetcwd.o 105lib-y += xgetcwd.o
105lib-y += xgethostbyname.o 106lib-y += xgethostbyname.o
106lib-y += xreadlink.o 107lib-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)
77void bb_show_usage(void) 84void 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
126void lbb_prepare(const char *applet 149void lbb_prepare(const char *applet
127 USE_FEATURE_INDIVIDUAL(, char **argv)) 150 USE_FEATURE_INDIVIDUAL(, char **argv))
151 MAIN_EXTERNALLY_VISIBLE;
152void 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;
158bool re_execed; 184bool re_execed;
159#endif 185#endif
160 186
187
188#if !ENABLE_FEATURE_INDIVIDUAL
189
161USE_FEATURE_SUID(static uid_t ruid;) /* real uid */ 190USE_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
665int lbb_main(char **argv) 697int lbb_main(char **argv)
@@ -667,6 +699,11 @@ int lbb_main(char **argv)
667int main(int argc ATTRIBUTE_UNUSED, char **argv) 699int 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
12int die_sleep;
13#if ENABLE_FEATURE_PREFER_APPLETS || ENABLE_HUSH
14jmp_buf die_jmp;
15#endif
16
17void 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
39void bb_error_msg_and_die(const char *s, ...) 12void 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
286const char *opt_complementary; 286const 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
288enum { 292enum {
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