1 /* vi: set sw=4 ts=4: */
3 * lash -- the BusyBox Lame-Ass SHell
5 * Copyright (C) 1999-2003 by Erik Andersen <andersen@codepoet.org>
7 * Based in part on ladsh.c by Michael K. Johnson and Erik W. Troan, which is
8 * under the following liberal license: "We have placed this source code in the
9 * public domain. Use it in any project, free or commercial."
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 /* This shell's parsing engine is officially at a dead-end. Future
28 * work shell work should be done using hush, msh, or ash. This is
29 * still a very useful, small shell -- it just don't need any more
30 * features beyond what it already has...
33 //For debugging/development on the shell only...
44 #include <sys/ioctl.h>
52 #ifdef CONFIG_LOCALE_SUPPORT
57 #define expand_t glob_t
60 static const int MAX_READ = 128; /* size of input buffer for `read' builtin */
61 #define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
64 enum redir_type { REDIRECT_INPUT, REDIRECT_OVERWRITE,
68 static const unsigned int DEFAULT_CONTEXT=0x1;
69 static const unsigned int IF_TRUE_CONTEXT=0x2;
70 static const unsigned int IF_FALSE_CONTEXT=0x4;
71 static const unsigned int THEN_EXP_CONTEXT=0x8;
72 static const unsigned int ELSE_EXP_CONTEXT=0x10;
76 struct job *head; /* head of list of running jobs */
77 struct job *fg; /* current foreground job */
81 enum redir_type type; /* type of redirection */
82 int fd; /* file descriptor being redirected */
83 char *filename; /* file to redirect fd to */
87 pid_t pid; /* 0 if exited */
88 char **argv; /* program name and arguments */
89 int num_redirects; /* elements in redirection array */
90 struct redir_struct *redirects; /* I/O redirects */
91 int is_stopped; /* is the program currently running? */
92 struct job *family; /* pointer back to the child's parent job */
96 int jobid; /* job number */
97 int num_progs; /* total number of programs in job */
98 int running_progs; /* number of programs running */
99 char *text; /* name of job */
100 char *cmdbuf; /* buffer various argv's point into */
101 pid_t pgrp; /* process group ID for the job */
102 struct child_prog *progs; /* array of programs in job */
103 struct job *next; /* to track background commands */
104 int stopped_progs; /* number of programs alive, but stopped */
105 unsigned int job_context; /* bitmask defining current context */
106 struct jobset *job_list;
109 struct built_in_command {
110 char *cmd; /* name */
111 char *descr; /* description */
112 int (*function) (struct child_prog *); /* function ptr */
117 struct close_me *next;
120 /* function prototypes for builtins */
121 static int builtin_cd(struct child_prog *cmd);
122 static int builtin_exec(struct child_prog *cmd);
123 static int builtin_exit(struct child_prog *cmd);
124 static int builtin_fg_bg(struct child_prog *cmd);
125 static int builtin_help(struct child_prog *cmd);
126 static int builtin_jobs(struct child_prog *dummy);
127 static int builtin_pwd(struct child_prog *dummy);
128 static int builtin_export(struct child_prog *cmd);
129 static int builtin_source(struct child_prog *cmd);
130 static int builtin_unset(struct child_prog *cmd);
131 static int builtin_read(struct child_prog *cmd);
134 /* function prototypes for shell stuff */
135 static void mark_open(int fd);
136 static void mark_closed(int fd);
137 static void close_all(void);
138 static void checkjobs(struct jobset *job_list);
139 static void remove_job(struct jobset *j_list, struct job *job);
140 static int get_command(FILE * source, char *command);
141 static int parse_command(char **command_ptr, struct job *job, int *inbg);
142 static int run_command(struct job *newjob, int inbg, int outpipe[2]);
143 static int pseudo_exec(struct child_prog *cmd) __attribute__ ((noreturn));
144 static int busy_loop(FILE * input);
147 /* Table of built-in functions (these are non-forking builtins, meaning they
148 * can change global variables in the parent shell process but they will not
149 * work with pipes and redirects; 'unset foo | whatever' will not work) */
150 static struct built_in_command bltins[] = {
151 {"bg", "Resume a job in the background", builtin_fg_bg},
152 {"cd", "Change working directory", builtin_cd},
153 {"exec", "Exec command, replacing this shell with the exec'd process", builtin_exec},
154 {"exit", "Exit from shell()", builtin_exit},
155 {"fg", "Bring job into the foreground", builtin_fg_bg},
156 {"jobs", "Lists the active jobs", builtin_jobs},
157 {"export", "Set environment variable", builtin_export},
158 {"unset", "Unset environment variable", builtin_unset},
159 {"read", "Input environment variable", builtin_read},
160 {".", "Source-in and run commands in a file", builtin_source},
161 /* to do: add ulimit */
165 /* Table of forking built-in functions (things that fork cannot change global
166 * variables in the parent process, such as the current working directory) */
167 static struct built_in_command bltins_forking[] = {
168 {"pwd", "Print current directory", builtin_pwd},
169 {"help", "List shell built-in commands", builtin_help},
174 static int shell_context; /* Type prompt trigger (PS1 or PS2) */
177 /* Globals that are static to this file */
178 static const char *cwd;
179 static char *local_pending_command = NULL;
180 static struct jobset job_list = { NULL, NULL };
183 static struct close_me *close_me_head;
184 static int last_return_code;
185 static int last_bg_pid;
186 static unsigned int last_jobid;
187 static int shell_terminal;
188 static pid_t shell_pgrp;
190 static char *PS2 = "> ";
194 static inline void debug_printf(const char *format, ...)
197 va_start(args, format);
198 vfprintf(stderr, format, args);
202 static inline void debug_printf(const char *format, ...) { }
206 Most builtins need access to the struct child_prog that has
207 their arguments, previously coded as cmd->progs[0]. That coding
208 can exhibit a bug, if the builtin is not the first command in
209 a pipeline: "echo foo | exec sort" will attempt to exec foo.
211 builtin previous use notes
212 ------ ----------------- ---------
214 exec cmd->progs[0] squashed bug: didn't look for applets or forking builtins
216 fg_bg cmd->progs[0], job_list->head, job_list->fg
225 I added "struct job *family;" to struct child_prog,
226 and switched API to builtin_foo(struct child_prog *child);
227 So cmd->text becomes child->family->text
228 cmd->job_context becomes child->family->job_context
229 cmd->progs[0] becomes *child
230 job_list becomes child->family->job_list
233 /* built-in 'cd <path>' handler */
234 static int builtin_cd(struct child_prog *child)
238 if (child->argv[1] == NULL)
239 newdir = getenv("HOME");
241 newdir = child->argv[1];
243 printf("cd: %s: %m\n", newdir);
246 cwd = xgetcwd((char *)cwd);
248 cwd = bb_msg_unknown;
252 /* built-in 'exec' handler */
253 static int builtin_exec(struct child_prog *child)
255 if (child->argv[1] == NULL)
256 return EXIT_SUCCESS; /* Really? */
263 /* built-in 'exit' handler */
264 static int builtin_exit(struct child_prog *child)
266 if (child->argv[1] == NULL)
269 exit (atoi(child->argv[1]));
272 /* built-in 'fg' and 'bg' handler */
273 static int builtin_fg_bg(struct child_prog *child)
276 struct job *job=NULL;
278 /* If they gave us no args, assume they want the last backgrounded task */
279 if (!child->argv[1]) {
280 for (job = child->family->job_list->head; job; job = job->next) {
281 if (job->jobid == last_jobid) {
286 bb_error_msg("%s: no current job", child->argv[0]);
290 if (sscanf(child->argv[1], "%%%d", &jobnum) != 1) {
291 bb_error_msg("%s: bad argument '%s'", child->argv[0], child->argv[1]);
294 for (job = child->family->job_list->head; job; job = job->next) {
295 if (job->jobid == jobnum) {
300 bb_error_msg("%s: %d: no such job", child->argv[0], jobnum);
305 if (*child->argv[0] == 'f') {
306 /* Put the job into the foreground. */
307 tcsetpgrp(shell_terminal, job->pgrp);
309 child->family->job_list->fg = job;
312 /* Restart the processes in the job */
313 for (i = 0; i < job->num_progs; i++)
314 job->progs[i].is_stopped = 0;
316 job->stopped_progs = 0;
318 if ( (i=kill(- job->pgrp, SIGCONT)) < 0) {
320 remove_job(&job_list, job);
322 bb_perror_msg("kill (SIGCONT)");
329 /* built-in 'help' handler */
330 static int builtin_help(struct child_prog *dummy)
332 struct built_in_command *x;
334 printf("\nBuilt-in commands:\n");
335 printf("-------------------\n");
336 for (x = bltins; x->cmd; x++) {
339 printf("%s\t%s\n", x->cmd, x->descr);
341 for (x = bltins_forking; x->cmd; x++) {
344 printf("%s\t%s\n", x->cmd, x->descr);
350 /* built-in 'jobs' handler */
351 static int builtin_jobs(struct child_prog *child)
356 for (job = child->family->job_list->head; job; job = job->next) {
357 if (job->running_progs == job->stopped_progs)
358 status_string = "Stopped";
360 status_string = "Running";
362 printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->text);
368 /* built-in 'pwd' handler */
369 static int builtin_pwd(struct child_prog *dummy)
371 cwd = xgetcwd((char *)cwd);
373 cwd = bb_msg_unknown;
378 /* built-in 'export VAR=value' handler */
379 static int builtin_export(struct child_prog *child)
382 char *v = child->argv[1];
386 for (e = environ; *e; e++) {
393 fprintf(stderr, "export: %m\n");
394 #ifdef CONFIG_FEATURE_SH_FANCY_PROMPT
395 if (strncmp(v, "PS1=", 4)==0)
399 #ifdef CONFIG_LOCALE_SUPPORT
400 if(strncmp(v, "LC_ALL=", 7)==0)
401 setlocale(LC_ALL, getenv("LC_ALL"));
402 if(strncmp(v, "LC_CTYPE=", 9)==0)
403 setlocale(LC_CTYPE, getenv("LC_CTYPE"));
409 /* built-in 'read VAR' handler */
410 static int builtin_read(struct child_prog *child)
412 int res = 0, len, newlen;
414 char string[MAX_READ];
416 if (child->argv[1]) {
417 /* argument (VAR) given: put "VAR=" into buffer */
418 safe_strncpy(string, child->argv[1], MAX_READ-1);
419 len = strlen(string);
422 fgets(&string[len], sizeof(string) - len, stdin); /* read string */
423 newlen = strlen(string);
425 string[--newlen] = '\0'; /* chomp trailing newline */
427 ** string should now contain "VAR=<value>"
428 ** copy it (putenv() won't do that, so we must make sure
429 ** the string resides in a static buffer!)
432 if((s = strdup(string)))
435 fprintf(stderr, "read: %m\n");
438 fgets(string, sizeof(string), stdin);
443 /* Built-in '.' handler (read-in and execute commands from file) */
444 static int builtin_source(struct child_prog *child)
450 if (child->argv[1] == NULL)
453 input = fopen(child->argv[1], "r");
455 printf( "Couldn't open file '%s'\n", child->argv[1]);
461 /* Now run the file */
462 status = busy_loop(input);
468 /* built-in 'unset VAR' handler */
469 static int builtin_unset(struct child_prog *child)
471 if (child->argv[1] == NULL) {
472 printf( "unset: parameter required.\n");
475 unsetenv(child->argv[1]);
479 static void mark_open(int fd)
481 struct close_me *new = xmalloc(sizeof(struct close_me));
483 new->next = close_me_head;
487 static void mark_closed(int fd)
489 struct close_me *tmp;
490 if (close_me_head == NULL || close_me_head->fd != fd)
491 bb_error_msg_and_die("corrupt close_me");
493 close_me_head = close_me_head->next;
497 static void close_all()
499 struct close_me *c, *tmp;
500 for (c=close_me_head; c; c=tmp) {
505 close_me_head = NULL;
509 /* free up all memory from a job */
510 static void free_job(struct job *cmd)
515 for (i = 0; i < cmd->num_progs; i++) {
516 free(cmd->progs[i].argv);
517 if (cmd->progs[i].redirects)
518 free(cmd->progs[i].redirects);
523 keep = cmd->job_list;
524 memset(cmd, 0, sizeof(struct job));
525 cmd->job_list = keep;
528 /* remove a job from a jobset */
529 static void remove_job(struct jobset *j_list, struct job *job)
534 if (job == j_list->head) {
535 j_list->head = job->next;
537 prevjob = j_list->head;
538 while (prevjob->next != job)
539 prevjob = prevjob->next;
540 prevjob->next = job->next;
544 last_jobid = j_list->head->jobid;
551 /* Checks to see if any background processes have exited -- if they
552 have, figure out why and see if a job has completed */
553 static void checkjobs(struct jobset *j_list)
560 while ((childpid = waitpid(-1, &status, WNOHANG | WUNTRACED)) > 0) {
561 for (job = j_list->head; job; job = job->next) {
563 while (prognum < job->num_progs &&
564 job->progs[prognum].pid != childpid) prognum++;
565 if (prognum < job->num_progs)
569 /* This happens on backticked commands */
573 if (WIFEXITED(status) || WIFSIGNALED(status)) {
575 job->running_progs--;
576 job->progs[prognum].pid = 0;
578 if (!job->running_progs) {
579 printf(JOB_STATUS_FORMAT, job->jobid, "Done", job->text);
581 remove_job(j_list, job);
585 job->stopped_progs++;
586 job->progs[prognum].is_stopped = 1;
589 /* Printing this stuff is a pain, since it tends to
590 * overwrite the prompt an inconveinient moments. So
592 if (job->stopped_progs == job->num_progs) {
593 printf(JOB_STATUS_FORMAT, job->jobid, "Stopped",
600 if (childpid == -1 && errno != ECHILD)
601 bb_perror_msg("waitpid");
604 /* squirrel != NULL means we squirrel away copies of stdin, stdout,
605 * and stderr if they are redirected. */
606 static int setup_redirects(struct child_prog *prog, int squirrel[])
611 struct redir_struct *redir = prog->redirects;
613 for (i = 0; i < prog->num_redirects; i++, redir++) {
614 switch (redir->type) {
618 case REDIRECT_OVERWRITE:
619 mode = O_WRONLY | O_CREAT | O_TRUNC;
621 case REDIRECT_APPEND:
622 mode = O_WRONLY | O_CREAT | O_APPEND;
626 openfd = open(redir->filename, mode, 0666);
628 /* this could get lost if stderr has been redirected, but
629 bash and ash both lose it as well (though zsh doesn't!) */
630 bb_perror_msg("error opening %s", redir->filename);
634 if (openfd != redir->fd) {
635 if (squirrel && redir->fd < 3) {
636 squirrel[redir->fd] = dup(redir->fd);
638 dup2(openfd, redir->fd);
646 static void restore_redirects(int squirrel[])
649 for (i=0; i<3; i++) {
652 /* No error checking. I sure wouldn't know what
653 * to do with an error if I found one! */
660 static inline void cmdedit_set_initial_prompt(void)
662 #ifndef CONFIG_FEATURE_SH_FANCY_PROMPT
671 static inline void setup_prompt_string(char **prompt_str)
673 #ifndef CONFIG_FEATURE_SH_FANCY_PROMPT
674 /* Set up the prompt */
675 if (shell_context == 0) {
677 PS1=xmalloc(strlen(cwd)+4);
678 sprintf(PS1, "%s %s", cwd, ( geteuid() != 0 ) ? "$ ":"# ");
684 *prompt_str = (shell_context==0)? PS1 : PS2;
688 static int get_command(FILE * source, char *command)
692 if (source == NULL) {
693 if (local_pending_command) {
694 /* a command specified (-c option): return it & mark it done */
695 strcpy(command, local_pending_command);
696 free(local_pending_command);
697 local_pending_command = NULL;
703 if (source == stdin) {
704 setup_prompt_string(&prompt_str);
706 #ifdef CONFIG_FEATURE_COMMAND_EDITING
708 ** enable command line editing only while a command line
709 ** is actually being read; otherwise, we'll end up bequeathing
710 ** atexit() handlers and other unwanted stuff to our
711 ** child processes (rob@sysgo.de)
713 cmdedit_read_input(prompt_str, command);
716 fputs(prompt_str, stdout);
720 if (!fgets(command, BUFSIZ - 2, source)) {
729 static char* itoa(register int i)
731 static char a[7]; /* Max 7 ints */
732 register char *b = a + sizeof(a) - 1;
740 *--b = '0' + (i % 10);
749 char * strsep_space( char *string, int * ix)
755 /* Short circuit the trivial case */
756 if ( !string || ! string[*ix])
759 /* Find the end of the token. */
760 while( string && string[*ix] && !isspace(string[*ix]) ) {
764 /* Find the end of any whitespace trailing behind
765 * the token and let that be part of the token */
766 while( string && string[*ix] && isspace(string[*ix]) ) {
770 if (! string && *ix==0) {
771 /* Nothing useful was found */
775 token = xmalloc(*ix+1);
777 strncpy(token, string, *ix);
782 static int expand_arguments(char *command)
784 int total_length=0, length, i, retval, ix = 0;
785 expand_t expand_result;
786 char *tmpcmd, *cmd, *cmd_copy;
787 char *src, *dst, *var;
788 const char *out_of_space = "out of space during expansion";
789 int flags = GLOB_NOCHECK
798 /* get rid of the terminating \n */
801 /* Fix up escape sequences to be the Real Thing(tm) */
802 while( command && command[ix]) {
803 if (command[ix] == '\\') {
804 const char *tmp = command+ix+1;
805 command[ix] = bb_process_escape_sequence( &tmp );
806 memmove(command+ix + 1, tmp, strlen(tmp)+1);
810 /* Use glob and then fixup environment variables and such */
812 /* It turns out that glob is very stupid. We have to feed it one word at a
813 * time since it can't cope with a full string. Here we convert command
814 * (char*) into cmd (char**, one word per string) */
816 /* We need a clean copy, so strsep can mess up the copy while
817 * we write stuff into the original (in a minute) */
818 cmd = cmd_copy = bb_xstrdup(command);
820 for (ix = 0, tmpcmd = cmd;
821 (tmpcmd = strsep_space(cmd, &ix)) != NULL; cmd += ix, ix=0) {
824 /* we need to trim() the result for glob! */
826 retval = glob(tmpcmd, flags, NULL, &expand_result);
827 free(tmpcmd); /* Free mem allocated by strsep_space */
828 if (retval == GLOB_NOSPACE) {
829 /* Mem may have been allocated... */
830 globfree (&expand_result);
831 bb_error_msg(out_of_space);
833 } else if (retval != 0) {
834 /* Some other error. GLOB_NOMATCH shouldn't
835 * happen because of the GLOB_NOCHECK flag in
837 bb_error_msg("syntax error");
840 /* Convert from char** (one word per string) to a simple char*,
841 * but don't overflow command which is BUFSIZ in length */
842 for (i=0; i < expand_result.gl_pathc; i++) {
843 length=strlen(expand_result.gl_pathv[i]);
844 if (total_length+length+1 >= BUFSIZ) {
845 bb_error_msg(out_of_space);
848 strcat(command+total_length, " ");
850 strcat(command+total_length, expand_result.gl_pathv[i]);
851 total_length+=length;
853 globfree (&expand_result);
859 /* Now do the shell variable substitutions which
860 * wordexp can't do for us, namely $? and $! */
862 while((dst = strchr(src,'$')) != NULL){
866 var = itoa(last_return_code);
872 var = itoa(last_bg_pid);
874 /* Everything else like $$, $#, $[0-9], etc. should all be
875 * expanded by wordexp(), so we can in theory skip that stuff
876 * here, but just to be on the safe side (i.e., since uClibc
877 * wordexp doesn't do this stuff yet), lets leave it in for
880 var = itoa(getpid());
885 case '0':case '1':case '2':case '3':case '4':
886 case '5':case '6':case '7':case '8':case '9':
888 int ixx=*(dst+1)-48+1;
899 /* a single character construction was found, and
900 * already handled in the case statement */
903 /* Looks like an environment variable */
905 int num_skip_chars=0;
906 int dstlen = strlen(dst);
907 /* Is this a ${foo} type variable? */
908 if (dstlen >=2 && *(dst+1) == '{') {
909 src=strchr(dst+1, '}');
913 while(isalnum(*src) || *src=='_') src++;
919 *src='\0'; /* temporary */
920 var = getenv(dst + 1 + num_skip_chars);
922 src += num_skip_chars;
925 /* Seems we got an un-expandable variable. So delete it. */
929 int subst_len = strlen(var);
930 int trail_len = strlen(src);
931 if (dst+subst_len+trail_len >= command+BUFSIZ) {
932 bb_error_msg(out_of_space);
935 /* Move stuff to the end of the string to accommodate
936 * filling the created gap with the new stuff */
937 memmove(dst+subst_len, src, trail_len+1);
938 /* Now copy in the new stuff */
939 memcpy(dst, var, subst_len);
947 /* Return cmd->num_progs as 0 if no command is present (e.g. an empty
948 line). If a valid command is found, command_ptr is set to point to
949 the beginning of the next command (if the original command had more
950 then one job associated with it) or NULL if no more commands are
952 static int parse_command(char **command_ptr, struct job *job, int *inbg)
955 char *return_command = NULL;
956 char *src, *buf, *chptr;
960 int i, saw_quote = 0;
963 struct child_prog *prog;
965 /* skip leading white space */
966 while (**command_ptr && isspace(**command_ptr))
969 /* this handles empty lines or leading '#' characters */
970 if (!**command_ptr || (**command_ptr == '#')) {
977 job->progs = xmalloc(sizeof(*job->progs));
979 /* We set the argv elements to point inside of this string. The
980 memory is freed by free_job(). Allocate twice the original
981 length in case we need to quote every single character.
983 Getting clean memory relieves us of the task of NULL
984 terminating things and makes the rest of this look a bit
985 cleaner (though it is, admittedly, a tad less efficient) */
986 job->cmdbuf = command = xcalloc(2*strlen(*command_ptr) + 1, sizeof(char));
990 prog->num_redirects = 0;
991 prog->redirects = NULL;
992 prog->is_stopped = 0;
996 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
997 prog->argv[0] = job->cmdbuf;
1001 while (*src && !done) {
1002 if (quote == *src) {
1008 bb_error_msg("character expected after \\");
1013 /* in shell, "\'" should yield \' */
1014 if (*src != quote) {
1018 } else if (*src == '*' || *src == '?' || *src == '[' ||
1019 *src == ']') *buf++ = '\\';
1021 } else if (isspace(*src)) {
1022 if (*prog->argv[argc_l] || saw_quote) {
1024 /* +1 here leaves room for the NULL which ends argv */
1025 if ((argc_l + 1) == argv_alloced) {
1027 prog->argv = xrealloc(prog->argv,
1028 sizeof(*prog->argv) *
1031 prog->argv[argc_l] = buf;
1042 case '#': /* comment */
1049 case '>': /* redirects */
1051 i = prog->num_redirects++;
1052 prog->redirects = xrealloc(prog->redirects,
1053 sizeof(*prog->redirects) *
1056 prog->redirects[i].fd = -1;
1057 if (buf != prog->argv[argc_l]) {
1058 /* the stuff before this character may be the file number
1060 prog->redirects[i].fd =
1061 strtol(prog->argv[argc_l], &chptr, 10);
1063 if (*chptr && *prog->argv[argc_l]) {
1065 prog->argv[argc_l] = buf;
1069 if (prog->redirects[i].fd == -1) {
1071 prog->redirects[i].fd = 1;
1073 prog->redirects[i].fd = 0;
1076 if (*src++ == '>') {
1078 prog->redirects[i].type =
1079 REDIRECT_APPEND, src++;
1081 prog->redirects[i].type = REDIRECT_OVERWRITE;
1083 prog->redirects[i].type = REDIRECT_INPUT;
1086 /* This isn't POSIX sh compliant. Oh well. */
1088 while (isspace(*chptr))
1092 bb_error_msg("file name expected after %c", *(src-1));
1098 prog->redirects[i].filename = buf;
1099 while (*chptr && !isspace(*chptr))
1102 src = chptr - 1; /* we src++ later */
1103 prog->argv[argc_l] = ++buf;
1106 case '|': /* pipe */
1107 /* finish this command */
1108 if (*prog->argv[argc_l] || saw_quote)
1111 bb_error_msg("empty command in pipe");
1116 prog->argv[argc_l] = NULL;
1118 /* and start the next */
1120 job->progs = xrealloc(job->progs,
1121 sizeof(*job->progs) * job->num_progs);
1122 prog = job->progs + (job->num_progs - 1);
1123 prog->num_redirects = 0;
1124 prog->redirects = NULL;
1125 prog->is_stopped = 0;
1130 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1131 prog->argv[0] = ++buf;
1134 while (*src && isspace(*src))
1138 bb_error_msg("empty command in pipe");
1143 src--; /* we'll ++ it at the end of the loop */
1147 case '&': /* background */
1149 case ';': /* multiple commands */
1151 return_command = *command_ptr + (src - *command_ptr) + 1;
1157 bb_error_msg("character expected after \\");
1161 if (*src == '*' || *src == '[' || *src == ']'
1162 || *src == '?') *buf++ = '\\';
1171 if (*prog->argv[argc_l] || saw_quote) {
1178 prog->argv[argc_l] = NULL;
1180 if (!return_command) {
1181 job->text = xmalloc(strlen(*command_ptr) + 1);
1182 strcpy(job->text, *command_ptr);
1184 /* This leaves any trailing spaces, which is a bit sloppy */
1185 count = return_command - *command_ptr;
1186 job->text = xmalloc(count + 1);
1187 strncpy(job->text, *command_ptr, count);
1188 job->text[count] = '\0';
1191 *command_ptr = return_command;
1196 /* Run the child_prog, no matter what kind of command it uses.
1198 static int pseudo_exec(struct child_prog *child)
1200 struct built_in_command *x;
1201 #ifdef CONFIG_FEATURE_SH_STANDALONE_SHELL
1205 /* Check if the command matches any of the non-forking builtins.
1206 * Depending on context, this might be redundant. But it's
1207 * easier to waste a few CPU cycles than it is to figure out
1208 * if this is one of those cases.
1210 for (x = bltins; x->cmd; x++) {
1211 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1212 _exit(x->function(child));
1216 /* Check if the command matches any of the forking builtins. */
1217 for (x = bltins_forking; x->cmd; x++) {
1218 if (strcmp(child->argv[0], x->cmd) == 0) {
1219 bb_applet_name=x->cmd;
1220 _exit (x->function(child));
1223 #ifdef CONFIG_FEATURE_SH_STANDALONE_SHELL
1224 /* Check if the command matches any busybox internal
1225 * commands ("applets") here. Following discussions from
1226 * November 2000 on busybox@busybox.net, don't use
1227 * bb_get_last_path_component(). This way explicit (with
1228 * slashes) filenames will never be interpreted as an
1229 * applet, just like with builtins. This way the user can
1230 * override an applet with an explicit filename reference.
1231 * The only downside to this change is that an explicit
1232 * /bin/foo invocation will fork and exec /bin/foo, even if
1233 * /bin/foo is a symlink to busybox.
1235 name = child->argv[0];
1237 #ifdef CONFIG_FEATURE_SH_APPLETS_ALWAYS_WIN
1238 /* If you enable CONFIG_FEATURE_SH_APPLETS_ALWAYS_WIN, then
1239 * if you run /bin/cat, it will use BusyBox cat even if
1240 * /bin/cat exists on the filesystem and is _not_ busybox.
1241 * Some systems want this, others do not. Choose wisely. :-)
1243 name = bb_get_last_path_component(name);
1247 char** argv_l=child->argv;
1249 for(argc_l=0;*argv_l!=NULL; argv_l++, argc_l++);
1251 run_applet_by_name(name, argc_l, child->argv);
1255 execvp(child->argv[0], child->argv);
1257 /* Do not use bb_perror_msg_and_die() here, since we must not
1258 * call exit() but should call _exit() instead */
1259 fprintf(stderr, "%s: %m\n", child->argv[0]);
1260 _exit(EXIT_FAILURE);
1263 static void insert_job(struct job *newjob, int inbg)
1266 struct jobset *j_list=newjob->job_list;
1268 /* find the ID for thejob to use */
1270 for (thejob = j_list->head; thejob; thejob = thejob->next)
1271 if (thejob->jobid >= newjob->jobid)
1272 newjob->jobid = thejob->jobid + 1;
1274 /* add thejob to the list of running jobs */
1275 if (!j_list->head) {
1276 thejob = j_list->head = xmalloc(sizeof(*thejob));
1278 for (thejob = j_list->head; thejob->next; thejob = thejob->next) /* nothing */;
1279 thejob->next = xmalloc(sizeof(*thejob));
1280 thejob = thejob->next;
1283 *thejob = *newjob; /* physically copy the struct job */
1284 thejob->next = NULL;
1285 thejob->running_progs = thejob->num_progs;
1286 thejob->stopped_progs = 0;
1289 /* we don't wait for background thejobs to return -- append it
1290 to the list of backgrounded thejobs and leave it alone */
1291 printf("[%d] %d\n", thejob->jobid,
1292 newjob->progs[newjob->num_progs - 1].pid);
1293 last_jobid = newjob->jobid;
1294 last_bg_pid=newjob->progs[newjob->num_progs - 1].pid;
1296 newjob->job_list->fg = thejob;
1298 /* move the new process group into the foreground */
1299 /* suppress messages when run from /linuxrc mag@sysgo.de */
1300 if (tcsetpgrp(shell_terminal, newjob->pgrp) && errno != ENOTTY)
1301 bb_perror_msg("tcsetpgrp");
1305 static int run_command(struct job *newjob, int inbg, int outpipe[2])
1307 /* struct job *thejob; */
1309 int nextin, nextout;
1310 int pipefds[2]; /* pipefd[0] is for reading */
1311 struct built_in_command *x;
1312 struct child_prog *child;
1314 nextin = 0, nextout = 1;
1315 for (i = 0; i < newjob->num_progs; i++) {
1316 child = & (newjob->progs[i]);
1318 if ((i + 1) < newjob->num_progs) {
1319 if (pipe(pipefds)<0) bb_perror_msg_and_die("pipe");
1320 nextout = pipefds[1];
1322 if (outpipe[1]!=-1) {
1323 nextout = outpipe[1];
1330 /* Check if the command matches any non-forking builtins,
1331 * but only if this is a simple command.
1332 * Non-forking builtins within pipes have to fork anyway,
1333 * and are handled in pseudo_exec. "echo foo | read bar"
1334 * is doomed to failure, and doesn't work on bash, either.
1336 if (newjob->num_progs == 1) {
1337 for (x = bltins; x->cmd; x++) {
1338 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1339 int squirrel[] = {-1, -1, -1};
1341 setup_redirects(child, squirrel);
1342 rcode = x->function(child);
1343 restore_redirects(squirrel);
1349 #if !defined(__UCLIBC__) || defined(__UCLIBC_HAS_MMU__)
1350 if (!(child->pid = fork()))
1352 if (!(child->pid = vfork()))
1355 /* Set the handling for job control signals back to the default. */
1356 signal(SIGINT, SIG_DFL);
1357 signal(SIGQUIT, SIG_DFL);
1358 signal(SIGTSTP, SIG_DFL);
1359 signal(SIGTTIN, SIG_DFL);
1360 signal(SIGTTOU, SIG_DFL);
1361 signal(SIGCHLD, SIG_DFL);
1365 if (outpipe[1]!=-1) {
1375 dup2(nextout, 2); /* Really? */
1380 /* explicit redirects override pipes */
1381 setup_redirects(child,NULL);
1385 if (outpipe[1]!=-1) {
1389 /* put our child in the process group whose leader is the
1390 first process in this pipe */
1391 setpgid(child->pid, newjob->progs[0].pid);
1397 /* If there isn't another process, nextin is garbage
1398 but it doesn't matter */
1399 nextin = pipefds[0];
1402 newjob->pgrp = newjob->progs[0].pid;
1404 insert_job(newjob, inbg);
1409 static int busy_loop(FILE * input)
1412 char *next_command = NULL;
1418 newjob.job_list = &job_list;
1419 newjob.job_context = DEFAULT_CONTEXT;
1421 /* save current owner of TTY so we can restore it on exit */
1422 parent_pgrp = tcgetpgrp(shell_terminal);
1424 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1428 /* no job is in the foreground */
1430 /* see if any background processes have exited */
1431 checkjobs(&job_list);
1433 if (!next_command) {
1434 if (get_command(input, command))
1436 next_command = command;
1439 if (! expand_arguments(next_command)) {
1441 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1442 next_command = NULL;
1446 if (!parse_command(&next_command, &newjob, &inbg) &&
1448 int pipefds[2] = {-1,-1};
1449 debug_printf( "job=%p fed to run_command by busy_loop()'\n",
1451 run_command(&newjob, inbg, pipefds);
1455 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1456 next_command = NULL;
1459 /* a job is running in the foreground; wait for it */
1461 while (!job_list.fg->progs[i].pid ||
1462 job_list.fg->progs[i].is_stopped == 1) i++;
1464 if (waitpid(job_list.fg->progs[i].pid, &status, WUNTRACED)<0) {
1465 if (errno != ECHILD) {
1466 bb_perror_msg_and_die("waitpid(%d)",job_list.fg->progs[i].pid);
1470 if (WIFEXITED(status) || WIFSIGNALED(status)) {
1471 /* the child exited */
1472 job_list.fg->running_progs--;
1473 job_list.fg->progs[i].pid = 0;
1475 last_return_code=WEXITSTATUS(status);
1477 if (!job_list.fg->running_progs) {
1479 remove_job(&job_list, job_list.fg);
1483 /* the child was stopped */
1484 job_list.fg->stopped_progs++;
1485 job_list.fg->progs[i].is_stopped = 1;
1487 if (job_list.fg->stopped_progs == job_list.fg->running_progs) {
1488 printf("\n" JOB_STATUS_FORMAT, job_list.fg->jobid,
1489 "Stopped", job_list.fg->text);
1495 /* move the shell to the foreground */
1496 /* suppress messages when run from /linuxrc mag@sysgo.de */
1497 if (tcsetpgrp(shell_terminal, getpgrp()) && errno != ENOTTY)
1498 bb_perror_msg("tcsetpgrp");
1504 /* return controlling TTY back to parent process group before exiting */
1505 if (tcsetpgrp(shell_terminal, parent_pgrp) && errno != ENOTTY)
1506 bb_perror_msg("tcsetpgrp");
1508 /* return exit status if called with "-c" */
1509 if (input == NULL && WIFEXITED(status))
1510 return WEXITSTATUS(status);
1516 #ifdef CONFIG_FEATURE_CLEAN_UP
1517 void free_memory(void)
1519 if (cwd && cwd!=bb_msg_unknown) {
1522 if (local_pending_command)
1523 free(local_pending_command);
1525 if (job_list.fg && !job_list.fg->running_progs) {
1526 remove_job(&job_list, job_list.fg);
1531 /* Make sure we have a controlling tty. If we get started under a job
1532 * aware app (like bash for example), make sure we are now in charge so
1533 * we don't fight over who gets the foreground */
1534 static void setup_job_control(void)
1538 /* Loop until we are in the foreground. */
1539 while ((status = tcgetpgrp (shell_terminal)) >= 0) {
1540 if (status == (shell_pgrp = getpgrp ())) {
1543 kill (- shell_pgrp, SIGTTIN);
1546 /* Ignore interactive and job-control signals. */
1547 signal(SIGINT, SIG_IGN);
1548 signal(SIGQUIT, SIG_IGN);
1549 signal(SIGTSTP, SIG_IGN);
1550 signal(SIGTTIN, SIG_IGN);
1551 signal(SIGTTOU, SIG_IGN);
1552 signal(SIGCHLD, SIG_IGN);
1554 /* Put ourselves in our own process group. */
1556 shell_pgrp = getpid ();
1557 setpgid (shell_pgrp, shell_pgrp);
1559 /* Grab control of the terminal. */
1560 tcsetpgrp(shell_terminal, shell_pgrp);
1563 int lash_main(int argc_l, char **argv_l)
1565 int opt, interactive=FALSE;
1566 FILE *input = stdin;
1570 /* These variables need re-initializing when recursing */
1572 local_pending_command = NULL;
1573 close_me_head = NULL;
1574 job_list.head = NULL;
1578 if (argv[0] && argv[0][0] == '-') {
1580 prof_input = fopen("/etc/profile", "r");
1582 int tmp_fd = fileno(prof_input);
1584 /* Now run the file */
1585 busy_loop(prof_input);
1587 mark_closed(tmp_fd);
1591 while ((opt = getopt(argc_l, argv_l, "cxi")) > 0) {
1595 if (local_pending_command != 0)
1596 bb_error_msg_and_die("multiple -c arguments");
1597 local_pending_command = bb_xstrdup(argv[optind]);
1608 /* A shell is interactive if the `-i' flag was given, or if all of
1609 * the following conditions are met:
1611 * no arguments remaining or the -s flag given
1612 * standard input is a terminal
1613 * standard output is a terminal
1614 * Refer to Posix.2, the description of the `sh' utility. */
1615 if (argv[optind]==NULL && input==stdin &&
1616 isatty(fileno(stdin)) && isatty(fileno(stdout))) {
1619 setup_job_control();
1620 if (interactive==TRUE) {
1621 //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
1622 /* Looks like they want an interactive shell */
1623 #ifndef CONFIG_FEATURE_SH_EXTRA_QUIET
1624 printf( "\n\n" BB_BANNER " Built-in shell (lash)\n");
1625 printf( "Enter 'help' for a list of built-in commands.\n\n");
1627 } else if (local_pending_command==NULL) {
1628 //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
1629 input = bb_xfopen(argv[optind], "r");
1630 mark_open(fileno(input)); /* be lazy, never mark this closed */
1633 /* initialize the cwd -- this is never freed...*/
1636 cwd = bb_msg_unknown;
1638 #ifdef CONFIG_FEATURE_CLEAN_UP
1639 atexit(free_memory);
1642 #ifdef CONFIG_FEATURE_COMMAND_EDITING
1643 cmdedit_set_initial_prompt();
1648 return (busy_loop(input));