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 -- sortof...
43 #define BB_FEATURE_SH_IF_EXPRESSIONS
45 /* This is currently sortof broken, only for the brave... */
46 #undef HANDLE_CONTINUATION_CHARS
48 /* This would be great -- if wordexp wouldn't strip all quoting
49 * out from the target strings... As is, a parser needs */
50 #undef BB_FEATURE_SH_WORDEXP
52 //For debugging/development on the shell only...
63 #include <sys/ioctl.h>
68 // fix compile with uClibc (which does #define index strchr) -andy
73 #undef BB_FEATURE_SH_WORDEXP
75 #if BB_FEATURE_SH_WORDEXP
77 #define expand_t wordexp_t
78 #undef BB_FEATURE_SH_BACKTICKS
81 #define expand_t glob_t
87 static const int MAX_LINE = 256; /* size of input buffer for cwd data */
88 static const int MAX_READ = 128; /* size of input buffer for `read' builtin */
89 #define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
92 enum redir_type { REDIRECT_INPUT, REDIRECT_OVERWRITE,
96 static const unsigned int DEFAULT_CONTEXT=0x1;
97 static const unsigned int IF_TRUE_CONTEXT=0x2;
98 static const unsigned int IF_FALSE_CONTEXT=0x4;
99 static const unsigned int THEN_EXP_CONTEXT=0x8;
100 static const unsigned int ELSE_EXP_CONTEXT=0x10;
104 struct job *head; /* head of list of running jobs */
105 struct job *fg; /* current foreground job */
108 struct redir_struct {
109 enum redir_type type; /* type of redirection */
110 int fd; /* file descriptor being redirected */
111 char *filename; /* file to redirect fd to */
115 pid_t pid; /* 0 if exited */
116 char **argv; /* program name and arguments */
117 int num_redirects; /* elements in redirection array */
118 struct redir_struct *redirects; /* I/O redirects */
119 int is_stopped; /* is the program currently running? */
120 struct job *family; /* pointer back to the child's parent job */
124 int jobid; /* job number */
125 int num_progs; /* total number of programs in job */
126 int running_progs; /* number of programs running */
127 char *text; /* name of job */
128 char *cmdbuf; /* buffer various argv's point into */
129 pid_t pgrp; /* process group ID for the job */
130 struct child_prog *progs; /* array of programs in job */
131 struct job *next; /* to track background commands */
132 int stopped_progs; /* number of programs alive, but stopped */
133 unsigned int job_context; /* bitmask defining current context */
134 struct jobset *job_list;
137 struct built_in_command {
138 char *cmd; /* name */
139 char *descr; /* description */
140 int (*function) (struct child_prog *); /* function ptr */
145 struct close_me *next;
148 /* function prototypes for builtins */
149 static int builtin_cd(struct child_prog *cmd);
150 static int builtin_env(struct child_prog *dummy);
151 static int builtin_exec(struct child_prog *cmd);
152 static int builtin_exit(struct child_prog *cmd);
153 static int builtin_fg_bg(struct child_prog *cmd);
154 static int builtin_help(struct child_prog *cmd);
155 static int builtin_jobs(struct child_prog *dummy);
156 static int builtin_pwd(struct child_prog *dummy);
157 static int builtin_export(struct child_prog *cmd);
158 static int builtin_source(struct child_prog *cmd);
159 static int builtin_unset(struct child_prog *cmd);
160 static int builtin_read(struct child_prog *cmd);
161 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
162 static int builtin_if(struct child_prog *cmd);
163 static int builtin_then(struct child_prog *cmd);
164 static int builtin_else(struct child_prog *cmd);
165 static int builtin_fi(struct child_prog *cmd);
166 /* function prototypes for shell stuff */
167 static int run_command_predicate(char *cmd);
171 /* function prototypes for shell stuff */
172 static void mark_open(int fd);
173 static void mark_closed(int fd);
174 static void close_all(void);
175 static void checkjobs(struct jobset *job_list);
176 static int get_command(FILE * source, char *command);
177 static int parse_command(char **command_ptr, struct job *job, int *inbg);
178 static int run_command(struct job *newjob, int inbg, int outpipe[2]);
179 static int pseudo_exec(struct child_prog *cmd) __attribute__ ((noreturn));
180 static int busy_loop(FILE * input);
183 /* Table of built-in functions (these are non-forking builtins, meaning they
184 * can change global variables in the parent shell process but they will not
185 * work with pipes and redirects; 'unset foo | whatever' will not work) */
186 static struct built_in_command bltins[] = {
187 {"bg", "Resume a job in the background", builtin_fg_bg},
188 {"cd", "Change working directory", builtin_cd},
189 {"exec", "Exec command, replacing this shell with the exec'd process", builtin_exec},
190 {"exit", "Exit from shell()", builtin_exit},
191 {"fg", "Bring job into the foreground", builtin_fg_bg},
192 {"jobs", "Lists the active jobs", builtin_jobs},
193 {"export", "Set environment variable", builtin_export},
194 {"unset", "Unset environment variable", builtin_unset},
195 {"read", "Input environment variable", builtin_read},
196 {".", "Source-in and run commands in a file", builtin_source},
197 /* to do: add ulimit */
198 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
199 {"if", NULL, builtin_if},
200 {"then", NULL, builtin_then},
201 {"else", NULL, builtin_else},
202 {"fi", NULL, builtin_fi},
207 /* Table of forking built-in functions (things that fork cannot change global
208 * variables in the parent process, such as the current working directory) */
209 static struct built_in_command bltins_forking[] = {
210 {"env", "Print all environment variables", builtin_env},
211 {"pwd", "Print current directory", builtin_pwd},
212 {"help", "List shell built-in commands", builtin_help},
217 /* Variables we export */
218 unsigned int shell_context; /* Used in cmdedit.c to reset the
219 context when someone hits ^C */
222 /* Globals that are static to this file */
224 static char *local_pending_command = NULL;
225 static struct jobset job_list = { NULL, NULL };
228 static struct close_me *close_me_head;
229 #ifdef BB_FEATURE_SH_ENVIRONMENT
230 static int last_bg_pid;
231 static int last_return_code;
232 static int show_x_trace;
234 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
235 static char syntax_err[]="syntax error near unexpected token";
243 static inline void debug_printf(const char *format, ...)
246 va_start(args, format);
247 vfprintf(stderr, format, args);
251 static inline void debug_printf(const char *format, ...) { }
255 Most builtins need access to the struct child_prog that has
256 their arguments, previously coded as cmd->progs[0]. That coding
257 can exhibit a bug, if the builtin is not the first command in
258 a pipeline: "echo foo | exec sort" will attempt to exec foo.
260 builtin previous use notes
261 ------ ----------------- ---------
264 exec cmd->progs[0] squashed bug: didn't look for applets or forking builtins
266 fg_bg cmd->progs[0], job_list->head, job_list->fg
270 export cmd->progs[0] passes cmd, job_list to builtin_env(), which ignores them
274 if cmd->job_context, cmd->text
275 then cmd->job_context, cmd->text
276 else cmd->job_context, cmd->text
279 The use of cmd->text by if/then/else/fi is hopelessly hacky.
280 Would it work to increment cmd->progs[0]->argv and recurse,
281 somewhat like builtin_exec does?
283 I added "struct job *family;" to struct child_prog,
284 and switched API to builtin_foo(struct child_prog *child);
285 So cmd->text becomes child->family->text
286 cmd->job_context becomes child->family->job_context
287 cmd->progs[0] becomes *child
288 job_list becomes child->family->job_list
291 /* built-in 'cd <path>' handler */
292 static int builtin_cd(struct child_prog *child)
296 if (child->argv[1] == NULL)
297 newdir = getenv("HOME");
299 newdir = child->argv[1];
301 printf("cd: %s: %m\n", newdir);
304 getcwd(cwd, sizeof(char)*MAX_LINE);
309 /* built-in 'env' handler */
310 static int builtin_env(struct child_prog *dummy)
314 for (e = environ; *e; e++) {
320 /* built-in 'exec' handler */
321 static int builtin_exec(struct child_prog *child)
323 if (child->argv[1] == NULL)
324 return EXIT_SUCCESS; /* Really? */
331 /* built-in 'exit' handler */
332 static int builtin_exit(struct child_prog *child)
334 if (child->argv[1] == NULL)
337 exit (atoi(child->argv[1]));
340 /* built-in 'fg' and 'bg' handler */
341 static int builtin_fg_bg(struct child_prog *child)
344 struct job *job=NULL;
346 if (!child->argv[1] || child->argv[2]) {
347 error_msg("%s: exactly one argument is expected",
352 if (sscanf(child->argv[1], "%%%d", &jobNum) != 1) {
353 error_msg("%s: bad argument '%s'",
354 child->argv[0], child->argv[1]);
358 for (job = child->family->job_list->head; job; job = job->next) {
359 if (job->jobid == jobNum) {
365 error_msg("%s: unknown job %d",
366 child->argv[0], jobNum);
370 if (*child->argv[0] == 'f') {
371 /* Make this job the foreground job */
372 /* suppress messages when run from /linuxrc mag@sysgo.de */
373 if (tcsetpgrp(0, job->pgrp) && errno != ENOTTY)
374 perror_msg("tcsetpgrp");
375 child->family->job_list->fg = job;
378 /* Restart the processes in the job */
379 for (i = 0; i < job->num_progs; i++)
380 job->progs[i].is_stopped = 0;
382 kill(-job->pgrp, SIGCONT);
384 job->stopped_progs = 0;
389 /* built-in 'help' handler */
390 static int builtin_help(struct child_prog *dummy)
392 struct built_in_command *x;
394 printf("\nBuilt-in commands:\n");
395 printf("-------------------\n");
396 for (x = bltins; x->cmd; x++) {
399 printf("%s\t%s\n", x->cmd, x->descr);
401 for (x = bltins_forking; x->cmd; x++) {
404 printf("%s\t%s\n", x->cmd, x->descr);
410 /* built-in 'jobs' handler */
411 static int builtin_jobs(struct child_prog *child)
416 for (job = child->family->job_list->head; job; job = job->next) {
417 if (job->running_progs == job->stopped_progs)
418 status_string = "Stopped";
420 status_string = "Running";
422 printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->text);
428 /* built-in 'pwd' handler */
429 static int builtin_pwd(struct child_prog *dummy)
431 getcwd(cwd, MAX_LINE);
432 printf( "%s\n", cwd);
436 /* built-in 'export VAR=value' handler */
437 static int builtin_export(struct child_prog *child)
440 char *v = child->argv[1];
443 return (builtin_env(child));
447 fprintf(stderr, "export: %m\n");
448 #ifndef BB_FEATURE_SH_SIMPLE_PROMPT
449 if (strncmp(v, "PS1=", 4)==0)
451 else if (strncmp(v, "PS2=", 4)==0)
457 /* built-in 'read VAR' handler */
458 static int builtin_read(struct child_prog *child)
460 int res = 0, len, newlen;
462 char string[MAX_READ];
464 if (child->argv[1]) {
465 /* argument (VAR) given: put "VAR=" into buffer */
466 strcpy(string, child->argv[1]);
467 len = strlen(string);
470 fgets(&string[len], sizeof(string) - len, stdin); /* read string */
471 newlen = strlen(string);
473 string[--newlen] = '\0'; /* chomp trailing newline */
475 ** string should now contain "VAR=<value>"
476 ** copy it (putenv() won't do that, so we must make sure
477 ** the string resides in a static buffer!)
480 if((s = strdup(string)))
483 fprintf(stderr, "read: %m\n");
486 fgets(string, sizeof(string), stdin);
491 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
492 /* Built-in handler for 'if' commands */
493 static int builtin_if(struct child_prog *child)
495 struct job *cmd = child->family;
497 char* charptr1=cmd->text+3; /* skip over the leading 'if ' */
499 /* Now run the 'if' command */
500 debug_printf( "job=%p entering builtin_if ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
501 status = run_command_predicate(charptr1);
502 debug_printf( "if test returned ");
504 debug_printf( "TRUE\n");
505 cmd->job_context |= IF_TRUE_CONTEXT;
507 debug_printf( "FALSE\n");
508 cmd->job_context |= IF_FALSE_CONTEXT;
510 debug_printf("job=%p builtin_if set job context to %x\n", cmd, cmd->job_context);
516 /* Built-in handler for 'then' (part of the 'if' command) */
517 static int builtin_then(struct child_prog *child)
519 struct job *cmd = child->family;
520 char* charptr1=cmd->text+5; /* skip over the leading 'then ' */
522 debug_printf( "job=%p entering builtin_then ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
523 if (! (cmd->job_context & (IF_TRUE_CONTEXT|IF_FALSE_CONTEXT))) {
524 shell_context = 0; /* Reset the shell's context on an error */
525 error_msg("%s `then'", syntax_err);
529 cmd->job_context |= THEN_EXP_CONTEXT;
530 debug_printf("job=%p builtin_then set job context to %x\n", cmd, cmd->job_context);
532 /* If the if result was FALSE, skip the 'then' stuff */
533 if (cmd->job_context & IF_FALSE_CONTEXT) {
537 /* Seems the if result was TRUE, so run the 'then' command */
538 debug_printf( "'then' now running '%s'\n", charptr1);
540 return(run_command_predicate(charptr1));
543 /* Built-in handler for 'else' (part of the 'if' command) */
544 static int builtin_else(struct child_prog *child)
546 struct job *cmd = child->family;
547 char* charptr1=cmd->text+5; /* skip over the leading 'else ' */
549 debug_printf( "job=%p entering builtin_else ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
551 if (! (cmd->job_context & THEN_EXP_CONTEXT)) {
552 shell_context = 0; /* Reset the shell's context on an error */
553 error_msg("%s `else'", syntax_err);
556 /* If the if result was TRUE, skip the 'else' stuff */
557 if (cmd->job_context & IF_TRUE_CONTEXT) {
561 cmd->job_context |= ELSE_EXP_CONTEXT;
562 debug_printf("job=%p builtin_else set job context to %x\n", cmd, cmd->job_context);
564 /* Now run the 'else' command */
565 debug_printf( "'else' now running '%s'\n", charptr1);
566 return(run_command_predicate(charptr1));
569 /* Built-in handler for 'fi' (part of the 'if' command) */
570 static int builtin_fi(struct child_prog *child)
572 struct job *cmd = child->family;
573 debug_printf( "job=%p entering builtin_fi ('%s')-- context=%d\n", cmd, "", cmd->job_context);
574 if (! (cmd->job_context & (IF_TRUE_CONTEXT|IF_FALSE_CONTEXT))) {
575 shell_context = 0; /* Reset the shell's context on an error */
576 error_msg("%s `fi'", syntax_err);
579 /* Clear out the if and then context bits */
580 cmd->job_context &= ~(IF_TRUE_CONTEXT|IF_FALSE_CONTEXT|THEN_EXP_CONTEXT|ELSE_EXP_CONTEXT);
581 debug_printf("job=%p builtin_fi set job context to %x\n", cmd, cmd->job_context);
587 /* Built-in '.' handler (read-in and execute commands from file) */
588 static int builtin_source(struct child_prog *child)
594 if (child->argv[1] == NULL)
597 input = fopen(child->argv[1], "r");
599 printf( "Couldn't open file '%s'\n", child->argv[1]);
605 /* Now run the file */
606 status = busy_loop(input);
612 /* built-in 'unset VAR' handler */
613 static int builtin_unset(struct child_prog *child)
615 if (child->argv[1] == NULL) {
616 printf( "unset: parameter required.\n");
619 unsetenv(child->argv[1]);
623 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
624 /* currently used by if/then/else.
626 * Reparsing the command line for this purpose is gross,
627 * incorrect, and fundamentally unfixable; in particular,
628 * think about what happens with command substitution.
629 * We really need to pull out the run, wait, return status
630 * functionality out of busy_loop so we can child->argv++
631 * and use that, without going back through parse_command.
633 static int run_command_predicate(char *cmd)
636 local_pending_command = xmalloc(n+1);
637 strncpy(local_pending_command, cmd, n);
638 local_pending_command[n]='\0';
639 return( busy_loop(NULL));
643 static void mark_open(int fd)
645 struct close_me *new = xmalloc(sizeof(struct close_me));
647 new->next = close_me_head;
651 static void mark_closed(int fd)
653 struct close_me *tmp;
654 if (close_me_head == NULL || close_me_head->fd != fd)
655 error_msg_and_die("corrupt close_me");
657 close_me_head = close_me_head->next;
661 static void close_all()
663 struct close_me *c, *tmp;
664 for (c=close_me_head; c; c=tmp) {
669 close_me_head = NULL;
673 /* free up all memory from a job */
674 static void free_job(struct job *cmd)
679 for (i = 0; i < cmd->num_progs; i++) {
680 free(cmd->progs[i].argv);
681 if (cmd->progs[i].redirects)
682 free(cmd->progs[i].redirects);
690 keep = cmd->job_list;
691 memset(cmd, 0, sizeof(struct job));
692 cmd->job_list = keep;
695 /* remove a job from the job_list */
696 static void remove_job(struct jobset *job_list, struct job *job)
701 if (job == job_list->head) {
702 job_list->head = job->next;
704 prevjob = job_list->head;
705 while (prevjob->next != job)
706 prevjob = prevjob->next;
707 prevjob->next = job->next;
713 /* Checks to see if any background processes have exited -- if they
714 have, figure out why and see if a job has completed */
715 static void checkjobs(struct jobset *job_list)
722 while ((childpid = waitpid(-1, &status, WNOHANG | WUNTRACED)) > 0) {
723 for (job = job_list->head; job; job = job->next) {
725 while (prognum < job->num_progs &&
726 job->progs[prognum].pid != childpid) prognum++;
727 if (prognum < job->num_progs)
731 /* This happens on backticked commands */
735 if (WIFEXITED(status) || WIFSIGNALED(status)) {
737 job->running_progs--;
738 job->progs[prognum].pid = 0;
740 if (!job->running_progs) {
741 printf(JOB_STATUS_FORMAT, job->jobid, "Done", job->text);
742 remove_job(job_list, job);
746 job->stopped_progs++;
747 job->progs[prognum].is_stopped = 1;
749 if (job->stopped_progs == job->num_progs) {
750 printf(JOB_STATUS_FORMAT, job->jobid, "Stopped",
756 if (childpid == -1 && errno != ECHILD)
757 perror_msg("waitpid");
760 /* squirrel != NULL means we squirrel away copies of stdin, stdout,
761 * and stderr if they are redirected. */
762 static int setup_redirects(struct child_prog *prog, int squirrel[])
767 struct redir_struct *redir = prog->redirects;
769 for (i = 0; i < prog->num_redirects; i++, redir++) {
770 switch (redir->type) {
774 case REDIRECT_OVERWRITE:
775 mode = O_WRONLY | O_CREAT | O_TRUNC;
777 case REDIRECT_APPEND:
778 mode = O_WRONLY | O_CREAT | O_APPEND;
782 openfd = open(redir->filename, mode, 0666);
784 /* this could get lost if stderr has been redirected, but
785 bash and ash both lose it as well (though zsh doesn't!) */
786 perror_msg("error opening %s", redir->filename);
790 if (openfd != redir->fd) {
791 if (squirrel && redir->fd < 3) {
792 squirrel[redir->fd] = dup(redir->fd);
794 dup2(openfd, redir->fd);
802 static void restore_redirects(int squirrel[])
805 for (i=0; i<3; i++) {
808 /* No error checking. I sure wouldn't know what
809 * to do with an error if I found one! */
816 static inline void cmdedit_set_initial_prompt(void)
818 #ifdef BB_FEATURE_SH_SIMPLE_PROMPT
832 static inline void setup_prompt_string(char **prompt_str)
834 #ifdef BB_FEATURE_SH_SIMPLE_PROMPT
835 /* Set up the prompt */
836 if (shell_context == 0) {
839 PS1=xmalloc(strlen(cwd)+4);
840 sprintf(PS1, "%s %s", cwd, ( geteuid() != 0 ) ? "$ ":"# ");
846 *prompt_str = (shell_context==0)? PS1 : PS2;
850 static int get_command(FILE * source, char *command)
854 if (source == NULL) {
855 if (local_pending_command) {
856 /* a command specified (-c option): return it & mark it done */
857 strcpy(command, local_pending_command);
858 free(local_pending_command);
859 local_pending_command = NULL;
865 if (source == stdin) {
866 setup_prompt_string(&prompt_str);
868 #ifdef BB_FEATURE_COMMAND_EDITING
870 ** enable command line editing only while a command line
871 ** is actually being read; otherwise, we'll end up bequeathing
872 ** atexit() handlers and other unwanted stuff to our
873 ** child processes (rob@sysgo.de)
875 cmdedit_read_input(prompt_str, command);
879 fputs(prompt_str, stdout);
883 if (!fgets(command, BUFSIZ - 2, source)) {
889 /* remove trailing newline */
895 #ifdef BB_FEATURE_SH_ENVIRONMENT
896 static char* itoa(register int i)
898 static char a[7]; /* Max 7 ints */
899 register char *b = a + sizeof(a) - 1;
907 *--b = '0' + (i % 10);
917 #if defined BB_FEATURE_SH_ENVIRONMENT && ! defined BB_FEATURE_SH_WORDEXP
918 char * strsep_space( char *string, int * index)
924 /* Short circuit the trivial case */
925 if ( !string || ! string[*index])
928 /* Find the end of the token. */
929 while( string && string[*index] && !isspace(string[*index]) ) {
933 /* Find the end of any whitespace trailing behind
934 * the token and let that be part of the token */
935 while( string && string[*index] && isspace(string[*index]) ) {
939 if (! string && *index==0) {
940 /* Nothing useful was found */
944 token = xmalloc(*index+1);
945 token[*index] = '\0';
946 strncpy(token, string, *index);
953 static int expand_arguments(char *command)
955 #ifdef BB_FEATURE_SH_ENVIRONMENT
956 expand_t expand_result;
957 char *src, *dst, *var;
959 int i=0, length, total_length=0, retval;
960 const char *out_of_space = "out of space during expansion";
963 /* get rid of the terminating \n */
966 /* Fix up escape sequences to be the Real Thing(tm) */
967 while( command && command[index]) {
968 if (command[index] == '\\') {
969 char *tmp = command+index+1;
970 command[index+1] = process_escape_sequence( &tmp );
971 memmove(command+index, command+index+1, strlen(command+index));
976 #ifdef BB_FEATURE_SH_ENVIRONMENT
979 #if BB_FEATURE_SH_WORDEXP
980 /* This first part uses wordexp() which is a wonderful C lib
981 * function which expands nearly everything. */
982 retval = wordexp (command, &expand_result, WRDE_SHOWERR);
983 if (retval == WRDE_NOSPACE) {
984 /* Mem may have been allocated... */
985 wordfree (&expand_result);
986 error_msg(out_of_space);
990 /* Some other error. */
991 error_msg("syntax error");
995 if (expand_result.we_wordc > 0) {
996 /* Convert from char** (one word per string) to a simple char*,
997 * but don't overflow command which is BUFSIZ in length */
999 while (i < expand_result.we_wordc && total_length < BUFSIZ) {
1000 length=strlen(expand_result.we_wordv[i])+1;
1001 if (BUFSIZ-total_length-length <= 0) {
1002 error_msg(out_of_space);
1005 strcat(command+total_length, expand_result.we_wordv[i++]);
1006 strcat(command+total_length, " ");
1007 total_length+=length;
1009 wordfree (&expand_result);
1013 /* Ok. They don't have a recent glibc and they don't have uClibc. Chances
1014 * are about 100% they don't have wordexp(). So instead the best we can do
1015 * is use glob and then fixup environment variables and such ourselves.
1016 * This is better then nothing, but certainly not perfect */
1018 /* It turns out that glob is very stupid. We have to feed it one word at a
1019 * time since it can't cope with a full string. Here we convert command
1020 * (char*) into cmd (char**, one word per string) */
1023 int flags = GLOB_NOCHECK
1031 char *tmpcmd, *cmd, *cmd_copy;
1032 /* We need a clean copy, so strsep can mess up the copy while
1033 * we write stuff into the original (in a minute) */
1034 cmd = cmd_copy = strdup(command);
1036 for (index = 0, tmpcmd = cmd;
1037 (tmpcmd = strsep_space(cmd, &index)) != NULL; cmd += index, index=0) {
1038 if (*tmpcmd == '\0')
1040 retval = glob(tmpcmd, flags, NULL, &expand_result);
1041 free(tmpcmd); /* Free mem allocated by strsep_space */
1042 if (retval == GLOB_NOSPACE) {
1043 /* Mem may have been allocated... */
1044 globfree (&expand_result);
1045 error_msg(out_of_space);
1047 } else if (retval != 0) {
1048 /* Some other error. GLOB_NOMATCH shouldn't
1049 * happen because of the GLOB_NOCHECK flag in
1051 error_msg("syntax error");
1054 /* Convert from char** (one word per string) to a simple char*,
1055 * but don't overflow command which is BUFSIZ in length */
1056 for (i=0; i < expand_result.gl_pathc; i++) {
1057 length=strlen(expand_result.gl_pathv[i]);
1058 if (BUFSIZ-total_length-length <= 0) {
1059 error_msg(out_of_space);
1062 strcat(command+total_length, expand_result.gl_pathv[i]);
1063 total_length+=length;
1065 globfree (&expand_result);
1074 /* Now do the shell variable substitutions which
1075 * wordexp can't do for us, namely $? and $! */
1077 while((dst = strchr(src,'$')) != NULL){
1081 var = itoa(last_return_code);
1084 if (last_bg_pid==-1)
1087 var = itoa(last_bg_pid);
1089 /* Everything else like $$, $#, $[0-9], etc should all be
1090 * expanded by wordexp(), so we can in theory skip that stuff
1091 * here, but just to be on the safe side (i.e. since uClibc
1092 * wordexp doesn't do this stuff yet), lets leave it in for
1095 var = itoa(getpid());
1100 case '0':case '1':case '2':case '3':case '4':
1101 case '5':case '6':case '7':case '8':case '9':
1103 int index=*(dst + 1)-48;
1104 if (index >= argc) {
1114 /* a single character construction was found, and
1115 * already handled in the case statement */
1118 /* Looks like an environment variable */
1120 int num_skip_chars=1;
1121 int dstlen = strlen(dst);
1122 /* Is this a ${foo} type variable? */
1123 if (dstlen >=2 && *(dst+1) == '{') {
1124 src=strchr(dst+1, '}');
1127 src=strpbrk(dst+1, " \t~`!$^&*()=|\\[];\"'<>?./");
1133 *src='\0'; /* temporary */
1134 var = getenv(dst + num_skip_chars);
1136 if (num_skip_chars==2) {
1141 /* Seems we got an un-expandable variable. So delete it. */
1145 int subst_len = strlen(var);
1146 int trail_len = strlen(src);
1147 if (dst+subst_len+trail_len >= command+BUFSIZ) {
1148 error_msg(out_of_space);
1151 /* Move stuff to the end of the string to accommodate
1152 * filling the created gap with the new stuff */
1153 memmove(dst+subst_len, src, trail_len);
1154 *(dst+subst_len+trail_len)='\0';
1155 /* Now copy in the new stuff */
1156 memcpy(dst, var, subst_len);
1157 src = dst+subst_len;
1165 /* Return cmd->num_progs as 0 if no command is present (e.g. an empty
1166 line). If a valid command is found, command_ptr is set to point to
1167 the beginning of the next command (if the original command had more
1168 then one job associated with it) or NULL if no more commands are
1170 static int parse_command(char **command_ptr, struct job *job, int *inbg)
1173 char *return_command = NULL;
1174 char *src, *buf, *chptr;
1181 struct child_prog *prog;
1183 /* skip leading white space */
1184 while (**command_ptr && isspace(**command_ptr))
1187 /* this handles empty lines or leading '#' characters */
1188 if (!**command_ptr || (**command_ptr == '#')) {
1195 job->progs = xmalloc(sizeof(*job->progs));
1197 /* We set the argv elements to point inside of this string. The
1198 memory is freed by free_job(). Allocate twice the original
1199 length in case we need to quote every single character.
1201 Getting clean memory relieves us of the task of NULL
1202 terminating things and makes the rest of this look a bit
1203 cleaner (though it is, admittedly, a tad less efficient) */
1204 job->cmdbuf = command = xcalloc(2*strlen(*command_ptr) + 1, sizeof(char));
1208 prog->num_redirects = 0;
1209 prog->redirects = NULL;
1210 prog->is_stopped = 0;
1214 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1215 prog->argv[0] = job->cmdbuf;
1219 while (*src && !done) {
1220 if (quote == *src) {
1226 error_msg("character expected after \\");
1231 /* in shell, "\'" should yield \' */
1232 if (*src != quote) {
1236 } else if (*src == '*' || *src == '?' || *src == '[' ||
1237 *src == ']') *buf++ = '\\';
1239 } else if (isspace(*src)) {
1240 if (*prog->argv[argc_l]) {
1242 /* +1 here leaves room for the NULL which ends argv */
1243 if ((argc_l + 1) == argv_alloced) {
1245 prog->argv = xrealloc(prog->argv,
1246 sizeof(*prog->argv) *
1249 prog->argv[argc_l] = buf;
1258 case '#': /* comment */
1265 case '>': /* redirects */
1267 i = prog->num_redirects++;
1268 prog->redirects = xrealloc(prog->redirects,
1269 sizeof(*prog->redirects) *
1272 prog->redirects[i].fd = -1;
1273 if (buf != prog->argv[argc_l]) {
1274 /* the stuff before this character may be the file number
1276 prog->redirects[i].fd =
1277 strtol(prog->argv[argc_l], &chptr, 10);
1279 if (*chptr && *prog->argv[argc_l]) {
1281 prog->argv[argc_l] = buf;
1285 if (prog->redirects[i].fd == -1) {
1287 prog->redirects[i].fd = 1;
1289 prog->redirects[i].fd = 0;
1292 if (*src++ == '>') {
1294 prog->redirects[i].type =
1295 REDIRECT_APPEND, src++;
1297 prog->redirects[i].type = REDIRECT_OVERWRITE;
1299 prog->redirects[i].type = REDIRECT_INPUT;
1302 /* This isn't POSIX sh compliant. Oh well. */
1304 while (isspace(*chptr))
1308 error_msg("file name expected after %c", *(src-1));
1314 prog->redirects[i].filename = buf;
1315 while (*chptr && !isspace(*chptr))
1318 src = chptr - 1; /* we src++ later */
1319 prog->argv[argc_l] = ++buf;
1322 case '|': /* pipe */
1323 /* finish this command */
1324 if (*prog->argv[argc_l])
1327 error_msg("empty command in pipe");
1332 prog->argv[argc_l] = NULL;
1334 /* and start the next */
1336 job->progs = xrealloc(job->progs,
1337 sizeof(*job->progs) * job->num_progs);
1338 prog = job->progs + (job->num_progs - 1);
1339 prog->num_redirects = 0;
1340 prog->redirects = NULL;
1341 prog->is_stopped = 0;
1346 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1347 prog->argv[0] = ++buf;
1350 while (*src && isspace(*src))
1354 error_msg("empty command in pipe");
1359 src--; /* we'll ++ it at the end of the loop */
1363 case '&': /* background */
1365 case ';': /* multiple commands */
1367 return_command = *command_ptr + (src - *command_ptr) + 1;
1370 #ifdef BB_FEATURE_SH_BACKTICKS
1372 /* Exec a backtick-ed command */
1373 /* Besides any previous brokenness, I have not
1374 * updated backtick handling for close_me support.
1375 * I don't know if it needs it or not. -- LRD */
1377 char* charptr1=NULL, *charptr2;
1380 struct jobset njob_list = { NULL, NULL };
1384 ptr=strchr(++src, '`');
1386 fprintf(stderr, "Unmatched '`' in command\n");
1391 /* Make some space to hold just the backticked command */
1392 charptr1 = charptr2 = xmalloc(1+ptr-src);
1393 memcpy(charptr1, src, ptr-src);
1394 charptr1[ptr-src] = '\0';
1395 newjob = xmalloc(sizeof(struct job));
1396 newjob->job_list = &njob_list;
1397 /* Now parse and run the backticked command */
1398 if (!parse_command(&charptr1, newjob, inbg)
1399 && newjob->num_progs) {
1401 run_command(newjob, 0, pipefd);
1403 checkjobs(job->job_list);
1404 free_job(newjob); /* doesn't actually free newjob,
1405 looks like a memory leak */
1408 /* Make a copy of any stuff left over in the command
1409 * line after the second backtick */
1410 charptr2 = xmalloc(strlen(ptr)+1);
1411 memcpy(charptr2, ptr+1, strlen(ptr));
1414 /* Copy the output from the backtick-ed command into the
1415 * command line, making extra room as needed */
1417 charptr1 = xmalloc(BUFSIZ);
1418 while ( (size=full_read(pipefd[0], charptr1, BUFSIZ-1)) >0) {
1419 int newsize=src - *command_ptr + size + 1 + strlen(charptr2);
1420 if (newsize > BUFSIZ) {
1421 *command_ptr=xrealloc(*command_ptr, newsize);
1423 memcpy(src, charptr1, size);
1431 /* Now paste into the *command_ptr all the stuff
1432 * leftover after the second backtick */
1433 memcpy(src, charptr2, strlen(charptr2)+1);
1436 /* Now recursively call parse_command to deal with the new
1437 * and improved version of the command line with the backtick
1438 * results expanded in place... */
1440 struct jobset *jl=job->job_list;
1444 return(parse_command(command_ptr, job, inbg));
1447 #endif // BB_FEATURE_SH_BACKTICKS
1452 /* This is currently a little broken... */
1453 #ifdef HANDLE_CONTINUATION_CHARS
1454 /* They fed us a continuation char, so continue reading stuff
1455 * on the next line, then tack that onto the end of the current
1459 printf("erik: found a continue char at EOL...\n");
1460 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1461 if (get_command(input, command)) {
1462 error_msg("character expected after \\");
1467 newsize = strlen(*command_ptr) + strlen(command) + 2;
1468 if (newsize > BUFSIZ) {
1469 printf("erik: doing realloc\n");
1470 *command_ptr=xrealloc(*command_ptr, newsize);
1472 printf("erik: A: *command_ptr='%s'\n", *command_ptr);
1473 memcpy(--src, command, strlen(command));
1474 printf("erik: B: *command_ptr='%s'\n", *command_ptr);
1478 error_msg("character expected after \\");
1484 if (*src == '*' || *src == '[' || *src == ']'
1485 || *src == '?') *buf++ = '\\';
1494 if (*prog->argv[argc_l]) {
1501 prog->argv[argc_l] = NULL;
1503 if (!return_command) {
1504 job->text = xmalloc(strlen(*command_ptr) + 1);
1505 strcpy(job->text, *command_ptr);
1507 /* This leaves any trailing spaces, which is a bit sloppy */
1508 count = return_command - *command_ptr;
1509 job->text = xmalloc(count + 1);
1510 strncpy(job->text, *command_ptr, count);
1511 job->text[count] = '\0';
1514 *command_ptr = return_command;
1519 /* Run the child_prog, no matter what kind of command it uses.
1521 static int pseudo_exec(struct child_prog *child)
1523 struct built_in_command *x;
1524 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
1528 /* Check if the command matches any of the non-forking builtins.
1529 * Depending on context, this might be redundant. But it's
1530 * easier to waste a few CPU cycles than it is to figure out
1531 * if this is one of those cases.
1533 for (x = bltins; x->cmd; x++) {
1534 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1535 exit(x->function(child));
1539 /* Check if the command matches any of the forking builtins. */
1540 for (x = bltins_forking; x->cmd; x++) {
1541 if (strcmp(child->argv[0], x->cmd) == 0) {
1543 exit (x->function(child));
1546 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
1547 /* Check if the command matches any busybox internal
1548 * commands ("applets") here. Following discussions from
1549 * November 2000 on busybox@opensource.lineo.com, don't use
1550 * get_last_path_component(). This way explicit (with
1551 * slashes) filenames will never be interpreted as an
1552 * applet, just like with builtins. This way the user can
1553 * override an applet with an explicit filename reference.
1554 * The only downside to this change is that an explicit
1555 * /bin/foo invocation will fork and exec /bin/foo, even if
1556 * /bin/foo is a symlink to busybox.
1558 name = child->argv[0];
1560 #ifdef BB_FEATURE_SH_APPLETS_ALWAYS_WIN
1561 /* If you enable BB_FEATURE_SH_APPLETS_ALWAYS_WIN, then
1562 * if you run /bin/cat, it will use BusyBox cat even if
1563 * /bin/cat exists on the filesystem and is _not_ busybox.
1564 * Some systems want this, others do not. Choose wisely. :-)
1566 name = get_last_path_component(name);
1570 char** argv=child->argv;
1572 for(argc_l=0;*argv!=NULL; argv++, argc_l++);
1574 run_applet_by_name(name, argc_l, child->argv);
1578 execvp(child->argv[0], child->argv);
1579 perror_msg_and_die("%s", child->argv[0]);
1582 static void insert_job(struct job *newjob, int inbg)
1585 struct jobset *job_list=newjob->job_list;
1587 /* find the ID for thejob to use */
1589 for (thejob = job_list->head; thejob; thejob = thejob->next)
1590 if (thejob->jobid >= newjob->jobid)
1591 newjob->jobid = thejob->jobid + 1;
1593 /* add thejob to the list of running jobs */
1594 if (!job_list->head) {
1595 thejob = job_list->head = xmalloc(sizeof(*thejob));
1597 for (thejob = job_list->head; thejob->next; thejob = thejob->next) /* nothing */;
1598 thejob->next = xmalloc(sizeof(*thejob));
1599 thejob = thejob->next;
1602 *thejob = *newjob; /* physically copy the struct job */
1603 thejob->next = NULL;
1604 thejob->running_progs = thejob->num_progs;
1605 thejob->stopped_progs = 0;
1608 /* we don't wait for background thejobs to return -- append it
1609 to the list of backgrounded thejobs and leave it alone */
1610 printf("[%d] %d\n", thejob->jobid,
1611 newjob->progs[newjob->num_progs - 1].pid);
1612 #ifdef BB_FEATURE_SH_ENVIRONMENT
1613 last_bg_pid=newjob->progs[newjob->num_progs - 1].pid;
1616 newjob->job_list->fg = thejob;
1618 /* move the new process group into the foreground */
1619 /* suppress messages when run from /linuxrc mag@sysgo.de */
1620 if (tcsetpgrp(0, newjob->pgrp) && errno != ENOTTY)
1621 perror_msg("tcsetpgrp");
1625 static int run_command(struct job *newjob, int inbg, int outpipe[2])
1627 /* struct job *thejob; */
1629 int nextin, nextout;
1630 int pipefds[2]; /* pipefd[0] is for reading */
1631 struct built_in_command *x;
1632 struct child_prog *child;
1634 nextin = 0, nextout = 1;
1635 for (i = 0; i < newjob->num_progs; i++) {
1636 child = & (newjob->progs[i]);
1638 if ((i + 1) < newjob->num_progs) {
1639 if (pipe(pipefds)<0) perror_msg_and_die("pipe");
1640 nextout = pipefds[1];
1642 if (outpipe[1]!=-1) {
1643 nextout = outpipe[1];
1649 #ifdef BB_FEATURE_SH_ENVIRONMENT
1650 if (show_x_trace==TRUE) {
1653 for (j = 0; child->argv[j]; j++) {
1655 fputs(child->argv[j], stderr);
1657 fputc('\n', stderr);
1661 /* Check if the command matches any non-forking builtins,
1662 * but only if this is a simple command.
1663 * Non-forking builtins within pipes have to fork anyway,
1664 * and are handled in pseudo_exec. "echo foo | read bar"
1665 * is doomed to failure, and doesn't work on bash, either.
1667 if (newjob->num_progs == 1) {
1668 for (x = bltins; x->cmd; x++) {
1669 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1670 int squirrel[] = {-1, -1, -1};
1672 setup_redirects(child, squirrel);
1673 rcode = x->function(child);
1674 restore_redirects(squirrel);
1680 if (!(child->pid = fork())) {
1681 signal(SIGTTOU, SIG_DFL);
1685 if (outpipe[1]!=-1) {
1695 dup2(nextout, 2); /* Really? */
1700 /* explicit redirects override pipes */
1701 setup_redirects(child,NULL);
1705 if (outpipe[1]!=-1) {
1709 /* put our child in the process group whose leader is the
1710 first process in this pipe */
1711 setpgid(child->pid, newjob->progs[0].pid);
1717 /* If there isn't another process, nextin is garbage
1718 but it doesn't matter */
1719 nextin = pipefds[0];
1722 newjob->pgrp = newjob->progs[0].pid;
1724 insert_job(newjob, inbg);
1729 static int busy_loop(FILE * input)
1732 char *next_command = NULL;
1738 newjob.job_list = &job_list;
1739 newjob.job_context = DEFAULT_CONTEXT;
1741 /* save current owner of TTY so we can restore it on exit */
1742 parent_pgrp = tcgetpgrp(0);
1744 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1746 /* don't pay any attention to this signal; it just confuses
1747 things and isn't really meant for shells anyway */
1748 signal(SIGTTOU, SIG_IGN);
1752 /* no job is in the foreground */
1754 /* see if any background processes have exited */
1755 checkjobs(&job_list);
1757 if (!next_command) {
1758 if (get_command(input, command))
1760 next_command = command;
1763 if (expand_arguments(next_command) == FALSE) {
1765 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1766 next_command = NULL;
1770 if (!parse_command(&next_command, &newjob, &inbg) &&
1772 int pipefds[2] = {-1,-1};
1773 debug_printf( "job=%p fed to run_command by busy_loop()'\n",
1775 run_command(&newjob, inbg, pipefds);
1779 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1780 next_command = NULL;
1783 /* a job is running in the foreground; wait for it */
1785 while (!job_list.fg->progs[i].pid ||
1786 job_list.fg->progs[i].is_stopped == 1) i++;
1788 if (waitpid(job_list.fg->progs[i].pid, &status, WUNTRACED)<0)
1789 perror_msg_and_die("waitpid(%d)",job_list.fg->progs[i].pid);
1791 if (WIFEXITED(status) || WIFSIGNALED(status)) {
1792 /* the child exited */
1793 job_list.fg->running_progs--;
1794 job_list.fg->progs[i].pid = 0;
1796 #ifdef BB_FEATURE_SH_ENVIRONMENT
1797 last_return_code=WEXITSTATUS(status);
1798 debug_printf("'%s' exited -- return code %d\n",
1799 job_list.fg->text, last_return_code);
1801 if (!job_list.fg->running_progs) {
1803 remove_job(&job_list, job_list.fg);
1807 /* the child was stopped */
1808 job_list.fg->stopped_progs++;
1809 job_list.fg->progs[i].is_stopped = 1;
1811 if (job_list.fg->stopped_progs == job_list.fg->running_progs) {
1812 printf("\n" JOB_STATUS_FORMAT, job_list.fg->jobid,
1813 "Stopped", job_list.fg->text);
1819 /* move the shell to the foreground */
1820 /* suppress messages when run from /linuxrc mag@sysgo.de */
1821 if (tcsetpgrp(0, getpid()) && errno != ENOTTY)
1822 perror_msg("tcsetpgrp");
1828 /* return controlling TTY back to parent process group before exiting */
1829 if (tcsetpgrp(0, parent_pgrp))
1830 perror_msg("tcsetpgrp");
1832 /* return exit status if called with "-c" */
1833 if (input == NULL && WIFEXITED(status))
1834 return WEXITSTATUS(status);
1840 #ifdef BB_FEATURE_CLEAN_UP
1841 void free_memory(void)
1845 if (local_pending_command)
1846 free(local_pending_command);
1848 if (job_list.fg && !job_list.fg->running_progs) {
1849 remove_job(&job_list, job_list.fg);
1855 int shell_main(int argc_l, char **argv_l)
1857 int opt, interactive=FALSE;
1858 FILE *input = stdin;
1862 /* These variables need re-initializing when recursing */
1865 local_pending_command = NULL;
1866 close_me_head = NULL;
1867 job_list.head = NULL;
1869 #ifdef BB_FEATURE_SH_ENVIRONMENT
1875 if (argv[0] && argv[0][0] == '-') {
1877 prof_input = fopen("/etc/profile", "r");
1879 printf( "Couldn't open file '/etc/profile'\n");
1881 int tmp_fd = fileno(prof_input);
1883 /* Now run the file */
1884 busy_loop(prof_input);
1886 mark_closed(tmp_fd);
1890 while ((opt = getopt(argc_l, argv_l, "cxi")) > 0) {
1894 if (local_pending_command != 0)
1895 error_msg_and_die("multiple -c arguments");
1896 local_pending_command = xstrdup(argv[optind]);
1900 #ifdef BB_FEATURE_SH_ENVIRONMENT
1902 show_x_trace = TRUE;
1912 /* A shell is interactive if the `-i' flag was given, or if all of
1913 * the following conditions are met:
1915 * no arguments remaining or the -s flag given
1916 * standard input is a terminal
1917 * standard output is a terminal
1918 * Refer to Posix.2, the description of the `sh' utility. */
1919 if (argv[optind]==NULL && input==stdin &&
1920 isatty(fileno(stdin)) && isatty(fileno(stdout))) {
1923 if (interactive==TRUE) {
1924 //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
1925 /* Looks like they want an interactive shell */
1926 printf( "\n\nBusyBox v%s (%s) Built-in shell (lash)\n", BB_VER, BB_BT);
1927 printf( "Enter 'help' for a list of built-in commands.\n\n");
1928 } else if (local_pending_command==NULL) {
1929 //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
1930 input = xfopen(argv[optind], "r");
1931 mark_open(fileno(input)); /* be lazy, never mark this closed */
1934 /* initialize the cwd -- this is never freed...*/
1935 cwd=(char*)xmalloc(sizeof(char)*MAX_LINE+1);
1936 getcwd(cwd, sizeof(char)*MAX_LINE);
1938 #ifdef BB_FEATURE_CLEAN_UP
1939 atexit(free_memory);
1942 #ifdef BB_FEATURE_COMMAND_EDITING
1943 cmdedit_set_initial_prompt();
1949 return (busy_loop(input));