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