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

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