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_env(struct child_prog *dummy);
147 static int builtin_exec(struct child_prog *cmd);
148 static int builtin_exit(struct child_prog *cmd);
149 static int builtin_fg_bg(struct child_prog *cmd);
150 static int builtin_help(struct child_prog *cmd);
151 static int builtin_jobs(struct child_prog *dummy);
152 static int builtin_pwd(struct child_prog *dummy);
153 static int builtin_export(struct child_prog *cmd);
154 static int builtin_source(struct child_prog *cmd);
155 static int builtin_unset(struct child_prog *cmd);
156 static int builtin_read(struct child_prog *cmd);
157 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
158 static int builtin_if(struct child_prog *cmd);
159 static int builtin_then(struct child_prog *cmd);
160 static int builtin_else(struct child_prog *cmd);
161 static int builtin_fi(struct child_prog *cmd);
162 /* function prototypes for shell stuff */
163 static int run_command_predicate(char *cmd);
167 /* function prototypes for shell stuff */
168 static void mark_open(int fd);
169 static void mark_closed(int fd);
170 static void close_all(void);
171 static void checkjobs(struct jobset *job_list);
172 static int get_command(FILE * source, char *command);
173 static int parse_command(char **command_ptr, struct job *job, int *inbg);
174 static int run_command(struct job *newjob, int inbg, int outpipe[2]);
175 static int pseudo_exec(struct child_prog *cmd) __attribute__ ((noreturn));
176 static int busy_loop(FILE * input);
179 /* Table of built-in functions (these are non-forking builtins, meaning they
180 * can change global variables in the parent shell process but they will not
181 * work with pipes and redirects; 'unset foo | whatever' will not work) */
182 static struct built_in_command bltins[] = {
183 {"bg", "Resume a job in the background", builtin_fg_bg},
184 {"cd", "Change working directory", builtin_cd},
185 {"exec", "Exec command, replacing this shell with the exec'd process", builtin_exec},
186 {"exit", "Exit from shell()", builtin_exit},
187 {"fg", "Bring job into the foreground", builtin_fg_bg},
188 {"jobs", "Lists the active jobs", builtin_jobs},
189 {"export", "Set environment variable", builtin_export},
190 {"unset", "Unset environment variable", builtin_unset},
191 {"read", "Input environment variable", builtin_read},
192 {".", "Source-in and run commands in a file", builtin_source},
193 /* to do: add ulimit */
194 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
195 {"if", NULL, builtin_if},
196 {"then", NULL, builtin_then},
197 {"else", NULL, builtin_else},
198 {"fi", NULL, builtin_fi},
203 /* Table of forking built-in functions (things that fork cannot change global
204 * variables in the parent process, such as the current working directory) */
205 static struct built_in_command bltins_forking[] = {
206 {"env", "Print all environment variables", builtin_env},
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";
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 ------ ----------------- ---------
260 exec cmd->progs[0] squashed bug: didn't look for applets or forking builtins
262 fg_bg cmd->progs[0], job_list->head, job_list->fg
266 export cmd->progs[0] passes cmd, job_list to builtin_env(), which ignores them
270 if cmd->job_context, cmd->text
271 then cmd->job_context, cmd->text
272 else cmd->job_context, cmd->text
275 The use of cmd->text by if/then/else/fi is hopelessly hacky.
276 Would it work to increment cmd->progs[0]->argv and recurse,
277 somewhat like builtin_exec does?
279 I added "struct job *family;" to struct child_prog,
280 and switched API to builtin_foo(struct child_prog *child);
281 So cmd->text becomes child->family->text
282 cmd->job_context becomes child->family->job_context
283 cmd->progs[0] becomes *child
284 job_list becomes child->family->job_list
287 /* built-in 'cd <path>' handler */
288 static int builtin_cd(struct child_prog *child)
292 if (child->argv[1] == NULL)
293 newdir = getenv("HOME");
295 newdir = child->argv[1];
297 printf("cd: %s: %m\n", newdir);
300 getcwd(cwd, sizeof(char)*MAX_LINE);
305 /* built-in 'env' handler */
306 static int builtin_env(struct child_prog *dummy)
310 for (e = environ; *e; e++) {
316 /* built-in 'exec' handler */
317 static int builtin_exec(struct child_prog *child)
319 if (child->argv[1] == NULL)
320 return EXIT_SUCCESS; /* Really? */
327 /* built-in 'exit' handler */
328 static int builtin_exit(struct child_prog *child)
330 if (child->argv[1] == NULL)
333 exit (atoi(child->argv[1]));
336 /* built-in 'fg' and 'bg' handler */
337 static int builtin_fg_bg(struct child_prog *child)
340 struct job *job=NULL;
342 if (!child->argv[1] || child->argv[2]) {
343 error_msg("%s: exactly one argument is expected",
348 if (sscanf(child->argv[1], "%%%d", &jobNum) != 1) {
349 error_msg("%s: bad argument '%s'",
350 child->argv[0], child->argv[1]);
354 for (job = child->family->job_list->head; job; job = job->next) {
355 if (job->jobid == jobNum) {
361 error_msg("%s: unknown job %d",
362 child->argv[0], jobNum);
366 if (*child->argv[0] == 'f') {
367 /* Make this job the foreground job */
368 /* suppress messages when run from /linuxrc mag@sysgo.de */
369 if (tcsetpgrp(0, job->pgrp) && errno != ENOTTY)
370 perror_msg("tcsetpgrp");
371 child->family->job_list->fg = job;
374 /* Restart the processes in the job */
375 for (i = 0; i < job->num_progs; i++)
376 job->progs[i].is_stopped = 0;
378 kill(-job->pgrp, SIGCONT);
380 job->stopped_progs = 0;
385 /* built-in 'help' handler */
386 static int builtin_help(struct child_prog *dummy)
388 struct built_in_command *x;
390 printf("\nBuilt-in commands:\n");
391 printf("-------------------\n");
392 for (x = bltins; x->cmd; x++) {
395 printf("%s\t%s\n", x->cmd, x->descr);
397 for (x = bltins_forking; x->cmd; x++) {
400 printf("%s\t%s\n", x->cmd, x->descr);
406 /* built-in 'jobs' handler */
407 static int builtin_jobs(struct child_prog *child)
412 for (job = child->family->job_list->head; job; job = job->next) {
413 if (job->running_progs == job->stopped_progs)
414 status_string = "Stopped";
416 status_string = "Running";
418 printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->text);
424 /* built-in 'pwd' handler */
425 static int builtin_pwd(struct child_prog *dummy)
427 getcwd(cwd, MAX_LINE);
428 printf( "%s\n", cwd);
432 /* built-in 'export VAR=value' handler */
433 static int builtin_export(struct child_prog *child)
436 char *v = child->argv[1];
439 return (builtin_env(child));
443 fprintf(stderr, "export: %m\n");
444 #ifndef BB_FEATURE_SH_SIMPLE_PROMPT
445 if (strncmp(v, "PS1=", 4)==0)
447 else if (strncmp(v, "PS2=", 4)==0)
450 if(strncmp(v, "LC_ALL=", 7)==0)
451 setlocale(LC_ALL, getenv("LC_ALL"));
452 if(strncmp(v, "LC_CTYPE=", 9)==0)
453 setlocale(LC_CTYPE, getenv("LC_CTYPE"));
458 /* built-in 'read VAR' handler */
459 static int builtin_read(struct child_prog *child)
461 int res = 0, len, newlen;
463 char string[MAX_READ];
465 if (child->argv[1]) {
466 /* argument (VAR) given: put "VAR=" into buffer */
467 strcpy(string, child->argv[1]);
468 len = strlen(string);
471 fgets(&string[len], sizeof(string) - len, stdin); /* read string */
472 newlen = strlen(string);
474 string[--newlen] = '\0'; /* chomp trailing newline */
476 ** string should now contain "VAR=<value>"
477 ** copy it (putenv() won't do that, so we must make sure
478 ** the string resides in a static buffer!)
481 if((s = strdup(string)))
484 fprintf(stderr, "read: %m\n");
487 fgets(string, sizeof(string), stdin);
492 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
493 /* Built-in handler for 'if' commands */
494 static int builtin_if(struct child_prog *child)
496 struct job *cmd = child->family;
498 char* charptr1=cmd->text+3; /* skip over the leading 'if ' */
500 /* Now run the 'if' command */
501 debug_printf( "job=%p entering builtin_if ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
502 status = run_command_predicate(charptr1);
503 debug_printf( "if test returned ");
505 debug_printf( "TRUE\n");
506 cmd->job_context |= IF_TRUE_CONTEXT;
508 debug_printf( "FALSE\n");
509 cmd->job_context |= IF_FALSE_CONTEXT;
511 debug_printf("job=%p builtin_if set job context to %x\n", cmd, cmd->job_context);
517 /* Built-in handler for 'then' (part of the 'if' command) */
518 static int builtin_then(struct child_prog *child)
520 struct job *cmd = child->family;
521 char* charptr1=cmd->text+5; /* skip over the leading 'then ' */
523 debug_printf( "job=%p entering builtin_then ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
524 if (! (cmd->job_context & (IF_TRUE_CONTEXT|IF_FALSE_CONTEXT))) {
525 shell_context = 0; /* Reset the shell's context on an error */
526 error_msg("%s `then'", syntax_err);
530 cmd->job_context |= THEN_EXP_CONTEXT;
531 debug_printf("job=%p builtin_then set job context to %x\n", cmd, cmd->job_context);
533 /* If the if result was FALSE, skip the 'then' stuff */
534 if (cmd->job_context & IF_FALSE_CONTEXT) {
538 /* Seems the if result was TRUE, so run the 'then' command */
539 debug_printf( "'then' now running '%s'\n", charptr1);
541 return(run_command_predicate(charptr1));
544 /* Built-in handler for 'else' (part of the 'if' command) */
545 static int builtin_else(struct child_prog *child)
547 struct job *cmd = child->family;
548 char* charptr1=cmd->text+5; /* skip over the leading 'else ' */
550 debug_printf( "job=%p entering builtin_else ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
552 if (! (cmd->job_context & THEN_EXP_CONTEXT)) {
553 shell_context = 0; /* Reset the shell's context on an error */
554 error_msg("%s `else'", syntax_err);
557 /* If the if result was TRUE, skip the 'else' stuff */
558 if (cmd->job_context & IF_TRUE_CONTEXT) {
562 cmd->job_context |= ELSE_EXP_CONTEXT;
563 debug_printf("job=%p builtin_else set job context to %x\n", cmd, cmd->job_context);
565 /* Now run the 'else' command */
566 debug_printf( "'else' now running '%s'\n", charptr1);
567 return(run_command_predicate(charptr1));
570 /* Built-in handler for 'fi' (part of the 'if' command) */
571 static int builtin_fi(struct child_prog *child)
573 struct job *cmd = child->family;
574 debug_printf( "job=%p entering builtin_fi ('%s')-- context=%d\n", cmd, "", cmd->job_context);
575 if (! (cmd->job_context & (IF_TRUE_CONTEXT|IF_FALSE_CONTEXT))) {
576 shell_context = 0; /* Reset the shell's context on an error */
577 error_msg("%s `fi'", syntax_err);
580 /* Clear out the if and then context bits */
581 cmd->job_context &= ~(IF_TRUE_CONTEXT|IF_FALSE_CONTEXT|THEN_EXP_CONTEXT|ELSE_EXP_CONTEXT);
582 debug_printf("job=%p builtin_fi set job context to %x\n", cmd, cmd->job_context);
588 /* Built-in '.' handler (read-in and execute commands from file) */
589 static int builtin_source(struct child_prog *child)
595 if (child->argv[1] == NULL)
598 input = fopen(child->argv[1], "r");
600 printf( "Couldn't open file '%s'\n", child->argv[1]);
606 /* Now run the file */
607 status = busy_loop(input);
613 /* built-in 'unset VAR' handler */
614 static int builtin_unset(struct child_prog *child)
616 if (child->argv[1] == NULL) {
617 printf( "unset: parameter required.\n");
620 unsetenv(child->argv[1]);
624 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
625 /* currently used by if/then/else.
627 * Reparsing the command line for this purpose is gross,
628 * incorrect, and fundamentally unfixable; in particular,
629 * think about what happens with command substitution.
630 * We really need to pull out the run, wait, return status
631 * functionality out of busy_loop so we can child->argv++
632 * and use that, without going back through parse_command.
634 static int run_command_predicate(char *cmd)
637 local_pending_command = xmalloc(n+1);
638 strncpy(local_pending_command, cmd, n);
639 local_pending_command[n]='\0';
640 return( busy_loop(NULL));
644 static void mark_open(int fd)
646 struct close_me *new = xmalloc(sizeof(struct close_me));
648 new->next = close_me_head;
652 static void mark_closed(int fd)
654 struct close_me *tmp;
655 if (close_me_head == NULL || close_me_head->fd != fd)
656 error_msg_and_die("corrupt close_me");
658 close_me_head = close_me_head->next;
662 static void close_all()
664 struct close_me *c, *tmp;
665 for (c=close_me_head; c; c=tmp) {
670 close_me_head = NULL;
674 /* free up all memory from a job */
675 static void free_job(struct job *cmd)
680 for (i = 0; i < cmd->num_progs; i++) {
681 free(cmd->progs[i].argv);
682 if (cmd->progs[i].redirects)
683 free(cmd->progs[i].redirects);
691 keep = cmd->job_list;
692 memset(cmd, 0, sizeof(struct job));
693 cmd->job_list = keep;
696 /* remove a job from a jobset */
697 static void remove_job(struct jobset *j_list, struct job *job)
702 if (job == j_list->head) {
703 j_list->head = job->next;
705 prevjob = j_list->head;
706 while (prevjob->next != job)
707 prevjob = prevjob->next;
708 prevjob->next = job->next;
714 /* Checks to see if any background processes have exited -- if they
715 have, figure out why and see if a job has completed */
716 static void checkjobs(struct jobset *j_list)
723 while ((childpid = waitpid(-1, &status, WNOHANG | WUNTRACED)) > 0) {
724 for (job = j_list->head; job; job = job->next) {
726 while (prognum < job->num_progs &&
727 job->progs[prognum].pid != childpid) prognum++;
728 if (prognum < job->num_progs)
732 /* This happens on backticked commands */
736 if (WIFEXITED(status) || WIFSIGNALED(status)) {
738 job->running_progs--;
739 job->progs[prognum].pid = 0;
741 if (!job->running_progs) {
742 printf(JOB_STATUS_FORMAT, job->jobid, "Done", job->text);
743 remove_job(j_list, job);
747 job->stopped_progs++;
748 job->progs[prognum].is_stopped = 1;
750 if (job->stopped_progs == job->num_progs) {
751 printf(JOB_STATUS_FORMAT, job->jobid, "Stopped",
757 if (childpid == -1 && errno != ECHILD)
758 perror_msg("waitpid");
761 /* squirrel != NULL means we squirrel away copies of stdin, stdout,
762 * and stderr if they are redirected. */
763 static int setup_redirects(struct child_prog *prog, int squirrel[])
768 struct redir_struct *redir = prog->redirects;
770 for (i = 0; i < prog->num_redirects; i++, redir++) {
771 switch (redir->type) {
775 case REDIRECT_OVERWRITE:
776 mode = O_WRONLY | O_CREAT | O_TRUNC;
778 case REDIRECT_APPEND:
779 mode = O_WRONLY | O_CREAT | O_APPEND;
783 openfd = open(redir->filename, mode, 0666);
785 /* this could get lost if stderr has been redirected, but
786 bash and ash both lose it as well (though zsh doesn't!) */
787 perror_msg("error opening %s", redir->filename);
791 if (openfd != redir->fd) {
792 if (squirrel && redir->fd < 3) {
793 squirrel[redir->fd] = dup(redir->fd);
795 dup2(openfd, redir->fd);
803 static void restore_redirects(int squirrel[])
806 for (i=0; i<3; i++) {
809 /* No error checking. I sure wouldn't know what
810 * to do with an error if I found one! */
817 static inline void cmdedit_set_initial_prompt(void)
819 #ifdef BB_FEATURE_SH_SIMPLE_PROMPT
833 static inline void setup_prompt_string(char **prompt_str)
835 #ifdef BB_FEATURE_SH_SIMPLE_PROMPT
836 /* Set up the prompt */
837 if (shell_context == 0) {
840 PS1=xmalloc(strlen(cwd)+4);
841 sprintf(PS1, "%s %s", cwd, ( geteuid() != 0 ) ? "$ ":"# ");
847 *prompt_str = (shell_context==0)? PS1 : PS2;
851 static int get_command(FILE * source, char *command)
855 if (source == NULL) {
856 if (local_pending_command) {
857 /* a command specified (-c option): return it & mark it done */
858 strcpy(command, local_pending_command);
859 free(local_pending_command);
860 local_pending_command = NULL;
866 if (source == stdin) {
867 setup_prompt_string(&prompt_str);
869 #ifdef BB_FEATURE_COMMAND_EDITING
871 ** enable command line editing only while a command line
872 ** is actually being read; otherwise, we'll end up bequeathing
873 ** atexit() handlers and other unwanted stuff to our
874 ** child processes (rob@sysgo.de)
876 cmdedit_read_input(prompt_str, command);
880 fputs(prompt_str, stdout);
884 if (!fgets(command, BUFSIZ - 2, source)) {
893 #ifdef BB_FEATURE_SH_ENVIRONMENT
894 static char* itoa(register int i)
896 static char a[7]; /* Max 7 ints */
897 register char *b = a + sizeof(a) - 1;
905 *--b = '0' + (i % 10);
915 #if defined BB_FEATURE_SH_ENVIRONMENT && ! defined BB_FEATURE_SH_WORDEXP
916 char * strsep_space( char *string, int * ix)
922 /* Short circuit the trivial case */
923 if ( !string || ! string[*ix])
926 /* Find the end of the token. */
927 while( string && string[*ix] && !isspace(string[*ix]) ) {
931 /* Find the end of any whitespace trailing behind
932 * the token and let that be part of the token */
933 while( string && string[*ix] && isspace(string[*ix]) ) {
937 if (! string && *ix==0) {
938 /* Nothing useful was found */
942 token = xmalloc(*ix+1);
944 strncpy(token, string, *ix);
951 static int expand_arguments(char *command)
953 #ifdef BB_FEATURE_SH_ENVIRONMENT
954 expand_t expand_result;
955 char *src, *dst, *var;
957 int i=0, length, total_length=0, retval;
958 const char *out_of_space = "out of space during expansion";
961 /* get rid of the terminating \n */
964 /* Fix up escape sequences to be the Real Thing(tm) */
965 while( command && command[ix]) {
966 if (command[ix] == '\\') {
967 char *tmp = command+ix+1;
968 command[ix] = process_escape_sequence( &tmp );
969 memmove(command+ix + 1, tmp, strlen(tmp)+1);
974 #ifdef BB_FEATURE_SH_ENVIRONMENT
977 #ifdef BB_FEATURE_SH_WORDEXP
978 /* This first part uses wordexp() which is a wonderful C lib
979 * function which expands nearly everything. */
980 retval = wordexp (command, &expand_result, WRDE_SHOWERR);
981 if (retval == WRDE_NOSPACE) {
982 /* Mem may have been allocated... */
983 wordfree (&expand_result);
984 error_msg(out_of_space);
988 /* Some other error. */
989 error_msg("syntax error");
993 if (expand_result.we_wordc > 0) {
994 /* Convert from char** (one word per string) to a simple char*,
995 * but don't overflow command which is BUFSIZ in length */
997 while (i < expand_result.we_wordc && total_length < BUFSIZ) {
998 length=strlen(expand_result.we_wordv[i])+1;
999 if (BUFSIZ-total_length-length <= 0) {
1000 error_msg(out_of_space);
1003 strcat(command+total_length, expand_result.we_wordv[i++]);
1004 strcat(command+total_length, " ");
1005 total_length+=length;
1007 wordfree (&expand_result);
1011 /* Ok. They don't have a recent glibc and they don't have uClibc. Chances
1012 * are about 100% they don't have wordexp(). So instead the best we can do
1013 * is use glob and then fixup environment variables and such ourselves.
1014 * This is better then nothing, but certainly not perfect */
1016 /* It turns out that glob is very stupid. We have to feed it one word at a
1017 * time since it can't cope with a full string. Here we convert command
1018 * (char*) into cmd (char**, one word per string) */
1021 int flags = GLOB_NOCHECK
1029 char *tmpcmd, *cmd, *cmd_copy;
1030 /* We need a clean copy, so strsep can mess up the copy while
1031 * we write stuff into the original (in a minute) */
1032 cmd = cmd_copy = strdup(command);
1034 for (ix = 0, tmpcmd = cmd;
1035 (tmpcmd = strsep_space(cmd, &ix)) != NULL; cmd += ix, ix=0) {
1036 if (*tmpcmd == '\0')
1038 retval = glob(tmpcmd, flags, NULL, &expand_result);
1039 free(tmpcmd); /* Free mem allocated by strsep_space */
1040 if (retval == GLOB_NOSPACE) {
1041 /* Mem may have been allocated... */
1042 globfree (&expand_result);
1043 error_msg(out_of_space);
1045 } else if (retval != 0) {
1046 /* Some other error. GLOB_NOMATCH shouldn't
1047 * happen because of the GLOB_NOCHECK flag in
1049 error_msg("syntax error");
1052 /* Convert from char** (one word per string) to a simple char*,
1053 * but don't overflow command which is BUFSIZ in length */
1054 for (i=0; i < expand_result.gl_pathc; i++) {
1055 length=strlen(expand_result.gl_pathv[i]);
1056 if (total_length+length+1 >= BUFSIZ) {
1057 error_msg(out_of_space);
1061 strcat(command+total_length, " ");
1064 strcat(command+total_length, expand_result.gl_pathv[i]);
1065 total_length+=length;
1067 globfree (&expand_result);
1076 /* Now do the shell variable substitutions which
1077 * wordexp can't do for us, namely $? and $! */
1079 while((dst = strchr(src,'$')) != NULL){
1083 var = itoa(last_return_code);
1086 if (last_bg_pid==-1)
1089 var = itoa(last_bg_pid);
1091 /* Everything else like $$, $#, $[0-9], etc should all be
1092 * expanded by wordexp(), so we can in theory skip that stuff
1093 * here, but just to be on the safe side (i.e. since uClibc
1094 * wordexp doesn't do this stuff yet), lets leave it in for
1097 var = itoa(getpid());
1102 case '0':case '1':case '2':case '3':case '4':
1103 case '5':case '6':case '7':case '8':case '9':
1105 int ixx=*(dst + 1)-48;
1116 /* a single character construction was found, and
1117 * already handled in the case statement */
1120 /* Looks like an environment variable */
1122 int num_skip_chars=0;
1123 int dstlen = strlen(dst);
1124 /* Is this a ${foo} type variable? */
1125 if (dstlen >=2 && *(dst+1) == '{') {
1126 src=strchr(dst+1, '}');
1130 while(isalnum(*src) || *src=='_') src++;
1136 *src='\0'; /* temporary */
1137 var = getenv(dst + 1 + num_skip_chars);
1139 src += num_skip_chars;
1142 /* Seems we got an un-expandable variable. So delete it. */
1146 int subst_len = strlen(var);
1147 int trail_len = strlen(src);
1148 if (dst+subst_len+trail_len >= command+BUFSIZ) {
1149 error_msg(out_of_space);
1152 /* Move stuff to the end of the string to accommodate
1153 * filling the created gap with the new stuff */
1154 memmove(dst+subst_len, src, trail_len+1);
1155 /* Now copy in the new stuff */
1156 memcpy(dst, var, subst_len);
1157 src = dst+subst_len;
1165 /* Return cmd->num_progs as 0 if no command is present (e.g. an empty
1166 line). If a valid command is found, command_ptr is set to point to
1167 the beginning of the next command (if the original command had more
1168 then one job associated with it) or NULL if no more commands are
1170 static int parse_command(char **command_ptr, struct job *job, int *inbg)
1173 char *return_command = NULL;
1174 char *src, *buf, *chptr;
1181 struct child_prog *prog;
1183 /* skip leading white space */
1184 while (**command_ptr && isspace(**command_ptr))
1187 /* this handles empty lines or leading '#' characters */
1188 if (!**command_ptr || (**command_ptr == '#')) {
1195 job->progs = xmalloc(sizeof(*job->progs));
1197 /* We set the argv elements to point inside of this string. The
1198 memory is freed by free_job(). Allocate twice the original
1199 length in case we need to quote every single character.
1201 Getting clean memory relieves us of the task of NULL
1202 terminating things and makes the rest of this look a bit
1203 cleaner (though it is, admittedly, a tad less efficient) */
1204 job->cmdbuf = command = xcalloc(2*strlen(*command_ptr) + 1, sizeof(char));
1208 prog->num_redirects = 0;
1209 prog->redirects = NULL;
1210 prog->is_stopped = 0;
1214 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1215 prog->argv[0] = job->cmdbuf;
1219 while (*src && !done) {
1220 if (quote == *src) {
1226 error_msg("character expected after \\");
1231 /* in shell, "\'" should yield \' */
1232 if (*src != quote) {
1236 } else if (*src == '*' || *src == '?' || *src == '[' ||
1237 *src == ']') *buf++ = '\\';
1239 } else if (isspace(*src)) {
1240 if (*prog->argv[argc_l]) {
1242 /* +1 here leaves room for the NULL which ends argv */
1243 if ((argc_l + 1) == argv_alloced) {
1245 prog->argv = xrealloc(prog->argv,
1246 sizeof(*prog->argv) *
1249 prog->argv[argc_l] = buf;
1258 case '#': /* comment */
1265 case '>': /* redirects */
1267 i = prog->num_redirects++;
1268 prog->redirects = xrealloc(prog->redirects,
1269 sizeof(*prog->redirects) *
1272 prog->redirects[i].fd = -1;
1273 if (buf != prog->argv[argc_l]) {
1274 /* the stuff before this character may be the file number
1276 prog->redirects[i].fd =
1277 strtol(prog->argv[argc_l], &chptr, 10);
1279 if (*chptr && *prog->argv[argc_l]) {
1281 prog->argv[argc_l] = buf;
1285 if (prog->redirects[i].fd == -1) {
1287 prog->redirects[i].fd = 1;
1289 prog->redirects[i].fd = 0;
1292 if (*src++ == '>') {
1294 prog->redirects[i].type =
1295 REDIRECT_APPEND, src++;
1297 prog->redirects[i].type = REDIRECT_OVERWRITE;
1299 prog->redirects[i].type = REDIRECT_INPUT;
1302 /* This isn't POSIX sh compliant. Oh well. */
1304 while (isspace(*chptr))
1308 error_msg("file name expected after %c", *(src-1));
1314 prog->redirects[i].filename = buf;
1315 while (*chptr && !isspace(*chptr))
1318 src = chptr - 1; /* we src++ later */
1319 prog->argv[argc_l] = ++buf;
1322 case '|': /* pipe */
1323 /* finish this command */
1324 if (*prog->argv[argc_l])
1327 error_msg("empty command in pipe");
1332 prog->argv[argc_l] = NULL;
1334 /* and start the next */
1336 job->progs = xrealloc(job->progs,
1337 sizeof(*job->progs) * job->num_progs);
1338 prog = job->progs + (job->num_progs - 1);
1339 prog->num_redirects = 0;
1340 prog->redirects = NULL;
1341 prog->is_stopped = 0;
1346 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1347 prog->argv[0] = ++buf;
1350 while (*src && isspace(*src))
1354 error_msg("empty command in pipe");
1359 src--; /* we'll ++ it at the end of the loop */
1363 case '&': /* background */
1365 case ';': /* multiple commands */
1367 return_command = *command_ptr + (src - *command_ptr) + 1;
1370 #ifdef BB_FEATURE_SH_BACKTICKS
1372 /* Exec a backtick-ed command */
1373 /* Besides any previous brokenness, I have not
1374 * updated backtick handling for close_me support.
1375 * I don't know if it needs it or not. -- LRD */
1377 char* charptr1=NULL, *charptr2;
1380 struct jobset njob_list = { NULL, NULL };
1384 ptr=strchr(++src, '`');
1386 fprintf(stderr, "Unmatched '`' in command\n");
1391 /* Make some space to hold just the backticked command */
1392 charptr1 = charptr2 = xmalloc(1+ptr-src);
1393 memcpy(charptr1, src, ptr-src);
1394 charptr1[ptr-src] = '\0';
1395 newjob = xmalloc(sizeof(struct job));
1396 newjob->job_list = &njob_list;
1397 /* Now parse and run the backticked command */
1398 if (!parse_command(&charptr1, newjob, inbg)
1399 && newjob->num_progs) {
1401 run_command(newjob, 0, pipefd);
1403 checkjobs(job->job_list);
1404 free_job(newjob); /* doesn't actually free newjob,
1405 looks like a memory leak */
1408 /* Make a copy of any stuff left over in the command
1409 * line after the second backtick */
1410 charptr2 = xmalloc(strlen(ptr)+1);
1411 memcpy(charptr2, ptr+1, strlen(ptr));
1414 /* Copy the output from the backtick-ed command into the
1415 * command line, making extra room as needed */
1417 charptr1 = xmalloc(BUFSIZ);
1418 while ( (size=full_read(pipefd[0], charptr1, BUFSIZ-1)) >0) {
1419 int newsize=src - *command_ptr + size + 1 + strlen(charptr2);
1420 if (newsize > BUFSIZ) {
1421 *command_ptr=xrealloc(*command_ptr, newsize);
1423 memcpy(src, charptr1, size);
1431 /* Now paste into the *command_ptr all the stuff
1432 * leftover after the second backtick */
1433 memcpy(src, charptr2, strlen(charptr2)+1);
1436 /* Now recursively call parse_command to deal with the new
1437 * and improved version of the command line with the backtick
1438 * results expanded in place... */
1440 struct jobset *jl=job->job_list;
1444 return(parse_command(command_ptr, job, inbg));
1447 #endif // BB_FEATURE_SH_BACKTICKS
1452 /* This is currently a little broken... */
1453 #ifdef HANDLE_CONTINUATION_CHARS
1454 /* They fed us a continuation char, so continue reading stuff
1455 * on the next line, then tack that onto the end of the current
1459 printf("erik: found a continue char at EOL...\n");
1460 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1461 if (get_command(input, command)) {
1462 error_msg("character expected after \\");
1467 newsize = strlen(*command_ptr) + strlen(command) + 2;
1468 if (newsize > BUFSIZ) {
1469 printf("erik: doing realloc\n");
1470 *command_ptr=xrealloc(*command_ptr, newsize);
1472 printf("erik: A: *command_ptr='%s'\n", *command_ptr);
1473 memcpy(--src, command, strlen(command));
1474 printf("erik: B: *command_ptr='%s'\n", *command_ptr);
1478 error_msg("character expected after \\");
1483 if (*src == '*' || *src == '[' || *src == ']'
1484 || *src == '?') *buf++ = '\\';
1493 if (*prog->argv[argc_l]) {
1500 prog->argv[argc_l] = NULL;
1502 if (!return_command) {
1503 job->text = xmalloc(strlen(*command_ptr) + 1);
1504 strcpy(job->text, *command_ptr);
1506 /* This leaves any trailing spaces, which is a bit sloppy */
1507 count = return_command - *command_ptr;
1508 job->text = xmalloc(count + 1);
1509 strncpy(job->text, *command_ptr, count);
1510 job->text[count] = '\0';
1513 *command_ptr = return_command;
1518 /* Run the child_prog, no matter what kind of command it uses.
1520 static int pseudo_exec(struct child_prog *child)
1522 struct built_in_command *x;
1523 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
1527 /* Check if the command matches any of the non-forking builtins.
1528 * Depending on context, this might be redundant. But it's
1529 * easier to waste a few CPU cycles than it is to figure out
1530 * if this is one of those cases.
1532 for (x = bltins; x->cmd; x++) {
1533 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1534 exit(x->function(child));
1538 /* Check if the command matches any of the forking builtins. */
1539 for (x = bltins_forking; x->cmd; x++) {
1540 if (strcmp(child->argv[0], x->cmd) == 0) {
1542 exit (x->function(child));
1545 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
1546 /* Check if the command matches any busybox internal
1547 * commands ("applets") here. Following discussions from
1548 * November 2000 on busybox@opensource.lineo.com, don't use
1549 * get_last_path_component(). This way explicit (with
1550 * slashes) filenames will never be interpreted as an
1551 * applet, just like with builtins. This way the user can
1552 * override an applet with an explicit filename reference.
1553 * The only downside to this change is that an explicit
1554 * /bin/foo invocation will fork and exec /bin/foo, even if
1555 * /bin/foo is a symlink to busybox.
1557 name = child->argv[0];
1559 #ifdef BB_FEATURE_SH_APPLETS_ALWAYS_WIN
1560 /* If you enable BB_FEATURE_SH_APPLETS_ALWAYS_WIN, then
1561 * if you run /bin/cat, it will use BusyBox cat even if
1562 * /bin/cat exists on the filesystem and is _not_ busybox.
1563 * Some systems want this, others do not. Choose wisely. :-)
1565 name = get_last_path_component(name);
1569 char** argv_l=child->argv;
1571 for(argc_l=0;*argv_l!=NULL; argv_l++, argc_l++);
1573 run_applet_by_name(name, argc_l, child->argv);
1577 execvp(child->argv[0], child->argv);
1578 perror_msg_and_die("%s", child->argv[0]);
1581 static void insert_job(struct job *newjob, int inbg)
1584 struct jobset *j_list=newjob->job_list;
1586 /* find the ID for thejob to use */
1588 for (thejob = j_list->head; thejob; thejob = thejob->next)
1589 if (thejob->jobid >= newjob->jobid)
1590 newjob->jobid = thejob->jobid + 1;
1592 /* add thejob to the list of running jobs */
1593 if (!j_list->head) {
1594 thejob = j_list->head = xmalloc(sizeof(*thejob));
1596 for (thejob = j_list->head; thejob->next; thejob = thejob->next) /* nothing */;
1597 thejob->next = xmalloc(sizeof(*thejob));
1598 thejob = thejob->next;
1601 *thejob = *newjob; /* physically copy the struct job */
1602 thejob->next = NULL;
1603 thejob->running_progs = thejob->num_progs;
1604 thejob->stopped_progs = 0;
1607 /* we don't wait for background thejobs to return -- append it
1608 to the list of backgrounded thejobs and leave it alone */
1609 printf("[%d] %d\n", thejob->jobid,
1610 newjob->progs[newjob->num_progs - 1].pid);
1611 #ifdef BB_FEATURE_SH_ENVIRONMENT
1612 last_bg_pid=newjob->progs[newjob->num_progs - 1].pid;
1615 newjob->job_list->fg = thejob;
1617 /* move the new process group into the foreground */
1618 /* suppress messages when run from /linuxrc mag@sysgo.de */
1619 if (tcsetpgrp(0, newjob->pgrp) && errno != ENOTTY)
1620 perror_msg("tcsetpgrp");
1624 static int run_command(struct job *newjob, int inbg, int outpipe[2])
1626 /* struct job *thejob; */
1628 int nextin, nextout;
1629 int pipefds[2]; /* pipefd[0] is for reading */
1630 struct built_in_command *x;
1631 struct child_prog *child;
1633 nextin = 0, nextout = 1;
1634 for (i = 0; i < newjob->num_progs; i++) {
1635 child = & (newjob->progs[i]);
1637 if ((i + 1) < newjob->num_progs) {
1638 if (pipe(pipefds)<0) perror_msg_and_die("pipe");
1639 nextout = pipefds[1];
1641 if (outpipe[1]!=-1) {
1642 nextout = outpipe[1];
1648 #ifdef BB_FEATURE_SH_ENVIRONMENT
1649 if (show_x_trace==TRUE) {
1652 for (j = 0; child->argv[j]; j++) {
1654 fputs(child->argv[j], stderr);
1656 fputc('\n', stderr);
1660 /* Check if the command matches any non-forking builtins,
1661 * but only if this is a simple command.
1662 * Non-forking builtins within pipes have to fork anyway,
1663 * and are handled in pseudo_exec. "echo foo | read bar"
1664 * is doomed to failure, and doesn't work on bash, either.
1666 if (newjob->num_progs == 1) {
1667 for (x = bltins; x->cmd; x++) {
1668 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1669 int squirrel[] = {-1, -1, -1};
1671 setup_redirects(child, squirrel);
1672 rcode = x->function(child);
1673 restore_redirects(squirrel);
1679 if (!(child->pid = fork())) {
1680 signal(SIGTTOU, SIG_DFL);
1684 if (outpipe[1]!=-1) {
1694 dup2(nextout, 2); /* Really? */
1699 /* explicit redirects override pipes */
1700 setup_redirects(child,NULL);
1704 if (outpipe[1]!=-1) {
1708 /* put our child in the process group whose leader is the
1709 first process in this pipe */
1710 setpgid(child->pid, newjob->progs[0].pid);
1716 /* If there isn't another process, nextin is garbage
1717 but it doesn't matter */
1718 nextin = pipefds[0];
1721 newjob->pgrp = newjob->progs[0].pid;
1723 insert_job(newjob, inbg);
1728 static int busy_loop(FILE * input)
1731 char *next_command = NULL;
1737 newjob.job_list = &job_list;
1738 newjob.job_context = DEFAULT_CONTEXT;
1740 /* save current owner of TTY so we can restore it on exit */
1741 parent_pgrp = tcgetpgrp(0);
1743 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1745 /* don't pay any attention to this signal; it just confuses
1746 things and isn't really meant for shells anyway */
1747 signal(SIGTTOU, SIG_IGN);
1751 /* no job is in the foreground */
1753 /* see if any background processes have exited */
1754 checkjobs(&job_list);
1756 if (!next_command) {
1757 if (get_command(input, command))
1759 next_command = command;
1762 if (expand_arguments(next_command) == FALSE) {
1764 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1765 next_command = NULL;
1769 if (!parse_command(&next_command, &newjob, &inbg) &&
1771 int pipefds[2] = {-1,-1};
1772 debug_printf( "job=%p fed to run_command by busy_loop()'\n",
1774 run_command(&newjob, inbg, pipefds);
1778 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1779 next_command = NULL;
1782 /* a job is running in the foreground; wait for it */
1784 while (!job_list.fg->progs[i].pid ||
1785 job_list.fg->progs[i].is_stopped == 1) i++;
1787 if (waitpid(job_list.fg->progs[i].pid, &status, WUNTRACED)<0)
1788 perror_msg_and_die("waitpid(%d)",job_list.fg->progs[i].pid);
1790 if (WIFEXITED(status) || WIFSIGNALED(status)) {
1791 /* the child exited */
1792 job_list.fg->running_progs--;
1793 job_list.fg->progs[i].pid = 0;
1795 #ifdef BB_FEATURE_SH_ENVIRONMENT
1796 last_return_code=WEXITSTATUS(status);
1797 debug_printf("'%s' exited -- return code %d\n",
1798 job_list.fg->text, last_return_code);
1800 if (!job_list.fg->running_progs) {
1802 remove_job(&job_list, job_list.fg);
1806 /* the child was stopped */
1807 job_list.fg->stopped_progs++;
1808 job_list.fg->progs[i].is_stopped = 1;
1810 if (job_list.fg->stopped_progs == job_list.fg->running_progs) {
1811 printf("\n" JOB_STATUS_FORMAT, job_list.fg->jobid,
1812 "Stopped", job_list.fg->text);
1818 /* move the shell to the foreground */
1819 /* suppress messages when run from /linuxrc mag@sysgo.de */
1820 if (tcsetpgrp(0, getpid()) && errno != ENOTTY)
1821 perror_msg("tcsetpgrp");
1827 /* return controlling TTY back to parent process group before exiting */
1828 if (tcsetpgrp(0, parent_pgrp))
1829 perror_msg("tcsetpgrp");
1831 /* return exit status if called with "-c" */
1832 if (input == NULL && WIFEXITED(status))
1833 return WEXITSTATUS(status);
1839 #ifdef BB_FEATURE_CLEAN_UP
1840 void free_memory(void)
1844 if (local_pending_command)
1845 free(local_pending_command);
1847 if (job_list.fg && !job_list.fg->running_progs) {
1848 remove_job(&job_list, job_list.fg);
1854 int shell_main(int argc_l, char **argv_l)
1856 int opt, interactive=FALSE;
1857 FILE *input = stdin;
1861 /* These variables need re-initializing when recursing */
1864 local_pending_command = NULL;
1865 close_me_head = NULL;
1866 job_list.head = NULL;
1868 #ifdef BB_FEATURE_SH_ENVIRONMENT
1874 if (argv[0] && argv[0][0] == '-') {
1876 prof_input = fopen("/etc/profile", "r");
1878 printf( "Couldn't open file '/etc/profile'\n");
1880 int tmp_fd = fileno(prof_input);
1882 /* Now run the file */
1883 busy_loop(prof_input);
1885 mark_closed(tmp_fd);
1889 while ((opt = getopt(argc_l, argv_l, "cxi")) > 0) {
1893 if (local_pending_command != 0)
1894 error_msg_and_die("multiple -c arguments");
1895 local_pending_command = xstrdup(argv[optind]);
1899 #ifdef BB_FEATURE_SH_ENVIRONMENT
1901 show_x_trace = TRUE;
1911 /* A shell is interactive if the `-i' flag was given, or if all of
1912 * the following conditions are met:
1914 * no arguments remaining or the -s flag given
1915 * standard input is a terminal
1916 * standard output is a terminal
1917 * Refer to Posix.2, the description of the `sh' utility. */
1918 if (argv[optind]==NULL && input==stdin &&
1919 isatty(fileno(stdin)) && isatty(fileno(stdout))) {
1922 if (interactive==TRUE) {
1923 //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
1924 /* Looks like they want an interactive shell */
1925 printf( "\n\nBusyBox v%s (%s) Built-in shell (lash)\n", BB_VER, BB_BT);
1926 printf( "Enter 'help' for a list of built-in commands.\n\n");
1927 } else if (local_pending_command==NULL) {
1928 //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
1929 input = xfopen(argv[optind], "r");
1930 mark_open(fileno(input)); /* be lazy, never mark this closed */
1933 /* initialize the cwd -- this is never freed...*/
1934 cwd=(char*)xmalloc(sizeof(char)*MAX_LINE+1);
1935 getcwd(cwd, sizeof(char)*MAX_LINE);
1937 #ifdef BB_FEATURE_CLEAN_UP
1938 atexit(free_memory);
1941 #ifdef BB_FEATURE_COMMAND_EDITING
1942 cmdedit_set_initial_prompt();
1948 return (busy_loop(input));