hush: handle LINENO the same way as RANDOM: variable is "ephemeral"
[oweals/busybox.git] / shell / hush.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * A prototype Bourne shell grammar parser.
4  * Intended to follow the original Thompson and Ritchie
5  * "small and simple is beautiful" philosophy, which
6  * incidentally is a good match to today's BusyBox.
7  *
8  * Copyright (C) 2000,2001  Larry Doolittle <larry@doolittle.boa.org>
9  * Copyright (C) 2008,2009  Denys Vlasenko <vda.linux@googlemail.com>
10  *
11  * Licensed under GPLv2 or later, see file LICENSE in this source tree.
12  *
13  * Credits:
14  *      The parser routines proper are all original material, first
15  *      written Dec 2000 and Jan 2001 by Larry Doolittle.  The
16  *      execution engine, the builtins, and much of the underlying
17  *      support has been adapted from busybox-0.49pre's lash, which is
18  *      Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
19  *      written by Erik Andersen <andersen@codepoet.org>.  That, in turn,
20  *      is based in part on ladsh.c, by Michael K. Johnson and Erik W.
21  *      Troan, which they placed in the public domain.  I don't know
22  *      how much of the Johnson/Troan code has survived the repeated
23  *      rewrites.
24  *
25  * Other credits:
26  *      o_addchr derived from similar w_addchar function in glibc-2.2.
27  *      parse_redirect, redirect_opt_num, and big chunks of main
28  *      and many builtins derived from contributions by Erik Andersen.
29  *      Miscellaneous bugfixes from Matt Kraai.
30  *
31  * There are two big (and related) architecture differences between
32  * this parser and the lash parser.  One is that this version is
33  * actually designed from the ground up to understand nearly all
34  * of the Bourne grammar.  The second, consequential change is that
35  * the parser and input reader have been turned inside out.  Now,
36  * the parser is in control, and asks for input as needed.  The old
37  * way had the input reader in control, and it asked for parsing to
38  * take place as needed.  The new way makes it much easier to properly
39  * handle the recursion implicit in the various substitutions, especially
40  * across continuation lines.
41  *
42  * TODOs:
43  *      grep for "TODO" and fix (some of them are easy)
44  *      make complex ${var%...} constructs support optional
45  *      make here documents optional
46  *      special variables (done: PWD, PPID, RANDOM)
47  *      follow IFS rules more precisely, including update semantics
48  *      tilde expansion
49  *      aliases
50  *      "command" missing features:
51  *          command -p CMD: run CMD using default $PATH
52  *              (can use this to override standalone shell as well?)
53  *          command BLTIN: disables special-ness (e.g. errors do not abort)
54  *          command -V CMD1 CMD2 CMD3 (multiple args) (not in standard)
55  *      builtins mandated by standards we don't support:
56  *          [un]alias, fc:
57  *          fc -l[nr] [BEG] [END]: list range of commands in history
58  *          fc [-e EDITOR] [BEG] [END]: edit/rerun range of commands
59  *          fc -s [PAT=REP] [CMD]: rerun CMD, replacing PAT with REP
60  *
61  * Bash compat TODO:
62  *      redirection of stdout+stderr: &> and >&
63  *      reserved words: function select
64  *      advanced test: [[ ]]
65  *      process substitution: <(list) and >(list)
66  *      =~: regex operator
67  *      let EXPR [EXPR...]
68  *          Each EXPR is an arithmetic expression (ARITHMETIC EVALUATION)
69  *          If the last arg evaluates to 0, let returns 1; 0 otherwise.
70  *          NB: let `echo 'a=a + 1'` - error (IOW: multi-word expansion is used)
71  *      ((EXPR))
72  *          The EXPR is evaluated according to ARITHMETIC EVALUATION.
73  *          This is exactly equivalent to let "EXPR".
74  *      $[EXPR]: synonym for $((EXPR))
75  *      indirect expansion: ${!VAR}
76  *      substring op on @: ${@:n:m}
77  *
78  * Won't do:
79  *      Some builtins mandated by standards:
80  *          newgrp [GRP]: not a builtin in bash but a suid binary
81  *              which spawns a new shell with new group ID
82  *
83  * Status of [[ support:
84  * [[ args ]] are CMD_SINGLEWORD_NOGLOB:
85  *   v='a b'; [[ $v = 'a b' ]]; echo 0:$?
86  *   [[ /bin/n* ]]; echo 0:$?
87  * TODO:
88  * &&/|| are AND/OR ops, -a/-o are not
89  * quoting needs to be considered (-f is an operator, "-f" and ""-f are not; etc)
90  * = is glob match operator, not equality operator: STR = GLOB
91  * (in GLOB, quoting is significant on char-by-char basis: a*cd"*")
92  * == same as =
93  * add =~ regex match operator: STR =~ REGEX
94  */
95 //config:config HUSH
96 //config:       bool "hush (68 kb)"
97 //config:       default y
98 //config:       help
99 //config:       hush is a small shell. It handles the normal flow control
100 //config:       constructs such as if/then/elif/else/fi, for/in/do/done, while loops,
101 //config:       case/esac. Redirections, here documents, $((arithmetic))
102 //config:       and functions are supported.
103 //config:
104 //config:       It will compile and work on no-mmu systems.
105 //config:
106 //config:       It does not handle select, aliases, tilde expansion,
107 //config:       &>file and >&file redirection of stdout+stderr.
108 //config:
109 //config:config HUSH_BASH_COMPAT
110 //config:       bool "bash-compatible extensions"
111 //config:       default y
112 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
113 //config:
114 //config:config HUSH_BRACE_EXPANSION
115 //config:       bool "Brace expansion"
116 //config:       default y
117 //config:       depends on HUSH_BASH_COMPAT
118 //config:       help
119 //config:       Enable {abc,def} extension.
120 //config:
121 //config:config HUSH_LINENO_VAR
122 //config:       bool "$LINENO variable"
123 //config:       default y
124 //config:       depends on HUSH_BASH_COMPAT
125 //config:
126 //config:config HUSH_BASH_SOURCE_CURDIR
127 //config:       bool "'source' and '.' builtins search current directory after $PATH"
128 //config:       default n   # do not encourage non-standard behavior
129 //config:       depends on HUSH_BASH_COMPAT
130 //config:       help
131 //config:       This is not compliant with standards. Avoid if possible.
132 //config:
133 //config:config HUSH_INTERACTIVE
134 //config:       bool "Interactive mode"
135 //config:       default y
136 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
137 //config:       help
138 //config:       Enable interactive mode (prompt and command editing).
139 //config:       Without this, hush simply reads and executes commands
140 //config:       from stdin just like a shell script from a file.
141 //config:       No prompt, no PS1/PS2 magic shell variables.
142 //config:
143 //config:config HUSH_SAVEHISTORY
144 //config:       bool "Save command history to .hush_history"
145 //config:       default y
146 //config:       depends on HUSH_INTERACTIVE && FEATURE_EDITING_SAVEHISTORY
147 //config:
148 //config:config HUSH_JOB
149 //config:       bool "Job control"
150 //config:       default y
151 //config:       depends on HUSH_INTERACTIVE
152 //config:       help
153 //config:       Enable job control: Ctrl-Z backgrounds, Ctrl-C interrupts current
154 //config:       command (not entire shell), fg/bg builtins work. Without this option,
155 //config:       "cmd &" still works by simply spawning a process and immediately
156 //config:       prompting for next command (or executing next command in a script),
157 //config:       but no separate process group is formed.
158 //config:
159 //config:config HUSH_TICK
160 //config:       bool "Support command substitution"
161 //config:       default y
162 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
163 //config:       help
164 //config:       Enable `command` and $(command).
165 //config:
166 //config:config HUSH_IF
167 //config:       bool "Support if/then/elif/else/fi"
168 //config:       default y
169 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
170 //config:
171 //config:config HUSH_LOOPS
172 //config:       bool "Support for, while and until loops"
173 //config:       default y
174 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
175 //config:
176 //config:config HUSH_CASE
177 //config:       bool "Support case ... esac statement"
178 //config:       default y
179 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
180 //config:       help
181 //config:       Enable case ... esac statement. +400 bytes.
182 //config:
183 //config:config HUSH_FUNCTIONS
184 //config:       bool "Support funcname() { commands; } syntax"
185 //config:       default y
186 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
187 //config:       help
188 //config:       Enable support for shell functions. +800 bytes.
189 //config:
190 //config:config HUSH_LOCAL
191 //config:       bool "local builtin"
192 //config:       default y
193 //config:       depends on HUSH_FUNCTIONS
194 //config:       help
195 //config:       Enable support for local variables in functions.
196 //config:
197 //config:config HUSH_RANDOM_SUPPORT
198 //config:       bool "Pseudorandom generator and $RANDOM variable"
199 //config:       default y
200 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
201 //config:       help
202 //config:       Enable pseudorandom generator and dynamic variable "$RANDOM".
203 //config:       Each read of "$RANDOM" will generate a new pseudorandom value.
204 //config:
205 //config:config HUSH_MODE_X
206 //config:       bool "Support 'hush -x' option and 'set -x' command"
207 //config:       default y
208 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
209 //config:       help
210 //config:       This instructs hush to print commands before execution.
211 //config:       Adds ~300 bytes.
212 //config:
213 //config:config HUSH_ECHO
214 //config:       bool "echo builtin"
215 //config:       default y
216 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
217 //config:
218 //config:config HUSH_PRINTF
219 //config:       bool "printf builtin"
220 //config:       default y
221 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
222 //config:
223 //config:config HUSH_TEST
224 //config:       bool "test builtin"
225 //config:       default y
226 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
227 //config:
228 //config:config HUSH_HELP
229 //config:       bool "help builtin"
230 //config:       default y
231 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
232 //config:
233 //config:config HUSH_EXPORT
234 //config:       bool "export builtin"
235 //config:       default y
236 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
237 //config:
238 //config:config HUSH_EXPORT_N
239 //config:       bool "Support 'export -n' option"
240 //config:       default y
241 //config:       depends on HUSH_EXPORT
242 //config:       help
243 //config:       export -n unexports variables. It is a bash extension.
244 //config:
245 //config:config HUSH_READONLY
246 //config:       bool "readonly builtin"
247 //config:       default y
248 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
249 //config:       help
250 //config:       Enable support for read-only variables.
251 //config:
252 //config:config HUSH_KILL
253 //config:       bool "kill builtin (supports kill %jobspec)"
254 //config:       default y
255 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
256 //config:
257 //config:config HUSH_WAIT
258 //config:       bool "wait builtin"
259 //config:       default y
260 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
261 //config:
262 //config:config HUSH_COMMAND
263 //config:       bool "command builtin"
264 //config:       default y
265 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
266 //config:
267 //config:config HUSH_TRAP
268 //config:       bool "trap builtin"
269 //config:       default y
270 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
271 //config:
272 //config:config HUSH_TYPE
273 //config:       bool "type builtin"
274 //config:       default y
275 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
276 //config:
277 //config:config HUSH_TIMES
278 //config:       bool "times builtin"
279 //config:       default y
280 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
281 //config:
282 //config:config HUSH_READ
283 //config:       bool "read builtin"
284 //config:       default y
285 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
286 //config:
287 //config:config HUSH_SET
288 //config:       bool "set builtin"
289 //config:       default y
290 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
291 //config:
292 //config:config HUSH_UNSET
293 //config:       bool "unset builtin"
294 //config:       default y
295 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
296 //config:
297 //config:config HUSH_ULIMIT
298 //config:       bool "ulimit builtin"
299 //config:       default y
300 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
301 //config:
302 //config:config HUSH_UMASK
303 //config:       bool "umask builtin"
304 //config:       default y
305 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
306 //config:
307 //config:config HUSH_GETOPTS
308 //config:       bool "getopts builtin"
309 //config:       default y
310 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
311 //config:
312 //config:config HUSH_MEMLEAK
313 //config:       bool "memleak builtin (debugging)"
314 //config:       default n
315 //config:       depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
316
317 //applet:IF_HUSH(APPLET(hush, BB_DIR_BIN, BB_SUID_DROP))
318 //                       APPLET_ODDNAME:name  main  location    suid_type     help
319 //applet:IF_SH_IS_HUSH(  APPLET_ODDNAME(sh,   hush, BB_DIR_BIN, BB_SUID_DROP, hush))
320 //applet:IF_BASH_IS_HUSH(APPLET_ODDNAME(bash, hush, BB_DIR_BIN, BB_SUID_DROP, hush))
321
322 //kbuild:lib-$(CONFIG_HUSH) += hush.o match.o shell_common.o
323 //kbuild:lib-$(CONFIG_SH_IS_HUSH) += hush.o match.o shell_common.o
324 //kbuild:lib-$(CONFIG_BASH_IS_HUSH) += hush.o match.o shell_common.o
325 //kbuild:lib-$(CONFIG_HUSH_RANDOM_SUPPORT) += random.o
326
327 /* -i (interactive) is also accepted,
328  * but does nothing, therefore not shown in help.
329  * NOMMU-specific options are not meant to be used by users,
330  * therefore we don't show them either.
331  */
332 //usage:#define hush_trivial_usage
333 //usage:        "[-enxl] [-c 'SCRIPT' [ARG0 [ARGS]] / FILE [ARGS] / -s [ARGS]]"
334 //usage:#define hush_full_usage "\n\n"
335 //usage:        "Unix shell interpreter"
336
337 #if !(defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) \
338         || defined(__APPLE__) \
339     )
340 # include <malloc.h>   /* for malloc_trim */
341 #endif
342 #include <glob.h>
343 /* #include <dmalloc.h> */
344 #if ENABLE_HUSH_CASE
345 # include <fnmatch.h>
346 #endif
347 #include <sys/times.h>
348 #include <sys/utsname.h> /* for setting $HOSTNAME */
349
350 #include "busybox.h"  /* for APPLET_IS_NOFORK/NOEXEC */
351 #include "unicode.h"
352 #include "shell_common.h"
353 #include "math.h"
354 #include "match.h"
355 #if ENABLE_HUSH_RANDOM_SUPPORT
356 # include "random.h"
357 #else
358 # define CLEAR_RANDOM_T(rnd) ((void)0)
359 #endif
360 #ifndef O_CLOEXEC
361 # define O_CLOEXEC 0
362 #endif
363 #ifndef F_DUPFD_CLOEXEC
364 # define F_DUPFD_CLOEXEC F_DUPFD
365 #endif
366
367 #if ENABLE_FEATURE_SH_EMBEDDED_SCRIPTS && !(ENABLE_ASH || ENABLE_SH_IS_ASH || ENABLE_BASH_IS_ASH)
368 # include "embedded_scripts.h"
369 #else
370 # define NUM_SCRIPTS 0
371 #endif
372
373 /* So far, all bash compat is controlled by one config option */
374 /* Separate defines document which part of code implements what */
375 #define BASH_PATTERN_SUBST ENABLE_HUSH_BASH_COMPAT
376 #define BASH_SUBSTR        ENABLE_HUSH_BASH_COMPAT
377 #define BASH_SOURCE        ENABLE_HUSH_BASH_COMPAT
378 #define BASH_HOSTNAME_VAR  ENABLE_HUSH_BASH_COMPAT
379 #define BASH_EPOCH_VARS    ENABLE_HUSH_BASH_COMPAT
380 #define BASH_TEST2         (ENABLE_HUSH_BASH_COMPAT && ENABLE_HUSH_TEST)
381 #define BASH_READ_D        ENABLE_HUSH_BASH_COMPAT
382
383
384 /* Build knobs */
385 #define LEAK_HUNTING 0
386 #define BUILD_AS_NOMMU 0
387 /* Enable/disable sanity checks. Ok to enable in production,
388  * only adds a bit of bloat. Set to >1 to get non-production level verbosity.
389  * Keeping 1 for now even in released versions.
390  */
391 #define HUSH_DEBUG 1
392 /* Slightly bigger (+200 bytes), but faster hush.
393  * So far it only enables a trick with counting SIGCHLDs and forks,
394  * which allows us to do fewer waitpid's.
395  * (we can detect a case where neither forks were done nor SIGCHLDs happened
396  * and therefore waitpid will return the same result as last time)
397  */
398 #define ENABLE_HUSH_FAST 0
399 /* TODO: implement simplified code for users which do not need ${var%...} ops
400  * So far ${var%...} ops are always enabled:
401  */
402 #define ENABLE_HUSH_DOLLAR_OPS 1
403
404
405 #if BUILD_AS_NOMMU
406 # undef BB_MMU
407 # undef USE_FOR_NOMMU
408 # undef USE_FOR_MMU
409 # define BB_MMU 0
410 # define USE_FOR_NOMMU(...) __VA_ARGS__
411 # define USE_FOR_MMU(...)
412 #endif
413
414 #include "NUM_APPLETS.h"
415 #if NUM_APPLETS == 1
416 /* STANDALONE does not make sense, and won't compile */
417 # undef CONFIG_FEATURE_SH_STANDALONE
418 # undef ENABLE_FEATURE_SH_STANDALONE
419 # undef IF_FEATURE_SH_STANDALONE
420 # undef IF_NOT_FEATURE_SH_STANDALONE
421 # define ENABLE_FEATURE_SH_STANDALONE 0
422 # define IF_FEATURE_SH_STANDALONE(...)
423 # define IF_NOT_FEATURE_SH_STANDALONE(...) __VA_ARGS__
424 #endif
425
426 #if !ENABLE_HUSH_INTERACTIVE
427 # undef ENABLE_FEATURE_EDITING
428 # define ENABLE_FEATURE_EDITING 0
429 # undef ENABLE_FEATURE_EDITING_FANCY_PROMPT
430 # define ENABLE_FEATURE_EDITING_FANCY_PROMPT 0
431 # undef ENABLE_FEATURE_EDITING_SAVE_ON_EXIT
432 # define ENABLE_FEATURE_EDITING_SAVE_ON_EXIT 0
433 #endif
434
435 /* Do we support ANY keywords? */
436 #if ENABLE_HUSH_IF || ENABLE_HUSH_LOOPS || ENABLE_HUSH_CASE
437 # define HAS_KEYWORDS 1
438 # define IF_HAS_KEYWORDS(...) __VA_ARGS__
439 # define IF_HAS_NO_KEYWORDS(...)
440 #else
441 # define HAS_KEYWORDS 0
442 # define IF_HAS_KEYWORDS(...)
443 # define IF_HAS_NO_KEYWORDS(...) __VA_ARGS__
444 #endif
445
446 /* If you comment out one of these below, it will be #defined later
447  * to perform debug printfs to stderr: */
448 #define debug_printf(...)         do {} while (0)
449 /* Finer-grained debug switches */
450 #define debug_printf_parse(...)   do {} while (0)
451 #define debug_printf_heredoc(...) do {} while (0)
452 #define debug_print_tree(a, b)    do {} while (0)
453 #define debug_printf_exec(...)    do {} while (0)
454 #define debug_printf_env(...)     do {} while (0)
455 #define debug_printf_jobs(...)    do {} while (0)
456 #define debug_printf_expand(...)  do {} while (0)
457 #define debug_printf_varexp(...)  do {} while (0)
458 #define debug_printf_glob(...)    do {} while (0)
459 #define debug_printf_redir(...)   do {} while (0)
460 #define debug_printf_list(...)    do {} while (0)
461 #define debug_printf_subst(...)   do {} while (0)
462 #define debug_printf_prompt(...)  do {} while (0)
463 #define debug_printf_clean(...)   do {} while (0)
464
465 #define ERR_PTR ((void*)(long)1)
466
467 #define JOB_STATUS_FORMAT    "[%u] %-22s %.40s\n"
468
469 #define _SPECIAL_VARS_STR     "_*@$!?#"
470 #define SPECIAL_VARS_STR     ("_*@$!?#" + 1)
471 #define NUMERIC_SPECVARS_STR ("_*@$!?#" + 3)
472 #if BASH_PATTERN_SUBST
473 /* Support / and // replace ops */
474 /* Note that // is stored as \ in "encoded" string representation */
475 # define VAR_ENCODED_SUBST_OPS      "\\/%#:-=+?"
476 # define VAR_SUBST_OPS             ("\\/%#:-=+?" + 1)
477 # define MINUS_PLUS_EQUAL_QUESTION ("\\/%#:-=+?" + 5)
478 #else
479 # define VAR_ENCODED_SUBST_OPS      "%#:-=+?"
480 # define VAR_SUBST_OPS              "%#:-=+?"
481 # define MINUS_PLUS_EQUAL_QUESTION ("%#:-=+?" + 3)
482 #endif
483
484 #define SPECIAL_VAR_SYMBOL_STR "\3"
485 #define SPECIAL_VAR_SYMBOL       3
486 /* The "variable" with name "\1" emits string "\3". Testcase: "echo ^C" */
487 #define SPECIAL_VAR_QUOTED_SVS   1
488
489 struct variable;
490
491 static const char hush_version_str[] ALIGN1 = "HUSH_VERSION="BB_VER;
492
493 /* This supports saving pointers malloced in vfork child,
494  * to be freed in the parent.
495  */
496 #if !BB_MMU
497 typedef struct nommu_save_t {
498         struct variable *old_vars;
499         char **argv;
500         char **argv_from_re_execing;
501 } nommu_save_t;
502 #endif
503
504 enum {
505         RES_NONE  = 0,
506 #if ENABLE_HUSH_IF
507         RES_IF    ,
508         RES_THEN  ,
509         RES_ELIF  ,
510         RES_ELSE  ,
511         RES_FI    ,
512 #endif
513 #if ENABLE_HUSH_LOOPS
514         RES_FOR   ,
515         RES_WHILE ,
516         RES_UNTIL ,
517         RES_DO    ,
518         RES_DONE  ,
519 #endif
520 #if ENABLE_HUSH_LOOPS || ENABLE_HUSH_CASE
521         RES_IN    ,
522 #endif
523 #if ENABLE_HUSH_CASE
524         RES_CASE  ,
525         /* three pseudo-keywords support contrived "case" syntax: */
526         RES_CASE_IN,   /* "case ... IN", turns into RES_MATCH when IN is observed */
527         RES_MATCH ,    /* "word)" */
528         RES_CASE_BODY, /* "this command is inside CASE" */
529         RES_ESAC  ,
530 #endif
531         RES_XXXX  ,
532         RES_SNTX
533 };
534
535 typedef struct o_string {
536         char *data;
537         int length; /* position where data is appended */
538         int maxlen;
539         int o_expflags;
540         /* At least some part of the string was inside '' or "",
541          * possibly empty one: word"", wo''rd etc. */
542         smallint has_quoted_part;
543         smallint has_empty_slot;
544         smallint ended_in_ifs;
545 } o_string;
546 enum {
547         EXP_FLAG_SINGLEWORD     = 0x80, /* must be 0x80 */
548         EXP_FLAG_GLOB           = 0x2,
549         /* Protect newly added chars against globbing
550          * by prepending \ to *, ?, [, \ */
551         EXP_FLAG_ESC_GLOB_CHARS = 0x1,
552 };
553 /* Used for initialization: o_string foo = NULL_O_STRING; */
554 #define NULL_O_STRING { NULL }
555
556 #ifndef debug_printf_parse
557 static const char *const assignment_flag[] = {
558         "MAYBE_ASSIGNMENT",
559         "DEFINITELY_ASSIGNMENT",
560         "NOT_ASSIGNMENT",
561         "WORD_IS_KEYWORD",
562 };
563 #endif
564
565 /* We almost can use standard FILE api, but we need an ability to move
566  * its fd when redirects coincide with it. No api exists for that
567  * (RFE for it at https://sourceware.org/bugzilla/show_bug.cgi?id=21902).
568  * HFILE is our internal alternative. Only supports reading.
569  * Since we now can, we incorporate linked list of all opened HFILEs
570  * into the struct (used to be a separate mini-list).
571  */
572 typedef struct HFILE {
573         char *cur;
574         char *end;
575         struct HFILE *next_hfile;
576         int is_stdin;
577         int fd;
578         char buf[1024];
579 } HFILE;
580
581 typedef struct in_str {
582         const char *p;
583         int peek_buf[2];
584         int last_char;
585         HFILE *file;
586 } in_str;
587
588 /* The descrip member of this structure is only used to make
589  * debugging output pretty */
590 static const struct {
591         int mode;
592         signed char default_fd;
593         char descrip[3];
594 } redir_table[] = {
595         { O_RDONLY,                  0, "<"  },
596         { O_CREAT|O_TRUNC|O_WRONLY,  1, ">"  },
597         { O_CREAT|O_APPEND|O_WRONLY, 1, ">>" },
598         { O_CREAT|O_RDWR,            1, "<>" },
599         { O_RDONLY,                  0, "<<" },
600 /* Should not be needed. Bogus default_fd helps in debugging */
601 /*      { O_RDONLY,                 77, "<<" }, */
602 };
603
604 struct redir_struct {
605         struct redir_struct *next;
606         char *rd_filename;          /* filename */
607         int rd_fd;                  /* fd to redirect */
608         /* fd to redirect to, or -3 if rd_fd is to be closed (n>&-) */
609         int rd_dup;
610         smallint rd_type;           /* (enum redir_type) */
611         /* note: for heredocs, rd_filename contains heredoc delimiter,
612          * and subsequently heredoc itself; and rd_dup is a bitmask:
613          * bit 0: do we need to trim leading tabs?
614          * bit 1: is heredoc quoted (<<'delim' syntax) ?
615          */
616 };
617 typedef enum redir_type {
618         REDIRECT_INPUT     = 0,
619         REDIRECT_OVERWRITE = 1,
620         REDIRECT_APPEND    = 2,
621         REDIRECT_IO        = 3,
622         REDIRECT_HEREDOC   = 4,
623         REDIRECT_HEREDOC2  = 5, /* REDIRECT_HEREDOC after heredoc is loaded */
624
625         REDIRFD_CLOSE      = -3,
626         REDIRFD_SYNTAX_ERR = -2,
627         REDIRFD_TO_FILE    = -1,
628         /* otherwise, rd_fd is redirected to rd_dup */
629
630         HEREDOC_SKIPTABS = 1,
631         HEREDOC_QUOTED   = 2,
632 } redir_type;
633
634
635 struct command {
636         pid_t pid;                  /* 0 if exited */
637         unsigned assignment_cnt;    /* how many argv[i] are assignments? */
638 #if ENABLE_HUSH_LINENO_VAR
639         unsigned lineno;
640 #endif
641         smallint cmd_type;          /* CMD_xxx */
642 #define CMD_NORMAL   0
643 #define CMD_SUBSHELL 1
644 #if BASH_TEST2 || ENABLE_HUSH_LOCAL || ENABLE_HUSH_EXPORT || ENABLE_HUSH_READONLY
645 /* used for "[[ EXPR ]]", and to prevent word splitting and globbing in
646  * "export v=t*"
647  */
648 # define CMD_SINGLEWORD_NOGLOB 2
649 #endif
650 #if ENABLE_HUSH_FUNCTIONS
651 # define CMD_FUNCDEF 3
652 #endif
653
654         smalluint cmd_exitcode;
655         /* if non-NULL, this "command" is { list }, ( list ), or a compound statement */
656         struct pipe *group;
657 #if !BB_MMU
658         char *group_as_string;
659 #endif
660 #if ENABLE_HUSH_FUNCTIONS
661         struct function *child_func;
662 /* This field is used to prevent a bug here:
663  * while...do f1() {a;}; f1; f1() {b;}; f1; done
664  * When we execute "f1() {a;}" cmd, we create new function and clear
665  * cmd->group, cmd->group_as_string, cmd->argv[0].
666  * When we execute "f1() {b;}", we notice that f1 exists,
667  * and that its "parent cmd" struct is still "alive",
668  * we put those fields back into cmd->xxx
669  * (struct function has ->parent_cmd ptr to facilitate that).
670  * When we loop back, we can execute "f1() {a;}" again and set f1 correctly.
671  * Without this trick, loop would execute a;b;b;b;...
672  * instead of correct sequence a;b;a;b;...
673  * When command is freed, it severs the link
674  * (sets ->child_func->parent_cmd to NULL).
675  */
676 #endif
677         char **argv;                /* command name and arguments */
678 /* argv vector may contain variable references (^Cvar^C, ^C0^C etc)
679  * and on execution these are substituted with their values.
680  * Substitution can make _several_ words out of one argv[n]!
681  * Example: argv[0]=='.^C*^C.' here: echo .$*.
682  * References of the form ^C`cmd arg^C are `cmd arg` substitutions.
683  */
684         struct redir_struct *redirects; /* I/O redirections */
685 };
686 /* Is there anything in this command at all? */
687 #define IS_NULL_CMD(cmd) \
688         (!(cmd)->group && !(cmd)->argv && !(cmd)->redirects)
689
690 struct pipe {
691         struct pipe *next;
692         int num_cmds;               /* total number of commands in pipe */
693         int alive_cmds;             /* number of commands running (not exited) */
694         int stopped_cmds;           /* number of commands alive, but stopped */
695 #if ENABLE_HUSH_JOB
696         unsigned jobid;             /* job number */
697         pid_t pgrp;                 /* process group ID for the job */
698         char *cmdtext;              /* name of job */
699 #endif
700         struct command *cmds;       /* array of commands in pipe */
701         smallint followup;          /* PIPE_BG, PIPE_SEQ, PIPE_OR, PIPE_AND */
702         IF_HAS_KEYWORDS(smallint pi_inverted;) /* "! cmd | cmd" */
703         IF_HAS_KEYWORDS(smallint res_word;) /* needed for if, for, while, until... */
704 };
705 typedef enum pipe_style {
706         PIPE_SEQ = 0,
707         PIPE_AND = 1,
708         PIPE_OR  = 2,
709         PIPE_BG  = 3,
710 } pipe_style;
711 /* Is there anything in this pipe at all? */
712 #define IS_NULL_PIPE(pi) \
713         ((pi)->num_cmds == 0 IF_HAS_KEYWORDS( && (pi)->res_word == RES_NONE))
714
715 /* This holds pointers to the various results of parsing */
716 struct parse_context {
717         /* linked list of pipes */
718         struct pipe *list_head;
719         /* last pipe (being constructed right now) */
720         struct pipe *pipe;
721         /* last command in pipe (being constructed right now) */
722         struct command *command;
723         /* last redirect in command->redirects list */
724         struct redir_struct *pending_redirect;
725         o_string word;
726 #if !BB_MMU
727         o_string as_string;
728 #endif
729         smallint is_assignment; /* 0:maybe, 1:yes, 2:no, 3:keyword */
730 #if HAS_KEYWORDS
731         smallint ctx_res_w;
732         smallint ctx_inverted; /* "! cmd | cmd" */
733 #if ENABLE_HUSH_CASE
734         smallint ctx_dsemicolon; /* ";;" seen */
735 #endif
736         /* bitmask of FLAG_xxx, for figuring out valid reserved words */
737         int old_flag;
738         /* group we are enclosed in:
739          * example: "if pipe1; pipe2; then pipe3; fi"
740          * when we see "if" or "then", we malloc and copy current context,
741          * and make ->stack point to it. then we parse pipeN.
742          * when closing "then" / fi" / whatever is found,
743          * we move list_head into ->stack->command->group,
744          * copy ->stack into current context, and delete ->stack.
745          * (parsing of { list } and ( list ) doesn't use this method)
746          */
747         struct parse_context *stack;
748 #endif
749 };
750 enum {
751         MAYBE_ASSIGNMENT      = 0,
752         DEFINITELY_ASSIGNMENT = 1,
753         NOT_ASSIGNMENT        = 2,
754         /* Not an assignment, but next word may be: "if v=xyz cmd;" */
755         WORD_IS_KEYWORD       = 3,
756 };
757
758 /* On program start, environ points to initial environment.
759  * putenv adds new pointers into it, unsetenv removes them.
760  * Neither of these (de)allocates the strings.
761  * setenv allocates new strings in malloc space and does putenv,
762  * and thus setenv is unusable (leaky) for shell's purposes */
763 #define setenv(...) setenv_is_leaky_dont_use()
764 struct variable {
765         struct variable *next;
766         char *varstr;        /* points to "name=" portion */
767         int max_len;         /* if > 0, name is part of initial env; else name is malloced */
768         uint16_t var_nest_level;
769         smallint flg_export; /* putenv should be done on this var */
770         smallint flg_read_only;
771 };
772
773 enum {
774         BC_BREAK = 1,
775         BC_CONTINUE = 2,
776 };
777
778 #if ENABLE_HUSH_FUNCTIONS
779 struct function {
780         struct function *next;
781         char *name;
782         struct command *parent_cmd;
783         struct pipe *body;
784 # if !BB_MMU
785         char *body_as_string;
786 # endif
787 };
788 #endif
789
790
791 /* set -/+o OPT support. (TODO: make it optional)
792  * bash supports the following opts:
793  * allexport       off
794  * braceexpand     on
795  * emacs           on
796  * errexit         off
797  * errtrace        off
798  * functrace       off
799  * hashall         on
800  * histexpand      off
801  * history         on
802  * ignoreeof       off
803  * interactive-comments    on
804  * keyword         off
805  * monitor         on
806  * noclobber       off
807  * noexec          off
808  * noglob          off
809  * nolog           off
810  * notify          off
811  * nounset         off
812  * onecmd          off
813  * physical        off
814  * pipefail        off
815  * posix           off
816  * privileged      off
817  * verbose         off
818  * vi              off
819  * xtrace          off
820  */
821 static const char o_opt_strings[] ALIGN1 =
822         "pipefail\0"
823         "noexec\0"
824         "errexit\0"
825 #if ENABLE_HUSH_MODE_X
826         "xtrace\0"
827 #endif
828         ;
829 enum {
830         OPT_O_PIPEFAIL,
831         OPT_O_NOEXEC,
832         OPT_O_ERREXIT,
833 #if ENABLE_HUSH_MODE_X
834         OPT_O_XTRACE,
835 #endif
836         NUM_OPT_O
837 };
838
839 /* "Globals" within this file */
840 /* Sorted roughly by size (smaller offsets == smaller code) */
841 struct globals {
842         /* interactive_fd != 0 means we are an interactive shell.
843          * If we are, then saved_tty_pgrp can also be != 0, meaning
844          * that controlling tty is available. With saved_tty_pgrp == 0,
845          * job control still works, but terminal signals
846          * (^C, ^Z, ^Y, ^\) won't work at all, and background
847          * process groups can only be created with "cmd &".
848          * With saved_tty_pgrp != 0, hush will use tcsetpgrp()
849          * to give tty to the foreground process group,
850          * and will take it back when the group is stopped (^Z)
851          * or killed (^C).
852          */
853 #if ENABLE_HUSH_INTERACTIVE
854         /* 'interactive_fd' is a fd# open to ctty, if we have one
855          * _AND_ if we decided to act interactively */
856         int interactive_fd;
857         IF_NOT_FEATURE_EDITING_FANCY_PROMPT(char *PS1;)
858 # define G_interactive_fd (G.interactive_fd)
859 #else
860 # define G_interactive_fd 0
861 #endif
862 #if ENABLE_FEATURE_EDITING
863         line_input_t *line_input_state;
864 #endif
865         pid_t root_pid;
866         pid_t root_ppid;
867         pid_t last_bg_pid;
868 #if ENABLE_HUSH_RANDOM_SUPPORT
869         random_t random_gen;
870 #endif
871 #if ENABLE_HUSH_JOB
872         int run_list_level;
873         unsigned last_jobid;
874         pid_t saved_tty_pgrp;
875         struct pipe *job_list;
876 # define G_saved_tty_pgrp (G.saved_tty_pgrp)
877 #else
878 # define G_saved_tty_pgrp 0
879 #endif
880         /* How deeply are we in context where "set -e" is ignored */
881         int errexit_depth;
882         /* "set -e" rules (do we follow them correctly?):
883          * Exit if pipe, list, or compound command exits with a non-zero status.
884          * Shell does not exit if failed command is part of condition in
885          * if/while, part of && or || list except the last command, any command
886          * in a pipe but the last, or if the command's return value is being
887          * inverted with !. If a compound command other than a subshell returns a
888          * non-zero status because a command failed while -e was being ignored, the
889          * shell does not exit. A trap on ERR, if set, is executed before the shell
890          * exits [ERR is a bashism].
891          *
892          * If a compound command or function executes in a context where -e is
893          * ignored, none of the commands executed within are affected by the -e
894          * setting. If a compound command or function sets -e while executing in a
895          * context where -e is ignored, that setting does not have any effect until
896          * the compound command or the command containing the function call completes.
897          */
898
899         char o_opt[NUM_OPT_O];
900 #if ENABLE_HUSH_MODE_X
901 # define G_x_mode (G.o_opt[OPT_O_XTRACE])
902 #else
903 # define G_x_mode 0
904 #endif
905 #if ENABLE_HUSH_INTERACTIVE
906         smallint promptmode; /* 0: PS1, 1: PS2 */
907 #endif
908         smallint flag_SIGINT;
909 #if ENABLE_HUSH_LOOPS
910         smallint flag_break_continue;
911 #endif
912 #if ENABLE_HUSH_FUNCTIONS
913         /* 0: outside of a function (or sourced file)
914          * -1: inside of a function, ok to use return builtin
915          * 1: return is invoked, skip all till end of func
916          */
917         smallint flag_return_in_progress;
918 # define G_flag_return_in_progress (G.flag_return_in_progress)
919 #else
920 # define G_flag_return_in_progress 0
921 #endif
922         smallint exiting; /* used to prevent EXIT trap recursion */
923         /* These support $? */
924         smalluint last_exitcode;
925         smalluint expand_exitcode;
926         smalluint last_bg_pid_exitcode;
927 #if ENABLE_HUSH_SET
928         /* are global_argv and global_argv[1..n] malloced? (note: not [0]) */
929         smalluint global_args_malloced;
930 # define G_global_args_malloced (G.global_args_malloced)
931 #else
932 # define G_global_args_malloced 0
933 #endif
934 #if ENABLE_HUSH_BASH_COMPAT
935         int dead_job_exitcode; /* for "wait -n" */
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 parse_lineno;
971         unsigned execute_lineno;
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 BASH_EPOCH_VARS
1012         char epoch_buf[sizeof("%lu.nnnnnn") + sizeof(long)*3];
1013 #endif
1014 #if ENABLE_FEATURE_EDITING
1015         char user_input_buf[CONFIG_FEATURE_EDITING_MAX_LEN];
1016 #endif
1017 };
1018 #define G (*ptr_to_globals)
1019 /* Not #defining name to G.name - this quickly gets unwieldy
1020  * (too many defines). Also, I actually prefer to see when a variable
1021  * is global, thus "G." prefix is a useful hint */
1022 #define INIT_G() do { \
1023         SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
1024         /* memset(&G.sa, 0, sizeof(G.sa)); */  \
1025         sigfillset(&G.sa.sa_mask); \
1026         G.sa.sa_flags = SA_RESTART; \
1027 } while (0)
1028
1029
1030 /* Function prototypes for builtins */
1031 static int builtin_cd(char **argv) FAST_FUNC;
1032 #if ENABLE_HUSH_ECHO
1033 static int builtin_echo(char **argv) FAST_FUNC;
1034 #endif
1035 static int builtin_eval(char **argv) FAST_FUNC;
1036 static int builtin_exec(char **argv) FAST_FUNC;
1037 static int builtin_exit(char **argv) FAST_FUNC;
1038 #if ENABLE_HUSH_EXPORT
1039 static int builtin_export(char **argv) FAST_FUNC;
1040 #endif
1041 #if ENABLE_HUSH_READONLY
1042 static int builtin_readonly(char **argv) FAST_FUNC;
1043 #endif
1044 #if ENABLE_HUSH_JOB
1045 static int builtin_fg_bg(char **argv) FAST_FUNC;
1046 static int builtin_jobs(char **argv) FAST_FUNC;
1047 #endif
1048 #if ENABLE_HUSH_GETOPTS
1049 static int builtin_getopts(char **argv) FAST_FUNC;
1050 #endif
1051 #if ENABLE_HUSH_HELP
1052 static int builtin_help(char **argv) FAST_FUNC;
1053 #endif
1054 #if MAX_HISTORY && ENABLE_FEATURE_EDITING
1055 static int builtin_history(char **argv) FAST_FUNC;
1056 #endif
1057 #if ENABLE_HUSH_LOCAL
1058 static int builtin_local(char **argv) FAST_FUNC;
1059 #endif
1060 #if ENABLE_HUSH_MEMLEAK
1061 static int builtin_memleak(char **argv) FAST_FUNC;
1062 #endif
1063 #if ENABLE_HUSH_PRINTF
1064 static int builtin_printf(char **argv) FAST_FUNC;
1065 #endif
1066 static int builtin_pwd(char **argv) FAST_FUNC;
1067 #if ENABLE_HUSH_READ
1068 static int builtin_read(char **argv) FAST_FUNC;
1069 #endif
1070 #if ENABLE_HUSH_SET
1071 static int builtin_set(char **argv) FAST_FUNC;
1072 #endif
1073 static int builtin_shift(char **argv) FAST_FUNC;
1074 static int builtin_source(char **argv) FAST_FUNC;
1075 #if ENABLE_HUSH_TEST || BASH_TEST2
1076 static int builtin_test(char **argv) FAST_FUNC;
1077 #endif
1078 #if ENABLE_HUSH_TRAP
1079 static int builtin_trap(char **argv) FAST_FUNC;
1080 #endif
1081 #if ENABLE_HUSH_TYPE
1082 static int builtin_type(char **argv) FAST_FUNC;
1083 #endif
1084 #if ENABLE_HUSH_TIMES
1085 static int builtin_times(char **argv) FAST_FUNC;
1086 #endif
1087 static int builtin_true(char **argv) FAST_FUNC;
1088 #if ENABLE_HUSH_UMASK
1089 static int builtin_umask(char **argv) FAST_FUNC;
1090 #endif
1091 #if ENABLE_HUSH_UNSET
1092 static int builtin_unset(char **argv) FAST_FUNC;
1093 #endif
1094 #if ENABLE_HUSH_KILL
1095 static int builtin_kill(char **argv) FAST_FUNC;
1096 #endif
1097 #if ENABLE_HUSH_WAIT
1098 static int builtin_wait(char **argv) FAST_FUNC;
1099 #endif
1100 #if ENABLE_HUSH_LOOPS
1101 static int builtin_break(char **argv) FAST_FUNC;
1102 static int builtin_continue(char **argv) FAST_FUNC;
1103 #endif
1104 #if ENABLE_HUSH_FUNCTIONS
1105 static int builtin_return(char **argv) FAST_FUNC;
1106 #endif
1107
1108 /* Table of built-in functions.  They can be forked or not, depending on
1109  * context: within pipes, they fork.  As simple commands, they do not.
1110  * When used in non-forking context, they can change global variables
1111  * in the parent shell process.  If forked, of course they cannot.
1112  * For example, 'unset foo | whatever' will parse and run, but foo will
1113  * still be set at the end. */
1114 struct built_in_command {
1115         const char *b_cmd;
1116         int (*b_function)(char **argv) FAST_FUNC;
1117 #if ENABLE_HUSH_HELP
1118         const char *b_descr;
1119 # define BLTIN(cmd, func, help) { cmd, func, help }
1120 #else
1121 # define BLTIN(cmd, func, help) { cmd, func }
1122 #endif
1123 };
1124
1125 static const struct built_in_command bltins1[] = {
1126         BLTIN("."        , builtin_source  , "Run commands in file"),
1127         BLTIN(":"        , builtin_true    , NULL),
1128 #if ENABLE_HUSH_JOB
1129         BLTIN("bg"       , builtin_fg_bg   , "Resume job in background"),
1130 #endif
1131 #if ENABLE_HUSH_LOOPS
1132         BLTIN("break"    , builtin_break   , "Exit loop"),
1133 #endif
1134         BLTIN("cd"       , builtin_cd      , "Change directory"),
1135 #if ENABLE_HUSH_LOOPS
1136         BLTIN("continue" , builtin_continue, "Start new loop iteration"),
1137 #endif
1138         BLTIN("eval"     , builtin_eval    , "Construct and run shell command"),
1139         BLTIN("exec"     , builtin_exec    , "Execute command, don't return to shell"),
1140         BLTIN("exit"     , builtin_exit    , NULL),
1141 #if ENABLE_HUSH_EXPORT
1142         BLTIN("export"   , builtin_export  , "Set environment variables"),
1143 #endif
1144 #if ENABLE_HUSH_JOB
1145         BLTIN("fg"       , builtin_fg_bg   , "Bring job to foreground"),
1146 #endif
1147 #if ENABLE_HUSH_GETOPTS
1148         BLTIN("getopts"  , builtin_getopts , NULL),
1149 #endif
1150 #if ENABLE_HUSH_HELP
1151         BLTIN("help"     , builtin_help    , NULL),
1152 #endif
1153 #if MAX_HISTORY && ENABLE_FEATURE_EDITING
1154         BLTIN("history"  , builtin_history , "Show history"),
1155 #endif
1156 #if ENABLE_HUSH_JOB
1157         BLTIN("jobs"     , builtin_jobs    , "List jobs"),
1158 #endif
1159 #if ENABLE_HUSH_KILL
1160         BLTIN("kill"     , builtin_kill    , "Send signals to processes"),
1161 #endif
1162 #if ENABLE_HUSH_LOCAL
1163         BLTIN("local"    , builtin_local   , "Set local variables"),
1164 #endif
1165 #if ENABLE_HUSH_MEMLEAK
1166         BLTIN("memleak"  , builtin_memleak , NULL),
1167 #endif
1168 #if ENABLE_HUSH_READ
1169         BLTIN("read"     , builtin_read    , "Input into variable"),
1170 #endif
1171 #if ENABLE_HUSH_READONLY
1172         BLTIN("readonly" , builtin_readonly, "Make variables read-only"),
1173 #endif
1174 #if ENABLE_HUSH_FUNCTIONS
1175         BLTIN("return"   , builtin_return  , "Return from function"),
1176 #endif
1177 #if ENABLE_HUSH_SET
1178         BLTIN("set"      , builtin_set     , "Set positional parameters"),
1179 #endif
1180         BLTIN("shift"    , builtin_shift   , "Shift positional parameters"),
1181 #if BASH_SOURCE
1182         BLTIN("source"   , builtin_source  , NULL),
1183 #endif
1184 #if ENABLE_HUSH_TIMES
1185         BLTIN("times"    , builtin_times   , NULL),
1186 #endif
1187 #if ENABLE_HUSH_TRAP
1188         BLTIN("trap"     , builtin_trap    , "Trap signals"),
1189 #endif
1190         BLTIN("true"     , builtin_true    , NULL),
1191 #if ENABLE_HUSH_TYPE
1192         BLTIN("type"     , builtin_type    , "Show command type"),
1193 #endif
1194 #if ENABLE_HUSH_ULIMIT
1195         BLTIN("ulimit"   , shell_builtin_ulimit, "Control resource limits"),
1196 #endif
1197 #if ENABLE_HUSH_UMASK
1198         BLTIN("umask"    , builtin_umask   , "Set file creation mask"),
1199 #endif
1200 #if ENABLE_HUSH_UNSET
1201         BLTIN("unset"    , builtin_unset   , "Unset variables"),
1202 #endif
1203 #if ENABLE_HUSH_WAIT
1204         BLTIN("wait"     , builtin_wait    , "Wait for process to finish"),
1205 #endif
1206 };
1207 /* These builtins won't be used if we are on NOMMU and need to re-exec
1208  * (it's cheaper to run an external program in this case):
1209  */
1210 static const struct built_in_command bltins2[] = {
1211 #if ENABLE_HUSH_TEST
1212         BLTIN("["        , builtin_test    , NULL),
1213 #endif
1214 #if BASH_TEST2
1215         BLTIN("[["       , builtin_test    , NULL),
1216 #endif
1217 #if ENABLE_HUSH_ECHO
1218         BLTIN("echo"     , builtin_echo    , NULL),
1219 #endif
1220 #if ENABLE_HUSH_PRINTF
1221         BLTIN("printf"   , builtin_printf  , NULL),
1222 #endif
1223         BLTIN("pwd"      , builtin_pwd     , NULL),
1224 #if ENABLE_HUSH_TEST
1225         BLTIN("test"     , builtin_test    , NULL),
1226 #endif
1227 };
1228
1229
1230 /* Debug printouts.
1231  */
1232 #if HUSH_DEBUG >= 2
1233 /* prevent disasters with G.debug_indent < 0 */
1234 # define indent() fdprintf(2, "%*s", (G.debug_indent * 2) & 0xff, "")
1235 # define debug_enter() (G.debug_indent++)
1236 # define debug_leave() (G.debug_indent--)
1237 #else
1238 # define indent()      ((void)0)
1239 # define debug_enter() ((void)0)
1240 # define debug_leave() ((void)0)
1241 #endif
1242
1243 #ifndef debug_printf
1244 # define debug_printf(...) (indent(), fdprintf(2, __VA_ARGS__))
1245 #endif
1246
1247 #ifndef debug_printf_parse
1248 # define debug_printf_parse(...) (indent(), fdprintf(2, __VA_ARGS__))
1249 #endif
1250
1251 #ifndef debug_printf_heredoc
1252 # define debug_printf_heredoc(...) (indent(), fdprintf(2, __VA_ARGS__))
1253 #endif
1254
1255 #ifndef debug_printf_exec
1256 #define debug_printf_exec(...) (indent(), fdprintf(2, __VA_ARGS__))
1257 #endif
1258
1259 #ifndef debug_printf_env
1260 # define debug_printf_env(...) (indent(), fdprintf(2, __VA_ARGS__))
1261 #endif
1262
1263 #ifndef debug_printf_jobs
1264 # define debug_printf_jobs(...) (indent(), fdprintf(2, __VA_ARGS__))
1265 # define DEBUG_JOBS 1
1266 #else
1267 # define DEBUG_JOBS 0
1268 #endif
1269
1270 #ifndef debug_printf_expand
1271 # define debug_printf_expand(...) (indent(), fdprintf(2, __VA_ARGS__))
1272 # define DEBUG_EXPAND 1
1273 #else
1274 # define DEBUG_EXPAND 0
1275 #endif
1276
1277 #ifndef debug_printf_varexp
1278 # define debug_printf_varexp(...) (indent(), fdprintf(2, __VA_ARGS__))
1279 #endif
1280
1281 #ifndef debug_printf_glob
1282 # define debug_printf_glob(...) (indent(), fdprintf(2, __VA_ARGS__))
1283 # define DEBUG_GLOB 1
1284 #else
1285 # define DEBUG_GLOB 0
1286 #endif
1287
1288 #ifndef debug_printf_redir
1289 # define debug_printf_redir(...) (indent(), fdprintf(2, __VA_ARGS__))
1290 #endif
1291
1292 #ifndef debug_printf_list
1293 # define debug_printf_list(...) (indent(), fdprintf(2, __VA_ARGS__))
1294 #endif
1295
1296 #ifndef debug_printf_subst
1297 # define debug_printf_subst(...) (indent(), fdprintf(2, __VA_ARGS__))
1298 #endif
1299
1300 #ifndef debug_printf_prompt
1301 # define debug_printf_prompt(...) (indent(), fdprintf(2, __VA_ARGS__))
1302 #endif
1303
1304 #ifndef debug_printf_clean
1305 # define debug_printf_clean(...) (indent(), fdprintf(2, __VA_ARGS__))
1306 # define DEBUG_CLEAN 1
1307 #else
1308 # define DEBUG_CLEAN 0
1309 #endif
1310
1311 #if DEBUG_EXPAND
1312 static void debug_print_strings(const char *prefix, char **vv)
1313 {
1314         indent();
1315         fdprintf(2, "%s:\n", prefix);
1316         while (*vv)
1317                 fdprintf(2, " '%s'\n", *vv++);
1318 }
1319 #else
1320 # define debug_print_strings(prefix, vv) ((void)0)
1321 #endif
1322
1323
1324 /* Leak hunting. Use hush_leaktool.sh for post-processing.
1325  */
1326 #if LEAK_HUNTING
1327 static void *xxmalloc(int lineno, size_t size)
1328 {
1329         void *ptr = xmalloc((size + 0xff) & ~0xff);
1330         fdprintf(2, "line %d: malloc %p\n", lineno, ptr);
1331         return ptr;
1332 }
1333 static void *xxrealloc(int lineno, void *ptr, size_t size)
1334 {
1335         ptr = xrealloc(ptr, (size + 0xff) & ~0xff);
1336         fdprintf(2, "line %d: realloc %p\n", lineno, ptr);
1337         return ptr;
1338 }
1339 static char *xxstrdup(int lineno, const char *str)
1340 {
1341         char *ptr = xstrdup(str);
1342         fdprintf(2, "line %d: strdup %p\n", lineno, ptr);
1343         return ptr;
1344 }
1345 static void xxfree(void *ptr)
1346 {
1347         fdprintf(2, "free %p\n", ptr);
1348         free(ptr);
1349 }
1350 # define xmalloc(s)     xxmalloc(__LINE__, s)
1351 # define xrealloc(p, s) xxrealloc(__LINE__, p, s)
1352 # define xstrdup(s)     xxstrdup(__LINE__, s)
1353 # define free(p)        xxfree(p)
1354 #endif
1355
1356
1357 /* Syntax and runtime errors. They always abort scripts.
1358  * In interactive use they usually discard unparsed and/or unexecuted commands
1359  * and return to the prompt.
1360  * HUSH_DEBUG >= 2 prints line number in this file where it was detected.
1361  */
1362 #if HUSH_DEBUG < 2
1363 # define msg_and_die_if_script(lineno, ...)     msg_and_die_if_script(__VA_ARGS__)
1364 # define syntax_error(lineno, msg)              syntax_error(msg)
1365 # define syntax_error_at(lineno, msg)           syntax_error_at(msg)
1366 # define syntax_error_unterm_ch(lineno, ch)     syntax_error_unterm_ch(ch)
1367 # define syntax_error_unterm_str(lineno, s)     syntax_error_unterm_str(s)
1368 # define syntax_error_unexpected_ch(lineno, ch) syntax_error_unexpected_ch(ch)
1369 #endif
1370
1371 static void die_if_script(void)
1372 {
1373         if (!G_interactive_fd) {
1374                 if (G.last_exitcode) /* sometines it's 2, not 1 (bash compat) */
1375                         xfunc_error_retval = G.last_exitcode;
1376                 xfunc_die();
1377         }
1378 }
1379
1380 static void msg_and_die_if_script(unsigned lineno, const char *fmt, ...)
1381 {
1382         va_list p;
1383
1384 #if HUSH_DEBUG >= 2
1385         bb_error_msg("hush.c:%u", lineno);
1386 #endif
1387         va_start(p, fmt);
1388         bb_verror_msg(fmt, p, NULL);
1389         va_end(p);
1390         die_if_script();
1391 }
1392
1393 static void syntax_error(unsigned lineno UNUSED_PARAM, const char *msg)
1394 {
1395         if (msg)
1396                 bb_error_msg("syntax error: %s", msg);
1397         else
1398                 bb_error_msg("syntax error");
1399         die_if_script();
1400 }
1401
1402 static void syntax_error_at(unsigned lineno UNUSED_PARAM, const char *msg)
1403 {
1404         bb_error_msg("syntax error at '%s'", msg);
1405         die_if_script();
1406 }
1407
1408 static void syntax_error_unterm_str(unsigned lineno UNUSED_PARAM, const char *s)
1409 {
1410         bb_error_msg("syntax error: unterminated %s", s);
1411 //? source4.tests fails: in bash, echo ${^} in script does not terminate the script
1412 //      die_if_script();
1413 }
1414
1415 static void syntax_error_unterm_ch(unsigned lineno, char ch)
1416 {
1417         char msg[2] = { ch, '\0' };
1418         syntax_error_unterm_str(lineno, msg);
1419 }
1420
1421 static void syntax_error_unexpected_ch(unsigned lineno UNUSED_PARAM, int ch)
1422 {
1423         char msg[2];
1424         msg[0] = ch;
1425         msg[1] = '\0';
1426 #if HUSH_DEBUG >= 2
1427         bb_error_msg("hush.c:%u", lineno);
1428 #endif
1429         bb_error_msg("syntax error: unexpected %s", ch == EOF ? "EOF" : msg);
1430         die_if_script();
1431 }
1432
1433 #if HUSH_DEBUG < 2
1434 # undef msg_and_die_if_script
1435 # undef syntax_error
1436 # undef syntax_error_at
1437 # undef syntax_error_unterm_ch
1438 # undef syntax_error_unterm_str
1439 # undef syntax_error_unexpected_ch
1440 #else
1441 # define msg_and_die_if_script(...)     msg_and_die_if_script(__LINE__, __VA_ARGS__)
1442 # define syntax_error(msg)              syntax_error(__LINE__, msg)
1443 # define syntax_error_at(msg)           syntax_error_at(__LINE__, msg)
1444 # define syntax_error_unterm_ch(ch)     syntax_error_unterm_ch(__LINE__, ch)
1445 # define syntax_error_unterm_str(s)     syntax_error_unterm_str(__LINE__, s)
1446 # define syntax_error_unexpected_ch(ch) syntax_error_unexpected_ch(__LINE__, ch)
1447 #endif
1448
1449
1450 /* Utility functions
1451  */
1452 /* Replace each \x with x in place, return ptr past NUL. */
1453 static char *unbackslash(char *src)
1454 {
1455         char *dst = src = strchrnul(src, '\\');
1456         while (1) {
1457                 if (*src == '\\') {
1458                         src++;
1459                         if (*src != '\0') {
1460                                 /* \x -> x */
1461                                 *dst++ = *src++;
1462                                 continue;
1463                         }
1464                         /* else: "\<nul>". Do not delete this backslash.
1465                          * Testcase: eval 'echo ok\'
1466                          */
1467                         *dst++ = '\\';
1468                         /* fallthrough */
1469                 }
1470                 if ((*dst++ = *src++) == '\0')
1471                         break;
1472         }
1473         return dst;
1474 }
1475
1476 static char **add_strings_to_strings(char **strings, char **add, int need_to_dup)
1477 {
1478         int i;
1479         unsigned count1;
1480         unsigned count2;
1481         char **v;
1482
1483         v = strings;
1484         count1 = 0;
1485         if (v) {
1486                 while (*v) {
1487                         count1++;
1488                         v++;
1489                 }
1490         }
1491         count2 = 0;
1492         v = add;
1493         while (*v) {
1494                 count2++;
1495                 v++;
1496         }
1497         v = xrealloc(strings, (count1 + count2 + 1) * sizeof(char*));
1498         v[count1 + count2] = NULL;
1499         i = count2;
1500         while (--i >= 0)
1501                 v[count1 + i] = (need_to_dup ? xstrdup(add[i]) : add[i]);
1502         return v;
1503 }
1504 #if LEAK_HUNTING
1505 static char **xx_add_strings_to_strings(int lineno, char **strings, char **add, int need_to_dup)
1506 {
1507         char **ptr = add_strings_to_strings(strings, add, need_to_dup);
1508         fdprintf(2, "line %d: add_strings_to_strings %p\n", lineno, ptr);
1509         return ptr;
1510 }
1511 #define add_strings_to_strings(strings, add, need_to_dup) \
1512         xx_add_strings_to_strings(__LINE__, strings, add, need_to_dup)
1513 #endif
1514
1515 /* Note: takes ownership of "add" ptr (it is not strdup'ed) */
1516 static char **add_string_to_strings(char **strings, char *add)
1517 {
1518         char *v[2];
1519         v[0] = add;
1520         v[1] = NULL;
1521         return add_strings_to_strings(strings, v, /*dup:*/ 0);
1522 }
1523 #if LEAK_HUNTING
1524 static char **xx_add_string_to_strings(int lineno, char **strings, char *add)
1525 {
1526         char **ptr = add_string_to_strings(strings, add);
1527         fdprintf(2, "line %d: add_string_to_strings %p\n", lineno, ptr);
1528         return ptr;
1529 }
1530 #define add_string_to_strings(strings, add) \
1531         xx_add_string_to_strings(__LINE__, strings, add)
1532 #endif
1533
1534 static void free_strings(char **strings)
1535 {
1536         char **v;
1537
1538         if (!strings)
1539                 return;
1540         v = strings;
1541         while (*v) {
1542                 free(*v);
1543                 v++;
1544         }
1545         free(strings);
1546 }
1547
1548 static int dup_CLOEXEC(int fd, int avoid_fd)
1549 {
1550         int newfd;
1551  repeat:
1552         newfd = fcntl(fd, F_DUPFD_CLOEXEC, avoid_fd + 1);
1553         if (newfd >= 0) {
1554                 if (F_DUPFD_CLOEXEC == F_DUPFD) /* if old libc (w/o F_DUPFD_CLOEXEC) */
1555                         fcntl(newfd, F_SETFD, FD_CLOEXEC);
1556         } else { /* newfd < 0 */
1557                 if (errno == EBUSY)
1558                         goto repeat;
1559                 if (errno == EINTR)
1560                         goto repeat;
1561         }
1562         return newfd;
1563 }
1564
1565 static int xdup_CLOEXEC_and_close(int fd, int avoid_fd)
1566 {
1567         int newfd;
1568  repeat:
1569         newfd = fcntl(fd, F_DUPFD_CLOEXEC, avoid_fd + 1);
1570         if (newfd < 0) {
1571                 if (errno == EBUSY)
1572                         goto repeat;
1573                 if (errno == EINTR)
1574                         goto repeat;
1575                 /* fd was not open? */
1576                 if (errno == EBADF)
1577                         return fd;
1578                 xfunc_die();
1579         }
1580         if (F_DUPFD_CLOEXEC == F_DUPFD) /* if old libc (w/o F_DUPFD_CLOEXEC) */
1581                 fcntl(newfd, F_SETFD, FD_CLOEXEC);
1582         close(fd);
1583         return newfd;
1584 }
1585
1586
1587 /* Manipulating HFILEs */
1588 static HFILE *hfopen(const char *name)
1589 {
1590         HFILE *fp;
1591         int fd;
1592
1593         fd = STDIN_FILENO;
1594         if (name) {
1595                 fd = open(name, O_RDONLY | O_CLOEXEC);
1596                 if (fd < 0)
1597                         return NULL;
1598                 if (O_CLOEXEC == 0) /* ancient libc */
1599                         close_on_exec_on(fd);
1600         }
1601
1602         fp = xmalloc(sizeof(*fp));
1603         fp->is_stdin = (name == NULL);
1604         fp->fd = fd;
1605         fp->cur = fp->end = fp->buf;
1606         fp->next_hfile = G.HFILE_list;
1607         G.HFILE_list = fp;
1608         return fp;
1609 }
1610 static void hfclose(HFILE *fp)
1611 {
1612         HFILE **pp = &G.HFILE_list;
1613         while (*pp) {
1614                 HFILE *cur = *pp;
1615                 if (cur == fp) {
1616                         *pp = cur->next_hfile;
1617                         break;
1618                 }
1619                 pp = &cur->next_hfile;
1620         }
1621         if (fp->fd >= 0)
1622                 close(fp->fd);
1623         free(fp);
1624 }
1625 static int refill_HFILE_and_getc(HFILE *fp)
1626 {
1627         int n;
1628
1629         if (fp->fd < 0) {
1630                 /* Already saw EOF */
1631                 return EOF;
1632         }
1633         /* Try to buffer more input */
1634         fp->cur = fp->buf;
1635         n = safe_read(fp->fd, fp->buf, sizeof(fp->buf));
1636         if (n < 0) {
1637                 bb_perror_msg("read error");
1638                 n = 0;
1639         }
1640         fp->end = fp->buf + n;
1641         if (n == 0) {
1642                 /* EOF/error */
1643                 close(fp->fd);
1644                 fp->fd = -1;
1645                 return EOF;
1646         }
1647         return (unsigned char)(*fp->cur++);
1648 }
1649 /* Inlined for common case of non-empty buffer.
1650  */
1651 static ALWAYS_INLINE int hfgetc(HFILE *fp)
1652 {
1653         if (fp->cur < fp->end)
1654                 return (unsigned char)(*fp->cur++);
1655         /* Buffer empty */
1656         return refill_HFILE_and_getc(fp);
1657 }
1658 static int move_HFILEs_on_redirect(int fd, int avoid_fd)
1659 {
1660         HFILE *fl = G.HFILE_list;
1661         while (fl) {
1662                 if (fd == fl->fd) {
1663                         /* We use it only on script files, they are all CLOEXEC */
1664                         fl->fd = xdup_CLOEXEC_and_close(fd, avoid_fd);
1665                         debug_printf_redir("redirect_fd %d: matches a script fd, moving it to %d\n", fd, fl->fd);
1666                         return 1; /* "found and moved" */
1667                 }
1668                 fl = fl->next_hfile;
1669         }
1670 #if ENABLE_HUSH_MODE_X
1671         if (G.x_mode_fd > 0 && fd == G.x_mode_fd) {
1672                 G.x_mode_fd = xdup_CLOEXEC_and_close(fd, avoid_fd);
1673                 return 1; /* "found and moved" */
1674         }
1675 #endif
1676         return 0; /* "not in the list" */
1677 }
1678 #if ENABLE_FEATURE_SH_STANDALONE && BB_MMU
1679 static void close_all_HFILE_list(void)
1680 {
1681         HFILE *fl = G.HFILE_list;
1682         while (fl) {
1683                 /* hfclose would also free HFILE object.
1684                  * It is disastrous if we share memory with a vforked parent.
1685                  * I'm not sure we never come here after vfork.
1686                  * Therefore just close fd, nothing more.
1687                  *
1688                  * ">" instead of ">=": we don't close fd#0,
1689                  * interactive shell uses hfopen(NULL) as stdin input
1690                  * which has fl->fd == 0, but fd#0 gets redirected in pipes.
1691                  * If we'd close it here, then e.g. interactive "set | sort"
1692                  * with NOFORKed sort, would have sort's input fd closed.
1693                  */
1694                 if (fl->fd > 0)
1695                         /*hfclose(fl); - unsafe */
1696                         close(fl->fd);
1697                 fl = fl->next_hfile;
1698         }
1699 }
1700 #endif
1701 static int fd_in_HFILEs(int fd)
1702 {
1703         HFILE *fl = G.HFILE_list;
1704         while (fl) {
1705                 if (fl->fd == fd)
1706                         return 1;
1707                 fl = fl->next_hfile;
1708         }
1709         return 0;
1710 }
1711
1712
1713 /* Helpers for setting new $n and restoring them back
1714  */
1715 typedef struct save_arg_t {
1716         char *sv_argv0;
1717         char **sv_g_argv;
1718         int sv_g_argc;
1719         IF_HUSH_SET(smallint sv_g_malloced;)
1720 } save_arg_t;
1721
1722 static void save_and_replace_G_args(save_arg_t *sv, char **argv)
1723 {
1724         sv->sv_argv0 = argv[0];
1725         sv->sv_g_argv = G.global_argv;
1726         sv->sv_g_argc = G.global_argc;
1727         IF_HUSH_SET(sv->sv_g_malloced = G.global_args_malloced;)
1728
1729         argv[0] = G.global_argv[0]; /* retain $0 */
1730         G.global_argv = argv;
1731         IF_HUSH_SET(G.global_args_malloced = 0;)
1732
1733         G.global_argc = 1 + string_array_len(argv + 1);
1734 }
1735
1736 static void restore_G_args(save_arg_t *sv, char **argv)
1737 {
1738 #if ENABLE_HUSH_SET
1739         if (G.global_args_malloced) {
1740                 /* someone ran "set -- arg1 arg2 ...", undo */
1741                 char **pp = G.global_argv;
1742                 while (*++pp) /* note: does not free $0 */
1743                         free(*pp);
1744                 free(G.global_argv);
1745         }
1746 #endif
1747         argv[0] = sv->sv_argv0;
1748         G.global_argv = sv->sv_g_argv;
1749         G.global_argc = sv->sv_g_argc;
1750         IF_HUSH_SET(G.global_args_malloced = sv->sv_g_malloced;)
1751 }
1752
1753
1754 /* Basic theory of signal handling in shell
1755  * ========================================
1756  * This does not describe what hush does, rather, it is current understanding
1757  * what it _should_ do. If it doesn't, it's a bug.
1758  * http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#trap
1759  *
1760  * Signals are handled only after each pipe ("cmd | cmd | cmd" thing)
1761  * is finished or backgrounded. It is the same in interactive and
1762  * non-interactive shells, and is the same regardless of whether
1763  * a user trap handler is installed or a shell special one is in effect.
1764  * ^C or ^Z from keyboard seems to execute "at once" because it usually
1765  * backgrounds (i.e. stops) or kills all members of currently running
1766  * pipe.
1767  *
1768  * Wait builtin is interruptible by signals for which user trap is set
1769  * or by SIGINT in interactive shell.
1770  *
1771  * Trap handlers will execute even within trap handlers. (right?)
1772  *
1773  * User trap handlers are forgotten when subshell ("(cmd)") is entered,
1774  * except for handlers set to '' (empty string).
1775  *
1776  * If job control is off, backgrounded commands ("cmd &")
1777  * have SIGINT, SIGQUIT set to SIG_IGN.
1778  *
1779  * Commands which are run in command substitution ("`cmd`")
1780  * have SIGTTIN, SIGTTOU, SIGTSTP set to SIG_IGN.
1781  *
1782  * Ordinary commands have signals set to SIG_IGN/DFL as inherited
1783  * by the shell from its parent.
1784  *
1785  * Signals which differ from SIG_DFL action
1786  * (note: child (i.e., [v]forked) shell is not an interactive shell):
1787  *
1788  * SIGQUIT: ignore
1789  * SIGTERM (interactive): ignore
1790  * SIGHUP (interactive):
1791  *    send SIGCONT to stopped jobs, send SIGHUP to all jobs and exit
1792  * SIGTTIN, SIGTTOU, SIGTSTP (if job control is on): ignore
1793  *    Note that ^Z is handled not by trapping SIGTSTP, but by seeing
1794  *    that all pipe members are stopped. Try this in bash:
1795  *    while :; do :; done - ^Z does not background it
1796  *    (while :; do :; done) - ^Z backgrounds it
1797  * SIGINT (interactive): wait for last pipe, ignore the rest
1798  *    of the command line, show prompt. NB: ^C does not send SIGINT
1799  *    to interactive shell while shell is waiting for a pipe,
1800  *    since shell is bg'ed (is not in foreground process group).
1801  *    Example 1: this waits 5 sec, but does not execute ls:
1802  *    "echo $$; sleep 5; ls -l" + "kill -INT <pid>"
1803  *    Example 2: this does not wait and does not execute ls:
1804  *    "echo $$; sleep 5 & wait; ls -l" + "kill -INT <pid>"
1805  *    Example 3: this does not wait 5 sec, but executes ls:
1806  *    "sleep 5; ls -l" + press ^C
1807  *    Example 4: this does not wait and does not execute ls:
1808  *    "sleep 5 & wait; ls -l" + press ^C
1809  *
1810  * (What happens to signals which are IGN on shell start?)
1811  * (What happens with signal mask on shell start?)
1812  *
1813  * Old implementation
1814  * ==================
1815  * We use in-kernel pending signal mask to determine which signals were sent.
1816  * We block all signals which we don't want to take action immediately,
1817  * i.e. we block all signals which need to have special handling as described
1818  * above, and all signals which have traps set.
1819  * After each pipe execution, we extract any pending signals via sigtimedwait()
1820  * and act on them.
1821  *
1822  * unsigned special_sig_mask: a mask of such "special" signals
1823  * sigset_t blocked_set:  current blocked signal set
1824  *
1825  * "trap - SIGxxx":
1826  *    clear bit in blocked_set unless it is also in special_sig_mask
1827  * "trap 'cmd' SIGxxx":
1828  *    set bit in blocked_set (even if 'cmd' is '')
1829  * after [v]fork, if we plan to be a shell:
1830  *    unblock signals with special interactive handling
1831  *    (child shell is not interactive),
1832  *    unset all traps except '' (note: regardless of child shell's type - {}, (), etc)
1833  * after [v]fork, if we plan to exec:
1834  *    POSIX says fork clears pending signal mask in child - no need to clear it.
1835  *    Restore blocked signal set to one inherited by shell just prior to exec.
1836  *
1837  * Note: as a result, we do not use signal handlers much. The only uses
1838  * are to count SIGCHLDs
1839  * and to restore tty pgrp on signal-induced exit.
1840  *
1841  * Note 2 (compat):
1842  * Standard says "When a subshell is entered, traps that are not being ignored
1843  * are set to the default actions". bash interprets it so that traps which
1844  * are set to '' (ignore) are NOT reset to defaults. We do the same.
1845  *
1846  * Problem: the above approach makes it unwieldy to catch signals while
1847  * we are in read builtin, or while we read commands from stdin:
1848  * masked signals are not visible!
1849  *
1850  * New implementation
1851  * ==================
1852  * We record each signal we are interested in by installing signal handler
1853  * for them - a bit like emulating kernel pending signal mask in userspace.
1854  * We are interested in: signals which need to have special handling
1855  * as described above, and all signals which have traps set.
1856  * Signals are recorded in pending_set.
1857  * After each pipe execution, we extract any pending signals
1858  * and act on them.
1859  *
1860  * unsigned special_sig_mask: a mask of shell-special signals.
1861  * unsigned fatal_sig_mask: a mask of signals on which we restore tty pgrp.
1862  * char *traps[sig] if trap for sig is set (even if it's '').
1863  * sigset_t pending_set: set of sigs we received.
1864  *
1865  * "trap - SIGxxx":
1866  *    if sig is in special_sig_mask, set handler back to:
1867  *        record_pending_signo, or to IGN if it's a tty stop signal
1868  *    if sig is in fatal_sig_mask, set handler back to sigexit.
1869  *    else: set handler back to SIG_DFL
1870  * "trap 'cmd' SIGxxx":
1871  *    set handler to record_pending_signo.
1872  * "trap '' SIGxxx":
1873  *    set handler to SIG_IGN.
1874  * after [v]fork, if we plan to be a shell:
1875  *    set signals with special interactive handling to SIG_DFL
1876  *    (because child shell is not interactive),
1877  *    unset all traps except '' (note: regardless of child shell's type - {}, (), etc)
1878  * after [v]fork, if we plan to exec:
1879  *    POSIX says fork clears pending signal mask in child - no need to clear it.
1880  *
1881  * To make wait builtin interruptible, we handle SIGCHLD as special signal,
1882  * otherwise (if we leave it SIG_DFL) sigsuspend in wait builtin will not wake up on it.
1883  *
1884  * Note (compat):
1885  * Standard says "When a subshell is entered, traps that are not being ignored
1886  * are set to the default actions". bash interprets it so that traps which
1887  * are set to '' (ignore) are NOT reset to defaults. We do the same.
1888  */
1889 enum {
1890         SPECIAL_INTERACTIVE_SIGS = 0
1891                 | (1 << SIGTERM)
1892                 | (1 << SIGINT)
1893                 | (1 << SIGHUP)
1894                 ,
1895         SPECIAL_JOBSTOP_SIGS = 0
1896 #if ENABLE_HUSH_JOB
1897                 | (1 << SIGTTIN)
1898                 | (1 << SIGTTOU)
1899                 | (1 << SIGTSTP)
1900 #endif
1901                 ,
1902 };
1903
1904 static void record_pending_signo(int sig)
1905 {
1906         sigaddset(&G.pending_set, sig);
1907 #if ENABLE_HUSH_FAST
1908         if (sig == SIGCHLD) {
1909                 G.count_SIGCHLD++;
1910 //bb_error_msg("[%d] SIGCHLD_handler: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
1911         }
1912 #endif
1913 }
1914
1915 static sighandler_t install_sighandler(int sig, sighandler_t handler)
1916 {
1917         struct sigaction old_sa;
1918
1919         /* We could use signal() to install handlers... almost:
1920          * except that we need to mask ALL signals while handlers run.
1921          * I saw signal nesting in strace, race window isn't small.
1922          * SA_RESTART is also needed, but in Linux, signal()
1923          * sets SA_RESTART too.
1924          */
1925         /* memset(&G.sa, 0, sizeof(G.sa)); - already done */
1926         /* sigfillset(&G.sa.sa_mask);      - already done */
1927         /* G.sa.sa_flags = SA_RESTART;     - already done */
1928         G.sa.sa_handler = handler;
1929         sigaction(sig, &G.sa, &old_sa);
1930         return old_sa.sa_handler;
1931 }
1932
1933 static void hush_exit(int exitcode) NORETURN;
1934
1935 static void restore_ttypgrp_and__exit(void) NORETURN;
1936 static void restore_ttypgrp_and__exit(void)
1937 {
1938         /* xfunc has failed! die die die */
1939         /* no EXIT traps, this is an escape hatch! */
1940         G.exiting = 1;
1941         hush_exit(xfunc_error_retval);
1942 }
1943
1944 #if ENABLE_HUSH_JOB
1945
1946 /* Needed only on some libc:
1947  * It was observed that on exit(), fgetc'ed buffered data
1948  * gets "unwound" via lseek(fd, -NUM, SEEK_CUR).
1949  * With the net effect that even after fork(), not vfork(),
1950  * exit() in NOEXECed applet in "sh SCRIPT":
1951  *      noexec_applet_here
1952  *      echo END_OF_SCRIPT
1953  * lseeks fd in input FILE object from EOF to "e" in "echo END_OF_SCRIPT".
1954  * This makes "echo END_OF_SCRIPT" executed twice.
1955  * Similar problems can be seen with msg_and_die_if_script() -> xfunc_die()
1956  * and in `cmd` handling.
1957  * If set as die_func(), this makes xfunc_die() exit via _exit(), not exit():
1958  */
1959 static void fflush_and__exit(void) NORETURN;
1960 static void fflush_and__exit(void)
1961 {
1962         fflush_all();
1963         _exit(xfunc_error_retval);
1964 }
1965
1966 /* After [v]fork, in child: do not restore tty pgrp on xfunc death */
1967 # define disable_restore_tty_pgrp_on_exit() (die_func = fflush_and__exit)
1968 /* After [v]fork, in parent: restore tty pgrp on xfunc death */
1969 # define enable_restore_tty_pgrp_on_exit()  (die_func = restore_ttypgrp_and__exit)
1970
1971 /* Restores tty foreground process group, and exits.
1972  * May be called as signal handler for fatal signal
1973  * (will resend signal to itself, producing correct exit state)
1974  * or called directly with -EXITCODE.
1975  * We also call it if xfunc is exiting.
1976  */
1977 static void sigexit(int sig) NORETURN;
1978 static void sigexit(int sig)
1979 {
1980         /* Careful: we can end up here after [v]fork. Do not restore
1981          * tty pgrp then, only top-level shell process does that */
1982         if (G_saved_tty_pgrp && getpid() == G.root_pid) {
1983                 /* Disable all signals: job control, SIGPIPE, etc.
1984                  * Mostly paranoid measure, to prevent infinite SIGTTOU.
1985                  */
1986                 sigprocmask_allsigs(SIG_BLOCK);
1987                 tcsetpgrp(G_interactive_fd, G_saved_tty_pgrp);
1988         }
1989
1990         /* Not a signal, just exit */
1991         if (sig <= 0)
1992                 _exit(- sig);
1993
1994         kill_myself_with_sig(sig); /* does not return */
1995 }
1996 #else
1997
1998 # define disable_restore_tty_pgrp_on_exit() ((void)0)
1999 # define enable_restore_tty_pgrp_on_exit()  ((void)0)
2000
2001 #endif
2002
2003 static sighandler_t pick_sighandler(unsigned sig)
2004 {
2005         sighandler_t handler = SIG_DFL;
2006         if (sig < sizeof(unsigned)*8) {
2007                 unsigned sigmask = (1 << sig);
2008
2009 #if ENABLE_HUSH_JOB
2010                 /* is sig fatal? */
2011                 if (G_fatal_sig_mask & sigmask)
2012                         handler = sigexit;
2013                 else
2014 #endif
2015                 /* sig has special handling? */
2016                 if (G.special_sig_mask & sigmask) {
2017                         handler = record_pending_signo;
2018                         /* TTIN/TTOU/TSTP can't be set to record_pending_signo
2019                          * in order to ignore them: they will be raised
2020                          * in an endless loop when we try to do some
2021                          * terminal ioctls! We do have to _ignore_ these.
2022                          */
2023                         if (SPECIAL_JOBSTOP_SIGS & sigmask)
2024                                 handler = SIG_IGN;
2025                 }
2026         }
2027         return handler;
2028 }
2029
2030 /* Restores tty foreground process group, and exits. */
2031 static void hush_exit(int exitcode)
2032 {
2033 #if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT
2034         save_history(G.line_input_state);
2035 #endif
2036
2037         fflush_all();
2038         if (G.exiting <= 0 && G_traps && G_traps[0] && G_traps[0][0]) {
2039                 char *argv[3];
2040                 /* argv[0] is unused */
2041                 argv[1] = xstrdup(G_traps[0]); /* copy, since EXIT trap handler may modify G_traps[0] */
2042                 argv[2] = NULL;
2043                 G.exiting = 1; /* prevent EXIT trap recursion */
2044                 /* Note: G_traps[0] is not cleared!
2045                  * "trap" will still show it, if executed
2046                  * in the handler */
2047                 builtin_eval(argv);
2048         }
2049
2050 #if ENABLE_FEATURE_CLEAN_UP
2051         {
2052                 struct variable *cur_var;
2053                 if (G.cwd != bb_msg_unknown)
2054                         free((char*)G.cwd);
2055                 cur_var = G.top_var;
2056                 while (cur_var) {
2057                         struct variable *tmp = cur_var;
2058                         if (!cur_var->max_len)
2059                                 free(cur_var->varstr);
2060                         cur_var = cur_var->next;
2061                         free(tmp);
2062                 }
2063         }
2064 #endif
2065
2066         fflush_all();
2067 #if ENABLE_HUSH_JOB
2068         sigexit(- (exitcode & 0xff));
2069 #else
2070         _exit(exitcode);
2071 #endif
2072 }
2073
2074
2075 //TODO: return a mask of ALL handled sigs?
2076 static int check_and_run_traps(void)
2077 {
2078         int last_sig = 0;
2079
2080         while (1) {
2081                 int sig;
2082
2083                 if (sigisemptyset(&G.pending_set))
2084                         break;
2085                 sig = 0;
2086                 do {
2087                         sig++;
2088                         if (sigismember(&G.pending_set, sig)) {
2089                                 sigdelset(&G.pending_set, sig);
2090                                 goto got_sig;
2091                         }
2092                 } while (sig < NSIG);
2093                 break;
2094  got_sig:
2095                 if (G_traps && G_traps[sig]) {
2096                         debug_printf_exec("%s: sig:%d handler:'%s'\n", __func__, sig, G.traps[sig]);
2097                         if (G_traps[sig][0]) {
2098                                 /* We have user-defined handler */
2099                                 smalluint save_rcode;
2100                                 char *argv[3];
2101                                 /* argv[0] is unused */
2102                                 argv[1] = xstrdup(G_traps[sig]);
2103                                 /* why strdup? trap can modify itself: trap 'trap "echo oops" INT' INT */
2104                                 argv[2] = NULL;
2105                                 save_rcode = G.last_exitcode;
2106                                 builtin_eval(argv);
2107                                 free(argv[1]);
2108 //FIXME: shouldn't it be set to 128 + sig instead?
2109                                 G.last_exitcode = save_rcode;
2110                                 last_sig = sig;
2111                         } /* else: "" trap, ignoring signal */
2112                         continue;
2113                 }
2114                 /* not a trap: special action */
2115                 switch (sig) {
2116                 case SIGINT:
2117                         debug_printf_exec("%s: sig:%d default SIGINT handler\n", __func__, sig);
2118                         G.flag_SIGINT = 1;
2119                         last_sig = sig;
2120                         break;
2121 #if ENABLE_HUSH_JOB
2122                 case SIGHUP: {
2123 //TODO: why are we doing this? ash and dash don't do this,
2124 //they have no handler for SIGHUP at all,
2125 //they rely on kernel to send SIGHUP+SIGCONT to orphaned process groups
2126                         struct pipe *job;
2127                         debug_printf_exec("%s: sig:%d default SIGHUP handler\n", __func__, sig);
2128                         /* bash is observed to signal whole process groups,
2129                          * not individual processes */
2130                         for (job = G.job_list; job; job = job->next) {
2131                                 if (job->pgrp <= 0)
2132                                         continue;
2133                                 debug_printf_exec("HUPing pgrp %d\n", job->pgrp);
2134                                 if (kill(- job->pgrp, SIGHUP) == 0)
2135                                         kill(- job->pgrp, SIGCONT);
2136                         }
2137                         sigexit(SIGHUP);
2138                 }
2139 #endif
2140 #if ENABLE_HUSH_FAST
2141                 case SIGCHLD:
2142                         debug_printf_exec("%s: sig:%d default SIGCHLD handler\n", __func__, sig);
2143                         G.count_SIGCHLD++;
2144 //bb_error_msg("[%d] check_and_run_traps: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
2145                         /* Note:
2146                          * We don't do 'last_sig = sig' here -> NOT returning this sig.
2147                          * This simplifies wait builtin a bit.
2148                          */
2149                         break;
2150 #endif
2151                 default: /* ignored: */
2152                         debug_printf_exec("%s: sig:%d default handling is to ignore\n", __func__, sig);
2153                         /* SIGTERM, SIGQUIT, SIGTTIN, SIGTTOU, SIGTSTP */
2154                         /* Note:
2155                          * We don't do 'last_sig = sig' here -> NOT returning this sig.
2156                          * Example: wait is not interrupted by TERM
2157                          * in interactive shell, because TERM is ignored.
2158                          */
2159                         break;
2160                 }
2161         }
2162         return last_sig;
2163 }
2164
2165
2166 static const char *get_cwd(int force)
2167 {
2168         if (force || G.cwd == NULL) {
2169                 /* xrealloc_getcwd_or_warn(arg) calls free(arg),
2170                  * we must not try to free(bb_msg_unknown) */
2171                 if (G.cwd == bb_msg_unknown)
2172                         G.cwd = NULL;
2173                 G.cwd = xrealloc_getcwd_or_warn((char *)G.cwd);
2174                 if (!G.cwd)
2175                         G.cwd = bb_msg_unknown;
2176         }
2177         return G.cwd;
2178 }
2179
2180
2181 /*
2182  * Shell and environment variable support
2183  */
2184 static struct variable **get_ptr_to_local_var(const char *name, unsigned len)
2185 {
2186         struct variable **pp;
2187         struct variable *cur;
2188
2189         pp = &G.top_var;
2190         while ((cur = *pp) != NULL) {
2191                 if (strncmp(cur->varstr, name, len) == 0 && cur->varstr[len] == '=')
2192                         return pp;
2193                 pp = &cur->next;
2194         }
2195         return NULL;
2196 }
2197
2198 static const char* FAST_FUNC get_local_var_value(const char *name)
2199 {
2200         struct variable **vpp;
2201         unsigned len = strlen(name);
2202
2203         if (G.expanded_assignments) {
2204                 char **cpp = G.expanded_assignments;
2205                 while (*cpp) {
2206                         char *cp = *cpp;
2207                         if (strncmp(cp, name, len) == 0 && cp[len] == '=')
2208                                 return cp + len + 1;
2209                         cpp++;
2210                 }
2211         }
2212
2213         vpp = get_ptr_to_local_var(name, len);
2214         if (vpp)
2215                 return (*vpp)->varstr + len + 1;
2216
2217         if (strcmp(name, "PPID") == 0)
2218                 return utoa(G.root_ppid);
2219         // bash compat: UID? EUID?
2220 #if ENABLE_HUSH_RANDOM_SUPPORT
2221         if (strcmp(name, "RANDOM") == 0)
2222                 return utoa(next_random(&G.random_gen));
2223 #endif
2224 #if ENABLE_HUSH_LINENO_VAR
2225         if (strcmp(name, "LINENO") == 0)
2226                 return utoa(G.execute_lineno);
2227 #endif
2228 #if BASH_EPOCH_VARS
2229         {
2230                 const char *fmt = NULL;
2231                 if (strcmp(name, "EPOCHSECONDS") == 0)
2232                         fmt = "%lu";
2233                 else if (strcmp(name, "EPOCHREALTIME") == 0)
2234                         fmt = "%lu.%06u";
2235                 if (fmt) {
2236                         struct timeval tv;
2237                         gettimeofday(&tv, NULL);
2238                         sprintf(G.epoch_buf, fmt, (unsigned long)tv.tv_sec,
2239                                         (unsigned)tv.tv_usec);
2240                         return G.epoch_buf;
2241                 }
2242         }
2243 #endif
2244         return NULL;
2245 }
2246
2247 #if ENABLE_HUSH_GETOPTS
2248 static void handle_changed_special_names(const char *name, unsigned name_len)
2249 {
2250         if (name_len == 6) {
2251                 if (strncmp(name, "OPTIND", 6) == 0) {
2252                         G.getopt_count = 0;
2253                         return;
2254                 }
2255         }
2256 }
2257 #else
2258 /* Do not even bother evaluating arguments */
2259 # define handle_changed_special_names(...) ((void)0)
2260 #endif
2261
2262 /* str holds "NAME=VAL" and is expected to be malloced.
2263  * We take ownership of it.
2264  */
2265 #define SETFLAG_EXPORT   (1 << 0)
2266 #define SETFLAG_UNEXPORT (1 << 1)
2267 #define SETFLAG_MAKE_RO  (1 << 2)
2268 #define SETFLAG_VARLVL_SHIFT   3
2269 static int set_local_var(char *str, unsigned flags)
2270 {
2271         struct variable **cur_pp;
2272         struct variable *cur;
2273         char *free_me = NULL;
2274         char *eq_sign;
2275         int name_len;
2276         int retval;
2277         unsigned local_lvl = (flags >> SETFLAG_VARLVL_SHIFT);
2278
2279         eq_sign = strchr(str, '=');
2280         if (HUSH_DEBUG && !eq_sign)
2281                 bb_error_msg_and_die("BUG in setvar");
2282
2283         name_len = eq_sign - str + 1; /* including '=' */
2284         cur_pp = &G.top_var;
2285         while ((cur = *cur_pp) != NULL) {
2286                 if (strncmp(cur->varstr, str, name_len) != 0) {
2287                         cur_pp = &cur->next;
2288                         continue;
2289                 }
2290
2291                 /* We found an existing var with this name */
2292                 if (cur->flg_read_only) {
2293                         bb_error_msg("%s: readonly variable", str);
2294                         free(str);
2295 //NOTE: in bash, assignment in "export READONLY_VAR=Z" fails, and sets $?=1,
2296 //but export per se succeeds (does put the var in env). We don't mimic that.
2297                         return -1;
2298                 }
2299                 if (flags & SETFLAG_UNEXPORT) { // && cur->flg_export ?
2300                         debug_printf_env("%s: unsetenv '%s'\n", __func__, str);
2301                         *eq_sign = '\0';
2302                         unsetenv(str);
2303                         *eq_sign = '=';
2304                 }
2305                 if (cur->var_nest_level < local_lvl) {
2306                         /* bash 3.2.33(1) and exported vars:
2307                          * # export z=z
2308                          * # f() { local z=a; env | grep ^z; }
2309                          * # f
2310                          * z=a
2311                          * # env | grep ^z
2312                          * z=z
2313                          */
2314                         if (cur->flg_export)
2315                                 flags |= SETFLAG_EXPORT;
2316                         /* New variable is local ("local VAR=VAL" or
2317                          * "VAR=VAL cmd")
2318                          * and existing one is global, or local
2319                          * on a lower level that new one.
2320                          * Remove it from global variable list:
2321                          */
2322                         *cur_pp = cur->next;
2323                         if (G.shadowed_vars_pp) {
2324                                 /* Save in "shadowed" list */
2325                                 debug_printf_env("shadowing %s'%s'/%u by '%s'/%u\n",
2326                                         cur->flg_export ? "exported " : "",
2327                                         cur->varstr, cur->var_nest_level, str, local_lvl
2328                                 );
2329                                 cur->next = *G.shadowed_vars_pp;
2330                                 *G.shadowed_vars_pp = cur;
2331                         } else {
2332                                 /* Came from pseudo_exec_argv(), no need to save: delete it */
2333                                 debug_printf_env("shadow-deleting %s'%s'/%u by '%s'/%u\n",
2334                                         cur->flg_export ? "exported " : "",
2335                                         cur->varstr, cur->var_nest_level, str, local_lvl
2336                                 );
2337                                 if (cur->max_len == 0) /* allocated "VAR=VAL"? */
2338                                         free_me = cur->varstr; /* then free it later */
2339                                 free(cur);
2340                         }
2341                         break;
2342                 }
2343
2344                 if (strcmp(cur->varstr + name_len, eq_sign + 1) == 0) {
2345                         debug_printf_env("assignement '%s' does not change anything\n", str);
2346  free_and_exp:
2347                         free(str);
2348                         goto exp;
2349                 }
2350
2351                 /* Replace the value in the found "struct variable" */
2352                 if (cur->max_len != 0) {
2353                         if (cur->max_len >= strnlen(str, cur->max_len + 1)) {
2354                                 /* This one is from startup env, reuse space */
2355                                 debug_printf_env("reusing startup env for '%s'\n", str);
2356                                 strcpy(cur->varstr, str);
2357                                 goto free_and_exp;
2358                         }
2359                         /* Can't reuse */
2360                         cur->max_len = 0;
2361                         goto set_str_and_exp;
2362                 }
2363                 /* max_len == 0 signifies "malloced" var, which we can
2364                  * (and have to) free. But we can't free(cur->varstr) here:
2365                  * if cur->flg_export is 1, it is in the environment.
2366                  * We should either unsetenv+free, or wait until putenv,
2367                  * then putenv(new)+free(old).
2368                  */
2369                 free_me = cur->varstr;
2370                 goto set_str_and_exp;
2371         }
2372
2373         /* Not found or shadowed - create new variable struct */
2374         debug_printf_env("%s: alloc new var '%s'/%u\n", __func__, str, local_lvl);
2375         cur = xzalloc(sizeof(*cur));
2376         cur->var_nest_level = local_lvl;
2377         cur->next = *cur_pp;
2378         *cur_pp = cur;
2379
2380  set_str_and_exp:
2381         cur->varstr = str;
2382  exp:
2383 #if !BB_MMU || ENABLE_HUSH_READONLY
2384         if (flags & SETFLAG_MAKE_RO) {
2385                 cur->flg_read_only = 1;
2386         }
2387 #endif
2388         if (flags & SETFLAG_EXPORT)
2389                 cur->flg_export = 1;
2390         retval = 0;
2391         if (cur->flg_export) {
2392                 if (flags & SETFLAG_UNEXPORT) {
2393                         cur->flg_export = 0;
2394                         /* unsetenv was already done */
2395                 } else {
2396                         debug_printf_env("%s: putenv '%s'/%u\n", __func__, cur->varstr, cur->var_nest_level);
2397                         retval = putenv(cur->varstr);
2398                         /* fall through to "free(free_me)" -
2399                          * only now we can free old exported malloced string
2400                          */
2401                 }
2402         }
2403         free(free_me);
2404
2405         handle_changed_special_names(cur->varstr, name_len - 1);
2406
2407         return retval;
2408 }
2409
2410 static void FAST_FUNC set_local_var_from_halves(const char *name, const char *val)
2411 {
2412         char *var = xasprintf("%s=%s", name, val);
2413         set_local_var(var, /*flag:*/ 0);
2414 }
2415
2416 /* Used at startup and after each cd */
2417 static void set_pwd_var(unsigned flag)
2418 {
2419         set_local_var(xasprintf("PWD=%s", get_cwd(/*force:*/ 1)), flag);
2420 }
2421
2422 #if ENABLE_HUSH_UNSET || ENABLE_HUSH_GETOPTS
2423 static int unset_local_var_len(const char *name, int name_len)
2424 {
2425         struct variable *cur;
2426         struct variable **cur_pp;
2427
2428         cur_pp = &G.top_var;
2429         while ((cur = *cur_pp) != NULL) {
2430                 if (strncmp(cur->varstr, name, name_len) == 0
2431                  && cur->varstr[name_len] == '='
2432                 ) {
2433                         if (cur->flg_read_only) {
2434                                 bb_error_msg("%s: readonly variable", name);
2435                                 return EXIT_FAILURE;
2436                         }
2437
2438                         *cur_pp = cur->next;
2439                         debug_printf_env("%s: unsetenv '%s'\n", __func__, cur->varstr);
2440                         bb_unsetenv(cur->varstr);
2441                         if (!cur->max_len)
2442                                 free(cur->varstr);
2443                         free(cur);
2444
2445                         break;
2446                 }
2447                 cur_pp = &cur->next;
2448         }
2449
2450         /* Handle "unset LINENO" et al even if did not find the variable to unset */
2451         handle_changed_special_names(name, name_len);
2452
2453         return EXIT_SUCCESS;
2454 }
2455
2456 static int unset_local_var(const char *name)
2457 {
2458         return unset_local_var_len(name, strlen(name));
2459 }
2460 #endif
2461
2462
2463 /*
2464  * Helpers for "var1=val1 var2=val2 cmd" feature
2465  */
2466 static void add_vars(struct variable *var)
2467 {
2468         struct variable *next;
2469
2470         while (var) {
2471                 next = var->next;
2472                 var->next = G.top_var;
2473                 G.top_var = var;
2474                 if (var->flg_export) {
2475                         debug_printf_env("%s: restoring exported '%s'/%u\n", __func__, var->varstr, var->var_nest_level);
2476                         putenv(var->varstr);
2477                 } else {
2478                         debug_printf_env("%s: restoring variable '%s'/%u\n", __func__, var->varstr, var->var_nest_level);
2479                 }
2480                 var = next;
2481         }
2482 }
2483
2484 /* We put strings[i] into variable table and possibly putenv them.
2485  * If variable is read only, we can free the strings[i]
2486  * which attempts to overwrite it.
2487  * The strings[] vector itself is freed.
2488  */
2489 static void set_vars_and_save_old(char **strings)
2490 {
2491         char **s;
2492
2493         if (!strings)
2494                 return;
2495
2496         s = strings;
2497         while (*s) {
2498                 struct variable *var_p;
2499                 struct variable **var_pp;
2500                 char *eq;
2501
2502                 eq = strchr(*s, '=');
2503                 if (HUSH_DEBUG && !eq)
2504                         bb_error_msg_and_die("BUG in varexp4");
2505                 var_pp = get_ptr_to_local_var(*s, eq - *s);
2506                 if (var_pp) {
2507                         var_p = *var_pp;
2508                         if (var_p->flg_read_only) {
2509                                 char **p;
2510                                 bb_error_msg("%s: readonly variable", *s);
2511                                 /*
2512                                  * "VAR=V BLTIN" unsets VARs after BLTIN completes.
2513                                  * If VAR is readonly, leaving it in the list
2514                                  * after asssignment error (msg above)
2515                                  * causes doubled error message later, on unset.
2516                                  */
2517                                 debug_printf_env("removing/freeing '%s' element\n", *s);
2518                                 free(*s);
2519                                 p = s;
2520                                 do { *p = p[1]; p++; } while (*p);
2521                                 goto next;
2522                         }
2523                         /* below, set_local_var() with nest level will
2524                          * "shadow" (remove) this variable from
2525                          * global linked list.
2526                          */
2527                 }
2528                 debug_printf_env("%s: env override '%s'/%u\n", __func__, *s, G.var_nest_level);
2529                 set_local_var(*s, (G.var_nest_level << SETFLAG_VARLVL_SHIFT) | SETFLAG_EXPORT);
2530                 s++;
2531  next: ;
2532         }
2533         free(strings);
2534 }
2535
2536
2537 /*
2538  * Unicode helper
2539  */
2540 static void reinit_unicode_for_hush(void)
2541 {
2542         /* Unicode support should be activated even if LANG is set
2543          * _during_ shell execution, not only if it was set when
2544          * shell was started. Therefore, re-check LANG every time:
2545          */
2546         if (ENABLE_FEATURE_CHECK_UNICODE_IN_ENV
2547          || ENABLE_UNICODE_USING_LOCALE
2548         ) {
2549                 const char *s = get_local_var_value("LC_ALL");
2550                 if (!s) s = get_local_var_value("LC_CTYPE");
2551                 if (!s) s = get_local_var_value("LANG");
2552                 reinit_unicode(s);
2553         }
2554 }
2555
2556 /*
2557  * in_str support (strings, and "strings" read from files).
2558  */
2559
2560 #if ENABLE_HUSH_INTERACTIVE
2561 /* To test correct lineedit/interactive behavior, type from command line:
2562  *      echo $P\
2563  *      \
2564  *      AT\
2565  *      H\
2566  *      \
2567  * It exercises a lot of corner cases.
2568  */
2569 static const char *setup_prompt_string(void)
2570 {
2571         const char *prompt_str;
2572
2573         debug_printf_prompt("%s promptmode:%d\n", __func__, G.promptmode);
2574
2575 # if ENABLE_FEATURE_EDITING_FANCY_PROMPT
2576         prompt_str = get_local_var_value(G.promptmode == 0 ? "PS1" : "PS2");
2577         if (!prompt_str)
2578                 prompt_str = "";
2579 # else
2580         prompt_str = "> "; /* if PS2, else... */
2581         if (G.promptmode == 0) { /* PS1 */
2582                 /* No fancy prompts supported, (re)generate "CURDIR $ " by hand */
2583                 free(G.PS1);
2584                 /* bash uses $PWD value, even if it is set by user.
2585                  * It uses current dir only if PWD is unset.
2586                  * We always use current dir. */
2587                 G.PS1 = xasprintf("%s %c ", get_cwd(0), (geteuid() != 0) ? '$' : '#');
2588         }
2589 # endif
2590         debug_printf("prompt_str '%s'\n", prompt_str);
2591         return prompt_str;
2592 }
2593 static int get_user_input(struct in_str *i)
2594 {
2595         int r;
2596         const char *prompt_str;
2597
2598         prompt_str = setup_prompt_string();
2599 # if ENABLE_FEATURE_EDITING
2600         for (;;) {
2601                 reinit_unicode_for_hush();
2602                 if (G.flag_SIGINT) {
2603                         /* There was ^C'ed, make it look prettier: */
2604                         bb_putchar('\n');
2605                         G.flag_SIGINT = 0;
2606                 }
2607                 /* buglet: SIGINT will not make new prompt to appear _at once_,
2608                  * only after <Enter>. (^C works immediately) */
2609                 r = read_line_input(G.line_input_state, prompt_str,
2610                                 G.user_input_buf, CONFIG_FEATURE_EDITING_MAX_LEN-1
2611                 );
2612                 /* read_line_input intercepts ^C, "convert" it to SIGINT */
2613                 if (r == 0)
2614                         raise(SIGINT);
2615                 check_and_run_traps();
2616                 if (r != 0 && !G.flag_SIGINT)
2617                         break;
2618                 /* ^C or SIGINT: repeat */
2619                 /* bash prints ^C even on real SIGINT (non-kbd generated) */
2620                 write(STDOUT_FILENO, "^C", 2);
2621                 G.last_exitcode = 128 + SIGINT;
2622         }
2623         if (r < 0) {
2624                 /* EOF/error detected */
2625                 i->p = NULL;
2626                 i->peek_buf[0] = r = EOF;
2627                 return r;
2628         }
2629         i->p = G.user_input_buf;
2630         return (unsigned char)*i->p++;
2631 # else
2632         for (;;) {
2633                 G.flag_SIGINT = 0;
2634                 if (i->last_char == '\0' || i->last_char == '\n') {
2635                         /* Why check_and_run_traps here? Try this interactively:
2636                          * $ trap 'echo INT' INT; (sleep 2; kill -INT $$) &
2637                          * $ <[enter], repeatedly...>
2638                          * Without check_and_run_traps, handler never runs.
2639                          */
2640                         check_and_run_traps();
2641                         fputs(prompt_str, stdout);
2642                 }
2643                 fflush_all();
2644 //FIXME: here ^C or SIGINT will have effect only after <Enter>
2645                 r = hfgetc(i->file);
2646                 /* In !ENABLE_FEATURE_EDITING we don't use read_line_input,
2647                  * no ^C masking happens during fgetc, no special code for ^C:
2648                  * it generates SIGINT as usual.
2649                  */
2650                 check_and_run_traps();
2651                 if (G.flag_SIGINT)
2652                         G.last_exitcode = 128 + SIGINT;
2653                 if (r != '\0')
2654                         break;
2655         }
2656         return r;
2657 # endif
2658 }
2659 /* This is the magic location that prints prompts
2660  * and gets data back from the user */
2661 static int fgetc_interactive(struct in_str *i)
2662 {
2663         int ch;
2664         /* If it's interactive stdin, get new line. */
2665         if (G_interactive_fd && i->file->is_stdin) {
2666                 /* Returns first char (or EOF), the rest is in i->p[] */
2667                 ch = get_user_input(i);
2668                 G.promptmode = 1; /* PS2 */
2669                 debug_printf_prompt("%s promptmode=%d\n", __func__, G.promptmode);
2670         } else {
2671                 /* Not stdin: script file, sourced file, etc */
2672                 do ch = hfgetc(i->file); while (ch == '\0');
2673         }
2674         return ch;
2675 }
2676 #else
2677 static ALWAYS_INLINE int fgetc_interactive(struct in_str *i)
2678 {
2679         int ch;
2680         do ch = hfgetc(i->file); while (ch == '\0');
2681         return ch;
2682 }
2683 #endif  /* INTERACTIVE */
2684
2685 static int i_getch(struct in_str *i)
2686 {
2687         int ch;
2688
2689         if (!i->file) {
2690                 /* string-based in_str */
2691                 ch = (unsigned char)*i->p;
2692                 if (ch != '\0') {
2693                         i->p++;
2694                         i->last_char = ch;
2695                         return ch;
2696                 }
2697                 return EOF;
2698         }
2699
2700         /* FILE-based in_str */
2701
2702 #if ENABLE_FEATURE_EDITING
2703         /* This can be stdin, check line editing char[] buffer */
2704         if (i->p && *i->p != '\0') {
2705                 ch = (unsigned char)*i->p++;
2706                 goto out;
2707         }
2708 #endif
2709         /* peek_buf[] is an int array, not char. Can contain EOF. */
2710         ch = i->peek_buf[0];
2711         if (ch != 0) {
2712                 int ch2 = i->peek_buf[1];
2713                 i->peek_buf[0] = ch2;
2714                 if (ch2 == 0) /* very likely, avoid redundant write */
2715                         goto out;
2716                 i->peek_buf[1] = 0;
2717                 goto out;
2718         }
2719
2720         ch = fgetc_interactive(i);
2721  out:
2722         debug_printf("file_get: got '%c' %d\n", ch, ch);
2723         i->last_char = ch;
2724 #if ENABLE_HUSH_LINENO_VAR
2725         if (ch == '\n') {
2726                 G.parse_lineno++;
2727                 debug_printf_parse("G.parse_lineno++ = %u\n", G.parse_lineno);
2728         }
2729 #endif
2730         return ch;
2731 }
2732
2733 static int i_peek(struct in_str *i)
2734 {
2735         int ch;
2736
2737         if (!i->file) {
2738                 /* string-based in_str */
2739                 /* Doesn't report EOF on NUL. None of the callers care. */
2740                 return (unsigned char)*i->p;
2741         }
2742
2743         /* FILE-based in_str */
2744
2745 #if ENABLE_FEATURE_EDITING && ENABLE_HUSH_INTERACTIVE
2746         /* This can be stdin, check line editing char[] buffer */
2747         if (i->p && *i->p != '\0')
2748                 return (unsigned char)*i->p;
2749 #endif
2750         /* peek_buf[] is an int array, not char. Can contain EOF. */
2751         ch = i->peek_buf[0];
2752         if (ch != 0)
2753                 return ch;
2754
2755         /* Need to get a new char */
2756         ch = fgetc_interactive(i);
2757         debug_printf("file_peek: got '%c' %d\n", ch, ch);
2758
2759         /* Save it by either rolling back line editing buffer, or in i->peek_buf[0] */
2760 #if ENABLE_FEATURE_EDITING && ENABLE_HUSH_INTERACTIVE
2761         if (i->p) {
2762                 i->p -= 1;
2763                 return ch;
2764         }
2765 #endif
2766         i->peek_buf[0] = ch;
2767         /*i->peek_buf[1] = 0; - already is */
2768         return ch;
2769 }
2770
2771 /* Only ever called if i_peek() was called, and did not return EOF.
2772  * IOW: we know the previous peek saw an ordinary char, not EOF, not NUL,
2773  * not end-of-line. Therefore we never need to read a new editing line here.
2774  */
2775 static int i_peek2(struct in_str *i)
2776 {
2777         int ch;
2778
2779         /* There are two cases when i->p[] buffer exists.
2780          * (1) it's a string in_str.
2781          * (2) It's a file, and we have a saved line editing buffer.
2782          * In both cases, we know that i->p[0] exists and not NUL, and
2783          * the peek2 result is in i->p[1].
2784          */
2785         if (i->p)
2786                 return (unsigned char)i->p[1];
2787
2788         /* Now we know it is a file-based in_str. */
2789
2790         /* peek_buf[] is an int array, not char. Can contain EOF. */
2791         /* Is there 2nd char? */
2792         ch = i->peek_buf[1];
2793         if (ch == 0) {
2794                 /* We did not read it yet, get it now */
2795                 do ch = hfgetc(i->file); while (ch == '\0');
2796                 i->peek_buf[1] = ch;
2797         }
2798
2799         debug_printf("file_peek2: got '%c' %d\n", ch, ch);
2800         return ch;
2801 }
2802
2803 static int i_getch_and_eat_bkslash_nl(struct in_str *input)
2804 {
2805         for (;;) {
2806                 int ch, ch2;
2807
2808                 ch = i_getch(input);
2809                 if (ch != '\\')
2810                         return ch;
2811                 ch2 = i_peek(input);
2812                 if (ch2 != '\n')
2813                         return ch;
2814                 /* backslash+newline, skip it */
2815                 i_getch(input);
2816         }
2817 }
2818
2819 /* Note: this function _eats_ \<newline> pairs, safe to use plain
2820  * i_getch() after it instead of i_getch_and_eat_bkslash_nl().
2821  */
2822 static int i_peek_and_eat_bkslash_nl(struct in_str *input)
2823 {
2824         for (;;) {
2825                 int ch, ch2;
2826
2827                 ch = i_peek(input);
2828                 if (ch != '\\')
2829                         return ch;
2830                 ch2 = i_peek2(input);
2831                 if (ch2 != '\n')
2832                         return ch;
2833                 /* backslash+newline, skip it */
2834                 i_getch(input);
2835                 i_getch(input);
2836         }
2837 }
2838
2839 static void setup_file_in_str(struct in_str *i, HFILE *fp)
2840 {
2841         memset(i, 0, sizeof(*i));
2842         i->file = fp;
2843         /* i->p = NULL; */
2844 }
2845
2846 static void setup_string_in_str(struct in_str *i, const char *s)
2847 {
2848         memset(i, 0, sizeof(*i));
2849         /*i->file = NULL */;
2850         i->p = s;
2851 }
2852
2853
2854 /*
2855  * o_string support
2856  */
2857 #define B_CHUNK  (32 * sizeof(char*))
2858
2859 static void o_reset_to_empty_unquoted(o_string *o)
2860 {
2861         o->length = 0;
2862         o->has_quoted_part = 0;
2863         if (o->data)
2864                 o->data[0] = '\0';
2865 }
2866
2867 static void o_free_and_set_NULL(o_string *o)
2868 {
2869         free(o->data);
2870         memset(o, 0, sizeof(*o));
2871 }
2872
2873 static ALWAYS_INLINE void o_free(o_string *o)
2874 {
2875         free(o->data);
2876 }
2877
2878 static void o_grow_by(o_string *o, int len)
2879 {
2880         if (o->length + len > o->maxlen) {
2881                 o->maxlen += (2 * len) | (B_CHUNK-1);
2882                 o->data = xrealloc(o->data, 1 + o->maxlen);
2883         }
2884 }
2885
2886 static void o_addchr(o_string *o, int ch)
2887 {
2888         debug_printf("o_addchr: '%c' o->length=%d o=%p\n", ch, o->length, o);
2889         if (o->length < o->maxlen) {
2890                 /* likely. avoid o_grow_by() call */
2891  add:
2892                 o->data[o->length] = ch;
2893                 o->length++;
2894                 o->data[o->length] = '\0';
2895                 return;
2896         }
2897         o_grow_by(o, 1);
2898         goto add;
2899 }
2900
2901 #if 0
2902 /* Valid only if we know o_string is not empty */
2903 static void o_delchr(o_string *o)
2904 {
2905         o->length--;
2906         o->data[o->length] = '\0';
2907 }
2908 #endif
2909
2910 static void o_addblock(o_string *o, const char *str, int len)
2911 {
2912         o_grow_by(o, len);
2913         ((char*)mempcpy(&o->data[o->length], str, len))[0] = '\0';
2914         o->length += len;
2915 }
2916
2917 static void o_addstr(o_string *o, const char *str)
2918 {
2919         o_addblock(o, str, strlen(str));
2920 }
2921
2922 static void o_addstr_with_NUL(o_string *o, const char *str)
2923 {
2924         o_addblock(o, str, strlen(str) + 1);
2925 }
2926
2927 #if !BB_MMU
2928 static void nommu_addchr(o_string *o, int ch)
2929 {
2930         if (o)
2931                 o_addchr(o, ch);
2932 }
2933 #else
2934 # define nommu_addchr(o, str) ((void)0)
2935 #endif
2936
2937 #if ENABLE_HUSH_MODE_X
2938 static void x_mode_addchr(int ch)
2939 {
2940         o_addchr(&G.x_mode_buf, ch);
2941 }
2942 static void x_mode_addstr(const char *str)
2943 {
2944         o_addstr(&G.x_mode_buf, str);
2945 }
2946 static void x_mode_addblock(const char *str, int len)
2947 {
2948         o_addblock(&G.x_mode_buf, str, len);
2949 }
2950 static void x_mode_prefix(void)
2951 {
2952         int n = G.x_mode_depth;
2953         do x_mode_addchr('+'); while (--n >= 0);
2954 }
2955 static void x_mode_flush(void)
2956 {
2957         int len = G.x_mode_buf.length;
2958         if (len <= 0)
2959                 return;
2960         if (G.x_mode_fd > 0) {
2961                 G.x_mode_buf.data[len] = '\n';
2962                 full_write(G.x_mode_fd, G.x_mode_buf.data, len + 1);
2963         }
2964         G.x_mode_buf.length = 0;
2965 }
2966 #endif
2967
2968 /*
2969  * HUSH_BRACE_EXPANSION code needs corresponding quoting on variable expansion side.
2970  * Currently, "v='{q,w}'; echo $v" erroneously expands braces in $v.
2971  * Apparently, on unquoted $v bash still does globbing
2972  * ("v='*.txt'; echo $v" prints all .txt files),
2973  * but NOT brace expansion! Thus, there should be TWO independent
2974  * quoting mechanisms on $v expansion side: one protects
2975  * $v from brace expansion, and other additionally protects "$v" against globbing.
2976  * We have only second one.
2977  */
2978
2979 #if ENABLE_HUSH_BRACE_EXPANSION
2980 # define MAYBE_BRACES "{}"
2981 #else
2982 # define MAYBE_BRACES ""
2983 #endif
2984
2985 /* My analysis of quoting semantics tells me that state information
2986  * is associated with a destination, not a source.
2987  */
2988 static void o_addqchr(o_string *o, int ch)
2989 {
2990         int sz = 1;
2991         char *found = strchr("*?[\\" MAYBE_BRACES, ch);
2992         if (found)
2993                 sz++;
2994         o_grow_by(o, sz);
2995         if (found) {
2996                 o->data[o->length] = '\\';
2997                 o->length++;
2998         }
2999         o->data[o->length] = ch;
3000         o->length++;
3001         o->data[o->length] = '\0';
3002 }
3003
3004 static void o_addQchr(o_string *o, int ch)
3005 {
3006         int sz = 1;
3007         if ((o->o_expflags & EXP_FLAG_ESC_GLOB_CHARS)
3008          && strchr("*?[\\" MAYBE_BRACES, ch)
3009         ) {
3010                 sz++;
3011                 o->data[o->length] = '\\';
3012                 o->length++;
3013         }
3014         o_grow_by(o, sz);
3015         o->data[o->length] = ch;
3016         o->length++;
3017         o->data[o->length] = '\0';
3018 }
3019
3020 static void o_addqblock(o_string *o, const char *str, int len)
3021 {
3022         while (len) {
3023                 char ch;
3024                 int sz;
3025                 int ordinary_cnt = strcspn(str, "*?[\\" MAYBE_BRACES);
3026                 if (ordinary_cnt > len) /* paranoia */
3027                         ordinary_cnt = len;
3028                 o_addblock(o, str, ordinary_cnt);
3029                 if (ordinary_cnt == len)
3030                         return; /* NUL is already added by o_addblock */
3031                 str += ordinary_cnt;
3032                 len -= ordinary_cnt + 1; /* we are processing + 1 char below */
3033
3034                 ch = *str++;
3035                 sz = 1;
3036                 if (ch) { /* it is necessarily one of "*?[\\" MAYBE_BRACES */
3037                         sz++;
3038                         o->data[o->length] = '\\';
3039                         o->length++;
3040                 }
3041                 o_grow_by(o, sz);
3042                 o->data[o->length] = ch;
3043                 o->length++;
3044         }
3045         o->data[o->length] = '\0';
3046 }
3047
3048 static void o_addQblock(o_string *o, const char *str, int len)
3049 {
3050         if (!(o->o_expflags & EXP_FLAG_ESC_GLOB_CHARS)) {
3051                 o_addblock(o, str, len);
3052                 return;
3053         }
3054         o_addqblock(o, str, len);
3055 }
3056
3057 static void o_addQstr(o_string *o, const char *str)
3058 {
3059         o_addQblock(o, str, strlen(str));
3060 }
3061
3062 /* A special kind of o_string for $VAR and `cmd` expansion.
3063  * It contains char* list[] at the beginning, which is grown in 16 element
3064  * increments. Actual string data starts at the next multiple of 16 * (char*).
3065  * list[i] contains an INDEX (int!) into this string data.
3066  * It means that if list[] needs to grow, data needs to be moved higher up
3067  * but list[i]'s need not be modified.
3068  * NB: remembering how many list[i]'s you have there is crucial.
3069  * o_finalize_list() operation post-processes this structure - calculates
3070  * and stores actual char* ptrs in list[]. Oh, it NULL terminates it as well.
3071  */
3072 #if DEBUG_EXPAND || DEBUG_GLOB
3073 static void debug_print_list(const char *prefix, o_string *o, int n)
3074 {
3075         char **list = (char**)o->data;
3076         int string_start = ((n + 0xf) & ~0xf) * sizeof(list[0]);
3077         int i = 0;
3078
3079         indent();
3080         fdprintf(2, "%s: list:%p n:%d string_start:%d length:%d maxlen:%d glob:%d quoted:%d escape:%d\n",
3081                         prefix, list, n, string_start, o->length, o->maxlen,
3082                         !!(o->o_expflags & EXP_FLAG_GLOB),
3083                         o->has_quoted_part,
3084                         !!(o->o_expflags & EXP_FLAG_ESC_GLOB_CHARS));
3085         while (i < n) {
3086                 indent();
3087                 fdprintf(2, " list[%d]=%d '%s' %p\n", i, (int)(uintptr_t)list[i],
3088                                 o->data + (int)(uintptr_t)list[i] + string_start,
3089                                 o->data + (int)(uintptr_t)list[i] + string_start);
3090                 i++;
3091         }
3092         if (n) {
3093                 const char *p = o->data + (int)(uintptr_t)list[n - 1] + string_start;
3094                 indent();
3095                 fdprintf(2, " total_sz:%ld\n", (long)((p + strlen(p) + 1) - o->data));
3096         }
3097 }
3098 #else
3099 # define debug_print_list(prefix, o, n) ((void)0)
3100 #endif
3101
3102 /* n = o_save_ptr_helper(str, n) "starts new string" by storing an index value
3103  * in list[n] so that it points past last stored byte so far.
3104  * It returns n+1. */
3105 static int o_save_ptr_helper(o_string *o, int n)
3106 {
3107         char **list = (char**)o->data;
3108         int string_start;
3109         int string_len;
3110
3111         if (!o->has_empty_slot) {
3112                 string_start = ((n + 0xf) & ~0xf) * sizeof(list[0]);
3113                 string_len = o->length - string_start;
3114                 if (!(n & 0xf)) { /* 0, 0x10, 0x20...? */
3115                         debug_printf_list("list[%d]=%d string_start=%d (growing)\n", n, string_len, string_start);
3116                         /* list[n] points to string_start, make space for 16 more pointers */
3117                         o->maxlen += 0x10 * sizeof(list[0]);
3118                         o->data = xrealloc(o->data, o->maxlen + 1);
3119                         list = (char**)o->data;
3120                         memmove(list + n + 0x10, list + n, string_len);
3121                         /*
3122                          * expand_on_ifs() has a "previous argv[] ends in IFS?"
3123                          * check. (grep for -prev-ifs-check-).
3124                          * Ensure that argv[-1][last] is not garbage
3125                          * but zero bytes, to save index check there.
3126                          */
3127                         list[n + 0x10 - 1] = 0;
3128                         o->length += 0x10 * sizeof(list[0]);
3129                 } else {
3130                         debug_printf_list("list[%d]=%d string_start=%d\n",
3131                                         n, string_len, string_start);
3132                 }
3133         } else {
3134                 /* We have empty slot at list[n], reuse without growth */
3135                 string_start = ((n+1 + 0xf) & ~0xf) * sizeof(list[0]); /* NB: n+1! */
3136                 string_len = o->length - string_start;
3137                 debug_printf_list("list[%d]=%d string_start=%d (empty slot)\n",
3138                                 n, string_len, string_start);
3139                 o->has_empty_slot = 0;
3140         }
3141         o->has_quoted_part = 0;
3142         list[n] = (char*)(uintptr_t)string_len;
3143         return n + 1;
3144 }
3145
3146 /* "What was our last o_save_ptr'ed position (byte offset relative o->data)?" */
3147 static int o_get_last_ptr(o_string *o, int n)
3148 {
3149         char **list = (char**)o->data;
3150         int string_start = ((n + 0xf) & ~0xf) * sizeof(list[0]);
3151
3152         return ((int)(uintptr_t)list[n-1]) + string_start;
3153 }
3154
3155 /*
3156  * Globbing routines.
3157  *
3158  * Most words in commands need to be globbed, even ones which are
3159  * (single or double) quoted. This stems from the possiblity of
3160  * constructs like "abc"* and 'abc'* - these should be globbed.
3161  * Having a different code path for fully-quoted strings ("abc",
3162  * 'abc') would only help performance-wise, but we still need
3163  * code for partially-quoted strings.
3164  *
3165  * Unfortunately, if we want to match bash and ash behavior in all cases,
3166  * the logic can't be "shell-syntax argument is first transformed
3167  * to a string, then globbed, and if globbing does not match anything,
3168  * it is used verbatim". Here are two examples where it fails:
3169  *
3170  *      echo 'b\*'?
3171  *
3172  * The globbing can't be avoided (because of '?' at the end).
3173  * The glob pattern is: b\\\*? - IOW, both \ and * are literals
3174  * and are glob-escaped. If this does not match, bash/ash print b\*?
3175  * - IOW: they "unbackslash" the glob pattern.
3176  * Now, look at this:
3177  *
3178  *      v='\\\*'; echo b$v?
3179  *
3180  * The glob pattern is the same here: b\\\*? - the unquoted $v expansion
3181  * should be used as glob pattern with no changes. However, if glob
3182  * does not match, bash/ash print b\\\*? - NOT THE SAME as first example!
3183  *
3184  * ash implements this by having an encoded representation of the word
3185  * to glob, which IS NOT THE SAME as the glob pattern - it has more data.
3186  * Glob pattern is derived from it. If glob fails, the decision what result
3187  * should be is made using that encoded representation. Not glob pattern.
3188  */
3189
3190 #if ENABLE_HUSH_BRACE_EXPANSION
3191 /* There in a GNU extension, GLOB_BRACE, but it is not usable:
3192  * first, it processes even {a} (no commas), second,
3193  * I didn't manage to make it return strings when they don't match
3194  * existing files. Need to re-implement it.
3195  */
3196
3197 /* Helper */
3198 static int glob_needed(const char *s)
3199 {
3200         while (*s) {
3201                 if (*s == '\\') {
3202                         if (!s[1])
3203                                 return 0;
3204                         s += 2;
3205                         continue;
3206                 }
3207                 if (*s == '*' || *s == '[' || *s == '?' || *s == '{')
3208                         return 1;
3209                 s++;
3210         }
3211         return 0;
3212 }
3213 /* Return pointer to next closing brace or to comma */
3214 static const char *next_brace_sub(const char *cp)
3215 {
3216         unsigned depth = 0;
3217         cp++;
3218         while (*cp != '\0') {
3219                 if (*cp == '\\') {
3220                         if (*++cp == '\0')
3221                                 break;
3222                         cp++;
3223                         continue;
3224                 }
3225                 if ((*cp == '}' && depth-- == 0) || (*cp == ',' && depth == 0))
3226                         break;
3227                 if (*cp++ == '{')
3228                         depth++;
3229         }
3230
3231         return *cp != '\0' ? cp : NULL;
3232 }
3233 /* Recursive brace globber. Note: may garble pattern[]. */
3234 static int glob_brace(char *pattern, o_string *o, int n)
3235 {
3236         char *new_pattern_buf;
3237         const char *begin;
3238         const char *next;
3239         const char *rest;
3240         const char *p;
3241         size_t rest_len;
3242
3243         debug_printf_glob("glob_brace('%s')\n", pattern);
3244
3245         begin = pattern;
3246         while (1) {
3247                 if (*begin == '\0')
3248                         goto simple_glob;
3249                 if (*begin == '{') {
3250                         /* Find the first sub-pattern and at the same time
3251                          * find the rest after the closing brace */
3252                         next = next_brace_sub(begin);
3253                         if (next == NULL) {
3254                                 /* An illegal expression */
3255                                 goto simple_glob;
3256                         }
3257                         if (*next == '}') {
3258                                 /* "{abc}" with no commas - illegal
3259                                  * brace expr, disregard and skip it */
3260                                 begin = next + 1;
3261                                 continue;
3262                         }
3263                         break;
3264                 }
3265                 if (*begin == '\\' && begin[1] != '\0')
3266                         begin++;
3267                 begin++;
3268         }
3269         debug_printf_glob("begin:%s\n", begin);
3270         debug_printf_glob("next:%s\n", next);
3271
3272         /* Now find the end of the whole brace expression */
3273         rest = next;
3274         while (*rest != '}') {
3275                 rest = next_brace_sub(rest);
3276                 if (rest == NULL) {
3277                         /* An illegal expression */
3278                         goto simple_glob;
3279                 }
3280                 debug_printf_glob("rest:%s\n", rest);
3281         }
3282         rest_len = strlen(++rest) + 1;
3283
3284         /* We are sure the brace expression is well-formed */
3285
3286         /* Allocate working buffer large enough for our work */
3287         new_pattern_buf = xmalloc(strlen(pattern));
3288
3289         /* We have a brace expression.  BEGIN points to the opening {,
3290          * NEXT points past the terminator of the first element, and REST
3291          * points past the final }.  We will accumulate result names from
3292          * recursive runs for each brace alternative in the buffer using
3293          * GLOB_APPEND.  */
3294
3295         p = begin + 1;
3296         while (1) {
3297                 /* Construct the new glob expression */
3298                 memcpy(
3299                         mempcpy(
3300                                 mempcpy(new_pattern_buf,
3301                                         /* We know the prefix for all sub-patterns */
3302                                         pattern, begin - pattern),
3303                                 p, next - p),
3304                         rest, rest_len);
3305
3306                 /* Note: glob_brace() may garble new_pattern_buf[].
3307                  * That's why we re-copy prefix every time (1st memcpy above).
3308                  */
3309                 n = glob_brace(new_pattern_buf, o, n);
3310                 if (*next == '}') {
3311                         /* We saw the last entry */
3312                         break;
3313                 }
3314                 p = next + 1;
3315                 next = next_brace_sub(next);
3316         }
3317         free(new_pattern_buf);
3318         return n;
3319
3320  simple_glob:
3321         {
3322                 int gr;
3323                 glob_t globdata;
3324
3325                 memset(&globdata, 0, sizeof(globdata));
3326                 gr = glob(pattern, 0, NULL, &globdata);
3327                 debug_printf_glob("glob('%s'):%d\n", pattern, gr);
3328                 if (gr != 0) {
3329                         if (gr == GLOB_NOMATCH) {
3330                                 globfree(&globdata);
3331                                 /* NB: garbles parameter */
3332                                 unbackslash(pattern);
3333                                 o_addstr_with_NUL(o, pattern);
3334                                 debug_printf_glob("glob pattern '%s' is literal\n", pattern);
3335                                 return o_save_ptr_helper(o, n);
3336                         }
3337                         if (gr == GLOB_NOSPACE)
3338                                 bb_die_memory_exhausted();
3339                         /* GLOB_ABORTED? Only happens with GLOB_ERR flag,
3340                          * but we didn't specify it. Paranoia again. */
3341                         bb_error_msg_and_die("glob error %d on '%s'", gr, pattern);
3342                 }
3343                 if (globdata.gl_pathv && globdata.gl_pathv[0]) {
3344                         char **argv = globdata.gl_pathv;
3345                         while (1) {
3346                                 o_addstr_with_NUL(o, *argv);
3347                                 n = o_save_ptr_helper(o, n);
3348                                 argv++;
3349                                 if (!*argv)
3350                                         break;
3351                         }
3352                 }
3353                 globfree(&globdata);
3354         }
3355         return n;
3356 }
3357 /* Performs globbing on last list[],
3358  * saving each result as a new list[].
3359  */
3360 static int perform_glob(o_string *o, int n)
3361 {
3362         char *pattern, *copy;
3363
3364         debug_printf_glob("start perform_glob: n:%d o->data:%p\n", n, o->data);
3365         if (!o->data)
3366                 return o_save_ptr_helper(o, n);
3367         pattern = o->data + o_get_last_ptr(o, n);
3368         debug_printf_glob("glob pattern '%s'\n", pattern);
3369         if (!glob_needed(pattern)) {
3370                 /* unbackslash last string in o in place, fix length */
3371                 o->length = unbackslash(pattern) - o->data;
3372                 debug_printf_glob("glob pattern '%s' is literal\n", pattern);
3373                 return o_save_ptr_helper(o, n);
3374         }
3375
3376         copy = xstrdup(pattern);
3377         /* "forget" pattern in o */
3378         o->length = pattern - o->data;
3379         n = glob_brace(copy, o, n);
3380         free(copy);
3381         if (DEBUG_GLOB)
3382                 debug_print_list("perform_glob returning", o, n);
3383         return n;
3384 }
3385
3386 #else /* !HUSH_BRACE_EXPANSION */
3387
3388 /* Helper */
3389 static int glob_needed(const char *s)
3390 {
3391         while (*s) {
3392                 if (*s == '\\') {
3393                         if (!s[1])
3394                                 return 0;
3395                         s += 2;
3396                         continue;
3397                 }
3398                 if (*s == '*' || *s == '[' || *s == '?')
3399                         return 1;
3400                 s++;
3401         }
3402         return 0;
3403 }
3404 /* Performs globbing on last list[],
3405  * saving each result as a new list[].
3406  */
3407 static int perform_glob(o_string *o, int n)
3408 {
3409         glob_t globdata;
3410         int gr;
3411         char *pattern;
3412
3413         debug_printf_glob("start perform_glob: n:%d o->data:%p\n", n, o->data);
3414         if (!o->data)
3415                 return o_save_ptr_helper(o, n);
3416         pattern = o->data + o_get_last_ptr(o, n);
3417         debug_printf_glob("glob pattern '%s'\n", pattern);
3418         if (!glob_needed(pattern)) {
3419  literal:
3420                 /* unbackslash last string in o in place, fix length */
3421                 o->length = unbackslash(pattern) - o->data;
3422                 debug_printf_glob("glob pattern '%s' is literal\n", pattern);
3423                 return o_save_ptr_helper(o, n);
3424         }
3425
3426         memset(&globdata, 0, sizeof(globdata));
3427         /* Can't use GLOB_NOCHECK: it does not unescape the string.
3428          * If we glob "*.\*" and don't find anything, we need
3429          * to fall back to using literal "*.*", but GLOB_NOCHECK
3430          * will return "*.\*"!
3431          */
3432         gr = glob(pattern, 0, NULL, &globdata);
3433         debug_printf_glob("glob('%s'):%d\n", pattern, gr);
3434         if (gr != 0) {
3435                 if (gr == GLOB_NOMATCH) {
3436                         globfree(&globdata);
3437                         goto literal;
3438                 }
3439                 if (gr == GLOB_NOSPACE)
3440                         bb_die_memory_exhausted();
3441                 /* GLOB_ABORTED? Only happens with GLOB_ERR flag,
3442                  * but we didn't specify it. Paranoia again. */
3443                 bb_error_msg_and_die("glob error %d on '%s'", gr, pattern);
3444         }
3445         if (globdata.gl_pathv && globdata.gl_pathv[0]) {
3446                 char **argv = globdata.gl_pathv;
3447                 /* "forget" pattern in o */
3448                 o->length = pattern - o->data;
3449                 while (1) {
3450                         o_addstr_with_NUL(o, *argv);
3451                         n = o_save_ptr_helper(o, n);
3452                         argv++;
3453                         if (!*argv)
3454                                 break;
3455                 }
3456         }
3457         globfree(&globdata);
3458         if (DEBUG_GLOB)
3459                 debug_print_list("perform_glob returning", o, n);
3460         return n;
3461 }
3462
3463 #endif /* !HUSH_BRACE_EXPANSION */
3464
3465 /* If o->o_expflags & EXP_FLAG_GLOB, glob the string so far remembered.
3466  * Otherwise, just finish current list[] and start new */
3467 static int o_save_ptr(o_string *o, int n)
3468 {
3469         if (o->o_expflags & EXP_FLAG_GLOB) {
3470                 /* If o->has_empty_slot, list[n] was already globbed
3471                  * (if it was requested back then when it was filled)
3472                  * so don't do that again! */
3473                 if (!o->has_empty_slot)
3474                         return perform_glob(o, n); /* o_save_ptr_helper is inside */
3475         }
3476         return o_save_ptr_helper(o, n);
3477 }
3478
3479 /* "Please convert list[n] to real char* ptrs, and NULL terminate it." */
3480 static char **o_finalize_list(o_string *o, int n)
3481 {
3482         char **list;
3483         int string_start;
3484
3485         if (DEBUG_EXPAND)
3486                 debug_print_list("finalized", o, n);
3487         debug_printf_expand("finalized n:%d\n", n);
3488         list = (char**)o->data;
3489         string_start = ((n + 0xf) & ~0xf) * sizeof(list[0]);
3490         list[--n] = NULL;
3491         while (n) {
3492                 n--;
3493                 list[n] = o->data + (int)(uintptr_t)list[n] + string_start;
3494         }
3495         return list;
3496 }
3497
3498 static void free_pipe_list(struct pipe *pi);
3499
3500 /* Returns pi->next - next pipe in the list */
3501 static struct pipe *free_pipe(struct pipe *pi)
3502 {
3503         struct pipe *next;
3504         int i;
3505
3506         debug_printf_clean("free_pipe (pid %d)\n", getpid());
3507         for (i = 0; i < pi->num_cmds; i++) {
3508                 struct command *command;
3509                 struct redir_struct *r, *rnext;
3510
3511                 command = &pi->cmds[i];
3512                 debug_printf_clean("  command %d:\n", i);
3513                 if (command->argv) {
3514                         if (DEBUG_CLEAN) {
3515                                 int a;
3516                                 char **p;
3517                                 for (a = 0, p = command->argv; *p; a++, p++) {
3518                                         debug_printf_clean("   argv[%d] = %s\n", a, *p);
3519                                 }
3520                         }
3521                         free_strings(command->argv);
3522                         //command->argv = NULL;
3523                 }
3524                 /* not "else if": on syntax error, we may have both! */
3525                 if (command->group) {
3526                         debug_printf_clean("   begin group (cmd_type:%d)\n",
3527                                         command->cmd_type);
3528                         free_pipe_list(command->group);
3529                         debug_printf_clean("   end group\n");
3530                         //command->group = NULL;
3531                 }
3532                 /* else is crucial here.
3533                  * If group != NULL, child_func is meaningless */
3534 #if ENABLE_HUSH_FUNCTIONS
3535                 else if (command->child_func) {
3536                         debug_printf_exec("cmd %p releases child func at %p\n", command, command->child_func);
3537                         command->child_func->parent_cmd = NULL;
3538                 }
3539 #endif
3540 #if !BB_MMU
3541                 free(command->group_as_string);
3542                 //command->group_as_string = NULL;
3543 #endif
3544                 for (r = command->redirects; r; r = rnext) {
3545                         debug_printf_clean("   redirect %d%s",
3546                                         r->rd_fd, redir_table[r->rd_type].descrip);
3547                         /* guard against the case >$FOO, where foo is unset or blank */
3548                         if (r->rd_filename) {
3549                                 debug_printf_clean(" fname:'%s'\n", r->rd_filename);
3550                                 free(r->rd_filename);
3551                                 //r->rd_filename = NULL;
3552                         }
3553                         debug_printf_clean(" rd_dup:%d\n", r->rd_dup);
3554                         rnext = r->next;
3555                         free(r);
3556                 }
3557                 //command->redirects = NULL;
3558         }
3559         free(pi->cmds);   /* children are an array, they get freed all at once */
3560         //pi->cmds = NULL;
3561 #if ENABLE_HUSH_JOB
3562         free(pi->cmdtext);
3563         //pi->cmdtext = NULL;
3564 #endif
3565
3566         next = pi->next;
3567         free(pi);
3568         return next;
3569 }
3570
3571 static void free_pipe_list(struct pipe *pi)
3572 {
3573         while (pi) {
3574 #if HAS_KEYWORDS
3575                 debug_printf_clean("pipe reserved word %d\n", pi->res_word);
3576 #endif
3577                 debug_printf_clean("pipe followup code %d\n", pi->followup);
3578                 pi = free_pipe(pi);
3579         }
3580 }
3581
3582
3583 /*** Parsing routines ***/
3584
3585 #ifndef debug_print_tree
3586 static void debug_print_tree(struct pipe *pi, int lvl)
3587 {
3588         static const char *const PIPE[] = {
3589                 [PIPE_SEQ] = "SEQ",
3590                 [PIPE_AND] = "AND",
3591                 [PIPE_OR ] = "OR" ,
3592                 [PIPE_BG ] = "BG" ,
3593         };
3594         static const char *RES[] = {
3595                 [RES_NONE ] = "NONE" ,
3596 # if ENABLE_HUSH_IF
3597                 [RES_IF   ] = "IF"   ,
3598                 [RES_THEN ] = "THEN" ,
3599                 [RES_ELIF ] = "ELIF" ,
3600                 [RES_ELSE ] = "ELSE" ,
3601                 [RES_FI   ] = "FI"   ,
3602 # endif
3603 # if ENABLE_HUSH_LOOPS
3604                 [RES_FOR  ] = "FOR"  ,
3605                 [RES_WHILE] = "WHILE",
3606                 [RES_UNTIL] = "UNTIL",
3607                 [RES_DO   ] = "DO"   ,
3608                 [RES_DONE ] = "DONE" ,
3609 # endif
3610 # if ENABLE_HUSH_LOOPS || ENABLE_HUSH_CASE
3611                 [RES_IN   ] = "IN"   ,
3612 # endif
3613 # if ENABLE_HUSH_CASE
3614                 [RES_CASE ] = "CASE" ,
3615                 [RES_CASE_IN ] = "CASE_IN" ,
3616                 [RES_MATCH] = "MATCH",
3617                 [RES_CASE_BODY] = "CASE_BODY",
3618                 [RES_ESAC ] = "ESAC" ,
3619 # endif
3620                 [RES_XXXX ] = "XXXX" ,
3621                 [RES_SNTX ] = "SNTX" ,
3622         };
3623         static const char *const CMDTYPE[] = {
3624                 "{}",
3625                 "()",
3626                 "[noglob]",
3627 # if ENABLE_HUSH_FUNCTIONS
3628                 "func()",
3629 # endif
3630         };
3631
3632         int pin, prn;
3633
3634         pin = 0;
3635         while (pi) {
3636                 fdprintf(2, "%*spipe %d %sres_word=%s followup=%d %s\n",
3637                                 lvl*2, "",
3638                                 pin,
3639                                 (IF_HAS_KEYWORDS(pi->pi_inverted ? "! " :) ""),
3640                                 RES[pi->res_word],
3641                                 pi->followup, PIPE[pi->followup]
3642                 );
3643                 prn = 0;
3644                 while (prn < pi->num_cmds) {
3645                         struct command *command = &pi->cmds[prn];
3646                         char **argv = command->argv;
3647
3648                         fdprintf(2, "%*s cmd %d assignment_cnt:%d",
3649                                         lvl*2, "", prn,
3650                                         command->assignment_cnt);
3651 #if ENABLE_HUSH_LINENO_VAR
3652                         fdprintf(2, " LINENO:%u", command->lineno);
3653 #endif
3654                         if (command->group) {
3655                                 fdprintf(2, " group %s: (argv=%p)%s%s\n",
3656                                                 CMDTYPE[command->cmd_type],
3657                                                 argv
3658 # if !BB_MMU
3659                                                 , " group_as_string:", command->group_as_string
3660 # else
3661                                                 , "", ""
3662 # endif
3663                                 );
3664                                 debug_print_tree(command->group, lvl+1);
3665                                 prn++;
3666                                 continue;
3667                         }
3668                         if (argv) while (*argv) {
3669                                 fdprintf(2, " '%s'", *argv);
3670                                 argv++;
3671                         }
3672                         if (command->redirects)
3673                                 fdprintf(2, " {redir}");
3674                         fdprintf(2, "\n");
3675                         prn++;
3676                 }
3677                 pi = pi->next;
3678                 pin++;
3679         }
3680 }
3681 #endif /* debug_print_tree */
3682
3683 static struct pipe *new_pipe(void)
3684 {
3685         struct pipe *pi;
3686         pi = xzalloc(sizeof(struct pipe));
3687         /*pi->res_word = RES_NONE; - RES_NONE is 0 anyway */
3688         return pi;
3689 }
3690
3691 /* Command (member of a pipe) is complete, or we start a new pipe
3692  * if ctx->command is NULL.
3693  * No errors possible here.
3694  */
3695 static int done_command(struct parse_context *ctx)
3696 {
3697         /* The command is really already in the pipe structure, so
3698          * advance the pipe counter and make a new, null command. */
3699         struct pipe *pi = ctx->pipe;
3700         struct command *command = ctx->command;
3701
3702 #if 0   /* Instead we emit error message at run time */
3703         if (ctx->pending_redirect) {
3704                 /* For example, "cmd >" (no filename to redirect to) */
3705                 syntax_error("invalid redirect");
3706                 ctx->pending_redirect = NULL;
3707         }
3708 #endif
3709
3710         if (command) {
3711                 if (IS_NULL_CMD(command)) {
3712                         debug_printf_parse("done_command: skipping null cmd, num_cmds=%d\n", pi->num_cmds);
3713                         goto clear_and_ret;
3714                 }
3715                 pi->num_cmds++;
3716                 debug_printf_parse("done_command: ++num_cmds=%d\n", pi->num_cmds);
3717                 //debug_print_tree(ctx->list_head, 20);
3718         } else {
3719                 debug_printf_parse("done_command: initializing, num_cmds=%d\n", pi->num_cmds);
3720         }
3721
3722         /* Only real trickiness here is that the uncommitted
3723          * command structure is not counted in pi->num_cmds. */
3724         pi->cmds = xrealloc(pi->cmds, sizeof(*pi->cmds) * (pi->num_cmds+1));
3725         ctx->command = command = &pi->cmds[pi->num_cmds];
3726  clear_and_ret:
3727         memset(command, 0, sizeof(*command));
3728 #if ENABLE_HUSH_LINENO_VAR
3729         command->lineno = G.parse_lineno;
3730         debug_printf_parse("command->lineno = G.parse_lineno (%u)\n", G.parse_lineno);
3731 #endif
3732         return pi->num_cmds; /* used only for 0/nonzero check */
3733 }
3734
3735 static void done_pipe(struct parse_context *ctx, pipe_style type)
3736 {
3737         int not_null;
3738
3739         debug_printf_parse("done_pipe entered, followup %d\n", type);
3740         /* Close previous command */
3741         not_null = done_command(ctx);
3742 #if HAS_KEYWORDS
3743         ctx->pipe->pi_inverted = ctx->ctx_inverted;
3744         ctx->ctx_inverted = 0;
3745         ctx->pipe->res_word = ctx->ctx_res_w;
3746 #endif
3747         if (type == PIPE_BG && ctx->list_head != ctx->pipe) {
3748                 /* Necessary since && and || have precedence over &:
3749                  * "cmd1 && cmd2 &" must spawn both cmds, not only cmd2,
3750                  * in a backgrounded subshell.
3751                  */
3752                 struct pipe *pi;
3753                 struct command *command;
3754
3755                 /* Is this actually this construct, all pipes end with && or ||? */
3756                 pi = ctx->list_head;
3757                 while (pi != ctx->pipe) {
3758                         if (pi->followup != PIPE_AND && pi->followup != PIPE_OR)
3759                                 goto no_conv;
3760                         pi = pi->next;
3761                 }
3762
3763                 debug_printf_parse("BG with more than one pipe, converting to { p1 &&...pN; } &\n");
3764                 pi->followup = PIPE_SEQ; /* close pN _not_ with "&"! */
3765                 pi = xzalloc(sizeof(*pi));
3766                 pi->followup = PIPE_BG;
3767                 pi->num_cmds = 1;
3768                 pi->cmds = xzalloc(sizeof(pi->cmds[0]));
3769                 command = &pi->cmds[0];
3770                 if (CMD_NORMAL != 0) /* "if xzalloc didn't do that already" */
3771                         command->cmd_type = CMD_NORMAL;
3772                 command->group = ctx->list_head;
3773 #if !BB_MMU
3774                 command->group_as_string = xstrndup(
3775                             ctx->as_string.data,
3776                             ctx->as_string.length - 1 /* do not copy last char, "&" */
3777                 );
3778 #endif
3779                 /* Replace all pipes in ctx with one newly created */
3780                 ctx->list_head = ctx->pipe = pi;
3781         } else {
3782  no_conv:
3783                 ctx->pipe->followup = type;
3784         }
3785
3786         /* Without this check, even just <enter> on command line generates
3787          * tree of three NOPs (!). Which is harmless but annoying.
3788          * IOW: it is safe to do it unconditionally. */
3789         if (not_null
3790 #if ENABLE_HUSH_IF
3791          || ctx->ctx_res_w == RES_FI
3792 #endif
3793 #if ENABLE_HUSH_LOOPS
3794          || ctx->ctx_res_w == RES_DONE
3795          || ctx->ctx_res_w == RES_FOR
3796          || ctx->ctx_res_w == RES_IN
3797 #endif
3798 #if ENABLE_HUSH_CASE
3799          || ctx->ctx_res_w == RES_ESAC
3800 #endif
3801         ) {
3802                 struct pipe *new_p;
3803                 debug_printf_parse("done_pipe: adding new pipe: "
3804                                 "not_null:%d ctx->ctx_res_w:%d\n",
3805                                 not_null, ctx->ctx_res_w);
3806                 new_p = new_pipe();
3807                 ctx->pipe->next = new_p;
3808                 ctx->pipe = new_p;
3809                 /* RES_THEN, RES_DO etc are "sticky" -
3810                  * they remain set for pipes inside if/while.
3811                  * This is used to control execution.
3812                  * RES_FOR and RES_IN are NOT sticky (needed to support
3813                  * cases where variable or value happens to match a keyword):
3814                  */
3815 #if ENABLE_HUSH_LOOPS
3816                 if (ctx->ctx_res_w == RES_FOR
3817                  || ctx->ctx_res_w == RES_IN)
3818                         ctx->ctx_res_w = RES_NONE;
3819 #endif
3820 #if ENABLE_HUSH_CASE
3821                 if (ctx->ctx_res_w == RES_MATCH)
3822                         ctx->ctx_res_w = RES_CASE_BODY;
3823                 if (ctx->ctx_res_w == RES_CASE)
3824                         ctx->ctx_res_w = RES_CASE_IN;
3825 #endif
3826                 ctx->command = NULL; /* trick done_command below */
3827                 /* Create the memory for command, roughly:
3828                  * ctx->pipe->cmds = new struct command;
3829                  * ctx->command = &ctx->pipe->cmds[0];
3830                  */
3831                 done_command(ctx);
3832                 //debug_print_tree(ctx->list_head, 10);
3833         }
3834         debug_printf_parse("done_pipe return\n");
3835 }
3836
3837 static void initialize_context(struct parse_context *ctx)
3838 {
3839         memset(ctx, 0, sizeof(*ctx));
3840         if (MAYBE_ASSIGNMENT != 0)
3841                 ctx->is_assignment = MAYBE_ASSIGNMENT;
3842         ctx->pipe = ctx->list_head = new_pipe();
3843         /* Create the memory for command, roughly:
3844          * ctx->pipe->cmds = new struct command;
3845          * ctx->command = &ctx->pipe->cmds[0];
3846          */
3847         done_command(ctx);
3848 }
3849
3850 /* If a reserved word is found and processed, parse context is modified
3851  * and 1 is returned.
3852  */
3853 #if HAS_KEYWORDS
3854 struct reserved_combo {
3855         char literal[6];
3856         unsigned char res;
3857         unsigned char assignment_flag;
3858         int flag;
3859 };
3860 enum {
3861         FLAG_END   = (1 << RES_NONE ),
3862 # if ENABLE_HUSH_IF
3863         FLAG_IF    = (1 << RES_IF   ),
3864         FLAG_THEN  = (1 << RES_THEN ),
3865         FLAG_ELIF  = (1 << RES_ELIF ),
3866         FLAG_ELSE  = (1 << RES_ELSE ),
3867         FLAG_FI    = (1 << RES_FI   ),
3868 # endif
3869 # if ENABLE_HUSH_LOOPS
3870         FLAG_FOR   = (1 << RES_FOR  ),
3871         FLAG_WHILE = (1 << RES_WHILE),
3872         FLAG_UNTIL = (1 << RES_UNTIL),
3873         FLAG_DO    = (1 << RES_DO   ),
3874         FLAG_DONE  = (1 << RES_DONE ),
3875         FLAG_IN    = (1 << RES_IN   ),
3876 # endif
3877 # if ENABLE_HUSH_CASE
3878         FLAG_MATCH = (1 << RES_MATCH),
3879         FLAG_ESAC  = (1 << RES_ESAC ),
3880 # endif
3881         FLAG_START = (1 << RES_XXXX ),
3882 };
3883
3884 static const struct reserved_combo* match_reserved_word(o_string *word)
3885 {
3886         /* Mostly a list of accepted follow-up reserved words.
3887          * FLAG_END means we are done with the sequence, and are ready
3888          * to turn the compound list into a command.
3889          * FLAG_START means the word must start a new compound list.
3890          */
3891         static const struct reserved_combo reserved_list[] = {
3892 # if ENABLE_HUSH_IF
3893                 { "!",     RES_NONE,  NOT_ASSIGNMENT  , 0 },
3894                 { "if",    RES_IF,    MAYBE_ASSIGNMENT, FLAG_THEN | FLAG_START },
3895                 { "then",  RES_THEN,  MAYBE_ASSIGNMENT, FLAG_ELIF | FLAG_ELSE | FLAG_FI },
3896                 { "elif",  RES_ELIF,  MAYBE_ASSIGNMENT, FLAG_THEN },
3897                 { "else",  RES_ELSE,  MAYBE_ASSIGNMENT, FLAG_FI   },
3898                 { "fi",    RES_FI,    NOT_ASSIGNMENT  , FLAG_END  },
3899 # endif
3900 # if ENABLE_HUSH_LOOPS
3901                 { "for",   RES_FOR,   NOT_ASSIGNMENT  , FLAG_IN | FLAG_DO | FLAG_START },
3902                 { "while", RES_WHILE, MAYBE_ASSIGNMENT, FLAG_DO | FLAG_START },
3903                 { "until", RES_UNTIL, MAYBE_ASSIGNMENT, FLAG_DO | FLAG_START },
3904                 { "in",    RES_IN,    NOT_ASSIGNMENT  , FLAG_DO   },
3905                 { "do",    RES_DO,    MAYBE_ASSIGNMENT, FLAG_DONE },
3906                 { "done",  RES_DONE,  NOT_ASSIGNMENT  , FLAG_END  },
3907 # endif
3908 # if ENABLE_HUSH_CASE
3909                 { "case",  RES_CASE,  NOT_ASSIGNMENT  , FLAG_MATCH | FLAG_START },
3910                 { "esac",  RES_ESAC,  NOT_ASSIGNMENT  , FLAG_END  },
3911 # endif
3912         };
3913         const struct reserved_combo *r;
3914
3915         for (r = reserved_list; r < reserved_list + ARRAY_SIZE(reserved_list); r++) {
3916                 if (strcmp(word->data, r->literal) == 0)
3917                         return r;
3918         }
3919         return NULL;
3920 }
3921 /* Return NULL: not a keyword, else: keyword
3922  */
3923 static const struct reserved_combo* reserved_word(struct parse_context *ctx)
3924 {
3925 # if ENABLE_HUSH_CASE
3926         static const struct reserved_combo reserved_match = {
3927                 "",        RES_MATCH, NOT_ASSIGNMENT , FLAG_MATCH | FLAG_ESAC
3928         };
3929 # endif
3930         const struct reserved_combo *r;
3931
3932         if (ctx->word.has_quoted_part)
3933                 return 0;
3934         r = match_reserved_word(&ctx->word);
3935         if (!r)
3936                 return r; /* NULL */
3937
3938         debug_printf("found reserved word %s, res %d\n", r->literal, r->res);
3939 # if ENABLE_HUSH_CASE
3940         if (r->res == RES_IN && ctx->ctx_res_w == RES_CASE_IN) {
3941                 /* "case word IN ..." - IN part starts first MATCH part */
3942                 r = &reserved_match;
3943         } else
3944 # endif
3945         if (r->flag == 0) { /* '!' */
3946                 if (ctx->ctx_inverted) { /* bash doesn't accept '! ! true' */
3947                         syntax_error("! ! command");
3948                         ctx->ctx_res_w = RES_SNTX;
3949                 }
3950                 ctx->ctx_inverted = 1;
3951                 return r;
3952         }
3953         if (r->flag & FLAG_START) {
3954                 struct parse_context *old;
3955
3956                 old = xmemdup(ctx, sizeof(*ctx));
3957                 debug_printf_parse("push stack %p\n", old);
3958                 initialize_context(ctx);
3959                 ctx->stack = old;
3960         } else if (/*ctx->ctx_res_w == RES_NONE ||*/ !(ctx->old_flag & (1 << r->res))) {
3961                 syntax_error_at(ctx->word.data);
3962                 ctx->ctx_res_w = RES_SNTX;
3963                 return r;
3964         } else {
3965                 /* "{...} fi" is ok. "{...} if" is not
3966                  * Example:
3967                  * if { echo foo; } then { echo bar; } fi */
3968                 if (ctx->command->group)
3969                         done_pipe(ctx, PIPE_SEQ);
3970         }
3971
3972         ctx->ctx_res_w = r->res;
3973         ctx->old_flag = r->flag;
3974         ctx->is_assignment = r->assignment_flag;
3975         debug_printf_parse("ctx->is_assignment='%s'\n", assignment_flag[ctx->is_assignment]);
3976
3977         if (ctx->old_flag & FLAG_END) {
3978                 struct parse_context *old;
3979
3980                 done_pipe(ctx, PIPE_SEQ);
3981                 debug_printf_parse("pop stack %p\n", ctx->stack);
3982                 old = ctx->stack;
3983                 old->command->group = ctx->list_head;
3984                 old->command->cmd_type = CMD_NORMAL;
3985 # if !BB_MMU
3986                 /* At this point, the compound command's string is in
3987                  * ctx->as_string... except for the leading keyword!
3988                  * Consider this example: "echo a | if true; then echo a; fi"
3989                  * ctx->as_string will contain "true; then echo a; fi",
3990                  * with "if " remaining in old->as_string!
3991                  */
3992                 {
3993                         char *str;
3994                         int len = old->as_string.length;
3995                         /* Concatenate halves */
3996                         o_addstr(&old->as_string, ctx->as_string.data);
3997                         o_free(&ctx->as_string);
3998                         /* Find where leading keyword starts in first half */
3999                         str = old->as_string.data + len;
4000                         if (str > old->as_string.data)
4001                                 str--; /* skip whitespace after keyword */
4002                         while (str > old->as_string.data && isalpha(str[-1]))
4003                                 str--;
4004                         /* Ugh, we're done with this horrid hack */
4005                         old->command->group_as_string = xstrdup(str);
4006                         debug_printf_parse("pop, remembering as:'%s'\n",
4007                                         old->command->group_as_string);
4008                 }
4009 # endif
4010                 *ctx = *old;   /* physical copy */
4011                 free(old);
4012         }
4013         return r;
4014 }
4015 #endif /* HAS_KEYWORDS */
4016
4017 /* Word is complete, look at it and update parsing context.
4018  * Normal return is 0. Syntax errors return 1.
4019  * Note: on return, word is reset, but not o_free'd!
4020  */
4021 static int done_word(struct parse_context *ctx)
4022 {
4023         struct command *command = ctx->command;
4024
4025         debug_printf_parse("done_word entered: '%s' %p\n", ctx->word.data, command);
4026         if (ctx->word.length == 0 && !ctx->word.has_quoted_part) {
4027                 debug_printf_parse("done_word return 0: true null, ignored\n");
4028                 return 0;
4029         }
4030
4031         if (ctx->pending_redirect) {
4032                 /* We do not glob in e.g. >*.tmp case. bash seems to glob here
4033                  * only if run as "bash", not "sh" */
4034                 /* http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html
4035                  * "2.7 Redirection
4036                  * If the redirection operator is "<<" or "<<-", the word
4037                  * that follows the redirection operator shall be
4038                  * subjected to quote removal; it is unspecified whether
4039                  * any of the other expansions occur. For the other
4040                  * redirection operators, the word that follows the
4041                  * redirection operator shall be subjected to tilde
4042                  * expansion, parameter expansion, command substitution,
4043                  * arithmetic expansion, and quote removal.
4044                  * Pathname expansion shall not be performed
4045                  * on the word by a non-interactive shell; an interactive
4046                  * shell may perform it, but shall do so only when
4047                  * the expansion would result in one word."
4048                  */
4049 //bash does not do parameter/command substitution or arithmetic expansion
4050 //for _heredoc_ redirection word: these constructs look for exact eof marker
4051 // as written:
4052 // <<EOF$t
4053 // <<EOF$((1))
4054 // <<EOF`true`  [this case also makes heredoc "quoted", a-la <<"EOF". Probably bash-4.3.43 bug]
4055
4056                 ctx->pending_redirect->rd_filename = xstrdup(ctx->word.data);
4057                 /* Cater for >\file case:
4058                  * >\a creates file a; >\\a, >"\a", >"\\a" create file \a
4059                  * Same with heredocs:
4060                  * for <<\H delim is H; <<\\H, <<"\H", <<"\\H" - \H
4061                  */
4062                 if (ctx->pending_redirect->rd_type == REDIRECT_HEREDOC) {
4063                         unbackslash(ctx->pending_redirect->rd_filename);
4064                         /* Is it <<"HEREDOC"? */
4065                         if (ctx->word.has_quoted_part) {
4066                                 ctx->pending_redirect->rd_dup |= HEREDOC_QUOTED;
4067                         }
4068                 }
4069                 debug_printf_parse("word stored in rd_filename: '%s'\n", ctx->word.data);
4070                 ctx->pending_redirect = NULL;
4071         } else {
4072 #if HAS_KEYWORDS
4073 # if ENABLE_HUSH_CASE
4074                 if (ctx->ctx_dsemicolon
4075                  && strcmp(ctx->word.data, "esac") != 0 /* not "... pattern) cmd;; esac" */
4076                 ) {
4077                         /* already done when ctx_dsemicolon was set to 1: */
4078                         /* ctx->ctx_res_w = RES_MATCH; */
4079                         ctx->ctx_dsemicolon = 0;
4080                 } else
4081 # endif
4082                 if (!command->argv /* if it's the first word... */
4083 # if ENABLE_HUSH_LOOPS
4084                  && ctx->ctx_res_w != RES_FOR /* ...not after FOR or IN */
4085                  && ctx->ctx_res_w != RES_IN
4086 # endif
4087 # if ENABLE_HUSH_CASE
4088                  && ctx->ctx_res_w != RES_CASE
4089 # endif
4090                 ) {
4091                         const struct reserved_combo *reserved;
4092                         reserved = reserved_word(ctx);
4093                         debug_printf_parse("checking for reserved-ness: %d\n", !!reserved);
4094                         if (reserved) {
4095 # if ENABLE_HUSH_LINENO_VAR
4096 /* Case:
4097  * "while ...; do
4098  *      cmd ..."
4099  * If we don't close the pipe _now_, immediately after "do", lineno logic
4100  * sees "cmd" as starting at "do" - i.e., at the previous line.
4101  */
4102                                 if (0
4103                                  IF_HUSH_IF(|| reserved->res == RES_THEN)
4104                                  IF_HUSH_IF(|| reserved->res == RES_ELIF)
4105                                  IF_HUSH_IF(|| reserved->res == RES_ELSE)
4106                                  IF_HUSH_LOOPS(|| reserved->res == RES_DO)
4107                                 ) {
4108                                         done_pipe(ctx, PIPE_SEQ);
4109                                 }
4110 # endif
4111                                 o_reset_to_empty_unquoted(&ctx->word);
4112                                 debug_printf_parse("done_word return %d\n",
4113                                                 (ctx->ctx_res_w == RES_SNTX));
4114                                 return (ctx->ctx_res_w == RES_SNTX);
4115                         }
4116 # if defined(CMD_SINGLEWORD_NOGLOB)
4117                         if (0
4118 #  if BASH_TEST2
4119                          || strcmp(ctx->word.data, "[[") == 0
4120 #  endif
4121                         /* In bash, local/export/readonly are special, args
4122                          * are assignments and therefore expansion of them
4123                          * should be "one-word" expansion:
4124                          *  $ export i=`echo 'a  b'` # one arg: "i=a  b"
4125                          * compare with:
4126                          *  $ ls i=`echo 'a  b'`     # two args: "i=a" and "b"
4127                          *  ls: cannot access i=a: No such file or directory
4128                          *  ls: cannot access b: No such file or directory
4129                          * Note: bash 3.2.33(1) does this only if export word
4130                          * itself is not quoted:
4131                          *  $ export i=`echo 'aaa  bbb'`; echo "$i"
4132                          *  aaa  bbb
4133                          *  $ "export" i=`echo 'aaa  bbb'`; echo "$i"
4134                          *  aaa
4135                          */
4136                          IF_HUSH_LOCAL(   || strcmp(ctx->word.data, "local") == 0)
4137                          IF_HUSH_EXPORT(  || strcmp(ctx->word.data, "export") == 0)
4138                          IF_HUSH_READONLY(|| strcmp(ctx->word.data, "readonly") == 0)
4139                         ) {
4140                                 command->cmd_type = CMD_SINGLEWORD_NOGLOB;
4141                         }
4142                         /* fall through */
4143 # endif
4144                 }
4145 #endif /* HAS_KEYWORDS */
4146
4147                 if (command->group) {
4148                         /* "{ echo foo; } echo bar" - bad */
4149                         syntax_error_at(ctx->word.data);
4150                         debug_printf_parse("done_word return 1: syntax error, "
4151                                         "groups and arglists don't mix\n");
4152                         return 1;
4153                 }
4154
4155                 /* If this word wasn't an assignment, next ones definitely
4156                  * can't be assignments. Even if they look like ones. */
4157                 if (ctx->is_assignment != DEFINITELY_ASSIGNMENT
4158                  && ctx->is_assignment != WORD_IS_KEYWORD
4159                 ) {
4160                         ctx->is_assignment = NOT_ASSIGNMENT;
4161                 } else {
4162                         if (ctx->is_assignment == DEFINITELY_ASSIGNMENT) {
4163                                 command->assignment_cnt++;
4164                                 debug_printf_parse("++assignment_cnt=%d\n", command->assignment_cnt);
4165                         }
4166                         debug_printf_parse("ctx->is_assignment was:'%s'\n", assignment_flag[ctx->is_assignment]);
4167                         ctx->is_assignment = MAYBE_ASSIGNMENT;
4168                 }
4169                 debug_printf_parse("ctx->is_assignment='%s'\n", assignment_flag[ctx->is_assignment]);
4170                 command->argv = add_string_to_strings(command->argv, xstrdup(ctx->word.data));
4171                 debug_print_strings("word appended to argv", command->argv);
4172         }
4173
4174 #if ENABLE_HUSH_LOOPS
4175         if (ctx->ctx_res_w == RES_FOR) {
4176                 if (ctx->word.has_quoted_part
4177                  || endofname(command->argv[0])[0] != '\0'
4178                 ) {
4179                         /* bash says just "not a valid identifier" */
4180                         syntax_error("not a valid identifier in for");
4181                         return 1;
4182                 }
4183                 /* Force FOR to have just one word (variable name) */
4184                 /* NB: basically, this makes hush see "for v in ..."
4185                  * syntax as if it is "for v; in ...". FOR and IN become
4186                  * two pipe structs in parse tree. */
4187                 done_pipe(ctx, PIPE_SEQ);
4188         }
4189 #endif
4190 #if ENABLE_HUSH_CASE
4191         /* Force CASE to have just one word */
4192         if (ctx->ctx_res_w == RES_CASE) {
4193                 done_pipe(ctx, PIPE_SEQ);
4194         }
4195 #endif
4196
4197         o_reset_to_empty_unquoted(&ctx->word);
4198
4199         debug_printf_parse("done_word return 0\n");
4200         return 0;
4201 }
4202
4203
4204 /* Peek ahead in the input to find out if we have a "&n" construct,
4205  * as in "2>&1", that represents duplicating a file descriptor.
4206  * Return:
4207  * REDIRFD_CLOSE if >&- "close fd" construct is seen,
4208  * REDIRFD_SYNTAX_ERR if syntax error,
4209  * REDIRFD_TO_FILE if no & was seen,
4210  * or the number found.
4211  */
4212 #if BB_MMU
4213 #define parse_redir_right_fd(as_string, input) \
4214         parse_redir_right_fd(input)
4215 #endif
4216 static int parse_redir_right_fd(o_string *as_string, struct in_str *input)
4217 {
4218         int ch, d, ok;
4219
4220         ch = i_peek(input);
4221         if (ch != '&')
4222                 return REDIRFD_TO_FILE;
4223
4224         ch = i_getch(input);  /* get the & */
4225         nommu_addchr(as_string, ch);
4226         ch = i_peek(input);
4227         if (ch == '-') {
4228                 ch = i_getch(input);
4229                 nommu_addchr(as_string, ch);
4230                 return REDIRFD_CLOSE;
4231         }
4232         d = 0;
4233         ok = 0;
4234         while (ch != EOF && isdigit(ch)) {
4235                 d = d*10 + (ch-'0');
4236                 ok = 1;
4237                 ch = i_getch(input);
4238                 nommu_addchr(as_string, ch);
4239                 ch = i_peek(input);
4240         }
4241         if (ok) return d;
4242
4243 //TODO: this is the place to catch ">&file" bashism (redirect both fd 1 and 2)
4244
4245         bb_error_msg("ambiguous redirect");
4246         return REDIRFD_SYNTAX_ERR;
4247 }
4248
4249 /* Return code is 0 normal, 1 if a syntax error is detected
4250  */
4251 static int parse_redirect(struct parse_context *ctx,
4252                 int fd,
4253                 redir_type style,
4254                 struct in_str *input)
4255 {
4256         struct command *command = ctx->command;
4257         struct redir_struct *redir;
4258         struct redir_struct **redirp;
4259         int dup_num;
4260
4261         dup_num = REDIRFD_TO_FILE;
4262         if (style != REDIRECT_HEREDOC) {
4263                 /* Check for a '>&1' type redirect */
4264                 dup_num = parse_redir_right_fd(&ctx->as_string, input);
4265                 if (dup_num == REDIRFD_SYNTAX_ERR)
4266                         return 1;
4267         } else {
4268                 int ch = i_peek_and_eat_bkslash_nl(input);
4269                 dup_num = (ch == '-'); /* HEREDOC_SKIPTABS bit is 1 */
4270                 if (dup_num) { /* <<-... */
4271                         ch = i_getch(input);
4272                         nommu_addchr(&ctx->as_string, ch);
4273                         ch = i_peek(input);
4274                 }
4275         }
4276
4277         if (style == REDIRECT_OVERWRITE && dup_num == REDIRFD_TO_FILE) {
4278                 int ch = i_peek_and_eat_bkslash_nl(input);
4279                 if (ch == '|') {
4280                         /* >|FILE redirect ("clobbering" >).
4281                          * Since we do not support "set -o noclobber" yet,
4282                          * >| and > are the same for now. Just eat |.
4283                          */
4284                         ch = i_getch(input);
4285                         nommu_addchr(&ctx->as_string, ch);
4286                 }
4287         }
4288
4289         /* Create a new redir_struct and append it to the linked list */
4290         redirp = &command->redirects;
4291         while ((redir = *redirp) != NULL) {
4292                 redirp = &(redir->next);
4293         }
4294         *redirp = redir = xzalloc(sizeof(*redir));
4295         /* redir->next = NULL; */
4296         /* redir->rd_filename = NULL; */
4297         redir->rd_type = style;
4298         redir->rd_fd = (fd == -1) ? redir_table[style].default_fd : fd;
4299
4300         debug_printf_parse("redirect type %d %s\n", redir->rd_fd,
4301                                 redir_table[style].descrip);
4302
4303         redir->rd_dup = dup_num;
4304         if (style != REDIRECT_HEREDOC && dup_num != REDIRFD_TO_FILE) {
4305                 /* Erik had a check here that the file descriptor in question
4306                  * is legit; I postpone that to "run time"
4307                  * A "-" representation of "close me" shows up as a -3 here */
4308                 debug_printf_parse("duplicating redirect '%d>&%d'\n",
4309                                 redir->rd_fd, redir->rd_dup);
4310         } else {
4311 #if 0           /* Instead we emit error message at run time */
4312                 if (ctx->pending_redirect) {
4313                         /* For example, "cmd > <file" */
4314                         syntax_error("invalid redirect");
4315                 }
4316 #endif
4317                 /* Set ctx->pending_redirect, so we know what to do at the
4318                  * end of the next parsed word. */
4319                 ctx->pending_redirect = redir;
4320         }
4321         return 0;
4322 }
4323
4324 /* If a redirect is immediately preceded by a number, that number is
4325  * supposed to tell which file descriptor to redirect.  This routine
4326  * looks for such preceding numbers.  In an ideal world this routine
4327  * needs to handle all the following classes of redirects...
4328  *     echo 2>foo     # redirects fd  2 to file "foo", nothing passed to echo
4329  *     echo 49>foo    # redirects fd 49 to file "foo", nothing passed to echo
4330  *     echo -2>foo    # redirects fd  1 to file "foo",    "-2" passed to echo
4331  *     echo 49x>foo   # redirects fd  1 to file "foo",   "49x" passed to echo
4332  *
4333  * http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html
4334  * "2.7 Redirection
4335  * ... If n is quoted, the number shall not be recognized as part of
4336  * the redirection expression. For example:
4337  * echo \2>a
4338  * writes the character 2 into file a"
4339  * We are getting it right by setting ->has_quoted_part on any \<char>
4340  *
4341  * A -1 return means no valid number was found,
4342  * the caller should use the appropriate default for this redirection.
4343  */
4344 static int redirect_opt_num(o_string *o)
4345 {
4346         int num;
4347
4348         if (o->data == NULL)
4349                 return -1;
4350         num = bb_strtou(o->data, NULL, 10);
4351         if (errno || num < 0)
4352                 return -1;
4353         o_reset_to_empty_unquoted(o);
4354         return num;
4355 }
4356
4357 #if BB_MMU
4358 #define fetch_till_str(as_string, input, word, skip_tabs) \
4359         fetch_till_str(input, word, skip_tabs)
4360 #endif
4361 static char *fetch_till_str(o_string *as_string,
4362                 struct in_str *input,
4363                 const char *word,
4364                 int heredoc_flags)
4365 {
4366         o_string heredoc = NULL_O_STRING;
4367         unsigned past_EOL;
4368         int prev = 0; /* not \ */
4369         int ch;
4370
4371         /* Starting with "" is necessary for this case:
4372          * cat <<EOF
4373          *
4374          * xxx
4375          * EOF
4376          */
4377         heredoc.data = xzalloc(1); /* start as "", not as NULL */
4378
4379         goto jump_in;
4380
4381         while (1) {
4382                 ch = i_getch(input);
4383                 if (ch != EOF)
4384                         nommu_addchr(as_string, ch);
4385                 if (ch == '\n' || ch == EOF) {
4386  check_heredoc_end:
4387                         if ((heredoc_flags & HEREDOC_QUOTED) || prev != '\\') {
4388                                 /* End-of-line, and not a line continuation */
4389                                 if (strcmp(heredoc.data + past_EOL, word) == 0) {
4390                                         heredoc.data[past_EOL] = '\0';
4391                                         debug_printf_heredoc("parsed '%s' heredoc '%s'\n", word, heredoc.data);
4392                                         return heredoc.data;
4393                                 }
4394                                 if (ch == '\n') {
4395                                         /* This is a new line.
4396                                          * Remember position and backslash-escaping status.
4397                                          */
4398                                         o_addchr(&heredoc, ch);
4399                                         prev = ch;
4400  jump_in:
4401                                         past_EOL = heredoc.length;
4402                                         /* Get 1st char of next line, possibly skipping leading tabs */
4403                                         do {
4404                                                 ch = i_getch(input);
4405                                                 if (ch != EOF)
4406                                                         nommu_addchr(as_string, ch);
4407                                         } while ((heredoc_flags & HEREDOC_SKIPTABS) && ch == '\t');
4408                                         /* If this immediately ended the line,
4409                                          * go back to end-of-line checks.
4410                                          */
4411                                         if (ch == '\n')
4412                                                 goto check_heredoc_end;
4413                                 }
4414                         } else {
4415                                 /* Backslash-line continuation in an unquoted
4416                                  * heredoc. This does not need special handling
4417                                  * for heredoc body (unquoted heredocs are
4418                                  * expanded on "execution" and that would take
4419                                  * care of this case too), but not the case
4420                                  * of line continuation *in terminator*:
4421                                  *  cat <<EOF
4422                                  *  Ok1
4423                                  *  EO\
4424                                  *  F
4425                                  */
4426                                 heredoc.data[--heredoc.length] = '\0';
4427                                 prev = 0; /* not '\' */
4428                                 continue;
4429                         }
4430                 }
4431                 if (ch == EOF) {
4432                         o_free(&heredoc);
4433                         return NULL; /* error */
4434                 }
4435                 o_addchr(&heredoc, ch);
4436                 nommu_addchr(as_string, ch);
4437                 if (prev == '\\' && ch == '\\')
4438                         /* Correctly handle foo\\<eol> (not a line cont.) */
4439                         prev = 0; /* not '\' */
4440                 else
4441                         prev = ch;
4442         }
4443 }
4444
4445 /* Look at entire parse tree for not-yet-loaded REDIRECT_HEREDOCs
4446  * and load them all. There should be exactly heredoc_cnt of them.
4447  */
4448 #if BB_MMU
4449 #define fetch_heredocs(as_string, pi, heredoc_cnt, input) \
4450         fetch_heredocs(pi, heredoc_cnt, input)
4451 #endif
4452 static int fetch_heredocs(o_string *as_string, struct pipe *pi, int heredoc_cnt, struct in_str *input)
4453 {
4454         while (pi && heredoc_cnt) {
4455                 int i;
4456                 struct command *cmd = pi->cmds;
4457
4458                 debug_printf_heredoc("fetch_heredocs: num_cmds:%d cmd argv0:'%s'\n",
4459                                 pi->num_cmds,
4460                                 cmd->argv ? cmd->argv[0] : "NONE"
4461                 );
4462                 for (i = 0; i < pi->num_cmds; i++) {
4463                         struct redir_struct *redir = cmd->redirects;
4464
4465                         debug_printf_heredoc("fetch_heredocs: %d cmd argv0:'%s'\n",
4466                                         i, cmd->argv ? cmd->argv[0] : "NONE");
4467                         while (redir) {
4468                                 if (redir->rd_type == REDIRECT_HEREDOC) {
4469                                         char *p;
4470
4471                                         redir->rd_type = REDIRECT_HEREDOC2;
4472                                         /* redir->rd_dup is (ab)used to indicate <<- */
4473                                         p = fetch_till_str(as_string, input,
4474                                                         redir->rd_filename, redir->rd_dup);
4475                                         if (!p) {
4476                                                 syntax_error("unexpected EOF in here document");
4477                                                 return -1;
4478                                         }
4479                                         free(redir->rd_filename);
4480                                         redir->rd_filename = p;
4481                                         heredoc_cnt--;
4482                                 }
4483                                 redir = redir->next;
4484                         }
4485                         if (cmd->group) {
4486                                 //bb_error_msg("%s:%u heredoc_cnt:%d", __func__, __LINE__, heredoc_cnt);
4487                                 heredoc_cnt = fetch_heredocs(as_string, cmd->group, heredoc_cnt, input);
4488                                 //bb_error_msg("%s:%u heredoc_cnt:%d", __func__, __LINE__, heredoc_cnt);
4489                                 if (heredoc_cnt < 0)
4490                                         return heredoc_cnt; /* error */
4491                         }
4492                         cmd++;
4493                 }
4494                 pi = pi->next;
4495         }
4496         return heredoc_cnt;
4497 }
4498
4499
4500 static int run_list(struct pipe *pi);
4501 #if BB_MMU
4502 #define parse_stream(pstring, heredoc_cnt_ptr, input, end_trigger) \
4503         parse_stream(heredoc_cnt_ptr, input, end_trigger)
4504 #endif
4505 static struct pipe *parse_stream(char **pstring,
4506                 int *heredoc_cnt_ptr,
4507                 struct in_str *input,
4508                 int end_trigger);
4509
4510 /* Returns number of heredocs not yet consumed,
4511  * or -1 on error.
4512  */
4513 static int parse_group(struct parse_context *ctx,
4514                 struct in_str *input, int ch)
4515 {
4516         /* ctx->word contains characters seen prior to ( or {.
4517          * Typically it's empty, but for function defs,
4518          * it contains function name (without '()'). */
4519 #if BB_MMU
4520 # define as_string NULL
4521 #else
4522         char *as_string = NULL;
4523 #endif
4524         struct pipe *pipe_list;
4525         int heredoc_cnt = 0;
4526         int endch;
4527         struct command *command = ctx->command;
4528
4529         debug_printf_parse("parse_group entered\n");
4530 #if ENABLE_HUSH_FUNCTIONS
4531         if (ch == '(' && !ctx->word.has_quoted_part) {
4532                 if (ctx->word.length)
4533                         if (done_word(ctx))
4534                                 return -1;
4535                 if (!command->argv)
4536                         goto skip; /* (... */
4537                 if (command->argv[1]) { /* word word ... (... */
4538                         syntax_error_unexpected_ch('(');
4539                         return -1;
4540                 }
4541                 /* it is "word(..." or "word (..." */
4542                 do
4543                         ch = i_getch(input);
4544                 while (ch == ' ' || ch == '\t');
4545                 if (ch != ')') {
4546                         syntax_error_unexpected_ch(ch);
4547                         return -1;
4548                 }
4549                 nommu_addchr(&ctx->as_string, ch);
4550                 do
4551                         ch = i_getch(input);
4552                 while (ch == ' ' || ch == '\t' || ch == '\n');
4553                 if (ch != '{' && ch != '(') {
4554                         syntax_error_unexpected_ch(ch);
4555                         return -1;
4556                 }
4557                 nommu_addchr(&ctx->as_string, ch);
4558                 command->cmd_type = CMD_FUNCDEF;
4559                 goto skip;
4560         }
4561 #endif
4562
4563 #if 0 /* Prevented by caller */
4564         if (command->argv /* word [word]{... */
4565          || ctx->word.length /* word{... */
4566          || ctx->word.has_quoted_part /* ""{... */
4567         ) {
4568                 syntax_error(NULL);
4569                 debug_printf_parse("parse_group return -1: "
4570                         "syntax error, groups and arglists don't mix\n");
4571                 return -1;
4572         }
4573 #endif
4574
4575  IF_HUSH_FUNCTIONS(skip:)
4576
4577         endch = '}';
4578         if (ch == '(') {
4579                 endch = ')';
4580                 IF_HUSH_FUNCTIONS(if (command->cmd_type != CMD_FUNCDEF))
4581                         command->cmd_type = CMD_SUBSHELL;
4582         } else {
4583                 /* bash does not allow "{echo...", requires whitespace */
4584                 ch = i_peek(input);
4585                 if (ch != ' ' && ch != '\t' && ch != '\n'
4586                  && ch != '('   /* but "{(..." is allowed (without whitespace) */
4587                 ) {
4588                         syntax_error_unexpected_ch(ch);
4589                         return -1;
4590                 }
4591                 if (ch != '(') {
4592                         ch = i_getch(input);
4593                         nommu_addchr(&ctx->as_string, ch);
4594                 }
4595         }
4596
4597         debug_printf_heredoc("calling parse_stream, heredoc_cnt:%d\n", heredoc_cnt);
4598         pipe_list = parse_stream(&as_string, &heredoc_cnt, input, endch);
4599         debug_printf_heredoc("parse_stream returned: heredoc_cnt:%d\n", heredoc_cnt);
4600 #if !BB_MMU
4601         if (as_string)
4602                 o_addstr(&ctx->as_string, as_string);
4603 #endif
4604
4605         /* empty ()/{} or parse error? */
4606         if (!pipe_list || pipe_list == ERR_PTR) {
4607                 /* parse_stream already emitted error msg */
4608                 if (!BB_MMU)
4609                         free(as_string);
4610                 debug_printf_parse("parse_group return -1: "
4611                         "parse_stream returned %p\n", pipe_list);
4612                 return -1;
4613         }
4614 #if !BB_MMU
4615         as_string[strlen(as_string) - 1] = '\0'; /* plink ')' or '}' */
4616         command->group_as_string = as_string;
4617         debug_printf_parse("end of group, remembering as:'%s'\n",
4618                         command->group_as_string);
4619 #endif
4620
4621 #if ENABLE_HUSH_FUNCTIONS
4622         /* Convert "f() (cmds)" to "f() {(cmds)}" */
4623         if (command->cmd_type == CMD_FUNCDEF && endch == ')') {
4624                 struct command *cmd2;
4625
4626                 cmd2 = xzalloc(sizeof(*cmd2));
4627                 cmd2->cmd_type = CMD_SUBSHELL;
4628                 cmd2->group = pipe_list;
4629 # if !BB_MMU
4630 //UNTESTED!
4631                 cmd2->group_as_string = command->group_as_string;
4632                 command->group_as_string = xasprintf("(%s)", command->group_as_string);
4633 # endif
4634
4635                 pipe_list = new_pipe();
4636                 pipe_list->cmds = cmd2;
4637                 pipe_list->num_cmds = 1;
4638         }
4639 #endif
4640
4641         command->group = pipe_list;
4642
4643         debug_printf_parse("parse_group return %d\n", heredoc_cnt);
4644         return heredoc_cnt;
4645         /* command remains "open", available for possible redirects */
4646 #undef as_string
4647 }
4648
4649 #if ENABLE_HUSH_TICK || ENABLE_FEATURE_SH_MATH || ENABLE_HUSH_DOLLAR_OPS
4650 /* Subroutines for copying $(...) and `...` things */
4651 /* '...' */
4652 static int add_till_single_quote(o_string *dest, struct in_str *input)
4653 {
4654         while (1) {
4655                 int ch = i_getch(input);
4656                 if (ch == EOF) {
4657                         syntax_error_unterm_ch('\'');
4658                         return 0;
4659                 }
4660                 if (ch == '\'')
4661                         return 1;
4662                 o_addchr(dest, ch);
4663         }
4664 }
4665 static int add_till_single_quote_dquoted(o_string *dest, struct in_str *input)
4666 {
4667         while (1) {
4668                 int ch = i_getch(input);
4669                 if (ch == EOF) {
4670                         syntax_error_unterm_ch('\'');
4671                         return 0;
4672                 }
4673                 if (ch == '\'')
4674                         return 1;
4675                 o_addqchr(dest, ch);
4676         }
4677 }
4678 /* "...\"...`..`...." - do we need to handle "...$(..)..." too? */
4679 static int add_till_backquote(o_string *dest, struct in_str *input, int in_dquote);
4680 static int add_till_double_quote(o_string *dest, struct in_str *input)
4681 {
4682         while (1) {
4683                 int ch = i_getch(input);
4684                 if (ch == EOF) {
4685                         syntax_error_unterm_ch('"');
4686                         return 0;
4687                 }
4688                 if (ch == '"')
4689                         return 1;
4690                 if (ch == '\\') {  /* \x. Copy both chars. */
4691                         o_addchr(dest, ch);
4692                         ch = i_getch(input);
4693                 }
4694                 o_addchr(dest, ch);
4695                 if (ch == '`') {
4696                         if (!add_till_backquote(dest, input, /*in_dquote:*/ 1))
4697                                 return 0;
4698                         o_addchr(dest, ch);
4699                         continue;
4700                 }
4701                 //if (ch == '$') ...
4702         }
4703 }
4704 /* Process `cmd` - copy contents until "`" is seen. Complicated by
4705  * \` quoting.
4706  * "Within the backquoted style of command substitution, backslash
4707  * shall retain its literal meaning, except when followed by: '$', '`', or '\'.
4708  * The search for the matching backquote shall be satisfied by the first
4709  * backquote found without a preceding backslash; during this search,
4710  * if a non-escaped backquote is encountered within a shell comment,
4711  * a here-document, an embedded command substitution of the $(command)
4712  * form, or a quoted string, undefined results occur. A single-quoted
4713  * or double-quoted string that begins, but does not end, within the
4714  * "`...`" sequence produces undefined results."
4715  * Example                               Output
4716  * echo `echo '\'TEST\`echo ZZ\`BEST`    \TESTZZBEST
4717  */
4718 static int add_till_backquote(o_string *dest, struct in_str *input, int in_dquote)
4719 {
4720         while (1) {
4721                 int ch = i_getch(input);
4722                 if (ch == '`')
4723                         return 1;
4724                 if (ch == '\\') {
4725                         /* \x. Copy both unless it is \`, \$, \\ and maybe \" */
4726                         ch = i_getch(input);
4727                         if (ch != '`'
4728                          && ch != '$'
4729                          && ch != '\\'
4730                          && (!in_dquote || ch != '"')
4731                         ) {
4732                                 o_addchr(dest, '\\');
4733                         }
4734                 }
4735                 if (ch == EOF) {
4736                         syntax_error_unterm_ch('`');
4737                         return 0;
4738                 }
4739                 o_addchr(dest, ch);
4740         }
4741 }
4742 /* Process $(cmd) - copy contents until ")" is seen. Complicated by
4743  * quoting and nested ()s.
4744  * "With the $(command) style of command substitution, all characters
4745  * following the open parenthesis to the matching closing parenthesis
4746  * constitute the command. Any valid shell script can be used for command,
4747  * except a script consisting solely of redirections which produces
4748  * unspecified results."
4749  * Example                              Output
4750  * echo $(echo '(TEST)' BEST)           (TEST) BEST
4751  * echo $(echo 'TEST)' BEST)            TEST) BEST
4752  * echo $(echo \(\(TEST\) BEST)         ((TEST) BEST
4753  *
4754  * Also adapted to eat ${var%...} and $((...)) constructs, since ... part
4755  * can contain arbitrary constructs, just like $(cmd).
4756  * In bash compat mode, it needs to also be able to stop on ':' or '/'
4757  * for ${var:N[:M]} and ${var/P[/R]} parsing.
4758  */
4759 #define DOUBLE_CLOSE_CHAR_FLAG 0x80
4760 static int add_till_closing_bracket(o_string *dest, struct in_str *input, unsigned end_ch)
4761 {
4762         int ch;
4763         char dbl = end_ch & DOUBLE_CLOSE_CHAR_FLAG;
4764 # if BASH_SUBSTR || BASH_PATTERN_SUBST
4765         char end_char2 = end_ch >> 8;
4766 # endif
4767         end_ch &= (DOUBLE_CLOSE_CHAR_FLAG - 1);
4768
4769 #if ENABLE_HUSH_INTERACTIVE
4770         G.promptmode = 1; /* PS2 */
4771 #endif
4772         debug_printf_prompt("%s promptmode=%d\n", __func__, G.promptmode);
4773
4774         while (1) {
4775                 ch = i_getch(input);
4776                 if (ch == EOF) {
4777                         syntax_error_unterm_ch(end_ch);
4778                         return 0;
4779                 }
4780                 if (ch == end_ch
4781 # if BASH_SUBSTR || BASH_PATTERN_SUBST
4782                  || ch == end_char2
4783 # endif
4784                 ) {
4785                         if (!dbl)
4786                                 break;
4787                         /* we look for closing )) of $((EXPR)) */
4788                         if (i_peek_and_eat_bkslash_nl(input) == end_ch) {
4789                                 i_getch(input); /* eat second ')' */
4790                                 break;
4791                         }
4792                 }
4793                 o_addchr(dest, ch);
4794                 //bb_error_msg("%s:o_addchr('%c')", __func__, ch);
4795                 if (ch == '(' || ch == '{') {
4796                         ch = (ch == '(' ? ')' : '}');
4797                         if (!add_till_closing_bracket(dest, input, ch))
4798                                 return 0;
4799                         o_addchr(dest, ch);
4800                         continue;
4801                 }
4802                 if (ch == '\'') {
4803                         if (!add_till_single_quote(dest, input))
4804                                 return 0;
4805                         o_addchr(dest, ch);
4806                         continue;
4807                 }
4808                 if (ch == '"') {
4809                         if (!add_till_double_quote(dest, input))
4810                                 return 0;
4811                         o_addchr(dest, ch);
4812                         continue;
4813                 }
4814                 if (ch == '`') {
4815                         if (!add_till_backquote(dest, input, /*in_dquote:*/ 0))
4816                                 return 0;
4817                         o_addchr(dest, ch);
4818                         continue;
4819                 }
4820                 if (ch == '\\') {
4821                         /* \x. Copy verbatim. Important for  \(, \) */
4822                         ch = i_getch(input);
4823                         if (ch == EOF) {
4824                                 syntax_error_unterm_ch(end_ch);
4825                                 return 0;
4826                         }
4827 #if 0
4828                         if (ch == '\n') {
4829                                 /* "backslash+newline", ignore both */
4830                                 o_delchr(dest); /* undo insertion of '\' */
4831                                 continue;
4832                         }
4833 #endif
4834                         o_addchr(dest, ch);
4835                         //bb_error_msg("%s:o_addchr('%c') after '\\'", __func__, ch);
4836                         continue;
4837                 }
4838         }
4839         debug_printf_parse("%s return '%s' ch:'%c'\n", __func__, dest->data, ch);
4840         return ch;
4841 }
4842 #endif /* ENABLE_HUSH_TICK || ENABLE_FEATURE_SH_MATH || ENABLE_HUSH_DOLLAR_OPS */
4843
4844 /* Return code: 0 for OK, 1 for syntax error */
4845 #if BB_MMU
4846 #define parse_dollar(as_string, dest, input, quote_mask) \
4847         parse_dollar(dest, input, quote_mask)
4848 #define as_string NULL
4849 #endif
4850 static int parse_dollar(o_string *as_string,
4851                 o_string *dest,
4852                 struct in_str *input, unsigned char quote_mask)
4853 {
4854         int ch = i_peek_and_eat_bkslash_nl(input);  /* first character after the $ */
4855
4856         debug_printf_parse("parse_dollar entered: ch='%c'\n", ch);
4857         if (isalpha(ch)) {
4858  make_var:
4859                 ch = i_getch(input);
4860                 nommu_addchr(as_string, ch);
4861  /*make_var1:*/
4862                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
4863                 while (1) {
4864                         debug_printf_parse(": '%c'\n", ch);
4865                         o_addchr(dest, ch | quote_mask);
4866                         quote_mask = 0;
4867                         ch = i_peek_and_eat_bkslash_nl(input);
4868                         if (!isalnum(ch) && ch != '_') {
4869                                 /* End of variable name reached */
4870                                 break;
4871                         }
4872                         ch = i_getch(input);
4873                         nommu_addchr(as_string, ch);
4874                 }
4875                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
4876         } else if (isdigit(ch)) {
4877  make_one_char_var:
4878                 ch = i_getch(input);
4879                 nommu_addchr(as_string, ch);
4880                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
4881                 debug_printf_parse(": '%c'\n", ch);
4882                 o_addchr(dest, ch | quote_mask);
4883                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
4884         } else switch (ch) {
4885         case '$': /* pid */
4886         case '!': /* last bg pid */
4887         case '?': /* last exit code */
4888         case '#': /* number of args */
4889         case '*': /* args */
4890         case '@': /* args */
4891                 goto make_one_char_var;
4892         case '{': {
4893                 char len_single_ch;
4894
4895                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
4896
4897                 ch = i_getch(input); /* eat '{' */
4898                 nommu_addchr(as_string, ch);
4899
4900                 ch = i_getch_and_eat_bkslash_nl(input); /* first char after '{' */
4901                 /* It should be ${?}, or ${#var},
4902                  * or even ${?+subst} - operator acting on a special variable,
4903                  * or the beginning of variable name.
4904                  */
4905                 if (ch == EOF
4906                  || (!strchr(_SPECIAL_VARS_STR, ch) && !isalnum(ch)) /* not one of those */
4907                 ) {
4908  bad_dollar_syntax:
4909                         syntax_error_unterm_str("${name}");
4910                         debug_printf_parse("parse_dollar return 0: unterminated ${name}\n");
4911                         return 0;
4912                 }
4913                 nommu_addchr(as_string, ch);
4914                 len_single_ch = ch;
4915                 ch |= quote_mask;
4916
4917                 /* It's possible to just call add_till_closing_bracket() at this point.
4918                  * However, this regresses some of our testsuite cases
4919                  * which check invalid constructs like ${%}.
4920                  * Oh well... let's check that the var name part is fine... */
4921
4922                 while (1) {
4923                         unsigned pos;
4924
4925                         o_addchr(dest, ch);
4926                         debug_printf_parse(": '%c'\n", ch);
4927
4928                         ch = i_getch(input);
4929                         nommu_addchr(as_string, ch);
4930                         if (ch == '}')
4931                                 break;
4932
4933                         if (!isalnum(ch) && ch != '_') {
4934                                 unsigned end_ch;
4935                                 unsigned char last_ch;
4936                                 /* handle parameter expansions
4937                                  * http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_06_02
4938                                  */
4939                                 if (!strchr(VAR_SUBST_OPS, ch)) { /* ${var<bad_char>... */
4940                                         if (len_single_ch != '#'
4941                                         /*|| !strchr(SPECIAL_VARS_STR, ch) - disallow errors like ${#+} ? */
4942                                          || i_peek(input) != '}'
4943                                         ) {
4944                                                 goto bad_dollar_syntax;
4945                                         }
4946                                         /* else: it's "length of C" ${#C} op,
4947                                          * where C is a single char
4948                                          * special var name, e.g. ${#!}.
4949                                          */
4950                                 }
4951                                 /* Eat everything until closing '}' (or ':') */
4952                                 end_ch = '}';
4953                                 if (BASH_SUBSTR
4954                                  && ch == ':'
4955                                  && !strchr(MINUS_PLUS_EQUAL_QUESTION, i_peek(input))
4956                                 ) {
4957                                         /* It's ${var:N[:M]} thing */
4958                                         end_ch = '}' * 0x100 + ':';
4959                                 }
4960                                 if (BASH_PATTERN_SUBST
4961                                  && ch == '/'
4962                                 ) {
4963                                         /* It's ${var/[/]pattern[/repl]} thing */
4964                                         if (i_peek(input) == '/') { /* ${var//pattern[/repl]}? */
4965                                                 i_getch(input);
4966                                                 nommu_addchr(as_string, '/');
4967                                                 ch = '\\';
4968                                         }
4969                                         end_ch = '}' * 0x100 + '/';
4970                                 }
4971                                 o_addchr(dest, ch);
4972                                 /* The pattern can't be empty.
4973                                  * IOW: if the first char after "${v//" is a slash,
4974                                  * it does not terminate the pattern - it's the first char of the pattern:
4975                                  *  v=/dev/ram; echo ${v////-}  prints -dev-ram (pattern is "/")
4976                                  *  v=/dev/ram; echo ${v///r/-} prints /dev-am  (pattern is "/r")
4977                                  */
4978                                 if (i_peek(input) == '/') {
4979                                         o_addchr(dest, i_getch(input));
4980                                 }
4981  again:
4982                                 if (!BB_MMU)
4983                                         pos = dest->length;
4984 #if ENABLE_HUSH_DOLLAR_OPS
4985                                 last_ch = add_till_closing_bracket(dest, input, end_ch);
4986                                 if (last_ch == 0) /* error? */
4987                                         return 0;
4988 #else
4989 #error Simple code to only allow ${var} is not implemented
4990 #endif
4991                                 if (as_string) {
4992                                         o_addstr(as_string, dest->data + pos);
4993                                         o_addchr(as_string, last_ch);
4994                                 }
4995
4996                                 if ((BASH_SUBSTR || BASH_PATTERN_SUBST)
4997                                          && (end_ch & 0xff00)
4998                                 ) {
4999                                         /* close the first block: */
5000                                         o_addchr(dest, SPECIAL_VAR_SYMBOL);
5001                                         /* while parsing N from ${var:N[:M]}
5002                                          * or pattern from ${var/[/]pattern[/repl]} */
5003                                         if ((end_ch & 0xff) == last_ch) {
5004                                                 /* got ':' or '/'- parse the rest */
5005                                                 end_ch = '}';
5006                                                 goto again;
5007                                         }
5008                                         /* got '}' */
5009                                         if (BASH_SUBSTR && end_ch == '}' * 0x100 + ':') {
5010                                                 /* it's ${var:N} - emulate :999999999 */
5011                                                 o_addstr(dest, "999999999");
5012                                         } /* else: it's ${var/[/]pattern} */
5013                                 }
5014                                 break;
5015                         }
5016                         len_single_ch = 0; /* it can't be ${#C} op */
5017                 }
5018                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
5019                 break;
5020         }
5021 #if ENABLE_FEATURE_SH_MATH || ENABLE_HUSH_TICK
5022         case '(': {
5023                 unsigned pos;
5024
5025                 ch = i_getch(input);
5026                 nommu_addchr(as_string, ch);
5027 # if ENABLE_FEATURE_SH_MATH
5028                 if (i_peek_and_eat_bkslash_nl(input) == '(') {
5029                         ch = i_getch(input);
5030                         nommu_addchr(as_string, ch);
5031                         o_addchr(dest, SPECIAL_VAR_SYMBOL);
5032                         o_addchr(dest, /*quote_mask |*/ '+');
5033                         if (!BB_MMU)
5034                                 pos = dest->length;
5035                         if (!add_till_closing_bracket(dest, input, ')' | DOUBLE_CLOSE_CHAR_FLAG))
5036                                 return 0; /* error */
5037                         if (as_string) {
5038                                 o_addstr(as_string, dest->data + pos);
5039                                 o_addchr(as_string, ')');
5040                                 o_addchr(as_string, ')');
5041                         }
5042                         o_addchr(dest, SPECIAL_VAR_SYMBOL);
5043                         break;
5044                 }
5045 # endif
5046 # if ENABLE_HUSH_TICK
5047                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
5048                 o_addchr(dest, quote_mask | '`');
5049                 if (!BB_MMU)
5050                         pos = dest->length;
5051                 if (!add_till_closing_bracket(dest, input, ')'))
5052                         return 0; /* error */
5053                 if (as_string) {
5054                         o_addstr(as_string, dest->data + pos);
5055                         o_addchr(as_string, ')');
5056                 }
5057                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
5058 # endif
5059                 break;
5060         }
5061 #endif
5062         case '_':
5063                 goto make_var;
5064 #if 0
5065         /* TODO: $_ and $-: */
5066         /* $_ Shell or shell script name; or last argument of last command
5067          * (if last command wasn't a pipe; if it was, bash sets $_ to "");
5068          * but in command's env, set to full pathname used to invoke it */
5069         /* $- Option flags set by set builtin or shell options (-i etc) */
5070                 ch = i_getch(input);
5071                 nommu_addchr(as_string, ch);
5072                 ch = i_peek_and_eat_bkslash_nl(input);
5073                 if (isalnum(ch)) { /* it's $_name or $_123 */
5074                         ch = '_';
5075                         goto make_var1;
5076                 }
5077                 /* else: it's $_ */
5078 #endif
5079         default:
5080                 o_addQchr(dest, '$');
5081         }
5082         debug_printf_parse("parse_dollar return 1 (ok)\n");
5083         return 1;
5084 #undef as_string
5085 }
5086
5087 #if BB_MMU
5088 #define encode_string(as_string, dest, input, dquote_end) \
5089         encode_string(dest, input, dquote_end)
5090 #define as_string NULL
5091 #endif
5092 static int encode_string(o_string *as_string,
5093                 o_string *dest,
5094                 struct in_str *input,
5095                 int dquote_end)
5096 {
5097         int ch;
5098         int next;
5099
5100  again:
5101         ch = i_getch(input);
5102         if (ch != EOF)
5103                 nommu_addchr(as_string, ch);
5104         if (ch == dquote_end) { /* may be only '"' or EOF */
5105                 debug_printf_parse("encode_string return 1 (ok)\n");
5106                 return 1;
5107         }
5108         /* note: can't move it above ch == dquote_end check! */
5109         if (ch == EOF) {
5110                 syntax_error_unterm_ch('"');
5111                 return 0; /* error */
5112         }
5113         next = '\0';
5114         if (ch != '\n') {
5115                 next = i_peek(input);
5116         }
5117         debug_printf_parse("\" ch=%c (%d) escape=%d\n",
5118                         ch, ch, !!(dest->o_expflags & EXP_FLAG_ESC_GLOB_CHARS));
5119         if (ch == '\\') {
5120                 if (next == EOF) {
5121                         /* Testcase: in interactive shell a file with
5122                          *  echo "unterminated string\<eof>
5123                          * is sourced.
5124                          */
5125                         syntax_error_unterm_ch('"');
5126                         return 0; /* error */
5127                 }
5128                 /* bash:
5129                  * "The backslash retains its special meaning [in "..."]
5130                  * only when followed by one of the following characters:
5131                  * $, `, ", \, or <newline>.  A double quote may be quoted
5132                  * within double quotes by preceding it with a backslash."
5133                  * NB: in (unquoted) heredoc, above does not apply to ",
5134                  * therefore we check for it by "next == dquote_end" cond.
5135                  */
5136                 if (next == dquote_end || strchr("$`\\\n", next)) {
5137                         ch = i_getch(input); /* eat next */
5138                         if (ch == '\n')
5139                                 goto again; /* skip \<newline> */
5140                 } /* else: ch remains == '\\', and we double it below: */
5141                 o_addqchr(dest, ch); /* \c if c is a glob char, else just c */
5142                 nommu_addchr(as_string, ch);
5143                 goto again;
5144         }
5145         if (ch == '$') {
5146                 if (!parse_dollar(as_string, dest, input, /*quote_mask:*/ 0x80)) {
5147                         debug_printf_parse("encode_string return 0: "
5148                                         "parse_dollar returned 0 (error)\n");
5149                         return 0;
5150                 }
5151                 goto again;
5152         }
5153 #if ENABLE_HUSH_TICK
5154         if (ch == '`') {
5155                 //unsigned pos = dest->length;
5156                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
5157                 o_addchr(dest, 0x80 | '`');
5158                 if (!add_till_backquote(dest, input, /*in_dquote:*/ dquote_end == '"'))
5159                         return 0; /* error */
5160                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
5161                 //debug_printf_subst("SUBST RES3 '%s'\n", dest->data + pos);
5162                 goto again;
5163         }
5164 #endif
5165         o_addQchr(dest, ch);
5166         goto again;
5167 #undef as_string
5168 }
5169
5170 /*
5171  * Scan input until EOF or end_trigger char.
5172  * Return a list of pipes to execute, or NULL on EOF
5173  * or if end_trigger character is met.
5174  * On syntax error, exit if shell is not interactive,
5175  * reset parsing machinery and start parsing anew,
5176  * or return ERR_PTR.
5177  */
5178 static struct pipe *parse_stream(char **pstring,
5179                 int *heredoc_cnt_ptr,
5180                 struct in_str *input,
5181                 int end_trigger)
5182 {
5183         struct parse_context ctx;
5184         int heredoc_cnt;
5185
5186         /* Single-quote triggers a bypass of the main loop until its mate is
5187          * found.  When recursing, quote state is passed in via ctx.word.o_expflags.
5188          */
5189         debug_printf_parse("parse_stream entered, end_trigger='%c'\n",
5190                         end_trigger ? end_trigger : 'X');
5191         debug_enter();
5192
5193         initialize_context(&ctx);
5194
5195         /* If very first arg is "" or '', ctx.word.data may end up NULL.
5196          * Preventing this:
5197          */
5198         ctx.word.data = xzalloc(1); /* start as "", not as NULL */
5199
5200         /* We used to separate words on $IFS here. This was wrong.
5201          * $IFS is used only for word splitting when $var is expanded,
5202          * here we should use blank chars as separators, not $IFS
5203          */
5204
5205         heredoc_cnt = 0;
5206         while (1) {
5207                 const char *is_blank;
5208                 const char *is_special;
5209                 int ch;
5210                 int next;
5211                 int redir_fd;
5212                 redir_type redir_style;
5213
5214                 ch = i_getch(input);
5215                 debug_printf_parse(": ch=%c (%d) escape=%d\n",
5216                                 ch, ch, !!(ctx.word.o_expflags & EXP_FLAG_ESC_GLOB_CHARS));
5217                 if (ch == EOF) {
5218                         struct pipe *pi;
5219
5220                         if (heredoc_cnt) {
5221                                 syntax_error_unterm_str("here document");
5222                                 goto parse_error;
5223                         }
5224                         if (end_trigger == ')') {
5225                                 syntax_error_unterm_ch('(');
5226                                 goto parse_error;
5227                         }
5228                         if (end_trigger == '}') {
5229                                 syntax_error_unterm_ch('{');
5230                                 goto parse_error;
5231                         }
5232
5233                         if (done_word(&ctx)) {
5234                                 goto parse_error;
5235                         }
5236                         o_free_and_set_NULL(&ctx.word);
5237                         done_pipe(&ctx, PIPE_SEQ);
5238                         pi = ctx.list_head;
5239                         /* If we got nothing... */
5240                         /* (this makes bare "&" cmd a no-op.
5241                          * bash says: "syntax error near unexpected token '&'") */
5242                         if (pi->num_cmds == 0
5243                         IF_HAS_KEYWORDS(&& pi->res_word == RES_NONE)
5244                         ) {
5245                                 free_pipe_list(pi);
5246                                 pi = NULL;
5247                         }
5248 #if !BB_MMU
5249                         debug_printf_parse("as_string1 '%s'\n", ctx.as_string.data);
5250                         if (pstring)
5251                                 *pstring = ctx.as_string.data;
5252                         else
5253                                 o_free(&ctx.as_string);
5254 #endif
5255                         // heredoc_cnt must be 0 here anyway
5256                         //if (heredoc_cnt_ptr)
5257                         //      *heredoc_cnt_ptr = heredoc_cnt;
5258                         debug_leave();
5259                         debug_printf_heredoc("parse_stream return heredoc_cnt:%d\n", heredoc_cnt);
5260                         debug_printf_parse("parse_stream return %p\n", pi);
5261                         return pi;
5262                 }
5263
5264                 /* Handle "'" and "\" first, as they won't play nice with
5265                  * i_peek_and_eat_bkslash_nl() anyway:
5266                  *   echo z\\
5267                  * and
5268                  *   echo '\
5269                  *   '
5270                  * would break.
5271                  */
5272                 if (ch == '\\') {
5273                         ch = i_getch(input);
5274                         if (ch == '\n')
5275                                 continue; /* drop \<newline>, get next char */
5276                         nommu_addchr(&ctx.as_string, '\\');
5277                         o_addchr(&ctx.word, '\\');
5278                         if (ch == EOF) {
5279                                 /* Testcase: eval 'echo Ok\' */
5280                                 /* bash-4.3.43 was removing backslash,
5281                                  * but 4.4.19 retains it, most other shells too
5282                                  */
5283                                 continue; /* get next char */
5284                         }
5285                         /* Example: echo Hello \2>file
5286                          * we need to know that word 2 is quoted
5287                          */
5288                         ctx.word.has_quoted_part = 1;
5289                         nommu_addchr(&ctx.as_string, ch);
5290                         o_addchr(&ctx.word, ch);
5291                         continue; /* get next char */
5292                 }
5293                 nommu_addchr(&ctx.as_string, ch);
5294                 if (ch == '\'') {
5295                         ctx.word.has_quoted_part = 1;
5296                         next = i_getch(input);
5297                         if (next == '\'' && !ctx.pending_redirect)
5298                                 goto insert_empty_quoted_str_marker;
5299
5300                         ch = next;
5301                         while (1) {
5302                                 if (ch == EOF) {
5303                                         syntax_error_unterm_ch('\'');
5304                                         goto parse_error;
5305                                 }
5306                                 nommu_addchr(&ctx.as_string, ch);
5307                                 if (ch == '\'')
5308                                         break;
5309                                 if (ch == SPECIAL_VAR_SYMBOL) {
5310                                         /* Convert raw ^C to corresponding special variable reference */
5311                                         o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
5312                                         o_addchr(&ctx.word, SPECIAL_VAR_QUOTED_SVS);
5313                                 }
5314                                 o_addqchr(&ctx.word, ch);
5315                                 ch = i_getch(input);
5316                         }
5317                         continue; /* get next char */
5318                 }
5319
5320                 next = '\0';
5321                 if (ch != '\n')
5322                         next = i_peek_and_eat_bkslash_nl(input);
5323
5324                 is_special = "{}<>;&|()#" /* special outside of "str" */
5325                                 "$\"" IF_HUSH_TICK("`") /* always special */
5326                                 SPECIAL_VAR_SYMBOL_STR;
5327                 /* Are { and } special here? */
5328                 if (ctx.command->argv /* word [word]{... - non-special */
5329                  || ctx.word.length       /* word{... - non-special */
5330                  || ctx.word.has_quoted_part     /* ""{... - non-special */
5331                  || (next != ';'             /* }; - special */
5332                     && next != ')'           /* }) - special */
5333                     && next != '('           /* {( - special */
5334                     && next != '&'           /* }& and }&& ... - special */
5335                     && next != '|'           /* }|| ... - special */
5336                     && !strchr(defifs, next) /* {word - non-special */
5337                     )
5338                 ) {
5339                         /* They are not special, skip "{}" */
5340                         is_special += 2;
5341                 }
5342                 is_special = strchr(is_special, ch);
5343                 is_blank = strchr(defifs, ch);
5344
5345                 if (!is_special && !is_blank) { /* ordinary char */
5346  ordinary_char:
5347                         o_addQchr(&ctx.word, ch);
5348                         if ((ctx.is_assignment == MAYBE_ASSIGNMENT
5349                             || ctx.is_assignment == WORD_IS_KEYWORD)
5350                          && ch == '='
5351                          && endofname(ctx.word.data)[0] == '='
5352                         ) {
5353                                 ctx.is_assignment = DEFINITELY_ASSIGNMENT;
5354                                 debug_printf_parse("ctx.is_assignment='%s'\n", assignment_flag[ctx.is_assignment]);
5355                         }
5356                         continue;
5357                 }
5358
5359                 if (is_blank) {
5360 #if ENABLE_HUSH_LINENO_VAR
5361 /* Case:
5362  * "while ...; do<whitespace><newline>
5363  *      cmd ..."
5364  * would think that "cmd" starts in <whitespace> -
5365  * i.e., at the previous line.
5366  * We need to skip all whitespace before newlines.
5367  */
5368                         while (ch != '\n') {
5369                                 next = i_peek(input);
5370                                 if (next != ' ' && next != '\t' && next != '\n')
5371                                         break; /* next char is not ws */
5372                                 ch = i_getch(input);
5373                         }
5374                         /* ch == last eaten whitespace char */
5375 #endif
5376                         if (done_word(&ctx)) {
5377                                 goto parse_error;
5378                         }
5379                         if (ch == '\n') {
5380                                 /* Is this a case when newline is simply ignored?
5381                                  * Some examples:
5382                                  * "cmd | <newline> cmd ..."
5383                                  * "case ... in <newline> word) ..."
5384                                  */
5385                                 if (IS_NULL_CMD(ctx.command)
5386                                  && ctx.word.length == 0
5387                                  && !ctx.word.has_quoted_part
5388                                  && heredoc_cnt == 0
5389                                 ) {
5390                                         /* This newline can be ignored. But...
5391                                          * Without check #1, interactive shell
5392                                          * ignores even bare <newline>,
5393                                          * and shows the continuation prompt:
5394                                          * ps1_prompt$ <enter>
5395                                          * ps2> _   <=== wrong, should be ps1
5396                                          * Without check #2, "cmd & <newline>"
5397                                          * is similarly mistreated.
5398                                          * (BTW, this makes "cmd & cmd"
5399                                          * and "cmd && cmd" non-orthogonal.
5400                                          * Really, ask yourself, why
5401                                          * "cmd && <newline>" doesn't start
5402                                          * cmd but waits for more input?
5403                                          * The only reason is that it might be
5404                                          * a "cmd1 && <nl> cmd2 &" construct,
5405                                          * cmd1 may need to run in BG).
5406                                          */
5407                                         struct pipe *pi = ctx.list_head;
5408                                         if (pi->num_cmds != 0       /* check #1 */
5409                                          && pi->followup != PIPE_BG /* check #2 */
5410                                         ) {
5411                                                 continue;
5412                                         }
5413                                 }
5414                                 /* Treat newline as a command separator. */
5415                                 done_pipe(&ctx, PIPE_SEQ);
5416                                 debug_printf_heredoc("heredoc_cnt:%d\n", heredoc_cnt);
5417                                 if (heredoc_cnt) {
5418                                         heredoc_cnt = fetch_heredocs(&ctx.as_string, ctx.list_head, heredoc_cnt, input);
5419                                         if (heredoc_cnt != 0)
5420                                                 goto parse_error;
5421                                 }
5422                                 ctx.is_assignment = MAYBE_ASSIGNMENT;
5423                                 debug_printf_parse("ctx.is_assignment='%s'\n", assignment_flag[ctx.is_assignment]);
5424                                 ch = ';';
5425                                 /* note: if (is_blank) continue;
5426                                  * will still trigger for us */
5427                         }
5428                 }
5429
5430                 /* "cmd}" or "cmd }..." without semicolon or &:
5431                  * } is an ordinary char in this case, even inside { cmd; }
5432                  * Pathological example: { ""}; } should exec "}" cmd
5433                  */
5434                 if (ch == '}') {
5435                         if (ctx.word.length != 0 /* word} */
5436                          || ctx.word.has_quoted_part    /* ""} */
5437                         ) {
5438                                 goto ordinary_char;
5439                         }
5440                         if (!IS_NULL_CMD(ctx.command)) { /* cmd } */
5441                                 /* Generally, there should be semicolon: "cmd; }"
5442                                  * However, bash allows to omit it if "cmd" is
5443                                  * a group. Examples:
5444                                  * { { echo 1; } }
5445                                  * {(echo 1)}
5446                                  * { echo 0 >&2 | { echo 1; } }
5447                                  * { while false; do :; done }
5448                                  * { case a in b) ;; esac }
5449                                  */
5450                                 if (ctx.command->group)
5451                                         goto term_group;
5452                                 goto ordinary_char;
5453                         }
5454                         if (!IS_NULL_PIPE(ctx.pipe)) /* cmd | } */
5455                                 /* Can't be an end of {cmd}, skip the check */
5456                                 goto skip_end_trigger;
5457                         /* else: } does terminate a group */
5458                 }
5459  term_group:
5460                 if (end_trigger && end_trigger == ch
5461                  && (ch != ';' || heredoc_cnt == 0)
5462 #if ENABLE_HUSH_CASE
5463                  && (ch != ')'
5464                     || ctx.ctx_res_w != RES_MATCH
5465                     || (!ctx.word.has_quoted_part && strcmp(ctx.word.data, "esac") == 0)
5466                     )
5467 #endif
5468                 ) {
5469                         if (done_word(&ctx)) {
5470                                 goto parse_error;
5471                         }
5472                         done_pipe(&ctx, PIPE_SEQ);
5473                         ctx.is_assignment = MAYBE_ASSIGNMENT;
5474                         debug_printf_parse("ctx.is_assignment='%s'\n", assignment_flag[ctx.is_assignment]);
5475                         /* Do we sit outside of any if's, loops or case's? */
5476                         if (!HAS_KEYWORDS
5477                         IF_HAS_KEYWORDS(|| (ctx.ctx_res_w == RES_NONE && ctx.old_flag == 0))
5478                         ) {
5479                                 o_free_and_set_NULL(&ctx.word);
5480 #if !BB_MMU
5481                                 debug_printf_parse("as_string2 '%s'\n", ctx.as_string.data);
5482                                 if (pstring)
5483                                         *pstring = ctx.as_string.data;
5484                                 else
5485                                         o_free(&ctx.as_string);
5486 #endif
5487                                 if (ch != ';' && IS_NULL_PIPE(ctx.list_head)) {
5488                                         /* Example: bare "{ }", "()" */
5489                                         G.last_exitcode = 2; /* bash compat */
5490                                         syntax_error_unexpected_ch(ch);
5491                                         goto parse_error2;
5492                                 }
5493                                 if (heredoc_cnt_ptr)
5494                                         *heredoc_cnt_ptr = heredoc_cnt;
5495                                 debug_printf_heredoc("parse_stream return heredoc_cnt:%d\n", heredoc_cnt);
5496                                 debug_printf_parse("parse_stream return %p: "
5497                                                 "end_trigger char found\n",
5498                                                 ctx.list_head);
5499                                 debug_leave();
5500                                 return ctx.list_head;
5501                         }
5502                 }
5503
5504                 if (is_blank)
5505                         continue;
5506
5507                 /* Catch <, > before deciding whether this word is
5508                  * an assignment. a=1 2>z b=2: b=2 is still assignment */
5509                 switch (ch) {
5510                 case '>':
5511                         redir_fd = redirect_opt_num(&ctx.word);
5512                         if (done_word(&ctx)) {
5513                                 goto parse_error;
5514                         }
5515                         redir_style = REDIRECT_OVERWRITE;
5516                         if (next == '>') {
5517                                 redir_style = REDIRECT_APPEND;
5518                                 ch = i_getch(input);
5519                                 nommu_addchr(&ctx.as_string, ch);
5520                         }
5521 #if 0
5522                         else if (next == '(') {
5523                                 syntax_error(">(process) not supported");
5524                                 goto parse_error;
5525                         }
5526 #endif
5527                         if (parse_redirect(&ctx, redir_fd, redir_style, input))
5528                                 goto parse_error;
5529                         continue; /* get next char */
5530                 case '<':
5531                         redir_fd = redirect_opt_num(&ctx.word);
5532                         if (done_word(&ctx)) {
5533                                 goto parse_error;
5534                         }
5535                         redir_style = REDIRECT_INPUT;
5536                         if (next == '<') {
5537                                 redir_style = REDIRECT_HEREDOC;
5538                                 heredoc_cnt++;
5539                                 debug_printf_heredoc("++heredoc_cnt=%d\n", heredoc_cnt);
5540                                 ch = i_getch(input);
5541                                 nommu_addchr(&ctx.as_string, ch);
5542                         } else if (next == '>') {
5543                                 redir_style = REDIRECT_IO;
5544                                 ch = i_getch(input);
5545                                 nommu_addchr(&ctx.as_string, ch);
5546                         }
5547 #if 0
5548                         else if (next == '(') {
5549                                 syntax_error("<(process) not supported");
5550                                 goto parse_error;
5551                         }
5552 #endif
5553                         if (parse_redirect(&ctx, redir_fd, redir_style, input))
5554                                 goto parse_error;
5555                         continue; /* get next char */
5556                 case '#':
5557                         if (ctx.word.length == 0 && !ctx.word.has_quoted_part) {
5558                                 /* skip "#comment" */
5559                                 /* note: we do not add it to &ctx.as_string */
5560 /* TODO: in bash:
5561  * comment inside $() goes to the next \n, even inside quoted string (!):
5562  * cmd "$(cmd2 #comment)" - syntax error
5563  * cmd "`cmd2 #comment`" - ok
5564  * We accept both (comment ends where command subst ends, in both cases).
5565  */
5566                                 while (1) {
5567                                         ch = i_peek(input);
5568                                         if (ch == '\n') {
5569                                                 nommu_addchr(&ctx.as_string, '\n');
5570                                                 break;
5571                                         }
5572                                         ch = i_getch(input);
5573                                         if (ch == EOF)
5574                                                 break;
5575                                 }
5576                                 continue; /* get next char */
5577                         }
5578                         break;
5579                 }
5580  skip_end_trigger:
5581
5582                 if (ctx.is_assignment == MAYBE_ASSIGNMENT
5583                  /* check that we are not in word in "a=1 2>word b=1": */
5584                  && !ctx.pending_redirect
5585                 ) {
5586                         /* ch is a special char and thus this word
5587                          * cannot be an assignment */
5588                         ctx.is_assignment = NOT_ASSIGNMENT;
5589                         debug_printf_parse("ctx.is_assignment='%s'\n", assignment_flag[ctx.is_assignment]);
5590                 }
5591
5592                 /* Note: nommu_addchr(&ctx.as_string, ch) is already done */
5593
5594                 switch (ch) {
5595                 case SPECIAL_VAR_SYMBOL:
5596                         /* Convert raw ^C to corresponding special variable reference */
5597                         o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
5598                         o_addchr(&ctx.word, SPECIAL_VAR_QUOTED_SVS);
5599                         /* fall through */
5600                 case '#':
5601                         /* non-comment #: "echo a#b" etc */
5602                         o_addchr(&ctx.word, ch);
5603                         continue; /* get next char */
5604                 case '$':
5605                         if (!parse_dollar(&ctx.as_string, &ctx.word, input, /*quote_mask:*/ 0)) {
5606                                 debug_printf_parse("parse_stream parse error: "
5607                                         "parse_dollar returned 0 (error)\n");
5608                                 goto parse_error;
5609                         }
5610                         continue; /* get next char */
5611                 case '"':
5612                         ctx.word.has_quoted_part = 1;
5613                         if (next == '"' && !ctx.pending_redirect) {
5614                                 i_getch(input); /* eat second " */
5615  insert_empty_quoted_str_marker:
5616                                 nommu_addchr(&ctx.as_string, next);
5617                                 o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
5618                                 o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
5619                                 continue; /* get next char */
5620                         }
5621                         if (ctx.is_assignment == NOT_ASSIGNMENT)
5622                                 ctx.word.o_expflags |= EXP_FLAG_ESC_GLOB_CHARS;
5623                         if (!encode_string(&ctx.as_string, &ctx.word, input, '"'))
5624                                 goto parse_error;
5625                         ctx.word.o_expflags &= ~EXP_FLAG_ESC_GLOB_CHARS;
5626                         continue; /* get next char */
5627 #if ENABLE_HUSH_TICK
5628                 case '`': {
5629                         USE_FOR_NOMMU(unsigned pos;)
5630
5631                         o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
5632                         o_addchr(&ctx.word, '`');
5633                         USE_FOR_NOMMU(pos = ctx.word.length;)
5634                         if (!add_till_backquote(&ctx.word, input, /*in_dquote:*/ 0))
5635                                 goto parse_error;
5636 # if !BB_MMU
5637                         o_addstr(&ctx.as_string, ctx.word.data + pos);
5638                         o_addchr(&ctx.as_string, '`');
5639 # endif
5640                         o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
5641                         //debug_printf_subst("SUBST RES3 '%s'\n", ctx.word.data + pos);
5642                         continue; /* get next char */
5643                 }
5644 #endif
5645                 case ';':
5646 #if ENABLE_HUSH_CASE
5647  case_semi:
5648 #endif
5649                         if (done_word(&ctx)) {
5650                                 goto parse_error;
5651                         }
5652                         done_pipe(&ctx, PIPE_SEQ);
5653 #if ENABLE_HUSH_CASE
5654                         /* Eat multiple semicolons, detect
5655                          * whether it means something special */
5656                         while (1) {
5657                                 ch = i_peek_and_eat_bkslash_nl(input);
5658                                 if (ch != ';')
5659                                         break;
5660                                 ch = i_getch(input);
5661                                 nommu_addchr(&ctx.as_string, ch);
5662                                 if (ctx.ctx_res_w == RES_CASE_BODY) {
5663                                         ctx.ctx_dsemicolon = 1;
5664                                         ctx.ctx_res_w = RES_MATCH;
5665                                         break;
5666                                 }
5667                         }
5668 #endif
5669  new_cmd:
5670                         /* We just finished a cmd. New one may start
5671                          * with an assignment */
5672                         ctx.is_assignment = MAYBE_ASSIGNMENT;
5673                         debug_printf_parse("ctx.is_assignment='%s'\n", assignment_flag[ctx.is_assignment]);
5674                         continue; /* get next char */
5675                 case '&':
5676                         if (done_word(&ctx)) {
5677                                 goto parse_error;
5678                         }
5679                         if (next == '&') {
5680                                 ch = i_getch(input);
5681                                 nommu_addchr(&ctx.as_string, ch);
5682                                 done_pipe(&ctx, PIPE_AND);
5683                         } else {
5684                                 done_pipe(&ctx, PIPE_BG);
5685                         }
5686                         goto new_cmd;
5687                 case '|':
5688                         if (done_word(&ctx)) {
5689                                 goto parse_error;
5690                         }
5691 #if ENABLE_HUSH_CASE
5692                         if (ctx.ctx_res_w == RES_MATCH)
5693                                 break; /* we are in case's "word | word)" */
5694 #endif
5695                         if (next == '|') { /* || */
5696                                 ch = i_getch(input);
5697                                 nommu_addchr(&ctx.as_string, ch);
5698                                 done_pipe(&ctx, PIPE_OR);
5699                         } else {
5700                                 /* we could pick up a file descriptor choice here
5701                                  * with redirect_opt_num(), but bash doesn't do it.
5702                                  * "echo foo 2| cat" yields "foo 2". */
5703                                 done_command(&ctx);
5704                         }
5705                         goto new_cmd;
5706                 case '(':
5707 #if ENABLE_HUSH_CASE
5708                         /* "case... in [(]word)..." - skip '(' */
5709                         if (ctx.ctx_res_w == RES_MATCH
5710                          && ctx.command->argv == NULL /* not (word|(... */
5711                          && ctx.word.length == 0 /* not word(... */
5712                          && ctx.word.has_quoted_part == 0 /* not ""(... */
5713                         ) {
5714                                 continue; /* get next char */
5715                         }
5716 #endif
5717                         /* fall through */
5718                 case '{': {
5719                         int n = parse_group(&ctx, input, ch);
5720                         if (n < 0) {
5721                                 goto parse_error;
5722                         }
5723                         debug_printf_heredoc("parse_group done, needs heredocs:%d\n", n);
5724                         heredoc_cnt += n;
5725                         goto new_cmd;
5726                 }
5727                 case ')':
5728 #if ENABLE_HUSH_CASE
5729                         if (ctx.ctx_res_w == RES_MATCH)
5730                                 goto case_semi;
5731 #endif
5732
5733                 case '}':
5734                         /* proper use of this character is caught by end_trigger:
5735                          * if we see {, we call parse_group(..., end_trigger='}')
5736                          * and it will match } earlier (not here). */
5737                         G.last_exitcode = 2;
5738                         syntax_error_unexpected_ch(ch);
5739                         goto parse_error2;
5740                 default:
5741                         if (HUSH_DEBUG)
5742                                 bb_error_msg_and_die("BUG: unexpected %c", ch);
5743                 }
5744         } /* while (1) */
5745
5746  parse_error:
5747         G.last_exitcode = 1;
5748  parse_error2:
5749         {
5750                 struct parse_context *pctx;
5751                 IF_HAS_KEYWORDS(struct parse_context *p2;)
5752
5753                 /* Clean up allocated tree.
5754                  * Sample for finding leaks on syntax error recovery path.
5755                  * Run it from interactive shell, watch pmap `pidof hush`.
5756                  * while if false; then false; fi; do break; fi
5757                  * Samples to catch leaks at execution:
5758                  * while if (true | { true;}); then echo ok; fi; do break; done
5759                  * while if (true | { true;}); then echo ok; fi; do (if echo ok; break; then :; fi) | cat; break; done
5760                  */
5761                 pctx = &ctx;
5762                 do {
5763                         /* Update pipe/command counts,
5764                          * otherwise freeing may miss some */
5765                         done_pipe(pctx, PIPE_SEQ);
5766                         debug_printf_clean("freeing list %p from ctx %p\n",
5767                                         pctx->list_head, pctx);
5768                         debug_print_tree(pctx->list_head, 0);
5769                         free_pipe_list(pctx->list_head);
5770                         debug_printf_clean("freed list %p\n", pctx->list_head);
5771 #if !BB_MMU
5772                         o_free(&pctx->as_string);
5773 #endif
5774                         IF_HAS_KEYWORDS(p2 = pctx->stack;)
5775                         if (pctx != &ctx) {
5776                                 free(pctx);
5777                         }
5778                         IF_HAS_KEYWORDS(pctx = p2;)
5779                 } while (HAS_KEYWORDS && pctx);
5780
5781                 o_free(&ctx.word);
5782 #if !BB_MMU
5783                 if (pstring)
5784                         *pstring = NULL;
5785 #endif
5786                 debug_leave();
5787                 return ERR_PTR;
5788         }
5789 }
5790
5791
5792 /*** Execution routines ***/
5793
5794 /* Expansion can recurse, need forward decls: */
5795 #if !BASH_PATTERN_SUBST && !ENABLE_HUSH_CASE
5796 #define expand_string_to_string(str, EXP_flags, do_unbackslash) \
5797         expand_string_to_string(str)
5798 #endif
5799 static char *expand_string_to_string(const char *str, int EXP_flags, int do_unbackslash);
5800 #if ENABLE_HUSH_TICK
5801 static int process_command_subs(o_string *dest, const char *s);
5802 #endif
5803 static int expand_vars_to_list(o_string *output, int n, char *arg);
5804
5805 /* expand_strvec_to_strvec() takes a list of strings, expands
5806  * all variable references within and returns a pointer to
5807  * a list of expanded strings, possibly with larger number
5808  * of strings. (Think VAR="a b"; echo $VAR).
5809  * This new list is allocated as a single malloc block.
5810  * NULL-terminated list of char* pointers is at the beginning of it,
5811  * followed by strings themselves.
5812  * Caller can deallocate entire list by single free(list). */
5813
5814 /* A horde of its helpers come first: */
5815
5816 static void o_addblock_duplicate_backslash(o_string *o, const char *str, int len)
5817 {
5818         while (--len >= 0) {
5819                 char c = *str++;
5820
5821 #if ENABLE_HUSH_BRACE_EXPANSION
5822                 if (c == '{' || c == '}') {
5823                         /* { -> \{, } -> \} */
5824                         o_addchr(o, '\\');
5825                         /* And now we want to add { or } and continue:
5826                          *  o_addchr(o, c);
5827                          *  continue;
5828                          * luckily, just falling through achieves this.
5829                          */
5830                 }
5831 #endif
5832                 o_addchr(o, c);
5833                 if (c == '\\') {
5834                         /* \z -> \\\z; \<eol> -> \\<eol> */
5835                         o_addchr(o, '\\');
5836                         if (len) {
5837                                 len--;
5838                                 o_addchr(o, '\\');
5839                                 o_addchr(o, *str++);
5840                         }
5841                 }
5842         }
5843 }
5844
5845 /* Store given string, finalizing the word and starting new one whenever
5846  * we encounter IFS char(s). This is used for expanding variable values.
5847  * End-of-string does NOT finalize word: think about 'echo -$VAR-'.
5848  * Return in output->ended_in_ifs:
5849  * 1 - ended with IFS char, else 0 (this includes case of empty str).
5850  */
5851 static int expand_on_ifs(o_string *output, int n, const char *str)
5852 {
5853         int last_is_ifs = 0;
5854
5855         while (1) {
5856                 int word_len;
5857
5858                 if (!*str)  /* EOL - do not finalize word */
5859                         break;
5860                 word_len = strcspn(str, G.ifs);
5861                 if (word_len) {
5862                         /* We have WORD_LEN leading non-IFS chars */
5863                         if (!(output->o_expflags & EXP_FLAG_GLOB)) {
5864                                 o_addblock(output, str, word_len);
5865                         } else {
5866                                 /* Protect backslashes against globbing up :)
5867                                  * Example: "v='\*'; echo b$v" prints "b\*"
5868                                  * (and does not try to glob on "*")
5869                                  */
5870                                 o_addblock_duplicate_backslash(output, str, word_len);
5871                                 /*/ Why can't we do it easier? */
5872                                 /*o_addblock(output, str, word_len); - WRONG: "v='\*'; echo Z$v" prints "Z*" instead of "Z\*" */
5873                                 /*o_addqblock(output, str, word_len); - WRONG: "v='*'; echo Z$v" prints "Z*" instead of Z* files */
5874                         }
5875                         last_is_ifs = 0;
5876                         str += word_len;
5877                         if (!*str)  /* EOL - do not finalize word */
5878                                 break;
5879                 }
5880
5881                 /* We know str here points to at least one IFS char */
5882                 last_is_ifs = 1;
5883                 str += strspn(str, G.ifs_whitespace); /* skip IFS whitespace chars */
5884                 if (!*str)  /* EOL - do not finalize word */
5885                         break;
5886
5887                 if (G.ifs_whitespace != G.ifs /* usually false ($IFS is usually all whitespace), */
5888                  && strchr(G.ifs, *str)       /* the second check would fail */
5889                 ) {
5890                         /* This is a non-whitespace $IFS char */
5891                         /* Skip it and IFS whitespace chars, start new word */
5892                         str++;
5893                         str += strspn(str, G.ifs_whitespace);
5894                         goto new_word;
5895                 }
5896
5897                 /* Start new word... but not always! */
5898                 /* Case "v=' a'; echo ''$v": we do need to finalize empty word: */
5899                 if (output->has_quoted_part
5900                 /*
5901                  * Case "v=' a'; echo $v":
5902                  * here nothing precedes the space in $v expansion,
5903                  * therefore we should not finish the word
5904                  * (IOW: if there *is* word to finalize, only then do it):
5905                  * It's okay if this accesses the byte before first argv[]:
5906                  * past call to o_save_ptr() cleared it to zero byte
5907                  * (grep for -prev-ifs-check-).
5908                  */
5909                  || output->data[output->length - 1]
5910                 ) {
5911  new_word:
5912                         o_addchr(output, '\0');
5913                         debug_print_list("expand_on_ifs", output, n);
5914                         n = o_save_ptr(output, n);
5915                 }
5916         }
5917
5918         output->ended_in_ifs = last_is_ifs;
5919         debug_print_list("expand_on_ifs[1]", output, n);
5920         return n;
5921 }
5922
5923 /* Helper to expand $((...)) and heredoc body. These act as if
5924  * they are in double quotes, with the exception that they are not :).
5925  * Just the rules are similar: "expand only $var and `cmd`"
5926  *
5927  * Returns malloced string.
5928  * As an optimization, we return NULL if expansion is not needed.
5929  */
5930 static char *encode_then_expand_string(const char *str)
5931 {
5932         char *exp_str;
5933         struct in_str input;
5934         o_string dest = NULL_O_STRING;
5935         const char *cp;
5936
5937         cp = str;
5938         for (;;) {
5939                 if (!*cp) return NULL; /* string has no special chars */
5940                 if (*cp == '$') break;
5941                 if (*cp == '\\') break;
5942 #if ENABLE_HUSH_TICK
5943                 if (*cp == '`') break;
5944 #endif
5945                 cp++;
5946         }
5947
5948         /* We need to expand. Example:
5949          * echo $(($a + `echo 1`)) $((1 + $((2)) ))
5950          */
5951         setup_string_in_str(&input, str);
5952         encode_string(NULL, &dest, &input, EOF);
5953 //TODO: error check (encode_string returns 0 on error)?
5954         //bb_error_msg("'%s' -> '%s'", str, dest.data);
5955         exp_str = expand_string_to_string(dest.data,
5956                         EXP_FLAG_ESC_GLOB_CHARS,
5957                         /*unbackslash:*/ 1
5958         );
5959         //bb_error_msg("'%s' -> '%s'", dest.data, exp_str);
5960         o_free(&dest);
5961         return exp_str;
5962 }
5963
5964 static const char *first_special_char_in_vararg(const char *cp)
5965 {
5966         for (;;) {
5967                 if (!*cp) return NULL; /* string has no special chars */
5968                 if (*cp == '$') return cp;
5969                 if (*cp == '\\') return cp;
5970                 if (*cp == '\'') return cp;
5971                 if (*cp == '"') return cp;
5972 #if ENABLE_HUSH_TICK
5973                 if (*cp == '`') return cp;
5974 #endif
5975                 /* dquoted "${x:+ARG}" should not glob, therefore
5976                  * '*' et al require some non-literal processing: */
5977                 if (*cp == '*') return cp;
5978                 if (*cp == '?') return cp;
5979                 if (*cp == '[') return cp;
5980                 cp++;
5981         }
5982 }
5983
5984 /* Expanding ARG in ${var#ARG}, ${var%ARG}, or ${var/ARG/ARG}.
5985  * These can contain single- and double-quoted strings,
5986  * and treated as if the ARG string is initially unquoted. IOW:
5987  * ${var#ARG} and "${var#ARG}" treat ARG the same (ARG can even be
5988  * a dquoted string: "${var#"zz"}"), the difference only comes later
5989  * (word splitting and globbing of the ${var...} result).
5990  */
5991 #if !BASH_PATTERN_SUBST
5992 #define encode_then_expand_vararg(str, handle_squotes, do_unbackslash) \
5993         encode_then_expand_vararg(str, handle_squotes)
5994 #endif
5995 static char *encode_then_expand_vararg(const char *str, int handle_squotes, int do_unbackslash)
5996 {
5997 #if !BASH_PATTERN_SUBST && ENABLE_HUSH_CASE
5998         const int do_unbackslash = 0;
5999 #endif
6000         char *exp_str;
6001         struct in_str input;
6002         o_string dest = NULL_O_STRING;
6003
6004         if (!first_special_char_in_vararg(str)) {
6005                 /* string has no special chars */
6006                 return NULL;
6007         }
6008
6009         setup_string_in_str(&input, str);
6010         dest.data = xzalloc(1); /* start as "", not as NULL */
6011         exp_str = NULL;
6012
6013         for (;;) {
6014                 int ch;
6015
6016                 ch = i_getch(&input);
6017                 debug_printf_parse("%s: ch=%c (%d) escape=%d\n",
6018                                 __func__, ch, ch, !!dest.o_expflags);
6019
6020                 if (!dest.o_expflags) {
6021                         if (ch == EOF)
6022                                 break;
6023                         if (handle_squotes && ch == '\'') {
6024                                 if (!add_till_single_quote_dquoted(&dest, &input))
6025                                         goto ret; /* error */
6026                                 continue;
6027                         }
6028                 }
6029                 if (ch == EOF) {
6030                         syntax_error_unterm_ch('"');
6031                         goto ret; /* error */
6032                 }
6033                 if (ch == '"') {
6034                         dest.o_expflags ^= EXP_FLAG_ESC_GLOB_CHARS;
6035                         continue;
6036                 }
6037                 if (ch == '\\') {
6038                         ch = i_getch(&input);
6039                         if (ch == EOF) {
6040 //example? error message?       syntax_error_unterm_ch('"');
6041                                 debug_printf_parse("%s: error: \\<eof>\n", __func__);
6042                                 goto ret;
6043                         }
6044                         o_addqchr(&dest, ch);
6045                         continue;
6046                 }
6047                 if (ch == '$') {
6048                         if (!parse_dollar(NULL, &dest, &input, /*quote_mask:*/ 0x80)) {
6049                                 debug_printf_parse("%s: error: parse_dollar returned 0 (error)\n", __func__);
6050                                 goto ret;
6051                         }
6052                         continue;
6053                 }
6054 #if ENABLE_HUSH_TICK
6055                 if (ch == '`') {
6056                         //unsigned pos = dest->length;
6057                         o_addchr(&dest, SPECIAL_VAR_SYMBOL);
6058                         o_addchr(&dest, 0x80 | '`');
6059                         if (!add_till_backquote(&dest, &input,
6060                                         /*in_dquote:*/ dest.o_expflags /* nonzero if EXP_FLAG_ESC_GLOB_CHARS set */
6061                                 )
6062                         ) {
6063                                 goto ret; /* error */
6064                         }
6065                         o_addchr(&dest, SPECIAL_VAR_SYMBOL);
6066                         //debug_printf_subst("SUBST RES3 '%s'\n", dest->data + pos);
6067                         continue;
6068                 }
6069 #endif
6070                 o_addQchr(&dest, ch);
6071         } /* for (;;) */
6072
6073         debug_printf_parse("encode: '%s' -> '%s'\n", str, dest.data);
6074         exp_str = expand_string_to_string(dest.data,
6075                         do_unbackslash ? EXP_FLAG_ESC_GLOB_CHARS : 0,
6076                         do_unbackslash
6077         );
6078  ret:
6079         debug_printf_parse("expand: '%s' -> '%s'\n", dest.data, exp_str);
6080         o_free(&dest);
6081         return exp_str;
6082 }
6083
6084 /* Expanding ARG in ${var+ARG}, ${var-ARG}
6085  */
6086 static int encode_then_append_var_plusminus(o_string *output, int n,
6087                 char *str, int dquoted)
6088 {
6089         struct in_str input;
6090         o_string dest = NULL_O_STRING;
6091
6092         if (!first_special_char_in_vararg(str)
6093          && '\0' == str[strcspn(str, G.ifs)]
6094         ) {
6095                 /* string has no special chars
6096                  * && string has no $IFS chars
6097                  */
6098                 if (dquoted) {
6099                         /* Prints 1 (quoted expansion is a "" word, not nothing):
6100                          * set -- "${notexist-}"; echo $#
6101                          */
6102                         output->has_quoted_part = 1;
6103                 }
6104                 return expand_vars_to_list(output, n, str);
6105         }
6106
6107         setup_string_in_str(&input, str);
6108
6109         for (;;) {
6110                 int ch;
6111
6112                 ch = i_getch(&input);
6113                 debug_printf_parse("%s: ch=%c (%d) escape=%x\n",
6114                                 __func__, ch, ch, dest.o_expflags);
6115
6116                 if (!dest.o_expflags) {
6117                         if (ch == EOF)
6118                                 break;
6119                         if (!dquoted && strchr(G.ifs, ch)) {
6120                                 /* PREFIX${x:d${e}f ...} and we met space: expand "d${e}f" and start new word.
6121                                  * do not assume we are at the start of the word (PREFIX above).
6122                                  */
6123                                 if (dest.data) {
6124                                         n = expand_vars_to_list(output, n, dest.data);
6125                                         o_free_and_set_NULL(&dest);
6126                                         o_addchr(output, '\0');
6127                                         n = o_save_ptr(output, n); /* create next word */
6128                                 } else
6129                                 if (output->length != o_get_last_ptr(output, n)
6130                                  || output->has_quoted_part
6131                                 ) {
6132                                         /* For these cases:
6133                                          * f() { for i; do echo "|$i|"; done; }; x=x
6134                                          * f a${x:+ }b  # 1st condition
6135                                          * |a|
6136                                          * |b|
6137                                          * f ""${x:+ }b  # 2nd condition
6138                                          * ||
6139                                          * |b|
6140                                          */
6141                                         o_addchr(output, '\0');
6142                                         n = o_save_ptr(output, n); /* create next word */
6143                                 }
6144                                 continue;
6145                         }
6146                         if (!dquoted && ch == '\'') {
6147                                 if (!add_till_single_quote_dquoted(&dest, &input))
6148                                         goto ret; /* error */
6149                                 o_addchr(&dest, SPECIAL_VAR_SYMBOL);
6150                                 o_addchr(&dest, SPECIAL_VAR_SYMBOL);
6151                                 continue;
6152                         }
6153                 }
6154                 if (ch == EOF) {
6155                         syntax_error_unterm_ch('"');
6156                         goto ret; /* error */
6157                 }
6158                 if (ch == '"') {
6159                         dest.o_expflags ^= EXP_FLAG_ESC_GLOB_CHARS;
6160                         if (dest.o_expflags) {
6161                                 o_addchr(&dest, SPECIAL_VAR_SYMBOL);
6162                                 o_addchr(&dest, SPECIAL_VAR_SYMBOL);
6163                         }
6164                         continue;
6165                 }
6166                 if (ch == '\\') {
6167                         ch = i_getch(&input);
6168                         if (ch == EOF) {
6169 //example? error message?       syntax_error_unterm_ch('"');
6170                                 debug_printf_parse("%s: error: \\<eof>\n", __func__);
6171                                 goto ret;
6172                         }
6173                         o_addqchr(&dest, ch);
6174                         continue;
6175                 }
6176                 if (ch == '$') {
6177                         if (!parse_dollar(NULL, &dest, &input, /*quote_mask:*/ (dest.o_expflags || dquoted) ? 0x80 : 0)) {
6178                                 debug_printf_parse("%s: error: parse_dollar returned 0 (error)\n", __func__);
6179                                 goto ret;
6180                         }
6181                         continue;
6182                 }
6183 #if ENABLE_HUSH_TICK
6184                 if (ch == '`') {
6185                         //unsigned pos = dest->length;
6186                         o_addchr(&dest, SPECIAL_VAR_SYMBOL);
6187                         o_addchr(&dest, (dest.o_expflags || dquoted) ? 0x80 | '`' : '`');
6188                         if (!add_till_backquote(&dest, &input,
6189                                         /*in_dquote:*/ dest.o_expflags /* nonzero if EXP_FLAG_ESC_GLOB_CHARS set */
6190                                 )
6191                         ) {
6192                                 goto ret; /* error */
6193                         }
6194                         o_addchr(&dest, SPECIAL_VAR_SYMBOL);
6195                         //debug_printf_subst("SUBST RES3 '%s'\n", dest->data + pos);
6196                         continue;
6197                 }
6198 #endif
6199                 if (dquoted) {
6200                         /* Always glob-protect if in dquotes:
6201                          * x=x; echo "${x:+/bin/c*}" - prints: /bin/c*
6202                          * x=x; echo "${x:+"/bin/c*"}" - prints: /bin/c*
6203                          */
6204                         o_addqchr(&dest, ch);
6205                 } else {
6206                         /* Glob-protect only if char is quoted:
6207                          * x=x; echo ${x:+/bin/c*} - prints many filenames
6208                          * x=x; echo ${x:+"/bin/c*"} - prints: /bin/c*
6209                          */
6210                         o_addQchr(&dest, ch);
6211                 }
6212         } /* for (;;) */
6213
6214         if (dest.data) {
6215                 n = expand_vars_to_list(output, n, dest.data);
6216         }
6217  ret:
6218         o_free(&dest);
6219         return n;
6220 }
6221
6222 #if ENABLE_FEATURE_SH_MATH
6223 static arith_t expand_and_evaluate_arith(const char *arg, const char **errmsg_p)
6224 {
6225         arith_state_t math_state;
6226         arith_t res;
6227         char *exp_str;
6228
6229         math_state.lookupvar = get_local_var_value;
6230         math_state.setvar = set_local_var_from_halves;
6231         //math_state.endofname = endofname;
6232         exp_str = encode_then_expand_string(arg);
6233         res = arith(&math_state, exp_str ? exp_str : arg);
6234         free(exp_str);
6235         if (errmsg_p)
6236                 *errmsg_p = math_state.errmsg;
6237         if (math_state.errmsg)
6238                 msg_and_die_if_script(math_state.errmsg);
6239         return res;
6240 }
6241 #endif
6242
6243 #if BASH_PATTERN_SUBST
6244 /* ${var/[/]pattern[/repl]} helpers */
6245 static char *strstr_pattern(char *val, const char *pattern, int *size)
6246 {
6247         while (1) {
6248                 char *end = scan_and_match(val, pattern, SCAN_MOVE_FROM_RIGHT + SCAN_MATCH_LEFT_HALF);
6249                 debug_printf_varexp("val:'%s' pattern:'%s' end:'%s'\n", val, pattern, end);
6250                 if (end) {
6251                         *size = end - val;
6252                         return val;
6253                 }
6254                 if (*val == '\0')
6255                         return NULL;
6256                 /* Optimization: if "*pat" did not match the start of "string",
6257                  * we know that "tring", "ring" etc will not match too:
6258                  */
6259                 if (pattern[0] == '*')
6260                         return NULL;
6261                 val++;
6262         }
6263 }
6264 static char *replace_pattern(char *val, const char *pattern, const char *repl, char exp_op)
6265 {
6266         char *result = NULL;
6267         unsigned res_len = 0;
6268         unsigned repl_len = strlen(repl);
6269
6270         /* Null pattern never matches, including if "var" is empty */
6271         if (!pattern[0])
6272                 return result; /* NULL, no replaces happened */
6273
6274         while (1) {
6275                 int size;
6276                 char *s = strstr_pattern(val, pattern, &size);
6277                 if (!s)
6278                         break;
6279
6280                 result = xrealloc(result, res_len + (s - val) + repl_len + 1);
6281                 strcpy(mempcpy(result + res_len, val, s - val), repl);
6282                 res_len += (s - val) + repl_len;
6283                 debug_printf_varexp("val:'%s' s:'%s' result:'%s'\n", val, s, result);
6284
6285                 val = s + size;
6286                 if (exp_op == '/')
6287                         break;
6288         }
6289         if (*val && result) {
6290                 result = xrealloc(result, res_len + strlen(val) + 1);
6291                 strcpy(result + res_len, val);
6292                 debug_printf_varexp("val:'%s' result:'%s'\n", val, result);
6293         }
6294         debug_printf_varexp("result:'%s'\n", result);
6295         return result;
6296 }
6297 #endif /* BASH_PATTERN_SUBST */
6298
6299 static int append_str_maybe_ifs_split(o_string *output, int n,
6300                 int first_ch, const char *val)
6301 {
6302         if (!(first_ch & 0x80)) { /* unquoted $VAR */
6303                 debug_printf_expand("unquoted '%s', output->o_escape:%d\n", val,
6304                                 !!(output->o_expflags & EXP_FLAG_ESC_GLOB_CHARS));
6305                 if (val && val[0])
6306                         n = expand_on_ifs(output, n, val);
6307         } else { /* quoted "$VAR" */
6308                 output->has_quoted_part = 1;
6309                 debug_printf_expand("quoted '%s', output->o_escape:%d\n", val,
6310                                 !!(output->o_expflags & EXP_FLAG_ESC_GLOB_CHARS));
6311                 if (val && val[0])
6312                         o_addQstr(output, val);
6313         }
6314         return n;
6315 }
6316
6317 /* Handle <SPECIAL_VAR_SYMBOL>varname...<SPECIAL_VAR_SYMBOL> construct.
6318  */
6319 static NOINLINE int expand_one_var(o_string *output, int n,
6320                 int first_ch, char *arg, char **pp)
6321 {
6322         const char *val;
6323         char *to_be_freed;
6324         char *p;
6325         char *var;
6326         char exp_op;
6327         char exp_save = exp_save; /* for compiler */
6328         char *exp_saveptr; /* points to expansion operator */
6329         char *exp_word = exp_word; /* for compiler */
6330         char arg0;
6331
6332         val = NULL;
6333         to_be_freed = NULL;
6334         p = *pp;
6335         *p = '\0'; /* replace trailing SPECIAL_VAR_SYMBOL */
6336         var = arg;
6337         exp_saveptr = arg[1] ? strchr(VAR_ENCODED_SUBST_OPS, arg[1]) : NULL;
6338         arg0 = arg[0];
6339         arg[0] = (arg0 & 0x7f);
6340         exp_op = 0;
6341
6342         if (arg[0] == '#' && arg[1] /* ${#...} but not ${#} */
6343          && (!exp_saveptr               /* and ( not(${#<op_char>...}) */
6344             || (arg[2] == '\0' && strchr(SPECIAL_VARS_STR, arg[1])) /* or ${#C} "len of $C" ) */
6345             )           /* NB: skipping ^^^specvar check mishandles ${#::2} */
6346         ) {
6347                 /* It must be length operator: ${#var} */
6348                 var++;
6349                 exp_op = 'L';
6350         } else {
6351                 /* Maybe handle parameter expansion */
6352                 if (exp_saveptr /* if 2nd char is one of expansion operators */
6353                  && strchr(NUMERIC_SPECVARS_STR, arg[0]) /* 1st char is special variable */
6354                 ) {
6355                         /* ${?:0}, ${#[:]%0} etc */
6356                         exp_saveptr = var + 1;
6357                 } else {
6358                         /* ${?}, ${var}, ${var:0}, ${var[:]%0} etc */
6359                         exp_saveptr = var+1 + strcspn(var+1, VAR_ENCODED_SUBST_OPS);
6360                 }
6361                 exp_op = exp_save = *exp_saveptr;
6362                 if (exp_op) {
6363                         exp_word = exp_saveptr + 1;
6364                         if (exp_op == ':') {
6365                                 exp_op = *exp_word++;
6366 //TODO: try ${var:} and ${var:bogus} in non-bash config
6367                                 if (BASH_SUBSTR
6368                                  && (!exp_op || !strchr(MINUS_PLUS_EQUAL_QUESTION, exp_op))
6369                                 ) {
6370                                         /* oops... it's ${var:N[:M]}, not ${var:?xxx} or some such */
6371                                         exp_op = ':';
6372                                         exp_word--;
6373                                 }
6374                         }
6375                         *exp_saveptr = '\0';
6376                 } /* else: it's not an expansion op, but bare ${var} */
6377         }
6378
6379         /* Look up the variable in question */
6380         if (isdigit(var[0])) {
6381                 /* parse_dollar should have vetted var for us */
6382                 int nn = xatoi_positive(var);
6383                 if (nn < G.global_argc)
6384                         val = G.global_argv[nn];
6385                 /* else val remains NULL: $N with too big N */
6386         } else {
6387                 switch (var[0]) {
6388                 case '$': /* pid */
6389                         val = utoa(G.root_pid);
6390                         break;
6391                 case '!': /* bg pid */
6392                         val = G.last_bg_pid ? utoa(G.last_bg_pid) : "";
6393                         break;
6394                 case '?': /* exitcode */
6395                         val = utoa(G.last_exitcode);
6396                         break;
6397                 case '#': /* argc */
6398                         val = utoa(G.global_argc ? G.global_argc-1 : 0);
6399                         break;
6400                 default:
6401                         val = get_local_var_value(var);
6402                 }
6403         }
6404
6405         /* Handle any expansions */
6406         if (exp_op == 'L') {
6407                 reinit_unicode_for_hush();
6408                 debug_printf_expand("expand: length(%s)=", val);
6409                 val = utoa(val ? unicode_strlen(val) : 0);
6410                 debug_printf_expand("%s\n", val);
6411         } else if (exp_op) {
6412                 if (exp_op == '%' || exp_op == '#') {
6413                         /* Standard-mandated substring removal ops:
6414                          * ${parameter%word} - remove smallest suffix pattern
6415                          * ${parameter%%word} - remove largest suffix pattern
6416                          * ${parameter#word} - remove smallest prefix pattern
6417                          * ${parameter##word} - remove largest prefix pattern
6418                          *
6419                          * Word is expanded to produce a glob pattern.
6420                          * Then var's value is matched to it and matching part removed.
6421                          */
6422 //FIXME: ${x#...${...}...}
6423 //should evaluate inner ${...} even if x is "" and no shrinking of it is possible -
6424 //inner ${...} may have side effects!
6425                         if (val && val[0]) {
6426                                 char *t;
6427                                 char *exp_exp_word;
6428                                 char *loc;
6429                                 unsigned scan_flags = pick_scan(exp_op, *exp_word);
6430                                 if (exp_op == *exp_word)  /* ## or %% */
6431                                         exp_word++;
6432                                 debug_printf_expand("expand: exp_word:'%s'\n", exp_word);
6433                                 exp_exp_word = encode_then_expand_vararg(exp_word, /*handle_squotes:*/ 1, /*unbackslash:*/ 0);
6434                                 if (exp_exp_word)
6435                                         exp_word = exp_exp_word;
6436                                 debug_printf_expand("expand: exp_word:'%s'\n", exp_word);
6437                                 /*
6438                                  * HACK ALERT. We depend here on the fact that
6439                                  * G.global_argv and results of utoa and get_local_var_value
6440                                  * are actually in writable memory:
6441                                  * scan_and_match momentarily stores NULs there.
6442                                  */
6443                                 t = (char*)val;
6444                                 loc = scan_and_match(t, exp_word, scan_flags);
6445                                 debug_printf_expand("op:%c str:'%s' pat:'%s' res:'%s'\n", exp_op, t, exp_word, loc);
6446                                 free(exp_exp_word);
6447                                 if (loc) { /* match was found */
6448                                         if (scan_flags & SCAN_MATCH_LEFT_HALF) /* #[#] */
6449                                                 val = loc; /* take right part */
6450                                         else /* %[%] */
6451                                                 val = to_be_freed = xstrndup(val, loc - val); /* left */
6452                                 }
6453                         }
6454                 }
6455 #if BASH_PATTERN_SUBST
6456                 else if (exp_op == '/' || exp_op == '\\') {
6457                         /* It's ${var/[/]pattern[/repl]} thing.
6458                          * Note that in encoded form it has TWO parts:
6459                          * var/pattern<SPECIAL_VAR_SYMBOL>repl<SPECIAL_VAR_SYMBOL>
6460                          * and if // is used, it is encoded as \:
6461                          * var\pattern<SPECIAL_VAR_SYMBOL>repl<SPECIAL_VAR_SYMBOL>
6462                          */
6463                         if (val && val[0]) {
6464                                 /* pattern uses non-standard expansion.
6465                                  * repl should be unbackslashed and globbed
6466                                  * by the usual expansion rules:
6467                                  *  >az >bz
6468                                  *  v='a bz'; echo "${v/a*z/a*z}" #prints "a*z"
6469                                  *  v='a bz'; echo "${v/a*z/\z}"  #prints "z"
6470                                  *  v='a bz'; echo ${v/a*z/a*z}   #prints "az"
6471                                  *  v='a bz'; echo ${v/a*z/\z}    #prints "z"
6472                                  * (note that a*z _pattern_ is never globbed!)
6473                                  */
6474                                 char *pattern, *repl, *t;
6475                                 pattern = encode_then_expand_vararg(exp_word, /*handle_squotes:*/ 1, /*unbackslash:*/ 0);
6476                                 if (!pattern)
6477                                         pattern = xstrdup(exp_word);
6478                                 debug_printf_varexp("pattern:'%s'->'%s'\n", exp_word, pattern);
6479                                 *p++ = SPECIAL_VAR_SYMBOL;
6480                                 exp_word = p;
6481                                 p = strchr(p, SPECIAL_VAR_SYMBOL);
6482                                 *p = '\0';
6483                                 repl = encode_then_expand_vararg(exp_word, /*handle_squotes:*/ 1, /*unbackslash:*/ 1);
6484                                 debug_printf_varexp("repl:'%s'->'%s'\n", exp_word, repl);
6485                                 /* HACK ALERT. We depend here on the fact that
6486                                  * G.global_argv and results of utoa and get_local_var_value
6487                                  * are actually in writable memory:
6488                                  * replace_pattern momentarily stores NULs there. */
6489                                 t = (char*)val;
6490                                 to_be_freed = replace_pattern(t,
6491                                                 pattern,
6492                                                 (repl ? repl : exp_word),
6493                                                 exp_op);
6494                                 if (to_be_freed) /* at least one replace happened */
6495                                         val = to_be_freed;
6496                                 free(pattern);
6497                                 free(repl);
6498                         } else {
6499                                 /* Empty variable always gives nothing */
6500                                 // "v=''; echo ${v/*/w}" prints "", not "w"
6501                                 /* Just skip "replace" part */
6502                                 *p++ = SPECIAL_VAR_SYMBOL;
6503                                 p = strchr(p, SPECIAL_VAR_SYMBOL);
6504                                 *p = '\0';
6505                         }
6506                 }
6507 #endif /* BASH_PATTERN_SUBST */
6508                 else if (exp_op == ':') {
6509 #if BASH_SUBSTR && ENABLE_FEATURE_SH_MATH
6510                         /* It's ${var:N[:M]} bashism.
6511                          * Note that in encoded form it has TWO parts:
6512                          * var:N<SPECIAL_VAR_SYMBOL>M<SPECIAL_VAR_SYMBOL>
6513                          */
6514                         arith_t beg, len;
6515                         const char *errmsg;
6516
6517                         beg = expand_and_evaluate_arith(exp_word, &errmsg);
6518                         if (errmsg)
6519                                 goto arith_err;
6520                         debug_printf_varexp("beg:'%s'=%lld\n", exp_word, (long long)beg);
6521                         *p++ = SPECIAL_VAR_SYMBOL;
6522                         exp_word = p;
6523                         p = strchr(p, SPECIAL_VAR_SYMBOL);
6524                         *p = '\0';
6525                         len = expand_and_evaluate_arith(exp_word, &errmsg);
6526                         if (errmsg)
6527                                 goto arith_err;
6528                         debug_printf_varexp("len:'%s'=%lld\n", exp_word, (long long)len);
6529                         if (beg < 0) {
6530                                 /* negative beg counts from the end */
6531                                 beg = (arith_t)strlen(val) + beg;
6532                                 if (beg < 0) /* ${v: -999999} is "" */
6533                                         beg = len = 0;
6534                         }
6535                         debug_printf_varexp("from val:'%s'\n", val);
6536                         if (len < 0) {
6537                                 /* in bash, len=-n means strlen()-n */
6538                                 len = (arith_t)strlen(val) - beg + len;
6539                                 if (len < 0) /* bash compat */
6540                                         msg_and_die_if_script("%s: substring expression < 0", var);
6541                         }
6542                         if (len <= 0 || !val || beg >= strlen(val)) {
6543  arith_err:
6544                                 val = NULL;
6545                         } else {
6546                                 /* Paranoia. What if user entered 9999999999999
6547                                  * which fits in arith_t but not int? */
6548                                 if (len >= INT_MAX)
6549                                         len = INT_MAX;
6550                                 val = to_be_freed = xstrndup(val + beg, len);
6551                         }
6552                         debug_printf_varexp("val:'%s'\n", val);
6553 #else /* not (HUSH_SUBSTR_EXPANSION && FEATURE_SH_MATH) */
6554                         msg_and_die_if_script("malformed ${%s:...}", var);
6555                         val = NULL;
6556 #endif
6557                 } else { /* one of "-=+?" */
6558                         /* Standard-mandated substitution ops:
6559                          * ${var?word} - indicate error if unset
6560                          *      If var is unset, word (or a message indicating it is unset
6561                          *      if word is null) is written to standard error
6562                          *      and the shell exits with a non-zero exit status.
6563                          *      Otherwise, the value of var is substituted.
6564                          * ${var-word} - use default value
6565                          *      If var is unset, word is substituted.
6566                          * ${var=word} - assign and use default value
6567                          *      If var is unset, word is assigned to var.
6568                          *      In all cases, final value of var is substituted.
6569                          * ${var+word} - use alternative value
6570                          *      If var is unset, null is substituted.
6571                          *      Otherwise, word is substituted.
6572                          *
6573                          * Word is subjected to tilde expansion, parameter expansion,
6574                          * command substitution, and arithmetic expansion.
6575                          * If word is not needed, it is not expanded.
6576                          *
6577                          * Colon forms (${var:-word}, ${var:=word} etc) do the same,
6578                          * but also treat null var as if it is unset.
6579                          *
6580                          * Word-splitting and single quote behavior:
6581                          *
6582                          * $ f() { for i; do echo "|$i|"; done; };
6583                          *
6584                          * $ x=; f ${x:?'x y' z}
6585                          * bash: x: x y z              #BUG: does not abort, ${} results in empty expansion
6586                          * $ x=; f "${x:?'x y' z}"
6587                          * bash: x: x y z       # dash prints: dash: x: 'x y' z   #BUG: does not abort, ${} results in ""
6588                          *
6589                          * $ x=; f ${x:='x y' z}
6590                          * |x|
6591                          * |y|
6592                          * |z|
6593                          * $ x=; f "${x:='x y' z}"
6594                          * |'x y' z|
6595                          *
6596                          * $ x=x; f ${x:+'x y' z}
6597                          * |x y|
6598                          * |z|
6599                          * $ x=x; f "${x:+'x y' z}"
6600                          * |'x y' z|
6601                          *
6602                          * $ x=; f ${x:-'x y' z}
6603                          * |x y|
6604                          * |z|
6605                          * $ x=; f "${x:-'x y' z}"
6606                          * |'x y' z|
6607                          */
6608                         int use_word = (!val || ((exp_save == ':') && !val[0]));
6609                         if (exp_op == '+')
6610                                 use_word = !use_word;
6611                         debug_printf_expand("expand: op:%c (null:%s) test:%i\n", exp_op,
6612                                         (exp_save == ':') ? "true" : "false", use_word);
6613                         if (use_word) {
6614                                 if (exp_op == '+' || exp_op == '-') {
6615                                         /* ${var+word} - use alternative value */
6616                                         /* ${var-word} - use default value */
6617                                         n = encode_then_append_var_plusminus(output, n, exp_word,
6618                                                         /*dquoted:*/ (arg0 & 0x80)
6619                                         );
6620                                         val = NULL;
6621                                 } else {
6622                                         /* ${var?word} - indicate error if unset */
6623                                         /* ${var=word} - assign and use default value */
6624                                         to_be_freed = encode_then_expand_vararg(exp_word,
6625                                                         /*handle_squotes:*/ !(arg0 & 0x80),
6626                                                         /*unbackslash:*/ 0
6627                                         );
6628                                         if (to_be_freed)
6629                                                 exp_word = to_be_freed;
6630                                         if (exp_op == '?') {
6631                                                 /* mimic bash message */
6632                                                 msg_and_die_if_script("%s: %s",
6633                                                         var,
6634                                                         exp_word[0]
6635                                                         ? exp_word
6636                                                         : "parameter null or not set"
6637                                                         /* ash has more specific messages, a-la: */
6638                                                         /*: (exp_save == ':' ? "parameter null or not set" : "parameter not set")*/
6639                                                 );
6640 //TODO: how interactive bash aborts expansion mid-command?
6641 //It aborts the entire line, returns to prompt:
6642 // $ f() { for i; do echo "|$i|"; done; }; x=; f "${x:?'x y' z}"; echo YO
6643 // bash: x: x y z
6644 // $
6645 // ("echo YO" is not executed, neither the f function call)
6646                                         } else {
6647                                                 val = exp_word;
6648                                         }
6649                                         if (exp_op == '=') {
6650                                                 /* ${var=[word]} or ${var:=[word]} */
6651                                                 if (isdigit(var[0]) || var[0] == '#') {
6652                                                         /* mimic bash message */
6653                                                         msg_and_die_if_script("$%s: cannot assign in this way", var);
6654                                                         val = NULL;
6655                                                 } else {
6656                                                         char *new_var = xasprintf("%s=%s", var, val);
6657                                                         set_local_var(new_var, /*flag:*/ 0);
6658                                                 }
6659                                         }
6660                                 }
6661                         }
6662                 } /* one of "-=+?" */
6663
6664                 *exp_saveptr = exp_save;
6665         } /* if (exp_op) */
6666
6667         arg[0] = arg0;
6668         *pp = p;
6669
6670         n = append_str_maybe_ifs_split(output, n, first_ch, val);
6671
6672         free(to_be_freed);
6673         return n;
6674 }
6675
6676 /* Expand all variable references in given string, adding words to list[]
6677  * at n, n+1,... positions. Return updated n (so that list[n] is next one
6678  * to be filled). This routine is extremely tricky: has to deal with
6679  * variables/parameters with whitespace, $* and $@, and constructs like
6680  * 'echo -$*-'. If you play here, you must run testsuite afterwards! */
6681 static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg)
6682 {
6683         /* output->o_expflags & EXP_FLAG_SINGLEWORD (0x80) if we are in
6684          * expansion of right-hand side of assignment == 1-element expand.
6685          */
6686         char cant_be_null = 0; /* only bit 0x80 matters */
6687         char *p;
6688
6689         debug_printf_expand("expand_vars_to_list: arg:'%s' singleword:%x\n", arg,
6690                         !!(output->o_expflags & EXP_FLAG_SINGLEWORD));
6691         debug_print_list("expand_vars_to_list[0]", output, n);
6692
6693         while ((p = strchr(arg, SPECIAL_VAR_SYMBOL)) != NULL) {
6694                 char first_ch;
6695 #if ENABLE_FEATURE_SH_MATH
6696                 char arith_buf[sizeof(arith_t)*3 + 2];
6697 #endif
6698
6699                 if (output->ended_in_ifs) {
6700                         o_addchr(output, '\0');
6701                         n = o_save_ptr(output, n);
6702                         output->ended_in_ifs = 0;
6703                 }
6704
6705                 o_addblock(output, arg, p - arg);
6706                 debug_print_list("expand_vars_to_list[1]", output, n);
6707                 arg = ++p;
6708                 p = strchr(p, SPECIAL_VAR_SYMBOL);
6709
6710                 /* Fetch special var name (if it is indeed one of them)
6711                  * and quote bit, force the bit on if singleword expansion -
6712                  * important for not getting v=$@ expand to many words. */
6713                 first_ch = arg[0] | (output->o_expflags & EXP_FLAG_SINGLEWORD);
6714
6715                 /* Is this variable quoted and thus expansion can't be null?
6716                  * "$@" is special. Even if quoted, it can still
6717                  * expand to nothing (not even an empty string),
6718                  * thus it is excluded. */
6719                 if ((first_ch & 0x7f) != '@')
6720                         cant_be_null |= first_ch;
6721
6722                 switch (first_ch & 0x7f) {
6723                 /* Highest bit in first_ch indicates that var is double-quoted */
6724                 case '*':
6725                 case '@': {
6726                         int i;
6727                         if (!G.global_argv[1])
6728                                 break;
6729                         i = 1;
6730                         cant_be_null |= first_ch; /* do it for "$@" _now_, when we know it's not empty */
6731                         if (!(first_ch & 0x80)) { /* unquoted $* or $@ */
6732                                 while (G.global_argv[i]) {
6733                                         n = expand_on_ifs(output, n, G.global_argv[i]);
6734                                         debug_printf_expand("expand_vars_to_list: argv %d (last %d)\n", i, G.global_argc - 1);
6735                                         if (G.global_argv[i++][0] && G.global_argv[i]) {
6736                                                 /* this argv[] is not empty and not last:
6737                                                  * put terminating NUL, start new word */
6738                                                 o_addchr(output, '\0');
6739                                                 debug_print_list("expand_vars_to_list[2]", output, n);
6740                                                 n = o_save_ptr(output, n);
6741                                                 debug_print_list("expand_vars_to_list[3]", output, n);
6742                                         }
6743                                 }
6744                         } else
6745                         /* If EXP_FLAG_SINGLEWORD, we handle assignment 'a=....$@.....'
6746                          * and in this case should treat it like '$*' - see 'else...' below */
6747                         if (first_ch == (char)('@'|0x80)  /* quoted $@ */
6748                          && !(output->o_expflags & EXP_FLAG_SINGLEWORD) /* not v="$@" case */
6749                         ) {
6750                                 while (1) {
6751                                         o_addQstr(output, G.global_argv[i]);
6752                                         if (++i >= G.global_argc)
6753                                                 break;
6754                                         o_addchr(output, '\0');
6755                                         debug_print_list("expand_vars_to_list[4]", output, n);
6756                                         n = o_save_ptr(output, n);
6757                                 }
6758                         } else { /* quoted $* (or v="$@" case): add as one word */
6759                                 while (1) {
6760                                         o_addQstr(output, G.global_argv[i]);
6761                                         if (!G.global_argv[++i])
6762                                                 break;
6763                                         if (G.ifs[0])
6764                                                 o_addchr(output, G.ifs[0]);
6765                                 }
6766                                 output->has_quoted_part = 1;
6767                         }
6768                         break;
6769                 }
6770                 case SPECIAL_VAR_SYMBOL: {
6771                         /* <SPECIAL_VAR_SYMBOL><SPECIAL_VAR_SYMBOL> */
6772                         /* "Empty variable", used to make "" etc to not disappear */
6773                         output->has_quoted_part = 1;
6774                         cant_be_null = 0x80;
6775                         arg++;
6776                         break;
6777                 }
6778                 case SPECIAL_VAR_QUOTED_SVS:
6779                         /* <SPECIAL_VAR_SYMBOL><SPECIAL_VAR_QUOTED_SVS><SPECIAL_VAR_SYMBOL> */
6780                         /* "^C variable", represents literal ^C char (possible in scripts) */
6781                         o_addchr(output, SPECIAL_VAR_SYMBOL);
6782                         arg++;
6783                         break;
6784 #if ENABLE_HUSH_TICK
6785                 case '`': {
6786                         /* <SPECIAL_VAR_SYMBOL>`cmd<SPECIAL_VAR_SYMBOL> */
6787                         o_string subst_result = NULL_O_STRING;
6788
6789                         *p = '\0'; /* replace trailing <SPECIAL_VAR_SYMBOL> */
6790                         arg++;
6791                         /* Can't just stuff it into output o_string,
6792                          * expanded result may need to be globbed
6793                          * and $IFS-split */
6794                         debug_printf_subst("SUBST '%s' first_ch %x\n", arg, first_ch);
6795                         G.last_exitcode = process_command_subs(&subst_result, arg);
6796                         G.expand_exitcode = G.last_exitcode;
6797                         debug_printf_subst("SUBST RES:%d '%s'\n", G.last_exitcode, subst_result.data);
6798                         n = append_str_maybe_ifs_split(output, n, first_ch, subst_result.data);
6799                         o_free(&subst_result);
6800                         break;
6801                 }
6802 #endif
6803 #if ENABLE_FEATURE_SH_MATH
6804                 case '+': {
6805                         /* <SPECIAL_VAR_SYMBOL>+arith<SPECIAL_VAR_SYMBOL> */
6806                         arith_t res;
6807
6808                         arg++; /* skip '+' */
6809                         *p = '\0'; /* replace trailing <SPECIAL_VAR_SYMBOL> */
6810                         debug_printf_subst("ARITH '%s' first_ch %x\n", arg, first_ch);
6811                         res = expand_and_evaluate_arith(arg, NULL);
6812                         debug_printf_subst("ARITH RES '"ARITH_FMT"'\n", res);
6813                         sprintf(arith_buf, ARITH_FMT, res);
6814                         o_addstr(output, arith_buf);
6815                         break;
6816                 }
6817 #endif
6818                 default:
6819                         /* <SPECIAL_VAR_SYMBOL>varname[ops]<SPECIAL_VAR_SYMBOL> */
6820                         n = expand_one_var(output, n, first_ch, arg, &p);
6821                         break;
6822                 } /* switch (char after <SPECIAL_VAR_SYMBOL>) */
6823
6824                 /* Restore NULL'ed SPECIAL_VAR_SYMBOL.
6825                  * Do the check to avoid writing to a const string. */
6826                 if (*p != SPECIAL_VAR_SYMBOL)
6827                         *p = SPECIAL_VAR_SYMBOL;
6828                 arg = ++p;
6829         } /* end of "while (SPECIAL_VAR_SYMBOL is found) ..." */
6830
6831         if (*arg) {
6832                 /* handle trailing string */
6833                 if (output->ended_in_ifs) {
6834                         o_addchr(output, '\0');
6835                         n = o_save_ptr(output, n);
6836                 }
6837                 debug_print_list("expand_vars_to_list[a]", output, n);
6838                 /* this part is literal, and it was already pre-quoted
6839                  * if needed (much earlier), do not use o_addQstr here!
6840                  */
6841                 o_addstr(output, arg);
6842                 debug_print_list("expand_vars_to_list[b]", output, n);
6843         } else
6844         if (output->length == o_get_last_ptr(output, n) /* expansion is empty */
6845          && !(cant_be_null & 0x80)   /* and all vars were not quoted */
6846          && !output->has_quoted_part
6847         ) {
6848                 n--;
6849                 /* allow to reuse list[n] later without re-growth */
6850                 output->has_empty_slot = 1;
6851         }
6852
6853         return n;
6854 }
6855
6856 static char **expand_variables(char **argv, unsigned expflags)
6857 {
6858         int n;
6859         char **list;
6860         o_string output = NULL_O_STRING;
6861
6862         output.o_expflags = expflags;
6863
6864         n = 0;
6865         for (;;) {
6866                 /* go to next list[n] */
6867                 output.ended_in_ifs = 0;
6868                 n = o_save_ptr(&output, n);
6869
6870                 if (!*argv)
6871                         break;
6872
6873                 /* expand argv[i] */
6874                 n = expand_vars_to_list(&output, n, *argv++);
6875                 /* if (!output->has_empty_slot) -- need this?? */
6876                         o_addchr(&output, '\0');
6877         }
6878         debug_print_list("expand_variables", &output, n);
6879
6880         /* output.data (malloced in one block) gets returned in "list" */
6881         list = o_finalize_list(&output, n);
6882         debug_print_strings("expand_variables[1]", list);
6883         return list;
6884 }
6885
6886 static char **expand_strvec_to_strvec(char **argv)
6887 {
6888         return expand_variables(argv, EXP_FLAG_GLOB | EXP_FLAG_ESC_GLOB_CHARS);
6889 }
6890
6891 #if defined(CMD_SINGLEWORD_NOGLOB)
6892 static char **expand_strvec_to_strvec_singleword_noglob(char **argv)
6893 {
6894         return expand_variables(argv, EXP_FLAG_SINGLEWORD);
6895 }
6896 #endif
6897
6898 /* Used for expansion of right hand of assignments,
6899  * $((...)), heredocs, variable expansion parts.
6900  *
6901  * NB: should NOT do globbing!
6902  * "export v=/bin/c*; env | grep ^v=" outputs "v=/bin/c*"
6903  */
6904 static char *expand_string_to_string(const char *str, int EXP_flags, int do_unbackslash)
6905 {
6906 #if !BASH_PATTERN_SUBST && !ENABLE_HUSH_CASE
6907         const int do_unbackslash = 1;
6908         const int EXP_flags = EXP_FLAG_ESC_GLOB_CHARS;
6909 #endif
6910         char *argv[2], **list;
6911
6912         debug_printf_expand("string_to_string<='%s'\n", str);
6913         /* This is generally an optimization, but it also
6914          * handles "", which otherwise trips over !list[0] check below.
6915          * (is this ever happens that we actually get str="" here?)
6916          */
6917         if (!strchr(str, SPECIAL_VAR_SYMBOL) && !strchr(str, '\\')) {
6918                 //TODO: Can use on strings with \ too, just unbackslash() them?
6919                 debug_printf_expand("string_to_string(fast)=>'%s'\n", str);
6920                 return xstrdup(str);
6921         }
6922
6923         argv[0] = (char*)str;
6924         argv[1] = NULL;
6925         list = expand_variables(argv, EXP_flags | EXP_FLAG_SINGLEWORD);
6926         if (!list[0]) {
6927                 /* Example where it happens:
6928                  * x=; echo ${x:-"$@"}
6929                  */
6930                 ((char*)list)[0] = '\0';
6931         } else {
6932                 if (HUSH_DEBUG)
6933                         if (list[1])
6934                                 bb_error_msg_and_die("BUG in varexp2");
6935                 /* actually, just move string 2*sizeof(char*) bytes back */
6936                 overlapping_strcpy((char*)list, list[0]);
6937                 if (do_unbackslash)
6938                         unbackslash((char*)list);
6939         }
6940         debug_printf_expand("string_to_string=>'%s'\n", (char*)list);
6941         return (char*)list;
6942 }
6943
6944 #if 0
6945 static char* expand_strvec_to_string(char **argv)
6946 {
6947         char **list;
6948
6949         list = expand_variables(argv, EXP_FLAG_SINGLEWORD);
6950         /* Convert all NULs to spaces */
6951         if (list[0]) {
6952                 int n = 1;
6953                 while (list[n]) {
6954                         if (HUSH_DEBUG)
6955                                 if (list[n-1] + strlen(list[n-1]) + 1 != list[n])
6956                                         bb_error_msg_and_die("BUG in varexp3");
6957                         /* bash uses ' ' regardless of $IFS contents */
6958                         list[n][-1] = ' ';
6959                         n++;
6960                 }
6961         }
6962         overlapping_strcpy((char*)list, list[0] ? list[0] : "");
6963         debug_printf_expand("strvec_to_string='%s'\n", (char*)list);
6964         return (char*)list;
6965 }
6966 #endif
6967
6968 static char **expand_assignments(char **argv, int count)
6969 {
6970         int i;
6971         char **p;
6972
6973         G.expanded_assignments = p = NULL;
6974         /* Expand assignments into one string each */
6975         for (i = 0; i < count; i++) {
6976                 p = add_string_to_strings(p,
6977                         expand_string_to_string(argv[i],
6978                                 EXP_FLAG_ESC_GLOB_CHARS,
6979                                 /*unbackslash:*/ 1
6980                         )
6981                 );
6982                 G.expanded_assignments = p;
6983         }
6984         G.expanded_assignments = NULL;
6985         return p;
6986 }
6987
6988
6989 static void switch_off_special_sigs(unsigned mask)
6990 {
6991         unsigned sig = 0;
6992         while ((mask >>= 1) != 0) {
6993                 sig++;
6994                 if (!(mask & 1))
6995                         continue;
6996 #if ENABLE_HUSH_TRAP
6997                 if (G_traps) {
6998                         if (G_traps[sig] && !G_traps[sig][0])
6999                                 /* trap is '', has to remain SIG_IGN */
7000                                 continue;
7001                         free(G_traps[sig]);
7002                         G_traps[sig] = NULL;
7003                 }
7004 #endif
7005                 /* We are here only if no trap or trap was not '' */
7006                 install_sighandler(sig, SIG_DFL);
7007         }
7008 }
7009
7010 #if BB_MMU
7011 /* never called */
7012 void re_execute_shell(char ***to_free, const char *s,
7013                 char *g_argv0, char **g_argv,
7014                 char **builtin_argv) NORETURN;
7015
7016 static void reset_traps_to_defaults(void)
7017 {
7018         /* This function is always called in a child shell
7019          * after fork (not vfork, NOMMU doesn't use this function).
7020          */
7021         IF_HUSH_TRAP(unsigned sig;)
7022         unsigned mask;
7023
7024         /* Child shells are not interactive.
7025          * SIGTTIN/SIGTTOU/SIGTSTP should not have special handling.
7026          * Testcase: (while :; do :; done) + ^Z should background.
7027          * Same goes for SIGTERM, SIGHUP, SIGINT.
7028          */
7029         mask = (G.special_sig_mask & SPECIAL_INTERACTIVE_SIGS) | G_fatal_sig_mask;
7030         if (!G_traps && !mask)
7031                 return; /* already no traps and no special sigs */
7032
7033         /* Switch off special sigs */
7034         switch_off_special_sigs(mask);
7035 # if ENABLE_HUSH_JOB
7036         G_fatal_sig_mask = 0;
7037 # endif
7038         G.special_sig_mask &= ~SPECIAL_INTERACTIVE_SIGS;
7039         /* SIGQUIT,SIGCHLD and maybe SPECIAL_JOBSTOP_SIGS
7040          * remain set in G.special_sig_mask */
7041
7042 # if ENABLE_HUSH_TRAP
7043         if (!G_traps)
7044                 return;
7045
7046         /* Reset all sigs to default except ones with empty traps */
7047         for (sig = 0; sig < NSIG; sig++) {
7048                 if (!G_traps[sig])
7049                         continue; /* no trap: nothing to do */
7050                 if (!G_traps[sig][0])
7051                         continue; /* empty trap: has to remain SIG_IGN */
7052                 /* sig has non-empty trap, reset it: */
7053                 free(G_traps[sig]);
7054                 G_traps[sig] = NULL;
7055                 /* There is no signal for trap 0 (EXIT) */
7056                 if (sig == 0)
7057                         continue;
7058                 install_sighandler(sig, pick_sighandler(sig));
7059         }
7060 # endif
7061 }
7062
7063 #else /* !BB_MMU */
7064
7065 static void re_execute_shell(char ***to_free, const char *s,
7066                 char *g_argv0, char **g_argv,
7067                 char **builtin_argv) NORETURN;
7068 static void re_execute_shell(char ***to_free, const char *s,
7069                 char *g_argv0, char **g_argv,
7070                 char **builtin_argv)
7071 {
7072 # define NOMMU_HACK_FMT ("-$%x:%x:%x:%x:%x:%llx" IF_HUSH_LOOPS(":%x"))
7073         /* delims + 2 * (number of bytes in printed hex numbers) */
7074         char param_buf[sizeof(NOMMU_HACK_FMT) + 2 * (sizeof(int)*6 + sizeof(long long)*1)];
7075         char *heredoc_argv[4];
7076         struct variable *cur;
7077 # if ENABLE_HUSH_FUNCTIONS
7078         struct function *funcp;
7079 # endif
7080         char **argv, **pp;
7081         unsigned cnt;
7082         unsigned long long empty_trap_mask;
7083
7084         if (!g_argv0) { /* heredoc */
7085                 argv = heredoc_argv;
7086                 argv[0] = (char *) G.argv0_for_re_execing;
7087                 argv[1] = (char *) "-<";
7088                 argv[2] = (char *) s;
7089                 argv[3] = NULL;
7090                 pp = &argv[3]; /* used as pointer to empty environment */
7091                 goto do_exec;
7092         }
7093
7094         cnt = 0;
7095         pp = builtin_argv;
7096         if (pp) while (*pp++)
7097                 cnt++;
7098
7099         empty_trap_mask = 0;
7100         if (G_traps) {
7101                 int sig;
7102                 for (sig = 1; sig < NSIG; sig++) {
7103                         if (G_traps[sig] && !G_traps[sig][0])
7104                                 empty_trap_mask |= 1LL << sig;
7105                 }
7106         }
7107
7108         sprintf(param_buf, NOMMU_HACK_FMT
7109                         , (unsigned) G.root_pid
7110                         , (unsigned) G.root_ppid
7111                         , (unsigned) G.last_bg_pid
7112                         , (unsigned) G.last_exitcode
7113                         , cnt
7114                         , empty_trap_mask
7115                         IF_HUSH_LOOPS(, G.depth_of_loop)
7116                         );
7117 # undef NOMMU_HACK_FMT
7118         /* 1:hush 2:-$<pid>:<pid>:<exitcode>:<etc...> <vars...> <funcs...>
7119          * 3:-c 4:<cmd> 5:<arg0> <argN...> 6:NULL
7120          */
7121         cnt += 6;
7122         for (cur = G.top_var; cur; cur = cur->next) {
7123                 if (!cur->flg_export || cur->flg_read_only)
7124                         cnt += 2;
7125         }
7126 # if ENABLE_HUSH_FUNCTIONS
7127         for (funcp = G.top_func; funcp; funcp = funcp->next)
7128                 cnt += 3;
7129 # endif
7130         pp = g_argv;
7131         while (*pp++)
7132                 cnt++;
7133         *to_free = argv = pp = xzalloc(sizeof(argv[0]) * cnt);
7134         *pp++ = (char *) G.argv0_for_re_execing;
7135         *pp++ = param_buf;
7136         for (cur = G.top_var; cur; cur = cur->next) {
7137                 if (strcmp(cur->varstr, hush_version_str) == 0)
7138                         continue;
7139                 if (cur->flg_read_only) {
7140                         *pp++ = (char *) "-R";
7141                         *pp++ = cur->varstr;
7142                 } else if (!cur->flg_export) {
7143                         *pp++ = (char *) "-V";
7144                         *pp++ = cur->varstr;
7145                 }
7146         }
7147 # if ENABLE_HUSH_FUNCTIONS
7148         for (funcp = G.top_func; funcp; funcp = funcp->next) {
7149                 *pp++ = (char *) "-F";
7150                 *pp++ = funcp->name;
7151                 *pp++ = funcp->body_as_string;
7152         }
7153 # endif
7154         /* We can pass activated traps here. Say, -Tnn:trap_string
7155          *
7156          * However, POSIX says that subshells reset signals with traps
7157          * to SIG_DFL.
7158          * I tested bash-3.2 and it not only does that with true subshells
7159          * of the form ( list ), but with any forked children shells.
7160          * I set trap "echo W" WINCH; and then tried:
7161          *
7162          * { echo 1; sleep 20; echo 2; } &
7163          * while true; do echo 1; sleep 20; echo 2; break; done &
7164          * true | { echo 1; sleep 20; echo 2; } | cat
7165          *
7166          * In all these cases sending SIGWINCH to the child shell
7167          * did not run the trap. If I add trap "echo V" WINCH;
7168          * _inside_ group (just before echo 1), it works.
7169          *
7170          * I conclude it means we don't need to pass active traps here.
7171          */
7172         *pp++ = (char *) "-c";
7173         *pp++ = (char *) s;
7174         if (builtin_argv) {
7175                 while (*++builtin_argv)
7176                         *pp++ = *builtin_argv;
7177                 *pp++ = (char *) "";
7178         }
7179         *pp++ = g_argv0;
7180         while (*g_argv)
7181                 *pp++ = *g_argv++;
7182         /* *pp = NULL; - is already there */
7183         pp = environ;
7184
7185  do_exec:
7186         debug_printf_exec("re_execute_shell pid:%d cmd:'%s'\n", getpid(), s);
7187         /* Don't propagate SIG_IGN to the child */
7188         if (SPECIAL_JOBSTOP_SIGS != 0)
7189                 switch_off_special_sigs(G.special_sig_mask & SPECIAL_JOBSTOP_SIGS);
7190         execve(bb_busybox_exec_path, argv, pp);
7191         /* Fallback. Useful for init=/bin/hush usage etc */
7192         if (argv[0][0] == '/')
7193                 execve(argv[0], argv, pp);
7194         xfunc_error_retval = 127;
7195         bb_error_msg_and_die("can't re-execute the shell");
7196 }
7197 #endif  /* !BB_MMU */
7198
7199
7200 static int run_and_free_list(struct pipe *pi);
7201
7202 /* Executing from string: eval, sh -c '...'
7203  *          or from file: /etc/profile, . file, sh <script>, sh (intereactive)
7204  * end_trigger controls how often we stop parsing
7205  * NUL: parse all, execute, return
7206  * ';': parse till ';' or newline, execute, repeat till EOF
7207  */
7208 static void parse_and_run_stream(struct in_str *inp, int end_trigger)
7209 {
7210         /* Why we need empty flag?
7211          * An obscure corner case "false; ``; echo $?":
7212          * empty command in `` should still set $? to 0.
7213          * But we can't just set $? to 0 at the start,
7214          * this breaks "false; echo `echo $?`" case.
7215          */
7216         bool empty = 1;
7217         while (1) {
7218                 struct pipe *pipe_list;
7219
7220 #if ENABLE_HUSH_INTERACTIVE
7221                 if (end_trigger == ';') {
7222                         G.promptmode = 0; /* PS1 */
7223                         debug_printf_prompt("%s promptmode=%d\n", __func__, G.promptmode);
7224                 }
7225 #endif
7226                 pipe_list = parse_stream(NULL, NULL, inp, end_trigger);
7227                 if (!pipe_list || pipe_list == ERR_PTR) { /* EOF/error */
7228                         /* If we are in "big" script
7229                          * (not in `cmd` or something similar)...
7230                          */
7231                         if (pipe_list == ERR_PTR && end_trigger == ';') {
7232                                 /* Discard cached input (rest of line) */
7233                                 int ch = inp->last_char;
7234                                 while (ch != EOF && ch != '\n') {
7235                                         //bb_error_msg("Discarded:'%c'", ch);
7236                                         ch = i_getch(inp);
7237                                 }
7238                                 /* Force prompt */
7239                                 inp->p = NULL;
7240                                 /* This stream isn't empty */
7241                                 empty = 0;
7242                                 continue;
7243                         }
7244                         if (!pipe_list && empty)
7245                                 G.last_exitcode = 0;
7246                         break;
7247                 }
7248                 debug_print_tree(pipe_list, 0);
7249                 debug_printf_exec("parse_and_run_stream: run_and_free_list\n");
7250                 run_and_free_list(pipe_list);
7251                 empty = 0;
7252                 if (G_flag_return_in_progress == 1)
7253                         break;
7254         }
7255 }
7256
7257 static void parse_and_run_string(const char *s)
7258 {
7259         struct in_str input;
7260         //IF_HUSH_LINENO_VAR(unsigned sv = G.parse_lineno;)
7261
7262         setup_string_in_str(&input, s);
7263         parse_and_run_stream(&input, '\0');
7264         //IF_HUSH_LINENO_VAR(G.parse_lineno = sv;)
7265 }
7266
7267 static void parse_and_run_file(HFILE *fp)
7268 {
7269         struct in_str input;
7270         IF_HUSH_LINENO_VAR(unsigned sv = G.parse_lineno;)
7271
7272         IF_HUSH_LINENO_VAR(G.parse_lineno = 1;)
7273         setup_file_in_str(&input, fp);
7274         parse_and_run_stream(&input, ';');
7275         IF_HUSH_LINENO_VAR(G.parse_lineno = sv;)
7276 }
7277
7278 #if ENABLE_HUSH_TICK
7279 static int generate_stream_from_string(const char *s, pid_t *pid_p)
7280 {
7281         pid_t pid;
7282         int channel[2];
7283 # if !BB_MMU
7284         char **to_free = NULL;
7285 # endif
7286
7287         xpipe(channel);
7288         pid = BB_MMU ? xfork() : xvfork();
7289         if (pid == 0) { /* child */
7290                 disable_restore_tty_pgrp_on_exit();
7291                 /* Process substitution is not considered to be usual
7292                  * 'command execution'.
7293                  * SUSv3 says ctrl-Z should be ignored, ctrl-C should not.
7294                  */
7295                 bb_signals(0
7296                         + (1 << SIGTSTP)
7297                         + (1 << SIGTTIN)
7298                         + (1 << SIGTTOU)
7299                         , SIG_IGN);
7300                 close(channel[0]); /* NB: close _first_, then move fd! */
7301                 xmove_fd(channel[1], 1);
7302 # if ENABLE_HUSH_TRAP
7303                 /* Awful hack for `trap` or $(trap).
7304                  *
7305                  * http://www.opengroup.org/onlinepubs/009695399/utilities/trap.html
7306                  * contains an example where "trap" is executed in a subshell:
7307                  *
7308                  * save_traps=$(trap)
7309                  * ...
7310                  * eval "$save_traps"
7311                  *
7312                  * Standard does not say that "trap" in subshell shall print
7313                  * parent shell's traps. It only says that its output
7314                  * must have suitable form, but then, in the above example
7315                  * (which is not supposed to be normative), it implies that.
7316                  *
7317                  * bash (and probably other shell) does implement it
7318                  * (traps are reset to defaults, but "trap" still shows them),
7319                  * but as a result, "trap" logic is hopelessly messed up:
7320                  *
7321                  * # trap
7322                  * trap -- 'echo Ho' SIGWINCH  <--- we have a handler
7323                  * # (trap)        <--- trap is in subshell - no output (correct, traps are reset)
7324                  * # true | trap   <--- trap is in subshell - no output (ditto)
7325                  * # echo `true | trap`    <--- in subshell - output (but traps are reset!)
7326                  * trap -- 'echo Ho' SIGWINCH
7327                  * # echo `(trap)`         <--- in subshell in subshell - output
7328                  * trap -- 'echo Ho' SIGWINCH
7329                  * # echo `true | (trap)`  <--- in subshell in subshell in subshell - output!
7330                  * trap -- 'echo Ho' SIGWINCH
7331                  *
7332                  * The rules when to forget and when to not forget traps
7333                  * get really complex and nonsensical.
7334                  *
7335                  * Our solution: ONLY bare $(trap) or `trap` is special.
7336                  */
7337                 s = skip_whitespace(s);
7338                 if (is_prefixed_with(s, "trap")
7339                  && skip_whitespace(s + 4)[0] == '\0'
7340                 ) {
7341                         static const char *const argv[] = { NULL, NULL };
7342                         builtin_trap((char**)argv);
7343                         fflush_all(); /* important */
7344                         _exit(0);
7345                 }
7346 # endif
7347 # if BB_MMU
7348                 /* Prevent it from trying to handle ctrl-z etc */
7349                 IF_HUSH_JOB(G.run_list_level = 1;)
7350                 CLEAR_RANDOM_T(&G.random_gen); /* or else $RANDOM repeats in child */
7351                 reset_traps_to_defaults();
7352                 IF_HUSH_MODE_X(G.x_mode_depth++;)
7353                 //bb_error_msg("%s: ++x_mode_depth=%d", __func__, G.x_mode_depth);
7354                 parse_and_run_string(s);
7355                 _exit(G.last_exitcode);
7356 # else
7357         /* We re-execute after vfork on NOMMU. This makes this script safe:
7358          * yes "0123456789012345678901234567890" | dd bs=32 count=64k >BIG
7359          * huge=`cat BIG` # was blocking here forever
7360          * echo OK
7361          */
7362                 re_execute_shell(&to_free,
7363                                 s,
7364                                 G.global_argv[0],
7365                                 G.global_argv + 1,
7366                                 NULL);
7367 # endif
7368         }
7369
7370         /* parent */
7371         *pid_p = pid;
7372 # if ENABLE_HUSH_FAST
7373         G.count_SIGCHLD++;
7374 //bb_error_msg("[%d] fork in generate_stream_from_string:"
7375 //              " G.count_SIGCHLD:%d G.handled_SIGCHLD:%d",
7376 //              getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
7377 # endif
7378         enable_restore_tty_pgrp_on_exit();
7379 # if !BB_MMU
7380         free(to_free);
7381 # endif
7382         close(channel[1]);
7383         return channel[0];
7384 }
7385
7386 /* Return code is exit status of the process that is run. */
7387 static int process_command_subs(o_string *dest, const char *s)
7388 {
7389         FILE *fp;
7390         pid_t pid;
7391         int status, ch, eol_cnt;
7392
7393         fp = xfdopen_for_read(generate_stream_from_string(s, &pid));
7394
7395         /* Now send results of command back into original context */
7396         eol_cnt = 0;
7397         while ((ch = getc(fp)) != EOF) {
7398                 if (ch == '\0')
7399                         continue;
7400                 if (ch == '\n') {
7401                         eol_cnt++;
7402                         continue;
7403                 }
7404                 while (eol_cnt) {
7405                         o_addchr(dest, '\n');
7406                         eol_cnt--;
7407                 }
7408                 o_addQchr(dest, ch);
7409         }
7410
7411         debug_printf("done reading from `cmd` pipe, closing it\n");
7412         fclose(fp);
7413         /* We need to extract exitcode. Test case
7414          * "true; echo `sleep 1; false` $?"
7415          * should print 1 */
7416         safe_waitpid(pid, &status, 0);
7417         debug_printf("child exited. returning its exitcode:%d\n", WEXITSTATUS(status));
7418         return WEXITSTATUS(status);
7419 }
7420 #endif /* ENABLE_HUSH_TICK */
7421
7422
7423 static void setup_heredoc(struct redir_struct *redir)
7424 {
7425         struct fd_pair pair;
7426         pid_t pid;
7427         int len, written;
7428         /* the _body_ of heredoc (misleading field name) */
7429         const char *heredoc = redir->rd_filename;
7430         char *expanded;
7431 #if !BB_MMU
7432         char **to_free;
7433 #endif
7434
7435         expanded = NULL;
7436         if (!(redir->rd_dup & HEREDOC_QUOTED)) {
7437                 expanded = encode_then_expand_string(heredoc);
7438                 if (expanded)
7439                         heredoc = expanded;
7440         }
7441         len = strlen(heredoc);
7442
7443         close(redir->rd_fd); /* often saves dup2+close in xmove_fd */
7444         xpiped_pair(pair);
7445         xmove_fd(pair.rd, redir->rd_fd);
7446
7447         /* Try writing without forking. Newer kernels have
7448          * dynamically growing pipes. Must use non-blocking write! */
7449         ndelay_on(pair.wr);
7450         while (1) {
7451                 written = write(pair.wr, heredoc, len);
7452                 if (written <= 0)
7453                         break;
7454                 len -= written;
7455                 if (len == 0) {
7456                         close(pair.wr);
7457                         free(expanded);
7458                         return;
7459                 }
7460                 heredoc += written;
7461         }
7462         ndelay_off(pair.wr);
7463
7464         /* Okay, pipe buffer was not big enough */
7465         /* Note: we must not create a stray child (bastard? :)
7466          * for the unsuspecting parent process. Child creates a grandchild
7467          * and exits before parent execs the process which consumes heredoc
7468          * (that exec happens after we return from this function) */
7469 #if !BB_MMU
7470         to_free = NULL;
7471 #endif
7472         pid = xvfork();
7473         if (pid == 0) {
7474                 /* child */
7475                 disable_restore_tty_pgrp_on_exit();
7476                 pid = BB_MMU ? xfork() : xvfork();
7477                 if (pid != 0)
7478                         _exit(0);
7479                 /* grandchild */
7480                 close(redir->rd_fd); /* read side of the pipe */
7481 #if BB_MMU
7482                 full_write(pair.wr, heredoc, len); /* may loop or block */
7483                 _exit(0);
7484 #else
7485                 /* Delegate blocking writes to another process */
7486                 xmove_fd(pair.wr, STDOUT_FILENO);
7487                 re_execute_shell(&to_free, heredoc, NULL, NULL, NULL);
7488 #endif
7489         }
7490         /* parent */
7491 #if ENABLE_HUSH_FAST
7492         G.count_SIGCHLD++;
7493 //bb_error_msg("[%d] fork in setup_heredoc: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
7494 #endif
7495         enable_restore_tty_pgrp_on_exit();
7496 #if !BB_MMU
7497         free(to_free);
7498 #endif
7499         close(pair.wr);
7500         free(expanded);
7501         wait(NULL); /* wait till child has died */
7502 }
7503
7504 struct squirrel {
7505         int orig_fd;
7506         int moved_to;
7507         /* moved_to = n: fd was moved to n; restore back to orig_fd after redir */
7508         /* moved_to = -1: fd was opened by redirect; close orig_fd after redir */
7509 };
7510
7511 static struct squirrel *append_squirrel(struct squirrel *sq, int i, int orig, int moved)
7512 {
7513         sq = xrealloc(sq, (i + 2) * sizeof(sq[0]));
7514         sq[i].orig_fd = orig;
7515         sq[i].moved_to = moved;
7516         sq[i+1].orig_fd = -1; /* end marker */
7517         return sq;
7518 }
7519
7520 static struct squirrel *add_squirrel(struct squirrel *sq, int fd, int avoid_fd)
7521 {
7522         int moved_to;
7523         int i;
7524
7525         i = 0;
7526         if (sq) for (; sq[i].orig_fd >= 0; i++) {
7527                 /* If we collide with an already moved fd... */
7528                 if (fd == sq[i].moved_to) {
7529                         sq[i].moved_to = dup_CLOEXEC(sq[i].moved_to, avoid_fd);
7530                         debug_printf_redir("redirect_fd %d: already busy, moving to %d\n", fd, sq[i].moved_to);
7531                         if (sq[i].moved_to < 0) /* what? */
7532                                 xfunc_die();
7533                         return sq;
7534                 }
7535                 if (fd == sq[i].orig_fd) {
7536                         /* Example: echo Hello >/dev/null 1>&2 */
7537                         debug_printf_redir("redirect_fd %d: already moved\n", fd);
7538                         return sq;
7539                 }
7540         }
7541
7542         /* If this fd is open, we move and remember it; if it's closed, moved_to = -1 */
7543         moved_to = dup_CLOEXEC(fd, avoid_fd);
7544         debug_printf_redir("redirect_fd %d: previous fd is moved to %d (-1 if it was closed)\n", fd, moved_to);
7545         if (moved_to < 0 && errno != EBADF)
7546                 xfunc_die();
7547         return append_squirrel(sq, i, fd, moved_to);
7548 }
7549
7550 static struct squirrel *add_squirrel_closed(struct squirrel *sq, int fd)
7551 {
7552         int i;
7553
7554         i = 0;
7555         if (sq) for (; sq[i].orig_fd >= 0; i++) {
7556                 /* If we collide with an already moved fd... */
7557                 if (fd == sq[i].orig_fd) {
7558                         /* Examples:
7559                          * "echo 3>FILE 3>&- 3>FILE"
7560                          * "echo 3>&- 3>FILE"
7561                          * No need for last redirect to insert
7562                          * another "need to close 3" indicator.
7563                          */
7564                         debug_printf_redir("redirect_fd %d: already moved or closed\n", fd);
7565                         return sq;
7566                 }
7567         }
7568
7569         debug_printf_redir("redirect_fd %d: previous fd was closed\n", fd);
7570         return append_squirrel(sq, i, fd, -1);
7571 }
7572
7573 /* fd: redirect wants this fd to be used (e.g. 3>file).
7574  * Move all conflicting internally used fds,
7575  * and remember them so that we can restore them later.
7576  */
7577 static int save_fd_on_redirect(int fd, int avoid_fd, struct squirrel **sqp)
7578 {
7579         if (avoid_fd < 9) /* the important case here is that it can be -1 */
7580                 avoid_fd = 9;
7581
7582 #if ENABLE_HUSH_INTERACTIVE
7583         if (fd == G_interactive_fd) {
7584                 /* Testcase: "ls -l /proc/$$/fd 255>&-" should work */
7585                 G_interactive_fd = xdup_CLOEXEC_and_close(G_interactive_fd, avoid_fd);
7586                 debug_printf_redir("redirect_fd %d: matches interactive_fd, moving it to %d\n", fd, G_interactive_fd);
7587                 return 1; /* "we closed fd" */
7588         }
7589 #endif
7590         /* Are we called from setup_redirects(squirrel==NULL)
7591          * in redirect in a [v]forked child?
7592          */
7593         if (sqp == NULL) {
7594                 /* No need to move script fds.
7595                  * For NOMMU case, it's actively wrong: we'd change ->fd
7596                  * fields in memory for the parent, but parent's fds
7597                  * aren't be moved, it would use wrong fd!
7598                  * Reproducer: "cmd 3>FILE" in script.
7599                  * If we would call move_HFILEs_on_redirect(), child would:
7600                  *  fcntl64(3, F_DUPFD_CLOEXEC, 10)   = 10
7601                  *  close(3)                          = 0
7602                  * and change ->fd to 10 if fd#3 is a script fd. WRONG.
7603                  */
7604                 //bb_error_msg("sqp == NULL: [v]forked child");
7605                 return 0;
7606         }
7607
7608         /* If this one of script's fds? */
7609         if (move_HFILEs_on_redirect(fd, avoid_fd))
7610                 return 1; /* yes. "we closed fd" (actually moved it) */
7611
7612         /* Are we called for "exec 3>FILE"? Came through
7613          * redirect_and_varexp_helper(squirrel=ERR_PTR) -> setup_redirects(ERR_PTR)
7614          * This case used to fail for this script:
7615          *  exec 3>FILE
7616          *  echo Ok
7617          *  ...100000 more lines...
7618          *  echo Ok
7619          * as follows:
7620          *  read(3, "exec 3>FILE\necho Ok\necho Ok"..., 1024) = 1024
7621          *  open("FILE", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 4
7622          *  dup2(4, 3)                        = 3
7623          *  ^^^^^^^^ oops, we lost fd#3 opened to our script!
7624          *  close(4)                          = 0
7625          *  write(1, "Ok\n", 3)               = 3
7626          *  ...                               = 3
7627          *  write(1, "Ok\n", 3)               = 3
7628          *  read(3, 0x94fbc08, 1024)          = -1 EBADF (Bad file descriptor)
7629          *  ^^^^^^^^ oops, wrong fd!!!
7630          * With this case separate from sqp == NULL and *after* move_HFILEs,
7631          * it now works:
7632          */
7633         if (sqp == ERR_PTR) {
7634                 /* Don't preserve redirected fds: exec is _meant_ to change these */
7635                 //bb_error_msg("sqp == ERR_PTR: exec >FILE");
7636                 return 0;
7637         }
7638
7639         /* Check whether it collides with any open fds (e.g. stdio), save fds as needed */
7640         *sqp = add_squirrel(*sqp, fd, avoid_fd);
7641         return 0; /* "we did not close fd" */
7642 }
7643
7644 static void restore_redirects(struct squirrel *sq)
7645 {
7646         if (sq) {
7647                 int i;
7648                 for (i = 0; sq[i].orig_fd >= 0; i++) {
7649                         if (sq[i].moved_to >= 0) {
7650                                 /* We simply die on error */
7651                                 debug_printf_redir("restoring redirected fd from %d to %d\n", sq[i].moved_to, sq[i].orig_fd);
7652                                 xmove_fd(sq[i].moved_to, sq[i].orig_fd);
7653                         } else {
7654                                 /* cmd1 9>FILE; cmd2_should_see_fd9_closed */
7655                                 debug_printf_redir("restoring redirected fd %d: closing it\n", sq[i].orig_fd);
7656                                 close(sq[i].orig_fd);
7657                         }
7658                 }
7659                 free(sq);
7660         }
7661
7662         /* If moved, G_interactive_fd stays on new fd, not restoring it */
7663 }
7664
7665 #if ENABLE_FEATURE_SH_STANDALONE && BB_MMU
7666 static void close_saved_fds_and_FILE_fds(void)
7667 {
7668         if (G_interactive_fd)
7669                 close(G_interactive_fd);
7670         close_all_HFILE_list();
7671 }
7672 #endif
7673
7674 static int internally_opened_fd(int fd, struct squirrel *sq)
7675 {
7676         int i;
7677
7678 #if ENABLE_HUSH_INTERACTIVE
7679         if (fd == G_interactive_fd)
7680                 return 1;
7681 #endif
7682         /* If this one of script's fds? */
7683         if (fd_in_HFILEs(fd))
7684                 return 1;
7685
7686         if (sq) for (i = 0; sq[i].orig_fd >= 0; i++) {
7687                 if (fd == sq[i].moved_to)
7688                         return 1;
7689         }
7690         return 0;
7691 }
7692
7693 /* squirrel != NULL means we squirrel away copies of stdin, stdout,
7694  * and stderr if they are redirected. */
7695 static int setup_redirects(struct command *prog, struct squirrel **sqp)
7696 {
7697         struct redir_struct *redir;
7698
7699         for (redir = prog->redirects; redir; redir = redir->next) {
7700                 int newfd;
7701                 int closed;
7702
7703                 if (redir->rd_type == REDIRECT_HEREDOC2) {
7704                         /* "rd_fd<<HERE" case */
7705                         save_fd_on_redirect(redir->rd_fd, /*avoid:*/ 0, sqp);
7706                         /* for REDIRECT_HEREDOC2, rd_filename holds _contents_
7707                          * of the heredoc */
7708                         debug_printf_redir("set heredoc '%s'\n",
7709                                         redir->rd_filename);
7710                         setup_heredoc(redir);
7711                         continue;
7712                 }
7713
7714                 if (redir->rd_dup == REDIRFD_TO_FILE) {
7715                         /* "rd_fd<*>file" case (<*> is <,>,>>,<>) */
7716                         char *p;
7717                         int mode;
7718
7719                         if (redir->rd_filename == NULL) {
7720                                 /* Examples:
7721                                  * "cmd >" (no filename)
7722                                  * "cmd > <file" (2nd redirect starts too early)
7723                                  */
7724                                 syntax_error("invalid redirect");
7725                                 continue;
7726                         }
7727                         mode = redir_table[redir->rd_type].mode;
7728                         p = expand_string_to_string(redir->rd_filename,
7729                                 EXP_FLAG_ESC_GLOB_CHARS, /*unbackslash:*/ 1);
7730                         newfd = open_or_warn(p, mode);
7731                         free(p);
7732                         if (newfd < 0) {
7733                                 /* Error message from open_or_warn can be lost
7734                                  * if stderr has been redirected, but bash
7735                                  * and ash both lose it as well
7736                                  * (though zsh doesn't!)
7737                                  */
7738                                 return 1;
7739                         }
7740                         if (newfd == redir->rd_fd && sqp) {
7741                                 /* open() gave us precisely the fd we wanted.
7742                                  * This means that this fd was not busy
7743                                  * (not opened to anywhere).
7744                                  * Remember to close it on restore:
7745                                  */
7746                                 *sqp = add_squirrel_closed(*sqp, newfd);
7747                                 debug_printf_redir("redir to previously closed fd %d\n", newfd);
7748                         }
7749                 } else {
7750                         /* "rd_fd>&rd_dup" or "rd_fd>&-" case */
7751                         newfd = redir->rd_dup;
7752                 }
7753
7754                 if (newfd == redir->rd_fd)
7755                         continue;
7756
7757                 /* if "N>FILE": move newfd to redir->rd_fd */
7758                 /* if "N>&M": dup newfd to redir->rd_fd */
7759                 /* if "N>&-": close redir->rd_fd (newfd is REDIRFD_CLOSE) */
7760
7761                 closed = save_fd_on_redirect(redir->rd_fd, /*avoid:*/ newfd, sqp);
7762                 if (newfd == REDIRFD_CLOSE) {
7763                         /* "N>&-" means "close me" */
7764                         if (!closed) {
7765                                 /* ^^^ optimization: saving may already
7766                                  * have closed it. If not... */
7767                                 close(redir->rd_fd);
7768                         }
7769                         /* Sometimes we do another close on restore, getting EBADF.
7770                          * Consider "echo 3>FILE 3>&-"
7771                          * first redirect remembers "need to close 3",
7772                          * and second redirect closes 3! Restore code then closes 3 again.
7773                          */
7774                 } else {
7775                         /* if newfd is a script fd or saved fd, simulate EBADF */
7776                         if (internally_opened_fd(newfd, sqp && sqp != ERR_PTR ? *sqp : NULL)) {
7777                                 //errno = EBADF;
7778                                 //bb_perror_msg_and_die("can't duplicate file descriptor");
7779                                 newfd = -1; /* same effect as code above */
7780                         }
7781                         xdup2(newfd, redir->rd_fd);
7782                         if (redir->rd_dup == REDIRFD_TO_FILE)
7783                                 /* "rd_fd > FILE" */
7784                                 close(newfd);
7785                         /* else: "rd_fd > rd_dup" */
7786                 }
7787         }
7788         return 0;
7789 }
7790
7791 static char *find_in_path(const char *arg)
7792 {
7793         char *ret = NULL;
7794         const char *PATH = get_local_var_value("PATH");
7795
7796         if (!PATH)
7797                 return NULL;
7798
7799         while (1) {
7800                 const char *end = strchrnul(PATH, ':');
7801                 int sz = end - PATH; /* must be int! */
7802
7803                 free(ret);
7804                 if (sz != 0) {
7805                         ret = xasprintf("%.*s/%s", sz, PATH, arg);
7806                 } else {
7807                         /* We have xxx::yyyy in $PATH,
7808                          * it means "use current dir" */
7809                         ret = xstrdup(arg);
7810                 }
7811                 if (access(ret, F_OK) == 0)
7812                         break;
7813
7814                 if (*end == '\0') {
7815                         free(ret);
7816                         return NULL;
7817                 }
7818                 PATH = end + 1;
7819         }
7820
7821         return ret;
7822 }
7823
7824 static const struct built_in_command *find_builtin_helper(const char *name,
7825                 const struct built_in_command *x,
7826                 const struct built_in_command *end)
7827 {
7828         while (x != end) {
7829                 if (strcmp(name, x->b_cmd) != 0) {
7830                         x++;
7831                         continue;
7832                 }
7833                 debug_printf_exec("found builtin '%s'\n", name);
7834                 return x;
7835         }
7836         return NULL;
7837 }
7838 static const struct built_in_command *find_builtin1(const char *name)
7839 {
7840         return find_builtin_helper(name, bltins1, &bltins1[ARRAY_SIZE(bltins1)]);
7841 }
7842 static const struct built_in_command *find_builtin(const char *name)
7843 {
7844         const struct built_in_command *x = find_builtin1(name);
7845         if (x)
7846                 return x;
7847         return find_builtin_helper(name, bltins2, &bltins2[ARRAY_SIZE(bltins2)]);
7848 }
7849
7850 static void remove_nested_vars(void)
7851 {
7852         struct variable *cur;
7853         struct variable **cur_pp;
7854
7855         cur_pp = &G.top_var;
7856         while ((cur = *cur_pp) != NULL) {
7857                 if (cur->var_nest_level <= G.var_nest_level) {
7858                         cur_pp = &cur->next;
7859                         continue;
7860                 }
7861                 /* Unexport */
7862                 if (cur->flg_export) {
7863                         debug_printf_env("unexporting nested '%s'/%u\n", cur->varstr, cur->var_nest_level);
7864                         bb_unsetenv(cur->varstr);
7865                 }
7866                 /* Remove from global list */
7867                 *cur_pp = cur->next;
7868                 /* Free */
7869                 if (!cur->max_len) {
7870                         debug_printf_env("freeing nested '%s'/%u\n", cur->varstr, cur->var_nest_level);
7871                         free(cur->varstr);
7872                 }
7873                 free(cur);
7874         }
7875 }
7876
7877 static void enter_var_nest_level(void)
7878 {
7879         G.var_nest_level++;
7880         debug_printf_env("var_nest_level++ %u\n", G.var_nest_level);
7881
7882         /* Try: f() { echo -n .; f; }; f
7883          * struct variable::var_nest_level is uint16_t,
7884          * thus limiting recursion to < 2^16.
7885          * In any case, with 8 Mbyte stack SEGV happens
7886          * not too long after 2^16 recursions anyway.
7887          */
7888         if (G.var_nest_level > 0xff00)
7889                 bb_error_msg_and_die("fatal recursion (depth %u)", G.var_nest_level);
7890 }
7891
7892 static void leave_var_nest_level(void)
7893 {
7894         G.var_nest_level--;
7895         debug_printf_env("var_nest_level-- %u\n", G.var_nest_level);
7896         if (HUSH_DEBUG && (int)G.var_nest_level < 0)
7897                 bb_error_msg_and_die("BUG: nesting underflow");
7898
7899         remove_nested_vars();
7900 }
7901
7902 #if ENABLE_HUSH_FUNCTIONS
7903 static struct function **find_function_slot(const char *name)
7904 {
7905         struct function *funcp;
7906         struct function **funcpp = &G.top_func;
7907
7908         while ((funcp = *funcpp) != NULL) {
7909                 if (strcmp(name, funcp->name) == 0) {
7910                         debug_printf_exec("found function '%s'\n", name);
7911                         break;
7912                 }
7913                 funcpp = &funcp->next;
7914         }
7915         return funcpp;
7916 }
7917
7918 static ALWAYS_INLINE const struct function *find_function(const char *name)
7919 {
7920         const struct function *funcp = *find_function_slot(name);
7921         return funcp;
7922 }
7923
7924 /* Note: takes ownership on name ptr */
7925 static struct function *new_function(char *name)
7926 {
7927         struct function **funcpp = find_function_slot(name);
7928         struct function *funcp = *funcpp;
7929
7930         if (funcp != NULL) {
7931                 struct command *cmd = funcp->parent_cmd;
7932                 debug_printf_exec("func %p parent_cmd %p\n", funcp, cmd);
7933                 if (!cmd) {
7934                         debug_printf_exec("freeing & replacing function '%s'\n", funcp->name);
7935                         free(funcp->name);
7936                         /* Note: if !funcp->body, do not free body_as_string!
7937                          * This is a special case of "-F name body" function:
7938                          * body_as_string was not malloced! */
7939                         if (funcp->body) {
7940                                 free_pipe_list(funcp->body);
7941 # if !BB_MMU
7942                                 free(funcp->body_as_string);
7943 # endif
7944                         }
7945                 } else {
7946                         debug_printf_exec("reinserting in tree & replacing function '%s'\n", funcp->name);
7947                         cmd->argv[0] = funcp->name;
7948                         cmd->group = funcp->body;
7949 # if !BB_MMU
7950                         cmd->group_as_string = funcp->body_as_string;
7951 # endif
7952                 }
7953         } else {
7954                 debug_printf_exec("remembering new function '%s'\n", name);
7955                 funcp = *funcpp = xzalloc(sizeof(*funcp));
7956                 /*funcp->next = NULL;*/
7957         }
7958
7959         funcp->name = name;
7960         return funcp;
7961 }
7962
7963 # if ENABLE_HUSH_UNSET
7964 static void unset_func(const char *name)
7965 {
7966         struct function **funcpp = find_function_slot(name);
7967         struct function *funcp = *funcpp;
7968
7969         if (funcp != NULL) {
7970                 debug_printf_exec("freeing function '%s'\n", funcp->name);
7971                 *funcpp = funcp->next;
7972                 /* funcp is unlinked now, deleting it.
7973                  * Note: if !funcp->body, the function was created by
7974                  * "-F name body", do not free ->body_as_string
7975                  * and ->name as they were not malloced. */
7976                 if (funcp->body) {
7977                         free_pipe_list(funcp->body);
7978                         free(funcp->name);
7979 #  if !BB_MMU
7980                         free(funcp->body_as_string);
7981 #  endif
7982                 }
7983                 free(funcp);
7984         }
7985 }
7986 # endif
7987
7988 # if BB_MMU
7989 #define exec_function(to_free, funcp, argv) \
7990         exec_function(funcp, argv)
7991 # endif
7992 static void exec_function(char ***to_free,
7993                 const struct function *funcp,
7994                 char **argv) NORETURN;
7995 static void exec_function(char ***to_free,
7996                 const struct function *funcp,
7997                 char **argv)
7998 {
7999 # if BB_MMU
8000         int n;
8001
8002         argv[0] = G.global_argv[0];
8003         G.global_argv = argv;
8004         G.global_argc = n = 1 + string_array_len(argv + 1);
8005
8006 // Example when we are here: "cmd | func"
8007 // func will run with saved-redirect fds open.
8008 // $ f() { echo /proc/self/fd/*; }
8009 // $ true | f
8010 // /proc/self/fd/0 /proc/self/fd/1 /proc/self/fd/2 /proc/self/fd/255 /proc/self/fd/3
8011 // stdio^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ G_interactive_fd^ DIR fd for glob
8012 // Same in script:
8013 // $ . ./SCRIPT
8014 // /proc/self/fd/0 /proc/self/fd/1 /proc/self/fd/2 /proc/self/fd/255 /proc/self/fd/3 /proc/self/fd/4
8015 // stdio^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ G_interactive_fd^ opened ./SCRIPT DIR fd for glob
8016 // They are CLOEXEC so external programs won't see them, but
8017 // for "more correctness" we might want to close those extra fds here:
8018 //?     close_saved_fds_and_FILE_fds();
8019
8020         /* "we are in a function, ok to use return" */
8021         G_flag_return_in_progress = -1;
8022         enter_var_nest_level();
8023         IF_HUSH_LOCAL(G.func_nest_level++;)
8024
8025         /* On MMU, funcp->body is always non-NULL */
8026         n = run_list(funcp->body);
8027         fflush_all();
8028         _exit(n);
8029 # else
8030 //?     close_saved_fds_and_FILE_fds();
8031
8032 //TODO: check whether "true | func_with_return" works
8033
8034         re_execute_shell(to_free,
8035                         funcp->body_as_string,
8036                         G.global_argv[0],
8037                         argv + 1,
8038                         NULL);
8039 # endif
8040 }
8041
8042 static int run_function(const struct function *funcp, char **argv)
8043 {
8044         int rc;
8045         save_arg_t sv;
8046         smallint sv_flg;
8047
8048         save_and_replace_G_args(&sv, argv);
8049
8050         /* "We are in function, ok to use return" */
8051         sv_flg = G_flag_return_in_progress;
8052         G_flag_return_in_progress = -1;
8053
8054         /* Make "local" variables properly shadow previous ones */
8055         IF_HUSH_LOCAL(enter_var_nest_level();)
8056         IF_HUSH_LOCAL(G.func_nest_level++;)
8057
8058         /* On MMU, funcp->body is always non-NULL */
8059 # if !BB_MMU
8060         if (!funcp->body) {
8061                 /* Function defined by -F */
8062                 parse_and_run_string(funcp->body_as_string);
8063                 rc = G.last_exitcode;
8064         } else
8065 # endif
8066         {
8067                 rc = run_list(funcp->body);
8068         }
8069
8070         IF_HUSH_LOCAL(G.func_nest_level--;)
8071         IF_HUSH_LOCAL(leave_var_nest_level();)
8072
8073         G_flag_return_in_progress = sv_flg;
8074
8075         restore_G_args(&sv, argv);
8076
8077         return rc;
8078 }
8079 #endif /* ENABLE_HUSH_FUNCTIONS */
8080
8081
8082 #if BB_MMU
8083 #define exec_builtin(to_free, x, argv) \
8084         exec_builtin(x, argv)
8085 #else
8086 #define exec_builtin(to_free, x, argv) \
8087         exec_builtin(to_free, argv)
8088 #endif
8089 static void exec_builtin(char ***to_free,
8090                 const struct built_in_command *x,
8091                 char **argv) NORETURN;
8092 static void exec_builtin(char ***to_free,
8093                 const struct built_in_command *x,
8094                 char **argv)
8095 {
8096 #if BB_MMU
8097         int rcode;
8098         fflush_all();
8099 //?     close_saved_fds_and_FILE_fds();
8100         rcode = x->b_function(argv);
8101         fflush_all();
8102         _exit(rcode);
8103 #else
8104         fflush_all();
8105         /* On NOMMU, we must never block!
8106          * Example: { sleep 99 | read line; } & echo Ok
8107          */
8108         re_execute_shell(to_free,
8109                         argv[0],
8110                         G.global_argv[0],
8111                         G.global_argv + 1,
8112                         argv);
8113 #endif
8114 }
8115
8116
8117 static void execvp_or_die(char **argv) NORETURN;
8118 static void execvp_or_die(char **argv)
8119 {
8120         int e;
8121         debug_printf_exec("execing '%s'\n", argv[0]);
8122         /* Don't propagate SIG_IGN to the child */
8123         if (SPECIAL_JOBSTOP_SIGS != 0)
8124                 switch_off_special_sigs(G.special_sig_mask & SPECIAL_JOBSTOP_SIGS);
8125         execvp(argv[0], argv);
8126         e = 2;
8127         if (errno == EACCES) e = 126;
8128         if (errno == ENOENT) e = 127;
8129         bb_perror_msg("can't execute '%s'", argv[0]);
8130         _exit(e);
8131 }
8132
8133 #if ENABLE_HUSH_MODE_X
8134 static void x_mode_print_optionally_squoted(const char *str)
8135 {
8136         unsigned len;
8137         const char *cp;
8138
8139         cp = str;
8140
8141         /* the set of chars which-cause-string-to-be-squoted mimics bash */
8142         /* test a char with: bash -c 'set -x; echo "CH"' */
8143         if (str[strcspn(str, "\\\"'`$(){}[]<>;#&|~*?!^"
8144                         " " "\001\002\003\004\005\006\007"
8145                         "\010\011\012\013\014\015\016\017"
8146                         "\020\021\022\023\024\025\026\027"
8147                         "\030\031\032\033\034\035\036\037"
8148                         )
8149                 ] == '\0'
8150         ) {
8151                 /* string has no special chars */
8152                 x_mode_addstr(str);
8153                 return;
8154         }
8155
8156         cp = str;
8157         for (;;) {
8158                 /* print '....' up to EOL or first squote */
8159                 len = (int)(strchrnul(cp, '\'') - cp);
8160                 if (len != 0) {
8161                         x_mode_addchr('\'');
8162                         x_mode_addblock(cp, len);
8163                         x_mode_addchr('\'');
8164                         cp += len;
8165                 }
8166                 if (*cp == '\0')
8167                         break;
8168                 /* string contains squote(s), print them as \' */
8169                 x_mode_addchr('\\');
8170                 x_mode_addchr('\'');
8171                 cp++;
8172         }
8173 }
8174 static void dump_cmd_in_x_mode(char **argv)
8175 {
8176         if (G_x_mode && argv) {
8177                 unsigned n;
8178
8179                 /* "+[+++...][ cmd...]\n\0" */
8180                 x_mode_prefix();
8181                 n = 0;
8182                 while (argv[n]) {
8183                         x_mode_addchr(' ');
8184                         if (argv[n][0] == '\0') {
8185                                 x_mode_addchr('\'');
8186                                 x_mode_addchr('\'');
8187                         } else {
8188                                 x_mode_print_optionally_squoted(argv[n]);
8189                         }
8190                         n++;
8191                 }
8192                 x_mode_flush();
8193         }
8194 }
8195 #else
8196 # define dump_cmd_in_x_mode(argv) ((void)0)
8197 #endif
8198
8199 #if ENABLE_HUSH_COMMAND
8200 static void if_command_vV_print_and_exit(char opt_vV, char *cmd, const char *explanation)
8201 {
8202         char *to_free;
8203
8204         if (!opt_vV)
8205                 return;
8206
8207         to_free = NULL;
8208         if (!explanation) {
8209                 char *path = getenv("PATH");
8210                 explanation = to_free = find_executable(cmd, &path); /* path == NULL is ok */
8211                 if (!explanation)
8212                         _exit(1); /* PROG was not found */
8213                 if (opt_vV != 'V')
8214                         cmd = to_free; /* -v PROG prints "/path/to/PROG" */
8215         }
8216         printf((opt_vV == 'V') ? "%s is %s\n" : "%s\n", cmd, explanation);
8217         free(to_free);
8218         fflush_all();
8219         _exit(0);
8220 }
8221 #else
8222 # define if_command_vV_print_and_exit(a,b,c) ((void)0)
8223 #endif
8224
8225 #if BB_MMU
8226 #define pseudo_exec_argv(nommu_save, argv, assignment_cnt, argv_expanded) \
8227         pseudo_exec_argv(argv, assignment_cnt, argv_expanded)
8228 #define pseudo_exec(nommu_save, command, argv_expanded) \
8229         pseudo_exec(command, argv_expanded)
8230 #endif
8231
8232 /* Called after [v]fork() in run_pipe, or from builtin_exec.
8233  * Never returns.
8234  * Don't exit() here.  If you don't exec, use _exit instead.
8235  * The at_exit handlers apparently confuse the calling process,
8236  * in particular stdin handling. Not sure why? -- because of vfork! (vda)
8237  */
8238 static void pseudo_exec_argv(nommu_save_t *nommu_save,
8239                 char **argv, int assignment_cnt,
8240                 char **argv_expanded) NORETURN;
8241 static NOINLINE void pseudo_exec_argv(nommu_save_t *nommu_save,
8242                 char **argv, int assignment_cnt,
8243                 char **argv_expanded)
8244 {
8245         const struct built_in_command *x;
8246         struct variable **sv_shadowed;
8247         char **new_env;
8248         IF_HUSH_COMMAND(char opt_vV = 0;)
8249         IF_HUSH_FUNCTIONS(const struct function *funcp;)
8250
8251         new_env = expand_assignments(argv, assignment_cnt);
8252         dump_cmd_in_x_mode(new_env);
8253
8254         if (!argv[assignment_cnt]) {
8255                 /* Case when we are here: ... | var=val | ...
8256                  * (note that we do not exit early, i.e., do not optimize out
8257                  * expand_assignments(): think about ... | var=`sleep 1` | ...
8258                  */
8259                 free_strings(new_env);
8260                 _exit(EXIT_SUCCESS);
8261         }
8262
8263         sv_shadowed = G.shadowed_vars_pp;
8264 #if BB_MMU
8265         G.shadowed_vars_pp = NULL; /* "don't save, free them instead" */
8266 #else
8267         G.shadowed_vars_pp = &nommu_save->old_vars;
8268         G.var_nest_level++;
8269 #endif
8270         set_vars_and_save_old(new_env);
8271         G.shadowed_vars_pp = sv_shadowed;
8272
8273         if (argv_expanded) {
8274                 argv = argv_expanded;
8275         } else {
8276                 argv = expand_strvec_to_strvec(argv + assignment_cnt);
8277 #if !BB_MMU
8278                 nommu_save->argv = argv;
8279 #endif
8280         }
8281         dump_cmd_in_x_mode(argv);
8282
8283 #if ENABLE_FEATURE_SH_STANDALONE || BB_MMU
8284         if (strchr(argv[0], '/') != NULL)
8285                 goto skip;
8286 #endif
8287
8288 #if ENABLE_HUSH_FUNCTIONS
8289         /* Check if the command matches any functions (this goes before bltins) */
8290         funcp = find_function(argv[0]);
8291         if (funcp)
8292                 exec_function(&nommu_save->argv_from_re_execing, funcp, argv);
8293 #endif
8294
8295 #if ENABLE_HUSH_COMMAND
8296         /* "command BAR": run BAR without looking it up among functions
8297          * "command -v BAR": print "BAR" or "/path/to/BAR"; or exit 1
8298          * "command -V BAR": print "BAR is {a function,a shell builtin,/path/to/BAR}"
8299          */
8300         while (strcmp(argv[0], "command") == 0 && argv[1]) {
8301                 char *p;
8302
8303                 argv++;
8304                 p = *argv;
8305                 if (p[0] != '-' || !p[1])
8306                         continue; /* bash allows "command command command [-OPT] BAR" */
8307
8308                 for (;;) {
8309                         p++;
8310                         switch (*p) {
8311                         case '\0':
8312                                 argv++;
8313                                 p = *argv;
8314                                 if (p[0] != '-' || !p[1])
8315                                         goto after_opts;
8316                                 continue; /* next arg is also -opts, process it too */
8317                         case 'v':
8318                         case 'V':
8319                                 opt_vV = *p;
8320                                 continue;
8321                         default:
8322                                 bb_error_msg_and_die("%s: %s: invalid option", "command", argv[0]);
8323                         }
8324                 }
8325         }
8326  after_opts:
8327 # if ENABLE_HUSH_FUNCTIONS
8328         if (opt_vV && find_function(argv[0]))
8329                 if_command_vV_print_and_exit(opt_vV, argv[0], "a function");
8330 # endif
8331 #endif
8332
8333         /* Check if the command matches any of the builtins.
8334          * Depending on context, this might be redundant.  But it's
8335          * easier to waste a few CPU cycles than it is to figure out
8336          * if this is one of those cases.
8337          */
8338         /* Why "BB_MMU ? :" difference in logic? -
8339          * On NOMMU, it is more expensive to re-execute shell
8340          * just in order to run echo or test builtin.
8341          * It's better to skip it here and run corresponding
8342          * non-builtin later. */
8343         x = BB_MMU ? find_builtin(argv[0]) : find_builtin1(argv[0]);
8344         if (x) {
8345                 if_command_vV_print_and_exit(opt_vV, argv[0], "a shell builtin");
8346                 exec_builtin(&nommu_save->argv_from_re_execing, x, argv);
8347         }
8348
8349 #if ENABLE_FEATURE_SH_STANDALONE
8350         /* Check if the command matches any busybox applets */
8351         {
8352                 int a = find_applet_by_name(argv[0]);
8353                 if (a >= 0) {
8354                         if_command_vV_print_and_exit(opt_vV, argv[0], "an applet");
8355 # if BB_MMU /* see above why on NOMMU it is not allowed */
8356                         if (APPLET_IS_NOEXEC(a)) {
8357                                 /* Do not leak open fds from opened script files etc.
8358                                  * Testcase: interactive "ls -l /proc/self/fd"
8359                                  * should not show tty fd open.
8360                                  */
8361                                 close_saved_fds_and_FILE_fds();
8362 //FIXME: should also close saved redir fds
8363 //This casuses test failures in
8364 //redir_children_should_not_see_saved_fd_2.tests
8365 //redir_children_should_not_see_saved_fd_3.tests
8366 //if you replace "busybox find" with just "find" in them
8367                                 /* Without this, "rm -i FILE" can't be ^C'ed: */
8368                                 switch_off_special_sigs(G.special_sig_mask);
8369                                 debug_printf_exec("running applet '%s'\n", argv[0]);
8370                                 run_noexec_applet_and_exit(a, argv[0], argv);
8371                         }
8372 # endif
8373                         /* Re-exec ourselves */
8374                         debug_printf_exec("re-execing applet '%s'\n", argv[0]);
8375                         /* Don't propagate SIG_IGN to the child */
8376                         if (SPECIAL_JOBSTOP_SIGS != 0)
8377                                 switch_off_special_sigs(G.special_sig_mask & SPECIAL_JOBSTOP_SIGS);
8378                         execv(bb_busybox_exec_path, argv);
8379                         /* If they called chroot or otherwise made the binary no longer
8380                          * executable, fall through */
8381                 }
8382         }
8383 #endif
8384
8385 #if ENABLE_FEATURE_SH_STANDALONE || BB_MMU
8386  skip:
8387 #endif
8388         if_command_vV_print_and_exit(opt_vV, argv[0], NULL);
8389         execvp_or_die(argv);
8390 }
8391
8392 /* Called after [v]fork() in run_pipe
8393  */
8394 static void pseudo_exec(nommu_save_t *nommu_save,
8395                 struct command *command,
8396                 char **argv_expanded) NORETURN;
8397 static void pseudo_exec(nommu_save_t *nommu_save,
8398                 struct command *command,
8399                 char **argv_expanded)
8400 {
8401 #if ENABLE_HUSH_FUNCTIONS
8402         if (command->cmd_type == CMD_FUNCDEF) {
8403                 /* Ignore funcdefs in pipes:
8404                  * true | f() { cmd }
8405                  */
8406                 _exit(0);
8407         }
8408 #endif
8409
8410         if (command->argv) {
8411                 pseudo_exec_argv(nommu_save, command->argv,
8412                                 command->assignment_cnt, argv_expanded);
8413         }
8414
8415         if (command->group) {
8416                 /* Cases when we are here:
8417                  * ( list )
8418                  * { list } &
8419                  * ... | ( list ) | ...
8420                  * ... | { list } | ...
8421                  */
8422 #if BB_MMU
8423                 int rcode;
8424                 debug_printf_exec("pseudo_exec: run_list\n");
8425                 reset_traps_to_defaults();
8426                 rcode = run_list(command->group);
8427                 /* OK to leak memory by not calling free_pipe_list,
8428                  * since this process is about to exit */
8429                 _exit(rcode);
8430 #else
8431                 re_execute_shell(&nommu_save->argv_from_re_execing,
8432                                 command->group_as_string,
8433                                 G.global_argv[0],
8434                                 G.global_argv + 1,
8435                                 NULL);
8436 #endif
8437         }
8438
8439         /* Case when we are here: ... | >file */
8440         debug_printf_exec("pseudo_exec'ed null command\n");
8441         _exit(EXIT_SUCCESS);
8442 }
8443
8444 #if ENABLE_HUSH_JOB
8445 static const char *get_cmdtext(struct pipe *pi)
8446 {
8447         char **argv;
8448         char *p;
8449         int len;
8450
8451         /* This is subtle. ->cmdtext is created only on first backgrounding.
8452          * (Think "cat, <ctrl-z>, fg, <ctrl-z>, fg, <ctrl-z>...." here...)
8453          * On subsequent bg argv is trashed, but we won't use it */
8454         if (pi->cmdtext)
8455                 return pi->cmdtext;
8456
8457         argv = pi->cmds[0].argv;
8458         if (!argv) {
8459                 pi->cmdtext = xzalloc(1);
8460                 return pi->cmdtext;
8461         }
8462         len = 0;
8463         do {
8464                 len += strlen(*argv) + 1;
8465         } while (*++argv);
8466         p = xmalloc(len);
8467         pi->cmdtext = p;
8468         argv = pi->cmds[0].argv;
8469         do {
8470                 p = stpcpy(p, *argv);
8471                 *p++ = ' ';
8472         } while (*++argv);
8473         p[-1] = '\0';
8474         return pi->cmdtext;
8475 }
8476
8477 static void remove_job_from_table(struct pipe *pi)
8478 {
8479         struct pipe *prev_pipe;
8480
8481         if (pi == G.job_list) {
8482                 G.job_list = pi->next;
8483         } else {
8484                 prev_pipe = G.job_list;
8485                 while (prev_pipe->next != pi)
8486                         prev_pipe = prev_pipe->next;
8487                 prev_pipe->next = pi->next;
8488         }
8489         G.last_jobid = 0;
8490         if (G.job_list)
8491                 G.last_jobid = G.job_list->jobid;
8492 }
8493
8494 static void delete_finished_job(struct pipe *pi)
8495 {
8496         remove_job_from_table(pi);
8497         free_pipe(pi);
8498 }
8499
8500 static void clean_up_last_dead_job(void)
8501 {
8502         if (G.job_list && !G.job_list->alive_cmds)
8503                 delete_finished_job(G.job_list);
8504 }
8505
8506 static void insert_job_into_table(struct pipe *pi)
8507 {
8508         struct pipe *job, **jobp;
8509         int i;
8510
8511         clean_up_last_dead_job();
8512
8513         /* Find the end of the list, and find next job ID to use */
8514         i = 0;
8515         jobp = &G.job_list;
8516         while ((job = *jobp) != NULL) {
8517                 if (job->jobid > i)
8518                         i = job->jobid;
8519                 jobp = &job->next;
8520         }
8521         pi->jobid = i + 1;
8522
8523         /* Create a new job struct at the end */
8524         job = *jobp = xmemdup(pi, sizeof(*pi));
8525         job->next = NULL;
8526         job->cmds = xzalloc(sizeof(pi->cmds[0]) * pi->num_cmds);
8527         /* Cannot copy entire pi->cmds[] vector! This causes double frees */
8528         for (i = 0; i < pi->num_cmds; i++) {
8529                 job->cmds[i].pid = pi->cmds[i].pid;
8530                 /* all other fields are not used and stay zero */
8531         }
8532         job->cmdtext = xstrdup(get_cmdtext(pi));
8533
8534         if (G_interactive_fd)
8535                 printf("[%u] %u %s\n", job->jobid, (unsigned)job->cmds[0].pid, job->cmdtext);
8536         G.last_jobid = job->jobid;
8537 }
8538 #endif /* JOB */
8539
8540 static int job_exited_or_stopped(struct pipe *pi)
8541 {
8542         int rcode, i;
8543
8544         if (pi->alive_cmds != pi->stopped_cmds)
8545                 return -1;
8546
8547         /* All processes in fg pipe have exited or stopped */
8548         rcode = 0;
8549         i = pi->num_cmds;
8550         while (--i >= 0) {
8551                 rcode = pi->cmds[i].cmd_exitcode;
8552                 /* usually last process gives overall exitstatus,
8553                  * but with "set -o pipefail", last *failed* process does */
8554                 if (G.o_opt[OPT_O_PIPEFAIL] == 0 || rcode != 0)
8555                         break;
8556         }
8557         IF_HAS_KEYWORDS(if (pi->pi_inverted) rcode = !rcode;)
8558         return rcode;
8559 }
8560
8561 static int process_wait_result(struct pipe *fg_pipe, pid_t childpid, int status)
8562 {
8563 #if ENABLE_HUSH_JOB
8564         struct pipe *pi;
8565 #endif
8566         int i, dead;
8567
8568         dead = WIFEXITED(status) || WIFSIGNALED(status);
8569
8570 #if DEBUG_JOBS
8571         if (WIFSTOPPED(status))
8572                 debug_printf_jobs("pid %d stopped by sig %d (exitcode %d)\n",
8573                                 childpid, WSTOPSIG(status), WEXITSTATUS(status));
8574         if (WIFSIGNALED(status))
8575                 debug_printf_jobs("pid %d killed by sig %d (exitcode %d)\n",
8576                                 childpid, WTERMSIG(status), WEXITSTATUS(status));
8577         if (WIFEXITED(status))
8578                 debug_printf_jobs("pid %d exited, exitcode %d\n",
8579                                 childpid, WEXITSTATUS(status));
8580 #endif
8581         /* Were we asked to wait for a fg pipe? */
8582         if (fg_pipe) {
8583                 i = fg_pipe->num_cmds;
8584
8585                 while (--i >= 0) {
8586                         int rcode;
8587
8588                         debug_printf_jobs("check pid %d\n", fg_pipe->cmds[i].pid);
8589                         if (fg_pipe->cmds[i].pid != childpid)
8590                                 continue;
8591                         if (dead) {
8592                                 int ex;
8593                                 fg_pipe->cmds[i].pid = 0;
8594                                 fg_pipe->alive_cmds--;
8595                                 ex = WEXITSTATUS(status);
8596                                 /* bash prints killer signal's name for *last*
8597                                  * process in pipe (prints just newline for SIGINT/SIGPIPE).
8598                                  * Mimic this. Example: "sleep 5" + (^\ or kill -QUIT)
8599                                  */
8600                                 if (WIFSIGNALED(status)) {
8601                                         int sig = WTERMSIG(status);
8602                                         if (i == fg_pipe->num_cmds-1)
8603                                                 /* TODO: use strsignal() instead for bash compat? but that's bloat... */
8604                                                 puts(sig == SIGINT || sig == SIGPIPE ? "" : get_signame(sig));
8605                                         /* TODO: if (WCOREDUMP(status)) + " (core dumped)"; */
8606                                         /* TODO: MIPS has 128 sigs (1..128), what if sig==128 here?
8607                                          * Maybe we need to use sig | 128? */
8608                                         ex = sig + 128;
8609                                 }
8610                                 fg_pipe->cmds[i].cmd_exitcode = ex;
8611                         } else {
8612                                 fg_pipe->stopped_cmds++;
8613                         }
8614                         debug_printf_jobs("fg_pipe: alive_cmds %d stopped_cmds %d\n",
8615                                         fg_pipe->alive_cmds, fg_pipe->stopped_cmds);
8616                         rcode = job_exited_or_stopped(fg_pipe);
8617                         if (rcode >= 0) {
8618 /* Note: *non-interactive* bash does not continue if all processes in fg pipe
8619  * are stopped. Testcase: "cat | cat" in a script (not on command line!)
8620  * and "killall -STOP cat" */
8621                                 if (G_interactive_fd) {
8622 #if ENABLE_HUSH_JOB
8623                                         if (fg_pipe->alive_cmds != 0)
8624                                                 insert_job_into_table(fg_pipe);
8625 #endif
8626                                         return rcode;
8627                                 }
8628                                 if (fg_pipe->alive_cmds == 0)
8629                                         return rcode;
8630                         }
8631                         /* There are still running processes in the fg_pipe */
8632                         return -1;
8633                 }
8634                 /* It wasn't in fg_pipe, look for process in bg pipes */
8635         }
8636
8637 #if ENABLE_HUSH_JOB
8638         /* We were asked to wait for bg or orphaned children */
8639         /* No need to remember exitcode in this case */
8640         for (pi = G.job_list; pi; pi = pi->next) {
8641                 for (i = 0; i < pi->num_cmds; i++) {
8642                         if (pi->cmds[i].pid == childpid)
8643                                 goto found_pi_and_prognum;
8644                 }
8645         }
8646         /* Happens when shell is used as init process (init=/bin/sh) */
8647         debug_printf("checkjobs: pid %d was not in our list!\n", childpid);
8648         return -1; /* this wasn't a process from fg_pipe */
8649
8650  found_pi_and_prognum:
8651         if (dead) {
8652                 /* child exited */
8653                 int rcode = WEXITSTATUS(status);
8654                 if (WIFSIGNALED(status))
8655                         rcode = 128 + WTERMSIG(status);
8656                 pi->cmds[i].cmd_exitcode = rcode;
8657                 if (G.last_bg_pid == pi->cmds[i].pid)
8658                         G.last_bg_pid_exitcode = rcode;
8659                 pi->cmds[i].pid = 0;
8660                 pi->alive_cmds--;
8661                 if (!pi->alive_cmds) {
8662 #if ENABLE_HUSH_BASH_COMPAT
8663                         G.dead_job_exitcode = job_exited_or_stopped(pi);
8664 #endif
8665                         if (G_interactive_fd) {
8666                                 printf(JOB_STATUS_FORMAT, pi->jobid,
8667                                                 "Done", pi->cmdtext);
8668                                 delete_finished_job(pi);
8669                         } else {
8670 /*
8671  * bash deletes finished jobs from job table only in interactive mode,
8672  * after "jobs" cmd, or if pid of a new process matches one of the old ones
8673  * (see cleanup_dead_jobs(), delete_old_job(), J_NOTIFIED in bash source).
8674  * Testcase script: "(exit 3) & sleep 1; wait %1; echo $?" prints 3 in bash.
8675  * We only retain one "dead" job, if it's the single job on the list.
8676  * This covers most of real-world scenarios where this is useful.
8677  */
8678                                 if (pi != G.job_list)
8679                                         delete_finished_job(pi);
8680                         }
8681                 }
8682         } else {
8683                 /* child stopped */
8684                 pi->stopped_cmds++;
8685         }
8686 #endif
8687         return -1; /* this wasn't a process from fg_pipe */
8688 }
8689
8690 /* Check to see if any processes have exited -- if they have,
8691  * figure out why and see if a job has completed.
8692  *
8693  * If non-NULL fg_pipe: wait for its completion or stop.
8694  * Return its exitcode or zero if stopped.
8695  *
8696  * Alternatively (fg_pipe == NULL, waitfor_pid != 0):
8697  * waitpid(WNOHANG), if waitfor_pid exits or stops, return exitcode+1,
8698  * else return <0 if waitpid errors out (e.g. ECHILD: nothing to wait for)
8699  * or 0 if no children changed status.
8700  *
8701  * Alternatively (fg_pipe == NULL, waitfor_pid == 0),
8702  * return <0 if waitpid errors out (e.g. ECHILD: nothing to wait for)
8703  * or 0 if no children changed status.
8704  */
8705 static int checkjobs(struct pipe *fg_pipe, pid_t waitfor_pid)
8706 {
8707         int attributes;
8708         int status;
8709         int rcode = 0;
8710
8711         debug_printf_jobs("checkjobs %p\n", fg_pipe);
8712
8713         attributes = WUNTRACED;
8714         if (fg_pipe == NULL)
8715                 attributes |= WNOHANG;
8716
8717         errno = 0;
8718 #if ENABLE_HUSH_FAST
8719         if (G.handled_SIGCHLD == G.count_SIGCHLD) {
8720 //bb_error_msg("[%d] checkjobs: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d children?:%d fg_pipe:%p",
8721 //getpid(), G.count_SIGCHLD, G.handled_SIGCHLD, G.we_have_children, fg_pipe);
8722                 /* There was neither fork nor SIGCHLD since last waitpid */
8723                 /* Avoid doing waitpid syscall if possible */
8724                 if (!G.we_have_children) {
8725                         errno = ECHILD;
8726                         return -1;
8727                 }
8728                 if (fg_pipe == NULL) { /* is WNOHANG set? */
8729                         /* We have children, but they did not exit
8730                          * or stop yet (we saw no SIGCHLD) */
8731                         return 0;
8732                 }
8733                 /* else: !WNOHANG, waitpid will block, can't short-circuit */
8734         }
8735 #endif
8736
8737 /* Do we do this right?
8738  * bash-3.00# sleep 20 | false
8739  * <ctrl-Z pressed>
8740  * [3]+  Stopped          sleep 20 | false
8741  * bash-3.00# echo $?
8742  * 1   <========== bg pipe is not fully done, but exitcode is already known!
8743  * [hush 1.14.0: yes we do it right]
8744  */
8745         while (1) {
8746                 pid_t childpid;
8747 #if ENABLE_HUSH_FAST
8748                 int i;
8749                 i = G.count_SIGCHLD;
8750 #endif
8751                 childpid = waitpid(-1, &status, attributes);
8752                 if (childpid <= 0) {
8753                         if (childpid && errno != ECHILD)
8754                                 bb_perror_msg("waitpid");
8755 #if ENABLE_HUSH_FAST
8756                         else { /* Until next SIGCHLD, waitpid's are useless */
8757                                 G.we_have_children = (childpid == 0);
8758                                 G.handled_SIGCHLD = i;
8759 //bb_error_msg("[%d] checkjobs: waitpid returned <= 0, G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
8760                         }
8761 #endif
8762                         /* ECHILD (no children), or 0 (no change in children status) */
8763                         rcode = childpid;
8764                         break;
8765                 }
8766                 rcode = process_wait_result(fg_pipe, childpid, status);
8767                 if (rcode >= 0) {
8768                         /* fg_pipe exited or stopped */
8769                         break;
8770                 }
8771                 if (childpid == waitfor_pid) { /* "wait PID" */
8772                         debug_printf_exec("childpid==waitfor_pid:%d status:0x%08x\n", childpid, status);
8773                         rcode = WEXITSTATUS(status);
8774                         if (WIFSIGNALED(status))
8775                                 rcode = 128 + WTERMSIG(status);
8776                         if (WIFSTOPPED(status))
8777                                 /* bash: "cmd & wait $!" and cmd stops: $? = 128 + stopsig */
8778                                 rcode = 128 + WSTOPSIG(status);
8779                         rcode++;
8780                         break; /* "wait PID" called us, give it exitcode+1 */
8781                 }
8782 #if ENABLE_HUSH_BASH_COMPAT
8783                 if (-1 == waitfor_pid /* "wait -n" (wait for any one job) */
8784                  && G.dead_job_exitcode >= 0 /* some job did finish */
8785                 ) {
8786                         debug_printf_exec("waitfor_pid:-1\n");
8787                         rcode = G.dead_job_exitcode + 1;
8788                         break;
8789                 }
8790 #endif
8791                 /* This wasn't one of our processes, or */
8792                 /* fg_pipe still has running processes, do waitpid again */
8793         } /* while (waitpid succeeds)... */
8794
8795         return rcode;
8796 }
8797
8798 #if ENABLE_HUSH_JOB
8799 static int checkjobs_and_fg_shell(struct pipe *fg_pipe)
8800 {
8801         pid_t p;
8802         int rcode = checkjobs(fg_pipe, 0 /*(no pid to wait for)*/);
8803         if (G_saved_tty_pgrp) {
8804                 /* Job finished, move the shell to the foreground */
8805                 p = getpgrp(); /* our process group id */
8806                 debug_printf_jobs("fg'ing ourself: getpgrp()=%d\n", (int)p);
8807                 tcsetpgrp(G_interactive_fd, p);
8808         }
8809         return rcode;
8810 }
8811 #endif
8812
8813 /* Start all the jobs, but don't wait for anything to finish.
8814  * See checkjobs().
8815  *
8816  * Return code is normally -1, when the caller has to wait for children
8817  * to finish to determine the exit status of the pipe.  If the pipe
8818  * is a simple builtin command, however, the action is done by the
8819  * time run_pipe returns, and the exit code is provided as the
8820  * return value.
8821  *
8822  * Returns -1 only if started some children. IOW: we have to
8823  * mask out retvals of builtins etc with 0xff!
8824  *
8825  * The only case when we do not need to [v]fork is when the pipe
8826  * is single, non-backgrounded, non-subshell command. Examples:
8827  * cmd ; ...   { list } ; ...
8828  * cmd && ...  { list } && ...
8829  * cmd || ...  { list } || ...
8830  * If it is, then we can run cmd as a builtin, NOFORK,
8831  * or (if SH_STANDALONE) an applet, and we can run the { list }
8832  * with run_list. If it isn't one of these, we fork and exec cmd.
8833  *
8834  * Cases when we must fork:
8835  * non-single:   cmd | cmd
8836  * backgrounded: cmd &     { list } &
8837  * subshell:     ( list ) [&]
8838  */
8839 #if !ENABLE_HUSH_MODE_X
8840 #define redirect_and_varexp_helper(command, sqp, argv_expanded) \
8841         redirect_and_varexp_helper(command, sqp)
8842 #endif
8843 static int redirect_and_varexp_helper(
8844                 struct command *command,
8845                 struct squirrel **sqp,
8846                 char **argv_expanded)
8847 {
8848         /* Assignments occur before redirects. Try:
8849          * a=`sleep 1` sleep 2 3>/qwe/rty
8850          */
8851
8852         char **new_env = expand_assignments(command->argv, command->assignment_cnt);
8853         dump_cmd_in_x_mode(new_env);
8854         dump_cmd_in_x_mode(argv_expanded);
8855         /* this takes ownership of new_env[i] elements, and frees new_env: */
8856         set_vars_and_save_old(new_env);
8857
8858         return setup_redirects(command, sqp);
8859 }
8860 static NOINLINE int run_pipe(struct pipe *pi)
8861 {
8862         static const char *const null_ptr = NULL;
8863
8864         int cmd_no;
8865         int next_infd;
8866         struct command *command;
8867         char **argv_expanded;
8868         char **argv;
8869         struct squirrel *squirrel = NULL;
8870         int rcode;
8871
8872         debug_printf_exec("run_pipe start: members:%d\n", pi->num_cmds);
8873         debug_enter();
8874
8875         /* Testcase: set -- q w e; (IFS='' echo "$*"; IFS=''; echo "$*"); echo "$*"
8876          * Result should be 3 lines: q w e, qwe, q w e
8877          */
8878         if (G.ifs_whitespace != G.ifs)
8879                 free(G.ifs_whitespace);
8880         G.ifs = get_local_var_value("IFS");
8881         if (G.ifs) {
8882                 char *p;
8883                 G.ifs_whitespace = (char*)G.ifs;
8884                 p = skip_whitespace(G.ifs);
8885                 if (*p) {
8886                         /* Not all $IFS is whitespace */
8887                         char *d;
8888                         int len = p - G.ifs;
8889                         p = skip_non_whitespace(p);
8890                         G.ifs_whitespace = xmalloc(len + strlen(p) + 1); /* can overestimate */
8891                         d = mempcpy(G.ifs_whitespace, G.ifs, len);
8892                         while (*p) {
8893                                 if (isspace(*p))
8894                                         *d++ = *p;
8895                                 p++;
8896                         }
8897                         *d = '\0';
8898                 }
8899         } else {
8900                 G.ifs = defifs;
8901                 G.ifs_whitespace = (char*)G.ifs;
8902         }
8903
8904         IF_HUSH_JOB(pi->pgrp = -1;)
8905         pi->stopped_cmds = 0;
8906         command = &pi->cmds[0];
8907         argv_expanded = NULL;
8908
8909         if (pi->num_cmds != 1
8910          || pi->followup == PIPE_BG
8911          || command->cmd_type == CMD_SUBSHELL
8912         ) {
8913                 goto must_fork;
8914         }
8915
8916         pi->alive_cmds = 1;
8917
8918         debug_printf_exec(": group:%p argv:'%s'\n",
8919                 command->group, command->argv ? command->argv[0] : "NONE");
8920
8921         if (command->group) {
8922 #if ENABLE_HUSH_FUNCTIONS
8923                 if (command->cmd_type == CMD_FUNCDEF) {
8924                         /* "executing" func () { list } */
8925                         struct function *funcp;
8926
8927                         funcp = new_function(command->argv[0]);
8928                         /* funcp->name is already set to argv[0] */
8929                         funcp->body = command->group;
8930 # if !BB_MMU
8931                         funcp->body_as_string = command->group_as_string;
8932                         command->group_as_string = NULL;
8933 # endif
8934                         command->group = NULL;
8935                         command->argv[0] = NULL;
8936                         debug_printf_exec("cmd %p has child func at %p\n", command, funcp);
8937                         funcp->parent_cmd = command;
8938                         command->child_func = funcp;
8939
8940                         debug_printf_exec("run_pipe: return EXIT_SUCCESS\n");
8941                         debug_leave();
8942                         return EXIT_SUCCESS;
8943                 }
8944 #endif
8945                 /* { list } */
8946                 debug_printf_exec("non-subshell group\n");
8947                 rcode = 1; /* exitcode if redir failed */
8948                 if (setup_redirects(command, &squirrel) == 0) {
8949                         debug_printf_exec(": run_list\n");
8950 //FIXME: we need to pass squirrel down into run_list()
8951 //for SH_STANDALONE case, or else this construct:
8952 // { find /proc/self/fd; true; } >FILE; cmd2
8953 //has no way of closing saved fd#1 for "find",
8954 //and in SH_STANDALONE mode, "find" is not execed,
8955 //therefore CLOEXEC on saved fd does not help.
8956                         rcode = run_list(command->group) & 0xff;
8957                 }
8958                 restore_redirects(squirrel);
8959                 IF_HAS_KEYWORDS(if (pi->pi_inverted) rcode = !rcode;)
8960                 debug_leave();
8961                 debug_printf_exec("run_pipe: return %d\n", rcode);
8962                 return rcode;
8963         }
8964
8965         argv = command->argv ? command->argv : (char **) &null_ptr;
8966         {
8967                 const struct built_in_command *x;
8968                 IF_HUSH_FUNCTIONS(const struct function *funcp;)
8969                 IF_NOT_HUSH_FUNCTIONS(enum { funcp = 0 };)
8970                 struct variable **sv_shadowed;
8971                 struct variable *old_vars;
8972
8973 #if ENABLE_HUSH_LINENO_VAR
8974                 G.execute_lineno = command->lineno;
8975 #endif
8976
8977                 if (argv[command->assignment_cnt] == NULL) {
8978                         /* Assignments, but no command.
8979                          * Ensure redirects take effect (that is, create files).
8980                          * Try "a=t >file"
8981                          */
8982                         unsigned i;
8983                         G.expand_exitcode = 0;
8984  only_assignments:
8985                         rcode = setup_redirects(command, &squirrel);
8986                         restore_redirects(squirrel);
8987
8988                         /* Set shell variables */
8989                         i = 0;
8990                         while (i < command->assignment_cnt) {
8991                                 char *p = expand_string_to_string(argv[i],
8992                                                 EXP_FLAG_ESC_GLOB_CHARS,
8993                                                 /*unbackslash:*/ 1
8994                                 );
8995 #if ENABLE_HUSH_MODE_X
8996                                 if (G_x_mode) {
8997                                         char *eq;
8998                                         if (i == 0)
8999                                                 x_mode_prefix();
9000                                         x_mode_addchr(' ');
9001                                         eq = strchrnul(p, '=');
9002                                         if (*eq) eq++;
9003                                         x_mode_addblock(p, (eq - p));
9004                                         x_mode_print_optionally_squoted(eq);
9005                                         x_mode_flush();
9006                                 }
9007 #endif
9008                                 debug_printf_env("set shell var:'%s'->'%s'\n", *argv, p);
9009                                 if (set_local_var(p, /*flag:*/ 0)) {
9010                                         /* assignment to readonly var / putenv error? */
9011                                         rcode = 1;
9012                                 }
9013                                 i++;
9014                         }
9015                         /* Redirect error sets $? to 1. Otherwise,
9016                          * if evaluating assignment value set $?, retain it.
9017                          * Else, clear $?:
9018                          *  false; q=`exit 2`; echo $? - should print 2
9019                          *  false; x=1; echo $? - should print 0
9020                          * Because of the 2nd case, we can't just use G.last_exitcode.
9021                          */
9022                         if (rcode == 0)
9023                                 rcode = G.expand_exitcode;
9024                         IF_HAS_KEYWORDS(if (pi->pi_inverted) rcode = !rcode;)
9025                         debug_leave();
9026                         debug_printf_exec("run_pipe: return %d\n", rcode);
9027                         return rcode;
9028                 }
9029
9030                 /* Expand the rest into (possibly) many strings each */
9031 #if defined(CMD_SINGLEWORD_NOGLOB)
9032                 if (command->cmd_type == CMD_SINGLEWORD_NOGLOB)
9033                         argv_expanded = expand_strvec_to_strvec_singleword_noglob(argv + command->assignment_cnt);
9034                 else
9035 #endif
9036                         argv_expanded = expand_strvec_to_strvec(argv + command->assignment_cnt);
9037
9038                 /* If someone gives us an empty string: `cmd with empty output` */
9039                 if (!argv_expanded[0]) {
9040                         free(argv_expanded);
9041                         /* `false` still has to set exitcode 1 */
9042                         G.expand_exitcode = G.last_exitcode;
9043                         goto only_assignments;
9044                 }
9045
9046                 old_vars = NULL;
9047                 sv_shadowed = G.shadowed_vars_pp;
9048
9049                 /* Check if argv[0] matches any functions (this goes before bltins) */
9050                 IF_HUSH_FUNCTIONS(funcp = find_function(argv_expanded[0]);)
9051                 IF_HUSH_FUNCTIONS(x = NULL;)
9052                 IF_HUSH_FUNCTIONS(if (!funcp))
9053                         x = find_builtin(argv_expanded[0]);
9054                 if (x || funcp) {
9055                         if (x && x->b_function == builtin_exec && argv_expanded[1] == NULL) {
9056                                 debug_printf("exec with redirects only\n");
9057                                 /*
9058                                  * Variable assignments are executed, but then "forgotten":
9059                                  *  a=`sleep 1;echo A` exec 3>&-; echo $a
9060                                  * sleeps, but prints nothing.
9061                                  */
9062                                 enter_var_nest_level();
9063                                 G.shadowed_vars_pp = &old_vars;
9064                                 rcode = redirect_and_varexp_helper(command,
9065                                         /*squirrel:*/ ERR_PTR,
9066                                         argv_expanded
9067                                 );
9068                                 G.shadowed_vars_pp = sv_shadowed;
9069                                 /* rcode=1 can be if redir file can't be opened */
9070
9071                                 goto clean_up_and_ret1;
9072                         }
9073
9074                         /* Bump var nesting, or this will leak exported $a:
9075                          * a=b true; env | grep ^a=
9076                          */
9077                         enter_var_nest_level();
9078                         /* Collect all variables "shadowed" by helper
9079                          * (IOW: old vars overridden by "var1=val1 var2=val2 cmd..." syntax)
9080                          * into old_vars list:
9081                          */
9082                         G.shadowed_vars_pp = &old_vars;
9083                         rcode = redirect_and_varexp_helper(command, &squirrel, argv_expanded);
9084                         if (rcode == 0) {
9085                                 if (!funcp) {
9086                                         /* Do not collect *to old_vars list* vars shadowed
9087                                          * by e.g. "local VAR" builtin (collect them
9088                                          * in the previously nested list instead):
9089                                          * don't want them to be restored immediately
9090                                          * after "local" completes.
9091                                          */
9092                                         G.shadowed_vars_pp = sv_shadowed;
9093
9094                                         debug_printf_exec(": builtin '%s' '%s'...\n",
9095                                                 x->b_cmd, argv_expanded[1]);
9096                                         fflush_all();
9097                                         rcode = x->b_function(argv_expanded) & 0xff;
9098                                         fflush_all();
9099                                 }
9100 #if ENABLE_HUSH_FUNCTIONS
9101                                 else {
9102                                         debug_printf_exec(": function '%s' '%s'...\n",
9103                                                 funcp->name, argv_expanded[1]);
9104                                         rcode = run_function(funcp, argv_expanded) & 0xff;
9105                                         /*
9106                                          * But do collect *to old_vars list* vars shadowed
9107                                          * within function execution. To that end, restore
9108                                          * this pointer _after_ function run:
9109                                          */
9110                                         G.shadowed_vars_pp = sv_shadowed;
9111                                 }
9112 #endif
9113                         }
9114                 } else
9115                 if (ENABLE_FEATURE_SH_NOFORK && NUM_APPLETS > 1) {
9116                         int n = find_applet_by_name(argv_expanded[0]);
9117                         if (n < 0 || !APPLET_IS_NOFORK(n))
9118                                 goto must_fork;
9119
9120                         enter_var_nest_level();
9121                         /* Collect all variables "shadowed" by helper into old_vars list */
9122                         G.shadowed_vars_pp = &old_vars;
9123                         rcode = redirect_and_varexp_helper(command, &squirrel, argv_expanded);
9124                         G.shadowed_vars_pp = sv_shadowed;
9125
9126                         if (rcode == 0) {
9127                                 debug_printf_exec(": run_nofork_applet '%s' '%s'...\n",
9128                                         argv_expanded[0], argv_expanded[1]);
9129                                 /*
9130                                  * Note: signals (^C) can't interrupt here.
9131                                  * We remember them and they will be acted upon
9132                                  * after applet returns.
9133                                  * This makes applets which can run for a long time
9134                                  * and/or wait for user input ineligible for NOFORK:
9135                                  * for example, "yes" or "rm" (rm -i waits for input).
9136                                  */
9137                                 rcode = run_nofork_applet(n, argv_expanded);
9138                         }
9139                 } else
9140                         goto must_fork;
9141
9142                 restore_redirects(squirrel);
9143  clean_up_and_ret1:
9144                 leave_var_nest_level();
9145                 add_vars(old_vars);
9146
9147                 /*
9148                  * Try "usleep 99999999" + ^C + "echo $?"
9149                  * with FEATURE_SH_NOFORK=y.
9150                  */
9151                 if (!funcp) {
9152                         /* It was builtin or nofork.
9153                          * if this would be a real fork/execed program,
9154                          * it should have died if a fatal sig was received.
9155                          * But OTOH, there was no separate process,
9156                          * the sig was sent to _shell_, not to non-existing
9157                          * child.
9158                          * Let's just handle ^C only, this one is obvious:
9159                          * we aren't ok with exitcode 0 when ^C was pressed
9160                          * during builtin/nofork.
9161                          */
9162                         if (sigismember(&G.pending_set, SIGINT))
9163                                 rcode = 128 + SIGINT;
9164                 }
9165                 free(argv_expanded);
9166                 IF_HAS_KEYWORDS(if (pi->pi_inverted) rcode = !rcode;)
9167                 debug_leave();
9168                 debug_printf_exec("run_pipe return %d\n", rcode);
9169                 return rcode;
9170         }
9171
9172  must_fork:
9173         /* NB: argv_expanded may already be created, and that
9174          * might include `cmd` runs! Do not rerun it! We *must*
9175          * use argv_expanded if it's non-NULL */
9176
9177         /* Going to fork a child per each pipe member */
9178         pi->alive_cmds = 0;
9179         next_infd = 0;
9180
9181         cmd_no = 0;
9182         while (cmd_no < pi->num_cmds) {
9183                 struct fd_pair pipefds;
9184 #if !BB_MMU
9185                 int sv_var_nest_level = G.var_nest_level;
9186                 volatile nommu_save_t nommu_save;
9187                 nommu_save.old_vars = NULL;
9188                 nommu_save.argv = NULL;
9189                 nommu_save.argv_from_re_execing = NULL;
9190 #endif
9191                 command = &pi->cmds[cmd_no];
9192                 cmd_no++;
9193                 if (command->argv) {
9194                         debug_printf_exec(": pipe member '%s' '%s'...\n",
9195                                         command->argv[0], command->argv[1]);
9196                 } else {
9197                         debug_printf_exec(": pipe member with no argv\n");
9198                 }
9199
9200                 /* pipes are inserted between pairs of commands */
9201                 pipefds.rd = 0;
9202                 pipefds.wr = 1;
9203                 if (cmd_no < pi->num_cmds)
9204                         xpiped_pair(pipefds);
9205
9206 #if ENABLE_HUSH_LINENO_VAR
9207                 G.execute_lineno = command->lineno;
9208 #endif
9209
9210                 command->pid = BB_MMU ? fork() : vfork();
9211                 if (!command->pid) { /* child */
9212 #if ENABLE_HUSH_JOB
9213                         disable_restore_tty_pgrp_on_exit();
9214                         CLEAR_RANDOM_T(&G.random_gen); /* or else $RANDOM repeats in child */
9215
9216                         /* Every child adds itself to new process group
9217                          * with pgid == pid_of_first_child_in_pipe */
9218                         if (G.run_list_level == 1 && G_interactive_fd) {
9219                                 pid_t pgrp;
9220                                 pgrp = pi->pgrp;
9221                                 if (pgrp < 0) /* true for 1st process only */
9222                                         pgrp = getpid();
9223                                 if (setpgid(0, pgrp) == 0
9224                                  && pi->followup != PIPE_BG
9225                                  && G_saved_tty_pgrp /* we have ctty */
9226                                 ) {
9227                                         /* We do it in *every* child, not just first,
9228                                          * to avoid races */
9229                                         tcsetpgrp(G_interactive_fd, pgrp);
9230                                 }
9231                         }
9232 #endif
9233                         if (pi->alive_cmds == 0 && pi->followup == PIPE_BG) {
9234                                 /* 1st cmd in backgrounded pipe
9235                                  * should have its stdin /dev/null'ed */
9236                                 close(0);
9237                                 if (open(bb_dev_null, O_RDONLY))
9238                                         xopen("/", O_RDONLY);
9239                         } else {
9240                                 xmove_fd(next_infd, 0);
9241                         }
9242                         xmove_fd(pipefds.wr, 1);
9243                         if (pipefds.rd > 1)
9244                                 close(pipefds.rd);
9245                         /* Like bash, explicit redirects override pipes,
9246                          * and the pipe fd (fd#1) is available for dup'ing:
9247                          * "cmd1 2>&1 | cmd2": fd#1 is duped to fd#2, thus stderr
9248                          * of cmd1 goes into pipe.
9249                          */
9250                         if (setup_redirects(command, NULL)) {
9251                                 /* Happens when redir file can't be opened:
9252                                  * $ hush -c 'echo FOO >&2 | echo BAR 3>/qwe/rty; echo BAZ'
9253                                  * FOO
9254                                  * hush: can't open '/qwe/rty': No such file or directory
9255                                  * BAZ
9256                                  * (echo BAR is not executed, it hits _exit(1) below)
9257                                  */
9258                                 _exit(1);
9259                         }
9260
9261                         /* Stores to nommu_save list of env vars putenv'ed
9262                          * (NOMMU, on MMU we don't need that) */
9263                         /* cast away volatility... */
9264                         pseudo_exec((nommu_save_t*) &nommu_save, command, argv_expanded);
9265                         /* pseudo_exec() does not return */
9266                 }
9267
9268                 /* parent or error */
9269 #if ENABLE_HUSH_FAST
9270                 G.count_SIGCHLD++;
9271 //bb_error_msg("[%d] fork in run_pipe: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
9272 #endif
9273                 enable_restore_tty_pgrp_on_exit();
9274 #if !BB_MMU
9275                 /* Clean up after vforked child */
9276                 free(nommu_save.argv);
9277                 free(nommu_save.argv_from_re_execing);
9278                 G.var_nest_level = sv_var_nest_level;
9279                 remove_nested_vars();
9280                 add_vars(nommu_save.old_vars);
9281 #endif
9282                 free(argv_expanded);
9283                 argv_expanded = NULL;
9284                 if (command->pid < 0) { /* [v]fork failed */
9285                         /* Clearly indicate, was it fork or vfork */
9286                         bb_perror_msg(BB_MMU ? "vfork"+1 : "vfork");
9287                 } else {
9288                         pi->alive_cmds++;
9289 #if ENABLE_HUSH_JOB
9290                         /* Second and next children need to know pid of first one */
9291                         if (pi->pgrp < 0)
9292                                 pi->pgrp = command->pid;
9293 #endif
9294                 }
9295
9296                 if (cmd_no > 1)
9297                         close(next_infd);
9298                 if (cmd_no < pi->num_cmds)
9299                         close(pipefds.wr);
9300                 /* Pass read (output) pipe end to next iteration */
9301                 next_infd = pipefds.rd;
9302         }
9303
9304         if (!pi->alive_cmds) {
9305                 debug_leave();
9306                 debug_printf_exec("run_pipe return 1 (all forks failed, no children)\n");
9307                 return 1;
9308         }
9309
9310         debug_leave();
9311         debug_printf_exec("run_pipe return -1 (%u children started)\n", pi->alive_cmds);
9312         return -1;
9313 }
9314
9315 /* NB: called by pseudo_exec, and therefore must not modify any
9316  * global data until exec/_exit (we can be a child after vfork!) */
9317 static int run_list(struct pipe *pi)
9318 {
9319 #if ENABLE_HUSH_CASE
9320         char *case_word = NULL;
9321 #endif
9322 #if ENABLE_HUSH_LOOPS
9323         struct pipe *loop_top = NULL;
9324         char **for_lcur = NULL;
9325         char **for_list = NULL;
9326 #endif
9327         smallint last_followup;
9328         smalluint rcode;
9329 #if ENABLE_HUSH_IF || ENABLE_HUSH_CASE
9330         smalluint cond_code = 0;
9331 #else
9332         enum { cond_code = 0 };
9333 #endif
9334 #if HAS_KEYWORDS
9335         smallint rword;      /* RES_foo */
9336         smallint last_rword; /* ditto */
9337 #endif
9338
9339         debug_printf_exec("run_list start lvl %d\n", G.run_list_level);
9340         debug_enter();
9341
9342 #if ENABLE_HUSH_LOOPS
9343         /* Check syntax for "for" */
9344         {
9345                 struct pipe *cpipe;
9346                 for (cpipe = pi; cpipe; cpipe = cpipe->next) {
9347                         if (cpipe->res_word != RES_FOR && cpipe->res_word != RES_IN)
9348                                 continue;
9349                         /* current word is FOR or IN (BOLD in comments below) */
9350                         if (cpipe->next == NULL) {
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                         /* "FOR v; do ..." and "for v IN a b; do..." are ok */
9357                         if (cpipe->next->res_word == RES_DO)
9358                                 continue;
9359                         /* next word is not "do". It must be "in" then ("FOR v in ...") */
9360                         if (cpipe->res_word == RES_IN /* "for v IN a b; not_do..."? */
9361                          || cpipe->next->res_word != RES_IN /* FOR v not_do_and_not_in..."? */
9362                         ) {
9363                                 syntax_error("malformed for");
9364                                 debug_leave();
9365                                 debug_printf_exec("run_list lvl %d return 1\n", G.run_list_level);
9366                                 return 1;
9367                         }
9368                 }
9369         }
9370 #endif
9371
9372         /* Past this point, all code paths should jump to ret: label
9373          * in order to return, no direct "return" statements please.
9374          * This helps to ensure that no memory is leaked. */
9375
9376 #if ENABLE_HUSH_JOB
9377         G.run_list_level++;
9378 #endif
9379
9380 #if HAS_KEYWORDS
9381         rword = RES_NONE;
9382         last_rword = RES_XXXX;
9383 #endif
9384         last_followup = PIPE_SEQ;
9385         rcode = G.last_exitcode;
9386
9387         /* Go through list of pipes, (maybe) executing them. */
9388         for (; pi; pi = IF_HUSH_LOOPS(rword == RES_DONE ? loop_top : ) pi->next) {
9389                 int r;
9390                 int sv_errexit_depth;
9391
9392                 if (G.flag_SIGINT)
9393                         break;
9394                 if (G_flag_return_in_progress == 1)
9395                         break;
9396
9397                 IF_HAS_KEYWORDS(rword = pi->res_word;)
9398                 debug_printf_exec(": rword=%d cond_code=%d last_rword=%d\n",
9399                                 rword, cond_code, last_rword);
9400
9401                 sv_errexit_depth = G.errexit_depth;
9402                 if (
9403 #if ENABLE_HUSH_IF
9404                     rword == RES_IF || rword == RES_ELIF ||
9405 #endif
9406                     pi->followup != PIPE_SEQ
9407                 ) {
9408                         G.errexit_depth++;
9409                 }
9410 #if ENABLE_HUSH_LOOPS
9411                 if ((rword == RES_WHILE || rword == RES_UNTIL || rword == RES_FOR)
9412                  && loop_top == NULL /* avoid bumping G.depth_of_loop twice */
9413                 ) {
9414                         /* start of a loop: remember where loop starts */
9415                         loop_top = pi;
9416                         G.depth_of_loop++;
9417                 }
9418 #endif
9419                 /* Still in the same "if...", "then..." or "do..." branch? */
9420                 if (IF_HAS_KEYWORDS(rword == last_rword &&) 1) {
9421                         if ((rcode == 0 && last_followup == PIPE_OR)
9422                          || (rcode != 0 && last_followup == PIPE_AND)
9423                         ) {
9424                                 /* It is "<true> || CMD" or "<false> && CMD"
9425                                  * and we should not execute CMD */
9426                                 debug_printf_exec("skipped cmd because of || or &&\n");
9427                                 last_followup = pi->followup;
9428                                 goto dont_check_jobs_but_continue;
9429                         }
9430                 }
9431                 last_followup = pi->followup;
9432                 IF_HAS_KEYWORDS(last_rword = rword;)
9433 #if ENABLE_HUSH_IF
9434                 if (cond_code) {
9435                         if (rword == RES_THEN) {
9436                                 /* if false; then ... fi has exitcode 0! */
9437                                 G.last_exitcode = rcode = EXIT_SUCCESS;
9438                                 /* "if <false> THEN cmd": skip cmd */
9439                                 continue;
9440                         }
9441                 } else {
9442                         if (rword == RES_ELSE || rword == RES_ELIF) {
9443                                 /* "if <true> then ... ELSE/ELIF cmd":
9444                                  * skip cmd and all following ones */
9445                                 break;
9446                         }
9447                 }
9448 #endif
9449 #if ENABLE_HUSH_LOOPS
9450                 if (rword == RES_FOR) { /* && pi->num_cmds - always == 1 */
9451                         if (!for_lcur) {
9452                                 /* first loop through for */
9453
9454                                 static const char encoded_dollar_at[] ALIGN1 = {
9455                                         SPECIAL_VAR_SYMBOL, '@' | 0x80, SPECIAL_VAR_SYMBOL, '\0'
9456                                 }; /* encoded representation of "$@" */
9457                                 static const char *const encoded_dollar_at_argv[] = {
9458                                         encoded_dollar_at, NULL
9459                                 }; /* argv list with one element: "$@" */
9460                                 char **vals;
9461
9462                                 G.last_exitcode = rcode = EXIT_SUCCESS;
9463                                 vals = (char**)encoded_dollar_at_argv;
9464                                 if (pi->next->res_word == RES_IN) {
9465                                         /* if no variable values after "in" we skip "for" */
9466                                         if (!pi->next->cmds[0].argv) {
9467                                                 debug_printf_exec(": null FOR: exitcode EXIT_SUCCESS\n");
9468                                                 break;
9469                                         }
9470                                         vals = pi->next->cmds[0].argv;
9471                                 } /* else: "for var; do..." -> assume "$@" list */
9472                                 /* create list of variable values */
9473                                 debug_print_strings("for_list made from", vals);
9474                                 for_list = expand_strvec_to_strvec(vals);
9475                                 for_lcur = for_list;
9476                                 debug_print_strings("for_list", for_list);
9477                         }
9478                         if (!*for_lcur) {
9479                                 /* "for" loop is over, clean up */
9480                                 free(for_list);
9481                                 for_list = NULL;
9482                                 for_lcur = NULL;
9483                                 break;
9484                         }
9485                         /* Insert next value from for_lcur */
9486                         /* note: *for_lcur already has quotes removed, $var expanded, etc */
9487                         set_local_var(xasprintf("%s=%s", pi->cmds[0].argv[0], *for_lcur++), /*flag:*/ 0);
9488                         continue;
9489                 }
9490                 if (rword == RES_IN) {
9491                         continue; /* "for v IN list;..." - "in" has no cmds anyway */
9492                 }
9493                 if (rword == RES_DONE) {
9494                         continue; /* "done" has no cmds too */
9495                 }
9496 #endif
9497 #if ENABLE_HUSH_CASE
9498                 if (rword == RES_CASE) {
9499                         debug_printf_exec("CASE cond_code:%d\n", cond_code);
9500                         case_word = expand_string_to_string(pi->cmds->argv[0],
9501                                 EXP_FLAG_ESC_GLOB_CHARS, /*unbackslash:*/ 1);
9502                         debug_printf_exec("CASE word1:'%s'\n", case_word);
9503                         //unbackslash(case_word);
9504                         //debug_printf_exec("CASE word2:'%s'\n", case_word);
9505                         continue;
9506                 }
9507                 if (rword == RES_MATCH) {
9508                         char **argv;
9509
9510                         debug_printf_exec("MATCH cond_code:%d\n", cond_code);
9511                         if (!case_word) /* "case ... matched_word) ... WORD)": we executed selected branch, stop */
9512                                 break;
9513                         /* all prev words didn't match, does this one match? */
9514                         argv = pi->cmds->argv;
9515                         while (*argv) {
9516                                 char *pattern;
9517                                 debug_printf_exec("expand_string_to_string('%s')\n", *argv);
9518                                 pattern = expand_string_to_string(*argv,
9519                                                 EXP_FLAG_ESC_GLOB_CHARS,
9520                                                 /*unbackslash:*/ 0
9521                                 );
9522                                 /* TODO: which FNM_xxx flags to use? */
9523                                 cond_code = (fnmatch(pattern, case_word, /*flags:*/ 0) != 0);
9524                                 debug_printf_exec("fnmatch(pattern:'%s',str:'%s'):%d\n",
9525                                                 pattern, case_word, cond_code);
9526                                 free(pattern);
9527                                 if (cond_code == 0) {
9528                                         /* match! we will execute this branch */
9529                                         free(case_word);
9530                                         case_word = NULL; /* make future "word)" stop */
9531                                         break;
9532                                 }
9533                                 argv++;
9534                         }
9535                         continue;
9536                 }
9537                 if (rword == RES_CASE_BODY) { /* inside of a case branch */
9538                         debug_printf_exec("CASE_BODY cond_code:%d\n", cond_code);
9539                         if (cond_code != 0)
9540                                 continue; /* not matched yet, skip this pipe */
9541                 }
9542                 if (rword == RES_ESAC) {
9543                         debug_printf_exec("ESAC cond_code:%d\n", cond_code);
9544                         if (case_word) {
9545                                 /* "case" did not match anything: still set $? (to 0) */
9546                                 G.last_exitcode = rcode = EXIT_SUCCESS;
9547                         }
9548                 }
9549 #endif
9550                 /* Just pressing <enter> in shell should check for jobs.
9551                  * OTOH, in non-interactive shell this is useless
9552                  * and only leads to extra job checks */
9553                 if (pi->num_cmds == 0) {
9554                         if (G_interactive_fd)
9555                                 goto check_jobs_and_continue;
9556                         continue;
9557                 }
9558
9559                 /* After analyzing all keywords and conditions, we decided
9560                  * to execute this pipe. NB: have to do checkjobs(NULL)
9561                  * after run_pipe to collect any background children,
9562                  * even if list execution is to be stopped. */
9563                 debug_printf_exec(": run_pipe with %d members\n", pi->num_cmds);
9564 #if ENABLE_HUSH_LOOPS
9565                 G.flag_break_continue = 0;
9566 #endif
9567                 rcode = r = run_pipe(pi); /* NB: rcode is a smalluint, r is int */
9568                 if (r != -1) {
9569                         /* We ran a builtin, function, or group.
9570                          * rcode is already known
9571                          * and we don't need to wait for anything. */
9572                         debug_printf_exec(": builtin/func exitcode %d\n", rcode);
9573                         G.last_exitcode = rcode;
9574                         check_and_run_traps();
9575 #if ENABLE_HUSH_LOOPS
9576                         /* Was it "break" or "continue"? */
9577                         if (G.flag_break_continue) {
9578                                 smallint fbc = G.flag_break_continue;
9579                                 /* We might fall into outer *loop*,
9580                                  * don't want to break it too */
9581                                 if (loop_top) {
9582                                         G.depth_break_continue--;
9583                                         if (G.depth_break_continue == 0)
9584                                                 G.flag_break_continue = 0;
9585                                         /* else: e.g. "continue 2" should *break* once, *then* continue */
9586                                 } /* else: "while... do... { we are here (innermost list is not a loop!) };...done" */
9587                                 if (G.depth_break_continue != 0 || fbc == BC_BREAK) {
9588                                         checkjobs(NULL, 0 /*(no pid to wait for)*/);
9589                                         break;
9590                                 }
9591                                 /* "continue": simulate end of loop */
9592                                 rword = RES_DONE;
9593                                 continue;
9594                         }
9595 #endif
9596                         if (G_flag_return_in_progress == 1) {
9597                                 checkjobs(NULL, 0 /*(no pid to wait for)*/);
9598                                 break;
9599                         }
9600                 } else if (pi->followup == PIPE_BG) {
9601                         /* What does bash do with attempts to background builtins? */
9602                         /* even bash 3.2 doesn't do that well with nested bg:
9603                          * try "{ { sleep 10; echo DEEP; } & echo HERE; } &".
9604                          * I'm NOT treating inner &'s as jobs */
9605 #if ENABLE_HUSH_JOB
9606                         if (G.run_list_level == 1)
9607                                 insert_job_into_table(pi);
9608 #endif
9609                         /* Last command's pid goes to $! */
9610                         G.last_bg_pid = pi->cmds[pi->num_cmds - 1].pid;
9611                         G.last_bg_pid_exitcode = 0;
9612                         debug_printf_exec(": cmd&: exitcode EXIT_SUCCESS\n");
9613 /* Check pi->pi_inverted? "! sleep 1 & echo $?": bash says 1. dash and ash say 0 */
9614                         rcode = EXIT_SUCCESS;
9615                         goto check_traps;
9616                 } else {
9617 #if ENABLE_HUSH_JOB
9618                         if (G.run_list_level == 1 && G_interactive_fd) {
9619                                 /* Waits for completion, then fg's main shell */
9620                                 rcode = checkjobs_and_fg_shell(pi);
9621                                 debug_printf_exec(": checkjobs_and_fg_shell exitcode %d\n", rcode);
9622                                 goto check_traps;
9623                         }
9624 #endif
9625                         /* This one just waits for completion */
9626                         rcode = checkjobs(pi, 0 /*(no pid to wait for)*/);
9627                         debug_printf_exec(": checkjobs exitcode %d\n", rcode);
9628  check_traps:
9629                         G.last_exitcode = rcode;
9630                         check_and_run_traps();
9631                 }
9632
9633                 /* Handle "set -e" */
9634                 if (rcode != 0 && G.o_opt[OPT_O_ERREXIT]) {
9635                         debug_printf_exec("ERREXIT:1 errexit_depth:%d\n", G.errexit_depth);
9636                         if (G.errexit_depth == 0)
9637                                 hush_exit(rcode);
9638                 }
9639                 G.errexit_depth = sv_errexit_depth;
9640
9641                 /* Analyze how result affects subsequent commands */
9642 #if ENABLE_HUSH_IF
9643                 if (rword == RES_IF || rword == RES_ELIF)
9644                         cond_code = rcode;
9645 #endif
9646  check_jobs_and_continue:
9647                 checkjobs(NULL, 0 /*(no pid to wait for)*/);
9648  dont_check_jobs_but_continue: ;
9649 #if ENABLE_HUSH_LOOPS
9650                 /* Beware of "while false; true; do ..."! */
9651                 if (pi->next
9652                  && (pi->next->res_word == RES_DO || pi->next->res_word == RES_DONE)
9653                  /* check for RES_DONE is needed for "while ...; do \n done" case */
9654                 ) {
9655                         if (rword == RES_WHILE) {
9656                                 if (rcode) {
9657                                         /* "while false; do...done" - exitcode 0 */
9658                                         G.last_exitcode = rcode = EXIT_SUCCESS;
9659                                         debug_printf_exec(": while expr is false: breaking (exitcode:EXIT_SUCCESS)\n");
9660                                         break;
9661                                 }
9662                         }
9663                         if (rword == RES_UNTIL) {
9664                                 if (!rcode) {
9665                                         debug_printf_exec(": until expr is true: breaking\n");
9666                                         break;
9667                                 }
9668                         }
9669                 }
9670 #endif
9671         } /* for (pi) */
9672
9673 #if ENABLE_HUSH_JOB
9674         G.run_list_level--;
9675 #endif
9676 #if ENABLE_HUSH_LOOPS
9677         if (loop_top)
9678                 G.depth_of_loop--;
9679         free(for_list);
9680 #endif
9681 #if ENABLE_HUSH_CASE
9682         free(case_word);
9683 #endif
9684         debug_leave();
9685         debug_printf_exec("run_list lvl %d return %d\n", G.run_list_level + 1, rcode);
9686         return rcode;
9687 }
9688
9689 /* Select which version we will use */
9690 static int run_and_free_list(struct pipe *pi)
9691 {
9692         int rcode = 0;
9693         debug_printf_exec("run_and_free_list entered\n");
9694         if (!G.o_opt[OPT_O_NOEXEC]) {
9695                 debug_printf_exec(": run_list: 1st pipe with %d cmds\n", pi->num_cmds);
9696                 rcode = run_list(pi);
9697         }
9698         /* free_pipe_list has the side effect of clearing memory.
9699          * In the long run that function can be merged with run_list,
9700          * but doing that now would hobble the debugging effort. */
9701         free_pipe_list(pi);
9702         debug_printf_exec("run_and_free_list return %d\n", rcode);
9703         return rcode;
9704 }
9705
9706
9707 static void install_sighandlers(unsigned mask)
9708 {
9709         sighandler_t old_handler;
9710         unsigned sig = 0;
9711         while ((mask >>= 1) != 0) {
9712                 sig++;
9713                 if (!(mask & 1))
9714                         continue;
9715                 old_handler = install_sighandler(sig, pick_sighandler(sig));
9716                 /* POSIX allows shell to re-enable SIGCHLD
9717                  * even if it was SIG_IGN on entry.
9718                  * Therefore we skip IGN check for it:
9719                  */
9720                 if (sig == SIGCHLD)
9721                         continue;
9722                 /* bash re-enables SIGHUP which is SIG_IGNed on entry.
9723                  * Try: "trap '' HUP; bash; echo RET" and type "kill -HUP $$"
9724                  */
9725                 //if (sig == SIGHUP) continue; - TODO?
9726                 if (old_handler == SIG_IGN) {
9727                         /* oops... restore back to IGN, and record this fact */
9728                         install_sighandler(sig, old_handler);
9729 #if ENABLE_HUSH_TRAP
9730                         if (!G_traps)
9731                                 G_traps = xzalloc(sizeof(G_traps[0]) * NSIG);
9732                         free(G_traps[sig]);
9733                         G_traps[sig] = xzalloc(1); /* == xstrdup(""); */
9734 #endif
9735                 }
9736         }
9737 }
9738
9739 /* Called a few times only (or even once if "sh -c") */
9740 static void install_special_sighandlers(void)
9741 {
9742         unsigned mask;
9743
9744         /* Which signals are shell-special? */
9745         mask = (1 << SIGQUIT) | (1 << SIGCHLD);
9746         if (G_interactive_fd) {
9747                 mask |= SPECIAL_INTERACTIVE_SIGS;
9748                 if (G_saved_tty_pgrp) /* we have ctty, job control sigs work */
9749                         mask |= SPECIAL_JOBSTOP_SIGS;
9750         }
9751         /* Careful, do not re-install handlers we already installed */
9752         if (G.special_sig_mask != mask) {
9753                 unsigned diff = mask & ~G.special_sig_mask;
9754                 G.special_sig_mask = mask;
9755                 install_sighandlers(diff);
9756         }
9757 }
9758
9759 #if ENABLE_HUSH_JOB
9760 /* helper */
9761 /* Set handlers to restore tty pgrp and exit */
9762 static void install_fatal_sighandlers(void)
9763 {
9764         unsigned mask;
9765
9766         /* We will restore tty pgrp on these signals */
9767         mask = 0
9768                 /*+ (1 << SIGILL ) * HUSH_DEBUG*/
9769                 /*+ (1 << SIGFPE ) * HUSH_DEBUG*/
9770                 + (1 << SIGBUS ) * HUSH_DEBUG
9771                 + (1 << SIGSEGV) * HUSH_DEBUG
9772                 /*+ (1 << SIGTRAP) * HUSH_DEBUG*/
9773                 + (1 << SIGABRT)
9774         /* bash 3.2 seems to handle these just like 'fatal' ones */
9775                 + (1 << SIGPIPE)
9776                 + (1 << SIGALRM)
9777         /* if we are interactive, SIGHUP, SIGTERM and SIGINT are special sigs.
9778          * if we aren't interactive... but in this case
9779          * we never want to restore pgrp on exit, and this fn is not called
9780          */
9781                 /*+ (1 << SIGHUP )*/
9782                 /*+ (1 << SIGTERM)*/
9783                 /*+ (1 << SIGINT )*/
9784         ;
9785         G_fatal_sig_mask = mask;
9786
9787         install_sighandlers(mask);
9788 }
9789 #endif
9790
9791 static int set_mode(int state, char mode, const char *o_opt)
9792 {
9793         int idx;
9794         switch (mode) {
9795         case 'n':
9796                 G.o_opt[OPT_O_NOEXEC] = state;
9797                 break;
9798         case 'x':
9799                 IF_HUSH_MODE_X(G_x_mode = state;)
9800                 IF_HUSH_MODE_X(if (G.x_mode_fd <= 0) G.x_mode_fd = dup_CLOEXEC(2, 10);)
9801                 break;
9802         case 'o':
9803                 if (!o_opt) {
9804                         /* "set -+o" without parameter.
9805                          * in bash, set -o produces this output:
9806                          *  pipefail        off
9807                          * and set +o:
9808                          *  set +o pipefail
9809                          * We always use the second form.
9810                          */
9811                         const char *p = o_opt_strings;
9812                         idx = 0;
9813                         while (*p) {
9814                                 printf("set %co %s\n", (G.o_opt[idx] ? '-' : '+'), p);
9815                                 idx++;
9816                                 p += strlen(p) + 1;
9817                         }
9818                         break;
9819                 }
9820                 idx = index_in_strings(o_opt_strings, o_opt);
9821                 if (idx >= 0) {
9822                         G.o_opt[idx] = state;
9823                         break;
9824                 }
9825         case 'e':
9826                 G.o_opt[OPT_O_ERREXIT] = state;
9827                 break;
9828         default:
9829                 return EXIT_FAILURE;
9830         }
9831         return EXIT_SUCCESS;
9832 }
9833
9834 int hush_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
9835 int hush_main(int argc, char **argv)
9836 {
9837         enum {
9838                 OPT_login = (1 << 0),
9839                 OPT_s     = (1 << 1),
9840         };
9841         unsigned flags;
9842         unsigned builtin_argc;
9843         char **e;
9844         struct variable *cur_var;
9845         struct variable *shell_ver;
9846
9847         INIT_G();
9848         if (EXIT_SUCCESS != 0) /* if EXIT_SUCCESS == 0, it is already done */
9849                 G.last_exitcode = EXIT_SUCCESS;
9850
9851 #if ENABLE_HUSH_FAST
9852         G.count_SIGCHLD++; /* ensure it is != G.handled_SIGCHLD */
9853 #endif
9854 #if !BB_MMU
9855         G.argv0_for_re_execing = argv[0];
9856 #endif
9857
9858         /* Deal with HUSH_VERSION */
9859         debug_printf_env("unsetenv '%s'\n", "HUSH_VERSION");
9860         unsetenv("HUSH_VERSION"); /* in case it exists in initial env */
9861         shell_ver = xzalloc(sizeof(*shell_ver));
9862         shell_ver->flg_export = 1;
9863         shell_ver->flg_read_only = 1;
9864         /* Code which handles ${var<op>...} needs writable values for all variables,
9865          * therefore we xstrdup: */
9866         shell_ver->varstr = xstrdup(hush_version_str);
9867
9868         /* Create shell local variables from the values
9869          * currently living in the environment */
9870         G.top_var = shell_ver;
9871         cur_var = G.top_var;
9872         e = environ;
9873         if (e) while (*e) {
9874                 char *value = strchr(*e, '=');
9875                 if (value) { /* paranoia */
9876                         cur_var->next = xzalloc(sizeof(*cur_var));
9877                         cur_var = cur_var->next;
9878                         cur_var->varstr = *e;
9879                         cur_var->max_len = strlen(*e);
9880                         cur_var->flg_export = 1;
9881                 }
9882                 e++;
9883         }
9884         /* (Re)insert HUSH_VERSION into env (AFTER we scanned the env!) */
9885         debug_printf_env("putenv '%s'\n", shell_ver->varstr);
9886         putenv(shell_ver->varstr);
9887
9888         /* Export PWD */
9889         set_pwd_var(SETFLAG_EXPORT);
9890
9891 #if ENABLE_HUSH_INTERACTIVE && ENABLE_FEATURE_EDITING_FANCY_PROMPT
9892         /* Set (but not export) PS1/2 unless already set */
9893         if (!get_local_var_value("PS1"))
9894                 set_local_var_from_halves("PS1", "\\w \\$ ");
9895         if (!get_local_var_value("PS2"))
9896                 set_local_var_from_halves("PS2", "> ");
9897 #endif
9898
9899 #if BASH_HOSTNAME_VAR
9900         /* Set (but not export) HOSTNAME unless already set */
9901         if (!get_local_var_value("HOSTNAME")) {
9902                 struct utsname uts;
9903                 uname(&uts);
9904                 set_local_var_from_halves("HOSTNAME", uts.nodename);
9905         }
9906 #endif
9907         /* IFS is not inherited from the parent environment */
9908         set_local_var_from_halves("IFS", defifs);
9909
9910         /* bash also exports SHLVL and _,
9911          * and sets (but doesn't export) the following variables:
9912          * BASH=/bin/bash
9913          * BASH_VERSINFO=([0]="3" [1]="2" [2]="0" [3]="1" [4]="release" [5]="i386-pc-linux-gnu")
9914          * BASH_VERSION='3.2.0(1)-release'
9915          * HOSTTYPE=i386
9916          * MACHTYPE=i386-pc-linux-gnu
9917          * OSTYPE=linux-gnu
9918          * PPID=<NNNNN> - we also do it elsewhere
9919          * EUID=<NNNNN>
9920          * UID=<NNNNN>
9921          * GROUPS=()
9922          * LINES=<NNN>
9923          * COLUMNS=<NNN>
9924          * BASH_ARGC=()
9925          * BASH_ARGV=()
9926          * BASH_LINENO=()
9927          * BASH_SOURCE=()
9928          * DIRSTACK=()
9929          * PIPESTATUS=([0]="0")
9930          * HISTFILE=/<xxx>/.bash_history
9931          * HISTFILESIZE=500
9932          * HISTSIZE=500
9933          * MAILCHECK=60
9934          * PATH=/usr/gnu/bin:/usr/local/bin:/bin:/usr/bin:.
9935          * SHELL=/bin/bash
9936          * SHELLOPTS=braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor
9937          * TERM=dumb
9938          * OPTERR=1
9939          * OPTIND=1
9940          * PS4='+ '
9941          */
9942
9943 #if ENABLE_FEATURE_EDITING
9944         G.line_input_state = new_line_input_t(FOR_SHELL);
9945 #endif
9946
9947         /* Initialize some more globals to non-zero values */
9948         die_func = restore_ttypgrp_and__exit;
9949
9950         /* Shell is non-interactive at first. We need to call
9951          * install_special_sighandlers() if we are going to execute "sh <script>",
9952          * "sh -c <cmds>" or login shell's /etc/profile and friends.
9953          * If we later decide that we are interactive, we run install_special_sighandlers()
9954          * in order to intercept (more) signals.
9955          */
9956
9957         /* Parse options */
9958         /* http://www.opengroup.org/onlinepubs/9699919799/utilities/sh.html */
9959         flags = (argv[0] && argv[0][0] == '-') ? OPT_login : 0;
9960         builtin_argc = 0;
9961 #if NUM_SCRIPTS > 0
9962         if (argc < 0) {
9963                 optarg = get_script_content(-argc - 1);
9964                 optind = 0;
9965                 argc = string_array_len(argv);
9966                 goto run_script;
9967         }
9968 #endif
9969         while (1) {
9970                 int opt = getopt(argc, argv, "+c:exinsl"
9971 #if !BB_MMU
9972                                 "<:$:R:V:"
9973 # if ENABLE_HUSH_FUNCTIONS
9974                                 "F:"
9975 # endif
9976 #endif
9977                 );
9978                 if (opt <= 0)
9979                         break;
9980                 switch (opt) {
9981                 case 'c':
9982                         /* Possibilities:
9983                          * sh ... -c 'script'
9984                          * sh ... -c 'script' ARG0 [ARG1...]
9985                          * On NOMMU, if builtin_argc != 0,
9986                          * sh ... -c 'builtin' BARGV... "" ARG0 [ARG1...]
9987                          * "" needs to be replaced with NULL
9988                          * and BARGV vector fed to builtin function.
9989                          * Note: the form without ARG0 never happens:
9990                          * sh ... -c 'builtin' BARGV... ""
9991                          */
9992 #if NUM_SCRIPTS > 0
9993  run_script:
9994 #endif
9995                         if (!G.root_pid) {
9996                                 G.root_pid = getpid();
9997                                 G.root_ppid = getppid();
9998                         }
9999                         G.global_argv = argv + optind;
10000                         G.global_argc = argc - optind;
10001                         if (builtin_argc) {
10002                                 /* -c 'builtin' [BARGV...] "" ARG0 [ARG1...] */
10003                                 const struct built_in_command *x;
10004
10005                                 install_special_sighandlers();
10006                                 x = find_builtin(optarg);
10007                                 if (x) { /* paranoia */
10008                                         G.global_argc -= builtin_argc; /* skip [BARGV...] "" */
10009                                         G.global_argv += builtin_argc;
10010                                         G.global_argv[-1] = NULL; /* replace "" */
10011                                         fflush_all();
10012                                         G.last_exitcode = x->b_function(argv + optind - 1);
10013                                 }
10014                                 goto final_return;
10015                         }
10016                         if (!G.global_argv[0]) {
10017                                 /* -c 'script' (no params): prevent empty $0 */
10018                                 G.global_argv--; /* points to argv[i] of 'script' */
10019                                 G.global_argv[0] = argv[0];
10020                                 G.global_argc++;
10021                         } /* else -c 'script' ARG0 [ARG1...]: $0 is ARG0 */
10022                         install_special_sighandlers();
10023                         parse_and_run_string(optarg);
10024                         goto final_return;
10025                 case 'i':
10026                         /* Well, we cannot just declare interactiveness,
10027                          * we have to have some stuff (ctty, etc) */
10028                         /* G_interactive_fd++; */
10029                         break;
10030                 case 's':
10031                         flags |= OPT_s;
10032                         break;
10033                 case 'l':
10034                         flags |= OPT_login;
10035                         break;
10036 #if !BB_MMU
10037                 case '<': /* "big heredoc" support */
10038                         full_write1_str(optarg);
10039                         _exit(0);
10040                 case '$': {
10041                         unsigned long long empty_trap_mask;
10042
10043                         G.root_pid = bb_strtou(optarg, &optarg, 16);
10044                         optarg++;
10045                         G.root_ppid = bb_strtou(optarg, &optarg, 16);
10046                         optarg++;
10047                         G.last_bg_pid = bb_strtou(optarg, &optarg, 16);
10048                         optarg++;
10049                         G.last_exitcode = bb_strtou(optarg, &optarg, 16);
10050                         optarg++;
10051                         builtin_argc = bb_strtou(optarg, &optarg, 16);
10052                         optarg++;
10053                         empty_trap_mask = bb_strtoull(optarg, &optarg, 16);
10054                         if (empty_trap_mask != 0) {
10055                                 IF_HUSH_TRAP(int sig;)
10056                                 install_special_sighandlers();
10057 # if ENABLE_HUSH_TRAP
10058                                 G_traps = xzalloc(sizeof(G_traps[0]) * NSIG);
10059                                 for (sig = 1; sig < NSIG; sig++) {
10060                                         if (empty_trap_mask & (1LL << sig)) {
10061                                                 G_traps[sig] = xzalloc(1); /* == xstrdup(""); */
10062                                                 install_sighandler(sig, SIG_IGN);
10063                                         }
10064                                 }
10065 # endif
10066                         }
10067 # if ENABLE_HUSH_LOOPS
10068                         optarg++;
10069                         G.depth_of_loop = bb_strtou(optarg, &optarg, 16);
10070 # endif
10071 # if ENABLE_HUSH_FUNCTIONS
10072                         /* nommu uses re-exec trick for "... | func | ...",
10073                          * should allow "return".
10074                          * This accidentally allows returns in subshells.
10075                          */
10076                         G_flag_return_in_progress = -1;
10077 # endif
10078                         break;
10079                 }
10080                 case 'R':
10081                 case 'V':
10082                         set_local_var(xstrdup(optarg), opt == 'R' ? SETFLAG_MAKE_RO : 0);
10083                         break;
10084 # if ENABLE_HUSH_FUNCTIONS
10085                 case 'F': {
10086                         struct function *funcp = new_function(optarg);
10087                         /* funcp->name is already set to optarg */
10088                         /* funcp->body is set to NULL. It's a special case. */
10089                         funcp->body_as_string = argv[optind];
10090                         optind++;
10091                         break;
10092                 }
10093 # endif
10094 #endif
10095                 case 'n':
10096                 case 'x':
10097                 case 'e':
10098                         if (set_mode(1, opt, NULL) == 0) /* no error */
10099                                 break;
10100                 default:
10101 #ifndef BB_VER
10102                         fprintf(stderr, "Usage: sh [FILE]...\n"
10103                                         "   or: sh -c command [args]...\n\n");
10104                         exit(EXIT_FAILURE);
10105 #else
10106                         bb_show_usage();
10107 #endif
10108                 }
10109         } /* option parsing loop */
10110
10111         /* Skip options. Try "hush -l": $1 should not be "-l"! */
10112         G.global_argc = argc - (optind - 1);
10113         G.global_argv = argv + (optind - 1);
10114         G.global_argv[0] = argv[0];
10115
10116         if (!G.root_pid) {
10117                 G.root_pid = getpid();
10118                 G.root_ppid = getppid();
10119         }
10120
10121         /* If we are login shell... */
10122         if (flags & OPT_login) {
10123                 HFILE *input;
10124                 debug_printf("sourcing /etc/profile\n");
10125                 input = hfopen("/etc/profile");
10126                 if (input != NULL) {
10127                         install_special_sighandlers();
10128                         parse_and_run_file(input);
10129                         hfclose(input);
10130                 }
10131                 /* bash: after sourcing /etc/profile,
10132                  * tries to source (in the given order):
10133                  * ~/.bash_profile, ~/.bash_login, ~/.profile,
10134                  * stopping on first found. --noprofile turns this off.
10135                  * bash also sources ~/.bash_logout on exit.
10136                  * If called as sh, skips .bash_XXX files.
10137                  */
10138         }
10139
10140         /* -s is: hush -s ARGV1 ARGV2 (no SCRIPT) */
10141         if (!(flags & OPT_s) && G.global_argv[1]) {
10142                 HFILE *input;
10143                 /*
10144                  * "bash <script>" (which is never interactive (unless -i?))
10145                  * sources $BASH_ENV here (without scanning $PATH).
10146                  * If called as sh, does the same but with $ENV.
10147                  * Also NB, per POSIX, $ENV should undergo parameter expansion.
10148                  */
10149                 G.global_argc--;
10150                 G.global_argv++;
10151                 debug_printf("running script '%s'\n", G.global_argv[0]);
10152                 xfunc_error_retval = 127; /* for "hush /does/not/exist" case */
10153                 input = hfopen(G.global_argv[0]);
10154                 if (!input) {
10155                         bb_simple_perror_msg_and_die(G.global_argv[0]);
10156                 }
10157                 xfunc_error_retval = 1;
10158                 install_special_sighandlers();
10159                 parse_and_run_file(input);
10160 #if ENABLE_FEATURE_CLEAN_UP
10161                 hfclose(input);
10162 #endif
10163                 goto final_return;
10164         }
10165
10166         /* Up to here, shell was non-interactive. Now it may become one.
10167          * NB: don't forget to (re)run install_special_sighandlers() as needed.
10168          */
10169
10170         /* A shell is interactive if the '-i' flag was given,
10171          * or if all of the following conditions are met:
10172          *    no -c command
10173          *    no arguments remaining or the -s flag given
10174          *    standard input is a terminal
10175          *    standard output is a terminal
10176          * Refer to Posix.2, the description of the 'sh' utility.
10177          */
10178 #if ENABLE_HUSH_JOB
10179         if (isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)) {
10180                 G_saved_tty_pgrp = tcgetpgrp(STDIN_FILENO);
10181                 debug_printf("saved_tty_pgrp:%d\n", G_saved_tty_pgrp);
10182                 if (G_saved_tty_pgrp < 0)
10183                         G_saved_tty_pgrp = 0;
10184
10185                 /* try to dup stdin to high fd#, >= 255 */
10186                 G_interactive_fd = dup_CLOEXEC(STDIN_FILENO, 254);
10187                 if (G_interactive_fd < 0) {
10188                         /* try to dup to any fd */
10189                         G_interactive_fd = dup(STDIN_FILENO);
10190                         if (G_interactive_fd < 0) {
10191                                 /* give up */
10192                                 G_interactive_fd = 0;
10193                                 G_saved_tty_pgrp = 0;
10194                         }
10195                 }
10196 // TODO: track & disallow any attempts of user
10197 // to (inadvertently) close/redirect G_interactive_fd
10198         }
10199         debug_printf("interactive_fd:%d\n", G_interactive_fd);
10200         if (G_interactive_fd) {
10201                 close_on_exec_on(G_interactive_fd);
10202
10203                 if (G_saved_tty_pgrp) {
10204                         /* If we were run as 'hush &', sleep until we are
10205                          * in the foreground (tty pgrp == our pgrp).
10206                          * If we get started under a job aware app (like bash),
10207                          * make sure we are now in charge so we don't fight over
10208                          * who gets the foreground */
10209                         while (1) {
10210                                 pid_t shell_pgrp = getpgrp();
10211                                 G_saved_tty_pgrp = tcgetpgrp(G_interactive_fd);
10212                                 if (G_saved_tty_pgrp == shell_pgrp)
10213                                         break;
10214                                 /* send TTIN to ourself (should stop us) */
10215                                 kill(- shell_pgrp, SIGTTIN);
10216                         }
10217                 }
10218
10219                 /* Install more signal handlers */
10220                 install_special_sighandlers();
10221
10222                 if (G_saved_tty_pgrp) {
10223                         /* Set other signals to restore saved_tty_pgrp */
10224                         install_fatal_sighandlers();
10225                         /* Put ourselves in our own process group
10226                          * (bash, too, does this only if ctty is available) */
10227                         bb_setpgrp(); /* is the same as setpgid(our_pid, our_pid); */
10228                         /* Grab control of the terminal */
10229                         tcsetpgrp(G_interactive_fd, getpid());
10230                 }
10231                 enable_restore_tty_pgrp_on_exit();
10232
10233 # if ENABLE_HUSH_SAVEHISTORY && MAX_HISTORY > 0
10234                 {
10235                         const char *hp = get_local_var_value("HISTFILE");
10236                         if (!hp) {
10237                                 hp = get_local_var_value("HOME");
10238                                 if (hp)
10239                                         hp = concat_path_file(hp, ".hush_history");
10240                         } else {
10241                                 hp = xstrdup(hp);
10242                         }
10243                         if (hp) {
10244                                 G.line_input_state->hist_file = hp;
10245                                 //set_local_var(xasprintf("HISTFILE=%s", ...));
10246                         }
10247 #  if ENABLE_FEATURE_SH_HISTFILESIZE
10248                         hp = get_local_var_value("HISTFILESIZE");
10249                         G.line_input_state->max_history = size_from_HISTFILESIZE(hp);
10250 #  endif
10251                 }
10252 # endif
10253         } else {
10254                 install_special_sighandlers();
10255         }
10256 #elif ENABLE_HUSH_INTERACTIVE
10257         /* No job control compiled in, only prompt/line editing */
10258         if (isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)) {
10259                 G_interactive_fd = dup_CLOEXEC(STDIN_FILENO, 254);
10260                 if (G_interactive_fd < 0) {
10261                         /* try to dup to any fd */
10262                         G_interactive_fd = dup_CLOEXEC(STDIN_FILENO, -1);
10263                         if (G_interactive_fd < 0)
10264                                 /* give up */
10265                                 G_interactive_fd = 0;
10266                 }
10267         }
10268         if (G_interactive_fd) {
10269                 close_on_exec_on(G_interactive_fd);
10270         }
10271         install_special_sighandlers();
10272 #else
10273         /* We have interactiveness code disabled */
10274         install_special_sighandlers();
10275 #endif
10276         /* bash:
10277          * if interactive but not a login shell, sources ~/.bashrc
10278          * (--norc turns this off, --rcfile <file> overrides)
10279          */
10280
10281         if (!ENABLE_FEATURE_SH_EXTRA_QUIET && G_interactive_fd) {
10282                 /* note: ash and hush share this string */
10283                 printf("\n\n%s %s\n"
10284                         IF_HUSH_HELP("Enter 'help' for a list of built-in commands.\n")
10285                         "\n",
10286                         bb_banner,
10287                         "hush - the humble shell"
10288                 );
10289         }
10290
10291         parse_and_run_file(hfopen(NULL)); /* stdin */
10292
10293  final_return:
10294         hush_exit(G.last_exitcode);
10295 }
10296
10297
10298 /*
10299  * Built-ins
10300  */
10301 static int FAST_FUNC builtin_true(char **argv UNUSED_PARAM)
10302 {
10303         return 0;
10304 }
10305
10306 #if ENABLE_HUSH_TEST || ENABLE_HUSH_ECHO || ENABLE_HUSH_PRINTF || ENABLE_HUSH_KILL
10307 static int run_applet_main(char **argv, int (*applet_main_func)(int argc, char **argv))
10308 {
10309         int argc = string_array_len(argv);
10310         return applet_main_func(argc, argv);
10311 }
10312 #endif
10313 #if ENABLE_HUSH_TEST || BASH_TEST2
10314 static int FAST_FUNC builtin_test(char **argv)
10315 {
10316         return run_applet_main(argv, test_main);
10317 }
10318 #endif
10319 #if ENABLE_HUSH_ECHO
10320 static int FAST_FUNC builtin_echo(char **argv)
10321 {
10322         return run_applet_main(argv, echo_main);
10323 }
10324 #endif
10325 #if ENABLE_HUSH_PRINTF
10326 static int FAST_FUNC builtin_printf(char **argv)
10327 {
10328         return run_applet_main(argv, printf_main);
10329 }
10330 #endif
10331
10332 #if ENABLE_HUSH_HELP
10333 static int FAST_FUNC builtin_help(char **argv UNUSED_PARAM)
10334 {
10335         const struct built_in_command *x;
10336
10337         printf(
10338                 "Built-in commands:\n"
10339                 "------------------\n");
10340         for (x = bltins1; x != &bltins1[ARRAY_SIZE(bltins1)]; x++) {
10341                 if (x->b_descr)
10342                         printf("%-10s%s\n", x->b_cmd, x->b_descr);
10343         }
10344         return EXIT_SUCCESS;
10345 }
10346 #endif
10347
10348 #if MAX_HISTORY && ENABLE_FEATURE_EDITING
10349 static int FAST_FUNC builtin_history(char **argv UNUSED_PARAM)
10350 {
10351         show_history(G.line_input_state);
10352         return EXIT_SUCCESS;
10353 }
10354 #endif
10355
10356 static char **skip_dash_dash(char **argv)
10357 {
10358         argv++;
10359         if (argv[0] && argv[0][0] == '-' && argv[0][1] == '-' && argv[0][2] == '\0')
10360                 argv++;
10361         return argv;
10362 }
10363
10364 static int FAST_FUNC builtin_cd(char **argv)
10365 {
10366         const char *newdir;
10367
10368         argv = skip_dash_dash(argv);
10369         newdir = argv[0];
10370         if (newdir == NULL) {
10371                 /* bash does nothing (exitcode 0) if HOME is ""; if it's unset,
10372                  * bash says "bash: cd: HOME not set" and does nothing
10373                  * (exitcode 1)
10374                  */
10375                 const char *home = get_local_var_value("HOME");
10376                 newdir = home ? home : "/";
10377         }
10378         if (chdir(newdir)) {
10379                 /* Mimic bash message exactly */
10380                 bb_perror_msg("cd: %s", newdir);
10381                 return EXIT_FAILURE;
10382         }
10383         /* Read current dir (get_cwd(1) is inside) and set PWD.
10384          * Note: do not enforce exporting. If PWD was unset or unexported,
10385          * set it again, but do not export. bash does the same.
10386          */
10387         set_pwd_var(/*flag:*/ 0);
10388         return EXIT_SUCCESS;
10389 }
10390
10391 static int FAST_FUNC builtin_pwd(char **argv UNUSED_PARAM)
10392 {
10393         puts(get_cwd(0));
10394         return EXIT_SUCCESS;
10395 }
10396
10397 static int FAST_FUNC builtin_eval(char **argv)
10398 {
10399         argv = skip_dash_dash(argv);
10400
10401         if (!argv[0])
10402                 return EXIT_SUCCESS;
10403
10404         IF_HUSH_MODE_X(G.x_mode_depth++;)
10405         //bb_error_msg("%s: ++x_mode_depth=%d", __func__, G.x_mode_depth);
10406         if (!argv[1]) {
10407                 /* bash:
10408                  * eval "echo Hi; done" ("done" is syntax error):
10409                  * "echo Hi" will not execute too.
10410                  */
10411                 parse_and_run_string(argv[0]);
10412         } else {
10413                 /* "The eval utility shall construct a command by
10414                  * concatenating arguments together, separating
10415                  * each with a <space> character."
10416                  */
10417                 char *str, *p;
10418                 unsigned len = 0;
10419                 char **pp = argv;
10420                 do
10421                         len += strlen(*pp) + 1;
10422                 while (*++pp);
10423                 str = p = xmalloc(len);
10424                 pp = argv;
10425                 for (;;) {
10426                         p = stpcpy(p, *pp);
10427                         pp++;
10428                         if (!*pp)
10429                                 break;
10430                         *p++ = ' ';
10431                 }
10432                 parse_and_run_string(str);
10433                 free(str);
10434         }
10435         IF_HUSH_MODE_X(G.x_mode_depth--;)
10436         //bb_error_msg("%s: --x_mode_depth=%d", __func__, G.x_mode_depth);
10437         return G.last_exitcode;
10438 }
10439
10440 static int FAST_FUNC builtin_exec(char **argv)
10441 {
10442         argv = skip_dash_dash(argv);
10443         if (argv[0] == NULL)
10444                 return EXIT_SUCCESS; /* bash does this */
10445
10446         /* Careful: we can end up here after [v]fork. Do not restore
10447          * tty pgrp then, only top-level shell process does that */
10448         if (G_saved_tty_pgrp && getpid() == G.root_pid)
10449                 tcsetpgrp(G_interactive_fd, G_saved_tty_pgrp);
10450
10451         /* Saved-redirect fds, script fds and G_interactive_fd are still
10452          * open here. However, they are all CLOEXEC, and execv below
10453          * closes them. Try interactive "exec ls -l /proc/self/fd",
10454          * it should show no extra open fds in the "ls" process.
10455          * If we'd try to run builtins/NOEXECs, this would need improving.
10456          */
10457         //close_saved_fds_and_FILE_fds();
10458
10459         /* TODO: if exec fails, bash does NOT exit! We do.
10460          * We'll need to undo trap cleanup (it's inside execvp_or_die)
10461          * and tcsetpgrp, and this is inherently racy.
10462          */
10463         execvp_or_die(argv);
10464 }
10465
10466 static int FAST_FUNC builtin_exit(char **argv)
10467 {
10468         debug_printf_exec("%s()\n", __func__);
10469
10470         /* interactive bash:
10471          * # trap "echo EEE" EXIT
10472          * # exit
10473          * exit
10474          * There are stopped jobs.
10475          * (if there are _stopped_ jobs, running ones don't count)
10476          * # exit
10477          * exit
10478          * EEE (then bash exits)
10479          *
10480          * TODO: we can use G.exiting = -1 as indicator "last cmd was exit"
10481          */
10482
10483         /* note: EXIT trap is run by hush_exit */
10484         argv = skip_dash_dash(argv);
10485         if (argv[0] == NULL)
10486                 hush_exit(G.last_exitcode);
10487         /* mimic bash: exit 123abc == exit 255 + error msg */
10488         xfunc_error_retval = 255;
10489         /* bash: exit -2 == exit 254, no error msg */
10490         hush_exit(xatoi(argv[0]) & 0xff);
10491 }
10492
10493 #if ENABLE_HUSH_TYPE
10494 /* http://www.opengroup.org/onlinepubs/9699919799/utilities/type.html */
10495 static int FAST_FUNC builtin_type(char **argv)
10496 {
10497         int ret = EXIT_SUCCESS;
10498
10499         while (*++argv) {
10500                 const char *type;
10501                 char *path = NULL;
10502
10503                 if (0) {} /* make conditional compile easier below */
10504                 /*else if (find_alias(*argv))
10505                         type = "an alias";*/
10506 #if ENABLE_HUSH_FUNCTIONS
10507                 else if (find_function(*argv))
10508                         type = "a function";
10509 #endif
10510                 else if (find_builtin(*argv))
10511                         type = "a shell builtin";
10512                 else if ((path = find_in_path(*argv)) != NULL)
10513                         type = path;
10514                 else {
10515                         bb_error_msg("type: %s: not found", *argv);
10516                         ret = EXIT_FAILURE;
10517                         continue;
10518                 }
10519
10520                 printf("%s is %s\n", *argv, type);
10521                 free(path);
10522         }
10523
10524         return ret;
10525 }
10526 #endif
10527
10528 #if ENABLE_HUSH_READ
10529 /* Interruptibility of read builtin in bash
10530  * (tested on bash-4.2.8 by sending signals (not by ^C)):
10531  *
10532  * Empty trap makes read ignore corresponding signal, for any signal.
10533  *
10534  * SIGINT:
10535  * - terminates non-interactive shell;
10536  * - interrupts read in interactive shell;
10537  * if it has non-empty trap:
10538  * - executes trap and returns to command prompt in interactive shell;
10539  * - executes trap and returns to read in non-interactive shell;
10540  * SIGTERM:
10541  * - is ignored (does not interrupt) read in interactive shell;
10542  * - terminates non-interactive shell;
10543  * if it has non-empty trap:
10544  * - executes trap and returns to read;
10545  * SIGHUP:
10546  * - terminates shell (regardless of interactivity);
10547  * if it has non-empty trap:
10548  * - executes trap and returns to read;
10549  * SIGCHLD from children:
10550  * - does not interrupt read regardless of interactivity:
10551  *   try: sleep 1 & read x; echo $x
10552  */
10553 static int FAST_FUNC builtin_read(char **argv)
10554 {
10555         const char *r;
10556         struct builtin_read_params params;
10557
10558         memset(&params, 0, sizeof(params));
10559
10560         /* "!": do not abort on errors.
10561          * Option string must start with "sr" to match BUILTIN_READ_xxx
10562          */
10563         params.read_flags = getopt32(argv,
10564 #if BASH_READ_D
10565                 "!srn:p:t:u:d:", &params.opt_n, &params.opt_p, &params.opt_t, &params.opt_u, &params.opt_d
10566 #else
10567                 "!srn:p:t:u:", &params.opt_n, &params.opt_p, &params.opt_t, &params.opt_u
10568 #endif
10569         );
10570         if ((uint32_t)params.read_flags == (uint32_t)-1)
10571                 return EXIT_FAILURE;
10572         argv += optind;
10573         params.argv = argv;
10574         params.setvar = set_local_var_from_halves;
10575         params.ifs = get_local_var_value("IFS"); /* can be NULL */
10576
10577  again:
10578         r = shell_builtin_read(&params);
10579
10580         if ((uintptr_t)r == 1 && errno == EINTR) {
10581                 unsigned sig = check_and_run_traps();
10582                 if (sig != SIGINT)
10583                         goto again;
10584         }
10585
10586         if ((uintptr_t)r > 1) {
10587                 bb_error_msg("%s", r);
10588                 r = (char*)(uintptr_t)1;
10589         }
10590
10591         return (uintptr_t)r;
10592 }
10593 #endif
10594
10595 #if ENABLE_HUSH_UMASK
10596 static int FAST_FUNC builtin_umask(char **argv)
10597 {
10598         int rc;
10599         mode_t mask;
10600
10601         rc = 1;
10602         mask = umask(0);
10603         argv = skip_dash_dash(argv);
10604         if (argv[0]) {
10605                 mode_t old_mask = mask;
10606
10607                 /* numeric umasks are taken as-is */
10608                 /* symbolic umasks are inverted: "umask a=rx" calls umask(222) */
10609                 if (!isdigit(argv[0][0]))
10610                         mask ^= 0777;
10611                 mask = bb_parse_mode(argv[0], mask);
10612                 if (!isdigit(argv[0][0]))
10613                         mask ^= 0777;
10614                 if ((unsigned)mask > 0777) {
10615                         mask = old_mask;
10616                         /* bash messages:
10617                          * bash: umask: 'q': invalid symbolic mode operator
10618                          * bash: umask: 999: octal number out of range
10619                          */
10620                         bb_error_msg("%s: invalid mode '%s'", "umask", argv[0]);
10621                         rc = 0;
10622                 }
10623         } else {
10624                 /* Mimic bash */
10625                 printf("%04o\n", (unsigned) mask);
10626                 /* fall through and restore mask which we set to 0 */
10627         }
10628         umask(mask);
10629
10630         return !rc; /* rc != 0 - success */
10631 }
10632 #endif
10633
10634 #if ENABLE_HUSH_EXPORT || ENABLE_HUSH_TRAP
10635 static void print_escaped(const char *s)
10636 {
10637         if (*s == '\'')
10638                 goto squote;
10639         do {
10640                 const char *p = strchrnul(s, '\'');
10641                 /* print 'xxxx', possibly just '' */
10642                 printf("'%.*s'", (int)(p - s), s);
10643                 if (*p == '\0')
10644                         break;
10645                 s = p;
10646  squote:
10647                 /* s points to '; print "'''...'''" */
10648                 putchar('"');
10649                 do putchar('\''); while (*++s == '\'');
10650                 putchar('"');
10651         } while (*s);
10652 }
10653 #endif
10654
10655 #if ENABLE_HUSH_EXPORT || ENABLE_HUSH_LOCAL || ENABLE_HUSH_READONLY
10656 static int helper_export_local(char **argv, unsigned flags)
10657 {
10658         do {
10659                 char *name = *argv;
10660                 const char *name_end = endofname(name);
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                         if (*name_end != '=') {
10719                                 bb_error_msg("'%s': bad variable name", name);
10720                                 /* do not parse following argv[]s: */
10721                                 return 1;
10722                         }
10723                         /* (Un)exporting/making local NAME=VALUE */
10724                         name = xstrdup(name);
10725                         /* Testcase: export PS1='\w \$ ' */
10726                         unbackslash(name);
10727                 }
10728                 debug_printf_env("%s: set_local_var('%s')\n", __func__, name);
10729                 if (set_local_var(name, flags))
10730                         return EXIT_FAILURE;
10731         } while (*++argv);
10732         return EXIT_SUCCESS;
10733 }
10734 #endif
10735
10736 #if ENABLE_HUSH_EXPORT
10737 static int FAST_FUNC builtin_export(char **argv)
10738 {
10739         unsigned opt_unexport;
10740
10741 #if ENABLE_HUSH_EXPORT_N
10742         /* "!": do not abort on errors */
10743         opt_unexport = getopt32(argv, "!n");
10744         if (opt_unexport == (uint32_t)-1)
10745                 return EXIT_FAILURE;
10746         argv += optind;
10747 #else
10748         opt_unexport = 0;
10749         argv++;
10750 #endif
10751
10752         if (argv[0] == NULL) {
10753                 char **e = environ;
10754                 if (e) {
10755                         while (*e) {
10756 #if 0
10757                                 puts(*e++);
10758 #else
10759                                 /* ash emits: export VAR='VAL'
10760                                  * bash: declare -x VAR="VAL"
10761                                  * we follow ash example */
10762                                 const char *s = *e++;
10763                                 const char *p = strchr(s, '=');
10764
10765                                 if (!p) /* wtf? take next variable */
10766                                         continue;
10767                                 /* export var= */
10768                                 printf("export %.*s", (int)(p - s) + 1, s);
10769                                 print_escaped(p + 1);
10770                                 putchar('\n');
10771 #endif
10772                         }
10773                         /*fflush_all(); - done after each builtin anyway */
10774                 }
10775                 return EXIT_SUCCESS;
10776         }
10777
10778         return helper_export_local(argv, opt_unexport ? SETFLAG_UNEXPORT : SETFLAG_EXPORT);
10779 }
10780 #endif
10781
10782 #if ENABLE_HUSH_LOCAL
10783 static int FAST_FUNC builtin_local(char **argv)
10784 {
10785         if (G.func_nest_level == 0) {
10786                 bb_error_msg("%s: not in a function", argv[0]);
10787                 return EXIT_FAILURE; /* bash compat */
10788         }
10789         argv++;
10790         /* Since all builtins run in a nested variable level,
10791          * need to use level - 1 here. Or else the variable will be removed at once
10792          * after builtin returns.
10793          */
10794         return helper_export_local(argv, (G.var_nest_level - 1) << SETFLAG_VARLVL_SHIFT);
10795 }
10796 #endif
10797
10798 #if ENABLE_HUSH_READONLY
10799 static int FAST_FUNC builtin_readonly(char **argv)
10800 {
10801         argv++;
10802         if (*argv == NULL) {
10803                 /* bash: readonly [-p]: list all readonly VARs
10804                  * (-p has no effect in bash)
10805                  */
10806                 struct variable *e;
10807                 for (e = G.top_var; e; e = e->next) {
10808                         if (e->flg_read_only) {
10809 //TODO: quote value: readonly VAR='VAL'
10810                                 printf("readonly %s\n", e->varstr);
10811                         }
10812                 }
10813                 return EXIT_SUCCESS;
10814         }
10815         return helper_export_local(argv, SETFLAG_MAKE_RO);
10816 }
10817 #endif
10818
10819 #if ENABLE_HUSH_UNSET
10820 /* http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#unset */
10821 static int FAST_FUNC builtin_unset(char **argv)
10822 {
10823         int ret;
10824         unsigned opts;
10825
10826         /* "!": do not abort on errors */
10827         /* "+": stop at 1st non-option */
10828         opts = getopt32(argv, "!+vf");
10829         if (opts == (unsigned)-1)
10830                 return EXIT_FAILURE;
10831         if (opts == 3) {
10832                 bb_error_msg("unset: -v and -f are exclusive");
10833                 return EXIT_FAILURE;
10834         }
10835         argv += optind;
10836
10837         ret = EXIT_SUCCESS;
10838         while (*argv) {
10839                 if (!(opts & 2)) { /* not -f */
10840                         if (unset_local_var(*argv)) {
10841                                 /* unset <nonexistent_var> doesn't fail.
10842                                  * Error is when one tries to unset RO var.
10843                                  * Message was printed by unset_local_var. */
10844                                 ret = EXIT_FAILURE;
10845                         }
10846                 }
10847 # if ENABLE_HUSH_FUNCTIONS
10848                 else {
10849                         unset_func(*argv);
10850                 }
10851 # endif
10852                 argv++;
10853         }
10854         return ret;
10855 }
10856 #endif
10857
10858 #if ENABLE_HUSH_SET
10859 /* http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#set
10860  * built-in 'set' handler
10861  * SUSv3 says:
10862  * set [-abCefhmnuvx] [-o option] [argument...]
10863  * set [+abCefhmnuvx] [+o option] [argument...]
10864  * set -- [argument...]
10865  * set -o
10866  * set +o
10867  * Implementations shall support the options in both their hyphen and
10868  * plus-sign forms. These options can also be specified as options to sh.
10869  * Examples:
10870  * Write out all variables and their values: set
10871  * Set $1, $2, and $3 and set "$#" to 3: set c a b
10872  * Turn on the -x and -v options: set -xv
10873  * Unset all positional parameters: set --
10874  * Set $1 to the value of x, even if it begins with '-' or '+': set -- "$x"
10875  * Set the positional parameters to the expansion of x, even if x expands
10876  * with a leading '-' or '+': set -- $x
10877  *
10878  * So far, we only support "set -- [argument...]" and some of the short names.
10879  */
10880 static int FAST_FUNC builtin_set(char **argv)
10881 {
10882         int n;
10883         char **pp, **g_argv;
10884         char *arg = *++argv;
10885
10886         if (arg == NULL) {
10887                 struct variable *e;
10888                 for (e = G.top_var; e; e = e->next)
10889                         puts(e->varstr);
10890                 return EXIT_SUCCESS;
10891         }
10892
10893         do {
10894                 if (strcmp(arg, "--") == 0) {
10895                         ++argv;
10896                         goto set_argv;
10897                 }
10898                 if (arg[0] != '+' && arg[0] != '-')
10899                         break;
10900                 for (n = 1; arg[n]; ++n) {
10901                         if (set_mode((arg[0] == '-'), arg[n], argv[1]))
10902                                 goto error;
10903                         if (arg[n] == 'o' && argv[1])
10904                                 argv++;
10905                 }
10906         } while ((arg = *++argv) != NULL);
10907         /* Now argv[0] is 1st argument */
10908
10909         if (arg == NULL)
10910                 return EXIT_SUCCESS;
10911  set_argv:
10912
10913         /* NB: G.global_argv[0] ($0) is never freed/changed */
10914         g_argv = G.global_argv;
10915         if (G.global_args_malloced) {
10916                 pp = g_argv;
10917                 while (*++pp)
10918                         free(*pp);
10919                 g_argv[1] = NULL;
10920         } else {
10921                 G.global_args_malloced = 1;
10922                 pp = xzalloc(sizeof(pp[0]) * 2);
10923                 pp[0] = g_argv[0]; /* retain $0 */
10924                 g_argv = pp;
10925         }
10926         /* This realloc's G.global_argv */
10927         G.global_argv = pp = add_strings_to_strings(g_argv, argv, /*dup:*/ 1);
10928
10929         G.global_argc = 1 + string_array_len(pp + 1);
10930
10931         return EXIT_SUCCESS;
10932
10933         /* Nothing known, so abort */
10934  error:
10935         bb_error_msg("%s: %s: invalid option", "set", arg);
10936         return EXIT_FAILURE;
10937 }
10938 #endif
10939
10940 static int FAST_FUNC builtin_shift(char **argv)
10941 {
10942         int n = 1;
10943         argv = skip_dash_dash(argv);
10944         if (argv[0]) {
10945                 n = bb_strtou(argv[0], NULL, 10);
10946                 if (errno || n < 0) {
10947                         /* shared string with ash.c */
10948                         bb_error_msg("Illegal number: %s", argv[0]);
10949                         /*
10950                          * ash aborts in this case.
10951                          * bash prints error message and set $? to 1.
10952                          * Interestingly, for "shift 99999" bash does not
10953                          * print error message, but does set $? to 1
10954                          * (and does no shifting at all).
10955                          */
10956                 }
10957         }
10958         if (n >= 0 && n < G.global_argc) {
10959                 if (G_global_args_malloced) {
10960                         int m = 1;
10961                         while (m <= n)
10962                                 free(G.global_argv[m++]);
10963                 }
10964                 G.global_argc -= n;
10965                 memmove(&G.global_argv[1], &G.global_argv[n+1],
10966                                 G.global_argc * sizeof(G.global_argv[0]));
10967                 return EXIT_SUCCESS;
10968         }
10969         return EXIT_FAILURE;
10970 }
10971
10972 #if ENABLE_HUSH_GETOPTS
10973 static int FAST_FUNC builtin_getopts(char **argv)
10974 {
10975 /* http://pubs.opengroup.org/onlinepubs/9699919799/utilities/getopts.html
10976
10977 TODO:
10978 If a required argument is not found, and getopts is not silent,
10979 a question mark (?) is placed in VAR, OPTARG is unset, and a
10980 diagnostic message is printed.  If getopts is silent, then a
10981 colon (:) is placed in VAR and OPTARG is set to the option
10982 character found.
10983
10984 Test that VAR is a valid variable name?
10985
10986 "Whenever the shell is invoked, OPTIND shall be initialized to 1"
10987 */
10988         char cbuf[2];
10989         const char *cp, *optstring, *var;
10990         int c, n, exitcode, my_opterr;
10991         unsigned count;
10992
10993         optstring = *++argv;
10994         if (!optstring || !(var = *++argv)) {
10995                 bb_error_msg("usage: getopts OPTSTRING VAR [ARGS]");
10996                 return EXIT_FAILURE;
10997         }
10998
10999         if (argv[1])
11000                 argv[0] = G.global_argv[0]; /* for error messages in getopt() */
11001         else
11002                 argv = G.global_argv;
11003         cbuf[1] = '\0';
11004
11005         my_opterr = 0;
11006         if (optstring[0] != ':') {
11007                 cp = get_local_var_value("OPTERR");
11008                 /* 0 if "OPTERR=0", 1 otherwise */
11009                 my_opterr = (!cp || NOT_LONE_CHAR(cp, '0'));
11010         }
11011
11012         /* getopts stops on first non-option. Add "+" to force that */
11013         /*if (optstring[0] != '+')*/ {
11014                 char *s = alloca(strlen(optstring) + 2);
11015                 sprintf(s, "+%s", optstring);
11016                 optstring = s;
11017         }
11018
11019         /* Naively, now we should just
11020          *      cp = get_local_var_value("OPTIND");
11021          *      optind = cp ? atoi(cp) : 0;
11022          *      optarg = NULL;
11023          *      opterr = my_opterr;
11024          *      c = getopt(string_array_len(argv), argv, optstring);
11025          * and be done? Not so fast...
11026          * Unlike normal getopt() usage in C programs, here
11027          * each successive call will (usually) have the same argv[] CONTENTS,
11028          * but not the ADDRESSES. Worse yet, it's possible that between
11029          * invocations of "getopts", there will be calls to shell builtins
11030          * which use getopt() internally. Example:
11031          *      while getopts "abc" RES -a -bc -abc de; do
11032          *              unset -ff func
11033          *      done
11034          * This would not work correctly: getopt() call inside "unset"
11035          * modifies internal libc state which is tracking position in
11036          * multi-option strings ("-abc"). At best, it can skip options
11037          * or return the same option infinitely. With glibc implementation
11038          * of getopt(), it would use outright invalid pointers and return
11039          * garbage even _without_ "unset" mangling internal state.
11040          *
11041          * We resort to resetting getopt() state and calling it N times,
11042          * until we get Nth result (or failure).
11043          * (N == G.getopt_count is reset to 0 whenever OPTIND is [un]set).
11044          */
11045         GETOPT_RESET();
11046         count = 0;
11047         n = string_array_len(argv);
11048         do {
11049                 optarg = NULL;
11050                 opterr = (count < G.getopt_count) ? 0 : my_opterr;
11051                 c = getopt(n, argv, optstring);
11052                 if (c < 0)
11053                         break;
11054                 count++;
11055         } while (count <= G.getopt_count);
11056
11057         /* Set OPTIND. Prevent resetting of the magic counter! */
11058         set_local_var_from_halves("OPTIND", utoa(optind));
11059         G.getopt_count = count; /* "next time, give me N+1'th result" */
11060         GETOPT_RESET(); /* just in case */
11061
11062         /* Set OPTARG */
11063         /* Always set or unset, never left as-is, even on exit/error:
11064          * "If no option was found, or if the option that was found
11065          * does not have an option-argument, OPTARG shall be unset."
11066          */
11067         cp = optarg;
11068         if (c == '?') {
11069                 /* If ":optstring" and unknown option is seen,
11070                  * it is stored to OPTARG.
11071                  */
11072                 if (optstring[1] == ':') {
11073                         cbuf[0] = optopt;
11074                         cp = cbuf;
11075                 }
11076         }
11077         if (cp)
11078                 set_local_var_from_halves("OPTARG", cp);
11079         else
11080                 unset_local_var("OPTARG");
11081
11082         /* Convert -1 to "?" */
11083         exitcode = EXIT_SUCCESS;
11084         if (c < 0) { /* -1: end of options */
11085                 exitcode = EXIT_FAILURE;
11086                 c = '?';
11087         }
11088
11089         /* Set VAR */
11090         cbuf[0] = c;
11091         set_local_var_from_halves(var, cbuf);
11092
11093         return exitcode;
11094 }
11095 #endif
11096
11097 static int FAST_FUNC builtin_source(char **argv)
11098 {
11099         char *arg_path, *filename;
11100         HFILE *input;
11101         save_arg_t sv;
11102         char *args_need_save;
11103 #if ENABLE_HUSH_FUNCTIONS
11104         smallint sv_flg;
11105 #endif
11106
11107         argv = skip_dash_dash(argv);
11108         filename = argv[0];
11109         if (!filename) {
11110                 /* bash says: "bash: .: filename argument required" */
11111                 return 2; /* bash compat */
11112         }
11113         arg_path = NULL;
11114         if (!strchr(filename, '/')) {
11115                 arg_path = find_in_path(filename);
11116                 if (arg_path)
11117                         filename = arg_path;
11118                 else if (!ENABLE_HUSH_BASH_SOURCE_CURDIR) {
11119                         errno = ENOENT;
11120                         bb_simple_perror_msg(filename);
11121                         return EXIT_FAILURE;
11122                 }
11123         }
11124         input = hfopen(filename);
11125         free(arg_path);
11126         if (!input) {
11127                 bb_perror_msg("%s", filename);
11128                 /* POSIX: non-interactive shell should abort here,
11129                  * not merely fail. So far no one complained :)
11130                  */
11131                 return EXIT_FAILURE;
11132         }
11133
11134 #if ENABLE_HUSH_FUNCTIONS
11135         sv_flg = G_flag_return_in_progress;
11136         /* "we are inside sourced file, ok to use return" */
11137         G_flag_return_in_progress = -1;
11138 #endif
11139         args_need_save = argv[1]; /* used as a boolean variable */
11140         if (args_need_save)
11141                 save_and_replace_G_args(&sv, argv);
11142
11143         /* "false; . ./empty_line; echo Zero:$?" should print 0 */
11144         G.last_exitcode = 0;
11145         parse_and_run_file(input);
11146         hfclose(input);
11147
11148         if (args_need_save) /* can't use argv[1] instead: "shift" can mangle it */
11149                 restore_G_args(&sv, argv);
11150 #if ENABLE_HUSH_FUNCTIONS
11151         G_flag_return_in_progress = sv_flg;
11152 #endif
11153
11154         return G.last_exitcode;
11155 }
11156
11157 #if ENABLE_HUSH_TRAP
11158 static int FAST_FUNC builtin_trap(char **argv)
11159 {
11160         int sig;
11161         char *new_cmd;
11162
11163         if (!G_traps)
11164                 G_traps = xzalloc(sizeof(G_traps[0]) * NSIG);
11165
11166         argv++;
11167         if (!*argv) {
11168                 int i;
11169                 /* No args: print all trapped */
11170                 for (i = 0; i < NSIG; ++i) {
11171                         if (G_traps[i]) {
11172                                 printf("trap -- ");
11173                                 print_escaped(G_traps[i]);
11174                                 /* note: bash adds "SIG", but only if invoked
11175                                  * as "bash". If called as "sh", or if set -o posix,
11176                                  * then it prints short signal names.
11177                                  * We are printing short names: */
11178                                 printf(" %s\n", get_signame(i));
11179                         }
11180                 }
11181                 /*fflush_all(); - done after each builtin anyway */
11182                 return EXIT_SUCCESS;
11183         }
11184
11185         new_cmd = NULL;
11186         /* If first arg is a number: reset all specified signals */
11187         sig = bb_strtou(*argv, NULL, 10);
11188         if (errno == 0) {
11189                 int ret;
11190  process_sig_list:
11191                 ret = EXIT_SUCCESS;
11192                 while (*argv) {
11193                         sighandler_t handler;
11194
11195                         sig = get_signum(*argv++);
11196                         if (sig < 0) {
11197                                 ret = EXIT_FAILURE;
11198                                 /* Mimic bash message exactly */
11199                                 bb_error_msg("trap: %s: invalid signal specification", argv[-1]);
11200                                 continue;
11201                         }
11202
11203                         free(G_traps[sig]);
11204                         G_traps[sig] = xstrdup(new_cmd);
11205
11206                         debug_printf("trap: setting SIG%s (%i) to '%s'\n",
11207                                 get_signame(sig), sig, G_traps[sig]);
11208
11209                         /* There is no signal for 0 (EXIT) */
11210                         if (sig == 0)
11211                                 continue;
11212
11213                         if (new_cmd)
11214                                 handler = (new_cmd[0] ? record_pending_signo : SIG_IGN);
11215                         else
11216                                 /* We are removing trap handler */
11217                                 handler = pick_sighandler(sig);
11218                         install_sighandler(sig, handler);
11219                 }
11220                 return ret;
11221         }
11222
11223         if (!argv[1]) { /* no second arg */
11224                 bb_error_msg("trap: invalid arguments");
11225                 return EXIT_FAILURE;
11226         }
11227
11228         /* First arg is "-": reset all specified to default */
11229         /* First arg is "--": skip it, the rest is "handler SIGs..." */
11230         /* Everything else: set arg as signal handler
11231          * (includes "" case, which ignores signal) */
11232         if (argv[0][0] == '-') {
11233                 if (argv[0][1] == '\0') { /* "-" */
11234                         /* new_cmd remains NULL: "reset these sigs" */
11235                         goto reset_traps;
11236                 }
11237                 if (argv[0][1] == '-' && argv[0][2] == '\0') { /* "--" */
11238                         argv++;
11239                 }
11240                 /* else: "-something", no special meaning */
11241         }
11242         new_cmd = *argv;
11243  reset_traps:
11244         argv++;
11245         goto process_sig_list;
11246 }
11247 #endif
11248
11249 #if ENABLE_HUSH_JOB
11250 static struct pipe *parse_jobspec(const char *str)
11251 {
11252         struct pipe *pi;
11253         unsigned jobnum;
11254
11255         if (sscanf(str, "%%%u", &jobnum) != 1) {
11256                 if (str[0] != '%'
11257                  || (str[1] != '%' && str[1] != '+' && str[1] != '\0')
11258                 ) {
11259                         bb_error_msg("bad argument '%s'", str);
11260                         return NULL;
11261                 }
11262                 /* It is "%%", "%+" or "%" - current job */
11263                 jobnum = G.last_jobid;
11264                 if (jobnum == 0) {
11265                         bb_error_msg("no current job");
11266                         return NULL;
11267                 }
11268         }
11269         for (pi = G.job_list; pi; pi = pi->next) {
11270                 if (pi->jobid == jobnum) {
11271                         return pi;
11272                 }
11273         }
11274         bb_error_msg("%u: no such job", jobnum);
11275         return NULL;
11276 }
11277
11278 static int FAST_FUNC builtin_jobs(char **argv UNUSED_PARAM)
11279 {
11280         struct pipe *job;
11281         const char *status_string;
11282
11283         checkjobs(NULL, 0 /*(no pid to wait for)*/);
11284         for (job = G.job_list; job; job = job->next) {
11285                 if (job->alive_cmds == job->stopped_cmds)
11286                         status_string = "Stopped";
11287                 else
11288                         status_string = "Running";
11289
11290                 printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->cmdtext);
11291         }
11292
11293         clean_up_last_dead_job();
11294
11295         return EXIT_SUCCESS;
11296 }
11297
11298 /* built-in 'fg' and 'bg' handler */
11299 static int FAST_FUNC builtin_fg_bg(char **argv)
11300 {
11301         int i;
11302         struct pipe *pi;
11303
11304         if (!G_interactive_fd)
11305                 return EXIT_FAILURE;
11306
11307         /* If they gave us no args, assume they want the last backgrounded task */
11308         if (!argv[1]) {
11309                 for (pi = G.job_list; pi; pi = pi->next) {
11310                         if (pi->jobid == G.last_jobid) {
11311                                 goto found;
11312                         }
11313                 }
11314                 bb_error_msg("%s: no current job", argv[0]);
11315                 return EXIT_FAILURE;
11316         }
11317
11318         pi = parse_jobspec(argv[1]);
11319         if (!pi)
11320                 return EXIT_FAILURE;
11321  found:
11322         /* TODO: bash prints a string representation
11323          * of job being foregrounded (like "sleep 1 | cat") */
11324         if (argv[0][0] == 'f' && G_saved_tty_pgrp) {
11325                 /* Put the job into the foreground.  */
11326                 tcsetpgrp(G_interactive_fd, pi->pgrp);
11327         }
11328
11329         /* Restart the processes in the job */
11330         debug_printf_jobs("reviving %d procs, pgrp %d\n", pi->num_cmds, pi->pgrp);
11331         for (i = 0; i < pi->num_cmds; i++) {
11332                 debug_printf_jobs("reviving pid %d\n", pi->cmds[i].pid);
11333         }
11334         pi->stopped_cmds = 0;
11335
11336         i = kill(- pi->pgrp, SIGCONT);
11337         if (i < 0) {
11338                 if (errno == ESRCH) {
11339                         delete_finished_job(pi);
11340                         return EXIT_SUCCESS;
11341                 }
11342                 bb_perror_msg("kill (SIGCONT)");
11343         }
11344
11345         if (argv[0][0] == 'f') {
11346                 remove_job_from_table(pi); /* FG job shouldn't be in job table */
11347                 return checkjobs_and_fg_shell(pi);
11348         }
11349         return EXIT_SUCCESS;
11350 }
11351 #endif
11352
11353 #if ENABLE_HUSH_KILL
11354 static int FAST_FUNC builtin_kill(char **argv)
11355 {
11356         int ret = 0;
11357
11358 # if ENABLE_HUSH_JOB
11359         if (argv[1] && strcmp(argv[1], "-l") != 0) {
11360                 int i = 1;
11361
11362                 do {
11363                         struct pipe *pi;
11364                         char *dst;
11365                         int j, n;
11366
11367                         if (argv[i][0] != '%')
11368                                 continue;
11369                         /*
11370                          * "kill %N" - job kill
11371                          * Converting to pgrp / pid kill
11372                          */
11373                         pi = parse_jobspec(argv[i]);
11374                         if (!pi) {
11375                                 /* Eat bad jobspec */
11376                                 j = i;
11377                                 do {
11378                                         j++;
11379                                         argv[j - 1] = argv[j];
11380                                 } while (argv[j]);
11381                                 ret = 1;
11382                                 i--;
11383                                 continue;
11384                         }
11385                         /*
11386                          * In jobs started under job control, we signal
11387                          * entire process group by kill -PGRP_ID.
11388                          * This happens, f.e., in interactive shell.
11389                          *
11390                          * Otherwise, we signal each child via
11391                          * kill PID1 PID2 PID3.
11392                          * Testcases:
11393                          * sh -c 'sleep 1|sleep 1 & kill %1'
11394                          * sh -c 'true|sleep 2 & sleep 1; kill %1'
11395                          * sh -c 'true|sleep 1 & sleep 2; kill %1'
11396                          */
11397                         n = G_interactive_fd ? 1 : pi->num_cmds;
11398                         dst = alloca(n * sizeof(int)*4);
11399                         argv[i] = dst;
11400                         if (G_interactive_fd)
11401                                 dst += sprintf(dst, " -%u", (int)pi->pgrp);
11402                         else for (j = 0; j < n; j++) {
11403                                 struct command *cmd = &pi->cmds[j];
11404                                 /* Skip exited members of the job */
11405                                 if (cmd->pid == 0)
11406                                         continue;
11407                                 /*
11408                                  * kill_main has matching code to expect
11409                                  * leading space. Needed to not confuse
11410                                  * negative pids with "kill -SIGNAL_NO" syntax
11411                                  */
11412                                 dst += sprintf(dst, " %u", (int)cmd->pid);
11413                         }
11414                         *dst = '\0';
11415                 } while (argv[++i]);
11416         }
11417 # endif
11418
11419         if (argv[1] || ret == 0) {
11420                 ret = run_applet_main(argv, kill_main);
11421         }
11422         /* else: ret = 1, "kill %bad_jobspec" case */
11423         return ret;
11424 }
11425 #endif
11426
11427 #if ENABLE_HUSH_WAIT
11428 /* http://www.opengroup.org/onlinepubs/9699919799/utilities/wait.html */
11429 #if !ENABLE_HUSH_JOB
11430 # define wait_for_child_or_signal(pipe,pid) wait_for_child_or_signal(pid)
11431 #endif
11432 static int wait_for_child_or_signal(struct pipe *waitfor_pipe, pid_t waitfor_pid)
11433 {
11434         int ret = 0;
11435         for (;;) {
11436                 int sig;
11437                 sigset_t oldset;
11438
11439                 if (!sigisemptyset(&G.pending_set))
11440                         goto check_sig;
11441
11442                 /* waitpid is not interruptible by SA_RESTARTed
11443                  * signals which we use. Thus, this ugly dance:
11444                  */
11445
11446                 /* Make sure possible SIGCHLD is stored in kernel's
11447                  * pending signal mask before we call waitpid.
11448                  * Or else we may race with SIGCHLD, lose it,
11449                  * and get stuck in sigsuspend...
11450                  */
11451                 sigfillset(&oldset); /* block all signals, remember old set */
11452                 sigprocmask2(SIG_SETMASK, &oldset);
11453
11454                 if (!sigisemptyset(&G.pending_set)) {
11455                         /* Crap! we raced with some signal! */
11456                         goto restore;
11457                 }
11458
11459                 /*errno = 0; - checkjobs does this */
11460 /* Can't pass waitfor_pipe into checkjobs(): it won't be interruptible */
11461                 ret = checkjobs(NULL, waitfor_pid); /* waitpid(WNOHANG) inside */
11462                 debug_printf_exec("checkjobs:%d\n", ret);
11463 #if ENABLE_HUSH_JOB
11464                 if (waitfor_pipe) {
11465                         int rcode = job_exited_or_stopped(waitfor_pipe);
11466                         debug_printf_exec("job_exited_or_stopped:%d\n", rcode);
11467                         if (rcode >= 0) {
11468                                 ret = rcode;
11469                                 sigprocmask(SIG_SETMASK, &oldset, NULL);
11470                                 break;
11471                         }
11472                 }
11473 #endif
11474                 /* if ECHILD, there are no children (ret is -1 or 0) */
11475                 /* if ret == 0, no children changed state */
11476                 /* if ret != 0, it's exitcode+1 of exited waitfor_pid child */
11477                 if (errno == ECHILD || ret) {
11478                         ret--;
11479                         if (ret < 0) /* if ECHILD, may need to fix "ret" */
11480                                 ret = 0;
11481 #if ENABLE_HUSH_BASH_COMPAT
11482                         if (waitfor_pid == -1 && errno == ECHILD) {
11483                                 /* exitcode of "wait -n" with no children is 127, not 0 */
11484                                 ret = 127;
11485                         }
11486 #endif
11487                         sigprocmask(SIG_SETMASK, &oldset, NULL);
11488                         break;
11489                 }
11490                 /* Wait for SIGCHLD or any other signal */
11491                 /* It is vitally important for sigsuspend that SIGCHLD has non-DFL handler! */
11492                 /* Note: sigsuspend invokes signal handler */
11493                 sigsuspend(&oldset);
11494  restore:
11495                 sigprocmask(SIG_SETMASK, &oldset, NULL);
11496  check_sig:
11497                 /* So, did we get a signal? */
11498                 sig = check_and_run_traps();
11499                 if (sig /*&& sig != SIGCHLD - always true */) {
11500                         /* Do this for any (non-ignored) signal, not only for ^C */
11501                         ret = 128 + sig;
11502                         break;
11503                 }
11504                 /* SIGCHLD, or no signal, or ignored one, such as SIGQUIT. Repeat */
11505         }
11506         return ret;
11507 }
11508
11509 static int FAST_FUNC builtin_wait(char **argv)
11510 {
11511         int ret;
11512         int status;
11513
11514         argv = skip_dash_dash(argv);
11515 #if ENABLE_HUSH_BASH_COMPAT
11516         if (argv[0] && strcmp(argv[0], "-n") == 0) {
11517                 /* wait -n */
11518                 /* (bash accepts "wait -n PID" too and ignores PID) */
11519                 G.dead_job_exitcode = -1;
11520                 return wait_for_child_or_signal(NULL, -1 /*no job, wait for one job*/);
11521         }
11522 #endif
11523         if (argv[0] == NULL) {
11524                 /* Don't care about wait results */
11525                 /* Note 1: must wait until there are no more children */
11526                 /* Note 2: must be interruptible */
11527                 /* Examples:
11528                  * $ sleep 3 & sleep 6 & wait
11529                  * [1] 30934 sleep 3
11530                  * [2] 30935 sleep 6
11531                  * [1] Done                   sleep 3
11532                  * [2] Done                   sleep 6
11533                  * $ sleep 3 & sleep 6 & wait
11534                  * [1] 30936 sleep 3
11535                  * [2] 30937 sleep 6
11536                  * [1] Done                   sleep 3
11537                  * ^C <-- after ~4 sec from keyboard
11538                  * $
11539                  */
11540                 return wait_for_child_or_signal(NULL, 0 /*no job and no pid to wait for*/);
11541         }
11542
11543         do {
11544                 pid_t pid = bb_strtou(*argv, NULL, 10);
11545                 if (errno || pid <= 0) {
11546 #if ENABLE_HUSH_JOB
11547                         if (argv[0][0] == '%') {
11548                                 struct pipe *wait_pipe;
11549                                 ret = 127; /* bash compat for bad jobspecs */
11550                                 wait_pipe = parse_jobspec(*argv);
11551                                 if (wait_pipe) {
11552                                         ret = job_exited_or_stopped(wait_pipe);
11553                                         if (ret < 0) {
11554                                                 ret = wait_for_child_or_signal(wait_pipe, 0);
11555                                         } else {
11556                                                 /* waiting on "last dead job" removes it */
11557                                                 clean_up_last_dead_job();
11558                                         }
11559                                 }
11560                                 /* else: parse_jobspec() already emitted error msg */
11561                                 continue;
11562                         }
11563 #endif
11564                         /* mimic bash message */
11565                         bb_error_msg("wait: '%s': not a pid or valid job spec", *argv);
11566                         ret = EXIT_FAILURE;
11567                         continue; /* bash checks all argv[] */
11568                 }
11569
11570                 /* Do we have such child? */
11571                 ret = waitpid(pid, &status, WNOHANG);
11572                 if (ret < 0) {
11573                         /* No */
11574                         ret = 127;
11575                         if (errno == ECHILD) {
11576                                 if (pid == G.last_bg_pid) {
11577                                         /* "wait $!" but last bg task has already exited. Try:
11578                                          * (sleep 1; exit 3) & sleep 2; echo $?; wait $!; echo $?
11579                                          * In bash it prints exitcode 0, then 3.
11580                                          * In dash, it is 127.
11581                                          */
11582                                         ret = G.last_bg_pid_exitcode;
11583                                 } else {
11584                                         /* Example: "wait 1". mimic bash message */
11585                                         bb_error_msg("wait: pid %d is not a child of this shell", (int)pid);
11586                                 }
11587                         } else {
11588                                 /* ??? */
11589                                 bb_perror_msg("wait %s", *argv);
11590                         }
11591                         continue; /* bash checks all argv[] */
11592                 }
11593                 if (ret == 0) {
11594                         /* Yes, and it still runs */
11595                         ret = wait_for_child_or_signal(NULL, pid);
11596                 } else {
11597                         /* Yes, and it just exited */
11598                         process_wait_result(NULL, pid, status);
11599                         ret = WEXITSTATUS(status);
11600                         if (WIFSIGNALED(status))
11601                                 ret = 128 + WTERMSIG(status);
11602                 }
11603         } while (*++argv);
11604
11605         return ret;
11606 }
11607 #endif
11608
11609 #if ENABLE_HUSH_LOOPS || ENABLE_HUSH_FUNCTIONS
11610 static unsigned parse_numeric_argv1(char **argv, unsigned def, unsigned def_min)
11611 {
11612         if (argv[1]) {
11613                 def = bb_strtou(argv[1], NULL, 10);
11614                 if (errno || def < def_min || argv[2]) {
11615                         bb_error_msg("%s: bad arguments", argv[0]);
11616                         def = UINT_MAX;
11617                 }
11618         }
11619         return def;
11620 }
11621 #endif
11622
11623 #if ENABLE_HUSH_LOOPS
11624 static int FAST_FUNC builtin_break(char **argv)
11625 {
11626         unsigned depth;
11627         if (G.depth_of_loop == 0) {
11628                 bb_error_msg("%s: only meaningful in a loop", argv[0]);
11629                 /* if we came from builtin_continue(), need to undo "= 1" */
11630                 G.flag_break_continue = 0;
11631                 return EXIT_SUCCESS; /* bash compat */
11632         }
11633         G.flag_break_continue++; /* BC_BREAK = 1, or BC_CONTINUE = 2 */
11634
11635         G.depth_break_continue = depth = parse_numeric_argv1(argv, 1, 1);
11636         if (depth == UINT_MAX)
11637                 G.flag_break_continue = BC_BREAK;
11638         if (G.depth_of_loop < depth)
11639                 G.depth_break_continue = G.depth_of_loop;
11640
11641         return EXIT_SUCCESS;
11642 }
11643
11644 static int FAST_FUNC builtin_continue(char **argv)
11645 {
11646         G.flag_break_continue = 1; /* BC_CONTINUE = 2 = 1+1 */
11647         return builtin_break(argv);
11648 }
11649 #endif
11650
11651 #if ENABLE_HUSH_FUNCTIONS
11652 static int FAST_FUNC builtin_return(char **argv)
11653 {
11654         int rc;
11655
11656         if (G_flag_return_in_progress != -1) {
11657                 bb_error_msg("%s: not in a function or sourced script", argv[0]);
11658                 return EXIT_FAILURE; /* bash compat */
11659         }
11660
11661         G_flag_return_in_progress = 1;
11662
11663         /* bash:
11664          * out of range: wraps around at 256, does not error out
11665          * non-numeric param:
11666          * f() { false; return qwe; }; f; echo $?
11667          * bash: return: qwe: numeric argument required  <== we do this
11668          * 255  <== we also do this
11669          */
11670         rc = parse_numeric_argv1(argv, G.last_exitcode, 0);
11671         return rc;
11672 }
11673 #endif
11674
11675 #if ENABLE_HUSH_TIMES
11676 static int FAST_FUNC builtin_times(char **argv UNUSED_PARAM)
11677 {
11678         static const uint8_t times_tbl[] ALIGN1 = {
11679                 ' ',  offsetof(struct tms, tms_utime),
11680                 '\n', offsetof(struct tms, tms_stime),
11681                 ' ',  offsetof(struct tms, tms_cutime),
11682                 '\n', offsetof(struct tms, tms_cstime),
11683                 0
11684         };
11685         const uint8_t *p;
11686         unsigned clk_tck;
11687         struct tms buf;
11688
11689         clk_tck = bb_clk_tck();
11690
11691         times(&buf);
11692         p = times_tbl;
11693         do {
11694                 unsigned sec, frac;
11695                 unsigned long t;
11696                 t = *(clock_t *)(((char *) &buf) + p[1]);
11697                 sec = t / clk_tck;
11698                 frac = t % clk_tck;
11699                 printf("%um%u.%03us%c",
11700                         sec / 60, sec % 60,
11701                         (frac * 1000) / clk_tck,
11702                         p[0]);
11703                 p += 2;
11704         } while (*p);
11705
11706         return EXIT_SUCCESS;
11707 }
11708 #endif
11709
11710 #if ENABLE_HUSH_MEMLEAK
11711 static int FAST_FUNC builtin_memleak(char **argv UNUSED_PARAM)
11712 {
11713         void *p;
11714         unsigned long l;
11715
11716 # ifdef M_TRIM_THRESHOLD
11717         /* Optional. Reduces probability of false positives */
11718         malloc_trim(0);
11719 # endif
11720         /* Crude attempt to find where "free memory" starts,
11721          * sans fragmentation. */
11722         p = malloc(240);
11723         l = (unsigned long)p;
11724         free(p);
11725         p = malloc(3400);
11726         if (l < (unsigned long)p) l = (unsigned long)p;
11727         free(p);
11728
11729
11730 # if 0  /* debug */
11731         {
11732                 struct mallinfo mi = mallinfo();
11733                 printf("top alloc:0x%lx malloced:%d+%d=%d\n", l,
11734                         mi.arena, mi.hblkhd, mi.arena + mi.hblkhd);
11735         }
11736 # endif
11737
11738         if (!G.memleak_value)
11739                 G.memleak_value = l;
11740
11741         l -= G.memleak_value;
11742         if ((long)l < 0)
11743                 l = 0;
11744         l /= 1024;
11745         if (l > 127)
11746                 l = 127;
11747
11748         /* Exitcode is "how many kilobytes we leaked since 1st call" */
11749         return l;
11750 }
11751 #endif