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) ATTRIBUTE_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 ATTRIBUTE_UNUSED *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 ATTRIBUTE_UNUSED *dummy)
313 const struct built_in_command *x;
315 printf("\nBuilt-in commands:\n"
316 "-------------------\n");
317 for (x = bltins; x <= &VEC_LAST(bltins); x++) {
318 if (x->descr == NULL)
320 printf("%s\t%s\n", x->cmd, x->descr);
326 /* built-in 'jobs' handler */
327 static int builtin_jobs(struct child_prog *child)
330 const char *status_string;
332 for (job = child->family->job_list->head; job; job = job->next) {
333 if (job->running_progs == job->stopped_progs)
334 status_string = "Stopped";
336 status_string = "Running";
338 printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->text);
344 /* built-in 'pwd' handler */
345 static int builtin_pwd(struct child_prog ATTRIBUTE_UNUSED *dummy)
352 /* built-in 'export VAR=value' handler */
353 static int builtin_export(struct child_prog *child)
356 char *v = child->argv[1];
360 for (e = environ; *e; e++) {
367 bb_perror_msg("export");
368 #if ENABLE_FEATURE_EDITING_FANCY_PROMPT
369 if (strncmp(v, "PS1=", 4) == 0)
373 #if ENABLE_LOCALE_SUPPORT
374 // TODO: why getenv? "" would be just as good...
375 if (strncmp(v, "LC_ALL=", 7) == 0)
376 setlocale(LC_ALL, getenv("LC_ALL"));
377 if (strncmp(v, "LC_CTYPE=", 9) == 0)
378 setlocale(LC_CTYPE, getenv("LC_CTYPE"));
384 /* built-in 'read VAR' handler */
385 static int builtin_read(struct child_prog *child)
389 char string[MAX_READ];
391 if (child->argv[1]) {
392 /* argument (VAR) given: put "VAR=" into buffer */
393 safe_strncpy(string, child->argv[1], MAX_READ-1);
394 len = strlen(string);
397 fgets(&string[len], sizeof(string) - len, stdin); /* read string */
398 res = strlen(string);
400 string[--res] = '\0'; /* chomp trailing newline */
402 ** string should now contain "VAR=<value>"
403 ** copy it (putenv() won't do that, so we must make sure
404 ** the string resides in a static buffer!)
411 bb_perror_msg("read");
413 fgets(string, sizeof(string), stdin);
418 /* Built-in '.' handler (read-in and execute commands from file) */
419 static int builtin_source(struct child_prog *child)
424 input = fopen_or_warn(child->argv[1], "r");
429 llist_add_to(&close_me_list, (void *)(long)fileno(input));
430 /* Now run the file */
431 status = busy_loop(input);
433 llist_pop(&close_me_list);
437 /* built-in 'unset VAR' handler */
438 static int builtin_unset(struct child_prog *child)
440 if (child->argv[1] == NULL) {
441 printf(bb_msg_requires_arg, "unset");
444 unsetenv(child->argv[1]);
448 #if ENABLE_LASH_JOB_CONTROL
449 /* free up all memory from a job */
450 static void free_job(struct job *cmd)
455 for (i = 0; i < cmd->num_progs; i++) {
456 free(cmd->progs[i].argv);
457 #if ENABLE_LASH_PIPE_N_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 = open_or_warn(redir->filename, mode);
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 close_on_exec_on(squirrel[redir->fd]);
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[] ALIGN1 = "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());
813 var = itoa(global_argc - 1);
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;
819 if (ixx >= global_argc) {
822 var = global_argv[ixx];
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));
1143 /* Check if the command matches any busybox internal
1144 * commands ("applets") here. Following discussions from
1145 * November 2000 on busybox@busybox.net, don't use
1146 * bb_get_last_path_component_nostrip(). This way explicit
1147 * (with slashes) filenames will never be interpreted as an
1148 * applet, just like with builtins. This way the user can
1149 * override an applet with an explicit filename reference.
1150 * The only downside to this change is that an explicit
1151 * /bin/foo invocation will fork and exec /bin/foo, even if
1152 * /bin/foo is a symlink to busybox.
1154 if (ENABLE_FEATURE_SH_STANDALONE) {
1155 run_applet_and_exit(child->argv[0], child->argv);
1158 execvp(child->argv[0], child->argv);
1160 /* Do not use bb_perror_msg_and_die() here, since we must not
1161 * call exit() but should call _exit() instead */
1162 bb_simple_perror_msg(child->argv[0]);
1163 _exit(EXIT_FAILURE);
1166 static void insert_job(struct job *newjob, int inbg)
1169 struct jobset *j_list = newjob->job_list;
1171 /* find the ID for thejob to use */
1173 for (thejob = j_list->head; thejob; thejob = thejob->next)
1174 if (thejob->jobid >= newjob->jobid)
1175 newjob->jobid = thejob->jobid + 1;
1177 /* add thejob to the list of running jobs */
1178 if (!j_list->head) {
1179 thejob = j_list->head = xmalloc(sizeof(*thejob));
1181 for (thejob = j_list->head; thejob->next; thejob = thejob->next) /* nothing */;
1182 thejob->next = xmalloc(sizeof(*thejob));
1183 thejob = thejob->next;
1186 *thejob = *newjob; /* physically copy the struct job */
1187 thejob->next = NULL;
1188 thejob->running_progs = thejob->num_progs;
1189 thejob->stopped_progs = 0;
1191 #if ENABLE_LASH_JOB_CONTROL
1193 /* we don't wait for background thejobs to return -- append it
1194 to the list of backgrounded thejobs and leave it alone */
1195 printf("[%d] %d\n", thejob->jobid,
1196 newjob->progs[newjob->num_progs - 1].pid);
1197 last_jobid = newjob->jobid;
1198 last_bg_pid = newjob->progs[newjob->num_progs - 1].pid;
1200 newjob->job_list->fg = thejob;
1202 /* move the new process group into the foreground */
1203 /* Ignore errors since child could have already exited */
1204 tcsetpgrp(shell_terminal, newjob->pgrp);
1209 static int run_command(struct job *newjob, int inbg, int outpipe[2])
1211 /* struct job *thejob; */
1213 int nextin, nextout;
1214 int pipefds[2]; /* pipefd[0] is for reading */
1215 const struct built_in_command *x;
1216 struct child_prog *child;
1219 for (i = 0; i < newjob->num_progs; i++) {
1220 child = &(newjob->progs[i]);
1223 if ((i + 1) < newjob->num_progs) {
1225 nextout = pipefds[1];
1226 } else if (outpipe[1] != -1) {
1227 nextout = outpipe[1];
1230 /* Check if the command matches any non-forking builtins,
1231 * but only if this is a simple command.
1232 * Non-forking builtins within pipes have to fork anyway,
1233 * and are handled in pseudo_exec. "echo foo | read bar"
1234 * is doomed to failure, and doesn't work on bash, either.
1236 if (newjob->num_progs == 1) {
1238 int squirrel[] = {-1, -1, -1};
1240 /* Check if the command sets an environment variable. */
1241 if (strchr(child->argv[0], '=') != NULL) {
1242 child->argv[1] = child->argv[0];
1243 return builtin_export(child);
1246 for (x = bltins; x <= &VEC_LAST(bltins); x++) {
1247 if (strcmp(child->argv[0], x->cmd) == 0) {
1248 setup_redirects(child, squirrel);
1249 rcode = x->function(child);
1250 restore_redirects(squirrel);
1254 #if ENABLE_FEATURE_SH_STANDALONE
1256 int a = find_applet_by_name(child->argv[i]);
1257 if (a >= 0 && APPLET_IS_NOFORK(a)) {
1258 setup_redirects(child, squirrel);
1259 rcode = run_nofork_applet(a, child->argv + i);
1260 restore_redirects(squirrel);
1268 child->pid = fork();
1270 child->pid = vfork();
1273 /* Set the handling for job control signals back to the default. */
1274 signal(SIGINT, SIG_DFL);
1275 signal(SIGQUIT, SIG_DFL);
1276 signal(SIGTSTP, SIG_DFL);
1277 signal(SIGTTIN, SIG_DFL);
1278 signal(SIGTTOU, SIG_DFL);
1279 signal(SIGCHLD, SIG_DFL);
1281 /* Close all open filehandles. */
1282 while (close_me_list)
1283 close((long)llist_pop(&close_me_list));
1285 if (outpipe[1] != -1) {
1295 dup2(nextout, 2); /* Really? */
1300 /* explicit redirects override pipes */
1301 setup_redirects(child,NULL);
1305 if (outpipe[1] != -1) {
1309 /* put our child in the process group whose leader is the
1310 first process in this pipe */
1311 setpgid(child->pid, newjob->progs[0].pid);
1317 /* If there isn't another process, nextin is garbage
1318 but it doesn't matter */
1319 nextin = pipefds[0];
1322 newjob->pgrp = newjob->progs[0].pid;
1324 insert_job(newjob, inbg);
1329 static int busy_loop(FILE * input)
1332 char *next_command = NULL;
1337 #if ENABLE_LASH_JOB_CONTROL
1339 /* save current owner of TTY so we can restore it on exit */
1340 parent_pgrp = tcgetpgrp(shell_terminal);
1342 newjob.job_list = &job_list;
1343 newjob.job_context = DEFAULT_CONTEXT;
1345 command = xzalloc(BUFSIZ);
1349 /* no job is in the foreground */
1351 /* see if any background processes have exited */
1352 checkjobs(&job_list);
1354 if (!next_command) {
1355 if (get_command_bufsiz(input, command))
1357 next_command = command;
1360 if (!expand_arguments(next_command)) {
1362 command = xzalloc(BUFSIZ);
1363 next_command = NULL;
1367 if (!parse_command(&next_command, &newjob, &inbg) &&
1369 int pipefds[2] = { -1, -1 };
1370 debug_printf("job=%p fed to run_command by busy_loop()'\n",
1372 run_command(&newjob, inbg, pipefds);
1376 command = xzalloc(BUFSIZ);
1377 next_command = NULL;
1380 /* a job is running in the foreground; wait for it */
1382 while (!job_list.fg->progs[i].pid ||
1383 job_list.fg->progs[i].is_stopped == 1) i++;
1385 if (waitpid(job_list.fg->progs[i].pid, &status, WUNTRACED) < 0) {
1386 if (errno != ECHILD) {
1387 bb_perror_msg_and_die("waitpid(%d)", job_list.fg->progs[i].pid);
1391 if (WIFEXITED(status) || WIFSIGNALED(status)) {
1392 /* the child exited */
1393 job_list.fg->running_progs--;
1394 job_list.fg->progs[i].pid = 0;
1396 last_return_code = WEXITSTATUS(status);
1398 if (!job_list.fg->running_progs) {
1400 remove_job(&job_list, job_list.fg);
1404 #if ENABLE_LASH_JOB_CONTROL
1406 /* the child was stopped */
1407 job_list.fg->stopped_progs++;
1408 job_list.fg->progs[i].is_stopped = 1;
1410 if (job_list.fg->stopped_progs == job_list.fg->running_progs) {
1411 printf("\n" JOB_STATUS_FORMAT, job_list.fg->jobid,
1412 "Stopped", job_list.fg->text);
1418 /* move the shell to the foreground */
1419 /* suppress messages when run from /linuxrc mag@sysgo.de */
1420 if (tcsetpgrp(shell_terminal, getpgrp()) && errno != ENOTTY)
1421 bb_perror_msg("tcsetpgrp");
1428 #if ENABLE_LASH_JOB_CONTROL
1429 /* return controlling TTY back to parent process group before exiting */
1430 if (tcsetpgrp(shell_terminal, parent_pgrp) && errno != ENOTTY)
1431 bb_perror_msg("tcsetpgrp");
1434 /* return exit status if called with "-c" */
1435 if (input == NULL && WIFEXITED(status))
1436 return WEXITSTATUS(status);
1441 #if ENABLE_FEATURE_CLEAN_UP
1442 static void free_memory(void)
1446 if (job_list.fg && !job_list.fg->running_progs) {
1447 remove_job(&job_list, job_list.fg);
1451 void free_memory(void);
1454 #if ENABLE_LASH_JOB_CONTROL
1455 /* Make sure we have a controlling tty. If we get started under a job
1456 * aware app (like bash for example), make sure we are now in charge so
1457 * we don't fight over who gets the foreground */
1458 static void setup_job_control(void)
1463 /* Loop until we are in the foreground. */
1464 while ((status = tcgetpgrp(shell_terminal)) >= 0) {
1465 shell_pgrp = getpgrp();
1466 if (status == shell_pgrp) {
1469 kill(- shell_pgrp, SIGTTIN);
1472 /* Ignore interactive and job-control signals. */
1473 signal(SIGINT, SIG_IGN);
1474 signal(SIGQUIT, SIG_IGN);
1475 signal(SIGTSTP, SIG_IGN);
1476 signal(SIGTTIN, SIG_IGN);
1477 signal(SIGTTOU, SIG_IGN);
1478 signal(SIGCHLD, SIG_IGN);
1480 /* Put ourselves in our own process group. */
1482 shell_pgrp = getpid();
1483 setpgid(shell_pgrp, shell_pgrp);
1485 /* Grab control of the terminal. */
1486 tcsetpgrp(shell_terminal, shell_pgrp);
1489 static inline void setup_job_control(void)
1494 int lash_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
1495 int lash_main(int argc, char **argv)
1498 FILE *input = stdin;
1503 #if ENABLE_FEATURE_EDITING
1504 line_input_state = new_line_input_t(FOR_SHELL);
1507 /* These variables need re-initializing when recursing */
1509 close_me_list = NULL;
1510 job_list.head = NULL;
1512 last_return_code = 1;
1514 if (global_argv[0] && global_argv[0][0] == '-') {
1516 prof_input = fopen("/etc/profile", "r");
1518 llist_add_to(&close_me_list, (void *)(long)fileno(prof_input));
1519 /* Now run the file */
1520 busy_loop(prof_input);
1521 fclose_if_not_stdin(prof_input);
1522 llist_pop(&close_me_list);
1526 opt = getopt32(argv, "+ic:", &local_pending_command);
1527 #define LASH_OPT_i (1<<0)
1528 #define LASH_OPT_c (1<<1)
1529 if (opt & LASH_OPT_c) {
1532 global_argv += optind;
1534 /* A shell is interactive if the `-i' flag was given, or if all of
1535 * the following conditions are met:
1537 * no arguments remaining or the -s flag given
1538 * standard input is a terminal
1539 * standard output is a terminal
1540 * Refer to Posix.2, the description of the `sh' utility. */
1541 if (global_argv[optind] == NULL && input == stdin
1542 && isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)
1546 setup_job_control();
1547 if (opt & LASH_OPT_i) {
1548 /* Looks like they want an interactive shell */
1549 if (!ENABLE_FEATURE_SH_EXTRA_QUIET) {
1550 printf("\n\n%s built-in shell (lash)\n"
1551 "Enter 'help' for a list of built-in commands.\n\n",
1554 } else if (!local_pending_command && global_argv[optind]) {
1555 //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
1556 input = xfopen(global_argv[optind], "r");
1557 /* be lazy, never mark this closed */
1558 llist_add_to(&close_me_list, (void *)(long)fileno(input));
1561 /* initialize the cwd -- this is never freed...*/
1564 if (ENABLE_FEATURE_CLEAN_UP) atexit(free_memory);
1566 if (ENABLE_FEATURE_EDITING) cmdedit_set_initial_prompt();
1569 return busy_loop(input);