BusyBox shell (lash) can now be used as a standalone shell when

BB_FEATURE_STANDALONE_SHELL is defined (i.e. BusyBox can now completely replace
sash).  Also fixed it so shell builtins now respect pipes and redirects.
 -Erik
This commit is contained in:
Erik Andersen 2000-05-13 06:33:19 +00:00
parent 73c8c9cf9a
commit bcd6177853
8 changed files with 87 additions and 28 deletions

View File

@ -30,6 +30,10 @@
* zcat now works (wasn't working since option parsing was broken) * zcat now works (wasn't working since option parsing was broken)
* Renamed "mnc" to the more correct "nc". * Renamed "mnc" to the more correct "nc".
* Makefile intelligence updates * 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 * More doc updates

View File

@ -30,7 +30,7 @@ int atexit(void (*__func) (void))
void *__libc_stack_end; void *__libc_stack_end;
#endif #endif
static const struct Applet applets[] = { const struct BB_applet applets[] = {
#ifdef BB_BASENAME #ifdef BB_BASENAME
{"basename", basename_main, _BB_DIR_USR_BIN}, {"basename", basename_main, _BB_DIR_USR_BIN},
@ -350,7 +350,7 @@ int main(int argc, char **argv)
{ {
char *s; char *s;
char *name; char *name;
const struct Applet *a = applets; const struct BB_applet *a = applets;
for (s = name = argv[0]; *s != '\0';) { for (s = name = argv[0]; *s != '\0';) {
if (*s++ == '/') if (*s++ == '/')
@ -384,7 +384,7 @@ int busybox_main(int argc, char **argv)
argv++; argv++;
if (been_there_done_that == 1 || argc < 1) { 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", fprintf(stderr, "BusyBox v%s (%s) multi-call binary -- GPL2\n\n",
BB_VER, BB_BT); BB_VER, BB_BT);

View File

@ -30,7 +30,7 @@ int atexit(void (*__func) (void))
void *__libc_stack_end; void *__libc_stack_end;
#endif #endif
static const struct Applet applets[] = { const struct BB_applet applets[] = {
#ifdef BB_BASENAME #ifdef BB_BASENAME
{"basename", basename_main, _BB_DIR_USR_BIN}, {"basename", basename_main, _BB_DIR_USR_BIN},
@ -350,7 +350,7 @@ int main(int argc, char **argv)
{ {
char *s; char *s;
char *name; char *name;
const struct Applet *a = applets; const struct BB_applet *a = applets;
for (s = name = argv[0]; *s != '\0';) { for (s = name = argv[0]; *s != '\0';) {
if (*s++ == '/') if (*s++ == '/')
@ -384,7 +384,7 @@ int busybox_main(int argc, char **argv)
argv++; argv++;
if (been_there_done_that == 1 || argc < 1) { 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", fprintf(stderr, "BusyBox v%s (%s) multi-call binary -- GPL2\n\n",
BB_VER, BB_BT); BB_VER, BB_BT);

View File

@ -201,6 +201,11 @@
// Enable command line editing in the shell // Enable command line editing in the shell
//#define BB_FEATURE_SH_COMMAND_EDITING //#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 // Enable tab completion in the shell (not yet
// working very well -- so don't turn this on) // working very well -- so don't turn this on)
//#define BB_FEATURE_SH_TAB_COMPLETION //#define BB_FEATURE_SH_TAB_COMPLETION

View File

@ -90,11 +90,13 @@ enum Location {
_BB_DIR_USR_SBIN _BB_DIR_USR_SBIN
}; };
struct Applet { struct BB_applet {
const char* name; const char* name;
int (*main)(int argc, char** argv); int (*main)(int argc, char** argv);
enum Location location; enum Location location;
}; };
/* From busybox.c */
extern const struct BB_applet applets[];
extern int basename_main(int argc, char **argv); extern int basename_main(int argc, char **argv);
extern int busybox_main(int argc, char** argv); extern int busybox_main(int argc, char** argv);

30
lash.c
View File

@ -721,6 +721,7 @@ static int parseCommand(char **commandPtr, struct job *job, int *isBg)
return 0; return 0;
} }
static int runCommand(struct job newJob, struct jobSet *jobList, int inBg) static int runCommand(struct job newJob, struct jobSet *jobList, int inBg)
{ {
struct job *job; struct job *job;
@ -728,14 +729,10 @@ static int runCommand(struct job newJob, struct jobSet *jobList, int inBg)
int nextin, nextout; int nextin, nextout;
int pipefds[2]; /* pipefd[0] is for reading */ int pipefds[2]; /* pipefd[0] is for reading */
struct builtInCommand *x; 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; nextin = 0, nextout = 1;
for (i = 0; i < newJob.numProgs; i++) { 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 */ /* explicit redirections override pipes */
setupRedirections(newJob.progs + i); 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); execvp(newJob.progs[i].argv[0], newJob.progs[i].argv);
fatalError("sh: %s: %s\n", newJob.progs[i].argv[0], fatalError("sh: %s: %s\n", newJob.progs[i].argv[0],
strerror(errno)); strerror(errno));

30
sh.c
View File

@ -721,6 +721,7 @@ static int parseCommand(char **commandPtr, struct job *job, int *isBg)
return 0; return 0;
} }
static int runCommand(struct job newJob, struct jobSet *jobList, int inBg) static int runCommand(struct job newJob, struct jobSet *jobList, int inBg)
{ {
struct job *job; struct job *job;
@ -728,14 +729,10 @@ static int runCommand(struct job newJob, struct jobSet *jobList, int inBg)
int nextin, nextout; int nextin, nextout;
int pipefds[2]; /* pipefd[0] is for reading */ int pipefds[2]; /* pipefd[0] is for reading */
struct builtInCommand *x; 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; nextin = 0, nextout = 1;
for (i = 0; i < newJob.numProgs; i++) { 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 */ /* explicit redirections override pipes */
setupRedirections(newJob.progs + i); 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); execvp(newJob.progs[i].argv[0], newJob.progs[i].argv);
fatalError("sh: %s: %s\n", newJob.progs[i].argv[0], fatalError("sh: %s: %s\n", newJob.progs[i].argv[0],
strerror(errno)); strerror(errno));

View File

@ -721,6 +721,7 @@ static int parseCommand(char **commandPtr, struct job *job, int *isBg)
return 0; return 0;
} }
static int runCommand(struct job newJob, struct jobSet *jobList, int inBg) static int runCommand(struct job newJob, struct jobSet *jobList, int inBg)
{ {
struct job *job; struct job *job;
@ -728,14 +729,10 @@ static int runCommand(struct job newJob, struct jobSet *jobList, int inBg)
int nextin, nextout; int nextin, nextout;
int pipefds[2]; /* pipefd[0] is for reading */ int pipefds[2]; /* pipefd[0] is for reading */
struct builtInCommand *x; 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; nextin = 0, nextout = 1;
for (i = 0; i < newJob.numProgs; i++) { 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 */ /* explicit redirections override pipes */
setupRedirections(newJob.progs + i); 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); execvp(newJob.progs[i].argv[0], newJob.progs[i].argv);
fatalError("sh: %s: %s\n", newJob.progs[i].argv[0], fatalError("sh: %s: %s\n", newJob.progs[i].argv[0],
strerror(errno)); strerror(errno));