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