1 /* vi: set sw=4 ts=4: */
3 * lash -- the BusyBox Lame-Ass SHell
5 * Copyright (C) 2000 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...
61 #include <sys/ioctl.h>
67 #define MAX_LINE 256 /* size of input buffer for cwd data */
68 #define MAX_READ 128 /* size of input buffer for `read' builtin */
69 #define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
70 extern size_t NUM_APPLETS;
73 enum redir_type { REDIRECT_INPUT, REDIRECT_OVERWRITE,
77 static const unsigned int DEFAULT_CONTEXT=0x1;
78 static const unsigned int IF_TRUE_CONTEXT=0x2;
79 static const unsigned int IF_FALSE_CONTEXT=0x4;
80 static const unsigned int THEN_EXP_CONTEXT=0x8;
81 static const unsigned int ELSE_EXP_CONTEXT=0x10;
85 struct job *head; /* head of list of running jobs */
86 struct job *fg; /* current foreground job */
90 enum redir_type type; /* type of redirection */
91 int fd; /* file descriptor being redirected */
92 char *filename; /* file to redirect fd to */
96 pid_t pid; /* 0 if exited */
97 char **argv; /* program name and arguments */
98 int num_redirects; /* elements in redirection array */
99 struct redir_struct *redirects; /* I/O redirects */
100 glob_t glob_result; /* result of parameter globbing */
101 int free_glob; /* should we globfree(&glob_result)? */
102 int is_stopped; /* is the program currently running? */
103 struct job *family; /* pointer back to the child's parent job */
107 int jobid; /* job number */
108 int num_progs; /* total number of programs in job */
109 int running_progs; /* number of programs running */
110 char *text; /* name of job */
111 char *cmdbuf; /* buffer various argv's point into */
112 pid_t pgrp; /* process group ID for the job */
113 struct child_prog *progs; /* array of programs in job */
114 struct job *next; /* to track background commands */
115 int stopped_progs; /* number of programs alive, but stopped */
116 unsigned int job_context; /* bitmask defining current context */
117 struct jobset *job_list;
120 struct built_in_command {
121 char *cmd; /* name */
122 char *descr; /* description */
123 int (*function) (struct child_prog *); /* function ptr */
128 struct close_me *next;
131 /* function prototypes for builtins */
132 static int builtin_cd(struct child_prog *cmd);
133 static int builtin_env(struct child_prog *dummy);
134 static int builtin_exec(struct child_prog *cmd);
135 static int builtin_exit(struct child_prog *cmd);
136 static int builtin_fg_bg(struct child_prog *cmd);
137 static int builtin_help(struct child_prog *cmd);
138 static int builtin_jobs(struct child_prog *dummy);
139 static int builtin_pwd(struct child_prog *dummy);
140 static int builtin_export(struct child_prog *cmd);
141 static int builtin_source(struct child_prog *cmd);
142 static int builtin_unset(struct child_prog *cmd);
143 static int builtin_read(struct child_prog *cmd);
144 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
145 static int builtin_if(struct child_prog *cmd);
146 static int builtin_then(struct child_prog *cmd);
147 static int builtin_else(struct child_prog *cmd);
148 static int builtin_fi(struct child_prog *cmd);
149 /* function prototypes for shell stuff */
150 static int run_command_predicate(char *cmd);
154 /* function prototypes for shell stuff */
155 static void mark_open(int fd);
156 static void mark_closed(int fd);
157 static void checkjobs(struct jobset *job_list);
158 static int get_command(FILE * source, char *command);
159 static int parse_command(char **command_ptr, struct job *job, int *inbg);
160 static int run_command(struct job *newjob, int inbg, int outpipe[2]);
161 static int pseudo_exec(struct child_prog *cmd) __attribute__ ((noreturn));
162 static int busy_loop(FILE * input);
165 /* Table of built-in functions (these are non-forking builtins, meaning they
166 * can change global variables in the parent shell process but they will not
167 * work with pipes and redirects; 'unset foo | whatever' will not work) */
168 static struct built_in_command bltins[] = {
169 {"bg", "Resume a job in the background", builtin_fg_bg},
170 {"cd", "Change working directory", builtin_cd},
171 {"exec", "Exec command, replacing this shell with the exec'd process", builtin_exec},
172 {"exit", "Exit from shell()", builtin_exit},
173 {"fg", "Bring job into the foreground", builtin_fg_bg},
174 {"jobs", "Lists the active jobs", builtin_jobs},
175 {"export", "Set environment variable", builtin_export},
176 {"unset", "Unset environment variable", builtin_unset},
177 {"read", "Input environment variable", builtin_read},
178 {".", "Source-in and run commands in a file", builtin_source},
179 /* to do: add ulimit */
180 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
181 {"if", NULL, builtin_if},
182 {"then", NULL, builtin_then},
183 {"else", NULL, builtin_else},
184 {"fi", NULL, builtin_fi},
189 /* Table of forking built-in functions (things that fork cannot change global
190 * variables in the parent process, such as the current working directory) */
191 static struct built_in_command bltins_forking[] = {
192 {"env", "Print all environment variables", builtin_env},
193 {"pwd", "Print current directory", builtin_pwd},
194 {"help", "List shell built-in commands", builtin_help},
199 /* Variables we export */
200 unsigned int shell_context; /* Used in cmdedit.c to reset the
201 context when someone hits ^C */
204 /* Globals that are static to this file */
206 static char *local_pending_command;
207 static struct jobset job_list = { NULL, NULL };
210 static struct close_me *close_me_head = NULL;
211 #ifdef BB_FEATURE_SH_ENVIRONMENT
212 static int last_bg_pid=-1;
213 static int last_return_code=-1;
214 static int show_x_trace=FALSE;
216 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
217 static char syntax_err[]="syntax error near unexpected token";
221 static inline void debug_printf(const char *format, ...)
224 va_start(args, format);
225 vfprintf(stderr, format, args);
229 static inline void debug_printf(const char *format, ...) { }
233 Most builtins need access to the struct child_prog that has
234 their arguments, previously coded as cmd->progs[0]. That coding
235 can exhibit a bug, if the builtin is not the first command in
236 a pipeline: "echo foo | exec sort" will attempt to exec foo.
238 builtin previous use notes
239 ------ ----------------- ---------
242 exec cmd->progs[0] squashed bug: didn't look for applets or forking builtins
244 fg_bg cmd->progs[0], job_list->head, job_list->fg
248 export cmd->progs[0] passes cmd, job_list to builtin_env(), which ignores them
252 if cmd->job_context, cmd->text
253 then cmd->job_context, cmd->text
254 else cmd->job_context, cmd->text
257 The use of cmd->text by if/then/else/fi is hopelessly hacky.
258 Would it work to increment cmd->progs[0]->argv and recurse,
259 somewhat like builtin_exec does?
261 I added "struct job *family;" to struct child_prog,
262 and switched API to builtin_foo(struct child_prog *child);
263 So cmd->text becomes child->family->text
264 cmd->job_context becomes child->family->job_context
265 cmd->progs[0] becomes *child
266 job_list becomes child->family->job_list
269 /* built-in 'cd <path>' handler */
270 static int builtin_cd(struct child_prog *child)
274 if (child->argv[1] == NULL)
275 newdir = getenv("HOME");
277 newdir = child->argv[1];
279 printf("cd: %s: %s\n", newdir, strerror(errno));
282 getcwd(cwd, sizeof(char)*MAX_LINE);
287 /* built-in 'env' handler */
288 static int builtin_env(struct child_prog *dummy)
292 for (e = environ; *e; e++) {
293 fprintf(stdout, "%s\n", *e);
298 /* built-in 'exec' handler */
299 static int builtin_exec(struct child_prog *child)
301 if (child->argv[1] == NULL)
302 return EXIT_SUCCESS; /* Really? */
308 /* built-in 'exit' handler */
309 static int builtin_exit(struct child_prog *child)
311 if (child->argv[1] == NULL)
314 exit (atoi(child->argv[1]));
317 /* built-in 'fg' and 'bg' handler */
318 static int builtin_fg_bg(struct child_prog *child)
321 struct job *job=NULL;
323 if (!child->argv[1] || child->argv[2]) {
324 error_msg("%s: exactly one argument is expected\n",
329 if (sscanf(child->argv[1], "%%%d", &jobNum) != 1) {
330 error_msg("%s: bad argument '%s'\n",
331 child->argv[0], child->argv[1]);
335 for (job = child->family->job_list->head; job; job = job->next) {
336 if (job->jobid == jobNum) {
342 error_msg("%s: unknown job %d\n",
343 child->argv[0], jobNum);
347 if (*child->argv[0] == 'f') {
348 /* Make this job the foreground job */
349 /* suppress messages when run from /linuxrc mag@sysgo.de */
350 if (tcsetpgrp(0, job->pgrp) && errno != ENOTTY)
351 perror_msg("tcsetpgrp");
352 child->family->job_list->fg = job;
355 /* Restart the processes in the job */
356 for (i = 0; i < job->num_progs; i++)
357 job->progs[i].is_stopped = 0;
359 kill(-job->pgrp, SIGCONT);
361 job->stopped_progs = 0;
366 /* built-in 'help' handler */
367 static int builtin_help(struct child_prog *dummy)
369 struct built_in_command *x;
371 printf("\nBuilt-in commands:\n");
372 printf("-------------------\n");
373 for (x = bltins; x->cmd; x++) {
376 printf("%s\t%s\n", x->cmd, x->descr);
378 for (x = bltins_forking; x->cmd; x++) {
381 printf("%s\t%s\n", x->cmd, x->descr);
387 /* built-in 'jobs' handler */
388 static int builtin_jobs(struct child_prog *child)
393 for (job = child->family->job_list->head; job; job = job->next) {
394 if (job->running_progs == job->stopped_progs)
395 status_string = "Stopped";
397 status_string = "Running";
399 printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->text);
405 /* built-in 'pwd' handler */
406 static int builtin_pwd(struct child_prog *dummy)
408 getcwd(cwd, MAX_LINE);
409 fprintf(stdout, "%s\n", cwd);
413 /* built-in 'export VAR=value' handler */
414 static int builtin_export(struct child_prog *child)
418 if (child->argv[1] == NULL) {
419 return (builtin_env(child));
421 res = putenv(child->argv[1]);
423 fprintf(stderr, "export: %s\n", strerror(errno));
427 /* built-in 'read VAR' handler */
428 static int builtin_read(struct child_prog *child)
430 int res = 0, len, newlen;
432 char string[MAX_READ];
434 if (child->argv[1]) {
435 /* argument (VAR) given: put "VAR=" into buffer */
436 strcpy(string, child->argv[1]);
437 len = strlen(string);
440 fgets(&string[len], sizeof(string) - len, stdin); /* read string */
441 newlen = strlen(string);
443 string[--newlen] = '\0'; /* chomp trailing newline */
445 ** string should now contain "VAR=<value>"
446 ** copy it (putenv() won't do that, so we must make sure
447 ** the string resides in a static buffer!)
450 if((s = strdup(string)))
453 fprintf(stderr, "read: %s\n", strerror(errno));
456 fgets(string, sizeof(string), stdin);
461 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
462 /* Built-in handler for 'if' commands */
463 static int builtin_if(struct child_prog *child)
465 struct job *cmd = child->family;
467 char* charptr1=cmd->text+3; /* skip over the leading 'if ' */
469 /* Now run the 'if' command */
470 debug_printf( "job=%p entering builtin_if ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
471 status = run_command_predicate(charptr1);
472 debug_printf( "if test returned ");
474 debug_printf( "TRUE\n");
475 cmd->job_context |= IF_TRUE_CONTEXT;
477 debug_printf( "FALSE\n");
478 cmd->job_context |= IF_FALSE_CONTEXT;
480 debug_printf("job=%p builtin_if set job context to %x\n", cmd, cmd->job_context);
486 /* Built-in handler for 'then' (part of the 'if' command) */
487 static int builtin_then(struct child_prog *child)
489 struct job *cmd = child->family;
490 char* charptr1=cmd->text+5; /* skip over the leading 'then ' */
492 debug_printf( "job=%p entering builtin_then ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
493 if (! (cmd->job_context & (IF_TRUE_CONTEXT|IF_FALSE_CONTEXT))) {
494 shell_context = 0; /* Reset the shell's context on an error */
495 error_msg("%s `then'\n", syntax_err);
499 cmd->job_context |= THEN_EXP_CONTEXT;
500 debug_printf("job=%p builtin_then set job context to %x\n", cmd, cmd->job_context);
502 /* If the if result was FALSE, skip the 'then' stuff */
503 if (cmd->job_context & IF_FALSE_CONTEXT) {
507 /* Seems the if result was TRUE, so run the 'then' command */
508 debug_printf( "'then' now running '%s'\n", charptr1);
510 return(run_command_predicate(charptr1));
513 /* Built-in handler for 'else' (part of the 'if' command) */
514 static int builtin_else(struct child_prog *child)
516 struct job *cmd = child->family;
517 char* charptr1=cmd->text+5; /* skip over the leading 'else ' */
519 debug_printf( "job=%p entering builtin_else ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
521 if (! (cmd->job_context & THEN_EXP_CONTEXT)) {
522 shell_context = 0; /* Reset the shell's context on an error */
523 error_msg("%s `else'\n", syntax_err);
526 /* If the if result was TRUE, skip the 'else' stuff */
527 if (cmd->job_context & IF_TRUE_CONTEXT) {
531 cmd->job_context |= ELSE_EXP_CONTEXT;
532 debug_printf("job=%p builtin_else set job context to %x\n", cmd, cmd->job_context);
534 /* Now run the 'else' command */
535 debug_printf( "'else' now running '%s'\n", charptr1);
536 return(run_command_predicate(charptr1));
539 /* Built-in handler for 'fi' (part of the 'if' command) */
540 static int builtin_fi(struct child_prog *child)
542 struct job *cmd = child->family;
543 debug_printf( "job=%p entering builtin_fi ('%s')-- context=%d\n", cmd, "", cmd->job_context);
544 if (! (cmd->job_context & (IF_TRUE_CONTEXT|IF_FALSE_CONTEXT))) {
545 shell_context = 0; /* Reset the shell's context on an error */
546 error_msg("%s `fi'\n", syntax_err);
549 /* Clear out the if and then context bits */
550 cmd->job_context &= ~(IF_TRUE_CONTEXT|IF_FALSE_CONTEXT|THEN_EXP_CONTEXT|ELSE_EXP_CONTEXT);
551 debug_printf("job=%p builtin_fi set job context to %x\n", cmd, cmd->job_context);
557 /* Built-in '.' handler (read-in and execute commands from file) */
558 static int builtin_source(struct child_prog *child)
564 if (child->argv[1] == NULL)
567 input = fopen(child->argv[1], "r");
569 fprintf(stdout, "Couldn't open file '%s'\n", child->argv[1]);
575 /* Now run the file */
576 status = busy_loop(input);
582 /* built-in 'unset VAR' handler */
583 static int builtin_unset(struct child_prog *child)
585 if (child->argv[1] == NULL) {
586 fprintf(stdout, "unset: parameter required.\n");
589 unsetenv(child->argv[1]);
593 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
594 /* currently used by if/then/else.
596 * Reparsing the command line for this purpose is gross,
597 * incorrect, and fundamentally unfixable; in particular,
598 * think about what happens with command substitution.
599 * We really need to pull out the run, wait, return status
600 * functionality out of busy_loop so we can child->argv++
601 * and use that, without going back through parse_command.
603 static int run_command_predicate(char *cmd)
606 local_pending_command = xmalloc(n+1);
607 strncpy(local_pending_command, cmd, n);
608 local_pending_command[n]='\0';
609 return( busy_loop(NULL));
613 static void mark_open(int fd)
615 struct close_me *new = xmalloc(sizeof(struct close_me));
617 new->next = close_me_head;
621 static void mark_closed(int fd)
623 struct close_me *tmp;
624 if (close_me_head == NULL || close_me_head->fd != fd)
625 error_msg_and_die("corrupt close_me");
627 close_me_head = close_me_head->next;
631 static void close_all()
634 for (c=close_me_head; c; c=c->next) {
637 close_me_head = NULL;
641 /* free up all memory from a job */
642 static void free_job(struct job *cmd)
646 for (i = 0; i < cmd->num_progs; i++) {
647 free(cmd->progs[i].argv);
648 if (cmd->progs[i].redirects)
649 free(cmd->progs[i].redirects);
650 if (cmd->progs[i].free_glob)
651 globfree(&cmd->progs[i].glob_result);
657 memset(cmd, 0, sizeof(struct job));
660 /* remove a job from the job_list */
661 static void remove_job(struct jobset *job_list, struct job *job)
666 if (job == job_list->head) {
667 job_list->head = job->next;
669 prevjob = job_list->head;
670 while (prevjob->next != job)
671 prevjob = prevjob->next;
672 prevjob->next = job->next;
678 /* Checks to see if any background processes have exited -- if they
679 have, figure out why and see if a job has completed */
680 static void checkjobs(struct jobset *job_list)
687 while ((childpid = waitpid(-1, &status, WNOHANG | WUNTRACED)) > 0) {
688 for (job = job_list->head; job; job = job->next) {
690 while (prognum < job->num_progs &&
691 job->progs[prognum].pid != childpid) prognum++;
692 if (prognum < job->num_progs)
696 /* This happens on backticked commands */
700 if (WIFEXITED(status) || WIFSIGNALED(status)) {
702 job->running_progs--;
703 job->progs[prognum].pid = 0;
705 if (!job->running_progs) {
706 printf(JOB_STATUS_FORMAT, job->jobid, "Done", job->text);
707 remove_job(job_list, job);
711 job->stopped_progs++;
712 job->progs[prognum].is_stopped = 1;
714 if (job->stopped_progs == job->num_progs) {
715 printf(JOB_STATUS_FORMAT, job->jobid, "Stopped",
721 if (childpid == -1 && errno != ECHILD)
722 perror_msg("waitpid");
725 /* squirrel != NULL means we squirrel away copies of stdin, stdout,
726 * and stderr if they are redirected. */
727 static int setup_redirects(struct child_prog *prog, int squirrel[])
732 struct redir_struct *redir = prog->redirects;
734 for (i = 0; i < prog->num_redirects; i++, redir++) {
735 switch (redir->type) {
739 case REDIRECT_OVERWRITE:
740 mode = O_WRONLY | O_CREAT | O_TRUNC;
742 case REDIRECT_APPEND:
743 mode = O_WRONLY | O_CREAT | O_APPEND;
747 openfd = open(redir->filename, mode, 0666);
749 /* this could get lost if stderr has been redirected, but
750 bash and ash both lose it as well (though zsh doesn't!) */
751 error_msg("error opening %s: %s\n", redir->filename,
756 if (openfd != redir->fd) {
757 if (squirrel && redir->fd < 3) {
758 squirrel[redir->fd] = dup(redir->fd);
760 dup2(openfd, redir->fd);
768 static void restore_redirects(int squirrel[])
771 for (i=0; i<3; i++) {
774 /* No error checking. I sure wouldn't know what
775 * to do with an error if I found one! */
782 static char* setup_prompt_string(int state)
784 char user[9],buf[255],*s;
786 char prompt_str[BUFSIZ];
788 /* Set up the prompt */
790 /* get User Name and setup prompt */
791 strcpy(prompt,( geteuid() != 0 ) ? "$ ":"# ");
792 my_getpwuid(user, geteuid());
795 gethostname(buf, 255);
796 s = strchr(buf, '.');
805 snprintf(prompt_str, BUFSIZ-1, "[%s@%s %s]%s", user, buf,
806 get_last_path_component(cwd), prompt);
808 sprintf(prompt_str, "%s", prompt);
810 return(strdup(prompt_str)); /* Must free this memory */
813 static int get_command(FILE * source, char *command)
817 if (source == NULL) {
818 if (local_pending_command) {
819 /* a command specified (-c option): return it & mark it done */
820 strcpy(command, local_pending_command);
821 free(local_pending_command);
822 local_pending_command = NULL;
828 if (source == stdin) {
829 prompt_str = setup_prompt_string(shell_context);
831 #ifdef BB_FEATURE_SH_COMMAND_EDITING
833 ** enable command line editing only while a command line
834 ** is actually being read; otherwise, we'll end up bequeathing
835 ** atexit() handlers and other unwanted stuff to our
836 ** child processes (rob@sysgo.de)
839 cmdedit_read_input(prompt_str, command);
844 fputs(prompt_str, stdout);
849 if (!fgets(command, BUFSIZ - 2, source)) {
855 /* remove trailing newline */
856 command[strlen(command) - 1] = '\0';
861 #ifdef BB_FEATURE_SH_ENVIRONMENT
862 static char* itoa(register int i)
864 static char a[7]; /* Max 7 ints */
865 register char *b = a + sizeof(a) - 1;
873 *--b = '0' + (i % 10);
883 static void expand_argument(struct child_prog *prog, int *argcPtr,
884 int *argv_alloced_ptr)
886 int argc_l = *argcPtr;
887 int argv_alloced = *argv_alloced_ptr;
891 char *src, *dst, *var;
893 if (argc_l > 1) { /* cmd->glob_result is already initialized */
895 i = prog->glob_result.gl_pathc;
901 /* do shell variable substitution */
902 if(*prog->argv[argc_l - 1] == '$') {
903 if ((var = getenv(prog->argv[argc_l - 1] + 1))) {
904 prog->argv[argc_l - 1] = var;
906 #ifdef BB_FEATURE_SH_ENVIRONMENT
908 switch(*(prog->argv[argc_l - 1] + 1)) {
910 prog->argv[argc_l - 1] = itoa(last_return_code);
913 prog->argv[argc_l - 1] = itoa(getpid());
916 prog->argv[argc_l - 1] = itoa(argc-1);
920 *(prog->argv[argc_l - 1])='\0';
922 prog->argv[argc_l - 1] = itoa(last_bg_pid);
924 case '0':case '1':case '2':case '3':case '4':
925 case '5':case '6':case '7':case '8':case '9':
927 int index=*(prog->argv[argc_l - 1] + 1)-48;
929 *(prog->argv[argc_l - 1])='\0';
931 prog->argv[argc_l - 1] = argv[index];
940 if (strpbrk(prog->argv[argc_l - 1],"*[]?")!= NULL){
941 rc = glob(prog->argv[argc_l - 1], flags, NULL, &prog->glob_result);
942 if (rc == GLOB_NOSPACE) {
943 error_msg("out of space during glob operation\n");
945 } else if (rc == GLOB_NOMATCH ||
946 (!rc && (prog->glob_result.gl_pathc - i) == 1 &&
947 strcmp(prog->argv[argc_l - 1],
948 prog->glob_result.gl_pathv[i]) == 0)) {
949 /* we need to remove whatever \ quoting is still present */
950 src = dst = prog->argv[argc_l - 1];
954 *dst++ = process_escape_sequence(&src);
962 argv_alloced += (prog->glob_result.gl_pathc - i);
963 prog->argv = xrealloc(prog->argv, argv_alloced * sizeof(*prog->argv));
964 memcpy(prog->argv + (argc_l - 1), prog->glob_result.gl_pathv + i,
965 sizeof(*(prog->argv)) * (prog->glob_result.gl_pathc - i));
966 argc_l += (prog->glob_result.gl_pathc - i - 1);
969 src = dst = prog->argv[argc_l - 1];
973 *dst++ = process_escape_sequence(&src);
981 prog->glob_result.gl_pathc=0;
983 prog->glob_result.gl_pathv=NULL;
985 *argv_alloced_ptr = argv_alloced;
989 /* Return cmd->num_progs as 0 if no command is present (e.g. an empty
990 line). If a valid command is found, command_ptr is set to point to
991 the beginning of the next command (if the original command had more
992 then one job associated with it) or NULL if no more commands are
994 static int parse_command(char **command_ptr, struct job *job, int *inbg)
997 char *return_command = NULL;
998 char *src, *buf, *chptr;
1005 struct child_prog *prog;
1007 /* skip leading white space */
1008 while (**command_ptr && isspace(**command_ptr))
1011 /* this handles empty lines or leading '#' characters */
1012 if (!**command_ptr || (**command_ptr == '#')) {
1019 job->progs = xmalloc(sizeof(*job->progs));
1021 /* We set the argv elements to point inside of this string. The
1022 memory is freed by free_job(). Allocate twice the original
1023 length in case we need to quote every single character.
1025 Getting clean memory relieves us of the task of NULL
1026 terminating things and makes the rest of this look a bit
1027 cleaner (though it is, admittedly, a tad less efficient) */
1028 job->cmdbuf = command = xcalloc(2*strlen(*command_ptr) + 1, sizeof(char));
1032 prog->num_redirects = 0;
1033 prog->redirects = NULL;
1034 prog->free_glob = 0;
1035 prog->is_stopped = 0;
1039 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1040 prog->argv[0] = job->cmdbuf;
1044 while (*src && !done) {
1045 if (quote == *src) {
1051 error_msg("character expected after \\\n");
1056 /* in shell, "\'" should yield \' */
1057 if (*src != quote) {
1061 } else if (*src == '*' || *src == '?' || *src == '[' ||
1062 *src == ']') *buf++ = '\\';
1064 } else if (isspace(*src)) {
1065 if (*prog->argv[argc_l]) {
1067 /* +1 here leaves room for the NULL which ends argv */
1068 if ((argc_l + 1) == argv_alloced) {
1070 prog->argv = xrealloc(prog->argv,
1071 sizeof(*prog->argv) *
1074 expand_argument(prog, &argc_l, &argv_alloced);
1075 prog->argv[argc_l] = buf;
1084 case '#': /* comment */
1091 case '>': /* redirects */
1093 i = prog->num_redirects++;
1094 prog->redirects = xrealloc(prog->redirects,
1095 sizeof(*prog->redirects) *
1098 prog->redirects[i].fd = -1;
1099 if (buf != prog->argv[argc_l]) {
1100 /* the stuff before this character may be the file number
1102 prog->redirects[i].fd =
1103 strtol(prog->argv[argc_l], &chptr, 10);
1105 if (*chptr && *prog->argv[argc_l]) {
1107 expand_argument(prog, &argc_l, &argv_alloced);
1108 prog->argv[argc_l] = buf;
1112 if (prog->redirects[i].fd == -1) {
1114 prog->redirects[i].fd = 1;
1116 prog->redirects[i].fd = 0;
1119 if (*src++ == '>') {
1121 prog->redirects[i].type =
1122 REDIRECT_APPEND, src++;
1124 prog->redirects[i].type = REDIRECT_OVERWRITE;
1126 prog->redirects[i].type = REDIRECT_INPUT;
1129 /* This isn't POSIX sh compliant. Oh well. */
1131 while (isspace(*chptr))
1135 error_msg("file name expected after %c\n", *src);
1141 prog->redirects[i].filename = buf;
1142 while (*chptr && !isspace(*chptr))
1145 src = chptr - 1; /* we src++ later */
1146 prog->argv[argc_l] = ++buf;
1149 case '|': /* pipe */
1150 /* finish this command */
1151 if (*prog->argv[argc_l])
1154 error_msg("empty command in pipe\n");
1159 prog->argv[argc_l] = NULL;
1161 /* and start the next */
1163 job->progs = xrealloc(job->progs,
1164 sizeof(*job->progs) * job->num_progs);
1165 prog = job->progs + (job->num_progs - 1);
1166 prog->num_redirects = 0;
1167 prog->redirects = NULL;
1168 prog->free_glob = 0;
1169 prog->is_stopped = 0;
1174 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1175 prog->argv[0] = ++buf;
1178 while (*src && isspace(*src))
1182 error_msg("empty command in pipe\n");
1187 src--; /* we'll ++ it at the end of the loop */
1191 case '&': /* background */
1193 case ';': /* multiple commands */
1195 return_command = *command_ptr + (src - *command_ptr) + 1;
1198 #ifdef BB_FEATURE_SH_BACKTICKS
1200 /* Exec a backtick-ed command */
1201 /* Besides any previous brokenness, I have not
1202 * updated backtick handling for close_me support.
1203 * I don't know if it needs it or not. -- LRD */
1205 char* charptr1=NULL, *charptr2;
1208 struct jobset njob_list = { NULL, NULL };
1212 ptr=strchr(++src, '`');
1214 fprintf(stderr, "Unmatched '`' in command\n");
1219 /* Make some space to hold just the backticked command */
1220 charptr1 = charptr2 = xmalloc(1+ptr-src);
1221 memcpy(charptr1, src, ptr-src);
1222 charptr1[ptr-src] = '\0';
1223 newjob = xmalloc(sizeof(struct job));
1224 newjob->job_list = &njob_list;
1225 /* Now parse and run the backticked command */
1226 if (!parse_command(&charptr1, newjob, inbg)
1227 && newjob->num_progs) {
1229 run_command(newjob, 0, pipefd);
1231 checkjobs(job->job_list);
1232 free_job(newjob); /* doesn't actually free newjob,
1233 looks like a memory leak */
1236 /* Make a copy of any stuff left over in the command
1237 * line after the second backtick */
1238 charptr2 = xmalloc(strlen(ptr)+1);
1239 memcpy(charptr2, ptr+1, strlen(ptr));
1242 /* Copy the output from the backtick-ed command into the
1243 * command line, making extra room as needed */
1245 charptr1 = xmalloc(BUFSIZ);
1246 while ( (size=full_read(pipefd[0], charptr1, BUFSIZ-1)) >0) {
1247 int newsize=src - *command_ptr + size + 1 + strlen(charptr2);
1248 if (newsize > BUFSIZ) {
1249 *command_ptr=xrealloc(*command_ptr, newsize);
1251 memcpy(src, charptr1, size);
1259 /* Now paste into the *command_ptr all the stuff
1260 * leftover after the second backtick */
1261 memcpy(src, charptr2, strlen(charptr2)+1);
1264 /* Now recursively call parse_command to deal with the new
1265 * and improved version of the command line with the backtick
1266 * results expanded in place... */
1268 struct jobset *jl=job->job_list;
1272 return(parse_command(command_ptr, job, inbg));
1275 #endif // BB_FEATURE_SH_BACKTICKS
1280 /* This is currently a little broken... */
1281 #ifdef HANDLE_CONTINUATION_CHARS
1282 /* They fed us a continuation char, so continue reading stuff
1283 * on the next line, then tack that onto the end of the current
1287 printf("erik: found a continue char at EOL...\n");
1288 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1289 if (get_command(input, command)) {
1290 error_msg("character expected after \\\n");
1295 newsize = strlen(*command_ptr) + strlen(command) + 2;
1296 if (newsize > BUFSIZ) {
1297 printf("erik: doing realloc\n");
1298 *command_ptr=xrealloc(*command_ptr, newsize);
1300 printf("erik: A: *command_ptr='%s'\n", *command_ptr);
1301 memcpy(--src, command, strlen(command));
1302 printf("erik: B: *command_ptr='%s'\n", *command_ptr);
1306 error_msg("character expected after \\\n");
1312 if (*src == '*' || *src == '[' || *src == ']'
1313 || *src == '?') *buf++ = '\\';
1322 if (*prog->argv[argc_l]) {
1324 expand_argument(prog, &argc_l, &argv_alloced);
1330 prog->argv[argc_l] = NULL;
1332 if (!return_command) {
1333 job->text = xmalloc(strlen(*command_ptr) + 1);
1334 strcpy(job->text, *command_ptr);
1336 /* This leaves any trailing spaces, which is a bit sloppy */
1337 count = return_command - *command_ptr;
1338 job->text = xmalloc(count + 1);
1339 strncpy(job->text, *command_ptr, count);
1340 job->text[count] = '\0';
1343 *command_ptr = return_command;
1348 /* Run the child_prog, no matter what kind of command it uses.
1350 static int pseudo_exec(struct child_prog *child)
1352 struct built_in_command *x;
1353 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
1354 struct BB_applet search_applet, *applet;
1357 /* Check if the command matches any of the non-forking builtins.
1358 * Depending on context, this might be redundant. But it's
1359 * easier to waste a few CPU cycles than it is to figure out
1360 * if this is one of those cases.
1362 for (x = bltins; x->cmd; x++) {
1363 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1364 exit(x->function(child));
1368 /* Check if the command matches any of the forking builtins. */
1369 for (x = bltins_forking; x->cmd; x++) {
1370 if (strcmp(child->argv[0], x->cmd) == 0) {
1372 exit (x->function(child));
1375 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
1376 /* Check if the command matches any busybox internal
1377 * commands ("applets") here. Following discussions from
1378 * November 2000 on busybox@opensource.lineo.com, don't use
1379 * get_last_path_component(). This way explicit (with
1380 * slashes) filenames will never be interpreted as an
1381 * applet, just like with builtins. This way the user can
1382 * override an applet with an explicit filename reference.
1383 * The only downside to this change is that an explicit
1384 * /bin/foo invocation will fork and exec /bin/foo, even if
1385 * /bin/foo is a symlink to busybox.
1387 search_applet.name = child->argv[0];
1389 #ifdef BB_FEATURE_SH_APPLETS_ALWAYS_WIN
1390 /* If you enable BB_FEATURE_SH_APPLETS_ALWAYS_WIN, then
1391 * if you run /bin/cat, it will use BusyBox cat even if
1392 * /bin/cat exists on the filesystem and is _not_ busybox.
1393 * Some systems want this, others do not. Choose wisely. :-)
1395 search_applet.name = get_last_path_component(search_applet.name);
1398 /* Do a binary search to find the applet entry given the name. */
1399 applet = bsearch(&search_applet, applets, NUM_APPLETS,
1400 sizeof(struct BB_applet), applet_name_compare);
1401 if (applet != NULL) {
1403 char** argv=child->argv;
1404 for(argc_l=0;*argv!=NULL; argv++, argc_l++);
1405 applet_name=applet->name;
1407 exit((*(applet->main)) (argc_l, child->argv));
1411 execvp(child->argv[0], child->argv);
1412 perror_msg_and_die("%s", child->argv[0]);
1415 static void insert_job(struct job *newjob, int inbg)
1418 struct jobset *job_list=newjob->job_list;
1420 /* find the ID for thejob to use */
1422 for (thejob = job_list->head; thejob; thejob = thejob->next)
1423 if (thejob->jobid >= newjob->jobid)
1424 newjob->jobid = thejob->jobid + 1;
1426 /* add thejob to the list of running jobs */
1427 if (!job_list->head) {
1428 thejob = job_list->head = xmalloc(sizeof(*thejob));
1430 for (thejob = job_list->head; thejob->next; thejob = thejob->next) /* nothing */;
1431 thejob->next = xmalloc(sizeof(*thejob));
1432 thejob = thejob->next;
1435 *thejob = *newjob; /* physically copy the struct job */
1436 thejob->next = NULL;
1437 thejob->running_progs = thejob->num_progs;
1438 thejob->stopped_progs = 0;
1441 /* we don't wait for background thejobs to return -- append it
1442 to the list of backgrounded thejobs and leave it alone */
1443 printf("[%d] %d\n", thejob->jobid,
1444 newjob->progs[newjob->num_progs - 1].pid);
1445 #ifdef BB_FEATURE_SH_ENVIRONMENT
1446 last_bg_pid=newjob->progs[newjob->num_progs - 1].pid;
1449 newjob->job_list->fg = thejob;
1451 /* move the new process group into the foreground */
1452 /* suppress messages when run from /linuxrc mag@sysgo.de */
1453 if (tcsetpgrp(0, newjob->pgrp) && errno != ENOTTY)
1454 perror_msg("tcsetpgrp");
1458 static int run_command(struct job *newjob, int inbg, int outpipe[2])
1460 /* struct job *thejob; */
1462 int nextin, nextout;
1463 int pipefds[2]; /* pipefd[0] is for reading */
1464 struct built_in_command *x;
1465 struct child_prog *child;
1467 nextin = 0, nextout = 1;
1468 for (i = 0; i < newjob->num_progs; i++) {
1469 child = & (newjob->progs[i]);
1471 if ((i + 1) < newjob->num_progs) {
1472 if (pipe(pipefds)<0) perror_msg_and_die("pipe");
1473 nextout = pipefds[1];
1475 if (outpipe[1]!=-1) {
1476 nextout = outpipe[1];
1482 #ifdef BB_FEATURE_SH_ENVIRONMENT
1483 if (show_x_trace==TRUE) {
1486 for (j = 0; child->argv[j]; j++) {
1488 fputs(child->argv[j], stderr);
1490 fputc('\n', stderr);
1494 /* Check if the command matches any non-forking builtins,
1495 * but only if this is a simple command.
1496 * Non-forking builtins within pipes have to fork anyway,
1497 * and are handled in pseudo_exec. "echo foo | read bar"
1498 * is doomed to failure, and doesn't work on bash, either.
1500 if (newjob->num_progs == 1) {
1501 for (x = bltins; x->cmd; x++) {
1502 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1503 int squirrel[] = {-1, -1, -1};
1505 setup_redirects(child, squirrel);
1506 rcode = x->function(child);
1507 restore_redirects(squirrel);
1513 if (!(child->pid = fork())) {
1514 signal(SIGTTOU, SIG_DFL);
1518 if (outpipe[1]!=-1) {
1528 dup2(nextout, 2); /* Really? */
1533 /* explicit redirects override pipes */
1534 setup_redirects(child,NULL);
1538 if (outpipe[1]!=-1) {
1542 /* put our child in the process group whose leader is the
1543 first process in this pipe */
1544 setpgid(child->pid, newjob->progs[0].pid);
1550 /* If there isn't another process, nextin is garbage
1551 but it doesn't matter */
1552 nextin = pipefds[0];
1555 newjob->pgrp = newjob->progs[0].pid;
1557 insert_job(newjob, inbg);
1562 static int busy_loop(FILE * input)
1565 char *next_command = NULL;
1571 newjob.job_list = &job_list;
1572 newjob.job_context = DEFAULT_CONTEXT;
1574 /* save current owner of TTY so we can restore it on exit */
1575 parent_pgrp = tcgetpgrp(0);
1577 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1579 /* don't pay any attention to this signal; it just confuses
1580 things and isn't really meant for shells anyway */
1581 signal(SIGTTOU, SIG_IGN);
1585 /* no job is in the foreground */
1587 /* see if any background processes have exited */
1588 checkjobs(&job_list);
1590 if (!next_command) {
1591 if (get_command(input, command))
1593 next_command = command;
1596 if (!parse_command(&next_command, &newjob, &inbg) &&
1598 int pipefds[2] = {-1,-1};
1599 debug_printf( "job=%p being fed to run_command by busy_loop()'\n", &newjob);
1600 run_command(&newjob, inbg, pipefds);
1604 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1605 next_command = NULL;
1608 /* a job is running in the foreground; wait for it */
1610 while (!job_list.fg->progs[i].pid ||
1611 job_list.fg->progs[i].is_stopped == 1) i++;
1613 if (waitpid(job_list.fg->progs[i].pid, &status, WUNTRACED)<0)
1614 perror_msg_and_die("waitpid(%d)",job_list.fg->progs[i].pid);
1616 if (WIFEXITED(status) || WIFSIGNALED(status)) {
1617 /* the child exited */
1618 job_list.fg->running_progs--;
1619 job_list.fg->progs[i].pid = 0;
1621 #ifdef BB_FEATURE_SH_ENVIRONMENT
1622 last_return_code=WEXITSTATUS(status);
1624 debug_printf("'%s' exited -- return code %d\n",
1625 job_list.fg->text, last_return_code);
1626 if (!job_list.fg->running_progs) {
1628 remove_job(&job_list, job_list.fg);
1632 /* the child was stopped */
1633 job_list.fg->stopped_progs++;
1634 job_list.fg->progs[i].is_stopped = 1;
1636 if (job_list.fg->stopped_progs == job_list.fg->running_progs) {
1637 printf("\n" JOB_STATUS_FORMAT, job_list.fg->jobid,
1638 "Stopped", job_list.fg->text);
1644 /* move the shell to the foreground */
1645 /* suppress messages when run from /linuxrc mag@sysgo.de */
1646 if (tcsetpgrp(0, getpid()) && errno != ENOTTY)
1647 perror_msg("tcsetpgrp");
1653 /* return controlling TTY back to parent process group before exiting */
1654 if (tcsetpgrp(0, parent_pgrp))
1655 perror_msg("tcsetpgrp");
1657 /* return exit status if called with "-c" */
1658 if (input == NULL && WIFEXITED(status))
1659 return WEXITSTATUS(status);
1665 #ifdef BB_FEATURE_CLEAN_UP
1666 void free_memory(void)
1672 if (local_pending_command)
1673 free(local_pending_command);
1675 if (job_list.fg && !job_list.fg->running_progs) {
1676 remove_job(&job_list, job_list.fg);
1682 int shell_main(int argc_l, char **argv_l)
1684 int opt, interactive=FALSE;
1685 FILE *input = stdin;
1691 #ifdef BB_FEATURE_STANDALONE_SHELL
1692 /* These variables need re-initializing when recursing */
1693 local_pending_command = NULL;
1694 job_list.head = NULL;
1696 #ifdef BB_FEATURE_SH_ENVIRONMENT
1698 last_return_code=-1;
1703 if (argv[0] && argv[0][0] == '-') {
1705 prof_input = fopen("/etc/profile", "r");
1707 fprintf(stdout, "Couldn't open file '/etc/profile'\n");
1709 int tmp_fd = fileno(prof_input);
1711 /* Now run the file */
1712 busy_loop(prof_input);
1714 mark_closed(tmp_fd);
1718 while ((opt = getopt(argc_l, argv_l, "cxi")) > 0) {
1722 if (local_pending_command != 0)
1723 error_msg_and_die("multiple -c arguments\n");
1724 local_pending_command = xstrdup(argv[optind]);
1728 #ifdef BB_FEATURE_SH_ENVIRONMENT
1730 show_x_trace = TRUE;
1740 /* A shell is interactive if the `-i' flag was given, or if all of
1741 * the following conditions are met:
1743 * no arguments remaining or the -s flag given
1744 * standard input is a terminal
1745 * standard output is a terminal
1746 * Refer to Posix.2, the description of the `sh' utility. */
1747 if (argv[optind]==NULL && input==stdin &&
1748 isatty(fileno(stdin)) && isatty(fileno(stdout))) {
1751 if (interactive==TRUE) {
1752 //fprintf(stdout, "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
1753 /* Looks like they want an interactive shell */
1754 fprintf(stdout, "\n\nBusyBox v%s (%s) Built-in shell (lash)\n", BB_VER, BB_BT);
1755 fprintf(stdout, "Enter 'help' for a list of built-in commands.\n\n");
1756 } else if (local_pending_command==NULL) {
1757 //fprintf(stdout, "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
1758 input = xfopen(argv[optind], "r");
1759 mark_open(fileno(input)); /* be lazy, never mark this closed */
1762 /* initialize the cwd -- this is never freed...*/
1763 cwd=(char*)xmalloc(sizeof(char)*MAX_LINE+1);
1764 getcwd(cwd, sizeof(char)*MAX_LINE);
1766 #ifdef BB_FEATURE_CLEAN_UP
1767 atexit(free_memory);
1770 return (busy_loop(input));