Magellan Linux

Annotation of /trunk/mkinitrd-magellan/busybox/shell/hush.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 532 - (hide annotations) (download)
Sat Sep 1 22:45:15 2007 UTC (16 years, 8 months ago) by niro
File MIME type: text/plain
File size: 79488 byte(s)
-import if magellan mkinitrd; it is a fork of redhats mkinitrd-5.0.8 with all magellan patches and features; deprecates magellan-src/mkinitrd

1 niro 532 /* vi: set sw=4 ts=4: */
2     /*
3     * sh.c -- a prototype Bourne shell grammar parser
4     * Intended to follow the original Thompson and Ritchie
5     * "small and simple is beautiful" philosophy, which
6     * incidentally is a good match to today's BusyBox.
7     *
8     * Copyright (C) 2000,2001 Larry Doolittle <larry@doolittle.boa.org>
9     *
10     * Credits:
11     * The parser routines proper are all original material, first
12     * written Dec 2000 and Jan 2001 by Larry Doolittle. The
13     * execution engine, the builtins, and much of the underlying
14     * support has been adapted from busybox-0.49pre's lash, which is
15     * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
16     * written by Erik Andersen <andersen@codepoet.org>. That, in turn,
17     * is based in part on ladsh.c, by Michael K. Johnson and Erik W.
18     * Troan, which they placed in the public domain. I don't know
19     * how much of the Johnson/Troan code has survived the repeated
20     * rewrites.
21     *
22     * Other credits:
23     * simple_itoa() was lifted from boa-0.93.15
24     * b_addchr() derived from similar w_addchar function in glibc-2.2
25     * setup_redirect(), redirect_opt_num(), and big chunks of main()
26     * and many builtins derived from contributions by Erik Andersen
27     * miscellaneous bugfixes from Matt Kraai
28     *
29     * There are two big (and related) architecture differences between
30     * this parser and the lash parser. One is that this version is
31     * actually designed from the ground up to understand nearly all
32     * of the Bourne grammar. The second, consequential change is that
33     * the parser and input reader have been turned inside out. Now,
34     * the parser is in control, and asks for input as needed. The old
35     * way had the input reader in control, and it asked for parsing to
36     * take place as needed. The new way makes it much easier to properly
37     * handle the recursion implicit in the various substitutions, especially
38     * across continuation lines.
39     *
40     * Bash grammar not implemented: (how many of these were in original sh?)
41     * $@ (those sure look like weird quoting rules)
42     * $_
43     * ! negation operator for pipes
44     * &> and >& redirection of stdout+stderr
45     * Brace Expansion
46     * Tilde Expansion
47     * fancy forms of Parameter Expansion
48     * aliases
49     * Arithmetic Expansion
50     * <(list) and >(list) Process Substitution
51     * reserved words: case, esac, select, function
52     * Here Documents ( << word )
53     * Functions
54     * Major bugs:
55     * job handling woefully incomplete and buggy
56     * reserved word execution woefully incomplete and buggy
57     * to-do:
58     * port selected bugfixes from post-0.49 busybox lash - done?
59     * finish implementing reserved words: for, while, until, do, done
60     * change { and } from special chars to reserved words
61     * builtins: break, continue, eval, return, set, trap, ulimit
62     * test magic exec
63     * handle children going into background
64     * clean up recognition of null pipes
65     * check setting of global_argc and global_argv
66     * control-C handling, probably with longjmp
67     * follow IFS rules more precisely, including update semantics
68     * figure out what to do with backslash-newline
69     * explain why we use signal instead of sigaction
70     * propagate syntax errors, die on resource errors?
71     * continuation lines, both explicit and implicit - done?
72     * memory leak finding and plugging - done?
73     * more testing, especially quoting rules and redirection
74     * document how quoting rules not precisely followed for variable assignments
75     * maybe change map[] to use 2-bit entries
76     * (eventually) remove all the printf's
77     *
78     * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
79     */
80    
81     #include "busybox.h"
82     #include <ctype.h> /* isalpha, isdigit */
83     #include <unistd.h> /* getpid */
84     #include <stdlib.h> /* getenv, atoi */
85     #include <string.h> /* strchr */
86     #include <stdio.h> /* popen etc. */
87     #include <glob.h> /* glob, of course */
88     #include <stdarg.h> /* va_list */
89     #include <errno.h>
90     #include <fcntl.h>
91     #include <getopt.h> /* should be pretty obvious */
92    
93     #include <sys/stat.h> /* ulimit */
94     #include <sys/types.h>
95     #include <sys/wait.h>
96     #include <signal.h>
97    
98     /* #include <dmalloc.h> */
99     /* #define DEBUG_SHELL */
100    
101     #include "cmdedit.h"
102    
103     #define SPECIAL_VAR_SYMBOL 03
104     #define FLAG_EXIT_FROM_LOOP 1
105     #define FLAG_PARSE_SEMICOLON (1 << 1) /* symbol ';' is special for parser */
106     #define FLAG_REPARSING (1 << 2) /* >=2nd pass */
107    
108     typedef enum {
109     REDIRECT_INPUT = 1,
110     REDIRECT_OVERWRITE = 2,
111     REDIRECT_APPEND = 3,
112     REDIRECT_HEREIS = 4,
113     REDIRECT_IO = 5
114     } redir_type;
115    
116     /* The descrip member of this structure is only used to make debugging
117     * output pretty */
118     static const struct {int mode; int default_fd; const char *descrip;} redir_table[] = {
119     { 0, 0, "()" },
120     { O_RDONLY, 0, "<" },
121     { O_CREAT|O_TRUNC|O_WRONLY, 1, ">" },
122     { O_CREAT|O_APPEND|O_WRONLY, 1, ">>" },
123     { O_RDONLY, -1, "<<" },
124     { O_RDWR, 1, "<>" }
125     };
126    
127     typedef enum {
128     PIPE_SEQ = 1,
129     PIPE_AND = 2,
130     PIPE_OR = 3,
131     PIPE_BG = 4,
132     } pipe_style;
133    
134     /* might eventually control execution */
135     typedef enum {
136     RES_NONE = 0,
137     RES_IF = 1,
138     RES_THEN = 2,
139     RES_ELIF = 3,
140     RES_ELSE = 4,
141     RES_FI = 5,
142     RES_FOR = 6,
143     RES_WHILE = 7,
144     RES_UNTIL = 8,
145     RES_DO = 9,
146     RES_DONE = 10,
147     RES_XXXX = 11,
148     RES_IN = 12,
149     RES_SNTX = 13
150     } reserved_style;
151     #define FLAG_END (1<<RES_NONE)
152     #define FLAG_IF (1<<RES_IF)
153     #define FLAG_THEN (1<<RES_THEN)
154     #define FLAG_ELIF (1<<RES_ELIF)
155     #define FLAG_ELSE (1<<RES_ELSE)
156     #define FLAG_FI (1<<RES_FI)
157     #define FLAG_FOR (1<<RES_FOR)
158     #define FLAG_WHILE (1<<RES_WHILE)
159     #define FLAG_UNTIL (1<<RES_UNTIL)
160     #define FLAG_DO (1<<RES_DO)
161     #define FLAG_DONE (1<<RES_DONE)
162     #define FLAG_IN (1<<RES_IN)
163     #define FLAG_START (1<<RES_XXXX)
164    
165     /* This holds pointers to the various results of parsing */
166     struct p_context {
167     struct child_prog *child;
168     struct pipe *list_head;
169     struct pipe *pipe;
170     struct redir_struct *pending_redirect;
171     reserved_style w;
172     int old_flag; /* for figuring out valid reserved words */
173     struct p_context *stack;
174     int type; /* define type of parser : ";$" common or special symbol */
175     /* How about quoting status? */
176     };
177    
178     struct redir_struct {
179     redir_type type; /* type of redirection */
180     int fd; /* file descriptor being redirected */
181     int dup; /* -1, or file descriptor being duplicated */
182     struct redir_struct *next; /* pointer to the next redirect in the list */
183     glob_t word; /* *word.gl_pathv is the filename */
184     };
185    
186     struct child_prog {
187     pid_t pid; /* 0 if exited */
188     char **argv; /* program name and arguments */
189     struct pipe *group; /* if non-NULL, first in group or subshell */
190     int subshell; /* flag, non-zero if group must be forked */
191     struct redir_struct *redirects; /* I/O redirections */
192     glob_t glob_result; /* result of parameter globbing */
193     int is_stopped; /* is the program currently running? */
194     struct pipe *family; /* pointer back to the child's parent pipe */
195     int sp; /* number of SPECIAL_VAR_SYMBOL */
196     int type;
197     };
198    
199     struct pipe {
200     int jobid; /* job number */
201     int num_progs; /* total number of programs in job */
202     int running_progs; /* number of programs running */
203     char *text; /* name of job */
204     char *cmdbuf; /* buffer various argv's point into */
205     pid_t pgrp; /* process group ID for the job */
206     struct child_prog *progs; /* array of commands in pipe */
207     struct pipe *next; /* to track background commands */
208     int stopped_progs; /* number of programs alive, but stopped */
209     int job_context; /* bitmask defining current context */
210     pipe_style followup; /* PIPE_BG, PIPE_SEQ, PIPE_OR, PIPE_AND */
211     reserved_style r_mode; /* supports if, for, while, until */
212     };
213    
214     struct close_me {
215     int fd;
216     struct close_me *next;
217     };
218    
219     struct variables {
220     char *name;
221     char *value;
222     int flg_export;
223     int flg_read_only;
224     struct variables *next;
225     };
226    
227     /* globals, connect us to the outside world
228     * the first three support $?, $#, and $1 */
229     static char **global_argv;
230     static int global_argc;
231     static int last_return_code;
232     extern char **environ; /* This is in <unistd.h>, but protected with __USE_GNU */
233    
234     /* "globals" within this file */
235     static char *ifs;
236     static unsigned char map[256];
237     static int fake_mode;
238     static int interactive;
239     static struct close_me *close_me_head;
240     static const char *cwd;
241     static struct pipe *job_list;
242     static unsigned int last_bg_pid;
243     static int last_jobid;
244     static unsigned int shell_terminal;
245     static char *PS1;
246     static char *PS2;
247     static struct variables shell_ver = { "HUSH_VERSION", "0.01", 1, 1, 0 };
248     static struct variables *top_vars = &shell_ver;
249    
250    
251     #define B_CHUNK (100)
252     #define B_NOSPAC 1
253    
254     typedef struct {
255     char *data;
256     int length;
257     int maxlen;
258     int quote;
259     int nonnull;
260     } o_string;
261     #define NULL_O_STRING {NULL,0,0,0,0}
262     /* used for initialization:
263     o_string foo = NULL_O_STRING; */
264    
265     /* I can almost use ordinary FILE *. Is open_memstream() universally
266     * available? Where is it documented? */
267     struct in_str {
268     const char *p;
269     char peek_buf[2];
270     int __promptme;
271     int promptmode;
272     FILE *file;
273     int (*get) (struct in_str *);
274     int (*peek) (struct in_str *);
275     };
276     #define b_getch(input) ((input)->get(input))
277     #define b_peek(input) ((input)->peek(input))
278    
279     #define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
280    
281     struct built_in_command {
282     const char *cmd; /* name */
283     const char *descr; /* description */
284     int (*function) (struct child_prog *); /* function ptr */
285     };
286    
287     /* belongs in busybox.h */
288     static int max(int a, int b) {
289     return (a>b)?a:b;
290     }
291    
292     /* This should be in utility.c */
293     #ifdef DEBUG_SHELL
294     static void debug_printf(const char *format, ...)
295     {
296     va_list args;
297     va_start(args, format);
298     vfprintf(stderr, format, args);
299     va_end(args);
300     }
301     /* broken, of course, but OK for testing */
302     static char *indenter(int i)
303     {
304     static char blanks[]=" ";
305     return &blanks[sizeof(blanks)-i-1];
306     }
307     #else
308     #define debug_printf(...) do {;} while(0);
309     #endif
310     #define final_printf debug_printf
311    
312     static void __syntax(char *file, int line) {
313     bb_error_msg("syntax error %s:%d", file, line);
314     }
315     // NB: was __FILE__, but that produces full path sometimess, so...
316     #define syntax() __syntax("hush.c", __LINE__)
317    
318     /* Index of subroutines: */
319     /* function prototypes for builtins */
320     static int builtin_cd(struct child_prog *child);
321     static int builtin_env(struct child_prog *child);
322     static int builtin_eval(struct child_prog *child);
323     static int builtin_exec(struct child_prog *child);
324     static int builtin_exit(struct child_prog *child);
325     static int builtin_export(struct child_prog *child);
326     static int builtin_fg_bg(struct child_prog *child);
327     static int builtin_help(struct child_prog *child);
328     static int builtin_jobs(struct child_prog *child);
329     static int builtin_pwd(struct child_prog *child);
330     static int builtin_read(struct child_prog *child);
331     static int builtin_set(struct child_prog *child);
332     static int builtin_shift(struct child_prog *child);
333     static int builtin_source(struct child_prog *child);
334     static int builtin_umask(struct child_prog *child);
335     static int builtin_unset(struct child_prog *child);
336     static int builtin_not_written(struct child_prog *child);
337     /* o_string manipulation: */
338     static int b_check_space(o_string *o, int len);
339     static int b_addchr(o_string *o, int ch);
340     static void b_reset(o_string *o);
341     static int b_addqchr(o_string *o, int ch, int quote);
342     static int b_adduint(o_string *o, unsigned int i);
343     /* in_str manipulations: */
344     static int static_get(struct in_str *i);
345     static int static_peek(struct in_str *i);
346     static int file_get(struct in_str *i);
347     static int file_peek(struct in_str *i);
348     static void setup_file_in_str(struct in_str *i, FILE *f);
349     static void setup_string_in_str(struct in_str *i, const char *s);
350     /* close_me manipulations: */
351     static void mark_open(int fd);
352     static void mark_closed(int fd);
353     static void close_all(void);
354     /* "run" the final data structures: */
355     static int free_pipe_list(struct pipe *head, int indent);
356     static int free_pipe(struct pipe *pi, int indent);
357     /* really run the final data structures: */
358     static int setup_redirects(struct child_prog *prog, int squirrel[]);
359     static int run_list_real(struct pipe *pi);
360     static void pseudo_exec(struct child_prog *child) ATTRIBUTE_NORETURN;
361     static int run_pipe_real(struct pipe *pi);
362     /* extended glob support: */
363     static int globhack(const char *src, int flags, glob_t *pglob);
364     static int glob_needed(const char *s);
365     static int xglob(o_string *dest, int flags, glob_t *pglob);
366     /* variable assignment: */
367     static int is_assignment(const char *s);
368     /* data structure manipulation: */
369     static int setup_redirect(struct p_context *ctx, int fd, redir_type style, struct in_str *input);
370     static void initialize_context(struct p_context *ctx);
371     static int done_word(o_string *dest, struct p_context *ctx);
372     static int done_command(struct p_context *ctx);
373     static int done_pipe(struct p_context *ctx, pipe_style type);
374     /* primary string parsing: */
375     static int redirect_dup_num(struct in_str *input);
376     static int redirect_opt_num(o_string *o);
377     static int process_command_subs(o_string *dest, struct p_context *ctx, struct in_str *input, int subst_end);
378     static int parse_group(o_string *dest, struct p_context *ctx, struct in_str *input, int ch);
379     static char *lookup_param(char *src);
380     static char *make_string(char **inp);
381     static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *input);
382     static int parse_string(o_string *dest, struct p_context *ctx, const char *src);
383     static int parse_stream(o_string *dest, struct p_context *ctx, struct in_str *input0, int end_trigger);
384     /* setup: */
385     static int parse_stream_outer(struct in_str *inp, int flag);
386     static int parse_string_outer(const char *s, int flag);
387     static int parse_file_outer(FILE *f);
388     /* job management: */
389     static int checkjobs(struct pipe* fg_pipe);
390     static void insert_bg_job(struct pipe *pi);
391     static void remove_bg_job(struct pipe *pi);
392     /* local variable support */
393     static char **make_list_in(char **inp, char *name);
394     static char *insert_var_value(char *inp);
395     static char *get_local_var(const char *var);
396     static void unset_local_var(const char *name);
397     static int set_local_var(const char *s, int flg_export);
398    
399     /* Table of built-in functions. They can be forked or not, depending on
400     * context: within pipes, they fork. As simple commands, they do not.
401     * When used in non-forking context, they can change global variables
402     * in the parent shell process. If forked, of course they cannot.
403     * For example, 'unset foo | whatever' will parse and run, but foo will
404     * still be set at the end. */
405     static const struct built_in_command bltins[] = {
406     {"bg", "Resume a job in the background", builtin_fg_bg},
407     {"break", "Exit for, while or until loop", builtin_not_written},
408     {"cd", "Change working directory", builtin_cd},
409     {"continue", "Continue for, while or until loop", builtin_not_written},
410     {"env", "Print all environment variables", builtin_env},
411     {"eval", "Construct and run shell command", builtin_eval},
412     {"exec", "Exec command, replacing this shell with the exec'd process",
413     builtin_exec},
414     {"exit", "Exit from shell()", builtin_exit},
415     {"export", "Set environment variable", builtin_export},
416     {"fg", "Bring job into the foreground", builtin_fg_bg},
417     {"jobs", "Lists the active jobs", builtin_jobs},
418     {"pwd", "Print current directory", builtin_pwd},
419     {"read", "Input environment variable", builtin_read},
420     {"return", "Return from a function", builtin_not_written},
421     {"set", "Set/unset shell local variables", builtin_set},
422     {"shift", "Shift positional parameters", builtin_shift},
423     {"trap", "Trap signals", builtin_not_written},
424     {"ulimit","Controls resource limits", builtin_not_written},
425     {"umask","Sets file creation mask", builtin_umask},
426     {"unset", "Unset environment variable", builtin_unset},
427     {".", "Source-in and run commands in a file", builtin_source},
428     {"help", "List shell built-in commands", builtin_help},
429     {NULL, NULL, NULL}
430     };
431    
432     static const char *set_cwd(void)
433     {
434     if(cwd==bb_msg_unknown)
435     cwd = NULL; /* xgetcwd(arg) called free(arg) */
436     cwd = xgetcwd((char *)cwd);
437     if (!cwd)
438     cwd = bb_msg_unknown;
439     return cwd;
440     }
441    
442     /* built-in 'eval' handler */
443     static int builtin_eval(struct child_prog *child)
444     {
445     char *str = NULL;
446     int rcode = EXIT_SUCCESS;
447    
448     if (child->argv[1]) {
449     str = make_string(child->argv + 1);
450     parse_string_outer(str, FLAG_EXIT_FROM_LOOP |
451     FLAG_PARSE_SEMICOLON);
452     free(str);
453     rcode = last_return_code;
454     }
455     return rcode;
456     }
457    
458     /* built-in 'cd <path>' handler */
459     static int builtin_cd(struct child_prog *child)
460     {
461     char *newdir;
462     if (child->argv[1] == NULL)
463     newdir = getenv("HOME");
464     else
465     newdir = child->argv[1];
466     if (chdir(newdir)) {
467     printf("cd: %s: %s\n", newdir, strerror(errno));
468     return EXIT_FAILURE;
469     }
470     set_cwd();
471     return EXIT_SUCCESS;
472     }
473    
474     /* built-in 'env' handler */
475     static int builtin_env(struct child_prog *dummy ATTRIBUTE_UNUSED)
476     {
477     char **e = environ;
478     if (e == NULL) return EXIT_FAILURE;
479     for (; *e; e++) {
480     puts(*e);
481     }
482     return EXIT_SUCCESS;
483     }
484    
485     /* built-in 'exec' handler */
486     static int builtin_exec(struct child_prog *child)
487     {
488     if (child->argv[1] == NULL)
489     return EXIT_SUCCESS; /* Really? */
490     child->argv++;
491     pseudo_exec(child);
492     /* never returns */
493     }
494    
495     /* built-in 'exit' handler */
496     static int builtin_exit(struct child_prog *child)
497     {
498     if (child->argv[1] == NULL)
499     exit(last_return_code);
500     exit (atoi(child->argv[1]));
501     }
502    
503     /* built-in 'export VAR=value' handler */
504     static int builtin_export(struct child_prog *child)
505     {
506     int res = 0;
507     char *name = child->argv[1];
508    
509     if (name == NULL) {
510     return builtin_env(child);
511     }
512    
513     name = strdup(name);
514    
515     if(name) {
516     char *value = strchr(name, '=');
517    
518     if (!value) {
519     char *tmp;
520     /* They are exporting something without an =VALUE */
521    
522     value = get_local_var(name);
523     if (value) {
524     size_t ln = strlen(name);
525    
526     tmp = realloc(name, ln+strlen(value)+2);
527     if(tmp==NULL)
528     res = -1;
529     else {
530     sprintf(tmp+ln, "=%s", value);
531     name = tmp;
532     }
533     } else {
534     /* bash does not return an error when trying to export
535     * an undefined variable. Do likewise. */
536     res = 1;
537     }
538     }
539     }
540     if (res<0)
541     bb_perror_msg("export");
542     else if(res==0)
543     res = set_local_var(name, 1);
544     else
545     res = 0;
546     free(name);
547     return res;
548     }
549    
550     /* built-in 'fg' and 'bg' handler */
551     static int builtin_fg_bg(struct child_prog *child)
552     {
553     int i, jobnum;
554     struct pipe *pi=NULL;
555    
556     if (!interactive)
557     return EXIT_FAILURE;
558     /* If they gave us no args, assume they want the last backgrounded task */
559     if (!child->argv[1]) {
560     for (pi = job_list; pi; pi = pi->next) {
561     if (pi->jobid == last_jobid) {
562     break;
563     }
564     }
565     if (!pi) {
566     bb_error_msg("%s: no current job", child->argv[0]);
567     return EXIT_FAILURE;
568     }
569     } else {
570     if (sscanf(child->argv[1], "%%%d", &jobnum) != 1) {
571     bb_error_msg("%s: bad argument '%s'", child->argv[0], child->argv[1]);
572     return EXIT_FAILURE;
573     }
574     for (pi = job_list; pi; pi = pi->next) {
575     if (pi->jobid == jobnum) {
576     break;
577     }
578     }
579     if (!pi) {
580     bb_error_msg("%s: %d: no such job", child->argv[0], jobnum);
581     return EXIT_FAILURE;
582     }
583     }
584    
585     if (*child->argv[0] == 'f') {
586     /* Put the job into the foreground. */
587     tcsetpgrp(shell_terminal, pi->pgrp);
588     }
589    
590     /* Restart the processes in the job */
591     for (i = 0; i < pi->num_progs; i++)
592     pi->progs[i].is_stopped = 0;
593    
594     if ( (i=kill(- pi->pgrp, SIGCONT)) < 0) {
595     if (i == ESRCH) {
596     remove_bg_job(pi);
597     } else {
598     bb_perror_msg("kill (SIGCONT)");
599     }
600     }
601    
602     pi->stopped_progs = 0;
603     return EXIT_SUCCESS;
604     }
605    
606     /* built-in 'help' handler */
607     static int builtin_help(struct child_prog *dummy ATTRIBUTE_UNUSED)
608     {
609     const struct built_in_command *x;
610    
611     printf("\nBuilt-in commands:\n");
612     printf("-------------------\n");
613     for (x = bltins; x->cmd; x++) {
614     if (x->descr==NULL)
615     continue;
616     printf("%s\t%s\n", x->cmd, x->descr);
617     }
618     printf("\n\n");
619     return EXIT_SUCCESS;
620     }
621    
622     /* built-in 'jobs' handler */
623     static int builtin_jobs(struct child_prog *child ATTRIBUTE_UNUSED)
624     {
625     struct pipe *job;
626     char *status_string;
627    
628     for (job = job_list; job; job = job->next) {
629     if (job->running_progs == job->stopped_progs)
630     status_string = "Stopped";
631     else
632     status_string = "Running";
633    
634     printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->text);
635     }
636     return EXIT_SUCCESS;
637     }
638    
639    
640     /* built-in 'pwd' handler */
641     static int builtin_pwd(struct child_prog *dummy ATTRIBUTE_UNUSED)
642     {
643     puts(set_cwd());
644     return EXIT_SUCCESS;
645     }
646    
647     /* built-in 'read VAR' handler */
648     static int builtin_read(struct child_prog *child)
649     {
650     int res;
651    
652     if (child->argv[1]) {
653     char string[BUFSIZ];
654     char *var = 0;
655    
656     string[0] = 0; /* In case stdin has only EOF */
657     /* read string */
658     fgets(string, sizeof(string), stdin);
659     chomp(string);
660     var = malloc(strlen(child->argv[1])+strlen(string)+2);
661     if(var) {
662     sprintf(var, "%s=%s", child->argv[1], string);
663     res = set_local_var(var, 0);
664     } else
665     res = -1;
666     if (res)
667     bb_perror_msg("read");
668     free(var); /* So not move up to avoid breaking errno */
669     return res;
670     } else {
671     do res=getchar(); while(res!='\n' && res!=EOF);
672     return 0;
673     }
674     }
675    
676     /* built-in 'set VAR=value' handler */
677     static int builtin_set(struct child_prog *child)
678     {
679     char *temp = child->argv[1];
680     struct variables *e;
681    
682     if (temp == NULL)
683     for(e = top_vars; e; e=e->next)
684     printf("%s=%s\n", e->name, e->value);
685     else
686     set_local_var(temp, 0);
687    
688     return EXIT_SUCCESS;
689     }
690    
691    
692     /* Built-in 'shift' handler */
693     static int builtin_shift(struct child_prog *child)
694     {
695     int n=1;
696     if (child->argv[1]) {
697     n=atoi(child->argv[1]);
698     }
699     if (n>=0 && n<global_argc) {
700     /* XXX This probably breaks $0 */
701     global_argc -= n;
702     global_argv += n;
703     return EXIT_SUCCESS;
704     } else {
705     return EXIT_FAILURE;
706     }
707     }
708    
709     /* Built-in '.' handler (read-in and execute commands from file) */
710     static int builtin_source(struct child_prog *child)
711     {
712     FILE *input;
713     int status;
714    
715     if (child->argv[1] == NULL)
716     return EXIT_FAILURE;
717    
718     /* XXX search through $PATH is missing */
719     input = fopen(child->argv[1], "r");
720     if (!input) {
721     bb_error_msg("cannot open '%s'", child->argv[1]);
722     return EXIT_FAILURE;
723     }
724    
725     /* Now run the file */
726     /* XXX argv and argc are broken; need to save old global_argv
727     * (pointer only is OK!) on this stack frame,
728     * set global_argv=child->argv+1, recurse, and restore. */
729     mark_open(fileno(input));
730     status = parse_file_outer(input);
731     mark_closed(fileno(input));
732     fclose(input);
733     return status;
734     }
735    
736     static int builtin_umask(struct child_prog *child)
737     {
738     mode_t new_umask;
739     const char *arg = child->argv[1];
740     char *end;
741     if (arg) {
742     new_umask=strtoul(arg, &end, 8);
743     if (*end!='\0' || end == arg) {
744     return EXIT_FAILURE;
745     }
746     } else {
747     printf("%.3o\n", (unsigned int) (new_umask=umask(0)));
748     }
749     umask(new_umask);
750     return EXIT_SUCCESS;
751     }
752    
753     /* built-in 'unset VAR' handler */
754     static int builtin_unset(struct child_prog *child)
755     {
756     /* bash returned already true */
757     unset_local_var(child->argv[1]);
758     return EXIT_SUCCESS;
759     }
760    
761     static int builtin_not_written(struct child_prog *child)
762     {
763     printf("builtin_%s not written\n",child->argv[0]);
764     return EXIT_FAILURE;
765     }
766    
767     static int b_check_space(o_string *o, int len)
768     {
769     /* It would be easy to drop a more restrictive policy
770     * in here, such as setting a maximum string length */
771     if (o->length + len > o->maxlen) {
772     char *old_data = o->data;
773     /* assert (data == NULL || o->maxlen != 0); */
774     o->maxlen += max(2*len, B_CHUNK);
775     o->data = realloc(o->data, 1 + o->maxlen);
776     if (o->data == NULL) {
777     free(old_data);
778     }
779     }
780     return o->data == NULL;
781     }
782    
783     static int b_addchr(o_string *o, int ch)
784     {
785     debug_printf("b_addchr: %c %d %p\n", ch, o->length, o);
786     if (b_check_space(o, 1)) return B_NOSPAC;
787     o->data[o->length] = ch;
788     o->length++;
789     o->data[o->length] = '\0';
790     return 0;
791     }
792    
793     static void b_reset(o_string *o)
794     {
795     o->length = 0;
796     o->nonnull = 0;
797     if (o->data != NULL) *o->data = '\0';
798     }
799    
800     static void b_free(o_string *o)
801     {
802     b_reset(o);
803     free(o->data);
804     o->data = NULL;
805     o->maxlen = 0;
806     }
807    
808     /* My analysis of quoting semantics tells me that state information
809     * is associated with a destination, not a source.
810     */
811     static int b_addqchr(o_string *o, int ch, int quote)
812     {
813     if (quote && strchr("*?[\\",ch)) {
814     int rc;
815     rc = b_addchr(o, '\\');
816     if (rc) return rc;
817     }
818     return b_addchr(o, ch);
819     }
820    
821     /* belongs in utility.c */
822     static char *simple_itoa(unsigned int i)
823     {
824     /* 21 digits plus null terminator, good for 64-bit or smaller ints */
825     static char local[22];
826     char *p = &local[21];
827     *p-- = '\0';
828     do {
829     *p-- = '0' + i % 10;
830     i /= 10;
831     } while (i > 0);
832     return p + 1;
833     }
834    
835     static int b_adduint(o_string *o, unsigned int i)
836     {
837     int r;
838     char *p = simple_itoa(i);
839     /* no escape checking necessary */
840     do r=b_addchr(o, *p++); while (r==0 && *p);
841     return r;
842     }
843    
844     static int static_get(struct in_str *i)
845     {
846     int ch=*i->p++;
847     if (ch=='\0') return EOF;
848     return ch;
849     }
850    
851     static int static_peek(struct in_str *i)
852     {
853     return *i->p;
854     }
855    
856     static void cmdedit_set_initial_prompt(void)
857     {
858     #ifndef CONFIG_FEATURE_SH_FANCY_PROMPT
859     PS1 = NULL;
860     #else
861     PS1 = getenv("PS1");
862     if(PS1==0)
863     PS1 = "\\w \\$ ";
864     #endif
865     }
866    
867     static void setup_prompt_string(int promptmode, char **prompt_str)
868     {
869     debug_printf("setup_prompt_string %d ",promptmode);
870     #ifndef CONFIG_FEATURE_SH_FANCY_PROMPT
871     /* Set up the prompt */
872     if (promptmode == 1) {
873     free(PS1);
874     PS1=xmalloc(strlen(cwd)+4);
875     sprintf(PS1, "%s %s", cwd, ( geteuid() != 0 ) ? "$ ":"# ");
876     *prompt_str = PS1;
877     } else {
878     *prompt_str = PS2;
879     }
880     #else
881     *prompt_str = (promptmode==1)? PS1 : PS2;
882     #endif
883     debug_printf("result %s\n",*prompt_str);
884     }
885    
886     static void get_user_input(struct in_str *i)
887     {
888     char *prompt_str;
889     static char the_command[BUFSIZ];
890    
891     setup_prompt_string(i->promptmode, &prompt_str);
892     #ifdef CONFIG_FEATURE_COMMAND_EDITING
893     /*
894     ** enable command line editing only while a command line
895     ** is actually being read; otherwise, we'll end up bequeathing
896     ** atexit() handlers and other unwanted stuff to our
897     ** child processes (rob@sysgo.de)
898     */
899     cmdedit_read_input(prompt_str, the_command);
900     #else
901     fputs(prompt_str, stdout);
902     fflush(stdout);
903     the_command[0]=fgetc(i->file);
904     the_command[1]='\0';
905     #endif
906     fflush(stdout);
907     i->p = the_command;
908     }
909    
910     /* This is the magic location that prints prompts
911     * and gets data back from the user */
912     static int file_get(struct in_str *i)
913     {
914     int ch;
915    
916     ch = 0;
917     /* If there is data waiting, eat it up */
918     if (i->p && *i->p) {
919     ch=*i->p++;
920     } else {
921     /* need to double check i->file because we might be doing something
922     * more complicated by now, like sourcing or substituting. */
923     if (i->__promptme && interactive && i->file == stdin) {
924     while(! i->p || (interactive && strlen(i->p)==0) ) {
925     get_user_input(i);
926     }
927     i->promptmode=2;
928     i->__promptme = 0;
929     if (i->p && *i->p) {
930     ch=*i->p++;
931     }
932     } else {
933     ch = fgetc(i->file);
934     }
935    
936     debug_printf("b_getch: got a %d\n", ch);
937     }
938     if (ch == '\n') i->__promptme=1;
939     return ch;
940     }
941    
942     /* All the callers guarantee this routine will never be
943     * used right after a newline, so prompting is not needed.
944     */
945     static int file_peek(struct in_str *i)
946     {
947     if (i->p && *i->p) {
948     return *i->p;
949     } else {
950     i->peek_buf[0] = fgetc(i->file);
951     i->peek_buf[1] = '\0';
952     i->p = i->peek_buf;
953     debug_printf("b_peek: got a %d\n", *i->p);
954     return *i->p;
955     }
956     }
957    
958     static void setup_file_in_str(struct in_str *i, FILE *f)
959     {
960     i->peek = file_peek;
961     i->get = file_get;
962     i->__promptme=1;
963     i->promptmode=1;
964     i->file = f;
965     i->p = NULL;
966     }
967    
968     static void setup_string_in_str(struct in_str *i, const char *s)
969     {
970     i->peek = static_peek;
971     i->get = static_get;
972     i->__promptme=1;
973     i->promptmode=1;
974     i->p = s;
975     }
976    
977     static void mark_open(int fd)
978     {
979     struct close_me *new = xmalloc(sizeof(struct close_me));
980     new->fd = fd;
981     new->next = close_me_head;
982     close_me_head = new;
983     }
984    
985     static void mark_closed(int fd)
986     {
987     struct close_me *tmp;
988     if (close_me_head == NULL || close_me_head->fd != fd)
989     bb_error_msg_and_die("corrupt close_me");
990     tmp = close_me_head;
991     close_me_head = close_me_head->next;
992     free(tmp);
993     }
994    
995     static void close_all(void)
996     {
997     struct close_me *c;
998     for (c=close_me_head; c; c=c->next) {
999     close(c->fd);
1000     }
1001     close_me_head = NULL;
1002     }
1003    
1004     /* squirrel != NULL means we squirrel away copies of stdin, stdout,
1005     * and stderr if they are redirected. */
1006     static int setup_redirects(struct child_prog *prog, int squirrel[])
1007     {
1008     int openfd, mode;
1009     struct redir_struct *redir;
1010    
1011     for (redir=prog->redirects; redir; redir=redir->next) {
1012     if (redir->dup == -1 && redir->word.gl_pathv == NULL) {
1013     /* something went wrong in the parse. Pretend it didn't happen */
1014     continue;
1015     }
1016     if (redir->dup == -1) {
1017     mode=redir_table[redir->type].mode;
1018     openfd = open(redir->word.gl_pathv[0], mode, 0666);
1019     if (openfd < 0) {
1020     /* this could get lost if stderr has been redirected, but
1021     bash and ash both lose it as well (though zsh doesn't!) */
1022     bb_perror_msg("error opening %s", redir->word.gl_pathv[0]);
1023     return 1;
1024     }
1025     } else {
1026     openfd = redir->dup;
1027     }
1028    
1029     if (openfd != redir->fd) {
1030     if (squirrel && redir->fd < 3) {
1031     squirrel[redir->fd] = dup(redir->fd);
1032     }
1033     if (openfd == -3) {
1034     close(openfd);
1035     } else {
1036     dup2(openfd, redir->fd);
1037     if (redir->dup == -1)
1038     close (openfd);
1039     }
1040     }
1041     }
1042     return 0;
1043     }
1044    
1045     static void restore_redirects(int squirrel[])
1046     {
1047     int i, fd;
1048     for (i=0; i<3; i++) {
1049     fd = squirrel[i];
1050     if (fd != -1) {
1051     /* No error checking. I sure wouldn't know what
1052     * to do with an error if I found one! */
1053     dup2(fd, i);
1054     close(fd);
1055     }
1056     }
1057     }
1058    
1059     /* never returns */
1060     /* XXX no exit() here. If you don't exec, use _exit instead.
1061     * The at_exit handlers apparently confuse the calling process,
1062     * in particular stdin handling. Not sure why? */
1063     static void pseudo_exec(struct child_prog *child)
1064     {
1065     int i, rcode;
1066     char *p;
1067     const struct built_in_command *x;
1068     if (child->argv) {
1069     for (i=0; is_assignment(child->argv[i]); i++) {
1070     debug_printf("pid %d environment modification: %s\n",getpid(),child->argv[i]);
1071     p = insert_var_value(child->argv[i]);
1072     putenv(strdup(p));
1073     if (p != child->argv[i]) free(p);
1074     }
1075     child->argv+=i; /* XXX this hack isn't so horrible, since we are about
1076     to exit, and therefore don't need to keep data
1077     structures consistent for free() use. */
1078     /* If a variable is assigned in a forest, and nobody listens,
1079     * was it ever really set?
1080     */
1081     if (child->argv[0] == NULL) {
1082     _exit(EXIT_SUCCESS);
1083     }
1084    
1085     /*
1086     * Check if the command matches any of the builtins.
1087     * Depending on context, this might be redundant. But it's
1088     * easier to waste a few CPU cycles than it is to figure out
1089     * if this is one of those cases.
1090     */
1091     for (x = bltins; x->cmd; x++) {
1092     if (strcmp(child->argv[0], x->cmd) == 0 ) {
1093     debug_printf("builtin exec %s\n", child->argv[0]);
1094     rcode = x->function(child);
1095     fflush(stdout);
1096     _exit(rcode);
1097     }
1098     }
1099    
1100     /* Check if the command matches any busybox internal commands
1101     * ("applets") here.
1102     * FIXME: This feature is not 100% safe, since
1103     * BusyBox is not fully reentrant, so we have no guarantee the things
1104     * from the .bss are still zeroed, or that things from .data are still
1105     * at their defaults. We could exec ourself from /proc/self/exe, but I
1106     * really dislike relying on /proc for things. We could exec ourself
1107     * from global_argv[0], but if we are in a chroot, we may not be able
1108     * to find ourself... */
1109     #ifdef CONFIG_FEATURE_SH_STANDALONE_SHELL
1110     {
1111     int argc_l;
1112     char** argv_l=child->argv;
1113     char *name = child->argv[0];
1114    
1115     /* Count argc for use in a second... */
1116     for(argc_l=0;*argv_l!=NULL; argv_l++, argc_l++);
1117     optind = 1;
1118     debug_printf("running applet %s\n", name);
1119     run_applet_by_name(name, argc_l, child->argv);
1120     }
1121     #endif
1122     debug_printf("exec of %s\n",child->argv[0]);
1123     execvp(child->argv[0],child->argv);
1124     bb_perror_msg("cannot exec: %s",child->argv[0]);
1125     _exit(1);
1126     } else if (child->group) {
1127     debug_printf("runtime nesting to group\n");
1128     interactive=0; /* crucial!!!! */
1129     rcode = run_list_real(child->group);
1130     /* OK to leak memory by not calling free_pipe_list,
1131     * since this process is about to exit */
1132     _exit(rcode);
1133     } else {
1134     /* Can happen. See what bash does with ">foo" by itself. */
1135     debug_printf("trying to pseudo_exec null command\n");
1136     _exit(EXIT_SUCCESS);
1137     }
1138     }
1139    
1140     static void insert_bg_job(struct pipe *pi)
1141     {
1142     struct pipe *thejob;
1143    
1144     /* Linear search for the ID of the job to use */
1145     pi->jobid = 1;
1146     for (thejob = job_list; thejob; thejob = thejob->next)
1147     if (thejob->jobid >= pi->jobid)
1148     pi->jobid = thejob->jobid + 1;
1149    
1150     /* add thejob to the list of running jobs */
1151     if (!job_list) {
1152     thejob = job_list = xmalloc(sizeof(*thejob));
1153     } else {
1154     for (thejob = job_list; thejob->next; thejob = thejob->next) /* nothing */;
1155     thejob->next = xmalloc(sizeof(*thejob));
1156     thejob = thejob->next;
1157     }
1158    
1159     /* physically copy the struct job */
1160     memcpy(thejob, pi, sizeof(struct pipe));
1161     thejob->next = NULL;
1162     thejob->running_progs = thejob->num_progs;
1163     thejob->stopped_progs = 0;
1164     thejob->text = xmalloc(BUFSIZ); /* cmdedit buffer size */
1165    
1166     //if (pi->progs[0] && pi->progs[0].argv && pi->progs[0].argv[0])
1167     {
1168     char *bar=thejob->text;
1169     char **foo=pi->progs[0].argv;
1170     while(foo && *foo) {
1171     bar += sprintf(bar, "%s ", *foo++);
1172     }
1173     }
1174    
1175     /* we don't wait for background thejobs to return -- append it
1176     to the list of backgrounded thejobs and leave it alone */
1177     printf("[%d] %d\n", thejob->jobid, thejob->progs[0].pid);
1178     last_bg_pid = thejob->progs[0].pid;
1179     last_jobid = thejob->jobid;
1180     }
1181    
1182     /* remove a backgrounded job */
1183     static void remove_bg_job(struct pipe *pi)
1184     {
1185     struct pipe *prev_pipe;
1186    
1187     if (pi == job_list) {
1188     job_list = pi->next;
1189     } else {
1190     prev_pipe = job_list;
1191     while (prev_pipe->next != pi)
1192     prev_pipe = prev_pipe->next;
1193     prev_pipe->next = pi->next;
1194     }
1195     if (job_list)
1196     last_jobid = job_list->jobid;
1197     else
1198     last_jobid = 0;
1199    
1200     pi->stopped_progs = 0;
1201     free_pipe(pi, 0);
1202     free(pi);
1203     }
1204    
1205     /* Checks to see if any processes have exited -- if they
1206     have, figure out why and see if a job has completed */
1207     static int checkjobs(struct pipe* fg_pipe)
1208     {
1209     int attributes;
1210     int status;
1211     int prognum = 0;
1212     struct pipe *pi;
1213     pid_t childpid;
1214    
1215     attributes = WUNTRACED;
1216     if (fg_pipe==NULL) {
1217     attributes |= WNOHANG;
1218     }
1219    
1220     while ((childpid = waitpid(-1, &status, attributes)) > 0) {
1221     if (fg_pipe) {
1222     int i, rcode = 0;
1223     for (i=0; i < fg_pipe->num_progs; i++) {
1224     if (fg_pipe->progs[i].pid == childpid) {
1225     if (i==fg_pipe->num_progs-1)
1226     rcode=WEXITSTATUS(status);
1227     (fg_pipe->num_progs)--;
1228     return rcode;
1229     }
1230     }
1231     }
1232    
1233     for (pi = job_list; pi; pi = pi->next) {
1234     prognum = 0;
1235     while (prognum < pi->num_progs && pi->progs[prognum].pid != childpid) {
1236     prognum++;
1237     }
1238     if (prognum < pi->num_progs)
1239     break;
1240     }
1241    
1242     if(pi==NULL) {
1243     debug_printf("checkjobs: pid %d was not in our list!\n", childpid);
1244     continue;
1245     }
1246    
1247     if (WIFEXITED(status) || WIFSIGNALED(status)) {
1248     /* child exited */
1249     pi->running_progs--;
1250     pi->progs[prognum].pid = 0;
1251    
1252     if (!pi->running_progs) {
1253     printf(JOB_STATUS_FORMAT, pi->jobid, "Done", pi->text);
1254     remove_bg_job(pi);
1255     }
1256     } else {
1257     /* child stopped */
1258     pi->stopped_progs++;
1259     pi->progs[prognum].is_stopped = 1;
1260     }
1261     }
1262    
1263     if (childpid == -1 && errno != ECHILD)
1264     bb_perror_msg("waitpid");
1265    
1266     /* move the shell to the foreground */
1267     //if (interactive && tcsetpgrp(shell_terminal, getpgid(0)))
1268     // bb_perror_msg("tcsetpgrp-2");
1269     return -1;
1270     }
1271    
1272     /* run_pipe_real() starts all the jobs, but doesn't wait for anything
1273     * to finish. See checkjobs().
1274     *
1275     * return code is normally -1, when the caller has to wait for children
1276     * to finish to determine the exit status of the pipe. If the pipe
1277     * is a simple builtin command, however, the action is done by the
1278     * time run_pipe_real returns, and the exit code is provided as the
1279     * return value.
1280     *
1281     * The input of the pipe is always stdin, the output is always
1282     * stdout. The outpipe[] mechanism in BusyBox-0.48 lash is bogus,
1283     * because it tries to avoid running the command substitution in
1284     * subshell, when that is in fact necessary. The subshell process
1285     * now has its stdout directed to the input of the appropriate pipe,
1286     * so this routine is noticeably simpler.
1287     */
1288     static int run_pipe_real(struct pipe *pi)
1289     {
1290     int i;
1291     int nextin, nextout;
1292     int pipefds[2]; /* pipefds[0] is for reading */
1293     struct child_prog *child;
1294     const struct built_in_command *x;
1295     char *p;
1296    
1297     nextin = 0;
1298     pi->pgrp = -1;
1299    
1300     /* Check if this is a simple builtin (not part of a pipe).
1301     * Builtins within pipes have to fork anyway, and are handled in
1302     * pseudo_exec. "echo foo | read bar" doesn't work on bash, either.
1303     */
1304     child = & (pi->progs[0]);
1305     if (pi->num_progs == 1 && child->group && child->subshell == 0) {
1306     int squirrel[] = {-1, -1, -1};
1307     int rcode;
1308     debug_printf("non-subshell grouping\n");
1309     setup_redirects(child, squirrel);
1310     /* XXX could we merge code with following builtin case,
1311     * by creating a pseudo builtin that calls run_list_real? */
1312     rcode = run_list_real(child->group);
1313     restore_redirects(squirrel);
1314     return rcode;
1315     } else if (pi->num_progs == 1 && pi->progs[0].argv != NULL) {
1316     for (i=0; is_assignment(child->argv[i]); i++) { /* nothing */ }
1317     if (i!=0 && child->argv[i]==NULL) {
1318     /* assignments, but no command: set the local environment */
1319     for (i=0; child->argv[i]!=NULL; i++) {
1320    
1321     /* Ok, this case is tricky. We have to decide if this is a
1322     * local variable, or an already exported variable. If it is
1323     * already exported, we have to export the new value. If it is
1324     * not exported, we need only set this as a local variable.
1325     * This junk is all to decide whether or not to export this
1326     * variable. */
1327     int export_me=0;
1328     char *name, *value;
1329     name = xstrdup(child->argv[i]);
1330     debug_printf("Local environment set: %s\n", name);
1331     value = strchr(name, '=');
1332     if (value)
1333     *value=0;
1334     if ( get_local_var(name)) {
1335     export_me=1;
1336     }
1337     free(name);
1338     p = insert_var_value(child->argv[i]);
1339     set_local_var(p, export_me);
1340     if (p != child->argv[i]) free(p);
1341     }
1342     return EXIT_SUCCESS; /* don't worry about errors in set_local_var() yet */
1343     }
1344     for (i = 0; is_assignment(child->argv[i]); i++) {
1345     p = insert_var_value(child->argv[i]);
1346     putenv(strdup(p));
1347     if (p != child->argv[i]) {
1348     child->sp--;
1349     free(p);
1350     }
1351     }
1352     if (child->sp) {
1353     char * str = NULL;
1354    
1355     str = make_string((child->argv + i));
1356     parse_string_outer(str, FLAG_EXIT_FROM_LOOP | FLAG_REPARSING);
1357     free(str);
1358     return last_return_code;
1359     }
1360     for (x = bltins; x->cmd; x++) {
1361     if (strcmp(child->argv[i], x->cmd) == 0 ) {
1362     int squirrel[] = {-1, -1, -1};
1363     int rcode;
1364     if (x->function == builtin_exec && child->argv[i+1]==NULL) {
1365     debug_printf("magic exec\n");
1366     setup_redirects(child,NULL);
1367     return EXIT_SUCCESS;
1368     }
1369     debug_printf("builtin inline %s\n", child->argv[0]);
1370     /* XXX setup_redirects acts on file descriptors, not FILEs.
1371     * This is perfect for work that comes after exec().
1372     * Is it really safe for inline use? Experimentally,
1373     * things seem to work with glibc. */
1374     setup_redirects(child, squirrel);
1375     child->argv+=i; /* XXX horrible hack */
1376     rcode = x->function(child);
1377     child->argv-=i; /* XXX restore hack so free() can work right */
1378     restore_redirects(squirrel);
1379     return rcode;
1380     }
1381     }
1382     }
1383    
1384     for (i = 0; i < pi->num_progs; i++) {
1385     child = & (pi->progs[i]);
1386    
1387     /* pipes are inserted between pairs of commands */
1388     if ((i + 1) < pi->num_progs) {
1389     if (pipe(pipefds)<0) bb_perror_msg_and_die("pipe");
1390     nextout = pipefds[1];
1391     } else {
1392     nextout=1;
1393     pipefds[0] = -1;
1394     }
1395    
1396     /* XXX test for failed fork()? */
1397     #if !defined(__UCLIBC__) || defined(__ARCH_HAS_MMU__)
1398     if (!(child->pid = fork()))
1399     #else
1400     if (!(child->pid = vfork()))
1401     #endif
1402     {
1403     /* Set the handling for job control signals back to the default. */
1404     signal(SIGINT, SIG_DFL);
1405     signal(SIGQUIT, SIG_DFL);
1406     signal(SIGTERM, SIG_DFL);
1407     signal(SIGTSTP, SIG_DFL);
1408     signal(SIGTTIN, SIG_DFL);
1409     signal(SIGTTOU, SIG_DFL);
1410     signal(SIGCHLD, SIG_DFL);
1411    
1412     close_all();
1413    
1414     if (nextin != 0) {
1415     dup2(nextin, 0);
1416     close(nextin);
1417     }
1418     if (nextout != 1) {
1419     dup2(nextout, 1);
1420     close(nextout);
1421     }
1422     if (pipefds[0]!=-1) {
1423     close(pipefds[0]); /* opposite end of our output pipe */
1424     }
1425    
1426     /* Like bash, explicit redirects override pipes,
1427     * and the pipe fd is available for dup'ing. */
1428     setup_redirects(child,NULL);
1429    
1430     if (interactive && pi->followup!=PIPE_BG) {
1431     /* If we (the child) win the race, put ourselves in the process
1432     * group whose leader is the first process in this pipe. */
1433     if (pi->pgrp < 0) {
1434     pi->pgrp = getpid();
1435     }
1436     if (setpgid(0, pi->pgrp) == 0) {
1437     tcsetpgrp(2, pi->pgrp);
1438     }
1439     }
1440    
1441     pseudo_exec(child);
1442     }
1443    
1444    
1445     /* put our child in the process group whose leader is the
1446     first process in this pipe */
1447     if (pi->pgrp < 0) {
1448     pi->pgrp = child->pid;
1449     }
1450     /* Don't check for errors. The child may be dead already,
1451     * in which case setpgid returns error code EACCES. */
1452     setpgid(child->pid, pi->pgrp);
1453    
1454     if (nextin != 0)
1455     close(nextin);
1456     if (nextout != 1)
1457     close(nextout);
1458    
1459     /* If there isn't another process, nextin is garbage
1460     but it doesn't matter */
1461     nextin = pipefds[0];
1462     }
1463     return -1;
1464     }
1465    
1466     static int run_list_real(struct pipe *pi)
1467     {
1468     char *save_name = NULL;
1469     char **list = NULL;
1470     char **save_list = NULL;
1471     struct pipe *rpipe;
1472     int flag_rep = 0;
1473     int save_num_progs;
1474     int rcode=0, flag_skip=1;
1475     int flag_restore = 0;
1476     int if_code=0, next_if_code=0; /* need double-buffer to handle elif */
1477     reserved_style rmode, skip_more_in_this_rmode=RES_XXXX;
1478     /* check syntax for "for" */
1479     for (rpipe = pi; rpipe; rpipe = rpipe->next) {
1480     if ((rpipe->r_mode == RES_IN ||
1481     rpipe->r_mode == RES_FOR) &&
1482     (rpipe->next == NULL)) {
1483     syntax();
1484     return 1;
1485     }
1486     if ((rpipe->r_mode == RES_IN &&
1487     (rpipe->next->r_mode == RES_IN &&
1488     rpipe->next->progs->argv != NULL))||
1489     (rpipe->r_mode == RES_FOR &&
1490     rpipe->next->r_mode != RES_IN)) {
1491     syntax();
1492     return 1;
1493     }
1494     }
1495     for (; pi; pi = (flag_restore != 0) ? rpipe : pi->next) {
1496     if (pi->r_mode == RES_WHILE || pi->r_mode == RES_UNTIL ||
1497     pi->r_mode == RES_FOR) {
1498     flag_restore = 0;
1499     if (!rpipe) {
1500     flag_rep = 0;
1501     rpipe = pi;
1502     }
1503     }
1504     rmode = pi->r_mode;
1505     debug_printf("rmode=%d if_code=%d next_if_code=%d skip_more=%d\n", rmode, if_code, next_if_code, skip_more_in_this_rmode);
1506     if (rmode == skip_more_in_this_rmode && flag_skip) {
1507     if (pi->followup == PIPE_SEQ) flag_skip=0;
1508     continue;
1509     }
1510     flag_skip = 1;
1511     skip_more_in_this_rmode = RES_XXXX;
1512     if (rmode == RES_THEN || rmode == RES_ELSE) if_code = next_if_code;
1513     if (rmode == RES_THEN && if_code) continue;
1514     if (rmode == RES_ELSE && !if_code) continue;
1515     if (rmode == RES_ELIF && !if_code) break;
1516     if (rmode == RES_FOR && pi->num_progs) {
1517     if (!list) {
1518     /* if no variable values after "in" we skip "for" */
1519     if (!pi->next->progs->argv) continue;
1520     /* create list of variable values */
1521     list = make_list_in(pi->next->progs->argv,
1522     pi->progs->argv[0]);
1523     save_list = list;
1524     save_name = pi->progs->argv[0];
1525     pi->progs->argv[0] = NULL;
1526     flag_rep = 1;
1527     }
1528     if (!(*list)) {
1529     free(pi->progs->argv[0]);
1530     free(save_list);
1531     list = NULL;
1532     flag_rep = 0;
1533     pi->progs->argv[0] = save_name;
1534     pi->progs->glob_result.gl_pathv[0] =
1535     pi->progs->argv[0];
1536     continue;
1537     } else {
1538     /* insert new value from list for variable */
1539     if (pi->progs->argv[0])
1540     free(pi->progs->argv[0]);
1541     pi->progs->argv[0] = *list++;
1542     pi->progs->glob_result.gl_pathv[0] =
1543     pi->progs->argv[0];
1544     }
1545     }
1546     if (rmode == RES_IN) continue;
1547     if (rmode == RES_DO) {
1548     if (!flag_rep) continue;
1549     }
1550     if ((rmode == RES_DONE)) {
1551     if (flag_rep) {
1552     flag_restore = 1;
1553     } else {
1554     rpipe = NULL;
1555     }
1556     }
1557     if (pi->num_progs == 0) continue;
1558     save_num_progs = pi->num_progs; /* save number of programs */
1559     rcode = run_pipe_real(pi);
1560     debug_printf("run_pipe_real returned %d\n",rcode);
1561     if (rcode!=-1) {
1562     /* We only ran a builtin: rcode was set by the return value
1563     * of run_pipe_real(), and we don't need to wait for anything. */
1564     } else if (pi->followup==PIPE_BG) {
1565     /* XXX check bash's behavior with nontrivial pipes */
1566     /* XXX compute jobid */
1567     /* XXX what does bash do with attempts to background builtins? */
1568     insert_bg_job(pi);
1569     rcode = EXIT_SUCCESS;
1570     } else {
1571     if (interactive) {
1572     /* move the new process group into the foreground */
1573     if (tcsetpgrp(shell_terminal, pi->pgrp) && errno != ENOTTY)
1574     bb_perror_msg("tcsetpgrp-3");
1575     rcode = checkjobs(pi);
1576     /* move the shell to the foreground */
1577     if (tcsetpgrp(shell_terminal, getpgid(0)) && errno != ENOTTY)
1578     bb_perror_msg("tcsetpgrp-4");
1579     } else {
1580     rcode = checkjobs(pi);
1581     }
1582     debug_printf("checkjobs returned %d\n",rcode);
1583     }
1584     last_return_code=rcode;
1585     pi->num_progs = save_num_progs; /* restore number of programs */
1586     if ( rmode == RES_IF || rmode == RES_ELIF )
1587     next_if_code=rcode; /* can be overwritten a number of times */
1588     if (rmode == RES_WHILE)
1589     flag_rep = !last_return_code;
1590     if (rmode == RES_UNTIL)
1591     flag_rep = last_return_code;
1592     if ( (rcode==EXIT_SUCCESS && pi->followup==PIPE_OR) ||
1593     (rcode!=EXIT_SUCCESS && pi->followup==PIPE_AND) )
1594     skip_more_in_this_rmode=rmode;
1595     checkjobs(NULL);
1596     }
1597     return rcode;
1598     }
1599    
1600     /* return code is the exit status of the pipe */
1601     static int free_pipe(struct pipe *pi, int indent)
1602     {
1603     char **p;
1604     struct child_prog *child;
1605     struct redir_struct *r, *rnext;
1606     int a, i, ret_code=0;
1607    
1608     if (pi->stopped_progs > 0)
1609     return ret_code;
1610     final_printf("%s run pipe: (pid %d)\n",indenter(indent),getpid());
1611     for (i=0; i<pi->num_progs; i++) {
1612     child = &pi->progs[i];
1613     final_printf("%s command %d:\n",indenter(indent),i);
1614     if (child->argv) {
1615     for (a=0,p=child->argv; *p; a++,p++) {
1616     final_printf("%s argv[%d] = %s\n",indenter(indent),a,*p);
1617     }
1618     globfree(&child->glob_result);
1619     child->argv=NULL;
1620     } else if (child->group) {
1621     final_printf("%s begin group (subshell:%d)\n",indenter(indent), child->subshell);
1622     ret_code = free_pipe_list(child->group,indent+3);
1623     final_printf("%s end group\n",indenter(indent));
1624     } else {
1625     final_printf("%s (nil)\n",indenter(indent));
1626     }
1627     for (r=child->redirects; r; r=rnext) {
1628     final_printf("%s redirect %d%s", indenter(indent), r->fd, redir_table[r->type].descrip);
1629     if (r->dup == -1) {
1630     /* guard against the case >$FOO, where foo is unset or blank */
1631     if (r->word.gl_pathv) {
1632     final_printf(" %s\n", *r->word.gl_pathv);
1633     globfree(&r->word);
1634     }
1635     } else {
1636     final_printf("&%d\n", r->dup);
1637     }
1638     rnext=r->next;
1639     free(r);
1640     }
1641     child->redirects=NULL;
1642     }
1643     free(pi->progs); /* children are an array, they get freed all at once */
1644     pi->progs=NULL;
1645     return ret_code;
1646     }
1647    
1648     static int free_pipe_list(struct pipe *head, int indent)
1649     {
1650     int rcode=0; /* if list has no members */
1651     struct pipe *pi, *next;
1652     for (pi=head; pi; pi=next) {
1653     final_printf("%s pipe reserved mode %d\n", indenter(indent), pi->r_mode);
1654     rcode = free_pipe(pi, indent);
1655     final_printf("%s pipe followup code %d\n", indenter(indent), pi->followup);
1656     next=pi->next;
1657     pi->next=NULL;
1658     free(pi);
1659     }
1660     return rcode;
1661     }
1662    
1663     /* Select which version we will use */
1664     static int run_list(struct pipe *pi)
1665     {
1666     int rcode=0;
1667     if (fake_mode==0) {
1668     rcode = run_list_real(pi);
1669     }
1670     /* free_pipe_list has the side effect of clearing memory
1671     * In the long run that function can be merged with run_list_real,
1672     * but doing that now would hobble the debugging effort. */
1673     free_pipe_list(pi,0);
1674     return rcode;
1675     }
1676    
1677     /* The API for glob is arguably broken. This routine pushes a non-matching
1678     * string into the output structure, removing non-backslashed backslashes.
1679     * If someone can prove me wrong, by performing this function within the
1680     * original glob(3) api, feel free to rewrite this routine into oblivion.
1681     * Return code (0 vs. GLOB_NOSPACE) matches glob(3).
1682     * XXX broken if the last character is '\\', check that before calling.
1683     */
1684     static int globhack(const char *src, int flags, glob_t *pglob)
1685     {
1686     int cnt=0, pathc;
1687     const char *s;
1688     char *dest;
1689     for (cnt=1, s=src; s && *s; s++) {
1690     if (*s == '\\') s++;
1691     cnt++;
1692     }
1693     dest = malloc(cnt);
1694     if (!dest) return GLOB_NOSPACE;
1695     if (!(flags & GLOB_APPEND)) {
1696     pglob->gl_pathv=NULL;
1697     pglob->gl_pathc=0;
1698     pglob->gl_offs=0;
1699     pglob->gl_offs=0;
1700     }
1701     pathc = ++pglob->gl_pathc;
1702     pglob->gl_pathv = realloc(pglob->gl_pathv, (pathc+1)*sizeof(*pglob->gl_pathv));
1703     if (pglob->gl_pathv == NULL) return GLOB_NOSPACE;
1704     pglob->gl_pathv[pathc-1]=dest;
1705     pglob->gl_pathv[pathc]=NULL;
1706     for (s=src; s && *s; s++, dest++) {
1707     if (*s == '\\') s++;
1708     *dest = *s;
1709     }
1710     *dest='\0';
1711     return 0;
1712     }
1713    
1714     /* XXX broken if the last character is '\\', check that before calling */
1715     static int glob_needed(const char *s)
1716     {
1717     for (; *s; s++) {
1718     if (*s == '\\') s++;
1719     if (strchr("*[?",*s)) return 1;
1720     }
1721     return 0;
1722     }
1723    
1724     static int xglob(o_string *dest, int flags, glob_t *pglob)
1725     {
1726     int gr;
1727    
1728     /* short-circuit for null word */
1729     /* we can code this better when the debug_printf's are gone */
1730     if (dest->length == 0) {
1731     if (dest->nonnull) {
1732     /* bash man page calls this an "explicit" null */
1733     gr = globhack(dest->data, flags, pglob);
1734     debug_printf("globhack returned %d\n",gr);
1735     } else {
1736     return 0;
1737     }
1738     } else if (glob_needed(dest->data)) {
1739     gr = glob(dest->data, flags, NULL, pglob);
1740     debug_printf("glob returned %d\n",gr);
1741     if (gr == GLOB_NOMATCH) {
1742     /* quote removal, or more accurately, backslash removal */
1743     gr = globhack(dest->data, flags, pglob);
1744     debug_printf("globhack returned %d\n",gr);
1745     }
1746     } else {
1747     gr = globhack(dest->data, flags, pglob);
1748     debug_printf("globhack returned %d\n",gr);
1749     }
1750     if (gr == GLOB_NOSPACE)
1751     bb_error_msg_and_die("out of memory during glob");
1752     if (gr != 0) { /* GLOB_ABORTED ? */
1753     bb_error_msg("glob(3) error %d",gr);
1754     }
1755     /* globprint(glob_target); */
1756     return gr;
1757     }
1758    
1759     /* This is used to get/check local shell variables */
1760     static char *get_local_var(const char *s)
1761     {
1762     struct variables *cur;
1763    
1764     if (!s)
1765     return NULL;
1766     for (cur = top_vars; cur; cur=cur->next)
1767     if(strcmp(cur->name, s)==0)
1768     return cur->value;
1769     return NULL;
1770     }
1771    
1772     /* This is used to set local shell variables
1773     flg_export==0 if only local (not exporting) variable
1774     flg_export==1 if "new" exporting environ
1775     flg_export>1 if current startup environ (not call putenv()) */
1776     static int set_local_var(const char *s, int flg_export)
1777     {
1778     char *name, *value;
1779     int result=0;
1780     struct variables *cur;
1781    
1782     name=strdup(s);
1783    
1784     /* Assume when we enter this function that we are already in
1785     * NAME=VALUE format. So the first order of business is to
1786     * split 's' on the '=' into 'name' and 'value' */
1787     value = strchr(name, '=');
1788     if (value==0 && ++value==0) {
1789     free(name);
1790     return -1;
1791     }
1792     *value++ = 0;
1793    
1794     for(cur = top_vars; cur; cur = cur->next) {
1795     if(strcmp(cur->name, name)==0)
1796     break;
1797     }
1798    
1799     if(cur) {
1800     if(strcmp(cur->value, value)==0) {
1801     if(flg_export>0 && cur->flg_export==0)
1802     cur->flg_export=flg_export;
1803     else
1804     result++;
1805     } else {
1806     if(cur->flg_read_only) {
1807     bb_error_msg("%s: readonly variable", name);
1808     result = -1;
1809     } else {
1810     if(flg_export>0 || cur->flg_export>1)
1811     cur->flg_export=1;
1812     free(cur->value);
1813    
1814     cur->value = strdup(value);
1815     }
1816     }
1817     } else {
1818     cur = malloc(sizeof(struct variables));
1819     if(!cur) {
1820     result = -1;
1821     } else {
1822     cur->name = strdup(name);
1823     if(cur->name == 0) {
1824     free(cur);
1825     result = -1;
1826     } else {
1827     struct variables *bottom = top_vars;
1828     cur->value = strdup(value);
1829     cur->next = 0;
1830     cur->flg_export = flg_export;
1831     cur->flg_read_only = 0;
1832     while(bottom->next) bottom=bottom->next;
1833     bottom->next = cur;
1834     }
1835     }
1836     }
1837    
1838     if(result==0 && cur->flg_export==1) {
1839     *(value-1) = '=';
1840     result = putenv(name);
1841     } else {
1842     free(name);
1843     if(result>0) /* equivalent to previous set */
1844     result = 0;
1845     }
1846     return result;
1847     }
1848    
1849     static void unset_local_var(const char *name)
1850     {
1851     struct variables *cur;
1852    
1853     if (name) {
1854     for (cur = top_vars; cur; cur=cur->next) {
1855     if(strcmp(cur->name, name)==0)
1856     break;
1857     }
1858     if(cur!=0) {
1859     struct variables *next = top_vars;
1860     if(cur->flg_read_only) {
1861     bb_error_msg("%s: readonly variable", name);
1862     return;
1863     } else {
1864     if(cur->flg_export)
1865     unsetenv(cur->name);
1866     free(cur->name);
1867     free(cur->value);
1868     while (next->next != cur)
1869     next = next->next;
1870     next->next = cur->next;
1871     }
1872     free(cur);
1873     }
1874     }
1875     }
1876    
1877     static int is_assignment(const char *s)
1878     {
1879     if (s==NULL || !isalpha(*s)) return 0;
1880     ++s;
1881     while(isalnum(*s) || *s=='_') ++s;
1882     return *s=='=';
1883     }
1884    
1885     /* the src parameter allows us to peek forward to a possible &n syntax
1886     * for file descriptor duplication, e.g., "2>&1".
1887     * Return code is 0 normally, 1 if a syntax error is detected in src.
1888     * Resource errors (in xmalloc) cause the process to exit */
1889     static int setup_redirect(struct p_context *ctx, int fd, redir_type style,
1890     struct in_str *input)
1891     {
1892     struct child_prog *child=ctx->child;
1893     struct redir_struct *redir = child->redirects;
1894     struct redir_struct *last_redir=NULL;
1895    
1896     /* Create a new redir_struct and drop it onto the end of the linked list */
1897     while(redir) {
1898     last_redir=redir;
1899     redir=redir->next;
1900     }
1901     redir = xmalloc(sizeof(struct redir_struct));
1902     redir->next=NULL;
1903     redir->word.gl_pathv=NULL;
1904     if (last_redir) {
1905     last_redir->next=redir;
1906     } else {
1907     child->redirects=redir;
1908     }
1909    
1910     redir->type=style;
1911     redir->fd= (fd==-1) ? redir_table[style].default_fd : fd ;
1912    
1913     debug_printf("Redirect type %d%s\n", redir->fd, redir_table[style].descrip);
1914    
1915     /* Check for a '2>&1' type redirect */
1916     redir->dup = redirect_dup_num(input);
1917     if (redir->dup == -2) return 1; /* syntax error */
1918     if (redir->dup != -1) {
1919     /* Erik had a check here that the file descriptor in question
1920     * is legit; I postpone that to "run time"
1921     * A "-" representation of "close me" shows up as a -3 here */
1922     debug_printf("Duplicating redirect '%d>&%d'\n", redir->fd, redir->dup);
1923     } else {
1924     /* We do _not_ try to open the file that src points to,
1925     * since we need to return and let src be expanded first.
1926     * Set ctx->pending_redirect, so we know what to do at the
1927     * end of the next parsed word.
1928     */
1929     ctx->pending_redirect = redir;
1930     }
1931     return 0;
1932     }
1933    
1934     static struct pipe *new_pipe(void) {
1935     struct pipe *pi;
1936     pi = xmalloc(sizeof(struct pipe));
1937     pi->num_progs = 0;
1938     pi->progs = NULL;
1939     pi->next = NULL;
1940     pi->followup = 0; /* invalid */
1941     pi->r_mode = RES_NONE;
1942     return pi;
1943     }
1944    
1945     static void initialize_context(struct p_context *ctx)
1946     {
1947     ctx->pipe=NULL;
1948     ctx->pending_redirect=NULL;
1949     ctx->child=NULL;
1950     ctx->list_head=new_pipe();
1951     ctx->pipe=ctx->list_head;
1952     ctx->w=RES_NONE;
1953     ctx->stack=NULL;
1954     ctx->old_flag=0;
1955     done_command(ctx); /* creates the memory for working child */
1956     }
1957    
1958     /* normal return is 0
1959     * if a reserved word is found, and processed, return 1
1960     * should handle if, then, elif, else, fi, for, while, until, do, done.
1961     * case, function, and select are obnoxious, save those for later.
1962     */
1963     static int reserved_word(o_string *dest, struct p_context *ctx)
1964     {
1965     struct reserved_combo {
1966     char *literal;
1967     int code;
1968     long flag;
1969     };
1970     /* Mostly a list of accepted follow-up reserved words.
1971     * FLAG_END means we are done with the sequence, and are ready
1972     * to turn the compound list into a command.
1973     * FLAG_START means the word must start a new compound list.
1974     */
1975     static struct reserved_combo reserved_list[] = {
1976     { "if", RES_IF, FLAG_THEN | FLAG_START },
1977     { "then", RES_THEN, FLAG_ELIF | FLAG_ELSE | FLAG_FI },
1978     { "elif", RES_ELIF, FLAG_THEN },
1979     { "else", RES_ELSE, FLAG_FI },
1980     { "fi", RES_FI, FLAG_END },
1981     { "for", RES_FOR, FLAG_IN | FLAG_START },
1982     { "while", RES_WHILE, FLAG_DO | FLAG_START },
1983     { "until", RES_UNTIL, FLAG_DO | FLAG_START },
1984     { "in", RES_IN, FLAG_DO },
1985     { "do", RES_DO, FLAG_DONE },
1986     { "done", RES_DONE, FLAG_END }
1987     };
1988     struct reserved_combo *r;
1989     for (r=reserved_list;
1990     #define NRES sizeof(reserved_list)/sizeof(struct reserved_combo)
1991     r<reserved_list+NRES; r++) {
1992     if (strcmp(dest->data, r->literal) == 0) {
1993     debug_printf("found reserved word %s, code %d\n",r->literal,r->code);
1994     if (r->flag & FLAG_START) {
1995     struct p_context *new = xmalloc(sizeof(struct p_context));
1996     debug_printf("push stack\n");
1997     if (ctx->w == RES_IN || ctx->w == RES_FOR) {
1998     syntax();
1999     free(new);
2000     ctx->w = RES_SNTX;
2001     b_reset(dest);
2002     return 1;
2003     }
2004     *new = *ctx; /* physical copy */
2005     initialize_context(ctx);
2006     ctx->stack=new;
2007     } else if ( ctx->w == RES_NONE || ! (ctx->old_flag & (1<<r->code))) {
2008     syntax();
2009     ctx->w = RES_SNTX;
2010     b_reset(dest);
2011     return 1;
2012     }
2013     ctx->w=r->code;
2014     ctx->old_flag = r->flag;
2015     if (ctx->old_flag & FLAG_END) {
2016     struct p_context *old;
2017     debug_printf("pop stack\n");
2018     done_pipe(ctx,PIPE_SEQ);
2019     old = ctx->stack;
2020     old->child->group = ctx->list_head;
2021     old->child->subshell = 0;
2022     *ctx = *old; /* physical copy */
2023     free(old);
2024     }
2025     b_reset (dest);
2026     return 1;
2027     }
2028     }
2029     return 0;
2030     }
2031    
2032     /* normal return is 0.
2033     * Syntax or xglob errors return 1. */
2034     static int done_word(o_string *dest, struct p_context *ctx)
2035     {
2036     struct child_prog *child=ctx->child;
2037     glob_t *glob_target;
2038     int gr, flags = 0;
2039    
2040     debug_printf("done_word: %s %p\n", dest->data, child);
2041     if (dest->length == 0 && !dest->nonnull) {
2042     debug_printf(" true null, ignored\n");
2043     return 0;
2044     }
2045     if (ctx->pending_redirect) {
2046     glob_target = &ctx->pending_redirect->word;
2047     } else {
2048     if (child->group) {
2049     syntax();
2050     return 1; /* syntax error, groups and arglists don't mix */
2051     }
2052     if (!child->argv && (ctx->type & FLAG_PARSE_SEMICOLON)) {
2053     debug_printf("checking %s for reserved-ness\n",dest->data);
2054     if (reserved_word(dest,ctx)) return ctx->w==RES_SNTX;
2055     }
2056     glob_target = &child->glob_result;
2057     if (child->argv) flags |= GLOB_APPEND;
2058     }
2059     gr = xglob(dest, flags, glob_target);
2060     if (gr != 0) return 1;
2061    
2062     b_reset(dest);
2063     if (ctx->pending_redirect) {
2064     ctx->pending_redirect=NULL;
2065     if (glob_target->gl_pathc != 1) {
2066     bb_error_msg("ambiguous redirect");
2067     return 1;
2068     }
2069     } else {
2070     child->argv = glob_target->gl_pathv;
2071     }
2072     if (ctx->w == RES_FOR) {
2073     done_word(dest,ctx);
2074     done_pipe(ctx,PIPE_SEQ);
2075     }
2076     return 0;
2077     }
2078    
2079     /* The only possible error here is out of memory, in which case
2080     * xmalloc exits. */
2081     static int done_command(struct p_context *ctx)
2082     {
2083     /* The child is really already in the pipe structure, so
2084     * advance the pipe counter and make a new, null child.
2085     * Only real trickiness here is that the uncommitted
2086     * child structure, to which ctx->child points, is not
2087     * counted in pi->num_progs. */
2088     struct pipe *pi=ctx->pipe;
2089     struct child_prog *prog=ctx->child;
2090    
2091     if (prog && prog->group == NULL
2092     && prog->argv == NULL
2093     && prog->redirects == NULL) {
2094     debug_printf("done_command: skipping null command\n");
2095     return 0;
2096     } else if (prog) {
2097     pi->num_progs++;
2098     debug_printf("done_command: num_progs incremented to %d\n",pi->num_progs);
2099     } else {
2100     debug_printf("done_command: initializing\n");
2101     }
2102     pi->progs = xrealloc(pi->progs, sizeof(*pi->progs) * (pi->num_progs+1));
2103    
2104     prog = pi->progs + pi->num_progs;
2105     prog->redirects = NULL;
2106     prog->argv = NULL;
2107     prog->is_stopped = 0;
2108     prog->group = NULL;
2109     prog->glob_result.gl_pathv = NULL;
2110     prog->family = pi;
2111     prog->sp = 0;
2112     ctx->child = prog;
2113     prog->type = ctx->type;
2114    
2115     /* but ctx->pipe and ctx->list_head remain unchanged */
2116     return 0;
2117     }
2118    
2119     static int done_pipe(struct p_context *ctx, pipe_style type)
2120     {
2121     struct pipe *new_p;
2122     done_command(ctx); /* implicit closure of previous command */
2123     debug_printf("done_pipe, type %d\n", type);
2124     ctx->pipe->followup = type;
2125     ctx->pipe->r_mode = ctx->w;
2126     new_p=new_pipe();
2127     ctx->pipe->next = new_p;
2128     ctx->pipe = new_p;
2129     ctx->child = NULL;
2130     done_command(ctx); /* set up new pipe to accept commands */
2131     return 0;
2132     }
2133    
2134     /* peek ahead in the in_str to find out if we have a "&n" construct,
2135     * as in "2>&1", that represents duplicating a file descriptor.
2136     * returns either -2 (syntax error), -1 (no &), or the number found.
2137     */
2138     static int redirect_dup_num(struct in_str *input)
2139     {
2140     int ch, d=0, ok=0;
2141     ch = b_peek(input);
2142     if (ch != '&') return -1;
2143    
2144     b_getch(input); /* get the & */
2145     ch=b_peek(input);
2146     if (ch == '-') {
2147     b_getch(input);
2148     return -3; /* "-" represents "close me" */
2149     }
2150     while (isdigit(ch)) {
2151     d = d*10+(ch-'0');
2152     ok=1;
2153     b_getch(input);
2154     ch = b_peek(input);
2155     }
2156     if (ok) return d;
2157    
2158     bb_error_msg("ambiguous redirect");
2159     return -2;
2160     }
2161    
2162     /* If a redirect is immediately preceded by a number, that number is
2163     * supposed to tell which file descriptor to redirect. This routine
2164     * looks for such preceding numbers. In an ideal world this routine
2165     * needs to handle all the following classes of redirects...
2166     * echo 2>foo # redirects fd 2 to file "foo", nothing passed to echo
2167     * echo 49>foo # redirects fd 49 to file "foo", nothing passed to echo
2168     * echo -2>foo # redirects fd 1 to file "foo", "-2" passed to echo
2169     * echo 49x>foo # redirects fd 1 to file "foo", "49x" passed to echo
2170     * A -1 output from this program means no valid number was found, so the
2171     * caller should use the appropriate default for this redirection.
2172     */
2173     static int redirect_opt_num(o_string *o)
2174     {
2175     int num;
2176    
2177     if (o->length==0) return -1;
2178     for(num=0; num<o->length; num++) {
2179     if (!isdigit(*(o->data+num))) {
2180     return -1;
2181     }
2182     }
2183     /* reuse num (and save an int) */
2184     num=atoi(o->data);
2185     b_reset(o);
2186     return num;
2187     }
2188    
2189     static FILE *generate_stream_from_list(struct pipe *head)
2190     {
2191     FILE *pf;
2192     int pid, channel[2];
2193     if (pipe(channel)<0) bb_perror_msg_and_die("pipe");
2194     #if !defined(__UCLIBC__) || defined(__ARCH_HAS_MMU__)
2195     pid=fork();
2196     #else
2197     pid=vfork();
2198     #endif
2199     if (pid<0) {
2200     bb_perror_msg_and_die("fork");
2201     } else if (pid==0) {
2202     close(channel[0]);
2203     if (channel[1] != 1) {
2204     dup2(channel[1],1);
2205     close(channel[1]);
2206     }
2207     _exit(run_list_real(head)); /* leaks memory */
2208     }
2209     debug_printf("forked child %d\n",pid);
2210     close(channel[1]);
2211     pf = fdopen(channel[0],"r");
2212     debug_printf("pipe on FILE *%p\n",pf);
2213     return pf;
2214     }
2215    
2216     /* this version hacked for testing purposes */
2217     /* return code is exit status of the process that is run. */
2218     static int process_command_subs(o_string *dest, struct p_context *ctx, struct in_str *input, int subst_end)
2219     {
2220     int retcode;
2221     o_string result=NULL_O_STRING;
2222     struct p_context inner;
2223     FILE *p;
2224     struct in_str pipe_str;
2225     initialize_context(&inner);
2226    
2227     /* recursion to generate command */
2228     retcode = parse_stream(&result, &inner, input, subst_end);
2229     if (retcode != 0) return retcode; /* syntax error or EOF */
2230     done_word(&result, &inner);
2231     done_pipe(&inner, PIPE_SEQ);
2232     b_free(&result);
2233    
2234     p=generate_stream_from_list(inner.list_head);
2235     if (p==NULL) return 1;
2236     mark_open(fileno(p));
2237     setup_file_in_str(&pipe_str, p);
2238    
2239     /* now send results of command back into original context */
2240     retcode = parse_stream(dest, ctx, &pipe_str, '\0');
2241     /* XXX In case of a syntax error, should we try to kill the child?
2242     * That would be tough to do right, so just read until EOF. */
2243     if (retcode == 1) {
2244     while (b_getch(&pipe_str)!=EOF) { /* discard */ };
2245     }
2246    
2247     debug_printf("done reading from pipe, pclose()ing\n");
2248     /* This is the step that wait()s for the child. Should be pretty
2249     * safe, since we just read an EOF from its stdout. We could try
2250     * to better, by using wait(), and keeping track of background jobs
2251     * at the same time. That would be a lot of work, and contrary
2252     * to the KISS philosophy of this program. */
2253     mark_closed(fileno(p));
2254     retcode=pclose(p);
2255     free_pipe_list(inner.list_head,0);
2256     debug_printf("pclosed, retcode=%d\n",retcode);
2257     /* XXX this process fails to trim a single trailing newline */
2258     return retcode;
2259     }
2260    
2261     static int parse_group(o_string *dest, struct p_context *ctx,
2262     struct in_str *input, int ch)
2263     {
2264     int rcode, endch=0;
2265     struct p_context sub;
2266     struct child_prog *child = ctx->child;
2267     if (child->argv) {
2268     syntax();
2269     return 1; /* syntax error, groups and arglists don't mix */
2270     }
2271     initialize_context(&sub);
2272     switch (ch) {
2273     case '(': endch=')'; child->subshell=1; break;
2274     case '{': endch='}'; break;
2275     default: syntax(); /* really logic error */
2276     }
2277     rcode=parse_stream(dest,&sub,input,endch);
2278     done_word(dest,&sub); /* finish off the final word in the subcontext */
2279     done_pipe(&sub, PIPE_SEQ); /* and the final command there, too */
2280     child->group = sub.list_head;
2281     return rcode;
2282     /* child remains "open", available for possible redirects */
2283     }
2284    
2285     /* basically useful version until someone wants to get fancier,
2286     * see the bash man page under "Parameter Expansion" */
2287     static char *lookup_param(char *src)
2288     {
2289     char *p=NULL;
2290     if (src) {
2291     p = getenv(src);
2292     if (!p)
2293     p = get_local_var(src);
2294     }
2295     return p;
2296     }
2297    
2298     /* return code: 0 for OK, 1 for syntax error */
2299     static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *input)
2300     {
2301     int i, advance=0;
2302     char sep[]=" ";
2303     int ch = input->peek(input); /* first character after the $ */
2304     debug_printf("handle_dollar: ch=%c\n",ch);
2305     if (isalpha(ch)) {
2306     b_addchr(dest, SPECIAL_VAR_SYMBOL);
2307     ctx->child->sp++;
2308     while(ch=b_peek(input),isalnum(ch) || ch=='_') {
2309     b_getch(input);
2310     b_addchr(dest,ch);
2311     }
2312     b_addchr(dest, SPECIAL_VAR_SYMBOL);
2313     } else if (isdigit(ch)) {
2314     i = ch-'0'; /* XXX is $0 special? */
2315     if (i<global_argc) {
2316     parse_string(dest, ctx, global_argv[i]); /* recursion */
2317     }
2318     advance = 1;
2319     } else switch (ch) {
2320     case '$':
2321     b_adduint(dest,getpid());
2322     advance = 1;
2323     break;
2324     case '!':
2325     if (last_bg_pid > 0) b_adduint(dest, last_bg_pid);
2326     advance = 1;
2327     break;
2328     case '?':
2329     b_adduint(dest,last_return_code);
2330     advance = 1;
2331     break;
2332     case '#':
2333     b_adduint(dest,global_argc ? global_argc-1 : 0);
2334     advance = 1;
2335     break;
2336     case '{':
2337     b_addchr(dest, SPECIAL_VAR_SYMBOL);
2338     ctx->child->sp++;
2339     b_getch(input);
2340     /* XXX maybe someone will try to escape the '}' */
2341     while(ch=b_getch(input),ch!=EOF && ch!='}') {
2342     b_addchr(dest,ch);
2343     }
2344     if (ch != '}') {
2345     syntax();
2346     return 1;
2347     }
2348     b_addchr(dest, SPECIAL_VAR_SYMBOL);
2349     break;
2350     case '(':
2351     b_getch(input);
2352     process_command_subs(dest, ctx, input, ')');
2353     break;
2354     case '*':
2355     sep[0]=ifs[0];
2356     for (i=1; i<global_argc; i++) {
2357     parse_string(dest, ctx, global_argv[i]);
2358     if (i+1 < global_argc) parse_string(dest, ctx, sep);
2359     }
2360     break;
2361     case '@':
2362     case '-':
2363     case '_':
2364     /* still unhandled, but should be eventually */
2365     bb_error_msg("unhandled syntax: $%c",ch);
2366     return 1;
2367     break;
2368     default:
2369     b_addqchr(dest,'$',dest->quote);
2370     }
2371     /* Eat the character if the flag was set. If the compiler
2372     * is smart enough, we could substitute "b_getch(input);"
2373     * for all the "advance = 1;" above, and also end up with
2374     * a nice size-optimized program. Hah! That'll be the day.
2375     */
2376     if (advance) b_getch(input);
2377     return 0;
2378     }
2379    
2380     int parse_string(o_string *dest, struct p_context *ctx, const char *src)
2381     {
2382     struct in_str foo;
2383     setup_string_in_str(&foo, src);
2384     return parse_stream(dest, ctx, &foo, '\0');
2385     }
2386    
2387     /* return code is 0 for normal exit, 1 for syntax error */
2388     int parse_stream(o_string *dest, struct p_context *ctx,
2389     struct in_str *input, int end_trigger)
2390     {
2391     int ch, m;
2392     int redir_fd;
2393     redir_type redir_style;
2394     int next;
2395    
2396     /* Only double-quote state is handled in the state variable dest->quote.
2397     * A single-quote triggers a bypass of the main loop until its mate is
2398     * found. When recursing, quote state is passed in via dest->quote. */
2399    
2400     debug_printf("parse_stream, end_trigger=%d\n",end_trigger);
2401     while ((ch=b_getch(input))!=EOF) {
2402     m = map[ch];
2403     next = (ch == '\n') ? 0 : b_peek(input);
2404     debug_printf("parse_stream: ch=%c (%d) m=%d quote=%d\n",
2405     ch,ch,m,dest->quote);
2406     if (m==0 || ((m==1 || m==2) && dest->quote)) {
2407     b_addqchr(dest, ch, dest->quote);
2408     } else {
2409     if (m==2) { /* unquoted IFS */
2410     if (done_word(dest, ctx)) {
2411     return 1;
2412     }
2413     /* If we aren't performing a substitution, treat a newline as a
2414     * command separator. */
2415     if (end_trigger != '\0' && ch=='\n')
2416     done_pipe(ctx,PIPE_SEQ);
2417     }
2418     if (ch == end_trigger && !dest->quote && ctx->w==RES_NONE) {
2419     debug_printf("leaving parse_stream (triggered)\n");
2420     return 0;
2421     }
2422     if (m!=2) switch (ch) {
2423     case '#':
2424     if (dest->length == 0 && !dest->quote) {
2425     while(ch=b_peek(input),ch!=EOF && ch!='\n') { b_getch(input); }
2426     } else {
2427     b_addqchr(dest, ch, dest->quote);
2428     }
2429     break;
2430     case '\\':
2431     if (next == EOF) {
2432     syntax();
2433     return 1;
2434     }
2435     b_addqchr(dest, '\\', dest->quote);
2436     b_addqchr(dest, b_getch(input), dest->quote);
2437     break;
2438     case '$':
2439     if (handle_dollar(dest, ctx, input)!=0) return 1;
2440     break;
2441     case '\'':
2442     dest->nonnull = 1;
2443     while(ch=b_getch(input),ch!=EOF && ch!='\'') {
2444     b_addchr(dest,ch);
2445     }
2446     if (ch==EOF) {
2447     syntax();
2448     return 1;
2449     }
2450     break;
2451     case '"':
2452     dest->nonnull = 1;
2453     dest->quote = !dest->quote;
2454     break;
2455     case '`':
2456     process_command_subs(dest, ctx, input, '`');
2457     break;
2458     case '>':
2459     redir_fd = redirect_opt_num(dest);
2460     done_word(dest, ctx);
2461     redir_style=REDIRECT_OVERWRITE;
2462     if (next == '>') {
2463     redir_style=REDIRECT_APPEND;
2464     b_getch(input);
2465     } else if (next == '(') {
2466     syntax(); /* until we support >(list) Process Substitution */
2467     return 1;
2468     }
2469     setup_redirect(ctx, redir_fd, redir_style, input);
2470     break;
2471     case '<':
2472     redir_fd = redirect_opt_num(dest);
2473     done_word(dest, ctx);
2474     redir_style=REDIRECT_INPUT;
2475     if (next == '<') {
2476     redir_style=REDIRECT_HEREIS;
2477     b_getch(input);
2478     } else if (next == '>') {
2479     redir_style=REDIRECT_IO;
2480     b_getch(input);
2481     } else if (next == '(') {
2482     syntax(); /* until we support <(list) Process Substitution */
2483     return 1;
2484     }
2485     setup_redirect(ctx, redir_fd, redir_style, input);
2486     break;
2487     case ';':
2488     done_word(dest, ctx);
2489     done_pipe(ctx,PIPE_SEQ);
2490     break;
2491     case '&':
2492     done_word(dest, ctx);
2493     if (next=='&') {
2494     b_getch(input);
2495     done_pipe(ctx,PIPE_AND);
2496     } else {
2497     done_pipe(ctx,PIPE_BG);
2498     }
2499     break;
2500     case '|':
2501     done_word(dest, ctx);
2502     if (next=='|') {
2503     b_getch(input);
2504     done_pipe(ctx,PIPE_OR);
2505     } else {
2506     /* we could pick up a file descriptor choice here
2507     * with redirect_opt_num(), but bash doesn't do it.
2508     * "echo foo 2| cat" yields "foo 2". */
2509     done_command(ctx);
2510     }
2511     break;
2512     case '(':
2513     case '{':
2514     if (parse_group(dest, ctx, input, ch)!=0) return 1;
2515     break;
2516     case ')':
2517     case '}':
2518     syntax(); /* Proper use of this character caught by end_trigger */
2519     return 1;
2520     break;
2521     default:
2522     syntax(); /* this is really an internal logic error */
2523     return 1;
2524     }
2525     }
2526     }
2527     /* complain if quote? No, maybe we just finished a command substitution
2528     * that was quoted. Example:
2529     * $ echo "`cat foo` plus more"
2530     * and we just got the EOF generated by the subshell that ran "cat foo"
2531     * The only real complaint is if we got an EOF when end_trigger != '\0',
2532     * that is, we were really supposed to get end_trigger, and never got
2533     * one before the EOF. Can't use the standard "syntax error" return code,
2534     * so that parse_stream_outer can distinguish the EOF and exit smoothly. */
2535     debug_printf("leaving parse_stream (EOF)\n");
2536     if (end_trigger != '\0') return -1;
2537     return 0;
2538     }
2539    
2540     static void mapset(const char *set, int code)
2541     {
2542     const unsigned char *s;
2543     for (s = (const unsigned char *)set; *s; s++) map[(int)*s] = code;
2544     }
2545    
2546     static void update_ifs_map(void)
2547     {
2548     /* char *ifs and char map[256] are both globals. */
2549     ifs = getenv("IFS");
2550     if (ifs == NULL) ifs=" \t\n";
2551     /* Precompute a list of 'flow through' behavior so it can be treated
2552     * quickly up front. Computation is necessary because of IFS.
2553     * Special case handling of IFS == " \t\n" is not implemented.
2554     * The map[] array only really needs two bits each, and on most machines
2555     * that would be faster because of the reduced L1 cache footprint.
2556     */
2557     memset(map,0,sizeof(map)); /* most characters flow through always */
2558     mapset("\\$'\"`", 3); /* never flow through */
2559     mapset("<>;&|(){}#", 1); /* flow through if quoted */
2560     mapset(ifs, 2); /* also flow through if quoted */
2561     }
2562    
2563     /* most recursion does not come through here, the exception is
2564     * from builtin_source() */
2565     int parse_stream_outer(struct in_str *inp, int flag)
2566     {
2567    
2568     struct p_context ctx;
2569     o_string temp=NULL_O_STRING;
2570     int rcode;
2571     do {
2572     ctx.type = flag;
2573     initialize_context(&ctx);
2574     update_ifs_map();
2575     if (!(flag & FLAG_PARSE_SEMICOLON) || (flag & FLAG_REPARSING)) mapset(";$&|", 0);
2576     inp->promptmode=1;
2577     rcode = parse_stream(&temp, &ctx, inp, '\n');
2578     if (rcode != 1 && ctx.old_flag != 0) {
2579     syntax();
2580     }
2581     if (rcode != 1 && ctx.old_flag == 0) {
2582     done_word(&temp, &ctx);
2583     done_pipe(&ctx,PIPE_SEQ);
2584     run_list(ctx.list_head);
2585     } else {
2586     if (ctx.old_flag != 0) {
2587     free(ctx.stack);
2588     b_reset(&temp);
2589     }
2590     temp.nonnull = 0;
2591     temp.quote = 0;
2592     inp->p = NULL;
2593     free_pipe_list(ctx.list_head,0);
2594     }
2595     b_free(&temp);
2596     } while (rcode != -1 && !(flag & FLAG_EXIT_FROM_LOOP)); /* loop on syntax errors, return on EOF */
2597     return 0;
2598     }
2599    
2600     static int parse_string_outer(const char *s, int flag)
2601     {
2602     struct in_str input;
2603     setup_string_in_str(&input, s);
2604     return parse_stream_outer(&input, flag);
2605     }
2606    
2607     static int parse_file_outer(FILE *f)
2608     {
2609     int rcode;
2610     struct in_str input;
2611     setup_file_in_str(&input, f);
2612     rcode = parse_stream_outer(&input, FLAG_PARSE_SEMICOLON);
2613     return rcode;
2614     }
2615    
2616     /* Make sure we have a controlling tty. If we get started under a job
2617     * aware app (like bash for example), make sure we are now in charge so
2618     * we don't fight over who gets the foreground */
2619     static void setup_job_control(void)
2620     {
2621     static pid_t shell_pgrp;
2622     /* Loop until we are in the foreground. */
2623     while (tcgetpgrp (shell_terminal) != (shell_pgrp = getpgrp ()))
2624     kill (- shell_pgrp, SIGTTIN);
2625    
2626     /* Ignore interactive and job-control signals. */
2627     signal(SIGINT, SIG_IGN);
2628     signal(SIGQUIT, SIG_IGN);
2629     signal(SIGTERM, SIG_IGN);
2630     signal(SIGTSTP, SIG_IGN);
2631     signal(SIGTTIN, SIG_IGN);
2632     signal(SIGTTOU, SIG_IGN);
2633     signal(SIGCHLD, SIG_IGN);
2634    
2635     /* Put ourselves in our own process group. */
2636     setsid();
2637     shell_pgrp = getpid();
2638     setpgid(shell_pgrp, shell_pgrp);
2639    
2640     /* Grab control of the terminal. */
2641     tcsetpgrp(shell_terminal, shell_pgrp);
2642     }
2643    
2644     int hush_main(int argc, char **argv)
2645     {
2646     int opt;
2647     FILE *input;
2648     char **e = environ;
2649    
2650     /* XXX what should these be while sourcing /etc/profile? */
2651     global_argc = argc;
2652     global_argv = argv;
2653    
2654     /* (re?) initialize globals. Sometimes hush_main() ends up calling
2655     * hush_main(), therefore we cannot rely on the BSS to zero out this
2656     * stuff. Reset these to 0 every time. */
2657     ifs = NULL;
2658     /* map[] is taken care of with call to update_ifs_map() */
2659     fake_mode = 0;
2660     interactive = 0;
2661     close_me_head = NULL;
2662     last_bg_pid = 0;
2663     job_list = NULL;
2664     last_jobid = 0;
2665    
2666     /* Initialize some more globals to non-zero values */
2667     set_cwd();
2668     if (ENABLE_FEATURE_COMMAND_EDITING) cmdedit_set_initial_prompt();
2669     else PS1 = NULL;
2670     PS2 = "> ";
2671    
2672     /* initialize our shell local variables with the values
2673     * currently living in the environment */
2674     if (e) {
2675     for (; *e; e++)
2676     set_local_var(*e, 2); /* without call putenv() */
2677     }
2678    
2679     last_return_code=EXIT_SUCCESS;
2680    
2681    
2682     if (argv[0] && argv[0][0] == '-') {
2683     debug_printf("\nsourcing /etc/profile\n");
2684     if ((input = fopen("/etc/profile", "r")) != NULL) {
2685     mark_open(fileno(input));
2686     parse_file_outer(input);
2687     mark_closed(fileno(input));
2688     fclose(input);
2689     }
2690     }
2691     input=stdin;
2692    
2693     while ((opt = getopt(argc, argv, "c:xif")) > 0) {
2694     switch (opt) {
2695     case 'c':
2696     {
2697     global_argv = argv+optind;
2698     global_argc = argc-optind;
2699     opt = parse_string_outer(optarg, FLAG_PARSE_SEMICOLON);
2700     goto final_return;
2701     }
2702     break;
2703     case 'i':
2704     interactive++;
2705     break;
2706     case 'f':
2707     fake_mode++;
2708     break;
2709     default:
2710     #ifndef BB_VER
2711     fprintf(stderr, "Usage: sh [FILE]...\n"
2712     " or: sh -c command [args]...\n\n");
2713     exit(EXIT_FAILURE);
2714     #else
2715     bb_show_usage();
2716     #endif
2717     }
2718     }
2719     /* A shell is interactive if the `-i' flag was given, or if all of
2720     * the following conditions are met:
2721     * no -c command
2722     * no arguments remaining or the -s flag given
2723     * standard input is a terminal
2724     * standard output is a terminal
2725     * Refer to Posix.2, the description of the `sh' utility. */
2726     if (argv[optind]==NULL && input==stdin &&
2727     isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)) {
2728     interactive++;
2729     }
2730    
2731     debug_printf("\ninteractive=%d\n", interactive);
2732     if (interactive) {
2733     /* Looks like they want an interactive shell */
2734     #ifndef CONFIG_FEATURE_SH_EXTRA_QUIET
2735     printf( "\n\n%s hush - the humble shell v0.01 (testing)\n",
2736     BB_BANNER);
2737     printf( "Enter 'help' for a list of built-in commands.\n\n");
2738     #endif
2739     setup_job_control();
2740     }
2741    
2742     if (argv[optind]==NULL) {
2743     opt=parse_file_outer(stdin);
2744     goto final_return;
2745     }
2746    
2747     debug_printf("\nrunning script '%s'\n", argv[optind]);
2748     global_argv = argv+optind;
2749     global_argc = argc-optind;
2750     input = xfopen(argv[optind], "r");
2751     opt = parse_file_outer(input);
2752    
2753     #ifdef CONFIG_FEATURE_CLEAN_UP
2754     fclose(input);
2755     if (cwd && cwd != bb_msg_unknown)
2756     free((char*)cwd);
2757     {
2758     struct variables *cur, *tmp;
2759     for(cur = top_vars; cur; cur = tmp) {
2760     tmp = cur->next;
2761     if (!cur->flg_read_only) {
2762     free(cur->name);
2763     free(cur->value);
2764     free(cur);
2765     }
2766     }
2767     }
2768     #endif
2769    
2770     final_return:
2771     return opt ? opt : last_return_code;
2772     }
2773    
2774     static char *insert_var_value(char *inp)
2775     {
2776     int res_str_len = 0;
2777     int len;
2778     int done = 0;
2779     char *p, *p1, *res_str = NULL;
2780    
2781     while ((p = strchr(inp, SPECIAL_VAR_SYMBOL))) {
2782     if (p != inp) {
2783     len = p - inp;
2784     res_str = xrealloc(res_str, (res_str_len + len));
2785     strncpy((res_str + res_str_len), inp, len);
2786     res_str_len += len;
2787     }
2788     inp = ++p;
2789     p = strchr(inp, SPECIAL_VAR_SYMBOL);
2790     *p = '\0';
2791     if ((p1 = lookup_param(inp))) {
2792     len = res_str_len + strlen(p1);
2793     res_str = xrealloc(res_str, (1 + len));
2794     strcpy((res_str + res_str_len), p1);
2795     res_str_len = len;
2796     }
2797     *p = SPECIAL_VAR_SYMBOL;
2798     inp = ++p;
2799     done = 1;
2800     }
2801     if (done) {
2802     res_str = xrealloc(res_str, (1 + res_str_len + strlen(inp)));
2803     strcpy((res_str + res_str_len), inp);
2804     while ((p = strchr(res_str, '\n'))) {
2805     *p = ' ';
2806     }
2807     }
2808     return (res_str == NULL) ? inp : res_str;
2809     }
2810    
2811     static char **make_list_in(char **inp, char *name)
2812     {
2813     int len, i;
2814     int name_len = strlen(name);
2815     int n = 0;
2816     char **list;
2817     char *p1, *p2, *p3;
2818    
2819     /* create list of variable values */
2820     list = xmalloc(sizeof(*list));
2821     for (i = 0; inp[i]; i++) {
2822     p3 = insert_var_value(inp[i]);
2823     p1 = p3;
2824     while (*p1) {
2825     if ((*p1 == ' ')) {
2826     p1++;
2827     continue;
2828     }
2829     if ((p2 = strchr(p1, ' '))) {
2830     len = p2 - p1;
2831     } else {
2832     len = strlen(p1);
2833     p2 = p1 + len;
2834     }
2835     /* we use n + 2 in realloc for list,because we add
2836     * new element and then we will add NULL element */
2837     list = xrealloc(list, sizeof(*list) * (n + 2));
2838     list[n] = xmalloc(2 + name_len + len);
2839     strcpy(list[n], name);
2840     strcat(list[n], "=");
2841     strncat(list[n], p1, len);
2842     list[n++][name_len + len + 1] = '\0';
2843     p1 = p2;
2844     }
2845     if (p3 != inp[i]) free(p3);
2846     }
2847     list[n] = NULL;
2848     return list;
2849     }
2850    
2851     /* Make new string for parser */
2852     static char * make_string(char ** inp)
2853     {
2854     char *p;
2855     char *str = NULL;
2856     int n;
2857     int len = 2;
2858    
2859     for (n = 0; inp[n]; n++) {
2860     p = insert_var_value(inp[n]);
2861     str = xrealloc(str, (len + strlen(p)));
2862     if (n) {
2863     strcat(str, " ");
2864     } else {
2865     *str = '\0';
2866     }
2867     strcat(str, p);
2868     len = strlen(str) + 3;
2869     if (p != inp[n]) free(p);
2870     }
2871     len = strlen(str);
2872     *(str + len) = '\n';
2873     *(str + len + 1) = '\0';
2874     return str;
2875     }