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