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 #ifdef BB_LOCALE_SUPPORT
72 //#define BB_FEATURE_SH_WORDEXP
74 #ifdef BB_FEATURE_SH_WORDEXP
76 #define expand_t wordexp_t
77 #undef BB_FEATURE_SH_BACKTICKS
80 #define expand_t glob_t
86 static const int MAX_READ = 128; /* size of input buffer for `read' builtin */
87 #define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
90 enum redir_type { REDIRECT_INPUT, REDIRECT_OVERWRITE,
94 static const unsigned int DEFAULT_CONTEXT=0x1;
95 static const unsigned int IF_TRUE_CONTEXT=0x2;
96 static const unsigned int IF_FALSE_CONTEXT=0x4;
97 static const unsigned int THEN_EXP_CONTEXT=0x8;
98 static const unsigned int ELSE_EXP_CONTEXT=0x10;
102 struct job *head; /* head of list of running jobs */
103 struct job *fg; /* current foreground job */
106 struct redir_struct {
107 enum redir_type type; /* type of redirection */
108 int fd; /* file descriptor being redirected */
109 char *filename; /* file to redirect fd to */
113 pid_t pid; /* 0 if exited */
114 char **argv; /* program name and arguments */
115 int num_redirects; /* elements in redirection array */
116 struct redir_struct *redirects; /* I/O redirects */
117 int is_stopped; /* is the program currently running? */
118 struct job *family; /* pointer back to the child's parent job */
122 int jobid; /* job number */
123 int num_progs; /* total number of programs in job */
124 int running_progs; /* number of programs running */
125 char *text; /* name of job */
126 char *cmdbuf; /* buffer various argv's point into */
127 pid_t pgrp; /* process group ID for the job */
128 struct child_prog *progs; /* array of programs in job */
129 struct job *next; /* to track background commands */
130 int stopped_progs; /* number of programs alive, but stopped */
131 unsigned int job_context; /* bitmask defining current context */
132 struct jobset *job_list;
135 struct built_in_command {
136 char *cmd; /* name */
137 char *descr; /* description */
138 int (*function) (struct child_prog *); /* function ptr */
143 struct close_me *next;
146 /* function prototypes for builtins */
147 static int builtin_cd(struct child_prog *cmd);
148 static int builtin_exec(struct child_prog *cmd);
149 static int builtin_exit(struct child_prog *cmd);
150 static int builtin_fg_bg(struct child_prog *cmd);
151 static int builtin_help(struct child_prog *cmd);
152 static int builtin_jobs(struct child_prog *dummy);
153 static int builtin_pwd(struct child_prog *dummy);
154 static int builtin_export(struct child_prog *cmd);
155 static int builtin_source(struct child_prog *cmd);
156 static int builtin_unset(struct child_prog *cmd);
157 static int builtin_read(struct child_prog *cmd);
158 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
159 static int builtin_if(struct child_prog *cmd);
160 static int builtin_then(struct child_prog *cmd);
161 static int builtin_else(struct child_prog *cmd);
162 static int builtin_fi(struct child_prog *cmd);
163 /* function prototypes for shell stuff */
164 static int run_command_predicate(char *cmd);
168 /* function prototypes for shell stuff */
169 static void mark_open(int fd);
170 static void mark_closed(int fd);
171 static void close_all(void);
172 static void checkjobs(struct jobset *job_list);
173 static int get_command(FILE * source, char *command);
174 static int parse_command(char **command_ptr, struct job *job, int *inbg);
175 static int run_command(struct job *newjob, int inbg, int outpipe[2]);
176 static int pseudo_exec(struct child_prog *cmd) __attribute__ ((noreturn));
177 static int busy_loop(FILE * input);
180 /* Table of built-in functions (these are non-forking builtins, meaning they
181 * can change global variables in the parent shell process but they will not
182 * work with pipes and redirects; 'unset foo | whatever' will not work) */
183 static struct built_in_command bltins[] = {
184 {"bg", "Resume a job in the background", builtin_fg_bg},
185 {"cd", "Change working directory", builtin_cd},
186 {"exec", "Exec command, replacing this shell with the exec'd process", builtin_exec},
187 {"exit", "Exit from shell()", builtin_exit},
188 {"fg", "Bring job into the foreground", builtin_fg_bg},
189 {"jobs", "Lists the active jobs", builtin_jobs},
190 {"export", "Set environment variable", builtin_export},
191 {"unset", "Unset environment variable", builtin_unset},
192 {"read", "Input environment variable", builtin_read},
193 {".", "Source-in and run commands in a file", builtin_source},
194 /* to do: add ulimit */
195 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
196 {"if", NULL, builtin_if},
197 {"then", NULL, builtin_then},
198 {"else", NULL, builtin_else},
199 {"fi", NULL, builtin_fi},
204 /* Table of forking built-in functions (things that fork cannot change global
205 * variables in the parent process, such as the current working directory) */
206 static struct built_in_command bltins_forking[] = {
207 {"pwd", "Print current directory", builtin_pwd},
208 {"help", "List shell built-in commands", builtin_help},
213 /* Variables we export */
214 unsigned int shell_context; /* Used in cmdedit.c to reset the
215 context when someone hits ^C */
218 /* Globals that are static to this file */
220 static char *local_pending_command = NULL;
221 static struct jobset job_list = { NULL, NULL };
224 static struct close_me *close_me_head;
225 #ifdef BB_FEATURE_SH_ENVIRONMENT
226 static int last_bg_pid;
227 static int last_return_code;
228 static int show_x_trace;
230 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
231 static char syntax_err[]="syntax error near unexpected token";
235 static char *PS2 = "> ";
239 static inline void debug_printf(const char *format, ...)
242 va_start(args, format);
243 vfprintf(stderr, format, args);
247 static inline void debug_printf(const char *format, ...) { }
251 Most builtins need access to the struct child_prog that has
252 their arguments, previously coded as cmd->progs[0]. That coding
253 can exhibit a bug, if the builtin is not the first command in
254 a pipeline: "echo foo | exec sort" will attempt to exec foo.
256 builtin previous use notes
257 ------ ----------------- ---------
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
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);
304 /* built-in 'exec' handler */
305 static int builtin_exec(struct child_prog *child)
307 if (child->argv[1] == NULL)
308 return EXIT_SUCCESS; /* Really? */
315 /* built-in 'exit' handler */
316 static int builtin_exit(struct child_prog *child)
318 if (child->argv[1] == NULL)
321 exit (atoi(child->argv[1]));
324 /* built-in 'fg' and 'bg' handler */
325 static int builtin_fg_bg(struct child_prog *child)
328 struct job *job=NULL;
330 if (!child->argv[1] || child->argv[2]) {
331 error_msg("%s: exactly one argument is expected",
336 if (sscanf(child->argv[1], "%%%d", &jobNum) != 1) {
337 error_msg("%s: bad argument '%s'",
338 child->argv[0], child->argv[1]);
342 for (job = child->family->job_list->head; job; job = job->next) {
343 if (job->jobid == jobNum) {
349 error_msg("%s: unknown job %d",
350 child->argv[0], jobNum);
354 if (*child->argv[0] == 'f') {
355 /* Make this job the foreground job */
356 /* suppress messages when run from /linuxrc mag@sysgo.de */
357 if (tcsetpgrp(0, job->pgrp) && errno != ENOTTY)
358 perror_msg("tcsetpgrp");
359 child->family->job_list->fg = job;
362 /* Restart the processes in the job */
363 for (i = 0; i < job->num_progs; i++)
364 job->progs[i].is_stopped = 0;
366 kill(-job->pgrp, SIGCONT);
368 job->stopped_progs = 0;
373 /* built-in 'help' handler */
374 static int builtin_help(struct child_prog *dummy)
376 struct built_in_command *x;
378 printf("\nBuilt-in commands:\n");
379 printf("-------------------\n");
380 for (x = bltins; x->cmd; x++) {
383 printf("%s\t%s\n", x->cmd, x->descr);
385 for (x = bltins_forking; x->cmd; x++) {
388 printf("%s\t%s\n", x->cmd, x->descr);
394 /* built-in 'jobs' handler */
395 static int builtin_jobs(struct child_prog *child)
400 for (job = child->family->job_list->head; job; job = job->next) {
401 if (job->running_progs == job->stopped_progs)
402 status_string = "Stopped";
404 status_string = "Running";
406 printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->text);
412 /* built-in 'pwd' handler */
413 static int builtin_pwd(struct child_prog *dummy)
415 printf( "%s\n", cwd);
419 /* built-in 'export VAR=value' handler */
420 static int builtin_export(struct child_prog *child)
423 char *v = child->argv[1];
427 for (e = environ; *e; e++) {
434 fprintf(stderr, "export: %m\n");
435 #ifndef BB_FEATURE_SH_SIMPLE_PROMPT
436 if (strncmp(v, "PS1=", 4)==0)
440 #ifdef BB_LOCALE_SUPPORT
441 if(strncmp(v, "LC_ALL=", 7)==0)
442 setlocale(LC_ALL, getenv("LC_ALL"));
443 if(strncmp(v, "LC_CTYPE=", 9)==0)
444 setlocale(LC_CTYPE, getenv("LC_CTYPE"));
450 /* built-in 'read VAR' handler */
451 static int builtin_read(struct child_prog *child)
453 int res = 0, len, newlen;
455 char string[MAX_READ];
457 if (child->argv[1]) {
458 /* argument (VAR) given: put "VAR=" into buffer */
459 strcpy(string, child->argv[1]);
460 len = strlen(string);
463 fgets(&string[len], sizeof(string) - len, stdin); /* read string */
464 newlen = strlen(string);
466 string[--newlen] = '\0'; /* chomp trailing newline */
468 ** string should now contain "VAR=<value>"
469 ** copy it (putenv() won't do that, so we must make sure
470 ** the string resides in a static buffer!)
473 if((s = strdup(string)))
476 fprintf(stderr, "read: %m\n");
479 fgets(string, sizeof(string), stdin);
484 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
485 /* Built-in handler for 'if' commands */
486 static int builtin_if(struct child_prog *child)
488 struct job *cmd = child->family;
490 char* charptr1=cmd->text+3; /* skip over the leading 'if ' */
492 /* Now run the 'if' command */
493 debug_printf( "job=%p entering builtin_if ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
494 status = run_command_predicate(charptr1);
495 debug_printf( "if test returned ");
497 debug_printf( "TRUE\n");
498 cmd->job_context |= IF_TRUE_CONTEXT;
500 debug_printf( "FALSE\n");
501 cmd->job_context |= IF_FALSE_CONTEXT;
503 debug_printf("job=%p builtin_if set job context to %x\n", cmd, cmd->job_context);
509 /* Built-in handler for 'then' (part of the 'if' command) */
510 static int builtin_then(struct child_prog *child)
512 struct job *cmd = child->family;
513 char* charptr1=cmd->text+5; /* skip over the leading 'then ' */
515 debug_printf( "job=%p entering builtin_then ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
516 if (! (cmd->job_context & (IF_TRUE_CONTEXT|IF_FALSE_CONTEXT))) {
517 shell_context = 0; /* Reset the shell's context on an error */
518 error_msg("%s `then'", syntax_err);
522 cmd->job_context |= THEN_EXP_CONTEXT;
523 debug_printf("job=%p builtin_then set job context to %x\n", cmd, cmd->job_context);
525 /* If the if result was FALSE, skip the 'then' stuff */
526 if (cmd->job_context & IF_FALSE_CONTEXT) {
530 /* Seems the if result was TRUE, so run the 'then' command */
531 debug_printf( "'then' now running '%s'\n", charptr1);
533 return(run_command_predicate(charptr1));
536 /* Built-in handler for 'else' (part of the 'if' command) */
537 static int builtin_else(struct child_prog *child)
539 struct job *cmd = child->family;
540 char* charptr1=cmd->text+5; /* skip over the leading 'else ' */
542 debug_printf( "job=%p entering builtin_else ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
544 if (! (cmd->job_context & THEN_EXP_CONTEXT)) {
545 shell_context = 0; /* Reset the shell's context on an error */
546 error_msg("%s `else'", syntax_err);
549 /* If the if result was TRUE, skip the 'else' stuff */
550 if (cmd->job_context & IF_TRUE_CONTEXT) {
554 cmd->job_context |= ELSE_EXP_CONTEXT;
555 debug_printf("job=%p builtin_else set job context to %x\n", cmd, cmd->job_context);
557 /* Now run the 'else' command */
558 debug_printf( "'else' now running '%s'\n", charptr1);
559 return(run_command_predicate(charptr1));
562 /* Built-in handler for 'fi' (part of the 'if' command) */
563 static int builtin_fi(struct child_prog *child)
565 struct job *cmd = child->family;
566 debug_printf( "job=%p entering builtin_fi ('%s')-- context=%d\n", cmd, "", cmd->job_context);
567 if (! (cmd->job_context & (IF_TRUE_CONTEXT|IF_FALSE_CONTEXT))) {
568 shell_context = 0; /* Reset the shell's context on an error */
569 error_msg("%s `fi'", syntax_err);
572 /* Clear out the if and then context bits */
573 cmd->job_context &= ~(IF_TRUE_CONTEXT|IF_FALSE_CONTEXT|THEN_EXP_CONTEXT|ELSE_EXP_CONTEXT);
574 debug_printf("job=%p builtin_fi set job context to %x\n", cmd, cmd->job_context);
580 /* Built-in '.' handler (read-in and execute commands from file) */
581 static int builtin_source(struct child_prog *child)
587 if (child->argv[1] == NULL)
590 input = fopen(child->argv[1], "r");
592 printf( "Couldn't open file '%s'\n", child->argv[1]);
598 /* Now run the file */
599 status = busy_loop(input);
605 /* built-in 'unset VAR' handler */
606 static int builtin_unset(struct child_prog *child)
608 if (child->argv[1] == NULL) {
609 printf( "unset: parameter required.\n");
612 unsetenv(child->argv[1]);
616 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
617 /* currently used by if/then/else.
619 * Reparsing the command line for this purpose is gross,
620 * incorrect, and fundamentally unfixable; in particular,
621 * think about what happens with command substitution.
622 * We really need to pull out the run, wait, return status
623 * functionality out of busy_loop so we can child->argv++
624 * and use that, without going back through parse_command.
626 static int run_command_predicate(char *cmd)
628 local_pending_command = xstrdup(cmd);
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
817 static inline void setup_prompt_string(char **prompt_str)
819 #ifdef BB_FEATURE_SH_SIMPLE_PROMPT
820 /* Set up the prompt */
821 if (shell_context == 0) {
824 PS1=xmalloc(strlen(cwd)+4);
825 sprintf(PS1, "%s %s", cwd, ( geteuid() != 0 ) ? "$ ":"# ");
831 *prompt_str = (shell_context==0)? PS1 : PS2;
835 static int get_command(FILE * source, char *command)
839 if (source == NULL) {
840 if (local_pending_command) {
841 /* a command specified (-c option): return it & mark it done */
842 strcpy(command, local_pending_command);
843 free(local_pending_command);
844 local_pending_command = NULL;
850 if (source == stdin) {
851 setup_prompt_string(&prompt_str);
853 #ifdef BB_FEATURE_COMMAND_EDITING
855 ** enable command line editing only while a command line
856 ** is actually being read; otherwise, we'll end up bequeathing
857 ** atexit() handlers and other unwanted stuff to our
858 ** child processes (rob@sysgo.de)
860 cmdedit_read_input(prompt_str, command);
864 fputs(prompt_str, stdout);
868 if (!fgets(command, BUFSIZ - 2, source)) {
877 #ifdef BB_FEATURE_SH_ENVIRONMENT
878 static char* itoa(register int i)
880 static char a[7]; /* Max 7 ints */
881 register char *b = a + sizeof(a) - 1;
889 *--b = '0' + (i % 10);
899 #if defined BB_FEATURE_SH_ENVIRONMENT && ! defined BB_FEATURE_SH_WORDEXP
900 char * strsep_space( char *string, int * ix)
906 /* Short circuit the trivial case */
907 if ( !string || ! string[*ix])
910 /* Find the end of the token. */
911 while( string && string[*ix] && !isspace(string[*ix]) ) {
915 /* Find the end of any whitespace trailing behind
916 * the token and let that be part of the token */
917 while( string && string[*ix] && isspace(string[*ix]) ) {
921 if (! string && *ix==0) {
922 /* Nothing useful was found */
926 token = xmalloc(*ix+1);
928 strncpy(token, string, *ix);
935 static int expand_arguments(char *command)
937 #ifdef BB_FEATURE_SH_ENVIRONMENT
938 expand_t expand_result;
939 char *src, *dst, *var;
941 int i=0, length, total_length=0, retval;
942 const char *out_of_space = "out of space during expansion";
945 /* get rid of the terminating \n */
948 /* Fix up escape sequences to be the Real Thing(tm) */
949 while( command && command[ix]) {
950 if (command[ix] == '\\') {
951 const char *tmp = command+ix+1;
952 command[ix] = process_escape_sequence( &tmp );
953 memmove(command+ix + 1, tmp, strlen(tmp)+1);
958 #ifdef BB_FEATURE_SH_ENVIRONMENT
961 #ifdef BB_FEATURE_SH_WORDEXP
962 /* This first part uses wordexp() which is a wonderful C lib
963 * function which expands nearly everything. */
964 retval = wordexp (command, &expand_result, WRDE_SHOWERR);
965 if (retval == WRDE_NOSPACE) {
966 /* Mem may have been allocated... */
967 wordfree (&expand_result);
968 error_msg(out_of_space);
972 /* Some other error. */
973 error_msg("syntax error");
977 if (expand_result.we_wordc > 0) {
978 /* Convert from char** (one word per string) to a simple char*,
979 * but don't overflow command which is BUFSIZ in length */
981 while (i < expand_result.we_wordc && total_length < BUFSIZ) {
982 length=strlen(expand_result.we_wordv[i])+1;
983 if (BUFSIZ-total_length-length <= 0) {
984 error_msg(out_of_space);
987 strcat(command+total_length, expand_result.we_wordv[i++]);
988 strcat(command+total_length, " ");
989 total_length+=length;
991 wordfree (&expand_result);
995 /* Ok. They don't have a recent glibc and they don't have uClibc. Chances
996 * are about 100% they don't have wordexp(). So instead the best we can do
997 * is use glob and then fixup environment variables and such ourselves.
998 * This is better then nothing, but certainly not perfect */
1000 /* It turns out that glob is very stupid. We have to feed it one word at a
1001 * time since it can't cope with a full string. Here we convert command
1002 * (char*) into cmd (char**, one word per string) */
1005 int flags = GLOB_NOCHECK
1013 char *tmpcmd, *cmd, *cmd_copy;
1014 /* We need a clean copy, so strsep can mess up the copy while
1015 * we write stuff into the original (in a minute) */
1016 cmd = cmd_copy = strdup(command);
1018 for (ix = 0, tmpcmd = cmd;
1019 (tmpcmd = strsep_space(cmd, &ix)) != NULL; cmd += ix, ix=0) {
1020 if (*tmpcmd == '\0')
1022 /* we need to trim() the result for glob! */
1024 retval = glob(tmpcmd, flags, NULL, &expand_result);
1025 free(tmpcmd); /* Free mem allocated by strsep_space */
1026 if (retval == GLOB_NOSPACE) {
1027 /* Mem may have been allocated... */
1028 globfree (&expand_result);
1029 error_msg(out_of_space);
1031 } else if (retval != 0) {
1032 /* Some other error. GLOB_NOMATCH shouldn't
1033 * happen because of the GLOB_NOCHECK flag in
1035 error_msg("syntax error");
1038 /* Convert from char** (one word per string) to a simple char*,
1039 * but don't overflow command which is BUFSIZ in length */
1040 for (i=0; i < expand_result.gl_pathc; i++) {
1041 length=strlen(expand_result.gl_pathv[i]);
1042 if (total_length+length+1 >= BUFSIZ) {
1043 error_msg(out_of_space);
1046 strcat(command+total_length, " ");
1048 strcat(command+total_length, expand_result.gl_pathv[i]);
1049 total_length+=length;
1051 globfree (&expand_result);
1060 /* Now do the shell variable substitutions which
1061 * wordexp can't do for us, namely $? and $! */
1063 while((dst = strchr(src,'$')) != NULL){
1067 var = itoa(last_return_code);
1070 if (last_bg_pid==-1)
1073 var = itoa(last_bg_pid);
1075 /* Everything else like $$, $#, $[0-9], etc should all be
1076 * expanded by wordexp(), so we can in theory skip that stuff
1077 * here, but just to be on the safe side (i.e. since uClibc
1078 * wordexp doesn't do this stuff yet), lets leave it in for
1081 var = itoa(getpid());
1086 case '0':case '1':case '2':case '3':case '4':
1087 case '5':case '6':case '7':case '8':case '9':
1089 int ixx=*(dst + 1)-48;
1100 /* a single character construction was found, and
1101 * already handled in the case statement */
1104 /* Looks like an environment variable */
1106 int num_skip_chars=0;
1107 int dstlen = strlen(dst);
1108 /* Is this a ${foo} type variable? */
1109 if (dstlen >=2 && *(dst+1) == '{') {
1110 src=strchr(dst+1, '}');
1114 while(isalnum(*src) || *src=='_') src++;
1120 *src='\0'; /* temporary */
1121 var = getenv(dst + 1 + num_skip_chars);
1123 src += num_skip_chars;
1126 /* Seems we got an un-expandable variable. So delete it. */
1130 int subst_len = strlen(var);
1131 int trail_len = strlen(src);
1132 if (dst+subst_len+trail_len >= command+BUFSIZ) {
1133 error_msg(out_of_space);
1136 /* Move stuff to the end of the string to accommodate
1137 * filling the created gap with the new stuff */
1138 memmove(dst+subst_len, src, trail_len+1);
1139 /* Now copy in the new stuff */
1140 memcpy(dst, var, subst_len);
1141 src = dst+subst_len;
1149 /* Return cmd->num_progs as 0 if no command is present (e.g. an empty
1150 line). If a valid command is found, command_ptr is set to point to
1151 the beginning of the next command (if the original command had more
1152 then one job associated with it) or NULL if no more commands are
1154 static int parse_command(char **command_ptr, struct job *job, int *inbg)
1157 char *return_command = NULL;
1158 char *src, *buf, *chptr;
1162 int i, saw_quote = 0;
1165 struct child_prog *prog;
1167 /* skip leading white space */
1168 while (**command_ptr && isspace(**command_ptr))
1171 /* this handles empty lines or leading '#' characters */
1172 if (!**command_ptr || (**command_ptr == '#')) {
1179 job->progs = xmalloc(sizeof(*job->progs));
1181 /* We set the argv elements to point inside of this string. The
1182 memory is freed by free_job(). Allocate twice the original
1183 length in case we need to quote every single character.
1185 Getting clean memory relieves us of the task of NULL
1186 terminating things and makes the rest of this look a bit
1187 cleaner (though it is, admittedly, a tad less efficient) */
1188 job->cmdbuf = command = xcalloc(2*strlen(*command_ptr) + 1, sizeof(char));
1192 prog->num_redirects = 0;
1193 prog->redirects = NULL;
1194 prog->is_stopped = 0;
1198 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1199 prog->argv[0] = job->cmdbuf;
1203 while (*src && !done) {
1204 if (quote == *src) {
1210 error_msg("character expected after \\");
1215 /* in shell, "\'" should yield \' */
1216 if (*src != quote) {
1220 } else if (*src == '*' || *src == '?' || *src == '[' ||
1221 *src == ']') *buf++ = '\\';
1223 } else if (isspace(*src)) {
1224 if (*prog->argv[argc_l] || saw_quote) {
1226 /* +1 here leaves room for the NULL which ends argv */
1227 if ((argc_l + 1) == argv_alloced) {
1229 prog->argv = xrealloc(prog->argv,
1230 sizeof(*prog->argv) *
1233 prog->argv[argc_l] = buf;
1244 case '#': /* comment */
1251 case '>': /* redirects */
1253 i = prog->num_redirects++;
1254 prog->redirects = xrealloc(prog->redirects,
1255 sizeof(*prog->redirects) *
1258 prog->redirects[i].fd = -1;
1259 if (buf != prog->argv[argc_l]) {
1260 /* the stuff before this character may be the file number
1262 prog->redirects[i].fd =
1263 strtol(prog->argv[argc_l], &chptr, 10);
1265 if (*chptr && *prog->argv[argc_l]) {
1267 prog->argv[argc_l] = buf;
1271 if (prog->redirects[i].fd == -1) {
1273 prog->redirects[i].fd = 1;
1275 prog->redirects[i].fd = 0;
1278 if (*src++ == '>') {
1280 prog->redirects[i].type =
1281 REDIRECT_APPEND, src++;
1283 prog->redirects[i].type = REDIRECT_OVERWRITE;
1285 prog->redirects[i].type = REDIRECT_INPUT;
1288 /* This isn't POSIX sh compliant. Oh well. */
1290 while (isspace(*chptr))
1294 error_msg("file name expected after %c", *(src-1));
1300 prog->redirects[i].filename = buf;
1301 while (*chptr && !isspace(*chptr))
1304 src = chptr - 1; /* we src++ later */
1305 prog->argv[argc_l] = ++buf;
1308 case '|': /* pipe */
1309 /* finish this command */
1310 if (*prog->argv[argc_l] || saw_quote)
1313 error_msg("empty command in pipe");
1318 prog->argv[argc_l] = NULL;
1320 /* and start the next */
1322 job->progs = xrealloc(job->progs,
1323 sizeof(*job->progs) * job->num_progs);
1324 prog = job->progs + (job->num_progs - 1);
1325 prog->num_redirects = 0;
1326 prog->redirects = NULL;
1327 prog->is_stopped = 0;
1332 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1333 prog->argv[0] = ++buf;
1336 while (*src && isspace(*src))
1340 error_msg("empty command in pipe");
1345 src--; /* we'll ++ it at the end of the loop */
1349 case '&': /* background */
1351 case ';': /* multiple commands */
1353 return_command = *command_ptr + (src - *command_ptr) + 1;
1356 #ifdef BB_FEATURE_SH_BACKTICKS
1358 /* Exec a backtick-ed command */
1359 /* Besides any previous brokenness, I have not
1360 * updated backtick handling for close_me support.
1361 * I don't know if it needs it or not. -- LRD */
1363 char* charptr1=NULL, *charptr2;
1366 struct jobset njob_list = { NULL, NULL };
1370 ptr=strchr(++src, '`');
1372 fprintf(stderr, "Unmatched '`' in command\n");
1377 /* Make some space to hold just the backticked command */
1378 charptr1 = charptr2 = xmalloc(1+ptr-src);
1379 memcpy(charptr1, src, ptr-src);
1380 charptr1[ptr-src] = '\0';
1381 newjob = xmalloc(sizeof(struct job));
1382 newjob->job_list = &njob_list;
1383 /* Now parse and run the backticked command */
1384 if (!parse_command(&charptr1, newjob, inbg)
1385 && newjob->num_progs) {
1387 run_command(newjob, 0, pipefd);
1389 checkjobs(job->job_list);
1390 free_job(newjob); /* doesn't actually free newjob,
1391 looks like a memory leak */
1394 /* Make a copy of any stuff left over in the command
1395 * line after the second backtick */
1396 charptr2 = xmalloc(strlen(ptr)+1);
1397 memcpy(charptr2, ptr+1, strlen(ptr));
1400 /* Copy the output from the backtick-ed command into the
1401 * command line, making extra room as needed */
1403 charptr1 = xmalloc(BUFSIZ);
1404 while ( (size=full_read(pipefd[0], charptr1, BUFSIZ-1)) >0) {
1405 int newsize=src - *command_ptr + size + 1 + strlen(charptr2);
1406 if (newsize > BUFSIZ) {
1407 *command_ptr=xrealloc(*command_ptr, newsize);
1409 memcpy(src, charptr1, size);
1417 /* Now paste into the *command_ptr all the stuff
1418 * leftover after the second backtick */
1419 memcpy(src, charptr2, strlen(charptr2)+1);
1422 /* Now recursively call parse_command to deal with the new
1423 * and improved version of the command line with the backtick
1424 * results expanded in place... */
1426 struct jobset *jl=job->job_list;
1430 return(parse_command(command_ptr, job, inbg));
1433 #endif // BB_FEATURE_SH_BACKTICKS
1438 /* This is currently a little broken... */
1439 #ifdef HANDLE_CONTINUATION_CHARS
1440 /* They fed us a continuation char, so continue reading stuff
1441 * on the next line, then tack that onto the end of the current
1445 printf("erik: found a continue char at EOL...\n");
1446 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1447 if (get_command(input, command)) {
1448 error_msg("character expected after \\");
1453 newsize = strlen(*command_ptr) + strlen(command) + 2;
1454 if (newsize > BUFSIZ) {
1455 printf("erik: doing realloc\n");
1456 *command_ptr=xrealloc(*command_ptr, newsize);
1458 printf("erik: A: *command_ptr='%s'\n", *command_ptr);
1459 memcpy(--src, command, strlen(command));
1460 printf("erik: B: *command_ptr='%s'\n", *command_ptr);
1464 error_msg("character expected after \\");
1469 if (*src == '*' || *src == '[' || *src == ']'
1470 || *src == '?') *buf++ = '\\';
1479 if (*prog->argv[argc_l] || saw_quote) {
1486 prog->argv[argc_l] = NULL;
1488 if (!return_command) {
1489 job->text = xmalloc(strlen(*command_ptr) + 1);
1490 strcpy(job->text, *command_ptr);
1492 /* This leaves any trailing spaces, which is a bit sloppy */
1493 count = return_command - *command_ptr;
1494 job->text = xmalloc(count + 1);
1495 strncpy(job->text, *command_ptr, count);
1496 job->text[count] = '\0';
1499 *command_ptr = return_command;
1504 /* Run the child_prog, no matter what kind of command it uses.
1506 static int pseudo_exec(struct child_prog *child)
1508 struct built_in_command *x;
1509 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
1513 /* Check if the command matches any of the non-forking builtins.
1514 * Depending on context, this might be redundant. But it's
1515 * easier to waste a few CPU cycles than it is to figure out
1516 * if this is one of those cases.
1518 for (x = bltins; x->cmd; x++) {
1519 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1520 exit(x->function(child));
1524 /* Check if the command matches any of the forking builtins. */
1525 for (x = bltins_forking; x->cmd; x++) {
1526 if (strcmp(child->argv[0], x->cmd) == 0) {
1528 exit (x->function(child));
1531 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
1532 /* Check if the command matches any busybox internal
1533 * commands ("applets") here. Following discussions from
1534 * November 2000 on busybox@opensource.lineo.com, don't use
1535 * get_last_path_component(). This way explicit (with
1536 * slashes) filenames will never be interpreted as an
1537 * applet, just like with builtins. This way the user can
1538 * override an applet with an explicit filename reference.
1539 * The only downside to this change is that an explicit
1540 * /bin/foo invocation will fork and exec /bin/foo, even if
1541 * /bin/foo is a symlink to busybox.
1543 name = child->argv[0];
1545 #ifdef BB_FEATURE_SH_APPLETS_ALWAYS_WIN
1546 /* If you enable BB_FEATURE_SH_APPLETS_ALWAYS_WIN, then
1547 * if you run /bin/cat, it will use BusyBox cat even if
1548 * /bin/cat exists on the filesystem and is _not_ busybox.
1549 * Some systems want this, others do not. Choose wisely. :-)
1551 name = get_last_path_component(name);
1555 char** argv_l=child->argv;
1557 for(argc_l=0;*argv_l!=NULL; argv_l++, argc_l++);
1559 run_applet_by_name(name, argc_l, child->argv);
1563 execvp(child->argv[0], child->argv);
1564 perror_msg_and_die("%s", child->argv[0]);
1567 static void insert_job(struct job *newjob, int inbg)
1570 struct jobset *j_list=newjob->job_list;
1572 /* find the ID for thejob to use */
1574 for (thejob = j_list->head; thejob; thejob = thejob->next)
1575 if (thejob->jobid >= newjob->jobid)
1576 newjob->jobid = thejob->jobid + 1;
1578 /* add thejob to the list of running jobs */
1579 if (!j_list->head) {
1580 thejob = j_list->head = xmalloc(sizeof(*thejob));
1582 for (thejob = j_list->head; thejob->next; thejob = thejob->next) /* nothing */;
1583 thejob->next = xmalloc(sizeof(*thejob));
1584 thejob = thejob->next;
1587 *thejob = *newjob; /* physically copy the struct job */
1588 thejob->next = NULL;
1589 thejob->running_progs = thejob->num_progs;
1590 thejob->stopped_progs = 0;
1593 /* we don't wait for background thejobs to return -- append it
1594 to the list of backgrounded thejobs and leave it alone */
1595 printf("[%d] %d\n", thejob->jobid,
1596 newjob->progs[newjob->num_progs - 1].pid);
1597 #ifdef BB_FEATURE_SH_ENVIRONMENT
1598 last_bg_pid=newjob->progs[newjob->num_progs - 1].pid;
1601 newjob->job_list->fg = thejob;
1603 /* move the new process group into the foreground */
1604 /* suppress messages when run from /linuxrc mag@sysgo.de */
1605 if (tcsetpgrp(0, newjob->pgrp) && errno != ENOTTY)
1606 perror_msg("tcsetpgrp");
1610 static int run_command(struct job *newjob, int inbg, int outpipe[2])
1612 /* struct job *thejob; */
1614 int nextin, nextout;
1615 int pipefds[2]; /* pipefd[0] is for reading */
1616 struct built_in_command *x;
1617 struct child_prog *child;
1619 nextin = 0, nextout = 1;
1620 for (i = 0; i < newjob->num_progs; i++) {
1621 child = & (newjob->progs[i]);
1623 if ((i + 1) < newjob->num_progs) {
1624 if (pipe(pipefds)<0) perror_msg_and_die("pipe");
1625 nextout = pipefds[1];
1627 if (outpipe[1]!=-1) {
1628 nextout = outpipe[1];
1634 #ifdef BB_FEATURE_SH_ENVIRONMENT
1635 if (show_x_trace==TRUE) {
1638 for (j = 0; child->argv[j]; j++) {
1640 fputs(child->argv[j], stderr);
1642 fputc('\n', stderr);
1646 /* Check if the command matches any non-forking builtins,
1647 * but only if this is a simple command.
1648 * Non-forking builtins within pipes have to fork anyway,
1649 * and are handled in pseudo_exec. "echo foo | read bar"
1650 * is doomed to failure, and doesn't work on bash, either.
1652 if (newjob->num_progs == 1) {
1653 for (x = bltins; x->cmd; x++) {
1654 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1655 int squirrel[] = {-1, -1, -1};
1657 setup_redirects(child, squirrel);
1658 rcode = x->function(child);
1659 restore_redirects(squirrel);
1665 if (!(child->pid = fork())) {
1666 signal(SIGTTOU, SIG_DFL);
1670 if (outpipe[1]!=-1) {
1680 dup2(nextout, 2); /* Really? */
1685 /* explicit redirects override pipes */
1686 setup_redirects(child,NULL);
1690 if (outpipe[1]!=-1) {
1694 /* put our child in the process group whose leader is the
1695 first process in this pipe */
1696 setpgid(child->pid, newjob->progs[0].pid);
1702 /* If there isn't another process, nextin is garbage
1703 but it doesn't matter */
1704 nextin = pipefds[0];
1707 newjob->pgrp = newjob->progs[0].pid;
1709 insert_job(newjob, inbg);
1714 static int busy_loop(FILE * input)
1717 char *next_command = NULL;
1723 newjob.job_list = &job_list;
1724 newjob.job_context = DEFAULT_CONTEXT;
1726 /* save current owner of TTY so we can restore it on exit */
1727 parent_pgrp = tcgetpgrp(0);
1729 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1731 /* don't pay any attention to this signal; it just confuses
1732 things and isn't really meant for shells anyway */
1733 signal(SIGTTOU, SIG_IGN);
1737 /* no job is in the foreground */
1739 /* see if any background processes have exited */
1740 checkjobs(&job_list);
1742 if (!next_command) {
1743 if (get_command(input, command))
1745 next_command = command;
1748 if (expand_arguments(next_command) == FALSE) {
1750 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1751 next_command = NULL;
1755 if (!parse_command(&next_command, &newjob, &inbg) &&
1757 int pipefds[2] = {-1,-1};
1758 debug_printf( "job=%p fed to run_command by busy_loop()'\n",
1760 run_command(&newjob, inbg, pipefds);
1764 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1765 next_command = NULL;
1768 /* a job is running in the foreground; wait for it */
1770 while (!job_list.fg->progs[i].pid ||
1771 job_list.fg->progs[i].is_stopped == 1) i++;
1773 if (waitpid(job_list.fg->progs[i].pid, &status, WUNTRACED)<0)
1774 perror_msg_and_die("waitpid(%d)",job_list.fg->progs[i].pid);
1776 if (WIFEXITED(status) || WIFSIGNALED(status)) {
1777 /* the child exited */
1778 job_list.fg->running_progs--;
1779 job_list.fg->progs[i].pid = 0;
1781 #ifdef BB_FEATURE_SH_ENVIRONMENT
1782 last_return_code=WEXITSTATUS(status);
1783 debug_printf("'%s' exited -- return code %d\n",
1784 job_list.fg->text, last_return_code);
1786 if (!job_list.fg->running_progs) {
1788 remove_job(&job_list, job_list.fg);
1792 /* the child was stopped */
1793 job_list.fg->stopped_progs++;
1794 job_list.fg->progs[i].is_stopped = 1;
1796 if (job_list.fg->stopped_progs == job_list.fg->running_progs) {
1797 printf("\n" JOB_STATUS_FORMAT, job_list.fg->jobid,
1798 "Stopped", job_list.fg->text);
1804 /* move the shell to the foreground */
1805 /* suppress messages when run from /linuxrc mag@sysgo.de */
1806 if (tcsetpgrp(0, getpgrp()) && errno != ENOTTY)
1807 perror_msg("tcsetpgrp");
1813 /* return controlling TTY back to parent process group before exiting */
1814 if (tcsetpgrp(0, parent_pgrp))
1815 perror_msg("tcsetpgrp");
1817 /* return exit status if called with "-c" */
1818 if (input == NULL && WIFEXITED(status))
1819 return WEXITSTATUS(status);
1825 #ifdef BB_FEATURE_CLEAN_UP
1826 void free_memory(void)
1832 if (local_pending_command)
1833 free(local_pending_command);
1835 if (job_list.fg && !job_list.fg->running_progs) {
1836 remove_job(&job_list, job_list.fg);
1842 int shell_main(int argc_l, char **argv_l)
1844 int opt, interactive=FALSE;
1845 FILE *input = stdin;
1849 /* These variables need re-initializing when recursing */
1851 local_pending_command = NULL;
1852 close_me_head = NULL;
1853 job_list.head = NULL;
1855 #ifdef BB_FEATURE_SH_ENVIRONMENT
1861 if (argv[0] && argv[0][0] == '-') {
1863 prof_input = fopen("/etc/profile", "r");
1865 printf( "Couldn't open file '/etc/profile'\n");
1867 int tmp_fd = fileno(prof_input);
1869 /* Now run the file */
1870 busy_loop(prof_input);
1872 mark_closed(tmp_fd);
1876 while ((opt = getopt(argc_l, argv_l, "cxi")) > 0) {
1880 if (local_pending_command != 0)
1881 error_msg_and_die("multiple -c arguments");
1882 local_pending_command = xstrdup(argv[optind]);
1886 #ifdef BB_FEATURE_SH_ENVIRONMENT
1888 show_x_trace = TRUE;
1898 /* A shell is interactive if the `-i' flag was given, or if all of
1899 * the following conditions are met:
1901 * no arguments remaining or the -s flag given
1902 * standard input is a terminal
1903 * standard output is a terminal
1904 * Refer to Posix.2, the description of the `sh' utility. */
1905 if (argv[optind]==NULL && input==stdin &&
1906 isatty(fileno(stdin)) && isatty(fileno(stdout))) {
1909 if (interactive==TRUE) {
1910 //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
1911 /* Looks like they want an interactive shell */
1912 printf( "\n\n" BB_BANNER " Built-in shell (lash)\n");
1913 printf( "Enter 'help' for a list of built-in commands.\n\n");
1914 } else if (local_pending_command==NULL) {
1915 //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
1916 input = xfopen(argv[optind], "r");
1917 mark_open(fileno(input)); /* be lazy, never mark this closed */
1920 /* initialize the cwd -- this is never freed...*/
1923 #ifdef BB_FEATURE_CLEAN_UP
1924 atexit(free_memory);
1927 #ifdef BB_FEATURE_COMMAND_EDITING
1928 cmdedit_set_initial_prompt();
1933 return (busy_loop(input));