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...
28 #define expand_t glob_t
30 /* Always enable for the moment... */
31 #define CONFIG_LASH_PIPE_N_REDIRECTS
32 #define CONFIG_LASH_JOB_CONTROL
33 #define ENABLE_LASH_PIPE_N_REDIRECTS 1
34 #define ENABLE_LASH_JOB_CONTROL 1
37 enum { MAX_READ = 128 }; /* size of input buffer for 'read' builtin */
38 #define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
41 #if ENABLE_LASH_PIPE_N_REDIRECTS
42 enum redir_type { REDIRECT_INPUT, REDIRECT_OVERWRITE,
48 DEFAULT_CONTEXT = 0x1,
49 IF_TRUE_CONTEXT = 0x2,
50 IF_FALSE_CONTEXT = 0x4,
51 THEN_EXP_CONTEXT = 0x8,
52 ELSE_EXP_CONTEXT = 0x10
55 #define LASH_OPT_DONE (1)
56 #define LASH_OPT_SAW_QUOTE (2)
58 #if ENABLE_LASH_PIPE_N_REDIRECTS
60 enum redir_type type; /* type of redirection */
61 int fd; /* file descriptor being redirected */
62 char *filename; /* file to redirect fd to */
67 pid_t pid; /* 0 if exited */
68 char **argv; /* program name and arguments */
69 int num_redirects; /* elements in redirection array */
70 int is_stopped; /* is the program currently running? */
71 struct job *family; /* pointer back to the child's parent job */
72 #if ENABLE_LASH_PIPE_N_REDIRECTS
73 struct redir_struct *redirects; /* I/O redirects */
78 struct job *head; /* head of list of running jobs */
79 struct job *fg; /* current foreground job */
83 int jobid; /* job number */
84 int num_progs; /* total number of programs in job */
85 int running_progs; /* number of programs running */
86 char *text; /* name of job */
87 char *cmdbuf; /* buffer various argv's point into */
88 pid_t pgrp; /* process group ID for the job */
89 struct child_prog *progs; /* array of programs in job */
90 struct job *next; /* to track background commands */
91 int stopped_progs; /* number of programs alive, but stopped */
92 unsigned int job_context; /* bitmask defining current context */
93 struct jobset *job_list;
96 struct built_in_command {
97 const char *cmd; /* name */
98 const char *descr; /* description */
99 int (*function) (struct child_prog *); /* function ptr */
102 /* function prototypes for builtins */
103 static int builtin_cd(struct child_prog *cmd);
104 static int builtin_exec(struct child_prog *cmd);
105 static int builtin_exit(struct child_prog *cmd);
106 static int builtin_fg_bg(struct child_prog *cmd);
107 static int builtin_help(struct child_prog *cmd);
108 static int builtin_jobs(struct child_prog *dummy);
109 static int builtin_pwd(struct child_prog *dummy);
110 static int builtin_export(struct child_prog *cmd);
111 static int builtin_source(struct child_prog *cmd);
112 static int builtin_unset(struct child_prog *cmd);
113 static int builtin_read(struct child_prog *cmd);
116 /* function prototypes for shell stuff */
117 static void checkjobs(struct jobset *job_list);
118 static void remove_job(struct jobset *j_list, struct job *job);
119 static int get_command_bufsiz(FILE *source, char *command);
120 static int parse_command(char **command_ptr, struct job *job, int *inbg);
121 static int run_command(struct job *newjob, int inbg, int outpipe[2]);
122 static int pseudo_exec(struct child_prog *cmd) NORETURN;
123 static int busy_loop(FILE *input);
126 /* Table of built-in functions (these are non-forking builtins, meaning they
127 * can change global variables in the parent shell process but they will not
128 * work with pipes and redirects; 'unset foo | whatever' will not work) */
129 static const struct built_in_command bltins[] = {
130 {"bg" , "Resume a job in the background", builtin_fg_bg},
131 {"cd" , "Change working directory", builtin_cd},
132 {"exec" , "Exec command, replacing this shell with the exec'd process", builtin_exec},
133 {"exit" , "Exit from shell()", builtin_exit},
134 {"fg" , "Bring job into the foreground", builtin_fg_bg},
135 {"jobs" , "Lists the active jobs", builtin_jobs},
136 {"export", "Set environment variable", builtin_export},
137 {"unset" , "Unset environment variable", builtin_unset},
138 {"read" , "Input environment variable", builtin_read},
139 {"." , "Source-in and run commands in a file", builtin_source},
140 /* These were "forked applets", but distinction was nuked */
141 /* Original comment retained: */
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 {"pwd" , "Print current directory", builtin_pwd},
145 {"help" , "List shell built-in commands", builtin_help},
146 /* to do: add ulimit */
150 #define VEC_LAST(v) v[ARRAY_SIZE(v)-1]
153 static int shell_context; /* Type prompt trigger (PS1 or PS2) */
156 /* Globals that are static to this file */
158 static char *local_pending_command;
159 static struct jobset job_list = { NULL, NULL };
160 static int global_argc;
161 static char **global_argv;
162 static llist_t *close_me_list;
163 static int last_return_code;
164 static int last_bg_pid;
165 static unsigned int last_jobid;
166 static int shell_terminal;
167 static const char *PS1;
168 static const char *PS2 = "> ";
172 static inline void debug_printf(const char *format, ...)
175 va_start(args, format);
176 vfprintf(stderr, format, args);
180 static inline void debug_printf(const char UNUSED_PARAM *format, ...) { }
184 Most builtins need access to the struct child_prog that has
185 their arguments, previously coded as cmd->progs[0]. That coding
186 can exhibit a bug, if the builtin is not the first command in
187 a pipeline: "echo foo | exec sort" will attempt to exec foo.
189 builtin previous use notes
190 ------ ----------------- ---------
192 exec cmd->progs[0] squashed bug: didn't look for applets or forking builtins
194 fg_bg cmd->progs[0], job_list->head, job_list->fg
203 I added "struct job *family;" to struct child_prog,
204 and switched API to builtin_foo(struct child_prog *child);
205 So cmd->text becomes child->family->text
206 cmd->job_context becomes child->family->job_context
207 cmd->progs[0] becomes *child
208 job_list becomes child->family->job_list
212 static void update_cwd(void)
214 cwd = xrealloc_getcwd_or_warn(cwd);
216 cwd = xstrdup(bb_msg_unknown);
219 /* built-in 'cd <path>' handler */
220 static int builtin_cd(struct child_prog *child)
224 if (child->argv[1] == NULL)
225 newdir = getenv("HOME");
227 newdir = child->argv[1];
229 bb_perror_msg("cd: %s", newdir);
236 /* built-in 'exec' handler */
237 static int builtin_exec(struct child_prog *child)
239 if (child->argv[1] == NULL)
240 return EXIT_SUCCESS; /* Really? */
242 while (close_me_list)
243 close((long)llist_pop(&close_me_list));
248 /* built-in 'exit' handler */
249 static int builtin_exit(struct child_prog *child)
251 if (child->argv[1] == NULL)
254 exit(atoi(child->argv[1]));
257 /* built-in 'fg' and 'bg' handler */
258 static int builtin_fg_bg(struct child_prog *child)
263 /* If they gave us no args, assume they want the last backgrounded task */
264 if (!child->argv[1]) {
265 for (job = child->family->job_list->head; job; job = job->next) {
266 if (job->jobid == last_jobid) {
270 bb_error_msg("%s: no current job", child->argv[0]);
273 if (sscanf(child->argv[1], "%%%d", &jobnum) != 1) {
274 bb_error_msg(bb_msg_invalid_arg, child->argv[1], child->argv[0]);
277 for (job = child->family->job_list->head; job; job = job->next) {
278 if (job->jobid == jobnum) {
282 bb_error_msg("%s: %d: no such job", child->argv[0], jobnum);
285 if (*child->argv[0] == 'f') {
286 /* Put the job into the foreground. */
287 tcsetpgrp(shell_terminal, job->pgrp);
289 child->family->job_list->fg = job;
292 /* Restart the processes in the job */
293 for (i = 0; i < job->num_progs; i++)
294 job->progs[i].is_stopped = 0;
296 job->stopped_progs = 0;
298 i = kill(- job->pgrp, SIGCONT);
300 if (errno == ESRCH) {
301 remove_job(&job_list, job);
303 bb_perror_msg("kill (SIGCONT)");
310 /* built-in 'help' handler */
311 static int builtin_help(struct child_prog UNUSED_PARAM *dummy)
313 const struct built_in_command *x;
316 "Built-in commands:\n"
317 "------------------\n");
318 for (x = bltins; x <= &VEC_LAST(bltins); x++) {
319 if (x->descr == NULL)
321 printf("%s\t%s\n", x->cmd, x->descr);
327 /* built-in 'jobs' handler */
328 static int builtin_jobs(struct child_prog *child)
331 const char *status_string;
333 for (job = child->family->job_list->head; job; job = job->next) {
334 if (job->running_progs == job->stopped_progs)
335 status_string = "Stopped";
337 status_string = "Running";
339 printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->text);
345 /* built-in 'pwd' handler */
346 static int builtin_pwd(struct child_prog UNUSED_PARAM *dummy)
353 /* built-in 'export VAR=value' handler */
354 static int builtin_export(struct child_prog *child)
357 char *v = child->argv[1];
361 for (e = environ; *e; e++) {
368 bb_perror_msg("export");
369 #if ENABLE_FEATURE_EDITING_FANCY_PROMPT
370 if (strncmp(v, "PS1=", 4) == 0)
374 #if ENABLE_LOCALE_SUPPORT
375 // TODO: why getenv? "" would be just as good...
376 if (strncmp(v, "LC_ALL=", 7) == 0)
377 setlocale(LC_ALL, getenv("LC_ALL"));
378 if (strncmp(v, "LC_CTYPE=", 9) == 0)
379 setlocale(LC_CTYPE, getenv("LC_CTYPE"));
385 /* built-in 'read VAR' handler */
386 static int builtin_read(struct child_prog *child)
390 char string[MAX_READ];
392 if (child->argv[1]) {
393 /* argument (VAR) given: put "VAR=" into buffer */
394 safe_strncpy(string, child->argv[1], MAX_READ-1);
395 len = strlen(string);
398 fgets(&string[len], sizeof(string) - len, stdin); /* read string */
399 res = strlen(string);
401 string[--res] = '\0'; /* chomp trailing newline */
403 ** string should now contain "VAR=<value>"
404 ** copy it (putenv() won't do that, so we must make sure
405 ** the string resides in a static buffer!)
412 bb_perror_msg("read");
414 fgets(string, sizeof(string), stdin);
419 /* Built-in '.' handler (read-in and execute commands from file) */
420 static int builtin_source(struct child_prog *child)
425 input = fopen_or_warn(child->argv[1], "r");
430 llist_add_to(&close_me_list, (void *)(long)fileno(input));
431 /* Now run the file */
432 status = busy_loop(input);
434 llist_pop(&close_me_list);
438 /* built-in 'unset VAR' handler */
439 static int builtin_unset(struct child_prog *child)
441 if (child->argv[1] == NULL) {
442 printf(bb_msg_requires_arg, "unset");
445 unsetenv(child->argv[1]);
449 #if ENABLE_LASH_JOB_CONTROL
450 /* free up all memory from a job */
451 static void free_job(struct job *cmd)
456 for (i = 0; i < cmd->num_progs; i++) {
457 free(cmd->progs[i].argv);
458 #if ENABLE_LASH_PIPE_N_REDIRECTS
459 free(cmd->progs[i].redirects);
465 keep = cmd->job_list;
466 memset(cmd, 0, sizeof(struct job));
467 cmd->job_list = keep;
470 /* remove a job from a jobset */
471 static void remove_job(struct jobset *j_list, struct job *job)
476 if (job == j_list->head) {
477 j_list->head = job->next;
479 prevjob = j_list->head;
480 while (prevjob->next != job)
481 prevjob = prevjob->next;
482 prevjob->next = job->next;
486 last_jobid = j_list->head->jobid;
493 /* Checks to see if any background processes have exited -- if they
494 have, figure out why and see if a job has completed */
495 static void checkjobs(struct jobset *j_list)
502 while ((childpid = waitpid(-1, &status, WNOHANG | WUNTRACED)) > 0) {
503 for (job = j_list->head; job; job = job->next) {
505 while (prognum < job->num_progs &&
506 job->progs[prognum].pid != childpid) prognum++;
507 if (prognum < job->num_progs)
511 /* This happens on backticked commands */
515 if (WIFEXITED(status) || WIFSIGNALED(status)) {
517 job->running_progs--;
518 job->progs[prognum].pid = 0;
520 if (!job->running_progs) {
521 printf(JOB_STATUS_FORMAT, job->jobid, "Done", job->text);
523 remove_job(j_list, job);
527 job->stopped_progs++;
528 job->progs[prognum].is_stopped = 1;
532 if (childpid == -1 && errno != ECHILD)
533 bb_perror_msg("waitpid");
536 static void checkjobs(struct jobset *j_list)
539 static void free_job(struct job *cmd)
542 static void remove_job(struct jobset *j_list, struct job *job)
547 #if ENABLE_LASH_PIPE_N_REDIRECTS
548 /* squirrel != NULL means we squirrel away copies of stdin, stdout,
549 * and stderr if they are redirected. */
550 static int setup_redirects(struct child_prog *prog, int squirrel[])
555 struct redir_struct *redir = prog->redirects;
557 for (i = 0; i < prog->num_redirects; i++, redir++) {
558 switch (redir->type) {
562 case REDIRECT_OVERWRITE:
563 mode = O_WRONLY | O_CREAT | O_TRUNC;
565 case REDIRECT_APPEND:
566 mode = O_WRONLY | O_CREAT | O_APPEND;
570 openfd = open_or_warn(redir->filename, mode);
572 /* this could get lost if stderr has been redirected, but
573 bash and ash both lose it as well (though zsh doesn't!) */
577 if (openfd != redir->fd) {
578 if (squirrel && redir->fd < 3) {
579 squirrel[redir->fd] = dup(redir->fd);
580 close_on_exec_on(squirrel[redir->fd]);
582 dup2(openfd, redir->fd);
590 static void restore_redirects(int squirrel[])
593 for (i = 0; i < 3; i++) {
596 /* No error checking. I sure wouldn't know what
597 * to do with an error if I found one! */
604 static inline int setup_redirects(struct child_prog *prog, int squirrel[])
608 static inline void restore_redirects(int squirrel[])
613 static inline void cmdedit_set_initial_prompt(void)
615 #if !ENABLE_FEATURE_EDITING_FANCY_PROMPT
624 static inline const char* setup_prompt_string(void)
626 #if !ENABLE_FEATURE_EDITING_FANCY_PROMPT
627 /* Set up the prompt */
628 if (shell_context == 0) {
631 ns = xmalloc(strlen(cwd)+4);
632 sprintf(ns, "%s %c ", cwd, (geteuid() != 0) ? '$': '#');
639 return (shell_context == 0)? PS1 : PS2;
643 #if ENABLE_FEATURE_EDITING
644 static line_input_t *line_input_state;
647 static int get_command_bufsiz(FILE *source, char *command)
649 const char *prompt_str;
651 if (source == NULL) {
652 if (local_pending_command) {
653 /* a command specified (-c option): return it & mark it done */
654 strncpy(command, local_pending_command, BUFSIZ);
655 local_pending_command = NULL;
661 if (source == stdin) {
662 prompt_str = setup_prompt_string();
664 #if ENABLE_FEATURE_EDITING
666 ** enable command line editing only while a command line
667 ** is actually being read; otherwise, we'll end up bequeathing
668 ** atexit() handlers and other unwanted stuff to our
669 ** child processes (rob@sysgo.de)
671 read_line_input(prompt_str, command, BUFSIZ, line_input_state);
674 fputs(prompt_str, stdout);
678 if (!fgets(command, BUFSIZ - 2, source)) {
687 static char * strsep_space(char *string, int * ix)
689 /* Short circuit the trivial case */
690 if (!string || ! string[*ix])
693 /* Find the end of the token. */
694 while (string[*ix] && !isspace(string[*ix]) ) {
698 /* Find the end of any whitespace trailing behind
699 * the token and let that be part of the token */
700 while (string[*ix] && isspace(string[*ix])) {
705 /* Nothing useful was found */
709 return xstrndup(string, *ix);
712 static int expand_arguments(char *command)
714 static const char out_of_space[] ALIGN1 = "out of space during expansion";
716 int total_length = 0, length, i, retval, ix = 0;
717 expand_t expand_result;
718 char *tmpcmd, *cmd, *cmd_copy;
719 char *src, *dst, *var;
720 int flags = GLOB_NOCHECK
729 /* get rid of the terminating \n */
732 /* Fix up escape sequences to be the Real Thing(tm) */
733 while (command && command[ix]) {
734 if (command[ix] == '\\') {
735 const char *tmp = command+ix+1;
736 command[ix] = bb_process_escape_sequence( &tmp );
737 memmove(command+ix + 1, tmp, strlen(tmp)+1);
741 /* Use glob and then fixup environment variables and such */
743 /* It turns out that glob is very stupid. We have to feed it one word at a
744 * time since it can't cope with a full string. Here we convert command
745 * (char*) into cmd (char**, one word per string) */
747 /* We need a clean copy, so strsep can mess up the copy while
748 * we write stuff into the original (in a minute) */
749 cmd = cmd_copy = xstrdup(command);
751 for (ix = 0, tmpcmd = cmd;
752 (tmpcmd = strsep_space(cmd, &ix)) != NULL; cmd += ix, ix = 0) {
755 /* we need to trim() the result for glob! */
757 retval = glob(tmpcmd, flags, NULL, &expand_result);
758 free(tmpcmd); /* Free mem allocated by strsep_space */
759 if (retval == GLOB_NOSPACE) {
760 /* Mem may have been allocated... */
761 globfree(&expand_result);
762 bb_error_msg(out_of_space);
764 } else if (retval != 0) {
765 /* Some other error. GLOB_NOMATCH shouldn't
766 * happen because of the GLOB_NOCHECK flag in
768 bb_error_msg("syntax error");
771 /* Convert from char** (one word per string) to a simple char*,
772 * but don't overflow command which is BUFSIZ in length */
773 for (i = 0; i < expand_result.gl_pathc; i++) {
774 length = strlen(expand_result.gl_pathv[i]);
775 if (total_length+length+1 >= BUFSIZ) {
776 bb_error_msg(out_of_space);
779 strcat(command+total_length, " ");
781 strcat(command+total_length, expand_result.gl_pathv[i]);
782 total_length += length;
784 globfree(&expand_result);
790 /* Now do the shell variable substitutions which
791 * wordexp can't do for us, namely $? and $! */
793 while ((dst = strchr(src,'$')) != NULL) {
797 var = itoa(last_return_code);
800 if (last_bg_pid == -1)
803 var = itoa(last_bg_pid);
805 /* Everything else like $$, $#, $[0-9], etc. should all be
806 * expanded by wordexp(), so we can in theory skip that stuff
807 * here, but just to be on the safe side (i.e., since uClibc
808 * wordexp doesn't do this stuff yet), lets leave it in for
811 var = itoa(getpid());
814 var = itoa(global_argc - 1);
816 case '0':case '1':case '2':case '3':case '4':
817 case '5':case '6':case '7':case '8':case '9':
819 int ixx = *(dst+1)-48+1;
820 if (ixx >= global_argc) {
823 var = global_argv[ixx];
830 /* a single character construction was found, and
831 * already handled in the case statement */
834 /* Looks like an environment variable */
836 int num_skip_chars = 0;
837 int dstlen = strlen(dst);
838 /* Is this a ${foo} type variable? */
839 if (dstlen >= 2 && *(dst+1) == '{') {
840 src = strchr(dst+1, '}');
844 while (isalnum(*src) || *src == '_') src++;
850 *src = '\0'; /* temporary */
851 var = getenv(dst + 1 + num_skip_chars);
853 src += num_skip_chars;
856 /* Seems we got an un-expandable variable. So delete it. */
860 int subst_len = strlen(var);
861 int trail_len = strlen(src);
862 if (dst+subst_len+trail_len >= command+BUFSIZ) {
863 bb_error_msg(out_of_space);
866 /* Move stuff to the end of the string to accommodate
867 * filling the created gap with the new stuff */
868 memmove(dst+subst_len, src, trail_len+1);
869 /* Now copy in the new stuff */
870 memcpy(dst, var, subst_len);
878 /* Return cmd->num_progs as 0 if no command is present (e.g. an empty
879 line). If a valid command is found, command_ptr is set to point to
880 the beginning of the next command (if the original command had more
881 then one job associated with it) or NULL if no more commands are
883 static int parse_command(char **command_ptr, struct job *job, int *inbg)
886 char *return_command = NULL;
892 struct child_prog *prog;
893 #if ENABLE_LASH_PIPE_N_REDIRECTS
898 /* skip leading white space */
899 *command_ptr = skip_whitespace(*command_ptr);
901 /* this handles empty lines or leading '#' characters */
902 if (!**command_ptr || (**command_ptr == '#')) {
909 job->progs = xmalloc(sizeof(*job->progs));
911 /* We set the argv elements to point inside of this string. The
912 memory is freed by free_job(). Allocate twice the original
913 length in case we need to quote every single character.
915 Getting clean memory relieves us of the task of NULL
916 terminating things and makes the rest of this look a bit
917 cleaner (though it is, admittedly, a tad less efficient) */
918 job->cmdbuf = command = xzalloc(2*strlen(*command_ptr) + 1);
922 prog->num_redirects = 0;
923 prog->is_stopped = 0;
925 #if ENABLE_LASH_PIPE_N_REDIRECTS
926 prog->redirects = NULL;
930 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
931 prog->argv[0] = job->cmdbuf;
936 while (*src && !(flag & LASH_OPT_DONE)) {
943 bb_error_msg("character expected after \\");
948 /* in shell, "\'" should yield \' */
954 if (*src == '*' || *src == '?'
955 || *src == '[' || *src == ']'
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 /* Check if the command matches any of the forking builtins. */
1142 for (x = bltins; x <= &VEC_LAST(bltins); x++) {
1143 if (strcmp(child->argv[0], x->cmd) == 0) {
1144 _exit(x->function(child));
1148 /* Check if the command matches any busybox internal
1149 * commands ("applets") here. Following discussions from
1150 * November 2000 on busybox@busybox.net, don't use
1151 * bb_get_last_path_component_nostrip(). This way explicit
1152 * (with slashes) filenames will never be interpreted as an
1153 * applet, just like with builtins. This way the user can
1154 * override an applet with an explicit filename reference.
1155 * The only downside to this change is that an explicit
1156 * /bin/foo invocation will fork and exec /bin/foo, even if
1157 * /bin/foo is a symlink to busybox.
1159 if (ENABLE_FEATURE_SH_STANDALONE) {
1160 run_applet_and_exit(child->argv[0], child->argv);
1163 execvp(child->argv[0], child->argv);
1165 /* Do not use bb_perror_msg_and_die() here, since we must not
1166 * call exit() but should call _exit() instead */
1167 bb_simple_perror_msg(child->argv[0]);
1168 _exit(EXIT_FAILURE);
1171 static void insert_job(struct job *newjob, int inbg)
1174 struct jobset *j_list = newjob->job_list;
1176 /* find the ID for thejob to use */
1178 for (thejob = j_list->head; thejob; thejob = thejob->next)
1179 if (thejob->jobid >= newjob->jobid)
1180 newjob->jobid = thejob->jobid + 1;
1182 /* add thejob to the list of running jobs */
1183 if (!j_list->head) {
1184 thejob = j_list->head = xmalloc(sizeof(*thejob));
1186 for (thejob = j_list->head; thejob->next; thejob = thejob->next) /* nothing */;
1187 thejob->next = xmalloc(sizeof(*thejob));
1188 thejob = thejob->next;
1191 *thejob = *newjob; /* physically copy the struct job */
1192 thejob->next = NULL;
1193 thejob->running_progs = thejob->num_progs;
1194 thejob->stopped_progs = 0;
1196 #if ENABLE_LASH_JOB_CONTROL
1198 /* we don't wait for background thejobs to return -- append it
1199 to the list of backgrounded thejobs and leave it alone */
1200 printf("[%d] %d\n", thejob->jobid,
1201 newjob->progs[newjob->num_progs - 1].pid);
1202 last_jobid = newjob->jobid;
1203 last_bg_pid = newjob->progs[newjob->num_progs - 1].pid;
1205 newjob->job_list->fg = thejob;
1207 /* move the new process group into the foreground */
1208 /* Ignore errors since child could have already exited */
1209 tcsetpgrp(shell_terminal, newjob->pgrp);
1214 static int run_command(struct job *newjob, int inbg, int outpipe[2])
1216 /* struct job *thejob; */
1218 int nextin, nextout;
1219 int pipefds[2]; /* pipefd[0] is for reading */
1220 const struct built_in_command *x;
1221 struct child_prog *child;
1224 for (i = 0; i < newjob->num_progs; i++) {
1225 child = &(newjob->progs[i]);
1228 if ((i + 1) < newjob->num_progs) {
1230 nextout = pipefds[1];
1231 } else if (outpipe[1] != -1) {
1232 nextout = outpipe[1];
1235 /* Check if the command matches any non-forking builtins,
1236 * but only if this is a simple command.
1237 * Non-forking builtins within pipes have to fork anyway,
1238 * and are handled in pseudo_exec. "echo foo | read bar"
1239 * is doomed to failure, and doesn't work on bash, either.
1241 if (newjob->num_progs == 1) {
1243 int squirrel[] = {-1, -1, -1};
1245 /* Check if the command sets an environment variable. */
1246 if (strchr(child->argv[0], '=') != NULL) {
1247 child->argv[1] = child->argv[0];
1248 return builtin_export(child);
1251 for (x = bltins; x <= &VEC_LAST(bltins); x++) {
1252 if (strcmp(child->argv[0], x->cmd) == 0) {
1253 setup_redirects(child, squirrel);
1254 rcode = x->function(child);
1255 restore_redirects(squirrel);
1259 #if ENABLE_FEATURE_SH_STANDALONE
1261 int a = find_applet_by_name(child->argv[i]);
1262 if (a >= 0 && APPLET_IS_NOFORK(a)) {
1263 setup_redirects(child, squirrel);
1264 rcode = run_nofork_applet(a, child->argv + i);
1265 restore_redirects(squirrel);
1273 child->pid = fork();
1275 child->pid = vfork();
1278 /* Set the handling for job control signals back to the default. */
1279 signal(SIGINT, SIG_DFL);
1280 signal(SIGQUIT, SIG_DFL);
1281 signal(SIGTSTP, SIG_DFL);
1282 signal(SIGTTIN, SIG_DFL);
1283 signal(SIGTTOU, SIG_DFL);
1284 signal(SIGCHLD, SIG_DFL);
1286 /* Close all open filehandles. */
1287 while (close_me_list)
1288 close((long)llist_pop(&close_me_list));
1290 if (outpipe[1] != -1) {
1300 dup2(nextout, 2); /* Really? */
1305 /* explicit redirects override pipes */
1306 setup_redirects(child,NULL);
1310 if (outpipe[1] != -1) {
1314 /* put our child in the process group whose leader is the
1315 first process in this pipe */
1316 setpgid(child->pid, newjob->progs[0].pid);
1322 /* If there isn't another process, nextin is garbage
1323 but it doesn't matter */
1324 nextin = pipefds[0];
1327 newjob->pgrp = newjob->progs[0].pid;
1329 insert_job(newjob, inbg);
1334 static int busy_loop(FILE *input)
1337 char *next_command = NULL;
1342 #if ENABLE_LASH_JOB_CONTROL
1344 /* save current owner of TTY so we can restore it on exit */
1345 parent_pgrp = tcgetpgrp(shell_terminal);
1347 newjob.job_list = &job_list;
1348 newjob.job_context = DEFAULT_CONTEXT;
1350 command = xzalloc(BUFSIZ);
1354 /* no job is in the foreground */
1356 /* see if any background processes have exited */
1357 checkjobs(&job_list);
1359 if (!next_command) {
1360 if (get_command_bufsiz(input, command))
1362 next_command = command;
1365 if (!expand_arguments(next_command)) {
1367 command = xzalloc(BUFSIZ);
1368 next_command = NULL;
1372 if (!parse_command(&next_command, &newjob, &inbg)
1375 int pipefds[2] = { -1, -1 };
1376 debug_printf("job=%p fed to run_command by busy_loop()'\n",
1378 run_command(&newjob, inbg, pipefds);
1382 command = xzalloc(BUFSIZ);
1383 next_command = NULL;
1386 /* a job is running in the foreground; wait for it */
1388 while (!job_list.fg->progs[i].pid ||
1389 job_list.fg->progs[i].is_stopped == 1) i++;
1391 if (waitpid(job_list.fg->progs[i].pid, &status, WUNTRACED) < 0) {
1392 if (errno != ECHILD) {
1393 bb_perror_msg_and_die("waitpid(%d)", job_list.fg->progs[i].pid);
1397 if (WIFEXITED(status) || WIFSIGNALED(status)) {
1398 /* the child exited */
1399 job_list.fg->running_progs--;
1400 job_list.fg->progs[i].pid = 0;
1402 last_return_code = WEXITSTATUS(status);
1404 if (!job_list.fg->running_progs) {
1406 remove_job(&job_list, job_list.fg);
1410 #if ENABLE_LASH_JOB_CONTROL
1412 /* the child was stopped */
1413 job_list.fg->stopped_progs++;
1414 job_list.fg->progs[i].is_stopped = 1;
1416 if (job_list.fg->stopped_progs == job_list.fg->running_progs) {
1417 printf("\n" JOB_STATUS_FORMAT, job_list.fg->jobid,
1418 "Stopped", job_list.fg->text);
1424 /* move the shell to the foreground */
1425 /* suppress messages when run from /linuxrc mag@sysgo.de */
1426 if (tcsetpgrp(shell_terminal, getpgrp()) && errno != ENOTTY)
1427 bb_perror_msg("tcsetpgrp");
1434 #if ENABLE_LASH_JOB_CONTROL
1435 /* return controlling TTY back to parent process group before exiting */
1436 if (tcsetpgrp(shell_terminal, parent_pgrp) && errno != ENOTTY)
1437 bb_perror_msg("tcsetpgrp");
1440 /* return exit status if called with "-c" */
1441 if (input == NULL && WIFEXITED(status))
1442 return WEXITSTATUS(status);
1447 #if ENABLE_FEATURE_CLEAN_UP
1448 static void free_memory(void)
1452 if (job_list.fg && !job_list.fg->running_progs) {
1453 remove_job(&job_list, job_list.fg);
1457 void free_memory(void);
1460 #if ENABLE_LASH_JOB_CONTROL
1461 /* Make sure we have a controlling tty. If we get started under a job
1462 * aware app (like bash for example), make sure we are now in charge so
1463 * we don't fight over who gets the foreground */
1464 static void setup_job_control(void)
1469 /* Loop until we are in the foreground. */
1470 while ((status = tcgetpgrp(shell_terminal)) >= 0) {
1471 shell_pgrp = getpgrp();
1472 if (status == shell_pgrp) {
1475 kill(- shell_pgrp, SIGTTIN);
1478 /* Ignore interactive and job-control signals. */
1479 signal(SIGINT, SIG_IGN);
1480 signal(SIGQUIT, SIG_IGN);
1481 signal(SIGTSTP, SIG_IGN);
1482 signal(SIGTTIN, SIG_IGN);
1483 signal(SIGTTOU, SIG_IGN);
1484 signal(SIGCHLD, SIG_IGN);
1486 /* Put ourselves in our own process group. */
1488 shell_pgrp = getpid();
1489 setpgid(shell_pgrp, shell_pgrp);
1491 /* Grab control of the terminal. */
1492 tcsetpgrp(shell_terminal, shell_pgrp);
1495 static inline void setup_job_control(void)
1500 int lash_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
1501 int lash_main(int argc, char **argv)
1504 FILE *input = stdin;
1509 #if ENABLE_FEATURE_EDITING
1510 line_input_state = new_line_input_t(FOR_SHELL);
1513 /* These variables need re-initializing when recursing */
1515 close_me_list = NULL;
1516 job_list.head = NULL;
1518 last_return_code = 1;
1520 if (global_argv[0] && global_argv[0][0] == '-') {
1522 prof_input = fopen_for_read("/etc/profile");
1524 llist_add_to(&close_me_list, (void *)(long)fileno(prof_input));
1525 /* Now run the file */
1526 busy_loop(prof_input);
1527 fclose_if_not_stdin(prof_input);
1528 llist_pop(&close_me_list);
1532 opt = getopt32(argv, "+ic:", &local_pending_command);
1533 #define LASH_OPT_i (1<<0)
1534 #define LASH_OPT_c (1<<1)
1535 if (opt & LASH_OPT_c) {
1538 global_argv += optind;
1540 /* A shell is interactive if the `-i' flag was given, or if all of
1541 * the following conditions are met:
1543 * no arguments remaining or the -s flag given
1544 * standard input is a terminal
1545 * standard output is a terminal
1546 * Refer to Posix.2, the description of the `sh' utility. */
1547 if (global_argv[optind] == NULL && input == stdin
1548 && isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)
1552 setup_job_control();
1553 if (opt & LASH_OPT_i) {
1554 /* Looks like they want an interactive shell */
1555 if (!ENABLE_FEATURE_SH_EXTRA_QUIET) {
1556 printf("\n\n%s built-in shell (lash)\n"
1557 "Enter 'help' for a list of built-in commands.\n\n",
1560 } else if (!local_pending_command && global_argv[optind]) {
1561 //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
1562 input = xfopen_for_read(global_argv[optind]);
1563 /* be lazy, never mark this closed */
1564 llist_add_to(&close_me_list, (void *)(long)fileno(input));
1567 /* initialize the cwd -- this is never freed...*/
1570 if (ENABLE_FEATURE_CLEAN_UP) atexit(free_memory);
1572 if (ENABLE_FEATURE_EDITING) cmdedit_set_initial_prompt();
1575 return busy_loop(input);