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