Fix up some silly macros and use xmalloc and friends exclusively.
[oweals/busybox.git] / sh.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * lash -- the BusyBox Lame-Ass SHell
4  *
5  * Copyright (C) 1999,2000,2001 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 <stdio.h>
53 #include <stdlib.h>
54 #include <ctype.h>
55 #include <errno.h>
56 #include <fcntl.h>
57 #include <glob.h>
58 #include <signal.h>
59 #include <string.h>
60 #include <sys/ioctl.h>
61 #include <sys/wait.h>
62 #include <unistd.h>
63 #include <getopt.h>
64 #include "busybox.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
71
72 enum redir_type { REDIRECT_INPUT, REDIRECT_OVERWRITE,
73         REDIRECT_APPEND
74 };
75
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;
81
82
83 struct jobset {
84         struct job *head;                       /* head of list of running jobs */
85         struct job *fg;                         /* current foreground job */
86 };
87
88 struct redir_struct {
89         enum redir_type type;   /* type of redirection */
90         int fd;                                         /* file descriptor being redirected */
91         char *filename;                         /* file to redirect fd to */
92 };
93
94 struct child_prog {
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 */
103 };
104
105 struct 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;
117 };
118
119 struct built_in_command {
120         char *cmd;                                      /* name */
121         char *descr;                            /* description */
122         int (*function) (struct child_prog *);  /* function ptr */
123 };
124
125 struct close_me {
126         int fd;
127         struct close_me *next;
128 };
129
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);
150 #endif
151
152
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);
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         close_all();
305         pseudo_exec(child);
306         /* never returns */
307 }
308
309 /* built-in 'exit' handler */
310 static int builtin_exit(struct child_prog *child)
311 {
312         if (child->argv[1] == NULL)
313                 exit(EXIT_SUCCESS);
314
315         exit (atoi(child->argv[1]));
316 }
317
318 /* built-in 'fg' and 'bg' handler */
319 static int builtin_fg_bg(struct child_prog *child)
320 {
321         int i, jobNum;
322         struct job *job=NULL;
323         
324         if (!child->argv[1] || child->argv[2]) {
325                 error_msg("%s: exactly one argument is expected",
326                                 child->argv[0]);
327                 return EXIT_FAILURE;
328         }
329
330         if (sscanf(child->argv[1], "%%%d", &jobNum) != 1) {
331                 error_msg("%s: bad argument '%s'",
332                                 child->argv[0], child->argv[1]);
333                 return EXIT_FAILURE;
334         }
335
336         for (job = child->family->job_list->head; job; job = job->next) {
337                 if (job->jobid == jobNum) {
338                         break;
339                 }
340         }
341
342         if (!job) {
343                 error_msg("%s: unknown job %d",
344                                 child->argv[0], jobNum);
345                 return EXIT_FAILURE;
346         }
347
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;
354         }
355
356         /* Restart the processes in the job */
357         for (i = 0; i < job->num_progs; i++)
358                 job->progs[i].is_stopped = 0;
359
360         kill(-job->pgrp, SIGCONT);
361
362         job->stopped_progs = 0;
363
364         return EXIT_SUCCESS;
365 }
366
367 /* built-in 'help' handler */
368 static int builtin_help(struct child_prog *dummy)
369 {
370         struct built_in_command *x;
371
372         printf("\nBuilt-in commands:\n");
373         printf("-------------------\n");
374         for (x = bltins; x->cmd; x++) {
375                 if (x->descr==NULL)
376                         continue;
377                 printf("%s\t%s\n", x->cmd, x->descr);
378         }
379         for (x = bltins_forking; x->cmd; x++) {
380                 if (x->descr==NULL)
381                         continue;
382                 printf("%s\t%s\n", x->cmd, x->descr);
383         }
384         printf("\n\n");
385         return EXIT_SUCCESS;
386 }
387
388 /* built-in 'jobs' handler */
389 static int builtin_jobs(struct child_prog *child)
390 {
391         struct job *job;
392         char *status_string;
393
394         for (job = child->family->job_list->head; job; job = job->next) {
395                 if (job->running_progs == job->stopped_progs)
396                         status_string = "Stopped";
397                 else
398                         status_string = "Running";
399
400                 printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->text);
401         }
402         return EXIT_SUCCESS;
403 }
404
405
406 /* built-in 'pwd' handler */
407 static int builtin_pwd(struct child_prog *dummy)
408 {
409         getcwd(cwd, MAX_LINE);
410         printf( "%s\n", cwd);
411         return EXIT_SUCCESS;
412 }
413
414 /* built-in 'export VAR=value' handler */
415 static int builtin_export(struct child_prog *child)
416 {
417         int res;
418
419         if (child->argv[1] == NULL) {
420                 return (builtin_env(child));
421         }
422         res = putenv(child->argv[1]);
423         if (res)
424                 fprintf(stderr, "export: %s\n", strerror(errno));
425         return (res);
426 }
427
428 /* built-in 'read VAR' handler */
429 static int builtin_read(struct child_prog *child)
430 {
431         int res = 0, len, newlen;
432         char *s;
433         char string[MAX_READ];
434
435         if (child->argv[1]) {
436                 /* argument (VAR) given: put "VAR=" into buffer */
437                 strcpy(string, child->argv[1]);
438                 len = strlen(string);
439                 string[len++] = '=';
440                 string[len]   = '\0';
441                 fgets(&string[len], sizeof(string) - len, stdin);       /* read string */
442                 newlen = strlen(string);
443                 if(newlen > len)
444                         string[--newlen] = '\0';        /* chomp trailing newline */
445                 /*
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!)
449                 */
450                 res = -1;
451                 if((s = strdup(string)))
452                         res = putenv(s);
453                 if (res)
454                         fprintf(stderr, "read: %s\n", strerror(errno));
455         }
456         else
457                 fgets(string, sizeof(string), stdin);
458
459         return (res);
460 }
461
462 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
463 /* Built-in handler for 'if' commands */
464 static int builtin_if(struct child_prog *child)
465 {
466         struct job *cmd = child->family;
467         int status;
468         char* charptr1=cmd->text+3; /* skip over the leading 'if ' */
469
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 ");
474         if (status == 0) {
475                 debug_printf( "TRUE\n");
476                 cmd->job_context |= IF_TRUE_CONTEXT;
477         } else {
478                 debug_printf( "FALSE\n");
479                 cmd->job_context |= IF_FALSE_CONTEXT;
480         }
481         debug_printf("job=%p builtin_if set job context to %x\n", cmd, cmd->job_context);
482         shell_context++;
483
484         return status;
485 }
486
487 /* Built-in handler for 'then' (part of the 'if' command) */
488 static int builtin_then(struct child_prog *child)
489 {
490         struct job *cmd = child->family;
491         char* charptr1=cmd->text+5; /* skip over the leading 'then ' */
492
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);
497                 return EXIT_FAILURE;
498         }
499
500         cmd->job_context |= THEN_EXP_CONTEXT;
501         debug_printf("job=%p builtin_then set job context to %x\n", cmd, cmd->job_context);
502
503         /* If the if result was FALSE, skip the 'then' stuff */
504         if (cmd->job_context & IF_FALSE_CONTEXT) {
505                 return EXIT_SUCCESS;
506         }
507
508         /* Seems the if result was TRUE, so run the 'then' command */
509         debug_printf( "'then' now running '%s'\n", charptr1);
510
511         return(run_command_predicate(charptr1));
512 }
513
514 /* Built-in handler for 'else' (part of the 'if' command) */
515 static int builtin_else(struct child_prog *child)
516 {
517         struct job *cmd = child->family;
518         char* charptr1=cmd->text+5; /* skip over the leading 'else ' */
519
520         debug_printf( "job=%p entering builtin_else ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
521
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);
525                 return EXIT_FAILURE;
526         }
527         /* If the if result was TRUE, skip the 'else' stuff */
528         if (cmd->job_context & IF_TRUE_CONTEXT) {
529                 return EXIT_SUCCESS;
530         }
531
532         cmd->job_context |= ELSE_EXP_CONTEXT;
533         debug_printf("job=%p builtin_else set job context to %x\n", cmd, cmd->job_context);
534
535         /* Now run the 'else' command */
536         debug_printf( "'else' now running '%s'\n", charptr1);
537         return(run_command_predicate(charptr1));
538 }
539
540 /* Built-in handler for 'fi' (part of the 'if' command) */
541 static int builtin_fi(struct child_prog *child)
542 {
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);
548                 return EXIT_FAILURE;
549         }
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);
553         shell_context--;
554         return EXIT_SUCCESS;
555 }
556 #endif
557
558 /* Built-in '.' handler (read-in and execute commands from file) */
559 static int builtin_source(struct child_prog *child)
560 {
561         FILE *input;
562         int status;
563         int fd;
564
565         if (child->argv[1] == NULL)
566                 return EXIT_FAILURE;
567
568         input = fopen(child->argv[1], "r");
569         if (!input) {
570                 printf( "Couldn't open file '%s'\n", child->argv[1]);
571                 return EXIT_FAILURE;
572         }
573
574         fd=fileno(input);
575         mark_open(fd);
576         /* Now run the file */
577         status = busy_loop(input);
578         fclose(input);
579         mark_closed(fd);
580         return (status);
581 }
582
583 /* built-in 'unset VAR' handler */
584 static int builtin_unset(struct child_prog *child)
585 {
586         if (child->argv[1] == NULL) {
587                 printf( "unset: parameter required.\n");
588                 return EXIT_FAILURE;
589         }
590         unsetenv(child->argv[1]);
591         return EXIT_SUCCESS;
592 }
593
594 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
595 /* currently used by if/then/else.
596  *
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.
603  */
604 static int run_command_predicate(char *cmd)
605 {
606         int n=strlen(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));
611 }
612 #endif
613
614 static void mark_open(int fd)
615 {
616         struct close_me *new = xmalloc(sizeof(struct close_me));
617         new->fd = fd;
618         new->next = close_me_head;
619         close_me_head = new;
620 }
621
622 static void mark_closed(int fd)
623 {
624         struct close_me *tmp;
625         if (close_me_head == NULL || close_me_head->fd != fd)
626                 error_msg_and_die("corrupt close_me");
627         tmp = close_me_head;
628         close_me_head = close_me_head->next;
629         free(tmp);
630 }
631
632 static void close_all()
633 {
634         struct close_me *c;
635         for (c=close_me_head; c; c=c->next) {
636                 mark_closed(c->fd);
637         }
638         close_me_head = NULL;
639 }
640
641
642 /* free up all memory from a job */
643 static void free_job(struct job *cmd)
644 {
645         int i;
646
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);
653         }
654         free(cmd->progs);
655         if (cmd->text)
656                 free(cmd->text);
657         free(cmd->cmdbuf);
658         memset(cmd, 0, sizeof(struct job));
659 }
660
661 /* remove a job from the job_list */
662 static void remove_job(struct jobset *job_list, struct job *job)
663 {
664         struct job *prevjob;
665
666         free_job(job);
667         if (job == job_list->head) {
668                 job_list->head = job->next;
669         } else {
670                 prevjob = job_list->head;
671                 while (prevjob->next != job)
672                         prevjob = prevjob->next;
673                 prevjob->next = job->next;
674         }
675
676         free(job);
677 }
678
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)
682 {
683         struct job *job;
684         pid_t childpid;
685         int status;
686         int prognum = 0;
687
688         while ((childpid = waitpid(-1, &status, WNOHANG | WUNTRACED)) > 0) {
689                 for (job = job_list->head; job; job = job->next) {
690                         prognum = 0;
691                         while (prognum < job->num_progs &&
692                                    job->progs[prognum].pid != childpid) prognum++;
693                         if (prognum < job->num_progs)
694                                 break;
695                 }
696
697                 /* This happens on backticked commands */
698                 if(job==NULL)
699                         return;
700
701                 if (WIFEXITED(status) || WIFSIGNALED(status)) {
702                         /* child exited */
703                         job->running_progs--;
704                         job->progs[prognum].pid = 0;
705
706                         if (!job->running_progs) {
707                                 printf(JOB_STATUS_FORMAT, job->jobid, "Done", job->text);
708                                 remove_job(job_list, job);
709                         }
710                 } else {
711                         /* child stopped */
712                         job->stopped_progs++;
713                         job->progs[prognum].is_stopped = 1;
714
715                         if (job->stopped_progs == job->num_progs) {
716                                 printf(JOB_STATUS_FORMAT, job->jobid, "Stopped",
717                                            job->text);
718                         }
719                 }
720         }
721
722         if (childpid == -1 && errno != ECHILD)
723                 perror_msg("waitpid");
724 }
725
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[])
729 {
730         int i;
731         int openfd;
732         int mode = O_RDONLY;
733         struct redir_struct *redir = prog->redirects;
734
735         for (i = 0; i < prog->num_redirects; i++, redir++) {
736                 switch (redir->type) {
737                 case REDIRECT_INPUT:
738                         mode = O_RDONLY;
739                         break;
740                 case REDIRECT_OVERWRITE:
741                         mode = O_WRONLY | O_CREAT | O_TRUNC;
742                         break;
743                 case REDIRECT_APPEND:
744                         mode = O_WRONLY | O_CREAT | O_APPEND;
745                         break;
746                 }
747
748                 openfd = open(redir->filename, mode, 0666);
749                 if (openfd < 0) {
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,
753                                         strerror(errno));
754                         return 1;
755                 }
756
757                 if (openfd != redir->fd) {
758                         if (squirrel && redir->fd < 3) {
759                                 squirrel[redir->fd] = dup(redir->fd);
760                         }
761                         dup2(openfd, redir->fd);
762                         close(openfd);
763                 }
764         }
765
766         return 0;
767 }
768
769 static void restore_redirects(int squirrel[])
770 {
771         int i, fd;
772         for (i=0; i<3; i++) {
773                 fd = squirrel[i];
774                 if (fd != -1) {
775                         /* No error checking.  I sure wouldn't know what
776                          * to do with an error if I found one! */
777                         dup2(fd, i);
778                         close(fd);
779                 }
780         }
781 }
782
783 #if defined(BB_FEATURE_SH_SIMPLE_PROMPT)
784 static char* setup_prompt_string(int state)
785 {
786        char prompt_str[BUFSIZ];
787
788        /* Set up the prompt */
789        if (state == 0) {
790                /* simple prompt */
791                sprintf(prompt_str, "%s %s", cwd, ( geteuid() != 0 ) ?  "$ ":"# ");
792        } else {
793                strcpy(prompt_str,"> ");
794        }
795
796        return(strdup(prompt_str));  /* Must free this memory */
797 }
798
799 #else
800
801 static char* setup_prompt_string(int state)
802 {
803         char user[9],buf[255],*s;
804         char prompt[3];
805         char prompt_str[BUFSIZ];
806
807         /* Set up the prompt */
808         if (state == 0) {
809                 /* get User Name and setup prompt */
810                 strcpy(prompt,( geteuid() != 0 ) ? "$ ":"# ");
811                 my_getpwuid(user, geteuid());
812
813                 /* get HostName */
814                 gethostname(buf, 255);
815                 s = strchr(buf, '.');
816                 if (s) {
817                         *s = 0;
818                 }
819         } else {
820                 strcpy(prompt,"> ");
821         }
822
823         if (state == 0) {
824                 snprintf(prompt_str, BUFSIZ-1, "[%s@%s %s]%s", user, buf, 
825                                 get_last_path_component(cwd), prompt);
826         } else {
827                 sprintf(prompt_str, "%s", prompt);
828         }
829         return(strdup(prompt_str));  /* Must free this memory */
830 }
831
832 #endif 
833
834 static int get_command(FILE * source, char *command)
835 {
836         char *prompt_str;
837
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;
844                         return 0;
845                 }
846                 return 1;
847         }
848
849         if (source == stdin) {
850                 prompt_str = setup_prompt_string(shell_context);
851
852 #ifdef BB_FEATURE_SH_COMMAND_EDITING
853                 /*
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)
858                 */
859                 cmdedit_read_input(prompt_str, command);
860                 cmdedit_terminate();
861                 free(prompt_str);
862                 return 0;
863 #else
864                 fputs(prompt_str, stdout);
865                 free(prompt_str);
866 #endif
867         }
868
869         if (!fgets(command, BUFSIZ - 2, source)) {
870                 if (source == stdin)
871                         printf("\n");
872                 return 1;
873         }
874
875         /* remove trailing newline */
876         command[strlen(command) - 1] = '\0';
877
878         return 0;
879 }
880
881 #ifdef BB_FEATURE_SH_ENVIRONMENT
882 static char* itoa(register int i)
883 {
884         static char a[7]; /* Max 7 ints */
885         register char *b = a + sizeof(a) - 1;
886         int   sign = (i < 0);
887
888         if (sign)
889                 i = -i;
890         *b = 0;
891         do
892         {
893                 *--b = '0' + (i % 10);
894                 i /= 10;
895         }
896         while (i);
897         if (sign)
898                 *--b = '-';
899         return b;
900 }
901 #endif
902
903 static void expand_argument(struct child_prog *prog, int *argcPtr,
904                                                          int *argv_alloced_ptr)
905 {
906         int argc_l = *argcPtr;
907         int argv_alloced = *argv_alloced_ptr;
908         int rc;
909         int flags;
910         int i;
911         char *src, *dst, *var;
912
913         if (argc_l > 1) {                               /* cmd->glob_result is already initialized */
914                 flags = GLOB_APPEND;
915                 i = prog->glob_result.gl_pathc;
916         } else {
917                 prog->free_glob = 1;
918                 flags = 0;
919                 i = 0;
920         }
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))) {
926                         switch(*(dst+1)) {
927                                 case '?':
928                                         var = itoa(last_return_code);
929                                         break;
930                                 case '$':
931                                         var = itoa(getpid());
932                                         break;
933                                 case '#':
934                                         var = itoa(argc-1);
935                                         break;
936                                 case '!':
937                                         if (last_bg_pid==-1)
938                                                 *(var)='\0';
939                                         else
940                                                 var = itoa(last_bg_pid);
941                                         break;
942                                 case '0':case '1':case '2':case '3':case '4':
943                                 case '5':case '6':case '7':case '8':case '9':
944                                         {
945                                                 int index=*(dst + 1)-48;
946                                                 if (index >= argc) {
947                                                         var='\0';
948                                                 } else {
949                                                         var = argv[index];
950                                                 }
951                                         }
952                                         break;
953                         }
954                 }
955                 if (var) {
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) {
963                                 offset=strlen(src);
964                                 safe_strncpy(src+strlen(src), dst, strlen(dst)+1);
965                         }
966                         prog->argv[argc_l -1] = src;
967                 } else {
968                         memset(dst, 0, strlen(src)-strlen(dst)); 
969                 }
970         }
971 #endif
972
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");
977                         return;
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];
984                         while (*src) {
985                                 if (*src == '\\') {
986                                         src++; 
987                                         *dst++ = process_escape_sequence(&src);
988                                 } else { 
989                                         *dst++ = *src;
990                                         src++;
991                                 }
992                         }
993                         *dst = '\0';
994                 } else if (!rc) {
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);
1000                 }
1001         }else{
1002                         src = dst = prog->argv[argc_l - 1];
1003                         while (*src) {
1004                                 if (*src == '\\') {
1005                                         src++; 
1006                                         *dst++ = process_escape_sequence(&src);
1007                                 } else { 
1008                                         *dst++ = *src;
1009                                         src++;
1010                                 }
1011                         }
1012                         *dst = '\0';
1013                         
1014                         prog->glob_result.gl_pathc=0;
1015                         if (flags==0)
1016                                 prog->glob_result.gl_pathv=NULL;
1017         }
1018         *argv_alloced_ptr = argv_alloced;
1019         *argcPtr = argc_l;
1020 }
1021
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 
1026    present. */
1027 static int parse_command(char **command_ptr, struct job *job, int *inbg)
1028 {
1029         char *command;
1030         char *return_command = NULL;
1031         char *src, *buf, *chptr;
1032         int argc_l = 0;
1033         int done = 0;
1034         int argv_alloced;
1035         int i;
1036         char quote = '\0';
1037         int count;
1038         struct child_prog *prog;
1039
1040         /* skip leading white space */
1041         while (**command_ptr && isspace(**command_ptr))
1042                 (*command_ptr)++;
1043
1044         /* this handles empty lines or leading '#' characters */
1045         if (!**command_ptr || (**command_ptr == '#')) {
1046                 job->num_progs=0;
1047                 return 0;
1048         }
1049
1050         *inbg = 0;
1051         job->num_progs = 1;
1052         job->progs = xmalloc(sizeof(*job->progs));
1053
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.
1057
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));
1062         job->text = NULL;
1063
1064         prog = job->progs;
1065         prog->num_redirects = 0;
1066         prog->redirects = NULL;
1067         prog->free_glob = 0;
1068         prog->is_stopped = 0;
1069         prog->family = job;
1070
1071         argv_alloced = 5;
1072         prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1073         prog->argv[0] = job->cmdbuf;
1074
1075         buf = command;
1076         src = *command_ptr;
1077         while (*src && !done) {
1078                 if (quote == *src) {
1079                         quote = '\0';
1080                 } else if (quote) {
1081                         if (*src == '\\') {
1082                                 src++;
1083                                 if (!*src) {
1084                                         error_msg("character expected after \\");
1085                                         free_job(job);
1086                                         return 1;
1087                                 }
1088
1089                                 /* in shell, "\'" should yield \' */
1090                                 if (*src != quote) {
1091                                         *buf++ = '\\';
1092                                         *buf++ = '\\';
1093                                 }
1094                         } else if (*src == '*' || *src == '?' || *src == '[' ||
1095                                            *src == ']') *buf++ = '\\';
1096                         *buf++ = *src;
1097                 } else if (isspace(*src)) {
1098                         if (*prog->argv[argc_l]) {
1099                                 buf++, argc_l++;
1100                                 /* +1 here leaves room for the NULL which ends argv */
1101                                 if ((argc_l + 1) == argv_alloced) {
1102                                         argv_alloced += 5;
1103                                         prog->argv = xrealloc(prog->argv,
1104                                                                                   sizeof(*prog->argv) *
1105                                                                                   argv_alloced);
1106                                 }
1107                                 expand_argument(prog, &argc_l, &argv_alloced);
1108                                 prog->argv[argc_l] = buf;
1109                         }
1110                 } else
1111                         switch (*src) {
1112                         case '"':
1113                         case '\'':
1114                                 quote = *src;
1115                                 break;
1116
1117                         case '#':                       /* comment */
1118                                 if (*(src-1)== '$')
1119                                         *buf++ = *src;
1120                                 else
1121                                         done = 1;
1122                                 break;
1123
1124                         case '>':                       /* redirects */
1125                         case '<':
1126                                 i = prog->num_redirects++;
1127                                 prog->redirects = xrealloc(prog->redirects,
1128                                                                                           sizeof(*prog->redirects) *
1129                                                                                           (i + 1));
1130
1131                                 prog->redirects[i].fd = -1;
1132                                 if (buf != prog->argv[argc_l]) {
1133                                         /* the stuff before this character may be the file number 
1134                                            being redirected */
1135                                         prog->redirects[i].fd =
1136                                                 strtol(prog->argv[argc_l], &chptr, 10);
1137
1138                                         if (*chptr && *prog->argv[argc_l]) {
1139                                                 buf++, argc_l++;
1140                                                 expand_argument(prog, &argc_l, &argv_alloced);
1141                                                 prog->argv[argc_l] = buf;
1142                                         }
1143                                 }
1144
1145                                 if (prog->redirects[i].fd == -1) {
1146                                         if (*src == '>')
1147                                                 prog->redirects[i].fd = 1;
1148                                         else
1149                                                 prog->redirects[i].fd = 0;
1150                                 }
1151
1152                                 if (*src++ == '>') {
1153                                         if (*src == '>')
1154                                                 prog->redirects[i].type =
1155                                                         REDIRECT_APPEND, src++;
1156                                         else
1157                                                 prog->redirects[i].type = REDIRECT_OVERWRITE;
1158                                 } else {
1159                                         prog->redirects[i].type = REDIRECT_INPUT;
1160                                 }
1161
1162                                 /* This isn't POSIX sh compliant. Oh well. */
1163                                 chptr = src;
1164                                 while (isspace(*chptr))
1165                                         chptr++;
1166
1167                                 if (!*chptr) {
1168                                         error_msg("file name expected after %c", *src);
1169                                         free_job(job);
1170                                         job->num_progs=0;
1171                                         return 1;
1172                                 }
1173
1174                                 prog->redirects[i].filename = buf;
1175                                 while (*chptr && !isspace(*chptr))
1176                                         *buf++ = *chptr++;
1177
1178                                 src = chptr - 1;        /* we src++ later */
1179                                 prog->argv[argc_l] = ++buf;
1180                                 break;
1181
1182                         case '|':                       /* pipe */
1183                                 /* finish this command */
1184                                 if (*prog->argv[argc_l])
1185                                         argc_l++;
1186                                 if (!argc_l) {
1187                                         error_msg("empty command in pipe");
1188                                         free_job(job);
1189                                         job->num_progs=0;
1190                                         return 1;
1191                                 }
1192                                 prog->argv[argc_l] = NULL;
1193
1194                                 /* and start the next */
1195                                 job->num_progs++;
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;
1203                                 prog->family = job;
1204                                 argc_l = 0;
1205
1206                                 argv_alloced = 5;
1207                                 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1208                                 prog->argv[0] = ++buf;
1209
1210                                 src++;
1211                                 while (*src && isspace(*src))
1212                                         src++;
1213
1214                                 if (!*src) {
1215                                         error_msg("empty command in pipe");
1216                                         free_job(job);
1217                                         job->num_progs=0;
1218                                         return 1;
1219                                 }
1220                                 src--;                  /* we'll ++ it at the end of the loop */
1221
1222                                 break;
1223
1224                         case '&':                       /* background */
1225                                 *inbg = 1;
1226                         case ';':                       /* multiple commands */
1227                                 done = 1;
1228                                 return_command = *command_ptr + (src - *command_ptr) + 1;
1229                                 break;
1230
1231 #ifdef BB_FEATURE_SH_BACKTICKS
1232                         case '`':
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 */
1237                                 {
1238                                         char* charptr1=NULL, *charptr2;
1239                                         char* ptr=NULL;
1240                                         struct job *newjob;
1241                                         struct jobset njob_list = { NULL, NULL };
1242                                         int pipefd[2];
1243                                         int size;
1244
1245                                         ptr=strchr(++src, '`');
1246                                         if (ptr==NULL) {
1247                                                 fprintf(stderr, "Unmatched '`' in command\n");
1248                                                 free_job(job);
1249                                                 return 1;
1250                                         }
1251
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) {
1261                                                 pipe(pipefd);
1262                                                 run_command(newjob, 0, pipefd);
1263                                         }
1264                                         checkjobs(job->job_list);
1265                                         free_job(newjob);  /* doesn't actually free newjob,
1266                                                              looks like a memory leak */
1267                                         free(charptr2);
1268                                         
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));
1273
1274
1275                                         /* Copy the output from the backtick-ed command into the
1276                                          * command line, making extra room as needed  */
1277                                         --src;
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);
1283                                                 }
1284                                                 memcpy(src, charptr1, size); 
1285                                                 src+=size;
1286                                         }
1287                                         free(charptr1);
1288                                         close(pipefd[0]);
1289                                         if (*(src-1)=='\n')
1290                                                 --src;
1291
1292                                         /* Now paste into the *command_ptr all the stuff 
1293                                          * leftover after the second backtick */
1294                                         memcpy(src, charptr2, strlen(charptr2)+1);
1295                                         free(charptr2);
1296
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... */
1300                                         {
1301                                                 struct jobset *jl=job->job_list;
1302                                                 free_job(job);
1303                                                 job->job_list = jl;
1304                                         }
1305                                         return(parse_command(command_ptr, job, inbg));
1306                                 }
1307                                 break;
1308 #endif // BB_FEATURE_SH_BACKTICKS
1309
1310                         case '\\':
1311                                 src++;
1312                                 if (!*src) {
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
1317                                          * command */
1318                                         char *command;
1319                                         int newsize;
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 \\");
1324                                                 free(command);
1325                                                 free_job(job);
1326                                                 return 1;
1327                                         }
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);
1332                                         }
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);
1336                                         free(command);
1337                                         break;
1338 #else
1339                                         error_msg("character expected after \\");
1340                                         free(command);
1341                                         free_job(job);
1342                                         return 1;
1343 #endif
1344                                 }
1345                                 if (*src == '*' || *src == '[' || *src == ']'
1346                                         || *src == '?') *buf++ = '\\';
1347                                 /* fallthrough */
1348                         default:
1349                                 *buf++ = *src;
1350                         }
1351
1352                 src++;
1353         }
1354
1355         if (*prog->argv[argc_l]) {
1356                 argc_l++;
1357                 expand_argument(prog, &argc_l, &argv_alloced);
1358         }
1359         if (!argc_l) {
1360                 free_job(job);
1361                 return 0;
1362         }
1363         prog->argv[argc_l] = NULL;
1364
1365         if (!return_command) {
1366                 job->text = xmalloc(strlen(*command_ptr) + 1);
1367                 strcpy(job->text, *command_ptr);
1368         } else {
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';
1374         }
1375
1376         *command_ptr = return_command;
1377         
1378         return 0;
1379 }
1380
1381 /* Run the child_prog, no matter what kind of command it uses.
1382  */
1383 static int pseudo_exec(struct child_prog *child)
1384 {
1385         struct built_in_command *x;
1386 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
1387         char *name;
1388 #endif
1389
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.
1394          */
1395         for (x = bltins; x->cmd; x++) {
1396                 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1397                         exit(x->function(child));
1398                 }
1399         }
1400
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) {
1404                         applet_name=x->cmd;
1405                         exit (x->function(child));
1406                 }
1407         }
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.
1419          */
1420         name = child->argv[0];
1421
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.  :-)
1427          */
1428         name = get_last_path_component(name);
1429 #endif
1430
1431         {
1432             char** argv=child->argv;
1433             int argc_l;
1434             for(argc_l=0;*argv!=NULL; argv++, argc_l++);
1435             optind = 1;
1436             run_applet_by_name(name, argc_l, child->argv);
1437         }
1438 #endif
1439
1440         execvp(child->argv[0], child->argv);
1441         perror_msg_and_die("%s", child->argv[0]);
1442 }
1443
1444 static void insert_job(struct job *newjob, int inbg)
1445 {
1446         struct job *thejob;
1447         struct jobset *job_list=newjob->job_list;
1448
1449         /* find the ID for thejob to use */
1450         newjob->jobid = 1;
1451         for (thejob = job_list->head; thejob; thejob = thejob->next)
1452                 if (thejob->jobid >= newjob->jobid)
1453                         newjob->jobid = thejob->jobid + 1;
1454
1455         /* add thejob to the list of running jobs */
1456         if (!job_list->head) {
1457                 thejob = job_list->head = xmalloc(sizeof(*thejob));
1458         } else {
1459                 for (thejob = job_list->head; thejob->next; thejob = thejob->next) /* nothing */;
1460                 thejob->next = xmalloc(sizeof(*thejob));
1461                 thejob = thejob->next;
1462         }
1463
1464         *thejob = *newjob;   /* physically copy the struct job */
1465         thejob->next = NULL;
1466         thejob->running_progs = thejob->num_progs;
1467         thejob->stopped_progs = 0;
1468
1469         if (inbg) {
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;
1476 #endif
1477         } else {
1478                 newjob->job_list->fg = thejob;
1479
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");
1484         }
1485 }
1486
1487 static int run_command(struct job *newjob, int inbg, int outpipe[2])
1488 {
1489         /* struct job *thejob; */
1490         int i;
1491         int nextin, nextout;
1492         int pipefds[2];                         /* pipefd[0] is for reading */
1493         struct built_in_command *x;
1494         struct child_prog *child;
1495
1496         nextin = 0, nextout = 1;
1497         for (i = 0; i < newjob->num_progs; i++) {
1498                 child = & (newjob->progs[i]);
1499
1500                 if ((i + 1) < newjob->num_progs) {
1501                         if (pipe(pipefds)<0) perror_msg_and_die("pipe");
1502                         nextout = pipefds[1];
1503                 } else {
1504                         if (outpipe[1]!=-1) {
1505                                 nextout = outpipe[1];
1506                         } else {
1507                                 nextout = 1;
1508                         }
1509                 }
1510
1511 #ifdef BB_FEATURE_SH_ENVIRONMENT
1512                 if (show_x_trace==TRUE) {
1513                         int j;
1514                         fputc('+', stderr);
1515                         for (j = 0; child->argv[j]; j++) {
1516                                 fputc(' ', stderr);
1517                                 fputs(child->argv[j], stderr);
1518                         }
1519                         fputc('\n', stderr);
1520                 }
1521 #endif
1522
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.
1528                  */
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};
1533                                         int rcode;
1534                                         setup_redirects(child, squirrel);
1535                                         rcode = x->function(child);
1536                                         restore_redirects(squirrel);
1537                                         return rcode;
1538                                 }
1539                         }
1540                 }
1541
1542                 if (!(child->pid = fork())) {
1543                         signal(SIGTTOU, SIG_DFL);
1544
1545                         close_all();
1546
1547                         if (outpipe[1]!=-1) {
1548                                 close(outpipe[0]);
1549                         }
1550                         if (nextin != 0) {
1551                                 dup2(nextin, 0);
1552                                 close(nextin);
1553                         }
1554
1555                         if (nextout != 1) {
1556                                 dup2(nextout, 1);
1557                                 dup2(nextout, 2);  /* Really? */
1558                                 close(nextout);
1559                                 close(pipefds[0]);
1560                         }
1561
1562                         /* explicit redirects override pipes */
1563                         setup_redirects(child,NULL);
1564
1565                         pseudo_exec(child);
1566                 }
1567                 if (outpipe[1]!=-1) {
1568                         close(outpipe[1]);
1569                 }
1570
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);
1574                 if (nextin != 0)
1575                         close(nextin);
1576                 if (nextout != 1)
1577                         close(nextout);
1578
1579                 /* If there isn't another process, nextin is garbage 
1580                    but it doesn't matter */
1581                 nextin = pipefds[0];
1582         }
1583
1584         newjob->pgrp = newjob->progs[0].pid;
1585
1586         insert_job(newjob, inbg);
1587
1588         return 0;
1589 }
1590
1591 static int busy_loop(FILE * input)
1592 {
1593         char *command;
1594         char *next_command = NULL;
1595         struct job newjob;
1596         pid_t  parent_pgrp;
1597         int i;
1598         int inbg;
1599         int status;
1600         newjob.job_list = &job_list;
1601         newjob.job_context = DEFAULT_CONTEXT;
1602
1603         /* save current owner of TTY so we can restore it on exit */
1604         parent_pgrp = tcgetpgrp(0);
1605
1606         command = (char *) xcalloc(BUFSIZ, sizeof(char));
1607
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);
1611
1612         while (1) {
1613                 if (!job_list.fg) {
1614                         /* no job is in the foreground */
1615
1616                         /* see if any background processes have exited */
1617                         checkjobs(&job_list);
1618
1619                         if (!next_command) {
1620                                 if (get_command(input, command))
1621                                         break;
1622                                 next_command = command;
1623                         }
1624
1625                         if (!parse_command(&next_command, &newjob, &inbg) &&
1626                                 newjob.num_progs) {
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);
1630                         }
1631                         else {
1632                                 free(command);
1633                                 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1634                                 next_command = NULL;
1635                         }
1636                 } else {
1637                         /* a job is running in the foreground; wait for it */
1638                         i = 0;
1639                         while (!job_list.fg->progs[i].pid ||
1640                                    job_list.fg->progs[i].is_stopped == 1) i++;
1641
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);
1644
1645                         if (WIFEXITED(status) || WIFSIGNALED(status)) {
1646                                 /* the child exited */
1647                                 job_list.fg->running_progs--;
1648                                 job_list.fg->progs[i].pid = 0;
1649
1650 #ifdef BB_FEATURE_SH_ENVIRONMENT
1651                                 last_return_code=WEXITSTATUS(status);
1652 #endif
1653                                 debug_printf("'%s' exited -- return code %d\n",
1654                                                 job_list.fg->text, last_return_code);
1655                                 if (!job_list.fg->running_progs) {
1656                                         /* child exited */
1657                                         remove_job(&job_list, job_list.fg);
1658                                         job_list.fg = NULL;
1659                                 }
1660                         } else {
1661                                 /* the child was stopped */
1662                                 job_list.fg->stopped_progs++;
1663                                 job_list.fg->progs[i].is_stopped = 1;
1664
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);
1668                                         job_list.fg = NULL;
1669                                 }
1670                         }
1671
1672                         if (!job_list.fg) {
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"); 
1677                         }
1678                 }
1679         }
1680         free(command);
1681
1682         /* return controlling TTY back to parent process group before exiting */
1683         if (tcsetpgrp(0, parent_pgrp))
1684                 perror_msg("tcsetpgrp");
1685
1686         /* return exit status if called with "-c" */
1687         if (input == NULL && WIFEXITED(status))
1688                 return WEXITSTATUS(status);
1689         
1690         return 0;
1691 }
1692
1693
1694 #ifdef BB_FEATURE_CLEAN_UP
1695 void free_memory(void)
1696 {
1697         if (cwd)
1698                 free(cwd);
1699         if (local_pending_command)
1700                 free(local_pending_command);
1701
1702         if (job_list.fg && !job_list.fg->running_progs) {
1703                 remove_job(&job_list, job_list.fg);
1704         }
1705 }
1706 #endif
1707
1708
1709 int shell_main(int argc_l, char **argv_l)
1710 {
1711         int opt, interactive=FALSE;
1712         FILE *input = stdin;
1713         argc = argc_l;
1714         argv = argv_l;
1715
1716         shell_context = 0;
1717         cwd=NULL;
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;
1722         job_list.fg = NULL;
1723 #ifdef BB_FEATURE_SH_ENVIRONMENT
1724         last_bg_pid=-1;
1725         last_return_code=-1;
1726         show_x_trace=FALSE;
1727 #endif
1728 #endif
1729
1730         if (argv[0] && argv[0][0] == '-') {
1731                 FILE *prof_input;
1732                 prof_input = fopen("/etc/profile", "r");
1733                 if (!prof_input) {
1734                         printf( "Couldn't open file '/etc/profile'\n");
1735                 } else {
1736                         int tmp_fd = fileno(prof_input);
1737                         mark_open(tmp_fd);      
1738                         /* Now run the file */
1739                         busy_loop(prof_input);
1740                         fclose(prof_input);
1741                         mark_closed(tmp_fd);
1742                 }
1743         }
1744
1745         while ((opt = getopt(argc_l, argv_l, "cxi")) > 0) {
1746                 switch (opt) {
1747                         case 'c':
1748                                 input = NULL;
1749                                 if (local_pending_command != 0)
1750                                         error_msg_and_die("multiple -c arguments");
1751                                 local_pending_command = xstrdup(argv[optind]);
1752                                 optind++;
1753                                 argv = argv+optind;
1754                                 break;
1755 #ifdef BB_FEATURE_SH_ENVIRONMENT
1756                         case 'x':
1757                                 show_x_trace = TRUE;
1758                                 break;
1759 #endif
1760                         case 'i':
1761                                 interactive = TRUE;
1762                                 break;
1763                         default:
1764                                 show_usage();
1765                 }
1766         }
1767         /* A shell is interactive if the `-i' flag was given, or if all of
1768          * the following conditions are met:
1769          *        no -c command
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))) {
1776                 interactive=TRUE;
1777         }
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 */
1787         }
1788
1789         /* initialize the cwd -- this is never freed...*/
1790         cwd=(char*)xmalloc(sizeof(char)*MAX_LINE+1);
1791         getcwd(cwd, sizeof(char)*MAX_LINE);
1792
1793 #ifdef BB_FEATURE_CLEAN_UP
1794         atexit(free_memory);
1795 #endif
1796
1797         return (busy_loop(input));
1798 }