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