diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-11-28 06:49:03 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-11-28 06:49:03 +0000 |
commit | 1aa7e477b1b727db77cac2d717f0fcca40587f78 (patch) | |
tree | 247171517f0e01d32a71a5e96f4bef462cc0e9c6 /libbb | |
parent | 79c6904faff1ebd4bf4b7d9cd0c20ca70f4cec75 (diff) | |
download | busybox-w32-1aa7e477b1b727db77cac2d717f0fcca40587f78.tar.gz busybox-w32-1aa7e477b1b727db77cac2d717f0fcca40587f78.tar.bz2 busybox-w32-1aa7e477b1b727db77cac2d717f0fcca40587f78.zip |
reorganize applet table. Eliminates pointers to names.
Should be a big win for libbusybox. busybox wins too:
text data bss dec hex filename
776524 929 9100 786553 c0079 busybox_old
775903 929 9100 785932 bfe0c busybox_unstripped
Diffstat (limited to 'libbb')
-rw-r--r-- | libbb/appletlib.c | 87 | ||||
-rw-r--r-- | libbb/execable.c | 2 | ||||
-rw-r--r-- | libbb/vfork_daemon_rexec.c | 22 |
3 files changed, 55 insertions, 56 deletions
diff --git a/libbb/appletlib.c b/libbb/appletlib.c index 4bd60d049..dcf24f5a9 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c | |||
@@ -33,13 +33,9 @@ static const char usage_messages[] ALIGN1 = "" | |||
33 | #define usage_messages 0 | 33 | #define usage_messages 0 |
34 | #endif /* SHOW_USAGE */ | 34 | #endif /* SHOW_USAGE */ |
35 | 35 | ||
36 | /* Define struct bb_applet applets[] */ | ||
37 | #include "applets.h" | ||
38 | 36 | ||
39 | #if ENABLE_FEATURE_SH_STANDALONE | 37 | /* Include generated applet names, pointers to <apllet>_main, etc */ |
40 | /* -1 because last entry is NULL */ | 38 | #include "applet_tables.h" |
41 | const unsigned short NUM_APPLETS = ARRAY_SIZE(applets) - 1; | ||
42 | #endif | ||
43 | 39 | ||
44 | 40 | ||
45 | #if ENABLE_FEATURE_COMPRESS_USAGE | 41 | #if ENABLE_FEATURE_COMPRESS_USAGE |
@@ -84,16 +80,14 @@ void bb_show_usage(void) | |||
84 | const char *format_string; | 80 | const char *format_string; |
85 | const char *p; | 81 | const char *p; |
86 | const char *usage_string = p = unpack_usage_messages(); | 82 | const char *usage_string = p = unpack_usage_messages(); |
87 | const struct bb_applet *ap = find_applet_by_name(applet_name); | 83 | int ap = find_applet_by_name(applet_name); |
88 | int i; | ||
89 | 84 | ||
90 | if (!ap) /* never happens, paranoia */ | 85 | if (ap < 0) /* never happens, paranoia */ |
91 | xfunc_die(); | 86 | xfunc_die(); |
92 | 87 | ||
93 | i = ap - applets; | 88 | while (ap) { |
94 | while (i) { | ||
95 | while (*p++) continue; | 89 | while (*p++) continue; |
96 | i--; | 90 | ap--; |
97 | } | 91 | } |
98 | 92 | ||
99 | fprintf(stderr, "%s multi-call binary\n", bb_banner); | 93 | fprintf(stderr, "%s multi-call binary\n", bb_banner); |
@@ -107,18 +101,22 @@ void bb_show_usage(void) | |||
107 | } | 101 | } |
108 | 102 | ||
109 | 103 | ||
110 | static int applet_name_compare(const void *name, const void *vapplet) | 104 | static int applet_name_compare(const void *name, const void *v) |
111 | { | 105 | { |
112 | const struct bb_applet *applet = vapplet; | 106 | int i = (const char *)v - applet_names; |
113 | 107 | return strcmp(name, APPLET_NAME(i)); | |
114 | return strcmp(name, applet->name); | ||
115 | } | 108 | } |
116 | 109 | ||
117 | const struct bb_applet *find_applet_by_name(const char *name) | 110 | int find_applet_by_name(const char *name) |
118 | { | 111 | { |
112 | const char *p; | ||
119 | /* Do a binary search to find the applet entry given the name. */ | 113 | /* Do a binary search to find the applet entry given the name. */ |
120 | return bsearch(name, applets, ARRAY_SIZE(applets)-1, sizeof(applets[0]), | 114 | |
121 | applet_name_compare); | 115 | /* NB: any char pointer will work as well, not necessarily applet_names */ |
116 | p = bsearch(name, applet_names, ARRAY_SIZE(applet_mains), 1, applet_name_compare); | ||
117 | if (!p) | ||
118 | return -1; | ||
119 | return p - applet_names; | ||
122 | } | 120 | } |
123 | 121 | ||
124 | 122 | ||
@@ -166,7 +164,7 @@ USE_FEATURE_SUID(static uid_t ruid;) /* real uid */ | |||
166 | 164 | ||
167 | /* applets[] is const, so we have to define this "override" structure */ | 165 | /* applets[] is const, so we have to define this "override" structure */ |
168 | static struct BB_suid_config { | 166 | static struct BB_suid_config { |
169 | const struct bb_applet *m_applet; | 167 | int m_applet; |
170 | uid_t m_uid; | 168 | uid_t m_uid; |
171 | gid_t m_gid; | 169 | gid_t m_gid; |
172 | mode_t m_mode; | 170 | mode_t m_mode; |
@@ -232,7 +230,7 @@ static void parse_config_file(void) | |||
232 | { | 230 | { |
233 | struct BB_suid_config *sct_head; | 231 | struct BB_suid_config *sct_head; |
234 | struct BB_suid_config *sct; | 232 | struct BB_suid_config *sct; |
235 | const struct bb_applet *applet; | 233 | int applet_no; |
236 | FILE *f; | 234 | FILE *f; |
237 | const char *errmsg; | 235 | const char *errmsg; |
238 | char *s; | 236 | char *s; |
@@ -343,14 +341,14 @@ static void parse_config_file(void) | |||
343 | * applet is currently built in and ignore it otherwise. | 341 | * applet is currently built in and ignore it otherwise. |
344 | * Note: this can hide config file bugs which only pop | 342 | * Note: this can hide config file bugs which only pop |
345 | * up when the busybox configuration is changed. */ | 343 | * up when the busybox configuration is changed. */ |
346 | applet = find_applet_by_name(s); | 344 | applet_no = find_applet_by_name(s); |
347 | if (applet) { | 345 | if (applet_no >= 0) { |
348 | /* Note: We currently don't check for duplicates! | 346 | /* Note: We currently don't check for duplicates! |
349 | * The last config line for each applet will be the | 347 | * The last config line for each applet will be the |
350 | * one used since we insert at the head of the list. | 348 | * one used since we insert at the head of the list. |
351 | * I suppose this could be considered a feature. */ | 349 | * I suppose this could be considered a feature. */ |
352 | sct = xmalloc(sizeof(struct BB_suid_config)); | 350 | sct = xmalloc(sizeof(struct BB_suid_config)); |
353 | sct->m_applet = applet; | 351 | sct->m_applet = applet_no; |
354 | sct->m_mode = 0; | 352 | sct->m_mode = 0; |
355 | sct->m_next = sct_head; | 353 | sct->m_next = sct_head; |
356 | sct_head = sct; | 354 | sct_head = sct; |
@@ -441,7 +439,7 @@ static inline void parse_config_file(void) | |||
441 | 439 | ||
442 | 440 | ||
443 | #if ENABLE_FEATURE_SUID | 441 | #if ENABLE_FEATURE_SUID |
444 | static void check_suid(const struct bb_applet *applet) | 442 | static void check_suid(int applet_no) |
445 | { | 443 | { |
446 | gid_t rgid; /* real gid */ | 444 | gid_t rgid; /* real gid */ |
447 | 445 | ||
@@ -456,7 +454,7 @@ static void check_suid(const struct bb_applet *applet) | |||
456 | mode_t m; | 454 | mode_t m; |
457 | 455 | ||
458 | for (sct = suid_config; sct; sct = sct->m_next) { | 456 | for (sct = suid_config; sct; sct = sct->m_next) { |
459 | if (sct->m_applet == applet) | 457 | if (sct->m_applet == applet_no) |
460 | goto found; | 458 | goto found; |
461 | } | 459 | } |
462 | goto check_need_suid; | 460 | goto check_need_suid; |
@@ -504,12 +502,12 @@ static void check_suid(const struct bb_applet *applet) | |||
504 | #endif | 502 | #endif |
505 | check_need_suid: | 503 | check_need_suid: |
506 | #endif | 504 | #endif |
507 | if (applet->need_suid == _BB_SUID_ALWAYS) { | 505 | if (APPLET_SUID(applet_no) == _BB_SUID_ALWAYS) { |
508 | /* Real uid is not 0. If euid isn't 0 too, suid bit | 506 | /* Real uid is not 0. If euid isn't 0 too, suid bit |
509 | * is most probably not set on our executable */ | 507 | * is most probably not set on our executable */ |
510 | if (geteuid()) | 508 | if (geteuid()) |
511 | bb_error_msg_and_die("must be suid to work properly"); | 509 | bb_error_msg_and_die("must be suid to work properly"); |
512 | } else if (applet->need_suid == _BB_SUID_NEVER) { | 510 | } else if (APPLET_SUID(applet_no) == _BB_SUID_NEVER) { |
513 | xsetgid(rgid); /* drop all privileges */ | 511 | xsetgid(rgid); /* drop all privileges */ |
514 | xsetuid(ruid); | 512 | xsetuid(ruid); |
515 | } | 513 | } |
@@ -536,18 +534,19 @@ static void install_links(const char *busybox, int use_symbolic_links) | |||
536 | usr_sbin | 534 | usr_sbin |
537 | }; | 535 | }; |
538 | 536 | ||
539 | int (*lf)(const char *, const char *) = link; | 537 | int (*lf)(const char *, const char *); |
540 | char *fpc; | 538 | char *fpc; |
541 | int i; | 539 | int i; |
542 | int rc; | 540 | int rc; |
543 | 541 | ||
542 | lf = link; | ||
544 | if (use_symbolic_links) | 543 | if (use_symbolic_links) |
545 | lf = symlink; | 544 | lf = symlink; |
546 | 545 | ||
547 | for (i = 0; applets[i].name != NULL; i++) { | 546 | for (i = 0; i < ARRAY_SIZE(applet_mains); i++) { |
548 | fpc = concat_path_file( | 547 | fpc = concat_path_file( |
549 | install_dir[applets[i].install_loc], | 548 | install_dir[APPLET_INSTALL_LOC(i)], |
550 | applets[i].name); | 549 | APPLET_NAME(i)); |
551 | rc = lf(busybox, fpc); | 550 | rc = lf(busybox, fpc); |
552 | if (rc != 0 && errno != EEXIST) { | 551 | if (rc != 0 && errno != EEXIST) { |
553 | bb_simple_perror_msg(fpc); | 552 | bb_simple_perror_msg(fpc); |
@@ -564,7 +563,7 @@ static int busybox_main(char **argv) | |||
564 | { | 563 | { |
565 | if (!argv[1]) { | 564 | if (!argv[1]) { |
566 | /* Called without arguments */ | 565 | /* Called without arguments */ |
567 | const struct bb_applet *a; | 566 | const char *a; |
568 | int col, output_width; | 567 | int col, output_width; |
569 | help: | 568 | help: |
570 | output_width = 80; | 569 | output_width = 80; |
@@ -588,14 +587,14 @@ static int busybox_main(char **argv) | |||
588 | "\twill act like whatever it was invoked as!\n" | 587 | "\twill act like whatever it was invoked as!\n" |
589 | "\nCurrently defined functions:\n"); | 588 | "\nCurrently defined functions:\n"); |
590 | col = 0; | 589 | col = 0; |
591 | a = applets; | 590 | a = applet_names; |
592 | while (a->name) { | 591 | while (*a) { |
593 | if (col > output_width) { | 592 | if (col > output_width) { |
594 | puts(","); | 593 | puts(","); |
595 | col = 0; | 594 | col = 0; |
596 | } | 595 | } |
597 | col += printf("%s%s", (col ? ", " : "\t"), a->name); | 596 | col += printf("%s%s", (col ? ", " : "\t"), a); |
598 | a++; | 597 | a += strlen(a) + 1; |
599 | } | 598 | } |
600 | puts("\n"); | 599 | puts("\n"); |
601 | return 0; | 600 | return 0; |
@@ -629,7 +628,7 @@ static int busybox_main(char **argv) | |||
629 | bb_error_msg_and_die("applet not found"); | 628 | bb_error_msg_and_die("applet not found"); |
630 | } | 629 | } |
631 | 630 | ||
632 | void run_appletstruct_and_exit(const struct bb_applet *applet, char **argv) | 631 | void run_applet_no_and_exit(int applet_no, char **argv) |
633 | { | 632 | { |
634 | int argc = 1; | 633 | int argc = 1; |
635 | 634 | ||
@@ -640,19 +639,19 @@ void run_appletstruct_and_exit(const struct bb_applet *applet, char **argv) | |||
640 | optind = 1; | 639 | optind = 1; |
641 | xfunc_error_retval = EXIT_FAILURE; | 640 | xfunc_error_retval = EXIT_FAILURE; |
642 | 641 | ||
643 | applet_name = applet->name; | 642 | applet_name = APPLET_NAME(applet_no); |
644 | if (argc == 2 && !strcmp(argv[1], "--help")) | 643 | if (argc == 2 && !strcmp(argv[1], "--help")) |
645 | bb_show_usage(); | 644 | bb_show_usage(); |
646 | if (ENABLE_FEATURE_SUID) | 645 | if (ENABLE_FEATURE_SUID) |
647 | check_suid(applet); | 646 | check_suid(applet_no); |
648 | exit(applet->main(argc, argv)); | 647 | exit(applet_mains[applet_no](argc, argv)); |
649 | } | 648 | } |
650 | 649 | ||
651 | void run_applet_and_exit(const char *name, char **argv) | 650 | void run_applet_and_exit(const char *name, char **argv) |
652 | { | 651 | { |
653 | const struct bb_applet *applet = find_applet_by_name(name); | 652 | int applet = find_applet_by_name(name); |
654 | if (applet) | 653 | if (applet >= 0) |
655 | run_appletstruct_and_exit(applet, argv); | 654 | run_applet_no_and_exit(applet, argv); |
656 | if (!strncmp(name, "busybox", 7)) | 655 | if (!strncmp(name, "busybox", 7)) |
657 | exit(busybox_main(argv)); | 656 | exit(busybox_main(argv)); |
658 | } | 657 | } |
diff --git a/libbb/execable.c b/libbb/execable.c index f679108be..2649a6cfe 100644 --- a/libbb/execable.c +++ b/libbb/execable.c | |||
@@ -65,7 +65,7 @@ int exists_execable(const char *filename) | |||
65 | */ | 65 | */ |
66 | int bb_execvp(const char *file, char *const argv[]) | 66 | int bb_execvp(const char *file, char *const argv[]) |
67 | { | 67 | { |
68 | return execvp(find_applet_by_name(file) ? bb_busybox_exec_path : file, | 68 | return execvp(find_applet_by_name(file) >= 0 ? bb_busybox_exec_path : file, |
69 | argv); | 69 | argv); |
70 | } | 70 | } |
71 | #endif | 71 | #endif |
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c index a01065d69..1d6817ee6 100644 --- a/libbb/vfork_daemon_rexec.c +++ b/libbb/vfork_daemon_rexec.c | |||
@@ -16,7 +16,7 @@ | |||
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <paths.h> | 18 | #include <paths.h> |
19 | #include "busybox.h" /* for struct bb_applet */ | 19 | #include "busybox.h" /* uses applet tables */ |
20 | 20 | ||
21 | /* This does a fork/exec in one call, using vfork(). Returns PID of new child, | 21 | /* This does a fork/exec in one call, using vfork(). Returns PID of new child, |
22 | * -1 for failure. Runs argv[0], searching path if that has no / in it. */ | 22 | * -1 for failure. Runs argv[0], searching path if that has no / in it. */ |
@@ -120,11 +120,11 @@ void restore_nofork_data(struct nofork_save_area *save) | |||
120 | die_sleep = save->die_sleep; | 120 | die_sleep = save->die_sleep; |
121 | } | 121 | } |
122 | 122 | ||
123 | int run_nofork_applet_prime(struct nofork_save_area *old, const struct bb_applet *a, char **argv) | 123 | int run_nofork_applet_prime(struct nofork_save_area *old, int applet_no, char **argv) |
124 | { | 124 | { |
125 | int rc, argc; | 125 | int rc, argc; |
126 | 126 | ||
127 | applet_name = a->name; | 127 | applet_name = APPLET_NAME(applet_no); |
128 | xfunc_error_retval = EXIT_FAILURE; | 128 | xfunc_error_retval = EXIT_FAILURE; |
129 | /*option_mask32 = 0; - not needed */ | 129 | /*option_mask32 = 0; - not needed */ |
130 | /* special flag for xfunc_die(). If xfunc will "die" | 130 | /* special flag for xfunc_die(). If xfunc will "die" |
@@ -143,7 +143,7 @@ int run_nofork_applet_prime(struct nofork_save_area *old, const struct bb_applet | |||
143 | char *tmp_argv[argc+1]; | 143 | char *tmp_argv[argc+1]; |
144 | memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0])); | 144 | memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0])); |
145 | /* Finally we can call NOFORK applet's main() */ | 145 | /* Finally we can call NOFORK applet's main() */ |
146 | rc = a->main(argc, tmp_argv); | 146 | rc = applet_mains[applet_no](argc, tmp_argv); |
147 | } else { /* xfunc died in NOFORK applet */ | 147 | } else { /* xfunc died in NOFORK applet */ |
148 | /* in case they meant to return 0... */ | 148 | /* in case they meant to return 0... */ |
149 | if (rc == -2222) | 149 | if (rc == -2222) |
@@ -155,13 +155,13 @@ int run_nofork_applet_prime(struct nofork_save_area *old, const struct bb_applet | |||
155 | return rc; | 155 | return rc; |
156 | } | 156 | } |
157 | 157 | ||
158 | int run_nofork_applet(const struct bb_applet *a, char **argv) | 158 | int run_nofork_applet(int applet_no, char **argv) |
159 | { | 159 | { |
160 | struct nofork_save_area old; | 160 | struct nofork_save_area old; |
161 | 161 | ||
162 | /* Saving globals */ | 162 | /* Saving globals */ |
163 | save_nofork_data(&old); | 163 | save_nofork_data(&old); |
164 | return run_nofork_applet_prime(&old, a, argv); | 164 | return run_nofork_applet_prime(&old, applet_no, argv); |
165 | } | 165 | } |
166 | #endif /* FEATURE_PREFER_APPLETS */ | 166 | #endif /* FEATURE_PREFER_APPLETS */ |
167 | 167 | ||
@@ -169,15 +169,15 @@ int spawn_and_wait(char **argv) | |||
169 | { | 169 | { |
170 | int rc; | 170 | int rc; |
171 | #if ENABLE_FEATURE_PREFER_APPLETS | 171 | #if ENABLE_FEATURE_PREFER_APPLETS |
172 | const struct bb_applet *a = find_applet_by_name(argv[0]); | 172 | int a = find_applet_by_name(argv[0]); |
173 | 173 | ||
174 | if (a && (a->nofork | 174 | if (a >= 0 && (APPLET_IS_NOFORK(a) |
175 | #if BB_MMU | 175 | #if BB_MMU |
176 | || a->noexec /* NOEXEC trick needs fork() */ | 176 | || APPLET_IS_NOEXEC(a) /* NOEXEC trick needs fork() */ |
177 | #endif | 177 | #endif |
178 | )) { | 178 | )) { |
179 | #if BB_MMU | 179 | #if BB_MMU |
180 | if (a->nofork) | 180 | if (APPLET_IS_NOFORK(a)) |
181 | #endif | 181 | #endif |
182 | { | 182 | { |
183 | return run_nofork_applet(a, argv); | 183 | return run_nofork_applet(a, argv); |
@@ -190,7 +190,7 @@ int spawn_and_wait(char **argv) | |||
190 | return wait4pid(rc); | 190 | return wait4pid(rc); |
191 | /* child */ | 191 | /* child */ |
192 | xfunc_error_retval = EXIT_FAILURE; | 192 | xfunc_error_retval = EXIT_FAILURE; |
193 | run_appletstruct_and_exit(a, argv); | 193 | run_applet_no_and_exit(a, argv); |
194 | #endif | 194 | #endif |
195 | } | 195 | } |
196 | #endif /* FEATURE_PREFER_APPLETS */ | 196 | #endif /* FEATURE_PREFER_APPLETS */ |