more bugs fixed -- found doing regression testing
[oweals/busybox.git] / sh.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * lash -- the BusyBox Lame-Ass SHell
4  *
5  * Copyright (C) 2000 by Lineo, inc.
6  * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
7  *
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."
11  *
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.
16  *
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.
21  *
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
25  *
26  */
27
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 .
33  */
34 //
35 //This works pretty well now, and is now on by default.
36 #define BB_FEATURE_SH_ENVIRONMENT
37 //
38 //Backtick support has some problems, use at your own risk!
39 //#define BB_FEATURE_SH_BACKTICKS
40 //
41 //If, then, else, etc. support..  This should now behave basically
42 //like any other Bourne shell...
43 #define BB_FEATURE_SH_IF_EXPRESSIONS
44 //
45 /* This is currently a little broken... */
46 //#define HANDLE_CONTINUATION_CHARS
47 //
48 //For debugging/development on the shell only...
49 //#define DEBUG_SHELL
50
51
52 #include "busybox.h"
53 #include <stdio.h>
54 #include <stdlib.h>
55 #include <ctype.h>
56 #include <errno.h>
57 #include <fcntl.h>
58 #include <glob.h>
59 #include <signal.h>
60 #include <string.h>
61 #include <sys/ioctl.h>
62 #include <sys/wait.h>
63 #include <unistd.h>
64 #include <getopt.h>
65 #include "cmdedit.h"
66
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"
70 extern size_t NUM_APPLETS;
71
72
73 enum redir_type { REDIRECT_INPUT, REDIRECT_OVERWRITE,
74         REDIRECT_APPEND
75 };
76
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;
82
83
84 struct jobset {
85         struct job *head;                       /* head of list of running jobs */
86         struct job *fg;                         /* current foreground job */
87 };
88
89 struct redir_struct {
90         enum redir_type type;   /* type of redirection */
91         int fd;                                         /* file descriptor being redirected */
92         char *filename;                         /* file to redirect fd to */
93 };
94
95 struct child_prog {
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 */
104 };
105
106 struct 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;
118 };
119
120 struct built_in_command {
121         char *cmd;                                      /* name */
122         char *descr;                            /* description */
123         int (*function) (struct child_prog *);  /* function ptr */
124 };
125
126 struct close_me {
127         int fd;
128         struct close_me *next;
129 };
130
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);
151 #endif
152
153
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);
163
164
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},
185 #endif
186         {NULL, NULL, NULL}
187 };
188
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},
195         {NULL, NULL, NULL}
196 };
197
198
199 /* Variables we export */
200 unsigned int shell_context;  /* Used in cmdedit.c to reset the
201                                                                 context when someone hits ^C */
202
203
204 /* Globals that are static to this file */
205 static char *cwd;
206 static char *local_pending_command = NULL;
207 static struct jobset job_list = { NULL, NULL };
208 static int argc;
209 static char **argv;
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;
215 #endif
216 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
217 static char syntax_err[]="syntax error near unexpected token";
218 #endif
219
220 #ifdef DEBUG_SHELL
221 static inline void debug_printf(const char *format, ...)
222 {
223         va_list args;
224         va_start(args, format);
225         vfprintf(stderr, format, args);
226         va_end(args);
227 }
228 #else
229 static inline void debug_printf(const char *format, ...) { }
230 #endif
231
232 /*
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.
237
238 builtin   previous use      notes
239 ------ -----------------  ---------
240 cd      cmd->progs[0]
241 env     0
242 exec    cmd->progs[0]  squashed bug: didn't look for applets or forking builtins
243 exit    cmd->progs[0]
244 fg_bg   cmd->progs[0], job_list->head, job_list->fg
245 help    0
246 jobs    job_list->head
247 pwd     0
248 export  cmd->progs[0]  passes cmd, job_list to builtin_env(), which ignores them
249 source  cmd->progs[0]
250 unset   cmd->progs[0]
251 read    cmd->progs[0]
252 if      cmd->job_context,  cmd->text
253 then    cmd->job_context,  cmd->text
254 else    cmd->job_context,  cmd->text
255 fi      cmd->job_context
256
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?
260
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
267  */
268
269 /* built-in 'cd <path>' handler */
270 static int builtin_cd(struct child_prog *child)
271 {
272         char *newdir;
273
274         if (child->argv[1] == NULL)
275                 newdir = getenv("HOME");
276         else
277                 newdir = child->argv[1];
278         if (chdir(newdir)) {
279                 printf("cd: %s: %s\n", newdir, strerror(errno));
280                 return EXIT_FAILURE;
281         }
282         getcwd(cwd, sizeof(char)*MAX_LINE);
283
284         return EXIT_SUCCESS;
285 }
286
287 /* built-in 'env' handler */
288 static int builtin_env(struct child_prog *dummy)
289 {
290         char **e;
291
292         for (e = environ; *e; e++) {
293                 printf( "%s\n", *e);
294         }
295         return (0);
296 }
297
298 /* built-in 'exec' handler */
299 static int builtin_exec(struct child_prog *child)
300 {
301         if (child->argv[1] == NULL)
302                 return EXIT_SUCCESS;   /* Really? */
303         child->argv++;
304         pseudo_exec(child);
305         /* never returns */
306 }
307
308 /* built-in 'exit' handler */
309 static int builtin_exit(struct child_prog *child)
310 {
311         if (child->argv[1] == NULL)
312                 exit(EXIT_SUCCESS);
313
314         exit (atoi(child->argv[1]));
315 }
316
317 /* built-in 'fg' and 'bg' handler */
318 static int builtin_fg_bg(struct child_prog *child)
319 {
320         int i, jobNum;
321         struct job *job=NULL;
322         
323         if (!child->argv[1] || child->argv[2]) {
324                 error_msg("%s: exactly one argument is expected\n",
325                                 child->argv[0]);
326                 return EXIT_FAILURE;
327         }
328
329         if (sscanf(child->argv[1], "%%%d", &jobNum) != 1) {
330                 error_msg("%s: bad argument '%s'\n",
331                                 child->argv[0], child->argv[1]);
332                 return EXIT_FAILURE;
333         }
334
335         for (job = child->family->job_list->head; job; job = job->next) {
336                 if (job->jobid == jobNum) {
337                         break;
338                 }
339         }
340
341         if (!job) {
342                 error_msg("%s: unknown job %d\n",
343                                 child->argv[0], jobNum);
344                 return EXIT_FAILURE;
345         }
346
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;
353         }
354
355         /* Restart the processes in the job */
356         for (i = 0; i < job->num_progs; i++)
357                 job->progs[i].is_stopped = 0;
358
359         kill(-job->pgrp, SIGCONT);
360
361         job->stopped_progs = 0;
362
363         return EXIT_SUCCESS;
364 }
365
366 /* built-in 'help' handler */
367 static int builtin_help(struct child_prog *dummy)
368 {
369         struct built_in_command *x;
370
371         printf("\nBuilt-in commands:\n");
372         printf("-------------------\n");
373         for (x = bltins; x->cmd; x++) {
374                 if (x->descr==NULL)
375                         continue;
376                 printf("%s\t%s\n", x->cmd, x->descr);
377         }
378         for (x = bltins_forking; x->cmd; x++) {
379                 if (x->descr==NULL)
380                         continue;
381                 printf("%s\t%s\n", x->cmd, x->descr);
382         }
383         printf("\n\n");
384         return EXIT_SUCCESS;
385 }
386
387 /* built-in 'jobs' handler */
388 static int builtin_jobs(struct child_prog *child)
389 {
390         struct job *job;
391         char *status_string;
392
393         for (job = child->family->job_list->head; job; job = job->next) {
394                 if (job->running_progs == job->stopped_progs)
395                         status_string = "Stopped";
396                 else
397                         status_string = "Running";
398
399                 printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->text);
400         }
401         return EXIT_SUCCESS;
402 }
403
404
405 /* built-in 'pwd' handler */
406 static int builtin_pwd(struct child_prog *dummy)
407 {
408         getcwd(cwd, MAX_LINE);
409         printf( "%s\n", cwd);
410         return EXIT_SUCCESS;
411 }
412
413 /* built-in 'export VAR=value' handler */
414 static int builtin_export(struct child_prog *child)
415 {
416         int res;
417
418         if (child->argv[1] == NULL) {
419                 return (builtin_env(child));
420         }
421         res = putenv(child->argv[1]);
422         if (res)
423                 fprintf(stderr, "export: %s\n", strerror(errno));
424         return (res);
425 }
426
427 /* built-in 'read VAR' handler */
428 static int builtin_read(struct child_prog *child)
429 {
430         int res = 0, len, newlen;
431         char *s;
432         char string[MAX_READ];
433
434         if (child->argv[1]) {
435                 /* argument (VAR) given: put "VAR=" into buffer */
436                 strcpy(string, child->argv[1]);
437                 len = strlen(string);
438                 string[len++] = '=';
439                 string[len]   = '\0';
440                 fgets(&string[len], sizeof(string) - len, stdin);       /* read string */
441                 newlen = strlen(string);
442                 if(newlen > len)
443                         string[--newlen] = '\0';        /* chomp trailing newline */
444                 /*
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!)
448                 */
449                 res = -1;
450                 if((s = strdup(string)))
451                         res = putenv(s);
452                 if (res)
453                         fprintf(stderr, "read: %s\n", strerror(errno));
454         }
455         else
456                 fgets(string, sizeof(string), stdin);
457
458         return (res);
459 }
460
461 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
462 /* Built-in handler for 'if' commands */
463 static int builtin_if(struct child_prog *child)
464 {
465         struct job *cmd = child->family;
466         int status;
467         char* charptr1=cmd->text+3; /* skip over the leading 'if ' */
468
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 ");
473         if (status == 0) {
474                 debug_printf( "TRUE\n");
475                 cmd->job_context |= IF_TRUE_CONTEXT;
476         } else {
477                 debug_printf( "FALSE\n");
478                 cmd->job_context |= IF_FALSE_CONTEXT;
479         }
480         debug_printf("job=%p builtin_if set job context to %x\n", cmd, cmd->job_context);
481         shell_context++;
482
483         return status;
484 }
485
486 /* Built-in handler for 'then' (part of the 'if' command) */
487 static int builtin_then(struct child_prog *child)
488 {
489         struct job *cmd = child->family;
490         char* charptr1=cmd->text+5; /* skip over the leading 'then ' */
491
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);
496                 return EXIT_FAILURE;
497         }
498
499         cmd->job_context |= THEN_EXP_CONTEXT;
500         debug_printf("job=%p builtin_then set job context to %x\n", cmd, cmd->job_context);
501
502         /* If the if result was FALSE, skip the 'then' stuff */
503         if (cmd->job_context & IF_FALSE_CONTEXT) {
504                 return EXIT_SUCCESS;
505         }
506
507         /* Seems the if result was TRUE, so run the 'then' command */
508         debug_printf( "'then' now running '%s'\n", charptr1);
509
510         return(run_command_predicate(charptr1));
511 }
512
513 /* Built-in handler for 'else' (part of the 'if' command) */
514 static int builtin_else(struct child_prog *child)
515 {
516         struct job *cmd = child->family;
517         char* charptr1=cmd->text+5; /* skip over the leading 'else ' */
518
519         debug_printf( "job=%p entering builtin_else ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
520
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);
524                 return EXIT_FAILURE;
525         }
526         /* If the if result was TRUE, skip the 'else' stuff */
527         if (cmd->job_context & IF_TRUE_CONTEXT) {
528                 return EXIT_SUCCESS;
529         }
530
531         cmd->job_context |= ELSE_EXP_CONTEXT;
532         debug_printf("job=%p builtin_else set job context to %x\n", cmd, cmd->job_context);
533
534         /* Now run the 'else' command */
535         debug_printf( "'else' now running '%s'\n", charptr1);
536         return(run_command_predicate(charptr1));
537 }
538
539 /* Built-in handler for 'fi' (part of the 'if' command) */
540 static int builtin_fi(struct child_prog *child)
541 {
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);
547                 return EXIT_FAILURE;
548         }
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);
552         shell_context--;
553         return EXIT_SUCCESS;
554 }
555 #endif
556
557 /* Built-in '.' handler (read-in and execute commands from file) */
558 static int builtin_source(struct child_prog *child)
559 {
560         FILE *input;
561         int status;
562         int fd;
563
564         if (child->argv[1] == NULL)
565                 return EXIT_FAILURE;
566
567         input = fopen(child->argv[1], "r");
568         if (!input) {
569                 printf( "Couldn't open file '%s'\n", child->argv[1]);
570                 return EXIT_FAILURE;
571         }
572
573         fd=fileno(input);
574         mark_open(fd);
575         /* Now run the file */
576         status = busy_loop(input);
577         fclose(input);
578         mark_closed(fd);
579         return (status);
580 }
581
582 /* built-in 'unset VAR' handler */
583 static int builtin_unset(struct child_prog *child)
584 {
585         if (child->argv[1] == NULL) {
586                 printf( "unset: parameter required.\n");
587                 return EXIT_FAILURE;
588         }
589         unsetenv(child->argv[1]);
590         return EXIT_SUCCESS;
591 }
592
593 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
594 /* currently used by if/then/else.
595  *
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.
602  */
603 static int run_command_predicate(char *cmd)
604 {
605         int n=strlen(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));
610 }
611 #endif
612
613 static void mark_open(int fd)
614 {
615         struct close_me *new = xmalloc(sizeof(struct close_me));
616         new->fd = fd;
617         new->next = close_me_head;
618         close_me_head = new;
619 }
620
621 static void mark_closed(int fd)
622 {
623         struct close_me *tmp;
624         if (close_me_head == NULL || close_me_head->fd != fd)
625                 error_msg_and_die("corrupt close_me");
626         tmp = close_me_head;
627         close_me_head = close_me_head->next;
628         free(tmp);
629 }
630
631 static void close_all()
632 {
633         struct close_me *c;
634         for (c=close_me_head; c; c=c->next) {
635                 close(c->fd);
636         }
637         close_me_head = NULL;
638 }
639
640
641 /* free up all memory from a job */
642 static void free_job(struct job *cmd)
643 {
644         int i;
645
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);
652         }
653         free(cmd->progs);
654         if (cmd->text)
655                 free(cmd->text);
656         free(cmd->cmdbuf);
657         memset(cmd, 0, sizeof(struct job));
658 }
659
660 /* remove a job from the job_list */
661 static void remove_job(struct jobset *job_list, struct job *job)
662 {
663         struct job *prevjob;
664
665         free_job(job);
666         if (job == job_list->head) {
667                 job_list->head = job->next;
668         } else {
669                 prevjob = job_list->head;
670                 while (prevjob->next != job)
671                         prevjob = prevjob->next;
672                 prevjob->next = job->next;
673         }
674
675         free(job);
676 }
677
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)
681 {
682         struct job *job;
683         pid_t childpid;
684         int status;
685         int prognum = 0;
686
687         while ((childpid = waitpid(-1, &status, WNOHANG | WUNTRACED)) > 0) {
688                 for (job = job_list->head; job; job = job->next) {
689                         prognum = 0;
690                         while (prognum < job->num_progs &&
691                                    job->progs[prognum].pid != childpid) prognum++;
692                         if (prognum < job->num_progs)
693                                 break;
694                 }
695
696                 /* This happens on backticked commands */
697                 if(job==NULL)
698                         return;
699
700                 if (WIFEXITED(status) || WIFSIGNALED(status)) {
701                         /* child exited */
702                         job->running_progs--;
703                         job->progs[prognum].pid = 0;
704
705                         if (!job->running_progs) {
706                                 printf(JOB_STATUS_FORMAT, job->jobid, "Done", job->text);
707                                 remove_job(job_list, job);
708                         }
709                 } else {
710                         /* child stopped */
711                         job->stopped_progs++;
712                         job->progs[prognum].is_stopped = 1;
713
714                         if (job->stopped_progs == job->num_progs) {
715                                 printf(JOB_STATUS_FORMAT, job->jobid, "Stopped",
716                                            job->text);
717                         }
718                 }
719         }
720
721         if (childpid == -1 && errno != ECHILD)
722                 perror_msg("waitpid");
723 }
724
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[])
728 {
729         int i;
730         int openfd;
731         int mode = O_RDONLY;
732         struct redir_struct *redir = prog->redirects;
733
734         for (i = 0; i < prog->num_redirects; i++, redir++) {
735                 switch (redir->type) {
736                 case REDIRECT_INPUT:
737                         mode = O_RDONLY;
738                         break;
739                 case REDIRECT_OVERWRITE:
740                         mode = O_WRONLY | O_CREAT | O_TRUNC;
741                         break;
742                 case REDIRECT_APPEND:
743                         mode = O_WRONLY | O_CREAT | O_APPEND;
744                         break;
745                 }
746
747                 openfd = open(redir->filename, mode, 0666);
748                 if (openfd < 0) {
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,
752                                         strerror(errno));
753                         return 1;
754                 }
755
756                 if (openfd != redir->fd) {
757                         if (squirrel && redir->fd < 3) {
758                                 squirrel[redir->fd] = dup(redir->fd);
759                         }
760                         dup2(openfd, redir->fd);
761                         close(openfd);
762                 }
763         }
764
765         return 0;
766 }
767
768 static void restore_redirects(int squirrel[])
769 {
770         int i, fd;
771         for (i=0; i<3; i++) {
772                 fd = squirrel[i];
773                 if (fd != -1) {
774                         /* No error checking.  I sure wouldn't know what
775                          * to do with an error if I found one! */
776                         dup2(fd, i);
777                         close(fd);
778                 }
779         }
780 }
781
782 static char* setup_prompt_string(int state)
783 {
784         char user[9],buf[255],*s;
785         char prompt[3];
786         char prompt_str[BUFSIZ];
787
788         /* Set up the prompt */
789         if (state == 0) {
790                 /* get User Name and setup prompt */
791                 strcpy(prompt,( geteuid() != 0 ) ? "$ ":"# ");
792                 my_getpwuid(user, geteuid());
793
794                 /* get HostName */
795                 gethostname(buf, 255);
796                 s = strchr(buf, '.');
797                 if (s) {
798                         *s = 0;
799                 }
800         } else {
801                 strcpy(prompt,"> ");
802         }
803
804         if (state == 0) {
805                 snprintf(prompt_str, BUFSIZ-1, "[%s@%s %s]%s", user, buf, 
806                                 get_last_path_component(cwd), prompt);
807         } else {
808                 sprintf(prompt_str, "%s", prompt);
809         }
810         return(strdup(prompt_str));  /* Must free this memory */
811 }
812
813 static int get_command(FILE * source, char *command)
814 {
815         char *prompt_str;
816
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;
823                         return 0;
824                 }
825                 return 1;
826         }
827
828         if (source == stdin) {
829                 prompt_str = setup_prompt_string(shell_context);
830
831 #ifdef BB_FEATURE_SH_COMMAND_EDITING
832                 /*
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)
837                 */
838                 cmdedit_init();
839                 cmdedit_read_input(prompt_str, command);
840                 free(prompt_str);
841                 cmdedit_terminate();
842                 return 0;
843 #else
844                 fputs(prompt_str, stdout);
845                 free(prompt_str);
846 #endif
847         }
848
849         if (!fgets(command, BUFSIZ - 2, source)) {
850                 if (source == stdin)
851                         printf("\n");
852                 return 1;
853         }
854
855         /* remove trailing newline */
856         command[strlen(command) - 1] = '\0';
857
858         return 0;
859 }
860
861 #ifdef BB_FEATURE_SH_ENVIRONMENT
862 static char* itoa(register int i)
863 {
864         static char a[7]; /* Max 7 ints */
865         register char *b = a + sizeof(a) - 1;
866         int   sign = (i < 0);
867
868         if (sign)
869                 i = -i;
870         *b = 0;
871         do
872         {
873                 *--b = '0' + (i % 10);
874                 i /= 10;
875         }
876         while (i);
877         if (sign)
878                 *--b = '-';
879         return b;
880 }
881 #endif
882
883 static void expand_argument(struct child_prog *prog, int *argcPtr,
884                                                          int *argv_alloced_ptr)
885 {
886         int argc_l = *argcPtr;
887         int argv_alloced = *argv_alloced_ptr;
888         int rc;
889         int flags;
890         int i;
891         char *src, *dst, *var;
892
893         if (argc_l > 1) {                               /* cmd->glob_result is already initialized */
894                 flags = GLOB_APPEND;
895                 i = prog->glob_result.gl_pathc;
896         } else {
897                 prog->free_glob = 1;
898                 flags = 0;
899                 i = 0;
900         }
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;
905                 } 
906 #ifdef BB_FEATURE_SH_ENVIRONMENT
907                 else {
908                         switch(*(prog->argv[argc_l - 1] + 1)) {
909                                 case '?':
910                                         prog->argv[argc_l - 1] = itoa(last_return_code);
911                                         break;
912                                 case '$':
913                                         prog->argv[argc_l - 1] = itoa(getpid());
914                                         break;
915                                 case '#':
916                                         prog->argv[argc_l - 1] = itoa(argc-1);
917                                         break;
918                                 case '!':
919                                         if (last_bg_pid==-1)
920                                                 *(prog->argv[argc_l - 1])='\0';
921                                         else
922                                                 prog->argv[argc_l - 1] = itoa(last_bg_pid);
923                                         break;
924                                 case '0':case '1':case '2':case '3':case '4':
925                                 case '5':case '6':case '7':case '8':case '9':
926                                         {
927                                                 int index=*(prog->argv[argc_l - 1] + 1)-48;
928                                                 if (index >= argc) {
929                                                         *(prog->argv[argc_l - 1])='\0';
930                                                 } else {
931                                                         prog->argv[argc_l - 1] = argv[index];
932                                                 }
933                                         }
934                                         break;
935                         }
936                 }
937 #endif
938         }
939
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");
944                         return;
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];
951                         while (*src) {
952                                 if (*src == '\\') {
953                                         src++; 
954                                         *dst++ = process_escape_sequence(&src);
955                                 } else { 
956                                         *dst++ = *src;
957                                         src++;
958                                 }
959                         }
960                         *dst = '\0';
961                 } else if (!rc) {
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);
967                 }
968         }else{
969                         src = dst = prog->argv[argc_l - 1];
970                         while (*src) {
971                                 if (*src == '\\') {
972                                         src++; 
973                                         *dst++ = process_escape_sequence(&src);
974                                 } else { 
975                                         *dst++ = *src;
976                                         src++;
977                                 }
978                         }
979                         *dst = '\0';
980                         
981                         prog->glob_result.gl_pathc=0;
982                         if (flags==0)
983                                 prog->glob_result.gl_pathv=NULL;
984         }
985         *argv_alloced_ptr = argv_alloced;
986         *argcPtr = argc_l;
987 }
988
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 
993    present. */
994 static int parse_command(char **command_ptr, struct job *job, int *inbg)
995 {
996         char *command;
997         char *return_command = NULL;
998         char *src, *buf, *chptr;
999         int argc_l = 0;
1000         int done = 0;
1001         int argv_alloced;
1002         int i;
1003         char quote = '\0';
1004         int count;
1005         struct child_prog *prog;
1006
1007         /* skip leading white space */
1008         while (**command_ptr && isspace(**command_ptr))
1009                 (*command_ptr)++;
1010
1011         /* this handles empty lines or leading '#' characters */
1012         if (!**command_ptr || (**command_ptr == '#')) {
1013                 job->num_progs=0;
1014                 return 0;
1015         }
1016
1017         *inbg = 0;
1018         job->num_progs = 1;
1019         job->progs = xmalloc(sizeof(*job->progs));
1020
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.
1024
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));
1029         job->text = NULL;
1030
1031         prog = job->progs;
1032         prog->num_redirects = 0;
1033         prog->redirects = NULL;
1034         prog->free_glob = 0;
1035         prog->is_stopped = 0;
1036         prog->family = job;
1037
1038         argv_alloced = 5;
1039         prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1040         prog->argv[0] = job->cmdbuf;
1041
1042         buf = command;
1043         src = *command_ptr;
1044         while (*src && !done) {
1045                 if (quote == *src) {
1046                         quote = '\0';
1047                 } else if (quote) {
1048                         if (*src == '\\') {
1049                                 src++;
1050                                 if (!*src) {
1051                                         error_msg("character expected after \\\n");
1052                                         free_job(job);
1053                                         return 1;
1054                                 }
1055
1056                                 /* in shell, "\'" should yield \' */
1057                                 if (*src != quote) {
1058                                         *buf++ = '\\';
1059                                         *buf++ = '\\';
1060                                 }
1061                         } else if (*src == '*' || *src == '?' || *src == '[' ||
1062                                            *src == ']') *buf++ = '\\';
1063                         *buf++ = *src;
1064                 } else if (isspace(*src)) {
1065                         if (*prog->argv[argc_l]) {
1066                                 buf++, argc_l++;
1067                                 /* +1 here leaves room for the NULL which ends argv */
1068                                 if ((argc_l + 1) == argv_alloced) {
1069                                         argv_alloced += 5;
1070                                         prog->argv = xrealloc(prog->argv,
1071                                                                                   sizeof(*prog->argv) *
1072                                                                                   argv_alloced);
1073                                 }
1074                                 expand_argument(prog, &argc_l, &argv_alloced);
1075                                 prog->argv[argc_l] = buf;
1076                         }
1077                 } else
1078                         switch (*src) {
1079                         case '"':
1080                         case '\'':
1081                                 quote = *src;
1082                                 break;
1083
1084                         case '#':                       /* comment */
1085                                 if (*(src-1)== '$')
1086                                         *buf++ = *src;
1087                                 else
1088                                         done = 1;
1089                                 break;
1090
1091                         case '>':                       /* redirects */
1092                         case '<':
1093                                 i = prog->num_redirects++;
1094                                 prog->redirects = xrealloc(prog->redirects,
1095                                                                                           sizeof(*prog->redirects) *
1096                                                                                           (i + 1));
1097
1098                                 prog->redirects[i].fd = -1;
1099                                 if (buf != prog->argv[argc_l]) {
1100                                         /* the stuff before this character may be the file number 
1101                                            being redirected */
1102                                         prog->redirects[i].fd =
1103                                                 strtol(prog->argv[argc_l], &chptr, 10);
1104
1105                                         if (*chptr && *prog->argv[argc_l]) {
1106                                                 buf++, argc_l++;
1107                                                 expand_argument(prog, &argc_l, &argv_alloced);
1108                                                 prog->argv[argc_l] = buf;
1109                                         }
1110                                 }
1111
1112                                 if (prog->redirects[i].fd == -1) {
1113                                         if (*src == '>')
1114                                                 prog->redirects[i].fd = 1;
1115                                         else
1116                                                 prog->redirects[i].fd = 0;
1117                                 }
1118
1119                                 if (*src++ == '>') {
1120                                         if (*src == '>')
1121                                                 prog->redirects[i].type =
1122                                                         REDIRECT_APPEND, src++;
1123                                         else
1124                                                 prog->redirects[i].type = REDIRECT_OVERWRITE;
1125                                 } else {
1126                                         prog->redirects[i].type = REDIRECT_INPUT;
1127                                 }
1128
1129                                 /* This isn't POSIX sh compliant. Oh well. */
1130                                 chptr = src;
1131                                 while (isspace(*chptr))
1132                                         chptr++;
1133
1134                                 if (!*chptr) {
1135                                         error_msg("file name expected after %c\n", *src);
1136                                         free_job(job);
1137                                         job->num_progs=0;
1138                                         return 1;
1139                                 }
1140
1141                                 prog->redirects[i].filename = buf;
1142                                 while (*chptr && !isspace(*chptr))
1143                                         *buf++ = *chptr++;
1144
1145                                 src = chptr - 1;        /* we src++ later */
1146                                 prog->argv[argc_l] = ++buf;
1147                                 break;
1148
1149                         case '|':                       /* pipe */
1150                                 /* finish this command */
1151                                 if (*prog->argv[argc_l])
1152                                         argc_l++;
1153                                 if (!argc_l) {
1154                                         error_msg("empty command in pipe\n");
1155                                         free_job(job);
1156                                         job->num_progs=0;
1157                                         return 1;
1158                                 }
1159                                 prog->argv[argc_l] = NULL;
1160
1161                                 /* and start the next */
1162                                 job->num_progs++;
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;
1170                                 prog->family = job;
1171                                 argc_l = 0;
1172
1173                                 argv_alloced = 5;
1174                                 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1175                                 prog->argv[0] = ++buf;
1176
1177                                 src++;
1178                                 while (*src && isspace(*src))
1179                                         src++;
1180
1181                                 if (!*src) {
1182                                         error_msg("empty command in pipe\n");
1183                                         free_job(job);
1184                                         job->num_progs=0;
1185                                         return 1;
1186                                 }
1187                                 src--;                  /* we'll ++ it at the end of the loop */
1188
1189                                 break;
1190
1191                         case '&':                       /* background */
1192                                 *inbg = 1;
1193                         case ';':                       /* multiple commands */
1194                                 done = 1;
1195                                 return_command = *command_ptr + (src - *command_ptr) + 1;
1196                                 break;
1197
1198 #ifdef BB_FEATURE_SH_BACKTICKS
1199                         case '`':
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 */
1204                                 {
1205                                         char* charptr1=NULL, *charptr2;
1206                                         char* ptr=NULL;
1207                                         struct job *newjob;
1208                                         struct jobset njob_list = { NULL, NULL };
1209                                         int pipefd[2];
1210                                         int size;
1211
1212                                         ptr=strchr(++src, '`');
1213                                         if (ptr==NULL) {
1214                                                 fprintf(stderr, "Unmatched '`' in command\n");
1215                                                 free_job(job);
1216                                                 return 1;
1217                                         }
1218
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) {
1228                                                 pipe(pipefd);
1229                                                 run_command(newjob, 0, pipefd);
1230                                         }
1231                                         checkjobs(job->job_list);
1232                                         free_job(newjob);  /* doesn't actually free newjob,
1233                                                              looks like a memory leak */
1234                                         free(charptr2);
1235                                         
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));
1240
1241
1242                                         /* Copy the output from the backtick-ed command into the
1243                                          * command line, making extra room as needed  */
1244                                         --src;
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);
1250                                                 }
1251                                                 memcpy(src, charptr1, size); 
1252                                                 src+=size;
1253                                         }
1254                                         free(charptr1);
1255                                         close(pipefd[0]);
1256                                         if (*(src-1)=='\n')
1257                                                 --src;
1258
1259                                         /* Now paste into the *command_ptr all the stuff 
1260                                          * leftover after the second backtick */
1261                                         memcpy(src, charptr2, strlen(charptr2)+1);
1262                                         free(charptr2);
1263
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... */
1267                                         {
1268                                                 struct jobset *jl=job->job_list;
1269                                                 free_job(job);
1270                                                 job->job_list = jl;
1271                                         }
1272                                         return(parse_command(command_ptr, job, inbg));
1273                                 }
1274                                 break;
1275 #endif // BB_FEATURE_SH_BACKTICKS
1276
1277                         case '\\':
1278                                 src++;
1279                                 if (!*src) {
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
1284                                          * command */
1285                                         char *command;
1286                                         int newsize;
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");
1291                                                 free(command);
1292                                                 free_job(job);
1293                                                 return 1;
1294                                         }
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);
1299                                         }
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);
1303                                         free(command);
1304                                         break;
1305 #else
1306                                         error_msg("character expected after \\\n");
1307                                         free(command);
1308                                         free_job(job);
1309                                         return 1;
1310 #endif
1311                                 }
1312                                 if (*src == '*' || *src == '[' || *src == ']'
1313                                         || *src == '?') *buf++ = '\\';
1314                                 /* fallthrough */
1315                         default:
1316                                 *buf++ = *src;
1317                         }
1318
1319                 src++;
1320         }
1321
1322         if (*prog->argv[argc_l]) {
1323                 argc_l++;
1324                 expand_argument(prog, &argc_l, &argv_alloced);
1325         }
1326         if (!argc_l) {
1327                 free_job(job);
1328                 return 0;
1329         }
1330         prog->argv[argc_l] = NULL;
1331
1332         if (!return_command) {
1333                 job->text = xmalloc(strlen(*command_ptr) + 1);
1334                 strcpy(job->text, *command_ptr);
1335         } else {
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';
1341         }
1342
1343         *command_ptr = return_command;
1344         
1345         return 0;
1346 }
1347
1348 /* Run the child_prog, no matter what kind of command it uses.
1349  */
1350 static int pseudo_exec(struct child_prog *child)
1351 {
1352         struct built_in_command *x;
1353 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
1354         struct BB_applet search_applet, *applet;
1355 #endif
1356
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.
1361          */
1362         for (x = bltins; x->cmd; x++) {
1363                 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1364                         exit(x->function(child));
1365                 }
1366         }
1367
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) {
1371                         applet_name=x->cmd;
1372                         exit (x->function(child));
1373                 }
1374         }
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.
1386          */
1387         search_applet.name = child->argv[0];
1388
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.  :-)
1394          */
1395         search_applet.name = get_last_path_component(search_applet.name);
1396 #endif
1397
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) {
1402                 int argc_l;
1403                 char** argv=child->argv;
1404                 for(argc_l=0;*argv!=NULL; argv++, argc_l++);
1405                 applet_name=applet->name;
1406                 optind = 1;
1407                 exit((*(applet->main)) (argc_l, child->argv));
1408         }
1409 #endif
1410
1411         execvp(child->argv[0], child->argv);
1412         perror_msg_and_die("%s", child->argv[0]);
1413 }
1414
1415 static void insert_job(struct job *newjob, int inbg)
1416 {
1417         struct job *thejob;
1418         struct jobset *job_list=newjob->job_list;
1419
1420         /* find the ID for thejob to use */
1421         newjob->jobid = 1;
1422         for (thejob = job_list->head; thejob; thejob = thejob->next)
1423                 if (thejob->jobid >= newjob->jobid)
1424                         newjob->jobid = thejob->jobid + 1;
1425
1426         /* add thejob to the list of running jobs */
1427         if (!job_list->head) {
1428                 thejob = job_list->head = xmalloc(sizeof(*thejob));
1429         } else {
1430                 for (thejob = job_list->head; thejob->next; thejob = thejob->next) /* nothing */;
1431                 thejob->next = xmalloc(sizeof(*thejob));
1432                 thejob = thejob->next;
1433         }
1434
1435         *thejob = *newjob;   /* physically copy the struct job */
1436         thejob->next = NULL;
1437         thejob->running_progs = thejob->num_progs;
1438         thejob->stopped_progs = 0;
1439
1440         if (inbg) {
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;
1447 #endif
1448         } else {
1449                 newjob->job_list->fg = thejob;
1450
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");
1455         }
1456 }
1457
1458 static int run_command(struct job *newjob, int inbg, int outpipe[2])
1459 {
1460         /* struct job *thejob; */
1461         int i;
1462         int nextin, nextout;
1463         int pipefds[2];                         /* pipefd[0] is for reading */
1464         struct built_in_command *x;
1465         struct child_prog *child;
1466
1467         nextin = 0, nextout = 1;
1468         for (i = 0; i < newjob->num_progs; i++) {
1469                 child = & (newjob->progs[i]);
1470
1471                 if ((i + 1) < newjob->num_progs) {
1472                         if (pipe(pipefds)<0) perror_msg_and_die("pipe");
1473                         nextout = pipefds[1];
1474                 } else {
1475                         if (outpipe[1]!=-1) {
1476                                 nextout = outpipe[1];
1477                         } else {
1478                                 nextout = 1;
1479                         }
1480                 }
1481
1482 #ifdef BB_FEATURE_SH_ENVIRONMENT
1483                 if (show_x_trace==TRUE) {
1484                         int j;
1485                         fputc('+', stderr);
1486                         for (j = 0; child->argv[j]; j++) {
1487                                 fputc(' ', stderr);
1488                                 fputs(child->argv[j], stderr);
1489                         }
1490                         fputc('\n', stderr);
1491                 }
1492 #endif
1493
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.
1499                  */
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};
1504                                         int rcode;
1505                                         setup_redirects(child, squirrel);
1506                                         rcode = x->function(child);
1507                                         restore_redirects(squirrel);
1508                                         return rcode;
1509                                 }
1510                         }
1511                 }
1512
1513                 if (!(child->pid = fork())) {
1514                         signal(SIGTTOU, SIG_DFL);
1515
1516                         close_all();
1517
1518                         if (outpipe[1]!=-1) {
1519                                 close(outpipe[0]);
1520                         }
1521                         if (nextin != 0) {
1522                                 dup2(nextin, 0);
1523                                 close(nextin);
1524                         }
1525
1526                         if (nextout != 1) {
1527                                 dup2(nextout, 1);
1528                                 dup2(nextout, 2);  /* Really? */
1529                                 close(nextout);
1530                                 close(pipefds[0]);
1531                         }
1532
1533                         /* explicit redirects override pipes */
1534                         setup_redirects(child,NULL);
1535
1536                         pseudo_exec(child);
1537                 }
1538                 if (outpipe[1]!=-1) {
1539                         close(outpipe[1]);
1540                 }
1541
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);
1545                 if (nextin != 0)
1546                         close(nextin);
1547                 if (nextout != 1)
1548                         close(nextout);
1549
1550                 /* If there isn't another process, nextin is garbage 
1551                    but it doesn't matter */
1552                 nextin = pipefds[0];
1553         }
1554
1555         newjob->pgrp = newjob->progs[0].pid;
1556
1557         insert_job(newjob, inbg);
1558
1559         return 0;
1560 }
1561
1562 static int busy_loop(FILE * input)
1563 {
1564         char *command;
1565         char *next_command = NULL;
1566         struct job newjob;
1567         pid_t  parent_pgrp;
1568         int i;
1569         int inbg;
1570         int status;
1571         newjob.job_list = &job_list;
1572         newjob.job_context = DEFAULT_CONTEXT;
1573
1574         /* save current owner of TTY so we can restore it on exit */
1575         parent_pgrp = tcgetpgrp(0);
1576
1577         command = (char *) xcalloc(BUFSIZ, sizeof(char));
1578
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);
1582
1583         while (1) {
1584                 if (!job_list.fg) {
1585                         /* no job is in the foreground */
1586
1587                         /* see if any background processes have exited */
1588                         checkjobs(&job_list);
1589
1590                         if (!next_command) {
1591                                 if (get_command(input, command))
1592                                         break;
1593                                 next_command = command;
1594                         }
1595
1596                         if (!parse_command(&next_command, &newjob, &inbg) &&
1597                                 newjob.num_progs) {
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);
1601                         }
1602                         else {
1603                                 free(command);
1604                                 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1605                                 next_command = NULL;
1606                         }
1607                 } else {
1608                         /* a job is running in the foreground; wait for it */
1609                         i = 0;
1610                         while (!job_list.fg->progs[i].pid ||
1611                                    job_list.fg->progs[i].is_stopped == 1) i++;
1612
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);
1615
1616                         if (WIFEXITED(status) || WIFSIGNALED(status)) {
1617                                 /* the child exited */
1618                                 job_list.fg->running_progs--;
1619                                 job_list.fg->progs[i].pid = 0;
1620
1621 #ifdef BB_FEATURE_SH_ENVIRONMENT
1622                                 last_return_code=WEXITSTATUS(status);
1623 #endif
1624                                 debug_printf("'%s' exited -- return code %d\n",
1625                                                 job_list.fg->text, last_return_code);
1626                                 if (!job_list.fg->running_progs) {
1627                                         /* child exited */
1628                                         remove_job(&job_list, job_list.fg);
1629                                         job_list.fg = NULL;
1630                                 }
1631                         } else {
1632                                 /* the child was stopped */
1633                                 job_list.fg->stopped_progs++;
1634                                 job_list.fg->progs[i].is_stopped = 1;
1635
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);
1639                                         job_list.fg = NULL;
1640                                 }
1641                         }
1642
1643                         if (!job_list.fg) {
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"); 
1648                         }
1649                 }
1650         }
1651         free(command);
1652
1653         /* return controlling TTY back to parent process group before exiting */
1654         if (tcsetpgrp(0, parent_pgrp))
1655                 perror_msg("tcsetpgrp");
1656
1657         /* return exit status if called with "-c" */
1658         if (input == NULL && WIFEXITED(status))
1659                 return WEXITSTATUS(status);
1660         
1661         return 0;
1662 }
1663
1664
1665 #ifdef BB_FEATURE_CLEAN_UP
1666 void free_memory(void)
1667 {
1668         if (cwd)
1669                 free(cwd);
1670         if (local_pending_command)
1671                 free(local_pending_command);
1672
1673         if (job_list.fg && !job_list.fg->running_progs) {
1674                 remove_job(&job_list, job_list.fg);
1675         }
1676 }
1677 #endif
1678
1679
1680 int shell_main(int argc_l, char **argv_l)
1681 {
1682         int opt, interactive=FALSE;
1683         FILE *input = stdin;
1684         argc = argc_l;
1685         argv = argv_l;
1686
1687         shell_context = 0;
1688         cwd=NULL;
1689 #ifdef BB_FEATURE_STANDALONE_SHELL
1690         /* These variables need re-initializing when recursing */
1691         local_pending_command = NULL;
1692         job_list.head = NULL;
1693         job_list.fg = NULL;
1694 #ifdef BB_FEATURE_SH_ENVIRONMENT
1695         last_bg_pid=-1;
1696         last_return_code=-1;
1697         show_x_trace=FALSE;
1698 #endif
1699 #endif
1700
1701         if (argv[0] && argv[0][0] == '-') {
1702                 FILE *prof_input;
1703                 prof_input = fopen("/etc/profile", "r");
1704                 if (!prof_input) {
1705                         printf( "Couldn't open file '/etc/profile'\n");
1706                 } else {
1707                         int tmp_fd = fileno(prof_input);
1708                         mark_open(tmp_fd);      
1709                         /* Now run the file */
1710                         busy_loop(prof_input);
1711                         fclose(prof_input);
1712                         mark_closed(tmp_fd);
1713                 }
1714         }
1715
1716         while ((opt = getopt(argc_l, argv_l, "cxi")) > 0) {
1717                 switch (opt) {
1718                         case 'c':
1719                                 input = NULL;
1720                                 if (local_pending_command != 0)
1721                                         error_msg_and_die("multiple -c arguments\n");
1722                                 local_pending_command = xstrdup(argv[optind]);
1723                                 optind++;
1724                                 argv = argv+optind;
1725                                 break;
1726 #ifdef BB_FEATURE_SH_ENVIRONMENT
1727                         case 'x':
1728                                 show_x_trace = TRUE;
1729                                 break;
1730 #endif
1731                         case 'i':
1732                                 interactive = TRUE;
1733                                 break;
1734                         default:
1735                                 usage(shell_usage);
1736                 }
1737         }
1738         /* A shell is interactive if the `-i' flag was given, or if all of
1739          * the following conditions are met:
1740          *        no -c command
1741          *    no arguments remaining or the -s flag given
1742          *    standard input is a terminal
1743          *    standard output is a terminal
1744          *    Refer to Posix.2, the description of the `sh' utility. */
1745         if (argv[optind]==NULL && input==stdin &&
1746                         isatty(fileno(stdin)) && isatty(fileno(stdout))) {
1747                 interactive=TRUE;
1748         }
1749         if (interactive==TRUE) {
1750                 //printf( "optind=%d  argv[optind]='%s'\n", optind, argv[optind]);
1751                 /* Looks like they want an interactive shell */
1752                 printf( "\n\nBusyBox v%s (%s) Built-in shell (lash)\n", BB_VER, BB_BT);
1753                 printf( "Enter 'help' for a list of built-in commands.\n\n");
1754         } else if (local_pending_command==NULL) {
1755                 //printf( "optind=%d  argv[optind]='%s'\n", optind, argv[optind]);
1756                 input = xfopen(argv[optind], "r");
1757                 mark_open(fileno(input));  /* be lazy, never mark this closed */
1758         }
1759
1760         /* initialize the cwd -- this is never freed...*/
1761         cwd=(char*)xmalloc(sizeof(char)*MAX_LINE+1);
1762         getcwd(cwd, sizeof(char)*MAX_LINE);
1763
1764 #ifdef BB_FEATURE_CLEAN_UP
1765         atexit(free_memory);
1766 #endif
1767
1768         return (busy_loop(input));
1769 }