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) |
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 = "" #define usage_messages 0 #endif /* SHOW_USAGE */ -/* Define struct bb_applet applets[] */ -#include "applets.h" -#if ENABLE_FEATURE_SH_STANDALONE -/* -1 because last entry is NULL */ -const unsigned short NUM_APPLETS = ARRAY_SIZE(applets) - 1; -#endif +/* Include generated applet names, pointers to <apllet>_main, etc */ +#include "applet_tables.h" #if ENABLE_FEATURE_COMPRESS_USAGE @@ -84,16 +80,14 @@ void bb_show_usage(void) const char *format_string; const char *p; const char *usage_string = p = unpack_usage_messages(); - const struct bb_applet *ap = find_applet_by_name(applet_name); - int i; + int ap = find_applet_by_name(applet_name); - if (!ap) /* never happens, paranoia */ + if (ap < 0) /* never happens, paranoia */ xfunc_die(); - i = ap - applets; - while (i) { + while (ap) { while (*p++) continue; - i--; + ap--; } fprintf(stderr, "%s multi-call binary\n", bb_banner); @@ -107,18 +101,22 @@ void bb_show_usage(void) } -static int applet_name_compare(const void *name, const void *vapplet) +static int applet_name_compare(const void *name, const void *v) { - const struct bb_applet *applet = vapplet; - - return strcmp(name, applet->name); + int i = (const char *)v - applet_names; + return strcmp(name, APPLET_NAME(i)); } -const struct bb_applet *find_applet_by_name(const char *name) +int find_applet_by_name(const char *name) { + const char *p; /* Do a binary search to find the applet entry given the name. */ - return bsearch(name, applets, ARRAY_SIZE(applets)-1, sizeof(applets[0]), - applet_name_compare); + + /* NB: any char pointer will work as well, not necessarily applet_names */ + p = bsearch(name, applet_names, ARRAY_SIZE(applet_mains), 1, applet_name_compare); + if (!p) + return -1; + return p - applet_names; } @@ -166,7 +164,7 @@ USE_FEATURE_SUID(static uid_t ruid;) /* real uid */ /* applets[] is const, so we have to define this "override" structure */ static struct BB_suid_config { - const struct bb_applet *m_applet; + int m_applet; uid_t m_uid; gid_t m_gid; mode_t m_mode; @@ -232,7 +230,7 @@ static void parse_config_file(void) { struct BB_suid_config *sct_head; struct BB_suid_config *sct; - const struct bb_applet *applet; + int applet_no; FILE *f; const char *errmsg; char *s; @@ -343,14 +341,14 @@ static void parse_config_file(void) * applet is currently built in and ignore it otherwise. * Note: this can hide config file bugs which only pop * up when the busybox configuration is changed. */ - applet = find_applet_by_name(s); - if (applet) { + applet_no = find_applet_by_name(s); + if (applet_no >= 0) { /* Note: We currently don't check for duplicates! * The last config line for each applet will be the * one used since we insert at the head of the list. * I suppose this could be considered a feature. */ sct = xmalloc(sizeof(struct BB_suid_config)); - sct->m_applet = applet; + sct->m_applet = applet_no; sct->m_mode = 0; sct->m_next = sct_head; sct_head = sct; @@ -441,7 +439,7 @@ static inline void parse_config_file(void) #if ENABLE_FEATURE_SUID -static void check_suid(const struct bb_applet *applet) +static void check_suid(int applet_no) { gid_t rgid; /* real gid */ @@ -456,7 +454,7 @@ static void check_suid(const struct bb_applet *applet) mode_t m; for (sct = suid_config; sct; sct = sct->m_next) { - if (sct->m_applet == applet) + if (sct->m_applet == applet_no) goto found; } goto check_need_suid; @@ -504,12 +502,12 @@ static void check_suid(const struct bb_applet *applet) #endif check_need_suid: #endif - if (applet->need_suid == _BB_SUID_ALWAYS) { + if (APPLET_SUID(applet_no) == _BB_SUID_ALWAYS) { /* Real uid is not 0. If euid isn't 0 too, suid bit * is most probably not set on our executable */ if (geteuid()) bb_error_msg_and_die("must be suid to work properly"); - } else if (applet->need_suid == _BB_SUID_NEVER) { + } else if (APPLET_SUID(applet_no) == _BB_SUID_NEVER) { xsetgid(rgid); /* drop all privileges */ xsetuid(ruid); } @@ -536,18 +534,19 @@ static void install_links(const char *busybox, int use_symbolic_links) usr_sbin }; - int (*lf)(const char *, const char *) = link; + int (*lf)(const char *, const char *); char *fpc; int i; int rc; + lf = link; if (use_symbolic_links) lf = symlink; - for (i = 0; applets[i].name != NULL; i++) { + for (i = 0; i < ARRAY_SIZE(applet_mains); i++) { fpc = concat_path_file( - install_dir[applets[i].install_loc], - applets[i].name); + install_dir[APPLET_INSTALL_LOC(i)], + APPLET_NAME(i)); rc = lf(busybox, fpc); if (rc != 0 && errno != EEXIST) { bb_simple_perror_msg(fpc); @@ -564,7 +563,7 @@ static int busybox_main(char **argv) { if (!argv[1]) { /* Called without arguments */ - const struct bb_applet *a; + const char *a; int col, output_width; help: output_width = 80; @@ -588,14 +587,14 @@ static int busybox_main(char **argv) "\twill act like whatever it was invoked as!\n" "\nCurrently defined functions:\n"); col = 0; - a = applets; - while (a->name) { + a = applet_names; + while (*a) { if (col > output_width) { puts(","); col = 0; } - col += printf("%s%s", (col ? ", " : "\t"), a->name); - a++; + col += printf("%s%s", (col ? ", " : "\t"), a); + a += strlen(a) + 1; } puts("\n"); return 0; @@ -629,7 +628,7 @@ static int busybox_main(char **argv) bb_error_msg_and_die("applet not found"); } -void run_appletstruct_and_exit(const struct bb_applet *applet, char **argv) +void run_applet_no_and_exit(int applet_no, char **argv) { int argc = 1; @@ -640,19 +639,19 @@ void run_appletstruct_and_exit(const struct bb_applet *applet, char **argv) optind = 1; xfunc_error_retval = EXIT_FAILURE; - applet_name = applet->name; + applet_name = APPLET_NAME(applet_no); if (argc == 2 && !strcmp(argv[1], "--help")) bb_show_usage(); if (ENABLE_FEATURE_SUID) - check_suid(applet); - exit(applet->main(argc, argv)); + check_suid(applet_no); + exit(applet_mains[applet_no](argc, argv)); } void run_applet_and_exit(const char *name, char **argv) { - const struct bb_applet *applet = find_applet_by_name(name); - if (applet) - run_appletstruct_and_exit(applet, argv); + int applet = find_applet_by_name(name); + if (applet >= 0) + run_applet_no_and_exit(applet, argv); if (!strncmp(name, "busybox", 7)) exit(busybox_main(argv)); } 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) */ int bb_execvp(const char *file, char *const argv[]) { - return execvp(find_applet_by_name(file) ? bb_busybox_exec_path : file, + return execvp(find_applet_by_name(file) >= 0 ? bb_busybox_exec_path : file, argv); } #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 @@ */ #include <paths.h> -#include "busybox.h" /* for struct bb_applet */ +#include "busybox.h" /* uses applet tables */ /* This does a fork/exec in one call, using vfork(). Returns PID of new child, * -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) die_sleep = save->die_sleep; } -int run_nofork_applet_prime(struct nofork_save_area *old, const struct bb_applet *a, char **argv) +int run_nofork_applet_prime(struct nofork_save_area *old, int applet_no, char **argv) { int rc, argc; - applet_name = a->name; + applet_name = APPLET_NAME(applet_no); xfunc_error_retval = EXIT_FAILURE; /*option_mask32 = 0; - not needed */ /* 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 char *tmp_argv[argc+1]; memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0])); /* Finally we can call NOFORK applet's main() */ - rc = a->main(argc, tmp_argv); + rc = applet_mains[applet_no](argc, tmp_argv); } else { /* xfunc died in NOFORK applet */ /* in case they meant to return 0... */ if (rc == -2222) @@ -155,13 +155,13 @@ int run_nofork_applet_prime(struct nofork_save_area *old, const struct bb_applet return rc; } -int run_nofork_applet(const struct bb_applet *a, char **argv) +int run_nofork_applet(int applet_no, char **argv) { struct nofork_save_area old; /* Saving globals */ save_nofork_data(&old); - return run_nofork_applet_prime(&old, a, argv); + return run_nofork_applet_prime(&old, applet_no, argv); } #endif /* FEATURE_PREFER_APPLETS */ @@ -169,15 +169,15 @@ int spawn_and_wait(char **argv) { int rc; #if ENABLE_FEATURE_PREFER_APPLETS - const struct bb_applet *a = find_applet_by_name(argv[0]); + int a = find_applet_by_name(argv[0]); - if (a && (a->nofork + if (a >= 0 && (APPLET_IS_NOFORK(a) #if BB_MMU - || a->noexec /* NOEXEC trick needs fork() */ + || APPLET_IS_NOEXEC(a) /* NOEXEC trick needs fork() */ #endif )) { #if BB_MMU - if (a->nofork) + if (APPLET_IS_NOFORK(a)) #endif { return run_nofork_applet(a, argv); @@ -190,7 +190,7 @@ int spawn_and_wait(char **argv) return wait4pid(rc); /* child */ xfunc_error_retval = EXIT_FAILURE; - run_appletstruct_and_exit(a, argv); + run_applet_no_and_exit(a, argv); #endif } #endif /* FEATURE_PREFER_APPLETS */ |