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
36 enum { MAX_READ = 128 }; /* size of input buffer for 'read' builtin */
37 #define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
40 #if ENABLE_LASH_PIPE_N_REDIRECTS
41 enum redir_type { REDIRECT_INPUT, REDIRECT_OVERWRITE,
47 DEFAULT_CONTEXT = 0x1,
48 IF_TRUE_CONTEXT = 0x2,
49 IF_FALSE_CONTEXT = 0x4,
50 THEN_EXP_CONTEXT = 0x8,
51 ELSE_EXP_CONTEXT = 0x10
54 #define LASH_OPT_DONE (1)
55 #define LASH_OPT_SAW_QUOTE (2)
57 #if ENABLE_LASH_PIPE_N_REDIRECTS
59 enum redir_type type; /* type of redirection */
60 int fd; /* file descriptor being redirected */
61 char *filename; /* file to redirect fd to */
66 pid_t pid; /* 0 if exited */
67 char **argv; /* program name and arguments */
68 int num_redirects; /* elements in redirection array */
69 int is_stopped; /* is the program currently running? */
70 struct job *family; /* pointer back to the child's parent job */
71 #if ENABLE_LASH_PIPE_N_REDIRECTS
72 struct redir_struct *redirects; /* I/O redirects */
77 struct job *head; /* head of list of running jobs */
78 struct job *fg; /* current foreground job */
82 int jobid; /* job number */
83 int num_progs; /* total number of programs in job */
84 int running_progs; /* number of programs running */
85 char *text; /* name of job */
86 char *cmdbuf; /* buffer various argv's point into */
87 pid_t pgrp; /* process group ID for the job */
88 struct child_prog *progs; /* array of programs in job */
89 struct job *next; /* to track background commands */
90 int stopped_progs; /* number of programs alive, but stopped */
91 unsigned int job_context; /* bitmask defining current context */
92 struct jobset *job_list;
95 struct built_in_command {
96 const char *cmd; /* name */
97 const char *descr; /* description */
98 int (*function) (struct child_prog *); /* function ptr */
101 /* function prototypes for builtins */
102 static int builtin_cd(struct child_prog *cmd);
103 static int builtin_exec(struct child_prog *cmd);
104 static int builtin_exit(struct child_prog *cmd);
105 static int builtin_fg_bg(struct child_prog *cmd);
106 static int builtin_help(struct child_prog *cmd);
107 static int builtin_jobs(struct child_prog *dummy);
108 static int builtin_pwd(struct child_prog *dummy);
109 static int builtin_export(struct child_prog *cmd);
110 static int builtin_source(struct child_prog *cmd);
111 static int builtin_unset(struct child_prog *cmd);
112 static int builtin_read(struct child_prog *cmd);
115 /* function prototypes for shell stuff */
116 static void checkjobs(struct jobset *job_list);
117 static void remove_job(struct jobset *j_list, struct job *job);
118 static int get_command_bufsiz(FILE * source, char *command);
119 static int parse_command(char **command_ptr, struct job *job, int *inbg);
120 static int run_command(struct job *newjob, int inbg, int outpipe[2]);
121 static int pseudo_exec(struct child_prog *cmd) ATTRIBUTE_NORETURN;
122 static int busy_loop(FILE * input);
125 /* Table of built-in functions (these are non-forking builtins, meaning they
126 * can change global variables in the parent shell process but they will not
127 * work with pipes and redirects; 'unset foo | whatever' will not work) */
128 static const struct built_in_command bltins[] = {
129 {"bg" , "Resume a job in the background", builtin_fg_bg},
130 {"cd" , "Change working directory", builtin_cd},
131 {"exec" , "Exec command, replacing this shell with the exec'd process", builtin_exec},
132 {"exit" , "Exit from shell()", builtin_exit},
133 {"fg" , "Bring job into the foreground", builtin_fg_bg},
134 {"jobs" , "Lists the active jobs", builtin_jobs},
135 {"export", "Set environment variable", builtin_export},
136 {"unset" , "Unset environment variable", builtin_unset},
137 {"read" , "Input environment variable", builtin_read},
138 {"." , "Source-in and run commands in a file", builtin_source},
139 /* These were "forked applets", but distinction was nuked */
140 /* Original comment retained: */
141 /* Table of forking built-in functions (things that fork cannot change global
142 * variables in the parent process, such as the current working directory) */
143 {"pwd" , "Print current directory", builtin_pwd},
144 {"help" , "List shell built-in commands", builtin_help},
145 /* to do: add ulimit */
148 #define VEC_SIZE(v) (sizeof(v)/sizeof(v[0]))
149 #define VEC_LAST(v) v[VEC_SIZE(v)-1]
152 static int shell_context; /* Type prompt trigger (PS1 or PS2) */
155 /* Globals that are static to this file */
157 static char *local_pending_command;
158 static struct jobset job_list = { NULL, NULL };
161 static llist_t *close_me_list;
162 static int last_return_code;
163 static int last_bg_pid;
164 static unsigned int last_jobid;
165 static int shell_terminal;
166 static const char *PS1;
167 static const char *PS2 = "> ";
171 static inline void debug_printf(const char *format, ...)
174 va_start(args, format);
175 vfprintf(stderr, format, args);
179 static inline void debug_printf(const char ATTRIBUTE_UNUSED *format, ...) { }
183 Most builtins need access to the struct child_prog that has
184 their arguments, previously coded as cmd->progs[0]. That coding
185 can exhibit a bug, if the builtin is not the first command in
186 a pipeline: "echo foo | exec sort" will attempt to exec foo.
188 builtin previous use notes
189 ------ ----------------- ---------
191 exec cmd->progs[0] squashed bug: didn't look for applets or forking builtins
193 fg_bg cmd->progs[0], job_list->head, job_list->fg
202 I added "struct job *family;" to struct child_prog,
203 and switched API to builtin_foo(struct child_prog *child);
204 So cmd->text becomes child->family->text
205 cmd->job_context becomes child->family->job_context
206 cmd->progs[0] becomes *child
207 job_list becomes child->family->job_list
211 static void update_cwd(void)
213 cwd = xrealloc_getcwd_or_warn(cwd);
215 cwd = xstrdup(bb_msg_unknown);
218 /* built-in 'cd <path>' handler */
219 static int builtin_cd(struct child_prog *child)
223 if (child->argv[1] == NULL)
224 newdir = getenv("HOME");
226 newdir = child->argv[1];
228 bb_perror_msg("cd: %s", newdir);
235 /* built-in 'exec' handler */
236 static int builtin_exec(struct child_prog *child)
238 if (child->argv[1] == NULL)
239 return EXIT_SUCCESS; /* Really? */
241 while (close_me_list)
242 close((long)llist_pop(&close_me_list));
247 /* built-in 'exit' handler */
248 static int builtin_exit(struct child_prog *child)
250 if (child->argv[1] == NULL)
253 exit(atoi(child->argv[1]));
256 /* built-in 'fg' and 'bg' handler */
257 static int builtin_fg_bg(struct child_prog *child)
262 /* If they gave us no args, assume they want the last backgrounded task */
263 if (!child->argv[1]) {
264 for (job = child->family->job_list->head; job; job = job->next) {
265 if (job->jobid == last_jobid) {
269 bb_error_msg("%s: no current job", child->argv[0]);
272 if (sscanf(child->argv[1], "%%%d", &jobnum) != 1) {
273 bb_error_msg(bb_msg_invalid_arg, child->argv[1], child->argv[0]);
276 for (job = child->family->job_list->head; job; job = job->next) {
277 if (job->jobid == jobnum) {
281 bb_error_msg("%s: %d: no such job", child->argv[0], jobnum);
284 if (*child->argv[0] == 'f') {
285 /* Put the job into the foreground. */
286 tcsetpgrp(shell_terminal, job->pgrp);
288 child->family->job_list->fg = job;
291 /* Restart the processes in the job */
292 for (i = 0; i < job->num_progs; i++)
293 job->progs[i].is_stopped = 0;
295 job->stopped_progs = 0;
297 i = kill(- job->pgrp, SIGCONT);
299 if (errno == ESRCH) {
300 remove_job(&job_list, job);
302 bb_perror_msg("kill (SIGCONT)");
309 /* built-in 'help' handler */
310 static int builtin_help(struct child_prog ATTRIBUTE_UNUSED *dummy)
312 const struct built_in_command *x;
314 printf("\nBuilt-in commands:\n"
315 "-------------------\n");
316 for (x = bltins; x <= &VEC_LAST(bltins); x++) {
317 if (x->descr == NULL)
319 printf("%s\t%s\n", x->cmd, x->descr);
325 /* built-in 'jobs' handler */
326 static int builtin_jobs(struct child_prog *child)
329 const char *status_string;
331 for (job = child->family->job_list->head; job; job = job->next) {
332 if (job->running_progs == job->stopped_progs)
333 status_string = "Stopped";
335 status_string = "Running";
337 printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->text);
343 /* built-in 'pwd' handler */
344 static int builtin_pwd(struct child_prog ATTRIBUTE_UNUSED *dummy)
351 /* built-in 'export VAR=value' handler */
352 static int builtin_export(struct child_prog *child)
355 char *v = child->argv[1];
359 for (e = environ; *e; e++) {
366 bb_perror_msg("export");
367 #if ENABLE_FEATURE_EDITING_FANCY_PROMPT
368 if (strncmp(v, "PS1=", 4) == 0)
372 #if ENABLE_LOCALE_SUPPORT
373 // TODO: why getenv? "" would be just as good...
374 if (strncmp(v, "LC_ALL=", 7) == 0)
375 setlocale(LC_ALL, getenv("LC_ALL"));
376 if (strncmp(v, "LC_CTYPE=", 9) == 0)
377 setlocale(LC_CTYPE, getenv("LC_CTYPE"));
383 /* built-in 'read VAR' handler */
384 static int builtin_read(struct child_prog *child)
388 char string[MAX_READ];
390 if (child->argv[1]) {
391 /* argument (VAR) given: put "VAR=" into buffer */
392 safe_strncpy(string, child->argv[1], MAX_READ-1);
393 len = strlen(string);
396 fgets(&string[len], sizeof(string) - len, stdin); /* read string */
397 res = strlen(string);
399 string[--res] = '\0'; /* chomp trailing newline */
401 ** string should now contain "VAR=<value>"
402 ** copy it (putenv() won't do that, so we must make sure
403 ** the string resides in a static buffer!)
410 bb_perror_msg("read");
412 fgets(string, sizeof(string), stdin);
417 /* Built-in '.' handler (read-in and execute commands from file) */
418 static int builtin_source(struct child_prog *child)
423 input = fopen_or_warn(child->argv[1], "r");
428 llist_add_to(&close_me_list, (void *)(long)fileno(input));
429 /* Now run the file */
430 status = busy_loop(input);
432 llist_pop(&close_me_list);
436 /* built-in 'unset VAR' handler */
437 static int builtin_unset(struct child_prog *child)
439 if (child->argv[1] == NULL) {
440 printf(bb_msg_requires_arg, "unset");
443 unsetenv(child->argv[1]);
447 #if ENABLE_LASH_JOB_CONTROL
448 /* free up all memory from a job */
449 static void free_job(struct job *cmd)
454 for (i = 0; i < cmd->num_progs; i++) {
455 free(cmd->progs[i].argv);
456 #if ENABLE_LASH_PIPE_N_REDIRECTS
457 if (cmd->progs[i].redirects)
458 free(cmd->progs[i].redirects);
464 keep = cmd->job_list;
465 memset(cmd, 0, sizeof(struct job));
466 cmd->job_list = keep;
469 /* remove a job from a jobset */
470 static void remove_job(struct jobset *j_list, struct job *job)
475 if (job == j_list->head) {
476 j_list->head = job->next;
478 prevjob = j_list->head;
479 while (prevjob->next != job)
480 prevjob = prevjob->next;
481 prevjob->next = job->next;
485 last_jobid = j_list->head->jobid;
492 /* Checks to see if any background processes have exited -- if they
493 have, figure out why and see if a job has completed */
494 static void checkjobs(struct jobset *j_list)
501 while ((childpid = waitpid(-1, &status, WNOHANG | WUNTRACED)) > 0) {
502 for (job = j_list->head; job; job = job->next) {
504 while (prognum < job->num_progs &&
505 job->progs[prognum].pid != childpid) prognum++;
506 if (prognum < job->num_progs)
510 /* This happens on backticked commands */
514 if (WIFEXITED(status) || WIFSIGNALED(status)) {
516 job->running_progs--;
517 job->progs[prognum].pid = 0;
519 if (!job->running_progs) {
520 printf(JOB_STATUS_FORMAT, job->jobid, "Done", job->text);
522 remove_job(j_list, job);
526 job->stopped_progs++;
527 job->progs[prognum].is_stopped = 1;
531 if (childpid == -1 && errno != ECHILD)
532 bb_perror_msg("waitpid");
535 static void checkjobs(struct jobset *j_list)
538 static void free_job(struct job *cmd)
541 static void remove_job(struct jobset *j_list, struct job *job)
546 #if ENABLE_LASH_PIPE_N_REDIRECTS
547 /* squirrel != NULL means we squirrel away copies of stdin, stdout,
548 * and stderr if they are redirected. */
549 static int setup_redirects(struct child_prog *prog, int squirrel[])
554 struct redir_struct *redir = prog->redirects;
556 for (i = 0; i < prog->num_redirects; i++, redir++) {
557 switch (redir->type) {
561 case REDIRECT_OVERWRITE:
562 mode = O_WRONLY | O_CREAT | O_TRUNC;
564 case REDIRECT_APPEND:
565 mode = O_WRONLY | O_CREAT | O_APPEND;
569 openfd = open3_or_warn(redir->filename, mode, 0666);
571 /* this could get lost if stderr has been redirected, but
572 bash and ash both lose it as well (though zsh doesn't!) */
576 if (openfd != redir->fd) {
577 if (squirrel && redir->fd < 3) {
578 squirrel[redir->fd] = dup(redir->fd);
579 fcntl(squirrel[redir->fd], F_SETFD, FD_CLOEXEC);
581 dup2(openfd, redir->fd);
589 static void restore_redirects(int squirrel[])
592 for (i = 0; i < 3; i++) {
595 /* No error checking. I sure wouldn't know what
596 * to do with an error if I found one! */
603 static inline int setup_redirects(struct child_prog *prog, int squirrel[])
607 static inline void restore_redirects(int squirrel[])
612 static inline void cmdedit_set_initial_prompt(void)
614 #if !ENABLE_FEATURE_EDITING_FANCY_PROMPT
623 static inline const char* setup_prompt_string(void)
625 #if !ENABLE_FEATURE_EDITING_FANCY_PROMPT
626 /* Set up the prompt */
627 if (shell_context == 0) {
630 ns = xmalloc(strlen(cwd)+4);
631 sprintf(ns, "%s %c ", cwd, (geteuid() != 0) ? '$': '#');
638 return (shell_context == 0)? PS1 : PS2;
642 #if ENABLE_FEATURE_EDITING
643 static line_input_t *line_input_state;
646 static int get_command_bufsiz(FILE * source, char *command)
648 const char *prompt_str;
650 if (source == NULL) {
651 if (local_pending_command) {
652 /* a command specified (-c option): return it & mark it done */
653 strncpy(command, local_pending_command, BUFSIZ);
654 local_pending_command = NULL;
660 if (source == stdin) {
661 prompt_str = setup_prompt_string();
663 #if ENABLE_FEATURE_EDITING
665 ** enable command line editing only while a command line
666 ** is actually being read; otherwise, we'll end up bequeathing
667 ** atexit() handlers and other unwanted stuff to our
668 ** child processes (rob@sysgo.de)
670 read_line_input(prompt_str, command, BUFSIZ, line_input_state);
673 fputs(prompt_str, stdout);
677 if (!fgets(command, BUFSIZ - 2, source)) {
686 static char * strsep_space(char *string, int * ix)
688 /* Short circuit the trivial case */
689 if (!string || ! string[*ix])
692 /* Find the end of the token. */
693 while (string[*ix] && !isspace(string[*ix]) ) {
697 /* Find the end of any whitespace trailing behind
698 * the token and let that be part of the token */
699 while (string[*ix] && (isspace)(string[*ix]) ) {
704 /* Nothing useful was found */
708 return xstrndup(string, *ix);
711 static int expand_arguments(char *command)
713 static const char out_of_space[] = "out of space during expansion";
715 int total_length = 0, length, i, retval, ix = 0;
716 expand_t expand_result;
717 char *tmpcmd, *cmd, *cmd_copy;
718 char *src, *dst, *var;
719 int flags = GLOB_NOCHECK
728 /* get rid of the terminating \n */
731 /* Fix up escape sequences to be the Real Thing(tm) */
732 while (command && command[ix]) {
733 if (command[ix] == '\\') {
734 const char *tmp = command+ix+1;
735 command[ix] = bb_process_escape_sequence( &tmp );
736 memmove(command+ix + 1, tmp, strlen(tmp)+1);
740 /* Use glob and then fixup environment variables and such */
742 /* It turns out that glob is very stupid. We have to feed it one word at a
743 * time since it can't cope with a full string. Here we convert command
744 * (char*) into cmd (char**, one word per string) */
746 /* We need a clean copy, so strsep can mess up the copy while
747 * we write stuff into the original (in a minute) */
748 cmd = cmd_copy = xstrdup(command);
750 for (ix = 0, tmpcmd = cmd;
751 (tmpcmd = strsep_space(cmd, &ix)) != NULL; cmd += ix, ix = 0) {
754 /* we need to trim() the result for glob! */
756 retval = glob(tmpcmd, flags, NULL, &expand_result);
757 free(tmpcmd); /* Free mem allocated by strsep_space */
758 if (retval == GLOB_NOSPACE) {
759 /* Mem may have been allocated... */
760 globfree(&expand_result);
761 bb_error_msg(out_of_space);
763 } else if (retval != 0) {
764 /* Some other error. GLOB_NOMATCH shouldn't
765 * happen because of the GLOB_NOCHECK flag in
767 bb_error_msg("syntax error");
770 /* Convert from char** (one word per string) to a simple char*,
771 * but don't overflow command which is BUFSIZ in length */
772 for (i = 0; i < expand_result.gl_pathc; i++) {
773 length = strlen(expand_result.gl_pathv[i]);
774 if (total_length+length+1 >= BUFSIZ) {
775 bb_error_msg(out_of_space);
778 strcat(command+total_length, " ");
780 strcat(command+total_length, expand_result.gl_pathv[i]);
781 total_length += length;
783 globfree(&expand_result);
789 /* Now do the shell variable substitutions which
790 * wordexp can't do for us, namely $? and $! */
792 while ((dst = strchr(src,'$')) != NULL) {
796 var = itoa(last_return_code);
799 if (last_bg_pid == -1)
802 var = itoa(last_bg_pid);
804 /* Everything else like $$, $#, $[0-9], etc. should all be
805 * expanded by wordexp(), so we can in theory skip that stuff
806 * here, but just to be on the safe side (i.e., since uClibc
807 * wordexp doesn't do this stuff yet), lets leave it in for
810 var = itoa(getpid());
815 case '0':case '1':case '2':case '3':case '4':
816 case '5':case '6':case '7':case '8':case '9':
818 int ixx = *(dst+1)-48+1;
829 /* a single character construction was found, and
830 * already handled in the case statement */
833 /* Looks like an environment variable */
835 int num_skip_chars = 0;
836 int dstlen = strlen(dst);
837 /* Is this a ${foo} type variable? */
838 if (dstlen >= 2 && *(dst+1) == '{') {
839 src = strchr(dst+1, '}');
843 while ((isalnum)(*src) || *src == '_') src++;
849 *src = '\0'; /* temporary */
850 var = getenv(dst + 1 + num_skip_chars);
852 src += num_skip_chars;
855 /* Seems we got an un-expandable variable. So delete it. */
859 int subst_len = strlen(var);
860 int trail_len = strlen(src);
861 if (dst+subst_len+trail_len >= command+BUFSIZ) {
862 bb_error_msg(out_of_space);
865 /* Move stuff to the end of the string to accommodate
866 * filling the created gap with the new stuff */
867 memmove(dst+subst_len, src, trail_len+1);
868 /* Now copy in the new stuff */
869 memcpy(dst, var, subst_len);
877 /* Return cmd->num_progs as 0 if no command is present (e.g. an empty
878 line). If a valid command is found, command_ptr is set to point to
879 the beginning of the next command (if the original command had more
880 then one job associated with it) or NULL if no more commands are
882 static int parse_command(char **command_ptr, struct job *job, int *inbg)
885 char *return_command = NULL;
891 struct child_prog *prog;
892 #if ENABLE_LASH_PIPE_N_REDIRECTS
897 /* skip leading white space */
898 *command_ptr = skip_whitespace(*command_ptr);
900 /* this handles empty lines or leading '#' characters */
901 if (!**command_ptr || (**command_ptr == '#')) {
908 job->progs = xmalloc(sizeof(*job->progs));
910 /* We set the argv elements to point inside of this string. The
911 memory is freed by free_job(). Allocate twice the original
912 length in case we need to quote every single character.
914 Getting clean memory relieves us of the task of NULL
915 terminating things and makes the rest of this look a bit
916 cleaner (though it is, admittedly, a tad less efficient) */
917 job->cmdbuf = command = xzalloc(2*strlen(*command_ptr) + 1);
921 prog->num_redirects = 0;
922 prog->is_stopped = 0;
924 #if ENABLE_LASH_PIPE_N_REDIRECTS
925 prog->redirects = NULL;
929 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
930 prog->argv[0] = job->cmdbuf;
935 while (*src && !(flag & LASH_OPT_DONE)) {
942 bb_error_msg("character expected after \\");
947 /* in shell, "\'" should yield \' */
952 } else if (*src == '*' || *src == '?' || *src == '[' ||
953 *src == ']') *buf++ = '\\';
955 } else if (isspace(*src)) {
956 if (*prog->argv[argc_l] || (flag & LASH_OPT_SAW_QUOTE)) {
958 /* +1 here leaves room for the NULL which ends argv */
959 if ((argc_l + 1) == argv_alloced) {
961 prog->argv = xrealloc(prog->argv,
962 sizeof(*prog->argv) * argv_alloced);
964 prog->argv[argc_l] = buf;
965 flag ^= LASH_OPT_SAW_QUOTE;
972 flag |= LASH_OPT_SAW_QUOTE;
975 case '#': /* comment */
979 flag |= LASH_OPT_DONE;
982 #if ENABLE_LASH_PIPE_N_REDIRECTS
983 case '>': /* redirects */
985 i = prog->num_redirects++;
986 prog->redirects = xrealloc(prog->redirects,
987 sizeof(*prog->redirects) * (i + 1));
989 prog->redirects[i].fd = -1;
990 if (buf != prog->argv[argc_l]) {
991 /* the stuff before this character may be the file number
993 prog->redirects[i].fd =
994 strtol(prog->argv[argc_l], &chptr, 10);
996 if (*chptr && *prog->argv[argc_l]) {
998 prog->argv[argc_l] = buf;
1002 if (prog->redirects[i].fd == -1) {
1004 prog->redirects[i].fd = 1;
1006 prog->redirects[i].fd = 0;
1009 if (*src++ == '>') {
1011 prog->redirects[i].type =
1012 REDIRECT_APPEND, src++;
1014 prog->redirects[i].type = REDIRECT_OVERWRITE;
1016 prog->redirects[i].type = REDIRECT_INPUT;
1019 /* This isn't POSIX sh compliant. Oh well. */
1021 chptr = skip_whitespace(chptr);
1024 bb_error_msg("file name expected after %c", *(src-1));
1030 prog->redirects[i].filename = buf;
1031 while (*chptr && !isspace(*chptr))
1034 src = chptr - 1; /* we src++ later */
1035 prog->argv[argc_l] = ++buf;
1038 case '|': /* pipe */
1039 /* finish this command */
1040 if (*prog->argv[argc_l] || flag & LASH_OPT_SAW_QUOTE)
1043 goto empty_command_in_pipe;
1045 prog->argv[argc_l] = NULL;
1047 /* and start the next */
1049 job->progs = xrealloc(job->progs,
1050 sizeof(*job->progs) * job->num_progs);
1051 prog = job->progs + (job->num_progs - 1);
1052 prog->num_redirects = 0;
1053 prog->redirects = NULL;
1054 prog->is_stopped = 0;
1059 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1060 prog->argv[0] = ++buf;
1063 src = skip_whitespace(src);
1066 empty_command_in_pipe:
1067 bb_error_msg("empty command in pipe");
1072 src--; /* we'll ++ it at the end of the loop */
1077 #if ENABLE_LASH_JOB_CONTROL
1078 case '&': /* background */
1082 case ';': /* multiple commands */
1083 flag |= LASH_OPT_DONE;
1084 return_command = *command_ptr + (src - *command_ptr) + 1;
1090 bb_error_msg("character expected after \\");
1094 if (*src == '*' || *src == '[' || *src == ']'
1095 || *src == '?') *buf++ = '\\';
1104 if (*prog->argv[argc_l] || flag & LASH_OPT_SAW_QUOTE) {
1111 prog->argv[argc_l] = NULL;
1113 if (!return_command) {
1114 job->text = xstrdup(*command_ptr);
1116 /* This leaves any trailing spaces, which is a bit sloppy */
1117 job->text = xstrndup(*command_ptr, return_command - *command_ptr);
1120 *command_ptr = return_command;
1125 /* Run the child_prog, no matter what kind of command it uses.
1127 static int pseudo_exec(struct child_prog *child)
1129 const struct built_in_command *x;
1131 /* Check if the command matches any of the non-forking builtins.
1132 * Depending on context, this might be redundant. But it's
1133 * easier to waste a few CPU cycles than it is to figure out
1134 * if this is one of those cases.
1136 /* Check if the command matches any of the forking builtins. */
1137 for (x = bltins; x <= &VEC_LAST(bltins); x++) {
1138 if (strcmp(child->argv[0], x->cmd) == 0) {
1139 _exit(x->function(child));
1144 /* Check if the command matches any busybox internal
1145 * commands ("applets") here. Following discussions from
1146 * November 2000 on busybox@busybox.net, don't use
1147 * bb_get_last_path_component(). This way explicit (with
1148 * slashes) filenames will never be interpreted as an
1149 * applet, just like with builtins. This way the user can
1150 * override an applet with an explicit filename reference.
1151 * The only downside to this change is that an explicit
1152 * /bin/foo invocation will fork and exec /bin/foo, even if
1153 * /bin/foo is a symlink to busybox.
1155 if (ENABLE_FEATURE_SH_STANDALONE) {
1156 run_applet_and_exit(child->argv[0], child->argv);
1159 execvp(child->argv[0], child->argv);
1161 /* Do not use bb_perror_msg_and_die() here, since we must not
1162 * call exit() but should call _exit() instead */
1163 bb_perror_msg("%s", child->argv[0]);
1164 _exit(EXIT_FAILURE);
1167 static void insert_job(struct job *newjob, int inbg)
1170 struct jobset *j_list = newjob->job_list;
1172 /* find the ID for thejob to use */
1174 for (thejob = j_list->head; thejob; thejob = thejob->next)
1175 if (thejob->jobid >= newjob->jobid)
1176 newjob->jobid = thejob->jobid + 1;
1178 /* add thejob to the list of running jobs */
1179 if (!j_list->head) {
1180 thejob = j_list->head = xmalloc(sizeof(*thejob));
1182 for (thejob = j_list->head; thejob->next; thejob = thejob->next) /* nothing */;
1183 thejob->next = xmalloc(sizeof(*thejob));
1184 thejob = thejob->next;
1187 *thejob = *newjob; /* physically copy the struct job */
1188 thejob->next = NULL;
1189 thejob->running_progs = thejob->num_progs;
1190 thejob->stopped_progs = 0;
1192 #if ENABLE_LASH_JOB_CONTROL
1194 /* we don't wait for background thejobs to return -- append it
1195 to the list of backgrounded thejobs and leave it alone */
1196 printf("[%d] %d\n", thejob->jobid,
1197 newjob->progs[newjob->num_progs - 1].pid);
1198 last_jobid = newjob->jobid;
1199 last_bg_pid = newjob->progs[newjob->num_progs - 1].pid;
1201 newjob->job_list->fg = thejob;
1203 /* move the new process group into the foreground */
1204 /* Ignore errors since child could have already exited */
1205 tcsetpgrp(shell_terminal, newjob->pgrp);
1210 static int run_command(struct job *newjob, int inbg, int outpipe[2])
1212 /* struct job *thejob; */
1214 int nextin, nextout;
1215 int pipefds[2]; /* pipefd[0] is for reading */
1216 const struct built_in_command *x;
1217 struct child_prog *child;
1220 for (i = 0; i < newjob->num_progs; i++) {
1221 child = &(newjob->progs[i]);
1224 if ((i + 1) < newjob->num_progs) {
1225 if (pipe(pipefds) < 0)
1226 bb_perror_msg_and_die("pipe");
1227 nextout = pipefds[1];
1228 } else if (outpipe[1] != -1) {
1229 nextout = outpipe[1];
1232 /* Check if the command matches any non-forking builtins,
1233 * but only if this is a simple command.
1234 * Non-forking builtins within pipes have to fork anyway,
1235 * and are handled in pseudo_exec. "echo foo | read bar"
1236 * is doomed to failure, and doesn't work on bash, either.
1238 if (newjob->num_progs == 1) {
1240 int squirrel[] = {-1, -1, -1};
1242 /* Check if the command sets an environment variable. */
1243 if (strchr(child->argv[0], '=') != NULL) {
1244 child->argv[1] = child->argv[0];
1245 return builtin_export(child);
1248 for (x = bltins; x <= &VEC_LAST(bltins); x++) {
1249 if (strcmp(child->argv[0], x->cmd) == 0) {
1250 setup_redirects(child, squirrel);
1251 rcode = x->function(child);
1252 restore_redirects(squirrel);
1256 #if ENABLE_FEATURE_SH_STANDALONE
1258 const struct bb_applet *a = find_applet_by_name(child->argv[i]);
1259 if (a && a->nofork) {
1260 setup_redirects(child, squirrel);
1261 rcode = run_nofork_applet(a, child->argv + i);
1262 restore_redirects(squirrel);
1270 child->pid = fork();
1272 child->pid = vfork();
1275 /* Set the handling for job control signals back to the default. */
1276 signal(SIGINT, SIG_DFL);
1277 signal(SIGQUIT, SIG_DFL);
1278 signal(SIGTSTP, SIG_DFL);
1279 signal(SIGTTIN, SIG_DFL);
1280 signal(SIGTTOU, SIG_DFL);
1281 signal(SIGCHLD, SIG_DFL);
1283 /* Close all open filehandles. */
1284 while (close_me_list)
1285 close((long)llist_pop(&close_me_list));
1287 if (outpipe[1] != -1) {
1297 dup2(nextout, 2); /* Really? */
1302 /* explicit redirects override pipes */
1303 setup_redirects(child,NULL);
1307 if (outpipe[1] != -1) {
1311 /* put our child in the process group whose leader is the
1312 first process in this pipe */
1313 setpgid(child->pid, newjob->progs[0].pid);
1319 /* If there isn't another process, nextin is garbage
1320 but it doesn't matter */
1321 nextin = pipefds[0];
1324 newjob->pgrp = newjob->progs[0].pid;
1326 insert_job(newjob, inbg);
1331 static int busy_loop(FILE * input)
1334 char *next_command = NULL;
1339 #if ENABLE_LASH_JOB_CONTROL
1341 /* save current owner of TTY so we can restore it on exit */
1342 parent_pgrp = tcgetpgrp(shell_terminal);
1344 newjob.job_list = &job_list;
1345 newjob.job_context = DEFAULT_CONTEXT;
1347 command = xzalloc(BUFSIZ);
1351 /* no job is in the foreground */
1353 /* see if any background processes have exited */
1354 checkjobs(&job_list);
1356 if (!next_command) {
1357 if (get_command_bufsiz(input, command))
1359 next_command = command;
1362 if (!expand_arguments(next_command)) {
1364 command = xzalloc(BUFSIZ);
1365 next_command = NULL;
1369 if (!parse_command(&next_command, &newjob, &inbg) &&
1371 int pipefds[2] = { -1, -1 };
1372 debug_printf("job=%p fed to run_command by busy_loop()'\n",
1374 run_command(&newjob, inbg, pipefds);
1378 command = xzalloc(BUFSIZ);
1379 next_command = NULL;
1382 /* a job is running in the foreground; wait for it */
1384 while (!job_list.fg->progs[i].pid ||
1385 job_list.fg->progs[i].is_stopped == 1) i++;
1387 if (waitpid(job_list.fg->progs[i].pid, &status, WUNTRACED) < 0) {
1388 if (errno != ECHILD) {
1389 bb_perror_msg_and_die("waitpid(%d)", job_list.fg->progs[i].pid);
1393 if (WIFEXITED(status) || WIFSIGNALED(status)) {
1394 /* the child exited */
1395 job_list.fg->running_progs--;
1396 job_list.fg->progs[i].pid = 0;
1398 last_return_code = WEXITSTATUS(status);
1400 if (!job_list.fg->running_progs) {
1402 remove_job(&job_list, job_list.fg);
1406 #if ENABLE_LASH_JOB_CONTROL
1408 /* the child was stopped */
1409 job_list.fg->stopped_progs++;
1410 job_list.fg->progs[i].is_stopped = 1;
1412 if (job_list.fg->stopped_progs == job_list.fg->running_progs) {
1413 printf("\n" JOB_STATUS_FORMAT, job_list.fg->jobid,
1414 "Stopped", job_list.fg->text);
1420 /* move the shell to the foreground */
1421 /* suppress messages when run from /linuxrc mag@sysgo.de */
1422 if (tcsetpgrp(shell_terminal, getpgrp()) && errno != ENOTTY)
1423 bb_perror_msg("tcsetpgrp");
1430 #if ENABLE_LASH_JOB_CONTROL
1431 /* return controlling TTY back to parent process group before exiting */
1432 if (tcsetpgrp(shell_terminal, parent_pgrp) && errno != ENOTTY)
1433 bb_perror_msg("tcsetpgrp");
1436 /* return exit status if called with "-c" */
1437 if (input == NULL && WIFEXITED(status))
1438 return WEXITSTATUS(status);
1443 #if ENABLE_FEATURE_CLEAN_UP
1444 static void free_memory(void)
1448 if (job_list.fg && !job_list.fg->running_progs) {
1449 remove_job(&job_list, job_list.fg);
1453 void free_memory(void);
1456 #if ENABLE_LASH_JOB_CONTROL
1457 /* Make sure we have a controlling tty. If we get started under a job
1458 * aware app (like bash for example), make sure we are now in charge so
1459 * we don't fight over who gets the foreground */
1460 static void setup_job_control(void)
1465 /* Loop until we are in the foreground. */
1466 while ((status = tcgetpgrp(shell_terminal)) >= 0) {
1467 shell_pgrp = getpgrp();
1468 if (status == shell_pgrp) {
1471 kill(- shell_pgrp, SIGTTIN);
1474 /* Ignore interactive and job-control signals. */
1475 signal(SIGINT, SIG_IGN);
1476 signal(SIGQUIT, SIG_IGN);
1477 signal(SIGTSTP, SIG_IGN);
1478 signal(SIGTTIN, SIG_IGN);
1479 signal(SIGTTOU, SIG_IGN);
1480 signal(SIGCHLD, SIG_IGN);
1482 /* Put ourselves in our own process group. */
1484 shell_pgrp = getpid();
1485 setpgid(shell_pgrp, shell_pgrp);
1487 /* Grab control of the terminal. */
1488 tcsetpgrp(shell_terminal, shell_pgrp);
1491 static inline void setup_job_control(void)
1496 int lash_main(int argc_l, char **argv_l);
1497 int lash_main(int argc_l, char **argv_l)
1500 FILE *input = stdin;
1504 #if ENABLE_FEATURE_EDITING
1505 line_input_state = new_line_input_t(FOR_SHELL);
1508 /* These variables need re-initializing when recursing */
1510 close_me_list = NULL;
1511 job_list.head = NULL;
1513 last_return_code = 1;
1515 if (argv[0] && argv[0][0] == '-') {
1517 prof_input = fopen("/etc/profile", "r");
1519 llist_add_to(&close_me_list, (void *)(long)fileno(prof_input));
1520 /* Now run the file */
1521 busy_loop(prof_input);
1522 fclose_if_not_stdin(prof_input);
1523 llist_pop(&close_me_list);
1527 opt = getopt32(argc_l, argv_l, "+ic:", &local_pending_command);
1528 #define LASH_OPT_i (1<<0)
1529 #define LASH_OPT_c (1<<1)
1530 if (opt & LASH_OPT_c) {
1535 /* A shell is interactive if the `-i' flag was given, or if all of
1536 * the following conditions are met:
1538 * no arguments remaining or the -s flag given
1539 * standard input is a terminal
1540 * standard output is a terminal
1541 * Refer to Posix.2, the description of the `sh' utility. */
1542 if (argv[optind] == NULL && input == stdin
1543 && isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)
1547 setup_job_control();
1548 if (opt & LASH_OPT_i) {
1549 /* Looks like they want an interactive shell */
1550 if (!ENABLE_FEATURE_SH_EXTRA_QUIET) {
1551 printf("\n\n%s Built-in shell (lash)\n"
1552 "Enter 'help' for a list of built-in commands.\n\n",
1555 } else if (!local_pending_command && argv[optind]) {
1556 //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
1557 input = xfopen(argv[optind], "r");
1558 /* be lazy, never mark this closed */
1559 llist_add_to(&close_me_list, (void *)(long)fileno(input));
1562 /* initialize the cwd -- this is never freed...*/
1565 if (ENABLE_FEATURE_CLEAN_UP) atexit(free_memory);
1567 if (ENABLE_FEATURE_EDITING) cmdedit_set_initial_prompt();
1570 return busy_loop(input);