Fix up builtin overrides, and hack in the binary search for finding
authorEric Andersen <andersen@codepoet.org>
Fri, 17 Nov 2000 18:25:26 +0000 (18:25 -0000)
committerEric Andersen <andersen@codepoet.org>
Fri, 17 Nov 2000 18:25:26 +0000 (18:25 -0000)
matching applets into the shell.

Config.h
applets/busybox.c
busybox.c
busybox.h
include/busybox.h
lash.c
sh.c
shell/lash.c
utility.c

index c010671..82c17d6 100644 (file)
--- a/Config.h
+++ b/Config.h
 #define BB_FEATURE_SH_STANDALONE_SHELL
 //
 //When this is enabled, busybox shell builtins can be called using full path
-//names.  This causes builtins (which includes every single busybox command
-//when you enable BB_FEATURE_SH_STANDALONE_SHELL) to override real commands on
-//the filesystem.  When this is enabled, if you run /bin/cat, it will use
-//BusyBox cat even if /bin/cat exists on the filesystem and is _not_ busybox.
-//Some systems want this, others do not.  Choose wisely.  :-)
+//names.  This causes builtins (i.e. every single busybox command) to override
+//real commands on the filesystem.  For example, if you run run /bin/cat, it
+//will use BusyBox cat even if /bin/cat exists on the filesystem and is _not_
+//busybox.  Some systems want this, others do not.  Choose wisely.  :-) This
+//only has meaning when BB_FEATURE_SH_STANDALONE_SHELL is enabled.
 //BB_FEATURE_SH_BUILTINS_ALWAYS_WIN
 //
 // Enable tab completion in the shell (not yet 
index d356e4c..0a3333d 100644 (file)
@@ -81,14 +81,6 @@ static void install_links(const char *busybox, int use_symbolic_links)
 
 #endif /* BB_FEATURE_INSTALLER */
 
