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"
70 extern size_t NUM_APPLETS;
73 enum redir_type { REDIRECT_INPUT, REDIRECT_OVERWRITE,
77 static const unsigned int DEFAULT_CONTEXT=0x1;
78 static const unsigned int IF_TRUE_CONTEXT=0x2;
79 static const unsigned int IF_FALSE_CONTEXT=0x4;
80 static const unsigned int THEN_EXP_CONTEXT=0x8;
81 static const unsigned int ELSE_EXP_CONTEXT=0x10;
85 struct job *head; /* head of list of running jobs */
86 struct job *fg; /* current foreground job */
90 enum redir_type type; /* type of redirection */
91 int fd; /* file descriptor being redirected */
92 char *filename; /* file to redirect fd to */
96 pid_t pid; /* 0 if exited */
97 char **argv; /* program name and arguments */
98 int num_redirects; /* elements in redirection array */
99 struct redir_struct *redirects; /* I/O redirects */
100 glob_t glob_result; /* result of parameter globbing */
101 int free_glob; /* should we globfree(&glob_result)? */
102 int is_stopped; /* is the program currently running? */
103 struct job *family; /* pointer back to the child's parent job */
107 int jobid; /* job number */
108 int num_progs; /* total number of programs in job */
109 int running_progs; /* number of programs running */
110 char *text; /* name of job */
111 char *cmdbuf; /* buffer various argv's point into */
112 pid_t pgrp; /* process group ID for the job */
113 struct child_prog *progs; /* array of programs in job */
114 struct job *next; /* to track background commands */
115 int stopped_progs; /* number of programs alive, but stopped */
116 unsigned int job_context; /* bitmask defining current context */
117 struct jobset *job_list;
120 struct built_in_command {
121 char *cmd; /* name */
122 char *descr; /* description */
123 int (*function) (struct child_prog *); /* function ptr */
128 struct close_me *next;
131 /* function prototypes for builtins */
132 static int builtin_cd(struct child_prog *cmd);
133 static int builtin_env(struct child_prog *dummy);
134 static int builtin_exec(struct child_prog *cmd);
135 static int builtin_exit(struct child_prog *cmd);
136 static int builtin_fg_bg(struct child_prog *cmd);
137 static int builtin_help(struct child_prog *cmd);
138 static int builtin_jobs(struct child_prog *dummy);
139 static int builtin_pwd(struct child_prog *dummy);
140 static int builtin_export(struct child_prog *cmd);
141 static int builtin_source(struct child_prog *cmd);
142 static int builtin_unset(struct child_prog *cmd);
143 static int builtin_read(struct child_prog *cmd);
144 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
145 static int builtin_if(struct child_prog *cmd);
146 static int builtin_then(struct child_prog *cmd);
147 static int builtin_else(struct child_prog *cmd);
148 static int builtin_fi(struct child_prog *cmd);
149 /* function prototypes for shell stuff */
150 static int run_command_predicate(char *cmd);
154 /* function prototypes for shell stuff */
155 static void mark_open(int fd);
156 static void mark_closed(int fd);
157 static void checkjobs(struct jobset *job_list);
158 static int get_command(FILE * source, char *command);
159 static int parse_command(char **command_ptr, struct job *job, int *inbg);
160 static int run_command(struct job *newjob, int inbg, int outpipe[2]);
161 static int pseudo_exec(struct child_prog *cmd) __attribute__ ((noreturn));
162 static int busy_loop(FILE * input);
165 /* Table of built-in functions (these are non-forking builtins, meaning they
166 * can change global variables in the parent shell process but they will not
167 * work with pipes and redirects; 'unset foo | whatever' will not work) */
168 static struct built_in_command bltins[] = {
169 {"bg", "Resume a job in the background", builtin_fg_bg},
170 {"cd", "Change working directory", builtin_cd},
171 {"exec", "Exec command, replacing this shell with the exec'd process", builtin_exec},
172 {"exit", "Exit from shell()", builtin_exit},
173 {"fg", "Bring job into the foreground", builtin_fg_bg},
174 {"jobs", "Lists the active jobs", builtin_jobs},
175 {"export", "Set environment variable", builtin_export},
176 {"unset", "Unset environment variable", builtin_unset},
177 {"read", "Input environment variable", builtin_read},
178 {".", "Source-in and run commands in a file", builtin_source},
179 /* to do: add ulimit */
180 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
181 {"if", NULL, builtin_if},
182 {"then", NULL, builtin_then},
183 {"else", NULL, builtin_else},
184 {"fi", NULL, builtin_fi},
189 /* Table of forking built-in functions (things that fork cannot change global
190 * variables in the parent process, such as the current working directory) */
191 static struct built_in_command bltins_forking[] = {
192 {"env", "Print all environment variables", builtin_env},
193 {"pwd", "Print current directory", builtin_pwd},
194 {"help", "List shell built-in commands", builtin_help},
199 /* Variables we export */
200 unsigned int shell_context; /* Used in cmdedit.c to reset the
201 context when someone hits ^C */
204 /* Globals that are static to this file */
206 static char *local_pending_command = NULL;
207 static struct jobset job_list = { NULL, NULL };
210 static struct close_me *close_me_head = NULL;
211 #ifdef BB_FEATURE_SH_ENVIRONMENT
212 static int last_bg_pid=-1;
213 static int last_return_code=-1;
214 static int show_x_trace=FALSE;
216 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
217 static char syntax_err[]="syntax error near unexpected token";
221 static inline void debug_printf(const char *format, ...)
224 va_start(args, format);
225 vfprintf(stderr, format, args);
229 static inline void debug_printf(const char *format, ...) { }
233 Most builtins need access to the struct child_prog that has
234 their arguments, previously coded as cmd->progs[0]. That coding
235 can exhibit a bug, if the builtin is not the first command in
236 a pipeline: "echo foo | exec sort" will attempt to exec foo.
238 builtin previous use notes
239 ------ ----------------- ---------
242 exec cmd->progs[0] squashed bug: didn't look for applets or forking builtins
244 fg_bg cmd->progs[0], job_list->head, job_list->fg
248 export cmd->progs[0] passes cmd, job_list to builtin_env(), which ignores them
252 if cmd->job_context, cmd->text
253 then cmd->job_context, cmd->text
254 else cmd->job_context, cmd->text
257 The use of cmd->text by if/then/else/fi is hopelessly hacky.
258 Would it work to increment cmd->progs[0]->argv and recurse,
259 somewhat like builtin_exec does?
261 I added "struct job *family;" to struct child_prog,
262 and switched API to builtin_foo(struct child_prog *child);
263 So cmd->text becomes child->family->text
264 cmd->job_context becomes child->family->job_context
265 cmd->progs[0] becomes *child
266 job_list becomes child->family->job_list
269 /* built-in 'cd <path>' handler */
270 static int builtin_cd(struct child_prog *child)
274 if (child->argv[1] == NULL)
275 newdir = getenv("HOME");
277 newdir = child->argv[1];
279 printf("cd: %s: %s\n", newdir, strerror(errno));
282 getcwd(cwd, sizeof(char)*MAX_LINE);
287 /* built-in 'env' handler */
288 static int builtin_env(struct child_prog *dummy)
292 for (e = environ; *e; e++) {
298 /* built-in 'exec' handler */
299 static int builtin_exec(struct child_prog *child)
301 if (child->argv[1] == NULL)
302 return EXIT_SUCCESS; /* Really? */
308 /* built-in 'exit' handler */
309 static int builtin_exit(struct child_prog *child)
311 if (child->argv[1] == NULL)
314 exit (atoi(child->argv[1]));
317 /* built-in 'fg' and 'bg' handler */
318 static int builtin_fg_bg(struct child_prog *child)
321 struct job *job=NULL;
323 if (!child->argv[1] || child->argv[2]) {
324 error_msg("%s: exactly one argument is expected\n",
329 if (sscanf(child->argv[1], "%%%d", &jobNum) != 1) {
330 error_msg("%s: bad argument '%s'\n",
331 child->argv[0], child->argv[1]);
335 for (job = child->family->job_list->head; job; job = job->next) {
336 if (job->jobid == jobNum) {
342 error_msg("%s: unknown job %d\n",
343 child->argv[0], jobNum);
347 if (*child->argv[0] == 'f') {
348 /* Make this job the foreground job */
349 /* suppress messages when run from /linuxrc mag@sysgo.de */
350 if (tcsetpgrp(0, job->pgrp) && errno != ENOTTY)
351 perror_msg("tcsetpgrp");
352 child->family->job_list->fg = job;
355 /* Restart the processes in the job */
356 for (i = 0; i < job->num_progs; i++)
357 job->progs[i].is_stopped = 0;
359 kill(-job->pgrp, SIGCONT);
361 job->stopped_progs = 0;
366 /* built-in 'help' handler */
367 static int builtin_help(struct child_prog *dummy)
369 struct built_in_command *x;
371 printf("\nBuilt-in commands:\n");
372 printf("-------------------\n");
373 for (x = bltins; x->cmd; x++) {
376 printf("%s\t%s\n", x->cmd, x->descr);
378 for (x = bltins_forking; x->cmd; x++) {
381 printf("%s\t%s\n", x->cmd, x->descr);
387 /* built-in 'jobs' handler */
388 static int builtin_jobs(struct child_prog *child)
393 for (job = child->family->job_list->head; job; job = job->next) {
394 if (job->running_progs == job->stopped_progs)
395 status_string = "Stopped";
397 status_string = "Running";
399 printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->text);
405 /* built-in 'pwd' handler */
406 static int builtin_pwd(struct child_prog *dummy)
408 getcwd(cwd, MAX_LINE);
409 printf( "%s\n", cwd);
413 /* built-in 'export VAR=value' handler */
414 static int builtin_export(struct child_prog *child)
418 if (child->argv[1] == NULL) {
419 return (builtin_env(child));
421 res = putenv(child->argv[1]);
423 fprintf(stderr, "export: %s\n", strerror(errno));
427 /* built-in 'read VAR' handler */
428 static int builtin_read(struct child_prog *child)
430 int res = 0, len, newlen;
432 char string[MAX_READ];
434 if (child->argv[1]) {
435 /* argument (VAR) given: put "VAR=" into buffer */
436 strcpy(string, child->argv[1]);
437 len = strlen(string);
440 fgets(&string[len], sizeof(string) - len, stdin); /* read string */
441 newlen = strlen(string);
443 string[--newlen] = '\0'; /* chomp trailing newline */
445 ** string should now contain "VAR=<value>"
446 ** copy it (putenv() won't do that, so we must make sure
447 ** the string resides in a static buffer!)
450 if((s = strdup(string)))
453 fprintf(stderr, "read: %s\n", strerror(errno));
456 fgets(string, sizeof(string), stdin);
461 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
462 /* Built-in handler for 'if' commands */
463 static int builtin_if(struct child_prog *child)
465 struct job *cmd = child->family;
467 char* charptr1=cmd->text+3; /* skip over the leading 'if ' */
469 /* Now run the 'if' command */
470 debug_printf( "job=%p entering builtin_if ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
471 status = run_command_predicate(charptr1);
472 debug_printf( "if test returned ");
474 debug_printf( "TRUE\n");
475 cmd->job_context |= IF_TRUE_CONTEXT;
477 debug_printf( "FALSE\n");
478 cmd->job_context |= IF_FALSE_CONTEXT;
480 debug_printf("job=%p builtin_if set job context to %x\n", cmd, cmd->job_context);
486 /* Built-in handler for 'then' (part of the 'if' command) */
487 static int builtin_then(struct child_prog *child)
489 struct job *cmd = child->family;
490 char* charptr1=cmd->text+5; /* skip over the leading 'then ' */
492 debug_printf( "job=%p entering builtin_then ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
493 if (! (cmd->job_context & (IF_TRUE_CONTEXT|IF_FALSE_CONTEXT))) {
494 shell_context = 0; /* Reset the shell's context on an error */
495 error_msg("%s `then'\n", syntax_err);
499 cmd->job_context |= THEN_EXP_CONTEXT;
500 debug_printf("job=%p builtin_then set job context to %x\n", cmd, cmd->job_context);
502 /* If the if result was FALSE, skip the 'then' stuff */
503 if (cmd->job_context & IF_FALSE_CONTEXT) {
507 /* Seems the if result was TRUE, so run the 'then' command */
508 debug_printf( "'then' now running '%s'\n", charptr1);
510 return(run_command_predicate(charptr1));
513 /* Built-in handler for 'else' (part of the 'if' command) */
514 static int builtin_else(struct child_prog *child)
516 struct job *cmd = child->family;
517 char* charptr1=cmd->text+5; /* skip over the leading 'else ' */
519 debug_printf( "job=%p entering builtin_else ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
521 if (! (cmd->job_context & THEN_EXP_CONTEXT)) {
522 shell_context = 0; /* Reset the shell's context on an error */
523 error_msg("%s `else'\n", syntax_err);
526 /* If the if result was TRUE, skip the 'else' stuff */
527 if (cmd->job_context & IF_TRUE_CONTEXT) {
531 cmd->job_context |= ELSE_EXP_CONTEXT;
532 debug_printf("job=%p builtin_else set job context to %x\n", cmd, cmd->job_context);
534 /* Now run the 'else' command */
535 debug_printf( "'else' now running '%s'\n", charptr1);
536 return(run_command_predicate(charptr1));
539 /* Built-in handler for 'fi' (part of the 'if' command) */
540 static int builtin_fi(struct child_prog *child)
542 struct job *cmd = child->family;
543 debug_printf( "job=%p entering builtin_fi ('%s')-- context=%d\n", cmd, "", cmd->job_context);
544 if (! (cmd->job_context & (IF_TRUE_CONTEXT|IF_FALSE_CONTEXT))) {
545 shell_context = 0; /* Reset the shell's context on an error */
546 error_msg("%s `fi'\n", syntax_err);
549 /* Clear out the if and then context bits */
550 cmd->job_context &= ~(IF_TRUE_CONTEXT|IF_FALSE_CONTEXT|THEN_EXP_CONTEXT|ELSE_EXP_CONTEXT);
551 debug_printf("job=%p builtin_fi set job context to %x\n", cmd, cmd->job_context);
557 /* Built-in '.' handler (read-in and execute commands from file) */
558 static int builtin_source(struct child_prog *child)
564 if (child->argv[1] == NULL)
567 input = fopen(child->argv[1], "r");
569 printf( "Couldn't open file '%s'\n", child->argv[1]);
575 /* Now run the file */
576 status = busy_loop(input);
582 /* built-in 'unset VAR' handler */
583 static int builtin_unset(struct child_prog *child)
585 if (child->argv[1] == NULL) {
586 printf( "unset: parameter required.\n");
589 unsetenv(child->argv[1]);
593 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
594 /* currently used by if/then/else.
596 * Reparsing the command line for this purpose is gross,
597 * incorrect, and fundamentally unfixable; in particular,
598 * think about what happens with command substitution.
599 * We really need to pull out the run, wait, return status
600 * functionality out of busy_loop so we can child->argv++
601 * and use that, without going back through parse_command.
603 static int run_command_predicate(char *cmd)
606 local_pending_command = xmalloc(n+1);
607 strncpy(local_pending_command, cmd, n);
608 local_pending_command[n]='\0';
609 return( busy_loop(NULL));
613 static void mark_open(int fd)
615 struct close_me *new = xmalloc(sizeof(struct close_me));
617 new->next = close_me_head;
621 static void mark_closed(int fd)
623 struct close_me *tmp;
624 if (close_me_head == NULL || close_me_head->fd != fd)
625 error_msg_and_die("corrupt close_me");
627 close_me_head = close_me_head->next;
631 static void close_all()
634 for (c=close_me_head; c; c=c->next) {
637 close_me_head = NULL;
641 /* free up all memory from a job */
642 static void free_job(struct job *cmd)
646 for (i = 0; i < cmd->num_progs; i++) {
647 free(cmd->progs[i].argv);
648 if (cmd->progs[i].redirects)
649 free(cmd->progs[i].redirects);
650 if (cmd->progs[i].free_glob)
651 globfree(&cmd->progs[i].glob_result);
657 memset(cmd, 0, sizeof(struct job));
660 /* remove a job from the job_list */
661 static void remove_job(struct jobset *job_list, struct job *job)
666 if (job == job_list->head) {
667 job_list->head = job->next;
669 prevjob = job_list->head;
670 while (prevjob->next != job)
671 prevjob = prevjob->next;
672 prevjob->next = job->next;
678 /* Checks to see if any background processes have exited -- if they
679 have, figure out why and see if a job has completed */
680 static void checkjobs(struct jobset *job_list)
687 while ((childpid = waitpid(-1, &status, WNOHANG | WUNTRACED)) > 0) {
688 for (job = job_list->head; job; job = job->next) {
690 while (prognum < job->num_progs &&
691 job->progs[prognum].pid != childpid) prognum++;
692 if (prognum < job->num_progs)
696 /* This happens on backticked commands */
700 if (WIFEXITED(status) || WIFSIGNALED(status)) {
702 job->running_progs--;
703 job->progs[prognum].pid = 0;
705 if (!job->running_progs) {
706 printf(JOB_STATUS_FORMAT, job->jobid, "Done", job->text);
707 remove_job(job_list, job);
711 job->stopped_progs++;
712 job->progs[prognum].is_stopped = 1;
714 if (job->stopped_progs == job->num_progs) {
715 printf(JOB_STATUS_FORMAT, job->jobid, "Stopped",
721 if (childpid == -1 && errno != ECHILD)
722 perror_msg("waitpid");
725 /* squirrel != NULL means we squirrel away copies of stdin, stdout,
726 * and stderr if they are redirected. */
727 static int setup_redirects(struct child_prog *prog, int squirrel[])
732 struct redir_struct *redir = prog->redirects;
734 for (i = 0; i < prog->num_redirects; i++, redir++) {
735 switch (redir->type) {
739 case REDIRECT_OVERWRITE:
740 mode = O_WRONLY | O_CREAT | O_TRUNC;
742 case REDIRECT_APPEND:
743 mode = O_WRONLY | O_CREAT | O_APPEND;
747 openfd = open(redir->filename, mode, 0666);
749 /* this could get lost if stderr has been redirected, but
750 bash and ash both lose it as well (though zsh doesn't!) */
751 error_msg("error opening %s: %s\n", redir->filename,
756 if (openfd != redir->fd) {
757 if (squirrel && redir->fd < 3) {
758 squirrel[redir->fd] = dup(redir->fd);
760 dup2(openfd, redir->fd);
768 static void restore_redirects(int squirrel[])
771 for (i=0; i<3; i++) {
774 /* No error checking. I sure wouldn't know what
775 * to do with an error if I found one! */
782 #if defined(BB_FEATURE_SH_SIMPLE_PROMPT)
783 static char* setup_prompt_string(int state)
785 char prompt_str[BUFSIZ];
787 /* Set up the prompt */
790 sprintf(prompt_str, "%s %s", cwd, ( geteuid() != 0 ) ? "$ ":"# ");
792 strcpy(prompt_str,"> ");
795 return(strdup(prompt_str)); /* Must free this memory */
800 static char* setup_prompt_string(int state)
802 char user[9],buf[255],*s;
804 char prompt_str[BUFSIZ];
806 /* Set up the prompt */
808 /* get User Name and setup prompt */
809 strcpy(prompt,( geteuid() != 0 ) ? "$ ":"# ");
810 my_getpwuid(user, geteuid());
813 gethostname(buf, 255);
814 s = strchr(buf, '.');
823 snprintf(prompt_str, BUFSIZ-1, "[%s@%s %s]%s", user, buf,
824 get_last_path_component(cwd), prompt);
826 sprintf(prompt_str, "%s", prompt);
828 return(strdup(prompt_str)); /* Must free this memory */
833 static int get_command(FILE * source, char *command)
837 if (source == NULL) {
838 if (local_pending_command) {
839 /* a command specified (-c option): return it & mark it done */
840 strcpy(command, local_pending_command);
841 free(local_pending_command);
842 local_pending_command = NULL;
848 if (source == stdin) {
849 prompt_str = setup_prompt_string(shell_context);
851 #ifdef BB_FEATURE_SH_COMMAND_EDITING
853 ** enable command line editing only while a command line
854 ** is actually being read; otherwise, we'll end up bequeathing
855 ** atexit() handlers and other unwanted stuff to our
856 ** child processes (rob@sysgo.de)
859 cmdedit_read_input(prompt_str, command);
864 fputs(prompt_str, stdout);
869 if (!fgets(command, BUFSIZ - 2, source)) {
875 /* remove trailing newline */
876 command[strlen(command) - 1] = '\0';
881 #ifdef BB_FEATURE_SH_ENVIRONMENT
882 static char* itoa(register int i)
884 static char a[7]; /* Max 7 ints */
885 register char *b = a + sizeof(a) - 1;
893 *--b = '0' + (i % 10);
903 static void expand_argument(struct child_prog *prog, int *argcPtr,
904 int *argv_alloced_ptr)
906 int argc_l = *argcPtr;
907 int argv_alloced = *argv_alloced_ptr;
911 char *src, *dst, *var;
913 if (argc_l > 1) { /* cmd->glob_result is already initialized */
915 i = prog->glob_result.gl_pathc;
921 /* do shell variable substitution */
922 if(*prog->argv[argc_l - 1] == '$') {
923 if ((var = getenv(prog->argv[argc_l - 1] + 1))) {
924 prog->argv[argc_l - 1] = var;
926 #ifdef BB_FEATURE_SH_ENVIRONMENT
928 switch(*(prog->argv[argc_l - 1] + 1)) {
930 prog->argv[argc_l - 1] = itoa(last_return_code);
933 prog->argv[argc_l - 1] = itoa(getpid());
936 prog->argv[argc_l - 1] = itoa(argc-1);
940 *(prog->argv[argc_l - 1])='\0';
942 prog->argv[argc_l - 1] = itoa(last_bg_pid);
944 case '0':case '1':case '2':case '3':case '4':
945 case '5':case '6':case '7':case '8':case '9':
947 int index=*(prog->argv[argc_l - 1] + 1)-48;
949 *(prog->argv[argc_l - 1])='\0';
951 prog->argv[argc_l - 1] = argv[index];
960 if (strpbrk(prog->argv[argc_l - 1],"*[]?")!= NULL){
961 rc = glob(prog->argv[argc_l - 1], flags, NULL, &prog->glob_result);
962 if (rc == GLOB_NOSPACE) {
963 error_msg("out of space during glob operation\n");
965 } else if (rc == GLOB_NOMATCH ||
966 (!rc && (prog->glob_result.gl_pathc - i) == 1 &&
967 strcmp(prog->argv[argc_l - 1],
968 prog->glob_result.gl_pathv[i]) == 0)) {
969 /* we need to remove whatever \ quoting is still present */
970 src = dst = prog->argv[argc_l - 1];
974 *dst++ = process_escape_sequence(&src);
982 argv_alloced += (prog->glob_result.gl_pathc - i);
983 prog->argv = xrealloc(prog->argv, argv_alloced * sizeof(*prog->argv));
984 memcpy(prog->argv + (argc_l - 1), prog->glob_result.gl_pathv + i,
985 sizeof(*(prog->argv)) * (prog->glob_result.gl_pathc - i));
986 argc_l += (prog->glob_result.gl_pathc - i - 1);
989 src = dst = prog->argv[argc_l - 1];
993 *dst++ = process_escape_sequence(&src);
1001 prog->glob_result.gl_pathc=0;
1003 prog->glob_result.gl_pathv=NULL;
1005 *argv_alloced_ptr = argv_alloced;
1009 /* Return cmd->num_progs as 0 if no command is present (e.g. an empty
1010 line). If a valid command is found, command_ptr is set to point to
1011 the beginning of the next command (if the original command had more
1012 then one job associated with it) or NULL if no more commands are
1014 static int parse_command(char **command_ptr, struct job *job, int *inbg)
1017 char *return_command = NULL;
1018 char *src, *buf, *chptr;
1025 struct child_prog *prog;
1027 /* skip leading white space */
1028 while (**command_ptr && isspace(**command_ptr))
1031 /* this handles empty lines or leading '#' characters */
1032 if (!**command_ptr || (**command_ptr == '#')) {
1039 job->progs = xmalloc(sizeof(*job->progs));
1041 /* We set the argv elements to point inside of this string. The
1042 memory is freed by free_job(). Allocate twice the original
1043 length in case we need to quote every single character.
1045 Getting clean memory relieves us of the task of NULL
1046 terminating things and makes the rest of this look a bit
1047 cleaner (though it is, admittedly, a tad less efficient) */
1048 job->cmdbuf = command = xcalloc(2*strlen(*command_ptr) + 1, sizeof(char));
1052 prog->num_redirects = 0;
1053 prog->redirects = NULL;
1054 prog->free_glob = 0;
1055 prog->is_stopped = 0;
1059 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1060 prog->argv[0] = job->cmdbuf;
1064 while (*src && !done) {
1065 if (quote == *src) {
1071 error_msg("character expected after \\\n");
1076 /* in shell, "\'" should yield \' */
1077 if (*src != quote) {
1081 } else if (*src == '*' || *src == '?' || *src == '[' ||
1082 *src == ']') *buf++ = '\\';
1084 } else if (isspace(*src)) {
1085 if (*prog->argv[argc_l]) {
1087 /* +1 here leaves room for the NULL which ends argv */
1088 if ((argc_l + 1) == argv_alloced) {
1090 prog->argv = xrealloc(prog->argv,
1091 sizeof(*prog->argv) *
1094 expand_argument(prog, &argc_l, &argv_alloced);
1095 prog->argv[argc_l] = buf;
1104 case '#': /* comment */
1111 case '>': /* redirects */
1113 i = prog->num_redirects++;
1114 prog->redirects = xrealloc(prog->redirects,
1115 sizeof(*prog->redirects) *
1118 prog->redirects[i].fd = -1;
1119 if (buf != prog->argv[argc_l]) {
1120 /* the stuff before this character may be the file number
1122 prog->redirects[i].fd =
1123 strtol(prog->argv[argc_l], &chptr, 10);
1125 if (*chptr && *prog->argv[argc_l]) {
1127 expand_argument(prog, &argc_l, &argv_alloced);
1128 prog->argv[argc_l] = buf;
1132 if (prog->redirects[i].fd == -1) {
1134 prog->redirects[i].fd = 1;
1136 prog->redirects[i].fd = 0;
1139 if (*src++ == '>') {
1141 prog->redirects[i].type =
1142 REDIRECT_APPEND, src++;
1144 prog->redirects[i].type = REDIRECT_OVERWRITE;
1146 prog->redirects[i].type = REDIRECT_INPUT;
1149 /* This isn't POSIX sh compliant. Oh well. */
1151 while (isspace(*chptr))
1155 error_msg("file name expected after %c\n", *src);
1161 prog->redirects[i].filename = buf;
1162 while (*chptr && !isspace(*chptr))
1165 src = chptr - 1; /* we src++ later */
1166 prog->argv[argc_l] = ++buf;
1169 case '|': /* pipe */
1170 /* finish this command */
1171 if (*prog->argv[argc_l])
1174 error_msg("empty command in pipe\n");
1179 prog->argv[argc_l] = NULL;
1181 /* and start the next */
1183 job->progs = xrealloc(job->progs,
1184 sizeof(*job->progs) * job->num_progs);
1185 prog = job->progs + (job->num_progs - 1);
1186 prog->num_redirects = 0;
1187 prog->redirects = NULL;
1188 prog->free_glob = 0;
1189 prog->is_stopped = 0;
1194 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1195 prog->argv[0] = ++buf;
1198 while (*src && isspace(*src))
1202 error_msg("empty command in pipe\n");
1207 src--; /* we'll ++ it at the end of the loop */
1211 case '&': /* background */
1213 case ';': /* multiple commands */
1215 return_command = *command_ptr + (src - *command_ptr) + 1;
1218 #ifdef BB_FEATURE_SH_BACKTICKS
1220 /* Exec a backtick-ed command */
1221 /* Besides any previous brokenness, I have not
1222 * updated backtick handling for close_me support.
1223 * I don't know if it needs it or not. -- LRD */
1225 char* charptr1=NULL, *charptr2;
1228 struct jobset njob_list = { NULL, NULL };
1232 ptr=strchr(++src, '`');
1234 fprintf(stderr, "Unmatched '`' in command\n");
1239 /* Make some space to hold just the backticked command */
1240 charptr1 = charptr2 = xmalloc(1+ptr-src);
1241 memcpy(charptr1, src, ptr-src);
1242 charptr1[ptr-src] = '\0';
1243 newjob = xmalloc(sizeof(struct job));
1244 newjob->job_list = &njob_list;
1245 /* Now parse and run the backticked command */
1246 if (!parse_command(&charptr1, newjob, inbg)
1247 && newjob->num_progs) {
1249 run_command(newjob, 0, pipefd);
1251 checkjobs(job->job_list);
1252 free_job(newjob); /* doesn't actually free newjob,
1253 looks like a memory leak */
1256 /* Make a copy of any stuff left over in the command
1257 * line after the second backtick */
1258 charptr2 = xmalloc(strlen(ptr)+1);
1259 memcpy(charptr2, ptr+1, strlen(ptr));
1262 /* Copy the output from the backtick-ed command into the
1263 * command line, making extra room as needed */
1265 charptr1 = xmalloc(BUFSIZ);
1266 while ( (size=full_read(pipefd[0], charptr1, BUFSIZ-1)) >0) {
1267 int newsize=src - *command_ptr + size + 1 + strlen(charptr2);
1268 if (newsize > BUFSIZ) {
1269 *command_ptr=xrealloc(*command_ptr, newsize);
1271 memcpy(src, charptr1, size);
1279 /* Now paste into the *command_ptr all the stuff
1280 * leftover after the second backtick */
1281 memcpy(src, charptr2, strlen(charptr2)+1);
1284 /* Now recursively call parse_command to deal with the new
1285 * and improved version of the command line with the backtick
1286 * results expanded in place... */
1288 struct jobset *jl=job->job_list;
1292 return(parse_command(command_ptr, job, inbg));
1295 #endif // BB_FEATURE_SH_BACKTICKS
1300 /* This is currently a little broken... */
1301 #ifdef HANDLE_CONTINUATION_CHARS
1302 /* They fed us a continuation char, so continue reading stuff
1303 * on the next line, then tack that onto the end of the current
1307 printf("erik: found a continue char at EOL...\n");
1308 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1309 if (get_command(input, command)) {
1310 error_msg("character expected after \\\n");
1315 newsize = strlen(*command_ptr) + strlen(command) + 2;
1316 if (newsize > BUFSIZ) {
1317 printf("erik: doing realloc\n");
1318 *command_ptr=xrealloc(*command_ptr, newsize);
1320 printf("erik: A: *command_ptr='%s'\n", *command_ptr);
1321 memcpy(--src, command, strlen(command));
1322 printf("erik: B: *command_ptr='%s'\n", *command_ptr);
1326 error_msg("character expected after \\\n");
1332 if (*src == '*' || *src == '[' || *src == ']'
1333 || *src == '?') *buf++ = '\\';
1342 if (*prog->argv[argc_l]) {
1344 expand_argument(prog, &argc_l, &argv_alloced);
1350 prog->argv[argc_l] = NULL;
1352 if (!return_command) {
1353 job->text = xmalloc(strlen(*command_ptr) + 1);
1354 strcpy(job->text, *command_ptr);
1356 /* This leaves any trailing spaces, which is a bit sloppy */
1357 count = return_command - *command_ptr;
1358 job->text = xmalloc(count + 1);
1359 strncpy(job->text, *command_ptr, count);
1360 job->text[count] = '\0';
1363 *command_ptr = return_command;
1368 /* Run the child_prog, no matter what kind of command it uses.
1370 static int pseudo_exec(struct child_prog *child)
1372 struct built_in_command *x;
1373 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
1374 struct BB_applet search_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 search_applet.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 search_applet.name = get_last_path_component(search_applet.name);
1418 /* Do a binary search to find the applet entry given the name. */
1419 applet = bsearch(&search_applet, applets, NUM_APPLETS,
1420 sizeof(struct BB_applet), applet_name_compare);
1421 if (applet != NULL) {
1423 char** argv=child->argv;
1424 for(argc_l=0;*argv!=NULL; argv++, argc_l++);
1425 applet_name=applet->name;
1427 exit((*(applet->main)) (argc_l, child->argv));
1431 execvp(child->argv[0], child->argv);
1432 perror_msg_and_die("%s", child->argv[0]);
1435 static void insert_job(struct job *newjob, int inbg)
1438 struct jobset *job_list=newjob->job_list;
1440 /* find the ID for thejob to use */
1442 for (thejob = job_list->head; thejob; thejob = thejob->next)
1443 if (thejob->jobid >= newjob->jobid)
1444 newjob->jobid = thejob->jobid + 1;
1446 /* add thejob to the list of running jobs */
1447 if (!job_list->head) {
1448 thejob = job_list->head = xmalloc(sizeof(*thejob));
1450 for (thejob = job_list->head; thejob->next; thejob = thejob->next) /* nothing */;
1451 thejob->next = xmalloc(sizeof(*thejob));
1452 thejob = thejob->next;
1455 *thejob = *newjob; /* physically copy the struct job */
1456 thejob->next = NULL;
1457 thejob->running_progs = thejob->num_progs;
1458 thejob->stopped_progs = 0;
1461 /* we don't wait for background thejobs to return -- append it
1462 to the list of backgrounded thejobs and leave it alone */
1463 printf("[%d] %d\n", thejob->jobid,
1464 newjob->progs[newjob->num_progs - 1].pid);
1465 #ifdef BB_FEATURE_SH_ENVIRONMENT
1466 last_bg_pid=newjob->progs[newjob->num_progs - 1].pid;
1469 newjob->job_list->fg = thejob;
1471 /* move the new process group into the foreground */
1472 /* suppress messages when run from /linuxrc mag@sysgo.de */
1473 if (tcsetpgrp(0, newjob->pgrp) && errno != ENOTTY)
1474 perror_msg("tcsetpgrp");
1478 static int run_command(struct job *newjob, int inbg, int outpipe[2])
1480 /* struct job *thejob; */
1482 int nextin, nextout;
1483 int pipefds[2]; /* pipefd[0] is for reading */
1484 struct built_in_command *x;
1485 struct child_prog *child;
1487 nextin = 0, nextout = 1;
1488 for (i = 0; i < newjob->num_progs; i++) {
1489 child = & (newjob->progs[i]);
1491 if ((i + 1) < newjob->num_progs) {
1492 if (pipe(pipefds)<0) perror_msg_and_die("pipe");
1493 nextout = pipefds[1];
1495 if (outpipe[1]!=-1) {
1496 nextout = outpipe[1];
1502 #ifdef BB_FEATURE_SH_ENVIRONMENT
1503 if (show_x_trace==TRUE) {
1506 for (j = 0; child->argv[j]; j++) {
1508 fputs(child->argv[j], stderr);
1510 fputc('\n', stderr);
1514 /* Check if the command matches any non-forking builtins,
1515 * but only if this is a simple command.
1516 * Non-forking builtins within pipes have to fork anyway,
1517 * and are handled in pseudo_exec. "echo foo | read bar"
1518 * is doomed to failure, and doesn't work on bash, either.
1520 if (newjob->num_progs == 1) {
1521 for (x = bltins; x->cmd; x++) {
1522 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1523 int squirrel[] = {-1, -1, -1};
1525 setup_redirects(child, squirrel);
1526 rcode = x->function(child);
1527 restore_redirects(squirrel);
1533 if (!(child->pid = fork())) {
1534 signal(SIGTTOU, SIG_DFL);
1538 if (outpipe[1]!=-1) {
1548 dup2(nextout, 2); /* Really? */
1553 /* explicit redirects override pipes */
1554 setup_redirects(child,NULL);
1558 if (outpipe[1]!=-1) {
1562 /* put our child in the process group whose leader is the
1563 first process in this pipe */
1564 setpgid(child->pid, newjob->progs[0].pid);
1570 /* If there isn't another process, nextin is garbage
1571 but it doesn't matter */
1572 nextin = pipefds[0];
1575 newjob->pgrp = newjob->progs[0].pid;
1577 insert_job(newjob, inbg);
1582 static int busy_loop(FILE * input)
1585 char *next_command = NULL;
1591 newjob.job_list = &job_list;
1592 newjob.job_context = DEFAULT_CONTEXT;
1594 /* save current owner of TTY so we can restore it on exit */
1595 parent_pgrp = tcgetpgrp(0);
1597 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1599 /* don't pay any attention to this signal; it just confuses
1600 things and isn't really meant for shells anyway */
1601 signal(SIGTTOU, SIG_IGN);
1605 /* no job is in the foreground */
1607 /* see if any background processes have exited */
1608 checkjobs(&job_list);
1610 if (!next_command) {
1611 if (get_command(input, command))
1613 next_command = command;
1616 if (!parse_command(&next_command, &newjob, &inbg) &&
1618 int pipefds[2] = {-1,-1};
1619 debug_printf( "job=%p being fed to run_command by busy_loop()'\n", &newjob);
1620 run_command(&newjob, inbg, pipefds);
1624 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1625 next_command = NULL;
1628 /* a job is running in the foreground; wait for it */
1630 while (!job_list.fg->progs[i].pid ||
1631 job_list.fg->progs[i].is_stopped == 1) i++;
1633 if (waitpid(job_list.fg->progs[i].pid, &status, WUNTRACED)<0)
1634 perror_msg_and_die("waitpid(%d)",job_list.fg->progs[i].pid);
1636 if (WIFEXITED(status) || WIFSIGNALED(status)) {
1637 /* the child exited */
1638 job_list.fg->running_progs--;
1639 job_list.fg->progs[i].pid = 0;
1641 #ifdef BB_FEATURE_SH_ENVIRONMENT
1642 last_return_code=WEXITSTATUS(status);
1644 debug_printf("'%s' exited -- return code %d\n",
1645 job_list.fg->text, last_return_code);
1646 if (!job_list.fg->running_progs) {
1648 remove_job(&job_list, job_list.fg);
1652 /* the child was stopped */
1653 job_list.fg->stopped_progs++;
1654 job_list.fg->progs[i].is_stopped = 1;
1656 if (job_list.fg->stopped_progs == job_list.fg->running_progs) {
1657 printf("\n" JOB_STATUS_FORMAT, job_list.fg->jobid,
1658 "Stopped", job_list.fg->text);
1664 /* move the shell to the foreground */
1665 /* suppress messages when run from /linuxrc mag@sysgo.de */
1666 if (tcsetpgrp(0, getpid()) && errno != ENOTTY)
1667 perror_msg("tcsetpgrp");
1673 /* return controlling TTY back to parent process group before exiting */
1674 if (tcsetpgrp(0, parent_pgrp))
1675 perror_msg("tcsetpgrp");
1677 /* return exit status if called with "-c" */
1678 if (input == NULL && WIFEXITED(status))
1679 return WEXITSTATUS(status);
1685 #ifdef BB_FEATURE_CLEAN_UP
1686 void free_memory(void)
1690 if (local_pending_command)
1691 free(local_pending_command);
1693 if (job_list.fg && !job_list.fg->running_progs) {
1694 remove_job(&job_list, job_list.fg);
1700 int shell_main(int argc_l, char **argv_l)
1702 int opt, interactive=FALSE;
1703 FILE *input = stdin;
1709 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
1710 /* These variables need re-initializing when recursing */
1711 local_pending_command = NULL;
1712 job_list.head = NULL;
1714 #ifdef BB_FEATURE_SH_ENVIRONMENT
1716 last_return_code=-1;
1721 if (argv[0] && argv[0][0] == '-') {
1723 prof_input = fopen("/etc/profile", "r");
1725 printf( "Couldn't open file '/etc/profile'\n");
1727 int tmp_fd = fileno(prof_input);
1729 /* Now run the file */
1730 busy_loop(prof_input);
1732 mark_closed(tmp_fd);
1736 while ((opt = getopt(argc_l, argv_l, "cxi")) > 0) {
1740 if (local_pending_command != 0)
1741 error_msg_and_die("multiple -c arguments\n");
1742 local_pending_command = xstrdup(argv[optind]);
1746 #ifdef BB_FEATURE_SH_ENVIRONMENT
1748 show_x_trace = TRUE;
1758 /* A shell is interactive if the `-i' flag was given, or if all of
1759 * the following conditions are met:
1761 * no arguments remaining or the -s flag given
1762 * standard input is a terminal
1763 * standard output is a terminal
1764 * Refer to Posix.2, the description of the `sh' utility. */
1765 if (argv[optind]==NULL && input==stdin &&
1766 isatty(fileno(stdin)) && isatty(fileno(stdout))) {
1769 if (interactive==TRUE) {
1770 //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
1771 /* Looks like they want an interactive shell */
1772 printf( "\n\nBusyBox v%s (%s) Built-in shell (lash)\n", BB_VER, BB_BT);
1773 printf( "Enter 'help' for a list of built-in commands.\n\n");
1774 } else if (local_pending_command==NULL) {
1775 //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
1776 input = xfopen(argv[optind], "r");
1777 mark_open(fileno(input)); /* be lazy, never mark this closed */
1780 /* initialize the cwd -- this is never freed...*/
1781 cwd=(char*)xmalloc(sizeof(char)*MAX_LINE+1);
1782 getcwd(cwd, sizeof(char)*MAX_LINE);
1784 #ifdef BB_FEATURE_CLEAN_UP
1785 atexit(free_memory);
1788 return (busy_loop(input));