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 /* This shell's parsing engine is officially at a dead-end.
29 * Future work shell work should be done using hush.c
32 //For debugging/development on the shell only...
43 #include <sys/ioctl.h>
51 #ifdef BB_LOCALE_SUPPORT
56 #define expand_t glob_t
59 static const int MAX_READ = 128; /* size of input buffer for `read' builtin */
60 #define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
63 enum redir_type { REDIRECT_INPUT, REDIRECT_OVERWRITE,
67 static const unsigned int DEFAULT_CONTEXT=0x1;
68 static const unsigned int IF_TRUE_CONTEXT=0x2;
69 static const unsigned int IF_FALSE_CONTEXT=0x4;
70 static const unsigned int THEN_EXP_CONTEXT=0x8;
71 static const unsigned int ELSE_EXP_CONTEXT=0x10;
75 struct job *head; /* head of list of running jobs */
76 struct job *fg; /* current foreground job */
80 enum redir_type type; /* type of redirection */
81 int fd; /* file descriptor being redirected */
82 char *filename; /* file to redirect fd to */
86 pid_t pid; /* 0 if exited */
87 char **argv; /* program name and arguments */
88 int num_redirects; /* elements in redirection array */
89 struct redir_struct *redirects; /* I/O redirects */
90 int is_stopped; /* is the program currently running? */
91 struct job *family; /* pointer back to the child's parent job */
95 int jobid; /* job number */
96 int num_progs; /* total number of programs in job */
97 int running_progs; /* number of programs running */
98 char *text; /* name of job */
99 char *cmdbuf; /* buffer various argv's point into */
100 pid_t pgrp; /* process group ID for the job */
101 struct child_prog *progs; /* array of programs in job */
102 struct job *next; /* to track background commands */
103 int stopped_progs; /* number of programs alive, but stopped */
104 unsigned int job_context; /* bitmask defining current context */
105 struct jobset *job_list;
108 struct built_in_command {
109 char *cmd; /* name */
110 char *descr; /* description */
111 int (*function) (struct child_prog *); /* function ptr */
116 struct close_me *next;
119 /* function prototypes for builtins */
120 static int builtin_cd(struct child_prog *cmd);
121 static int builtin_exec(struct child_prog *cmd);
122 static int builtin_exit(struct child_prog *cmd);
123 static int builtin_fg_bg(struct child_prog *cmd);
124 static int builtin_help(struct child_prog *cmd);
125 static int builtin_jobs(struct child_prog *dummy);
126 static int builtin_pwd(struct child_prog *dummy);
127 static int builtin_export(struct child_prog *cmd);
128 static int builtin_source(struct child_prog *cmd);
129 static int builtin_unset(struct child_prog *cmd);
130 static int builtin_read(struct child_prog *cmd);
133 /* function prototypes for shell stuff */
134 static void mark_open(int fd);
135 static void mark_closed(int fd);
136 static void close_all(void);
137 static void checkjobs(struct jobset *job_list);
138 static void remove_job(struct jobset *j_list, struct job *job);
139 static int get_command(FILE * source, char *command);
140 static int parse_command(char **command_ptr, struct job *job, int *inbg);
141 static int run_command(struct job *newjob, int inbg, int outpipe[2]);
142 static int pseudo_exec(struct child_prog *cmd) __attribute__ ((noreturn));
143 static int busy_loop(FILE * input);
146 /* Table of built-in functions (these are non-forking builtins, meaning they
147 * can change global variables in the parent shell process but they will not
148 * work with pipes and redirects; 'unset foo | whatever' will not work) */
149 static struct built_in_command bltins[] = {
150 {"bg", "Resume a job in the background", builtin_fg_bg},
151 {"cd", "Change working directory", builtin_cd},
152 {"exec", "Exec command, replacing this shell with the exec'd process", builtin_exec},
153 {"exit", "Exit from shell()", builtin_exit},
154 {"fg", "Bring job into the foreground", builtin_fg_bg},
155 {"jobs", "Lists the active jobs", builtin_jobs},
156 {"export", "Set environment variable", builtin_export},
157 {"unset", "Unset environment variable", builtin_unset},
158 {"read", "Input environment variable", builtin_read},
159 {".", "Source-in and run commands in a file", builtin_source},
160 /* to do: add ulimit */
164 /* Table of forking built-in functions (things that fork cannot change global
165 * variables in the parent process, such as the current working directory) */
166 static struct built_in_command bltins_forking[] = {
167 {"pwd", "Print current directory", builtin_pwd},
168 {"help", "List shell built-in commands", builtin_help},
173 /* Variables we export */
174 unsigned int shell_context; /* Used in cmdedit.c to reset the
175 context when someone hits ^C */
178 /* Globals that are static to this file */
179 static const char *cwd;
180 static char *local_pending_command = NULL;
181 static struct jobset job_list = { NULL, NULL };
184 static struct close_me *close_me_head;
185 static int last_return_code;
186 static int last_bg_pid;
187 static unsigned int last_jobid;
188 static int shell_terminal;
189 static pid_t shell_pgrp;
191 static char *PS2 = "> ";
195 static inline void debug_printf(const char *format, ...)
198 va_start(args, format);
199 vfprintf(stderr, format, args);
203 static inline void debug_printf(const char *format, ...) { }
207 Most builtins need access to the struct child_prog that has
208 their arguments, previously coded as cmd->progs[0]. That coding
209 can exhibit a bug, if the builtin is not the first command in
210 a pipeline: "echo foo | exec sort" will attempt to exec foo.
212 builtin previous use notes
213 ------ ----------------- ---------
215 exec cmd->progs[0] squashed bug: didn't look for applets or forking builtins
217 fg_bg cmd->progs[0], job_list->head, job_list->fg
226 I added "struct job *family;" to struct child_prog,
227 and switched API to builtin_foo(struct child_prog *child);
228 So cmd->text becomes child->family->text
229 cmd->job_context becomes child->family->job_context
230 cmd->progs[0] becomes *child
231 job_list becomes child->family->job_list
234 /* built-in 'cd <path>' handler */
235 static int builtin_cd(struct child_prog *child)
239 if (child->argv[1] == NULL)
240 newdir = getenv("HOME");
242 newdir = child->argv[1];
244 printf("cd: %s: %m\n", newdir);
247 cwd = xgetcwd((char *)cwd);
253 /* built-in 'exec' handler */
254 static int builtin_exec(struct child_prog *child)
256 if (child->argv[1] == NULL)
257 return EXIT_SUCCESS; /* Really? */
264 /* built-in 'exit' handler */
265 static int builtin_exit(struct child_prog *child)
267 if (child->argv[1] == NULL)
270 exit (atoi(child->argv[1]));
273 /* built-in 'fg' and 'bg' handler */
274 static int builtin_fg_bg(struct child_prog *child)
277 struct job *job=NULL;
279 /* If they gave us no args, assume they want the last backgrounded task */
280 if (!child->argv[1]) {
281 for (job = child->family->job_list->head; job; job = job->next) {
282 if (job->jobid == last_jobid) {
287 error_msg("%s: no current job", child->argv[0]);
291 if (sscanf(child->argv[1], "%%%d", &jobnum) != 1) {
292 error_msg("%s: bad argument '%s'", child->argv[0], child->argv[1]);
295 for (job = child->family->job_list->head; job; job = job->next) {
296 if (job->jobid == jobnum) {
301 error_msg("%s: %d: no such job", child->argv[0], jobnum);
306 if (*child->argv[0] == 'f') {
307 /* Put the job into the foreground. */
308 tcsetpgrp(shell_terminal, job->pgrp);
310 child->family->job_list->fg = job;
313 /* Restart the processes in the job */
314 for (i = 0; i < job->num_progs; i++)
315 job->progs[i].is_stopped = 0;
317 job->stopped_progs = 0;
319 if ( (i=kill(- job->pgrp, SIGCONT)) < 0) {
321 remove_job(&job_list, job);
323 perror_msg("kill (SIGCONT)");
330 /* built-in 'help' handler */
331 static int builtin_help(struct child_prog *dummy)
333 struct built_in_command *x;
335 printf("\nBuilt-in commands:\n");
336 printf("-------------------\n");
337 for (x = bltins; x->cmd; x++) {
340 printf("%s\t%s\n", x->cmd, x->descr);
342 for (x = bltins_forking; x->cmd; x++) {
345 printf("%s\t%s\n", x->cmd, x->descr);
351 /* built-in 'jobs' handler */
352 static int builtin_jobs(struct child_prog *child)
357 for (job = child->family->job_list->head; job; job = job->next) {
358 if (job->running_progs == job->stopped_progs)
359 status_string = "Stopped";
361 status_string = "Running";
363 printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->text);
369 /* built-in 'pwd' handler */
370 static int builtin_pwd(struct child_prog *dummy)
372 cwd = xgetcwd((char *)cwd);
379 /* built-in 'export VAR=value' handler */
380 static int builtin_export(struct child_prog *child)
383 char *v = child->argv[1];
387 for (e = environ; *e; e++) {
394 fprintf(stderr, "export: %m\n");
395 #ifdef BB_FEATURE_SH_FANCY_PROMPT
396 if (strncmp(v, "PS1=", 4)==0)
400 #ifdef BB_LOCALE_SUPPORT
401 if(strncmp(v, "LC_ALL=", 7)==0)
402 setlocale(LC_ALL, getenv("LC_ALL"));
403 if(strncmp(v, "LC_CTYPE=", 9)==0)
404 setlocale(LC_CTYPE, getenv("LC_CTYPE"));
410 /* built-in 'read VAR' handler */
411 static int builtin_read(struct child_prog *child)
413 int res = 0, len, newlen;
415 char string[MAX_READ];
417 if (child->argv[1]) {
418 /* argument (VAR) given: put "VAR=" into buffer */
419 strcpy(string, child->argv[1]);
420 len = strlen(string);
423 fgets(&string[len], sizeof(string) - len, stdin); /* read string */
424 newlen = strlen(string);
426 string[--newlen] = '\0'; /* chomp trailing newline */
428 ** string should now contain "VAR=<value>"
429 ** copy it (putenv() won't do that, so we must make sure
430 ** the string resides in a static buffer!)
433 if((s = strdup(string)))
436 fprintf(stderr, "read: %m\n");
439 fgets(string, sizeof(string), stdin);
444 /* Built-in '.' handler (read-in and execute commands from file) */
445 static int builtin_source(struct child_prog *child)
451 if (child->argv[1] == NULL)
454 input = fopen(child->argv[1], "r");
456 printf( "Couldn't open file '%s'\n", child->argv[1]);
462 /* Now run the file */
463 status = busy_loop(input);
469 /* built-in 'unset VAR' handler */
470 static int builtin_unset(struct child_prog *child)
472 if (child->argv[1] == NULL) {
473 printf( "unset: parameter required.\n");
476 unsetenv(child->argv[1]);
480 static void mark_open(int fd)
482 struct close_me *new = xmalloc(sizeof(struct close_me));
484 new->next = close_me_head;
488 static void mark_closed(int fd)
490 struct close_me *tmp;
491 if (close_me_head == NULL || close_me_head->fd != fd)
492 error_msg_and_die("corrupt close_me");
494 close_me_head = close_me_head->next;
498 static void close_all()
500 struct close_me *c, *tmp;
501 for (c=close_me_head; c; c=tmp) {
506 close_me_head = NULL;
510 /* free up all memory from a job */
511 static void free_job(struct job *cmd)
516 for (i = 0; i < cmd->num_progs; i++) {
517 free(cmd->progs[i].argv);
518 if (cmd->progs[i].redirects)
519 free(cmd->progs[i].redirects);
527 keep = cmd->job_list;
528 memset(cmd, 0, sizeof(struct job));
529 cmd->job_list = keep;
532 /* remove a job from a jobset */
533 static void remove_job(struct jobset *j_list, struct job *job)
538 if (job == j_list->head) {
539 j_list->head = job->next;
541 prevjob = j_list->head;
542 while (prevjob->next != job)
543 prevjob = prevjob->next;
544 prevjob->next = job->next;
548 last_jobid = j_list->head->jobid;
555 /* Checks to see if any background processes have exited -- if they
556 have, figure out why and see if a job has completed */
557 static void checkjobs(struct jobset *j_list)
564 while ((childpid = waitpid(-1, &status, WNOHANG | WUNTRACED)) > 0) {
565 for (job = j_list->head; job; job = job->next) {
567 while (prognum < job->num_progs &&
568 job->progs[prognum].pid != childpid) prognum++;
569 if (prognum < job->num_progs)
573 /* This happens on backticked commands */
577 if (WIFEXITED(status) || WIFSIGNALED(status)) {
579 job->running_progs--;
580 job->progs[prognum].pid = 0;
582 if (!job->running_progs) {
583 printf(JOB_STATUS_FORMAT, job->jobid, "Done", job->text);
585 remove_job(j_list, job);
589 job->stopped_progs++;
590 job->progs[prognum].is_stopped = 1;
593 /* Printing this stuff is a pain, since it tends to
594 * overwrite the prompt an inconveinient moments. So
596 if (job->stopped_progs == job->num_progs) {
597 printf(JOB_STATUS_FORMAT, job->jobid, "Stopped",
604 if (childpid == -1 && errno != ECHILD)
605 perror_msg("waitpid");
608 /* squirrel != NULL means we squirrel away copies of stdin, stdout,
609 * and stderr if they are redirected. */
610 static int setup_redirects(struct child_prog *prog, int squirrel[])
615 struct redir_struct *redir = prog->redirects;
617 for (i = 0; i < prog->num_redirects; i++, redir++) {
618 switch (redir->type) {
622 case REDIRECT_OVERWRITE:
623 mode = O_WRONLY | O_CREAT | O_TRUNC;
625 case REDIRECT_APPEND:
626 mode = O_WRONLY | O_CREAT | O_APPEND;
630 openfd = open(redir->filename, mode, 0666);
632 /* this could get lost if stderr has been redirected, but
633 bash and ash both lose it as well (though zsh doesn't!) */
634 perror_msg("error opening %s", redir->filename);
638 if (openfd != redir->fd) {
639 if (squirrel && redir->fd < 3) {
640 squirrel[redir->fd] = dup(redir->fd);
642 dup2(openfd, redir->fd);
650 static void restore_redirects(int squirrel[])
653 for (i=0; i<3; i++) {
656 /* No error checking. I sure wouldn't know what
657 * to do with an error if I found one! */
664 static inline void cmdedit_set_initial_prompt(void)
666 #ifndef BB_FEATURE_SH_FANCY_PROMPT
675 static inline void setup_prompt_string(char **prompt_str)
677 #ifndef BB_FEATURE_SH_FANCY_PROMPT
678 /* Set up the prompt */
679 if (shell_context == 0) {
682 PS1=xmalloc(strlen(cwd)+4);
683 sprintf(PS1, "%s %s", cwd, ( geteuid() != 0 ) ? "$ ":"# ");
689 *prompt_str = (shell_context==0)? PS1 : PS2;
693 static int get_command(FILE * source, char *command)
697 if (source == NULL) {
698 if (local_pending_command) {
699 /* a command specified (-c option): return it & mark it done */
700 strcpy(command, local_pending_command);
701 free(local_pending_command);
702 local_pending_command = NULL;
708 if (source == stdin) {
709 setup_prompt_string(&prompt_str);
711 #ifdef BB_FEATURE_COMMAND_EDITING
713 ** enable command line editing only while a command line
714 ** is actually being read; otherwise, we'll end up bequeathing
715 ** atexit() handlers and other unwanted stuff to our
716 ** child processes (rob@sysgo.de)
718 cmdedit_read_input(prompt_str, command);
722 fputs(prompt_str, stdout);
726 if (!fgets(command, BUFSIZ - 2, source)) {
735 static char* itoa(register int i)
737 static char a[7]; /* Max 7 ints */
738 register char *b = a + sizeof(a) - 1;
746 *--b = '0' + (i % 10);
755 char * strsep_space( char *string, int * ix)
761 /* Short circuit the trivial case */
762 if ( !string || ! string[*ix])
765 /* Find the end of the token. */
766 while( string && string[*ix] && !isspace(string[*ix]) ) {
770 /* Find the end of any whitespace trailing behind
771 * the token and let that be part of the token */
772 while( string && string[*ix] && isspace(string[*ix]) ) {
776 if (! string && *ix==0) {
777 /* Nothing useful was found */
781 token = xmalloc(*ix+1);
783 strncpy(token, string, *ix);
788 static int expand_arguments(char *command)
790 int total_length=0, length, i, retval, ix = 0;
791 expand_t expand_result;
792 char *tmpcmd, *cmd, *cmd_copy;
793 char *src, *dst, *var;
794 const char *out_of_space = "out of space during expansion";
795 int flags = GLOB_NOCHECK
804 /* get rid of the terminating \n */
807 /* Fix up escape sequences to be the Real Thing(tm) */
808 while( command && command[ix]) {
809 if (command[ix] == '\\') {
810 const char *tmp = command+ix+1;
811 command[ix] = process_escape_sequence( &tmp );
812 memmove(command+ix + 1, tmp, strlen(tmp)+1);
816 /* Use glob and then fixup environment variables and such */
818 /* It turns out that glob is very stupid. We have to feed it one word at a
819 * time since it can't cope with a full string. Here we convert command
820 * (char*) into cmd (char**, one word per string) */
822 /* We need a clean copy, so strsep can mess up the copy while
823 * we write stuff into the original (in a minute) */
824 cmd = cmd_copy = strdup(command);
826 for (ix = 0, tmpcmd = cmd;
827 (tmpcmd = strsep_space(cmd, &ix)) != NULL; cmd += ix, ix=0) {
830 /* we need to trim() the result for glob! */
832 retval = glob(tmpcmd, flags, NULL, &expand_result);
833 free(tmpcmd); /* Free mem allocated by strsep_space */
834 if (retval == GLOB_NOSPACE) {
835 /* Mem may have been allocated... */
836 globfree (&expand_result);
837 error_msg(out_of_space);
839 } else if (retval != 0) {
840 /* Some other error. GLOB_NOMATCH shouldn't
841 * happen because of the GLOB_NOCHECK flag in
843 error_msg("syntax error");
846 /* Convert from char** (one word per string) to a simple char*,
847 * but don't overflow command which is BUFSIZ in length */
848 for (i=0; i < expand_result.gl_pathc; i++) {
849 length=strlen(expand_result.gl_pathv[i]);
850 if (total_length+length+1 >= BUFSIZ) {
851 error_msg(out_of_space);
854 strcat(command+total_length, " ");
856 strcat(command+total_length, expand_result.gl_pathv[i]);
857 total_length+=length;
859 globfree (&expand_result);
865 /* Now do the shell variable substitutions which
866 * wordexp can't do for us, namely $? and $! */
868 while((dst = strchr(src,'$')) != NULL){
872 var = itoa(last_return_code);
878 var = itoa(last_bg_pid);
880 /* Everything else like $$, $#, $[0-9], etc. should all be
881 * expanded by wordexp(), so we can in theory skip that stuff
882 * here, but just to be on the safe side (i.e., since uClibc
883 * wordexp doesn't do this stuff yet), lets leave it in for
886 var = itoa(getpid());
891 case '0':case '1':case '2':case '3':case '4':
892 case '5':case '6':case '7':case '8':case '9':
894 int ixx=*(dst + 1)-48;
905 /* a single character construction was found, and
906 * already handled in the case statement */
909 /* Looks like an environment variable */
911 int num_skip_chars=0;
912 int dstlen = strlen(dst);
913 /* Is this a ${foo} type variable? */
914 if (dstlen >=2 && *(dst+1) == '{') {
915 src=strchr(dst+1, '}');
919 while(isalnum(*src) || *src=='_') src++;
925 *src='\0'; /* temporary */
926 var = getenv(dst + 1 + num_skip_chars);
928 src += num_skip_chars;
931 /* Seems we got an un-expandable variable. So delete it. */
935 int subst_len = strlen(var);
936 int trail_len = strlen(src);
937 if (dst+subst_len+trail_len >= command+BUFSIZ) {
938 error_msg(out_of_space);
941 /* Move stuff to the end of the string to accommodate
942 * filling the created gap with the new stuff */
943 memmove(dst+subst_len, src, trail_len+1);
944 /* Now copy in the new stuff */
945 memcpy(dst, var, subst_len);
953 /* Return cmd->num_progs as 0 if no command is present (e.g. an empty
954 line). If a valid command is found, command_ptr is set to point to
955 the beginning of the next command (if the original command had more
956 then one job associated with it) or NULL if no more commands are
958 static int parse_command(char **command_ptr, struct job *job, int *inbg)
961 char *return_command = NULL;
962 char *src, *buf, *chptr;
966 int i, saw_quote = 0;
969 struct child_prog *prog;
971 /* skip leading white space */
972 while (**command_ptr && isspace(**command_ptr))
975 /* this handles empty lines or leading '#' characters */
976 if (!**command_ptr || (**command_ptr == '#')) {
983 job->progs = xmalloc(sizeof(*job->progs));
985 /* We set the argv elements to point inside of this string. The
986 memory is freed by free_job(). Allocate twice the original
987 length in case we need to quote every single character.
989 Getting clean memory relieves us of the task of NULL
990 terminating things and makes the rest of this look a bit
991 cleaner (though it is, admittedly, a tad less efficient) */
992 job->cmdbuf = command = xcalloc(2*strlen(*command_ptr) + 1, sizeof(char));
996 prog->num_redirects = 0;
997 prog->redirects = NULL;
998 prog->is_stopped = 0;
1002 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1003 prog->argv[0] = job->cmdbuf;
1007 while (*src && !done) {
1008 if (quote == *src) {
1014 error_msg("character expected after \\");
1019 /* in shell, "\'" should yield \' */
1020 if (*src != quote) {
1024 } else if (*src == '*' || *src == '?' || *src == '[' ||
1025 *src == ']') *buf++ = '\\';
1027 } else if (isspace(*src)) {
1028 if (*prog->argv[argc_l] || saw_quote) {
1030 /* +1 here leaves room for the NULL which ends argv */
1031 if ((argc_l + 1) == argv_alloced) {
1033 prog->argv = xrealloc(prog->argv,
1034 sizeof(*prog->argv) *
1037 prog->argv[argc_l] = buf;
1048 case '#': /* comment */
1055 case '>': /* redirects */
1057 i = prog->num_redirects++;
1058 prog->redirects = xrealloc(prog->redirects,
1059 sizeof(*prog->redirects) *
1062 prog->redirects[i].fd = -1;
1063 if (buf != prog->argv[argc_l]) {
1064 /* the stuff before this character may be the file number
1066 prog->redirects[i].fd =
1067 strtol(prog->argv[argc_l], &chptr, 10);
1069 if (*chptr && *prog->argv[argc_l]) {
1071 prog->argv[argc_l] = buf;
1075 if (prog->redirects[i].fd == -1) {
1077 prog->redirects[i].fd = 1;
1079 prog->redirects[i].fd = 0;
1082 if (*src++ == '>') {
1084 prog->redirects[i].type =
1085 REDIRECT_APPEND, src++;
1087 prog->redirects[i].type = REDIRECT_OVERWRITE;
1089 prog->redirects[i].type = REDIRECT_INPUT;
1092 /* This isn't POSIX sh compliant. Oh well. */
1094 while (isspace(*chptr))
1098 error_msg("file name expected after %c", *(src-1));
1104 prog->redirects[i].filename = buf;
1105 while (*chptr && !isspace(*chptr))
1108 src = chptr - 1; /* we src++ later */
1109 prog->argv[argc_l] = ++buf;
1112 case '|': /* pipe */
1113 /* finish this command */
1114 if (*prog->argv[argc_l] || saw_quote)
1117 error_msg("empty command in pipe");
1122 prog->argv[argc_l] = NULL;
1124 /* and start the next */
1126 job->progs = xrealloc(job->progs,
1127 sizeof(*job->progs) * job->num_progs);
1128 prog = job->progs + (job->num_progs - 1);
1129 prog->num_redirects = 0;
1130 prog->redirects = NULL;
1131 prog->is_stopped = 0;
1136 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1137 prog->argv[0] = ++buf;
1140 while (*src && isspace(*src))
1144 error_msg("empty command in pipe");
1149 src--; /* we'll ++ it at the end of the loop */
1153 case '&': /* background */
1155 case ';': /* multiple commands */
1157 return_command = *command_ptr + (src - *command_ptr) + 1;
1163 error_msg("character expected after \\");
1167 if (*src == '*' || *src == '[' || *src == ']'
1168 || *src == '?') *buf++ = '\\';
1177 if (*prog->argv[argc_l] || saw_quote) {
1184 prog->argv[argc_l] = NULL;
1186 if (!return_command) {
1187 job->text = xmalloc(strlen(*command_ptr) + 1);
1188 strcpy(job->text, *command_ptr);
1190 /* This leaves any trailing spaces, which is a bit sloppy */
1191 count = return_command - *command_ptr;
1192 job->text = xmalloc(count + 1);
1193 strncpy(job->text, *command_ptr, count);
1194 job->text[count] = '\0';
1197 *command_ptr = return_command;
1202 /* Run the child_prog, no matter what kind of command it uses.
1204 static int pseudo_exec(struct child_prog *child)
1206 struct built_in_command *x;
1207 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
1211 /* Check if the command matches any of the non-forking builtins.
1212 * Depending on context, this might be redundant. But it's
1213 * easier to waste a few CPU cycles than it is to figure out
1214 * if this is one of those cases.
1216 for (x = bltins; x->cmd; x++) {
1217 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1218 exit(x->function(child));
1222 /* Check if the command matches any of the forking builtins. */
1223 for (x = bltins_forking; x->cmd; x++) {
1224 if (strcmp(child->argv[0], x->cmd) == 0) {
1226 exit (x->function(child));
1229 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
1230 /* Check if the command matches any busybox internal
1231 * commands ("applets") here. Following discussions from
1232 * November 2000 on busybox@opensource.lineo.com, don't use
1233 * get_last_path_component(). This way explicit (with
1234 * slashes) filenames will never be interpreted as an
1235 * applet, just like with builtins. This way the user can
1236 * override an applet with an explicit filename reference.
1237 * The only downside to this change is that an explicit
1238 * /bin/foo invocation will fork and exec /bin/foo, even if
1239 * /bin/foo is a symlink to busybox.
1241 name = child->argv[0];
1243 #ifdef BB_FEATURE_SH_APPLETS_ALWAYS_WIN
1244 /* If you enable BB_FEATURE_SH_APPLETS_ALWAYS_WIN, then
1245 * if you run /bin/cat, it will use BusyBox cat even if
1246 * /bin/cat exists on the filesystem and is _not_ busybox.
1247 * Some systems want this, others do not. Choose wisely. :-)
1249 name = get_last_path_component(name);
1253 char** argv_l=child->argv;
1255 for(argc_l=0;*argv_l!=NULL; argv_l++, argc_l++);
1257 run_applet_by_name(name, argc_l, child->argv);
1261 execvp(child->argv[0], child->argv);
1262 perror_msg_and_die("%s", child->argv[0]);
1265 static void insert_job(struct job *newjob, int inbg)
1268 struct jobset *j_list=newjob->job_list;
1270 /* find the ID for thejob to use */
1272 for (thejob = j_list->head; thejob; thejob = thejob->next)
1273 if (thejob->jobid >= newjob->jobid)
1274 newjob->jobid = thejob->jobid + 1;
1276 /* add thejob to the list of running jobs */
1277 if (!j_list->head) {
1278 thejob = j_list->head = xmalloc(sizeof(*thejob));
1280 for (thejob = j_list->head; thejob->next; thejob = thejob->next) /* nothing */;
1281 thejob->next = xmalloc(sizeof(*thejob));
1282 thejob = thejob->next;
1285 *thejob = *newjob; /* physically copy the struct job */
1286 thejob->next = NULL;
1287 thejob->running_progs = thejob->num_progs;
1288 thejob->stopped_progs = 0;
1291 /* we don't wait for background thejobs to return -- append it
1292 to the list of backgrounded thejobs and leave it alone */
1293 printf("[%d] %d\n", thejob->jobid,
1294 newjob->progs[newjob->num_progs - 1].pid);
1295 last_jobid = newjob->jobid;
1296 last_bg_pid=newjob->progs[newjob->num_progs - 1].pid;
1298 newjob->job_list->fg = thejob;
1300 /* move the new process group into the foreground */
1301 /* suppress messages when run from /linuxrc mag@sysgo.de */
1302 if (tcsetpgrp(shell_terminal, newjob->pgrp) && errno != ENOTTY)
1303 perror_msg("tcsetpgrp");
1307 static int run_command(struct job *newjob, int inbg, int outpipe[2])
1309 /* struct job *thejob; */
1311 int nextin, nextout;
1312 int pipefds[2]; /* pipefd[0] is for reading */
1313 struct built_in_command *x;
1314 struct child_prog *child;
1316 nextin = 0, nextout = 1;
1317 for (i = 0; i < newjob->num_progs; i++) {
1318 child = & (newjob->progs[i]);
1320 if ((i + 1) < newjob->num_progs) {
1321 if (pipe(pipefds)<0) perror_msg_and_die("pipe");
1322 nextout = pipefds[1];
1324 if (outpipe[1]!=-1) {
1325 nextout = outpipe[1];
1332 /* Check if the command matches any non-forking builtins,
1333 * but only if this is a simple command.
1334 * Non-forking builtins within pipes have to fork anyway,
1335 * and are handled in pseudo_exec. "echo foo | read bar"
1336 * is doomed to failure, and doesn't work on bash, either.
1338 if (newjob->num_progs == 1) {
1339 for (x = bltins; x->cmd; x++) {
1340 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1341 int squirrel[] = {-1, -1, -1};
1343 setup_redirects(child, squirrel);
1344 rcode = x->function(child);
1345 restore_redirects(squirrel);
1351 if (!(child->pid = fork())) {
1352 /* Set the handling for job control signals back to the default. */
1353 signal(SIGINT, SIG_DFL);
1354 signal(SIGQUIT, SIG_DFL);
1355 signal(SIGTSTP, SIG_DFL);
1356 signal(SIGTTIN, SIG_DFL);
1357 signal(SIGTTOU, SIG_DFL);
1358 signal(SIGCHLD, SIG_DFL);
1362 if (outpipe[1]!=-1) {
1372 dup2(nextout, 2); /* Really? */
1377 /* explicit redirects override pipes */
1378 setup_redirects(child,NULL);
1382 if (outpipe[1]!=-1) {
1386 /* put our child in the process group whose leader is the
1387 first process in this pipe */
1388 setpgid(child->pid, newjob->progs[0].pid);
1394 /* If there isn't another process, nextin is garbage
1395 but it doesn't matter */
1396 nextin = pipefds[0];
1399 newjob->pgrp = newjob->progs[0].pid;
1401 insert_job(newjob, inbg);
1406 static int busy_loop(FILE * input)
1409 char *next_command = NULL;
1415 newjob.job_list = &job_list;
1416 newjob.job_context = DEFAULT_CONTEXT;
1418 /* save current owner of TTY so we can restore it on exit */
1419 parent_pgrp = tcgetpgrp(shell_terminal);
1421 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1425 /* no job is in the foreground */
1427 /* see if any background processes have exited */
1428 checkjobs(&job_list);
1430 if (!next_command) {
1431 if (get_command(input, command))
1433 next_command = command;
1436 if (expand_arguments(next_command) == FALSE) {
1438 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1439 next_command = NULL;
1443 if (!parse_command(&next_command, &newjob, &inbg) &&
1445 int pipefds[2] = {-1,-1};
1446 debug_printf( "job=%p fed to run_command by busy_loop()'\n",
1448 run_command(&newjob, inbg, pipefds);
1452 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1453 next_command = NULL;
1456 /* a job is running in the foreground; wait for it */
1458 while (!job_list.fg->progs[i].pid ||
1459 job_list.fg->progs[i].is_stopped == 1) i++;
1461 if (waitpid(job_list.fg->progs[i].pid, &status, WUNTRACED)<0)
1462 perror_msg_and_die("waitpid(%d)",job_list.fg->progs[i].pid);
1464 if (WIFEXITED(status) || WIFSIGNALED(status)) {
1465 /* the child exited */
1466 job_list.fg->running_progs--;
1467 job_list.fg->progs[i].pid = 0;
1469 last_return_code=WEXITSTATUS(status);
1471 if (!job_list.fg->running_progs) {
1473 remove_job(&job_list, job_list.fg);
1477 /* the child was stopped */
1478 job_list.fg->stopped_progs++;
1479 job_list.fg->progs[i].is_stopped = 1;
1481 if (job_list.fg->stopped_progs == job_list.fg->running_progs) {
1482 printf("\n" JOB_STATUS_FORMAT, job_list.fg->jobid,
1483 "Stopped", job_list.fg->text);
1489 /* move the shell to the foreground */
1490 /* suppress messages when run from /linuxrc mag@sysgo.de */
1491 if (tcsetpgrp(shell_terminal, getpgrp()) && errno != ENOTTY)
1492 perror_msg("tcsetpgrp");
1498 /* return controlling TTY back to parent process group before exiting */
1499 if (tcsetpgrp(shell_terminal, parent_pgrp))
1500 perror_msg("tcsetpgrp");
1502 /* return exit status if called with "-c" */
1503 if (input == NULL && WIFEXITED(status))
1504 return WEXITSTATUS(status);
1510 #ifdef BB_FEATURE_CLEAN_UP
1511 void free_memory(void)
1516 if (local_pending_command)
1517 free(local_pending_command);
1519 if (job_list.fg && !job_list.fg->running_progs) {
1520 remove_job(&job_list, job_list.fg);
1525 /* Make sure we have a controlling tty. If we get started under a job
1526 * aware app (like bash for example), make sure we are now in charge so
1527 * we don't fight over who gets the foreground */
1528 static void setup_job_control()
1530 /* Loop until we are in the foreground. */
1531 while (tcgetpgrp (shell_terminal) != (shell_pgrp = getpgrp ()))
1532 kill (- shell_pgrp, SIGTTIN);
1534 /* Ignore interactive and job-control signals. */
1535 signal(SIGINT, SIG_IGN);
1536 signal(SIGQUIT, SIG_IGN);
1537 signal(SIGTSTP, SIG_IGN);
1538 signal(SIGTTIN, SIG_IGN);
1539 signal(SIGTTOU, SIG_IGN);
1540 signal(SIGCHLD, SIG_IGN);
1542 /* Put ourselves in our own process group. */
1544 shell_pgrp = getpid ();
1545 setpgid (shell_pgrp, shell_pgrp);
1547 /* Grab control of the terminal. */
1548 tcsetpgrp(shell_terminal, shell_pgrp);
1551 int shell_main(int argc_l, char **argv_l)
1553 int opt, interactive=FALSE;
1554 FILE *input = stdin;
1558 /* These variables need re-initializing when recursing */
1561 local_pending_command = NULL;
1562 close_me_head = NULL;
1563 job_list.head = NULL;
1567 if (argv[0] && argv[0][0] == '-') {
1569 prof_input = fopen("/etc/profile", "r");
1571 int tmp_fd = fileno(prof_input);
1573 /* Now run the file */
1574 busy_loop(prof_input);
1576 mark_closed(tmp_fd);
1580 while ((opt = getopt(argc_l, argv_l, "cxi")) > 0) {
1584 if (local_pending_command != 0)
1585 error_msg_and_die("multiple -c arguments");
1586 local_pending_command = xstrdup(argv[optind]);
1597 /* A shell is interactive if the `-i' flag was given, or if all of
1598 * the following conditions are met:
1600 * no arguments remaining or the -s flag given
1601 * standard input is a terminal
1602 * standard output is a terminal
1603 * Refer to Posix.2, the description of the `sh' utility. */
1604 if (argv[optind]==NULL && input==stdin &&
1605 isatty(fileno(stdin)) && isatty(fileno(stdout))) {
1608 setup_job_control();
1609 if (interactive==TRUE) {
1610 //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
1611 /* Looks like they want an interactive shell */
1612 printf( "\n\n" BB_BANNER " Built-in shell (lash)\n");
1613 printf( "Enter 'help' for a list of built-in commands.\n\n");
1614 } else if (local_pending_command==NULL) {
1615 //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
1616 input = xfopen(argv[optind], "r");
1617 mark_open(fileno(input)); /* be lazy, never mark this closed */
1620 /* initialize the cwd -- this is never freed...*/
1625 #ifdef BB_FEATURE_CLEAN_UP
1626 atexit(free_memory);
1629 #ifdef BB_FEATURE_COMMAND_EDITING
1630 cmdedit_set_initial_prompt();
1635 return (busy_loop(input));