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...
60 #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 close_all(void);
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;
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? */
309 /* built-in 'exit' handler */
310 static int builtin_exit(struct child_prog *child)
312 if (child->argv[1] == NULL)
315 exit (atoi(child->argv[1]));
318 /* built-in 'fg' and 'bg' handler */
319 static int builtin_fg_bg(struct child_prog *child)
322 struct job *job=NULL;
324 if (!child->argv[1] || child->argv[2]) {
325 error_msg("%s: exactly one argument is expected",
330 if (sscanf(child->argv[1], "%%%d", &jobNum) != 1) {
331 error_msg("%s: bad argument '%s'",
332 child->argv[0], child->argv[1]);
336 for (job = child->family->job_list->head; job; job = job->next) {
337 if (job->jobid == jobNum) {
343 error_msg("%s: unknown job %d",
344 child->argv[0], jobNum);
348 if (*child->argv[0] == 'f') {
349 /* Make this job the foreground job */
350 /* suppress messages when run from /linuxrc mag@sysgo.de */
351 if (tcsetpgrp(0, job->pgrp) && errno != ENOTTY)
352 perror_msg("tcsetpgrp");
353 child->family->job_list->fg = job;
356 /* Restart the processes in the job */
357 for (i = 0; i < job->num_progs; i++)
358 job->progs[i].is_stopped = 0;
360 kill(-job->pgrp, SIGCONT);
362 job->stopped_progs = 0;
367 /* built-in 'help' handler */
368 static int builtin_help(struct child_prog *dummy)
370 struct built_in_command *x;
372 printf("\nBuilt-in commands:\n");
373 printf("-------------------\n");
374 for (x = bltins; x->cmd; x++) {
377 printf("%s\t%s\n", x->cmd, x->descr);
379 for (x = bltins_forking; x->cmd; x++) {
382 printf("%s\t%s\n", x->cmd, x->descr);
388 /* built-in 'jobs' handler */
389 static int builtin_jobs(struct child_prog *child)
394 for (job = child->family->job_list->head; job; job = job->next) {
395 if (job->running_progs == job->stopped_progs)
396 status_string = "Stopped";
398 status_string = "Running";
400 printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->text);
406 /* built-in 'pwd' handler */
407 static int builtin_pwd(struct child_prog *dummy)
409 getcwd(cwd, MAX_LINE);
410 printf( "%s\n", cwd);
414 /* built-in 'export VAR=value' handler */
415 static int builtin_export(struct child_prog *child)
419 if (child->argv[1] == NULL) {
420 return (builtin_env(child));
422 res = putenv(child->argv[1]);
424 fprintf(stderr, "export: %s\n", strerror(errno));
428 /* built-in 'read VAR' handler */
429 static int builtin_read(struct child_prog *child)
431 int res = 0, len, newlen;
433 char string[MAX_READ];
435 if (child->argv[1]) {
436 /* argument (VAR) given: put "VAR=" into buffer */
437 strcpy(string, child->argv[1]);
438 len = strlen(string);
441 fgets(&string[len], sizeof(string) - len, stdin); /* read string */
442 newlen = strlen(string);
444 string[--newlen] = '\0'; /* chomp trailing newline */
446 ** string should now contain "VAR=<value>"
447 ** copy it (putenv() won't do that, so we must make sure
448 ** the string resides in a static buffer!)
451 if((s = strdup(string)))
454 fprintf(stderr, "read: %s\n", strerror(errno));
457 fgets(string, sizeof(string), stdin);
462 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
463 /* Built-in handler for 'if' commands */
464 static int builtin_if(struct child_prog *child)
466 struct job *cmd = child->family;
468 char* charptr1=cmd->text+3; /* skip over the leading 'if ' */
470 /* Now run the 'if' command */
471 debug_printf( "job=%p entering builtin_if ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
472 status = run_command_predicate(charptr1);
473 debug_printf( "if test returned ");
475 debug_printf( "TRUE\n");
476 cmd->job_context |= IF_TRUE_CONTEXT;
478 debug_printf( "FALSE\n");
479 cmd->job_context |= IF_FALSE_CONTEXT;
481 debug_printf("job=%p builtin_if set job context to %x\n", cmd, cmd->job_context);
487 /* Built-in handler for 'then' (part of the 'if' command) */
488 static int builtin_then(struct child_prog *child)
490 struct job *cmd = child->family;
491 char* charptr1=cmd->text+5; /* skip over the leading 'then ' */
493 debug_printf( "job=%p entering builtin_then ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
494 if (! (cmd->job_context & (IF_TRUE_CONTEXT|IF_FALSE_CONTEXT))) {
495 shell_context = 0; /* Reset the shell's context on an error */
496 error_msg("%s `then'", syntax_err);
500 cmd->job_context |= THEN_EXP_CONTEXT;
501 debug_printf("job=%p builtin_then set job context to %x\n", cmd, cmd->job_context);
503 /* If the if result was FALSE, skip the 'then' stuff */
504 if (cmd->job_context & IF_FALSE_CONTEXT) {
508 /* Seems the if result was TRUE, so run the 'then' command */
509 debug_printf( "'then' now running '%s'\n", charptr1);
511 return(run_command_predicate(charptr1));
514 /* Built-in handler for 'else' (part of the 'if' command) */
515 static int builtin_else(struct child_prog *child)
517 struct job *cmd = child->family;
518 char* charptr1=cmd->text+5; /* skip over the leading 'else ' */
520 debug_printf( "job=%p entering builtin_else ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
522 if (! (cmd->job_context & THEN_EXP_CONTEXT)) {
523 shell_context = 0; /* Reset the shell's context on an error */
524 error_msg("%s `else'", syntax_err);
527 /* If the if result was TRUE, skip the 'else' stuff */
528 if (cmd->job_context & IF_TRUE_CONTEXT) {
532 cmd->job_context |= ELSE_EXP_CONTEXT;
533 debug_printf("job=%p builtin_else set job context to %x\n", cmd, cmd->job_context);
535 /* Now run the 'else' command */
536 debug_printf( "'else' now running '%s'\n", charptr1);
537 return(run_command_predicate(charptr1));
540 /* Built-in handler for 'fi' (part of the 'if' command) */
541 static int builtin_fi(struct child_prog *child)
543 struct job *cmd = child->family;
544 debug_printf( "job=%p entering builtin_fi ('%s')-- context=%d\n", cmd, "", cmd->job_context);
545 if (! (cmd->job_context & (IF_TRUE_CONTEXT|IF_FALSE_CONTEXT))) {
546 shell_context = 0; /* Reset the shell's context on an error */
547 error_msg("%s `fi'", syntax_err);
550 /* Clear out the if and then context bits */
551 cmd->job_context &= ~(IF_TRUE_CONTEXT|IF_FALSE_CONTEXT|THEN_EXP_CONTEXT|ELSE_EXP_CONTEXT);
552 debug_printf("job=%p builtin_fi set job context to %x\n", cmd, cmd->job_context);
558 /* Built-in '.' handler (read-in and execute commands from file) */
559 static int builtin_source(struct child_prog *child)
565 if (child->argv[1] == NULL)
568 input = fopen(child->argv[1], "r");
570 printf( "Couldn't open file '%s'\n", child->argv[1]);
576 /* Now run the file */
577 status = busy_loop(input);
583 /* built-in 'unset VAR' handler */
584 static int builtin_unset(struct child_prog *child)
586 if (child->argv[1] == NULL) {
587 printf( "unset: parameter required.\n");
590 unsetenv(child->argv[1]);
594 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
595 /* currently used by if/then/else.
597 * Reparsing the command line for this purpose is gross,
598 * incorrect, and fundamentally unfixable; in particular,
599 * think about what happens with command substitution.
600 * We really need to pull out the run, wait, return status
601 * functionality out of busy_loop so we can child->argv++
602 * and use that, without going back through parse_command.
604 static int run_command_predicate(char *cmd)
607 local_pending_command = xmalloc(n+1);
608 strncpy(local_pending_command, cmd, n);
609 local_pending_command[n]='\0';
610 return( busy_loop(NULL));
614 static void mark_open(int fd)
616 struct close_me *new = xmalloc(sizeof(struct close_me));
618 new->next = close_me_head;
622 static void mark_closed(int fd)
624 struct close_me *tmp;
625 if (close_me_head == NULL || close_me_head->fd != fd)
626 error_msg_and_die("corrupt close_me");
628 close_me_head = close_me_head->next;
632 static void close_all()
635 struct close_me *c, *tmp;
636 for (c=close_me_head; c; c=tmp) {
641 close_me_head = NULL;
645 /* free up all memory from a job */
646 static void free_job(struct job *cmd)
650 for (i = 0; i < cmd->num_progs; i++) {
651 free(cmd->progs[i].argv);
652 if (cmd->progs[i].redirects)
653 free(cmd->progs[i].redirects);
654 if (cmd->progs[i].free_glob)
655 globfree(&cmd->progs[i].glob_result);
661 memset(cmd, 0, sizeof(struct job));
664 /* remove a job from the job_list */
665 static void remove_job(struct jobset *job_list, struct job *job)
670 if (job == job_list->head) {
671 job_list->head = job->next;
673 prevjob = job_list->head;
674 while (prevjob->next != job)
675 prevjob = prevjob->next;
676 prevjob->next = job->next;
682 /* Checks to see if any background processes have exited -- if they
683 have, figure out why and see if a job has completed */
684 static void checkjobs(struct jobset *job_list)
691 while ((childpid = waitpid(-1, &status, WNOHANG | WUNTRACED)) > 0) {
692 for (job = job_list->head; job; job = job->next) {
694 while (prognum < job->num_progs &&
695 job->progs[prognum].pid != childpid) prognum++;
696 if (prognum < job->num_progs)
700 /* This happens on backticked commands */
704 if (WIFEXITED(status) || WIFSIGNALED(status)) {
706 job->running_progs--;
707 job->progs[prognum].pid = 0;
709 if (!job->running_progs) {
710 printf(JOB_STATUS_FORMAT, job->jobid, "Done", job->text);
711 remove_job(job_list, job);
715 job->stopped_progs++;
716 job->progs[prognum].is_stopped = 1;
718 if (job->stopped_progs == job->num_progs) {
719 printf(JOB_STATUS_FORMAT, job->jobid, "Stopped",
725 if (childpid == -1 && errno != ECHILD)
726 perror_msg("waitpid");
729 /* squirrel != NULL means we squirrel away copies of stdin, stdout,
730 * and stderr if they are redirected. */
731 static int setup_redirects(struct child_prog *prog, int squirrel[])
736 struct redir_struct *redir = prog->redirects;
738 for (i = 0; i < prog->num_redirects; i++, redir++) {
739 switch (redir->type) {
743 case REDIRECT_OVERWRITE:
744 mode = O_WRONLY | O_CREAT | O_TRUNC;
746 case REDIRECT_APPEND:
747 mode = O_WRONLY | O_CREAT | O_APPEND;
751 openfd = open(redir->filename, mode, 0666);
753 /* this could get lost if stderr has been redirected, but
754 bash and ash both lose it as well (though zsh doesn't!) */
755 error_msg("error opening %s: %s", redir->filename,
760 if (openfd != redir->fd) {
761 if (squirrel && redir->fd < 3) {
762 squirrel[redir->fd] = dup(redir->fd);
764 dup2(openfd, redir->fd);
772 static void restore_redirects(int squirrel[])
775 for (i=0; i<3; i++) {
778 /* No error checking. I sure wouldn't know what
779 * to do with an error if I found one! */
786 #if defined(BB_FEATURE_SH_SIMPLE_PROMPT)
787 static char* setup_prompt_string(int state)
789 char prompt_str[BUFSIZ];
791 /* Set up the prompt */
794 sprintf(prompt_str, "%s %s", cwd, ( geteuid() != 0 ) ? "$ ":"# ");
796 strcpy(prompt_str,"> ");
799 return(strdup(prompt_str)); /* Must free this memory */
804 static char* setup_prompt_string(int state)
806 char user[9],buf[255],*s;
808 char prompt_str[BUFSIZ];
810 /* Set up the prompt */
812 /* get User Name and setup prompt */
813 strcpy(prompt,( geteuid() != 0 ) ? "$ ":"# ");
814 my_getpwuid(user, geteuid());
817 gethostname(buf, 255);
818 s = strchr(buf, '.');
827 snprintf(prompt_str, BUFSIZ-1, "[%s@%s %s]%s", user, buf,
828 get_last_path_component(cwd), prompt);
830 sprintf(prompt_str, "%s", prompt);
832 return(strdup(prompt_str)); /* Must free this memory */
837 static int get_command(FILE * source, char *command)
841 if (source == NULL) {
842 if (local_pending_command) {
843 /* a command specified (-c option): return it & mark it done */
844 strcpy(command, local_pending_command);
845 free(local_pending_command);
846 local_pending_command = NULL;
852 if (source == stdin) {
853 prompt_str = setup_prompt_string(shell_context);
855 #ifdef BB_FEATURE_SH_COMMAND_EDITING
857 ** enable command line editing only while a command line
858 ** is actually being read; otherwise, we'll end up bequeathing
859 ** atexit() handlers and other unwanted stuff to our
860 ** child processes (rob@sysgo.de)
862 cmdedit_read_input(prompt_str, command);
867 fputs(prompt_str, stdout);
872 if (!fgets(command, BUFSIZ - 2, source)) {
878 /* remove trailing newline */
879 command[strlen(command) - 1] = '\0';
884 #ifdef BB_FEATURE_SH_ENVIRONMENT
885 static char* itoa(register int i)
887 static char a[7]; /* Max 7 ints */
888 register char *b = a + sizeof(a) - 1;
896 *--b = '0' + (i % 10);
906 static void expand_argument(struct child_prog *prog, int *argcPtr,
907 int *argv_alloced_ptr)
909 int argc_l = *argcPtr;
910 int argv_alloced = *argv_alloced_ptr;
914 char *src, *dst, *var;
916 if (argc_l > 1) { /* cmd->glob_result is already initialized */
918 i = prog->glob_result.gl_pathc;
924 #ifdef BB_FEATURE_SH_ENVIRONMENT
925 /* do shell variable substitution */
926 src = prog->argv[argc_l - 1];
927 while((dst = strchr(src,'$')) != NULL){
928 if (!(var = getenv(dst + 1))) {
931 var = itoa(last_return_code);
934 var = itoa(getpid());
943 var = itoa(last_bg_pid);
945 case '0':case '1':case '2':case '3':case '4':
946 case '5':case '6':case '7':case '8':case '9':
948 int index=*(dst + 1)-48;
959 int offset = dst-src;
960 #warning I have a memory leak which needs to be plugged somehow
961 src = (char*)xmalloc(strlen(src)-strlen(dst)+strlen(var)+1);
962 strncpy(src, prog->argv[argc_l -1], offset);
963 safe_strncpy(src+offset, var, strlen(var)+1);
964 /* If there are any remaining $ variables in the src string, put them back */
965 if ((dst = strchr(prog->argv[argc_l -1]+offset+1,'$')) != NULL) {
967 safe_strncpy(src+strlen(src), dst, strlen(dst)+1);
969 prog->argv[argc_l -1] = src;
971 memset(dst, 0, strlen(src)-strlen(dst));
976 if (strpbrk(prog->argv[argc_l - 1],"*[]?")!= NULL){
977 rc = glob(prog->argv[argc_l - 1], flags, NULL, &prog->glob_result);
978 if (rc == GLOB_NOSPACE) {
979 error_msg("out of space during glob operation");
981 } else if (rc == GLOB_NOMATCH ||
982 (!rc && (prog->glob_result.gl_pathc - i) == 1 &&
983 strcmp(prog->argv[argc_l - 1],
984 prog->glob_result.gl_pathv[i]) == 0)) {
985 /* we need to remove whatever \ quoting is still present */
986 src = dst = prog->argv[argc_l - 1];
990 *dst++ = process_escape_sequence(&src);
998 argv_alloced += (prog->glob_result.gl_pathc - i);
999 prog->argv = xrealloc(prog->argv, argv_alloced * sizeof(*prog->argv));
1000 memcpy(prog->argv + (argc_l - 1), prog->glob_result.gl_pathv + i,
1001 sizeof(*(prog->argv)) * (prog->glob_result.gl_pathc - i));
1002 argc_l += (prog->glob_result.gl_pathc - i - 1);
1005 src = dst = prog->argv[argc_l - 1];
1009 *dst++ = process_escape_sequence(&src);
1017 prog->glob_result.gl_pathc=0;
1019 prog->glob_result.gl_pathv=NULL;
1021 *argv_alloced_ptr = argv_alloced;
1025 /* Return cmd->num_progs as 0 if no command is present (e.g. an empty
1026 line). If a valid command is found, command_ptr is set to point to
1027 the beginning of the next command (if the original command had more
1028 then one job associated with it) or NULL if no more commands are
1030 static int parse_command(char **command_ptr, struct job *job, int *inbg)
1033 char *return_command = NULL;
1034 char *src, *buf, *chptr;
1041 struct child_prog *prog;
1043 /* skip leading white space */
1044 while (**command_ptr && isspace(**command_ptr))
1047 /* this handles empty lines or leading '#' characters */
1048 if (!**command_ptr || (**command_ptr == '#')) {
1055 job->progs = xmalloc(sizeof(*job->progs));
1057 /* We set the argv elements to point inside of this string. The
1058 memory is freed by free_job(). Allocate twice the original
1059 length in case we need to quote every single character.
1061 Getting clean memory relieves us of the task of NULL
1062 terminating things and makes the rest of this look a bit
1063 cleaner (though it is, admittedly, a tad less efficient) */
1064 job->cmdbuf = command = xcalloc(2*strlen(*command_ptr) + 1, sizeof(char));
1068 prog->num_redirects = 0;
1069 prog->redirects = NULL;
1070 prog->free_glob = 0;
1071 prog->is_stopped = 0;
1075 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1076 prog->argv[0] = job->cmdbuf;
1080 while (*src && !done) {
1081 if (quote == *src) {
1087 error_msg("character expected after \\");
1092 /* in shell, "\'" should yield \' */
1093 if (*src != quote) {
1097 } else if (*src == '*' || *src == '?' || *src == '[' ||
1098 *src == ']') *buf++ = '\\';
1100 } else if (isspace(*src)) {
1101 if (*prog->argv[argc_l]) {
1103 /* +1 here leaves room for the NULL which ends argv */
1104 if ((argc_l + 1) == argv_alloced) {
1106 prog->argv = xrealloc(prog->argv,
1107 sizeof(*prog->argv) *
1110 expand_argument(prog, &argc_l, &argv_alloced);
1111 prog->argv[argc_l] = buf;
1120 case '#': /* comment */
1127 case '>': /* redirects */
1129 i = prog->num_redirects++;
1130 prog->redirects = xrealloc(prog->redirects,
1131 sizeof(*prog->redirects) *
1134 prog->redirects[i].fd = -1;
1135 if (buf != prog->argv[argc_l]) {
1136 /* the stuff before this character may be the file number
1138 prog->redirects[i].fd =
1139 strtol(prog->argv[argc_l], &chptr, 10);
1141 if (*chptr && *prog->argv[argc_l]) {
1143 expand_argument(prog, &argc_l, &argv_alloced);
1144 prog->argv[argc_l] = buf;
1148 if (prog->redirects[i].fd == -1) {
1150 prog->redirects[i].fd = 1;
1152 prog->redirects[i].fd = 0;
1155 if (*src++ == '>') {
1157 prog->redirects[i].type =
1158 REDIRECT_APPEND, src++;
1160 prog->redirects[i].type = REDIRECT_OVERWRITE;
1162 prog->redirects[i].type = REDIRECT_INPUT;
1165 /* This isn't POSIX sh compliant. Oh well. */
1167 while (isspace(*chptr))
1171 error_msg("file name expected after %c", *src);
1177 prog->redirects[i].filename = buf;
1178 while (*chptr && !isspace(*chptr))
1181 src = chptr - 1; /* we src++ later */
1182 prog->argv[argc_l] = ++buf;
1185 case '|': /* pipe */
1186 /* finish this command */
1187 if (*prog->argv[argc_l])
1190 error_msg("empty command in pipe");
1195 prog->argv[argc_l] = NULL;
1197 /* and start the next */
1199 job->progs = xrealloc(job->progs,
1200 sizeof(*job->progs) * job->num_progs);
1201 prog = job->progs + (job->num_progs - 1);
1202 prog->num_redirects = 0;
1203 prog->redirects = NULL;
1204 prog->free_glob = 0;
1205 prog->is_stopped = 0;
1210 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1211 prog->argv[0] = ++buf;
1214 while (*src && isspace(*src))
1218 error_msg("empty command in pipe");
1223 src--; /* we'll ++ it at the end of the loop */
1227 case '&': /* background */
1229 case ';': /* multiple commands */
1231 return_command = *command_ptr + (src - *command_ptr) + 1;
1234 #ifdef BB_FEATURE_SH_BACKTICKS
1236 /* Exec a backtick-ed command */
1237 /* Besides any previous brokenness, I have not
1238 * updated backtick handling for close_me support.
1239 * I don't know if it needs it or not. -- LRD */
1241 char* charptr1=NULL, *charptr2;
1244 struct jobset njob_list = { NULL, NULL };
1248 ptr=strchr(++src, '`');
1250 fprintf(stderr, "Unmatched '`' in command\n");
1255 /* Make some space to hold just the backticked command */
1256 charptr1 = charptr2 = xmalloc(1+ptr-src);
1257 memcpy(charptr1, src, ptr-src);
1258 charptr1[ptr-src] = '\0';
1259 newjob = xmalloc(sizeof(struct job));
1260 newjob->job_list = &njob_list;
1261 /* Now parse and run the backticked command */
1262 if (!parse_command(&charptr1, newjob, inbg)
1263 && newjob->num_progs) {
1265 run_command(newjob, 0, pipefd);
1267 checkjobs(job->job_list);
1268 free_job(newjob); /* doesn't actually free newjob,
1269 looks like a memory leak */
1272 /* Make a copy of any stuff left over in the command
1273 * line after the second backtick */
1274 charptr2 = xmalloc(strlen(ptr)+1);
1275 memcpy(charptr2, ptr+1, strlen(ptr));
1278 /* Copy the output from the backtick-ed command into the
1279 * command line, making extra room as needed */
1281 charptr1 = xmalloc(BUFSIZ);
1282 while ( (size=full_read(pipefd[0], charptr1, BUFSIZ-1)) >0) {
1283 int newsize=src - *command_ptr + size + 1 + strlen(charptr2);
1284 if (newsize > BUFSIZ) {
1285 *command_ptr=xrealloc(*command_ptr, newsize);
1287 memcpy(src, charptr1, size);
1295 /* Now paste into the *command_ptr all the stuff
1296 * leftover after the second backtick */
1297 memcpy(src, charptr2, strlen(charptr2)+1);
1300 /* Now recursively call parse_command to deal with the new
1301 * and improved version of the command line with the backtick
1302 * results expanded in place... */
1304 struct jobset *jl=job->job_list;
1308 return(parse_command(command_ptr, job, inbg));
1311 #endif // BB_FEATURE_SH_BACKTICKS
1316 /* This is currently a little broken... */
1317 #ifdef HANDLE_CONTINUATION_CHARS
1318 /* They fed us a continuation char, so continue reading stuff
1319 * on the next line, then tack that onto the end of the current
1323 printf("erik: found a continue char at EOL...\n");
1324 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1325 if (get_command(input, command)) {
1326 error_msg("character expected after \\");
1331 newsize = strlen(*command_ptr) + strlen(command) + 2;
1332 if (newsize > BUFSIZ) {
1333 printf("erik: doing realloc\n");
1334 *command_ptr=xrealloc(*command_ptr, newsize);
1336 printf("erik: A: *command_ptr='%s'\n", *command_ptr);
1337 memcpy(--src, command, strlen(command));
1338 printf("erik: B: *command_ptr='%s'\n", *command_ptr);
1342 error_msg("character expected after \\");
1348 if (*src == '*' || *src == '[' || *src == ']'
1349 || *src == '?') *buf++ = '\\';
1358 if (*prog->argv[argc_l]) {
1360 expand_argument(prog, &argc_l, &argv_alloced);
1366 prog->argv[argc_l] = NULL;
1368 if (!return_command) {
1369 job->text = xmalloc(strlen(*command_ptr) + 1);
1370 strcpy(job->text, *command_ptr);
1372 /* This leaves any trailing spaces, which is a bit sloppy */
1373 count = return_command - *command_ptr;
1374 job->text = xmalloc(count + 1);
1375 strncpy(job->text, *command_ptr, count);
1376 job->text[count] = '\0';
1379 *command_ptr = return_command;
1384 /* Run the child_prog, no matter what kind of command it uses.
1386 static int pseudo_exec(struct child_prog *child)
1388 struct built_in_command *x;
1389 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
1393 /* Check if the command matches any of the non-forking builtins.
1394 * Depending on context, this might be redundant. But it's
1395 * easier to waste a few CPU cycles than it is to figure out
1396 * if this is one of those cases.
1398 for (x = bltins; x->cmd; x++) {
1399 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1400 exit(x->function(child));
1404 /* Check if the command matches any of the forking builtins. */
1405 for (x = bltins_forking; x->cmd; x++) {
1406 if (strcmp(child->argv[0], x->cmd) == 0) {
1408 exit (x->function(child));
1411 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
1412 /* Check if the command matches any busybox internal
1413 * commands ("applets") here. Following discussions from
1414 * November 2000 on busybox@opensource.lineo.com, don't use
1415 * get_last_path_component(). This way explicit (with
1416 * slashes) filenames will never be interpreted as an
1417 * applet, just like with builtins. This way the user can
1418 * override an applet with an explicit filename reference.
1419 * The only downside to this change is that an explicit
1420 * /bin/foo invocation will fork and exec /bin/foo, even if
1421 * /bin/foo is a symlink to busybox.
1423 name = child->argv[0];
1425 #ifdef BB_FEATURE_SH_APPLETS_ALWAYS_WIN
1426 /* If you enable BB_FEATURE_SH_APPLETS_ALWAYS_WIN, then
1427 * if you run /bin/cat, it will use BusyBox cat even if
1428 * /bin/cat exists on the filesystem and is _not_ busybox.
1429 * Some systems want this, others do not. Choose wisely. :-)
1431 name = get_last_path_component(name);
1435 char** argv=child->argv;
1437 for(argc_l=0;*argv!=NULL; argv++, argc_l++);
1439 run_applet_by_name(name, argc_l, child->argv);
1443 execvp(child->argv[0], child->argv);
1444 perror_msg_and_die("%s", child->argv[0]);
1447 static void insert_job(struct job *newjob, int inbg)
1450 struct jobset *job_list=newjob->job_list;
1452 /* find the ID for thejob to use */
1454 for (thejob = job_list->head; thejob; thejob = thejob->next)
1455 if (thejob->jobid >= newjob->jobid)
1456 newjob->jobid = thejob->jobid + 1;
1458 /* add thejob to the list of running jobs */
1459 if (!job_list->head) {
1460 thejob = job_list->head = xmalloc(sizeof(*thejob));
1462 for (thejob = job_list->head; thejob->next; thejob = thejob->next) /* nothing */;
1463 thejob->next = xmalloc(sizeof(*thejob));
1464 thejob = thejob->next;
1467 *thejob = *newjob; /* physically copy the struct job */
1468 thejob->next = NULL;
1469 thejob->running_progs = thejob->num_progs;
1470 thejob->stopped_progs = 0;
1473 /* we don't wait for background thejobs to return -- append it
1474 to the list of backgrounded thejobs and leave it alone */
1475 printf("[%d] %d\n", thejob->jobid,
1476 newjob->progs[newjob->num_progs - 1].pid);
1477 #ifdef BB_FEATURE_SH_ENVIRONMENT
1478 last_bg_pid=newjob->progs[newjob->num_progs - 1].pid;
1481 newjob->job_list->fg = thejob;
1483 /* move the new process group into the foreground */
1484 /* suppress messages when run from /linuxrc mag@sysgo.de */
1485 if (tcsetpgrp(0, newjob->pgrp) && errno != ENOTTY)
1486 perror_msg("tcsetpgrp");
1490 static int run_command(struct job *newjob, int inbg, int outpipe[2])
1492 /* struct job *thejob; */
1494 int nextin, nextout;
1495 int pipefds[2]; /* pipefd[0] is for reading */
1496 struct built_in_command *x;
1497 struct child_prog *child;
1499 nextin = 0, nextout = 1;
1500 for (i = 0; i < newjob->num_progs; i++) {
1501 child = & (newjob->progs[i]);
1503 if ((i + 1) < newjob->num_progs) {
1504 if (pipe(pipefds)<0) perror_msg_and_die("pipe");
1505 nextout = pipefds[1];
1507 if (outpipe[1]!=-1) {
1508 nextout = outpipe[1];
1514 #ifdef BB_FEATURE_SH_ENVIRONMENT
1515 if (show_x_trace==TRUE) {
1518 for (j = 0; child->argv[j]; j++) {
1520 fputs(child->argv[j], stderr);
1522 fputc('\n', stderr);
1526 /* Check if the command matches any non-forking builtins,
1527 * but only if this is a simple command.
1528 * Non-forking builtins within pipes have to fork anyway,
1529 * and are handled in pseudo_exec. "echo foo | read bar"
1530 * is doomed to failure, and doesn't work on bash, either.
1532 if (newjob->num_progs == 1) {
1533 for (x = bltins; x->cmd; x++) {
1534 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1535 int squirrel[] = {-1, -1, -1};
1537 setup_redirects(child, squirrel);
1538 rcode = x->function(child);
1539 restore_redirects(squirrel);
1545 if (!(child->pid = fork())) {
1546 signal(SIGTTOU, SIG_DFL);
1550 if (outpipe[1]!=-1) {
1560 dup2(nextout, 2); /* Really? */
1565 /* explicit redirects override pipes */
1566 setup_redirects(child,NULL);
1570 if (outpipe[1]!=-1) {
1574 /* put our child in the process group whose leader is the
1575 first process in this pipe */
1576 setpgid(child->pid, newjob->progs[0].pid);
1582 /* If there isn't another process, nextin is garbage
1583 but it doesn't matter */
1584 nextin = pipefds[0];
1587 newjob->pgrp = newjob->progs[0].pid;
1589 insert_job(newjob, inbg);
1594 static int busy_loop(FILE * input)
1597 char *next_command = NULL;
1603 newjob.job_list = &job_list;
1604 newjob.job_context = DEFAULT_CONTEXT;
1606 /* save current owner of TTY so we can restore it on exit */
1607 parent_pgrp = tcgetpgrp(0);
1609 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1611 /* don't pay any attention to this signal; it just confuses
1612 things and isn't really meant for shells anyway */
1613 signal(SIGTTOU, SIG_IGN);
1617 /* no job is in the foreground */
1619 /* see if any background processes have exited */
1620 checkjobs(&job_list);
1622 if (!next_command) {
1623 if (get_command(input, command))
1625 next_command = command;
1628 if (!parse_command(&next_command, &newjob, &inbg) &&
1630 int pipefds[2] = {-1,-1};
1631 debug_printf( "job=%p being fed to run_command by busy_loop()'\n", &newjob);
1632 run_command(&newjob, inbg, pipefds);
1636 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1637 next_command = NULL;
1640 /* a job is running in the foreground; wait for it */
1642 while (!job_list.fg->progs[i].pid ||
1643 job_list.fg->progs[i].is_stopped == 1) i++;
1645 if (waitpid(job_list.fg->progs[i].pid, &status, WUNTRACED)<0)
1646 perror_msg_and_die("waitpid(%d)",job_list.fg->progs[i].pid);
1648 if (WIFEXITED(status) || WIFSIGNALED(status)) {
1649 /* the child exited */
1650 job_list.fg->running_progs--;
1651 job_list.fg->progs[i].pid = 0;
1653 #ifdef BB_FEATURE_SH_ENVIRONMENT
1654 last_return_code=WEXITSTATUS(status);
1656 debug_printf("'%s' exited -- return code %d\n",
1657 job_list.fg->text, last_return_code);
1658 if (!job_list.fg->running_progs) {
1660 remove_job(&job_list, job_list.fg);
1664 /* the child was stopped */
1665 job_list.fg->stopped_progs++;
1666 job_list.fg->progs[i].is_stopped = 1;
1668 if (job_list.fg->stopped_progs == job_list.fg->running_progs) {
1669 printf("\n" JOB_STATUS_FORMAT, job_list.fg->jobid,
1670 "Stopped", job_list.fg->text);
1676 /* move the shell to the foreground */
1677 /* suppress messages when run from /linuxrc mag@sysgo.de */
1678 if (tcsetpgrp(0, getpid()) && errno != ENOTTY)
1679 perror_msg("tcsetpgrp");
1685 /* return controlling TTY back to parent process group before exiting */
1686 if (tcsetpgrp(0, parent_pgrp))
1687 perror_msg("tcsetpgrp");
1689 /* return exit status if called with "-c" */
1690 if (input == NULL && WIFEXITED(status))
1691 return WEXITSTATUS(status);
1697 #ifdef BB_FEATURE_CLEAN_UP
1698 void free_memory(void)
1702 if (local_pending_command)
1703 free(local_pending_command);
1705 if (job_list.fg && !job_list.fg->running_progs) {
1706 remove_job(&job_list, job_list.fg);
1712 int shell_main(int argc_l, char **argv_l)
1714 int opt, interactive=FALSE;
1715 FILE *input = stdin;
1719 /* These variables need re-initializing when recursing */
1722 local_pending_command = NULL;
1723 close_me_head = NULL;
1724 job_list.head = NULL;
1726 #ifdef BB_FEATURE_SH_ENVIRONMENT
1728 last_return_code=-1;
1732 if (argv[0] && argv[0][0] == '-') {
1734 prof_input = fopen("/etc/profile", "r");
1736 printf( "Couldn't open file '/etc/profile'\n");
1738 int tmp_fd = fileno(prof_input);
1740 /* Now run the file */
1741 busy_loop(prof_input);
1743 mark_closed(tmp_fd);
1747 while ((opt = getopt(argc_l, argv_l, "cxi")) > 0) {
1751 if (local_pending_command != 0)
1752 error_msg_and_die("multiple -c arguments");
1753 local_pending_command = xstrdup(argv[optind]);
1757 #ifdef BB_FEATURE_SH_ENVIRONMENT
1759 show_x_trace = TRUE;
1769 /* A shell is interactive if the `-i' flag was given, or if all of
1770 * the following conditions are met:
1772 * no arguments remaining or the -s flag given
1773 * standard input is a terminal
1774 * standard output is a terminal
1775 * Refer to Posix.2, the description of the `sh' utility. */
1776 if (argv[optind]==NULL && input==stdin &&
1777 isatty(fileno(stdin)) && isatty(fileno(stdout))) {
1780 if (interactive==TRUE) {
1781 //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
1782 /* Looks like they want an interactive shell */
1783 printf( "\n\nBusyBox v%s (%s) Built-in shell (lash)\n", BB_VER, BB_BT);
1784 printf( "Enter 'help' for a list of built-in commands.\n\n");
1785 } else if (local_pending_command==NULL) {
1786 //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
1787 input = xfopen(argv[optind], "r");
1788 mark_open(fileno(input)); /* be lazy, never mark this closed */
1791 /* initialize the cwd -- this is never freed...*/
1792 cwd=(char*)xmalloc(sizeof(char)*MAX_LINE+1);
1793 getcwd(cwd, sizeof(char)*MAX_LINE);
1795 #ifdef BB_FEATURE_CLEAN_UP
1796 atexit(free_memory);
1799 return (busy_loop(input));