2e4a4bcc684d328cbed5d2ee4fc1e760a252b296
[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 (64 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 #ifndef PIPE_BUF
367 # define PIPE_BUF 4096  /* amount of buffering in a pipe */
368 #endif
369
370 #if ENABLE_FEATURE_SH_EMBEDDED_SCRIPTS && !(ENABLE_ASH || ENABLE_SH_IS_ASH || ENABLE_BASH_IS_ASH)
371 # include "embedded_scripts.h"
372 #else
373 # define NUM_SCRIPTS 0
374 #endif
375
376 /* So far, all bash compat is controlled by one config option */
377 /* Separate defines document which part of code implements what */
378 #define BASH_PATTERN_SUBST ENABLE_HUSH_BASH_COMPAT
379 #define BASH_SUBSTR        ENABLE_HUSH_BASH_COMPAT
380 #define BASH_SOURCE        ENABLE_HUSH_BASH_COMPAT
381 #define BASH_HOSTNAME_VAR  ENABLE_HUSH_BASH_COMPAT
382 #define BASH_TEST2         (ENABLE_HUSH_BASH_COMPAT && ENABLE_HUSH_TEST)
383 #define BASH_READ_D        ENABLE_HUSH_BASH_COMPAT
384
385
386 /* Build knobs */
387 #define LEAK_HUNTING 0
388 #define BUILD_AS_NOMMU 0
389 /* Enable/disable sanity checks. Ok to enable in production,
390  * only adds a bit of bloat. Set to >1 to get non-production level verbosity.
391  * Keeping 1 for now even in released versions.
392  */
393 #define HUSH_DEBUG 1
394 /* Slightly bigger (+200 bytes), but faster hush.
395  * So far it only enables a trick with counting SIGCHLDs and forks,
396  * which allows us to do fewer waitpid's.
397  * (we can detect a case where neither forks were done nor SIGCHLDs happened
398  * and therefore waitpid will return the same result as last time)
399  */
400 #define ENABLE_HUSH_FAST 0
401 /* TODO: implement simplified code for users which do not need ${var%...} ops
402  * So far ${var%...} ops are always enabled:
403  */
404 #define ENABLE_HUSH_DOLLAR_OPS 1
405
406
407 #if BUILD_AS_NOMMU
408 # undef BB_MMU
409 # undef USE_FOR_NOMMU
410 # undef USE_FOR_MMU
411 # define BB_MMU 0
412 # define USE_FOR_NOMMU(...) __VA_ARGS__
413 # define USE_FOR_MMU(...)
414 #endif
415
416 #include "NUM_APPLETS.h"
417 #if NUM_APPLETS == 1
418 /* STANDALONE does not make sense, and won't compile */
419 # undef CONFIG_FEATURE_SH_STANDALONE
420 # undef ENABLE_FEATURE_SH_STANDALONE
421 # undef IF_FEATURE_SH_STANDALONE
422 # undef IF_NOT_FEATURE_SH_STANDALONE
423 # define ENABLE_FEATURE_SH_STANDALONE 0
424 # define IF_FEATURE_SH_STANDALONE(...)
425 # define IF_NOT_FEATURE_SH_STANDALONE(...) __VA_ARGS__
426 #endif
427
428 #if !ENABLE_HUSH_INTERACTIVE
429 # undef ENABLE_FEATURE_EDITING
430 # define ENABLE_FEATURE_EDITING 0
431 # undef ENABLE_FEATURE_EDITING_FANCY_PROMPT
432 # define ENABLE_FEATURE_EDITING_FANCY_PROMPT 0
433 # undef ENABLE_FEATURE_EDITING_SAVE_ON_EXIT
434 # define ENABLE_FEATURE_EDITING_SAVE_ON_EXIT 0
435 #endif
436
437 /* Do we support ANY keywords? */
438 #if ENABLE_HUSH_IF || ENABLE_HUSH_LOOPS || ENABLE_HUSH_CASE
439 # define HAS_KEYWORDS 1
440 # define IF_HAS_KEYWORDS(...) __VA_ARGS__
441 # define IF_HAS_NO_KEYWORDS(...)
442 #else
443 # define HAS_KEYWORDS 0
444 # define IF_HAS_KEYWORDS(...)
445 # define IF_HAS_NO_KEYWORDS(...) __VA_ARGS__
446 #endif
447
448 /* If you comment out one of these below, it will be #defined later
449  * to perform debug printfs to stderr: */
450 #define debug_printf(...)         do {} while (0)
451 /* Finer-grained debug switches */
452 #define debug_printf_parse(...)   do {} while (0)
453 #define debug_printf_heredoc(...) do {} while (0)
454 #define debug_print_tree(a, b)    do {} while (0)
455 #define debug_printf_exec(...)    do {} while (0)
456 #define debug_printf_env(...)     do {} while (0)
457 #define debug_printf_jobs(...)    do {} while (0)
458 #define debug_printf_expand(...)  do {} while (0)
459 #define debug_printf_varexp(...)  do {} while (0)
460 #define debug_printf_glob(...)    do {} while (0)
461 #define debug_printf_redir(...)   do {} while (0)
462 #define debug_printf_list(...)    do {} while (0)
463 #define debug_printf_subst(...)   do {} while (0)
464 #define debug_printf_prompt(...)  do {} while (0)
465 #define debug_printf_clean(...)   do {} while (0)
466
467 #define ERR_PTR ((void*)(long)1)
468
469 #define JOB_STATUS_FORMAT    "[%u] %-22s %.40s\n"
470
471 #define _SPECIAL_VARS_STR     "_*@$!?#"
472 #define SPECIAL_VARS_STR     ("_*@$!?#" + 1)
473 #define NUMERIC_SPECVARS_STR ("_*@$!?#" + 3)
474 #if BASH_PATTERN_SUBST
475 /* Support / and // replace ops */
476 /* Note that // is stored as \ in "encoded" string representation */
477 # define VAR_ENCODED_SUBST_OPS      "\\/%#:-=+?"
478 # define VAR_SUBST_OPS             ("\\/%#:-=+?" + 1)
479 # define MINUS_PLUS_EQUAL_QUESTION ("\\/%#:-=+?" + 5)
480 #else
481 # define VAR_ENCODED_SUBST_OPS      "%#:-=+?"
482 # define VAR_SUBST_OPS              "%#:-=+?"
483 # define MINUS_PLUS_EQUAL_QUESTION ("%#:-=+?" + 3)
484 #endif
485
486 #define SPECIAL_VAR_SYMBOL_STR "\3"
487 #define SPECIAL_VAR_SYMBOL       3
488 /* The "variable" with name "\1" emits string "\3". Testcase: "echo ^C" */
489 #define SPECIAL_VAR_QUOTED_SVS   1
490
491 struct variable;
492
493 static const char hush_version_str[] ALIGN1 = "HUSH_VERSION="BB_VER;
494
495 /* This supports saving pointers malloced in vfork child,
496  * to be freed in the parent.
497  */
498 #if !BB_MMU
499 typedef struct nommu_save_t {
500         struct variable *old_vars;
501         char **argv;
502         char **argv_from_re_execing;
503 } nommu_save_t;
504 #endif
505
506 enum {
507         RES_NONE  = 0,
508 #if ENABLE_HUSH_IF
509         RES_IF    ,
510         RES_THEN  ,
511         RES_ELIF  ,
512         RES_ELSE  ,
513         RES_FI    ,
514 #endif
515 #if ENABLE_HUSH_LOOPS
516         RES_FOR   ,
517         RES_WHILE ,
518         RES_UNTIL ,
519         RES_DO    ,
520         RES_DONE  ,
521 #endif
522 #if ENABLE_HUSH_LOOPS || ENABLE_HUSH_CASE
523         RES_IN    ,
524 #endif
525 #if ENABLE_HUSH_CASE
526         RES_CASE  ,
527         /* three pseudo-keywords support contrived "case" syntax: */
528         RES_CASE_IN,   /* "case ... IN", turns into RES_MATCH when IN is observed */
529         RES_MATCH ,    /* "word)" */
530         RES_CASE_BODY, /* "this command is inside CASE" */
531         RES_ESAC  ,
532 #endif
533         RES_XXXX  ,
534         RES_SNTX
535 };
536
537 typedef struct o_string {
538         char *data;
539         int length; /* position where data is appended */
540         int maxlen;
541         int o_expflags;
542         /* At least some part of the string was inside '' or "",
543          * possibly empty one: word"", wo''rd etc. */
544         smallint has_quoted_part;
545         smallint has_empty_slot;
546         smallint ended_in_ifs;
547 } o_string;
548 enum {
549         EXP_FLAG_SINGLEWORD     = 0x80, /* must be 0x80 */
550         EXP_FLAG_GLOB           = 0x2,
551         /* Protect newly added chars against globbing
552          * by prepending \ to *, ?, [, \ */
553         EXP_FLAG_ESC_GLOB_CHARS = 0x1,
554 };
555 /* Used for initialization: o_string foo = NULL_O_STRING; */
556 #define NULL_O_STRING { NULL }
557
558 #ifndef debug_printf_parse
559 static const char *const assignment_flag[] = {
560         "MAYBE_ASSIGNMENT",
561         "DEFINITELY_ASSIGNMENT",
562         "NOT_ASSIGNMENT",
563         "WORD_IS_KEYWORD",
564 };
565 #endif
566
567 /* We almost can use standard FILE api, but we need an ability to move
568  * its fd when redirects coincide with it. No api exists for that
569  * (RFE for it at https://sourceware.org/bugzilla/show_bug.cgi?id=21902).
570  * HFILE is our internal alternative. Only supports reading.
571  * Since we now can, we incorporate linked list of all opened HFILEs
572  * into the struct (used to be a separate mini-list).
573  */
574 typedef struct HFILE {
575         char *cur;
576         char *end;
577         struct HFILE *next_hfile;
578         int is_stdin;
579         int fd;
580         char buf[1024];
581 } HFILE;
582
583 typedef struct in_str {
584         const char *p;
585         int peek_buf[2];
586         int last_char;
587         HFILE *file;
588 } in_str;
589
590 /* The descrip member of this structure is only used to make
591  * debugging output pretty */
592 static const struct {
593         int mode;
594         signed char default_fd;
595         char descrip[3];
596 } redir_table[] = {
597         { O_RDONLY,                  0, "<"  },
598         { O_CREAT|O_TRUNC|O_WRONLY,  1, ">"  },
599         { O_CREAT|O_APPEND|O_WRONLY, 1, ">>" },
600         { O_CREAT|O_RDWR,            1, "<>" },
601         { O_RDONLY,                  0, "<<" },
602 /* Should not be needed. Bogus default_fd helps in debugging */
603 /*      { O_RDONLY,                 77, "<<" }, */
604 };
605
606 struct redir_struct {
607         struct redir_struct *next;
608         char *rd_filename;          /* filename */
609         int rd_fd;                  /* fd to redirect */
610         /* fd to redirect to, or -3 if rd_fd is to be closed (n>&-) */
611         int rd_dup;
612         smallint rd_type;           /* (enum redir_type) */
613         /* note: for heredocs, rd_filename contains heredoc delimiter,
614          * and subsequently heredoc itself; and rd_dup is a bitmask:
615          * bit 0: do we need to trim leading tabs?
616          * bit 1: is heredoc quoted (<<'delim' syntax) ?
617          */
618 };
619 typedef enum redir_type {
620         REDIRECT_INPUT     = 0,
621         REDIRECT_OVERWRITE = 1,
622         REDIRECT_APPEND    = 2,
623         REDIRECT_IO        = 3,
624         REDIRECT_HEREDOC   = 4,
625         REDIRECT_HEREDOC2  = 5, /* REDIRECT_HEREDOC after heredoc is loaded */
626
627         REDIRFD_CLOSE      = -3,
628         REDIRFD_SYNTAX_ERR = -2,
629         REDIRFD_TO_FILE    = -1,
630         /* otherwise, rd_fd is redirected to rd_dup */
631
632         HEREDOC_SKIPTABS = 1,
633         HEREDOC_QUOTED   = 2,
634 } redir_type;
635
636
637 struct command {
638         pid_t pid;                  /* 0 if exited */
639         unsigned assignment_cnt;    /* how many argv[i] are assignments? */
640 #if ENABLE_HUSH_LINENO_VAR
641         unsigned lineno;
642 #endif
643         smallint cmd_type;          /* CMD_xxx */
644 #define CMD_NORMAL   0
645 #define CMD_SUBSHELL 1
646 #if BASH_TEST2 || ENABLE_HUSH_LOCAL || ENABLE_HUSH_EXPORT || ENABLE_HUSH_READONLY
647 /* used for "[[ EXPR ]]", and to prevent word splitting and globbing in
648  * "export v=t*"
649  */
650 # define CMD_SINGLEWORD_NOGLOB 2
651 #endif
652 #if ENABLE_HUSH_FUNCTIONS
653 # define CMD_FUNCDEF 3
654 #endif
655
656         smalluint cmd_exitcode;
657         /* if non-NULL, this "command" is { list }, ( list ), or a compound statement */
658         struct pipe *group;
659 #if !BB_MMU
660         char *group_as_string;
661 #endif
662 #if ENABLE_HUSH_FUNCTIONS
663         struct function *child_func;
664 /* This field is used to prevent a bug here:
665  * while...do f1() {a;}; f1; f1() {b;}; f1; done
666  * When we execute "f1() {a;}" cmd, we create new function and clear
667  * cmd->group, cmd->group_as_string, cmd->argv[0].
668  * When we execute "f1() {b;}", we notice that f1 exists,
669  * and that its "parent cmd" struct is still "alive",
670  * we put those fields back into cmd->xxx
671  * (struct function has ->parent_cmd ptr to facilitate that).
672  * When we loop back, we can execute "f1() {a;}" again and set f1 correctly.
673  * Without this trick, loop would execute a;b;b;b;...
674  * instead of correct sequence a;b;a;b;...
675  * When command is freed, it severs the link
676  * (sets ->child_func->parent_cmd to NULL).
677  */
678 #endif
679         char **argv;                /* command name and arguments */
680 /* argv vector may contain variable references (^Cvar^C, ^C0^C etc)
681  * and on execution these are substituted with their values.
682  * Substitution can make _several_ words out of one argv[n]!
683  * Example: argv[0]=='.^C*^C.' here: echo .$*.
684  * References of the form ^C`cmd arg^C are `cmd arg` substitutions.
685  */
686         struct redir_struct *redirects; /* I/O redirections */
687 };
688 /* Is there anything in this command at all? */
689 #define IS_NULL_CMD(cmd) \
690         (!(cmd)->group && !(cmd)->argv && !(cmd)->redirects)
691
692 struct pipe {
693         struct pipe *next;
694         int num_cmds;               /* total number of commands in pipe */
695         int alive_cmds;             /* number of commands running (not exited) */
696         int stopped_cmds;           /* number of commands alive, but stopped */
697 #if ENABLE_HUSH_JOB
698         unsigned jobid;             /* job number */
699         pid_t pgrp;                 /* process group ID for the job */
700         char *cmdtext;              /* name of job */
701 #endif
702         struct command *cmds;       /* array of commands in pipe */
703         smallint followup;          /* PIPE_BG, PIPE_SEQ, PIPE_OR, PIPE_AND */
704         IF_HAS_KEYWORDS(smallint pi_inverted;) /* "! cmd | cmd" */
705         IF_HAS_KEYWORDS(smallint res_word;) /* needed for if, for, while, until... */
706 };
707 typedef enum pipe_style {
708         PIPE_SEQ = 0,
709         PIPE_AND = 1,
710         PIPE_OR  = 2,
711         PIPE_BG  = 3,
712 } pipe_style;
713 /* Is there anything in this pipe at all? */
714 #define IS_NULL_PIPE(pi) \
715         ((pi)->num_cmds == 0 IF_HAS_KEYWORDS( && (pi)->res_word == RES_NONE))
716
717 /* This holds pointers to the various results of parsing */
718 struct parse_context {
719         /* linked list of pipes */
720         struct pipe *list_head;
721         /* last pipe (being constructed right now) */
722         struct pipe *pipe;
723         /* last command in pipe (being constructed right now) */
724         struct command *command;
725         /* last redirect in command->redirects list */
726         struct redir_struct *pending_redirect;
727         o_string word;
728 #if !BB_MMU
729         o_string as_string;
730 #endif
731         smallint is_assignment; /* 0:maybe, 1:yes, 2:no, 3:keyword */
732 #if HAS_KEYWORDS
733         smallint ctx_res_w;
734         smallint ctx_inverted; /* "! cmd | cmd" */
735 #if ENABLE_HUSH_CASE
736         smallint ctx_dsemicolon; /* ";;" seen */
737 #endif
738         /* bitmask of FLAG_xxx, for figuring out valid reserved words */
739         int old_flag;
740         /* group we are enclosed in:
741          * example: "if pipe1; pipe2; then pipe3; fi"
742          * when we see "if" or "then", we malloc and copy current context,
743          * and make ->stack point to it. then we parse pipeN.
744          * when closing "then" / fi" / whatever is found,
745          * we move list_head into ->stack->command->group,
746          * copy ->stack into current context, and delete ->stack.
747          * (parsing of { list } and ( list ) doesn't use this method)
748          */
749         struct parse_context *stack;
750 #endif
751 };
752 enum {
753         MAYBE_ASSIGNMENT      = 0,
754         DEFINITELY_ASSIGNMENT = 1,
755         NOT_ASSIGNMENT        = 2,
756         /* Not an assignment, but next word may be: "if v=xyz cmd;" */
757         WORD_IS_KEYWORD       = 3,
758 };
759
760 /* On program start, environ points to initial environment.
761  * putenv adds new pointers into it, unsetenv removes them.
762  * Neither of these (de)allocates the strings.
763  * setenv allocates new strings in malloc space and does putenv,
764  * and thus setenv is unusable (leaky) for shell's purposes */
765 #define setenv(...) setenv_is_leaky_dont_use()
766 struct variable {
767         struct variable *next;
768         char *varstr;        /* points to "name=" portion */
769         int max_len;         /* if > 0, name is part of initial env; else name is malloced */
770         uint16_t var_nest_level;
771         smallint flg_export; /* putenv should be done on this var */
772         smallint flg_read_only;
773 };
774
775 enum {
776         BC_BREAK = 1,
777         BC_CONTINUE = 2,
778 };
779
780 #if ENABLE_HUSH_FUNCTIONS
781 struct function {
782         struct function *next;
783         char *name;
784         struct command *parent_cmd;
785         struct pipe *body;
786 # if !BB_MMU
787         char *body_as_string;
788 # endif
789 };
790 #endif
791
792
793 /* set -/+o OPT support. (TODO: make it optional)
794  * bash supports the following opts:
795  * allexport       off
796  * braceexpand     on
797  * emacs           on
798  * errexit         off
799  * errtrace        off
800  * functrace       off
801  * hashall         on
802  * histexpand      off
803  * history         on
804  * ignoreeof       off
805  * interactive-comments    on
806  * keyword         off
807  * monitor         on
808  * noclobber       off
809  * noexec          off
810  * noglob          off
811  * nolog           off
812  * notify          off
813  * nounset         off
814  * onecmd          off
815  * physical        off
816  * pipefail        off
817  * posix           off
818  * privileged      off
819  * verbose         off
820  * vi              off
821  * xtrace          off
822  */
823 static const char o_opt_strings[] ALIGN1 =
824         "pipefail\0"
825         "noexec\0"
826         "errexit\0"
827 #if ENABLE_HUSH_MODE_X
828         "xtrace\0"
829 #endif
830         ;
831 enum {
832         OPT_O_PIPEFAIL,
833         OPT_O_NOEXEC,
834         OPT_O_ERREXIT,
835 #if ENABLE_HUSH_MODE_X
836         OPT_O_XTRACE,
837 #endif
838         NUM_OPT_O
839 };
840
841 /* "Globals" within this file */
842 /* Sorted roughly by size (smaller offsets == smaller code) */
843 struct globals {
844         /* interactive_fd != 0 means we are an interactive shell.
845          * If we are, then saved_tty_pgrp can also be != 0, meaning
846          * that controlling tty is available. With saved_tty_pgrp == 0,
847          * job control still works, but terminal signals
848          * (^C, ^Z, ^Y, ^\) won't work at all, and background
849          * process groups can only be created with "cmd &".
850          * With saved_tty_pgrp != 0, hush will use tcsetpgrp()
851          * to give tty to the foreground process group,
852          * and will take it back when the group is stopped (^Z)
853          * or killed (^C).
854          */
855 #if ENABLE_HUSH_INTERACTIVE
856         /* 'interactive_fd' is a fd# open to ctty, if we have one
857          * _AND_ if we decided to act interactively */
858         int interactive_fd;
859         const char *PS1;
860         IF_FEATURE_EDITING_FANCY_PROMPT(const char *PS2;)
861 # define G_interactive_fd (G.interactive_fd)
862 #else
863 # define G_interactive_fd 0
864 #endif
865 #if ENABLE_FEATURE_EDITING
866         line_input_t *line_input_state;
867 #endif
868         pid_t root_pid;
869         pid_t root_ppid;
870         pid_t last_bg_pid;
871 #if ENABLE_HUSH_RANDOM_SUPPORT
872         random_t random_gen;
873 #endif
874 #if ENABLE_HUSH_JOB
875         int run_list_level;
876         unsigned last_jobid;
877         pid_t saved_tty_pgrp;
878         struct pipe *job_list;
879 # define G_saved_tty_pgrp (G.saved_tty_pgrp)
880 #else
881 # define G_saved_tty_pgrp 0
882 #endif
883         /* How deeply are we in context where "set -e" is ignored */
884         int errexit_depth;
885         /* "set -e" rules (do we follow them correctly?):
886          * Exit if pipe, list, or compound command exits with a non-zero status.
887          * Shell does not exit if failed command is part of condition in
888          * if/while, part of && or || list except the last command, any command
889          * in a pipe but the last, or if the command's return value is being
890          * inverted with !. If a compound command other than a subshell returns a
891          * non-zero status because a command failed while -e was being ignored, the
892          * shell does not exit. A trap on ERR, if set, is executed before the shell
893          * exits [ERR is a bashism].
894          *
895          * If a compound command or function executes in a context where -e is
896          * ignored, none of the commands executed within are affected by the -e
897          * setting. If a compound command or function sets -e while executing in a
898          * context where -e is ignored, that setting does not have any effect until
899          * the compound command or the command containing the function call completes.
900          */
901
902         char o_opt[NUM_OPT_O];
903 #if ENABLE_HUSH_MODE_X
904 # define G_x_mode (G.o_opt[OPT_O_XTRACE])
905 #else
906 # define G_x_mode 0
907 #endif
908 #if ENABLE_HUSH_INTERACTIVE
909         smallint promptmode; /* 0: PS1, 1: PS2 */
910 #endif
911         smallint flag_SIGINT;
912 #if ENABLE_HUSH_LOOPS
913         smallint flag_break_continue;
914 #endif
915 #if ENABLE_HUSH_FUNCTIONS
916         /* 0: outside of a function (or sourced file)
917          * -1: inside of a function, ok to use return builtin
918          * 1: return is invoked, skip all till end of func
919          */
920         smallint flag_return_in_progress;
921 # define G_flag_return_in_progress (G.flag_return_in_progress)
922 #else
923 # define G_flag_return_in_progress 0
924 #endif
925         smallint exiting; /* used to prevent EXIT trap recursion */
926         /* These support $?, $#, and $1 */
927         smalluint last_exitcode;
928         smalluint expand_exitcode;
929         smalluint last_bg_pid_exitcode;
930 #if ENABLE_HUSH_SET
931         /* are global_argv and global_argv[1..n] malloced? (note: not [0]) */
932         smalluint global_args_malloced;
933 # define G_global_args_malloced (G.global_args_malloced)
934 #else
935 # define G_global_args_malloced 0
936 #endif
937         /* how many non-NULL argv's we have. NB: $# + 1 */
938         int global_argc;
939         char **global_argv;
940 #if !BB_MMU
941         char *argv0_for_re_execing;
942 #endif
943 #if ENABLE_HUSH_LOOPS
944         unsigned depth_break_continue;
945         unsigned depth_of_loop;
946 #endif
947 #if ENABLE_HUSH_GETOPTS
948         unsigned getopt_count;
949 #endif
950         const char *ifs;
951         char *ifs_whitespace; /* = G.ifs or malloced */
952         const char *cwd;
953         struct variable *top_var;
954         char **expanded_assignments;
955         struct variable **shadowed_vars_pp;
956         unsigned var_nest_level;
957 #if ENABLE_HUSH_FUNCTIONS
958 # if ENABLE_HUSH_LOCAL
959         unsigned func_nest_level; /* solely to prevent "local v" in non-functions */
960 # endif
961         struct function *top_func;
962 #endif
963         /* Signal and trap handling */
964 #if ENABLE_HUSH_FAST
965         unsigned count_SIGCHLD;
966         unsigned handled_SIGCHLD;
967         smallint we_have_children;
968 #endif
969 #if ENABLE_HUSH_LINENO_VAR
970         unsigned lineno;
971         char *lineno_var;
972 #endif
973         HFILE *HFILE_list;
974         /* Which signals have non-DFL handler (even with no traps set)?
975          * Set at the start to:
976          * (SIGQUIT + maybe SPECIAL_INTERACTIVE_SIGS + maybe SPECIAL_JOBSTOP_SIGS)
977          * SPECIAL_INTERACTIVE_SIGS are cleared after fork.
978          * The rest is cleared right before execv syscalls.
979          * Other than these two times, never modified.
980          */
981         unsigned special_sig_mask;
982 #if ENABLE_HUSH_JOB
983         unsigned fatal_sig_mask;
984 # define G_fatal_sig_mask (G.fatal_sig_mask)
985 #else
986 # define G_fatal_sig_mask 0
987 #endif
988 #if ENABLE_HUSH_TRAP
989         char **traps; /* char *traps[NSIG] */
990 # define G_traps G.traps
991 #else
992 # define G_traps ((char**)NULL)
993 #endif
994         sigset_t pending_set;
995 #if ENABLE_HUSH_MEMLEAK
996         unsigned long memleak_value;
997 #endif
998 #if ENABLE_HUSH_MODE_X
999         unsigned x_mode_depth;
1000         /* "set -x" output should not be redirectable with subsequent 2>FILE.
1001          * We dup fd#2 to x_mode_fd when "set -x" is executed, and use it
1002          * for all subsequent output.
1003          */
1004         int x_mode_fd;
1005         o_string x_mode_buf;
1006 #endif
1007 #if HUSH_DEBUG >= 2
1008         int debug_indent;
1009 #endif
1010         struct sigaction sa;
1011 #if ENABLE_FEATURE_EDITING
1012         char user_input_buf[CONFIG_FEATURE_EDITING_MAX_LEN];
1013 #endif
1014 };
1015 #define G (*ptr_to_globals)
1016 /* Not #defining name to G.name - this quickly gets unwieldy
1017  * (too many defines). Also, I actually prefer to see when a variable
1018  * is global, thus "G." prefix is a useful hint */
1019 #define INIT_G() do { \
1020         SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
1021         /* memset(&G.sa, 0, sizeof(G.sa)); */  \
1022         sigfillset(&G.sa.sa_mask); \
1023         G.sa.sa_flags = SA_RESTART; \
1024 } while (0)
1025
1026
1027 /* Function prototypes for builtins */
1028 static int builtin_cd(char **argv) FAST_FUNC;
1029 #if ENABLE_HUSH_ECHO
1030 static int builtin_echo(char **argv) FAST_FUNC;
1031 #endif
1032 static int builtin_eval(char **argv) FAST_FUNC;
1033 static int builtin_exec(char **argv) FAST_FUNC;
1034 static int builtin_exit(char **argv) FAST_FUNC;
1035 #if ENABLE_HUSH_EXPORT
1036 static int builtin_export(char **argv) FAST_FUNC;
1037 #endif
1038 #if ENABLE_HUSH_READONLY
1039 static int builtin_readonly(char **argv) FAST_FUNC;
1040 #endif
1041 #if ENABLE_HUSH_JOB
1042 static int builtin_fg_bg(char **argv) FAST_FUNC;
1043 static int builtin_jobs(char **argv) FAST_FUNC;
1044 #endif
1045 #if ENABLE_HUSH_GETOPTS
1046 static int builtin_getopts(char **argv) FAST_FUNC;
1047 #endif
1048 #if ENABLE_HUSH_HELP
1049 static int builtin_help(char **argv) FAST_FUNC;
1050 #endif
1051 #if MAX_HISTORY && ENABLE_FEATURE_EDITING
1052 static int builtin_history(char **argv) FAST_FUNC;
1053 #endif
1054 #if ENABLE_HUSH_LOCAL
1055 static int builtin_local(char **argv) FAST_FUNC;
1056 #endif
1057 #if ENABLE_HUSH_MEMLEAK
1058 static int builtin_memleak(char **argv) FAST_FUNC;
1059 #endif
1060 #if ENABLE_HUSH_PRINTF
1061 static int builtin_printf(char **argv) FAST_FUNC;
1062 #endif
1063 static int builtin_pwd(char **argv) FAST_FUNC;
1064 #if ENABLE_HUSH_READ
1065 static int builtin_read(char **argv) FAST_FUNC;
1066 #endif
1067 #if ENABLE_HUSH_SET
1068 static int builtin_set(char **argv) FAST_FUNC;
1069 #endif
1070 static int builtin_shift(char **argv) FAST_FUNC;
1071 static int builtin_source(char **argv) FAST_FUNC;
1072 #if ENABLE_HUSH_TEST || BASH_TEST2
1073 static int builtin_test(char **argv) FAST_FUNC;
1074 #endif
1075 #if ENABLE_HUSH_TRAP
1076 static int builtin_trap(char **argv) FAST_FUNC;
1077 #endif
1078 #if ENABLE_HUSH_TYPE
1079 static int builtin_type(char **argv) FAST_FUNC;
1080 #endif
1081 #if ENABLE_HUSH_TIMES
1082 static int builtin_times(char **argv) FAST_FUNC;
1083 #endif
1084 static int builtin_true(char **argv) FAST_FUNC;
1085 #if ENABLE_HUSH_UMASK
1086 static int builtin_umask(char **argv) FAST_FUNC;
1087 #endif
1088 #if ENABLE_HUSH_UNSET
1089 static int builtin_unset(char **argv) FAST_FUNC;
1090 #endif
1091 #if ENABLE_HUSH_KILL
1092 static int builtin_kill(char **argv) FAST_FUNC;
1093 #endif
1094 #if ENABLE_HUSH_WAIT
1095 static int builtin_wait(char **argv) FAST_FUNC;
1096 #endif
1097 #if ENABLE_HUSH_LOOPS
1098 static int builtin_break(char **argv) FAST_FUNC;
1099 static int builtin_continue(char **argv) FAST_FUNC;
1100 #endif
1101 #if ENABLE_HUSH_FUNCTIONS
1102 static int builtin_return(char **argv) FAST_FUNC;
1103 #endif
1104
1105 /* Table of built-in functions.  They can be forked or not, depending on
1106  * context: within pipes, they fork.  As simple commands, they do not.
1107  * When used in non-forking context, they can change global variables
1108  * in the parent shell process.  If forked, of course they cannot.
1109  * For example, 'unset foo | whatever' will parse and run, but foo will
1110  * still be set at the end. */
1111 struct built_in_command {
1112         const char *b_cmd;
1113         int (*b_function)(char **argv) FAST_FUNC;
1114 #if ENABLE_HUSH_HELP
1115         const char *b_descr;
1116 # define BLTIN(cmd, func, help) { cmd, func, help }
1117 #else
1118 # define BLTIN(cmd, func, help) { cmd, func }
1119 #endif
1120 };
1121
1122 static const struct built_in_command bltins1[] = {
1123         BLTIN("."        , builtin_source  , "Run commands in file"),
1124         BLTIN(":"        , builtin_true    , NULL),
1125 #if ENABLE_HUSH_JOB
1126         BLTIN("bg"       , builtin_fg_bg   , "Resume job in background"),
1127 #endif
1128 #if ENABLE_HUSH_LOOPS
1129         BLTIN("break"    , builtin_break   , "Exit loop"),
1130 #endif
1131         BLTIN("cd"       , builtin_cd      , "Change directory"),
1132 #if ENABLE_HUSH_LOOPS
1133         BLTIN("continue" , builtin_continue, "Start new loop iteration"),
1134 #endif
1135         BLTIN("eval"     , builtin_eval    , "Construct and run shell command"),
1136         BLTIN("exec"     , builtin_exec    , "Execute command, don't return to shell"),
1137         BLTIN("exit"     , builtin_exit    , NULL),
1138 #if ENABLE_HUSH_EXPORT
1139         BLTIN("export"   , builtin_export  , "Set environment variables"),
1140 #endif
1141 #if ENABLE_HUSH_JOB
1142         BLTIN("fg"       , builtin_fg_bg   , "Bring job to foreground"),
1143 #endif
1144 #if ENABLE_HUSH_GETOPTS
1145         BLTIN("getopts"  , builtin_getopts , NULL),
1146 #endif
1147 #if ENABLE_HUSH_HELP
1148         BLTIN("help"     , builtin_help    , NULL),
1149 #endif
1150 #if MAX_HISTORY && ENABLE_FEATURE_EDITING
1151         BLTIN("history"  , builtin_history , "Show history"),
1152 #endif
1153 #if ENABLE_HUSH_JOB
1154         BLTIN("jobs"     , builtin_jobs    , "List jobs"),
1155 #endif
1156 #if ENABLE_HUSH_KILL
1157         BLTIN("kill"     , builtin_kill    , "Send signals to processes"),
1158 #endif
1159 #if ENABLE_HUSH_LOCAL
1160         BLTIN("local"    , builtin_local   , "Set local variables"),
1161 #endif
1162 #if ENABLE_HUSH_MEMLEAK
1163         BLTIN("memleak"  , builtin_memleak , NULL),
1164 #endif
1165 #if ENABLE_HUSH_READ
1166         BLTIN("read"     , builtin_read    , "Input into variable"),
1167 #endif
1168 #if ENABLE_HUSH_READONLY
1169         BLTIN("readonly" , builtin_readonly, "Make variables read-only"),
1170 #endif
1171 #if ENABLE_HUSH_FUNCTIONS
1172         BLTIN("return"   , builtin_return  , "Return from function"),
1173 #endif
1174 #if ENABLE_HUSH_SET
1175         BLTIN("set"      , builtin_set     , "Set positional parameters"),
1176 #endif
1177         BLTIN("shift"    , builtin_shift   , "Shift positional parameters"),
1178 #if BASH_SOURCE
1179         BLTIN("source"   , builtin_source  , NULL),
1180 #endif
1181 #if ENABLE_HUSH_TIMES
1182         BLTIN("times"    , builtin_times   , NULL),
1183 #endif
1184 #if ENABLE_HUSH_TRAP
1185         BLTIN("trap"     , builtin_trap    , "Trap signals"),
1186 #endif
1187         BLTIN("true"     , builtin_true    , NULL),
1188 #if ENABLE_HUSH_TYPE
1189         BLTIN("type"     , builtin_type    , "Show command type"),
1190 #endif
1191 #if ENABLE_HUSH_ULIMIT
1192         BLTIN("ulimit"   , shell_builtin_ulimit, "Control resource limits"),
1193 #endif
1194 #if ENABLE_HUSH_UMASK
1195         BLTIN("umask"    , builtin_umask   , "Set file creation mask"),
1196 #endif
1197 #if ENABLE_HUSH_UNSET
1198         BLTIN("unset"    , builtin_unset   , "Unset variables"),
1199 #endif
1200 #if ENABLE_HUSH_WAIT
1201         BLTIN("wait"     , builtin_wait    , "Wait for process to finish"),
1202 #endif
1203 };
1204 /* These builtins won't be used if we are on NOMMU and need to re-exec
1205  * (it's cheaper to run an external program in this case):
1206  */
1207 static const struct built_in_command bltins2[] = {
1208 #if ENABLE_HUSH_TEST
1209         BLTIN("["        , builtin_test    , NULL),
1210 #endif
1211 #if BASH_TEST2
1212         BLTIN("[["       , builtin_test    , NULL),
1213 #endif
1214 #if ENABLE_HUSH_ECHO
1215         BLTIN("echo"     , builtin_echo    , NULL),
1216 #endif
1217 #if ENABLE_HUSH_PRINTF
1218         BLTIN("printf"   , builtin_printf  , NULL),
1219 #endif
1220         BLTIN("pwd"      , builtin_pwd     , NULL),
1221 #if ENABLE_HUSH_TEST
1222         BLTIN("test"     , builtin_test    , NULL),
1223 #endif
1224 };
1225
1226
1227 /* Debug printouts.
1228  */
1229 #if HUSH_DEBUG >= 2
1230 /* prevent disasters with G.debug_indent < 0 */
1231 # define indent() fdprintf(2, "%*s", (G.debug_indent * 2) & 0xff, "")
1232 # define debug_enter() (G.debug_indent++)
1233 # define debug_leave() (G.debug_indent--)
1234 #else
1235 # define indent()      ((void)0)
1236 # define debug_enter() ((void)0)
1237 # define debug_leave() ((void)0)
1238 #endif
1239
1240 #ifndef debug_printf
1241 # define debug_printf(...) (indent(), fdprintf(2, __VA_ARGS__))
1242 #endif
1243
1244 #ifndef debug_printf_parse
1245 # define debug_printf_parse(...) (indent(), fdprintf(2, __VA_ARGS__))
1246 #endif
1247
1248 #ifndef debug_printf_heredoc
1249 # define debug_printf_heredoc(...) (indent(), fdprintf(2, __VA_ARGS__))
1250 #endif
1251
1252 #ifndef debug_printf_exec
1253 #define debug_printf_exec(...) (indent(), fdprintf(2, __VA_ARGS__))
1254 #endif
1255
1256 #ifndef debug_printf_env
1257 # define debug_printf_env(...) (indent(), fdprintf(2, __VA_ARGS__))
1258 #endif
1259
1260 #ifndef debug_printf_jobs
1261 # define debug_printf_jobs(...) (indent(), fdprintf(2, __VA_ARGS__))
1262 # define DEBUG_JOBS 1
1263 #else
1264 # define DEBUG_JOBS 0
1265 #endif
1266
1267 #ifndef debug_printf_expand
1268 # define debug_printf_expand(...) (indent(), fdprintf(2, __VA_ARGS__))
1269 # define DEBUG_EXPAND 1
1270 #else
1271 # define DEBUG_EXPAND 0
1272 #endif
1273
1274 #ifndef debug_printf_varexp
1275 # define debug_printf_varexp(...) (indent(), fdprintf(2, __VA_ARGS__))
1276 #endif
1277
1278 #ifndef debug_printf_glob
1279 # define debug_printf_glob(...) (indent(), fdprintf(2, __VA_ARGS__))
1280 # define DEBUG_GLOB 1
1281 #else
1282 # define DEBUG_GLOB 0
1283 #endif
1284
1285 #ifndef debug_printf_redir
1286 # define debug_printf_redir(...) (indent(), fdprintf(2, __VA_ARGS__))
1287 #endif
1288
1289 #ifndef debug_printf_list
1290 # define debug_printf_list(...) (indent(), fdprintf(2, __VA_ARGS__))
1291 #endif
1292
1293 #ifndef debug_printf_subst
1294 # define debug_printf_subst(...) (indent(), fdprintf(2, __VA_ARGS__))
1295 #endif
1296
1297 #ifndef debug_printf_prompt
1298 # define debug_printf_prompt(...) (indent(), fdprintf(2, __VA_ARGS__))
1299 #endif
1300
1301 #ifndef debug_printf_clean
1302 # define debug_printf_clean(...) (indent(), fdprintf(2, __VA_ARGS__))
1303 # define DEBUG_CLEAN 1
1304 #else
1305 # define DEBUG_CLEAN 0
1306 #endif
1307
1308 #if DEBUG_EXPAND
1309 static void debug_print_strings(const char *prefix, char **vv)
1310 {
1311         indent();
1312         fdprintf(2, "%s:\n", prefix);
1313         while (*vv)
1314                 fdprintf(2, " '%s'\n", *vv++);
1315 }
1316 #else
1317 # define debug_print_strings(prefix, vv) ((void)0)
1318 #endif
1319
1320
1321 /* Leak hunting. Use hush_leaktool.sh for post-processing.
1322  */
1323 #if LEAK_HUNTING
1324 static void *xxmalloc(int lineno, size_t size)
1325 {
1326         void *ptr = xmalloc((size + 0xff) & ~0xff);
1327         fdprintf(2, "line %d: malloc %p\n", lineno, ptr);
1328         return ptr;
1329 }
1330 static void *xxrealloc(int lineno, void *ptr, size_t size)
1331 {
1332         ptr = xrealloc(ptr, (size + 0xff) & ~0xff);
1333         fdprintf(2, "line %d: realloc %p\n", lineno, ptr);
1334         return ptr;
1335 }
1336 static char *xxstrdup(int lineno, const char *str)
1337 {
1338         char *ptr = xstrdup(str);
1339         fdprintf(2, "line %d: strdup %p\n", lineno, ptr);
1340         return ptr;
1341 }
1342 static void xxfree(void *ptr)
1343 {
1344         fdprintf(2, "free %p\n", ptr);
1345         free(ptr);
1346 }
1347 # define xmalloc(s)     xxmalloc(__LINE__, s)
1348 # define xrealloc(p, s) xxrealloc(__LINE__, p, s)
1349 # define xstrdup(s)     xxstrdup(__LINE__, s)
1350 # define free(p)        xxfree(p)
1351 #endif
1352
1353
1354 /* Syntax and runtime errors. They always abort scripts.
1355  * In interactive use they usually discard unparsed and/or unexecuted commands
1356  * and return to the prompt.
1357  * HUSH_DEBUG >= 2 prints line number in this file where it was detected.
1358  */
1359 #if HUSH_DEBUG < 2
1360 # define msg_and_die_if_script(lineno, ...)     msg_and_die_if_script(__VA_ARGS__)
1361 # define syntax_error(lineno, msg)              syntax_error(msg)
1362 # define syntax_error_at(lineno, msg)           syntax_error_at(msg)
1363 # define syntax_error_unterm_ch(lineno, ch)     syntax_error_unterm_ch(ch)
1364 # define syntax_error_unterm_str(lineno, s)     syntax_error_unterm_str(s)
1365 # define syntax_error_unexpected_ch(lineno, ch) syntax_error_unexpected_ch(ch)
1366 #endif
1367
1368 static void die_if_script(void)
1369 {
1370         if (!G_interactive_fd) {
1371                 if (G.last_exitcode) /* sometines it's 2, not 1 (bash compat) */
1372                         xfunc_error_retval = G.last_exitcode;
1373                 xfunc_die();
1374         }
1375 }
1376
1377 static void msg_and_die_if_script(unsigned lineno, const char *fmt, ...)
1378 {
1379         va_list p;
1380
1381 #if HUSH_DEBUG >= 2
1382         bb_error_msg("hush.c:%u", lineno);
1383 #endif
1384         va_start(p, fmt);
1385         bb_verror_msg(fmt, p, NULL);
1386         va_end(p);
1387         die_if_script();
1388 }
1389
1390 static void syntax_error(unsigned lineno UNUSED_PARAM, const char *msg)
1391 {
1392         if (msg)
1393                 bb_error_msg("syntax error: %s", msg);
1394         else
1395                 bb_error_msg("syntax error");
1396         die_if_script();
1397 }
1398
1399 static void syntax_error_at(unsigned lineno UNUSED_PARAM, const char *msg)
1400 {
1401         bb_error_msg("syntax error at '%s'", msg);
1402         die_if_script();
1403 }
1404
1405 static void syntax_error_unterm_str(unsigned lineno UNUSED_PARAM, const char *s)
1406 {
1407         bb_error_msg("syntax error: unterminated %s", s);
1408 //? source4.tests fails: in bash, echo ${^} in script does not terminate the script
1409 //      die_if_script();
1410 }
1411
1412 static void syntax_error_unterm_ch(unsigned lineno, char ch)
1413 {
1414         char msg[2] = { ch, '\0' };
1415         syntax_error_unterm_str(lineno, msg);
1416 }
1417
1418 static void syntax_error_unexpected_ch(unsigned lineno UNUSED_PARAM, int ch)
1419 {
1420         char msg[2];
1421         msg[0] = ch;
1422         msg[1] = '\0';
1423 #if HUSH_DEBUG >= 2
1424         bb_error_msg("hush.c:%u", lineno);
1425 #endif
1426         bb_error_msg("syntax error: unexpected %s", ch == EOF ? "EOF" : msg);
1427         die_if_script();
1428 }
1429
1430 #if HUSH_DEBUG < 2
1431 # undef msg_and_die_if_script
1432 # undef syntax_error
1433 # undef syntax_error_at
1434 # undef syntax_error_unterm_ch
1435 # undef syntax_error_unterm_str
1436 # undef syntax_error_unexpected_ch
1437 #else
1438 # define msg_and_die_if_script(...)     msg_and_die_if_script(__LINE__, __VA_ARGS__)
1439 # define syntax_error(msg)              syntax_error(__LINE__, msg)
1440 # define syntax_error_at(msg)           syntax_error_at(__LINE__, msg)
1441 # define syntax_error_unterm_ch(ch)     syntax_error_unterm_ch(__LINE__, ch)
1442 # define syntax_error_unterm_str(s)     syntax_error_unterm_str(__LINE__, s)
1443 # define syntax_error_unexpected_ch(ch) syntax_error_unexpected_ch(__LINE__, ch)
1444 #endif
1445
1446
1447 #if ENABLE_HUSH_INTERACTIVE && ENABLE_FEATURE_EDITING_FANCY_PROMPT
1448 static void cmdedit_update_prompt(void);
1449 #else
1450 # define cmdedit_update_prompt() ((void)0)
1451 #endif
1452
1453
1454 /* Utility functions
1455  */
1456 /* Replace each \x with x in place, return ptr past NUL. */
1457 static char *unbackslash(char *src)
1458 {
1459         char *dst = src = strchrnul(src, '\\');
1460         while (1) {
1461                 if (*src == '\\') {
1462                         src++;
1463                         if (*src != '\0') {
1464                                 /* \x -> x */
1465                                 *dst++ = *src++;
1466                                 continue;
1467                         }
1468                         /* else: "\<nul>". Do not delete this backslash.
1469                          * Testcase: eval 'echo ok\'
1470                          */
1471                         *dst++ = '\\';
1472                         /* fallthrough */
1473                 }
1474                 if ((*dst++ = *src++) == '\0')
1475                         break;
1476         }
1477         return dst;
1478 }
1479
1480 static char **add_strings_to_strings(char **strings, char **add, int need_to_dup)
1481 {
1482         int i;
1483         unsigned count1;
1484         unsigned count2;
1485         char **v;
1486
1487         v = strings;
1488         count1 = 0;
1489         if (v) {
1490                 while (*v) {
1491                         count1++;
1492                         v++;
1493                 }
1494         }
1495         count2 = 0;
1496         v = add;
1497         while (*v) {
1498                 count2++;
1499                 v++;
1500         }
1501         v = xrealloc(strings, (count1 + count2 + 1) * sizeof(char*));
1502         v[count1 + count2] = NULL;
1503         i = count2;
1504         while (--i >= 0)
1505                 v[count1 + i] = (need_to_dup ? xstrdup(add[i]) : add[i]);
1506         return v;
1507 }
1508 #if LEAK_HUNTING
1509 static char **xx_add_strings_to_strings(int lineno, char **strings, char **add, int need_to_dup)
1510 {
1511         char **ptr = add_strings_to_strings(strings, add, need_to_dup);
1512         fdprintf(2, "line %d: add_strings_to_strings %p\n", lineno, ptr);
1513         return ptr;
1514 }
1515 #define add_strings_to_strings(strings, add, need_to_dup) \
1516         xx_add_strings_to_strings(__LINE__, strings, add, need_to_dup)
1517 #endif
1518
1519 /* Note: takes ownership of "add" ptr (it is not strdup'ed) */
1520 static char **add_string_to_strings(char **strings, char *add)
1521 {
1522         char *v[2];
1523         v[0] = add;
1524         v[1] = NULL;
1525         return add_strings_to_strings(strings, v, /*dup:*/ 0);
1526 }
1527 #if LEAK_HUNTING
1528 static char **xx_add_string_to_strings(int lineno, char **strings, char *add)
1529 {
1530         char **ptr = add_string_to_strings(strings, add);
1531         fdprintf(2, "line %d: add_string_to_strings %p\n", lineno, ptr);
1532         return ptr;
1533 }
1534 #define add_string_to_strings(strings, add) \
1535         xx_add_string_to_strings(__LINE__, strings, add)
1536 #endif
1537
1538 static void free_strings(char **strings)
1539 {
1540         char **v;
1541
1542         if (!strings)
1543                 return;
1544         v = strings;
1545         while (*v) {
1546                 free(*v);
1547                 v++;
1548         }
1549         free(strings);
1550 }
1551
1552 static int dup_CLOEXEC(int fd, int avoid_fd)
1553 {
1554         int newfd;
1555  repeat:
1556         newfd = fcntl(fd, F_DUPFD_CLOEXEC, avoid_fd + 1);
1557         if (newfd >= 0) {
1558                 if (F_DUPFD_CLOEXEC == F_DUPFD) /* if old libc (w/o F_DUPFD_CLOEXEC) */
1559                         fcntl(newfd, F_SETFD, FD_CLOEXEC);
1560         } else { /* newfd < 0 */
1561                 if (errno == EBUSY)
1562                         goto repeat;
1563                 if (errno == EINTR)
1564                         goto repeat;
1565         }
1566         return newfd;
1567 }
1568
1569 static int xdup_CLOEXEC_and_close(int fd, int avoid_fd)
1570 {
1571         int newfd;
1572  repeat:
1573         newfd = fcntl(fd, F_DUPFD_CLOEXEC, avoid_fd + 1);
1574         if (newfd < 0) {
1575                 if (errno == EBUSY)
1576                         goto repeat;
1577                 if (errno == EINTR)
1578                         goto repeat;
1579                 /* fd was not open? */
1580                 if (errno == EBADF)
1581                         return fd;
1582                 xfunc_die();
1583         }
1584         if (F_DUPFD_CLOEXEC == F_DUPFD) /* if old libc (w/o F_DUPFD_CLOEXEC) */
1585                 fcntl(newfd, F_SETFD, FD_CLOEXEC);
1586         close(fd);
1587         return newfd;
1588 }
1589
1590
1591 /* Manipulating HFILEs */
1592 static HFILE *hfopen(const char *name)
1593 {
1594         HFILE *fp;
1595         int fd;
1596
1597         fd = STDIN_FILENO;
1598         if (name) {
1599                 fd = open(name, O_RDONLY | O_CLOEXEC);
1600                 if (fd < 0)
1601                         return NULL;
1602                 if (O_CLOEXEC == 0) /* ancient libc */
1603                         close_on_exec_on(fd);
1604         }
1605
1606         fp = xmalloc(sizeof(*fp));
1607         fp->is_stdin = (name == NULL);
1608         fp->fd = fd;
1609         fp->cur = fp->end = fp->buf;
1610         fp->next_hfile = G.HFILE_list;
1611         G.HFILE_list = fp;
1612         return fp;
1613 }
1614 static void hfclose(HFILE *fp)
1615 {
1616         HFILE **pp = &G.HFILE_list;
1617         while (*pp) {
1618                 HFILE *cur = *pp;
1619                 if (cur == fp) {
1620                         *pp = cur->next_hfile;
1621                         break;
1622                 }
1623                 pp = &cur->next_hfile;
1624         }
1625         if (fp->fd >= 0)
1626                 close(fp->fd);
1627         free(fp);
1628 }
1629 static int refill_HFILE_and_getc(HFILE *fp)
1630 {
1631         int n;
1632
1633         if (fp->fd < 0) {
1634                 /* Already saw EOF */
1635                 return EOF;
1636         }
1637         /* Try to buffer more input */
1638         fp->cur = fp->buf;
1639         n = safe_read(fp->fd, fp->buf, sizeof(fp->buf));
1640         if (n < 0) {
1641                 bb_perror_msg("read error");
1642                 n = 0;
1643         }
1644         fp->end = fp->buf + n;
1645         if (n == 0) {
1646                 /* EOF/error */
1647                 close(fp->fd);
1648                 fp->fd = -1;
1649                 return EOF;
1650         }
1651         return (unsigned char)(*fp->cur++);
1652 }
1653 /* Inlined for common case of non-empty buffer.
1654  */
1655 static ALWAYS_INLINE int hfgetc(HFILE *fp)
1656 {
1657         if (fp->cur < fp->end)
1658                 return (unsigned char)(*fp->cur++);
1659         /* Buffer empty */
1660         return refill_HFILE_and_getc(fp);
1661 }
1662 static int move_HFILEs_on_redirect(int fd, int avoid_fd)
1663 {
1664         HFILE *fl = G.HFILE_list;
1665         while (fl) {
1666                 if (fd == fl->fd) {
1667                         /* We use it only on script files, they are all CLOEXEC */
1668                         fl->fd = xdup_CLOEXEC_and_close(fd, avoid_fd);
1669                         debug_printf_redir("redirect_fd %d: matches a script fd, moving it to %d\n", fd, fl->fd);
1670                         return 1; /* "found and moved" */
1671                 }
1672                 fl = fl->next_hfile;
1673         }
1674 #if ENABLE_HUSH_MODE_X
1675         if (G.x_mode_fd > 0 && fd == G.x_mode_fd) {
1676                 G.x_mode_fd = xdup_CLOEXEC_and_close(fd, avoid_fd);
1677                 return 1; /* "found and moved" */
1678         }
1679 #endif
1680         return 0; /* "not in the list" */
1681 }
1682 #if ENABLE_FEATURE_SH_STANDALONE && BB_MMU
1683 static void close_all_HFILE_list(void)
1684 {
1685         HFILE *fl = G.HFILE_list;
1686         while (fl) {
1687                 /* hfclose would also free HFILE object.
1688                  * It is disastrous if we share memory with a vforked parent.
1689                  * I'm not sure we never come here after vfork.
1690                  * Therefore just close fd, nothing more.
1691                  *
1692                  * ">" instead of ">=": we don't close fd#0,
1693                  * interactive shell uses hfopen(NULL) as stdin input
1694                  * which has fl->fd == 0, but fd#0 gets redirected in pipes.
1695                  * If we'd close it here, then e.g. interactive "set | sort"
1696                  * with NOFORKed sort, would have sort's input fd closed.
1697                  */
1698                 if (fl->fd > 0)
1699                         /*hfclose(fl); - unsafe */
1700                         close(fl->fd);
1701                 fl = fl->next_hfile;
1702         }
1703 }
1704 #endif
1705 static int fd_in_HFILEs(int fd)
1706 {
1707         HFILE *fl = G.HFILE_list;
1708         while (fl) {
1709                 if (fl->fd == fd)
1710                         return 1;
1711                 fl = fl->next_hfile;
1712         }
1713         return 0;
1714 }
1715
1716
1717 /* Helpers for setting new $n and restoring them back
1718  */
1719 typedef struct save_arg_t {
1720         char *sv_argv0;
1721         char **sv_g_argv;
1722         int sv_g_argc;
1723         IF_HUSH_SET(smallint sv_g_malloced;)
1724 } save_arg_t;
1725
1726 static void save_and_replace_G_args(save_arg_t *sv, char **argv)
1727 {
1728         sv->sv_argv0 = argv[0];
1729         sv->sv_g_argv = G.global_argv;
1730         sv->sv_g_argc = G.global_argc;
1731         IF_HUSH_SET(sv->sv_g_malloced = G.global_args_malloced;)
1732
1733         argv[0] = G.global_argv[0]; /* retain $0 */
1734         G.global_argv = argv;
1735         IF_HUSH_SET(G.global_args_malloced = 0;)
1736
1737         G.global_argc = 1 + string_array_len(argv + 1);
1738 }
1739
1740 static void restore_G_args(save_arg_t *sv, char **argv)
1741 {
1742 #if ENABLE_HUSH_SET
1743         if (G.global_args_malloced) {
1744                 /* someone ran "set -- arg1 arg2 ...", undo */
1745                 char **pp = G.global_argv;
1746                 while (*++pp) /* note: does not free $0 */
1747                         free(*pp);
1748                 free(G.global_argv);
1749         }
1750 #endif
1751         argv[0] = sv->sv_argv0;
1752         G.global_argv = sv->sv_g_argv;
1753         G.global_argc = sv->sv_g_argc;
1754         IF_HUSH_SET(G.global_args_malloced = sv->sv_g_malloced;)
1755 }
1756
1757
1758 /* Basic theory of signal handling in shell
1759  * ========================================
1760  * This does not describe what hush does, rather, it is current understanding
1761  * what it _should_ do. If it doesn't, it's a bug.
1762  * http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#trap
1763  *
1764  * Signals are handled only after each pipe ("cmd | cmd | cmd" thing)
1765  * is finished or backgrounded. It is the same in interactive and
1766  * non-interactive shells, and is the same regardless of whether
1767  * a user trap handler is installed or a shell special one is in effect.
1768  * ^C or ^Z from keyboard seems to execute "at once" because it usually
1769  * backgrounds (i.e. stops) or kills all members of currently running
1770  * pipe.
1771  *
1772  * Wait builtin is interruptible by signals for which user trap is set
1773  * or by SIGINT in interactive shell.
1774  *
1775  * Trap handlers will execute even within trap handlers. (right?)
1776  *
1777  * User trap handlers are forgotten when subshell ("(cmd)") is entered,
1778  * except for handlers set to '' (empty string).
1779  *
1780  * If job control is off, backgrounded commands ("cmd &")
1781  * have SIGINT, SIGQUIT set to SIG_IGN.
1782  *
1783  * Commands which are run in command substitution ("`cmd`")
1784  * have SIGTTIN, SIGTTOU, SIGTSTP set to SIG_IGN.
1785  *
1786  * Ordinary commands have signals set to SIG_IGN/DFL as inherited
1787  * by the shell from its parent.
1788  *
1789  * Signals which differ from SIG_DFL action
1790  * (note: child (i.e., [v]forked) shell is not an interactive shell):
1791  *
1792  * SIGQUIT: ignore
1793  * SIGTERM (interactive): ignore
1794  * SIGHUP (interactive):
1795  *    send SIGCONT to stopped jobs, send SIGHUP to all jobs and exit
1796  * SIGTTIN, SIGTTOU, SIGTSTP (if job control is on): ignore
1797  *    Note that ^Z is handled not by trapping SIGTSTP, but by seeing
1798  *    that all pipe members are stopped. Try this in bash:
1799  *    while :; do :; done - ^Z does not background it
1800  *    (while :; do :; done) - ^Z backgrounds it
1801  * SIGINT (interactive): wait for last pipe, ignore the rest
1802  *    of the command line, show prompt. NB: ^C does not send SIGINT
1803  *    to interactive shell while shell is waiting for a pipe,
1804  *    since shell is bg'ed (is not in foreground process group).
1805  *    Example 1: this waits 5 sec, but does not execute ls:
1806  *    "echo $$; sleep 5; ls -l" + "kill -INT <pid>"
1807  *    Example 2: this does not wait and does not execute ls:
1808  *    "echo $$; sleep 5 & wait; ls -l" + "kill -INT <pid>"
1809  *    Example 3: this does not wait 5 sec, but executes ls:
1810  *    "sleep 5; ls -l" + press ^C
1811  *    Example 4: this does not wait and does not execute ls:
1812  *    "sleep 5 & wait; ls -l" + press ^C
1813  *
1814  * (What happens to signals which are IGN on shell start?)
1815  * (What happens with signal mask on shell start?)
1816  *
1817  * Old implementation
1818  * ==================
1819  * We use in-kernel pending signal mask to determine which signals were sent.
1820  * We block all signals which we don't want to take action immediately,
1821  * i.e. we block all signals which need to have special handling as described
1822  * above, and all signals which have traps set.
1823  * After each pipe execution, we extract any pending signals via sigtimedwait()
1824  * and act on them.
1825  *
1826  * unsigned special_sig_mask: a mask of such "special" signals
1827  * sigset_t blocked_set:  current blocked signal set
1828  *
1829  * "trap - SIGxxx":
1830  *    clear bit in blocked_set unless it is also in special_sig_mask
1831  * "trap 'cmd' SIGxxx":
1832  *    set bit in blocked_set (even if 'cmd' is '')
1833  * after [v]fork, if we plan to be a shell:
1834  *    unblock signals with special interactive handling
1835  *    (child shell is not interactive),
1836  *    unset all traps except '' (note: regardless of child shell's type - {}, (), etc)
1837  * after [v]fork, if we plan to exec:
1838  *    POSIX says fork clears pending signal mask in child - no need to clear it.
1839  *    Restore blocked signal set to one inherited by shell just prior to exec.
1840  *
1841  * Note: as a result, we do not use signal handlers much. The only uses
1842  * are to count SIGCHLDs
1843  * and to restore tty pgrp on signal-induced exit.
1844  *
1845  * Note 2 (compat):
1846  * Standard says "When a subshell is entered, traps that are not being ignored
1847  * are set to the default actions". bash interprets it so that traps which
1848  * are set to '' (ignore) are NOT reset to defaults. We do the same.
1849  *
1850  * Problem: the above approach makes it unwieldy to catch signals while
1851  * we are in read builtin, or while we read commands from stdin:
1852  * masked signals are not visible!
1853  *
1854  * New implementation
1855  * ==================
1856  * We record each signal we are interested in by installing signal handler
1857  * for them - a bit like emulating kernel pending signal mask in userspace.
1858  * We are interested in: signals which need to have special handling
1859  * as described above, and all signals which have traps set.
1860  * Signals are recorded in pending_set.
1861  * After each pipe execution, we extract any pending signals
1862  * and act on them.
1863  *
1864  * unsigned special_sig_mask: a mask of shell-special signals.
1865  * unsigned fatal_sig_mask: a mask of signals on which we restore tty pgrp.
1866  * char *traps[sig] if trap for sig is set (even if it's '').
1867  * sigset_t pending_set: set of sigs we received.
1868  *
1869  * "trap - SIGxxx":
1870  *    if sig is in special_sig_mask, set handler back to:
1871  *        record_pending_signo, or to IGN if it's a tty stop signal
1872  *    if sig is in fatal_sig_mask, set handler back to sigexit.
1873  *    else: set handler back to SIG_DFL
1874  * "trap 'cmd' SIGxxx":
1875  *    set handler to record_pending_signo.
1876  * "trap '' SIGxxx":
1877  *    set handler to SIG_IGN.
1878  * after [v]fork, if we plan to be a shell:
1879  *    set signals with special interactive handling to SIG_DFL
1880  *    (because child shell is not interactive),
1881  *    unset all traps except '' (note: regardless of child shell's type - {}, (), etc)
1882  * after [v]fork, if we plan to exec:
1883  *    POSIX says fork clears pending signal mask in child - no need to clear it.
1884  *
1885  * To make wait builtin interruptible, we handle SIGCHLD as special signal,
1886  * otherwise (if we leave it SIG_DFL) sigsuspend in wait builtin will not wake up on it.
1887  *
1888  * Note (compat):
1889  * Standard says "When a subshell is entered, traps that are not being ignored
1890  * are set to the default actions". bash interprets it so that traps which
1891  * are set to '' (ignore) are NOT reset to defaults. We do the same.
1892  */
1893 enum {
1894         SPECIAL_INTERACTIVE_SIGS = 0
1895                 | (1 << SIGTERM)
1896                 | (1 << SIGINT)
1897                 | (1 << SIGHUP)
1898                 ,
1899         SPECIAL_JOBSTOP_SIGS = 0
1900 #if ENABLE_HUSH_JOB
1901                 | (1 << SIGTTIN)
1902                 | (1 << SIGTTOU)
1903                 | (1 << SIGTSTP)
1904 #endif
1905                 ,
1906 };
1907
1908 static void record_pending_signo(int sig)
1909 {
1910         sigaddset(&G.pending_set, sig);
1911 #if ENABLE_HUSH_FAST
1912         if (sig == SIGCHLD) {
1913                 G.count_SIGCHLD++;
1914 //bb_error_msg("[%d] SIGCHLD_handler: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
1915         }
1916 #endif
1917 }
1918
1919 static sighandler_t install_sighandler(int sig, sighandler_t handler)
1920 {
1921         struct sigaction old_sa;
1922
1923         /* We could use signal() to install handlers... almost:
1924          * except that we need to mask ALL signals while handlers run.
1925          * I saw signal nesting in strace, race window isn't small.
1926          * SA_RESTART is also needed, but in Linux, signal()
1927          * sets SA_RESTART too.
1928          */
1929         /* memset(&G.sa, 0, sizeof(G.sa)); - already done */
1930         /* sigfillset(&G.sa.sa_mask);      - already done */
1931         /* G.sa.sa_flags = SA_RESTART;     - already done */
1932         G.sa.sa_handler = handler;
1933         sigaction(sig, &G.sa, &old_sa);
1934         return old_sa.sa_handler;
1935 }
1936
1937 static void hush_exit(int exitcode) NORETURN;
1938
1939 static void restore_ttypgrp_and__exit(void) NORETURN;
1940 static void restore_ttypgrp_and__exit(void)
1941 {
1942         /* xfunc has failed! die die die */
1943         /* no EXIT traps, this is an escape hatch! */
1944         G.exiting = 1;
1945         hush_exit(xfunc_error_retval);
1946 }
1947
1948 #if ENABLE_HUSH_JOB
1949
1950 /* Needed only on some libc:
1951  * It was observed that on exit(), fgetc'ed buffered data
1952  * gets "unwound" via lseek(fd, -NUM, SEEK_CUR).
1953  * With the net effect that even after fork(), not vfork(),
1954  * exit() in NOEXECed applet in "sh SCRIPT":
1955  *      noexec_applet_here
1956  *      echo END_OF_SCRIPT
1957  * lseeks fd in input FILE object from EOF to "e" in "echo END_OF_SCRIPT".
1958  * This makes "echo END_OF_SCRIPT" executed twice.
1959  * Similar problems can be seen with msg_and_die_if_script() -> xfunc_die()
1960  * and in `cmd` handling.
1961  * If set as die_func(), this makes xfunc_die() exit via _exit(), not exit():
1962  */
1963 static void fflush_and__exit(void) NORETURN;
1964 static void fflush_and__exit(void)
1965 {
1966         fflush_all();
1967         _exit(xfunc_error_retval);
1968 }
1969
1970 /* After [v]fork, in child: do not restore tty pgrp on xfunc death */
1971 # define disable_restore_tty_pgrp_on_exit() (die_func = fflush_and__exit)
1972 /* After [v]fork, in parent: restore tty pgrp on xfunc death */
1973 # define enable_restore_tty_pgrp_on_exit()  (die_func = restore_ttypgrp_and__exit)
1974
1975 /* Restores tty foreground process group, and exits.
1976  * May be called as signal handler for fatal signal
1977  * (will resend signal to itself, producing correct exit state)
1978  * or called directly with -EXITCODE.
1979  * We also call it if xfunc is exiting.
1980  */
1981 static void sigexit(int sig) NORETURN;
1982 static void sigexit(int sig)
1983 {
1984         /* Careful: we can end up here after [v]fork. Do not restore
1985          * tty pgrp then, only top-level shell process does that */
1986         if (G_saved_tty_pgrp && getpid() == G.root_pid) {
1987                 /* Disable all signals: job control, SIGPIPE, etc.
1988                  * Mostly paranoid measure, to prevent infinite SIGTTOU.
1989                  */
1990                 sigprocmask_allsigs(SIG_BLOCK);
1991                 tcsetpgrp(G_interactive_fd, G_saved_tty_pgrp);
1992         }
1993
1994         /* Not a signal, just exit */
1995         if (sig <= 0)
1996                 _exit(- sig);
1997
1998         kill_myself_with_sig(sig); /* does not return */
1999 }
2000 #else
2001
2002 # define disable_restore_tty_pgrp_on_exit() ((void)0)
2003 # define enable_restore_tty_pgrp_on_exit()  ((void)0)
2004
2005 #endif
2006
2007 static sighandler_t pick_sighandler(unsigned sig)
2008 {
2009         sighandler_t handler = SIG_DFL;
2010         if (sig < sizeof(unsigned)*8) {
2011                 unsigned sigmask = (1 << sig);
2012
2013 #if ENABLE_HUSH_JOB
2014                 /* is sig fatal? */
2015                 if (G_fatal_sig_mask & sigmask)
2016                         handler = sigexit;
2017                 else
2018 #endif
2019                 /* sig has special handling? */
2020                 if (G.special_sig_mask & sigmask) {
2021                         handler = record_pending_signo;
2022                         /* TTIN/TTOU/TSTP can't be set to record_pending_signo
2023                          * in order to ignore them: they will be raised
2024                          * in an endless loop when we try to do some
2025                          * terminal ioctls! We do have to _ignore_ these.
2026                          */
2027                         if (SPECIAL_JOBSTOP_SIGS & sigmask)
2028                                 handler = SIG_IGN;
2029                 }
2030         }
2031         return handler;
2032 }
2033
2034 /* Restores tty foreground process group, and exits. */
2035 static void hush_exit(int exitcode)
2036 {
2037 #if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT
2038         save_history(G.line_input_state);
2039 #endif
2040
2041         fflush_all();
2042         if (G.exiting <= 0 && G_traps && G_traps[0] && G_traps[0][0]) {
2043                 char *argv[3];
2044                 /* argv[0] is unused */
2045                 argv[1] = xstrdup(G_traps[0]); /* copy, since EXIT trap handler may modify G_traps[0] */
2046                 argv[2] = NULL;
2047                 G.exiting = 1; /* prevent EXIT trap recursion */
2048                 /* Note: G_traps[0] is not cleared!
2049                  * "trap" will still show it, if executed
2050                  * in the handler */
2051                 builtin_eval(argv);
2052         }
2053
2054 #if ENABLE_FEATURE_CLEAN_UP
2055         {
2056                 struct variable *cur_var;
2057                 if (G.cwd != bb_msg_unknown)
2058                         free((char*)G.cwd);
2059                 cur_var = G.top_var;
2060                 while (cur_var) {
2061                         struct variable *tmp = cur_var;
2062                         if (!cur_var->max_len)
2063                                 free(cur_var->varstr);
2064                         cur_var = cur_var->next;
2065                         free(tmp);
2066                 }
2067         }
2068 #endif
2069
2070         fflush_all();
2071 #if ENABLE_HUSH_JOB
2072         sigexit(- (exitcode & 0xff));
2073 #else
2074         _exit(exitcode);
2075 #endif
2076 }
2077
2078
2079 //TODO: return a mask of ALL handled sigs?
2080 static int check_and_run_traps(void)
2081 {
2082         int last_sig = 0;
2083
2084         while (1) {
2085                 int sig;
2086
2087                 if (sigisemptyset(&G.pending_set))
2088                         break;
2089                 sig = 0;
2090                 do {
2091                         sig++;
2092                         if (sigismember(&G.pending_set, sig)) {
2093                                 sigdelset(&G.pending_set, sig);
2094                                 goto got_sig;
2095                         }
2096                 } while (sig < NSIG);
2097                 break;
2098  got_sig:
2099                 if (G_traps && G_traps[sig]) {
2100                         debug_printf_exec("%s: sig:%d handler:'%s'\n", __func__, sig, G.traps[sig]);
2101                         if (G_traps[sig][0]) {
2102                                 /* We have user-defined handler */
2103                                 smalluint save_rcode;
2104                                 char *argv[3];
2105                                 /* argv[0] is unused */
2106                                 argv[1] = xstrdup(G_traps[sig]);
2107                                 /* why strdup? trap can modify itself: trap 'trap "echo oops" INT' INT */
2108                                 argv[2] = NULL;
2109                                 save_rcode = G.last_exitcode;
2110                                 builtin_eval(argv);
2111                                 free(argv[1]);
2112 //FIXME: shouldn't it be set to 128 + sig instead?
2113                                 G.last_exitcode = save_rcode;
2114                                 last_sig = sig;
2115                         } /* else: "" trap, ignoring signal */
2116                         continue;
2117                 }
2118                 /* not a trap: special action */
2119                 switch (sig) {
2120                 case SIGINT:
2121                         debug_printf_exec("%s: sig:%d default SIGINT handler\n", __func__, sig);
2122                         G.flag_SIGINT = 1;
2123                         last_sig = sig;
2124                         break;
2125 #if ENABLE_HUSH_JOB
2126                 case SIGHUP: {
2127 //TODO: why are we doing this? ash and dash don't do this,
2128 //they have no handler for SIGHUP at all,
2129 //they rely on kernel to send SIGHUP+SIGCONT to orphaned process groups
2130                         struct pipe *job;
2131                         debug_printf_exec("%s: sig:%d default SIGHUP handler\n", __func__, sig);
2132                         /* bash is observed to signal whole process groups,
2133                          * not individual processes */
2134                         for (job = G.job_list; job; job = job->next) {
2135                                 if (job->pgrp <= 0)
2136                                         continue;
2137                                 debug_printf_exec("HUPing pgrp %d\n", job->pgrp);
2138                                 if (kill(- job->pgrp, SIGHUP) == 0)
2139                                         kill(- job->pgrp, SIGCONT);
2140                         }
2141                         sigexit(SIGHUP);
2142                 }
2143 #endif
2144 #if ENABLE_HUSH_FAST
2145                 case SIGCHLD:
2146                         debug_printf_exec("%s: sig:%d default SIGCHLD handler\n", __func__, sig);
2147                         G.count_SIGCHLD++;
2148 //bb_error_msg("[%d] check_and_run_traps: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
2149                         /* Note:
2150                          * We don't do 'last_sig = sig' here -> NOT returning this sig.
2151                          * This simplifies wait builtin a bit.
2152                          */
2153                         break;
2154 #endif
2155                 default: /* ignored: */
2156                         debug_printf_exec("%s: sig:%d default handling is to ignore\n", __func__, sig);
2157                         /* SIGTERM, SIGQUIT, SIGTTIN, SIGTTOU, SIGTSTP */
2158                         /* Note:
2159                          * We don't do 'last_sig = sig' here -> NOT returning this sig.
2160                          * Example: wait is not interrupted by TERM
2161                          * in interactive shell, because TERM is ignored.
2162                          */
2163                         break;
2164                 }
2165         }
2166         return last_sig;
2167 }
2168
2169
2170 static const char *get_cwd(int force)
2171 {
2172         if (force || G.cwd == NULL) {
2173                 /* xrealloc_getcwd_or_warn(arg) calls free(arg),
2174                  * we must not try to free(bb_msg_unknown) */
2175                 if (G.cwd == bb_msg_unknown)
2176                         G.cwd = NULL;
2177                 G.cwd = xrealloc_getcwd_or_warn((char *)G.cwd);
2178                 if (!G.cwd)
2179                         G.cwd = bb_msg_unknown;
2180         }
2181         return G.cwd;
2182 }
2183
2184
2185 /*
2186  * Shell and environment variable support
2187  */
2188 static struct variable **get_ptr_to_local_var(const char *name, unsigned len)
2189 {
2190         struct variable **pp;
2191         struct variable *cur;
2192
2193         pp = &G.top_var;
2194         while ((cur = *pp) != NULL) {
2195                 if (strncmp(cur->varstr, name, len) == 0 && cur->varstr[len] == '=')
2196                         return pp;
2197                 pp = &cur->next;
2198         }
2199         return NULL;
2200 }
2201
2202 static const char* FAST_FUNC get_local_var_value(const char *name)
2203 {
2204         struct variable **vpp;
2205         unsigned len = strlen(name);
2206
2207         if (G.expanded_assignments) {
2208                 char **cpp = G.expanded_assignments;
2209                 while (*cpp) {
2210                         char *cp = *cpp;
2211                         if (strncmp(cp, name, len) == 0 && cp[len] == '=')
2212                                 return cp + len + 1;
2213                         cpp++;
2214                 }
2215         }
2216
2217         vpp = get_ptr_to_local_var(name, len);
2218         if (vpp)
2219                 return (*vpp)->varstr + len + 1;
2220
2221         if (strcmp(name, "PPID") == 0)
2222                 return utoa(G.root_ppid);
2223         // bash compat: UID? EUID?
2224 #if ENABLE_HUSH_RANDOM_SUPPORT
2225         if (strcmp(name, "RANDOM") == 0)
2226                 return utoa(next_random(&G.random_gen));
2227 #endif
2228         return NULL;
2229 }
2230
2231 static void handle_changed_special_names(const char *name, unsigned name_len)
2232 {
2233         if (ENABLE_HUSH_INTERACTIVE && ENABLE_FEATURE_EDITING_FANCY_PROMPT
2234          && name_len == 3 && name[0] == 'P' && name[1] == 'S'
2235         ) {
2236                 cmdedit_update_prompt();
2237                 return;
2238         }
2239
2240         if ((ENABLE_HUSH_LINENO_VAR || ENABLE_HUSH_GETOPTS)
2241          && name_len == 6
2242         ) {
2243 #if ENABLE_HUSH_LINENO_VAR
2244                 if (strncmp(name, "LINENO", 6) == 0) {
2245                         G.lineno_var = NULL;
2246                         return;
2247                 }
2248 #endif
2249 #if ENABLE_HUSH_GETOPTS
2250                 if (strncmp(name, "OPTIND", 6) == 0) {
2251                         G.getopt_count = 0;
2252                         return;
2253                 }
2254 #endif
2255         }
2256 }
2257
2258 /* str holds "NAME=VAL" and is expected to be malloced.
2259  * We take ownership of it.
2260  */
2261 #define SETFLAG_EXPORT   (1 << 0)
2262 #define SETFLAG_UNEXPORT (1 << 1)
2263 #define SETFLAG_MAKE_RO  (1 << 2)
2264 #define SETFLAG_VARLVL_SHIFT   3
2265 static int set_local_var(char *str, unsigned flags)
2266 {
2267         struct variable **cur_pp;
2268         struct variable *cur;
2269         char *free_me = NULL;
2270         char *eq_sign;
2271         int name_len;
2272         unsigned local_lvl = (flags >> SETFLAG_VARLVL_SHIFT);
2273
2274         eq_sign = strchr(str, '=');
2275         if (HUSH_DEBUG && !eq_sign)
2276                 bb_error_msg_and_die("BUG in setvar");
2277
2278         name_len = eq_sign - str + 1; /* including '=' */
2279         cur_pp = &G.top_var;
2280         while ((cur = *cur_pp) != NULL) {
2281                 if (strncmp(cur->varstr, str, name_len) != 0) {
2282                         cur_pp = &cur->next;
2283                         continue;
2284                 }
2285
2286                 /* We found an existing var with this name */
2287                 if (cur->flg_read_only) {
2288                         bb_error_msg("%s: readonly variable", str);
2289                         free(str);
2290 //NOTE: in bash, assignment in "export READONLY_VAR=Z" fails, and sets $?=1,
2291 //but export per se succeeds (does put the var in env). We don't mimic that.
2292                         return -1;
2293                 }
2294                 if (flags & SETFLAG_UNEXPORT) { // && cur->flg_export ?
2295                         debug_printf_env("%s: unsetenv '%s'\n", __func__, str);
2296                         *eq_sign = '\0';
2297                         unsetenv(str);
2298                         *eq_sign = '=';
2299                 }
2300                 if (cur->var_nest_level < local_lvl) {
2301                         /* bash 3.2.33(1) and exported vars:
2302                          * # export z=z
2303                          * # f() { local z=a; env | grep ^z; }
2304                          * # f
2305                          * z=a
2306                          * # env | grep ^z
2307                          * z=z
2308                          */
2309                         if (cur->flg_export)
2310                                 flags |= SETFLAG_EXPORT;
2311                         /* New variable is local ("local VAR=VAL" or
2312                          * "VAR=VAL cmd")
2313                          * and existing one is global, or local
2314                          * on a lower level that new one.
2315                          * Remove it from global variable list:
2316                          */
2317                         *cur_pp = cur->next;
2318                         if (G.shadowed_vars_pp) {
2319                                 /* Save in "shadowed" list */
2320                                 debug_printf_env("shadowing %s'%s'/%u by '%s'/%u\n",
2321                                         cur->flg_export ? "exported " : "",
2322                                         cur->varstr, cur->var_nest_level, str, local_lvl
2323                                 );
2324                                 cur->next = *G.shadowed_vars_pp;
2325                                 *G.shadowed_vars_pp = cur;
2326                         } else {
2327                                 /* Came from pseudo_exec_argv(), no need to save: delete it */
2328                                 debug_printf_env("shadow-deleting %s'%s'/%u by '%s'/%u\n",
2329                                         cur->flg_export ? "exported " : "",
2330                                         cur->varstr, cur->var_nest_level, str, local_lvl
2331                                 );
2332                                 if (cur->max_len == 0) /* allocated "VAR=VAL"? */
2333                                         free_me = cur->varstr; /* then free it later */
2334                                 free(cur);
2335                         }
2336                         break;
2337                 }
2338
2339                 if (strcmp(cur->varstr + name_len, eq_sign + 1) == 0) {
2340                         debug_printf_env("assignement '%s' does not change anything\n", str);
2341  free_and_exp:
2342                         free(str);
2343                         goto exp;
2344                 }
2345
2346                 /* Replace the value in the found "struct variable" */
2347                 if (cur->max_len != 0) {
2348                         if (cur->max_len >= strnlen(str, cur->max_len + 1)) {
2349                                 /* This one is from startup env, reuse space */
2350                                 debug_printf_env("reusing startup env for '%s'\n", str);
2351                                 strcpy(cur->varstr, str);
2352                                 goto free_and_exp;
2353                         }
2354                         /* Can't reuse */
2355                         cur->max_len = 0;
2356                         goto set_str_and_exp;
2357                 }
2358                 /* max_len == 0 signifies "malloced" var, which we can
2359                  * (and have to) free. But we can't free(cur->varstr) here:
2360                  * if cur->flg_export is 1, it is in the environment.
2361                  * We should either unsetenv+free, or wait until putenv,
2362                  * then putenv(new)+free(old).
2363                  */
2364                 free_me = cur->varstr;
2365                 goto set_str_and_exp;
2366         }
2367
2368         /* Not found or shadowed - create new variable struct */
2369         debug_printf_env("%s: alloc new var '%s'/%u\n", __func__, str, local_lvl);
2370         cur = xzalloc(sizeof(*cur));
2371         cur->var_nest_level = local_lvl;
2372         cur->next = *cur_pp;
2373         *cur_pp = cur;
2374
2375  set_str_and_exp:
2376         cur->varstr = str;
2377  exp:
2378 #if !BB_MMU || ENABLE_HUSH_READONLY
2379         if (flags & SETFLAG_MAKE_RO) {
2380                 cur->flg_read_only = 1;
2381         }
2382 #endif
2383         if (flags & SETFLAG_EXPORT)
2384                 cur->flg_export = 1;
2385         if (cur->flg_export) {
2386                 if (flags & SETFLAG_UNEXPORT) {
2387                         cur->flg_export = 0;
2388                         /* unsetenv was already done */
2389                 } else {
2390                         int i;
2391                         debug_printf_env("%s: putenv '%s'/%u\n", __func__, cur->varstr, cur->var_nest_level);
2392                         i = putenv(cur->varstr);
2393                         /* only now we can free old exported malloced string */
2394                         free(free_me);
2395                         return i;
2396                 }
2397         }
2398         free(free_me);
2399
2400         handle_changed_special_names(cur->varstr, name_len - 1);
2401
2402         return 0;
2403 }
2404
2405 static void FAST_FUNC set_local_var_from_halves(const char *name, const char *val)
2406 {
2407         char *var = xasprintf("%s=%s", name, val);
2408         set_local_var(var, /*flag:*/ 0);
2409 }
2410
2411 /* Used at startup and after each cd */
2412 static void set_pwd_var(unsigned flag)
2413 {
2414         set_local_var(xasprintf("PWD=%s", get_cwd(/*force:*/ 1)), flag);
2415 }
2416
2417 #if ENABLE_HUSH_UNSET || ENABLE_HUSH_GETOPTS
2418 static int unset_local_var_len(const char *name, int name_len)
2419 {
2420         struct variable *cur;
2421         struct variable **cur_pp;
2422
2423         cur_pp = &G.top_var;
2424         while ((cur = *cur_pp) != NULL) {
2425                 if (strncmp(cur->varstr, name, name_len) == 0
2426                  && cur->varstr[name_len] == '='
2427                 ) {
2428                         if (cur->flg_read_only) {
2429                                 bb_error_msg("%s: readonly variable", name);
2430                                 return EXIT_FAILURE;
2431                         }
2432
2433                         *cur_pp = cur->next;
2434                         debug_printf_env("%s: unsetenv '%s'\n", __func__, cur->varstr);
2435                         bb_unsetenv(cur->varstr);
2436                         if (!cur->max_len)
2437                                 free(cur->varstr);
2438                         free(cur);
2439
2440                         break;
2441                 }
2442                 cur_pp = &cur->next;
2443         }
2444
2445         /* Handle "unset PS1" et al even if did not find the variable to unset */
2446         handle_changed_special_names(name, name_len);
2447
2448         return EXIT_SUCCESS;
2449 }
2450
2451 static int unset_local_var(const char *name)
2452 {
2453         return unset_local_var_len(name, strlen(name));
2454 }
2455 #endif
2456
2457
2458 /*
2459  * Helpers for "var1=val1 var2=val2 cmd" feature
2460  */
2461 static void add_vars(struct variable *var)
2462 {
2463         struct variable *next;
2464
2465         while (var) {
2466                 next = var->next;
2467                 var->next = G.top_var;
2468                 G.top_var = var;
2469                 if (var->flg_export) {
2470                         debug_printf_env("%s: restoring exported '%s'/%u\n", __func__, var->varstr, var->var_nest_level);
2471                         putenv(var->varstr);
2472                 } else {
2473                         debug_printf_env("%s: restoring variable '%s'/%u\n", __func__, var->varstr, var->var_nest_level);
2474                 }
2475                 var = next;
2476         }
2477 }
2478
2479 /* We put strings[i] into variable table and possibly putenv them.
2480  * If variable is read only, we can free the strings[i]
2481  * which attempts to overwrite it.
2482  * The strings[] vector itself is freed.
2483  */
2484 static void set_vars_and_save_old(char **strings)
2485 {
2486         char **s;
2487
2488         if (!strings)
2489                 return;
2490
2491         s = strings;
2492         while (*s) {
2493                 struct variable *var_p;
2494                 struct variable **var_pp;
2495                 char *eq;
2496
2497                 eq = strchr(*s, '=');
2498                 if (HUSH_DEBUG && !eq)
2499                         bb_error_msg_and_die("BUG in varexp4");
2500                 var_pp = get_ptr_to_local_var(*s, eq - *s);
2501                 if (var_pp) {
2502                         var_p = *var_pp;
2503                         if (var_p->flg_read_only) {
2504                                 char **p;
2505                                 bb_error_msg("%s: readonly variable", *s);
2506                                 /*
2507                                  * "VAR=V BLTIN" unsets VARs after BLTIN completes.
2508                                  * If VAR is readonly, leaving it in the list
2509                                  * after asssignment error (msg above)
2510                                  * causes doubled error message later, on unset.
2511                                  */
2512                                 debug_printf_env("removing/freeing '%s' element\n", *s);
2513                                 free(*s);
2514                                 p = s;
2515                                 do { *p = p[1]; p++; } while (*p);
2516                                 goto next;
2517                         }
2518                         /* below, set_local_var() with nest level will
2519                          * "shadow" (remove) this variable from
2520                          * global linked list.
2521                          */
2522                 }
2523                 debug_printf_env("%s: env override '%s'/%u\n", __func__, *s, G.var_nest_level);
2524                 set_local_var(*s, (G.var_nest_level << SETFLAG_VARLVL_SHIFT) | SETFLAG_EXPORT);
2525                 s++;
2526  next: ;
2527         }
2528         free(strings);
2529 }
2530
2531
2532 /*
2533  * Unicode helper
2534  */
2535 static void reinit_unicode_for_hush(void)
2536 {
2537         /* Unicode support should be activated even if LANG is set
2538          * _during_ shell execution, not only if it was set when
2539          * shell was started. Therefore, re-check LANG every time:
2540          */
2541         if (ENABLE_FEATURE_CHECK_UNICODE_IN_ENV
2542          || ENABLE_UNICODE_USING_LOCALE
2543         ) {
2544                 const char *s = get_local_var_value("LC_ALL");
2545                 if (!s) s = get_local_var_value("LC_CTYPE");
2546                 if (!s) s = get_local_var_value("LANG");
2547                 reinit_unicode(s);
2548         }
2549 }
2550
2551 /*
2552  * in_str support (strings, and "strings" read from files).
2553  */
2554
2555 #if ENABLE_HUSH_INTERACTIVE
2556 /* To test correct lineedit/interactive behavior, type from command line:
2557  *      echo $P\
2558  *      \
2559  *      AT\
2560  *      H\
2561  *      \
2562  * It exercises a lot of corner cases.
2563  */
2564 # if ENABLE_FEATURE_EDITING_FANCY_PROMPT
2565 static void cmdedit_update_prompt(void)
2566 {
2567         G.PS1 = get_local_var_value("PS1");
2568         if (G.PS1 == NULL)
2569                 G.PS1 = "";
2570         G.PS2 = get_local_var_value("PS2");
2571         if (G.PS2 == NULL)
2572                 G.PS2 = "";
2573 }
2574 # endif
2575 static const char *setup_prompt_string(void)
2576 {
2577         const char *prompt_str;
2578
2579         debug_printf_prompt("%s promptmode:%d\n", __func__, G.promptmode);
2580
2581         IF_FEATURE_EDITING_FANCY_PROMPT(    prompt_str = G.PS2;)
2582         IF_NOT_FEATURE_EDITING_FANCY_PROMPT(prompt_str = "> ";)
2583         if (G.promptmode == 0) { /* PS1 */
2584                 if (!ENABLE_FEATURE_EDITING_FANCY_PROMPT) {
2585                         /* No fancy prompts supported, (re)generate "CURDIR $ " by hand */
2586                         free((char*)G.PS1);
2587                         /* bash uses $PWD value, even if it is set by user.
2588                          * It uses current dir only if PWD is unset.
2589                          * We always use current dir. */
2590                         G.PS1 = xasprintf("%s %c ", get_cwd(0), (geteuid() != 0) ? '$' : '#');
2591                 }
2592                 prompt_str = G.PS1;
2593         }
2594         debug_printf("prompt_str '%s'\n", prompt_str);
2595         return prompt_str;
2596 }
2597 static int get_user_input(struct in_str *i)
2598 {
2599         int r;
2600         const char *prompt_str;
2601
2602         prompt_str = setup_prompt_string();
2603 # if ENABLE_FEATURE_EDITING
2604         for (;;) {
2605                 reinit_unicode_for_hush();
2606                 if (G.flag_SIGINT) {
2607                         /* There was ^C'ed, make it look prettier: */
2608                         bb_putchar('\n');
2609                         G.flag_SIGINT = 0;
2610                 }
2611                 /* buglet: SIGINT will not make new prompt to appear _at once_,
2612                  * only after <Enter>. (^C works immediately) */
2613                 r = read_line_input(G.line_input_state, prompt_str,
2614                                 G.user_input_buf, CONFIG_FEATURE_EDITING_MAX_LEN-1
2615                 );
2616                 /* read_line_input intercepts ^C, "convert" it to SIGINT */
2617                 if (r == 0)
2618                         raise(SIGINT);
2619                 check_and_run_traps();
2620                 if (r != 0 && !G.flag_SIGINT)
2621                         break;
2622                 /* ^C or SIGINT: repeat */
2623                 /* bash prints ^C even on real SIGINT (non-kbd generated) */
2624                 write(STDOUT_FILENO, "^C", 2);
2625                 G.last_exitcode = 128 + SIGINT;
2626         }
2627         if (r < 0) {
2628                 /* EOF/error detected */
2629                 i->p = NULL;
2630                 i->peek_buf[0] = r = EOF;
2631                 return r;
2632         }
2633         i->p = G.user_input_buf;
2634         return (unsigned char)*i->p++;
2635 # else
2636         for (;;) {
2637                 G.flag_SIGINT = 0;
2638                 if (i->last_char == '\0' || i->last_char == '\n') {
2639                         /* Why check_and_run_traps here? Try this interactively:
2640                          * $ trap 'echo INT' INT; (sleep 2; kill -INT $$) &
2641                          * $ <[enter], repeatedly...>
2642                          * Without check_and_run_traps, handler never runs.
2643                          */
2644                         check_and_run_traps();
2645                         fputs(prompt_str, stdout);
2646                 }
2647                 fflush_all();
2648 //FIXME: here ^C or SIGINT will have effect only after <Enter>
2649                 r = hfgetc(i->file);
2650                 /* In !ENABLE_FEATURE_EDITING we don't use read_line_input,
2651                  * no ^C masking happens during fgetc, no special code for ^C:
2652                  * it generates SIGINT as usual.
2653                  */
2654                 check_and_run_traps();
2655                 if (G.flag_SIGINT)
2656                         G.last_exitcode = 128 + SIGINT;
2657                 if (r != '\0')
2658                         break;
2659         }
2660         return r;
2661 # endif
2662 }
2663 /* This is the magic location that prints prompts
2664  * and gets data back from the user */
2665 static int fgetc_interactive(struct in_str *i)
2666 {
2667         int ch;
2668         /* If it's interactive stdin, get new line. */
2669         if (G_interactive_fd && i->file->is_stdin) {
2670                 /* Returns first char (or EOF), the rest is in i->p[] */
2671                 ch = get_user_input(i);
2672                 G.promptmode = 1; /* PS2 */
2673                 debug_printf_prompt("%s promptmode=%d\n", __func__, G.promptmode);
2674         } else {
2675                 /* Not stdin: script file, sourced file, etc */
2676                 do ch = hfgetc(i->file); while (ch == '\0');
2677         }
2678         return ch;
2679 }
2680 #else
2681 static ALWAYS_INLINE int fgetc_interactive(struct in_str *i)
2682 {
2683         int ch;
2684         do ch = hfgetc(i->file); while (ch == '\0');
2685         return ch;
2686 }
2687 #endif  /* INTERACTIVE */
2688
2689 static int i_getch(struct in_str *i)
2690 {
2691         int ch;
2692
2693         if (!i->file) {
2694                 /* string-based in_str */
2695                 ch = (unsigned char)*i->p;
2696                 if (ch != '\0') {
2697                         i->p++;
2698                         i->last_char = ch;
2699                         return ch;
2700                 }
2701                 return EOF;
2702         }
2703
2704         /* FILE-based in_str */
2705
2706 #if ENABLE_FEATURE_EDITING
2707         /* This can be stdin, check line editing char[] buffer */
2708         if (i->p && *i->p != '\0') {
2709                 ch = (unsigned char)*i->p++;
2710                 goto out;
2711         }
2712 #endif
2713         /* peek_buf[] is an int array, not char. Can contain EOF. */
2714         ch = i->peek_buf[0];
2715         if (ch != 0) {
2716                 int ch2 = i->peek_buf[1];
2717                 i->peek_buf[0] = ch2;
2718                 if (ch2 == 0) /* very likely, avoid redundant write */
2719                         goto out;
2720                 i->peek_buf[1] = 0;
2721                 goto out;
2722         }
2723
2724         ch = fgetc_interactive(i);
2725  out:
2726         debug_printf("file_get: got '%c' %d\n", ch, ch);
2727         i->last_char = ch;
2728 #if ENABLE_HUSH_LINENO_VAR
2729         if (ch == '\n') {
2730                 G.lineno++;
2731                 debug_printf_parse("G.lineno++ = %u\n", G.lineno);
2732         }
2733 #endif
2734         return ch;
2735 }
2736
2737 static int i_peek(struct in_str *i)
2738 {
2739         int ch;
2740
2741         if (!i->file) {
2742                 /* string-based in_str */
2743                 /* Doesn't report EOF on NUL. None of the callers care. */
2744                 return (unsigned char)*i->p;
2745         }
2746
2747         /* FILE-based in_str */
2748
2749 #if ENABLE_FEATURE_EDITING && ENABLE_HUSH_INTERACTIVE
2750         /* This can be stdin, check line editing char[] buffer */
2751         if (i->p && *i->p != '\0')
2752                 return (unsigned char)*i->p;
2753 #endif
2754         /* peek_buf[] is an int array, not char. Can contain EOF. */
2755         ch = i->peek_buf[0];
2756         if (ch != 0)
2757                 return ch;
2758
2759         /* Need to get a new char */
2760         ch = fgetc_interactive(i);
2761         debug_printf("file_peek: got '%c' %d\n", ch, ch);
2762
2763         /* Save it by either rolling back line editing buffer, or in i->peek_buf[0] */
2764 #if ENABLE_FEATURE_EDITING && ENABLE_HUSH_INTERACTIVE
2765         if (i->p) {
2766                 i->p -= 1;
2767                 return ch;
2768         }
2769 #endif
2770         i->peek_buf[0] = ch;
2771         /*i->peek_buf[1] = 0; - already is */
2772         return ch;
2773 }
2774
2775 /* Only ever called if i_peek() was called, and did not return EOF.
2776  * IOW: we know the previous peek saw an ordinary char, not EOF, not NUL,
2777  * not end-of-line. Therefore we never need to read a new editing line here.
2778  */
2779 static int i_peek2(struct in_str *i)
2780 {
2781         int ch;
2782
2783         /* There are two cases when i->p[] buffer exists.
2784          * (1) it's a string in_str.
2785          * (2) It's a file, and we have a saved line editing buffer.
2786          * In both cases, we know that i->p[0] exists and not NUL, and
2787          * the peek2 result is in i->p[1].
2788          */
2789         if (i->p)
2790                 return (unsigned char)i->p[1];
2791
2792         /* Now we know it is a file-based in_str. */
2793
2794         /* peek_buf[] is an int array, not char. Can contain EOF. */
2795         /* Is there 2nd char? */
2796         ch = i->peek_buf[1];
2797         if (ch == 0) {
2798                 /* We did not read it yet, get it now */
2799                 do ch = hfgetc(i->file); while (ch == '\0');
2800                 i->peek_buf[1] = ch;
2801         }
2802
2803         debug_printf("file_peek2: got '%c' %d\n", ch, ch);
2804         return ch;
2805 }
2806
2807 static int i_getch_and_eat_bkslash_nl(struct in_str *input)
2808 {
2809         for (;;) {
2810                 int ch, ch2;
2811
2812                 ch = i_getch(input);
2813                 if (ch != '\\')
2814                         return ch;
2815                 ch2 = i_peek(input);
2816                 if (ch2 != '\n')
2817                         return ch;
2818                 /* backslash+newline, skip it */
2819                 i_getch(input);
2820         }
2821 }
2822
2823 /* Note: this function _eats_ \<newline> pairs, safe to use plain
2824  * i_getch() after it instead of i_getch_and_eat_bkslash_nl().
2825  */
2826 static int i_peek_and_eat_bkslash_nl(struct in_str *input)
2827 {
2828         for (;;) {
2829                 int ch, ch2;
2830
2831                 ch = i_peek(input);
2832                 if (ch != '\\')
2833                         return ch;
2834                 ch2 = i_peek2(input);
2835                 if (ch2 != '\n')
2836                         return ch;
2837                 /* backslash+newline, skip it */
2838                 i_getch(input);
2839                 i_getch(input);
2840         }
2841 }
2842
2843 static void setup_file_in_str(struct in_str *i, HFILE *fp)
2844 {
2845         memset(i, 0, sizeof(*i));
2846         i->file = fp;
2847         /* i->p = NULL; */
2848 }
2849
2850 static void setup_string_in_str(struct in_str *i, const char *s)
2851 {
2852         memset(i, 0, sizeof(*i));
2853         /*i->file = NULL */;
2854         i->p = s;
2855 }
2856
2857
2858 /*
2859  * o_string support
2860  */
2861 #define B_CHUNK  (32 * sizeof(char*))
2862
2863 static void o_reset_to_empty_unquoted(o_string *o)
2864 {
2865         o->length = 0;
2866         o->has_quoted_part = 0;
2867         if (o->data)
2868                 o->data[0] = '\0';
2869 }
2870
2871 static void o_free_and_set_NULL(o_string *o)
2872 {
2873         free(o->data);
2874         memset(o, 0, sizeof(*o));
2875 }
2876
2877 static ALWAYS_INLINE void o_free(o_string *o)
2878 {
2879         free(o->data);
2880 }
2881
2882 static void o_grow_by(o_string *o, int len)
2883 {
2884         if (o->length + len > o->maxlen) {
2885                 o->maxlen += (2 * len) | (B_CHUNK-1);
2886                 o->data = xrealloc(o->data, 1 + o->maxlen);
2887         }
2888 }
2889
2890 static void o_addchr(o_string *o, int ch)
2891 {
2892         debug_printf("o_addchr: '%c' o->length=%d o=%p\n", ch, o->length, o);
2893         if (o->length < o->maxlen) {
2894                 /* likely. avoid o_grow_by() call */
2895  add:
2896                 o->data[o->length] = ch;
2897                 o->length++;
2898                 o->data[o->length] = '\0';
2899                 return;
2900         }
2901         o_grow_by(o, 1);
2902         goto add;
2903 }
2904
2905 #if 0
2906 /* Valid only if we know o_string is not empty */
2907 static void o_delchr(o_string *o)
2908 {
2909         o->length--;
2910         o->data[o->length] = '\0';
2911 }
2912 #endif
2913
2914 static void o_addblock(o_string *o, const char *str, int len)
2915 {
2916         o_grow_by(o, len);
2917         ((char*)mempcpy(&o->data[o->length], str, len))[0] = '\0';
2918         o->length += len;
2919 }
2920
2921 static void o_addstr(o_string *o, const char *str)
2922 {
2923         o_addblock(o, str, strlen(str));
2924 }
2925
2926 static void o_addstr_with_NUL(o_string *o, const char *str)
2927 {
2928         o_addblock(o, str, strlen(str) + 1);
2929 }
2930
2931 #if !BB_MMU
2932 static void nommu_addchr(o_string *o, int ch)
2933 {
2934         if (o)
2935                 o_addchr(o, ch);
2936 }
2937 #else
2938 # define nommu_addchr(o, str) ((void)0)
2939 #endif
2940
2941 #if ENABLE_HUSH_MODE_X
2942 static void x_mode_addchr(int ch)
2943 {
2944         o_addchr(&G.x_mode_buf, ch);
2945 }
2946 static void x_mode_addstr(const char *str)
2947 {
2948         o_addstr(&G.x_mode_buf, str);
2949 }
2950 static void x_mode_addblock(const char *str, int len)
2951 {
2952         o_addblock(&G.x_mode_buf, str, len);
2953 }
2954 static void x_mode_prefix(void)
2955 {
2956         int n = G.x_mode_depth;
2957         do x_mode_addchr('+'); while (--n >= 0);
2958 }
2959 static void x_mode_flush(void)
2960 {
2961         int len = G.x_mode_buf.length;
2962         if (len <= 0)
2963                 return;
2964         if (G.x_mode_fd > 0) {
2965                 G.x_mode_buf.data[len] = '\n';
2966                 full_write(G.x_mode_fd, G.x_mode_buf.data, len + 1);
2967         }
2968         G.x_mode_buf.length = 0;
2969 }
2970 #endif
2971
2972 /*
2973  * HUSH_BRACE_EXPANSION code needs corresponding quoting on variable expansion side.
2974  * Currently, "v='{q,w}'; echo $v" erroneously expands braces in $v.
2975  * Apparently, on unquoted $v bash still does globbing
2976  * ("v='*.txt'; echo $v" prints all .txt files),
2977  * but NOT brace expansion! Thus, there should be TWO independent
2978  * quoting mechanisms on $v expansion side: one protects
2979  * $v from brace expansion, and other additionally protects "$v" against globbing.
2980  * We have only second one.
2981  */
2982
2983 #if ENABLE_HUSH_BRACE_EXPANSION
2984 # define MAYBE_BRACES "{}"
2985 #else
2986 # define MAYBE_BRACES ""
2987 #endif
2988
2989 /* My analysis of quoting semantics tells me that state information
2990  * is associated with a destination, not a source.
2991  */
2992 static void o_addqchr(o_string *o, int ch)
2993 {
2994         int sz = 1;
2995         char *found = strchr("*?[\\" MAYBE_BRACES, ch);
2996         if (found)
2997                 sz++;
2998         o_grow_by(o, sz);
2999         if (found) {
3000                 o->data[o->length] = '\\';
3001                 o->length++;
3002         }
3003         o->data[o->length] = ch;
3004         o->length++;
3005         o->data[o->length] = '\0';
3006 }
3007
3008 static void o_addQchr(o_string *o, int ch)
3009 {
3010         int sz = 1;
3011         if ((o->o_expflags & EXP_FLAG_ESC_GLOB_CHARS)
3012          && strchr("*?[\\" MAYBE_BRACES, ch)
3013         ) {
3014                 sz++;
3015                 o->data[o->length] = '\\';
3016                 o->length++;
3017         }
3018         o_grow_by(o, sz);
3019         o->data[o->length] = ch;
3020         o->length++;
3021         o->data[o->length] = '\0';
3022 }
3023
3024 static void o_addqblock(o_string *o, const char *str, int len)
3025 {
3026         while (len) {
3027                 char ch;
3028                 int sz;
3029                 int ordinary_cnt = strcspn(str, "*?[\\" MAYBE_BRACES);
3030                 if (ordinary_cnt > len) /* paranoia */
3031                         ordinary_cnt = len;
3032                 o_addblock(o, str, ordinary_cnt);
3033                 if (ordinary_cnt == len)
3034                         return; /* NUL is already added by o_addblock */
3035                 str += ordinary_cnt;
3036                 len -= ordinary_cnt + 1; /* we are processing + 1 char below */
3037
3038                 ch = *str++;
3039                 sz = 1;
3040                 if (ch) { /* it is necessarily one of "*?[\\" MAYBE_BRACES */
3041                         sz++;
3042                         o->data[o->length] = '\\';
3043                         o->length++;
3044                 }
3045                 o_grow_by(o, sz);
3046                 o->data[o->length] = ch;
3047                 o->length++;
3048         }
3049         o->data[o->length] = '\0';
3050 }
3051
3052 static void o_addQblock(o_string *o, const char *str, int len)
3053 {
3054         if (!(o->o_expflags & EXP_FLAG_ESC_GLOB_CHARS)) {
3055                 o_addblock(o, str, len);
3056                 return;
3057         }
3058         o_addqblock(o, str, len);
3059 }
3060
3061 static void o_addQstr(o_string *o, const char *str)
3062 {
3063         o_addQblock(o, str, strlen(str));
3064 }
3065
3066 /* A special kind of o_string for $VAR and `cmd` expansion.
3067  * It contains char* list[] at the beginning, which is grown in 16 element
3068  * increments. Actual string data starts at the next multiple of 16 * (char*).
3069  * list[i] contains an INDEX (int!) into this string data.
3070  * It means that if list[] needs to grow, data needs to be moved higher up
3071  * but list[i]'s need not be modified.
3072  * NB: remembering how many list[i]'s you have there is crucial.
3073  * o_finalize_list() operation post-processes this structure - calculates
3074  * and stores actual char* ptrs in list[]. Oh, it NULL terminates it as well.
3075  */
3076 #if DEBUG_EXPAND || DEBUG_GLOB
3077 static void debug_print_list(const char *prefix, o_string *o, int n)
3078 {
3079         char **list = (char**)o->data;
3080         int string_start = ((n + 0xf) & ~0xf) * sizeof(list[0]);
3081         int i = 0;
3082
3083         indent();
3084         fdprintf(2, "%s: list:%p n:%d string_start:%d length:%d maxlen:%d glob:%d quoted:%d escape:%d\n",
3085                         prefix, list, n, string_start, o->length, o->maxlen,
3086                         !!(o->o_expflags & EXP_FLAG_GLOB),
3087                         o->has_quoted_part,
3088                         !!(o->o_expflags & EXP_FLAG_ESC_GLOB_CHARS));
3089         while (i < n) {
3090                 indent();
3091                 fdprintf(2, " list[%d]=%d '%s' %p\n", i, (int)(uintptr_t)list[i],
3092                                 o->data + (int)(uintptr_t)list[i] + string_start,
3093                                 o->data + (int)(uintptr_t)list[i] + string_start);
3094                 i++;
3095         }
3096         if (n) {
3097                 const char *p = o->data + (int)(uintptr_t)list[n - 1] + string_start;
3098                 indent();
3099                 fdprintf(2, " total_sz:%ld\n", (long)((p + strlen(p) + 1) - o->data));
3100         }
3101 }
3102 #else
3103 # define debug_print_list(prefix, o, n) ((void)0)
3104 #endif
3105
3106 /* n = o_save_ptr_helper(str, n) "starts new string" by storing an index value
3107  * in list[n] so that it points past last stored byte so far.
3108  * It returns n+1. */
3109 static int o_save_ptr_helper(o_string *o, int n)
3110 {
3111         char **list = (char**)o->data;
3112         int string_start;
3113         int string_len;
3114
3115         if (!o->has_empty_slot) {
3116                 string_start = ((n + 0xf) & ~0xf) * sizeof(list[0]);
3117                 string_len = o->length - string_start;
3118                 if (!(n & 0xf)) { /* 0, 0x10, 0x20...? */
3119                         debug_printf_list("list[%d]=%d string_start=%d (growing)\n", n, string_len, string_start);
3120                         /* list[n] points to string_start, make space for 16 more pointers */
3121                         o->maxlen += 0x10 * sizeof(list[0]);
3122                         o->data = xrealloc(o->data, o->maxlen + 1);
3123                         list = (char**)o->data;
3124                         memmove(list + n + 0x10, list + n, string_len);
3125                         /*
3126                          * expand_on_ifs() has a "previous argv[] ends in IFS?"
3127                          * check. (grep for -prev-ifs-check-).
3128                          * Ensure that argv[-1][last] is not garbage
3129                          * but zero bytes, to save index check there.
3130                          */
3131                         list[n + 0x10 - 1] = 0;
3132                         o->length += 0x10 * sizeof(list[0]);
3133                 } else {
3134                         debug_printf_list("list[%d]=%d string_start=%d\n",
3135                                         n, string_len, string_start);
3136                 }
3137         } else {
3138                 /* We have empty slot at list[n], reuse without growth */
3139                 string_start = ((n+1 + 0xf) & ~0xf) * sizeof(list[0]); /* NB: n+1! */
3140                 string_len = o->length - string_start;
3141                 debug_printf_list("list[%d]=%d string_start=%d (empty slot)\n",
3142                                 n, string_len, string_start);
3143                 o->has_empty_slot = 0;
3144         }
3145         o->has_quoted_part = 0;
3146         list[n] = (char*)(uintptr_t)string_len;
3147         return n + 1;
3148 }
3149
3150 /* "What was our last o_save_ptr'ed position (byte offset relative o->data)?" */
3151 static int o_get_last_ptr(o_string *o, int n)
3152 {
3153         char **list = (char**)o->data;
3154         int string_start = ((n + 0xf) & ~0xf) * sizeof(list[0]);
3155
3156         return ((int)(uintptr_t)list[n-1]) + string_start;
3157 }
3158
3159 /*
3160  * Globbing routines.
3161  *
3162  * Most words in commands need to be globbed, even ones which are
3163  * (single or double) quoted. This stems from the possiblity of
3164  * constructs like "abc"* and 'abc'* - these should be globbed.
3165  * Having a different code path for fully-quoted strings ("abc",
3166  * 'abc') would only help performance-wise, but we still need
3167  * code for partially-quoted strings.
3168  *
3169  * Unfortunately, if we want to match bash and ash behavior in all cases,
3170  * the logic can't be "shell-syntax argument is first transformed
3171  * to a string, then globbed, and if globbing does not match anything,
3172  * it is used verbatim". Here are two examples where it fails:
3173  *
3174  *      echo 'b\*'?
3175  *
3176  * The globbing can't be avoided (because of '?' at the end).
3177  * The glob pattern is: b\\\*? - IOW, both \ and * are literals
3178  * and are glob-escaped. If this does not match, bash/ash print b\*?
3179  * - IOW: they "unbackslash" the glob pattern.
3180  * Now, look at this:
3181  *
3182  *      v='\\\*'; echo b$v?
3183  *
3184  * The glob pattern is the same here: b\\\*? - the unquoted $v expansion
3185  * should be used as glob pattern with no changes. However, if glob
3186  * does not match, bash/ash print b\\\*? - NOT THE SAME as first example!
3187  *
3188  * ash implements this by having an encoded representation of the word
3189  * to glob, which IS NOT THE SAME as the glob pattern - it has more data.
3190  * Glob pattern is derived from it. If glob fails, the decision what result
3191  * should be is made using that encoded representation. Not glob pattern.
3192  */
3193
3194 #if ENABLE_HUSH_BRACE_EXPANSION
3195 /* There in a GNU extension, GLOB_BRACE, but it is not usable:
3196  * first, it processes even {a} (no commas), second,
3197  * I didn't manage to make it return strings when they don't match
3198  * existing files. Need to re-implement it.
3199  */
3200
3201 /* Helper */
3202 static int glob_needed(const char *s)
3203 {
3204         while (*s) {
3205                 if (*s == '\\') {
3206                         if (!s[1])
3207                                 return 0;
3208                         s += 2;
3209                         continue;
3210                 }
3211                 if (*s == '*' || *s == '[' || *s == '?' || *s == '{')
3212                         return 1;
3213                 s++;
3214         }
3215         return 0;
3216 }
3217 /* Return pointer to next closing brace or to comma */
3218 static const char *next_brace_sub(const char *cp)
3219 {
3220         unsigned depth = 0;
3221         cp++;
3222         while (*cp != '\0') {
3223                 if (*cp == '\\') {
3224                         if (*++cp == '\0')
3225                                 break;
3226                         cp++;
3227                         continue;
3228                 }
3229                 if ((*cp == '}' && depth-- == 0) || (*cp == ',' && depth == 0))
3230                         break;
3231                 if (*cp++ == '{')
3232                         depth++;
3233         }
3234
3235         return *cp != '\0' ? cp : NULL;
3236 }
3237 /* Recursive brace globber. Note: may garble pattern[]. */
3238 static int glob_brace(char *pattern, o_string *o, int n)
3239 {
3240         char *new_pattern_buf;
3241         const char *begin;
3242         const char *next;
3243         const char *rest;
3244         const char *p;
3245         size_t rest_len;
3246
3247         debug_printf_glob("glob_brace('%s')\n", pattern);
3248
3249         begin = pattern;
3250         while (1) {
3251                 if (*begin == '\0')
3252                         goto simple_glob;
3253                 if (*begin == '{') {
3254                         /* Find the first sub-pattern and at the same time
3255                          * find the rest after the closing brace */
3256                         next = next_brace_sub(begin);
3257                         if (next == NULL) {
3258                                 /* An illegal expression */
3259                                 goto simple_glob;
3260                         }
3261                         if (*next == '}') {
3262                                 /* "{abc}" with no commas - illegal
3263                                  * brace expr, disregard and skip it */
3264                                 begin = next + 1;
3265                                 continue;
3266                         }
3267                         break;
3268                 }
3269                 if (*begin == '\\' && begin[1] != '\0')
3270                         begin++;
3271                 begin++;
3272         }
3273         debug_printf_glob("begin:%s\n", begin);
3274         debug_printf_glob("next:%s\n", next);
3275
3276         /* Now find the end of the whole brace expression */
3277         rest = next;
3278         while (*rest != '}') {
3279                 rest = next_brace_sub(rest);
3280                 if (rest == NULL) {
3281                         /* An illegal expression */
3282                         goto simple_glob;
3283                 }
3284                 debug_printf_glob("rest:%s\n", rest);
3285         }
3286         rest_len = strlen(++rest) + 1;
3287
3288         /* We are sure the brace expression is well-formed */
3289
3290         /* Allocate working buffer large enough for our work */
3291         new_pattern_buf = xmalloc(strlen(pattern));
3292
3293         /* We have a brace expression.  BEGIN points to the opening {,
3294          * NEXT points past the terminator of the first element, and REST
3295          * points past the final }.  We will accumulate result names from
3296          * recursive runs for each brace alternative in the buffer using
3297          * GLOB_APPEND.  */
3298
3299         p = begin + 1;
3300         while (1) {
3301                 /* Construct the new glob expression */
3302                 memcpy(
3303                         mempcpy(
3304                                 mempcpy(new_pattern_buf,
3305                                         /* We know the prefix for all sub-patterns */
3306                                         pattern, begin - pattern),
3307                                 p, next - p),
3308                         rest, rest_len);
3309
3310                 /* Note: glob_brace() may garble new_pattern_buf[].
3311                  * That's why we re-copy prefix every time (1st memcpy above).
3312                  */
3313                 n = glob_brace(new_pattern_buf, o, n);
3314                 if (*next == '}') {
3315                         /* We saw the last entry */
3316                         break;
3317                 }
3318                 p = next + 1;
3319                 next = next_brace_sub(next);
3320         }
3321         free(new_pattern_buf);
3322         return n;
3323
3324  simple_glob:
3325         {
3326                 int gr;
3327                 glob_t globdata;
3328
3329                 memset(&globdata, 0, sizeof(globdata));
3330                 gr = glob(pattern, 0, NULL, &globdata);
3331                 debug_printf_glob("glob('%s'):%d\n", pattern, gr);
3332                 if (gr != 0) {
3333                         if (gr == GLOB_NOMATCH) {
3334                                 globfree(&globdata);
3335                                 /* NB: garbles parameter */
3336                                 unbackslash(pattern);
3337                                 o_addstr_with_NUL(o, pattern);
3338                                 debug_printf_glob("glob pattern '%s' is literal\n", pattern);
3339                                 return o_save_ptr_helper(o, n);
3340                         }
3341                         if (gr == GLOB_NOSPACE)
3342                                 bb_die_memory_exhausted();
3343                         /* GLOB_ABORTED? Only happens with GLOB_ERR flag,
3344                          * but we didn't specify it. Paranoia again. */
3345                         bb_error_msg_and_die("glob error %d on '%s'", gr, pattern);
3346                 }
3347                 if (globdata.gl_pathv && globdata.gl_pathv[0]) {
3348                         char **argv = globdata.gl_pathv;
3349                         while (1) {
3350                                 o_addstr_with_NUL(o, *argv);
3351                                 n = o_save_ptr_helper(o, n);
3352                                 argv++;
3353                                 if (!*argv)
3354                                         break;
3355                         }
3356                 }
3357                 globfree(&globdata);
3358         }
3359         return n;
3360 }
3361 /* Performs globbing on last list[],
3362  * saving each result as a new list[].
3363  */
3364 static int perform_glob(o_string *o, int n)
3365 {
3366         char *pattern, *copy;
3367
3368         debug_printf_glob("start perform_glob: n:%d o->data:%p\n", n, o->data);
3369         if (!o->data)
3370                 return o_save_ptr_helper(o, n);
3371         pattern = o->data + o_get_last_ptr(o, n);
3372         debug_printf_glob("glob pattern '%s'\n", pattern);
3373         if (!glob_needed(pattern)) {
3374                 /* unbackslash last string in o in place, fix length */
3375                 o->length = unbackslash(pattern) - o->data;
3376                 debug_printf_glob("glob pattern '%s' is literal\n", pattern);
3377                 return o_save_ptr_helper(o, n);
3378         }
3379
3380         copy = xstrdup(pattern);
3381         /* "forget" pattern in o */
3382         o->length = pattern - o->data;
3383         n = glob_brace(copy, o, n);
3384         free(copy);
3385         if (DEBUG_GLOB)
3386                 debug_print_list("perform_glob returning", o, n);
3387         return n;
3388 }
3389
3390 #else /* !HUSH_BRACE_EXPANSION */
3391
3392 /* Helper */
3393 static int glob_needed(const char *s)
3394 {
3395         while (*s) {
3396                 if (*s == '\\') {
3397                         if (!s[1])
3398                                 return 0;
3399                         s += 2;
3400                         continue;
3401                 }
3402                 if (*s == '*' || *s == '[' || *s == '?')
3403                         return 1;
3404                 s++;
3405         }
3406         return 0;
3407 }
3408 /* Performs globbing on last list[],
3409  * saving each result as a new list[].
3410  */
3411 static int perform_glob(o_string *o, int n)
3412 {
3413         glob_t globdata;
3414         int gr;
3415         char *pattern;
3416
3417         debug_printf_glob("start perform_glob: n:%d o->data:%p\n", n, o->data);
3418         if (!o->data)
3419                 return o_save_ptr_helper(o, n);
3420         pattern = o->data + o_get_last_ptr(o, n);
3421         debug_printf_glob("glob pattern '%s'\n", pattern);
3422         if (!glob_needed(pattern)) {
3423  literal:
3424                 /* unbackslash last string in o in place, fix length */
3425                 o->length = unbackslash(pattern) - o->data;
3426                 debug_printf_glob("glob pattern '%s' is literal\n", pattern);
3427                 return o_save_ptr_helper(o, n);
3428         }
3429
3430         memset(&globdata, 0, sizeof(globdata));
3431         /* Can't use GLOB_NOCHECK: it does not unescape the string.
3432          * If we glob "*.\*" and don't find anything, we need
3433          * to fall back to using literal "*.*", but GLOB_NOCHECK
3434          * will return "*.\*"!
3435          */
3436         gr = glob(pattern, 0, NULL, &globdata);
3437         debug_printf_glob("glob('%s'):%d\n", pattern, gr);
3438         if (gr != 0) {
3439                 if (gr == GLOB_NOMATCH) {
3440                         globfree(&globdata);
3441                         goto literal;
3442                 }
3443                 if (gr == GLOB_NOSPACE)
3444                         bb_die_memory_exhausted();
3445                 /* GLOB_ABORTED? Only happens with GLOB_ERR flag,
3446                  * but we didn't specify it. Paranoia again. */
3447                 bb_error_msg_and_die("glob error %d on '%s'", gr, pattern);
3448         }
3449         if (globdata.gl_pathv && globdata.gl_pathv[0]) {
3450                 char **argv = globdata.gl_pathv;
3451                 /* "forget" pattern in o */
3452                 o->length = pattern - o->data;
3453                 while (1) {
3454                         o_addstr_with_NUL(o, *argv);
3455                         n = o_save_ptr_helper(o, n);
3456                         argv++;
3457                         if (!*argv)
3458                                 break;
3459                 }
3460         }
3461         globfree(&globdata);
3462         if (DEBUG_GLOB)
3463                 debug_print_list("perform_glob returning", o, n);
3464         return n;
3465 }
3466
3467 #endif /* !HUSH_BRACE_EXPANSION */
3468
3469 /* If o->o_expflags & EXP_FLAG_GLOB, glob the string so far remembered.
3470  * Otherwise, just finish current list[] and start new */
3471 static int o_save_ptr(o_string *o, int n)
3472 {
3473         if (o->o_expflags & EXP_FLAG_GLOB) {
3474                 /* If o->has_empty_slot, list[n] was already globbed
3475                  * (if it was requested back then when it was filled)
3476                  * so don't do that again! */
3477                 if (!o->has_empty_slot)
3478                         return perform_glob(o, n); /* o_save_ptr_helper is inside */
3479         }
3480         return o_save_ptr_helper(o, n);
3481 }
3482
3483 /* "Please convert list[n] to real char* ptrs, and NULL terminate it." */
3484 static char **o_finalize_list(o_string *o, int n)
3485 {
3486         char **list;
3487         int string_start;
3488
3489         if (DEBUG_EXPAND)
3490                 debug_print_list("finalized", o, n);
3491         debug_printf_expand("finalized n:%d\n", n);
3492         list = (char**)o->data;
3493         string_start = ((n + 0xf) & ~0xf) * sizeof(list[0]);
3494         list[--n] = NULL;
3495         while (n) {
3496                 n--;
3497                 list[n] = o->data + (int)(uintptr_t)list[n] + string_start;
3498         }
3499         return list;
3500 }
3501
3502 static void free_pipe_list(struct pipe *pi);
3503
3504 /* Returns pi->next - next pipe in the list */
3505 static struct pipe *free_pipe(struct pipe *pi)
3506 {
3507         struct pipe *next;
3508         int i;
3509
3510         debug_printf_clean("free_pipe (pid %d)\n", getpid());
3511         for (i = 0; i < pi->num_cmds; i++) {
3512                 struct command *command;
3513                 struct redir_struct *r, *rnext;
3514
3515                 command = &pi->cmds[i];
3516                 debug_printf_clean("  command %d:\n", i);
3517                 if (command->argv) {
3518                         if (DEBUG_CLEAN) {
3519                                 int a;
3520                                 char **p;
3521                                 for (a = 0, p = command->argv; *p; a++, p++) {
3522                                         debug_printf_clean("   argv[%d] = %s\n", a, *p);
3523                                 }
3524                         }
3525                         free_strings(command->argv);
3526                         //command->argv = NULL;
3527                 }
3528                 /* not "else if": on syntax error, we may have both! */
3529                 if (command->group) {
3530                         debug_printf_clean("   begin group (cmd_type:%d)\n",
3531                                         command->cmd_type);
3532                         free_pipe_list(command->group);
3533                         debug_printf_clean("   end group\n");
3534                         //command->group = NULL;
3535                 }
3536                 /* else is crucial here.
3537                  * If group != NULL, child_func is meaningless */
3538 #if ENABLE_HUSH_FUNCTIONS
3539                 else if (command->child_func) {
3540                         debug_printf_exec("cmd %p releases child func at %p\n", command, command->child_func);
3541                         command->child_func->parent_cmd = NULL;
3542                 }
3543 #endif
3544 #if !BB_MMU
3545                 free(command->group_as_string);
3546                 //command->group_as_string = NULL;
3547 #endif
3548                 for (r = command->redirects; r; r = rnext) {
3549                         debug_printf_clean("   redirect %d%s",
3550                                         r->rd_fd, redir_table[r->rd_type].descrip);
3551                         /* guard against the case >$FOO, where foo is unset or blank */
3552                         if (r->rd_filename) {
3553                                 debug_printf_clean(" fname:'%s'\n", r->rd_filename);
3554                                 free(r->rd_filename);
3555                                 //r->rd_filename = NULL;
3556                         }
3557                         debug_printf_clean(" rd_dup:%d\n", r->rd_dup);
3558                         rnext = r->next;
3559                         free(r);
3560                 }
3561                 //command->redirects = NULL;
3562         }
3563         free(pi->cmds);   /* children are an array, they get freed all at once */
3564         //pi->cmds = NULL;
3565 #if ENABLE_HUSH_JOB
3566         free(pi->cmdtext);
3567         //pi->cmdtext = NULL;
3568 #endif
3569
3570         next = pi->next;
3571         free(pi);
3572         return next;
3573 }
3574
3575 static void free_pipe_list(struct pipe *pi)
3576 {
3577         while (pi) {
3578 #if HAS_KEYWORDS
3579                 debug_printf_clean("pipe reserved word %d\n", pi->res_word);
3580 #endif
3581                 debug_printf_clean("pipe followup code %d\n", pi->followup);
3582                 pi = free_pipe(pi);
3583         }
3584 }
3585
3586
3587 /*** Parsing routines ***/
3588
3589 #ifndef debug_print_tree
3590 static void debug_print_tree(struct pipe *pi, int lvl)
3591 {
3592         static const char *const PIPE[] = {
3593                 [PIPE_SEQ] = "SEQ",
3594                 [PIPE_AND] = "AND",
3595                 [PIPE_OR ] = "OR" ,
3596                 [PIPE_BG ] = "BG" ,
3597         };
3598         static const char *RES[] = {
3599                 [RES_NONE ] = "NONE" ,
3600 # if ENABLE_HUSH_IF
3601                 [RES_IF   ] = "IF"   ,
3602                 [RES_THEN ] = "THEN" ,
3603                 [RES_ELIF ] = "ELIF" ,
3604                 [RES_ELSE ] = "ELSE" ,
3605                 [RES_FI   ] = "FI"   ,
3606 # endif
3607 # if ENABLE_HUSH_LOOPS
3608                 [RES_FOR  ] = "FOR"  ,
3609                 [RES_WHILE] = "WHILE",
3610                 [RES_UNTIL] = "UNTIL",
3611                 [RES_DO   ] = "DO"   ,
3612                 [RES_DONE ] = "DONE" ,
3613 # endif
3614 # if ENABLE_HUSH_LOOPS || ENABLE_HUSH_CASE
3615                 [RES_IN   ] = "IN"   ,
3616 # endif
3617 # if ENABLE_HUSH_CASE
3618                 [RES_CASE ] = "CASE" ,
3619                 [RES_CASE_IN ] = "CASE_IN" ,
3620                 [RES_MATCH] = "MATCH",
3621                 [RES_CASE_BODY] = "CASE_BODY",
3622                 [RES_ESAC ] = "ESAC" ,
3623 # endif
3624                 [RES_XXXX ] = "XXXX" ,
3625                 [RES_SNTX ] = "SNTX" ,
3626         };
3627         static const char *const CMDTYPE[] = {
3628                 "{}",
3629                 "()",
3630                 "[noglob]",
3631 # if ENABLE_HUSH_FUNCTIONS
3632                 "func()",
3633 # endif
3634         };
3635
3636         int pin, prn;
3637
3638         pin = 0;
3639         while (pi) {
3640                 fdprintf(2, "%*spipe %d %sres_word=%s followup=%d %s\n",
3641                                 lvl*2, "",
3642                                 pin,
3643                                 (IF_HAS_KEYWORDS(pi->pi_inverted ? "! " :) ""),
3644                                 RES[pi->res_word],
3645                                 pi->followup, PIPE[pi->followup]
3646                 );
3647                 prn = 0;
3648                 while (prn < pi->num_cmds) {
3649                         struct command *command = &pi->cmds[prn];
3650                         char **argv = command->argv;
3651
3652                         fdprintf(2, "%*s cmd %d assignment_cnt:%d",
3653                                         lvl*2, "", prn,
3654                                         command->assignment_cnt);
3655 #if ENABLE_HUSH_LINENO_VAR
3656                         fdprintf(2, " LINENO:%u", command->lineno);
3657 #endif
3658                         if (command->group) {
3659                                 fdprintf(2, " group %s: (argv=%p)%s%s\n",
3660                                                 CMDTYPE[command->cmd_type],
3661                                                 argv
3662 # if !BB_MMU
3663                                                 , " group_as_string:", command->group_as_string
3664 # else
3665                                                 , "", ""
3666 # endif
3667                                 );
3668                                 debug_print_tree(command->group, lvl+1);
3669                                 prn++;
3670                                 continue;
3671                         }
3672                         if (argv) while (*argv) {
3673                                 fdprintf(2, " '%s'", *argv);
3674                                 argv++;
3675                         }
3676                         if (command->redirects)
3677                                 fdprintf(2, " {redir}");
3678                         fdprintf(2, "\n");
3679                         prn++;
3680                 }
3681                 pi = pi->next;
3682                 pin++;
3683         }
3684 }
3685 #endif /* debug_print_tree */
3686
3687 static struct pipe *new_pipe(void)
3688 {
3689         struct pipe *pi;
3690         pi = xzalloc(sizeof(struct pipe));
3691         /*pi->res_word = RES_NONE; - RES_NONE is 0 anyway */
3692         return pi;
3693 }
3694
3695 /* Command (member of a pipe) is complete, or we start a new pipe
3696  * if ctx->command is NULL.
3697  * No errors possible here.
3698  */
3699 static int done_command(struct parse_context *ctx)
3700 {
3701         /* The command is really already in the pipe structure, so
3702          * advance the pipe counter and make a new, null command. */
3703         struct pipe *pi = ctx->pipe;
3704         struct command *command = ctx->command;
3705
3706 #if 0   /* Instead we emit error message at run time */
3707         if (ctx->pending_redirect) {
3708                 /* For example, "cmd >" (no filename to redirect to) */
3709                 syntax_error("invalid redirect");
3710                 ctx->pending_redirect = NULL;
3711         }
3712 #endif
3713
3714         if (command) {
3715                 if (IS_NULL_CMD(command)) {
3716                         debug_printf_parse("done_command: skipping null cmd, num_cmds=%d\n", pi->num_cmds);
3717                         goto clear_and_ret;
3718                 }
3719                 pi->num_cmds++;
3720                 debug_printf_parse("done_command: ++num_cmds=%d\n", pi->num_cmds);
3721                 //debug_print_tree(ctx->list_head, 20);
3722         } else {
3723                 debug_printf_parse("done_command: initializing, num_cmds=%d\n", pi->num_cmds);
3724         }
3725
3726         /* Only real trickiness here is that the uncommitted
3727          * command structure is not counted in pi->num_cmds. */
3728         pi->cmds = xrealloc(pi->cmds, sizeof(*pi->cmds) * (pi->num_cmds+1));
3729         ctx->command = command = &pi->cmds[pi->num_cmds];
3730  clear_and_ret:
3731         memset(command, 0, sizeof(*command));
3732 #if ENABLE_HUSH_LINENO_VAR
3733         command->lineno = G.lineno;
3734         debug_printf_parse("command->lineno = G.lineno (%u)\n", G.lineno);
3735 #endif
3736         return pi->num_cmds; /* used only for 0/nonzero check */
3737 }
3738
3739 static void done_pipe(struct parse_context *ctx, pipe_style type)
3740 {
3741         int not_null;
3742
3743         debug_printf_parse("done_pipe entered, followup %d\n", type);
3744         /* Close previous command */
3745         not_null = done_command(ctx);
3746 #if HAS_KEYWORDS
3747         ctx->pipe->pi_inverted = ctx->ctx_inverted;
3748         ctx->ctx_inverted = 0;
3749         ctx->pipe->res_word = ctx->ctx_res_w;
3750 #endif
3751         if (type == PIPE_BG && ctx->list_head != ctx->pipe) {
3752                 /* Necessary since && and || have precedence over &:
3753                  * "cmd1 && cmd2 &" must spawn both cmds, not only cmd2,
3754                  * in a backgrounded subshell.
3755                  */
3756                 struct pipe *pi;
3757                 struct command *command;
3758
3759                 /* Is this actually this construct, all pipes end with && or ||? */
3760                 pi = ctx->list_head;
3761                 while (pi != ctx->pipe) {
3762                         if (pi->followup != PIPE_AND && pi->followup != PIPE_OR)
3763                                 goto no_conv;
3764                         pi = pi->next;
3765                 }
3766
3767                 debug_printf_parse("BG with more than one pipe, converting to { p1 &&...pN; } &\n");
3768                 pi->followup = PIPE_SEQ; /* close pN _not_ with "&"! */
3769                 pi = xzalloc(sizeof(*pi));
3770                 pi->followup = PIPE_BG;
3771                 pi->num_cmds = 1;
3772                 pi->cmds = xzalloc(sizeof(pi->cmds[0]));
3773                 command = &pi->cmds[0];
3774                 if (CMD_NORMAL != 0) /* "if xzalloc didn't do that already" */
3775                         command->cmd_type = CMD_NORMAL;
3776                 command->group = ctx->list_head;
3777 #if !BB_MMU
3778                 command->group_as_string = xstrndup(
3779                             ctx->as_string.data,
3780                             ctx->as_string.length - 1 /* do not copy last char, "&" */
3781                 );
3782 #endif
3783                 /* Replace all pipes in ctx with one newly created */
3784                 ctx->list_head = ctx->pipe = pi;
3785         } else {
3786  no_conv:
3787                 ctx->pipe->followup = type;
3788         }
3789
3790         /* Without this check, even just <enter> on command line generates
3791          * tree of three NOPs (!). Which is harmless but annoying.
3792          * IOW: it is safe to do it unconditionally. */
3793         if (not_null
3794 #if ENABLE_HUSH_IF
3795          || ctx->ctx_res_w == RES_FI
3796 #endif
3797 #if ENABLE_HUSH_LOOPS
3798          || ctx->ctx_res_w == RES_DONE
3799          || ctx->ctx_res_w == RES_FOR
3800          || ctx->ctx_res_w == RES_IN
3801 #endif
3802 #if ENABLE_HUSH_CASE
3803          || ctx->ctx_res_w == RES_ESAC
3804 #endif
3805         ) {
3806                 struct pipe *new_p;
3807                 debug_printf_parse("done_pipe: adding new pipe: "
3808                                 "not_null:%d ctx->ctx_res_w:%d\n",
3809                                 not_null, ctx->ctx_res_w);
3810                 new_p = new_pipe();
3811                 ctx->pipe->next = new_p;
3812                 ctx->pipe = new_p;
3813                 /* RES_THEN, RES_DO etc are "sticky" -
3814                  * they remain set for pipes inside if/while.
3815                  * This is used to control execution.
3816                  * RES_FOR and RES_IN are NOT sticky (needed to support
3817                  * cases where variable or value happens to match a keyword):
3818                  */
3819 #if ENABLE_HUSH_LOOPS
3820                 if (ctx->ctx_res_w == RES_FOR
3821                  || ctx->ctx_res_w == RES_IN)
3822                         ctx->ctx_res_w = RES_NONE;
3823 #endif
3824 #if ENABLE_HUSH_CASE
3825                 if (ctx->ctx_res_w == RES_MATCH)
3826                         ctx->ctx_res_w = RES_CASE_BODY;
3827                 if (ctx->ctx_res_w == RES_CASE)
3828                         ctx->ctx_res_w = RES_CASE_IN;
3829 #endif
3830                 ctx->command = NULL; /* trick done_command below */
3831                 /* Create the memory for command, roughly:
3832                  * ctx->pipe->cmds = new struct command;
3833                  * ctx->command = &ctx->pipe->cmds[0];
3834                  */
3835                 done_command(ctx);
3836                 //debug_print_tree(ctx->list_head, 10);
3837         }
3838         debug_printf_parse("done_pipe return\n");
3839 }
3840
3841 static void initialize_context(struct parse_context *ctx)
3842 {
3843         memset(ctx, 0, sizeof(*ctx));
3844         if (MAYBE_ASSIGNMENT != 0)
3845                 ctx->is_assignment = MAYBE_ASSIGNMENT;
3846         ctx->pipe = ctx->list_head = new_pipe();
3847         /* Create the memory for command, roughly:
3848          * ctx->pipe->cmds = new struct command;
3849          * ctx->command = &ctx->pipe->cmds[0];
3850          */
3851         done_command(ctx);
3852 }
3853
3854 /* If a reserved word is found and processed, parse context is modified
3855  * and 1 is returned.
3856  */
3857 #if HAS_KEYWORDS
3858 struct reserved_combo {
3859         char literal[6];
3860         unsigned char res;
3861         unsigned char assignment_flag;
3862         int flag;
3863 };
3864 enum {
3865         FLAG_END   = (1 << RES_NONE ),
3866 # if ENABLE_HUSH_IF
3867         FLAG_IF    = (1 << RES_IF   ),
3868         FLAG_THEN  = (1 << RES_THEN ),
3869         FLAG_ELIF  = (1 << RES_ELIF ),
3870         FLAG_ELSE  = (1 << RES_ELSE ),
3871         FLAG_FI    = (1 << RES_FI   ),
3872 # endif
3873 # if ENABLE_HUSH_LOOPS
3874         FLAG_FOR   = (1 << RES_FOR  ),
3875         FLAG_WHILE = (1 << RES_WHILE),
3876         FLAG_UNTIL = (1 << RES_UNTIL),
3877         FLAG_DO    = (1 << RES_DO   ),
3878         FLAG_DONE  = (1 << RES_DONE ),
3879         FLAG_IN    = (1 << RES_IN   ),
3880 # endif
3881 # if ENABLE_HUSH_CASE
3882         FLAG_MATCH = (1 << RES_MATCH),
3883         FLAG_ESAC  = (1 << RES_ESAC ),
3884 # endif
3885         FLAG_START = (1 << RES_XXXX ),
3886 };
3887
3888 static const struct reserved_combo* match_reserved_word(o_string *word)
3889 {
3890         /* Mostly a list of accepted follow-up reserved words.
3891          * FLAG_END means we are done with the sequence, and are ready
3892          * to turn the compound list into a command.
3893          * FLAG_START means the word must start a new compound list.
3894          */
3895         static const struct reserved_combo reserved_list[] = {
3896 # if ENABLE_HUSH_IF
3897                 { "!",     RES_NONE,  NOT_ASSIGNMENT  , 0 },
3898                 { "if",    RES_IF,    MAYBE_ASSIGNMENT, FLAG_THEN | FLAG_START },
3899                 { "then",  RES_THEN,  MAYBE_ASSIGNMENT, FLAG_ELIF | FLAG_ELSE | FLAG_FI },
3900                 { "elif",  RES_ELIF,  MAYBE_ASSIGNMENT, FLAG_THEN },
3901                 { "else",  RES_ELSE,  MAYBE_ASSIGNMENT, FLAG_FI   },
3902                 { "fi",    RES_FI,    NOT_ASSIGNMENT  , FLAG_END  },
3903 # endif
3904 # if ENABLE_HUSH_LOOPS
3905                 { "for",   RES_FOR,   NOT_ASSIGNMENT  , FLAG_IN | FLAG_DO | FLAG_START },
3906                 { "while", RES_WHILE, MAYBE_ASSIGNMENT, FLAG_DO | FLAG_START },
3907                 { "until", RES_UNTIL, MAYBE_ASSIGNMENT, FLAG_DO | FLAG_START },
3908                 { "in",    RES_IN,    NOT_ASSIGNMENT  , FLAG_DO   },
3909                 { "do",    RES_DO,    MAYBE_ASSIGNMENT, FLAG_DONE },
3910                 { "done",  RES_DONE,  NOT_ASSIGNMENT  , FLAG_END  },
3911 # endif
3912 # if ENABLE_HUSH_CASE
3913                 { "case",  RES_CASE,  NOT_ASSIGNMENT  , FLAG_MATCH | FLAG_START },
3914                 { "esac",  RES_ESAC,  NOT_ASSIGNMENT  , FLAG_END  },
3915 # endif
3916         };
3917         const struct reserved_combo *r;
3918
3919         for (r = reserved_list; r < reserved_list + ARRAY_SIZE(reserved_list); r++) {
3920                 if (strcmp(word->data, r->literal) == 0)
3921                         return r;
3922         }
3923         return NULL;
3924 }
3925 /* Return NULL: not a keyword, else: keyword
3926  */
3927 static const struct reserved_combo* reserved_word(struct parse_context *ctx)
3928 {
3929 # if ENABLE_HUSH_CASE
3930         static const struct reserved_combo reserved_match = {
3931                 "",        RES_MATCH, NOT_ASSIGNMENT , FLAG_MATCH | FLAG_ESAC
3932         };
3933 # endif
3934         const struct reserved_combo *r;
3935
3936         if (ctx->word.has_quoted_part)
3937                 return 0;
3938         r = match_reserved_word(&ctx->word);
3939         if (!r)
3940                 return r; /* NULL */
3941
3942         debug_printf("found reserved word %s, res %d\n", r->literal, r->res);
3943 # if ENABLE_HUSH_CASE
3944         if (r->res == RES_IN && ctx->ctx_res_w == RES_CASE_IN) {
3945                 /* "case word IN ..." - IN part starts first MATCH part */
3946                 r = &reserved_match;
3947         } else
3948 # endif
3949         if (r->flag == 0) { /* '!' */
3950                 if (ctx->ctx_inverted) { /* bash doesn't accept '! ! true' */
3951                         syntax_error("! ! command");
3952                         ctx->ctx_res_w = RES_SNTX;
3953                 }
3954                 ctx->ctx_inverted = 1;
3955                 return r;
3956         }
3957         if (r->flag & FLAG_START) {
3958                 struct parse_context *old;
3959
3960                 old = xmemdup(ctx, sizeof(*ctx));
3961                 debug_printf_parse("push stack %p\n", old);
3962                 initialize_context(ctx);
3963                 ctx->stack = old;
3964         } else if (/*ctx->ctx_res_w == RES_NONE ||*/ !(ctx->old_flag & (1 << r->res))) {
3965                 syntax_error_at(ctx->word.data);
3966                 ctx->ctx_res_w = RES_SNTX;
3967                 return r;
3968         } else {
3969                 /* "{...} fi" is ok. "{...} if" is not
3970                  * Example:
3971                  * if { echo foo; } then { echo bar; } fi */
3972                 if (ctx->command->group)
3973                         done_pipe(ctx, PIPE_SEQ);
3974         }
3975
3976         ctx->ctx_res_w = r->res;
3977         ctx->old_flag = r->flag;
3978         ctx->is_assignment = r->assignment_flag;
3979         debug_printf_parse("ctx->is_assignment='%s'\n", assignment_flag[ctx->is_assignment]);
3980
3981         if (ctx->old_flag & FLAG_END) {
3982                 struct parse_context *old;
3983
3984                 done_pipe(ctx, PIPE_SEQ);
3985                 debug_printf_parse("pop stack %p\n", ctx->stack);
3986                 old = ctx->stack;
3987                 old->command->group = ctx->list_head;
3988                 old->command->cmd_type = CMD_NORMAL;
3989 # if !BB_MMU
3990                 /* At this point, the compound command's string is in
3991                  * ctx->as_string... except for the leading keyword!
3992                  * Consider this example: "echo a | if true; then echo a; fi"
3993                  * ctx->as_string will contain "true; then echo a; fi",
3994                  * with "if " remaining in old->as_string!
3995                  */
3996                 {
3997                         char *str;
3998                         int len = old->as_string.length;
3999                         /* Concatenate halves */
4000                         o_addstr(&old->as_string, ctx->as_string.data);
4001                         o_free(&ctx->as_string);
4002                         /* Find where leading keyword starts in first half */
4003                         str = old->as_string.data + len;
4004                         if (str > old->as_string.data)
4005                                 str--; /* skip whitespace after keyword */
4006                         while (str > old->as_string.data && isalpha(str[-1]))
4007                                 str--;
4008                         /* Ugh, we're done with this horrid hack */
4009                         old->command->group_as_string = xstrdup(str);
4010                         debug_printf_parse("pop, remembering as:'%s'\n",
4011                                         old->command->group_as_string);
4012                 }
4013 # endif
4014                 *ctx = *old;   /* physical copy */
4015                 free(old);
4016         }
4017         return r;
4018 }
4019 #endif /* HAS_KEYWORDS */
4020
4021 /* Word is complete, look at it and update parsing context.
4022  * Normal return is 0. Syntax errors return 1.
4023  * Note: on return, word is reset, but not o_free'd!
4024  */
4025 static int done_word(struct parse_context *ctx)
4026 {
4027         struct command *command = ctx->command;
4028
4029         debug_printf_parse("done_word entered: '%s' %p\n", ctx->word.data, command);
4030         if (ctx->word.length == 0 && !ctx->word.has_quoted_part) {
4031                 debug_printf_parse("done_word return 0: true null, ignored\n");
4032                 return 0;
4033         }
4034
4035         if (ctx->pending_redirect) {
4036                 /* We do not glob in e.g. >*.tmp case. bash seems to glob here
4037                  * only if run as "bash", not "sh" */
4038                 /* http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html
4039                  * "2.7 Redirection
4040                  * If the redirection operator is "<<" or "<<-", the word
4041                  * that follows the redirection operator shall be
4042                  * subjected to quote removal; it is unspecified whether
4043                  * any of the other expansions occur. For the other
4044                  * redirection operators, the word that follows the
4045                  * redirection operator shall be subjected to tilde
4046                  * expansion, parameter expansion, command substitution,
4047                  * arithmetic expansion, and quote removal.
4048                  * Pathname expansion shall not be performed
4049                  * on the word by a non-interactive shell; an interactive
4050                  * shell may perform it, but shall do so only when
4051                  * the expansion would result in one word."
4052                  */
4053 //bash does not do parameter/command substitution or arithmetic expansion
4054 //for _heredoc_ redirection word: these constructs look for exact eof marker
4055 // as written:
4056 // <<EOF$t
4057 // <<EOF$((1))
4058 // <<EOF`true`  [this case also makes heredoc "quoted", a-la <<"EOF". Probably bash-4.3.43 bug]
4059
4060                 ctx->pending_redirect->rd_filename = xstrdup(ctx->word.data);
4061                 /* Cater for >\file case:
4062                  * >\a creates file a; >\\a, >"\a", >"\\a" create file \a
4063                  * Same with heredocs:
4064                  * for <<\H delim is H; <<\\H, <<"\H", <<"\\H" - \H
4065                  */
4066                 if (ctx->pending_redirect->rd_type == REDIRECT_HEREDOC) {
4067                         unbackslash(ctx->pending_redirect->rd_filename);
4068                         /* Is it <<"HEREDOC"? */
4069                         if (ctx->word.has_quoted_part) {
4070                                 ctx->pending_redirect->rd_dup |= HEREDOC_QUOTED;
4071                         }
4072                 }
4073                 debug_printf_parse("word stored in rd_filename: '%s'\n", ctx->word.data);
4074                 ctx->pending_redirect = NULL;
4075         } else {
4076 #if HAS_KEYWORDS
4077 # if ENABLE_HUSH_CASE
4078                 if (ctx->ctx_dsemicolon
4079                  && strcmp(ctx->word.data, "esac") != 0 /* not "... pattern) cmd;; esac" */
4080                 ) {
4081                         /* already done when ctx_dsemicolon was set to 1: */
4082                         /* ctx->ctx_res_w = RES_MATCH; */
4083                         ctx->ctx_dsemicolon = 0;
4084                 } else
4085 # endif
4086                 if (!command->argv /* if it's the first word... */
4087 # if ENABLE_HUSH_LOOPS
4088                  && ctx->ctx_res_w != RES_FOR /* ...not after FOR or IN */
4089                  && ctx->ctx_res_w != RES_IN
4090 # endif
4091 # if ENABLE_HUSH_CASE
4092                  && ctx->ctx_res_w != RES_CASE
4093 # endif
4094                 ) {
4095                         const struct reserved_combo *reserved;
4096                         reserved = reserved_word(ctx);
4097                         debug_printf_parse("checking for reserved-ness: %d\n", !!reserved);
4098                         if (reserved) {
4099 # if ENABLE_HUSH_LINENO_VAR
4100 /* Case:
4101  * "while ...; do
4102  *      cmd ..."
4103  * If we don't close the pipe _now_, immediately after "do", lineno logic
4104  * sees "cmd" as starting at "do" - i.e., at the previous line.
4105  */
4106                                 if (0
4107                                  IF_HUSH_IF(|| reserved->res == RES_THEN)
4108                                  IF_HUSH_IF(|| reserved->res == RES_ELIF)
4109                                  IF_HUSH_IF(|| reserved->res == RES_ELSE)
4110                                  IF_HUSH_LOOPS(|| reserved->res == RES_DO)
4111                                 ) {
4112                                         done_pipe(ctx, PIPE_SEQ);
4113                                 }
4114 # endif
4115                                 o_reset_to_empty_unquoted(&ctx->word);
4116                                 debug_printf_parse("done_word return %d\n",
4117                                                 (ctx->ctx_res_w == RES_SNTX));
4118                                 return (ctx->ctx_res_w == RES_SNTX);
4119                         }
4120 # if defined(CMD_SINGLEWORD_NOGLOB)
4121                         if (0
4122 #  if BASH_TEST2
4123                          || strcmp(ctx->word.data, "[[") == 0
4124 #  endif
4125                         /* In bash, local/export/readonly are special, args
4126                          * are assignments and therefore expansion of them
4127                          * should be "one-word" expansion:
4128                          *  $ export i=`echo 'a  b'` # one arg: "i=a  b"
4129                          * compare with:
4130                          *  $ ls i=`echo 'a  b'`     # two args: "i=a" and "b"
4131                          *  ls: cannot access i=a: No such file or directory
4132                          *  ls: cannot access b: No such file or directory
4133                          * Note: bash 3.2.33(1) does this only if export word
4134                          * itself is not quoted:
4135                          *  $ export i=`echo 'aaa  bbb'`; echo "$i"
4136                          *  aaa  bbb
4137                          *  $ "export" i=`echo 'aaa  bbb'`; echo "$i"
4138                          *  aaa
4139                          */
4140                          IF_HUSH_LOCAL(   || strcmp(ctx->word.data, "local") == 0)
4141                          IF_HUSH_EXPORT(  || strcmp(ctx->word.data, "export") == 0)
4142                          IF_HUSH_READONLY(|| strcmp(ctx->word.data, "readonly") == 0)
4143                         ) {
4144                                 command->cmd_type = CMD_SINGLEWORD_NOGLOB;
4145                         }
4146                         /* fall through */
4147 # endif
4148                 }
4149 #endif /* HAS_KEYWORDS */
4150
4151                 if (command->group) {
4152                         /* "{ echo foo; } echo bar" - bad */
4153                         syntax_error_at(ctx->word.data);
4154                         debug_printf_parse("done_word return 1: syntax error, "
4155                                         "groups and arglists don't mix\n");
4156                         return 1;
4157                 }
4158
4159                 /* If this word wasn't an assignment, next ones definitely
4160                  * can't be assignments. Even if they look like ones. */
4161                 if (ctx->is_assignment != DEFINITELY_ASSIGNMENT
4162                  && ctx->is_assignment != WORD_IS_KEYWORD
4163                 ) {
4164                         ctx->is_assignment = NOT_ASSIGNMENT;
4165                 } else {
4166                         if (ctx->is_assignment == DEFINITELY_ASSIGNMENT) {
4167                                 command->assignment_cnt++;
4168                                 debug_printf_parse("++assignment_cnt=%d\n", command->assignment_cnt);
4169                         }
4170                         debug_printf_parse("ctx->is_assignment was:'%s'\n", assignment_flag[ctx->is_assignment]);
4171                         ctx->is_assignment = MAYBE_ASSIGNMENT;
4172                 }
4173                 debug_printf_parse("ctx->is_assignment='%s'\n", assignment_flag[ctx->is_assignment]);
4174                 command->argv = add_string_to_strings(command->argv, xstrdup(ctx->word.data));
4175                 debug_print_strings("word appended to argv", command->argv);
4176         }
4177
4178 #if ENABLE_HUSH_LOOPS
4179         if (ctx->ctx_res_w == RES_FOR) {
4180                 if (ctx->word.has_quoted_part
4181                  || !is_well_formed_var_name(command->argv[0], '\0')
4182                 ) {
4183                         /* bash says just "not a valid identifier" */
4184                         syntax_error("not a valid identifier in for");
4185                         return 1;
4186                 }
4187                 /* Force FOR to have just one word (variable name) */
4188                 /* NB: basically, this makes hush see "for v in ..."
4189                  * syntax as if it is "for v; in ...". FOR and IN become
4190                  * two pipe structs in parse tree. */
4191                 done_pipe(ctx, PIPE_SEQ);
4192         }
4193 #endif
4194 #if ENABLE_HUSH_CASE
4195         /* Force CASE to have just one word */
4196         if (ctx->ctx_res_w == RES_CASE) {
4197                 done_pipe(ctx, PIPE_SEQ);
4198         }
4199 #endif
4200
4201         o_reset_to_empty_unquoted(&ctx->word);
4202
4203         debug_printf_parse("done_word return 0\n");
4204         return 0;
4205 }
4206
4207
4208 /* Peek ahead in the input to find out if we have a "&n" construct,
4209  * as in "2>&1", that represents duplicating a file descriptor.
4210  * Return:
4211  * REDIRFD_CLOSE if >&- "close fd" construct is seen,
4212  * REDIRFD_SYNTAX_ERR if syntax error,
4213  * REDIRFD_TO_FILE if no & was seen,
4214  * or the number found.
4215  */
4216 #if BB_MMU
4217 #define parse_redir_right_fd(as_string, input) \
4218         parse_redir_right_fd(input)
4219 #endif
4220 static int parse_redir_right_fd(o_string *as_string, struct in_str *input)
4221 {
4222         int ch, d, ok;
4223
4224         ch = i_peek(input);
4225         if (ch != '&')
4226                 return REDIRFD_TO_FILE;
4227
4228         ch = i_getch(input);  /* get the & */
4229         nommu_addchr(as_string, ch);
4230         ch = i_peek(input);
4231         if (ch == '-') {
4232                 ch = i_getch(input);
4233                 nommu_addchr(as_string, ch);
4234                 return REDIRFD_CLOSE;
4235         }
4236         d = 0;
4237         ok = 0;
4238         while (ch != EOF && isdigit(ch)) {
4239                 d = d*10 + (ch-'0');
4240                 ok = 1;
4241                 ch = i_getch(input);
4242                 nommu_addchr(as_string, ch);
4243                 ch = i_peek(input);
4244         }
4245         if (ok) return d;
4246
4247 //TODO: this is the place to catch ">&file" bashism (redirect both fd 1 and 2)
4248
4249         bb_error_msg("ambiguous redirect");
4250         return REDIRFD_SYNTAX_ERR;
4251 }
4252
4253 /* Return code is 0 normal, 1 if a syntax error is detected
4254  */
4255 static int parse_redirect(struct parse_context *ctx,
4256                 int fd,
4257                 redir_type style,
4258                 struct in_str *input)
4259 {
4260         struct command *command = ctx->command;
4261         struct redir_struct *redir;
4262         struct redir_struct **redirp;
4263         int dup_num;
4264
4265         dup_num = REDIRFD_TO_FILE;
4266         if (style != REDIRECT_HEREDOC) {
4267                 /* Check for a '>&1' type redirect */
4268                 dup_num = parse_redir_right_fd(&ctx->as_string, input);
4269                 if (dup_num == REDIRFD_SYNTAX_ERR)
4270                         return 1;
4271         } else {
4272                 int ch = i_peek_and_eat_bkslash_nl(input);
4273                 dup_num = (ch == '-'); /* HEREDOC_SKIPTABS bit is 1 */
4274                 if (dup_num) { /* <<-... */
4275                         ch = i_getch(input);
4276                         nommu_addchr(&ctx->as_string, ch);
4277                         ch = i_peek(input);
4278                 }
4279         }
4280
4281         if (style == REDIRECT_OVERWRITE && dup_num == REDIRFD_TO_FILE) {
4282                 int ch = i_peek_and_eat_bkslash_nl(input);
4283                 if (ch == '|') {
4284                         /* >|FILE redirect ("clobbering" >).
4285                          * Since we do not support "set -o noclobber" yet,
4286                          * >| and > are the same for now. Just eat |.
4287                          */
4288                         ch = i_getch(input);
4289                         nommu_addchr(&ctx->as_string, ch);
4290                 }
4291         }
4292
4293         /* Create a new redir_struct and append it to the linked list */
4294         redirp = &command->redirects;
4295         while ((redir = *redirp) != NULL) {
4296                 redirp = &(redir->next);
4297         }
4298         *redirp = redir = xzalloc(sizeof(*redir));
4299         /* redir->next = NULL; */
4300         /* redir->rd_filename = NULL; */
4301         redir->rd_type = style;
4302         redir->rd_fd = (fd == -1) ? redir_table[style].default_fd : fd;
4303
4304         debug_printf_parse("redirect type %d %s\n", redir->rd_fd,
4305                                 redir_table[style].descrip);
4306
4307         redir->rd_dup = dup_num;
4308         if (style != REDIRECT_HEREDOC && dup_num != REDIRFD_TO_FILE) {
4309                 /* Erik had a check here that the file descriptor in question
4310                  * is legit; I postpone that to "run time"
4311                  * A "-" representation of "close me" shows up as a -3 here */
4312                 debug_printf_parse("duplicating redirect '%d>&%d'\n",
4313                                 redir->rd_fd, redir->rd_dup);
4314         } else {
4315 #if 0           /* Instead we emit error message at run time */
4316                 if (ctx->pending_redirect) {
4317                         /* For example, "cmd > <file" */
4318                         syntax_error("invalid redirect");
4319                 }
4320 #endif
4321                 /* Set ctx->pending_redirect, so we know what to do at the
4322                  * end of the next parsed word. */
4323                 ctx->pending_redirect = redir;
4324         }
4325         return 0;
4326 }
4327
4328 /* If a redirect is immediately preceded by a number, that number is
4329  * supposed to tell which file descriptor to redirect.  This routine
4330  * looks for such preceding numbers.  In an ideal world this routine
4331  * needs to handle all the following classes of redirects...
4332  *     echo 2>foo     # redirects fd  2 to file "foo", nothing passed to echo
4333  *     echo 49>foo    # redirects fd 49 to file "foo", nothing passed to echo
4334  *     echo -2>foo    # redirects fd  1 to file "foo",    "-2" passed to echo
4335  *     echo 49x>foo   # redirects fd  1 to file "foo",   "49x" passed to echo
4336  *
4337  * http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html
4338  * "2.7 Redirection
4339  * ... If n is quoted, the number shall not be recognized as part of
4340  * the redirection expression. For example:
4341  * echo \2>a
4342  * writes the character 2 into file a"
4343  * We are getting it right by setting ->has_quoted_part on any \<char>
4344  *
4345  * A -1 return means no valid number was found,
4346  * the caller should use the appropriate default for this redirection.
4347  */
4348 static int redirect_opt_num(o_string *o)
4349 {
4350         int num;
4351
4352         if (o->data == NULL)
4353                 return -1;
4354         num = bb_strtou(o->data, NULL, 10);
4355         if (errno || num < 0)
4356                 return -1;
4357         o_reset_to_empty_unquoted(o);
4358         return num;
4359 }
4360
4361 #if BB_MMU
4362 #define fetch_till_str(as_string, input, word, skip_tabs) \
4363         fetch_till_str(input, word, skip_tabs)
4364 #endif
4365 static char *fetch_till_str(o_string *as_string,
4366                 struct in_str *input,
4367                 const char *word,
4368                 int heredoc_flags)
4369 {
4370         o_string heredoc = NULL_O_STRING;
4371         unsigned past_EOL;
4372         int prev = 0; /* not \ */
4373         int ch;
4374
4375         /* Starting with "" is necessary for this case:
4376          * cat <<EOF
4377          *
4378          * xxx
4379          * EOF
4380          */
4381         heredoc.data = xzalloc(1); /* start as "", not as NULL */
4382
4383         goto jump_in;
4384
4385         while (1) {
4386                 ch = i_getch(input);
4387                 if (ch != EOF)
4388                         nommu_addchr(as_string, ch);
4389                 if (ch == '\n' || ch == EOF) {
4390  check_heredoc_end:
4391                         if ((heredoc_flags & HEREDOC_QUOTED) || prev != '\\') {
4392                                 /* End-of-line, and not a line continuation */
4393                                 if (strcmp(heredoc.data + past_EOL, word) == 0) {
4394                                         heredoc.data[past_EOL] = '\0';
4395                                         debug_printf_heredoc("parsed '%s' heredoc '%s'\n", word, heredoc.data);
4396                                         return heredoc.data;
4397                                 }
4398                                 if (ch == '\n') {
4399                                         /* This is a new line.
4400                                          * Remember position and backslash-escaping status.
4401                                          */
4402                                         o_addchr(&heredoc, ch);
4403                                         prev = ch;
4404  jump_in:
4405                                         past_EOL = heredoc.length;
4406                                         /* Get 1st char of next line, possibly skipping leading tabs */
4407                                         do {
4408                                                 ch = i_getch(input);
4409                                                 if (ch != EOF)
4410                                                         nommu_addchr(as_string, ch);
4411                                         } while ((heredoc_flags & HEREDOC_SKIPTABS) && ch == '\t');
4412                                         /* If this immediately ended the line,
4413                                          * go back to end-of-line checks.
4414                                          */
4415                                         if (ch == '\n')
4416                                                 goto check_heredoc_end;
4417                                 }
4418                         } else {
4419                                 /* Backslash-line continuation in an unquoted
4420                                  * heredoc. This does not need special handling
4421                                  * for heredoc body (unquoted heredocs are
4422                                  * expanded on "execution" and that would take
4423                                  * care of this case too), but not the case
4424                                  * of line continuation *in terminator*:
4425                                  *  cat <<EOF
4426                                  *  Ok1
4427                                  *  EO\
4428                                  *  F
4429                                  */
4430                                 heredoc.data[--heredoc.length] = '\0';
4431                                 prev = 0; /* not '\' */
4432                                 continue;
4433                         }
4434                 }
4435                 if (ch == EOF) {
4436                         o_free(&heredoc);
4437                         return NULL; /* error */
4438                 }
4439                 o_addchr(&heredoc, ch);
4440                 nommu_addchr(as_string, ch);
4441                 if (prev == '\\' && ch == '\\')
4442                         /* Correctly handle foo\\<eol> (not a line cont.) */
4443                         prev = 0; /* not '\' */
4444                 else
4445                         prev = ch;
4446         }
4447 }
4448
4449 /* Look at entire parse tree for not-yet-loaded REDIRECT_HEREDOCs
4450  * and load them all. There should be exactly heredoc_cnt of them.
4451  */
4452 #if BB_MMU
4453 #define fetch_heredocs(as_string, pi, heredoc_cnt, input) \
4454         fetch_heredocs(pi, heredoc_cnt, input)
4455 #endif
4456 static int fetch_heredocs(o_string *as_string, struct pipe *pi, int heredoc_cnt, struct in_str *input)
4457 {
4458         while (pi && heredoc_cnt) {
4459                 int i;
4460                 struct command *cmd = pi->cmds;
4461
4462                 debug_printf_heredoc("fetch_heredocs: num_cmds:%d cmd argv0:'%s'\n",
4463                                 pi->num_cmds,
4464                                 cmd->argv ? cmd->argv[0] : "NONE"
4465                 );
4466                 for (i = 0; i < pi->num_cmds; i++) {
4467                         struct redir_struct *redir = cmd->redirects;
4468
4469                         debug_printf_heredoc("fetch_heredocs: %d cmd argv0:'%s'\n",
4470                                         i, cmd->argv ? cmd->argv[0] : "NONE");
4471                         while (redir) {
4472                                 if (redir->rd_type == REDIRECT_HEREDOC) {
4473                                         char *p;
4474
4475                                         redir->rd_type = REDIRECT_HEREDOC2;
4476                                         /* redir->rd_dup is (ab)used to indicate <<- */
4477                                         p = fetch_till_str(as_string, input,
4478                                                         redir->rd_filename, redir->rd_dup);
4479                                         if (!p) {
4480                                                 syntax_error("unexpected EOF in here document");
4481                                                 return -1;
4482                                         }
4483                                         free(redir->rd_filename);
4484                                         redir->rd_filename = p;
4485                                         heredoc_cnt--;
4486                                 }
4487                                 redir = redir->next;
4488                         }
4489                         if (cmd->group) {
4490                                 //bb_error_msg("%s:%u heredoc_cnt:%d", __func__, __LINE__, heredoc_cnt);
4491                                 heredoc_cnt = fetch_heredocs(as_string, cmd->group, heredoc_cnt, input);
4492                                 //bb_error_msg("%s:%u heredoc_cnt:%d", __func__, __LINE__, heredoc_cnt);
4493                                 if (heredoc_cnt < 0)
4494                                         return heredoc_cnt; /* error */
4495                         }
4496                         cmd++;
4497                 }
4498                 pi = pi->next;
4499         }
4500         return heredoc_cnt;
4501 }
4502
4503
4504 static int run_list(struct pipe *pi);
4505 #if BB_MMU
4506 #define parse_stream(pstring, heredoc_cnt_ptr, input, end_trigger) \
4507         parse_stream(heredoc_cnt_ptr, input, end_trigger)
4508 #endif
4509 static struct pipe *parse_stream(char **pstring,
4510                 int *heredoc_cnt_ptr,
4511                 struct in_str *input,
4512                 int end_trigger);
4513
4514 /* Returns number of heredocs not yet consumed,
4515  * or -1 on error.
4516  */
4517 static int parse_group(struct parse_context *ctx,
4518                 struct in_str *input, int ch)
4519 {
4520         /* ctx->word contains characters seen prior to ( or {.
4521          * Typically it's empty, but for function defs,
4522          * it contains function name (without '()'). */
4523 #if BB_MMU
4524 # define as_string NULL
4525 #else
4526         char *as_string = NULL;
4527 #endif
4528         struct pipe *pipe_list;
4529         int heredoc_cnt = 0;
4530         int endch;
4531         struct command *command = ctx->command;
4532
4533         debug_printf_parse("parse_group entered\n");
4534 #if ENABLE_HUSH_FUNCTIONS
4535         if (ch == '(' && !ctx->word.has_quoted_part) {
4536                 if (ctx->word.length)
4537                         if (done_word(ctx))
4538                                 return -1;
4539                 if (!command->argv)
4540                         goto skip; /* (... */
4541                 if (command->argv[1]) { /* word word ... (... */
4542                         syntax_error_unexpected_ch('(');
4543                         return -1;
4544                 }
4545                 /* it is "word(..." or "word (..." */
4546                 do
4547                         ch = i_getch(input);
4548                 while (ch == ' ' || ch == '\t');
4549                 if (ch != ')') {
4550                         syntax_error_unexpected_ch(ch);
4551                         return -1;
4552                 }
4553                 nommu_addchr(&ctx->as_string, ch);
4554                 do
4555                         ch = i_getch(input);
4556                 while (ch == ' ' || ch == '\t' || ch == '\n');
4557                 if (ch != '{' && ch != '(') {
4558                         syntax_error_unexpected_ch(ch);
4559                         return -1;
4560                 }
4561                 nommu_addchr(&ctx->as_string, ch);
4562                 command->cmd_type = CMD_FUNCDEF;
4563                 goto skip;
4564         }
4565 #endif
4566
4567 #if 0 /* Prevented by caller */
4568         if (command->argv /* word [word]{... */
4569          || ctx->word.length /* word{... */
4570          || ctx->word.has_quoted_part /* ""{... */
4571         ) {
4572                 syntax_error(NULL);
4573                 debug_printf_parse("parse_group return -1: "
4574                         "syntax error, groups and arglists don't mix\n");
4575                 return -1;
4576         }
4577 #endif
4578
4579  IF_HUSH_FUNCTIONS(skip:)
4580
4581         endch = '}';
4582         if (ch == '(') {
4583                 endch = ')';
4584                 IF_HUSH_FUNCTIONS(if (command->cmd_type != CMD_FUNCDEF))
4585                         command->cmd_type = CMD_SUBSHELL;
4586         } else {
4587                 /* bash does not allow "{echo...", requires whitespace */
4588                 ch = i_peek(input);
4589                 if (ch != ' ' && ch != '\t' && ch != '\n'
4590                  && ch != '('   /* but "{(..." is allowed (without whitespace) */
4591                 ) {
4592                         syntax_error_unexpected_ch(ch);
4593                         return -1;
4594                 }
4595                 if (ch != '(') {
4596                         ch = i_getch(input);
4597                         nommu_addchr(&ctx->as_string, ch);
4598                 }
4599         }
4600
4601         debug_printf_heredoc("calling parse_stream, heredoc_cnt:%d\n", heredoc_cnt);
4602         pipe_list = parse_stream(&as_string, &heredoc_cnt, input, endch);
4603         debug_printf_heredoc("parse_stream returned: heredoc_cnt:%d\n", heredoc_cnt);
4604 #if !BB_MMU
4605         if (as_string)
4606                 o_addstr(&ctx->as_string, as_string);
4607 #endif
4608
4609         /* empty ()/{} or parse error? */
4610         if (!pipe_list || pipe_list == ERR_PTR) {
4611                 /* parse_stream already emitted error msg */
4612                 if (!BB_MMU)
4613                         free(as_string);
4614                 debug_printf_parse("parse_group return -1: "
4615                         "parse_stream returned %p\n", pipe_list);
4616                 return -1;
4617         }
4618 #if !BB_MMU
4619         as_string[strlen(as_string) - 1] = '\0'; /* plink ')' or '}' */
4620         command->group_as_string = as_string;
4621         debug_printf_parse("end of group, remembering as:'%s'\n",
4622                         command->group_as_string);
4623 #endif
4624
4625 #if ENABLE_HUSH_FUNCTIONS
4626         /* Convert "f() (cmds)" to "f() {(cmds)}" */
4627         if (command->cmd_type == CMD_FUNCDEF && endch == ')') {
4628                 struct command *cmd2;
4629
4630                 cmd2 = xzalloc(sizeof(*cmd2));
4631                 cmd2->cmd_type = CMD_SUBSHELL;
4632                 cmd2->group = pipe_list;
4633 # if !BB_MMU
4634 //UNTESTED!
4635                 cmd2->group_as_string = command->group_as_string;
4636                 command->group_as_string = xasprintf("(%s)", command->group_as_string);
4637 # endif
4638
4639                 pipe_list = new_pipe();
4640                 pipe_list->cmds = cmd2;
4641                 pipe_list->num_cmds = 1;
4642         }
4643 #endif
4644
4645         command->group = pipe_list;
4646
4647         debug_printf_parse("parse_group return %d\n", heredoc_cnt);
4648         return heredoc_cnt;
4649         /* command remains "open", available for possible redirects */
4650 #undef as_string
4651 }
4652
4653 #if ENABLE_HUSH_TICK || ENABLE_FEATURE_SH_MATH || ENABLE_HUSH_DOLLAR_OPS
4654 /* Subroutines for copying $(...) and `...` things */
4655 /* '...' */
4656 static int add_till_single_quote(o_string *dest, struct in_str *input)
4657 {
4658         while (1) {
4659                 int ch = i_getch(input);
4660                 if (ch == EOF) {
4661                         syntax_error_unterm_ch('\'');
4662                         return 0;
4663                 }
4664                 if (ch == '\'')
4665                         return 1;
4666                 o_addchr(dest, ch);
4667         }
4668 }
4669 static int add_till_single_quote_dquoted(o_string *dest, struct in_str *input)
4670 {
4671         while (1) {
4672                 int ch = i_getch(input);
4673                 if (ch == EOF) {
4674                         syntax_error_unterm_ch('\'');
4675                         return 0;
4676                 }
4677                 if (ch == '\'')
4678                         return 1;
4679                 o_addqchr(dest, ch);
4680         }
4681 }
4682 /* "...\"...`..`...." - do we need to handle "...$(..)..." too? */
4683 static int add_till_backquote(o_string *dest, struct in_str *input, int in_dquote);
4684 static int add_till_double_quote(o_string *dest, struct in_str *input)
4685 {
4686         while (1) {
4687                 int ch = i_getch(input);
4688                 if (ch == EOF) {
4689                         syntax_error_unterm_ch('"');
4690                         return 0;
4691                 }
4692                 if (ch == '"')
4693                         return 1;
4694                 if (ch == '\\') {  /* \x. Copy both chars. */
4695                         o_addchr(dest, ch);
4696                         ch = i_getch(input);
4697                 }
4698                 o_addchr(dest, ch);
4699                 if (ch == '`') {
4700                         if (!add_till_backquote(dest, input, /*in_dquote:*/ 1))
4701                                 return 0;
4702                         o_addchr(dest, ch);
4703                         continue;
4704                 }
4705                 //if (ch == '$') ...
4706         }
4707 }
4708 /* Process `cmd` - copy contents until "`" is seen. Complicated by
4709  * \` quoting.
4710  * "Within the backquoted style of command substitution, backslash
4711  * shall retain its literal meaning, except when followed by: '$', '`', or '\'.
4712  * The search for the matching backquote shall be satisfied by the first
4713  * backquote found without a preceding backslash; during this search,
4714  * if a non-escaped backquote is encountered within a shell comment,
4715  * a here-document, an embedded command substitution of the $(command)
4716  * form, or a quoted string, undefined results occur. A single-quoted
4717  * or double-quoted string that begins, but does not end, within the
4718  * "`...`" sequence produces undefined results."
4719  * Example                               Output
4720  * echo `echo '\'TEST\`echo ZZ\`BEST`    \TESTZZBEST
4721  */
4722 static int add_till_backquote(o_string *dest, struct in_str *input, int in_dquote)
4723 {
4724         while (1) {
4725                 int ch = i_getch(input);
4726                 if (ch == '`')
4727                         return 1;
4728                 if (ch == '\\') {
4729                         /* \x. Copy both unless it is \`, \$, \\ and maybe \" */
4730                         ch = i_getch(input);
4731                         if (ch != '`'
4732                          && ch != '$'
4733                          && ch != '\\'
4734                          && (!in_dquote || ch != '"')
4735                         ) {
4736                                 o_addchr(dest, '\\');
4737                         }
4738                 }
4739                 if (ch == EOF) {
4740                         syntax_error_unterm_ch('`');
4741                         return 0;
4742                 }
4743                 o_addchr(dest, ch);
4744         }
4745 }
4746 /* Process $(cmd) - copy contents until ")" is seen. Complicated by
4747  * quoting and nested ()s.
4748  * "With the $(command) style of command substitution, all characters
4749  * following the open parenthesis to the matching closing parenthesis
4750  * constitute the command. Any valid shell script can be used for command,
4751  * except a script consisting solely of redirections which produces
4752  * unspecified results."
4753  * Example                              Output
4754  * echo $(echo '(TEST)' BEST)           (TEST) BEST
4755  * echo $(echo 'TEST)' BEST)            TEST) BEST
4756  * echo $(echo \(\(TEST\) BEST)         ((TEST) BEST
4757  *
4758  * Also adapted to eat ${var%...} and $((...)) constructs, since ... part
4759  * can contain arbitrary constructs, just like $(cmd).
4760  * In bash compat mode, it needs to also be able to stop on ':' or '/'
4761  * for ${var:N[:M]} and ${var/P[/R]} parsing.
4762  */
4763 #define DOUBLE_CLOSE_CHAR_FLAG 0x80
4764 static int add_till_closing_bracket(o_string *dest, struct in_str *input, unsigned end_ch)
4765 {
4766         int ch;
4767         char dbl = end_ch & DOUBLE_CLOSE_CHAR_FLAG;
4768 # if BASH_SUBSTR || BASH_PATTERN_SUBST
4769         char end_char2 = end_ch >> 8;
4770 # endif
4771         end_ch &= (DOUBLE_CLOSE_CHAR_FLAG - 1);
4772
4773 #if ENABLE_HUSH_INTERACTIVE
4774         G.promptmode = 1; /* PS2 */
4775 #endif
4776         debug_printf_prompt("%s promptmode=%d\n", __func__, G.promptmode);
4777
4778         while (1) {
4779                 ch = i_getch(input);
4780                 if (ch == EOF) {
4781                         syntax_error_unterm_ch(end_ch);
4782                         return 0;
4783                 }
4784                 if (ch == end_ch
4785 # if BASH_SUBSTR || BASH_PATTERN_SUBST
4786                  || ch == end_char2
4787 # endif
4788                 ) {
4789                         if (!dbl)
4790                                 break;
4791                         /* we look for closing )) of $((EXPR)) */
4792                         if (i_peek_and_eat_bkslash_nl(input) == end_ch) {
4793                                 i_getch(input); /* eat second ')' */
4794                                 break;
4795                         }
4796                 }
4797                 o_addchr(dest, ch);
4798                 //bb_error_msg("%s:o_addchr('%c')", __func__, ch);
4799                 if (ch == '(' || ch == '{') {
4800                         ch = (ch == '(' ? ')' : '}');
4801                         if (!add_till_closing_bracket(dest, input, ch))
4802                                 return 0;
4803                         o_addchr(dest, ch);
4804                         continue;
4805                 }
4806                 if (ch == '\'') {
4807                         if (!add_till_single_quote(dest, input))
4808                                 return 0;
4809                         o_addchr(dest, ch);
4810                         continue;
4811                 }
4812                 if (ch == '"') {
4813                         if (!add_till_double_quote(dest, input))
4814                                 return 0;
4815                         o_addchr(dest, ch);
4816                         continue;
4817                 }
4818                 if (ch == '`') {
4819                         if (!add_till_backquote(dest, input, /*in_dquote:*/ 0))
4820                                 return 0;
4821                         o_addchr(dest, ch);
4822                         continue;
4823                 }
4824                 if (ch == '\\') {
4825                         /* \x. Copy verbatim. Important for  \(, \) */
4826                         ch = i_getch(input);
4827                         if (ch == EOF) {
4828                                 syntax_error_unterm_ch(end_ch);
4829                                 return 0;
4830                         }
4831 #if 0
4832                         if (ch == '\n') {
4833                                 /* "backslash+newline", ignore both */
4834                                 o_delchr(dest); /* undo insertion of '\' */
4835                                 continue;
4836                         }
4837 #endif
4838                         o_addchr(dest, ch);
4839                         //bb_error_msg("%s:o_addchr('%c') after '\\'", __func__, ch);
4840                         continue;
4841                 }
4842         }
4843         debug_printf_parse("%s return '%s' ch:'%c'\n", __func__, dest->data, ch);
4844         return ch;
4845 }
4846 #endif /* ENABLE_HUSH_TICK || ENABLE_FEATURE_SH_MATH || ENABLE_HUSH_DOLLAR_OPS */
4847
4848 /* Return code: 0 for OK, 1 for syntax error */
4849 #if BB_MMU
4850 #define parse_dollar(as_string, dest, input, quote_mask) \
4851         parse_dollar(dest, input, quote_mask)
4852 #define as_string NULL
4853 #endif
4854 static int parse_dollar(o_string *as_string,
4855                 o_string *dest,
4856                 struct in_str *input, unsigned char quote_mask)
4857 {
4858         int ch = i_peek_and_eat_bkslash_nl(input);  /* first character after the $ */
4859
4860         debug_printf_parse("parse_dollar entered: ch='%c'\n", ch);
4861         if (isalpha(ch)) {
4862  make_var:
4863                 ch = i_getch(input);
4864                 nommu_addchr(as_string, ch);
4865  /*make_var1:*/
4866                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
4867                 while (1) {
4868                         debug_printf_parse(": '%c'\n", ch);
4869                         o_addchr(dest, ch | quote_mask);
4870                         quote_mask = 0;
4871                         ch = i_peek_and_eat_bkslash_nl(input);
4872                         if (!isalnum(ch) && ch != '_') {
4873                                 /* End of variable name reached */
4874                                 break;
4875                         }
4876                         ch = i_getch(input);
4877                         nommu_addchr(as_string, ch);
4878                 }
4879                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
4880         } else if (isdigit(ch)) {
4881  make_one_char_var:
4882                 ch = i_getch(input);
4883                 nommu_addchr(as_string, ch);
4884                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
4885                 debug_printf_parse(": '%c'\n", ch);
4886                 o_addchr(dest, ch | quote_mask);
4887                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
4888         } else switch (ch) {
4889         case '$': /* pid */
4890         case '!': /* last bg pid */
4891         case '?': /* last exit code */
4892         case '#': /* number of args */
4893         case '*': /* args */
4894         case '@': /* args */
4895                 goto make_one_char_var;
4896         case '{': {
4897                 char len_single_ch;
4898
4899                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
4900
4901                 ch = i_getch(input); /* eat '{' */
4902                 nommu_addchr(as_string, ch);
4903
4904                 ch = i_getch_and_eat_bkslash_nl(input); /* first char after '{' */
4905                 /* It should be ${?}, or ${#var},
4906                  * or even ${?+subst} - operator acting on a special variable,
4907                  * or the beginning of variable name.
4908                  */
4909                 if (ch == EOF
4910                  || (!strchr(_SPECIAL_VARS_STR, ch) && !isalnum(ch)) /* not one of those */
4911                 ) {
4912  bad_dollar_syntax:
4913                         syntax_error_unterm_str("${name}");
4914                         debug_printf_parse("parse_dollar return 0: unterminated ${name}\n");
4915                         return 0;
4916                 }
4917                 nommu_addchr(as_string, ch);
4918                 len_single_ch = ch;
4919                 ch |= quote_mask;
4920
4921                 /* It's possible to just call add_till_closing_bracket() at this point.
4922                  * However, this regresses some of our testsuite cases
4923                  * which check invalid constructs like ${%}.
4924                  * Oh well... let's check that the var name part is fine... */
4925
4926                 while (1) {
4927                         unsigned pos;
4928
4929                         o_addchr(dest, ch);
4930                         debug_printf_parse(": '%c'\n", ch);
4931
4932                         ch = i_getch(input);
4933                         nommu_addchr(as_string, ch);
4934                         if (ch == '}')
4935                                 break;
4936
4937                         if (!isalnum(ch) && ch != '_') {
4938                                 unsigned end_ch;
4939                                 unsigned char last_ch;
4940                                 /* handle parameter expansions
4941                                  * http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_06_02
4942                                  */
4943                                 if (!strchr(VAR_SUBST_OPS, ch)) { /* ${var<bad_char>... */
4944                                         if (len_single_ch != '#'
4945                                         /*|| !strchr(SPECIAL_VARS_STR, ch) - disallow errors like ${#+} ? */
4946                                          || i_peek(input) != '}'
4947                                         ) {
4948                                                 goto bad_dollar_syntax;
4949                                         }
4950                                         /* else: it's "length of C" ${#C} op,
4951                                          * where C is a single char
4952                                          * special var name, e.g. ${#!}.
4953                                          */
4954                                 }
4955                                 /* Eat everything until closing '}' (or ':') */
4956                                 end_ch = '}';
4957                                 if (BASH_SUBSTR
4958                                  && ch == ':'
4959                                  && !strchr(MINUS_PLUS_EQUAL_QUESTION, i_peek(input))
4960                                 ) {
4961                                         /* It's ${var:N[:M]} thing */
4962                                         end_ch = '}' * 0x100 + ':';
4963                                 }
4964                                 if (BASH_PATTERN_SUBST
4965                                  && ch == '/'
4966                                 ) {
4967                                         /* It's ${var/[/]pattern[/repl]} thing */
4968                                         if (i_peek(input) == '/') { /* ${var//pattern[/repl]}? */
4969                                                 i_getch(input);
4970                                                 nommu_addchr(as_string, '/');
4971                                                 ch = '\\';
4972                                         }
4973                                         end_ch = '}' * 0x100 + '/';
4974                                 }
4975                                 o_addchr(dest, ch);
4976                                 /* The pattern can't be empty.
4977                                  * IOW: if the first char after "${v//" is a slash,
4978                                  * it does not terminate the pattern - it's the first char of the pattern:
4979                                  *  v=/dev/ram; echo ${v////-}  prints -dev-ram (pattern is "/")
4980                                  *  v=/dev/ram; echo ${v///r/-} prints /dev-am  (pattern is "/r")
4981                                  */
4982                                 if (i_peek(input) == '/') {
4983                                         o_addchr(dest, i_getch(input));
4984                                 }
4985  again:
4986                                 if (!BB_MMU)
4987                                         pos = dest->length;
4988 #if ENABLE_HUSH_DOLLAR_OPS
4989                                 last_ch = add_till_closing_bracket(dest, input, end_ch);
4990                                 if (last_ch == 0) /* error? */
4991                                         return 0;
4992 #else
4993 #error Simple code to only allow ${var} is not implemented
4994 #endif
4995                                 if (as_string) {
4996                                         o_addstr(as_string, dest->data + pos);
4997                                         o_addchr(as_string, last_ch);
4998                                 }
4999
5000                                 if ((BASH_SUBSTR || BASH_PATTERN_SUBST)
5001                                          && (end_ch & 0xff00)
5002                                 ) {
5003                                         /* close the first block: */
5004                                         o_addchr(dest, SPECIAL_VAR_SYMBOL);
5005                                         /* while parsing N from ${var:N[:M]}
5006                                          * or pattern from ${var/[/]pattern[/repl]} */
5007                                         if ((end_ch & 0xff) == last_ch) {
5008                                                 /* got ':' or '/'- parse the rest */
5009                                                 end_ch = '}';
5010                                                 goto again;
5011                                         }
5012                                         /* got '}' */
5013                                         if (BASH_SUBSTR && end_ch == '}' * 0x100 + ':') {
5014                                                 /* it's ${var:N} - emulate :999999999 */
5015                                                 o_addstr(dest, "999999999");
5016                                         } /* else: it's ${var/[/]pattern} */
5017                                 }
5018                                 break;
5019                         }
5020                         len_single_ch = 0; /* it can't be ${#C} op */
5021                 }
5022                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
5023                 break;
5024         }
5025 #if ENABLE_FEATURE_SH_MATH || ENABLE_HUSH_TICK
5026         case '(': {
5027                 unsigned pos;
5028
5029                 ch = i_getch(input);
5030                 nommu_addchr(as_string, ch);
5031 # if ENABLE_FEATURE_SH_MATH
5032                 if (i_peek_and_eat_bkslash_nl(input) == '(') {
5033                         ch = i_getch(input);
5034                         nommu_addchr(as_string, ch);
5035                         o_addchr(dest, SPECIAL_VAR_SYMBOL);
5036                         o_addchr(dest, /*quote_mask |*/ '+');
5037                         if (!BB_MMU)
5038                                 pos = dest->length;
5039                         if (!add_till_closing_bracket(dest, input, ')' | DOUBLE_CLOSE_CHAR_FLAG))
5040                                 return 0; /* error */
5041                         if (as_string) {
5042                                 o_addstr(as_string, dest->data + pos);
5043                                 o_addchr(as_string, ')');
5044                                 o_addchr(as_string, ')');
5045                         }
5046                         o_addchr(dest, SPECIAL_VAR_SYMBOL);
5047                         break;
5048                 }
5049 # endif
5050 # if ENABLE_HUSH_TICK
5051                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
5052                 o_addchr(dest, quote_mask | '`');
5053                 if (!BB_MMU)
5054                         pos = dest->length;
5055                 if (!add_till_closing_bracket(dest, input, ')'))
5056                         return 0; /* error */
5057                 if (as_string) {
5058                         o_addstr(as_string, dest->data + pos);
5059                         o_addchr(as_string, ')');
5060                 }
5061                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
5062 # endif
5063                 break;
5064         }
5065 #endif
5066         case '_':
5067                 goto make_var;
5068 #if 0
5069         /* TODO: $_ and $-: */
5070         /* $_ Shell or shell script name; or last argument of last command
5071          * (if last command wasn't a pipe; if it was, bash sets $_ to "");
5072          * but in command's env, set to full pathname used to invoke it */
5073         /* $- Option flags set by set builtin or shell options (-i etc) */
5074                 ch = i_getch(input);
5075                 nommu_addchr(as_string, ch);
5076                 ch = i_peek_and_eat_bkslash_nl(input);
5077                 if (isalnum(ch)) { /* it's $_name or $_123 */
5078                         ch = '_';
5079                         goto make_var1;
5080                 }
5081                 /* else: it's $_ */
5082 #endif
5083         default:
5084                 o_addQchr(dest, '$');
5085         }
5086         debug_printf_parse("parse_dollar return 1 (ok)\n");
5087         return 1;
5088 #undef as_string
5089 }
5090
5091 #if BB_MMU
5092 #define encode_string(as_string, dest, input, dquote_end) \
5093         encode_string(dest, input, dquote_end)
5094 #define as_string NULL
5095 #endif
5096 static int encode_string(o_string *as_string,
5097                 o_string *dest,
5098                 struct in_str *input,
5099                 int dquote_end)
5100 {
5101         int ch;
5102         int next;
5103
5104  again:
5105         ch = i_getch(input);
5106         if (ch != EOF)
5107                 nommu_addchr(as_string, ch);
5108         if (ch == dquote_end) { /* may be only '"' or EOF */
5109                 debug_printf_parse("encode_string return 1 (ok)\n");
5110                 return 1;
5111         }
5112         /* note: can't move it above ch == dquote_end check! */
5113         if (ch == EOF) {
5114                 syntax_error_unterm_ch('"');
5115                 return 0; /* error */
5116         }
5117         next = '\0';
5118         if (ch != '\n') {
5119                 next = i_peek(input);
5120         }
5121         debug_printf_parse("\" ch=%c (%d) escape=%d\n",
5122                         ch, ch, !!(dest->o_expflags & EXP_FLAG_ESC_GLOB_CHARS));
5123         if (ch == '\\') {
5124                 if (next == EOF) {
5125                         /* Testcase: in interactive shell a file with
5126                          *  echo "unterminated string\<eof>
5127                          * is sourced.
5128                          */
5129                         syntax_error_unterm_ch('"');
5130                         return 0; /* error */
5131                 }
5132                 /* bash:
5133                  * "The backslash retains its special meaning [in "..."]
5134                  * only when followed by one of the following characters:
5135                  * $, `, ", \, or <newline>.  A double quote may be quoted
5136                  * within double quotes by preceding it with a backslash."
5137                  * NB: in (unquoted) heredoc, above does not apply to ",
5138                  * therefore we check for it by "next == dquote_end" cond.
5139                  */
5140                 if (next == dquote_end || strchr("$`\\\n", next)) {
5141                         ch = i_getch(input); /* eat next */
5142                         if (ch == '\n')
5143                                 goto again; /* skip \<newline> */
5144                 } /* else: ch remains == '\\', and we double it below: */
5145                 o_addqchr(dest, ch); /* \c if c is a glob char, else just c */
5146                 nommu_addchr(as_string, ch);
5147                 goto again;
5148         }
5149         if (ch == '$') {
5150                 if (!parse_dollar(as_string, dest, input, /*quote_mask:*/ 0x80)) {
5151                         debug_printf_parse("encode_string return 0: "
5152                                         "parse_dollar returned 0 (error)\n");
5153                         return 0;
5154                 }
5155                 goto again;
5156         }
5157 #if ENABLE_HUSH_TICK
5158         if (ch == '`') {
5159                 //unsigned pos = dest->length;
5160                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
5161                 o_addchr(dest, 0x80 | '`');
5162                 if (!add_till_backquote(dest, input, /*in_dquote:*/ dquote_end == '"'))
5163                         return 0; /* error */
5164                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
5165                 //debug_printf_subst("SUBST RES3 '%s'\n", dest->data + pos);
5166                 goto again;
5167         }
5168 #endif
5169         o_addQchr(dest, ch);
5170         goto again;
5171 #undef as_string
5172 }
5173
5174 /*
5175  * Scan input until EOF or end_trigger char.
5176  * Return a list of pipes to execute, or NULL on EOF
5177  * or if end_trigger character is met.
5178  * On syntax error, exit if shell is not interactive,
5179  * reset parsing machinery and start parsing anew,
5180  * or return ERR_PTR.
5181  */
5182 static struct pipe *parse_stream(char **pstring,
5183                 int *heredoc_cnt_ptr,
5184                 struct in_str *input,
5185                 int end_trigger)
5186 {
5187         struct parse_context ctx;
5188         int heredoc_cnt;
5189
5190         /* Single-quote triggers a bypass of the main loop until its mate is
5191          * found.  When recursing, quote state is passed in via ctx.word.o_expflags.
5192          */
5193         debug_printf_parse("parse_stream entered, end_trigger='%c'\n",
5194                         end_trigger ? end_trigger : 'X');
5195         debug_enter();
5196
5197         initialize_context(&ctx);
5198
5199         /* If very first arg is "" or '', ctx.word.data may end up NULL.
5200          * Preventing this:
5201          */
5202         ctx.word.data = xzalloc(1); /* start as "", not as NULL */
5203
5204         /* We used to separate words on $IFS here. This was wrong.
5205          * $IFS is used only for word splitting when $var is expanded,
5206          * here we should use blank chars as separators, not $IFS
5207          */
5208
5209         heredoc_cnt = 0;
5210         while (1) {
5211                 const char *is_blank;
5212                 const char *is_special;
5213                 int ch;
5214                 int next;
5215                 int redir_fd;
5216                 redir_type redir_style;
5217
5218                 ch = i_getch(input);
5219                 debug_printf_parse(": ch=%c (%d) escape=%d\n",
5220                                 ch, ch, !!(ctx.word.o_expflags & EXP_FLAG_ESC_GLOB_CHARS));
5221                 if (ch == EOF) {
5222                         struct pipe *pi;
5223
5224                         if (heredoc_cnt) {
5225                                 syntax_error_unterm_str("here document");
5226                                 goto parse_error;
5227                         }
5228                         if (end_trigger == ')') {
5229                                 syntax_error_unterm_ch('(');
5230                                 goto parse_error;
5231                         }
5232                         if (end_trigger == '}') {
5233                                 syntax_error_unterm_ch('{');
5234                                 goto parse_error;
5235                         }
5236
5237                         if (done_word(&ctx)) {
5238                                 goto parse_error;
5239                         }
5240                         o_free_and_set_NULL(&ctx.word);
5241                         done_pipe(&ctx, PIPE_SEQ);
5242                         pi = ctx.list_head;
5243                         /* If we got nothing... */
5244                         /* (this makes bare "&" cmd a no-op.
5245                          * bash says: "syntax error near unexpected token '&'") */
5246                         if (pi->num_cmds == 0
5247                         IF_HAS_KEYWORDS(&& pi->res_word == RES_NONE)
5248                         ) {
5249                                 free_pipe_list(pi);
5250                                 pi = NULL;
5251                         }
5252 #if !BB_MMU
5253                         debug_printf_parse("as_string1 '%s'\n", ctx.as_string.data);
5254                         if (pstring)
5255                                 *pstring = ctx.as_string.data;
5256                         else
5257                                 o_free(&ctx.as_string);
5258 #endif
5259                         // heredoc_cnt must be 0 here anyway
5260                         //if (heredoc_cnt_ptr)
5261                         //      *heredoc_cnt_ptr = heredoc_cnt;
5262                         debug_leave();
5263                         debug_printf_heredoc("parse_stream return heredoc_cnt:%d\n", heredoc_cnt);
5264                         debug_printf_parse("parse_stream return %p\n", pi);
5265                         return pi;
5266                 }
5267
5268                 /* Handle "'" and "\" first, as they won't play nice with
5269                  * i_peek_and_eat_bkslash_nl() anyway:
5270                  *   echo z\\
5271                  * and
5272                  *   echo '\
5273                  *   '
5274                  * would break.
5275                  */
5276                 if (ch == '\\') {
5277                         ch = i_getch(input);
5278                         if (ch == '\n')
5279                                 continue; /* drop \<newline>, get next char */
5280                         nommu_addchr(&ctx.as_string, '\\');
5281                         o_addchr(&ctx.word, '\\');
5282                         if (ch == EOF) {
5283                                 /* Testcase: eval 'echo Ok\' */
5284                                 /* bash-4.3.43 was removing backslash,
5285                                  * but 4.4.19 retains it, most other shells too
5286                                  */
5287                                 continue; /* get next char */
5288                         }
5289                         /* Example: echo Hello \2>file
5290                          * we need to know that word 2 is quoted
5291                          */
5292                         ctx.word.has_quoted_part = 1;
5293                         nommu_addchr(&ctx.as_string, ch);
5294                         o_addchr(&ctx.word, ch);
5295                         continue; /* get next char */
5296                 }
5297                 nommu_addchr(&ctx.as_string, ch);
5298                 if (ch == '\'') {
5299                         ctx.word.has_quoted_part = 1;
5300                         next = i_getch(input);
5301                         if (next == '\'' && !ctx.pending_redirect)
5302                                 goto insert_empty_quoted_str_marker;
5303
5304                         ch = next;
5305                         while (1) {
5306                                 if (ch == EOF) {
5307                                         syntax_error_unterm_ch('\'');
5308                                         goto parse_error;
5309                                 }
5310                                 nommu_addchr(&ctx.as_string, ch);
5311                                 if (ch == '\'')
5312                                         break;
5313                                 if (ch == SPECIAL_VAR_SYMBOL) {
5314                                         /* Convert raw ^C to corresponding special variable reference */
5315                                         o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
5316                                         o_addchr(&ctx.word, SPECIAL_VAR_QUOTED_SVS);
5317                                 }
5318                                 o_addqchr(&ctx.word, ch);
5319                                 ch = i_getch(input);
5320                         }
5321                         continue; /* get next char */
5322                 }
5323
5324                 next = '\0';
5325                 if (ch != '\n')
5326                         next = i_peek_and_eat_bkslash_nl(input);
5327
5328                 is_special = "{}<>;&|()#" /* special outside of "str" */
5329                                 "$\"" IF_HUSH_TICK("`") /* always special */
5330                                 SPECIAL_VAR_SYMBOL_STR;
5331                 /* Are { and } special here? */
5332                 if (ctx.command->argv /* word [word]{... - non-special */
5333                  || ctx.word.length       /* word{... - non-special */
5334                  || ctx.word.has_quoted_part     /* ""{... - non-special */
5335                  || (next != ';'             /* }; - special */
5336                     && next != ')'           /* }) - special */
5337                     && next != '('           /* {( - special */
5338                     && next != '&'           /* }& and }&& ... - special */
5339                     && next != '|'           /* }|| ... - special */
5340                     && !strchr(defifs, next) /* {word - non-special */
5341                     )
5342                 ) {
5343                         /* They are not special, skip "{}" */
5344                         is_special += 2;
5345                 }
5346                 is_special = strchr(is_special, ch);
5347                 is_blank = strchr(defifs, ch);
5348
5349                 if (!is_special && !is_blank) { /* ordinary char */
5350  ordinary_char:
5351                         o_addQchr(&ctx.word, ch);
5352                         if ((ctx.is_assignment == MAYBE_ASSIGNMENT
5353                             || ctx.is_assignment == WORD_IS_KEYWORD)
5354                          && ch == '='
5355                          && is_well_formed_var_name(ctx.word.data, '=')
5356                         ) {
5357                                 ctx.is_assignment = DEFINITELY_ASSIGNMENT;
5358                                 debug_printf_parse("ctx.is_assignment='%s'\n", assignment_flag[ctx.is_assignment]);
5359                         }
5360                         continue;
5361                 }
5362
5363                 if (is_blank) {
5364 #if ENABLE_HUSH_LINENO_VAR
5365 /* Case:
5366  * "while ...; do<whitespace><newline>
5367  *      cmd ..."
5368  * would think that "cmd" starts in <whitespace> -
5369  * i.e., at the previous line.
5370  * We need to skip all whitespace before newlines.
5371  */
5372                         while (ch != '\n') {
5373                                 next = i_peek(input);
5374                                 if (next != ' ' && next != '\t' && next != '\n')
5375                                         break; /* next char is not ws */
5376                                 ch = i_getch(input);
5377                         }
5378                         /* ch == last eaten whitespace char */
5379 #endif
5380                         if (done_word(&ctx)) {
5381                                 goto parse_error;
5382                         }
5383                         if (ch == '\n') {
5384                                 /* Is this a case when newline is simply ignored?
5385                                  * Some examples:
5386                                  * "cmd | <newline> cmd ..."
5387                                  * "case ... in <newline> word) ..."
5388                                  */
5389                                 if (IS_NULL_CMD(ctx.command)
5390                                  && ctx.word.length == 0
5391                                  && !ctx.word.has_quoted_part
5392                                  && heredoc_cnt == 0
5393                                 ) {
5394                                         /* This newline can be ignored. But...
5395                                          * Without check #1, interactive shell
5396                                          * ignores even bare <newline>,
5397                                          * and shows the continuation prompt:
5398                                          * ps1_prompt$ <enter>
5399                                          * ps2> _   <=== wrong, should be ps1
5400                                          * Without check #2, "cmd & <newline>"
5401                                          * is similarly mistreated.
5402                                          * (BTW, this makes "cmd & cmd"
5403                                          * and "cmd && cmd" non-orthogonal.
5404                                          * Really, ask yourself, why
5405                                          * "cmd && <newline>" doesn't start
5406                                          * cmd but waits for more input?
5407                                          * The only reason is that it might be
5408                                          * a "cmd1 && <nl> cmd2 &" construct,
5409                                          * cmd1 may need to run in BG).
5410                                          */
5411                                         struct pipe *pi = ctx.list_head;
5412                                         if (pi->num_cmds != 0       /* check #1 */
5413                                          && pi->followup != PIPE_BG /* check #2 */
5414                                         ) {
5415                                                 continue;
5416                                         }
5417                                 }
5418                                 /* Treat newline as a command separator. */
5419                                 done_pipe(&ctx, PIPE_SEQ);
5420                                 debug_printf_heredoc("heredoc_cnt:%d\n", heredoc_cnt);
5421                                 if (heredoc_cnt) {
5422                                         heredoc_cnt = fetch_heredocs(&ctx.as_string, ctx.list_head, heredoc_cnt, input);
5423                                         if (heredoc_cnt != 0)
5424                                                 goto parse_error;
5425                                 }
5426                                 ctx.is_assignment = MAYBE_ASSIGNMENT;
5427                                 debug_printf_parse("ctx.is_assignment='%s'\n", assignment_flag[ctx.is_assignment]);
5428                                 ch = ';';
5429                                 /* note: if (is_blank) continue;
5430                                  * will still trigger for us */
5431                         }
5432                 }
5433
5434                 /* "cmd}" or "cmd }..." without semicolon or &:
5435                  * } is an ordinary char in this case, even inside { cmd; }
5436                  * Pathological example: { ""}; } should exec "}" cmd
5437                  */
5438                 if (ch == '}') {
5439                         if (ctx.word.length != 0 /* word} */
5440                          || ctx.word.has_quoted_part    /* ""} */
5441                         ) {
5442                                 goto ordinary_char;
5443                         }
5444                         if (!IS_NULL_CMD(ctx.command)) { /* cmd } */
5445                                 /* Generally, there should be semicolon: "cmd; }"
5446                                  * However, bash allows to omit it if "cmd" is
5447                                  * a group. Examples:
5448                                  * { { echo 1; } }
5449                                  * {(echo 1)}
5450                                  * { echo 0 >&2 | { echo 1; } }
5451                                  * { while false; do :; done }
5452                                  * { case a in b) ;; esac }
5453                                  */
5454                                 if (ctx.command->group)
5455                                         goto term_group;
5456                                 goto ordinary_char;
5457                         }
5458                         if (!IS_NULL_PIPE(ctx.pipe)) /* cmd | } */
5459                                 /* Can't be an end of {cmd}, skip the check */
5460                                 goto skip_end_trigger;
5461                         /* else: } does terminate a group */
5462                 }
5463  term_group:
5464                 if (end_trigger && end_trigger == ch
5465                  && (ch != ';' || heredoc_cnt == 0)
5466 #if ENABLE_HUSH_CASE
5467                  && (ch != ')'
5468                     || ctx.ctx_res_w != RES_MATCH
5469                     || (!ctx.word.has_quoted_part && strcmp(ctx.word.data, "esac") == 0)
5470                     )
5471 #endif
5472                 ) {
5473                         if (done_word(&ctx)) {
5474                                 goto parse_error;
5475                         }
5476                         done_pipe(&ctx, PIPE_SEQ);
5477                         ctx.is_assignment = MAYBE_ASSIGNMENT;
5478                         debug_printf_parse("ctx.is_assignment='%s'\n", assignment_flag[ctx.is_assignment]);
5479                         /* Do we sit outside of any if's, loops or case's? */
5480                         if (!HAS_KEYWORDS
5481                         IF_HAS_KEYWORDS(|| (ctx.ctx_res_w == RES_NONE && ctx.old_flag == 0))
5482                         ) {
5483                                 o_free_and_set_NULL(&ctx.word);
5484 #if !BB_MMU
5485                                 debug_printf_parse("as_string2 '%s'\n", ctx.as_string.data);
5486                                 if (pstring)
5487                                         *pstring = ctx.as_string.data;
5488                                 else
5489                                         o_free(&ctx.as_string);
5490 #endif
5491                                 if (ch != ';' && IS_NULL_PIPE(ctx.list_head)) {
5492                                         /* Example: bare "{ }", "()" */
5493                                         G.last_exitcode = 2; /* bash compat */
5494                                         syntax_error_unexpected_ch(ch);
5495                                         goto parse_error2;
5496                                 }
5497                                 if (heredoc_cnt_ptr)
5498                                         *heredoc_cnt_ptr = heredoc_cnt;
5499                                 debug_printf_heredoc("parse_stream return heredoc_cnt:%d\n", heredoc_cnt);
5500                                 debug_printf_parse("parse_stream return %p: "
5501                                                 "end_trigger char found\n",
5502                                                 ctx.list_head);
5503                                 debug_leave();
5504                                 return ctx.list_head;
5505                         }
5506                 }
5507
5508                 if (is_blank)
5509                         continue;
5510
5511                 /* Catch <, > before deciding whether this word is
5512                  * an assignment. a=1 2>z b=2: b=2 is still assignment */
5513                 switch (ch) {
5514                 case '>':
5515                         redir_fd = redirect_opt_num(&ctx.word);
5516                         if (done_word(&ctx)) {
5517                                 goto parse_error;
5518                         }
5519                         redir_style = REDIRECT_OVERWRITE;
5520                         if (next == '>') {
5521                                 redir_style = REDIRECT_APPEND;
5522                                 ch = i_getch(input);
5523                                 nommu_addchr(&ctx.as_string, ch);
5524                         }
5525 #if 0
5526                         else if (next == '(') {
5527                                 syntax_error(">(process) not supported");
5528                                 goto parse_error;
5529                         }
5530 #endif
5531                         if (parse_redirect(&ctx, redir_fd, redir_style, input))
5532                                 goto parse_error;
5533                         continue; /* get next char */
5534                 case '<':
5535                         redir_fd = redirect_opt_num(&ctx.word);
5536                         if (done_word(&ctx)) {
5537                                 goto parse_error;
5538                         }
5539                         redir_style = REDIRECT_INPUT;
5540                         if (next == '<') {
5541                                 redir_style = REDIRECT_HEREDOC;
5542                                 heredoc_cnt++;
5543                                 debug_printf_heredoc("++heredoc_cnt=%d\n", heredoc_cnt);
5544                                 ch = i_getch(input);
5545                                 nommu_addchr(&ctx.as_string, ch);
5546                         } else if (next == '>') {
5547                                 redir_style = REDIRECT_IO;
5548                                 ch = i_getch(input);
5549                                 nommu_addchr(&ctx.as_string, ch);
5550                         }
5551 #if 0
5552                         else if (next == '(') {
5553                                 syntax_error("<(process) not supported");
5554                                 goto parse_error;
5555                         }
5556 #endif
5557                         if (parse_redirect(&ctx, redir_fd, redir_style, input))
5558                                 goto parse_error;
5559                         continue; /* get next char */
5560                 case '#':
5561                         if (ctx.word.length == 0 && !ctx.word.has_quoted_part) {
5562                                 /* skip "#comment" */
5563                                 /* note: we do not add it to &ctx.as_string */
5564 /* TODO: in bash:
5565  * comment inside $() goes to the next \n, even inside quoted string (!):
5566  * cmd "$(cmd2 #comment)" - syntax error
5567  * cmd "`cmd2 #comment`" - ok
5568  * We accept both (comment ends where command subst ends, in both cases).
5569  */
5570                                 while (1) {
5571                                         ch = i_peek(input);
5572                                         if (ch == '\n') {
5573                                                 nommu_addchr(&ctx.as_string, '\n');
5574                                                 break;
5575                                         }
5576                                         ch = i_getch(input);
5577                                         if (ch == EOF)
5578                                                 break;
5579                                 }
5580                                 continue; /* get next char */
5581                         }
5582                         break;
5583                 }
5584  skip_end_trigger:
5585
5586                 if (ctx.is_assignment == MAYBE_ASSIGNMENT
5587                  /* check that we are not in word in "a=1 2>word b=1": */
5588                  && !ctx.pending_redirect
5589                 ) {
5590                         /* ch is a special char and thus this word
5591                          * cannot be an assignment */
5592                         ctx.is_assignment = NOT_ASSIGNMENT;
5593                         debug_printf_parse("ctx.is_assignment='%s'\n", assignment_flag[ctx.is_assignment]);
5594                 }
5595
5596                 /* Note: nommu_addchr(&ctx.as_string, ch) is already done */
5597
5598                 switch (ch) {
5599                 case SPECIAL_VAR_SYMBOL:
5600                         /* Convert raw ^C to corresponding special variable reference */
5601                         o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
5602                         o_addchr(&ctx.word, SPECIAL_VAR_QUOTED_SVS);
5603                         /* fall through */
5604                 case '#':
5605                         /* non-comment #: "echo a#b" etc */
5606                         o_addchr(&ctx.word, ch);
5607                         continue; /* get next char */
5608                 case '$':
5609                         if (!parse_dollar(&ctx.as_string, &ctx.word, input, /*quote_mask:*/ 0)) {
5610                                 debug_printf_parse("parse_stream parse error: "
5611                                         "parse_dollar returned 0 (error)\n");
5612                                 goto parse_error;
5613                         }
5614                         continue; /* get next char */
5615                 case '"':
5616                         ctx.word.has_quoted_part = 1;
5617                         if (next == '"' && !ctx.pending_redirect) {
5618                                 i_getch(input); /* eat second " */
5619  insert_empty_quoted_str_marker:
5620                                 nommu_addchr(&ctx.as_string, next);
5621                                 o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
5622                                 o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
5623                                 continue; /* get next char */
5624                         }
5625                         if (ctx.is_assignment == NOT_ASSIGNMENT)
5626                                 ctx.word.o_expflags |= EXP_FLAG_ESC_GLOB_CHARS;
5627                         if (!encode_string(&ctx.as_string, &ctx.word, input, '"'))
5628                                 goto parse_error;
5629                         ctx.word.o_expflags &= ~EXP_FLAG_ESC_GLOB_CHARS;
5630                         continue; /* get next char */
5631 #if ENABLE_HUSH_TICK
5632                 case '`': {
5633                         USE_FOR_NOMMU(unsigned pos;)
5634
5635                         o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
5636                         o_addchr(&ctx.word, '`');
5637                         USE_FOR_NOMMU(pos = ctx.word.length;)
5638                         if (!add_till_backquote(&ctx.word, input, /*in_dquote:*/ 0))
5639                                 goto parse_error;
5640 # if !BB_MMU
5641                         o_addstr(&ctx.as_string, ctx.word.data + pos);
5642                         o_addchr(&ctx.as_string, '`');
5643 # endif
5644                         o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
5645                         //debug_printf_subst("SUBST RES3 '%s'\n", ctx.word.data + pos);
5646                         continue; /* get next char */
5647                 }
5648 #endif
5649                 case ';':
5650 #if ENABLE_HUSH_CASE
5651  case_semi:
5652 #endif
5653                         if (done_word(&ctx)) {
5654                                 goto parse_error;
5655                         }
5656                         done_pipe(&ctx, PIPE_SEQ);
5657 #if ENABLE_HUSH_CASE
5658                         /* Eat multiple semicolons, detect
5659                          * whether it means something special */
5660                         while (1) {
5661                                 ch = i_peek_and_eat_bkslash_nl(input);
5662                                 if (ch != ';')
5663                                         break;
5664                                 ch = i_getch(input);
5665                                 nommu_addchr(&ctx.as_string, ch);
5666                                 if (ctx.ctx_res_w == RES_CASE_BODY) {
5667                                         ctx.ctx_dsemicolon = 1;
5668                                         ctx.ctx_res_w = RES_MATCH;
5669                                         break;
5670                                 }
5671                         }
5672 #endif
5673  new_cmd:
5674                         /* We just finished a cmd. New one may start
5675                          * with an assignment */
5676                         ctx.is_assignment = MAYBE_ASSIGNMENT;
5677                         debug_printf_parse("ctx.is_assignment='%s'\n", assignment_flag[ctx.is_assignment]);
5678                         continue; /* get next char */
5679                 case '&':
5680                         if (done_word(&ctx)) {
5681                                 goto parse_error;
5682                         }
5683                         if (next == '&') {
5684                                 ch = i_getch(input);
5685                                 nommu_addchr(&ctx.as_string, ch);
5686                                 done_pipe(&ctx, PIPE_AND);
5687                         } else {
5688                                 done_pipe(&ctx, PIPE_BG);
5689                         }
5690                         goto new_cmd;
5691                 case '|':
5692                         if (done_word(&ctx)) {
5693                                 goto parse_error;
5694                         }
5695 #if ENABLE_HUSH_CASE
5696                         if (ctx.ctx_res_w == RES_MATCH)
5697                                 break; /* we are in case's "word | word)" */
5698 #endif
5699                         if (next == '|') { /* || */
5700                                 ch = i_getch(input);
5701                                 nommu_addchr(&ctx.as_string, ch);
5702                                 done_pipe(&ctx, PIPE_OR);
5703                         } else {
5704                                 /* we could pick up a file descriptor choice here
5705                                  * with redirect_opt_num(), but bash doesn't do it.
5706                                  * "echo foo 2| cat" yields "foo 2". */
5707                                 done_command(&ctx);
5708                         }
5709                         goto new_cmd;
5710                 case '(':
5711 #if ENABLE_HUSH_CASE
5712                         /* "case... in [(]word)..." - skip '(' */
5713                         if (ctx.ctx_res_w == RES_MATCH
5714                          && ctx.command->argv == NULL /* not (word|(... */
5715                          && ctx.word.length == 0 /* not word(... */
5716                          && ctx.word.has_quoted_part == 0 /* not ""(... */
5717                         ) {
5718                                 continue; /* get next char */
5719                         }
5720 #endif
5721                         /* fall through */
5722                 case '{': {
5723                         int n = parse_group(&ctx, input, ch);
5724                         if (n < 0) {
5725                                 goto parse_error;
5726                         }
5727                         debug_printf_heredoc("parse_group done, needs heredocs:%d\n", n);
5728                         heredoc_cnt += n;
5729                         goto new_cmd;
5730                 }
5731                 case ')':
5732 #if ENABLE_HUSH_CASE
5733                         if (ctx.ctx_res_w == RES_MATCH)
5734                                 goto case_semi;
5735 #endif
5736
5737                 case '}':
5738                         /* proper use of this character is caught by end_trigger:
5739                          * if we see {, we call parse_group(..., end_trigger='}')
5740                          * and it will match } earlier (not here). */
5741                         G.last_exitcode = 2;
5742                         syntax_error_unexpected_ch(ch);
5743                         goto parse_error2;
5744                 default:
5745                         if (HUSH_DEBUG)
5746                                 bb_error_msg_and_die("BUG: unexpected %c", ch);
5747                 }
5748         } /* while (1) */
5749
5750  parse_error:
5751         G.last_exitcode = 1;
5752  parse_error2:
5753         {
5754                 struct parse_context *pctx;
5755                 IF_HAS_KEYWORDS(struct parse_context *p2;)
5756
5757                 /* Clean up allocated tree.
5758                  * Sample for finding leaks on syntax error recovery path.
5759                  * Run it from interactive shell, watch pmap `pidof hush`.
5760                  * while if false; then false; fi; do break; fi
5761                  * Samples to catch leaks at execution:
5762                  * while if (true | { true;}); then echo ok; fi; do break; done
5763                  * while if (true | { true;}); then echo ok; fi; do (if echo ok; break; then :; fi) | cat; break; done
5764                  */
5765                 pctx = &ctx;
5766                 do {
5767                         /* Update pipe/command counts,
5768                          * otherwise freeing may miss some */
5769                         done_pipe(pctx, PIPE_SEQ);
5770                         debug_printf_clean("freeing list %p from ctx %p\n",
5771                                         pctx->list_head, pctx);
5772                         debug_print_tree(pctx->list_head, 0);
5773                         free_pipe_list(pctx->list_head);
5774                         debug_printf_clean("freed list %p\n", pctx->list_head);
5775 #if !BB_MMU
5776                         o_free(&pctx->as_string);
5777 #endif
5778                         IF_HAS_KEYWORDS(p2 = pctx->stack;)
5779                         if (pctx != &ctx) {
5780                                 free(pctx);
5781                         }
5782                         IF_HAS_KEYWORDS(pctx = p2;)
5783                 } while (HAS_KEYWORDS && pctx);
5784
5785                 o_free(&ctx.word);
5786 #if !BB_MMU
5787                 if (pstring)
5788                         *pstring = NULL;
5789 #endif
5790                 debug_leave();
5791                 return ERR_PTR;
5792         }
5793 }
5794
5795
5796 /*** Execution routines ***/
5797
5798 /* Expansion can recurse, need forward decls: */
5799 #if !BASH_PATTERN_SUBST && !ENABLE_HUSH_CASE
5800 #define expand_string_to_string(str, EXP_flags, do_unbackslash) \
5801         expand_string_to_string(str)
5802 #endif
5803 static char *expand_string_to_string(const char *str, int EXP_flags, int do_unbackslash);
5804 #if ENABLE_HUSH_TICK
5805 static int process_command_subs(o_string *dest, const char *s);
5806 #endif
5807 static int expand_vars_to_list(o_string *output, int n, char *arg);
5808
5809 /* expand_strvec_to_strvec() takes a list of strings, expands
5810  * all variable references within and returns a pointer to
5811  * a list of expanded strings, possibly with larger number
5812  * of strings. (Think VAR="a b"; echo $VAR).
5813  * This new list is allocated as a single malloc block.
5814  * NULL-terminated list of char* pointers is at the beginning of it,
5815  * followed by strings themselves.
5816  * Caller can deallocate entire list by single free(list). */
5817
5818 /* A horde of its helpers come first: */
5819
5820 static void o_addblock_duplicate_backslash(o_string *o, const char *str, int len)
5821 {
5822         while (--len >= 0) {
5823                 char c = *str++;
5824
5825 #if ENABLE_HUSH_BRACE_EXPANSION
5826                 if (c == '{' || c == '}') {
5827                         /* { -> \{, } -> \} */
5828                         o_addchr(o, '\\');
5829                         /* And now we want to add { or } and continue:
5830                          *  o_addchr(o, c);
5831                          *  continue;
5832                          * luckily, just falling through achieves this.
5833                          */
5834                 }
5835 #endif
5836                 o_addchr(o, c);
5837                 if (c == '\\') {
5838                         /* \z -> \\\z; \<eol> -> \\<eol> */
5839                         o_addchr(o, '\\');
5840                         if (len) {
5841                                 len--;
5842                                 o_addchr(o, '\\');
5843                                 o_addchr(o, *str++);
5844                         }
5845                 }
5846         }
5847 }
5848
5849 /* Store given string, finalizing the word and starting new one whenever
5850  * we encounter IFS char(s). This is used for expanding variable values.
5851  * End-of-string does NOT finalize word: think about 'echo -$VAR-'.
5852  * Return in output->ended_in_ifs:
5853  * 1 - ended with IFS char, else 0 (this includes case of empty str).
5854  */
5855 static int expand_on_ifs(o_string *output, int n, const char *str)
5856 {
5857         int last_is_ifs = 0;
5858
5859         while (1) {
5860                 int word_len;
5861
5862                 if (!*str)  /* EOL - do not finalize word */
5863                         break;
5864                 word_len = strcspn(str, G.ifs);
5865                 if (word_len) {
5866                         /* We have WORD_LEN leading non-IFS chars */
5867                         if (!(output->o_expflags & EXP_FLAG_GLOB)) {
5868                                 o_addblock(output, str, word_len);
5869                         } else {
5870                                 /* Protect backslashes against globbing up :)
5871                                  * Example: "v='\*'; echo b$v" prints "b\*"
5872                                  * (and does not try to glob on "*")
5873                                  */
5874                                 o_addblock_duplicate_backslash(output, str, word_len);
5875                                 /*/ Why can't we do it easier? */
5876                                 /*o_addblock(output, str, word_len); - WRONG: "v='\*'; echo Z$v" prints "Z*" instead of "Z\*" */
5877                                 /*o_addqblock(output, str, word_len); - WRONG: "v='*'; echo Z$v" prints "Z*" instead of Z* files */
5878                         }
5879                         last_is_ifs = 0;
5880                         str += word_len;
5881                         if (!*str)  /* EOL - do not finalize word */
5882                                 break;
5883                 }
5884
5885                 /* We know str here points to at least one IFS char */
5886                 last_is_ifs = 1;
5887                 str += strspn(str, G.ifs_whitespace); /* skip IFS whitespace chars */
5888                 if (!*str)  /* EOL - do not finalize word */
5889                         break;
5890
5891                 if (G.ifs_whitespace != G.ifs /* usually false ($IFS is usually all whitespace), */
5892                  && strchr(G.ifs, *str)       /* the second check would fail */
5893                 ) {
5894                         /* This is a non-whitespace $IFS char */
5895                         /* Skip it and IFS whitespace chars, start new word */
5896                         str++;
5897                         str += strspn(str, G.ifs_whitespace);
5898                         goto new_word;
5899                 }
5900
5901                 /* Start new word... but not always! */
5902                 /* Case "v=' a'; echo ''$v": we do need to finalize empty word: */
5903                 if (output->has_quoted_part
5904                 /*
5905                  * Case "v=' a'; echo $v":
5906                  * here nothing precedes the space in $v expansion,
5907                  * therefore we should not finish the word
5908                  * (IOW: if there *is* word to finalize, only then do it):
5909                  * It's okay if this accesses the byte before first argv[]:
5910                  * past call to o_save_ptr() cleared it to zero byte
5911                  * (grep for -prev-ifs-check-).
5912                  */
5913                  || output->data[output->length - 1]
5914                 ) {
5915  new_word:
5916                         o_addchr(output, '\0');
5917                         debug_print_list("expand_on_ifs", output, n);
5918                         n = o_save_ptr(output, n);
5919                 }
5920         }
5921
5922         output->ended_in_ifs = last_is_ifs;
5923         debug_print_list("expand_on_ifs[1]", output, n);
5924         return n;
5925 }
5926
5927 /* Helper to expand $((...)) and heredoc body. These act as if
5928  * they are in double quotes, with the exception that they are not :).
5929  * Just the rules are similar: "expand only $var and `cmd`"
5930  *
5931  * Returns malloced string.
5932  * As an optimization, we return NULL if expansion is not needed.
5933  */
5934 static char *encode_then_expand_string(const char *str)
5935 {
5936         char *exp_str;
5937         struct in_str input;
5938         o_string dest = NULL_O_STRING;
5939         const char *cp;
5940
5941         cp = str;
5942         for (;;) {
5943                 if (!*cp) return NULL; /* string has no special chars */
5944                 if (*cp == '$') break;
5945                 if (*cp == '\\') break;
5946 #if ENABLE_HUSH_TICK
5947                 if (*cp == '`') break;
5948 #endif
5949                 cp++;
5950         }
5951
5952         /* We need to expand. Example:
5953          * echo $(($a + `echo 1`)) $((1 + $((2)) ))
5954          */
5955         setup_string_in_str(&input, str);
5956         encode_string(NULL, &dest, &input, EOF);
5957 //TODO: error check (encode_string returns 0 on error)?
5958         //bb_error_msg("'%s' -> '%s'", str, dest.data);
5959         exp_str = expand_string_to_string(dest.data,
5960                         EXP_FLAG_ESC_GLOB_CHARS,
5961                         /*unbackslash:*/ 1
5962         );
5963         //bb_error_msg("'%s' -> '%s'", dest.data, exp_str);
5964         o_free(&dest);
5965         return exp_str;
5966 }
5967
5968 static const char *first_special_char_in_vararg(const char *cp)
5969 {
5970         for (;;) {
5971                 if (!*cp) return NULL; /* string has no special chars */
5972                 if (*cp == '$') return cp;
5973                 if (*cp == '\\') return cp;
5974                 if (*cp == '\'') return cp;
5975                 if (*cp == '"') return cp;
5976 #if ENABLE_HUSH_TICK
5977                 if (*cp == '`') return cp;
5978 #endif
5979                 /* dquoted "${x:+ARG}" should not glob, therefore
5980                  * '*' et al require some non-literal processing: */
5981                 if (*cp == '*') return cp;
5982                 if (*cp == '?') return cp;
5983                 if (*cp == '[') return cp;
5984                 cp++;
5985         }
5986 }
5987
5988 /* Expanding ARG in ${var#ARG}, ${var%ARG}, or ${var/ARG/ARG}.
5989  * These can contain single- and double-quoted strings,
5990  * and treated as if the ARG string is initially unquoted. IOW:
5991  * ${var#ARG} and "${var#ARG}" treat ARG the same (ARG can even be
5992  * a dquoted string: "${var#"zz"}"), the difference only comes later
5993  * (word splitting and globbing of the ${var...} result).
5994  */
5995 #if !BASH_PATTERN_SUBST
5996 #define encode_then_expand_vararg(str, handle_squotes, do_unbackslash) \
5997         encode_then_expand_vararg(str, handle_squotes)
5998 #endif
5999 static char *encode_then_expand_vararg(const char *str, int handle_squotes, int do_unbackslash)
6000 {
6001 #if !BASH_PATTERN_SUBST
6002         const int do_unbackslash = 0;
6003 #endif
6004         char *exp_str;
6005         struct in_str input;
6006         o_string dest = NULL_O_STRING;
6007
6008         if (!first_special_char_in_vararg(str)) {
6009                 /* string has no special chars */
6010                 return NULL;
6011         }
6012
6013         setup_string_in_str(&input, str);
6014         dest.data = xzalloc(1); /* start as "", not as NULL */
6015         exp_str = NULL;
6016
6017         for (;;) {
6018                 int ch;
6019
6020                 ch = i_getch(&input);
6021                 debug_printf_parse("%s: ch=%c (%d) escape=%d\n",
6022                                 __func__, ch, ch, !!dest.o_expflags);
6023
6024                 if (!dest.o_expflags) {
6025                         if (ch == EOF)
6026                                 break;
6027                         if (handle_squotes && ch == '\'') {
6028                                 if (!add_till_single_quote_dquoted(&dest, &input))
6029                                         goto ret; /* error */
6030                                 continue;
6031                         }
6032                 }
6033                 if (ch == EOF) {
6034                         syntax_error_unterm_ch('"');
6035                         goto ret; /* error */
6036                 }
6037                 if (ch == '"') {
6038                         dest.o_expflags ^= EXP_FLAG_ESC_GLOB_CHARS;
6039                         continue;
6040                 }
6041                 if (ch == '\\') {
6042                         ch = i_getch(&input);
6043                         if (ch == EOF) {
6044 //example? error message?       syntax_error_unterm_ch('"');
6045                                 debug_printf_parse("%s: error: \\<eof>\n", __func__);
6046                                 goto ret;
6047                         }
6048                         o_addqchr(&dest, ch);
6049                         continue;
6050                 }
6051                 if (ch == '$') {
6052                         if (!parse_dollar(NULL, &dest, &input, /*quote_mask:*/ 0x80)) {
6053                                 debug_printf_parse("%s: error: parse_dollar returned 0 (error)\n", __func__);
6054                                 goto ret;
6055                         }
6056                         continue;
6057                 }
6058 #if ENABLE_HUSH_TICK
6059                 if (ch == '`') {
6060                         //unsigned pos = dest->length;
6061                         o_addchr(&dest, SPECIAL_VAR_SYMBOL);
6062                         o_addchr(&dest, 0x80 | '`');
6063                         if (!add_till_backquote(&dest, &input,
6064                                         /*in_dquote:*/ dest.o_expflags /* nonzero if EXP_FLAG_ESC_GLOB_CHARS set */
6065                                 )
6066                         ) {
6067                                 goto ret; /* error */
6068                         }
6069                         o_addchr(&dest, SPECIAL_VAR_SYMBOL);
6070                         //debug_printf_subst("SUBST RES3 '%s'\n", dest->data + pos);
6071                         continue;
6072                 }
6073 #endif
6074                 o_addQchr(&dest, ch);
6075         } /* for (;;) */
6076
6077         debug_printf_parse("encode: '%s' -> '%s'\n", str, dest.data);
6078         exp_str = expand_string_to_string(dest.data,
6079                         do_unbackslash ? EXP_FLAG_ESC_GLOB_CHARS : 0,
6080                         do_unbackslash
6081         );
6082  ret:
6083         debug_printf_parse("expand: '%s' -> '%s'\n", dest.data, exp_str);
6084         o_free(&dest);
6085         return exp_str;
6086 }
6087
6088 /* Expanding ARG in ${var+ARG}, ${var-ARG}
6089  */
6090 static int encode_then_append_var_plusminus(o_string *output, int n,
6091                 char *str, int dquoted)
6092 {
6093         struct in_str input;
6094         o_string dest = NULL_O_STRING;
6095
6096         if (!first_special_char_in_vararg(str)
6097          && '\0' == str[strcspn(str, G.ifs)]
6098         ) {
6099                 /* string has no special chars
6100                  * && string has no $IFS chars
6101                  */
6102                 return expand_vars_to_list(output, n, str);
6103         }
6104
6105         setup_string_in_str(&input, str);
6106
6107         for (;;) {
6108                 int ch;
6109
6110                 ch = i_getch(&input);
6111                 debug_printf_parse("%s: ch=%c (%d) escape=%x\n",
6112                                 __func__, ch, ch, dest.o_expflags);
6113
6114                 if (!dest.o_expflags) {
6115                         if (ch == EOF)
6116                                 break;
6117                         if (!dquoted && strchr(G.ifs, ch)) {
6118                                 /* PREFIX${x:d${e}f ...} and we met space: expand "d${e}f" and start new word.
6119                                  * do not assume we are at the start of the word (PREFIX above).
6120                                  */
6121                                 if (dest.data) {
6122                                         n = expand_vars_to_list(output, n, dest.data);
6123                                         o_free_and_set_NULL(&dest);
6124                                         o_addchr(output, '\0');
6125                                         n = o_save_ptr(output, n); /* create next word */
6126                                 } else
6127                                 if (output->length != o_get_last_ptr(output, n)
6128                                  || output->has_quoted_part
6129                                 ) {
6130                                         /* For these cases:
6131                                          * f() { for i; do echo "|$i|"; done; }; x=x
6132                                          * f a${x:+ }b  # 1st condition
6133                                          * |a|
6134                                          * |b|
6135                                          * f ""${x:+ }b  # 2nd condition
6136                                          * ||
6137                                          * |b|
6138                                          */
6139                                         o_addchr(output, '\0');
6140                                         n = o_save_ptr(output, n); /* create next word */
6141                                 }
6142                                 continue;
6143                         }
6144                         if (!dquoted && ch == '\'') {
6145                                 if (!add_till_single_quote_dquoted(&dest, &input))
6146                                         goto ret; /* error */
6147                                 o_addchr(&dest, SPECIAL_VAR_SYMBOL);
6148                                 o_addchr(&dest, SPECIAL_VAR_SYMBOL);
6149                                 continue;
6150                         }
6151                 }
6152                 if (ch == EOF) {
6153                         syntax_error_unterm_ch('"');
6154                         goto ret; /* error */
6155                 }
6156                 if (ch == '"') {
6157                         dest.o_expflags ^= EXP_FLAG_ESC_GLOB_CHARS;
6158                         if (dest.o_expflags) {
6159                                 o_addchr(&dest, SPECIAL_VAR_SYMBOL);
6160                                 o_addchr(&dest, SPECIAL_VAR_SYMBOL);
6161                         }
6162                         continue;
6163                 }
6164                 if (ch == '\\') {
6165                         ch = i_getch(&input);
6166                         if (ch == EOF) {
6167 //example? error message?       syntax_error_unterm_ch('"');
6168                                 debug_printf_parse("%s: error: \\<eof>\n", __func__);
6169                                 goto ret;
6170                         }
6171                         o_addqchr(&dest, ch);
6172                         continue;
6173                 }
6174                 if (ch == '$') {
6175                         if (!parse_dollar(NULL, &dest, &input, /*quote_mask:*/ (dest.o_expflags || dquoted) ? 0x80 : 0)) {
6176                                 debug_printf_parse("%s: error: parse_dollar returned 0 (error)\n", __func__);
6177                                 goto ret;
6178                         }
6179                         continue;
6180                 }
6181 #if ENABLE_HUSH_TICK
6182                 if (ch == '`') {
6183                         //unsigned pos = dest->length;
6184                         o_addchr(&dest, SPECIAL_VAR_SYMBOL);
6185                         o_addchr(&dest, (dest.o_expflags || dquoted) ? 0x80 | '`' : '`');
6186                         if (!add_till_backquote(&dest, &input,
6187                                         /*in_dquote:*/ dest.o_expflags /* nonzero if EXP_FLAG_ESC_GLOB_CHARS set */
6188                                 )
6189                         ) {
6190                                 goto ret; /* error */
6191                         }
6192                         o_addchr(&dest, SPECIAL_VAR_SYMBOL);
6193                         //debug_printf_subst("SUBST RES3 '%s'\n", dest->data + pos);
6194                         continue;
6195                 }
6196 #endif
6197                 if (dquoted) {
6198                         /* Always glob-protect if in dquotes:
6199                          * x=x; echo "${x:+/bin/c*}" - prints: /bin/c*
6200                          * x=x; echo "${x:+"/bin/c*"}" - prints: /bin/c*
6201                          */
6202                         o_addqchr(&dest, ch);
6203                 } else {
6204                         /* Glob-protect only if char is quoted:
6205                          * x=x; echo ${x:+/bin/c*} - prints many filenames
6206                          * x=x; echo ${x:+"/bin/c*"} - prints: /bin/c*
6207                          */
6208                         o_addQchr(&dest, ch);
6209                 }
6210         } /* for (;;) */
6211
6212         if (dest.data) {
6213                 n = expand_vars_to_list(output, n, dest.data);
6214         }
6215  ret:
6216         o_free(&dest);
6217         return n;
6218 }
6219
6220 #if ENABLE_FEATURE_SH_MATH
6221 static arith_t expand_and_evaluate_arith(const char *arg, const char **errmsg_p)
6222 {
6223         arith_state_t math_state;
6224         arith_t res;
6225         char *exp_str;
6226
6227         math_state.lookupvar = get_local_var_value;
6228         math_state.setvar = set_local_var_from_halves;
6229         //math_state.endofname = endofname;
6230         exp_str = encode_then_expand_string(arg);
6231         res = arith(&math_state, exp_str ? exp_str : arg);
6232         free(exp_str);
6233         if (errmsg_p)
6234                 *errmsg_p = math_state.errmsg;
6235         if (math_state.errmsg)
6236                 msg_and_die_if_script(math_state.errmsg);
6237         return res;
6238 }
6239 #endif
6240
6241 #if BASH_PATTERN_SUBST
6242 /* ${var/[/]pattern[/repl]} helpers */
6243 static char *strstr_pattern(char *val, const char *pattern, int *size)
6244 {
6245         while (1) {
6246                 char *end = scan_and_match(val, pattern, SCAN_MOVE_FROM_RIGHT + SCAN_MATCH_LEFT_HALF);
6247                 debug_printf_varexp("val:'%s' pattern:'%s' end:'%s'\n", val, pattern, end);
6248                 if (end) {
6249                         *size = end - val;
6250                         return val;
6251                 }
6252                 if (*val == '\0')
6253                         return NULL;
6254                 /* Optimization: if "*pat" did not match the start of "string",
6255                  * we know that "tring", "ring" etc will not match too:
6256                  */
6257                 if (pattern[0] == '*')
6258                         return NULL;
6259                 val++;
6260         }
6261 }
6262 static char *replace_pattern(char *val, const char *pattern, const char *repl, char exp_op)
6263 {
6264         char *result = NULL;
6265         unsigned res_len = 0;
6266         unsigned repl_len = strlen(repl);
6267
6268         /* Null pattern never matches, including if "var" is empty */
6269         if (!pattern[0])
6270                 return result; /* NULL, no replaces happened */
6271
6272         while (1) {
6273                 int size;
6274                 char *s = strstr_pattern(val, pattern, &size);
6275                 if (!s)
6276                         break;
6277
6278                 result = xrealloc(result, res_len + (s - val) + repl_len + 1);
6279                 strcpy(mempcpy(result + res_len, val, s - val), repl);
6280                 res_len += (s - val) + repl_len;
6281                 debug_printf_varexp("val:'%s' s:'%s' result:'%s'\n", val, s, result);
6282
6283                 val = s + size;
6284                 if (exp_op == '/')
6285                         break;
6286         }
6287         if (*val && result) {
6288                 result = xrealloc(result, res_len + strlen(val) + 1);
6289                 strcpy(result + res_len, val);
6290                 debug_printf_varexp("val:'%s' result:'%s'\n", val, result);
6291         }
6292         debug_printf_varexp("result:'%s'\n", result);
6293         return result;
6294 }
6295 #endif /* BASH_PATTERN_SUBST */
6296
6297 static int append_str_maybe_ifs_split(o_string *output, int n,
6298                 int first_ch, const char *val)
6299 {
6300         if (!(first_ch & 0x80)) { /* unquoted $VAR */
6301                 debug_printf_expand("unquoted '%s', output->o_escape:%d\n", val,
6302                                 !!(output->o_expflags & EXP_FLAG_ESC_GLOB_CHARS));
6303                 if (val && val[0])
6304                         n = expand_on_ifs(output, n, val);
6305         } else { /* quoted "$VAR" */
6306                 output->has_quoted_part = 1;
6307                 debug_printf_expand("quoted '%s', output->o_escape:%d\n", val,
6308                                 !!(output->o_expflags & EXP_FLAG_ESC_GLOB_CHARS));
6309                 if (val && val[0])
6310                         o_addQstr(output, val);
6311         }
6312         return n;
6313 }
6314
6315 /* Handle <SPECIAL_VAR_SYMBOL>varname...<SPECIAL_VAR_SYMBOL> construct.
6316  */
6317 static NOINLINE int expand_one_var(o_string *output, int n,
6318                 int first_ch, char *arg, char **pp)
6319 {
6320         const char *val;
6321         char *to_be_freed;
6322         char *p;
6323         char *var;
6324         char exp_op;
6325         char exp_save = exp_save; /* for compiler */
6326         char *exp_saveptr; /* points to expansion operator */
6327         char *exp_word = exp_word; /* for compiler */
6328         char arg0;
6329
6330         val = NULL;
6331         to_be_freed = NULL;
6332         p = *pp;
6333         *p = '\0'; /* replace trailing SPECIAL_VAR_SYMBOL */
6334         var = arg;
6335         exp_saveptr = arg[1] ? strchr(VAR_ENCODED_SUBST_OPS, arg[1]) : NULL;
6336         arg0 = arg[0];
6337         arg[0] = (arg0 & 0x7f);
6338         exp_op = 0;
6339
6340         if (arg[0] == '#' && arg[1] /* ${#...} but not ${#} */
6341          && (!exp_saveptr               /* and ( not(${#<op_char>...}) */
6342             || (arg[2] == '\0' && strchr(SPECIAL_VARS_STR, arg[1])) /* or ${#C} "len of $C" ) */
6343             )           /* NB: skipping ^^^specvar check mishandles ${#::2} */
6344         ) {
6345                 /* It must be length operator: ${#var} */
6346                 var++;
6347                 exp_op = 'L';
6348         } else {
6349                 /* Maybe handle parameter expansion */
6350                 if (exp_saveptr /* if 2nd char is one of expansion operators */
6351                  && strchr(NUMERIC_SPECVARS_STR, arg[0]) /* 1st char is special variable */
6352                 ) {
6353                         /* ${?:0}, ${#[:]%0} etc */
6354                         exp_saveptr = var + 1;
6355                 } else {
6356                         /* ${?}, ${var}, ${var:0}, ${var[:]%0} etc */
6357                         exp_saveptr = var+1 + strcspn(var+1, VAR_ENCODED_SUBST_OPS);
6358                 }
6359                 exp_op = exp_save = *exp_saveptr;
6360                 if (exp_op) {
6361                         exp_word = exp_saveptr + 1;
6362                         if (exp_op == ':') {
6363                                 exp_op = *exp_word++;
6364 //TODO: try ${var:} and ${var:bogus} in non-bash config
6365                                 if (BASH_SUBSTR
6366                                  && (!exp_op || !strchr(MINUS_PLUS_EQUAL_QUESTION, exp_op))
6367                                 ) {
6368                                         /* oops... it's ${var:N[:M]}, not ${var:?xxx} or some such */
6369                                         exp_op = ':';
6370                                         exp_word--;
6371                                 }
6372                         }
6373                         *exp_saveptr = '\0';
6374                 } /* else: it's not an expansion op, but bare ${var} */
6375         }
6376
6377         /* Look up the variable in question */
6378         if (isdigit(var[0])) {
6379                 /* parse_dollar should have vetted var for us */
6380                 int nn = xatoi_positive(var);
6381                 if (nn < G.global_argc)
6382                         val = G.global_argv[nn];
6383                 /* else val remains NULL: $N with too big N */
6384         } else {
6385                 switch (var[0]) {
6386                 case '$': /* pid */
6387                         val = utoa(G.root_pid);
6388                         break;
6389                 case '!': /* bg pid */
6390                         val = G.last_bg_pid ? utoa(G.last_bg_pid) : "";
6391                         break;
6392                 case '?': /* exitcode */
6393                         val = utoa(G.last_exitcode);
6394                         break;
6395                 case '#': /* argc */
6396                         val = utoa(G.global_argc ? G.global_argc-1 : 0);
6397                         break;
6398                 default:
6399                         val = get_local_var_value(var);
6400                 }
6401         }
6402
6403         /* Handle any expansions */
6404         if (exp_op == 'L') {
6405                 reinit_unicode_for_hush();
6406                 debug_printf_expand("expand: length(%s)=", val);
6407                 val = utoa(val ? unicode_strlen(val) : 0);
6408                 debug_printf_expand("%s\n", val);
6409         } else if (exp_op) {
6410                 if (exp_op == '%' || exp_op == '#') {
6411                         /* Standard-mandated substring removal ops:
6412                          * ${parameter%word} - remove smallest suffix pattern
6413                          * ${parameter%%word} - remove largest suffix pattern
6414                          * ${parameter#word} - remove smallest prefix pattern
6415                          * ${parameter##word} - remove largest prefix pattern
6416                          *
6417                          * Word is expanded to produce a glob pattern.
6418                          * Then var's value is matched to it and matching part removed.
6419                          */
6420 //FIXME: ${x#...${...}...}
6421 //should evaluate inner ${...} even if x is "" and no shrinking of it is possible -
6422 //inner ${...} may have side effects!
6423                         if (val && val[0]) {
6424                                 char *t;
6425                                 char *exp_exp_word;
6426                                 char *loc;
6427                                 unsigned scan_flags = pick_scan(exp_op, *exp_word);
6428                                 if (exp_op == *exp_word)  /* ## or %% */
6429                                         exp_word++;
6430                                 debug_printf_expand("expand: exp_word:'%s'\n", exp_word);
6431                                 exp_exp_word = encode_then_expand_vararg(exp_word, /*handle_squotes:*/ 1, /*unbackslash:*/ 0);
6432                                 if (exp_exp_word)
6433                                         exp_word = exp_exp_word;
6434                                 debug_printf_expand("expand: exp_word:'%s'\n", exp_word);
6435                                 /*
6436                                  * HACK ALERT. We depend here on the fact that
6437                                  * G.global_argv and results of utoa and get_local_var_value
6438                                  * are actually in writable memory:
6439                                  * scan_and_match momentarily stores NULs there.
6440                                  */
6441                                 t = (char*)val;
6442                                 loc = scan_and_match(t, exp_word, scan_flags);
6443                                 debug_printf_expand("op:%c str:'%s' pat:'%s' res:'%s'\n", exp_op, t, exp_word, loc);
6444                                 free(exp_exp_word);
6445                                 if (loc) { /* match was found */
6446                                         if (scan_flags & SCAN_MATCH_LEFT_HALF) /* #[#] */
6447                                                 val = loc; /* take right part */
6448                                         else /* %[%] */
6449                                                 val = to_be_freed = xstrndup(val, loc - val); /* left */
6450                                 }
6451                         }
6452                 }
6453 #if BASH_PATTERN_SUBST
6454                 else if (exp_op == '/' || exp_op == '\\') {
6455                         /* It's ${var/[/]pattern[/repl]} thing.
6456                          * Note that in encoded form it has TWO parts:
6457                          * var/pattern<SPECIAL_VAR_SYMBOL>repl<SPECIAL_VAR_SYMBOL>
6458                          * and if // is used, it is encoded as \:
6459                          * var\pattern<SPECIAL_VAR_SYMBOL>repl<SPECIAL_VAR_SYMBOL>
6460                          */
6461                         if (val && val[0]) {
6462                                 /* pattern uses non-standard expansion.
6463                                  * repl should be unbackslashed and globbed
6464                                  * by the usual expansion rules:
6465                                  *  >az >bz
6466                                  *  v='a bz'; echo "${v/a*z/a*z}" #prints "a*z"
6467                                  *  v='a bz'; echo "${v/a*z/\z}"  #prints "z"
6468                                  *  v='a bz'; echo ${v/a*z/a*z}   #prints "az"
6469                                  *  v='a bz'; echo ${v/a*z/\z}    #prints "z"
6470                                  * (note that a*z _pattern_ is never globbed!)
6471                                  */
6472                                 char *pattern, *repl, *t;
6473                                 pattern = encode_then_expand_vararg(exp_word, /*handle_squotes:*/ 1, /*unbackslash:*/ 0);
6474                                 if (!pattern)
6475                                         pattern = xstrdup(exp_word);
6476                                 debug_printf_varexp("pattern:'%s'->'%s'\n", exp_word, pattern);
6477                                 *p++ = SPECIAL_VAR_SYMBOL;
6478                                 exp_word = p;
6479                                 p = strchr(p, SPECIAL_VAR_SYMBOL);
6480                                 *p = '\0';
6481                                 repl = encode_then_expand_vararg(exp_word, /*handle_squotes:*/ 1, /*unbackslash:*/ 1);
6482                                 debug_printf_varexp("repl:'%s'->'%s'\n", exp_word, repl);
6483                                 /* HACK ALERT. We depend here on the fact that
6484                                  * G.global_argv and results of utoa and get_local_var_value
6485                                  * are actually in writable memory:
6486                                  * replace_pattern momentarily stores NULs there. */
6487                                 t = (char*)val;
6488                                 to_be_freed = replace_pattern(t,
6489                                                 pattern,
6490                                                 (repl ? repl : exp_word),
6491                                                 exp_op);
6492                                 if (to_be_freed) /* at least one replace happened */
6493                                         val = to_be_freed;
6494                                 free(pattern);
6495                                 free(repl);
6496                         } else {
6497                                 /* Empty variable always gives nothing */
6498                                 // "v=''; echo ${v/*/w}" prints "", not "w"
6499                                 /* Just skip "replace" part */
6500                                 *p++ = SPECIAL_VAR_SYMBOL;
6501                                 p = strchr(p, SPECIAL_VAR_SYMBOL);
6502                                 *p = '\0';
6503                         }
6504                 }
6505 #endif /* BASH_PATTERN_SUBST */
6506                 else if (exp_op == ':') {
6507 #if BASH_SUBSTR && ENABLE_FEATURE_SH_MATH
6508                         /* It's ${var:N[:M]} bashism.
6509                          * Note that in encoded form it has TWO parts:
6510                          * var:N<SPECIAL_VAR_SYMBOL>M<SPECIAL_VAR_SYMBOL>
6511                          */
6512                         arith_t beg, len;
6513                         const char *errmsg;
6514
6515                         beg = expand_and_evaluate_arith(exp_word, &errmsg);
6516                         if (errmsg)
6517                                 goto arith_err;
6518                         debug_printf_varexp("beg:'%s'=%lld\n", exp_word, (long long)beg);
6519                         *p++ = SPECIAL_VAR_SYMBOL;
6520                         exp_word = p;
6521                         p = strchr(p, SPECIAL_VAR_SYMBOL);
6522                         *p = '\0';
6523                         len = expand_and_evaluate_arith(exp_word, &errmsg);
6524                         if (errmsg)
6525                                 goto arith_err;
6526                         debug_printf_varexp("len:'%s'=%lld\n", exp_word, (long long)len);
6527                         if (beg < 0) {
6528                                 /* negative beg counts from the end */
6529                                 beg = (arith_t)strlen(val) + beg;
6530                                 if (beg < 0) /* ${v: -999999} is "" */
6531                                         beg = len = 0;
6532                         }
6533                         debug_printf_varexp("from val:'%s'\n", val);
6534                         if (len < 0) {
6535                                 /* in bash, len=-n means strlen()-n */
6536                                 len = (arith_t)strlen(val) - beg + len;
6537                                 if (len < 0) /* bash compat */
6538                                         msg_and_die_if_script("%s: substring expression < 0", var);
6539                         }
6540                         if (len <= 0 || !val || beg >= strlen(val)) {
6541  arith_err:
6542                                 val = NULL;
6543                         } else {
6544                                 /* Paranoia. What if user entered 9999999999999
6545                                  * which fits in arith_t but not int? */
6546                                 if (len >= INT_MAX)
6547                                         len = INT_MAX;
6548                                 val = to_be_freed = xstrndup(val + beg, len);
6549                         }
6550                         debug_printf_varexp("val:'%s'\n", val);
6551 #else /* not (HUSH_SUBSTR_EXPANSION && FEATURE_SH_MATH) */
6552                         msg_and_die_if_script("malformed ${%s:...}", var);
6553                         val = NULL;
6554 #endif
6555                 } else { /* one of "-=+?" */
6556                         /* Standard-mandated substitution ops:
6557                          * ${var?word} - indicate error if unset
6558                          *      If var is unset, word (or a message indicating it is unset
6559                          *      if word is null) is written to standard error
6560                          *      and the shell exits with a non-zero exit status.
6561                          *      Otherwise, the value of var is substituted.
6562                          * ${var-word} - use default value
6563                          *      If var is unset, word is substituted.
6564                          * ${var=word} - assign and use default value
6565                          *      If var is unset, word is assigned to var.
6566                          *      In all cases, final value of var is substituted.
6567                          * ${var+word} - use alternative value
6568                          *      If var is unset, null is substituted.
6569                          *      Otherwise, word is substituted.
6570                          *
6571                          * Word is subjected to tilde expansion, parameter expansion,
6572                          * command substitution, and arithmetic expansion.
6573                          * If word is not needed, it is not expanded.
6574                          *
6575                          * Colon forms (${var:-word}, ${var:=word} etc) do the same,
6576                          * but also treat null var as if it is unset.
6577                          *
6578                          * Word-splitting and single quote behavior:
6579                          *
6580                          * $ f() { for i; do echo "|$i|"; done; };
6581                          *
6582                          * $ x=; f ${x:?'x y' z}
6583                          * bash: x: x y z              #BUG: does not abort, ${} results in empty expansion
6584                          * $ x=; f "${x:?'x y' z}"
6585                          * bash: x: x y z       # dash prints: dash: x: 'x y' z   #BUG: does not abort, ${} results in ""
6586                          *
6587                          * $ x=; f ${x:='x y' z}
6588                          * |x|
6589                          * |y|
6590                          * |z|
6591                          * $ x=; f "${x:='x y' z}"
6592                          * |'x y' z|
6593                          *
6594                          * $ x=x; f ${x:+'x y' z}
6595                          * |x y|
6596                          * |z|
6597                          * $ x=x; f "${x:+'x y' z}"
6598                          * |'x y' z|
6599                          *
6600                          * $ x=; f ${x:-'x y' z}
6601                          * |x y|
6602                          * |z|
6603                          * $ x=; f "${x:-'x y' z}"
6604                          * |'x y' z|
6605                          */
6606                         int use_word = (!val || ((exp_save == ':') && !val[0]));
6607                         if (exp_op == '+')
6608                                 use_word = !use_word;
6609                         debug_printf_expand("expand: op:%c (null:%s) test:%i\n", exp_op,
6610                                         (exp_save == ':') ? "true" : "false", use_word);
6611                         if (use_word) {
6612                                 if (exp_op == '+' || exp_op == '-') {
6613                                         /* ${var+word} - use alternative value */
6614                                         /* ${var-word} - use default value */
6615                                         n = encode_then_append_var_plusminus(output, n, exp_word,
6616                                                         /*dquoted:*/ (arg0 & 0x80)
6617                                         );
6618                                         val = NULL;
6619                                 } else {
6620                                         /* ${var?word} - indicate error if unset */
6621                                         /* ${var=word} - assign and use default value */
6622                                         to_be_freed = encode_then_expand_vararg(exp_word,
6623                                                         /*handle_squotes:*/ !(arg0 & 0x80),
6624                                                         /*unbackslash:*/ 0
6625                                         );
6626                                         if (to_be_freed)
6627                                                 exp_word = to_be_freed;
6628                                         if (exp_op == '?') {
6629                                                 /* mimic bash message */
6630                                                 msg_and_die_if_script("%s: %s",
6631                                                         var,
6632                                                         exp_word[0]
6633                                                         ? exp_word
6634                                                         : "parameter null or not set"
6635                                                         /* ash has more specific messages, a-la: */
6636                                                         /*: (exp_save == ':' ? "parameter null or not set" : "parameter not set")*/
6637                                                 );
6638 //TODO: how interactive bash aborts expansion mid-command?
6639 //It aborts the entire line, returns to prompt:
6640 // $ f() { for i; do echo "|$i|"; done; }; x=; f "${x:?'x y' z}"; echo YO
6641 // bash: x: x y z
6642 // $
6643 // ("echo YO" is not executed, neither the f function call)
6644                                         } else {
6645                                                 val = exp_word;
6646                                         }
6647                                         if (exp_op == '=') {
6648                                                 /* ${var=[word]} or ${var:=[word]} */
6649                                                 if (isdigit(var[0]) || var[0] == '#') {
6650                                                         /* mimic bash message */
6651                                                         msg_and_die_if_script("$%s: cannot assign in this way", var);
6652                                                         val = NULL;
6653                                                 } else {
6654                                                         char *new_var = xasprintf("%s=%s", var, val);
6655                                                         set_local_var(new_var, /*flag:*/ 0);
6656                                                 }
6657                                         }
6658                                 }
6659                         }
6660                 } /* one of "-=+?" */
6661
6662                 *exp_saveptr = exp_save;
6663         } /* if (exp_op) */
6664
6665         arg[0] = arg0;
6666         *pp = p;
6667
6668         n = append_str_maybe_ifs_split(output, n, first_ch, val);
6669
6670         free(to_be_freed);
6671         return n;
6672 }
6673
6674 /* Expand all variable references in given string, adding words to list[]
6675  * at n, n+1,... positions. Return updated n (so that list[n] is next one
6676  * to be filled). This routine is extremely tricky: has to deal with
6677  * variables/parameters with whitespace, $* and $@, and constructs like
6678  * 'echo -$*-'. If you play here, you must run testsuite afterwards! */
6679 static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg)
6680 {
6681         /* output->o_expflags & EXP_FLAG_SINGLEWORD (0x80) if we are in
6682          * expansion of right-hand side of assignment == 1-element expand.
6683          */
6684         char cant_be_null = 0; /* only bit 0x80 matters */
6685         char *p;
6686
6687         debug_printf_expand("expand_vars_to_list: arg:'%s' singleword:%x\n", arg,
6688                         !!(output->o_expflags & EXP_FLAG_SINGLEWORD));
6689         debug_print_list("expand_vars_to_list[0]", output, n);
6690
6691         while ((p = strchr(arg, SPECIAL_VAR_SYMBOL)) != NULL) {
6692                 char first_ch;
6693 #if ENABLE_FEATURE_SH_MATH
6694                 char arith_buf[sizeof(arith_t)*3 + 2];
6695 #endif
6696
6697                 if (output->ended_in_ifs) {
6698                         o_addchr(output, '\0');
6699                         n = o_save_ptr(output, n);
6700                         output->ended_in_ifs = 0;
6701                 }
6702
6703                 o_addblock(output, arg, p - arg);
6704                 debug_print_list("expand_vars_to_list[1]", output, n);
6705                 arg = ++p;
6706                 p = strchr(p, SPECIAL_VAR_SYMBOL);
6707
6708                 /* Fetch special var name (if it is indeed one of them)
6709                  * and quote bit, force the bit on if singleword expansion -
6710                  * important for not getting v=$@ expand to many words. */
6711                 first_ch = arg[0] | (output->o_expflags & EXP_FLAG_SINGLEWORD);
6712
6713                 /* Is this variable quoted and thus expansion can't be null?
6714                  * "$@" is special. Even if quoted, it can still
6715                  * expand to nothing (not even an empty string),
6716                  * thus it is excluded. */
6717                 if ((first_ch & 0x7f) != '@')
6718                         cant_be_null |= first_ch;
6719
6720                 switch (first_ch & 0x7f) {
6721                 /* Highest bit in first_ch indicates that var is double-quoted */
6722                 case '*':
6723                 case '@': {
6724                         int i;
6725                         if (!G.global_argv[1])
6726                                 break;
6727                         i = 1;
6728                         cant_be_null |= first_ch; /* do it for "$@" _now_, when we know it's not empty */
6729                         if (!(first_ch & 0x80)) { /* unquoted $* or $@ */
6730                                 while (G.global_argv[i]) {
6731                                         n = expand_on_ifs(output, n, G.global_argv[i]);
6732                                         debug_printf_expand("expand_vars_to_list: argv %d (last %d)\n", i, G.global_argc - 1);
6733                                         if (G.global_argv[i++][0] && G.global_argv[i]) {
6734                                                 /* this argv[] is not empty and not last:
6735                                                  * put terminating NUL, start new word */
6736                                                 o_addchr(output, '\0');
6737                                                 debug_print_list("expand_vars_to_list[2]", output, n);
6738                                                 n = o_save_ptr(output, n);
6739                                                 debug_print_list("expand_vars_to_list[3]", output, n);
6740                                         }
6741                                 }
6742                         } else
6743                         /* If EXP_FLAG_SINGLEWORD, we handle assignment 'a=....$@.....'
6744                          * and in this case should treat it like '$*' - see 'else...' below */
6745                         if (first_ch == (char)('@'|0x80)  /* quoted $@ */
6746                          && !(output->o_expflags & EXP_FLAG_SINGLEWORD) /* not v="$@" case */
6747                         ) {
6748                                 while (1) {
6749                                         o_addQstr(output, G.global_argv[i]);
6750                                         if (++i >= G.global_argc)
6751                                                 break;
6752                                         o_addchr(output, '\0');
6753                                         debug_print_list("expand_vars_to_list[4]", output, n);
6754                                         n = o_save_ptr(output, n);
6755                                 }
6756                         } else { /* quoted $* (or v="$@" case): add as one word */
6757                                 while (1) {
6758                                         o_addQstr(output, G.global_argv[i]);
6759                                         if (!G.global_argv[++i])
6760                                                 break;
6761                                         if (G.ifs[0])
6762                                                 o_addchr(output, G.ifs[0]);
6763                                 }
6764                                 output->has_quoted_part = 1;
6765                         }
6766                         break;
6767                 }
6768                 case SPECIAL_VAR_SYMBOL: {
6769                         /* <SPECIAL_VAR_SYMBOL><SPECIAL_VAR_SYMBOL> */
6770                         /* "Empty variable", used to make "" etc to not disappear */
6771                         output->has_quoted_part = 1;
6772                         cant_be_null = 0x80;
6773                         arg++;
6774                         break;
6775                 }
6776                 case SPECIAL_VAR_QUOTED_SVS:
6777                         /* <SPECIAL_VAR_SYMBOL><SPECIAL_VAR_QUOTED_SVS><SPECIAL_VAR_SYMBOL> */
6778                         /* "^C variable", represents literal ^C char (possible in scripts) */
6779                         o_addchr(output, SPECIAL_VAR_SYMBOL);
6780                         arg++;
6781                         break;
6782 #if ENABLE_HUSH_TICK
6783                 case '`': {
6784                         /* <SPECIAL_VAR_SYMBOL>`cmd<SPECIAL_VAR_SYMBOL> */
6785                         o_string subst_result = NULL_O_STRING;
6786
6787                         *p = '\0'; /* replace trailing <SPECIAL_VAR_SYMBOL> */
6788                         arg++;
6789                         /* Can't just stuff it into output o_string,
6790                          * expanded result may need to be globbed
6791                          * and $IFS-split */
6792                         debug_printf_subst("SUBST '%s' first_ch %x\n", arg, first_ch);
6793                         G.last_exitcode = process_command_subs(&subst_result, arg);
6794                         G.expand_exitcode = G.last_exitcode;
6795                         debug_printf_subst("SUBST RES:%d '%s'\n", G.last_exitcode, subst_result.data);
6796                         n = append_str_maybe_ifs_split(output, n, first_ch, subst_result.data);
6797                         o_free(&subst_result);
6798                         break;
6799                 }
6800 #endif
6801 #if ENABLE_FEATURE_SH_MATH
6802                 case '+': {
6803                         /* <SPECIAL_VAR_SYMBOL>+arith<SPECIAL_VAR_SYMBOL> */
6804                         arith_t res;
6805
6806                         arg++; /* skip '+' */
6807                         *p = '\0'; /* replace trailing <SPECIAL_VAR_SYMBOL> */
6808                         debug_printf_subst("ARITH '%s' first_ch %x\n", arg, first_ch);
6809                         res = expand_and_evaluate_arith(arg, NULL);
6810                         debug_printf_subst("ARITH RES '"ARITH_FMT"'\n", res);
6811                         sprintf(arith_buf, ARITH_FMT, res);
6812                         o_addstr(output, arith_buf);
6813                         break;
6814                 }
6815 #endif
6816                 default:
6817                         /* <SPECIAL_VAR_SYMBOL>varname[ops]<SPECIAL_VAR_SYMBOL> */
6818                         n = expand_one_var(output, n, first_ch, arg, &p);
6819                         break;
6820                 } /* switch (char after <SPECIAL_VAR_SYMBOL>) */
6821
6822                 /* Restore NULL'ed SPECIAL_VAR_SYMBOL.
6823                  * Do the check to avoid writing to a const string. */
6824                 if (*p != SPECIAL_VAR_SYMBOL)
6825                         *p = SPECIAL_VAR_SYMBOL;
6826                 arg = ++p;
6827         } /* end of "while (SPECIAL_VAR_SYMBOL is found) ..." */
6828
6829         if (*arg) {
6830                 /* handle trailing string */
6831                 if (output->ended_in_ifs) {
6832                         o_addchr(output, '\0');
6833                         n = o_save_ptr(output, n);
6834                 }
6835                 debug_print_list("expand_vars_to_list[a]", output, n);
6836                 /* this part is literal, and it was already pre-quoted
6837                  * if needed (much earlier), do not use o_addQstr here!
6838                  */
6839                 o_addstr(output, arg);
6840                 debug_print_list("expand_vars_to_list[b]", output, n);
6841         } else
6842         if (output->length == o_get_last_ptr(output, n) /* expansion is empty */
6843          && !(cant_be_null & 0x80)   /* and all vars were not quoted */
6844          && !output->has_quoted_part
6845         ) {
6846                 n--;
6847                 /* allow to reuse list[n] later without re-growth */
6848                 output->has_empty_slot = 1;
6849         }
6850
6851         return n;
6852 }
6853
6854 static char **expand_variables(char **argv, unsigned expflags)
6855 {
6856         int n;
6857         char **list;
6858         o_string output = NULL_O_STRING;
6859
6860         output.o_expflags = expflags;
6861
6862         n = 0;
6863         for (;;) {
6864                 /* go to next list[n] */
6865                 output.ended_in_ifs = 0;
6866                 n = o_save_ptr(&output, n);
6867
6868                 if (!*argv)
6869                         break;
6870
6871                 /* expand argv[i] */
6872                 n = expand_vars_to_list(&output, n, *argv++);
6873                 /* if (!output->has_empty_slot) -- need this?? */
6874                         o_addchr(&output, '\0');
6875         }
6876         debug_print_list("expand_variables", &output, n);
6877
6878         /* output.data (malloced in one block) gets returned in "list" */
6879         list = o_finalize_list(&output, n);
6880         debug_print_strings("expand_variables[1]", list);
6881         return list;
6882 }
6883
6884 static char **expand_strvec_to_strvec(char **argv)
6885 {
6886         return expand_variables(argv, EXP_FLAG_GLOB | EXP_FLAG_ESC_GLOB_CHARS);
6887 }
6888
6889 #if defined(CMD_SINGLEWORD_NOGLOB)
6890 static char **expand_strvec_to_strvec_singleword_noglob(char **argv)
6891 {
6892         return expand_variables(argv, EXP_FLAG_SINGLEWORD);
6893 }
6894 #endif
6895
6896 /* Used for expansion of right hand of assignments,
6897  * $((...)), heredocs, variable expansion parts.
6898  *
6899  * NB: should NOT do globbing!
6900  * "export v=/bin/c*; env | grep ^v=" outputs "v=/bin/c*"
6901  */
6902 static char *expand_string_to_string(const char *str, int EXP_flags, int do_unbackslash)
6903 {
6904 #if !BASH_PATTERN_SUBST && !ENABLE_HUSH_CASE
6905         const int do_unbackslash = 1;
6906         const int EXP_flags = EXP_FLAG_ESC_GLOB_CHARS;
6907 #endif
6908         char *argv[2], **list;
6909
6910         debug_printf_expand("string_to_string<='%s'\n", str);
6911         /* This is generally an optimization, but it also
6912          * handles "", which otherwise trips over !list[0] check below.
6913          * (is this ever happens that we actually get str="" here?)
6914          */
6915         if (!strchr(str, SPECIAL_VAR_SYMBOL) && !strchr(str, '\\')) {
6916                 //TODO: Can use on strings with \ too, just unbackslash() them?
6917                 debug_printf_expand("string_to_string(fast)=>'%s'\n", str);
6918                 return xstrdup(str);
6919         }
6920
6921         argv[0] = (char*)str;
6922         argv[1] = NULL;
6923         list = expand_variables(argv, EXP_flags | EXP_FLAG_SINGLEWORD);
6924         if (!list[0]) {
6925                 /* Example where it happens:
6926                  * x=; echo ${x:-"$@"}
6927                  */
6928                 ((char*)list)[0] = '\0';
6929         } else {
6930                 if (HUSH_DEBUG)
6931                         if (list[1])
6932                                 bb_error_msg_and_die("BUG in varexp2");
6933                 /* actually, just move string 2*sizeof(char*) bytes back */
6934                 overlapping_strcpy((char*)list, list[0]);
6935                 if (do_unbackslash)
6936                         unbackslash((char*)list);
6937         }
6938         debug_printf_expand("string_to_string=>'%s'\n", (char*)list);
6939         return (char*)list;
6940 }
6941
6942 #if 0
6943 static char* expand_strvec_to_string(char **argv)
6944 {
6945         char **list;
6946
6947         list = expand_variables(argv, EXP_FLAG_SINGLEWORD);
6948         /* Convert all NULs to spaces */
6949         if (list[0]) {
6950                 int n = 1;
6951                 while (list[n]) {
6952                         if (HUSH_DEBUG)
6953                                 if (list[n-1] + strlen(list[n-1]) + 1 != list[n])
6954                                         bb_error_msg_and_die("BUG in varexp3");
6955                         /* bash uses ' ' regardless of $IFS contents */
6956                         list[n][-1] = ' ';
6957                         n++;
6958                 }
6959         }
6960         overlapping_strcpy((char*)list, list[0] ? list[0] : "");
6961         debug_printf_expand("strvec_to_string='%s'\n", (char*)list);
6962         return (char*)list;
6963 }
6964 #endif
6965
6966 static char **expand_assignments(char **argv, int count)
6967 {
6968         int i;
6969         char **p;
6970
6971         G.expanded_assignments = p = NULL;
6972         /* Expand assignments into one string each */
6973         for (i = 0; i < count; i++) {
6974                 p = add_string_to_strings(p,
6975                         expand_string_to_string(argv[i],
6976                                 EXP_FLAG_ESC_GLOB_CHARS,
6977                                 /*unbackslash:*/ 1
6978                         )
6979                 );
6980                 G.expanded_assignments = p;
6981         }
6982         G.expanded_assignments = NULL;
6983         return p;
6984 }
6985
6986
6987 static void switch_off_special_sigs(unsigned mask)
6988 {
6989         unsigned sig = 0;
6990         while ((mask >>= 1) != 0) {
6991                 sig++;
6992                 if (!(mask & 1))
6993                         continue;
6994 #if ENABLE_HUSH_TRAP
6995                 if (G_traps) {
6996                         if (G_traps[sig] && !G_traps[sig][0])
6997                                 /* trap is '', has to remain SIG_IGN */
6998                                 continue;
6999                         free(G_traps[sig]);
7000                         G_traps[sig] = NULL;
7001                 }
7002 #endif
7003                 /* We are here only if no trap or trap was not '' */
7004                 install_sighandler(sig, SIG_DFL);
7005         }
7006 }
7007
7008 #if BB_MMU
7009 /* never called */
7010 void re_execute_shell(char ***to_free, const char *s,
7011                 char *g_argv0, char **g_argv,
7012                 char **builtin_argv) NORETURN;
7013
7014 static void reset_traps_to_defaults(void)
7015 {
7016         /* This function is always called in a child shell
7017          * after fork (not vfork, NOMMU doesn't use this function).
7018          */
7019         IF_HUSH_TRAP(unsigned sig;)
7020         unsigned mask;
7021
7022         /* Child shells are not interactive.
7023          * SIGTTIN/SIGTTOU/SIGTSTP should not have special handling.
7024          * Testcase: (while :; do :; done) + ^Z should background.
7025          * Same goes for SIGTERM, SIGHUP, SIGINT.
7026          */
7027         mask = (G.special_sig_mask & SPECIAL_INTERACTIVE_SIGS) | G_fatal_sig_mask;
7028         if (!G_traps && !mask)
7029                 return; /* already no traps and no special sigs */
7030
7031         /* Switch off special sigs */
7032         switch_off_special_sigs(mask);
7033 # if ENABLE_HUSH_JOB
7034         G_fatal_sig_mask = 0;
7035 # endif
7036         G.special_sig_mask &= ~SPECIAL_INTERACTIVE_SIGS;
7037         /* SIGQUIT,SIGCHLD and maybe SPECIAL_JOBSTOP_SIGS
7038          * remain set in G.special_sig_mask */
7039
7040 # if ENABLE_HUSH_TRAP
7041         if (!G_traps)
7042                 return;
7043
7044         /* Reset all sigs to default except ones with empty traps */
7045         for (sig = 0; sig < NSIG; sig++) {
7046                 if (!G_traps[sig])
7047                         continue; /* no trap: nothing to do */
7048                 if (!G_traps[sig][0])
7049                         continue; /* empty trap: has to remain SIG_IGN */
7050                 /* sig has non-empty trap, reset it: */
7051                 free(G_traps[sig]);
7052                 G_traps[sig] = NULL;
7053                 /* There is no signal for trap 0 (EXIT) */
7054                 if (sig == 0)
7055                         continue;
7056                 install_sighandler(sig, pick_sighandler(sig));
7057         }
7058 # endif
7059 }
7060
7061 #else /* !BB_MMU */
7062
7063 static void re_execute_shell(char ***to_free, const char *s,
7064                 char *g_argv0, char **g_argv,
7065                 char **builtin_argv) NORETURN;
7066 static void re_execute_shell(char ***to_free, const char *s,
7067                 char *g_argv0, char **g_argv,
7068                 char **builtin_argv)
7069 {
7070 # define NOMMU_HACK_FMT ("-$%x:%x:%x:%x:%x:%llx" IF_HUSH_LOOPS(":%x"))
7071         /* delims + 2 * (number of bytes in printed hex numbers) */
7072         char param_buf[sizeof(NOMMU_HACK_FMT) + 2 * (sizeof(int)*6 + sizeof(long long)*1)];
7073         char *heredoc_argv[4];
7074         struct variable *cur;
7075 # if ENABLE_HUSH_FUNCTIONS
7076         struct function *funcp;
7077 # endif
7078         char **argv, **pp;
7079         unsigned cnt;
7080         unsigned long long empty_trap_mask;
7081
7082         if (!g_argv0) { /* heredoc */
7083                 argv = heredoc_argv;
7084                 argv[0] = (char *) G.argv0_for_re_execing;
7085                 argv[1] = (char *) "-<";
7086                 argv[2] = (char *) s;
7087                 argv[3] = NULL;
7088                 pp = &argv[3]; /* used as pointer to empty environment */
7089                 goto do_exec;
7090         }
7091
7092         cnt = 0;
7093         pp = builtin_argv;
7094         if (pp) while (*pp++)
7095                 cnt++;
7096
7097         empty_trap_mask = 0;
7098         if (G_traps) {
7099                 int sig;
7100                 for (sig = 1; sig < NSIG; sig++) {
7101                         if (G_traps[sig] && !G_traps[sig][0])
7102                                 empty_trap_mask |= 1LL << sig;
7103                 }
7104         }
7105
7106         sprintf(param_buf, NOMMU_HACK_FMT
7107                         , (unsigned) G.root_pid
7108                         , (unsigned) G.root_ppid
7109                         , (unsigned) G.last_bg_pid
7110                         , (unsigned) G.last_exitcode
7111                         , cnt
7112                         , empty_trap_mask
7113                         IF_HUSH_LOOPS(, G.depth_of_loop)
7114                         );
7115 # undef NOMMU_HACK_FMT
7116         /* 1:hush 2:-$<pid>:<pid>:<exitcode>:<etc...> <vars...> <funcs...>
7117          * 3:-c 4:<cmd> 5:<arg0> <argN...> 6:NULL
7118          */
7119         cnt += 6;
7120         for (cur = G.top_var; cur; cur = cur->next) {
7121                 if (!cur->flg_export || cur->flg_read_only)
7122                         cnt += 2;
7123         }
7124 # if ENABLE_HUSH_FUNCTIONS
7125         for (funcp = G.top_func; funcp; funcp = funcp->next)
7126                 cnt += 3;
7127 # endif
7128         pp = g_argv;
7129         while (*pp++)
7130                 cnt++;
7131         *to_free = argv = pp = xzalloc(sizeof(argv[0]) * cnt);
7132         *pp++ = (char *) G.argv0_for_re_execing;
7133         *pp++ = param_buf;
7134         for (cur = G.top_var; cur; cur = cur->next) {
7135                 if (strcmp(cur->varstr, hush_version_str) == 0)
7136                         continue;
7137                 if (cur->flg_read_only) {
7138                         *pp++ = (char *) "-R";
7139                         *pp++ = cur->varstr;
7140                 } else if (!cur->flg_export) {
7141                         *pp++ = (char *) "-V";
7142                         *pp++ = cur->varstr;
7143                 }
7144         }
7145 # if ENABLE_HUSH_FUNCTIONS
7146         for (funcp = G.top_func; funcp; funcp = funcp->next) {
7147                 *pp++ = (char *) "-F";
7148                 *pp++ = funcp->name;
7149                 *pp++ = funcp->body_as_string;
7150         }
7151 # endif
7152         /* We can pass activated traps here. Say, -Tnn:trap_string
7153          *
7154          * However, POSIX says that subshells reset signals with traps
7155          * to SIG_DFL.
7156          * I tested bash-3.2 and it not only does that with true subshells
7157          * of the form ( list ), but with any forked children shells.
7158          * I set trap "echo W" WINCH; and then tried:
7159          *
7160          * { echo 1; sleep 20; echo 2; } &
7161          * while true; do echo 1; sleep 20; echo 2; break; done &
7162          * true | { echo 1; sleep 20; echo 2; } | cat
7163          *
7164          * In all these cases sending SIGWINCH to the child shell
7165          * did not run the trap. If I add trap "echo V" WINCH;
7166          * _inside_ group (just before echo 1), it works.
7167          *
7168          * I conclude it means we don't need to pass active traps here.
7169          */
7170         *pp++ = (char *) "-c";
7171         *pp++ = (char *) s;
7172         if (builtin_argv) {
7173                 while (*++builtin_argv)
7174                         *pp++ = *builtin_argv;
7175                 *pp++ = (char *) "";
7176         }
7177         *pp++ = g_argv0;
7178         while (*g_argv)
7179                 *pp++ = *g_argv++;
7180         /* *pp = NULL; - is already there */
7181         pp = environ;
7182
7183  do_exec:
7184         debug_printf_exec("re_execute_shell pid:%d cmd:'%s'\n", getpid(), s);
7185         /* Don't propagate SIG_IGN to the child */
7186         if (SPECIAL_JOBSTOP_SIGS != 0)
7187                 switch_off_special_sigs(G.special_sig_mask & SPECIAL_JOBSTOP_SIGS);
7188         execve(bb_busybox_exec_path, argv, pp);
7189         /* Fallback. Useful for init=/bin/hush usage etc */
7190         if (argv[0][0] == '/')
7191                 execve(argv[0], argv, pp);
7192         xfunc_error_retval = 127;
7193         bb_error_msg_and_die("can't re-execute the shell");
7194 }
7195 #endif  /* !BB_MMU */
7196
7197
7198 static int run_and_free_list(struct pipe *pi);
7199
7200 /* Executing from string: eval, sh -c '...'
7201  *          or from file: /etc/profile, . file, sh <script>, sh (intereactive)
7202  * end_trigger controls how often we stop parsing
7203  * NUL: parse all, execute, return
7204  * ';': parse till ';' or newline, execute, repeat till EOF
7205  */
7206 static void parse_and_run_stream(struct in_str *inp, int end_trigger)
7207 {
7208         /* Why we need empty flag?
7209          * An obscure corner case "false; ``; echo $?":
7210          * empty command in `` should still set $? to 0.
7211          * But we can't just set $? to 0 at the start,
7212          * this breaks "false; echo `echo $?`" case.
7213          */
7214         bool empty = 1;
7215         while (1) {
7216                 struct pipe *pipe_list;
7217
7218 #if ENABLE_HUSH_INTERACTIVE
7219                 if (end_trigger == ';') {
7220                         G.promptmode = 0; /* PS1 */
7221                         debug_printf_prompt("%s promptmode=%d\n", __func__, G.promptmode);
7222                 }
7223 #endif
7224                 pipe_list = parse_stream(NULL, NULL, inp, end_trigger);
7225                 if (!pipe_list || pipe_list == ERR_PTR) { /* EOF/error */
7226                         /* If we are in "big" script
7227                          * (not in `cmd` or something similar)...
7228                          */
7229                         if (pipe_list == ERR_PTR && end_trigger == ';') {
7230                                 /* Discard cached input (rest of line) */
7231                                 int ch = inp->last_char;
7232                                 while (ch != EOF && ch != '\n') {
7233                                         //bb_error_msg("Discarded:'%c'", ch);
7234                                         ch = i_getch(inp);
7235                                 }
7236                                 /* Force prompt */
7237                                 inp->p = NULL;
7238                                 /* This stream isn't empty */
7239                                 empty = 0;
7240                                 continue;
7241                         }
7242                         if (!pipe_list && empty)
7243                                 G.last_exitcode = 0;
7244                         break;
7245                 }
7246                 debug_print_tree(pipe_list, 0);
7247                 debug_printf_exec("parse_and_run_stream: run_and_free_list\n");
7248                 run_and_free_list(pipe_list);
7249                 empty = 0;
7250                 if (G_flag_return_in_progress == 1)
7251                         break;
7252         }
7253 }
7254
7255 static void parse_and_run_string(const char *s)
7256 {
7257         struct in_str input;
7258         //IF_HUSH_LINENO_VAR(unsigned sv = G.lineno;)
7259
7260         setup_string_in_str(&input, s);
7261         parse_and_run_stream(&input, '\0');
7262         //IF_HUSH_LINENO_VAR(G.lineno = sv;)
7263 }
7264
7265 static void parse_and_run_file(HFILE *fp)
7266 {
7267         struct in_str input;
7268         IF_HUSH_LINENO_VAR(unsigned sv = G.lineno;)
7269
7270         IF_HUSH_LINENO_VAR(G.lineno = 1;)
7271         setup_file_in_str(&input, fp);
7272         parse_and_run_stream(&input, ';');
7273         IF_HUSH_LINENO_VAR(G.lineno = sv;)
7274 }
7275
7276 #if ENABLE_HUSH_TICK
7277 static int generate_stream_from_string(const char *s, pid_t *pid_p)
7278 {
7279         pid_t pid;
7280         int channel[2];
7281 # if !BB_MMU
7282         char **to_free = NULL;
7283 # endif
7284
7285         xpipe(channel);
7286         pid = BB_MMU ? xfork() : xvfork();
7287         if (pid == 0) { /* child */
7288                 disable_restore_tty_pgrp_on_exit();
7289                 /* Process substitution is not considered to be usual
7290                  * 'command execution'.
7291                  * SUSv3 says ctrl-Z should be ignored, ctrl-C should not.
7292                  */
7293                 bb_signals(0
7294                         + (1 << SIGTSTP)
7295                         + (1 << SIGTTIN)
7296                         + (1 << SIGTTOU)
7297                         , SIG_IGN);
7298                 close(channel[0]); /* NB: close _first_, then move fd! */
7299                 xmove_fd(channel[1], 1);
7300 # if ENABLE_HUSH_TRAP
7301                 /* Awful hack for `trap` or $(trap).
7302                  *
7303                  * http://www.opengroup.org/onlinepubs/009695399/utilities/trap.html
7304                  * contains an example where "trap" is executed in a subshell:
7305                  *
7306                  * save_traps=$(trap)
7307                  * ...
7308                  * eval "$save_traps"
7309                  *
7310                  * Standard does not say that "trap" in subshell shall print
7311                  * parent shell's traps. It only says that its output
7312                  * must have suitable form, but then, in the above example
7313                  * (which is not supposed to be normative), it implies that.
7314                  *
7315                  * bash (and probably other shell) does implement it
7316                  * (traps are reset to defaults, but "trap" still shows them),
7317                  * but as a result, "trap" logic is hopelessly messed up:
7318                  *
7319                  * # trap
7320                  * trap -- 'echo Ho' SIGWINCH  <--- we have a handler
7321                  * # (trap)        <--- trap is in subshell - no output (correct, traps are reset)
7322                  * # true | trap   <--- trap is in subshell - no output (ditto)
7323                  * # echo `true | trap`    <--- in subshell - output (but traps are reset!)
7324                  * trap -- 'echo Ho' SIGWINCH
7325                  * # echo `(trap)`         <--- in subshell in subshell - output
7326                  * trap -- 'echo Ho' SIGWINCH
7327                  * # echo `true | (trap)`  <--- in subshell in subshell in subshell - output!
7328                  * trap -- 'echo Ho' SIGWINCH
7329                  *
7330                  * The rules when to forget and when to not forget traps
7331                  * get really complex and nonsensical.
7332                  *
7333                  * Our solution: ONLY bare $(trap) or `trap` is special.
7334                  */
7335                 s = skip_whitespace(s);
7336                 if (is_prefixed_with(s, "trap")
7337                  && skip_whitespace(s + 4)[0] == '\0'
7338                 ) {
7339                         static const char *const argv[] = { NULL, NULL };
7340                         builtin_trap((char**)argv);
7341                         fflush_all(); /* important */
7342                         _exit(0);
7343                 }
7344 # endif
7345 # if BB_MMU
7346                 /* Prevent it from trying to handle ctrl-z etc */
7347                 IF_HUSH_JOB(G.run_list_level = 1;)
7348                 CLEAR_RANDOM_T(&G.random_gen); /* or else $RANDOM repeats in child */
7349                 reset_traps_to_defaults();
7350                 IF_HUSH_MODE_X(G.x_mode_depth++;)
7351                 //bb_error_msg("%s: ++x_mode_depth=%d", __func__, G.x_mode_depth);
7352                 parse_and_run_string(s);
7353                 _exit(G.last_exitcode);
7354 # else
7355         /* We re-execute after vfork on NOMMU. This makes this script safe:
7356          * yes "0123456789012345678901234567890" | dd bs=32 count=64k >BIG
7357          * huge=`cat BIG` # was blocking here forever
7358          * echo OK
7359          */
7360                 re_execute_shell(&to_free,
7361                                 s,
7362                                 G.global_argv[0],
7363                                 G.global_argv + 1,
7364                                 NULL);
7365 # endif
7366         }
7367
7368         /* parent */
7369         *pid_p = pid;
7370 # if ENABLE_HUSH_FAST
7371         G.count_SIGCHLD++;
7372 //bb_error_msg("[%d] fork in generate_stream_from_string:"
7373 //              " G.count_SIGCHLD:%d G.handled_SIGCHLD:%d",
7374 //              getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
7375 # endif
7376         enable_restore_tty_pgrp_on_exit();
7377 # if !BB_MMU
7378         free(to_free);
7379 # endif
7380         close(channel[1]);
7381         return channel[0];
7382 }
7383
7384 /* Return code is exit status of the process that is run. */
7385 static int process_command_subs(o_string *dest, const char *s)
7386 {
7387         FILE *fp;
7388         pid_t pid;
7389         int status, ch, eol_cnt;
7390
7391         fp = xfdopen_for_read(generate_stream_from_string(s, &pid));
7392
7393         /* Now send results of command back into original context */
7394         eol_cnt = 0;
7395         while ((ch = getc(fp)) != EOF) {
7396                 if (ch == '\0')
7397                         continue;
7398                 if (ch == '\n') {
7399                         eol_cnt++;
7400                         continue;
7401                 }
7402                 while (eol_cnt) {
7403                         o_addchr(dest, '\n');
7404                         eol_cnt--;
7405                 }
7406                 o_addQchr(dest, ch);
7407         }
7408
7409         debug_printf("done reading from `cmd` pipe, closing it\n");
7410         fclose(fp);
7411         /* We need to extract exitcode. Test case
7412          * "true; echo `sleep 1; false` $?"
7413          * should print 1 */
7414         safe_waitpid(pid, &status, 0);
7415         debug_printf("child exited. returning its exitcode:%d\n", WEXITSTATUS(status));
7416         return WEXITSTATUS(status);
7417 }
7418 #endif /* ENABLE_HUSH_TICK */
7419
7420
7421 static void setup_heredoc(struct redir_struct *redir)
7422 {
7423         struct fd_pair pair;
7424         pid_t pid;
7425         int len, written;
7426         /* the _body_ of heredoc (misleading field name) */
7427         const char *heredoc = redir->rd_filename;
7428         char *expanded;
7429 #if !BB_MMU
7430         char **to_free;
7431 #endif
7432
7433         expanded = NULL;
7434         if (!(redir->rd_dup & HEREDOC_QUOTED)) {
7435                 expanded = encode_then_expand_string(heredoc);
7436                 if (expanded)
7437                         heredoc = expanded;
7438         }
7439         len = strlen(heredoc);
7440
7441         close(redir->rd_fd); /* often saves dup2+close in xmove_fd */
7442         xpiped_pair(pair);
7443         xmove_fd(pair.rd, redir->rd_fd);
7444
7445         /* Try writing without forking. Newer kernels have
7446          * dynamically growing pipes. Must use non-blocking write! */
7447         ndelay_on(pair.wr);
7448         while (1) {
7449                 written = write(pair.wr, heredoc, len);
7450                 if (written <= 0)
7451                         break;
7452                 len -= written;
7453                 if (len == 0) {
7454                         close(pair.wr);
7455                         free(expanded);
7456                         return;
7457                 }
7458                 heredoc += written;
7459         }
7460         ndelay_off(pair.wr);
7461
7462         /* Okay, pipe buffer was not big enough */
7463         /* Note: we must not create a stray child (bastard? :)
7464          * for the unsuspecting parent process. Child creates a grandchild
7465          * and exits before parent execs the process which consumes heredoc
7466          * (that exec happens after we return from this function) */
7467 #if !BB_MMU
7468         to_free = NULL;
7469 #endif
7470         pid = xvfork();
7471         if (pid == 0) {
7472                 /* child */
7473                 disable_restore_tty_pgrp_on_exit();
7474                 pid = BB_MMU ? xfork() : xvfork();
7475                 if (pid != 0)
7476                         _exit(0);
7477                 /* grandchild */
7478                 close(redir->rd_fd); /* read side of the pipe */
7479 #if BB_MMU
7480                 full_write(pair.wr, heredoc, len); /* may loop or block */
7481                 _exit(0);
7482 #else
7483                 /* Delegate blocking writes to another process */
7484                 xmove_fd(pair.wr, STDOUT_FILENO);
7485                 re_execute_shell(&to_free, heredoc, NULL, NULL, NULL);
7486 #endif
7487         }
7488         /* parent */
7489 #if ENABLE_HUSH_FAST
7490         G.count_SIGCHLD++;
7491 //bb_error_msg("[%d] fork in setup_heredoc: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
7492 #endif
7493         enable_restore_tty_pgrp_on_exit();
7494 #if !BB_MMU
7495         free(to_free);
7496 #endif
7497         close(pair.wr);
7498         free(expanded);
7499         wait(NULL); /* wait till child has died */
7500 }
7501
7502 struct squirrel {
7503         int orig_fd;
7504         int moved_to;
7505         /* moved_to = n: fd was moved to n; restore back to orig_fd after redir */
7506         /* moved_to = -1: fd was opened by redirect; close orig_fd after redir */
7507 };
7508
7509 static struct squirrel *append_squirrel(struct squirrel *sq, int i, int orig, int moved)
7510 {
7511         sq = xrealloc(sq, (i + 2) * sizeof(sq[0]));
7512         sq[i].orig_fd = orig;
7513         sq[i].moved_to = moved;
7514         sq[i+1].orig_fd = -1; /* end marker */
7515         return sq;
7516 }
7517
7518 static struct squirrel *add_squirrel(struct squirrel *sq, int fd, int avoid_fd)
7519 {
7520         int moved_to;
7521         int i;
7522
7523         i = 0;
7524         if (sq) for (; sq[i].orig_fd >= 0; i++) {
7525                 /* If we collide with an already moved fd... */
7526                 if (fd == sq[i].moved_to) {
7527                         sq[i].moved_to = dup_CLOEXEC(sq[i].moved_to, avoid_fd);
7528                         debug_printf_redir("redirect_fd %d: already busy, moving to %d\n", fd, sq[i].moved_to);
7529                         if (sq[i].moved_to < 0) /* what? */
7530                                 xfunc_die();
7531                         return sq;
7532                 }
7533                 if (fd == sq[i].orig_fd) {
7534                         /* Example: echo Hello >/dev/null 1>&2 */
7535                         debug_printf_redir("redirect_fd %d: already moved\n", fd);
7536                         return sq;
7537                 }
7538         }
7539
7540         /* If this fd is open, we move and remember it; if it's closed, moved_to = -1 */
7541         moved_to = dup_CLOEXEC(fd, avoid_fd);
7542         debug_printf_redir("redirect_fd %d: previous fd is moved to %d (-1 if it was closed)\n", fd, moved_to);
7543         if (moved_to < 0 && errno != EBADF)
7544                 xfunc_die();
7545         return append_squirrel(sq, i, fd, moved_to);
7546 }
7547
7548 static struct squirrel *add_squirrel_closed(struct squirrel *sq, int fd)
7549 {
7550         int i;
7551
7552         i = 0;
7553         if (sq) for (; sq[i].orig_fd >= 0; i++) {
7554                 /* If we collide with an already moved fd... */
7555                 if (fd == sq[i].orig_fd) {
7556                         /* Examples:
7557                          * "echo 3>FILE 3>&- 3>FILE"
7558                          * "echo 3>&- 3>FILE"
7559                          * No need for last redirect to insert
7560                          * another "need to close 3" indicator.
7561                          */
7562                         debug_printf_redir("redirect_fd %d: already moved or closed\n", fd);
7563                         return sq;
7564                 }
7565         }
7566
7567         debug_printf_redir("redirect_fd %d: previous fd was closed\n", fd);
7568         return append_squirrel(sq, i, fd, -1);
7569 }
7570
7571 /* fd: redirect wants this fd to be used (e.g. 3>file).
7572  * Move all conflicting internally used fds,
7573  * and remember them so that we can restore them later.
7574  */
7575 static int save_fd_on_redirect(int fd, int avoid_fd, struct squirrel **sqp)
7576 {
7577         if (avoid_fd < 9) /* the important case here is that it can be -1 */
7578                 avoid_fd = 9;
7579
7580 #if ENABLE_HUSH_INTERACTIVE
7581         if (fd == G.interactive_fd) {
7582                 /* Testcase: "ls -l /proc/$$/fd 255>&-" should work */
7583                 G.interactive_fd = xdup_CLOEXEC_and_close(G.interactive_fd, avoid_fd);
7584                 debug_printf_redir("redirect_fd %d: matches interactive_fd, moving it to %d\n", fd, G.interactive_fd);
7585                 return 1; /* "we closed fd" */
7586         }
7587 #endif
7588         /* Are we called from setup_redirects(squirrel==NULL)
7589          * in redirect in a [v]forked child?
7590          */
7591         if (sqp == NULL) {
7592                 /* No need to move script fds.
7593                  * For NOMMU case, it's actively wrong: we'd change ->fd
7594                  * fields in memory for the parent, but parent's fds
7595                  * aren't be moved, it would use wrong fd!
7596                  * Reproducer: "cmd 3>FILE" in script.
7597                  * If we would call move_HFILEs_on_redirect(), child would:
7598                  *  fcntl64(3, F_DUPFD_CLOEXEC, 10)   = 10
7599                  *  close(3)                          = 0
7600                  * and change ->fd to 10 if fd#3 is a script fd. WRONG.
7601                  */
7602                 //bb_error_msg("sqp == NULL: [v]forked child");
7603                 return 0;
7604         }
7605
7606         /* If this one of script's fds? */
7607         if (move_HFILEs_on_redirect(fd, avoid_fd))
7608                 return 1; /* yes. "we closed fd" (actually moved it) */
7609
7610         /* Are we called for "exec 3>FILE"? Came through
7611          * redirect_and_varexp_helper(squirrel=ERR_PTR) -> setup_redirects(ERR_PTR)
7612          * This case used to fail for this script:
7613          *  exec 3>FILE
7614          *  echo Ok
7615          *  ...100000 more lines...
7616          *  echo Ok
7617          * as follows:
7618          *  read(3, "exec 3>FILE\necho Ok\necho Ok"..., 1024) = 1024
7619          *  open("FILE", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 4
7620          *  dup2(4, 3)                        = 3
7621          *  ^^^^^^^^ oops, we lost fd#3 opened to our script!
7622          *  close(4)                          = 0
7623          *  write(1, "Ok\n", 3)               = 3
7624          *  ...                               = 3
7625          *  write(1, "Ok\n", 3)               = 3
7626          *  read(3, 0x94fbc08, 1024)          = -1 EBADF (Bad file descriptor)
7627          *  ^^^^^^^^ oops, wrong fd!!!
7628          * With this case separate from sqp == NULL and *after* move_HFILEs,
7629          * it now works:
7630          */
7631         if (sqp == ERR_PTR) {
7632                 /* Don't preserve redirected fds: exec is _meant_ to change these */
7633                 //bb_error_msg("sqp == ERR_PTR: exec >FILE");
7634                 return 0;
7635         }
7636
7637         /* Check whether it collides with any open fds (e.g. stdio), save fds as needed */
7638         *sqp = add_squirrel(*sqp, fd, avoid_fd);
7639         return 0; /* "we did not close fd" */
7640 }
7641
7642 static void restore_redirects(struct squirrel *sq)
7643 {
7644         if (sq) {
7645                 int i;
7646                 for (i = 0; sq[i].orig_fd >= 0; i++) {
7647                         if (sq[i].moved_to >= 0) {
7648                                 /* We simply die on error */
7649                                 debug_printf_redir("restoring redirected fd from %d to %d\n", sq[i].moved_to, sq[i].orig_fd);
7650                                 xmove_fd(sq[i].moved_to, sq[i].orig_fd);
7651                         } else {
7652                                 /* cmd1 9>FILE; cmd2_should_see_fd9_closed */
7653                                 debug_printf_redir("restoring redirected fd %d: closing it\n", sq[i].orig_fd);
7654                                 close(sq[i].orig_fd);
7655                         }
7656                 }
7657                 free(sq);
7658         }
7659
7660         /* If moved, G.interactive_fd stays on new fd, not restoring it */
7661 }
7662
7663 #if ENABLE_FEATURE_SH_STANDALONE && BB_MMU
7664 static void close_saved_fds_and_FILE_fds(void)
7665 {
7666         if (G_interactive_fd)
7667                 close(G_interactive_fd);
7668         close_all_HFILE_list();
7669 }
7670 #endif
7671
7672 static int internally_opened_fd(int fd, struct squirrel *sq)
7673 {
7674         int i;
7675
7676 #if ENABLE_HUSH_INTERACTIVE
7677         if (fd == G.interactive_fd)
7678                 return 1;
7679 #endif
7680         /* If this one of script's fds? */
7681         if (fd_in_HFILEs(fd))
7682                 return 1;
7683
7684         if (sq) for (i = 0; sq[i].orig_fd >= 0; i++) {
7685                 if (fd == sq[i].moved_to)
7686                         return 1;
7687         }
7688         return 0;
7689 }
7690
7691 /* squirrel != NULL means we squirrel away copies of stdin, stdout,
7692  * and stderr if they are redirected. */
7693 static int setup_redirects(struct command *prog, struct squirrel **sqp)
7694 {
7695         struct redir_struct *redir;
7696
7697         for (redir = prog->redirects; redir; redir = redir->next) {
7698                 int newfd;
7699                 int closed;
7700
7701                 if (redir->rd_type == REDIRECT_HEREDOC2) {
7702                         /* "rd_fd<<HERE" case */
7703                         save_fd_on_redirect(redir->rd_fd, /*avoid:*/ 0, sqp);
7704                         /* for REDIRECT_HEREDOC2, rd_filename holds _contents_
7705                          * of the heredoc */
7706                         debug_printf_redir("set heredoc '%s'\n",
7707                                         redir->rd_filename);
7708                         setup_heredoc(redir);
7709                         continue;
7710                 }
7711
7712                 if (redir->rd_dup == REDIRFD_TO_FILE) {
7713                         /* "rd_fd<*>file" case (<*> is <,>,>>,<>) */
7714                         char *p;
7715                         int mode;
7716
7717                         if (redir->rd_filename == NULL) {
7718                                 /* Examples:
7719                                  * "cmd >" (no filename)
7720                                  * "cmd > <file" (2nd redirect starts too early)
7721                                  */
7722                                 syntax_error("invalid redirect");
7723                                 continue;
7724                         }
7725                         mode = redir_table[redir->rd_type].mode;
7726                         p = expand_string_to_string(redir->rd_filename,
7727                                 EXP_FLAG_ESC_GLOB_CHARS, /*unbackslash:*/ 1);
7728                         newfd = open_or_warn(p, mode);
7729                         free(p);
7730                         if (newfd < 0) {
7731                                 /* Error message from open_or_warn can be lost
7732                                  * if stderr has been redirected, but bash
7733                                  * and ash both lose it as well
7734                                  * (though zsh doesn't!)
7735                                  */
7736                                 return 1;
7737                         }
7738                         if (newfd == redir->rd_fd && sqp) {
7739                                 /* open() gave us precisely the fd we wanted.
7740                                  * This means that this fd was not busy
7741                                  * (not opened to anywhere).
7742                                  * Remember to close it on restore:
7743                                  */
7744                                 *sqp = add_squirrel_closed(*sqp, newfd);
7745                                 debug_printf_redir("redir to previously closed fd %d\n", newfd);
7746                         }
7747                 } else {
7748                         /* "rd_fd>&rd_dup" or "rd_fd>&-" case */
7749                         newfd = redir->rd_dup;
7750                 }
7751
7752                 if (newfd == redir->rd_fd)
7753                         continue;
7754
7755                 /* if "N>FILE": move newfd to redir->rd_fd */
7756                 /* if "N>&M": dup newfd to redir->rd_fd */
7757                 /* if "N>&-": close redir->rd_fd (newfd is REDIRFD_CLOSE) */
7758
7759                 closed = save_fd_on_redirect(redir->rd_fd, /*avoid:*/ newfd, sqp);
7760                 if (newfd == REDIRFD_CLOSE) {
7761                         /* "N>&-" means "close me" */
7762                         if (!closed) {
7763                                 /* ^^^ optimization: saving may already
7764                                  * have closed it. If not... */
7765                                 close(redir->rd_fd);
7766                         }
7767                         /* Sometimes we do another close on restore, getting EBADF.
7768                          * Consider "echo 3>FILE 3>&-"
7769                          * first redirect remembers "need to close 3",
7770                          * and second redirect closes 3! Restore code then closes 3 again.
7771                          */
7772                 } else {
7773                         /* if newfd is a script fd or saved fd, simulate EBADF */
7774                         if (internally_opened_fd(newfd, sqp && sqp != ERR_PTR ? *sqp : NULL)) {
7775                                 //errno = EBADF;
7776                                 //bb_perror_msg_and_die("can't duplicate file descriptor");
7777                                 newfd = -1; /* same effect as code above */
7778                         }
7779                         xdup2(newfd, redir->rd_fd);
7780                         if (redir->rd_dup == REDIRFD_TO_FILE)
7781                                 /* "rd_fd > FILE" */
7782                                 close(newfd);
7783                         /* else: "rd_fd > rd_dup" */
7784                 }
7785         }
7786         return 0;
7787 }
7788
7789 static char *find_in_path(const char *arg)
7790 {
7791         char *ret = NULL;
7792         const char *PATH = get_local_var_value("PATH");
7793
7794         if (!PATH)
7795                 return NULL;
7796
7797         while (1) {
7798                 const char *end = strchrnul(PATH, ':');
7799                 int sz = end - PATH; /* must be int! */
7800
7801                 free(ret);
7802                 if (sz != 0) {
7803                         ret = xasprintf("%.*s/%s", sz, PATH, arg);
7804                 } else {
7805                         /* We have xxx::yyyy in $PATH,
7806                          * it means "use current dir" */
7807                         ret = xstrdup(arg);
7808                 }
7809                 if (access(ret, F_OK) == 0)
7810                         break;
7811
7812                 if (*end == '\0') {
7813                         free(ret);
7814                         return NULL;
7815                 }
7816                 PATH = end + 1;
7817         }
7818
7819         return ret;
7820 }
7821
7822 static const struct built_in_command *find_builtin_helper(const char *name,
7823                 const struct built_in_command *x,
7824                 const struct built_in_command *end)
7825 {
7826         while (x != end) {
7827                 if (strcmp(name, x->b_cmd) != 0) {
7828                         x++;
7829                         continue;
7830                 }
7831                 debug_printf_exec("found builtin '%s'\n", name);
7832                 return x;
7833         }
7834         return NULL;
7835 }
7836 static const struct built_in_command *find_builtin1(const char *name)
7837 {
7838         return find_builtin_helper(name, bltins1, &bltins1[ARRAY_SIZE(bltins1)]);
7839 }
7840 static const struct built_in_command *find_builtin(const char *name)
7841 {
7842         const struct built_in_command *x = find_builtin1(name);
7843         if (x)
7844                 return x;
7845         return find_builtin_helper(name, bltins2, &bltins2[ARRAY_SIZE(bltins2)]);
7846 }
7847
7848 static void remove_nested_vars(void)
7849 {
7850         struct variable *cur;
7851         struct variable **cur_pp;
7852
7853         cur_pp = &G.top_var;
7854         while ((cur = *cur_pp) != NULL) {
7855                 if (cur->var_nest_level <= G.var_nest_level) {
7856                         cur_pp = &cur->next;
7857                         continue;
7858                 }
7859                 /* Unexport */
7860                 if (cur->flg_export) {
7861                         debug_printf_env("unexporting nested '%s'/%u\n", cur->varstr, cur->var_nest_level);
7862                         bb_unsetenv(cur->varstr);
7863                 }
7864                 /* Remove from global list */
7865                 *cur_pp = cur->next;
7866                 /* Free */
7867                 if (!cur->max_len) {
7868                         debug_printf_env("freeing nested '%s'/%u\n", cur->varstr, cur->var_nest_level);
7869                         free(cur->varstr);
7870                 }
7871                 free(cur);
7872         }
7873 }
7874
7875 static void enter_var_nest_level(void)
7876 {
7877         G.var_nest_level++;
7878         debug_printf_env("var_nest_level++ %u\n", G.var_nest_level);
7879
7880         /* Try: f() { echo -n .; f; }; f
7881          * struct variable::var_nest_level is uint16_t,
7882          * thus limiting recursion to < 2^16.
7883          * In any case, with 8 Mbyte stack SEGV happens
7884          * not too long after 2^16 recursions anyway.
7885          */
7886         if (G.var_nest_level > 0xff00)
7887                 bb_error_msg_and_die("fatal recursion (depth %u)", G.var_nest_level);
7888 }
7889
7890 static void leave_var_nest_level(void)
7891 {
7892         G.var_nest_level--;
7893         debug_printf_env("var_nest_level-- %u\n", G.var_nest_level);
7894         if (HUSH_DEBUG && (int)G.var_nest_level < 0)
7895                 bb_error_msg_and_die("BUG: nesting underflow");
7896
7897         remove_nested_vars();
7898 }
7899
7900 #if ENABLE_HUSH_FUNCTIONS
7901 static struct function **find_function_slot(const char *name)
7902 {
7903         struct function *funcp;
7904         struct function **funcpp = &G.top_func;
7905
7906         while ((funcp = *funcpp) != NULL) {
7907                 if (strcmp(name, funcp->name) == 0) {
7908                         debug_printf_exec("found function '%s'\n", name);
7909                         break;
7910                 }
7911                 funcpp = &funcp->next;
7912         }
7913         return funcpp;
7914 }
7915
7916 static ALWAYS_INLINE const struct function *find_function(const char *name)
7917 {
7918         const struct function *funcp = *find_function_slot(name);
7919         return funcp;
7920 }
7921
7922 /* Note: takes ownership on name ptr */
7923 static struct function *new_function(char *name)
7924 {
7925         struct function **funcpp = find_function_slot(name);
7926         struct function *funcp = *funcpp;
7927
7928         if (funcp != NULL) {
7929                 struct command *cmd = funcp->parent_cmd;
7930                 debug_printf_exec("func %p parent_cmd %p\n", funcp, cmd);
7931                 if (!cmd) {
7932                         debug_printf_exec("freeing & replacing function '%s'\n", funcp->name);
7933                         free(funcp->name);
7934                         /* Note: if !funcp->body, do not free body_as_string!
7935                          * This is a special case of "-F name body" function:
7936                          * body_as_string was not malloced! */
7937                         if (funcp->body) {
7938                                 free_pipe_list(funcp->body);
7939 # if !BB_MMU
7940                                 free(funcp->body_as_string);
7941 # endif
7942                         }
7943                 } else {
7944                         debug_printf_exec("reinserting in tree & replacing function '%s'\n", funcp->name);
7945                         cmd->argv[0] = funcp->name;
7946                         cmd->group = funcp->body;
7947 # if !BB_MMU
7948                         cmd->group_as_string = funcp->body_as_string;
7949 # endif
7950                 }
7951         } else {
7952                 debug_printf_exec("remembering new function '%s'\n", name);
7953                 funcp = *funcpp = xzalloc(sizeof(*funcp));
7954                 /*funcp->next = NULL;*/
7955         }
7956
7957         funcp->name = name;
7958         return funcp;
7959 }
7960
7961 # if ENABLE_HUSH_UNSET
7962 static void unset_func(const char *name)
7963 {
7964         struct function **funcpp = find_function_slot(name);
7965         struct function *funcp = *funcpp;
7966
7967         if (funcp != NULL) {
7968                 debug_printf_exec("freeing function '%s'\n", funcp->name);
7969                 *funcpp = funcp->next;
7970                 /* funcp is unlinked now, deleting it.
7971                  * Note: if !funcp->body, the function was created by
7972                  * "-F name body", do not free ->body_as_string
7973                  * and ->name as they were not malloced. */
7974                 if (funcp->body) {
7975                         free_pipe_list(funcp->body);
7976                         free(funcp->name);
7977 #  if !BB_MMU
7978                         free(funcp->body_as_string);
7979 #  endif
7980                 }
7981                 free(funcp);
7982         }
7983 }
7984 # endif
7985
7986 # if BB_MMU
7987 #define exec_function(to_free, funcp, argv) \
7988         exec_function(funcp, argv)
7989 # endif
7990 static void exec_function(char ***to_free,
7991                 const struct function *funcp,
7992                 char **argv) NORETURN;
7993 static void exec_function(char ***to_free,
7994                 const struct function *funcp,
7995                 char **argv)
7996 {
7997 # if BB_MMU
7998         int n;
7999
8000         argv[0] = G.global_argv[0];
8001         G.global_argv = argv;
8002         G.global_argc = n = 1 + string_array_len(argv + 1);
8003
8004 // Example when we are here: "cmd | func"
8005 // func will run with saved-redirect fds open.
8006 // $ f() { echo /proc/self/fd/*; }
8007 // $ true | f
8008 // /proc/self/fd/0 /proc/self/fd/1 /proc/self/fd/2 /proc/self/fd/255 /proc/self/fd/3
8009 // stdio^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ G_interactive_fd^ DIR fd for glob
8010 // Same in script:
8011 // $ . ./SCRIPT
8012 // /proc/self/fd/0 /proc/self/fd/1 /proc/self/fd/2 /proc/self/fd/255 /proc/self/fd/3 /proc/self/fd/4
8013 // stdio^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ G_interactive_fd^ opened ./SCRIPT DIR fd for glob
8014 // They are CLOEXEC so external programs won't see them, but
8015 // for "more correctness" we might want to close those extra fds here:
8016 //?     close_saved_fds_and_FILE_fds();
8017
8018         /* "we are in a function, ok to use return" */
8019         G_flag_return_in_progress = -1;
8020         enter_var_nest_level();
8021         IF_HUSH_LOCAL(G.func_nest_level++;)
8022
8023         /* On MMU, funcp->body is always non-NULL */
8024         n = run_list(funcp->body);
8025         fflush_all();
8026         _exit(n);
8027 # else
8028 //?     close_saved_fds_and_FILE_fds();
8029
8030 //TODO: check whether "true | func_with_return" works
8031
8032         re_execute_shell(to_free,
8033                         funcp->body_as_string,
8034                         G.global_argv[0],
8035                         argv + 1,
8036                         NULL);
8037 # endif
8038 }
8039
8040 static int run_function(const struct function *funcp, char **argv)
8041 {
8042         int rc;
8043         save_arg_t sv;
8044         smallint sv_flg;
8045
8046         save_and_replace_G_args(&sv, argv);
8047
8048         /* "We are in function, ok to use return" */
8049         sv_flg = G_flag_return_in_progress;
8050         G_flag_return_in_progress = -1;
8051
8052         /* Make "local" variables properly shadow previous ones */
8053         IF_HUSH_LOCAL(enter_var_nest_level();)
8054         IF_HUSH_LOCAL(G.func_nest_level++;)
8055
8056         /* On MMU, funcp->body is always non-NULL */
8057 # if !BB_MMU
8058         if (!funcp->body) {
8059                 /* Function defined by -F */
8060                 parse_and_run_string(funcp->body_as_string);
8061                 rc = G.last_exitcode;
8062         } else
8063 # endif
8064         {
8065                 rc = run_list(funcp->body);
8066         }
8067
8068         IF_HUSH_LOCAL(G.func_nest_level--;)
8069         IF_HUSH_LOCAL(leave_var_nest_level();)
8070
8071         G_flag_return_in_progress = sv_flg;
8072
8073         restore_G_args(&sv, argv);
8074
8075         return rc;
8076 }
8077 #endif /* ENABLE_HUSH_FUNCTIONS */
8078
8079
8080 #if BB_MMU
8081 #define exec_builtin(to_free, x, argv) \
8082         exec_builtin(x, argv)
8083 #else
8084 #define exec_builtin(to_free, x, argv) \
8085         exec_builtin(to_free, argv)
8086 #endif
8087 static void exec_builtin(char ***to_free,
8088                 const struct built_in_command *x,
8089                 char **argv) NORETURN;
8090 static void exec_builtin(char ***to_free,
8091                 const struct built_in_command *x,
8092                 char **argv)
8093 {
8094 #if BB_MMU
8095         int rcode;
8096         fflush_all();
8097 //?     close_saved_fds_and_FILE_fds();
8098         rcode = x->b_function(argv);
8099         fflush_all();
8100         _exit(rcode);
8101 #else
8102         fflush_all();
8103         /* On NOMMU, we must never block!
8104          * Example: { sleep 99 | read line; } & echo Ok
8105          */
8106         re_execute_shell(to_free,
8107                         argv[0],
8108                         G.global_argv[0],
8109                         G.global_argv + 1,
8110                         argv);
8111 #endif
8112 }
8113
8114
8115 static void execvp_or_die(char **argv) NORETURN;
8116 static void execvp_or_die(char **argv)
8117 {
8118         int e;
8119         debug_printf_exec("execing '%s'\n", argv[0]);
8120         /* Don't propagate SIG_IGN to the child */
8121         if (SPECIAL_JOBSTOP_SIGS != 0)
8122                 switch_off_special_sigs(G.special_sig_mask & SPECIAL_JOBSTOP_SIGS);
8123         execvp(argv[0], argv);
8124         e = 2;
8125         if (errno == EACCES) e = 126;
8126         if (errno == ENOENT) e = 127;
8127         bb_perror_msg("can't execute '%s'", argv[0]);
8128         _exit(e);
8129 }
8130
8131 #if ENABLE_HUSH_MODE_X
8132 static void x_mode_print_optionally_squoted(const char *str)
8133 {
8134         unsigned len;
8135         const char *cp;
8136
8137         cp = str;
8138
8139         /* the set of chars which-cause-string-to-be-squoted mimics bash */
8140         /* test a char with: bash -c 'set -x; echo "CH"' */
8141         if (str[strcspn(str, "\\\"'`$(){}[]<>;#&|~*?!^"
8142                         " " "\001\002\003\004\005\006\007"
8143                         "\010\011\012\013\014\015\016\017"
8144                         "\020\021\022\023\024\025\026\027"
8145                         "\030\031\032\033\034\035\036\037"
8146                         )
8147                 ] == '\0'
8148         ) {
8149                 /* string has no special chars */
8150                 x_mode_addstr(str);
8151                 return;
8152         }
8153
8154         cp = str;
8155         for (;;) {
8156                 /* print '....' up to EOL or first squote */
8157                 len = (int)(strchrnul(cp, '\'') - cp);
8158                 if (len != 0) {
8159                         x_mode_addchr('\'');
8160                         x_mode_addblock(cp, len);
8161                         x_mode_addchr('\'');
8162                         cp += len;
8163                 }
8164                 if (*cp == '\0')
8165                         break;
8166                 /* string contains squote(s), print them as \' */
8167                 x_mode_addchr('\\');
8168                 x_mode_addchr('\'');
8169                 cp++;
8170         }
8171 }
8172 static void dump_cmd_in_x_mode(char **argv)
8173 {
8174         if (G_x_mode && argv) {
8175                 unsigned n;
8176
8177                 /* "+[+++...][ cmd...]\n\0" */
8178                 x_mode_prefix();
8179                 n = 0;
8180                 while (argv[n]) {
8181                         x_mode_addchr(' ');
8182                         if (argv[n][0] == '\0') {
8183                                 x_mode_addchr('\'');
8184                                 x_mode_addchr('\'');
8185                         } else {
8186                                 x_mode_print_optionally_squoted(argv[n]);
8187                         }
8188                         n++;
8189                 }
8190                 x_mode_flush();
8191         }
8192 }
8193 #else
8194 # define dump_cmd_in_x_mode(argv) ((void)0)
8195 #endif
8196
8197 #if ENABLE_HUSH_COMMAND
8198 static void if_command_vV_print_and_exit(char opt_vV, char *cmd, const char *explanation)
8199 {
8200         char *to_free;
8201
8202         if (!opt_vV)
8203                 return;
8204
8205         to_free = NULL;
8206         if (!explanation) {
8207                 char *path = getenv("PATH");
8208                 explanation = to_free = find_executable(cmd, &path); /* path == NULL is ok */
8209                 if (!explanation)
8210                         _exit(1); /* PROG was not found */
8211                 if (opt_vV != 'V')
8212                         cmd = to_free; /* -v PROG prints "/path/to/PROG" */
8213         }
8214         printf((opt_vV == 'V') ? "%s is %s\n" : "%s\n", cmd, explanation);
8215         free(to_free);
8216         fflush_all();
8217         _exit(0);
8218 }
8219 #else
8220 # define if_command_vV_print_and_exit(a,b,c) ((void)0)
8221 #endif
8222
8223 #if BB_MMU
8224 #define pseudo_exec_argv(nommu_save, argv, assignment_cnt, argv_expanded) \
8225         pseudo_exec_argv(argv, assignment_cnt, argv_expanded)
8226 #define pseudo_exec(nommu_save, command, argv_expanded) \
8227         pseudo_exec(command, argv_expanded)
8228 #endif
8229
8230 /* Called after [v]fork() in run_pipe, or from builtin_exec.
8231  * Never returns.
8232  * Don't exit() here.  If you don't exec, use _exit instead.
8233  * The at_exit handlers apparently confuse the calling process,
8234  * in particular stdin handling. Not sure why? -- because of vfork! (vda)
8235  */
8236 static void pseudo_exec_argv(nommu_save_t *nommu_save,
8237                 char **argv, int assignment_cnt,
8238                 char **argv_expanded) NORETURN;
8239 static NOINLINE void pseudo_exec_argv(nommu_save_t *nommu_save,
8240                 char **argv, int assignment_cnt,
8241                 char **argv_expanded)
8242 {
8243         const struct built_in_command *x;
8244         struct variable **sv_shadowed;
8245         char **new_env;
8246         IF_HUSH_COMMAND(char opt_vV = 0;)
8247         IF_HUSH_FUNCTIONS(const struct function *funcp;)
8248
8249         new_env = expand_assignments(argv, assignment_cnt);
8250         dump_cmd_in_x_mode(new_env);
8251
8252         if (!argv[assignment_cnt]) {
8253                 /* Case when we are here: ... | var=val | ...
8254                  * (note that we do not exit early, i.e., do not optimize out
8255                  * expand_assignments(): think about ... | var=`sleep 1` | ...
8256                  */
8257                 free_strings(new_env);
8258                 _exit(EXIT_SUCCESS);
8259         }
8260
8261         sv_shadowed = G.shadowed_vars_pp;
8262 #if BB_MMU
8263         G.shadowed_vars_pp = NULL; /* "don't save, free them instead" */
8264 #else
8265         G.shadowed_vars_pp = &nommu_save->old_vars;
8266         G.var_nest_level++;
8267 #endif
8268         set_vars_and_save_old(new_env);
8269         G.shadowed_vars_pp = sv_shadowed;
8270
8271         if (argv_expanded) {
8272                 argv = argv_expanded;
8273         } else {
8274                 argv = expand_strvec_to_strvec(argv + assignment_cnt);
8275 #if !BB_MMU
8276                 nommu_save->argv = argv;
8277 #endif
8278         }
8279         dump_cmd_in_x_mode(argv);
8280
8281 #if ENABLE_FEATURE_SH_STANDALONE || BB_MMU
8282         if (strchr(argv[0], '/') != NULL)
8283                 goto skip;
8284 #endif
8285
8286 #if ENABLE_HUSH_FUNCTIONS
8287         /* Check if the command matches any functions (this goes before bltins) */
8288         funcp = find_function(argv[0]);
8289         if (funcp)
8290                 exec_function(&nommu_save->argv_from_re_execing, funcp, argv);
8291 #endif
8292
8293 #if ENABLE_HUSH_COMMAND
8294         /* "command BAR": run BAR without looking it up among functions
8295          * "command -v BAR": print "BAR" or "/path/to/BAR"; or exit 1
8296          * "command -V BAR": print "BAR is {a function,a shell builtin,/path/to/BAR}"
8297          */
8298         while (strcmp(argv[0], "command") == 0 && argv[1]) {
8299                 char *p;
8300
8301                 argv++;
8302                 p = *argv;
8303                 if (p[0] != '-' || !p[1])
8304                         continue; /* bash allows "command command command [-OPT] BAR" */
8305
8306                 for (;;) {
8307                         p++;
8308                         switch (*p) {
8309                         case '\0':
8310                                 argv++;
8311                                 p = *argv;
8312                                 if (p[0] != '-' || !p[1])
8313                                         goto after_opts;
8314                                 continue; /* next arg is also -opts, process it too */
8315                         case 'v':
8316                         case 'V':
8317                                 opt_vV = *p;
8318                                 continue;
8319                         default:
8320                                 bb_error_msg_and_die("%s: %s: invalid option", "command", argv[0]);
8321                         }
8322                 }
8323         }
8324  after_opts:
8325 # if ENABLE_HUSH_FUNCTIONS
8326         if (opt_vV && find_function(argv[0]))
8327                 if_command_vV_print_and_exit(opt_vV, argv[0], "a function");
8328 # endif
8329 #endif
8330
8331         /* Check if the command matches any of the builtins.
8332          * Depending on context, this might be redundant.  But it's
8333          * easier to waste a few CPU cycles than it is to figure out
8334          * if this is one of those cases.
8335          */
8336         /* Why "BB_MMU ? :" difference in logic? -
8337          * On NOMMU, it is more expensive to re-execute shell
8338          * just in order to run echo or test builtin.
8339          * It's better to skip it here and run corresponding
8340          * non-builtin later. */
8341         x = BB_MMU ? find_builtin(argv[0]) : find_builtin1(argv[0]);
8342         if (x) {
8343                 if_command_vV_print_and_exit(opt_vV, argv[0], "a shell builtin");
8344                 exec_builtin(&nommu_save->argv_from_re_execing, x, argv);
8345         }
8346
8347 #if ENABLE_FEATURE_SH_STANDALONE
8348         /* Check if the command matches any busybox applets */
8349         {
8350                 int a = find_applet_by_name(argv[0]);
8351                 if (a >= 0) {
8352                         if_command_vV_print_and_exit(opt_vV, argv[0], "an applet");
8353 # if BB_MMU /* see above why on NOMMU it is not allowed */
8354                         if (APPLET_IS_NOEXEC(a)) {
8355                                 /* Do not leak open fds from opened script files etc.
8356                                  * Testcase: interactive "ls -l /proc/self/fd"
8357                                  * should not show tty fd open.
8358                                  */
8359                                 close_saved_fds_and_FILE_fds();
8360 //FIXME: should also close saved redir fds
8361 //This casuses test failures in
8362 //redir_children_should_not_see_saved_fd_2.tests
8363 //redir_children_should_not_see_saved_fd_3.tests
8364 //if you replace "busybox find" with just "find" in them
8365                                 /* Without this, "rm -i FILE" can't be ^C'ed: */
8366                                 switch_off_special_sigs(G.special_sig_mask);
8367                                 debug_printf_exec("running applet '%s'\n", argv[0]);
8368                                 run_noexec_applet_and_exit(a, argv[0], argv);
8369                         }
8370 # endif
8371                         /* Re-exec ourselves */
8372                         debug_printf_exec("re-execing applet '%s'\n", argv[0]);
8373                         /* Don't propagate SIG_IGN to the child */
8374                         if (SPECIAL_JOBSTOP_SIGS != 0)
8375                                 switch_off_special_sigs(G.special_sig_mask & SPECIAL_JOBSTOP_SIGS);
8376                         execv(bb_busybox_exec_path, argv);
8377                         /* If they called chroot or otherwise made the binary no longer
8378                          * executable, fall through */
8379                 }
8380         }
8381 #endif
8382
8383 #if ENABLE_FEATURE_SH_STANDALONE || BB_MMU
8384  skip:
8385 #endif
8386         if_command_vV_print_and_exit(opt_vV, argv[0], NULL);
8387         execvp_or_die(argv);
8388 }
8389
8390 /* Called after [v]fork() in run_pipe
8391  */
8392 static void pseudo_exec(nommu_save_t *nommu_save,
8393                 struct command *command,
8394                 char **argv_expanded) NORETURN;
8395 static void pseudo_exec(nommu_save_t *nommu_save,
8396                 struct command *command,
8397                 char **argv_expanded)
8398 {
8399 #if ENABLE_HUSH_FUNCTIONS
8400         if (command->cmd_type == CMD_FUNCDEF) {
8401                 /* Ignore funcdefs in pipes:
8402                  * true | f() { cmd }
8403                  */
8404                 _exit(0);
8405         }
8406 #endif
8407
8408         if (command->argv) {
8409                 pseudo_exec_argv(nommu_save, command->argv,
8410                                 command->assignment_cnt, argv_expanded);
8411         }
8412
8413         if (command->group) {
8414                 /* Cases when we are here:
8415                  * ( list )
8416                  * { list } &
8417                  * ... | ( list ) | ...
8418                  * ... | { list } | ...
8419                  */
8420 #if BB_MMU
8421                 int rcode;
8422                 debug_printf_exec("pseudo_exec: run_list\n");
8423                 reset_traps_to_defaults();
8424                 rcode = run_list(command->group);
8425                 /* OK to leak memory by not calling free_pipe_list,
8426                  * since this process is about to exit */
8427                 _exit(rcode);
8428 #else
8429                 re_execute_shell(&nommu_save->argv_from_re_execing,
8430                                 command->group_as_string,
8431                                 G.global_argv[0],
8432                                 G.global_argv + 1,
8433                                 NULL);
8434 #endif
8435         }
8436
8437         /* Case when we are here: ... | >file */
8438         debug_printf_exec("pseudo_exec'ed null command\n");
8439         _exit(EXIT_SUCCESS);
8440 }
8441
8442 #if ENABLE_HUSH_JOB
8443 static const char *get_cmdtext(struct pipe *pi)
8444 {
8445         char **argv;
8446         char *p;
8447         int len;
8448
8449         /* This is subtle. ->cmdtext is created only on first backgrounding.
8450          * (Think "cat, <ctrl-z>, fg, <ctrl-z>, fg, <ctrl-z>...." here...)
8451          * On subsequent bg argv is trashed, but we won't use it */
8452         if (pi->cmdtext)
8453                 return pi->cmdtext;
8454
8455         argv = pi->cmds[0].argv;
8456         if (!argv) {
8457                 pi->cmdtext = xzalloc(1);
8458                 return pi->cmdtext;
8459         }
8460         len = 0;
8461         do {
8462                 len += strlen(*argv) + 1;
8463         } while (*++argv);
8464         p = xmalloc(len);
8465         pi->cmdtext = p;
8466         argv = pi->cmds[0].argv;
8467         do {
8468                 p = stpcpy(p, *argv);
8469                 *p++ = ' ';
8470         } while (*++argv);
8471         p[-1] = '\0';
8472         return pi->cmdtext;
8473 }
8474
8475 static void remove_job_from_table(struct pipe *pi)
8476 {
8477         struct pipe *prev_pipe;
8478
8479         if (pi == G.job_list) {
8480                 G.job_list = pi->next;
8481         } else {
8482                 prev_pipe = G.job_list;
8483                 while (prev_pipe->next != pi)
8484                         prev_pipe = prev_pipe->next;
8485                 prev_pipe->next = pi->next;
8486         }
8487         G.last_jobid = 0;
8488         if (G.job_list)
8489                 G.last_jobid = G.job_list->jobid;
8490 }
8491
8492 static void delete_finished_job(struct pipe *pi)
8493 {
8494         remove_job_from_table(pi);
8495         free_pipe(pi);
8496 }
8497
8498 static void clean_up_last_dead_job(void)
8499 {
8500         if (G.job_list && !G.job_list->alive_cmds)
8501                 delete_finished_job(G.job_list);
8502 }
8503
8504 static void insert_job_into_table(struct pipe *pi)
8505 {
8506         struct pipe *job, **jobp;
8507         int i;
8508
8509         clean_up_last_dead_job();
8510
8511         /* Find the end of the list, and find next job ID to use */
8512         i = 0;
8513         jobp = &G.job_list;
8514         while ((job = *jobp) != NULL) {
8515                 if (job->jobid > i)
8516                         i = job->jobid;
8517                 jobp = &job->next;
8518         }
8519         pi->jobid = i + 1;
8520
8521         /* Create a new job struct at the end */
8522         job = *jobp = xmemdup(pi, sizeof(*pi));
8523         job->next = NULL;
8524         job->cmds = xzalloc(sizeof(pi->cmds[0]) * pi->num_cmds);
8525         /* Cannot copy entire pi->cmds[] vector! This causes double frees */
8526         for (i = 0; i < pi->num_cmds; i++) {
8527                 job->cmds[i].pid = pi->cmds[i].pid;
8528                 /* all other fields are not used and stay zero */
8529         }
8530         job->cmdtext = xstrdup(get_cmdtext(pi));
8531
8532         if (G_interactive_fd)
8533                 printf("[%u] %u %s\n", job->jobid, (unsigned)job->cmds[0].pid, job->cmdtext);
8534         G.last_jobid = job->jobid;
8535 }
8536 #endif /* JOB */
8537
8538 static int job_exited_or_stopped(struct pipe *pi)
8539 {
8540         int rcode, i;
8541
8542         if (pi->alive_cmds != pi->stopped_cmds)
8543                 return -1;
8544
8545         /* All processes in fg pipe have exited or stopped */
8546         rcode = 0;
8547         i = pi->num_cmds;
8548         while (--i >= 0) {
8549                 rcode = pi->cmds[i].cmd_exitcode;
8550                 /* usually last process gives overall exitstatus,
8551                  * but with "set -o pipefail", last *failed* process does */
8552                 if (G.o_opt[OPT_O_PIPEFAIL] == 0 || rcode != 0)
8553                         break;
8554         }
8555         IF_HAS_KEYWORDS(if (pi->pi_inverted) rcode = !rcode;)
8556         return rcode;
8557 }
8558
8559 static int process_wait_result(struct pipe *fg_pipe, pid_t childpid, int status)
8560 {
8561 #if ENABLE_HUSH_JOB
8562         struct pipe *pi;
8563 #endif
8564         int i, dead;
8565
8566         dead = WIFEXITED(status) || WIFSIGNALED(status);
8567
8568 #if DEBUG_JOBS
8569         if (WIFSTOPPED(status))
8570                 debug_printf_jobs("pid %d stopped by sig %d (exitcode %d)\n",
8571                                 childpid, WSTOPSIG(status), WEXITSTATUS(status));
8572         if (WIFSIGNALED(status))
8573                 debug_printf_jobs("pid %d killed by sig %d (exitcode %d)\n",
8574                                 childpid, WTERMSIG(status), WEXITSTATUS(status));
8575         if (WIFEXITED(status))
8576                 debug_printf_jobs("pid %d exited, exitcode %d\n",
8577                                 childpid, WEXITSTATUS(status));
8578 #endif
8579         /* Were we asked to wait for a fg pipe? */
8580         if (fg_pipe) {
8581                 i = fg_pipe->num_cmds;
8582
8583                 while (--i >= 0) {
8584                         int rcode;
8585
8586                         debug_printf_jobs("check pid %d\n", fg_pipe->cmds[i].pid);
8587                         if (fg_pipe->cmds[i].pid != childpid)
8588                                 continue;
8589                         if (dead) {
8590                                 int ex;
8591                                 fg_pipe->cmds[i].pid = 0;
8592                                 fg_pipe->alive_cmds--;
8593                                 ex = WEXITSTATUS(status);
8594                                 /* bash prints killer signal's name for *last*
8595                                  * process in pipe (prints just newline for SIGINT/SIGPIPE).
8596                                  * Mimic this. Example: "sleep 5" + (^\ or kill -QUIT)
8597                                  */
8598                                 if (WIFSIGNALED(status)) {
8599                                         int sig = WTERMSIG(status);
8600                                         if (i == fg_pipe->num_cmds-1)
8601                                                 /* TODO: use strsignal() instead for bash compat? but that's bloat... */
8602                                                 puts(sig == SIGINT || sig == SIGPIPE ? "" : get_signame(sig));
8603                                         /* TODO: if (WCOREDUMP(status)) + " (core dumped)"; */
8604                                         /* TODO: MIPS has 128 sigs (1..128), what if sig==128 here?
8605                                          * Maybe we need to use sig | 128? */
8606                                         ex = sig + 128;
8607                                 }
8608                                 fg_pipe->cmds[i].cmd_exitcode = ex;
8609                         } else {
8610                                 fg_pipe->stopped_cmds++;
8611                         }
8612                         debug_printf_jobs("fg_pipe: alive_cmds %d stopped_cmds %d\n",
8613                                         fg_pipe->alive_cmds, fg_pipe->stopped_cmds);
8614                         rcode = job_exited_or_stopped(fg_pipe);
8615                         if (rcode >= 0) {
8616 /* Note: *non-interactive* bash does not continue if all processes in fg pipe
8617  * are stopped. Testcase: "cat | cat" in a script (not on command line!)
8618  * and "killall -STOP cat" */
8619                                 if (G_interactive_fd) {
8620 #if ENABLE_HUSH_JOB
8621                                         if (fg_pipe->alive_cmds != 0)
8622                                                 insert_job_into_table(fg_pipe);
8623 #endif
8624                                         return rcode;
8625                                 }
8626                                 if (fg_pipe->alive_cmds == 0)
8627                                         return rcode;
8628                         }
8629                         /* There are still running processes in the fg_pipe */
8630                         return -1;
8631                 }
8632                 /* It wasn't in fg_pipe, look for process in bg pipes */
8633         }
8634
8635 #if ENABLE_HUSH_JOB
8636         /* We were asked to wait for bg or orphaned children */
8637         /* No need to remember exitcode in this case */
8638         for (pi = G.job_list; pi; pi = pi->next) {
8639                 for (i = 0; i < pi->num_cmds; i++) {
8640                         if (pi->cmds[i].pid == childpid)
8641                                 goto found_pi_and_prognum;
8642                 }
8643         }
8644         /* Happens when shell is used as init process (init=/bin/sh) */
8645         debug_printf("checkjobs: pid %d was not in our list!\n", childpid);
8646         return -1; /* this wasn't a process from fg_pipe */
8647
8648  found_pi_and_prognum:
8649         if (dead) {
8650                 /* child exited */
8651                 int rcode = WEXITSTATUS(status);
8652                 if (WIFSIGNALED(status))
8653                         rcode = 128 + WTERMSIG(status);
8654                 pi->cmds[i].cmd_exitcode = rcode;
8655                 if (G.last_bg_pid == pi->cmds[i].pid)
8656                         G.last_bg_pid_exitcode = rcode;
8657                 pi->cmds[i].pid = 0;
8658                 pi->alive_cmds--;
8659                 if (!pi->alive_cmds) {
8660                         if (G_interactive_fd) {
8661                                 printf(JOB_STATUS_FORMAT, pi->jobid,
8662                                                 "Done", pi->cmdtext);
8663                                 delete_finished_job(pi);
8664                         } else {
8665 /*
8666  * bash deletes finished jobs from job table only in interactive mode,
8667  * after "jobs" cmd, or if pid of a new process matches one of the old ones
8668  * (see cleanup_dead_jobs(), delete_old_job(), J_NOTIFIED in bash source).
8669  * Testcase script: "(exit 3) & sleep 1; wait %1; echo $?" prints 3 in bash.
8670  * We only retain one "dead" job, if it's the single job on the list.
8671  * This covers most of real-world scenarios where this is useful.
8672  */
8673                                 if (pi != G.job_list)
8674                                         delete_finished_job(pi);
8675                         }
8676                 }
8677         } else {
8678                 /* child stopped */
8679                 pi->stopped_cmds++;
8680         }
8681 #endif
8682         return -1; /* this wasn't a process from fg_pipe */
8683 }
8684
8685 /* Check to see if any processes have exited -- if they have,
8686  * figure out why and see if a job has completed.
8687  *
8688  * If non-NULL fg_pipe: wait for its completion or stop.
8689  * Return its exitcode or zero if stopped.
8690  *
8691  * Alternatively (fg_pipe == NULL, waitfor_pid != 0):
8692  * waitpid(WNOHANG), if waitfor_pid exits or stops, return exitcode+1,
8693  * else return <0 if waitpid errors out (e.g. ECHILD: nothing to wait for)
8694  * or 0 if no children changed status.
8695  *
8696  * Alternatively (fg_pipe == NULL, waitfor_pid == 0),
8697  * return <0 if waitpid errors out (e.g. ECHILD: nothing to wait for)
8698  * or 0 if no children changed status.
8699  */
8700 static int checkjobs(struct pipe *fg_pipe, pid_t waitfor_pid)
8701 {
8702         int attributes;
8703         int status;
8704         int rcode = 0;
8705
8706         debug_printf_jobs("checkjobs %p\n", fg_pipe);
8707
8708         attributes = WUNTRACED;
8709         if (fg_pipe == NULL)
8710                 attributes |= WNOHANG;
8711
8712         errno = 0;
8713 #if ENABLE_HUSH_FAST
8714         if (G.handled_SIGCHLD == G.count_SIGCHLD) {
8715 //bb_error_msg("[%d] checkjobs: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d children?:%d fg_pipe:%p",
8716 //getpid(), G.count_SIGCHLD, G.handled_SIGCHLD, G.we_have_children, fg_pipe);
8717                 /* There was neither fork nor SIGCHLD since last waitpid */
8718                 /* Avoid doing waitpid syscall if possible */
8719                 if (!G.we_have_children) {
8720                         errno = ECHILD;
8721                         return -1;
8722                 }
8723                 if (fg_pipe == NULL) { /* is WNOHANG set? */
8724                         /* We have children, but they did not exit
8725                          * or stop yet (we saw no SIGCHLD) */
8726                         return 0;
8727                 }
8728                 /* else: !WNOHANG, waitpid will block, can't short-circuit */
8729         }
8730 #endif
8731
8732 /* Do we do this right?
8733  * bash-3.00# sleep 20 | false
8734  * <ctrl-Z pressed>
8735  * [3]+  Stopped          sleep 20 | false
8736  * bash-3.00# echo $?
8737  * 1   <========== bg pipe is not fully done, but exitcode is already known!
8738  * [hush 1.14.0: yes we do it right]
8739  */
8740         while (1) {
8741                 pid_t childpid;
8742 #if ENABLE_HUSH_FAST
8743                 int i;
8744                 i = G.count_SIGCHLD;
8745 #endif
8746                 childpid = waitpid(-1, &status, attributes);
8747                 if (childpid <= 0) {
8748                         if (childpid && errno != ECHILD)
8749                                 bb_perror_msg("waitpid");
8750 #if ENABLE_HUSH_FAST
8751                         else { /* Until next SIGCHLD, waitpid's are useless */
8752                                 G.we_have_children = (childpid == 0);
8753                                 G.handled_SIGCHLD = i;
8754 //bb_error_msg("[%d] checkjobs: waitpid returned <= 0, G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
8755                         }
8756 #endif
8757                         /* ECHILD (no children), or 0 (no change in children status) */
8758                         rcode = childpid;
8759                         break;
8760                 }
8761                 rcode = process_wait_result(fg_pipe, childpid, status);
8762                 if (rcode >= 0) {
8763                         /* fg_pipe exited or stopped */
8764                         break;
8765                 }
8766                 if (childpid == waitfor_pid) {
8767                         debug_printf_exec("childpid==waitfor_pid:%d status:0x%08x\n", childpid, status);
8768                         rcode = WEXITSTATUS(status);
8769                         if (WIFSIGNALED(status))
8770                                 rcode = 128 + WTERMSIG(status);
8771                         if (WIFSTOPPED(status))
8772                                 /* bash: "cmd & wait $!" and cmd stops: $? = 128 + stopsig */
8773                                 rcode = 128 + WSTOPSIG(status);
8774                         rcode++;
8775                         break; /* "wait PID" called us, give it exitcode+1 */
8776                 }
8777                 /* This wasn't one of our processes, or */
8778                 /* fg_pipe still has running processes, do waitpid again */
8779         } /* while (waitpid succeeds)... */
8780
8781         return rcode;
8782 }
8783
8784 #if ENABLE_HUSH_JOB
8785 static int checkjobs_and_fg_shell(struct pipe *fg_pipe)
8786 {
8787         pid_t p;
8788         int rcode = checkjobs(fg_pipe, 0 /*(no pid to wait for)*/);
8789         if (G_saved_tty_pgrp) {
8790                 /* Job finished, move the shell to the foreground */
8791                 p = getpgrp(); /* our process group id */
8792                 debug_printf_jobs("fg'ing ourself: getpgrp()=%d\n", (int)p);
8793                 tcsetpgrp(G_interactive_fd, p);
8794         }
8795         return rcode;
8796 }
8797 #endif
8798
8799 /* Start all the jobs, but don't wait for anything to finish.
8800  * See checkjobs().
8801  *
8802  * Return code is normally -1, when the caller has to wait for children
8803  * to finish to determine the exit status of the pipe.  If the pipe
8804  * is a simple builtin command, however, the action is done by the
8805  * time run_pipe returns, and the exit code is provided as the
8806  * return value.
8807  *
8808  * Returns -1 only if started some children. IOW: we have to
8809  * mask out retvals of builtins etc with 0xff!
8810  *
8811  * The only case when we do not need to [v]fork is when the pipe
8812  * is single, non-backgrounded, non-subshell command. Examples:
8813  * cmd ; ...   { list } ; ...
8814  * cmd && ...  { list } && ...
8815  * cmd || ...  { list } || ...
8816  * If it is, then we can run cmd as a builtin, NOFORK,
8817  * or (if SH_STANDALONE) an applet, and we can run the { list }
8818  * with run_list. If it isn't one of these, we fork and exec cmd.
8819  *
8820  * Cases when we must fork:
8821  * non-single:   cmd | cmd
8822  * backgrounded: cmd &     { list } &
8823  * subshell:     ( list ) [&]
8824  */
8825 #if !ENABLE_HUSH_MODE_X
8826 #define redirect_and_varexp_helper(command, sqp, argv_expanded) \
8827         redirect_and_varexp_helper(command, sqp)
8828 #endif
8829 static int redirect_and_varexp_helper(
8830                 struct command *command,
8831                 struct squirrel **sqp,
8832                 char **argv_expanded)
8833 {
8834         /* Assignments occur before redirects. Try:
8835          * a=`sleep 1` sleep 2 3>/qwe/rty
8836          */
8837
8838         char **new_env = expand_assignments(command->argv, command->assignment_cnt);
8839         dump_cmd_in_x_mode(new_env);
8840         dump_cmd_in_x_mode(argv_expanded);
8841         /* this takes ownership of new_env[i] elements, and frees new_env: */
8842         set_vars_and_save_old(new_env);
8843
8844         return setup_redirects(command, sqp);
8845 }
8846 static NOINLINE int run_pipe(struct pipe *pi)
8847 {
8848         static const char *const null_ptr = NULL;
8849
8850         int cmd_no;
8851         int next_infd;
8852         struct command *command;
8853         char **argv_expanded;
8854         char **argv;
8855         struct squirrel *squirrel = NULL;
8856         int rcode;
8857
8858         debug_printf_exec("run_pipe start: members:%d\n", pi->num_cmds);
8859         debug_enter();
8860
8861         /* Testcase: set -- q w e; (IFS='' echo "$*"; IFS=''; echo "$*"); echo "$*"
8862          * Result should be 3 lines: q w e, qwe, q w e
8863          */
8864         if (G.ifs_whitespace != G.ifs)
8865                 free(G.ifs_whitespace);
8866         G.ifs = get_local_var_value("IFS");
8867         if (G.ifs) {
8868                 char *p;
8869                 G.ifs_whitespace = (char*)G.ifs;
8870                 p = skip_whitespace(G.ifs);
8871                 if (*p) {
8872                         /* Not all $IFS is whitespace */
8873                         char *d;
8874                         int len = p - G.ifs;
8875                         p = skip_non_whitespace(p);
8876                         G.ifs_whitespace = xmalloc(len + strlen(p) + 1); /* can overestimate */
8877                         d = mempcpy(G.ifs_whitespace, G.ifs, len);
8878                         while (*p) {
8879                                 if (isspace(*p))
8880                                         *d++ = *p;
8881                                 p++;
8882                         }
8883                         *d = '\0';
8884                 }
8885         } else {
8886                 G.ifs = defifs;
8887                 G.ifs_whitespace = (char*)G.ifs;
8888         }
8889
8890         IF_HUSH_JOB(pi->pgrp = -1;)
8891         pi->stopped_cmds = 0;
8892         command = &pi->cmds[0];
8893         argv_expanded = NULL;
8894
8895         if (pi->num_cmds != 1
8896          || pi->followup == PIPE_BG
8897          || command->cmd_type == CMD_SUBSHELL
8898         ) {
8899                 goto must_fork;
8900         }
8901
8902         pi->alive_cmds = 1;
8903
8904         debug_printf_exec(": group:%p argv:'%s'\n",
8905                 command->group, command->argv ? command->argv[0] : "NONE");
8906
8907         if (command->group) {
8908 #if ENABLE_HUSH_FUNCTIONS
8909                 if (command->cmd_type == CMD_FUNCDEF) {
8910                         /* "executing" func () { list } */
8911                         struct function *funcp;
8912
8913                         funcp = new_function(command->argv[0]);
8914                         /* funcp->name is already set to argv[0] */
8915                         funcp->body = command->group;
8916 # if !BB_MMU
8917                         funcp->body_as_string = command->group_as_string;
8918                         command->group_as_string = NULL;
8919 # endif
8920                         command->group = NULL;
8921                         command->argv[0] = NULL;
8922                         debug_printf_exec("cmd %p has child func at %p\n", command, funcp);
8923                         funcp->parent_cmd = command;
8924                         command->child_func = funcp;
8925
8926                         debug_printf_exec("run_pipe: return EXIT_SUCCESS\n");
8927                         debug_leave();
8928                         return EXIT_SUCCESS;
8929                 }
8930 #endif
8931                 /* { list } */
8932                 debug_printf_exec("non-subshell group\n");
8933                 rcode = 1; /* exitcode if redir failed */
8934                 if (setup_redirects(command, &squirrel) == 0) {
8935                         debug_printf_exec(": run_list\n");
8936 //FIXME: we need to pass squirrel down into run_list()
8937 //for SH_STANDALONE case, or else this construct:
8938 // { find /proc/self/fd; true; } >FILE; cmd2
8939 //has no way of closing saved fd#1 for "find",
8940 //and in SH_STANDALONE mode, "find" is not execed,
8941 //therefore CLOEXEC on saved fd does not help.
8942                         rcode = run_list(command->group) & 0xff;
8943                 }
8944                 restore_redirects(squirrel);
8945                 IF_HAS_KEYWORDS(if (pi->pi_inverted) rcode = !rcode;)
8946                 debug_leave();
8947                 debug_printf_exec("run_pipe: return %d\n", rcode);
8948                 return rcode;
8949         }
8950
8951         argv = command->argv ? command->argv : (char **) &null_ptr;
8952         {
8953                 const struct built_in_command *x;
8954                 IF_HUSH_FUNCTIONS(const struct function *funcp;)
8955                 IF_NOT_HUSH_FUNCTIONS(enum { funcp = 0 };)
8956                 struct variable **sv_shadowed;
8957                 struct variable *old_vars;
8958
8959 #if ENABLE_HUSH_LINENO_VAR
8960                 if (G.lineno_var)
8961                         strcpy(G.lineno_var + sizeof("LINENO=")-1, utoa(command->lineno));
8962 #endif
8963
8964                 if (argv[command->assignment_cnt] == NULL) {
8965                         /* Assignments, but no command.
8966                          * Ensure redirects take effect (that is, create files).
8967                          * Try "a=t >file"
8968                          */
8969                         unsigned i;
8970                         G.expand_exitcode = 0;
8971  only_assignments:
8972                         rcode = setup_redirects(command, &squirrel);
8973                         restore_redirects(squirrel);
8974
8975                         /* Set shell variables */
8976                         i = 0;
8977                         while (i < command->assignment_cnt) {
8978                                 char *p = expand_string_to_string(argv[i],
8979                                                 EXP_FLAG_ESC_GLOB_CHARS,
8980                                                 /*unbackslash:*/ 1
8981                                 );
8982 #if ENABLE_HUSH_MODE_X
8983                                 if (G_x_mode) {
8984                                         char *eq;
8985                                         if (i == 0)
8986                                                 x_mode_prefix();
8987                                         x_mode_addchr(' ');
8988                                         eq = strchrnul(p, '=');
8989                                         if (*eq) eq++;
8990                                         x_mode_addblock(p, (eq - p));
8991                                         x_mode_print_optionally_squoted(eq);
8992                                         x_mode_flush();
8993                                 }
8994 #endif
8995                                 debug_printf_env("set shell var:'%s'->'%s'\n", *argv, p);
8996                                 if (set_local_var(p, /*flag:*/ 0)) {
8997                                         /* assignment to readonly var / putenv error? */
8998                                         rcode = 1;
8999                                 }
9000                                 i++;
9001                         }
9002                         /* Redirect error sets $? to 1. Otherwise,
9003                          * if evaluating assignment value set $?, retain it.
9004                          * Else, clear $?:
9005                          *  false; q=`exit 2`; echo $? - should print 2
9006                          *  false; x=1; echo $? - should print 0
9007                          * Because of the 2nd case, we can't just use G.last_exitcode.
9008                          */
9009                         if (rcode == 0)
9010                                 rcode = G.expand_exitcode;
9011                         IF_HAS_KEYWORDS(if (pi->pi_inverted) rcode = !rcode;)
9012                         debug_leave();
9013                         debug_printf_exec("run_pipe: return %d\n", rcode);
9014                         return rcode;
9015                 }
9016
9017                 /* Expand the rest into (possibly) many strings each */
9018 #if defined(CMD_SINGLEWORD_NOGLOB)
9019                 if (command->cmd_type == CMD_SINGLEWORD_NOGLOB)
9020                         argv_expanded = expand_strvec_to_strvec_singleword_noglob(argv + command->assignment_cnt);
9021                 else
9022 #endif
9023                         argv_expanded = expand_strvec_to_strvec(argv + command->assignment_cnt);
9024
9025                 /* If someone gives us an empty string: `cmd with empty output` */
9026                 if (!argv_expanded[0]) {
9027                         free(argv_expanded);
9028                         /* `false` still has to set exitcode 1 */
9029                         G.expand_exitcode = G.last_exitcode;
9030                         goto only_assignments;
9031                 }
9032
9033                 old_vars = NULL;
9034                 sv_shadowed = G.shadowed_vars_pp;
9035
9036                 /* Check if argv[0] matches any functions (this goes before bltins) */
9037                 IF_HUSH_FUNCTIONS(funcp = find_function(argv_expanded[0]);)
9038                 IF_HUSH_FUNCTIONS(x = NULL;)
9039                 IF_HUSH_FUNCTIONS(if (!funcp))
9040                         x = find_builtin(argv_expanded[0]);
9041                 if (x || funcp) {
9042                         if (x && x->b_function == builtin_exec && argv_expanded[1] == NULL) {
9043                                 debug_printf("exec with redirects only\n");
9044                                 /*
9045                                  * Variable assignments are executed, but then "forgotten":
9046                                  *  a=`sleep 1;echo A` exec 3>&-; echo $a
9047                                  * sleeps, but prints nothing.
9048                                  */
9049                                 enter_var_nest_level();
9050                                 G.shadowed_vars_pp = &old_vars;
9051                                 rcode = redirect_and_varexp_helper(command,
9052                                         /*squirrel:*/ ERR_PTR,
9053                                         argv_expanded
9054                                 );
9055                                 G.shadowed_vars_pp = sv_shadowed;
9056                                 /* rcode=1 can be if redir file can't be opened */
9057
9058                                 goto clean_up_and_ret1;
9059                         }
9060
9061                         /* Bump var nesting, or this will leak exported $a:
9062                          * a=b true; env | grep ^a=
9063                          */
9064                         enter_var_nest_level();
9065                         /* Collect all variables "shadowed" by helper
9066                          * (IOW: old vars overridden by "var1=val1 var2=val2 cmd..." syntax)
9067                          * into old_vars list:
9068                          */
9069                         G.shadowed_vars_pp = &old_vars;
9070                         rcode = redirect_and_varexp_helper(command, &squirrel, argv_expanded);
9071                         if (rcode == 0) {
9072                                 if (!funcp) {
9073                                         /* Do not collect *to old_vars list* vars shadowed
9074                                          * by e.g. "local VAR" builtin (collect them
9075                                          * in the previously nested list instead):
9076                                          * don't want them to be restored immediately
9077                                          * after "local" completes.
9078                                          */
9079                                         G.shadowed_vars_pp = sv_shadowed;
9080
9081                                         debug_printf_exec(": builtin '%s' '%s'...\n",
9082                                                 x->b_cmd, argv_expanded[1]);
9083                                         fflush_all();
9084                                         rcode = x->b_function(argv_expanded) & 0xff;
9085                                         fflush_all();
9086                                 }
9087 #if ENABLE_HUSH_FUNCTIONS
9088                                 else {
9089                                         debug_printf_exec(": function '%s' '%s'...\n",
9090                                                 funcp->name, argv_expanded[1]);
9091                                         rcode = run_function(funcp, argv_expanded) & 0xff;
9092                                         /*
9093                                          * But do collect *to old_vars list* vars shadowed
9094                                          * within function execution. To that end, restore
9095                                          * this pointer _after_ function run:
9096                                          */
9097                                         G.shadowed_vars_pp = sv_shadowed;
9098                                 }
9099 #endif
9100                         }
9101                 } else
9102                 if (ENABLE_FEATURE_SH_NOFORK && NUM_APPLETS > 1) {
9103                         int n = find_applet_by_name(argv_expanded[0]);
9104                         if (n < 0 || !APPLET_IS_NOFORK(n))
9105                                 goto must_fork;
9106
9107                         enter_var_nest_level();
9108                         /* Collect all variables "shadowed" by helper into old_vars list */
9109                         G.shadowed_vars_pp = &old_vars;
9110                         rcode = redirect_and_varexp_helper(command, &squirrel, argv_expanded);
9111                         G.shadowed_vars_pp = sv_shadowed;
9112
9113                         if (rcode == 0) {
9114                                 debug_printf_exec(": run_nofork_applet '%s' '%s'...\n",
9115                                         argv_expanded[0], argv_expanded[1]);
9116                                 /*
9117                                  * Note: signals (^C) can't interrupt here.
9118                                  * We remember them and they will be acted upon
9119                                  * after applet returns.
9120                                  * This makes applets which can run for a long time
9121                                  * and/or wait for user input ineligible for NOFORK:
9122                                  * for example, "yes" or "rm" (rm -i waits for input).
9123                                  */
9124                                 rcode = run_nofork_applet(n, argv_expanded);
9125                         }
9126                 } else
9127                         goto must_fork;
9128
9129                 restore_redirects(squirrel);
9130  clean_up_and_ret1:
9131                 leave_var_nest_level();
9132                 add_vars(old_vars);
9133
9134                 /*
9135                  * Try "usleep 99999999" + ^C + "echo $?"
9136                  * with FEATURE_SH_NOFORK=y.
9137                  */
9138                 if (!funcp) {
9139                         /* It was builtin or nofork.
9140                          * if this would be a real fork/execed program,
9141                          * it should have died if a fatal sig was received.
9142                          * But OTOH, there was no separate process,
9143                          * the sig was sent to _shell_, not to non-existing
9144                          * child.
9145                          * Let's just handle ^C only, this one is obvious:
9146                          * we aren't ok with exitcode 0 when ^C was pressed
9147                          * during builtin/nofork.
9148                          */
9149                         if (sigismember(&G.pending_set, SIGINT))
9150                                 rcode = 128 + SIGINT;
9151                 }
9152                 free(argv_expanded);
9153                 IF_HAS_KEYWORDS(if (pi->pi_inverted) rcode = !rcode;)
9154                 debug_leave();
9155                 debug_printf_exec("run_pipe return %d\n", rcode);
9156                 return rcode;
9157         }
9158
9159  must_fork:
9160         /* NB: argv_expanded may already be created, and that
9161          * might include `cmd` runs! Do not rerun it! We *must*
9162          * use argv_expanded if it's non-NULL */
9163
9164         /* Going to fork a child per each pipe member */
9165         pi->alive_cmds = 0;
9166         next_infd = 0;
9167
9168         cmd_no = 0;
9169         while (cmd_no < pi->num_cmds) {
9170                 struct fd_pair pipefds;
9171 #if !BB_MMU
9172                 int sv_var_nest_level = G.var_nest_level;
9173                 volatile nommu_save_t nommu_save;
9174                 nommu_save.old_vars = NULL;
9175                 nommu_save.argv = NULL;
9176                 nommu_save.argv_from_re_execing = NULL;
9177 #endif
9178                 command = &pi->cmds[cmd_no];
9179                 cmd_no++;
9180                 if (command->argv) {
9181                         debug_printf_exec(": pipe member '%s' '%s'...\n",
9182                                         command->argv[0], command->argv[1]);
9183                 } else {
9184                         debug_printf_exec(": pipe member with no argv\n");
9185                 }
9186
9187                 /* pipes are inserted between pairs of commands */
9188                 pipefds.rd = 0;
9189                 pipefds.wr = 1;
9190                 if (cmd_no < pi->num_cmds)
9191                         xpiped_pair(pipefds);
9192
9193 #if ENABLE_HUSH_LINENO_VAR
9194                 if (G.lineno_var)
9195                         strcpy(G.lineno_var + sizeof("LINENO=")-1, utoa(command->lineno));
9196 #endif
9197
9198                 command->pid = BB_MMU ? fork() : vfork();
9199                 if (!command->pid) { /* child */
9200 #if ENABLE_HUSH_JOB
9201                         disable_restore_tty_pgrp_on_exit();
9202                         CLEAR_RANDOM_T(&G.random_gen); /* or else $RANDOM repeats in child */
9203
9204                         /* Every child adds itself to new process group
9205                          * with pgid == pid_of_first_child_in_pipe */
9206                         if (G.run_list_level == 1 && G_interactive_fd) {
9207                                 pid_t pgrp;
9208                                 pgrp = pi->pgrp;
9209                                 if (pgrp < 0) /* true for 1st process only */
9210                                         pgrp = getpid();
9211                                 if (setpgid(0, pgrp) == 0
9212                                  && pi->followup != PIPE_BG
9213                                  && G_saved_tty_pgrp /* we have ctty */
9214                                 ) {
9215                                         /* We do it in *every* child, not just first,
9216                                          * to avoid races */
9217                                         tcsetpgrp(G_interactive_fd, pgrp);
9218                                 }
9219                         }
9220 #endif
9221                         if (pi->alive_cmds == 0 && pi->followup == PIPE_BG) {
9222                                 /* 1st cmd in backgrounded pipe
9223                                  * should have its stdin /dev/null'ed */
9224                                 close(0);
9225                                 if (open(bb_dev_null, O_RDONLY))
9226                                         xopen("/", O_RDONLY);
9227                         } else {
9228                                 xmove_fd(next_infd, 0);
9229                         }
9230                         xmove_fd(pipefds.wr, 1);
9231                         if (pipefds.rd > 1)
9232                                 close(pipefds.rd);
9233                         /* Like bash, explicit redirects override pipes,
9234                          * and the pipe fd (fd#1) is available for dup'ing:
9235                          * "cmd1 2>&1 | cmd2": fd#1 is duped to fd#2, thus stderr
9236                          * of cmd1 goes into pipe.
9237                          */
9238                         if (setup_redirects(command, NULL)) {
9239                                 /* Happens when redir file can't be opened:
9240                                  * $ hush -c 'echo FOO >&2 | echo BAR 3>/qwe/rty; echo BAZ'
9241                                  * FOO
9242                                  * hush: can't open '/qwe/rty': No such file or directory
9243                                  * BAZ
9244                                  * (echo BAR is not executed, it hits _exit(1) below)
9245                                  */
9246                                 _exit(1);
9247                         }
9248
9249                         /* Stores to nommu_save list of env vars putenv'ed
9250                          * (NOMMU, on MMU we don't need that) */
9251                         /* cast away volatility... */
9252                         pseudo_exec((nommu_save_t*) &nommu_save, command, argv_expanded);
9253                         /* pseudo_exec() does not return */
9254                 }
9255
9256                 /* parent or error */
9257 #if ENABLE_HUSH_FAST
9258                 G.count_SIGCHLD++;
9259 //bb_error_msg("[%d] fork in run_pipe: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
9260 #endif
9261                 enable_restore_tty_pgrp_on_exit();
9262 #if !BB_MMU
9263                 /* Clean up after vforked child */
9264                 free(nommu_save.argv);
9265                 free(nommu_save.argv_from_re_execing);
9266                 G.var_nest_level = sv_var_nest_level;
9267                 remove_nested_vars();
9268                 add_vars(nommu_save.old_vars);
9269 #endif
9270                 free(argv_expanded);
9271                 argv_expanded = NULL;
9272                 if (command->pid < 0) { /* [v]fork failed */
9273                         /* Clearly indicate, was it fork or vfork */
9274                         bb_perror_msg(BB_MMU ? "vfork"+1 : "vfork");
9275                 } else {
9276                         pi->alive_cmds++;
9277 #if ENABLE_HUSH_JOB
9278                         /* Second and next children need to know pid of first one */
9279                         if (pi->pgrp < 0)
9280                                 pi->pgrp = command->pid;
9281 #endif
9282                 }
9283
9284                 if (cmd_no > 1)
9285                         close(next_infd);
9286                 if (cmd_no < pi->num_cmds)
9287                         close(pipefds.wr);
9288                 /* Pass read (output) pipe end to next iteration */
9289                 next_infd = pipefds.rd;
9290         }
9291
9292         if (!pi->alive_cmds) {
9293                 debug_leave();
9294                 debug_printf_exec("run_pipe return 1 (all forks failed, no children)\n");
9295                 return 1;
9296         }
9297
9298         debug_leave();
9299         debug_printf_exec("run_pipe return -1 (%u children started)\n", pi->alive_cmds);
9300         return -1;
9301 }
9302
9303 /* NB: called by pseudo_exec, and therefore must not modify any
9304  * global data until exec/_exit (we can be a child after vfork!) */
9305 static int run_list(struct pipe *pi)
9306 {
9307 #if ENABLE_HUSH_CASE
9308         char *case_word = NULL;
9309 #endif
9310 #if ENABLE_HUSH_LOOPS
9311         struct pipe *loop_top = NULL;
9312         char **for_lcur = NULL;
9313         char **for_list = NULL;
9314 #endif
9315         smallint last_followup;
9316         smalluint rcode;
9317 #if ENABLE_HUSH_IF || ENABLE_HUSH_CASE
9318         smalluint cond_code = 0;
9319 #else
9320         enum { cond_code = 0 };
9321 #endif
9322 #if HAS_KEYWORDS
9323         smallint rword;      /* RES_foo */
9324         smallint last_rword; /* ditto */
9325 #endif
9326
9327         debug_printf_exec("run_list start lvl %d\n", G.run_list_level);
9328         debug_enter();
9329
9330 #if ENABLE_HUSH_LOOPS
9331         /* Check syntax for "for" */
9332         {
9333                 struct pipe *cpipe;
9334                 for (cpipe = pi; cpipe; cpipe = cpipe->next) {
9335                         if (cpipe->res_word != RES_FOR && cpipe->res_word != RES_IN)
9336                                 continue;
9337                         /* current word is FOR or IN (BOLD in comments below) */
9338                         if (cpipe->next == NULL) {
9339                                 syntax_error("malformed for");
9340                                 debug_leave();
9341                                 debug_printf_exec("run_list lvl %d return 1\n", G.run_list_level);
9342                                 return 1;
9343                         }
9344                         /* "FOR v; do ..." and "for v IN a b; do..." are ok */
9345                         if (cpipe->next->res_word == RES_DO)
9346                                 continue;
9347                         /* next word is not "do". It must be "in" then ("FOR v in ...") */
9348                         if (cpipe->res_word == RES_IN /* "for v IN a b; not_do..."? */
9349                          || cpipe->next->res_word != RES_IN /* FOR v not_do_and_not_in..."? */
9350                         ) {
9351                                 syntax_error("malformed for");
9352                                 debug_leave();
9353                                 debug_printf_exec("run_list lvl %d return 1\n", G.run_list_level);
9354                                 return 1;
9355                         }
9356                 }
9357         }
9358 #endif
9359
9360         /* Past this point, all code paths should jump to ret: label
9361          * in order to return, no direct "return" statements please.
9362          * This helps to ensure that no memory is leaked. */
9363
9364 #if ENABLE_HUSH_JOB
9365         G.run_list_level++;
9366 #endif
9367
9368 #if HAS_KEYWORDS
9369         rword = RES_NONE;
9370         last_rword = RES_XXXX;
9371 #endif
9372         last_followup = PIPE_SEQ;
9373         rcode = G.last_exitcode;
9374
9375         /* Go through list of pipes, (maybe) executing them. */
9376         for (; pi; pi = IF_HUSH_LOOPS(rword == RES_DONE ? loop_top : ) pi->next) {
9377                 int r;
9378                 int sv_errexit_depth;
9379
9380                 if (G.flag_SIGINT)
9381                         break;
9382                 if (G_flag_return_in_progress == 1)
9383                         break;
9384
9385                 IF_HAS_KEYWORDS(rword = pi->res_word;)
9386                 debug_printf_exec(": rword=%d cond_code=%d last_rword=%d\n",
9387                                 rword, cond_code, last_rword);
9388
9389                 sv_errexit_depth = G.errexit_depth;
9390                 if (
9391 #if ENABLE_HUSH_IF
9392                     rword == RES_IF || rword == RES_ELIF ||
9393 #endif
9394                     pi->followup != PIPE_SEQ
9395                 ) {
9396                         G.errexit_depth++;
9397                 }
9398 #if ENABLE_HUSH_LOOPS
9399                 if ((rword == RES_WHILE || rword == RES_UNTIL || rword == RES_FOR)
9400                  && loop_top == NULL /* avoid bumping G.depth_of_loop twice */
9401                 ) {
9402                         /* start of a loop: remember where loop starts */
9403                         loop_top = pi;
9404                         G.depth_of_loop++;
9405                 }
9406 #endif
9407                 /* Still in the same "if...", "then..." or "do..." branch? */
9408                 if (IF_HAS_KEYWORDS(rword == last_rword &&) 1) {
9409                         if ((rcode == 0 && last_followup == PIPE_OR)
9410                          || (rcode != 0 && last_followup == PIPE_AND)
9411                         ) {
9412                                 /* It is "<true> || CMD" or "<false> && CMD"
9413                                  * and we should not execute CMD */
9414                                 debug_printf_exec("skipped cmd because of || or &&\n");
9415                                 last_followup = pi->followup;
9416                                 goto dont_check_jobs_but_continue;
9417                         }
9418                 }
9419                 last_followup = pi->followup;
9420                 IF_HAS_KEYWORDS(last_rword = rword;)
9421 #if ENABLE_HUSH_IF
9422                 if (cond_code) {
9423                         if (rword == RES_THEN) {
9424                                 /* if false; then ... fi has exitcode 0! */
9425                                 G.last_exitcode = rcode = EXIT_SUCCESS;
9426                                 /* "if <false> THEN cmd": skip cmd */
9427                                 continue;
9428                         }
9429                 } else {
9430                         if (rword == RES_ELSE || rword == RES_ELIF) {
9431                                 /* "if <true> then ... ELSE/ELIF cmd":
9432                                  * skip cmd and all following ones */
9433                                 break;
9434                         }
9435                 }
9436 #endif
9437 #if ENABLE_HUSH_LOOPS
9438                 if (rword == RES_FOR) { /* && pi->num_cmds - always == 1 */
9439                         if (!for_lcur) {
9440                                 /* first loop through for */
9441
9442                                 static const char encoded_dollar_at[] ALIGN1 = {
9443                                         SPECIAL_VAR_SYMBOL, '@' | 0x80, SPECIAL_VAR_SYMBOL, '\0'
9444                                 }; /* encoded representation of "$@" */
9445                                 static const char *const encoded_dollar_at_argv[] = {
9446                                         encoded_dollar_at, NULL
9447                                 }; /* argv list with one element: "$@" */
9448                                 char **vals;
9449
9450                                 G.last_exitcode = rcode = EXIT_SUCCESS;
9451                                 vals = (char**)encoded_dollar_at_argv;
9452                                 if (pi->next->res_word == RES_IN) {
9453                                         /* if no variable values after "in" we skip "for" */
9454                                         if (!pi->next->cmds[0].argv) {
9455                                                 debug_printf_exec(": null FOR: exitcode EXIT_SUCCESS\n");
9456                                                 break;
9457                                         }
9458                                         vals = pi->next->cmds[0].argv;
9459                                 } /* else: "for var; do..." -> assume "$@" list */
9460                                 /* create list of variable values */
9461                                 debug_print_strings("for_list made from", vals);
9462                                 for_list = expand_strvec_to_strvec(vals);
9463                                 for_lcur = for_list;
9464                                 debug_print_strings("for_list", for_list);
9465                         }
9466                         if (!*for_lcur) {
9467                                 /* "for" loop is over, clean up */
9468                                 free(for_list);
9469                                 for_list = NULL;
9470                                 for_lcur = NULL;
9471                                 break;
9472                         }
9473                         /* Insert next value from for_lcur */
9474                         /* note: *for_lcur already has quotes removed, $var expanded, etc */
9475                         set_local_var(xasprintf("%s=%s", pi->cmds[0].argv[0], *for_lcur++), /*flag:*/ 0);
9476                         continue;
9477                 }
9478                 if (rword == RES_IN) {
9479                         continue; /* "for v IN list;..." - "in" has no cmds anyway */
9480                 }
9481                 if (rword == RES_DONE) {
9482                         continue; /* "done" has no cmds too */
9483                 }
9484 #endif
9485 #if ENABLE_HUSH_CASE
9486                 if (rword == RES_CASE) {
9487                         debug_printf_exec("CASE cond_code:%d\n", cond_code);
9488                         case_word = expand_string_to_string(pi->cmds->argv[0],
9489                                 EXP_FLAG_ESC_GLOB_CHARS, /*unbackslash:*/ 1);
9490                         debug_printf_exec("CASE word1:'%s'\n", case_word);
9491                         //unbackslash(case_word);
9492                         //debug_printf_exec("CASE word2:'%s'\n", case_word);
9493                         continue;
9494                 }
9495                 if (rword == RES_MATCH) {
9496                         char **argv;
9497
9498                         debug_printf_exec("MATCH cond_code:%d\n", cond_code);
9499                         if (!case_word) /* "case ... matched_word) ... WORD)": we executed selected branch, stop */
9500                                 break;
9501                         /* all prev words didn't match, does this one match? */
9502                         argv = pi->cmds->argv;
9503                         while (*argv) {
9504                                 char *pattern;
9505                                 debug_printf_exec("expand_string_to_string('%s')\n", *argv);
9506                                 pattern = expand_string_to_string(*argv,
9507                                                 EXP_FLAG_ESC_GLOB_CHARS,
9508                                                 /*unbackslash:*/ 0
9509                                 );
9510                                 /* TODO: which FNM_xxx flags to use? */
9511                                 cond_code = (fnmatch(pattern, case_word, /*flags:*/ 0) != 0);
9512                                 debug_printf_exec("fnmatch(pattern:'%s',str:'%s'):%d\n",
9513                                                 pattern, case_word, cond_code);
9514                                 free(pattern);
9515                                 if (cond_code == 0) {
9516                                         /* match! we will execute this branch */
9517                                         free(case_word);
9518                                         case_word = NULL; /* make future "word)" stop */
9519                                         break;
9520                                 }
9521                                 argv++;
9522                         }
9523                         continue;
9524                 }
9525                 if (rword == RES_CASE_BODY) { /* inside of a case branch */
9526                         debug_printf_exec("CASE_BODY cond_code:%d\n", cond_code);
9527                         if (cond_code != 0)
9528                                 continue; /* not matched yet, skip this pipe */
9529                 }
9530                 if (rword == RES_ESAC) {
9531                         debug_printf_exec("ESAC cond_code:%d\n", cond_code);
9532                         if (case_word) {
9533                                 /* "case" did not match anything: still set $? (to 0) */
9534                                 G.last_exitcode = rcode = EXIT_SUCCESS;
9535                         }
9536                 }
9537 #endif
9538                 /* Just pressing <enter> in shell should check for jobs.
9539                  * OTOH, in non-interactive shell this is useless
9540                  * and only leads to extra job checks */
9541                 if (pi->num_cmds == 0) {
9542                         if (G_interactive_fd)
9543                                 goto check_jobs_and_continue;
9544                         continue;
9545                 }
9546
9547                 /* After analyzing all keywords and conditions, we decided
9548                  * to execute this pipe. NB: have to do checkjobs(NULL)
9549                  * after run_pipe to collect any background children,
9550                  * even if list execution is to be stopped. */
9551                 debug_printf_exec(": run_pipe with %d members\n", pi->num_cmds);
9552 #if ENABLE_HUSH_LOOPS
9553                 G.flag_break_continue = 0;
9554 #endif
9555                 rcode = r = run_pipe(pi); /* NB: rcode is a smalluint, r is int */
9556                 if (r != -1) {
9557                         /* We ran a builtin, function, or group.
9558                          * rcode is already known
9559                          * and we don't need to wait for anything. */
9560                         debug_printf_exec(": builtin/func exitcode %d\n", rcode);
9561                         G.last_exitcode = rcode;
9562                         check_and_run_traps();
9563 #if ENABLE_HUSH_LOOPS
9564                         /* Was it "break" or "continue"? */
9565                         if (G.flag_break_continue) {
9566                                 smallint fbc = G.flag_break_continue;
9567                                 /* We might fall into outer *loop*,
9568                                  * don't want to break it too */
9569                                 if (loop_top) {
9570                                         G.depth_break_continue--;
9571                                         if (G.depth_break_continue == 0)
9572                                                 G.flag_break_continue = 0;
9573                                         /* else: e.g. "continue 2" should *break* once, *then* continue */
9574                                 } /* else: "while... do... { we are here (innermost list is not a loop!) };...done" */
9575                                 if (G.depth_break_continue != 0 || fbc == BC_BREAK) {
9576                                         checkjobs(NULL, 0 /*(no pid to wait for)*/);
9577                                         break;
9578                                 }
9579                                 /* "continue": simulate end of loop */
9580                                 rword = RES_DONE;
9581                                 continue;
9582                         }
9583 #endif
9584                         if (G_flag_return_in_progress == 1) {
9585                                 checkjobs(NULL, 0 /*(no pid to wait for)*/);
9586                                 break;
9587                         }
9588                 } else if (pi->followup == PIPE_BG) {
9589                         /* What does bash do with attempts to background builtins? */
9590                         /* even bash 3.2 doesn't do that well with nested bg:
9591                          * try "{ { sleep 10; echo DEEP; } & echo HERE; } &".
9592                          * I'm NOT treating inner &'s as jobs */
9593 #if ENABLE_HUSH_JOB
9594                         if (G.run_list_level == 1)
9595                                 insert_job_into_table(pi);
9596 #endif
9597                         /* Last command's pid goes to $! */
9598                         G.last_bg_pid = pi->cmds[pi->num_cmds - 1].pid;
9599                         G.last_bg_pid_exitcode = 0;
9600                         debug_printf_exec(": cmd&: exitcode EXIT_SUCCESS\n");
9601 /* Check pi->pi_inverted? "! sleep 1 & echo $?": bash says 1. dash and ash say 0 */
9602                         rcode = EXIT_SUCCESS;
9603                         goto check_traps;
9604                 } else {
9605 #if ENABLE_HUSH_JOB
9606                         if (G.run_list_level == 1 && G_interactive_fd) {
9607                                 /* Waits for completion, then fg's main shell */
9608                                 rcode = checkjobs_and_fg_shell(pi);
9609                                 debug_printf_exec(": checkjobs_and_fg_shell exitcode %d\n", rcode);
9610                                 goto check_traps;
9611                         }
9612 #endif
9613                         /* This one just waits for completion */
9614                         rcode = checkjobs(pi, 0 /*(no pid to wait for)*/);
9615                         debug_printf_exec(": checkjobs exitcode %d\n", rcode);
9616  check_traps:
9617                         G.last_exitcode = rcode;
9618                         check_and_run_traps();
9619                 }
9620
9621                 /* Handle "set -e" */
9622                 if (rcode != 0 && G.o_opt[OPT_O_ERREXIT]) {
9623                         debug_printf_exec("ERREXIT:1 errexit_depth:%d\n", G.errexit_depth);
9624                         if (G.errexit_depth == 0)
9625                                 hush_exit(rcode);
9626                 }
9627                 G.errexit_depth = sv_errexit_depth;
9628
9629                 /* Analyze how result affects subsequent commands */
9630 #if ENABLE_HUSH_IF
9631                 if (rword == RES_IF || rword == RES_ELIF)
9632                         cond_code = rcode;
9633 #endif
9634  check_jobs_and_continue:
9635                 checkjobs(NULL, 0 /*(no pid to wait for)*/);
9636  dont_check_jobs_but_continue: ;
9637 #if ENABLE_HUSH_LOOPS
9638                 /* Beware of "while false; true; do ..."! */
9639                 if (pi->next
9640                  && (pi->next->res_word == RES_DO || pi->next->res_word == RES_DONE)
9641                  /* check for RES_DONE is needed for "while ...; do \n done" case */
9642                 ) {
9643                         if (rword == RES_WHILE) {
9644                                 if (rcode) {
9645                                         /* "while false; do...done" - exitcode 0 */
9646                                         G.last_exitcode = rcode = EXIT_SUCCESS;
9647                                         debug_printf_exec(": while expr is false: breaking (exitcode:EXIT_SUCCESS)\n");
9648                                         break;
9649                                 }
9650                         }
9651                         if (rword == RES_UNTIL) {
9652                                 if (!rcode) {
9653                                         debug_printf_exec(": until expr is true: breaking\n");
9654                                         break;
9655                                 }
9656                         }
9657                 }
9658 #endif
9659         } /* for (pi) */
9660
9661 #if ENABLE_HUSH_JOB
9662         G.run_list_level--;
9663 #endif
9664 #if ENABLE_HUSH_LOOPS
9665         if (loop_top)
9666                 G.depth_of_loop--;
9667         free(for_list);
9668 #endif
9669 #if ENABLE_HUSH_CASE
9670         free(case_word);
9671 #endif
9672         debug_leave();
9673         debug_printf_exec("run_list lvl %d return %d\n", G.run_list_level + 1, rcode);
9674         return rcode;
9675 }
9676
9677 /* Select which version we will use */
9678 static int run_and_free_list(struct pipe *pi)
9679 {
9680         int rcode = 0;
9681         debug_printf_exec("run_and_free_list entered\n");
9682         if (!G.o_opt[OPT_O_NOEXEC]) {
9683                 debug_printf_exec(": run_list: 1st pipe with %d cmds\n", pi->num_cmds);
9684                 rcode = run_list(pi);
9685         }
9686         /* free_pipe_list has the side effect of clearing memory.
9687          * In the long run that function can be merged with run_list,
9688          * but doing that now would hobble the debugging effort. */
9689         free_pipe_list(pi);
9690         debug_printf_exec("run_and_free_list return %d\n", rcode);
9691         return rcode;
9692 }
9693
9694
9695 static void install_sighandlers(unsigned mask)
9696 {
9697         sighandler_t old_handler;
9698         unsigned sig = 0;
9699         while ((mask >>= 1) != 0) {
9700                 sig++;
9701                 if (!(mask & 1))
9702                         continue;
9703                 old_handler = install_sighandler(sig, pick_sighandler(sig));
9704                 /* POSIX allows shell to re-enable SIGCHLD
9705                  * even if it was SIG_IGN on entry.
9706                  * Therefore we skip IGN check for it:
9707                  */
9708                 if (sig == SIGCHLD)
9709                         continue;
9710                 /* bash re-enables SIGHUP which is SIG_IGNed on entry.
9711                  * Try: "trap '' HUP; bash; echo RET" and type "kill -HUP $$"
9712                  */
9713                 //if (sig == SIGHUP) continue; - TODO?
9714                 if (old_handler == SIG_IGN) {
9715                         /* oops... restore back to IGN, and record this fact */
9716                         install_sighandler(sig, old_handler);
9717 #if ENABLE_HUSH_TRAP
9718                         if (!G_traps)
9719                                 G_traps = xzalloc(sizeof(G_traps[0]) * NSIG);
9720                         free(G_traps[sig]);
9721                         G_traps[sig] = xzalloc(1); /* == xstrdup(""); */
9722 #endif
9723                 }
9724         }
9725 }
9726
9727 /* Called a few times only (or even once if "sh -c") */
9728 static void install_special_sighandlers(void)
9729 {
9730         unsigned mask;
9731
9732         /* Which signals are shell-special? */
9733         mask = (1 << SIGQUIT) | (1 << SIGCHLD);
9734         if (G_interactive_fd) {
9735                 mask |= SPECIAL_INTERACTIVE_SIGS;
9736                 if (G_saved_tty_pgrp) /* we have ctty, job control sigs work */
9737                         mask |= SPECIAL_JOBSTOP_SIGS;
9738         }
9739         /* Careful, do not re-install handlers we already installed */
9740         if (G.special_sig_mask != mask) {
9741                 unsigned diff = mask & ~G.special_sig_mask;
9742                 G.special_sig_mask = mask;
9743                 install_sighandlers(diff);
9744         }
9745 }
9746
9747 #if ENABLE_HUSH_JOB
9748 /* helper */
9749 /* Set handlers to restore tty pgrp and exit */
9750 static void install_fatal_sighandlers(void)
9751 {
9752         unsigned mask;
9753
9754         /* We will restore tty pgrp on these signals */
9755         mask = 0
9756                 /*+ (1 << SIGILL ) * HUSH_DEBUG*/
9757                 /*+ (1 << SIGFPE ) * HUSH_DEBUG*/
9758                 + (1 << SIGBUS ) * HUSH_DEBUG
9759                 + (1 << SIGSEGV) * HUSH_DEBUG
9760                 /*+ (1 << SIGTRAP) * HUSH_DEBUG*/
9761                 + (1 << SIGABRT)
9762         /* bash 3.2 seems to handle these just like 'fatal' ones */
9763                 + (1 << SIGPIPE)
9764                 + (1 << SIGALRM)
9765         /* if we are interactive, SIGHUP, SIGTERM and SIGINT are special sigs.
9766          * if we aren't interactive... but in this case
9767          * we never want to restore pgrp on exit, and this fn is not called
9768          */
9769                 /*+ (1 << SIGHUP )*/
9770                 /*+ (1 << SIGTERM)*/
9771                 /*+ (1 << SIGINT )*/
9772         ;
9773         G_fatal_sig_mask = mask;
9774
9775         install_sighandlers(mask);
9776 }
9777 #endif
9778
9779 static int set_mode(int state, char mode, const char *o_opt)
9780 {
9781         int idx;
9782         switch (mode) {
9783         case 'n':
9784                 G.o_opt[OPT_O_NOEXEC] = state;
9785                 break;
9786         case 'x':
9787                 IF_HUSH_MODE_X(G_x_mode = state;)
9788                 IF_HUSH_MODE_X(if (G.x_mode_fd <= 0) G.x_mode_fd = dup_CLOEXEC(2, 10);)
9789                 break;
9790         case 'o':
9791                 if (!o_opt) {
9792                         /* "set -+o" without parameter.
9793                          * in bash, set -o produces this output:
9794                          *  pipefail        off
9795                          * and set +o:
9796                          *  set +o pipefail
9797                          * We always use the second form.
9798                          */
9799                         const char *p = o_opt_strings;
9800                         idx = 0;
9801                         while (*p) {
9802                                 printf("set %co %s\n", (G.o_opt[idx] ? '-' : '+'), p);
9803                                 idx++;
9804                                 p += strlen(p) + 1;
9805                         }
9806                         break;
9807                 }
9808                 idx = index_in_strings(o_opt_strings, o_opt);
9809                 if (idx >= 0) {
9810                         G.o_opt[idx] = state;
9811                         break;
9812                 }
9813         case 'e':
9814                 G.o_opt[OPT_O_ERREXIT] = state;
9815                 break;
9816         default:
9817                 return EXIT_FAILURE;
9818         }
9819         return EXIT_SUCCESS;
9820 }
9821
9822 int hush_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
9823 int hush_main(int argc, char **argv)
9824 {
9825         enum {
9826                 OPT_login = (1 << 0),
9827                 OPT_s     = (1 << 1),
9828         };
9829         unsigned flags;
9830         unsigned builtin_argc;
9831         char **e;
9832         struct variable *cur_var;
9833         struct variable *shell_ver;
9834
9835         INIT_G();
9836         if (EXIT_SUCCESS != 0) /* if EXIT_SUCCESS == 0, it is already done */
9837                 G.last_exitcode = EXIT_SUCCESS;
9838
9839 #if ENABLE_HUSH_FAST
9840         G.count_SIGCHLD++; /* ensure it is != G.handled_SIGCHLD */
9841 #endif
9842 #if !BB_MMU
9843         G.argv0_for_re_execing = argv[0];
9844 #endif
9845
9846         /* Deal with HUSH_VERSION */
9847         debug_printf_env("unsetenv '%s'\n", "HUSH_VERSION");
9848         unsetenv("HUSH_VERSION"); /* in case it exists in initial env */
9849         shell_ver = xzalloc(sizeof(*shell_ver));
9850         shell_ver->flg_export = 1;
9851         shell_ver->flg_read_only = 1;
9852         /* Code which handles ${var<op>...} needs writable values for all variables,
9853          * therefore we xstrdup: */
9854         shell_ver->varstr = xstrdup(hush_version_str);
9855
9856         /* Create shell local variables from the values
9857          * currently living in the environment */
9858         G.top_var = shell_ver;
9859         cur_var = G.top_var;
9860         e = environ;
9861         if (e) while (*e) {
9862                 char *value = strchr(*e, '=');
9863                 if (value) { /* paranoia */
9864                         cur_var->next = xzalloc(sizeof(*cur_var));
9865                         cur_var = cur_var->next;
9866                         cur_var->varstr = *e;
9867                         cur_var->max_len = strlen(*e);
9868                         cur_var->flg_export = 1;
9869                 }
9870                 e++;
9871         }
9872         /* (Re)insert HUSH_VERSION into env (AFTER we scanned the env!) */
9873         debug_printf_env("putenv '%s'\n", shell_ver->varstr);
9874         putenv(shell_ver->varstr);
9875
9876         /* Export PWD */
9877         set_pwd_var(SETFLAG_EXPORT);
9878
9879 #if ENABLE_HUSH_INTERACTIVE && ENABLE_FEATURE_EDITING_FANCY_PROMPT
9880         /* Set (but not export) PS1/2 unless already set */
9881         if (!get_local_var_value("PS1"))
9882                 set_local_var_from_halves("PS1", "\\w \\$ ");
9883         if (!get_local_var_value("PS2"))
9884                 set_local_var_from_halves("PS2", "> ");
9885 #endif
9886
9887 #if BASH_HOSTNAME_VAR
9888         /* Set (but not export) HOSTNAME unless already set */
9889         if (!get_local_var_value("HOSTNAME")) {
9890                 struct utsname uts;
9891                 uname(&uts);
9892                 set_local_var_from_halves("HOSTNAME", uts.nodename);
9893         }
9894 #endif
9895         /* IFS is not inherited from the parent environment */
9896         set_local_var_from_halves("IFS", defifs);
9897
9898         /* bash also exports SHLVL and _,
9899          * and sets (but doesn't export) the following variables:
9900          * BASH=/bin/bash
9901          * BASH_VERSINFO=([0]="3" [1]="2" [2]="0" [3]="1" [4]="release" [5]="i386-pc-linux-gnu")
9902          * BASH_VERSION='3.2.0(1)-release'
9903          * HOSTTYPE=i386
9904          * MACHTYPE=i386-pc-linux-gnu
9905          * OSTYPE=linux-gnu
9906          * PPID=<NNNNN> - we also do it elsewhere
9907          * EUID=<NNNNN>
9908          * UID=<NNNNN>
9909          * GROUPS=()
9910          * LINES=<NNN>
9911          * COLUMNS=<NNN>
9912          * BASH_ARGC=()
9913          * BASH_ARGV=()
9914          * BASH_LINENO=()
9915          * BASH_SOURCE=()
9916          * DIRSTACK=()
9917          * PIPESTATUS=([0]="0")
9918          * HISTFILE=/<xxx>/.bash_history
9919          * HISTFILESIZE=500
9920          * HISTSIZE=500
9921          * MAILCHECK=60
9922          * PATH=/usr/gnu/bin:/usr/local/bin:/bin:/usr/bin:.
9923          * SHELL=/bin/bash
9924          * SHELLOPTS=braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor
9925          * TERM=dumb
9926          * OPTERR=1
9927          * OPTIND=1
9928          * PS4='+ '
9929          */
9930
9931 #if ENABLE_HUSH_LINENO_VAR
9932         if (ENABLE_HUSH_LINENO_VAR) {
9933                 char *p = xasprintf("LINENO=%*s", (int)(sizeof(int)*3), "");
9934                 set_local_var(p, /*flags*/ 0);
9935                 G.lineno_var = p; /* can't assign before set_local_var("LINENO=...") */
9936         }
9937 #endif
9938
9939 #if ENABLE_FEATURE_EDITING
9940         G.line_input_state = new_line_input_t(FOR_SHELL);
9941 #endif
9942
9943         /* Initialize some more globals to non-zero values */
9944         cmdedit_update_prompt();
9945
9946         die_func = restore_ttypgrp_and__exit;
9947
9948         /* Shell is non-interactive at first. We need to call
9949          * install_special_sighandlers() if we are going to execute "sh <script>",
9950          * "sh -c <cmds>" or login shell's /etc/profile and friends.
9951          * If we later decide that we are interactive, we run install_special_sighandlers()
9952          * in order to intercept (more) signals.
9953          */
9954
9955         /* Parse options */
9956         /* http://www.opengroup.org/onlinepubs/9699919799/utilities/sh.html */
9957         flags = (argv[0] && argv[0][0] == '-') ? OPT_login : 0;
9958         builtin_argc = 0;
9959 #if NUM_SCRIPTS > 0
9960         if (argc < 0) {
9961                 optarg = get_script_content(-argc - 1);
9962                 optind = 0;
9963                 argc = string_array_len(argv);
9964                 goto run_script;
9965         }
9966 #endif
9967         while (1) {
9968                 int opt = getopt(argc, argv, "+c:exinsl"
9969 #if !BB_MMU
9970                                 "<:$:R:V:"
9971 # if ENABLE_HUSH_FUNCTIONS
9972                                 "F:"
9973 # endif
9974 #endif
9975                 );
9976                 if (opt <= 0)
9977                         break;
9978                 switch (opt) {
9979                 case 'c':
9980                         /* Possibilities:
9981                          * sh ... -c 'script'
9982                          * sh ... -c 'script' ARG0 [ARG1...]
9983                          * On NOMMU, if builtin_argc != 0,
9984                          * sh ... -c 'builtin' BARGV... "" ARG0 [ARG1...]
9985                          * "" needs to be replaced with NULL
9986                          * and BARGV vector fed to builtin function.
9987                          * Note: the form without ARG0 never happens:
9988                          * sh ... -c 'builtin' BARGV... ""
9989                          */
9990 #if NUM_SCRIPTS > 0
9991  run_script:
9992 #endif
9993                         if (!G.root_pid) {
9994                                 G.root_pid = getpid();
9995                                 G.root_ppid = getppid();
9996                         }
9997                         G.global_argv = argv + optind;
9998                         G.global_argc = argc - optind;
9999                         if (builtin_argc) {
10000                                 /* -c 'builtin' [BARGV...] "" ARG0 [ARG1...] */
10001                                 const struct built_in_command *x;
10002
10003                                 install_special_sighandlers();
10004                                 x = find_builtin(optarg);
10005                                 if (x) { /* paranoia */
10006                                         G.global_argc -= builtin_argc; /* skip [BARGV...] "" */
10007                                         G.global_argv += builtin_argc;
10008                                         G.global_argv[-1] = NULL; /* replace "" */
10009                                         fflush_all();
10010                                         G.last_exitcode = x->b_function(argv + optind - 1);
10011                                 }
10012                                 goto final_return;
10013                         }
10014                         if (!G.global_argv[0]) {
10015                                 /* -c 'script' (no params): prevent empty $0 */
10016                                 G.global_argv--; /* points to argv[i] of 'script' */
10017                                 G.global_argv[0] = argv[0];
10018                                 G.global_argc++;
10019                         } /* else -c 'script' ARG0 [ARG1...]: $0 is ARG0 */
10020                         install_special_sighandlers();
10021                         parse_and_run_string(optarg);
10022                         goto final_return;
10023                 case 'i':
10024                         /* Well, we cannot just declare interactiveness,
10025                          * we have to have some stuff (ctty, etc) */
10026                         /* G_interactive_fd++; */
10027                         break;
10028                 case 's':
10029                         flags |= OPT_s;
10030                         break;
10031                 case 'l':
10032                         flags |= OPT_login;
10033                         break;
10034 #if !BB_MMU
10035                 case '<': /* "big heredoc" support */
10036                         full_write1_str(optarg);
10037                         _exit(0);
10038                 case '$': {
10039                         unsigned long long empty_trap_mask;
10040
10041                         G.root_pid = bb_strtou(optarg, &optarg, 16);
10042                         optarg++;
10043                         G.root_ppid = bb_strtou(optarg, &optarg, 16);
10044                         optarg++;
10045                         G.last_bg_pid = bb_strtou(optarg, &optarg, 16);
10046                         optarg++;
10047                         G.last_exitcode = bb_strtou(optarg, &optarg, 16);
10048                         optarg++;
10049                         builtin_argc = bb_strtou(optarg, &optarg, 16);
10050                         optarg++;
10051                         empty_trap_mask = bb_strtoull(optarg, &optarg, 16);
10052                         if (empty_trap_mask != 0) {
10053                                 IF_HUSH_TRAP(int sig;)
10054                                 install_special_sighandlers();
10055 # if ENABLE_HUSH_TRAP
10056                                 G_traps = xzalloc(sizeof(G_traps[0]) * NSIG);
10057                                 for (sig = 1; sig < NSIG; sig++) {
10058                                         if (empty_trap_mask & (1LL << sig)) {
10059                                                 G_traps[sig] = xzalloc(1); /* == xstrdup(""); */
10060                                                 install_sighandler(sig, SIG_IGN);
10061                                         }
10062                                 }
10063 # endif
10064                         }
10065 # if ENABLE_HUSH_LOOPS
10066                         optarg++;
10067                         G.depth_of_loop = bb_strtou(optarg, &optarg, 16);
10068 # endif
10069 # if ENABLE_HUSH_FUNCTIONS
10070                         /* nommu uses re-exec trick for "... | func | ...",
10071                          * should allow "return".
10072                          * This accidentally allows returns in subshells.
10073                          */
10074                         G_flag_return_in_progress = -1;
10075 # endif
10076                         break;
10077                 }
10078                 case 'R':
10079                 case 'V':
10080                         set_local_var(xstrdup(optarg), opt == 'R' ? SETFLAG_MAKE_RO : 0);
10081                         break;
10082 # if ENABLE_HUSH_FUNCTIONS
10083                 case 'F': {
10084                         struct function *funcp = new_function(optarg);
10085                         /* funcp->name is already set to optarg */
10086                         /* funcp->body is set to NULL. It's a special case. */
10087                         funcp->body_as_string = argv[optind];
10088                         optind++;
10089                         break;
10090                 }
10091 # endif
10092 #endif
10093                 case 'n':
10094                 case 'x':
10095                 case 'e':
10096                         if (set_mode(1, opt, NULL) == 0) /* no error */
10097                                 break;
10098                 default:
10099 #ifndef BB_VER
10100                         fprintf(stderr, "Usage: sh [FILE]...\n"
10101                                         "   or: sh -c command [args]...\n\n");
10102                         exit(EXIT_FAILURE);
10103 #else
10104                         bb_show_usage();
10105 #endif
10106                 }
10107         } /* option parsing loop */
10108
10109         /* Skip options. Try "hush -l": $1 should not be "-l"! */
10110         G.global_argc = argc - (optind - 1);
10111         G.global_argv = argv + (optind - 1);
10112         G.global_argv[0] = argv[0];
10113
10114         if (!G.root_pid) {
10115                 G.root_pid = getpid();
10116                 G.root_ppid = getppid();
10117         }
10118
10119         /* If we are login shell... */
10120         if (flags & OPT_login) {
10121                 HFILE *input;
10122                 debug_printf("sourcing /etc/profile\n");
10123                 input = hfopen("/etc/profile");
10124                 if (input != NULL) {
10125                         install_special_sighandlers();
10126                         parse_and_run_file(input);
10127                         hfclose(input);
10128                 }
10129                 /* bash: after sourcing /etc/profile,
10130                  * tries to source (in the given order):
10131                  * ~/.bash_profile, ~/.bash_login, ~/.profile,
10132                  * stopping on first found. --noprofile turns this off.
10133                  * bash also sources ~/.bash_logout on exit.
10134                  * If called as sh, skips .bash_XXX files.
10135                  */
10136         }
10137
10138         /* -s is: hush -s ARGV1 ARGV2 (no SCRIPT) */
10139         if (!(flags & OPT_s) && G.global_argv[1]) {
10140                 HFILE *input;
10141                 /*
10142                  * "bash <script>" (which is never interactive (unless -i?))
10143                  * sources $BASH_ENV here (without scanning $PATH).
10144                  * If called as sh, does the same but with $ENV.
10145                  * Also NB, per POSIX, $ENV should undergo parameter expansion.
10146                  */
10147                 G.global_argc--;
10148                 G.global_argv++;
10149                 debug_printf("running script '%s'\n", G.global_argv[0]);
10150                 xfunc_error_retval = 127; /* for "hush /does/not/exist" case */
10151                 input = hfopen(G.global_argv[0]);
10152                 if (!input) {
10153                         bb_simple_perror_msg_and_die(G.global_argv[0]);
10154                 }
10155                 xfunc_error_retval = 1;
10156                 install_special_sighandlers();
10157                 parse_and_run_file(input);
10158 #if ENABLE_FEATURE_CLEAN_UP
10159                 hfclose(input);
10160 #endif
10161                 goto final_return;
10162         }
10163
10164         /* Up to here, shell was non-interactive. Now it may become one.
10165          * NB: don't forget to (re)run install_special_sighandlers() as needed.
10166          */
10167
10168         /* A shell is interactive if the '-i' flag was given,
10169          * or if all of the following conditions are met:
10170          *    no -c command
10171          *    no arguments remaining or the -s flag given
10172          *    standard input is a terminal
10173          *    standard output is a terminal
10174          * Refer to Posix.2, the description of the 'sh' utility.
10175          */
10176 #if ENABLE_HUSH_JOB
10177         if (isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)) {
10178                 G_saved_tty_pgrp = tcgetpgrp(STDIN_FILENO);
10179                 debug_printf("saved_tty_pgrp:%d\n", G_saved_tty_pgrp);
10180                 if (G_saved_tty_pgrp < 0)
10181                         G_saved_tty_pgrp = 0;
10182
10183                 /* try to dup stdin to high fd#, >= 255 */
10184                 G_interactive_fd = dup_CLOEXEC(STDIN_FILENO, 254);
10185                 if (G_interactive_fd < 0) {
10186                         /* try to dup to any fd */
10187                         G_interactive_fd = dup(STDIN_FILENO);
10188                         if (G_interactive_fd < 0) {
10189                                 /* give up */
10190                                 G_interactive_fd = 0;
10191                                 G_saved_tty_pgrp = 0;
10192                         }
10193                 }
10194 // TODO: track & disallow any attempts of user
10195 // to (inadvertently) close/redirect G_interactive_fd
10196         }
10197         debug_printf("interactive_fd:%d\n", G_interactive_fd);
10198         if (G_interactive_fd) {
10199                 close_on_exec_on(G_interactive_fd);
10200
10201                 if (G_saved_tty_pgrp) {
10202                         /* If we were run as 'hush &', sleep until we are
10203                          * in the foreground (tty pgrp == our pgrp).
10204                          * If we get started under a job aware app (like bash),
10205                          * make sure we are now in charge so we don't fight over
10206                          * who gets the foreground */
10207                         while (1) {
10208                                 pid_t shell_pgrp = getpgrp();
10209                                 G_saved_tty_pgrp = tcgetpgrp(G_interactive_fd);
10210                                 if (G_saved_tty_pgrp == shell_pgrp)
10211                                         break;
10212                                 /* send TTIN to ourself (should stop us) */
10213                                 kill(- shell_pgrp, SIGTTIN);
10214                         }
10215                 }
10216
10217                 /* Install more signal handlers */
10218                 install_special_sighandlers();
10219
10220                 if (G_saved_tty_pgrp) {
10221                         /* Set other signals to restore saved_tty_pgrp */
10222                         install_fatal_sighandlers();
10223                         /* Put ourselves in our own process group
10224                          * (bash, too, does this only if ctty is available) */
10225                         bb_setpgrp(); /* is the same as setpgid(our_pid, our_pid); */
10226                         /* Grab control of the terminal */
10227                         tcsetpgrp(G_interactive_fd, getpid());
10228                 }
10229                 enable_restore_tty_pgrp_on_exit();
10230
10231 # if ENABLE_HUSH_SAVEHISTORY && MAX_HISTORY > 0
10232                 {
10233                         const char *hp = get_local_var_value("HISTFILE");
10234                         if (!hp) {
10235                                 hp = get_local_var_value("HOME");
10236                                 if (hp)
10237                                         hp = concat_path_file(hp, ".hush_history");
10238                         } else {
10239                                 hp = xstrdup(hp);
10240                         }
10241                         if (hp) {
10242                                 G.line_input_state->hist_file = hp;
10243                                 //set_local_var(xasprintf("HISTFILE=%s", ...));
10244                         }
10245 #  if ENABLE_FEATURE_SH_HISTFILESIZE
10246                         hp = get_local_var_value("HISTFILESIZE");
10247                         G.line_input_state->max_history = size_from_HISTFILESIZE(hp);
10248 #  endif
10249                 }
10250 # endif
10251         } else {
10252                 install_special_sighandlers();
10253         }
10254 #elif ENABLE_HUSH_INTERACTIVE
10255         /* No job control compiled in, only prompt/line editing */
10256         if (isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)) {
10257                 G_interactive_fd = dup_CLOEXEC(STDIN_FILENO, 254);
10258                 if (G_interactive_fd < 0) {
10259                         /* try to dup to any fd */
10260                         G_interactive_fd = dup_CLOEXEC(STDIN_FILENO, -1);
10261                         if (G_interactive_fd < 0)
10262                                 /* give up */
10263                                 G_interactive_fd = 0;
10264                 }
10265         }
10266         if (G_interactive_fd) {
10267                 close_on_exec_on(G_interactive_fd);
10268         }
10269         install_special_sighandlers();
10270 #else
10271         /* We have interactiveness code disabled */
10272         install_special_sighandlers();
10273 #endif
10274         /* bash:
10275          * if interactive but not a login shell, sources ~/.bashrc
10276          * (--norc turns this off, --rcfile <file> overrides)
10277          */
10278
10279         if (!ENABLE_FEATURE_SH_EXTRA_QUIET && G_interactive_fd) {
10280                 /* note: ash and hush share this string */
10281                 printf("\n\n%s %s\n"
10282                         IF_HUSH_HELP("Enter 'help' for a list of built-in commands.\n")
10283                         "\n",
10284                         bb_banner,
10285                         "hush - the humble shell"
10286                 );
10287         }
10288
10289         parse_and_run_file(hfopen(NULL)); /* stdin */
10290
10291  final_return:
10292         hush_exit(G.last_exitcode);
10293 }
10294
10295
10296 /*
10297  * Built-ins
10298  */
10299 static int FAST_FUNC builtin_true(char **argv UNUSED_PARAM)
10300 {
10301         return 0;
10302 }
10303
10304 #if ENABLE_HUSH_TEST || ENABLE_HUSH_ECHO || ENABLE_HUSH_PRINTF || ENABLE_HUSH_KILL
10305 static int run_applet_main(char **argv, int (*applet_main_func)(int argc, char **argv))
10306 {
10307         int argc = string_array_len(argv);
10308         return applet_main_func(argc, argv);
10309 }
10310 #endif
10311 #if ENABLE_HUSH_TEST || BASH_TEST2
10312 static int FAST_FUNC builtin_test(char **argv)
10313 {
10314         return run_applet_main(argv, test_main);
10315 }
10316 #endif
10317 #if ENABLE_HUSH_ECHO
10318 static int FAST_FUNC builtin_echo(char **argv)
10319 {
10320         return run_applet_main(argv, echo_main);
10321 }
10322 #endif
10323 #if ENABLE_HUSH_PRINTF
10324 static int FAST_FUNC builtin_printf(char **argv)
10325 {
10326         return run_applet_main(argv, printf_main);
10327 }
10328 #endif
10329
10330 #if ENABLE_HUSH_HELP
10331 static int FAST_FUNC builtin_help(char **argv UNUSED_PARAM)
10332 {
10333         const struct built_in_command *x;
10334
10335         printf(
10336                 "Built-in commands:\n"
10337                 "------------------\n");
10338         for (x = bltins1; x != &bltins1[ARRAY_SIZE(bltins1)]; x++) {
10339                 if (x->b_descr)
10340                         printf("%-10s%s\n", x->b_cmd, x->b_descr);
10341         }
10342         return EXIT_SUCCESS;
10343 }
10344 #endif
10345
10346 #if MAX_HISTORY && ENABLE_FEATURE_EDITING
10347 static int FAST_FUNC builtin_history(char **argv UNUSED_PARAM)
10348 {
10349         show_history(G.line_input_state);
10350         return EXIT_SUCCESS;
10351 }
10352 #endif
10353
10354 static char **skip_dash_dash(char **argv)
10355 {
10356         argv++;
10357         if (argv[0] && argv[0][0] == '-' && argv[0][1] == '-' && argv[0][2] == '\0')
10358                 argv++;
10359         return argv;
10360 }
10361
10362 static int FAST_FUNC builtin_cd(char **argv)
10363 {
10364         const char *newdir;
10365
10366         argv = skip_dash_dash(argv);
10367         newdir = argv[0];
10368         if (newdir == NULL) {
10369                 /* bash does nothing (exitcode 0) if HOME is ""; if it's unset,
10370                  * bash says "bash: cd: HOME not set" and does nothing
10371                  * (exitcode 1)
10372                  */
10373                 const char *home = get_local_var_value("HOME");
10374                 newdir = home ? home : "/";
10375         }
10376         if (chdir(newdir)) {
10377                 /* Mimic bash message exactly */
10378                 bb_perror_msg("cd: %s", newdir);
10379                 return EXIT_FAILURE;
10380         }
10381         /* Read current dir (get_cwd(1) is inside) and set PWD.
10382          * Note: do not enforce exporting. If PWD was unset or unexported,
10383          * set it again, but do not export. bash does the same.
10384          */
10385         set_pwd_var(/*flag:*/ 0);
10386         return EXIT_SUCCESS;
10387 }
10388
10389 static int FAST_FUNC builtin_pwd(char **argv UNUSED_PARAM)
10390 {
10391         puts(get_cwd(0));
10392         return EXIT_SUCCESS;
10393 }
10394
10395 static int FAST_FUNC builtin_eval(char **argv)
10396 {
10397         argv = skip_dash_dash(argv);
10398
10399         if (!argv[0])
10400                 return EXIT_SUCCESS;
10401
10402         IF_HUSH_MODE_X(G.x_mode_depth++;)
10403         //bb_error_msg("%s: ++x_mode_depth=%d", __func__, G.x_mode_depth);
10404         if (!argv[1]) {
10405                 /* bash:
10406                  * eval "echo Hi; done" ("done" is syntax error):
10407                  * "echo Hi" will not execute too.
10408                  */
10409                 parse_and_run_string(argv[0]);
10410         } else {
10411                 /* "The eval utility shall construct a command by
10412                  * concatenating arguments together, separating
10413                  * each with a <space> character."
10414                  */
10415                 char *str, *p;
10416                 unsigned len = 0;
10417                 char **pp = argv;
10418                 do
10419                         len += strlen(*pp) + 1;
10420                 while (*++pp);
10421                 str = p = xmalloc(len);
10422                 pp = argv;
10423                 for (;;) {
10424                         p = stpcpy(p, *pp);
10425                         pp++;
10426                         if (!*pp)
10427                                 break;
10428                         *p++ = ' ';
10429                 }
10430                 parse_and_run_string(str);
10431                 free(str);
10432         }
10433         IF_HUSH_MODE_X(G.x_mode_depth--;)
10434         //bb_error_msg("%s: --x_mode_depth=%d", __func__, G.x_mode_depth);
10435         return G.last_exitcode;
10436 }
10437
10438 static int FAST_FUNC builtin_exec(char **argv)
10439 {
10440         argv = skip_dash_dash(argv);
10441         if (argv[0] == NULL)
10442                 return EXIT_SUCCESS; /* bash does this */
10443
10444         /* Careful: we can end up here after [v]fork. Do not restore
10445          * tty pgrp then, only top-level shell process does that */
10446         if (G_saved_tty_pgrp && getpid() == G.root_pid)
10447                 tcsetpgrp(G_interactive_fd, G_saved_tty_pgrp);
10448
10449         /* Saved-redirect fds, script fds and G_interactive_fd are still
10450          * open here. However, they are all CLOEXEC, and execv below
10451          * closes them. Try interactive "exec ls -l /proc/self/fd",
10452          * it should show no extra open fds in the "ls" process.
10453          * If we'd try to run builtins/NOEXECs, this would need improving.
10454          */
10455         //close_saved_fds_and_FILE_fds();
10456
10457         /* TODO: if exec fails, bash does NOT exit! We do.
10458          * We'll need to undo trap cleanup (it's inside execvp_or_die)
10459          * and tcsetpgrp, and this is inherently racy.
10460          */
10461         execvp_or_die(argv);
10462 }
10463
10464 static int FAST_FUNC builtin_exit(char **argv)
10465 {
10466         debug_printf_exec("%s()\n", __func__);
10467
10468         /* interactive bash:
10469          * # trap "echo EEE" EXIT
10470          * # exit
10471          * exit
10472          * There are stopped jobs.
10473          * (if there are _stopped_ jobs, running ones don't count)
10474          * # exit
10475          * exit
10476          * EEE (then bash exits)
10477          *
10478          * TODO: we can use G.exiting = -1 as indicator "last cmd was exit"
10479          */
10480
10481         /* note: EXIT trap is run by hush_exit */
10482         argv = skip_dash_dash(argv);
10483         if (argv[0] == NULL)
10484                 hush_exit(G.last_exitcode);
10485         /* mimic bash: exit 123abc == exit 255 + error msg */
10486         xfunc_error_retval = 255;
10487         /* bash: exit -2 == exit 254, no error msg */
10488         hush_exit(xatoi(argv[0]) & 0xff);
10489 }
10490
10491 #if ENABLE_HUSH_TYPE
10492 /* http://www.opengroup.org/onlinepubs/9699919799/utilities/type.html */
10493 static int FAST_FUNC builtin_type(char **argv)
10494 {
10495         int ret = EXIT_SUCCESS;
10496
10497         while (*++argv) {
10498                 const char *type;
10499                 char *path = NULL;
10500
10501                 if (0) {} /* make conditional compile easier below */
10502                 /*else if (find_alias(*argv))
10503                         type = "an alias";*/
10504 #if ENABLE_HUSH_FUNCTIONS
10505                 else if (find_function(*argv))
10506                         type = "a function";
10507 #endif
10508                 else if (find_builtin(*argv))
10509                         type = "a shell builtin";
10510                 else if ((path = find_in_path(*argv)) != NULL)
10511                         type = path;
10512                 else {
10513                         bb_error_msg("type: %s: not found", *argv);
10514                         ret = EXIT_FAILURE;
10515                         continue;
10516                 }
10517
10518                 printf("%s is %s\n", *argv, type);
10519                 free(path);
10520         }
10521
10522         return ret;
10523 }
10524 #endif
10525
10526 #if ENABLE_HUSH_READ
10527 /* Interruptibility of read builtin in bash
10528  * (tested on bash-4.2.8 by sending signals (not by ^C)):
10529  *
10530  * Empty trap makes read ignore corresponding signal, for any signal.
10531  *
10532  * SIGINT:
10533  * - terminates non-interactive shell;
10534  * - interrupts read in interactive shell;
10535  * if it has non-empty trap:
10536  * - executes trap and returns to command prompt in interactive shell;
10537  * - executes trap and returns to read in non-interactive shell;
10538  * SIGTERM:
10539  * - is ignored (does not interrupt) read in interactive shell;
10540  * - terminates non-interactive shell;
10541  * if it has non-empty trap:
10542  * - executes trap and returns to read;
10543  * SIGHUP:
10544  * - terminates shell (regardless of interactivity);
10545  * if it has non-empty trap:
10546  * - executes trap and returns to read;
10547  * SIGCHLD from children:
10548  * - does not interrupt read regardless of interactivity:
10549  *   try: sleep 1 & read x; echo $x
10550  */
10551 static int FAST_FUNC builtin_read(char **argv)
10552 {
10553         const char *r;
10554         struct builtin_read_params params;
10555
10556         memset(&params, 0, sizeof(params));
10557
10558         /* "!": do not abort on errors.
10559          * Option string must start with "sr" to match BUILTIN_READ_xxx
10560          */
10561         params.read_flags = getopt32(argv,
10562 #if BASH_READ_D
10563                 "!srn:p:t:u:d:", &params.opt_n, &params.opt_p, &params.opt_t, &params.opt_u, &params.opt_d
10564 #else
10565                 "!srn:p:t:u:", &params.opt_n, &params.opt_p, &params.opt_t, &params.opt_u
10566 #endif
10567         );
10568         if ((uint32_t)params.read_flags == (uint32_t)-1)
10569                 return EXIT_FAILURE;
10570         argv += optind;
10571         params.argv = argv;
10572         params.setvar = set_local_var_from_halves;
10573         params.ifs = get_local_var_value("IFS"); /* can be NULL */
10574
10575  again:
10576         r = shell_builtin_read(&params);
10577
10578         if ((uintptr_t)r == 1 && errno == EINTR) {
10579                 unsigned sig = check_and_run_traps();
10580                 if (sig != SIGINT)
10581                         goto again;
10582         }
10583
10584         if ((uintptr_t)r > 1) {
10585                 bb_error_msg("%s", r);
10586                 r = (char*)(uintptr_t)1;
10587         }
10588
10589         return (uintptr_t)r;
10590 }
10591 #endif
10592
10593 #if ENABLE_HUSH_UMASK
10594 static int FAST_FUNC builtin_umask(char **argv)
10595 {
10596         int rc;
10597         mode_t mask;
10598
10599         rc = 1;
10600         mask = umask(0);
10601         argv = skip_dash_dash(argv);
10602         if (argv[0]) {
10603                 mode_t old_mask = mask;
10604
10605                 /* numeric umasks are taken as-is */
10606                 /* symbolic umasks are inverted: "umask a=rx" calls umask(222) */
10607                 if (!isdigit(argv[0][0]))
10608                         mask ^= 0777;
10609                 mask = bb_parse_mode(argv[0], mask);
10610                 if (!isdigit(argv[0][0]))
10611                         mask ^= 0777;
10612                 if ((unsigned)mask > 0777) {
10613                         mask = old_mask;
10614                         /* bash messages:
10615                          * bash: umask: 'q': invalid symbolic mode operator
10616                          * bash: umask: 999: octal number out of range
10617                          */
10618                         bb_error_msg("%s: invalid mode '%s'", "umask", argv[0]);
10619                         rc = 0;
10620                 }
10621         } else {
10622                 /* Mimic bash */
10623                 printf("%04o\n", (unsigned) mask);
10624                 /* fall through and restore mask which we set to 0 */
10625         }
10626         umask(mask);
10627
10628         return !rc; /* rc != 0 - success */
10629 }
10630 #endif
10631
10632 #if ENABLE_HUSH_EXPORT || ENABLE_HUSH_TRAP
10633 static void print_escaped(const char *s)
10634 {
10635         if (*s == '\'')
10636                 goto squote;
10637         do {
10638                 const char *p = strchrnul(s, '\'');
10639                 /* print 'xxxx', possibly just '' */
10640                 printf("'%.*s'", (int)(p - s), s);
10641                 if (*p == '\0')
10642                         break;
10643                 s = p;
10644  squote:
10645                 /* s points to '; print "'''...'''" */
10646                 putchar('"');
10647                 do putchar('\''); while (*++s == '\'');
10648                 putchar('"');
10649         } while (*s);
10650 }
10651 #endif
10652
10653 #if ENABLE_HUSH_EXPORT || ENABLE_HUSH_LOCAL || ENABLE_HUSH_READONLY
10654 static int helper_export_local(char **argv, unsigned flags)
10655 {
10656         do {
10657                 char *name = *argv;
10658                 char *name_end = strchrnul(name, '=');
10659
10660                 /* So far we do not check that name is valid (TODO?) */
10661
10662                 if (*name_end == '\0') {
10663                         struct variable *var, **vpp;
10664
10665                         vpp = get_ptr_to_local_var(name, name_end - name);
10666                         var = vpp ? *vpp : NULL;
10667
10668                         if (flags & SETFLAG_UNEXPORT) {
10669                                 /* export -n NAME (without =VALUE) */
10670                                 if (var) {
10671                                         var->flg_export = 0;
10672                                         debug_printf_env("%s: unsetenv '%s'\n", __func__, name);
10673                                         unsetenv(name);
10674                                 } /* else: export -n NOT_EXISTING_VAR: no-op */
10675                                 continue;
10676                         }
10677                         if (flags & SETFLAG_EXPORT) {
10678                                 /* export NAME (without =VALUE) */
10679                                 if (var) {
10680                                         var->flg_export = 1;
10681                                         debug_printf_env("%s: putenv '%s'\n", __func__, var->varstr);
10682                                         putenv(var->varstr);
10683                                         continue;
10684                                 }
10685                         }
10686                         if (flags & SETFLAG_MAKE_RO) {
10687                                 /* readonly NAME (without =VALUE) */
10688                                 if (var) {
10689                                         var->flg_read_only = 1;
10690                                         continue;
10691                                 }
10692                         }
10693 # if ENABLE_HUSH_LOCAL
10694                         /* Is this "local" bltin? */
10695                         if (!(flags & (SETFLAG_EXPORT|SETFLAG_UNEXPORT|SETFLAG_MAKE_RO))) {
10696                                 unsigned lvl = flags >> SETFLAG_VARLVL_SHIFT;
10697                                 if (var && var->var_nest_level == lvl) {
10698                                         /* "local x=abc; ...; local x" - ignore second local decl */
10699                                         continue;
10700                                 }
10701                         }
10702 # endif
10703                         /* Exporting non-existing variable.
10704                          * bash does not put it in environment,
10705                          * but remembers that it is exported,
10706                          * and does put it in env when it is set later.
10707                          * We just set it to "" and export.
10708                          */
10709                         /* Or, it's "local NAME" (without =VALUE).
10710                          * bash sets the value to "".
10711                          */
10712                         /* Or, it's "readonly NAME" (without =VALUE).
10713                          * bash remembers NAME and disallows its creation
10714                          * in the future.
10715                          */
10716                         name = xasprintf("%s=", name);
10717                 } else {
10718                         /* (Un)exporting/making local NAME=VALUE */
10719                         name = xstrdup(name);
10720                 }
10721                 debug_printf_env("%s: set_local_var('%s')\n", __func__, name);
10722                 if (set_local_var(name, flags))
10723                         return EXIT_FAILURE;
10724         } while (*++argv);
10725         return EXIT_SUCCESS;
10726 }
10727 #endif
10728
10729 #if ENABLE_HUSH_EXPORT
10730 static int FAST_FUNC builtin_export(char **argv)
10731 {
10732         unsigned opt_unexport;
10733
10734 #if ENABLE_HUSH_EXPORT_N
10735         /* "!": do not abort on errors */
10736         opt_unexport = getopt32(argv, "!n");
10737         if (opt_unexport == (uint32_t)-1)
10738                 return EXIT_FAILURE;
10739         argv += optind;
10740 #else
10741         opt_unexport = 0;
10742         argv++;
10743 #endif
10744
10745         if (argv[0] == NULL) {
10746                 char **e = environ;
10747                 if (e) {
10748                         while (*e) {
10749 #if 0
10750                                 puts(*e++);
10751 #else
10752                                 /* ash emits: export VAR='VAL'
10753                                  * bash: declare -x VAR="VAL"
10754                                  * we follow ash example */
10755                                 const char *s = *e++;
10756                                 const char *p = strchr(s, '=');
10757
10758                                 if (!p) /* wtf? take next variable */
10759                                         continue;
10760                                 /* export var= */
10761                                 printf("export %.*s", (int)(p - s) + 1, s);
10762                                 print_escaped(p + 1);
10763                                 putchar('\n');
10764 #endif
10765                         }
10766                         /*fflush_all(); - done after each builtin anyway */
10767                 }
10768                 return EXIT_SUCCESS;
10769         }
10770
10771         return helper_export_local(argv, opt_unexport ? SETFLAG_UNEXPORT : SETFLAG_EXPORT);
10772 }
10773 #endif
10774
10775 #if ENABLE_HUSH_LOCAL
10776 static int FAST_FUNC builtin_local(char **argv)
10777 {
10778         if (G.func_nest_level == 0) {
10779                 bb_error_msg("%s: not in a function", argv[0]);
10780                 return EXIT_FAILURE; /* bash compat */
10781         }
10782         argv++;
10783         /* Since all builtins run in a nested variable level,
10784          * need to use level - 1 here. Or else the variable will be removed at once
10785          * after builtin returns.
10786          */
10787         return helper_export_local(argv, (G.var_nest_level - 1) << SETFLAG_VARLVL_SHIFT);
10788 }
10789 #endif
10790
10791 #if ENABLE_HUSH_READONLY
10792 static int FAST_FUNC builtin_readonly(char **argv)
10793 {
10794         argv++;
10795         if (*argv == NULL) {
10796                 /* bash: readonly [-p]: list all readonly VARs
10797                  * (-p has no effect in bash)
10798                  */
10799                 struct variable *e;
10800                 for (e = G.top_var; e; e = e->next) {
10801                         if (e->flg_read_only) {
10802 //TODO: quote value: readonly VAR='VAL'
10803                                 printf("readonly %s\n", e->varstr);
10804                         }
10805                 }
10806                 return EXIT_SUCCESS;
10807         }
10808         return helper_export_local(argv, SETFLAG_MAKE_RO);
10809 }
10810 #endif
10811
10812 #if ENABLE_HUSH_UNSET
10813 /* http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#unset */
10814 static int FAST_FUNC builtin_unset(char **argv)
10815 {
10816         int ret;
10817         unsigned opts;
10818
10819         /* "!": do not abort on errors */
10820         /* "+": stop at 1st non-option */
10821         opts = getopt32(argv, "!+vf");
10822         if (opts == (unsigned)-1)
10823                 return EXIT_FAILURE;
10824         if (opts == 3) {
10825                 bb_error_msg("unset: -v and -f are exclusive");
10826                 return EXIT_FAILURE;
10827         }
10828         argv += optind;
10829
10830         ret = EXIT_SUCCESS;
10831         while (*argv) {
10832                 if (!(opts & 2)) { /* not -f */
10833                         if (unset_local_var(*argv)) {
10834                                 /* unset <nonexistent_var> doesn't fail.
10835                                  * Error is when one tries to unset RO var.
10836                                  * Message was printed by unset_local_var. */
10837                                 ret = EXIT_FAILURE;
10838                         }
10839                 }
10840 # if ENABLE_HUSH_FUNCTIONS
10841                 else {
10842                         unset_func(*argv);
10843                 }
10844 # endif
10845                 argv++;
10846         }
10847         return ret;
10848 }
10849 #endif
10850
10851 #if ENABLE_HUSH_SET
10852 /* http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#set
10853  * built-in 'set' handler
10854  * SUSv3 says:
10855  * set [-abCefhmnuvx] [-o option] [argument...]
10856  * set [+abCefhmnuvx] [+o option] [argument...]
10857  * set -- [argument...]
10858  * set -o
10859  * set +o
10860  * Implementations shall support the options in both their hyphen and
10861  * plus-sign forms. These options can also be specified as options to sh.
10862  * Examples:
10863  * Write out all variables and their values: set
10864  * Set $1, $2, and $3 and set "$#" to 3: set c a b
10865  * Turn on the -x and -v options: set -xv
10866  * Unset all positional parameters: set --
10867  * Set $1 to the value of x, even if it begins with '-' or '+': set -- "$x"
10868  * Set the positional parameters to the expansion of x, even if x expands
10869  * with a leading '-' or '+': set -- $x
10870  *
10871  * So far, we only support "set -- [argument...]" and some of the short names.
10872  */
10873 static int FAST_FUNC builtin_set(char **argv)
10874 {
10875         int n;
10876         char **pp, **g_argv;
10877         char *arg = *++argv;
10878
10879         if (arg == NULL) {
10880                 struct variable *e;
10881                 for (e = G.top_var; e; e = e->next)
10882                         puts(e->varstr);
10883                 return EXIT_SUCCESS;
10884         }
10885
10886         do {
10887                 if (strcmp(arg, "--") == 0) {
10888                         ++argv;
10889                         goto set_argv;
10890                 }
10891                 if (arg[0] != '+' && arg[0] != '-')
10892                         break;
10893                 for (n = 1; arg[n]; ++n) {
10894                         if (set_mode((arg[0] == '-'), arg[n], argv[1]))
10895                                 goto error;
10896                         if (arg[n] == 'o' && argv[1])
10897                                 argv++;
10898                 }
10899         } while ((arg = *++argv) != NULL);
10900         /* Now argv[0] is 1st argument */
10901
10902         if (arg == NULL)
10903                 return EXIT_SUCCESS;
10904  set_argv:
10905
10906         /* NB: G.global_argv[0] ($0) is never freed/changed */
10907         g_argv = G.global_argv;
10908         if (G.global_args_malloced) {
10909                 pp = g_argv;
10910                 while (*++pp)
10911                         free(*pp);
10912                 g_argv[1] = NULL;
10913         } else {
10914                 G.global_args_malloced = 1;
10915                 pp = xzalloc(sizeof(pp[0]) * 2);
10916                 pp[0] = g_argv[0]; /* retain $0 */
10917                 g_argv = pp;
10918         }
10919         /* This realloc's G.global_argv */
10920         G.global_argv = pp = add_strings_to_strings(g_argv, argv, /*dup:*/ 1);
10921
10922         G.global_argc = 1 + string_array_len(pp + 1);
10923
10924         return EXIT_SUCCESS;
10925
10926         /* Nothing known, so abort */
10927  error:
10928         bb_error_msg("%s: %s: invalid option", "set", arg);
10929         return EXIT_FAILURE;
10930 }
10931 #endif
10932
10933 static int FAST_FUNC builtin_shift(char **argv)
10934 {
10935         int n = 1;
10936         argv = skip_dash_dash(argv);
10937         if (argv[0]) {
10938                 n = bb_strtou(argv[0], NULL, 10);
10939                 if (errno || n < 0) {
10940                         /* shared string with ash.c */
10941                         bb_error_msg("Illegal number: %s", argv[0]);
10942                         /*
10943                          * ash aborts in this case.
10944                          * bash prints error message and set $? to 1.
10945                          * Interestingly, for "shift 99999" bash does not
10946                          * print error message, but does set $? to 1
10947                          * (and does no shifting at all).
10948                          */
10949                 }
10950         }
10951         if (n >= 0 && n < G.global_argc) {
10952                 if (G_global_args_malloced) {
10953                         int m = 1;
10954                         while (m <= n)
10955                                 free(G.global_argv[m++]);
10956                 }
10957                 G.global_argc -= n;
10958                 memmove(&G.global_argv[1], &G.global_argv[n+1],
10959                                 G.global_argc * sizeof(G.global_argv[0]));
10960                 return EXIT_SUCCESS;
10961         }
10962         return EXIT_FAILURE;
10963 }
10964
10965 #if ENABLE_HUSH_GETOPTS
10966 static int FAST_FUNC builtin_getopts(char **argv)
10967 {
10968 /* http://pubs.opengroup.org/onlinepubs/9699919799/utilities/getopts.html
10969
10970 TODO:
10971 If a required argument is not found, and getopts is not silent,
10972 a question mark (?) is placed in VAR, OPTARG is unset, and a
10973 diagnostic message is printed.  If getopts is silent, then a
10974 colon (:) is placed in VAR and OPTARG is set to the option
10975 character found.
10976
10977 Test that VAR is a valid variable name?
10978
10979 "Whenever the shell is invoked, OPTIND shall be initialized to 1"
10980 */
10981         char cbuf[2];
10982         const char *cp, *optstring, *var;
10983         int c, n, exitcode, my_opterr;
10984         unsigned count;
10985
10986         optstring = *++argv;
10987         if (!optstring || !(var = *++argv)) {
10988                 bb_error_msg("usage: getopts OPTSTRING VAR [ARGS]");
10989                 return EXIT_FAILURE;
10990         }
10991
10992         if (argv[1])
10993                 argv[0] = G.global_argv[0]; /* for error messages in getopt() */
10994         else
10995                 argv = G.global_argv;
10996         cbuf[1] = '\0';
10997
10998         my_opterr = 0;
10999         if (optstring[0] != ':') {
11000                 cp = get_local_var_value("OPTERR");
11001                 /* 0 if "OPTERR=0", 1 otherwise */
11002                 my_opterr = (!cp || NOT_LONE_CHAR(cp, '0'));
11003         }
11004
11005         /* getopts stops on first non-option. Add "+" to force that */
11006         /*if (optstring[0] != '+')*/ {
11007                 char *s = alloca(strlen(optstring) + 2);
11008                 sprintf(s, "+%s", optstring);
11009                 optstring = s;
11010         }
11011
11012         /* Naively, now we should just
11013          *      cp = get_local_var_value("OPTIND");
11014          *      optind = cp ? atoi(cp) : 0;
11015          *      optarg = NULL;
11016          *      opterr = my_opterr;
11017          *      c = getopt(string_array_len(argv), argv, optstring);
11018          * and be done? Not so fast...
11019          * Unlike normal getopt() usage in C programs, here
11020          * each successive call will (usually) have the same argv[] CONTENTS,
11021          * but not the ADDRESSES. Worse yet, it's possible that between
11022          * invocations of "getopts", there will be calls to shell builtins
11023          * which use getopt() internally. Example:
11024          *      while getopts "abc" RES -a -bc -abc de; do
11025          *              unset -ff func
11026          *      done
11027          * This would not work correctly: getopt() call inside "unset"
11028          * modifies internal libc state which is tracking position in
11029          * multi-option strings ("-abc"). At best, it can skip options
11030          * or return the same option infinitely. With glibc implementation
11031          * of getopt(), it would use outright invalid pointers and return
11032          * garbage even _without_ "unset" mangling internal state.
11033          *
11034          * We resort to resetting getopt() state and calling it N times,
11035          * until we get Nth result (or failure).
11036          * (N == G.getopt_count is reset to 0 whenever OPTIND is [un]set).
11037          */
11038         GETOPT_RESET();
11039         count = 0;
11040         n = string_array_len(argv);
11041         do {
11042                 optarg = NULL;
11043                 opterr = (count < G.getopt_count) ? 0 : my_opterr;
11044                 c = getopt(n, argv, optstring);
11045                 if (c < 0)
11046                         break;
11047                 count++;
11048         } while (count <= G.getopt_count);
11049
11050         /* Set OPTIND. Prevent resetting of the magic counter! */
11051         set_local_var_from_halves("OPTIND", utoa(optind));
11052         G.getopt_count = count; /* "next time, give me N+1'th result" */
11053         GETOPT_RESET(); /* just in case */
11054
11055         /* Set OPTARG */
11056         /* Always set or unset, never left as-is, even on exit/error:
11057          * "If no option was found, or if the option that was found
11058          * does not have an option-argument, OPTARG shall be unset."
11059          */
11060         cp = optarg;
11061         if (c == '?') {
11062                 /* If ":optstring" and unknown option is seen,
11063                  * it is stored to OPTARG.
11064                  */
11065                 if (optstring[1] == ':') {
11066                         cbuf[0] = optopt;
11067                         cp = cbuf;
11068                 }
11069         }
11070         if (cp)
11071                 set_local_var_from_halves("OPTARG", cp);
11072         else
11073                 unset_local_var("OPTARG");
11074
11075         /* Convert -1 to "?" */
11076         exitcode = EXIT_SUCCESS;
11077         if (c < 0) { /* -1: end of options */
11078                 exitcode = EXIT_FAILURE;
11079                 c = '?';
11080         }
11081
11082         /* Set VAR */
11083         cbuf[0] = c;
11084         set_local_var_from_halves(var, cbuf);
11085
11086         return exitcode;
11087 }
11088 #endif
11089
11090 static int FAST_FUNC builtin_source(char **argv)
11091 {
11092         char *arg_path, *filename;
11093         HFILE *input;
11094         save_arg_t sv;
11095         char *args_need_save;
11096 #if ENABLE_HUSH_FUNCTIONS
11097         smallint sv_flg;
11098 #endif
11099
11100         argv = skip_dash_dash(argv);
11101         filename = argv[0];
11102         if (!filename) {
11103                 /* bash says: "bash: .: filename argument required" */
11104                 return 2; /* bash compat */
11105         }
11106         arg_path = NULL;
11107         if (!strchr(filename, '/')) {
11108                 arg_path = find_in_path(filename);
11109                 if (arg_path)
11110                         filename = arg_path;
11111                 else if (!ENABLE_HUSH_BASH_SOURCE_CURDIR) {
11112                         errno = ENOENT;
11113                         bb_simple_perror_msg(filename);
11114                         return EXIT_FAILURE;
11115                 }
11116         }
11117         input = hfopen(filename);
11118         free(arg_path);
11119         if (!input) {
11120                 bb_perror_msg("%s", filename);
11121                 /* POSIX: non-interactive shell should abort here,
11122                  * not merely fail. So far no one complained :)
11123                  */
11124                 return EXIT_FAILURE;
11125         }
11126
11127 #if ENABLE_HUSH_FUNCTIONS
11128         sv_flg = G_flag_return_in_progress;
11129         /* "we are inside sourced file, ok to use return" */
11130         G_flag_return_in_progress = -1;
11131 #endif
11132         args_need_save = argv[1]; /* used as a boolean variable */
11133         if (args_need_save)
11134                 save_and_replace_G_args(&sv, argv);
11135
11136         /* "false; . ./empty_line; echo Zero:$?" should print 0 */
11137         G.last_exitcode = 0;
11138         parse_and_run_file(input);
11139         hfclose(input);
11140
11141         if (args_need_save) /* can't use argv[1] instead: "shift" can mangle it */
11142                 restore_G_args(&sv, argv);
11143 #if ENABLE_HUSH_FUNCTIONS
11144         G_flag_return_in_progress = sv_flg;
11145 #endif
11146
11147         return G.last_exitcode;
11148 }
11149
11150 #if ENABLE_HUSH_TRAP
11151 static int FAST_FUNC builtin_trap(char **argv)
11152 {
11153         int sig;
11154         char *new_cmd;
11155
11156         if (!G_traps)
11157                 G_traps = xzalloc(sizeof(G_traps[0]) * NSIG);
11158
11159         argv++;
11160         if (!*argv) {
11161                 int i;
11162                 /* No args: print all trapped */
11163                 for (i = 0; i < NSIG; ++i) {
11164                         if (G_traps[i]) {
11165                                 printf("trap -- ");
11166                                 print_escaped(G_traps[i]);
11167                                 /* note: bash adds "SIG", but only if invoked
11168                                  * as "bash". If called as "sh", or if set -o posix,
11169                                  * then it prints short signal names.
11170                                  * We are printing short names: */
11171                                 printf(" %s\n", get_signame(i));
11172                         }
11173                 }
11174                 /*fflush_all(); - done after each builtin anyway */
11175                 return EXIT_SUCCESS;
11176         }
11177
11178         new_cmd = NULL;
11179         /* If first arg is a number: reset all specified signals */
11180         sig = bb_strtou(*argv, NULL, 10);
11181         if (errno == 0) {
11182                 int ret;
11183  process_sig_list:
11184                 ret = EXIT_SUCCESS;
11185                 while (*argv) {
11186                         sighandler_t handler;
11187
11188                         sig = get_signum(*argv++);
11189                         if (sig < 0) {
11190                                 ret = EXIT_FAILURE;
11191                                 /* Mimic bash message exactly */
11192                                 bb_error_msg("trap: %s: invalid signal specification", argv[-1]);
11193                                 continue;
11194                         }
11195
11196                         free(G_traps[sig]);
11197                         G_traps[sig] = xstrdup(new_cmd);
11198
11199                         debug_printf("trap: setting SIG%s (%i) to '%s'\n",
11200                                 get_signame(sig), sig, G_traps[sig]);
11201
11202                         /* There is no signal for 0 (EXIT) */
11203                         if (sig == 0)
11204                                 continue;
11205
11206                         if (new_cmd)
11207                                 handler = (new_cmd[0] ? record_pending_signo : SIG_IGN);
11208                         else
11209                                 /* We are removing trap handler */
11210                                 handler = pick_sighandler(sig);
11211                         install_sighandler(sig, handler);
11212                 }
11213                 return ret;
11214         }
11215
11216         if (!argv[1]) { /* no second arg */
11217                 bb_error_msg("trap: invalid arguments");
11218                 return EXIT_FAILURE;
11219         }
11220
11221         /* First arg is "-": reset all specified to default */
11222         /* First arg is "--": skip it, the rest is "handler SIGs..." */
11223         /* Everything else: set arg as signal handler
11224          * (includes "" case, which ignores signal) */
11225         if (argv[0][0] == '-') {
11226                 if (argv[0][1] == '\0') { /* "-" */
11227                         /* new_cmd remains NULL: "reset these sigs" */
11228                         goto reset_traps;
11229                 }
11230                 if (argv[0][1] == '-' && argv[0][2] == '\0') { /* "--" */
11231                         argv++;
11232                 }
11233                 /* else: "-something", no special meaning */
11234         }
11235         new_cmd = *argv;
11236  reset_traps:
11237         argv++;
11238         goto process_sig_list;
11239 }
11240 #endif
11241
11242 #if ENABLE_HUSH_JOB
11243 static struct pipe *parse_jobspec(const char *str)
11244 {
11245         struct pipe *pi;
11246         unsigned jobnum;
11247
11248         if (sscanf(str, "%%%u", &jobnum) != 1) {
11249                 if (str[0] != '%'
11250                  || (str[1] != '%' && str[1] != '+' && str[1] != '\0')
11251                 ) {
11252                         bb_error_msg("bad argument '%s'", str);
11253                         return NULL;
11254                 }
11255                 /* It is "%%", "%+" or "%" - current job */
11256                 jobnum = G.last_jobid;
11257                 if (jobnum == 0) {
11258                         bb_error_msg("no current job");
11259                         return NULL;
11260                 }
11261         }
11262         for (pi = G.job_list; pi; pi = pi->next) {
11263                 if (pi->jobid == jobnum) {
11264                         return pi;
11265                 }
11266         }
11267         bb_error_msg("%u: no such job", jobnum);
11268         return NULL;
11269 }
11270
11271 static int FAST_FUNC builtin_jobs(char **argv UNUSED_PARAM)
11272 {
11273         struct pipe *job;
11274         const char *status_string;
11275
11276         checkjobs(NULL, 0 /*(no pid to wait for)*/);
11277         for (job = G.job_list; job; job = job->next) {
11278                 if (job->alive_cmds == job->stopped_cmds)
11279                         status_string = "Stopped";
11280                 else
11281                         status_string = "Running";
11282
11283                 printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->cmdtext);
11284         }
11285
11286         clean_up_last_dead_job();
11287
11288         return EXIT_SUCCESS;
11289 }
11290
11291 /* built-in 'fg' and 'bg' handler */
11292 static int FAST_FUNC builtin_fg_bg(char **argv)
11293 {
11294         int i;
11295         struct pipe *pi;
11296
11297         if (!G_interactive_fd)
11298                 return EXIT_FAILURE;
11299
11300         /* If they gave us no args, assume they want the last backgrounded task */
11301         if (!argv[1]) {
11302                 for (pi = G.job_list; pi; pi = pi->next) {
11303                         if (pi->jobid == G.last_jobid) {
11304                                 goto found;
11305                         }
11306                 }
11307                 bb_error_msg("%s: no current job", argv[0]);
11308                 return EXIT_FAILURE;
11309         }
11310
11311         pi = parse_jobspec(argv[1]);
11312         if (!pi)
11313                 return EXIT_FAILURE;
11314  found:
11315         /* TODO: bash prints a string representation
11316          * of job being foregrounded (like "sleep 1 | cat") */
11317         if (argv[0][0] == 'f' && G_saved_tty_pgrp) {
11318                 /* Put the job into the foreground.  */
11319                 tcsetpgrp(G_interactive_fd, pi->pgrp);
11320         }
11321
11322         /* Restart the processes in the job */
11323         debug_printf_jobs("reviving %d procs, pgrp %d\n", pi->num_cmds, pi->pgrp);
11324         for (i = 0; i < pi->num_cmds; i++) {
11325                 debug_printf_jobs("reviving pid %d\n", pi->cmds[i].pid);
11326         }
11327         pi->stopped_cmds = 0;
11328
11329         i = kill(- pi->pgrp, SIGCONT);
11330         if (i < 0) {
11331                 if (errno == ESRCH) {
11332                         delete_finished_job(pi);
11333                         return EXIT_SUCCESS;
11334                 }
11335                 bb_perror_msg("kill (SIGCONT)");
11336         }
11337
11338         if (argv[0][0] == 'f') {
11339                 remove_job_from_table(pi); /* FG job shouldn't be in job table */
11340                 return checkjobs_and_fg_shell(pi);
11341         }
11342         return EXIT_SUCCESS;
11343 }
11344 #endif
11345
11346 #if ENABLE_HUSH_KILL
11347 static int FAST_FUNC builtin_kill(char **argv)
11348 {
11349         int ret = 0;
11350
11351 # if ENABLE_HUSH_JOB
11352         if (argv[1] && strcmp(argv[1], "-l") != 0) {
11353                 int i = 1;
11354
11355                 do {
11356                         struct pipe *pi;
11357                         char *dst;
11358                         int j, n;
11359
11360                         if (argv[i][0] != '%')
11361                                 continue;
11362                         /*
11363                          * "kill %N" - job kill
11364                          * Converting to pgrp / pid kill
11365                          */
11366                         pi = parse_jobspec(argv[i]);
11367                         if (!pi) {
11368                                 /* Eat bad jobspec */
11369                                 j = i;
11370                                 do {
11371                                         j++;
11372                                         argv[j - 1] = argv[j];
11373                                 } while (argv[j]);
11374                                 ret = 1;
11375                                 i--;
11376                                 continue;
11377                         }
11378                         /*
11379                          * In jobs started under job control, we signal
11380                          * entire process group by kill -PGRP_ID.
11381                          * This happens, f.e., in interactive shell.
11382                          *
11383                          * Otherwise, we signal each child via
11384                          * kill PID1 PID2 PID3.
11385                          * Testcases:
11386                          * sh -c 'sleep 1|sleep 1 & kill %1'
11387                          * sh -c 'true|sleep 2 & sleep 1; kill %1'
11388                          * sh -c 'true|sleep 1 & sleep 2; kill %1'
11389                          */
11390                         n = G_interactive_fd ? 1 : pi->num_cmds;
11391                         dst = alloca(n * sizeof(int)*4);
11392                         argv[i] = dst;
11393                         if (G_interactive_fd)
11394                                 dst += sprintf(dst, " -%u", (int)pi->pgrp);
11395                         else for (j = 0; j < n; j++) {
11396                                 struct command *cmd = &pi->cmds[j];
11397                                 /* Skip exited members of the job */
11398                                 if (cmd->pid == 0)
11399                                         continue;
11400                                 /*
11401                                  * kill_main has matching code to expect
11402                                  * leading space. Needed to not confuse
11403                                  * negative pids with "kill -SIGNAL_NO" syntax
11404                                  */
11405                                 dst += sprintf(dst, " %u", (int)cmd->pid);
11406                         }
11407                         *dst = '\0';
11408                 } while (argv[++i]);
11409         }
11410 # endif
11411
11412         if (argv[1] || ret == 0) {
11413                 ret = run_applet_main(argv, kill_main);
11414         }
11415         /* else: ret = 1, "kill %bad_jobspec" case */
11416         return ret;
11417 }
11418 #endif
11419
11420 #if ENABLE_HUSH_WAIT
11421 /* http://www.opengroup.org/onlinepubs/9699919799/utilities/wait.html */
11422 #if !ENABLE_HUSH_JOB
11423 # define wait_for_child_or_signal(pipe,pid) wait_for_child_or_signal(pid)
11424 #endif
11425 static int wait_for_child_or_signal(struct pipe *waitfor_pipe, pid_t waitfor_pid)
11426 {
11427         int ret = 0;
11428         for (;;) {
11429                 int sig;
11430                 sigset_t oldset;
11431
11432                 if (!sigisemptyset(&G.pending_set))
11433                         goto check_sig;
11434
11435                 /* waitpid is not interruptible by SA_RESTARTed
11436                  * signals which we use. Thus, this ugly dance:
11437                  */
11438
11439                 /* Make sure possible SIGCHLD is stored in kernel's
11440                  * pending signal mask before we call waitpid.
11441                  * Or else we may race with SIGCHLD, lose it,
11442                  * and get stuck in sigsuspend...
11443                  */
11444                 sigfillset(&oldset); /* block all signals, remember old set */
11445                 sigprocmask2(SIG_SETMASK, &oldset);
11446
11447                 if (!sigisemptyset(&G.pending_set)) {
11448                         /* Crap! we raced with some signal! */
11449                         goto restore;
11450                 }
11451
11452                 /*errno = 0; - checkjobs does this */
11453 /* Can't pass waitfor_pipe into checkjobs(): it won't be interruptible */
11454                 ret = checkjobs(NULL, waitfor_pid); /* waitpid(WNOHANG) inside */
11455                 debug_printf_exec("checkjobs:%d\n", ret);
11456 #if ENABLE_HUSH_JOB
11457                 if (waitfor_pipe) {
11458                         int rcode = job_exited_or_stopped(waitfor_pipe);
11459                         debug_printf_exec("job_exited_or_stopped:%d\n", rcode);
11460                         if (rcode >= 0) {
11461                                 ret = rcode;
11462                                 sigprocmask(SIG_SETMASK, &oldset, NULL);
11463                                 break;
11464                         }
11465                 }
11466 #endif
11467                 /* if ECHILD, there are no children (ret is -1 or 0) */
11468                 /* if ret == 0, no children changed state */
11469                 /* if ret != 0, it's exitcode+1 of exited waitfor_pid child */
11470                 if (errno == ECHILD || ret) {
11471                         ret--;
11472                         if (ret < 0) /* if ECHILD, may need to fix "ret" */
11473                                 ret = 0;
11474                         sigprocmask(SIG_SETMASK, &oldset, NULL);
11475                         break;
11476                 }
11477                 /* Wait for SIGCHLD or any other signal */
11478                 /* It is vitally important for sigsuspend that SIGCHLD has non-DFL handler! */
11479                 /* Note: sigsuspend invokes signal handler */
11480                 sigsuspend(&oldset);
11481  restore:
11482                 sigprocmask(SIG_SETMASK, &oldset, NULL);
11483  check_sig:
11484                 /* So, did we get a signal? */
11485                 sig = check_and_run_traps();
11486                 if (sig /*&& sig != SIGCHLD - always true */) {
11487                         /* Do this for any (non-ignored) signal, not only for ^C */
11488                         ret = 128 + sig;
11489                         break;
11490                 }
11491                 /* SIGCHLD, or no signal, or ignored one, such as SIGQUIT. Repeat */
11492         }
11493         return ret;
11494 }
11495
11496 static int FAST_FUNC builtin_wait(char **argv)
11497 {
11498         int ret;
11499         int status;
11500
11501         argv = skip_dash_dash(argv);
11502         if (argv[0] == NULL) {
11503                 /* Don't care about wait results */
11504                 /* Note 1: must wait until there are no more children */
11505                 /* Note 2: must be interruptible */
11506                 /* Examples:
11507                  * $ sleep 3 & sleep 6 & wait
11508                  * [1] 30934 sleep 3
11509                  * [2] 30935 sleep 6
11510                  * [1] Done                   sleep 3
11511                  * [2] Done                   sleep 6
11512                  * $ sleep 3 & sleep 6 & wait
11513                  * [1] 30936 sleep 3
11514                  * [2] 30937 sleep 6
11515                  * [1] Done                   sleep 3
11516                  * ^C <-- after ~4 sec from keyboard
11517                  * $
11518                  */
11519                 return wait_for_child_or_signal(NULL, 0 /*(no job and no pid to wait for)*/);
11520         }
11521
11522         do {
11523                 pid_t pid = bb_strtou(*argv, NULL, 10);
11524                 if (errno || pid <= 0) {
11525 #if ENABLE_HUSH_JOB
11526                         if (argv[0][0] == '%') {
11527                                 struct pipe *wait_pipe;
11528                                 ret = 127; /* bash compat for bad jobspecs */
11529                                 wait_pipe = parse_jobspec(*argv);
11530                                 if (wait_pipe) {
11531                                         ret = job_exited_or_stopped(wait_pipe);
11532                                         if (ret < 0) {
11533                                                 ret = wait_for_child_or_signal(wait_pipe, 0);
11534                                         } else {
11535                                                 /* waiting on "last dead job" removes it */
11536                                                 clean_up_last_dead_job();
11537                                         }
11538                                 }
11539                                 /* else: parse_jobspec() already emitted error msg */
11540                                 continue;
11541                         }
11542 #endif
11543                         /* mimic bash message */
11544                         bb_error_msg("wait: '%s': not a pid or valid job spec", *argv);
11545                         ret = EXIT_FAILURE;
11546                         continue; /* bash checks all argv[] */
11547                 }
11548
11549                 /* Do we have such child? */
11550                 ret = waitpid(pid, &status, WNOHANG);
11551                 if (ret < 0) {
11552                         /* No */
11553                         ret = 127;
11554                         if (errno == ECHILD) {
11555                                 if (pid == G.last_bg_pid) {
11556                                         /* "wait $!" but last bg task has already exited. Try:
11557                                          * (sleep 1; exit 3) & sleep 2; echo $?; wait $!; echo $?
11558                                          * In bash it prints exitcode 0, then 3.
11559                                          * In dash, it is 127.
11560                                          */
11561                                         ret = G.last_bg_pid_exitcode;
11562                                 } else {
11563                                         /* Example: "wait 1". mimic bash message */
11564                                         bb_error_msg("wait: pid %d is not a child of this shell", (int)pid);
11565                                 }
11566                         } else {
11567                                 /* ??? */
11568                                 bb_perror_msg("wait %s", *argv);
11569                         }
11570                         continue; /* bash checks all argv[] */
11571                 }
11572                 if (ret == 0) {
11573                         /* Yes, and it still runs */
11574                         ret = wait_for_child_or_signal(NULL, pid);
11575                 } else {
11576                         /* Yes, and it just exited */
11577                         process_wait_result(NULL, pid, status);
11578                         ret = WEXITSTATUS(status);
11579                         if (WIFSIGNALED(status))
11580                                 ret = 128 + WTERMSIG(status);
11581                 }
11582         } while (*++argv);
11583
11584         return ret;
11585 }
11586 #endif
11587
11588 #if ENABLE_HUSH_LOOPS || ENABLE_HUSH_FUNCTIONS
11589 static unsigned parse_numeric_argv1(char **argv, unsigned def, unsigned def_min)
11590 {
11591         if (argv[1]) {
11592                 def = bb_strtou(argv[1], NULL, 10);
11593                 if (errno || def < def_min || argv[2]) {
11594                         bb_error_msg("%s: bad arguments", argv[0]);
11595                         def = UINT_MAX;
11596                 }
11597         }
11598         return def;
11599 }
11600 #endif
11601
11602 #if ENABLE_HUSH_LOOPS
11603 static int FAST_FUNC builtin_break(char **argv)
11604 {
11605         unsigned depth;
11606         if (G.depth_of_loop == 0) {
11607                 bb_error_msg("%s: only meaningful in a loop", argv[0]);
11608                 /* if we came from builtin_continue(), need to undo "= 1" */
11609                 G.flag_break_continue = 0;
11610                 return EXIT_SUCCESS; /* bash compat */
11611         }
11612         G.flag_break_continue++; /* BC_BREAK = 1, or BC_CONTINUE = 2 */
11613
11614         G.depth_break_continue = depth = parse_numeric_argv1(argv, 1, 1);
11615         if (depth == UINT_MAX)
11616                 G.flag_break_continue = BC_BREAK;
11617         if (G.depth_of_loop < depth)
11618                 G.depth_break_continue = G.depth_of_loop;
11619
11620         return EXIT_SUCCESS;
11621 }
11622
11623 static int FAST_FUNC builtin_continue(char **argv)
11624 {
11625         G.flag_break_continue = 1; /* BC_CONTINUE = 2 = 1+1 */
11626         return builtin_break(argv);
11627 }
11628 #endif
11629
11630 #if ENABLE_HUSH_FUNCTIONS
11631 static int FAST_FUNC builtin_return(char **argv)
11632 {
11633         int rc;
11634
11635         if (G_flag_return_in_progress != -1) {
11636                 bb_error_msg("%s: not in a function or sourced script", argv[0]);
11637                 return EXIT_FAILURE; /* bash compat */
11638         }
11639
11640         G_flag_return_in_progress = 1;
11641
11642         /* bash:
11643          * out of range: wraps around at 256, does not error out
11644          * non-numeric param:
11645          * f() { false; return qwe; }; f; echo $?
11646          * bash: return: qwe: numeric argument required  <== we do this
11647          * 255  <== we also do this
11648          */
11649         rc = parse_numeric_argv1(argv, G.last_exitcode, 0);
11650         return rc;
11651 }
11652 #endif
11653
11654 #if ENABLE_HUSH_TIMES
11655 static int FAST_FUNC builtin_times(char **argv UNUSED_PARAM)
11656 {
11657         static const uint8_t times_tbl[] ALIGN1 = {
11658                 ' ',  offsetof(struct tms, tms_utime),
11659                 '\n', offsetof(struct tms, tms_stime),
11660                 ' ',  offsetof(struct tms, tms_cutime),
11661                 '\n', offsetof(struct tms, tms_cstime),
11662                 0
11663         };
11664         const uint8_t *p;
11665         unsigned clk_tck;
11666         struct tms buf;
11667
11668         clk_tck = bb_clk_tck();
11669
11670         times(&buf);
11671         p = times_tbl;
11672         do {
11673                 unsigned sec, frac;
11674                 unsigned long t;
11675                 t = *(clock_t *)(((char *) &buf) + p[1]);
11676                 sec = t / clk_tck;
11677                 frac = t % clk_tck;
11678                 printf("%um%u.%03us%c",
11679                         sec / 60, sec % 60,
11680                         (frac * 1000) / clk_tck,
11681                         p[0]);
11682                 p += 2;
11683         } while (*p);
11684
11685         return EXIT_SUCCESS;
11686 }
11687 #endif
11688
11689 #if ENABLE_HUSH_MEMLEAK
11690 static int FAST_FUNC builtin_memleak(char **argv UNUSED_PARAM)
11691 {
11692         void *p;
11693         unsigned long l;
11694
11695 # ifdef M_TRIM_THRESHOLD
11696         /* Optional. Reduces probability of false positives */
11697         malloc_trim(0);
11698 # endif
11699         /* Crude attempt to find where "free memory" starts,
11700          * sans fragmentation. */
11701         p = malloc(240);
11702         l = (unsigned long)p;
11703         free(p);
11704         p = malloc(3400);
11705         if (l < (unsigned long)p) l = (unsigned long)p;
11706         free(p);
11707
11708
11709 # if 0  /* debug */
11710         {
11711                 struct mallinfo mi = mallinfo();
11712                 printf("top alloc:0x%lx malloced:%d+%d=%d\n", l,
11713                         mi.arena, mi.hblkhd, mi.arena + mi.hblkhd);
11714         }
11715 # endif
11716
11717         if (!G.memleak_value)
11718                 G.memleak_value = l;
11719
11720         l -= G.memleak_value;
11721         if ((long)l < 0)
11722                 l = 0;
11723         l /= 1024;
11724         if (l > 127)
11725                 l = 127;
11726
11727         /* Exitcode is "how many kilobytes we leaked since 1st call" */
11728         return l;
11729 }
11730 #endif