usage.c: remove reference to busybox.h
[platform/upstream/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 #include <getopt.h>
24 #include <glob.h>
25
26 #include "busybox.h" /* for struct bb_applet */
27
28 #define expand_t        glob_t
29
30 /* Always enable for the moment... */
31 #define CONFIG_LASH_PIPE_N_REDIRECTS
32 #define CONFIG_LASH_JOB_CONTROL
33 #define ENABLE_LASH_PIPE_N_REDIRECTS 1
34 #define ENABLE_LASH_JOB_CONTROL      1
35
36
37 enum { MAX_READ = 128 }; /* size of input buffer for 'read' builtin */
38 #define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
39
40
41 #if ENABLE_LASH_PIPE_N_REDIRECTS
42 enum redir_type { REDIRECT_INPUT, REDIRECT_OVERWRITE,
43         REDIRECT_APPEND
44 };
45 #endif
46
47 enum {
48         DEFAULT_CONTEXT = 0x1,
49         IF_TRUE_CONTEXT = 0x2,
50         IF_FALSE_CONTEXT = 0x4,
51         THEN_EXP_CONTEXT = 0x8,
52         ELSE_EXP_CONTEXT = 0x10
53 };
54
55 #define LASH_OPT_DONE (1)
56 #define LASH_OPT_SAW_QUOTE (2)
57
58 #if ENABLE_LASH_PIPE_N_REDIRECTS
59 struct redir_struct {
60         enum redir_type type;   /* type of redirection */
61         int fd;                                         /* file descriptor being redirected */
62         char *filename;                         /* file to redirect fd to */
63 };
64 #endif
65
66 struct child_prog {
67         pid_t pid;                                      /* 0 if exited */
68         char **argv;                            /* program name and arguments */
69         int num_redirects;                      /* elements in redirection array */
70         int is_stopped;                         /* is the program currently running? */
71         struct job *family;                     /* pointer back to the child's parent job */
72 #if ENABLE_LASH_PIPE_N_REDIRECTS
73         struct redir_struct *redirects; /* I/O redirects */
74 #endif
75 };
76
77 struct jobset {
78         struct job *head;                       /* head of list of running jobs */
79         struct job *fg;                         /* current foreground job */
80 };
81
82 struct job {
83         int jobid;                                      /* job number */
84         int num_progs;                          /* total number of programs in job */
85         int running_progs;                      /* number of programs running */
86         char *text;                                     /* name of job */
87         char *cmdbuf;                           /* buffer various argv's point into */
88         pid_t pgrp;                                     /* process group ID for the job */
89         struct child_prog *progs;       /* array of programs in job */
90         struct job *next;                       /* to track background commands */
91         int stopped_progs;                      /* number of programs alive, but stopped */
92         unsigned int job_context;       /* bitmask defining current context */
93         struct jobset *job_list;
94 };
95
96 struct built_in_command {
97         const char *cmd;   /* name */
98         const char *descr; /* description */
99         int (*function) (struct child_prog *);  /* function ptr */
100 };
101
102 /* function prototypes for builtins */
103 static int builtin_cd(struct child_prog *cmd);
104 static int builtin_exec(struct child_prog *cmd);
105 static int builtin_exit(struct child_prog *cmd);
106 static int builtin_fg_bg(struct child_prog *cmd);
107 static int builtin_help(struct child_prog *cmd);
108 static int builtin_jobs(struct child_prog *dummy);
109 static int builtin_pwd(struct child_prog *dummy);
110 static int builtin_export(struct child_prog *cmd);
111 static int builtin_source(struct child_prog *cmd);
112 static int builtin_unset(struct child_prog *cmd);
113 static int builtin_read(struct child_prog *cmd);
114
115
116 /* function prototypes for shell stuff */
117 static void checkjobs(struct jobset *job_list);
118 static void remove_job(struct jobset *j_list, struct job *job);
119 static int get_command_bufsiz(FILE * source, char *command);
120 static int parse_command(char **command_ptr, struct job *job, int *inbg);
121 static int run_command(struct job *newjob, int inbg, int outpipe[2]);
122 static int pseudo_exec(struct child_prog *cmd) ATTRIBUTE_NORETURN;
123 static int busy_loop(FILE * input);
124
125
126 /* Table of built-in functions (these are non-forking builtins, meaning they
127  * can change global variables in the parent shell process but they will not
128  * work with pipes and redirects; 'unset foo | whatever' will not work) */
129 static const struct built_in_command bltins[] = {
130         {"bg"    , "Resume a job in the background", builtin_fg_bg},
131         {"cd"    , "Change working directory", builtin_cd},
132         {"exec"  , "Exec command, replacing this shell with the exec'd process", builtin_exec},
133         {"exit"  , "Exit from shell()", builtin_exit},
134         {"fg"    , "Bring job into the foreground", builtin_fg_bg},
135         {"jobs"  , "Lists the active jobs", builtin_jobs},
136         {"export", "Set environment variable", builtin_export},
137         {"unset" , "Unset environment variable", builtin_unset},
138         {"read"  , "Input environment variable", builtin_read},
139         {"."     , "Source-in and run commands in a file", builtin_source},
140         /* These were "forked applets", but distinction was nuked */
141         /* Original comment retained: */
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         {"pwd"   , "Print current directory", builtin_pwd},
145         {"help"  , "List shell built-in commands", builtin_help},
146         /* to do: add ulimit */
147 };
148
149 #define VEC_SIZE(v) (sizeof(v)/sizeof(v[0]))
150 #define VEC_LAST(v) v[VEC_SIZE(v)-1]
151
152
153 static int shell_context;  /* Type prompt trigger (PS1 or PS2) */
154
155
156 /* Globals that are static to this file */
157 static char *cwd;
158 static char *local_pending_command;
159 static struct jobset job_list = { NULL, NULL };
160 static int argc;
161 static char **argv;
162 static llist_t *close_me_list;
163 static int last_return_code;
164 static int last_bg_pid;
165 static unsigned int last_jobid;
166 static int shell_terminal;
167 static const char *PS1;
168 static const char *PS2 = "> ";
169
170
171 #ifdef DEBUG_SHELL
172 static inline void debug_printf(const char *format, ...)
173 {
174         va_list args;
175         va_start(args, format);
176         vfprintf(stderr, format, args);
177         va_end(args);
178 }
179 #else
180 static inline void debug_printf(const char ATTRIBUTE_UNUSED *format, ...) { }
181 #endif
182
183 /*
184         Most builtins need access to the struct child_prog that has
185         their arguments, previously coded as cmd->progs[0].  That coding
186         can exhibit a bug, if the builtin is not the first command in
187         a pipeline: "echo foo | exec sort" will attempt to exec foo.
188
189 builtin   previous use      notes
190 ------ -----------------  ---------
191 cd      cmd->progs[0]
192 exec    cmd->progs[0]  squashed bug: didn't look for applets or forking builtins
193 exit    cmd->progs[0]
194 fg_bg   cmd->progs[0], job_list->head, job_list->fg
195 help    0
196 jobs    job_list->head
197 pwd     0
198 export  cmd->progs[0]
199 source  cmd->progs[0]
200 unset   cmd->progs[0]
201 read    cmd->progs[0]
202
203 I added "struct job *family;" to struct child_prog,
204 and switched API to builtin_foo(struct child_prog *child);
205 So   cmd->text        becomes  child->family->text
206      cmd->job_context  becomes  child->family->job_context
207      cmd->progs[0]    becomes  *child
208      job_list          becomes  child->family->job_list
209  */
210
211
212 static void update_cwd(void)
213 {
214         cwd = xrealloc_getcwd_or_warn(cwd);
215         if (!cwd)
216                 cwd = xstrdup(bb_msg_unknown);
217 }
218
219 /* built-in 'cd <path>' handler */
220 static int builtin_cd(struct child_prog *child)
221 {
222         char *newdir;
223
224         if (child->argv[1] == NULL)
225                 newdir = getenv("HOME");
226         else
227                 newdir = child->argv[1];
228         if (chdir(newdir)) {
229                 bb_perror_msg("cd: %s", newdir);
230                 return EXIT_FAILURE;
231         }
232         update_cwd();
233         return EXIT_SUCCESS;
234 }
235
236 /* built-in 'exec' handler */
237 static int builtin_exec(struct child_prog *child)
238 {
239         if (child->argv[1] == NULL)
240                 return EXIT_SUCCESS;   /* Really? */
241         child->argv++;
242         while (close_me_list)
243                 close((long)llist_pop(&close_me_list));
244         pseudo_exec(child);
245         /* never returns */
246 }
247
248 /* built-in 'exit' handler */
249 static int builtin_exit(struct child_prog *child)
250 {
251         if (child->argv[1] == NULL)
252                 exit(EXIT_SUCCESS);
253
254         exit(atoi(child->argv[1]));
255 }
256
257 /* built-in 'fg' and 'bg' handler */
258 static int builtin_fg_bg(struct child_prog *child)
259 {
260         int i, jobnum;
261         struct job *job;
262
263         /* If they gave us no args, assume they want the last backgrounded task */
264         if (!child->argv[1]) {
265                 for (job = child->family->job_list->head; job; job = job->next) {
266                         if (job->jobid == last_jobid) {
267                                 goto found;
268                         }
269                 }
270                 bb_error_msg("%s: no current job", child->argv[0]);
271                 return EXIT_FAILURE;
272         }
273         if (sscanf(child->argv[1], "%%%d", &jobnum) != 1) {
274                 bb_error_msg(bb_msg_invalid_arg, child->argv[1], child->argv[0]);
275                 return EXIT_FAILURE;
276         }
277         for (job = child->family->job_list->head; job; job = job->next) {
278                 if (job->jobid == jobnum) {
279                         goto found;
280                 }
281         }
282         bb_error_msg("%s: %d: no such job", child->argv[0], jobnum);
283         return EXIT_FAILURE;
284  found:
285         if (*child->argv[0] == 'f') {
286                 /* Put the job into the foreground.  */
287                 tcsetpgrp(shell_terminal, job->pgrp);
288
289                 child->family->job_list->fg = job;
290         }
291
292         /* Restart the processes in the job */
293         for (i = 0; i < job->num_progs; i++)
294                 job->progs[i].is_stopped = 0;
295
296         job->stopped_progs = 0;
297
298         i = kill(- job->pgrp, SIGCONT);
299         if (i < 0) {
300                 if (errno == ESRCH) {
301                         remove_job(&job_list, job);
302                 } else {
303                         bb_perror_msg("kill (SIGCONT)");
304                 }
305         }
306
307         return EXIT_SUCCESS;
308 }
309
310 /* built-in 'help' handler */
311 static int builtin_help(struct child_prog ATTRIBUTE_UNUSED *dummy)
312 {
313         const struct built_in_command *x;
314
315         printf("\nBuilt-in commands:\n"
316                "-------------------\n");
317         for (x = bltins; x <= &VEC_LAST(bltins); 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         const 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         update_cwd();
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 #if ENABLE_FEATURE_EDITING_FANCY_PROMPT
369         if (strncmp(v, "PS1=", 4) == 0)
370                 PS1 = getenv("PS1");
371 #endif
372
373 #if ENABLE_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                 s = strdup(string);
408                 if (s)
409                         res = putenv(s);
410                 if (res)
411                         bb_perror_msg("read");
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 #if ENABLE_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 #if ENABLE_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 #if ENABLE_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 = open3_or_warn(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                         return 1;
575                 }
576
577                 if (openfd != redir->fd) {
578                         if (squirrel && redir->fd < 3) {
579                                 squirrel[redir->fd] = dup(redir->fd);
580                                 fcntl(squirrel[redir->fd], F_SETFD, FD_CLOEXEC);
581                         }
582                         dup2(openfd, redir->fd);
583                         close(openfd);
584                 }
585         }
586
587         return 0;
588 }
589
590 static void restore_redirects(int squirrel[])
591 {
592         int i, fd;
593         for (i = 0; i < 3; i++) {
594                 fd = squirrel[i];
595                 if (fd != -1) {
596                         /* No error checking.  I sure wouldn't know what
597                          * to do with an error if I found one! */
598                         dup2(fd, i);
599                         close(fd);
600                 }
601         }
602 }
603 #else
604 static inline int setup_redirects(struct child_prog *prog, int squirrel[])
605 {
606         return 0;
607 }
608 static inline void restore_redirects(int squirrel[])
609 {
610 }
611 #endif
612
613 static inline void cmdedit_set_initial_prompt(void)
614 {
615 #if !ENABLE_FEATURE_EDITING_FANCY_PROMPT
616         PS1 = NULL;
617 #else
618         PS1 = getenv("PS1");
619         if (PS1 == 0)
620                 PS1 = "\\w \\$ ";
621 #endif
622 }
623
624 static inline const char* setup_prompt_string(void)
625 {
626 #if !ENABLE_FEATURE_EDITING_FANCY_PROMPT
627         /* Set up the prompt */
628         if (shell_context == 0) {
629                 char *ns;
630                 free((char*)PS1);
631                 ns = xmalloc(strlen(cwd)+4);
632                 sprintf(ns, "%s %c ", cwd, (geteuid() != 0) ? '$': '#');
633                 PS1 = ns;
634                 return ns;
635         } else {
636                 return PS2;
637         }
638 #else
639         return (shell_context == 0)? PS1 : PS2;
640 #endif
641 }
642
643 #if ENABLE_FEATURE_EDITING
644 static line_input_t *line_input_state;
645 #endif
646
647 static int get_command_bufsiz(FILE * source, char *command)
648 {
649         const char *prompt_str;
650
651         if (source == NULL) {
652                 if (local_pending_command) {
653                         /* a command specified (-c option): return it & mark it done */
654                         strncpy(command, local_pending_command, BUFSIZ);
655                         local_pending_command = NULL;
656                         return 0;
657                 }
658                 return 1;
659         }
660
661         if (source == stdin) {
662                 prompt_str = setup_prompt_string();
663
664 #if ENABLE_FEATURE_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         static const char out_of_space[] = "out of space during expansion";
715
716         int total_length = 0, length, i, retval, ix = 0;
717         expand_t expand_result;
718         char *tmpcmd, *cmd, *cmd_copy;
719         char *src, *dst, *var;
720         int flags = GLOB_NOCHECK
721 #ifdef GLOB_BRACE
722                 | GLOB_BRACE
723 #endif
724 #ifdef GLOB_TILDE
725                 | GLOB_TILDE
726 #endif
727                 ;
728
729         /* get rid of the terminating \n */
730         chomp(command);
731
732         /* Fix up escape sequences to be the Real Thing(tm) */
733         while (command && command[ix]) {
734                 if (command[ix] == '\\') {
735                         const char *tmp = command+ix+1;
736                         command[ix] = bb_process_escape_sequence(  &tmp );
737                         memmove(command+ix + 1, tmp, strlen(tmp)+1);
738                 }
739                 ix++;
740         }
741         /* Use glob and then fixup environment variables and such */
742
743         /* It turns out that glob is very stupid.  We have to feed it one word at a
744          * time since it can't cope with a full string.  Here we convert command
745          * (char*) into cmd (char**, one word per string) */
746
747         /* We need a clean copy, so strsep can mess up the copy while
748          * we write stuff into the original (in a minute) */
749         cmd = cmd_copy = xstrdup(command);
750         *command = '\0';
751         for (ix = 0, tmpcmd = cmd;
752                         (tmpcmd = strsep_space(cmd, &ix)) != NULL; cmd += ix, ix = 0) {
753                 if (*tmpcmd == '\0')
754                         break;
755                 /* we need to trim() the result for glob! */
756                 trim(tmpcmd);
757                 retval = glob(tmpcmd, flags, NULL, &expand_result);
758                 free(tmpcmd); /* Free mem allocated by strsep_space */
759                 if (retval == GLOB_NOSPACE) {
760                         /* Mem may have been allocated... */
761                         globfree(&expand_result);
762                         bb_error_msg(out_of_space);
763                         return FALSE;
764                 } else if (retval != 0) {
765                         /* Some other error.  GLOB_NOMATCH shouldn't
766                          * happen because of the GLOB_NOCHECK flag in
767                          * the glob call. */
768                         bb_error_msg("syntax error");
769                         return FALSE;
770                 } else {
771                         /* Convert from char** (one word per string) to a simple char*,
772                          * but don't overflow command which is BUFSIZ in length */
773                         for (i = 0; i < expand_result.gl_pathc; i++) {
774                                 length = strlen(expand_result.gl_pathv[i]);
775                                 if (total_length+length+1 >= BUFSIZ) {
776                                         bb_error_msg(out_of_space);
777                                         return FALSE;
778                                 }
779                                 strcat(command+total_length, " ");
780                                 total_length += 1;
781                                 strcat(command+total_length, expand_result.gl_pathv[i]);
782                                 total_length += length;
783                         }
784                         globfree(&expand_result);
785                 }
786         }
787         free(cmd_copy);
788         trim(command);
789
790         /* Now do the shell variable substitutions which
791          * wordexp can't do for us, namely $? and $! */
792         src = command;
793         while ((dst = strchr(src,'$')) != NULL) {
794                 var = NULL;
795                 switch (*(dst+1)) {
796                         case '?':
797                                 var = itoa(last_return_code);
798                                 break;
799                         case '!':
800                                 if (last_bg_pid == -1)
801                                         *var = '\0';
802                                 else
803                                         var = itoa(last_bg_pid);
804                                 break;
805                                 /* Everything else like $$, $#, $[0-9], etc. should all be
806                                  * expanded by wordexp(), so we can in theory skip that stuff
807                                  * here, but just to be on the safe side (i.e., since uClibc
808                                  * wordexp doesn't do this stuff yet), lets leave it in for
809                                  * now. */
810                         case '$':
811                                 var = itoa(getpid());
812                                 break;
813                         case '#':
814                                 var = itoa(argc-1);
815                                 break;
816                         case '0':case '1':case '2':case '3':case '4':
817                         case '5':case '6':case '7':case '8':case '9':
818                                 {
819                                         int ixx = *(dst+1)-48+1;
820                                         if (ixx >= argc) {
821                                                 var = '\0';
822                                         } else {
823                                                 var = argv[ixx];
824                                         }
825                                 }
826                                 break;
827
828                 }
829                 if (var) {
830                         /* a single character construction was found, and
831                          * already handled in the case statement */
832                         src = dst + 2;
833                 } else {
834                         /* Looks like an environment variable */
835                         char delim_hold;
836                         int num_skip_chars = 0;
837                         int dstlen = strlen(dst);
838                         /* Is this a ${foo} type variable? */
839                         if (dstlen >= 2 && *(dst+1) == '{') {
840                                 src = strchr(dst+1, '}');
841                                 num_skip_chars = 1;
842                         } else {
843                                 src = dst + 1;
844                                 while ((isalnum)(*src) || *src == '_') src++;
845                         }
846                         if (src == NULL) {
847                                 src = dst+dstlen;
848                         }
849                         delim_hold = *src;
850                         *src = '\0';  /* temporary */
851                         var = getenv(dst + 1 + num_skip_chars);
852                         *src = delim_hold;
853                         src += num_skip_chars;
854                 }
855                 if (var == NULL) {
856                         /* Seems we got an un-expandable variable.  So delete it. */
857                         var = (char*)"";
858                 }
859                 {
860                         int subst_len = strlen(var);
861                         int trail_len = strlen(src);
862                         if (dst+subst_len+trail_len >= command+BUFSIZ) {
863                                 bb_error_msg(out_of_space);
864                                 return FALSE;
865                         }
866                         /* Move stuff to the end of the string to accommodate
867                          * filling the created gap with the new stuff */
868                         memmove(dst+subst_len, src, trail_len+1);
869                         /* Now copy in the new stuff */
870                         memcpy(dst, var, subst_len);
871                         src = dst+subst_len;
872                 }
873         }
874
875         return TRUE;
876 }
877
878 /* Return cmd->num_progs as 0 if no command is present (e.g. an empty
879    line). If a valid command is found, command_ptr is set to point to
880    the beginning of the next command (if the original command had more
881    then one job associated with it) or NULL if no more commands are
882    present. */
883 static int parse_command(char **command_ptr, struct job *job, int *inbg)
884 {
885         char *command;
886         char *return_command = NULL;
887         char *src, *buf;
888         int argc_l;
889         int flag;
890         int argv_alloced;
891         char quote = '\0';
892         struct child_prog *prog;
893 #if ENABLE_LASH_PIPE_N_REDIRECTS
894         int i;
895         char *chptr;
896 #endif
897
898         /* skip leading white space */
899         *command_ptr = skip_whitespace(*command_ptr);
900
901         /* this handles empty lines or leading '#' characters */
902         if (!**command_ptr || (**command_ptr == '#')) {
903                 job->num_progs = 0;
904                 return 0;
905         }
906
907         *inbg = 0;
908         job->num_progs = 1;
909         job->progs = xmalloc(sizeof(*job->progs));
910
911         /* We set the argv elements to point inside of this string. The
912            memory is freed by free_job(). Allocate twice the original
913            length in case we need to quote every single character.
914
915            Getting clean memory relieves us of the task of NULL
916            terminating things and makes the rest of this look a bit
917            cleaner (though it is, admittedly, a tad less efficient) */
918         job->cmdbuf = command = xzalloc(2*strlen(*command_ptr) + 1);
919         job->text = NULL;
920
921         prog = job->progs;
922         prog->num_redirects = 0;
923         prog->is_stopped = 0;
924         prog->family = job;
925 #if ENABLE_LASH_PIPE_N_REDIRECTS
926         prog->redirects = NULL;
927 #endif
928
929         argv_alloced = 5;
930         prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
931         prog->argv[0] = job->cmdbuf;
932
933         flag = argc_l = 0;
934         buf = command;
935         src = *command_ptr;
936         while (*src && !(flag & LASH_OPT_DONE)) {
937                 if (quote == *src) {
938                         quote = '\0';
939                 } else if (quote) {
940                         if (*src == '\\') {
941                                 src++;
942                                 if (!*src) {
943                                         bb_error_msg("character expected after \\");
944                                         free_job(job);
945                                         return 1;
946                                 }
947
948                                 /* in shell, "\'" should yield \' */
949                                 if (*src != quote) {
950                                         *buf++ = '\\';
951                                         *buf++ = '\\';
952                                 }
953                         } else if (*src == '*' || *src == '?' || *src == '[' ||
954                                            *src == ']') *buf++ = '\\';
955                         *buf++ = *src;
956                 } else if (isspace(*src)) {
957                         if (*prog->argv[argc_l] || (flag & LASH_OPT_SAW_QUOTE)) {
958                                 buf++, argc_l++;
959                                 /* +1 here leaves room for the NULL which ends argv */
960                                 if ((argc_l + 1) == argv_alloced) {
961                                         argv_alloced += 5;
962                                         prog->argv = xrealloc(prog->argv,
963                                                         sizeof(*prog->argv) * 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 #if ENABLE_LASH_PIPE_N_REDIRECTS
984                         case '>':                       /* redirects */
985                         case '<':
986                                 i = prog->num_redirects++;
987                                 prog->redirects = xrealloc(prog->redirects,
988                                                 sizeof(*prog->redirects) * (i + 1));
989
990                                 prog->redirects[i].fd = -1;
991                                 if (buf != prog->argv[argc_l]) {
992                                         /* the stuff before this character may be the file number
993                                            being redirected */
994                                         prog->redirects[i].fd =
995                                                 strtol(prog->argv[argc_l], &chptr, 10);
996
997                                         if (*chptr && *prog->argv[argc_l]) {
998                                                 buf++, argc_l++;
999                                                 prog->argv[argc_l] = buf;
1000                                         }
1001                                 }
1002
1003                                 if (prog->redirects[i].fd == -1) {
1004                                         if (*src == '>')
1005                                                 prog->redirects[i].fd = 1;
1006                                         else
1007                                                 prog->redirects[i].fd = 0;
1008                                 }
1009
1010                                 if (*src++ == '>') {
1011                                         if (*src == '>')
1012                                                 prog->redirects[i].type =
1013                                                         REDIRECT_APPEND, src++;
1014                                         else
1015                                                 prog->redirects[i].type = REDIRECT_OVERWRITE;
1016                                 } else {
1017                                         prog->redirects[i].type = REDIRECT_INPUT;
1018                                 }
1019
1020                                 /* This isn't POSIX sh compliant. Oh well. */
1021                                 chptr = src;
1022                                 chptr = skip_whitespace(chptr);
1023
1024                                 if (!*chptr) {
1025                                         bb_error_msg("file name expected after %c", *(src-1));
1026                                         free_job(job);
1027                                         job->num_progs = 0;
1028                                         return 1;
1029                                 }
1030
1031                                 prog->redirects[i].filename = buf;
1032                                 while (*chptr && !isspace(*chptr))
1033                                         *buf++ = *chptr++;
1034
1035                                 src = chptr - 1;        /* we src++ later */
1036                                 prog->argv[argc_l] = ++buf;
1037                                 break;
1038
1039                         case '|':                       /* pipe */
1040                                 /* finish this command */
1041                                 if (*prog->argv[argc_l] || flag & LASH_OPT_SAW_QUOTE)
1042                                         argc_l++;
1043                                 if (!argc_l) {
1044                                         goto empty_command_in_pipe;
1045                                 }
1046                                 prog->argv[argc_l] = NULL;
1047
1048                                 /* and start the next */
1049                                 job->num_progs++;
1050                                 job->progs = xrealloc(job->progs,
1051                                                 sizeof(*job->progs) * job->num_progs);
1052                                 prog = job->progs + (job->num_progs - 1);
1053                                 prog->num_redirects = 0;
1054                                 prog->redirects = NULL;
1055                                 prog->is_stopped = 0;
1056                                 prog->family = job;
1057                                 argc_l = 0;
1058
1059                                 argv_alloced = 5;
1060                                 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1061                                 prog->argv[0] = ++buf;
1062
1063                                 src++;
1064                                 src = skip_whitespace(src);
1065
1066                                 if (!*src) {
1067 empty_command_in_pipe:
1068                                         bb_error_msg("empty command in pipe");
1069                                         free_job(job);
1070                                         job->num_progs = 0;
1071                                         return 1;
1072                                 }
1073                                 src--;                  /* we'll ++ it at the end of the loop */
1074
1075                                 break;
1076 #endif
1077
1078 #if ENABLE_LASH_JOB_CONTROL
1079                         case '&':                       /* background */
1080                                 *inbg = 1;
1081                                 /* fallthrough */
1082 #endif
1083                         case ';':                       /* multiple commands */
1084                                 flag |= LASH_OPT_DONE;
1085                                 return_command = *command_ptr + (src - *command_ptr) + 1;
1086                                 break;
1087
1088                         case '\\':
1089                                 src++;
1090                                 if (!*src) {
1091                                         bb_error_msg("character expected after \\");
1092                                         free_job(job);
1093                                         return 1;
1094                                 }
1095                                 if (*src == '*' || *src == '[' || *src == ']'
1096                                         || *src == '?') *buf++ = '\\';
1097                                 /* fallthrough */
1098                         default:
1099                                 *buf++ = *src;
1100                         }
1101
1102                 src++;
1103         }
1104
1105         if (*prog->argv[argc_l] || flag & LASH_OPT_SAW_QUOTE) {
1106                 argc_l++;
1107         }
1108         if (!argc_l) {
1109                 free_job(job);
1110                 return 0;
1111         }
1112         prog->argv[argc_l] = NULL;
1113
1114         if (!return_command) {
1115                 job->text = xstrdup(*command_ptr);
1116         } else {
1117                 /* This leaves any trailing spaces, which is a bit sloppy */
1118                 job->text = xstrndup(*command_ptr, return_command - *command_ptr);
1119         }
1120
1121         *command_ptr = return_command;
1122
1123         return 0;
1124 }
1125
1126 /* Run the child_prog, no matter what kind of command it uses.
1127  */
1128 static int pseudo_exec(struct child_prog *child)
1129 {
1130         const struct built_in_command *x;
1131
1132         /* Check if the command matches any of the non-forking builtins.
1133          * Depending on context, this might be redundant.  But it's
1134          * easier to waste a few CPU cycles than it is to figure out
1135          * if this is one of those cases.
1136          */
1137         /* Check if the command matches any of the forking builtins. */
1138         for (x = bltins; x <= &VEC_LAST(bltins); x++) {
1139                 if (strcmp(child->argv[0], x->cmd) == 0) {
1140                         _exit(x->function(child));
1141                 }
1142         }
1143
1144
1145         /* Check if the command matches any busybox internal
1146          * commands ("applets") here.  Following discussions from
1147          * November 2000 on busybox@busybox.net, don't use
1148          * bb_get_last_path_component().  This way explicit (with
1149          * slashes) filenames will never be interpreted as an
1150          * applet, just like with builtins.  This way the user can
1151          * override an applet with an explicit filename reference.
1152          * The only downside to this change is that an explicit
1153          * /bin/foo invocation will fork and exec /bin/foo, even if
1154          * /bin/foo is a symlink to busybox.
1155          */
1156         if (ENABLE_FEATURE_SH_STANDALONE) {
1157                 run_applet_and_exit(child->argv[0], child->argv);
1158         }
1159
1160         execvp(child->argv[0], child->argv);
1161
1162         /* Do not use bb_perror_msg_and_die() here, since we must not
1163          * call exit() but should call _exit() instead */
1164         bb_perror_msg("%s", child->argv[0]);
1165         _exit(EXIT_FAILURE);
1166 }
1167
1168 static void insert_job(struct job *newjob, int inbg)
1169 {
1170         struct job *thejob;
1171         struct jobset *j_list = newjob->job_list;
1172
1173         /* find the ID for thejob to use */
1174         newjob->jobid = 1;
1175         for (thejob = j_list->head; thejob; thejob = thejob->next)
1176                 if (thejob->jobid >= newjob->jobid)
1177                         newjob->jobid = thejob->jobid + 1;
1178
1179         /* add thejob to the list of running jobs */
1180         if (!j_list->head) {
1181                 thejob = j_list->head = xmalloc(sizeof(*thejob));
1182         } else {
1183                 for (thejob = j_list->head; thejob->next; thejob = thejob->next) /* nothing */;
1184                 thejob->next = xmalloc(sizeof(*thejob));
1185                 thejob = thejob->next;
1186         }
1187
1188         *thejob = *newjob;   /* physically copy the struct job */
1189         thejob->next = NULL;
1190         thejob->running_progs = thejob->num_progs;
1191         thejob->stopped_progs = 0;
1192
1193 #if ENABLE_LASH_JOB_CONTROL
1194         if (inbg) {
1195                 /* we don't wait for background thejobs to return -- append it
1196                    to the list of backgrounded thejobs and leave it alone */
1197                 printf("[%d] %d\n", thejob->jobid,
1198                            newjob->progs[newjob->num_progs - 1].pid);
1199                 last_jobid = newjob->jobid;
1200                 last_bg_pid = newjob->progs[newjob->num_progs - 1].pid;
1201         } else {
1202                 newjob->job_list->fg = thejob;
1203
1204                 /* move the new process group into the foreground */
1205                 /* Ignore errors since child could have already exited */
1206                 tcsetpgrp(shell_terminal, newjob->pgrp);
1207         }
1208 #endif
1209 }
1210
1211 static int run_command(struct job *newjob, int inbg, int outpipe[2])
1212 {
1213         /* struct job *thejob; */
1214         int i;
1215         int nextin, nextout;
1216         int pipefds[2];                         /* pipefd[0] is for reading */
1217         const struct built_in_command *x;
1218         struct child_prog *child;
1219
1220         nextin = 0;
1221         for (i = 0; i < newjob->num_progs; i++) {
1222                 child = &(newjob->progs[i]);
1223
1224                 nextout = 1;
1225                 if ((i + 1) < newjob->num_progs) {
1226                         xpipe(pipefds);
1227                         nextout = pipefds[1];
1228                 } else if (outpipe[1] != -1) {
1229                         nextout = outpipe[1];
1230                 }
1231
1232                 /* Check if the command matches any non-forking builtins,
1233                  * but only if this is a simple command.
1234                  * Non-forking builtins within pipes have to fork anyway,
1235                  * and are handled in pseudo_exec.  "echo foo | read bar"
1236                  * is doomed to failure, and doesn't work on bash, either.
1237                  */
1238                 if (newjob->num_progs == 1) {
1239                         int rcode;
1240                         int squirrel[] = {-1, -1, -1};
1241
1242                         /* Check if the command sets an environment variable. */
1243                         if (strchr(child->argv[0], '=') != NULL) {
1244                                 child->argv[1] = child->argv[0];
1245                                 return builtin_export(child);
1246                         }
1247
1248                         for (x = bltins; x <= &VEC_LAST(bltins); x++) {
1249                                 if (strcmp(child->argv[0], x->cmd) == 0) {
1250                                         setup_redirects(child, squirrel);
1251                                         rcode = x->function(child);
1252                                         restore_redirects(squirrel);
1253                                         return rcode;
1254                                 }
1255                         }
1256 #if ENABLE_FEATURE_SH_STANDALONE
1257                         {
1258                                 const struct bb_applet *a = find_applet_by_name(child->argv[i]);
1259                                 if (a && a->nofork) {
1260                                         setup_redirects(child, squirrel);
1261                                         rcode = run_nofork_applet(a, child->argv + i);
1262                                         restore_redirects(squirrel);
1263                                         return rcode;
1264                                 }
1265                         }
1266 #endif
1267                 }
1268
1269 #if BB_MMU
1270                 child->pid = fork();
1271 #else
1272                 child->pid = vfork();
1273 #endif
1274                 if (!child->pid) {
1275                         /* Set the handling for job control signals back to the default.  */
1276                         signal(SIGINT, SIG_DFL);
1277                         signal(SIGQUIT, SIG_DFL);
1278                         signal(SIGTSTP, SIG_DFL);
1279                         signal(SIGTTIN, SIG_DFL);
1280                         signal(SIGTTOU, SIG_DFL);
1281                         signal(SIGCHLD, SIG_DFL);
1282
1283                         /* Close all open filehandles. */
1284                         while (close_me_list)
1285                                 close((long)llist_pop(&close_me_list));
1286
1287                         if (outpipe[1] != -1) {
1288                                 close(outpipe[0]);
1289                         }
1290                         if (nextin != 0) {
1291                                 dup2(nextin, 0);
1292                                 close(nextin);
1293                         }
1294
1295                         if (nextout != 1) {
1296                                 dup2(nextout, 1);
1297                                 dup2(nextout, 2);  /* Really? */
1298                                 close(nextout);
1299                                 close(pipefds[0]);
1300                         }
1301
1302                         /* explicit redirects override pipes */
1303                         setup_redirects(child,NULL);
1304
1305                         pseudo_exec(child);
1306                 }
1307                 if (outpipe[1] != -1) {
1308                         close(outpipe[1]);
1309                 }
1310
1311                 /* put our child in the process group whose leader is the
1312                    first process in this pipe */
1313                 setpgid(child->pid, newjob->progs[0].pid);
1314                 if (nextin != 0)
1315                         close(nextin);
1316                 if (nextout != 1)
1317                         close(nextout);
1318
1319                 /* If there isn't another process, nextin is garbage
1320                    but it doesn't matter */
1321                 nextin = pipefds[0];
1322         }
1323
1324         newjob->pgrp = newjob->progs[0].pid;
1325
1326         insert_job(newjob, inbg);
1327
1328         return 0;
1329 }
1330
1331 static int busy_loop(FILE * input)
1332 {
1333         char *command;
1334         char *next_command = NULL;
1335         struct job newjob;
1336         int i;
1337         int inbg = 0;
1338         int status;
1339 #if ENABLE_LASH_JOB_CONTROL
1340         pid_t  parent_pgrp;
1341         /* save current owner of TTY so we can restore it on exit */
1342         parent_pgrp = tcgetpgrp(shell_terminal);
1343 #endif
1344         newjob.job_list = &job_list;
1345         newjob.job_context = DEFAULT_CONTEXT;
1346
1347         command = xzalloc(BUFSIZ);
1348
1349         while (1) {
1350                 if (!job_list.fg) {
1351                         /* no job is in the foreground */
1352
1353                         /* see if any background processes have exited */
1354                         checkjobs(&job_list);
1355
1356                         if (!next_command) {
1357                                 if (get_command_bufsiz(input, command))
1358                                         break;
1359                                 next_command = command;
1360                         }
1361
1362                         if (!expand_arguments(next_command)) {
1363                                 free(command);
1364                                 command = xzalloc(BUFSIZ);
1365                                 next_command = NULL;
1366                                 continue;
1367                         }
1368
1369                         if (!parse_command(&next_command, &newjob, &inbg) &&
1370                                 newjob.num_progs) {
1371                                 int pipefds[2] = { -1, -1 };
1372                                 debug_printf("job=%p fed to run_command by busy_loop()'\n",
1373                                                 &newjob);
1374                                 run_command(&newjob, inbg, pipefds);
1375                         }
1376                         else {
1377                                 free(command);
1378                                 command = xzalloc(BUFSIZ);
1379                                 next_command = NULL;
1380                         }
1381                 } else {
1382                         /* a job is running in the foreground; wait for it */
1383                         i = 0;
1384                         while (!job_list.fg->progs[i].pid ||
1385                                    job_list.fg->progs[i].is_stopped == 1) i++;
1386
1387                         if (waitpid(job_list.fg->progs[i].pid, &status, WUNTRACED) < 0) {
1388                                 if (errno != ECHILD) {
1389                                         bb_perror_msg_and_die("waitpid(%d)", job_list.fg->progs[i].pid);
1390                                 }
1391                         }
1392
1393                         if (WIFEXITED(status) || WIFSIGNALED(status)) {
1394                                 /* the child exited */
1395                                 job_list.fg->running_progs--;
1396                                 job_list.fg->progs[i].pid = 0;
1397
1398                                 last_return_code = WEXITSTATUS(status);
1399
1400                                 if (!job_list.fg->running_progs) {
1401                                         /* child exited */
1402                                         remove_job(&job_list, job_list.fg);
1403                                         job_list.fg = NULL;
1404                                 }
1405                         }
1406 #if ENABLE_LASH_JOB_CONTROL
1407                         else {
1408                                 /* the child was stopped */
1409                                 job_list.fg->stopped_progs++;
1410                                 job_list.fg->progs[i].is_stopped = 1;
1411
1412                                 if (job_list.fg->stopped_progs == job_list.fg->running_progs) {
1413                                         printf("\n" JOB_STATUS_FORMAT, job_list.fg->jobid,
1414                                                    "Stopped", job_list.fg->text);
1415                                         job_list.fg = NULL;
1416                                 }
1417                         }
1418
1419                         if (!job_list.fg) {
1420                                 /* move the shell to the foreground */
1421                                 /* suppress messages when run from /linuxrc mag@sysgo.de */
1422                                 if (tcsetpgrp(shell_terminal, getpgrp()) && errno != ENOTTY)
1423                                         bb_perror_msg("tcsetpgrp");
1424                         }
1425 #endif
1426                 }
1427         }
1428         free(command);
1429
1430 #if ENABLE_LASH_JOB_CONTROL
1431         /* return controlling TTY back to parent process group before exiting */
1432         if (tcsetpgrp(shell_terminal, parent_pgrp) && errno != ENOTTY)
1433                 bb_perror_msg("tcsetpgrp");
1434 #endif
1435
1436         /* return exit status if called with "-c" */
1437         if (input == NULL && WIFEXITED(status))
1438                 return WEXITSTATUS(status);
1439
1440         return 0;
1441 }
1442
1443 #if ENABLE_FEATURE_CLEAN_UP
1444 static void free_memory(void)
1445 {
1446         free(cwd);
1447
1448         if (job_list.fg && !job_list.fg->running_progs) {
1449                 remove_job(&job_list, job_list.fg);
1450         }
1451 }
1452 #else
1453 void free_memory(void);
1454 #endif
1455
1456 #if ENABLE_LASH_JOB_CONTROL
1457 /* Make sure we have a controlling tty.  If we get started under a job
1458  * aware app (like bash for example), make sure we are now in charge so
1459  * we don't fight over who gets the foreground */
1460 static void setup_job_control(void)
1461 {
1462         int status;
1463         pid_t shell_pgrp;
1464
1465         /* Loop until we are in the foreground.  */
1466         while ((status = tcgetpgrp(shell_terminal)) >= 0) {
1467                 shell_pgrp = getpgrp();
1468                 if (status == shell_pgrp) {
1469                         break;
1470                 }
1471                 kill(- shell_pgrp, SIGTTIN);
1472         }
1473
1474         /* Ignore interactive and job-control signals.  */
1475         signal(SIGINT, SIG_IGN);
1476         signal(SIGQUIT, SIG_IGN);
1477         signal(SIGTSTP, SIG_IGN);
1478         signal(SIGTTIN, SIG_IGN);
1479         signal(SIGTTOU, SIG_IGN);
1480         signal(SIGCHLD, SIG_IGN);
1481
1482         /* Put ourselves in our own process group.  */
1483         setsid();
1484         shell_pgrp = getpid();
1485         setpgid(shell_pgrp, shell_pgrp);
1486
1487         /* Grab control of the terminal.  */
1488         tcsetpgrp(shell_terminal, shell_pgrp);
1489 }
1490 #else
1491 static inline void setup_job_control(void)
1492 {
1493 }
1494 #endif
1495
1496 int lash_main(int argc_l, char **argv_l);
1497 int lash_main(int argc_l, char **argv_l)
1498 {
1499         unsigned opt;
1500         FILE *input = stdin;
1501         argc = argc_l;
1502         argv = argv_l;
1503
1504 #if ENABLE_FEATURE_EDITING
1505         line_input_state = new_line_input_t(FOR_SHELL);
1506 #endif
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<<1)
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         update_cwd();
1564
1565         if (ENABLE_FEATURE_CLEAN_UP) atexit(free_memory);
1566
1567         if (ENABLE_FEATURE_EDITING) cmdedit_set_initial_prompt();
1568         else PS1 = NULL;
1569
1570         return busy_loop(input);
1571 }