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...
60 #include <sys/ioctl.h>
67 static const int MAX_LINE = 256; /* size of input buffer for cwd data */
68 static const int MAX_READ = 128; /* size of input buffer for `read' builtin */
69 #define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
72 enum redir_type { REDIRECT_INPUT, REDIRECT_OVERWRITE,
76 static const unsigned int DEFAULT_CONTEXT=0x1;
77 static const unsigned int IF_TRUE_CONTEXT=0x2;
78 static const unsigned int IF_FALSE_CONTEXT=0x4;
79 static const unsigned int THEN_EXP_CONTEXT=0x8;
80 static const unsigned int ELSE_EXP_CONTEXT=0x10;
84 struct job *head; /* head of list of running jobs */
85 struct job *fg; /* current foreground job */
89 enum redir_type type; /* type of redirection */
90 int fd; /* file descriptor being redirected */
91 char *filename; /* file to redirect fd to */
95 pid_t pid; /* 0 if exited */
96 char **argv; /* program name and arguments */
97 int num_redirects; /* elements in redirection array */
98 struct redir_struct *redirects; /* I/O redirects */
99 glob_t glob_result; /* result of parameter globbing */
100 int free_glob; /* should we globfree(&glob_result)? */
101 int is_stopped; /* is the program currently running? */
102 struct job *family; /* pointer back to the child's parent job */
106 int jobid; /* job number */
107 int num_progs; /* total number of programs in job */
108 int running_progs; /* number of programs running */
109 char *text; /* name of job */
110 char *cmdbuf; /* buffer various argv's point into */
111 pid_t pgrp; /* process group ID for the job */
112 struct child_prog *progs; /* array of programs in job */
113 struct job *next; /* to track background commands */
114 int stopped_progs; /* number of programs alive, but stopped */
115 unsigned int job_context; /* bitmask defining current context */
116 struct jobset *job_list;
119 struct built_in_command {
120 char *cmd; /* name */
121 char *descr; /* description */
122 int (*function) (struct child_prog *); /* function ptr */
127 struct close_me *next;
130 /* function prototypes for builtins */
131 static int builtin_cd(struct child_prog *cmd);
132 static int builtin_env(struct child_prog *dummy);
133 static int builtin_exec(struct child_prog *cmd);
134 static int builtin_exit(struct child_prog *cmd);
135 static int builtin_fg_bg(struct child_prog *cmd);
136 static int builtin_help(struct child_prog *cmd);
137 static int builtin_jobs(struct child_prog *dummy);
138 static int builtin_pwd(struct child_prog *dummy);
139 static int builtin_export(struct child_prog *cmd);
140 static int builtin_source(struct child_prog *cmd);
141 static int builtin_unset(struct child_prog *cmd);
142 static int builtin_read(struct child_prog *cmd);
143 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
144 static int builtin_if(struct child_prog *cmd);
145 static int builtin_then(struct child_prog *cmd);
146 static int builtin_else(struct child_prog *cmd);
147 static int builtin_fi(struct child_prog *cmd);
148 /* function prototypes for shell stuff */
149 static int run_command_predicate(char *cmd);
153 /* function prototypes for shell stuff */
154 static void mark_open(int fd);
155 static void mark_closed(int fd);
156 static void close_all(void);
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 = NULL;
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++) {
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? */
309 /* built-in 'exit' handler */
310 static int builtin_exit(struct child_prog *child)
312 if (child->argv[1] == NULL)
315 exit (atoi(child->argv[1]));
318 /* built-in 'fg' and 'bg' handler */
319 static int builtin_fg_bg(struct child_prog *child)
322 struct job *job=NULL;
324 if (!child->argv[1] || child->argv[2]) {
325 error_msg("%s: exactly one argument is expected",
330 if (sscanf(child->argv[1], "%%%d", &jobNum) != 1) {
331 error_msg("%s: bad argument '%s'",
332 child->argv[0], child->argv[1]);
336 for (job = child->family->job_list->head; job; job = job->next) {
337 if (job->jobid == jobNum) {
343 error_msg("%s: unknown job %d",
344 child->argv[0], jobNum);
348 if (*child->argv[0] == 'f') {
349 /* Make this job the foreground job */
350 /* suppress messages when run from /linuxrc mag@sysgo.de */
351 if (tcsetpgrp(0, job->pgrp) && errno != ENOTTY)
352 perror_msg("tcsetpgrp");
353 child->family->job_list->fg = job;
356 /* Restart the processes in the job */
357 for (i = 0; i < job->num_progs; i++)
358 job->progs[i].is_stopped = 0;
360 kill(-job->pgrp, SIGCONT);
362 job->stopped_progs = 0;
367 /* built-in 'help' handler */
368 static int builtin_help(struct child_prog *dummy)
370 struct built_in_command *x;
372 printf("\nBuilt-in commands:\n");
373 printf("-------------------\n");
374 for (x = bltins; x->cmd; x++) {
377 printf("%s\t%s\n", x->cmd, x->descr);
379 for (x = bltins_forking; x->cmd; x++) {
382 printf("%s\t%s\n", x->cmd, x->descr);
388 /* built-in 'jobs' handler */
389 static int builtin_jobs(struct child_prog *child)
394 for (job = child->family->job_list->head; job; job = job->next) {
395 if (job->running_progs == job->stopped_progs)
396 status_string = "Stopped";
398 status_string = "Running";
400 printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->text);
406 /* built-in 'pwd' handler */
407 static int builtin_pwd(struct child_prog *dummy)
409 getcwd(cwd, MAX_LINE);
410 printf( "%s\n", cwd);
414 /* built-in 'export VAR=value' handler */
415 static int builtin_export(struct child_prog *child)
419 if (child->argv[1] == NULL) {
420 return (builtin_env(child));
422 res = putenv(child->argv[1]);
424 fprintf(stderr, "export: %s\n", strerror(errno));
428 /* built-in 'read VAR' handler */
429 static int builtin_read(struct child_prog *child)
431 int res = 0, len, newlen;
433 char string[MAX_READ];
435 if (child->argv[1]) {
436 /* argument (VAR) given: put "VAR=" into buffer */
437 strcpy(string, child->argv[1]);
438 len = strlen(string);
441 fgets(&string[len], sizeof(string) - len, stdin); /* read string */
442 newlen = strlen(string);
444 string[--newlen] = '\0'; /* chomp trailing newline */
446 ** string should now contain "VAR=<value>"
447 ** copy it (putenv() won't do that, so we must make sure
448 ** the string resides in a static buffer!)
451 if((s = strdup(string)))
454 fprintf(stderr, "read: %s\n", strerror(errno));
457 fgets(string, sizeof(string), stdin);
462 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
463 /* Built-in handler for 'if' commands */
464 static int builtin_if(struct child_prog *child)
466 struct job *cmd = child->family;
468 char* charptr1=cmd->text+3; /* skip over the leading 'if ' */
470 /* Now run the 'if' command */
471 debug_printf( "job=%p entering builtin_if ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
472 status = run_command_predicate(charptr1);
473 debug_printf( "if test returned ");
475 debug_printf( "TRUE\n");
476 cmd->job_context |= IF_TRUE_CONTEXT;
478 debug_printf( "FALSE\n");
479 cmd->job_context |= IF_FALSE_CONTEXT;
481 debug_printf("job=%p builtin_if set job context to %x\n", cmd, cmd->job_context);
487 /* Built-in handler for 'then' (part of the 'if' command) */
488 static int builtin_then(struct child_prog *child)
490 struct job *cmd = child->family;
491 char* charptr1=cmd->text+5; /* skip over the leading 'then ' */
493 debug_printf( "job=%p entering builtin_then ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
494 if (! (cmd->job_context & (IF_TRUE_CONTEXT|IF_FALSE_CONTEXT))) {
495 shell_context = 0; /* Reset the shell's context on an error */
496 error_msg("%s `then'", syntax_err);
500 cmd->job_context |= THEN_EXP_CONTEXT;
501 debug_printf("job=%p builtin_then set job context to %x\n", cmd, cmd->job_context);
503 /* If the if result was FALSE, skip the 'then' stuff */
504 if (cmd->job_context & IF_FALSE_CONTEXT) {
508 /* Seems the if result was TRUE, so run the 'then' command */
509 debug_printf( "'then' now running '%s'\n", charptr1);
511 return(run_command_predicate(charptr1));
514 /* Built-in handler for 'else' (part of the 'if' command) */
515 static int builtin_else(struct child_prog *child)
517 struct job *cmd = child->family;
518 char* charptr1=cmd->text+5; /* skip over the leading 'else ' */
520 debug_printf( "job=%p entering builtin_else ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
522 if (! (cmd->job_context & THEN_EXP_CONTEXT)) {
523 shell_context = 0; /* Reset the shell's context on an error */
524 error_msg("%s `else'", syntax_err);
527 /* If the if result was TRUE, skip the 'else' stuff */
528 if (cmd->job_context & IF_TRUE_CONTEXT) {
532 cmd->job_context |= ELSE_EXP_CONTEXT;
533 debug_printf("job=%p builtin_else set job context to %x\n", cmd, cmd->job_context);
535 /* Now run the 'else' command */
536 debug_printf( "'else' now running '%s'\n", charptr1);
537 return(run_command_predicate(charptr1));
540 /* Built-in handler for 'fi' (part of the 'if' command) */
541 static int builtin_fi(struct child_prog *child)
543 struct job *cmd = child->family;
544 debug_printf( "job=%p entering builtin_fi ('%s')-- context=%d\n", cmd, "", cmd->job_context);
545 if (! (cmd->job_context & (IF_TRUE_CONTEXT|IF_FALSE_CONTEXT))) {
546 shell_context = 0; /* Reset the shell's context on an error */
547 error_msg("%s `fi'", syntax_err);
550 /* Clear out the if and then context bits */
551 cmd->job_context &= ~(IF_TRUE_CONTEXT|IF_FALSE_CONTEXT|THEN_EXP_CONTEXT|ELSE_EXP_CONTEXT);
552 debug_printf("job=%p builtin_fi set job context to %x\n", cmd, cmd->job_context);
558 /* Built-in '.' handler (read-in and execute commands from file) */
559 static int builtin_source(struct child_prog *child)
565 if (child->argv[1] == NULL)
568 input = fopen(child->argv[1], "r");
570 printf( "Couldn't open file '%s'\n", child->argv[1]);
576 /* Now run the file */
577 status = busy_loop(input);
583 /* built-in 'unset VAR' handler */
584 static int builtin_unset(struct child_prog *child)
586 if (child->argv[1] == NULL) {
587 printf( "unset: parameter required.\n");
590 unsetenv(child->argv[1]);
594 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
595 /* currently used by if/then/else.
597 * Reparsing the command line for this purpose is gross,
598 * incorrect, and fundamentally unfixable; in particular,
599 * think about what happens with command substitution.
600 * We really need to pull out the run, wait, return status
601 * functionality out of busy_loop so we can child->argv++
602 * and use that, without going back through parse_command.
604 static int run_command_predicate(char *cmd)
607 local_pending_command = xmalloc(n+1);
608 strncpy(local_pending_command, cmd, n);
609 local_pending_command[n]='\0';
610 return( busy_loop(NULL));
614 static void mark_open(int fd)
616 struct close_me *new = xmalloc(sizeof(struct close_me));
618 new->next = close_me_head;
622 static void mark_closed(int fd)
624 struct close_me *tmp;
625 if (close_me_head == NULL || close_me_head->fd != fd)
626 error_msg_and_die("corrupt close_me");
628 close_me_head = close_me_head->next;
632 static void close_all()
635 for (c=close_me_head; c; c=c->next) {
638 close_me_head = NULL;
642 /* free up all memory from a job */
643 static void free_job(struct job *cmd)
647 for (i = 0; i < cmd->num_progs; i++) {
648 free(cmd->progs[i].argv);
649 if (cmd->progs[i].redirects)
650 free(cmd->progs[i].redirects);
651 if (cmd->progs[i].free_glob)
652 globfree(&cmd->progs[i].glob_result);
658 memset(cmd, 0, sizeof(struct job));
661 /* remove a job from the job_list */
662 static void remove_job(struct jobset *job_list, struct job *job)
667 if (job == job_list->head) {
668 job_list->head = job->next;
670 prevjob = job_list->head;
671 while (prevjob->next != job)
672 prevjob = prevjob->next;
673 prevjob->next = job->next;
679 /* Checks to see if any background processes have exited -- if they
680 have, figure out why and see if a job has completed */
681 static void checkjobs(struct jobset *job_list)
688 while ((childpid = waitpid(-1, &status, WNOHANG | WUNTRACED)) > 0) {
689 for (job = job_list->head; job; job = job->next) {
691 while (prognum < job->num_progs &&
692 job->progs[prognum].pid != childpid) prognum++;
693 if (prognum < job->num_progs)
697 /* This happens on backticked commands */
701 if (WIFEXITED(status) || WIFSIGNALED(status)) {
703 job->running_progs--;
704 job->progs[prognum].pid = 0;
706 if (!job->running_progs) {
707 printf(JOB_STATUS_FORMAT, job->jobid, "Done", job->text);
708 remove_job(job_list, job);
712 job->stopped_progs++;
713 job->progs[prognum].is_stopped = 1;
715 if (job->stopped_progs == job->num_progs) {
716 printf(JOB_STATUS_FORMAT, job->jobid, "Stopped",
722 if (childpid == -1 && errno != ECHILD)
723 perror_msg("waitpid");
726 /* squirrel != NULL means we squirrel away copies of stdin, stdout,
727 * and stderr if they are redirected. */
728 static int setup_redirects(struct child_prog *prog, int squirrel[])
733 struct redir_struct *redir = prog->redirects;
735 for (i = 0; i < prog->num_redirects; i++, redir++) {
736 switch (redir->type) {
740 case REDIRECT_OVERWRITE:
741 mode = O_WRONLY | O_CREAT | O_TRUNC;
743 case REDIRECT_APPEND:
744 mode = O_WRONLY | O_CREAT | O_APPEND;
748 openfd = open(redir->filename, mode, 0666);
750 /* this could get lost if stderr has been redirected, but
751 bash and ash both lose it as well (though zsh doesn't!) */
752 error_msg("error opening %s: %s", redir->filename,
757 if (openfd != redir->fd) {
758 if (squirrel && redir->fd < 3) {
759 squirrel[redir->fd] = dup(redir->fd);
761 dup2(openfd, redir->fd);
769 static void restore_redirects(int squirrel[])
772 for (i=0; i<3; i++) {
775 /* No error checking. I sure wouldn't know what
776 * to do with an error if I found one! */
783 #if defined(BB_FEATURE_SH_SIMPLE_PROMPT)
784 static char* setup_prompt_string(int state)
786 char prompt_str[BUFSIZ];
788 /* Set up the prompt */
791 sprintf(prompt_str, "%s %s", cwd, ( geteuid() != 0 ) ? "$ ":"# ");
793 strcpy(prompt_str,"> ");
796 return(strdup(prompt_str)); /* Must free this memory */
801 static char* setup_prompt_string(int state)
803 char user[9],buf[255],*s;
805 char prompt_str[BUFSIZ];
807 /* Set up the prompt */
809 /* get User Name and setup prompt */
810 strcpy(prompt,( geteuid() != 0 ) ? "$ ":"# ");
811 my_getpwuid(user, geteuid());
814 gethostname(buf, 255);
815 s = strchr(buf, '.');
824 snprintf(prompt_str, BUFSIZ-1, "[%s@%s %s]%s", user, buf,
825 get_last_path_component(cwd), prompt);
827 sprintf(prompt_str, "%s", prompt);
829 return(strdup(prompt_str)); /* Must free this memory */
834 static int get_command(FILE * source, char *command)
838 if (source == NULL) {
839 if (local_pending_command) {
840 /* a command specified (-c option): return it & mark it done */
841 strcpy(command, local_pending_command);
842 free(local_pending_command);
843 local_pending_command = NULL;
849 if (source == stdin) {
850 prompt_str = setup_prompt_string(shell_context);
852 #ifdef BB_FEATURE_SH_COMMAND_EDITING
854 ** enable command line editing only while a command line
855 ** is actually being read; otherwise, we'll end up bequeathing
856 ** atexit() handlers and other unwanted stuff to our
857 ** child processes (rob@sysgo.de)
859 cmdedit_read_input(prompt_str, command);
864 fputs(prompt_str, stdout);
869 if (!fgets(command, BUFSIZ - 2, source)) {
875 /* remove trailing newline */
876 command[strlen(command) - 1] = '\0';
881 #ifdef BB_FEATURE_SH_ENVIRONMENT
882 static char* itoa(register int i)
884 static char a[7]; /* Max 7 ints */
885 register char *b = a + sizeof(a) - 1;
893 *--b = '0' + (i % 10);
903 static void expand_argument(struct child_prog *prog, int *argcPtr,
904 int *argv_alloced_ptr)
906 int argc_l = *argcPtr;
907 int argv_alloced = *argv_alloced_ptr;
911 char *src, *dst, *var;
913 if (argc_l > 1) { /* cmd->glob_result is already initialized */
915 i = prog->glob_result.gl_pathc;
921 #ifdef BB_FEATURE_SH_ENVIRONMENT
922 /* do shell variable substitution */
923 src = prog->argv[argc_l - 1];
924 while((dst = strchr(src,'$')) != NULL){
925 if (!(var = getenv(dst + 1))) {
928 var = itoa(last_return_code);
931 var = itoa(getpid());
940 var = itoa(last_bg_pid);
942 case '0':case '1':case '2':case '3':case '4':
943 case '5':case '6':case '7':case '8':case '9':
945 int index=*(dst + 1)-48;
956 int offset = dst-src;
957 #warning I have a memory leak which needs to be plugged somehow
958 src = (char*)xmalloc(strlen(src)-strlen(dst)+strlen(var)+1);
959 strncpy(src, prog->argv[argc_l -1], offset);
960 safe_strncpy(src+offset, var, strlen(var)+1);
961 /* If there are any remaining $ variables in the src string, put them back */
962 if ((dst = strchr(prog->argv[argc_l -1]+offset+1,'$')) != NULL) {
964 safe_strncpy(src+strlen(src), dst, strlen(dst)+1);
966 prog->argv[argc_l -1] = src;
968 memset(dst, 0, strlen(src)-strlen(dst));
973 if (strpbrk(prog->argv[argc_l - 1],"*[]?")!= NULL){
974 rc = glob(prog->argv[argc_l - 1], flags, NULL, &prog->glob_result);
975 if (rc == GLOB_NOSPACE) {
976 error_msg("out of space during glob operation");
978 } else if (rc == GLOB_NOMATCH ||
979 (!rc && (prog->glob_result.gl_pathc - i) == 1 &&
980 strcmp(prog->argv[argc_l - 1],
981 prog->glob_result.gl_pathv[i]) == 0)) {
982 /* we need to remove whatever \ quoting is still present */
983 src = dst = prog->argv[argc_l - 1];
987 *dst++ = process_escape_sequence(&src);
995 argv_alloced += (prog->glob_result.gl_pathc - i);
996 prog->argv = xrealloc(prog->argv, argv_alloced * sizeof(*prog->argv));
997 memcpy(prog->argv + (argc_l - 1), prog->glob_result.gl_pathv + i,
998 sizeof(*(prog->argv)) * (prog->glob_result.gl_pathc - i));
999 argc_l += (prog->glob_result.gl_pathc - i - 1);
1002 src = dst = prog->argv[argc_l - 1];
1006 *dst++ = process_escape_sequence(&src);
1014 prog->glob_result.gl_pathc=0;
1016 prog->glob_result.gl_pathv=NULL;
1018 *argv_alloced_ptr = argv_alloced;
1022 /* Return cmd->num_progs as 0 if no command is present (e.g. an empty
1023 line). If a valid command is found, command_ptr is set to point to
1024 the beginning of the next command (if the original command had more
1025 then one job associated with it) or NULL if no more commands are
1027 static int parse_command(char **command_ptr, struct job *job, int *inbg)
1030 char *return_command = NULL;
1031 char *src, *buf, *chptr;
1038 struct child_prog *prog;
1040 /* skip leading white space */
1041 while (**command_ptr && isspace(**command_ptr))
1044 /* this handles empty lines or leading '#' characters */
1045 if (!**command_ptr || (**command_ptr == '#')) {
1052 job->progs = xmalloc(sizeof(*job->progs));
1054 /* We set the argv elements to point inside of this string. The
1055 memory is freed by free_job(). Allocate twice the original
1056 length in case we need to quote every single character.
1058 Getting clean memory relieves us of the task of NULL
1059 terminating things and makes the rest of this look a bit
1060 cleaner (though it is, admittedly, a tad less efficient) */
1061 job->cmdbuf = command = xcalloc(2*strlen(*command_ptr) + 1, sizeof(char));
1065 prog->num_redirects = 0;
1066 prog->redirects = NULL;
1067 prog->free_glob = 0;
1068 prog->is_stopped = 0;
1072 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1073 prog->argv[0] = job->cmdbuf;
1077 while (*src && !done) {
1078 if (quote == *src) {
1084 error_msg("character expected after \\");
1089 /* in shell, "\'" should yield \' */
1090 if (*src != quote) {
1094 } else if (*src == '*' || *src == '?' || *src == '[' ||
1095 *src == ']') *buf++ = '\\';
1097 } else if (isspace(*src)) {
1098 if (*prog->argv[argc_l]) {
1100 /* +1 here leaves room for the NULL which ends argv */
1101 if ((argc_l + 1) == argv_alloced) {
1103 prog->argv = xrealloc(prog->argv,
1104 sizeof(*prog->argv) *
1107 expand_argument(prog, &argc_l, &argv_alloced);
1108 prog->argv[argc_l] = buf;
1117 case '#': /* comment */
1124 case '>': /* redirects */
1126 i = prog->num_redirects++;
1127 prog->redirects = xrealloc(prog->redirects,
1128 sizeof(*prog->redirects) *
1131 prog->redirects[i].fd = -1;
1132 if (buf != prog->argv[argc_l]) {
1133 /* the stuff before this character may be the file number
1135 prog->redirects[i].fd =
1136 strtol(prog->argv[argc_l], &chptr, 10);
1138 if (*chptr && *prog->argv[argc_l]) {
1140 expand_argument(prog, &argc_l, &argv_alloced);
1141 prog->argv[argc_l] = buf;
1145 if (prog->redirects[i].fd == -1) {
1147 prog->redirects[i].fd = 1;
1149 prog->redirects[i].fd = 0;
1152 if (*src++ == '>') {
1154 prog->redirects[i].type =
1155 REDIRECT_APPEND, src++;
1157 prog->redirects[i].type = REDIRECT_OVERWRITE;
1159 prog->redirects[i].type = REDIRECT_INPUT;
1162 /* This isn't POSIX sh compliant. Oh well. */
1164 while (isspace(*chptr))
1168 error_msg("file name expected after %c", *src);
1174 prog->redirects[i].filename = buf;
1175 while (*chptr && !isspace(*chptr))
1178 src = chptr - 1; /* we src++ later */
1179 prog->argv[argc_l] = ++buf;
1182 case '|': /* pipe */
1183 /* finish this command */
1184 if (*prog->argv[argc_l])
1187 error_msg("empty command in pipe");
1192 prog->argv[argc_l] = NULL;
1194 /* and start the next */
1196 job->progs = xrealloc(job->progs,
1197 sizeof(*job->progs) * job->num_progs);
1198 prog = job->progs + (job->num_progs - 1);
1199 prog->num_redirects = 0;
1200 prog->redirects = NULL;
1201 prog->free_glob = 0;
1202 prog->is_stopped = 0;
1207 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1208 prog->argv[0] = ++buf;
1211 while (*src && isspace(*src))
1215 error_msg("empty command in pipe");
1220 src--; /* we'll ++ it at the end of the loop */
1224 case '&': /* background */
1226 case ';': /* multiple commands */
1228 return_command = *command_ptr + (src - *command_ptr) + 1;
1231 #ifdef BB_FEATURE_SH_BACKTICKS
1233 /* Exec a backtick-ed command */
1234 /* Besides any previous brokenness, I have not
1235 * updated backtick handling for close_me support.
1236 * I don't know if it needs it or not. -- LRD */
1238 char* charptr1=NULL, *charptr2;
1241 struct jobset njob_list = { NULL, NULL };
1245 ptr=strchr(++src, '`');
1247 fprintf(stderr, "Unmatched '`' in command\n");
1252 /* Make some space to hold just the backticked command */
1253 charptr1 = charptr2 = xmalloc(1+ptr-src);
1254 memcpy(charptr1, src, ptr-src);
1255 charptr1[ptr-src] = '\0';
1256 newjob = xmalloc(sizeof(struct job));
1257 newjob->job_list = &njob_list;
1258 /* Now parse and run the backticked command */
1259 if (!parse_command(&charptr1, newjob, inbg)
1260 && newjob->num_progs) {
1262 run_command(newjob, 0, pipefd);
1264 checkjobs(job->job_list);
1265 free_job(newjob); /* doesn't actually free newjob,
1266 looks like a memory leak */
1269 /* Make a copy of any stuff left over in the command
1270 * line after the second backtick */
1271 charptr2 = xmalloc(strlen(ptr)+1);
1272 memcpy(charptr2, ptr+1, strlen(ptr));
1275 /* Copy the output from the backtick-ed command into the
1276 * command line, making extra room as needed */
1278 charptr1 = xmalloc(BUFSIZ);
1279 while ( (size=full_read(pipefd[0], charptr1, BUFSIZ-1)) >0) {
1280 int newsize=src - *command_ptr + size + 1 + strlen(charptr2);
1281 if (newsize > BUFSIZ) {
1282 *command_ptr=xrealloc(*command_ptr, newsize);
1284 memcpy(src, charptr1, size);
1292 /* Now paste into the *command_ptr all the stuff
1293 * leftover after the second backtick */
1294 memcpy(src, charptr2, strlen(charptr2)+1);
1297 /* Now recursively call parse_command to deal with the new
1298 * and improved version of the command line with the backtick
1299 * results expanded in place... */
1301 struct jobset *jl=job->job_list;
1305 return(parse_command(command_ptr, job, inbg));
1308 #endif // BB_FEATURE_SH_BACKTICKS
1313 /* This is currently a little broken... */
1314 #ifdef HANDLE_CONTINUATION_CHARS
1315 /* They fed us a continuation char, so continue reading stuff
1316 * on the next line, then tack that onto the end of the current
1320 printf("erik: found a continue char at EOL...\n");
1321 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1322 if (get_command(input, command)) {
1323 error_msg("character expected after \\");
1328 newsize = strlen(*command_ptr) + strlen(command) + 2;
1329 if (newsize > BUFSIZ) {
1330 printf("erik: doing realloc\n");
1331 *command_ptr=xrealloc(*command_ptr, newsize);
1333 printf("erik: A: *command_ptr='%s'\n", *command_ptr);
1334 memcpy(--src, command, strlen(command));
1335 printf("erik: B: *command_ptr='%s'\n", *command_ptr);
1339 error_msg("character expected after \\");
1345 if (*src == '*' || *src == '[' || *src == ']'
1346 || *src == '?') *buf++ = '\\';
1355 if (*prog->argv[argc_l]) {
1357 expand_argument(prog, &argc_l, &argv_alloced);
1363 prog->argv[argc_l] = NULL;
1365 if (!return_command) {
1366 job->text = xmalloc(strlen(*command_ptr) + 1);
1367 strcpy(job->text, *command_ptr);
1369 /* This leaves any trailing spaces, which is a bit sloppy */
1370 count = return_command - *command_ptr;
1371 job->text = xmalloc(count + 1);
1372 strncpy(job->text, *command_ptr, count);
1373 job->text[count] = '\0';
1376 *command_ptr = return_command;
1381 /* Run the child_prog, no matter what kind of command it uses.
1383 static int pseudo_exec(struct child_prog *child)
1385 struct built_in_command *x;
1386 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
1390 /* Check if the command matches any of the non-forking builtins.
1391 * Depending on context, this might be redundant. But it's
1392 * easier to waste a few CPU cycles than it is to figure out
1393 * if this is one of those cases.
1395 for (x = bltins; x->cmd; x++) {
1396 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1397 exit(x->function(child));
1401 /* Check if the command matches any of the forking builtins. */
1402 for (x = bltins_forking; x->cmd; x++) {
1403 if (strcmp(child->argv[0], x->cmd) == 0) {
1405 exit (x->function(child));
1408 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
1409 /* Check if the command matches any busybox internal
1410 * commands ("applets") here. Following discussions from
1411 * November 2000 on busybox@opensource.lineo.com, don't use
1412 * get_last_path_component(). This way explicit (with
1413 * slashes) filenames will never be interpreted as an
1414 * applet, just like with builtins. This way the user can
1415 * override an applet with an explicit filename reference.
1416 * The only downside to this change is that an explicit
1417 * /bin/foo invocation will fork and exec /bin/foo, even if
1418 * /bin/foo is a symlink to busybox.
1420 name = child->argv[0];
1422 #ifdef BB_FEATURE_SH_APPLETS_ALWAYS_WIN
1423 /* If you enable BB_FEATURE_SH_APPLETS_ALWAYS_WIN, then
1424 * if you run /bin/cat, it will use BusyBox cat even if
1425 * /bin/cat exists on the filesystem and is _not_ busybox.
1426 * Some systems want this, others do not. Choose wisely. :-)
1428 name = get_last_path_component(name);
1432 char** argv=child->argv;
1434 for(argc_l=0;*argv!=NULL; argv++, argc_l++);
1436 run_applet_by_name(name, argc_l, child->argv);
1440 execvp(child->argv[0], child->argv);
1441 perror_msg_and_die("%s", child->argv[0]);
1444 static void insert_job(struct job *newjob, int inbg)
1447 struct jobset *job_list=newjob->job_list;
1449 /* find the ID for thejob to use */
1451 for (thejob = job_list->head; thejob; thejob = thejob->next)
1452 if (thejob->jobid >= newjob->jobid)
1453 newjob->jobid = thejob->jobid + 1;
1455 /* add thejob to the list of running jobs */
1456 if (!job_list->head) {
1457 thejob = job_list->head = xmalloc(sizeof(*thejob));
1459 for (thejob = job_list->head; thejob->next; thejob = thejob->next) /* nothing */;
1460 thejob->next = xmalloc(sizeof(*thejob));
1461 thejob = thejob->next;
1464 *thejob = *newjob; /* physically copy the struct job */
1465 thejob->next = NULL;
1466 thejob->running_progs = thejob->num_progs;
1467 thejob->stopped_progs = 0;
1470 /* we don't wait for background thejobs to return -- append it
1471 to the list of backgrounded thejobs and leave it alone */
1472 printf("[%d] %d\n", thejob->jobid,
1473 newjob->progs[newjob->num_progs - 1].pid);
1474 #ifdef BB_FEATURE_SH_ENVIRONMENT
1475 last_bg_pid=newjob->progs[newjob->num_progs - 1].pid;
1478 newjob->job_list->fg = thejob;
1480 /* move the new process group into the foreground */
1481 /* suppress messages when run from /linuxrc mag@sysgo.de */
1482 if (tcsetpgrp(0, newjob->pgrp) && errno != ENOTTY)
1483 perror_msg("tcsetpgrp");
1487 static int run_command(struct job *newjob, int inbg, int outpipe[2])
1489 /* struct job *thejob; */
1491 int nextin, nextout;
1492 int pipefds[2]; /* pipefd[0] is for reading */
1493 struct built_in_command *x;
1494 struct child_prog *child;
1496 nextin = 0, nextout = 1;
1497 for (i = 0; i < newjob->num_progs; i++) {
1498 child = & (newjob->progs[i]);
1500 if ((i + 1) < newjob->num_progs) {
1501 if (pipe(pipefds)<0) perror_msg_and_die("pipe");
1502 nextout = pipefds[1];
1504 if (outpipe[1]!=-1) {
1505 nextout = outpipe[1];
1511 #ifdef BB_FEATURE_SH_ENVIRONMENT
1512 if (show_x_trace==TRUE) {
1515 for (j = 0; child->argv[j]; j++) {
1517 fputs(child->argv[j], stderr);
1519 fputc('\n', stderr);
1523 /* Check if the command matches any non-forking builtins,
1524 * but only if this is a simple command.
1525 * Non-forking builtins within pipes have to fork anyway,
1526 * and are handled in pseudo_exec. "echo foo | read bar"
1527 * is doomed to failure, and doesn't work on bash, either.
1529 if (newjob->num_progs == 1) {
1530 for (x = bltins; x->cmd; x++) {
1531 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1532 int squirrel[] = {-1, -1, -1};
1534 setup_redirects(child, squirrel);
1535 rcode = x->function(child);
1536 restore_redirects(squirrel);
1542 if (!(child->pid = fork())) {
1543 signal(SIGTTOU, SIG_DFL);
1547 if (outpipe[1]!=-1) {
1557 dup2(nextout, 2); /* Really? */
1562 /* explicit redirects override pipes */
1563 setup_redirects(child,NULL);
1567 if (outpipe[1]!=-1) {
1571 /* put our child in the process group whose leader is the
1572 first process in this pipe */
1573 setpgid(child->pid, newjob->progs[0].pid);
1579 /* If there isn't another process, nextin is garbage
1580 but it doesn't matter */
1581 nextin = pipefds[0];
1584 newjob->pgrp = newjob->progs[0].pid;
1586 insert_job(newjob, inbg);
1591 static int busy_loop(FILE * input)
1594 char *next_command = NULL;
1600 newjob.job_list = &job_list;
1601 newjob.job_context = DEFAULT_CONTEXT;
1603 /* save current owner of TTY so we can restore it on exit */
1604 parent_pgrp = tcgetpgrp(0);
1606 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1608 /* don't pay any attention to this signal; it just confuses
1609 things and isn't really meant for shells anyway */
1610 signal(SIGTTOU, SIG_IGN);
1614 /* no job is in the foreground */
1616 /* see if any background processes have exited */
1617 checkjobs(&job_list);
1619 if (!next_command) {
1620 if (get_command(input, command))
1622 next_command = command;
1625 if (!parse_command(&next_command, &newjob, &inbg) &&
1627 int pipefds[2] = {-1,-1};
1628 debug_printf( "job=%p being fed to run_command by busy_loop()'\n", &newjob);
1629 run_command(&newjob, inbg, pipefds);
1633 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1634 next_command = NULL;
1637 /* a job is running in the foreground; wait for it */
1639 while (!job_list.fg->progs[i].pid ||
1640 job_list.fg->progs[i].is_stopped == 1) i++;
1642 if (waitpid(job_list.fg->progs[i].pid, &status, WUNTRACED)<0)
1643 perror_msg_and_die("waitpid(%d)",job_list.fg->progs[i].pid);
1645 if (WIFEXITED(status) || WIFSIGNALED(status)) {
1646 /* the child exited */
1647 job_list.fg->running_progs--;
1648 job_list.fg->progs[i].pid = 0;
1650 #ifdef BB_FEATURE_SH_ENVIRONMENT
1651 last_return_code=WEXITSTATUS(status);
1653 debug_printf("'%s' exited -- return code %d\n",
1654 job_list.fg->text, last_return_code);
1655 if (!job_list.fg->running_progs) {
1657 remove_job(&job_list, job_list.fg);
1661 /* the child was stopped */
1662 job_list.fg->stopped_progs++;
1663 job_list.fg->progs[i].is_stopped = 1;
1665 if (job_list.fg->stopped_progs == job_list.fg->running_progs) {
1666 printf("\n" JOB_STATUS_FORMAT, job_list.fg->jobid,
1667 "Stopped", job_list.fg->text);
1673 /* move the shell to the foreground */
1674 /* suppress messages when run from /linuxrc mag@sysgo.de */
1675 if (tcsetpgrp(0, getpid()) && errno != ENOTTY)
1676 perror_msg("tcsetpgrp");
1682 /* return controlling TTY back to parent process group before exiting */
1683 if (tcsetpgrp(0, parent_pgrp))
1684 perror_msg("tcsetpgrp");
1686 /* return exit status if called with "-c" */
1687 if (input == NULL && WIFEXITED(status))
1688 return WEXITSTATUS(status);
1694 #ifdef BB_FEATURE_CLEAN_UP
1695 void free_memory(void)
1699 if (local_pending_command)
1700 free(local_pending_command);
1702 if (job_list.fg && !job_list.fg->running_progs) {
1703 remove_job(&job_list, job_list.fg);
1709 int shell_main(int argc_l, char **argv_l)
1711 int opt, interactive=FALSE;
1712 FILE *input = stdin;
1718 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
1719 /* These variables need re-initializing when recursing */
1720 local_pending_command = NULL;
1721 job_list.head = NULL;
1723 #ifdef BB_FEATURE_SH_ENVIRONMENT
1725 last_return_code=-1;
1730 if (argv[0] && argv[0][0] == '-') {
1732 prof_input = fopen("/etc/profile", "r");
1734 printf( "Couldn't open file '/etc/profile'\n");
1736 int tmp_fd = fileno(prof_input);
1738 /* Now run the file */
1739 busy_loop(prof_input);
1741 mark_closed(tmp_fd);
1745 while ((opt = getopt(argc_l, argv_l, "cxi")) > 0) {
1749 if (local_pending_command != 0)
1750 error_msg_and_die("multiple -c arguments");
1751 local_pending_command = xstrdup(argv[optind]);
1755 #ifdef BB_FEATURE_SH_ENVIRONMENT
1757 show_x_trace = TRUE;
1767 /* A shell is interactive if the `-i' flag was given, or if all of
1768 * the following conditions are met:
1770 * no arguments remaining or the -s flag given
1771 * standard input is a terminal
1772 * standard output is a terminal
1773 * Refer to Posix.2, the description of the `sh' utility. */
1774 if (argv[optind]==NULL && input==stdin &&
1775 isatty(fileno(stdin)) && isatty(fileno(stdout))) {
1778 if (interactive==TRUE) {
1779 //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
1780 /* Looks like they want an interactive shell */
1781 printf( "\n\nBusyBox v%s (%s) Built-in shell (lash)\n", BB_VER, BB_BT);
1782 printf( "Enter 'help' for a list of built-in commands.\n\n");
1783 } else if (local_pending_command==NULL) {
1784 //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
1785 input = xfopen(argv[optind], "r");
1786 mark_open(fileno(input)); /* be lazy, never mark this closed */
1789 /* initialize the cwd -- this is never freed...*/
1790 cwd=(char*)xmalloc(sizeof(char)*MAX_LINE+1);
1791 getcwd(cwd, sizeof(char)*MAX_LINE);
1793 #ifdef BB_FEATURE_CLEAN_UP
1794 atexit(free_memory);
1797 return (busy_loop(input));