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()
634 struct close_me *c, *tmp;
635 for (c=close_me_head; c; c=tmp) {
640 close_me_head = NULL;
644 /* free up all memory from a job */
645 static void free_job(struct job *cmd)
649 for (i = 0; i < cmd->num_progs; i++) {
650 free(cmd->progs[i].argv);
651 if (cmd->progs[i].redirects)
652 free(cmd->progs[i].redirects);
653 if (cmd->progs[i].free_glob)
654 globfree(&cmd->progs[i].glob_result);
660 memset(cmd, 0, sizeof(struct job));
663 /* remove a job from the job_list */
664 static void remove_job(struct jobset *job_list, struct job *job)
669 if (job == job_list->head) {
670 job_list->head = job->next;
672 prevjob = job_list->head;
673 while (prevjob->next != job)
674 prevjob = prevjob->next;
675 prevjob->next = job->next;
681 /* Checks to see if any background processes have exited -- if they
682 have, figure out why and see if a job has completed */
683 static void checkjobs(struct jobset *job_list)
690 while ((childpid = waitpid(-1, &status, WNOHANG | WUNTRACED)) > 0) {
691 for (job = job_list->head; job; job = job->next) {
693 while (prognum < job->num_progs &&
694 job->progs[prognum].pid != childpid) prognum++;
695 if (prognum < job->num_progs)
699 /* This happens on backticked commands */
703 if (WIFEXITED(status) || WIFSIGNALED(status)) {
705 job->running_progs--;
706 job->progs[prognum].pid = 0;
708 if (!job->running_progs) {
709 printf(JOB_STATUS_FORMAT, job->jobid, "Done", job->text);
710 remove_job(job_list, job);
714 job->stopped_progs++;
715 job->progs[prognum].is_stopped = 1;
717 if (job->stopped_progs == job->num_progs) {
718 printf(JOB_STATUS_FORMAT, job->jobid, "Stopped",
724 if (childpid == -1 && errno != ECHILD)
725 perror_msg("waitpid");
728 /* squirrel != NULL means we squirrel away copies of stdin, stdout,
729 * and stderr if they are redirected. */
730 static int setup_redirects(struct child_prog *prog, int squirrel[])
735 struct redir_struct *redir = prog->redirects;
737 for (i = 0; i < prog->num_redirects; i++, redir++) {
738 switch (redir->type) {
742 case REDIRECT_OVERWRITE:
743 mode = O_WRONLY | O_CREAT | O_TRUNC;
745 case REDIRECT_APPEND:
746 mode = O_WRONLY | O_CREAT | O_APPEND;
750 openfd = open(redir->filename, mode, 0666);
752 /* this could get lost if stderr has been redirected, but
753 bash and ash both lose it as well (though zsh doesn't!) */
754 error_msg("error opening %s: %s", redir->filename,
759 if (openfd != redir->fd) {
760 if (squirrel && redir->fd < 3) {
761 squirrel[redir->fd] = dup(redir->fd);
763 dup2(openfd, redir->fd);
771 static void restore_redirects(int squirrel[])
774 for (i=0; i<3; i++) {
777 /* No error checking. I sure wouldn't know what
778 * to do with an error if I found one! */
785 #if defined(BB_FEATURE_SH_SIMPLE_PROMPT)
786 static char* setup_prompt_string(int state)
788 char prompt_str[BUFSIZ];
790 /* Set up the prompt */
793 sprintf(prompt_str, "%s %s", cwd, ( geteuid() != 0 ) ? "$ ":"# ");
795 strcpy(prompt_str,"> ");
798 return(strdup(prompt_str)); /* Must free this memory */
803 static char* setup_prompt_string(int state)
805 char user[9],buf[255],*s;
807 char prompt_str[BUFSIZ];
809 /* Set up the prompt */
811 /* get User Name and setup prompt */
812 strcpy(prompt,( geteuid() != 0 ) ? "$ ":"# ");
813 my_getpwuid(user, geteuid());
816 gethostname(buf, 255);
817 s = strchr(buf, '.');
826 snprintf(prompt_str, BUFSIZ-1, "[%s@%s %s]%s", user, buf,
827 get_last_path_component(cwd), prompt);
829 sprintf(prompt_str, "%s", prompt);
831 return(strdup(prompt_str)); /* Must free this memory */
836 static int get_command(FILE * source, char *command)
840 if (source == NULL) {
841 if (local_pending_command) {
842 /* a command specified (-c option): return it & mark it done */
843 strcpy(command, local_pending_command);
844 free(local_pending_command);
845 local_pending_command = NULL;
851 if (source == stdin) {
852 prompt_str = setup_prompt_string(shell_context);
854 #ifdef BB_FEATURE_SH_COMMAND_EDITING
856 ** enable command line editing only while a command line
857 ** is actually being read; otherwise, we'll end up bequeathing
858 ** atexit() handlers and other unwanted stuff to our
859 ** child processes (rob@sysgo.de)
861 cmdedit_read_input(prompt_str, command);
866 fputs(prompt_str, stdout);
871 if (!fgets(command, BUFSIZ - 2, source)) {
877 /* remove trailing newline */
878 command[strlen(command) - 1] = '\0';
883 #ifdef BB_FEATURE_SH_ENVIRONMENT
884 static char* itoa(register int i)
886 static char a[7]; /* Max 7 ints */
887 register char *b = a + sizeof(a) - 1;
895 *--b = '0' + (i % 10);
905 static void expand_argument(struct child_prog *prog, int *argcPtr,
906 int *argv_alloced_ptr)
908 int argc_l = *argcPtr;
909 int argv_alloced = *argv_alloced_ptr;
913 char *src, *dst, *var;
915 if (argc_l > 1) { /* cmd->glob_result is already initialized */
917 i = prog->glob_result.gl_pathc;
923 #ifdef BB_FEATURE_SH_ENVIRONMENT
924 /* do shell variable substitution */
925 src = prog->argv[argc_l - 1];
926 while((dst = strchr(src,'$')) != NULL){
927 if (!(var = getenv(dst + 1))) {
930 var = itoa(last_return_code);
933 var = itoa(getpid());
942 var = 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=*(dst + 1)-48;
958 int offset = dst-src;
959 #warning I have a memory leak which needs to be plugged somehow
960 src = (char*)xmalloc(strlen(src)-strlen(dst)+strlen(var)+1);
961 strncpy(src, prog->argv[argc_l -1], offset);
962 safe_strncpy(src+offset, var, strlen(var)+1);
963 /* If there are any remaining $ variables in the src string, put them back */
964 if ((dst = strchr(prog->argv[argc_l -1]+offset+1,'$')) != NULL) {
966 safe_strncpy(src+strlen(src), dst, strlen(dst)+1);
968 prog->argv[argc_l -1] = src;
970 memset(dst, 0, strlen(src)-strlen(dst));
975 if (strpbrk(prog->argv[argc_l - 1],"*[]?")!= NULL){
976 rc = glob(prog->argv[argc_l - 1], flags, NULL, &prog->glob_result);
977 if (rc == GLOB_NOSPACE) {
978 error_msg("out of space during glob operation");
980 } else if (rc == GLOB_NOMATCH ||
981 (!rc && (prog->glob_result.gl_pathc - i) == 1 &&
982 strcmp(prog->argv[argc_l - 1],
983 prog->glob_result.gl_pathv[i]) == 0)) {
984 /* we need to remove whatever \ quoting is still present */
985 src = dst = prog->argv[argc_l - 1];
989 *dst++ = process_escape_sequence(&src);
997 argv_alloced += (prog->glob_result.gl_pathc - i);
998 prog->argv = xrealloc(prog->argv, argv_alloced * sizeof(*prog->argv));
999 memcpy(prog->argv + (argc_l - 1), prog->glob_result.gl_pathv + i,
1000 sizeof(*(prog->argv)) * (prog->glob_result.gl_pathc - i));
1001 argc_l += (prog->glob_result.gl_pathc - i - 1);
1004 src = dst = prog->argv[argc_l - 1];
1008 *dst++ = process_escape_sequence(&src);
1016 prog->glob_result.gl_pathc=0;
1018 prog->glob_result.gl_pathv=NULL;
1020 *argv_alloced_ptr = argv_alloced;
1024 /* Return cmd->num_progs as 0 if no command is present (e.g. an empty
1025 line). If a valid command is found, command_ptr is set to point to
1026 the beginning of the next command (if the original command had more
1027 then one job associated with it) or NULL if no more commands are
1029 static int parse_command(char **command_ptr, struct job *job, int *inbg)
1032 char *return_command = NULL;
1033 char *src, *buf, *chptr;
1040 struct child_prog *prog;
1042 /* skip leading white space */
1043 while (**command_ptr && isspace(**command_ptr))
1046 /* this handles empty lines or leading '#' characters */
1047 if (!**command_ptr || (**command_ptr == '#')) {
1054 job->progs = xmalloc(sizeof(*job->progs));
1056 /* We set the argv elements to point inside of this string. The
1057 memory is freed by free_job(). Allocate twice the original
1058 length in case we need to quote every single character.
1060 Getting clean memory relieves us of the task of NULL
1061 terminating things and makes the rest of this look a bit
1062 cleaner (though it is, admittedly, a tad less efficient) */
1063 job->cmdbuf = command = xcalloc(2*strlen(*command_ptr) + 1, sizeof(char));
1067 prog->num_redirects = 0;
1068 prog->redirects = NULL;
1069 prog->free_glob = 0;
1070 prog->is_stopped = 0;
1074 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1075 prog->argv[0] = job->cmdbuf;
1079 while (*src && !done) {
1080 if (quote == *src) {
1086 error_msg("character expected after \\");
1091 /* in shell, "\'" should yield \' */
1092 if (*src != quote) {
1096 } else if (*src == '*' || *src == '?' || *src == '[' ||
1097 *src == ']') *buf++ = '\\';
1099 } else if (isspace(*src)) {
1100 if (*prog->argv[argc_l]) {
1102 /* +1 here leaves room for the NULL which ends argv */
1103 if ((argc_l + 1) == argv_alloced) {
1105 prog->argv = xrealloc(prog->argv,
1106 sizeof(*prog->argv) *
1109 expand_argument(prog, &argc_l, &argv_alloced);
1110 prog->argv[argc_l] = buf;
1119 case '#': /* comment */
1126 case '>': /* redirects */
1128 i = prog->num_redirects++;
1129 prog->redirects = xrealloc(prog->redirects,
1130 sizeof(*prog->redirects) *
1133 prog->redirects[i].fd = -1;
1134 if (buf != prog->argv[argc_l]) {
1135 /* the stuff before this character may be the file number
1137 prog->redirects[i].fd =
1138 strtol(prog->argv[argc_l], &chptr, 10);
1140 if (*chptr && *prog->argv[argc_l]) {
1142 expand_argument(prog, &argc_l, &argv_alloced);
1143 prog->argv[argc_l] = buf;
1147 if (prog->redirects[i].fd == -1) {
1149 prog->redirects[i].fd = 1;
1151 prog->redirects[i].fd = 0;
1154 if (*src++ == '>') {
1156 prog->redirects[i].type =
1157 REDIRECT_APPEND, src++;
1159 prog->redirects[i].type = REDIRECT_OVERWRITE;
1161 prog->redirects[i].type = REDIRECT_INPUT;
1164 /* This isn't POSIX sh compliant. Oh well. */
1166 while (isspace(*chptr))
1170 error_msg("file name expected after %c", *src);
1176 prog->redirects[i].filename = buf;
1177 while (*chptr && !isspace(*chptr))
1180 src = chptr - 1; /* we src++ later */
1181 prog->argv[argc_l] = ++buf;
1184 case '|': /* pipe */
1185 /* finish this command */
1186 if (*prog->argv[argc_l])
1189 error_msg("empty command in pipe");
1194 prog->argv[argc_l] = NULL;
1196 /* and start the next */
1198 job->progs = xrealloc(job->progs,
1199 sizeof(*job->progs) * job->num_progs);
1200 prog = job->progs + (job->num_progs - 1);
1201 prog->num_redirects = 0;
1202 prog->redirects = NULL;
1203 prog->free_glob = 0;
1204 prog->is_stopped = 0;
1209 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1210 prog->argv[0] = ++buf;
1213 while (*src && isspace(*src))
1217 error_msg("empty command in pipe");
1222 src--; /* we'll ++ it at the end of the loop */
1226 case '&': /* background */
1228 case ';': /* multiple commands */
1230 return_command = *command_ptr + (src - *command_ptr) + 1;
1233 #ifdef BB_FEATURE_SH_BACKTICKS
1235 /* Exec a backtick-ed command */
1236 /* Besides any previous brokenness, I have not
1237 * updated backtick handling for close_me support.
1238 * I don't know if it needs it or not. -- LRD */
1240 char* charptr1=NULL, *charptr2;
1243 struct jobset njob_list = { NULL, NULL };
1247 ptr=strchr(++src, '`');
1249 fprintf(stderr, "Unmatched '`' in command\n");
1254 /* Make some space to hold just the backticked command */
1255 charptr1 = charptr2 = xmalloc(1+ptr-src);
1256 memcpy(charptr1, src, ptr-src);
1257 charptr1[ptr-src] = '\0';
1258 newjob = xmalloc(sizeof(struct job));
1259 newjob->job_list = &njob_list;
1260 /* Now parse and run the backticked command */
1261 if (!parse_command(&charptr1, newjob, inbg)
1262 && newjob->num_progs) {
1264 run_command(newjob, 0, pipefd);
1266 checkjobs(job->job_list);
1267 free_job(newjob); /* doesn't actually free newjob,
1268 looks like a memory leak */
1271 /* Make a copy of any stuff left over in the command
1272 * line after the second backtick */
1273 charptr2 = xmalloc(strlen(ptr)+1);
1274 memcpy(charptr2, ptr+1, strlen(ptr));
1277 /* Copy the output from the backtick-ed command into the
1278 * command line, making extra room as needed */
1280 charptr1 = xmalloc(BUFSIZ);
1281 while ( (size=full_read(pipefd[0], charptr1, BUFSIZ-1)) >0) {
1282 int newsize=src - *command_ptr + size + 1 + strlen(charptr2);
1283 if (newsize > BUFSIZ) {
1284 *command_ptr=xrealloc(*command_ptr, newsize);
1286 memcpy(src, charptr1, size);
1294 /* Now paste into the *command_ptr all the stuff
1295 * leftover after the second backtick */
1296 memcpy(src, charptr2, strlen(charptr2)+1);
1299 /* Now recursively call parse_command to deal with the new
1300 * and improved version of the command line with the backtick
1301 * results expanded in place... */
1303 struct jobset *jl=job->job_list;
1307 return(parse_command(command_ptr, job, inbg));
1310 #endif // BB_FEATURE_SH_BACKTICKS
1315 /* This is currently a little broken... */
1316 #ifdef HANDLE_CONTINUATION_CHARS
1317 /* They fed us a continuation char, so continue reading stuff
1318 * on the next line, then tack that onto the end of the current
1322 printf("erik: found a continue char at EOL...\n");
1323 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1324 if (get_command(input, command)) {
1325 error_msg("character expected after \\");
1330 newsize = strlen(*command_ptr) + strlen(command) + 2;
1331 if (newsize > BUFSIZ) {
1332 printf("erik: doing realloc\n");
1333 *command_ptr=xrealloc(*command_ptr, newsize);
1335 printf("erik: A: *command_ptr='%s'\n", *command_ptr);
1336 memcpy(--src, command, strlen(command));
1337 printf("erik: B: *command_ptr='%s'\n", *command_ptr);
1341 error_msg("character expected after \\");
1347 if (*src == '*' || *src == '[' || *src == ']'
1348 || *src == '?') *buf++ = '\\';
1357 if (*prog->argv[argc_l]) {
1359 expand_argument(prog, &argc_l, &argv_alloced);
1365 prog->argv[argc_l] = NULL;
1367 if (!return_command) {
1368 job->text = xmalloc(strlen(*command_ptr) + 1);
1369 strcpy(job->text, *command_ptr);
1371 /* This leaves any trailing spaces, which is a bit sloppy */
1372 count = return_command - *command_ptr;
1373 job->text = xmalloc(count + 1);
1374 strncpy(job->text, *command_ptr, count);
1375 job->text[count] = '\0';
1378 *command_ptr = return_command;
1383 /* Run the child_prog, no matter what kind of command it uses.
1385 static int pseudo_exec(struct child_prog *child)
1387 struct built_in_command *x;
1388 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
1392 /* Check if the command matches any of the non-forking builtins.
1393 * Depending on context, this might be redundant. But it's
1394 * easier to waste a few CPU cycles than it is to figure out
1395 * if this is one of those cases.
1397 for (x = bltins; x->cmd; x++) {
1398 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1399 exit(x->function(child));
1403 /* Check if the command matches any of the forking builtins. */
1404 for (x = bltins_forking; x->cmd; x++) {
1405 if (strcmp(child->argv[0], x->cmd) == 0) {
1407 exit (x->function(child));
1410 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
1411 /* Check if the command matches any busybox internal
1412 * commands ("applets") here. Following discussions from
1413 * November 2000 on busybox@opensource.lineo.com, don't use
1414 * get_last_path_component(). This way explicit (with
1415 * slashes) filenames will never be interpreted as an
1416 * applet, just like with builtins. This way the user can
1417 * override an applet with an explicit filename reference.
1418 * The only downside to this change is that an explicit
1419 * /bin/foo invocation will fork and exec /bin/foo, even if
1420 * /bin/foo is a symlink to busybox.
1422 name = child->argv[0];
1424 #ifdef BB_FEATURE_SH_APPLETS_ALWAYS_WIN
1425 /* If you enable BB_FEATURE_SH_APPLETS_ALWAYS_WIN, then
1426 * if you run /bin/cat, it will use BusyBox cat even if
1427 * /bin/cat exists on the filesystem and is _not_ busybox.
1428 * Some systems want this, others do not. Choose wisely. :-)
1430 name = get_last_path_component(name);
1434 char** argv=child->argv;
1436 for(argc_l=0;*argv!=NULL; argv++, argc_l++);
1438 run_applet_by_name(name, argc_l, child->argv);
1442 execvp(child->argv[0], child->argv);
1443 perror_msg_and_die("%s", child->argv[0]);
1446 static void insert_job(struct job *newjob, int inbg)
1449 struct jobset *job_list=newjob->job_list;
1451 /* find the ID for thejob to use */
1453 for (thejob = job_list->head; thejob; thejob = thejob->next)
1454 if (thejob->jobid >= newjob->jobid)
1455 newjob->jobid = thejob->jobid + 1;
1457 /* add thejob to the list of running jobs */
1458 if (!job_list->head) {
1459 thejob = job_list->head = xmalloc(sizeof(*thejob));
1461 for (thejob = job_list->head; thejob->next; thejob = thejob->next) /* nothing */;
1462 thejob->next = xmalloc(sizeof(*thejob));
1463 thejob = thejob->next;
1466 *thejob = *newjob; /* physically copy the struct job */
1467 thejob->next = NULL;
1468 thejob->running_progs = thejob->num_progs;
1469 thejob->stopped_progs = 0;
1472 /* we don't wait for background thejobs to return -- append it
1473 to the list of backgrounded thejobs and leave it alone */
1474 printf("[%d] %d\n", thejob->jobid,
1475 newjob->progs[newjob->num_progs - 1].pid);
1476 #ifdef BB_FEATURE_SH_ENVIRONMENT
1477 last_bg_pid=newjob->progs[newjob->num_progs - 1].pid;
1480 newjob->job_list->fg = thejob;
1482 /* move the new process group into the foreground */
1483 /* suppress messages when run from /linuxrc mag@sysgo.de */
1484 if (tcsetpgrp(0, newjob->pgrp) && errno != ENOTTY)
1485 perror_msg("tcsetpgrp");
1489 static int run_command(struct job *newjob, int inbg, int outpipe[2])
1491 /* struct job *thejob; */
1493 int nextin, nextout;
1494 int pipefds[2]; /* pipefd[0] is for reading */
1495 struct built_in_command *x;
1496 struct child_prog *child;
1498 nextin = 0, nextout = 1;
1499 for (i = 0; i < newjob->num_progs; i++) {
1500 child = & (newjob->progs[i]);
1502 if ((i + 1) < newjob->num_progs) {
1503 if (pipe(pipefds)<0) perror_msg_and_die("pipe");
1504 nextout = pipefds[1];
1506 if (outpipe[1]!=-1) {
1507 nextout = outpipe[1];
1513 #ifdef BB_FEATURE_SH_ENVIRONMENT
1514 if (show_x_trace==TRUE) {
1517 for (j = 0; child->argv[j]; j++) {
1519 fputs(child->argv[j], stderr);
1521 fputc('\n', stderr);
1525 /* Check if the command matches any non-forking builtins,
1526 * but only if this is a simple command.
1527 * Non-forking builtins within pipes have to fork anyway,
1528 * and are handled in pseudo_exec. "echo foo | read bar"
1529 * is doomed to failure, and doesn't work on bash, either.
1531 if (newjob->num_progs == 1) {
1532 for (x = bltins; x->cmd; x++) {
1533 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1534 int squirrel[] = {-1, -1, -1};
1536 setup_redirects(child, squirrel);
1537 rcode = x->function(child);
1538 restore_redirects(squirrel);
1544 if (!(child->pid = fork())) {
1545 signal(SIGTTOU, SIG_DFL);
1549 if (outpipe[1]!=-1) {
1559 dup2(nextout, 2); /* Really? */
1564 /* explicit redirects override pipes */
1565 setup_redirects(child,NULL);
1569 if (outpipe[1]!=-1) {
1573 /* put our child in the process group whose leader is the
1574 first process in this pipe */
1575 setpgid(child->pid, newjob->progs[0].pid);
1581 /* If there isn't another process, nextin is garbage
1582 but it doesn't matter */
1583 nextin = pipefds[0];
1586 newjob->pgrp = newjob->progs[0].pid;
1588 insert_job(newjob, inbg);
1593 static int busy_loop(FILE * input)
1596 char *next_command = NULL;
1602 newjob.job_list = &job_list;
1603 newjob.job_context = DEFAULT_CONTEXT;
1605 /* save current owner of TTY so we can restore it on exit */
1606 parent_pgrp = tcgetpgrp(0);
1608 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1610 /* don't pay any attention to this signal; it just confuses
1611 things and isn't really meant for shells anyway */
1612 signal(SIGTTOU, SIG_IGN);
1616 /* no job is in the foreground */
1618 /* see if any background processes have exited */
1619 checkjobs(&job_list);
1621 if (!next_command) {
1622 if (get_command(input, command))
1624 next_command = command;
1627 if (!parse_command(&next_command, &newjob, &inbg) &&
1629 int pipefds[2] = {-1,-1};
1630 debug_printf( "job=%p being fed to run_command by busy_loop()'\n", &newjob);
1631 run_command(&newjob, inbg, pipefds);
1635 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1636 next_command = NULL;
1639 /* a job is running in the foreground; wait for it */
1641 while (!job_list.fg->progs[i].pid ||
1642 job_list.fg->progs[i].is_stopped == 1) i++;
1644 if (waitpid(job_list.fg->progs[i].pid, &status, WUNTRACED)<0)
1645 perror_msg_and_die("waitpid(%d)",job_list.fg->progs[i].pid);
1647 if (WIFEXITED(status) || WIFSIGNALED(status)) {
1648 /* the child exited */
1649 job_list.fg->running_progs--;
1650 job_list.fg->progs[i].pid = 0;
1652 #ifdef BB_FEATURE_SH_ENVIRONMENT
1653 last_return_code=WEXITSTATUS(status);
1655 debug_printf("'%s' exited -- return code %d\n",
1656 job_list.fg->text, last_return_code);
1657 if (!job_list.fg->running_progs) {
1659 remove_job(&job_list, job_list.fg);
1663 /* the child was stopped */
1664 job_list.fg->stopped_progs++;
1665 job_list.fg->progs[i].is_stopped = 1;
1667 if (job_list.fg->stopped_progs == job_list.fg->running_progs) {
1668 printf("\n" JOB_STATUS_FORMAT, job_list.fg->jobid,
1669 "Stopped", job_list.fg->text);
1675 /* move the shell to the foreground */
1676 /* suppress messages when run from /linuxrc mag@sysgo.de */
1677 if (tcsetpgrp(0, getpid()) && errno != ENOTTY)
1678 perror_msg("tcsetpgrp");
1684 /* return controlling TTY back to parent process group before exiting */
1685 if (tcsetpgrp(0, parent_pgrp))
1686 perror_msg("tcsetpgrp");
1688 /* return exit status if called with "-c" */
1689 if (input == NULL && WIFEXITED(status))
1690 return WEXITSTATUS(status);
1696 #ifdef BB_FEATURE_CLEAN_UP
1697 void free_memory(void)
1701 if (local_pending_command)
1702 free(local_pending_command);
1704 if (job_list.fg && !job_list.fg->running_progs) {
1705 remove_job(&job_list, job_list.fg);
1711 int shell_main(int argc_l, char **argv_l)
1713 int opt, interactive=FALSE;
1714 FILE *input = stdin;
1718 /* These variables need re-initializing when recursing */
1721 local_pending_command = NULL;
1722 close_me_head = NULL;
1723 job_list.head = NULL;
1725 #ifdef BB_FEATURE_SH_ENVIRONMENT
1727 last_return_code=-1;
1731 if (argv[0] && argv[0][0] == '-') {
1733 prof_input = fopen("/etc/profile", "r");
1735 printf( "Couldn't open file '/etc/profile'\n");
1737 int tmp_fd = fileno(prof_input);
1739 /* Now run the file */
1740 busy_loop(prof_input);
1742 mark_closed(tmp_fd);
1746 while ((opt = getopt(argc_l, argv_l, "cxi")) > 0) {
1750 if (local_pending_command != 0)
1751 error_msg_and_die("multiple -c arguments");
1752 local_pending_command = xstrdup(argv[optind]);
1756 #ifdef BB_FEATURE_SH_ENVIRONMENT
1758 show_x_trace = TRUE;
1768 /* A shell is interactive if the `-i' flag was given, or if all of
1769 * the following conditions are met:
1771 * no arguments remaining or the -s flag given
1772 * standard input is a terminal
1773 * standard output is a terminal
1774 * Refer to Posix.2, the description of the `sh' utility. */
1775 if (argv[optind]==NULL && input==stdin &&
1776 isatty(fileno(stdin)) && isatty(fileno(stdout))) {
1779 if (interactive==TRUE) {
1780 //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
1781 /* Looks like they want an interactive shell */
1782 printf( "\n\nBusyBox v%s (%s) Built-in shell (lash)\n", BB_VER, BB_BT);
1783 printf( "Enter 'help' for a list of built-in commands.\n\n");
1784 } else if (local_pending_command==NULL) {
1785 //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
1786 input = xfopen(argv[optind], "r");
1787 mark_open(fileno(input)); /* be lazy, never mark this closed */
1790 /* initialize the cwd -- this is never freed...*/
1791 cwd=(char*)xmalloc(sizeof(char)*MAX_LINE+1);
1792 getcwd(cwd, sizeof(char)*MAX_LINE);
1794 #ifdef BB_FEATURE_CLEAN_UP
1795 atexit(free_memory);
1798 return (busy_loop(input));