hush: implement "return NUM in trap sets $? after trap"
[oweals/busybox.git] / shell / hush.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * A prototype Bourne shell grammar parser.
4  * Intended to follow the original Thompson and Ritchie
5  * "small and simple is beautiful" philosophy, which
6  * incidentally is a good match to today's BusyBox.
7  *
8  * Copyright (C) 2000,2001  Larry Doolittle <larry@doolittle.boa.org>
9  * 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  *      make complex ${var%...} constructs support optional
45  *      make here documents optional
46  *      special variables (done: PWD, PPID, RANDOM)
47  *      follow IFS rules more precisely, including update semantics
48  *      tilde expansion
49  *      aliases
50  *      "command" missing features:
51  *          command -p CMD: run CMD using default $PATH
52  *              (can use this to override standalone shell as well?)
53  *          command BLTIN: disables special-ness (e.g. errors do not abort)
54  *          command -V CMD1 CMD2 CMD3 (multiple args) (not in standard)
55  *      builtins mandated by standards we don't support:
56  *          [un]alias, fc:
57  *          fc -l[nr] [BEG] [END]: list range of commands in history
58  *          fc [-e EDITOR] [BEG] [END]: edit/rerun range of commands
59  *          fc -s [PAT=REP] [CMD]: rerun CMD, replacing PAT with REP
60  *
61  * Bash compat TODO:
62  *      redirection of stdout+stderr: &> and >&
63  *      reserved words: function select
64  *      advanced test: [[ ]]
65  *      process substitution: <(list) and >(list)
66  *      =~: regex operator
67  *      let EXPR [EXPR...]
68  *          Each EXPR is an arithmetic expression (ARITHMETIC EVALUATION)
69  *          If the last arg evaluates to 0, let returns 1; 0 otherwise.
70  *          NB: let `echo 'a=a + 1'` - error (IOW: multi-word expansion is used)
71  *      ((EXPR))
72  *          The EXPR is evaluated according to ARITHMETIC EVALUATION.
73  *          This is exactly equivalent to let "EXPR".
74  *      $[EXPR]: synonym for $((EXPR))
75  *      indirect expansion: ${!VAR}
76  *      substring op on @: ${@:n:m}
77  *
78  * Won't do:
79  *      Some builtins mandated by standards:
80  *          newgrp [GRP]: not a builtin in bash but a suid binary
81  *              which spawns a new shell with new group ID
82  *
83  * Status of [[ support:
84  * [[ args ]] are CMD_SINGLEWORD_NOGLOB:
85  *   v='a b'; [[ $v = 'a b' ]]; echo 0:$?
86  *   [[ /bin/n* ]]; echo 0:$?
87  * TODO:
88  * &&/|| are AND/OR ops, -a/-o are not
89  * quoting needs to be considered (-f is an operator, "-f" and ""-f are not; etc)
90  * = is glob match operator, not equality operator: STR = GLOB
91  * (in GLOB, quoting is significant on char-by-char basis: a*cd"*")
92  * == same as =
93  * add =~ regex match operator: STR =~ REGEX
94  */
95 //config:config HUSH
96 //config:       bool "hush (68 kb)"
97 //config:       default y
98 //config:       help
99 //config:       hush is a small shell. It handles the normal flow control
100 //config:       constructs such as if/then/elif/else/fi, for/in/do/done, while loops,
101 //config:       case/esac. Redirections, here documents, $((arithmetic))
102 //config:       and functions are supported.
103 //config:
104 //config:       It will compile and work on no-mmu systems.
105 //config:
106 //config:       It does not handle select, aliases, tilde expansion,
107 //config:       &>file and >&file redirection of stdout+stderr.
108 //config:
109 //config:config HUSH_BASH_COMPAT
110 //config:       bool "bash-compatible extensions"
111 //config:       default y
112 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
113 //config:
114 //config:config HUSH_BRACE_EXPANSION
115 //config:       bool "Brace expansion"
116 //config:       default y
117 //config:       depends on HUSH_BASH_COMPAT
118 //config:       help
119 //config:       Enable {abc,def} extension.
120 //config:
121 //config:config HUSH_LINENO_VAR
122 //config:       bool "$LINENO variable"
123 //config:       default y
124 //config:       depends on HUSH_BASH_COMPAT
125 //config:
126 //config:config HUSH_BASH_SOURCE_CURDIR
127 //config:       bool "'source' and '.' builtins search current directory after $PATH"
128 //config:       default n   # do not encourage non-standard behavior
129 //config:       depends on HUSH_BASH_COMPAT
130 //config:       help
131 //config:       This is not compliant with standards. Avoid if possible.
132 //config:
133 //config:config HUSH_INTERACTIVE
134 //config:       bool "Interactive mode"
135 //config:       default y
136 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
137 //config:       help
138 //config:       Enable interactive mode (prompt and command editing).
139 //config:       Without this, hush simply reads and executes commands
140 //config:       from stdin just like a shell script from a file.
141 //config:       No prompt, no PS1/PS2 magic shell variables.
142 //config:
143 //config:config HUSH_SAVEHISTORY
144 //config:       bool "Save command history to .hush_history"
145 //config:       default y
146 //config:       depends on HUSH_INTERACTIVE && FEATURE_EDITING_SAVEHISTORY
147 //config:
148 //config:config HUSH_JOB
149 //config:       bool "Job control"
150 //config:       default y
151 //config:       depends on HUSH_INTERACTIVE
152 //config:       help
153 //config:       Enable job control: Ctrl-Z backgrounds, Ctrl-C interrupts current
154 //config:       command (not entire shell), fg/bg builtins work. Without this option,
155 //config:       "cmd &" still works by simply spawning a process and immediately
156 //config:       prompting for next command (or executing next command in a script),
157 //config:       but no separate process group is formed.
158 //config:
159 //config:config HUSH_TICK
160 //config:       bool "Support command substitution"
161 //config:       default y
162 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
163 //config:       help
164 //config:       Enable `command` and $(command).
165 //config:
166 //config:config HUSH_IF
167 //config:       bool "Support if/then/elif/else/fi"
168 //config:       default y
169 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
170 //config:
171 //config:config HUSH_LOOPS
172 //config:       bool "Support for, while and until loops"
173 //config:       default y
174 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
175 //config:
176 //config:config HUSH_CASE
177 //config:       bool "Support case ... esac statement"
178 //config:       default y
179 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
180 //config:       help
181 //config:       Enable case ... esac statement. +400 bytes.
182 //config:
183 //config:config HUSH_FUNCTIONS
184 //config:       bool "Support funcname() { commands; } syntax"
185 //config:       default y
186 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
187 //config:       help
188 //config:       Enable support for shell functions. +800 bytes.
189 //config:
190 //config:config HUSH_LOCAL
191 //config:       bool "local builtin"
192 //config:       default y
193 //config:       depends on HUSH_FUNCTIONS
194 //config:       help
195 //config:       Enable support for local variables in functions.
196 //config:
197 //config:config HUSH_RANDOM_SUPPORT
198 //config:       bool "Pseudorandom generator and $RANDOM variable"
199 //config:       default y
200 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
201 //config:       help
202 //config:       Enable pseudorandom generator and dynamic variable "$RANDOM".
203 //config:       Each read of "$RANDOM" will generate a new pseudorandom value.
204 //config:
205 //config:config HUSH_MODE_X
206 //config:       bool "Support 'hush -x' option and 'set -x' command"
207 //config:       default y
208 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
209 //config:       help
210 //config:       This instructs hush to print commands before execution.
211 //config:       Adds ~300 bytes.
212 //config:
213 //config:config HUSH_ECHO
214 //config:       bool "echo builtin"
215 //config:       default y
216 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
217 //config:
218 //config:config HUSH_PRINTF
219 //config:       bool "printf builtin"
220 //config:       default y
221 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
222 //config:
223 //config:config HUSH_TEST
224 //config:       bool "test builtin"
225 //config:       default y
226 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
227 //config:
228 //config:config HUSH_HELP
229 //config:       bool "help builtin"
230 //config:       default y
231 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
232 //config:
233 //config:config HUSH_EXPORT
234 //config:       bool "export builtin"
235 //config:       default y
236 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
237 //config:
238 //config:config HUSH_EXPORT_N
239 //config:       bool "Support 'export -n' option"
240 //config:       default y
241 //config:       depends on HUSH_EXPORT
242 //config:       help
243 //config:       export -n unexports variables. It is a bash extension.
244 //config:
245 //config:config HUSH_READONLY
246 //config:       bool "readonly builtin"
247 //config:       default y
248 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
249 //config:       help
250 //config:       Enable support for read-only variables.
251 //config:
252 //config:config HUSH_KILL
253 //config:       bool "kill builtin (supports kill %jobspec)"
254 //config:       default y
255 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
256 //config:
257 //config:config HUSH_WAIT
258 //config:       bool "wait builtin"
259 //config:       default y
260 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
261 //config:
262 //config:config HUSH_COMMAND
263 //config:       bool "command builtin"
264 //config:       default y
265 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
266 //config:
267 //config:config HUSH_TRAP
268 //config:       bool "trap builtin"
269 //config:       default y
270 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
271 //config:
272 //config:config HUSH_TYPE
273 //config:       bool "type builtin"
274 //config:       default y
275 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
276 //config:
277 //config:config HUSH_TIMES
278 //config:       bool "times builtin"
279 //config:       default y
280 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
281 //config:
282 //config:config HUSH_READ
283 //config:       bool "read builtin"
284 //config:       default y
285 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
286 //config:
287 //config:config HUSH_SET
288 //config:       bool "set builtin"
289 //config:       default y
290 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
291 //config:
292 //config:config HUSH_UNSET
293 //config:       bool "unset builtin"
294 //config:       default y
295 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
296 //config:
297 //config:config HUSH_ULIMIT
298 //config:       bool "ulimit builtin"
299 //config:       default y
300 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
301 //config:
302 //config:config HUSH_UMASK
303 //config:       bool "umask builtin"
304 //config:       default y
305 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
306 //config:
307 //config:config HUSH_GETOPTS
308 //config:       bool "getopts builtin"
309 //config:       default y
310 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
311 //config:
312 //config:config HUSH_MEMLEAK
313 //config:       bool "memleak builtin (debugging)"
314 //config:       default n
315 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
316
317 //applet:IF_HUSH(APPLET(hush, BB_DIR_BIN, BB_SUID_DROP))
318 //                       APPLET_ODDNAME:name  main  location    suid_type     help
319 //applet:IF_SH_IS_HUSH(  APPLET_ODDNAME(sh,   hush, BB_DIR_BIN, BB_SUID_DROP, hush))
320 //applet:IF_BASH_IS_HUSH(APPLET_ODDNAME(bash, hush, BB_DIR_BIN, BB_SUID_DROP, hush))
321
322 //kbuild:lib-$(CONFIG_HUSH) += hush.o match.o shell_common.o
323 //kbuild:lib-$(CONFIG_SH_IS_HUSH) += hush.o match.o shell_common.o
324 //kbuild:lib-$(CONFIG_BASH_IS_HUSH) += hush.o match.o shell_common.o
325 //kbuild:lib-$(CONFIG_HUSH_RANDOM_SUPPORT) += random.o
326
327 /* -i (interactive) is also accepted,
328  * but does nothing, therefore not shown in help.
329  * NOMMU-specific options are not meant to be used by users,
330  * therefore we don't show them either.
331  */
332 //usage:#define hush_trivial_usage
333 //usage:        "[-enxl] [-c 'SCRIPT' [ARG0 [ARGS]] / FILE [ARGS] / -s [ARGS]]"
334 //usage:#define hush_full_usage "\n\n"
335 //usage:        "Unix shell interpreter"
336
337 #if !(defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) \
338         || defined(__APPLE__) \
339     )
340 # include <malloc.h>   /* for malloc_trim */
341 #endif
342 #include <glob.h>
343 /* #include <dmalloc.h> */
344 #if ENABLE_HUSH_CASE
345 # include <fnmatch.h>
346 #endif
347 #include <sys/times.h>
348 #include <sys/utsname.h> /* for setting $HOSTNAME */
349
350 #include "busybox.h"  /* for APPLET_IS_NOFORK/NOEXEC */
351 #include "unicode.h"
352 #include "shell_common.h"
353 #include "math.h"
354 #include "match.h"
355 #if ENABLE_HUSH_RANDOM_SUPPORT
356 # include "random.h"
357 #else
358 # define CLEAR_RANDOM_T(rnd) ((void)0)
359 #endif
360 #ifndef O_CLOEXEC
361 # define O_CLOEXEC 0
362 #endif
363 #ifndef F_DUPFD_CLOEXEC
364 # define F_DUPFD_CLOEXEC F_DUPFD
365 #endif
366
367 #if ENABLE_FEATURE_SH_EMBEDDED_SCRIPTS && !(ENABLE_ASH || ENABLE_SH_IS_ASH || ENABLE_BASH_IS_ASH)
368 # include "embedded_scripts.h"
369 #else
370 # define NUM_SCRIPTS 0
371 #endif
372
373 /* So far, all bash compat is controlled by one config option */
374 /* Separate defines document which part of code implements what */
375 #define BASH_PATTERN_SUBST ENABLE_HUSH_BASH_COMPAT
376 #define BASH_SUBSTR        ENABLE_HUSH_BASH_COMPAT
377 #define BASH_SOURCE        ENABLE_HUSH_BASH_COMPAT
378 #define BASH_HOSTNAME_VAR  ENABLE_HUSH_BASH_COMPAT
379 #define BASH_EPOCH_VARS    ENABLE_HUSH_BASH_COMPAT
380 #define BASH_TEST2         (ENABLE_HUSH_BASH_COMPAT && ENABLE_HUSH_TEST)
381 #define BASH_READ_D        ENABLE_HUSH_BASH_COMPAT
382
383
384 /* Build knobs */
385 #define LEAK_HUNTING 0
386 #define BUILD_AS_NOMMU 0
387 /* Enable/disable sanity checks. Ok to enable in production,
388  * only adds a bit of bloat. Set to >1 to get non-production level verbosity.
389  * Keeping 1 for now even in released versions.
390  */
391 #define HUSH_DEBUG 1
392 /* Slightly bigger (+200 bytes), but faster hush.
393  * So far it only enables a trick with counting SIGCHLDs and forks,
394  * which allows us to do fewer waitpid's.
395  * (we can detect a case where neither forks were done nor SIGCHLDs happened
396  * and therefore waitpid will return the same result as last time)
397  */
398 #define ENABLE_HUSH_FAST 0
399 /* TODO: implement simplified code for users which do not need ${var%...} ops
400  * So far ${var%...} ops are always enabled:
401  */
402 #define ENABLE_HUSH_DOLLAR_OPS 1
403
404
405 #if BUILD_AS_NOMMU
406 # undef BB_MMU
407 # undef USE_FOR_NOMMU
408 # undef USE_FOR_MMU
409 # define BB_MMU 0
410 # define USE_FOR_NOMMU(...) __VA_ARGS__
411 # define USE_FOR_MMU(...)
412 #endif
413
414 #include "NUM_APPLETS.h"
415 #if NUM_APPLETS == 1
416 /* STANDALONE does not make sense, and won't compile */
417 # undef CONFIG_FEATURE_SH_STANDALONE
418 # undef ENABLE_FEATURE_SH_STANDALONE
419 # undef IF_FEATURE_SH_STANDALONE
420 # undef IF_NOT_FEATURE_SH_STANDALONE
421 # define ENABLE_FEATURE_SH_STANDALONE 0
422 # define IF_FEATURE_SH_STANDALONE(...)
423 # define IF_NOT_FEATURE_SH_STANDALONE(...) __VA_ARGS__
424 #endif
425
426 #if !ENABLE_HUSH_INTERACTIVE
427 # undef ENABLE_FEATURE_EDITING
428 # define ENABLE_FEATURE_EDITING 0
429 # undef ENABLE_FEATURE_EDITING_FANCY_PROMPT
430 # define ENABLE_FEATURE_EDITING_FANCY_PROMPT 0
431 # undef ENABLE_FEATURE_EDITING_SAVE_ON_EXIT
432 # define ENABLE_FEATURE_EDITING_SAVE_ON_EXIT 0
433 #endif
434
435 /* Do we support ANY keywords? */
436 #if ENABLE_HUSH_IF || ENABLE_HUSH_LOOPS || ENABLE_HUSH_CASE
437 # define HAS_KEYWORDS 1
438 # define IF_HAS_KEYWORDS(...) __VA_ARGS__
439 # define IF_HAS_NO_KEYWORDS(...)
440 #else
441 # define HAS_KEYWORDS 0
442 # define IF_HAS_KEYWORDS(...)
443 # define IF_HAS_NO_KEYWORDS(...) __VA_ARGS__
444 #endif
445
446 /* If you comment out one of these below, it will be #defined later
447  * to perform debug printfs to stderr: */
448 #define debug_printf(...)         do {} while (0)
449 /* Finer-grained debug switches */
450 #define debug_printf_parse(...)   do {} while (0)
451 #define debug_printf_heredoc(...) do {} while (0)
452 #define debug_print_tree(a, b)    do {} while (0)
453 #define debug_printf_exec(...)    do {} while (0)
454 #define debug_printf_env(...)     do {} while (0)
455 #define debug_printf_jobs(...)    do {} while (0)
456 #define debug_printf_expand(...)  do {} while (0)
457 #define debug_printf_varexp(...)  do {} while (0)
458 #define debug_printf_glob(...)    do {} while (0)
459 #define debug_printf_redir(...)   do {} while (0)
460 #define debug_printf_list(...)    do {} while (0)
461 #define debug_printf_subst(...)   do {} while (0)
462 #define debug_printf_prompt(...)  do {} while (0)
463 #define debug_printf_clean(...)   do {} while (0)
464
465 #define ERR_PTR ((void*)(long)1)
466
467 #define JOB_STATUS_FORMAT    "[%u] %-22s %.40s\n"
468
469 #define _SPECIAL_VARS_STR     "_*@$!?#-"
470 #define SPECIAL_VARS_STR     ("_*@$!?#-" + 1)
471 #define NUMERIC_SPECVARS_STR ("_*@$!?#-" + 3)
472 #if BASH_PATTERN_SUBST
473 /* Support / and // replace ops */
474 /* Note that // is stored as \ in "encoded" string representation */
475 # define VAR_ENCODED_SUBST_OPS      "\\/%#:-=+?"
476 # define VAR_SUBST_OPS             ("\\/%#:-=+?" + 1)
477 # define MINUS_PLUS_EQUAL_QUESTION ("\\/%#:-=+?" + 5)
478 #else
479 # define VAR_ENCODED_SUBST_OPS      "%#:-=+?"
480 # define VAR_SUBST_OPS              "%#:-=+?"
481 # define MINUS_PLUS_EQUAL_QUESTION ("%#:-=+?" + 3)
482 #endif
483
484 #define SPECIAL_VAR_SYMBOL_STR "\3"
485 #define SPECIAL_VAR_SYMBOL       3
486 /* The "variable" with name "\1" emits string "\3". Testcase: "echo ^C" */
487 #define SPECIAL_VAR_QUOTED_SVS   1
488
489 struct variable;
490
491 static const char hush_version_str[] ALIGN1 = "HUSH_VERSION="BB_VER;
492
493 /* This supports saving pointers malloced in vfork child,
494  * to be freed in the parent.
495  */
496 #if !BB_MMU
497 typedef struct nommu_save_t {
498         struct variable *old_vars;
499         char **argv;
500         char **argv_from_re_execing;
501 } nommu_save_t;
502 #endif
503
504 enum {
505         RES_NONE  = 0,
506 #if ENABLE_HUSH_IF
507         RES_IF    ,
508         RES_THEN  ,
509         RES_ELIF  ,
510         RES_ELSE  ,
511         RES_FI    ,
512 #endif
513 #if ENABLE_HUSH_LOOPS
514         RES_FOR   ,
515         RES_WHILE ,
516         RES_UNTIL ,
517         RES_DO    ,
518         RES_DONE  ,
519 #endif
520 #if ENABLE_HUSH_LOOPS || ENABLE_HUSH_CASE
521         RES_IN    ,
522 #endif
523 #if ENABLE_HUSH_CASE
524         RES_CASE  ,
525         /* three pseudo-keywords support contrived "case" syntax: */
526         RES_CASE_IN,   /* "case ... IN", turns into RES_MATCH when IN is observed */
527         RES_MATCH ,    /* "word)" */
528         RES_CASE_BODY, /* "this command is inside CASE" */
529         RES_ESAC  ,
530 #endif
531         RES_XXXX  ,
532         RES_SNTX
533 };
534
535 typedef struct o_string {
536         char *data;
537         int length; /* position where data is appended */
538         int maxlen;
539         int o_expflags;
540         /* At least some part of the string was inside '' or "",
541          * possibly empty one: word"", wo''rd etc. */
542         smallint has_quoted_part;
543         smallint has_empty_slot;
544         smallint ended_in_ifs;
545 } o_string;
546 enum {
547         EXP_FLAG_SINGLEWORD     = 0x80, /* must be 0x80 */
548         EXP_FLAG_GLOB           = 0x2,
549         /* Protect newly added chars against globbing
550          * by prepending \ to *, ?, [, \ */
551         EXP_FLAG_ESC_GLOB_CHARS = 0x1,
552 };
553 /* Used for initialization: o_string foo = NULL_O_STRING; */
554 #define NULL_O_STRING { NULL }
555
556 #ifndef debug_printf_parse
557 static const char *const assignment_flag[] = {
558         "MAYBE_ASSIGNMENT",
559         "DEFINITELY_ASSIGNMENT",
560         "NOT_ASSIGNMENT",
561         "WORD_IS_KEYWORD",
562 };
563 #endif
564
565 /* We almost can use standard FILE api, but we need an ability to move
566  * its fd when redirects coincide with it. No api exists for that
567  * (RFE for it at https://sourceware.org/bugzilla/show_bug.cgi?id=21902).
568  * HFILE is our internal alternative. Only supports reading.
569  * Since we now can, we incorporate linked list of all opened HFILEs
570  * into the struct (used to be a separate mini-list).
571  */
572 typedef struct HFILE {
573         char *cur;
574         char *end;
575         struct HFILE *next_hfile;
576         int fd;
577         char buf[1024];
578 } HFILE;
579
580 typedef struct in_str {
581         const char *p;
582         int peek_buf[2];
583         int last_char;
584         HFILE *file;
585 } in_str;
586
587 /* The descrip member of this structure is only used to make
588  * debugging output pretty */
589 static const struct {
590         int mode;
591         signed char default_fd;
592         char descrip[3];
593 } redir_table[] = {
594         { O_RDONLY,                  0, "<"  },
595         { O_CREAT|O_TRUNC|O_WRONLY,  1, ">"  },
596         { O_CREAT|O_APPEND|O_WRONLY, 1, ">>" },
597         { O_CREAT|O_RDWR,            1, "<>" },
598         { O_RDONLY,                  0, "<<" },
599 /* Should not be needed. Bogus default_fd helps in debugging */
600 /*      { O_RDONLY,                 77, "<<" }, */
601 };
602
603 struct redir_struct {
604         struct redir_struct *next;
605         char *rd_filename;          /* filename */
606         int rd_fd;                  /* fd to redirect */
607         /* fd to redirect to, or -3 if rd_fd is to be closed (n>&-) */
608         int rd_dup;
609         smallint rd_type;           /* (enum redir_type) */
610         /* note: for heredocs, rd_filename contains heredoc delimiter,
611          * and subsequently heredoc itself; and rd_dup is a bitmask:
612          * bit 0: do we need to trim leading tabs?
613          * bit 1: is heredoc quoted (<<'delim' syntax) ?
614          */
615 };
616 typedef enum redir_type {
617         REDIRECT_INPUT     = 0,
618         REDIRECT_OVERWRITE = 1,
619         REDIRECT_APPEND    = 2,
620         REDIRECT_IO        = 3,
621         REDIRECT_HEREDOC   = 4,
622         REDIRECT_HEREDOC2  = 5, /* REDIRECT_HEREDOC after heredoc is loaded */
623
624         REDIRFD_CLOSE      = -3,
625         REDIRFD_SYNTAX_ERR = -2,
626         REDIRFD_TO_FILE    = -1,
627         /* otherwise, rd_fd is redirected to rd_dup */
628
629         HEREDOC_SKIPTABS = 1,
630         HEREDOC_QUOTED   = 2,
631 } redir_type;
632
633
634 struct command {
635         pid_t pid;                  /* 0 if exited */
636         unsigned assignment_cnt;    /* how many argv[i] are assignments? */
637 #if ENABLE_HUSH_LINENO_VAR
638         unsigned lineno;
639 #endif
640         smallint cmd_type;          /* CMD_xxx */
641 #define CMD_NORMAL   0
642 #define CMD_SUBSHELL 1
643 #if BASH_TEST2 || ENABLE_HUSH_LOCAL || ENABLE_HUSH_EXPORT || ENABLE_HUSH_READONLY
644 /* used for "[[ EXPR ]]", and to prevent word splitting and globbing in
645  * "export v=t*"
646  */
647 # define CMD_SINGLEWORD_NOGLOB 2
648 #endif
649 #if ENABLE_HUSH_FUNCTIONS
650 # define CMD_FUNCDEF 3
651 #endif
652
653         smalluint cmd_exitcode;
654         /* if non-NULL, this "command" is { list }, ( list ), or a compound statement */
655         struct pipe *group;
656 #if !BB_MMU
657         char *group_as_string;
658 #endif
659 #if ENABLE_HUSH_FUNCTIONS
660         struct function *child_func;
661 /* This field is used to prevent a bug here:
662  * while...do f1() {a;}; f1; f1() {b;}; f1; done
663  * When we execute "f1() {a;}" cmd, we create new function and clear
664  * cmd->group, cmd->group_as_string, cmd->argv[0].
665  * When we execute "f1() {b;}", we notice that f1 exists,
666  * and that its "parent cmd" struct is still "alive",
667  * we put those fields back into cmd->xxx
668  * (struct function has ->parent_cmd ptr to facilitate that).
669  * When we loop back, we can execute "f1() {a;}" again and set f1 correctly.
670  * Without this trick, loop would execute a;b;b;b;...
671  * instead of correct sequence a;b;a;b;...
672  * When command is freed, it severs the link
673  * (sets ->child_func->parent_cmd to NULL).
674  */
675 #endif
676         char **argv;                /* command name and arguments */
677 /* argv vector may contain variable references (^Cvar^C, ^C0^C etc)
678  * and on execution these are substituted with their values.
679  * Substitution can make _several_ words out of one argv[n]!
680  * Example: argv[0]=='.^C*^C.' here: echo .$*.
681  * References of the form ^C`cmd arg^C are `cmd arg` substitutions.
682  */
683         struct redir_struct *redirects; /* I/O redirections */
684 };
685 /* Is there anything in this command at all? */
686 #define IS_NULL_CMD(cmd) \
687         (!(cmd)->group && !(cmd)->argv && !(cmd)->redirects)
688
689 struct pipe {
690         struct pipe *next;
691         int num_cmds;               /* total number of commands in pipe */
692         int alive_cmds;             /* number of commands running (not exited) */
693         int stopped_cmds;           /* number of commands alive, but stopped */
694 #if ENABLE_HUSH_JOB
695         unsigned jobid;             /* job number */
696         pid_t pgrp;                 /* process group ID for the job */
697         char *cmdtext;              /* name of job */
698 #endif
699         struct command *cmds;       /* array of commands in pipe */
700         smallint followup;          /* PIPE_BG, PIPE_SEQ, PIPE_OR, PIPE_AND */
701         IF_HAS_KEYWORDS(smallint pi_inverted;) /* "! cmd | cmd" */
702         IF_HAS_KEYWORDS(smallint res_word;) /* needed for if, for, while, until... */
703 };
704 typedef enum pipe_style {
705         PIPE_SEQ = 0,
706         PIPE_AND = 1,
707         PIPE_OR  = 2,
708         PIPE_BG  = 3,
709 } pipe_style;
710 /* Is there anything in this pipe at all? */
711 #define IS_NULL_PIPE(pi) \
712         ((pi)->num_cmds == 0 IF_HAS_KEYWORDS( && (pi)->res_word == RES_NONE))
713
714 /* This holds pointers to the various results of parsing */
715 struct parse_context {
716         /* linked list of pipes */
717         struct pipe *list_head;
718         /* last pipe (being constructed right now) */
719         struct pipe *pipe;
720         /* last command in pipe (being constructed right now) */
721         struct command *command;
722         /* last redirect in command->redirects list */
723         struct redir_struct *pending_redirect;
724         o_string word;
725 #if !BB_MMU
726         o_string as_string;
727 #endif
728         smallint is_assignment; /* 0:maybe, 1:yes, 2:no, 3:keyword */
729 #if HAS_KEYWORDS
730         smallint ctx_res_w;
731         smallint ctx_inverted; /* "! cmd | cmd" */
732 #if ENABLE_HUSH_CASE
733         smallint ctx_dsemicolon; /* ";;" seen */
734 #endif
735         /* bitmask of FLAG_xxx, for figuring out valid reserved words */
736         int old_flag;
737         /* group we are enclosed in:
738          * example: "if pipe1; pipe2; then pipe3; fi"
739          * when we see "if" or "then", we malloc and copy current context,
740          * and make ->stack point to it. then we parse pipeN.
741          * when closing "then" / fi" / whatever is found,
742          * we move list_head into ->stack->command->group,
743          * copy ->stack into current context, and delete ->stack.
744          * (parsing of { list } and ( list ) doesn't use this method)
745          */
746         struct parse_context *stack;
747 #endif
748 };
749 enum {
750         MAYBE_ASSIGNMENT      = 0,
751         DEFINITELY_ASSIGNMENT = 1,
752         NOT_ASSIGNMENT        = 2,
753         /* Not an assignment, but next word may be: "if v=xyz cmd;" */
754         WORD_IS_KEYWORD       = 3,
755 };
756
757 /* On program start, environ points to initial environment.
758  * putenv adds new pointers into it, unsetenv removes them.
759  * Neither of these (de)allocates the strings.
760  * setenv allocates new strings in malloc space and does putenv,
761  * and thus setenv is unusable (leaky) for shell's purposes */
762 #define setenv(...) setenv_is_leaky_dont_use()
763 struct variable {
764         struct variable *next;
765         char *varstr;        /* points to "name=" portion */
766         int max_len;         /* if > 0, name is part of initial env; else name is malloced */
767         uint16_t var_nest_level;
768         smallint flg_export; /* putenv should be done on this var */
769         smallint flg_read_only;
770 };
771
772 enum {
773         BC_BREAK = 1,
774         BC_CONTINUE = 2,
775 };
776
777 #if ENABLE_HUSH_FUNCTIONS
778 struct function {
779         struct function *next;
780         char *name;
781         struct command *parent_cmd;
782         struct pipe *body;
783 # if !BB_MMU
784         char *body_as_string;
785 # endif
786 };
787 #endif
788
789
790 /* set -/+o OPT support. (TODO: make it optional)
791  * bash supports the following opts:
792  * allexport       off
793  * braceexpand     on
794  * emacs           on
795  * errexit         off
796  * errtrace        off
797  * functrace       off
798  * hashall         on
799  * histexpand      off
800  * history         on
801  * ignoreeof       off
802  * interactive-comments    on
803  * keyword         off
804  * monitor         on
805  * noclobber       off
806  * noexec          off
807  * noglob          off
808  * nolog           off
809  * notify          off
810  * nounset         off
811  * onecmd          off
812  * physical        off
813  * pipefail        off
814  * posix           off
815  * privileged      off
816  * verbose         off
817  * vi              off
818  * xtrace          off
819  */
820 static const char o_opt_strings[] ALIGN1 =
821         "pipefail\0"
822         "noexec\0"
823         "errexit\0"
824 #if ENABLE_HUSH_MODE_X
825         "xtrace\0"
826 #endif
827         ;
828 enum {
829         OPT_O_PIPEFAIL,
830         OPT_O_NOEXEC,
831         OPT_O_ERREXIT,
832 #if ENABLE_HUSH_MODE_X
833         OPT_O_XTRACE,
834 #endif
835         NUM_OPT_O
836 };
837
838 /* "Globals" within this file */
839 /* Sorted roughly by size (smaller offsets == smaller code) */
840 struct globals {
841         /* interactive_fd != 0 means we are an interactive shell.
842          * If we are, then saved_tty_pgrp can also be != 0, meaning
843          * that controlling tty is available. With saved_tty_pgrp == 0,
844          * job control still works, but terminal signals
845          * (^C, ^Z, ^Y, ^\) won't work at all, and background
846          * process groups can only be created with "cmd &".
847          * With saved_tty_pgrp != 0, hush will use tcsetpgrp()
848          * to give tty to the foreground process group,
849          * and will take it back when the group is stopped (^Z)
850          * or killed (^C).
851          */
852 #if ENABLE_HUSH_INTERACTIVE
853         /* 'interactive_fd' is a fd# open to ctty, if we have one
854          * _AND_ if we decided to act interactively */
855         int interactive_fd;
856         IF_NOT_FEATURE_EDITING_FANCY_PROMPT(char *PS1;)
857 # define G_interactive_fd (G.interactive_fd)
858 #else
859 # define G_interactive_fd 0
860 #endif
861 #if ENABLE_FEATURE_EDITING
862         line_input_t *line_input_state;
863 #endif
864         pid_t root_pid;
865         pid_t root_ppid;
866         pid_t last_bg_pid;
867 #if ENABLE_HUSH_RANDOM_SUPPORT
868         random_t random_gen;
869 #endif
870 #if ENABLE_HUSH_JOB
871         int run_list_level;
872         unsigned last_jobid;
873         pid_t saved_tty_pgrp;
874         struct pipe *job_list;
875 # define G_saved_tty_pgrp (G.saved_tty_pgrp)
876 #else
877 # define G_saved_tty_pgrp 0
878 #endif
879         /* How deeply are we in context where "set -e" is ignored */
880         int errexit_depth;
881         /* "set -e" rules (do we follow them correctly?):
882          * Exit if pipe, list, or compound command exits with a non-zero status.
883          * Shell does not exit if failed command is part of condition in
884          * if/while, part of && or || list except the last command, any command
885          * in a pipe but the last, or if the command's return value is being
886          * inverted with !. If a compound command other than a subshell returns a
887          * non-zero status because a command failed while -e was being ignored, the
888          * shell does not exit. A trap on ERR, if set, is executed before the shell
889          * exits [ERR is a bashism].
890          *
891          * If a compound command or function executes in a context where -e is
892          * ignored, none of the commands executed within are affected by the -e
893          * setting. If a compound command or function sets -e while executing in a
894          * context where -e is ignored, that setting does not have any effect until
895          * the compound command or the command containing the function call completes.
896          */
897
898         char o_opt[NUM_OPT_O];
899 #if ENABLE_HUSH_MODE_X
900 # define G_x_mode (G.o_opt[OPT_O_XTRACE])
901 #else
902 # define G_x_mode 0
903 #endif
904         char opt_s;
905         char opt_c;
906 #if ENABLE_HUSH_INTERACTIVE
907         smallint promptmode; /* 0: PS1, 1: PS2 */
908 #endif
909         smallint flag_SIGINT;
910 #if ENABLE_HUSH_LOOPS
911         smallint flag_break_continue;
912 #endif
913 #if ENABLE_HUSH_FUNCTIONS
914         /* 0: outside of a function (or sourced file)
915          * -1: inside of a function, ok to use return builtin
916          * 1: return is invoked, skip all till end of func
917          */
918         smallint flag_return_in_progress;
919 # define G_flag_return_in_progress (G.flag_return_in_progress)
920 #else
921 # define G_flag_return_in_progress 0
922 #endif
923         smallint exiting; /* used to prevent EXIT trap recursion */
924         /* These support $? */
925         smalluint last_exitcode;
926         smalluint expand_exitcode;
927         smalluint last_bg_pid_exitcode;
928 #if ENABLE_HUSH_SET
929         /* are global_argv and global_argv[1..n] malloced? (note: not [0]) */
930         smalluint global_args_malloced;
931 # define G_global_args_malloced (G.global_args_malloced)
932 #else
933 # define G_global_args_malloced 0
934 #endif
935 #if ENABLE_HUSH_BASH_COMPAT
936         int dead_job_exitcode; /* for "wait -n" */
937 #endif
938         /* how many non-NULL argv's we have. NB: $# + 1 */
939         int global_argc;
940         char **global_argv;
941 #if !BB_MMU
942         char *argv0_for_re_execing;
943 #endif
944 #if ENABLE_HUSH_LOOPS
945         unsigned depth_break_continue;
946         unsigned depth_of_loop;
947 #endif
948 #if ENABLE_HUSH_GETOPTS
949         unsigned getopt_count;
950 #endif
951         const char *ifs;
952         char *ifs_whitespace; /* = G.ifs or malloced */
953         const char *cwd;
954         struct variable *top_var;
955         char **expanded_assignments;
956         struct variable **shadowed_vars_pp;
957         unsigned var_nest_level;
958 #if ENABLE_HUSH_FUNCTIONS
959 # if ENABLE_HUSH_LOCAL
960         unsigned func_nest_level; /* solely to prevent "local v" in non-functions */
961 # endif
962         struct function *top_func;
963 #endif
964         /* Signal and trap handling */
965 #if ENABLE_HUSH_FAST
966         unsigned count_SIGCHLD;
967         unsigned handled_SIGCHLD;
968         smallint we_have_children;
969 #endif
970 #if ENABLE_HUSH_LINENO_VAR
971         unsigned parse_lineno;
972         unsigned execute_lineno;
973 #endif
974         HFILE *HFILE_list;
975         HFILE *HFILE_stdin;
976         /* Which signals have non-DFL handler (even with no traps set)?
977          * Set at the start to:
978          * (SIGQUIT + maybe SPECIAL_INTERACTIVE_SIGS + maybe SPECIAL_JOBSTOP_SIGS)
979          * SPECIAL_INTERACTIVE_SIGS are cleared after fork.
980          * The rest is cleared right before execv syscalls.
981          * Other than these two times, never modified.
982          */
983         unsigned special_sig_mask;
984 #if ENABLE_HUSH_JOB
985         unsigned fatal_sig_mask;
986 # define G_fatal_sig_mask (G.fatal_sig_mask)
987 #else
988 # define G_fatal_sig_mask 0
989 #endif
990 #if ENABLE_HUSH_TRAP
991 # if ENABLE_HUSH_FUNCTIONS
992         int return_exitcode;
993 # endif
994         char **traps; /* char *traps[NSIG] */
995 # define G_traps G.traps
996 #else
997 # define G_traps ((char**)NULL)
998 #endif
999         sigset_t pending_set;
1000 #if ENABLE_HUSH_MEMLEAK
1001         unsigned long memleak_value;
1002 #endif
1003 #if ENABLE_HUSH_MODE_X
1004         unsigned x_mode_depth;
1005         /* "set -x" output should not be redirectable with subsequent 2>FILE.
1006          * We dup fd#2 to x_mode_fd when "set -x" is executed, and use it
1007          * for all subsequent output.
1008          */
1009         int x_mode_fd;
1010         o_string x_mode_buf;
1011 #endif
1012 #if HUSH_DEBUG >= 2
1013         int debug_indent;
1014 #endif
1015         struct sigaction sa;
1016         char optstring_buf[sizeof("eixcs")];
1017 #if BASH_EPOCH_VARS
1018         char epoch_buf[sizeof("%lu.nnnnnn") + sizeof(long)*3];
1019 #endif
1020 #if ENABLE_FEATURE_EDITING
1021         char user_input_buf[CONFIG_FEATURE_EDITING_MAX_LEN];
1022 #endif
1023 };
1024 #define G (*ptr_to_globals)
1025 /* Not #defining name to G.name - this quickly gets unwieldy
1026  * (too many defines). Also, I actually prefer to see when a variable
1027  * is global, thus "G." prefix is a useful hint */
1028 #define INIT_G() do { \
1029         SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
1030         /* memset(&G.sa, 0, sizeof(G.sa)); */  \
1031         sigfillset(&G.sa.sa_mask); \
1032         G.sa.sa_flags = SA_RESTART; \
1033 } while (0)
1034
1035
1036 /* Function prototypes for builtins */
1037 static int builtin_cd(char **argv) FAST_FUNC;
1038 #if ENABLE_HUSH_ECHO
1039 static int builtin_echo(char **argv) FAST_FUNC;
1040 #endif
1041 static int builtin_eval(char **argv) FAST_FUNC;
1042 static int builtin_exec(char **argv) FAST_FUNC;
1043 static int builtin_exit(char **argv) FAST_FUNC;
1044 #if ENABLE_HUSH_EXPORT
1045 static int builtin_export(char **argv) FAST_FUNC;
1046 #endif
1047 #if ENABLE_HUSH_READONLY
1048 static int builtin_readonly(char **argv) FAST_FUNC;
1049 #endif
1050 #if ENABLE_HUSH_JOB
1051 static int builtin_fg_bg(char **argv) FAST_FUNC;
1052 static int builtin_jobs(char **argv) FAST_FUNC;
1053 #endif
1054 #if ENABLE_HUSH_GETOPTS
1055 static int builtin_getopts(char **argv) FAST_FUNC;
1056 #endif
1057 #if ENABLE_HUSH_HELP
1058 static int builtin_help(char **argv) FAST_FUNC;
1059 #endif
1060 #if MAX_HISTORY && ENABLE_FEATURE_EDITING
1061 static int builtin_history(char **argv) FAST_FUNC;
1062 #endif
1063 #if ENABLE_HUSH_LOCAL
1064 static int builtin_local(char **argv) FAST_FUNC;
1065 #endif
1066 #if ENABLE_HUSH_MEMLEAK
1067 static int builtin_memleak(char **argv) FAST_FUNC;
1068 #endif
1069 #if ENABLE_HUSH_PRINTF
1070 static int builtin_printf(char **argv) FAST_FUNC;
1071 #endif
1072 static int builtin_pwd(char **argv) FAST_FUNC;
1073 #if ENABLE_HUSH_READ
1074 static int builtin_read(char **argv) FAST_FUNC;
1075 #endif
1076 #if ENABLE_HUSH_SET
1077 static int builtin_set(char **argv) FAST_FUNC;
1078 #endif
1079 static int builtin_shift(char **argv) FAST_FUNC;
1080 static int builtin_source(char **argv) FAST_FUNC;
1081 #if ENABLE_HUSH_TEST || BASH_TEST2
1082 static int builtin_test(char **argv) FAST_FUNC;
1083 #endif
1084 #if ENABLE_HUSH_TRAP
1085 static int builtin_trap(char **argv) FAST_FUNC;
1086 #endif
1087 #if ENABLE_HUSH_TYPE
1088 static int builtin_type(char **argv) FAST_FUNC;
1089 #endif
1090 #if ENABLE_HUSH_TIMES
1091 static int builtin_times(char **argv) FAST_FUNC;
1092 #endif
1093 static int builtin_true(char **argv) FAST_FUNC;
1094 #if ENABLE_HUSH_UMASK
1095 static int builtin_umask(char **argv) FAST_FUNC;
1096 #endif
1097 #if ENABLE_HUSH_UNSET
1098 static int builtin_unset(char **argv) FAST_FUNC;
1099 #endif
1100 #if ENABLE_HUSH_KILL
1101 static int builtin_kill(char **argv) FAST_FUNC;
1102 #endif
1103 #if ENABLE_HUSH_WAIT
1104 static int builtin_wait(char **argv) FAST_FUNC;
1105 #endif
1106 #if ENABLE_HUSH_LOOPS
1107 static int builtin_break(char **argv) FAST_FUNC;
1108 static int builtin_continue(char **argv) FAST_FUNC;
1109 #endif
1110 #if ENABLE_HUSH_FUNCTIONS
1111 static int builtin_return(char **argv) FAST_FUNC;
1112 #endif
1113
1114 /* Table of built-in functions.  They can be forked or not, depending on
1115  * context: within pipes, they fork.  As simple commands, they do not.
1116  * When used in non-forking context, they can change global variables
1117  * in the parent shell process.  If forked, of course they cannot.
1118  * For example, 'unset foo | whatever' will parse and run, but foo will
1119  * still be set at the end. */
1120 struct built_in_command {
1121         const char *b_cmd;
1122         int (*b_function)(char **argv) FAST_FUNC;
1123 #if ENABLE_HUSH_HELP
1124         const char *b_descr;
1125 # define BLTIN(cmd, func, help) { cmd, func, help }
1126 #else
1127 # define BLTIN(cmd, func, help) { cmd, func }
1128 #endif
1129 };
1130
1131 static const struct built_in_command bltins1[] = {
1132         BLTIN("."        , builtin_source  , "Run commands in file"),
1133         BLTIN(":"        , builtin_true    , NULL),
1134 #if ENABLE_HUSH_JOB
1135         BLTIN("bg"       , builtin_fg_bg   , "Resume job in background"),
1136 #endif
1137 #if ENABLE_HUSH_LOOPS
1138         BLTIN("break"    , builtin_break   , "Exit loop"),
1139 #endif
1140         BLTIN("cd"       , builtin_cd      , "Change directory"),
1141 #if ENABLE_HUSH_LOOPS
1142         BLTIN("continue" , builtin_continue, "Start new loop iteration"),
1143 #endif
1144         BLTIN("eval"     , builtin_eval    , "Construct and run shell command"),
1145         BLTIN("exec"     , builtin_exec    , "Execute command, don't return to shell"),
1146         BLTIN("exit"     , builtin_exit    , NULL),
1147 #if ENABLE_HUSH_EXPORT
1148         BLTIN("export"   , builtin_export  , "Set environment variables"),
1149 #endif
1150 #if ENABLE_HUSH_JOB
1151         BLTIN("fg"       , builtin_fg_bg   , "Bring job to foreground"),
1152 #endif
1153 #if ENABLE_HUSH_GETOPTS
1154         BLTIN("getopts"  , builtin_getopts , NULL),
1155 #endif
1156 #if ENABLE_HUSH_HELP
1157         BLTIN("help"     , builtin_help    , NULL),
1158 #endif
1159 #if MAX_HISTORY && ENABLE_FEATURE_EDITING
1160         BLTIN("history"  , builtin_history , "Show history"),
1161 #endif
1162 #if ENABLE_HUSH_JOB
1163         BLTIN("jobs"     , builtin_jobs    , "List jobs"),
1164 #endif
1165 #if ENABLE_HUSH_KILL
1166         BLTIN("kill"     , builtin_kill    , "Send signals to processes"),
1167 #endif
1168 #if ENABLE_HUSH_LOCAL
1169         BLTIN("local"    , builtin_local   , "Set local variables"),
1170 #endif
1171 #if ENABLE_HUSH_MEMLEAK
1172         BLTIN("memleak"  , builtin_memleak , NULL),
1173 #endif
1174 #if ENABLE_HUSH_READ
1175         BLTIN("read"     , builtin_read    , "Input into variable"),
1176 #endif
1177 #if ENABLE_HUSH_READONLY
1178         BLTIN("readonly" , builtin_readonly, "Make variables read-only"),
1179 #endif
1180 #if ENABLE_HUSH_FUNCTIONS
1181         BLTIN("return"   , builtin_return  , "Return from function"),
1182 #endif
1183 #if ENABLE_HUSH_SET
1184         BLTIN("set"      , builtin_set     , "Set positional parameters"),
1185 #endif
1186         BLTIN("shift"    , builtin_shift   , "Shift positional parameters"),
1187 #if BASH_SOURCE
1188         BLTIN("source"   , builtin_source  , NULL),
1189 #endif
1190 #if ENABLE_HUSH_TIMES
1191         BLTIN("times"    , builtin_times   , NULL),
1192 #endif
1193 #if ENABLE_HUSH_TRAP
1194         BLTIN("trap"     , builtin_trap    , "Trap signals"),
1195 #endif
1196         BLTIN("true"     , builtin_true    , NULL),
1197 #if ENABLE_HUSH_TYPE
1198         BLTIN("type"     , builtin_type    , "Show command type"),
1199 #endif
1200 #if ENABLE_HUSH_ULIMIT
1201         BLTIN("ulimit"   , shell_builtin_ulimit, "Control resource limits"),
1202 #endif
1203 #if ENABLE_HUSH_UMASK
1204         BLTIN("umask"    , builtin_umask   , "Set file creation mask"),
1205 #endif
1206 #if ENABLE_HUSH_UNSET
1207         BLTIN("unset"    , builtin_unset   , "Unset variables"),
1208 #endif
1209 #if ENABLE_HUSH_WAIT
1210         BLTIN("wait"     , builtin_wait    , "Wait for process to finish"),
1211 #endif
1212 };
1213 /* These builtins won't be used if we are on NOMMU and need to re-exec
1214  * (it's cheaper to run an external program in this case):
1215  */
1216 static const struct built_in_command bltins2[] = {
1217 #if ENABLE_HUSH_TEST
1218         BLTIN("["        , builtin_test    , NULL),
1219 #endif
1220 #if BASH_TEST2
1221         BLTIN("[["       , builtin_test    , NULL),
1222 #endif
1223 #if ENABLE_HUSH_ECHO
1224         BLTIN("echo"     , builtin_echo    , NULL),
1225 #endif
1226 #if ENABLE_HUSH_PRINTF
1227         BLTIN("printf"   , builtin_printf  , NULL),
1228 #endif
1229         BLTIN("pwd"      , builtin_pwd     , NULL),
1230 #if ENABLE_HUSH_TEST
1231         BLTIN("test"     , builtin_test    , NULL),
1232 #endif
1233 };
1234
1235
1236 /* Debug printouts.
1237  */
1238 #if HUSH_DEBUG >= 2
1239 /* prevent disasters with G.debug_indent < 0 */
1240 # define indent() fdprintf(2, "%*s", (G.debug_indent * 2) & 0xff, "")
1241 # define debug_enter() (G.debug_indent++)
1242 # define debug_leave() (G.debug_indent--)
1243 #else
1244 # define indent()      ((void)0)
1245 # define debug_enter() ((void)0)
1246 # define debug_leave() ((void)0)
1247 #endif
1248
1249 #ifndef debug_printf
1250 # define debug_printf(...) (indent(), fdprintf(2, __VA_ARGS__))
1251 #endif
1252
1253 #ifndef debug_printf_parse
1254 # define debug_printf_parse(...) (indent(), fdprintf(2, __VA_ARGS__))
1255 #endif
1256
1257 #ifndef debug_printf_heredoc
1258 # define debug_printf_heredoc(...) (indent(), fdprintf(2, __VA_ARGS__))
1259 #endif
1260
1261 #ifndef debug_printf_exec
1262 #define debug_printf_exec(...) (indent(), fdprintf(2, __VA_ARGS__))
1263 #endif
1264
1265 #ifndef debug_printf_env
1266 # define debug_printf_env(...) (indent(), fdprintf(2, __VA_ARGS__))
1267 #endif
1268
1269 #ifndef debug_printf_jobs
1270 # define debug_printf_jobs(...) (indent(), fdprintf(2, __VA_ARGS__))
1271 # define DEBUG_JOBS 1
1272 #else
1273 # define DEBUG_JOBS 0
1274 #endif
1275
1276 #ifndef debug_printf_expand
1277 # define debug_printf_expand(...) (indent(), fdprintf(2, __VA_ARGS__))
1278 # define DEBUG_EXPAND 1
1279 #else
1280 # define DEBUG_EXPAND 0
1281 #endif
1282
1283 #ifndef debug_printf_varexp
1284 # define debug_printf_varexp(...) (indent(), fdprintf(2, __VA_ARGS__))
1285 #endif
1286
1287 #ifndef debug_printf_glob
1288 # define debug_printf_glob(...) (indent(), fdprintf(2, __VA_ARGS__))
1289 # define DEBUG_GLOB 1
1290 #else
1291 # define DEBUG_GLOB 0
1292 #endif
1293
1294 #ifndef debug_printf_redir
1295 # define debug_printf_redir(...) (indent(), fdprintf(2, __VA_ARGS__))
1296 #endif
1297
1298 #ifndef debug_printf_list
1299 # define debug_printf_list(...) (indent(), fdprintf(2, __VA_ARGS__))
1300 #endif
1301
1302 #ifndef debug_printf_subst
1303 # define debug_printf_subst(...) (indent(), fdprintf(2, __VA_ARGS__))
1304 #endif
1305
1306 #ifndef debug_printf_prompt
1307 # define debug_printf_prompt(...) (indent(), fdprintf(2, __VA_ARGS__))
1308 #endif
1309
1310 #ifndef debug_printf_clean
1311 # define debug_printf_clean(...) (indent(), fdprintf(2, __VA_ARGS__))
1312 # define DEBUG_CLEAN 1
1313 #else
1314 # define DEBUG_CLEAN 0
1315 #endif
1316
1317 #if DEBUG_EXPAND
1318 static void debug_print_strings(const char *prefix, char **vv)
1319 {
1320         indent();
1321         fdprintf(2, "%s:\n", prefix);
1322         while (*vv)
1323                 fdprintf(2, " '%s'\n", *vv++);
1324 }
1325 #else
1326 # define debug_print_strings(prefix, vv) ((void)0)
1327 #endif
1328
1329
1330 /* Leak hunting. Use hush_leaktool.sh for post-processing.
1331  */
1332 #if LEAK_HUNTING
1333 static void *xxmalloc(int lineno, size_t size)
1334 {
1335         void *ptr = xmalloc((size + 0xff) & ~0xff);
1336         fdprintf(2, "line %d: malloc %p\n", lineno, ptr);
1337         return ptr;
1338 }
1339 static void *xxrealloc(int lineno, void *ptr, size_t size)
1340 {
1341         ptr = xrealloc(ptr, (size + 0xff) & ~0xff);
1342         fdprintf(2, "line %d: realloc %p\n", lineno, ptr);
1343         return ptr;
1344 }
1345 static char *xxstrdup(int lineno, const char *str)
1346 {
1347         char *ptr = xstrdup(str);
1348         fdprintf(2, "line %d: strdup %p\n", lineno, ptr);
1349         return ptr;
1350 }
1351 static void xxfree(void *ptr)
1352 {
1353         fdprintf(2, "free %p\n", ptr);
1354         free(ptr);
1355 }
1356 # define xmalloc(s)     xxmalloc(__LINE__, s)
1357 # define xrealloc(p, s) xxrealloc(__LINE__, p, s)
1358 # define xstrdup(s)     xxstrdup(__LINE__, s)
1359 # define free(p)        xxfree(p)
1360 #endif
1361
1362
1363 /* Syntax and runtime errors. They always abort scripts.
1364  * In interactive use they usually discard unparsed and/or unexecuted commands
1365  * and return to the prompt.
1366  * HUSH_DEBUG >= 2 prints line number in this file where it was detected.
1367  */
1368 #if HUSH_DEBUG < 2
1369 # define msg_and_die_if_script(lineno, ...)     msg_and_die_if_script(__VA_ARGS__)
1370 # define syntax_error(lineno, msg)              syntax_error(msg)
1371 # define syntax_error_at(lineno, msg)           syntax_error_at(msg)
1372 # define syntax_error_unterm_ch(lineno, ch)     syntax_error_unterm_ch(ch)
1373 # define syntax_error_unterm_str(lineno, s)     syntax_error_unterm_str(s)
1374 # define syntax_error_unexpected_ch(lineno, ch) syntax_error_unexpected_ch(ch)
1375 #endif
1376
1377 static void die_if_script(void)
1378 {
1379         if (!G_interactive_fd) {
1380                 if (G.last_exitcode) /* sometines it's 2, not 1 (bash compat) */
1381                         xfunc_error_retval = G.last_exitcode;
1382                 xfunc_die();
1383         }
1384 }
1385
1386 static void msg_and_die_if_script(unsigned lineno, const char *fmt, ...)
1387 {
1388         va_list p;
1389
1390 #if HUSH_DEBUG >= 2
1391         bb_error_msg("hush.c:%u", lineno);
1392 #endif
1393         va_start(p, fmt);
1394         bb_verror_msg(fmt, p, NULL);
1395         va_end(p);
1396         die_if_script();
1397 }
1398
1399 static void syntax_error(unsigned lineno UNUSED_PARAM, const char *msg)
1400 {
1401         if (msg)
1402                 bb_error_msg("syntax error: %s", msg);
1403         else
1404                 bb_simple_error_msg("syntax error");
1405         die_if_script();
1406 }
1407
1408 static void syntax_error_at(unsigned lineno UNUSED_PARAM, const char *msg)
1409 {
1410         bb_error_msg("syntax error at '%s'", msg);
1411         die_if_script();
1412 }
1413
1414 static void syntax_error_unterm_str(unsigned lineno UNUSED_PARAM, const char *s)
1415 {
1416         bb_error_msg("syntax error: unterminated %s", s);
1417 //? source4.tests fails: in bash, echo ${^} in script does not terminate the script
1418 //      die_if_script();
1419 }
1420
1421 static void syntax_error_unterm_ch(unsigned lineno, char ch)
1422 {
1423         char msg[2] = { ch, '\0' };
1424         syntax_error_unterm_str(lineno, msg);
1425 }
1426
1427 static void syntax_error_unexpected_ch(unsigned lineno UNUSED_PARAM, int ch)
1428 {
1429         char msg[2];
1430         msg[0] = ch;
1431         msg[1] = '\0';
1432 #if HUSH_DEBUG >= 2
1433         bb_error_msg("hush.c:%u", lineno);
1434 #endif
1435         bb_error_msg("syntax error: unexpected %s", ch == EOF ? "EOF" : msg);
1436         die_if_script();
1437 }
1438
1439 #if HUSH_DEBUG < 2
1440 # undef msg_and_die_if_script
1441 # undef syntax_error
1442 # undef syntax_error_at
1443 # undef syntax_error_unterm_ch
1444 # undef syntax_error_unterm_str
1445 # undef syntax_error_unexpected_ch
1446 #else
1447 # define msg_and_die_if_script(...)     msg_and_die_if_script(__LINE__, __VA_ARGS__)
1448 # define syntax_error(msg)              syntax_error(__LINE__, msg)
1449 # define syntax_error_at(msg)           syntax_error_at(__LINE__, msg)
1450 # define syntax_error_unterm_ch(ch)     syntax_error_unterm_ch(__LINE__, ch)
1451 # define syntax_error_unterm_str(s)     syntax_error_unterm_str(__LINE__, s)
1452 # define syntax_error_unexpected_ch(ch) syntax_error_unexpected_ch(__LINE__, ch)
1453 #endif
1454
1455
1456 /* Utility functions
1457  */
1458 /* Replace each \x with x in place, return ptr past NUL. */
1459 static char *unbackslash(char *src)
1460 {
1461         char *dst = src = strchrnul(src, '\\');
1462         while (1) {
1463                 if (*src == '\\') {
1464                         src++;
1465                         if (*src != '\0') {
1466                                 /* \x -> x */
1467                                 *dst++ = *src++;
1468                                 continue;
1469                         }
1470                         /* else: "\<nul>". Do not delete this backslash.
1471                          * Testcase: eval 'echo ok\'
1472                          */
1473                         *dst++ = '\\';
1474                         /* fallthrough */
1475                 }
1476                 if ((*dst++ = *src++) == '\0')
1477                         break;
1478         }
1479         return dst;
1480 }
1481
1482 static char **add_strings_to_strings(char **strings, char **add, int need_to_dup)
1483 {
1484         int i;
1485         unsigned count1;
1486         unsigned count2;
1487         char **v;
1488
1489         v = strings;
1490         count1 = 0;
1491         if (v) {
1492                 while (*v) {
1493                         count1++;
1494                         v++;
1495                 }
1496         }
1497         count2 = 0;
1498         v = add;
1499         while (*v) {
1500                 count2++;
1501                 v++;
1502         }
1503         v = xrealloc(strings, (count1 + count2 + 1) * sizeof(char*));
1504         v[count1 + count2] = NULL;
1505         i = count2;
1506         while (--i >= 0)
1507                 v[count1 + i] = (need_to_dup ? xstrdup(add[i]) : add[i]);
1508         return v;
1509 }
1510 #if LEAK_HUNTING
1511 static char **xx_add_strings_to_strings(int lineno, char **strings, char **add, int need_to_dup)
1512 {
1513         char **ptr = add_strings_to_strings(strings, add, need_to_dup);
1514         fdprintf(2, "line %d: add_strings_to_strings %p\n", lineno, ptr);
1515         return ptr;
1516 }
1517 #define add_strings_to_strings(strings, add, need_to_dup) \
1518         xx_add_strings_to_strings(__LINE__, strings, add, need_to_dup)
1519 #endif
1520
1521 /* Note: takes ownership of "add" ptr (it is not strdup'ed) */
1522 static char **add_string_to_strings(char **strings, char *add)
1523 {
1524         char *v[2];
1525         v[0] = add;
1526         v[1] = NULL;
1527         return add_strings_to_strings(strings, v, /*dup:*/ 0);
1528 }
1529 #if LEAK_HUNTING
1530 static char **xx_add_string_to_strings(int lineno, char **strings, char *add)
1531 {
1532         char **ptr = add_string_to_strings(strings, add);
1533         fdprintf(2, "line %d: add_string_to_strings %p\n", lineno, ptr);
1534         return ptr;
1535 }
1536 #define add_string_to_strings(strings, add) \
1537         xx_add_string_to_strings(__LINE__, strings, add)
1538 #endif
1539
1540 static void free_strings(char **strings)
1541 {
1542         char **v;
1543
1544         if (!strings)
1545                 return;
1546         v = strings;
1547         while (*v) {
1548                 free(*v);
1549                 v++;
1550         }
1551         free(strings);
1552 }
1553
1554 static int dup_CLOEXEC(int fd, int avoid_fd)
1555 {
1556         int newfd;
1557  repeat:
1558         newfd = fcntl(fd, F_DUPFD_CLOEXEC, avoid_fd + 1);
1559         if (newfd >= 0) {
1560                 if (F_DUPFD_CLOEXEC == F_DUPFD) /* if old libc (w/o F_DUPFD_CLOEXEC) */
1561                         fcntl(newfd, F_SETFD, FD_CLOEXEC);
1562         } else { /* newfd < 0 */
1563                 if (errno == EBUSY)
1564                         goto repeat;
1565                 if (errno == EINTR)
1566                         goto repeat;
1567         }
1568         return newfd;
1569 }
1570
1571 static int xdup_CLOEXEC_and_close(int fd, int avoid_fd)
1572 {
1573         int newfd;
1574  repeat:
1575         newfd = fcntl(fd, F_DUPFD_CLOEXEC, avoid_fd + 1);
1576         if (newfd < 0) {
1577                 if (errno == EBUSY)
1578                         goto repeat;
1579                 if (errno == EINTR)
1580                         goto repeat;
1581                 /* fd was not open? */
1582                 if (errno == EBADF)
1583                         return fd;
1584                 xfunc_die();
1585         }
1586         if (F_DUPFD_CLOEXEC == F_DUPFD) /* if old libc (w/o F_DUPFD_CLOEXEC) */
1587                 fcntl(newfd, F_SETFD, FD_CLOEXEC);
1588         close(fd);
1589         return newfd;
1590 }
1591
1592
1593 /* Manipulating HFILEs */
1594 static HFILE *hfopen(const char *name)
1595 {
1596         HFILE *fp;
1597         int fd;
1598
1599         fd = STDIN_FILENO;
1600         if (name) {
1601                 fd = open(name, O_RDONLY | O_CLOEXEC);
1602                 if (fd < 0)
1603                         return NULL;
1604                 if (O_CLOEXEC == 0) /* ancient libc */
1605                         close_on_exec_on(fd);
1606         }
1607
1608         fp = xmalloc(sizeof(*fp));
1609         if (name == NULL)
1610                 G.HFILE_stdin = fp;
1611         fp->fd = fd;
1612         fp->cur = fp->end = fp->buf;
1613         fp->next_hfile = G.HFILE_list;
1614         G.HFILE_list = fp;
1615         return fp;
1616 }
1617 static void hfclose(HFILE *fp)
1618 {
1619         HFILE **pp = &G.HFILE_list;
1620         while (*pp) {
1621                 HFILE *cur = *pp;
1622                 if (cur == fp) {
1623                         *pp = cur->next_hfile;
1624                         break;
1625                 }
1626                 pp = &cur->next_hfile;
1627         }
1628         if (fp->fd >= 0)
1629                 close(fp->fd);
1630         free(fp);
1631 }
1632 static int refill_HFILE_and_getc(HFILE *fp)
1633 {
1634         int n;
1635
1636         if (fp->fd < 0) {
1637                 /* Already saw EOF */
1638                 return EOF;
1639         }
1640         /* Try to buffer more input */
1641         fp->cur = fp->buf;
1642         n = safe_read(fp->fd, fp->buf, sizeof(fp->buf));
1643         if (n < 0) {
1644                 bb_simple_perror_msg("read error");
1645                 n = 0;
1646         }
1647         fp->end = fp->buf + n;
1648         if (n == 0) {
1649                 /* EOF/error */
1650                 close(fp->fd);
1651                 fp->fd = -1;
1652                 return EOF;
1653         }
1654         return (unsigned char)(*fp->cur++);
1655 }
1656 /* Inlined for common case of non-empty buffer.
1657  */
1658 static ALWAYS_INLINE int hfgetc(HFILE *fp)
1659 {
1660         if (fp->cur < fp->end)
1661                 return (unsigned char)(*fp->cur++);
1662         /* Buffer empty */
1663         return refill_HFILE_and_getc(fp);
1664 }
1665 static int move_HFILEs_on_redirect(int fd, int avoid_fd)
1666 {
1667         HFILE *fl = G.HFILE_list;
1668         while (fl) {
1669                 if (fd == fl->fd) {
1670                         /* We use it only on script files, they are all CLOEXEC */
1671                         fl->fd = xdup_CLOEXEC_and_close(fd, avoid_fd);
1672                         debug_printf_redir("redirect_fd %d: matches a script fd, moving it to %d\n", fd, fl->fd);
1673                         return 1; /* "found and moved" */
1674                 }
1675                 fl = fl->next_hfile;
1676         }
1677 #if ENABLE_HUSH_MODE_X
1678         if (G.x_mode_fd > 0 && fd == G.x_mode_fd) {
1679                 G.x_mode_fd = xdup_CLOEXEC_and_close(fd, avoid_fd);
1680                 return 1; /* "found and moved" */
1681         }
1682 #endif
1683         return 0; /* "not in the list" */
1684 }
1685 #if ENABLE_FEATURE_SH_STANDALONE && BB_MMU
1686 static void close_all_HFILE_list(void)
1687 {
1688         HFILE *fl = G.HFILE_list;
1689         while (fl) {
1690                 /* hfclose would also free HFILE object.
1691                  * It is disastrous if we share memory with a vforked parent.
1692                  * I'm not sure we never come here after vfork.
1693                  * Therefore just close fd, nothing more.
1694                  *
1695                  * ">" instead of ">=": we don't close fd#0,
1696                  * interactive shell uses hfopen(NULL) as stdin input
1697                  * which has fl->fd == 0, but fd#0 gets redirected in pipes.
1698                  * If we'd close it here, then e.g. interactive "set | sort"
1699                  * with NOFORKed sort, would have sort's input fd closed.
1700                  */
1701                 if (fl->fd > 0)
1702                         /*hfclose(fl); - unsafe */
1703                         close(fl->fd);
1704                 fl = fl->next_hfile;
1705         }
1706 }
1707 #endif
1708 static int fd_in_HFILEs(int fd)
1709 {
1710         HFILE *fl = G.HFILE_list;
1711         while (fl) {
1712                 if (fl->fd == fd)
1713                         return 1;
1714                 fl = fl->next_hfile;
1715         }
1716         return 0;
1717 }
1718
1719
1720 /* Helpers for setting new $n and restoring them back
1721  */
1722 typedef struct save_arg_t {
1723         char *sv_argv0;
1724         char **sv_g_argv;
1725         int sv_g_argc;
1726         IF_HUSH_SET(smallint sv_g_malloced;)
1727 } save_arg_t;
1728
1729 static void save_and_replace_G_args(save_arg_t *sv, char **argv)
1730 {
1731         sv->sv_argv0 = argv[0];
1732         sv->sv_g_argv = G.global_argv;
1733         sv->sv_g_argc = G.global_argc;
1734         IF_HUSH_SET(sv->sv_g_malloced = G.global_args_malloced;)
1735
1736         argv[0] = G.global_argv[0]; /* retain $0 */
1737         G.global_argv = argv;
1738         IF_HUSH_SET(G.global_args_malloced = 0;)
1739
1740         G.global_argc = 1 + string_array_len(argv + 1);
1741 }
1742
1743 static void restore_G_args(save_arg_t *sv, char **argv)
1744 {
1745 #if ENABLE_HUSH_SET
1746         if (G.global_args_malloced) {
1747                 /* someone ran "set -- arg1 arg2 ...", undo */
1748                 char **pp = G.global_argv;
1749                 while (*++pp) /* note: does not free $0 */
1750                         free(*pp);
1751                 free(G.global_argv);
1752         }
1753 #endif
1754         argv[0] = sv->sv_argv0;
1755         G.global_argv = sv->sv_g_argv;
1756         G.global_argc = sv->sv_g_argc;
1757         IF_HUSH_SET(G.global_args_malloced = sv->sv_g_malloced;)
1758 }
1759
1760
1761 /* Basic theory of signal handling in shell
1762  * ========================================
1763  * This does not describe what hush does, rather, it is current understanding
1764  * what it _should_ do. If it doesn't, it's a bug.
1765  * http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#trap
1766  *
1767  * Signals are handled only after each pipe ("cmd | cmd | cmd" thing)
1768  * is finished or backgrounded. It is the same in interactive and
1769  * non-interactive shells, and is the same regardless of whether
1770  * a user trap handler is installed or a shell special one is in effect.
1771  * ^C or ^Z from keyboard seems to execute "at once" because it usually
1772  * backgrounds (i.e. stops) or kills all members of currently running
1773  * pipe.
1774  *
1775  * Wait builtin is interruptible by signals for which user trap is set
1776  * or by SIGINT in interactive shell.
1777  *
1778  * Trap handlers will execute even within trap handlers. (right?)
1779  *
1780  * User trap handlers are forgotten when subshell ("(cmd)") is entered,
1781  * except for handlers set to '' (empty string).
1782  *
1783  * If job control is off, backgrounded commands ("cmd &")
1784  * have SIGINT, SIGQUIT set to SIG_IGN.
1785  *
1786  * Commands which are run in command substitution ("`cmd`")
1787  * have SIGTTIN, SIGTTOU, SIGTSTP set to SIG_IGN.
1788  *
1789  * Ordinary commands have signals set to SIG_IGN/DFL as inherited
1790  * by the shell from its parent.
1791  *
1792  * Signals which differ from SIG_DFL action
1793  * (note: child (i.e., [v]forked) shell is not an interactive shell):
1794  *
1795  * SIGQUIT: ignore
1796  * SIGTERM (interactive): ignore
1797  * SIGHUP (interactive):
1798  *    send SIGCONT to stopped jobs, send SIGHUP to all jobs and exit
1799  * SIGTTIN, SIGTTOU, SIGTSTP (if job control is on): ignore
1800  *    Note that ^Z is handled not by trapping SIGTSTP, but by seeing
1801  *    that all pipe members are stopped. Try this in bash:
1802  *    while :; do :; done - ^Z does not background it
1803  *    (while :; do :; done) - ^Z backgrounds it
1804  * SIGINT (interactive): wait for last pipe, ignore the rest
1805  *    of the command line, show prompt. NB: ^C does not send SIGINT
1806  *    to interactive shell while shell is waiting for a pipe,
1807  *    since shell is bg'ed (is not in foreground process group).
1808  *    Example 1: this waits 5 sec, but does not execute ls:
1809  *    "echo $$; sleep 5; ls -l" + "kill -INT <pid>"
1810  *    Example 2: this does not wait and does not execute ls:
1811  *    "echo $$; sleep 5 & wait; ls -l" + "kill -INT <pid>"
1812  *    Example 3: this does not wait 5 sec, but executes ls:
1813  *    "sleep 5; ls -l" + press ^C
1814  *    Example 4: this does not wait and does not execute ls:
1815  *    "sleep 5 & wait; ls -l" + press ^C
1816  *
1817  * (What happens to signals which are IGN on shell start?)
1818  * (What happens with signal mask on shell start?)
1819  *
1820  * Old implementation
1821  * ==================
1822  * We use in-kernel pending signal mask to determine which signals were sent.
1823  * We block all signals which we don't want to take action immediately,
1824  * i.e. we block all signals which need to have special handling as described
1825  * above, and all signals which have traps set.
1826  * After each pipe execution, we extract any pending signals via sigtimedwait()
1827  * and act on them.
1828  *
1829  * unsigned special_sig_mask: a mask of such "special" signals
1830  * sigset_t blocked_set:  current blocked signal set
1831  *
1832  * "trap - SIGxxx":
1833  *    clear bit in blocked_set unless it is also in special_sig_mask
1834  * "trap 'cmd' SIGxxx":
1835  *    set bit in blocked_set (even if 'cmd' is '')
1836  * after [v]fork, if we plan to be a shell:
1837  *    unblock signals with special interactive handling
1838  *    (child shell is not interactive),
1839  *    unset all traps except '' (note: regardless of child shell's type - {}, (), etc)
1840  * after [v]fork, if we plan to exec:
1841  *    POSIX says fork clears pending signal mask in child - no need to clear it.
1842  *    Restore blocked signal set to one inherited by shell just prior to exec.
1843  *
1844  * Note: as a result, we do not use signal handlers much. The only uses
1845  * are to count SIGCHLDs
1846  * and to restore tty pgrp on signal-induced exit.
1847  *
1848  * Note 2 (compat):
1849  * Standard says "When a subshell is entered, traps that are not being ignored
1850  * are set to the default actions". bash interprets it so that traps which
1851  * are set to '' (ignore) are NOT reset to defaults. We do the same.
1852  *
1853  * Problem: the above approach makes it unwieldy to catch signals while
1854  * we are in read builtin, or while we read commands from stdin:
1855  * masked signals are not visible!
1856  *
1857  * New implementation
1858  * ==================
1859  * We record each signal we are interested in by installing signal handler
1860  * for them - a bit like emulating kernel pending signal mask in userspace.
1861  * We are interested in: signals which need to have special handling
1862  * as described above, and all signals which have traps set.
1863  * Signals are recorded in pending_set.
1864  * After each pipe execution, we extract any pending signals
1865  * and act on them.
1866  *
1867  * unsigned special_sig_mask: a mask of shell-special signals.
1868  * unsigned fatal_sig_mask: a mask of signals on which we restore tty pgrp.
1869  * char *traps[sig] if trap for sig is set (even if it's '').
1870  * sigset_t pending_set: set of sigs we received.
1871  *
1872  * "trap - SIGxxx":
1873  *    if sig is in special_sig_mask, set handler back to:
1874  *        record_pending_signo, or to IGN if it's a tty stop signal
1875  *    if sig is in fatal_sig_mask, set handler back to sigexit.
1876  *    else: set handler back to SIG_DFL
1877  * "trap 'cmd' SIGxxx":
1878  *    set handler to record_pending_signo.
1879  * "trap '' SIGxxx":
1880  *    set handler to SIG_IGN.
1881  * after [v]fork, if we plan to be a shell:
1882  *    set signals with special interactive handling to SIG_DFL
1883  *    (because child shell is not interactive),
1884  *    unset all traps except '' (note: regardless of child shell's type - {}, (), etc)
1885  * after [v]fork, if we plan to exec:
1886  *    POSIX says fork clears pending signal mask in child - no need to clear it.
1887  *
1888  * To make wait builtin interruptible, we handle SIGCHLD as special signal,
1889  * otherwise (if we leave it SIG_DFL) sigsuspend in wait builtin will not wake up on it.
1890  *
1891  * Note (compat):
1892  * Standard says "When a subshell is entered, traps that are not being ignored
1893  * are set to the default actions". bash interprets it so that traps which
1894  * are set to '' (ignore) are NOT reset to defaults. We do the same.
1895  */
1896 enum {
1897         SPECIAL_INTERACTIVE_SIGS = 0
1898                 | (1 << SIGTERM)
1899                 | (1 << SIGINT)
1900                 | (1 << SIGHUP)
1901                 ,
1902         SPECIAL_JOBSTOP_SIGS = 0
1903 #if ENABLE_HUSH_JOB
1904                 | (1 << SIGTTIN)
1905                 | (1 << SIGTTOU)
1906                 | (1 << SIGTSTP)
1907 #endif
1908                 ,
1909 };
1910
1911 static void record_pending_signo(int sig)
1912 {
1913         sigaddset(&G.pending_set, sig);
1914 #if ENABLE_HUSH_FAST
1915         if (sig == SIGCHLD) {
1916                 G.count_SIGCHLD++;
1917 //bb_error_msg("[%d] SIGCHLD_handler: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
1918         }
1919 #endif
1920 }
1921
1922 static sighandler_t install_sighandler(int sig, sighandler_t handler)
1923 {
1924         struct sigaction old_sa;
1925
1926         /* We could use signal() to install handlers... almost:
1927          * except that we need to mask ALL signals while handlers run.
1928          * I saw signal nesting in strace, race window isn't small.
1929          * SA_RESTART is also needed, but in Linux, signal()
1930          * sets SA_RESTART too.
1931          */
1932         /* memset(&G.sa, 0, sizeof(G.sa)); - already done */
1933         /* sigfillset(&G.sa.sa_mask);      - already done */
1934         /* G.sa.sa_flags = SA_RESTART;     - already done */
1935         G.sa.sa_handler = handler;
1936         sigaction(sig, &G.sa, &old_sa);
1937         return old_sa.sa_handler;
1938 }
1939
1940 static void hush_exit(int exitcode) NORETURN;
1941
1942 static void restore_ttypgrp_and__exit(void) NORETURN;
1943 static void restore_ttypgrp_and__exit(void)
1944 {
1945         /* xfunc has failed! die die die */
1946         /* no EXIT traps, this is an escape hatch! */
1947         G.exiting = 1;
1948         hush_exit(xfunc_error_retval);
1949 }
1950
1951 #if ENABLE_HUSH_JOB
1952
1953 /* Needed only on some libc:
1954  * It was observed that on exit(), fgetc'ed buffered data
1955  * gets "unwound" via lseek(fd, -NUM, SEEK_CUR).
1956  * With the net effect that even after fork(), not vfork(),
1957  * exit() in NOEXECed applet in "sh SCRIPT":
1958  *      noexec_applet_here
1959  *      echo END_OF_SCRIPT
1960  * lseeks fd in input FILE object from EOF to "e" in "echo END_OF_SCRIPT".
1961  * This makes "echo END_OF_SCRIPT" executed twice.
1962  * Similar problems can be seen with msg_and_die_if_script() -> xfunc_die()
1963  * and in `cmd` handling.
1964  * If set as die_func(), this makes xfunc_die() exit via _exit(), not exit():
1965  */
1966 static void fflush_and__exit(void) NORETURN;
1967 static void fflush_and__exit(void)
1968 {
1969         fflush_all();
1970         _exit(xfunc_error_retval);
1971 }
1972
1973 /* After [v]fork, in child: do not restore tty pgrp on xfunc death */
1974 # define disable_restore_tty_pgrp_on_exit() (die_func = fflush_and__exit)
1975 /* After [v]fork, in parent: restore tty pgrp on xfunc death */
1976 # define enable_restore_tty_pgrp_on_exit()  (die_func = restore_ttypgrp_and__exit)
1977
1978 /* Restores tty foreground process group, and exits.
1979  * May be called as signal handler for fatal signal
1980  * (will resend signal to itself, producing correct exit state)
1981  * or called directly with -EXITCODE.
1982  * We also call it if xfunc is exiting.
1983  */
1984 static void sigexit(int sig) NORETURN;
1985 static void sigexit(int sig)
1986 {
1987         /* Careful: we can end up here after [v]fork. Do not restore
1988          * tty pgrp then, only top-level shell process does that */
1989         if (G_saved_tty_pgrp && getpid() == G.root_pid) {
1990                 /* Disable all signals: job control, SIGPIPE, etc.
1991                  * Mostly paranoid measure, to prevent infinite SIGTTOU.
1992                  */
1993                 sigprocmask_allsigs(SIG_BLOCK);
1994                 tcsetpgrp(G_interactive_fd, G_saved_tty_pgrp);
1995         }
1996
1997         /* Not a signal, just exit */
1998         if (sig <= 0)
1999                 _exit(- sig);
2000
2001         kill_myself_with_sig(sig); /* does not return */
2002 }
2003 #else
2004
2005 # define disable_restore_tty_pgrp_on_exit() ((void)0)
2006 # define enable_restore_tty_pgrp_on_exit()  ((void)0)
2007
2008 #endif
2009
2010 static sighandler_t pick_sighandler(unsigned sig)
2011 {
2012         sighandler_t handler = SIG_DFL;
2013         if (sig < sizeof(unsigned)*8) {
2014                 unsigned sigmask = (1 << sig);
2015
2016 #if ENABLE_HUSH_JOB
2017                 /* is sig fatal? */
2018                 if (G_fatal_sig_mask & sigmask)
2019                         handler = sigexit;
2020                 else
2021 #endif
2022                 /* sig has special handling? */
2023                 if (G.special_sig_mask & sigmask) {
2024                         handler = record_pending_signo;
2025                         /* TTIN/TTOU/TSTP can't be set to record_pending_signo
2026                          * in order to ignore them: they will be raised
2027                          * in an endless loop when we try to do some
2028                          * terminal ioctls! We do have to _ignore_ these.
2029                          */
2030                         if (SPECIAL_JOBSTOP_SIGS & sigmask)
2031                                 handler = SIG_IGN;
2032                 }
2033         }
2034         return handler;
2035 }
2036
2037 /* Restores tty foreground process group, and exits. */
2038 static void hush_exit(int exitcode)
2039 {
2040 #if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT
2041         if (G.line_input_state)
2042                 save_history(G.line_input_state);
2043 #endif
2044
2045         fflush_all();
2046         if (G.exiting <= 0 && G_traps && G_traps[0] && G_traps[0][0]) {
2047                 char *argv[3];
2048                 /* argv[0] is unused */
2049                 argv[1] = xstrdup(G_traps[0]); /* copy, since EXIT trap handler may modify G_traps[0] */
2050                 argv[2] = NULL;
2051                 G.exiting = 1; /* prevent EXIT trap recursion */
2052                 /* Note: G_traps[0] is not cleared!
2053                  * "trap" will still show it, if executed
2054                  * in the handler */
2055                 builtin_eval(argv);
2056         }
2057
2058 #if ENABLE_FEATURE_CLEAN_UP
2059         {
2060                 struct variable *cur_var;
2061                 if (G.cwd != bb_msg_unknown)
2062                         free((char*)G.cwd);
2063                 cur_var = G.top_var;
2064                 while (cur_var) {
2065                         struct variable *tmp = cur_var;
2066                         if (!cur_var->max_len)
2067                                 free(cur_var->varstr);
2068                         cur_var = cur_var->next;
2069                         free(tmp);
2070                 }
2071         }
2072 #endif
2073
2074         fflush_all();
2075 #if ENABLE_HUSH_JOB
2076         sigexit(- (exitcode & 0xff));
2077 #else
2078         _exit(exitcode);
2079 #endif
2080 }
2081
2082
2083 //TODO: return a mask of ALL handled sigs?
2084 static int check_and_run_traps(void)
2085 {
2086         int last_sig = 0;
2087
2088         while (1) {
2089                 int sig;
2090
2091                 if (sigisemptyset(&G.pending_set))
2092                         break;
2093                 sig = 0;
2094                 do {
2095                         sig++;
2096                         if (sigismember(&G.pending_set, sig)) {
2097                                 sigdelset(&G.pending_set, sig);
2098                                 goto got_sig;
2099                         }
2100                 } while (sig < NSIG);
2101                 break;
2102  got_sig:
2103 #if ENABLE_HUSH_TRAP
2104                 if (G_traps && G_traps[sig]) {
2105                         debug_printf_exec("%s: sig:%d handler:'%s'\n", __func__, sig, G.traps[sig]);
2106                         if (G_traps[sig][0]) {
2107                                 /* We have user-defined handler */
2108                                 smalluint save_rcode;
2109                                 char *argv[3];
2110                                 /* argv[0] is unused */
2111                                 argv[1] = xstrdup(G_traps[sig]);
2112                                 /* why strdup? trap can modify itself: trap 'trap "echo oops" INT' INT */
2113                                 argv[2] = NULL;
2114                                 save_rcode = G.last_exitcode;
2115                                 builtin_eval(argv);
2116                                 free(argv[1]);
2117                                 G.last_exitcode = save_rcode;
2118 # if ENABLE_HUSH_FUNCTIONS
2119                                 if (G.return_exitcode >= 0) {
2120                                         debug_printf_exec("trap exitcode:%d\n", G.return_exitcode);
2121                                         G.last_exitcode = G.return_exitcode;
2122                                 }
2123 # endif
2124                                 last_sig = sig;
2125                         } /* else: "" trap, ignoring signal */
2126                         continue;
2127                 }
2128 #endif
2129                 /* not a trap: special action */
2130                 switch (sig) {
2131                 case SIGINT:
2132                         debug_printf_exec("%s: sig:%d default SIGINT handler\n", __func__, sig);
2133                         G.flag_SIGINT = 1;
2134                         last_sig = sig;
2135                         break;
2136 #if ENABLE_HUSH_JOB
2137                 case SIGHUP: {
2138 //TODO: why are we doing this? ash and dash don't do this,
2139 //they have no handler for SIGHUP at all,
2140 //they rely on kernel to send SIGHUP+SIGCONT to orphaned process groups
2141                         struct pipe *job;
2142                         debug_printf_exec("%s: sig:%d default SIGHUP handler\n", __func__, sig);
2143                         /* bash is observed to signal whole process groups,
2144                          * not individual processes */
2145                         for (job = G.job_list; job; job = job->next) {
2146                                 if (job->pgrp <= 0)
2147                                         continue;
2148                                 debug_printf_exec("HUPing pgrp %d\n", job->pgrp);
2149                                 if (kill(- job->pgrp, SIGHUP) == 0)
2150                                         kill(- job->pgrp, SIGCONT);
2151                         }
2152                         sigexit(SIGHUP);
2153                 }
2154 #endif
2155 #if ENABLE_HUSH_FAST
2156                 case SIGCHLD:
2157                         debug_printf_exec("%s: sig:%d default SIGCHLD handler\n", __func__, sig);
2158                         G.count_SIGCHLD++;
2159 //bb_error_msg("[%d] check_and_run_traps: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
2160                         /* Note:
2161                          * We don't do 'last_sig = sig' here -> NOT returning this sig.
2162                          * This simplifies wait builtin a bit.
2163                          */
2164                         break;
2165 #endif
2166                 default: /* ignored: */
2167                         debug_printf_exec("%s: sig:%d default handling is to ignore\n", __func__, sig);
2168                         /* SIGTERM, SIGQUIT, SIGTTIN, SIGTTOU, SIGTSTP */
2169                         /* Note:
2170                          * We don't do 'last_sig = sig' here -> NOT returning this sig.
2171                          * Example: wait is not interrupted by TERM
2172                          * in interactive shell, because TERM is ignored.
2173                          */
2174                         break;
2175                 }
2176         }
2177         return last_sig;
2178 }
2179
2180
2181 static const char *get_cwd(int force)
2182 {
2183         if (force || G.cwd == NULL) {
2184                 /* xrealloc_getcwd_or_warn(arg) calls free(arg),
2185                  * we must not try to free(bb_msg_unknown) */
2186                 if (G.cwd == bb_msg_unknown)
2187                         G.cwd = NULL;
2188                 G.cwd = xrealloc_getcwd_or_warn((char *)G.cwd);
2189                 if (!G.cwd)
2190                         G.cwd = bb_msg_unknown;
2191         }
2192         return G.cwd;
2193 }
2194
2195
2196 /*
2197  * Shell and environment variable support
2198  */
2199 static struct variable **get_ptr_to_local_var(const char *name, unsigned len)
2200 {
2201         struct variable **pp;
2202         struct variable *cur;
2203
2204         pp = &G.top_var;
2205         while ((cur = *pp) != NULL) {
2206                 if (strncmp(cur->varstr, name, len) == 0 && cur->varstr[len] == '=')
2207                         return pp;
2208                 pp = &cur->next;
2209         }
2210         return NULL;
2211 }
2212
2213 static const char* FAST_FUNC get_local_var_value(const char *name)
2214 {
2215         struct variable **vpp;
2216         unsigned len = strlen(name);
2217
2218         if (G.expanded_assignments) {
2219                 char **cpp = G.expanded_assignments;
2220                 while (*cpp) {
2221                         char *cp = *cpp;
2222                         if (strncmp(cp, name, len) == 0 && cp[len] == '=')
2223                                 return cp + len + 1;
2224                         cpp++;
2225                 }
2226         }
2227
2228         vpp = get_ptr_to_local_var(name, len);
2229         if (vpp)
2230                 return (*vpp)->varstr + len + 1;
2231
2232         if (strcmp(name, "PPID") == 0)
2233                 return utoa(G.root_ppid);
2234         // bash compat: UID? EUID?
2235 #if ENABLE_HUSH_RANDOM_SUPPORT
2236         if (strcmp(name, "RANDOM") == 0)
2237                 return utoa(next_random(&G.random_gen));
2238 #endif
2239 #if ENABLE_HUSH_LINENO_VAR
2240         if (strcmp(name, "LINENO") == 0)
2241                 return utoa(G.execute_lineno);
2242 #endif
2243 #if BASH_EPOCH_VARS
2244         {
2245                 const char *fmt = NULL;
2246                 if (strcmp(name, "EPOCHSECONDS") == 0)
2247                         fmt = "%lu";
2248                 else if (strcmp(name, "EPOCHREALTIME") == 0)
2249                         fmt = "%lu.%06u";
2250                 if (fmt) {
2251                         struct timeval tv;
2252                         gettimeofday(&tv, NULL);
2253                         sprintf(G.epoch_buf, fmt, (unsigned long)tv.tv_sec,
2254                                         (unsigned)tv.tv_usec);
2255                         return G.epoch_buf;
2256                 }
2257         }
2258 #endif
2259         return NULL;
2260 }
2261
2262 #if ENABLE_HUSH_GETOPTS
2263 static void handle_changed_special_names(const char *name, unsigned name_len)
2264 {
2265         if (name_len == 6) {
2266                 if (strncmp(name, "OPTIND", 6) == 0) {
2267                         G.getopt_count = 0;
2268                         return;
2269                 }
2270         }
2271 }
2272 #else
2273 /* Do not even bother evaluating arguments */
2274 # define handle_changed_special_names(...) ((void)0)
2275 #endif
2276
2277 /* str holds "NAME=VAL" and is expected to be malloced.
2278  * We take ownership of it.
2279  */
2280 #define SETFLAG_EXPORT   (1 << 0)
2281 #define SETFLAG_UNEXPORT (1 << 1)
2282 #define SETFLAG_MAKE_RO  (1 << 2)
2283 #define SETFLAG_VARLVL_SHIFT   3
2284 static int set_local_var(char *str, unsigned flags)
2285 {
2286         struct variable **cur_pp;
2287         struct variable *cur;
2288         char *free_me = NULL;
2289         char *eq_sign;
2290         int name_len;
2291         int retval;
2292         unsigned local_lvl = (flags >> SETFLAG_VARLVL_SHIFT);
2293
2294         eq_sign = strchr(str, '=');
2295         if (HUSH_DEBUG && !eq_sign)
2296                 bb_simple_error_msg_and_die("BUG in setvar");
2297
2298         name_len = eq_sign - str + 1; /* including '=' */
2299         cur_pp = &G.top_var;
2300         while ((cur = *cur_pp) != NULL) {
2301                 if (strncmp(cur->varstr, str, name_len) != 0) {
2302                         cur_pp = &cur->next;
2303                         continue;
2304                 }
2305
2306                 /* We found an existing var with this name */
2307                 if (cur->flg_read_only) {
2308                         bb_error_msg("%s: readonly variable", str);
2309                         free(str);
2310 //NOTE: in bash, assignment in "export READONLY_VAR=Z" fails, and sets $?=1,
2311 //but export per se succeeds (does put the var in env). We don't mimic that.
2312                         return -1;
2313                 }
2314                 if (flags & SETFLAG_UNEXPORT) { // && cur->flg_export ?
2315                         debug_printf_env("%s: unsetenv '%s'\n", __func__, str);
2316                         *eq_sign = '\0';
2317                         unsetenv(str);
2318                         *eq_sign = '=';
2319                 }
2320                 if (cur->var_nest_level < local_lvl) {
2321                         /* bash 3.2.33(1) and exported vars:
2322                          * # export z=z
2323                          * # f() { local z=a; env | grep ^z; }
2324                          * # f
2325                          * z=a
2326                          * # env | grep ^z
2327                          * z=z
2328                          */
2329                         if (cur->flg_export)
2330                                 flags |= SETFLAG_EXPORT;
2331                         /* New variable is local ("local VAR=VAL" or
2332                          * "VAR=VAL cmd")
2333                          * and existing one is global, or local
2334                          * on a lower level that new one.
2335                          * Remove it from global variable list:
2336                          */
2337                         *cur_pp = cur->next;
2338                         if (G.shadowed_vars_pp) {
2339                                 /* Save in "shadowed" list */
2340                                 debug_printf_env("shadowing %s'%s'/%u by '%s'/%u\n",
2341                                         cur->flg_export ? "exported " : "",
2342                                         cur->varstr, cur->var_nest_level, str, local_lvl
2343                                 );
2344                                 cur->next = *G.shadowed_vars_pp;
2345                                 *G.shadowed_vars_pp = cur;
2346                         } else {
2347                                 /* Came from pseudo_exec_argv(), no need to save: delete it */
2348                                 debug_printf_env("shadow-deleting %s'%s'/%u by '%s'/%u\n",
2349                                         cur->flg_export ? "exported " : "",
2350                                         cur->varstr, cur->var_nest_level, str, local_lvl
2351                                 );
2352                                 if (cur->max_len == 0) /* allocated "VAR=VAL"? */
2353                                         free_me = cur->varstr; /* then free it later */
2354                                 free(cur);
2355                         }
2356                         break;
2357                 }
2358
2359                 if (strcmp(cur->varstr + name_len, eq_sign + 1) == 0) {
2360                         debug_printf_env("assignement '%s' does not change anything\n", str);
2361  free_and_exp:
2362                         free(str);
2363                         goto exp;
2364                 }
2365
2366                 /* Replace the value in the found "struct variable" */
2367                 if (cur->max_len != 0) {
2368                         if (cur->max_len >= strnlen(str, cur->max_len + 1)) {
2369                                 /* This one is from startup env, reuse space */
2370                                 debug_printf_env("reusing startup env for '%s'\n", str);
2371                                 strcpy(cur->varstr, str);
2372                                 goto free_and_exp;
2373                         }
2374                         /* Can't reuse */
2375                         cur->max_len = 0;
2376                         goto set_str_and_exp;
2377                 }
2378                 /* max_len == 0 signifies "malloced" var, which we can
2379                  * (and have to) free. But we can't free(cur->varstr) here:
2380                  * if cur->flg_export is 1, it is in the environment.
2381                  * We should either unsetenv+free, or wait until putenv,
2382                  * then putenv(new)+free(old).
2383                  */
2384                 free_me = cur->varstr;
2385                 goto set_str_and_exp;
2386         }
2387
2388         /* Not found or shadowed - create new variable struct */
2389         debug_printf_env("%s: alloc new var '%s'/%u\n", __func__, str, local_lvl);
2390         cur = xzalloc(sizeof(*cur));
2391         cur->var_nest_level = local_lvl;
2392         cur->next = *cur_pp;
2393         *cur_pp = cur;
2394
2395  set_str_and_exp:
2396         cur->varstr = str;
2397  exp:
2398 #if !BB_MMU || ENABLE_HUSH_READONLY
2399         if (flags & SETFLAG_MAKE_RO) {
2400                 cur->flg_read_only = 1;
2401         }
2402 #endif
2403         if (flags & SETFLAG_EXPORT)
2404                 cur->flg_export = 1;
2405         retval = 0;
2406         if (cur->flg_export) {
2407                 if (flags & SETFLAG_UNEXPORT) {
2408                         cur->flg_export = 0;
2409                         /* unsetenv was already done */
2410                 } else {
2411                         debug_printf_env("%s: putenv '%s'/%u\n", __func__, cur->varstr, cur->var_nest_level);
2412                         retval = putenv(cur->varstr);
2413                         /* fall through to "free(free_me)" -
2414                          * only now we can free old exported malloced string
2415                          */
2416                 }
2417         }
2418         free(free_me);
2419
2420         handle_changed_special_names(cur->varstr, name_len - 1);
2421
2422         return retval;
2423 }
2424
2425 static void FAST_FUNC set_local_var_from_halves(const char *name, const char *val)
2426 {
2427         char *var = xasprintf("%s=%s", name, val);
2428         set_local_var(var, /*flag:*/ 0);
2429 }
2430
2431 /* Used at startup and after each cd */
2432 static void set_pwd_var(unsigned flag)
2433 {
2434         set_local_var(xasprintf("PWD=%s", get_cwd(/*force:*/ 1)), flag);
2435 }
2436
2437 #if ENABLE_HUSH_UNSET || ENABLE_HUSH_GETOPTS
2438 static int unset_local_var_len(const char *name, int name_len)
2439 {
2440         struct variable *cur;
2441         struct variable **cur_pp;
2442
2443         cur_pp = &G.top_var;
2444         while ((cur = *cur_pp) != NULL) {
2445                 if (strncmp(cur->varstr, name, name_len) == 0
2446                  && cur->varstr[name_len] == '='
2447                 ) {
2448                         if (cur->flg_read_only) {
2449                                 bb_error_msg("%s: readonly variable", name);
2450                                 return EXIT_FAILURE;
2451                         }
2452
2453                         *cur_pp = cur->next;
2454                         debug_printf_env("%s: unsetenv '%s'\n", __func__, cur->varstr);
2455                         bb_unsetenv(cur->varstr);
2456                         if (!cur->max_len)
2457                                 free(cur->varstr);
2458                         free(cur);
2459
2460                         break;
2461                 }
2462                 cur_pp = &cur->next;
2463         }
2464
2465         /* Handle "unset LINENO" et al even if did not find the variable to unset */
2466         handle_changed_special_names(name, name_len);
2467
2468         return EXIT_SUCCESS;
2469 }
2470
2471 static int unset_local_var(const char *name)
2472 {
2473         return unset_local_var_len(name, strlen(name));
2474 }
2475 #endif
2476
2477
2478 /*
2479  * Helpers for "var1=val1 var2=val2 cmd" feature
2480  */
2481 static void add_vars(struct variable *var)
2482 {
2483         struct variable *next;
2484
2485         while (var) {
2486                 next = var->next;
2487                 var->next = G.top_var;
2488                 G.top_var = var;
2489                 if (var->flg_export) {
2490                         debug_printf_env("%s: restoring exported '%s'/%u\n", __func__, var->varstr, var->var_nest_level);
2491                         putenv(var->varstr);
2492                 } else {
2493                         debug_printf_env("%s: restoring variable '%s'/%u\n", __func__, var->varstr, var->var_nest_level);
2494                 }
2495                 var = next;
2496         }
2497 }
2498
2499 /* We put strings[i] into variable table and possibly putenv them.
2500  * If variable is read only, we can free the strings[i]
2501  * which attempts to overwrite it.
2502  * The strings[] vector itself is freed.
2503  */
2504 static void set_vars_and_save_old(char **strings)
2505 {
2506         char **s;
2507
2508         if (!strings)
2509                 return;
2510
2511         s = strings;
2512         while (*s) {
2513                 struct variable *var_p;
2514                 struct variable **var_pp;
2515                 char *eq;
2516
2517                 eq = strchr(*s, '=');
2518                 if (HUSH_DEBUG && !eq)
2519                         bb_simple_error_msg_and_die("BUG in varexp4");
2520                 var_pp = get_ptr_to_local_var(*s, eq - *s);
2521                 if (var_pp) {
2522                         var_p = *var_pp;
2523                         if (var_p->flg_read_only) {
2524                                 char **p;
2525                                 bb_error_msg("%s: readonly variable", *s);
2526                                 /*
2527                                  * "VAR=V BLTIN" unsets VARs after BLTIN completes.
2528                                  * If VAR is readonly, leaving it in the list
2529                                  * after asssignment error (msg above)
2530                                  * causes doubled error message later, on unset.
2531                                  */
2532                                 debug_printf_env("removing/freeing '%s' element\n", *s);
2533                                 free(*s);
2534                                 p = s;
2535                                 do { *p = p[1]; p++; } while (*p);
2536                                 goto next;
2537                         }
2538                         /* below, set_local_var() with nest level will
2539                          * "shadow" (remove) this variable from
2540                          * global linked list.
2541                          */
2542                 }
2543                 debug_printf_env("%s: env override '%s'/%u\n", __func__, *s, G.var_nest_level);
2544                 set_local_var(*s, (G.var_nest_level << SETFLAG_VARLVL_SHIFT) | SETFLAG_EXPORT);
2545                 s++;
2546  next: ;
2547         }
2548         free(strings);
2549 }
2550
2551
2552 /*
2553  * Unicode helper
2554  */
2555 static void reinit_unicode_for_hush(void)
2556 {
2557         /* Unicode support should be activated even if LANG is set
2558          * _during_ shell execution, not only if it was set when
2559          * shell was started. Therefore, re-check LANG every time:
2560          */
2561         if (ENABLE_FEATURE_CHECK_UNICODE_IN_ENV
2562          || ENABLE_UNICODE_USING_LOCALE
2563         ) {
2564                 const char *s = get_local_var_value("LC_ALL");
2565                 if (!s) s = get_local_var_value("LC_CTYPE");
2566                 if (!s) s = get_local_var_value("LANG");
2567                 reinit_unicode(s);
2568         }
2569 }
2570
2571 /*
2572  * in_str support (strings, and "strings" read from files).
2573  */
2574
2575 #if ENABLE_HUSH_INTERACTIVE
2576 /* To test correct lineedit/interactive behavior, type from command line:
2577  *      echo $P\
2578  *      \
2579  *      AT\
2580  *      H\
2581  *      \
2582  * It exercises a lot of corner cases.
2583  */
2584 static const char *setup_prompt_string(void)
2585 {
2586         const char *prompt_str;
2587
2588         debug_printf_prompt("%s promptmode:%d\n", __func__, G.promptmode);
2589
2590 # if ENABLE_FEATURE_EDITING_FANCY_PROMPT
2591         prompt_str = get_local_var_value(G.promptmode == 0 ? "PS1" : "PS2");
2592         if (!prompt_str)
2593                 prompt_str = "";
2594 # else
2595         prompt_str = "> "; /* if PS2, else... */
2596         if (G.promptmode == 0) { /* PS1 */
2597                 /* No fancy prompts supported, (re)generate "CURDIR $ " by hand */
2598                 free(G.PS1);
2599                 /* bash uses $PWD value, even if it is set by user.
2600                  * It uses current dir only if PWD is unset.
2601                  * We always use current dir. */
2602                 G.PS1 = xasprintf("%s %c ", get_cwd(0), (geteuid() != 0) ? '$' : '#');
2603         }
2604 # endif
2605         debug_printf("prompt_str '%s'\n", prompt_str);
2606         return prompt_str;
2607 }
2608 static int get_user_input(struct in_str *i)
2609 {
2610         int r;
2611         const char *prompt_str;
2612
2613         prompt_str = setup_prompt_string();
2614 # if ENABLE_FEATURE_EDITING
2615         for (;;) {
2616                 reinit_unicode_for_hush();
2617                 if (G.flag_SIGINT) {
2618                         /* There was ^C'ed, make it look prettier: */
2619                         bb_putchar('\n');
2620                         G.flag_SIGINT = 0;
2621                 }
2622                 /* buglet: SIGINT will not make new prompt to appear _at once_,
2623                  * only after <Enter>. (^C works immediately) */
2624                 r = read_line_input(G.line_input_state, prompt_str,
2625                                 G.user_input_buf, CONFIG_FEATURE_EDITING_MAX_LEN-1
2626                 );
2627                 /* read_line_input intercepts ^C, "convert" it to SIGINT */
2628                 if (r == 0)
2629                         raise(SIGINT);
2630                 check_and_run_traps();
2631                 if (r != 0 && !G.flag_SIGINT)
2632                         break;
2633                 /* ^C or SIGINT: repeat */
2634                 /* bash prints ^C even on real SIGINT (non-kbd generated) */
2635                 write(STDOUT_FILENO, "^C", 2);
2636                 G.last_exitcode = 128 + SIGINT;
2637         }
2638         if (r < 0) {
2639                 /* EOF/error detected */
2640                 i->p = NULL;
2641                 i->peek_buf[0] = r = EOF;
2642                 return r;
2643         }
2644         i->p = G.user_input_buf;
2645         return (unsigned char)*i->p++;
2646 # else
2647         for (;;) {
2648                 G.flag_SIGINT = 0;
2649                 if (i->last_char == '\0' || i->last_char == '\n') {
2650                         /* Why check_and_run_traps here? Try this interactively:
2651                          * $ trap 'echo INT' INT; (sleep 2; kill -INT $$) &
2652                          * $ <[enter], repeatedly...>
2653                          * Without check_and_run_traps, handler never runs.
2654                          */
2655                         check_and_run_traps();
2656                         fputs(prompt_str, stdout);
2657                 }
2658                 fflush_all();
2659 //FIXME: here ^C or SIGINT will have effect only after <Enter>
2660                 r = hfgetc(i->file);
2661                 /* In !ENABLE_FEATURE_EDITING we don't use read_line_input,
2662                  * no ^C masking happens during fgetc, no special code for ^C:
2663                  * it generates SIGINT as usual.
2664                  */
2665                 check_and_run_traps();
2666                 if (G.flag_SIGINT)
2667                         G.last_exitcode = 128 + SIGINT;
2668                 if (r != '\0')
2669                         break;
2670         }
2671         return r;
2672 # endif
2673 }
2674 /* This is the magic location that prints prompts
2675  * and gets data back from the user */
2676 static int fgetc_interactive(struct in_str *i)
2677 {
2678         int ch;
2679         /* If it's interactive stdin, get new line. */
2680         if (G_interactive_fd && i->file == G.HFILE_stdin) {
2681                 /* Returns first char (or EOF), the rest is in i->p[] */
2682                 ch = get_user_input(i);
2683                 G.promptmode = 1; /* PS2 */
2684                 debug_printf_prompt("%s promptmode=%d\n", __func__, G.promptmode);
2685         } else {
2686                 /* Not stdin: script file, sourced file, etc */
2687                 do ch = hfgetc(i->file); while (ch == '\0');
2688         }
2689         return ch;
2690 }
2691 #else
2692 static ALWAYS_INLINE int fgetc_interactive(struct in_str *i)
2693 {
2694         int ch;
2695         do ch = hfgetc(i->file); while (ch == '\0');
2696         return ch;
2697 }
2698 #endif  /* INTERACTIVE */
2699
2700 static int i_getch(struct in_str *i)
2701 {
2702         int ch;
2703
2704         if (!i->file) {
2705                 /* string-based in_str */
2706                 ch = (unsigned char)*i->p;
2707                 if (ch != '\0') {
2708                         i->p++;
2709                         i->last_char = ch;
2710                         return ch;
2711                 }
2712                 return EOF;
2713         }
2714
2715         /* FILE-based in_str */
2716
2717 #if ENABLE_FEATURE_EDITING
2718         /* This can be stdin, check line editing char[] buffer */
2719         if (i->p && *i->p != '\0') {
2720                 ch = (unsigned char)*i->p++;
2721                 goto out;
2722         }
2723 #endif
2724         /* peek_buf[] is an int array, not char. Can contain EOF. */
2725         ch = i->peek_buf[0];
2726         if (ch != 0) {
2727                 int ch2 = i->peek_buf[1];
2728                 i->peek_buf[0] = ch2;
2729                 if (ch2 == 0) /* very likely, avoid redundant write */
2730                         goto out;
2731                 i->peek_buf[1] = 0;
2732                 goto out;
2733         }
2734
2735         ch = fgetc_interactive(i);
2736  out:
2737         debug_printf("file_get: got '%c' %d\n", ch, ch);
2738         i->last_char = ch;
2739 #if ENABLE_HUSH_LINENO_VAR
2740         if (ch == '\n') {
2741                 G.parse_lineno++;
2742                 debug_printf_parse("G.parse_lineno++ = %u\n", G.parse_lineno);
2743         }
2744 #endif
2745         return ch;
2746 }
2747
2748 static int i_peek(struct in_str *i)
2749 {
2750         int ch;
2751
2752         if (!i->file) {
2753                 /* string-based in_str */
2754                 /* Doesn't report EOF on NUL. None of the callers care. */
2755                 return (unsigned char)*i->p;
2756         }
2757
2758         /* FILE-based in_str */
2759
2760 #if ENABLE_FEATURE_EDITING && ENABLE_HUSH_INTERACTIVE
2761         /* This can be stdin, check line editing char[] buffer */
2762         if (i->p && *i->p != '\0')
2763                 return (unsigned char)*i->p;
2764 #endif
2765         /* peek_buf[] is an int array, not char. Can contain EOF. */
2766         ch = i->peek_buf[0];
2767         if (ch != 0)
2768                 return ch;
2769
2770         /* Need to get a new char */
2771         ch = fgetc_interactive(i);
2772         debug_printf("file_peek: got '%c' %d\n", ch, ch);
2773
2774         /* Save it by either rolling back line editing buffer, or in i->peek_buf[0] */
2775 #if ENABLE_FEATURE_EDITING && ENABLE_HUSH_INTERACTIVE
2776         if (i->p) {
2777                 i->p -= 1;
2778                 return ch;
2779         }
2780 #endif
2781         i->peek_buf[0] = ch;
2782         /*i->peek_buf[1] = 0; - already is */
2783         return ch;
2784 }
2785
2786 /* Only ever called if i_peek() was called, and did not return EOF.
2787  * IOW: we know the previous peek saw an ordinary char, not EOF, not NUL,
2788  * not end-of-line. Therefore we never need to read a new editing line here.
2789  */
2790 static int i_peek2(struct in_str *i)
2791 {
2792         int ch;
2793
2794         /* There are two cases when i->p[] buffer exists.
2795          * (1) it's a string in_str.
2796          * (2) It's a file, and we have a saved line editing buffer.
2797          * In both cases, we know that i->p[0] exists and not NUL, and
2798          * the peek2 result is in i->p[1].
2799          */
2800         if (i->p)
2801                 return (unsigned char)i->p[1];
2802
2803         /* Now we know it is a file-based in_str. */
2804
2805         /* peek_buf[] is an int array, not char. Can contain EOF. */
2806         /* Is there 2nd char? */
2807         ch = i->peek_buf[1];
2808         if (ch == 0) {
2809                 /* We did not read it yet, get it now */
2810                 do ch = hfgetc(i->file); while (ch == '\0');
2811                 i->peek_buf[1] = ch;
2812         }
2813
2814         debug_printf("file_peek2: got '%c' %d\n", ch, ch);
2815         return ch;
2816 }
2817
2818 static int i_getch_and_eat_bkslash_nl(struct in_str *input)
2819 {
2820         for (;;) {
2821                 int ch, ch2;
2822
2823                 ch = i_getch(input);
2824                 if (ch != '\\')
2825                         return ch;
2826                 ch2 = i_peek(input);
2827                 if (ch2 != '\n')
2828                         return ch;
2829                 /* backslash+newline, skip it */
2830                 i_getch(input);
2831         }
2832 }
2833
2834 /* Note: this function _eats_ \<newline> pairs, safe to use plain
2835  * i_getch() after it instead of i_getch_and_eat_bkslash_nl().
2836  */
2837 static int i_peek_and_eat_bkslash_nl(struct in_str *input)
2838 {
2839         for (;;) {
2840                 int ch, ch2;
2841
2842                 ch = i_peek(input);
2843                 if (ch != '\\')
2844                         return ch;
2845                 ch2 = i_peek2(input);
2846                 if (ch2 != '\n')
2847                         return ch;
2848                 /* backslash+newline, skip it */
2849                 i_getch(input);
2850                 i_getch(input);
2851         }
2852 }
2853
2854 static void setup_file_in_str(struct in_str *i, HFILE *fp)
2855 {
2856         memset(i, 0, sizeof(*i));
2857         i->file = fp;
2858         /* i->p = NULL; */
2859 }
2860
2861 static void setup_string_in_str(struct in_str *i, const char *s)
2862 {
2863         memset(i, 0, sizeof(*i));
2864         /*i->file = NULL */;
2865         i->p = s;
2866 }
2867
2868
2869 /*
2870  * o_string support
2871  */
2872 #define B_CHUNK  (32 * sizeof(char*))
2873
2874 static void o_reset_to_empty_unquoted(o_string *o)
2875 {
2876         o->length = 0;
2877         o->has_quoted_part = 0;
2878         if (o->data)
2879                 o->data[0] = '\0';
2880 }
2881
2882 static void o_free_and_set_NULL(o_string *o)
2883 {
2884         free(o->data);
2885         memset(o, 0, sizeof(*o));
2886 }
2887
2888 static ALWAYS_INLINE void o_free(o_string *o)
2889 {
2890         free(o->data);
2891 }
2892
2893 static void o_grow_by(o_string *o, int len)
2894 {
2895         if (o->length + len > o->maxlen) {
2896                 o->maxlen += (2 * len) | (B_CHUNK-1);
2897                 o->data = xrealloc(o->data, 1 + o->maxlen);
2898         }
2899 }
2900
2901 static void o_addchr(o_string *o, int ch)
2902 {
2903         debug_printf("o_addchr: '%c' o->length=%d o=%p\n", ch, o->length, o);
2904         if (o->length < o->maxlen) {
2905                 /* likely. avoid o_grow_by() call */
2906  add:
2907                 o->data[o->length] = ch;
2908                 o->length++;
2909                 o->data[o->length] = '\0';
2910                 return;
2911         }
2912         o_grow_by(o, 1);
2913         goto add;
2914 }
2915
2916 #if 0
2917 /* Valid only if we know o_string is not empty */
2918 static void o_delchr(o_string *o)
2919 {
2920         o->length--;
2921         o->data[o->length] = '\0';
2922 }
2923 #endif
2924
2925 static void o_addblock(o_string *o, const char *str, int len)
2926 {
2927         o_grow_by(o, len);
2928         ((char*)mempcpy(&o->data[o->length], str, len))[0] = '\0';
2929         o->length += len;
2930 }
2931
2932 static void o_addstr(o_string *o, const char *str)
2933 {
2934         o_addblock(o, str, strlen(str));
2935 }
2936
2937 static void o_addstr_with_NUL(o_string *o, const char *str)
2938 {
2939         o_addblock(o, str, strlen(str) + 1);
2940 }
2941
2942 #if !BB_MMU
2943 static void nommu_addchr(o_string *o, int ch)
2944 {
2945         if (o)
2946                 o_addchr(o, ch);
2947 }
2948 #else
2949 # define nommu_addchr(o, str) ((void)0)
2950 #endif
2951
2952 #if ENABLE_HUSH_MODE_X
2953 static void x_mode_addchr(int ch)
2954 {
2955         o_addchr(&G.x_mode_buf, ch);
2956 }
2957 static void x_mode_addstr(const char *str)
2958 {
2959         o_addstr(&G.x_mode_buf, str);
2960 }
2961 static void x_mode_addblock(const char *str, int len)
2962 {
2963         o_addblock(&G.x_mode_buf, str, len);
2964 }
2965 static void x_mode_prefix(void)
2966 {
2967         int n = G.x_mode_depth;
2968         do x_mode_addchr('+'); while (--n >= 0);
2969 }
2970 static void x_mode_flush(void)
2971 {
2972         int len = G.x_mode_buf.length;
2973         if (len <= 0)
2974                 return;
2975         if (G.x_mode_fd > 0) {
2976                 G.x_mode_buf.data[len] = '\n';
2977                 full_write(G.x_mode_fd, G.x_mode_buf.data, len + 1);
2978         }
2979         G.x_mode_buf.length = 0;
2980 }
2981 #endif
2982
2983 /*
2984  * HUSH_BRACE_EXPANSION code needs corresponding quoting on variable expansion side.
2985  * Currently, "v='{q,w}'; echo $v" erroneously expands braces in $v.
2986  * Apparently, on unquoted $v bash still does globbing
2987  * ("v='*.txt'; echo $v" prints all .txt files),
2988  * but NOT brace expansion! Thus, there should be TWO independent
2989  * quoting mechanisms on $v expansion side: one protects
2990  * $v from brace expansion, and other additionally protects "$v" against globbing.
2991  * We have only second one.
2992  */
2993
2994 #if ENABLE_HUSH_BRACE_EXPANSION
2995 # define MAYBE_BRACES "{}"
2996 #else
2997 # define MAYBE_BRACES ""
2998 #endif
2999
3000 /* My analysis of quoting semantics tells me that state information
3001  * is associated with a destination, not a source.
3002  */
3003 static void o_addqchr(o_string *o, int ch)
3004 {
3005         int sz = 1;
3006         char *found = strchr("*?[\\" MAYBE_BRACES, ch);
3007         if (found)
3008                 sz++;
3009         o_grow_by(o, sz);
3010         if (found) {
3011                 o->data[o->length] = '\\';
3012                 o->length++;
3013         }
3014         o->data[o->length] = ch;
3015         o->length++;
3016         o->data[o->length] = '\0';
3017 }
3018
3019 static void o_addQchr(o_string *o, int ch)
3020 {
3021         int sz = 1;
3022         if ((o->o_expflags & EXP_FLAG_ESC_GLOB_CHARS)
3023          && strchr("*?[\\" MAYBE_BRACES, ch)
3024         ) {
3025                 sz++;
3026                 o->data[o->length] = '\\';
3027                 o->length++;
3028         }
3029         o_grow_by(o, sz);
3030         o->data[o->length] = ch;
3031         o->length++;
3032         o->data[o->length] = '\0';
3033 }
3034
3035 static void o_addqblock(o_string *o, const char *str, int len)
3036 {
3037         while (len) {
3038                 char ch;
3039                 int sz;
3040                 int ordinary_cnt = strcspn(str, "*?[\\" MAYBE_BRACES);
3041                 if (ordinary_cnt > len) /* paranoia */
3042                         ordinary_cnt = len;
3043                 o_addblock(o, str, ordinary_cnt);
3044                 if (ordinary_cnt == len)
3045                         return; /* NUL is already added by o_addblock */
3046                 str += ordinary_cnt;
3047                 len -= ordinary_cnt + 1; /* we are processing + 1 char below */
3048
3049                 ch = *str++;
3050                 sz = 1;
3051                 if (ch) { /* it is necessarily one of "*?[\\" MAYBE_BRACES */
3052                         sz++;
3053                         o->data[o->length] = '\\';
3054                         o->length++;
3055                 }
3056                 o_grow_by(o, sz);
3057                 o->data[o->length] = ch;
3058                 o->length++;
3059         }
3060         o->data[o->length] = '\0';
3061 }
3062
3063 static void o_addQblock(o_string *o, const char *str, int len)
3064 {
3065         if (!(o->o_expflags & EXP_FLAG_ESC_GLOB_CHARS)) {
3066                 o_addblock(o, str, len);
3067                 return;
3068         }
3069         o_addqblock(o, str, len);
3070 }
3071
3072 static void o_addQstr(o_string *o, const char *str)
3073 {
3074         o_addQblock(o, str, strlen(str));
3075 }
3076
3077 /* A special kind of o_string for $VAR and `cmd` expansion.
3078  * It contains char* list[] at the beginning, which is grown in 16 element
3079  * increments. Actual string data starts at the next multiple of 16 * (char*).
3080  * list[i] contains an INDEX (int!) into this string data.
3081  * It means that if list[] needs to grow, data needs to be moved higher up
3082  * but list[i]'s need not be modified.
3083  * NB: remembering how many list[i]'s you have there is crucial.
3084  * o_finalize_list() operation post-processes this structure - calculates
3085  * and stores actual char* ptrs in list[]. Oh, it NULL terminates it as well.
3086  */
3087 #if DEBUG_EXPAND || DEBUG_GLOB
3088 static void debug_print_list(const char *prefix, o_string *o, int n)
3089 {
3090         char **list = (char**)o->data;
3091         int string_start = ((n + 0xf) & ~0xf) * sizeof(list[0]);
3092         int i = 0;
3093
3094         indent();
3095         fdprintf(2, "%s: list:%p n:%d string_start:%d length:%d maxlen:%d glob:%d quoted:%d escape:%d\n",
3096                         prefix, list, n, string_start, o->length, o->maxlen,
3097                         !!(o->o_expflags & EXP_FLAG_GLOB),
3098                         o->has_quoted_part,
3099                         !!(o->o_expflags & EXP_FLAG_ESC_GLOB_CHARS));
3100         while (i < n) {
3101                 indent();
3102                 fdprintf(2, " list[%d]=%d '%s' %p\n", i, (int)(uintptr_t)list[i],
3103                                 o->data + (int)(uintptr_t)list[i] + string_start,
3104                                 o->data + (int)(uintptr_t)list[i] + string_start);
3105                 i++;
3106         }
3107         if (n) {
3108                 const char *p = o->data + (int)(uintptr_t)list[n - 1] + string_start;
3109                 indent();
3110                 fdprintf(2, " total_sz:%ld\n", (long)((p + strlen(p) + 1) - o->data));
3111         }
3112 }
3113 #else
3114 # define debug_print_list(prefix, o, n) ((void)0)
3115 #endif
3116
3117 /* n = o_save_ptr_helper(str, n) "starts new string" by storing an index value
3118  * in list[n] so that it points past last stored byte so far.
3119  * It returns n+1. */
3120 static int o_save_ptr_helper(o_string *o, int n)
3121 {
3122         char **list = (char**)o->data;
3123         int string_start;
3124         int string_len;
3125
3126         if (!o->has_empty_slot) {
3127                 string_start = ((n + 0xf) & ~0xf) * sizeof(list[0]);
3128                 string_len = o->length - string_start;
3129                 if (!(n & 0xf)) { /* 0, 0x10, 0x20...? */
3130                         debug_printf_list("list[%d]=%d string_start=%d (growing)\n", n, string_len, string_start);
3131                         /* list[n] points to string_start, make space for 16 more pointers */
3132                         o->maxlen += 0x10 * sizeof(list[0]);
3133                         o->data = xrealloc(o->data, o->maxlen + 1);
3134                         list = (char**)o->data;
3135                         memmove(list + n + 0x10, list + n, string_len);
3136                         /*
3137                          * expand_on_ifs() has a "previous argv[] ends in IFS?"
3138                          * check. (grep for -prev-ifs-check-).
3139                          * Ensure that argv[-1][last] is not garbage
3140                          * but zero bytes, to save index check there.
3141                          */
3142                         list[n + 0x10 - 1] = 0;
3143                         o->length += 0x10 * sizeof(list[0]);
3144                 } else {
3145                         debug_printf_list("list[%d]=%d string_start=%d\n",
3146                                         n, string_len, string_start);
3147                 }
3148         } else {
3149                 /* We have empty slot at list[n], reuse without growth */
3150                 string_start = ((n+1 + 0xf) & ~0xf) * sizeof(list[0]); /* NB: n+1! */
3151                 string_len = o->length - string_start;
3152                 debug_printf_list("list[%d]=%d string_start=%d (empty slot)\n",
3153                                 n, string_len, string_start);
3154                 o->has_empty_slot = 0;
3155         }
3156         o->has_quoted_part = 0;
3157         list[n] = (char*)(uintptr_t)string_len;
3158         return n + 1;
3159 }
3160
3161 /* "What was our last o_save_ptr'ed position (byte offset relative o->data)?" */
3162 static int o_get_last_ptr(o_string *o, int n)
3163 {
3164         char **list = (char**)o->data;
3165         int string_start = ((n + 0xf) & ~0xf) * sizeof(list[0]);
3166
3167         return ((int)(uintptr_t)list[n-1]) + string_start;
3168 }
3169
3170 /*
3171  * Globbing routines.
3172  *
3173  * Most words in commands need to be globbed, even ones which are
3174  * (single or double) quoted. This stems from the possiblity of
3175  * constructs like "abc"* and 'abc'* - these should be globbed.
3176  * Having a different code path for fully-quoted strings ("abc",
3177  * 'abc') would only help performance-wise, but we still need
3178  * code for partially-quoted strings.
3179  *
3180  * Unfortunately, if we want to match bash and ash behavior in all cases,
3181  * the logic can't be "shell-syntax argument is first transformed
3182  * to a string, then globbed, and if globbing does not match anything,
3183  * it is used verbatim". Here are two examples where it fails:
3184  *
3185  *      echo 'b\*'?
3186  *
3187  * The globbing can't be avoided (because of '?' at the end).
3188  * The glob pattern is: b\\\*? - IOW, both \ and * are literals
3189  * and are glob-escaped. If this does not match, bash/ash print b\*?
3190  * - IOW: they "unbackslash" the glob pattern.
3191  * Now, look at this:
3192  *
3193  *      v='\\\*'; echo b$v?
3194  *
3195  * The glob pattern is the same here: b\\\*? - the unquoted $v expansion
3196  * should be used as glob pattern with no changes. However, if glob
3197  * does not match, bash/ash print b\\\*? - NOT THE SAME as first example!
3198  *
3199  * ash implements this by having an encoded representation of the word
3200  * to glob, which IS NOT THE SAME as the glob pattern - it has more data.
3201  * Glob pattern is derived from it. If glob fails, the decision what result
3202  * should be is made using that encoded representation. Not glob pattern.
3203  */
3204
3205 #if ENABLE_HUSH_BRACE_EXPANSION
3206 /* There in a GNU extension, GLOB_BRACE, but it is not usable:
3207  * first, it processes even {a} (no commas), second,
3208  * I didn't manage to make it return strings when they don't match
3209  * existing files. Need to re-implement it.
3210  */
3211
3212 /* Helper */
3213 static int glob_needed(const char *s)
3214 {
3215         while (*s) {
3216                 if (*s == '\\') {
3217                         if (!s[1])
3218                                 return 0;
3219                         s += 2;
3220                         continue;
3221                 }
3222                 if (*s == '*' || *s == '[' || *s == '?' || *s == '{')
3223                         return 1;
3224                 s++;
3225         }
3226         return 0;
3227 }
3228 /* Return pointer to next closing brace or to comma */
3229 static const char *next_brace_sub(const char *cp)
3230 {
3231         unsigned depth = 0;
3232         cp++;
3233         while (*cp != '\0') {
3234                 if (*cp == '\\') {
3235                         if (*++cp == '\0')
3236                                 break;
3237                         cp++;
3238                         continue;
3239                 }
3240                 if ((*cp == '}' && depth-- == 0) || (*cp == ',' && depth == 0))
3241                         break;
3242                 if (*cp++ == '{')
3243                         depth++;
3244         }
3245
3246         return *cp != '\0' ? cp : NULL;
3247 }
3248 /* Recursive brace globber. Note: may garble pattern[]. */
3249 static int glob_brace(char *pattern, o_string *o, int n)
3250 {
3251         char *new_pattern_buf;
3252         const char *begin;
3253         const char *next;
3254         const char *rest;
3255         const char *p;
3256         size_t rest_len;
3257
3258         debug_printf_glob("glob_brace('%s')\n", pattern);
3259
3260         begin = pattern;
3261         while (1) {
3262                 if (*begin == '\0')
3263                         goto simple_glob;
3264                 if (*begin == '{') {
3265                         /* Find the first sub-pattern and at the same time
3266                          * find the rest after the closing brace */
3267                         next = next_brace_sub(begin);
3268                         if (next == NULL) {
3269                                 /* An illegal expression */
3270                                 goto simple_glob;
3271                         }
3272                         if (*next == '}') {
3273                                 /* "{abc}" with no commas - illegal
3274                                  * brace expr, disregard and skip it */
3275                                 begin = next + 1;
3276                                 continue;
3277                         }
3278                         break;
3279                 }
3280                 if (*begin == '\\' && begin[1] != '\0')
3281                         begin++;
3282                 begin++;
3283         }
3284         debug_printf_glob("begin:%s\n", begin);
3285         debug_printf_glob("next:%s\n", next);
3286
3287         /* Now find the end of the whole brace expression */
3288         rest = next;
3289         while (*rest != '}') {
3290                 rest = next_brace_sub(rest);
3291                 if (rest == NULL) {
3292                         /* An illegal expression */
3293                         goto simple_glob;
3294                 }
3295                 debug_printf_glob("rest:%s\n", rest);
3296         }
3297         rest_len = strlen(++rest) + 1;
3298
3299         /* We are sure the brace expression is well-formed */
3300
3301         /* Allocate working buffer large enough for our work */
3302         new_pattern_buf = xmalloc(strlen(pattern));
3303
3304         /* We have a brace expression.  BEGIN points to the opening {,
3305          * NEXT points past the terminator of the first element, and REST
3306          * points past the final }.  We will accumulate result names from
3307          * recursive runs for each brace alternative in the buffer using
3308          * GLOB_APPEND.  */
3309
3310         p = begin + 1;
3311         while (1) {
3312                 /* Construct the new glob expression */
3313                 memcpy(
3314                         mempcpy(
3315                                 mempcpy(new_pattern_buf,
3316                                         /* We know the prefix for all sub-patterns */
3317                                         pattern, begin - pattern),
3318                                 p, next - p),
3319                         rest, rest_len);
3320
3321                 /* Note: glob_brace() may garble new_pattern_buf[].
3322                  * That's why we re-copy prefix every time (1st memcpy above).
3323                  */
3324                 n = glob_brace(new_pattern_buf, o, n);
3325                 if (*next == '}') {
3326                         /* We saw the last entry */
3327                         break;
3328                 }
3329                 p = next + 1;
3330                 next = next_brace_sub(next);
3331         }
3332         free(new_pattern_buf);
3333         return n;
3334
3335  simple_glob:
3336         {
3337                 int gr;
3338                 glob_t globdata;
3339
3340                 memset(&globdata, 0, sizeof(globdata));
3341                 gr = glob(pattern, 0, NULL, &globdata);
3342                 debug_printf_glob("glob('%s'):%d\n", pattern, gr);
3343                 if (gr != 0) {
3344                         if (gr == GLOB_NOMATCH) {
3345                                 globfree(&globdata);
3346                                 /* NB: garbles parameter */
3347                                 unbackslash(pattern);
3348                                 o_addstr_with_NUL(o, pattern);
3349                                 debug_printf_glob("glob pattern '%s' is literal\n", pattern);
3350                                 return o_save_ptr_helper(o, n);
3351                         }
3352                         if (gr == GLOB_NOSPACE)
3353                                 bb_die_memory_exhausted();
3354                         /* GLOB_ABORTED? Only happens with GLOB_ERR flag,
3355                          * but we didn't specify it. Paranoia again. */
3356                         bb_error_msg_and_die("glob error %d on '%s'", gr, pattern);
3357                 }
3358                 if (globdata.gl_pathv && globdata.gl_pathv[0]) {
3359                         char **argv = globdata.gl_pathv;
3360                         while (1) {
3361                                 o_addstr_with_NUL(o, *argv);
3362                                 n = o_save_ptr_helper(o, n);
3363                                 argv++;
3364                                 if (!*argv)
3365                                         break;
3366                         }
3367                 }
3368                 globfree(&globdata);
3369         }
3370         return n;
3371 }
3372 /* Performs globbing on last list[],
3373  * saving each result as a new list[].
3374  */
3375 static int perform_glob(o_string *o, int n)
3376 {
3377         char *pattern, *copy;
3378
3379         debug_printf_glob("start perform_glob: n:%d o->data:%p\n", n, o->data);
3380         if (!o->data)
3381                 return o_save_ptr_helper(o, n);
3382         pattern = o->data + o_get_last_ptr(o, n);
3383         debug_printf_glob("glob pattern '%s'\n", pattern);
3384         if (!glob_needed(pattern)) {
3385                 /* unbackslash last string in o in place, fix length */
3386                 o->length = unbackslash(pattern) - o->data;
3387                 debug_printf_glob("glob pattern '%s' is literal\n", pattern);
3388                 return o_save_ptr_helper(o, n);
3389         }
3390
3391         copy = xstrdup(pattern);
3392         /* "forget" pattern in o */
3393         o->length = pattern - o->data;
3394         n = glob_brace(copy, o, n);
3395         free(copy);
3396         if (DEBUG_GLOB)
3397                 debug_print_list("perform_glob returning", o, n);
3398         return n;
3399 }
3400
3401 #else /* !HUSH_BRACE_EXPANSION */
3402
3403 /* Helper */
3404 static int glob_needed(const char *s)
3405 {
3406         while (*s) {
3407                 if (*s == '\\') {
3408                         if (!s[1])
3409                                 return 0;
3410                         s += 2;
3411                         continue;
3412                 }
3413                 if (*s == '*' || *s == '[' || *s == '?')
3414                         return 1;
3415                 s++;
3416         }
3417         return 0;
3418 }
3419 /* Performs globbing on last list[],
3420  * saving each result as a new list[].
3421  */
3422 static int perform_glob(o_string *o, int n)
3423 {
3424         glob_t globdata;
3425         int gr;
3426         char *pattern;
3427
3428         debug_printf_glob("start perform_glob: n:%d o->data:%p\n", n, o->data);
3429         if (!o->data)
3430                 return o_save_ptr_helper(o, n);
3431         pattern = o->data + o_get_last_ptr(o, n);
3432         debug_printf_glob("glob pattern '%s'\n", pattern);
3433         if (!glob_needed(pattern)) {
3434  literal:
3435                 /* unbackslash last string in o in place, fix length */
3436                 o->length = unbackslash(pattern) - o->data;
3437                 debug_printf_glob("glob pattern '%s' is literal\n", pattern);
3438                 return o_save_ptr_helper(o, n);
3439         }
3440
3441         memset(&globdata, 0, sizeof(globdata));
3442         /* Can't use GLOB_NOCHECK: it does not unescape the string.
3443          * If we glob "*.\*" and don't find anything, we need
3444          * to fall back to using literal "*.*", but GLOB_NOCHECK
3445          * will return "*.\*"!
3446          */
3447         gr = glob(pattern, 0, NULL, &globdata);
3448         debug_printf_glob("glob('%s'):%d\n", pattern, gr);
3449         if (gr != 0) {
3450                 if (gr == GLOB_NOMATCH) {
3451                         globfree(&globdata);
3452                         goto literal;
3453                 }
3454                 if (gr == GLOB_NOSPACE)
3455                         bb_die_memory_exhausted();
3456                 /* GLOB_ABORTED? Only happens with GLOB_ERR flag,
3457                  * but we didn't specify it. Paranoia again. */
3458                 bb_error_msg_and_die("glob error %d on '%s'", gr, pattern);
3459         }
3460         if (globdata.gl_pathv && globdata.gl_pathv[0]) {
3461                 char **argv = globdata.gl_pathv;
3462                 /* "forget" pattern in o */
3463                 o->length = pattern - o->data;
3464                 while (1) {
3465                         o_addstr_with_NUL(o, *argv);
3466                         n = o_save_ptr_helper(o, n);
3467                         argv++;
3468                         if (!*argv)
3469                                 break;
3470                 }
3471         }
3472         globfree(&globdata);
3473         if (DEBUG_GLOB)
3474                 debug_print_list("perform_glob returning", o, n);
3475         return n;
3476 }
3477
3478 #endif /* !HUSH_BRACE_EXPANSION */
3479
3480 /* If o->o_expflags & EXP_FLAG_GLOB, glob the string so far remembered.
3481  * Otherwise, just finish current list[] and start new */
3482 static int o_save_ptr(o_string *o, int n)
3483 {
3484         if (o->o_expflags & EXP_FLAG_GLOB) {
3485                 /* If o->has_empty_slot, list[n] was already globbed
3486                  * (if it was requested back then when it was filled)
3487                  * so don't do that again! */
3488                 if (!o->has_empty_slot)
3489                         return perform_glob(o, n); /* o_save_ptr_helper is inside */
3490         }
3491         return o_save_ptr_helper(o, n);
3492 }
3493
3494 /* "Please convert list[n] to real char* ptrs, and NULL terminate it." */
3495 static char **o_finalize_list(o_string *o, int n)
3496 {
3497         char **list;
3498         int string_start;
3499
3500         if (DEBUG_EXPAND)
3501                 debug_print_list("finalized", o, n);
3502         debug_printf_expand("finalized n:%d\n", n);
3503         list = (char**)o->data;
3504         string_start = ((n + 0xf) & ~0xf) * sizeof(list[0]);
3505         list[--n] = NULL;
3506         while (n) {
3507                 n--;
3508                 list[n] = o->data + (int)(uintptr_t)list[n] + string_start;
3509         }
3510         return list;
3511 }
3512
3513 static void free_pipe_list(struct pipe *pi);
3514
3515 /* Returns pi->next - next pipe in the list */
3516 static struct pipe *free_pipe(struct pipe *pi)
3517 {
3518         struct pipe *next;
3519         int i;
3520
3521         debug_printf_clean("free_pipe (pid %d)\n", getpid());
3522         for (i = 0; i < pi->num_cmds; i++) {
3523                 struct command *command;
3524                 struct redir_struct *r, *rnext;
3525
3526                 command = &pi->cmds[i];
3527                 debug_printf_clean("  command %d:\n", i);
3528                 if (command->argv) {
3529                         if (DEBUG_CLEAN) {
3530                                 int a;
3531                                 char **p;
3532                                 for (a = 0, p = command->argv; *p; a++, p++) {
3533                                         debug_printf_clean("   argv[%d] = %s\n", a, *p);
3534                                 }
3535                         }
3536                         free_strings(command->argv);
3537                         //command->argv = NULL;
3538                 }
3539                 /* not "else if": on syntax error, we may have both! */
3540                 if (command->group) {
3541                         debug_printf_clean("   begin group (cmd_type:%d)\n",
3542                                         command->cmd_type);
3543                         free_pipe_list(command->group);
3544                         debug_printf_clean("   end group\n");
3545                         //command->group = NULL;
3546                 }
3547                 /* else is crucial here.
3548                  * If group != NULL, child_func is meaningless */
3549 #if ENABLE_HUSH_FUNCTIONS
3550                 else if (command->child_func) {
3551                         debug_printf_exec("cmd %p releases child func at %p\n", command, command->child_func);
3552                         command->child_func->parent_cmd = NULL;
3553                 }
3554 #endif
3555 #if !BB_MMU
3556                 free(command->group_as_string);
3557                 //command->group_as_string = NULL;
3558 #endif
3559                 for (r = command->redirects; r; r = rnext) {
3560                         debug_printf_clean("   redirect %d%s",
3561                                         r->rd_fd, redir_table[r->rd_type].descrip);
3562                         /* guard against the case >$FOO, where foo is unset or blank */
3563                         if (r->rd_filename) {
3564                                 debug_printf_clean(" fname:'%s'\n", r->rd_filename);
3565                                 free(r->rd_filename);
3566                                 //r->rd_filename = NULL;
3567                         }
3568                         debug_printf_clean(" rd_dup:%d\n", r->rd_dup);
3569                         rnext = r->next;
3570                         free(r);
3571                 }
3572                 //command->redirects = NULL;
3573         }
3574         free(pi->cmds);   /* children are an array, they get freed all at once */
3575         //pi->cmds = NULL;
3576 #if ENABLE_HUSH_JOB
3577         free(pi->cmdtext);
3578         //pi->cmdtext = NULL;
3579 #endif
3580
3581         next = pi->next;
3582         free(pi);
3583         return next;
3584 }
3585
3586 static void free_pipe_list(struct pipe *pi)
3587 {
3588         while (pi) {
3589 #if HAS_KEYWORDS
3590                 debug_printf_clean("pipe reserved word %d\n", pi->res_word);
3591 #endif
3592                 debug_printf_clean("pipe followup code %d\n", pi->followup);
3593                 pi = free_pipe(pi);
3594         }
3595 }
3596
3597
3598 /*** Parsing routines ***/
3599
3600 #ifndef debug_print_tree
3601 static void debug_print_tree(struct pipe *pi, int lvl)
3602 {
3603         static const char *const PIPE[] = {
3604                 [PIPE_SEQ] = "SEQ",
3605                 [PIPE_AND] = "AND",
3606                 [PIPE_OR ] = "OR" ,
3607                 [PIPE_BG ] = "BG" ,
3608         };
3609         static const char *RES[] = {
3610                 [RES_NONE ] = "NONE" ,
3611 # if ENABLE_HUSH_IF
3612                 [RES_IF   ] = "IF"   ,
3613                 [RES_THEN ] = "THEN" ,
3614                 [RES_ELIF ] = "ELIF" ,
3615                 [RES_ELSE ] = "ELSE" ,
3616                 [RES_FI   ] = "FI"   ,
3617 # endif
3618 # if ENABLE_HUSH_LOOPS
3619                 [RES_FOR  ] = "FOR"  ,
3620                 [RES_WHILE] = "WHILE",
3621                 [RES_UNTIL] = "UNTIL",
3622                 [RES_DO   ] = "DO"   ,
3623                 [RES_DONE ] = "DONE" ,
3624 # endif
3625 # if ENABLE_HUSH_LOOPS || ENABLE_HUSH_CASE
3626                 [RES_IN   ] = "IN"   ,
3627 # endif
3628 # if ENABLE_HUSH_CASE
3629                 [RES_CASE ] = "CASE" ,
3630                 [RES_CASE_IN ] = "CASE_IN" ,
3631                 [RES_MATCH] = "MATCH",
3632                 [RES_CASE_BODY] = "CASE_BODY",
3633                 [RES_ESAC ] = "ESAC" ,
3634 # endif
3635                 [RES_XXXX ] = "XXXX" ,
3636                 [RES_SNTX ] = "SNTX" ,
3637         };
3638         static const char *const CMDTYPE[] = {
3639                 "{}",
3640                 "()",
3641                 "[noglob]",
3642 # if ENABLE_HUSH_FUNCTIONS
3643                 "func()",
3644 # endif
3645         };
3646
3647         int pin, prn;
3648
3649         pin = 0;
3650         while (pi) {
3651                 fdprintf(2, "%*spipe %d %sres_word=%s followup=%d %s\n",
3652                                 lvl*2, "",
3653                                 pin,
3654                                 (IF_HAS_KEYWORDS(pi->pi_inverted ? "! " :) ""),
3655                                 RES[pi->res_word],
3656                                 pi->followup, PIPE[pi->followup]
3657                 );
3658                 prn = 0;
3659                 while (prn < pi->num_cmds) {
3660                         struct command *command = &pi->cmds[prn];
3661                         char **argv = command->argv;
3662
3663                         fdprintf(2, "%*s cmd %d assignment_cnt:%d",
3664                                         lvl*2, "", prn,
3665                                         command->assignment_cnt);
3666 # if ENABLE_HUSH_LINENO_VAR
3667                         fdprintf(2, " LINENO:%u", command->lineno);
3668 # endif
3669                         if (command->group) {
3670                                 fdprintf(2, " group %s: (argv=%p)%s%s\n",
3671                                                 CMDTYPE[command->cmd_type],
3672                                                 argv
3673 # if !BB_MMU
3674                                                 , " group_as_string:", command->group_as_string
3675 # else
3676                                                 , "", ""
3677 # endif
3678                                 );
3679                                 debug_print_tree(command->group, lvl+1);
3680                                 prn++;
3681                                 continue;
3682                         }
3683                         if (argv) while (*argv) {
3684                                 fdprintf(2, " '%s'", *argv);
3685                                 argv++;
3686                         }
3687                         if (command->redirects)
3688                                 fdprintf(2, " {redir}");
3689                         fdprintf(2, "\n");
3690                         prn++;
3691                 }
3692                 pi = pi->next;
3693                 pin++;
3694         }
3695 }
3696 #endif /* debug_print_tree */
3697
3698 static struct pipe *new_pipe(void)
3699 {
3700         struct pipe *pi;
3701         pi = xzalloc(sizeof(struct pipe));
3702         /*pi->res_word = RES_NONE; - RES_NONE is 0 anyway */
3703         return pi;
3704 }
3705
3706 /* Command (member of a pipe) is complete, or we start a new pipe
3707  * if ctx->command is NULL.
3708  * No errors possible here.
3709  */
3710 static int done_command(struct parse_context *ctx)
3711 {
3712         /* The command is really already in the pipe structure, so
3713          * advance the pipe counter and make a new, null command. */
3714         struct pipe *pi = ctx->pipe;
3715         struct command *command = ctx->command;
3716
3717 #if 0   /* Instead we emit error message at run time */
3718         if (ctx->pending_redirect) {
3719                 /* For example, "cmd >" (no filename to redirect to) */
3720                 syntax_error("invalid redirect");
3721                 ctx->pending_redirect = NULL;
3722         }
3723 #endif
3724
3725         if (command) {
3726                 if (IS_NULL_CMD(command)) {
3727                         debug_printf_parse("done_command: skipping null cmd, num_cmds=%d\n", pi->num_cmds);
3728                         goto clear_and_ret;
3729                 }
3730                 pi->num_cmds++;
3731                 debug_printf_parse("done_command: ++num_cmds=%d\n", pi->num_cmds);
3732                 //debug_print_tree(ctx->list_head, 20);
3733         } else {
3734                 debug_printf_parse("done_command: initializing, num_cmds=%d\n", pi->num_cmds);
3735         }
3736
3737         /* Only real trickiness here is that the uncommitted
3738          * command structure is not counted in pi->num_cmds. */
3739         pi->cmds = xrealloc(pi->cmds, sizeof(*pi->cmds) * (pi->num_cmds+1));
3740         ctx->command = command = &pi->cmds[pi->num_cmds];
3741  clear_and_ret:
3742         memset(command, 0, sizeof(*command));
3743 #if ENABLE_HUSH_LINENO_VAR
3744         command->lineno = G.parse_lineno;
3745         debug_printf_parse("command->lineno = G.parse_lineno (%u)\n", G.parse_lineno);
3746 #endif
3747         return pi->num_cmds; /* used only for 0/nonzero check */
3748 }
3749
3750 static void done_pipe(struct parse_context *ctx, pipe_style type)
3751 {
3752         int not_null;
3753
3754         debug_printf_parse("done_pipe entered, followup %d\n", type);
3755         /* Close previous command */
3756         not_null = done_command(ctx);
3757 #if HAS_KEYWORDS
3758         ctx->pipe->pi_inverted = ctx->ctx_inverted;
3759         ctx->ctx_inverted = 0;
3760         ctx->pipe->res_word = ctx->ctx_res_w;
3761 #endif
3762         if (type == PIPE_BG && ctx->list_head != ctx->pipe) {
3763                 /* Necessary since && and || have precedence over &:
3764                  * "cmd1 && cmd2 &" must spawn both cmds, not only cmd2,
3765                  * in a backgrounded subshell.
3766                  */
3767                 struct pipe *pi;
3768                 struct command *command;
3769
3770                 /* Is this actually this construct, all pipes end with && or ||? */
3771                 pi = ctx->list_head;
3772                 while (pi != ctx->pipe) {
3773                         if (pi->followup != PIPE_AND && pi->followup != PIPE_OR)
3774                                 goto no_conv;
3775                         pi = pi->next;
3776                 }
3777
3778                 debug_printf_parse("BG with more than one pipe, converting to { p1 &&...pN; } &\n");
3779                 pi->followup = PIPE_SEQ; /* close pN _not_ with "&"! */
3780                 pi = xzalloc(sizeof(*pi));
3781                 pi->followup = PIPE_BG;
3782                 pi->num_cmds = 1;
3783                 pi->cmds = xzalloc(sizeof(pi->cmds[0]));
3784                 command = &pi->cmds[0];
3785                 if (CMD_NORMAL != 0) /* "if xzalloc didn't do that already" */
3786                         command->cmd_type = CMD_NORMAL;
3787                 command->group = ctx->list_head;
3788 #if !BB_MMU
3789                 command->group_as_string = xstrndup(
3790                             ctx->as_string.data,
3791                             ctx->as_string.length - 1 /* do not copy last char, "&" */
3792                 );
3793 #endif
3794                 /* Replace all pipes in ctx with one newly created */
3795                 ctx->list_head = ctx->pipe = pi;
3796         } else {
3797  no_conv:
3798                 ctx->pipe->followup = type;
3799         }
3800
3801         /* Without this check, even just <enter> on command line generates
3802          * tree of three NOPs (!). Which is harmless but annoying.
3803          * IOW: it is safe to do it unconditionally. */
3804         if (not_null
3805 #if ENABLE_HUSH_IF
3806          || ctx->ctx_res_w == RES_FI
3807 #endif
3808 #if ENABLE_HUSH_LOOPS
3809          || ctx->ctx_res_w == RES_DONE
3810          || ctx->ctx_res_w == RES_FOR
3811          || ctx->ctx_res_w == RES_IN
3812 #endif
3813 #if ENABLE_HUSH_CASE
3814          || ctx->ctx_res_w == RES_ESAC
3815 #endif
3816         ) {
3817                 struct pipe *new_p;
3818                 debug_printf_parse("done_pipe: adding new pipe: "
3819                                 "not_null:%d ctx->ctx_res_w:%d\n",
3820                                 not_null, ctx->ctx_res_w);
3821                 new_p = new_pipe();
3822                 ctx->pipe->next = new_p;
3823                 ctx->pipe = new_p;
3824                 /* RES_THEN, RES_DO etc are "sticky" -
3825                  * they remain set for pipes inside if/while.
3826                  * This is used to control execution.
3827                  * RES_FOR and RES_IN are NOT sticky (needed to support
3828                  * cases where variable or value happens to match a keyword):
3829                  */
3830 #if ENABLE_HUSH_LOOPS
3831                 if (ctx->ctx_res_w == RES_FOR
3832                  || ctx->ctx_res_w == RES_IN)
3833                         ctx->ctx_res_w = RES_NONE;
3834 #endif
3835 #if ENABLE_HUSH_CASE
3836                 if (ctx->ctx_res_w == RES_MATCH)
3837                         ctx->ctx_res_w = RES_CASE_BODY;
3838                 if (ctx->ctx_res_w == RES_CASE)
3839                         ctx->ctx_res_w = RES_CASE_IN;
3840 #endif
3841                 ctx->command = NULL; /* trick done_command below */
3842                 /* Create the memory for command, roughly:
3843                  * ctx->pipe->cmds = new struct command;
3844                  * ctx->command = &ctx->pipe->cmds[0];
3845                  */
3846                 done_command(ctx);
3847                 //debug_print_tree(ctx->list_head, 10);
3848         }
3849         debug_printf_parse("done_pipe return\n");
3850 }
3851
3852 static void initialize_context(struct parse_context *ctx)
3853 {
3854         memset(ctx, 0, sizeof(*ctx));
3855         if (MAYBE_ASSIGNMENT != 0)
3856                 ctx->is_assignment = MAYBE_ASSIGNMENT;
3857         ctx->pipe = ctx->list_head = new_pipe();
3858         /* Create the memory for command, roughly:
3859          * ctx->pipe->cmds = new struct command;
3860          * ctx->command = &ctx->pipe->cmds[0];
3861          */
3862         done_command(ctx);
3863 }
3864
3865 /* If a reserved word is found and processed, parse context is modified
3866  * and 1 is returned.
3867  */
3868 #if HAS_KEYWORDS
3869 struct reserved_combo {
3870         char literal[6];
3871         unsigned char res;
3872         unsigned char assignment_flag;
3873         int flag;
3874 };
3875 enum {
3876         FLAG_END   = (1 << RES_NONE ),
3877 # if ENABLE_HUSH_IF
3878         FLAG_IF    = (1 << RES_IF   ),
3879         FLAG_THEN  = (1 << RES_THEN ),
3880         FLAG_ELIF  = (1 << RES_ELIF ),
3881         FLAG_ELSE  = (1 << RES_ELSE ),
3882         FLAG_FI    = (1 << RES_FI   ),
3883 # endif
3884 # if ENABLE_HUSH_LOOPS
3885         FLAG_FOR   = (1 << RES_FOR  ),
3886         FLAG_WHILE = (1 << RES_WHILE),
3887         FLAG_UNTIL = (1 << RES_UNTIL),
3888         FLAG_DO    = (1 << RES_DO   ),
3889         FLAG_DONE  = (1 << RES_DONE ),
3890         FLAG_IN    = (1 << RES_IN   ),
3891 # endif
3892 # if ENABLE_HUSH_CASE
3893         FLAG_MATCH = (1 << RES_MATCH),
3894         FLAG_ESAC  = (1 << RES_ESAC ),
3895 # endif
3896         FLAG_START = (1 << RES_XXXX ),
3897 };
3898
3899 static const struct reserved_combo* match_reserved_word(o_string *word)
3900 {
3901         /* Mostly a list of accepted follow-up reserved words.
3902          * FLAG_END means we are done with the sequence, and are ready
3903          * to turn the compound list into a command.
3904          * FLAG_START means the word must start a new compound list.
3905          */
3906         static const struct reserved_combo reserved_list[] = {
3907 # if ENABLE_HUSH_IF
3908                 { "!",     RES_NONE,  NOT_ASSIGNMENT  , 0 },
3909                 { "if",    RES_IF,    MAYBE_ASSIGNMENT, FLAG_THEN | FLAG_START },
3910                 { "then",  RES_THEN,  MAYBE_ASSIGNMENT, FLAG_ELIF | FLAG_ELSE | FLAG_FI },
3911                 { "elif",  RES_ELIF,  MAYBE_ASSIGNMENT, FLAG_THEN },
3912                 { "else",  RES_ELSE,  MAYBE_ASSIGNMENT, FLAG_FI   },
3913                 { "fi",    RES_FI,    NOT_ASSIGNMENT  , FLAG_END  },
3914 # endif
3915 # if ENABLE_HUSH_LOOPS
3916                 { "for",   RES_FOR,   NOT_ASSIGNMENT  , FLAG_IN | FLAG_DO | FLAG_START },
3917                 { "while", RES_WHILE, MAYBE_ASSIGNMENT, FLAG_DO | FLAG_START },
3918                 { "until", RES_UNTIL, MAYBE_ASSIGNMENT, FLAG_DO | FLAG_START },
3919                 { "in",    RES_IN,    NOT_ASSIGNMENT  , FLAG_DO   },
3920                 { "do",    RES_DO,    MAYBE_ASSIGNMENT, FLAG_DONE },
3921                 { "done",  RES_DONE,  NOT_ASSIGNMENT  , FLAG_END  },
3922 # endif
3923 # if ENABLE_HUSH_CASE
3924                 { "case",  RES_CASE,  NOT_ASSIGNMENT  , FLAG_MATCH | FLAG_START },
3925                 { "esac",  RES_ESAC,  NOT_ASSIGNMENT  , FLAG_END  },
3926 # endif
3927         };
3928         const struct reserved_combo *r;
3929
3930         for (r = reserved_list; r < reserved_list + ARRAY_SIZE(reserved_list); r++) {
3931                 if (strcmp(word->data, r->literal) == 0)
3932                         return r;
3933         }
3934         return NULL;
3935 }
3936 /* Return NULL: not a keyword, else: keyword
3937  */
3938 static const struct reserved_combo* reserved_word(struct parse_context *ctx)
3939 {
3940 # if ENABLE_HUSH_CASE
3941         static const struct reserved_combo reserved_match = {
3942                 "",        RES_MATCH, NOT_ASSIGNMENT , FLAG_MATCH | FLAG_ESAC
3943         };
3944 # endif
3945         const struct reserved_combo *r;
3946
3947         if (ctx->word.has_quoted_part)
3948                 return 0;
3949         r = match_reserved_word(&ctx->word);
3950         if (!r)
3951                 return r; /* NULL */
3952
3953         debug_printf("found reserved word %s, res %d\n", r->literal, r->res);
3954 # if ENABLE_HUSH_CASE
3955         if (r->res == RES_IN && ctx->ctx_res_w == RES_CASE_IN) {
3956                 /* "case word IN ..." - IN part starts first MATCH part */
3957                 r = &reserved_match;
3958         } else
3959 # endif
3960         if (r->flag == 0) { /* '!' */
3961                 if (ctx->ctx_inverted) { /* bash doesn't accept '! ! true' */
3962                         syntax_error("! ! command");
3963                         ctx->ctx_res_w = RES_SNTX;
3964                 }
3965                 ctx->ctx_inverted = 1;
3966                 return r;
3967         }
3968         if (r->flag & FLAG_START) {
3969                 struct parse_context *old;
3970
3971                 old = xmemdup(ctx, sizeof(*ctx));
3972                 debug_printf_parse("push stack %p\n", old);
3973                 initialize_context(ctx);
3974                 ctx->stack = old;
3975         } else if (/*ctx->ctx_res_w == RES_NONE ||*/ !(ctx->old_flag & (1 << r->res))) {
3976                 syntax_error_at(ctx->word.data);
3977                 ctx->ctx_res_w = RES_SNTX;
3978                 return r;
3979         } else {
3980                 /* "{...} fi" is ok. "{...} if" is not
3981                  * Example:
3982                  * if { echo foo; } then { echo bar; } fi */
3983                 if (ctx->command->group)
3984                         done_pipe(ctx, PIPE_SEQ);
3985         }
3986
3987         ctx->ctx_res_w = r->res;
3988         ctx->old_flag = r->flag;
3989         ctx->is_assignment = r->assignment_flag;
3990         debug_printf_parse("ctx->is_assignment='%s'\n", assignment_flag[ctx->is_assignment]);
3991
3992         if (ctx->old_flag & FLAG_END) {
3993                 struct parse_context *old;
3994
3995                 done_pipe(ctx, PIPE_SEQ);
3996                 debug_printf_parse("pop stack %p\n", ctx->stack);
3997                 old = ctx->stack;
3998                 old->command->group = ctx->list_head;
3999                 old->command->cmd_type = CMD_NORMAL;
4000 # if !BB_MMU
4001                 /* At this point, the compound command's string is in
4002                  * ctx->as_string... except for the leading keyword!
4003                  * Consider this example: "echo a | if true; then echo a; fi"
4004                  * ctx->as_string will contain "true; then echo a; fi",
4005                  * with "if " remaining in old->as_string!
4006                  */
4007                 {
4008                         char *str;
4009                         int len = old->as_string.length;
4010                         /* Concatenate halves */
4011                         o_addstr(&old->as_string, ctx->as_string.data);
4012                         o_free(&ctx->as_string);
4013                         /* Find where leading keyword starts in first half */
4014                         str = old->as_string.data + len;
4015                         if (str > old->as_string.data)
4016                                 str--; /* skip whitespace after keyword */
4017                         while (str > old->as_string.data && isalpha(str[-1]))
4018                                 str--;
4019                         /* Ugh, we're done with this horrid hack */
4020                         old->command->group_as_string = xstrdup(str);
4021                         debug_printf_parse("pop, remembering as:'%s'\n",
4022                                         old->command->group_as_string);
4023                 }
4024 # endif
4025                 *ctx = *old;   /* physical copy */
4026                 free(old);
4027         }
4028         return r;
4029 }
4030 #endif /* HAS_KEYWORDS */
4031
4032 /* Word is complete, look at it and update parsing context.
4033  * Normal return is 0. Syntax errors return 1.
4034  * Note: on return, word is reset, but not o_free'd!
4035  */
4036 static int done_word(struct parse_context *ctx)
4037 {
4038         struct command *command = ctx->command;
4039
4040         debug_printf_parse("done_word entered: '%s' %p\n", ctx->word.data, command);
4041         if (ctx->word.length == 0 && !ctx->word.has_quoted_part) {
4042                 debug_printf_parse("done_word return 0: true null, ignored\n");
4043                 return 0;
4044         }
4045
4046         if (ctx->pending_redirect) {
4047                 /* We do not glob in e.g. >*.tmp case. bash seems to glob here
4048                  * only if run as "bash", not "sh" */
4049                 /* http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html
4050                  * "2.7 Redirection
4051                  * If the redirection operator is "<<" or "<<-", the word
4052                  * that follows the redirection operator shall be
4053                  * subjected to quote removal; it is unspecified whether
4054                  * any of the other expansions occur. For the other
4055                  * redirection operators, the word that follows the
4056                  * redirection operator shall be subjected to tilde
4057                  * expansion, parameter expansion, command substitution,
4058                  * arithmetic expansion, and quote removal.
4059                  * Pathname expansion shall not be performed
4060                  * on the word by a non-interactive shell; an interactive
4061                  * shell may perform it, but shall do so only when
4062                  * the expansion would result in one word."
4063                  */
4064 //bash does not do parameter/command substitution or arithmetic expansion
4065 //for _heredoc_ redirection word: these constructs look for exact eof marker
4066 // as written:
4067 // <<EOF$t
4068 // <<EOF$((1))
4069 // <<EOF`true`  [this case also makes heredoc "quoted", a-la <<"EOF". Probably bash-4.3.43 bug]
4070
4071                 ctx->pending_redirect->rd_filename = xstrdup(ctx->word.data);
4072                 /* Cater for >\file case:
4073                  * >\a creates file a; >\\a, >"\a", >"\\a" create file \a
4074                  * Same with heredocs:
4075                  * for <<\H delim is H; <<\\H, <<"\H", <<"\\H" - \H
4076                  */
4077                 if (ctx->pending_redirect->rd_type == REDIRECT_HEREDOC) {
4078                         unbackslash(ctx->pending_redirect->rd_filename);
4079                         /* Is it <<"HEREDOC"? */
4080                         if (ctx->word.has_quoted_part) {
4081                                 ctx->pending_redirect->rd_dup |= HEREDOC_QUOTED;
4082                         }
4083                 }
4084                 debug_printf_parse("word stored in rd_filename: '%s'\n", ctx->word.data);
4085                 ctx->pending_redirect = NULL;
4086         } else {
4087 #if HAS_KEYWORDS
4088 # if ENABLE_HUSH_CASE
4089                 if (ctx->ctx_dsemicolon
4090                  && strcmp(ctx->word.data, "esac") != 0 /* not "... pattern) cmd;; esac" */
4091                 ) {
4092                         /* already done when ctx_dsemicolon was set to 1: */
4093                         /* ctx->ctx_res_w = RES_MATCH; */
4094                         ctx->ctx_dsemicolon = 0;
4095                 } else
4096 # endif
4097                 if (!command->argv /* if it's the first word... */
4098 # if ENABLE_HUSH_LOOPS
4099                  && ctx->ctx_res_w != RES_FOR /* ...not after FOR or IN */
4100                  && ctx->ctx_res_w != RES_IN
4101 # endif
4102 # if ENABLE_HUSH_CASE
4103                  && ctx->ctx_res_w != RES_CASE
4104 # endif
4105                 ) {
4106                         const struct reserved_combo *reserved;
4107                         reserved = reserved_word(ctx);
4108                         debug_printf_parse("checking for reserved-ness: %d\n", !!reserved);
4109                         if (reserved) {
4110 # if ENABLE_HUSH_LINENO_VAR
4111 /* Case:
4112  * "while ...; do
4113  *      cmd ..."
4114  * If we don't close the pipe _now_, immediately after "do", lineno logic
4115  * sees "cmd" as starting at "do" - i.e., at the previous line.
4116  */
4117                                 if (0
4118                                  IF_HUSH_IF(|| reserved->res == RES_THEN)
4119                                  IF_HUSH_IF(|| reserved->res == RES_ELIF)
4120                                  IF_HUSH_IF(|| reserved->res == RES_ELSE)
4121                                  IF_HUSH_LOOPS(|| reserved->res == RES_DO)
4122                                 ) {
4123                                         done_pipe(ctx, PIPE_SEQ);
4124                                 }
4125 # endif
4126                                 o_reset_to_empty_unquoted(&ctx->word);
4127                                 debug_printf_parse("done_word return %d\n",
4128                                                 (ctx->ctx_res_w == RES_SNTX));
4129                                 return (ctx->ctx_res_w == RES_SNTX);
4130                         }
4131 # if defined(CMD_SINGLEWORD_NOGLOB)
4132                         if (0
4133 #  if BASH_TEST2
4134                          || strcmp(ctx->word.data, "[[") == 0
4135 #  endif
4136                         /* In bash, local/export/readonly are special, args
4137                          * are assignments and therefore expansion of them
4138                          * should be "one-word" expansion:
4139                          *  $ export i=`echo 'a  b'` # one arg: "i=a  b"
4140                          * compare with:
4141                          *  $ ls i=`echo 'a  b'`     # two args: "i=a" and "b"
4142                          *  ls: cannot access i=a: No such file or directory
4143                          *  ls: cannot access b: No such file or directory
4144                          * Note: bash 3.2.33(1) does this only if export word
4145                          * itself is not quoted:
4146                          *  $ export i=`echo 'aaa  bbb'`; echo "$i"
4147                          *  aaa  bbb
4148                          *  $ "export" i=`echo 'aaa  bbb'`; echo "$i"
4149                          *  aaa
4150                          */
4151                          IF_HUSH_LOCAL(   || strcmp(ctx->word.data, "local") == 0)
4152                          IF_HUSH_EXPORT(  || strcmp(ctx->word.data, "export") == 0)
4153                          IF_HUSH_READONLY(|| strcmp(ctx->word.data, "readonly") == 0)
4154                         ) {
4155                                 command->cmd_type = CMD_SINGLEWORD_NOGLOB;
4156                         }
4157                         /* fall through */
4158 # endif
4159                 }
4160 #endif /* HAS_KEYWORDS */
4161
4162                 if (command->group) {
4163                         /* "{ echo foo; } echo bar" - bad */
4164                         syntax_error_at(ctx->word.data);
4165                         debug_printf_parse("done_word return 1: syntax error, "
4166                                         "groups and arglists don't mix\n");
4167                         return 1;
4168                 }
4169
4170                 /* If this word wasn't an assignment, next ones definitely
4171                  * can't be assignments. Even if they look like ones. */
4172                 if (ctx->is_assignment != DEFINITELY_ASSIGNMENT
4173                  && ctx->is_assignment != WORD_IS_KEYWORD
4174                 ) {
4175                         ctx->is_assignment = NOT_ASSIGNMENT;
4176                 } else {
4177                         if (ctx->is_assignment == DEFINITELY_ASSIGNMENT) {
4178                                 command->assignment_cnt++;
4179                                 debug_printf_parse("++assignment_cnt=%d\n", command->assignment_cnt);
4180                         }
4181                         debug_printf_parse("ctx->is_assignment was:'%s'\n", assignment_flag[ctx->is_assignment]);
4182                         ctx->is_assignment = MAYBE_ASSIGNMENT;
4183                 }
4184                 debug_printf_parse("ctx->is_assignment='%s'\n", assignment_flag[ctx->is_assignment]);
4185                 command->argv = add_string_to_strings(command->argv, xstrdup(ctx->word.data));
4186                 debug_print_strings("word appended to argv", command->argv);
4187         }
4188
4189 #if ENABLE_HUSH_LOOPS
4190         if (ctx->ctx_res_w == RES_FOR) {
4191                 if (ctx->word.has_quoted_part
4192                  || endofname(command->argv[0])[0] != '\0'
4193                 ) {
4194                         /* bash says just "not a valid identifier" */
4195                         syntax_error("not a valid identifier in for");
4196                         return 1;
4197                 }
4198                 /* Force FOR to have just one word (variable name) */
4199                 /* NB: basically, this makes hush see "for v in ..."
4200                  * syntax as if it is "for v; in ...". FOR and IN become
4201                  * two pipe structs in parse tree. */
4202                 done_pipe(ctx, PIPE_SEQ);
4203         }
4204 #endif
4205 #if ENABLE_HUSH_CASE
4206         /* Force CASE to have just one word */
4207         if (ctx->ctx_res_w == RES_CASE) {
4208                 done_pipe(ctx, PIPE_SEQ);
4209         }
4210 #endif
4211
4212         o_reset_to_empty_unquoted(&ctx->word);
4213
4214         debug_printf_parse("done_word return 0\n");
4215         return 0;
4216 }
4217
4218
4219 /* Peek ahead in the input to find out if we have a "&n" construct,
4220  * as in "2>&1", that represents duplicating a file descriptor.
4221  * Return:
4222  * REDIRFD_CLOSE if >&- "close fd" construct is seen,
4223  * REDIRFD_SYNTAX_ERR if syntax error,
4224  * REDIRFD_TO_FILE if no & was seen,
4225  * or the number found.
4226  */
4227 #if BB_MMU
4228 #define parse_redir_right_fd(as_string, input) \
4229         parse_redir_right_fd(input)
4230 #endif
4231 static int parse_redir_right_fd(o_string *as_string, struct in_str *input)
4232 {
4233         int ch, d, ok;
4234
4235         ch = i_peek(input);
4236         if (ch != '&')
4237                 return REDIRFD_TO_FILE;
4238
4239         ch = i_getch(input);  /* get the & */
4240         nommu_addchr(as_string, ch);
4241         ch = i_peek(input);
4242         if (ch == '-') {
4243                 ch = i_getch(input);
4244                 nommu_addchr(as_string, ch);
4245                 return REDIRFD_CLOSE;
4246         }
4247         d = 0;
4248         ok = 0;
4249         while (ch != EOF && isdigit(ch)) {
4250                 d = d*10 + (ch-'0');
4251                 ok = 1;
4252                 ch = i_getch(input);
4253                 nommu_addchr(as_string, ch);
4254                 ch = i_peek(input);
4255         }
4256         if (ok) return d;
4257
4258 //TODO: this is the place to catch ">&file" bashism (redirect both fd 1 and 2)
4259
4260         bb_simple_error_msg("ambiguous redirect");
4261         return REDIRFD_SYNTAX_ERR;
4262 }
4263
4264 /* Return code is 0 normal, 1 if a syntax error is detected
4265  */
4266 static int parse_redirect(struct parse_context *ctx,
4267                 int fd,
4268                 redir_type style,
4269                 struct in_str *input)
4270 {
4271         struct command *command = ctx->command;
4272         struct redir_struct *redir;
4273         struct redir_struct **redirp;
4274         int dup_num;
4275
4276         dup_num = REDIRFD_TO_FILE;
4277         if (style != REDIRECT_HEREDOC) {
4278                 /* Check for a '>&1' type redirect */
4279                 dup_num = parse_redir_right_fd(&ctx->as_string, input);
4280                 if (dup_num == REDIRFD_SYNTAX_ERR)
4281                         return 1;
4282         } else {
4283                 int ch = i_peek_and_eat_bkslash_nl(input);
4284                 dup_num = (ch == '-'); /* HEREDOC_SKIPTABS bit is 1 */
4285                 if (dup_num) { /* <<-... */
4286                         ch = i_getch(input);
4287                         nommu_addchr(&ctx->as_string, ch);
4288                         ch = i_peek(input);
4289                 }
4290         }
4291
4292         if (style == REDIRECT_OVERWRITE && dup_num == REDIRFD_TO_FILE) {
4293                 int ch = i_peek_and_eat_bkslash_nl(input);
4294                 if (ch == '|') {
4295                         /* >|FILE redirect ("clobbering" >).
4296                          * Since we do not support "set -o noclobber" yet,
4297                          * >| and > are the same for now. Just eat |.
4298                          */
4299                         ch = i_getch(input);
4300                         nommu_addchr(&ctx->as_string, ch);
4301                 }
4302         }
4303
4304         /* Create a new redir_struct and append it to the linked list */
4305         redirp = &command->redirects;
4306         while ((redir = *redirp) != NULL) {
4307                 redirp = &(redir->next);
4308         }
4309         *redirp = redir = xzalloc(sizeof(*redir));
4310         /* redir->next = NULL; */
4311         /* redir->rd_filename = NULL; */
4312         redir->rd_type = style;
4313         redir->rd_fd = (fd == -1) ? redir_table[style].default_fd : fd;
4314
4315         debug_printf_parse("redirect type %d %s\n", redir->rd_fd,
4316                                 redir_table[style].descrip);
4317
4318         redir->rd_dup = dup_num;
4319         if (style != REDIRECT_HEREDOC && dup_num != REDIRFD_TO_FILE) {
4320                 /* Erik had a check here that the file descriptor in question
4321                  * is legit; I postpone that to "run time"
4322                  * A "-" representation of "close me" shows up as a -3 here */
4323                 debug_printf_parse("duplicating redirect '%d>&%d'\n",
4324                                 redir->rd_fd, redir->rd_dup);
4325         } else {
4326 #if 0           /* Instead we emit error message at run time */
4327                 if (ctx->pending_redirect) {
4328                         /* For example, "cmd > <file" */
4329                         syntax_error("invalid redirect");
4330                 }
4331 #endif
4332                 /* Set ctx->pending_redirect, so we know what to do at the
4333                  * end of the next parsed word. */
4334                 ctx->pending_redirect = redir;
4335         }
4336         return 0;
4337 }
4338
4339 /* If a redirect is immediately preceded by a number, that number is
4340  * supposed to tell which file descriptor to redirect.  This routine
4341  * looks for such preceding numbers.  In an ideal world this routine
4342  * needs to handle all the following classes of redirects...
4343  *     echo 2>foo     # redirects fd  2 to file "foo", nothing passed to echo
4344  *     echo 49>foo    # redirects fd 49 to file "foo", nothing passed to echo
4345  *     echo -2>foo    # redirects fd  1 to file "foo",    "-2" passed to echo
4346  *     echo 49x>foo   # redirects fd  1 to file "foo",   "49x" passed to echo
4347  *
4348  * http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html
4349  * "2.7 Redirection
4350  * ... If n is quoted, the number shall not be recognized as part of
4351  * the redirection expression. For example:
4352  * echo \2>a
4353  * writes the character 2 into file a"
4354  * We are getting it right by setting ->has_quoted_part on any \<char>
4355  *
4356  * A -1 return means no valid number was found,
4357  * the caller should use the appropriate default for this redirection.
4358  */
4359 static int redirect_opt_num(o_string *o)
4360 {
4361         int num;
4362
4363         if (o->data == NULL)
4364                 return -1;
4365         num = bb_strtou(o->data, NULL, 10);
4366         if (errno || num < 0)
4367                 return -1;
4368         o_reset_to_empty_unquoted(o);
4369         return num;
4370 }
4371
4372 #if BB_MMU
4373 #define fetch_till_str(as_string, input, word, skip_tabs) \
4374         fetch_till_str(input, word, skip_tabs)
4375 #endif
4376 static char *fetch_till_str(o_string *as_string,
4377                 struct in_str *input,
4378                 const char *word,
4379                 int heredoc_flags)
4380 {
4381         o_string heredoc = NULL_O_STRING;
4382         unsigned past_EOL;
4383         int prev = 0; /* not \ */
4384         int ch;
4385
4386         /* Starting with "" is necessary for this case:
4387          * cat <<EOF
4388          *
4389          * xxx
4390          * EOF
4391          */
4392         heredoc.data = xzalloc(1); /* start as "", not as NULL */
4393
4394         goto jump_in;
4395
4396         while (1) {
4397                 ch = i_getch(input);
4398                 if (ch != EOF)
4399                         nommu_addchr(as_string, ch);
4400                 if (ch == '\n' || ch == EOF) {
4401  check_heredoc_end:
4402                         if ((heredoc_flags & HEREDOC_QUOTED) || prev != '\\') {
4403                                 /* End-of-line, and not a line continuation */
4404                                 if (strcmp(heredoc.data + past_EOL, word) == 0) {
4405                                         heredoc.data[past_EOL] = '\0';
4406                                         debug_printf_heredoc("parsed '%s' heredoc '%s'\n", word, heredoc.data);
4407                                         return heredoc.data;
4408                                 }
4409                                 if (ch == '\n') {
4410                                         /* This is a new line.
4411                                          * Remember position and backslash-escaping status.
4412                                          */
4413                                         o_addchr(&heredoc, ch);
4414                                         prev = ch;
4415  jump_in:
4416                                         past_EOL = heredoc.length;
4417                                         /* Get 1st char of next line, possibly skipping leading tabs */
4418                                         do {
4419                                                 ch = i_getch(input);
4420                                                 if (ch != EOF)
4421                                                         nommu_addchr(as_string, ch);
4422                                         } while ((heredoc_flags & HEREDOC_SKIPTABS) && ch == '\t');
4423                                         /* If this immediately ended the line,
4424                                          * go back to end-of-line checks.
4425                                          */
4426                                         if (ch == '\n')
4427                                                 goto check_heredoc_end;
4428                                 }
4429                         } else {
4430                                 /* Backslash-line continuation in an unquoted
4431                                  * heredoc. This does not need special handling
4432                                  * for heredoc body (unquoted heredocs are
4433                                  * expanded on "execution" and that would take
4434                                  * care of this case too), but not the case
4435                                  * of line continuation *in terminator*:
4436                                  *  cat <<EOF
4437                                  *  Ok1
4438                                  *  EO\
4439                                  *  F
4440                                  */
4441                                 heredoc.data[--heredoc.length] = '\0';
4442                                 prev = 0; /* not '\' */
4443                                 continue;
4444                         }
4445                 }
4446                 if (ch == EOF) {
4447                         o_free(&heredoc);
4448                         return NULL; /* error */
4449                 }
4450                 o_addchr(&heredoc, ch);
4451                 nommu_addchr(as_string, ch);
4452                 if (prev == '\\' && ch == '\\')
4453                         /* Correctly handle foo\\<eol> (not a line cont.) */
4454                         prev = 0; /* not '\' */
4455                 else
4456                         prev = ch;
4457         }
4458 }
4459
4460 /* Look at entire parse tree for not-yet-loaded REDIRECT_HEREDOCs
4461  * and load them all. There should be exactly heredoc_cnt of them.
4462  */
4463 #if BB_MMU
4464 #define fetch_heredocs(as_string, pi, heredoc_cnt, input) \
4465         fetch_heredocs(pi, heredoc_cnt, input)
4466 #endif
4467 static int fetch_heredocs(o_string *as_string, struct pipe *pi, int heredoc_cnt, struct in_str *input)
4468 {
4469         while (pi && heredoc_cnt) {
4470                 int i;
4471                 struct command *cmd = pi->cmds;
4472
4473                 debug_printf_heredoc("fetch_heredocs: num_cmds:%d cmd argv0:'%s'\n",
4474                                 pi->num_cmds,
4475                                 cmd->argv ? cmd->argv[0] : "NONE"
4476                 );
4477                 for (i = 0; i < pi->num_cmds; i++) {
4478                         struct redir_struct *redir = cmd->redirects;
4479
4480                         debug_printf_heredoc("fetch_heredocs: %d cmd argv0:'%s'\n",
4481                                         i, cmd->argv ? cmd->argv[0] : "NONE");
4482                         while (redir) {
4483                                 if (redir->rd_type == REDIRECT_HEREDOC) {
4484                                         char *p;
4485
4486                                         redir->rd_type = REDIRECT_HEREDOC2;
4487                                         /* redir->rd_dup is (ab)used to indicate <<- */
4488                                         p = fetch_till_str(as_string, input,
4489                                                         redir->rd_filename, redir->rd_dup);
4490                                         if (!p) {
4491                                                 syntax_error("unexpected EOF in here document");
4492                                                 return -1;
4493                                         }
4494                                         free(redir->rd_filename);
4495                                         redir->rd_filename = p;
4496                                         heredoc_cnt--;
4497                                 }
4498                                 redir = redir->next;
4499                         }
4500                         if (cmd->group) {
4501                                 //bb_error_msg("%s:%u heredoc_cnt:%d", __func__, __LINE__, heredoc_cnt);
4502                                 heredoc_cnt = fetch_heredocs(as_string, cmd->group, heredoc_cnt, input);
4503                                 //bb_error_msg("%s:%u heredoc_cnt:%d", __func__, __LINE__, heredoc_cnt);
4504                                 if (heredoc_cnt < 0)
4505                                         return heredoc_cnt; /* error */
4506                         }
4507                         cmd++;
4508                 }
4509                 pi = pi->next;
4510         }
4511         return heredoc_cnt;
4512 }
4513
4514
4515 static int run_list(struct pipe *pi);
4516 #if BB_MMU
4517 #define parse_stream(pstring, heredoc_cnt_ptr, input, end_trigger) \
4518         parse_stream(heredoc_cnt_ptr, input, end_trigger)
4519 #endif
4520 static struct pipe *parse_stream(char **pstring,
4521                 int *heredoc_cnt_ptr,
4522                 struct in_str *input,
4523                 int end_trigger);
4524
4525 /* Returns number of heredocs not yet consumed,
4526  * or -1 on error.
4527  */
4528 static int parse_group(struct parse_context *ctx,
4529                 struct in_str *input, int ch)
4530 {
4531         /* ctx->word contains characters seen prior to ( or {.
4532          * Typically it's empty, but for function defs,
4533          * it contains function name (without '()'). */
4534 #if BB_MMU
4535 # define as_string NULL
4536 #else
4537         char *as_string = NULL;
4538 #endif
4539         struct pipe *pipe_list;
4540         int heredoc_cnt = 0;
4541         int endch;
4542         struct command *command = ctx->command;
4543
4544         debug_printf_parse("parse_group entered\n");
4545 #if ENABLE_HUSH_FUNCTIONS
4546         if (ch == '(' && !ctx->word.has_quoted_part) {
4547                 if (ctx->word.length)
4548                         if (done_word(ctx))
4549                                 return -1;
4550                 if (!command->argv)
4551                         goto skip; /* (... */
4552                 if (command->argv[1]) { /* word word ... (... */
4553                         syntax_error_unexpected_ch('(');
4554                         return -1;
4555                 }
4556                 /* it is "word(..." or "word (..." */
4557                 do
4558                         ch = i_getch(input);
4559                 while (ch == ' ' || ch == '\t');
4560                 if (ch != ')') {
4561                         syntax_error_unexpected_ch(ch);
4562                         return -1;
4563                 }
4564                 nommu_addchr(&ctx->as_string, ch);
4565                 do
4566                         ch = i_getch(input);
4567                 while (ch == ' ' || ch == '\t' || ch == '\n');
4568                 if (ch != '{' && ch != '(') {
4569                         syntax_error_unexpected_ch(ch);
4570                         return -1;
4571                 }
4572                 nommu_addchr(&ctx->as_string, ch);
4573                 command->cmd_type = CMD_FUNCDEF;
4574                 goto skip;
4575         }
4576 #endif
4577
4578 #if 0 /* Prevented by caller */
4579         if (command->argv /* word [word]{... */
4580          || ctx->word.length /* word{... */
4581          || ctx->word.has_quoted_part /* ""{... */
4582         ) {
4583                 syntax_error(NULL);
4584                 debug_printf_parse("parse_group return -1: "
4585                         "syntax error, groups and arglists don't mix\n");
4586                 return -1;
4587         }
4588 #endif
4589
4590  IF_HUSH_FUNCTIONS(skip:)
4591
4592         endch = '}';
4593         if (ch == '(') {
4594                 endch = ')';
4595                 IF_HUSH_FUNCTIONS(if (command->cmd_type != CMD_FUNCDEF))
4596                         command->cmd_type = CMD_SUBSHELL;
4597         } else {
4598                 /* bash does not allow "{echo...", requires whitespace */
4599                 ch = i_peek(input);
4600                 if (ch != ' ' && ch != '\t' && ch != '\n'
4601                  && ch != '('   /* but "{(..." is allowed (without whitespace) */
4602                 ) {
4603                         syntax_error_unexpected_ch(ch);
4604                         return -1;
4605                 }
4606                 if (ch != '(') {
4607                         ch = i_getch(input);
4608                         nommu_addchr(&ctx->as_string, ch);
4609                 }
4610         }
4611
4612         debug_printf_heredoc("calling parse_stream, heredoc_cnt:%d\n", heredoc_cnt);
4613         pipe_list = parse_stream(&as_string, &heredoc_cnt, input, endch);
4614         debug_printf_heredoc("parse_stream returned: heredoc_cnt:%d\n", heredoc_cnt);
4615 #if !BB_MMU
4616         if (as_string)
4617                 o_addstr(&ctx->as_string, as_string);
4618 #endif
4619
4620         /* empty ()/{} or parse error? */
4621         if (!pipe_list || pipe_list == ERR_PTR) {
4622                 /* parse_stream already emitted error msg */
4623                 if (!BB_MMU)
4624                         free(as_string);
4625                 debug_printf_parse("parse_group return -1: "
4626                         "parse_stream returned %p\n", pipe_list);
4627                 return -1;
4628         }
4629 #if !BB_MMU
4630         as_string[strlen(as_string) - 1] = '\0'; /* plink ')' or '}' */
4631         command->group_as_string = as_string;
4632         debug_printf_parse("end of group, remembering as:'%s'\n",
4633                         command->group_as_string);
4634 #endif
4635
4636 #if ENABLE_HUSH_FUNCTIONS
4637         /* Convert "f() (cmds)" to "f() {(cmds)}" */
4638         if (command->cmd_type == CMD_FUNCDEF && endch == ')') {
4639                 struct command *cmd2;
4640
4641                 cmd2 = xzalloc(sizeof(*cmd2));
4642                 cmd2->cmd_type = CMD_SUBSHELL;
4643                 cmd2->group = pipe_list;
4644 # if !BB_MMU
4645 //UNTESTED!
4646                 cmd2->group_as_string = command->group_as_string;
4647                 command->group_as_string = xasprintf("(%s)", command->group_as_string);
4648 # endif
4649
4650                 pipe_list = new_pipe();
4651                 pipe_list->cmds = cmd2;
4652                 pipe_list->num_cmds = 1;
4653         }
4654 #endif
4655
4656         command->group = pipe_list;
4657
4658         debug_printf_parse("parse_group return %d\n", heredoc_cnt);
4659         return heredoc_cnt;
4660         /* command remains "open", available for possible redirects */
4661 #undef as_string
4662 }
4663
4664 #if ENABLE_HUSH_TICK || ENABLE_FEATURE_SH_MATH || ENABLE_HUSH_DOLLAR_OPS
4665 /* Subroutines for copying $(...) and `...` things */
4666 /* '...' */
4667 static int add_till_single_quote(o_string *dest, struct in_str *input)
4668 {
4669         while (1) {
4670                 int ch = i_getch(input);
4671                 if (ch == EOF) {
4672                         syntax_error_unterm_ch('\'');
4673                         return 0;
4674                 }
4675                 if (ch == '\'')
4676                         return 1;
4677                 o_addchr(dest, ch);
4678         }
4679 }
4680 static int add_till_single_quote_dquoted(o_string *dest, struct in_str *input)
4681 {
4682         while (1) {
4683                 int ch = i_getch(input);
4684                 if (ch == EOF) {
4685                         syntax_error_unterm_ch('\'');
4686                         return 0;
4687                 }
4688                 if (ch == '\'')
4689                         return 1;
4690                 o_addqchr(dest, ch);
4691         }
4692 }
4693 /* "...\"...`..`...." - do we need to handle "...$(..)..." too? */
4694 static int add_till_backquote(o_string *dest, struct in_str *input, int in_dquote);
4695 static int add_till_double_quote(o_string *dest, struct in_str *input)
4696 {
4697         while (1) {
4698                 int ch = i_getch(input);
4699                 if (ch == EOF) {
4700                         syntax_error_unterm_ch('"');
4701                         return 0;
4702                 }
4703                 if (ch == '"')
4704                         return 1;
4705                 if (ch == '\\') {  /* \x. Copy both chars. */
4706                         o_addchr(dest, ch);
4707                         ch = i_getch(input);
4708                 }
4709                 o_addchr(dest, ch);
4710                 if (ch == '`') {
4711                         if (!add_till_backquote(dest, input, /*in_dquote:*/ 1))
4712                                 return 0;
4713                         o_addchr(dest, ch);
4714                         continue;
4715                 }
4716                 //if (ch == '$') ...
4717         }
4718 }
4719 /* Process `cmd` - copy contents until "`" is seen. Complicated by
4720  * \` quoting.
4721  * "Within the backquoted style of command substitution, backslash
4722  * shall retain its literal meaning, except when followed by: '$', '`', or '\'.
4723  * The search for the matching backquote shall be satisfied by the first
4724  * backquote found without a preceding backslash; during this search,
4725  * if a non-escaped backquote is encountered within a shell comment,
4726  * a here-document, an embedded command substitution of the $(command)
4727  * form, or a quoted string, undefined results occur. A single-quoted
4728  * or double-quoted string that begins, but does not end, within the
4729  * "`...`" sequence produces undefined results."
4730  * Example                               Output
4731  * echo `echo '\'TEST\`echo ZZ\`BEST`    \TESTZZBEST
4732  */
4733 static int add_till_backquote(o_string *dest, struct in_str *input, int in_dquote)
4734 {
4735         while (1) {
4736                 int ch = i_getch(input);
4737                 if (ch == '`')
4738                         return 1;
4739                 if (ch == '\\') {
4740                         /* \x. Copy both unless it is \`, \$, \\ and maybe \" */
4741                         ch = i_getch(input);
4742                         if (ch != '`'
4743                          && ch != '$'
4744                          && ch != '\\'
4745                          && (!in_dquote || ch != '"')
4746                         ) {
4747                                 o_addchr(dest, '\\');
4748                         }
4749                 }
4750                 if (ch == EOF) {
4751                         syntax_error_unterm_ch('`');
4752                         return 0;
4753                 }
4754                 o_addchr(dest, ch);
4755         }
4756 }
4757 /* Process $(cmd) - copy contents until ")" is seen. Complicated by
4758  * quoting and nested ()s.
4759  * "With the $(command) style of command substitution, all characters
4760  * following the open parenthesis to the matching closing parenthesis
4761  * constitute the command. Any valid shell script can be used for command,
4762  * except a script consisting solely of redirections which produces
4763  * unspecified results."
4764  * Example                              Output
4765  * echo $(echo '(TEST)' BEST)           (TEST) BEST
4766  * echo $(echo 'TEST)' BEST)            TEST) BEST
4767  * echo $(echo \(\(TEST\) BEST)         ((TEST) BEST
4768  *
4769  * Also adapted to eat ${var%...} and $((...)) constructs, since ... part
4770  * can contain arbitrary constructs, just like $(cmd).
4771  * In bash compat mode, it needs to also be able to stop on ':' or '/'
4772  * for ${var:N[:M]} and ${var/P[/R]} parsing.
4773  */
4774 #define DOUBLE_CLOSE_CHAR_FLAG 0x80
4775 static int add_till_closing_bracket(o_string *dest, struct in_str *input, unsigned end_ch)
4776 {
4777         int ch;
4778         char dbl = end_ch & DOUBLE_CLOSE_CHAR_FLAG;
4779 # if BASH_SUBSTR || BASH_PATTERN_SUBST
4780         char end_char2 = end_ch >> 8;
4781 # endif
4782         end_ch &= (DOUBLE_CLOSE_CHAR_FLAG - 1);
4783
4784 # if ENABLE_HUSH_INTERACTIVE
4785         G.promptmode = 1; /* PS2 */
4786 # endif
4787         debug_printf_prompt("%s promptmode=%d\n", __func__, G.promptmode);
4788
4789         while (1) {
4790                 ch = i_getch(input);
4791                 if (ch == EOF) {
4792                         syntax_error_unterm_ch(end_ch);
4793                         return 0;
4794                 }
4795                 if (ch == end_ch
4796 # if BASH_SUBSTR || BASH_PATTERN_SUBST
4797                  || ch == end_char2
4798 # endif
4799                 ) {
4800                         if (!dbl)
4801                                 break;
4802                         /* we look for closing )) of $((EXPR)) */
4803                         if (i_peek_and_eat_bkslash_nl(input) == end_ch) {
4804                                 i_getch(input); /* eat second ')' */
4805                                 break;
4806                         }
4807                 }
4808                 o_addchr(dest, ch);
4809                 //bb_error_msg("%s:o_addchr('%c')", __func__, ch);
4810                 if (ch == '(' || ch == '{') {
4811                         ch = (ch == '(' ? ')' : '}');
4812                         if (!add_till_closing_bracket(dest, input, ch))
4813                                 return 0;
4814                         o_addchr(dest, ch);
4815                         continue;
4816                 }
4817                 if (ch == '\'') {
4818                         if (!add_till_single_quote(dest, input))
4819                                 return 0;
4820                         o_addchr(dest, ch);
4821                         continue;
4822                 }
4823                 if (ch == '"') {
4824                         if (!add_till_double_quote(dest, input))
4825                                 return 0;
4826                         o_addchr(dest, ch);
4827                         continue;
4828                 }
4829                 if (ch == '`') {
4830                         if (!add_till_backquote(dest, input, /*in_dquote:*/ 0))
4831                                 return 0;
4832                         o_addchr(dest, ch);
4833                         continue;
4834                 }
4835                 if (ch == '\\') {
4836                         /* \x. Copy verbatim. Important for  \(, \) */
4837                         ch = i_getch(input);
4838                         if (ch == EOF) {
4839                                 syntax_error_unterm_ch(end_ch);
4840                                 return 0;
4841                         }
4842 # if 0
4843                         if (ch == '\n') {
4844                                 /* "backslash+newline", ignore both */
4845                                 o_delchr(dest); /* undo insertion of '\' */
4846                                 continue;
4847                         }
4848 # endif
4849                         o_addchr(dest, ch);
4850                         //bb_error_msg("%s:o_addchr('%c') after '\\'", __func__, ch);
4851                         continue;
4852                 }
4853         }
4854         debug_printf_parse("%s return '%s' ch:'%c'\n", __func__, dest->data, ch);
4855         return ch;
4856 }
4857 #endif /* ENABLE_HUSH_TICK || ENABLE_FEATURE_SH_MATH || ENABLE_HUSH_DOLLAR_OPS */
4858
4859 /* Return code: 0 for OK, 1 for syntax error */
4860 #if BB_MMU
4861 #define parse_dollar(as_string, dest, input, quote_mask) \
4862         parse_dollar(dest, input, quote_mask)
4863 #define as_string NULL
4864 #endif
4865 static int parse_dollar(o_string *as_string,
4866                 o_string *dest,
4867                 struct in_str *input, unsigned char quote_mask)
4868 {
4869         int ch = i_peek_and_eat_bkslash_nl(input);  /* first character after the $ */
4870
4871         debug_printf_parse("parse_dollar entered: ch='%c'\n", ch);
4872         if (isalpha(ch)) {
4873  make_var:
4874                 ch = i_getch(input);
4875                 nommu_addchr(as_string, ch);
4876  /*make_var1:*/
4877                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
4878                 while (1) {
4879                         debug_printf_parse(": '%c'\n", ch);
4880                         o_addchr(dest, ch | quote_mask);
4881                         quote_mask = 0;
4882                         ch = i_peek_and_eat_bkslash_nl(input);
4883                         if (!isalnum(ch) && ch != '_') {
4884                                 /* End of variable name reached */
4885                                 break;
4886                         }
4887                         ch = i_getch(input);
4888                         nommu_addchr(as_string, ch);
4889                 }
4890                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
4891         } else if (isdigit(ch)) {
4892  make_one_char_var:
4893                 ch = i_getch(input);
4894                 nommu_addchr(as_string, ch);
4895                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
4896                 debug_printf_parse(": '%c'\n", ch);
4897                 o_addchr(dest, ch | quote_mask);
4898                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
4899         } else switch (ch) {
4900         case '$': /* pid */
4901         case '!': /* last bg pid */
4902         case '?': /* last exit code */
4903         case '#': /* number of args */
4904         case '*': /* args */
4905         case '@': /* args */
4906         case '-': /* $- option flags set by set builtin or shell options (-i etc) */
4907                 goto make_one_char_var;
4908         case '{': {
4909                 char len_single_ch;
4910
4911                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
4912
4913                 ch = i_getch(input); /* eat '{' */
4914                 nommu_addchr(as_string, ch);
4915
4916                 ch = i_getch_and_eat_bkslash_nl(input); /* first char after '{' */
4917                 /* It should be ${?}, or ${#var},
4918                  * or even ${?+subst} - operator acting on a special variable,
4919                  * or the beginning of variable name.
4920                  */
4921                 if (ch == EOF
4922                  || (!strchr(_SPECIAL_VARS_STR, ch) && !isalnum(ch)) /* not one of those */
4923                 ) {
4924  bad_dollar_syntax:
4925                         syntax_error_unterm_str("${name}");
4926                         debug_printf_parse("parse_dollar return 0: unterminated ${name}\n");
4927                         return 0;
4928                 }
4929                 nommu_addchr(as_string, ch);
4930                 len_single_ch = ch;
4931                 ch |= quote_mask;
4932
4933                 /* It's possible to just call add_till_closing_bracket() at this point.
4934                  * However, this regresses some of our testsuite cases
4935                  * which check invalid constructs like ${%}.
4936                  * Oh well... let's check that the var name part is fine... */
4937
4938                 while (1) {
4939                         unsigned pos;
4940
4941                         o_addchr(dest, ch);
4942                         debug_printf_parse(": '%c'\n", ch);
4943
4944                         ch = i_getch(input);
4945                         nommu_addchr(as_string, ch);
4946                         if (ch == '}')
4947                                 break;
4948
4949                         if (!isalnum(ch) && ch != '_') {
4950                                 unsigned end_ch;
4951                                 unsigned char last_ch;
4952                                 /* handle parameter expansions
4953                                  * http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_06_02
4954                                  */
4955                                 if (!strchr(VAR_SUBST_OPS, ch)) { /* ${var<bad_char>... */
4956                                         if (len_single_ch != '#'
4957                                         /*|| !strchr(SPECIAL_VARS_STR, ch) - disallow errors like ${#+} ? */
4958                                          || i_peek(input) != '}'
4959                                         ) {
4960                                                 goto bad_dollar_syntax;
4961                                         }
4962                                         /* else: it's "length of C" ${#C} op,
4963                                          * where C is a single char
4964                                          * special var name, e.g. ${#!}.
4965                                          */
4966                                 }
4967                                 /* Eat everything until closing '}' (or ':') */
4968                                 end_ch = '}';
4969                                 if (BASH_SUBSTR
4970                                  && ch == ':'
4971                                  && !strchr(MINUS_PLUS_EQUAL_QUESTION, i_peek(input))
4972                                 ) {
4973                                         /* It's ${var:N[:M]} thing */
4974                                         end_ch = '}' * 0x100 + ':';
4975                                 }
4976                                 if (BASH_PATTERN_SUBST
4977                                  && ch == '/'
4978                                 ) {
4979                                         /* It's ${var/[/]pattern[/repl]} thing */
4980                                         if (i_peek(input) == '/') { /* ${var//pattern[/repl]}? */
4981                                                 i_getch(input);
4982                                                 nommu_addchr(as_string, '/');
4983                                                 ch = '\\';
4984                                         }
4985                                         end_ch = '}' * 0x100 + '/';
4986                                 }
4987                                 o_addchr(dest, ch);
4988                                 /* The pattern can't be empty.
4989                                  * IOW: if the first char after "${v//" is a slash,
4990                                  * it does not terminate the pattern - it's the first char of the pattern:
4991                                  *  v=/dev/ram; echo ${v////-}  prints -dev-ram (pattern is "/")
4992                                  *  v=/dev/ram; echo ${v///r/-} prints /dev-am  (pattern is "/r")
4993                                  */
4994                                 if (i_peek(input) == '/') {
4995                                         o_addchr(dest, i_getch(input));
4996                                 }
4997  again:
4998                                 if (!BB_MMU)
4999                                         pos = dest->length;
5000 #if ENABLE_HUSH_DOLLAR_OPS
5001                                 last_ch = add_till_closing_bracket(dest, input, end_ch);
5002                                 if (last_ch == 0) /* error? */
5003                                         return 0;
5004 #else
5005 # error Simple code to only allow ${var} is not implemented
5006 #endif
5007                                 if (as_string) {
5008                                         o_addstr(as_string, dest->data + pos);
5009                                         o_addchr(as_string, last_ch);
5010                                 }
5011
5012                                 if ((BASH_SUBSTR || BASH_PATTERN_SUBST)
5013                                          && (end_ch & 0xff00)
5014                                 ) {
5015                                         /* close the first block: */
5016                                         o_addchr(dest, SPECIAL_VAR_SYMBOL);
5017                                         /* while parsing N from ${var:N[:M]}
5018                                          * or pattern from ${var/[/]pattern[/repl]} */
5019                                         if ((end_ch & 0xff) == last_ch) {
5020                                                 /* got ':' or '/'- parse the rest */
5021                                                 end_ch = '}';
5022                                                 goto again;
5023                                         }
5024                                         /* got '}' */
5025                                         if (BASH_SUBSTR && end_ch == '}' * 0x100 + ':') {
5026                                                 /* it's ${var:N} - emulate :999999999 */
5027                                                 o_addstr(dest, "999999999");
5028                                         } /* else: it's ${var/[/]pattern} */
5029                                 }
5030                                 break;
5031                         }
5032                         len_single_ch = 0; /* it can't be ${#C} op */
5033                 }
5034                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
5035                 break;
5036         }
5037 #if ENABLE_FEATURE_SH_MATH || ENABLE_HUSH_TICK
5038         case '(': {
5039                 unsigned pos;
5040
5041                 ch = i_getch(input);
5042                 nommu_addchr(as_string, ch);
5043 # if ENABLE_FEATURE_SH_MATH
5044                 if (i_peek_and_eat_bkslash_nl(input) == '(') {
5045                         ch = i_getch(input);
5046                         nommu_addchr(as_string, ch);
5047                         o_addchr(dest, SPECIAL_VAR_SYMBOL);
5048                         o_addchr(dest, /*quote_mask |*/ '+');
5049                         if (!BB_MMU)
5050                                 pos = dest->length;
5051                         if (!add_till_closing_bracket(dest, input, ')' | DOUBLE_CLOSE_CHAR_FLAG))
5052                                 return 0; /* error */
5053                         if (as_string) {
5054                                 o_addstr(as_string, dest->data + pos);
5055                                 o_addchr(as_string, ')');
5056                                 o_addchr(as_string, ')');
5057                         }
5058                         o_addchr(dest, SPECIAL_VAR_SYMBOL);
5059                         break;
5060                 }
5061 # endif
5062 # if ENABLE_HUSH_TICK
5063                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
5064                 o_addchr(dest, quote_mask | '`');
5065                 if (!BB_MMU)
5066                         pos = dest->length;
5067                 if (!add_till_closing_bracket(dest, input, ')'))
5068                         return 0; /* error */
5069                 if (as_string) {
5070                         o_addstr(as_string, dest->data + pos);
5071                         o_addchr(as_string, ')');
5072                 }
5073                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
5074 # endif
5075                 break;
5076         }
5077 #endif
5078         case '_':
5079                 goto make_var;
5080 #if 0
5081         /* TODO: $_: */
5082         /* $_ Shell or shell script name; or last argument of last command
5083          * (if last command wasn't a pipe; if it was, bash sets $_ to "");
5084          * but in command's env, set to full pathname used to invoke it */
5085                 ch = i_getch(input);
5086                 nommu_addchr(as_string, ch);
5087                 ch = i_peek_and_eat_bkslash_nl(input);
5088                 if (isalnum(ch)) { /* it's $_name or $_123 */
5089                         ch = '_';
5090                         goto make_var1;
5091                 }
5092                 /* else: it's $_ */
5093 #endif
5094         default:
5095                 o_addQchr(dest, '$');
5096         }
5097         debug_printf_parse("parse_dollar return 1 (ok)\n");
5098         return 1;
5099 #undef as_string
5100 }
5101
5102 #if BB_MMU
5103 #define encode_string(as_string, dest, input, dquote_end) \
5104         encode_string(dest, input, dquote_end)
5105 #define as_string NULL
5106 #endif
5107 static int encode_string(o_string *as_string,
5108                 o_string *dest,
5109                 struct in_str *input,
5110                 int dquote_end)
5111 {
5112         int ch;
5113         int next;
5114
5115  again:
5116         ch = i_getch(input);
5117         if (ch != EOF)
5118                 nommu_addchr(as_string, ch);
5119         if (ch == dquote_end) { /* may be only '"' or EOF */
5120                 debug_printf_parse("encode_string return 1 (ok)\n");
5121                 return 1;
5122         }
5123         /* note: can't move it above ch == dquote_end check! */
5124         if (ch == EOF) {
5125                 syntax_error_unterm_ch('"');
5126                 return 0; /* error */
5127         }
5128         next = '\0';
5129         if (ch != '\n') {
5130                 next = i_peek(input);
5131         }
5132         debug_printf_parse("\" ch=%c (%d) escape=%d\n",
5133                         ch, ch, !!(dest->o_expflags & EXP_FLAG_ESC_GLOB_CHARS));
5134         if (ch == '\\') {
5135                 if (next == EOF) {
5136                         /* Testcase: in interactive shell a file with
5137                          *  echo "unterminated string\<eof>
5138                          * is sourced.
5139                          */
5140                         syntax_error_unterm_ch('"');
5141                         return 0; /* error */
5142                 }
5143                 /* bash:
5144                  * "The backslash retains its special meaning [in "..."]
5145                  * only when followed by one of the following characters:
5146                  * $, `, ", \, or <newline>.  A double quote may be quoted
5147                  * within double quotes by preceding it with a backslash."
5148                  * NB: in (unquoted) heredoc, above does not apply to ",
5149                  * therefore we check for it by "next == dquote_end" cond.
5150                  */
5151                 if (next == dquote_end || strchr("$`\\\n", next)) {
5152                         ch = i_getch(input); /* eat next */
5153                         if (ch == '\n')
5154                                 goto again; /* skip \<newline> */
5155                 } /* else: ch remains == '\\', and we double it below: */
5156                 o_addqchr(dest, ch); /* \c if c is a glob char, else just c */
5157                 nommu_addchr(as_string, ch);
5158                 goto again;
5159         }
5160         if (ch == '$') {
5161                 if (!parse_dollar(as_string, dest, input, /*quote_mask:*/ 0x80)) {
5162                         debug_printf_parse("encode_string return 0: "
5163                                         "parse_dollar returned 0 (error)\n");
5164                         return 0;
5165                 }
5166                 goto again;
5167         }
5168 #if ENABLE_HUSH_TICK
5169         if (ch == '`') {
5170                 //unsigned pos = dest->length;
5171                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
5172                 o_addchr(dest, 0x80 | '`');
5173                 if (!add_till_backquote(dest, input, /*in_dquote:*/ dquote_end == '"'))
5174                         return 0; /* error */
5175                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
5176                 //debug_printf_subst("SUBST RES3 '%s'\n", dest->data + pos);
5177                 goto again;
5178         }
5179 #endif
5180         o_addQchr(dest, ch);
5181         goto again;
5182 #undef as_string
5183 }
5184
5185 /*
5186  * Scan input until EOF or end_trigger char.
5187  * Return a list of pipes to execute, or NULL on EOF
5188  * or if end_trigger character is met.
5189  * On syntax error, exit if shell is not interactive,
5190  * reset parsing machinery and start parsing anew,
5191  * or return ERR_PTR.
5192  */
5193 static struct pipe *parse_stream(char **pstring,
5194                 int *heredoc_cnt_ptr,
5195                 struct in_str *input,
5196                 int end_trigger)
5197 {
5198         struct parse_context ctx;
5199         int heredoc_cnt;
5200
5201         /* Single-quote triggers a bypass of the main loop until its mate is
5202          * found.  When recursing, quote state is passed in via ctx.word.o_expflags.
5203          */
5204         debug_printf_parse("parse_stream entered, end_trigger='%c'\n",
5205                         end_trigger ? end_trigger : 'X');
5206         debug_enter();
5207
5208         initialize_context(&ctx);
5209
5210         /* If very first arg is "" or '', ctx.word.data may end up NULL.
5211          * Preventing this:
5212          */
5213         ctx.word.data = xzalloc(1); /* start as "", not as NULL */
5214
5215         /* We used to separate words on $IFS here. This was wrong.
5216          * $IFS is used only for word splitting when $var is expanded,
5217          * here we should use blank chars as separators, not $IFS
5218          */
5219
5220         heredoc_cnt = 0;
5221         while (1) {
5222                 const char *is_blank;
5223                 const char *is_special;
5224                 int ch;
5225                 int next;
5226                 int redir_fd;
5227                 redir_type redir_style;
5228
5229                 ch = i_getch(input);
5230                 debug_printf_parse(": ch=%c (%d) escape=%d\n",
5231                                 ch, ch, !!(ctx.word.o_expflags & EXP_FLAG_ESC_GLOB_CHARS));
5232                 if (ch == EOF) {
5233                         struct pipe *pi;
5234
5235                         if (heredoc_cnt) {
5236                                 syntax_error_unterm_str("here document");
5237                                 goto parse_error;
5238                         }
5239                         if (end_trigger == ')') {
5240                                 syntax_error_unterm_ch('(');
5241                                 goto parse_error;
5242                         }
5243                         if (end_trigger == '}') {
5244                                 syntax_error_unterm_ch('{');
5245                                 goto parse_error;
5246                         }
5247
5248                         if (done_word(&ctx)) {
5249                                 goto parse_error;
5250                         }
5251                         o_free_and_set_NULL(&ctx.word);
5252                         done_pipe(&ctx, PIPE_SEQ);
5253                         pi = ctx.list_head;
5254                         /* If we got nothing... */
5255                         /* (this makes bare "&" cmd a no-op.
5256                          * bash says: "syntax error near unexpected token '&'") */
5257                         if (pi->num_cmds == 0
5258                         IF_HAS_KEYWORDS(&& pi->res_word == RES_NONE)
5259                         ) {
5260                                 free_pipe_list(pi);
5261                                 pi = NULL;
5262                         }
5263 #if !BB_MMU
5264                         debug_printf_parse("as_string1 '%s'\n", ctx.as_string.data);
5265                         if (pstring)
5266                                 *pstring = ctx.as_string.data;
5267                         else
5268                                 o_free(&ctx.as_string);
5269 #endif
5270                         // heredoc_cnt must be 0 here anyway
5271                         //if (heredoc_cnt_ptr)
5272                         //      *heredoc_cnt_ptr = heredoc_cnt;
5273                         debug_leave();
5274                         debug_printf_heredoc("parse_stream return heredoc_cnt:%d\n", heredoc_cnt);
5275                         debug_printf_parse("parse_stream return %p\n", pi);
5276                         return pi;
5277                 }
5278
5279                 /* Handle "'" and "\" first, as they won't play nice with
5280                  * i_peek_and_eat_bkslash_nl() anyway:
5281                  *   echo z\\
5282                  * and
5283                  *   echo '\
5284                  *   '
5285                  * would break.
5286                  */
5287                 if (ch == '\\') {
5288                         ch = i_getch(input);
5289                         if (ch == '\n')
5290                                 continue; /* drop \<newline>, get next char */
5291                         nommu_addchr(&ctx.as_string, '\\');
5292                         o_addchr(&ctx.word, '\\');
5293                         if (ch == EOF) {
5294                                 /* Testcase: eval 'echo Ok\' */
5295                                 /* bash-4.3.43 was removing backslash,
5296                                  * but 4.4.19 retains it, most other shells too
5297                                  */
5298                                 continue; /* get next char */
5299                         }
5300                         /* Example: echo Hello \2>file
5301                          * we need to know that word 2 is quoted
5302                          */
5303                         ctx.word.has_quoted_part = 1;
5304                         nommu_addchr(&ctx.as_string, ch);
5305                         o_addchr(&ctx.word, ch);
5306                         continue; /* get next char */
5307                 }
5308                 nommu_addchr(&ctx.as_string, ch);
5309                 if (ch == '\'') {
5310                         ctx.word.has_quoted_part = 1;
5311                         next = i_getch(input);
5312                         if (next == '\'' && !ctx.pending_redirect)
5313                                 goto insert_empty_quoted_str_marker;
5314
5315                         ch = next;
5316                         while (1) {
5317                                 if (ch == EOF) {
5318                                         syntax_error_unterm_ch('\'');
5319                                         goto parse_error;
5320                                 }
5321                                 nommu_addchr(&ctx.as_string, ch);
5322                                 if (ch == '\'')
5323                                         break;
5324                                 if (ch == SPECIAL_VAR_SYMBOL) {
5325                                         /* Convert raw ^C to corresponding special variable reference */
5326                                         o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
5327                                         o_addchr(&ctx.word, SPECIAL_VAR_QUOTED_SVS);
5328                                 }
5329                                 o_addqchr(&ctx.word, ch);
5330                                 ch = i_getch(input);
5331                         }
5332                         continue; /* get next char */
5333                 }
5334
5335                 next = '\0';
5336                 if (ch != '\n')
5337                         next = i_peek_and_eat_bkslash_nl(input);
5338
5339                 is_special = "{}<>;&|()#" /* special outside of "str" */
5340                                 "$\"" IF_HUSH_TICK("`") /* always special */
5341                                 SPECIAL_VAR_SYMBOL_STR;
5342                 /* Are { and } special here? */
5343                 if (ctx.command->argv /* word [word]{... - non-special */
5344                  || ctx.word.length       /* word{... - non-special */
5345                  || ctx.word.has_quoted_part     /* ""{... - non-special */
5346                  || (next != ';'             /* }; - special */
5347                     && next != ')'           /* }) - special */
5348                     && next != '('           /* {( - special */
5349                     && next != '&'           /* }& and }&& ... - special */
5350                     && next != '|'           /* }|| ... - special */
5351                     && !strchr(defifs, next) /* {word - non-special */
5352                     )
5353                 ) {
5354                         /* They are not special, skip "{}" */
5355                         is_special += 2;
5356                 }
5357                 is_special = strchr(is_special, ch);
5358                 is_blank = strchr(defifs, ch);
5359
5360                 if (!is_special && !is_blank) { /* ordinary char */
5361  ordinary_char:
5362                         o_addQchr(&ctx.word, ch);
5363                         if ((ctx.is_assignment == MAYBE_ASSIGNMENT
5364                             || ctx.is_assignment == WORD_IS_KEYWORD)
5365                          && ch == '='
5366                          && endofname(ctx.word.data)[0] == '='
5367                         ) {
5368                                 ctx.is_assignment = DEFINITELY_ASSIGNMENT;
5369                                 debug_printf_parse("ctx.is_assignment='%s'\n", assignment_flag[ctx.is_assignment]);
5370                         }
5371                         continue;
5372                 }
5373
5374                 if (is_blank) {
5375 #if ENABLE_HUSH_LINENO_VAR
5376 /* Case:
5377  * "while ...; do<whitespace><newline>
5378  *      cmd ..."
5379  * would think that "cmd" starts in <whitespace> -
5380  * i.e., at the previous line.
5381  * We need to skip all whitespace before newlines.
5382  */
5383                         while (ch != '\n') {
5384                                 next = i_peek(input);
5385                                 if (next != ' ' && next != '\t' && next != '\n')
5386                                         break; /* next char is not ws */
5387                                 ch = i_getch(input);
5388                         }
5389                         /* ch == last eaten whitespace char */
5390 #endif
5391                         if (done_word(&ctx)) {
5392                                 goto parse_error;
5393                         }
5394                         if (ch == '\n') {
5395                                 /* Is this a case when newline is simply ignored?
5396                                  * Some examples:
5397                                  * "cmd | <newline> cmd ..."
5398                                  * "case ... in <newline> word) ..."
5399                                  */
5400                                 if (IS_NULL_CMD(ctx.command)
5401                                  && ctx.word.length == 0
5402                                  && !ctx.word.has_quoted_part
5403                                  && heredoc_cnt == 0
5404                                 ) {
5405                                         /* This newline can be ignored. But...
5406                                          * Without check #1, interactive shell
5407                                          * ignores even bare <newline>,
5408                                          * and shows the continuation prompt:
5409                                          * ps1_prompt$ <enter>
5410                                          * ps2> _   <=== wrong, should be ps1
5411                                          * Without check #2, "cmd & <newline>"
5412                                          * is similarly mistreated.
5413                                          * (BTW, this makes "cmd & cmd"
5414                                          * and "cmd && cmd" non-orthogonal.
5415                                          * Really, ask yourself, why
5416                                          * "cmd && <newline>" doesn't start
5417                                          * cmd but waits for more input?
5418                                          * The only reason is that it might be
5419                                          * a "cmd1 && <nl> cmd2 &" construct,
5420                                          * cmd1 may need to run in BG).
5421                                          */
5422                                         struct pipe *pi = ctx.list_head;
5423                                         if (pi->num_cmds != 0       /* check #1 */
5424                                          && pi->followup != PIPE_BG /* check #2 */
5425                                         ) {
5426                                                 continue;
5427                                         }
5428                                 }
5429                                 /* Treat newline as a command separator. */
5430                                 done_pipe(&ctx, PIPE_SEQ);
5431                                 debug_printf_heredoc("heredoc_cnt:%d\n", heredoc_cnt);
5432                                 if (heredoc_cnt) {
5433                                         heredoc_cnt = fetch_heredocs(&ctx.as_string, ctx.list_head, heredoc_cnt, input);
5434                                         if (heredoc_cnt != 0)
5435                                                 goto parse_error;
5436                                 }
5437                                 ctx.is_assignment = MAYBE_ASSIGNMENT;
5438                                 debug_printf_parse("ctx.is_assignment='%s'\n", assignment_flag[ctx.is_assignment]);
5439                                 ch = ';';
5440                                 /* note: if (is_blank) continue;
5441                                  * will still trigger for us */
5442                         }
5443                 }
5444
5445                 /* "cmd}" or "cmd }..." without semicolon or &:
5446                  * } is an ordinary char in this case, even inside { cmd; }
5447                  * Pathological example: { ""}; } should exec "}" cmd
5448                  */
5449                 if (ch == '}') {
5450                         if (ctx.word.length != 0 /* word} */
5451                          || ctx.word.has_quoted_part    /* ""} */
5452                         ) {
5453                                 goto ordinary_char;
5454                         }
5455                         if (!IS_NULL_CMD(ctx.command)) { /* cmd } */
5456                                 /* Generally, there should be semicolon: "cmd; }"
5457                                  * However, bash allows to omit it if "cmd" is
5458                                  * a group. Examples:
5459                                  * { { echo 1; } }
5460                                  * {(echo 1)}
5461                                  * { echo 0 >&2 | { echo 1; } }
5462                                  * { while false; do :; done }
5463                                  * { case a in b) ;; esac }
5464                                  */
5465                                 if (ctx.command->group)
5466                                         goto term_group;
5467                                 goto ordinary_char;
5468                         }
5469                         if (!IS_NULL_PIPE(ctx.pipe)) /* cmd | } */
5470                                 /* Can't be an end of {cmd}, skip the check */
5471                                 goto skip_end_trigger;
5472                         /* else: } does terminate a group */
5473                 }
5474  term_group:
5475                 if (end_trigger && end_trigger == ch
5476                  && (ch != ';' || heredoc_cnt == 0)
5477 #if ENABLE_HUSH_CASE
5478                  && (ch != ')'
5479                     || ctx.ctx_res_w != RES_MATCH
5480                     || (!ctx.word.has_quoted_part && strcmp(ctx.word.data, "esac") == 0)
5481                     )
5482 #endif
5483                 ) {
5484                         if (done_word(&ctx)) {
5485                                 goto parse_error;
5486                         }
5487                         done_pipe(&ctx, PIPE_SEQ);
5488                         ctx.is_assignment = MAYBE_ASSIGNMENT;
5489                         debug_printf_parse("ctx.is_assignment='%s'\n", assignment_flag[ctx.is_assignment]);
5490                         /* Do we sit outside of any if's, loops or case's? */
5491                         if (!HAS_KEYWORDS
5492                         IF_HAS_KEYWORDS(|| (ctx.ctx_res_w == RES_NONE && ctx.old_flag == 0))
5493                         ) {
5494                                 o_free_and_set_NULL(&ctx.word);
5495 #if !BB_MMU
5496                                 debug_printf_parse("as_string2 '%s'\n", ctx.as_string.data);
5497                                 if (pstring)
5498                                         *pstring = ctx.as_string.data;
5499                                 else
5500                                         o_free(&ctx.as_string);
5501 #endif
5502                                 if (ch != ';' && IS_NULL_PIPE(ctx.list_head)) {
5503                                         /* Example: bare "{ }", "()" */
5504                                         G.last_exitcode = 2; /* bash compat */
5505                                         syntax_error_unexpected_ch(ch);
5506                                         goto parse_error2;
5507                                 }
5508                                 if (heredoc_cnt_ptr)
5509                                         *heredoc_cnt_ptr = heredoc_cnt;
5510                                 debug_printf_heredoc("parse_stream return heredoc_cnt:%d\n", heredoc_cnt);
5511                                 debug_printf_parse("parse_stream return %p: "
5512                                                 "end_trigger char found\n",
5513                                                 ctx.list_head);
5514                                 debug_leave();
5515                                 return ctx.list_head;
5516                         }
5517                 }
5518
5519                 if (is_blank)
5520                         continue;
5521
5522                 /* Catch <, > before deciding whether this word is
5523                  * an assignment. a=1 2>z b=2: b=2 is still assignment */
5524                 switch (ch) {
5525                 case '>':
5526                         redir_fd = redirect_opt_num(&ctx.word);
5527                         if (done_word(&ctx)) {
5528                                 goto parse_error;
5529                         }
5530                         redir_style = REDIRECT_OVERWRITE;
5531                         if (next == '>') {
5532                                 redir_style = REDIRECT_APPEND;
5533                                 ch = i_getch(input);
5534                                 nommu_addchr(&ctx.as_string, ch);
5535                         }
5536 #if 0
5537                         else if (next == '(') {
5538                                 syntax_error(">(process) not supported");
5539                                 goto parse_error;
5540                         }
5541 #endif
5542                         if (parse_redirect(&ctx, redir_fd, redir_style, input))
5543                                 goto parse_error;
5544                         continue; /* get next char */
5545                 case '<':
5546                         redir_fd = redirect_opt_num(&ctx.word);
5547                         if (done_word(&ctx)) {
5548                                 goto parse_error;
5549                         }
5550                         redir_style = REDIRECT_INPUT;
5551                         if (next == '<') {
5552                                 redir_style = REDIRECT_HEREDOC;
5553                                 heredoc_cnt++;
5554                                 debug_printf_heredoc("++heredoc_cnt=%d\n", heredoc_cnt);
5555                                 ch = i_getch(input);
5556                                 nommu_addchr(&ctx.as_string, ch);
5557                         } else if (next == '>') {
5558                                 redir_style = REDIRECT_IO;
5559                                 ch = i_getch(input);
5560                                 nommu_addchr(&ctx.as_string, ch);
5561                         }
5562 #if 0
5563                         else if (next == '(') {
5564                                 syntax_error("<(process) not supported");
5565                                 goto parse_error;
5566                         }
5567 #endif
5568                         if (parse_redirect(&ctx, redir_fd, redir_style, input))
5569                                 goto parse_error;
5570                         continue; /* get next char */
5571                 case '#':
5572                         if (ctx.word.length == 0 && !ctx.word.has_quoted_part) {
5573                                 /* skip "#comment" */
5574                                 /* note: we do not add it to &ctx.as_string */
5575 /* TODO: in bash:
5576  * comment inside $() goes to the next \n, even inside quoted string (!):
5577  * cmd "$(cmd2 #comment)" - syntax error
5578  * cmd "`cmd2 #comment`" - ok
5579  * We accept both (comment ends where command subst ends, in both cases).
5580  */
5581                                 while (1) {
5582                                         ch = i_peek(input);
5583                                         if (ch == '\n') {
5584                                                 nommu_addchr(&ctx.as_string, '\n');
5585                                                 break;
5586                                         }
5587                                         ch = i_getch(input);
5588                                         if (ch == EOF)
5589                                                 break;
5590                                 }
5591                                 continue; /* get next char */
5592                         }
5593                         break;
5594                 }
5595  skip_end_trigger:
5596
5597                 if (ctx.is_assignment == MAYBE_ASSIGNMENT
5598                  /* check that we are not in word in "a=1 2>word b=1": */
5599                  && !ctx.pending_redirect
5600                 ) {
5601                         /* ch is a special char and thus this word
5602                          * cannot be an assignment */
5603                         ctx.is_assignment = NOT_ASSIGNMENT;
5604                         debug_printf_parse("ctx.is_assignment='%s'\n", assignment_flag[ctx.is_assignment]);
5605                 }
5606
5607                 /* Note: nommu_addchr(&ctx.as_string, ch) is already done */
5608
5609                 switch (ch) {
5610                 case SPECIAL_VAR_SYMBOL:
5611                         /* Convert raw ^C to corresponding special variable reference */
5612                         o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
5613                         o_addchr(&ctx.word, SPECIAL_VAR_QUOTED_SVS);
5614                         /* fall through */
5615                 case '#':
5616                         /* non-comment #: "echo a#b" etc */
5617                         o_addchr(&ctx.word, ch);
5618                         continue; /* get next char */
5619                 case '$':
5620                         if (!parse_dollar(&ctx.as_string, &ctx.word, input, /*quote_mask:*/ 0)) {
5621                                 debug_printf_parse("parse_stream parse error: "
5622                                         "parse_dollar returned 0 (error)\n");
5623                                 goto parse_error;
5624                         }
5625                         continue; /* get next char */
5626                 case '"':
5627                         ctx.word.has_quoted_part = 1;
5628                         if (next == '"' && !ctx.pending_redirect) {
5629                                 i_getch(input); /* eat second " */
5630  insert_empty_quoted_str_marker:
5631                                 nommu_addchr(&ctx.as_string, next);
5632                                 o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
5633                                 o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
5634                                 continue; /* get next char */
5635                         }
5636                         if (ctx.is_assignment == NOT_ASSIGNMENT)
5637                                 ctx.word.o_expflags |= EXP_FLAG_ESC_GLOB_CHARS;
5638                         if (!encode_string(&ctx.as_string, &ctx.word, input, '"'))
5639                                 goto parse_error;
5640                         ctx.word.o_expflags &= ~EXP_FLAG_ESC_GLOB_CHARS;
5641                         continue; /* get next char */
5642 #if ENABLE_HUSH_TICK
5643                 case '`': {
5644                         USE_FOR_NOMMU(unsigned pos;)
5645
5646                         o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
5647                         o_addchr(&ctx.word, '`');
5648                         USE_FOR_NOMMU(pos = ctx.word.length;)
5649                         if (!add_till_backquote(&ctx.word, input, /*in_dquote:*/ 0))
5650                                 goto parse_error;
5651 # if !BB_MMU
5652                         o_addstr(&ctx.as_string, ctx.word.data + pos);
5653                         o_addchr(&ctx.as_string, '`');
5654 # endif
5655                         o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
5656                         //debug_printf_subst("SUBST RES3 '%s'\n", ctx.word.data + pos);
5657                         continue; /* get next char */
5658                 }
5659 #endif
5660                 case ';':
5661 #if ENABLE_HUSH_CASE
5662  case_semi:
5663 #endif
5664                         if (done_word(&ctx)) {
5665                                 goto parse_error;
5666                         }
5667                         done_pipe(&ctx, PIPE_SEQ);
5668 #if ENABLE_HUSH_CASE
5669                         /* Eat multiple semicolons, detect
5670                          * whether it means something special */
5671                         while (1) {
5672                                 ch = i_peek_and_eat_bkslash_nl(input);
5673                                 if (ch != ';')
5674                                         break;
5675                                 ch = i_getch(input);
5676                                 nommu_addchr(&ctx.as_string, ch);
5677                                 if (ctx.ctx_res_w == RES_CASE_BODY) {
5678                                         ctx.ctx_dsemicolon = 1;
5679                                         ctx.ctx_res_w = RES_MATCH;
5680                                         break;
5681                                 }
5682                         }
5683 #endif
5684  new_cmd:
5685                         /* We just finished a cmd. New one may start
5686                          * with an assignment */
5687                         ctx.is_assignment = MAYBE_ASSIGNMENT;
5688                         debug_printf_parse("ctx.is_assignment='%s'\n", assignment_flag[ctx.is_assignment]);
5689                         continue; /* get next char */
5690                 case '&':
5691                         if (done_word(&ctx)) {
5692                                 goto parse_error;
5693                         }
5694                         if (next == '&') {
5695                                 ch = i_getch(input);
5696                                 nommu_addchr(&ctx.as_string, ch);
5697                                 done_pipe(&ctx, PIPE_AND);
5698                         } else {
5699                                 done_pipe(&ctx, PIPE_BG);
5700                         }
5701                         goto new_cmd;
5702                 case '|':
5703                         if (done_word(&ctx)) {
5704                                 goto parse_error;
5705                         }
5706 #if ENABLE_HUSH_CASE
5707                         if (ctx.ctx_res_w == RES_MATCH)
5708                                 break; /* we are in case's "word | word)" */
5709 #endif
5710                         if (next == '|') { /* || */
5711                                 ch = i_getch(input);
5712                                 nommu_addchr(&ctx.as_string, ch);
5713                                 done_pipe(&ctx, PIPE_OR);
5714                         } else {
5715                                 /* we could pick up a file descriptor choice here
5716                                  * with redirect_opt_num(), but bash doesn't do it.
5717                                  * "echo foo 2| cat" yields "foo 2". */
5718                                 done_command(&ctx);
5719                         }
5720                         goto new_cmd;
5721                 case '(':
5722 #if ENABLE_HUSH_CASE
5723                         /* "case... in [(]word)..." - skip '(' */
5724                         if (ctx.ctx_res_w == RES_MATCH
5725                          && ctx.command->argv == NULL /* not (word|(... */
5726                          && ctx.word.length == 0 /* not word(... */
5727                          && ctx.word.has_quoted_part == 0 /* not ""(... */
5728                         ) {
5729                                 continue; /* get next char */
5730                         }
5731 #endif
5732                         /* fall through */
5733                 case '{': {
5734                         int n = parse_group(&ctx, input, ch);
5735                         if (n < 0) {
5736                                 goto parse_error;
5737                         }
5738                         debug_printf_heredoc("parse_group done, needs heredocs:%d\n", n);
5739                         heredoc_cnt += n;
5740                         goto new_cmd;
5741                 }
5742                 case ')':
5743 #if ENABLE_HUSH_CASE
5744                         if (ctx.ctx_res_w == RES_MATCH)
5745                                 goto case_semi;
5746 #endif
5747
5748                 case '}':
5749                         /* proper use of this character is caught by end_trigger:
5750                          * if we see {, we call parse_group(..., end_trigger='}')
5751                          * and it will match } earlier (not here). */
5752                         G.last_exitcode = 2;
5753                         syntax_error_unexpected_ch(ch);
5754                         goto parse_error2;
5755                 default:
5756                         if (HUSH_DEBUG)
5757                                 bb_error_msg_and_die("BUG: unexpected %c", ch);
5758                 }
5759         } /* while (1) */
5760
5761  parse_error:
5762         G.last_exitcode = 1;
5763  parse_error2:
5764         {
5765                 struct parse_context *pctx;
5766                 IF_HAS_KEYWORDS(struct parse_context *p2;)
5767
5768                 /* Clean up allocated tree.
5769                  * Sample for finding leaks on syntax error recovery path.
5770                  * Run it from interactive shell, watch pmap `pidof hush`.
5771                  * while if false; then false; fi; do break; fi
5772                  * Samples to catch leaks at execution:
5773                  * while if (true | { true;}); then echo ok; fi; do break; done
5774                  * while if (true | { true;}); then echo ok; fi; do (if echo ok; break; then :; fi) | cat; break; done
5775                  */
5776                 pctx = &ctx;
5777                 do {
5778                         /* Update pipe/command counts,
5779                          * otherwise freeing may miss some */
5780                         done_pipe(pctx, PIPE_SEQ);
5781                         debug_printf_clean("freeing list %p from ctx %p\n",
5782                                         pctx->list_head, pctx);
5783                         debug_print_tree(pctx->list_head, 0);
5784                         free_pipe_list(pctx->list_head);
5785                         debug_printf_clean("freed list %p\n", pctx->list_head);
5786 #if !BB_MMU
5787                         o_free(&pctx->as_string);
5788 #endif
5789                         IF_HAS_KEYWORDS(p2 = pctx->stack;)
5790                         if (pctx != &ctx) {
5791                                 free(pctx);
5792                         }
5793                         IF_HAS_KEYWORDS(pctx = p2;)
5794                 } while (HAS_KEYWORDS && pctx);
5795
5796                 o_free(&ctx.word);
5797 #if !BB_MMU
5798                 if (pstring)
5799                         *pstring = NULL;
5800 #endif
5801                 debug_leave();
5802                 return ERR_PTR;
5803         }
5804 }
5805
5806
5807 /*** Execution routines ***/
5808
5809 /* Expansion can recurse, need forward decls: */
5810 #if !BASH_PATTERN_SUBST && !ENABLE_HUSH_CASE
5811 #define expand_string_to_string(str, EXP_flags, do_unbackslash) \
5812         expand_string_to_string(str)
5813 #endif
5814 static char *expand_string_to_string(const char *str, int EXP_flags, int do_unbackslash);
5815 #if ENABLE_HUSH_TICK
5816 static int process_command_subs(o_string *dest, const char *s);
5817 #endif
5818 static int expand_vars_to_list(o_string *output, int n, char *arg);
5819
5820 /* expand_strvec_to_strvec() takes a list of strings, expands
5821  * all variable references within and returns a pointer to
5822  * a list of expanded strings, possibly with larger number
5823  * of strings. (Think VAR="a b"; echo $VAR).
5824  * This new list is allocated as a single malloc block.
5825  * NULL-terminated list of char* pointers is at the beginning of it,
5826  * followed by strings themselves.
5827  * Caller can deallocate entire list by single free(list). */
5828
5829 /* A horde of its helpers come first: */
5830
5831 static void o_addblock_duplicate_backslash(o_string *o, const char *str, int len)
5832 {
5833         while (--len >= 0) {
5834                 char c = *str++;
5835
5836 #if ENABLE_HUSH_BRACE_EXPANSION
5837                 if (c == '{' || c == '}') {
5838                         /* { -> \{, } -> \} */
5839                         o_addchr(o, '\\');
5840                         /* And now we want to add { or } and continue:
5841                          *  o_addchr(o, c);
5842                          *  continue;
5843                          * luckily, just falling through achieves this.
5844                          */
5845                 }
5846 #endif
5847                 o_addchr(o, c);
5848                 if (c == '\\') {
5849                         /* \z -> \\\z; \<eol> -> \\<eol> */
5850                         o_addchr(o, '\\');
5851                         if (len) {
5852                                 len--;
5853                                 o_addchr(o, '\\');
5854                                 o_addchr(o, *str++);
5855                         }
5856                 }
5857         }
5858 }
5859
5860 /* Store given string, finalizing the word and starting new one whenever
5861  * we encounter IFS char(s). This is used for expanding variable values.
5862  * End-of-string does NOT finalize word: think about 'echo -$VAR-'.
5863  * Return in output->ended_in_ifs:
5864  * 1 - ended with IFS char, else 0 (this includes case of empty str).
5865  */
5866 static int expand_on_ifs(o_string *output, int n, const char *str)
5867 {
5868         int last_is_ifs = 0;
5869
5870         while (1) {
5871                 int word_len;
5872
5873                 if (!*str)  /* EOL - do not finalize word */
5874                         break;
5875                 word_len = strcspn(str, G.ifs);
5876                 if (word_len) {
5877                         /* We have WORD_LEN leading non-IFS chars */
5878                         if (!(output->o_expflags & EXP_FLAG_GLOB)) {
5879                                 o_addblock(output, str, word_len);
5880                         } else {
5881                                 /* Protect backslashes against globbing up :)
5882                                  * Example: "v='\*'; echo b$v" prints "b\*"
5883                                  * (and does not try to glob on "*")
5884                                  */
5885                                 o_addblock_duplicate_backslash(output, str, word_len);
5886                                 /*/ Why can't we do it easier? */
5887                                 /*o_addblock(output, str, word_len); - WRONG: "v='\*'; echo Z$v" prints "Z*" instead of "Z\*" */
5888                                 /*o_addqblock(output, str, word_len); - WRONG: "v='*'; echo Z$v" prints "Z*" instead of Z* files */
5889                         }
5890                         last_is_ifs = 0;
5891                         str += word_len;
5892                         if (!*str)  /* EOL - do not finalize word */
5893                                 break;
5894                 }
5895
5896                 /* We know str here points to at least one IFS char */
5897                 last_is_ifs = 1;
5898                 str += strspn(str, G.ifs_whitespace); /* skip IFS whitespace chars */
5899                 if (!*str)  /* EOL - do not finalize word */
5900                         break;
5901
5902                 if (G.ifs_whitespace != G.ifs /* usually false ($IFS is usually all whitespace), */
5903                  && strchr(G.ifs, *str)       /* the second check would fail */
5904                 ) {
5905                         /* This is a non-whitespace $IFS char */
5906                         /* Skip it and IFS whitespace chars, start new word */
5907                         str++;
5908                         str += strspn(str, G.ifs_whitespace);
5909                         goto new_word;
5910                 }
5911
5912                 /* Start new word... but not always! */
5913                 /* Case "v=' a'; echo ''$v": we do need to finalize empty word: */
5914                 if (output->has_quoted_part
5915                 /*
5916                  * Case "v=' a'; echo $v":
5917                  * here nothing precedes the space in $v expansion,
5918                  * therefore we should not finish the word
5919                  * (IOW: if there *is* word to finalize, only then do it):
5920                  * It's okay if this accesses the byte before first argv[]:
5921                  * past call to o_save_ptr() cleared it to zero byte
5922                  * (grep for -prev-ifs-check-).
5923                  */
5924                  || output->data[output->length - 1]
5925                 ) {
5926  new_word:
5927                         o_addchr(output, '\0');
5928                         debug_print_list("expand_on_ifs", output, n);
5929                         n = o_save_ptr(output, n);
5930                 }
5931         }
5932
5933         output->ended_in_ifs = last_is_ifs;
5934         debug_print_list("expand_on_ifs[1]", output, n);
5935         return n;
5936 }
5937
5938 /* Helper to expand $((...)) and heredoc body. These act as if
5939  * they are in double quotes, with the exception that they are not :).
5940  * Just the rules are similar: "expand only $var and `cmd`"
5941  *
5942  * Returns malloced string.
5943  * As an optimization, we return NULL if expansion is not needed.
5944  */
5945 static char *encode_then_expand_string(const char *str)
5946 {
5947         char *exp_str;
5948         struct in_str input;
5949         o_string dest = NULL_O_STRING;
5950         const char *cp;
5951
5952         cp = str;
5953         for (;;) {
5954                 if (!*cp) return NULL; /* string has no special chars */
5955                 if (*cp == '$') break;
5956                 if (*cp == '\\') break;
5957 #if ENABLE_HUSH_TICK
5958                 if (*cp == '`') break;
5959 #endif
5960                 cp++;
5961         }
5962
5963         /* We need to expand. Example:
5964          * echo $(($a + `echo 1`)) $((1 + $((2)) ))
5965          */
5966         setup_string_in_str(&input, str);
5967         encode_string(NULL, &dest, &input, EOF);
5968 //TODO: error check (encode_string returns 0 on error)?
5969         //bb_error_msg("'%s' -> '%s'", str, dest.data);
5970         exp_str = expand_string_to_string(dest.data,
5971                         EXP_FLAG_ESC_GLOB_CHARS,
5972                         /*unbackslash:*/ 1
5973         );
5974         //bb_error_msg("'%s' -> '%s'", dest.data, exp_str);
5975         o_free(&dest);
5976         return exp_str;
5977 }
5978
5979 static const char *first_special_char_in_vararg(const char *cp)
5980 {
5981         for (;;) {
5982                 if (!*cp) return NULL; /* string has no special chars */
5983                 if (*cp == '$') return cp;
5984                 if (*cp == '\\') return cp;
5985                 if (*cp == '\'') return cp;
5986                 if (*cp == '"') return cp;
5987 #if ENABLE_HUSH_TICK
5988                 if (*cp == '`') return cp;
5989 #endif
5990                 /* dquoted "${x:+ARG}" should not glob, therefore
5991                  * '*' et al require some non-literal processing: */
5992                 if (*cp == '*') return cp;
5993                 if (*cp == '?') return cp;
5994                 if (*cp == '[') return cp;
5995                 cp++;
5996         }
5997 }
5998
5999 /* Expanding ARG in ${var#ARG}, ${var%ARG}, or ${var/ARG/ARG}.
6000  * These can contain single- and double-quoted strings,
6001  * and treated as if the ARG string is initially unquoted. IOW:
6002  * ${var#ARG} and "${var#ARG}" treat ARG the same (ARG can even be
6003  * a dquoted string: "${var#"zz"}"), the difference only comes later
6004  * (word splitting and globbing of the ${var...} result).
6005  */
6006 #if !BASH_PATTERN_SUBST
6007 #define encode_then_expand_vararg(str, handle_squotes, do_unbackslash) \
6008         encode_then_expand_vararg(str, handle_squotes)
6009 #endif
6010 static char *encode_then_expand_vararg(const char *str, int handle_squotes, int do_unbackslash)
6011 {
6012 #if !BASH_PATTERN_SUBST && ENABLE_HUSH_CASE
6013         const int do_unbackslash = 0;
6014 #endif
6015         char *exp_str;
6016         struct in_str input;
6017         o_string dest = NULL_O_STRING;
6018
6019         if (!first_special_char_in_vararg(str)) {
6020                 /* string has no special chars */
6021                 return NULL;
6022         }
6023
6024         setup_string_in_str(&input, str);
6025         dest.data = xzalloc(1); /* start as "", not as NULL */
6026         exp_str = NULL;
6027
6028         for (;;) {
6029                 int ch;
6030
6031                 ch = i_getch(&input);
6032                 debug_printf_parse("%s: ch=%c (%d) escape=%d\n",
6033                                 __func__, ch, ch, !!dest.o_expflags);
6034
6035                 if (!dest.o_expflags) {
6036                         if (ch == EOF)
6037                                 break;
6038                         if (handle_squotes && ch == '\'') {
6039                                 if (!add_till_single_quote_dquoted(&dest, &input))
6040                                         goto ret; /* error */
6041                                 continue;
6042                         }
6043                 }
6044                 if (ch == EOF) {
6045                         syntax_error_unterm_ch('"');
6046                         goto ret; /* error */
6047                 }
6048                 if (ch == '"') {
6049                         dest.o_expflags ^= EXP_FLAG_ESC_GLOB_CHARS;
6050                         continue;
6051                 }
6052                 if (ch == '\\') {
6053                         ch = i_getch(&input);
6054                         if (ch == EOF) {
6055 //example? error message?       syntax_error_unterm_ch('"');
6056                                 debug_printf_parse("%s: error: \\<eof>\n", __func__);
6057                                 goto ret;
6058                         }
6059                         o_addqchr(&dest, ch);
6060                         continue;
6061                 }
6062                 if (ch == '$') {
6063                         if (!parse_dollar(NULL, &dest, &input, /*quote_mask:*/ 0x80)) {
6064                                 debug_printf_parse("%s: error: parse_dollar returned 0 (error)\n", __func__);
6065                                 goto ret;
6066                         }
6067                         continue;
6068                 }
6069 #if ENABLE_HUSH_TICK
6070                 if (ch == '`') {
6071                         //unsigned pos = dest->length;
6072                         o_addchr(&dest, SPECIAL_VAR_SYMBOL);
6073                         o_addchr(&dest, 0x80 | '`');
6074                         if (!add_till_backquote(&dest, &input,
6075                                         /*in_dquote:*/ dest.o_expflags /* nonzero if EXP_FLAG_ESC_GLOB_CHARS set */
6076                                 )
6077                         ) {
6078                                 goto ret; /* error */
6079                         }
6080                         o_addchr(&dest, SPECIAL_VAR_SYMBOL);
6081                         //debug_printf_subst("SUBST RES3 '%s'\n", dest->data + pos);
6082                         continue;
6083                 }
6084 #endif
6085                 o_addQchr(&dest, ch);
6086         } /* for (;;) */
6087
6088         debug_printf_parse("encode: '%s' -> '%s'\n", str, dest.data);
6089         exp_str = expand_string_to_string(dest.data,
6090                         do_unbackslash ? EXP_FLAG_ESC_GLOB_CHARS : 0,
6091                         do_unbackslash
6092         );
6093  ret:
6094         debug_printf_parse("expand: '%s' -> '%s'\n", dest.data, exp_str);
6095         o_free(&dest);
6096         return exp_str;
6097 }
6098
6099 /* Expanding ARG in ${var+ARG}, ${var-ARG}
6100  */
6101 static int encode_then_append_var_plusminus(o_string *output, int n,
6102                 char *str, int dquoted)
6103 {
6104         struct in_str input;
6105         o_string dest = NULL_O_STRING;
6106
6107         if (!first_special_char_in_vararg(str)
6108          && '\0' == str[strcspn(str, G.ifs)]
6109         ) {
6110                 /* string has no special chars
6111                  * && string has no $IFS chars
6112                  */
6113                 if (dquoted) {
6114                         /* Prints 1 (quoted expansion is a "" word, not nothing):
6115                          * set -- "${notexist-}"; echo $#
6116                          */
6117                         output->has_quoted_part = 1;
6118                 }
6119                 return expand_vars_to_list(output, n, str);
6120         }
6121
6122         setup_string_in_str(&input, str);
6123
6124         for (;;) {
6125                 int ch;
6126
6127                 ch = i_getch(&input);
6128                 debug_printf_parse("%s: ch=%c (%d) escape=%x\n",
6129                                 __func__, ch, ch, dest.o_expflags);
6130
6131                 if (!dest.o_expflags) {
6132                         if (ch == EOF)
6133                                 break;
6134                         if (!dquoted && strchr(G.ifs, ch)) {
6135                                 /* PREFIX${x:d${e}f ...} and we met space: expand "d${e}f" and start new word.
6136                                  * do not assume we are at the start of the word (PREFIX above).
6137                                  */
6138                                 if (dest.data) {
6139                                         n = expand_vars_to_list(output, n, dest.data);
6140                                         o_free_and_set_NULL(&dest);
6141                                         o_addchr(output, '\0');
6142                                         n = o_save_ptr(output, n); /* create next word */
6143                                 } else
6144                                 if (output->length != o_get_last_ptr(output, n)
6145                                  || output->has_quoted_part
6146                                 ) {
6147                                         /* For these cases:
6148                                          * f() { for i; do echo "|$i|"; done; }; x=x
6149                                          * f a${x:+ }b  # 1st condition
6150                                          * |a|
6151                                          * |b|
6152                                          * f ""${x:+ }b  # 2nd condition
6153                                          * ||
6154                                          * |b|
6155                                          */
6156                                         o_addchr(output, '\0');
6157                                         n = o_save_ptr(output, n); /* create next word */
6158                                 }
6159                                 continue;
6160                         }
6161                         if (!dquoted && ch == '\'') {
6162                                 if (!add_till_single_quote_dquoted(&dest, &input))
6163                                         goto ret; /* error */
6164                                 o_addchr(&dest, SPECIAL_VAR_SYMBOL);
6165                                 o_addchr(&dest, SPECIAL_VAR_SYMBOL);
6166                                 continue;
6167                         }
6168                 }
6169                 if (ch == EOF) {
6170                         syntax_error_unterm_ch('"');
6171                         goto ret; /* error */
6172                 }
6173                 if (ch == '"') {
6174                         dest.o_expflags ^= EXP_FLAG_ESC_GLOB_CHARS;
6175                         if (dest.o_expflags) {
6176                                 o_addchr(&dest, SPECIAL_VAR_SYMBOL);
6177                                 o_addchr(&dest, SPECIAL_VAR_SYMBOL);
6178                         }
6179                         continue;
6180                 }
6181                 if (ch == '\\') {
6182                         ch = i_getch(&input);
6183                         if (ch == EOF) {
6184 //example? error message?       syntax_error_unterm_ch('"');
6185                                 debug_printf_parse("%s: error: \\<eof>\n", __func__);
6186                                 goto ret;
6187                         }
6188                         o_addqchr(&dest, ch);
6189                         continue;
6190                 }
6191                 if (ch == '$') {
6192                         if (!parse_dollar(NULL, &dest, &input, /*quote_mask:*/ (dest.o_expflags || dquoted) ? 0x80 : 0)) {
6193                                 debug_printf_parse("%s: error: parse_dollar returned 0 (error)\n", __func__);
6194                                 goto ret;
6195                         }
6196                         continue;
6197                 }
6198 #if ENABLE_HUSH_TICK
6199                 if (ch == '`') {
6200                         //unsigned pos = dest->length;
6201                         o_addchr(&dest, SPECIAL_VAR_SYMBOL);
6202                         o_addchr(&dest, (dest.o_expflags || dquoted) ? 0x80 | '`' : '`');
6203                         if (!add_till_backquote(&dest, &input,
6204                                         /*in_dquote:*/ dest.o_expflags /* nonzero if EXP_FLAG_ESC_GLOB_CHARS set */
6205                                 )
6206                         ) {
6207                                 goto ret; /* error */
6208                         }
6209                         o_addchr(&dest, SPECIAL_VAR_SYMBOL);
6210                         //debug_printf_subst("SUBST RES3 '%s'\n", dest->data + pos);
6211                         continue;
6212                 }
6213 #endif
6214                 if (dquoted) {
6215                         /* Always glob-protect if in dquotes:
6216                          * x=x; echo "${x:+/bin/c*}" - prints: /bin/c*
6217                          * x=x; echo "${x:+"/bin/c*"}" - prints: /bin/c*
6218                          */
6219                         o_addqchr(&dest, ch);
6220                 } else {
6221                         /* Glob-protect only if char is quoted:
6222                          * x=x; echo ${x:+/bin/c*} - prints many filenames
6223                          * x=x; echo ${x:+"/bin/c*"} - prints: /bin/c*
6224                          */
6225                         o_addQchr(&dest, ch);
6226                 }
6227         } /* for (;;) */
6228
6229         if (dest.data) {
6230                 n = expand_vars_to_list(output, n, dest.data);
6231         }
6232  ret:
6233         o_free(&dest);
6234         return n;
6235 }
6236
6237 #if ENABLE_FEATURE_SH_MATH
6238 static arith_t expand_and_evaluate_arith(const char *arg, const char **errmsg_p)
6239 {
6240         arith_state_t math_state;
6241         arith_t res;
6242         char *exp_str;
6243
6244         math_state.lookupvar = get_local_var_value;
6245         math_state.setvar = set_local_var_from_halves;
6246         //math_state.endofname = endofname;
6247         exp_str = encode_then_expand_string(arg);
6248         res = arith(&math_state, exp_str ? exp_str : arg);
6249         free(exp_str);
6250         if (errmsg_p)
6251                 *errmsg_p = math_state.errmsg;
6252         if (math_state.errmsg)
6253                 msg_and_die_if_script(math_state.errmsg);
6254         return res;
6255 }
6256 #endif
6257
6258 #if BASH_PATTERN_SUBST
6259 /* ${var/[/]pattern[/repl]} helpers */
6260 static char *strstr_pattern(char *val, const char *pattern, int *size)
6261 {
6262         while (1) {
6263                 char *end = scan_and_match(val, pattern, SCAN_MOVE_FROM_RIGHT + SCAN_MATCH_LEFT_HALF);
6264                 debug_printf_varexp("val:'%s' pattern:'%s' end:'%s'\n", val, pattern, end);
6265                 if (end) {
6266                         *size = end - val;
6267                         return val;
6268                 }
6269                 if (*val == '\0')
6270                         return NULL;
6271                 /* Optimization: if "*pat" did not match the start of "string",
6272                  * we know that "tring", "ring" etc will not match too:
6273                  */
6274                 if (pattern[0] == '*')
6275                         return NULL;
6276                 val++;
6277         }
6278 }
6279 static char *replace_pattern(char *val, const char *pattern, const char *repl, char exp_op)
6280 {
6281         char *result = NULL;
6282         unsigned res_len = 0;
6283         unsigned repl_len = strlen(repl);
6284
6285         /* Null pattern never matches, including if "var" is empty */
6286         if (!pattern[0])
6287                 return result; /* NULL, no replaces happened */
6288
6289         while (1) {
6290                 int size;
6291                 char *s = strstr_pattern(val, pattern, &size);
6292                 if (!s)
6293                         break;
6294
6295                 result = xrealloc(result, res_len + (s - val) + repl_len + 1);
6296                 strcpy(mempcpy(result + res_len, val, s - val), repl);
6297                 res_len += (s - val) + repl_len;
6298                 debug_printf_varexp("val:'%s' s:'%s' result:'%s'\n", val, s, result);
6299
6300                 val = s + size;
6301                 if (exp_op == '/')
6302                         break;
6303         }
6304         if (*val && result) {
6305                 result = xrealloc(result, res_len + strlen(val) + 1);
6306                 strcpy(result + res_len, val);
6307                 debug_printf_varexp("val:'%s' result:'%s'\n", val, result);
6308         }
6309         debug_printf_varexp("result:'%s'\n", result);
6310         return result;
6311 }
6312 #endif /* BASH_PATTERN_SUBST */
6313
6314 static int append_str_maybe_ifs_split(o_string *output, int n,
6315                 int first_ch, const char *val)
6316 {
6317         if (!(first_ch & 0x80)) { /* unquoted $VAR */
6318                 debug_printf_expand("unquoted '%s', output->o_escape:%d\n", val,
6319                                 !!(output->o_expflags & EXP_FLAG_ESC_GLOB_CHARS));
6320                 if (val && val[0])
6321                         n = expand_on_ifs(output, n, val);
6322         } else { /* quoted "$VAR" */
6323                 output->has_quoted_part = 1;
6324                 debug_printf_expand("quoted '%s', output->o_escape:%d\n", val,
6325                                 !!(output->o_expflags & EXP_FLAG_ESC_GLOB_CHARS));
6326                 if (val && val[0])
6327                         o_addQstr(output, val);
6328         }
6329         return n;
6330 }
6331
6332 /* Handle <SPECIAL_VAR_SYMBOL>varname...<SPECIAL_VAR_SYMBOL> construct.
6333  */
6334 static NOINLINE int expand_one_var(o_string *output, int n,
6335                 int first_ch, char *arg, char **pp)
6336 {
6337         const char *val;
6338         char *to_be_freed;
6339         char *p;
6340         char *var;
6341         char exp_op;
6342         char exp_save = exp_save; /* for compiler */
6343         char *exp_saveptr; /* points to expansion operator */
6344         char *exp_word = exp_word; /* for compiler */
6345         char arg0;
6346
6347         val = NULL;
6348         to_be_freed = NULL;
6349         p = *pp;
6350         *p = '\0'; /* replace trailing SPECIAL_VAR_SYMBOL */
6351         var = arg;
6352         exp_saveptr = arg[1] ? strchr(VAR_ENCODED_SUBST_OPS, arg[1]) : NULL;
6353         arg0 = arg[0];
6354         arg[0] = (arg0 & 0x7f);
6355         exp_op = 0;
6356
6357         if (arg[0] == '#' && arg[1] /* ${#...} but not ${#} */
6358          && (!exp_saveptr               /* and ( not(${#<op_char>...}) */
6359             || (arg[2] == '\0' && strchr(SPECIAL_VARS_STR, arg[1])) /* or ${#C} "len of $C" ) */
6360             )           /* NB: skipping ^^^specvar check mishandles ${#::2} */
6361         ) {
6362                 /* It must be length operator: ${#var} */
6363                 var++;
6364                 exp_op = 'L';
6365         } else {
6366                 /* Maybe handle parameter expansion */
6367                 if (exp_saveptr /* if 2nd char is one of expansion operators */
6368                  && strchr(NUMERIC_SPECVARS_STR, arg[0]) /* 1st char is special variable */
6369                 ) {
6370                         /* ${?:0}, ${#[:]%0} etc */
6371                         exp_saveptr = var + 1;
6372                 } else {
6373                         /* ${?}, ${var}, ${var:0}, ${var[:]%0} etc */
6374                         exp_saveptr = var+1 + strcspn(var+1, VAR_ENCODED_SUBST_OPS);
6375                 }
6376                 exp_op = exp_save = *exp_saveptr;
6377                 if (exp_op) {
6378                         exp_word = exp_saveptr + 1;
6379                         if (exp_op == ':') {
6380                                 exp_op = *exp_word++;
6381 //TODO: try ${var:} and ${var:bogus} in non-bash config
6382                                 if (BASH_SUBSTR
6383                                  && (!exp_op || !strchr(MINUS_PLUS_EQUAL_QUESTION, exp_op))
6384                                 ) {
6385                                         /* oops... it's ${var:N[:M]}, not ${var:?xxx} or some such */
6386                                         exp_op = ':';
6387                                         exp_word--;
6388                                 }
6389                         }
6390                         *exp_saveptr = '\0';
6391                 } /* else: it's not an expansion op, but bare ${var} */
6392         }
6393
6394         /* Look up the variable in question */
6395         if (isdigit(var[0])) {
6396                 /* parse_dollar should have vetted var for us */
6397                 int nn = xatoi_positive(var);
6398                 if (nn < G.global_argc)
6399                         val = G.global_argv[nn];
6400                 /* else val remains NULL: $N with too big N */
6401         } else {
6402                 switch (var[0]) {
6403                 case '$': /* pid */
6404                         val = utoa(G.root_pid);
6405                         break;
6406                 case '!': /* bg pid */
6407                         val = G.last_bg_pid ? utoa(G.last_bg_pid) : "";
6408                         break;
6409                 case '?': /* exitcode */
6410                         val = utoa(G.last_exitcode);
6411                         break;
6412                 case '#': /* argc */
6413                         val = utoa(G.global_argc ? G.global_argc-1 : 0);
6414                         break;
6415                 case '-': { /* active options */
6416                         /* Check set_mode() to see what option chars we support */
6417                         char *cp;
6418                         val = cp = G.optstring_buf;
6419                         if (G.o_opt[OPT_O_ERREXIT])
6420                                 *cp++ = 'e';
6421                         if (G_interactive_fd)
6422                                 *cp++ = 'i';
6423                         if (G_x_mode)
6424                                 *cp++ = 'x';
6425                         /* If G.o_opt[OPT_O_NOEXEC] is true,
6426                          * commands read but are not executed,
6427                          * so $- can not execute too, 'n' is never seen in $-.
6428                          */
6429                         if (G.opt_c)
6430                                 *cp++ = 'c';
6431                         if (G.opt_s)
6432                                 *cp++ = 's';
6433                         *cp = '\0';
6434                         break;
6435                 }
6436                 default:
6437                         val = get_local_var_value(var);
6438                 }
6439         }
6440
6441         /* Handle any expansions */
6442         if (exp_op == 'L') {
6443                 reinit_unicode_for_hush();
6444                 debug_printf_expand("expand: length(%s)=", val);
6445                 val = utoa(val ? unicode_strlen(val) : 0);
6446                 debug_printf_expand("%s\n", val);
6447         } else if (exp_op) {
6448                 if (exp_op == '%' || exp_op == '#') {
6449                         /* Standard-mandated substring removal ops:
6450                          * ${parameter%word} - remove smallest suffix pattern
6451                          * ${parameter%%word} - remove largest suffix pattern
6452                          * ${parameter#word} - remove smallest prefix pattern
6453                          * ${parameter##word} - remove largest prefix pattern
6454                          *
6455                          * Word is expanded to produce a glob pattern.
6456                          * Then var's value is matched to it and matching part removed.
6457                          */
6458 //FIXME: ${x#...${...}...}
6459 //should evaluate inner ${...} even if x is "" and no shrinking of it is possible -
6460 //inner ${...} may have side effects!
6461                         if (val && val[0]) {
6462                                 char *t;
6463                                 char *exp_exp_word;
6464                                 char *loc;
6465                                 unsigned scan_flags = pick_scan(exp_op, *exp_word);
6466                                 if (exp_op == *exp_word)  /* ## or %% */
6467                                         exp_word++;
6468                                 debug_printf_expand("expand: exp_word:'%s'\n", exp_word);
6469                                 exp_exp_word = encode_then_expand_vararg(exp_word, /*handle_squotes:*/ 1, /*unbackslash:*/ 0);
6470                                 if (exp_exp_word)
6471                                         exp_word = exp_exp_word;
6472                                 debug_printf_expand("expand: exp_word:'%s'\n", exp_word);
6473                                 /*
6474                                  * HACK ALERT. We depend here on the fact that
6475                                  * G.global_argv and results of utoa and get_local_var_value
6476                                  * are actually in writable memory:
6477                                  * scan_and_match momentarily stores NULs there.
6478                                  */
6479                                 t = (char*)val;
6480                                 loc = scan_and_match(t, exp_word, scan_flags);
6481                                 debug_printf_expand("op:%c str:'%s' pat:'%s' res:'%s'\n", exp_op, t, exp_word, loc);
6482                                 free(exp_exp_word);
6483                                 if (loc) { /* match was found */
6484                                         if (scan_flags & SCAN_MATCH_LEFT_HALF) /* #[#] */
6485                                                 val = loc; /* take right part */
6486                                         else /* %[%] */
6487                                                 val = to_be_freed = xstrndup(val, loc - val); /* left */
6488                                 }
6489                         }
6490                 }
6491 #if BASH_PATTERN_SUBST
6492                 else if (exp_op == '/' || exp_op == '\\') {
6493                         /* It's ${var/[/]pattern[/repl]} thing.
6494                          * Note that in encoded form it has TWO parts:
6495                          * var/pattern<SPECIAL_VAR_SYMBOL>repl<SPECIAL_VAR_SYMBOL>
6496                          * and if // is used, it is encoded as \:
6497                          * var\pattern<SPECIAL_VAR_SYMBOL>repl<SPECIAL_VAR_SYMBOL>
6498                          */
6499                         if (val && val[0]) {
6500                                 /* pattern uses non-standard expansion.
6501                                  * repl should be unbackslashed and globbed
6502                                  * by the usual expansion rules:
6503                                  *  >az >bz
6504                                  *  v='a bz'; echo "${v/a*z/a*z}" #prints "a*z"
6505                                  *  v='a bz'; echo "${v/a*z/\z}"  #prints "z"
6506                                  *  v='a bz'; echo ${v/a*z/a*z}   #prints "az"
6507                                  *  v='a bz'; echo ${v/a*z/\z}    #prints "z"
6508                                  * (note that a*z _pattern_ is never globbed!)
6509                                  */
6510                                 char *pattern, *repl, *t;
6511                                 pattern = encode_then_expand_vararg(exp_word, /*handle_squotes:*/ 1, /*unbackslash:*/ 0);
6512                                 if (!pattern)
6513                                         pattern = xstrdup(exp_word);
6514                                 debug_printf_varexp("pattern:'%s'->'%s'\n", exp_word, pattern);
6515                                 *p++ = SPECIAL_VAR_SYMBOL;
6516                                 exp_word = p;
6517                                 p = strchr(p, SPECIAL_VAR_SYMBOL);
6518                                 *p = '\0';
6519                                 repl = encode_then_expand_vararg(exp_word, /*handle_squotes:*/ 1, /*unbackslash:*/ 1);
6520                                 debug_printf_varexp("repl:'%s'->'%s'\n", exp_word, repl);
6521                                 /* HACK ALERT. We depend here on the fact that
6522                                  * G.global_argv and results of utoa and get_local_var_value
6523                                  * are actually in writable memory:
6524                                  * replace_pattern momentarily stores NULs there. */
6525                                 t = (char*)val;
6526                                 to_be_freed = replace_pattern(t,
6527                                                 pattern,
6528                                                 (repl ? repl : exp_word),
6529                                                 exp_op);
6530                                 if (to_be_freed) /* at least one replace happened */
6531                                         val = to_be_freed;
6532                                 free(pattern);
6533                                 free(repl);
6534                         } else {
6535                                 /* Empty variable always gives nothing */
6536                                 // "v=''; echo ${v/*/w}" prints "", not "w"
6537                                 /* Just skip "replace" part */
6538                                 *p++ = SPECIAL_VAR_SYMBOL;
6539                                 p = strchr(p, SPECIAL_VAR_SYMBOL);
6540                                 *p = '\0';
6541                         }
6542                 }
6543 #endif /* BASH_PATTERN_SUBST */
6544                 else if (exp_op == ':') {
6545 #if BASH_SUBSTR && ENABLE_FEATURE_SH_MATH
6546                         /* It's ${var:N[:M]} bashism.
6547                          * Note that in encoded form it has TWO parts:
6548                          * var:N<SPECIAL_VAR_SYMBOL>M<SPECIAL_VAR_SYMBOL>
6549                          */
6550                         arith_t beg, len;
6551                         const char *errmsg;
6552
6553                         beg = expand_and_evaluate_arith(exp_word, &errmsg);
6554                         if (errmsg)
6555                                 goto arith_err;
6556                         debug_printf_varexp("beg:'%s'=%lld\n", exp_word, (long long)beg);
6557                         *p++ = SPECIAL_VAR_SYMBOL;
6558                         exp_word = p;
6559                         p = strchr(p, SPECIAL_VAR_SYMBOL);
6560                         *p = '\0';
6561                         len = expand_and_evaluate_arith(exp_word, &errmsg);
6562                         if (errmsg)
6563                                 goto arith_err;
6564                         debug_printf_varexp("len:'%s'=%lld\n", exp_word, (long long)len);
6565                         if (beg < 0) {
6566                                 /* negative beg counts from the end */
6567                                 beg = (arith_t)strlen(val) + beg;
6568                                 if (beg < 0) /* ${v: -999999} is "" */
6569                                         beg = len = 0;
6570                         }
6571                         debug_printf_varexp("from val:'%s'\n", val);
6572                         if (len < 0) {
6573                                 /* in bash, len=-n means strlen()-n */
6574                                 len = (arith_t)strlen(val) - beg + len;
6575                                 if (len < 0) /* bash compat */
6576                                         msg_and_die_if_script("%s: substring expression < 0", var);
6577                         }
6578                         if (len <= 0 || !val || beg >= strlen(val)) {
6579  arith_err:
6580                                 val = NULL;
6581                         } else {
6582                                 /* Paranoia. What if user entered 9999999999999
6583                                  * which fits in arith_t but not int? */
6584                                 if (len >= INT_MAX)
6585                                         len = INT_MAX;
6586                                 val = to_be_freed = xstrndup(val + beg, len);
6587                         }
6588                         debug_printf_varexp("val:'%s'\n", val);
6589 #else /* not (HUSH_SUBSTR_EXPANSION && FEATURE_SH_MATH) */
6590                         msg_and_die_if_script("malformed ${%s:...}", var);
6591                         val = NULL;
6592 #endif
6593                 } else { /* one of "-=+?" */
6594                         /* Standard-mandated substitution ops:
6595                          * ${var?word} - indicate error if unset
6596                          *      If var is unset, word (or a message indicating it is unset
6597                          *      if word is null) is written to standard error
6598                          *      and the shell exits with a non-zero exit status.
6599                          *      Otherwise, the value of var is substituted.
6600                          * ${var-word} - use default value
6601                          *      If var is unset, word is substituted.
6602                          * ${var=word} - assign and use default value
6603                          *      If var is unset, word is assigned to var.
6604                          *      In all cases, final value of var is substituted.
6605                          * ${var+word} - use alternative value
6606                          *      If var is unset, null is substituted.
6607                          *      Otherwise, word is substituted.
6608                          *
6609                          * Word is subjected to tilde expansion, parameter expansion,
6610                          * command substitution, and arithmetic expansion.
6611                          * If word is not needed, it is not expanded.
6612                          *
6613                          * Colon forms (${var:-word}, ${var:=word} etc) do the same,
6614                          * but also treat null var as if it is unset.
6615                          *
6616                          * Word-splitting and single quote behavior:
6617                          *
6618                          * $ f() { for i; do echo "|$i|"; done; };
6619                          *
6620                          * $ x=; f ${x:?'x y' z}
6621                          * bash: x: x y z              #BUG: does not abort, ${} results in empty expansion
6622                          * $ x=; f "${x:?'x y' z}"
6623                          * bash: x: x y z       # dash prints: dash: x: 'x y' z   #BUG: does not abort, ${} results in ""
6624                          *
6625                          * $ x=; f ${x:='x y' z}
6626                          * |x|
6627                          * |y|
6628                          * |z|
6629                          * $ x=; f "${x:='x y' z}"
6630                          * |'x y' z|
6631                          *
6632                          * $ x=x; f ${x:+'x y' z}
6633                          * |x y|
6634                          * |z|
6635                          * $ x=x; f "${x:+'x y' z}"
6636                          * |'x y' z|
6637                          *
6638                          * $ x=; f ${x:-'x y' z}
6639                          * |x y|
6640                          * |z|
6641                          * $ x=; f "${x:-'x y' z}"
6642                          * |'x y' z|
6643                          */
6644                         int use_word = (!val || ((exp_save == ':') && !val[0]));
6645                         if (exp_op == '+')
6646                                 use_word = !use_word;
6647                         debug_printf_expand("expand: op:%c (null:%s) test:%i\n", exp_op,
6648                                         (exp_save == ':') ? "true" : "false", use_word);
6649                         if (use_word) {
6650                                 if (exp_op == '+' || exp_op == '-') {
6651                                         /* ${var+word} - use alternative value */
6652                                         /* ${var-word} - use default value */
6653                                         n = encode_then_append_var_plusminus(output, n, exp_word,
6654                                                         /*dquoted:*/ (arg0 & 0x80)
6655                                         );
6656                                         val = NULL;
6657                                 } else {
6658                                         /* ${var?word} - indicate error if unset */
6659                                         /* ${var=word} - assign and use default value */
6660                                         to_be_freed = encode_then_expand_vararg(exp_word,
6661                                                         /*handle_squotes:*/ !(arg0 & 0x80),
6662                                                         /*unbackslash:*/ 0
6663                                         );
6664                                         if (to_be_freed)
6665                                                 exp_word = to_be_freed;
6666                                         if (exp_op == '?') {
6667                                                 /* mimic bash message */
6668                                                 msg_and_die_if_script("%s: %s",
6669                                                         var,
6670                                                         exp_word[0]
6671                                                         ? exp_word
6672                                                         : "parameter null or not set"
6673                                                         /* ash has more specific messages, a-la: */
6674                                                         /*: (exp_save == ':' ? "parameter null or not set" : "parameter not set")*/
6675                                                 );
6676 //TODO: how interactive bash aborts expansion mid-command?
6677 //It aborts the entire line, returns to prompt:
6678 // $ f() { for i; do echo "|$i|"; done; }; x=; f "${x:?'x y' z}"; echo YO
6679 // bash: x: x y z
6680 // $
6681 // ("echo YO" is not executed, neither the f function call)
6682                                         } else {
6683                                                 val = exp_word;
6684                                         }
6685                                         if (exp_op == '=') {
6686                                                 /* ${var=[word]} or ${var:=[word]} */
6687                                                 if (isdigit(var[0]) || var[0] == '#') {
6688                                                         /* mimic bash message */
6689                                                         msg_and_die_if_script("$%s: cannot assign in this way", var);
6690                                                         val = NULL;
6691                                                 } else {
6692                                                         char *new_var = xasprintf("%s=%s", var, val);
6693                                                         set_local_var(new_var, /*flag:*/ 0);
6694                                                 }
6695                                         }
6696                                 }
6697                         }
6698                 } /* one of "-=+?" */
6699
6700                 *exp_saveptr = exp_save;
6701         } /* if (exp_op) */
6702
6703         arg[0] = arg0;
6704         *pp = p;
6705
6706         n = append_str_maybe_ifs_split(output, n, first_ch, val);
6707
6708         free(to_be_freed);
6709         return n;
6710 }
6711
6712 /* Expand all variable references in given string, adding words to list[]
6713  * at n, n+1,... positions. Return updated n (so that list[n] is next one
6714  * to be filled). This routine is extremely tricky: has to deal with
6715  * variables/parameters with whitespace, $* and $@, and constructs like
6716  * 'echo -$*-'. If you play here, you must run testsuite afterwards! */
6717 static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg)
6718 {
6719         /* output->o_expflags & EXP_FLAG_SINGLEWORD (0x80) if we are in
6720          * expansion of right-hand side of assignment == 1-element expand.
6721          */
6722         char cant_be_null = 0; /* only bit 0x80 matters */
6723         char *p;
6724
6725         debug_printf_expand("expand_vars_to_list: arg:'%s' singleword:%x\n", arg,
6726                         !!(output->o_expflags & EXP_FLAG_SINGLEWORD));
6727         debug_print_list("expand_vars_to_list[0]", output, n);
6728
6729         while ((p = strchr(arg, SPECIAL_VAR_SYMBOL)) != NULL) {
6730                 char first_ch;
6731 #if ENABLE_FEATURE_SH_MATH
6732                 char arith_buf[sizeof(arith_t)*3 + 2];
6733 #endif
6734
6735                 if (output->ended_in_ifs) {
6736                         o_addchr(output, '\0');
6737                         n = o_save_ptr(output, n);
6738                         output->ended_in_ifs = 0;
6739                 }
6740
6741                 o_addblock(output, arg, p - arg);
6742                 debug_print_list("expand_vars_to_list[1]", output, n);
6743                 arg = ++p;
6744                 p = strchr(p, SPECIAL_VAR_SYMBOL);
6745
6746                 /* Fetch special var name (if it is indeed one of them)
6747                  * and quote bit, force the bit on if singleword expansion -
6748                  * important for not getting v=$@ expand to many words. */
6749                 first_ch = arg[0] | (output->o_expflags & EXP_FLAG_SINGLEWORD);
6750
6751                 /* Is this variable quoted and thus expansion can't be null?
6752                  * "$@" is special. Even if quoted, it can still
6753                  * expand to nothing (not even an empty string),
6754                  * thus it is excluded. */
6755                 if ((first_ch & 0x7f) != '@')
6756                         cant_be_null |= first_ch;
6757
6758                 switch (first_ch & 0x7f) {
6759                 /* Highest bit in first_ch indicates that var is double-quoted */
6760                 case '*':
6761                 case '@': {
6762                         int i;
6763                         if (!G.global_argv[1])
6764                                 break;
6765                         i = 1;
6766                         cant_be_null |= first_ch; /* do it for "$@" _now_, when we know it's not empty */
6767                         if (!(first_ch & 0x80)) { /* unquoted $* or $@ */
6768                                 while (G.global_argv[i]) {
6769                                         n = expand_on_ifs(output, n, G.global_argv[i]);
6770                                         debug_printf_expand("expand_vars_to_list: argv %d (last %d)\n", i, G.global_argc - 1);
6771                                         if (G.global_argv[i++][0] && G.global_argv[i]) {
6772                                                 /* this argv[] is not empty and not last:
6773                                                  * put terminating NUL, start new word */
6774                                                 o_addchr(output, '\0');
6775                                                 debug_print_list("expand_vars_to_list[2]", output, n);
6776                                                 n = o_save_ptr(output, n);
6777                                                 debug_print_list("expand_vars_to_list[3]", output, n);
6778                                         }
6779                                 }
6780                         } else
6781                         /* If EXP_FLAG_SINGLEWORD, we handle assignment 'a=....$@.....'
6782                          * and in this case should treat it like '$*' - see 'else...' below */
6783                         if (first_ch == (char)('@'|0x80)  /* quoted $@ */
6784                          && !(output->o_expflags & EXP_FLAG_SINGLEWORD) /* not v="$@" case */
6785                         ) {
6786                                 while (1) {
6787                                         o_addQstr(output, G.global_argv[i]);
6788                                         if (++i >= G.global_argc)
6789                                                 break;
6790                                         o_addchr(output, '\0');
6791                                         debug_print_list("expand_vars_to_list[4]", output, n);
6792                                         n = o_save_ptr(output, n);
6793                                 }
6794                         } else { /* quoted $* (or v="$@" case): add as one word */
6795                                 while (1) {
6796                                         o_addQstr(output, G.global_argv[i]);
6797                                         if (!G.global_argv[++i])
6798                                                 break;
6799                                         if (G.ifs[0])
6800                                                 o_addchr(output, G.ifs[0]);
6801                                 }
6802                                 output->has_quoted_part = 1;
6803                         }
6804                         break;
6805                 }
6806                 case SPECIAL_VAR_SYMBOL: {
6807                         /* <SPECIAL_VAR_SYMBOL><SPECIAL_VAR_SYMBOL> */
6808                         /* "Empty variable", used to make "" etc to not disappear */
6809                         output->has_quoted_part = 1;
6810                         cant_be_null = 0x80;
6811                         arg++;
6812                         break;
6813                 }
6814                 case SPECIAL_VAR_QUOTED_SVS:
6815                         /* <SPECIAL_VAR_SYMBOL><SPECIAL_VAR_QUOTED_SVS><SPECIAL_VAR_SYMBOL> */
6816                         /* "^C variable", represents literal ^C char (possible in scripts) */
6817                         o_addchr(output, SPECIAL_VAR_SYMBOL);
6818                         arg++;
6819                         break;
6820 #if ENABLE_HUSH_TICK
6821                 case '`': {
6822                         /* <SPECIAL_VAR_SYMBOL>`cmd<SPECIAL_VAR_SYMBOL> */
6823                         o_string subst_result = NULL_O_STRING;
6824
6825                         *p = '\0'; /* replace trailing <SPECIAL_VAR_SYMBOL> */
6826                         arg++;
6827                         /* Can't just stuff it into output o_string,
6828                          * expanded result may need to be globbed
6829                          * and $IFS-split */
6830                         debug_printf_subst("SUBST '%s' first_ch %x\n", arg, first_ch);
6831                         G.last_exitcode = process_command_subs(&subst_result, arg);
6832                         G.expand_exitcode = G.last_exitcode;
6833                         debug_printf_subst("SUBST RES:%d '%s'\n", G.last_exitcode, subst_result.data);
6834                         n = append_str_maybe_ifs_split(output, n, first_ch, subst_result.data);
6835                         o_free(&subst_result);
6836                         break;
6837                 }
6838 #endif
6839 #if ENABLE_FEATURE_SH_MATH
6840                 case '+': {
6841                         /* <SPECIAL_VAR_SYMBOL>+arith<SPECIAL_VAR_SYMBOL> */
6842                         arith_t res;
6843
6844                         arg++; /* skip '+' */
6845                         *p = '\0'; /* replace trailing <SPECIAL_VAR_SYMBOL> */
6846                         debug_printf_subst("ARITH '%s' first_ch %x\n", arg, first_ch);
6847                         res = expand_and_evaluate_arith(arg, NULL);
6848                         debug_printf_subst("ARITH RES '"ARITH_FMT"'\n", res);
6849                         sprintf(arith_buf, ARITH_FMT, res);
6850                         o_addstr(output, arith_buf);
6851                         break;
6852                 }
6853 #endif
6854                 default:
6855                         /* <SPECIAL_VAR_SYMBOL>varname[ops]<SPECIAL_VAR_SYMBOL> */
6856                         n = expand_one_var(output, n, first_ch, arg, &p);
6857                         break;
6858                 } /* switch (char after <SPECIAL_VAR_SYMBOL>) */
6859
6860                 /* Restore NULL'ed SPECIAL_VAR_SYMBOL.
6861                  * Do the check to avoid writing to a const string. */
6862                 if (*p != SPECIAL_VAR_SYMBOL)
6863                         *p = SPECIAL_VAR_SYMBOL;
6864                 arg = ++p;
6865         } /* end of "while (SPECIAL_VAR_SYMBOL is found) ..." */
6866
6867         if (*arg) {
6868                 /* handle trailing string */
6869                 if (output->ended_in_ifs) {
6870                         o_addchr(output, '\0');
6871                         n = o_save_ptr(output, n);
6872                 }
6873                 debug_print_list("expand_vars_to_list[a]", output, n);
6874                 /* this part is literal, and it was already pre-quoted
6875                  * if needed (much earlier), do not use o_addQstr here!
6876                  */
6877                 o_addstr(output, arg);
6878                 debug_print_list("expand_vars_to_list[b]", output, n);
6879         } else
6880         if (output->length == o_get_last_ptr(output, n) /* expansion is empty */
6881          && !(cant_be_null & 0x80)   /* and all vars were not quoted */
6882          && !output->has_quoted_part
6883         ) {
6884                 n--;
6885                 /* allow to reuse list[n] later without re-growth */
6886                 output->has_empty_slot = 1;
6887         }
6888
6889         return n;
6890 }
6891
6892 static char **expand_variables(char **argv, unsigned expflags)
6893 {
6894         int n;
6895         char **list;
6896         o_string output = NULL_O_STRING;
6897
6898         output.o_expflags = expflags;
6899
6900         n = 0;
6901         for (;;) {
6902                 /* go to next list[n] */
6903                 output.ended_in_ifs = 0;
6904                 n = o_save_ptr(&output, n);
6905
6906                 if (!*argv)
6907                         break;
6908
6909                 /* expand argv[i] */
6910                 n = expand_vars_to_list(&output, n, *argv++);
6911                 /* if (!output->has_empty_slot) -- need this?? */
6912                         o_addchr(&output, '\0');
6913         }
6914         debug_print_list("expand_variables", &output, n);
6915
6916         /* output.data (malloced in one block) gets returned in "list" */
6917         list = o_finalize_list(&output, n);
6918         debug_print_strings("expand_variables[1]", list);
6919         return list;
6920 }
6921
6922 static char **expand_strvec_to_strvec(char **argv)
6923 {
6924         return expand_variables(argv, EXP_FLAG_GLOB | EXP_FLAG_ESC_GLOB_CHARS);
6925 }
6926
6927 #if defined(CMD_SINGLEWORD_NOGLOB)
6928 static char **expand_strvec_to_strvec_singleword_noglob(char **argv)
6929 {
6930         return expand_variables(argv, EXP_FLAG_SINGLEWORD);
6931 }
6932 #endif
6933
6934 /* Used for expansion of right hand of assignments,
6935  * $((...)), heredocs, variable expansion parts.
6936  *
6937  * NB: should NOT do globbing!
6938  * "export v=/bin/c*; env | grep ^v=" outputs "v=/bin/c*"
6939  */
6940 static char *expand_string_to_string(const char *str, int EXP_flags, int do_unbackslash)
6941 {
6942 #if !BASH_PATTERN_SUBST && !ENABLE_HUSH_CASE
6943         const int do_unbackslash = 1;
6944         const int EXP_flags = EXP_FLAG_ESC_GLOB_CHARS;
6945 #endif
6946         char *argv[2], **list;
6947
6948         debug_printf_expand("string_to_string<='%s'\n", str);
6949         /* This is generally an optimization, but it also
6950          * handles "", which otherwise trips over !list[0] check below.
6951          * (is this ever happens that we actually get str="" here?)
6952          */
6953         if (!strchr(str, SPECIAL_VAR_SYMBOL) && !strchr(str, '\\')) {
6954                 //TODO: Can use on strings with \ too, just unbackslash() them?
6955                 debug_printf_expand("string_to_string(fast)=>'%s'\n", str);
6956                 return xstrdup(str);
6957         }
6958
6959         argv[0] = (char*)str;
6960         argv[1] = NULL;
6961         list = expand_variables(argv, EXP_flags | EXP_FLAG_SINGLEWORD);
6962         if (!list[0]) {
6963                 /* Example where it happens:
6964                  * x=; echo ${x:-"$@"}
6965                  */
6966                 ((char*)list)[0] = '\0';
6967         } else {
6968                 if (HUSH_DEBUG)
6969                         if (list[1])
6970                                 bb_simple_error_msg_and_die("BUG in varexp2");
6971                 /* actually, just move string 2*sizeof(char*) bytes back */
6972                 overlapping_strcpy((char*)list, list[0]);
6973                 if (do_unbackslash)
6974                         unbackslash((char*)list);
6975         }
6976         debug_printf_expand("string_to_string=>'%s'\n", (char*)list);
6977         return (char*)list;
6978 }
6979
6980 #if 0
6981 static char* expand_strvec_to_string(char **argv)
6982 {
6983         char **list;
6984
6985         list = expand_variables(argv, EXP_FLAG_SINGLEWORD);
6986         /* Convert all NULs to spaces */
6987         if (list[0]) {
6988                 int n = 1;
6989                 while (list[n]) {
6990                         if (HUSH_DEBUG)
6991                                 if (list[n-1] + strlen(list[n-1]) + 1 != list[n])
6992                                         bb_error_msg_and_die("BUG in varexp3");
6993                         /* bash uses ' ' regardless of $IFS contents */
6994                         list[n][-1] = ' ';
6995                         n++;
6996                 }
6997         }
6998         overlapping_strcpy((char*)list, list[0] ? list[0] : "");
6999         debug_printf_expand("strvec_to_string='%s'\n", (char*)list);
7000         return (char*)list;
7001 }
7002 #endif
7003
7004 static char **expand_assignments(char **argv, int count)
7005 {
7006         int i;
7007         char **p;
7008
7009         G.expanded_assignments = p = NULL;
7010         /* Expand assignments into one string each */
7011         for (i = 0; i < count; i++) {
7012                 p = add_string_to_strings(p,
7013                         expand_string_to_string(argv[i],
7014                                 EXP_FLAG_ESC_GLOB_CHARS,
7015                                 /*unbackslash:*/ 1
7016                         )
7017                 );
7018                 G.expanded_assignments = p;
7019         }
7020         G.expanded_assignments = NULL;
7021         return p;
7022 }
7023
7024
7025 static void switch_off_special_sigs(unsigned mask)
7026 {
7027         unsigned sig = 0;
7028         while ((mask >>= 1) != 0) {
7029                 sig++;
7030                 if (!(mask & 1))
7031                         continue;
7032 #if ENABLE_HUSH_TRAP
7033                 if (G_traps) {
7034                         if (G_traps[sig] && !G_traps[sig][0])
7035                                 /* trap is '', has to remain SIG_IGN */
7036                                 continue;
7037                         free(G_traps[sig]);
7038                         G_traps[sig] = NULL;
7039                 }
7040 #endif
7041                 /* We are here only if no trap or trap was not '' */
7042                 install_sighandler(sig, SIG_DFL);
7043         }
7044 }
7045
7046 #if BB_MMU
7047 /* never called */
7048 void re_execute_shell(char ***to_free, const char *s,
7049                 char *g_argv0, char **g_argv,
7050                 char **builtin_argv) NORETURN;
7051
7052 static void reset_traps_to_defaults(void)
7053 {
7054         /* This function is always called in a child shell
7055          * after fork (not vfork, NOMMU doesn't use this function).
7056          */
7057         IF_HUSH_TRAP(unsigned sig;)
7058         unsigned mask;
7059
7060         /* Child shells are not interactive.
7061          * SIGTTIN/SIGTTOU/SIGTSTP should not have special handling.
7062          * Testcase: (while :; do :; done) + ^Z should background.
7063          * Same goes for SIGTERM, SIGHUP, SIGINT.
7064          */
7065         mask = (G.special_sig_mask & SPECIAL_INTERACTIVE_SIGS) | G_fatal_sig_mask;
7066         if (!G_traps && !mask)
7067                 return; /* already no traps and no special sigs */
7068
7069         /* Switch off special sigs */
7070         switch_off_special_sigs(mask);
7071 # if ENABLE_HUSH_JOB
7072         G_fatal_sig_mask = 0;
7073 # endif
7074         G.special_sig_mask &= ~SPECIAL_INTERACTIVE_SIGS;
7075         /* SIGQUIT,SIGCHLD and maybe SPECIAL_JOBSTOP_SIGS
7076          * remain set in G.special_sig_mask */
7077
7078 # if ENABLE_HUSH_TRAP
7079         if (!G_traps)
7080                 return;
7081
7082         /* Reset all sigs to default except ones with empty traps */
7083         for (sig = 0; sig < NSIG; sig++) {
7084                 if (!G_traps[sig])
7085                         continue; /* no trap: nothing to do */
7086                 if (!G_traps[sig][0])
7087                         continue; /* empty trap: has to remain SIG_IGN */
7088                 /* sig has non-empty trap, reset it: */
7089                 free(G_traps[sig]);
7090                 G_traps[sig] = NULL;
7091                 /* There is no signal for trap 0 (EXIT) */
7092                 if (sig == 0)
7093                         continue;
7094                 install_sighandler(sig, pick_sighandler(sig));
7095         }
7096 # endif
7097 }
7098
7099 #else /* !BB_MMU */
7100
7101 static void re_execute_shell(char ***to_free, const char *s,
7102                 char *g_argv0, char **g_argv,
7103                 char **builtin_argv) NORETURN;
7104 static void re_execute_shell(char ***to_free, const char *s,
7105                 char *g_argv0, char **g_argv,
7106                 char **builtin_argv)
7107 {
7108 # define NOMMU_HACK_FMT ("-$%x:%x:%x:%x:%x:%llx" IF_HUSH_LOOPS(":%x"))
7109         /* delims + 2 * (number of bytes in printed hex numbers) */
7110         char param_buf[sizeof(NOMMU_HACK_FMT) + 2 * (sizeof(int)*6 + sizeof(long long)*1)];
7111         char *heredoc_argv[4];
7112         struct variable *cur;
7113 # if ENABLE_HUSH_FUNCTIONS
7114         struct function *funcp;
7115 # endif
7116         char **argv, **pp;
7117         unsigned cnt;
7118         unsigned long long empty_trap_mask;
7119
7120         if (!g_argv0) { /* heredoc */
7121                 argv = heredoc_argv;
7122                 argv[0] = (char *) G.argv0_for_re_execing;
7123                 argv[1] = (char *) "-<";
7124                 argv[2] = (char *) s;
7125                 argv[3] = NULL;
7126                 pp = &argv[3]; /* used as pointer to empty environment */
7127                 goto do_exec;
7128         }
7129
7130         cnt = 0;
7131         pp = builtin_argv;
7132         if (pp) while (*pp++)
7133                 cnt++;
7134
7135         empty_trap_mask = 0;
7136         if (G_traps) {
7137                 int sig;
7138                 for (sig = 1; sig < NSIG; sig++) {
7139                         if (G_traps[sig] && !G_traps[sig][0])
7140                                 empty_trap_mask |= 1LL << sig;
7141                 }
7142         }
7143
7144         sprintf(param_buf, NOMMU_HACK_FMT
7145                         , (unsigned) G.root_pid
7146                         , (unsigned) G.root_ppid
7147                         , (unsigned) G.last_bg_pid
7148                         , (unsigned) G.last_exitcode
7149                         , cnt
7150                         , empty_trap_mask
7151                         IF_HUSH_LOOPS(, G.depth_of_loop)
7152                         );
7153 # undef NOMMU_HACK_FMT
7154         /* 1:hush 2:-$<pid>:<pid>:<exitcode>:<etc...> <vars...> <funcs...>
7155          * 3:-c 4:<cmd> 5:<arg0> <argN...> 6:NULL
7156          */
7157         cnt += 6;
7158         for (cur = G.top_var; cur; cur = cur->next) {
7159                 if (!cur->flg_export || cur->flg_read_only)
7160                         cnt += 2;
7161         }
7162 # if ENABLE_HUSH_FUNCTIONS
7163         for (funcp = G.top_func; funcp; funcp = funcp->next)
7164                 cnt += 3;
7165 # endif
7166         pp = g_argv;
7167         while (*pp++)
7168                 cnt++;
7169         *to_free = argv = pp = xzalloc(sizeof(argv[0]) * cnt);
7170         *pp++ = (char *) G.argv0_for_re_execing;
7171         *pp++ = param_buf;
7172         for (cur = G.top_var; cur; cur = cur->next) {
7173                 if (strcmp(cur->varstr, hush_version_str) == 0)
7174                         continue;
7175                 if (cur->flg_read_only) {
7176                         *pp++ = (char *) "-R";
7177                         *pp++ = cur->varstr;
7178                 } else if (!cur->flg_export) {
7179                         *pp++ = (char *) "-V";
7180                         *pp++ = cur->varstr;
7181                 }
7182         }
7183 # if ENABLE_HUSH_FUNCTIONS
7184         for (funcp = G.top_func; funcp; funcp = funcp->next) {
7185                 *pp++ = (char *) "-F";
7186                 *pp++ = funcp->name;
7187                 *pp++ = funcp->body_as_string;
7188         }
7189 # endif
7190         /* We can pass activated traps here. Say, -Tnn:trap_string
7191          *
7192          * However, POSIX says that subshells reset signals with traps
7193          * to SIG_DFL.
7194          * I tested bash-3.2 and it not only does that with true subshells
7195          * of the form ( list ), but with any forked children shells.
7196          * I set trap "echo W" WINCH; and then tried:
7197          *
7198          * { echo 1; sleep 20; echo 2; } &
7199          * while true; do echo 1; sleep 20; echo 2; break; done &
7200          * true | { echo 1; sleep 20; echo 2; } | cat
7201          *
7202          * In all these cases sending SIGWINCH to the child shell
7203          * did not run the trap. If I add trap "echo V" WINCH;
7204          * _inside_ group (just before echo 1), it works.
7205          *
7206          * I conclude it means we don't need to pass active traps here.
7207          */
7208         *pp++ = (char *) "-c";
7209         *pp++ = (char *) s;
7210         if (builtin_argv) {
7211                 while (*++builtin_argv)
7212                         *pp++ = *builtin_argv;
7213                 *pp++ = (char *) "";
7214         }
7215         *pp++ = g_argv0;
7216         while (*g_argv)
7217                 *pp++ = *g_argv++;
7218         /* *pp = NULL; - is already there */
7219         pp = environ;
7220
7221  do_exec:
7222         debug_printf_exec("re_execute_shell pid:%d cmd:'%s'\n", getpid(), s);
7223         /* Don't propagate SIG_IGN to the child */
7224         if (SPECIAL_JOBSTOP_SIGS != 0)
7225                 switch_off_special_sigs(G.special_sig_mask & SPECIAL_JOBSTOP_SIGS);
7226         execve(bb_busybox_exec_path, argv, pp);
7227         /* Fallback. Useful for init=/bin/hush usage etc */
7228         if (argv[0][0] == '/')
7229                 execve(argv[0], argv, pp);
7230         xfunc_error_retval = 127;
7231         bb_simple_error_msg_and_die("can't re-execute the shell");
7232 }
7233 #endif  /* !BB_MMU */
7234
7235
7236 static int run_and_free_list(struct pipe *pi);
7237
7238 /* Executing from string: eval, sh -c '...'
7239  *          or from file: /etc/profile, . file, sh <script>, sh (intereactive)
7240  * end_trigger controls how often we stop parsing
7241  * NUL: parse all, execute, return
7242  * ';': parse till ';' or newline, execute, repeat till EOF
7243  */
7244 static void parse_and_run_stream(struct in_str *inp, int end_trigger)
7245 {
7246         /* Why we need empty flag?
7247          * An obscure corner case "false; ``; echo $?":
7248          * empty command in `` should still set $? to 0.
7249          * But we can't just set $? to 0 at the start,
7250          * this breaks "false; echo `echo $?`" case.
7251          */
7252         bool empty = 1;
7253         while (1) {
7254                 struct pipe *pipe_list;
7255
7256 #if ENABLE_HUSH_INTERACTIVE
7257                 if (end_trigger == ';') {
7258                         G.promptmode = 0; /* PS1 */
7259                         debug_printf_prompt("%s promptmode=%d\n", __func__, G.promptmode);
7260                 }
7261 #endif
7262                 pipe_list = parse_stream(NULL, NULL, inp, end_trigger);
7263                 if (!pipe_list || pipe_list == ERR_PTR) { /* EOF/error */
7264                         /* If we are in "big" script
7265                          * (not in `cmd` or something similar)...
7266                          */
7267                         if (pipe_list == ERR_PTR && end_trigger == ';') {
7268                                 /* Discard cached input (rest of line) */
7269                                 int ch = inp->last_char;
7270                                 while (ch != EOF && ch != '\n') {
7271                                         //bb_error_msg("Discarded:'%c'", ch);
7272                                         ch = i_getch(inp);
7273                                 }
7274                                 /* Force prompt */
7275                                 inp->p = NULL;
7276                                 /* This stream isn't empty */
7277                                 empty = 0;
7278                                 continue;
7279                         }
7280                         if (!pipe_list && empty)
7281                                 G.last_exitcode = 0;
7282                         break;
7283                 }
7284                 debug_print_tree(pipe_list, 0);
7285                 debug_printf_exec("parse_and_run_stream: run_and_free_list\n");
7286                 run_and_free_list(pipe_list);
7287                 empty = 0;
7288                 if (G_flag_return_in_progress == 1)
7289                         break;
7290         }
7291 }
7292
7293 static void parse_and_run_string(const char *s)
7294 {
7295         struct in_str input;
7296         //IF_HUSH_LINENO_VAR(unsigned sv = G.parse_lineno;)
7297
7298         setup_string_in_str(&input, s);
7299         parse_and_run_stream(&input, '\0');
7300         //IF_HUSH_LINENO_VAR(G.parse_lineno = sv;)
7301 }
7302
7303 static void parse_and_run_file(HFILE *fp)
7304 {
7305         struct in_str input;
7306         IF_HUSH_LINENO_VAR(unsigned sv = G.parse_lineno;)
7307
7308         IF_HUSH_LINENO_VAR(G.parse_lineno = 1;)
7309         setup_file_in_str(&input, fp);
7310         parse_and_run_stream(&input, ';');
7311         IF_HUSH_LINENO_VAR(G.parse_lineno = sv;)
7312 }
7313
7314 #if ENABLE_HUSH_TICK
7315 static int generate_stream_from_string(const char *s, pid_t *pid_p)
7316 {
7317         pid_t pid;
7318         int channel[2];
7319 # if !BB_MMU
7320         char **to_free = NULL;
7321 # endif
7322
7323         xpipe(channel);
7324         pid = BB_MMU ? xfork() : xvfork();
7325         if (pid == 0) { /* child */
7326                 disable_restore_tty_pgrp_on_exit();
7327                 /* Process substitution is not considered to be usual
7328                  * 'command execution'.
7329                  * SUSv3 says ctrl-Z should be ignored, ctrl-C should not.
7330                  */
7331                 bb_signals(0
7332                         + (1 << SIGTSTP)
7333                         + (1 << SIGTTIN)
7334                         + (1 << SIGTTOU)
7335                         , SIG_IGN);
7336                 close(channel[0]); /* NB: close _first_, then move fd! */
7337                 xmove_fd(channel[1], 1);
7338 # if ENABLE_HUSH_TRAP
7339                 /* Awful hack for `trap` or $(trap).
7340                  *
7341                  * http://www.opengroup.org/onlinepubs/009695399/utilities/trap.html
7342                  * contains an example where "trap" is executed in a subshell:
7343                  *
7344                  * save_traps=$(trap)
7345                  * ...
7346                  * eval "$save_traps"
7347                  *
7348                  * Standard does not say that "trap" in subshell shall print
7349                  * parent shell's traps. It only says that its output
7350                  * must have suitable form, but then, in the above example
7351                  * (which is not supposed to be normative), it implies that.
7352                  *
7353                  * bash (and probably other shell) does implement it
7354                  * (traps are reset to defaults, but "trap" still shows them),
7355                  * but as a result, "trap" logic is hopelessly messed up:
7356                  *
7357                  * # trap
7358                  * trap -- 'echo Ho' SIGWINCH  <--- we have a handler
7359                  * # (trap)        <--- trap is in subshell - no output (correct, traps are reset)
7360                  * # true | trap   <--- trap is in subshell - no output (ditto)
7361                  * # echo `true | trap`    <--- in subshell - output (but traps are reset!)
7362                  * trap -- 'echo Ho' SIGWINCH
7363                  * # echo `(trap)`         <--- in subshell in subshell - output
7364                  * trap -- 'echo Ho' SIGWINCH
7365                  * # echo `true | (trap)`  <--- in subshell in subshell in subshell - output!
7366                  * trap -- 'echo Ho' SIGWINCH
7367                  *
7368                  * The rules when to forget and when to not forget traps
7369                  * get really complex and nonsensical.
7370                  *
7371                  * Our solution: ONLY bare $(trap) or `trap` is special.
7372                  */
7373                 s = skip_whitespace(s);
7374                 if (is_prefixed_with(s, "trap")
7375                  && skip_whitespace(s + 4)[0] == '\0'
7376                 ) {
7377                         static const char *const argv[] = { NULL, NULL };
7378                         builtin_trap((char**)argv);
7379                         fflush_all(); /* important */
7380                         _exit(0);
7381                 }
7382 # endif
7383 # if BB_MMU
7384                 /* Prevent it from trying to handle ctrl-z etc */
7385                 IF_HUSH_JOB(G.run_list_level = 1;)
7386                 CLEAR_RANDOM_T(&G.random_gen); /* or else $RANDOM repeats in child */
7387                 reset_traps_to_defaults();
7388                 IF_HUSH_MODE_X(G.x_mode_depth++;)
7389                 //bb_error_msg("%s: ++x_mode_depth=%d", __func__, G.x_mode_depth);
7390                 parse_and_run_string(s);
7391                 _exit(G.last_exitcode);
7392 # else
7393         /* We re-execute after vfork on NOMMU. This makes this script safe:
7394          * yes "0123456789012345678901234567890" | dd bs=32 count=64k >BIG
7395          * huge=`cat BIG` # was blocking here forever
7396          * echo OK
7397          */
7398                 re_execute_shell(&to_free,
7399                                 s,
7400                                 G.global_argv[0],
7401                                 G.global_argv + 1,
7402                                 NULL);
7403 # endif
7404         }
7405
7406         /* parent */
7407         *pid_p = pid;
7408 # if ENABLE_HUSH_FAST
7409         G.count_SIGCHLD++;
7410 //bb_error_msg("[%d] fork in generate_stream_from_string:"
7411 //              " G.count_SIGCHLD:%d G.handled_SIGCHLD:%d",
7412 //              getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
7413 # endif
7414         enable_restore_tty_pgrp_on_exit();
7415 # if !BB_MMU
7416         free(to_free);
7417 # endif
7418         close(channel[1]);
7419         return channel[0];
7420 }
7421
7422 /* Return code is exit status of the process that is run. */
7423 static int process_command_subs(o_string *dest, const char *s)
7424 {
7425         FILE *fp;
7426         pid_t pid;
7427         int status, ch, eol_cnt;
7428
7429         fp = xfdopen_for_read(generate_stream_from_string(s, &pid));
7430
7431         /* Now send results of command back into original context */
7432         eol_cnt = 0;
7433         while ((ch = getc(fp)) != EOF) {
7434                 if (ch == '\0')
7435                         continue;
7436                 if (ch == '\n') {
7437                         eol_cnt++;
7438                         continue;
7439                 }
7440                 while (eol_cnt) {
7441                         o_addchr(dest, '\n');
7442                         eol_cnt--;
7443                 }
7444                 o_addQchr(dest, ch);
7445         }
7446
7447         debug_printf("done reading from `cmd` pipe, closing it\n");
7448         fclose(fp);
7449         /* We need to extract exitcode. Test case
7450          * "true; echo `sleep 1; false` $?"
7451          * should print 1 */
7452         safe_waitpid(pid, &status, 0);
7453         debug_printf("child exited. returning its exitcode:%d\n", WEXITSTATUS(status));
7454         return WEXITSTATUS(status);
7455 }
7456 #endif /* ENABLE_HUSH_TICK */
7457
7458
7459 static void setup_heredoc(struct redir_struct *redir)
7460 {
7461         struct fd_pair pair;
7462         pid_t pid;
7463         int len, written;
7464         /* the _body_ of heredoc (misleading field name) */
7465         const char *heredoc = redir->rd_filename;
7466         char *expanded;
7467 #if !BB_MMU
7468         char **to_free;
7469 #endif
7470
7471         expanded = NULL;
7472         if (!(redir->rd_dup & HEREDOC_QUOTED)) {
7473                 expanded = encode_then_expand_string(heredoc);
7474                 if (expanded)
7475                         heredoc = expanded;
7476         }
7477         len = strlen(heredoc);
7478
7479         close(redir->rd_fd); /* often saves dup2+close in xmove_fd */
7480         xpiped_pair(pair);
7481         xmove_fd(pair.rd, redir->rd_fd);
7482
7483         /* Try writing without forking. Newer kernels have
7484          * dynamically growing pipes. Must use non-blocking write! */
7485         ndelay_on(pair.wr);
7486         while (1) {
7487                 written = write(pair.wr, heredoc, len);
7488                 if (written <= 0)
7489                         break;
7490                 len -= written;
7491                 if (len == 0) {
7492                         close(pair.wr);
7493                         free(expanded);
7494                         return;
7495                 }
7496                 heredoc += written;
7497         }
7498         ndelay_off(pair.wr);
7499
7500         /* Okay, pipe buffer was not big enough */
7501         /* Note: we must not create a stray child (bastard? :)
7502          * for the unsuspecting parent process. Child creates a grandchild
7503          * and exits before parent execs the process which consumes heredoc
7504          * (that exec happens after we return from this function) */
7505 #if !BB_MMU
7506         to_free = NULL;
7507 #endif
7508         pid = xvfork();
7509         if (pid == 0) {
7510                 /* child */
7511                 disable_restore_tty_pgrp_on_exit();
7512                 pid = BB_MMU ? xfork() : xvfork();
7513                 if (pid != 0)
7514                         _exit(0);
7515                 /* grandchild */
7516                 close(redir->rd_fd); /* read side of the pipe */
7517 #if BB_MMU
7518                 full_write(pair.wr, heredoc, len); /* may loop or block */
7519                 _exit(0);
7520 #else
7521                 /* Delegate blocking writes to another process */
7522                 xmove_fd(pair.wr, STDOUT_FILENO);
7523                 re_execute_shell(&to_free, heredoc, NULL, NULL, NULL);
7524 #endif
7525         }
7526         /* parent */
7527 #if ENABLE_HUSH_FAST
7528         G.count_SIGCHLD++;
7529 //bb_error_msg("[%d] fork in setup_heredoc: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
7530 #endif
7531         enable_restore_tty_pgrp_on_exit();
7532 #if !BB_MMU
7533         free(to_free);
7534 #endif
7535         close(pair.wr);
7536         free(expanded);
7537         wait(NULL); /* wait till child has died */
7538 }
7539
7540 struct squirrel {
7541         int orig_fd;
7542         int moved_to;
7543         /* moved_to = n: fd was moved to n; restore back to orig_fd after redir */
7544         /* moved_to = -1: fd was opened by redirect; close orig_fd after redir */
7545 };
7546
7547 static struct squirrel *append_squirrel(struct squirrel *sq, int i, int orig, int moved)
7548 {
7549         sq = xrealloc(sq, (i + 2) * sizeof(sq[0]));
7550         sq[i].orig_fd = orig;
7551         sq[i].moved_to = moved;
7552         sq[i+1].orig_fd = -1; /* end marker */
7553         return sq;
7554 }
7555
7556 static struct squirrel *add_squirrel(struct squirrel *sq, int fd, int avoid_fd)
7557 {
7558         int moved_to;
7559         int i;
7560
7561         i = 0;
7562         if (sq) for (; sq[i].orig_fd >= 0; i++) {
7563                 /* If we collide with an already moved fd... */
7564                 if (fd == sq[i].moved_to) {
7565                         sq[i].moved_to = dup_CLOEXEC(sq[i].moved_to, avoid_fd);
7566                         debug_printf_redir("redirect_fd %d: already busy, moving to %d\n", fd, sq[i].moved_to);
7567                         if (sq[i].moved_to < 0) /* what? */
7568                                 xfunc_die();
7569                         return sq;
7570                 }
7571                 if (fd == sq[i].orig_fd) {
7572                         /* Example: echo Hello >/dev/null 1>&2 */
7573                         debug_printf_redir("redirect_fd %d: already moved\n", fd);
7574                         return sq;
7575                 }
7576         }
7577
7578         /* If this fd is open, we move and remember it; if it's closed, moved_to = -1 */
7579         moved_to = dup_CLOEXEC(fd, avoid_fd);
7580         debug_printf_redir("redirect_fd %d: previous fd is moved to %d (-1 if it was closed)\n", fd, moved_to);
7581         if (moved_to < 0 && errno != EBADF)
7582                 xfunc_die();
7583         return append_squirrel(sq, i, fd, moved_to);
7584 }
7585
7586 static struct squirrel *add_squirrel_closed(struct squirrel *sq, int fd)
7587 {
7588         int i;
7589
7590         i = 0;
7591         if (sq) for (; sq[i].orig_fd >= 0; i++) {
7592                 /* If we collide with an already moved fd... */
7593                 if (fd == sq[i].orig_fd) {
7594                         /* Examples:
7595                          * "echo 3>FILE 3>&- 3>FILE"
7596                          * "echo 3>&- 3>FILE"
7597                          * No need for last redirect to insert
7598                          * another "need to close 3" indicator.
7599                          */
7600                         debug_printf_redir("redirect_fd %d: already moved or closed\n", fd);
7601                         return sq;
7602                 }
7603         }
7604
7605         debug_printf_redir("redirect_fd %d: previous fd was closed\n", fd);
7606         return append_squirrel(sq, i, fd, -1);
7607 }
7608
7609 /* fd: redirect wants this fd to be used (e.g. 3>file).
7610  * Move all conflicting internally used fds,
7611  * and remember them so that we can restore them later.
7612  */
7613 static int save_fd_on_redirect(int fd, int avoid_fd, struct squirrel **sqp)
7614 {
7615         if (avoid_fd < 9) /* the important case here is that it can be -1 */
7616                 avoid_fd = 9;
7617
7618 #if ENABLE_HUSH_INTERACTIVE
7619         if (fd != 0 /* don't trigger for G_interactive_fd == 0 (that's "not interactive" flag) */
7620          && fd == G_interactive_fd
7621         ) {
7622                 /* Testcase: "ls -l /proc/$$/fd 255>&-" should work */
7623                 G_interactive_fd = xdup_CLOEXEC_and_close(G_interactive_fd, avoid_fd);
7624                 debug_printf_redir("redirect_fd %d: matches interactive_fd, moving it to %d\n", fd, G_interactive_fd);
7625                 return 1; /* "we closed fd" */
7626         }
7627 #endif
7628         /* Are we called from setup_redirects(squirrel==NULL)
7629          * in redirect in a [v]forked child?
7630          */
7631         if (sqp == NULL) {
7632                 /* No need to move script fds.
7633                  * For NOMMU case, it's actively wrong: we'd change ->fd
7634                  * fields in memory for the parent, but parent's fds
7635                  * aren't moved, it would use wrong fd!
7636                  * Reproducer: "cmd 3>FILE" in script.
7637                  * If we would call move_HFILEs_on_redirect(), child would:
7638                  *  fcntl64(3, F_DUPFD_CLOEXEC, 10)   = 10
7639                  *  close(3)                          = 0
7640                  * and change ->fd to 10 if fd#3 is a script fd. WRONG.
7641                  */
7642                 //bb_error_msg("sqp == NULL: [v]forked child");
7643                 return 0;
7644         }
7645
7646         /* If this one of script's fds? */
7647         if (move_HFILEs_on_redirect(fd, avoid_fd))
7648                 return 1; /* yes. "we closed fd" (actually moved it) */
7649
7650         /* Are we called for "exec 3>FILE"? Came through
7651          * redirect_and_varexp_helper(squirrel=ERR_PTR) -> setup_redirects(ERR_PTR)
7652          * This case used to fail for this script:
7653          *  exec 3>FILE
7654          *  echo Ok
7655          *  ...100000 more lines...
7656          *  echo Ok
7657          * as follows:
7658          *  read(3, "exec 3>FILE\necho Ok\necho Ok"..., 1024) = 1024
7659          *  open("FILE", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 4
7660          *  dup2(4, 3)                        = 3
7661          *  ^^^^^^^^ oops, we lost fd#3 opened to our script!
7662          *  close(4)                          = 0
7663          *  write(1, "Ok\n", 3)               = 3
7664          *  ...                               = 3
7665          *  write(1, "Ok\n", 3)               = 3
7666          *  read(3, 0x94fbc08, 1024)          = -1 EBADF (Bad file descriptor)
7667          *  ^^^^^^^^ oops, wrong fd!!!
7668          * With this case separate from sqp == NULL and *after* move_HFILEs,
7669          * it now works:
7670          */
7671         if (sqp == ERR_PTR) {
7672                 /* Don't preserve redirected fds: exec is _meant_ to change these */
7673                 //bb_error_msg("sqp == ERR_PTR: exec >FILE");
7674                 return 0;
7675         }
7676
7677         /* Check whether it collides with any open fds (e.g. stdio), save fds as needed */
7678         *sqp = add_squirrel(*sqp, fd, avoid_fd);
7679         return 0; /* "we did not close fd" */
7680 }
7681
7682 static void restore_redirects(struct squirrel *sq)
7683 {
7684         if (sq) {
7685                 int i;
7686                 for (i = 0; sq[i].orig_fd >= 0; i++) {
7687                         if (sq[i].moved_to >= 0) {
7688                                 /* We simply die on error */
7689                                 debug_printf_redir("restoring redirected fd from %d to %d\n", sq[i].moved_to, sq[i].orig_fd);
7690                                 xmove_fd(sq[i].moved_to, sq[i].orig_fd);
7691                         } else {
7692                                 /* cmd1 9>FILE; cmd2_should_see_fd9_closed */
7693                                 debug_printf_redir("restoring redirected fd %d: closing it\n", sq[i].orig_fd);
7694                                 close(sq[i].orig_fd);
7695                         }
7696                 }
7697                 free(sq);
7698         }
7699         if (G.HFILE_stdin
7700          && G.HFILE_stdin->fd != STDIN_FILENO
7701         ) {
7702                 /* Testcase: interactive "read r <FILE; echo $r; read r; echo $r".
7703                  * Redirect moves ->fd to e.g. 10,
7704                  * and it is not restored above (we do not restore script fds
7705                  * after redirects, we just use new, "moved" fds).
7706                  * However for stdin, get_user_input() -> read_line_input(),
7707                  * and read builtin, depend on fd == STDIN_FILENO.
7708                  */
7709                 debug_printf_redir("restoring %d to stdin\n", G.HFILE_stdin->fd);
7710                 xmove_fd(G.HFILE_stdin->fd, STDIN_FILENO);
7711                 G.HFILE_stdin->fd = STDIN_FILENO;
7712         }
7713
7714         /* If moved, G_interactive_fd stays on new fd, not restoring it */
7715 }
7716
7717 #if ENABLE_FEATURE_SH_STANDALONE && BB_MMU
7718 static void close_saved_fds_and_FILE_fds(void)
7719 {
7720         if (G_interactive_fd)
7721                 close(G_interactive_fd);
7722         close_all_HFILE_list();
7723 }
7724 #endif
7725
7726 static int internally_opened_fd(int fd, struct squirrel *sq)
7727 {
7728         int i;
7729
7730 #if ENABLE_HUSH_INTERACTIVE
7731         if (fd == G_interactive_fd)
7732                 return 1;
7733 #endif
7734         /* If this one of script's fds? */
7735         if (fd_in_HFILEs(fd))
7736                 return 1;
7737
7738         if (sq) for (i = 0; sq[i].orig_fd >= 0; i++) {
7739                 if (fd == sq[i].moved_to)
7740                         return 1;
7741         }
7742         return 0;
7743 }
7744
7745 /* squirrel != NULL means we squirrel away copies of stdin, stdout,
7746  * and stderr if they are redirected. */
7747 static int setup_redirects(struct command *prog, struct squirrel **sqp)
7748 {
7749         struct redir_struct *redir;
7750
7751         for (redir = prog->redirects; redir; redir = redir->next) {
7752                 int newfd;
7753                 int closed;
7754
7755                 if (redir->rd_type == REDIRECT_HEREDOC2) {
7756                         /* "rd_fd<<HERE" case */
7757                         save_fd_on_redirect(redir->rd_fd, /*avoid:*/ 0, sqp);
7758                         /* for REDIRECT_HEREDOC2, rd_filename holds _contents_
7759                          * of the heredoc */
7760                         debug_printf_redir("set heredoc '%s'\n",
7761                                         redir->rd_filename);
7762                         setup_heredoc(redir);
7763                         continue;
7764                 }
7765
7766                 if (redir->rd_dup == REDIRFD_TO_FILE) {
7767                         /* "rd_fd<*>file" case (<*> is <,>,>>,<>) */
7768                         char *p;
7769                         int mode;
7770
7771                         if (redir->rd_filename == NULL) {
7772                                 /* Examples:
7773                                  * "cmd >" (no filename)
7774                                  * "cmd > <file" (2nd redirect starts too early)
7775                                  */
7776                                 syntax_error("invalid redirect");
7777                                 continue;
7778                         }
7779                         mode = redir_table[redir->rd_type].mode;
7780                         p = expand_string_to_string(redir->rd_filename,
7781                                 EXP_FLAG_ESC_GLOB_CHARS, /*unbackslash:*/ 1);
7782                         newfd = open_or_warn(p, mode);
7783                         free(p);
7784                         if (newfd < 0) {
7785                                 /* Error message from open_or_warn can be lost
7786                                  * if stderr has been redirected, but bash
7787                                  * and ash both lose it as well
7788                                  * (though zsh doesn't!)
7789                                  */
7790                                 return 1;
7791                         }
7792                         if (newfd == redir->rd_fd && sqp) {
7793                                 /* open() gave us precisely the fd we wanted.
7794                                  * This means that this fd was not busy
7795                                  * (not opened to anywhere).
7796                                  * Remember to close it on restore:
7797                                  */
7798                                 *sqp = add_squirrel_closed(*sqp, newfd);
7799                                 debug_printf_redir("redir to previously closed fd %d\n", newfd);
7800                         }
7801                 } else {
7802                         /* "rd_fd>&rd_dup" or "rd_fd>&-" case */
7803                         newfd = redir->rd_dup;
7804                 }
7805
7806                 if (newfd == redir->rd_fd)
7807                         continue;
7808
7809                 /* if "N>FILE": move newfd to redir->rd_fd */
7810                 /* if "N>&M": dup newfd to redir->rd_fd */
7811                 /* if "N>&-": close redir->rd_fd (newfd is REDIRFD_CLOSE) */
7812
7813                 closed = save_fd_on_redirect(redir->rd_fd, /*avoid:*/ newfd, sqp);
7814                 if (newfd == REDIRFD_CLOSE) {
7815                         /* "N>&-" means "close me" */
7816                         if (!closed) {
7817                                 /* ^^^ optimization: saving may already
7818                                  * have closed it. If not... */
7819                                 close(redir->rd_fd);
7820                         }
7821                         /* Sometimes we do another close on restore, getting EBADF.
7822                          * Consider "echo 3>FILE 3>&-"
7823                          * first redirect remembers "need to close 3",
7824                          * and second redirect closes 3! Restore code then closes 3 again.
7825                          */
7826                 } else {
7827                         /* if newfd is a script fd or saved fd, simulate EBADF */
7828                         if (internally_opened_fd(newfd, sqp && sqp != ERR_PTR ? *sqp : NULL)) {
7829                                 //errno = EBADF;
7830                                 //bb_perror_msg_and_die("can't duplicate file descriptor");
7831                                 newfd = -1; /* same effect as code above */
7832                         }
7833                         xdup2(newfd, redir->rd_fd);
7834                         if (redir->rd_dup == REDIRFD_TO_FILE)
7835                                 /* "rd_fd > FILE" */
7836                                 close(newfd);
7837                         /* else: "rd_fd > rd_dup" */
7838                 }
7839         }
7840         return 0;
7841 }
7842
7843 static char *find_in_path(const char *arg)
7844 {
7845         char *ret = NULL;
7846         const char *PATH = get_local_var_value("PATH");
7847
7848         if (!PATH)
7849                 return NULL;
7850
7851         while (1) {
7852                 const char *end = strchrnul(PATH, ':');
7853                 int sz = end - PATH; /* must be int! */
7854
7855                 free(ret);
7856                 if (sz != 0) {
7857                         ret = xasprintf("%.*s/%s", sz, PATH, arg);
7858                 } else {
7859                         /* We have xxx::yyyy in $PATH,
7860                          * it means "use current dir" */
7861                         ret = xstrdup(arg);
7862                 }
7863                 if (access(ret, F_OK) == 0)
7864                         break;
7865
7866                 if (*end == '\0') {
7867                         free(ret);
7868                         return NULL;
7869                 }
7870                 PATH = end + 1;
7871         }
7872
7873         return ret;
7874 }
7875
7876 static const struct built_in_command *find_builtin_helper(const char *name,
7877                 const struct built_in_command *x,
7878                 const struct built_in_command *end)
7879 {
7880         while (x != end) {
7881                 if (strcmp(name, x->b_cmd) != 0) {
7882                         x++;
7883                         continue;
7884                 }
7885                 debug_printf_exec("found builtin '%s'\n", name);
7886                 return x;
7887         }
7888         return NULL;
7889 }
7890 static const struct built_in_command *find_builtin1(const char *name)
7891 {
7892         return find_builtin_helper(name, bltins1, &bltins1[ARRAY_SIZE(bltins1)]);
7893 }
7894 static const struct built_in_command *find_builtin(const char *name)
7895 {
7896         const struct built_in_command *x = find_builtin1(name);
7897         if (x)
7898                 return x;
7899         return find_builtin_helper(name, bltins2, &bltins2[ARRAY_SIZE(bltins2)]);
7900 }
7901
7902 #if EDITING_HAS_get_exe_name
7903 static const char * FAST_FUNC get_builtin_name(int i)
7904 {
7905         if (/*i >= 0 && */ i < ARRAY_SIZE(bltins1)) {
7906                 return bltins1[i].b_cmd;
7907         }
7908         i -= ARRAY_SIZE(bltins1);
7909         if (i < ARRAY_SIZE(bltins2)) {
7910                 return bltins2[i].b_cmd;
7911         }
7912         return NULL;
7913 }
7914 #endif
7915
7916 static void remove_nested_vars(void)
7917 {
7918         struct variable *cur;
7919         struct variable **cur_pp;
7920
7921         cur_pp = &G.top_var;
7922         while ((cur = *cur_pp) != NULL) {
7923                 if (cur->var_nest_level <= G.var_nest_level) {
7924                         cur_pp = &cur->next;
7925                         continue;
7926                 }
7927                 /* Unexport */
7928                 if (cur->flg_export) {
7929                         debug_printf_env("unexporting nested '%s'/%u\n", cur->varstr, cur->var_nest_level);
7930                         bb_unsetenv(cur->varstr);
7931                 }
7932                 /* Remove from global list */
7933                 *cur_pp = cur->next;
7934                 /* Free */
7935                 if (!cur->max_len) {
7936                         debug_printf_env("freeing nested '%s'/%u\n", cur->varstr, cur->var_nest_level);
7937                         free(cur->varstr);
7938                 }
7939                 free(cur);
7940         }
7941 }
7942
7943 static void enter_var_nest_level(void)
7944 {
7945         G.var_nest_level++;
7946         debug_printf_env("var_nest_level++ %u\n", G.var_nest_level);
7947
7948         /* Try: f() { echo -n .; f; }; f
7949          * struct variable::var_nest_level is uint16_t,
7950          * thus limiting recursion to < 2^16.
7951          * In any case, with 8 Mbyte stack SEGV happens
7952          * not too long after 2^16 recursions anyway.
7953          */
7954         if (G.var_nest_level > 0xff00)
7955                 bb_error_msg_and_die("fatal recursion (depth %u)", G.var_nest_level);
7956 }
7957
7958 static void leave_var_nest_level(void)
7959 {
7960         G.var_nest_level--;
7961         debug_printf_env("var_nest_level-- %u\n", G.var_nest_level);
7962         if (HUSH_DEBUG && (int)G.var_nest_level < 0)
7963                 bb_simple_error_msg_and_die("BUG: nesting underflow");
7964
7965         remove_nested_vars();
7966 }
7967
7968 #if ENABLE_HUSH_FUNCTIONS
7969 static struct function **find_function_slot(const char *name)
7970 {
7971         struct function *funcp;
7972         struct function **funcpp = &G.top_func;
7973
7974         while ((funcp = *funcpp) != NULL) {
7975                 if (strcmp(name, funcp->name) == 0) {
7976                         debug_printf_exec("found function '%s'\n", name);
7977                         break;
7978                 }
7979                 funcpp = &funcp->next;
7980         }
7981         return funcpp;
7982 }
7983
7984 static ALWAYS_INLINE const struct function *find_function(const char *name)
7985 {
7986         const struct function *funcp = *find_function_slot(name);
7987         return funcp;
7988 }
7989
7990 /* Note: takes ownership on name ptr */
7991 static struct function *new_function(char *name)
7992 {
7993         struct function **funcpp = find_function_slot(name);
7994         struct function *funcp = *funcpp;
7995
7996         if (funcp != NULL) {
7997                 struct command *cmd = funcp->parent_cmd;
7998                 debug_printf_exec("func %p parent_cmd %p\n", funcp, cmd);
7999                 if (!cmd) {
8000                         debug_printf_exec("freeing & replacing function '%s'\n", funcp->name);
8001                         free(funcp->name);
8002                         /* Note: if !funcp->body, do not free body_as_string!
8003                          * This is a special case of "-F name body" function:
8004                          * body_as_string was not malloced! */
8005                         if (funcp->body) {
8006                                 free_pipe_list(funcp->body);
8007 # if !BB_MMU
8008                                 free(funcp->body_as_string);
8009 # endif
8010                         }
8011                 } else {
8012                         debug_printf_exec("reinserting in tree & replacing function '%s'\n", funcp->name);
8013                         cmd->argv[0] = funcp->name;
8014                         cmd->group = funcp->body;
8015 # if !BB_MMU
8016                         cmd->group_as_string = funcp->body_as_string;
8017 # endif
8018                 }
8019         } else {
8020                 debug_printf_exec("remembering new function '%s'\n", name);
8021                 funcp = *funcpp = xzalloc(sizeof(*funcp));
8022                 /*funcp->next = NULL;*/
8023         }
8024
8025         funcp->name = name;
8026         return funcp;
8027 }
8028
8029 # if ENABLE_HUSH_UNSET
8030 static void unset_func(const char *name)
8031 {
8032         struct function **funcpp = find_function_slot(name);
8033         struct function *funcp = *funcpp;
8034
8035         if (funcp != NULL) {
8036                 debug_printf_exec("freeing function '%s'\n", funcp->name);
8037                 *funcpp = funcp->next;
8038                 /* funcp is unlinked now, deleting it.
8039                  * Note: if !funcp->body, the function was created by
8040                  * "-F name body", do not free ->body_as_string
8041                  * and ->name as they were not malloced. */
8042                 if (funcp->body) {
8043                         free_pipe_list(funcp->body);
8044                         free(funcp->name);
8045 #  if !BB_MMU
8046                         free(funcp->body_as_string);
8047 #  endif
8048                 }
8049                 free(funcp);
8050         }
8051 }
8052 # endif
8053
8054 # if BB_MMU
8055 #define exec_function(to_free, funcp, argv) \
8056         exec_function(funcp, argv)
8057 # endif
8058 static void exec_function(char ***to_free,
8059                 const struct function *funcp,
8060                 char **argv) NORETURN;
8061 static void exec_function(char ***to_free,
8062                 const struct function *funcp,
8063                 char **argv)
8064 {
8065 # if BB_MMU
8066         int n;
8067
8068         argv[0] = G.global_argv[0];
8069         G.global_argv = argv;
8070         G.global_argc = n = 1 + string_array_len(argv + 1);
8071
8072 // Example when we are here: "cmd | func"
8073 // func will run with saved-redirect fds open.
8074 // $ f() { echo /proc/self/fd/*; }
8075 // $ true | f
8076 // /proc/self/fd/0 /proc/self/fd/1 /proc/self/fd/2 /proc/self/fd/255 /proc/self/fd/3
8077 // stdio^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ G_interactive_fd^ DIR fd for glob
8078 // Same in script:
8079 // $ . ./SCRIPT
8080 // /proc/self/fd/0 /proc/self/fd/1 /proc/self/fd/2 /proc/self/fd/255 /proc/self/fd/3 /proc/self/fd/4
8081 // stdio^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ G_interactive_fd^ opened ./SCRIPT DIR fd for glob
8082 // They are CLOEXEC so external programs won't see them, but
8083 // for "more correctness" we might want to close those extra fds here:
8084 //?     close_saved_fds_and_FILE_fds();
8085
8086         /* "we are in a function, ok to use return" */
8087         G_flag_return_in_progress = -1;
8088         enter_var_nest_level();
8089         IF_HUSH_LOCAL(G.func_nest_level++;)
8090
8091         /* On MMU, funcp->body is always non-NULL */
8092         n = run_list(funcp->body);
8093         fflush_all();
8094         _exit(n);
8095 # else
8096 //?     close_saved_fds_and_FILE_fds();
8097
8098 //TODO: check whether "true | func_with_return" works
8099
8100         re_execute_shell(to_free,
8101                         funcp->body_as_string,
8102                         G.global_argv[0],
8103                         argv + 1,
8104                         NULL);
8105 # endif
8106 }
8107
8108 static int run_function(const struct function *funcp, char **argv)
8109 {
8110         int rc;
8111         save_arg_t sv;
8112         smallint sv_flg;
8113
8114         save_and_replace_G_args(&sv, argv);
8115
8116         /* "We are in function, ok to use return" */
8117         sv_flg = G_flag_return_in_progress;
8118         G_flag_return_in_progress = -1;
8119
8120         /* Make "local" variables properly shadow previous ones */
8121         IF_HUSH_LOCAL(enter_var_nest_level();)
8122         IF_HUSH_LOCAL(G.func_nest_level++;)
8123
8124         /* On MMU, funcp->body is always non-NULL */
8125 # if !BB_MMU
8126         if (!funcp->body) {
8127                 /* Function defined by -F */
8128                 parse_and_run_string(funcp->body_as_string);
8129                 rc = G.last_exitcode;
8130         } else
8131 # endif
8132         {
8133                 rc = run_list(funcp->body);
8134         }
8135
8136         IF_HUSH_LOCAL(G.func_nest_level--;)
8137         IF_HUSH_LOCAL(leave_var_nest_level();)
8138
8139         G_flag_return_in_progress = sv_flg;
8140 # if ENABLE_HUSH_TRAP
8141         debug_printf_exec("G.return_exitcode=-1\n");
8142         G.return_exitcode = -1; /* invalidate stashed return value */
8143 # endif
8144
8145         restore_G_args(&sv, argv);
8146
8147         return rc;
8148 }
8149 #endif /* ENABLE_HUSH_FUNCTIONS */
8150
8151
8152 #if BB_MMU
8153 #define exec_builtin(to_free, x, argv) \
8154         exec_builtin(x, argv)
8155 #else
8156 #define exec_builtin(to_free, x, argv) \
8157         exec_builtin(to_free, argv)
8158 #endif
8159 static void exec_builtin(char ***to_free,
8160                 const struct built_in_command *x,
8161                 char **argv) NORETURN;
8162 static void exec_builtin(char ***to_free,
8163                 const struct built_in_command *x,
8164                 char **argv)
8165 {
8166 #if BB_MMU
8167         int rcode;
8168         fflush_all();
8169 //?     close_saved_fds_and_FILE_fds();
8170         rcode = x->b_function(argv);
8171         fflush_all();
8172         _exit(rcode);
8173 #else
8174         fflush_all();
8175         /* On NOMMU, we must never block!
8176          * Example: { sleep 99 | read line; } & echo Ok
8177          */
8178         re_execute_shell(to_free,
8179                         argv[0],
8180                         G.global_argv[0],
8181                         G.global_argv + 1,
8182                         argv);
8183 #endif
8184 }
8185
8186
8187 static void execvp_or_die(char **argv) NORETURN;
8188 static void execvp_or_die(char **argv)
8189 {
8190         int e;
8191         debug_printf_exec("execing '%s'\n", argv[0]);
8192         /* Don't propagate SIG_IGN to the child */
8193         if (SPECIAL_JOBSTOP_SIGS != 0)
8194                 switch_off_special_sigs(G.special_sig_mask & SPECIAL_JOBSTOP_SIGS);
8195         execvp(argv[0], argv);
8196         e = 2;
8197         if (errno == EACCES) e = 126;
8198         if (errno == ENOENT) e = 127;
8199         bb_perror_msg("can't execute '%s'", argv[0]);
8200         _exit(e);
8201 }
8202
8203 #if ENABLE_HUSH_MODE_X
8204 static void x_mode_print_optionally_squoted(const char *str)
8205 {
8206         unsigned len;
8207         const char *cp;
8208
8209         cp = str;
8210
8211         /* the set of chars which-cause-string-to-be-squoted mimics bash */
8212         /* test a char with: bash -c 'set -x; echo "CH"' */
8213         if (str[strcspn(str, "\\\"'`$(){}[]<>;#&|~*?!^"
8214                         " " "\001\002\003\004\005\006\007"
8215                         "\010\011\012\013\014\015\016\017"
8216                         "\020\021\022\023\024\025\026\027"
8217                         "\030\031\032\033\034\035\036\037"
8218                         )
8219                 ] == '\0'
8220         ) {
8221                 /* string has no special chars */
8222                 x_mode_addstr(str);
8223                 return;
8224         }
8225
8226         cp = str;
8227         for (;;) {
8228                 /* print '....' up to EOL or first squote */
8229                 len = (int)(strchrnul(cp, '\'') - cp);
8230                 if (len != 0) {
8231                         x_mode_addchr('\'');
8232                         x_mode_addblock(cp, len);
8233                         x_mode_addchr('\'');
8234                         cp += len;
8235                 }
8236                 if (*cp == '\0')
8237                         break;
8238                 /* string contains squote(s), print them as \' */
8239                 x_mode_addchr('\\');
8240                 x_mode_addchr('\'');
8241                 cp++;
8242         }
8243 }
8244 static void dump_cmd_in_x_mode(char **argv)
8245 {
8246         if (G_x_mode && argv) {
8247                 unsigned n;
8248
8249                 /* "+[+++...][ cmd...]\n\0" */
8250                 x_mode_prefix();
8251                 n = 0;
8252                 while (argv[n]) {
8253                         x_mode_addchr(' ');
8254                         if (argv[n][0] == '\0') {
8255                                 x_mode_addchr('\'');
8256                                 x_mode_addchr('\'');
8257                         } else {
8258                                 x_mode_print_optionally_squoted(argv[n]);
8259                         }
8260                         n++;
8261                 }
8262                 x_mode_flush();
8263         }
8264 }
8265 #else
8266 # define dump_cmd_in_x_mode(argv) ((void)0)
8267 #endif
8268
8269 #if ENABLE_HUSH_COMMAND
8270 static void if_command_vV_print_and_exit(char opt_vV, char *cmd, const char *explanation)
8271 {
8272         char *to_free;
8273
8274         if (!opt_vV)
8275                 return;
8276
8277         to_free = NULL;
8278         if (!explanation) {
8279                 char *path = getenv("PATH");
8280                 explanation = to_free = find_executable(cmd, &path); /* path == NULL is ok */
8281                 if (!explanation)
8282                         _exit(1); /* PROG was not found */
8283                 if (opt_vV != 'V')
8284                         cmd = to_free; /* -v PROG prints "/path/to/PROG" */
8285         }
8286         printf((opt_vV == 'V') ? "%s is %s\n" : "%s\n", cmd, explanation);
8287         free(to_free);
8288         fflush_all();
8289         _exit(0);
8290 }
8291 #else
8292 # define if_command_vV_print_and_exit(a,b,c) ((void)0)
8293 #endif
8294
8295 #if BB_MMU
8296 #define pseudo_exec_argv(nommu_save, argv, assignment_cnt, argv_expanded) \
8297         pseudo_exec_argv(argv, assignment_cnt, argv_expanded)
8298 #define pseudo_exec(nommu_save, command, argv_expanded) \
8299         pseudo_exec(command, argv_expanded)
8300 #endif
8301
8302 /* Called after [v]fork() in run_pipe, or from builtin_exec.
8303  * Never returns.
8304  * Don't exit() here.  If you don't exec, use _exit instead.
8305  * The at_exit handlers apparently confuse the calling process,
8306  * in particular stdin handling. Not sure why? -- because of vfork! (vda)
8307  */
8308 static void pseudo_exec_argv(nommu_save_t *nommu_save,
8309                 char **argv, int assignment_cnt,
8310                 char **argv_expanded) NORETURN;
8311 static NOINLINE void pseudo_exec_argv(nommu_save_t *nommu_save,
8312                 char **argv, int assignment_cnt,
8313                 char **argv_expanded)
8314 {
8315         const struct built_in_command *x;
8316         struct variable **sv_shadowed;
8317         char **new_env;
8318         IF_HUSH_COMMAND(char opt_vV = 0;)
8319         IF_HUSH_FUNCTIONS(const struct function *funcp;)
8320
8321         new_env = expand_assignments(argv, assignment_cnt);
8322         dump_cmd_in_x_mode(new_env);
8323
8324         if (!argv[assignment_cnt]) {
8325                 /* Case when we are here: ... | var=val | ...
8326                  * (note that we do not exit early, i.e., do not optimize out
8327                  * expand_assignments(): think about ... | var=`sleep 1` | ...
8328                  */
8329                 free_strings(new_env);
8330                 _exit(EXIT_SUCCESS);
8331         }
8332
8333         sv_shadowed = G.shadowed_vars_pp;
8334 #if BB_MMU
8335         G.shadowed_vars_pp = NULL; /* "don't save, free them instead" */
8336 #else
8337         G.shadowed_vars_pp = &nommu_save->old_vars;
8338         G.var_nest_level++;
8339 #endif
8340         set_vars_and_save_old(new_env);
8341         G.shadowed_vars_pp = sv_shadowed;
8342
8343         if (argv_expanded) {
8344                 argv = argv_expanded;
8345         } else {
8346                 argv = expand_strvec_to_strvec(argv + assignment_cnt);
8347 #if !BB_MMU
8348                 nommu_save->argv = argv;
8349 #endif
8350         }
8351         dump_cmd_in_x_mode(argv);
8352
8353 #if ENABLE_FEATURE_SH_STANDALONE || BB_MMU
8354         if (strchr(argv[0], '/') != NULL)
8355                 goto skip;
8356 #endif
8357
8358 #if ENABLE_HUSH_FUNCTIONS
8359         /* Check if the command matches any functions (this goes before bltins) */
8360         funcp = find_function(argv[0]);
8361         if (funcp)
8362                 exec_function(&nommu_save->argv_from_re_execing, funcp, argv);
8363 #endif
8364
8365 #if ENABLE_HUSH_COMMAND
8366         /* "command BAR": run BAR without looking it up among functions
8367          * "command -v BAR": print "BAR" or "/path/to/BAR"; or exit 1
8368          * "command -V BAR": print "BAR is {a function,a shell builtin,/path/to/BAR}"
8369          */
8370         while (strcmp(argv[0], "command") == 0 && argv[1]) {
8371                 char *p;
8372
8373                 argv++;
8374                 p = *argv;
8375                 if (p[0] != '-' || !p[1])
8376                         continue; /* bash allows "command command command [-OPT] BAR" */
8377
8378                 for (;;) {
8379                         p++;
8380                         switch (*p) {
8381                         case '\0':
8382                                 argv++;
8383                                 p = *argv;
8384                                 if (p[0] != '-' || !p[1])
8385                                         goto after_opts;
8386                                 continue; /* next arg is also -opts, process it too */
8387                         case 'v':
8388                         case 'V':
8389                                 opt_vV = *p;
8390                                 continue;
8391                         default:
8392                                 bb_error_msg_and_die("%s: %s: invalid option", "command", argv[0]);
8393                         }
8394                 }
8395         }
8396  after_opts:
8397 # if ENABLE_HUSH_FUNCTIONS
8398         if (opt_vV && find_function(argv[0]))
8399                 if_command_vV_print_and_exit(opt_vV, argv[0], "a function");
8400 # endif
8401 #endif
8402
8403         /* Check if the command matches any of the builtins.
8404          * Depending on context, this might be redundant.  But it's
8405          * easier to waste a few CPU cycles than it is to figure out
8406          * if this is one of those cases.
8407          */
8408         /* Why "BB_MMU ? :" difference in logic? -
8409          * On NOMMU, it is more expensive to re-execute shell
8410          * just in order to run echo or test builtin.
8411          * It's better to skip it here and run corresponding
8412          * non-builtin later. */
8413         x = BB_MMU ? find_builtin(argv[0]) : find_builtin1(argv[0]);
8414         if (x) {
8415                 if_command_vV_print_and_exit(opt_vV, argv[0], "a shell builtin");
8416                 exec_builtin(&nommu_save->argv_from_re_execing, x, argv);
8417         }
8418
8419 #if ENABLE_FEATURE_SH_STANDALONE
8420         /* Check if the command matches any busybox applets */
8421         {
8422                 int a = find_applet_by_name(argv[0]);
8423                 if (a >= 0) {
8424                         if_command_vV_print_and_exit(opt_vV, argv[0], "an applet");
8425 # if BB_MMU /* see above why on NOMMU it is not allowed */
8426                         if (APPLET_IS_NOEXEC(a)) {
8427                                 /* Do not leak open fds from opened script files etc.
8428                                  * Testcase: interactive "ls -l /proc/self/fd"
8429                                  * should not show tty fd open.
8430                                  */
8431                                 close_saved_fds_and_FILE_fds();
8432 //FIXME: should also close saved redir fds
8433 //This casuses test failures in
8434 //redir_children_should_not_see_saved_fd_2.tests
8435 //redir_children_should_not_see_saved_fd_3.tests
8436 //if you replace "busybox find" with just "find" in them
8437                                 /* Without this, "rm -i FILE" can't be ^C'ed: */
8438                                 switch_off_special_sigs(G.special_sig_mask);
8439                                 debug_printf_exec("running applet '%s'\n", argv[0]);
8440                                 run_noexec_applet_and_exit(a, argv[0], argv);
8441                         }
8442 # endif
8443                         /* Re-exec ourselves */
8444                         debug_printf_exec("re-execing applet '%s'\n", argv[0]);
8445                         /* Don't propagate SIG_IGN to the child */
8446                         if (SPECIAL_JOBSTOP_SIGS != 0)
8447                                 switch_off_special_sigs(G.special_sig_mask & SPECIAL_JOBSTOP_SIGS);
8448                         execv(bb_busybox_exec_path, argv);
8449                         /* If they called chroot or otherwise made the binary no longer
8450                          * executable, fall through */
8451                 }
8452         }
8453 #endif
8454
8455 #if ENABLE_FEATURE_SH_STANDALONE || BB_MMU
8456  skip:
8457 #endif
8458         if_command_vV_print_and_exit(opt_vV, argv[0], NULL);
8459         execvp_or_die(argv);
8460 }
8461
8462 /* Called after [v]fork() in run_pipe
8463  */
8464 static void pseudo_exec(nommu_save_t *nommu_save,
8465                 struct command *command,
8466                 char **argv_expanded) NORETURN;
8467 static void pseudo_exec(nommu_save_t *nommu_save,
8468                 struct command *command,
8469                 char **argv_expanded)
8470 {
8471 #if ENABLE_HUSH_FUNCTIONS
8472         if (command->cmd_type == CMD_FUNCDEF) {
8473                 /* Ignore funcdefs in pipes:
8474                  * true | f() { cmd }
8475                  */
8476                 _exit(0);
8477         }
8478 #endif
8479
8480         if (command->argv) {
8481                 pseudo_exec_argv(nommu_save, command->argv,
8482                                 command->assignment_cnt, argv_expanded);
8483         }
8484
8485         if (command->group) {
8486                 /* Cases when we are here:
8487                  * ( list )
8488                  * { list } &
8489                  * ... | ( list ) | ...
8490                  * ... | { list } | ...
8491                  */
8492 #if BB_MMU
8493                 int rcode;
8494                 debug_printf_exec("pseudo_exec: run_list\n");
8495                 reset_traps_to_defaults();
8496                 rcode = run_list(command->group);
8497                 /* OK to leak memory by not calling free_pipe_list,
8498                  * since this process is about to exit */
8499                 _exit(rcode);
8500 #else
8501                 re_execute_shell(&nommu_save->argv_from_re_execing,
8502                                 command->group_as_string,
8503                                 G.global_argv[0],
8504                                 G.global_argv + 1,
8505                                 NULL);
8506 #endif
8507         }
8508
8509         /* Case when we are here: ... | >file */
8510         debug_printf_exec("pseudo_exec'ed null command\n");
8511         _exit(EXIT_SUCCESS);
8512 }
8513
8514 #if ENABLE_HUSH_JOB
8515 static const char *get_cmdtext(struct pipe *pi)
8516 {
8517         char **argv;
8518         char *p;
8519         int len;
8520
8521         /* This is subtle. ->cmdtext is created only on first backgrounding.
8522          * (Think "cat, <ctrl-z>, fg, <ctrl-z>, fg, <ctrl-z>...." here...)
8523          * On subsequent bg argv is trashed, but we won't use it */
8524         if (pi->cmdtext)
8525                 return pi->cmdtext;
8526
8527         argv = pi->cmds[0].argv;
8528         if (!argv) {
8529                 pi->cmdtext = xzalloc(1);
8530                 return pi->cmdtext;
8531         }
8532         len = 0;
8533         do {
8534                 len += strlen(*argv) + 1;
8535         } while (*++argv);
8536         p = xmalloc(len);
8537         pi->cmdtext = p;
8538         argv = pi->cmds[0].argv;
8539         do {
8540                 p = stpcpy(p, *argv);
8541                 *p++ = ' ';
8542         } while (*++argv);
8543         p[-1] = '\0';
8544         return pi->cmdtext;
8545 }
8546
8547 static void remove_job_from_table(struct pipe *pi)
8548 {
8549         struct pipe *prev_pipe;
8550
8551         if (pi == G.job_list) {
8552                 G.job_list = pi->next;
8553         } else {
8554                 prev_pipe = G.job_list;
8555                 while (prev_pipe->next != pi)
8556                         prev_pipe = prev_pipe->next;
8557                 prev_pipe->next = pi->next;
8558         }
8559         G.last_jobid = 0;
8560         if (G.job_list)
8561                 G.last_jobid = G.job_list->jobid;
8562 }
8563
8564 static void delete_finished_job(struct pipe *pi)
8565 {
8566         remove_job_from_table(pi);
8567         free_pipe(pi);
8568 }
8569
8570 static void clean_up_last_dead_job(void)
8571 {
8572         if (G.job_list && !G.job_list->alive_cmds)
8573                 delete_finished_job(G.job_list);
8574 }
8575
8576 static void insert_job_into_table(struct pipe *pi)
8577 {
8578         struct pipe *job, **jobp;
8579         int i;
8580
8581         clean_up_last_dead_job();
8582
8583         /* Find the end of the list, and find next job ID to use */
8584         i = 0;
8585         jobp = &G.job_list;
8586         while ((job = *jobp) != NULL) {
8587                 if (job->jobid > i)
8588                         i = job->jobid;
8589                 jobp = &job->next;
8590         }
8591         pi->jobid = i + 1;
8592
8593         /* Create a new job struct at the end */
8594         job = *jobp = xmemdup(pi, sizeof(*pi));
8595         job->next = NULL;
8596         job->cmds = xzalloc(sizeof(pi->cmds[0]) * pi->num_cmds);
8597         /* Cannot copy entire pi->cmds[] vector! This causes double frees */
8598         for (i = 0; i < pi->num_cmds; i++) {
8599                 job->cmds[i].pid = pi->cmds[i].pid;
8600                 /* all other fields are not used and stay zero */
8601         }
8602         job->cmdtext = xstrdup(get_cmdtext(pi));
8603
8604         if (G_interactive_fd)
8605                 printf("[%u] %u %s\n", job->jobid, (unsigned)job->cmds[0].pid, job->cmdtext);
8606         G.last_jobid = job->jobid;
8607 }
8608 #endif /* JOB */
8609
8610 static int job_exited_or_stopped(struct pipe *pi)
8611 {
8612         int rcode, i;
8613
8614         if (pi->alive_cmds != pi->stopped_cmds)
8615                 return -1;
8616
8617         /* All processes in fg pipe have exited or stopped */
8618         rcode = 0;
8619         i = pi->num_cmds;
8620         while (--i >= 0) {
8621                 rcode = pi->cmds[i].cmd_exitcode;
8622                 /* usually last process gives overall exitstatus,
8623                  * but with "set -o pipefail", last *failed* process does */
8624                 if (G.o_opt[OPT_O_PIPEFAIL] == 0 || rcode != 0)
8625                         break;
8626         }
8627         IF_HAS_KEYWORDS(if (pi->pi_inverted) rcode = !rcode;)
8628         return rcode;
8629 }
8630
8631 static int process_wait_result(struct pipe *fg_pipe, pid_t childpid, int status)
8632 {
8633 #if ENABLE_HUSH_JOB
8634         struct pipe *pi;
8635 #endif
8636         int i, dead;
8637
8638         dead = WIFEXITED(status) || WIFSIGNALED(status);
8639
8640 #if DEBUG_JOBS
8641         if (WIFSTOPPED(status))
8642                 debug_printf_jobs("pid %d stopped by sig %d (exitcode %d)\n",
8643                                 childpid, WSTOPSIG(status), WEXITSTATUS(status));
8644         if (WIFSIGNALED(status))
8645                 debug_printf_jobs("pid %d killed by sig %d (exitcode %d)\n",
8646                                 childpid, WTERMSIG(status), WEXITSTATUS(status));
8647         if (WIFEXITED(status))
8648                 debug_printf_jobs("pid %d exited, exitcode %d\n",
8649                                 childpid, WEXITSTATUS(status));
8650 #endif
8651         /* Were we asked to wait for a fg pipe? */
8652         if (fg_pipe) {
8653                 i = fg_pipe->num_cmds;
8654
8655                 while (--i >= 0) {
8656                         int rcode;
8657
8658                         debug_printf_jobs("check pid %d\n", fg_pipe->cmds[i].pid);
8659                         if (fg_pipe->cmds[i].pid != childpid)
8660                                 continue;
8661                         if (dead) {
8662                                 int ex;
8663                                 fg_pipe->cmds[i].pid = 0;
8664                                 fg_pipe->alive_cmds--;
8665                                 ex = WEXITSTATUS(status);
8666                                 /* bash prints killer signal's name for *last*
8667                                  * process in pipe (prints just newline for SIGINT/SIGPIPE).
8668                                  * Mimic this. Example: "sleep 5" + (^\ or kill -QUIT)
8669                                  */
8670                                 if (WIFSIGNALED(status)) {
8671                                         int sig = WTERMSIG(status);
8672                                         if (i == fg_pipe->num_cmds-1)
8673                                                 /* TODO: use strsignal() instead for bash compat? but that's bloat... */
8674                                                 puts(sig == SIGINT || sig == SIGPIPE ? "" : get_signame(sig));
8675                                         /* TODO: if (WCOREDUMP(status)) + " (core dumped)"; */
8676                                         /* TODO: MIPS has 128 sigs (1..128), what if sig==128 here?
8677                                          * Maybe we need to use sig | 128? */
8678                                         ex = sig + 128;
8679                                 }
8680                                 fg_pipe->cmds[i].cmd_exitcode = ex;
8681                         } else {
8682                                 fg_pipe->stopped_cmds++;
8683                         }
8684                         debug_printf_jobs("fg_pipe: alive_cmds %d stopped_cmds %d\n",
8685                                         fg_pipe->alive_cmds, fg_pipe->stopped_cmds);
8686                         rcode = job_exited_or_stopped(fg_pipe);
8687                         if (rcode >= 0) {
8688 /* Note: *non-interactive* bash does not continue if all processes in fg pipe
8689  * are stopped. Testcase: "cat | cat" in a script (not on command line!)
8690  * and "killall -STOP cat" */
8691                                 if (G_interactive_fd) {
8692 #if ENABLE_HUSH_JOB
8693                                         if (fg_pipe->alive_cmds != 0)
8694                                                 insert_job_into_table(fg_pipe);
8695 #endif
8696                                         return rcode;
8697                                 }
8698                                 if (fg_pipe->alive_cmds == 0)
8699                                         return rcode;
8700                         }
8701                         /* There are still running processes in the fg_pipe */
8702                         return -1;
8703                 }
8704                 /* It wasn't in fg_pipe, look for process in bg pipes */
8705         }
8706
8707 #if ENABLE_HUSH_JOB
8708         /* We were asked to wait for bg or orphaned children */
8709         /* No need to remember exitcode in this case */
8710         for (pi = G.job_list; pi; pi = pi->next) {
8711                 for (i = 0; i < pi->num_cmds; i++) {
8712                         if (pi->cmds[i].pid == childpid)
8713                                 goto found_pi_and_prognum;
8714                 }
8715         }
8716         /* Happens when shell is used as init process (init=/bin/sh) */
8717         debug_printf("checkjobs: pid %d was not in our list!\n", childpid);
8718         return -1; /* this wasn't a process from fg_pipe */
8719
8720  found_pi_and_prognum:
8721         if (dead) {
8722                 /* child exited */
8723                 int rcode = WEXITSTATUS(status);
8724                 if (WIFSIGNALED(status))
8725                         rcode = 128 + WTERMSIG(status);
8726                 pi->cmds[i].cmd_exitcode = rcode;
8727                 if (G.last_bg_pid == pi->cmds[i].pid)
8728                         G.last_bg_pid_exitcode = rcode;
8729                 pi->cmds[i].pid = 0;
8730                 pi->alive_cmds--;
8731                 if (!pi->alive_cmds) {
8732 # if ENABLE_HUSH_BASH_COMPAT
8733                         G.dead_job_exitcode = job_exited_or_stopped(pi);
8734 # endif
8735                         if (G_interactive_fd) {
8736                                 printf(JOB_STATUS_FORMAT, pi->jobid,
8737                                                 "Done", pi->cmdtext);
8738                                 delete_finished_job(pi);
8739                         } else {
8740 /*
8741  * bash deletes finished jobs from job table only in interactive mode,
8742  * after "jobs" cmd, or if pid of a new process matches one of the old ones
8743  * (see cleanup_dead_jobs(), delete_old_job(), J_NOTIFIED in bash source).
8744  * Testcase script: "(exit 3) & sleep 1; wait %1; echo $?" prints 3 in bash.
8745  * We only retain one "dead" job, if it's the single job on the list.
8746  * This covers most of real-world scenarios where this is useful.
8747  */
8748                                 if (pi != G.job_list)
8749                                         delete_finished_job(pi);
8750                         }
8751                 }
8752         } else {
8753                 /* child stopped */
8754                 pi->stopped_cmds++;
8755         }
8756 #endif
8757         return -1; /* this wasn't a process from fg_pipe */
8758 }
8759
8760 /* Check to see if any processes have exited -- if they have,
8761  * figure out why and see if a job has completed.
8762  *
8763  * If non-NULL fg_pipe: wait for its completion or stop.
8764  * Return its exitcode or zero if stopped.
8765  *
8766  * Alternatively (fg_pipe == NULL, waitfor_pid != 0):
8767  * waitpid(WNOHANG), if waitfor_pid exits or stops, return exitcode+1,
8768  * else return <0 if waitpid errors out (e.g. ECHILD: nothing to wait for)
8769  * or 0 if no children changed status.
8770  *
8771  * Alternatively (fg_pipe == NULL, waitfor_pid == 0),
8772  * return <0 if waitpid errors out (e.g. ECHILD: nothing to wait for)
8773  * or 0 if no children changed status.
8774  */
8775 static int checkjobs(struct pipe *fg_pipe, pid_t waitfor_pid)
8776 {
8777         int attributes;
8778         int status;
8779         int rcode = 0;
8780
8781         debug_printf_jobs("checkjobs %p\n", fg_pipe);
8782
8783         attributes = WUNTRACED;
8784         if (fg_pipe == NULL)
8785                 attributes |= WNOHANG;
8786
8787         errno = 0;
8788 #if ENABLE_HUSH_FAST
8789         if (G.handled_SIGCHLD == G.count_SIGCHLD) {
8790 //bb_error_msg("[%d] checkjobs: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d children?:%d fg_pipe:%p",
8791 //getpid(), G.count_SIGCHLD, G.handled_SIGCHLD, G.we_have_children, fg_pipe);
8792                 /* There was neither fork nor SIGCHLD since last waitpid */
8793                 /* Avoid doing waitpid syscall if possible */
8794                 if (!G.we_have_children) {
8795                         errno = ECHILD;
8796                         return -1;
8797                 }
8798                 if (fg_pipe == NULL) { /* is WNOHANG set? */
8799                         /* We have children, but they did not exit
8800                          * or stop yet (we saw no SIGCHLD) */
8801                         return 0;
8802                 }
8803                 /* else: !WNOHANG, waitpid will block, can't short-circuit */
8804         }
8805 #endif
8806
8807 /* Do we do this right?
8808  * bash-3.00# sleep 20 | false
8809  * <ctrl-Z pressed>
8810  * [3]+  Stopped          sleep 20 | false
8811  * bash-3.00# echo $?
8812  * 1   <========== bg pipe is not fully done, but exitcode is already known!
8813  * [hush 1.14.0: yes we do it right]
8814  */
8815         while (1) {
8816                 pid_t childpid;
8817 #if ENABLE_HUSH_FAST
8818                 int i;
8819                 i = G.count_SIGCHLD;
8820 #endif
8821                 childpid = waitpid(-1, &status, attributes);
8822                 if (childpid <= 0) {
8823                         if (childpid && errno != ECHILD)
8824                                 bb_simple_perror_msg("waitpid");
8825 #if ENABLE_HUSH_FAST
8826                         else { /* Until next SIGCHLD, waitpid's are useless */
8827                                 G.we_have_children = (childpid == 0);
8828                                 G.handled_SIGCHLD = i;
8829 //bb_error_msg("[%d] checkjobs: waitpid returned <= 0, G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
8830                         }
8831 #endif
8832                         /* ECHILD (no children), or 0 (no change in children status) */
8833                         rcode = childpid;
8834                         break;
8835                 }
8836                 rcode = process_wait_result(fg_pipe, childpid, status);
8837                 if (rcode >= 0) {
8838                         /* fg_pipe exited or stopped */
8839                         break;
8840                 }
8841                 if (childpid == waitfor_pid) { /* "wait PID" */
8842                         debug_printf_exec("childpid==waitfor_pid:%d status:0x%08x\n", childpid, status);
8843                         rcode = WEXITSTATUS(status);
8844                         if (WIFSIGNALED(status))
8845                                 rcode = 128 + WTERMSIG(status);
8846                         if (WIFSTOPPED(status))
8847                                 /* bash: "cmd & wait $!" and cmd stops: $? = 128 + stopsig */
8848                                 rcode = 128 + WSTOPSIG(status);
8849                         rcode++;
8850                         break; /* "wait PID" called us, give it exitcode+1 */
8851                 }
8852 #if ENABLE_HUSH_BASH_COMPAT
8853                 if (-1 == waitfor_pid /* "wait -n" (wait for any one job) */
8854                  && G.dead_job_exitcode >= 0 /* some job did finish */
8855                 ) {
8856                         debug_printf_exec("waitfor_pid:-1\n");
8857                         rcode = G.dead_job_exitcode + 1;
8858                         break;
8859                 }
8860 #endif
8861                 /* This wasn't one of our processes, or */
8862                 /* fg_pipe still has running processes, do waitpid again */
8863         } /* while (waitpid succeeds)... */
8864
8865         return rcode;
8866 }
8867
8868 #if ENABLE_HUSH_JOB
8869 static int checkjobs_and_fg_shell(struct pipe *fg_pipe)
8870 {
8871         pid_t p;
8872         int rcode = checkjobs(fg_pipe, 0 /*(no pid to wait for)*/);
8873         if (G_saved_tty_pgrp) {
8874                 /* Job finished, move the shell to the foreground */
8875                 p = getpgrp(); /* our process group id */
8876                 debug_printf_jobs("fg'ing ourself: getpgrp()=%d\n", (int)p);
8877                 tcsetpgrp(G_interactive_fd, p);
8878         }
8879         return rcode;
8880 }
8881 #endif
8882
8883 /* Start all the jobs, but don't wait for anything to finish.
8884  * See checkjobs().
8885  *
8886  * Return code is normally -1, when the caller has to wait for children
8887  * to finish to determine the exit status of the pipe.  If the pipe
8888  * is a simple builtin command, however, the action is done by the
8889  * time run_pipe returns, and the exit code is provided as the
8890  * return value.
8891  *
8892  * Returns -1 only if started some children. IOW: we have to
8893  * mask out retvals of builtins etc with 0xff!
8894  *
8895  * The only case when we do not need to [v]fork is when the pipe
8896  * is single, non-backgrounded, non-subshell command. Examples:
8897  * cmd ; ...   { list } ; ...
8898  * cmd && ...  { list } && ...
8899  * cmd || ...  { list } || ...
8900  * If it is, then we can run cmd as a builtin, NOFORK,
8901  * or (if SH_STANDALONE) an applet, and we can run the { list }
8902  * with run_list. If it isn't one of these, we fork and exec cmd.
8903  *
8904  * Cases when we must fork:
8905  * non-single:   cmd | cmd
8906  * backgrounded: cmd &     { list } &
8907  * subshell:     ( list ) [&]
8908  */
8909 #if !ENABLE_HUSH_MODE_X
8910 #define redirect_and_varexp_helper(command, sqp, argv_expanded) \
8911         redirect_and_varexp_helper(command, sqp)
8912 #endif
8913 static int redirect_and_varexp_helper(
8914                 struct command *command,
8915                 struct squirrel **sqp,
8916                 char **argv_expanded)
8917 {
8918         /* Assignments occur before redirects. Try:
8919          * a=`sleep 1` sleep 2 3>/qwe/rty
8920          */
8921
8922         char **new_env = expand_assignments(command->argv, command->assignment_cnt);
8923         dump_cmd_in_x_mode(new_env);
8924         dump_cmd_in_x_mode(argv_expanded);
8925         /* this takes ownership of new_env[i] elements, and frees new_env: */
8926         set_vars_and_save_old(new_env);
8927
8928         return setup_redirects(command, sqp);
8929 }
8930 static NOINLINE int run_pipe(struct pipe *pi)
8931 {
8932         static const char *const null_ptr = NULL;
8933
8934         int cmd_no;
8935         int next_infd;
8936         struct command *command;
8937         char **argv_expanded;
8938         char **argv;
8939         struct squirrel *squirrel = NULL;
8940         int rcode;
8941
8942         debug_printf_exec("run_pipe start: members:%d\n", pi->num_cmds);
8943         debug_enter();
8944
8945         /* Testcase: set -- q w e; (IFS='' echo "$*"; IFS=''; echo "$*"); echo "$*"
8946          * Result should be 3 lines: q w e, qwe, q w e
8947          */
8948         if (G.ifs_whitespace != G.ifs)
8949                 free(G.ifs_whitespace);
8950         G.ifs = get_local_var_value("IFS");
8951         if (G.ifs) {
8952                 char *p;
8953                 G.ifs_whitespace = (char*)G.ifs;
8954                 p = skip_whitespace(G.ifs);
8955                 if (*p) {
8956                         /* Not all $IFS is whitespace */
8957                         char *d;
8958                         int len = p - G.ifs;
8959                         p = skip_non_whitespace(p);
8960                         G.ifs_whitespace = xmalloc(len + strlen(p) + 1); /* can overestimate */
8961                         d = mempcpy(G.ifs_whitespace, G.ifs, len);
8962                         while (*p) {
8963                                 if (isspace(*p))
8964                                         *d++ = *p;
8965                                 p++;
8966                         }
8967                         *d = '\0';
8968                 }
8969         } else {
8970                 G.ifs = defifs;
8971                 G.ifs_whitespace = (char*)G.ifs;
8972         }
8973
8974         IF_HUSH_JOB(pi->pgrp = -1;)
8975         pi->stopped_cmds = 0;
8976         command = &pi->cmds[0];
8977         argv_expanded = NULL;
8978
8979         if (pi->num_cmds != 1
8980          || pi->followup == PIPE_BG
8981          || command->cmd_type == CMD_SUBSHELL
8982         ) {
8983                 goto must_fork;
8984         }
8985
8986         pi->alive_cmds = 1;
8987
8988         debug_printf_exec(": group:%p argv:'%s'\n",
8989                 command->group, command->argv ? command->argv[0] : "NONE");
8990
8991         if (command->group) {
8992 #if ENABLE_HUSH_FUNCTIONS
8993                 if (command->cmd_type == CMD_FUNCDEF) {
8994                         /* "executing" func () { list } */
8995                         struct function *funcp;
8996
8997                         funcp = new_function(command->argv[0]);
8998                         /* funcp->name is already set to argv[0] */
8999                         funcp->body = command->group;
9000 # if !BB_MMU
9001                         funcp->body_as_string = command->group_as_string;
9002                         command->group_as_string = NULL;
9003 # endif
9004                         command->group = NULL;
9005                         command->argv[0] = NULL;
9006                         debug_printf_exec("cmd %p has child func at %p\n", command, funcp);
9007                         funcp->parent_cmd = command;
9008                         command->child_func = funcp;
9009
9010                         debug_printf_exec("run_pipe: return EXIT_SUCCESS\n");
9011                         debug_leave();
9012                         return EXIT_SUCCESS;
9013                 }
9014 #endif
9015                 /* { list } */
9016                 debug_printf_exec("non-subshell group\n");
9017                 rcode = 1; /* exitcode if redir failed */
9018                 if (setup_redirects(command, &squirrel) == 0) {
9019                         debug_printf_exec(": run_list\n");
9020 //FIXME: we need to pass squirrel down into run_list()
9021 //for SH_STANDALONE case, or else this construct:
9022 // { find /proc/self/fd; true; } >FILE; cmd2
9023 //has no way of closing saved fd#1 for "find",
9024 //and in SH_STANDALONE mode, "find" is not execed,
9025 //therefore CLOEXEC on saved fd does not help.
9026                         rcode = run_list(command->group) & 0xff;
9027                 }
9028                 restore_redirects(squirrel);
9029                 IF_HAS_KEYWORDS(if (pi->pi_inverted) rcode = !rcode;)
9030                 debug_leave();
9031                 debug_printf_exec("run_pipe: return %d\n", rcode);
9032                 return rcode;
9033         }
9034
9035         argv = command->argv ? command->argv : (char **) &null_ptr;
9036         {
9037                 const struct built_in_command *x;
9038                 IF_HUSH_FUNCTIONS(const struct function *funcp;)
9039                 IF_NOT_HUSH_FUNCTIONS(enum { funcp = 0 };)
9040                 struct variable **sv_shadowed;
9041                 struct variable *old_vars;
9042
9043 #if ENABLE_HUSH_LINENO_VAR
9044                 G.execute_lineno = command->lineno;
9045 #endif
9046
9047                 if (argv[command->assignment_cnt] == NULL) {
9048                         /* Assignments, but no command.
9049                          * Ensure redirects take effect (that is, create files).
9050                          * Try "a=t >file"
9051                          */
9052                         unsigned i;
9053                         G.expand_exitcode = 0;
9054  only_assignments:
9055                         rcode = setup_redirects(command, &squirrel);
9056                         restore_redirects(squirrel);
9057
9058                         /* Set shell variables */
9059                         i = 0;
9060                         while (i < command->assignment_cnt) {
9061                                 char *p = expand_string_to_string(argv[i],
9062                                                 EXP_FLAG_ESC_GLOB_CHARS,
9063                                                 /*unbackslash:*/ 1
9064                                 );
9065 #if ENABLE_HUSH_MODE_X
9066                                 if (G_x_mode) {
9067                                         char *eq;
9068                                         if (i == 0)
9069                                                 x_mode_prefix();
9070                                         x_mode_addchr(' ');
9071                                         eq = strchrnul(p, '=');
9072                                         if (*eq) eq++;
9073                                         x_mode_addblock(p, (eq - p));
9074                                         x_mode_print_optionally_squoted(eq);
9075                                         x_mode_flush();
9076                                 }
9077 #endif
9078                                 debug_printf_env("set shell var:'%s'->'%s'\n", *argv, p);
9079                                 if (set_local_var(p, /*flag:*/ 0)) {
9080                                         /* assignment to readonly var / putenv error? */
9081                                         rcode = 1;
9082                                 }
9083                                 i++;
9084                         }
9085                         /* Redirect error sets $? to 1. Otherwise,
9086                          * if evaluating assignment value set $?, retain it.
9087                          * Else, clear $?:
9088                          *  false; q=`exit 2`; echo $? - should print 2
9089                          *  false; x=1; echo $? - should print 0
9090                          * Because of the 2nd case, we can't just use G.last_exitcode.
9091                          */
9092                         if (rcode == 0)
9093                                 rcode = G.expand_exitcode;
9094                         IF_HAS_KEYWORDS(if (pi->pi_inverted) rcode = !rcode;)
9095                         debug_leave();
9096                         debug_printf_exec("run_pipe: return %d\n", rcode);
9097                         return rcode;
9098                 }
9099
9100                 /* Expand the rest into (possibly) many strings each */
9101 #if defined(CMD_SINGLEWORD_NOGLOB)
9102                 if (command->cmd_type == CMD_SINGLEWORD_NOGLOB)
9103                         argv_expanded = expand_strvec_to_strvec_singleword_noglob(argv + command->assignment_cnt);
9104                 else
9105 #endif
9106                         argv_expanded = expand_strvec_to_strvec(argv + command->assignment_cnt);
9107
9108                 /* If someone gives us an empty string: `cmd with empty output` */
9109                 if (!argv_expanded[0]) {
9110                         free(argv_expanded);
9111                         /* `false` still has to set exitcode 1 */
9112                         G.expand_exitcode = G.last_exitcode;
9113                         goto only_assignments;
9114                 }
9115
9116                 old_vars = NULL;
9117                 sv_shadowed = G.shadowed_vars_pp;
9118
9119                 /* Check if argv[0] matches any functions (this goes before bltins) */
9120                 IF_HUSH_FUNCTIONS(funcp = find_function(argv_expanded[0]);)
9121                 IF_HUSH_FUNCTIONS(x = NULL;)
9122                 IF_HUSH_FUNCTIONS(if (!funcp))
9123                         x = find_builtin(argv_expanded[0]);
9124                 if (x || funcp) {
9125                         if (x && x->b_function == builtin_exec && argv_expanded[1] == NULL) {
9126                                 debug_printf("exec with redirects only\n");
9127                                 /*
9128                                  * Variable assignments are executed, but then "forgotten":
9129                                  *  a=`sleep 1;echo A` exec 3>&-; echo $a
9130                                  * sleeps, but prints nothing.
9131                                  */
9132                                 enter_var_nest_level();
9133                                 G.shadowed_vars_pp = &old_vars;
9134                                 rcode = redirect_and_varexp_helper(command,
9135                                         /*squirrel:*/ ERR_PTR,
9136                                         argv_expanded
9137                                 );
9138                                 G.shadowed_vars_pp = sv_shadowed;
9139                                 /* rcode=1 can be if redir file can't be opened */
9140
9141                                 goto clean_up_and_ret1;
9142                         }
9143
9144                         /* Bump var nesting, or this will leak exported $a:
9145                          * a=b true; env | grep ^a=
9146                          */
9147                         enter_var_nest_level();
9148                         /* Collect all variables "shadowed" by helper
9149                          * (IOW: old vars overridden by "var1=val1 var2=val2 cmd..." syntax)
9150                          * into old_vars list:
9151                          */
9152                         G.shadowed_vars_pp = &old_vars;
9153                         rcode = redirect_and_varexp_helper(command, &squirrel, argv_expanded);
9154                         if (rcode == 0) {
9155                                 if (!funcp) {
9156                                         /* Do not collect *to old_vars list* vars shadowed
9157                                          * by e.g. "local VAR" builtin (collect them
9158                                          * in the previously nested list instead):
9159                                          * don't want them to be restored immediately
9160                                          * after "local" completes.
9161                                          */
9162                                         G.shadowed_vars_pp = sv_shadowed;
9163
9164                                         debug_printf_exec(": builtin '%s' '%s'...\n",
9165                                                 x->b_cmd, argv_expanded[1]);
9166                                         fflush_all();
9167                                         rcode = x->b_function(argv_expanded) & 0xff;
9168                                         fflush_all();
9169                                 }
9170 #if ENABLE_HUSH_FUNCTIONS
9171                                 else {
9172                                         debug_printf_exec(": function '%s' '%s'...\n",
9173                                                 funcp->name, argv_expanded[1]);
9174                                         rcode = run_function(funcp, argv_expanded) & 0xff;
9175                                         /*
9176                                          * But do collect *to old_vars list* vars shadowed
9177                                          * within function execution. To that end, restore
9178                                          * this pointer _after_ function run:
9179                                          */
9180                                         G.shadowed_vars_pp = sv_shadowed;
9181                                 }
9182 #endif
9183                         }
9184                 } else
9185                 if (ENABLE_FEATURE_SH_NOFORK && NUM_APPLETS > 1) {
9186                         int n = find_applet_by_name(argv_expanded[0]);
9187                         if (n < 0 || !APPLET_IS_NOFORK(n))
9188                                 goto must_fork;
9189
9190                         enter_var_nest_level();
9191                         /* Collect all variables "shadowed" by helper into old_vars list */
9192                         G.shadowed_vars_pp = &old_vars;
9193                         rcode = redirect_and_varexp_helper(command, &squirrel, argv_expanded);
9194                         G.shadowed_vars_pp = sv_shadowed;
9195
9196                         if (rcode == 0) {
9197                                 debug_printf_exec(": run_nofork_applet '%s' '%s'...\n",
9198                                         argv_expanded[0], argv_expanded[1]);
9199                                 /*
9200                                  * Note: signals (^C) can't interrupt here.
9201                                  * We remember them and they will be acted upon
9202                                  * after applet returns.
9203                                  * This makes applets which can run for a long time
9204                                  * and/or wait for user input ineligible for NOFORK:
9205                                  * for example, "yes" or "rm" (rm -i waits for input).
9206                                  */
9207                                 rcode = run_nofork_applet(n, argv_expanded);
9208                         }
9209                 } else
9210                         goto must_fork;
9211
9212                 restore_redirects(squirrel);
9213  clean_up_and_ret1:
9214                 leave_var_nest_level();
9215                 add_vars(old_vars);
9216
9217                 /*
9218                  * Try "usleep 99999999" + ^C + "echo $?"
9219                  * with FEATURE_SH_NOFORK=y.
9220                  */
9221                 if (!funcp) {
9222                         /* It was builtin or nofork.
9223                          * if this would be a real fork/execed program,
9224                          * it should have died if a fatal sig was received.
9225                          * But OTOH, there was no separate process,
9226                          * the sig was sent to _shell_, not to non-existing
9227                          * child.
9228                          * Let's just handle ^C only, this one is obvious:
9229                          * we aren't ok with exitcode 0 when ^C was pressed
9230                          * during builtin/nofork.
9231                          */
9232                         if (sigismember(&G.pending_set, SIGINT))
9233                                 rcode = 128 + SIGINT;
9234                 }
9235                 free(argv_expanded);
9236                 IF_HAS_KEYWORDS(if (pi->pi_inverted) rcode = !rcode;)
9237                 debug_leave();
9238                 debug_printf_exec("run_pipe return %d\n", rcode);
9239                 return rcode;
9240         }
9241
9242  must_fork:
9243         /* NB: argv_expanded may already be created, and that
9244          * might include `cmd` runs! Do not rerun it! We *must*
9245          * use argv_expanded if it's non-NULL */
9246
9247         /* Going to fork a child per each pipe member */
9248         pi->alive_cmds = 0;
9249         next_infd = 0;
9250
9251         cmd_no = 0;
9252         while (cmd_no < pi->num_cmds) {
9253                 struct fd_pair pipefds;
9254 #if !BB_MMU
9255                 int sv_var_nest_level = G.var_nest_level;
9256                 volatile nommu_save_t nommu_save;
9257                 nommu_save.old_vars = NULL;
9258                 nommu_save.argv = NULL;
9259                 nommu_save.argv_from_re_execing = NULL;
9260 #endif
9261                 command = &pi->cmds[cmd_no];
9262                 cmd_no++;
9263                 if (command->argv) {
9264                         debug_printf_exec(": pipe member '%s' '%s'...\n",
9265                                         command->argv[0], command->argv[1]);
9266                 } else {
9267                         debug_printf_exec(": pipe member with no argv\n");
9268                 }
9269
9270                 /* pipes are inserted between pairs of commands */
9271                 pipefds.rd = 0;
9272                 pipefds.wr = 1;
9273                 if (cmd_no < pi->num_cmds)
9274                         xpiped_pair(pipefds);
9275
9276 #if ENABLE_HUSH_LINENO_VAR
9277                 G.execute_lineno = command->lineno;
9278 #endif
9279
9280                 command->pid = BB_MMU ? fork() : vfork();
9281                 if (!command->pid) { /* child */
9282 #if ENABLE_HUSH_JOB
9283                         disable_restore_tty_pgrp_on_exit();
9284                         CLEAR_RANDOM_T(&G.random_gen); /* or else $RANDOM repeats in child */
9285
9286                         /* Every child adds itself to new process group
9287                          * with pgid == pid_of_first_child_in_pipe */
9288                         if (G.run_list_level == 1 && G_interactive_fd) {
9289                                 pid_t pgrp;
9290                                 pgrp = pi->pgrp;
9291                                 if (pgrp < 0) /* true for 1st process only */
9292                                         pgrp = getpid();
9293                                 if (setpgid(0, pgrp) == 0
9294                                  && pi->followup != PIPE_BG
9295                                  && G_saved_tty_pgrp /* we have ctty */
9296                                 ) {
9297                                         /* We do it in *every* child, not just first,
9298                                          * to avoid races */
9299                                         tcsetpgrp(G_interactive_fd, pgrp);
9300                                 }
9301                         }
9302 #endif
9303                         if (pi->alive_cmds == 0 && pi->followup == PIPE_BG) {
9304                                 /* 1st cmd in backgrounded pipe
9305                                  * should have its stdin /dev/null'ed */
9306                                 close(0);
9307                                 if (open(bb_dev_null, O_RDONLY))
9308                                         xopen("/", O_RDONLY);
9309                         } else {
9310                                 xmove_fd(next_infd, 0);
9311                         }
9312                         xmove_fd(pipefds.wr, 1);
9313                         if (pipefds.rd > 1)
9314                                 close(pipefds.rd);
9315                         /* Like bash, explicit redirects override pipes,
9316                          * and the pipe fd (fd#1) is available for dup'ing:
9317                          * "cmd1 2>&1 | cmd2": fd#1 is duped to fd#2, thus stderr
9318                          * of cmd1 goes into pipe.
9319                          */
9320                         if (setup_redirects(command, NULL)) {
9321                                 /* Happens when redir file can't be opened:
9322                                  * $ hush -c 'echo FOO >&2 | echo BAR 3>/qwe/rty; echo BAZ'
9323                                  * FOO
9324                                  * hush: can't open '/qwe/rty': No such file or directory
9325                                  * BAZ
9326                                  * (echo BAR is not executed, it hits _exit(1) below)
9327                                  */
9328                                 _exit(1);
9329                         }
9330
9331                         /* Stores to nommu_save list of env vars putenv'ed
9332                          * (NOMMU, on MMU we don't need that) */
9333                         /* cast away volatility... */
9334                         pseudo_exec((nommu_save_t*) &nommu_save, command, argv_expanded);
9335                         /* pseudo_exec() does not return */
9336                 }
9337
9338                 /* parent or error */
9339 #if ENABLE_HUSH_FAST
9340                 G.count_SIGCHLD++;
9341 //bb_error_msg("[%d] fork in run_pipe: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
9342 #endif
9343                 enable_restore_tty_pgrp_on_exit();
9344 #if !BB_MMU
9345                 /* Clean up after vforked child */
9346                 free(nommu_save.argv);
9347                 free(nommu_save.argv_from_re_execing);
9348                 G.var_nest_level = sv_var_nest_level;
9349                 remove_nested_vars();
9350                 add_vars(nommu_save.old_vars);
9351 #endif
9352                 free(argv_expanded);
9353                 argv_expanded = NULL;
9354                 if (command->pid < 0) { /* [v]fork failed */
9355                         /* Clearly indicate, was it fork or vfork */
9356                         bb_simple_perror_msg(BB_MMU ? "vfork"+1 : "vfork");
9357                 } else {
9358                         pi->alive_cmds++;
9359 #if ENABLE_HUSH_JOB
9360                         /* Second and next children need to know pid of first one */
9361                         if (pi->pgrp < 0)
9362                                 pi->pgrp = command->pid;
9363 #endif
9364                 }
9365
9366                 if (cmd_no > 1)
9367                         close(next_infd);
9368                 if (cmd_no < pi->num_cmds)
9369                         close(pipefds.wr);
9370                 /* Pass read (output) pipe end to next iteration */
9371                 next_infd = pipefds.rd;
9372         }
9373
9374         if (!pi->alive_cmds) {
9375                 debug_leave();
9376                 debug_printf_exec("run_pipe return 1 (all forks failed, no children)\n");
9377                 return 1;
9378         }
9379
9380         debug_leave();
9381         debug_printf_exec("run_pipe return -1 (%u children started)\n", pi->alive_cmds);
9382         return -1;
9383 }
9384
9385 /* NB: called by pseudo_exec, and therefore must not modify any
9386  * global data until exec/_exit (we can be a child after vfork!) */
9387 static int run_list(struct pipe *pi)
9388 {
9389 #if ENABLE_HUSH_CASE
9390         char *case_word = NULL;
9391 #endif
9392 #if ENABLE_HUSH_LOOPS
9393         struct pipe *loop_top = NULL;
9394         char **for_lcur = NULL;
9395         char **for_list = NULL;
9396 #endif
9397         smallint last_followup;
9398         smalluint rcode;
9399 #if ENABLE_HUSH_IF || ENABLE_HUSH_CASE
9400         smalluint cond_code = 0;
9401 #else
9402         enum { cond_code = 0 };
9403 #endif
9404 #if HAS_KEYWORDS
9405         smallint rword;      /* RES_foo */
9406         smallint last_rword; /* ditto */
9407 #endif
9408
9409         debug_printf_exec("run_list start lvl %d\n", G.run_list_level);
9410         debug_enter();
9411
9412 #if ENABLE_HUSH_LOOPS
9413         /* Check syntax for "for" */
9414         {
9415                 struct pipe *cpipe;
9416                 for (cpipe = pi; cpipe; cpipe = cpipe->next) {
9417                         if (cpipe->res_word != RES_FOR && cpipe->res_word != RES_IN)
9418                                 continue;
9419                         /* current word is FOR or IN (BOLD in comments below) */
9420                         if (cpipe->next == NULL) {
9421                                 syntax_error("malformed for");
9422                                 debug_leave();
9423                                 debug_printf_exec("run_list lvl %d return 1\n", G.run_list_level);
9424                                 return 1;
9425                         }
9426                         /* "FOR v; do ..." and "for v IN a b; do..." are ok */
9427                         if (cpipe->next->res_word == RES_DO)
9428                                 continue;
9429                         /* next word is not "do". It must be "in" then ("FOR v in ...") */
9430                         if (cpipe->res_word == RES_IN /* "for v IN a b; not_do..."? */
9431                          || cpipe->next->res_word != RES_IN /* FOR v not_do_and_not_in..."? */
9432                         ) {
9433                                 syntax_error("malformed for");
9434                                 debug_leave();
9435                                 debug_printf_exec("run_list lvl %d return 1\n", G.run_list_level);
9436                                 return 1;
9437                         }
9438                 }
9439         }
9440 #endif
9441
9442         /* Past this point, all code paths should jump to ret: label
9443          * in order to return, no direct "return" statements please.
9444          * This helps to ensure that no memory is leaked. */
9445
9446 #if ENABLE_HUSH_JOB
9447         G.run_list_level++;
9448 #endif
9449
9450 #if HAS_KEYWORDS
9451         rword = RES_NONE;
9452         last_rword = RES_XXXX;
9453 #endif
9454         last_followup = PIPE_SEQ;
9455         rcode = G.last_exitcode;
9456
9457         /* Go through list of pipes, (maybe) executing them. */
9458         for (; pi; pi = IF_HUSH_LOOPS(rword == RES_DONE ? loop_top : ) pi->next) {
9459                 int r;
9460                 int sv_errexit_depth;
9461
9462                 if (G.flag_SIGINT)
9463                         break;
9464                 if (G_flag_return_in_progress == 1)
9465                         break;
9466
9467                 IF_HAS_KEYWORDS(rword = pi->res_word;)
9468                 debug_printf_exec(": rword=%d cond_code=%d last_rword=%d\n",
9469                                 rword, cond_code, last_rword);
9470
9471                 sv_errexit_depth = G.errexit_depth;
9472                 if (
9473 #if ENABLE_HUSH_IF
9474                     rword == RES_IF || rword == RES_ELIF ||
9475 #endif
9476                     pi->followup != PIPE_SEQ
9477                 ) {
9478                         G.errexit_depth++;
9479                 }
9480 #if ENABLE_HUSH_LOOPS
9481                 if ((rword == RES_WHILE || rword == RES_UNTIL || rword == RES_FOR)
9482                  && loop_top == NULL /* avoid bumping G.depth_of_loop twice */
9483                 ) {
9484                         /* start of a loop: remember where loop starts */
9485                         loop_top = pi;
9486                         G.depth_of_loop++;
9487                 }
9488 #endif
9489                 /* Still in the same "if...", "then..." or "do..." branch? */
9490                 if (IF_HAS_KEYWORDS(rword == last_rword &&) 1) {
9491                         if ((rcode == 0 && last_followup == PIPE_OR)
9492                          || (rcode != 0 && last_followup == PIPE_AND)
9493                         ) {
9494                                 /* It is "<true> || CMD" or "<false> && CMD"
9495                                  * and we should not execute CMD */
9496                                 debug_printf_exec("skipped cmd because of || or &&\n");
9497                                 last_followup = pi->followup;
9498                                 goto dont_check_jobs_but_continue;
9499                         }
9500                 }
9501                 last_followup = pi->followup;
9502                 IF_HAS_KEYWORDS(last_rword = rword;)
9503 #if ENABLE_HUSH_IF
9504                 if (cond_code) {
9505                         if (rword == RES_THEN) {
9506                                 /* if false; then ... fi has exitcode 0! */
9507                                 G.last_exitcode = rcode = EXIT_SUCCESS;
9508                                 /* "if <false> THEN cmd": skip cmd */
9509                                 continue;
9510                         }
9511                 } else {
9512                         if (rword == RES_ELSE || rword == RES_ELIF) {
9513                                 /* "if <true> then ... ELSE/ELIF cmd":
9514                                  * skip cmd and all following ones */
9515                                 break;
9516                         }
9517                 }
9518 #endif
9519 #if ENABLE_HUSH_LOOPS
9520                 if (rword == RES_FOR) { /* && pi->num_cmds - always == 1 */
9521                         if (!for_lcur) {
9522                                 /* first loop through for */
9523
9524                                 static const char encoded_dollar_at[] ALIGN1 = {
9525                                         SPECIAL_VAR_SYMBOL, '@' | 0x80, SPECIAL_VAR_SYMBOL, '\0'
9526                                 }; /* encoded representation of "$@" */
9527                                 static const char *const encoded_dollar_at_argv[] = {
9528                                         encoded_dollar_at, NULL
9529                                 }; /* argv list with one element: "$@" */
9530                                 char **vals;
9531
9532                                 G.last_exitcode = rcode = EXIT_SUCCESS;
9533                                 vals = (char**)encoded_dollar_at_argv;
9534                                 if (pi->next->res_word == RES_IN) {
9535                                         /* if no variable values after "in" we skip "for" */
9536                                         if (!pi->next->cmds[0].argv) {
9537                                                 debug_printf_exec(": null FOR: exitcode EXIT_SUCCESS\n");
9538                                                 break;
9539                                         }
9540                                         vals = pi->next->cmds[0].argv;
9541                                 } /* else: "for var; do..." -> assume "$@" list */
9542                                 /* create list of variable values */
9543                                 debug_print_strings("for_list made from", vals);
9544                                 for_list = expand_strvec_to_strvec(vals);
9545                                 for_lcur = for_list;
9546                                 debug_print_strings("for_list", for_list);
9547                         }
9548                         if (!*for_lcur) {
9549                                 /* "for" loop is over, clean up */
9550                                 free(for_list);
9551                                 for_list = NULL;
9552                                 for_lcur = NULL;
9553                                 break;
9554                         }
9555                         /* Insert next value from for_lcur */
9556                         /* note: *for_lcur already has quotes removed, $var expanded, etc */
9557                         set_local_var(xasprintf("%s=%s", pi->cmds[0].argv[0], *for_lcur++), /*flag:*/ 0);
9558                         continue;
9559                 }
9560                 if (rword == RES_IN) {
9561                         continue; /* "for v IN list;..." - "in" has no cmds anyway */
9562                 }
9563                 if (rword == RES_DONE) {
9564                         continue; /* "done" has no cmds too */
9565                 }
9566 #endif
9567 #if ENABLE_HUSH_CASE
9568                 if (rword == RES_CASE) {
9569                         debug_printf_exec("CASE cond_code:%d\n", cond_code);
9570                         case_word = expand_string_to_string(pi->cmds->argv[0],
9571                                 EXP_FLAG_ESC_GLOB_CHARS, /*unbackslash:*/ 1);
9572                         debug_printf_exec("CASE word1:'%s'\n", case_word);
9573                         //unbackslash(case_word);
9574                         //debug_printf_exec("CASE word2:'%s'\n", case_word);
9575                         continue;
9576                 }
9577                 if (rword == RES_MATCH) {
9578                         char **argv;
9579
9580                         debug_printf_exec("MATCH cond_code:%d\n", cond_code);
9581                         if (!case_word) /* "case ... matched_word) ... WORD)": we executed selected branch, stop */
9582                                 break;
9583                         /* all prev words didn't match, does this one match? */
9584                         argv = pi->cmds->argv;
9585                         while (*argv) {
9586                                 char *pattern;
9587                                 debug_printf_exec("expand_string_to_string('%s')\n", *argv);
9588                                 pattern = expand_string_to_string(*argv,
9589                                                 EXP_FLAG_ESC_GLOB_CHARS,
9590                                                 /*unbackslash:*/ 0
9591                                 );
9592                                 /* TODO: which FNM_xxx flags to use? */
9593                                 cond_code = (fnmatch(pattern, case_word, /*flags:*/ 0) != 0);
9594                                 debug_printf_exec("fnmatch(pattern:'%s',str:'%s'):%d\n",
9595                                                 pattern, case_word, cond_code);
9596                                 free(pattern);
9597                                 if (cond_code == 0) {
9598                                         /* match! we will execute this branch */
9599                                         free(case_word);
9600                                         case_word = NULL; /* make future "word)" stop */
9601                                         break;
9602                                 }
9603                                 argv++;
9604                         }
9605                         continue;
9606                 }
9607                 if (rword == RES_CASE_BODY) { /* inside of a case branch */
9608                         debug_printf_exec("CASE_BODY cond_code:%d\n", cond_code);
9609                         if (cond_code != 0)
9610                                 continue; /* not matched yet, skip this pipe */
9611                 }
9612                 if (rword == RES_ESAC) {
9613                         debug_printf_exec("ESAC cond_code:%d\n", cond_code);
9614                         if (case_word) {
9615                                 /* "case" did not match anything: still set $? (to 0) */
9616                                 G.last_exitcode = rcode = EXIT_SUCCESS;
9617                         }
9618                 }
9619 #endif
9620                 /* Just pressing <enter> in shell should check for jobs.
9621                  * OTOH, in non-interactive shell this is useless
9622                  * and only leads to extra job checks */
9623                 if (pi->num_cmds == 0) {
9624                         if (G_interactive_fd)
9625                                 goto check_jobs_and_continue;
9626                         continue;
9627                 }
9628
9629                 /* After analyzing all keywords and conditions, we decided
9630                  * to execute this pipe. NB: have to do checkjobs(NULL)
9631                  * after run_pipe to collect any background children,
9632                  * even if list execution is to be stopped. */
9633                 debug_printf_exec(": run_pipe with %d members\n", pi->num_cmds);
9634 #if ENABLE_HUSH_LOOPS
9635                 G.flag_break_continue = 0;
9636 #endif
9637                 rcode = r = run_pipe(pi); /* NB: rcode is a smalluint, r is int */
9638                 if (r != -1) {
9639                         /* We ran a builtin, function, or group.
9640                          * rcode is already known
9641                          * and we don't need to wait for anything. */
9642                         debug_printf_exec(": builtin/func exitcode %d\n", rcode);
9643                         G.last_exitcode = rcode;
9644                         check_and_run_traps();
9645 #if ENABLE_HUSH_TRAP && ENABLE_HUSH_FUNCTIONS
9646                         rcode = G.last_exitcode; /* "return" in trap can change it, read back */
9647 #endif
9648 #if ENABLE_HUSH_LOOPS
9649                         /* Was it "break" or "continue"? */
9650                         if (G.flag_break_continue) {
9651                                 smallint fbc = G.flag_break_continue;
9652                                 /* We might fall into outer *loop*,
9653                                  * don't want to break it too */
9654                                 if (loop_top) {
9655                                         G.depth_break_continue--;
9656                                         if (G.depth_break_continue == 0)
9657                                                 G.flag_break_continue = 0;
9658                                         /* else: e.g. "continue 2" should *break* once, *then* continue */
9659                                 } /* else: "while... do... { we are here (innermost list is not a loop!) };...done" */
9660                                 if (G.depth_break_continue != 0 || fbc == BC_BREAK) {
9661                                         checkjobs(NULL, 0 /*(no pid to wait for)*/);
9662                                         break;
9663                                 }
9664                                 /* "continue": simulate end of loop */
9665                                 rword = RES_DONE;
9666                                 continue;
9667                         }
9668 #endif
9669                         if (G_flag_return_in_progress == 1) {
9670                                 checkjobs(NULL, 0 /*(no pid to wait for)*/);
9671                                 break;
9672                         }
9673                 } else if (pi->followup == PIPE_BG) {
9674                         /* What does bash do with attempts to background builtins? */
9675                         /* even bash 3.2 doesn't do that well with nested bg:
9676                          * try "{ { sleep 10; echo DEEP; } & echo HERE; } &".
9677                          * I'm NOT treating inner &'s as jobs */
9678 #if ENABLE_HUSH_JOB
9679                         if (G.run_list_level == 1)
9680                                 insert_job_into_table(pi);
9681 #endif
9682                         /* Last command's pid goes to $! */
9683                         G.last_bg_pid = pi->cmds[pi->num_cmds - 1].pid;
9684                         G.last_bg_pid_exitcode = 0;
9685                         debug_printf_exec(": cmd&: exitcode EXIT_SUCCESS\n");
9686 /* Check pi->pi_inverted? "! sleep 1 & echo $?": bash says 1. dash and ash say 0 */
9687                         rcode = EXIT_SUCCESS;
9688                         goto check_traps;
9689                 } else {
9690 #if ENABLE_HUSH_JOB
9691                         if (G.run_list_level == 1 && G_interactive_fd) {
9692                                 /* Waits for completion, then fg's main shell */
9693                                 rcode = checkjobs_and_fg_shell(pi);
9694                                 debug_printf_exec(": checkjobs_and_fg_shell exitcode %d\n", rcode);
9695                                 goto check_traps;
9696                         }
9697 #endif
9698                         /* This one just waits for completion */
9699                         rcode = checkjobs(pi, 0 /*(no pid to wait for)*/);
9700                         debug_printf_exec(": checkjobs exitcode %d\n", rcode);
9701  check_traps:
9702                         G.last_exitcode = rcode;
9703                         check_and_run_traps();
9704 #if ENABLE_HUSH_TRAP && ENABLE_HUSH_FUNCTIONS
9705                         rcode = G.last_exitcode; /* "return" in trap can change it, read back */
9706 #endif
9707                 }
9708
9709                 /* Handle "set -e" */
9710                 if (rcode != 0 && G.o_opt[OPT_O_ERREXIT]) {
9711                         debug_printf_exec("ERREXIT:1 errexit_depth:%d\n", G.errexit_depth);
9712                         if (G.errexit_depth == 0)
9713                                 hush_exit(rcode);
9714                 }
9715                 G.errexit_depth = sv_errexit_depth;
9716
9717                 /* Analyze how result affects subsequent commands */
9718 #if ENABLE_HUSH_IF
9719                 if (rword == RES_IF || rword == RES_ELIF)
9720                         cond_code = rcode;
9721 #endif
9722  check_jobs_and_continue:
9723                 checkjobs(NULL, 0 /*(no pid to wait for)*/);
9724  dont_check_jobs_but_continue: ;
9725 #if ENABLE_HUSH_LOOPS
9726                 /* Beware of "while false; true; do ..."! */
9727                 if (pi->next
9728                  && (pi->next->res_word == RES_DO || pi->next->res_word == RES_DONE)
9729                  /* check for RES_DONE is needed for "while ...; do \n done" case */
9730                 ) {
9731                         if (rword == RES_WHILE) {
9732                                 if (rcode) {
9733                                         /* "while false; do...done" - exitcode 0 */
9734                                         G.last_exitcode = rcode = EXIT_SUCCESS;
9735                                         debug_printf_exec(": while expr is false: breaking (exitcode:EXIT_SUCCESS)\n");
9736                                         break;
9737                                 }
9738                         }
9739                         if (rword == RES_UNTIL) {
9740                                 if (!rcode) {
9741                                         debug_printf_exec(": until expr is true: breaking\n");
9742                                         break;
9743                                 }
9744                         }
9745                 }
9746 #endif
9747         } /* for (pi) */
9748
9749 #if ENABLE_HUSH_JOB
9750         G.run_list_level--;
9751 #endif
9752 #if ENABLE_HUSH_LOOPS
9753         if (loop_top)
9754                 G.depth_of_loop--;
9755         free(for_list);
9756 #endif
9757 #if ENABLE_HUSH_CASE
9758         free(case_word);
9759 #endif
9760         debug_leave();
9761         debug_printf_exec("run_list lvl %d return %d\n", G.run_list_level + 1, rcode);
9762         return rcode;
9763 }
9764
9765 /* Select which version we will use */
9766 static int run_and_free_list(struct pipe *pi)
9767 {
9768         int rcode = 0;
9769         debug_printf_exec("run_and_free_list entered\n");
9770         if (!G.o_opt[OPT_O_NOEXEC]) {
9771                 debug_printf_exec(": run_list: 1st pipe with %d cmds\n", pi->num_cmds);
9772                 rcode = run_list(pi);
9773         }
9774         /* free_pipe_list has the side effect of clearing memory.
9775          * In the long run that function can be merged with run_list,
9776          * but doing that now would hobble the debugging effort. */
9777         free_pipe_list(pi);
9778         debug_printf_exec("run_and_free_list return %d\n", rcode);
9779         return rcode;
9780 }
9781
9782
9783 static void install_sighandlers(unsigned mask)
9784 {
9785         sighandler_t old_handler;
9786         unsigned sig = 0;
9787         while ((mask >>= 1) != 0) {
9788                 sig++;
9789                 if (!(mask & 1))
9790                         continue;
9791                 old_handler = install_sighandler(sig, pick_sighandler(sig));
9792                 /* POSIX allows shell to re-enable SIGCHLD
9793                  * even if it was SIG_IGN on entry.
9794                  * Therefore we skip IGN check for it:
9795                  */
9796                 if (sig == SIGCHLD)
9797                         continue;
9798                 /* Interactive bash re-enables SIGHUP which is SIG_IGNed on entry.
9799                  * Try:
9800                  * trap '' hup; bash; echo RET  # type "kill -hup $$", see SIGHUP having effect
9801                  * trap '' hup; bash -c 'kill -hup $$; echo ALIVE'  # here SIGHUP is SIG_IGNed
9802                  */
9803                 if (sig == SIGHUP && G_interactive_fd)
9804                         continue;
9805                 /* Unless one of the above signals, is it SIG_IGN? */
9806                 if (old_handler == SIG_IGN) {
9807                         /* oops... restore back to IGN, and record this fact */
9808                         install_sighandler(sig, old_handler);
9809 #if ENABLE_HUSH_TRAP
9810                         if (!G_traps)
9811                                 G_traps = xzalloc(sizeof(G_traps[0]) * NSIG);
9812                         free(G_traps[sig]);
9813                         G_traps[sig] = xzalloc(1); /* == xstrdup(""); */
9814 #endif
9815                 }
9816         }
9817 }
9818
9819 /* Called a few times only (or even once if "sh -c") */
9820 static void install_special_sighandlers(void)
9821 {
9822         unsigned mask;
9823
9824         /* Which signals are shell-special? */
9825         mask = (1 << SIGQUIT) | (1 << SIGCHLD);
9826         if (G_interactive_fd) {
9827                 mask |= SPECIAL_INTERACTIVE_SIGS;
9828                 if (G_saved_tty_pgrp) /* we have ctty, job control sigs work */
9829                         mask |= SPECIAL_JOBSTOP_SIGS;
9830         }
9831         /* Careful, do not re-install handlers we already installed */
9832         if (G.special_sig_mask != mask) {
9833                 unsigned diff = mask & ~G.special_sig_mask;
9834                 G.special_sig_mask = mask;
9835                 install_sighandlers(diff);
9836         }
9837 }
9838
9839 #if ENABLE_HUSH_JOB
9840 /* helper */
9841 /* Set handlers to restore tty pgrp and exit */
9842 static void install_fatal_sighandlers(void)
9843 {
9844         unsigned mask;
9845
9846         /* We will restore tty pgrp on these signals */
9847         mask = 0
9848                 /*+ (1 << SIGILL ) * HUSH_DEBUG*/
9849                 /*+ (1 << SIGFPE ) * HUSH_DEBUG*/
9850                 + (1 << SIGBUS ) * HUSH_DEBUG
9851                 + (1 << SIGSEGV) * HUSH_DEBUG
9852                 /*+ (1 << SIGTRAP) * HUSH_DEBUG*/
9853                 + (1 << SIGABRT)
9854         /* bash 3.2 seems to handle these just like 'fatal' ones */
9855                 + (1 << SIGPIPE)
9856                 + (1 << SIGALRM)
9857         /* if we are interactive, SIGHUP, SIGTERM and SIGINT are special sigs.
9858          * if we aren't interactive... but in this case
9859          * we never want to restore pgrp on exit, and this fn is not called
9860          */
9861                 /*+ (1 << SIGHUP )*/
9862                 /*+ (1 << SIGTERM)*/
9863                 /*+ (1 << SIGINT )*/
9864         ;
9865         G_fatal_sig_mask = mask;
9866
9867         install_sighandlers(mask);
9868 }
9869 #endif
9870
9871 static int set_mode(int state, char mode, const char *o_opt)
9872 {
9873         int idx;
9874         switch (mode) {
9875         case 'n':
9876                 G.o_opt[OPT_O_NOEXEC] = state;
9877                 break;
9878         case 'x':
9879                 IF_HUSH_MODE_X(G_x_mode = state;)
9880                 IF_HUSH_MODE_X(if (G.x_mode_fd <= 0) G.x_mode_fd = dup_CLOEXEC(2, 10);)
9881                 break;
9882         case 'e':
9883                 G.o_opt[OPT_O_ERREXIT] = state;
9884                 break;
9885         case 'o':
9886                 if (!o_opt) {
9887                         /* "set -o" or "set +o" without parameter.
9888                          * in bash, set -o produces this output:
9889                          *  pipefail        off
9890                          * and set +o:
9891                          *  set +o pipefail
9892                          * We always use the second form.
9893                          */
9894                         const char *p = o_opt_strings;
9895                         idx = 0;
9896                         while (*p) {
9897                                 printf("set %co %s\n", (G.o_opt[idx] ? '-' : '+'), p);
9898                                 idx++;
9899                                 p += strlen(p) + 1;
9900                         }
9901                         break;
9902                 }
9903                 idx = index_in_strings(o_opt_strings, o_opt);
9904                 if (idx >= 0) {
9905                         G.o_opt[idx] = state;
9906                         break;
9907                 }
9908                 /* fall through to error */
9909         default:
9910                 return EXIT_FAILURE;
9911         }
9912         return EXIT_SUCCESS;
9913 }
9914
9915 int hush_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
9916 int hush_main(int argc, char **argv)
9917 {
9918         enum {
9919                 OPT_login = (1 << 0),
9920         };
9921         unsigned flags;
9922         unsigned builtin_argc;
9923         char **e;
9924         struct variable *cur_var;
9925         struct variable *shell_ver;
9926
9927         INIT_G();
9928         if (EXIT_SUCCESS != 0) /* if EXIT_SUCCESS == 0, it is already done */
9929                 G.last_exitcode = EXIT_SUCCESS;
9930 #if ENABLE_HUSH_TRAP && ENABLE_HUSH_FUNCTIONS
9931         G.return_exitcode = -1;
9932 #endif
9933
9934 #if ENABLE_HUSH_FAST
9935         G.count_SIGCHLD++; /* ensure it is != G.handled_SIGCHLD */
9936 #endif
9937 #if !BB_MMU
9938         G.argv0_for_re_execing = argv[0];
9939 #endif
9940
9941         /* Deal with HUSH_VERSION */
9942         debug_printf_env("unsetenv '%s'\n", "HUSH_VERSION");
9943         unsetenv("HUSH_VERSION"); /* in case it exists in initial env */
9944         shell_ver = xzalloc(sizeof(*shell_ver));
9945         shell_ver->flg_export = 1;
9946         shell_ver->flg_read_only = 1;
9947         /* Code which handles ${var<op>...} needs writable values for all variables,
9948          * therefore we xstrdup: */
9949         shell_ver->varstr = xstrdup(hush_version_str);
9950
9951         /* Create shell local variables from the values
9952          * currently living in the environment */
9953         G.top_var = shell_ver;
9954         cur_var = G.top_var;
9955         e = environ;
9956         if (e) while (*e) {
9957                 char *value = strchr(*e, '=');
9958                 if (value) { /* paranoia */
9959                         cur_var->next = xzalloc(sizeof(*cur_var));
9960                         cur_var = cur_var->next;
9961                         cur_var->varstr = *e;
9962                         cur_var->max_len = strlen(*e);
9963                         cur_var->flg_export = 1;
9964                 }
9965                 e++;
9966         }
9967         /* (Re)insert HUSH_VERSION into env (AFTER we scanned the env!) */
9968         debug_printf_env("putenv '%s'\n", shell_ver->varstr);
9969         putenv(shell_ver->varstr);
9970
9971         /* Export PWD */
9972         set_pwd_var(SETFLAG_EXPORT);
9973
9974 #if BASH_HOSTNAME_VAR
9975         /* Set (but not export) HOSTNAME unless already set */
9976         if (!get_local_var_value("HOSTNAME")) {
9977                 struct utsname uts;
9978                 uname(&uts);
9979                 set_local_var_from_halves("HOSTNAME", uts.nodename);
9980         }
9981 #endif
9982         /* IFS is not inherited from the parent environment */
9983         set_local_var_from_halves("IFS", defifs);
9984
9985         if (!get_local_var_value("PATH"))
9986                 set_local_var_from_halves("PATH", bb_default_root_path);
9987
9988         /* PS1/PS2 are set later, if we determine that we are interactive */
9989
9990         /* bash also exports SHLVL and _,
9991          * and sets (but doesn't export) the following variables:
9992          * BASH=/bin/bash
9993          * BASH_VERSINFO=([0]="3" [1]="2" [2]="0" [3]="1" [4]="release" [5]="i386-pc-linux-gnu")
9994          * BASH_VERSION='3.2.0(1)-release'
9995          * HOSTTYPE=i386
9996          * MACHTYPE=i386-pc-linux-gnu
9997          * OSTYPE=linux-gnu
9998          * PPID=<NNNNN> - we also do it elsewhere
9999          * EUID=<NNNNN>
10000          * UID=<NNNNN>
10001          * GROUPS=()
10002          * LINES=<NNN>
10003          * COLUMNS=<NNN>
10004          * BASH_ARGC=()
10005          * BASH_ARGV=()
10006          * BASH_LINENO=()
10007          * BASH_SOURCE=()
10008          * DIRSTACK=()
10009          * PIPESTATUS=([0]="0")
10010          * HISTFILE=/<xxx>/.bash_history
10011          * HISTFILESIZE=500
10012          * HISTSIZE=500
10013          * MAILCHECK=60
10014          * PATH=/usr/gnu/bin:/usr/local/bin:/bin:/usr/bin:.
10015          * SHELL=/bin/bash
10016          * SHELLOPTS=braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor
10017          * TERM=dumb
10018          * OPTERR=1
10019          * OPTIND=1
10020          * PS4='+ '
10021          */
10022
10023         /* Initialize some more globals to non-zero values */
10024         die_func = restore_ttypgrp_and__exit;
10025
10026         /* Shell is non-interactive at first. We need to call
10027          * install_special_sighandlers() if we are going to execute "sh <script>",
10028          * "sh -c <cmds>" or login shell's /etc/profile and friends.
10029          * If we later decide that we are interactive, we run install_special_sighandlers()
10030          * in order to intercept (more) signals.
10031          */
10032
10033         /* Parse options */
10034         /* http://www.opengroup.org/onlinepubs/9699919799/utilities/sh.html */
10035         flags = (argv[0] && argv[0][0] == '-') ? OPT_login : 0;
10036         builtin_argc = 0;
10037 #if NUM_SCRIPTS > 0
10038         if (argc < 0) {
10039                 optarg = get_script_content(-argc - 1);
10040                 optind = 0;
10041                 argc = string_array_len(argv);
10042                 goto run_script;
10043         }
10044 #endif
10045         while (1) {
10046                 int opt = getopt(argc, argv, "+c:exinsl"
10047 #if !BB_MMU
10048                                 "<:$:R:V:"
10049 # if ENABLE_HUSH_FUNCTIONS
10050                                 "F:"
10051 # endif
10052 #endif
10053                 );
10054                 if (opt <= 0)
10055                         break;
10056                 switch (opt) {
10057                 case 'c':
10058                         /* Possibilities:
10059                          * sh ... -c 'script'
10060                          * sh ... -c 'script' ARG0 [ARG1...]
10061                          * On NOMMU, if builtin_argc != 0,
10062                          * sh ... -c 'builtin' BARGV... "" ARG0 [ARG1...]
10063                          * "" needs to be replaced with NULL
10064                          * and BARGV vector fed to builtin function.
10065                          * Note: the form without ARG0 never happens:
10066                          * sh ... -c 'builtin' BARGV... ""
10067                          */
10068 #if NUM_SCRIPTS > 0
10069  run_script:
10070 #endif
10071                         if (!G.root_pid) {
10072                                 G.root_pid = getpid();
10073                                 G.root_ppid = getppid();
10074                         }
10075                         G.global_argv = argv + optind;
10076                         G.global_argc = argc - optind;
10077                         if (builtin_argc) {
10078                                 /* -c 'builtin' [BARGV...] "" ARG0 [ARG1...] */
10079                                 const struct built_in_command *x;
10080
10081                                 install_special_sighandlers();
10082                                 x = find_builtin(optarg);
10083                                 if (x) { /* paranoia */
10084                                         G.global_argc -= builtin_argc; /* skip [BARGV...] "" */
10085                                         G.global_argv += builtin_argc;
10086                                         G.global_argv[-1] = NULL; /* replace "" */
10087                                         fflush_all();
10088                                         G.last_exitcode = x->b_function(argv + optind - 1);
10089                                 }
10090                                 goto final_return;
10091                         }
10092                         G.opt_c = 1;
10093                         if (!G.global_argv[0]) {
10094                                 /* -c 'script' (no params): prevent empty $0 */
10095                                 G.global_argv--; /* points to argv[i] of 'script' */
10096                                 G.global_argv[0] = argv[0];
10097                                 G.global_argc++;
10098                         } /* else -c 'script' ARG0 [ARG1...]: $0 is ARG0 */
10099                         install_special_sighandlers();
10100                         parse_and_run_string(optarg);
10101                         goto final_return;
10102                 case 'i':
10103                         /* Well, we cannot just declare interactiveness,
10104                          * we have to have some stuff (ctty, etc) */
10105                         /* G_interactive_fd++; */
10106                         break;
10107                 case 's':
10108                         G.opt_s = 1;
10109                         break;
10110                 case 'l':
10111                         flags |= OPT_login;
10112                         break;
10113 #if !BB_MMU
10114                 case '<': /* "big heredoc" support */
10115                         full_write1_str(optarg);
10116                         _exit(0);
10117                 case '$': {
10118                         unsigned long long empty_trap_mask;
10119
10120                         G.root_pid = bb_strtou(optarg, &optarg, 16);
10121                         optarg++;
10122                         G.root_ppid = bb_strtou(optarg, &optarg, 16);
10123                         optarg++;
10124                         G.last_bg_pid = bb_strtou(optarg, &optarg, 16);
10125                         optarg++;
10126                         G.last_exitcode = bb_strtou(optarg, &optarg, 16);
10127                         optarg++;
10128                         builtin_argc = bb_strtou(optarg, &optarg, 16);
10129                         optarg++;
10130                         empty_trap_mask = bb_strtoull(optarg, &optarg, 16);
10131                         if (empty_trap_mask != 0) {
10132                                 IF_HUSH_TRAP(int sig;)
10133                                 install_special_sighandlers();
10134 # if ENABLE_HUSH_TRAP
10135                                 G_traps = xzalloc(sizeof(G_traps[0]) * NSIG);
10136                                 for (sig = 1; sig < NSIG; sig++) {
10137                                         if (empty_trap_mask & (1LL << sig)) {
10138                                                 G_traps[sig] = xzalloc(1); /* == xstrdup(""); */
10139                                                 install_sighandler(sig, SIG_IGN);
10140                                         }
10141                                 }
10142 # endif
10143                         }
10144 # if ENABLE_HUSH_LOOPS
10145                         optarg++;
10146                         G.depth_of_loop = bb_strtou(optarg, &optarg, 16);
10147 # endif
10148 # if ENABLE_HUSH_FUNCTIONS
10149                         /* nommu uses re-exec trick for "... | func | ...",
10150                          * should allow "return".
10151                          * This accidentally allows returns in subshells.
10152                          */
10153                         G_flag_return_in_progress = -1;
10154 # endif
10155                         break;
10156                 }
10157                 case 'R':
10158                 case 'V':
10159                         set_local_var(xstrdup(optarg), opt == 'R' ? SETFLAG_MAKE_RO : 0);
10160                         break;
10161 # if ENABLE_HUSH_FUNCTIONS
10162                 case 'F': {
10163                         struct function *funcp = new_function(optarg);
10164                         /* funcp->name is already set to optarg */
10165                         /* funcp->body is set to NULL. It's a special case. */
10166                         funcp->body_as_string = argv[optind];
10167                         optind++;
10168                         break;
10169                 }
10170 # endif
10171 #endif
10172                 case 'n':
10173                 case 'x':
10174                 case 'e':
10175                         if (set_mode(1, opt, NULL) == 0) /* no error */
10176                                 break;
10177                 default:
10178 #ifndef BB_VER
10179                         fprintf(stderr, "Usage: sh [FILE]...\n"
10180                                         "   or: sh -c command [args]...\n\n");
10181                         exit(EXIT_FAILURE);
10182 #else
10183                         bb_show_usage();
10184 #endif
10185                 }
10186         } /* option parsing loop */
10187
10188         /* Skip options. Try "hush -l": $1 should not be "-l"! */
10189         G.global_argc = argc - (optind - 1);
10190         G.global_argv = argv + (optind - 1);
10191         G.global_argv[0] = argv[0];
10192
10193         if (!G.root_pid) {
10194                 G.root_pid = getpid();
10195                 G.root_ppid = getppid();
10196         }
10197
10198         /* If we are login shell... */
10199         if (flags & OPT_login) {
10200                 HFILE *input;
10201                 debug_printf("sourcing /etc/profile\n");
10202                 input = hfopen("/etc/profile");
10203                 if (input != NULL) {
10204                         install_special_sighandlers();
10205                         parse_and_run_file(input);
10206                         hfclose(input);
10207                 }
10208                 /* bash: after sourcing /etc/profile,
10209                  * tries to source (in the given order):
10210                  * ~/.bash_profile, ~/.bash_login, ~/.profile,
10211                  * stopping on first found. --noprofile turns this off.
10212                  * bash also sources ~/.bash_logout on exit.
10213                  * If called as sh, skips .bash_XXX files.
10214                  */
10215         }
10216
10217         /* -s is: hush -s ARGV1 ARGV2 (no SCRIPT) */
10218         if (!G.opt_s && G.global_argv[1]) {
10219                 HFILE *input;
10220                 /*
10221                  * "bash <script>" (which is never interactive (unless -i?))
10222                  * sources $BASH_ENV here (without scanning $PATH).
10223                  * If called as sh, does the same but with $ENV.
10224                  * Also NB, per POSIX, $ENV should undergo parameter expansion.
10225                  */
10226                 G.global_argc--;
10227                 G.global_argv++;
10228                 debug_printf("running script '%s'\n", G.global_argv[0]);
10229                 xfunc_error_retval = 127; /* for "hush /does/not/exist" case */
10230                 input = hfopen(G.global_argv[0]);
10231                 if (!input) {
10232                         bb_simple_perror_msg_and_die(G.global_argv[0]);
10233                 }
10234                 xfunc_error_retval = 1;
10235                 install_special_sighandlers();
10236                 parse_and_run_file(input);
10237 #if ENABLE_FEATURE_CLEAN_UP
10238                 hfclose(input);
10239 #endif
10240                 goto final_return;
10241         }
10242         /* "implicit" -s: bare interactive hush shows 's' in $- */
10243         G.opt_s = 1;
10244
10245         /* Up to here, shell was non-interactive. Now it may become one.
10246          * NB: don't forget to (re)run install_special_sighandlers() as needed.
10247          */
10248
10249         /* A shell is interactive if the '-i' flag was given,
10250          * or if all of the following conditions are met:
10251          *    no -c command
10252          *    no arguments remaining or the -s flag given
10253          *    standard input is a terminal
10254          *    standard output is a terminal
10255          * Refer to Posix.2, the description of the 'sh' utility.
10256          */
10257 #if ENABLE_HUSH_JOB
10258         if (isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)) {
10259                 G_saved_tty_pgrp = tcgetpgrp(STDIN_FILENO);
10260                 debug_printf("saved_tty_pgrp:%d\n", G_saved_tty_pgrp);
10261                 if (G_saved_tty_pgrp < 0)
10262                         G_saved_tty_pgrp = 0;
10263
10264                 /* try to dup stdin to high fd#, >= 255 */
10265                 G_interactive_fd = dup_CLOEXEC(STDIN_FILENO, 254);
10266                 if (G_interactive_fd < 0) {
10267                         /* try to dup to any fd */
10268                         G_interactive_fd = dup(STDIN_FILENO);
10269                         if (G_interactive_fd < 0) {
10270                                 /* give up */
10271                                 G_interactive_fd = 0;
10272                                 G_saved_tty_pgrp = 0;
10273                         }
10274                 }
10275         }
10276         debug_printf("interactive_fd:%d\n", G_interactive_fd);
10277         if (G_interactive_fd) {
10278                 close_on_exec_on(G_interactive_fd);
10279
10280                 if (G_saved_tty_pgrp) {
10281                         /* If we were run as 'hush &', sleep until we are
10282                          * in the foreground (tty pgrp == our pgrp).
10283                          * If we get started under a job aware app (like bash),
10284                          * make sure we are now in charge so we don't fight over
10285                          * who gets the foreground */
10286                         while (1) {
10287                                 pid_t shell_pgrp = getpgrp();
10288                                 G_saved_tty_pgrp = tcgetpgrp(G_interactive_fd);
10289                                 if (G_saved_tty_pgrp == shell_pgrp)
10290                                         break;
10291                                 /* send TTIN to ourself (should stop us) */
10292                                 kill(- shell_pgrp, SIGTTIN);
10293                         }
10294                 }
10295
10296                 /* Install more signal handlers */
10297                 install_special_sighandlers();
10298
10299                 if (G_saved_tty_pgrp) {
10300                         /* Set other signals to restore saved_tty_pgrp */
10301                         install_fatal_sighandlers();
10302                         /* Put ourselves in our own process group
10303                          * (bash, too, does this only if ctty is available) */
10304                         bb_setpgrp(); /* is the same as setpgid(our_pid, our_pid); */
10305                         /* Grab control of the terminal */
10306                         tcsetpgrp(G_interactive_fd, getpid());
10307                 }
10308                 enable_restore_tty_pgrp_on_exit();
10309
10310 # if ENABLE_FEATURE_EDITING
10311                 G.line_input_state = new_line_input_t(FOR_SHELL);
10312 #  if EDITING_HAS_get_exe_name
10313                 G.line_input_state->get_exe_name = get_builtin_name;
10314 #  endif
10315 # endif
10316 # if ENABLE_HUSH_SAVEHISTORY && MAX_HISTORY > 0
10317                 {
10318                         const char *hp = get_local_var_value("HISTFILE");
10319                         if (!hp) {
10320                                 hp = get_local_var_value("HOME");
10321                                 if (hp)
10322                                         hp = concat_path_file(hp, ".hush_history");
10323                         } else {
10324                                 hp = xstrdup(hp);
10325                         }
10326                         if (hp) {
10327                                 G.line_input_state->hist_file = hp;
10328                                 //set_local_var(xasprintf("HISTFILE=%s", ...));
10329                         }
10330 #  if ENABLE_FEATURE_SH_HISTFILESIZE
10331                         hp = get_local_var_value("HISTFILESIZE");
10332                         G.line_input_state->max_history = size_from_HISTFILESIZE(hp);
10333 #  endif
10334                 }
10335 # endif
10336         } else {
10337                 install_special_sighandlers();
10338         }
10339 #elif ENABLE_HUSH_INTERACTIVE
10340         /* No job control compiled in, only prompt/line editing */
10341         if (isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)) {
10342                 G_interactive_fd = dup_CLOEXEC(STDIN_FILENO, 254);
10343                 if (G_interactive_fd < 0) {
10344                         /* try to dup to any fd */
10345                         G_interactive_fd = dup_CLOEXEC(STDIN_FILENO, -1);
10346                         if (G_interactive_fd < 0)
10347                                 /* give up */
10348                                 G_interactive_fd = 0;
10349                 }
10350         }
10351         if (G_interactive_fd) {
10352                 close_on_exec_on(G_interactive_fd);
10353         }
10354         install_special_sighandlers();
10355 #else
10356         /* We have interactiveness code disabled */
10357         install_special_sighandlers();
10358 #endif
10359         /* bash:
10360          * if interactive but not a login shell, sources ~/.bashrc
10361          * (--norc turns this off, --rcfile <file> overrides)
10362          */
10363
10364         if (G_interactive_fd) {
10365 #if ENABLE_HUSH_INTERACTIVE && ENABLE_FEATURE_EDITING_FANCY_PROMPT
10366                 /* Set (but not export) PS1/2 unless already set */
10367                 if (!get_local_var_value("PS1"))
10368                         set_local_var_from_halves("PS1", "\\w \\$ ");
10369                 if (!get_local_var_value("PS2"))
10370                         set_local_var_from_halves("PS2", "> ");
10371 #endif
10372                 if (!ENABLE_FEATURE_SH_EXTRA_QUIET) {
10373                         /* note: ash and hush share this string */
10374                         printf("\n\n%s %s\n"
10375                                 IF_HUSH_HELP("Enter 'help' for a list of built-in commands.\n")
10376                                 "\n",
10377                                 bb_banner,
10378                                 "hush - the humble shell"
10379                         );
10380                 }
10381         }
10382
10383         parse_and_run_file(hfopen(NULL)); /* stdin */
10384
10385  final_return:
10386         hush_exit(G.last_exitcode);
10387 }
10388
10389
10390 /*
10391  * Built-ins
10392  */
10393 static int FAST_FUNC builtin_true(char **argv UNUSED_PARAM)
10394 {
10395         return 0;
10396 }
10397
10398 #if ENABLE_HUSH_TEST || ENABLE_HUSH_ECHO || ENABLE_HUSH_PRINTF || ENABLE_HUSH_KILL
10399 static int run_applet_main(char **argv, int (*applet_main_func)(int argc, char **argv))
10400 {
10401         int argc = string_array_len(argv);
10402         return applet_main_func(argc, argv);
10403 }
10404 #endif
10405 #if ENABLE_HUSH_TEST || BASH_TEST2
10406 static int FAST_FUNC builtin_test(char **argv)
10407 {
10408         return run_applet_main(argv, test_main);
10409 }
10410 #endif
10411 #if ENABLE_HUSH_ECHO
10412 static int FAST_FUNC builtin_echo(char **argv)
10413 {
10414         return run_applet_main(argv, echo_main);
10415 }
10416 #endif
10417 #if ENABLE_HUSH_PRINTF
10418 static int FAST_FUNC builtin_printf(char **argv)
10419 {
10420         return run_applet_main(argv, printf_main);
10421 }
10422 #endif
10423
10424 #if ENABLE_HUSH_HELP
10425 static int FAST_FUNC builtin_help(char **argv UNUSED_PARAM)
10426 {
10427         const struct built_in_command *x;
10428
10429         printf(
10430                 "Built-in commands:\n"
10431                 "------------------\n");
10432         for (x = bltins1; x != &bltins1[ARRAY_SIZE(bltins1)]; x++) {
10433                 if (x->b_descr)
10434                         printf("%-10s%s\n", x->b_cmd, x->b_descr);
10435         }
10436         return EXIT_SUCCESS;
10437 }
10438 #endif
10439
10440 #if MAX_HISTORY && ENABLE_FEATURE_EDITING
10441 static int FAST_FUNC builtin_history(char **argv UNUSED_PARAM)
10442 {
10443         if (G.line_input_state)
10444                 show_history(G.line_input_state);
10445         return EXIT_SUCCESS;
10446 }
10447 #endif
10448
10449 static char **skip_dash_dash(char **argv)
10450 {
10451         argv++;
10452         if (argv[0] && argv[0][0] == '-' && argv[0][1] == '-' && argv[0][2] == '\0')
10453                 argv++;
10454         return argv;
10455 }
10456
10457 static int FAST_FUNC builtin_cd(char **argv)
10458 {
10459         const char *newdir;
10460
10461         argv = skip_dash_dash(argv);
10462         newdir = argv[0];
10463         if (newdir == NULL) {
10464                 /* bash does nothing (exitcode 0) if HOME is ""; if it's unset,
10465                  * bash says "bash: cd: HOME not set" and does nothing
10466                  * (exitcode 1)
10467                  */
10468                 const char *home = get_local_var_value("HOME");
10469                 newdir = home ? home : "/";
10470         }
10471         if (chdir(newdir)) {
10472                 /* Mimic bash message exactly */
10473                 bb_perror_msg("cd: %s", newdir);
10474                 return EXIT_FAILURE;
10475         }
10476         /* Read current dir (get_cwd(1) is inside) and set PWD.
10477          * Note: do not enforce exporting. If PWD was unset or unexported,
10478          * set it again, but do not export. bash does the same.
10479          */
10480         set_pwd_var(/*flag:*/ 0);
10481         return EXIT_SUCCESS;
10482 }
10483
10484 static int FAST_FUNC builtin_pwd(char **argv UNUSED_PARAM)
10485 {
10486         puts(get_cwd(0));
10487         return EXIT_SUCCESS;
10488 }
10489
10490 static int FAST_FUNC builtin_eval(char **argv)
10491 {
10492         argv = skip_dash_dash(argv);
10493
10494         if (!argv[0])
10495                 return EXIT_SUCCESS;
10496
10497         IF_HUSH_MODE_X(G.x_mode_depth++;)
10498         //bb_error_msg("%s: ++x_mode_depth=%d", __func__, G.x_mode_depth);
10499         if (!argv[1]) {
10500                 /* bash:
10501                  * eval "echo Hi; done" ("done" is syntax error):
10502                  * "echo Hi" will not execute too.
10503                  */
10504                 parse_and_run_string(argv[0]);
10505         } else {
10506                 /* "The eval utility shall construct a command by
10507                  * concatenating arguments together, separating
10508                  * each with a <space> character."
10509                  */
10510                 char *str, *p;
10511                 unsigned len = 0;
10512                 char **pp = argv;
10513                 do
10514                         len += strlen(*pp) + 1;
10515                 while (*++pp);
10516                 str = p = xmalloc(len);
10517                 pp = argv;
10518                 for (;;) {
10519                         p = stpcpy(p, *pp);
10520                         pp++;
10521                         if (!*pp)
10522                                 break;
10523                         *p++ = ' ';
10524                 }
10525                 parse_and_run_string(str);
10526                 free(str);
10527         }
10528         IF_HUSH_MODE_X(G.x_mode_depth--;)
10529         //bb_error_msg("%s: --x_mode_depth=%d", __func__, G.x_mode_depth);
10530         return G.last_exitcode;
10531 }
10532
10533 static int FAST_FUNC builtin_exec(char **argv)
10534 {
10535         argv = skip_dash_dash(argv);
10536         if (argv[0] == NULL)
10537                 return EXIT_SUCCESS; /* bash does this */
10538
10539         /* Careful: we can end up here after [v]fork. Do not restore
10540          * tty pgrp then, only top-level shell process does that */
10541         if (G_saved_tty_pgrp && getpid() == G.root_pid)
10542                 tcsetpgrp(G_interactive_fd, G_saved_tty_pgrp);
10543
10544         /* Saved-redirect fds, script fds and G_interactive_fd are still
10545          * open here. However, they are all CLOEXEC, and execv below
10546          * closes them. Try interactive "exec ls -l /proc/self/fd",
10547          * it should show no extra open fds in the "ls" process.
10548          * If we'd try to run builtins/NOEXECs, this would need improving.
10549          */
10550         //close_saved_fds_and_FILE_fds();
10551
10552         /* TODO: if exec fails, bash does NOT exit! We do.
10553          * We'll need to undo trap cleanup (it's inside execvp_or_die)
10554          * and tcsetpgrp, and this is inherently racy.
10555          */
10556         execvp_or_die(argv);
10557 }
10558
10559 static int FAST_FUNC builtin_exit(char **argv)
10560 {
10561         debug_printf_exec("%s()\n", __func__);
10562
10563         /* interactive bash:
10564          * # trap "echo EEE" EXIT
10565          * # exit
10566          * exit
10567          * There are stopped jobs.
10568          * (if there are _stopped_ jobs, running ones don't count)
10569          * # exit
10570          * exit
10571          * EEE (then bash exits)
10572          *
10573          * TODO: we can use G.exiting = -1 as indicator "last cmd was exit"
10574          */
10575
10576         /* note: EXIT trap is run by hush_exit */
10577         argv = skip_dash_dash(argv);
10578         if (argv[0] == NULL)
10579                 hush_exit(G.last_exitcode);
10580         /* mimic bash: exit 123abc == exit 255 + error msg */
10581         xfunc_error_retval = 255;
10582         /* bash: exit -2 == exit 254, no error msg */
10583         hush_exit(xatoi(argv[0]) & 0xff);
10584 }
10585
10586 #if ENABLE_HUSH_TYPE
10587 /* http://www.opengroup.org/onlinepubs/9699919799/utilities/type.html */
10588 static int FAST_FUNC builtin_type(char **argv)
10589 {
10590         int ret = EXIT_SUCCESS;
10591
10592         while (*++argv) {
10593                 const char *type;
10594                 char *path = NULL;
10595
10596                 if (0) {} /* make conditional compile easier below */
10597                 /*else if (find_alias(*argv))
10598                         type = "an alias";*/
10599 # if ENABLE_HUSH_FUNCTIONS
10600                 else if (find_function(*argv))
10601                         type = "a function";
10602 # endif
10603                 else if (find_builtin(*argv))
10604                         type = "a shell builtin";
10605                 else if ((path = find_in_path(*argv)) != NULL)
10606                         type = path;
10607                 else {
10608                         bb_error_msg("type: %s: not found", *argv);
10609                         ret = EXIT_FAILURE;
10610                         continue;
10611                 }
10612
10613                 printf("%s is %s\n", *argv, type);
10614                 free(path);
10615         }
10616
10617         return ret;
10618 }
10619 #endif
10620
10621 #if ENABLE_HUSH_READ
10622 /* Interruptibility of read builtin in bash
10623  * (tested on bash-4.2.8 by sending signals (not by ^C)):
10624  *
10625  * Empty trap makes read ignore corresponding signal, for any signal.
10626  *
10627  * SIGINT:
10628  * - terminates non-interactive shell;
10629  * - interrupts read in interactive shell;
10630  * if it has non-empty trap:
10631  * - executes trap and returns to command prompt in interactive shell;
10632  * - executes trap and returns to read in non-interactive shell;
10633  * SIGTERM:
10634  * - is ignored (does not interrupt) read in interactive shell;
10635  * - terminates non-interactive shell;
10636  * if it has non-empty trap:
10637  * - executes trap and returns to read;
10638  * SIGHUP:
10639  * - terminates shell (regardless of interactivity);
10640  * if it has non-empty trap:
10641  * - executes trap and returns to read;
10642  * SIGCHLD from children:
10643  * - does not interrupt read regardless of interactivity:
10644  *   try: sleep 1 & read x; echo $x
10645  */
10646 static int FAST_FUNC builtin_read(char **argv)
10647 {
10648         const char *r;
10649         struct builtin_read_params params;
10650
10651         memset(&params, 0, sizeof(params));
10652
10653         /* "!": do not abort on errors.
10654          * Option string must start with "sr" to match BUILTIN_READ_xxx
10655          */
10656         params.read_flags = getopt32(argv,
10657 # if BASH_READ_D
10658                 "!srn:p:t:u:d:", &params.opt_n, &params.opt_p, &params.opt_t, &params.opt_u, &params.opt_d
10659 # else
10660                 "!srn:p:t:u:", &params.opt_n, &params.opt_p, &params.opt_t, &params.opt_u
10661 # endif
10662         );
10663         if ((uint32_t)params.read_flags == (uint32_t)-1)
10664                 return EXIT_FAILURE;
10665         argv += optind;
10666         params.argv = argv;
10667         params.setvar = set_local_var_from_halves;
10668         params.ifs = get_local_var_value("IFS"); /* can be NULL */
10669
10670  again:
10671         r = shell_builtin_read(&params);
10672
10673         if ((uintptr_t)r == 1 && errno == EINTR) {
10674                 unsigned sig = check_and_run_traps();
10675                 if (sig != SIGINT)
10676                         goto again;
10677         }
10678
10679         if ((uintptr_t)r > 1) {
10680                 bb_simple_error_msg(r);
10681                 r = (char*)(uintptr_t)1;
10682         }
10683
10684         return (uintptr_t)r;
10685 }
10686 #endif
10687
10688 #if ENABLE_HUSH_UMASK
10689 static int FAST_FUNC builtin_umask(char **argv)
10690 {
10691         int rc;
10692         mode_t mask;
10693
10694         rc = 1;
10695         mask = umask(0);
10696         argv = skip_dash_dash(argv);
10697         if (argv[0]) {
10698                 mode_t old_mask = mask;
10699
10700                 /* numeric umasks are taken as-is */
10701                 /* symbolic umasks are inverted: "umask a=rx" calls umask(222) */
10702                 if (!isdigit(argv[0][0]))
10703                         mask ^= 0777;
10704                 mask = bb_parse_mode(argv[0], mask);
10705                 if (!isdigit(argv[0][0]))
10706                         mask ^= 0777;
10707                 if ((unsigned)mask > 0777) {
10708                         mask = old_mask;
10709                         /* bash messages:
10710                          * bash: umask: 'q': invalid symbolic mode operator
10711                          * bash: umask: 999: octal number out of range
10712                          */
10713                         bb_error_msg("%s: invalid mode '%s'", "umask", argv[0]);
10714                         rc = 0;
10715                 }
10716         } else {
10717                 /* Mimic bash */
10718                 printf("%04o\n", (unsigned) mask);
10719                 /* fall through and restore mask which we set to 0 */
10720         }
10721         umask(mask);
10722
10723         return !rc; /* rc != 0 - success */
10724 }
10725 #endif
10726
10727 #if ENABLE_HUSH_EXPORT || ENABLE_HUSH_TRAP
10728 static void print_escaped(const char *s)
10729 {
10730         if (*s == '\'')
10731                 goto squote;
10732         do {
10733                 const char *p = strchrnul(s, '\'');
10734                 /* print 'xxxx', possibly just '' */
10735                 printf("'%.*s'", (int)(p - s), s);
10736                 if (*p == '\0')
10737                         break;
10738                 s = p;
10739  squote:
10740                 /* s points to '; print "'''...'''" */
10741                 putchar('"');
10742                 do putchar('\''); while (*++s == '\'');
10743                 putchar('"');
10744         } while (*s);
10745 }
10746 #endif
10747
10748 #if ENABLE_HUSH_EXPORT || ENABLE_HUSH_LOCAL || ENABLE_HUSH_READONLY
10749 static int helper_export_local(char **argv, unsigned flags)
10750 {
10751         do {
10752                 char *name = *argv;
10753                 const char *name_end = endofname(name);
10754
10755                 if (*name_end == '\0') {
10756                         struct variable *var, **vpp;
10757
10758                         vpp = get_ptr_to_local_var(name, name_end - name);
10759                         var = vpp ? *vpp : NULL;
10760
10761                         if (flags & SETFLAG_UNEXPORT) {
10762                                 /* export -n NAME (without =VALUE) */
10763                                 if (var) {
10764                                         var->flg_export = 0;
10765                                         debug_printf_env("%s: unsetenv '%s'\n", __func__, name);
10766                                         unsetenv(name);
10767                                 } /* else: export -n NOT_EXISTING_VAR: no-op */
10768                                 continue;
10769                         }
10770                         if (flags & SETFLAG_EXPORT) {
10771                                 /* export NAME (without =VALUE) */
10772                                 if (var) {
10773                                         var->flg_export = 1;
10774                                         debug_printf_env("%s: putenv '%s'\n", __func__, var->varstr);
10775                                         putenv(var->varstr);
10776                                         continue;
10777                                 }
10778                         }
10779                         if (flags & SETFLAG_MAKE_RO) {
10780                                 /* readonly NAME (without =VALUE) */
10781                                 if (var) {
10782                                         var->flg_read_only = 1;
10783                                         continue;
10784                                 }
10785                         }
10786 # if ENABLE_HUSH_LOCAL
10787                         /* Is this "local" bltin? */
10788                         if (!(flags & (SETFLAG_EXPORT|SETFLAG_UNEXPORT|SETFLAG_MAKE_RO))) {
10789                                 unsigned lvl = flags >> SETFLAG_VARLVL_SHIFT;
10790                                 if (var && var->var_nest_level == lvl) {
10791                                         /* "local x=abc; ...; local x" - ignore second local decl */
10792                                         continue;
10793                                 }
10794                         }
10795 # endif
10796                         /* Exporting non-existing variable.
10797                          * bash does not put it in environment,
10798                          * but remembers that it is exported,
10799                          * and does put it in env when it is set later.
10800                          * We just set it to "" and export.
10801                          */
10802                         /* Or, it's "local NAME" (without =VALUE).
10803                          * bash sets the value to "".
10804                          */
10805                         /* Or, it's "readonly NAME" (without =VALUE).
10806                          * bash remembers NAME and disallows its creation
10807                          * in the future.
10808                          */
10809                         name = xasprintf("%s=", name);
10810                 } else {
10811                         if (*name_end != '=') {
10812                                 bb_error_msg("'%s': bad variable name", name);
10813                                 /* do not parse following argv[]s: */
10814                                 return 1;
10815                         }
10816                         /* (Un)exporting/making local NAME=VALUE */
10817                         name = xstrdup(name);
10818                         /* Testcase: export PS1='\w \$ ' */
10819                         unbackslash(name);
10820                 }
10821                 debug_printf_env("%s: set_local_var('%s')\n", __func__, name);
10822                 if (set_local_var(name, flags))
10823                         return EXIT_FAILURE;
10824         } while (*++argv);
10825         return EXIT_SUCCESS;
10826 }
10827 #endif
10828
10829 #if ENABLE_HUSH_EXPORT
10830 static int FAST_FUNC builtin_export(char **argv)
10831 {
10832         unsigned opt_unexport;
10833
10834 # if ENABLE_HUSH_EXPORT_N
10835         /* "!": do not abort on errors */
10836         opt_unexport = getopt32(argv, "!n");
10837         if (opt_unexport == (uint32_t)-1)
10838                 return EXIT_FAILURE;
10839         argv += optind;
10840 # else
10841         opt_unexport = 0;
10842         argv++;
10843 # endif
10844
10845         if (argv[0] == NULL) {
10846                 char **e = environ;
10847                 if (e) {
10848                         while (*e) {
10849 # if 0
10850                                 puts(*e++);
10851 # else
10852                                 /* ash emits: export VAR='VAL'
10853                                  * bash: declare -x VAR="VAL"
10854                                  * we follow ash example */
10855                                 const char *s = *e++;
10856                                 const char *p = strchr(s, '=');
10857
10858                                 if (!p) /* wtf? take next variable */
10859                                         continue;
10860                                 /* export var= */
10861                                 printf("export %.*s", (int)(p - s) + 1, s);
10862                                 print_escaped(p + 1);
10863                                 putchar('\n');
10864 # endif
10865                         }
10866                         /*fflush_all(); - done after each builtin anyway */
10867                 }
10868                 return EXIT_SUCCESS;
10869         }
10870
10871         return helper_export_local(argv, opt_unexport ? SETFLAG_UNEXPORT : SETFLAG_EXPORT);
10872 }
10873 #endif
10874
10875 #if ENABLE_HUSH_LOCAL
10876 static int FAST_FUNC builtin_local(char **argv)
10877 {
10878         if (G.func_nest_level == 0) {
10879                 bb_error_msg("%s: not in a function", argv[0]);
10880                 return EXIT_FAILURE; /* bash compat */
10881         }
10882         argv++;
10883         /* Since all builtins run in a nested variable level,
10884          * need to use level - 1 here. Or else the variable will be removed at once
10885          * after builtin returns.
10886          */
10887         return helper_export_local(argv, (G.var_nest_level - 1) << SETFLAG_VARLVL_SHIFT);
10888 }
10889 #endif
10890
10891 #if ENABLE_HUSH_READONLY
10892 static int FAST_FUNC builtin_readonly(char **argv)
10893 {
10894         argv++;
10895         if (*argv == NULL) {
10896                 /* bash: readonly [-p]: list all readonly VARs
10897                  * (-p has no effect in bash)
10898                  */
10899                 struct variable *e;
10900                 for (e = G.top_var; e; e = e->next) {
10901                         if (e->flg_read_only) {
10902 //TODO: quote value: readonly VAR='VAL'
10903                                 printf("readonly %s\n", e->varstr);
10904                         }
10905                 }
10906                 return EXIT_SUCCESS;
10907         }
10908         return helper_export_local(argv, SETFLAG_MAKE_RO);
10909 }
10910 #endif
10911
10912 #if ENABLE_HUSH_UNSET
10913 /* http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#unset */
10914 static int FAST_FUNC builtin_unset(char **argv)
10915 {
10916         int ret;
10917         unsigned opts;
10918
10919         /* "!": do not abort on errors */
10920         /* "+": stop at 1st non-option */
10921         opts = getopt32(argv, "!+vf");
10922         if (opts == (unsigned)-1)
10923                 return EXIT_FAILURE;
10924         if (opts == 3) {
10925                 bb_simple_error_msg("unset: -v and -f are exclusive");
10926                 return EXIT_FAILURE;
10927         }
10928         argv += optind;
10929
10930         ret = EXIT_SUCCESS;
10931         while (*argv) {
10932                 if (!(opts & 2)) { /* not -f */
10933                         if (unset_local_var(*argv)) {
10934                                 /* unset <nonexistent_var> doesn't fail.
10935                                  * Error is when one tries to unset RO var.
10936                                  * Message was printed by unset_local_var. */
10937                                 ret = EXIT_FAILURE;
10938                         }
10939                 }
10940 # if ENABLE_HUSH_FUNCTIONS
10941                 else {
10942                         unset_func(*argv);
10943                 }
10944 # endif
10945                 argv++;
10946         }
10947         return ret;
10948 }
10949 #endif
10950
10951 #if ENABLE_HUSH_SET
10952 /* http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#set
10953  * built-in 'set' handler
10954  * SUSv3 says:
10955  * set [-abCefhmnuvx] [-o option] [argument...]
10956  * set [+abCefhmnuvx] [+o option] [argument...]
10957  * set -- [argument...]
10958  * set -o
10959  * set +o
10960  * Implementations shall support the options in both their hyphen and
10961  * plus-sign forms. These options can also be specified as options to sh.
10962  * Examples:
10963  * Write out all variables and their values: set
10964  * Set $1, $2, and $3 and set "$#" to 3: set c a b
10965  * Turn on the -x and -v options: set -xv
10966  * Unset all positional parameters: set --
10967  * Set $1 to the value of x, even if it begins with '-' or '+': set -- "$x"
10968  * Set the positional parameters to the expansion of x, even if x expands
10969  * with a leading '-' or '+': set -- $x
10970  *
10971  * So far, we only support "set -- [argument...]" and some of the short names.
10972  */
10973 static int FAST_FUNC builtin_set(char **argv)
10974 {
10975         int n;
10976         char **pp, **g_argv;
10977         char *arg = *++argv;
10978
10979         if (arg == NULL) {
10980                 struct variable *e;
10981                 for (e = G.top_var; e; e = e->next)
10982                         puts(e->varstr);
10983                 return EXIT_SUCCESS;
10984         }
10985
10986         do {
10987                 if (strcmp(arg, "--") == 0) {
10988                         ++argv;
10989                         goto set_argv;
10990                 }
10991                 if (arg[0] != '+' && arg[0] != '-')
10992                         break;
10993                 for (n = 1; arg[n]; ++n) {
10994                         if (set_mode((arg[0] == '-'), arg[n], argv[1])) {
10995                                 bb_error_msg("%s: %s: invalid option", "set", arg);
10996                                 return EXIT_FAILURE;
10997                         }
10998                         if (arg[n] == 'o' && argv[1])
10999                                 argv++;
11000                 }
11001         } while ((arg = *++argv) != NULL);
11002         /* Now argv[0] is 1st argument */
11003
11004         if (arg == NULL)
11005                 return EXIT_SUCCESS;
11006  set_argv:
11007
11008         /* NB: G.global_argv[0] ($0) is never freed/changed */
11009         g_argv = G.global_argv;
11010         if (G.global_args_malloced) {
11011                 pp = g_argv;
11012                 while (*++pp)
11013                         free(*pp);
11014                 g_argv[1] = NULL;
11015         } else {
11016                 G.global_args_malloced = 1;
11017                 pp = xzalloc(sizeof(pp[0]) * 2);
11018                 pp[0] = g_argv[0]; /* retain $0 */
11019                 g_argv = pp;
11020         }
11021         /* This realloc's G.global_argv */
11022         G.global_argv = pp = add_strings_to_strings(g_argv, argv, /*dup:*/ 1);
11023
11024         G.global_argc = 1 + string_array_len(pp + 1);
11025
11026         return EXIT_SUCCESS;
11027 }
11028 #endif
11029
11030 static int FAST_FUNC builtin_shift(char **argv)
11031 {
11032         int n = 1;
11033         argv = skip_dash_dash(argv);
11034         if (argv[0]) {
11035                 n = bb_strtou(argv[0], NULL, 10);
11036                 if (errno || n < 0) {
11037                         /* shared string with ash.c */
11038                         bb_error_msg("Illegal number: %s", argv[0]);
11039                         /*
11040                          * ash aborts in this case.
11041                          * bash prints error message and set $? to 1.
11042                          * Interestingly, for "shift 99999" bash does not
11043                          * print error message, but does set $? to 1
11044                          * (and does no shifting at all).
11045                          */
11046                 }
11047         }
11048         if (n >= 0 && n < G.global_argc) {
11049                 if (G_global_args_malloced) {
11050                         int m = 1;
11051                         while (m <= n)
11052                                 free(G.global_argv[m++]);
11053                 }
11054                 G.global_argc -= n;
11055                 memmove(&G.global_argv[1], &G.global_argv[n+1],
11056                                 G.global_argc * sizeof(G.global_argv[0]));
11057                 return EXIT_SUCCESS;
11058         }
11059         return EXIT_FAILURE;
11060 }
11061
11062 #if ENABLE_HUSH_GETOPTS
11063 static int FAST_FUNC builtin_getopts(char **argv)
11064 {
11065 /* http://pubs.opengroup.org/onlinepubs/9699919799/utilities/getopts.html
11066
11067 TODO:
11068 If a required argument is not found, and getopts is not silent,
11069 a question mark (?) is placed in VAR, OPTARG is unset, and a
11070 diagnostic message is printed.  If getopts is silent, then a
11071 colon (:) is placed in VAR and OPTARG is set to the option
11072 character found.
11073
11074 Test that VAR is a valid variable name?
11075
11076 "Whenever the shell is invoked, OPTIND shall be initialized to 1"
11077 */
11078         char cbuf[2];
11079         const char *cp, *optstring, *var;
11080         int c, n, exitcode, my_opterr;
11081         unsigned count;
11082
11083         optstring = *++argv;
11084         if (!optstring || !(var = *++argv)) {
11085                 bb_simple_error_msg("usage: getopts OPTSTRING VAR [ARGS]");
11086                 return EXIT_FAILURE;
11087         }
11088
11089         if (argv[1])
11090                 argv[0] = G.global_argv[0]; /* for error messages in getopt() */
11091         else
11092                 argv = G.global_argv;
11093         cbuf[1] = '\0';
11094
11095         my_opterr = 0;
11096         if (optstring[0] != ':') {
11097                 cp = get_local_var_value("OPTERR");
11098                 /* 0 if "OPTERR=0", 1 otherwise */
11099                 my_opterr = (!cp || NOT_LONE_CHAR(cp, '0'));
11100         }
11101
11102         /* getopts stops on first non-option. Add "+" to force that */
11103         /*if (optstring[0] != '+')*/ {
11104                 char *s = alloca(strlen(optstring) + 2);
11105                 sprintf(s, "+%s", optstring);
11106                 optstring = s;
11107         }
11108
11109         /* Naively, now we should just
11110          *      cp = get_local_var_value("OPTIND");
11111          *      optind = cp ? atoi(cp) : 0;
11112          *      optarg = NULL;
11113          *      opterr = my_opterr;
11114          *      c = getopt(string_array_len(argv), argv, optstring);
11115          * and be done? Not so fast...
11116          * Unlike normal getopt() usage in C programs, here
11117          * each successive call will (usually) have the same argv[] CONTENTS,
11118          * but not the ADDRESSES. Worse yet, it's possible that between
11119          * invocations of "getopts", there will be calls to shell builtins
11120          * which use getopt() internally. Example:
11121          *      while getopts "abc" RES -a -bc -abc de; do
11122          *              unset -ff func
11123          *      done
11124          * This would not work correctly: getopt() call inside "unset"
11125          * modifies internal libc state which is tracking position in
11126          * multi-option strings ("-abc"). At best, it can skip options
11127          * or return the same option infinitely. With glibc implementation
11128          * of getopt(), it would use outright invalid pointers and return
11129          * garbage even _without_ "unset" mangling internal state.
11130          *
11131          * We resort to resetting getopt() state and calling it N times,
11132          * until we get Nth result (or failure).
11133          * (N == G.getopt_count is reset to 0 whenever OPTIND is [un]set).
11134          */
11135         GETOPT_RESET();
11136         count = 0;
11137         n = string_array_len(argv);
11138         do {
11139                 optarg = NULL;
11140                 opterr = (count < G.getopt_count) ? 0 : my_opterr;
11141                 c = getopt(n, argv, optstring);
11142                 if (c < 0)
11143                         break;
11144                 count++;
11145         } while (count <= G.getopt_count);
11146
11147         /* Set OPTIND. Prevent resetting of the magic counter! */
11148         set_local_var_from_halves("OPTIND", utoa(optind));
11149         G.getopt_count = count; /* "next time, give me N+1'th result" */
11150         GETOPT_RESET(); /* just in case */
11151
11152         /* Set OPTARG */
11153         /* Always set or unset, never left as-is, even on exit/error:
11154          * "If no option was found, or if the option that was found
11155          * does not have an option-argument, OPTARG shall be unset."
11156          */
11157         cp = optarg;
11158         if (c == '?') {
11159                 /* If ":optstring" and unknown option is seen,
11160                  * it is stored to OPTARG.
11161                  */
11162                 if (optstring[1] == ':') {
11163                         cbuf[0] = optopt;
11164                         cp = cbuf;
11165                 }
11166         }
11167         if (cp)
11168                 set_local_var_from_halves("OPTARG", cp);
11169         else
11170                 unset_local_var("OPTARG");
11171
11172         /* Convert -1 to "?" */
11173         exitcode = EXIT_SUCCESS;
11174         if (c < 0) { /* -1: end of options */
11175                 exitcode = EXIT_FAILURE;
11176                 c = '?';
11177         }
11178
11179         /* Set VAR */
11180         cbuf[0] = c;
11181         set_local_var_from_halves(var, cbuf);
11182
11183         return exitcode;
11184 }
11185 #endif
11186
11187 static int FAST_FUNC builtin_source(char **argv)
11188 {
11189         char *arg_path, *filename;
11190         HFILE *input;
11191         save_arg_t sv;
11192         char *args_need_save;
11193 #if ENABLE_HUSH_FUNCTIONS
11194         smallint sv_flg;
11195 #endif
11196
11197         argv = skip_dash_dash(argv);
11198         filename = argv[0];
11199         if (!filename) {
11200                 /* bash says: "bash: .: filename argument required" */
11201                 return 2; /* bash compat */
11202         }
11203         arg_path = NULL;
11204         if (!strchr(filename, '/')) {
11205                 arg_path = find_in_path(filename);
11206                 if (arg_path)
11207                         filename = arg_path;
11208                 else if (!ENABLE_HUSH_BASH_SOURCE_CURDIR) {
11209                         errno = ENOENT;
11210                         bb_simple_perror_msg(filename);
11211                         return EXIT_FAILURE;
11212                 }
11213         }
11214         input = hfopen(filename);
11215         free(arg_path);
11216         if (!input) {
11217                 bb_perror_msg("%s", filename);
11218                 /* POSIX: non-interactive shell should abort here,
11219                  * not merely fail. So far no one complained :)
11220                  */
11221                 return EXIT_FAILURE;
11222         }
11223
11224 #if ENABLE_HUSH_FUNCTIONS
11225         sv_flg = G_flag_return_in_progress;
11226         /* "we are inside sourced file, ok to use return" */
11227         G_flag_return_in_progress = -1;
11228 #endif
11229         args_need_save = argv[1]; /* used as a boolean variable */
11230         if (args_need_save)
11231                 save_and_replace_G_args(&sv, argv);
11232
11233         /* "false; . ./empty_line; echo Zero:$?" should print 0 */
11234         G.last_exitcode = 0;
11235         parse_and_run_file(input);
11236         hfclose(input);
11237
11238         if (args_need_save) /* can't use argv[1] instead: "shift" can mangle it */
11239                 restore_G_args(&sv, argv);
11240 #if ENABLE_HUSH_FUNCTIONS
11241         G_flag_return_in_progress = sv_flg;
11242 #endif
11243
11244         return G.last_exitcode;
11245 }
11246
11247 #if ENABLE_HUSH_TRAP
11248 static int FAST_FUNC builtin_trap(char **argv)
11249 {
11250         int sig;
11251         char *new_cmd;
11252
11253         if (!G_traps)
11254                 G_traps = xzalloc(sizeof(G_traps[0]) * NSIG);
11255
11256         argv++;
11257         if (!*argv) {
11258                 int i;
11259                 /* No args: print all trapped */
11260                 for (i = 0; i < NSIG; ++i) {
11261                         if (G_traps[i]) {
11262                                 printf("trap -- ");
11263                                 print_escaped(G_traps[i]);
11264                                 /* note: bash adds "SIG", but only if invoked
11265                                  * as "bash". If called as "sh", or if set -o posix,
11266                                  * then it prints short signal names.
11267                                  * We are printing short names: */
11268                                 printf(" %s\n", get_signame(i));
11269                         }
11270                 }
11271                 /*fflush_all(); - done after each builtin anyway */
11272                 return EXIT_SUCCESS;
11273         }
11274
11275         new_cmd = NULL;
11276         /* If first arg is a number: reset all specified signals */
11277         sig = bb_strtou(*argv, NULL, 10);
11278         if (errno == 0) {
11279                 int ret;
11280  process_sig_list:
11281                 ret = EXIT_SUCCESS;
11282                 while (*argv) {
11283                         sighandler_t handler;
11284
11285                         sig = get_signum(*argv++);
11286                         if (sig < 0) {
11287                                 ret = EXIT_FAILURE;
11288                                 /* Mimic bash message exactly */
11289                                 bb_error_msg("trap: %s: invalid signal specification", argv[-1]);
11290                                 continue;
11291                         }
11292
11293                         free(G_traps[sig]);
11294                         G_traps[sig] = xstrdup(new_cmd);
11295
11296                         debug_printf("trap: setting SIG%s (%i) to '%s'\n",
11297                                 get_signame(sig), sig, G_traps[sig]);
11298
11299                         /* There is no signal for 0 (EXIT) */
11300                         if (sig == 0)
11301                                 continue;
11302
11303                         if (new_cmd)
11304                                 handler = (new_cmd[0] ? record_pending_signo : SIG_IGN);
11305                         else
11306                                 /* We are removing trap handler */
11307                                 handler = pick_sighandler(sig);
11308                         install_sighandler(sig, handler);
11309                 }
11310                 return ret;
11311         }
11312
11313         if (!argv[1]) { /* no second arg */
11314                 bb_simple_error_msg("trap: invalid arguments");
11315                 return EXIT_FAILURE;
11316         }
11317
11318         /* First arg is "-": reset all specified to default */
11319         /* First arg is "--": skip it, the rest is "handler SIGs..." */
11320         /* Everything else: set arg as signal handler
11321          * (includes "" case, which ignores signal) */
11322         if (argv[0][0] == '-') {
11323                 if (argv[0][1] == '\0') { /* "-" */
11324                         /* new_cmd remains NULL: "reset these sigs" */
11325                         goto reset_traps;
11326                 }
11327                 if (argv[0][1] == '-' && argv[0][2] == '\0') { /* "--" */
11328                         argv++;
11329                 }
11330                 /* else: "-something", no special meaning */
11331         }
11332         new_cmd = *argv;
11333  reset_traps:
11334         argv++;
11335         goto process_sig_list;
11336 }
11337 #endif
11338
11339 #if ENABLE_HUSH_JOB
11340 static struct pipe *parse_jobspec(const char *str)
11341 {
11342         struct pipe *pi;
11343         unsigned jobnum;
11344
11345         if (sscanf(str, "%%%u", &jobnum) != 1) {
11346                 if (str[0] != '%'
11347                  || (str[1] != '%' && str[1] != '+' && str[1] != '\0')
11348                 ) {
11349                         bb_error_msg("bad argument '%s'", str);
11350                         return NULL;
11351                 }
11352                 /* It is "%%", "%+" or "%" - current job */
11353                 jobnum = G.last_jobid;
11354                 if (jobnum == 0) {
11355                         bb_simple_error_msg("no current job");
11356                         return NULL;
11357                 }
11358         }
11359         for (pi = G.job_list; pi; pi = pi->next) {
11360                 if (pi->jobid == jobnum) {
11361                         return pi;
11362                 }
11363         }
11364         bb_error_msg("%u: no such job", jobnum);
11365         return NULL;
11366 }
11367
11368 static int FAST_FUNC builtin_jobs(char **argv UNUSED_PARAM)
11369 {
11370         struct pipe *job;
11371         const char *status_string;
11372
11373         checkjobs(NULL, 0 /*(no pid to wait for)*/);
11374         for (job = G.job_list; job; job = job->next) {
11375                 if (job->alive_cmds == job->stopped_cmds)
11376                         status_string = "Stopped";
11377                 else
11378                         status_string = "Running";
11379
11380                 printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->cmdtext);
11381         }
11382
11383         clean_up_last_dead_job();
11384
11385         return EXIT_SUCCESS;
11386 }
11387
11388 /* built-in 'fg' and 'bg' handler */
11389 static int FAST_FUNC builtin_fg_bg(char **argv)
11390 {
11391         int i;
11392         struct pipe *pi;
11393
11394         if (!G_interactive_fd)
11395                 return EXIT_FAILURE;
11396
11397         /* If they gave us no args, assume they want the last backgrounded task */
11398         if (!argv[1]) {
11399                 for (pi = G.job_list; pi; pi = pi->next) {
11400                         if (pi->jobid == G.last_jobid) {
11401                                 goto found;
11402                         }
11403                 }
11404                 bb_error_msg("%s: no current job", argv[0]);
11405                 return EXIT_FAILURE;
11406         }
11407
11408         pi = parse_jobspec(argv[1]);
11409         if (!pi)
11410                 return EXIT_FAILURE;
11411  found:
11412         /* TODO: bash prints a string representation
11413          * of job being foregrounded (like "sleep 1 | cat") */
11414         if (argv[0][0] == 'f' && G_saved_tty_pgrp) {
11415                 /* Put the job into the foreground.  */
11416                 tcsetpgrp(G_interactive_fd, pi->pgrp);
11417         }
11418
11419         /* Restart the processes in the job */
11420         debug_printf_jobs("reviving %d procs, pgrp %d\n", pi->num_cmds, pi->pgrp);
11421         for (i = 0; i < pi->num_cmds; i++) {
11422                 debug_printf_jobs("reviving pid %d\n", pi->cmds[i].pid);
11423         }
11424         pi->stopped_cmds = 0;
11425
11426         i = kill(- pi->pgrp, SIGCONT);
11427         if (i < 0) {
11428                 if (errno == ESRCH) {
11429                         delete_finished_job(pi);
11430                         return EXIT_SUCCESS;
11431                 }
11432                 bb_simple_perror_msg("kill (SIGCONT)");
11433         }
11434
11435         if (argv[0][0] == 'f') {
11436                 remove_job_from_table(pi); /* FG job shouldn't be in job table */
11437                 return checkjobs_and_fg_shell(pi);
11438         }
11439         return EXIT_SUCCESS;
11440 }
11441 #endif
11442
11443 #if ENABLE_HUSH_KILL
11444 static int FAST_FUNC builtin_kill(char **argv)
11445 {
11446         int ret = 0;
11447
11448 # if ENABLE_HUSH_JOB
11449         if (argv[1] && strcmp(argv[1], "-l") != 0) {
11450                 int i = 1;
11451
11452                 do {
11453                         struct pipe *pi;
11454                         char *dst;
11455                         int j, n;
11456
11457                         if (argv[i][0] != '%')
11458                                 continue;
11459                         /*
11460                          * "kill %N" - job kill
11461                          * Converting to pgrp / pid kill
11462                          */
11463                         pi = parse_jobspec(argv[i]);
11464                         if (!pi) {
11465                                 /* Eat bad jobspec */
11466                                 j = i;
11467                                 do {
11468                                         j++;
11469                                         argv[j - 1] = argv[j];
11470                                 } while (argv[j]);
11471                                 ret = 1;
11472                                 i--;
11473                                 continue;
11474                         }
11475                         /*
11476                          * In jobs started under job control, we signal
11477                          * entire process group by kill -PGRP_ID.
11478                          * This happens, f.e., in interactive shell.
11479                          *
11480                          * Otherwise, we signal each child via
11481                          * kill PID1 PID2 PID3.
11482                          * Testcases:
11483                          * sh -c 'sleep 1|sleep 1 & kill %1'
11484                          * sh -c 'true|sleep 2 & sleep 1; kill %1'
11485                          * sh -c 'true|sleep 1 & sleep 2; kill %1'
11486                          */
11487                         n = G_interactive_fd ? 1 : pi->num_cmds;
11488                         dst = alloca(n * sizeof(int)*4);
11489                         argv[i] = dst;
11490                         if (G_interactive_fd)
11491                                 dst += sprintf(dst, " -%u", (int)pi->pgrp);
11492                         else for (j = 0; j < n; j++) {
11493                                 struct command *cmd = &pi->cmds[j];
11494                                 /* Skip exited members of the job */
11495                                 if (cmd->pid == 0)
11496                                         continue;
11497                                 /*
11498                                  * kill_main has matching code to expect
11499                                  * leading space. Needed to not confuse
11500                                  * negative pids with "kill -SIGNAL_NO" syntax
11501                                  */
11502                                 dst += sprintf(dst, " %u", (int)cmd->pid);
11503                         }
11504                         *dst = '\0';
11505                 } while (argv[++i]);
11506         }
11507 # endif
11508
11509         if (argv[1] || ret == 0) {
11510                 ret = run_applet_main(argv, kill_main);
11511         }
11512         /* else: ret = 1, "kill %bad_jobspec" case */
11513         return ret;
11514 }
11515 #endif
11516
11517 #if ENABLE_HUSH_WAIT
11518 /* http://www.opengroup.org/onlinepubs/9699919799/utilities/wait.html */
11519 # if !ENABLE_HUSH_JOB
11520 #  define wait_for_child_or_signal(pipe,pid) wait_for_child_or_signal(pid)
11521 # endif
11522 static int wait_for_child_or_signal(struct pipe *waitfor_pipe, pid_t waitfor_pid)
11523 {
11524         int ret = 0;
11525         for (;;) {
11526                 int sig;
11527                 sigset_t oldset;
11528
11529                 if (!sigisemptyset(&G.pending_set))
11530                         goto check_sig;
11531
11532                 /* waitpid is not interruptible by SA_RESTARTed
11533                  * signals which we use. Thus, this ugly dance:
11534                  */
11535
11536                 /* Make sure possible SIGCHLD is stored in kernel's
11537                  * pending signal mask before we call waitpid.
11538                  * Or else we may race with SIGCHLD, lose it,
11539                  * and get stuck in sigsuspend...
11540                  */
11541                 sigfillset(&oldset); /* block all signals, remember old set */
11542                 sigprocmask2(SIG_SETMASK, &oldset);
11543
11544                 if (!sigisemptyset(&G.pending_set)) {
11545                         /* Crap! we raced with some signal! */
11546                         goto restore;
11547                 }
11548
11549                 /*errno = 0; - checkjobs does this */
11550 /* Can't pass waitfor_pipe into checkjobs(): it won't be interruptible */
11551                 ret = checkjobs(NULL, waitfor_pid); /* waitpid(WNOHANG) inside */
11552                 debug_printf_exec("checkjobs:%d\n", ret);
11553 # if ENABLE_HUSH_JOB
11554                 if (waitfor_pipe) {
11555                         int rcode = job_exited_or_stopped(waitfor_pipe);
11556                         debug_printf_exec("job_exited_or_stopped:%d\n", rcode);
11557                         if (rcode >= 0) {
11558                                 ret = rcode;
11559                                 sigprocmask(SIG_SETMASK, &oldset, NULL);
11560                                 break;
11561                         }
11562                 }
11563 # endif
11564                 /* if ECHILD, there are no children (ret is -1 or 0) */
11565                 /* if ret == 0, no children changed state */
11566                 /* if ret != 0, it's exitcode+1 of exited waitfor_pid child */
11567                 if (errno == ECHILD || ret) {
11568                         ret--;
11569                         if (ret < 0) /* if ECHILD, may need to fix "ret" */
11570                                 ret = 0;
11571 # if ENABLE_HUSH_BASH_COMPAT
11572                         if (waitfor_pid == -1 && errno == ECHILD) {
11573                                 /* exitcode of "wait -n" with no children is 127, not 0 */
11574                                 ret = 127;
11575                         }
11576 # endif
11577                         sigprocmask(SIG_SETMASK, &oldset, NULL);
11578                         break;
11579                 }
11580                 /* Wait for SIGCHLD or any other signal */
11581                 /* It is vitally important for sigsuspend that SIGCHLD has non-DFL handler! */
11582                 /* Note: sigsuspend invokes signal handler */
11583                 sigsuspend(&oldset);
11584                 /* ^^^ add "sigdelset(&oldset, SIGCHLD)" before sigsuspend
11585                  * to make sure SIGCHLD is not masked off?
11586                  * It was reported that this:
11587                  *      fn() { : | return; }
11588                  *      shopt -s lastpipe
11589                  *      fn
11590                  *      exec hush SCRIPT
11591                  * under bash 4.4.23 runs SCRIPT with SIGCHLD masked,
11592                  * making "wait" commands in SCRIPT block forever.
11593                  */
11594  restore:
11595                 sigprocmask(SIG_SETMASK, &oldset, NULL);
11596  check_sig:
11597                 /* So, did we get a signal? */
11598                 sig = check_and_run_traps();
11599                 if (sig /*&& sig != SIGCHLD - always true */) {
11600                         /* Do this for any (non-ignored) signal, not only for ^C */
11601                         ret = 128 + sig;
11602                         break;
11603                 }
11604                 /* SIGCHLD, or no signal, or ignored one, such as SIGQUIT. Repeat */
11605         }
11606         return ret;
11607 }
11608
11609 static int FAST_FUNC builtin_wait(char **argv)
11610 {
11611         int ret;
11612         int status;
11613
11614         argv = skip_dash_dash(argv);
11615 # if ENABLE_HUSH_BASH_COMPAT
11616         if (argv[0] && strcmp(argv[0], "-n") == 0) {
11617                 /* wait -n */
11618                 /* (bash accepts "wait -n PID" too and ignores PID) */
11619                 G.dead_job_exitcode = -1;
11620                 return wait_for_child_or_signal(NULL, -1 /*no job, wait for one job*/);
11621         }
11622 # endif
11623         if (argv[0] == NULL) {
11624                 /* Don't care about wait results */
11625                 /* Note 1: must wait until there are no more children */
11626                 /* Note 2: must be interruptible */
11627                 /* Examples:
11628                  * $ sleep 3 & sleep 6 & wait
11629                  * [1] 30934 sleep 3
11630                  * [2] 30935 sleep 6
11631                  * [1] Done                   sleep 3
11632                  * [2] Done                   sleep 6
11633                  * $ sleep 3 & sleep 6 & wait
11634                  * [1] 30936 sleep 3
11635                  * [2] 30937 sleep 6
11636                  * [1] Done                   sleep 3
11637                  * ^C <-- after ~4 sec from keyboard
11638                  * $
11639                  */
11640                 return wait_for_child_or_signal(NULL, 0 /*no job and no pid to wait for*/);
11641         }
11642
11643         do {
11644                 pid_t pid = bb_strtou(*argv, NULL, 10);
11645                 if (errno || pid <= 0) {
11646 # if ENABLE_HUSH_JOB
11647                         if (argv[0][0] == '%') {
11648                                 struct pipe *wait_pipe;
11649                                 ret = 127; /* bash compat for bad jobspecs */
11650                                 wait_pipe = parse_jobspec(*argv);
11651                                 if (wait_pipe) {
11652                                         ret = job_exited_or_stopped(wait_pipe);
11653                                         if (ret < 0) {
11654                                                 ret = wait_for_child_or_signal(wait_pipe, 0);
11655                                         } else {
11656                                                 /* waiting on "last dead job" removes it */
11657                                                 clean_up_last_dead_job();
11658                                         }
11659                                 }
11660                                 /* else: parse_jobspec() already emitted error msg */
11661                                 continue;
11662                         }
11663 # endif
11664                         /* mimic bash message */
11665                         bb_error_msg("wait: '%s': not a pid or valid job spec", *argv);
11666                         ret = EXIT_FAILURE;
11667                         continue; /* bash checks all argv[] */
11668                 }
11669
11670                 /* Do we have such child? */
11671                 ret = waitpid(pid, &status, WNOHANG);
11672                 if (ret < 0) {
11673                         /* No */
11674                         ret = 127;
11675                         if (errno == ECHILD) {
11676                                 if (pid == G.last_bg_pid) {
11677                                         /* "wait $!" but last bg task has already exited. Try:
11678                                          * (sleep 1; exit 3) & sleep 2; echo $?; wait $!; echo $?
11679                                          * In bash it prints exitcode 0, then 3.
11680                                          * In dash, it is 127.
11681                                          */
11682                                         ret = G.last_bg_pid_exitcode;
11683                                 } else {
11684                                         /* Example: "wait 1". mimic bash message */
11685                                         bb_error_msg("wait: pid %u is not a child of this shell", (unsigned)pid);
11686                                 }
11687                         } else {
11688                                 /* ??? */
11689                                 bb_perror_msg("wait %s", *argv);
11690                         }
11691                         continue; /* bash checks all argv[] */
11692                 }
11693                 if (ret == 0) {
11694                         /* Yes, and it still runs */
11695                         ret = wait_for_child_or_signal(NULL, pid);
11696                 } else {
11697                         /* Yes, and it just exited */
11698                         process_wait_result(NULL, pid, status);
11699                         ret = WEXITSTATUS(status);
11700                         if (WIFSIGNALED(status))
11701                                 ret = 128 + WTERMSIG(status);
11702                 }
11703         } while (*++argv);
11704
11705         return ret;
11706 }
11707 #endif
11708
11709 #if ENABLE_HUSH_LOOPS || ENABLE_HUSH_FUNCTIONS
11710 static unsigned parse_numeric_argv1(char **argv, unsigned def, unsigned def_min)
11711 {
11712         if (argv[1]) {
11713                 def = bb_strtou(argv[1], NULL, 10);
11714                 if (errno || def < def_min || argv[2]) {
11715                         bb_error_msg("%s: bad arguments", argv[0]);
11716                         def = UINT_MAX;
11717                 }
11718         }
11719         return def;
11720 }
11721 #endif
11722
11723 #if ENABLE_HUSH_LOOPS
11724 static int FAST_FUNC builtin_break(char **argv)
11725 {
11726         unsigned depth;
11727         if (G.depth_of_loop == 0) {
11728                 bb_error_msg("%s: only meaningful in a loop", argv[0]);
11729                 /* if we came from builtin_continue(), need to undo "= 1" */
11730                 G.flag_break_continue = 0;
11731                 return EXIT_SUCCESS; /* bash compat */
11732         }
11733         G.flag_break_continue++; /* BC_BREAK = 1, or BC_CONTINUE = 2 */
11734
11735         G.depth_break_continue = depth = parse_numeric_argv1(argv, 1, 1);
11736         if (depth == UINT_MAX)
11737                 G.flag_break_continue = BC_BREAK;
11738         if (G.depth_of_loop < depth)
11739                 G.depth_break_continue = G.depth_of_loop;
11740
11741         return EXIT_SUCCESS;
11742 }
11743
11744 static int FAST_FUNC builtin_continue(char **argv)
11745 {
11746         G.flag_break_continue = 1; /* BC_CONTINUE = 2 = 1+1 */
11747         return builtin_break(argv);
11748 }
11749 #endif
11750
11751 #if ENABLE_HUSH_FUNCTIONS
11752 static int FAST_FUNC builtin_return(char **argv)
11753 {
11754         int rc;
11755
11756         if (G_flag_return_in_progress != -1) {
11757                 bb_error_msg("%s: not in a function or sourced script", argv[0]);
11758                 return EXIT_FAILURE; /* bash compat */
11759         }
11760
11761         G_flag_return_in_progress = 1;
11762
11763         /* bash:
11764          * out of range: wraps around at 256, does not error out
11765          * non-numeric param:
11766          * f() { false; return qwe; }; f; echo $?
11767          * bash: return: qwe: numeric argument required  <== we do this
11768          * 255  <== we also do this
11769          */
11770         rc = parse_numeric_argv1(argv, G.last_exitcode, 0);
11771 # if ENABLE_HUSH_TRAP
11772         if (argv[1]) { /* "return ARG" inside a running trap sets $? */
11773                 debug_printf_exec("G.return_exitcode=%d\n", rc);
11774                 G.return_exitcode = rc;
11775         }
11776 # endif
11777         return rc;
11778 }
11779 #endif
11780
11781 #if ENABLE_HUSH_TIMES
11782 static int FAST_FUNC builtin_times(char **argv UNUSED_PARAM)
11783 {
11784         static const uint8_t times_tbl[] ALIGN1 = {
11785                 ' ',  offsetof(struct tms, tms_utime),
11786                 '\n', offsetof(struct tms, tms_stime),
11787                 ' ',  offsetof(struct tms, tms_cutime),
11788                 '\n', offsetof(struct tms, tms_cstime),
11789                 0
11790         };
11791         const uint8_t *p;
11792         unsigned clk_tck;
11793         struct tms buf;
11794
11795         clk_tck = bb_clk_tck();
11796
11797         times(&buf);
11798         p = times_tbl;
11799         do {
11800                 unsigned sec, frac;
11801                 unsigned long t;
11802                 t = *(clock_t *)(((char *) &buf) + p[1]);
11803                 sec = t / clk_tck;
11804                 frac = t % clk_tck;
11805                 printf("%um%u.%03us%c",
11806                         sec / 60, sec % 60,
11807                         (frac * 1000) / clk_tck,
11808                         p[0]);
11809                 p += 2;
11810         } while (*p);
11811
11812         return EXIT_SUCCESS;
11813 }
11814 #endif
11815
11816 #if ENABLE_HUSH_MEMLEAK
11817 static int FAST_FUNC builtin_memleak(char **argv UNUSED_PARAM)
11818 {
11819         void *p;
11820         unsigned long l;
11821
11822 # ifdef M_TRIM_THRESHOLD
11823         /* Optional. Reduces probability of false positives */
11824         malloc_trim(0);
11825 # endif
11826         /* Crude attempt to find where "free memory" starts,
11827          * sans fragmentation. */
11828         p = malloc(240);
11829         l = (unsigned long)p;
11830         free(p);
11831         p = malloc(3400);
11832         if (l < (unsigned long)p) l = (unsigned long)p;
11833         free(p);
11834
11835
11836 # if 0  /* debug */
11837         {
11838                 struct mallinfo mi = mallinfo();
11839                 printf("top alloc:0x%lx malloced:%d+%d=%d\n", l,
11840                         mi.arena, mi.hblkhd, mi.arena + mi.hblkhd);
11841         }
11842 # endif
11843
11844         if (!G.memleak_value)
11845                 G.memleak_value = l;
11846
11847         l -= G.memleak_value;
11848         if ((long)l < 0)
11849                 l = 0;
11850         l /= 1024;
11851         if (l > 127)
11852                 l = 127;
11853
11854         /* Exitcode is "how many kilobytes we leaked since 1st call" */
11855         return l;
11856 }
11857 #endif