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
33 enum { MAX_READ = 128 }; /* size of input buffer for 'read' builtin */
34 #define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
37 #ifdef CONFIG_LASH_PIPE_N_REDIRECTS
38 enum redir_type { REDIRECT_INPUT, REDIRECT_OVERWRITE,
44 DEFAULT_CONTEXT = 0x1,
45 IF_TRUE_CONTEXT = 0x2,
46 IF_FALSE_CONTEXT = 0x4,
47 THEN_EXP_CONTEXT = 0x8,
48 ELSE_EXP_CONTEXT = 0x10
51 #define LASH_OPT_DONE (1)
52 #define LASH_OPT_SAW_QUOTE (2)
54 #ifdef CONFIG_LASH_PIPE_N_REDIRECTS
56 enum redir_type type; /* type of redirection */
57 int fd; /* file descriptor being redirected */
58 char *filename; /* file to redirect fd to */
63 pid_t pid; /* 0 if exited */
64 char **argv; /* program name and arguments */
65 int num_redirects; /* elements in redirection array */
66 int is_stopped; /* is the program currently running? */
67 struct job *family; /* pointer back to the child's parent job */
68 #ifdef CONFIG_LASH_PIPE_N_REDIRECTS
69 struct redir_struct *redirects; /* I/O redirects */
74 struct job *head; /* head of list of running jobs */
75 struct job *fg; /* current foreground job */
79 int jobid; /* job number */
80 int num_progs; /* total number of programs in job */
81 int running_progs; /* number of programs running */
82 char *text; /* name of job */
83 char *cmdbuf; /* buffer various argv's point into */
84 pid_t pgrp; /* process group ID for the job */
85 struct child_prog *progs; /* array of programs in job */
86 struct job *next; /* to track background commands */
87 int stopped_progs; /* number of programs alive, but stopped */
88 unsigned int job_context; /* bitmask defining current context */
89 struct jobset *job_list;
92 struct built_in_command {
93 const char *cmd; /* name */
94 const char *descr; /* description */
95 int (*function) (struct child_prog *); /* function ptr */
98 /* function prototypes for builtins */
99 static int builtin_cd(struct child_prog *cmd);
100 static int builtin_exec(struct child_prog *cmd);
101 static int builtin_exit(struct child_prog *cmd);
102 static int builtin_fg_bg(struct child_prog *cmd);
103 static int builtin_help(struct child_prog *cmd);
104 static int builtin_jobs(struct child_prog *dummy);
105 static int builtin_pwd(struct child_prog *dummy);
106 static int builtin_export(struct child_prog *cmd);
107 static int builtin_source(struct child_prog *cmd);
108 static int builtin_unset(struct child_prog *cmd);
109 static int builtin_read(struct child_prog *cmd);
112 /* function prototypes for shell stuff */
113 static void checkjobs(struct jobset *job_list);
114 static void remove_job(struct jobset *j_list, struct job *job);
115 static int get_command(FILE * source, char *command);
116 static int parse_command(char **command_ptr, struct job *job, int *inbg);
117 static int run_command(struct job *newjob, int inbg, int outpipe[2]);
118 static int pseudo_exec(struct child_prog *cmd) ATTRIBUTE_NORETURN;
119 static int busy_loop(FILE * input);
122 /* Table of built-in functions (these are non-forking builtins, meaning they
123 * can change global variables in the parent shell process but they will not
124 * work with pipes and redirects; 'unset foo | whatever' will not work) */
125 static const struct built_in_command bltins[] = {
126 {"bg", "Resume a job in the background", builtin_fg_bg},
127 {"cd", "Change working directory", builtin_cd},
128 {"exec", "Exec command, replacing this shell with the exec'd process", builtin_exec},
129 {"exit", "Exit from shell()", builtin_exit},
130 {"fg", "Bring job into the foreground", builtin_fg_bg},
131 {"jobs", "Lists the active jobs", builtin_jobs},
132 {"export", "Set environment variable", builtin_export},
133 {"unset", "Unset environment variable", builtin_unset},
134 {"read", "Input environment variable", builtin_read},
135 {".", "Source-in and run commands in a file", builtin_source},
136 /* to do: add ulimit */
140 /* Table of forking built-in functions (things that fork cannot change global
141 * variables in the parent process, such as the current working directory) */
142 static struct built_in_command bltins_forking[] = {
143 {"pwd", "Print current directory", builtin_pwd},
144 {"help", "List shell built-in commands", builtin_help},
149 static int shell_context; /* Type prompt trigger (PS1 or PS2) */
152 /* Globals that are static to this file */
153 static const char *cwd;
154 static char *local_pending_command;
155 static struct jobset job_list = { NULL, NULL };
158 static llist_t *close_me_list;
159 static int last_return_code;
160 static int last_bg_pid;
161 static unsigned int last_jobid;
162 static int shell_terminal;
163 static const char *PS1;
164 static const char *PS2 = "> ";
168 static inline void debug_printf(const char *format, ...)
171 va_start(args, format);
172 vfprintf(stderr, format, args);
176 static inline void debug_printf(const char ATTRIBUTE_UNUSED *format, ...) { }
180 Most builtins need access to the struct child_prog that has
181 their arguments, previously coded as cmd->progs[0]. That coding
182 can exhibit a bug, if the builtin is not the first command in
183 a pipeline: "echo foo | exec sort" will attempt to exec foo.
185 builtin previous use notes
186 ------ ----------------- ---------
188 exec cmd->progs[0] squashed bug: didn't look for applets or forking builtins
190 fg_bg cmd->progs[0], job_list->head, job_list->fg
199 I added "struct job *family;" to struct child_prog,
200 and switched API to builtin_foo(struct child_prog *child);
201 So cmd->text becomes child->family->text
202 cmd->job_context becomes child->family->job_context
203 cmd->progs[0] becomes *child
204 job_list becomes child->family->job_list
207 /* built-in 'cd <path>' handler */
208 static int builtin_cd(struct child_prog *child)
212 if (child->argv[1] == NULL)
213 newdir = getenv("HOME");
215 newdir = child->argv[1];
217 bb_perror_msg("cd: %s", newdir);
220 cwd = xrealloc_getcwd_or_warn((char *)cwd);
222 cwd = bb_msg_unknown;
226 /* built-in 'exec' handler */
227 static int builtin_exec(struct child_prog *child)
229 if (child->argv[1] == NULL)
230 return EXIT_SUCCESS; /* Really? */
232 while(close_me_list) close((long)llist_pop(&close_me_list));
237 /* built-in 'exit' handler */
238 static int builtin_exit(struct child_prog *child)
240 if (child->argv[1] == NULL)
243 exit (atoi(child->argv[1]));
246 /* built-in 'fg' and 'bg' handler */
247 static int builtin_fg_bg(struct child_prog *child)
250 struct job *job=NULL;
252 /* If they gave us no args, assume they want the last backgrounded task */
253 if (!child->argv[1]) {
254 for (job = child->family->job_list->head; job; job = job->next) {
255 if (job->jobid == last_jobid) {
260 bb_error_msg("%s: no current job", child->argv[0]);
264 if (sscanf(child->argv[1], "%%%d", &jobnum) != 1) {
265 bb_error_msg(bb_msg_invalid_arg, child->argv[1], child->argv[0]);
268 for (job = child->family->job_list->head; job; job = job->next) {
269 if (job->jobid == jobnum) {
274 bb_error_msg("%s: %d: no such job", child->argv[0], jobnum);
279 if (*child->argv[0] == 'f') {
280 /* Put the job into the foreground. */
281 tcsetpgrp(shell_terminal, job->pgrp);
283 child->family->job_list->fg = job;
286 /* Restart the processes in the job */
287 for (i = 0; i < job->num_progs; i++)
288 job->progs[i].is_stopped = 0;
290 job->stopped_progs = 0;
292 if ( (i=kill(- job->pgrp, SIGCONT)) < 0) {
294 remove_job(&job_list, job);
296 bb_perror_msg("kill (SIGCONT)");
303 /* built-in 'help' handler */
304 static int builtin_help(struct child_prog ATTRIBUTE_UNUSED *dummy)
306 const struct built_in_command *x;
308 printf("\nBuilt-in commands:\n"
309 "-------------------\n");
310 for (x = bltins; x->cmd; x++) {
311 if (x->descr == NULL)
313 printf("%s\t%s\n", x->cmd, x->descr);
315 for (x = bltins_forking; x->cmd; x++) {
316 if (x->descr == NULL)
318 printf("%s\t%s\n", x->cmd, x->descr);
324 /* built-in 'jobs' handler */
325 static int builtin_jobs(struct child_prog *child)
328 const char *status_string;
330 for (job = child->family->job_list->head; job; job = job->next) {
331 if (job->running_progs == job->stopped_progs)
332 status_string = "Stopped";
334 status_string = "Running";
336 printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->text);
342 /* built-in 'pwd' handler */
343 static int builtin_pwd(struct child_prog ATTRIBUTE_UNUSED *dummy)
345 cwd = xrealloc_getcwd_or_warn((char *)cwd);
347 cwd = bb_msg_unknown;
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 #ifdef CONFIG_FEATURE_EDITING_FANCY_PROMPT
369 if (strncmp(v, "PS1=", 4)==0)
373 #ifdef CONFIG_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!)
407 if ((s = strdup(string)))
410 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 #ifdef CONFIG_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 #ifdef CONFIG_LASH_PIPE_N_REDIRECTS
458 if (cmd->progs[i].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 #ifdef CONFIG_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(redir->filename, mode, 0666);
572 /* this could get lost if stderr has been redirected, but
573 bash and ash both lose it as well (though zsh doesn't!) */
574 bb_perror_msg("error opening %s", redir->filename);
578 if (openfd != redir->fd) {
579 if (squirrel && redir->fd < 3) {
580 squirrel[redir->fd] = dup(redir->fd);
581 fcntl (squirrel[redir->fd], F_SETFD, FD_CLOEXEC);
583 dup2(openfd, redir->fd);
591 static void restore_redirects(int squirrel[])
594 for (i=0; i<3; i++) {
597 /* No error checking. I sure wouldn't know what
598 * to do with an error if I found one! */
605 static inline int setup_redirects(struct child_prog *prog, int squirrel[])
609 static inline void restore_redirects(int squirrel[])
614 static inline void cmdedit_set_initial_prompt(void)
616 #if !ENABLE_FEATURE_EDITING_FANCY_PROMPT
625 static inline const char* setup_prompt_string(void)
627 #if !ENABLE_FEATURE_EDITING_FANCY_PROMPT
628 /* Set up the prompt */
629 if (shell_context == 0) {
632 ns = xmalloc(strlen(cwd)+4);
633 sprintf(ns, "%s %c ", cwd, (geteuid() != 0) ? '$': '#');
640 return (shell_context==0)? PS1 : PS2;
644 #if ENABLE_FEATURE_EDITING
645 static line_input_t *line_input_state;
648 static int get_command(FILE * source, char *command)
650 const char *prompt_str;
652 if (source == NULL) {
653 if (local_pending_command) {
654 /* a command specified (-c option): return it & mark it done */
655 strcpy(command, local_pending_command);
656 free(local_pending_command);
657 local_pending_command = NULL;
663 if (source == stdin) {
664 prompt_str = setup_prompt_string();
666 #if ENABLE_FEATURE_EDITING
668 ** enable command line editing only while a command line
669 ** is actually being read; otherwise, we'll end up bequeathing
670 ** atexit() handlers and other unwanted stuff to our
671 ** child processes (rob@sysgo.de)
673 read_line_input(prompt_str, command, BUFSIZ, line_input_state);
676 fputs(prompt_str, stdout);
680 if (!fgets(command, BUFSIZ - 2, source)) {
689 static char * strsep_space( char *string, int * ix)
691 /* Short circuit the trivial case */
692 if ( !string || ! string[*ix])
695 /* Find the end of the token. */
696 while (string[*ix] && !isspace(string[*ix]) ) {
700 /* Find the end of any whitespace trailing behind
701 * the token and let that be part of the token */
702 while (string[*ix] && (isspace)(string[*ix]) ) {
707 /* Nothing useful was found */
711 return xstrndup(string, *ix);
714 static int expand_arguments(char *command)
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 const char * const out_of_space = "out of space during expansion";
721 int flags = GLOB_NOCHECK
730 /* get rid of the terminating \n */
733 /* Fix up escape sequences to be the Real Thing(tm) */
734 while( command && command[ix]) {
735 if (command[ix] == '\\') {
736 const char *tmp = command+ix+1;
737 command[ix] = bb_process_escape_sequence( &tmp );
738 memmove(command+ix + 1, tmp, strlen(tmp)+1);
742 /* Use glob and then fixup environment variables and such */
744 /* It turns out that glob is very stupid. We have to feed it one word at a
745 * time since it can't cope with a full string. Here we convert command
746 * (char*) into cmd (char**, one word per string) */
748 /* We need a clean copy, so strsep can mess up the copy while
749 * we write stuff into the original (in a minute) */
750 cmd = cmd_copy = xstrdup(command);
752 for (ix = 0, tmpcmd = cmd;
753 (tmpcmd = strsep_space(cmd, &ix)) != NULL; cmd += ix, ix=0) {
756 /* we need to trim() the result for glob! */
758 retval = glob(tmpcmd, flags, NULL, &expand_result);
759 free(tmpcmd); /* Free mem allocated by strsep_space */
760 if (retval == GLOB_NOSPACE) {
761 /* Mem may have been allocated... */
762 globfree (&expand_result);
763 bb_error_msg(out_of_space);
765 } else if (retval != 0) {
766 /* Some other error. GLOB_NOMATCH shouldn't
767 * happen because of the GLOB_NOCHECK flag in
769 bb_error_msg("syntax error");
772 /* Convert from char** (one word per string) to a simple char*,
773 * but don't overflow command which is BUFSIZ in length */
774 for (i=0; i < expand_result.gl_pathc; i++) {
775 length=strlen(expand_result.gl_pathv[i]);
776 if (total_length+length+1 >= BUFSIZ) {
777 bb_error_msg(out_of_space);
780 strcat(command+total_length, " ");
782 strcat(command+total_length, expand_result.gl_pathv[i]);
783 total_length+=length;
785 globfree (&expand_result);
791 /* Now do the shell variable substitutions which
792 * wordexp can't do for us, namely $? and $! */
794 while((dst = strchr(src,'$')) != NULL){
798 var = itoa(last_return_code);
804 var = itoa(last_bg_pid);
806 /* Everything else like $$, $#, $[0-9], etc. should all be
807 * expanded by wordexp(), so we can in theory skip that stuff
808 * here, but just to be on the safe side (i.e., since uClibc
809 * wordexp doesn't do this stuff yet), lets leave it in for
812 var = itoa(getpid());
817 case '0':case '1':case '2':case '3':case '4':
818 case '5':case '6':case '7':case '8':case '9':
820 int ixx=*(dst+1)-48+1;
831 /* a single character construction was found, and
832 * already handled in the case statement */
835 /* Looks like an environment variable */
837 int num_skip_chars=0;
838 int dstlen = strlen(dst);
839 /* Is this a ${foo} type variable? */
840 if (dstlen >=2 && *(dst+1) == '{') {
841 src=strchr(dst+1, '}');
845 while((isalnum)(*src) || *src=='_') src++;
851 *src='\0'; /* temporary */
852 var = getenv(dst + 1 + num_skip_chars);
854 src += num_skip_chars;
857 /* Seems we got an un-expandable variable. So delete it. */
861 int subst_len = strlen(var);
862 int trail_len = strlen(src);
863 if (dst+subst_len+trail_len >= command+BUFSIZ) {
864 bb_error_msg(out_of_space);
867 /* Move stuff to the end of the string to accommodate
868 * filling the created gap with the new stuff */
869 memmove(dst+subst_len, src, trail_len+1);
870 /* Now copy in the new stuff */
871 memcpy(dst, var, subst_len);
879 /* Return cmd->num_progs as 0 if no command is present (e.g. an empty
880 line). If a valid command is found, command_ptr is set to point to
881 the beginning of the next command (if the original command had more
882 then one job associated with it) or NULL if no more commands are
884 static int parse_command(char **command_ptr, struct job *job, int *inbg)
887 char *return_command = NULL;
893 struct child_prog *prog;
894 #ifdef CONFIG_LASH_PIPE_N_REDIRECTS
899 /* skip leading white space */
900 *command_ptr = skip_whitespace(*command_ptr);
902 /* this handles empty lines or leading '#' characters */
903 if (!**command_ptr || (**command_ptr == '#')) {
910 job->progs = xmalloc(sizeof(*job->progs));
912 /* We set the argv elements to point inside of this string. The
913 memory is freed by free_job(). Allocate twice the original
914 length in case we need to quote every single character.
916 Getting clean memory relieves us of the task of NULL
917 terminating things and makes the rest of this look a bit
918 cleaner (though it is, admittedly, a tad less efficient) */
919 job->cmdbuf = command = xzalloc(2*strlen(*command_ptr) + 1);
923 prog->num_redirects = 0;
924 prog->is_stopped = 0;
926 #ifdef CONFIG_LASH_PIPE_N_REDIRECTS
927 prog->redirects = NULL;
931 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
932 prog->argv[0] = job->cmdbuf;
937 while (*src && !(flag & LASH_OPT_DONE)) {
944 bb_error_msg("character expected after \\");
949 /* in shell, "\'" should yield \' */
954 } else if (*src == '*' || *src == '?' || *src == '[' ||
955 *src == ']') *buf++ = '\\';
957 } else if (isspace(*src)) {
958 if (*prog->argv[argc_l] || flag & LASH_OPT_SAW_QUOTE) {
960 /* +1 here leaves room for the NULL which ends argv */
961 if ((argc_l + 1) == argv_alloced) {
963 prog->argv = xrealloc(prog->argv,
964 sizeof(*prog->argv) *
967 prog->argv[argc_l] = buf;
968 flag ^= LASH_OPT_SAW_QUOTE;
975 flag |= LASH_OPT_SAW_QUOTE;
978 case '#': /* comment */
982 flag |= LASH_OPT_DONE;
985 #ifdef CONFIG_LASH_PIPE_N_REDIRECTS
986 case '>': /* redirects */
988 i = prog->num_redirects++;
989 prog->redirects = xrealloc(prog->redirects,
990 sizeof(*prog->redirects) *
993 prog->redirects[i].fd = -1;
994 if (buf != prog->argv[argc_l]) {
995 /* the stuff before this character may be the file number
997 prog->redirects[i].fd =
998 strtol(prog->argv[argc_l], &chptr, 10);
1000 if (*chptr && *prog->argv[argc_l]) {
1002 prog->argv[argc_l] = buf;
1006 if (prog->redirects[i].fd == -1) {
1008 prog->redirects[i].fd = 1;
1010 prog->redirects[i].fd = 0;
1013 if (*src++ == '>') {
1015 prog->redirects[i].type =
1016 REDIRECT_APPEND, src++;
1018 prog->redirects[i].type = REDIRECT_OVERWRITE;
1020 prog->redirects[i].type = REDIRECT_INPUT;
1023 /* This isn't POSIX sh compliant. Oh well. */
1025 chptr = skip_whitespace(chptr);
1028 bb_error_msg("file name expected after %c", *(src-1));
1034 prog->redirects[i].filename = buf;
1035 while (*chptr && !isspace(*chptr))
1038 src = chptr - 1; /* we src++ later */
1039 prog->argv[argc_l] = ++buf;
1042 case '|': /* pipe */
1043 /* finish this command */
1044 if (*prog->argv[argc_l] || flag & LASH_OPT_SAW_QUOTE)
1047 goto empty_command_in_pipe;
1049 prog->argv[argc_l] = NULL;
1051 /* and start the next */
1053 job->progs = xrealloc(job->progs,
1054 sizeof(*job->progs) * job->num_progs);
1055 prog = job->progs + (job->num_progs - 1);
1056 prog->num_redirects = 0;
1057 prog->redirects = NULL;
1058 prog->is_stopped = 0;
1063 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1064 prog->argv[0] = ++buf;
1067 src = skip_whitespace(src);
1070 empty_command_in_pipe:
1071 bb_error_msg("empty command in pipe");
1076 src--; /* we'll ++ it at the end of the loop */
1081 #ifdef CONFIG_LASH_JOB_CONTROL
1082 case '&': /* background */
1086 case ';': /* multiple commands */
1087 flag |= LASH_OPT_DONE;
1088 return_command = *command_ptr + (src - *command_ptr) + 1;
1094 bb_error_msg("character expected after \\");
1098 if (*src == '*' || *src == '[' || *src == ']'
1099 || *src == '?') *buf++ = '\\';
1108 if (*prog->argv[argc_l] || flag & LASH_OPT_SAW_QUOTE) {
1115 prog->argv[argc_l] = NULL;
1117 if (!return_command) {
1118 job->text = xstrdup(*command_ptr);
1120 /* This leaves any trailing spaces, which is a bit sloppy */
1121 job->text = xstrndup(*command_ptr, return_command - *command_ptr);
1124 *command_ptr = return_command;
1129 /* Run the child_prog, no matter what kind of command it uses.
1131 static int pseudo_exec(struct child_prog *child)
1133 const struct built_in_command *x;
1135 /* Check if the command matches any of the non-forking builtins.
1136 * Depending on context, this might be redundant. But it's
1137 * easier to waste a few CPU cycles than it is to figure out
1138 * if this is one of those cases.
1140 for (x = bltins; x->cmd; x++) {
1141 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1142 _exit(x->function(child));
1146 /* Check if the command matches any of the forking builtins. */
1147 for (x = bltins_forking; x->cmd; x++) {
1148 if (strcmp(child->argv[0], x->cmd) == 0) {
1150 _exit (x->function(child));
1154 /* Check if the command matches any busybox internal
1155 * commands ("applets") here. Following discussions from
1156 * November 2000 on busybox@busybox.net, don't use
1157 * bb_get_last_path_component(). This way explicit (with
1158 * slashes) filenames will never be interpreted as an
1159 * applet, just like with builtins. This way the user can
1160 * override an applet with an explicit filename reference.
1161 * The only downside to this change is that an explicit
1162 * /bin/foo invocation will fork and exec /bin/foo, even if
1163 * /bin/foo is a symlink to busybox.
1166 if (ENABLE_FEATURE_SH_STANDALONE_SHELL) {
1167 char **argv_l = child->argv;
1170 for (argc_l=0; *argv_l; argv_l++, argc_l++);
1172 run_applet_by_name(child->argv[0], argc_l, child->argv);
1175 execvp(child->argv[0], child->argv);
1177 /* Do not use bb_perror_msg_and_die() here, since we must not
1178 * call exit() but should call _exit() instead */
1179 bb_perror_msg("%s", child->argv[0]);
1180 _exit(EXIT_FAILURE);
1183 static void insert_job(struct job *newjob, int inbg)
1186 struct jobset *j_list=newjob->job_list;
1188 /* find the ID for thejob to use */
1190 for (thejob = j_list->head; thejob; thejob = thejob->next)
1191 if (thejob->jobid >= newjob->jobid)
1192 newjob->jobid = thejob->jobid + 1;
1194 /* add thejob to the list of running jobs */
1195 if (!j_list->head) {
1196 thejob = j_list->head = xmalloc(sizeof(*thejob));
1198 for (thejob = j_list->head; thejob->next; thejob = thejob->next) /* nothing */;
1199 thejob->next = xmalloc(sizeof(*thejob));
1200 thejob = thejob->next;
1203 *thejob = *newjob; /* physically copy the struct job */
1204 thejob->next = NULL;
1205 thejob->running_progs = thejob->num_progs;
1206 thejob->stopped_progs = 0;
1208 #ifdef CONFIG_LASH_JOB_CONTROL
1210 /* we don't wait for background thejobs to return -- append it
1211 to the list of backgrounded thejobs and leave it alone */
1212 printf("[%d] %d\n", thejob->jobid,
1213 newjob->progs[newjob->num_progs - 1].pid);
1214 last_jobid = newjob->jobid;
1215 last_bg_pid=newjob->progs[newjob->num_progs - 1].pid;
1217 newjob->job_list->fg = thejob;
1219 /* move the new process group into the foreground */
1220 /* Ignore errors since child could have already exited */
1221 tcsetpgrp(shell_terminal, newjob->pgrp);
1226 static int run_command(struct job *newjob, int inbg, int outpipe[2])
1228 /* struct job *thejob; */
1230 int nextin, nextout;
1231 int pipefds[2]; /* pipefd[0] is for reading */
1232 const struct built_in_command *x;
1233 struct child_prog *child;
1235 nextin = 0, nextout = 1;
1236 for (i = 0; i < newjob->num_progs; i++) {
1237 child = & (newjob->progs[i]);
1239 if ((i + 1) < newjob->num_progs) {
1240 if (pipe(pipefds)<0) bb_perror_msg_and_die("pipe");
1241 nextout = pipefds[1];
1243 if (outpipe[1]!=-1) {
1244 nextout = outpipe[1];
1251 /* Check if the command matches any non-forking builtins,
1252 * but only if this is a simple command.
1253 * Non-forking builtins within pipes have to fork anyway,
1254 * and are handled in pseudo_exec. "echo foo | read bar"
1255 * is doomed to failure, and doesn't work on bash, either.
1257 if (newjob->num_progs == 1) {
1258 /* Check if the command sets an environment variable. */
1259 if (strchr(child->argv[0], '=') != NULL) {
1260 child->argv[1] = child->argv[0];
1261 return builtin_export(child);
1264 for (x = bltins; x->cmd; x++) {
1265 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1267 int squirrel[] = {-1, -1, -1};
1268 setup_redirects(child, squirrel);
1269 rcode = x->function(child);
1270 restore_redirects(squirrel);
1276 #if !defined(__UCLIBC__) || defined(__ARCH_HAS_MMU__)
1277 if (!(child->pid = fork()))
1279 if (!(child->pid = vfork()))
1282 /* Set the handling for job control signals back to the default. */
1283 signal(SIGINT, SIG_DFL);
1284 signal(SIGQUIT, SIG_DFL);
1285 signal(SIGTSTP, SIG_DFL);
1286 signal(SIGTTIN, SIG_DFL);
1287 signal(SIGTTOU, SIG_DFL);
1288 signal(SIGCHLD, SIG_DFL);
1290 /* Close all open filehandles. */
1291 while(close_me_list) close((long)llist_pop(&close_me_list));
1293 if (outpipe[1]!=-1) {
1303 dup2(nextout, 2); /* Really? */
1308 /* explicit redirects override pipes */
1309 setup_redirects(child,NULL);
1313 if (outpipe[1]!=-1) {
1317 /* put our child in the process group whose leader is the
1318 first process in this pipe */
1319 setpgid(child->pid, newjob->progs[0].pid);
1325 /* If there isn't another process, nextin is garbage
1326 but it doesn't matter */
1327 nextin = pipefds[0];
1330 newjob->pgrp = newjob->progs[0].pid;
1332 insert_job(newjob, inbg);
1337 static int busy_loop(FILE * input)
1340 char *next_command = NULL;
1345 #ifdef CONFIG_LASH_JOB_CONTROL
1347 /* save current owner of TTY so we can restore it on exit */
1348 parent_pgrp = tcgetpgrp(shell_terminal);
1350 newjob.job_list = &job_list;
1351 newjob.job_context = DEFAULT_CONTEXT;
1353 command = xzalloc(BUFSIZ);
1357 /* no job is in the foreground */
1359 /* see if any background processes have exited */
1360 checkjobs(&job_list);
1362 if (!next_command) {
1363 if (get_command(input, command))
1365 next_command = command;
1368 if (! expand_arguments(next_command)) {
1370 command = xzalloc(BUFSIZ);
1371 next_command = NULL;
1375 if (!parse_command(&next_command, &newjob, &inbg) &&
1377 int pipefds[2] = {-1,-1};
1378 debug_printf( "job=%p fed to run_command by busy_loop()'\n",
1380 run_command(&newjob, inbg, pipefds);
1384 command = xzalloc(BUFSIZ);
1385 next_command = NULL;
1388 /* a job is running in the foreground; wait for it */
1390 while (!job_list.fg->progs[i].pid ||
1391 job_list.fg->progs[i].is_stopped == 1) i++;
1393 if (waitpid(job_list.fg->progs[i].pid, &status, WUNTRACED)<0) {
1394 if (errno != ECHILD) {
1395 bb_perror_msg_and_die("waitpid(%d)",job_list.fg->progs[i].pid);
1399 if (WIFEXITED(status) || WIFSIGNALED(status)) {
1400 /* the child exited */
1401 job_list.fg->running_progs--;
1402 job_list.fg->progs[i].pid = 0;
1404 last_return_code=WEXITSTATUS(status);
1406 if (!job_list.fg->running_progs) {
1408 remove_job(&job_list, job_list.fg);
1412 #ifdef CONFIG_LASH_JOB_CONTROL
1414 /* the child was stopped */
1415 job_list.fg->stopped_progs++;
1416 job_list.fg->progs[i].is_stopped = 1;
1418 if (job_list.fg->stopped_progs == job_list.fg->running_progs) {
1419 printf("\n" JOB_STATUS_FORMAT, job_list.fg->jobid,
1420 "Stopped", job_list.fg->text);
1426 /* move the shell to the foreground */
1427 /* suppress messages when run from /linuxrc mag@sysgo.de */
1428 if (tcsetpgrp(shell_terminal, getpgrp()) && errno != ENOTTY)
1429 bb_perror_msg("tcsetpgrp");
1436 #ifdef CONFIG_LASH_JOB_CONTROL
1437 /* return controlling TTY back to parent process group before exiting */
1438 if (tcsetpgrp(shell_terminal, parent_pgrp) && errno != ENOTTY)
1439 bb_perror_msg("tcsetpgrp");
1442 /* return exit status if called with "-c" */
1443 if (input == NULL && WIFEXITED(status))
1444 return WEXITSTATUS(status);
1449 #ifdef CONFIG_FEATURE_CLEAN_UP
1450 static void free_memory(void)
1452 if (cwd && cwd!=bb_msg_unknown) {
1455 if (local_pending_command)
1456 free(local_pending_command);
1458 if (job_list.fg && !job_list.fg->running_progs) {
1459 remove_job(&job_list, job_list.fg);
1463 void free_memory(void);
1466 #ifdef CONFIG_LASH_JOB_CONTROL
1467 /* Make sure we have a controlling tty. If we get started under a job
1468 * aware app (like bash for example), make sure we are now in charge so
1469 * we don't fight over who gets the foreground */
1470 static void setup_job_control(void)
1475 /* Loop until we are in the foreground. */
1476 while ((status = tcgetpgrp (shell_terminal)) >= 0) {
1477 if (status == (shell_pgrp = getpgrp ())) {
1480 kill (- shell_pgrp, SIGTTIN);
1483 /* Ignore interactive and job-control signals. */
1484 signal(SIGINT, SIG_IGN);
1485 signal(SIGQUIT, SIG_IGN);
1486 signal(SIGTSTP, SIG_IGN);
1487 signal(SIGTTIN, SIG_IGN);
1488 signal(SIGTTOU, SIG_IGN);
1489 signal(SIGCHLD, SIG_IGN);
1491 /* Put ourselves in our own process group. */
1493 shell_pgrp = getpid();
1494 setpgid(shell_pgrp, shell_pgrp);
1496 /* Grab control of the terminal. */
1497 tcsetpgrp(shell_terminal, shell_pgrp);
1500 static inline void setup_job_control(void)
1505 int lash_main(int argc_l, char **argv_l);
1506 int lash_main(int argc_l, char **argv_l)
1509 FILE *input = stdin;
1513 #if ENABLE_FEATURE_EDITING
1514 line_input_state = new_line_input_t(FOR_SHELL);
1517 /* These variables need re-initializing when recursing */
1519 close_me_list = NULL;
1520 job_list.head = NULL;
1524 if (argv[0] && argv[0][0] == '-') {
1526 prof_input = fopen("/etc/profile", "r");
1528 llist_add_to(&close_me_list, (void *)(long)fileno(prof_input));
1529 /* Now run the file */
1530 busy_loop(prof_input);
1531 fclose_if_not_stdin(prof_input);
1532 llist_pop(&close_me_list);
1536 opt = getopt32(argc_l, argv_l, "+ic:", &local_pending_command);
1537 #define LASH_OPT_i (1<<0)
1538 #define LASH_OPT_c (1<<2)
1539 if (opt & LASH_OPT_c) {
1544 /* A shell is interactive if the `-i' flag was given, or if all of
1545 * the following conditions are met:
1547 * no arguments remaining or the -s flag given
1548 * standard input is a terminal
1549 * standard output is a terminal
1550 * Refer to Posix.2, the description of the `sh' utility. */
1551 if (argv[optind]==NULL && input==stdin &&
1552 isatty(STDIN_FILENO) && isatty(STDOUT_FILENO))
1556 setup_job_control();
1557 if (opt & LASH_OPT_i) {
1558 /* Looks like they want an interactive shell */
1559 if (!ENABLE_FEATURE_SH_EXTRA_QUIET) {
1560 printf("\n\n%s Built-in shell (lash)\n"
1561 "Enter 'help' for a list of built-in commands.\n\n",
1564 } else if (!local_pending_command && argv[optind]) {
1565 //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
1566 input = xfopen(argv[optind], "r");
1567 /* be lazy, never mark this closed */
1568 llist_add_to(&close_me_list, (void *)(long)fileno(input));
1571 /* initialize the cwd -- this is never freed...*/
1572 cwd = xrealloc_getcwd_or_warn(NULL);
1574 cwd = bb_msg_unknown;
1576 if (ENABLE_FEATURE_CLEAN_UP) atexit(free_memory);
1578 if (ENABLE_FEATURE_EDITING) cmdedit_set_initial_prompt();
1581 return (busy_loop(input));