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