hush: randomconfig fixes
[oweals/busybox.git] / shell / hush.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * 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  *      o_addchr() derived from similar w_addchar function in glibc-2.2.
24  *      setup_redirect(), redirect_opt_num(), and big chunks of main()
25  *      and many builtins derived from contributions by Erik Andersen.
26  *      Miscellaneous bugfixes from Matt Kraai.
27  *
28  * There are two big (and related) architecture differences between
29  * this parser and the lash parser.  One is that this version is
30  * actually designed from the ground up to understand nearly all
31  * of the Bourne grammar.  The second, consequential change is that
32  * the parser and input reader have been turned inside out.  Now,
33  * the parser is in control, and asks for input as needed.  The old
34  * way had the input reader in control, and it asked for parsing to
35  * take place as needed.  The new way makes it much easier to properly
36  * handle the recursion implicit in the various substitutions, especially
37  * across continuation lines.
38  *
39  * POSIX syntax not implemented:
40  *      aliases
41  *      <(list) and >(list) Process Substitution
42  *      Here Documents ( << word )
43  *      Functions
44  *      Tilde Expansion
45  *      Parameter Expansion for substring processing ${var#word} ${var%word}
46  *
47  * Bash stuff maybe optional enable:
48  *      &> and >& redirection of stdout+stderr
49  *      Brace expansion
50  *      reserved words: [[ ]] function select
51  *      substrings ${var:1:5}
52  *
53  * Major bugs:
54  *      job handling woefully incomplete and buggy (improved --vda)
55  * to-do:
56  *      port selected bugfixes from post-0.49 busybox lash - done?
57  *      change { and } from special chars to reserved words
58  *      builtins: return, trap, ulimit
59  *      test magic exec with redirection only
60  *      follow IFS rules more precisely, including update semantics
61  *      figure out what to do with backslash-newline
62  *      propagate syntax errors, die on resource errors?
63  *      continuation lines, both explicit and implicit - done?
64  *      maybe change charmap[] to use 2-bit entries
65  *
66  * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
67  */
68
69 #include "busybox.h" /* for APPLET_IS_NOFORK/NOEXEC */
70 //TODO: pull in some .h and find out whether we have SINGLE_APPLET_MAIN?
71 //#include "applet_tables.h" doesn't work
72 #include <glob.h>
73 /* #include <dmalloc.h> */
74 #if ENABLE_HUSH_CASE
75 #include <fnmatch.h>
76 #endif
77
78 #include "math.h"
79
80 #define HUSH_VER_STR "0.92"
81
82 #if defined SINGLE_APPLET_MAIN
83 /* STANDALONE does not make sense, and won't compile */
84 #undef CONFIG_FEATURE_SH_STANDALONE
85 #undef ENABLE_FEATURE_SH_STANDALONE
86 #undef USE_FEATURE_SH_STANDALONE
87 #define SKIP_FEATURE_SH_STANDALONE(...) __VA_ARGS__
88 #define ENABLE_FEATURE_SH_STANDALONE 0
89 #define USE_FEATURE_SH_STANDALONE(...)
90 #define SKIP_FEATURE_SH_STANDALONE(...) __VA_ARGS__
91 #endif
92
93 #if !BB_MMU && ENABLE_HUSH_TICK
94 //#undef ENABLE_HUSH_TICK
95 //#define ENABLE_HUSH_TICK 0
96 #warning On NOMMU, hush command substitution is dangerous.
97 #warning Dont use it for commands which produce lots of output.
98 #warning For more info see shell/hush.c, generate_stream_from_list().
99 #endif
100
101 #if !ENABLE_HUSH_INTERACTIVE
102 #undef ENABLE_FEATURE_EDITING
103 #define ENABLE_FEATURE_EDITING 0
104 #undef ENABLE_FEATURE_EDITING_FANCY_PROMPT
105 #define ENABLE_FEATURE_EDITING_FANCY_PROMPT 0
106 #endif
107
108 /* Do we support ANY keywords? */
109 #if ENABLE_HUSH_IF || ENABLE_HUSH_LOOPS || ENABLE_HUSH_CASE
110 #define HAS_KEYWORDS 1
111 #define IF_HAS_KEYWORDS(...) __VA_ARGS__
112 #define IF_HAS_NO_KEYWORDS(...)
113 #else
114 #define HAS_KEYWORDS 0
115 #define IF_HAS_KEYWORDS(...)
116 #define IF_HAS_NO_KEYWORDS(...) __VA_ARGS__
117 #endif
118
119 /* Keep unconditionally on for now */
120 #define HUSH_DEBUG 1
121 /* In progress... */
122 #define ENABLE_HUSH_FUNCTIONS 0
123
124
125 /* If you comment out one of these below, it will be #defined later
126  * to perform debug printfs to stderr: */
127 #define debug_printf(...)        do {} while (0)
128 /* Finer-grained debug switches */
129 #define debug_printf_parse(...)  do {} while (0)
130 #define debug_print_tree(a, b)   do {} while (0)
131 #define debug_printf_exec(...)   do {} while (0)
132 #define debug_printf_env(...)    do {} while (0)
133 #define debug_printf_jobs(...)   do {} while (0)
134 #define debug_printf_expand(...) do {} while (0)
135 #define debug_printf_glob(...)   do {} while (0)
136 #define debug_printf_list(...)   do {} while (0)
137 #define debug_printf_subst(...)  do {} while (0)
138 #define debug_printf_clean(...)  do {} while (0)
139
140 #ifndef debug_printf
141 #define debug_printf(...) fprintf(stderr, __VA_ARGS__)
142 #endif
143
144 #ifndef debug_printf_parse
145 #define debug_printf_parse(...) fprintf(stderr, __VA_ARGS__)
146 #endif
147
148 #ifndef debug_printf_exec
149 #define debug_printf_exec(...) fprintf(stderr, __VA_ARGS__)
150 #endif
151
152 #ifndef debug_printf_env
153 #define debug_printf_env(...) fprintf(stderr, __VA_ARGS__)
154 #endif
155
156 #ifndef debug_printf_jobs
157 #define debug_printf_jobs(...) fprintf(stderr, __VA_ARGS__)
158 #define DEBUG_JOBS 1
159 #else
160 #define DEBUG_JOBS 0
161 #endif
162
163 #ifndef debug_printf_expand
164 #define debug_printf_expand(...) fprintf(stderr, __VA_ARGS__)
165 #define DEBUG_EXPAND 1
166 #else
167 #define DEBUG_EXPAND 0
168 #endif
169
170 #ifndef debug_printf_glob
171 #define debug_printf_glob(...) fprintf(stderr, __VA_ARGS__)
172 #define DEBUG_GLOB 1
173 #else
174 #define DEBUG_GLOB 0
175 #endif
176
177 #ifndef debug_printf_list
178 #define debug_printf_list(...) fprintf(stderr, __VA_ARGS__)
179 #endif
180
181 #ifndef debug_printf_subst
182 #define debug_printf_subst(...) fprintf(stderr, __VA_ARGS__)
183 #endif
184
185 #ifndef debug_printf_clean
186 /* broken, of course, but OK for testing */
187 static const char *indenter(int i)
188 {
189         static const char blanks[] ALIGN1 =
190                 "                                    ";
191         return &blanks[sizeof(blanks) - i - 1];
192 }
193 #define debug_printf_clean(...) fprintf(stderr, __VA_ARGS__)
194 #define DEBUG_CLEAN 1
195 #endif
196
197 #if DEBUG_EXPAND
198 static void debug_print_strings(const char *prefix, char **vv)
199 {
200         fprintf(stderr, "%s:\n", prefix);
201         while (*vv)
202                 fprintf(stderr, " '%s'\n", *vv++);
203 }
204 #else
205 #define debug_print_strings(prefix, vv) ((void)0)
206 #endif
207
208 /*
209  * Leak hunting. Use hush_leaktool.sh for post-processing.
210  */
211 #ifdef FOR_HUSH_LEAKTOOL
212 /* suppress "warning: no previous prototype..." */
213 void *xxmalloc(int lineno, size_t size);
214 void *xxrealloc(int lineno, void *ptr, size_t size);
215 char *xxstrdup(int lineno, const char *str);
216 void xxfree(void *ptr);
217 void *xxmalloc(int lineno, size_t size)
218 {
219         void *ptr = xmalloc((size + 0xff) & ~0xff);
220         fdprintf(2, "line %d: malloc %p\n", lineno, ptr);
221         return ptr;
222 }
223 void *xxrealloc(int lineno, void *ptr, size_t size)
224 {
225         ptr = xrealloc(ptr, (size + 0xff) & ~0xff);
226         fdprintf(2, "line %d: realloc %p\n", lineno, ptr);
227         return ptr;
228 }
229 char *xxstrdup(int lineno, const char *str)
230 {
231         char *ptr = xstrdup(str);
232         fdprintf(2, "line %d: strdup %p\n", lineno, ptr);
233         return ptr;
234 }
235 void xxfree(void *ptr)
236 {
237         fdprintf(2, "free %p\n", ptr);
238         free(ptr);
239 }
240 #define xmalloc(s)     xxmalloc(__LINE__, s)
241 #define xrealloc(p, s) xxrealloc(__LINE__, p, s)
242 #define xstrdup(s)     xxstrdup(__LINE__, s)
243 #define free(p)        xxfree(p)
244 #endif
245
246
247 #define ERR_PTR ((void*)(long)1)
248
249 static const char hush_version_str[] ALIGN1 = "HUSH_VERSION="HUSH_VER_STR;
250
251 #define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
252
253 #define SPECIAL_VAR_SYMBOL 3
254
255 typedef enum redir_type {
256         REDIRECT_INPUT     = 1,
257         REDIRECT_OVERWRITE = 2,
258         REDIRECT_APPEND    = 3,
259         REDIRECT_HEREIS    = 4,
260         REDIRECT_IO        = 5
261 } redir_type;
262
263 /* The descrip member of this structure is only used to make
264  * debugging output pretty */
265 static const struct {
266         int mode;
267         signed char default_fd;
268         char descrip[3];
269 } redir_table[] = {
270         { 0,                         0, "()" },
271         { O_RDONLY,                  0, "<"  },
272         { O_CREAT|O_TRUNC|O_WRONLY,  1, ">"  },
273         { O_CREAT|O_APPEND|O_WRONLY, 1, ">>" },
274         { O_RDONLY,                 -1, "<<" },
275         { O_RDWR,                    1, "<>" }
276 };
277
278 typedef enum pipe_style {
279         PIPE_SEQ = 1,
280         PIPE_AND = 2,
281         PIPE_OR  = 3,
282         PIPE_BG  = 4,
283 } pipe_style;
284
285 typedef enum reserved_style {
286         RES_NONE  = 0,
287 #if ENABLE_HUSH_IF
288         RES_IF    ,
289         RES_THEN  ,
290         RES_ELIF  ,
291         RES_ELSE  ,
292         RES_FI    ,
293 #endif
294 #if ENABLE_HUSH_LOOPS
295         RES_FOR   ,
296         RES_WHILE ,
297         RES_UNTIL ,
298         RES_DO    ,
299         RES_DONE  ,
300 #endif
301 #if ENABLE_HUSH_LOOPS || ENABLE_HUSH_CASE
302         RES_IN    ,
303 #endif
304 #if ENABLE_HUSH_CASE
305         RES_CASE  ,
306         /* two pseudo-keywords support contrived "case" syntax: */
307         RES_MATCH , /* "word)" */
308         RES_CASEI , /* "this command is inside CASE" */
309         RES_ESAC  ,
310 #endif
311         RES_XXXX  ,
312         RES_SNTX
313 } reserved_style;
314
315 struct redir_struct {
316         struct redir_struct *next;
317         char *rd_filename;          /* filename */
318         int fd;                     /* file descriptor being redirected */
319         int dup;                    /* -1, or file descriptor being duplicated */
320         smallint /*enum redir_type*/ rd_type;
321 };
322
323 struct command {
324         pid_t pid;                  /* 0 if exited */
325         int assignment_cnt;         /* how many argv[i] are assignments? */
326         smallint is_stopped;        /* is the command currently running? */
327         smallint grp_type;          /* GRP_xxx */
328         struct pipe *group;         /* if non-NULL, this "prog" is {} group,
329                                      * subshell, or a compound statement */
330         char **argv;                /* command name and arguments */
331         struct redir_struct *redirects; /* I/O redirections */
332 };
333 /* argv vector may contain variable references (^Cvar^C, ^C0^C etc)
334  * and on execution these are substituted with their values.
335  * Substitution can make _several_ words out of one argv[n]!
336  * Example: argv[0]=='.^C*^C.' here: echo .$*.
337  * References of the form ^C`cmd arg^C are `cmd arg` substitutions.
338  */
339 #define GRP_NORMAL   0
340 #define GRP_SUBSHELL 1
341 #if ENABLE_HUSH_FUNCTIONS
342 #define GRP_FUNCTION 2
343 #endif
344
345 struct pipe {
346         struct pipe *next;
347         int num_cmds;               /* total number of commands in job */
348         int alive_cmds;             /* number of commands running (not exited) */
349         int stopped_cmds;           /* number of commands alive, but stopped */
350 #if ENABLE_HUSH_JOB
351         int jobid;                  /* job number */
352         pid_t pgrp;                 /* process group ID for the job */
353         char *cmdtext;              /* name of job */
354 #endif
355         struct command *cmds;       /* array of commands in pipe */
356         smallint followup;          /* PIPE_BG, PIPE_SEQ, PIPE_OR, PIPE_AND */
357         IF_HAS_KEYWORDS(smallint pi_inverted;) /* "! cmd | cmd" */
358         IF_HAS_KEYWORDS(smallint res_word;) /* needed for if, for, while, until... */
359 };
360
361 /* This holds pointers to the various results of parsing */
362 struct parse_context {
363         /* linked list of pipes */
364         struct pipe *list_head;
365         /* last pipe (being constructed right now) */
366         struct pipe *pipe;
367         /* last command in pipe (being constructed right now) */
368         struct command *command;
369         /* last redirect in command->redirects list */
370         struct redir_struct *pending_redirect;
371 #if HAS_KEYWORDS
372         smallint ctx_res_w;
373         smallint ctx_inverted; /* "! cmd | cmd" */
374 #if ENABLE_HUSH_CASE
375         smallint ctx_dsemicolon; /* ";;" seen */
376 #endif
377         /* bitmask of FLAG_xxx, for figuring out valid reserved words */
378         int old_flag;
379         /* group we are enclosed in:
380          * example 1: "{ { false; ..."
381          * example 2: "if true; then { false; ..."
382          * example 3: "if true; then if false; ..."
383          * when we find closing "}" / "fi" / whatever, we move list_head
384          * into stack->command->group and delete ourself.
385          */
386         struct parse_context *stack;
387 #endif
388 };
389
390 /* On program start, environ points to initial environment.
391  * putenv adds new pointers into it, unsetenv removes them.
392  * Neither of these (de)allocates the strings.
393  * setenv allocates new strings in malloc space and does putenv,
394  * and thus setenv is unusable (leaky) for shell's purposes */
395 #define setenv(...) setenv_is_leaky_dont_use()
396 struct variable {
397         struct variable *next;
398         char *varstr;        /* points to "name=" portion */
399         int max_len;         /* if > 0, name is part of initial env; else name is malloced */
400         smallint flg_export; /* putenv should be done on this var */
401         smallint flg_read_only;
402 };
403
404 typedef struct o_string {
405         char *data;
406         int length; /* position where data is appended */
407         int maxlen;
408         /* Protect newly added chars against globbing
409          * (by prepending \ to *, ?, [, \) */
410         smallint o_escape;
411         smallint o_glob;
412         smallint nonnull;
413         smallint has_empty_slot;
414         smallint o_assignment; /* 0:maybe, 1:yes, 2:no */
415 } o_string;
416 enum {
417         MAYBE_ASSIGNMENT = 0,
418         DEFINITELY_ASSIGNMENT = 1,
419         NOT_ASSIGNMENT = 2,
420         WORD_IS_KEYWORD = 3, /* not assigment, but next word may be: "if v=xyz cmd;" */
421 };
422 /* Used for initialization: o_string foo = NULL_O_STRING; */
423 #define NULL_O_STRING { NULL }
424
425 /* I can almost use ordinary FILE*.  Is open_memstream() universally
426  * available?  Where is it documented? */
427 typedef struct in_str {
428         const char *p;
429         /* eof_flag=1: last char in ->p is really an EOF */
430         char eof_flag; /* meaningless if ->p == NULL */
431         char peek_buf[2];
432 #if ENABLE_HUSH_INTERACTIVE
433         smallint promptme;
434         smallint promptmode; /* 0: PS1, 1: PS2 */
435 #endif
436         FILE *file;
437         int (*get) (struct in_str *);
438         int (*peek) (struct in_str *);
439 } in_str;
440 #define i_getch(input) ((input)->get(input))
441 #define i_peek(input) ((input)->peek(input))
442
443 enum {
444         CHAR_ORDINARY           = 0,
445         CHAR_ORDINARY_IF_QUOTED = 1, /* example: *, # */
446         CHAR_IFS                = 2, /* treated as ordinary if quoted */
447         CHAR_SPECIAL            = 3, /* \, $, ", maybe ` */
448 };
449
450 enum {
451         BC_BREAK = 1,
452         BC_CONTINUE = 2,
453 };
454
455
456 /* "Globals" within this file */
457 /* Sorted roughly by size (smaller offsets == smaller code) */
458 struct globals {
459 #if ENABLE_HUSH_INTERACTIVE
460         /* 'interactive_fd' is a fd# open to ctty, if we have one
461          * _AND_ if we decided to act interactively */
462         int interactive_fd;
463         const char *PS1;
464         const char *PS2;
465 #define G_interactive_fd (G.interactive_fd)
466 #else
467 #define G_interactive_fd 0
468 #endif
469 #if ENABLE_FEATURE_EDITING
470         line_input_t *line_input_state;
471 #endif
472         pid_t root_pid;
473         pid_t last_bg_pid;
474 #if ENABLE_HUSH_JOB
475         int run_list_level;
476         pid_t saved_tty_pgrp;
477         int last_jobid;
478         struct pipe *job_list;
479         struct pipe *toplevel_list;
480 ////    smallint ctrl_z_flag;
481 #endif
482         smallint flag_SIGINT;
483 #if ENABLE_HUSH_LOOPS
484         smallint flag_break_continue;
485 #endif
486         smallint fake_mode;
487         /* These four support $?, $#, and $1 */
488         smalluint last_return_code;
489         /* is global_argv and global_argv[1..n] malloced? (note: not [0]) */
490         smalluint global_args_malloced;
491         /* how many non-NULL argv's we have. NB: $# + 1 */
492         int global_argc;
493         char **global_argv;
494 #if ENABLE_HUSH_LOOPS
495         unsigned depth_break_continue;
496         unsigned depth_of_loop;
497 #endif
498         const char *ifs;
499         const char *cwd;
500         struct variable *top_var; /* = &G.shell_ver (set in main()) */
501         struct variable shell_ver;
502 #if ENABLE_FEATURE_SH_STANDALONE
503         struct nofork_save_area nofork_save;
504 #endif
505 #if ENABLE_HUSH_JOB
506         sigjmp_buf toplevel_jb;
507 #endif
508         unsigned char charmap[256];
509         char user_input_buf[ENABLE_FEATURE_EDITING ? BUFSIZ : 2];
510         /* Signal and trap handling */
511 //      unsigned count_SIGCHLD;
512 //      unsigned handled_SIGCHLD;
513         /* which signals have non-DFL handler (even with no traps set)? */
514         unsigned non_DFL_mask;
515         char **traps; /* char *traps[NSIG] */
516         sigset_t blocked_set;
517         sigset_t inherited_set;
518 };
519 #define G (*ptr_to_globals)
520 /* Not #defining name to G.name - this quickly gets unwieldy
521  * (too many defines). Also, I actually prefer to see when a variable
522  * is global, thus "G." prefix is a useful hint */
523 #define INIT_G() do { \
524         SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
525 } while (0)
526
527
528 /* Function prototypes for builtins */
529 static int builtin_cd(char **argv);
530 static int builtin_echo(char **argv);
531 static int builtin_eval(char **argv);
532 static int builtin_exec(char **argv);
533 static int builtin_exit(char **argv);
534 static int builtin_export(char **argv);
535 #if ENABLE_HUSH_JOB
536 static int builtin_fg_bg(char **argv);
537 static int builtin_jobs(char **argv);
538 #endif
539 #if ENABLE_HUSH_HELP
540 static int builtin_help(char **argv);
541 #endif
542 static int builtin_pwd(char **argv);
543 static int builtin_read(char **argv);
544 static int builtin_test(char **argv);
545 static int builtin_trap(char **argv);
546 static int builtin_true(char **argv);
547 static int builtin_set(char **argv);
548 static int builtin_shift(char **argv);
549 static int builtin_source(char **argv);
550 static int builtin_umask(char **argv);
551 static int builtin_unset(char **argv);
552 static int builtin_wait(char **argv);
553 #if ENABLE_HUSH_LOOPS
554 static int builtin_break(char **argv);
555 static int builtin_continue(char **argv);
556 #endif
557 //static int builtin_not_written(char **argv);
558
559 /* Table of built-in functions.  They can be forked or not, depending on
560  * context: within pipes, they fork.  As simple commands, they do not.
561  * When used in non-forking context, they can change global variables
562  * in the parent shell process.  If forked, of course they cannot.
563  * For example, 'unset foo | whatever' will parse and run, but foo will
564  * still be set at the end. */
565 struct built_in_command {
566         const char *cmd;
567         int (*function)(char **argv);
568 #if ENABLE_HUSH_HELP
569         const char *descr;
570 #define BLTIN(cmd, func, help) { cmd, func, help }
571 #else
572 #define BLTIN(cmd, func, help) { cmd, func }
573 #endif
574 };
575
576 /* For now, echo and test are unconditionally enabled.
577  * Maybe make it configurable? */
578 static const struct built_in_command bltins[] = {
579         BLTIN("."     , builtin_source, "Run commands in a file"),
580         BLTIN(":"     , builtin_true, "No-op"),
581         BLTIN("["     , builtin_test, "Test condition"),
582 #if ENABLE_HUSH_JOB
583         BLTIN("bg"    , builtin_fg_bg, "Resume a job in the background"),
584 #endif
585 #if ENABLE_HUSH_LOOPS
586         BLTIN("break" , builtin_break, "Exit from a loop"),
587 #endif
588         BLTIN("cd"    , builtin_cd, "Change directory"),
589 #if ENABLE_HUSH_LOOPS
590         BLTIN("continue", builtin_continue, "Start new loop iteration"),
591 #endif
592         BLTIN("echo"  , builtin_echo, "Write to stdout"),
593         BLTIN("eval"  , builtin_eval, "Construct and run shell command"),
594         BLTIN("exec"  , builtin_exec, "Execute command, don't return to shell"),
595         BLTIN("exit"  , builtin_exit, "Exit"),
596         BLTIN("export", builtin_export, "Set environment variable"),
597 #if ENABLE_HUSH_JOB
598         BLTIN("fg"    , builtin_fg_bg, "Bring job into the foreground"),
599         BLTIN("jobs"  , builtin_jobs, "List active jobs"),
600 #endif
601         BLTIN("pwd"   , builtin_pwd, "Print current directory"),
602         BLTIN("read"  , builtin_read, "Input environment variable"),
603 //      BLTIN("return", builtin_not_written, "Return from a function"),
604         BLTIN("set"   , builtin_set, "Set/unset shell local variables"),
605         BLTIN("shift" , builtin_shift, "Shift positional parameters"),
606         BLTIN("test"  , builtin_test, "Test condition"),
607         BLTIN("trap"  , builtin_trap, "Trap signals"),
608 //      BLTIN("ulimit", builtin_not_written, "Control resource limits"),
609         BLTIN("umask" , builtin_umask, "Set file creation mask"),
610         BLTIN("unset" , builtin_unset, "Unset environment variable"),
611         BLTIN("wait"  , builtin_wait, "Wait for process"),
612 #if ENABLE_HUSH_HELP
613         BLTIN("help"  , builtin_help, "List shell built-in commands"),
614 #endif
615 };
616
617
618 /* Normal */
619 static void maybe_die(const char *notice, const char *msg)
620 {
621         /* Was using fancy stuff:
622          * (G_interactive_fd ? bb_error_msg : bb_error_msg_and_die)(...params...)
623          * but it SEGVs. ?! Oh well... explicit temp ptr works around that */
624         void FAST_FUNC (*fp)(const char *s, ...) = bb_error_msg_and_die;
625 #if ENABLE_HUSH_INTERACTIVE
626         fp = (G_interactive_fd ? bb_error_msg : bb_error_msg_and_die);
627 #endif
628         fp(msg ? "%s: %s" : notice, notice, msg);
629 }
630 #if 1
631 #define syntax(msg) maybe_die("syntax error", msg);
632 #else
633 /* Debug -- trick gcc to expand __LINE__ and convert to string */
634 #define __syntax(msg, line) maybe_die("syntax error hush.c:" # line, msg)
635 #define _syntax(msg, line) __syntax(msg, line)
636 #define syntax(msg) _syntax(msg, __LINE__)
637 #endif
638
639 static int glob_needed(const char *s)
640 {
641         while (*s) {
642                 if (*s == '\\')
643                         s++;
644                 if (*s == '*' || *s == '[' || *s == '?')
645                         return 1;
646                 s++;
647         }
648         return 0;
649 }
650
651 static int is_assignment(const char *s)
652 {
653         if (!s || !(isalpha(*s) || *s == '_'))
654                 return 0;
655         s++;
656         while (isalnum(*s) || *s == '_')
657                 s++;
658         return *s == '=';
659 }
660
661 /* Replace each \x with x in place, return ptr past NUL. */
662 static char *unbackslash(char *src)
663 {
664         char *dst = src;
665         while (1) {
666                 if (*src == '\\')
667                         src++;
668                 if ((*dst++ = *src++) == '\0')
669                         break;
670         }
671         return dst;
672 }
673
674 static char **add_strings_to_strings(char **strings, char **add, int need_to_dup)
675 {
676         int i;
677         unsigned count1;
678         unsigned count2;
679         char **v;
680
681         v = strings;
682         count1 = 0;
683         if (v) {
684                 while (*v) {
685                         count1++;
686                         v++;
687                 }
688         }
689         count2 = 0;
690         v = add;
691         while (*v) {
692                 count2++;
693                 v++;
694         }
695         v = xrealloc(strings, (count1 + count2 + 1) * sizeof(char*));
696         v[count1 + count2] = NULL;
697         i = count2;
698         while (--i >= 0)
699                 v[count1 + i] = (need_to_dup ? xstrdup(add[i]) : add[i]);
700         return v;
701 }
702
703 static char **add_string_to_strings(char **strings, char *add)
704 {
705         char *v[2];
706         v[0] = add;
707         v[1] = NULL;
708         return add_strings_to_strings(strings, v, /*dup:*/ 0);
709 }
710
711 static void putenv_all(char **strings)
712 {
713         if (!strings)
714                 return;
715         while (*strings) {
716                 debug_printf_env("putenv '%s'\n", *strings);
717                 putenv(*strings++);
718         }
719 }
720
721 static char **putenv_all_and_save_old(char **strings)
722 {
723         char **old = NULL;
724         char **s = strings;
725
726         if (!strings)
727                 return old;
728         while (*strings) {
729                 char *v, *eq;
730
731                 eq = strchr(*strings, '=');
732                 if (eq) {
733                         *eq = '\0';
734                         v = getenv(*strings);
735                         *eq = '=';
736                         if (v) {
737                                 /* v points to VAL in VAR=VAL, go back to VAR */
738                                 v -= (eq - *strings) + 1;
739                                 old = add_string_to_strings(old, v);
740                         }
741                 }
742                 strings++;
743         }
744         putenv_all(s);
745         return old;
746 }
747
748 static void free_strings_and_unsetenv(char **strings, int unset)
749 {
750         char **v;
751
752         if (!strings)
753                 return;
754
755         v = strings;
756         while (*v) {
757                 if (unset) {
758                         debug_printf_env("unsetenv '%s'\n", *v);
759                         bb_unsetenv(*v);
760                 }
761                 free(*v++);
762         }
763         free(strings);
764 }
765
766 static void free_strings(char **strings)
767 {
768         free_strings_and_unsetenv(strings, 0);
769 }
770
771
772 /* Basic theory of signal handling in shell
773  * ========================================
774  * This does not describe what hush does, rather, it is current understanding
775  * what it _should_ do. If it doesn't, it's a bug.
776  * http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#trap
777  *
778  * Signals are handled only after each pipe ("cmd | cmd | cmd" thing)
779  * is finished or backgrounded. It is the same in interactive and
780  * non-interactive shells, and is the same regardless of whether
781  * a user trap handler is installed or a shell special one is in effect.
782  * ^C or ^Z from keyboard seem to execute "at once" because it usually
783  * backgrounds (i.e. stops) or kills all members of currently running
784  * pipe.
785  *
786  * Wait builtin in interruptible by signals for which user trap is set
787  * or by SIGINT in interactive shell.
788  *
789  * Trap handlers will execute even within trap handlers. (right?)
790  *
791  * User trap handlers are forgotten when subshell ("(cmd)") is entered. [TODO]
792  *
793  * If job control is off, backgrounded commands ("cmd &")
794  * have SIGINT, SIGQUIT set to SIG_IGN.
795  *
796  * Commands run in command substitution ("`cmd`")
797  * have SIGTTIN, SIGTTOU, SIGTSTP set to SIG_IGN.
798  *
799  * Ordinary commands have signals set to SIG_IGN/DFL set as inherited
800  * by the shell from its parent.
801  *
802  * Siganls which differ from SIG_DFL action
803  * (note: child (i.e., [v]forked) shell is not an interactive shell):
804  *
805  * SIGQUIT: ignore
806  * SIGTERM (interactive): ignore
807  * SIGHUP (interactive):
808  *    send SIGCONT to stopped jobs, send SIGHUP to all jobs and exit
809  * SIGTTIN, SIGTTOU, SIGTSTP (if job control is on): ignore
810  *    (note that ^Z is handled not by trapping SIGTSTP, but by seeing
811  *    that all pipe members are stopped) (right?)
812  * SIGINT (interactive): wait for last pipe, ignore the rest
813  *    of the command line, show prompt. NB: ^C does not send SIGINT
814  *    to interactive shell while shell is waiting for a pipe,
815  *    since shell is bg'ed (is not in foreground process group).
816  *    (check/expand this)
817  *    Example 1: this waits 5 sec, but does not execute ls:
818  *    "echo $$; sleep 5; ls -l" + "kill -INT <pid>"
819  *    Example 2: this does not wait and does not execute ls:
820  *    "echo $$; sleep 5 & wait; ls -l" + "kill -INT <pid>"
821  *    Example 3: this does not wait 5 sec, but executes ls:
822  *    "sleep 5; ls -l" + press ^C
823  *
824  * (What happens to signals which are IGN on shell start?)
825  * (What happens with signal mask on shell start?)
826  *
827  * Implementation in hush
828  * ======================
829  * We use in-kernel pending signal mask to determine which signals were sent.
830  * We block all signals which we don't want to take action immediately,
831  * i.e. we block all signals which need to have special handling as described
832  * above, and all signals which have traps set.
833  * After each pipe execution, we extract any pending signals via sigtimedwait()
834  * and act on them.
835  *
836  * unsigned non_DFL_mask: a mask of such "special" signals
837  * sigset_t blocked_set:  current blocked signal set
838  *
839  * "trap - SIGxxx":
840  *    clear bit in blocked_set unless it is also in non_DFL
841  * "trap 'cmd' SIGxxx":
842  *    set bit in blocked_set (even if 'cmd' is '')
843  * after [v]fork, if we plan to be a shell:
844  *    nothing for {} child shell (say, "true | { true; true; } | true")
845  *    unset all traps if () shell. [TODO]
846  * after [v]fork, if we plan to exec:
847  *    POSIX says pending signal mask is cleared in child - no need to clear it.
848  *    Restore blocked signal set to one inherited by shell just prior to exec.
849  *
850  * Note: as a result, we do not use signal handlers much. The only uses
851  * are to count SIGCHLDs [disabled - bug somewhere, + bloat]
852  * and to restore tty pgrp on signal-induced exit.
853  *
854  * TODO: check/fix wait builtin to be interruptible.
855  */
856
857 //static void SIGCHLD_handler(int sig UNUSED_PARAM)
858 //{
859 //      G.count_SIGCHLD++;
860 //}
861
862 /* called once at shell init */
863 static void init_signal_mask(void)
864 {
865         unsigned sig;
866         unsigned mask = (1 << SIGQUIT);
867         if (G_interactive_fd) {
868                 mask = 0
869                         | (1 << SIGQUIT)
870                         | (1 << SIGTERM)
871                         | (1 << SIGHUP)
872 #if ENABLE_HUSH_JOB
873                         | (1 << SIGTTIN) | (1 << SIGTTOU) | (1 << SIGTSTP)
874 #endif
875                         | (1 << SIGINT)
876                 ;
877         }
878         G.non_DFL_mask = mask;
879
880         sigprocmask(SIG_SETMASK, NULL, &G.blocked_set);
881         sig = 0;
882         while (mask) {
883                 if (mask & 1)
884                         sigaddset(&G.blocked_set, sig);
885                 mask >>= 1;
886                 sig++;
887         }
888         sigdelset(&G.blocked_set, SIGCHLD);
889         sigprocmask(SIG_SETMASK, &G.blocked_set, &G.inherited_set);
890 }
891
892 static int check_and_run_traps(int sig)
893 {
894         static const struct timespec zero_timespec = { 0, 0 };
895         smalluint save_rcode;
896         int last_sig = 0;
897
898         if (sig)
899                 goto jump_in;
900         while (1) {
901                 sig = sigtimedwait(&G.blocked_set, NULL, &zero_timespec);
902                 if (sig <= 0)
903                         break;
904  jump_in:
905                 last_sig = sig;
906                 if (G.traps && G.traps[sig]) {
907                         if (G.traps[sig][0]) {
908                                 /* We have user-defined handler */
909                                 char *argv[] = { NULL, xstrdup(G.traps[sig]), NULL };
910                                 save_rcode = G.last_return_code;
911                                 builtin_eval(argv);
912                                 free(argv[1]);
913                                 G.last_return_code = save_rcode;
914                         } /* else: "" trap, ignoring signal */
915                         continue;
916                 }
917                 /* not a trap: special action */
918                 switch (sig) {
919 //              case SIGCHLD:
920 //                      G.count_SIGCHLD++;
921 //                      break;
922                 case SIGINT:
923                         bb_putchar('\n');
924                         G.flag_SIGINT = 1;
925                         break;
926 //TODO
927 //              case SIGHUP: ...
928 //                      break;
929                 default: /* SIGTERM, SIGQUIT, SIGTTIN, SIGTTOU, SIGTSTP */
930                         break;
931                 }
932         }
933         return last_sig;
934 }
935
936 #if ENABLE_HUSH_JOB
937
938 /* Restores tty foreground process group, and exits.
939  * May be called as signal handler for fatal signal
940  * (will faithfully resend signal to itself, producing correct exit state)
941  * or called directly with -EXITCODE.
942  * We also call it if xfunc is exiting. */
943 static void sigexit(int sig) NORETURN;
944 static void sigexit(int sig)
945 {
946         /* Disable all signals: job control, SIGPIPE, etc. */
947         sigprocmask_allsigs(SIG_BLOCK);
948
949         /* Careful: we can end up here after [v]fork. Do not restore
950          * tty pgrp then, only top-level shell process does that */
951         if (G_interactive_fd && getpid() == G.root_pid)
952                 tcsetpgrp(G_interactive_fd, G.saved_tty_pgrp);
953
954         /* Not a signal, just exit */
955         if (sig <= 0)
956                 _exit(- sig);
957
958         kill_myself_with_sig(sig); /* does not return */
959 }
960
961 /* helper */
962 static void maybe_set_sighandler(int sig)
963 {
964         void (*handler)(int);
965         /* non_DFL_mask'ed signals are, well, masked,
966          * no need to set handler for them.
967          */
968         if (!((G.non_DFL_mask >> sig) & 1)) {
969                 handler = signal(sig, sigexit);
970                 if (handler == SIG_IGN) /* oops... restore back to IGN! */
971                         signal(sig, handler);
972         }
973 }
974 /* Used only to set handler to restore pgrp on exit */
975 static void set_fatal_signals_to_sigexit(void)
976 {
977         if (HUSH_DEBUG) {
978                 maybe_set_sighandler(SIGILL );
979                 maybe_set_sighandler(SIGFPE );
980                 maybe_set_sighandler(SIGBUS );
981                 maybe_set_sighandler(SIGSEGV);
982                 maybe_set_sighandler(SIGTRAP);
983         } /* else: hush is perfect. what SEGV? */
984
985         maybe_set_sighandler(SIGABRT);
986
987         /* bash 3.2 seems to handle these just like 'fatal' ones */
988         maybe_set_sighandler(SIGPIPE);
989         maybe_set_sighandler(SIGALRM);
990         maybe_set_sighandler(SIGHUP );
991
992         /* if we aren't interactive... but in this case
993          * we never want to restore pgrp on exit, and this fn is not called */
994         /*maybe_set_sighandler(SIGTERM);*/
995         /*maybe_set_sighandler(SIGINT );*/
996 }
997 /* Used only to suppress ^Z in `cmd` */
998 static void set_jobctrl_signals_to_IGN(void)
999 {
1000         bb_signals(0
1001                 + (1 << SIGTSTP)
1002                 + (1 << SIGTTIN)
1003                 + (1 << SIGTTOU)
1004                 , SIG_IGN);
1005 }
1006
1007 #else /* !JOB */
1008
1009 #define set_fatal_signals_to_sigexit(handler) ((void)0)
1010 #define set_jobctrl_signals_to_IGN(handler)  ((void)0)
1011
1012 #endif /* JOB */
1013
1014 /* Restores tty foreground process group, and exits. */
1015 static void hush_exit(int exitcode) NORETURN;
1016 static void hush_exit(int exitcode)
1017 {
1018         if (G.traps && G.traps[0] && G.traps[0][0]) {
1019                 char *argv[] = { NULL, xstrdup(G.traps[0]), NULL };
1020                 builtin_eval(argv);
1021                 free(argv[1]);
1022         }
1023
1024 #if ENABLE_HUSH_JOB
1025         fflush(NULL); /* flush all streams */
1026         sigexit(- (exitcode & 0xff));
1027 #else
1028         exit(exitcode);
1029 #endif
1030 }
1031
1032
1033 static const char *set_cwd(void)
1034 {
1035         /* xrealloc_getcwd_or_warn(arg) calls free(arg),
1036          * we must not try to free(bb_msg_unknown) */
1037         if (G.cwd == bb_msg_unknown)
1038                 G.cwd = NULL;
1039         G.cwd = xrealloc_getcwd_or_warn((char *)G.cwd);
1040         if (!G.cwd)
1041                 G.cwd = bb_msg_unknown;
1042         return G.cwd;
1043 }
1044
1045
1046 /* Get/check local shell variables */
1047 static struct variable *get_local_var(const char *name)
1048 {
1049         struct variable *cur;
1050         int len;
1051
1052         if (!name)
1053                 return NULL;
1054         len = strlen(name);
1055         for (cur = G.top_var; cur; cur = cur->next) {
1056                 if (strncmp(cur->varstr, name, len) == 0 && cur->varstr[len] == '=')
1057                         return cur;
1058         }
1059         return NULL;
1060 }
1061
1062 /* Basically useful version until someone wants to get fancier,
1063  * see the bash man page under "Parameter Expansion" */
1064 static const char *lookup_param(const char *src)
1065 {
1066         struct variable *var = get_local_var(src);
1067         if (var)
1068                 return strchr(var->varstr, '=') + 1;
1069         return NULL;
1070 }
1071
1072 /* str holds "NAME=VAL" and is expected to be malloced.
1073  * We take ownership of it.
1074  * flg_export is used by:
1075  *  0: do not export
1076  *  1: export
1077  * -1: if NAME is set, leave export status alone
1078  *     if NAME is not set, do not export
1079  */
1080 static int set_local_var(char *str, int flg_export)
1081 {
1082         struct variable *cur;
1083         char *value;
1084         int name_len;
1085
1086         value = strchr(str, '=');
1087         if (!value) { /* not expected to ever happen? */
1088                 free(str);
1089                 return -1;
1090         }
1091
1092         name_len = value - str + 1; /* including '=' */
1093         cur = G.top_var; /* cannot be NULL (we have HUSH_VERSION and it's RO) */
1094         while (1) {
1095                 if (strncmp(cur->varstr, str, name_len) != 0) {
1096                         if (!cur->next) {
1097                                 /* Bail out. Note that now cur points
1098                                  * to last var in linked list */
1099                                 break;
1100                         }
1101                         cur = cur->next;
1102                         continue;
1103                 }
1104                 /* We found an existing var with this name */
1105                 *value = '\0';
1106                 if (cur->flg_read_only) {
1107                         bb_error_msg("%s: readonly variable", str);
1108                         free(str);
1109                         return -1;
1110                 }
1111                 debug_printf_env("%s: unsetenv '%s'\n", __func__, str);
1112                 unsetenv(str); /* just in case */
1113                 *value = '=';
1114                 if (strcmp(cur->varstr, str) == 0) {
1115  free_and_exp:
1116                         free(str);
1117                         goto exp;
1118                 }
1119                 if (cur->max_len >= strlen(str)) {
1120                         /* This one is from startup env, reuse space */
1121                         strcpy(cur->varstr, str);
1122                         goto free_and_exp;
1123                 }
1124                 /* max_len == 0 signifies "malloced" var, which we can
1125                  * (and has to) free */
1126                 if (!cur->max_len)
1127                         free(cur->varstr);
1128                 cur->max_len = 0;
1129                 goto set_str_and_exp;
1130         }
1131
1132         /* Not found - create next variable struct */
1133         cur->next = xzalloc(sizeof(*cur));
1134         cur = cur->next;
1135
1136  set_str_and_exp:
1137         cur->varstr = str;
1138  exp:
1139         if (flg_export == 1)
1140                 cur->flg_export = 1;
1141         if (cur->flg_export) {
1142                 debug_printf_env("%s: putenv '%s'\n", __func__, cur->varstr);
1143                 return putenv(cur->varstr);
1144         }
1145         return 0;
1146 }
1147
1148 static int unset_local_var(const char *name)
1149 {
1150         struct variable *cur;
1151         struct variable *prev = prev; /* for gcc */
1152         int name_len;
1153
1154         if (!name)
1155                 return EXIT_SUCCESS;
1156         name_len = strlen(name);
1157         cur = G.top_var;
1158         while (cur) {
1159                 if (strncmp(cur->varstr, name, name_len) == 0 && cur->varstr[name_len] == '=') {
1160                         if (cur->flg_read_only) {
1161                                 bb_error_msg("%s: readonly variable", name);
1162                                 return EXIT_FAILURE;
1163                         }
1164                         /* prev is ok to use here because 1st variable, HUSH_VERSION,
1165                          * is ro, and we cannot reach this code on the 1st pass */
1166                         prev->next = cur->next;
1167                         debug_printf_env("%s: unsetenv '%s'\n", __func__, cur->varstr);
1168                         bb_unsetenv(cur->varstr);
1169                         if (!cur->max_len)
1170                                 free(cur->varstr);
1171                         free(cur);
1172                         return EXIT_SUCCESS;
1173                 }
1174                 prev = cur;
1175                 cur = cur->next;
1176         }
1177         return EXIT_SUCCESS;
1178 }
1179
1180 #if ENABLE_SH_MATH_SUPPORT
1181 #define is_name(c)      ((c) == '_' || isalpha((unsigned char)(c)))
1182 #define is_in_name(c)   ((c) == '_' || isalnum((unsigned char)(c)))
1183 static char *endofname(const char *name)
1184 {
1185         char *p;
1186
1187         p = (char *) name;
1188         if (!is_name(*p))
1189                 return p;
1190         while (*++p) {
1191                 if (!is_in_name(*p))
1192                         break;
1193         }
1194         return p;
1195 }
1196
1197 static void arith_set_local_var(const char *name, const char *val, int flags)
1198 {
1199         /* arith code doesnt malloc space, so do it for it */
1200         char *var = xasprintf("%s=%s", name, val);
1201         set_local_var(var, flags);
1202 }
1203 #endif
1204
1205
1206 /*
1207  * in_str support
1208  */
1209 static int static_get(struct in_str *i)
1210 {
1211         int ch = *i->p++;
1212         if (ch != '\0')
1213                 return ch;
1214         i->p--;
1215         return EOF;
1216 }
1217
1218 static int static_peek(struct in_str *i)
1219 {
1220         return *i->p;
1221 }
1222
1223 #if ENABLE_HUSH_INTERACTIVE
1224
1225 static void cmdedit_set_initial_prompt(void)
1226 {
1227         if (ENABLE_FEATURE_EDITING_FANCY_PROMPT) {
1228                 G.PS1 = getenv("PS1");
1229                 if (G.PS1 == NULL)
1230                         G.PS1 = "\\w \\$ ";
1231         } else
1232                 G.PS1 = NULL;
1233 }
1234
1235 static const char* setup_prompt_string(int promptmode)
1236 {
1237         const char *prompt_str;
1238         debug_printf("setup_prompt_string %d ", promptmode);
1239         if (!ENABLE_FEATURE_EDITING_FANCY_PROMPT) {
1240                 /* Set up the prompt */
1241                 if (promptmode == 0) { /* PS1 */
1242                         free((char*)G.PS1);
1243                         G.PS1 = xasprintf("%s %c ", G.cwd, (geteuid() != 0) ? '$' : '#');
1244                         prompt_str = G.PS1;
1245                 } else
1246                         prompt_str = G.PS2;
1247         } else
1248                 prompt_str = (promptmode == 0) ? G.PS1 : G.PS2;
1249         debug_printf("result '%s'\n", prompt_str);
1250         return prompt_str;
1251 }
1252
1253 static void get_user_input(struct in_str *i)
1254 {
1255         int r;
1256         const char *prompt_str;
1257
1258         prompt_str = setup_prompt_string(i->promptmode);
1259 #if ENABLE_FEATURE_EDITING
1260         /* Enable command line editing only while a command line
1261          * is actually being read */
1262         do {
1263                 G.flag_SIGINT = 0;
1264                 /* buglet: SIGINT will not make new prompt to appear _at once_,
1265                  * only after <Enter>. (^C will work) */
1266                 r = read_line_input(prompt_str, G.user_input_buf, BUFSIZ-1, G.line_input_state);
1267                 /* catch *SIGINT* etc (^C is handled by read_line_input) */
1268                 check_and_run_traps(0);
1269         } while (r == 0 || G.flag_SIGINT); /* repeat if ^C or SIGINT */
1270         i->eof_flag = (r < 0);
1271         if (i->eof_flag) { /* EOF/error detected */
1272                 G.user_input_buf[0] = EOF; /* yes, it will be truncated, it's ok */
1273                 G.user_input_buf[1] = '\0';
1274         }
1275 #else
1276         do {
1277                 G.flag_SIGINT = 0;
1278                 fputs(prompt_str, stdout);
1279                 fflush(stdout);
1280                 G.user_input_buf[0] = r = fgetc(i->file);
1281                 /*G.user_input_buf[1] = '\0'; - already is and never changed */
1282 //do we need check_and_run_traps(0)? (maybe only if stdin)
1283         } while (G.flag_SIGINT);
1284         i->eof_flag = (r == EOF);
1285 #endif
1286         i->p = G.user_input_buf;
1287 }
1288
1289 #endif  /* INTERACTIVE */
1290
1291 /* This is the magic location that prints prompts
1292  * and gets data back from the user */
1293 static int file_get(struct in_str *i)
1294 {
1295         int ch;
1296
1297         /* If there is data waiting, eat it up */
1298         if (i->p && *i->p) {
1299 #if ENABLE_HUSH_INTERACTIVE
1300  take_cached:
1301 #endif
1302                 ch = *i->p++;
1303                 if (i->eof_flag && !*i->p)
1304                         ch = EOF;
1305         } else {
1306                 /* need to double check i->file because we might be doing something
1307                  * more complicated by now, like sourcing or substituting. */
1308 #if ENABLE_HUSH_INTERACTIVE
1309                 if (G_interactive_fd && i->promptme && i->file == stdin) {
1310                         do {
1311                                 get_user_input(i);
1312                         } while (!*i->p); /* need non-empty line */
1313                         i->promptmode = 1; /* PS2 */
1314                         i->promptme = 0;
1315                         goto take_cached;
1316                 }
1317 #endif
1318                 ch = fgetc(i->file);
1319         }
1320         debug_printf("file_get: got a '%c' %d\n", ch, ch);
1321 #if ENABLE_HUSH_INTERACTIVE
1322         if (ch == '\n')
1323                 i->promptme = 1;
1324 #endif
1325         return ch;
1326 }
1327
1328 /* All the callers guarantee this routine will never be
1329  * used right after a newline, so prompting is not needed.
1330  */
1331 static int file_peek(struct in_str *i)
1332 {
1333         int ch;
1334         if (i->p && *i->p) {
1335                 if (i->eof_flag && !i->p[1])
1336                         return EOF;
1337                 return *i->p;
1338         }
1339         ch = fgetc(i->file);
1340         i->eof_flag = (ch == EOF);
1341         i->peek_buf[0] = ch;
1342         i->peek_buf[1] = '\0';
1343         i->p = i->peek_buf;
1344         debug_printf("file_peek: got a '%c' %d\n", *i->p, *i->p);
1345         return ch;
1346 }
1347
1348 static void setup_file_in_str(struct in_str *i, FILE *f)
1349 {
1350         i->peek = file_peek;
1351         i->get = file_get;
1352 #if ENABLE_HUSH_INTERACTIVE
1353         i->promptme = 1;
1354         i->promptmode = 0; /* PS1 */
1355 #endif
1356         i->file = f;
1357         i->p = NULL;
1358 }
1359
1360 static void setup_string_in_str(struct in_str *i, const char *s)
1361 {
1362         i->peek = static_peek;
1363         i->get = static_get;
1364 #if ENABLE_HUSH_INTERACTIVE
1365         i->promptme = 1;
1366         i->promptmode = 0; /* PS1 */
1367 #endif
1368         i->p = s;
1369         i->eof_flag = 0;
1370 }
1371
1372
1373 /*
1374  * o_string support
1375  */
1376 #define B_CHUNK  (32 * sizeof(char*))
1377
1378 static void o_reset(o_string *o)
1379 {
1380         o->length = 0;
1381         o->nonnull = 0;
1382         if (o->data)
1383                 o->data[0] = '\0';
1384 }
1385
1386 static void o_free(o_string *o)
1387 {
1388         free(o->data);
1389         memset(o, 0, sizeof(*o));
1390 }
1391
1392 static void o_grow_by(o_string *o, int len)
1393 {
1394         if (o->length + len > o->maxlen) {
1395                 o->maxlen += (2*len > B_CHUNK ? 2*len : B_CHUNK);
1396                 o->data = xrealloc(o->data, 1 + o->maxlen);
1397         }
1398 }
1399
1400 static void o_addchr(o_string *o, int ch)
1401 {
1402         debug_printf("o_addchr: '%c' o->length=%d o=%p\n", ch, o->length, o);
1403         o_grow_by(o, 1);
1404         o->data[o->length] = ch;
1405         o->length++;
1406         o->data[o->length] = '\0';
1407 }
1408
1409 static void o_addstr(o_string *o, const char *str, int len)
1410 {
1411         o_grow_by(o, len);
1412         memcpy(&o->data[o->length], str, len);
1413         o->length += len;
1414         o->data[o->length] = '\0';
1415 }
1416
1417 static void o_addstrauto(o_string *o, const char *str)
1418 {
1419         o_addstr(o, str, strlen(str) + 1);
1420 }
1421
1422 static void o_addstr_duplicate_backslash(o_string *o, const char *str, int len)
1423 {
1424         while (len) {
1425                 o_addchr(o, *str);
1426                 if (*str++ == '\\'
1427                  && (*str != '*' && *str != '?' && *str != '[')
1428                 ) {
1429                         o_addchr(o, '\\');
1430                 }
1431                 len--;
1432         }
1433 }
1434
1435 /* My analysis of quoting semantics tells me that state information
1436  * is associated with a destination, not a source.
1437  */
1438 static void o_addqchr(o_string *o, int ch)
1439 {
1440         int sz = 1;
1441         char *found = strchr("*?[\\", ch);
1442         if (found)
1443                 sz++;
1444         o_grow_by(o, sz);
1445         if (found) {
1446                 o->data[o->length] = '\\';
1447                 o->length++;
1448         }
1449         o->data[o->length] = ch;
1450         o->length++;
1451         o->data[o->length] = '\0';
1452 }
1453
1454 static void o_addQchr(o_string *o, int ch)
1455 {
1456         int sz = 1;
1457         if (o->o_escape && strchr("*?[\\", ch)) {
1458                 sz++;
1459                 o->data[o->length] = '\\';
1460                 o->length++;
1461         }
1462         o_grow_by(o, sz);
1463         o->data[o->length] = ch;
1464         o->length++;
1465         o->data[o->length] = '\0';
1466 }
1467
1468 static void o_addQstr(o_string *o, const char *str, int len)
1469 {
1470         if (!o->o_escape) {
1471                 o_addstr(o, str, len);
1472                 return;
1473         }
1474         while (len) {
1475                 char ch;
1476                 int sz;
1477                 int ordinary_cnt = strcspn(str, "*?[\\");
1478                 if (ordinary_cnt > len) /* paranoia */
1479                         ordinary_cnt = len;
1480                 o_addstr(o, str, ordinary_cnt);
1481                 if (ordinary_cnt == len)
1482                         return;
1483                 str += ordinary_cnt;
1484                 len -= ordinary_cnt + 1; /* we are processing + 1 char below */
1485
1486                 ch = *str++;
1487                 sz = 1;
1488                 if (ch) { /* it is necessarily one of "*?[\\" */
1489                         sz++;
1490                         o->data[o->length] = '\\';
1491                         o->length++;
1492                 }
1493                 o_grow_by(o, sz);
1494                 o->data[o->length] = ch;
1495                 o->length++;
1496                 o->data[o->length] = '\0';
1497         }
1498 }
1499
1500 /* A special kind of o_string for $VAR and `cmd` expansion.
1501  * It contains char* list[] at the beginning, which is grown in 16 element
1502  * increments. Actual string data starts at the next multiple of 16 * (char*).
1503  * list[i] contains an INDEX (int!) into this string data.
1504  * It means that if list[] needs to grow, data needs to be moved higher up
1505  * but list[i]'s need not be modified.
1506  * NB: remembering how many list[i]'s you have there is crucial.
1507  * o_finalize_list() operation post-processes this structure - calculates
1508  * and stores actual char* ptrs in list[]. Oh, it NULL terminates it as well.
1509  */
1510 #if DEBUG_EXPAND || DEBUG_GLOB
1511 static void debug_print_list(const char *prefix, o_string *o, int n)
1512 {
1513         char **list = (char**)o->data;
1514         int string_start = ((n + 0xf) & ~0xf) * sizeof(list[0]);
1515         int i = 0;
1516         fprintf(stderr, "%s: list:%p n:%d string_start:%d length:%d maxlen:%d\n",
1517                         prefix, list, n, string_start, o->length, o->maxlen);
1518         while (i < n) {
1519                 fprintf(stderr, " list[%d]=%d '%s' %p\n", i, (int)list[i],
1520                                 o->data + (int)list[i] + string_start,
1521                                 o->data + (int)list[i] + string_start);
1522                 i++;
1523         }
1524         if (n) {
1525                 const char *p = o->data + (int)list[n - 1] + string_start;
1526                 fprintf(stderr, " total_sz:%ld\n", (long)((p + strlen(p) + 1) - o->data));
1527         }
1528 }
1529 #else
1530 #define debug_print_list(prefix, o, n) ((void)0)
1531 #endif
1532
1533 /* n = o_save_ptr_helper(str, n) "starts new string" by storing an index value
1534  * in list[n] so that it points past last stored byte so far.
1535  * It returns n+1. */
1536 static int o_save_ptr_helper(o_string *o, int n)
1537 {
1538         char **list = (char**)o->data;
1539         int string_start;
1540         int string_len;
1541
1542         if (!o->has_empty_slot) {
1543                 string_start = ((n + 0xf) & ~0xf) * sizeof(list[0]);
1544                 string_len = o->length - string_start;
1545                 if (!(n & 0xf)) { /* 0, 0x10, 0x20...? */
1546                         debug_printf_list("list[%d]=%d string_start=%d (growing)\n", n, string_len, string_start);
1547                         /* list[n] points to string_start, make space for 16 more pointers */
1548                         o->maxlen += 0x10 * sizeof(list[0]);
1549                         o->data = xrealloc(o->data, o->maxlen + 1);
1550                         list = (char**)o->data;
1551                         memmove(list + n + 0x10, list + n, string_len);
1552                         o->length += 0x10 * sizeof(list[0]);
1553                 } else
1554                         debug_printf_list("list[%d]=%d string_start=%d\n", n, string_len, string_start);
1555         } else {
1556                 /* We have empty slot at list[n], reuse without growth */
1557                 string_start = ((n+1 + 0xf) & ~0xf) * sizeof(list[0]); /* NB: n+1! */
1558                 string_len = o->length - string_start;
1559                 debug_printf_list("list[%d]=%d string_start=%d (empty slot)\n", n, string_len, string_start);
1560                 o->has_empty_slot = 0;
1561         }
1562         list[n] = (char*)(ptrdiff_t)string_len;
1563         return n + 1;
1564 }
1565
1566 /* "What was our last o_save_ptr'ed position (byte offset relative o->data)?" */
1567 static int o_get_last_ptr(o_string *o, int n)
1568 {
1569         char **list = (char**)o->data;
1570         int string_start = ((n + 0xf) & ~0xf) * sizeof(list[0]);
1571
1572         return ((int)(ptrdiff_t)list[n-1]) + string_start;
1573 }
1574
1575 /* o_glob performs globbing on last list[], saving each result
1576  * as a new list[]. */
1577 static int o_glob(o_string *o, int n)
1578 {
1579         glob_t globdata;
1580         int gr;
1581         char *pattern;
1582
1583         debug_printf_glob("start o_glob: n:%d o->data:%p\n", n, o->data);
1584         if (!o->data)
1585                 return o_save_ptr_helper(o, n);
1586         pattern = o->data + o_get_last_ptr(o, n);
1587         debug_printf_glob("glob pattern '%s'\n", pattern);
1588         if (!glob_needed(pattern)) {
1589  literal:
1590                 o->length = unbackslash(pattern) - o->data;
1591                 debug_printf_glob("glob pattern '%s' is literal\n", pattern);
1592                 return o_save_ptr_helper(o, n);
1593         }
1594
1595         memset(&globdata, 0, sizeof(globdata));
1596         gr = glob(pattern, 0, NULL, &globdata);
1597         debug_printf_glob("glob('%s'):%d\n", pattern, gr);
1598         if (gr == GLOB_NOSPACE)
1599                 bb_error_msg_and_die("out of memory during glob");
1600         if (gr == GLOB_NOMATCH) {
1601                 globfree(&globdata);
1602                 goto literal;
1603         }
1604         if (gr != 0) { /* GLOB_ABORTED ? */
1605 //TODO: testcase for bad glob pattern behavior
1606                 bb_error_msg("glob(3) error %d on '%s'", gr, pattern);
1607         }
1608         if (globdata.gl_pathv && globdata.gl_pathv[0]) {
1609                 char **argv = globdata.gl_pathv;
1610                 o->length = pattern - o->data; /* "forget" pattern */
1611                 while (1) {
1612                         o_addstrauto(o, *argv);
1613                         n = o_save_ptr_helper(o, n);
1614                         argv++;
1615                         if (!*argv)
1616                                 break;
1617                 }
1618         }
1619         globfree(&globdata);
1620         if (DEBUG_GLOB)
1621                 debug_print_list("o_glob returning", o, n);
1622         return n;
1623 }
1624
1625 /* If o->o_glob == 1, glob the string so far remembered.
1626  * Otherwise, just finish current list[] and start new */
1627 static int o_save_ptr(o_string *o, int n)
1628 {
1629         if (o->o_glob) { /* if globbing is requested */
1630                 /* If o->has_empty_slot, list[n] was already globbed
1631                  * (if it was requested back then when it was filled)
1632                  * so don't do that again! */
1633                 if (!o->has_empty_slot)
1634                         return o_glob(o, n); /* o_save_ptr_helper is inside */
1635         }
1636         return o_save_ptr_helper(o, n);
1637 }
1638
1639 /* "Please convert list[n] to real char* ptrs, and NULL terminate it." */
1640 static char **o_finalize_list(o_string *o, int n)
1641 {
1642         char **list;
1643         int string_start;
1644
1645         n = o_save_ptr(o, n); /* force growth for list[n] if necessary */
1646         if (DEBUG_EXPAND)
1647                 debug_print_list("finalized", o, n);
1648         debug_printf_expand("finalized n:%d\n", n);
1649         list = (char**)o->data;
1650         string_start = ((n + 0xf) & ~0xf) * sizeof(list[0]);
1651         list[--n] = NULL;
1652         while (n) {
1653                 n--;
1654                 list[n] = o->data + (int)(ptrdiff_t)list[n] + string_start;
1655         }
1656         return list;
1657 }
1658
1659
1660 /* Expansion can recurse */
1661 #if ENABLE_HUSH_TICK
1662 static int process_command_subs(o_string *dest, struct in_str *input);
1663 #endif
1664 static char *expand_string_to_string(const char *str);
1665 static int parse_stream_dquoted(o_string *dest, struct in_str *input, int dquote_end);
1666
1667 /* expand_strvec_to_strvec() takes a list of strings, expands
1668  * all variable references within and returns a pointer to
1669  * a list of expanded strings, possibly with larger number
1670  * of strings. (Think VAR="a b"; echo $VAR).
1671  * This new list is allocated as a single malloc block.
1672  * NULL-terminated list of char* pointers is at the beginning of it,
1673  * followed by strings themself.
1674  * Caller can deallocate entire list by single free(list). */
1675
1676 /* Store given string, finalizing the word and starting new one whenever
1677  * we encounter IFS char(s). This is used for expanding variable values.
1678  * End-of-string does NOT finalize word: think about 'echo -$VAR-' */
1679 static int expand_on_ifs(o_string *output, int n, const char *str)
1680 {
1681         while (1) {
1682                 int word_len = strcspn(str, G.ifs);
1683                 if (word_len) {
1684                         if (output->o_escape || !output->o_glob)
1685                                 o_addQstr(output, str, word_len);
1686                         else /* protect backslashes against globbing up :) */
1687                                 o_addstr_duplicate_backslash(output, str, word_len);
1688                         str += word_len;
1689                 }
1690                 if (!*str)  /* EOL - do not finalize word */
1691                         break;
1692                 o_addchr(output, '\0');
1693                 debug_print_list("expand_on_ifs", output, n);
1694                 n = o_save_ptr(output, n);
1695                 str += strspn(str, G.ifs); /* skip ifs chars */
1696         }
1697         debug_print_list("expand_on_ifs[1]", output, n);
1698         return n;
1699 }
1700
1701 /* Expand all variable references in given string, adding words to list[]
1702  * at n, n+1,... positions. Return updated n (so that list[n] is next one
1703  * to be filled). This routine is extremely tricky: has to deal with
1704  * variables/parameters with whitespace, $* and $@, and constructs like
1705  * 'echo -$*-'. If you play here, you must run testsuite afterwards! */
1706 static int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask)
1707 {
1708         /* or_mask is either 0 (normal case) or 0x80
1709          * (expansion of right-hand side of assignment == 1-element expand.
1710          * It will also do no globbing, and thus we must not backslash-quote!) */
1711
1712         char first_ch, ored_ch;
1713         int i;
1714         const char *val;
1715         char *p;
1716
1717         ored_ch = 0;
1718
1719         debug_printf_expand("expand_vars_to_list: arg '%s'\n", arg);
1720         debug_print_list("expand_vars_to_list", output, n);
1721         n = o_save_ptr(output, n);
1722         debug_print_list("expand_vars_to_list[0]", output, n);
1723
1724         while ((p = strchr(arg, SPECIAL_VAR_SYMBOL)) != NULL) {
1725 #if ENABLE_HUSH_TICK
1726                 o_string subst_result = NULL_O_STRING;
1727 #endif
1728 #if ENABLE_SH_MATH_SUPPORT
1729                 char arith_buf[sizeof(arith_t)*3 + 2];
1730 #endif
1731                 o_addstr(output, arg, p - arg);
1732                 debug_print_list("expand_vars_to_list[1]", output, n);
1733                 arg = ++p;
1734                 p = strchr(p, SPECIAL_VAR_SYMBOL);
1735
1736                 first_ch = arg[0] | or_mask; /* forced to "quoted" if or_mask = 0x80 */
1737                 /* "$@" is special. Even if quoted, it can still
1738                  * expand to nothing (not even an empty string) */
1739                 if ((first_ch & 0x7f) != '@')
1740                         ored_ch |= first_ch;
1741
1742                 val = NULL;
1743                 switch (first_ch & 0x7f) {
1744                 /* Highest bit in first_ch indicates that var is double-quoted */
1745                 case '$': /* pid */
1746                         val = utoa(G.root_pid);
1747                         break;
1748                 case '!': /* bg pid */
1749                         val = G.last_bg_pid ? utoa(G.last_bg_pid) : (char*)"";
1750                         break;
1751                 case '?': /* exitcode */
1752                         val = utoa(G.last_return_code);
1753                         break;
1754                 case '#': /* argc */
1755                         if (arg[1] != SPECIAL_VAR_SYMBOL)
1756                                 /* actually, it's a ${#var} */
1757                                 goto case_default;
1758                         val = utoa(G.global_argc ? G.global_argc-1 : 0);
1759                         break;
1760                 case '*':
1761                 case '@':
1762                         i = 1;
1763                         if (!G.global_argv[i])
1764                                 break;
1765                         ored_ch |= first_ch; /* do it for "$@" _now_, when we know it's not empty */
1766                         if (!(first_ch & 0x80)) { /* unquoted $* or $@ */
1767                                 smallint sv = output->o_escape;
1768                                 /* unquoted var's contents should be globbed, so don't escape */
1769                                 output->o_escape = 0;
1770                                 while (G.global_argv[i]) {
1771                                         n = expand_on_ifs(output, n, G.global_argv[i]);
1772                                         debug_printf_expand("expand_vars_to_list: argv %d (last %d)\n", i, G.global_argc - 1);
1773                                         if (G.global_argv[i++][0] && G.global_argv[i]) {
1774                                                 /* this argv[] is not empty and not last:
1775                                                  * put terminating NUL, start new word */
1776                                                 o_addchr(output, '\0');
1777                                                 debug_print_list("expand_vars_to_list[2]", output, n);
1778                                                 n = o_save_ptr(output, n);
1779                                                 debug_print_list("expand_vars_to_list[3]", output, n);
1780                                         }
1781                                 }
1782                                 output->o_escape = sv;
1783                         } else
1784                         /* If or_mask is nonzero, we handle assignment 'a=....$@.....'
1785                          * and in this case should treat it like '$*' - see 'else...' below */
1786                         if (first_ch == ('@'|0x80) && !or_mask) { /* quoted $@ */
1787                                 while (1) {
1788                                         o_addQstr(output, G.global_argv[i], strlen(G.global_argv[i]));
1789                                         if (++i >= G.global_argc)
1790                                                 break;
1791                                         o_addchr(output, '\0');
1792                                         debug_print_list("expand_vars_to_list[4]", output, n);
1793                                         n = o_save_ptr(output, n);
1794                                 }
1795                         } else { /* quoted $*: add as one word */
1796                                 while (1) {
1797                                         o_addQstr(output, G.global_argv[i], strlen(G.global_argv[i]));
1798                                         if (!G.global_argv[++i])
1799                                                 break;
1800                                         if (G.ifs[0])
1801                                                 o_addchr(output, G.ifs[0]);
1802                                 }
1803                         }
1804                         break;
1805                 case SPECIAL_VAR_SYMBOL: /* <SPECIAL_VAR_SYMBOL><SPECIAL_VAR_SYMBOL> */
1806                         /* "Empty variable", used to make "" etc to not disappear */
1807                         arg++;
1808                         ored_ch = 0x80;
1809                         break;
1810 #if ENABLE_HUSH_TICK
1811                 case '`': { /* <SPECIAL_VAR_SYMBOL>`cmd<SPECIAL_VAR_SYMBOL> */
1812                         struct in_str input;
1813                         *p = '\0';
1814                         arg++;
1815 //TODO: can we just stuff it into "output" directly?
1816                         debug_printf_subst("SUBST '%s' first_ch %x\n", arg, first_ch);
1817                         setup_string_in_str(&input, arg);
1818                         process_command_subs(&subst_result, &input);
1819                         debug_printf_subst("SUBST RES '%s'\n", subst_result.data);
1820                         val = subst_result.data;
1821                         goto store_val;
1822                 }
1823 #endif
1824 #if ENABLE_SH_MATH_SUPPORT
1825                 case '+': { /* <SPECIAL_VAR_SYMBOL>+cmd<SPECIAL_VAR_SYMBOL> */
1826                         arith_eval_hooks_t hooks;
1827                         arith_t res;
1828                         int errcode;
1829                         char *exp_str;
1830
1831                         arg++; /* skip '+' */
1832                         *p = '\0'; /* replace trailing <SPECIAL_VAR_SYMBOL> */
1833                         debug_printf_subst("ARITH '%s' first_ch %x\n", arg, first_ch);
1834
1835                         /* Optional: skip expansion if expr is simple ("a + 3", "i++" etc) */
1836                         exp_str = arg;
1837                         while (1) {
1838                                 unsigned char c = *exp_str++;
1839                                 if (c == '\0') {
1840                                         exp_str = NULL;
1841                                         goto skip_expand;
1842                                 }
1843                                 if (isdigit(c))
1844                                         continue;
1845                                 if (strchr(" \t+-*/%_", c) != NULL)
1846                                         continue;
1847                                 c |= 0x20; /* tolower */
1848                                 if (c >= 'a' && c <= 'z')
1849                                         continue;
1850                                 break;
1851                         }
1852                         /* We need to expand. Example: "echo $(($a + 1)) $((1 + $((2)) ))" */
1853                         {
1854                                 struct in_str input;
1855                                 o_string dest = NULL_O_STRING;
1856
1857                                 setup_string_in_str(&input, arg);
1858                                 parse_stream_dquoted(&dest, &input, EOF);
1859                                 //bb_error_msg("'%s' -> '%s'", arg, dest.data);
1860                                 exp_str = expand_string_to_string(dest.data);
1861                                 //bb_error_msg("'%s' -> '%s'", dest.data, exp_str);
1862                                 o_free(&dest);
1863                         }
1864  skip_expand:
1865                         hooks.lookupvar = lookup_param;
1866                         hooks.setvar = arith_set_local_var;
1867                         hooks.endofname = endofname;
1868                         res = arith(exp_str ? exp_str : arg, &errcode, &hooks);
1869                         free(exp_str);
1870
1871                         if (errcode < 0) {
1872                                 switch (errcode) {
1873                                 case -3: maybe_die("arith", "exponent less than 0"); break;
1874                                 case -2: maybe_die("arith", "divide by zero"); break;
1875                                 case -5: maybe_die("arith", "expression recursion loop detected"); break;
1876                                 default: maybe_die("arith", "syntax error"); break;
1877                                 }
1878                         }
1879                         debug_printf_subst("ARITH RES '"arith_t_fmt"'\n", res);
1880                         sprintf(arith_buf, arith_t_fmt, res);
1881                         val = arith_buf;
1882                         break;
1883                 }
1884 #endif
1885                 default: /* <SPECIAL_VAR_SYMBOL>varname<SPECIAL_VAR_SYMBOL> */
1886                 case_default: {
1887                         bool exp_len = false, exp_null = false;
1888                         char *var = arg, exp_save, exp_op, *exp_word;
1889                         size_t exp_off = 0;
1890                         *p = '\0';
1891                         arg[0] = first_ch & 0x7f;
1892
1893                         /* prepare for expansions */
1894                         if (var[0] == '#') {
1895                                 /* handle length expansion ${#var} */
1896                                 exp_len = true;
1897                                 ++var;
1898                         } else {
1899                                 /* maybe handle parameter expansion */
1900                                 exp_off = strcspn(var, ":-=+?");
1901                                 if (!var[exp_off])
1902                                         exp_off = 0;
1903                                 if (exp_off) {
1904                                         exp_save = var[exp_off];
1905                                         exp_null = exp_save == ':';
1906                                         exp_word = var + exp_off;
1907                                         if (exp_null) ++exp_word;
1908                                         exp_op = *exp_word++;
1909                                         var[exp_off] = '\0';
1910                                 }
1911                         }
1912
1913                         /* lookup the variable in question */
1914                         if (isdigit(var[0])) {
1915                                 /* handle_dollar() should have vetted var for us */
1916                                 i = xatoi_u(var);
1917                                 if (i < G.global_argc)
1918                                         val = G.global_argv[i];
1919                                 /* else val remains NULL: $N with too big N */
1920                         } else
1921                                 val = lookup_param(var);
1922
1923                         /* handle any expansions */
1924                         if (exp_len) {
1925                                 debug_printf_expand("expand: length of '%s' = ", val);
1926                                 val = utoa(val ? strlen(val) : 0);
1927                                 debug_printf_expand("%s\n", val);
1928                         } else if (exp_off) {
1929                                 /* we need to do an expansion */
1930                                 int exp_test = (!val || (exp_null && !val[0]));
1931                                 if (exp_op == '+')
1932                                         exp_test = !exp_test;
1933                                 debug_printf_expand("expand: op:%c (null:%s) test:%i\n", exp_op,
1934                                         exp_null ? "true" : "false", exp_test);
1935                                 if (exp_test) {
1936                                         if (exp_op == '?')
1937                                                 maybe_die(var, *exp_word ? exp_word : "parameter null or not set");
1938                                         else
1939                                                 val = exp_word;
1940
1941                                         if (exp_op == '=') {
1942                                                 if (isdigit(var[0]) || var[0] == '#') {
1943                                                         maybe_die(var, "special vars cannot assign in this way");
1944                                                         val = NULL;
1945                                                 } else {
1946                                                         char *new_var = xmalloc(strlen(var) + strlen(val) + 2);
1947                                                         sprintf(new_var, "%s=%s", var, val);
1948                                                         set_local_var(new_var, -1);
1949                                                 }
1950                                         }
1951                                 }
1952                                 var[exp_off] = exp_save;
1953                         }
1954
1955                         arg[0] = first_ch;
1956
1957 #if ENABLE_HUSH_TICK
1958  store_val:
1959 #endif
1960                         if (!(first_ch & 0x80)) { /* unquoted $VAR */
1961                                 debug_printf_expand("unquoted '%s', output->o_escape:%d\n", val, output->o_escape);
1962                                 if (val) {
1963                                         /* unquoted var's contents should be globbed, so don't escape */
1964                                         smallint sv = output->o_escape;
1965                                         output->o_escape = 0;
1966                                         n = expand_on_ifs(output, n, val);
1967                                         val = NULL;
1968                                         output->o_escape = sv;
1969                                 }
1970                         } else { /* quoted $VAR, val will be appended below */
1971                                 debug_printf_expand("quoted '%s', output->o_escape:%d\n", val, output->o_escape);
1972                         }
1973                 } /* default: */
1974                 } /* switch (char after <SPECIAL_VAR_SYMBOL>) */
1975                 if (val) {
1976                         o_addQstr(output, val, strlen(val));
1977                 }
1978                 /* Do the check to avoid writing to a const string */
1979                 if (*p != SPECIAL_VAR_SYMBOL)
1980                         *p = SPECIAL_VAR_SYMBOL;
1981
1982 #if ENABLE_HUSH_TICK
1983                 o_free(&subst_result);
1984 #endif
1985                 arg = ++p;
1986         } /* end of "while (SPECIAL_VAR_SYMBOL is found) ..." */
1987
1988         if (arg[0]) {
1989                 debug_print_list("expand_vars_to_list[a]", output, n);
1990                 /* this part is literal, and it was already pre-quoted
1991                  * if needed (much earlier), do not use o_addQstr here! */
1992                 o_addstrauto(output, arg);
1993                 debug_print_list("expand_vars_to_list[b]", output, n);
1994         } else if (output->length == o_get_last_ptr(output, n) /* expansion is empty */
1995          && !(ored_ch & 0x80) /* and all vars were not quoted. */
1996         ) {
1997                 n--;
1998                 /* allow to reuse list[n] later without re-growth */
1999                 output->has_empty_slot = 1;
2000         } else {
2001                 o_addchr(output, '\0');
2002         }
2003         return n;
2004 }
2005
2006 static char **expand_variables(char **argv, int or_mask)
2007 {
2008         int n;
2009         char **list;
2010         char **v;
2011         o_string output = NULL_O_STRING;
2012
2013         if (or_mask & 0x100) {
2014                 output.o_escape = 1; /* protect against globbing for "$var" */
2015                 /* (unquoted $var will temporarily switch it off) */
2016                 output.o_glob = 1;
2017         }
2018
2019         n = 0;
2020         v = argv;
2021         while (*v) {
2022                 n = expand_vars_to_list(&output, n, *v, (char)or_mask);
2023                 v++;
2024         }
2025         debug_print_list("expand_variables", &output, n);
2026
2027         /* output.data (malloced in one block) gets returned in "list" */
2028         list = o_finalize_list(&output, n);
2029         debug_print_strings("expand_variables[1]", list);
2030         return list;
2031 }
2032
2033 static char **expand_strvec_to_strvec(char **argv)
2034 {
2035         return expand_variables(argv, 0x100);
2036 }
2037
2038 /* Used for expansion of right hand of assignments */
2039 /* NB: should NOT do globbing! "export v=/bin/c*; env | grep ^v=" outputs
2040  * "v=/bin/c*" */
2041 static char *expand_string_to_string(const char *str)
2042 {
2043         char *argv[2], **list;
2044
2045         argv[0] = (char*)str;
2046         argv[1] = NULL;
2047         list = expand_variables(argv, 0x80); /* 0x80: make one-element expansion */
2048         if (HUSH_DEBUG)
2049                 if (!list[0] || list[1])
2050                         bb_error_msg_and_die("BUG in varexp2");
2051         /* actually, just move string 2*sizeof(char*) bytes back */
2052         overlapping_strcpy((char*)list, list[0]);
2053         debug_printf_expand("string_to_string='%s'\n", (char*)list);
2054         return (char*)list;
2055 }
2056
2057 /* Used for "eval" builtin */
2058 static char* expand_strvec_to_string(char **argv)
2059 {
2060         char **list;
2061
2062         list = expand_variables(argv, 0x80);
2063         /* Convert all NULs to spaces */
2064         if (list[0]) {
2065                 int n = 1;
2066                 while (list[n]) {
2067                         if (HUSH_DEBUG)
2068                                 if (list[n-1] + strlen(list[n-1]) + 1 != list[n])
2069                                         bb_error_msg_and_die("BUG in varexp3");
2070                         list[n][-1] = ' '; /* TODO: or to G.ifs[0]? */
2071                         n++;
2072                 }
2073         }
2074         overlapping_strcpy((char*)list, list[0]);
2075         debug_printf_expand("strvec_to_string='%s'\n", (char*)list);
2076         return (char*)list;
2077 }
2078
2079 static char **expand_assignments(char **argv, int count)
2080 {
2081         int i;
2082         char **p = NULL;
2083         /* Expand assignments into one string each */
2084         for (i = 0; i < count; i++) {
2085                 p = add_string_to_strings(p, expand_string_to_string(argv[i]));
2086         }
2087         return p;
2088 }
2089
2090
2091 /* squirrel != NULL means we squirrel away copies of stdin, stdout,
2092  * and stderr if they are redirected. */
2093 static int setup_redirects(struct command *prog, int squirrel[])
2094 {
2095         int openfd, mode;
2096         struct redir_struct *redir;
2097
2098         for (redir = prog->redirects; redir; redir = redir->next) {
2099                 if (redir->dup == -1 && redir->rd_filename == NULL) {
2100                         /* something went wrong in the parse.  Pretend it didn't happen */
2101                         continue;
2102                 }
2103                 if (redir->dup == -1) {
2104                         char *p;
2105                         mode = redir_table[redir->rd_type].mode;
2106 //TODO: check redir for names like '\\'
2107                         p = expand_string_to_string(redir->rd_filename);
2108                         openfd = open_or_warn(p, mode);
2109                         free(p);
2110                         if (openfd < 0) {
2111                         /* this could get lost if stderr has been redirected, but
2112                            bash and ash both lose it as well (though zsh doesn't!) */
2113                                 return 1;
2114                         }
2115                 } else {
2116                         openfd = redir->dup;
2117                 }
2118
2119                 if (openfd != redir->fd) {
2120                         if (squirrel && redir->fd < 3) {
2121                                 squirrel[redir->fd] = dup(redir->fd);
2122                         }
2123                         if (openfd == -3) {
2124                                 //close(openfd); // close(-3) ??!
2125                         } else {
2126                                 dup2(openfd, redir->fd);
2127                                 if (redir->dup == -1)
2128                                         close(openfd);
2129                         }
2130                 }
2131         }
2132         return 0;
2133 }
2134
2135 static void restore_redirects(int squirrel[])
2136 {
2137         int i, fd;
2138         for (i = 0; i < 3; i++) {
2139                 fd = squirrel[i];
2140                 if (fd != -1) {
2141                         /* We simply die on error */
2142                         xmove_fd(fd, i);
2143                 }
2144         }
2145 }
2146
2147
2148 #if !defined(DEBUG_CLEAN)
2149 #define free_pipe_list(head, indent) free_pipe_list(head)
2150 #define free_pipe(pi, indent)        free_pipe(pi)
2151 #endif
2152 static void free_pipe_list(struct pipe *head, int indent);
2153
2154 /* return code is the exit status of the pipe */
2155 static void free_pipe(struct pipe *pi, int indent)
2156 {
2157         char **p;
2158         struct command *command;
2159         struct redir_struct *r, *rnext;
2160         int a, i;
2161
2162         if (pi->stopped_cmds > 0)
2163                 return;
2164         debug_printf_clean("%s run pipe: (pid %d)\n", indenter(indent), getpid());
2165         for (i = 0; i < pi->num_cmds; i++) {
2166                 command = &pi->cmds[i];
2167                 debug_printf_clean("%s  command %d:\n", indenter(indent), i);
2168                 if (command->argv) {
2169                         for (a = 0, p = command->argv; *p; a++, p++) {
2170                                 debug_printf_clean("%s   argv[%d] = %s\n", indenter(indent), a, *p);
2171                         }
2172                         free_strings(command->argv);
2173                         command->argv = NULL;
2174                 }
2175                 /* not "else if": on syntax error, we may have both! */
2176                 if (command->group) {
2177                         debug_printf_clean("%s   begin group (grp_type:%d)\n", indenter(indent), command->grp_type);
2178                         free_pipe_list(command->group, indent+3);
2179                         debug_printf_clean("%s   end group\n", indenter(indent));
2180                         command->group = NULL;
2181                 }
2182                 for (r = command->redirects; r; r = rnext) {
2183                         debug_printf_clean("%s   redirect %d%s", indenter(indent), r->fd, redir_table[r->rd_type].descrip);
2184                         if (r->dup == -1) {
2185                                 /* guard against the case >$FOO, where foo is unset or blank */
2186                                 if (r->rd_filename) {
2187                                         debug_printf_clean(" %s\n", r->rd_filename);
2188                                         free(r->rd_filename);
2189                                         r->rd_filename = NULL;
2190                                 }
2191                         } else {
2192                                 debug_printf_clean("&%d\n", r->dup);
2193                         }
2194                         rnext = r->next;
2195                         free(r);
2196                 }
2197                 command->redirects = NULL;
2198         }
2199         free(pi->cmds);   /* children are an array, they get freed all at once */
2200         pi->cmds = NULL;
2201 #if ENABLE_HUSH_JOB
2202         free(pi->cmdtext);
2203         pi->cmdtext = NULL;
2204 #endif
2205 }
2206
2207 static void free_pipe_list(struct pipe *head, int indent)
2208 {
2209         struct pipe *pi, *next;
2210
2211         for (pi = head; pi; pi = next) {
2212 #if HAS_KEYWORDS
2213                 debug_printf_clean("%s pipe reserved mode %d\n", indenter(indent), pi->res_word);
2214 #endif
2215                 free_pipe(pi, indent);
2216                 debug_printf_clean("%s pipe followup code %d\n", indenter(indent), pi->followup);
2217                 next = pi->next;
2218                 /*pi->next = NULL;*/
2219                 free(pi);
2220         }
2221 }
2222
2223
2224 #if !BB_MMU
2225 typedef struct nommu_save_t {
2226         char **new_env;
2227         char **old_env;
2228         char **argv;
2229 } nommu_save_t;
2230 #else
2231 #define pseudo_exec_argv(nommu_save, argv, assignment_cnt, argv_expanded) \
2232         pseudo_exec_argv(argv, assignment_cnt, argv_expanded)
2233 #define pseudo_exec(nommu_save, command, argv_expanded) \
2234         pseudo_exec(command, argv_expanded)
2235 #endif
2236
2237 /* Called after [v]fork() in run_pipe(), or from builtin_exec().
2238  * Never returns.
2239  * XXX no exit() here.  If you don't exec, use _exit instead.
2240  * The at_exit handlers apparently confuse the calling process,
2241  * in particular stdin handling.  Not sure why? -- because of vfork! (vda) */
2242 static void pseudo_exec_argv(nommu_save_t *nommu_save, char **argv, int assignment_cnt, char **argv_expanded) NORETURN;
2243 static void pseudo_exec_argv(nommu_save_t *nommu_save, char **argv, int assignment_cnt, char **argv_expanded)
2244 {
2245         int rcode;
2246         char **new_env;
2247         const struct built_in_command *x;
2248
2249         /* If a variable is assigned in a forest, and nobody listens,
2250          * was it ever really set?
2251          */
2252         if (!argv[assignment_cnt])
2253                 _exit(EXIT_SUCCESS);
2254
2255         new_env = expand_assignments(argv, assignment_cnt);
2256 #if BB_MMU
2257         putenv_all(new_env);
2258         free(new_env); /* optional */
2259 #else
2260         nommu_save->new_env = new_env;
2261         nommu_save->old_env = putenv_all_and_save_old(new_env);
2262 #endif
2263         if (argv_expanded) {
2264                 argv = argv_expanded;
2265         } else {
2266                 argv = expand_strvec_to_strvec(argv + assignment_cnt);
2267 #if !BB_MMU
2268                 nommu_save->argv = argv;
2269 #endif
2270         }
2271
2272         /*
2273          * Check if the command matches any of the builtins.
2274          * Depending on context, this might be redundant.  But it's
2275          * easier to waste a few CPU cycles than it is to figure out
2276          * if this is one of those cases.
2277          */
2278         for (x = bltins; x != &bltins[ARRAY_SIZE(bltins)]; x++) {
2279                 if (strcmp(argv[0], x->cmd) == 0) {
2280                         debug_printf_exec("running builtin '%s'\n", argv[0]);
2281                         rcode = x->function(argv);
2282                         fflush(stdout);
2283                         _exit(rcode);
2284                 }
2285         }
2286
2287         /* Check if the command matches any busybox applets */
2288 #if ENABLE_FEATURE_SH_STANDALONE
2289         if (strchr(argv[0], '/') == NULL) {
2290                 int a = find_applet_by_name(argv[0]);
2291                 if (a >= 0) {
2292                         if (APPLET_IS_NOEXEC(a)) {
2293                                 debug_printf_exec("running applet '%s'\n", argv[0]);
2294 // is it ok that run_applet_no_and_exit() does exit(), not _exit()?
2295                                 run_applet_no_and_exit(a, argv);
2296                         }
2297                         /* re-exec ourselves with the new arguments */
2298                         debug_printf_exec("re-execing applet '%s'\n", argv[0]);
2299                         execvp(bb_busybox_exec_path, argv);
2300                         /* If they called chroot or otherwise made the binary no longer
2301                          * executable, fall through */
2302                 }
2303         }
2304 #endif
2305
2306         sigprocmask(SIG_SETMASK, &G.inherited_set, NULL);
2307
2308         debug_printf_exec("execing '%s'\n", argv[0]);
2309         execvp(argv[0], argv);
2310         bb_perror_msg("can't exec '%s'", argv[0]);
2311         _exit(EXIT_FAILURE);
2312 }
2313
2314 static int run_list(struct pipe *pi);
2315
2316 /* Called after [v]fork() in run_pipe()
2317  */
2318 static void pseudo_exec(nommu_save_t *nommu_save, struct command *command, char **argv_expanded) NORETURN;
2319 static void pseudo_exec(nommu_save_t *nommu_save, struct command *command, char **argv_expanded)
2320 {
2321         if (command->argv)
2322                 pseudo_exec_argv(nommu_save, command->argv, command->assignment_cnt, argv_expanded);
2323
2324         if (command->group) {
2325 #if !BB_MMU
2326                 bb_error_msg_and_die("nested lists are not supported on NOMMU");
2327 #else
2328                 int rcode;
2329                 debug_printf_exec("pseudo_exec: run_list\n");
2330                 rcode = run_list(command->group);
2331                 /* OK to leak memory by not calling free_pipe_list,
2332                  * since this process is about to exit */
2333                 _exit(rcode);
2334 #endif
2335         }
2336
2337         /* Can happen.  See what bash does with ">foo" by itself. */
2338         debug_printf("trying to pseudo_exec null command\n");
2339         _exit(EXIT_SUCCESS);
2340 }
2341
2342 #if ENABLE_HUSH_JOB
2343 static const char *get_cmdtext(struct pipe *pi)
2344 {
2345         char **argv;
2346         char *p;
2347         int len;
2348
2349         /* This is subtle. ->cmdtext is created only on first backgrounding.
2350          * (Think "cat, <ctrl-z>, fg, <ctrl-z>, fg, <ctrl-z>...." here...)
2351          * On subsequent bg argv is trashed, but we won't use it */
2352         if (pi->cmdtext)
2353                 return pi->cmdtext;
2354         argv = pi->cmds[0].argv;
2355         if (!argv || !argv[0]) {
2356                 pi->cmdtext = xzalloc(1);
2357                 return pi->cmdtext;
2358         }
2359
2360         len = 0;
2361         do len += strlen(*argv) + 1; while (*++argv);
2362         pi->cmdtext = p = xmalloc(len);
2363         argv = pi->cmds[0].argv;
2364         do {
2365                 len = strlen(*argv);
2366                 memcpy(p, *argv, len);
2367                 p += len;
2368                 *p++ = ' ';
2369         } while (*++argv);
2370         p[-1] = '\0';
2371         return pi->cmdtext;
2372 }
2373
2374 static void insert_bg_job(struct pipe *pi)
2375 {
2376         struct pipe *thejob;
2377         int i;
2378
2379         /* Linear search for the ID of the job to use */
2380         pi->jobid = 1;
2381         for (thejob = G.job_list; thejob; thejob = thejob->next)
2382                 if (thejob->jobid >= pi->jobid)
2383                         pi->jobid = thejob->jobid + 1;
2384
2385         /* Add thejob to the list of running jobs */
2386         if (!G.job_list) {
2387                 thejob = G.job_list = xmalloc(sizeof(*thejob));
2388         } else {
2389                 for (thejob = G.job_list; thejob->next; thejob = thejob->next)
2390                         continue;
2391                 thejob->next = xmalloc(sizeof(*thejob));
2392                 thejob = thejob->next;
2393         }
2394
2395         /* Physically copy the struct job */
2396         memcpy(thejob, pi, sizeof(struct pipe));
2397         thejob->cmds = xzalloc(sizeof(pi->cmds[0]) * pi->num_cmds);
2398         /* We cannot copy entire pi->cmds[] vector! Double free()s will happen */
2399         for (i = 0; i < pi->num_cmds; i++) {
2400 // TODO: do we really need to have so many fields which are just dead weight
2401 // at execution stage?
2402                 thejob->cmds[i].pid = pi->cmds[i].pid;
2403                 /* all other fields are not used and stay zero */
2404         }
2405         thejob->next = NULL;
2406         thejob->cmdtext = xstrdup(get_cmdtext(pi));
2407
2408         /* We don't wait for background thejobs to return -- append it
2409            to the list of backgrounded thejobs and leave it alone */
2410         if (G_interactive_fd)
2411                 printf("[%d] %d %s\n", thejob->jobid, thejob->cmds[0].pid, thejob->cmdtext);
2412         G.last_bg_pid = thejob->cmds[0].pid;
2413         G.last_jobid = thejob->jobid;
2414 }
2415
2416 static void remove_bg_job(struct pipe *pi)
2417 {
2418         struct pipe *prev_pipe;
2419
2420         if (pi == G.job_list) {
2421                 G.job_list = pi->next;
2422         } else {
2423                 prev_pipe = G.job_list;
2424                 while (prev_pipe->next != pi)
2425                         prev_pipe = prev_pipe->next;
2426                 prev_pipe->next = pi->next;
2427         }
2428         if (G.job_list)
2429                 G.last_jobid = G.job_list->jobid;
2430         else
2431                 G.last_jobid = 0;
2432 }
2433
2434 /* Remove a backgrounded job */
2435 static void delete_finished_bg_job(struct pipe *pi)
2436 {
2437         remove_bg_job(pi);
2438         pi->stopped_cmds = 0;
2439         free_pipe(pi, 0);
2440         free(pi);
2441 }
2442 #endif /* JOB */
2443
2444 /* Check to see if any processes have exited -- if they
2445  * have, figure out why and see if a job has completed */
2446 static int checkjobs(struct pipe* fg_pipe)
2447 {
2448         int attributes;
2449         int status;
2450 #if ENABLE_HUSH_JOB
2451         struct pipe *pi;
2452 #endif
2453         pid_t childpid;
2454         int rcode = 0;
2455
2456         debug_printf_jobs("checkjobs %p\n", fg_pipe);
2457
2458         errno = 0;
2459 //      if (G.handled_SIGCHLD == G.count_SIGCHLD)
2460 //              /* avoid doing syscall, nothing there anyway */
2461 //              return rcode;
2462
2463         attributes = WUNTRACED;
2464         if (fg_pipe == NULL)
2465                 attributes |= WNOHANG;
2466
2467 /* Do we do this right?
2468  * bash-3.00# sleep 20 | false
2469  * <ctrl-Z pressed>
2470  * [3]+  Stopped          sleep 20 | false
2471  * bash-3.00# echo $?
2472  * 1   <========== bg pipe is not fully done, but exitcode is already known!
2473  */
2474
2475 //FIXME: non-interactive bash does not continue even if all processes in fg pipe
2476 //are stopped. Testcase: "cat | cat" in a script (not on command line)
2477 // + killall -STOP cat
2478
2479  wait_more:
2480         while (1) {
2481                 int i;
2482                 int dead;
2483
2484 //              i = G.count_SIGCHLD;
2485                 childpid = waitpid(-1, &status, attributes);
2486                 if (childpid <= 0) {
2487                         if (childpid && errno != ECHILD)
2488                                 bb_perror_msg("waitpid");
2489 //                      else /* Until next SIGCHLD, waitpid's are useless */
2490 //                              G.handled_SIGCHLD = i;
2491                         break;
2492                 }
2493                 dead = WIFEXITED(status) || WIFSIGNALED(status);
2494
2495 #if DEBUG_JOBS
2496                 if (WIFSTOPPED(status))
2497                         debug_printf_jobs("pid %d stopped by sig %d (exitcode %d)\n",
2498                                         childpid, WSTOPSIG(status), WEXITSTATUS(status));
2499                 if (WIFSIGNALED(status))
2500                         debug_printf_jobs("pid %d killed by sig %d (exitcode %d)\n",
2501                                         childpid, WTERMSIG(status), WEXITSTATUS(status));
2502                 if (WIFEXITED(status))
2503                         debug_printf_jobs("pid %d exited, exitcode %d\n",
2504                                         childpid, WEXITSTATUS(status));
2505 #endif
2506                 /* Were we asked to wait for fg pipe? */
2507                 if (fg_pipe) {
2508                         for (i = 0; i < fg_pipe->num_cmds; i++) {
2509                                 debug_printf_jobs("check pid %d\n", fg_pipe->cmds[i].pid);
2510                                 if (fg_pipe->cmds[i].pid != childpid)
2511                                         continue;
2512                                 /* printf("process %d exit %d\n", i, WEXITSTATUS(status)); */
2513                                 if (dead) {
2514                                         fg_pipe->cmds[i].pid = 0;
2515                                         fg_pipe->alive_cmds--;
2516                                         if (i == fg_pipe->num_cmds - 1) {
2517                                                 /* last process gives overall exitstatus */
2518                                                 rcode = WEXITSTATUS(status);
2519                                                 IF_HAS_KEYWORDS(if (fg_pipe->pi_inverted) rcode = !rcode;)
2520                                         }
2521                                 } else {
2522                                         fg_pipe->cmds[i].is_stopped = 1;
2523                                         fg_pipe->stopped_cmds++;
2524                                 }
2525                                 debug_printf_jobs("fg_pipe: alive_cmds %d stopped_cmds %d\n",
2526                                                 fg_pipe->alive_cmds, fg_pipe->stopped_cmds);
2527                                 if (fg_pipe->alive_cmds - fg_pipe->stopped_cmds <= 0) {
2528                                         /* All processes in fg pipe have exited/stopped */
2529 #if ENABLE_HUSH_JOB
2530                                         if (fg_pipe->alive_cmds)
2531                                                 insert_bg_job(fg_pipe);
2532 #endif
2533                                         return rcode;
2534                                 }
2535                                 /* There are still running processes in the fg pipe */
2536                                 goto wait_more; /* do waitpid again */
2537                         }
2538                         /* it wasnt fg_pipe, look for process in bg pipes */
2539                 }
2540
2541 #if ENABLE_HUSH_JOB
2542                 /* We asked to wait for bg or orphaned children */
2543                 /* No need to remember exitcode in this case */
2544                 for (pi = G.job_list; pi; pi = pi->next) {
2545                         for (i = 0; i < pi->num_cmds; i++) {
2546                                 if (pi->cmds[i].pid == childpid)
2547                                         goto found_pi_and_prognum;
2548                         }
2549                 }
2550                 /* Happens when shell is used as init process (init=/bin/sh) */
2551                 debug_printf("checkjobs: pid %d was not in our list!\n", childpid);
2552                 continue; /* do waitpid again */
2553
2554  found_pi_and_prognum:
2555                 if (dead) {
2556                         /* child exited */
2557                         pi->cmds[i].pid = 0;
2558                         pi->alive_cmds--;
2559                         if (!pi->alive_cmds) {
2560                                 if (G_interactive_fd)
2561                                         printf(JOB_STATUS_FORMAT, pi->jobid,
2562                                                         "Done", pi->cmdtext);
2563                                 delete_finished_bg_job(pi);
2564                         }
2565                 } else {
2566                         /* child stopped */
2567                         pi->cmds[i].is_stopped = 1;
2568                         pi->stopped_cmds++;
2569                 }
2570 #endif
2571         } /* while (waitpid succeeds)... */
2572
2573         return rcode;
2574 }
2575
2576 #if ENABLE_HUSH_JOB
2577 static int checkjobs_and_fg_shell(struct pipe* fg_pipe)
2578 {
2579         pid_t p;
2580         int rcode = checkjobs(fg_pipe);
2581         /* Job finished, move the shell to the foreground */
2582         p = getpgid(0); /* pgid of our process */
2583         debug_printf_jobs("fg'ing ourself: getpgid(0)=%d\n", (int)p);
2584         tcsetpgrp(G_interactive_fd, p);
2585         return rcode;
2586 }
2587 #endif
2588
2589 /* run_pipe() starts all the jobs, but doesn't wait for anything
2590  * to finish.  See checkjobs().
2591  *
2592  * return code is normally -1, when the caller has to wait for children
2593  * to finish to determine the exit status of the pipe.  If the pipe
2594  * is a simple builtin command, however, the action is done by the
2595  * time run_pipe returns, and the exit code is provided as the
2596  * return value.
2597  *
2598  * The input of the pipe is always stdin, the output is always
2599  * stdout.  The outpipe[] mechanism in BusyBox-0.48 lash is bogus,
2600  * because it tries to avoid running the command substitution in
2601  * subshell, when that is in fact necessary.  The subshell process
2602  * now has its stdout directed to the input of the appropriate pipe,
2603  * so this routine is noticeably simpler.
2604  *
2605  * Returns -1 only if started some children. IOW: we have to
2606  * mask out retvals of builtins etc with 0xff!
2607  */
2608 static int run_pipe(struct pipe *pi)
2609 {
2610         int i;
2611         int nextin;
2612         int pipefds[2];         /* pipefds[0] is for reading */
2613         struct command *command;
2614         char **argv_expanded;
2615         char **argv;
2616         const struct built_in_command *x;
2617         char *p;
2618         /* it is not always needed, but we aim to smaller code */
2619         int squirrel[] = { -1, -1, -1 };
2620         int rcode;
2621         const int single_and_fg = (pi->num_cmds == 1 && pi->followup != PIPE_BG);
2622
2623         debug_printf_exec("run_pipe start: single_and_fg=%d\n", single_and_fg);
2624
2625 #if ENABLE_HUSH_JOB
2626         pi->pgrp = -1;
2627 #endif
2628         pi->alive_cmds = 1;
2629         pi->stopped_cmds = 0;
2630
2631         /* Check if this is a simple builtin (not part of a pipe).
2632          * Builtins within pipes have to fork anyway, and are handled in
2633          * pseudo_exec.  "echo foo | read bar" doesn't work on bash, either.
2634          */
2635         command = &(pi->cmds[0]);
2636
2637 #if ENABLE_HUSH_FUNCTIONS
2638         if (single_and_fg && command->group && command->grp_type == GRP_FUNCTION) {
2639                 /* We "execute" function definition */
2640                 bb_error_msg("here we ought to remember function definition, and go on");
2641                 return EXIT_SUCCESS;
2642         }
2643 #endif
2644
2645         if (single_and_fg && command->group && command->grp_type == GRP_NORMAL) {
2646                 debug_printf("non-subshell grouping\n");
2647                 setup_redirects(command, squirrel);
2648                 debug_printf_exec(": run_list\n");
2649                 rcode = run_list(command->group) & 0xff;
2650                 restore_redirects(squirrel);
2651                 debug_printf_exec("run_pipe return %d\n", rcode);
2652                 IF_HAS_KEYWORDS(if (pi->pi_inverted) rcode = !rcode;)
2653                 return rcode;
2654         }
2655
2656         argv = command->argv;
2657         argv_expanded = NULL;
2658
2659         if (single_and_fg && argv != NULL) {
2660                 char **new_env = NULL;
2661                 char **old_env = NULL;
2662
2663                 i = command->assignment_cnt;
2664                 if (i != 0 && argv[i] == NULL) {
2665                         /* assignments, but no command: set local environment */
2666                         for (i = 0; argv[i] != NULL; i++) {
2667                                 debug_printf("local environment set: %s\n", argv[i]);
2668                                 p = expand_string_to_string(argv[i]);
2669                                 set_local_var(p, 0);
2670                         }
2671                         return EXIT_SUCCESS; /* don't worry about errors in set_local_var() yet */
2672                 }
2673
2674                 /* Expand the rest into (possibly) many strings each */
2675                 argv_expanded = expand_strvec_to_strvec(argv + i);
2676
2677                 for (x = bltins; x != &bltins[ARRAY_SIZE(bltins)]; x++) {
2678                         if (strcmp(argv_expanded[0], x->cmd) != 0)
2679                                 continue;
2680                         if (x->function == builtin_exec && argv_expanded[1] == NULL) {
2681                                 debug_printf("exec with redirects only\n");
2682                                 setup_redirects(command, NULL);
2683                                 rcode = EXIT_SUCCESS;
2684                                 goto clean_up_and_ret1;
2685                         }
2686                         debug_printf("builtin inline %s\n", argv_expanded[0]);
2687                         /* XXX setup_redirects acts on file descriptors, not FILEs.
2688                          * This is perfect for work that comes after exec().
2689                          * Is it really safe for inline use?  Experimentally,
2690                          * things seem to work with glibc. */
2691                         setup_redirects(command, squirrel);
2692                         new_env = expand_assignments(argv, command->assignment_cnt);
2693                         old_env = putenv_all_and_save_old(new_env);
2694                         debug_printf_exec(": builtin '%s' '%s'...\n", x->cmd, argv_expanded[1]);
2695                         rcode = x->function(argv_expanded) & 0xff;
2696 #if ENABLE_FEATURE_SH_STANDALONE
2697  clean_up_and_ret:
2698 #endif
2699                         restore_redirects(squirrel);
2700                         free_strings_and_unsetenv(new_env, 1);
2701                         putenv_all(old_env);
2702                         free(old_env); /* not free_strings()! */
2703  clean_up_and_ret1:
2704                         free(argv_expanded);
2705                         IF_HAS_KEYWORDS(if (pi->pi_inverted) rcode = !rcode;)
2706                         debug_printf_exec("run_pipe return %d\n", rcode);
2707                         return rcode;
2708                 }
2709 #if ENABLE_FEATURE_SH_STANDALONE
2710                 i = find_applet_by_name(argv_expanded[0]);
2711                 if (i >= 0 && APPLET_IS_NOFORK(i)) {
2712                         setup_redirects(command, squirrel);
2713                         save_nofork_data(&G.nofork_save);
2714                         new_env = expand_assignments(argv, command->assignment_cnt);
2715                         old_env = putenv_all_and_save_old(new_env);
2716                         debug_printf_exec(": run_nofork_applet '%s' '%s'...\n", argv_expanded[0], argv_expanded[1]);
2717                         rcode = run_nofork_applet_prime(&G.nofork_save, i, argv_expanded);
2718                         goto clean_up_and_ret;
2719                 }
2720 #endif
2721         }
2722
2723         /* NB: argv_expanded may already be created, and that
2724          * might include `cmd` runs! Do not rerun it! We *must*
2725          * use argv_expanded if it's non-NULL */
2726
2727         /* Going to fork a child per each pipe member */
2728         pi->alive_cmds = 0;
2729         nextin = 0;
2730
2731         for (i = 0; i < pi->num_cmds; i++) {
2732 #if !BB_MMU
2733                 volatile nommu_save_t nommu_save;
2734                 nommu_save.new_env = NULL;
2735                 nommu_save.old_env = NULL;
2736                 nommu_save.argv = NULL;
2737 #endif
2738                 command = &(pi->cmds[i]);
2739                 if (command->argv) {
2740                         debug_printf_exec(": pipe member '%s' '%s'...\n", command->argv[0], command->argv[1]);
2741                 } else
2742                         debug_printf_exec(": pipe member with no argv\n");
2743
2744                 /* pipes are inserted between pairs of commands */
2745                 pipefds[0] = 0;
2746                 pipefds[1] = 1;
2747                 if ((i + 1) < pi->num_cmds)
2748                         xpipe(pipefds);
2749
2750                 command->pid = BB_MMU ? fork() : vfork();
2751                 if (!command->pid) { /* child */
2752 #if ENABLE_HUSH_JOB
2753                         die_sleep = 0; /* let nofork's xfuncs die */
2754
2755                         /* Every child adds itself to new process group
2756                          * with pgid == pid_of_first_child_in_pipe */
2757                         if (G.run_list_level == 1 && G_interactive_fd) {
2758                                 pid_t pgrp;
2759                                 pgrp = pi->pgrp;
2760                                 if (pgrp < 0) /* true for 1st process only */
2761                                         pgrp = getpid();
2762                                 if (setpgid(0, pgrp) == 0 && pi->followup != PIPE_BG) {
2763                                         /* We do it in *every* child, not just first,
2764                                          * to avoid races */
2765                                         tcsetpgrp(G_interactive_fd, pgrp);
2766                                 }
2767                         }
2768 #endif
2769                         xmove_fd(nextin, 0);
2770                         xmove_fd(pipefds[1], 1); /* write end */
2771                         if (pipefds[0] > 1)
2772                                 close(pipefds[0]); /* read end */
2773                         /* Like bash, explicit redirects override pipes,
2774                          * and the pipe fd is available for dup'ing. */
2775                         setup_redirects(command, NULL);
2776
2777                         /* Restore default handlers just prior to exec */
2778                         /*signal(SIGCHLD, SIG_DFL); - so far we don't have any handlers */
2779
2780                         /* Stores to nommu_save list of env vars putenv'ed
2781                          * (NOMMU, on MMU we don't need that) */
2782                         /* cast away volatility... */
2783                         pseudo_exec((nommu_save_t*) &nommu_save, command, argv_expanded);
2784                         /* pseudo_exec() does not return */
2785                 }
2786                 /* parent */
2787 #if !BB_MMU
2788                 /* Clean up after vforked child */
2789                 free(nommu_save.argv);
2790                 free_strings_and_unsetenv(nommu_save.new_env, 1);
2791                 putenv_all(nommu_save.old_env);
2792 #endif
2793                 free(argv_expanded);
2794                 argv_expanded = NULL;
2795                 if (command->pid < 0) { /* [v]fork failed */
2796                         /* Clearly indicate, was it fork or vfork */
2797                         bb_perror_msg(BB_MMU ? "fork" : "vfork");
2798                 } else {
2799                         pi->alive_cmds++;
2800 #if ENABLE_HUSH_JOB
2801                         /* Second and next children need to know pid of first one */
2802                         if (pi->pgrp < 0)
2803                                 pi->pgrp = command->pid;
2804 #endif
2805                 }
2806
2807                 if (i)
2808                         close(nextin);
2809                 if ((i + 1) < pi->num_cmds)
2810                         close(pipefds[1]); /* write end */
2811                 /* Pass read (output) pipe end to next iteration */
2812                 nextin = pipefds[0];
2813         }
2814
2815         if (!pi->alive_cmds) {
2816                 debug_printf_exec("run_pipe return 1 (all forks failed, no children)\n");
2817                 return 1;
2818         }
2819
2820         debug_printf_exec("run_pipe return -1 (%u children started)\n", pi->alive_cmds);
2821         return -1;
2822 }
2823
2824 #ifndef debug_print_tree
2825 static void debug_print_tree(struct pipe *pi, int lvl)
2826 {
2827         static const char *const PIPE[] = {
2828                 [PIPE_SEQ] = "SEQ",
2829                 [PIPE_AND] = "AND",
2830                 [PIPE_OR ] = "OR" ,
2831                 [PIPE_BG ] = "BG" ,
2832         };
2833         static const char *RES[] = {
2834                 [RES_NONE ] = "NONE" ,
2835 #if ENABLE_HUSH_IF
2836                 [RES_IF   ] = "IF"   ,
2837                 [RES_THEN ] = "THEN" ,
2838                 [RES_ELIF ] = "ELIF" ,
2839                 [RES_ELSE ] = "ELSE" ,
2840                 [RES_FI   ] = "FI"   ,
2841 #endif
2842 #if ENABLE_HUSH_LOOPS
2843                 [RES_FOR  ] = "FOR"  ,
2844                 [RES_WHILE] = "WHILE",
2845                 [RES_UNTIL] = "UNTIL",
2846                 [RES_DO   ] = "DO"   ,
2847                 [RES_DONE ] = "DONE" ,
2848 #endif
2849 #if ENABLE_HUSH_LOOPS || ENABLE_HUSH_CASE
2850                 [RES_IN   ] = "IN"   ,
2851 #endif
2852 #if ENABLE_HUSH_CASE
2853                 [RES_CASE ] = "CASE" ,
2854                 [RES_MATCH] = "MATCH",
2855                 [RES_CASEI] = "CASEI",
2856                 [RES_ESAC ] = "ESAC" ,
2857 #endif
2858                 [RES_XXXX ] = "XXXX" ,
2859                 [RES_SNTX ] = "SNTX" ,
2860         };
2861         static const char *const GRPTYPE[] = {
2862                 "()",
2863                 "{}",
2864 #if ENABLE_HUSH_FUNCTIONS
2865                 "func()",
2866 #endif
2867         };
2868
2869         int pin, prn;
2870
2871         pin = 0;
2872         while (pi) {
2873                 fprintf(stderr, "%*spipe %d res_word=%s followup=%d %s\n", lvl*2, "",
2874                                 pin, RES[pi->res_word], pi->followup, PIPE[pi->followup]);
2875                 prn = 0;
2876                 while (prn < pi->num_cmds) {
2877                         struct command *command = &pi->cmds[prn];
2878                         char **argv = command->argv;
2879
2880                         fprintf(stderr, "%*s prog %d assignment_cnt:%d", lvl*2, "", prn, command->assignment_cnt);
2881                         if (command->group) {
2882                                 fprintf(stderr, " group %s: (argv=%p)\n",
2883                                                 GRPTYPE[command->grp_type],
2884                                                 argv);
2885                                 debug_print_tree(command->group, lvl+1);
2886                                 prn++;
2887                                 continue;
2888                         }
2889                         if (argv) while (*argv) {
2890                                 fprintf(stderr, " '%s'", *argv);
2891                                 argv++;
2892                         }
2893                         fprintf(stderr, "\n");
2894                         prn++;
2895                 }
2896                 pi = pi->next;
2897                 pin++;
2898         }
2899 }
2900 #endif
2901
2902 /* NB: called by pseudo_exec, and therefore must not modify any
2903  * global data until exec/_exit (we can be a child after vfork!) */
2904 static int run_list(struct pipe *pi)
2905 {
2906 #if ENABLE_HUSH_CASE
2907         char *case_word = NULL;
2908 #endif
2909 #if ENABLE_HUSH_LOOPS
2910         struct pipe *loop_top = NULL;
2911         char *for_varname = NULL;
2912         char **for_lcur = NULL;
2913         char **for_list = NULL;
2914 #endif
2915         smallint flag_skip = 1;
2916         smalluint rcode = 0; /* probably just for compiler */
2917 #if ENABLE_HUSH_IF || ENABLE_HUSH_CASE
2918         smalluint cond_code = 0;
2919 #else
2920         enum { cond_code = 0, };
2921 #endif
2922         /*enum reserved_style*/ smallint rword = RES_NONE;
2923         /*enum reserved_style*/ smallint skip_more_for_this_rword = RES_XXXX;
2924
2925         debug_printf_exec("run_list start lvl %d\n", G.run_list_level + 1);
2926
2927 #if ENABLE_HUSH_LOOPS
2928         /* Check syntax for "for" */
2929         for (struct pipe *cpipe = pi; cpipe; cpipe = cpipe->next) {
2930                 if (cpipe->res_word != RES_FOR && cpipe->res_word != RES_IN)
2931                         continue;
2932                 /* current word is FOR or IN (BOLD in comments below) */
2933                 if (cpipe->next == NULL) {
2934                         syntax("malformed for");
2935                         debug_printf_exec("run_list lvl %d return 1\n", G.run_list_level);
2936                         return 1;
2937                 }
2938                 /* "FOR v; do ..." and "for v IN a b; do..." are ok */
2939                 if (cpipe->next->res_word == RES_DO)
2940                         continue;
2941                 /* next word is not "do". It must be "in" then ("FOR v in ...") */
2942                 if (cpipe->res_word == RES_IN /* "for v IN a b; not_do..."? */
2943                  || cpipe->next->res_word != RES_IN /* FOR v not_do_and_not_in..."? */
2944                 ) {
2945                         syntax("malformed for");
2946                         debug_printf_exec("run_list lvl %d return 1\n", G.run_list_level);
2947                         return 1;
2948                 }
2949         }
2950 #endif
2951
2952         /* Past this point, all code paths should jump to ret: label
2953          * in order to return, no direct "return" statements please.
2954          * This helps to ensure that no memory is leaked. */
2955
2956 ////TODO: ctrl-Z handling needs re-thinking and re-testing
2957
2958 #if ENABLE_HUSH_JOB
2959         /* Example of nested list: "while true; do { sleep 1 | exit 2; } done".
2960          * We are saving state before entering outermost list ("while...done")
2961          * so that ctrl-Z will correctly background _entire_ outermost list,
2962          * not just a part of it (like "sleep 1 | exit 2") */
2963         if (++G.run_list_level == 1 && G_interactive_fd) {
2964                 if (sigsetjmp(G.toplevel_jb, 1)) {
2965                         /* ctrl-Z forked and we are parent; or ctrl-C.
2966                          * Sighandler has longjmped us here */
2967                         signal(SIGINT, SIG_IGN);
2968                         signal(SIGTSTP, SIG_IGN);
2969                         /* Restore level (we can be coming from deep inside
2970                          * nested levels) */
2971                         G.run_list_level = 1;
2972 #if ENABLE_FEATURE_SH_STANDALONE
2973                         if (G.nofork_save.saved) { /* if save area is valid */
2974                                 debug_printf_jobs("exiting nofork early\n");
2975                                 restore_nofork_data(&G.nofork_save);
2976                         }
2977 #endif
2978 ////                    if (G.ctrl_z_flag) {
2979 ////                            /* ctrl-Z has forked and stored pid of the child in pi->pid.
2980 ////                             * Remember this child as background job */
2981 ////                            insert_bg_job(pi);
2982 ////                    } else {
2983                                 /* ctrl-C. We just stop doing whatever we were doing */
2984                                 bb_putchar('\n');
2985 ////                    }
2986                         USE_HUSH_LOOPS(loop_top = NULL;)
2987                         USE_HUSH_LOOPS(G.depth_of_loop = 0;)
2988                         rcode = 0;
2989                         goto ret;
2990                 }
2991 ////            /* ctrl-Z handler will store pid etc in pi */
2992 ////            G.toplevel_list = pi;
2993 ////            G.ctrl_z_flag = 0;
2994 ////#if ENABLE_FEATURE_SH_STANDALONE
2995 ////            G.nofork_save.saved = 0; /* in case we will run a nofork later */
2996 ////#endif
2997 ////            signal_SA_RESTART_empty_mask(SIGTSTP, handler_ctrl_z);
2998 ////            signal(SIGINT, handler_ctrl_c);
2999         }
3000 #endif /* JOB */
3001
3002         /* Go through list of pipes, (maybe) executing them. */
3003         for (; pi; pi = USE_HUSH_LOOPS(rword == RES_DONE ? loop_top : ) pi->next) {
3004                 if (G.flag_SIGINT)
3005                         break;
3006
3007                 IF_HAS_KEYWORDS(rword = pi->res_word;)
3008                 IF_HAS_NO_KEYWORDS(rword = RES_NONE;)
3009                 debug_printf_exec(": rword=%d cond_code=%d skip_more=%d\n",
3010                                 rword, cond_code, skip_more_for_this_rword);
3011 #if ENABLE_HUSH_LOOPS
3012                 if ((rword == RES_WHILE || rword == RES_UNTIL || rword == RES_FOR)
3013                  && loop_top == NULL /* avoid bumping G.depth_of_loop twice */
3014                 ) {
3015                         /* start of a loop: remember where loop starts */
3016                         loop_top = pi;
3017                         G.depth_of_loop++;
3018                 }
3019 #endif
3020                 if (rword == skip_more_for_this_rword && flag_skip) {
3021                         if (pi->followup == PIPE_SEQ)
3022                                 flag_skip = 0;
3023                         /* it is "<false> && CMD" or "<true> || CMD"
3024                          * and we should not execute CMD */
3025                         continue;
3026                 }
3027                 flag_skip = 1;
3028                 skip_more_for_this_rword = RES_XXXX;
3029 #if ENABLE_HUSH_IF
3030                 if (cond_code) {
3031                         if (rword == RES_THEN) {
3032                                 /* "if <false> THEN cmd": skip cmd */
3033                                 continue;
3034                         }
3035                 } else {
3036                         if (rword == RES_ELSE || rword == RES_ELIF) {
3037                                 /* "if <true> then ... ELSE/ELIF cmd":
3038                                  * skip cmd and all following ones */
3039                                 break;
3040                         }
3041                 }
3042 #endif
3043 #if ENABLE_HUSH_LOOPS
3044                 if (rword == RES_FOR) { /* && pi->num_cmds - always == 1 */
3045                         if (!for_lcur) {
3046                                 /* first loop through for */
3047
3048                                 static const char encoded_dollar_at[] ALIGN1 = {
3049                                         SPECIAL_VAR_SYMBOL, '@' | 0x80, SPECIAL_VAR_SYMBOL, '\0'
3050                                 }; /* encoded representation of "$@" */
3051                                 static const char *const encoded_dollar_at_argv[] = {
3052                                         encoded_dollar_at, NULL
3053                                 }; /* argv list with one element: "$@" */
3054                                 char **vals;
3055
3056                                 vals = (char**)encoded_dollar_at_argv;
3057                                 if (pi->next->res_word == RES_IN) {
3058                                         /* if no variable values after "in" we skip "for" */
3059                                         if (!pi->next->cmds[0].argv)
3060                                                 break;
3061                                         vals = pi->next->cmds[0].argv;
3062                                 } /* else: "for var; do..." -> assume "$@" list */
3063                                 /* create list of variable values */
3064                                 debug_print_strings("for_list made from", vals);
3065                                 for_list = expand_strvec_to_strvec(vals);
3066                                 for_lcur = for_list;
3067                                 debug_print_strings("for_list", for_list);
3068                                 for_varname = pi->cmds[0].argv[0];
3069                                 pi->cmds[0].argv[0] = NULL;
3070                         }
3071                         free(pi->cmds[0].argv[0]);
3072                         if (!*for_lcur) {
3073                                 /* "for" loop is over, clean up */
3074                                 free(for_list);
3075                                 for_list = NULL;
3076                                 for_lcur = NULL;
3077                                 pi->cmds[0].argv[0] = for_varname;
3078                                 break;
3079                         }
3080                         /* insert next value from for_lcur */
3081 //TODO: does it need escaping?
3082                         pi->cmds[0].argv[0] = xasprintf("%s=%s", for_varname, *for_lcur++);
3083                         pi->cmds[0].assignment_cnt = 1;
3084                 }
3085                 if (rword == RES_IN) /* "for v IN list;..." - "in" has no cmds anyway */
3086                         continue;
3087                 if (rword == RES_DONE) {
3088                         continue; /* "done" has no cmds too */
3089                 }
3090 #endif
3091 #if ENABLE_HUSH_CASE
3092                 if (rword == RES_CASE) {
3093                         case_word = expand_strvec_to_string(pi->cmds->argv);
3094                         continue;
3095                 }
3096                 if (rword == RES_MATCH) {
3097                         char **argv;
3098
3099                         if (!case_word) /* "case ... matched_word) ... WORD)": we executed selected branch, stop */
3100                                 break;
3101                         /* all prev words didn't match, does this one match? */
3102                         argv = pi->cmds->argv;
3103                         while (*argv) {
3104                                 char *pattern = expand_string_to_string(*argv);
3105                                 /* TODO: which FNM_xxx flags to use? */
3106                                 cond_code = (fnmatch(pattern, case_word, /*flags:*/ 0) != 0);
3107                                 free(pattern);
3108                                 if (cond_code == 0) { /* match! we will execute this branch */
3109                                         free(case_word); /* make future "word)" stop */
3110                                         case_word = NULL;
3111                                         break;
3112                                 }
3113                                 argv++;
3114                         }
3115                         continue;
3116                 }
3117                 if (rword == RES_CASEI) { /* inside of a case branch */
3118                         if (cond_code != 0)
3119                                 continue; /* not matched yet, skip this pipe */
3120                 }
3121 #endif
3122                 /* Just pressing <enter> in shell should check for jobs.
3123                  * OTOH, in non-interactive shell this is useless
3124                  * and only leads to extra job checks */
3125                 if (pi->num_cmds == 0) {
3126                         if (G_interactive_fd)
3127                                 goto check_jobs_and_continue;
3128                         continue;
3129                 }
3130
3131                 /* After analyzing all keywords and conditions, we decided
3132                  * to execute this pipe. NB: have to do checkjobs(NULL)
3133                  * after run_pipe() to collect any background children,
3134                  * even if list execution is to be stopped. */
3135                 debug_printf_exec(": run_pipe with %d members\n", pi->num_cmds);
3136                 {
3137                         int r;
3138 #if ENABLE_HUSH_LOOPS
3139                         G.flag_break_continue = 0;
3140 #endif
3141                         rcode = r = run_pipe(pi); /* NB: rcode is a smallint */
3142                         if (r != -1) {
3143                                 /* we only ran a builtin: rcode is already known
3144                                  * and we don't need to wait for anything. */
3145                                 check_and_run_traps(0);
3146 #if ENABLE_HUSH_LOOPS
3147                                 /* was it "break" or "continue"? */
3148                                 if (G.flag_break_continue) {
3149                                         smallint fbc = G.flag_break_continue;
3150                                         /* we might fall into outer *loop*,
3151                                          * don't want to break it too */
3152                                         if (loop_top) {
3153                                                 G.depth_break_continue--;
3154                                                 if (G.depth_break_continue == 0)
3155                                                         G.flag_break_continue = 0;
3156                                                 /* else: e.g. "continue 2" should *break* once, *then* continue */
3157                                         } /* else: "while... do... { we are here (innermost list is not a loop!) };...done" */
3158                                         if (G.depth_break_continue != 0 || fbc == BC_BREAK)
3159                                                 goto check_jobs_and_break;
3160                                         /* "continue": simulate end of loop */
3161                                         rword = RES_DONE;
3162                                         continue;
3163                                 }
3164 #endif
3165                         } else if (pi->followup == PIPE_BG) {
3166                                 /* what does bash do with attempts to background builtins? */
3167                                 /* even bash 3.2 doesn't do that well with nested bg:
3168                                  * try "{ { sleep 10; echo DEEP; } & echo HERE; } &".
3169                                  * I'm NOT treating inner &'s as jobs */
3170                                 check_and_run_traps(0);
3171 #if ENABLE_HUSH_JOB
3172                                 if (G.run_list_level == 1)
3173                                         insert_bg_job(pi);
3174 #endif
3175                                 rcode = 0; /* EXIT_SUCCESS */
3176                         } else {
3177 #if ENABLE_HUSH_JOB
3178                                 if (G.run_list_level == 1 && G_interactive_fd) {
3179                                         /* waits for completion, then fg's main shell */
3180                                         rcode = checkjobs_and_fg_shell(pi);
3181                                         check_and_run_traps(0);
3182                                         debug_printf_exec(": checkjobs_and_fg_shell returned %d\n", rcode);
3183                                 } else
3184 #endif
3185                                 { /* this one just waits for completion */
3186                                         rcode = checkjobs(pi);
3187                                         check_and_run_traps(0);
3188                                         debug_printf_exec(": checkjobs returned %d\n", rcode);
3189                                 }
3190                         }
3191                 }
3192                 debug_printf_exec(": setting last_return_code=%d\n", rcode);
3193                 G.last_return_code = rcode;
3194
3195                 /* Analyze how result affects subsequent commands */
3196 #if ENABLE_HUSH_IF
3197                 if (rword == RES_IF || rword == RES_ELIF)
3198                         cond_code = rcode;
3199 #endif
3200 #if ENABLE_HUSH_LOOPS
3201                 if (rword == RES_WHILE) {
3202                         if (rcode) {
3203                                 rcode = 0; /* "while false; do...done" - exitcode 0 */
3204                                 goto check_jobs_and_break;
3205                         }
3206                 }
3207                 if (rword == RES_UNTIL) {
3208                         if (!rcode) {
3209  check_jobs_and_break:
3210                                 checkjobs(NULL);
3211                                 break;
3212                         }
3213                 }
3214 #endif
3215                 if ((rcode == 0 && pi->followup == PIPE_OR)
3216                  || (rcode != 0 && pi->followup == PIPE_AND)
3217                 ) {
3218                         skip_more_for_this_rword = rword;
3219                 }
3220
3221  check_jobs_and_continue:
3222                 checkjobs(NULL);
3223         } /* for (pi) */
3224
3225 #if ENABLE_HUSH_JOB
3226 ////    if (G.ctrl_z_flag) {
3227 ////            /* ctrl-Z forked somewhere in the past, we are the child,
3228 ////             * and now we completed running the list. Exit. */
3229 //////TODO: _exit?
3230 ////            exit(rcode);
3231 ////    }
3232  ret:
3233         G.run_list_level--;
3234 ////    if (!G.run_list_level && G_interactive_fd) {
3235 ////            signal(SIGTSTP, SIG_IGN);
3236 ////            signal(SIGINT, SIG_IGN);
3237 ////    }
3238 #endif
3239         debug_printf_exec("run_list lvl %d return %d\n", G.run_list_level + 1, rcode);
3240 #if ENABLE_HUSH_LOOPS
3241         if (loop_top)
3242                 G.depth_of_loop--;
3243         free(for_list);
3244 #endif
3245 #if ENABLE_HUSH_CASE
3246         free(case_word);
3247 #endif
3248         return rcode;
3249 }
3250
3251 /* Select which version we will use */
3252 static int run_and_free_list(struct pipe *pi)
3253 {
3254         int rcode = 0;
3255         debug_printf_exec("run_and_free_list entered\n");
3256         if (!G.fake_mode) {
3257                 debug_printf_exec(": run_list with %d members\n", pi->num_cmds);
3258                 rcode = run_list(pi);
3259         }
3260         /* free_pipe_list has the side effect of clearing memory.
3261          * In the long run that function can be merged with run_list,
3262          * but doing that now would hobble the debugging effort. */
3263         free_pipe_list(pi, /* indent: */ 0);
3264         debug_printf_exec("run_and_free_list return %d\n", rcode);
3265         return rcode;
3266 }
3267
3268
3269 /* Peek ahead in the in_str to find out if we have a "&n" construct,
3270  * as in "2>&1", that represents duplicating a file descriptor.
3271  * Return either -2 (syntax error), -1 (no &), or the number found.
3272  */
3273 static int redirect_dup_num(struct in_str *input)
3274 {
3275         int ch, d = 0, ok = 0;
3276         ch = i_peek(input);
3277         if (ch != '&') return -1;
3278
3279         i_getch(input);  /* get the & */
3280         ch = i_peek(input);
3281         if (ch == '-') {
3282                 i_getch(input);
3283                 return -3;  /* "-" represents "close me" */
3284         }
3285         while (isdigit(ch)) {
3286                 d = d*10 + (ch-'0');
3287                 ok = 1;
3288                 i_getch(input);
3289                 ch = i_peek(input);
3290         }
3291         if (ok) return d;
3292
3293         bb_error_msg("ambiguous redirect");
3294         return -2;
3295 }
3296
3297 /* The src parameter allows us to peek forward to a possible &n syntax
3298  * for file descriptor duplication, e.g., "2>&1".
3299  * Return code is 0 normally, 1 if a syntax error is detected in src.
3300  * Resource errors (in xmalloc) cause the process to exit */
3301 static int setup_redirect(struct parse_context *ctx,
3302                 int fd,
3303                 redir_type style,
3304                 struct in_str *input)
3305 {
3306         struct command *command = ctx->command;
3307         struct redir_struct *redir;
3308         struct redir_struct **redirp;
3309         int dup_num;
3310
3311         /* Check for a '2>&1' type redirect */
3312         dup_num = redirect_dup_num(input);
3313         if (dup_num == -2)
3314                 return 1;  /* syntax error */
3315
3316         /* Create a new redir_struct and drop it onto the end of the linked list */
3317         redirp = &command->redirects;
3318         while ((redir = *redirp) != NULL) {
3319                 redirp = &(redir->next);
3320         }
3321         *redirp = redir = xzalloc(sizeof(*redir));
3322         /* redir->next = NULL; */
3323         /* redir->rd_filename = NULL; */
3324         redir->rd_type = style;
3325         redir->fd = (fd == -1) ? redir_table[style].default_fd : fd;
3326
3327         debug_printf("Redirect type %d%s\n", redir->fd, redir_table[style].descrip);
3328
3329         redir->dup = dup_num;
3330         if (dup_num != -1) {
3331                 /* Erik had a check here that the file descriptor in question
3332                  * is legit; I postpone that to "run time"
3333                  * A "-" representation of "close me" shows up as a -3 here */
3334                 debug_printf("Duplicating redirect '%d>&%d'\n", redir->fd, redir->dup);
3335         } else {
3336                 /* We do _not_ try to open the file that src points to,
3337                  * since we need to return and let src be expanded first.
3338                  * Set ctx->pending_redirect, so we know what to do at the
3339                  * end of the next parsed word. */
3340                 ctx->pending_redirect = redir;
3341         }
3342         return 0;
3343 }
3344
3345
3346 static struct pipe *new_pipe(void)
3347 {
3348         struct pipe *pi;
3349         pi = xzalloc(sizeof(struct pipe));
3350         /*pi->followup = 0; - deliberately invalid value */
3351         /*pi->res_word = RES_NONE; - RES_NONE is 0 anyway */
3352         return pi;
3353 }
3354
3355 /* Command (member of a pipe) is complete. The only possible error here
3356  * is out of memory, in which case xmalloc exits. */
3357 static int done_command(struct parse_context *ctx)
3358 {
3359         /* The command is really already in the pipe structure, so
3360          * advance the pipe counter and make a new, null command. */
3361         struct pipe *pi = ctx->pipe;
3362         struct command *command = ctx->command;
3363
3364         if (command) {
3365                 if (command->group == NULL
3366                  && command->argv == NULL
3367                  && command->redirects == NULL
3368                 ) {
3369                         debug_printf_parse("done_command: skipping null cmd, num_cmds=%d\n", pi->num_cmds);
3370                         return pi->num_cmds;
3371                 }
3372                 pi->num_cmds++;
3373                 debug_printf_parse("done_command: ++num_cmds=%d\n", pi->num_cmds);
3374         } else {
3375                 debug_printf_parse("done_command: initializing, num_cmds=%d\n", pi->num_cmds);
3376         }
3377
3378         /* Only real trickiness here is that the uncommitted
3379          * command structure is not counted in pi->num_cmds. */
3380         pi->cmds = xrealloc(pi->cmds, sizeof(*pi->cmds) * (pi->num_cmds+1));
3381         command = &pi->cmds[pi->num_cmds];
3382         memset(command, 0, sizeof(*command));
3383
3384         ctx->command = command;
3385         /* but ctx->pipe and ctx->list_head remain unchanged */
3386
3387         return pi->num_cmds; /* used only for 0/nonzero check */
3388 }
3389
3390 static void done_pipe(struct parse_context *ctx, pipe_style type)
3391 {
3392         int not_null;
3393
3394         debug_printf_parse("done_pipe entered, followup %d\n", type);
3395         /* Close previous command */
3396         not_null = done_command(ctx);
3397         ctx->pipe->followup = type;
3398         IF_HAS_KEYWORDS(ctx->pipe->pi_inverted = ctx->ctx_inverted;)
3399         IF_HAS_KEYWORDS(ctx->ctx_inverted = 0;)
3400         IF_HAS_KEYWORDS(ctx->pipe->res_word = ctx->ctx_res_w;)
3401
3402         /* Without this check, even just <enter> on command line generates
3403          * tree of three NOPs (!). Which is harmless but annoying.
3404          * IOW: it is safe to do it unconditionally.
3405          * RES_NONE case is for "for a in; do ..." (empty IN set)
3406          * to work, possibly other cases too. */
3407         if (not_null IF_HAS_KEYWORDS(|| ctx->ctx_res_w != RES_NONE)) {
3408                 struct pipe *new_p;
3409                 debug_printf_parse("done_pipe: adding new pipe: "
3410                                 "not_null:%d ctx->ctx_res_w:%d\n",
3411                                 not_null, ctx->ctx_res_w);
3412                 new_p = new_pipe();
3413                 ctx->pipe->next = new_p;
3414                 ctx->pipe = new_p;
3415                 /* RES_THEN, RES_DO etc are "sticky" -
3416                  * they remain set for commands inside if/while.
3417                  * This is used to control execution.
3418                  * RES_FOR and RES_IN are NOT sticky (needed to support
3419                  * cases where variable or value happens to match a keyword):
3420                  */
3421 #if ENABLE_HUSH_LOOPS
3422                 if (ctx->ctx_res_w == RES_FOR
3423                  || ctx->ctx_res_w == RES_IN)
3424                         ctx->ctx_res_w = RES_NONE;
3425 #endif
3426 #if ENABLE_HUSH_CASE
3427                 if (ctx->ctx_res_w == RES_MATCH)
3428                         ctx->ctx_res_w = RES_CASEI;
3429 #endif
3430                 ctx->command = NULL; /* trick done_command below */
3431                 /* Create the memory for command, roughly:
3432                  * ctx->pipe->cmds = new struct command;
3433                  * ctx->command = &ctx->pipe->cmds[0];
3434                  */
3435                 done_command(ctx);
3436         }
3437         debug_printf_parse("done_pipe return\n");
3438 }
3439
3440 static void initialize_context(struct parse_context *ctx)
3441 {
3442         memset(ctx, 0, sizeof(*ctx));
3443         ctx->pipe = ctx->list_head = new_pipe();
3444         /* Create the memory for command, roughly:
3445          * ctx->pipe->cmds = new struct command;
3446          * ctx->command = &ctx->pipe->cmds[0];
3447          */
3448         done_command(ctx);
3449 }
3450
3451
3452 /* If a reserved word is found and processed, parse context is modified
3453  * and 1 is returned.
3454  */
3455 #if HAS_KEYWORDS
3456 struct reserved_combo {
3457         char literal[6];
3458         unsigned char res;
3459         unsigned char assignment_flag;
3460         int flag;
3461 };
3462 enum {
3463         FLAG_END   = (1 << RES_NONE ),
3464 #if ENABLE_HUSH_IF
3465         FLAG_IF    = (1 << RES_IF   ),
3466         FLAG_THEN  = (1 << RES_THEN ),
3467         FLAG_ELIF  = (1 << RES_ELIF ),
3468         FLAG_ELSE  = (1 << RES_ELSE ),
3469         FLAG_FI    = (1 << RES_FI   ),
3470 #endif
3471 #if ENABLE_HUSH_LOOPS
3472         FLAG_FOR   = (1 << RES_FOR  ),
3473         FLAG_WHILE = (1 << RES_WHILE),
3474         FLAG_UNTIL = (1 << RES_UNTIL),
3475         FLAG_DO    = (1 << RES_DO   ),
3476         FLAG_DONE  = (1 << RES_DONE ),
3477         FLAG_IN    = (1 << RES_IN   ),
3478 #endif
3479 #if ENABLE_HUSH_CASE
3480         FLAG_MATCH = (1 << RES_MATCH),
3481         FLAG_ESAC  = (1 << RES_ESAC ),
3482 #endif
3483         FLAG_START = (1 << RES_XXXX ),
3484 };
3485
3486 static const struct reserved_combo* match_reserved_word(o_string *word)
3487 {
3488         /* Mostly a list of accepted follow-up reserved words.
3489          * FLAG_END means we are done with the sequence, and are ready
3490          * to turn the compound list into a command.
3491          * FLAG_START means the word must start a new compound list.
3492          */
3493         static const struct reserved_combo reserved_list[] = {
3494 #if ENABLE_HUSH_IF
3495                 { "!",     RES_NONE,  NOT_ASSIGNMENT , 0 },
3496                 { "if",    RES_IF,    WORD_IS_KEYWORD, FLAG_THEN | FLAG_START },
3497                 { "then",  RES_THEN,  WORD_IS_KEYWORD, FLAG_ELIF | FLAG_ELSE | FLAG_FI },
3498                 { "elif",  RES_ELIF,  WORD_IS_KEYWORD, FLAG_THEN },
3499                 { "else",  RES_ELSE,  WORD_IS_KEYWORD, FLAG_FI   },
3500                 { "fi",    RES_FI,    NOT_ASSIGNMENT , FLAG_END  },
3501 #endif
3502 #if ENABLE_HUSH_LOOPS
3503                 { "for",   RES_FOR,   NOT_ASSIGNMENT , FLAG_IN | FLAG_DO | FLAG_START },
3504                 { "while", RES_WHILE, WORD_IS_KEYWORD, FLAG_DO | FLAG_START },
3505                 { "until", RES_UNTIL, WORD_IS_KEYWORD, FLAG_DO | FLAG_START },
3506                 { "in",    RES_IN,    NOT_ASSIGNMENT , FLAG_DO   },
3507                 { "do",    RES_DO,    WORD_IS_KEYWORD, FLAG_DONE },
3508                 { "done",  RES_DONE,  NOT_ASSIGNMENT , FLAG_END  },
3509 #endif
3510 #if ENABLE_HUSH_CASE
3511                 { "case",  RES_CASE,  NOT_ASSIGNMENT , FLAG_MATCH | FLAG_START },
3512                 { "esac",  RES_ESAC,  NOT_ASSIGNMENT , FLAG_END  },
3513 #endif
3514         };
3515         const struct reserved_combo *r;
3516
3517         for (r = reserved_list; r < reserved_list + ARRAY_SIZE(reserved_list); r++) {
3518                 if (strcmp(word->data, r->literal) == 0)
3519                         return r;
3520         }
3521         return NULL;
3522 }
3523 static int reserved_word(o_string *word, struct parse_context *ctx)
3524 {
3525 #if ENABLE_HUSH_CASE
3526         static const struct reserved_combo reserved_match = {
3527                 "",        RES_MATCH, NOT_ASSIGNMENT , FLAG_MATCH | FLAG_ESAC
3528         };
3529 #endif
3530         const struct reserved_combo *r;
3531
3532         r = match_reserved_word(word);
3533         if (!r)
3534                 return 0;
3535
3536         debug_printf("found reserved word %s, res %d\n", r->literal, r->res);
3537 #if ENABLE_HUSH_CASE
3538         if (r->res == RES_IN && ctx->ctx_res_w == RES_CASE)
3539                 /* "case word IN ..." - IN part starts first match part */
3540                 r = &reserved_match;
3541         else
3542 #endif
3543         if (r->flag == 0) { /* '!' */
3544                 if (ctx->ctx_inverted) { /* bash doesn't accept '! ! true' */
3545                         syntax("! ! command");
3546                         IF_HAS_KEYWORDS(ctx->ctx_res_w = RES_SNTX;)
3547                 }
3548                 ctx->ctx_inverted = 1;
3549                 return 1;
3550         }
3551         if (r->flag & FLAG_START) {
3552                 struct parse_context *old;
3553                 old = xmalloc(sizeof(*old));
3554                 debug_printf_parse("push stack %p\n", old);
3555                 *old = *ctx;   /* physical copy */
3556                 initialize_context(ctx);
3557                 ctx->stack = old;
3558         } else if (/*ctx->ctx_res_w == RES_NONE ||*/ !(ctx->old_flag & (1 << r->res))) {
3559                 syntax(word->data);
3560                 ctx->ctx_res_w = RES_SNTX;
3561                 return 1;
3562         }
3563         ctx->ctx_res_w = r->res;
3564         ctx->old_flag = r->flag;
3565         if (ctx->old_flag & FLAG_END) {
3566                 struct parse_context *old;
3567                 done_pipe(ctx, PIPE_SEQ);
3568                 debug_printf_parse("pop stack %p\n", ctx->stack);
3569                 old = ctx->stack;
3570                 old->command->group = ctx->list_head;
3571                 old->command->grp_type = GRP_NORMAL;
3572                 *ctx = *old;   /* physical copy */
3573                 free(old);
3574         }
3575         word->o_assignment = r->assignment_flag;
3576         return 1;
3577 }
3578 #endif
3579
3580 /* Word is complete, look at it and update parsing context.
3581  * Normal return is 0. Syntax errors return 1.
3582  * Note: on return, word is reset, but not o_free'd!
3583  */
3584 static int done_word(o_string *word, struct parse_context *ctx)
3585 {
3586         struct command *command = ctx->command;
3587
3588         debug_printf_parse("done_word entered: '%s' %p\n", word->data, command);
3589         if (word->length == 0 && word->nonnull == 0) {
3590                 debug_printf_parse("done_word return 0: true null, ignored\n");
3591                 return 0;
3592         }
3593         /* If this word wasn't an assignment, next ones definitely
3594          * can't be assignments. Even if they look like ones. */
3595         if (word->o_assignment != DEFINITELY_ASSIGNMENT
3596          && word->o_assignment != WORD_IS_KEYWORD
3597         ) {
3598                 word->o_assignment = NOT_ASSIGNMENT;
3599         } else {
3600                 if (word->o_assignment == DEFINITELY_ASSIGNMENT)
3601                         command->assignment_cnt++;
3602                 word->o_assignment = MAYBE_ASSIGNMENT;
3603         }
3604
3605         if (ctx->pending_redirect) {
3606                 /* We do not glob in e.g. >*.tmp case. bash seems to glob here
3607                  * only if run as "bash", not "sh" */
3608                 ctx->pending_redirect->rd_filename = xstrdup(word->data);
3609                 word->o_assignment = NOT_ASSIGNMENT;
3610                 debug_printf("word stored in rd_filename: '%s'\n", word->data);
3611         } else {
3612                 /* "{ echo foo; } echo bar" - bad */
3613                 /* NB: bash allows e.g.:
3614                  * if true; then { echo foo; } fi
3615                  * while if false; then false; fi do break; done
3616                  * TODO? */
3617                 if (command->group) {
3618                         syntax(word->data);
3619                         debug_printf_parse("done_word return 1: syntax error, "
3620                                         "groups and arglists don't mix\n");
3621                         return 1;
3622                 }
3623 #if HAS_KEYWORDS
3624 #if ENABLE_HUSH_CASE
3625                 if (ctx->ctx_dsemicolon
3626                  && strcmp(word->data, "esac") != 0 /* not "... pattern) cmd;; esac" */
3627                 ) {
3628                         /* already done when ctx_dsemicolon was set to 1: */
3629                         /* ctx->ctx_res_w = RES_MATCH; */
3630                         ctx->ctx_dsemicolon = 0;
3631                 } else
3632 #endif
3633                 if (!command->argv /* if it's the first word... */
3634 #if ENABLE_HUSH_LOOPS
3635                  && ctx->ctx_res_w != RES_FOR /* ...not after FOR or IN */
3636                  && ctx->ctx_res_w != RES_IN
3637 #endif
3638                 ) {
3639                         debug_printf_parse(": checking '%s' for reserved-ness\n", word->data);
3640                         if (reserved_word(word, ctx)) {
3641                                 o_reset(word);
3642                                 debug_printf_parse("done_word return %d\n", (ctx->ctx_res_w == RES_SNTX));
3643                                 return (ctx->ctx_res_w == RES_SNTX);
3644                         }
3645                 }
3646 #endif
3647                 if (word->nonnull /* word had "xx" or 'xx' at least as part of it. */
3648                  /* optimization: and if it's ("" or '') or ($v... or `cmd`...): */
3649                  && (word->data[0] == '\0' || word->data[0] == SPECIAL_VAR_SYMBOL)
3650                  /* (otherwise it's known to be not empty and is already safe) */
3651                 ) {
3652                         /* exclude "$@" - it can expand to no word despite "" */
3653                         char *p = word->data;
3654                         while (p[0] == SPECIAL_VAR_SYMBOL
3655                             && (p[1] & 0x7f) == '@'
3656                             && p[2] == SPECIAL_VAR_SYMBOL
3657                         ) {
3658                                 p += 3;
3659                         }
3660                         if (p == word->data || p[0] != '\0') {
3661                                 /* saw no "$@", or not only "$@" but some
3662                                  * real text is there too */
3663                                 /* insert "empty variable" reference, this makes
3664                                  * e.g. "", $empty"" etc to not disappear */
3665                                 o_addchr(word, SPECIAL_VAR_SYMBOL);
3666                                 o_addchr(word, SPECIAL_VAR_SYMBOL);
3667                         }
3668                 }
3669                 command->argv = add_string_to_strings(command->argv, xstrdup(word->data));
3670                 debug_print_strings("word appended to argv", command->argv);
3671         }
3672
3673         o_reset(word);
3674         ctx->pending_redirect = NULL;
3675
3676 #if ENABLE_HUSH_LOOPS
3677         /* Force FOR to have just one word (variable name) */
3678         /* NB: basically, this makes hush see "for v in ..." syntax as if
3679          * as it is "for v; in ...". FOR and IN become two pipe structs
3680          * in parse tree. */
3681         if (ctx->ctx_res_w == RES_FOR) {
3682 //TODO: check that command->argv[0] is a valid variable name!
3683                 done_pipe(ctx, PIPE_SEQ);
3684         }
3685 #endif
3686 #if ENABLE_HUSH_CASE
3687         /* Force CASE to have just one word */
3688         if (ctx->ctx_res_w == RES_CASE) {
3689                 done_pipe(ctx, PIPE_SEQ);
3690         }
3691 #endif
3692         debug_printf_parse("done_word return 0\n");
3693         return 0;
3694 }
3695
3696 /* If a redirect is immediately preceded by a number, that number is
3697  * supposed to tell which file descriptor to redirect.  This routine
3698  * looks for such preceding numbers.  In an ideal world this routine
3699  * needs to handle all the following classes of redirects...
3700  *     echo 2>foo     # redirects fd  2 to file "foo", nothing passed to echo
3701  *     echo 49>foo    # redirects fd 49 to file "foo", nothing passed to echo
3702  *     echo -2>foo    # redirects fd  1 to file "foo",    "-2" passed to echo
3703  *     echo 49x>foo   # redirects fd  1 to file "foo",   "49x" passed to echo
3704  * A -1 output from this program means no valid number was found, so the
3705  * caller should use the appropriate default for this redirection.
3706  */
3707 static int redirect_opt_num(o_string *o)
3708 {
3709         int num;
3710
3711         if (o->length == 0)
3712                 return -1;
3713         for (num = 0; num < o->length; num++) {
3714                 if (!isdigit(o->data[num])) {
3715                         return -1;
3716                 }
3717         }
3718         num = atoi(o->data);
3719         o_reset(o);
3720         return num;
3721 }
3722
3723 static struct pipe *parse_stream(struct in_str *input, int end_trigger);
3724
3725 #if ENABLE_HUSH_TICK
3726 static FILE *generate_stream_from_list(struct pipe *head)
3727 {
3728         FILE *pf;
3729         int pid, channel[2];
3730
3731         xpipe(channel);
3732 /* *** NOMMU WARNING *** */
3733 /* By using vfork here, we suspend parent till child exits or execs.
3734  * If child will not do it before it fills the pipe, it can block forever
3735  * in write(STDOUT_FILENO), and parent (shell) will be also stuck.
3736  * Try this script:
3737  * yes "0123456789012345678901234567890" | dd bs=32 count=64k >TESTFILE
3738  * huge=`cat TESTFILE` # will block here forever
3739  * echo OK
3740  */
3741         pid = BB_MMU ? fork() : vfork();
3742         if (pid < 0)
3743                 bb_perror_msg_and_die(BB_MMU ? "fork" : "vfork");
3744         if (pid == 0) { /* child */
3745                 if (ENABLE_HUSH_JOB)
3746                         die_sleep = 0; /* let nofork's xfuncs die */
3747                 close(channel[0]); /* NB: close _first_, then move fd! */
3748                 xmove_fd(channel[1], 1);
3749                 /* Prevent it from trying to handle ctrl-z etc */
3750 #if ENABLE_HUSH_JOB
3751                 G.run_list_level = 1;
3752 #endif
3753                 /* Process substitution is not considered to be usual
3754                  * 'command execution'.
3755                  * SUSv3 says ctrl-Z should be ignored, ctrl-C should not.
3756                  */
3757                 set_jobctrl_signals_to_IGN();
3758
3759                 /* Note: freeing 'head' here would break NOMMU. */
3760                 _exit(run_list(head));
3761         }
3762         close(channel[1]);
3763         pf = fdopen(channel[0], "r");
3764         return pf;
3765         /* 'head' is freed by the caller */
3766 }
3767
3768 /* Return code is exit status of the process that is run. */
3769 static int process_command_subs(o_string *dest,
3770                 struct in_str *input)
3771 {
3772         int retcode, ch, eol_cnt;
3773         struct pipe *pipe_list;
3774         FILE *p;
3775         struct in_str pipe_str;
3776
3777         /* Recursion to generate command */
3778         pipe_list = parse_stream(input, '\0');
3779         if (pipe_list == NULL)
3780                 return 0;  /* EOF: empty `cmd`: ``, `  ` etc */
3781         if (pipe_list == ERR_PTR)
3782                 return 1;  /* parse error. can this really happen? */
3783
3784         p = generate_stream_from_list(pipe_list);
3785         free_pipe_list(pipe_list, /* indent: */ 0);
3786         if (p == NULL)
3787                 return 1;
3788         close_on_exec_on(fileno(p));
3789
3790         /* Now send results of command back into original context */
3791         setup_file_in_str(&pipe_str, p);
3792         eol_cnt = 0;
3793         while ((ch = i_getch(&pipe_str)) != EOF) {
3794                 if (ch == '\n') {
3795                         eol_cnt++;
3796                         continue;
3797                 }
3798                 while (eol_cnt) {
3799                         o_addchr(dest, '\n');
3800                         eol_cnt--;
3801                 }
3802                 o_addQchr(dest, ch);
3803         }
3804
3805         debug_printf("done reading from pipe, pclose()ing\n");
3806         /* Note: we got EOF, and we just close the read end of the pipe.
3807          * We do not wait for the `cmd` child to terminate. bash and ash do.
3808          * Try this:
3809          * echo `echo Hi; exec 1>&-; sleep 2`
3810          */
3811         retcode = fclose(p);
3812         debug_printf("closed FILE from child, retcode=%d\n", retcode);
3813         return retcode;
3814 }
3815 #endif
3816
3817 static int parse_group(o_string *dest, struct parse_context *ctx,
3818         struct in_str *input, int ch)
3819 {
3820         /* dest contains characters seen prior to ( or {.
3821          * Typically it's empty, but for function defs,
3822          * it contains function name (without '()'). */
3823         struct pipe *pipe_list;
3824         int endch;
3825         struct command *command = ctx->command;
3826
3827         debug_printf_parse("parse_group entered\n");
3828 #if ENABLE_HUSH_FUNCTIONS
3829         if (ch == 'F') { /* function definition? */
3830                 bb_error_msg("aha '%s' is a function, parsing it...", dest->data);
3831                 //command->fname = dest->data;
3832                 command->grp_type = GRP_FUNCTION;
3833 //TODO: review every o_reset() location... do they handle all o_string fields correctly?
3834                 memset(dest, 0, sizeof(*dest));
3835         }
3836 #endif
3837         if (command->argv /* word [word](... */
3838          || dest->length /* word(... */
3839          || dest->nonnull /* ""(... */
3840         ) {
3841                 syntax(NULL);
3842                 debug_printf_parse("parse_group return 1: syntax error, groups and arglists don't mix\n");
3843                 return 1;
3844         }
3845         endch = '}';
3846         if (ch == '(') {
3847                 endch = ')';
3848                 command->grp_type = GRP_SUBSHELL;
3849         }
3850         pipe_list = parse_stream(input, endch);
3851         /* empty ()/{} or parse error? */
3852         if (!pipe_list || pipe_list == ERR_PTR) {
3853                 syntax(NULL);
3854                 debug_printf_parse("parse_group return 1: parse_stream returned %p\n", pipe_list);
3855                 return 1;
3856         }
3857         command->group = pipe_list;
3858         debug_printf_parse("parse_group return 0\n");
3859         return 0;
3860         /* command remains "open", available for possible redirects */
3861 }
3862
3863 #if ENABLE_HUSH_TICK || ENABLE_SH_MATH_SUPPORT
3864 /* Subroutines for copying $(...) and `...` things */
3865 static void add_till_backquote(o_string *dest, struct in_str *input);
3866 /* '...' */
3867 static void add_till_single_quote(o_string *dest, struct in_str *input)
3868 {
3869         while (1) {
3870                 int ch = i_getch(input);
3871                 if (ch == EOF)
3872                         break;
3873                 if (ch == '\'')
3874                         break;
3875                 o_addchr(dest, ch);
3876         }
3877 }
3878 /* "...\"...`..`...." - do we need to handle "...$(..)..." too? */
3879 static void add_till_double_quote(o_string *dest, struct in_str *input)
3880 {
3881         while (1) {
3882                 int ch = i_getch(input);
3883                 if (ch == '"')
3884                         break;
3885                 if (ch == '\\') {  /* \x. Copy both chars. */
3886                         o_addchr(dest, ch);
3887                         ch = i_getch(input);
3888                 }
3889                 if (ch == EOF)
3890                         break;
3891                 o_addchr(dest, ch);
3892                 if (ch == '`') {
3893                         add_till_backquote(dest, input);
3894                         o_addchr(dest, ch);
3895                         continue;
3896                 }
3897                 //if (ch == '$') ...
3898         }
3899 }
3900 /* Process `cmd` - copy contents until "`" is seen. Complicated by
3901  * \` quoting.
3902  * "Within the backquoted style of command substitution, backslash
3903  * shall retain its literal meaning, except when followed by: '$', '`', or '\'.
3904  * The search for the matching backquote shall be satisfied by the first
3905  * backquote found without a preceding backslash; during this search,
3906  * if a non-escaped backquote is encountered within a shell comment,
3907  * a here-document, an embedded command substitution of the $(command)
3908  * form, or a quoted string, undefined results occur. A single-quoted
3909  * or double-quoted string that begins, but does not end, within the
3910  * "`...`" sequence produces undefined results."
3911  * Example                               Output
3912  * echo `echo '\'TEST\`echo ZZ\`BEST`    \TESTZZBEST
3913  */
3914 static void add_till_backquote(o_string *dest, struct in_str *input)
3915 {
3916         while (1) {
3917                 int ch = i_getch(input);
3918                 if (ch == '`')
3919                         break;
3920                 if (ch == '\\') {  /* \x. Copy both chars unless it is \` */
3921                         int ch2 = i_getch(input);
3922                         if (ch2 != '`' && ch2 != '$' && ch2 != '\\')
3923                                 o_addchr(dest, ch);
3924                         ch = ch2;
3925                 }
3926                 if (ch == EOF)
3927                         break;
3928                 o_addchr(dest, ch);
3929         }
3930 }
3931 /* Process $(cmd) - copy contents until ")" is seen. Complicated by
3932  * quoting and nested ()s.
3933  * "With the $(command) style of command substitution, all characters
3934  * following the open parenthesis to the matching closing parenthesis
3935  * constitute the command. Any valid shell script can be used for command,
3936  * except a script consisting solely of redirections which produces
3937  * unspecified results."
3938  * Example                              Output
3939  * echo $(echo '(TEST)' BEST)           (TEST) BEST
3940  * echo $(echo 'TEST)' BEST)            TEST) BEST
3941  * echo $(echo \(\(TEST\) BEST)         ((TEST) BEST
3942  */
3943 static void add_till_closing_paren(o_string *dest, struct in_str *input, bool dbl)
3944 {
3945         int count = 0;
3946         while (1) {
3947                 int ch = i_getch(input);
3948                 if (ch == EOF)
3949                         break;
3950                 if (ch == '(')
3951                         count++;
3952                 if (ch == ')')
3953                         if (--count < 0) {
3954                                 if (!dbl)
3955                                         break;
3956                                 if (i_peek(input) == ')') {
3957                                         i_getch(input);
3958                                         break;
3959                                 }
3960                         }
3961                 o_addchr(dest, ch);
3962                 if (ch == '\'') {
3963                         add_till_single_quote(dest, input);
3964                         o_addchr(dest, ch);
3965                         continue;
3966                 }
3967                 if (ch == '"') {
3968                         add_till_double_quote(dest, input);
3969                         o_addchr(dest, ch);
3970                         continue;
3971                 }
3972                 if (ch == '\\') { /* \x. Copy verbatim. Important for  \(, \) */
3973                         ch = i_getch(input);
3974                         if (ch == EOF)
3975                                 break;
3976                         o_addchr(dest, ch);
3977                         continue;
3978                 }
3979         }
3980 }
3981 #endif /* ENABLE_HUSH_TICK || ENABLE_SH_MATH_SUPPORT */
3982
3983 /* Return code: 0 for OK, 1 for syntax error */
3984 static int handle_dollar(o_string *dest, struct in_str *input)
3985 {
3986         int expansion;
3987         int ch = i_peek(input);  /* first character after the $ */
3988         unsigned char quote_mask = dest->o_escape ? 0x80 : 0;
3989
3990         debug_printf_parse("handle_dollar entered: ch='%c'\n", ch);
3991         if (isalpha(ch)) {
3992                 i_getch(input);
3993  make_var:
3994                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
3995                 while (1) {
3996                         debug_printf_parse(": '%c'\n", ch);
3997                         o_addchr(dest, ch | quote_mask);
3998                         quote_mask = 0;
3999                         ch = i_peek(input);
4000                         if (!isalnum(ch) && ch != '_')
4001                                 break;
4002                         i_getch(input);
4003                 }
4004                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
4005         } else if (isdigit(ch)) {
4006  make_one_char_var:
4007                 i_getch(input);
4008                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
4009                 debug_printf_parse(": '%c'\n", ch);
4010                 o_addchr(dest, ch | quote_mask);
4011                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
4012         } else switch (ch) {
4013                 case '$': /* pid */
4014                 case '!': /* last bg pid */
4015                 case '?': /* last exit code */
4016                 case '#': /* number of args */
4017                 case '*': /* args */
4018                 case '@': /* args */
4019                         goto make_one_char_var;
4020                 case '{': {
4021                         bool first_char, all_digits;
4022
4023                         o_addchr(dest, SPECIAL_VAR_SYMBOL);
4024                         i_getch(input);
4025                         /* XXX maybe someone will try to escape the '}' */
4026                         expansion = 0;
4027                         first_char = true;
4028                         all_digits = false;
4029                         while (1) {
4030                                 ch = i_getch(input);
4031                                 if (ch == '}')
4032                                         break;
4033
4034                                 if (first_char) {
4035                                         if (ch == '#')
4036                                                 /* ${#var}: length of var contents */
4037                                                 goto char_ok;
4038                                         else if (isdigit(ch)) {
4039                                                 all_digits = true;
4040                                                 goto char_ok;
4041                                         }
4042                                 }
4043
4044                                 if (expansion < 2 &&
4045                                     ((all_digits && !isdigit(ch)) ||
4046                                      (!all_digits && !isalnum(ch) && ch != '_')))
4047                                 {
4048                                         /* handle parameter expansions
4049                                          * http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_06_02
4050                                          */
4051                                         if (first_char)
4052                                                 goto case_default;
4053                                         switch (ch) {
4054                                                 case ':': /* null modifier */
4055                                                         if (expansion == 0) {
4056                                                                 debug_printf_parse(": null modifier\n");
4057                                                                 ++expansion;
4058                                                                 break;
4059                                                         }
4060                                                         goto case_default;
4061
4062 #if 0 /* not implemented yet :( */
4063                                                 case '#': /* remove prefix */
4064                                                 case '%': /* remove suffix */
4065                                                         if (expansion == 0) {
4066                                                                 debug_printf_parse(": remove suffix/prefix\n");
4067                                                                 expansion = 2;
4068                                                                 break;
4069                                                         }
4070                                                         goto case_default;
4071 #endif
4072
4073                                                 case '-': /* default value */
4074                                                 case '=': /* assign default */
4075                                                 case '+': /* alternative */
4076                                                 case '?': /* error indicate */
4077                                                         debug_printf_parse(": parameter expansion\n");
4078                                                         expansion = 2;
4079                                                         break;
4080
4081                                                 default:
4082                                                 case_default:
4083                                                         syntax("unterminated ${name}");
4084                                                         debug_printf_parse("handle_dollar return 1: unterminated ${name}\n");
4085                                                         return 1;
4086                                                 }
4087                                 }
4088
4089  char_ok:
4090                                 debug_printf_parse(": '%c'\n", ch);
4091                                 o_addchr(dest, ch | quote_mask);
4092                                 quote_mask = 0;
4093                                 first_char = false;
4094                         }
4095                         o_addchr(dest, SPECIAL_VAR_SYMBOL);
4096                         break;
4097                 }
4098                 case '(': {
4099                         i_getch(input);
4100
4101 #if ENABLE_SH_MATH_SUPPORT
4102                         if (i_peek(input) == '(') {
4103                                 i_getch(input);
4104                                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
4105                                 o_addchr(dest, /*quote_mask |*/ '+');
4106                                 add_till_closing_paren(dest, input, true);
4107                                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
4108                                 break;
4109                         }
4110 #endif
4111
4112 #if ENABLE_HUSH_TICK
4113                         //int pos = dest->length;
4114                         o_addchr(dest, SPECIAL_VAR_SYMBOL);
4115                         o_addchr(dest, quote_mask | '`');
4116                         add_till_closing_paren(dest, input, false);
4117                         //debug_printf_subst("SUBST RES2 '%s'\n", dest->data + pos);
4118                         o_addchr(dest, SPECIAL_VAR_SYMBOL);
4119 #endif
4120                         break;
4121                 }
4122                 case '_':
4123                         i_getch(input);
4124                         ch = i_peek(input);
4125                         if (isalnum(ch)) { /* it's $_name or $_123 */
4126                                 ch = '_';
4127                                 goto make_var;
4128                         }
4129                         /* else: it's $_ */
4130                 case '-':
4131                         /* still unhandled, but should be eventually */
4132                         bb_error_msg("unhandled syntax: $%c", ch);
4133                         return 1;
4134                         break;
4135                 default:
4136                         o_addQchr(dest, '$');
4137         }
4138         debug_printf_parse("handle_dollar return 0\n");
4139         return 0;
4140 }
4141
4142 static int parse_stream_dquoted(o_string *dest, struct in_str *input, int dquote_end)
4143 {
4144         int ch, m;
4145         int next;
4146
4147  again:
4148         ch = i_getch(input);
4149         if (ch == dquote_end) { /* may be only '"' or EOF */
4150                 dest->nonnull = 1;
4151                 if (dest->o_assignment == NOT_ASSIGNMENT)
4152                         dest->o_escape ^= 1;
4153                 debug_printf_parse("parse_stream_dquoted return 0\n");
4154                 return 0;
4155         }
4156         if (ch == EOF) {
4157                 syntax("unterminated \"");
4158                 debug_printf_parse("parse_stream_dquoted return 1: unterminated \"\n");
4159                 return 1;
4160         }
4161         next = '\0';
4162         m = G.charmap[ch];
4163         if (ch != '\n') {
4164                 next = i_peek(input);
4165         }
4166         debug_printf_parse(": ch=%c (%d) m=%d escape=%d\n",
4167                                         ch, ch, m, dest->o_escape);
4168         /* Basically, checking every CHAR_SPECIAL char except '"' */
4169         if (ch == '\\') {
4170                 if (next == EOF) {
4171                         syntax("\\<eof>");
4172                         debug_printf_parse("parse_stream_dquoted return 1: \\<eof>\n");
4173                         return 1;
4174                 }
4175                 /* bash:
4176                  * "The backslash retains its special meaning [in "..."]
4177                  * only when followed by one of the following characters:
4178                  * $, `, ", \, or <newline>.  A double quote may be quoted
4179                  * within double quotes by preceding it with a backslash.
4180                  * If enabled, history expansion will be performed unless
4181                  * an ! appearing in double quotes is escaped using
4182                  * a backslash. The backslash preceding the ! is not removed."
4183                  */
4184                 if (strchr("$`\"\\", next) != NULL) {
4185                         o_addqchr(dest, i_getch(input));
4186                 } else {
4187                         o_addqchr(dest, '\\');
4188                 }
4189                 goto again;
4190         }
4191         if (ch == '$') {
4192                 if (handle_dollar(dest, input) != 0) {
4193                         debug_printf_parse("parse_stream_dquoted return 1: handle_dollar returned non-0\n");
4194                         return 1;
4195                 }
4196                 goto again;
4197         }
4198 #if ENABLE_HUSH_TICK
4199         if (ch == '`') {
4200                 //int pos = dest->length;
4201                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
4202                 o_addchr(dest, 0x80 | '`');
4203                 add_till_backquote(dest, input);
4204                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
4205                 //debug_printf_subst("SUBST RES3 '%s'\n", dest->data + pos);
4206                 goto again;
4207         }
4208 #endif
4209         o_addQchr(dest, ch);
4210         if (ch == '='
4211          && (dest->o_assignment == MAYBE_ASSIGNMENT
4212             || dest->o_assignment == WORD_IS_KEYWORD)
4213          && is_assignment(dest->data)
4214         ) {
4215                 dest->o_assignment = DEFINITELY_ASSIGNMENT;
4216         }
4217         goto again;
4218 }
4219
4220 /*
4221  * Scan input until EOF or end_trigger char.
4222  * Return a list of pipes to execute, or NULL on EOF
4223  * or if end_trigger character is met.
4224  * On syntax error, exit is shell is not interactive,
4225  * reset parsing machinery and start parsing anew,
4226  * or return ERR_PTR.
4227  */
4228 static struct pipe *parse_stream(struct in_str *input, int end_trigger)
4229 {
4230         struct parse_context ctx;
4231         o_string dest = NULL_O_STRING;
4232         int ch, m;
4233         int redir_fd;
4234         redir_type redir_style;
4235         int is_in_dquote;
4236         int next;
4237
4238         /* Double-quote state is handled in the state variable is_in_dquote.
4239          * A single-quote triggers a bypass of the main loop until its mate is
4240          * found.  When recursing, quote state is passed in via dest->o_escape. */
4241
4242         debug_printf_parse("parse_stream entered, end_trigger='%c'\n",
4243                         end_trigger ? : 'X');
4244
4245  reset:
4246 #if ENABLE_HUSH_INTERACTIVE
4247         input->promptmode = 0; /* PS1 */
4248 #endif
4249         /* dest.o_assignment = MAYBE_ASSIGNMENT; - already is */
4250         initialize_context(&ctx);
4251         is_in_dquote = 0;
4252         while (1) {
4253                 if (is_in_dquote) {
4254                         if (parse_stream_dquoted(&dest, input, '"')) {
4255                                 goto parse_error;
4256                         }
4257                         /* We reached closing '"' */
4258                         is_in_dquote = 0;
4259                 }
4260                 m = CHAR_IFS;
4261                 next = '\0';
4262                 ch = i_getch(input);
4263                 if (ch != EOF) {
4264                         m = G.charmap[ch];
4265                         if (ch != '\n') {
4266                                 next = i_peek(input);
4267                         }
4268                 }
4269                 debug_printf_parse(": ch=%c (%d) m=%d escape=%d\n",
4270                                                 ch, ch, m, dest.o_escape);
4271                 if (m == CHAR_ORDINARY) {
4272                         o_addQchr(&dest, ch);
4273                         if ((dest.o_assignment == MAYBE_ASSIGNMENT
4274                             || dest.o_assignment == WORD_IS_KEYWORD)
4275                          && ch == '='
4276                          && is_assignment(dest.data)
4277                         ) {
4278                                 dest.o_assignment = DEFINITELY_ASSIGNMENT;
4279                         }
4280                         continue;
4281                 }
4282
4283                 /* m is SPECIAL ($,`), IFS, or ORDINARY_IF_QUOTED (*,#) */
4284
4285                 if (m == CHAR_IFS) {
4286                         if (ch == EOF) {
4287                                 struct pipe *pi;
4288                                 if (done_word(&dest, &ctx)) {
4289                                         goto parse_error;
4290                                 }
4291                                 o_free(&dest);
4292                                 done_pipe(&ctx, PIPE_SEQ);
4293                                 /* If we got nothing... */
4294                                 pi = ctx.list_head;
4295                                 if (pi->num_cmds == 0
4296                                     IF_HAS_KEYWORDS( && pi->res_word == RES_NONE)
4297                                 ) {
4298                                         free_pipe_list(pi, 0);
4299                                         pi = NULL;
4300                                 }
4301                                 debug_printf_parse("parse_stream return %p\n", pi);
4302                                 return pi;
4303                         }
4304                         if (done_word(&dest, &ctx)) {
4305                                 goto parse_error;
4306                         }
4307                         if (ch == '\n') {
4308 #if ENABLE_HUSH_CASE
4309                                 /* "case ... in <newline> word) ..." -
4310                                  * newlines are ignored (but ';' wouldn't be) */
4311                                 if (ctx.command->argv == NULL
4312                                  && ctx.ctx_res_w == RES_MATCH
4313                                 ) {
4314                                         continue;
4315                                 }
4316 #endif
4317                                 /* Treat newline as a command separator. */
4318                                 done_pipe(&ctx, PIPE_SEQ);
4319                                 dest.o_assignment = MAYBE_ASSIGNMENT;
4320                                 ch = ';';
4321                                 /* note: if (m == CHAR_IFS) continue;
4322                                  * will still trigger for us */
4323                         }
4324                 }
4325                 if (end_trigger && end_trigger == ch) {
4326 //TODO: disallow "{ cmd }" without semicolon
4327                         if (done_word(&dest, &ctx)) {
4328                                 goto parse_error;
4329                         }
4330                         done_pipe(&ctx, PIPE_SEQ);
4331                         dest.o_assignment = MAYBE_ASSIGNMENT;
4332                         /* Do we sit outside of any if's, loops or case's? */
4333                         if (!HAS_KEYWORDS
4334                          IF_HAS_KEYWORDS(|| (ctx.ctx_res_w == RES_NONE && ctx.old_flag == 0))
4335                         ) {
4336                                 debug_printf_parse("parse_stream return %p: "
4337                                                 "end_trigger char found\n",
4338                                                 ctx.list_head);
4339                                 o_free(&dest);
4340                                 return ctx.list_head;
4341                         }
4342                 }
4343                 if (m == CHAR_IFS)
4344                         continue;
4345
4346                 /* m is SPECIAL (e.g. $,`) or ORDINARY_IF_QUOTED (*,#) */
4347
4348                 if (dest.o_assignment == MAYBE_ASSIGNMENT) {
4349                         /* ch is a special char and thus this word
4350                          * cannot be an assignment */
4351                         dest.o_assignment = NOT_ASSIGNMENT;
4352                 }
4353
4354                 switch (ch) {
4355                 case '#':
4356                         if (dest.length == 0) {
4357                                 while (1) {
4358                                         ch = i_peek(input);
4359                                         if (ch == EOF || ch == '\n')
4360                                                 break;
4361                                         i_getch(input);
4362                                 }
4363                         } else {
4364                                 o_addQchr(&dest, ch);
4365                         }
4366                         break;
4367                 case '\\':
4368                         if (next == EOF) {
4369                                 syntax("\\<eof>");
4370                                 goto parse_error;
4371                         }
4372                         o_addchr(&dest, '\\');
4373                         o_addchr(&dest, i_getch(input));
4374                         break;
4375                 case '$':
4376                         if (handle_dollar(&dest, input) != 0) {
4377                                 debug_printf_parse("parse_stream parse error: handle_dollar returned non-0\n");
4378                                 goto parse_error;
4379                         }
4380                         break;
4381                 case '\'':
4382                         dest.nonnull = 1;
4383                         while (1) {
4384                                 ch = i_getch(input);
4385                                 if (ch == EOF) {
4386                                         syntax("unterminated '");
4387                                         goto parse_error;
4388                                 }
4389                                 if (ch == '\'')
4390                                         break;
4391                                 if (dest.o_assignment == NOT_ASSIGNMENT)
4392                                         o_addqchr(&dest, ch);
4393                                 else
4394                                         o_addchr(&dest, ch);
4395                         }
4396                         break;
4397                 case '"':
4398                         dest.nonnull = 1;
4399                         is_in_dquote ^= 1; /* invert */
4400                         if (dest.o_assignment == NOT_ASSIGNMENT)
4401                                 dest.o_escape ^= 1;
4402                         break;
4403 #if ENABLE_HUSH_TICK
4404                 case '`': {
4405                         //int pos = dest.length;
4406                         o_addchr(&dest, SPECIAL_VAR_SYMBOL);
4407                         o_addchr(&dest, '`');
4408                         add_till_backquote(&dest, input);
4409                         o_addchr(&dest, SPECIAL_VAR_SYMBOL);
4410                         //debug_printf_subst("SUBST RES3 '%s'\n", dest.data + pos);
4411                         break;
4412                 }
4413 #endif
4414                 case '>':
4415                         redir_fd = redirect_opt_num(&dest);
4416                         if (done_word(&dest, &ctx)) {
4417                                 goto parse_error;
4418                         }
4419                         redir_style = REDIRECT_OVERWRITE;
4420                         if (next == '>') {
4421                                 redir_style = REDIRECT_APPEND;
4422                                 i_getch(input);
4423                         }
4424 #if 0
4425                         else if (next == '(') {
4426                                 syntax(">(process) not supported");
4427                                 goto parse_error;
4428                         }
4429 #endif
4430                         setup_redirect(&ctx, redir_fd, redir_style, input);
4431                         break;
4432                 case '<':
4433                         redir_fd = redirect_opt_num(&dest);
4434                         if (done_word(&dest, &ctx)) {
4435                                 goto parse_error;
4436                         }
4437                         redir_style = REDIRECT_INPUT;
4438                         if (next == '<') {
4439                                 redir_style = REDIRECT_HEREIS;
4440                                 i_getch(input);
4441                         } else if (next == '>') {
4442                                 redir_style = REDIRECT_IO;
4443                                 i_getch(input);
4444                         }
4445 #if 0
4446                         else if (next == '(') {
4447                                 syntax("<(process) not supported");
4448                                 goto parse_error;
4449                         }
4450 #endif
4451                         setup_redirect(&ctx, redir_fd, redir_style, input);
4452                         break;
4453                 case ';':
4454 #if ENABLE_HUSH_CASE
4455  case_semi:
4456 #endif
4457                         if (done_word(&dest, &ctx)) {
4458                                 goto parse_error;
4459                         }
4460                         done_pipe(&ctx, PIPE_SEQ);
4461 #if ENABLE_HUSH_CASE
4462                         /* Eat multiple semicolons, detect
4463                          * whether it means something special */
4464                         while (1) {
4465                                 ch = i_peek(input);
4466                                 if (ch != ';')
4467                                         break;
4468                                 i_getch(input);
4469                                 if (ctx.ctx_res_w == RES_CASEI) {
4470                                         ctx.ctx_dsemicolon = 1;
4471                                         ctx.ctx_res_w = RES_MATCH;
4472                                         break;
4473                                 }
4474                         }
4475 #endif
4476  new_cmd:
4477                         /* We just finished a cmd. New one may start
4478                          * with an assignment */
4479                         dest.o_assignment = MAYBE_ASSIGNMENT;
4480                         break;
4481                 case '&':
4482                         if (done_word(&dest, &ctx)) {
4483                                 goto parse_error;
4484                         }
4485                         if (next == '&') {
4486                                 i_getch(input);
4487                                 done_pipe(&ctx, PIPE_AND);
4488                         } else {
4489                                 done_pipe(&ctx, PIPE_BG);
4490                         }
4491                         goto new_cmd;
4492                 case '|':
4493                         if (done_word(&dest, &ctx)) {
4494                                 goto parse_error;
4495                         }
4496 #if ENABLE_HUSH_CASE
4497                         if (ctx.ctx_res_w == RES_MATCH)
4498                                 break; /* we are in case's "word | word)" */
4499 #endif
4500                         if (next == '|') { /* || */
4501                                 i_getch(input);
4502                                 done_pipe(&ctx, PIPE_OR);
4503                         } else {
4504                                 /* we could pick up a file descriptor choice here
4505                                  * with redirect_opt_num(), but bash doesn't do it.
4506                                  * "echo foo 2| cat" yields "foo 2". */
4507                                 done_command(&ctx);
4508                         }
4509                         goto new_cmd;
4510                 case '(':
4511 #if ENABLE_HUSH_CASE
4512                         /* "case... in [(]word)..." - skip '(' */
4513                         if (ctx.ctx_res_w == RES_MATCH
4514                          && ctx.command->argv == NULL /* not (word|(... */
4515                          && dest.length == 0 /* not word(... */
4516                          && dest.nonnull == 0 /* not ""(... */
4517                         ) {
4518                                 continue;
4519                         }
4520 #endif
4521 #if ENABLE_HUSH_FUNCTIONS
4522                         if (dest.length != 0 /* not just () but word() */
4523                          && dest.nonnull == 0 /* not a"b"c() */
4524                          && ctx.command->argv == NULL /* it's the first word */
4525 //TODO: "func ( ) {...}" - note spaces - is valid format too in bash
4526                          && i_peek(input) == ')'
4527                          && !match_reserved_word(&dest)
4528                         ) {
4529                                 bb_error_msg("seems like a function definition");
4530                                 i_getch(input);
4531                                 do {
4532 //TODO: do it properly.
4533                                         ch = i_getch(input);
4534                                 } while (ch == ' ' || ch == '\n');
4535                                 if (ch != '{') {
4536                                         syntax("was expecting {");
4537                                         goto parse_error;
4538                                 }
4539                                 ch = 'F'; /* magic value */
4540                         }
4541 #endif
4542                 case '{':
4543                         if (parse_group(&dest, &ctx, input, ch) != 0) {
4544                                 goto parse_error;
4545                         }
4546                         goto new_cmd;
4547                 case ')':
4548 #if ENABLE_HUSH_CASE
4549                         if (ctx.ctx_res_w == RES_MATCH)
4550                                 goto case_semi;
4551 #endif
4552                 case '}':
4553                         /* proper use of this character is caught by end_trigger:
4554                          * if we see {, we call parse_group(..., end_trigger='}')
4555                          * and it will match } earlier (not here). */
4556                         syntax("unexpected } or )");
4557                         goto parse_error;
4558                 default:
4559                         if (HUSH_DEBUG)
4560                                 bb_error_msg_and_die("BUG: unexpected %c\n", ch);
4561                 }
4562         } /* while (1) */
4563
4564  parse_error:
4565         {
4566                 struct parse_context *pctx;
4567                 IF_HAS_KEYWORDS(struct parse_context *p2;)
4568
4569                 /* Clean up allocated tree.
4570                  * Samples for finding leaks on syntax error recovery path.
4571                  * Execute them from interactive shell and watch pmap `pidof hush`.
4572                  * while if false; then false; fi do break; done (bash accepts it)
4573                  * while if false; then false; fi; do break; fi
4574                  */
4575                 pctx = &ctx;
4576                 do {
4577                         /* Update pipe/command counts,
4578                          * otherwise freeing may miss some */
4579                         done_pipe(pctx, PIPE_SEQ);
4580                         debug_printf_clean("freeing list %p from ctx %p\n",
4581                                         pctx->list_head, pctx);
4582                         debug_print_tree(pctx->list_head, 0);
4583                         free_pipe_list(pctx->list_head, 0);
4584                         debug_printf_clean("freed list %p\n", pctx->list_head);
4585                         IF_HAS_KEYWORDS(p2 = pctx->stack;)
4586                         if (pctx != &ctx) {
4587                                 free(pctx);
4588                         }
4589                         IF_HAS_KEYWORDS(pctx = p2;)
4590                 } while (HAS_KEYWORDS && pctx);
4591                 /* Free text, clear all dest fields */
4592                 o_free(&dest);
4593                 /* If we are not in top-level parse, we return,
4594                  * our caller will propagate error.
4595                  */
4596                 if (end_trigger != ';')
4597                         return ERR_PTR;
4598                 /* Discard cached input, force prompt */
4599                 input->p = NULL;
4600                 USE_HUSH_INTERACTIVE(input->promptme = 1;)
4601                 goto reset;
4602         }
4603 }
4604
4605 static void set_in_charmap(const char *set, int code)
4606 {
4607         while (*set)
4608                 G.charmap[(unsigned char)*set++] = code;
4609 }
4610
4611 static void update_charmap(void)
4612 {
4613         G.ifs = getenv("IFS");
4614         if (G.ifs == NULL)
4615                 G.ifs = " \t\n";
4616         /* Precompute a list of 'flow through' behavior so it can be treated
4617          * quickly up front.  Computation is necessary because of IFS.
4618          * Special case handling of IFS == " \t\n" is not implemented.
4619          * The charmap[] array only really needs two bits each,
4620          * and on most machines that would be faster (reduced L1 cache use).
4621          */
4622         memset(G.charmap, CHAR_ORDINARY, sizeof(G.charmap));
4623 #if ENABLE_HUSH_TICK
4624         set_in_charmap("\\$\"`", CHAR_SPECIAL);
4625 #else
4626         set_in_charmap("\\$\"", CHAR_SPECIAL);
4627 #endif
4628         set_in_charmap("<>;&|(){}#'", CHAR_ORDINARY_IF_QUOTED);
4629         set_in_charmap(G.ifs, CHAR_IFS);  /* are ordinary if quoted */
4630 }
4631
4632 /* Execiting from string: eval, sh -c '...'
4633  *          or from file: /etc/profile, . file, sh <script>, sh (intereactive)
4634  * end_trigger controls how often we stop parsing
4635  * NUL: parse all, execute, return
4636  * ';': parse till ';' or newline, execute, repeat till EOF
4637  */
4638 static void parse_and_run_stream(struct in_str *inp, int end_trigger)
4639 {
4640         while (1) {
4641                 struct pipe *pipe_list;
4642
4643                 update_charmap();
4644
4645                 pipe_list = parse_stream(inp, end_trigger);
4646                 if (!pipe_list) /* EOF */
4647                         break;
4648                 debug_print_tree(pipe_list, 0);
4649                 debug_printf_exec("parse_and_run_stream: run_and_free_list\n");
4650                 run_and_free_list(pipe_list);
4651                 /* Loop on syntax errors, return on EOF: */
4652         }
4653 }
4654
4655 static void parse_and_run_string(const char *s)
4656 {
4657         struct in_str input;
4658         setup_string_in_str(&input, s);
4659         parse_and_run_stream(&input, '\0');
4660 }
4661
4662 static void parse_and_run_file(FILE *f)
4663 {
4664         struct in_str input;
4665         setup_file_in_str(&input, f);
4666         parse_and_run_stream(&input, ';');
4667 }
4668
4669 #if ENABLE_HUSH_JOB
4670 /* Make sure we have a controlling tty.  If we get started under a job
4671  * aware app (like bash for example), make sure we are now in charge so
4672  * we don't fight over who gets the foreground */
4673 static void setup_job_control(void)
4674 {
4675         pid_t shell_pgrp;
4676
4677         shell_pgrp = getpgrp();
4678
4679         /* If we were ran as 'hush &',
4680          * sleep until we are in the foreground.  */
4681         while (tcgetpgrp(G_interactive_fd) != shell_pgrp) {
4682                 /* Send TTIN to ourself (should stop us) */
4683                 kill(- shell_pgrp, SIGTTIN);
4684                 shell_pgrp = getpgrp();
4685         }
4686
4687         /* We _must_ restore tty pgrp on fatal signals */
4688         set_fatal_signals_to_sigexit();
4689
4690         /* Put ourselves in our own process group.  */
4691         bb_setpgrp(); /* is the same as setpgid(our_pid, our_pid); */
4692         /* Grab control of the terminal.  */
4693         tcsetpgrp(G_interactive_fd, getpid());
4694 }
4695 #endif
4696
4697 static int set_mode(const char cstate, const char mode)
4698 {
4699         int state = (cstate == '-' ? 1 : 0);
4700         switch (mode) {
4701                 case 'n': G.fake_mode = state; break;
4702                 case 'x': /*G.debug_mode = state;*/ break;
4703                 default:  return EXIT_FAILURE;
4704         }
4705         return EXIT_SUCCESS;
4706 }
4707
4708 int hush_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
4709 int hush_main(int argc, char **argv)
4710 {
4711         static const struct variable const_shell_ver = {
4712                 .next = NULL,
4713                 .varstr = (char*)hush_version_str,
4714                 .max_len = 1, /* 0 can provoke free(name) */
4715                 .flg_export = 1,
4716                 .flg_read_only = 1,
4717         };
4718
4719         int opt;
4720         FILE *input;
4721         char **e;
4722         struct variable *cur_var;
4723
4724         INIT_G();
4725
4726         G.root_pid = getpid();
4727
4728         /* Deal with HUSH_VERSION */
4729         G.shell_ver = const_shell_ver; /* copying struct here */
4730         G.top_var = &G.shell_ver;
4731         debug_printf_env("unsetenv '%s'\n", "HUSH_VERSION");
4732         unsetenv("HUSH_VERSION"); /* in case it exists in initial env */
4733         /* Initialize our shell local variables with the values
4734          * currently living in the environment */
4735         cur_var = G.top_var;
4736         e = environ;
4737         if (e) while (*e) {
4738                 char *value = strchr(*e, '=');
4739                 if (value) { /* paranoia */
4740                         cur_var->next = xzalloc(sizeof(*cur_var));
4741                         cur_var = cur_var->next;
4742                         cur_var->varstr = *e;
4743                         cur_var->max_len = strlen(*e);
4744                         cur_var->flg_export = 1;
4745                 }
4746                 e++;
4747         }
4748         debug_printf_env("putenv '%s'\n", hush_version_str);
4749         putenv((char *)hush_version_str); /* reinstate HUSH_VERSION */
4750
4751 #if ENABLE_FEATURE_EDITING
4752         G.line_input_state = new_line_input_t(FOR_SHELL);
4753 #endif
4754         /* XXX what should these be while sourcing /etc/profile? */
4755         G.global_argc = argc;
4756         G.global_argv = argv;
4757         /* Initialize some more globals to non-zero values */
4758         set_cwd();
4759 #if ENABLE_HUSH_INTERACTIVE
4760         if (ENABLE_FEATURE_EDITING)
4761                 cmdedit_set_initial_prompt();
4762         G.PS2 = "> ";
4763 #endif
4764
4765         if (EXIT_SUCCESS) /* otherwise is already done */
4766                 G.last_return_code = EXIT_SUCCESS;
4767
4768         if (argv[0] && argv[0][0] == '-') {
4769                 debug_printf("sourcing /etc/profile\n");
4770                 input = fopen_for_read("/etc/profile");
4771                 if (input != NULL) {
4772                         close_on_exec_on(fileno(input));
4773                         parse_and_run_file(input);
4774                         fclose(input);
4775                 }
4776         }
4777         input = stdin;
4778
4779         /* http://www.opengroup.org/onlinepubs/9699919799/utilities/sh.html */
4780         while ((opt = getopt(argc, argv, "c:xins")) > 0) {
4781                 switch (opt) {
4782                 case 'c':
4783                         G.global_argv = argv + optind;
4784                         if (!argv[optind]) {
4785                                 /* -c 'script' (no params): prevent empty $0 */
4786                                 *--G.global_argv = argv[0];
4787                                 optind--;
4788                         } /* else -c 'script' PAR0 PAR1: $0 is PAR0 */
4789                         G.global_argc = argc - optind;
4790                         parse_and_run_string(optarg);
4791                         goto final_return;
4792                 case 'i':
4793                         /* Well, we cannot just declare interactiveness,
4794                          * we have to have some stuff (ctty, etc) */
4795                         /* G_interactive_fd++; */
4796                         break;
4797                 case 's':
4798                         /* "-s" means "read from stdin", but this is how we always
4799                          * operate, so simply do nothing here. */
4800                         break;
4801                 case 'n':
4802                 case 'x':
4803                         if (!set_mode('-', opt))
4804                                 break;
4805                 default:
4806 #ifndef BB_VER
4807                         fprintf(stderr, "Usage: sh [FILE]...\n"
4808                                         "   or: sh -c command [args]...\n\n");
4809                         exit(EXIT_FAILURE);
4810 #else
4811                         bb_show_usage();
4812 #endif
4813                 }
4814         }
4815 #if ENABLE_HUSH_JOB
4816         /* A shell is interactive if the '-i' flag was given, or if all of
4817          * the following conditions are met:
4818          *    no -c command
4819          *    no arguments remaining or the -s flag given
4820          *    standard input is a terminal
4821          *    standard output is a terminal
4822          *    Refer to Posix.2, the description of the 'sh' utility. */
4823         if (argv[optind] == NULL && input == stdin
4824          && isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)
4825         ) {
4826                 G.saved_tty_pgrp = tcgetpgrp(STDIN_FILENO);
4827                 debug_printf("saved_tty_pgrp=%d\n", G.saved_tty_pgrp);
4828                 if (G.saved_tty_pgrp >= 0) {
4829                         /* try to dup to high fd#, >= 255 */
4830                         G_interactive_fd = fcntl(STDIN_FILENO, F_DUPFD, 255);
4831                         if (G_interactive_fd < 0) {
4832                                 /* try to dup to any fd */
4833                                 G_interactive_fd = dup(STDIN_FILENO);
4834                                 if (G_interactive_fd < 0)
4835                                         /* give up */
4836                                         G_interactive_fd = 0;
4837                         }
4838                         // TODO: track & disallow any attempts of user
4839                         // to (inadvertently) close/redirect it
4840                 }
4841         }
4842         init_signal_mask(); /* note: ensures SIGCHLD is not masked */
4843         debug_printf("interactive_fd=%d\n", G_interactive_fd);
4844         if (G_interactive_fd) {
4845                 fcntl(G_interactive_fd, F_SETFD, FD_CLOEXEC);
4846                 /* Looks like they want an interactive shell */
4847                 setup_job_control();
4848                 /* -1 is special - makes xfuncs longjmp, not exit
4849                  * (we reset die_sleep = 0 whereever we [v]fork) */
4850                 die_sleep = -1;
4851                 if (setjmp(die_jmp)) {
4852                         /* xfunc has failed! die die die */
4853                         hush_exit(xfunc_error_retval);
4854                 }
4855         }
4856 #elif ENABLE_HUSH_INTERACTIVE
4857 /* no job control compiled, only prompt/line editing */
4858         if (argv[optind] == NULL && input == stdin
4859          && isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)
4860         ) {
4861                 G_interactive_fd = fcntl(STDIN_FILENO, F_DUPFD, 255);
4862                 if (G_interactive_fd < 0) {
4863                         /* try to dup to any fd */
4864                         G_interactive_fd = dup(STDIN_FILENO);
4865                         if (G_interactive_fd < 0)
4866                                 /* give up */
4867                                 G_interactive_fd = 0;
4868                 }
4869                 if (G_interactive_fd) {
4870                         fcntl(G_interactive_fd, F_SETFD, FD_CLOEXEC);
4871                 }
4872         }
4873         init_signal_mask(); /* note: ensures SIGCHLD is not masked */
4874 #else
4875         init_signal_mask();
4876 #endif
4877         /* POSIX allows shell to re-enable SIGCHLD
4878          * even if it was SIG_IGN on entry */
4879 //      G.count_SIGCHLD++; /* ensure it is != G.handled_SIGCHLD */
4880         signal(SIGCHLD, SIG_DFL); // SIGCHLD_handler);
4881
4882 #if ENABLE_HUSH_INTERACTIVE && !ENABLE_FEATURE_SH_EXTRA_QUIET
4883         if (G_interactive_fd) {
4884                 printf("\n\n%s hush - the humble shell v"HUSH_VER_STR"\n", bb_banner);
4885                 printf("Enter 'help' for a list of built-in commands.\n\n");
4886         }
4887 #endif
4888
4889         if (argv[optind] == NULL) {
4890                 parse_and_run_file(stdin);
4891         } else {
4892                 debug_printf("\nrunning script '%s'\n", argv[optind]);
4893                 G.global_argv = argv + optind;
4894                 G.global_argc = argc - optind;
4895                 input = xfopen_for_read(argv[optind]);
4896                 fcntl(fileno(input), F_SETFD, FD_CLOEXEC);
4897                 parse_and_run_file(input);
4898         }
4899
4900  final_return:
4901
4902 #if ENABLE_FEATURE_CLEAN_UP
4903         fclose(input);
4904         if (G.cwd != bb_msg_unknown)
4905                 free((char*)G.cwd);
4906         cur_var = G.top_var->next;
4907         while (cur_var) {
4908                 struct variable *tmp = cur_var;
4909                 if (!cur_var->max_len)
4910                         free(cur_var->varstr);
4911                 cur_var = cur_var->next;
4912                 free(tmp);
4913         }
4914 #endif
4915         hush_exit(G.last_return_code);
4916 }
4917
4918
4919 #if ENABLE_LASH
4920 int lash_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
4921 int lash_main(int argc, char **argv)
4922 {
4923         //bb_error_msg("lash is deprecated, please use hush instead");
4924         return hush_main(argc, argv);
4925 }
4926 #endif
4927
4928
4929 /*
4930  * Built-ins
4931  */
4932 static int builtin_trap(char **argv)
4933 {
4934         int i;
4935         int sig;
4936         char *new_cmd;
4937
4938         if (!G.traps)
4939                 G.traps = xzalloc(sizeof(G.traps[0]) * NSIG);
4940
4941         if (!argv[1]) {
4942                 /* No args: print all trapped.  This isn't 100% correct as we should
4943                  * be escaping the cmd so that it can be pasted back in ...
4944                  */
4945                 for (i = 0; i < NSIG; ++i)
4946                         if (G.traps[i])
4947                                 printf("trap -- '%s' %s\n", G.traps[i], get_signame(i));
4948                 return EXIT_SUCCESS;
4949         }
4950
4951         new_cmd = NULL;
4952         i = 0;
4953         /* if first arg is decimal: reset all specified */
4954         sig = bb_strtou(*++argv, NULL, 10);
4955         if (errno == 0) {
4956                 int ret;
4957  set_all:
4958                 ret = EXIT_SUCCESS;
4959                 while (*argv) {
4960                         sig = get_signum(*argv++);
4961                         if (sig < 0 || sig >= NSIG) {
4962                                 ret = EXIT_FAILURE;
4963                                 /* mimic bash message exactly */
4964                                 bb_perror_msg("trap: %s: invalid signal specification", argv[i]);
4965                                 continue;
4966                         }
4967
4968                         free(G.traps[sig]);
4969                         G.traps[sig] = xstrdup(new_cmd);
4970
4971                         debug_printf("trap: setting SIG%s (%i) to '%s'",
4972                                 get_signame(sig), sig, G.traps[sig]);
4973
4974                         /* There is no signal for 0 (EXIT) */
4975                         if (sig == 0)
4976                                 continue;
4977
4978                         if (new_cmd) {
4979                                 sigaddset(&G.blocked_set, sig);
4980                         } else {
4981                                 /* there was a trap handler, we are removing it
4982                                  * (if sig has non-DFL handling,
4983                                  * we don't need to do anything) */
4984                                 if (sig < 32 && (G.non_DFL_mask & (1 << sig)))
4985                                         continue;
4986                                 sigdelset(&G.blocked_set, sig);
4987                         }
4988                         sigprocmask(SIG_SETMASK, &G.blocked_set, NULL);
4989                 }
4990                 return ret;
4991         }
4992
4993         /* first arg is "-": reset all specified to default */
4994         /* first arg is "": ignore all specified */
4995         /* everything else: execute first arg upon signal */
4996         if (!argv[1]) {
4997                 bb_error_msg("trap: invalid arguments");
4998                 return EXIT_FAILURE;
4999         }
5000         if (LONE_DASH(*argv))
5001                 /* nothing! */;
5002         else
5003                 new_cmd = *argv;
5004         argv++;
5005         goto set_all;
5006 }
5007
5008 static int builtin_true(char **argv UNUSED_PARAM)
5009 {
5010         return 0;
5011 }
5012
5013 static int builtin_test(char **argv)
5014 {
5015         int argc = 0;
5016         while (*argv) {
5017                 argc++;
5018                 argv++;
5019         }
5020         return test_main(argc, argv - argc);
5021 }
5022
5023 static int builtin_echo(char **argv)
5024 {
5025         int argc = 0;
5026         while (*argv) {
5027                 argc++;
5028                 argv++;
5029         }
5030         return echo_main(argc, argv - argc);
5031 }
5032
5033 static int builtin_eval(char **argv)
5034 {
5035         int rcode = EXIT_SUCCESS;
5036
5037         if (argv[1]) {
5038                 char *str = expand_strvec_to_string(argv + 1);
5039                 /* bash:
5040                  * eval "echo Hi; done" ("done" is syntax error):
5041                  * "echo Hi" will not execute too.
5042                  */
5043                 parse_and_run_string(str);
5044                 free(str);
5045                 rcode = G.last_return_code;
5046         }
5047         return rcode;
5048 }
5049
5050 static int builtin_cd(char **argv)
5051 {
5052         const char *newdir;
5053         if (argv[1] == NULL) {
5054                 /* bash does nothing (exitcode 0) if HOME is ""; if it's unset,
5055                  * bash says "bash: cd: HOME not set" and does nothing (exitcode 1)
5056                  */
5057                 newdir = getenv("HOME") ? : "/";
5058         } else
5059                 newdir = argv[1];
5060         if (chdir(newdir)) {
5061                 printf("cd: %s: %s\n", newdir, strerror(errno));
5062                 return EXIT_FAILURE;
5063         }
5064         set_cwd();
5065         return EXIT_SUCCESS;
5066 }
5067
5068 static int builtin_exec(char **argv)
5069 {
5070         if (argv[1] == NULL)
5071                 return EXIT_SUCCESS; /* bash does this */
5072         {
5073 #if !BB_MMU
5074                 nommu_save_t dummy;
5075 #endif
5076 // FIXME: if exec fails, bash does NOT exit! We do...
5077                 pseudo_exec_argv(&dummy, argv + 1, 0, NULL);
5078                 /* never returns */
5079         }
5080 }
5081
5082 static int builtin_exit(char **argv)
5083 {
5084 // TODO: bash does it ONLY on top-level sh exit (+interacive only?)
5085         //puts("exit"); /* bash does it */
5086 // TODO: warn if we have background jobs: "There are stopped jobs"
5087 // On second consecutive 'exit', exit anyway.
5088         if (argv[1] == NULL)
5089                 hush_exit(G.last_return_code);
5090         /* mimic bash: exit 123abc == exit 255 + error msg */
5091         xfunc_error_retval = 255;
5092         /* bash: exit -2 == exit 254, no error msg */
5093         hush_exit(xatoi(argv[1]) & 0xff);
5094 }
5095
5096 static int builtin_export(char **argv)
5097 {
5098         const char *value;
5099         char *name = argv[1];
5100
5101         if (name == NULL) {
5102                 // TODO:
5103                 // ash emits: export VAR='VAL'
5104                 // bash: declare -x VAR="VAL"
5105                 // (both also escape as needed (quotes, $, etc))
5106                 char **e = environ;
5107                 if (e)
5108                         while (*e)
5109                                 puts(*e++);
5110                 return EXIT_SUCCESS;
5111         }
5112
5113         value = strchr(name, '=');
5114         if (!value) {
5115                 /* They are exporting something without a =VALUE */
5116                 struct variable *var;
5117
5118                 var = get_local_var(name);
5119                 if (var) {
5120                         var->flg_export = 1;
5121                         debug_printf_env("%s: putenv '%s'\n", __func__, var->varstr);
5122                         putenv(var->varstr);
5123                 }
5124                 /* bash does not return an error when trying to export
5125                  * an undefined variable.  Do likewise. */
5126                 return EXIT_SUCCESS;
5127         }
5128
5129         set_local_var(xstrdup(name), 1);
5130         return EXIT_SUCCESS;
5131 }
5132
5133 #if ENABLE_HUSH_JOB
5134 /* built-in 'fg' and 'bg' handler */
5135 static int builtin_fg_bg(char **argv)
5136 {
5137         int i, jobnum;
5138         struct pipe *pi;
5139
5140         if (!G_interactive_fd)
5141                 return EXIT_FAILURE;
5142         /* If they gave us no args, assume they want the last backgrounded task */
5143         if (!argv[1]) {
5144                 for (pi = G.job_list; pi; pi = pi->next) {
5145                         if (pi->jobid == G.last_jobid) {
5146                                 goto found;
5147                         }
5148                 }
5149                 bb_error_msg("%s: no current job", argv[0]);
5150                 return EXIT_FAILURE;
5151         }
5152         if (sscanf(argv[1], "%%%d", &jobnum) != 1) {
5153                 bb_error_msg("%s: bad argument '%s'", argv[0], argv[1]);
5154                 return EXIT_FAILURE;
5155         }
5156         for (pi = G.job_list; pi; pi = pi->next) {
5157                 if (pi->jobid == jobnum) {
5158                         goto found;
5159                 }
5160         }
5161         bb_error_msg("%s: %d: no such job", argv[0], jobnum);
5162         return EXIT_FAILURE;
5163  found:
5164         // TODO: bash prints a string representation
5165         // of job being foregrounded (like "sleep 1 | cat")
5166         if (*argv[0] == 'f') {
5167                 /* Put the job into the foreground.  */
5168                 tcsetpgrp(G_interactive_fd, pi->pgrp);
5169         }
5170
5171         /* Restart the processes in the job */
5172         debug_printf_jobs("reviving %d procs, pgrp %d\n", pi->num_cmds, pi->pgrp);
5173         for (i = 0; i < pi->num_cmds; i++) {
5174                 debug_printf_jobs("reviving pid %d\n", pi->cmds[i].pid);
5175                 pi->cmds[i].is_stopped = 0;
5176         }
5177         pi->stopped_cmds = 0;
5178
5179         i = kill(- pi->pgrp, SIGCONT);
5180         if (i < 0) {
5181                 if (errno == ESRCH) {
5182                         delete_finished_bg_job(pi);
5183                         return EXIT_SUCCESS;
5184                 } else {
5185                         bb_perror_msg("kill (SIGCONT)");
5186                 }
5187         }
5188
5189         if (*argv[0] == 'f') {
5190                 remove_bg_job(pi);
5191                 return checkjobs_and_fg_shell(pi);
5192         }
5193         return EXIT_SUCCESS;
5194 }
5195 #endif
5196
5197 #if ENABLE_HUSH_HELP
5198 static int builtin_help(char **argv UNUSED_PARAM)
5199 {
5200         const struct built_in_command *x;
5201
5202         printf("\nBuilt-in commands:\n");
5203         printf("-------------------\n");
5204         for (x = bltins; x != &bltins[ARRAY_SIZE(bltins)]; x++) {
5205                 printf("%s\t%s\n", x->cmd, x->descr);
5206         }
5207         printf("\n\n");
5208         return EXIT_SUCCESS;
5209 }
5210 #endif
5211
5212 #if ENABLE_HUSH_JOB
5213 static int builtin_jobs(char **argv UNUSED_PARAM)
5214 {
5215         struct pipe *job;
5216         const char *status_string;
5217
5218         for (job = G.job_list; job; job = job->next) {
5219                 if (job->alive_cmds == job->stopped_cmds)
5220                         status_string = "Stopped";
5221                 else
5222                         status_string = "Running";
5223
5224                 printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->cmdtext);
5225         }
5226         return EXIT_SUCCESS;
5227 }
5228 #endif
5229
5230 static int builtin_pwd(char **argv UNUSED_PARAM)
5231 {
5232         puts(set_cwd());
5233         return EXIT_SUCCESS;
5234 }
5235
5236 static int builtin_read(char **argv)
5237 {
5238         char *string;
5239         const char *name = argv[1] ? argv[1] : "REPLY";
5240
5241         string = xmalloc_reads(STDIN_FILENO, xasprintf("%s=", name), NULL);
5242         return set_local_var(string, 0);
5243 }
5244
5245 /* http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#set
5246  * built-in 'set' handler
5247  * SUSv3 says:
5248  * set [-abCefhmnuvx] [-o option] [argument...]
5249  * set [+abCefhmnuvx] [+o option] [argument...]
5250  * set -- [argument...]
5251  * set -o
5252  * set +o
5253  * Implementations shall support the options in both their hyphen and
5254  * plus-sign forms. These options can also be specified as options to sh.
5255  * Examples:
5256  * Write out all variables and their values: set
5257  * Set $1, $2, and $3 and set "$#" to 3: set c a b
5258  * Turn on the -x and -v options: set -xv
5259  * Unset all positional parameters: set --
5260  * Set $1 to the value of x, even if it begins with '-' or '+': set -- "$x"
5261  * Set the positional parameters to the expansion of x, even if x expands
5262  * with a leading '-' or '+': set -- $x
5263  *
5264  * So far, we only support "set -- [argument...]" and some of the short names.
5265  */
5266 static int builtin_set(char **argv)
5267 {
5268         int n;
5269         char **pp, **g_argv;
5270         char *arg = *++argv;
5271
5272         if (arg == NULL) {
5273                 struct variable *e;
5274                 for (e = G.top_var; e; e = e->next)
5275                         puts(e->varstr);
5276                 return EXIT_SUCCESS;
5277         }
5278
5279         do {
5280                 if (!strcmp(arg, "--")) {
5281                         ++argv;
5282                         goto set_argv;
5283                 }
5284
5285                 if (arg[0] == '+' || arg[0] == '-') {
5286                         for (n = 1; arg[n]; ++n)
5287                                 if (set_mode(arg[0], arg[n]))
5288                                         goto error;
5289                         continue;
5290                 }
5291
5292                 break;
5293         } while ((arg = *++argv) != NULL);
5294         /* Now argv[0] is 1st argument */
5295
5296         /* Only reset global_argv if we didn't process anything */
5297         if (arg == NULL)
5298                 return EXIT_SUCCESS;
5299  set_argv:
5300
5301         /* NB: G.global_argv[0] ($0) is never freed/changed */
5302         g_argv = G.global_argv;
5303         if (G.global_args_malloced) {
5304                 pp = g_argv;
5305                 while (*++pp)
5306                         free(*pp);
5307                 g_argv[1] = NULL;
5308         } else {
5309                 G.global_args_malloced = 1;
5310                 pp = xzalloc(sizeof(pp[0]) * 2);
5311                 pp[0] = g_argv[0]; /* retain $0 */
5312                 g_argv = pp;
5313         }
5314         /* This realloc's G.global_argv */
5315         G.global_argv = pp = add_strings_to_strings(g_argv, argv, /*dup:*/ 1);
5316
5317         n = 1;
5318         while (*++pp)
5319                 n++;
5320         G.global_argc = n;
5321
5322         return EXIT_SUCCESS;
5323
5324         /* Nothing known, so abort */
5325  error:
5326         bb_error_msg("set: %s: invalid option", arg);
5327         return EXIT_FAILURE;
5328 }
5329
5330 static int builtin_shift(char **argv)
5331 {
5332         int n = 1;
5333         if (argv[1]) {
5334                 n = atoi(argv[1]);
5335         }
5336         if (n >= 0 && n < G.global_argc) {
5337                 if (G.global_args_malloced) {
5338                         int m = 1;
5339                         while (m <= n)
5340                                 free(G.global_argv[m++]);
5341                 }
5342                 G.global_argc -= n;
5343                 memmove(&G.global_argv[1], &G.global_argv[n+1],
5344                                 G.global_argc * sizeof(G.global_argv[0]));
5345                 return EXIT_SUCCESS;
5346         }
5347         return EXIT_FAILURE;
5348 }
5349
5350 static int builtin_source(char **argv)
5351 {
5352         FILE *input;
5353
5354         if (argv[1] == NULL)
5355                 return EXIT_FAILURE;
5356
5357         /* XXX search through $PATH is missing */
5358         input = fopen_for_read(argv[1]);
5359         if (!input) {
5360                 bb_error_msg("can't open '%s'", argv[1]);
5361                 return EXIT_FAILURE;
5362         }
5363         close_on_exec_on(fileno(input));
5364
5365         /* Now run the file */
5366         /* XXX argv and argc are broken; need to save old G.global_argv
5367          * (pointer only is OK!) on this stack frame,
5368          * set G.global_argv=argv+1, recurse, and restore. */
5369         parse_and_run_file(input);
5370         fclose(input);
5371         return G.last_return_code;
5372 }
5373
5374 static int builtin_umask(char **argv)
5375 {
5376         mode_t new_umask;
5377         const char *arg = argv[1];
5378         if (arg) {
5379                 new_umask = bb_strtou(arg, NULL, 8);
5380                 if (errno)
5381                         return EXIT_FAILURE;
5382         } else {
5383                 new_umask = umask(0);
5384                 printf("%.3o\n", (unsigned) new_umask);
5385         }
5386         umask(new_umask);
5387         return EXIT_SUCCESS;
5388 }
5389
5390 /* http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#unset */
5391 static int builtin_unset(char **argv)
5392 {
5393         size_t i;
5394         int ret;
5395         bool var = true;
5396
5397         if (!argv[1])
5398                 return EXIT_SUCCESS;
5399
5400         i = 0;
5401         if (argv[1][0] == '-') {
5402                 switch (argv[1][1]) {
5403                 case 'v': break;
5404                 case 'f': if (ENABLE_HUSH_FUNCTIONS) { var = false; break; }
5405                 default:
5406                         bb_error_msg("unset: %s: invalid option", argv[1]);
5407                         return EXIT_FAILURE;
5408                 }
5409                 ++i;
5410         }
5411
5412         ret = EXIT_SUCCESS;
5413         while (argv[++i]) {
5414                 if (var) {
5415                         if (unset_local_var(argv[i]))
5416                                 ret = EXIT_FAILURE;
5417                 }
5418 #if ENABLE_HUSH_FUNCTIONS
5419                 else
5420                         unset_local_func(argv[i]);
5421 #endif
5422         }
5423         return ret;
5424 }
5425
5426 /* http://www.opengroup.org/onlinepubs/9699919799/utilities/wait.html */
5427 static int builtin_wait(char **argv)
5428 {
5429         int ret = EXIT_SUCCESS;
5430         int status, sig;
5431
5432         if (*++argv == NULL) {
5433                 /* Don't care about wait results */
5434                 /* Note 1: must wait until there are no more children */
5435                 /* Note 2: must be interruptible */
5436                 /* Examples:
5437                  * $ sleep 3 & sleep 6 & wait
5438                  * [1] 30934 sleep 3
5439                  * [2] 30935 sleep 6
5440                  * [1] Done                   sleep 3
5441                  * [2] Done                   sleep 6
5442                  * $ sleep 3 & sleep 6 & wait
5443                  * [1] 30936 sleep 3
5444                  * [2] 30937 sleep 6
5445                  * [1] Done                   sleep 3
5446                  * ^C <-- after ~4 sec from keyboard
5447                  * $
5448                  */
5449                 sigaddset(&G.blocked_set, SIGCHLD);
5450                 sigprocmask(SIG_SETMASK, &G.blocked_set, NULL);
5451                 while (1) {
5452                         checkjobs(NULL);
5453                         if (errno == ECHILD)
5454                                 break;
5455                         /* Wait for SIGCHLD or any other signal of interest */
5456                         /* sigtimedwait with infinite timeout: */
5457                         sig = sigwaitinfo(&G.blocked_set, NULL);
5458                         if (sig > 0) {
5459                                 sig = check_and_run_traps(sig);
5460                                 if (sig && sig != SIGCHLD) { /* see note 2 */
5461                                         ret = 128 + sig;
5462                                         break;
5463                                 }
5464                         }
5465                 }
5466                 sigdelset(&G.blocked_set, SIGCHLD);
5467                 sigprocmask(SIG_SETMASK, &G.blocked_set, NULL);
5468                 return ret;
5469         }
5470
5471         /* This is probably buggy wrt interruptible-ness */
5472         while (*argv) {
5473                 pid_t pid = bb_strtou(*argv, NULL, 10);
5474                 if (errno) {
5475                         /* mimic bash message */
5476                         bb_error_msg("wait: '%s': not a pid or valid job spec", *argv);
5477                         return EXIT_FAILURE;
5478                 }
5479                 if (waitpid(pid, &status, 0) == pid) {
5480                         if (WIFSIGNALED(status))
5481                                 ret = 128 + WTERMSIG(status);
5482                         else if (WIFEXITED(status))
5483                                 ret = WEXITSTATUS(status);
5484                         else /* wtf? */
5485                                 ret = EXIT_FAILURE;
5486                 } else {
5487                         bb_perror_msg("wait %s", *argv);
5488                         ret = 127;
5489                 }
5490                 argv++;
5491         }
5492
5493         return ret;
5494 }
5495
5496 #if ENABLE_HUSH_LOOPS
5497 static int builtin_break(char **argv)
5498 {
5499         if (G.depth_of_loop == 0) {
5500                 bb_error_msg("%s: only meaningful in a loop", argv[0]);
5501                 return EXIT_SUCCESS; /* bash compat */
5502         }
5503         G.flag_break_continue++; /* BC_BREAK = 1 */
5504         G.depth_break_continue = 1;
5505         if (argv[1]) {
5506                 G.depth_break_continue = bb_strtou(argv[1], NULL, 10);
5507                 if (errno || !G.depth_break_continue || argv[2]) {
5508                         bb_error_msg("%s: bad arguments", argv[0]);
5509                         G.flag_break_continue = BC_BREAK;
5510                         G.depth_break_continue = UINT_MAX;
5511                 }
5512         }
5513         if (G.depth_of_loop < G.depth_break_continue)
5514                 G.depth_break_continue = G.depth_of_loop;
5515         return EXIT_SUCCESS;
5516 }
5517
5518 static int builtin_continue(char **argv)
5519 {
5520         G.flag_break_continue = 1; /* BC_CONTINUE = 2 = 1+1 */
5521         return builtin_break(argv);
5522 }
5523 #endif