Set the close-on-exec flag, just to be saf
[oweals/busybox.git] / shell / lash.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * lash -- the BusyBox Lame-Ass SHell
4  *
5  * Copyright (C) 1999,2000 by Lineo, inc. and Erik Andersen
6  * Copyright (C) 1999,2000,2001 by Erik Andersen <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 /* This shell's parsing engine is officially at a dead-end.  Future
29  * work shell work should be done using hush, msh, or ash.  This is
30  * still a very useful, small shell -- it just don't need any more
31  * features beyond what it already has...
32  */
33
34 //For debugging/development on the shell only...
35 //#define DEBUG_SHELL
36
37
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <ctype.h>
41 #include <errno.h>
42 #include <fcntl.h>
43 #include <signal.h>
44 #include <string.h>
45 #include <sys/ioctl.h>
46 #include <sys/wait.h>
47 #include <unistd.h>
48 #include <getopt.h>
49 #include <termios.h>
50 #include "busybox.h"
51 #include "cmdedit.h"
52
53 #ifdef CONFIG_LOCALE_SUPPORT
54 #include <locale.h>
55 #endif
56
57 #include <glob.h>
58 #define expand_t        glob_t
59
60
61 static const int MAX_READ = 128;        /* size of input buffer for `read' builtin */
62 #define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
63
64
65 enum redir_type { REDIRECT_INPUT, REDIRECT_OVERWRITE,
66         REDIRECT_APPEND
67 };
68
69 static const unsigned int DEFAULT_CONTEXT=0x1;
70 static const unsigned int IF_TRUE_CONTEXT=0x2;
71 static const unsigned int IF_FALSE_CONTEXT=0x4;
72 static const unsigned int THEN_EXP_CONTEXT=0x8;
73 static const unsigned int ELSE_EXP_CONTEXT=0x10;
74
75
76 struct jobset {
77         struct job *head;                       /* head of list of running jobs */
78         struct job *fg;                         /* current foreground job */
79 };
80
81 struct redir_struct {
82         enum redir_type type;   /* type of redirection */
83         int fd;                                         /* file descriptor being redirected */
84         char *filename;                         /* file to redirect fd to */
85 };
86
87 struct child_prog {
88         pid_t pid;                                      /* 0 if exited */
89         char **argv;                            /* program name and arguments */
90         int num_redirects;                      /* elements in redirection array */
91         struct redir_struct *redirects; /* I/O redirects */
92         int is_stopped;                         /* is the program currently running? */
93         struct job *family;                     /* pointer back to the child's parent job */
94 };
95
96 struct job {
97         int jobid;                                      /* job number */
98         int num_progs;                          /* total number of programs in job */
99         int running_progs;                      /* number of programs running */
100         char *text;                                     /* name of job */
101         char *cmdbuf;                           /* buffer various argv's point into */
102         pid_t pgrp;                                     /* process group ID for the job */
103         struct child_prog *progs;       /* array of programs in job */
104         struct job *next;                       /* to track background commands */
105         int stopped_progs;                      /* number of programs alive, but stopped */
106         unsigned int job_context;       /* bitmask defining current context */
107         struct jobset *job_list;
108 };
109
110 struct built_in_command {
111         char *cmd;                                      /* name */
112         char *descr;                            /* description */
113         int (*function) (struct child_prog *);  /* function ptr */
114 };
115
116 struct close_me {
117         int fd;
118         struct close_me *next;
119 };
120
121 /* function prototypes for builtins */
122 static int builtin_cd(struct child_prog *cmd);
123 static int builtin_exec(struct child_prog *cmd);
124 static int builtin_exit(struct child_prog *cmd);
125 static int builtin_fg_bg(struct child_prog *cmd);
126 static int builtin_help(struct child_prog *cmd);
127 static int builtin_jobs(struct child_prog *dummy);
128 static int builtin_pwd(struct child_prog *dummy);
129 static int builtin_export(struct child_prog *cmd);
130 static int builtin_source(struct child_prog *cmd);
131 static int builtin_unset(struct child_prog *cmd);
132 static int builtin_read(struct child_prog *cmd);
133
134
135 /* function prototypes for shell stuff */
136 static void mark_open(int fd);
137 static void mark_closed(int fd);
138 static void close_all(void);
139 static void checkjobs(struct jobset *job_list);
140 static void remove_job(struct jobset *j_list, struct job *job);
141 static int get_command(FILE * source, char *command);
142 static int parse_command(char **command_ptr, struct job *job, int *inbg);
143 static int run_command(struct job *newjob, int inbg, int outpipe[2]);
144 static int pseudo_exec(struct child_prog *cmd) __attribute__ ((noreturn));
145 static int busy_loop(FILE * input);
146
147
148 /* Table of built-in functions (these are non-forking builtins, meaning they
149  * can change global variables in the parent shell process but they will not
150  * work with pipes and redirects; 'unset foo | whatever' will not work) */
151 static struct built_in_command bltins[] = {
152         {"bg", "Resume a job in the background", builtin_fg_bg},
153         {"cd", "Change working directory", builtin_cd},
154         {"exec", "Exec command, replacing this shell with the exec'd process", builtin_exec},
155         {"exit", "Exit from shell()", builtin_exit},
156         {"fg", "Bring job into the foreground", builtin_fg_bg},
157         {"jobs", "Lists the active jobs", builtin_jobs},
158         {"export", "Set environment variable", builtin_export},
159         {"unset", "Unset environment variable", builtin_unset},
160         {"read", "Input environment variable", builtin_read},
161         {".", "Source-in and run commands in a file", builtin_source},
162         /* to do: add ulimit */
163         {NULL, NULL, NULL}
164 };
165
166 /* Table of forking built-in functions (things that fork cannot change global
167  * variables in the parent process, such as the current working directory) */
168 static struct built_in_command bltins_forking[] = {
169         {"pwd", "Print current directory", builtin_pwd},
170         {"help", "List shell built-in commands", builtin_help},
171         {NULL, NULL, NULL}
172 };
173
174
175 static int shell_context;  /* Type prompt trigger (PS1 or PS2) */
176
177
178 /* Globals that are static to this file */
179 static const char *cwd;
180 static char *local_pending_command = NULL;
181 static struct jobset job_list = { NULL, NULL };
182 static int argc;
183 static char **argv;
184 static struct close_me *close_me_head;
185 static int last_return_code;
186 static int last_bg_pid;
187 static unsigned int last_jobid;
188 static int shell_terminal;
189 static pid_t shell_pgrp;
190 static char *PS1;
191 static char *PS2 = "> ";
192
193
194 #ifdef DEBUG_SHELL
195 static inline void debug_printf(const char *format, ...)
196 {
197         va_list args;
198         va_start(args, format);
199         vfprintf(stderr, format, args);
200         va_end(args);
201 }
202 #else
203 static inline void debug_printf(const char *format, ...) { }
204 #endif
205
206 /*
207         Most builtins need access to the struct child_prog that has
208         their arguments, previously coded as cmd->progs[0].  That coding
209         can exhibit a bug, if the builtin is not the first command in
210         a pipeline: "echo foo | exec sort" will attempt to exec foo.
211
212 builtin   previous use      notes
213 ------ -----------------  ---------
214 cd      cmd->progs[0]
215 exec    cmd->progs[0]  squashed bug: didn't look for applets or forking builtins
216 exit    cmd->progs[0]
217 fg_bg   cmd->progs[0], job_list->head, job_list->fg
218 help    0
219 jobs    job_list->head
220 pwd     0
221 export  cmd->progs[0]
222 source  cmd->progs[0]
223 unset   cmd->progs[0]
224 read    cmd->progs[0]
225
226 I added "struct job *family;" to struct child_prog,
227 and switched API to builtin_foo(struct child_prog *child);
228 So   cmd->text        becomes  child->family->text
229      cmd->job_context  becomes  child->family->job_context
230      cmd->progs[0]    becomes  *child
231      job_list          becomes  child->family->job_list
232  */
233
234 /* built-in 'cd <path>' handler */
235 static int builtin_cd(struct child_prog *child)
236 {
237         char *newdir;
238
239         if (child->argv[1] == NULL)
240                 newdir = getenv("HOME");
241         else
242                 newdir = child->argv[1];
243         if (chdir(newdir)) {
244                 printf("cd: %s: %m\n", newdir);
245                 return EXIT_FAILURE;
246         }
247         cwd = xgetcwd((char *)cwd);
248         if (!cwd)
249                 cwd = unknown;
250         return EXIT_SUCCESS;
251 }
252
253 /* built-in 'exec' handler */
254 static int builtin_exec(struct child_prog *child)
255 {
256         if (child->argv[1] == NULL)
257                 return EXIT_SUCCESS;   /* Really? */
258         child->argv++;
259         close_all();
260         pseudo_exec(child);
261         /* never returns */
262 }
263
264 /* built-in 'exit' handler */
265 static int builtin_exit(struct child_prog *child)
266 {
267         if (child->argv[1] == NULL)
268                 exit(EXIT_SUCCESS);
269
270         exit (atoi(child->argv[1]));
271 }
272
273 /* built-in 'fg' and 'bg' handler */
274 static int builtin_fg_bg(struct child_prog *child)
275 {
276         int i, jobnum;
277         struct job *job=NULL;
278
279         /* If they gave us no args, assume they want the last backgrounded task */
280         if (!child->argv[1]) {
281                 for (job = child->family->job_list->head; job; job = job->next) {
282                         if (job->jobid == last_jobid) {
283                                 break;
284                         }
285                 }
286                 if (!job) {
287                         error_msg("%s: no current job", child->argv[0]);
288                         return EXIT_FAILURE;
289                 }
290         } else {
291                 if (sscanf(child->argv[1], "%%%d", &jobnum) != 1) {
292                         error_msg("%s: bad argument '%s'", child->argv[0], child->argv[1]);
293                         return EXIT_FAILURE;
294                 }
295                 for (job = child->family->job_list->head; job; job = job->next) {
296                         if (job->jobid == jobnum) {
297                                 break;
298                         }
299                 }
300                 if (!job) {
301                         error_msg("%s: %d: no such job", child->argv[0], jobnum);
302                         return EXIT_FAILURE;
303                 }
304         }
305
306         if (*child->argv[0] == 'f') {
307                 /* Put the job into the foreground.  */
308                 tcsetpgrp(shell_terminal, job->pgrp);
309
310                 child->family->job_list->fg = job;
311         }
312
313         /* Restart the processes in the job */
314         for (i = 0; i < job->num_progs; i++)
315                 job->progs[i].is_stopped = 0;
316
317         job->stopped_progs = 0;
318
319         if ( (i=kill(- job->pgrp, SIGCONT)) < 0) {
320                 if (i == ESRCH) {
321                         remove_job(&job_list, job);
322                 } else {
323                         perror_msg("kill (SIGCONT)");
324                 }
325         }
326
327         return EXIT_SUCCESS;
328 }
329
330 /* built-in 'help' handler */
331 static int builtin_help(struct child_prog *dummy)
332 {
333         struct built_in_command *x;
334
335         printf("\nBuilt-in commands:\n");
336         printf("-------------------\n");
337         for (x = bltins; x->cmd; x++) {
338                 if (x->descr==NULL)
339                         continue;
340                 printf("%s\t%s\n", x->cmd, x->descr);
341         }
342         for (x = bltins_forking; x->cmd; x++) {
343                 if (x->descr==NULL)
344                         continue;
345                 printf("%s\t%s\n", x->cmd, x->descr);
346         }
347         printf("\n\n");
348         return EXIT_SUCCESS;
349 }
350
351 /* built-in 'jobs' handler */
352 static int builtin_jobs(struct child_prog *child)
353 {
354         struct job *job;
355         char *status_string;
356
357         for (job = child->family->job_list->head; job; job = job->next) {
358                 if (job->running_progs == job->stopped_progs)
359                         status_string = "Stopped";
360                 else
361                         status_string = "Running";
362
363                 printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->text);
364         }
365         return EXIT_SUCCESS;
366 }
367
368
369 /* built-in 'pwd' handler */
370 static int builtin_pwd(struct child_prog *dummy)
371 {
372         cwd = xgetcwd((char *)cwd);
373         if (!cwd)
374                 cwd = unknown;
375         puts(cwd);
376         return EXIT_SUCCESS;
377 }
378
379 /* built-in 'export VAR=value' handler */
380 static int builtin_export(struct child_prog *child)
381 {
382         int res;
383         char *v = child->argv[1];
384
385         if (v == NULL) {
386                 char **e;
387                 for (e = environ; *e; e++) {
388                         puts(*e);
389                 }
390                 return 0;
391         }
392         res = putenv(v);
393         if (res)
394                 fprintf(stderr, "export: %m\n");
395 #ifdef CONFIG_FEATURE_SH_FANCY_PROMPT
396         if (strncmp(v, "PS1=", 4)==0)
397                 PS1 = getenv("PS1");
398 #endif
399
400 #ifdef CONFIG_LOCALE_SUPPORT
401         if(strncmp(v, "LC_ALL=", 7)==0)
402                 setlocale(LC_ALL, getenv("LC_ALL"));
403         if(strncmp(v, "LC_CTYPE=", 9)==0)
404                 setlocale(LC_CTYPE, getenv("LC_CTYPE"));
405 #endif
406
407         return (res);
408 }
409
410 /* built-in 'read VAR' handler */
411 static int builtin_read(struct child_prog *child)
412 {
413         int res = 0, len, newlen;
414         char *s;
415         char string[MAX_READ];
416
417         if (child->argv[1]) {
418                 /* argument (VAR) given: put "VAR=" into buffer */
419                 safe_strncpy(string, child->argv[1], MAX_READ-1);
420                 len = strlen(string);
421                 string[len++] = '=';
422                 string[len]   = '\0';
423                 fgets(&string[len], sizeof(string) - len, stdin);       /* read string */
424                 newlen = strlen(string);
425                 if(newlen > len)
426                         string[--newlen] = '\0';        /* chomp trailing newline */
427                 /*
428                 ** string should now contain "VAR=<value>"
429                 ** copy it (putenv() won't do that, so we must make sure
430                 ** the string resides in a static buffer!)
431                 */
432                 res = -1;
433                 if((s = strdup(string)))
434                         res = putenv(s);
435                 if (res)
436                         fprintf(stderr, "read: %m\n");
437         }
438         else
439                 fgets(string, sizeof(string), stdin);
440
441         return (res);
442 }
443
444 /* Built-in '.' handler (read-in and execute commands from file) */
445 static int builtin_source(struct child_prog *child)
446 {
447         FILE *input;
448         int status;
449         int fd;
450
451         if (child->argv[1] == NULL)
452                 return EXIT_FAILURE;
453
454         input = fopen(child->argv[1], "r");
455         if (!input) {
456                 printf( "Couldn't open file '%s'\n", child->argv[1]);
457                 return EXIT_FAILURE;
458         }
459
460         fd=fileno(input);
461         mark_open(fd);
462         /* Now run the file */
463         status = busy_loop(input);
464         fclose(input);
465         mark_closed(fd);
466         return (status);
467 }
468
469 /* built-in 'unset VAR' handler */
470 static int builtin_unset(struct child_prog *child)
471 {
472         if (child->argv[1] == NULL) {
473                 printf( "unset: parameter required.\n");
474                 return EXIT_FAILURE;
475         }
476         unsetenv(child->argv[1]);
477         return EXIT_SUCCESS;
478 }
479
480 static void mark_open(int fd)
481 {
482         struct close_me *new = xmalloc(sizeof(struct close_me));
483         new->fd = fd;
484         new->next = close_me_head;
485         close_me_head = new;
486 }
487
488 static void mark_closed(int fd)
489 {
490         struct close_me *tmp;
491         if (close_me_head == NULL || close_me_head->fd != fd)
492                 error_msg_and_die("corrupt close_me");
493         tmp = close_me_head;
494         close_me_head = close_me_head->next;
495         free(tmp);
496 }
497
498 static void close_all()
499 {
500         struct close_me *c, *tmp;
501         for (c=close_me_head; c; c=tmp) {
502                 close(c->fd);
503                 tmp=c->next;
504                 free(c);
505         }
506         close_me_head = NULL;
507 }
508
509
510 /* free up all memory from a job */
511 static void free_job(struct job *cmd)
512 {
513         int i;
514         struct jobset *keep;
515
516         for (i = 0; i < cmd->num_progs; i++) {
517                 free(cmd->progs[i].argv);
518                 if (cmd->progs[i].redirects)
519                         free(cmd->progs[i].redirects);
520         }
521         if (cmd->progs)
522                 free(cmd->progs);
523         if (cmd->text)
524                 free(cmd->text);
525         if (cmd->cmdbuf)
526                 free(cmd->cmdbuf);
527         keep = cmd->job_list;
528         memset(cmd, 0, sizeof(struct job));
529         cmd->job_list = keep;
530 }
531
532 /* remove a job from a jobset */
533 static void remove_job(struct jobset *j_list, struct job *job)
534 {
535         struct job *prevjob;
536
537         free_job(job);
538         if (job == j_list->head) {
539                 j_list->head = job->next;
540         } else {
541                 prevjob = j_list->head;
542                 while (prevjob->next != job)
543                         prevjob = prevjob->next;
544                 prevjob->next = job->next;
545         }
546
547         if (j_list->head)
548                 last_jobid = j_list->head->jobid;
549         else
550                 last_jobid = 0;
551
552         free(job);
553 }
554
555 /* Checks to see if any background processes have exited -- if they 
556    have, figure out why and see if a job has completed */
557 static void checkjobs(struct jobset *j_list)
558 {
559         struct job *job;
560         pid_t childpid;
561         int status;
562         int prognum = 0;
563
564         while ((childpid = waitpid(-1, &status, WNOHANG | WUNTRACED)) > 0) {
565                 for (job = j_list->head; job; job = job->next) {
566                         prognum = 0;
567                         while (prognum < job->num_progs &&
568                                    job->progs[prognum].pid != childpid) prognum++;
569                         if (prognum < job->num_progs)
570                                 break;
571                 }
572
573                 /* This happens on backticked commands */
574                 if(job==NULL)
575                         return;
576
577                 if (WIFEXITED(status) || WIFSIGNALED(status)) {
578                         /* child exited */
579                         job->running_progs--;
580                         job->progs[prognum].pid = 0;
581
582                         if (!job->running_progs) {
583                                 printf(JOB_STATUS_FORMAT, job->jobid, "Done", job->text);
584                                 last_jobid=0;
585                                 remove_job(j_list, job);
586                         }
587                 } else {
588                         /* child stopped */
589                         job->stopped_progs++;
590                         job->progs[prognum].is_stopped = 1;
591
592 #if 0
593                         /* Printing this stuff is a pain, since it tends to
594                          * overwrite the prompt an inconveinient moments.  So
595                          * don't do that.  */
596                         if (job->stopped_progs == job->num_progs) {
597                                 printf(JOB_STATUS_FORMAT, job->jobid, "Stopped",
598                                            job->text);
599                         }
600 #endif  
601                 }
602         }
603
604         if (childpid == -1 && errno != ECHILD)
605                 perror_msg("waitpid");
606 }
607
608 /* squirrel != NULL means we squirrel away copies of stdin, stdout,
609  * and stderr if they are redirected. */
610 static int setup_redirects(struct child_prog *prog, int squirrel[])
611 {
612         int i;
613         int openfd;
614         int mode = O_RDONLY;
615         struct redir_struct *redir = prog->redirects;
616
617         for (i = 0; i < prog->num_redirects; i++, redir++) {
618                 switch (redir->type) {
619                 case REDIRECT_INPUT:
620                         mode = O_RDONLY;
621                         break;
622                 case REDIRECT_OVERWRITE:
623                         mode = O_WRONLY | O_CREAT | O_TRUNC;
624                         break;
625                 case REDIRECT_APPEND:
626                         mode = O_WRONLY | O_CREAT | O_APPEND;
627                         break;
628                 }
629
630                 openfd = open(redir->filename, mode, 0666);
631                 if (openfd < 0) {
632                         /* this could get lost if stderr has been redirected, but
633                            bash and ash both lose it as well (though zsh doesn't!) */
634                         perror_msg("error opening %s", redir->filename);
635                         return 1;
636                 }
637
638                 if (openfd != redir->fd) {
639                         if (squirrel && redir->fd < 3) {
640                                 squirrel[redir->fd] = dup(redir->fd);
641                         }
642                         dup2(openfd, redir->fd);
643                         close(openfd);
644                 }
645         }
646
647         return 0;
648 }
649
650 static void restore_redirects(int squirrel[])
651 {
652         int i, fd;
653         for (i=0; i<3; i++) {
654                 fd = squirrel[i];
655                 if (fd != -1) {
656                         /* No error checking.  I sure wouldn't know what
657                          * to do with an error if I found one! */
658                         dup2(fd, i);
659                         close(fd);
660                 }
661         }
662 }
663
664 static inline void cmdedit_set_initial_prompt(void)
665 {
666 #ifndef CONFIG_FEATURE_SH_FANCY_PROMPT
667         PS1 = NULL;
668 #else
669         PS1 = getenv("PS1");
670         if(PS1==0)
671                 PS1 = "\\w \\$ ";
672 #endif  
673 }
674
675 static inline void setup_prompt_string(char **prompt_str)
676 {
677 #ifndef CONFIG_FEATURE_SH_FANCY_PROMPT
678         /* Set up the prompt */
679         if (shell_context == 0) {
680                 if (PS1)
681                         free(PS1);
682                 PS1=xmalloc(strlen(cwd)+4);
683                 sprintf(PS1, "%s %s", cwd, ( geteuid() != 0 ) ?  "$ ":"# ");
684                 *prompt_str = PS1;
685         } else {
686                 *prompt_str = PS2;
687         }
688 #else
689         *prompt_str = (shell_context==0)? PS1 : PS2;
690 #endif  
691 }
692
693 static int get_command(FILE * source, char *command)
694 {
695         char *prompt_str;
696
697         if (source == NULL) {
698                 if (local_pending_command) {
699                         /* a command specified (-c option): return it & mark it done */
700                         strcpy(command, local_pending_command);
701                         free(local_pending_command);
702                         local_pending_command = NULL;
703                         return 0;
704                 }
705                 return 1;
706         }
707
708         if (source == stdin) {
709                 setup_prompt_string(&prompt_str);
710
711 #ifdef CONFIG_FEATURE_COMMAND_EDITING
712                 /*
713                 ** enable command line editing only while a command line
714                 ** is actually being read; otherwise, we'll end up bequeathing
715                 ** atexit() handlers and other unwanted stuff to our
716                 ** child processes (rob@sysgo.de)
717                 */
718                 cmdedit_read_input(prompt_str, command);
719                 return 0;
720 #else
721                 fputs(prompt_str, stdout);
722 #endif
723         }
724
725         if (!fgets(command, BUFSIZ - 2, source)) {
726                 if (source == stdin)
727                         printf("\n");
728                 return 1;
729         }
730
731         return 0;
732 }
733
734 static char* itoa(register int i)
735 {
736         static char a[7]; /* Max 7 ints */
737         register char *b = a + sizeof(a) - 1;
738         int   sign = (i < 0);
739
740         if (sign)
741                 i = -i;
742         *b = 0;
743         do
744         {
745                 *--b = '0' + (i % 10);
746                 i /= 10;
747         }
748         while (i);
749         if (sign)
750                 *--b = '-';
751         return b;
752 }
753
754 char * strsep_space( char *string, int * ix)
755 {
756         char *token, *begin;
757
758         begin = string;
759
760         /* Short circuit the trivial case */
761         if ( !string || ! string[*ix])
762                 return NULL;
763
764         /* Find the end of the token. */
765         while( string && string[*ix] && !isspace(string[*ix]) ) {
766                 (*ix)++;
767         }
768
769         /* Find the end of any whitespace trailing behind 
770          * the token and let that be part of the token */
771         while( string && string[*ix] && isspace(string[*ix]) ) {
772                 (*ix)++;
773         }
774
775         if (! string && *ix==0) {
776                 /* Nothing useful was found */
777                 return NULL;
778         }
779
780         token = xmalloc(*ix+1);
781         token[*ix] = '\0';
782         strncpy(token, string,  *ix); 
783
784         return token;
785 }
786
787 static int expand_arguments(char *command)
788 {
789         int total_length=0, length, i, retval, ix = 0;
790         expand_t expand_result;
791         char *tmpcmd, *cmd, *cmd_copy;
792         char *src, *dst, *var;
793         const char *out_of_space = "out of space during expansion";
794         int flags = GLOB_NOCHECK
795 #ifdef GLOB_BRACE
796                 | GLOB_BRACE
797 #endif  
798 #ifdef GLOB_TILDE
799                 | GLOB_TILDE
800 #endif  
801                 ;
802
803         /* get rid of the terminating \n */
804         chomp(command);
805
806         /* Fix up escape sequences to be the Real Thing(tm) */
807         while( command && command[ix]) {
808                 if (command[ix] == '\\') {
809                         const char *tmp = command+ix+1;
810                         command[ix] = process_escape_sequence(  &tmp );
811                         memmove(command+ix + 1, tmp, strlen(tmp)+1);
812                 }
813                 ix++;
814         }
815         /* Use glob and then fixup environment variables and such */
816
817         /* It turns out that glob is very stupid.  We have to feed it one word at a
818          * time since it can't cope with a full string.  Here we convert command
819          * (char*) into cmd (char**, one word per string) */
820
821         /* We need a clean copy, so strsep can mess up the copy while
822          * we write stuff into the original (in a minute) */
823         cmd = cmd_copy = xstrdup(command);
824         *command = '\0';
825         for (ix = 0, tmpcmd = cmd; 
826                         (tmpcmd = strsep_space(cmd, &ix)) != NULL; cmd += ix, ix=0) {
827                 if (*tmpcmd == '\0')
828                         break;
829                 /* we need to trim() the result for glob! */
830                 trim(tmpcmd);
831                 retval = glob(tmpcmd, flags, NULL, &expand_result);
832                 free(tmpcmd); /* Free mem allocated by strsep_space */
833                 if (retval == GLOB_NOSPACE) {
834                         /* Mem may have been allocated... */
835                         globfree (&expand_result);
836                         error_msg(out_of_space);
837                         return FALSE;
838                 } else if (retval != 0) {
839                         /* Some other error.  GLOB_NOMATCH shouldn't
840                          * happen because of the GLOB_NOCHECK flag in 
841                          * the glob call. */
842                         error_msg("syntax error");
843                         return FALSE;
844                 } else {
845                         /* Convert from char** (one word per string) to a simple char*,
846                          * but don't overflow command which is BUFSIZ in length */
847                         for (i=0; i < expand_result.gl_pathc; i++) {
848                                 length=strlen(expand_result.gl_pathv[i]);
849                                 if (total_length+length+1 >= BUFSIZ) {
850                                         error_msg(out_of_space);
851                                         return FALSE;
852                                 }
853                                 strcat(command+total_length, " ");
854                                 total_length+=1;
855                                 strcat(command+total_length, expand_result.gl_pathv[i]);
856                                 total_length+=length;
857                         }
858                         globfree (&expand_result);
859                 }
860         }
861         free(cmd_copy);
862         trim(command);
863
864         /* Now do the shell variable substitutions which 
865          * wordexp can't do for us, namely $? and $! */
866         src = command;
867         while((dst = strchr(src,'$')) != NULL){
868                 var = NULL;
869                 switch(*(dst+1)) {
870                         case '?':
871                                 var = itoa(last_return_code);
872                                 break;
873                         case '!':
874                                 if (last_bg_pid==-1)
875                                         *(var)='\0';
876                                 else
877                                         var = itoa(last_bg_pid);
878                                 break;
879                                 /* Everything else like $$, $#, $[0-9], etc. should all be
880                                  * expanded by wordexp(), so we can in theory skip that stuff
881                                  * here, but just to be on the safe side (i.e., since uClibc
882                                  * wordexp doesn't do this stuff yet), lets leave it in for
883                                  * now. */
884                         case '$':
885                                 var = itoa(getpid());
886                                 break;
887                         case '#':
888                                 var = itoa(argc-1);
889                                 break;
890                         case '0':case '1':case '2':case '3':case '4':
891                         case '5':case '6':case '7':case '8':case '9':
892                                 {
893                                         int ixx=*(dst + 1)-48;
894                                         if (ixx >= argc) {
895                                                 var='\0';
896                                         } else {
897                                                 var = argv[ixx];
898                                         }
899                                 }
900                                 break;
901
902                 }
903                 if (var) {
904                         /* a single character construction was found, and 
905                          * already handled in the case statement */
906                         src=dst+2;
907                 } else {
908                         /* Looks like an environment variable */
909                         char delim_hold;
910                         int num_skip_chars=0;
911                         int dstlen = strlen(dst);
912                         /* Is this a ${foo} type variable? */
913                         if (dstlen >=2 && *(dst+1) == '{') {
914                                 src=strchr(dst+1, '}');
915                                 num_skip_chars=1;
916                         } else {
917                                 src=dst+1;
918                                 while(isalnum(*src) || *src=='_') src++;
919                         }
920                         if (src == NULL) {
921                                 src = dst+dstlen;
922                         }
923                         delim_hold=*src;
924                         *src='\0';  /* temporary */
925                         var = getenv(dst + 1 + num_skip_chars);
926                         *src=delim_hold;
927                         src += num_skip_chars;
928                 }
929                 if (var == NULL) {
930                         /* Seems we got an un-expandable variable.  So delete it. */
931                         var = "";
932                 }
933                 {
934                         int subst_len = strlen(var);
935                         int trail_len = strlen(src);
936                         if (dst+subst_len+trail_len >= command+BUFSIZ) {
937                                 error_msg(out_of_space);
938                                 return FALSE;
939                         }
940                         /* Move stuff to the end of the string to accommodate
941                          * filling the created gap with the new stuff */
942                         memmove(dst+subst_len, src, trail_len+1);
943                         /* Now copy in the new stuff */
944                         memcpy(dst, var, subst_len);
945                         src = dst+subst_len;
946                 }
947         }
948
949         return TRUE;
950 }
951
952 /* Return cmd->num_progs as 0 if no command is present (e.g. an empty
953    line). If a valid command is found, command_ptr is set to point to
954    the beginning of the next command (if the original command had more 
955    then one job associated with it) or NULL if no more commands are 
956    present. */
957 static int parse_command(char **command_ptr, struct job *job, int *inbg)
958 {
959         char *command;
960         char *return_command = NULL;
961         char *src, *buf, *chptr;
962         int argc_l = 0;
963         int done = 0;
964         int argv_alloced;
965         int i, saw_quote = 0;
966         char quote = '\0';
967         int count;
968         struct child_prog *prog;
969
970         /* skip leading white space */
971         while (**command_ptr && isspace(**command_ptr))
972                 (*command_ptr)++;
973
974         /* this handles empty lines or leading '#' characters */
975         if (!**command_ptr || (**command_ptr == '#')) {
976                 job->num_progs=0;
977                 return 0;
978         }
979
980         *inbg = 0;
981         job->num_progs = 1;
982         job->progs = xmalloc(sizeof(*job->progs));
983
984         /* We set the argv elements to point inside of this string. The 
985            memory is freed by free_job(). Allocate twice the original
986            length in case we need to quote every single character.
987
988            Getting clean memory relieves us of the task of NULL 
989            terminating things and makes the rest of this look a bit 
990            cleaner (though it is, admittedly, a tad less efficient) */
991         job->cmdbuf = command = xcalloc(2*strlen(*command_ptr) + 1, sizeof(char));
992         job->text = NULL;
993
994         prog = job->progs;
995         prog->num_redirects = 0;
996         prog->redirects = NULL;
997         prog->is_stopped = 0;
998         prog->family = job;
999
1000         argv_alloced = 5;
1001         prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1002         prog->argv[0] = job->cmdbuf;
1003
1004         buf = command;
1005         src = *command_ptr;
1006         while (*src && !done) {
1007                 if (quote == *src) {
1008                         quote = '\0';
1009                 } else if (quote) {
1010                         if (*src == '\\') {
1011                                 src++;
1012                                 if (!*src) {
1013                                         error_msg("character expected after \\");
1014                                         free_job(job);
1015                                         return 1;
1016                                 }
1017
1018                                 /* in shell, "\'" should yield \' */
1019                                 if (*src != quote) {
1020                                         *buf++ = '\\';
1021                                         *buf++ = '\\';
1022                                 }
1023                         } else if (*src == '*' || *src == '?' || *src == '[' ||
1024                                            *src == ']') *buf++ = '\\';
1025                         *buf++ = *src;
1026                 } else if (isspace(*src)) {
1027                         if (*prog->argv[argc_l] || saw_quote) {
1028                                 buf++, argc_l++;
1029                                 /* +1 here leaves room for the NULL which ends argv */
1030                                 if ((argc_l + 1) == argv_alloced) {
1031                                         argv_alloced += 5;
1032                                         prog->argv = xrealloc(prog->argv,
1033                                                                                   sizeof(*prog->argv) *
1034                                                                                   argv_alloced);
1035                                 }
1036                                 prog->argv[argc_l] = buf;
1037                                 saw_quote = 0;
1038                         }
1039                 } else
1040                         switch (*src) {
1041                         case '"':
1042                         case '\'':
1043                                 quote = *src;
1044                                 saw_quote = 1;
1045                                 break;
1046
1047                         case '#':                       /* comment */
1048                                 if (*(src-1)== '$')
1049                                         *buf++ = *src;
1050                                 else
1051                                         done = 1;
1052                                 break;
1053
1054                         case '>':                       /* redirects */
1055                         case '<':
1056                                 i = prog->num_redirects++;
1057                                 prog->redirects = xrealloc(prog->redirects,
1058                                                                                           sizeof(*prog->redirects) *
1059                                                                                           (i + 1));
1060
1061                                 prog->redirects[i].fd = -1;
1062                                 if (buf != prog->argv[argc_l]) {
1063                                         /* the stuff before this character may be the file number 
1064                                            being redirected */
1065                                         prog->redirects[i].fd =
1066                                                 strtol(prog->argv[argc_l], &chptr, 10);
1067
1068                                         if (*chptr && *prog->argv[argc_l]) {
1069                                                 buf++, argc_l++;
1070                                                 prog->argv[argc_l] = buf;
1071                                         }
1072                                 }
1073
1074                                 if (prog->redirects[i].fd == -1) {
1075                                         if (*src == '>')
1076                                                 prog->redirects[i].fd = 1;
1077                                         else
1078                                                 prog->redirects[i].fd = 0;
1079                                 }
1080
1081                                 if (*src++ == '>') {
1082                                         if (*src == '>')
1083                                                 prog->redirects[i].type =
1084                                                         REDIRECT_APPEND, src++;
1085                                         else
1086                                                 prog->redirects[i].type = REDIRECT_OVERWRITE;
1087                                 } else {
1088                                         prog->redirects[i].type = REDIRECT_INPUT;
1089                                 }
1090
1091                                 /* This isn't POSIX sh compliant. Oh well. */
1092                                 chptr = src;
1093                                 while (isspace(*chptr))
1094                                         chptr++;
1095
1096                                 if (!*chptr) {
1097                                         error_msg("file name expected after %c", *(src-1));
1098                                         free_job(job);
1099                                         job->num_progs=0;
1100                                         return 1;
1101                                 }
1102
1103                                 prog->redirects[i].filename = buf;
1104                                 while (*chptr && !isspace(*chptr))
1105                                         *buf++ = *chptr++;
1106
1107                                 src = chptr - 1;        /* we src++ later */
1108                                 prog->argv[argc_l] = ++buf;
1109                                 break;
1110
1111                         case '|':                       /* pipe */
1112                                 /* finish this command */
1113                                 if (*prog->argv[argc_l] || saw_quote)
1114                                         argc_l++;
1115                                 if (!argc_l) {
1116                                         error_msg("empty command in pipe");
1117                                         free_job(job);
1118                                         job->num_progs=0;
1119                                         return 1;
1120                                 }
1121                                 prog->argv[argc_l] = NULL;
1122
1123                                 /* and start the next */
1124                                 job->num_progs++;
1125                                 job->progs = xrealloc(job->progs,
1126                                                                           sizeof(*job->progs) * job->num_progs);
1127                                 prog = job->progs + (job->num_progs - 1);
1128                                 prog->num_redirects = 0;
1129                                 prog->redirects = NULL;
1130                                 prog->is_stopped = 0;
1131                                 prog->family = job;
1132                                 argc_l = 0;
1133
1134                                 argv_alloced = 5;
1135                                 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1136                                 prog->argv[0] = ++buf;
1137
1138                                 src++;
1139                                 while (*src && isspace(*src))
1140                                         src++;
1141
1142                                 if (!*src) {
1143                                         error_msg("empty command in pipe");
1144                                         free_job(job);
1145                                         job->num_progs=0;
1146                                         return 1;
1147                                 }
1148                                 src--;                  /* we'll ++ it at the end of the loop */
1149
1150                                 break;
1151
1152                         case '&':                       /* background */
1153                                 *inbg = 1;
1154                         case ';':                       /* multiple commands */
1155                                 done = 1;
1156                                 return_command = *command_ptr + (src - *command_ptr) + 1;
1157                                 break;
1158
1159                         case '\\':
1160                                 src++;
1161                                 if (!*src) {
1162                                         error_msg("character expected after \\");
1163                                         free_job(job);
1164                                         return 1;
1165                                 }
1166                                 if (*src == '*' || *src == '[' || *src == ']'
1167                                         || *src == '?') *buf++ = '\\';
1168                                 /* fallthrough */
1169                         default:
1170                                 *buf++ = *src;
1171                         }
1172
1173                 src++;
1174         }
1175
1176         if (*prog->argv[argc_l] || saw_quote) {
1177                 argc_l++;
1178         }
1179         if (!argc_l) {
1180                 free_job(job);
1181                 return 0;
1182         }
1183         prog->argv[argc_l] = NULL;
1184
1185         if (!return_command) {
1186                 job->text = xmalloc(strlen(*command_ptr) + 1);
1187                 strcpy(job->text, *command_ptr);
1188         } else {
1189                 /* This leaves any trailing spaces, which is a bit sloppy */
1190                 count = return_command - *command_ptr;
1191                 job->text = xmalloc(count + 1);
1192                 strncpy(job->text, *command_ptr, count);
1193                 job->text[count] = '\0';
1194         }
1195
1196         *command_ptr = return_command;
1197         
1198         return 0;
1199 }
1200
1201 /* Run the child_prog, no matter what kind of command it uses.
1202  */
1203 static int pseudo_exec(struct child_prog *child)
1204 {
1205         struct built_in_command *x;
1206 #ifdef CONFIG_FEATURE_SH_STANDALONE_SHELL
1207         char *name;
1208 #endif
1209
1210         /* Check if the command matches any of the non-forking builtins.
1211          * Depending on context, this might be redundant.  But it's
1212          * easier to waste a few CPU cycles than it is to figure out
1213          * if this is one of those cases.
1214          */
1215         for (x = bltins; x->cmd; x++) {
1216                 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1217                         _exit(x->function(child));
1218                 }
1219         }
1220
1221         /* Check if the command matches any of the forking builtins. */
1222         for (x = bltins_forking; x->cmd; x++) {
1223                 if (strcmp(child->argv[0], x->cmd) == 0) {
1224                         applet_name=x->cmd;
1225                         _exit (x->function(child));
1226                 }
1227         }
1228 #ifdef CONFIG_FEATURE_SH_STANDALONE_SHELL
1229         /* Check if the command matches any busybox internal
1230          * commands ("applets") here.  Following discussions from
1231          * November 2000 on busybox@busybox.net, don't use
1232          * get_last_path_component().  This way explicit (with
1233          * slashes) filenames will never be interpreted as an
1234          * applet, just like with builtins.  This way the user can
1235          * override an applet with an explicit filename reference.
1236          * The only downside to this change is that an explicit
1237          * /bin/foo invocation will fork and exec /bin/foo, even if
1238          * /bin/foo is a symlink to busybox.
1239          */
1240         name = child->argv[0];
1241
1242 #ifdef CONFIG_FEATURE_SH_APPLETS_ALWAYS_WIN
1243         /* If you enable CONFIG_FEATURE_SH_APPLETS_ALWAYS_WIN, then
1244          * if you run /bin/cat, it will use BusyBox cat even if 
1245          * /bin/cat exists on the filesystem and is _not_ busybox.
1246          * Some systems want this, others do not.  Choose wisely.  :-)
1247          */
1248         name = get_last_path_component(name);
1249 #endif
1250
1251         {
1252             char** argv_l=child->argv;
1253             int argc_l;
1254             for(argc_l=0;*argv_l!=NULL; argv_l++, argc_l++);
1255             optind = 1;
1256             run_applet_by_name(name, argc_l, child->argv);
1257         }
1258 #endif
1259
1260         execvp(child->argv[0], child->argv);
1261
1262         /* Do not use perror_msg_and_die() here, since we must not 
1263          * call exit() but should call _exit() instead */
1264         fprintf(stderr, "%s: %s\n", child->argv[0], strerror(err));
1265         _exit(EXIT_FAILURE);
1266 }
1267
1268 static void insert_job(struct job *newjob, int inbg)
1269 {
1270         struct job *thejob;
1271         struct jobset *j_list=newjob->job_list;
1272
1273         /* find the ID for thejob to use */
1274         newjob->jobid = 1;
1275         for (thejob = j_list->head; thejob; thejob = thejob->next)
1276                 if (thejob->jobid >= newjob->jobid)
1277                         newjob->jobid = thejob->jobid + 1;
1278
1279         /* add thejob to the list of running jobs */
1280         if (!j_list->head) {
1281                 thejob = j_list->head = xmalloc(sizeof(*thejob));
1282         } else {
1283                 for (thejob = j_list->head; thejob->next; thejob = thejob->next) /* nothing */;
1284                 thejob->next = xmalloc(sizeof(*thejob));
1285                 thejob = thejob->next;
1286         }
1287
1288         *thejob = *newjob;   /* physically copy the struct job */
1289         thejob->next = NULL;
1290         thejob->running_progs = thejob->num_progs;
1291         thejob->stopped_progs = 0;
1292
1293         if (inbg) {
1294                 /* we don't wait for background thejobs to return -- append it 
1295                    to the list of backgrounded thejobs and leave it alone */
1296                 printf("[%d] %d\n", thejob->jobid,
1297                            newjob->progs[newjob->num_progs - 1].pid);
1298                 last_jobid = newjob->jobid;
1299                 last_bg_pid=newjob->progs[newjob->num_progs - 1].pid;
1300         } else {
1301                 newjob->job_list->fg = thejob;
1302
1303                 /* move the new process group into the foreground */
1304                 /* suppress messages when run from /linuxrc mag@sysgo.de */
1305                 if (tcsetpgrp(shell_terminal, newjob->pgrp) && errno != ENOTTY)
1306                         perror_msg("tcsetpgrp");
1307         }
1308 }
1309
1310 static int run_command(struct job *newjob, int inbg, int outpipe[2])
1311 {
1312         /* struct job *thejob; */
1313         int i;
1314         int nextin, nextout;
1315         int pipefds[2];                         /* pipefd[0] is for reading */
1316         struct built_in_command *x;
1317         struct child_prog *child;
1318
1319         nextin = 0, nextout = 1;
1320         for (i = 0; i < newjob->num_progs; i++) {
1321                 child = & (newjob->progs[i]);
1322
1323                 if ((i + 1) < newjob->num_progs) {
1324                         if (pipe(pipefds)<0) perror_msg_and_die("pipe");
1325                         nextout = pipefds[1];
1326                 } else {
1327                         if (outpipe[1]!=-1) {
1328                                 nextout = outpipe[1];
1329                         } else {
1330                                 nextout = 1;
1331                         }
1332                 }
1333
1334
1335                 /* Check if the command matches any non-forking builtins,
1336                  * but only if this is a simple command.
1337                  * Non-forking builtins within pipes have to fork anyway,
1338                  * and are handled in pseudo_exec.  "echo foo | read bar"
1339                  * is doomed to failure, and doesn't work on bash, either.
1340                  */
1341                 if (newjob->num_progs == 1) {
1342                         for (x = bltins; x->cmd; x++) {
1343                                 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1344                                         int squirrel[] = {-1, -1, -1};
1345                                         int rcode;
1346                                         setup_redirects(child, squirrel);
1347                                         rcode = x->function(child);
1348                                         restore_redirects(squirrel);
1349                                         return rcode;
1350                                 }
1351                         }
1352                 }
1353
1354 #if !defined(__UCLIBC__) || defined(__UCLIBC_HAS_MMU__)
1355                 if (!(child->pid = fork())) 
1356 #else
1357                 if (!(child->pid = vfork())) 
1358 #endif
1359                 {
1360                         /* Set the handling for job control signals back to the default.  */
1361                         signal(SIGINT, SIG_DFL);
1362                         signal(SIGQUIT, SIG_DFL);
1363                         signal(SIGTSTP, SIG_DFL);
1364                         signal(SIGTTIN, SIG_DFL);
1365                         signal(SIGTTOU, SIG_DFL);
1366                         signal(SIGCHLD, SIG_DFL);
1367
1368                         close_all();
1369
1370                         if (outpipe[1]!=-1) {
1371                                 close(outpipe[0]);
1372                         }
1373                         if (nextin != 0) {
1374                                 dup2(nextin, 0);
1375                                 close(nextin);
1376                         }
1377
1378                         if (nextout != 1) {
1379                                 dup2(nextout, 1);
1380                                 dup2(nextout, 2);  /* Really? */
1381                                 close(nextout);
1382                                 close(pipefds[0]);
1383                         }
1384
1385                         /* explicit redirects override pipes */
1386                         setup_redirects(child,NULL);
1387
1388                         pseudo_exec(child);
1389                 }
1390                 if (outpipe[1]!=-1) {
1391                         close(outpipe[1]);
1392                 }
1393
1394                 /* put our child in the process group whose leader is the
1395                    first process in this pipe */
1396                 setpgid(child->pid, newjob->progs[0].pid);
1397                 if (nextin != 0)
1398                         close(nextin);
1399                 if (nextout != 1)
1400                         close(nextout);
1401
1402                 /* If there isn't another process, nextin is garbage 
1403                    but it doesn't matter */
1404                 nextin = pipefds[0];
1405         }
1406
1407         newjob->pgrp = newjob->progs[0].pid;
1408
1409         insert_job(newjob, inbg);
1410
1411         return 0;
1412 }
1413
1414 static int busy_loop(FILE * input)
1415 {
1416         char *command;
1417         char *next_command = NULL;
1418         struct job newjob;
1419         pid_t  parent_pgrp;
1420         int i;
1421         int inbg;
1422         int status;
1423         newjob.job_list = &job_list;
1424         newjob.job_context = DEFAULT_CONTEXT;
1425
1426         /* save current owner of TTY so we can restore it on exit */
1427         parent_pgrp = tcgetpgrp(shell_terminal);
1428
1429         command = (char *) xcalloc(BUFSIZ, sizeof(char));
1430
1431         while (1) {
1432                 if (!job_list.fg) {
1433                         /* no job is in the foreground */
1434
1435                         /* see if any background processes have exited */
1436                         checkjobs(&job_list);
1437
1438                         if (!next_command) {
1439                                 if (get_command(input, command))
1440                                         break;
1441                                 next_command = command;
1442                         }
1443
1444                         if (! expand_arguments(next_command)) {
1445                                 free(command);
1446                                 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1447                                 next_command = NULL;
1448                                 continue;
1449                         }
1450
1451                         if (!parse_command(&next_command, &newjob, &inbg) &&
1452                                 newjob.num_progs) {
1453                                 int pipefds[2] = {-1,-1};
1454                                 debug_printf( "job=%p fed to run_command by busy_loop()'\n", 
1455                                                 &newjob);
1456                                 run_command(&newjob, inbg, pipefds);
1457                         }
1458                         else {
1459                                 free(command);
1460                                 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1461                                 next_command = NULL;
1462                         }
1463                 } else {
1464                         /* a job is running in the foreground; wait for it */
1465                         i = 0;
1466                         while (!job_list.fg->progs[i].pid ||
1467                                    job_list.fg->progs[i].is_stopped == 1) i++;
1468
1469                         if (waitpid(job_list.fg->progs[i].pid, &status, WUNTRACED)<0) {
1470                                 if (errno != ECHILD) {
1471                                         perror_msg_and_die("waitpid(%d)",job_list.fg->progs[i].pid);
1472                                 }
1473                         }
1474
1475                         if (WIFEXITED(status) || WIFSIGNALED(status)) {
1476                                 /* the child exited */
1477                                 job_list.fg->running_progs--;
1478                                 job_list.fg->progs[i].pid = 0;
1479
1480                                 last_return_code=WEXITSTATUS(status);
1481
1482                                 if (!job_list.fg->running_progs) {
1483                                         /* child exited */
1484                                         remove_job(&job_list, job_list.fg);
1485                                         job_list.fg = NULL;
1486                                 }
1487                         } else {
1488                                 /* the child was stopped */
1489                                 job_list.fg->stopped_progs++;
1490                                 job_list.fg->progs[i].is_stopped = 1;
1491
1492                                 if (job_list.fg->stopped_progs == job_list.fg->running_progs) {
1493                                         printf("\n" JOB_STATUS_FORMAT, job_list.fg->jobid,
1494                                                    "Stopped", job_list.fg->text);
1495                                         job_list.fg = NULL;
1496                                 }
1497                         }
1498
1499                         if (!job_list.fg) {
1500                                 /* move the shell to the foreground */
1501                                 /* suppress messages when run from /linuxrc mag@sysgo.de */
1502                                 if (tcsetpgrp(shell_terminal, getpgrp()) && errno != ENOTTY)
1503                                         perror_msg("tcsetpgrp"); 
1504                         }
1505                 }
1506         }
1507         free(command);
1508
1509         /* return controlling TTY back to parent process group before exiting */
1510         if (tcsetpgrp(shell_terminal, parent_pgrp) && errno != ENOTTY)
1511                 perror_msg("tcsetpgrp");
1512
1513         /* return exit status if called with "-c" */
1514         if (input == NULL && WIFEXITED(status))
1515                 return WEXITSTATUS(status);
1516         
1517         return 0;
1518 }
1519
1520
1521 #ifdef CONFIG_FEATURE_CLEAN_UP
1522 void free_memory(void)
1523 {
1524         if (cwd && cwd!=unknown) {
1525                 free((char*)cwd);
1526         }
1527         if (local_pending_command)
1528                 free(local_pending_command);
1529
1530         if (job_list.fg && !job_list.fg->running_progs) {
1531                 remove_job(&job_list, job_list.fg);
1532         }
1533 }
1534 #endif
1535
1536 /* Make sure we have a controlling tty.  If we get started under a job
1537  * aware app (like bash for example), make sure we are now in charge so
1538  * we don't fight over who gets the foreground */
1539 static void setup_job_control()
1540 {
1541         int status;
1542         
1543         /* Loop until we are in the foreground.  */
1544         while ((status = tcgetpgrp (shell_terminal)) >= 0) {
1545                 if (status == (shell_pgrp = getpgrp ())) {
1546                         break;
1547                 }
1548                 kill (- shell_pgrp, SIGTTIN);
1549         }
1550
1551         /* Ignore interactive and job-control signals.  */
1552         signal(SIGINT, SIG_IGN);
1553         signal(SIGQUIT, SIG_IGN);
1554         signal(SIGTSTP, SIG_IGN);
1555         signal(SIGTTIN, SIG_IGN);
1556         signal(SIGTTOU, SIG_IGN);
1557         signal(SIGCHLD, SIG_IGN);
1558
1559         /* Put ourselves in our own process group.  */
1560         setsid();
1561         shell_pgrp = getpid ();
1562         setpgid (shell_pgrp, shell_pgrp);
1563
1564         /* Grab control of the terminal.  */
1565         tcsetpgrp(shell_terminal, shell_pgrp);
1566 }
1567
1568 int lash_main(int argc_l, char **argv_l)
1569 {
1570         int opt, interactive=FALSE;
1571         FILE *input = stdin;
1572         argc = argc_l;
1573         argv = argv_l;
1574
1575         /* These variables need re-initializing when recursing */
1576         last_jobid = 0;
1577         local_pending_command = NULL;
1578         close_me_head = NULL;
1579         job_list.head = NULL;
1580         job_list.fg = NULL;
1581         last_return_code=1;
1582
1583         if (argv[0] && argv[0][0] == '-') {
1584                 FILE *prof_input;
1585                 prof_input = fopen("/etc/profile", "r");
1586                 if (prof_input) {
1587                         int tmp_fd = fileno(prof_input);
1588                         mark_open(tmp_fd);      
1589                         /* Now run the file */
1590                         busy_loop(prof_input);
1591                         fclose(prof_input);
1592                         mark_closed(tmp_fd);
1593                 }
1594         }
1595
1596         while ((opt = getopt(argc_l, argv_l, "cxi")) > 0) {
1597                 switch (opt) {
1598                         case 'c':
1599                                 input = NULL;
1600                                 if (local_pending_command != 0)
1601                                         error_msg_and_die("multiple -c arguments");
1602                                 local_pending_command = xstrdup(argv[optind]);
1603                                 optind++;
1604                                 argv = argv+optind;
1605                                 break;
1606                         case 'i':
1607                                 interactive = TRUE;
1608                                 break;
1609                         default:
1610                                 show_usage();
1611                 }
1612         }
1613         /* A shell is interactive if the `-i' flag was given, or if all of
1614          * the following conditions are met:
1615          *        no -c command
1616          *    no arguments remaining or the -s flag given
1617          *    standard input is a terminal
1618          *    standard output is a terminal
1619          *    Refer to Posix.2, the description of the `sh' utility. */
1620         if (argv[optind]==NULL && input==stdin &&
1621                         isatty(fileno(stdin)) && isatty(fileno(stdout))) {
1622                 interactive=TRUE;
1623         }
1624         setup_job_control();
1625         if (interactive==TRUE) {
1626                 //printf( "optind=%d  argv[optind]='%s'\n", optind, argv[optind]);
1627                 /* Looks like they want an interactive shell */
1628 #ifndef CONFIG_FEATURE_SH_EXTRA_QUIET 
1629                 printf( "\n\n" BB_BANNER " Built-in shell (lash)\n");
1630                 printf( "Enter 'help' for a list of built-in commands.\n\n");
1631 #endif
1632         } else if (local_pending_command==NULL) {
1633                 //printf( "optind=%d  argv[optind]='%s'\n", optind, argv[optind]);
1634                 input = xfopen(argv[optind], "r");
1635                 mark_open(fileno(input));  /* be lazy, never mark this closed */
1636         }
1637
1638         /* initialize the cwd -- this is never freed...*/
1639         cwd = xgetcwd(0);
1640         if (!cwd)
1641                 cwd = unknown;
1642
1643 #ifdef CONFIG_FEATURE_CLEAN_UP
1644         atexit(free_memory);
1645 #endif
1646
1647 #ifdef CONFIG_FEATURE_COMMAND_EDITING
1648         cmdedit_set_initial_prompt();
1649 #else
1650         PS1 = NULL;
1651 #endif
1652         
1653         return (busy_loop(input));
1654 }