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 #undef BB_FEATURE_SH_WORDEXP
70 #if BB_FEATURE_SH_WORDEXP
72 #define expand_t wordexp_t
73 #undef BB_FEATURE_SH_BACKTICKS
76 #define expand_t glob_t
82 static const int MAX_LINE = 256; /* size of input buffer for cwd data */
83 static const int MAX_READ = 128; /* size of input buffer for `read' builtin */
84 #define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
87 enum redir_type { REDIRECT_INPUT, REDIRECT_OVERWRITE,
91 static const unsigned int DEFAULT_CONTEXT=0x1;
92 static const unsigned int IF_TRUE_CONTEXT=0x2;
93 static const unsigned int IF_FALSE_CONTEXT=0x4;
94 static const unsigned int THEN_EXP_CONTEXT=0x8;
95 static const unsigned int ELSE_EXP_CONTEXT=0x10;
99 struct job *head; /* head of list of running jobs */
100 struct job *fg; /* current foreground job */
103 struct redir_struct {
104 enum redir_type type; /* type of redirection */
105 int fd; /* file descriptor being redirected */
106 char *filename; /* file to redirect fd to */
110 pid_t pid; /* 0 if exited */
111 char **argv; /* program name and arguments */
112 int num_redirects; /* elements in redirection array */
113 struct redir_struct *redirects; /* I/O redirects */
114 int is_stopped; /* is the program currently running? */
115 struct job *family; /* pointer back to the child's parent job */
119 int jobid; /* job number */
120 int num_progs; /* total number of programs in job */
121 int running_progs; /* number of programs running */
122 char *text; /* name of job */
123 char *cmdbuf; /* buffer various argv's point into */
124 pid_t pgrp; /* process group ID for the job */
125 struct child_prog *progs; /* array of programs in job */
126 struct job *next; /* to track background commands */
127 int stopped_progs; /* number of programs alive, but stopped */
128 unsigned int job_context; /* bitmask defining current context */
129 struct jobset *job_list;
132 struct built_in_command {
133 char *cmd; /* name */
134 char *descr; /* description */
135 int (*function) (struct child_prog *); /* function ptr */
140 struct close_me *next;
143 /* function prototypes for builtins */
144 static int builtin_cd(struct child_prog *cmd);
145 static int builtin_env(struct child_prog *dummy);
146 static int builtin_exec(struct child_prog *cmd);
147 static int builtin_exit(struct child_prog *cmd);
148 static int builtin_fg_bg(struct child_prog *cmd);
149 static int builtin_help(struct child_prog *cmd);
150 static int builtin_jobs(struct child_prog *dummy);
151 static int builtin_pwd(struct child_prog *dummy);
152 static int builtin_export(struct child_prog *cmd);
153 static int builtin_source(struct child_prog *cmd);
154 static int builtin_unset(struct child_prog *cmd);
155 static int builtin_read(struct child_prog *cmd);
156 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
157 static int builtin_if(struct child_prog *cmd);
158 static int builtin_then(struct child_prog *cmd);
159 static int builtin_else(struct child_prog *cmd);
160 static int builtin_fi(struct child_prog *cmd);
161 /* function prototypes for shell stuff */
162 static int run_command_predicate(char *cmd);
166 /* function prototypes for shell stuff */
167 static void mark_open(int fd);
168 static void mark_closed(int fd);
169 static void close_all(void);
170 static void checkjobs(struct jobset *job_list);
171 static int get_command(FILE * source, char *command);
172 static int parse_command(char **command_ptr, struct job *job, int *inbg);
173 static int run_command(struct job *newjob, int inbg, int outpipe[2]);
174 static int pseudo_exec(struct child_prog *cmd) __attribute__ ((noreturn));
175 static int busy_loop(FILE * input);
178 /* Table of built-in functions (these are non-forking builtins, meaning they
179 * can change global variables in the parent shell process but they will not
180 * work with pipes and redirects; 'unset foo | whatever' will not work) */
181 static struct built_in_command bltins[] = {
182 {"bg", "Resume a job in the background", builtin_fg_bg},
183 {"cd", "Change working directory", builtin_cd},
184 {"exec", "Exec command, replacing this shell with the exec'd process", builtin_exec},
185 {"exit", "Exit from shell()", builtin_exit},
186 {"fg", "Bring job into the foreground", builtin_fg_bg},
187 {"jobs", "Lists the active jobs", builtin_jobs},
188 {"export", "Set environment variable", builtin_export},
189 {"unset", "Unset environment variable", builtin_unset},
190 {"read", "Input environment variable", builtin_read},
191 {".", "Source-in and run commands in a file", builtin_source},
192 /* to do: add ulimit */
193 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
194 {"if", NULL, builtin_if},
195 {"then", NULL, builtin_then},
196 {"else", NULL, builtin_else},
197 {"fi", NULL, builtin_fi},
202 /* Table of forking built-in functions (things that fork cannot change global
203 * variables in the parent process, such as the current working directory) */
204 static struct built_in_command bltins_forking[] = {
205 {"env", "Print all environment variables", builtin_env},
206 {"pwd", "Print current directory", builtin_pwd},
207 {"help", "List shell built-in commands", builtin_help},
212 /* Variables we export */
213 unsigned int shell_context; /* Used in cmdedit.c to reset the
214 context when someone hits ^C */
217 /* Globals that are static to this file */
219 static char *local_pending_command = NULL;
220 static struct jobset job_list = { NULL, NULL };
223 static struct close_me *close_me_head;
224 #ifdef BB_FEATURE_SH_ENVIRONMENT
225 static int last_bg_pid;
226 static int last_return_code;
227 static int show_x_trace;
229 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
230 static char syntax_err[]="syntax error near unexpected token";
238 static inline void debug_printf(const char *format, ...)
241 va_start(args, format);
242 vfprintf(stderr, format, args);
246 static inline void debug_printf(const char *format, ...) { }
250 Most builtins need access to the struct child_prog that has
251 their arguments, previously coded as cmd->progs[0]. That coding
252 can exhibit a bug, if the builtin is not the first command in
253 a pipeline: "echo foo | exec sort" will attempt to exec foo.
255 builtin previous use notes
256 ------ ----------------- ---------
259 exec cmd->progs[0] squashed bug: didn't look for applets or forking builtins
261 fg_bg cmd->progs[0], job_list->head, job_list->fg
265 export cmd->progs[0] passes cmd, job_list to builtin_env(), which ignores them
269 if cmd->job_context, cmd->text
270 then cmd->job_context, cmd->text
271 else cmd->job_context, cmd->text
274 The use of cmd->text by if/then/else/fi is hopelessly hacky.
275 Would it work to increment cmd->progs[0]->argv and recurse,
276 somewhat like builtin_exec does?
278 I added "struct job *family;" to struct child_prog,
279 and switched API to builtin_foo(struct child_prog *child);
280 So cmd->text becomes child->family->text
281 cmd->job_context becomes child->family->job_context
282 cmd->progs[0] becomes *child
283 job_list becomes child->family->job_list
286 /* built-in 'cd <path>' handler */
287 static int builtin_cd(struct child_prog *child)
291 if (child->argv[1] == NULL)
292 newdir = getenv("HOME");
294 newdir = child->argv[1];
296 printf("cd: %s: %m\n", newdir);
299 getcwd(cwd, sizeof(char)*MAX_LINE);
304 /* built-in 'env' handler */
305 static int builtin_env(struct child_prog *dummy)
309 for (e = environ; *e; e++) {
315 /* built-in 'exec' handler */
316 static int builtin_exec(struct child_prog *child)
318 if (child->argv[1] == NULL)
319 return EXIT_SUCCESS; /* Really? */
326 /* built-in 'exit' handler */
327 static int builtin_exit(struct child_prog *child)
329 if (child->argv[1] == NULL)
332 exit (atoi(child->argv[1]));
335 /* built-in 'fg' and 'bg' handler */
336 static int builtin_fg_bg(struct child_prog *child)
339 struct job *job=NULL;
341 if (!child->argv[1] || child->argv[2]) {
342 error_msg("%s: exactly one argument is expected",
347 if (sscanf(child->argv[1], "%%%d", &jobNum) != 1) {
348 error_msg("%s: bad argument '%s'",
349 child->argv[0], child->argv[1]);
353 for (job = child->family->job_list->head; job; job = job->next) {
354 if (job->jobid == jobNum) {
360 error_msg("%s: unknown job %d",
361 child->argv[0], jobNum);
365 if (*child->argv[0] == 'f') {
366 /* Make this job the foreground job */
367 /* suppress messages when run from /linuxrc mag@sysgo.de */
368 if (tcsetpgrp(0, job->pgrp) && errno != ENOTTY)
369 perror_msg("tcsetpgrp");
370 child->family->job_list->fg = job;
373 /* Restart the processes in the job */
374 for (i = 0; i < job->num_progs; i++)
375 job->progs[i].is_stopped = 0;
377 kill(-job->pgrp, SIGCONT);
379 job->stopped_progs = 0;
384 /* built-in 'help' handler */
385 static int builtin_help(struct child_prog *dummy)
387 struct built_in_command *x;
389 printf("\nBuilt-in commands:\n");
390 printf("-------------------\n");
391 for (x = bltins; x->cmd; x++) {
394 printf("%s\t%s\n", x->cmd, x->descr);
396 for (x = bltins_forking; x->cmd; x++) {
399 printf("%s\t%s\n", x->cmd, x->descr);
405 /* built-in 'jobs' handler */
406 static int builtin_jobs(struct child_prog *child)
411 for (job = child->family->job_list->head; job; job = job->next) {
412 if (job->running_progs == job->stopped_progs)
413 status_string = "Stopped";
415 status_string = "Running";
417 printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->text);
423 /* built-in 'pwd' handler */
424 static int builtin_pwd(struct child_prog *dummy)
426 getcwd(cwd, MAX_LINE);
427 printf( "%s\n", cwd);
431 /* built-in 'export VAR=value' handler */
432 static int builtin_export(struct child_prog *child)
435 char *v = child->argv[1];
438 return (builtin_env(child));
442 fprintf(stderr, "export: %m\n");
443 #ifndef BB_FEATURE_SH_SIMPLE_PROMPT
444 if (strncmp(v, "PS1=", 4)==0)
446 else if (strncmp(v, "PS2=", 4)==0)
452 /* built-in 'read VAR' handler */
453 static int builtin_read(struct child_prog *child)
455 int res = 0, len, newlen;
457 char string[MAX_READ];
459 if (child->argv[1]) {
460 /* argument (VAR) given: put "VAR=" into buffer */
461 strcpy(string, child->argv[1]);
462 len = strlen(string);
465 fgets(&string[len], sizeof(string) - len, stdin); /* read string */
466 newlen = strlen(string);
468 string[--newlen] = '\0'; /* chomp trailing newline */
470 ** string should now contain "VAR=<value>"
471 ** copy it (putenv() won't do that, so we must make sure
472 ** the string resides in a static buffer!)
475 if((s = strdup(string)))
478 fprintf(stderr, "read: %m\n");
481 fgets(string, sizeof(string), stdin);
486 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
487 /* Built-in handler for 'if' commands */
488 static int builtin_if(struct child_prog *child)
490 struct job *cmd = child->family;
492 char* charptr1=cmd->text+3; /* skip over the leading 'if ' */
494 /* Now run the 'if' command */
495 debug_printf( "job=%p entering builtin_if ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
496 status = run_command_predicate(charptr1);
497 debug_printf( "if test returned ");
499 debug_printf( "TRUE\n");
500 cmd->job_context |= IF_TRUE_CONTEXT;
502 debug_printf( "FALSE\n");
503 cmd->job_context |= IF_FALSE_CONTEXT;
505 debug_printf("job=%p builtin_if set job context to %x\n", cmd, cmd->job_context);
511 /* Built-in handler for 'then' (part of the 'if' command) */
512 static int builtin_then(struct child_prog *child)
514 struct job *cmd = child->family;
515 char* charptr1=cmd->text+5; /* skip over the leading 'then ' */
517 debug_printf( "job=%p entering builtin_then ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
518 if (! (cmd->job_context & (IF_TRUE_CONTEXT|IF_FALSE_CONTEXT))) {
519 shell_context = 0; /* Reset the shell's context on an error */
520 error_msg("%s `then'", syntax_err);
524 cmd->job_context |= THEN_EXP_CONTEXT;
525 debug_printf("job=%p builtin_then set job context to %x\n", cmd, cmd->job_context);
527 /* If the if result was FALSE, skip the 'then' stuff */
528 if (cmd->job_context & IF_FALSE_CONTEXT) {
532 /* Seems the if result was TRUE, so run the 'then' command */
533 debug_printf( "'then' now running '%s'\n", charptr1);
535 return(run_command_predicate(charptr1));
538 /* Built-in handler for 'else' (part of the 'if' command) */
539 static int builtin_else(struct child_prog *child)
541 struct job *cmd = child->family;
542 char* charptr1=cmd->text+5; /* skip over the leading 'else ' */
544 debug_printf( "job=%p entering builtin_else ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
546 if (! (cmd->job_context & THEN_EXP_CONTEXT)) {
547 shell_context = 0; /* Reset the shell's context on an error */
548 error_msg("%s `else'", syntax_err);
551 /* If the if result was TRUE, skip the 'else' stuff */
552 if (cmd->job_context & IF_TRUE_CONTEXT) {
556 cmd->job_context |= ELSE_EXP_CONTEXT;
557 debug_printf("job=%p builtin_else set job context to %x\n", cmd, cmd->job_context);
559 /* Now run the 'else' command */
560 debug_printf( "'else' now running '%s'\n", charptr1);
561 return(run_command_predicate(charptr1));
564 /* Built-in handler for 'fi' (part of the 'if' command) */
565 static int builtin_fi(struct child_prog *child)
567 struct job *cmd = child->family;
568 debug_printf( "job=%p entering builtin_fi ('%s')-- context=%d\n", cmd, "", cmd->job_context);
569 if (! (cmd->job_context & (IF_TRUE_CONTEXT|IF_FALSE_CONTEXT))) {
570 shell_context = 0; /* Reset the shell's context on an error */
571 error_msg("%s `fi'", syntax_err);
574 /* Clear out the if and then context bits */
575 cmd->job_context &= ~(IF_TRUE_CONTEXT|IF_FALSE_CONTEXT|THEN_EXP_CONTEXT|ELSE_EXP_CONTEXT);
576 debug_printf("job=%p builtin_fi set job context to %x\n", cmd, cmd->job_context);
582 /* Built-in '.' handler (read-in and execute commands from file) */
583 static int builtin_source(struct child_prog *child)
589 if (child->argv[1] == NULL)
592 input = fopen(child->argv[1], "r");
594 printf( "Couldn't open file '%s'\n", child->argv[1]);
600 /* Now run the file */
601 status = busy_loop(input);
607 /* built-in 'unset VAR' handler */
608 static int builtin_unset(struct child_prog *child)
610 if (child->argv[1] == NULL) {
611 printf( "unset: parameter required.\n");
614 unsetenv(child->argv[1]);
618 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
619 /* currently used by if/then/else.
621 * Reparsing the command line for this purpose is gross,
622 * incorrect, and fundamentally unfixable; in particular,
623 * think about what happens with command substitution.
624 * We really need to pull out the run, wait, return status
625 * functionality out of busy_loop so we can child->argv++
626 * and use that, without going back through parse_command.
628 static int run_command_predicate(char *cmd)
631 local_pending_command = xmalloc(n+1);
632 strncpy(local_pending_command, cmd, n);
633 local_pending_command[n]='\0';
634 return( busy_loop(NULL));
638 static void mark_open(int fd)
640 struct close_me *new = xmalloc(sizeof(struct close_me));
642 new->next = close_me_head;
646 static void mark_closed(int fd)
648 struct close_me *tmp;
649 if (close_me_head == NULL || close_me_head->fd != fd)
650 error_msg_and_die("corrupt close_me");
652 close_me_head = close_me_head->next;
656 static void close_all()
658 struct close_me *c, *tmp;
659 for (c=close_me_head; c; c=tmp) {
664 close_me_head = NULL;
668 /* free up all memory from a job */
669 static void free_job(struct job *cmd)
674 for (i = 0; i < cmd->num_progs; i++) {
675 free(cmd->progs[i].argv);
676 if (cmd->progs[i].redirects)
677 free(cmd->progs[i].redirects);
685 keep = cmd->job_list;
686 memset(cmd, 0, sizeof(struct job));
687 cmd->job_list = keep;
690 /* remove a job from the job_list */
691 static void remove_job(struct jobset *job_list, struct job *job)
696 if (job == job_list->head) {
697 job_list->head = job->next;
699 prevjob = job_list->head;
700 while (prevjob->next != job)
701 prevjob = prevjob->next;
702 prevjob->next = job->next;
708 /* Checks to see if any background processes have exited -- if they
709 have, figure out why and see if a job has completed */
710 static void checkjobs(struct jobset *job_list)
717 while ((childpid = waitpid(-1, &status, WNOHANG | WUNTRACED)) > 0) {
718 for (job = job_list->head; job; job = job->next) {
720 while (prognum < job->num_progs &&
721 job->progs[prognum].pid != childpid) prognum++;
722 if (prognum < job->num_progs)
726 /* This happens on backticked commands */
730 if (WIFEXITED(status) || WIFSIGNALED(status)) {
732 job->running_progs--;
733 job->progs[prognum].pid = 0;
735 if (!job->running_progs) {
736 printf(JOB_STATUS_FORMAT, job->jobid, "Done", job->text);
737 remove_job(job_list, job);
741 job->stopped_progs++;
742 job->progs[prognum].is_stopped = 1;
744 if (job->stopped_progs == job->num_progs) {
745 printf(JOB_STATUS_FORMAT, job->jobid, "Stopped",
751 if (childpid == -1 && errno != ECHILD)
752 perror_msg("waitpid");
755 /* squirrel != NULL means we squirrel away copies of stdin, stdout,
756 * and stderr if they are redirected. */
757 static int setup_redirects(struct child_prog *prog, int squirrel[])
762 struct redir_struct *redir = prog->redirects;
764 for (i = 0; i < prog->num_redirects; i++, redir++) {
765 switch (redir->type) {
769 case REDIRECT_OVERWRITE:
770 mode = O_WRONLY | O_CREAT | O_TRUNC;
772 case REDIRECT_APPEND:
773 mode = O_WRONLY | O_CREAT | O_APPEND;
777 openfd = open(redir->filename, mode, 0666);
779 /* this could get lost if stderr has been redirected, but
780 bash and ash both lose it as well (though zsh doesn't!) */
781 perror_msg("error opening %s", redir->filename);
785 if (openfd != redir->fd) {
786 if (squirrel && redir->fd < 3) {
787 squirrel[redir->fd] = dup(redir->fd);
789 dup2(openfd, redir->fd);
797 static void restore_redirects(int squirrel[])
800 for (i=0; i<3; i++) {
803 /* No error checking. I sure wouldn't know what
804 * to do with an error if I found one! */
811 static inline void cmdedit_set_initial_prompt(void)
813 #ifdef BB_FEATURE_SH_SIMPLE_PROMPT
827 static inline void setup_prompt_string(char **prompt_str)
829 #ifdef BB_FEATURE_SH_SIMPLE_PROMPT
830 /* Set up the prompt */
831 if (shell_context == 0) {
834 PS1=xmalloc(strlen(cwd)+4);
835 sprintf(PS1, "%s %s", cwd, ( geteuid() != 0 ) ? "$ ":"# ");
841 *prompt_str = (shell_context==0)? PS1 : PS2;
845 static int get_command(FILE * source, char *command)
849 if (source == NULL) {
850 if (local_pending_command) {
851 /* a command specified (-c option): return it & mark it done */
852 strcpy(command, local_pending_command);
853 free(local_pending_command);
854 local_pending_command = NULL;
860 if (source == stdin) {
861 setup_prompt_string(&prompt_str);
863 #ifdef BB_FEATURE_COMMAND_EDITING
865 ** enable command line editing only while a command line
866 ** is actually being read; otherwise, we'll end up bequeathing
867 ** atexit() handlers and other unwanted stuff to our
868 ** child processes (rob@sysgo.de)
870 cmdedit_read_input(prompt_str, command);
874 fputs(prompt_str, stdout);
878 if (!fgets(command, BUFSIZ - 2, source)) {
884 /* remove trailing newline */
890 #ifdef BB_FEATURE_SH_ENVIRONMENT
891 static char* itoa(register int i)
893 static char a[7]; /* Max 7 ints */
894 register char *b = a + sizeof(a) - 1;
902 *--b = '0' + (i % 10);
912 #if defined BB_FEATURE_SH_ENVIRONMENT && ! defined BB_FEATURE_SH_WORDEXP
913 char * strsep_space( char *string, int * index)
919 /* Short circuit the trivial case */
920 if ( !string || ! string[*index])
923 /* Find the end of the token. */
924 while( string && string[*index] && !isspace(string[*index]) ) {
928 /* Find the end of any whitespace trailing behind
929 * the token and let that be part of the token */
930 while( string && string[*index] && isspace(string[*index]) ) {
934 if (! string && *index==0) {
935 /* Nothing useful was found */
939 token = xmalloc(*index);
940 token[*index] = '\0';
941 strncpy(token, string, *index);
948 static int expand_arguments(char *command)
950 #ifdef BB_FEATURE_SH_ENVIRONMENT
951 expand_t expand_result;
952 char *src, *dst, *var;
954 int i=0, length, total_length=0, retval;
955 const char *out_of_space = "out of space during expansion";
958 /* get rid of the terminating \n */
961 /* Fix up escape sequences to be the Real Thing(tm) */
962 while( command && command[index]) {
963 if (command[index] == '\\') {
964 char *tmp = command+index+1;
965 command[index+1] = process_escape_sequence( &tmp );
966 memmove(command+index, command+index+1, strlen(command+index));
971 #ifdef BB_FEATURE_SH_ENVIRONMENT
974 #if BB_FEATURE_SH_WORDEXP
975 /* This first part uses wordexp() which is a wonderful C lib
976 * function which expands nearly everything. */
977 retval = wordexp (command, &expand_result, WRDE_SHOWERR);
978 if (retval == WRDE_NOSPACE) {
979 /* Mem may have been allocated... */
980 wordfree (&expand_result);
981 error_msg(out_of_space);
985 /* Some other error. */
986 error_msg("syntax error");
990 if (expand_result.we_wordc > 0) {
991 /* Convert from char** (one word per string) to a simple char*,
992 * but don't overflow command which is BUFSIZ in length */
994 while (i < expand_result.we_wordc && total_length < BUFSIZ) {
995 length=strlen(expand_result.we_wordv[i])+1;
996 if (BUFSIZ-total_length-length <= 0) {
997 error_msg(out_of_space);
1000 strcat(command+total_length, expand_result.we_wordv[i++]);
1001 strcat(command+total_length, " ");
1002 total_length+=length;
1004 wordfree (&expand_result);
1008 /* Ok. They don't have a recent glibc and they don't have uClibc. Chances
1009 * are about 100% they don't have wordexp(). So instead the best we can do
1010 * is use glob and then fixup environment variables and such ourselves.
1011 * This is better then nothing, but certainly not perfect */
1013 /* It turns out that glob is very stupid. We have to feed it one word at a
1014 * time since it can't cope with a full string. Here we convert command
1015 * (char*) into cmd (char**, one word per string) */
1018 int flags = GLOB_NOCHECK
1026 char *tmpcmd, *cmd, *cmd_copy;
1027 /* We need a clean copy, so strsep can mess up the copy while
1028 * we write stuff into the original (in a minute) */
1029 cmd = cmd_copy = strdup(command);
1031 for (index = 0, tmpcmd = cmd;
1032 (tmpcmd = strsep_space(cmd, &index)) != NULL; cmd += index, index=0) {
1033 if (*tmpcmd == '\0')
1035 retval = glob(tmpcmd, flags, NULL, &expand_result);
1036 free(tmpcmd); /* Free mem allocated by strsep_space */
1037 if (retval == GLOB_NOSPACE) {
1038 /* Mem may have been allocated... */
1039 globfree (&expand_result);
1040 error_msg(out_of_space);
1042 } else if (retval != 0) {
1043 /* Some other error. GLOB_NOMATCH shouldn't
1044 * happen because of the GLOB_NOCHECK flag in
1046 error_msg("syntax error");
1049 /* Convert from char** (one word per string) to a simple char*,
1050 * but don't overflow command which is BUFSIZ in length */
1051 for (i=0; i < expand_result.gl_pathc; i++) {
1052 length=strlen(expand_result.gl_pathv[i])+1;
1053 if (BUFSIZ-total_length-length <= 0) {
1054 error_msg(out_of_space);
1057 strcat(command+total_length, expand_result.gl_pathv[i]);
1058 strcat(command+total_length, " ");
1059 total_length+=length;
1061 globfree (&expand_result);
1070 /* Now do the shell variable substitutions which
1071 * wordexp can't do for us, namely $? and $! */
1073 while((dst = strchr(src,'$')) != NULL){
1077 var = itoa(last_return_code);
1080 if (last_bg_pid==-1)
1083 var = itoa(last_bg_pid);
1085 /* Everything else like $$, $#, $[0-9], etc should all be
1086 * expanded by wordexp(), so we can in theory skip that stuff
1087 * here, but just to be on the safe side (i.e. since uClibc
1088 * wordexp doesn't do this stuff yet), lets leave it in for
1091 var = itoa(getpid());
1096 case '0':case '1':case '2':case '3':case '4':
1097 case '5':case '6':case '7':case '8':case '9':
1099 int index=*(dst + 1)-48;
1100 if (index >= argc) {
1110 /* a single character construction was found, and
1111 * already handled in the case statement */
1114 /* Looks like an environment variable */
1116 int num_skip_chars=1;
1117 int dstlen = strlen(dst);
1118 /* Is this a ${foo} type variable? */
1119 if (dstlen >=2 && *(dst+1) == '{') {
1120 src=strchr(dst+1, '}');
1123 src=strpbrk(dst+1, " \t~`!$^&*()=|\\[];\"'<>?./");
1129 *src='\0'; /* temporary */
1130 var = getenv(dst + num_skip_chars);
1132 if (num_skip_chars==2) {
1137 /* Seems we got an un-expandable variable. So delete it. */
1141 int subst_len = strlen(var);
1142 int trail_len = strlen(src);
1143 if (dst+subst_len+trail_len >= command+BUFSIZ) {
1144 error_msg(out_of_space);
1147 /* Move stuff to the end of the string to accommodate
1148 * filling the created gap with the new stuff */
1149 memmove(dst+subst_len, src, trail_len);
1150 *(dst+subst_len+trail_len)='\0';
1151 /* Now copy in the new stuff */
1152 memcpy(dst, var, subst_len);
1153 src = dst+subst_len;
1161 /* Return cmd->num_progs as 0 if no command is present (e.g. an empty
1162 line). If a valid command is found, command_ptr is set to point to
1163 the beginning of the next command (if the original command had more
1164 then one job associated with it) or NULL if no more commands are
1166 static int parse_command(char **command_ptr, struct job *job, int *inbg)
1169 char *return_command = NULL;
1170 char *src, *buf, *chptr;
1177 struct child_prog *prog;
1179 /* skip leading white space */
1180 while (**command_ptr && isspace(**command_ptr))
1183 /* this handles empty lines or leading '#' characters */
1184 if (!**command_ptr || (**command_ptr == '#')) {
1191 job->progs = xmalloc(sizeof(*job->progs));
1193 /* We set the argv elements to point inside of this string. The
1194 memory is freed by free_job(). Allocate twice the original
1195 length in case we need to quote every single character.
1197 Getting clean memory relieves us of the task of NULL
1198 terminating things and makes the rest of this look a bit
1199 cleaner (though it is, admittedly, a tad less efficient) */
1200 job->cmdbuf = command = xcalloc(2*strlen(*command_ptr) + 1, sizeof(char));
1204 prog->num_redirects = 0;
1205 prog->redirects = NULL;
1206 prog->is_stopped = 0;
1210 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1211 prog->argv[0] = job->cmdbuf;
1215 while (*src && !done) {
1216 if (quote == *src) {
1222 error_msg("character expected after \\");
1227 /* in shell, "\'" should yield \' */
1228 if (*src != quote) {
1232 } else if (*src == '*' || *src == '?' || *src == '[' ||
1233 *src == ']') *buf++ = '\\';
1235 } else if (isspace(*src)) {
1236 if (*prog->argv[argc_l]) {
1238 /* +1 here leaves room for the NULL which ends argv */
1239 if ((argc_l + 1) == argv_alloced) {
1241 prog->argv = xrealloc(prog->argv,
1242 sizeof(*prog->argv) *
1245 prog->argv[argc_l] = buf;
1254 case '#': /* comment */
1261 case '>': /* redirects */
1263 i = prog->num_redirects++;
1264 prog->redirects = xrealloc(prog->redirects,
1265 sizeof(*prog->redirects) *
1268 prog->redirects[i].fd = -1;
1269 if (buf != prog->argv[argc_l]) {
1270 /* the stuff before this character may be the file number
1272 prog->redirects[i].fd =
1273 strtol(prog->argv[argc_l], &chptr, 10);
1275 if (*chptr && *prog->argv[argc_l]) {
1277 prog->argv[argc_l] = buf;
1281 if (prog->redirects[i].fd == -1) {
1283 prog->redirects[i].fd = 1;
1285 prog->redirects[i].fd = 0;
1288 if (*src++ == '>') {
1290 prog->redirects[i].type =
1291 REDIRECT_APPEND, src++;
1293 prog->redirects[i].type = REDIRECT_OVERWRITE;
1295 prog->redirects[i].type = REDIRECT_INPUT;
1298 /* This isn't POSIX sh compliant. Oh well. */
1300 while (isspace(*chptr))
1304 error_msg("file name expected after %c", *(src-1));
1310 prog->redirects[i].filename = buf;
1311 while (*chptr && !isspace(*chptr))
1314 src = chptr - 1; /* we src++ later */
1315 prog->argv[argc_l] = ++buf;
1318 case '|': /* pipe */
1319 /* finish this command */
1320 if (*prog->argv[argc_l])
1323 error_msg("empty command in pipe");
1328 prog->argv[argc_l] = NULL;
1330 /* and start the next */
1332 job->progs = xrealloc(job->progs,
1333 sizeof(*job->progs) * job->num_progs);
1334 prog = job->progs + (job->num_progs - 1);
1335 prog->num_redirects = 0;
1336 prog->redirects = NULL;
1337 prog->is_stopped = 0;
1342 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1343 prog->argv[0] = ++buf;
1346 while (*src && isspace(*src))
1350 error_msg("empty command in pipe");
1355 src--; /* we'll ++ it at the end of the loop */
1359 case '&': /* background */
1361 case ';': /* multiple commands */
1363 return_command = *command_ptr + (src - *command_ptr) + 1;
1366 #ifdef BB_FEATURE_SH_BACKTICKS
1368 /* Exec a backtick-ed command */
1369 /* Besides any previous brokenness, I have not
1370 * updated backtick handling for close_me support.
1371 * I don't know if it needs it or not. -- LRD */
1373 char* charptr1=NULL, *charptr2;
1376 struct jobset njob_list = { NULL, NULL };
1380 ptr=strchr(++src, '`');
1382 fprintf(stderr, "Unmatched '`' in command\n");
1387 /* Make some space to hold just the backticked command */
1388 charptr1 = charptr2 = xmalloc(1+ptr-src);
1389 memcpy(charptr1, src, ptr-src);
1390 charptr1[ptr-src] = '\0';
1391 newjob = xmalloc(sizeof(struct job));
1392 newjob->job_list = &njob_list;
1393 /* Now parse and run the backticked command */
1394 if (!parse_command(&charptr1, newjob, inbg)
1395 && newjob->num_progs) {
1397 run_command(newjob, 0, pipefd);
1399 checkjobs(job->job_list);
1400 free_job(newjob); /* doesn't actually free newjob,
1401 looks like a memory leak */
1404 /* Make a copy of any stuff left over in the command
1405 * line after the second backtick */
1406 charptr2 = xmalloc(strlen(ptr)+1);
1407 memcpy(charptr2, ptr+1, strlen(ptr));
1410 /* Copy the output from the backtick-ed command into the
1411 * command line, making extra room as needed */
1413 charptr1 = xmalloc(BUFSIZ);
1414 while ( (size=full_read(pipefd[0], charptr1, BUFSIZ-1)) >0) {
1415 int newsize=src - *command_ptr + size + 1 + strlen(charptr2);
1416 if (newsize > BUFSIZ) {
1417 *command_ptr=xrealloc(*command_ptr, newsize);
1419 memcpy(src, charptr1, size);
1427 /* Now paste into the *command_ptr all the stuff
1428 * leftover after the second backtick */
1429 memcpy(src, charptr2, strlen(charptr2)+1);
1432 /* Now recursively call parse_command to deal with the new
1433 * and improved version of the command line with the backtick
1434 * results expanded in place... */
1436 struct jobset *jl=job->job_list;
1440 return(parse_command(command_ptr, job, inbg));
1443 #endif // BB_FEATURE_SH_BACKTICKS
1448 /* This is currently a little broken... */
1449 #ifdef HANDLE_CONTINUATION_CHARS
1450 /* They fed us a continuation char, so continue reading stuff
1451 * on the next line, then tack that onto the end of the current
1455 printf("erik: found a continue char at EOL...\n");
1456 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1457 if (get_command(input, command)) {
1458 error_msg("character expected after \\");
1463 newsize = strlen(*command_ptr) + strlen(command) + 2;
1464 if (newsize > BUFSIZ) {
1465 printf("erik: doing realloc\n");
1466 *command_ptr=xrealloc(*command_ptr, newsize);
1468 printf("erik: A: *command_ptr='%s'\n", *command_ptr);
1469 memcpy(--src, command, strlen(command));
1470 printf("erik: B: *command_ptr='%s'\n", *command_ptr);
1474 error_msg("character expected after \\");
1480 if (*src == '*' || *src == '[' || *src == ']'
1481 || *src == '?') *buf++ = '\\';
1490 if (*prog->argv[argc_l]) {
1497 prog->argv[argc_l] = NULL;
1499 if (!return_command) {
1500 job->text = xmalloc(strlen(*command_ptr) + 1);
1501 strcpy(job->text, *command_ptr);
1503 /* This leaves any trailing spaces, which is a bit sloppy */
1504 count = return_command - *command_ptr;
1505 job->text = xmalloc(count + 1);
1506 strncpy(job->text, *command_ptr, count);
1507 job->text[count] = '\0';
1510 *command_ptr = return_command;
1515 /* Run the child_prog, no matter what kind of command it uses.
1517 static int pseudo_exec(struct child_prog *child)
1519 struct built_in_command *x;
1520 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
1524 /* Check if the command matches any of the non-forking builtins.
1525 * Depending on context, this might be redundant. But it's
1526 * easier to waste a few CPU cycles than it is to figure out
1527 * if this is one of those cases.
1529 for (x = bltins; x->cmd; x++) {
1530 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1531 exit(x->function(child));
1535 /* Check if the command matches any of the forking builtins. */
1536 for (x = bltins_forking; x->cmd; x++) {
1537 if (strcmp(child->argv[0], x->cmd) == 0) {
1539 exit (x->function(child));
1542 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
1543 /* Check if the command matches any busybox internal
1544 * commands ("applets") here. Following discussions from
1545 * November 2000 on busybox@opensource.lineo.com, don't use
1546 * get_last_path_component(). This way explicit (with
1547 * slashes) filenames will never be interpreted as an
1548 * applet, just like with builtins. This way the user can
1549 * override an applet with an explicit filename reference.
1550 * The only downside to this change is that an explicit
1551 * /bin/foo invocation will fork and exec /bin/foo, even if
1552 * /bin/foo is a symlink to busybox.
1554 name = child->argv[0];
1556 #ifdef BB_FEATURE_SH_APPLETS_ALWAYS_WIN
1557 /* If you enable BB_FEATURE_SH_APPLETS_ALWAYS_WIN, then
1558 * if you run /bin/cat, it will use BusyBox cat even if
1559 * /bin/cat exists on the filesystem and is _not_ busybox.
1560 * Some systems want this, others do not. Choose wisely. :-)
1562 name = get_last_path_component(name);
1566 char** argv=child->argv;
1568 for(argc_l=0;*argv!=NULL; argv++, argc_l++);
1570 run_applet_by_name(name, argc_l, child->argv);
1574 execvp(child->argv[0], child->argv);
1575 perror_msg_and_die("%s", child->argv[0]);
1578 static void insert_job(struct job *newjob, int inbg)
1581 struct jobset *job_list=newjob->job_list;
1583 /* find the ID for thejob to use */
1585 for (thejob = job_list->head; thejob; thejob = thejob->next)
1586 if (thejob->jobid >= newjob->jobid)
1587 newjob->jobid = thejob->jobid + 1;
1589 /* add thejob to the list of running jobs */
1590 if (!job_list->head) {
1591 thejob = job_list->head = xmalloc(sizeof(*thejob));
1593 for (thejob = job_list->head; thejob->next; thejob = thejob->next) /* nothing */;
1594 thejob->next = xmalloc(sizeof(*thejob));
1595 thejob = thejob->next;
1598 *thejob = *newjob; /* physically copy the struct job */
1599 thejob->next = NULL;
1600 thejob->running_progs = thejob->num_progs;
1601 thejob->stopped_progs = 0;
1604 /* we don't wait for background thejobs to return -- append it
1605 to the list of backgrounded thejobs and leave it alone */
1606 printf("[%d] %d\n", thejob->jobid,
1607 newjob->progs[newjob->num_progs - 1].pid);
1608 #ifdef BB_FEATURE_SH_ENVIRONMENT
1609 last_bg_pid=newjob->progs[newjob->num_progs - 1].pid;
1612 newjob->job_list->fg = thejob;
1614 /* move the new process group into the foreground */
1615 /* suppress messages when run from /linuxrc mag@sysgo.de */
1616 if (tcsetpgrp(0, newjob->pgrp) && errno != ENOTTY)
1617 perror_msg("tcsetpgrp");
1621 static int run_command(struct job *newjob, int inbg, int outpipe[2])
1623 /* struct job *thejob; */
1625 int nextin, nextout;
1626 int pipefds[2]; /* pipefd[0] is for reading */
1627 struct built_in_command *x;
1628 struct child_prog *child;
1630 nextin = 0, nextout = 1;
1631 for (i = 0; i < newjob->num_progs; i++) {
1632 child = & (newjob->progs[i]);
1634 if ((i + 1) < newjob->num_progs) {
1635 if (pipe(pipefds)<0) perror_msg_and_die("pipe");
1636 nextout = pipefds[1];
1638 if (outpipe[1]!=-1) {
1639 nextout = outpipe[1];
1645 #ifdef BB_FEATURE_SH_ENVIRONMENT
1646 if (show_x_trace==TRUE) {
1649 for (j = 0; child->argv[j]; j++) {
1651 fputs(child->argv[j], stderr);
1653 fputc('\n', stderr);
1657 /* Check if the command matches any non-forking builtins,
1658 * but only if this is a simple command.
1659 * Non-forking builtins within pipes have to fork anyway,
1660 * and are handled in pseudo_exec. "echo foo | read bar"
1661 * is doomed to failure, and doesn't work on bash, either.
1663 if (newjob->num_progs == 1) {
1664 for (x = bltins; x->cmd; x++) {
1665 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1666 int squirrel[] = {-1, -1, -1};
1668 setup_redirects(child, squirrel);
1669 rcode = x->function(child);
1670 restore_redirects(squirrel);
1676 if (!(child->pid = fork())) {
1677 signal(SIGTTOU, SIG_DFL);
1681 if (outpipe[1]!=-1) {
1691 dup2(nextout, 2); /* Really? */
1696 /* explicit redirects override pipes */
1697 setup_redirects(child,NULL);
1701 if (outpipe[1]!=-1) {
1705 /* put our child in the process group whose leader is the
1706 first process in this pipe */
1707 setpgid(child->pid, newjob->progs[0].pid);
1713 /* If there isn't another process, nextin is garbage
1714 but it doesn't matter */
1715 nextin = pipefds[0];
1718 newjob->pgrp = newjob->progs[0].pid;
1720 insert_job(newjob, inbg);
1725 static int busy_loop(FILE * input)
1728 char *next_command = NULL;
1734 newjob.job_list = &job_list;
1735 newjob.job_context = DEFAULT_CONTEXT;
1737 /* save current owner of TTY so we can restore it on exit */
1738 parent_pgrp = tcgetpgrp(0);
1740 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1742 /* don't pay any attention to this signal; it just confuses
1743 things and isn't really meant for shells anyway */
1744 signal(SIGTTOU, SIG_IGN);
1748 /* no job is in the foreground */
1750 /* see if any background processes have exited */
1751 checkjobs(&job_list);
1753 if (!next_command) {
1754 if (get_command(input, command))
1756 next_command = command;
1759 if (expand_arguments(next_command) == FALSE) {
1761 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1762 next_command = NULL;
1766 if (!parse_command(&next_command, &newjob, &inbg) &&
1768 int pipefds[2] = {-1,-1};
1769 debug_printf( "job=%p fed to run_command by busy_loop()'\n",
1771 run_command(&newjob, inbg, pipefds);
1775 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1776 next_command = NULL;
1779 /* a job is running in the foreground; wait for it */
1781 while (!job_list.fg->progs[i].pid ||
1782 job_list.fg->progs[i].is_stopped == 1) i++;
1784 if (waitpid(job_list.fg->progs[i].pid, &status, WUNTRACED)<0)
1785 perror_msg_and_die("waitpid(%d)",job_list.fg->progs[i].pid);
1787 if (WIFEXITED(status) || WIFSIGNALED(status)) {
1788 /* the child exited */
1789 job_list.fg->running_progs--;
1790 job_list.fg->progs[i].pid = 0;
1792 #ifdef BB_FEATURE_SH_ENVIRONMENT
1793 last_return_code=WEXITSTATUS(status);
1794 debug_printf("'%s' exited -- return code %d\n",
1795 job_list.fg->text, last_return_code);
1797 if (!job_list.fg->running_progs) {
1799 remove_job(&job_list, job_list.fg);
1803 /* the child was stopped */
1804 job_list.fg->stopped_progs++;
1805 job_list.fg->progs[i].is_stopped = 1;
1807 if (job_list.fg->stopped_progs == job_list.fg->running_progs) {
1808 printf("\n" JOB_STATUS_FORMAT, job_list.fg->jobid,
1809 "Stopped", job_list.fg->text);
1815 /* move the shell to the foreground */
1816 /* suppress messages when run from /linuxrc mag@sysgo.de */
1817 if (tcsetpgrp(0, getpid()) && errno != ENOTTY)
1818 perror_msg("tcsetpgrp");
1824 /* return controlling TTY back to parent process group before exiting */
1825 if (tcsetpgrp(0, parent_pgrp))
1826 perror_msg("tcsetpgrp");
1828 /* return exit status if called with "-c" */
1829 if (input == NULL && WIFEXITED(status))
1830 return WEXITSTATUS(status);
1836 #ifdef BB_FEATURE_CLEAN_UP
1837 void free_memory(void)
1841 if (local_pending_command)
1842 free(local_pending_command);
1844 if (job_list.fg && !job_list.fg->running_progs) {
1845 remove_job(&job_list, job_list.fg);
1851 int shell_main(int argc_l, char **argv_l)
1853 int opt, interactive=FALSE;
1854 FILE *input = stdin;
1858 /* These variables need re-initializing when recursing */
1861 local_pending_command = NULL;
1862 close_me_head = NULL;
1863 job_list.head = NULL;
1865 #ifdef BB_FEATURE_SH_ENVIRONMENT
1871 if (argv[0] && argv[0][0] == '-') {
1873 prof_input = fopen("/etc/profile", "r");
1875 printf( "Couldn't open file '/etc/profile'\n");
1877 int tmp_fd = fileno(prof_input);
1879 /* Now run the file */
1880 busy_loop(prof_input);
1882 mark_closed(tmp_fd);
1886 while ((opt = getopt(argc_l, argv_l, "cxi")) > 0) {
1890 if (local_pending_command != 0)
1891 error_msg_and_die("multiple -c arguments");
1892 local_pending_command = xstrdup(argv[optind]);
1896 #ifdef BB_FEATURE_SH_ENVIRONMENT
1898 show_x_trace = TRUE;
1908 /* A shell is interactive if the `-i' flag was given, or if all of
1909 * the following conditions are met:
1911 * no arguments remaining or the -s flag given
1912 * standard input is a terminal
1913 * standard output is a terminal
1914 * Refer to Posix.2, the description of the `sh' utility. */
1915 if (argv[optind]==NULL && input==stdin &&
1916 isatty(fileno(stdin)) && isatty(fileno(stdout))) {
1919 if (interactive==TRUE) {
1920 //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
1921 /* Looks like they want an interactive shell */
1922 printf( "\n\nBusyBox v%s (%s) Built-in shell (lash)\n", BB_VER, BB_BT);
1923 printf( "Enter 'help' for a list of built-in commands.\n\n");
1924 } else if (local_pending_command==NULL) {
1925 //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
1926 input = xfopen(argv[optind], "r");
1927 mark_open(fileno(input)); /* be lazy, never mark this closed */
1930 /* initialize the cwd -- this is never freed...*/
1931 cwd=(char*)xmalloc(sizeof(char)*MAX_LINE+1);
1932 getcwd(cwd, sizeof(char)*MAX_LINE);
1934 #ifdef BB_FEATURE_CLEAN_UP
1935 atexit(free_memory);
1938 #ifdef BB_FEATURE_COMMAND_EDITING
1939 cmdedit_set_initial_prompt();
1945 return (busy_loop(input));