X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;ds=sidebyside;f=lash.c;h=8ea5e305befcbca4b28f9bc2f0ab9144b40e28cc;hb=77bd2db32527a81dd777f6835fddacc801855cbc;hp=e143cfe740393c2ac1a51c127104b3559ef12873;hpb=161220c4985b8c05a57f09b2693a6cad74d2e81d;p=oweals%2Fbusybox.git diff --git a/lash.c b/lash.c index e143cfe74..8ea5e305b 100644 --- a/lash.c +++ b/lash.c @@ -1,6 +1,6 @@ /* vi: set sw=4 ts=4: */ /* - * BusyBox Shell + * lash -- the BusyBox Lame-Ass SHell * * Copyright (C) 2000 by Lineo, inc. * Written by Erik Andersen , @@ -37,12 +37,11 @@ #include #include #include - - #ifdef BB_FEATURE_SH_COMMAND_EDITING #include "cmdedit.h" #endif + #define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n" @@ -98,7 +97,7 @@ static int shell_fg_bg(struct job *cmd, struct jobSet *jobList); static int shell_help(struct job *cmd, struct jobSet *junk); static int shell_jobs(struct job *dummy, struct jobSet *jobList); static int shell_pwd(struct job *dummy, struct jobSet *junk); -static int shell_set(struct job *cmd, struct jobSet *junk); +static int shell_export(struct job *cmd, struct jobSet *junk); static int shell_source(struct job *cmd, struct jobSet *jobList); static int shell_unset(struct job *cmd, struct jobSet *junk); @@ -114,29 +113,44 @@ static int busy_loop(FILE * input); static struct builtInCommand bltins[] = { {"bg", "Resume a job in the background", "bg [%%job]", shell_fg_bg}, {"cd", "Change working directory", "cd [dir]", shell_cd}, - //{"echo", "Echo arguments on stdout", "echo arg1 [...]", shell_echo}, - {"env", "Print all environment variables", "env", shell_env}, {"exit", "Exit from shell()", "exit", shell_exit}, {"fg", "Bring job into the foreground", "fg [%%job]", shell_fg_bg}, {"jobs", "Lists the active jobs", "jobs", shell_jobs}, - {"pwd", "Print current directory", "pwd", shell_pwd}, - {"set", "Set environment variable", "set [VAR=value]", shell_set}, + {"export", "Set environment variable", "export [VAR=value]", shell_export}, {"unset", "Unset environment variable", "unset VAR", shell_unset}, - - {".", "Source-in and run commands in a file", ". filename", - shell_source}, + {NULL, NULL, NULL, NULL} +}; + +/* Table of built-in functions */ +static struct builtInCommand bltins_forking[] = { + {"env", "Print all environment variables", "env", shell_env}, + {"pwd", "Print current directory", "pwd", shell_pwd}, + {".", "Source-in and run commands in a file", ". filename", shell_source}, {"help", "List shell built-in commands", "help", shell_help}, {NULL, NULL, NULL, NULL} }; static const char shell_usage[] = - "sh [FILE]...\n\n" "The BusyBox command interpreter (shell).\n\n"; - + "sh [FILE]...\n" +#ifndef BB_FEATURE_TRIVIAL_HELP + "\nlash: The BusyBox command interpreter (shell).\n\n" +#endif + ; static char cwd[1024]; static char *prompt = "# "; +#ifdef BB_FEATURE_SH_COMMAND_EDITING +void win_changed(int sig) +{ + struct winsize win = { 0, 0 }; + ioctl(0, TIOCGWINSZ, &win); + if (win.ws_col > 0) { + cmdedit_setwidth( win.ws_col - 1); + } +} +#endif /* built-in 'cd ' handler */ @@ -182,7 +196,7 @@ static int shell_exit(struct job *cmd, struct jobSet *junk) static int shell_fg_bg(struct job *cmd, struct jobSet *jobList) { int i, jobNum; - struct job *job; + struct job *job=NULL; if (!jobList->head) { if (!cmd->progs[0].argv[1] || cmd->progs[0].argv[2]) { @@ -238,6 +252,9 @@ static int shell_help(struct job *cmd, struct jobSet *junk) for (x = bltins; x->cmd; x++) { fprintf(stdout, "%s\t%s\n", x->cmd, x->descr); } + for (x = bltins_forking; x->cmd; x++) { + fprintf(stdout, "%s\t%s\n", x->cmd, x->descr); + } fprintf(stdout, "\n\n"); return TRUE; } @@ -268,8 +285,8 @@ static int shell_pwd(struct job *dummy, struct jobSet *junk) return TRUE; } -/* built-in 'set VAR=value' handler */ -static int shell_set(struct job *cmd, struct jobSet *junk) +/* built-in 'export VAR=value' handler */ +static int shell_export(struct job *cmd, struct jobSet *junk) { int res; @@ -278,7 +295,7 @@ static int shell_set(struct job *cmd, struct jobSet *junk) } res = putenv(cmd->progs[0].argv[1]); if (res) - fprintf(stdout, "set: %s\n", strerror(errno)); + fprintf(stdout, "export: %s\n", strerror(errno)); return (res); } @@ -396,11 +413,19 @@ static void checkJobs(struct jobSet *jobList) static int getCommand(FILE * source, char *command) { if (source == stdin) { - fprintf(stdout, "BBSHELL %s %s", cwd, prompt); - fflush(stdout); #ifdef BB_FEATURE_SH_COMMAND_EDITING - cmdedit_read_input(fileno(stdin), fileno(stdout), command); + int len; + char *promptStr; + len=fprintf(stdout, "%s %s", cwd, prompt); + fflush(stdout); + promptStr=(char*)malloc(sizeof(char)*(len+1)); + sprintf(promptStr, "%s %s", cwd, prompt); + cmdedit_read_input(promptStr, command); + free( promptStr); return 0; +#else + fprintf(stdout, "%s %s", cwd, prompt); + fflush(stdout); #endif } @@ -693,7 +718,6 @@ static int parseCommand(char **commandPtr, struct job *job, int *isBg) strcpy(job->text, *commandPtr); } else { /* This leaves any trailing spaces, which is a bit sloppy */ - count = returnCommand - *commandPtr; job->text = malloc(count + 1); strncpy(job->text, *commandPtr, count); @@ -705,6 +729,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; @@ -712,14 +737,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++) { @@ -730,6 +751,13 @@ static int runCommand(struct job newJob, struct jobSet *jobList, int inBg) nextout = 1; } + /* Match any built-ins here */ + for (x = bltins; x->cmd; x++) { + if (!strcmp(newJob.progs[i].argv[0], x->cmd)) { + return (x->function(&newJob, jobList)); + } + } + if (!(newJob.progs[i].pid = fork())) { signal(SIGTTOU, SIG_DFL); @@ -746,6 +774,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_forking; 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)); @@ -790,14 +837,12 @@ static int runCommand(struct job newJob, struct jobSet *jobList, int inBg) if (inBg) { /* we don't wait for background jobs to return -- append it to the list of backgrounded jobs and leave it alone */ - printf("[%d] %d\n", job->jobId, newJob.progs[newJob.numProgs - 1].pid); } else { jobList->fg = job; /* move the new process group into the foreground */ - if (tcsetpgrp(0, newJob.pgrp)) perror("tcsetpgrp"); } @@ -935,29 +980,28 @@ int shell_main(int argc, char **argv) /* initialize the cwd */ getcwd(cwd, sizeof(cwd)); +#ifdef BB_FEATURE_SH_COMMAND_EDITING + cmdedit_init(); + signal(SIGWINCH, win_changed); + win_changed(0); +#endif //if (argv[0] && argv[0][0] == '-') { // shell_source("/etc/profile"); //} if (argc < 2) { - fprintf(stdout, "\n\nBusyBox v%s (%s) Built-in shell\n", BB_VER, - BB_BT); - fprintf(stdout, - "Enter 'help' for a list of built-in commands.\n\n"); + fprintf(stdout, "\n\nBusyBox v%s (%s) Built-in shell\n", BB_VER, BB_BT); + fprintf(stdout, "Enter 'help' for a list of built-in commands.\n\n"); } else { + if (*argv[1]=='-') { + usage("sh\n\nlash -- the BusyBox LAme SHell (command interpreter)\n"); + } input = fopen(argv[1], "r"); - if (!input) - fatalError("A: Couldn't open file '%s': %s\n", argv[1], + if (!input) { + fatalError("sh: Couldn't open file '%s': %s\n", argv[1], strerror(errno)); -// else -// fatalError("Got it.\n"); - //exit(shell_source(argv[1])); - - /* Set terminal IO to canonical mode, and save old term settings. */ -#ifdef BB_FEATURE_SH_COMMAND_EDITING - cmdedit_init(); -#endif + } } return (busy_loop(input));