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