-static int applet_name_compare(const void *x, const void *y)
-{
-       const struct BB_applet *applet1 = x;
-       const struct BB_applet *applet2 = y;
-
-       return strcmp(applet1->name, applet2->name);
-}
-
 int main(int argc, char **argv)
 {
        struct BB_applet search_applet, *applet;
index d356e4c..0a3333d 100644 (file)
--- a/busybox.c
+++ b/busybox.c
@@ -81,14 +81,6 @@ static void install_links(const char *busybox, int use_symbolic_links)
 
 #endif /* BB_FEATURE_INSTALLER */
 
-static int applet_name_compare(const void *x, const void *y)
-{
-       const struct BB_applet *applet1 = x;
-       const struct BB_applet *applet2 = y;
-
-       return strcmp(applet1->name, applet2->name);
-}
-
 int main(int argc, char **argv)
 {
        struct BB_applet search_applet, *applet;
index d947ba3..2bc1c99 100644 (file)
--- a/busybox.h
+++ b/busybox.h
@@ -108,6 +108,8 @@ struct BB_applet {
 /* From busybox.c */
 extern const struct BB_applet applets[];
 
+extern int applet_name_compare(const void *x, const void *y);
+
 extern int ar_main(int argc, char **argv);
 extern int basename_main(int argc, char **argv);
 extern int bogomips_main(int argc, char **argv);
index d947ba3..2bc1c99 100644 (file)
@@ -108,6 +108,8 @@ struct BB_applet {
 /* From busybox.c */
 extern const struct BB_applet applets[];
 
+extern int applet_name_compare(const void *x, const void *y);
+
 extern int ar_main(int argc, char **argv);
 extern int basename_main(int argc, char **argv);
 extern int bogomips_main(int argc, char **argv);
diff --git a/lash.c b/lash.c
index d6ac1fc..1e0803f 100644 (file)
--- a/lash.c
+++ b/lash.c
@@ -1152,7 +1152,7 @@ static int runCommand(struct job *newJob, struct jobSet *jobList, int inBg, int
        int pipefds[2];                         /* pipefd[0] is for reading */
        struct builtInCommand *x;
 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
-       const struct BB_applet *a = applets;
+       struct BB_applet search_applet, *applet = applets;
 #endif
 
        nextin = 0, nextout = 1;
@@ -1214,40 +1214,44 @@ static int runCommand(struct job *newJob, struct jobSet *jobList, int inBg, int
                                }
                        }
 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
-                       /* Check if the command matches any busybox internal commands here */
-                       while (a->name != 0) {
+                       /* Check if the command matches any busybox internal
+                        * commands ("applets") here.  Following discussions from
+                        * November 2000 on busybox@opensource.lineo.com, don't use
+                        * get_last_path_component().  This way explicit (with
+                        * slashes) filenames will never be interpreted as an
+                        * applet, just like with builtins.  This way the user can
+                        * override an applet with an explicit filename reference.
+                        * The only downside to this change is that an explicit
+                        * /bin/foo invocation fill fork and exec /bin/foo, even if
+                        * /bin/foo is a symlink to busybox.
+                        */
+                       search_applet.name = newJob->progs[i].argv[0];
+
 #ifdef BB_FEATURE_SH_BUILTINS_ALWAYS_WIN
-                               if (strcmp(get_last_path_component(newJob->progs[i].argv[0]),
-                                                       a->name) == 0) 
-#else
-                                       /* Check if the command matches any busybox internal
-                                        * commands ("applets") here.  Following discussions from
-                                        * November 2000 on busybox@opensource.lineo.com, don't use
-                                        * get_last_path_component().  This way explicit (with
-                                        * slashes) filenames will never be interpreted as an
-                                        * applet, just like with builtins.  This way the user can
-                                        * override an applet with an explicit filename reference.
-                                        * The only downside to this change is that an explicit
-                                        * /bin/foo invocation fill fork and exec /bin/foo, even if
-                                        * /bin/foo is a symlink to busybox.
-                                       */
-                               if (strcmp(newJob->progs[i].argv[0], a->name) == 0) 
+                       /* If you enable BB_FEATURE_SH_BUILTINS_ALWAYS_WIN, then
+                        * if you run /bin/cat, it will use BusyBox cat even if 
+                        * /bin/cat exists on the filesystem and is _not_ busybox.
+                        * Some systems want this, others do not.  Choose wisely.  :-)
+                        */
+                       search_applet.name = get_last_path_component(search_applet.name);
 #endif
-                               {
-                                       int argc_l;
-                                       char** argv=newJob->progs[i].argv;
-                                       for(argc_l=0;*argv!=NULL; argv++, argc_l++);
-                                       applet_name=a->name;
-                                       optind = 1;
-                                       exit((*(a->main)) (argc_l, newJob->progs[i].argv));
-                               }
-                               a++;
+
+                       /* Do a binary search to find the applet entry given the name. */
+                       applet = bsearch(&search_applet, applets, NUM_APPLETS,
+                                       sizeof(struct BB_applet), applet_name_compare);
+                       if (applet != NULL) {
+                               int argc_l;
+                               char** argv=newJob->progs[i].argv;
+                               for(argc_l=0;*argv!=NULL; argv++, argc_l++);
+                               applet_name=applet->name;
+                               optind = 1;
+                               exit((*(applet->main)) (argc_l, newJob->progs[i].argv));
                        }
 #endif
 
                        execvp(newJob->progs[i].argv[0], newJob->progs[i].argv);
                        fatalError("%s: %s\n", newJob->progs[i].argv[0],
-                                          strerror(errno));
+                                       strerror(errno));
                }
                if (outPipe[1]!=-1) {
                        close(outPipe[1]);
diff --git a/sh.c b/sh.c
index d6ac1fc..1e0803f 100644 (file)
--- a/sh.c
+++ b/sh.c
@@ -1152,7 +1152,7 @@ static int runCommand(struct job *newJob, struct jobSet *jobList, int inBg, int
        int pipefds[2];                         /* pipefd[0] is for reading */
        struct builtInCommand *x;
 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
-       const struct BB_applet *a = applets;
+       struct BB_applet search_applet, *applet = applets;
 #endif
 
        nextin = 0, nextout = 1;
@@ -1214,40 +1214,44 @@ static int runCommand(struct job *newJob, struct jobSet *jobList, int inBg, int
                                }
                        }
 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
-                       /* Check if the command matches any busybox internal commands here */
-                       while (a->name != 0) {
+                       /* Check if the command matches any busybox internal
+                        * commands ("applets") here.  Following discussions from
+                        * November 2000 on busybox@opensource.lineo.com, don't use
+                        * get_last_path_component().  This way explicit (with
+                        * slashes) filenames will never be interpreted as an
+                        * applet, just like with builtins.  This way the user can
+                        * override an applet with an explicit filename reference.
+                        * The only downside to this change is that an explicit
+                        * /bin/foo invocation fill fork and exec /bin/foo, even if
+                        * /bin/foo is a symlink to busybox.
+                        */
+                       search_applet.name = newJob->progs[i].argv[0];
+
 #ifdef BB_FEATURE_SH_BUILTINS_ALWAYS_WIN
-                               if (strcmp(get_last_path_component(newJob->progs[i].argv[0]),
-                                                       a->name) == 0) 
-#else
-                                       /* Check if the command matches any busybox internal
-                                        * commands ("applets") here.  Following discussions from
-                                        * November 2000 on busybox@opensource.lineo.com, don't use
-                                        * get_last_path_component().  This way explicit (with
-                                        * slashes) filenames will never be interpreted as an
-                                        * applet, just like with builtins.  This way the user can
-                                        * override an applet with an explicit filename reference.
-                                        * The only downside to this change is that an explicit
-                                        * /bin/foo invocation fill fork and exec /bin/foo, even if
-                                        * /bin/foo is a symlink to busybox.
-                                       */
-                               if (strcmp(newJob->progs[i].argv[0], a->name) == 0) 
+                       /* If you enable BB_FEATURE_SH_BUILTINS_ALWAYS_WIN, then
+                        * if you run /bin/cat, it will use BusyBox cat even if 
+                        * /bin/cat exists on the filesystem and is _not_ busybox.
+                        * Some systems want this, others do not.  Choose wisely.  :-)
+                        */
+                       search_applet.name = get_last_path_component(search_applet.name);
 #endif
-                               {
-                                       int argc_l;
-                                       char** argv=newJob->progs[i].argv;
-                                       for(argc_l=0;*argv!=NULL; argv++, argc_l++);
-                                       applet_name=a->name;
-                                       optind = 1;
-                                       exit((*(a->main)) (argc_l, newJob->progs[i].argv));
-                               }
-                               a++;
+
+                       /* Do a binary search to find the applet entry given the name. */
+                       applet = bsearch(&search_applet, applets, NUM_APPLETS,
+                                       sizeof(struct BB_applet), applet_name_compare);
+                       if (applet != NULL) {
+                               int argc_l;
+                               char** argv=newJob->progs[i].argv;
+                               for(argc_l=0;*argv!=NULL; argv++, argc_l++);
+                               applet_name=applet->name;
+                               optind = 1;
+                               exit((*(applet->main)) (argc_l, newJob->progs[i].argv));
                        }
 #endif
 
                        execvp(newJob->progs[i].argv[0], newJob->progs[i].argv);
                        fatalError("%s: %s\n", newJob->progs[i].argv[0],
-                                          strerror(errno));
+                                       strerror(errno));
                }
                if (outPipe[1]!=-1) {
                        close(outPipe[1]);
index d6ac1fc..1e0803f 100644 (file)
@@ -1152,7 +1152,7 @@ static int runCommand(struct job *newJob, struct jobSet *jobList, int inBg, int
        int pipefds[2];                         /* pipefd[0] is for reading */
        struct builtInCommand *x;
 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
-       const struct BB_applet *a = applets;
+       struct BB_applet search_applet, *applet = applets;
 #endif
 
        nextin = 0, nextout = 1;
@@ -1214,40 +1214,44 @@ static int runCommand(struct job *newJob, struct jobSet *jobList, int inBg, int
                                }
                        }
 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
-                       /* Check if the command matches any busybox internal commands here */
-                       while (a->name != 0) {
+                       /* Check if the command matches any busybox internal
+                        * commands ("applets") here.  Following discussions from
+                        * November 2000 on busybox@opensource.lineo.com, don't use
+                        * get_last_path_component().  This way explicit (with
+                        * slashes) filenames will never be interpreted as an
+                        * applet, just like with builtins.  This way the user can
+                        * override an applet with an explicit filename reference.
+                        * The only downside to this change is that an explicit
+                        * /bin/foo invocation fill fork and exec /bin/foo, even if
+                        * /bin/foo is a symlink to busybox.
+                        */
+                       search_applet.name = newJob->progs[i].argv[0];
+
 #ifdef BB_FEATURE_SH_BUILTINS_ALWAYS_WIN
-                               if (strcmp(get_last_path_component(newJob->progs[i].argv[0]),
-                                                       a->name) == 0) 
-#else
-                                       /* Check if the command matches any busybox internal
-                                        * commands ("applets") here.  Following discussions from
-                                        * November 2000 on busybox@opensource.lineo.com, don't use
-                                        * get_last_path_component().  This way explicit (with
-                                        * slashes) filenames will never be interpreted as an
-                                        * applet, just like with builtins.  This way the user can
-                                        * override an applet with an explicit filename reference.
-                                        * The only downside to this change is that an explicit
-                                        * /bin/foo invocation fill fork and exec /bin/foo, even if
-                                        * /bin/foo is a symlink to busybox.
-                                       */
-                               if (strcmp(newJob->progs[i].argv[0], a->name) == 0) 
+                       /* If you enable BB_FEATURE_SH_BUILTINS_ALWAYS_WIN, then
+                        * if you run /bin/cat, it will use BusyBox cat even if 
+                        * /bin/cat exists on the filesystem and is _not_ busybox.
+                        * Some systems want this, others do not.  Choose wisely.  :-)
+                        */
+                       search_applet.name = get_last_path_component(search_applet.name);
 #endif
-                               {
-                                       int argc_l;
-                                       char** argv=newJob->progs[i].argv;
-                                       for(argc_l=0;*argv!=NULL; argv++, argc_l++);
-                                       applet_name=a->name;
-                                       optind = 1;
-                                       exit((*(a->main)) (argc_l, newJob->progs[i].argv));
-                               }
-                               a++;
+
+                       /* Do a binary search to find the applet entry given the name. */
+                       applet = bsearch(&search_applet, applets, NUM_APPLETS,
+                                       sizeof(struct BB_applet), applet_name_compare);
+                       if (applet != NULL) {
+                               int argc_l;
+                               char** argv=newJob->progs[i].argv;
+                               for(argc_l=0;*argv!=NULL; argv++, argc_l++);
+                               applet_name=applet->name;
+                               optind = 1;
+                               exit((*(applet->main)) (argc_l, newJob->progs[i].argv));
                        }
 #endif
 
                        execvp(newJob->progs[i].argv[0], newJob->progs[i].argv);
                        fatalError("%s: %s\n", newJob->progs[i].argv[0],
-                                          strerror(errno));
+                                       strerror(errno));
                }
                if (outPipe[1]!=-1) {
                        close(outPipe[1]);
index e79e441..c23ebcd 100644 (file)
--- a/utility.c
+++ b/utility.c
@@ -1775,6 +1775,14 @@ FILE *xfopen(const char *path, const char *mode)
 }
 #endif
 
+int applet_name_compare(const void *x, const void *y)
+{
+       const struct BB_applet *applet1 = x;
+       const struct BB_applet *applet2 = y;
+
+       return strcmp(applet1->name, applet2->name);
+}
+
 /* END CODE */
 /*
 Local Variables: