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...
43 #define BB_FEATURE_SH_IF_EXPRESSIONS
45 /* This is currently a little broken... */
46 //#define HANDLE_CONTINUATION_CHARS
48 //For debugging/development on the shell only...
61 #include <sys/ioctl.h>
67 static const int MAX_LINE = 256; /* size of input buffer for cwd data */
68 static const int MAX_READ = 128; /* size of input buffer for `read' builtin */
69 #define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
72 enum redir_type { REDIRECT_INPUT, REDIRECT_OVERWRITE,
76 static const unsigned int DEFAULT_CONTEXT=0x1;
77 static const unsigned int IF_TRUE_CONTEXT=0x2;
78 static const unsigned int IF_FALSE_CONTEXT=0x4;
79 static const unsigned int THEN_EXP_CONTEXT=0x8;
80 static const unsigned int ELSE_EXP_CONTEXT=0x10;
84 struct job *head; /* head of list of running jobs */
85 struct job *fg; /* current foreground job */
89 enum redir_type type; /* type of redirection */
90 int fd; /* file descriptor being redirected */
91 char *filename; /* file to redirect fd to */
95 pid_t pid; /* 0 if exited */
96 char **argv; /* program name and arguments */
97 int num_redirects; /* elements in redirection array */
98 struct redir_struct *redirects; /* I/O redirects */
99 glob_t glob_result; /* result of parameter globbing */
100 int free_glob; /* should we globfree(&glob_result)? */
101 int is_stopped; /* is the program currently running? */
102 struct job *family; /* pointer back to the child's parent job */
106 int jobid; /* job number */
107 int num_progs; /* total number of programs in job */
108 int running_progs; /* number of programs running */
109 char *text; /* name of job */
110 char *cmdbuf; /* buffer various argv's point into */
111 pid_t pgrp; /* process group ID for the job */
112 struct child_prog *progs; /* array of programs in job */
113 struct job *next; /* to track background commands */
114 int stopped_progs; /* number of programs alive, but stopped */
115 unsigned int job_context; /* bitmask defining current context */
116 struct jobset *job_list;
119 struct built_in_command {
120 char *cmd; /* name */
121 char *descr; /* description */
122 int (*function) (struct child_prog *); /* function ptr */
127 struct close_me *next;
130 /* function prototypes for builtins */
131 static int builtin_cd(struct child_prog *cmd);
132 static int builtin_env(struct child_prog *dummy);
133 static int builtin_exec(struct child_prog *cmd);
134 static int builtin_exit(struct child_prog *cmd);
135 static int builtin_fg_bg(struct child_prog *cmd);
136 static int builtin_help(struct child_prog *cmd);
137 static int builtin_jobs(struct child_prog *dummy);
138 static int builtin_pwd(struct child_prog *dummy);
139 static int builtin_export(struct child_prog *cmd);
140 static int builtin_source(struct child_prog *cmd);
141 static int builtin_unset(struct child_prog *cmd);
142 static int builtin_read(struct child_prog *cmd);
143 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
144 static int builtin_if(struct child_prog *cmd);
145 static int builtin_then(struct child_prog *cmd);
146 static int builtin_else(struct child_prog *cmd);
147 static int builtin_fi(struct child_prog *cmd);
148 /* function prototypes for shell stuff */
149 static int run_command_predicate(char *cmd);
153 /* function prototypes for shell stuff */
154 static void mark_open(int fd);
155 static void mark_closed(int fd);
156 static void checkjobs(struct jobset *job_list);
157 static int get_command(FILE * source, char *command);
158 static int parse_command(char **command_ptr, struct job *job, int *inbg);
159 static int run_command(struct job *newjob, int inbg, int outpipe[2]);
160 static int pseudo_exec(struct child_prog *cmd) __attribute__ ((noreturn));
161 static int busy_loop(FILE * input);
164 /* Table of built-in functions (these are non-forking builtins, meaning they
165 * can change global variables in the parent shell process but they will not
166 * work with pipes and redirects; 'unset foo | whatever' will not work) */
167 static struct built_in_command bltins[] = {
168 {"bg", "Resume a job in the background", builtin_fg_bg},
169 {"cd", "Change working directory", builtin_cd},
170 {"exec", "Exec command, replacing this shell with the exec'd process", builtin_exec},
171 {"exit", "Exit from shell()", builtin_exit},
172 {"fg", "Bring job into the foreground", builtin_fg_bg},
173 {"jobs", "Lists the active jobs", builtin_jobs},
174 {"export", "Set environment variable", builtin_export},
175 {"unset", "Unset environment variable", builtin_unset},
176 {"read", "Input environment variable", builtin_read},
177 {".", "Source-in and run commands in a file", builtin_source},
178 /* to do: add ulimit */
179 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
180 {"if", NULL, builtin_if},
181 {"then", NULL, builtin_then},
182 {"else", NULL, builtin_else},
183 {"fi", NULL, builtin_fi},
188 /* Table of forking built-in functions (things that fork cannot change global
189 * variables in the parent process, such as the current working directory) */
190 static struct built_in_command bltins_forking[] = {
191 {"env", "Print all environment variables", builtin_env},
192 {"pwd", "Print current directory", builtin_pwd},
193 {"help", "List shell built-in commands", builtin_help},
198 /* Variables we export */
199 unsigned int shell_context; /* Used in cmdedit.c to reset the
200 context when someone hits ^C */
203 /* Globals that are static to this file */
205 static char *local_pending_command = NULL;
206 static struct jobset job_list = { NULL, NULL };
209 static struct close_me *close_me_head = NULL;
210 #ifdef BB_FEATURE_SH_ENVIRONMENT
211 static int last_bg_pid=-1;
212 static int last_return_code=-1;
213 static int show_x_trace=FALSE;
215 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
216 static char syntax_err[]="syntax error near unexpected token";
220 static inline void debug_printf(const char *format, ...)
223 va_start(args, format);
224 vfprintf(stderr, format, args);
228 static inline void debug_printf(const char *format, ...) { }
232 Most builtins need access to the struct child_prog that has
233 their arguments, previously coded as cmd->progs[0]. That coding
234 can exhibit a bug, if the builtin is not the first command in
235 a pipeline: "echo foo | exec sort" will attempt to exec foo.
237 builtin previous use notes
238 ------ ----------------- ---------
241 exec cmd->progs[0] squashed bug: didn't look for applets or forking builtins
243 fg_bg cmd->progs[0], job_list->head, job_list->fg
247 export cmd->progs[0] passes cmd, job_list to builtin_env(), which ignores them
251 if cmd->job_context, cmd->text
252 then cmd->job_context, cmd->text
253 else cmd->job_context, cmd->text
256 The use of cmd->text by if/then/else/fi is hopelessly hacky.
257 Would it work to increment cmd->progs[0]->argv and recurse,
258 somewhat like builtin_exec does?
260 I added "struct job *family;" to struct child_prog,
261 and switched API to builtin_foo(struct child_prog *child);
262 So cmd->text becomes child->family->text
263 cmd->job_context becomes child->family->job_context
264 cmd->progs[0] becomes *child
265 job_list becomes child->family->job_list
268 /* built-in 'cd <path>' handler */
269 static int builtin_cd(struct child_prog *child)
273 if (child->argv[1] == NULL)
274 newdir = getenv("HOME");
276 newdir = child->argv[1];
278 printf("cd: %s: %s\n", newdir, strerror(errno));
281 getcwd(cwd, sizeof(char)*MAX_LINE);
286 /* built-in 'env' handler */
287 static int builtin_env(struct child_prog *dummy)
291 for (e = environ; *e; e++) {
297 /* built-in 'exec' handler */
298 static int builtin_exec(struct child_prog *child)
300 if (child->argv[1] == NULL)
301 return EXIT_SUCCESS; /* Really? */
307 /* built-in 'exit' handler */
308 static int builtin_exit(struct child_prog *child)
310 if (child->argv[1] == NULL)
313 exit (atoi(child->argv[1]));
316 /* built-in 'fg' and 'bg' handler */
317 static int builtin_fg_bg(struct child_prog *child)
320 struct job *job=NULL;
322 if (!child->argv[1] || child->argv[2]) {
323 error_msg("%s: exactly one argument is expected",
328 if (sscanf(child->argv[1], "%%%d", &jobNum) != 1) {
329 error_msg("%s: bad argument '%s'",
330 child->argv[0], child->argv[1]);
334 for (job = child->family->job_list->head; job; job = job->next) {
335 if (job->jobid == jobNum) {
341 error_msg("%s: unknown job %d",
342 child->argv[0], jobNum);
346 if (*child->argv[0] == 'f') {
347 /* Make this job the foreground job */
348 /* suppress messages when run from /linuxrc mag@sysgo.de */
349 if (tcsetpgrp(0, job->pgrp) && errno != ENOTTY)
350 perror_msg("tcsetpgrp");
351 child->family->job_list->fg = job;
354 /* Restart the processes in the job */
355 for (i = 0; i < job->num_progs; i++)
356 job->progs[i].is_stopped = 0;
358 kill(-job->pgrp, SIGCONT);
360 job->stopped_progs = 0;
365 /* built-in 'help' handler */
366 static int builtin_help(struct child_prog *dummy)
368 struct built_in_command *x;
370 printf("\nBuilt-in commands:\n");
371 printf("-------------------\n");
372 for (x = bltins; x->cmd; x++) {
375 printf("%s\t%s\n", x->cmd, x->descr);
377 for (x = bltins_forking; x->cmd; x++) {
380 printf("%s\t%s\n", x->cmd, x->descr);
386 /* built-in 'jobs' handler */
387 static int builtin_jobs(struct child_prog *child)
392 for (job = child->family->job_list->head; job; job = job->next) {
393 if (job->running_progs == job->stopped_progs)
394 status_string = "Stopped";
396 status_string = "Running";
398 printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->text);
404 /* built-in 'pwd' handler */
405 static int builtin_pwd(struct child_prog *dummy)
407 getcwd(cwd, MAX_LINE);
408 printf( "%s\n", cwd);
412 /* built-in 'export VAR=value' handler */
413 static int builtin_export(struct child_prog *child)
417 if (child->argv[1] == NULL) {
418 return (builtin_env(child));
420 res = putenv(child->argv[1]);
422 fprintf(stderr, "export: %s\n", strerror(errno));
426 /* built-in 'read VAR' handler */
427 static int builtin_read(struct child_prog *child)
429 int res = 0, len, newlen;
431 char string[MAX_READ];
433 if (child->argv[1]) {
434 /* argument (VAR) given: put "VAR=" into buffer */
435 strcpy(string, child->argv[1]);
436 len = strlen(string);
439 fgets(&string[len], sizeof(string) - len, stdin); /* read string */
440 newlen = strlen(string);
442 string[--newlen] = '\0'; /* chomp trailing newline */
444 ** string should now contain "VAR=<value>"
445 ** copy it (putenv() won't do that, so we must make sure
446 ** the string resides in a static buffer!)
449 if((s = strdup(string)))
452 fprintf(stderr, "read: %s\n", strerror(errno));
455 fgets(string, sizeof(string), stdin);
460 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
461 /* Built-in handler for 'if' commands */
462 static int builtin_if(struct child_prog *child)
464 struct job *cmd = child->family;
466 char* charptr1=cmd->text+3; /* skip over the leading 'if ' */
468 /* Now run the 'if' command */
469 debug_printf( "job=%p entering builtin_if ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
470 status = run_command_predicate(charptr1);
471 debug_printf( "if test returned ");
473 debug_printf( "TRUE\n");
474 cmd->job_context |= IF_TRUE_CONTEXT;
476 debug_printf( "FALSE\n");
477 cmd->job_context |= IF_FALSE_CONTEXT;
479 debug_printf("job=%p builtin_if set job context to %x\n", cmd, cmd->job_context);
485 /* Built-in handler for 'then' (part of the 'if' command) */
486 static int builtin_then(struct child_prog *child)
488 struct job *cmd = child->family;
489 char* charptr1=cmd->text+5; /* skip over the leading 'then ' */
491 debug_printf( "job=%p entering builtin_then ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
492 if (! (cmd->job_context & (IF_TRUE_CONTEXT|IF_FALSE_CONTEXT))) {
493 shell_context = 0; /* Reset the shell's context on an error */
494 error_msg("%s `then'", syntax_err);
498 cmd->job_context |= THEN_EXP_CONTEXT;
499 debug_printf("job=%p builtin_then set job context to %x\n", cmd, cmd->job_context);
501 /* If the if result was FALSE, skip the 'then' stuff */
502 if (cmd->job_context & IF_FALSE_CONTEXT) {
506 /* Seems the if result was TRUE, so run the 'then' command */
507 debug_printf( "'then' now running '%s'\n", charptr1);
509 return(run_command_predicate(charptr1));
512 /* Built-in handler for 'else' (part of the 'if' command) */
513 static int builtin_else(struct child_prog *child)
515 struct job *cmd = child->family;
516 char* charptr1=cmd->text+5; /* skip over the leading 'else ' */
518 debug_printf( "job=%p entering builtin_else ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
520 if (! (cmd->job_context & THEN_EXP_CONTEXT)) {
521 shell_context = 0; /* Reset the shell's context on an error */
522 error_msg("%s `else'", syntax_err);
525 /* If the if result was TRUE, skip the 'else' stuff */
526 if (cmd->job_context & IF_TRUE_CONTEXT) {
530 cmd->job_context |= ELSE_EXP_CONTEXT;
531 debug_printf("job=%p builtin_else set job context to %x\n", cmd, cmd->job_context);
533 /* Now run the 'else' command */
534 debug_printf( "'else' now running '%s'\n", charptr1);
535 return(run_command_predicate(charptr1));
538 /* Built-in handler for 'fi' (part of the 'if' command) */
539 static int builtin_fi(struct child_prog *child)
541 struct job *cmd = child->family;
542 debug_printf( "job=%p entering builtin_fi ('%s')-- context=%d\n", cmd, "", cmd->job_context);
543 if (! (cmd->job_context & (IF_TRUE_CONTEXT|IF_FALSE_CONTEXT))) {
544 shell_context = 0; /* Reset the shell's context on an error */
545 error_msg("%s `fi'", syntax_err);
548 /* Clear out the if and then context bits */
549 cmd->job_context &= ~(IF_TRUE_CONTEXT|IF_FALSE_CONTEXT|THEN_EXP_CONTEXT|ELSE_EXP_CONTEXT);
550 debug_printf("job=%p builtin_fi set job context to %x\n", cmd, cmd->job_context);
556 /* Built-in '.' handler (read-in and execute commands from file) */
557 static int builtin_source(struct child_prog *child)
563 if (child->argv[1] == NULL)
566 input = fopen(child->argv[1], "r");
568 printf( "Couldn't open file '%s'\n", child->argv[1]);
574 /* Now run the file */
575 status = busy_loop(input);
581 /* built-in 'unset VAR' handler */
582 static int builtin_unset(struct child_prog *child)
584 if (child->argv[1] == NULL) {
585 printf( "unset: parameter required.\n");
588 unsetenv(child->argv[1]);
592 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
593 /* currently used by if/then/else.
595 * Reparsing the command line for this purpose is gross,
596 * incorrect, and fundamentally unfixable; in particular,
597 * think about what happens with command substitution.
598 * We really need to pull out the run, wait, return status
599 * functionality out of busy_loop so we can child->argv++
600 * and use that, without going back through parse_command.
602 static int run_command_predicate(char *cmd)
605 local_pending_command = xmalloc(n+1);
606 strncpy(local_pending_command, cmd, n);
607 local_pending_command[n]='\0';
608 return( busy_loop(NULL));
612 static void mark_open(int fd)
614 struct close_me *new = xmalloc(sizeof(struct close_me));
616 new->next = close_me_head;
620 static void mark_closed(int fd)
622 struct close_me *tmp;
623 if (close_me_head == NULL || close_me_head->fd != fd)
624 error_msg_and_die("corrupt close_me");
626 close_me_head = close_me_head->next;
630 static void close_all()
633 for (c=close_me_head; c; c=c->next) {
636 close_me_head = NULL;
640 /* free up all memory from a job */
641 static void free_job(struct job *cmd)
645 for (i = 0; i < cmd->num_progs; i++) {
646 free(cmd->progs[i].argv);
647 if (cmd->progs[i].redirects)
648 free(cmd->progs[i].redirects);
649 if (cmd->progs[i].free_glob)
650 globfree(&cmd->progs[i].glob_result);
656 memset(cmd, 0, sizeof(struct job));
659 /* remove a job from the job_list */
660 static void remove_job(struct jobset *job_list, struct job *job)
665 if (job == job_list->head) {
666 job_list->head = job->next;
668 prevjob = job_list->head;
669 while (prevjob->next != job)
670 prevjob = prevjob->next;
671 prevjob->next = job->next;
677 /* Checks to see if any background processes have exited -- if they
678 have, figure out why and see if a job has completed */
679 static void checkjobs(struct jobset *job_list)
686 while ((childpid = waitpid(-1, &status, WNOHANG | WUNTRACED)) > 0) {
687 for (job = job_list->head; job; job = job->next) {
689 while (prognum < job->num_progs &&
690 job->progs[prognum].pid != childpid) prognum++;
691 if (prognum < job->num_progs)
695 /* This happens on backticked commands */
699 if (WIFEXITED(status) || WIFSIGNALED(status)) {
701 job->running_progs--;
702 job->progs[prognum].pid = 0;
704 if (!job->running_progs) {
705 printf(JOB_STATUS_FORMAT, job->jobid, "Done", job->text);
706 remove_job(job_list, job);
710 job->stopped_progs++;
711 job->progs[prognum].is_stopped = 1;
713 if (job->stopped_progs == job->num_progs) {
714 printf(JOB_STATUS_FORMAT, job->jobid, "Stopped",
720 if (childpid == -1 && errno != ECHILD)
721 perror_msg("waitpid");
724 /* squirrel != NULL means we squirrel away copies of stdin, stdout,
725 * and stderr if they are redirected. */
726 static int setup_redirects(struct child_prog *prog, int squirrel[])
731 struct redir_struct *redir = prog->redirects;
733 for (i = 0; i < prog->num_redirects; i++, redir++) {
734 switch (redir->type) {
738 case REDIRECT_OVERWRITE:
739 mode = O_WRONLY | O_CREAT | O_TRUNC;
741 case REDIRECT_APPEND:
742 mode = O_WRONLY | O_CREAT | O_APPEND;
746 openfd = open(redir->filename, mode, 0666);
748 /* this could get lost if stderr has been redirected, but
749 bash and ash both lose it as well (though zsh doesn't!) */
750 error_msg("error opening %s: %s", redir->filename,
755 if (openfd != redir->fd) {
756 if (squirrel && redir->fd < 3) {
757 squirrel[redir->fd] = dup(redir->fd);
759 dup2(openfd, redir->fd);
767 static void restore_redirects(int squirrel[])
770 for (i=0; i<3; i++) {
773 /* No error checking. I sure wouldn't know what
774 * to do with an error if I found one! */
781 #if defined(BB_FEATURE_SH_SIMPLE_PROMPT)
782 static char* setup_prompt_string(int state)
784 char prompt_str[BUFSIZ];
786 /* Set up the prompt */
789 sprintf(prompt_str, "%s %s", cwd, ( geteuid() != 0 ) ? "$ ":"# ");
791 strcpy(prompt_str,"> ");
794 return(strdup(prompt_str)); /* Must free this memory */
799 static char* setup_prompt_string(int state)
801 char user[9],buf[255],*s;
803 char prompt_str[BUFSIZ];
805 /* Set up the prompt */
807 /* get User Name and setup prompt */
808 strcpy(prompt,( geteuid() != 0 ) ? "$ ":"# ");
809 my_getpwuid(user, geteuid());
812 gethostname(buf, 255);
813 s = strchr(buf, '.');
822 snprintf(prompt_str, BUFSIZ-1, "[%s@%s %s]%s", user, buf,
823 get_last_path_component(cwd), prompt);
825 sprintf(prompt_str, "%s", prompt);
827 return(strdup(prompt_str)); /* Must free this memory */
832 static int get_command(FILE * source, char *command)
836 if (source == NULL) {
837 if (local_pending_command) {
838 /* a command specified (-c option): return it & mark it done */
839 strcpy(command, local_pending_command);
840 free(local_pending_command);
841 local_pending_command = NULL;
847 if (source == stdin) {
848 prompt_str = setup_prompt_string(shell_context);
850 #ifdef BB_FEATURE_SH_COMMAND_EDITING
852 ** enable command line editing only while a command line
853 ** is actually being read; otherwise, we'll end up bequeathing
854 ** atexit() handlers and other unwanted stuff to our
855 ** child processes (rob@sysgo.de)
858 cmdedit_read_input(prompt_str, command);
863 fputs(prompt_str, stdout);
868 if (!fgets(command, BUFSIZ - 2, source)) {
874 /* remove trailing newline */
875 command[strlen(command) - 1] = '\0';
880 #ifdef BB_FEATURE_SH_ENVIRONMENT
881 static char* itoa(register int i)
883 static char a[7]; /* Max 7 ints */
884 register char *b = a + sizeof(a) - 1;
892 *--b = '0' + (i % 10);
902 static void expand_argument(struct child_prog *prog, int *argcPtr,
903 int *argv_alloced_ptr)
905 int argc_l = *argcPtr;
906 int argv_alloced = *argv_alloced_ptr;
910 char *src, *dst, *var;
912 if (argc_l > 1) { /* cmd->glob_result is already initialized */
914 i = prog->glob_result.gl_pathc;
920 /* do shell variable substitution */
921 if(*prog->argv[argc_l - 1] == '$') {
922 if ((var = getenv(prog->argv[argc_l - 1] + 1))) {
923 prog->argv[argc_l - 1] = var;
925 #ifdef BB_FEATURE_SH_ENVIRONMENT
927 switch(*(prog->argv[argc_l - 1] + 1)) {
929 prog->argv[argc_l - 1] = itoa(last_return_code);
932 prog->argv[argc_l - 1] = itoa(getpid());
935 prog->argv[argc_l - 1] = itoa(argc-1);
939 *(prog->argv[argc_l - 1])='\0';
941 prog->argv[argc_l - 1] = itoa(last_bg_pid);
943 case '0':case '1':case '2':case '3':case '4':
944 case '5':case '6':case '7':case '8':case '9':
946 int index=*(prog->argv[argc_l - 1] + 1)-48;
948 *(prog->argv[argc_l - 1])='\0';
950 prog->argv[argc_l - 1] = argv[index];
959 if (strpbrk(prog->argv[argc_l - 1],"*[]?")!= NULL){
960 rc = glob(prog->argv[argc_l - 1], flags, NULL, &prog->glob_result);
961 if (rc == GLOB_NOSPACE) {
962 error_msg("out of space during glob operation");
964 } else if (rc == GLOB_NOMATCH ||
965 (!rc && (prog->glob_result.gl_pathc - i) == 1 &&
966 strcmp(prog->argv[argc_l - 1],
967 prog->glob_result.gl_pathv[i]) == 0)) {
968 /* we need to remove whatever \ quoting is still present */
969 src = dst = prog->argv[argc_l - 1];
973 *dst++ = process_escape_sequence(&src);
981 argv_alloced += (prog->glob_result.gl_pathc - i);
982 prog->argv = xrealloc(prog->argv, argv_alloced * sizeof(*prog->argv));
983 memcpy(prog->argv + (argc_l - 1), prog->glob_result.gl_pathv + i,
984 sizeof(*(prog->argv)) * (prog->glob_result.gl_pathc - i));
985 argc_l += (prog->glob_result.gl_pathc - i - 1);
988 src = dst = prog->argv[argc_l - 1];
992 *dst++ = process_escape_sequence(&src);
1000 prog->glob_result.gl_pathc=0;
1002 prog->glob_result.gl_pathv=NULL;
1004 *argv_alloced_ptr = argv_alloced;
1008 /* Return cmd->num_progs as 0 if no command is present (e.g. an empty
1009 line). If a valid command is found, command_ptr is set to point to
1010 the beginning of the next command (if the original command had more
1011 then one job associated with it) or NULL if no more commands are
1013 static int parse_command(char **command_ptr, struct job *job, int *inbg)
1016 char *return_command = NULL;
1017 char *src, *buf, *chptr;
1024 struct child_prog *prog;
1026 /* skip leading white space */
1027 while (**command_ptr && isspace(**command_ptr))
1030 /* this handles empty lines or leading '#' characters */
1031 if (!**command_ptr || (**command_ptr == '#')) {
1038 job->progs = xmalloc(sizeof(*job->progs));
1040 /* We set the argv elements to point inside of this string. The
1041 memory is freed by free_job(). Allocate twice the original
1042 length in case we need to quote every single character.
1044 Getting clean memory relieves us of the task of NULL
1045 terminating things and makes the rest of this look a bit
1046 cleaner (though it is, admittedly, a tad less efficient) */
1047 job->cmdbuf = command = xcalloc(2*strlen(*command_ptr) + 1, sizeof(char));
1051 prog->num_redirects = 0;
1052 prog->redirects = NULL;
1053 prog->free_glob = 0;
1054 prog->is_stopped = 0;
1058 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1059 prog->argv[0] = job->cmdbuf;
1063 while (*src && !done) {
1064 if (quote == *src) {
1070 error_msg("character expected after \\");
1075 /* in shell, "\'" should yield \' */
1076 if (*src != quote) {
1080 } else if (*src == '*' || *src == '?' || *src == '[' ||
1081 *src == ']') *buf++ = '\\';
1083 } else if (isspace(*src)) {
1084 if (*prog->argv[argc_l]) {
1086 /* +1 here leaves room for the NULL which ends argv */
1087 if ((argc_l + 1) == argv_alloced) {
1089 prog->argv = xrealloc(prog->argv,
1090 sizeof(*prog->argv) *
1093 expand_argument(prog, &argc_l, &argv_alloced);
1094 prog->argv[argc_l] = buf;
1103 case '#': /* comment */
1110 case '>': /* redirects */
1112 i = prog->num_redirects++;
1113 prog->redirects = xrealloc(prog->redirects,
1114 sizeof(*prog->redirects) *
1117 prog->redirects[i].fd = -1;
1118 if (buf != prog->argv[argc_l]) {
1119 /* the stuff before this character may be the file number
1121 prog->redirects[i].fd =
1122 strtol(prog->argv[argc_l], &chptr, 10);
1124 if (*chptr && *prog->argv[argc_l]) {
1126 expand_argument(prog, &argc_l, &argv_alloced);
1127 prog->argv[argc_l] = buf;
1131 if (prog->redirects[i].fd == -1) {
1133 prog->redirects[i].fd = 1;
1135 prog->redirects[i].fd = 0;
1138 if (*src++ == '>') {
1140 prog->redirects[i].type =
1141 REDIRECT_APPEND, src++;
1143 prog->redirects[i].type = REDIRECT_OVERWRITE;
1145 prog->redirects[i].type = REDIRECT_INPUT;
1148 /* This isn't POSIX sh compliant. Oh well. */
1150 while (isspace(*chptr))
1154 error_msg("file name expected after %c", *src);
1160 prog->redirects[i].filename = buf;
1161 while (*chptr && !isspace(*chptr))
1164 src = chptr - 1; /* we src++ later */
1165 prog->argv[argc_l] = ++buf;
1168 case '|': /* pipe */
1169 /* finish this command */
1170 if (*prog->argv[argc_l])
1173 error_msg("empty command in pipe");
1178 prog->argv[argc_l] = NULL;
1180 /* and start the next */
1182 job->progs = xrealloc(job->progs,
1183 sizeof(*job->progs) * job->num_progs);
1184 prog = job->progs + (job->num_progs - 1);
1185 prog->num_redirects = 0;
1186 prog->redirects = NULL;
1187 prog->free_glob = 0;
1188 prog->is_stopped = 0;
1193 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1194 prog->argv[0] = ++buf;
1197 while (*src && isspace(*src))
1201 error_msg("empty command in pipe");
1206 src--; /* we'll ++ it at the end of the loop */
1210 case '&': /* background */
1212 case ';': /* multiple commands */
1214 return_command = *command_ptr + (src - *command_ptr) + 1;
1217 #ifdef BB_FEATURE_SH_BACKTICKS
1219 /* Exec a backtick-ed command */
1220 /* Besides any previous brokenness, I have not
1221 * updated backtick handling for close_me support.
1222 * I don't know if it needs it or not. -- LRD */
1224 char* charptr1=NULL, *charptr2;
1227 struct jobset njob_list = { NULL, NULL };
1231 ptr=strchr(++src, '`');
1233 fprintf(stderr, "Unmatched '`' in command\n");
1238 /* Make some space to hold just the backticked command */
1239 charptr1 = charptr2 = xmalloc(1+ptr-src);
1240 memcpy(charptr1, src, ptr-src);
1241 charptr1[ptr-src] = '\0';
1242 newjob = xmalloc(sizeof(struct job));
1243 newjob->job_list = &njob_list;
1244 /* Now parse and run the backticked command */
1245 if (!parse_command(&charptr1, newjob, inbg)
1246 && newjob->num_progs) {
1248 run_command(newjob, 0, pipefd);
1250 checkjobs(job->job_list);
1251 free_job(newjob); /* doesn't actually free newjob,
1252 looks like a memory leak */
1255 /* Make a copy of any stuff left over in the command
1256 * line after the second backtick */
1257 charptr2 = xmalloc(strlen(ptr)+1);
1258 memcpy(charptr2, ptr+1, strlen(ptr));
1261 /* Copy the output from the backtick-ed command into the
1262 * command line, making extra room as needed */
1264 charptr1 = xmalloc(BUFSIZ);
1265 while ( (size=full_read(pipefd[0], charptr1, BUFSIZ-1)) >0) {
1266 int newsize=src - *command_ptr + size + 1 + strlen(charptr2);
1267 if (newsize > BUFSIZ) {
1268 *command_ptr=xrealloc(*command_ptr, newsize);
1270 memcpy(src, charptr1, size);
1278 /* Now paste into the *command_ptr all the stuff
1279 * leftover after the second backtick */
1280 memcpy(src, charptr2, strlen(charptr2)+1);
1283 /* Now recursively call parse_command to deal with the new
1284 * and improved version of the command line with the backtick
1285 * results expanded in place... */
1287 struct jobset *jl=job->job_list;
1291 return(parse_command(command_ptr, job, inbg));
1294 #endif // BB_FEATURE_SH_BACKTICKS
1299 /* This is currently a little broken... */
1300 #ifdef HANDLE_CONTINUATION_CHARS
1301 /* They fed us a continuation char, so continue reading stuff
1302 * on the next line, then tack that onto the end of the current
1306 printf("erik: found a continue char at EOL...\n");
1307 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1308 if (get_command(input, command)) {
1309 error_msg("character expected after \\");
1314 newsize = strlen(*command_ptr) + strlen(command) + 2;
1315 if (newsize > BUFSIZ) {
1316 printf("erik: doing realloc\n");
1317 *command_ptr=xrealloc(*command_ptr, newsize);
1319 printf("erik: A: *command_ptr='%s'\n", *command_ptr);
1320 memcpy(--src, command, strlen(command));
1321 printf("erik: B: *command_ptr='%s'\n", *command_ptr);
1325 error_msg("character expected after \\");
1331 if (*src == '*' || *src == '[' || *src == ']'
1332 || *src == '?') *buf++ = '\\';
1341 if (*prog->argv[argc_l]) {
1343 expand_argument(prog, &argc_l, &argv_alloced);
1349 prog->argv[argc_l] = NULL;
1351 if (!return_command) {
1352 job->text = xmalloc(strlen(*command_ptr) + 1);
1353 strcpy(job->text, *command_ptr);
1355 /* This leaves any trailing spaces, which is a bit sloppy */
1356 count = return_command - *command_ptr;
1357 job->text = xmalloc(count + 1);
1358 strncpy(job->text, *command_ptr, count);
1359 job->text[count] = '\0';
1362 *command_ptr = return_command;
1367 /* Run the child_prog, no matter what kind of command it uses.
1369 static int pseudo_exec(struct child_prog *child)
1371 struct built_in_command *x;
1372 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
1373 struct BB_applet *applet;
1377 /* Check if the command matches any of the non-forking builtins.
1378 * Depending on context, this might be redundant. But it's
1379 * easier to waste a few CPU cycles than it is to figure out
1380 * if this is one of those cases.
1382 for (x = bltins; x->cmd; x++) {
1383 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1384 exit(x->function(child));
1388 /* Check if the command matches any of the forking builtins. */
1389 for (x = bltins_forking; x->cmd; x++) {
1390 if (strcmp(child->argv[0], x->cmd) == 0) {
1392 exit (x->function(child));
1395 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
1396 /* Check if the command matches any busybox internal
1397 * commands ("applets") here. Following discussions from
1398 * November 2000 on busybox@opensource.lineo.com, don't use
1399 * get_last_path_component(). This way explicit (with
1400 * slashes) filenames will never be interpreted as an
1401 * applet, just like with builtins. This way the user can
1402 * override an applet with an explicit filename reference.
1403 * The only downside to this change is that an explicit
1404 * /bin/foo invocation will fork and exec /bin/foo, even if
1405 * /bin/foo is a symlink to busybox.
1407 name = child->argv[0];
1409 #ifdef BB_FEATURE_SH_APPLETS_ALWAYS_WIN
1410 /* If you enable BB_FEATURE_SH_APPLETS_ALWAYS_WIN, then
1411 * if you run /bin/cat, it will use BusyBox cat even if
1412 * /bin/cat exists on the filesystem and is _not_ busybox.
1413 * Some systems want this, others do not. Choose wisely. :-)
1415 name = get_last_path_component(name);
1418 /* Do a binary search to find the applet entry given the name. */
1419 if ((applet = find_applet_by_name(name)) != NULL) {
1421 char** argv=child->argv;
1422 for(argc_l=0;*argv!=NULL; argv++, argc_l++);
1423 applet_name=applet->name;
1425 exit((*(applet->main)) (argc_l, child->argv));
1429 execvp(child->argv[0], child->argv);
1430 perror_msg_and_die("%s", child->argv[0]);
1433 static void insert_job(struct job *newjob, int inbg)
1436 struct jobset *job_list=newjob->job_list;
1438 /* find the ID for thejob to use */
1440 for (thejob = job_list->head; thejob; thejob = thejob->next)
1441 if (thejob->jobid >= newjob->jobid)
1442 newjob->jobid = thejob->jobid + 1;
1444 /* add thejob to the list of running jobs */
1445 if (!job_list->head) {
1446 thejob = job_list->head = xmalloc(sizeof(*thejob));
1448 for (thejob = job_list->head; thejob->next; thejob = thejob->next) /* nothing */;
1449 thejob->next = xmalloc(sizeof(*thejob));
1450 thejob = thejob->next;
1453 *thejob = *newjob; /* physically copy the struct job */
1454 thejob->next = NULL;
1455 thejob->running_progs = thejob->num_progs;
1456 thejob->stopped_progs = 0;
1459 /* we don't wait for background thejobs to return -- append it
1460 to the list of backgrounded thejobs and leave it alone */
1461 printf("[%d] %d\n", thejob->jobid,
1462 newjob->progs[newjob->num_progs - 1].pid);
1463 #ifdef BB_FEATURE_SH_ENVIRONMENT
1464 last_bg_pid=newjob->progs[newjob->num_progs - 1].pid;
1467 newjob->job_list->fg = thejob;
1469 /* move the new process group into the foreground */
1470 /* suppress messages when run from /linuxrc mag@sysgo.de */
1471 if (tcsetpgrp(0, newjob->pgrp) && errno != ENOTTY)
1472 perror_msg("tcsetpgrp");
1476 static int run_command(struct job *newjob, int inbg, int outpipe[2])
1478 /* struct job *thejob; */
1480 int nextin, nextout;
1481 int pipefds[2]; /* pipefd[0] is for reading */
1482 struct built_in_command *x;
1483 struct child_prog *child;
1485 nextin = 0, nextout = 1;
1486 for (i = 0; i < newjob->num_progs; i++) {
1487 child = & (newjob->progs[i]);
1489 if ((i + 1) < newjob->num_progs) {
1490 if (pipe(pipefds)<0) perror_msg_and_die("pipe");
1491 nextout = pipefds[1];
1493 if (outpipe[1]!=-1) {
1494 nextout = outpipe[1];
1500 #ifdef BB_FEATURE_SH_ENVIRONMENT
1501 if (show_x_trace==TRUE) {
1504 for (j = 0; child->argv[j]; j++) {
1506 fputs(child->argv[j], stderr);
1508 fputc('\n', stderr);
1512 /* Check if the command matches any non-forking builtins,
1513 * but only if this is a simple command.
1514 * Non-forking builtins within pipes have to fork anyway,
1515 * and are handled in pseudo_exec. "echo foo | read bar"
1516 * is doomed to failure, and doesn't work on bash, either.
1518 if (newjob->num_progs == 1) {
1519 for (x = bltins; x->cmd; x++) {
1520 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1521 int squirrel[] = {-1, -1, -1};
1523 setup_redirects(child, squirrel);
1524 rcode = x->function(child);
1525 restore_redirects(squirrel);
1531 if (!(child->pid = fork())) {
1532 signal(SIGTTOU, SIG_DFL);
1536 if (outpipe[1]!=-1) {
1546 dup2(nextout, 2); /* Really? */
1551 /* explicit redirects override pipes */
1552 setup_redirects(child,NULL);
1556 if (outpipe[1]!=-1) {
1560 /* put our child in the process group whose leader is the
1561 first process in this pipe */
1562 setpgid(child->pid, newjob->progs[0].pid);
1568 /* If there isn't another process, nextin is garbage
1569 but it doesn't matter */
1570 nextin = pipefds[0];
1573 newjob->pgrp = newjob->progs[0].pid;
1575 insert_job(newjob, inbg);
1580 static int busy_loop(FILE * input)
1583 char *next_command = NULL;
1589 newjob.job_list = &job_list;
1590 newjob.job_context = DEFAULT_CONTEXT;
1592 /* save current owner of TTY so we can restore it on exit */
1593 parent_pgrp = tcgetpgrp(0);
1595 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1597 /* don't pay any attention to this signal; it just confuses
1598 things and isn't really meant for shells anyway */
1599 signal(SIGTTOU, SIG_IGN);
1603 /* no job is in the foreground */
1605 /* see if any background processes have exited */
1606 checkjobs(&job_list);
1608 if (!next_command) {
1609 if (get_command(input, command))
1611 next_command = command;
1614 if (!parse_command(&next_command, &newjob, &inbg) &&
1616 int pipefds[2] = {-1,-1};
1617 debug_printf( "job=%p being fed to run_command by busy_loop()'\n", &newjob);
1618 run_command(&newjob, inbg, pipefds);
1622 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1623 next_command = NULL;
1626 /* a job is running in the foreground; wait for it */
1628 while (!job_list.fg->progs[i].pid ||
1629 job_list.fg->progs[i].is_stopped == 1) i++;
1631 if (waitpid(job_list.fg->progs[i].pid, &status, WUNTRACED)<0)
1632 perror_msg_and_die("waitpid(%d)",job_list.fg->progs[i].pid);
1634 if (WIFEXITED(status) || WIFSIGNALED(status)) {
1635 /* the child exited */
1636 job_list.fg->running_progs--;
1637 job_list.fg->progs[i].pid = 0;
1639 #ifdef BB_FEATURE_SH_ENVIRONMENT
1640 last_return_code=WEXITSTATUS(status);
1642 debug_printf("'%s' exited -- return code %d\n",
1643 job_list.fg->text, last_return_code);
1644 if (!job_list.fg->running_progs) {
1646 remove_job(&job_list, job_list.fg);
1650 /* the child was stopped */
1651 job_list.fg->stopped_progs++;
1652 job_list.fg->progs[i].is_stopped = 1;
1654 if (job_list.fg->stopped_progs == job_list.fg->running_progs) {
1655 printf("\n" JOB_STATUS_FORMAT, job_list.fg->jobid,
1656 "Stopped", job_list.fg->text);
1662 /* move the shell to the foreground */
1663 /* suppress messages when run from /linuxrc mag@sysgo.de */
1664 if (tcsetpgrp(0, getpid()) && errno != ENOTTY)
1665 perror_msg("tcsetpgrp");
1671 /* return controlling TTY back to parent process group before exiting */
1672 if (tcsetpgrp(0, parent_pgrp))
1673 perror_msg("tcsetpgrp");
1675 /* return exit status if called with "-c" */
1676 if (input == NULL && WIFEXITED(status))
1677 return WEXITSTATUS(status);
1683 #ifdef BB_FEATURE_CLEAN_UP
1684 void free_memory(void)
1688 if (local_pending_command)
1689 free(local_pending_command);
1691 if (job_list.fg && !job_list.fg->running_progs) {
1692 remove_job(&job_list, job_list.fg);
1698 int shell_main(int argc_l, char **argv_l)
1700 int opt, interactive=FALSE;
1701 FILE *input = stdin;
1707 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
1708 /* These variables need re-initializing when recursing */
1709 local_pending_command = NULL;
1710 job_list.head = NULL;
1712 #ifdef BB_FEATURE_SH_ENVIRONMENT
1714 last_return_code=-1;
1719 if (argv[0] && argv[0][0] == '-') {
1721 prof_input = fopen("/etc/profile", "r");
1723 printf( "Couldn't open file '/etc/profile'\n");
1725 int tmp_fd = fileno(prof_input);
1727 /* Now run the file */
1728 busy_loop(prof_input);
1730 mark_closed(tmp_fd);
1734 while ((opt = getopt(argc_l, argv_l, "cxi")) > 0) {
1738 if (local_pending_command != 0)
1739 error_msg_and_die("multiple -c arguments");
1740 local_pending_command = xstrdup(argv[optind]);
1744 #ifdef BB_FEATURE_SH_ENVIRONMENT
1746 show_x_trace = TRUE;
1756 /* A shell is interactive if the `-i' flag was given, or if all of
1757 * the following conditions are met:
1759 * no arguments remaining or the -s flag given
1760 * standard input is a terminal
1761 * standard output is a terminal
1762 * Refer to Posix.2, the description of the `sh' utility. */
1763 if (argv[optind]==NULL && input==stdin &&
1764 isatty(fileno(stdin)) && isatty(fileno(stdout))) {
1767 if (interactive==TRUE) {
1768 //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
1769 /* Looks like they want an interactive shell */
1770 printf( "\n\nBusyBox v%s (%s) Built-in shell (lash)\n", BB_VER, BB_BT);
1771 printf( "Enter 'help' for a list of built-in commands.\n\n");
1772 } else if (local_pending_command==NULL) {
1773 //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
1774 input = xfopen(argv[optind], "r");
1775 mark_open(fileno(input)); /* be lazy, never mark this closed */
1778 /* initialize the cwd -- this is never freed...*/
1779 cwd=(char*)xmalloc(sizeof(char)*MAX_LINE+1);
1780 getcwd(cwd, sizeof(char)*MAX_LINE);
1782 #ifdef BB_FEATURE_CLEAN_UP
1783 atexit(free_memory);
1786 return (busy_loop(input));