1 /* vi: set sw=4 ts=4: */
3 * lash -- the BusyBox Lame-Ass SHell
5 * Copyright (C) 1999-2004 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 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
14 /* This shell's parsing engine is officially at a dead-end. Future
15 * work shell work should be done using hush, msh, or ash. This is
16 * still a very useful, small shell -- it just don't need any more
17 * features beyond what it already has...
20 //For debugging/development on the shell only...
27 #define expand_t glob_t
29 /* Always enable for the moment... */
30 #define CONFIG_LASH_PIPE_N_REDIRECTS
31 #define CONFIG_LASH_JOB_CONTROL
32 #define ENABLE_LASH_PIPE_N_REDIRECTS 1
33 #define ENABLE_LASH_JOB_CONTROL 1
35 enum { MAX_READ = 128 }; /* size of input buffer for 'read' builtin */
36 #define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
39 #if ENABLE_LASH_PIPE_N_REDIRECTS
40 enum redir_type { REDIRECT_INPUT, REDIRECT_OVERWRITE,
46 DEFAULT_CONTEXT = 0x1,
47 IF_TRUE_CONTEXT = 0x2,
48 IF_FALSE_CONTEXT = 0x4,
49 THEN_EXP_CONTEXT = 0x8,
50 ELSE_EXP_CONTEXT = 0x10
53 #define LASH_OPT_DONE (1)
54 #define LASH_OPT_SAW_QUOTE (2)
56 #if ENABLE_LASH_PIPE_N_REDIRECTS
58 enum redir_type type; /* type of redirection */
59 int fd; /* file descriptor being redirected */
60 char *filename; /* file to redirect fd to */
65 pid_t pid; /* 0 if exited */
66 char **argv; /* program name and arguments */
67 int num_redirects; /* elements in redirection array */
68 int is_stopped; /* is the program currently running? */
69 struct job *family; /* pointer back to the child's parent job */
70 #if ENABLE_LASH_PIPE_N_REDIRECTS
71 struct redir_struct *redirects; /* I/O redirects */
76 struct job *head; /* head of list of running jobs */
77 struct job *fg; /* current foreground job */
81 int jobid; /* job number */
82 int num_progs; /* total number of programs in job */
83 int running_progs; /* number of programs running */
84 char *text; /* name of job */
85 char *cmdbuf; /* buffer various argv's point into */
86 pid_t pgrp; /* process group ID for the job */
87 struct child_prog *progs; /* array of programs in job */
88 struct job *next; /* to track background commands */
89 int stopped_progs; /* number of programs alive, but stopped */
90 unsigned int job_context; /* bitmask defining current context */
91 struct jobset *job_list;
94 struct built_in_command {
95 const char *cmd; /* name */
96 const char *descr; /* description */
97 int (*function) (struct child_prog *); /* function ptr */
100 /* function prototypes for builtins */
101 static int builtin_cd(struct child_prog *cmd);
102 static int builtin_exec(struct child_prog *cmd);
103 static int builtin_exit(struct child_prog *cmd);
104 static int builtin_fg_bg(struct child_prog *cmd);
105 static int builtin_help(struct child_prog *cmd);
106 static int builtin_jobs(struct child_prog *dummy);
107 static int builtin_pwd(struct child_prog *dummy);
108 static int builtin_export(struct child_prog *cmd);
109 static int builtin_source(struct child_prog *cmd);
110 static int builtin_unset(struct child_prog *cmd);
111 static int builtin_read(struct child_prog *cmd);
114 /* function prototypes for shell stuff */
115 static void checkjobs(struct jobset *job_list);
116 static void remove_job(struct jobset *j_list, struct job *job);
117 static int get_command_bufsiz(FILE * source, char *command);
118 static int parse_command(char **command_ptr, struct job *job, int *inbg);
119 static int run_command(struct job *newjob, int inbg, int outpipe[2]);
120 static int pseudo_exec(struct child_prog *cmd) ATTRIBUTE_NORETURN;
121 static int busy_loop(FILE * input);
124 /* Table of built-in functions (these are non-forking builtins, meaning they
125 * can change global variables in the parent shell process but they will not
126 * work with pipes and redirects; 'unset foo | whatever' will not work) */
127 static const struct built_in_command bltins[] = {
128 {"bg", "Resume a job in the background", builtin_fg_bg},
129 {"cd", "Change working directory", builtin_cd},
130 {"exec", "Exec command, replacing this shell with the exec'd process", builtin_exec},
131 {"exit", "Exit from shell()", builtin_exit},
132 {"fg", "Bring job into the foreground", builtin_fg_bg},
133 {"jobs", "Lists the active jobs", builtin_jobs},
134 {"export", "Set environment variable", builtin_export},
135 {"unset", "Unset environment variable", builtin_unset},
136 {"read", "Input environment variable", builtin_read},
137 {".", "Source-in and run commands in a file", builtin_source},
138 /* to do: add ulimit */
142 /* Table of forking built-in functions (things that fork cannot change global
143 * variables in the parent process, such as the current working directory) */
144 static struct built_in_command bltins_forking[] = {
145 {"pwd", "Print current directory", builtin_pwd},
146 {"help", "List shell built-in commands", builtin_help},
151 static int shell_context; /* Type prompt trigger (PS1 or PS2) */
154 /* Globals that are static to this file */
155 static const char *cwd;
156 static char *local_pending_command;
157 static struct jobset job_list = { NULL, NULL };
160 static llist_t *close_me_list;
161 static int last_return_code;
162 static int last_bg_pid;
163 static unsigned int last_jobid;
164 static int shell_terminal;
165 static const char *PS1;
166 static const char *PS2 = "> ";
170 static inline void debug_printf(const char *format, ...)
173 va_start(args, format);
174 vfprintf(stderr, format, args);
178 static inline void debug_printf(const char ATTRIBUTE_UNUSED *format, ...) { }
182 Most builtins need access to the struct child_prog that has
183 their arguments, previously coded as cmd->progs[0]. That coding
184 can exhibit a bug, if the builtin is not the first command in
185 a pipeline: "echo foo | exec sort" will attempt to exec foo.
187 builtin previous use notes
188 ------ ----------------- ---------
190 exec cmd->progs[0] squashed bug: didn't look for applets or forking builtins
192 fg_bg cmd->progs[0], job_list->head, job_list->fg
201 I added "struct job *family;" to struct child_prog,
202 and switched API to builtin_foo(struct child_prog *child);
203 So cmd->text becomes child->family->text
204 cmd->job_context becomes child->family->job_context
205 cmd->progs[0] becomes *child
206 job_list becomes child->family->job_list
209 /* built-in 'cd <path>' handler */
210 static int builtin_cd(struct child_prog *child)
214 if (child->argv[1] == NULL)
215 newdir = getenv("HOME");
217 newdir = child->argv[1];
219 bb_perror_msg("cd: %s", newdir);
222 cwd = xrealloc_getcwd_or_warn((char *)cwd);
224 cwd = bb_msg_unknown;
228 /* built-in 'exec' handler */
229 static int builtin_exec(struct child_prog *child)
231 if (child->argv[1] == NULL)
232 return EXIT_SUCCESS; /* Really? */
234 while (close_me_list)
235 close((long)llist_pop(&close_me_list));
240 /* built-in 'exit' handler */
241 static int builtin_exit(struct child_prog *child)
243 if (child->argv[1] == NULL)
246 exit (atoi(child->argv[1]));
249 /* built-in 'fg' and 'bg' handler */
250 static int builtin_fg_bg(struct child_prog *child)
253 struct job *job = NULL;
255 /* If they gave us no args, assume they want the last backgrounded task */
256 if (!child->argv[1]) {
257 for (job = child->family->job_list->head; job; job = job->next) {
258 if (job->jobid == last_jobid) {
263 bb_error_msg("%s: no current job", child->argv[0]);
267 if (sscanf(child->argv[1], "%%%d", &jobnum) != 1) {
268 bb_error_msg(bb_msg_invalid_arg, child->argv[1], child->argv[0]);
271 for (job = child->family->job_list->head; job; job = job->next) {
272 if (job->jobid == jobnum) {
277 bb_error_msg("%s: %d: no such job", child->argv[0], jobnum);
282 if (*child->argv[0] == 'f') {
283 /* Put the job into the foreground. */
284 tcsetpgrp(shell_terminal, job->pgrp);
286 child->family->job_list->fg = job;
289 /* Restart the processes in the job */
290 for (i = 0; i < job->num_progs; i++)
291 job->progs[i].is_stopped = 0;
293 job->stopped_progs = 0;
295 i = kill(- job->pgrp, SIGCONT);
298 remove_job(&job_list, job);
300 bb_perror_msg("kill (SIGCONT)");
307 /* built-in 'help' handler */
308 static int builtin_help(struct child_prog ATTRIBUTE_UNUSED *dummy)
310 const struct built_in_command *x;
312 printf("\nBuilt-in commands:\n"
313 "-------------------\n");
314 for (x = bltins; x->cmd; x++) {
315 if (x->descr == NULL)
317 printf("%s\t%s\n", x->cmd, x->descr);
319 for (x = bltins_forking; x->cmd; x++) {
320 if (x->descr == NULL)
322 printf("%s\t%s\n", x->cmd, x->descr);
328 /* built-in 'jobs' handler */
329 static int builtin_jobs(struct child_prog *child)
332 const char *status_string;
334 for (job = child->family->job_list->head; job; job = job->next) {
335 if (job->running_progs == job->stopped_progs)
336 status_string = "Stopped";
338 status_string = "Running";
340 printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->text);
346 /* built-in 'pwd' handler */
347 static int builtin_pwd(struct child_prog ATTRIBUTE_UNUSED *dummy)
349 cwd = xrealloc_getcwd_or_warn((char *)cwd);
351 cwd = bb_msg_unknown;
356 /* built-in 'export VAR=value' handler */
357 static int builtin_export(struct child_prog *child)
360 char *v = child->argv[1];
364 for (e = environ; *e; e++) {
371 bb_perror_msg("export");
372 #if ENABLE_FEATURE_EDITING_FANCY_PROMPT
373 if (strncmp(v, "PS1=", 4) == 0)
377 #if ENABLE_LOCALE_SUPPORT
378 // TODO: why getenv? "" would be just as good...
379 if (strncmp(v, "LC_ALL=", 7) == 0)
380 setlocale(LC_ALL, getenv("LC_ALL"));
381 if (strncmp(v, "LC_CTYPE=", 9) == 0)
382 setlocale(LC_CTYPE, getenv("LC_CTYPE"));
388 /* built-in 'read VAR' handler */
389 static int builtin_read(struct child_prog *child)
393 char string[MAX_READ];
395 if (child->argv[1]) {
396 /* argument (VAR) given: put "VAR=" into buffer */
397 safe_strncpy(string, child->argv[1], MAX_READ-1);
398 len = strlen(string);
401 fgets(&string[len], sizeof(string) - len, stdin); /* read string */
402 res = strlen(string);
404 string[--res] = '\0'; /* chomp trailing newline */
406 ** string should now contain "VAR=<value>"
407 ** copy it (putenv() won't do that, so we must make sure
408 ** the string resides in a static buffer!)
411 if ((s = strdup(string)))
414 bb_perror_msg("read");
417 fgets(string, sizeof(string), stdin);
422 /* Built-in '.' handler (read-in and execute commands from file) */
423 static int builtin_source(struct child_prog *child)
428 input = fopen_or_warn(child->argv[1], "r");
433 llist_add_to(&close_me_list, (void *)(long)fileno(input));
434 /* Now run the file */
435 status = busy_loop(input);
437 llist_pop(&close_me_list);
441 /* built-in 'unset VAR' handler */
442 static int builtin_unset(struct child_prog *child)
444 if (child->argv[1] == NULL) {
445 printf(bb_msg_requires_arg, "unset");
448 unsetenv(child->argv[1]);
452 #if ENABLE_LASH_JOB_CONTROL
453 /* free up all memory from a job */
454 static void free_job(struct job *cmd)
459 for (i = 0; i < cmd->num_progs; i++) {
460 free(cmd->progs[i].argv);
461 #if ENABLE_LASH_PIPE_N_REDIRECTS
462 if (cmd->progs[i].redirects)
463 free(cmd->progs[i].redirects);
469 keep = cmd->job_list;
470 memset(cmd, 0, sizeof(struct job));
471 cmd->job_list = keep;
474 /* remove a job from a jobset */
475 static void remove_job(struct jobset *j_list, struct job *job)
480 if (job == j_list->head) {
481 j_list->head = job->next;
483 prevjob = j_list->head;
484 while (prevjob->next != job)
485 prevjob = prevjob->next;
486 prevjob->next = job->next;
490 last_jobid = j_list->head->jobid;
497 /* Checks to see if any background processes have exited -- if they
498 have, figure out why and see if a job has completed */
499 static void checkjobs(struct jobset *j_list)
506 while ((childpid = waitpid(-1, &status, WNOHANG | WUNTRACED)) > 0) {
507 for (job = j_list->head; job; job = job->next) {
509 while (prognum < job->num_progs &&
510 job->progs[prognum].pid != childpid) prognum++;
511 if (prognum < job->num_progs)
515 /* This happens on backticked commands */
519 if (WIFEXITED(status) || WIFSIGNALED(status)) {
521 job->running_progs--;
522 job->progs[prognum].pid = 0;
524 if (!job->running_progs) {
525 printf(JOB_STATUS_FORMAT, job->jobid, "Done", job->text);
527 remove_job(j_list, job);
531 job->stopped_progs++;
532 job->progs[prognum].is_stopped = 1;
536 if (childpid == -1 && errno != ECHILD)
537 bb_perror_msg("waitpid");
540 static void checkjobs(struct jobset *j_list)
543 static void free_job(struct job *cmd)
546 static void remove_job(struct jobset *j_list, struct job *job)
551 #if ENABLE_LASH_PIPE_N_REDIRECTS
552 /* squirrel != NULL means we squirrel away copies of stdin, stdout,
553 * and stderr if they are redirected. */
554 static int setup_redirects(struct child_prog *prog, int squirrel[])
559 struct redir_struct *redir = prog->redirects;
561 for (i = 0; i < prog->num_redirects; i++, redir++) {
562 switch (redir->type) {
566 case REDIRECT_OVERWRITE:
567 mode = O_WRONLY | O_CREAT | O_TRUNC;
569 case REDIRECT_APPEND:
570 mode = O_WRONLY | O_CREAT | O_APPEND;
574 openfd = open(redir->filename, mode, 0666);
576 /* this could get lost if stderr has been redirected, but
577 bash and ash both lose it as well (though zsh doesn't!) */
578 bb_perror_msg("error opening %s", redir->filename);
582 if (openfd != redir->fd) {
583 if (squirrel && redir->fd < 3) {
584 squirrel[redir->fd] = dup(redir->fd);
585 fcntl (squirrel[redir->fd], F_SETFD, FD_CLOEXEC);
587 dup2(openfd, redir->fd);
595 static void restore_redirects(int squirrel[])
598 for (i = 0; i < 3; i++) {
601 /* No error checking. I sure wouldn't know what
602 * to do with an error if I found one! */
609 static inline int setup_redirects(struct child_prog *prog, int squirrel[])
613 static inline void restore_redirects(int squirrel[])
618 static inline void cmdedit_set_initial_prompt(void)
620 #if !ENABLE_FEATURE_EDITING_FANCY_PROMPT
629 static inline const char* setup_prompt_string(void)
631 #if !ENABLE_FEATURE_EDITING_FANCY_PROMPT
632 /* Set up the prompt */
633 if (shell_context == 0) {
636 ns = xmalloc(strlen(cwd)+4);
637 sprintf(ns, "%s %c ", cwd, (geteuid() != 0) ? '$': '#');
644 return (shell_context == 0)? PS1 : PS2;
648 #if ENABLE_FEATURE_EDITING
649 static line_input_t *line_input_state;
652 static int get_command_bufsiz(FILE * source, char *command)
654 const char *prompt_str;
656 if (source == NULL) {
657 if (local_pending_command) {
658 /* a command specified (-c option): return it & mark it done */
659 strncpy(command, local_pending_command, BUFSIZ);
660 local_pending_command = NULL;
666 if (source == stdin) {
667 prompt_str = setup_prompt_string();
669 #if ENABLE_FEATURE_EDITING
671 ** enable command line editing only while a command line
672 ** is actually being read; otherwise, we'll end up bequeathing
673 ** atexit() handlers and other unwanted stuff to our
674 ** child processes (rob@sysgo.de)
676 read_line_input(prompt_str, command, BUFSIZ, line_input_state);
679 fputs(prompt_str, stdout);
683 if (!fgets(command, BUFSIZ - 2, source)) {
692 static char * strsep_space(char *string, int * ix)
694 /* Short circuit the trivial case */
695 if (!string || ! string[*ix])
698 /* Find the end of the token. */
699 while (string[*ix] && !isspace(string[*ix]) ) {
703 /* Find the end of any whitespace trailing behind
704 * the token and let that be part of the token */
705 while (string[*ix] && (isspace)(string[*ix]) ) {
710 /* Nothing useful was found */
714 return xstrndup(string, *ix);
717 static int expand_arguments(char *command)
719 int total_length = 0, length, i, retval, ix = 0;
720 expand_t expand_result;
721 char *tmpcmd, *cmd, *cmd_copy;
722 char *src, *dst, *var;
723 const char * const out_of_space = "out of space during expansion";
724 int flags = GLOB_NOCHECK
733 /* get rid of the terminating \n */
736 /* Fix up escape sequences to be the Real Thing(tm) */
737 while (command && command[ix]) {
738 if (command[ix] == '\\') {
739 const char *tmp = command+ix+1;
740 command[ix] = bb_process_escape_sequence( &tmp );
741 memmove(command+ix + 1, tmp, strlen(tmp)+1);
745 /* Use glob and then fixup environment variables and such */
747 /* It turns out that glob is very stupid. We have to feed it one word at a
748 * time since it can't cope with a full string. Here we convert command
749 * (char*) into cmd (char**, one word per string) */
751 /* We need a clean copy, so strsep can mess up the copy while
752 * we write stuff into the original (in a minute) */
753 cmd = cmd_copy = xstrdup(command);
755 for (ix = 0, tmpcmd = cmd;
756 (tmpcmd = strsep_space(cmd, &ix)) != NULL; cmd += ix, ix = 0) {
759 /* we need to trim() the result for glob! */
761 retval = glob(tmpcmd, flags, NULL, &expand_result);
762 free(tmpcmd); /* Free mem allocated by strsep_space */
763 if (retval == GLOB_NOSPACE) {
764 /* Mem may have been allocated... */
765 globfree (&expand_result);
766 bb_error_msg(out_of_space);
768 } else if (retval != 0) {
769 /* Some other error. GLOB_NOMATCH shouldn't
770 * happen because of the GLOB_NOCHECK flag in
772 bb_error_msg("syntax error");
775 /* Convert from char** (one word per string) to a simple char*,
776 * but don't overflow command which is BUFSIZ in length */
777 for (i = 0; i < expand_result.gl_pathc; i++) {
778 length = strlen(expand_result.gl_pathv[i]);
779 if (total_length+length+1 >= BUFSIZ) {
780 bb_error_msg(out_of_space);
783 strcat(command+total_length, " ");
785 strcat(command+total_length, expand_result.gl_pathv[i]);
786 total_length += length;
788 globfree (&expand_result);
794 /* Now do the shell variable substitutions which
795 * wordexp can't do for us, namely $? and $! */
797 while ((dst = strchr(src,'$')) != NULL) {
801 var = itoa(last_return_code);
804 if (last_bg_pid == -1)
807 var = itoa(last_bg_pid);
809 /* Everything else like $$, $#, $[0-9], etc. should all be
810 * expanded by wordexp(), so we can in theory skip that stuff
811 * here, but just to be on the safe side (i.e., since uClibc
812 * wordexp doesn't do this stuff yet), lets leave it in for
815 var = itoa(getpid());
820 case '0':case '1':case '2':case '3':case '4':
821 case '5':case '6':case '7':case '8':case '9':
823 int ixx = *(dst+1)-48+1;
834 /* a single character construction was found, and
835 * already handled in the case statement */
838 /* Looks like an environment variable */
840 int num_skip_chars = 0;
841 int dstlen = strlen(dst);
842 /* Is this a ${foo} type variable? */
843 if (dstlen >= 2 && *(dst+1) == '{') {
844 src = strchr(dst+1, '}');
848 while ((isalnum)(*src) || *src == '_') src++;
854 *src = '\0'; /* temporary */
855 var = getenv(dst + 1 + num_skip_chars);
857 src += num_skip_chars;
860 /* Seems we got an un-expandable variable. So delete it. */
864 int subst_len = strlen(var);
865 int trail_len = strlen(src);
866 if (dst+subst_len+trail_len >= command+BUFSIZ) {
867 bb_error_msg(out_of_space);
870 /* Move stuff to the end of the string to accommodate
871 * filling the created gap with the new stuff */
872 memmove(dst+subst_len, src, trail_len+1);
873 /* Now copy in the new stuff */
874 memcpy(dst, var, subst_len);
882 /* Return cmd->num_progs as 0 if no command is present (e.g. an empty
883 line). If a valid command is found, command_ptr is set to point to
884 the beginning of the next command (if the original command had more
885 then one job associated with it) or NULL if no more commands are
887 static int parse_command(char **command_ptr, struct job *job, int *inbg)
890 char *return_command = NULL;
896 struct child_prog *prog;
897 #if ENABLE_LASH_PIPE_N_REDIRECTS
902 /* skip leading white space */
903 *command_ptr = skip_whitespace(*command_ptr);
905 /* this handles empty lines or leading '#' characters */
906 if (!**command_ptr || (**command_ptr == '#')) {
913 job->progs = xmalloc(sizeof(*job->progs));
915 /* We set the argv elements to point inside of this string. The
916 memory is freed by free_job(). Allocate twice the original
917 length in case we need to quote every single character.
919 Getting clean memory relieves us of the task of NULL
920 terminating things and makes the rest of this look a bit
921 cleaner (though it is, admittedly, a tad less efficient) */
922 job->cmdbuf = command = xzalloc(2*strlen(*command_ptr) + 1);
926 prog->num_redirects = 0;
927 prog->is_stopped = 0;
929 #if ENABLE_LASH_PIPE_N_REDIRECTS
930 prog->redirects = NULL;
934 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
935 prog->argv[0] = job->cmdbuf;
940 while (*src && !(flag & LASH_OPT_DONE)) {
947 bb_error_msg("character expected after \\");
952 /* in shell, "\'" should yield \' */
957 } else if (*src == '*' || *src == '?' || *src == '[' ||
958 *src == ']') *buf++ = '\\';
960 } else if (isspace(*src)) {
961 if (*prog->argv[argc_l] || flag & LASH_OPT_SAW_QUOTE) {
963 /* +1 here leaves room for the NULL which ends argv */
964 if ((argc_l + 1) == argv_alloced) {
966 prog->argv = xrealloc(prog->argv,
967 sizeof(*prog->argv) * argv_alloced);
969 prog->argv[argc_l] = buf;
970 flag ^= LASH_OPT_SAW_QUOTE;
977 flag |= LASH_OPT_SAW_QUOTE;
980 case '#': /* comment */
984 flag |= LASH_OPT_DONE;
987 #if ENABLE_LASH_PIPE_N_REDIRECTS
988 case '>': /* redirects */
990 i = prog->num_redirects++;
991 prog->redirects = xrealloc(prog->redirects,
992 sizeof(*prog->redirects) * (i + 1));
994 prog->redirects[i].fd = -1;
995 if (buf != prog->argv[argc_l]) {
996 /* the stuff before this character may be the file number
998 prog->redirects[i].fd =
999 strtol(prog->argv[argc_l], &chptr, 10);
1001 if (*chptr && *prog->argv[argc_l]) {
1003 prog->argv[argc_l] = buf;
1007 if (prog->redirects[i].fd == -1) {
1009 prog->redirects[i].fd = 1;
1011 prog->redirects[i].fd = 0;
1014 if (*src++ == '>') {
1016 prog->redirects[i].type =
1017 REDIRECT_APPEND, src++;
1019 prog->redirects[i].type = REDIRECT_OVERWRITE;
1021 prog->redirects[i].type = REDIRECT_INPUT;
1024 /* This isn't POSIX sh compliant. Oh well. */
1026 chptr = skip_whitespace(chptr);
1029 bb_error_msg("file name expected after %c", *(src-1));
1035 prog->redirects[i].filename = buf;
1036 while (*chptr && !isspace(*chptr))
1039 src = chptr - 1; /* we src++ later */
1040 prog->argv[argc_l] = ++buf;
1043 case '|': /* pipe */
1044 /* finish this command */
1045 if (*prog->argv[argc_l] || flag & LASH_OPT_SAW_QUOTE)
1048 goto empty_command_in_pipe;
1050 prog->argv[argc_l] = NULL;
1052 /* and start the next */
1054 job->progs = xrealloc(job->progs,
1055 sizeof(*job->progs) * job->num_progs);
1056 prog = job->progs + (job->num_progs - 1);
1057 prog->num_redirects = 0;
1058 prog->redirects = NULL;
1059 prog->is_stopped = 0;
1064 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1065 prog->argv[0] = ++buf;
1068 src = skip_whitespace(src);
1071 empty_command_in_pipe:
1072 bb_error_msg("empty command in pipe");
1077 src--; /* we'll ++ it at the end of the loop */
1082 #if ENABLE_LASH_JOB_CONTROL
1083 case '&': /* background */
1087 case ';': /* multiple commands */
1088 flag |= LASH_OPT_DONE;
1089 return_command = *command_ptr + (src - *command_ptr) + 1;
1095 bb_error_msg("character expected after \\");
1099 if (*src == '*' || *src == '[' || *src == ']'
1100 || *src == '?') *buf++ = '\\';
1109 if (*prog->argv[argc_l] || flag & LASH_OPT_SAW_QUOTE) {
1116 prog->argv[argc_l] = NULL;
1118 if (!return_command) {
1119 job->text = xstrdup(*command_ptr);
1121 /* This leaves any trailing spaces, which is a bit sloppy */
1122 job->text = xstrndup(*command_ptr, return_command - *command_ptr);
1125 *command_ptr = return_command;
1130 /* Run the child_prog, no matter what kind of command it uses.
1132 static int pseudo_exec(struct child_prog *child)
1134 const struct built_in_command *x;
1136 /* Check if the command matches any of the non-forking builtins.
1137 * Depending on context, this might be redundant. But it's
1138 * easier to waste a few CPU cycles than it is to figure out
1139 * if this is one of those cases.
1141 for (x = bltins; x->cmd; x++) {
1142 if (strcmp(child->argv[0], x->cmd) == 0) {
1143 _exit(x->function(child));
1147 /* Check if the command matches any of the forking builtins. */
1148 for (x = bltins_forking; x->cmd; x++) {
1149 if (strcmp(child->argv[0], x->cmd) == 0) {
1150 applet_name = x->cmd;
1151 _exit(x->function(child));
1155 /* Check if the command matches any busybox internal
1156 * commands ("applets") here. Following discussions from
1157 * November 2000 on busybox@busybox.net, don't use
1158 * bb_get_last_path_component(). This way explicit (with
1159 * slashes) filenames will never be interpreted as an
1160 * applet, just like with builtins. This way the user can
1161 * override an applet with an explicit filename reference.
1162 * The only downside to this change is that an explicit
1163 * /bin/foo invocation will fork and exec /bin/foo, even if
1164 * /bin/foo is a symlink to busybox.
1166 if (ENABLE_FEATURE_SH_STANDALONE_SHELL) {
1167 char **argv_l = child->argv;
1170 for (argc_l = 0; *argv_l; argv_l++, argc_l++);
1172 run_applet_by_name(child->argv[0], argc_l, child->argv);
1175 execvp(child->argv[0], child->argv);
1177 /* Do not use bb_perror_msg_and_die() here, since we must not
1178 * call exit() but should call _exit() instead */
1179 bb_perror_msg("%s", child->argv[0]);
1180 _exit(EXIT_FAILURE);
1183 static void insert_job(struct job *newjob, int inbg)
1186 struct jobset *j_list = newjob->job_list;
1188 /* find the ID for thejob to use */
1190 for (thejob = j_list->head; thejob; thejob = thejob->next)
1191 if (thejob->jobid >= newjob->jobid)
1192 newjob->jobid = thejob->jobid + 1;
1194 /* add thejob to the list of running jobs */
1195 if (!j_list->head) {
1196 thejob = j_list->head = xmalloc(sizeof(*thejob));
1198 for (thejob = j_list->head; thejob->next; thejob = thejob->next) /* nothing */;
1199 thejob->next = xmalloc(sizeof(*thejob));
1200 thejob = thejob->next;
1203 *thejob = *newjob; /* physically copy the struct job */
1204 thejob->next = NULL;
1205 thejob->running_progs = thejob->num_progs;
1206 thejob->stopped_progs = 0;
1208 #if ENABLE_LASH_JOB_CONTROL
1210 /* we don't wait for background thejobs to return -- append it
1211 to the list of backgrounded thejobs and leave it alone */
1212 printf("[%d] %d\n", thejob->jobid,
1213 newjob->progs[newjob->num_progs - 1].pid);
1214 last_jobid = newjob->jobid;
1215 last_bg_pid = newjob->progs[newjob->num_progs - 1].pid;
1217 newjob->job_list->fg = thejob;
1219 /* move the new process group into the foreground */
1220 /* Ignore errors since child could have already exited */
1221 tcsetpgrp(shell_terminal, newjob->pgrp);
1226 static int run_command(struct job *newjob, int inbg, int outpipe[2])
1228 /* struct job *thejob; */
1230 int nextin, nextout;
1231 int pipefds[2]; /* pipefd[0] is for reading */
1232 const struct built_in_command *x;
1233 struct child_prog *child;
1235 nextin = 0, nextout = 1;
1236 for (i = 0; i < newjob->num_progs; i++) {
1237 child = & (newjob->progs[i]);
1239 if ((i + 1) < newjob->num_progs) {
1240 if (pipe(pipefds) < 0)
1241 bb_perror_msg_and_die("pipe");
1242 nextout = pipefds[1];
1244 if (outpipe[1] != -1) {
1245 nextout = outpipe[1];
1252 /* Check if the command matches any non-forking builtins,
1253 * but only if this is a simple command.
1254 * Non-forking builtins within pipes have to fork anyway,
1255 * and are handled in pseudo_exec. "echo foo | read bar"
1256 * is doomed to failure, and doesn't work on bash, either.
1258 if (newjob->num_progs == 1) {
1259 /* Check if the command sets an environment variable. */
1260 if (strchr(child->argv[0], '=') != NULL) {
1261 child->argv[1] = child->argv[0];
1262 return builtin_export(child);
1265 for (x = bltins; x->cmd; x++) {
1266 if (strcmp(child->argv[0], x->cmd) == 0) {
1268 int squirrel[] = {-1, -1, -1};
1269 setup_redirects(child, squirrel);
1270 rcode = x->function(child);
1271 restore_redirects(squirrel);
1277 #if !defined(__UCLIBC__) || defined(__ARCH_HAS_MMU__)
1278 if (!(child->pid = fork()))
1280 if (!(child->pid = vfork()))
1283 /* Set the handling for job control signals back to the default. */
1284 signal(SIGINT, SIG_DFL);
1285 signal(SIGQUIT, SIG_DFL);
1286 signal(SIGTSTP, SIG_DFL);
1287 signal(SIGTTIN, SIG_DFL);
1288 signal(SIGTTOU, SIG_DFL);
1289 signal(SIGCHLD, SIG_DFL);
1291 /* Close all open filehandles. */
1292 while (close_me_list)
1293 close((long)llist_pop(&close_me_list));
1295 if (outpipe[1] != -1) {
1305 dup2(nextout, 2); /* Really? */
1310 /* explicit redirects override pipes */
1311 setup_redirects(child,NULL);
1315 if (outpipe[1] != -1) {
1319 /* put our child in the process group whose leader is the
1320 first process in this pipe */
1321 setpgid(child->pid, newjob->progs[0].pid);
1327 /* If there isn't another process, nextin is garbage
1328 but it doesn't matter */
1329 nextin = pipefds[0];
1332 newjob->pgrp = newjob->progs[0].pid;
1334 insert_job(newjob, inbg);
1339 static int busy_loop(FILE * input)
1342 char *next_command = NULL;
1347 #if ENABLE_LASH_JOB_CONTROL
1349 /* save current owner of TTY so we can restore it on exit */
1350 parent_pgrp = tcgetpgrp(shell_terminal);
1352 newjob.job_list = &job_list;
1353 newjob.job_context = DEFAULT_CONTEXT;
1355 command = xzalloc(BUFSIZ);
1359 /* no job is in the foreground */
1361 /* see if any background processes have exited */
1362 checkjobs(&job_list);
1364 if (!next_command) {
1365 if (get_command_bufsiz(input, command))
1367 next_command = command;
1370 if (!expand_arguments(next_command)) {
1372 command = xzalloc(BUFSIZ);
1373 next_command = NULL;
1377 if (!parse_command(&next_command, &newjob, &inbg) &&
1379 int pipefds[2] = { -1, -1 };
1380 debug_printf("job=%p fed to run_command by busy_loop()'\n",
1382 run_command(&newjob, inbg, pipefds);
1386 command = xzalloc(BUFSIZ);
1387 next_command = NULL;
1390 /* a job is running in the foreground; wait for it */
1392 while (!job_list.fg->progs[i].pid ||
1393 job_list.fg->progs[i].is_stopped == 1) i++;
1395 if (waitpid(job_list.fg->progs[i].pid, &status, WUNTRACED) < 0) {
1396 if (errno != ECHILD) {
1397 bb_perror_msg_and_die("waitpid(%d)", job_list.fg->progs[i].pid);
1401 if (WIFEXITED(status) || WIFSIGNALED(status)) {
1402 /* the child exited */
1403 job_list.fg->running_progs--;
1404 job_list.fg->progs[i].pid = 0;
1406 last_return_code = WEXITSTATUS(status);
1408 if (!job_list.fg->running_progs) {
1410 remove_job(&job_list, job_list.fg);
1414 #if ENABLE_LASH_JOB_CONTROL
1416 /* the child was stopped */
1417 job_list.fg->stopped_progs++;
1418 job_list.fg->progs[i].is_stopped = 1;
1420 if (job_list.fg->stopped_progs == job_list.fg->running_progs) {
1421 printf("\n" JOB_STATUS_FORMAT, job_list.fg->jobid,
1422 "Stopped", job_list.fg->text);
1428 /* move the shell to the foreground */
1429 /* suppress messages when run from /linuxrc mag@sysgo.de */
1430 if (tcsetpgrp(shell_terminal, getpgrp()) && errno != ENOTTY)
1431 bb_perror_msg("tcsetpgrp");
1438 #if ENABLE_LASH_JOB_CONTROL
1439 /* return controlling TTY back to parent process group before exiting */
1440 if (tcsetpgrp(shell_terminal, parent_pgrp) && errno != ENOTTY)
1441 bb_perror_msg("tcsetpgrp");
1444 /* return exit status if called with "-c" */
1445 if (input == NULL && WIFEXITED(status))
1446 return WEXITSTATUS(status);
1451 #if ENABLE_FEATURE_CLEAN_UP
1452 static void free_memory(void)
1454 if (cwd && cwd != bb_msg_unknown) {
1458 if (job_list.fg && !job_list.fg->running_progs) {
1459 remove_job(&job_list, job_list.fg);
1463 void free_memory(void);
1466 #if ENABLE_LASH_JOB_CONTROL
1467 /* Make sure we have a controlling tty. If we get started under a job
1468 * aware app (like bash for example), make sure we are now in charge so
1469 * we don't fight over who gets the foreground */
1470 static void setup_job_control(void)
1475 /* Loop until we are in the foreground. */
1476 while ((status = tcgetpgrp (shell_terminal)) >= 0) {
1477 if (status == (shell_pgrp = getpgrp ())) {
1480 kill (- shell_pgrp, SIGTTIN);
1483 /* Ignore interactive and job-control signals. */
1484 signal(SIGINT, SIG_IGN);
1485 signal(SIGQUIT, SIG_IGN);
1486 signal(SIGTSTP, SIG_IGN);
1487 signal(SIGTTIN, SIG_IGN);
1488 signal(SIGTTOU, SIG_IGN);
1489 signal(SIGCHLD, SIG_IGN);
1491 /* Put ourselves in our own process group. */
1493 shell_pgrp = getpid();
1494 setpgid(shell_pgrp, shell_pgrp);
1496 /* Grab control of the terminal. */
1497 tcsetpgrp(shell_terminal, shell_pgrp);
1500 static inline void setup_job_control(void)
1505 int lash_main(int argc_l, char **argv_l);
1506 int lash_main(int argc_l, char **argv_l)
1509 FILE *input = stdin;
1513 #if ENABLE_FEATURE_EDITING
1514 line_input_state = new_line_input_t(FOR_SHELL);
1517 /* These variables need re-initializing when recursing */
1519 close_me_list = NULL;
1520 job_list.head = NULL;
1522 last_return_code = 1;
1524 if (argv[0] && argv[0][0] == '-') {
1526 prof_input = fopen("/etc/profile", "r");
1528 llist_add_to(&close_me_list, (void *)(long)fileno(prof_input));
1529 /* Now run the file */
1530 busy_loop(prof_input);
1531 fclose_if_not_stdin(prof_input);
1532 llist_pop(&close_me_list);
1536 opt = getopt32(argc_l, argv_l, "+ic:", &local_pending_command);
1537 #define LASH_OPT_i (1<<0)
1538 #define LASH_OPT_c (1<<1)
1539 if (opt & LASH_OPT_c) {
1544 /* A shell is interactive if the `-i' flag was given, or if all of
1545 * the following conditions are met:
1547 * no arguments remaining or the -s flag given
1548 * standard input is a terminal
1549 * standard output is a terminal
1550 * Refer to Posix.2, the description of the `sh' utility. */
1551 if (argv[optind] == NULL && input == stdin
1552 && isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)
1556 setup_job_control();
1557 if (opt & LASH_OPT_i) {
1558 /* Looks like they want an interactive shell */
1559 if (!ENABLE_FEATURE_SH_EXTRA_QUIET) {
1560 printf("\n\n%s Built-in shell (lash)\n"
1561 "Enter 'help' for a list of built-in commands.\n\n",
1564 } else if (!local_pending_command && argv[optind]) {
1565 //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
1566 input = xfopen(argv[optind], "r");
1567 /* be lazy, never mark this closed */
1568 llist_add_to(&close_me_list, (void *)(long)fileno(input));
1571 /* initialize the cwd -- this is never freed...*/
1572 cwd = xrealloc_getcwd_or_warn(NULL);
1574 cwd = bb_msg_unknown;
1576 if (ENABLE_FEATURE_CLEAN_UP) atexit(free_memory);
1578 if (ENABLE_FEATURE_EDITING) cmdedit_set_initial_prompt();
1581 return (busy_loop(input));