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