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>
69 //#define BB_FEATURE_SH_WORDEXP
71 #ifdef BB_FEATURE_SH_WORDEXP
73 #define expand_t wordexp_t
74 #undef BB_FEATURE_SH_BACKTICKS
77 #define expand_t glob_t
83 static const int MAX_LINE = 256; /* size of input buffer for cwd data */
84 static const int MAX_READ = 128; /* size of input buffer for `read' builtin */
85 #define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
88 enum redir_type { REDIRECT_INPUT, REDIRECT_OVERWRITE,
92 static const unsigned int DEFAULT_CONTEXT=0x1;
93 static const unsigned int IF_TRUE_CONTEXT=0x2;
94 static const unsigned int IF_FALSE_CONTEXT=0x4;
95 static const unsigned int THEN_EXP_CONTEXT=0x8;
96 static const unsigned int ELSE_EXP_CONTEXT=0x10;
100 struct job *head; /* head of list of running jobs */
101 struct job *fg; /* current foreground job */
104 struct redir_struct {
105 enum redir_type type; /* type of redirection */
106 int fd; /* file descriptor being redirected */
107 char *filename; /* file to redirect fd to */
111 pid_t pid; /* 0 if exited */
112 char **argv; /* program name and arguments */
113 int num_redirects; /* elements in redirection array */
114 struct redir_struct *redirects; /* I/O redirects */
115 int is_stopped; /* is the program currently running? */
116 struct job *family; /* pointer back to the child's parent job */
120 int jobid; /* job number */
121 int num_progs; /* total number of programs in job */
122 int running_progs; /* number of programs running */
123 char *text; /* name of job */
124 char *cmdbuf; /* buffer various argv's point into */
125 pid_t pgrp; /* process group ID for the job */
126 struct child_prog *progs; /* array of programs in job */
127 struct job *next; /* to track background commands */
128 int stopped_progs; /* number of programs alive, but stopped */
129 unsigned int job_context; /* bitmask defining current context */
130 struct jobset *job_list;
133 struct built_in_command {
134 char *cmd; /* name */
135 char *descr; /* description */
136 int (*function) (struct child_prog *); /* function ptr */
141 struct close_me *next;
144 /* function prototypes for builtins */
145 static int builtin_cd(struct child_prog *cmd);
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 {"pwd", "Print current directory", builtin_pwd},
206 {"help", "List shell built-in commands", builtin_help},
211 /* Variables we export */
212 unsigned int shell_context; /* Used in cmdedit.c to reset the
213 context when someone hits ^C */
216 /* Globals that are static to this file */
218 static char *local_pending_command = NULL;
219 static struct jobset job_list = { NULL, NULL };
222 static struct close_me *close_me_head;
223 #ifdef BB_FEATURE_SH_ENVIRONMENT
224 static int last_bg_pid;
225 static int last_return_code;
226 static int show_x_trace;
228 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
229 static char syntax_err[]="syntax error near unexpected token";
237 static inline void debug_printf(const char *format, ...)
240 va_start(args, format);
241 vfprintf(stderr, format, args);
245 static inline void debug_printf(const char *format, ...) { }
249 Most builtins need access to the struct child_prog that has
250 their arguments, previously coded as cmd->progs[0]. That coding
251 can exhibit a bug, if the builtin is not the first command in
252 a pipeline: "echo foo | exec sort" will attempt to exec foo.
254 builtin previous use notes
255 ------ ----------------- ---------
257 exec cmd->progs[0] squashed bug: didn't look for applets or forking builtins
259 fg_bg cmd->progs[0], job_list->head, job_list->fg
267 if cmd->job_context, cmd->text
268 then cmd->job_context, cmd->text
269 else cmd->job_context, cmd->text
272 The use of cmd->text by if/then/else/fi is hopelessly hacky.
273 Would it work to increment cmd->progs[0]->argv and recurse,
274 somewhat like builtin_exec does?
276 I added "struct job *family;" to struct child_prog,
277 and switched API to builtin_foo(struct child_prog *child);
278 So cmd->text becomes child->family->text
279 cmd->job_context becomes child->family->job_context
280 cmd->progs[0] becomes *child
281 job_list becomes child->family->job_list
284 /* built-in 'cd <path>' handler */
285 static int builtin_cd(struct child_prog *child)
289 if (child->argv[1] == NULL)
290 newdir = getenv("HOME");
292 newdir = child->argv[1];
294 printf("cd: %s: %m\n", newdir);
297 getcwd(cwd, sizeof(char)*MAX_LINE);
302 /* built-in 'exec' handler */
303 static int builtin_exec(struct child_prog *child)
305 if (child->argv[1] == NULL)
306 return EXIT_SUCCESS; /* Really? */
313 /* built-in 'exit' handler */
314 static int builtin_exit(struct child_prog *child)
316 if (child->argv[1] == NULL)
319 exit (atoi(child->argv[1]));
322 /* built-in 'fg' and 'bg' handler */
323 static int builtin_fg_bg(struct child_prog *child)
326 struct job *job=NULL;
328 if (!child->argv[1] || child->argv[2]) {
329 error_msg("%s: exactly one argument is expected",
334 if (sscanf(child->argv[1], "%%%d", &jobNum) != 1) {
335 error_msg("%s: bad argument '%s'",
336 child->argv[0], child->argv[1]);
340 for (job = child->family->job_list->head; job; job = job->next) {
341 if (job->jobid == jobNum) {
347 error_msg("%s: unknown job %d",
348 child->argv[0], jobNum);
352 if (*child->argv[0] == 'f') {
353 /* Make this job the foreground job */
354 /* suppress messages when run from /linuxrc mag@sysgo.de */
355 if (tcsetpgrp(0, job->pgrp) && errno != ENOTTY)
356 perror_msg("tcsetpgrp");
357 child->family->job_list->fg = job;
360 /* Restart the processes in the job */
361 for (i = 0; i < job->num_progs; i++)
362 job->progs[i].is_stopped = 0;
364 kill(-job->pgrp, SIGCONT);
366 job->stopped_progs = 0;
371 /* built-in 'help' handler */
372 static int builtin_help(struct child_prog *dummy)
374 struct built_in_command *x;
376 printf("\nBuilt-in commands:\n");
377 printf("-------------------\n");
378 for (x = bltins; x->cmd; x++) {
381 printf("%s\t%s\n", x->cmd, x->descr);
383 for (x = bltins_forking; x->cmd; x++) {
386 printf("%s\t%s\n", x->cmd, x->descr);
392 /* built-in 'jobs' handler */
393 static int builtin_jobs(struct child_prog *child)
398 for (job = child->family->job_list->head; job; job = job->next) {
399 if (job->running_progs == job->stopped_progs)
400 status_string = "Stopped";
402 status_string = "Running";
404 printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->text);
410 /* built-in 'pwd' handler */
411 static int builtin_pwd(struct child_prog *dummy)
413 getcwd(cwd, MAX_LINE);
414 printf( "%s\n", cwd);
418 /* built-in 'export VAR=value' handler */
419 static int builtin_export(struct child_prog *child)
422 char *v = child->argv[1];
426 for (e = environ; *e; e++) {
432 fprintf(stderr, "export: %m\n");
433 #ifndef BB_FEATURE_SH_SIMPLE_PROMPT
434 if (strncmp(v, "PS1=", 4)==0)
436 else if (strncmp(v, "PS2=", 4)==0)
439 if(strncmp(v, "LC_ALL=", 7)==0)
440 setlocale(LC_ALL, getenv("LC_ALL"));
441 if(strncmp(v, "LC_CTYPE=", 9)==0)
442 setlocale(LC_CTYPE, getenv("LC_CTYPE"));
447 /* built-in 'read VAR' handler */
448 static int builtin_read(struct child_prog *child)
450 int res = 0, len, newlen;
452 char string[MAX_READ];
454 if (child->argv[1]) {
455 /* argument (VAR) given: put "VAR=" into buffer */
456 strcpy(string, child->argv[1]);
457 len = strlen(string);
460 fgets(&string[len], sizeof(string) - len, stdin); /* read string */
461 newlen = strlen(string);
463 string[--newlen] = '\0'; /* chomp trailing newline */
465 ** string should now contain "VAR=<value>"
466 ** copy it (putenv() won't do that, so we must make sure
467 ** the string resides in a static buffer!)
470 if((s = strdup(string)))
473 fprintf(stderr, "read: %m\n");
476 fgets(string, sizeof(string), stdin);
481 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
482 /* Built-in handler for 'if' commands */
483 static int builtin_if(struct child_prog *child)
485 struct job *cmd = child->family;
487 char* charptr1=cmd->text+3; /* skip over the leading 'if ' */
489 /* Now run the 'if' command */
490 debug_printf( "job=%p entering builtin_if ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
491 status = run_command_predicate(charptr1);
492 debug_printf( "if test returned ");
494 debug_printf( "TRUE\n");
495 cmd->job_context |= IF_TRUE_CONTEXT;
497 debug_printf( "FALSE\n");
498 cmd->job_context |= IF_FALSE_CONTEXT;
500 debug_printf("job=%p builtin_if set job context to %x\n", cmd, cmd->job_context);
506 /* Built-in handler for 'then' (part of the 'if' command) */
507 static int builtin_then(struct child_prog *child)
509 struct job *cmd = child->family;
510 char* charptr1=cmd->text+5; /* skip over the leading 'then ' */
512 debug_printf( "job=%p entering builtin_then ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
513 if (! (cmd->job_context & (IF_TRUE_CONTEXT|IF_FALSE_CONTEXT))) {
514 shell_context = 0; /* Reset the shell's context on an error */
515 error_msg("%s `then'", syntax_err);
519 cmd->job_context |= THEN_EXP_CONTEXT;
520 debug_printf("job=%p builtin_then set job context to %x\n", cmd, cmd->job_context);
522 /* If the if result was FALSE, skip the 'then' stuff */
523 if (cmd->job_context & IF_FALSE_CONTEXT) {
527 /* Seems the if result was TRUE, so run the 'then' command */
528 debug_printf( "'then' now running '%s'\n", charptr1);
530 return(run_command_predicate(charptr1));
533 /* Built-in handler for 'else' (part of the 'if' command) */
534 static int builtin_else(struct child_prog *child)
536 struct job *cmd = child->family;
537 char* charptr1=cmd->text+5; /* skip over the leading 'else ' */
539 debug_printf( "job=%p entering builtin_else ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
541 if (! (cmd->job_context & THEN_EXP_CONTEXT)) {
542 shell_context = 0; /* Reset the shell's context on an error */
543 error_msg("%s `else'", syntax_err);
546 /* If the if result was TRUE, skip the 'else' stuff */
547 if (cmd->job_context & IF_TRUE_CONTEXT) {
551 cmd->job_context |= ELSE_EXP_CONTEXT;
552 debug_printf("job=%p builtin_else set job context to %x\n", cmd, cmd->job_context);
554 /* Now run the 'else' command */
555 debug_printf( "'else' now running '%s'\n", charptr1);
556 return(run_command_predicate(charptr1));
559 /* Built-in handler for 'fi' (part of the 'if' command) */
560 static int builtin_fi(struct child_prog *child)
562 struct job *cmd = child->family;
563 debug_printf( "job=%p entering builtin_fi ('%s')-- context=%d\n", cmd, "", cmd->job_context);
564 if (! (cmd->job_context & (IF_TRUE_CONTEXT|IF_FALSE_CONTEXT))) {
565 shell_context = 0; /* Reset the shell's context on an error */
566 error_msg("%s `fi'", syntax_err);
569 /* Clear out the if and then context bits */
570 cmd->job_context &= ~(IF_TRUE_CONTEXT|IF_FALSE_CONTEXT|THEN_EXP_CONTEXT|ELSE_EXP_CONTEXT);
571 debug_printf("job=%p builtin_fi set job context to %x\n", cmd, cmd->job_context);
577 /* Built-in '.' handler (read-in and execute commands from file) */
578 static int builtin_source(struct child_prog *child)
584 if (child->argv[1] == NULL)
587 input = fopen(child->argv[1], "r");
589 printf( "Couldn't open file '%s'\n", child->argv[1]);
595 /* Now run the file */
596 status = busy_loop(input);
602 /* built-in 'unset VAR' handler */
603 static int builtin_unset(struct child_prog *child)
605 if (child->argv[1] == NULL) {
606 printf( "unset: parameter required.\n");
609 unsetenv(child->argv[1]);
613 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
614 /* currently used by if/then/else.
616 * Reparsing the command line for this purpose is gross,
617 * incorrect, and fundamentally unfixable; in particular,
618 * think about what happens with command substitution.
619 * We really need to pull out the run, wait, return status
620 * functionality out of busy_loop so we can child->argv++
621 * and use that, without going back through parse_command.
623 static int run_command_predicate(char *cmd)
626 local_pending_command = xmalloc(n+1);
627 strncpy(local_pending_command, cmd, n);
628 local_pending_command[n]='\0';
629 return( busy_loop(NULL));
633 static void mark_open(int fd)
635 struct close_me *new = xmalloc(sizeof(struct close_me));
637 new->next = close_me_head;
641 static void mark_closed(int fd)
643 struct close_me *tmp;
644 if (close_me_head == NULL || close_me_head->fd != fd)
645 error_msg_and_die("corrupt close_me");
647 close_me_head = close_me_head->next;
651 static void close_all()
653 struct close_me *c, *tmp;
654 for (c=close_me_head; c; c=tmp) {
659 close_me_head = NULL;
663 /* free up all memory from a job */
664 static void free_job(struct job *cmd)
669 for (i = 0; i < cmd->num_progs; i++) {
670 free(cmd->progs[i].argv);
671 if (cmd->progs[i].redirects)
672 free(cmd->progs[i].redirects);
680 keep = cmd->job_list;
681 memset(cmd, 0, sizeof(struct job));
682 cmd->job_list = keep;
685 /* remove a job from a jobset */
686 static void remove_job(struct jobset *j_list, struct job *job)
691 if (job == j_list->head) {
692 j_list->head = job->next;
694 prevjob = j_list->head;
695 while (prevjob->next != job)
696 prevjob = prevjob->next;
697 prevjob->next = job->next;
703 /* Checks to see if any background processes have exited -- if they
704 have, figure out why and see if a job has completed */
705 static void checkjobs(struct jobset *j_list)
712 while ((childpid = waitpid(-1, &status, WNOHANG | WUNTRACED)) > 0) {
713 for (job = j_list->head; job; job = job->next) {
715 while (prognum < job->num_progs &&
716 job->progs[prognum].pid != childpid) prognum++;
717 if (prognum < job->num_progs)
721 /* This happens on backticked commands */
725 if (WIFEXITED(status) || WIFSIGNALED(status)) {
727 job->running_progs--;
728 job->progs[prognum].pid = 0;
730 if (!job->running_progs) {
731 printf(JOB_STATUS_FORMAT, job->jobid, "Done", job->text);
732 remove_job(j_list, job);
736 job->stopped_progs++;
737 job->progs[prognum].is_stopped = 1;
739 if (job->stopped_progs == job->num_progs) {
740 printf(JOB_STATUS_FORMAT, job->jobid, "Stopped",
746 if (childpid == -1 && errno != ECHILD)
747 perror_msg("waitpid");
750 /* squirrel != NULL means we squirrel away copies of stdin, stdout,
751 * and stderr if they are redirected. */
752 static int setup_redirects(struct child_prog *prog, int squirrel[])
757 struct redir_struct *redir = prog->redirects;
759 for (i = 0; i < prog->num_redirects; i++, redir++) {
760 switch (redir->type) {
764 case REDIRECT_OVERWRITE:
765 mode = O_WRONLY | O_CREAT | O_TRUNC;
767 case REDIRECT_APPEND:
768 mode = O_WRONLY | O_CREAT | O_APPEND;
772 openfd = open(redir->filename, mode, 0666);
774 /* this could get lost if stderr has been redirected, but
775 bash and ash both lose it as well (though zsh doesn't!) */
776 perror_msg("error opening %s", redir->filename);
780 if (openfd != redir->fd) {
781 if (squirrel && redir->fd < 3) {
782 squirrel[redir->fd] = dup(redir->fd);
784 dup2(openfd, redir->fd);
792 static void restore_redirects(int squirrel[])
795 for (i=0; i<3; i++) {
798 /* No error checking. I sure wouldn't know what
799 * to do with an error if I found one! */
806 static inline void cmdedit_set_initial_prompt(void)
808 #ifdef BB_FEATURE_SH_SIMPLE_PROMPT
822 static inline void setup_prompt_string(char **prompt_str)
824 #ifdef BB_FEATURE_SH_SIMPLE_PROMPT
825 /* Set up the prompt */
826 if (shell_context == 0) {
829 PS1=xmalloc(strlen(cwd)+4);
830 sprintf(PS1, "%s %s", cwd, ( geteuid() != 0 ) ? "$ ":"# ");
836 *prompt_str = (shell_context==0)? PS1 : PS2;
840 static int get_command(FILE * source, char *command)
844 if (source == NULL) {
845 if (local_pending_command) {
846 /* a command specified (-c option): return it & mark it done */
847 strcpy(command, local_pending_command);
848 free(local_pending_command);
849 local_pending_command = NULL;
855 if (source == stdin) {
856 setup_prompt_string(&prompt_str);
858 #ifdef BB_FEATURE_COMMAND_EDITING
860 ** enable command line editing only while a command line
861 ** is actually being read; otherwise, we'll end up bequeathing
862 ** atexit() handlers and other unwanted stuff to our
863 ** child processes (rob@sysgo.de)
865 cmdedit_read_input(prompt_str, command);
869 fputs(prompt_str, stdout);
873 if (!fgets(command, BUFSIZ - 2, source)) {
882 #ifdef BB_FEATURE_SH_ENVIRONMENT
883 static char* itoa(register int i)
885 static char a[7]; /* Max 7 ints */
886 register char *b = a + sizeof(a) - 1;
894 *--b = '0' + (i % 10);
904 #if defined BB_FEATURE_SH_ENVIRONMENT && ! defined BB_FEATURE_SH_WORDEXP
905 char * strsep_space( char *string, int * ix)
911 /* Short circuit the trivial case */
912 if ( !string || ! string[*ix])
915 /* Find the end of the token. */
916 while( string && string[*ix] && !isspace(string[*ix]) ) {
920 /* Find the end of any whitespace trailing behind
921 * the token and let that be part of the token */
922 while( string && string[*ix] && isspace(string[*ix]) ) {
926 if (! string && *ix==0) {
927 /* Nothing useful was found */
931 token = xmalloc(*ix+1);
933 strncpy(token, string, *ix);
940 static int expand_arguments(char *command)
942 #ifdef BB_FEATURE_SH_ENVIRONMENT
943 expand_t expand_result;
944 char *src, *dst, *var;
946 int i=0, length, total_length=0, retval;
947 const char *out_of_space = "out of space during expansion";
950 /* get rid of the terminating \n */
953 /* Fix up escape sequences to be the Real Thing(tm) */
954 while( command && command[ix]) {
955 if (command[ix] == '\\') {
956 char *tmp = command+ix+1;
957 command[ix] = process_escape_sequence( &tmp );
958 memmove(command+ix + 1, tmp, strlen(tmp)+1);
963 #ifdef BB_FEATURE_SH_ENVIRONMENT
966 #ifdef BB_FEATURE_SH_WORDEXP
967 /* This first part uses wordexp() which is a wonderful C lib
968 * function which expands nearly everything. */
969 retval = wordexp (command, &expand_result, WRDE_SHOWERR);
970 if (retval == WRDE_NOSPACE) {
971 /* Mem may have been allocated... */
972 wordfree (&expand_result);
973 error_msg(out_of_space);
977 /* Some other error. */
978 error_msg("syntax error");
982 if (expand_result.we_wordc > 0) {
983 /* Convert from char** (one word per string) to a simple char*,
984 * but don't overflow command which is BUFSIZ in length */
986 while (i < expand_result.we_wordc && total_length < BUFSIZ) {
987 length=strlen(expand_result.we_wordv[i])+1;
988 if (BUFSIZ-total_length-length <= 0) {
989 error_msg(out_of_space);
992 strcat(command+total_length, expand_result.we_wordv[i++]);
993 strcat(command+total_length, " ");
994 total_length+=length;
996 wordfree (&expand_result);
1000 /* Ok. They don't have a recent glibc and they don't have uClibc. Chances
1001 * are about 100% they don't have wordexp(). So instead the best we can do
1002 * is use glob and then fixup environment variables and such ourselves.
1003 * This is better then nothing, but certainly not perfect */
1005 /* It turns out that glob is very stupid. We have to feed it one word at a
1006 * time since it can't cope with a full string. Here we convert command
1007 * (char*) into cmd (char**, one word per string) */
1010 int flags = GLOB_NOCHECK
1018 char *tmpcmd, *cmd, *cmd_copy;
1019 /* We need a clean copy, so strsep can mess up the copy while
1020 * we write stuff into the original (in a minute) */
1021 cmd = cmd_copy = strdup(command);
1023 for (ix = 0, tmpcmd = cmd;
1024 (tmpcmd = strsep_space(cmd, &ix)) != NULL; cmd += ix, ix=0) {
1025 if (*tmpcmd == '\0')
1027 retval = glob(tmpcmd, flags, NULL, &expand_result);
1028 free(tmpcmd); /* Free mem allocated by strsep_space */
1029 if (retval == GLOB_NOSPACE) {
1030 /* Mem may have been allocated... */
1031 globfree (&expand_result);
1032 error_msg(out_of_space);
1034 } else if (retval != 0) {
1035 /* Some other error. GLOB_NOMATCH shouldn't
1036 * happen because of the GLOB_NOCHECK flag in
1038 error_msg("syntax error");
1041 /* Convert from char** (one word per string) to a simple char*,
1042 * but don't overflow command which is BUFSIZ in length */
1043 for (i=0; i < expand_result.gl_pathc; i++) {
1044 length=strlen(expand_result.gl_pathv[i]);
1045 if (total_length+length+1 >= BUFSIZ) {
1046 error_msg(out_of_space);
1050 strcat(command+total_length, " ");
1053 strcat(command+total_length, expand_result.gl_pathv[i]);
1054 total_length+=length;
1056 globfree (&expand_result);
1065 /* Now do the shell variable substitutions which
1066 * wordexp can't do for us, namely $? and $! */
1068 while((dst = strchr(src,'$')) != NULL){
1072 var = itoa(last_return_code);
1075 if (last_bg_pid==-1)
1078 var = itoa(last_bg_pid);
1080 /* Everything else like $$, $#, $[0-9], etc should all be
1081 * expanded by wordexp(), so we can in theory skip that stuff
1082 * here, but just to be on the safe side (i.e. since uClibc
1083 * wordexp doesn't do this stuff yet), lets leave it in for
1086 var = itoa(getpid());
1091 case '0':case '1':case '2':case '3':case '4':
1092 case '5':case '6':case '7':case '8':case '9':
1094 int ixx=*(dst + 1)-48;
1105 /* a single character construction was found, and
1106 * already handled in the case statement */
1109 /* Looks like an environment variable */
1111 int num_skip_chars=0;
1112 int dstlen = strlen(dst);
1113 /* Is this a ${foo} type variable? */
1114 if (dstlen >=2 && *(dst+1) == '{') {
1115 src=strchr(dst+1, '}');
1119 while(isalnum(*src) || *src=='_') src++;
1125 *src='\0'; /* temporary */
1126 var = getenv(dst + 1 + num_skip_chars);
1128 src += num_skip_chars;
1131 /* Seems we got an un-expandable variable. So delete it. */
1135 int subst_len = strlen(var);
1136 int trail_len = strlen(src);
1137 if (dst+subst_len+trail_len >= command+BUFSIZ) {
1138 error_msg(out_of_space);
1141 /* Move stuff to the end of the string to accommodate
1142 * filling the created gap with the new stuff */
1143 memmove(dst+subst_len, src, trail_len+1);
1144 /* Now copy in the new stuff */
1145 memcpy(dst, var, subst_len);
1146 src = dst+subst_len;
1154 /* Return cmd->num_progs as 0 if no command is present (e.g. an empty
1155 line). If a valid command is found, command_ptr is set to point to
1156 the beginning of the next command (if the original command had more
1157 then one job associated with it) or NULL if no more commands are
1159 static int parse_command(char **command_ptr, struct job *job, int *inbg)
1162 char *return_command = NULL;
1163 char *src, *buf, *chptr;
1170 struct child_prog *prog;
1172 /* skip leading white space */
1173 while (**command_ptr && isspace(**command_ptr))
1176 /* this handles empty lines or leading '#' characters */
1177 if (!**command_ptr || (**command_ptr == '#')) {
1184 job->progs = xmalloc(sizeof(*job->progs));
1186 /* We set the argv elements to point inside of this string. The
1187 memory is freed by free_job(). Allocate twice the original
1188 length in case we need to quote every single character.
1190 Getting clean memory relieves us of the task of NULL
1191 terminating things and makes the rest of this look a bit
1192 cleaner (though it is, admittedly, a tad less efficient) */
1193 job->cmdbuf = command = xcalloc(2*strlen(*command_ptr) + 1, sizeof(char));
1197 prog->num_redirects = 0;
1198 prog->redirects = NULL;
1199 prog->is_stopped = 0;
1203 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1204 prog->argv[0] = job->cmdbuf;
1208 while (*src && !done) {
1209 if (quote == *src) {
1215 error_msg("character expected after \\");
1220 /* in shell, "\'" should yield \' */
1221 if (*src != quote) {
1225 } else if (*src == '*' || *src == '?' || *src == '[' ||
1226 *src == ']') *buf++ = '\\';
1228 } else if (isspace(*src)) {
1229 if (*prog->argv[argc_l]) {
1231 /* +1 here leaves room for the NULL which ends argv */
1232 if ((argc_l + 1) == argv_alloced) {
1234 prog->argv = xrealloc(prog->argv,
1235 sizeof(*prog->argv) *
1238 prog->argv[argc_l] = buf;
1247 case '#': /* comment */
1254 case '>': /* redirects */
1256 i = prog->num_redirects++;
1257 prog->redirects = xrealloc(prog->redirects,
1258 sizeof(*prog->redirects) *
1261 prog->redirects[i].fd = -1;
1262 if (buf != prog->argv[argc_l]) {
1263 /* the stuff before this character may be the file number
1265 prog->redirects[i].fd =
1266 strtol(prog->argv[argc_l], &chptr, 10);
1268 if (*chptr && *prog->argv[argc_l]) {
1270 prog->argv[argc_l] = buf;
1274 if (prog->redirects[i].fd == -1) {
1276 prog->redirects[i].fd = 1;
1278 prog->redirects[i].fd = 0;
1281 if (*src++ == '>') {
1283 prog->redirects[i].type =
1284 REDIRECT_APPEND, src++;
1286 prog->redirects[i].type = REDIRECT_OVERWRITE;
1288 prog->redirects[i].type = REDIRECT_INPUT;
1291 /* This isn't POSIX sh compliant. Oh well. */
1293 while (isspace(*chptr))
1297 error_msg("file name expected after %c", *(src-1));
1303 prog->redirects[i].filename = buf;
1304 while (*chptr && !isspace(*chptr))
1307 src = chptr - 1; /* we src++ later */
1308 prog->argv[argc_l] = ++buf;
1311 case '|': /* pipe */
1312 /* finish this command */
1313 if (*prog->argv[argc_l])
1316 error_msg("empty command in pipe");
1321 prog->argv[argc_l] = NULL;
1323 /* and start the next */
1325 job->progs = xrealloc(job->progs,
1326 sizeof(*job->progs) * job->num_progs);
1327 prog = job->progs + (job->num_progs - 1);
1328 prog->num_redirects = 0;
1329 prog->redirects = NULL;
1330 prog->is_stopped = 0;
1335 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1336 prog->argv[0] = ++buf;
1339 while (*src && isspace(*src))
1343 error_msg("empty command in pipe");
1348 src--; /* we'll ++ it at the end of the loop */
1352 case '&': /* background */
1354 case ';': /* multiple commands */
1356 return_command = *command_ptr + (src - *command_ptr) + 1;
1359 #ifdef BB_FEATURE_SH_BACKTICKS
1361 /* Exec a backtick-ed command */
1362 /* Besides any previous brokenness, I have not
1363 * updated backtick handling for close_me support.
1364 * I don't know if it needs it or not. -- LRD */
1366 char* charptr1=NULL, *charptr2;
1369 struct jobset njob_list = { NULL, NULL };
1373 ptr=strchr(++src, '`');
1375 fprintf(stderr, "Unmatched '`' in command\n");
1380 /* Make some space to hold just the backticked command */
1381 charptr1 = charptr2 = xmalloc(1+ptr-src);
1382 memcpy(charptr1, src, ptr-src);
1383 charptr1[ptr-src] = '\0';
1384 newjob = xmalloc(sizeof(struct job));
1385 newjob->job_list = &njob_list;
1386 /* Now parse and run the backticked command */
1387 if (!parse_command(&charptr1, newjob, inbg)
1388 && newjob->num_progs) {
1390 run_command(newjob, 0, pipefd);
1392 checkjobs(job->job_list);
1393 free_job(newjob); /* doesn't actually free newjob,
1394 looks like a memory leak */
1397 /* Make a copy of any stuff left over in the command
1398 * line after the second backtick */
1399 charptr2 = xmalloc(strlen(ptr)+1);
1400 memcpy(charptr2, ptr+1, strlen(ptr));
1403 /* Copy the output from the backtick-ed command into the
1404 * command line, making extra room as needed */
1406 charptr1 = xmalloc(BUFSIZ);
1407 while ( (size=full_read(pipefd[0], charptr1, BUFSIZ-1)) >0) {
1408 int newsize=src - *command_ptr + size + 1 + strlen(charptr2);
1409 if (newsize > BUFSIZ) {
1410 *command_ptr=xrealloc(*command_ptr, newsize);
1412 memcpy(src, charptr1, size);
1420 /* Now paste into the *command_ptr all the stuff
1421 * leftover after the second backtick */
1422 memcpy(src, charptr2, strlen(charptr2)+1);
1425 /* Now recursively call parse_command to deal with the new
1426 * and improved version of the command line with the backtick
1427 * results expanded in place... */
1429 struct jobset *jl=job->job_list;
1433 return(parse_command(command_ptr, job, inbg));
1436 #endif // BB_FEATURE_SH_BACKTICKS
1441 /* This is currently a little broken... */
1442 #ifdef HANDLE_CONTINUATION_CHARS
1443 /* They fed us a continuation char, so continue reading stuff
1444 * on the next line, then tack that onto the end of the current
1448 printf("erik: found a continue char at EOL...\n");
1449 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1450 if (get_command(input, command)) {
1451 error_msg("character expected after \\");
1456 newsize = strlen(*command_ptr) + strlen(command) + 2;
1457 if (newsize > BUFSIZ) {
1458 printf("erik: doing realloc\n");
1459 *command_ptr=xrealloc(*command_ptr, newsize);
1461 printf("erik: A: *command_ptr='%s'\n", *command_ptr);
1462 memcpy(--src, command, strlen(command));
1463 printf("erik: B: *command_ptr='%s'\n", *command_ptr);
1467 error_msg("character expected after \\");
1472 if (*src == '*' || *src == '[' || *src == ']'
1473 || *src == '?') *buf++ = '\\';
1482 if (*prog->argv[argc_l]) {
1489 prog->argv[argc_l] = NULL;
1491 if (!return_command) {
1492 job->text = xmalloc(strlen(*command_ptr) + 1);
1493 strcpy(job->text, *command_ptr);
1495 /* This leaves any trailing spaces, which is a bit sloppy */
1496 count = return_command - *command_ptr;
1497 job->text = xmalloc(count + 1);
1498 strncpy(job->text, *command_ptr, count);
1499 job->text[count] = '\0';
1502 *command_ptr = return_command;
1507 /* Run the child_prog, no matter what kind of command it uses.
1509 static int pseudo_exec(struct child_prog *child)
1511 struct built_in_command *x;
1512 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
1516 /* Check if the command matches any of the non-forking builtins.
1517 * Depending on context, this might be redundant. But it's
1518 * easier to waste a few CPU cycles than it is to figure out
1519 * if this is one of those cases.
1521 for (x = bltins; x->cmd; x++) {
1522 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1523 exit(x->function(child));
1527 /* Check if the command matches any of the forking builtins. */
1528 for (x = bltins_forking; x->cmd; x++) {
1529 if (strcmp(child->argv[0], x->cmd) == 0) {
1531 exit (x->function(child));
1534 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
1535 /* Check if the command matches any busybox internal
1536 * commands ("applets") here. Following discussions from
1537 * November 2000 on busybox@opensource.lineo.com, don't use
1538 * get_last_path_component(). This way explicit (with
1539 * slashes) filenames will never be interpreted as an
1540 * applet, just like with builtins. This way the user can
1541 * override an applet with an explicit filename reference.
1542 * The only downside to this change is that an explicit
1543 * /bin/foo invocation will fork and exec /bin/foo, even if
1544 * /bin/foo is a symlink to busybox.
1546 name = child->argv[0];
1548 #ifdef BB_FEATURE_SH_APPLETS_ALWAYS_WIN
1549 /* If you enable BB_FEATURE_SH_APPLETS_ALWAYS_WIN, then
1550 * if you run /bin/cat, it will use BusyBox cat even if
1551 * /bin/cat exists on the filesystem and is _not_ busybox.
1552 * Some systems want this, others do not. Choose wisely. :-)
1554 name = get_last_path_component(name);
1558 char** argv_l=child->argv;
1560 for(argc_l=0;*argv_l!=NULL; argv_l++, argc_l++);
1562 run_applet_by_name(name, argc_l, child->argv);
1566 execvp(child->argv[0], child->argv);
1567 perror_msg_and_die("%s", child->argv[0]);
1570 static void insert_job(struct job *newjob, int inbg)
1573 struct jobset *j_list=newjob->job_list;
1575 /* find the ID for thejob to use */
1577 for (thejob = j_list->head; thejob; thejob = thejob->next)
1578 if (thejob->jobid >= newjob->jobid)
1579 newjob->jobid = thejob->jobid + 1;
1581 /* add thejob to the list of running jobs */
1582 if (!j_list->head) {
1583 thejob = j_list->head = xmalloc(sizeof(*thejob));
1585 for (thejob = j_list->head; thejob->next; thejob = thejob->next) /* nothing */;
1586 thejob->next = xmalloc(sizeof(*thejob));
1587 thejob = thejob->next;
1590 *thejob = *newjob; /* physically copy the struct job */
1591 thejob->next = NULL;
1592 thejob->running_progs = thejob->num_progs;
1593 thejob->stopped_progs = 0;
1596 /* we don't wait for background thejobs to return -- append it
1597 to the list of backgrounded thejobs and leave it alone */
1598 printf("[%d] %d\n", thejob->jobid,
1599 newjob->progs[newjob->num_progs - 1].pid);
1600 #ifdef BB_FEATURE_SH_ENVIRONMENT
1601 last_bg_pid=newjob->progs[newjob->num_progs - 1].pid;
1604 newjob->job_list->fg = thejob;
1606 /* move the new process group into the foreground */
1607 /* suppress messages when run from /linuxrc mag@sysgo.de */
1608 if (tcsetpgrp(0, newjob->pgrp) && errno != ENOTTY)
1609 perror_msg("tcsetpgrp");
1613 static int run_command(struct job *newjob, int inbg, int outpipe[2])
1615 /* struct job *thejob; */
1617 int nextin, nextout;
1618 int pipefds[2]; /* pipefd[0] is for reading */
1619 struct built_in_command *x;
1620 struct child_prog *child;
1622 nextin = 0, nextout = 1;
1623 for (i = 0; i < newjob->num_progs; i++) {
1624 child = & (newjob->progs[i]);
1626 if ((i + 1) < newjob->num_progs) {
1627 if (pipe(pipefds)<0) perror_msg_and_die("pipe");
1628 nextout = pipefds[1];
1630 if (outpipe[1]!=-1) {
1631 nextout = outpipe[1];
1637 #ifdef BB_FEATURE_SH_ENVIRONMENT
1638 if (show_x_trace==TRUE) {
1641 for (j = 0; child->argv[j]; j++) {
1643 fputs(child->argv[j], stderr);
1645 fputc('\n', stderr);
1649 /* Check if the command matches any non-forking builtins,
1650 * but only if this is a simple command.
1651 * Non-forking builtins within pipes have to fork anyway,
1652 * and are handled in pseudo_exec. "echo foo | read bar"
1653 * is doomed to failure, and doesn't work on bash, either.
1655 if (newjob->num_progs == 1) {
1656 for (x = bltins; x->cmd; x++) {
1657 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1658 int squirrel[] = {-1, -1, -1};
1660 setup_redirects(child, squirrel);
1661 rcode = x->function(child);
1662 restore_redirects(squirrel);
1668 if (!(child->pid = fork())) {
1669 signal(SIGTTOU, SIG_DFL);
1673 if (outpipe[1]!=-1) {
1683 dup2(nextout, 2); /* Really? */
1688 /* explicit redirects override pipes */
1689 setup_redirects(child,NULL);
1693 if (outpipe[1]!=-1) {
1697 /* put our child in the process group whose leader is the
1698 first process in this pipe */
1699 setpgid(child->pid, newjob->progs[0].pid);
1705 /* If there isn't another process, nextin is garbage
1706 but it doesn't matter */
1707 nextin = pipefds[0];
1710 newjob->pgrp = newjob->progs[0].pid;
1712 insert_job(newjob, inbg);
1717 static int busy_loop(FILE * input)
1720 char *next_command = NULL;
1726 newjob.job_list = &job_list;
1727 newjob.job_context = DEFAULT_CONTEXT;
1729 /* save current owner of TTY so we can restore it on exit */
1730 parent_pgrp = tcgetpgrp(0);
1732 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1734 /* don't pay any attention to this signal; it just confuses
1735 things and isn't really meant for shells anyway */
1736 signal(SIGTTOU, SIG_IGN);
1740 /* no job is in the foreground */
1742 /* see if any background processes have exited */
1743 checkjobs(&job_list);
1745 if (!next_command) {
1746 if (get_command(input, command))
1748 next_command = command;
1751 if (expand_arguments(next_command) == FALSE) {
1753 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1754 next_command = NULL;
1758 if (!parse_command(&next_command, &newjob, &inbg) &&
1760 int pipefds[2] = {-1,-1};
1761 debug_printf( "job=%p fed to run_command by busy_loop()'\n",
1763 run_command(&newjob, inbg, pipefds);
1767 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1768 next_command = NULL;
1771 /* a job is running in the foreground; wait for it */
1773 while (!job_list.fg->progs[i].pid ||
1774 job_list.fg->progs[i].is_stopped == 1) i++;
1776 if (waitpid(job_list.fg->progs[i].pid, &status, WUNTRACED)<0)
1777 perror_msg_and_die("waitpid(%d)",job_list.fg->progs[i].pid);
1779 if (WIFEXITED(status) || WIFSIGNALED(status)) {
1780 /* the child exited */
1781 job_list.fg->running_progs--;
1782 job_list.fg->progs[i].pid = 0;
1784 #ifdef BB_FEATURE_SH_ENVIRONMENT
1785 last_return_code=WEXITSTATUS(status);
1786 debug_printf("'%s' exited -- return code %d\n",
1787 job_list.fg->text, last_return_code);
1789 if (!job_list.fg->running_progs) {
1791 remove_job(&job_list, job_list.fg);
1795 /* the child was stopped */
1796 job_list.fg->stopped_progs++;
1797 job_list.fg->progs[i].is_stopped = 1;
1799 if (job_list.fg->stopped_progs == job_list.fg->running_progs) {
1800 printf("\n" JOB_STATUS_FORMAT, job_list.fg->jobid,
1801 "Stopped", job_list.fg->text);
1807 /* move the shell to the foreground */
1808 /* suppress messages when run from /linuxrc mag@sysgo.de */
1809 if (tcsetpgrp(0, getpid()) && errno != ENOTTY)
1810 perror_msg("tcsetpgrp");
1816 /* return controlling TTY back to parent process group before exiting */
1817 if (tcsetpgrp(0, parent_pgrp))
1818 perror_msg("tcsetpgrp");
1820 /* return exit status if called with "-c" */
1821 if (input == NULL && WIFEXITED(status))
1822 return WEXITSTATUS(status);
1828 #ifdef BB_FEATURE_CLEAN_UP
1829 void free_memory(void)
1833 if (local_pending_command)
1834 free(local_pending_command);
1836 if (job_list.fg && !job_list.fg->running_progs) {
1837 remove_job(&job_list, job_list.fg);
1843 int shell_main(int argc_l, char **argv_l)
1845 int opt, interactive=FALSE;
1846 FILE *input = stdin;
1850 /* These variables need re-initializing when recursing */
1853 local_pending_command = NULL;
1854 close_me_head = NULL;
1855 job_list.head = NULL;
1857 #ifdef BB_FEATURE_SH_ENVIRONMENT
1863 if (argv[0] && argv[0][0] == '-') {
1865 prof_input = fopen("/etc/profile", "r");
1867 printf( "Couldn't open file '/etc/profile'\n");
1869 int tmp_fd = fileno(prof_input);
1871 /* Now run the file */
1872 busy_loop(prof_input);
1874 mark_closed(tmp_fd);
1878 while ((opt = getopt(argc_l, argv_l, "cxi")) > 0) {
1882 if (local_pending_command != 0)
1883 error_msg_and_die("multiple -c arguments");
1884 local_pending_command = xstrdup(argv[optind]);
1888 #ifdef BB_FEATURE_SH_ENVIRONMENT
1890 show_x_trace = TRUE;
1900 /* A shell is interactive if the `-i' flag was given, or if all of
1901 * the following conditions are met:
1903 * no arguments remaining or the -s flag given
1904 * standard input is a terminal
1905 * standard output is a terminal
1906 * Refer to Posix.2, the description of the `sh' utility. */
1907 if (argv[optind]==NULL && input==stdin &&
1908 isatty(fileno(stdin)) && isatty(fileno(stdout))) {
1911 if (interactive==TRUE) {
1912 //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
1913 /* Looks like they want an interactive shell */
1914 printf( "\n\nBusyBox v%s (%s) Built-in shell (lash)\n", BB_VER, BB_BT);
1915 printf( "Enter 'help' for a list of built-in commands.\n\n");
1916 } else if (local_pending_command==NULL) {
1917 //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
1918 input = xfopen(argv[optind], "r");
1919 mark_open(fileno(input)); /* be lazy, never mark this closed */
1922 /* initialize the cwd -- this is never freed...*/
1923 cwd=(char*)xmalloc(sizeof(char)*MAX_LINE+1);
1924 getcwd(cwd, sizeof(char)*MAX_LINE);
1926 #ifdef BB_FEATURE_CLEAN_UP
1927 atexit(free_memory);
1930 #ifdef BB_FEATURE_COMMAND_EDITING
1931 cmdedit_set_initial_prompt();
1937 return (busy_loop(input));