diff --git a/Changelog b/Changelog index db2dc4494..87a0bd82e 100644 --- a/Changelog +++ b/Changelog @@ -30,6 +30,10 @@ * zcat now works (wasn't working since option parsing was broken) * Renamed "mnc" to the more correct "nc". * Makefile intelligence updates + * BusyBox sh (lash) internals now behave wrt pipes and redirects. + * BusyBox sh (lash) now supports being used as a standalone shell. When + BB_FEATURE_STANDALONE_SHELL is defined, all the busybox commands may + be invoked as shell internals. * More doc updates diff --git a/applets/busybox.c b/applets/busybox.c index 85b42df23..07caa3446 100644 --- a/applets/busybox.c +++ b/applets/busybox.c @@ -30,7 +30,7 @@ int atexit(void (*__func) (void)) void *__libc_stack_end; #endif -static const struct Applet applets[] = { +const struct BB_applet applets[] = { #ifdef BB_BASENAME {"basename", basename_main, _BB_DIR_USR_BIN}, @@ -350,7 +350,7 @@ int main(int argc, char **argv) { char *s; char *name; - const struct Applet *a = applets; + const struct BB_applet *a = applets; for (s = name = argv[0]; *s != '\0';) { if (*s++ == '/') @@ -384,7 +384,7 @@ int busybox_main(int argc, char **argv) argv++; if (been_there_done_that == 1 || argc < 1) { - const struct Applet *a = applets; + const struct BB_applet *a = applets; fprintf(stderr, "BusyBox v%s (%s) multi-call binary -- GPL2\n\n", BB_VER, BB_BT); diff --git a/busybox.c b/busybox.c index 85b42df23..07caa3446 100644 --- a/busybox.c +++ b/busybox.c @@ -30,7 +30,7 @@ int atexit(void (*__func) (void)) void *__libc_stack_end; #endif -static const struct Applet applets[] = { +const struct BB_applet applets[] = { #ifdef BB_BASENAME {"basename", basename_main, _BB_DIR_USR_BIN}, @@ -350,7 +350,7 @@ int main(int argc, char **argv) { char *s; char *name; - const struct Applet *a = applets; + const struct BB_applet *a = applets; for (s = name = argv[0]; *s != '\0';) { if (*s++ == '/') @@ -384,7 +384,7 @@ int busybox_main(int argc, char **argv) argv++; if (been_there_done_that == 1 || argc < 1) { - const struct Applet *a = applets; + const struct BB_applet *a = applets; fprintf(stderr, "BusyBox v%s (%s) multi-call binary -- GPL2\n\n", BB_VER, BB_BT); diff --git a/busybox.def.h b/busybox.def.h index 5652b4518..296c7f94a 100644 --- a/busybox.def.h +++ b/busybox.def.h @@ -201,6 +201,11 @@ // Enable command line editing in the shell //#define BB_FEATURE_SH_COMMAND_EDITING // +//Allow the shell to invoke all the compiled in BusyBox commands as if they +//were shell builtins. Nice for staticly linking an emergency rescue shell +//amoung other thing. +#ifdef BB_FEATURE_STANDALONE_SHELL +// // Enable tab completion in the shell (not yet // working very well -- so don't turn this on) //#define BB_FEATURE_SH_TAB_COMPLETION diff --git a/internal.h b/internal.h index a953ce2e5..92b0255b0 100644 --- a/internal.h +++ b/internal.h @@ -90,11 +90,13 @@ enum Location { _BB_DIR_USR_SBIN }; -struct Applet { +struct BB_applet { const char* name; int (*main)(int argc, char** argv); enum Location location; }; +/* From busybox.c */ +extern const struct BB_applet applets[]; extern int basename_main(int argc, char **argv); extern int busybox_main(int argc, char** argv); diff --git a/lash.c b/lash.c index e446ad113..05dab9254 100644 --- a/lash.c +++ b/lash.c @@ -721,6 +721,7 @@ static int parseCommand(char **commandPtr, struct job *job, int *isBg) return 0; } + static int runCommand(struct job newJob, struct jobSet *jobList, int inBg) { struct job *job; @@ -728,14 +729,10 @@ static int runCommand(struct job newJob, struct jobSet *jobList, int inBg) int nextin, nextout; int pipefds[2]; /* pipefd[0] is for reading */ struct builtInCommand *x; +#ifdef BB_FEATURE_STANDALONE_SHELL + const struct BB_applet *a = applets; +#endif - /* handle built-ins here -- we don't fork() so we can't background - these very easily */ - for (x = bltins; x->cmd; x++) { - if (!strcmp(newJob.progs[0].argv[0], x->cmd)) { - return (x->function(&newJob, jobList)); - } - } nextin = 0, nextout = 1; for (i = 0; i < newJob.numProgs; i++) { @@ -762,6 +759,25 @@ static int runCommand(struct job newJob, struct jobSet *jobList, int inBg) /* explicit redirections override pipes */ setupRedirections(newJob.progs + i); + /* Match any built-ins here */ + for (x = bltins; x->cmd; x++) { + if (!strcmp(newJob.progs[i].argv[0], x->cmd)) { + exit (x->function(&newJob, jobList)); + } + } +#ifdef BB_FEATURE_STANDALONE_SHELL + /* Handle busybox internals here */ + while (a->name != 0) { + if (strcmp(newJob.progs[i].argv[0], a->name) == 0) { + int argc; + char** argv=newJob.progs[i].argv; + for(argc=0;*argv!=NULL, argv++, argc++); + exit((*(a->main)) (argc, newJob.progs[i].argv)); + } + a++; + } +#endif + execvp(newJob.progs[i].argv[0], newJob.progs[i].argv); fatalError("sh: %s: %s\n", newJob.progs[i].argv[0], strerror(errno)); diff --git a/sh.c b/sh.c index e446ad113..05dab9254 100644 --- a/sh.c +++ b/sh.c @@ -721,6 +721,7 @@ static int parseCommand(char **commandPtr, struct job *job, int *isBg) return 0; } + static int runCommand(struct job newJob, struct jobSet *jobList, int inBg) { struct job *job; @@ -728,14 +729,10 @@ static int runCommand(struct job newJob, struct jobSet *jobList, int inBg) int nextin, nextout; int pipefds[2]; /* pipefd[0] is for reading */ struct builtInCommand *x; +#ifdef BB_FEATURE_STANDALONE_SHELL + const struct BB_applet *a = applets; +#endif - /* handle built-ins here -- we don't fork() so we can't background - these very easily */ - for (x = bltins; x->cmd; x++) { - if (!strcmp(newJob.progs[0].argv[0], x->cmd)) { - return (x->function(&newJob, jobList)); - } - } nextin = 0, nextout = 1; for (i = 0; i < newJob.numProgs; i++) { @@ -762,6 +759,25 @@ static int runCommand(struct job newJob, struct jobSet *jobList, int inBg) /* explicit redirections override pipes */ setupRedirections(newJob.progs + i); + /* Match any built-ins here */ + for (x = bltins; x->cmd; x++) { + if (!strcmp(newJob.progs[i].argv[0], x->cmd)) { + exit (x->function(&newJob, jobList)); + } + } +#ifdef BB_FEATURE_STANDALONE_SHELL + /* Handle busybox internals here */ + while (a->name != 0) { + if (strcmp(newJob.progs[i].argv[0], a->name) == 0) { + int argc; + char** argv=newJob.progs[i].argv; + for(argc=0;*argv!=NULL, argv++, argc++); + exit((*(a->main)) (argc, newJob.progs[i].argv)); + } + a++; + } +#endif + execvp(newJob.progs[i].argv[0], newJob.progs[i].argv); fatalError("sh: %s: %s\n", newJob.progs[i].argv[0], strerror(errno)); diff --git a/shell/lash.c b/shell/lash.c index e446ad113..05dab9254 100644 --- a/shell/lash.c +++ b/shell/lash.c @@ -721,6 +721,7 @@ static int parseCommand(char **commandPtr, struct job *job, int *isBg) return 0; } + static int runCommand(struct job newJob, struct jobSet *jobList, int inBg) { struct job *job; @@ -728,14 +729,10 @@ static int runCommand(struct job newJob, struct jobSet *jobList, int inBg) int nextin, nextout; int pipefds[2]; /* pipefd[0] is for reading */ struct builtInCommand *x; +#ifdef BB_FEATURE_STANDALONE_SHELL + const struct BB_applet *a = applets; +#endif - /* handle built-ins here -- we don't fork() so we can't background - these very easily */ - for (x = bltins; x->cmd; x++) { - if (!strcmp(newJob.progs[0].argv[0], x->cmd)) { - return (x->function(&newJob, jobList)); - } - } nextin = 0, nextout = 1; for (i = 0; i < newJob.numProgs; i++) { @@ -762,6 +759,25 @@ static int runCommand(struct job newJob, struct jobSet *jobList, int inBg) /* explicit redirections override pipes */ setupRedirections(newJob.progs + i); + /* Match any built-ins here */ + for (x = bltins; x->cmd; x++) { + if (!strcmp(newJob.progs[i].argv[0], x->cmd)) { + exit (x->function(&newJob, jobList)); + } + } +#ifdef BB_FEATURE_STANDALONE_SHELL + /* Handle busybox internals here */ + while (a->name != 0) { + if (strcmp(newJob.progs[i].argv[0], a->name) == 0) { + int argc; + char** argv=newJob.progs[i].argv; + for(argc=0;*argv!=NULL, argv++, argc++); + exit((*(a->main)) (argc, newJob.progs[i].argv)); + } + a++; + } +#endif + execvp(newJob.progs[i].argv[0], newJob.progs[i].argv); fatalError("sh: %s: %s\n", newJob.progs[i].argv[0], strerror(errno));