1 /* vi: set sw=4 ts=4: */
3 * lash -- the BusyBox Lame-Ass SHell
5 * Copyright (C) 1999,2000,2001 by Lineo, inc.
6 * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
8 * Based in part on ladsh.c by Michael K. Johnson and Erik W. Troan, which is
9 * under the following liberal license: "We have placed this source code in the
10 * public domain. Use it in any project, free or commercial."
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 /* The parsing engine of this program is officially at a dead-end.
29 * Future work in that direction should move to the work posted
30 * at http://doolittle.faludi.com/~larry/parser.html .
31 * A start on the integration of that work with the rest of sh.c
32 * is at http://codepoet.org/sh.c .
35 //This works pretty well now, and is now on by default.
36 #define BB_FEATURE_SH_ENVIRONMENT
38 //Backtick support has some problems, use at your own risk!
39 //#define BB_FEATURE_SH_BACKTICKS
41 //If, then, else, etc. support.. This should now behave basically
42 //like any other Bourne shell...
43 #define BB_FEATURE_SH_IF_EXPRESSIONS
45 /* This is currently a little broken... */
46 //#define HANDLE_CONTINUATION_CHARS
48 //For debugging/development on the shell only...
60 #include <sys/ioctl.h>
67 static const int MAX_LINE = 256; /* size of input buffer for cwd data */
68 static const int MAX_READ = 128; /* size of input buffer for `read' builtin */
69 #define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
72 enum redir_type { REDIRECT_INPUT, REDIRECT_OVERWRITE,
76 static const unsigned int DEFAULT_CONTEXT=0x1;
77 static const unsigned int IF_TRUE_CONTEXT=0x2;
78 static const unsigned int IF_FALSE_CONTEXT=0x4;
79 static const unsigned int THEN_EXP_CONTEXT=0x8;
80 static const unsigned int ELSE_EXP_CONTEXT=0x10;
84 struct job *head; /* head of list of running jobs */
85 struct job *fg; /* current foreground job */
89 enum redir_type type; /* type of redirection */
90 int fd; /* file descriptor being redirected */
91 char *filename; /* file to redirect fd to */
95 pid_t pid; /* 0 if exited */
96 char **argv; /* program name and arguments */
97 int num_redirects; /* elements in redirection array */
98 struct redir_struct *redirects; /* I/O redirects */
99 glob_t glob_result; /* result of parameter globbing */
100 int free_glob; /* should we globfree(&glob_result)? */
101 int is_stopped; /* is the program currently running? */
102 struct job *family; /* pointer back to the child's parent job */
106 int jobid; /* job number */
107 int num_progs; /* total number of programs in job */
108 int running_progs; /* number of programs running */
109 char *text; /* name of job */
110 char *cmdbuf; /* buffer various argv's point into */
111 pid_t pgrp; /* process group ID for the job */
112 struct child_prog *progs; /* array of programs in job */
113 struct job *next; /* to track background commands */
114 int stopped_progs; /* number of programs alive, but stopped */
115 unsigned int job_context; /* bitmask defining current context */
116 struct jobset *job_list;
119 struct built_in_command {
120 char *cmd; /* name */
121 char *descr; /* description */
122 int (*function) (struct child_prog *); /* function ptr */
127 struct close_me *next;
130 /* function prototypes for builtins */
131 static int builtin_cd(struct child_prog *cmd);
132 static int builtin_env(struct child_prog *dummy);
133 static int builtin_exec(struct child_prog *cmd);
134 static int builtin_exit(struct child_prog *cmd);
135 static int builtin_fg_bg(struct child_prog *cmd);
136 static int builtin_help(struct child_prog *cmd);
137 static int builtin_jobs(struct child_prog *dummy);
138 static int builtin_pwd(struct child_prog *dummy);
139 static int builtin_export(struct child_prog *cmd);
140 static int builtin_source(struct child_prog *cmd);
141 static int builtin_unset(struct child_prog *cmd);
142 static int builtin_read(struct child_prog *cmd);
143 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
144 static int builtin_if(struct child_prog *cmd);
145 static int builtin_then(struct child_prog *cmd);
146 static int builtin_else(struct child_prog *cmd);
147 static int builtin_fi(struct child_prog *cmd);
148 /* function prototypes for shell stuff */
149 static int run_command_predicate(char *cmd);
153 /* function prototypes for shell stuff */
154 static void mark_open(int fd);
155 static void mark_closed(int fd);
156 static void checkjobs(struct jobset *job_list);
157 static int get_command(FILE * source, char *command);
158 static int parse_command(char **command_ptr, struct job *job, int *inbg);
159 static int run_command(struct job *newjob, int inbg, int outpipe[2]);
160 static int pseudo_exec(struct child_prog *cmd) __attribute__ ((noreturn));
161 static int busy_loop(FILE * input);
164 /* Table of built-in functions (these are non-forking builtins, meaning they
165 * can change global variables in the parent shell process but they will not
166 * work with pipes and redirects; 'unset foo | whatever' will not work) */
167 static struct built_in_command bltins[] = {
168 {"bg", "Resume a job in the background", builtin_fg_bg},
169 {"cd", "Change working directory", builtin_cd},
170 {"exec", "Exec command, replacing this shell with the exec'd process", builtin_exec},
171 {"exit", "Exit from shell()", builtin_exit},
172 {"fg", "Bring job into the foreground", builtin_fg_bg},
173 {"jobs", "Lists the active jobs", builtin_jobs},
174 {"export", "Set environment variable", builtin_export},
175 {"unset", "Unset environment variable", builtin_unset},
176 {"read", "Input environment variable", builtin_read},
177 {".", "Source-in and run commands in a file", builtin_source},
178 /* to do: add ulimit */
179 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
180 {"if", NULL, builtin_if},
181 {"then", NULL, builtin_then},
182 {"else", NULL, builtin_else},
183 {"fi", NULL, builtin_fi},
188 /* Table of forking built-in functions (things that fork cannot change global
189 * variables in the parent process, such as the current working directory) */
190 static struct built_in_command bltins_forking[] = {
191 {"env", "Print all environment variables", builtin_env},
192 {"pwd", "Print current directory", builtin_pwd},
193 {"help", "List shell built-in commands", builtin_help},
198 /* Variables we export */
199 unsigned int shell_context; /* Used in cmdedit.c to reset the
200 context when someone hits ^C */
203 /* Globals that are static to this file */
205 static char *local_pending_command = NULL;
206 static struct jobset job_list = { NULL, NULL };
209 static struct close_me *close_me_head = NULL;
210 #ifdef BB_FEATURE_SH_ENVIRONMENT
211 static int last_bg_pid=-1;
212 static int last_return_code=-1;
213 static int show_x_trace=FALSE;
215 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
216 static char syntax_err[]="syntax error near unexpected token";
220 static inline void debug_printf(const char *format, ...)
223 va_start(args, format);
224 vfprintf(stderr, format, args);
228 static inline void debug_printf(const char *format, ...) { }
232 Most builtins need access to the struct child_prog that has
233 their arguments, previously coded as cmd->progs[0]. That coding
234 can exhibit a bug, if the builtin is not the first command in
235 a pipeline: "echo foo | exec sort" will attempt to exec foo.
237 builtin previous use notes
238 ------ ----------------- ---------
241 exec cmd->progs[0] squashed bug: didn't look for applets or forking builtins
243 fg_bg cmd->progs[0], job_list->head, job_list->fg
247 export cmd->progs[0] passes cmd, job_list to builtin_env(), which ignores them
251 if cmd->job_context, cmd->text
252 then cmd->job_context, cmd->text
253 else cmd->job_context, cmd->text
256 The use of cmd->text by if/then/else/fi is hopelessly hacky.
257 Would it work to increment cmd->progs[0]->argv and recurse,
258 somewhat like builtin_exec does?
260 I added "struct job *family;" to struct child_prog,
261 and switched API to builtin_foo(struct child_prog *child);
262 So cmd->text becomes child->family->text
263 cmd->job_context becomes child->family->job_context
264 cmd->progs[0] becomes *child
265 job_list becomes child->family->job_list
268 /* built-in 'cd <path>' handler */
269 static int builtin_cd(struct child_prog *child)
273 if (child->argv[1] == NULL)
274 newdir = getenv("HOME");
276 newdir = child->argv[1];
278 printf("cd: %s: %s\n", newdir, strerror(errno));
281 getcwd(cwd, sizeof(char)*MAX_LINE);
286 /* built-in 'env' handler */
287 static int builtin_env(struct child_prog *dummy)
291 for (e = environ; *e; e++) {
297 /* built-in 'exec' handler */
298 static int builtin_exec(struct child_prog *child)
300 if (child->argv[1] == NULL)
301 return EXIT_SUCCESS; /* Really? */
308 /* built-in 'exit' handler */
309 static int builtin_exit(struct child_prog *child)
311 if (child->argv[1] == NULL)
314 exit (atoi(child->argv[1]));
317 /* built-in 'fg' and 'bg' handler */
318 static int builtin_fg_bg(struct child_prog *child)
321 struct job *job=NULL;
323 if (!child->argv[1] || child->argv[2]) {
324 error_msg("%s: exactly one argument is expected",
329 if (sscanf(child->argv[1], "%%%d", &jobNum) != 1) {
330 error_msg("%s: bad argument '%s'",
331 child->argv[0], child->argv[1]);
335 for (job = child->family->job_list->head; job; job = job->next) {
336 if (job->jobid == jobNum) {
342 error_msg("%s: unknown job %d",
343 child->argv[0], jobNum);
347 if (*child->argv[0] == 'f') {
348 /* Make this job the foreground job */
349 /* suppress messages when run from /linuxrc mag@sysgo.de */
350 if (tcsetpgrp(0, job->pgrp) && errno != ENOTTY)
351 perror_msg("tcsetpgrp");
352 child->family->job_list->fg = job;
355 /* Restart the processes in the job */
356 for (i = 0; i < job->num_progs; i++)
357 job->progs[i].is_stopped = 0;
359 kill(-job->pgrp, SIGCONT);
361 job->stopped_progs = 0;
366 /* built-in 'help' handler */
367 static int builtin_help(struct child_prog *dummy)
369 struct built_in_command *x;
371 printf("\nBuilt-in commands:\n");
372 printf("-------------------\n");
373 for (x = bltins; x->cmd; x++) {
376 printf("%s\t%s\n", x->cmd, x->descr);
378 for (x = bltins_forking; x->cmd; x++) {
381 printf("%s\t%s\n", x->cmd, x->descr);
387 /* built-in 'jobs' handler */
388 static int builtin_jobs(struct child_prog *child)
393 for (job = child->family->job_list->head; job; job = job->next) {
394 if (job->running_progs == job->stopped_progs)
395 status_string = "Stopped";
397 status_string = "Running";
399 printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->text);
405 /* built-in 'pwd' handler */
406 static int builtin_pwd(struct child_prog *dummy)
408 getcwd(cwd, MAX_LINE);
409 printf( "%s\n", cwd);
413 /* built-in 'export VAR=value' handler */
414 static int builtin_export(struct child_prog *child)
418 if (child->argv[1] == NULL) {
419 return (builtin_env(child));
421 res = putenv(child->argv[1]);
423 fprintf(stderr, "export: %s\n", strerror(errno));
427 /* built-in 'read VAR' handler */
428 static int builtin_read(struct child_prog *child)
430 int res = 0, len, newlen;
432 char string[MAX_READ];
434 if (child->argv[1]) {
435 /* argument (VAR) given: put "VAR=" into buffer */
436 strcpy(string, child->argv[1]);
437 len = strlen(string);
440 fgets(&string[len], sizeof(string) - len, stdin); /* read string */
441 newlen = strlen(string);
443 string[--newlen] = '\0'; /* chomp trailing newline */
445 ** string should now contain "VAR=<value>"
446 ** copy it (putenv() won't do that, so we must make sure
447 ** the string resides in a static buffer!)
450 if((s = strdup(string)))
453 fprintf(stderr, "read: %s\n", strerror(errno));
456 fgets(string, sizeof(string), stdin);
461 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
462 /* Built-in handler for 'if' commands */
463 static int builtin_if(struct child_prog *child)
465 struct job *cmd = child->family;
467 char* charptr1=cmd->text+3; /* skip over the leading 'if ' */
469 /* Now run the 'if' command */
470 debug_printf( "job=%p entering builtin_if ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
471 status = run_command_predicate(charptr1);
472 debug_printf( "if test returned ");
474 debug_printf( "TRUE\n");
475 cmd->job_context |= IF_TRUE_CONTEXT;
477 debug_printf( "FALSE\n");
478 cmd->job_context |= IF_FALSE_CONTEXT;
480 debug_printf("job=%p builtin_if set job context to %x\n", cmd, cmd->job_context);
486 /* Built-in handler for 'then' (part of the 'if' command) */
487 static int builtin_then(struct child_prog *child)
489 struct job *cmd = child->family;
490 char* charptr1=cmd->text+5; /* skip over the leading 'then ' */
492 debug_printf( "job=%p entering builtin_then ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
493 if (! (cmd->job_context & (IF_TRUE_CONTEXT|IF_FALSE_CONTEXT))) {
494 shell_context = 0; /* Reset the shell's context on an error */
495 error_msg("%s `then'", syntax_err);
499 cmd->job_context |= THEN_EXP_CONTEXT;
500 debug_printf("job=%p builtin_then set job context to %x\n", cmd, cmd->job_context);
502 /* If the if result was FALSE, skip the 'then' stuff */
503 if (cmd->job_context & IF_FALSE_CONTEXT) {
507 /* Seems the if result was TRUE, so run the 'then' command */
508 debug_printf( "'then' now running '%s'\n", charptr1);
510 return(run_command_predicate(charptr1));
513 /* Built-in handler for 'else' (part of the 'if' command) */
514 static int builtin_else(struct child_prog *child)
516 struct job *cmd = child->family;
517 char* charptr1=cmd->text+5; /* skip over the leading 'else ' */
519 debug_printf( "job=%p entering builtin_else ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
521 if (! (cmd->job_context & THEN_EXP_CONTEXT)) {
522 shell_context = 0; /* Reset the shell's context on an error */
523 error_msg("%s `else'", syntax_err);
526 /* If the if result was TRUE, skip the 'else' stuff */
527 if (cmd->job_context & IF_TRUE_CONTEXT) {
531 cmd->job_context |= ELSE_EXP_CONTEXT;
532 debug_printf("job=%p builtin_else set job context to %x\n", cmd, cmd->job_context);
534 /* Now run the 'else' command */
535 debug_printf( "'else' now running '%s'\n", charptr1);
536 return(run_command_predicate(charptr1));
539 /* Built-in handler for 'fi' (part of the 'if' command) */
540 static int builtin_fi(struct child_prog *child)
542 struct job *cmd = child->family;
543 debug_printf( "job=%p entering builtin_fi ('%s')-- context=%d\n", cmd, "", cmd->job_context);
544 if (! (cmd->job_context & (IF_TRUE_CONTEXT|IF_FALSE_CONTEXT))) {
545 shell_context = 0; /* Reset the shell's context on an error */
546 error_msg("%s `fi'", syntax_err);
549 /* Clear out the if and then context bits */
550 cmd->job_context &= ~(IF_TRUE_CONTEXT|IF_FALSE_CONTEXT|THEN_EXP_CONTEXT|ELSE_EXP_CONTEXT);
551 debug_printf("job=%p builtin_fi set job context to %x\n", cmd, cmd->job_context);
557 /* Built-in '.' handler (read-in and execute commands from file) */
558 static int builtin_source(struct child_prog *child)
564 if (child->argv[1] == NULL)
567 input = fopen(child->argv[1], "r");
569 printf( "Couldn't open file '%s'\n", child->argv[1]);
575 /* Now run the file */
576 status = busy_loop(input);
582 /* built-in 'unset VAR' handler */
583 static int builtin_unset(struct child_prog *child)
585 if (child->argv[1] == NULL) {
586 printf( "unset: parameter required.\n");
589 unsetenv(child->argv[1]);
593 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
594 /* currently used by if/then/else.
596 * Reparsing the command line for this purpose is gross,
597 * incorrect, and fundamentally unfixable; in particular,
598 * think about what happens with command substitution.
599 * We really need to pull out the run, wait, return status
600 * functionality out of busy_loop so we can child->argv++
601 * and use that, without going back through parse_command.
603 static int run_command_predicate(char *cmd)
606 local_pending_command = xmalloc(n+1);
607 strncpy(local_pending_command, cmd, n);
608 local_pending_command[n]='\0';
609 return( busy_loop(NULL));
613 static void mark_open(int fd)
615 struct close_me *new = xmalloc(sizeof(struct close_me));
617 new->next = close_me_head;
621 static void mark_closed(int fd)
623 struct close_me *tmp;
624 if (close_me_head == NULL || close_me_head->fd != fd)
625 error_msg_and_die("corrupt close_me");
627 close_me_head = close_me_head->next;
631 static void close_all()
634 for (c=close_me_head; c; c=c->next) {
637 close_me_head = NULL;
641 /* free up all memory from a job */
642 static void free_job(struct job *cmd)
646 for (i = 0; i < cmd->num_progs; i++) {
647 free(cmd->progs[i].argv);
648 if (cmd->progs[i].redirects)
649 free(cmd->progs[i].redirects);
650 if (cmd->progs[i].free_glob)
651 globfree(&cmd->progs[i].glob_result);
657 memset(cmd, 0, sizeof(struct job));
660 /* remove a job from the job_list */
661 static void remove_job(struct jobset *job_list, struct job *job)
666 if (job == job_list->head) {
667 job_list->head = job->next;
669 prevjob = job_list->head;
670 while (prevjob->next != job)
671 prevjob = prevjob->next;
672 prevjob->next = job->next;
678 /* Checks to see if any background processes have exited -- if they
679 have, figure out why and see if a job has completed */
680 static void checkjobs(struct jobset *job_list)
687 while ((childpid = waitpid(-1, &status, WNOHANG | WUNTRACED)) > 0) {
688 for (job = job_list->head; job; job = job->next) {
690 while (prognum < job->num_progs &&
691 job->progs[prognum].pid != childpid) prognum++;
692 if (prognum < job->num_progs)
696 /* This happens on backticked commands */
700 if (WIFEXITED(status) || WIFSIGNALED(status)) {
702 job->running_progs--;
703 job->progs[prognum].pid = 0;
705 if (!job->running_progs) {
706 printf(JOB_STATUS_FORMAT, job->jobid, "Done", job->text);
707 remove_job(job_list, job);
711 job->stopped_progs++;
712 job->progs[prognum].is_stopped = 1;
714 if (job->stopped_progs == job->num_progs) {
715 printf(JOB_STATUS_FORMAT, job->jobid, "Stopped",
721 if (childpid == -1 && errno != ECHILD)
722 perror_msg("waitpid");
725 /* squirrel != NULL means we squirrel away copies of stdin, stdout,
726 * and stderr if they are redirected. */
727 static int setup_redirects(struct child_prog *prog, int squirrel[])
732 struct redir_struct *redir = prog->redirects;
734 for (i = 0; i < prog->num_redirects; i++, redir++) {
735 switch (redir->type) {
739 case REDIRECT_OVERWRITE:
740 mode = O_WRONLY | O_CREAT | O_TRUNC;
742 case REDIRECT_APPEND:
743 mode = O_WRONLY | O_CREAT | O_APPEND;
747 openfd = open(redir->filename, mode, 0666);
749 /* this could get lost if stderr has been redirected, but
750 bash and ash both lose it as well (though zsh doesn't!) */
751 error_msg("error opening %s: %s", redir->filename,
756 if (openfd != redir->fd) {
757 if (squirrel && redir->fd < 3) {
758 squirrel[redir->fd] = dup(redir->fd);
760 dup2(openfd, redir->fd);
768 static void restore_redirects(int squirrel[])
771 for (i=0; i<3; i++) {
774 /* No error checking. I sure wouldn't know what
775 * to do with an error if I found one! */
782 #if defined(BB_FEATURE_SH_SIMPLE_PROMPT)
783 static char* setup_prompt_string(int state)
785 char prompt_str[BUFSIZ];
787 /* Set up the prompt */
790 sprintf(prompt_str, "%s %s", cwd, ( geteuid() != 0 ) ? "$ ":"# ");
792 strcpy(prompt_str,"> ");
795 return(strdup(prompt_str)); /* Must free this memory */
800 static char* setup_prompt_string(int state)
802 char user[9],buf[255],*s;
804 char prompt_str[BUFSIZ];
806 /* Set up the prompt */
808 /* get User Name and setup prompt */
809 strcpy(prompt,( geteuid() != 0 ) ? "$ ":"# ");
810 my_getpwuid(user, geteuid());
813 gethostname(buf, 255);
814 s = strchr(buf, '.');
823 snprintf(prompt_str, BUFSIZ-1, "[%s@%s %s]%s", user, buf,
824 get_last_path_component(cwd), prompt);
826 sprintf(prompt_str, "%s", prompt);
828 return(strdup(prompt_str)); /* Must free this memory */
833 static int get_command(FILE * source, char *command)
837 if (source == NULL) {
838 if (local_pending_command) {
839 /* a command specified (-c option): return it & mark it done */
840 strcpy(command, local_pending_command);
841 free(local_pending_command);
842 local_pending_command = NULL;
848 if (source == stdin) {
849 prompt_str = setup_prompt_string(shell_context);
851 #ifdef BB_FEATURE_SH_COMMAND_EDITING
853 ** enable command line editing only while a command line
854 ** is actually being read; otherwise, we'll end up bequeathing
855 ** atexit() handlers and other unwanted stuff to our
856 ** child processes (rob@sysgo.de)
858 cmdedit_read_input(prompt_str, command);
863 fputs(prompt_str, stdout);
868 if (!fgets(command, BUFSIZ - 2, source)) {
874 /* remove trailing newline */
875 command[strlen(command) - 1] = '\0';
880 #ifdef BB_FEATURE_SH_ENVIRONMENT
881 static char* itoa(register int i)
883 static char a[7]; /* Max 7 ints */
884 register char *b = a + sizeof(a) - 1;
892 *--b = '0' + (i % 10);
902 static void expand_argument(struct child_prog *prog, int *argcPtr,
903 int *argv_alloced_ptr)
905 int argc_l = *argcPtr;
906 int argv_alloced = *argv_alloced_ptr;
910 char *src, *dst, *var;
912 if (argc_l > 1) { /* cmd->glob_result is already initialized */
914 i = prog->glob_result.gl_pathc;
920 #ifdef BB_FEATURE_SH_ENVIRONMENT
921 /* do shell variable substitution */
922 src = prog->argv[argc_l - 1];
923 while((dst = strchr(src,'$')) != NULL){
924 if (!(var = getenv(dst + 1))) {
927 var = itoa(last_return_code);
930 var = itoa(getpid());
939 var = itoa(last_bg_pid);
941 case '0':case '1':case '2':case '3':case '4':
942 case '5':case '6':case '7':case '8':case '9':
944 int index=*(dst + 1)-48;
955 int offset = dst-src;
956 #warning I have a memory leak which needs to be plugged somehow
957 src = (char*)xmalloc(strlen(src)-strlen(dst)+strlen(var)+1);
958 strncpy(src, prog->argv[argc_l -1], offset);
959 safe_strncpy(src+offset, var, strlen(var)+1);
960 /* If there are any remaining $ variables in the src string, put them back */
961 if ((dst = strchr(prog->argv[argc_l -1]+offset+1,'$')) != NULL) {
963 safe_strncpy(src+strlen(src), dst, strlen(dst)+1);
965 prog->argv[argc_l -1] = src;
967 memset(dst, 0, strlen(src)-strlen(dst));
972 if (strpbrk(prog->argv[argc_l - 1],"*[]?")!= NULL){
973 rc = glob(prog->argv[argc_l - 1], flags, NULL, &prog->glob_result);
974 if (rc == GLOB_NOSPACE) {
975 error_msg("out of space during glob operation");
977 } else if (rc == GLOB_NOMATCH ||
978 (!rc && (prog->glob_result.gl_pathc - i) == 1 &&
979 strcmp(prog->argv[argc_l - 1],
980 prog->glob_result.gl_pathv[i]) == 0)) {
981 /* we need to remove whatever \ quoting is still present */
982 src = dst = prog->argv[argc_l - 1];
986 *dst++ = process_escape_sequence(&src);
994 argv_alloced += (prog->glob_result.gl_pathc - i);
995 prog->argv = xrealloc(prog->argv, argv_alloced * sizeof(*prog->argv));
996 memcpy(prog->argv + (argc_l - 1), prog->glob_result.gl_pathv + i,
997 sizeof(*(prog->argv)) * (prog->glob_result.gl_pathc - i));
998 argc_l += (prog->glob_result.gl_pathc - i - 1);
1001 src = dst = prog->argv[argc_l - 1];
1005 *dst++ = process_escape_sequence(&src);
1013 prog->glob_result.gl_pathc=0;
1015 prog->glob_result.gl_pathv=NULL;
1017 *argv_alloced_ptr = argv_alloced;
1021 /* Return cmd->num_progs as 0 if no command is present (e.g. an empty
1022 line). If a valid command is found, command_ptr is set to point to
1023 the beginning of the next command (if the original command had more
1024 then one job associated with it) or NULL if no more commands are
1026 static int parse_command(char **command_ptr, struct job *job, int *inbg)
1029 char *return_command = NULL;
1030 char *src, *buf, *chptr;
1037 struct child_prog *prog;
1039 /* skip leading white space */
1040 while (**command_ptr && isspace(**command_ptr))
1043 /* this handles empty lines or leading '#' characters */
1044 if (!**command_ptr || (**command_ptr == '#')) {
1051 job->progs = xmalloc(sizeof(*job->progs));
1053 /* We set the argv elements to point inside of this string. The
1054 memory is freed by free_job(). Allocate twice the original
1055 length in case we need to quote every single character.
1057 Getting clean memory relieves us of the task of NULL
1058 terminating things and makes the rest of this look a bit
1059 cleaner (though it is, admittedly, a tad less efficient) */
1060 job->cmdbuf = command = xcalloc(2*strlen(*command_ptr) + 1, sizeof(char));
1064 prog->num_redirects = 0;
1065 prog->redirects = NULL;
1066 prog->free_glob = 0;
1067 prog->is_stopped = 0;
1071 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1072 prog->argv[0] = job->cmdbuf;
1076 while (*src && !done) {
1077 if (quote == *src) {
1083 error_msg("character expected after \\");
1088 /* in shell, "\'" should yield \' */
1089 if (*src != quote) {
1093 } else if (*src == '*' || *src == '?' || *src == '[' ||
1094 *src == ']') *buf++ = '\\';
1096 } else if (isspace(*src)) {
1097 if (*prog->argv[argc_l]) {
1099 /* +1 here leaves room for the NULL which ends argv */
1100 if ((argc_l + 1) == argv_alloced) {
1102 prog->argv = xrealloc(prog->argv,
1103 sizeof(*prog->argv) *
1106 expand_argument(prog, &argc_l, &argv_alloced);
1107 prog->argv[argc_l] = buf;
1116 case '#': /* comment */
1123 case '>': /* redirects */
1125 i = prog->num_redirects++;
1126 prog->redirects = xrealloc(prog->redirects,
1127 sizeof(*prog->redirects) *
1130 prog->redirects[i].fd = -1;
1131 if (buf != prog->argv[argc_l]) {
1132 /* the stuff before this character may be the file number
1134 prog->redirects[i].fd =
1135 strtol(prog->argv[argc_l], &chptr, 10);
1137 if (*chptr && *prog->argv[argc_l]) {
1139 expand_argument(prog, &argc_l, &argv_alloced);
1140 prog->argv[argc_l] = buf;
1144 if (prog->redirects[i].fd == -1) {
1146 prog->redirects[i].fd = 1;
1148 prog->redirects[i].fd = 0;
1151 if (*src++ == '>') {
1153 prog->redirects[i].type =
1154 REDIRECT_APPEND, src++;
1156 prog->redirects[i].type = REDIRECT_OVERWRITE;
1158 prog->redirects[i].type = REDIRECT_INPUT;
1161 /* This isn't POSIX sh compliant. Oh well. */
1163 while (isspace(*chptr))
1167 error_msg("file name expected after %c", *src);
1173 prog->redirects[i].filename = buf;
1174 while (*chptr && !isspace(*chptr))
1177 src = chptr - 1; /* we src++ later */
1178 prog->argv[argc_l] = ++buf;
1181 case '|': /* pipe */
1182 /* finish this command */
1183 if (*prog->argv[argc_l])
1186 error_msg("empty command in pipe");
1191 prog->argv[argc_l] = NULL;
1193 /* and start the next */
1195 job->progs = xrealloc(job->progs,
1196 sizeof(*job->progs) * job->num_progs);
1197 prog = job->progs + (job->num_progs - 1);
1198 prog->num_redirects = 0;
1199 prog->redirects = NULL;
1200 prog->free_glob = 0;
1201 prog->is_stopped = 0;
1206 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1207 prog->argv[0] = ++buf;
1210 while (*src && isspace(*src))
1214 error_msg("empty command in pipe");
1219 src--; /* we'll ++ it at the end of the loop */
1223 case '&': /* background */
1225 case ';': /* multiple commands */
1227 return_command = *command_ptr + (src - *command_ptr) + 1;
1230 #ifdef BB_FEATURE_SH_BACKTICKS
1232 /* Exec a backtick-ed command */
1233 /* Besides any previous brokenness, I have not
1234 * updated backtick handling for close_me support.
1235 * I don't know if it needs it or not. -- LRD */
1237 char* charptr1=NULL, *charptr2;
1240 struct jobset njob_list = { NULL, NULL };
1244 ptr=strchr(++src, '`');
1246 fprintf(stderr, "Unmatched '`' in command\n");
1251 /* Make some space to hold just the backticked command */
1252 charptr1 = charptr2 = xmalloc(1+ptr-src);
1253 memcpy(charptr1, src, ptr-src);
1254 charptr1[ptr-src] = '\0';
1255 newjob = xmalloc(sizeof(struct job));
1256 newjob->job_list = &njob_list;
1257 /* Now parse and run the backticked command */
1258 if (!parse_command(&charptr1, newjob, inbg)
1259 && newjob->num_progs) {
1261 run_command(newjob, 0, pipefd);
1263 checkjobs(job->job_list);
1264 free_job(newjob); /* doesn't actually free newjob,
1265 looks like a memory leak */
1268 /* Make a copy of any stuff left over in the command
1269 * line after the second backtick */
1270 charptr2 = xmalloc(strlen(ptr)+1);
1271 memcpy(charptr2, ptr+1, strlen(ptr));
1274 /* Copy the output from the backtick-ed command into the
1275 * command line, making extra room as needed */
1277 charptr1 = xmalloc(BUFSIZ);
1278 while ( (size=full_read(pipefd[0], charptr1, BUFSIZ-1)) >0) {
1279 int newsize=src - *command_ptr + size + 1 + strlen(charptr2);
1280 if (newsize > BUFSIZ) {
1281 *command_ptr=xrealloc(*command_ptr, newsize);
1283 memcpy(src, charptr1, size);
1291 /* Now paste into the *command_ptr all the stuff
1292 * leftover after the second backtick */
1293 memcpy(src, charptr2, strlen(charptr2)+1);
1296 /* Now recursively call parse_command to deal with the new
1297 * and improved version of the command line with the backtick
1298 * results expanded in place... */
1300 struct jobset *jl=job->job_list;
1304 return(parse_command(command_ptr, job, inbg));
1307 #endif // BB_FEATURE_SH_BACKTICKS
1312 /* This is currently a little broken... */
1313 #ifdef HANDLE_CONTINUATION_CHARS
1314 /* They fed us a continuation char, so continue reading stuff
1315 * on the next line, then tack that onto the end of the current
1319 printf("erik: found a continue char at EOL...\n");
1320 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1321 if (get_command(input, command)) {
1322 error_msg("character expected after \\");
1327 newsize = strlen(*command_ptr) + strlen(command) + 2;
1328 if (newsize > BUFSIZ) {
1329 printf("erik: doing realloc\n");
1330 *command_ptr=xrealloc(*command_ptr, newsize);
1332 printf("erik: A: *command_ptr='%s'\n", *command_ptr);
1333 memcpy(--src, command, strlen(command));
1334 printf("erik: B: *command_ptr='%s'\n", *command_ptr);
1338 error_msg("character expected after \\");
1344 if (*src == '*' || *src == '[' || *src == ']'
1345 || *src == '?') *buf++ = '\\';
1354 if (*prog->argv[argc_l]) {
1356 expand_argument(prog, &argc_l, &argv_alloced);
1362 prog->argv[argc_l] = NULL;
1364 if (!return_command) {
1365 job->text = xmalloc(strlen(*command_ptr) + 1);
1366 strcpy(job->text, *command_ptr);
1368 /* This leaves any trailing spaces, which is a bit sloppy */
1369 count = return_command - *command_ptr;
1370 job->text = xmalloc(count + 1);
1371 strncpy(job->text, *command_ptr, count);
1372 job->text[count] = '\0';
1375 *command_ptr = return_command;
1380 /* Run the child_prog, no matter what kind of command it uses.
1382 static int pseudo_exec(struct child_prog *child)
1384 struct built_in_command *x;
1385 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
1389 /* Check if the command matches any of the non-forking builtins.
1390 * Depending on context, this might be redundant. But it's
1391 * easier to waste a few CPU cycles than it is to figure out
1392 * if this is one of those cases.
1394 for (x = bltins; x->cmd; x++) {
1395 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1396 exit(x->function(child));
1400 /* Check if the command matches any of the forking builtins. */
1401 for (x = bltins_forking; x->cmd; x++) {
1402 if (strcmp(child->argv[0], x->cmd) == 0) {
1404 exit (x->function(child));
1407 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
1408 /* Check if the command matches any busybox internal
1409 * commands ("applets") here. Following discussions from
1410 * November 2000 on busybox@opensource.lineo.com, don't use
1411 * get_last_path_component(). This way explicit (with
1412 * slashes) filenames will never be interpreted as an
1413 * applet, just like with builtins. This way the user can
1414 * override an applet with an explicit filename reference.
1415 * The only downside to this change is that an explicit
1416 * /bin/foo invocation will fork and exec /bin/foo, even if
1417 * /bin/foo is a symlink to busybox.
1419 name = child->argv[0];
1421 #ifdef BB_FEATURE_SH_APPLETS_ALWAYS_WIN
1422 /* If you enable BB_FEATURE_SH_APPLETS_ALWAYS_WIN, then
1423 * if you run /bin/cat, it will use BusyBox cat even if
1424 * /bin/cat exists on the filesystem and is _not_ busybox.
1425 * Some systems want this, others do not. Choose wisely. :-)
1427 name = get_last_path_component(name);
1431 char** argv=child->argv;
1433 for(argc_l=0;*argv!=NULL; argv++, argc_l++);
1435 run_applet_by_name(name, argc_l, child->argv);
1439 execvp(child->argv[0], child->argv);
1440 perror_msg_and_die("%s", child->argv[0]);
1443 static void insert_job(struct job *newjob, int inbg)
1446 struct jobset *job_list=newjob->job_list;
1448 /* find the ID for thejob to use */
1450 for (thejob = job_list->head; thejob; thejob = thejob->next)
1451 if (thejob->jobid >= newjob->jobid)
1452 newjob->jobid = thejob->jobid + 1;
1454 /* add thejob to the list of running jobs */
1455 if (!job_list->head) {
1456 thejob = job_list->head = xmalloc(sizeof(*thejob));
1458 for (thejob = job_list->head; thejob->next; thejob = thejob->next) /* nothing */;
1459 thejob->next = xmalloc(sizeof(*thejob));
1460 thejob = thejob->next;
1463 *thejob = *newjob; /* physically copy the struct job */
1464 thejob->next = NULL;
1465 thejob->running_progs = thejob->num_progs;
1466 thejob->stopped_progs = 0;
1469 /* we don't wait for background thejobs to return -- append it
1470 to the list of backgrounded thejobs and leave it alone */
1471 printf("[%d] %d\n", thejob->jobid,
1472 newjob->progs[newjob->num_progs - 1].pid);
1473 #ifdef BB_FEATURE_SH_ENVIRONMENT
1474 last_bg_pid=newjob->progs[newjob->num_progs - 1].pid;
1477 newjob->job_list->fg = thejob;
1479 /* move the new process group into the foreground */
1480 /* suppress messages when run from /linuxrc mag@sysgo.de */
1481 if (tcsetpgrp(0, newjob->pgrp) && errno != ENOTTY)
1482 perror_msg("tcsetpgrp");
1486 static int run_command(struct job *newjob, int inbg, int outpipe[2])
1488 /* struct job *thejob; */
1490 int nextin, nextout;
1491 int pipefds[2]; /* pipefd[0] is for reading */
1492 struct built_in_command *x;
1493 struct child_prog *child;
1495 nextin = 0, nextout = 1;
1496 for (i = 0; i < newjob->num_progs; i++) {
1497 child = & (newjob->progs[i]);
1499 if ((i + 1) < newjob->num_progs) {
1500 if (pipe(pipefds)<0) perror_msg_and_die("pipe");
1501 nextout = pipefds[1];
1503 if (outpipe[1]!=-1) {
1504 nextout = outpipe[1];
1510 #ifdef BB_FEATURE_SH_ENVIRONMENT
1511 if (show_x_trace==TRUE) {
1514 for (j = 0; child->argv[j]; j++) {
1516 fputs(child->argv[j], stderr);
1518 fputc('\n', stderr);
1522 /* Check if the command matches any non-forking builtins,
1523 * but only if this is a simple command.
1524 * Non-forking builtins within pipes have to fork anyway,
1525 * and are handled in pseudo_exec. "echo foo | read bar"
1526 * is doomed to failure, and doesn't work on bash, either.
1528 if (newjob->num_progs == 1) {
1529 for (x = bltins; x->cmd; x++) {
1530 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1531 int squirrel[] = {-1, -1, -1};
1533 setup_redirects(child, squirrel);
1534 rcode = x->function(child);
1535 restore_redirects(squirrel);
1541 if (!(child->pid = fork())) {
1542 signal(SIGTTOU, SIG_DFL);
1546 if (outpipe[1]!=-1) {
1556 dup2(nextout, 2); /* Really? */
1561 /* explicit redirects override pipes */
1562 setup_redirects(child,NULL);
1566 if (outpipe[1]!=-1) {
1570 /* put our child in the process group whose leader is the
1571 first process in this pipe */
1572 setpgid(child->pid, newjob->progs[0].pid);
1578 /* If there isn't another process, nextin is garbage
1579 but it doesn't matter */
1580 nextin = pipefds[0];
1583 newjob->pgrp = newjob->progs[0].pid;
1585 insert_job(newjob, inbg);
1590 static int busy_loop(FILE * input)
1593 char *next_command = NULL;
1599 newjob.job_list = &job_list;
1600 newjob.job_context = DEFAULT_CONTEXT;
1602 /* save current owner of TTY so we can restore it on exit */
1603 parent_pgrp = tcgetpgrp(0);
1605 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1607 /* don't pay any attention to this signal; it just confuses
1608 things and isn't really meant for shells anyway */
1609 signal(SIGTTOU, SIG_IGN);
1613 /* no job is in the foreground */
1615 /* see if any background processes have exited */
1616 checkjobs(&job_list);
1618 if (!next_command) {
1619 if (get_command(input, command))
1621 next_command = command;
1624 if (!parse_command(&next_command, &newjob, &inbg) &&
1626 int pipefds[2] = {-1,-1};
1627 debug_printf( "job=%p being fed to run_command by busy_loop()'\n", &newjob);
1628 run_command(&newjob, inbg, pipefds);
1632 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1633 next_command = NULL;
1636 /* a job is running in the foreground; wait for it */
1638 while (!job_list.fg->progs[i].pid ||
1639 job_list.fg->progs[i].is_stopped == 1) i++;
1641 if (waitpid(job_list.fg->progs[i].pid, &status, WUNTRACED)<0)
1642 perror_msg_and_die("waitpid(%d)",job_list.fg->progs[i].pid);
1644 if (WIFEXITED(status) || WIFSIGNALED(status)) {
1645 /* the child exited */
1646 job_list.fg->running_progs--;
1647 job_list.fg->progs[i].pid = 0;
1649 #ifdef BB_FEATURE_SH_ENVIRONMENT
1650 last_return_code=WEXITSTATUS(status);
1652 debug_printf("'%s' exited -- return code %d\n",
1653 job_list.fg->text, last_return_code);
1654 if (!job_list.fg->running_progs) {
1656 remove_job(&job_list, job_list.fg);
1660 /* the child was stopped */
1661 job_list.fg->stopped_progs++;
1662 job_list.fg->progs[i].is_stopped = 1;
1664 if (job_list.fg->stopped_progs == job_list.fg->running_progs) {
1665 printf("\n" JOB_STATUS_FORMAT, job_list.fg->jobid,
1666 "Stopped", job_list.fg->text);
1672 /* move the shell to the foreground */
1673 /* suppress messages when run from /linuxrc mag@sysgo.de */
1674 if (tcsetpgrp(0, getpid()) && errno != ENOTTY)
1675 perror_msg("tcsetpgrp");
1681 /* return controlling TTY back to parent process group before exiting */
1682 if (tcsetpgrp(0, parent_pgrp))
1683 perror_msg("tcsetpgrp");
1685 /* return exit status if called with "-c" */
1686 if (input == NULL && WIFEXITED(status))
1687 return WEXITSTATUS(status);
1693 #ifdef BB_FEATURE_CLEAN_UP
1694 void free_memory(void)
1698 if (local_pending_command)
1699 free(local_pending_command);
1701 if (job_list.fg && !job_list.fg->running_progs) {
1702 remove_job(&job_list, job_list.fg);
1708 int shell_main(int argc_l, char **argv_l)
1710 int opt, interactive=FALSE;
1711 FILE *input = stdin;
1717 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
1718 /* These variables need re-initializing when recursing */
1719 local_pending_command = NULL;
1720 job_list.head = NULL;
1722 #ifdef BB_FEATURE_SH_ENVIRONMENT
1724 last_return_code=-1;
1729 if (argv[0] && argv[0][0] == '-') {
1731 prof_input = fopen("/etc/profile", "r");
1733 printf( "Couldn't open file '/etc/profile'\n");
1735 int tmp_fd = fileno(prof_input);
1737 /* Now run the file */
1738 busy_loop(prof_input);
1740 mark_closed(tmp_fd);
1744 while ((opt = getopt(argc_l, argv_l, "cxi")) > 0) {
1748 if (local_pending_command != 0)
1749 error_msg_and_die("multiple -c arguments");
1750 local_pending_command = xstrdup(argv[optind]);
1754 #ifdef BB_FEATURE_SH_ENVIRONMENT
1756 show_x_trace = TRUE;
1766 /* A shell is interactive if the `-i' flag was given, or if all of
1767 * the following conditions are met:
1769 * no arguments remaining or the -s flag given
1770 * standard input is a terminal
1771 * standard output is a terminal
1772 * Refer to Posix.2, the description of the `sh' utility. */
1773 if (argv[optind]==NULL && input==stdin &&
1774 isatty(fileno(stdin)) && isatty(fileno(stdout))) {
1777 if (interactive==TRUE) {
1778 //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
1779 /* Looks like they want an interactive shell */
1780 printf( "\n\nBusyBox v%s (%s) Built-in shell (lash)\n", BB_VER, BB_BT);
1781 printf( "Enter 'help' for a list of built-in commands.\n\n");
1782 } else if (local_pending_command==NULL) {
1783 //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
1784 input = xfopen(argv[optind], "r");
1785 mark_open(fileno(input)); /* be lazy, never mark this closed */
1788 /* initialize the cwd -- this is never freed...*/
1789 cwd=(char*)xmalloc(sizeof(char)*MAX_LINE+1);
1790 getcwd(cwd, sizeof(char)*MAX_LINE);
1792 #ifdef BB_FEATURE_CLEAN_UP
1793 atexit(free_memory);
1796 return (busy_loop(input));