1 /* vi: set sw=4 ts=4: */
3 * lash -- the BusyBox Lame-Ass SHell
5 * Copyright (C) 1999,2000,2001 by Lineo, inc.
6 * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
8 * Based in part on ladsh.c by Michael K. Johnson and Erik W. Troan, which is
9 * under the following liberal license: "We have placed this source code in the
10 * public domain. Use it in any project, free or commercial."
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 /* The parsing engine of this program is officially at a dead-end.
29 * Future work in that direction should move to the work posted
30 * at http://doolittle.faludi.com/~larry/parser.html .
31 * A start on the integration of that work with the rest of sh.c
32 * is at http://codepoet.org/sh.c .
35 //This works pretty well now, and is now on by default.
36 #define BB_FEATURE_SH_ENVIRONMENT
38 //Backtick support has some problems, use at your own risk!
39 //#define BB_FEATURE_SH_BACKTICKS
41 //If, then, else, etc. support.. This should now behave basically
42 //like any other Bourne shell...
43 #define BB_FEATURE_SH_IF_EXPRESSIONS
45 /* This is currently a little broken... */
46 //#define HANDLE_CONTINUATION_CHARS
48 //For debugging/development on the shell only...
59 #include <sys/ioctl.h>
64 #if ( (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1) ) || defined (__UCLIBC__)
66 #define expand_t wordexp_t
67 #undef BB_FEATURE_SH_BACKTICKS
70 #define expand_t glob_t
76 static const int MAX_LINE = 256; /* size of input buffer for cwd data */
77 static const int MAX_READ = 128; /* size of input buffer for `read' builtin */
78 #define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
81 enum redir_type { REDIRECT_INPUT, REDIRECT_OVERWRITE,
85 static const unsigned int DEFAULT_CONTEXT=0x1;
86 static const unsigned int IF_TRUE_CONTEXT=0x2;
87 static const unsigned int IF_FALSE_CONTEXT=0x4;
88 static const unsigned int THEN_EXP_CONTEXT=0x8;
89 static const unsigned int ELSE_EXP_CONTEXT=0x10;
93 struct job *head; /* head of list of running jobs */
94 struct job *fg; /* current foreground job */
98 enum redir_type type; /* type of redirection */
99 int fd; /* file descriptor being redirected */
100 char *filename; /* file to redirect fd to */
104 pid_t pid; /* 0 if exited */
105 char **argv; /* program name and arguments */
106 int num_redirects; /* elements in redirection array */
107 struct redir_struct *redirects; /* I/O redirects */
108 int is_stopped; /* is the program currently running? */
109 struct job *family; /* pointer back to the child's parent job */
113 int jobid; /* job number */
114 int num_progs; /* total number of programs in job */
115 int running_progs; /* number of programs running */
116 char *text; /* name of job */
117 char *cmdbuf; /* buffer various argv's point into */
118 pid_t pgrp; /* process group ID for the job */
119 struct child_prog *progs; /* array of programs in job */
120 struct job *next; /* to track background commands */
121 int stopped_progs; /* number of programs alive, but stopped */
122 unsigned int job_context; /* bitmask defining current context */
123 struct jobset *job_list;
126 struct built_in_command {
127 char *cmd; /* name */
128 char *descr; /* description */
129 int (*function) (struct child_prog *); /* function ptr */
134 struct close_me *next;
137 /* function prototypes for builtins */
138 static int builtin_cd(struct child_prog *cmd);
139 static int builtin_env(struct child_prog *dummy);
140 static int builtin_exec(struct child_prog *cmd);
141 static int builtin_exit(struct child_prog *cmd);
142 static int builtin_fg_bg(struct child_prog *cmd);
143 static int builtin_help(struct child_prog *cmd);
144 static int builtin_jobs(struct child_prog *dummy);
145 static int builtin_pwd(struct child_prog *dummy);
146 static int builtin_export(struct child_prog *cmd);
147 static int builtin_source(struct child_prog *cmd);
148 static int builtin_unset(struct child_prog *cmd);
149 static int builtin_read(struct child_prog *cmd);
150 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
151 static int builtin_if(struct child_prog *cmd);
152 static int builtin_then(struct child_prog *cmd);
153 static int builtin_else(struct child_prog *cmd);
154 static int builtin_fi(struct child_prog *cmd);
155 /* function prototypes for shell stuff */
156 static int run_command_predicate(char *cmd);
160 /* function prototypes for shell stuff */
161 static void mark_open(int fd);
162 static void mark_closed(int fd);
163 static void close_all(void);
164 static void checkjobs(struct jobset *job_list);
165 static int get_command(FILE * source, char *command);
166 static int parse_command(char **command_ptr, struct job *job, int *inbg);
167 static int run_command(struct job *newjob, int inbg, int outpipe[2]);
168 static int pseudo_exec(struct child_prog *cmd) __attribute__ ((noreturn));
169 static int busy_loop(FILE * input);
172 /* Table of built-in functions (these are non-forking builtins, meaning they
173 * can change global variables in the parent shell process but they will not
174 * work with pipes and redirects; 'unset foo | whatever' will not work) */
175 static struct built_in_command bltins[] = {
176 {"bg", "Resume a job in the background", builtin_fg_bg},
177 {"cd", "Change working directory", builtin_cd},
178 {"exec", "Exec command, replacing this shell with the exec'd process", builtin_exec},
179 {"exit", "Exit from shell()", builtin_exit},
180 {"fg", "Bring job into the foreground", builtin_fg_bg},
181 {"jobs", "Lists the active jobs", builtin_jobs},
182 {"export", "Set environment variable", builtin_export},
183 {"unset", "Unset environment variable", builtin_unset},
184 {"read", "Input environment variable", builtin_read},
185 {".", "Source-in and run commands in a file", builtin_source},
186 /* to do: add ulimit */
187 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
188 {"if", NULL, builtin_if},
189 {"then", NULL, builtin_then},
190 {"else", NULL, builtin_else},
191 {"fi", NULL, builtin_fi},
196 /* Table of forking built-in functions (things that fork cannot change global
197 * variables in the parent process, such as the current working directory) */
198 static struct built_in_command bltins_forking[] = {
199 {"env", "Print all environment variables", builtin_env},
200 {"pwd", "Print current directory", builtin_pwd},
201 {"help", "List shell built-in commands", builtin_help},
206 /* Variables we export */
207 unsigned int shell_context; /* Used in cmdedit.c to reset the
208 context when someone hits ^C */
211 /* Globals that are static to this file */
213 static char *local_pending_command = NULL;
214 static struct jobset job_list = { NULL, NULL };
217 static struct close_me *close_me_head;
218 #ifdef BB_FEATURE_SH_ENVIRONMENT
219 static int last_bg_pid;
220 static int last_return_code;
221 static int show_x_trace;
223 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
224 static char syntax_err[]="syntax error near unexpected token";
228 static inline void debug_printf(const char *format, ...)
231 va_start(args, format);
232 vfprintf(stderr, format, args);
236 static inline void debug_printf(const char *format, ...) { }
240 Most builtins need access to the struct child_prog that has
241 their arguments, previously coded as cmd->progs[0]. That coding
242 can exhibit a bug, if the builtin is not the first command in
243 a pipeline: "echo foo | exec sort" will attempt to exec foo.
245 builtin previous use notes
246 ------ ----------------- ---------
249 exec cmd->progs[0] squashed bug: didn't look for applets or forking builtins
251 fg_bg cmd->progs[0], job_list->head, job_list->fg
255 export cmd->progs[0] passes cmd, job_list to builtin_env(), which ignores them
259 if cmd->job_context, cmd->text
260 then cmd->job_context, cmd->text
261 else cmd->job_context, cmd->text
264 The use of cmd->text by if/then/else/fi is hopelessly hacky.
265 Would it work to increment cmd->progs[0]->argv and recurse,
266 somewhat like builtin_exec does?
268 I added "struct job *family;" to struct child_prog,
269 and switched API to builtin_foo(struct child_prog *child);
270 So cmd->text becomes child->family->text
271 cmd->job_context becomes child->family->job_context
272 cmd->progs[0] becomes *child
273 job_list becomes child->family->job_list
276 /* built-in 'cd <path>' handler */
277 static int builtin_cd(struct child_prog *child)
281 if (child->argv[1] == NULL)
282 newdir = getenv("HOME");
284 newdir = child->argv[1];
286 printf("cd: %s: %s\n", newdir, strerror(errno));
289 getcwd(cwd, sizeof(char)*MAX_LINE);
294 /* built-in 'env' handler */
295 static int builtin_env(struct child_prog *dummy)
299 for (e = environ; *e; e++) {
305 /* built-in 'exec' handler */
306 static int builtin_exec(struct child_prog *child)
308 if (child->argv[1] == NULL)
309 return EXIT_SUCCESS; /* Really? */
316 /* built-in 'exit' handler */
317 static int builtin_exit(struct child_prog *child)
319 if (child->argv[1] == NULL)
322 exit (atoi(child->argv[1]));
325 /* built-in 'fg' and 'bg' handler */
326 static int builtin_fg_bg(struct child_prog *child)
329 struct job *job=NULL;
331 if (!child->argv[1] || child->argv[2]) {
332 error_msg("%s: exactly one argument is expected",
337 if (sscanf(child->argv[1], "%%%d", &jobNum) != 1) {
338 error_msg("%s: bad argument '%s'",
339 child->argv[0], child->argv[1]);
343 for (job = child->family->job_list->head; job; job = job->next) {
344 if (job->jobid == jobNum) {
350 error_msg("%s: unknown job %d",
351 child->argv[0], jobNum);
355 if (*child->argv[0] == 'f') {
356 /* Make this job the foreground job */
357 /* suppress messages when run from /linuxrc mag@sysgo.de */
358 if (tcsetpgrp(0, job->pgrp) && errno != ENOTTY)
359 perror_msg("tcsetpgrp");
360 child->family->job_list->fg = job;
363 /* Restart the processes in the job */
364 for (i = 0; i < job->num_progs; i++)
365 job->progs[i].is_stopped = 0;
367 kill(-job->pgrp, SIGCONT);
369 job->stopped_progs = 0;
374 /* built-in 'help' handler */
375 static int builtin_help(struct child_prog *dummy)
377 struct built_in_command *x;
379 printf("\nBuilt-in commands:\n");
380 printf("-------------------\n");
381 for (x = bltins; x->cmd; x++) {
384 printf("%s\t%s\n", x->cmd, x->descr);
386 for (x = bltins_forking; x->cmd; x++) {
389 printf("%s\t%s\n", x->cmd, x->descr);
395 /* built-in 'jobs' handler */
396 static int builtin_jobs(struct child_prog *child)
401 for (job = child->family->job_list->head; job; job = job->next) {
402 if (job->running_progs == job->stopped_progs)
403 status_string = "Stopped";
405 status_string = "Running";
407 printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->text);
413 /* built-in 'pwd' handler */
414 static int builtin_pwd(struct child_prog *dummy)
416 getcwd(cwd, MAX_LINE);
417 printf( "%s\n", cwd);
421 /* built-in 'export VAR=value' handler */
422 static int builtin_export(struct child_prog *child)
426 if (child->argv[1] == NULL) {
427 return (builtin_env(child));
429 res = putenv(child->argv[1]);
431 fprintf(stderr, "export: %s\n", strerror(errno));
435 /* built-in 'read VAR' handler */
436 static int builtin_read(struct child_prog *child)
438 int res = 0, len, newlen;
440 char string[MAX_READ];
442 if (child->argv[1]) {
443 /* argument (VAR) given: put "VAR=" into buffer */
444 strcpy(string, child->argv[1]);
445 len = strlen(string);
448 fgets(&string[len], sizeof(string) - len, stdin); /* read string */
449 newlen = strlen(string);
451 string[--newlen] = '\0'; /* chomp trailing newline */
453 ** string should now contain "VAR=<value>"
454 ** copy it (putenv() won't do that, so we must make sure
455 ** the string resides in a static buffer!)
458 if((s = strdup(string)))
461 fprintf(stderr, "read: %s\n", strerror(errno));
464 fgets(string, sizeof(string), stdin);
469 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
470 /* Built-in handler for 'if' commands */
471 static int builtin_if(struct child_prog *child)
473 struct job *cmd = child->family;
475 char* charptr1=cmd->text+3; /* skip over the leading 'if ' */
477 /* Now run the 'if' command */
478 debug_printf( "job=%p entering builtin_if ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
479 status = run_command_predicate(charptr1);
480 debug_printf( "if test returned ");
482 debug_printf( "TRUE\n");
483 cmd->job_context |= IF_TRUE_CONTEXT;
485 debug_printf( "FALSE\n");
486 cmd->job_context |= IF_FALSE_CONTEXT;
488 debug_printf("job=%p builtin_if set job context to %x\n", cmd, cmd->job_context);
494 /* Built-in handler for 'then' (part of the 'if' command) */
495 static int builtin_then(struct child_prog *child)
497 struct job *cmd = child->family;
498 char* charptr1=cmd->text+5; /* skip over the leading 'then ' */
500 debug_printf( "job=%p entering builtin_then ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
501 if (! (cmd->job_context & (IF_TRUE_CONTEXT|IF_FALSE_CONTEXT))) {
502 shell_context = 0; /* Reset the shell's context on an error */
503 error_msg("%s `then'", syntax_err);
507 cmd->job_context |= THEN_EXP_CONTEXT;
508 debug_printf("job=%p builtin_then set job context to %x\n", cmd, cmd->job_context);
510 /* If the if result was FALSE, skip the 'then' stuff */
511 if (cmd->job_context & IF_FALSE_CONTEXT) {
515 /* Seems the if result was TRUE, so run the 'then' command */
516 debug_printf( "'then' now running '%s'\n", charptr1);
518 return(run_command_predicate(charptr1));
521 /* Built-in handler for 'else' (part of the 'if' command) */
522 static int builtin_else(struct child_prog *child)
524 struct job *cmd = child->family;
525 char* charptr1=cmd->text+5; /* skip over the leading 'else ' */
527 debug_printf( "job=%p entering builtin_else ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
529 if (! (cmd->job_context & THEN_EXP_CONTEXT)) {
530 shell_context = 0; /* Reset the shell's context on an error */
531 error_msg("%s `else'", syntax_err);
534 /* If the if result was TRUE, skip the 'else' stuff */
535 if (cmd->job_context & IF_TRUE_CONTEXT) {
539 cmd->job_context |= ELSE_EXP_CONTEXT;
540 debug_printf("job=%p builtin_else set job context to %x\n", cmd, cmd->job_context);
542 /* Now run the 'else' command */
543 debug_printf( "'else' now running '%s'\n", charptr1);
544 return(run_command_predicate(charptr1));
547 /* Built-in handler for 'fi' (part of the 'if' command) */
548 static int builtin_fi(struct child_prog *child)
550 struct job *cmd = child->family;
551 debug_printf( "job=%p entering builtin_fi ('%s')-- context=%d\n", cmd, "", cmd->job_context);
552 if (! (cmd->job_context & (IF_TRUE_CONTEXT|IF_FALSE_CONTEXT))) {
553 shell_context = 0; /* Reset the shell's context on an error */
554 error_msg("%s `fi'", syntax_err);
557 /* Clear out the if and then context bits */
558 cmd->job_context &= ~(IF_TRUE_CONTEXT|IF_FALSE_CONTEXT|THEN_EXP_CONTEXT|ELSE_EXP_CONTEXT);
559 debug_printf("job=%p builtin_fi set job context to %x\n", cmd, cmd->job_context);
565 /* Built-in '.' handler (read-in and execute commands from file) */
566 static int builtin_source(struct child_prog *child)
572 if (child->argv[1] == NULL)
575 input = fopen(child->argv[1], "r");
577 printf( "Couldn't open file '%s'\n", child->argv[1]);
583 /* Now run the file */
584 status = busy_loop(input);
590 /* built-in 'unset VAR' handler */
591 static int builtin_unset(struct child_prog *child)
593 if (child->argv[1] == NULL) {
594 printf( "unset: parameter required.\n");
597 unsetenv(child->argv[1]);
601 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
602 /* currently used by if/then/else.
604 * Reparsing the command line for this purpose is gross,
605 * incorrect, and fundamentally unfixable; in particular,
606 * think about what happens with command substitution.
607 * We really need to pull out the run, wait, return status
608 * functionality out of busy_loop so we can child->argv++
609 * and use that, without going back through parse_command.
611 static int run_command_predicate(char *cmd)
614 local_pending_command = xmalloc(n+1);
615 strncpy(local_pending_command, cmd, n);
616 local_pending_command[n]='\0';
617 return( busy_loop(NULL));
621 static void mark_open(int fd)
623 struct close_me *new = xmalloc(sizeof(struct close_me));
625 new->next = close_me_head;
629 static void mark_closed(int fd)
631 struct close_me *tmp;
632 if (close_me_head == NULL || close_me_head->fd != fd)
633 error_msg_and_die("corrupt close_me");
635 close_me_head = close_me_head->next;
639 static void close_all()
641 struct close_me *c, *tmp;
642 for (c=close_me_head; c; c=tmp) {
647 close_me_head = NULL;
651 /* free up all memory from a job */
652 static void free_job(struct job *cmd)
656 for (i = 0; i < cmd->num_progs; i++) {
657 free(cmd->progs[i].argv);
658 if (cmd->progs[i].redirects)
659 free(cmd->progs[i].redirects);
665 memset(cmd, 0, sizeof(struct job));
668 /* remove a job from the job_list */
669 static void remove_job(struct jobset *job_list, struct job *job)
674 if (job == job_list->head) {
675 job_list->head = job->next;
677 prevjob = job_list->head;
678 while (prevjob->next != job)
679 prevjob = prevjob->next;
680 prevjob->next = job->next;
686 /* Checks to see if any background processes have exited -- if they
687 have, figure out why and see if a job has completed */
688 static void checkjobs(struct jobset *job_list)
695 while ((childpid = waitpid(-1, &status, WNOHANG | WUNTRACED)) > 0) {
696 for (job = job_list->head; job; job = job->next) {
698 while (prognum < job->num_progs &&
699 job->progs[prognum].pid != childpid) prognum++;
700 if (prognum < job->num_progs)
704 /* This happens on backticked commands */
708 if (WIFEXITED(status) || WIFSIGNALED(status)) {
710 job->running_progs--;
711 job->progs[prognum].pid = 0;
713 if (!job->running_progs) {
714 printf(JOB_STATUS_FORMAT, job->jobid, "Done", job->text);
715 remove_job(job_list, job);
719 job->stopped_progs++;
720 job->progs[prognum].is_stopped = 1;
722 if (job->stopped_progs == job->num_progs) {
723 printf(JOB_STATUS_FORMAT, job->jobid, "Stopped",
729 if (childpid == -1 && errno != ECHILD)
730 perror_msg("waitpid");
733 /* squirrel != NULL means we squirrel away copies of stdin, stdout,
734 * and stderr if they are redirected. */
735 static int setup_redirects(struct child_prog *prog, int squirrel[])
740 struct redir_struct *redir = prog->redirects;
742 for (i = 0; i < prog->num_redirects; i++, redir++) {
743 switch (redir->type) {
747 case REDIRECT_OVERWRITE:
748 mode = O_WRONLY | O_CREAT | O_TRUNC;
750 case REDIRECT_APPEND:
751 mode = O_WRONLY | O_CREAT | O_APPEND;
755 openfd = open(redir->filename, mode, 0666);
757 /* this could get lost if stderr has been redirected, but
758 bash and ash both lose it as well (though zsh doesn't!) */
759 error_msg("error opening %s: %s", redir->filename,
764 if (openfd != redir->fd) {
765 if (squirrel && redir->fd < 3) {
766 squirrel[redir->fd] = dup(redir->fd);
768 dup2(openfd, redir->fd);
776 static void restore_redirects(int squirrel[])
779 for (i=0; i<3; i++) {
782 /* No error checking. I sure wouldn't know what
783 * to do with an error if I found one! */
790 #if defined(BB_FEATURE_SH_SIMPLE_PROMPT)
791 static char* setup_prompt_string(int state)
793 char prompt_str[BUFSIZ];
795 /* Set up the prompt */
798 sprintf(prompt_str, "%s %s", cwd, ( geteuid() != 0 ) ? "$ ":"# ");
800 strcpy(prompt_str,"> ");
803 return(strdup(prompt_str)); /* Must free this memory */
808 static char* setup_prompt_string(int state)
810 char user[9],buf[255],*s;
812 char prompt_str[BUFSIZ];
814 /* Set up the prompt */
816 /* get User Name and setup prompt */
817 strcpy(prompt,( geteuid() != 0 ) ? "$ ":"# ");
818 my_getpwuid(user, geteuid());
821 gethostname(buf, 255);
822 s = strchr(buf, '.');
831 snprintf(prompt_str, BUFSIZ-1, "[%s@%s %s]%s", user, buf,
832 get_last_path_component(cwd), prompt);
834 sprintf(prompt_str, "%s", prompt);
836 return(strdup(prompt_str)); /* Must free this memory */
841 static int get_command(FILE * source, char *command)
845 if (source == NULL) {
846 if (local_pending_command) {
847 /* a command specified (-c option): return it & mark it done */
848 strcpy(command, local_pending_command);
849 free(local_pending_command);
850 local_pending_command = NULL;
856 if (source == stdin) {
857 prompt_str = setup_prompt_string(shell_context);
859 #ifdef BB_FEATURE_SH_COMMAND_EDITING
861 ** enable command line editing only while a command line
862 ** is actually being read; otherwise, we'll end up bequeathing
863 ** atexit() handlers and other unwanted stuff to our
864 ** child processes (rob@sysgo.de)
866 cmdedit_read_input(prompt_str, command);
871 fputs(prompt_str, stdout);
876 if (!fgets(command, BUFSIZ - 2, source)) {
882 /* remove trailing newline */
888 #ifdef BB_FEATURE_SH_ENVIRONMENT
889 static char* itoa(register int i)
891 static char a[7]; /* Max 7 ints */
892 register char *b = a + sizeof(a) - 1;
900 *--b = '0' + (i % 10);
910 static int expand_arguments(char *command)
912 #ifdef BB_FEATURE_SH_ENVIRONMENT
913 expand_t expand_result;
914 char *src, *dst, *var;
915 int i=0, length, total_length=0, retval;
918 /* get rid of the terminating \n */
921 #ifdef BB_FEATURE_SH_ENVIRONMENT
924 #if ( (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1) ) || defined (__UCLIBC__)
925 /* This first part uses wordexp() which is a wonderful C lib
926 * function which expands nearly everything. */
927 retval = wordexp (command, &expand_result, 0);
928 if (retval == WRDE_NOSPACE) {
929 /* Mem may have been allocated... */
930 wordfree (&expand_result);
931 error_msg("out of space during expansion");
935 /* Some other error. */
936 error_msg("syntax error");
940 /* Convert from char** (one word per string) to a simple char*,
941 * but don't overflow command which is BUFSIZ in length */
943 while (i < expand_result.we_wordc && total_length < BUFSIZ) {
944 length=strlen(expand_result.we_wordv[i])+1;
945 if (BUFSIZ-total_length-length <= 0) {
946 error_msg("out of space during expansion");
949 strcat(command+total_length, expand_result.we_wordv[i++]);
950 strcat(command+total_length, " ");
951 total_length+=length;
953 wordfree (&expand_result);
956 /* Ok. They don't have glibc and they don't have uClibc. Chances are
957 * about 100% they don't have wordexp(), so instead, the best we can do is
958 * use glob, which is better then nothing, but certainly not perfect */
960 /* It turns out that glob is very stupid. We have to feed it
961 * one word at a time since it can't cope with a full string.
962 * Here we convert command (char*) into cmd (char**, one word
966 int flags = GLOB_NOCHECK|GLOB_BRACE|GLOB_TILDE;
968 /* We need a clean copy, so strsep can mess up the copy while
969 * we write stuff into the original in a minute */
970 char * cmd = strdup(command);
971 for (tmpcmd = cmd; (tmpcmd = strsep(&cmd, " \t")) != NULL;) {
974 retval = glob(tmpcmd, flags, NULL, &expand_result);
975 /* We can't haveGLOB_APPEND on the first glob call,
976 * so put it there now */
977 if (! (flags & GLOB_APPEND) )
978 flags |= GLOB_APPEND;
980 if (retval == GLOB_NOSPACE) {
981 /* Mem may have been allocated... */
982 globfree (&expand_result);
983 error_msg("out of space during expansion");
986 if (retval == GLOB_ABORTED || retval == GLOB_NOSYS) {
987 /* Some other error. */
988 error_msg("syntax error");
992 /* Convert from char** (one word per string) to a simple char*,
993 * but don't overflow command which is BUFSIZ in length */
995 if ( expand_result.gl_pathc > 1) {
996 while (i < expand_result.gl_pathc && total_length < BUFSIZ) {
997 length=strlen(expand_result.gl_pathv[i])+1;
998 if (BUFSIZ-total_length-length <= 0) {
999 error_msg("out of space during expansion");
1002 strcat(command+total_length, expand_result.gl_pathv[i++]);
1003 strcat(command+total_length, " ");
1004 total_length+=length;
1010 globfree (&expand_result);
1015 /* FIXME -- this routine (which is only used when folks
1016 * don't have a C library with wordexp) needs a bit of help
1017 * to handle things like 'echo $PATH$0' */
1019 /* Now do the shell variable substitutions which
1020 * wordexp can't do for us, namely $? and $! */
1022 while((dst = strchr(src,'$')) != NULL){
1023 /* Ok -- got a $ -- now clean up any trailing mess */
1025 if (!(var = getenv(dst + 1))) {
1028 var = itoa(last_return_code);
1031 if (last_bg_pid==-1)
1034 var = itoa(last_bg_pid);
1036 /* Everything else like $$, $#, $[0-9], etc should all be
1037 * expanded by wordexp(), so we can in theory skip that stuff
1038 * here, but just to be on the safe side (i.e. since uClibc
1039 * wordexp doesn't do this stuff yet), lets leave it in for
1042 var = itoa(getpid());
1047 case '0':case '1':case '2':case '3':case '4':
1048 case '5':case '6':case '7':case '8':case '9':
1050 int index=*(dst + 1)-48;
1051 if (index >= argc) {
1062 int subst_len = strlen(var);
1064 if ((next_dst=strpbrk(dst+1, " \t~`!$^&*()=|\\{}[];\"'<>?")) == NULL) {
1067 src = (char*)xrealloc(src, strlen(src) - strlen(next_dst)+strlen(var)+1);
1068 /* Move stuff to the end of the string to accommodate filling
1069 * the created gap with the new stuff */
1070 memmove(dst+subst_len, next_dst+1, subst_len);
1071 /* Now copy in the new stuff */
1072 strncpy(dst, var, subst_len+1);
1076 /* Seems we got an un-expandable variable. So delete it. */
1078 if ((next_dst=strpbrk(dst+1, " \t~`!$^&*()=|\\{}[];\"'<>?")) != NULL) {
1079 /* Move stuff to the end of the string to accommodate filling
1080 * the created gap with the new stuff */
1081 memmove(dst, next_dst, next_dst-dst);
1093 /* Return cmd->num_progs as 0 if no command is present (e.g. an empty
1094 line). If a valid command is found, command_ptr is set to point to
1095 the beginning of the next command (if the original command had more
1096 then one job associated with it) or NULL if no more commands are
1098 static int parse_command(char **command_ptr, struct job *job, int *inbg)
1101 char *return_command = NULL;
1102 char *src, *buf, *chptr;
1109 struct child_prog *prog;
1111 /* skip leading white space */
1112 while (**command_ptr && isspace(**command_ptr))
1115 /* this handles empty lines or leading '#' characters */
1116 if (!**command_ptr || (**command_ptr == '#')) {
1123 job->progs = xmalloc(sizeof(*job->progs));
1125 /* We set the argv elements to point inside of this string. The
1126 memory is freed by free_job(). Allocate twice the original
1127 length in case we need to quote every single character.
1129 Getting clean memory relieves us of the task of NULL
1130 terminating things and makes the rest of this look a bit
1131 cleaner (though it is, admittedly, a tad less efficient) */
1132 job->cmdbuf = command = xcalloc(2*strlen(*command_ptr) + 1, sizeof(char));
1136 prog->num_redirects = 0;
1137 prog->redirects = NULL;
1138 prog->is_stopped = 0;
1142 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1143 prog->argv[0] = job->cmdbuf;
1147 while (*src && !done) {
1148 if (quote == *src) {
1154 error_msg("character expected after \\");
1159 /* in shell, "\'" should yield \' */
1160 if (*src != quote) {
1164 } else if (*src == '*' || *src == '?' || *src == '[' ||
1165 *src == ']') *buf++ = '\\';
1167 } else if (isspace(*src)) {
1168 if (*prog->argv[argc_l]) {
1170 /* +1 here leaves room for the NULL which ends argv */
1171 if ((argc_l + 1) == argv_alloced) {
1173 prog->argv = xrealloc(prog->argv,
1174 sizeof(*prog->argv) *
1177 prog->argv[argc_l] = buf;
1186 case '#': /* comment */
1193 case '>': /* redirects */
1195 i = prog->num_redirects++;
1196 prog->redirects = xrealloc(prog->redirects,
1197 sizeof(*prog->redirects) *
1200 prog->redirects[i].fd = -1;
1201 if (buf != prog->argv[argc_l]) {
1202 /* the stuff before this character may be the file number
1204 prog->redirects[i].fd =
1205 strtol(prog->argv[argc_l], &chptr, 10);
1207 if (*chptr && *prog->argv[argc_l]) {
1209 prog->argv[argc_l] = buf;
1213 if (prog->redirects[i].fd == -1) {
1215 prog->redirects[i].fd = 1;
1217 prog->redirects[i].fd = 0;
1220 if (*src++ == '>') {
1222 prog->redirects[i].type =
1223 REDIRECT_APPEND, src++;
1225 prog->redirects[i].type = REDIRECT_OVERWRITE;
1227 prog->redirects[i].type = REDIRECT_INPUT;
1230 /* This isn't POSIX sh compliant. Oh well. */
1232 while (isspace(*chptr))
1236 error_msg("file name expected after %c", *src);
1242 prog->redirects[i].filename = buf;
1243 while (*chptr && !isspace(*chptr))
1246 src = chptr - 1; /* we src++ later */
1247 prog->argv[argc_l] = ++buf;
1250 case '|': /* pipe */
1251 /* finish this command */
1252 if (*prog->argv[argc_l])
1255 error_msg("empty command in pipe");
1260 prog->argv[argc_l] = NULL;
1262 /* and start the next */
1264 job->progs = xrealloc(job->progs,
1265 sizeof(*job->progs) * job->num_progs);
1266 prog = job->progs + (job->num_progs - 1);
1267 prog->num_redirects = 0;
1268 prog->redirects = NULL;
1269 prog->is_stopped = 0;
1274 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1275 prog->argv[0] = ++buf;
1278 while (*src && isspace(*src))
1282 error_msg("empty command in pipe");
1287 src--; /* we'll ++ it at the end of the loop */
1291 case '&': /* background */
1293 case ';': /* multiple commands */
1295 return_command = *command_ptr + (src - *command_ptr) + 1;
1298 #ifdef BB_FEATURE_SH_BACKTICKS
1300 /* Exec a backtick-ed command */
1301 /* Besides any previous brokenness, I have not
1302 * updated backtick handling for close_me support.
1303 * I don't know if it needs it or not. -- LRD */
1305 char* charptr1=NULL, *charptr2;
1308 struct jobset njob_list = { NULL, NULL };
1312 ptr=strchr(++src, '`');
1314 fprintf(stderr, "Unmatched '`' in command\n");
1319 /* Make some space to hold just the backticked command */
1320 charptr1 = charptr2 = xmalloc(1+ptr-src);
1321 memcpy(charptr1, src, ptr-src);
1322 charptr1[ptr-src] = '\0';
1323 newjob = xmalloc(sizeof(struct job));
1324 newjob->job_list = &njob_list;
1325 /* Now parse and run the backticked command */
1326 if (!parse_command(&charptr1, newjob, inbg)
1327 && newjob->num_progs) {
1329 run_command(newjob, 0, pipefd);
1331 checkjobs(job->job_list);
1332 free_job(newjob); /* doesn't actually free newjob,
1333 looks like a memory leak */
1336 /* Make a copy of any stuff left over in the command
1337 * line after the second backtick */
1338 charptr2 = xmalloc(strlen(ptr)+1);
1339 memcpy(charptr2, ptr+1, strlen(ptr));
1342 /* Copy the output from the backtick-ed command into the
1343 * command line, making extra room as needed */
1345 charptr1 = xmalloc(BUFSIZ);
1346 while ( (size=full_read(pipefd[0], charptr1, BUFSIZ-1)) >0) {
1347 int newsize=src - *command_ptr + size + 1 + strlen(charptr2);
1348 if (newsize > BUFSIZ) {
1349 *command_ptr=xrealloc(*command_ptr, newsize);
1351 memcpy(src, charptr1, size);
1359 /* Now paste into the *command_ptr all the stuff
1360 * leftover after the second backtick */
1361 memcpy(src, charptr2, strlen(charptr2)+1);
1364 /* Now recursively call parse_command to deal with the new
1365 * and improved version of the command line with the backtick
1366 * results expanded in place... */
1368 struct jobset *jl=job->job_list;
1372 return(parse_command(command_ptr, job, inbg));
1375 #endif // BB_FEATURE_SH_BACKTICKS
1380 /* This is currently a little broken... */
1381 #ifdef HANDLE_CONTINUATION_CHARS
1382 /* They fed us a continuation char, so continue reading stuff
1383 * on the next line, then tack that onto the end of the current
1387 printf("erik: found a continue char at EOL...\n");
1388 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1389 if (get_command(input, command)) {
1390 error_msg("character expected after \\");
1395 newsize = strlen(*command_ptr) + strlen(command) + 2;
1396 if (newsize > BUFSIZ) {
1397 printf("erik: doing realloc\n");
1398 *command_ptr=xrealloc(*command_ptr, newsize);
1400 printf("erik: A: *command_ptr='%s'\n", *command_ptr);
1401 memcpy(--src, command, strlen(command));
1402 printf("erik: B: *command_ptr='%s'\n", *command_ptr);
1406 error_msg("character expected after \\");
1412 if (*src == '*' || *src == '[' || *src == ']'
1413 || *src == '?') *buf++ = '\\';
1422 if (*prog->argv[argc_l]) {
1429 prog->argv[argc_l] = NULL;
1431 if (!return_command) {
1432 job->text = xmalloc(strlen(*command_ptr) + 1);
1433 strcpy(job->text, *command_ptr);
1435 /* This leaves any trailing spaces, which is a bit sloppy */
1436 count = return_command - *command_ptr;
1437 job->text = xmalloc(count + 1);
1438 strncpy(job->text, *command_ptr, count);
1439 job->text[count] = '\0';
1442 *command_ptr = return_command;
1447 /* Run the child_prog, no matter what kind of command it uses.
1449 static int pseudo_exec(struct child_prog *child)
1451 struct built_in_command *x;
1452 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
1456 /* Check if the command matches any of the non-forking builtins.
1457 * Depending on context, this might be redundant. But it's
1458 * easier to waste a few CPU cycles than it is to figure out
1459 * if this is one of those cases.
1461 for (x = bltins; x->cmd; x++) {
1462 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1463 exit(x->function(child));
1467 /* Check if the command matches any of the forking builtins. */
1468 for (x = bltins_forking; x->cmd; x++) {
1469 if (strcmp(child->argv[0], x->cmd) == 0) {
1471 exit (x->function(child));
1474 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
1475 /* Check if the command matches any busybox internal
1476 * commands ("applets") here. Following discussions from
1477 * November 2000 on busybox@opensource.lineo.com, don't use
1478 * get_last_path_component(). This way explicit (with
1479 * slashes) filenames will never be interpreted as an
1480 * applet, just like with builtins. This way the user can
1481 * override an applet with an explicit filename reference.
1482 * The only downside to this change is that an explicit
1483 * /bin/foo invocation will fork and exec /bin/foo, even if
1484 * /bin/foo is a symlink to busybox.
1486 name = child->argv[0];
1488 #ifdef BB_FEATURE_SH_APPLETS_ALWAYS_WIN
1489 /* If you enable BB_FEATURE_SH_APPLETS_ALWAYS_WIN, then
1490 * if you run /bin/cat, it will use BusyBox cat even if
1491 * /bin/cat exists on the filesystem and is _not_ busybox.
1492 * Some systems want this, others do not. Choose wisely. :-)
1494 name = get_last_path_component(name);
1498 char** argv=child->argv;
1500 for(argc_l=0;*argv!=NULL; argv++, argc_l++);
1502 run_applet_by_name(name, argc_l, child->argv);
1506 execvp(child->argv[0], child->argv);
1507 perror_msg_and_die("%s", child->argv[0]);
1510 static void insert_job(struct job *newjob, int inbg)
1513 struct jobset *job_list=newjob->job_list;
1515 /* find the ID for thejob to use */
1517 for (thejob = job_list->head; thejob; thejob = thejob->next)
1518 if (thejob->jobid >= newjob->jobid)
1519 newjob->jobid = thejob->jobid + 1;
1521 /* add thejob to the list of running jobs */
1522 if (!job_list->head) {
1523 thejob = job_list->head = xmalloc(sizeof(*thejob));
1525 for (thejob = job_list->head; thejob->next; thejob = thejob->next) /* nothing */;
1526 thejob->next = xmalloc(sizeof(*thejob));
1527 thejob = thejob->next;
1530 *thejob = *newjob; /* physically copy the struct job */
1531 thejob->next = NULL;
1532 thejob->running_progs = thejob->num_progs;
1533 thejob->stopped_progs = 0;
1536 /* we don't wait for background thejobs to return -- append it
1537 to the list of backgrounded thejobs and leave it alone */
1538 printf("[%d] %d\n", thejob->jobid,
1539 newjob->progs[newjob->num_progs - 1].pid);
1540 #ifdef BB_FEATURE_SH_ENVIRONMENT
1541 last_bg_pid=newjob->progs[newjob->num_progs - 1].pid;
1544 newjob->job_list->fg = thejob;
1546 /* move the new process group into the foreground */
1547 /* suppress messages when run from /linuxrc mag@sysgo.de */
1548 if (tcsetpgrp(0, newjob->pgrp) && errno != ENOTTY)
1549 perror_msg("tcsetpgrp");
1553 static int run_command(struct job *newjob, int inbg, int outpipe[2])
1555 /* struct job *thejob; */
1557 int nextin, nextout;
1558 int pipefds[2]; /* pipefd[0] is for reading */
1559 struct built_in_command *x;
1560 struct child_prog *child;
1562 nextin = 0, nextout = 1;
1563 for (i = 0; i < newjob->num_progs; i++) {
1564 child = & (newjob->progs[i]);
1566 if ((i + 1) < newjob->num_progs) {
1567 if (pipe(pipefds)<0) perror_msg_and_die("pipe");
1568 nextout = pipefds[1];
1570 if (outpipe[1]!=-1) {
1571 nextout = outpipe[1];
1577 #ifdef BB_FEATURE_SH_ENVIRONMENT
1578 if (show_x_trace==TRUE) {
1581 for (j = 0; child->argv[j]; j++) {
1583 fputs(child->argv[j], stderr);
1585 fputc('\n', stderr);
1589 /* Check if the command matches any non-forking builtins,
1590 * but only if this is a simple command.
1591 * Non-forking builtins within pipes have to fork anyway,
1592 * and are handled in pseudo_exec. "echo foo | read bar"
1593 * is doomed to failure, and doesn't work on bash, either.
1595 if (newjob->num_progs == 1) {
1596 for (x = bltins; x->cmd; x++) {
1597 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1598 int squirrel[] = {-1, -1, -1};
1600 setup_redirects(child, squirrel);
1601 rcode = x->function(child);
1602 restore_redirects(squirrel);
1608 if (!(child->pid = fork())) {
1609 signal(SIGTTOU, SIG_DFL);
1613 if (outpipe[1]!=-1) {
1623 dup2(nextout, 2); /* Really? */
1628 /* explicit redirects override pipes */
1629 setup_redirects(child,NULL);
1633 if (outpipe[1]!=-1) {
1637 /* put our child in the process group whose leader is the
1638 first process in this pipe */
1639 setpgid(child->pid, newjob->progs[0].pid);
1645 /* If there isn't another process, nextin is garbage
1646 but it doesn't matter */
1647 nextin = pipefds[0];
1650 newjob->pgrp = newjob->progs[0].pid;
1652 insert_job(newjob, inbg);
1657 static int busy_loop(FILE * input)
1660 char *next_command = NULL;
1666 newjob.job_list = &job_list;
1667 newjob.job_context = DEFAULT_CONTEXT;
1669 /* save current owner of TTY so we can restore it on exit */
1670 parent_pgrp = tcgetpgrp(0);
1672 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1674 /* don't pay any attention to this signal; it just confuses
1675 things and isn't really meant for shells anyway */
1676 signal(SIGTTOU, SIG_IGN);
1680 /* no job is in the foreground */
1682 /* see if any background processes have exited */
1683 checkjobs(&job_list);
1685 if (!next_command) {
1686 if (get_command(input, command))
1688 next_command = command;
1691 if (expand_arguments(next_command) == FALSE) {
1693 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1694 next_command = NULL;
1698 if (!parse_command(&next_command, &newjob, &inbg) &&
1700 int pipefds[2] = {-1,-1};
1701 debug_printf( "job=%p being fed to run_command by busy_loop()'\n", &newjob);
1702 run_command(&newjob, inbg, pipefds);
1706 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1707 next_command = NULL;
1710 /* a job is running in the foreground; wait for it */
1712 while (!job_list.fg->progs[i].pid ||
1713 job_list.fg->progs[i].is_stopped == 1) i++;
1715 if (waitpid(job_list.fg->progs[i].pid, &status, WUNTRACED)<0)
1716 perror_msg_and_die("waitpid(%d)",job_list.fg->progs[i].pid);
1718 if (WIFEXITED(status) || WIFSIGNALED(status)) {
1719 /* the child exited */
1720 job_list.fg->running_progs--;
1721 job_list.fg->progs[i].pid = 0;
1723 #ifdef BB_FEATURE_SH_ENVIRONMENT
1724 last_return_code=WEXITSTATUS(status);
1726 debug_printf("'%s' exited -- return code %d\n",
1727 job_list.fg->text, last_return_code);
1728 if (!job_list.fg->running_progs) {
1730 remove_job(&job_list, job_list.fg);
1734 /* the child was stopped */
1735 job_list.fg->stopped_progs++;
1736 job_list.fg->progs[i].is_stopped = 1;
1738 if (job_list.fg->stopped_progs == job_list.fg->running_progs) {
1739 printf("\n" JOB_STATUS_FORMAT, job_list.fg->jobid,
1740 "Stopped", job_list.fg->text);
1746 /* move the shell to the foreground */
1747 /* suppress messages when run from /linuxrc mag@sysgo.de */
1748 if (tcsetpgrp(0, getpid()) && errno != ENOTTY)
1749 perror_msg("tcsetpgrp");
1755 /* return controlling TTY back to parent process group before exiting */
1756 if (tcsetpgrp(0, parent_pgrp))
1757 perror_msg("tcsetpgrp");
1759 /* return exit status if called with "-c" */
1760 if (input == NULL && WIFEXITED(status))
1761 return WEXITSTATUS(status);
1767 #ifdef BB_FEATURE_CLEAN_UP
1768 void free_memory(void)
1772 if (local_pending_command)
1773 free(local_pending_command);
1775 if (job_list.fg && !job_list.fg->running_progs) {
1776 remove_job(&job_list, job_list.fg);
1782 int shell_main(int argc_l, char **argv_l)
1784 int opt, interactive=FALSE;
1785 FILE *input = stdin;
1789 /* These variables need re-initializing when recursing */
1792 local_pending_command = NULL;
1793 close_me_head = NULL;
1794 job_list.head = NULL;
1796 #ifdef BB_FEATURE_SH_ENVIRONMENT
1802 if (argv[0] && argv[0][0] == '-') {
1804 prof_input = fopen("/etc/profile", "r");
1806 printf( "Couldn't open file '/etc/profile'\n");
1808 int tmp_fd = fileno(prof_input);
1810 /* Now run the file */
1811 busy_loop(prof_input);
1813 mark_closed(tmp_fd);
1817 while ((opt = getopt(argc_l, argv_l, "cxi")) > 0) {
1821 if (local_pending_command != 0)
1822 error_msg_and_die("multiple -c arguments");
1823 local_pending_command = xstrdup(argv[optind]);
1827 #ifdef BB_FEATURE_SH_ENVIRONMENT
1829 show_x_trace = TRUE;
1839 /* A shell is interactive if the `-i' flag was given, or if all of
1840 * the following conditions are met:
1842 * no arguments remaining or the -s flag given
1843 * standard input is a terminal
1844 * standard output is a terminal
1845 * Refer to Posix.2, the description of the `sh' utility. */
1846 if (argv[optind]==NULL && input==stdin &&
1847 isatty(fileno(stdin)) && isatty(fileno(stdout))) {
1850 if (interactive==TRUE) {
1851 //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
1852 /* Looks like they want an interactive shell */
1853 printf( "\n\nBusyBox v%s (%s) Built-in shell (lash)\n", BB_VER, BB_BT);
1854 printf( "Enter 'help' for a list of built-in commands.\n\n");
1855 } else if (local_pending_command==NULL) {
1856 //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
1857 input = xfopen(argv[optind], "r");
1858 mark_open(fileno(input)); /* be lazy, never mark this closed */
1861 /* initialize the cwd -- this is never freed...*/
1862 cwd=(char*)xmalloc(sizeof(char)*MAX_LINE+1);
1863 getcwd(cwd, sizeof(char)*MAX_LINE);
1865 #ifdef BB_FEATURE_CLEAN_UP
1866 atexit(free_memory);
1869 return (busy_loop(input));