source: branches/2.2.9/mindi-busybox/shell/hush.c @ 2859

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