]> Git Repo - J-u-boot.git/blob - common/cli_hush_upstream.c
Merge patch series "examples: fix building on arm64"
[J-u-boot.git] / common / cli_hush_upstream.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 <[email protected]>
9  * Copyright (C) 2008,2009  Denys Vlasenko <[email protected]>
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 <[email protected]>
19  *      written by Erik Andersen <[email protected]>.  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  *      let EXPR [EXPR...]
67  *          Each EXPR is an arithmetic expression (ARITHMETIC EVALUATION)
68  *          If the last arg evaluates to 0, let returns 1; 0 otherwise.
69  *          NB: let `echo 'a=a + 1'` - error (IOW: multi-word expansion is used)
70  *      ((EXPR))
71  *          The EXPR is evaluated according to ARITHMETIC EVALUATION.
72  *          This is exactly equivalent to let "EXPR".
73  *      $[EXPR]: synonym for $((EXPR))
74  *      indirect expansion: ${!VAR}
75  *      substring op on @: ${@:n:m}
76  *
77  * Won't do:
78  *      Some builtins mandated by standards:
79  *          newgrp [GRP]: not a builtin in bash but a suid binary
80  *              which spawns a new shell with new group ID
81  *
82  * Status of [[ support:
83  * [[ args ]] are CMD_SINGLEWORD_NOGLOB:
84  *   v='a b'; [[ $v = 'a b' ]]; echo 0:$?
85  *   [[ /bin/n* ]]; echo 0:$?
86  *   = is glob match operator, not equality operator: STR = GLOB
87  *   == same as =
88  *   =~ is regex match operator: STR =~ REGEX
89  * TODO:
90  * quoting needs to be considered (-f is an operator, "-f" and ""-f are not; etc)
91  * in word = GLOB, quoting should be significant on char-by-char basis: a*cd"*"
92  */
93 //config:config HUSH
94 //config:       bool "hush (70 kb)"
95 //config:       default y
96 //config:       select SHELL_HUSH
97 //config:       help
98 //config:       hush is a small shell. It handles the normal flow control
99 //config:       constructs such as if/then/elif/else/fi, for/in/do/done, while loops,
100 //config:       case/esac. Redirections, here documents, $((arithmetic))
101 //config:       and functions are supported.
102 //config:
103 //config:       It will compile and work on no-mmu systems.
104 //config:
105 //config:       It does not handle select, aliases, tilde expansion,
106 //config:       &>file and >&file redirection of stdout+stderr.
107 //config:
108 // This option is visible (has a description) to make it possible to select
109 // a "scripted" applet (such as NOLOGIN) but avoid selecting any shells:
110 //config:config SHELL_HUSH
111 //config:       bool "Internal shell for embedded script support"
112 //config:       default n
113 //config:
114 //config:# hush options
115 //config:# It's only needed to get "nice" menuconfig indenting.
116 //config:if SHELL_HUSH || HUSH || SH_IS_HUSH || BASH_IS_HUSH
117 //config:
118 //config:config HUSH_BASH_COMPAT
119 //config:       bool "bash-compatible extensions"
120 //config:       default y
121 //config:       depends on SHELL_HUSH
122 //config:
123 //config:config HUSH_BRACE_EXPANSION
124 //config:       bool "Brace expansion"
125 //config:       default y
126 //config:       depends on HUSH_BASH_COMPAT
127 //config:       help
128 //config:       Enable {abc,def} extension.
129 //config:
130 //config:config HUSH_BASH_SOURCE_CURDIR
131 //config:       bool "'source' and '.' builtins search current directory after $PATH"
132 //config:       default n   # do not encourage non-standard behavior
133 //config:       depends on HUSH_BASH_COMPAT
134 //config:       help
135 //config:       This is not compliant with standards. Avoid if possible.
136 //config:
137 //config:config HUSH_LINENO_VAR
138 //config:       bool "$LINENO variable (bashism)"
139 //config:       default y
140 //config:       depends on SHELL_HUSH
141 //config:
142 //config:config HUSH_INTERACTIVE
143 //config:       bool "Interactive mode"
144 //config:       default y
145 //config:       depends on SHELL_HUSH
146 //config:       help
147 //config:       Enable interactive mode (prompt and command editing).
148 //config:       Without this, hush simply reads and executes commands
149 //config:       from stdin just like a shell script from a file.
150 //config:       No prompt, no PS1/PS2 magic shell variables.
151 //config:
152 //config:config HUSH_SAVEHISTORY
153 //config:       bool "Save command history to .hush_history"
154 //config:       default y
155 //config:       depends on HUSH_INTERACTIVE && FEATURE_EDITING_SAVEHISTORY
156 //config:
157 //config:config HUSH_JOB
158 //config:       bool "Job control"
159 //config:       default y
160 //config:       depends on HUSH_INTERACTIVE
161 //config:       help
162 //config:       Enable job control: Ctrl-Z backgrounds, Ctrl-C interrupts current
163 //config:       command (not entire shell), fg/bg builtins work. Without this option,
164 //config:       "cmd &" still works by simply spawning a process and immediately
165 //config:       prompting for next command (or executing next command in a script),
166 //config:       but no separate process group is formed.
167 //config:
168 //config:config HUSH_TICK
169 //config:       bool "Support command substitution"
170 //config:       default y
171 //config:       depends on SHELL_HUSH
172 //config:       help
173 //config:       Enable `command` and $(command).
174 //config:
175 //config:config HUSH_IF
176 //config:       bool "Support if/then/elif/else/fi"
177 //config:       default y
178 //config:       depends on SHELL_HUSH
179 //config:
180 //config:config HUSH_LOOPS
181 //config:       bool "Support for, while and until loops"
182 //config:       default y
183 //config:       depends on SHELL_HUSH
184 //config:
185 //config:config HUSH_CASE
186 //config:       bool "Support case ... esac statement"
187 //config:       default y
188 //config:       depends on SHELL_HUSH
189 //config:       help
190 //config:       Enable case ... esac statement. +400 bytes.
191 //config:
192 //config:config HUSH_FUNCTIONS
193 //config:       bool "Support funcname() { commands; } syntax"
194 //config:       default y
195 //config:       depends on SHELL_HUSH
196 //config:       help
197 //config:       Enable support for shell functions. +800 bytes.
198 //config:
199 //config:config HUSH_LOCAL
200 //config:       bool "local builtin"
201 //config:       default y
202 //config:       depends on HUSH_FUNCTIONS
203 //config:       help
204 //config:       Enable support for local variables in functions.
205 //config:
206 //config:config HUSH_RANDOM_SUPPORT
207 //config:       bool "Pseudorandom generator and $RANDOM variable"
208 //config:       default y
209 //config:       depends on SHELL_HUSH
210 //config:       help
211 //config:       Enable pseudorandom generator and dynamic variable "$RANDOM".
212 //config:       Each read of "$RANDOM" will generate a new pseudorandom value.
213 //config:
214 //config:config HUSH_MODE_X
215 //config:       bool "Support 'hush -x' option and 'set -x' command"
216 //config:       default y
217 //config:       depends on SHELL_HUSH
218 //config:       help
219 //config:       This instructs hush to print commands before execution.
220 //config:       Adds ~300 bytes.
221 //config:
222 //config:config HUSH_ECHO
223 //config:       bool "echo builtin"
224 //config:       default y
225 //config:       depends on SHELL_HUSH
226 //config:
227 //config:config HUSH_PRINTF
228 //config:       bool "printf builtin"
229 //config:       default y
230 //config:       depends on SHELL_HUSH
231 //config:
232 //config:config HUSH_TEST
233 //config:       bool "test builtin"
234 //config:       default y
235 //config:       depends on SHELL_HUSH
236 //config:
237 //config:config HUSH_HELP
238 //config:       bool "help builtin"
239 //config:       default y
240 //config:       depends on SHELL_HUSH
241 //config:
242 //config:config HUSH_EXPORT
243 //config:       bool "export builtin"
244 //config:       default y
245 //config:       depends on SHELL_HUSH
246 //config:
247 //config:config HUSH_EXPORT_N
248 //config:       bool "Support 'export -n' option"
249 //config:       default y
250 //config:       depends on HUSH_EXPORT
251 //config:       help
252 //config:       export -n unexports variables. It is a bash extension.
253 //config:
254 //config:config HUSH_READONLY
255 //config:       bool "readonly builtin"
256 //config:       default y
257 //config:       depends on SHELL_HUSH
258 //config:       help
259 //config:       Enable support for read-only variables.
260 //config:
261 //config:config HUSH_KILL
262 //config:       bool "kill builtin (supports kill %jobspec)"
263 //config:       default y
264 //config:       depends on SHELL_HUSH
265 //config:
266 //config:config HUSH_WAIT
267 //config:       bool "wait builtin"
268 //config:       default y
269 //config:       depends on SHELL_HUSH
270 //config:
271 //config:config HUSH_COMMAND
272 //config:       bool "command builtin"
273 //config:       default y
274 //config:       depends on SHELL_HUSH
275 //config:
276 //config:config HUSH_TRAP
277 //config:       bool "trap builtin"
278 //config:       default y
279 //config:       depends on SHELL_HUSH
280 //config:
281 //config:config HUSH_TYPE
282 //config:       bool "type builtin"
283 //config:       default y
284 //config:       depends on SHELL_HUSH
285 //config:
286 //config:config HUSH_TIMES
287 //config:       bool "times builtin"
288 //config:       default y
289 //config:       depends on SHELL_HUSH
290 //config:
291 //config:config HUSH_READ
292 //config:       bool "read builtin"
293 //config:       default y
294 //config:       depends on SHELL_HUSH
295 //config:
296 //config:config HUSH_SET
297 //config:       bool "set builtin"
298 //config:       default y
299 //config:       depends on SHELL_HUSH
300 //config:
301 //config:config HUSH_UNSET
302 //config:       bool "unset builtin"
303 //config:       default y
304 //config:       depends on SHELL_HUSH
305 //config:
306 //config:config HUSH_ULIMIT
307 //config:       bool "ulimit builtin"
308 //config:       default y
309 //config:       depends on SHELL_HUSH
310 //config:
311 //config:config HUSH_UMASK
312 //config:       bool "umask builtin"
313 //config:       default y
314 //config:       depends on SHELL_HUSH
315 //config:
316 //config:config HUSH_GETOPTS
317 //config:       bool "getopts builtin"
318 //config:       default y
319 //config:       depends on SHELL_HUSH
320 //config:
321 //config:config HUSH_MEMLEAK
322 //config:       bool "memleak builtin (debugging)"
323 //config:       default n
324 //config:       depends on SHELL_HUSH
325 //config:
326 //config:endif # hush options
327
328 //applet:IF_HUSH(APPLET(hush, BB_DIR_BIN, BB_SUID_DROP))
329 //                       APPLET_ODDNAME:name  main  location    suid_type     help
330 //applet:IF_SH_IS_HUSH(  APPLET_ODDNAME(sh,   hush, BB_DIR_BIN, BB_SUID_DROP, hush))
331 //applet:IF_BASH_IS_HUSH(APPLET_ODDNAME(bash, hush, BB_DIR_BIN, BB_SUID_DROP, hush))
332
333 //kbuild:lib-$(CONFIG_SHELL_HUSH) += hush.o match.o shell_common.o
334 //kbuild:lib-$(CONFIG_HUSH_RANDOM_SUPPORT) += random.o
335
336 /* -i (interactive) is also accepted,
337  * but does nothing, therefore not shown in help.
338  * NOMMU-specific options are not meant to be used by users,
339  * therefore we don't show them either.
340  */
341 //usage:#define hush_trivial_usage
342 //usage:        "[-enxl] [-c 'SCRIPT' [ARG0 ARGS] | FILE ARGS | -s ARGS]"
343 //usage:#define hush_full_usage "\n\n"
344 //usage:        "Unix shell interpreter"
345
346 #ifndef __U_BOOT__
347 #if !(defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) \
348         || defined(__APPLE__) \
349     )
350 # include <malloc.h>   /* for malloc_trim */
351 #endif
352 #include <glob.h>
353 /* #include <dmalloc.h> */
354 #if ENABLE_HUSH_CASE
355 # include <fnmatch.h>
356 #endif
357 #include <sys/times.h>
358 #include <sys/utsname.h> /* for setting $HOSTNAME */
359
360 #include "busybox.h"  /* for APPLET_IS_NOFORK/NOEXEC */
361 #include "unicode.h"
362 #include "shell_common.h"
363 #include "math.h"
364 #include "match.h"
365 #if ENABLE_HUSH_RANDOM_SUPPORT
366 # include "random.h"
367 #else
368 # define CLEAR_RANDOM_T(rnd) ((void)0)
369 #endif
370 #ifndef O_CLOEXEC
371 # define O_CLOEXEC 0
372 #endif
373 #ifndef F_DUPFD_CLOEXEC
374 # define F_DUPFD_CLOEXEC F_DUPFD
375 #endif
376
377 #if ENABLE_FEATURE_SH_EMBEDDED_SCRIPTS && !ENABLE_SHELL_ASH
378 # include "embedded_scripts.h"
379 #else
380 # define NUM_SCRIPTS 0
381 #endif
382 #endif /* !__U_BOOT__ */
383
384 /* So far, all bash compat is controlled by one config option */
385 /* Separate defines document which part of code implements what */
386 #define BASH_PATTERN_SUBST ENABLE_HUSH_BASH_COMPAT
387 #define BASH_SUBSTR        ENABLE_HUSH_BASH_COMPAT
388 #define BASH_SOURCE        ENABLE_HUSH_BASH_COMPAT
389 #define BASH_DOLLAR_SQUOTE ENABLE_HUSH_BASH_COMPAT
390 #define BASH_HOSTNAME_VAR  ENABLE_HUSH_BASH_COMPAT
391 #define BASH_EPOCH_VARS    ENABLE_HUSH_BASH_COMPAT
392 #define BASH_TEST2         (ENABLE_HUSH_BASH_COMPAT && ENABLE_HUSH_TEST)
393 #define BASH_READ_D        ENABLE_HUSH_BASH_COMPAT
394
395 /* Build knobs */
396 #define LEAK_HUNTING 0
397 #define BUILD_AS_NOMMU 0
398 /* Enable/disable sanity checks. Ok to enable in production,
399  * only adds a bit of bloat. Set to >1 to get non-production level verbosity.
400  * Keeping 1 for now even in released versions.
401  */
402 #define HUSH_DEBUG 1
403 /* Slightly bigger (+200 bytes), but faster hush.
404  * So far it only enables a trick with counting SIGCHLDs and forks,
405  * which allows us to do fewer waitpid's.
406  * (we can detect a case where neither forks were done nor SIGCHLDs happened
407  * and therefore waitpid will return the same result as last time)
408  */
409 #define ENABLE_HUSH_FAST 0
410 /* TODO: implement simplified code for users which do not need ${var%...} ops
411  * So far ${var%...} ops are always enabled:
412  */
413 #define ENABLE_HUSH_DOLLAR_OPS 1
414
415 #if BUILD_AS_NOMMU
416 # undef BB_MMU
417 # undef USE_FOR_NOMMU
418 # undef USE_FOR_MMU
419 # define BB_MMU 0
420 # define USE_FOR_NOMMU(...) __VA_ARGS__
421 # define USE_FOR_MMU(...)
422 #endif
423
424 #ifndef __U_BOOT__
425 #include "NUM_APPLETS.h"
426 #if NUM_APPLETS == 1
427 /* STANDALONE does not make sense, and won't compile */
428 # undef ENABLE_FEATURE_SH_STANDALONE
429 # undef IF_FEATURE_SH_STANDALONE
430 # undef IF_NOT_FEATURE_SH_STANDALONE
431 # define ENABLE_FEATURE_SH_STANDALONE 0
432 # define IF_FEATURE_SH_STANDALONE(...)
433 # define IF_NOT_FEATURE_SH_STANDALONE(...) __VA_ARGS__
434 #endif
435 #endif /* __U_BOOT__ */
436
437 #if !ENABLE_HUSH_INTERACTIVE
438 # undef ENABLE_FEATURE_EDITING
439 # define ENABLE_FEATURE_EDITING 0
440 # undef ENABLE_FEATURE_EDITING_FANCY_PROMPT
441 # define ENABLE_FEATURE_EDITING_FANCY_PROMPT 0
442 # undef ENABLE_FEATURE_EDITING_SAVE_ON_EXIT
443 # define ENABLE_FEATURE_EDITING_SAVE_ON_EXIT 0
444 #endif
445
446 /* Do we support ANY keywords? */
447 #if ENABLE_HUSH_IF || ENABLE_HUSH_LOOPS || ENABLE_HUSH_CASE
448 # define HAS_KEYWORDS 1
449 # define IF_HAS_KEYWORDS(...) __VA_ARGS__
450 # define IF_HAS_NO_KEYWORDS(...)
451 #else
452 # define HAS_KEYWORDS 0
453 # define IF_HAS_KEYWORDS(...)
454 # define IF_HAS_NO_KEYWORDS(...) __VA_ARGS__
455 #endif
456
457 /* If you comment out one of these below, it will be #defined later
458  * to perform debug printfs to stderr: */
459 #define debug_printf(...)         do {} while (0)
460 /* Finer-grained debug switches */
461 #define debug_printf_parse(...)   do {} while (0)
462 #define debug_printf_heredoc(...) do {} while (0)
463 #define debug_print_tree(a, b)    do {} while (0)
464 #define debug_printf_exec(...)    do {} while (0)
465 #define debug_printf_env(...)     do {} while (0)
466 #define debug_printf_jobs(...)    do {} while (0)
467 #define debug_printf_expand(...)  do {} while (0)
468 #define debug_printf_varexp(...)  do {} while (0)
469 #define debug_printf_glob(...)    do {} while (0)
470 #define debug_printf_redir(...)   do {} while (0)
471 #define debug_printf_list(...)    do {} while (0)
472 #define debug_printf_subst(...)   do {} while (0)
473 #define debug_printf_prompt(...)  do {} while (0)
474 #define debug_printf_clean(...)   do {} while (0)
475
476 #define ERR_PTR ((void*)(long)1)
477
478 #define JOB_STATUS_FORMAT    "[%u] %-22s %.40s\n"
479
480 #define _SPECIAL_VARS_STR     "_*@$!?#-"
481 #ifndef __U_BOOT__
482 #define SPECIAL_VARS_STR     ("_*@$!?#-" + 1)
483 #define NUMERIC_SPECVARS_STR ("_*@$!?#-" + 3)
484 #else /* __U_BOOT__ */
485 #define SPECIAL_VARS_STR     "*@$!?#-"
486 #define NUMERIC_SPECVARS_STR "$!?#-"
487 #endif /* __U_BOOT__ */
488 #if BASH_PATTERN_SUBST
489 /* Support / and // replace ops */
490 /* Note that // is stored as \ in "encoded" string representation */
491 # define VAR_ENCODED_SUBST_OPS      "\\/%#:-=+?"
492 # define VAR_SUBST_OPS             ("\\/%#:-=+?" + 1)
493 # define MINUS_PLUS_EQUAL_QUESTION ("\\/%#:-=+?" + 5)
494 #else
495 # define VAR_ENCODED_SUBST_OPS      "%#:-=+?"
496 # define VAR_SUBST_OPS              "%#:-=+?"
497 # define MINUS_PLUS_EQUAL_QUESTION ("%#:-=+?" + 3)
498 #endif
499
500 #define SPECIAL_VAR_SYMBOL_STR "\3"
501 #define SPECIAL_VAR_SYMBOL       3
502 /* The "variable" with name "\1" emits string "\3". Testcase: "echo ^C" */
503 #define SPECIAL_VAR_QUOTED_SVS   1
504
505 struct variable;
506
507 static const char hush_version_str[] ALIGN1 = "HUSH_VERSION="BB_VER;
508
509 /* This supports saving pointers malloced in vfork child,
510  * to be freed in the parent.
511  */
512 #if !BB_MMU
513 typedef struct nommu_save_t {
514         struct variable *old_vars;
515         char **argv;
516         char **argv_from_re_execing;
517 } nommu_save_t;
518 #endif
519
520 enum {
521         RES_NONE  = 0,
522 #if ENABLE_HUSH_IF
523         RES_IF    ,
524         RES_THEN  ,
525         RES_ELIF  ,
526         RES_ELSE  ,
527         RES_FI    ,
528 #endif
529 #if ENABLE_HUSH_LOOPS
530         RES_FOR   ,
531         RES_WHILE ,
532         RES_UNTIL ,
533         RES_DO    ,
534         RES_DONE  ,
535 #endif
536 #if ENABLE_HUSH_LOOPS || ENABLE_HUSH_CASE
537         RES_IN    ,
538 #endif
539 #if ENABLE_HUSH_CASE
540         RES_CASE  ,
541         /* three pseudo-keywords support contrived "case" syntax: */
542         RES_CASE_IN,   /* "case ... IN", turns into RES_MATCH when IN is observed */
543         RES_MATCH ,    /* "word)" */
544         RES_CASE_BODY, /* "this command is inside CASE" */
545         RES_ESAC  ,
546 #endif
547         RES_XXXX  ,
548         RES_SNTX
549 };
550
551 typedef struct o_string {
552         char *data;
553         int length; /* position where data is appended */
554         int maxlen;
555         int o_expflags;
556         /* At least some part of the string was inside '' or "",
557          * possibly empty one: word"", wo''rd etc. */
558         smallint has_quoted_part;
559         smallint has_empty_slot;
560         smallint ended_in_ifs;
561 } o_string;
562 enum {
563         EXP_FLAG_SINGLEWORD     = 0x80, /* must be 0x80 */
564         EXP_FLAG_GLOB           = 0x2,
565         /* Protect newly added chars against globbing
566          * by prepending \ to *, ?, [, \ */
567         EXP_FLAG_ESC_GLOB_CHARS = 0x1,
568 };
569 /* Used for initialization: o_string foo = NULL_O_STRING; */
570 #define NULL_O_STRING { NULL }
571
572 #ifndef debug_printf_parse
573 static const char *const assignment_flag[] ALIGN_PTR = {
574         "MAYBE_ASSIGNMENT",
575         "DEFINITELY_ASSIGNMENT",
576         "NOT_ASSIGNMENT",
577         "WORD_IS_KEYWORD",
578 };
579 #endif
580
581 /* We almost can use standard FILE api, but we need an ability to move
582  * its fd when redirects coincide with it. No api exists for that
583  * (RFE for it at https://sourceware.org/bugzilla/show_bug.cgi?id=21902).
584  * HFILE is our internal alternative. Only supports reading.
585  * Since we now can, we incorporate linked list of all opened HFILEs
586  * into the struct (used to be a separate mini-list).
587  */
588 typedef struct HFILE {
589         char *cur;
590         char *end;
591         struct HFILE *next_hfile;
592         int fd;
593         char buf[1024];
594 } HFILE;
595
596 typedef struct in_str {
597         const char *p;
598         int peek_buf[2];
599         int last_char;
600         HFILE *file;
601 } in_str;
602
603 #ifndef __U_BOOT__
604 /* The descrip member of this structure is only used to make
605  * debugging output pretty */
606 static const struct {
607         int32_t mode;
608         signed char default_fd;
609         char descrip[3];
610 } redir_table[] ALIGN4 = {
611         { O_RDONLY,                  0, "<"  },
612         { O_CREAT|O_TRUNC|O_WRONLY,  1, ">"  },
613         { O_CREAT|O_APPEND|O_WRONLY, 1, ">>" },
614         { O_CREAT|O_RDWR,            1, "<>" },
615         { O_RDONLY,                  0, "<<" },
616 /* Should not be needed. Bogus default_fd helps in debugging */
617 /*      { O_RDONLY,                 77, "<<" }, */
618 };
619
620 struct redir_struct {
621         struct redir_struct *next;
622         char *rd_filename;          /* filename */
623         int rd_fd;                  /* fd to redirect */
624         /* fd to redirect to, or -3 if rd_fd is to be closed (n>&-) */
625         int rd_dup;
626         smallint rd_type;           /* (enum redir_type) */
627         /* note: for heredocs, rd_filename contains heredoc delimiter,
628          * and subsequently heredoc itself; and rd_dup is a bitmask:
629          * bit 0: do we need to trim leading tabs?
630          * bit 1: is heredoc quoted (<<'delim' syntax) ?
631          */
632 };
633 typedef enum redir_type {
634         REDIRECT_INPUT     = 0,
635         REDIRECT_OVERWRITE = 1,
636         REDIRECT_APPEND    = 2,
637         REDIRECT_IO        = 3,
638         REDIRECT_HEREDOC   = 4,
639         REDIRECT_HEREDOC2  = 5, /* REDIRECT_HEREDOC after heredoc is loaded */
640
641         REDIRFD_CLOSE      = -3,
642         REDIRFD_SYNTAX_ERR = -2,
643         REDIRFD_TO_FILE    = -1,
644         /* otherwise, rd_fd is redirected to rd_dup */
645
646         HEREDOC_SKIPTABS = 1,
647         HEREDOC_QUOTED   = 2,
648 } redir_type;
649
650 #endif /* !__U_BOOT__ */
651
652 struct command {
653 #ifndef __U_BOOT__
654         pid_t pid;                  /* 0 if exited */
655 #endif /* !__U_BOOT__ */
656         unsigned assignment_cnt;    /* how many argv[i] are assignments? */
657 #if ENABLE_HUSH_LINENO_VAR
658         unsigned lineno;
659 #endif
660         smallint cmd_type;          /* CMD_xxx */
661 #define CMD_NORMAL   0
662 #define CMD_SUBSHELL 1
663 #if BASH_TEST2
664 /* used for "[[ EXPR ]]" */
665 # define CMD_TEST2_SINGLEWORD_NOGLOB 2
666 #endif
667 #if BASH_TEST2 || ENABLE_HUSH_LOCAL || ENABLE_HUSH_EXPORT || ENABLE_HUSH_READONLY
668 /* used to prevent word splitting and globbing in "export v=t*" */
669 # define CMD_SINGLEWORD_NOGLOB 3
670 #endif
671 #if ENABLE_HUSH_FUNCTIONS
672 # define CMD_FUNCDEF 4
673 #endif
674
675         smalluint cmd_exitcode;
676         /* if non-NULL, this "command" is { list }, ( list ), or a compound statement */
677         struct pipe *group;
678 #if !BB_MMU
679         char *group_as_string;
680 #endif
681 #if ENABLE_HUSH_FUNCTIONS
682         struct function *child_func;
683 /* This field is used to prevent a bug here:
684  * while...do f1() {a;}; f1; f1() {b;}; f1; done
685  * When we execute "f1() {a;}" cmd, we create new function and clear
686  * cmd->group, cmd->group_as_string, cmd->argv[0].
687  * When we execute "f1() {b;}", we notice that f1 exists,
688  * and that its "parent cmd" struct is still "alive",
689  * we put those fields back into cmd->xxx
690  * (struct function has ->parent_cmd ptr to facilitate that).
691  * When we loop back, we can execute "f1() {a;}" again and set f1 correctly.
692  * Without this trick, loop would execute a;b;b;b;...
693  * instead of correct sequence a;b;a;b;...
694  * When command is freed, it severs the link
695  * (sets ->child_func->parent_cmd to NULL).
696  */
697 #endif
698 #ifdef __U_BOOT__
699         int argc; /* number of program arguments */
700 #endif
701         char **argv;                /* command name and arguments */
702 /* argv vector may contain variable references (^Cvar^C, ^C0^C etc)
703  * and on execution these are substituted with their values.
704  * Substitution can make _several_ words out of one argv[n]!
705  * Example: argv[0]=='.^C*^C.' here: echo .$*.
706  * References of the form ^C`cmd arg^C are `cmd arg` substitutions.
707  */
708 #ifndef __U_BOOT__
709         struct redir_struct *redirects; /* I/O redirections */
710 #endif /* !__U_BOOT__ */
711 };
712 /* Is there anything in this command at all? */
713 #ifndef __U_BOOT__
714 #define IS_NULL_CMD(cmd) \
715         (!(cmd)->group && !(cmd)->argv && !(cmd)->redirects)
716
717 #else /* __U_BOOT__ */
718 #define IS_NULL_CMD(cmd) \
719         (!(cmd)->group && !(cmd)->argv)
720 #endif /* __U_BOOT__ */
721 struct pipe {
722         struct pipe *next;
723         int num_cmds;               /* total number of commands in pipe */
724 #ifndef __U_BOOT__
725         int alive_cmds;             /* number of commands running (not exited) */
726         int stopped_cmds;           /* number of commands alive, but stopped */
727 #if ENABLE_HUSH_JOB
728         unsigned jobid;             /* job number */
729         pid_t pgrp;                 /* process group ID for the job */
730         char *cmdtext;              /* name of job */
731 #endif
732 #endif /* !__U_BOOT__ */
733         struct command *cmds;       /* array of commands in pipe */
734         smallint followup;          /* PIPE_BG, PIPE_SEQ, PIPE_OR, PIPE_AND */
735         IF_HAS_KEYWORDS(smallint pi_inverted;) /* "! cmd | cmd" */
736         IF_HAS_KEYWORDS(smallint res_word;) /* needed for if, for, while, until... */
737 };
738 typedef enum pipe_style {
739         PIPE_SEQ = 0,
740         PIPE_AND = 1,
741         PIPE_OR  = 2,
742         PIPE_BG  = 3,
743 } pipe_style;
744 /* Is there anything in this pipe at all? */
745 #define IS_NULL_PIPE(pi) \
746         ((pi)->num_cmds == 0 IF_HAS_KEYWORDS( && (pi)->res_word == RES_NONE))
747
748 /* This holds pointers to the various results of parsing */
749 struct parse_context {
750         /* linked list of pipes */
751         struct pipe *list_head;
752         /* last pipe (being constructed right now) */
753         struct pipe *pipe;
754         /* last command in pipe (being constructed right now) */
755         struct command *command;
756 #ifndef __U_BOOT__
757         /* last redirect in command->redirects list */
758         struct redir_struct *pending_redirect;
759 #endif /* !__U_BOOT__ */
760         o_string word;
761 #if !BB_MMU
762         o_string as_string;
763 #endif
764         smallint is_assignment; /* 0:maybe, 1:yes, 2:no, 3:keyword */
765 #if HAS_KEYWORDS
766         smallint ctx_res_w;
767         smallint ctx_inverted; /* "! cmd | cmd" */
768 #if ENABLE_HUSH_CASE
769         smallint ctx_dsemicolon; /* ";;" seen */
770 #endif
771         /* bitmask of FLAG_xxx, for figuring out valid reserved words */
772         int old_flag;
773         /* group we are enclosed in:
774          * example: "if pipe1; pipe2; then pipe3; fi"
775          * when we see "if" or "then", we malloc and copy current context,
776          * and make ->stack point to it. then we parse pipeN.
777          * when closing "then" / fi" / whatever is found,
778          * we move list_head into ->stack->command->group,
779          * copy ->stack into current context, and delete ->stack.
780          * (parsing of { list } and ( list ) doesn't use this method)
781          */
782         struct parse_context *stack;
783 #endif
784 };
785 enum {
786         MAYBE_ASSIGNMENT      = 0,
787         DEFINITELY_ASSIGNMENT = 1,
788         NOT_ASSIGNMENT        = 2,
789         /* Not an assignment, but next word may be: "if v=xyz cmd;" */
790         WORD_IS_KEYWORD       = 3,
791 };
792
793 #ifndef __U_BOOT__
794 /* On program start, environ points to initial environment.
795  * putenv adds new pointers into it, unsetenv removes them.
796  * Neither of these (de)allocates the strings.
797  * setenv allocates new strings in malloc space and does putenv,
798  * and thus setenv is unusable (leaky) for shell's purposes */
799 #define setenv(...) setenv_is_leaky_dont_use()
800 #endif /* !__U_BOOT__ */
801 struct variable {
802         struct variable *next;
803         char *varstr;        /* points to "name=" portion */
804         int max_len;         /* if > 0, name is part of initial env; else name is malloced */
805 #ifndef __U_BOOT__
806         uint16_t var_nest_level;
807         smallint flg_export; /* putenv should be done on this var */
808         smallint flg_read_only;
809 #endif /* !__U_BOOT__ */
810 };
811
812 enum {
813         BC_BREAK = 1,
814         BC_CONTINUE = 2,
815 };
816
817 #if ENABLE_HUSH_FUNCTIONS
818 struct function {
819         struct function *next;
820         char *name;
821         struct command *parent_cmd;
822         struct pipe *body;
823 # if !BB_MMU
824         char *body_as_string;
825 # endif
826 };
827 #endif
828
829 /* set -/+o OPT support. (TODO: make it optional)
830  * bash supports the following opts:
831  * allexport       off
832  * braceexpand     on
833  * emacs           on
834  * errexit         off
835  * errtrace        off
836  * functrace       off
837  * hashall         on
838  * histexpand      off
839  * history         on
840  * ignoreeof       off
841  * interactive-comments    on
842  * keyword         off
843  * monitor         on
844  * noclobber       off
845  * noexec          off
846  * noglob          off
847  * nolog           off
848  * notify          off
849  * nounset         off
850  * onecmd          off
851  * physical        off
852  * pipefail        off
853  * posix           off
854  * privileged      off
855  * verbose         off
856  * vi              off
857  * xtrace          off
858  */
859 static const char o_opt_strings[] ALIGN1 =
860         "pipefail\0"
861         "noexec\0"
862         "errexit\0"
863 #if ENABLE_HUSH_MODE_X
864         "xtrace\0"
865 #endif
866         ;
867 enum {
868         OPT_O_PIPEFAIL,
869         OPT_O_NOEXEC,
870         OPT_O_ERREXIT,
871 #if ENABLE_HUSH_MODE_X
872         OPT_O_XTRACE,
873 #endif
874         NUM_OPT_O
875 };
876
877 /* "Globals" within this file */
878 /* Sorted roughly by size (smaller offsets == smaller code) */
879 struct globals {
880 #ifndef __U_BOOT__
881         /* interactive_fd != 0 means we are an interactive shell.
882          * If we are, then saved_tty_pgrp can also be != 0, meaning
883          * that controlling tty is available. With saved_tty_pgrp == 0,
884          * job control still works, but terminal signals
885          * (^C, ^Z, ^Y, ^\) won't work at all, and background
886          * process groups can only be created with "cmd &".
887          * With saved_tty_pgrp != 0, hush will use tcsetpgrp()
888          * to give tty to the foreground process group,
889          * and will take it back when the group is stopped (^Z)
890          * or killed (^C).
891          */
892 #if ENABLE_HUSH_INTERACTIVE
893         /* 'interactive_fd' is a fd# open to ctty, if we have one
894          * _AND_ if we decided to act interactively */
895         int interactive_fd;
896         IF_NOT_FEATURE_EDITING_FANCY_PROMPT(char *PS1;)
897 # define G_interactive_fd (G.interactive_fd)
898 #else
899 # define G_interactive_fd 0
900 #endif
901 #else /* __U_BOOT__ */
902 # define G_interactive_fd 0
903 #endif /* __U_BOOT__ */
904 #ifndef __U_BOOT__
905 #if ENABLE_FEATURE_EDITING
906         line_input_t *line_input_state;
907 #endif
908         pid_t root_pid;
909         pid_t root_ppid;
910         pid_t last_bg_pid;
911 #if ENABLE_HUSH_RANDOM_SUPPORT
912         random_t random_gen;
913 #endif
914 #if ENABLE_HUSH_JOB
915         int run_list_level;
916         unsigned last_jobid;
917         pid_t saved_tty_pgrp;
918         struct pipe *job_list;
919 # define G_saved_tty_pgrp (G.saved_tty_pgrp)
920 #else
921 # define G_saved_tty_pgrp 0
922 #endif
923 #endif /* !__U_BOOT__ */
924         /* How deeply are we in context where "set -e" is ignored */
925         int errexit_depth;
926 #ifndef __U_BOOT__
927         /* "set -e" rules (do we follow them correctly?):
928          * Exit if pipe, list, or compound command exits with a non-zero status.
929          * Shell does not exit if failed command is part of condition in
930          * if/while, part of && or || list except the last command, any command
931          * in a pipe but the last, or if the command's return value is being
932          * inverted with !. If a compound command other than a subshell returns a
933          * non-zero status because a command failed while -e was being ignored, the
934          * shell does not exit. A trap on ERR, if set, is executed before the shell
935          * exits [ERR is a bashism].
936          *
937          * If a compound command or function executes in a context where -e is
938          * ignored, none of the commands executed within are affected by the -e
939          * setting. If a compound command or function sets -e while executing in a
940          * context where -e is ignored, that setting does not have any effect until
941          * the compound command or the command containing the function call completes.
942          */
943
944         char o_opt[NUM_OPT_O];
945 #if ENABLE_HUSH_MODE_X
946 # define G_x_mode (G.o_opt[OPT_O_XTRACE])
947 #else
948 # define G_x_mode 0
949 #endif
950         char opt_s;
951         char opt_c;
952 #endif /* !__U_BOOT__ */
953 #if ENABLE_HUSH_INTERACTIVE
954         smallint promptmode; /* 0: PS1, 1: PS2 */
955 #endif
956         /* set by signal handler if SIGINT is received _and_ its trap is not set */
957         smallint flag_SIGINT;
958 #ifndef __U_BOOT__
959 #if ENABLE_HUSH_LOOPS
960         smallint flag_break_continue;
961 #endif
962 #endif /* !__U_BOOT__ */
963 #if ENABLE_HUSH_FUNCTIONS
964         /* 0: outside of a function (or sourced file)
965          * -1: inside of a function, ok to use return builtin
966          * 1: return is invoked, skip all till end of func
967          */
968         smallint flag_return_in_progress;
969 # define G_flag_return_in_progress (G.flag_return_in_progress)
970 #else
971 # define G_flag_return_in_progress 0
972 #endif
973         smallint exiting; /* used to prevent EXIT trap recursion */
974         /* These support $? */
975         smalluint last_exitcode;
976         smalluint expand_exitcode;
977         smalluint last_bg_pid_exitcode;
978 #ifndef __U_BOOT__
979 #if ENABLE_HUSH_SET
980         /* are global_argv and global_argv[1..n] malloced? (note: not [0]) */
981         smalluint global_args_malloced;
982 # define G_global_args_malloced (G.global_args_malloced)
983 #else
984 # define G_global_args_malloced 0
985 #endif
986 #if ENABLE_HUSH_BASH_COMPAT
987         int dead_job_exitcode; /* for "wait -n" */
988 #endif
989 #endif /* !__U_BOOT__ */
990         /* how many non-NULL argv's we have. NB: $# + 1 */
991         int global_argc;
992         char **global_argv;
993 #if !BB_MMU
994         char *argv0_for_re_execing;
995 #endif
996 #if ENABLE_HUSH_LOOPS
997 #ifndef __U_BOOT__
998         unsigned depth_break_continue;
999 #endif /* !__U_BOOT__ */
1000         unsigned depth_of_loop;
1001 #endif
1002 #ifndef __U_BOOT__
1003 #if ENABLE_HUSH_GETOPTS
1004         unsigned getopt_count;
1005 #endif
1006 #endif /* !__U_BOOT__ */
1007         const char *ifs;
1008 #ifdef __U_BOOT__
1009         int flag_repeat;
1010         int do_repeat;
1011         int run_command_flags;
1012 #endif /* __U_BOOT__ */
1013         char *ifs_whitespace; /* = G.ifs or malloced */
1014 #ifndef __U_BOOT__
1015         const char *cwd;
1016 #endif /* !__U_BOOT__ */
1017         struct variable *top_var;
1018         char **expanded_assignments;
1019         struct variable **shadowed_vars_pp;
1020         unsigned var_nest_level;
1021 #ifndef __U_BOOT__
1022 #if ENABLE_HUSH_FUNCTIONS
1023 # if ENABLE_HUSH_LOCAL
1024         unsigned func_nest_level; /* solely to prevent "local v" in non-functions */
1025 # endif
1026         struct function *top_func;
1027 #endif
1028         /* Signal and trap handling */
1029 #if ENABLE_HUSH_FAST
1030         unsigned count_SIGCHLD;
1031         unsigned handled_SIGCHLD;
1032         smallint we_have_children;
1033 #endif
1034 #if ENABLE_HUSH_LINENO_VAR
1035         unsigned parse_lineno;
1036         unsigned execute_lineno;
1037 #endif
1038         HFILE *HFILE_list;
1039         HFILE *HFILE_stdin;
1040         /* Which signals have non-DFL handler (even with no traps set)?
1041          * Set at the start to:
1042          * (SIGQUIT + maybe SPECIAL_INTERACTIVE_SIGS + maybe SPECIAL_JOBSTOP_SIGS)
1043          * SPECIAL_INTERACTIVE_SIGS are cleared after fork.
1044          * The rest is cleared right before execv syscalls.
1045          * Other than these two times, never modified.
1046          */
1047         unsigned special_sig_mask;
1048 #if ENABLE_HUSH_JOB
1049         unsigned fatal_sig_mask;
1050 # define G_fatal_sig_mask (G.fatal_sig_mask)
1051 #else
1052 # define G_fatal_sig_mask 0
1053 #endif
1054 #if ENABLE_HUSH_TRAP
1055         int pre_trap_exitcode;
1056 # if ENABLE_HUSH_FUNCTIONS
1057         int return_exitcode;
1058 # endif
1059         char **traps; /* char *traps[NSIG] */
1060 # define G_traps G.traps
1061 #else
1062 # define G_traps ((char**)NULL)
1063 #endif
1064         sigset_t pending_set;
1065 #if ENABLE_HUSH_MEMLEAK
1066         unsigned long memleak_value;
1067 #endif
1068 #if ENABLE_HUSH_MODE_X
1069         unsigned x_mode_depth;
1070         /* "set -x" output should not be redirectable with subsequent 2>FILE.
1071          * We dup fd#2 to x_mode_fd when "set -x" is executed, and use it
1072          * for all subsequent output.
1073          */
1074         int x_mode_fd;
1075         o_string x_mode_buf;
1076 #endif
1077 #endif /* !__U_BOOT__ */
1078 #if HUSH_DEBUG >= 2
1079         int debug_indent;
1080 #endif
1081 #ifndef __U_BOOT__
1082         struct sigaction sa;
1083         char optstring_buf[sizeof("eixcs")];
1084 #if BASH_EPOCH_VARS
1085         char epoch_buf[sizeof("%llu.nnnnnn") + sizeof(long long)*3];
1086 #endif
1087 #if ENABLE_FEATURE_EDITING
1088         char user_input_buf[CONFIG_FEATURE_EDITING_MAX_LEN];
1089 #endif
1090 #endif /* !__U_BOOT__ */
1091 };
1092 #ifdef __U_BOOT__
1093 struct globals *ptr_to_globals;
1094 #endif /* __U_BOOT__ */
1095 #define G (*ptr_to_globals)
1096 /* Not #defining name to G.name - this quickly gets unwieldy
1097  * (too many defines). Also, I actually prefer to see when a variable
1098  * is global, thus "G." prefix is a useful hint */
1099 #ifdef __U_BOOT__
1100 #define SET_PTR_TO_GLOBALS(x) do { \
1101         (*(struct globals**)&ptr_to_globals) = (void*)(x); \
1102         barrier(); \
1103 } while (0)
1104 #define INIT_G() do { \
1105         SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
1106         G.promptmode = 1; \
1107 } while (0)
1108 #else /* !__U_BOOT__ */
1109 #define INIT_G() do { \
1110         SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
1111         /* memset(&G.sa, 0, sizeof(G.sa)); */  \
1112         sigfillset(&G.sa.sa_mask); \
1113         G.sa.sa_flags = SA_RESTART; \
1114 } while (0)
1115 #endif /* !__U_BOOT__ */
1116
1117 #ifndef __U_BOOT__
1118 /* Function prototypes for builtins */
1119 static int builtin_cd(char **argv) FAST_FUNC;
1120 #if ENABLE_HUSH_ECHO
1121 static int builtin_echo(char **argv) FAST_FUNC;
1122 #endif
1123 static int builtin_eval(char **argv) FAST_FUNC;
1124 static int builtin_exec(char **argv) FAST_FUNC;
1125 static int builtin_exit(char **argv) FAST_FUNC;
1126 #if ENABLE_HUSH_EXPORT
1127 static int builtin_export(char **argv) FAST_FUNC;
1128 #endif
1129 #if ENABLE_HUSH_READONLY
1130 static int builtin_readonly(char **argv) FAST_FUNC;
1131 #endif
1132 static int builtin_false(char **argv) FAST_FUNC;
1133 #if ENABLE_HUSH_JOB
1134 static int builtin_fg_bg(char **argv) FAST_FUNC;
1135 static int builtin_jobs(char **argv) FAST_FUNC;
1136 #endif
1137 #if ENABLE_HUSH_GETOPTS
1138 static int builtin_getopts(char **argv) FAST_FUNC;
1139 #endif
1140 #if ENABLE_HUSH_HELP
1141 static int builtin_help(char **argv) FAST_FUNC;
1142 #endif
1143 #if MAX_HISTORY && ENABLE_FEATURE_EDITING
1144 static int builtin_history(char **argv) FAST_FUNC;
1145 #endif
1146 #if ENABLE_HUSH_LOCAL
1147 static int builtin_local(char **argv) FAST_FUNC;
1148 #endif
1149 #if ENABLE_HUSH_MEMLEAK
1150 static int builtin_memleak(char **argv) FAST_FUNC;
1151 #endif
1152 #if ENABLE_HUSH_PRINTF
1153 static int builtin_printf(char **argv) FAST_FUNC;
1154 #endif
1155 static int builtin_pwd(char **argv) FAST_FUNC;
1156 #if ENABLE_HUSH_READ
1157 static int builtin_read(char **argv) FAST_FUNC;
1158 #endif
1159 #if ENABLE_HUSH_SET
1160 static int builtin_set(char **argv) FAST_FUNC;
1161 #endif
1162 static int builtin_shift(char **argv) FAST_FUNC;
1163 static int builtin_source(char **argv) FAST_FUNC;
1164 #if ENABLE_HUSH_TEST || BASH_TEST2
1165 static int builtin_test(char **argv) FAST_FUNC;
1166 #endif
1167 #if ENABLE_HUSH_TRAP
1168 static int builtin_trap(char **argv) FAST_FUNC;
1169 #endif
1170 #if ENABLE_HUSH_TYPE
1171 static int builtin_type(char **argv) FAST_FUNC;
1172 #endif
1173 #if ENABLE_HUSH_TIMES
1174 static int builtin_times(char **argv) FAST_FUNC;
1175 #endif
1176 static int builtin_true(char **argv) FAST_FUNC;
1177 #if ENABLE_HUSH_UMASK
1178 static int builtin_umask(char **argv) FAST_FUNC;
1179 #endif
1180 #if ENABLE_HUSH_UNSET
1181 static int builtin_unset(char **argv) FAST_FUNC;
1182 #endif
1183 #if ENABLE_HUSH_KILL
1184 static int builtin_kill(char **argv) FAST_FUNC;
1185 #endif
1186 #if ENABLE_HUSH_WAIT
1187 static int builtin_wait(char **argv) FAST_FUNC;
1188 #endif
1189 #if ENABLE_HUSH_LOOPS
1190 static int builtin_break(char **argv) FAST_FUNC;
1191 static int builtin_continue(char **argv) FAST_FUNC;
1192 #endif
1193 #if ENABLE_HUSH_FUNCTIONS
1194 static int builtin_return(char **argv) FAST_FUNC;
1195 #endif
1196
1197 /* Table of built-in functions.  They can be forked or not, depending on
1198  * context: within pipes, they fork.  As simple commands, they do not.
1199  * When used in non-forking context, they can change global variables
1200  * in the parent shell process.  If forked, of course they cannot.
1201  * For example, 'unset foo | whatever' will parse and run, but foo will
1202  * still be set at the end. */
1203 struct built_in_command {
1204         const char *b_cmd;
1205         int (*b_function)(char **argv) FAST_FUNC;
1206 #if ENABLE_HUSH_HELP
1207         const char *b_descr;
1208 # define BLTIN(cmd, func, help) { cmd, func, help }
1209 #else
1210 # define BLTIN(cmd, func, help) { cmd, func }
1211 #endif
1212 };
1213
1214 static const struct built_in_command bltins1[] ALIGN_PTR = {
1215         BLTIN("."        , builtin_source  , "Run commands in file"),
1216         BLTIN(":"        , builtin_true    , NULL),
1217 #if ENABLE_HUSH_JOB
1218         BLTIN("bg"       , builtin_fg_bg   , "Resume job in background"),
1219 #endif
1220 #if ENABLE_HUSH_LOOPS
1221         BLTIN("break"    , builtin_break   , "Exit loop"),
1222 #endif
1223         BLTIN("cd"       , builtin_cd      , "Change directory"),
1224 #if ENABLE_HUSH_LOOPS
1225         BLTIN("continue" , builtin_continue, "Start new loop iteration"),
1226 #endif
1227         BLTIN("eval"     , builtin_eval    , "Construct and run shell command"),
1228         BLTIN("exec"     , builtin_exec    , "Execute command, don't return to shell"),
1229         BLTIN("exit"     , builtin_exit    , NULL),
1230 #if ENABLE_HUSH_EXPORT
1231         BLTIN("export"   , builtin_export  , "Set environment variables"),
1232 #endif
1233         BLTIN("false"    , builtin_false   , NULL),
1234 #if ENABLE_HUSH_JOB
1235         BLTIN("fg"       , builtin_fg_bg   , "Bring job to foreground"),
1236 #endif
1237 #if ENABLE_HUSH_GETOPTS
1238         BLTIN("getopts"  , builtin_getopts , NULL),
1239 #endif
1240 #if ENABLE_HUSH_HELP
1241         BLTIN("help"     , builtin_help    , NULL),
1242 #endif
1243 #if MAX_HISTORY && ENABLE_FEATURE_EDITING
1244         BLTIN("history"  , builtin_history , "Show history"),
1245 #endif
1246 #if ENABLE_HUSH_JOB
1247         BLTIN("jobs"     , builtin_jobs    , "List jobs"),
1248 #endif
1249 #if ENABLE_HUSH_KILL
1250         BLTIN("kill"     , builtin_kill    , "Send signals to processes"),
1251 #endif
1252 #if ENABLE_HUSH_LOCAL
1253         BLTIN("local"    , builtin_local   , "Set local variables"),
1254 #endif
1255 #if ENABLE_HUSH_MEMLEAK
1256         BLTIN("memleak"  , builtin_memleak , NULL),
1257 #endif
1258 #if ENABLE_HUSH_READ
1259         BLTIN("read"     , builtin_read    , "Input into variable"),
1260 #endif
1261 #if ENABLE_HUSH_READONLY
1262         BLTIN("readonly" , builtin_readonly, "Make variables read-only"),
1263 #endif
1264 #if ENABLE_HUSH_FUNCTIONS
1265         BLTIN("return"   , builtin_return  , "Return from function"),
1266 #endif
1267 #if ENABLE_HUSH_SET
1268         BLTIN("set"      , builtin_set     , "Set positional parameters"),
1269 #endif
1270         BLTIN("shift"    , builtin_shift   , "Shift positional parameters"),
1271 #if BASH_SOURCE
1272         BLTIN("source"   , builtin_source  , NULL),
1273 #endif
1274 #if ENABLE_HUSH_TIMES
1275         BLTIN("times"    , builtin_times   , NULL),
1276 #endif
1277 #if ENABLE_HUSH_TRAP
1278         BLTIN("trap"     , builtin_trap    , "Trap signals"),
1279 #endif
1280         BLTIN("true"     , builtin_true    , NULL),
1281 #if ENABLE_HUSH_TYPE
1282         BLTIN("type"     , builtin_type    , "Show command type"),
1283 #endif
1284 #if ENABLE_HUSH_ULIMIT
1285         BLTIN("ulimit"   , shell_builtin_ulimit, "Control resource limits"),
1286 #endif
1287 #if ENABLE_HUSH_UMASK
1288         BLTIN("umask"    , builtin_umask   , "Set file creation mask"),
1289 #endif
1290 #if ENABLE_HUSH_UNSET
1291         BLTIN("unset"    , builtin_unset   , "Unset variables"),
1292 #endif
1293 #if ENABLE_HUSH_WAIT
1294         BLTIN("wait"     , builtin_wait    , "Wait for process to finish"),
1295 #endif
1296 };
1297 /* These builtins won't be used if we are on NOMMU and need to re-exec
1298  * (it's cheaper to run an external program in this case):
1299  */
1300 static const struct built_in_command bltins2[] ALIGN_PTR = {
1301 #if ENABLE_HUSH_TEST
1302         BLTIN("["        , builtin_test    , NULL),
1303 #endif
1304 #if BASH_TEST2
1305         BLTIN("[["       , builtin_test    , NULL),
1306 #endif
1307 #if ENABLE_HUSH_ECHO
1308         BLTIN("echo"     , builtin_echo    , NULL),
1309 #endif
1310 #if ENABLE_HUSH_PRINTF
1311         BLTIN("printf"   , builtin_printf  , NULL),
1312 #endif
1313         BLTIN("pwd"      , builtin_pwd     , NULL),
1314 #if ENABLE_HUSH_TEST
1315         BLTIN("test"     , builtin_test    , NULL),
1316 #endif
1317 };
1318
1319 #endif /* !__U_BOOT__ */
1320
1321 /* Debug printouts.
1322  */
1323 #if HUSH_DEBUG >= 2
1324 /* prevent disasters with G.debug_indent < 0 */
1325 # define indent() fdprintf(2, "%*s", (G.debug_indent * 2) & 0xff, "")
1326 # define debug_enter() (G.debug_indent++)
1327 # define debug_leave() (G.debug_indent--)
1328 #else
1329 # define indent()      ((void)0)
1330 # define debug_enter() ((void)0)
1331 # define debug_leave() ((void)0)
1332 #endif
1333
1334 #ifndef debug_printf
1335 # define debug_printf(...) (indent(), fdprintf(2, __VA_ARGS__))
1336 #endif
1337
1338 #ifndef debug_printf_parse
1339 # define debug_printf_parse(...) (indent(), fdprintf(2, __VA_ARGS__))
1340 #endif
1341
1342 #ifndef debug_printf_heredoc
1343 # define debug_printf_heredoc(...) (indent(), fdprintf(2, __VA_ARGS__))
1344 #endif
1345
1346 #ifndef debug_printf_exec
1347 #define debug_printf_exec(...) (indent(), fdprintf(2, __VA_ARGS__))
1348 #endif
1349
1350 #ifndef debug_printf_env
1351 # define debug_printf_env(...) (indent(), fdprintf(2, __VA_ARGS__))
1352 #endif
1353
1354 #ifndef debug_printf_jobs
1355 # define debug_printf_jobs(...) (indent(), fdprintf(2, __VA_ARGS__))
1356 # define DEBUG_JOBS 1
1357 #else
1358 # define DEBUG_JOBS 0
1359 #endif
1360
1361 #ifndef debug_printf_expand
1362 # define debug_printf_expand(...) (indent(), fdprintf(2, __VA_ARGS__))
1363 # define DEBUG_EXPAND 1
1364 #else
1365 # define DEBUG_EXPAND 0
1366 #endif
1367
1368 #ifndef debug_printf_varexp
1369 # define debug_printf_varexp(...) (indent(), fdprintf(2, __VA_ARGS__))
1370 #endif
1371
1372 #ifndef debug_printf_glob
1373 # define debug_printf_glob(...) (indent(), fdprintf(2, __VA_ARGS__))
1374 # define DEBUG_GLOB 1
1375 #else
1376 # define DEBUG_GLOB 0
1377 #endif
1378
1379 #ifndef debug_printf_redir
1380 # define debug_printf_redir(...) (indent(), fdprintf(2, __VA_ARGS__))
1381 #endif
1382
1383 #ifndef debug_printf_list
1384 # define debug_printf_list(...) (indent(), fdprintf(2, __VA_ARGS__))
1385 #endif
1386
1387 #ifndef debug_printf_subst
1388 # define debug_printf_subst(...) (indent(), fdprintf(2, __VA_ARGS__))
1389 #endif
1390
1391 #ifndef debug_printf_prompt
1392 # define debug_printf_prompt(...) (indent(), fdprintf(2, __VA_ARGS__))
1393 #endif
1394
1395 #ifndef debug_printf_clean
1396 # define debug_printf_clean(...) (indent(), fdprintf(2, __VA_ARGS__))
1397 # define DEBUG_CLEAN 1
1398 #else
1399 # define DEBUG_CLEAN 0
1400 #endif
1401
1402 #if DEBUG_EXPAND
1403 static void debug_print_strings(const char *prefix, char **vv)
1404 {
1405         indent();
1406         fdprintf(2, "%s:\n", prefix);
1407         while (*vv)
1408                 fdprintf(2, " '%s'\n", *vv++);
1409 }
1410 #else
1411 # define debug_print_strings(prefix, vv) ((void)0)
1412 #endif
1413
1414 /* Leak hunting. Use hush_leaktool.sh for post-processing.
1415  */
1416 #if LEAK_HUNTING
1417 static void *xxmalloc(int lineno, size_t size)
1418 {
1419         void *ptr = xmalloc((size + 0xff) & ~0xff);
1420         fdprintf(2, "line %d: malloc %p\n", lineno, ptr);
1421         return ptr;
1422 }
1423 static void *xxrealloc(int lineno, void *ptr, size_t size)
1424 {
1425         ptr = xrealloc(ptr, (size + 0xff) & ~0xff);
1426         fdprintf(2, "line %d: realloc %p\n", lineno, ptr);
1427         return ptr;
1428 }
1429 static char *xxstrdup(int lineno, const char *str)
1430 {
1431         char *ptr = xstrdup(str);
1432         fdprintf(2, "line %d: strdup %p\n", lineno, ptr);
1433         return ptr;
1434 }
1435 static void xxfree(void *ptr)
1436 {
1437         fdprintf(2, "free %p\n", ptr);
1438         free(ptr);
1439 }
1440 # define xmalloc(s)     xxmalloc(__LINE__, s)
1441 # define xrealloc(p, s) xxrealloc(__LINE__, p, s)
1442 # define xstrdup(s)     xxstrdup(__LINE__, s)
1443 # define free(p)        xxfree(p)
1444 #endif
1445
1446 /* Syntax and runtime errors. They always abort scripts.
1447  * In interactive use they usually discard unparsed and/or unexecuted commands
1448  * and return to the prompt.
1449  * HUSH_DEBUG >= 2 prints line number in this file where it was detected.
1450  */
1451 #if HUSH_DEBUG < 2
1452 # define msg_and_die_if_script(lineno, ...)     msg_and_die_if_script(__VA_ARGS__)
1453 # define syntax_error(lineno, msg)              syntax_error(msg)
1454 # define syntax_error_at(lineno, msg)           syntax_error_at(msg)
1455 # define syntax_error_unterm_ch(lineno, ch)     syntax_error_unterm_ch(ch)
1456 # define syntax_error_unterm_str(lineno, s)     syntax_error_unterm_str(s)
1457 # define syntax_error_unexpected_ch(lineno, ch) syntax_error_unexpected_ch(ch)
1458 #endif
1459
1460 static void die_if_script(void)
1461 {
1462         if (!G_interactive_fd) {
1463                 if (G.last_exitcode) /* sometines it's 2, not 1 (bash compat) */
1464                         xfunc_error_retval = G.last_exitcode;
1465                 xfunc_die();
1466         }
1467 }
1468
1469 #ifdef __U_BOOT__
1470 static void __maybe_unused msg_and_die_if_script(unsigned lineno, const char *fmt, ...)
1471 #else /* !__U_BOOT__ */
1472 static void msg_and_die_if_script(unsigned lineno, const char *fmt, ...)
1473 #endif /* !__U_BOOT__ */
1474 {
1475         va_list p;
1476
1477 #if HUSH_DEBUG >= 2
1478         bb_error_msg("hush.c:%u", lineno);
1479 #endif
1480         va_start(p, fmt);
1481         bb_verror_msg(fmt, p, NULL);
1482         va_end(p);
1483         die_if_script();
1484 }
1485
1486 static void syntax_error(unsigned lineno UNUSED_PARAM, const char *msg)
1487 {
1488         if (msg)
1489                 bb_error_msg("syntax error: %s", msg);
1490         else
1491                 bb_simple_error_msg("syntax error");
1492         die_if_script();
1493 }
1494
1495 static void syntax_error_at(unsigned lineno UNUSED_PARAM, const char *msg)
1496 {
1497         bb_error_msg("syntax error at '%s'", msg);
1498         die_if_script();
1499 }
1500
1501 static void syntax_error_unterm_str(unsigned lineno UNUSED_PARAM, const char *s)
1502 {
1503         bb_error_msg("syntax error: unterminated %s", s);
1504 //? source4.tests fails: in bash, echo ${^} in script does not terminate the script
1505 // (but bash --posix, or if bash is run as "sh", does terminate in script, so maybe uncomment this?)
1506 //      die_if_script();
1507 }
1508
1509 static void syntax_error_unterm_ch(unsigned lineno, char ch)
1510 {
1511         char msg[2] = { ch, '\0' };
1512         syntax_error_unterm_str(lineno, msg);
1513 }
1514
1515 static void syntax_error_unexpected_ch(unsigned lineno UNUSED_PARAM, int ch)
1516 {
1517         char msg[2];
1518         msg[0] = ch;
1519         msg[1] = '\0';
1520 #if HUSH_DEBUG >= 2
1521         bb_error_msg("hush.c:%u", lineno);
1522 #endif
1523         bb_error_msg("syntax error: unexpected %s", ch == EOF ? "EOF" : msg);
1524         die_if_script();
1525 }
1526
1527 #if HUSH_DEBUG < 2
1528 # undef msg_and_die_if_script
1529 # undef syntax_error
1530 # undef syntax_error_at
1531 # undef syntax_error_unterm_ch
1532 # undef syntax_error_unterm_str
1533 # undef syntax_error_unexpected_ch
1534 #else
1535 # define msg_and_die_if_script(...)     msg_and_die_if_script(__LINE__, __VA_ARGS__)
1536 # define syntax_error(msg)              syntax_error(__LINE__, msg)
1537 # define syntax_error_at(msg)           syntax_error_at(__LINE__, msg)
1538 # define syntax_error_unterm_ch(ch)     syntax_error_unterm_ch(__LINE__, ch)
1539 # define syntax_error_unterm_str(s)     syntax_error_unterm_str(__LINE__, s)
1540 # define syntax_error_unexpected_ch(ch) syntax_error_unexpected_ch(__LINE__, ch)
1541 #endif
1542
1543 /* Utility functions
1544  */
1545 /* Replace each \x with x in place, return ptr past NUL. */
1546 static char *unbackslash(char *src)
1547 {
1548 #ifdef __U_BOOT__
1549         char *dst = src = (char *)strchrnul(src, '\\');
1550 #else /* !__U_BOOT__ */
1551         char *dst = src = strchrnul(src, '\\');
1552 #endif /* !__U_BOOT__ */
1553         while (1) {
1554                 if (*src == '\\') {
1555                         src++;
1556                         if (*src != '\0') {
1557                                 /* \x -> x */
1558                                 *dst++ = *src++;
1559                                 continue;
1560                         }
1561                         /* else: "\<nul>". Do not delete this backslash.
1562                          * Testcase: eval 'echo ok\'
1563                          */
1564                         *dst++ = '\\';
1565                         /* fallthrough */
1566                 }
1567                 if ((*dst++ = *src++) == '\0')
1568                         break;
1569         }
1570         return dst;
1571 }
1572
1573 static char **add_strings_to_strings(char **strings, char **add, int need_to_dup)
1574 {
1575         int i;
1576         unsigned count1;
1577         unsigned count2;
1578         char **v;
1579
1580         v = strings;
1581         count1 = 0;
1582         if (v) {
1583                 while (*v) {
1584                         count1++;
1585                         v++;
1586                 }
1587         }
1588         count2 = 0;
1589         v = add;
1590         while (*v) {
1591                 count2++;
1592                 v++;
1593         }
1594         v = xrealloc(strings, (count1 + count2 + 1) * sizeof(char*));
1595         v[count1 + count2] = NULL;
1596         i = count2;
1597         while (--i >= 0)
1598                 v[count1 + i] = (need_to_dup ? xstrdup(add[i]) : add[i]);
1599         return v;
1600 }
1601 #if LEAK_HUNTING
1602 static char **xx_add_strings_to_strings(int lineno, char **strings, char **add, int need_to_dup)
1603 {
1604         char **ptr = add_strings_to_strings(strings, add, need_to_dup);
1605         fdprintf(2, "line %d: add_strings_to_strings %p\n", lineno, ptr);
1606         return ptr;
1607 }
1608 #define add_strings_to_strings(strings, add, need_to_dup) \
1609         xx_add_strings_to_strings(__LINE__, strings, add, need_to_dup)
1610 #endif
1611
1612 /* Note: takes ownership of "add" ptr (it is not strdup'ed) */
1613 static char **add_string_to_strings(char **strings, char *add)
1614 {
1615         char *v[2];
1616         v[0] = add;
1617         v[1] = NULL;
1618         return add_strings_to_strings(strings, v, /*dup:*/ 0);
1619 }
1620
1621 #if LEAK_HUNTING
1622 static char **xx_add_string_to_strings(int lineno, char **strings, char *add)
1623 {
1624         char **ptr = add_string_to_strings(strings, add);
1625         fdprintf(2, "line %d: add_string_to_strings %p\n", lineno, ptr);
1626         return ptr;
1627 }
1628 #define add_string_to_strings(strings, add) \
1629         xx_add_string_to_strings(__LINE__, strings, add)
1630 #endif
1631
1632 static void free_strings(char **strings)
1633 {
1634         char **v;
1635
1636         if (!strings)
1637                 return;
1638         v = strings;
1639         while (*v) {
1640                 free(*v);
1641                 v++;
1642         }
1643         free(strings);
1644 }
1645
1646 #ifndef __U_BOOT__
1647 static int dup_CLOEXEC(int fd, int avoid_fd)
1648 {
1649         int newfd;
1650  repeat:
1651         newfd = fcntl(fd, F_DUPFD_CLOEXEC, avoid_fd + 1);
1652         if (newfd >= 0) {
1653                 if (F_DUPFD_CLOEXEC == F_DUPFD) /* if old libc (w/o F_DUPFD_CLOEXEC) */
1654                         close_on_exec_on(newfd);
1655         } else { /* newfd < 0 */
1656                 if (errno == EBUSY)
1657                         goto repeat;
1658                 if (errno == EINTR)
1659                         goto repeat;
1660                 if (errno != EBADF) {
1661                         /* "echo >&9999" gets EINVAL trying to save fd 1 to above 9999.
1662                          * We could try saving it _below_ 9999 instead (how?), but
1663                          * this probably means that dup2(9999,1) to effectuate >&9999
1664                          * would also not work: fd 9999 can't exist.
1665                          * (This differs from "echo >&99" where saving works, but
1666                          * subsequent dup2(99,1) fails if fd 99 is not open).
1667                          */
1668                         bb_perror_msg("fcntl(%d,F_DUPFD,%d)", fd, avoid_fd + 1);
1669                 }
1670         }
1671         return newfd;
1672 }
1673
1674 static int xdup_CLOEXEC_and_close(int fd, int avoid_fd)
1675 {
1676         int newfd;
1677  repeat:
1678         newfd = fcntl(fd, F_DUPFD_CLOEXEC, avoid_fd + 1);
1679         if (newfd < 0) {
1680                 if (errno == EBUSY)
1681                         goto repeat;
1682                 if (errno == EINTR)
1683                         goto repeat;
1684                 /* fd was not open? */
1685                 if (errno == EBADF)
1686                         return fd;
1687                 xfunc_die();
1688         }
1689         if (F_DUPFD_CLOEXEC == F_DUPFD) /* if old libc (w/o F_DUPFD_CLOEXEC) */
1690                 close_on_exec_on(newfd);
1691         close(fd);
1692         return newfd;
1693 }
1694
1695 /* Manipulating HFILEs */
1696 static HFILE *hfopen(const char *name)
1697 {
1698         HFILE *fp;
1699         int fd;
1700
1701         fd = STDIN_FILENO;
1702         if (name) {
1703                 fd = open(name, O_RDONLY | O_CLOEXEC);
1704                 if (fd < 0)
1705                         return NULL;
1706                 if (O_CLOEXEC == 0) /* ancient libc */
1707                         close_on_exec_on(fd);
1708         }
1709
1710         fp = xmalloc(sizeof(*fp));
1711         if (name == NULL)
1712                 G.HFILE_stdin = fp;
1713         fp->fd = fd;
1714         fp->cur = fp->end = fp->buf;
1715         fp->next_hfile = G.HFILE_list;
1716         G.HFILE_list = fp;
1717         return fp;
1718 }
1719 static void hfclose(HFILE *fp)
1720 {
1721         HFILE **pp = &G.HFILE_list;
1722         while (*pp) {
1723                 HFILE *cur = *pp;
1724                 if (cur == fp) {
1725                         *pp = cur->next_hfile;
1726                         break;
1727                 }
1728                 pp = &cur->next_hfile;
1729         }
1730         if (fp->fd >= 0)
1731                 close(fp->fd);
1732         free(fp);
1733 }
1734 static int refill_HFILE_and_getc(HFILE *fp)
1735 {
1736         int n;
1737
1738         if (fp->fd < 0) {
1739                 /* Already saw EOF */
1740                 return EOF;
1741         }
1742 #if ENABLE_HUSH_INTERACTIVE && !ENABLE_FEATURE_EDITING
1743         /* If user presses ^C, read() restarts after SIGINT (we use SA_RESTART).
1744          * IOW: ^C will not immediately stop line input.
1745          * But poll() is different: it does NOT restart after signals.
1746          */
1747         if (fp == G.HFILE_stdin) {
1748                 struct pollfd pfd[1];
1749                 pfd[0].fd = fp->fd;
1750                 pfd[0].events = POLLIN;
1751                 n = poll(pfd, 1, -1);
1752                 if (n < 0
1753                  /*&& errno == EINTR - assumed true */
1754                  && sigismember(&G.pending_set, SIGINT)
1755                 ) {
1756                         return '\0';
1757                 }
1758         }
1759 #else
1760 /* if FEATURE_EDITING=y, we do not use this routine for interactive input */
1761 #endif
1762         /* Try to buffer more input */
1763         n = safe_read(fp->fd, fp->buf, sizeof(fp->buf));
1764         if (n < 0) {
1765                 bb_simple_perror_msg("read error");
1766                 n = 0;
1767         }
1768         fp->cur = fp->buf;
1769         fp->end = fp->buf + n;
1770         if (n == 0) {
1771                 /* EOF/error */
1772                 close(fp->fd);
1773                 fp->fd = -1;
1774                 return EOF;
1775         }
1776         return (unsigned char)(*fp->cur++);
1777 }
1778 /* Inlined for common case of non-empty buffer.
1779  */
1780 static ALWAYS_INLINE int hfgetc(HFILE *fp)
1781 {
1782         if (fp->cur < fp->end)
1783                 return (unsigned char)(*fp->cur++);
1784         /* Buffer empty */
1785         return refill_HFILE_and_getc(fp);
1786 }
1787 static int move_HFILEs_on_redirect(int fd, int avoid_fd)
1788 {
1789         HFILE *fl = G.HFILE_list;
1790         while (fl) {
1791                 if (fd == fl->fd) {
1792                         /* We use it only on script files, they are all CLOEXEC */
1793                         fl->fd = xdup_CLOEXEC_and_close(fd, avoid_fd);
1794                         debug_printf_redir("redirect_fd %d: matches a script fd, moving it to %d\n", fd, fl->fd);
1795                         return 1; /* "found and moved" */
1796                 }
1797                 fl = fl->next_hfile;
1798         }
1799 #if ENABLE_HUSH_MODE_X
1800         if (G.x_mode_fd > 0 && fd == G.x_mode_fd) {
1801                 G.x_mode_fd = xdup_CLOEXEC_and_close(fd, avoid_fd);
1802                 return 1; /* "found and moved" */
1803         }
1804 #endif
1805         return 0; /* "not in the list" */
1806 }
1807 #if ENABLE_FEATURE_SH_STANDALONE && BB_MMU
1808 static void close_all_HFILE_list(void)
1809 {
1810         HFILE *fl = G.HFILE_list;
1811         while (fl) {
1812                 /* hfclose would also free HFILE object.
1813                  * It is disastrous if we share memory with a vforked parent.
1814                  * I'm not sure we never come here after vfork.
1815                  * Therefore just close fd, nothing more.
1816                  *
1817                  * ">" instead of ">=": we don't close fd#0,
1818                  * interactive shell uses hfopen(NULL) as stdin input
1819                  * which has fl->fd == 0, but fd#0 gets redirected in pipes.
1820                  * If we'd close it here, then e.g. interactive "set | sort"
1821                  * with NOFORKed sort, would have sort's input fd closed.
1822                  */
1823                 if (fl->fd > 0)
1824                         /*hfclose(fl); - unsafe */
1825                         close(fl->fd);
1826                 fl = fl->next_hfile;
1827         }
1828 }
1829 #endif
1830 static int fd_in_HFILEs(int fd)
1831 {
1832         HFILE *fl = G.HFILE_list;
1833         while (fl) {
1834                 if (fl->fd == fd)
1835                         return 1;
1836                 fl = fl->next_hfile;
1837         }
1838         return 0;
1839 }
1840
1841 #endif /* !__U_BOOT__ */
1842
1843 /* Helpers for setting new $n and restoring them back
1844  */
1845 typedef struct save_arg_t {
1846         char *sv_argv0;
1847         char **sv_g_argv;
1848         int sv_g_argc;
1849 #ifndef __U_BOOT__
1850         IF_HUSH_SET(smallint sv_g_malloced;)
1851 #endif /* !__U_BOOT__ */
1852 } save_arg_t;
1853
1854 #ifndef __U_BOOT__
1855 static void save_and_replace_G_args(save_arg_t *sv, char **argv)
1856 {
1857         sv->sv_argv0 = argv[0];
1858         sv->sv_g_argv = G.global_argv;
1859         sv->sv_g_argc = G.global_argc;
1860         IF_HUSH_SET(sv->sv_g_malloced = G.global_args_malloced;)
1861
1862         argv[0] = G.global_argv[0]; /* retain $0 */
1863         G.global_argv = argv;
1864         IF_HUSH_SET(G.global_args_malloced = 0;)
1865
1866         G.global_argc = 1 + string_array_len(argv + 1);
1867 }
1868
1869 static void restore_G_args(save_arg_t *sv, char **argv)
1870 {
1871 #if ENABLE_HUSH_SET
1872         if (G.global_args_malloced) {
1873                 /* someone ran "set -- arg1 arg2 ...", undo */
1874                 char **pp = G.global_argv;
1875                 while (*++pp) /* note: does not free $0 */
1876                         free(*pp);
1877                 free(G.global_argv);
1878         }
1879 #endif
1880         argv[0] = sv->sv_argv0;
1881         G.global_argv = sv->sv_g_argv;
1882         G.global_argc = sv->sv_g_argc;
1883         IF_HUSH_SET(G.global_args_malloced = sv->sv_g_malloced;)
1884 }
1885 #endif /* !__U_BOOT__ */
1886
1887 #ifndef __U_BOOT__
1888 /* Basic theory of signal handling in shell
1889  * ========================================
1890  * This does not describe what hush does, rather, it is current understanding
1891  * what it _should_ do. If it doesn't, it's a bug.
1892  * http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#trap
1893  *
1894  * Signals are handled only after each pipe ("cmd | cmd | cmd" thing)
1895  * is finished or backgrounded. It is the same in interactive and
1896  * non-interactive shells, and is the same regardless of whether
1897  * a user trap handler is installed or a shell special one is in effect.
1898  * ^C or ^Z from keyboard seems to execute "at once" because it usually
1899  * backgrounds (i.e. stops) or kills all members of currently running
1900  * pipe.
1901  *
1902  * Wait builtin is interruptible by signals for which user trap is set
1903  * or by SIGINT in interactive shell.
1904  *
1905  * Trap handlers will execute even within trap handlers. (right?)
1906  *
1907  * User trap handlers are forgotten when subshell ("(cmd)") is entered,
1908  * except for handlers set to '' (empty string).
1909  *
1910  * If job control is off, backgrounded commands ("cmd &")
1911  * have SIGINT, SIGQUIT set to SIG_IGN.
1912  *
1913  * Commands which are run in command substitution ("`cmd`")
1914  * have SIGTTIN, SIGTTOU, SIGTSTP set to SIG_IGN.
1915  *
1916  * Ordinary commands have signals set to SIG_IGN/DFL as inherited
1917  * by the shell from its parent.
1918  *
1919  * Signals which differ from SIG_DFL action
1920  * (note: child (i.e., [v]forked) shell is not an interactive shell):
1921  *
1922  * SIGQUIT: ignore
1923  * SIGTERM (interactive): ignore
1924  * SIGHUP (interactive):
1925  *    Send SIGCONT to stopped jobs, send SIGHUP to all jobs and exit.
1926  *    Kernel would do this for us ("orphaned process group" handling
1927  *    according to POSIX) if we are a session leader and thus our death
1928  *    frees the controlling tty, but to be bash-compatible, we also do it
1929  *    for every interactive shell's death by SIGHUP.
1930  *    (Also, we need to restore tty pgrp, otherwise e.g. Midnight Commander
1931  *    backgrounds when hush started from it gets killed by SIGHUP).
1932  * SIGTTIN, SIGTTOU, SIGTSTP (if job control is on): ignore
1933  *    Note that ^Z is handled not by trapping SIGTSTP, but by seeing
1934  *    that all pipe members are stopped. Try this in bash:
1935  *    while :; do :; done - ^Z does not background it
1936  *    (while :; do :; done) - ^Z backgrounds it
1937  * SIGINT (interactive): wait for last pipe, ignore the rest
1938  *    of the command line, show prompt. NB: ^C does not send SIGINT
1939  *    to interactive shell while shell is waiting for a pipe,
1940  *    since shell is bg'ed (is not in foreground process group).
1941  *    Example 1: this waits 5 sec, but does not execute ls:
1942  *    "echo $$; sleep 5; ls -l" + "kill -INT <pid>"
1943  *    Example 2: this does not wait and does not execute ls:
1944  *    "echo $$; sleep 5 & wait; ls -l" + "kill -INT <pid>"
1945  *    Example 3: this does not wait 5 sec, but executes ls:
1946  *    "sleep 5; ls -l" + press ^C
1947  *    Example 4: this does not wait and does not execute ls:
1948  *    "sleep 5 & wait; ls -l" + press ^C
1949  *
1950  * (What happens to signals which are IGN on shell start?)
1951  * (What happens with signal mask on shell start?)
1952  *
1953  * Old implementation
1954  * ==================
1955  * We use in-kernel pending signal mask to determine which signals were sent.
1956  * We block all signals which we don't want to take action immediately,
1957  * i.e. we block all signals which need to have special handling as described
1958  * above, and all signals which have traps set.
1959  * After each pipe execution, we extract any pending signals via sigtimedwait()
1960  * and act on them.
1961  *
1962  * unsigned special_sig_mask: a mask of such "special" signals
1963  * sigset_t blocked_set:  current blocked signal set
1964  *
1965  * "trap - SIGxxx":
1966  *    clear bit in blocked_set unless it is also in special_sig_mask
1967  * "trap 'cmd' SIGxxx":
1968  *    set bit in blocked_set (even if 'cmd' is '')
1969  * after [v]fork, if we plan to be a shell:
1970  *    unblock signals with special interactive handling
1971  *    (child shell is not interactive),
1972  *    unset all traps except '' (note: regardless of child shell's type - {}, (), etc)
1973  * after [v]fork, if we plan to exec:
1974  *    POSIX says fork clears pending signal mask in child - no need to clear it.
1975  *    Restore blocked signal set to one inherited by shell just prior to exec.
1976  *
1977  * Note: as a result, we do not use signal handlers much. The only uses
1978  * are to count SIGCHLDs
1979  * and to restore tty pgrp on signal-induced exit.
1980  *
1981  * Note 2 (compat):
1982  * Standard says "When a subshell is entered, traps that are not being ignored
1983  * are set to the default actions". bash interprets it so that traps which
1984  * are set to '' (ignore) are NOT reset to defaults. We do the same.
1985  *
1986  * Problem: the above approach makes it unwieldy to catch signals while
1987  * we are in read builtin, or while we read commands from stdin:
1988  * masked signals are not visible!
1989  *
1990  * New implementation
1991  * ==================
1992  * We record each signal we are interested in by installing signal handler
1993  * for them - a bit like emulating kernel pending signal mask in userspace.
1994  * We are interested in: signals which need to have special handling
1995  * as described above, and all signals which have traps set.
1996  * Signals are recorded in pending_set.
1997  * After each pipe execution, we extract any pending signals
1998  * and act on them.
1999  *
2000  * unsigned special_sig_mask: a mask of shell-special signals.
2001  * unsigned fatal_sig_mask: a mask of signals on which we restore tty pgrp.
2002  * char *traps[sig] if trap for sig is set (even if it's '').
2003  * sigset_t pending_set: set of sigs we received.
2004  *
2005  * "trap - SIGxxx":
2006  *    if sig is in special_sig_mask, set handler back to:
2007  *        record_pending_signo, or to IGN if it's a tty stop signal
2008  *    if sig is in fatal_sig_mask, set handler back to sigexit.
2009  *    else: set handler back to SIG_DFL
2010  * "trap 'cmd' SIGxxx":
2011  *    set handler to record_pending_signo.
2012  * "trap '' SIGxxx":
2013  *    set handler to SIG_IGN.
2014  * after [v]fork, if we plan to be a shell:
2015  *    set signals with special interactive handling to SIG_DFL
2016  *    (because child shell is not interactive),
2017  *    unset all traps except '' (note: regardless of child shell's type - {}, (), etc)
2018  * after [v]fork, if we plan to exec:
2019  *    POSIX says fork clears pending signal mask in child - no need to clear it.
2020  *
2021  * To make wait builtin interruptible, we handle SIGCHLD as special signal,
2022  * otherwise (if we leave it SIG_DFL) sigsuspend in wait builtin will not wake up on it.
2023  *
2024  * Note (compat):
2025  * Standard says "When a subshell is entered, traps that are not being ignored
2026  * are set to the default actions". bash interprets it so that traps which
2027  * are set to '' (ignore) are NOT reset to defaults. We do the same.
2028  */
2029 enum {
2030         SPECIAL_INTERACTIVE_SIGS = 0
2031                 | (1 << SIGTERM)
2032                 | (1 << SIGINT)
2033                 | (1 << SIGHUP)
2034                 ,
2035         SPECIAL_JOBSTOP_SIGS = 0
2036 #if ENABLE_HUSH_JOB
2037                 | (1 << SIGTTIN)
2038                 | (1 << SIGTTOU)
2039                 | (1 << SIGTSTP)
2040 #endif
2041                 ,
2042 };
2043
2044 static void record_pending_signo(int sig)
2045 {
2046         sigaddset(&G.pending_set, sig);
2047 #if ENABLE_FEATURE_EDITING
2048         if (sig != SIGCHLD
2049          || (G_traps && G_traps[SIGCHLD] && G_traps[SIGCHLD][0])
2050          /* ^^^ if SIGCHLD, interrupt line reading only if it has a trap */
2051         ) {
2052                 bb_got_signal = sig; /* for read_line_input: "we got a signal" */
2053         }
2054 #endif
2055 #if ENABLE_HUSH_FAST
2056         if (sig == SIGCHLD) {
2057                 G.count_SIGCHLD++;
2058 //bb_error_msg("[%d] SIGCHLD_handler: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
2059         }
2060 #endif
2061 }
2062
2063 static sighandler_t install_sighandler(int sig, sighandler_t handler)
2064 {
2065         struct sigaction old_sa;
2066
2067         /* We could use signal() to install handlers... almost:
2068          * except that we need to mask ALL signals while handlers run.
2069          * I saw signal nesting in strace, race window isn't small.
2070          * SA_RESTART is also needed, but in Linux, signal()
2071          * sets SA_RESTART too.
2072          */
2073         /* memset(&G.sa, 0, sizeof(G.sa)); - already done */
2074         /* sigfillset(&G.sa.sa_mask);      - already done */
2075         /* G.sa.sa_flags = SA_RESTART;     - already done */
2076         G.sa.sa_handler = handler;
2077         sigaction(sig, &G.sa, &old_sa);
2078         return old_sa.sa_handler;
2079 }
2080 #endif /* !__U_BOOT__ */
2081
2082 #ifndef __U_BOOT__
2083 static void hush_exit(int exitcode) NORETURN;
2084
2085 static void restore_ttypgrp_and__exit(void) NORETURN;
2086 static void restore_ttypgrp_and__exit(void)
2087 {
2088         /* xfunc has failed! die die die */
2089         /* no EXIT traps, this is an escape hatch! */
2090         G.exiting = 1;
2091         hush_exit(xfunc_error_retval);
2092 }
2093
2094 #if ENABLE_HUSH_JOB
2095
2096 /* Needed only on some libc:
2097  * It was observed that on exit(), fgetc'ed buffered data
2098  * gets "unwound" via lseek(fd, -NUM, SEEK_CUR).
2099  * With the net effect that even after fork(), not vfork(),
2100  * exit() in NOEXECed applet in "sh SCRIPT":
2101  *      noexec_applet_here
2102  *      echo END_OF_SCRIPT
2103  * lseeks fd in input FILE object from EOF to "e" in "echo END_OF_SCRIPT".
2104  * This makes "echo END_OF_SCRIPT" executed twice.
2105  * Similar problems can be seen with msg_and_die_if_script() -> xfunc_die()
2106  * and in `cmd` handling.
2107  * If set as die_func(), this makes xfunc_die() exit via _exit(), not exit():
2108  */
2109 static void fflush_and__exit(void) NORETURN;
2110 static void fflush_and__exit(void)
2111 {
2112         fflush_all();
2113         _exit(xfunc_error_retval);
2114 }
2115
2116 /* After [v]fork, in child: do not restore tty pgrp on xfunc death */
2117 # define disable_restore_tty_pgrp_on_exit() (die_func = fflush_and__exit)
2118 /* After [v]fork, in parent: restore tty pgrp on xfunc death */
2119 # define enable_restore_tty_pgrp_on_exit()  (die_func = restore_ttypgrp_and__exit)
2120
2121 /* Restores tty foreground process group, and exits.
2122  * May be called as signal handler for fatal signal
2123  * (will resend signal to itself, producing correct exit state)
2124  * or called directly with -EXITCODE.
2125  * We also call it if xfunc is exiting.
2126  */
2127 static void sigexit(int sig) NORETURN;
2128 static void sigexit(int sig)
2129 {
2130         /* Careful: we can end up here after [v]fork. Do not restore
2131          * tty pgrp then, only top-level shell process does that */
2132         if (G_saved_tty_pgrp && getpid() == G.root_pid) {
2133                 /* Disable all signals: job control, SIGPIPE, etc.
2134                  * Mostly paranoid measure, to prevent infinite SIGTTOU.
2135                  */
2136                 sigprocmask_allsigs(SIG_BLOCK);
2137                 tcsetpgrp(G_interactive_fd, G_saved_tty_pgrp);
2138         }
2139
2140         /* Not a signal, just exit */
2141         if (sig <= 0)
2142                 _exit(- sig);
2143
2144         kill_myself_with_sig(sig); /* does not return */
2145 }
2146 #else
2147
2148 # define disable_restore_tty_pgrp_on_exit() ((void)0)
2149 # define enable_restore_tty_pgrp_on_exit()  ((void)0)
2150
2151 #endif
2152 #endif /* !__U_BOOT__ */
2153
2154 #ifndef __U_BOOT__
2155 static sighandler_t pick_sighandler(unsigned sig)
2156 {
2157         sighandler_t handler = SIG_DFL;
2158         if (sig < sizeof(unsigned)*8) {
2159                 unsigned sigmask = (1 << sig);
2160
2161 #if ENABLE_HUSH_JOB
2162                 /* is sig fatal? */
2163                 if (G_fatal_sig_mask & sigmask)
2164                         handler = sigexit;
2165                 else
2166 #endif
2167                 /* sig has special handling? */
2168                 if (G.special_sig_mask & sigmask) {
2169                         handler = record_pending_signo;
2170                         /* TTIN/TTOU/TSTP can't be set to record_pending_signo
2171                          * in order to ignore them: they will be raised
2172                          * in an endless loop when we try to do some
2173                          * terminal ioctls! We do have to _ignore_ these.
2174                          */
2175                         if (SPECIAL_JOBSTOP_SIGS & sigmask)
2176                                 handler = SIG_IGN;
2177                 }
2178         }
2179         return handler;
2180 }
2181 #endif /* !__U_BOOT__ */
2182
2183 #ifndef __U_BOOT__
2184 /* Restores tty foreground process group, and exits. */
2185 static void hush_exit(int exitcode)
2186 {
2187 #if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT
2188         save_history(G.line_input_state); /* may be NULL */
2189 #endif
2190
2191         fflush_all();
2192         if (G.exiting <= 0 && G_traps && G_traps[0] && G_traps[0][0]) {
2193                 char *argv[3];
2194                 /* argv[0] is unused */
2195                 argv[1] = xstrdup(G_traps[0]); /* copy, since EXIT trap handler may modify G_traps[0] */
2196                 argv[2] = NULL;
2197                 G.exiting = 1; /* prevent EXIT trap recursion */
2198                 /* Note: G_traps[0] is not cleared!
2199                  * "trap" will still show it, if executed
2200                  * in the handler */
2201                 builtin_eval(argv);
2202         }
2203
2204 #if ENABLE_FEATURE_CLEAN_UP
2205         {
2206                 struct variable *cur_var;
2207                 if (G.cwd != bb_msg_unknown)
2208                         free((char*)G.cwd);
2209                 cur_var = G.top_var;
2210                 while (cur_var) {
2211                         struct variable *tmp = cur_var;
2212                         if (!cur_var->max_len)
2213                                 free(cur_var->varstr);
2214                         cur_var = cur_var->next;
2215                         free(tmp);
2216                 }
2217         }
2218 #endif
2219
2220         fflush_all();
2221 #if ENABLE_HUSH_JOB
2222         sigexit(- (exitcode & 0xff));
2223 #else
2224         _exit(exitcode);
2225 #endif
2226 }
2227
2228 //TODO: return a mask of ALL handled sigs?
2229 static int check_and_run_traps(void)
2230 {
2231         int last_sig = 0;
2232
2233         while (1) {
2234                 int sig;
2235
2236                 if (sigisemptyset(&G.pending_set))
2237                         break;
2238                 sig = 0;
2239                 do {
2240                         sig++;
2241                         if (sigismember(&G.pending_set, sig)) {
2242                                 sigdelset(&G.pending_set, sig);
2243                                 goto got_sig;
2244                         }
2245                 } while (sig < NSIG);
2246                 break;
2247  got_sig:
2248 #if ENABLE_HUSH_TRAP
2249                 if (G_traps && G_traps[sig]) {
2250                         debug_printf_exec("%s: sig:%d handler:'%s'\n", __func__, sig, G.traps[sig]);
2251                         if (G_traps[sig][0]) {
2252                                 /* We have user-defined handler */
2253                                 smalluint save_rcode;
2254                                 int save_pre;
2255                                 char *argv[3];
2256                                 /* argv[0] is unused */
2257                                 argv[1] = xstrdup(G_traps[sig]);
2258                                 /* why strdup? trap can modify itself: trap 'trap "echo oops" INT' INT */
2259                                 argv[2] = NULL;
2260                                 save_pre = G.pre_trap_exitcode;
2261                                 G.pre_trap_exitcode = save_rcode = G.last_exitcode;
2262                                 builtin_eval(argv);
2263                                 free(argv[1]);
2264                                 G.pre_trap_exitcode = save_pre;
2265                                 G.last_exitcode = save_rcode;
2266 # if ENABLE_HUSH_FUNCTIONS
2267                                 if (G.return_exitcode >= 0) {
2268                                         debug_printf_exec("trap exitcode:%d\n", G.return_exitcode);
2269                                         G.last_exitcode = G.return_exitcode;
2270                                 }
2271 # endif
2272                                 last_sig = sig;
2273                         } /* else: "" trap, ignoring signal */
2274                         continue;
2275                 }
2276 #endif
2277                 /* not a trap: special action */
2278                 switch (sig) {
2279                 case SIGINT:
2280                         debug_printf_exec("%s: sig:%d default SIGINT handler\n", __func__, sig);
2281                         G.flag_SIGINT = 1;
2282                         last_sig = sig;
2283                         break;
2284 #if ENABLE_HUSH_JOB
2285                 case SIGHUP: {
2286                         /* if (G_interactive_fd) - no need to check, the handler
2287                          * is only installed if we *are* interactive */
2288                         {
2289                                 /* bash compat: "Before exiting, an interactive
2290                                  * shell resends the SIGHUP to all jobs, running
2291                                  * or stopped.  Stopped jobs are sent SIGCONT
2292                                  * to ensure that they receive the SIGHUP."
2293                                  */
2294                                 struct pipe *job;
2295                                 debug_printf_exec("%s: sig:%d default SIGHUP handler\n", __func__, sig);
2296                                 /* bash is observed to signal whole process groups,
2297                                  * not individual processes */
2298                                 for (job = G.job_list; job; job = job->next) {
2299                                         if (job->pgrp <= 0)
2300                                                 continue;
2301                                         debug_printf_exec("HUPing pgrp %d\n", job->pgrp);
2302                                         if (kill(- job->pgrp, SIGHUP) == 0)
2303                                                 kill(- job->pgrp, SIGCONT);
2304                                 }
2305                         }
2306                         /* this restores tty pgrp, then kills us with SIGHUP */
2307                         sigexit(SIGHUP);
2308                 }
2309 #endif
2310 #if ENABLE_HUSH_FAST
2311                 case SIGCHLD:
2312                         debug_printf_exec("%s: sig:%d default SIGCHLD handler\n", __func__, sig);
2313                         G.count_SIGCHLD++;
2314 //bb_error_msg("[%d] check_and_run_traps: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
2315                         /* Note:
2316                          * We don't do 'last_sig = sig' here -> NOT returning this sig.
2317                          * This simplifies wait builtin a bit.
2318                          */
2319                         break;
2320 #endif
2321                 default: /* ignored: */
2322                         debug_printf_exec("%s: sig:%d default handling is to ignore\n", __func__, sig);
2323                         /* SIGTERM, SIGQUIT, SIGTTIN, SIGTTOU, SIGTSTP */
2324                         /* Note:
2325                          * We don't do 'last_sig = sig' here -> NOT returning this sig.
2326                          * Example: wait is not interrupted by TERM
2327                          * in interactive shell, because TERM is ignored.
2328                          */
2329                         break;
2330                 }
2331         }
2332         return last_sig;
2333 }
2334
2335 static const char *get_cwd(int force)
2336 {
2337         if (force || G.cwd == NULL) {
2338                 /* xrealloc_getcwd_or_warn(arg) calls free(arg),
2339                  * we must not try to free(bb_msg_unknown) */
2340                 if (G.cwd == bb_msg_unknown)
2341                         G.cwd = NULL;
2342                 G.cwd = xrealloc_getcwd_or_warn((char *)G.cwd);
2343                 if (!G.cwd)
2344                         G.cwd = bb_msg_unknown;
2345         }
2346         return G.cwd;
2347 }
2348
2349 #endif /* !__U_BOOT__ */
2350
2351 /*
2352  * Shell and environment variable support
2353  */
2354 static struct variable **get_ptr_to_local_var(const char *name)
2355 {
2356         struct variable **pp;
2357         struct variable *cur;
2358
2359         pp = &G.top_var;
2360         while ((cur = *pp) != NULL) {
2361                 if (varcmp(cur->varstr, name) == 0)
2362                         return pp;
2363                 pp = &cur->next;
2364         }
2365         return NULL;
2366 }
2367
2368 static const char* FAST_FUNC get_local_var_value(const char *name)
2369 {
2370         struct variable **vpp;
2371
2372         if (G.expanded_assignments) {
2373                 char **cpp = G.expanded_assignments;
2374                 while (*cpp) {
2375                         char *cp = *cpp;
2376                         if (varcmp(cp, name) == 0)
2377                                 return strchr(cp, '=') + 1;
2378                         cpp++;
2379                 }
2380         }
2381
2382         vpp = get_ptr_to_local_var(name);
2383         if (vpp)
2384                 return strchr((*vpp)->varstr, '=') + 1;
2385
2386 #ifndef __U_BOOT__
2387         if (strcmp(name, "PPID") == 0)
2388                 return utoa(G.root_ppid);
2389 #endif /* !__U_BOOT__ */
2390         // bash compat: UID? EUID?
2391 #if ENABLE_HUSH_RANDOM_SUPPORT
2392         if (strcmp(name, "RANDOM") == 0)
2393                 return utoa(next_random(&G.random_gen));
2394 #endif
2395 #if ENABLE_HUSH_LINENO_VAR
2396         if (strcmp(name, "LINENO") == 0)
2397                 return utoa(G.execute_lineno);
2398 #endif
2399 #if BASH_EPOCH_VARS
2400         {
2401                 const char *fmt = NULL;
2402                 if (strcmp(name, "EPOCHSECONDS") == 0)
2403                         fmt = "%llu";
2404                 else if (strcmp(name, "EPOCHREALTIME") == 0)
2405                         fmt = "%llu.%06u";
2406                 if (fmt) {
2407                         struct timeval tv;
2408                         xgettimeofday(&tv);
2409                         sprintf(G.epoch_buf, fmt, (unsigned long long)tv.tv_sec,
2410                                         (unsigned)tv.tv_usec);
2411                         return G.epoch_buf;
2412                 }
2413         }
2414 #endif
2415         return NULL;
2416 }
2417
2418 #ifndef __U_BOOT__
2419 #if ENABLE_HUSH_GETOPTS
2420 static void handle_changed_special_names(const char *name)
2421 {
2422         if (varcmp(name, "OPTIND") == 0) {
2423                 G.getopt_count = 0;
2424                 return;
2425         }
2426 }
2427 #else
2428 /* Do not even bother evaluating arguments */
2429 # define handle_changed_special_names(...) ((void)0)
2430 #endif
2431 #else /* __U_BOOT__ */
2432 /* Do not even bother evaluating arguments */
2433 # define handle_changed_special_names(...) ((void)0)
2434 #endif /* __U_BOOT__ */
2435
2436 /* str holds "NAME=VAL" and is expected to be malloced.
2437  * We take ownership of it.
2438  */
2439 #ifndef __U_BOOT__
2440 #define SETFLAG_EXPORT   (1 << 0)
2441 #define SETFLAG_UNEXPORT (1 << 1)
2442 #define SETFLAG_MAKE_RO  (1 << 2)
2443 #endif /* !__U_BOOT__ */
2444 #define SETFLAG_VARLVL_SHIFT   3
2445 #ifndef __U_BOOT__
2446 static int set_local_var(char *str, unsigned flags)
2447 #else /* __U_BOOT__ */
2448 int set_local_var_modern(char *str, int flags)
2449 #endif /* __U_BOOT__ */
2450 {
2451         struct variable **cur_pp;
2452         struct variable *cur;
2453         char *free_me = NULL;
2454         char *eq_sign;
2455         int name_len;
2456         int retval;
2457 #ifndef __U_BOOT__
2458         unsigned local_lvl = (flags >> SETFLAG_VARLVL_SHIFT);
2459 #endif /* !__U_BOOT__ */
2460
2461         eq_sign = strchr(str, '=');
2462         if (HUSH_DEBUG && !eq_sign)
2463                 bb_simple_error_msg_and_die("BUG in setvar");
2464
2465         name_len = eq_sign - str + 1; /* including '=' */
2466         cur_pp = &G.top_var;
2467         while ((cur = *cur_pp) != NULL) {
2468                 if (strncmp(cur->varstr, str, name_len) != 0) {
2469                         cur_pp = &cur->next;
2470                         continue;
2471                 }
2472
2473 #ifndef __U_BOOT__
2474                 /* We found an existing var with this name */
2475                 if (cur->flg_read_only) {
2476                         bb_error_msg("%s: readonly variable", str);
2477                         free(str);
2478 //NOTE: in bash, assignment in "export READONLY_VAR=Z" fails, and sets $?=1,
2479 //but export per se succeeds (does put the var in env). We don't mimic that.
2480                         return -1;
2481                 }
2482                 if (flags & SETFLAG_UNEXPORT) { // && cur->flg_export ?
2483                         debug_printf_env("%s: unsetenv '%s'\n", __func__, str);
2484                         *eq_sign = '\0';
2485                         unsetenv(str);
2486                         *eq_sign = '=';
2487                 }
2488                 if (cur->var_nest_level < local_lvl) {
2489                         /* bash 3.2.33(1) and exported vars:
2490                          * # export z=z
2491                          * # f() { local z=a; env | grep ^z; }
2492                          * # f
2493                          * z=a
2494                          * # env | grep ^z
2495                          * z=z
2496                          */
2497                         if (cur->flg_export)
2498                                 flags |= SETFLAG_EXPORT;
2499                         /* New variable is local ("local VAR=VAL" or
2500                          * "VAR=VAL cmd")
2501                          * and existing one is global, or local
2502                          * on a lower level that new one.
2503                          * Remove it from global variable list:
2504                          */
2505                         *cur_pp = cur->next;
2506                         if (G.shadowed_vars_pp) {
2507                                 /* Save in "shadowed" list */
2508                                 debug_printf_env("shadowing %s'%s'/%u by '%s'/%u\n",
2509                                         cur->flg_export ? "exported " : "",
2510                                         cur->varstr, cur->var_nest_level, str, local_lvl
2511                                 );
2512                                 cur->next = *G.shadowed_vars_pp;
2513                                 *G.shadowed_vars_pp = cur;
2514                         } else {
2515                                 /* Came from pseudo_exec_argv(), no need to save: delete it */
2516                                 debug_printf_env("shadow-deleting %s'%s'/%u by '%s'/%u\n",
2517                                         cur->flg_export ? "exported " : "",
2518                                         cur->varstr, cur->var_nest_level, str, local_lvl
2519                                 );
2520                                 if (cur->max_len == 0) /* allocated "VAR=VAL"? */
2521                                         free_me = cur->varstr; /* then free it later */
2522                                 free(cur);
2523                         }
2524                         break;
2525                 }
2526 #endif /* !__U_BOOT__ */
2527
2528                 if (strcmp(cur->varstr + name_len, eq_sign + 1) == 0) {
2529                         debug_printf_env("assignement '%s' does not change anything\n", str);
2530  free_and_exp:
2531                         free(str);
2532                         goto exp;
2533                 }
2534
2535                 /* Replace the value in the found "struct variable" */
2536                 if (cur->max_len != 0) {
2537                         if (cur->max_len >= strnlen(str, cur->max_len + 1)) {
2538                                 /* This one is from startup env, reuse space */
2539                                 debug_printf_env("reusing startup env for '%s'\n", str);
2540                                 strcpy(cur->varstr, str);
2541                                 goto free_and_exp;
2542                         }
2543                         /* Can't reuse */
2544                         cur->max_len = 0;
2545                         goto set_str_and_exp;
2546                 }
2547                 /* max_len == 0 signifies "malloced" var, which we can
2548                  * (and have to) free. But we can't free(cur->varstr) here:
2549                  * if cur->flg_export is 1, it is in the environment.
2550                  * We should either unsetenv+free, or wait until putenv,
2551                  * then putenv(new)+free(old).
2552                  */
2553                 free_me = cur->varstr;
2554                 goto set_str_and_exp;
2555         }
2556
2557         /* Not found or shadowed - create new variable struct */
2558 #ifndef __U_BOOT__
2559         debug_printf_env("%s: alloc new var '%s'/%u\n", __func__, str, local_lvl);
2560 #else /* __U_BOOT__ */
2561         debug_printf_env("%s: alloc new var '%s'\n", __func__, str);
2562 #endif /* __U_BOOT__ */
2563         cur = xzalloc(sizeof(*cur));
2564 #ifndef __U_BOOT__
2565         cur->var_nest_level = local_lvl;
2566 #endif /* !__U_BOOT__ */
2567         cur->next = *cur_pp;
2568         *cur_pp = cur;
2569
2570  set_str_and_exp:
2571         cur->varstr = str;
2572  exp:
2573 #ifndef __U_BOOT__
2574 #if !BB_MMU || ENABLE_HUSH_READONLY
2575         if (flags & SETFLAG_MAKE_RO) {
2576                 cur->flg_read_only = 1;
2577         }
2578 #endif
2579         if (flags & SETFLAG_EXPORT)
2580                 cur->flg_export = 1;
2581 #endif /* !__U_BOOT__ */
2582         retval = 0;
2583 #ifndef __U_BOOT__
2584         if (cur->flg_export) {
2585                 if (flags & SETFLAG_UNEXPORT) {
2586                         cur->flg_export = 0;
2587                         /* unsetenv was already done */
2588                 } else {
2589                         debug_printf_env("%s: putenv '%s'/%u\n", __func__, cur->varstr, cur->var_nest_level);
2590                         retval = putenv(cur->varstr);
2591                         /* fall through to "free(free_me)" -
2592                          * only now we can free old exported malloced string
2593                          */
2594                 }
2595         }
2596 #endif /* !__U_BOOT__ */
2597         free(free_me);
2598
2599         handle_changed_special_names(cur->varstr);
2600
2601         return retval;
2602 }
2603
2604 #ifndef __U_BOOT__
2605 static int set_local_var0(char *str)
2606 {
2607         return set_local_var(str, 0);
2608 }
2609
2610 static void FAST_FUNC set_local_var_from_halves(const char *name, const char *val)
2611 {
2612         char *var = xasprintf("%s=%s", name, val);
2613         set_local_var0(var);
2614 }
2615
2616 /* Used at startup and after each cd */
2617 static void set_pwd_var(unsigned flag)
2618 {
2619         set_local_var(xasprintf("PWD=%s", get_cwd(/*force:*/ 1)), flag);
2620 }
2621 #endif /* !__U_BOOT__ */
2622
2623 #if ENABLE_HUSH_UNSET || ENABLE_HUSH_GETOPTS
2624 static int unset_local_var(const char *name)
2625 {
2626         struct variable *cur;
2627         struct variable **cur_pp;
2628
2629         cur_pp = &G.top_var;
2630         while ((cur = *cur_pp) != NULL) {
2631                 if (varcmp(cur->varstr, name) == 0) {
2632                         if (cur->flg_read_only) {
2633                                 bb_error_msg("%s: readonly variable", name);
2634                                 return EXIT_FAILURE;
2635                         }
2636
2637                         *cur_pp = cur->next;
2638                         debug_printf_env("%s: unsetenv '%s'\n", __func__, cur->varstr);
2639                         bb_unsetenv(cur->varstr);
2640                         if (!cur->max_len)
2641                                 free(cur->varstr);
2642                         free(cur);
2643
2644                         break;
2645                 }
2646                 cur_pp = &cur->next;
2647         }
2648
2649         /* Handle "unset LINENO" et al even if did not find the variable to unset */
2650         handle_changed_special_names(name);
2651
2652         return EXIT_SUCCESS;
2653 }
2654 #endif
2655
2656 #ifndef __U_BOOT__
2657 /*
2658  * Helpers for "var1=val1 var2=val2 cmd" feature
2659  */
2660 static void add_vars(struct variable *var)
2661 {
2662         struct variable *next;
2663
2664         while (var) {
2665                 next = var->next;
2666                 var->next = G.top_var;
2667                 G.top_var = var;
2668                 if (var->flg_export) {
2669                         debug_printf_env("%s: restoring exported '%s'/%u\n", __func__, var->varstr, var->var_nest_level);
2670                         putenv(var->varstr);
2671                 } else {
2672                         debug_printf_env("%s: restoring variable '%s'/%u\n", __func__, var->varstr, var->var_nest_level);
2673                 }
2674                 var = next;
2675         }
2676 }
2677
2678 /* We put strings[i] into variable table and possibly putenv them.
2679  * If variable is read only, we can free the strings[i]
2680  * which attempts to overwrite it.
2681  * The strings[] vector itself is freed.
2682  */
2683 static void set_vars_and_save_old(char **strings)
2684 {
2685         char **s;
2686
2687         if (!strings)
2688                 return;
2689
2690         s = strings;
2691         while (*s) {
2692                 struct variable *var_p;
2693                 struct variable **var_pp;
2694                 char *eq;
2695
2696                 eq = strchr(*s, '=');
2697                 if (HUSH_DEBUG && !eq)
2698                         bb_simple_error_msg_and_die("BUG in varexp4");
2699                 var_pp = get_ptr_to_local_var(*s);
2700                 if (var_pp) {
2701                         var_p = *var_pp;
2702                         if (var_p->flg_read_only) {
2703                                 char **p;
2704                                 bb_error_msg("%s: readonly variable", *s);
2705                                 /*
2706                                  * "VAR=V BLTIN" unsets VARs after BLTIN completes.
2707                                  * If VAR is readonly, leaving it in the list
2708                                  * after asssignment error (msg above)
2709                                  * causes doubled error message later, on unset.
2710                                  */
2711                                 debug_printf_env("removing/freeing '%s' element\n", *s);
2712                                 free(*s);
2713                                 p = s;
2714                                 do { *p = p[1]; p++; } while (*p);
2715                                 goto next;
2716                         }
2717                         /* below, set_local_var() with nest level will
2718                          * "shadow" (remove) this variable from
2719                          * global linked list.
2720                          */
2721                 }
2722                 debug_printf_env("%s: env override '%s'/%u\n", __func__, *s, G.var_nest_level);
2723                 set_local_var(*s, (G.var_nest_level << SETFLAG_VARLVL_SHIFT) | SETFLAG_EXPORT);
2724                 s++;
2725  next: ;
2726         }
2727         free(strings);
2728 }
2729
2730 /*
2731  * Unicode helper
2732  */
2733 static void reinit_unicode_for_hush(void)
2734 {
2735         /* Unicode support should be activated even if LANG is set
2736          * _during_ shell execution, not only if it was set when
2737          * shell was started. Therefore, re-check LANG every time:
2738          */
2739         if (ENABLE_FEATURE_CHECK_UNICODE_IN_ENV
2740          || ENABLE_UNICODE_USING_LOCALE
2741         ) {
2742                 const char *s = get_local_var_value("LC_ALL");
2743                 if (!s) s = get_local_var_value("LC_CTYPE");
2744                 if (!s) s = get_local_var_value("LANG");
2745                 reinit_unicode(s);
2746         }
2747 }
2748
2749 #endif /* !__U_BOOT__ */
2750 /*
2751  * in_str support (strings, and "strings" read from files).
2752  */
2753
2754 #if ENABLE_HUSH_INTERACTIVE
2755 #ifndef __U_BOOT__
2756 /* To test correct lineedit/interactive behavior, type from command line:
2757  *      echo $P\
2758  *      \
2759  *      AT\
2760  *      H\
2761  *      \
2762  * It exercises a lot of corner cases.
2763  */
2764 static const char *setup_prompt_string(void)
2765 {
2766         const char *prompt_str;
2767
2768         debug_printf_prompt("%s promptmode:%d\n", __func__, G.promptmode);
2769
2770 # if ENABLE_FEATURE_EDITING_FANCY_PROMPT
2771         prompt_str = get_local_var_value(G.promptmode == 0 ? "PS1" : "PS2");
2772         if (!prompt_str)
2773                 prompt_str = "";
2774 # else
2775         prompt_str = "> "; /* if PS2, else... */
2776         if (G.promptmode == 0) { /* PS1 */
2777                 /* No fancy prompts supported, (re)generate "CURDIR $ " by hand */
2778                 free(G.PS1);
2779                 /* bash uses $PWD value, even if it is set by user.
2780                  * It uses current dir only if PWD is unset.
2781                  * We always use current dir. */
2782                 prompt_str = G.PS1 = xasprintf("%s %c ", get_cwd(0), (geteuid() != 0) ? '$' : '#');
2783         }
2784 # endif
2785         debug_printf("prompt_str '%s'\n", prompt_str);
2786         return prompt_str;
2787 }
2788 #endif /* !__U_BOOT__ */
2789
2790 #ifndef __U_BOOT__
2791 static int get_user_input(struct in_str *i)
2792 #else /* __U_BOOT__ */
2793 static void get_user_input(struct in_str *i)
2794 #endif /* __U_BOOT__ */
2795 {
2796 #ifndef __U_BOOT__
2797 # if ENABLE_FEATURE_EDITING
2798         /* In EDITING case, this function reads next input line,
2799          * saves it in i->p, then returns 1st char of it.
2800          */
2801         int r;
2802         const char *prompt_str;
2803
2804         prompt_str = setup_prompt_string();
2805         for (;;) {
2806                 reinit_unicode_for_hush();
2807                 G.flag_SIGINT = 0;
2808
2809                 bb_got_signal = 0;
2810                 if (!sigisemptyset(&G.pending_set)) {
2811                         /* Whoops, already got a signal, do not call read_line_input */
2812                         bb_got_signal = r = -1;
2813                 } else {
2814                         /* For shell, LI_INTERRUPTIBLE is set:
2815                          * read_line_input will abort on either
2816                          * getting EINTR in poll() and bb_got_signal became != 0,
2817                          * or if it sees bb_got_signal != 0
2818                          * (IOW: if signal arrives before poll() is reached).
2819                          * Interactive testcases:
2820                          * (while kill -INT $$; do sleep 1; done) &
2821                          * #^^^ prints ^C, prints prompt, repeats
2822                          * trap 'echo I' int; (while kill -INT $$; do sleep 1; done) &
2823                          * #^^^ prints ^C, prints "I", prints prompt, repeats
2824                          * trap 'echo T' term; (while kill $$; do sleep 1; done) &
2825                          * #^^^ prints "T", prints prompt, repeats
2826                          * #(bash 5.0.17 exits after first "T", looks like a bug)
2827                          */
2828                         r = read_line_input(G.line_input_state, prompt_str,
2829                                 G.user_input_buf, CONFIG_FEATURE_EDITING_MAX_LEN-1
2830                         );
2831                         /* read_line_input intercepts ^C, "convert" it to SIGINT */
2832                         if (r == 0)
2833                                 raise(SIGINT);
2834                 }
2835                 /* bash prints ^C (before running a trap, if any)
2836                  * both on keyboard ^C and on real SIGINT (non-kbd generated).
2837                  */
2838                 if (sigismember(&G.pending_set, SIGINT)) {
2839                         write(STDOUT_FILENO, "^C\n", 3);
2840                         G.last_exitcode = 128 | SIGINT;
2841                 }
2842                 check_and_run_traps();
2843                 if (r == 0) /* keyboard ^C? */
2844                         continue; /* go back, read another input line */
2845                 if (r > 0) /* normal input? (no ^C, no ^D, no signals) */
2846                         break;
2847                 if (!bb_got_signal) {
2848                         /* r < 0: ^D/EOF/error detected (but not signal) */
2849                         /* ^D on interactive input goes to next line before exiting: */
2850                         write(STDOUT_FILENO, "\n", 1);
2851                         i->p = NULL;
2852                         i->peek_buf[0] = r = EOF;
2853                         return r;
2854                 }
2855                 /* it was a signal: go back, read another input line */
2856         }
2857         i->p = G.user_input_buf;
2858         return (unsigned char)*i->p++;
2859 # else
2860         /* In !EDITING case, this function gets called for every char.
2861          * Buffering happens deeper in the call chain, in hfgetc(i->file).
2862          */
2863         int r;
2864
2865         for (;;) {
2866                 G.flag_SIGINT = 0;
2867                 if (i->last_char == '\0' || i->last_char == '\n') {
2868                         const char *prompt_str = setup_prompt_string();
2869                         /* Why check_and_run_traps here? Try this interactively:
2870                          * $ trap 'echo INT' INT; (sleep 2; kill -INT $$) &
2871                          * $ <[enter], repeatedly...>
2872                          * Without check_and_run_traps, handler never runs.
2873                          */
2874                         check_and_run_traps();
2875                         fputs_stdout(prompt_str);
2876                         fflush_all();
2877                 }
2878                 r = hfgetc(i->file);
2879                 /* In !ENABLE_FEATURE_EDITING we don't use read_line_input,
2880                  * no ^C masking happens during fgetc, no special code for ^C:
2881                  * it generates SIGINT as usual.
2882                  */
2883                 check_and_run_traps();
2884                 if (r != '\0' && !G.flag_SIGINT)
2885                         break;
2886                 if (G.flag_SIGINT) {
2887                         /* ^C or SIGINT: repeat */
2888                         /* bash prints ^C even on real SIGINT (non-kbd generated) */
2889                         /* kernel prints "^C" itself, just print newline: */
2890                         write(STDOUT_FILENO, "\n", 1);
2891                         G.last_exitcode = 128 | SIGINT;
2892                 }
2893         }
2894         return r;
2895 # endif
2896 #else /* __U_BOOT__ */
2897         int n;
2898         int promptme;
2899         static char the_command[CONFIG_SYS_CBSIZE + 1];
2900
2901         bootretry_reset_cmd_timeout();
2902         promptme = 1;
2903         n = u_boot_cli_readline(i);
2904
2905 # ifdef CONFIG_BOOT_RETRY_TIME
2906         if (n == -2) {
2907                 puts("\nTimeout waiting for command\n");
2908 #  ifdef CONFIG_RESET_TO_RETRY
2909                 do_reset(NULL, 0, 0, NULL);
2910 #  else
2911 #       error "This currently only works with CONFIG_RESET_TO_RETRY enabled"
2912 #  endif
2913         }
2914 # endif
2915         if (n == -1 ) {
2916                 G.flag_repeat = 0;
2917                 promptme = 0;
2918         }
2919         n = strlen(console_buffer);
2920         console_buffer[n] = '\n';
2921         console_buffer[n+1]= '\0';
2922         if (had_ctrlc())
2923                 G.flag_repeat = 0;
2924         clear_ctrlc();
2925         G.do_repeat = 0;
2926 #ifndef __U_BOOT__
2927         if (G.promptmode == 1) {
2928 #else /* __U_BOOT__ */
2929         if (!G.promptmode) {
2930 #endif /* __U_BOOT__ */
2931                 if (console_buffer[0] == '\n'&& G.flag_repeat == 0) {
2932                         strcpy(the_command, console_buffer);
2933                 }
2934                 else {
2935                         if (console_buffer[0] != '\n') {
2936                                 strcpy(the_command, console_buffer);
2937                                 G.flag_repeat = 1;
2938                         }
2939                         else {
2940                                 G.do_repeat = 1;
2941                         }
2942                 }
2943                 i->p = the_command;
2944         }
2945         else {
2946                 if (console_buffer[0] != '\n') {
2947                         if (strlen(the_command) + strlen(console_buffer)
2948                                 < CONFIG_SYS_CBSIZE) {
2949                                 n = strlen(the_command);
2950 #ifdef __U_BOOT__
2951                                 /*
2952                                  * To avoid writing to bad places, we check if
2953                                  * n is greater than 0.
2954                                  * This bug was found by Harald Seiler.
2955                                  */
2956                                 if (n > 0)
2957                                         the_command[n-1] = ' ';
2958                                 strcpy(&the_command[n], console_buffer);
2959 #else /* !__U_BOOT__ */
2960                         the_command[n-1] = ' ';
2961                         strcpy(&the_command[n], console_buffer);
2962 #endif /* !__U_BOOT__ */
2963                                 }
2964                                 else {
2965                                         the_command[0] = '\n';
2966                                         the_command[1] = '\0';
2967                                         G.flag_repeat = 0;
2968                                 }
2969                 }
2970                 if (promptme == 0) {
2971                         the_command[0] = '\n';
2972                         the_command[1] = '\0';
2973                 }
2974                 i->p = console_buffer;
2975         }
2976 #endif /* __U_BOOT__ */
2977 }
2978 /* This is the magic location that prints prompts
2979  * and gets data back from the user */
2980 static int fgetc_interactive(struct in_str *i)
2981 {
2982         int ch;
2983 #ifndef __U_BOOT__
2984         /* If it's interactive stdin, get new line. */
2985         if (G_interactive_fd && i->file == G.HFILE_stdin) {
2986 #endif /* !__U_BOOT__ */
2987 #ifndef __U_BOOT__
2988                 /* Returns first char (or EOF), the rest is in i->p[] */
2989                 ch = get_user_input(i);
2990 #else /* __U_BOOT__ */
2991                 /* Avoid garbage value and make clang happy. */
2992                 ch = 0;
2993                 /*
2994                  * get_user_input() does not return anything when used in
2995                  * U-Boot.
2996                  * So, we need to take the read character from i->p[].
2997                  */
2998                 get_user_input(i);
2999                 if (i->p && *i->p) {
3000                         ch = *i->p++;
3001                 }
3002 #endif /* __U_BOOT__ */
3003                 G.promptmode = 1; /* PS2 */
3004                 debug_printf_prompt("%s promptmode=%d\n", __func__, G.promptmode);
3005 #ifndef __U_BOOT__
3006         } else {
3007                 /* Not stdin: script file, sourced file, etc */
3008                 do ch = hfgetc(i->file); while (ch == '\0');
3009         }
3010 #endif /* !__U_BOOT__ */
3011         return ch;
3012 }
3013 #else  /* !INTERACTIVE */
3014 #ifndef __U_BOOT__
3015 static ALWAYS_INLINE int fgetc_interactive(struct in_str *i)
3016 {
3017         int ch;
3018         do ch = hfgetc(i->file); while (ch == '\0');
3019         return ch;
3020 }
3021 #endif /* !__U_BOOT__ */
3022 #endif  /* !INTERACTIVE */
3023
3024 static int i_getch(struct in_str *i)
3025 {
3026         int ch;
3027
3028 #ifndef __U_BOOT__
3029         if (!i->file) {
3030                 /* string-based in_str */
3031                 ch = (unsigned char)*i->p;
3032                 if (ch != '\0') {
3033                         i->p++;
3034                         i->last_char = ch;
3035 #if ENABLE_HUSH_LINENO_VAR
3036                         if (ch == '\n') {
3037                                 G.parse_lineno++;
3038                                 debug_printf_parse("G.parse_lineno++ = %u\n", G.parse_lineno);
3039                         }
3040 #endif
3041                         return ch;
3042                 }
3043                 return EOF;
3044         }
3045
3046 #endif /* !__U_BOOT__ */
3047         /* FILE-based in_str */
3048
3049 #if ENABLE_FEATURE_EDITING
3050         /* This can be stdin, check line editing char[] buffer */
3051         if (i->p && *i->p != '\0') {
3052                 ch = (unsigned char)*i->p++;
3053                 goto out;
3054 #ifndef __U_BOOT__
3055         }
3056 #else /* __U_BOOT__ */
3057         /*
3058          * There are two ways for command to be called:
3059          * 1. The first one is when they are typed by the user.
3060          * 2. The second one is through run_command() (NOTE command run
3061          * internally calls run_command()).
3062          *
3063          * In the second case, we do not get input from the user, so once we
3064          * get a '\0', it means we need to stop.
3065          * NOTE G.run_command_flags is only set on run_command call stack, so
3066          * we use this to know if we come from user input or run_command().
3067          */
3068         } else if (i->p && *i->p == '\0' && G.run_command_flags){
3069                 return EOF;
3070         }
3071 #endif /* __U_BOOT__ */
3072 #endif
3073 #ifndef __U_BOOT__
3074         /* peek_buf[] is an int array, not char. Can contain EOF. */
3075         ch = i->peek_buf[0];
3076         if (ch != 0) {
3077                 int ch2 = i->peek_buf[1];
3078                 i->peek_buf[0] = ch2;
3079                 if (ch2 == 0) /* very likely, avoid redundant write */
3080                         goto out;
3081                 i->peek_buf[1] = 0;
3082                 goto out;
3083         }
3084
3085 #endif /* !__U_BOOT__ */
3086         ch = fgetc_interactive(i);
3087  out:
3088         debug_printf("file_get: got '%c' %d\n", ch, ch);
3089         i->last_char = ch;
3090 #if ENABLE_HUSH_LINENO_VAR
3091         if (ch == '\n') {
3092                 G.parse_lineno++;
3093                 debug_printf_parse("G.parse_lineno++ = %u\n", G.parse_lineno);
3094         }
3095 #endif
3096         return ch;
3097 }
3098
3099 static int i_peek(struct in_str *i)
3100 {
3101 #ifndef __U_BOOT__
3102         int ch;
3103
3104         if (!i->file) {
3105                 /* string-based in_str */
3106                 /* Doesn't report EOF on NUL. None of the callers care. */
3107                 return (unsigned char)*i->p;
3108         }
3109
3110         /* FILE-based in_str */
3111
3112 #if ENABLE_FEATURE_EDITING && ENABLE_HUSH_INTERACTIVE
3113         /* This can be stdin, check line editing char[] buffer */
3114         if (i->p && *i->p != '\0')
3115                 return (unsigned char)*i->p;
3116 #endif
3117         /* peek_buf[] is an int array, not char. Can contain EOF. */
3118         ch = i->peek_buf[0];
3119         if (ch != 0)
3120                 return ch;
3121
3122         /* Need to get a new char */
3123         ch = fgetc_interactive(i);
3124         debug_printf("file_peek: got '%c' %d\n", ch, ch);
3125
3126         /* Save it by either rolling back line editing buffer, or in i->peek_buf[0] */
3127 #if ENABLE_FEATURE_EDITING && ENABLE_HUSH_INTERACTIVE
3128         if (i->p) {
3129                 i->p -= 1;
3130                 return ch;
3131         }
3132 #endif
3133         i->peek_buf[0] = ch;
3134         /*i->peek_buf[1] = 0; - already is */
3135         return ch;
3136 #else /* __U_BOOT__ */
3137         /* string-based in_str */
3138         /* Doesn't report EOF on NUL. None of the callers care. */
3139         return (unsigned char)*i->p;
3140 #endif /* __U_BOOT__ */
3141 }
3142
3143 /* Only ever called if i_peek() was called, and did not return EOF.
3144  * IOW: we know the previous peek saw an ordinary char, not EOF, not NUL,
3145  * not end-of-line. Therefore we never need to read a new editing line here.
3146  */
3147 static int i_peek2(struct in_str *i)
3148 {
3149 #ifndef __U_BOOT__
3150         int ch;
3151 #endif /* !__U_BOOT__ */
3152
3153         /* There are two cases when i->p[] buffer exists.
3154          * (1) it's a string in_str.
3155          * (2) It's a file, and we have a saved line editing buffer.
3156          * In both cases, we know that i->p[0] exists and not NUL, and
3157          * the peek2 result is in i->p[1].
3158          */
3159         if (i->p)
3160                 return (unsigned char)i->p[1];
3161
3162 #ifndef __U_BOOT__
3163         /* Now we know it is a file-based in_str. */
3164
3165         /* peek_buf[] is an int array, not char. Can contain EOF. */
3166         /* Is there 2nd char? */
3167         ch = i->peek_buf[1];
3168         if (ch == 0) {
3169                 /* We did not read it yet, get it now */
3170                 do ch = hfgetc(i->file); while (ch == '\0');
3171                 i->peek_buf[1] = ch;
3172         }
3173
3174         debug_printf("file_peek2: got '%c' %d\n", ch, ch);
3175         return ch;
3176 #else
3177         return 0;
3178 #endif /* __U_BOOT__ */
3179 }
3180
3181 static int i_getch_and_eat_bkslash_nl(struct in_str *input)
3182 {
3183         for (;;) {
3184                 int ch, ch2;
3185
3186                 ch = i_getch(input);
3187                 if (ch != '\\')
3188                         return ch;
3189                 ch2 = i_peek(input);
3190                 if (ch2 != '\n')
3191                         return ch;
3192                 /* backslash+newline, skip it */
3193                 i_getch(input);
3194         }
3195 }
3196
3197 /* Note: this function _eats_ \<newline> pairs, safe to use plain
3198  * i_getch() after it instead of i_getch_and_eat_bkslash_nl().
3199  */
3200 static int i_peek_and_eat_bkslash_nl(struct in_str *input)
3201 {
3202         for (;;) {
3203                 int ch, ch2;
3204
3205                 ch = i_peek(input);
3206                 if (ch != '\\')
3207                         return ch;
3208                 ch2 = i_peek2(input);
3209                 if (ch2 != '\n')
3210                         return ch;
3211                 /* backslash+newline, skip it */
3212                 i_getch(input);
3213                 i_getch(input);
3214         }
3215 }
3216
3217 #ifndef __U_BOOT__
3218 static void setup_file_in_str(struct in_str *i, HFILE *fp)
3219 #else /* __U_BOOT__ */
3220 static void setup_file_in_str(struct in_str *i)
3221 #endif /* __U_BOOT__ */
3222 {
3223         memset(i, 0, sizeof(*i));
3224 #ifndef __U_BOOT__
3225         i->file = fp;
3226         /* i->p = NULL; */
3227 #endif /* !__U_BOOT__ */
3228 }
3229
3230 static void setup_string_in_str(struct in_str *i, const char *s)
3231 {
3232         memset(i, 0, sizeof(*i));
3233         /*i->file = NULL */;
3234         i->p = s;
3235 }
3236
3237 /*
3238  * o_string support
3239  */
3240 #define B_CHUNK  (32 * sizeof(char*))
3241
3242 static void o_reset_to_empty_unquoted(o_string *o)
3243 {
3244         o->length = 0;
3245         o->has_quoted_part = 0;
3246         if (o->data)
3247                 o->data[0] = '\0';
3248 }
3249
3250 static void o_free_and_set_NULL(o_string *o)
3251 {
3252         free(o->data);
3253         memset(o, 0, sizeof(*o));
3254 }
3255
3256 static ALWAYS_INLINE void o_free(o_string *o)
3257 {
3258         free(o->data);
3259 }
3260
3261 static void o_grow_by(o_string *o, int len)
3262 {
3263         if (o->length + len > o->maxlen) {
3264                 o->maxlen += (2 * len) | (B_CHUNK-1);
3265                 o->data = xrealloc(o->data, 1 + o->maxlen);
3266         }
3267 }
3268
3269 static void o_addchr(o_string *o, int ch)
3270 {
3271         debug_printf("o_addchr: '%c' o->length=%d o=%p\n", ch, o->length, o);
3272         if (o->length < o->maxlen) {
3273                 /* likely. avoid o_grow_by() call */
3274  add:
3275                 o->data[o->length] = ch;
3276                 o->length++;
3277                 o->data[o->length] = '\0';
3278                 return;
3279         }
3280         o_grow_by(o, 1);
3281         goto add;
3282 }
3283
3284 #if 0
3285 /* Valid only if we know o_string is not empty */
3286 static void o_delchr(o_string *o)
3287 {
3288         o->length--;
3289         o->data[o->length] = '\0';
3290 }
3291 #endif
3292
3293 static void o_addblock(o_string *o, const char *str, int len)
3294 {
3295         o_grow_by(o, len);
3296         ((char*)mempcpy(&o->data[o->length], str, len))[0] = '\0';
3297         o->length += len;
3298 }
3299
3300 static void o_addstr(o_string *o, const char *str)
3301 {
3302         o_addblock(o, str, strlen(str));
3303 }
3304
3305 #ifndef __U_BOOT__
3306 static void o_addstr_with_NUL(o_string *o, const char *str)
3307 {
3308         o_addblock(o, str, strlen(str) + 1);
3309 }
3310 #endif /* !__U_BOOT__ */
3311
3312 #if !BB_MMU
3313 static void nommu_addchr(o_string *o, int ch)
3314 {
3315         if (o)
3316                 o_addchr(o, ch);
3317 }
3318 #else
3319 # define nommu_addchr(o, str) ((void)0)
3320 #endif
3321
3322 #ifndef __U_BOOT__
3323 #if ENABLE_HUSH_MODE_X
3324 static void x_mode_addchr(int ch)
3325 {
3326         o_addchr(&G.x_mode_buf, ch);
3327 }
3328 static void x_mode_addstr(const char *str)
3329 {
3330         o_addstr(&G.x_mode_buf, str);
3331 }
3332 static void x_mode_addblock(const char *str, int len)
3333 {
3334         o_addblock(&G.x_mode_buf, str, len);
3335 }
3336 static void x_mode_prefix(void)
3337 {
3338         int n = G.x_mode_depth;
3339         do x_mode_addchr('+'); while (--n >= 0);
3340 }
3341 static void x_mode_flush(void)
3342 {
3343         int len = G.x_mode_buf.length;
3344         if (len <= 0)
3345                 return;
3346         if (G.x_mode_fd > 0) {
3347                 G.x_mode_buf.data[len] = '\n';
3348                 full_write(G.x_mode_fd, G.x_mode_buf.data, len + 1);
3349         }
3350         G.x_mode_buf.length = 0;
3351 }
3352 #endif
3353 #endif /* !__U_BOOT__ */
3354
3355 /*
3356  * HUSH_BRACE_EXPANSION code needs corresponding quoting on variable expansion side.
3357  * Currently, "v='{q,w}'; echo $v" erroneously expands braces in $v.
3358  * Apparently, on unquoted $v bash still does globbing
3359  * ("v='*.txt'; echo $v" prints all .txt files),
3360  * but NOT brace expansion! Thus, there should be TWO independent
3361  * quoting mechanisms on $v expansion side: one protects
3362  * $v from brace expansion, and other additionally protects "$v" against globbing.
3363  * We have only second one.
3364  */
3365
3366 #if ENABLE_HUSH_BRACE_EXPANSION
3367 # define MAYBE_BRACES "{}"
3368 #else
3369 # define MAYBE_BRACES ""
3370 #endif
3371
3372 /* My analysis of quoting semantics tells me that state information
3373  * is associated with a destination, not a source.
3374  */
3375 static void o_addqchr(o_string *o, int ch)
3376 {
3377         int sz = 1;
3378         /* '-' is included because of this case:
3379          * >filename0 >filename1 >filename9; v='-'; echo filename[0"$v"9]
3380          */
3381         char *found = strchr("*?[-\\" MAYBE_BRACES, ch);
3382         if (found)
3383                 sz++;
3384         o_grow_by(o, sz);
3385         if (found) {
3386                 o->data[o->length] = '\\';
3387                 o->length++;
3388         }
3389         o->data[o->length] = ch;
3390         o->length++;
3391         o->data[o->length] = '\0';
3392 }
3393
3394 static void o_addQchr(o_string *o, int ch)
3395 {
3396         int sz = 1;
3397         if ((o->o_expflags & EXP_FLAG_ESC_GLOB_CHARS)
3398          && strchr("*?[-\\" MAYBE_BRACES, ch)
3399         ) {
3400                 sz++;
3401                 o->data[o->length] = '\\';
3402                 o->length++;
3403         }
3404         o_grow_by(o, sz);
3405         o->data[o->length] = ch;
3406         o->length++;
3407         o->data[o->length] = '\0';
3408 }
3409
3410 static void o_addqblock(o_string *o, const char *str, int len)
3411 {
3412         while (len) {
3413                 char ch;
3414                 int sz;
3415                 int ordinary_cnt = strcspn(str, "*?[-\\" MAYBE_BRACES);
3416                 if (ordinary_cnt > len) /* paranoia */
3417                         ordinary_cnt = len;
3418                 o_addblock(o, str, ordinary_cnt);
3419                 if (ordinary_cnt == len)
3420                         return; /* NUL is already added by o_addblock */
3421                 str += ordinary_cnt;
3422                 len -= ordinary_cnt + 1; /* we are processing + 1 char below */
3423
3424                 ch = *str++;
3425                 sz = 1;
3426                 if (ch) { /* it is necessarily one of "*?[-\\" MAYBE_BRACES */
3427                         sz++;
3428                         o->data[o->length] = '\\';
3429                         o->length++;
3430                 }
3431                 o_grow_by(o, sz);
3432                 o->data[o->length] = ch;
3433                 o->length++;
3434         }
3435         o->data[o->length] = '\0';
3436 }
3437
3438 static void o_addQblock(o_string *o, const char *str, int len)
3439 {
3440         if (!(o->o_expflags & EXP_FLAG_ESC_GLOB_CHARS)) {
3441                 o_addblock(o, str, len);
3442                 return;
3443         }
3444         o_addqblock(o, str, len);
3445 }
3446
3447 static void o_addQstr(o_string *o, const char *str)
3448 {
3449         o_addQblock(o, str, strlen(str));
3450 }
3451
3452 /* A special kind of o_string for $VAR and `cmd` expansion.
3453  * It contains char* list[] at the beginning, which is grown in 16 element
3454  * increments. Actual string data starts at the next multiple of 16 * (char*).
3455  * list[i] contains an INDEX (int!) into this string data.
3456  * It means that if list[] needs to grow, data needs to be moved higher up
3457  * but list[i]'s need not be modified.
3458  * NB: remembering how many list[i]'s you have there is crucial.
3459  * o_finalize_list() operation post-processes this structure - calculates
3460  * and stores actual char* ptrs in list[]. Oh, it NULL terminates it as well.
3461  */
3462 #if DEBUG_EXPAND || DEBUG_GLOB
3463 static void debug_print_list(const char *prefix, o_string *o, int n)
3464 {
3465         char **list = (char**)o->data;
3466         int string_start = ((n + 0xf) & ~0xf) * sizeof(list[0]);
3467         int i = 0;
3468
3469         indent();
3470         fdprintf(2, "%s: list:%p n:%d string_start:%d length:%d maxlen:%d glob:%d quoted:%d escape:%d\n",
3471                         prefix, list, n, string_start, o->length, o->maxlen,
3472                         !!(o->o_expflags & EXP_FLAG_GLOB),
3473                         o->has_quoted_part,
3474                         !!(o->o_expflags & EXP_FLAG_ESC_GLOB_CHARS));
3475         while (i < n) {
3476                 indent();
3477                 fdprintf(2, " list[%d]=%d '%s' %p\n", i, (int)(uintptr_t)list[i],
3478                                 o->data + (int)(uintptr_t)list[i] + string_start,
3479                                 o->data + (int)(uintptr_t)list[i] + string_start);
3480                 i++;
3481         }
3482         if (n) {
3483                 const char *p = o->data + (int)(uintptr_t)list[n - 1] + string_start;
3484                 indent();
3485 #ifndef __U_BOOT__
3486                 fdprintf(2, " total_sz:%ld\n", (long)((p + strlen(p) + 1) - o->data));
3487 #else /* __U_BOOT__ */
3488                 printf(" total_sz:%ld\n", (long)((p + strlen(p) + 1) - o->data));
3489 #endif /* __U_BOOT__ */
3490         }
3491 }
3492 #else
3493 # define debug_print_list(prefix, o, n) ((void)0)
3494 #endif
3495
3496 /* n = o_save_ptr_helper(str, n) "starts new string" by storing an index value
3497  * in list[n] so that it points past last stored byte so far.
3498  * It returns n+1. */
3499 static int o_save_ptr_helper(o_string *o, int n)
3500 {
3501         char **list = (char**)o->data;
3502         int string_start;
3503         int string_len;
3504
3505         if (!o->has_empty_slot) {
3506                 string_start = ((n + 0xf) & ~0xf) * sizeof(list[0]);
3507                 string_len = o->length - string_start;
3508                 if (!(n & 0xf)) { /* 0, 0x10, 0x20...? */
3509                         debug_printf_list("list[%d]=%d string_start=%d (growing)\n", n, string_len, string_start);
3510                         /* list[n] points to string_start, make space for 16 more pointers */
3511                         o->maxlen += 0x10 * sizeof(list[0]);
3512                         o->data = xrealloc(o->data, o->maxlen + 1);
3513                         list = (char**)o->data;
3514                         memmove(list + n + 0x10, list + n, string_len);
3515                         /*
3516                          * expand_on_ifs() has a "previous argv[] ends in IFS?"
3517                          * check. (grep for -prev-ifs-check-).
3518                          * Ensure that argv[-1][last] is not garbage
3519                          * but zero bytes, to save index check there.
3520                          */
3521                         list[n + 0x10 - 1] = 0;
3522                         o->length += 0x10 * sizeof(list[0]);
3523                 } else {
3524                         debug_printf_list("list[%d]=%d string_start=%d\n",
3525                                         n, string_len, string_start);
3526                 }
3527         } else {
3528                 /* We have empty slot at list[n], reuse without growth */
3529                 string_start = ((n+1 + 0xf) & ~0xf) * sizeof(list[0]); /* NB: n+1! */
3530                 string_len = o->length - string_start;
3531                 debug_printf_list("list[%d]=%d string_start=%d (empty slot)\n",
3532                                 n, string_len, string_start);
3533                 o->has_empty_slot = 0;
3534         }
3535         o->has_quoted_part = 0;
3536         list[n] = (char*)(uintptr_t)string_len;
3537         return n + 1;
3538 }
3539
3540 /* "What was our last o_save_ptr'ed position (byte offset relative o->data)?" */
3541 static int o_get_last_ptr(o_string *o, int n)
3542 {
3543         char **list = (char**)o->data;
3544         int string_start = ((n + 0xf) & ~0xf) * sizeof(list[0]);
3545
3546         return ((int)(uintptr_t)list[n-1]) + string_start;
3547 }
3548
3549 /*
3550  * Globbing routines.
3551  *
3552  * Most words in commands need to be globbed, even ones which are
3553  * (single or double) quoted. This stems from the possiblity of
3554  * constructs like "abc"* and 'abc'* - these should be globbed.
3555  * Having a different code path for fully-quoted strings ("abc",
3556  * 'abc') would only help performance-wise, but we still need
3557  * code for partially-quoted strings.
3558  *
3559  * Unfortunately, if we want to match bash and ash behavior in all cases,
3560  * the logic can't be "shell-syntax argument is first transformed
3561  * to a string, then globbed, and if globbing does not match anything,
3562  * it is used verbatim". Here are two examples where it fails:
3563  *
3564  *      echo 'b\*'?
3565  *
3566  * The globbing can't be avoided (because of '?' at the end).
3567  * The glob pattern is: b\\\*? - IOW, both \ and * are literals
3568  * and are glob-escaped. If this does not match, bash/ash print b\*?
3569  * - IOW: they "unbackslash" the glob pattern.
3570  * Now, look at this:
3571  *
3572  *      v='\\\*'; echo b$v?
3573  *
3574  * The glob pattern is the same here: b\\\*? - the unquoted $v expansion
3575  * should be used as glob pattern with no changes. However, if glob
3576  * does not match, bash/ash print b\\\*? - NOT THE SAME as first example!
3577  *
3578  * ash implements this by having an encoded representation of the word
3579  * to glob, which IS NOT THE SAME as the glob pattern - it has more data.
3580  * Glob pattern is derived from it. If glob fails, the decision what result
3581  * should be is made using that encoded representation. Not glob pattern.
3582  */
3583
3584 #if ENABLE_HUSH_BRACE_EXPANSION
3585 /* There in a GNU extension, GLOB_BRACE, but it is not usable:
3586  * first, it processes even {a} (no commas), second,
3587  * I didn't manage to make it return strings when they don't match
3588  * existing files. Need to re-implement it.
3589  */
3590
3591 /* Helper */
3592 static int glob_needed(const char *s)
3593 {
3594         while (*s) {
3595                 if (*s == '\\') {
3596                         if (!s[1])
3597                                 return 0;
3598                         s += 2;
3599                         continue;
3600                 }
3601                 if (*s == '*' || *s == '[' || *s == '?' || *s == '{')
3602                         return 1;
3603                 s++;
3604         }
3605         return 0;
3606 }
3607 /* Return pointer to next closing brace or to comma */
3608 static const char *next_brace_sub(const char *cp)
3609 {
3610         unsigned depth = 0;
3611         cp++;
3612         while (*cp != '\0') {
3613                 if (*cp == '\\') {
3614                         if (*++cp == '\0')
3615                                 break;
3616                         cp++;
3617                         continue;
3618                 }
3619                 if ((*cp == '}' && depth-- == 0) || (*cp == ',' && depth == 0))
3620                         break;
3621                 if (*cp++ == '{')
3622                         depth++;
3623         }
3624
3625         return *cp != '\0' ? cp : NULL;
3626 }
3627 /* Recursive brace globber. Note: may garble pattern[]. */
3628 static int glob_brace(char *pattern, o_string *o, int n)
3629 {
3630         char *new_pattern_buf;
3631         const char *begin;
3632         const char *next;
3633         const char *rest;
3634         const char *p;
3635         size_t rest_len;
3636
3637         debug_printf_glob("glob_brace('%s')\n", pattern);
3638
3639         begin = pattern;
3640         while (1) {
3641                 if (*begin == '\0')
3642                         goto simple_glob;
3643                 if (*begin == '{') {
3644                         /* Find the first sub-pattern and at the same time
3645                          * find the rest after the closing brace */
3646                         next = next_brace_sub(begin);
3647                         if (next == NULL) {
3648                                 /* An illegal expression */
3649                                 goto simple_glob;
3650                         }
3651                         if (*next == '}') {
3652                                 /* "{abc}" with no commas - illegal
3653                                  * brace expr, disregard and skip it */
3654                                 begin = next + 1;
3655                                 continue;
3656                         }
3657                         break;
3658                 }
3659                 if (*begin == '\\' && begin[1] != '\0')
3660                         begin++;
3661                 begin++;
3662         }
3663         debug_printf_glob("begin:%s\n", begin);
3664         debug_printf_glob("next:%s\n", next);
3665
3666         /* Now find the end of the whole brace expression */
3667         rest = next;
3668         while (*rest != '}') {
3669                 rest = next_brace_sub(rest);
3670                 if (rest == NULL) {
3671                         /* An illegal expression */
3672                         goto simple_glob;
3673                 }
3674                 debug_printf_glob("rest:%s\n", rest);
3675         }
3676         rest_len = strlen(++rest) + 1;
3677
3678         /* We are sure the brace expression is well-formed */
3679
3680         /* Allocate working buffer large enough for our work */
3681         new_pattern_buf = xmalloc(strlen(pattern));
3682
3683         /* We have a brace expression.  BEGIN points to the opening {,
3684          * NEXT points past the terminator of the first element, and REST
3685          * points past the final }.  We will accumulate result names from
3686          * recursive runs for each brace alternative in the buffer using
3687          * GLOB_APPEND. */
3688
3689         p = begin + 1;
3690         while (1) {
3691                 /* Construct the new glob expression */
3692                 memcpy(
3693                         mempcpy(
3694                                 mempcpy(new_pattern_buf,
3695                                         /* We know the prefix for all sub-patterns */
3696                                         pattern, begin - pattern),
3697                                 p, next - p),
3698                         rest, rest_len);
3699
3700                 /* Note: glob_brace() may garble new_pattern_buf[].
3701                  * That's why we re-copy prefix every time (1st memcpy above).
3702                  */
3703                 n = glob_brace(new_pattern_buf, o, n);
3704                 if (*next == '}') {
3705                         /* We saw the last entry */
3706                         break;
3707                 }
3708                 p = next + 1;
3709                 next = next_brace_sub(next);
3710         }
3711         free(new_pattern_buf);
3712         return n;
3713
3714  simple_glob:
3715         {
3716                 int gr;
3717                 glob_t globdata;
3718
3719                 memset(&globdata, 0, sizeof(globdata));
3720                 gr = glob(pattern, 0, NULL, &globdata);
3721                 debug_printf_glob("glob('%s'):%d\n", pattern, gr);
3722                 if (gr != 0) {
3723                         if (gr == GLOB_NOMATCH) {
3724                                 globfree(&globdata);
3725                                 /* NB: garbles parameter */
3726                                 unbackslash(pattern);
3727                                 o_addstr_with_NUL(o, pattern);
3728                                 debug_printf_glob("glob pattern '%s' is literal\n", pattern);
3729                                 return o_save_ptr_helper(o, n);
3730                         }
3731                         if (gr == GLOB_NOSPACE)
3732                                 bb_die_memory_exhausted();
3733                         /* GLOB_ABORTED? Only happens with GLOB_ERR flag,
3734                          * but we didn't specify it. Paranoia again. */
3735                         bb_error_msg_and_die("glob error %d on '%s'", gr, pattern);
3736                 }
3737                 if (globdata.gl_pathv && globdata.gl_pathv[0]) {
3738                         char **argv = globdata.gl_pathv;
3739                         while (1) {
3740                                 o_addstr_with_NUL(o, *argv);
3741                                 n = o_save_ptr_helper(o, n);
3742                                 argv++;
3743                                 if (!*argv)
3744                                         break;
3745                         }
3746                 }
3747                 globfree(&globdata);
3748         }
3749         return n;
3750 }
3751 /* Performs globbing on last list[],
3752  * saving each result as a new list[].
3753  */
3754 static int perform_glob(o_string *o, int n)
3755 {
3756         char *pattern, *copy;
3757
3758         debug_printf_glob("start perform_glob: n:%d o->data:%p\n", n, o->data);
3759         if (!o->data)
3760                 return o_save_ptr_helper(o, n);
3761         pattern = o->data + o_get_last_ptr(o, n);
3762         debug_printf_glob("glob pattern '%s'\n", pattern);
3763         if (!glob_needed(pattern)) {
3764                 /* unbackslash last string in o in place, fix length */
3765                 o->length = unbackslash(pattern) - o->data;
3766                 debug_printf_glob("glob pattern '%s' is literal\n", pattern);
3767                 return o_save_ptr_helper(o, n);
3768         }
3769
3770         copy = xstrdup(pattern);
3771         /* "forget" pattern in o */
3772         o->length = pattern - o->data;
3773         n = glob_brace(copy, o, n);
3774         free(copy);
3775         if (DEBUG_GLOB)
3776                 debug_print_list("perform_glob returning", o, n);
3777         return n;
3778 }
3779
3780 #else /* !HUSH_BRACE_EXPANSION */
3781
3782 /* Helper */
3783 static int glob_needed(const char *s)
3784 {
3785         while (*s) {
3786                 if (*s == '\\') {
3787                         if (!s[1])
3788                                 return 0;
3789                         s += 2;
3790                         continue;
3791                 }
3792                 if (*s == '*' || *s == '[' || *s == '?')
3793                         return 1;
3794                 s++;
3795         }
3796         return 0;
3797 }
3798 /* Performs globbing on last list[],
3799  * saving each result as a new list[].
3800  */
3801 static int perform_glob(o_string *o, int n)
3802 {
3803 #ifndef __U_BOOT__
3804         glob_t globdata;
3805         int gr;
3806 #endif /* __U_BOOT__ */
3807         char *pattern;
3808
3809         debug_printf_glob("start perform_glob: n:%d o->data:%p\n", n, o->data);
3810         if (!o->data)
3811                 return o_save_ptr_helper(o, n);
3812         pattern = o->data + o_get_last_ptr(o, n);
3813         debug_printf_glob("glob pattern '%s'\n", pattern);
3814         if (!glob_needed(pattern)) {
3815 #ifndef __U_BOOT__
3816  literal:
3817 #endif /* __U_BOOT__ */
3818                 /* unbackslash last string in o in place, fix length */
3819                 o->length = unbackslash(pattern) - o->data;
3820                 debug_printf_glob("glob pattern '%s' is literal\n", pattern);
3821                 return o_save_ptr_helper(o, n);
3822         }
3823
3824 #ifndef __U_BOOT__
3825         memset(&globdata, 0, sizeof(globdata));
3826         /* Can't use GLOB_NOCHECK: it does not unescape the string.
3827          * If we glob "*.\*" and don't find anything, we need
3828          * to fall back to using literal "*.*", but GLOB_NOCHECK
3829          * will return "*.\*"!
3830          */
3831         gr = glob(pattern, 0, NULL, &globdata);
3832         debug_printf_glob("glob('%s'):%d\n", pattern, gr);
3833         if (gr != 0) {
3834                 if (gr == GLOB_NOMATCH) {
3835                         globfree(&globdata);
3836                         goto literal;
3837                 }
3838                 if (gr == GLOB_NOSPACE)
3839                         bb_die_memory_exhausted();
3840                 /* GLOB_ABORTED? Only happens with GLOB_ERR flag,
3841                  * but we didn't specify it. Paranoia again. */
3842                 bb_error_msg_and_die("glob error %d on '%s'", gr, pattern);
3843         }
3844         if (globdata.gl_pathv && globdata.gl_pathv[0]) {
3845                 char **argv = globdata.gl_pathv;
3846                 /* "forget" pattern in o */
3847                 o->length = pattern - o->data;
3848                 while (1) {
3849                         o_addstr_with_NUL(o, *argv);
3850                         n = o_save_ptr_helper(o, n);
3851                         argv++;
3852                         if (!*argv)
3853                                 break;
3854                 }
3855         }
3856         globfree(&globdata);
3857         if (DEBUG_GLOB)
3858                 debug_print_list("perform_glob returning", o, n);
3859         return n;
3860 #else /* __U_BOOT__ */
3861         /*
3862          * NOTE We only use perform glob to call unbackslash to remove backslash
3863          * from string once expanded.
3864          * So, it seems OK to return this if no previous return was done.
3865          */
3866         return o_save_ptr_helper(o, n);
3867 #endif /* __U_BOOT__ */
3868 }
3869
3870 #endif /* !HUSH_BRACE_EXPANSION */
3871
3872 /* If o->o_expflags & EXP_FLAG_GLOB, glob the string so far remembered.
3873  * Otherwise, just finish current list[] and start new */
3874 static int o_save_ptr(o_string *o, int n)
3875 {
3876         if (o->o_expflags & EXP_FLAG_GLOB) {
3877                 /* If o->has_empty_slot, list[n] was already globbed
3878                  * (if it was requested back then when it was filled)
3879                  * so don't do that again! */
3880                 if (!o->has_empty_slot)
3881                         return perform_glob(o, n); /* o_save_ptr_helper is inside */
3882         }
3883         return o_save_ptr_helper(o, n);
3884 }
3885
3886 /* "Please convert list[n] to real char* ptrs, and NULL terminate it." */
3887 static char **o_finalize_list(o_string *o, int n)
3888 {
3889         char **list;
3890         int string_start;
3891
3892         if (DEBUG_EXPAND)
3893                 debug_print_list("finalized", o, n);
3894         debug_printf_expand("finalized n:%d\n", n);
3895         list = (char**)o->data;
3896         string_start = ((n + 0xf) & ~0xf) * sizeof(list[0]);
3897         list[--n] = NULL;
3898         while (n) {
3899                 n--;
3900                 list[n] = o->data + (int)(uintptr_t)list[n] + string_start;
3901         }
3902         return list;
3903 }
3904
3905 static void free_pipe_list(struct pipe *pi);
3906
3907 /* Returns pi->next - next pipe in the list */
3908 static struct pipe *free_pipe(struct pipe *pi)
3909 {
3910         struct pipe *next;
3911         int i;
3912
3913 #ifndef __U_BOOT__
3914         debug_printf_clean("free_pipe (pid %d)\n", getpid());
3915 #endif /* !__U_BOOT__ */
3916         for (i = 0; i < pi->num_cmds; i++) {
3917                 struct command *command;
3918 #ifndef __U_BOOT__
3919                 struct redir_struct *r, *rnext;
3920 #endif /* !__U_BOOT__ */
3921
3922                 command = &pi->cmds[i];
3923                 debug_printf_clean("  command %d:\n", i);
3924                 if (command->argv) {
3925                         if (DEBUG_CLEAN) {
3926                                 int a;
3927                                 char **p;
3928                                 for (a = 0, p = command->argv; *p; a++, p++) {
3929                                         debug_printf_clean("   argv[%d] = %s\n", a, *p);
3930                                 }
3931                         }
3932                         free_strings(command->argv);
3933                         //command->argv = NULL;
3934                 }
3935                 /* not "else if": on syntax error, we may have both! */
3936                 if (command->group) {
3937                         debug_printf_clean("   begin group (cmd_type:%d)\n",
3938                                         command->cmd_type);
3939                         free_pipe_list(command->group);
3940                         debug_printf_clean("   end group\n");
3941                         //command->group = NULL;
3942                 }
3943                 /* else is crucial here.
3944                  * If group != NULL, child_func is meaningless */
3945 #if ENABLE_HUSH_FUNCTIONS
3946                 else if (command->child_func) {
3947                         debug_printf_exec("cmd %p releases child func at %p\n", command, command->child_func);
3948                         command->child_func->parent_cmd = NULL;
3949                 }
3950 #endif
3951 #if !BB_MMU
3952                 free(command->group_as_string);
3953                 //command->group_as_string = NULL;
3954 #endif
3955 #ifndef __U_BOOT__
3956                 for (r = command->redirects; r; r = rnext) {
3957                         debug_printf_clean("   redirect %d%s",
3958                                         r->rd_fd, redir_table[r->rd_type].descrip);
3959                         /* guard against the case >$FOO, where foo is unset or blank */
3960                         if (r->rd_filename) {
3961                                 debug_printf_clean(" fname:'%s'\n", r->rd_filename);
3962                                 free(r->rd_filename);
3963                                 //r->rd_filename = NULL;
3964                         }
3965                         debug_printf_clean(" rd_dup:%d\n", r->rd_dup);
3966                         rnext = r->next;
3967                         free(r);
3968                 }
3969                 //command->redirects = NULL;
3970 #endif /* !__U_BOOT__ */
3971         }
3972         free(pi->cmds);   /* children are an array, they get freed all at once */
3973         //pi->cmds = NULL;
3974 #ifndef __U_BOOT__
3975 #if ENABLE_HUSH_JOB
3976         free(pi->cmdtext);
3977         //pi->cmdtext = NULL;
3978 #endif
3979 #endif /* !__U_BOOT__ */
3980
3981         next = pi->next;
3982         free(pi);
3983         return next;
3984 }
3985
3986 static void free_pipe_list(struct pipe *pi)
3987 {
3988         while (pi) {
3989 #if HAS_KEYWORDS
3990                 debug_printf_clean("pipe reserved word %d\n", pi->res_word);
3991 #endif
3992                 debug_printf_clean("pipe followup code %d\n", pi->followup);
3993                 pi = free_pipe(pi);
3994         }
3995 }
3996
3997 /*** Parsing routines ***/
3998
3999 #ifndef debug_print_tree
4000 static void debug_print_tree(struct pipe *pi, int lvl)
4001 {
4002         static const char *const PIPE[] ALIGN_PTR = {
4003                 [PIPE_SEQ] = "SEQ",
4004                 [PIPE_AND] = "AND",
4005                 [PIPE_OR ] = "OR" ,
4006                 [PIPE_BG ] = "BG" ,
4007         };
4008         static const char *RES[] = {
4009                 [RES_NONE ] = "NONE" ,
4010 # if ENABLE_HUSH_IF
4011                 [RES_IF   ] = "IF"   ,
4012                 [RES_THEN ] = "THEN" ,
4013                 [RES_ELIF ] = "ELIF" ,
4014                 [RES_ELSE ] = "ELSE" ,
4015                 [RES_FI   ] = "FI"   ,
4016 # endif
4017 # if ENABLE_HUSH_LOOPS
4018                 [RES_FOR  ] = "FOR"  ,
4019                 [RES_WHILE] = "WHILE",
4020                 [RES_UNTIL] = "UNTIL",
4021                 [RES_DO   ] = "DO"   ,
4022                 [RES_DONE ] = "DONE" ,
4023 # endif
4024 # if ENABLE_HUSH_LOOPS || ENABLE_HUSH_CASE
4025                 [RES_IN   ] = "IN"   ,
4026 # endif
4027 # if ENABLE_HUSH_CASE
4028                 [RES_CASE ] = "CASE" ,
4029                 [RES_CASE_IN ] = "CASE_IN" ,
4030                 [RES_MATCH] = "MATCH",
4031                 [RES_CASE_BODY] = "CASE_BODY",
4032                 [RES_ESAC ] = "ESAC" ,
4033 # endif
4034                 [RES_XXXX ] = "XXXX" ,
4035                 [RES_SNTX ] = "SNTX" ,
4036         };
4037         static const char *const CMDTYPE[] ALIGN_PTR = {
4038                 "{}",
4039                 "()",
4040                 "[noglob]",
4041 # if ENABLE_HUSH_FUNCTIONS
4042                 "func()",
4043 # endif
4044         };
4045
4046         int pin, prn;
4047
4048         pin = 0;
4049         while (pi) {
4050                 fdprintf(2, "%*spipe %d #cmds:%d %sres_word=%s followup=%d %s\n",
4051                                 lvl*2, "",
4052                                 pin,
4053                                 pi->num_cmds,
4054                                 (IF_HAS_KEYWORDS(pi->pi_inverted ? "! " :) ""),
4055                                 RES[pi->res_word],
4056                                 pi->followup, PIPE[pi->followup]
4057                 );
4058                 prn = 0;
4059                 while (prn < pi->num_cmds) {
4060                         struct command *command = &pi->cmds[prn];
4061                         char **argv = command->argv;
4062
4063                         fdprintf(2, "%*s cmd %d assignment_cnt:%d",
4064                                         lvl*2, "", prn,
4065                                         command->assignment_cnt);
4066 # if ENABLE_HUSH_LINENO_VAR
4067                         fdprintf(2, " LINENO:%u", command->lineno);
4068 # endif
4069                         if (command->group) {
4070                                 fdprintf(2, " group %s: (argv=%p)%s%s\n",
4071                                                 CMDTYPE[command->cmd_type],
4072                                                 argv
4073 # if !BB_MMU
4074                                                 , " group_as_string:", command->group_as_string
4075 # else
4076                                                 , "", ""
4077 # endif
4078                                 );
4079                                 debug_print_tree(command->group, lvl+1);
4080                                 prn++;
4081                                 continue;
4082                         }
4083                         if (argv) while (*argv) {
4084                                 fdprintf(2, " '%s'", *argv);
4085                                 argv++;
4086                         }
4087 #ifndef __U_BOOT__
4088                         if (command->redirects)
4089                                 fdprintf(2, " {redir}");
4090 #endif /* __U_BOOT__ */
4091                         fdprintf(2, "\n");
4092                         prn++;
4093                 }
4094                 pi = pi->next;
4095                 pin++;
4096         }
4097 }
4098 #endif /* debug_print_tree */
4099
4100 static struct pipe *new_pipe(void)
4101 {
4102         struct pipe *pi;
4103         pi = xzalloc(sizeof(struct pipe));
4104         /*pi->res_word = RES_NONE; - RES_NONE is 0 anyway */
4105         return pi;
4106 }
4107
4108 /* Command (member of a pipe) is complete, or we start a new pipe
4109  * if ctx->command is NULL.
4110  * No errors possible here.
4111  */
4112 static int done_command(struct parse_context *ctx)
4113 {
4114         /* The command is really already in the pipe structure, so
4115          * advance the pipe counter and make a new, null command. */
4116         struct pipe *pi = ctx->pipe;
4117         struct command *command = ctx->command;
4118
4119 #if 0   /* Instead we emit error message at run time */
4120         if (ctx->pending_redirect) {
4121                 /* For example, "cmd >" (no filename to redirect to) */
4122                 syntax_error("invalid redirect");
4123                 ctx->pending_redirect = NULL;
4124         }
4125 #endif
4126
4127         if (command) {
4128                 if (IS_NULL_CMD(command)) {
4129                         debug_printf_parse("done_command: skipping null cmd, num_cmds=%d\n", pi->num_cmds);
4130                         goto clear_and_ret;
4131                 }
4132                 pi->num_cmds++;
4133                 debug_printf_parse("done_command: ++num_cmds=%d\n", pi->num_cmds);
4134                 //debug_print_tree(ctx->list_head, 20);
4135         } else {
4136                 debug_printf_parse("done_command: initializing, num_cmds=%d\n", pi->num_cmds);
4137         }
4138
4139         /* Only real trickiness here is that the uncommitted
4140          * command structure is not counted in pi->num_cmds. */
4141         pi->cmds = xrealloc(pi->cmds, sizeof(*pi->cmds) * (pi->num_cmds+1));
4142         ctx->command = command = &pi->cmds[pi->num_cmds];
4143  clear_and_ret:
4144         memset(command, 0, sizeof(*command));
4145 #if ENABLE_HUSH_LINENO_VAR
4146         command->lineno = G.parse_lineno;
4147         debug_printf_parse("command->lineno = G.parse_lineno (%u)\n", G.parse_lineno);
4148 #endif
4149         return pi->num_cmds; /* used only for 0/nonzero check */
4150 }
4151
4152 static void done_pipe(struct parse_context *ctx, pipe_style type)
4153 {
4154         int not_null;
4155
4156         debug_printf_parse("done_pipe entered, followup %d\n", type);
4157         /* Close previous command */
4158         not_null = done_command(ctx);
4159 #if HAS_KEYWORDS
4160         ctx->pipe->pi_inverted = ctx->ctx_inverted;
4161         ctx->ctx_inverted = 0;
4162         ctx->pipe->res_word = ctx->ctx_res_w;
4163 #endif
4164         if (type == PIPE_BG && ctx->list_head != ctx->pipe) {
4165                 /* Necessary since && and || have precedence over &:
4166                  * "cmd1 && cmd2 &" must spawn both cmds, not only cmd2,
4167                  * in a backgrounded subshell.
4168                  */
4169                 struct pipe *pi;
4170                 struct command *command;
4171
4172                 /* Is this actually this construct, all pipes end with && or ||? */
4173                 pi = ctx->list_head;
4174                 while (pi != ctx->pipe) {
4175                         if (pi->followup != PIPE_AND && pi->followup != PIPE_OR)
4176                                 goto no_conv;
4177                         pi = pi->next;
4178                 }
4179
4180                 debug_printf_parse("BG with more than one pipe, converting to { p1 &&...pN; } &\n");
4181                 pi->followup = PIPE_SEQ; /* close pN _not_ with "&"! */
4182                 pi = xzalloc(sizeof(*pi));
4183                 pi->followup = PIPE_BG;
4184                 pi->num_cmds = 1;
4185                 pi->cmds = xzalloc(sizeof(pi->cmds[0]));
4186                 command = &pi->cmds[0];
4187                 if (CMD_NORMAL != 0) /* "if xzalloc didn't do that already" */
4188                         command->cmd_type = CMD_NORMAL;
4189                 command->group = ctx->list_head;
4190 #if !BB_MMU
4191                 command->group_as_string = xstrndup(
4192                             ctx->as_string.data,
4193                             ctx->as_string.length - 1 /* do not copy last char, "&" */
4194                 );
4195 #endif
4196                 /* Replace all pipes in ctx with one newly created */
4197                 ctx->list_head = ctx->pipe = pi;
4198                 /* for cases like "cmd && &", do not be tricked by last command
4199                  * being null - the entire {...} & is NOT null! */
4200                 not_null = 1;
4201         } else {
4202  no_conv:
4203                 ctx->pipe->followup = type;
4204         }
4205
4206         /* Without this check, even just <enter> on command line generates
4207          * tree of three NOPs (!). Which is harmless but annoying.
4208          * IOW: it is safe to do it unconditionally. */
4209         if (not_null
4210 #if ENABLE_HUSH_IF
4211          || ctx->ctx_res_w == RES_FI
4212 #endif
4213 #if ENABLE_HUSH_LOOPS
4214          || ctx->ctx_res_w == RES_DONE
4215          || ctx->ctx_res_w == RES_FOR
4216          || ctx->ctx_res_w == RES_IN
4217 #endif
4218 #if ENABLE_HUSH_CASE
4219          || ctx->ctx_res_w == RES_ESAC
4220 #endif
4221         ) {
4222                 struct pipe *new_p;
4223                 debug_printf_parse("done_pipe: adding new pipe: "
4224 #ifndef __U_BOOT__
4225                                 "not_null:%d ctx->ctx_res_w:%d\n",
4226                                 not_null, ctx->ctx_res_w);
4227 #else /* __U_BOOT__ */
4228                                 "not_null:%d\n",
4229                                 not_null);
4230 #endif /* __U_BOOT__ */
4231                 new_p = new_pipe();
4232                 ctx->pipe->next = new_p;
4233                 ctx->pipe = new_p;
4234                 /* RES_THEN, RES_DO etc are "sticky" -
4235                  * they remain set for pipes inside if/while.
4236                  * This is used to control execution.
4237                  * RES_FOR and RES_IN are NOT sticky (needed to support
4238                  * cases where variable or value happens to match a keyword):
4239                  */
4240 #if ENABLE_HUSH_LOOPS
4241                 if (ctx->ctx_res_w == RES_FOR
4242                  || ctx->ctx_res_w == RES_IN)
4243                         ctx->ctx_res_w = RES_NONE;
4244 #endif
4245 #if ENABLE_HUSH_CASE
4246                 if (ctx->ctx_res_w == RES_MATCH)
4247                         ctx->ctx_res_w = RES_CASE_BODY;
4248                 if (ctx->ctx_res_w == RES_CASE)
4249                         ctx->ctx_res_w = RES_CASE_IN;
4250 #endif
4251                 ctx->command = NULL; /* trick done_command below */
4252                 /* Create the memory for command, roughly:
4253                  * ctx->pipe->cmds = new struct command;
4254                  * ctx->command = &ctx->pipe->cmds[0];
4255                  */
4256                 done_command(ctx);
4257                 //debug_print_tree(ctx->list_head, 10);
4258         }
4259         debug_printf_parse("done_pipe return\n");
4260 }
4261
4262 static void initialize_context(struct parse_context *ctx)
4263 {
4264         memset(ctx, 0, sizeof(*ctx));
4265         if (MAYBE_ASSIGNMENT != 0)
4266                 ctx->is_assignment = MAYBE_ASSIGNMENT;
4267         ctx->pipe = ctx->list_head = new_pipe();
4268         /* Create the memory for command, roughly:
4269          * ctx->pipe->cmds = new struct command;
4270          * ctx->command = &ctx->pipe->cmds[0];
4271          */
4272         done_command(ctx);
4273 }
4274
4275 /* If a reserved word is found and processed, parse context is modified
4276  * and 1 is returned.
4277  */
4278 #if HAS_KEYWORDS
4279 struct reserved_combo {
4280         char literal[6];
4281         unsigned char res;
4282         unsigned char assignment_flag;
4283         uint32_t flag;
4284 };
4285 enum {
4286         FLAG_END   = (1 << RES_NONE ),
4287 # if ENABLE_HUSH_IF
4288         FLAG_IF    = (1 << RES_IF   ),
4289         FLAG_THEN  = (1 << RES_THEN ),
4290         FLAG_ELIF  = (1 << RES_ELIF ),
4291         FLAG_ELSE  = (1 << RES_ELSE ),
4292         FLAG_FI    = (1 << RES_FI   ),
4293 # endif
4294 # if ENABLE_HUSH_LOOPS
4295         FLAG_FOR   = (1 << RES_FOR  ),
4296         FLAG_WHILE = (1 << RES_WHILE),
4297         FLAG_UNTIL = (1 << RES_UNTIL),
4298         FLAG_DO    = (1 << RES_DO   ),
4299         FLAG_DONE  = (1 << RES_DONE ),
4300         FLAG_IN    = (1 << RES_IN   ),
4301 # endif
4302 # if ENABLE_HUSH_CASE
4303         FLAG_MATCH = (1 << RES_MATCH),
4304         FLAG_ESAC  = (1 << RES_ESAC ),
4305 # endif
4306         FLAG_START = (1 << RES_XXXX ),
4307 };
4308
4309 static const struct reserved_combo* match_reserved_word(o_string *word)
4310 {
4311         /* Mostly a list of accepted follow-up reserved words.
4312          * FLAG_END means we are done with the sequence, and are ready
4313          * to turn the compound list into a command.
4314          * FLAG_START means the word must start a new compound list.
4315          */
4316         static const struct reserved_combo reserved_list[] ALIGN4 = {
4317 # if ENABLE_HUSH_IF
4318                 { "!",     RES_NONE,  NOT_ASSIGNMENT  , 0 },
4319                 { "if",    RES_IF,    MAYBE_ASSIGNMENT, FLAG_THEN | FLAG_START },
4320                 { "then",  RES_THEN,  MAYBE_ASSIGNMENT, FLAG_ELIF | FLAG_ELSE | FLAG_FI },
4321                 { "elif",  RES_ELIF,  MAYBE_ASSIGNMENT, FLAG_THEN },
4322                 { "else",  RES_ELSE,  MAYBE_ASSIGNMENT, FLAG_FI   },
4323                 { "fi",    RES_FI,    NOT_ASSIGNMENT  , FLAG_END  },
4324 # endif
4325 # if ENABLE_HUSH_LOOPS
4326                 { "for",   RES_FOR,   NOT_ASSIGNMENT  , FLAG_IN | FLAG_DO | FLAG_START },
4327                 { "while", RES_WHILE, MAYBE_ASSIGNMENT, FLAG_DO | FLAG_START },
4328                 { "until", RES_UNTIL, MAYBE_ASSIGNMENT, FLAG_DO | FLAG_START },
4329                 { "in",    RES_IN,    NOT_ASSIGNMENT  , FLAG_DO   },
4330                 { "do",    RES_DO,    MAYBE_ASSIGNMENT, FLAG_DONE },
4331                 { "done",  RES_DONE,  NOT_ASSIGNMENT  , FLAG_END  },
4332 # endif
4333 # if ENABLE_HUSH_CASE
4334                 { "case",  RES_CASE,  NOT_ASSIGNMENT  , FLAG_MATCH | FLAG_START },
4335                 { "esac",  RES_ESAC,  NOT_ASSIGNMENT  , FLAG_END  },
4336 # endif
4337         };
4338         const struct reserved_combo *r;
4339
4340         for (r = reserved_list; r < reserved_list + ARRAY_SIZE(reserved_list); r++) {
4341                 if (strcmp(word->data, r->literal) == 0)
4342                         return r;
4343         }
4344         return NULL;
4345 }
4346 /* Return NULL: not a keyword, else: keyword
4347  */
4348 static const struct reserved_combo* reserved_word(struct parse_context *ctx)
4349 {
4350 # if ENABLE_HUSH_CASE
4351         static const struct reserved_combo reserved_match = {
4352                 "",        RES_MATCH, NOT_ASSIGNMENT , FLAG_MATCH | FLAG_ESAC
4353         };
4354 # endif
4355         const struct reserved_combo *r;
4356
4357         if (ctx->word.has_quoted_part)
4358                 return 0;
4359         r = match_reserved_word(&ctx->word);
4360         if (!r)
4361                 return r; /* NULL */
4362
4363         debug_printf("found reserved word %s, res %d\n", r->literal, r->res);
4364 # if ENABLE_HUSH_CASE
4365         if (r->res == RES_IN && ctx->ctx_res_w == RES_CASE_IN) {
4366                 /* "case word IN ..." - IN part starts first MATCH part */
4367                 r = &reserved_match;
4368         } else
4369 # endif
4370         if (r->flag == 0) { /* '!' */
4371                 if (ctx->ctx_inverted) { /* bash doesn't accept '! ! true' */
4372                         syntax_error("! ! command");
4373                         ctx->ctx_res_w = RES_SNTX;
4374                 }
4375                 ctx->ctx_inverted = 1;
4376                 return r;
4377         }
4378         if (r->flag & FLAG_START) {
4379                 struct parse_context *old;
4380
4381                 old = xmemdup(ctx, sizeof(*ctx));
4382                 debug_printf_parse("push stack %p\n", old);
4383                 initialize_context(ctx);
4384                 ctx->stack = old;
4385         } else if (/*ctx->ctx_res_w == RES_NONE ||*/ !(ctx->old_flag & (1 << r->res))) {
4386                 syntax_error_at(ctx->word.data);
4387                 ctx->ctx_res_w = RES_SNTX;
4388                 return r;
4389         } else {
4390                 /* "{...} fi" is ok. "{...} if" is not
4391                  * Example:
4392                  * if { echo foo; } then { echo bar; } fi */
4393                 if (ctx->command->group)
4394                         done_pipe(ctx, PIPE_SEQ);
4395         }
4396
4397         ctx->ctx_res_w = r->res;
4398         ctx->old_flag = r->flag;
4399         ctx->is_assignment = r->assignment_flag;
4400         debug_printf_parse("ctx->is_assignment='%s'\n", assignment_flag[ctx->is_assignment]);
4401
4402         if (ctx->old_flag & FLAG_END) {
4403                 struct parse_context *old;
4404
4405                 done_pipe(ctx, PIPE_SEQ);
4406                 debug_printf_parse("pop stack %p\n", ctx->stack);
4407                 old = ctx->stack;
4408                 old->command->group = ctx->list_head;
4409                 old->command->cmd_type = CMD_NORMAL;
4410 # if !BB_MMU
4411                 /* At this point, the compound command's string is in
4412                  * ctx->as_string... except for the leading keyword!
4413                  * Consider this example: "echo a | if true; then echo a; fi"
4414                  * ctx->as_string will contain "true; then echo a; fi",
4415                  * with "if " remaining in old->as_string!
4416                  */
4417                 {
4418                         char *str;
4419                         int len = old->as_string.length;
4420                         /* Concatenate halves */
4421                         o_addstr(&old->as_string, ctx->as_string.data);
4422                         o_free(&ctx->as_string);
4423                         /* Find where leading keyword starts in first half */
4424                         str = old->as_string.data + len;
4425                         if (str > old->as_string.data)
4426                                 str--; /* skip whitespace after keyword */
4427                         while (str > old->as_string.data && isalpha(str[-1]))
4428                                 str--;
4429                         /* Ugh, we're done with this horrid hack */
4430                         old->command->group_as_string = xstrdup(str);
4431                         debug_printf_parse("pop, remembering as:'%s'\n",
4432                                         old->command->group_as_string);
4433                 }
4434 # endif
4435                 *ctx = *old;   /* physical copy */
4436                 free(old);
4437         }
4438         return r;
4439 }
4440 #endif /* HAS_KEYWORDS */
4441
4442 /* Word is complete, look at it and update parsing context.
4443  * Normal return is 0. Syntax errors return 1.
4444  * Note: on return, word is reset, but not o_free'd!
4445  */
4446 static int done_word(struct parse_context *ctx)
4447 {
4448         struct command *command = ctx->command;
4449
4450         debug_printf_parse("done_word entered: '%s' %p\n", ctx->word.data, command);
4451         if (ctx->word.length == 0 && !ctx->word.has_quoted_part) {
4452                 debug_printf_parse("done_word return 0: true null, ignored\n");
4453                 return 0;
4454         }
4455
4456 #ifndef __U_BOOT__
4457         if (ctx->pending_redirect) {
4458                 /* We do not glob in e.g. >*.tmp case. bash seems to glob here
4459                  * only if run as "bash", not "sh" */
4460                 /* http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html
4461                  * "2.7 Redirection
4462                  * If the redirection operator is "<<" or "<<-", the word
4463                  * that follows the redirection operator shall be
4464                  * subjected to quote removal; it is unspecified whether
4465                  * any of the other expansions occur. For the other
4466                  * redirection operators, the word that follows the
4467                  * redirection operator shall be subjected to tilde
4468                  * expansion, parameter expansion, command substitution,
4469                  * arithmetic expansion, and quote removal.
4470                  * Pathname expansion shall not be performed
4471                  * on the word by a non-interactive shell; an interactive
4472                  * shell may perform it, but shall do so only when
4473                  * the expansion would result in one word."
4474                  */
4475 //bash does not do parameter/command substitution or arithmetic expansion
4476 //for _heredoc_ redirection word: these constructs look for exact eof marker
4477 // as written:
4478 // <<EOF$t
4479 // <<EOF$((1))
4480 // <<EOF`true`  [this case also makes heredoc "quoted", a-la <<"EOF". Probably bash-4.3.43 bug]
4481
4482                 ctx->pending_redirect->rd_filename = xstrdup(ctx->word.data);
4483                 /* Cater for >\file case:
4484                  * >\a creates file a; >\\a, >"\a", >"\\a" create file \a
4485                  * Same with heredocs:
4486                  * for <<\H delim is H; <<\\H, <<"\H", <<"\\H" - \H
4487                  */
4488                 if (ctx->pending_redirect->rd_type == REDIRECT_HEREDOC) {
4489                         unbackslash(ctx->pending_redirect->rd_filename);
4490                         /* Is it <<"HEREDOC"? */
4491                         if (ctx->word.has_quoted_part) {
4492                                 ctx->pending_redirect->rd_dup |= HEREDOC_QUOTED;
4493                         }
4494                 }
4495                 debug_printf_parse("word stored in rd_filename: '%s'\n", ctx->word.data);
4496                 ctx->pending_redirect = NULL;
4497         } else {
4498 #endif /* !__U_BOOT__ */
4499 #if HAS_KEYWORDS
4500 # if ENABLE_HUSH_CASE
4501                 if (ctx->ctx_dsemicolon
4502                  && strcmp(ctx->word.data, "esac") != 0 /* not "... pattern) cmd;; esac" */
4503                 ) {
4504                         /* already done when ctx_dsemicolon was set to 1: */
4505                         /* ctx->ctx_res_w = RES_MATCH; */
4506                         ctx->ctx_dsemicolon = 0;
4507                 } else
4508 # endif
4509 # if defined(CMD_TEST2_SINGLEWORD_NOGLOB)
4510                 if (command->cmd_type == CMD_TEST2_SINGLEWORD_NOGLOB
4511                  && strcmp(ctx->word.data, "]]") == 0
4512                 ) {
4513                         /* allow "[[ ]] >file" etc */
4514                         command->cmd_type = CMD_SINGLEWORD_NOGLOB;
4515                 } else
4516 # endif
4517                 if (!command->argv /* if it's the first word... */
4518 # if ENABLE_HUSH_LOOPS
4519                  && ctx->ctx_res_w != RES_FOR /* ...not after FOR or IN */
4520                  && ctx->ctx_res_w != RES_IN
4521 # endif
4522 # if ENABLE_HUSH_CASE
4523                  && ctx->ctx_res_w != RES_CASE
4524 # endif
4525                 ) {
4526                         const struct reserved_combo *reserved;
4527                         reserved = reserved_word(ctx);
4528                         debug_printf_parse("checking for reserved-ness: %d\n", !!reserved);
4529                         if (reserved) {
4530 # if ENABLE_HUSH_LINENO_VAR
4531 /* Case:
4532  * "while ...; do
4533  *      cmd ..."
4534  * If we don't close the pipe _now_, immediately after "do", lineno logic
4535  * sees "cmd" as starting at "do" - i.e., at the previous line.
4536  */
4537                                 if (0
4538                                  IF_HUSH_IF(|| reserved->res == RES_THEN)
4539                                  IF_HUSH_IF(|| reserved->res == RES_ELIF)
4540                                  IF_HUSH_IF(|| reserved->res == RES_ELSE)
4541                                  IF_HUSH_LOOPS(|| reserved->res == RES_DO)
4542                                 ) {
4543                                         done_pipe(ctx, PIPE_SEQ);
4544                                 }
4545 # endif
4546                                 o_reset_to_empty_unquoted(&ctx->word);
4547                                 debug_printf_parse("done_word return %d\n",
4548                                                 (ctx->ctx_res_w == RES_SNTX));
4549                                 return (ctx->ctx_res_w == RES_SNTX);
4550                         }
4551 # if defined(CMD_TEST2_SINGLEWORD_NOGLOB)
4552                         if (strcmp(ctx->word.data, "[[") == 0) {
4553                                 command->cmd_type = CMD_TEST2_SINGLEWORD_NOGLOB;
4554                         } else
4555 # endif
4556 # if defined(CMD_SINGLEWORD_NOGLOB)
4557                         if (0
4558                         /* In bash, local/export/readonly are special, args
4559                          * are assignments and therefore expansion of them
4560                          * should be "one-word" expansion:
4561                          *  $ export i=`echo 'a  b'` # one arg: "i=a  b"
4562                          * compare with:
4563                          *  $ ls i=`echo 'a  b'`     # two args: "i=a" and "b"
4564                          *  ls: cannot access i=a: No such file or directory
4565                          *  ls: cannot access b: No such file or directory
4566                          * Note: bash 3.2.33(1) does this only if export word
4567                          * itself is not quoted:
4568                          *  $ export i=`echo 'aaa  bbb'`; echo "$i"
4569                          *  aaa  bbb
4570                          *  $ "export" i=`echo 'aaa  bbb'`; echo "$i"
4571                          *  aaa
4572                          */
4573                          IF_HUSH_LOCAL(   || strcmp(ctx->word.data, "local") == 0)
4574                          IF_HUSH_EXPORT(  || strcmp(ctx->word.data, "export") == 0)
4575                          IF_HUSH_READONLY(|| strcmp(ctx->word.data, "readonly") == 0)
4576                         ) {
4577                                 command->cmd_type = CMD_SINGLEWORD_NOGLOB;
4578                         }
4579 # else
4580                         { /* empty block to pair "if ... else" */ }
4581 # endif
4582                 }
4583 #endif /* HAS_KEYWORDS */
4584
4585                 if (command->group) {
4586                         /* "{ echo foo; } echo bar" - bad */
4587                         syntax_error_at(ctx->word.data);
4588                         debug_printf_parse("done_word return 1: syntax error, "
4589                                         "groups and arglists don't mix\n");
4590                         return 1;
4591                 }
4592
4593                 /* If this word wasn't an assignment, next ones definitely
4594                  * can't be assignments. Even if they look like ones. */
4595                 if (ctx->is_assignment != DEFINITELY_ASSIGNMENT
4596                  && ctx->is_assignment != WORD_IS_KEYWORD
4597                 ) {
4598                         ctx->is_assignment = NOT_ASSIGNMENT;
4599                 } else {
4600                         if (ctx->is_assignment == DEFINITELY_ASSIGNMENT) {
4601                                 command->assignment_cnt++;
4602                                 debug_printf_parse("++assignment_cnt=%d\n", command->assignment_cnt);
4603                         }
4604                         debug_printf_parse("ctx->is_assignment was:'%s'\n", assignment_flag[ctx->is_assignment]);
4605                         ctx->is_assignment = MAYBE_ASSIGNMENT;
4606                 }
4607                 debug_printf_parse("ctx->is_assignment='%s'\n", assignment_flag[ctx->is_assignment]);
4608                 command->argv = add_string_to_strings(command->argv, xstrdup(ctx->word.data));
4609 #ifdef __U_BOOT__
4610                 command->argc++;
4611 #endif /* __U_BOOT__ */
4612                 debug_print_strings("word appended to argv", command->argv);
4613
4614 #ifndef __U_BOOT__
4615         }
4616 #endif /* !__U_BOOT__ */
4617
4618 #if ENABLE_HUSH_LOOPS
4619         if (ctx->ctx_res_w == RES_FOR) {
4620                 if (ctx->word.has_quoted_part
4621                  || endofname(command->argv[0])[0] != '\0'
4622                 ) {
4623                         /* bash says just "not a valid identifier" */
4624                         syntax_error("bad for loop variable");
4625                         return 1;
4626                 }
4627                 /* Force FOR to have just one word (variable name) */
4628                 /* NB: basically, this makes hush see "for v in ..."
4629                  * syntax as if it is "for v; in ...". FOR and IN become
4630                  * two pipe structs in parse tree. */
4631                 done_pipe(ctx, PIPE_SEQ);
4632         }
4633 #endif
4634 #if ENABLE_HUSH_CASE
4635         /* Force CASE to have just one word */
4636         if (ctx->ctx_res_w == RES_CASE) {
4637                 done_pipe(ctx, PIPE_SEQ);
4638         }
4639 #endif
4640
4641         o_reset_to_empty_unquoted(&ctx->word);
4642
4643         debug_printf_parse("done_word return 0\n");
4644         return 0;
4645 }
4646
4647 #ifndef __U_BOOT__
4648 /* Peek ahead in the input to find out if we have a "&n" construct,
4649  * as in "2>&1", that represents duplicating a file descriptor.
4650  * Return:
4651  * REDIRFD_CLOSE if >&- "close fd" construct is seen,
4652  * REDIRFD_SYNTAX_ERR if syntax error,
4653  * REDIRFD_TO_FILE if no & was seen,
4654  * or the number found.
4655  */
4656 #if BB_MMU
4657 #define parse_redir_right_fd(as_string, input) \
4658         parse_redir_right_fd(input)
4659 #endif
4660 static int parse_redir_right_fd(o_string *as_string, struct in_str *input)
4661 {
4662         int ch, d, ok;
4663
4664         ch = i_peek(input);
4665         if (ch != '&')
4666                 return REDIRFD_TO_FILE;
4667
4668         ch = i_getch(input);  /* get the & */
4669         nommu_addchr(as_string, ch);
4670         ch = i_peek(input);
4671         if (ch == '-') {
4672                 ch = i_getch(input);
4673                 nommu_addchr(as_string, ch);
4674                 return REDIRFD_CLOSE;
4675         }
4676         d = 0;
4677         ok = 0;
4678         while (ch != EOF && isdigit(ch)) {
4679                 d = d*10 + (ch-'0');
4680                 ok = 1;
4681                 ch = i_getch(input);
4682                 nommu_addchr(as_string, ch);
4683                 ch = i_peek(input);
4684         }
4685         if (ok) return d;
4686
4687 //TODO: this is the place to catch ">&file" bashism (redirect both fd 1 and 2)
4688
4689         bb_simple_error_msg("ambiguous redirect");
4690         return REDIRFD_SYNTAX_ERR;
4691 }
4692
4693 /* Return code is 0 normal, 1 if a syntax error is detected
4694  */
4695 static int parse_redirect(struct parse_context *ctx,
4696                 int fd,
4697                 redir_type style,
4698                 struct in_str *input)
4699 {
4700         struct command *command = ctx->command;
4701         struct redir_struct *redir;
4702         struct redir_struct **redirp;
4703         int dup_num;
4704
4705         dup_num = REDIRFD_TO_FILE;
4706         if (style != REDIRECT_HEREDOC) {
4707                 /* Check for a '>&1' type redirect */
4708                 dup_num = parse_redir_right_fd(&ctx->as_string, input);
4709                 if (dup_num == REDIRFD_SYNTAX_ERR)
4710                         return 1;
4711         } else {
4712                 int ch = i_peek_and_eat_bkslash_nl(input);
4713                 dup_num = (ch == '-'); /* HEREDOC_SKIPTABS bit is 1 */
4714                 if (dup_num) { /* <<-... */
4715                         ch = i_getch(input);
4716                         nommu_addchr(&ctx->as_string, ch);
4717                         ch = i_peek(input);
4718                 }
4719         }
4720
4721         if (style == REDIRECT_OVERWRITE && dup_num == REDIRFD_TO_FILE) {
4722                 int ch = i_peek_and_eat_bkslash_nl(input);
4723                 if (ch == '|') {
4724                         /* >|FILE redirect ("clobbering" >).
4725                          * Since we do not support "set -o noclobber" yet,
4726                          * >| and > are the same for now. Just eat |.
4727                          */
4728                         ch = i_getch(input);
4729                         nommu_addchr(&ctx->as_string, ch);
4730                 }
4731         }
4732
4733         /* Create a new redir_struct and append it to the linked list */
4734         redirp = &command->redirects;
4735         while ((redir = *redirp) != NULL) {
4736                 redirp = &(redir->next);
4737         }
4738         *redirp = redir = xzalloc(sizeof(*redir));
4739         /* redir->next = NULL; */
4740         /* redir->rd_filename = NULL; */
4741         redir->rd_type = style;
4742         redir->rd_fd = (fd == -1) ? redir_table[style].default_fd : fd;
4743
4744         debug_printf_parse("redirect type %d %s\n", redir->rd_fd,
4745                                 redir_table[style].descrip);
4746
4747         redir->rd_dup = dup_num;
4748         if (style != REDIRECT_HEREDOC && dup_num != REDIRFD_TO_FILE) {
4749                 /* Erik had a check here that the file descriptor in question
4750                  * is legit; I postpone that to "run time"
4751                  * A "-" representation of "close me" shows up as a -3 here */
4752                 debug_printf_parse("duplicating redirect '%d>&%d'\n",
4753                                 redir->rd_fd, redir->rd_dup);
4754         } else {
4755 #if 0           /* Instead we emit error message at run time */
4756                 if (ctx->pending_redirect) {
4757                         /* For example, "cmd > <file" */
4758                         syntax_error("invalid redirect");
4759                 }
4760 #endif
4761                 /* Set ctx->pending_redirect, so we know what to do at the
4762                  * end of the next parsed word. */
4763                 ctx->pending_redirect = redir;
4764         }
4765         return 0;
4766 }
4767
4768 /* If a redirect is immediately preceded by a number, that number is
4769  * supposed to tell which file descriptor to redirect.  This routine
4770  * looks for such preceding numbers.  In an ideal world this routine
4771  * needs to handle all the following classes of redirects...
4772  *     echo 2>foo     # redirects fd  2 to file "foo", nothing passed to echo
4773  *     echo 49>foo    # redirects fd 49 to file "foo", nothing passed to echo
4774  *     echo -2>foo    # redirects fd  1 to file "foo",    "-2" passed to echo
4775  *     echo 49x>foo   # redirects fd  1 to file "foo",   "49x" passed to echo
4776  *
4777  * http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html
4778  * "2.7 Redirection
4779  * ... If n is quoted, the number shall not be recognized as part of
4780  * the redirection expression. For example:
4781  * echo \2>a
4782  * writes the character 2 into file a"
4783  * We are getting it right by setting ->has_quoted_part on any \<char>
4784  *
4785  * A -1 return means no valid number was found,
4786  * the caller should use the appropriate default for this redirection.
4787  */
4788 static int redirect_opt_num(o_string *o)
4789 {
4790         int num;
4791
4792         if (o->data == NULL)
4793                 return -1;
4794         num = bb_strtou(o->data, NULL, 10);
4795         if (errno || num < 0)
4796                 return -1;
4797         o_reset_to_empty_unquoted(o);
4798         return num;
4799 }
4800
4801 #if BB_MMU
4802 #define fetch_till_str(as_string, input, word, skip_tabs) \
4803         fetch_till_str(input, word, skip_tabs)
4804 #endif
4805 static char *fetch_till_str(o_string *as_string,
4806                 struct in_str *input,
4807                 const char *word,
4808                 int heredoc_flags)
4809 {
4810         o_string heredoc = NULL_O_STRING;
4811         unsigned past_EOL;
4812         int prev = 0; /* not \ */
4813         int ch;
4814
4815         /* Starting with "" is necessary for this case:
4816          * cat <<EOF
4817          *
4818          * xxx
4819          * EOF
4820          */
4821         heredoc.data = xzalloc(1); /* start as "", not as NULL */
4822
4823         goto jump_in;
4824
4825         while (1) {
4826                 ch = i_getch(input);
4827                 if (ch != EOF)
4828                         nommu_addchr(as_string, ch);
4829                 if (ch == '\n' || ch == EOF) {
4830  check_heredoc_end:
4831 #ifndef __U_BOOT__
4832                         if ((heredoc_flags & HEREDOC_QUOTED) || prev != '\\') {
4833 #else /* __U_BOOT__ */
4834                         if (prev != '\\') {
4835 #endif
4836                                 /* End-of-line, and not a line continuation */
4837                                 if (strcmp(heredoc.data + past_EOL, word) == 0) {
4838                                         heredoc.data[past_EOL] = '\0';
4839                                         debug_printf_heredoc("parsed '%s' heredoc '%s'\n", word, heredoc.data);
4840                                         return heredoc.data;
4841                                 }
4842                                 if (ch == '\n') {
4843                                         /* This is a new line.
4844                                          * Remember position and backslash-escaping status.
4845                                          */
4846                                         o_addchr(&heredoc, ch);
4847                                         prev = ch;
4848  jump_in:
4849                                         past_EOL = heredoc.length;
4850                                         /* Get 1st char of next line, possibly skipping leading tabs */
4851                                         do {
4852                                                 ch = i_getch(input);
4853                                                 if (ch != EOF)
4854                                                         nommu_addchr(as_string, ch);
4855 #ifndef __U_BOOT__
4856                                         } while ((heredoc_flags & HEREDOC_SKIPTABS) && ch == '\t');
4857 #else /* __U_BOOT__ */
4858                                 } while (ch == '\t');
4859 #endif
4860                                         /* If this immediately ended the line,
4861                                          * go back to end-of-line checks.
4862                                          */
4863                                         if (ch == '\n')
4864                                                 goto check_heredoc_end;
4865                                 }
4866                         } else {
4867                                 /* Backslash-line continuation in an unquoted
4868                                  * heredoc. This does not need special handling
4869                                  * for heredoc body (unquoted heredocs are
4870                                  * expanded on "execution" and that would take
4871                                  * care of this case too), but not the case
4872                                  * of line continuation *in terminator*:
4873                                  *  cat <<EOF
4874                                  *  Ok1
4875                                  *  EO\
4876                                  *  F
4877                                  */
4878                                 heredoc.data[--heredoc.length] = '\0';
4879                                 prev = 0; /* not '\' */
4880                                 continue;
4881                         }
4882                 }
4883                 if (ch == EOF) {
4884                         o_free(&heredoc);
4885                         return NULL; /* error */
4886                 }
4887                 o_addchr(&heredoc, ch);
4888                 nommu_addchr(as_string, ch);
4889                 if (prev == '\\' && ch == '\\')
4890                         /* Correctly handle foo\\<eol> (not a line cont.) */
4891                         prev = 0; /* not '\' */
4892                 else
4893                         prev = ch;
4894         }
4895 }
4896 #endif /* !__U_BOOT__ */
4897
4898 /* Look at entire parse tree for not-yet-loaded REDIRECT_HEREDOCs
4899  * and load them all. There should be exactly heredoc_cnt of them.
4900  */
4901 #if BB_MMU
4902 #define fetch_heredocs(as_string, pi, heredoc_cnt, input) \
4903         fetch_heredocs(pi, heredoc_cnt, input)
4904 #endif
4905 static int fetch_heredocs(o_string *as_string, struct pipe *pi, int heredoc_cnt, struct in_str *input)
4906 {
4907         while (pi && heredoc_cnt) {
4908                 int i;
4909                 struct command *cmd = pi->cmds;
4910
4911                 debug_printf_heredoc("fetch_heredocs: num_cmds:%d cmd argv0:'%s'\n",
4912                                 pi->num_cmds,
4913                                 cmd->argv ? cmd->argv[0] : "NONE"
4914                 );
4915                 for (i = 0; i < pi->num_cmds; i++) {
4916 #ifndef __U_BOOT__
4917                         struct redir_struct *redir = cmd->redirects;
4918
4919 #endif /* !__U_BOOT__ */
4920                         debug_printf_heredoc("fetch_heredocs: %d cmd argv0:'%s'\n",
4921                                         i, cmd->argv ? cmd->argv[0] : "NONE");
4922 #ifndef __U_BOOT__
4923                         while (redir) {
4924                                 if (redir->rd_type == REDIRECT_HEREDOC) {
4925                                         char *p;
4926
4927                                         redir->rd_type = REDIRECT_HEREDOC2;
4928                                         /* redir->rd_dup is (ab)used to indicate <<- */
4929                                         p = fetch_till_str(as_string, input,
4930                                                         redir->rd_filename, redir->rd_dup);
4931                                         if (!p) {
4932                                                 syntax_error("unexpected EOF in here document");
4933                                                 return -1;
4934                                         }
4935                                         free(redir->rd_filename);
4936                                         redir->rd_filename = p;
4937                                         heredoc_cnt--;
4938                                 }
4939                                 redir = redir->next;
4940                         }
4941 #endif /* !__U_BOOT__ */
4942                         if (cmd->group) {
4943                                 //bb_error_msg("%s:%u heredoc_cnt:%d", __func__, __LINE__, heredoc_cnt);
4944                                 heredoc_cnt = fetch_heredocs(as_string, cmd->group, heredoc_cnt, input);
4945                                 //bb_error_msg("%s:%u heredoc_cnt:%d", __func__, __LINE__, heredoc_cnt);
4946                                 if (heredoc_cnt < 0)
4947                                         return heredoc_cnt; /* error */
4948                         }
4949                         cmd++;
4950                 }
4951                 pi = pi->next;
4952         }
4953         return heredoc_cnt;
4954 }
4955
4956 static int run_list(struct pipe *pi);
4957 #if BB_MMU
4958 #define parse_stream(pstring, heredoc_cnt_ptr, input, end_trigger) \
4959         parse_stream(heredoc_cnt_ptr, input, end_trigger)
4960 #endif
4961 static struct pipe *parse_stream(char **pstring,
4962                 int *heredoc_cnt_ptr,
4963                 struct in_str *input,
4964                 int end_trigger);
4965
4966 /* Returns number of heredocs not yet consumed,
4967  * or -1 on error.
4968  */
4969 static int parse_group(struct parse_context *ctx,
4970                 struct in_str *input, int ch)
4971 {
4972         /* ctx->word contains characters seen prior to ( or {.
4973          * Typically it's empty, but for function defs,
4974          * it contains function name (without '()'). */
4975 #if BB_MMU
4976 # define as_string NULL
4977 #else
4978         char *as_string = NULL;
4979 #endif
4980         struct pipe *pipe_list;
4981         int heredoc_cnt = 0;
4982         int endch;
4983         struct command *command = ctx->command;
4984
4985         debug_printf_parse("parse_group entered\n");
4986 #if ENABLE_HUSH_FUNCTIONS
4987         if (ch == '(' && !ctx->word.has_quoted_part) {
4988                 if (ctx->word.length)
4989                         if (done_word(ctx))
4990                                 return -1;
4991                 if (!command->argv)
4992                         goto skip; /* (... */
4993                 if (command->argv[1]) { /* word word ... (... */
4994                         syntax_error_unexpected_ch('(');
4995                         return -1;
4996                 }
4997                 /* it is "word(..." or "word (..." */
4998                 do
4999                         ch = i_getch(input);
5000                 while (ch == ' ' || ch == '\t');
5001                 if (ch != ')') {
5002                         syntax_error_unexpected_ch(ch);
5003                         return -1;
5004                 }
5005                 nommu_addchr(&ctx->as_string, ch);
5006                 do
5007                         ch = i_getch(input);
5008                 while (ch == ' ' || ch == '\t' || ch == '\n');
5009                 if (ch != '{' && ch != '(') {
5010                         syntax_error_unexpected_ch(ch);
5011                         return -1;
5012                 }
5013 //bash allows functions named "123", "..", "return"!
5014 //              if (endofname(command->argv[0])[0] != '\0') {
5015 //                      syntax_error("bad function name");
5016 //                      return -1;
5017 //              }
5018                 nommu_addchr(&ctx->as_string, ch);
5019                 command->cmd_type = CMD_FUNCDEF;
5020                 goto skip;
5021         }
5022 #endif
5023
5024 #if 0 /* Prevented by caller */
5025         if (command->argv /* word [word]{... */
5026          || ctx->word.length /* word{... */
5027          || ctx->word.has_quoted_part /* ""{... */
5028         ) {
5029                 syntax_error(NULL);
5030                 debug_printf_parse("parse_group return -1: "
5031                         "syntax error, groups and arglists don't mix\n");
5032                 return -1;
5033         }
5034 #endif
5035
5036 #ifndef __U_BOOT__
5037  IF_HUSH_FUNCTIONS(skip:)
5038 #endif /* !__U_BOOT__ */
5039
5040         endch = '}';
5041         if (ch == '(') {
5042                 endch = ')';
5043 #ifndef __U_BOOT__
5044                 IF_HUSH_FUNCTIONS(if (command->cmd_type != CMD_FUNCDEF))
5045                         command->cmd_type = CMD_SUBSHELL;
5046 #endif /* !__U_BOOT__ */
5047         } else {
5048                 /* bash does not allow "{echo...", requires whitespace */
5049                 ch = i_peek(input);
5050                 if (ch != ' ' && ch != '\t' && ch != '\n'
5051                  && ch != '('   /* but "{(..." is allowed (without whitespace) */
5052                 ) {
5053                         syntax_error_unexpected_ch(ch);
5054                         return -1;
5055                 }
5056                 if (ch != '(') {
5057                         ch = i_getch(input);
5058                         nommu_addchr(&ctx->as_string, ch);
5059                 }
5060         }
5061
5062         debug_printf_heredoc("calling parse_stream, heredoc_cnt:%d\n", heredoc_cnt);
5063         pipe_list = parse_stream(&as_string, &heredoc_cnt, input, endch);
5064         debug_printf_heredoc("parse_stream returned: heredoc_cnt:%d\n", heredoc_cnt);
5065 #if !BB_MMU
5066         if (as_string)
5067                 o_addstr(&ctx->as_string, as_string);
5068 #endif
5069
5070         /* empty ()/{} or parse error? */
5071         if (!pipe_list || pipe_list == ERR_PTR) {
5072                 /* parse_stream already emitted error msg */
5073                 if (!BB_MMU)
5074                         free(as_string);
5075                 debug_printf_parse("parse_group return -1: "
5076                         "parse_stream returned %p\n", pipe_list);
5077                 return -1;
5078         }
5079 #if !BB_MMU
5080         as_string[strlen(as_string) - 1] = '\0'; /* plink ')' or '}' */
5081         command->group_as_string = as_string;
5082         debug_printf_parse("end of group, remembering as:'%s'\n",
5083                         command->group_as_string);
5084 #endif
5085
5086 #if ENABLE_HUSH_FUNCTIONS
5087         /* Convert "f() (cmds)" to "f() {(cmds)}" */
5088         if (command->cmd_type == CMD_FUNCDEF && endch == ')') {
5089                 struct command *cmd2;
5090
5091                 cmd2 = xzalloc(sizeof(*cmd2));
5092                 cmd2->cmd_type = CMD_SUBSHELL;
5093                 cmd2->group = pipe_list;
5094 # if !BB_MMU
5095 //UNTESTED!
5096                 cmd2->group_as_string = command->group_as_string;
5097                 command->group_as_string = xasprintf("(%s)", command->group_as_string);
5098 # endif
5099
5100                 pipe_list = new_pipe();
5101                 pipe_list->cmds = cmd2;
5102                 pipe_list->num_cmds = 1;
5103         }
5104 #endif
5105
5106         command->group = pipe_list;
5107
5108         debug_printf_parse("parse_group return %d\n", heredoc_cnt);
5109         return heredoc_cnt;
5110         /* command remains "open", available for possible redirects */
5111 #undef as_string
5112 }
5113
5114 #ifndef __U_BOOT__
5115 #if ENABLE_HUSH_TICK || ENABLE_FEATURE_SH_MATH || ENABLE_HUSH_DOLLAR_OPS
5116 /* Subroutines for copying $(...) and `...` things */
5117 /* '...' */
5118 static int add_till_single_quote(o_string *dest, struct in_str *input)
5119 {
5120         while (1) {
5121                 int ch = i_getch(input);
5122                 if (ch == EOF) {
5123                         syntax_error_unterm_ch('\'');
5124                         return 0;
5125                 }
5126                 if (ch == '\'')
5127                         return 1;
5128                 o_addchr(dest, ch);
5129         }
5130 }
5131 static int add_till_single_quote_dquoted(o_string *dest, struct in_str *input)
5132 {
5133         while (1) {
5134                 int ch = i_getch(input);
5135                 if (ch == EOF) {
5136                         syntax_error_unterm_ch('\'');
5137                         return 0;
5138                 }
5139                 if (ch == '\'')
5140                         return 1;
5141                 o_addqchr(dest, ch);
5142         }
5143 }
5144
5145 /* "...\"...`..`...." - do we need to handle "...$(..)..." too? */
5146 static int add_till_backquote(o_string *dest, struct in_str *input, int in_dquote);
5147 static int add_till_double_quote(o_string *dest, struct in_str *input)
5148 {
5149         while (1) {
5150                 int ch = i_getch(input);
5151                 if (ch == EOF) {
5152                         syntax_error_unterm_ch('"');
5153                         return 0;
5154                 }
5155                 if (ch == '"')
5156                         return 1;
5157                 if (ch == '\\') {  /* \x. Copy both chars. */
5158                         o_addchr(dest, ch);
5159                         ch = i_getch(input);
5160                 }
5161                 o_addchr(dest, ch);
5162                 if (ch == '`') {
5163                         if (!add_till_backquote(dest, input, /*in_dquote:*/ 1))
5164                                 return 0;
5165                         o_addchr(dest, ch);
5166                         continue;
5167                 }
5168                 //if (ch == '$') ...
5169         }
5170 }
5171
5172 /* Process `cmd` - copy contents until "`" is seen. Complicated by
5173  * \` quoting.
5174  * "Within the backquoted style of command substitution, backslash
5175  * shall retain its literal meaning, except when followed by: '$', '`', or '\'.
5176  * The search for the matching backquote shall be satisfied by the first
5177  * backquote found without a preceding backslash; during this search,
5178  * if a non-escaped backquote is encountered within a shell comment,
5179  * a here-document, an embedded command substitution of the $(command)
5180  * form, or a quoted string, undefined results occur. A single-quoted
5181  * or double-quoted string that begins, but does not end, within the
5182  * "`...`" sequence produces undefined results."
5183  * Example                               Output
5184  * echo `echo '\'TEST\`echo ZZ\`BEST`    \TESTZZBEST
5185  */
5186 static int add_till_backquote(o_string *dest, struct in_str *input, int in_dquote)
5187 {
5188         while (1) {
5189                 int ch = i_getch(input);
5190                 if (ch == '`')
5191                         return 1;
5192                 if (ch == '\\') {
5193                         /* \x. Copy both unless it is \`, \$, \\ and maybe \" */
5194                         ch = i_getch(input);
5195                         if (ch != '`'
5196                          && ch != '$'
5197                          && ch != '\\'
5198                          && (!in_dquote || ch != '"')
5199                         ) {
5200                                 o_addchr(dest, '\\');
5201                         }
5202                 }
5203                 if (ch == EOF) {
5204                         syntax_error_unterm_ch('`');
5205                         return 0;
5206                 }
5207                 o_addchr(dest, ch);
5208         }
5209 }
5210 /* Process $(cmd) - copy contents until ")" is seen. Complicated by
5211  * quoting and nested ()s.
5212  * "With the $(command) style of command substitution, all characters
5213  * following the open parenthesis to the matching closing parenthesis
5214  * constitute the command. Any valid shell script can be used for command,
5215  * except a script consisting solely of redirections which produces
5216  * unspecified results."
5217  * Example                              Output
5218  * echo $(echo '(TEST)' BEST)           (TEST) BEST
5219  * echo $(echo 'TEST)' BEST)            TEST) BEST
5220  * echo $(echo \(\(TEST\) BEST)         ((TEST) BEST
5221  *
5222  * Also adapted to eat ${var%...} and $((...)) constructs, since ... part
5223  * can contain arbitrary constructs, just like $(cmd).
5224  * In bash compat mode, it needs to also be able to stop on ':' or '/'
5225  * for ${var:N[:M]} and ${var/P[/R]} parsing.
5226  */
5227 #define DOUBLE_CLOSE_CHAR_FLAG 0x80
5228 static int add_till_closing_bracket(o_string *dest, struct in_str *input, unsigned end_ch)
5229 {
5230         int ch;
5231         char dbl = end_ch & DOUBLE_CLOSE_CHAR_FLAG;
5232 # if BASH_SUBSTR || BASH_PATTERN_SUBST
5233         char end_char2 = end_ch >> 8;
5234 # endif
5235         end_ch &= (DOUBLE_CLOSE_CHAR_FLAG - 1);
5236
5237 # if ENABLE_HUSH_INTERACTIVE
5238         G.promptmode = 1; /* PS2 */
5239 # endif
5240         debug_printf_prompt("%s promptmode=%d\n", __func__, G.promptmode);
5241
5242         while (1) {
5243                 ch = i_getch(input);
5244                 if (ch == EOF) {
5245                         syntax_error_unterm_ch(end_ch);
5246                         return 0;
5247                 }
5248                 if (ch == end_ch
5249 # if BASH_SUBSTR || BASH_PATTERN_SUBST
5250                  || ch == end_char2
5251 # endif
5252                 ) {
5253                         if (!dbl)
5254                                 break;
5255                         /* we look for closing )) of $((EXPR)) */
5256                         if (i_peek_and_eat_bkslash_nl(input) == end_ch) {
5257                                 i_getch(input); /* eat second ')' */
5258                                 break;
5259                         }
5260                 }
5261                 o_addchr(dest, ch);
5262                 //bb_error_msg("%s:o_addchr('%c')", __func__, ch);
5263                 if (ch == '(' || ch == '{') {
5264                         ch = (ch == '(' ? ')' : '}');
5265                         if (!add_till_closing_bracket(dest, input, ch))
5266                                 return 0;
5267                         o_addchr(dest, ch);
5268                         continue;
5269                 }
5270                 if (ch == '\'') {
5271                         if (!add_till_single_quote(dest, input))
5272                                 return 0;
5273                         o_addchr(dest, ch);
5274                         continue;
5275                 }
5276                 if (ch == '"') {
5277                         if (!add_till_double_quote(dest, input))
5278                                 return 0;
5279                         o_addchr(dest, ch);
5280                         continue;
5281                 }
5282                 if (ch == '`') {
5283                         if (!add_till_backquote(dest, input, /*in_dquote:*/ 0))
5284                                 return 0;
5285                         o_addchr(dest, ch);
5286                         continue;
5287                 }
5288                 if (ch == '\\') {
5289                         /* \x. Copy verbatim. Important for  \(, \) */
5290                         ch = i_getch(input);
5291                         if (ch == EOF) {
5292                                 syntax_error_unterm_ch(end_ch);
5293                                 return 0;
5294                         }
5295 # if 0
5296                         if (ch == '\n') {
5297                                 /* "backslash+newline", ignore both */
5298                                 o_delchr(dest); /* undo insertion of '\' */
5299                                 continue;
5300                         }
5301 # endif
5302                         o_addchr(dest, ch);
5303                         //bb_error_msg("%s:o_addchr('%c') after '\\'", __func__, ch);
5304                         continue;
5305                 }
5306         }
5307         debug_printf_parse("%s return '%s' ch:'%c'\n", __func__, dest->data, ch);
5308         return ch;
5309 }
5310 #endif /* ENABLE_HUSH_TICK || ENABLE_FEATURE_SH_MATH || ENABLE_HUSH_DOLLAR_OPS */
5311
5312 #if BASH_DOLLAR_SQUOTE
5313 /* Return code: 1 for "found and parsed", 0 for "seen something else" */
5314 # if BB_MMU
5315 #define parse_dollar_squote(as_string, dest, input) \
5316         parse_dollar_squote(dest, input)
5317 #define as_string NULL
5318 # endif
5319 static int parse_dollar_squote(o_string *as_string, o_string *dest, struct in_str *input)
5320 {
5321         int start;
5322         int ch = i_peek_and_eat_bkslash_nl(input);  /* first character after the $ */
5323         debug_printf_parse("parse_dollar_squote entered: ch='%c'\n", ch);
5324         if (ch != '\'')
5325                 return 0;
5326
5327         dest->has_quoted_part = 1;
5328         start = dest->length;
5329
5330         ch = i_getch(input); /* eat ' */
5331         nommu_addchr(as_string, ch);
5332         while (1) {
5333                 ch = i_getch(input);
5334                 nommu_addchr(as_string, ch);
5335                 if (ch == EOF) {
5336                         syntax_error_unterm_ch('\'');
5337                         return 0;
5338                 }
5339                 if (ch == '\'')
5340                         break;
5341                 if (ch == SPECIAL_VAR_SYMBOL) {
5342                         /* Convert raw ^C to corresponding special variable reference */
5343                         o_addchr(dest, SPECIAL_VAR_SYMBOL);
5344                         o_addchr(dest, SPECIAL_VAR_QUOTED_SVS);
5345                         /* will addchr() another SPECIAL_VAR_SYMBOL (see after the if() block) */
5346                 } else if (ch == '\\') {
5347                         static const char C_escapes[] ALIGN1 = "nrbtfav""x\\01234567";
5348
5349                         ch = i_getch(input);
5350                         nommu_addchr(as_string, ch);
5351                         if (strchr(C_escapes, ch)) {
5352                                 char buf[4];
5353                                 char *p = buf;
5354                                 int cnt = 2;
5355
5356                                 buf[0] = ch;
5357                                 if ((unsigned char)(ch - '0') <= 7) { /* \ooo */
5358                                         do {
5359                                                 ch = i_peek(input);
5360                                                 if ((unsigned char)(ch - '0') > 7)
5361                                                         break;
5362                                                 *++p = ch = i_getch(input);
5363                                                 nommu_addchr(as_string, ch);
5364                                         } while (--cnt != 0);
5365                                 } else if (ch == 'x') { /* \xHH */
5366                                         do {
5367                                                 ch = i_peek(input);
5368                                                 if (!isxdigit(ch))
5369                                                         break;
5370                                                 *++p = ch = i_getch(input);
5371                                                 nommu_addchr(as_string, ch);
5372                                         } while (--cnt != 0);
5373                                         if (cnt == 2) { /* \x but next char is "bad" */
5374                                                 ch = 'x';
5375                                                 goto unrecognized;
5376                                         }
5377                                 } /* else simple seq like \\ or \t */
5378                                 *++p = '\0';
5379                                 p = buf;
5380                                 ch = bb_process_escape_sequence((void*)&p);
5381                                 //bb_error_msg("buf:'%s' ch:%x", buf, ch);
5382                                 if (ch == '\0')
5383                                         continue; /* bash compat: $'...\0...' emits nothing */
5384                         } else { /* unrecognized "\z": encode both chars unless ' or " */
5385                                 if (ch != '\'' && ch != '"') {
5386  unrecognized:
5387                                         o_addqchr(dest, '\\');
5388                                 }
5389                         }
5390                 } /* if (\...) */
5391                 o_addqchr(dest, ch);
5392         }
5393
5394         if (dest->length == start) {
5395                 /* $'', $'\0', $'\000\x00' and the like */
5396                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
5397                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
5398         }
5399
5400         return 1;
5401 # undef as_string
5402 }
5403 #else
5404 # define parse_dollar_squote(as_string, dest, input) 0
5405 #endif /* BASH_DOLLAR_SQUOTE */
5406 #endif /* !__U_BOOT__ */
5407
5408 /* Return code: 0 for OK, 1 for syntax error */
5409 #if BB_MMU
5410 #define parse_dollar(as_string, dest, input, quote_mask) \
5411         parse_dollar(dest, input, quote_mask)
5412 #define as_string NULL
5413 #endif
5414 static int parse_dollar(o_string *as_string,
5415                 o_string *dest,
5416                 struct in_str *input, unsigned char quote_mask)
5417 {
5418         int ch = i_peek_and_eat_bkslash_nl(input);  /* first character after the $ */
5419
5420         debug_printf_parse("parse_dollar entered: ch='%c' quote_mask:0x%x\n", ch, quote_mask);
5421         if (isalpha(ch)) {
5422  make_var:
5423                 ch = i_getch(input);
5424                 nommu_addchr(as_string, ch);
5425  /*make_var1:*/
5426                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
5427                 while (1) {
5428                         debug_printf_parse(": '%c'\n", ch);
5429                         o_addchr(dest, ch | quote_mask);
5430                         quote_mask = 0;
5431                         ch = i_peek_and_eat_bkslash_nl(input);
5432                         if (!isalnum(ch) && ch != '_') {
5433                                 /* End of variable name reached */
5434                                 break;
5435                         }
5436                         ch = i_getch(input);
5437                         nommu_addchr(as_string, ch);
5438                 }
5439                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
5440         } else if (isdigit(ch)) {
5441  make_one_char_var:
5442                 ch = i_getch(input);
5443                 nommu_addchr(as_string, ch);
5444                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
5445                 debug_printf_parse(": '%c'\n", ch);
5446                 o_addchr(dest, ch | quote_mask);
5447                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
5448         } else switch (ch) {
5449 #ifndef __U_BOOT__
5450         case '$': /* pid */
5451         case '!': /* last bg pid */
5452 #endif /* !__U_BOOT__ */
5453         case '?': /* last exit code */
5454         case '#': /* number of args */
5455         case '*': /* args */
5456         case '@': /* args */
5457         case '-': /* $- option flags set by set builtin or shell options (-i etc) */
5458                 goto make_one_char_var;
5459         case '{': {
5460                 char len_single_ch;
5461
5462                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
5463
5464                 ch = i_getch(input); /* eat '{' */
5465                 nommu_addchr(as_string, ch);
5466
5467                 ch = i_getch_and_eat_bkslash_nl(input); /* first char after '{' */
5468                 /* It should be ${?}, or ${#var},
5469                  * or even ${?+subst} - operator acting on a special variable,
5470                  * or the beginning of variable name.
5471                  */
5472                 if (ch == EOF
5473                  || (!strchr(_SPECIAL_VARS_STR, ch) && !isalnum(ch)) /* not one of those */
5474                 ) {
5475  bad_dollar_syntax:
5476                         syntax_error_unterm_str("${name}");
5477                         debug_printf_parse("parse_dollar return 0: unterminated ${name}\n");
5478                         return 0;
5479                 }
5480                 nommu_addchr(as_string, ch);
5481                 len_single_ch = ch;
5482                 ch |= quote_mask;
5483
5484                 /* It's possible to just call add_till_closing_bracket() at this point.
5485                  * However, this regresses some of our testsuite cases
5486                  * which check invalid constructs like ${%}.
5487                  * Oh well... let's check that the var name part is fine... */
5488
5489                 if (isdigit(len_single_ch)
5490                  || (len_single_ch == '#' && isdigit(i_peek_and_eat_bkslash_nl(input)))
5491                 ) {
5492                         /* Execution engine uses plain xatoi_positive()
5493                          * to interpret ${NNN} and {#NNN},
5494                          * check syntax here in the parser.
5495                          * (bash does not support expressions in ${#NN},
5496                          * e.g. ${#$var} and {#1:+WORD} are not supported).
5497                          */
5498                         unsigned cnt = 9; /* max 9 digits for ${NN} and 8 for {#NN} */
5499                         while (1) {
5500                                 o_addchr(dest, ch);
5501                                 debug_printf_parse(": '%c'\n", ch);
5502                                 ch = i_getch_and_eat_bkslash_nl(input);
5503                                 nommu_addchr(as_string, ch);
5504                                 if (ch == '}')
5505                                         break;
5506                                 if (--cnt == 0)
5507                                         goto bad_dollar_syntax;
5508                                 if (len_single_ch != '#' && strchr(VAR_SUBST_OPS, ch))
5509                                         /* ${NN<op>...} is valid */
5510                                         goto eat_until_closing;
5511                                 if (!isdigit(ch))
5512                                         goto bad_dollar_syntax;
5513                         }
5514                 } else
5515                 while (1) {
5516                         unsigned pos;
5517
5518                         o_addchr(dest, ch);
5519                         debug_printf_parse(": '%c'\n", ch);
5520
5521                         ch = i_getch(input);
5522                         nommu_addchr(as_string, ch);
5523                         if (ch == '}')
5524                                 break;
5525 #ifndef __U_BOOT__
5526                         if (!isalnum(ch) && ch != '_') {
5527 #else /* __U_BOOT__ */
5528                         /*
5529                          * In several places in U-Boot, we use variable like
5530                          * foo# (e.g. serial#), particularly in env.
5531                          * So, we need to authorize # to appear inside
5532                          * variable name and then expand this variable.
5533                          * NOTE Having # in variable name is not permitted in
5534                          * upstream hush but expansion will be done (even though
5535                          * the result will be empty).
5536                          */
5537                         if (!isalnum(ch) && ch != '_' && ch != '#') {
5538 #endif /* __U_BOOT__ */
5539                                 unsigned end_ch;
5540 #ifndef __U_BOOT__
5541                                 unsigned char last_ch;
5542 #endif /* !__U_BOOT__ */
5543                                 /* handle parameter expansions
5544                                  * http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_06_02
5545                                  */
5546                                 if (!strchr(VAR_SUBST_OPS, ch)) { /* ${var<bad_char>... */
5547                                         if (len_single_ch != '#'
5548                                         /*|| !strchr(SPECIAL_VARS_STR, ch) - disallow errors like ${#+} ? */
5549                                          || i_peek(input) != '}'
5550                                         ) {
5551                                                 goto bad_dollar_syntax;
5552                                         }
5553                                         /* else: it's "length of C" ${#C} op,
5554                                          * where C is a single char
5555                                          * special var name, e.g. ${#!}.
5556                                          */
5557                                 }
5558  eat_until_closing:
5559                                 /* Eat everything until closing '}' (or ':') */
5560                                 end_ch = '}';
5561 #ifndef __U_BOOT__
5562                                 if (BASH_SUBSTR
5563                                  && ch == ':'
5564                                  && !strchr(MINUS_PLUS_EQUAL_QUESTION, i_peek(input))
5565                                 ) {
5566                                         /* It's ${var:N[:M]} thing */
5567                                         end_ch = '}' * 0x100 + ':';
5568                                 }
5569                                 if (BASH_PATTERN_SUBST
5570                                  && ch == '/'
5571                                 ) {
5572                                         /* It's ${var/[/]pattern[/repl]} thing */
5573                                         if (i_peek(input) == '/') { /* ${var//pattern[/repl]}? */
5574                                                 i_getch(input);
5575                                                 nommu_addchr(as_string, '/');
5576                                                 ch = '\\';
5577                                         }
5578                                         end_ch = '}' * 0x100 + '/';
5579                                 }
5580 #endif /* !__U_BOOT__ */
5581                                 o_addchr(dest, ch);
5582                                 /* The pattern can't be empty.
5583                                  * IOW: if the first char after "${v//" is a slash,
5584                                  * it does not terminate the pattern - it's the first char of the pattern:
5585                                  *  v=/dev/ram; echo ${v////-}  prints -dev-ram (pattern is "/")
5586                                  *  v=/dev/ram; echo ${v///r/-} prints /dev-am  (pattern is "/r")
5587                                  */
5588                                 if (i_peek(input) == '/') {
5589                                         o_addchr(dest, i_getch(input));
5590                                 }
5591 #ifndef __U_BOOT__
5592  again:
5593 #endif /* !__U_BOOT__ */
5594                                 if (!BB_MMU)
5595                                         pos = dest->length;
5596 #if ENABLE_HUSH_DOLLAR_OPS
5597 #ifndef __U_BOOT__
5598                                 last_ch = add_till_closing_bracket(dest, input, end_ch);
5599                                 if (last_ch == 0) /* error? */
5600                                         return 0;
5601 #endif /* !__U_BOOT__ */
5602 #else
5603 # error Simple code to only allow ${var} is not implemented
5604 #endif
5605                                 if (as_string) {
5606                                         o_addstr(as_string, dest->data + pos);
5607 #ifndef __U_BOOT__
5608                                         o_addchr(as_string, last_ch);
5609 #endif /* !__U_BOOT__ */
5610                                 }
5611
5612 #ifndef __U_BOOT__
5613                                 if ((BASH_SUBSTR || BASH_PATTERN_SUBST)
5614                                          && (end_ch & 0xff00)
5615                                 ) {
5616                                         /* close the first block: */
5617                                         o_addchr(dest, SPECIAL_VAR_SYMBOL);
5618                                         /* while parsing N from ${var:N[:M]}
5619                                          * or pattern from ${var/[/]pattern[/repl]} */
5620                                         if ((end_ch & 0xff) == last_ch) {
5621                                                 /* got ':' or '/'- parse the rest */
5622                                                 end_ch = '}';
5623                                                 goto again;
5624                                         }
5625                                         /* got '}' */
5626                                         if (BASH_SUBSTR && end_ch == '}' * 0x100 + ':') {
5627                                                 /* it's ${var:N} - emulate :999999999 */
5628                                                 o_addstr(dest, "999999999");
5629                                         } /* else: it's ${var/[/]pattern} */
5630                                 }
5631 #endif /* !__U_BOOT__ */
5632                                 break;
5633                         }
5634                         len_single_ch = 0; /* it can't be ${#C} op */
5635                 }
5636                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
5637                 break;
5638         }
5639 #if ENABLE_FEATURE_SH_MATH || ENABLE_HUSH_TICK
5640         case '(': {
5641                 unsigned pos;
5642
5643                 ch = i_getch(input);
5644                 nommu_addchr(as_string, ch);
5645 # if ENABLE_FEATURE_SH_MATH
5646                 if (i_peek_and_eat_bkslash_nl(input) == '(') {
5647                         ch = i_getch(input);
5648                         nommu_addchr(as_string, ch);
5649                         o_addchr(dest, SPECIAL_VAR_SYMBOL);
5650                         o_addchr(dest, quote_mask | '+');
5651                         if (!BB_MMU)
5652                                 pos = dest->length;
5653                         if (!add_till_closing_bracket(dest, input, ')' | DOUBLE_CLOSE_CHAR_FLAG))
5654                                 return 0; /* error */
5655                         if (as_string) {
5656                                 o_addstr(as_string, dest->data + pos);
5657                                 o_addchr(as_string, ')');
5658                                 o_addchr(as_string, ')');
5659                         }
5660                         o_addchr(dest, SPECIAL_VAR_SYMBOL);
5661                         break;
5662                 }
5663 # endif
5664 # if ENABLE_HUSH_TICK
5665                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
5666                 o_addchr(dest, quote_mask | '`');
5667                 if (!BB_MMU)
5668                         pos = dest->length;
5669                 if (!add_till_closing_bracket(dest, input, ')'))
5670                         return 0; /* error */
5671                 if (as_string) {
5672                         o_addstr(as_string, dest->data + pos);
5673                         o_addchr(as_string, ')');
5674                 }
5675                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
5676 # endif
5677                 break;
5678         }
5679 #endif
5680         case '_':
5681                 goto make_var;
5682 #if 0
5683         /* TODO: $_: */
5684         /* $_ Shell or shell script name; or last argument of last command
5685          * (if last command wasn't a pipe; if it was, bash sets $_ to "");
5686          * but in command's env, set to full pathname used to invoke it */
5687                 ch = i_getch(input);
5688                 nommu_addchr(as_string, ch);
5689                 ch = i_peek_and_eat_bkslash_nl(input);
5690                 if (isalnum(ch)) { /* it's $_name or $_123 */
5691                         ch = '_';
5692                         goto make_var1;
5693                 }
5694                 /* else: it's $_ */
5695 #endif
5696         default:
5697                 o_addQchr(dest, '$');
5698         }
5699         debug_printf_parse("parse_dollar return 1 (ok)\n");
5700         return 1;
5701 #undef as_string
5702 }
5703
5704 #if BB_MMU
5705 #define encode_string(as_string, dest, input, dquote_end) \
5706         encode_string(dest, input, dquote_end)
5707 #define as_string NULL
5708 #endif
5709 static int encode_string(o_string *as_string,
5710                 o_string *dest,
5711                 struct in_str *input,
5712                 int dquote_end)
5713 {
5714         int ch;
5715         int next;
5716
5717  again:
5718         ch = i_getch(input);
5719         if (ch != EOF)
5720                 nommu_addchr(as_string, ch);
5721         if (ch == dquote_end) { /* may be only '"' or EOF */
5722                 debug_printf_parse("encode_string return 1 (ok)\n");
5723                 return 1;
5724         }
5725         /* note: can't move it above ch == dquote_end check! */
5726         if (ch == EOF) {
5727                 syntax_error_unterm_ch('"');
5728                 return 0; /* error */
5729         }
5730         next = '\0';
5731         if (ch != '\n') {
5732                 next = i_peek(input);
5733         }
5734         debug_printf_parse("\" ch=%c (%d) escape=%d\n",
5735                         ch, ch, !!(dest->o_expflags & EXP_FLAG_ESC_GLOB_CHARS));
5736         if (ch == '\\') {
5737                 if (next == EOF) {
5738                         /* Testcase: in interactive shell a file with
5739                          *  echo "unterminated string\<eof>
5740                          * is sourced.
5741                          */
5742                         syntax_error_unterm_ch('"');
5743                         return 0; /* error */
5744                 }
5745                 /* bash:
5746                  * "The backslash retains its special meaning [in "..."]
5747                  * only when followed by one of the following characters:
5748                  * $, `, ", \, or <newline>.  A double quote may be quoted
5749                  * within double quotes by preceding it with a backslash."
5750                  * NB: in (unquoted) heredoc, above does not apply to ",
5751                  * therefore we check for it by "next == dquote_end" cond.
5752                  */
5753                 if (next == dquote_end || strchr("$`\\\n", next)) {
5754                         ch = i_getch(input); /* eat next */
5755                         if (ch == '\n')
5756                                 goto again; /* skip \<newline> */
5757                 } /* else: ch remains == '\\', and we double it below: */
5758                 o_addqchr(dest, ch); /* \c if c is a glob char, else just c */
5759                 nommu_addchr(as_string, ch);
5760                 goto again;
5761         }
5762         if (ch == '$') {
5763                 //if (parse_dollar_squote(as_string, dest, input))
5764                 //      goto again;
5765                 if (!parse_dollar(as_string, dest, input, /*quote_mask:*/ 0x80)) {
5766                         debug_printf_parse("encode_string return 0: "
5767                                         "parse_dollar returned 0 (error)\n");
5768                         return 0;
5769                 }
5770                 goto again;
5771         }
5772 #if ENABLE_HUSH_TICK
5773         if (ch == '`') {
5774                 //unsigned pos = dest->length;
5775                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
5776                 o_addchr(dest, 0x80 | '`');
5777                 if (!add_till_backquote(dest, input, /*in_dquote:*/ dquote_end == '"'))
5778                         return 0; /* error */
5779                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
5780                 //debug_printf_subst("SUBST RES3 '%s'\n", dest->data + pos);
5781                 goto again;
5782         }
5783 #endif
5784         o_addQchr(dest, ch);
5785         if (ch == SPECIAL_VAR_SYMBOL) {
5786                 /* Convert "^C" to corresponding special variable reference */
5787                 o_addchr(dest, SPECIAL_VAR_QUOTED_SVS);
5788                 o_addchr(dest, SPECIAL_VAR_SYMBOL);
5789         }
5790         goto again;
5791 #undef as_string
5792 }
5793
5794 /*
5795  * Scan input until EOF or end_trigger char.
5796  * Return a list of pipes to execute, or NULL on EOF
5797  * or if end_trigger character is met.
5798  * On syntax error, exit if shell is not interactive,
5799  * reset parsing machinery and start parsing anew,
5800  * or return ERR_PTR.
5801  */
5802 static struct pipe *parse_stream(char **pstring,
5803                 int *heredoc_cnt_ptr,
5804                 struct in_str *input,
5805                 int end_trigger)
5806 {
5807         struct parse_context ctx;
5808         int heredoc_cnt;
5809
5810         /* Single-quote triggers a bypass of the main loop until its mate is
5811          * found.  When recursing, quote state is passed in via ctx.word.o_expflags.
5812          */
5813         debug_printf_parse("parse_stream entered, end_trigger='%c'\n",
5814                         end_trigger ? end_trigger : 'X');
5815         debug_enter();
5816
5817         initialize_context(&ctx);
5818
5819         /* If very first arg is "" or '', ctx.word.data may end up NULL.
5820          * Preventing this:
5821          */
5822         ctx.word.data = xzalloc(1); /* start as "", not as NULL */
5823
5824         /* We used to separate words on $IFS here. This was wrong.
5825          * $IFS is used only for word splitting when $var is expanded,
5826          * here we should use blank chars as separators, not $IFS
5827          */
5828
5829         heredoc_cnt = 0;
5830         while (1) {
5831                 const char *is_blank;
5832                 const char *is_special;
5833                 int ch;
5834                 int next;
5835 #ifndef __U_BOOT__
5836                 int redir_fd;
5837                 redir_type redir_style;
5838 #endif /* !__U_BOOT__ */
5839
5840                 ch = i_getch(input);
5841                 debug_printf_parse(": ch=%c (%d) escape=%d\n",
5842                                 ch, ch, !!(ctx.word.o_expflags & EXP_FLAG_ESC_GLOB_CHARS));
5843                 if (ch == EOF) {
5844                         struct pipe *pi;
5845
5846                         if (heredoc_cnt) {
5847                                 syntax_error_unterm_str("here document");
5848                                 goto parse_error_exitcode1;
5849                         }
5850                         if (end_trigger == ')') {
5851                                 syntax_error_unterm_ch('(');
5852                                 goto parse_error_exitcode1;
5853                         }
5854                         if (end_trigger == '}') {
5855                                 syntax_error_unterm_ch('{');
5856                                 goto parse_error_exitcode1;
5857                         }
5858
5859                         if (done_word(&ctx)) {
5860                                 goto parse_error_exitcode1;
5861                         }
5862                         o_free_and_set_NULL(&ctx.word);
5863                         done_pipe(&ctx, PIPE_SEQ);
5864
5865                         /* Do we sit inside of any if's, loops or case's? */
5866                         if (HAS_KEYWORDS
5867                         IF_HAS_KEYWORDS(&& (ctx.ctx_res_w != RES_NONE || ctx.old_flag != 0))
5868                         ) {
5869                                 syntax_error_unterm_str("compound statement");
5870                                 goto parse_error_exitcode1;
5871                         }
5872
5873                         pi = ctx.list_head;
5874                         /* If we got nothing... */
5875                         /* (this makes bare "&" cmd a no-op.
5876                          * bash says: "syntax error near unexpected token '&'") */
5877                         if (pi->num_cmds == 0
5878                         IF_HAS_KEYWORDS(&& pi->res_word == RES_NONE)
5879                         ) {
5880                                 free_pipe_list(pi);
5881                                 pi = NULL;
5882                         }
5883 #if !BB_MMU
5884                         debug_printf_parse("as_string1 '%s'\n", ctx.as_string.data);
5885                         if (pstring)
5886                                 *pstring = ctx.as_string.data;
5887                         else
5888                                 o_free(&ctx.as_string);
5889 #endif
5890                         // heredoc_cnt must be 0 here anyway
5891                         //if (heredoc_cnt_ptr)
5892                         //      *heredoc_cnt_ptr = heredoc_cnt;
5893                         debug_leave();
5894                         debug_printf_heredoc("parse_stream return heredoc_cnt:%d\n", heredoc_cnt);
5895                         debug_printf_parse("parse_stream return %p: EOF\n", pi);
5896                         return pi;
5897                 }
5898
5899                 /* Handle "'" and "\" first, as they won't play nice with
5900                  * i_peek_and_eat_bkslash_nl() anyway:
5901                  *   echo z\\
5902                  * and
5903                  *   echo '\
5904                  *   '
5905                  * would break.
5906                  */
5907                 if (ch == '\\') {
5908                         ch = i_getch(input);
5909                         if (ch == '\n')
5910                                 continue; /* drop \<newline>, get next char */
5911                         nommu_addchr(&ctx.as_string, '\\');
5912                         if (ch == SPECIAL_VAR_SYMBOL) {
5913                                 nommu_addchr(&ctx.as_string, ch);
5914                                 /* Convert \^C to corresponding special variable reference */
5915                                 goto case_SPECIAL_VAR_SYMBOL;
5916                         }
5917                         o_addchr(&ctx.word, '\\');
5918                         if (ch == EOF) {
5919                                 /* Testcase: eval 'echo Ok\' */
5920                                 /* bash-4.3.43 was removing backslash,
5921                                  * but 4.4.19 retains it, most other shells too
5922                                  */
5923                                 continue; /* get next char */
5924                         }
5925                         /* Example: echo Hello \2>file
5926                          * we need to know that word 2 is quoted
5927                          */
5928                         ctx.word.has_quoted_part = 1;
5929                         nommu_addchr(&ctx.as_string, ch);
5930                         o_addchr(&ctx.word, ch);
5931                         continue; /* get next char */
5932                 }
5933                 nommu_addchr(&ctx.as_string, ch);
5934                 if (ch == '\'') {
5935                         ctx.word.has_quoted_part = 1;
5936                         next = i_getch(input);
5937 #ifndef __U_BOOT__
5938                         if (next == '\'' && !ctx.pending_redirect)
5939                                 goto insert_empty_quoted_str_marker;
5940 #endif /* !__U_BOOT__ */
5941
5942                         ch = next;
5943                         while (1) {
5944                                 if (ch == EOF) {
5945                                         syntax_error_unterm_ch('\'');
5946                                         goto parse_error_exitcode1;
5947                                 }
5948                                 nommu_addchr(&ctx.as_string, ch);
5949                                 if (ch == '\'')
5950                                         break;
5951                                 if (ch == SPECIAL_VAR_SYMBOL) {
5952                                         /* Convert raw ^C to corresponding special variable reference */
5953                                         o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
5954                                         o_addchr(&ctx.word, SPECIAL_VAR_QUOTED_SVS);
5955                                 }
5956                                 o_addqchr(&ctx.word, ch);
5957                                 ch = i_getch(input);
5958                         }
5959                         continue; /* get next char */
5960                 }
5961
5962                 next = '\0';
5963                 if (ch != '\n')
5964                         next = i_peek_and_eat_bkslash_nl(input);
5965
5966                 is_special = "{}<>&|();#" /* special outside of "str" */
5967 #ifndef __U_BOOT__
5968                                 "$\"" IF_HUSH_TICK("`") /* always special */
5969 #else /* __U_BOOT__ */
5970                                 "$\""
5971 #endif /* __U_BOOT__ */
5972                                 SPECIAL_VAR_SYMBOL_STR;
5973 #if defined(CMD_TEST2_SINGLEWORD_NOGLOB)
5974                 if (ctx.command->cmd_type == CMD_TEST2_SINGLEWORD_NOGLOB) {
5975                         /* In [[ ]], {}<>&|() are not special */
5976                         is_special += 8;
5977                 } else
5978 #endif
5979                 /* Are { and } special here? */
5980                 if (ctx.command->argv /* word [word]{... - non-special */
5981                  || ctx.word.length       /* word{... - non-special */
5982                  || ctx.word.has_quoted_part     /* ""{... - non-special */
5983                  || (next != ';'             /* }; - special */
5984                     && next != ')'           /* }) - special */
5985                     && next != '('           /* {( - special */
5986                     && next != '&'           /* }& and }&& ... - special */
5987                     && next != '|'           /* }|| ... - special */
5988                     && !strchr(defifs, next) /* {word - non-special */
5989                     )
5990                 ) {
5991                         /* They are not special, skip "{}" */
5992                         is_special += 2;
5993                 }
5994                 is_special = strchr(is_special, ch);
5995                 is_blank = strchr(defifs, ch);
5996
5997                 if (!is_special && !is_blank) { /* ordinary char */
5998  ordinary_char:
5999                         o_addQchr(&ctx.word, ch);
6000                         if ((ctx.is_assignment == MAYBE_ASSIGNMENT
6001                             || ctx.is_assignment == WORD_IS_KEYWORD)
6002                          && ch == '='
6003                          && endofname(ctx.word.data)[0] == '='
6004                         ) {
6005                                 ctx.is_assignment = DEFINITELY_ASSIGNMENT;
6006                                 debug_printf_parse("ctx.is_assignment='%s'\n", assignment_flag[ctx.is_assignment]);
6007                         }
6008                         continue;
6009                 }
6010
6011                 if (is_blank) {
6012 #if ENABLE_HUSH_LINENO_VAR
6013 /* Case:
6014  * "while ...; do<whitespace><newline>
6015  *      cmd ..."
6016  * would think that "cmd" starts in <whitespace> -
6017  * i.e., at the previous line.
6018  * We need to skip all whitespace before newlines.
6019  */
6020                         while (ch != '\n') {
6021                                 next = i_peek(input);
6022                                 if (next != ' ' && next != '\t' && next != '\n')
6023                                         break; /* next char is not ws */
6024                                 ch = i_getch(input);
6025                         }
6026                         /* ch == last eaten whitespace char */
6027 #endif
6028                         if (done_word(&ctx)) {
6029                                 goto parse_error_exitcode1;
6030                         }
6031                         if (ch == '\n') {
6032                                 /* Is this a case when newline is simply ignored?
6033                                  * Some examples:
6034                                  * "cmd | <newline> cmd ..."
6035                                  * "case ... in <newline> word) ..."
6036                                  */
6037                                 if (IS_NULL_CMD(ctx.command)
6038                                  && ctx.word.length == 0
6039                                  && !ctx.word.has_quoted_part
6040                                  && heredoc_cnt == 0
6041                                 ) {
6042                                         /* This newline can be ignored. But...
6043                                          * Without check #1, interactive shell
6044                                          * ignores even bare <newline>,
6045                                          * and shows the continuation prompt:
6046                                          * ps1_prompt$ <enter>
6047                                          * ps2> _   <=== wrong, should be ps1
6048                                          * Without check #2, "cmd & <newline>"
6049                                          * is similarly mistreated.
6050                                          * (BTW, this makes "cmd & cmd"
6051                                          * and "cmd && cmd" non-orthogonal.
6052                                          * Really, ask yourself, why
6053                                          * "cmd && <newline>" doesn't start
6054                                          * cmd but waits for more input?
6055                                          * The only reason is that it might be
6056                                          * a "cmd1 && <nl> cmd2 &" construct,
6057                                          * cmd1 may need to run in BG).
6058                                          */
6059                                         struct pipe *pi = ctx.list_head;
6060                                         if (pi->num_cmds != 0       /* check #1 */
6061                                          && pi->followup != PIPE_BG /* check #2 */
6062                                         ) {
6063                                                 continue;
6064                                         }
6065                                 }
6066                                 /* Treat newline as a command separator. */
6067                                 done_pipe(&ctx, PIPE_SEQ);
6068                                 debug_printf_heredoc("heredoc_cnt:%d\n", heredoc_cnt);
6069                                 if (heredoc_cnt) {
6070                                         heredoc_cnt = fetch_heredocs(&ctx.as_string, ctx.list_head, heredoc_cnt, input);
6071                                         if (heredoc_cnt != 0)
6072                                                 goto parse_error_exitcode1;
6073                                 }
6074                                 ctx.is_assignment = MAYBE_ASSIGNMENT;
6075                                 debug_printf_parse("ctx.is_assignment='%s'\n", assignment_flag[ctx.is_assignment]);
6076                                 ch = ';';
6077                                 /* note: if (is_blank) continue;
6078                                  * will still trigger for us */
6079                         }
6080                 }
6081
6082                 /* "cmd}" or "cmd }..." without semicolon or &:
6083                  * } is an ordinary char in this case, even inside { cmd; }
6084                  * Pathological example: { ""}; } should exec "}" cmd
6085                  */
6086 #ifndef __U_BOOT__
6087                 if (ch == '}') {
6088 #else /* __U_BOOT__ */
6089                 if (ch == '}' || ch == ')') {
6090 #endif /* __U_BOOT__ */
6091                         if (ctx.word.length != 0 /* word} */
6092                          || ctx.word.has_quoted_part    /* ""} */
6093                         ) {
6094                                 goto ordinary_char;
6095                         }
6096                         if (!IS_NULL_CMD(ctx.command)) { /* cmd } */
6097                                 /* Generally, there should be semicolon: "cmd; }"
6098                                  * However, bash allows to omit it if "cmd" is
6099                                  * a group. Examples:
6100                                  * { { echo 1; } }
6101                                  * {(echo 1)}
6102                                  * { echo 0 >&2 | { echo 1; } }
6103                                  * { while false; do :; done }
6104                                  * { case a in b) ;; esac }
6105                                  */
6106                                 if (ctx.command->group)
6107                                         goto term_group;
6108                                 goto ordinary_char;
6109                         }
6110                         if (!IS_NULL_PIPE(ctx.pipe)) /* cmd | } */
6111                                 /* Can't be an end of {cmd}, skip the check */
6112                                 goto skip_end_trigger;
6113                         /* else: } does terminate a group */
6114                 }
6115  term_group:
6116                 if (end_trigger && end_trigger == ch
6117                  && (ch != ';' || heredoc_cnt == 0)
6118 #if ENABLE_HUSH_CASE
6119                  && (ch != ')'
6120                     || ctx.ctx_res_w != RES_MATCH
6121                     || (!ctx.word.has_quoted_part && strcmp(ctx.word.data, "esac") == 0)
6122                     )
6123 #endif
6124                 ) {
6125                         if (done_word(&ctx)) {
6126                                 goto parse_error_exitcode1;
6127                         }
6128                         done_pipe(&ctx, PIPE_SEQ);
6129                         ctx.is_assignment = MAYBE_ASSIGNMENT;
6130                         debug_printf_parse("ctx.is_assignment='%s'\n", assignment_flag[ctx.is_assignment]);
6131                         /* Do we sit outside of any if's, loops or case's? */
6132                         if (!HAS_KEYWORDS
6133                         IF_HAS_KEYWORDS(|| (ctx.ctx_res_w == RES_NONE && ctx.old_flag == 0))
6134                         ) {
6135                                 o_free_and_set_NULL(&ctx.word);
6136 #if !BB_MMU
6137                                 debug_printf_parse("as_string2 '%s'\n", ctx.as_string.data);
6138                                 if (pstring)
6139                                         *pstring = ctx.as_string.data;
6140                                 else
6141                                         o_free(&ctx.as_string);
6142 #endif
6143                                 if (ch != ';' && IS_NULL_PIPE(ctx.list_head)) {
6144                                         /* Example: bare "{ }", "()" */
6145                                         G.last_exitcode = 2; /* bash compat */
6146                                         syntax_error_unexpected_ch(ch);
6147                                         goto parse_error;
6148                                 }
6149                                 if (heredoc_cnt_ptr)
6150                                         *heredoc_cnt_ptr = heredoc_cnt;
6151                                 debug_printf_heredoc("parse_stream return heredoc_cnt:%d\n", heredoc_cnt);
6152                                 debug_printf_parse("parse_stream return %p: "
6153                                                 "end_trigger char found\n",
6154                                                 ctx.list_head);
6155                                 debug_leave();
6156                                 return ctx.list_head;
6157                         }
6158                 }
6159
6160                 if (is_blank)
6161                         continue;
6162
6163                 /* Catch <, > before deciding whether this word is
6164                  * an assignment. a=1 2>z b=2: b=2 is still assignment */
6165                 switch (ch) {
6166 #ifndef __U_BOOT__
6167                 case '>':
6168                         redir_fd = redirect_opt_num(&ctx.word);
6169                         if (done_word(&ctx)) {
6170                                 goto parse_error_exitcode1;
6171                         }
6172                         redir_style = REDIRECT_OVERWRITE;
6173                         if (next == '>') {
6174                                 redir_style = REDIRECT_APPEND;
6175                                 ch = i_getch(input);
6176                                 nommu_addchr(&ctx.as_string, ch);
6177                         }
6178 #if 0
6179                         else if (next == '(') {
6180                                 syntax_error(">(process) not supported");
6181                                 goto parse_error_exitcode1;
6182                         }
6183 #endif
6184                         if (parse_redirect(&ctx, redir_fd, redir_style, input))
6185                                 goto parse_error_exitcode1;
6186                         continue; /* get next char */
6187                 case '<':
6188                         redir_fd = redirect_opt_num(&ctx.word);
6189                         if (done_word(&ctx)) {
6190                                 goto parse_error_exitcode1;
6191                         }
6192                         redir_style = REDIRECT_INPUT;
6193                         if (next == '<') {
6194                                 redir_style = REDIRECT_HEREDOC;
6195                                 heredoc_cnt++;
6196                                 debug_printf_heredoc("++heredoc_cnt=%d\n", heredoc_cnt);
6197                                 ch = i_getch(input);
6198                                 nommu_addchr(&ctx.as_string, ch);
6199                         } else if (next == '>') {
6200                                 redir_style = REDIRECT_IO;
6201                                 ch = i_getch(input);
6202                                 nommu_addchr(&ctx.as_string, ch);
6203                         }
6204 #if 0
6205                         else if (next == '(') {
6206                                 syntax_error("<(process) not supported");
6207                                 goto parse_error_exitcode1;
6208                         }
6209 #endif
6210                         if (parse_redirect(&ctx, redir_fd, redir_style, input))
6211                                 goto parse_error_exitcode1;
6212                         continue; /* get next char */
6213 #else /* __U_BOOT__ */
6214                         /*
6215                          * In U-Boot, '<' and '>' can be used in test command to test if
6216                          * a string is, alphabetically, before or after another.
6217                          * In 2021 Busybox hush, we will keep the same behavior and so not treat
6218                          * them as redirection operator.
6219                          *
6220                          * Indeed, in U-Boot, tests are handled by the test command and not by the
6221                          * shell code.
6222                          * So, better to give this character as input to test command.
6223                          *
6224                          * NOTE In my opinion, when you use '<' or '>' I am almost sure
6225                          * you wanted to use "-gt" or "-lt" in place, so thinking to
6226                          * escape these will make you should check your code (sh syntax
6227                          * at this level is, for me, error prone).
6228                          */
6229                         case '>':
6230                                 fallthrough;
6231                         case '<':
6232                                 o_addQchr(&ctx.word, ch);
6233                                 continue;
6234 #endif /* __U_BOOT__ */
6235                 case '#':
6236                         if (ctx.word.length == 0 && !ctx.word.has_quoted_part) {
6237                                 /* skip "#comment" */
6238                                 /* note: we do not add it to &ctx.as_string */
6239 /* TODO: in bash:
6240  * comment inside $() goes to the next \n, even inside quoted string (!):
6241  * cmd "$(cmd2 #comment)" - syntax error
6242  * cmd "`cmd2 #comment`" - ok
6243  * We accept both (comment ends where command subst ends, in both cases).
6244  */
6245                                 while (1) {
6246                                         ch = i_peek(input);
6247                                         if (ch == '\n') {
6248                                                 nommu_addchr(&ctx.as_string, '\n');
6249                                                 break;
6250                                         }
6251                                         ch = i_getch(input);
6252                                         if (ch == EOF)
6253                                                 break;
6254                                 }
6255                                 continue; /* get next char */
6256                         }
6257                         break;
6258                 }
6259  skip_end_trigger:
6260
6261                 if (ctx.is_assignment == MAYBE_ASSIGNMENT
6262 #ifndef __U_BOOT__
6263                  /* check that we are not in word in "a=1 2>word b=1": */
6264                  && !ctx.pending_redirect
6265 #endif /* !__U_BOOT__ */
6266                 ) {
6267                         /* ch is a special char and thus this word
6268                          * cannot be an assignment */
6269                         ctx.is_assignment = NOT_ASSIGNMENT;
6270                         debug_printf_parse("ctx.is_assignment='%s'\n", assignment_flag[ctx.is_assignment]);
6271                 }
6272
6273                 /* Note: nommu_addchr(&ctx.as_string, ch) is already done */
6274
6275                 switch (ch) {
6276                 case_SPECIAL_VAR_SYMBOL:
6277                 case SPECIAL_VAR_SYMBOL:
6278                         /* Convert raw ^C to corresponding special variable reference */
6279                         o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
6280                         o_addchr(&ctx.word, SPECIAL_VAR_QUOTED_SVS);
6281                         /* fall through */
6282                 case '#':
6283                         /* non-comment #: "echo a#b" etc */
6284                         o_addchr(&ctx.word, ch);
6285                         continue; /* get next char */
6286                 case '$':
6287 #ifndef __U_BOOT__
6288                         if (parse_dollar_squote(&ctx.as_string, &ctx.word, input))
6289                                 continue; /* get next char */
6290 #endif /* !__U_BOOT__ */
6291                         if (!parse_dollar(&ctx.as_string, &ctx.word, input, /*quote_mask:*/ 0)) {
6292                                 debug_printf_parse("parse_stream parse error: "
6293                                         "parse_dollar returned 0 (error)\n");
6294                                 goto parse_error_exitcode1;
6295                         }
6296                         continue; /* get next char */
6297                 case '"':
6298                         ctx.word.has_quoted_part = 1;
6299 #ifndef __U_BOOT__
6300                         if (next == '"' && !ctx.pending_redirect) {
6301 #else /* __U_BOOT__ */
6302                         if (next == '"') {
6303 #endif /* __U_BOOT__ */
6304                                 i_getch(input); /* eat second " */
6305 #ifndef __U_BOOT__
6306  insert_empty_quoted_str_marker:
6307 #endif /* !__U_BOOT__ */
6308                                 nommu_addchr(&ctx.as_string, next);
6309                                 o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
6310                                 o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
6311                                 continue; /* get next char */
6312                         }
6313                         if (ctx.is_assignment == NOT_ASSIGNMENT)
6314                                 ctx.word.o_expflags |= EXP_FLAG_ESC_GLOB_CHARS;
6315                         if (!encode_string(&ctx.as_string, &ctx.word, input, '"'))
6316                                 goto parse_error_exitcode1;
6317                         ctx.word.o_expflags &= ~EXP_FLAG_ESC_GLOB_CHARS;
6318                         continue; /* get next char */
6319 #if ENABLE_HUSH_TICK
6320                 case '`': {
6321                         USE_FOR_NOMMU(unsigned pos;)
6322
6323                         o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
6324                         o_addchr(&ctx.word, '`');
6325                         USE_FOR_NOMMU(pos = ctx.word.length;)
6326                         if (!add_till_backquote(&ctx.word, input, /*in_dquote:*/ 0))
6327                                 goto parse_error_exitcode1;
6328 # if !BB_MMU
6329                         o_addstr(&ctx.as_string, ctx.word.data + pos);
6330                         o_addchr(&ctx.as_string, '`');
6331 # endif
6332                         o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
6333                         //debug_printf_subst("SUBST RES3 '%s'\n", ctx.word.data + pos);
6334                         continue; /* get next char */
6335                 }
6336 #endif
6337                 case ';':
6338 #if ENABLE_HUSH_CASE
6339  case_semi:
6340 #endif
6341                         if (done_word(&ctx)) {
6342                                 goto parse_error_exitcode1;
6343                         }
6344                         done_pipe(&ctx, PIPE_SEQ);
6345 #if ENABLE_HUSH_CASE
6346                         /* Eat multiple semicolons, detect
6347                          * whether it means something special */
6348                         while (1) {
6349                                 ch = i_peek_and_eat_bkslash_nl(input);
6350                                 if (ch != ';')
6351                                         break;
6352                                 ch = i_getch(input);
6353                                 nommu_addchr(&ctx.as_string, ch);
6354                                 if (ctx.ctx_res_w == RES_CASE_BODY) {
6355                                         ctx.ctx_dsemicolon = 1;
6356                                         ctx.ctx_res_w = RES_MATCH;
6357                                         break;
6358                                 }
6359                         }
6360 #endif
6361  new_cmd:
6362                         /* We just finished a cmd. New one may start
6363                          * with an assignment */
6364                         ctx.is_assignment = MAYBE_ASSIGNMENT;
6365                         debug_printf_parse("ctx.is_assignment='%s'\n", assignment_flag[ctx.is_assignment]);
6366                         continue; /* get next char */
6367                 case '&':
6368                         if (done_word(&ctx)) {
6369                                 goto parse_error_exitcode1;
6370                         }
6371                         if (next == '&') {
6372                                 ch = i_getch(input);
6373                                 nommu_addchr(&ctx.as_string, ch);
6374                                 done_pipe(&ctx, PIPE_AND);
6375                         } else {
6376                                 done_pipe(&ctx, PIPE_BG);
6377                         }
6378                         goto new_cmd;
6379                 case '|':
6380                         if (done_word(&ctx)) {
6381                                 goto parse_error_exitcode1;
6382                         }
6383 #if ENABLE_HUSH_CASE
6384                         if (ctx.ctx_res_w == RES_MATCH)
6385                                 break; /* we are in case's "word | word)" */
6386 #endif
6387                         if (next == '|') { /* || */
6388                                 ch = i_getch(input);
6389                                 nommu_addchr(&ctx.as_string, ch);
6390                                 done_pipe(&ctx, PIPE_OR);
6391                         } else {
6392                                 /* we could pick up a file descriptor choice here
6393                                  * with redirect_opt_num(), but bash doesn't do it.
6394                                  * "echo foo 2| cat" yields "foo 2". */
6395                                 done_command(&ctx);
6396                         }
6397                         goto new_cmd;
6398                 case '(':
6399 #if ENABLE_HUSH_CASE
6400                         /* "case... in [(]word)..." - skip '(' */
6401                         if (ctx.ctx_res_w == RES_MATCH
6402                          && ctx.command->argv == NULL /* not (word|(... */
6403                          && ctx.word.length == 0 /* not word(... */
6404                          && ctx.word.has_quoted_part == 0 /* not ""(... */
6405                         ) {
6406                                 continue; /* get next char */
6407                         }
6408 #endif
6409                         /* fall through */
6410                 case '{': {
6411                         int n = parse_group(&ctx, input, ch);
6412                         if (n < 0) {
6413                                 goto parse_error_exitcode1;
6414                         }
6415                         debug_printf_heredoc("parse_group done, needs heredocs:%d\n", n);
6416                         heredoc_cnt += n;
6417                         goto new_cmd;
6418                 }
6419                 case ')':
6420 #if ENABLE_HUSH_CASE
6421                         if (ctx.ctx_res_w == RES_MATCH)
6422                                 goto case_semi;
6423 #endif
6424                 case '}':
6425                         /* proper use of this character is caught by end_trigger:
6426                          * if we see {, we call parse_group(..., end_trigger='}')
6427                          * and it will match } earlier (not here). */
6428                         G.last_exitcode = 2;
6429                         syntax_error_unexpected_ch(ch);
6430                         goto parse_error;
6431                 default:
6432                         if (HUSH_DEBUG)
6433                                 bb_error_msg_and_die("BUG: unexpected %c", ch);
6434                 }
6435         } /* while (1) */
6436
6437  parse_error_exitcode1:
6438         G.last_exitcode = 1;
6439  parse_error:
6440         {
6441                 struct parse_context *pctx;
6442                 IF_HAS_KEYWORDS(struct parse_context *p2;)
6443
6444                 /* Clean up allocated tree.
6445                  * Sample for finding leaks on syntax error recovery path.
6446                  * Run it from interactive shell, watch pmap `pidof hush`.
6447                  * while if false; then false; fi; do break; fi
6448                  * Samples to catch leaks at execution:
6449                  * while if (true | { true;}); then echo ok; fi; do break; done
6450                  * while if (true | { true;}); then echo ok; fi; do (if echo ok; break; then :; fi) | cat; break; done
6451                  */
6452                 pctx = &ctx;
6453                 do {
6454                         /* Update pipe/command counts,
6455                          * otherwise freeing may miss some */
6456                         done_pipe(pctx, PIPE_SEQ);
6457                         debug_printf_clean("freeing list %p from ctx %p\n",
6458                                         pctx->list_head, pctx);
6459                         debug_print_tree(pctx->list_head, 0);
6460                         free_pipe_list(pctx->list_head);
6461                         debug_printf_clean("freed list %p\n", pctx->list_head);
6462 #if !BB_MMU
6463                         o_free(&pctx->as_string);
6464 #endif
6465                         IF_HAS_KEYWORDS(p2 = pctx->stack;)
6466                         if (pctx != &ctx) {
6467                                 free(pctx);
6468                         }
6469                         IF_HAS_KEYWORDS(pctx = p2;)
6470                 } while (HAS_KEYWORDS && pctx);
6471
6472                 o_free(&ctx.word);
6473 #if !BB_MMU
6474                 if (pstring)
6475                         *pstring = NULL;
6476 #endif
6477                 debug_leave();
6478                 return ERR_PTR;
6479         }
6480 }
6481
6482 /*** Execution routines ***/
6483
6484 /* Expansion can recurse, need forward decls: */
6485 #if !BASH_PATTERN_SUBST && !ENABLE_HUSH_CASE
6486 #define expand_string_to_string(str, EXP_flags, do_unbackslash) \
6487         expand_string_to_string(str)
6488 #endif
6489 static char *expand_string_to_string(const char *str, int EXP_flags, int do_unbackslash);
6490 #if ENABLE_HUSH_TICK
6491 static int process_command_subs(o_string *dest, const char *s);
6492 #endif
6493 static int expand_vars_to_list(o_string *output, int n, char *arg);
6494
6495 /* expand_strvec_to_strvec() takes a list of strings, expands
6496  * all variable references within and returns a pointer to
6497  * a list of expanded strings, possibly with larger number
6498  * of strings. (Think VAR="a b"; echo $VAR).
6499  * This new list is allocated as a single malloc block.
6500  * NULL-terminated list of char* pointers is at the beginning of it,
6501  * followed by strings themselves.
6502  * Caller can deallocate entire list by single free(list). */
6503
6504 /* A horde of its helpers come first: */
6505
6506 static void o_addblock_duplicate_backslash(o_string *o, const char *str, int len)
6507 {
6508         while (--len >= 0) {
6509                 char c = *str++;
6510
6511 #if ENABLE_HUSH_BRACE_EXPANSION
6512                 if (c == '{' || c == '}') {
6513                         /* { -> \{, } -> \} */
6514                         o_addchr(o, '\\');
6515                         /* And now we want to add { or } and continue:
6516                          *  o_addchr(o, c);
6517                          *  continue;
6518                          * luckily, just falling through achieves this.
6519                          */
6520                 }
6521 #endif
6522                 o_addchr(o, c);
6523                 if (c == '\\') {
6524                         /* \z -> \\\z; \<eol> -> \\<eol> */
6525                         o_addchr(o, '\\');
6526                         if (len) {
6527                                 len--;
6528                                 o_addchr(o, '\\');
6529                                 o_addchr(o, *str++);
6530                         }
6531                 }
6532         }
6533 }
6534
6535 /* Store given string, finalizing the word and starting new one whenever
6536  * we encounter IFS char(s). This is used for expanding variable values.
6537  * End-of-string does NOT finalize word: think about 'echo -$VAR-'.
6538  * Return in output->ended_in_ifs:
6539  * 1 - ended with IFS char, else 0 (this includes case of empty str).
6540  */
6541 static int expand_on_ifs(o_string *output, int n, const char *str)
6542 {
6543         int last_is_ifs = 0;
6544
6545         while (1) {
6546                 int word_len;
6547
6548                 if (!*str)  /* EOL - do not finalize word */
6549                         break;
6550                 word_len = strcspn(str, G.ifs);
6551                 if (word_len) {
6552                         /* We have WORD_LEN leading non-IFS chars */
6553                         if (!(output->o_expflags & EXP_FLAG_GLOB)) {
6554                                 o_addblock(output, str, word_len);
6555                         } else {
6556                                 /* Protect backslashes against globbing up :)
6557                                  * Example: "v='\*'; echo b$v" prints "b\*"
6558                                  * (and does not try to glob on "*")
6559                                  */
6560                                 o_addblock_duplicate_backslash(output, str, word_len);
6561                                 /*/ Why can't we do it easier? */
6562                                 /*o_addblock(output, str, word_len); - WRONG: "v='\*'; echo Z$v" prints "Z*" instead of "Z\*" */
6563                                 /*o_addqblock(output, str, word_len); - WRONG: "v='*'; echo Z$v" prints "Z*" instead of Z* files */
6564                         }
6565                         last_is_ifs = 0;
6566                         str += word_len;
6567                         if (!*str)  /* EOL - do not finalize word */
6568                                 break;
6569                 }
6570
6571                 /* We know str here points to at least one IFS char */
6572                 last_is_ifs = 1;
6573                 str += strspn(str, G.ifs_whitespace); /* skip IFS whitespace chars */
6574                 if (!*str)  /* EOL - do not finalize word */
6575                         break;
6576
6577                 if (G.ifs_whitespace != G.ifs /* usually false ($IFS is usually all whitespace), */
6578                  && strchr(G.ifs, *str)       /* the second check would fail */
6579                 ) {
6580                         /* This is a non-whitespace $IFS char */
6581                         /* Skip it and IFS whitespace chars, start new word */
6582                         str++;
6583                         str += strspn(str, G.ifs_whitespace);
6584                         goto new_word;
6585                 }
6586
6587                 /* Start new word... but not always! */
6588                 /* Case "v=' a'; echo ''$v": we do need to finalize empty word: */
6589                 if (output->has_quoted_part
6590                 /*
6591                  * Case "v=' a'; echo $v":
6592                  * here nothing precedes the space in $v expansion,
6593                  * therefore we should not finish the word
6594                  * (IOW: if there *is* word to finalize, only then do it):
6595                  * It's okay if this accesses the byte before first argv[]:
6596                  * past call to o_save_ptr() cleared it to zero byte
6597                  * (grep for -prev-ifs-check-).
6598                  */
6599                  || output->data[output->length - 1]
6600                 ) {
6601  new_word:
6602                         o_addchr(output, '\0');
6603                         debug_print_list("expand_on_ifs", output, n);
6604                         n = o_save_ptr(output, n);
6605                 }
6606         }
6607
6608         output->ended_in_ifs = last_is_ifs;
6609         debug_print_list("expand_on_ifs[1]", output, n);
6610         return n;
6611 }
6612
6613 #ifndef __U_BOOT__
6614 /* Helper to expand $((...)) and heredoc body. These act as if
6615  * they are in double quotes, with the exception that they are not :).
6616  * Just the rules are similar: "expand only $var and `cmd`"
6617  *
6618  * Returns malloced string.
6619  * As an optimization, we return NULL if expansion is not needed.
6620  */
6621 static char *encode_then_expand_string(const char *str)
6622 {
6623         char *exp_str;
6624         struct in_str input;
6625         o_string dest = NULL_O_STRING;
6626         const char *cp;
6627
6628         cp = str;
6629         for (;;) {
6630                 if (!*cp) return NULL; /* string has no special chars */
6631                 if (*cp == '$') break;
6632                 if (*cp == '\\') break;
6633 #if ENABLE_HUSH_TICK
6634                 if (*cp == '`') break;
6635 #endif
6636                 cp++;
6637         }
6638
6639         /* We need to expand. Example:
6640          * echo $(($a + `echo 1`)) $((1 + $((2)) ))
6641          */
6642         setup_string_in_str(&input, str);
6643         encode_string(NULL, &dest, &input, EOF);
6644 //TODO: error check (encode_string returns 0 on error)?
6645         //bb_error_msg("'%s' -> '%s'", str, dest.data);
6646         exp_str = expand_string_to_string(dest.data,
6647                         EXP_FLAG_ESC_GLOB_CHARS,
6648                         /*unbackslash:*/ 1
6649         );
6650         //bb_error_msg("'%s' -> '%s'", dest.data, exp_str);
6651         o_free(&dest);
6652         return exp_str;
6653 }
6654
6655 static const char *first_special_char_in_vararg(const char *cp)
6656 {
6657         for (;;) {
6658                 if (!*cp) return NULL; /* string has no special chars */
6659                 if (*cp == '$') return cp;
6660                 if (*cp == '\\') return cp;
6661                 if (*cp == '\'') return cp;
6662                 if (*cp == '"') return cp;
6663 #if ENABLE_HUSH_TICK
6664                 if (*cp == '`') return cp;
6665 #endif
6666                 /* dquoted "${x:+ARG}" should not glob, therefore
6667                  * '*' et al require some non-literal processing: */
6668                 if (*cp == '*') return cp;
6669                 if (*cp == '?') return cp;
6670                 if (*cp == '[') return cp;
6671                 cp++;
6672         }
6673 }
6674
6675 /* Expanding ARG in ${var#ARG}, ${var%ARG}, or ${var/ARG/ARG}.
6676  * These can contain single- and double-quoted strings,
6677  * and treated as if the ARG string is initially unquoted. IOW:
6678  * ${var#ARG} and "${var#ARG}" treat ARG the same (ARG can even be
6679  * a dquoted string: "${var#"zz"}"), the difference only comes later
6680  * (word splitting and globbing of the ${var...} result).
6681  */
6682 #if !BASH_PATTERN_SUBST
6683 #define encode_then_expand_vararg(str, handle_squotes, do_unbackslash) \
6684         encode_then_expand_vararg(str, handle_squotes)
6685 #endif
6686 static char *encode_then_expand_vararg(const char *str, int handle_squotes, int do_unbackslash)
6687 {
6688 #if !BASH_PATTERN_SUBST && ENABLE_HUSH_CASE
6689         const int do_unbackslash = 0;
6690 #endif
6691         char *exp_str;
6692         struct in_str input;
6693         o_string dest = NULL_O_STRING;
6694
6695         if (!first_special_char_in_vararg(str)) {
6696                 /* string has no special chars */
6697                 return NULL;
6698         }
6699
6700         setup_string_in_str(&input, str);
6701         dest.data = xzalloc(1); /* start as "", not as NULL */
6702         exp_str = NULL;
6703
6704         for (;;) {
6705                 int ch;
6706
6707                 ch = i_getch(&input);
6708                 debug_printf_parse("%s: ch=%c (%d) escape=%d\n",
6709                                 __func__, ch, ch, !!dest.o_expflags);
6710
6711                 if (!dest.o_expflags) {
6712                         if (ch == EOF)
6713                                 break;
6714                         if (handle_squotes && ch == '\'') {
6715                                 if (!add_till_single_quote_dquoted(&dest, &input))
6716                                         goto ret; /* error */
6717                                 continue;
6718                         }
6719                 }
6720                 if (ch == EOF) {
6721                         syntax_error_unterm_ch('"');
6722                         goto ret; /* error */
6723                 }
6724                 if (ch == '"') {
6725                         dest.o_expflags ^= EXP_FLAG_ESC_GLOB_CHARS;
6726                         continue;
6727                 }
6728                 if (ch == '\\') {
6729                         ch = i_getch(&input);
6730                         if (ch == EOF) {
6731 //example? error message?       syntax_error_unterm_ch('"');
6732                                 debug_printf_parse("%s: error: \\<eof>\n", __func__);
6733                                 goto ret;
6734                         }
6735                         o_addqchr(&dest, ch);
6736                         continue;
6737                 }
6738                 if (ch == '$') {
6739                         if (parse_dollar_squote(NULL, &dest, &input))
6740                                 continue;
6741                         if (!parse_dollar(NULL, &dest, &input, /*quote_mask:*/ 0x80)) {
6742                                 debug_printf_parse("%s: error: parse_dollar returned 0 (error)\n", __func__);
6743                                 goto ret;
6744                         }
6745                         continue;
6746                 }
6747 #if ENABLE_HUSH_TICK
6748                 if (ch == '`') {
6749                         //unsigned pos = dest->length;
6750                         o_addchr(&dest, SPECIAL_VAR_SYMBOL);
6751                         o_addchr(&dest, 0x80 | '`');
6752                         if (!add_till_backquote(&dest, &input,
6753                                         /*in_dquote:*/ dest.o_expflags /* nonzero if EXP_FLAG_ESC_GLOB_CHARS set */
6754                                 )
6755                         ) {
6756                                 goto ret; /* error */
6757                         }
6758                         o_addchr(&dest, SPECIAL_VAR_SYMBOL);
6759                         //debug_printf_subst("SUBST RES3 '%s'\n", dest->data + pos);
6760                         continue;
6761                 }
6762 #endif
6763                 o_addQchr(&dest, ch);
6764         } /* for (;;) */
6765
6766         debug_printf_parse("encode: '%s' -> '%s'\n", str, dest.data);
6767         exp_str = expand_string_to_string(dest.data,
6768                         do_unbackslash ? EXP_FLAG_ESC_GLOB_CHARS : 0,
6769                         do_unbackslash
6770         );
6771  ret:
6772         debug_printf_parse("expand: '%s' -> '%s'\n", dest.data, exp_str);
6773         o_free(&dest);
6774         return exp_str;
6775 }
6776
6777 /* Expanding ARG in ${var+ARG}, ${var-ARG}
6778  */
6779 static NOINLINE int encode_then_append_var_plusminus(o_string *output, int n,
6780                 char *str, int dquoted)
6781 {
6782         struct in_str input;
6783         o_string dest = NULL_O_STRING;
6784
6785         if (!first_special_char_in_vararg(str)
6786          && '\0' == str[strcspn(str, G.ifs)]
6787         ) {
6788                 /* string has no special chars
6789                  * && string has no $IFS chars
6790                  */
6791                 if (dquoted) {
6792                         /* Prints 1 (quoted expansion is a "" word, not nothing):
6793                          * set -- "${notexist-}"; echo $#
6794                          */
6795                         output->has_quoted_part = 1;
6796                 }
6797                 return expand_vars_to_list(output, n, str);
6798         }
6799
6800         setup_string_in_str(&input, str);
6801
6802         for (;;) {
6803                 int ch;
6804
6805                 ch = i_getch(&input);
6806                 debug_printf_parse("%s: ch=%c (%d) escape=%x\n",
6807                                 __func__, ch, ch, dest.o_expflags);
6808
6809                 if (!dest.o_expflags) {
6810                         if (ch == EOF)
6811                                 break;
6812                         if (!dquoted && !(output->o_expflags & EXP_FLAG_SINGLEWORD) && strchr(G.ifs, ch)) {
6813                                 /* PREFIX${x:d${e}f ...} and we met space: expand "d${e}f" and start new word.
6814                                  * do not assume we are at the start of the word (PREFIX above).
6815                                  */
6816                                 if (dest.data) {
6817                                         n = expand_vars_to_list(output, n, dest.data);
6818                                         o_free_and_set_NULL(&dest);
6819                                         o_addchr(output, '\0');
6820                                         n = o_save_ptr(output, n); /* create next word */
6821                                 } else
6822                                 if (output->length != o_get_last_ptr(output, n)
6823                                  || output->has_quoted_part
6824                                 ) {
6825                                         /* For these cases:
6826                                          * f() { for i; do echo "|$i|"; done; }; x=x
6827                                          * f a${x:+ }b  # 1st condition
6828                                          * |a|
6829                                          * |b|
6830                                          * f ""${x:+ }b  # 2nd condition
6831                                          * ||
6832                                          * |b|
6833                                          */
6834                                         o_addchr(output, '\0');
6835                                         n = o_save_ptr(output, n); /* create next word */
6836                                 }
6837                                 continue;
6838                         }
6839                         if (!dquoted && ch == '\'') {
6840                                 if (!add_till_single_quote_dquoted(&dest, &input))
6841                                         goto ret; /* error */
6842                                 o_addchr(&dest, SPECIAL_VAR_SYMBOL);
6843                                 o_addchr(&dest, SPECIAL_VAR_SYMBOL);
6844                                 continue;
6845                         }
6846                 }
6847                 if (ch == EOF) {
6848                         syntax_error_unterm_ch('"');
6849                         goto ret; /* error */
6850                 }
6851                 if (ch == '"') {
6852                         dest.o_expflags ^= EXP_FLAG_ESC_GLOB_CHARS;
6853                         if (dest.o_expflags) {
6854                                 o_addchr(&dest, SPECIAL_VAR_SYMBOL);
6855                                 o_addchr(&dest, SPECIAL_VAR_SYMBOL);
6856                         }
6857                         continue;
6858                 }
6859                 if (ch == '\\') {
6860                         ch = i_getch(&input);
6861                         if (ch == EOF) {
6862 //example? error message?       syntax_error_unterm_ch('"');
6863                                 debug_printf_parse("%s: error: \\<eof>\n", __func__);
6864                                 goto ret;
6865                         }
6866                         o_addqchr(&dest, ch);
6867                         continue;
6868                 }
6869                 if (ch == '$') {
6870                         if (!parse_dollar(NULL, &dest, &input, /*quote_mask:*/ (dest.o_expflags || dquoted) ? 0x80 : 0)) {
6871                                 debug_printf_parse("%s: error: parse_dollar returned 0 (error)\n", __func__);
6872                                 goto ret;
6873                         }
6874                         continue;
6875                 }
6876 #if ENABLE_HUSH_TICK
6877                 if (ch == '`') {
6878                         //unsigned pos = dest->length;
6879                         o_addchr(&dest, SPECIAL_VAR_SYMBOL);
6880                         o_addchr(&dest, (dest.o_expflags || dquoted) ? 0x80 | '`' : '`');
6881                         if (!add_till_backquote(&dest, &input,
6882                                         /*in_dquote:*/ dest.o_expflags /* nonzero if EXP_FLAG_ESC_GLOB_CHARS set */
6883                                 )
6884                         ) {
6885                                 goto ret; /* error */
6886                         }
6887                         o_addchr(&dest, SPECIAL_VAR_SYMBOL);
6888                         //debug_printf_subst("SUBST RES3 '%s'\n", dest->data + pos);
6889                         continue;
6890                 }
6891 #endif
6892                 if (dquoted) {
6893                         /* Always glob-protect if in dquotes:
6894                          * x=x; echo "${x:+/bin/c*}" - prints: /bin/c*
6895                          * x=x; echo "${x:+"/bin/c*"}" - prints: /bin/c*
6896                          */
6897                         o_addqchr(&dest, ch);
6898                 } else {
6899                         /* Glob-protect only if char is quoted:
6900                          * x=x; echo ${x:+/bin/c*} - prints many filenames
6901                          * x=x; echo ${x:+"/bin/c*"} - prints: /bin/c*
6902                          */
6903                         o_addQchr(&dest, ch);
6904                 }
6905         } /* for (;;) */
6906
6907         if (dest.data) {
6908                 n = expand_vars_to_list(output, n, dest.data);
6909         }
6910  ret:
6911         o_free(&dest);
6912         return n;
6913 }
6914 #endif /* !__U_BOOT__ */
6915
6916 #ifndef __U_BOOT__
6917 #if ENABLE_FEATURE_SH_MATH
6918 static arith_t expand_and_evaluate_arith(const char *arg, const char **errmsg_p)
6919 {
6920         arith_state_t math_state;
6921         arith_t res;
6922         char *exp_str;
6923
6924         math_state.lookupvar = get_local_var_value;
6925         math_state.setvar = set_local_var_from_halves;
6926         //math_state.endofname = endofname;
6927         exp_str = encode_then_expand_string(arg);
6928         res = arith(&math_state, exp_str ? exp_str : arg);
6929         free(exp_str);
6930         if (errmsg_p)
6931                 *errmsg_p = math_state.errmsg;
6932         if (math_state.errmsg)
6933                 msg_and_die_if_script(math_state.errmsg);
6934         return res;
6935 }
6936 #endif
6937 #endif /* !__U_BOOT__ */
6938
6939 #ifndef __U_BOOT__
6940 #if BASH_PATTERN_SUBST
6941 /* ${var/[/]pattern[/repl]} helpers */
6942 static char *strstr_pattern(char *val, const char *pattern, int *size)
6943 {
6944         int first_escaped = (pattern[0] == '\\' && pattern[1]);
6945         /* "first_escaped" trick allows to treat e.g. "\*no_glob_chars"
6946          * as literal too (as it is semi-common, and easy to accomodate
6947          * by just using str + 1).
6948          */
6949         int sz = strcspn(pattern + first_escaped * 2, "*?[\\");
6950         if ((pattern + first_escaped * 2)[sz] == '\0') {
6951                 /* Optimization for trivial patterns.
6952                  * Testcase for very slow replace (performs about 22k replaces):
6953                  * x=::::::::::::::::::::::
6954                  * x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;echo ${#x}
6955                  * echo "${x//:/|}"
6956                  */
6957                 *size = sz + first_escaped;
6958                 return strstr(val, pattern + first_escaped);
6959         }
6960
6961         while (1) {
6962                 char *end = scan_and_match(val, pattern, SCAN_MOVE_FROM_RIGHT + SCAN_MATCH_LEFT_HALF);
6963                 debug_printf_varexp("val:'%s' pattern:'%s' end:'%s'\n", val, pattern, end);
6964                 if (end) {
6965                         *size = end - val;
6966                         return val;
6967                 }
6968                 if (*val == '\0')
6969                         return NULL;
6970                 /* Optimization: if "*pat" did not match the start of "string",
6971                  * we know that "tring", "ring" etc will not match too:
6972                  */
6973                 if (pattern[0] == '*')
6974                         return NULL;
6975                 val++;
6976         }
6977 }
6978 static char *replace_pattern(char *val, const char *pattern, const char *repl, char exp_op)
6979 {
6980         char *result = NULL;
6981         unsigned res_len = 0;
6982         unsigned repl_len = strlen(repl);
6983
6984         /* Null pattern never matches, including if "var" is empty */
6985         if (!pattern[0])
6986                 return result; /* NULL, no replaces happened */
6987
6988         while (1) {
6989                 int size;
6990                 char *s = strstr_pattern(val, pattern, &size);
6991                 if (!s)
6992                         break;
6993
6994                 result = xrealloc(result, res_len + (s - val) + repl_len + 1);
6995                 strcpy(mempcpy(result + res_len, val, s - val), repl);
6996                 res_len += (s - val) + repl_len;
6997                 debug_printf_varexp("val:'%s' s:'%s' result:'%s'\n", val, s, result);
6998
6999                 val = s + size;
7000                 if (exp_op == '/')
7001                         break;
7002         }
7003         if (*val && result) {
7004                 result = xrealloc(result, res_len + strlen(val) + 1);
7005                 strcpy(result + res_len, val);
7006                 debug_printf_varexp("val:'%s' result:'%s'\n", val, result);
7007         }
7008         debug_printf_varexp("result:'%s'\n", result);
7009         return result;
7010 }
7011 #endif /* BASH_PATTERN_SUBST */
7012 #endif /* !__U_BOOT__ */
7013
7014 static int append_str_maybe_ifs_split(o_string *output, int n,
7015                 int first_ch, const char *val)
7016 {
7017         if (!(first_ch & 0x80)) { /* unquoted $VAR */
7018                 debug_printf_expand("unquoted '%s', output->o_escape:%d\n", val,
7019                                 !!(output->o_expflags & EXP_FLAG_ESC_GLOB_CHARS));
7020                 if (val && val[0])
7021                         n = expand_on_ifs(output, n, val);
7022         } else { /* quoted "$VAR" */
7023                 output->has_quoted_part = 1;
7024                 debug_printf_expand("quoted '%s', output->o_escape:%d\n", val,
7025                                 !!(output->o_expflags & EXP_FLAG_ESC_GLOB_CHARS));
7026                 if (val && val[0])
7027                         o_addQstr(output, val);
7028         }
7029         return n;
7030 }
7031
7032 /* Handle <SPECIAL_VAR_SYMBOL>varname...<SPECIAL_VAR_SYMBOL> construct.
7033  */
7034 static NOINLINE int expand_one_var(o_string *output, int n,
7035                 int first_ch, char *arg, char **pp)
7036 {
7037         const char *val;
7038         char *to_be_freed;
7039         char *p;
7040         char *var;
7041         char exp_op;
7042         char exp_save = exp_save; /* for compiler */
7043         char *exp_saveptr; /* points to expansion operator */
7044         char *exp_word = exp_word; /* for compiler */
7045         char arg0;
7046
7047         val = NULL;
7048         to_be_freed = NULL;
7049         p = *pp;
7050         *p = '\0'; /* replace trailing SPECIAL_VAR_SYMBOL */
7051         var = arg;
7052         exp_saveptr = arg[1] ? strchr(VAR_ENCODED_SUBST_OPS, arg[1]) : NULL;
7053         arg0 = arg[0];
7054         arg[0] = (arg0 & 0x7f);
7055         exp_op = 0;
7056
7057         if (arg[0] == '#' && arg[1] /* ${#...} but not ${#} */
7058          && (!exp_saveptr               /* and ( not(${#<op_char>...}) */
7059             || (arg[2] == '\0' && strchr(SPECIAL_VARS_STR, arg[1])) /* or ${#C} "len of $C" ) */
7060             )           /* NB: skipping ^^^specvar check mishandles ${#::2} */
7061         ) {
7062                 /* It must be length operator: ${#var} */
7063                 var++;
7064                 exp_op = 'L';
7065         } else {
7066                 /* Maybe handle parameter expansion */
7067                 if (exp_saveptr /* if 2nd char is one of expansion operators */
7068                  && strchr(NUMERIC_SPECVARS_STR, arg[0]) /* 1st char is special variable */
7069                 ) {
7070                         /* ${?:0}, ${#[:]%0} etc */
7071                         exp_saveptr = var + 1;
7072                 } else {
7073                         /* ${?}, ${var}, ${var:0}, ${var[:]%0} etc */
7074                         exp_saveptr = var+1 + strcspn(var+1, VAR_ENCODED_SUBST_OPS);
7075                 }
7076                 exp_op = exp_save = *exp_saveptr;
7077 #ifndef __U_BOOT__
7078                 if (exp_op) {
7079                         exp_word = exp_saveptr + 1;
7080                         if (exp_op == ':') {
7081                                 exp_op = *exp_word++;
7082 //TODO: try ${var:} and ${var:bogus} in non-bash config
7083                                 if (BASH_SUBSTR
7084                                  && (!exp_op || !strchr(MINUS_PLUS_EQUAL_QUESTION, exp_op))
7085                                 ) {
7086                                         /* oops... it's ${var:N[:M]}, not ${var:?xxx} or some such */
7087                                         exp_op = ':';
7088                                         exp_word--;
7089                                 }
7090                         }
7091                         *exp_saveptr = '\0';
7092                 } /* else: it's not an expansion op, but bare ${var} */
7093 #endif /* !__U_BOOT__ */
7094         }
7095
7096         /* Look up the variable in question */
7097         if (isdigit(var[0])) {
7098                 /* parse_dollar should have vetted var for us */
7099 #ifndef __U_BOOT__
7100                 int nn = xatoi_positive(var);
7101 #else /* __U_BOOT__ */
7102                 int nn = simple_strtoul(var, NULL, 10);
7103 #endif /* __U_BOOT__ */
7104                 if (nn < G.global_argc)
7105                         val = G.global_argv[nn];
7106                 /* else val remains NULL: $N with too big N */
7107         } else {
7108                 switch (var[0]) {
7109 #ifndef __U_BOOT__
7110                 case '$': /* pid */
7111                         val = utoa(G.root_pid);
7112                         break;
7113                 case '!': /* bg pid */
7114                         val = G.last_bg_pid ? utoa(G.last_bg_pid) : "";
7115                         break;
7116 #endif /* !__U_BOOT__ */
7117                 case '?': /* exitcode */
7118                         val = utoa(G.last_exitcode);
7119                         break;
7120                 case '#': /* argc */
7121                         val = utoa(G.global_argc ? G.global_argc-1 : 0);
7122                         break;
7123 #ifndef __U_BOOT__
7124                 case '-': { /* active options */
7125                         /* Check set_mode() to see what option chars we support */
7126                         char *cp;
7127                         val = cp = G.optstring_buf;
7128                         if (G.o_opt[OPT_O_ERREXIT])
7129                                 *cp++ = 'e';
7130                         if (G_interactive_fd)
7131                                 *cp++ = 'i';
7132                         if (G_x_mode)
7133                                 *cp++ = 'x';
7134                         /* If G.o_opt[OPT_O_NOEXEC] is true,
7135                          * commands read but are not executed,
7136                          * so $- can not execute too, 'n' is never seen in $-.
7137                          */
7138                         if (G.opt_c)
7139                                 *cp++ = 'c';
7140                         if (G.opt_s)
7141                                 *cp++ = 's';
7142                         *cp = '\0';
7143                         break;
7144                 }
7145 #endif /* !__U_BOOT__ */
7146                 default:
7147 #ifndef __U_BOOT__
7148                         val = get_local_var_value(var);
7149 #else /* __U_BOOT__ */
7150                         /*
7151                          * Environment variable set with setenv* have to be
7152                          * expanded.
7153                          * So, we first search if the variable exists in
7154                          * environment, if this is not the case, we default to
7155                          * local value.
7156                          */
7157                         val = env_get(var);
7158                         if (!val)
7159                                 val = get_local_var_value(var);
7160 #endif /* __U_BOOT__ */
7161                 }
7162         }
7163
7164 #ifndef __U_BOOT__
7165         /* Handle any expansions */
7166         if (exp_op == 'L') {
7167                 reinit_unicode_for_hush();
7168                 debug_printf_expand("expand: length(%s)=", val);
7169                 val = utoa(val ? unicode_strlen(val) : 0);
7170                 debug_printf_expand("%s\n", val);
7171         } else if (exp_op) {
7172                 if (exp_op == '%' || exp_op == '#') {
7173                         /* Standard-mandated substring removal ops:
7174                          * ${parameter%word} - remove smallest suffix pattern
7175                          * ${parameter%%word} - remove largest suffix pattern
7176                          * ${parameter#word} - remove smallest prefix pattern
7177                          * ${parameter##word} - remove largest prefix pattern
7178                          *
7179                          * Word is expanded to produce a glob pattern.
7180                          * Then var's value is matched to it and matching part removed.
7181                          */
7182                         /* bash compat: if x is "" and no shrinking of it is possible,
7183                          * inner ${...} is not evaluated. Example:
7184                          *  unset b; : ${a%${b=B}}; echo $b
7185                          * assignment b=B only happens if $a is not "".
7186                          */
7187                         if (val && val[0]) {
7188                                 char *t;
7189                                 char *exp_exp_word;
7190                                 char *loc;
7191                                 unsigned scan_flags = pick_scan(exp_op, *exp_word);
7192                                 if (exp_op == *exp_word)  /* ## or %% */
7193                                         exp_word++;
7194                                 debug_printf_expand("expand: exp_word:'%s'\n", exp_word);
7195                                 exp_exp_word = encode_then_expand_vararg(exp_word, /*handle_squotes:*/ 1, /*unbackslash:*/ 0);
7196                                 if (exp_exp_word)
7197                                         exp_word = exp_exp_word;
7198                                 debug_printf_expand("expand: exp_word:'%s'\n", exp_word);
7199                                 /*
7200                                  * HACK ALERT. We depend here on the fact that
7201                                  * G.global_argv and results of utoa and get_local_var_value
7202                                  * are actually in writable memory:
7203                                  * scan_and_match momentarily stores NULs there.
7204                                  */
7205                                 t = (char*)val;
7206                                 loc = scan_and_match(t, exp_word, scan_flags);
7207                                 debug_printf_expand("op:%c str:'%s' pat:'%s' res:'%s'\n", exp_op, t, exp_word, loc);
7208                                 free(exp_exp_word);
7209                                 if (loc) { /* match was found */
7210                                         if (scan_flags & SCAN_MATCH_LEFT_HALF) /* #[#] */
7211                                                 val = loc; /* take right part */
7212                                         else /* %[%] */
7213                                                 val = to_be_freed = xstrndup(val, loc - val); /* left */
7214                                 }
7215                         }
7216                 }
7217 #if BASH_PATTERN_SUBST
7218                 else if (exp_op == '/' || exp_op == '\\') {
7219                         /* It's ${var/[/]pattern[/repl]} thing.
7220                          * Note that in encoded form it has TWO parts:
7221                          * var/pattern<SPECIAL_VAR_SYMBOL>repl<SPECIAL_VAR_SYMBOL>
7222                          * and if // is used, it is encoded as \:
7223                          * var\pattern<SPECIAL_VAR_SYMBOL>repl<SPECIAL_VAR_SYMBOL>
7224                          */
7225                         /* bash compat: if var is "", both pattern and repl
7226                          * are still evaluated, if it is unset, then not:
7227                          * unset b; a=; : ${a/z/${b=3}}; echo $b      # b=3
7228                          * unset b; unset a; : ${a/z/${b=3}}; echo $b # b not set
7229                          */
7230                         if (val /*&& val[0]*/) {
7231                                 /* pattern uses non-standard expansion.
7232                                  * repl should be unbackslashed and globbed
7233                                  * by the usual expansion rules:
7234                                  *  >az >bz
7235                                  *  v='a bz'; echo "${v/a*z/a*z}" #prints "a*z"
7236                                  *  v='a bz'; echo "${v/a*z/\z}"  #prints "z"
7237                                  *  v='a bz'; echo ${v/a*z/a*z}   #prints "az"
7238                                  *  v='a bz'; echo ${v/a*z/\z}    #prints "z"
7239                                  * (note that a*z _pattern_ is never globbed!)
7240                                  */
7241                                 char *pattern, *repl, *t;
7242                                 pattern = encode_then_expand_vararg(exp_word, /*handle_squotes:*/ 1, /*unbackslash:*/ 0);
7243                                 if (!pattern)
7244                                         pattern = xstrdup(exp_word);
7245                                 debug_printf_varexp("pattern:'%s'->'%s'\n", exp_word, pattern);
7246                                 *p++ = SPECIAL_VAR_SYMBOL;
7247                                 exp_word = p;
7248                                 p = strchr(p, SPECIAL_VAR_SYMBOL);
7249                                 *p = '\0';
7250                                 repl = encode_then_expand_vararg(exp_word, /*handle_squotes:*/ 1, /*unbackslash:*/ 1);
7251                                 debug_printf_varexp("repl:'%s'->'%s'\n", exp_word, repl);
7252                                 /* HACK ALERT. We depend here on the fact that
7253                                  * G.global_argv and results of utoa and get_local_var_value
7254                                  * are actually in writable memory:
7255                                  * replace_pattern momentarily stores NULs there. */
7256                                 t = (char*)val;
7257                                 to_be_freed = replace_pattern(t,
7258                                                 pattern,
7259                                                 (repl ? repl : exp_word),
7260                                                 exp_op);
7261                                 if (to_be_freed) /* at least one replace happened */
7262                                         val = to_be_freed;
7263                                 free(pattern);
7264                                 free(repl);
7265                         } else {
7266                                 /* Unset variable always gives nothing */
7267                                 //  a=; echo ${a/*/w}      # "w"
7268                                 //  unset a; echo ${a/*/w} # ""
7269                                 /* Just skip "replace" part */
7270                                 *p++ = SPECIAL_VAR_SYMBOL;
7271                                 p = strchr(p, SPECIAL_VAR_SYMBOL);
7272                                 *p = '\0';
7273                         }
7274                 }
7275 #endif /* BASH_PATTERN_SUBST */
7276                 else if (exp_op == ':') {
7277 #if BASH_SUBSTR && ENABLE_FEATURE_SH_MATH
7278                         /* It's ${var:N[:M]} bashism.
7279                          * Note that in encoded form it has TWO parts:
7280                          * var:N<SPECIAL_VAR_SYMBOL>M<SPECIAL_VAR_SYMBOL>
7281                          */
7282                         arith_t beg, len;
7283                         unsigned vallen;
7284                         const char *errmsg;
7285
7286                         beg = expand_and_evaluate_arith(exp_word, &errmsg);
7287                         if (errmsg)
7288                                 goto empty_result;
7289                         debug_printf_varexp("beg:'%s'=%lld\n", exp_word, (long long)beg);
7290                         *p++ = SPECIAL_VAR_SYMBOL;
7291                         exp_word = p;
7292                         p = strchr(p, SPECIAL_VAR_SYMBOL);
7293                         *p = '\0';
7294                         vallen = val ? strlen(val) : 0;
7295                         if (beg < 0) {
7296                                 /* negative beg counts from the end */
7297                                 beg = (arith_t)vallen + beg;
7298                         }
7299                         /* If expansion will be empty, do not even evaluate len */
7300                         if (!val || beg < 0 || beg > vallen) {
7301                                 /* Why > vallen, not >=? bash:
7302                                  * unset b; a=ab; : ${a:2:${b=3}}; echo $b  # "", b=3 (!!!)
7303                                  * unset b; a=a; : ${a:2:${b=3}}; echo $b   # "", b not set
7304                                  */
7305                                 goto empty_result;
7306                         }
7307                         len = expand_and_evaluate_arith(exp_word, &errmsg);
7308                         if (errmsg)
7309                                 goto empty_result;
7310                         debug_printf_varexp("len:'%s'=%lld\n", exp_word, (long long)len);
7311                         debug_printf_varexp("from val:'%s'\n", val);
7312                         if (len < 0) {
7313                                 /* in bash, len=-n means strlen()-n */
7314                                 len = (arith_t)vallen - beg + len;
7315                                 if (len < 0) /* bash compat */
7316                                         msg_and_die_if_script("%s: substring expression < 0", var);
7317                         }
7318                         if (len <= 0 || !val /*|| beg >= vallen*/) {
7319  empty_result:
7320                                 val = NULL;
7321                         } else {
7322                                 /* Paranoia. What if user entered 9999999999999
7323                                  * which fits in arith_t but not int? */
7324                                 if (len > INT_MAX)
7325                                         len = INT_MAX;
7326                                 val = to_be_freed = xstrndup(val + beg, len);
7327                         }
7328                         debug_printf_varexp("val:'%s'\n", val);
7329 #else /* not (HUSH_SUBSTR_EXPANSION && FEATURE_SH_MATH) */
7330                         msg_and_die_if_script("malformed ${%s:...}", var);
7331                         val = NULL;
7332 #endif
7333                 } else { /* one of "-=+?" */
7334                         /* Standard-mandated substitution ops:
7335                          * ${var?word} - indicate error if unset
7336                          *      If var is unset, word (or a message indicating it is unset
7337                          *      if word is null) is written to standard error
7338                          *      and the shell exits with a non-zero exit status.
7339                          *      Otherwise, the value of var is substituted.
7340                          * ${var-word} - use default value
7341                          *      If var is unset, word is substituted.
7342                          * ${var=word} - assign and use default value
7343                          *      If var is unset, word is assigned to var.
7344                          *      In all cases, final value of var is substituted.
7345                          * ${var+word} - use alternative value
7346                          *      If var is unset, null is substituted.
7347                          *      Otherwise, word is substituted.
7348                          *
7349                          * Word is subjected to tilde expansion, parameter expansion,
7350                          * command substitution, and arithmetic expansion.
7351                          * If word is not needed, it is not expanded.
7352                          *
7353                          * Colon forms (${var:-word}, ${var:=word} etc) do the same,
7354                          * but also treat null var as if it is unset.
7355                          *
7356                          * Word-splitting and single quote behavior:
7357                          *
7358                          * $ f() { for i; do echo "|$i|"; done; }
7359                          *
7360                          * $ x=; f ${x:?'x y' z}; echo $?
7361                          * bash: x: x y z       # neither f nor "echo $?" executes
7362                          * (if interactive, bash does not exit, but merely aborts to prompt. $? is set to 1)
7363                          * $ x=; f "${x:?'x y' z}"
7364                          * bash: x: x y z       # dash prints: dash: x: 'x y' z
7365                          *
7366                          * $ x=; f ${x:='x y' z}
7367                          * |x|
7368                          * |y|
7369                          * |z|
7370                          * $ x=; f "${x:='x y' z}"
7371                          * |'x y' z|
7372                          *
7373                          * $ x=x; f ${x:+'x y' z}
7374                          * |x y|
7375                          * |z|
7376                          * $ x=x; f "${x:+'x y' z}"
7377                          * |'x y' z|
7378                          *
7379                          * $ x=; f ${x:-'x y' z}
7380                          * |x y|
7381                          * |z|
7382                          * $ x=; f "${x:-'x y' z}"
7383                          * |'x y' z|
7384                          */
7385                         int use_word = (!val || ((exp_save == ':') && !val[0]));
7386                         if (exp_op == '+')
7387                                 use_word = !use_word;
7388                         debug_printf_expand("expand: op:%c (null:%s) test:%i\n", exp_op,
7389                                         (exp_save == ':') ? "true" : "false", use_word);
7390                         if (use_word) {
7391                                 if (exp_op == '+' || exp_op == '-') {
7392                                         /* ${var+word} - use alternative value */
7393                                         /* ${var-word} - use default value */
7394                                         n = encode_then_append_var_plusminus(output, n, exp_word,
7395                                                         /*dquoted:*/ (arg0 & 0x80)
7396                                         );
7397                                         val = NULL;
7398                                 } else {
7399                                         /* ${var?word} - indicate error if unset */
7400                                         /* ${var=word} - assign and use default value */
7401                                         to_be_freed = encode_then_expand_vararg(exp_word,
7402                                                         /*handle_squotes:*/ !(arg0 & 0x80),
7403                                                         /*unbackslash:*/ 0
7404                                         );
7405                                         if (to_be_freed)
7406                                                 exp_word = to_be_freed;
7407                                         if (exp_op == '?') {
7408                                                 /* mimic bash message */
7409                                                 msg_and_die_if_script("%s: %s",
7410                                                         var,
7411                                                         exp_word[0]
7412                                                         ? exp_word
7413                                                         : "parameter null or not set"
7414                                                         /* ash has more specific messages, a-la: */
7415                                                         /*: (exp_save == ':' ? "parameter null or not set" : "parameter not set")*/
7416                                                 );
7417 //TODO: how interactive bash aborts expansion mid-command?
7418 //It aborts the entire line, returns to prompt:
7419 // $ f() { for i; do echo "|$i|"; done; }; x=; f "${x:?'x y' z}"; echo YO
7420 // bash: x: x y z
7421 // $
7422 // ("echo YO" is not executed, neither the f function call)
7423                                         } else {
7424                                                 val = exp_word;
7425                                         }
7426                                         if (exp_op == '=') {
7427                                                 /* ${var=[word]} or ${var:=[word]} */
7428                                                 if (isdigit(var[0]) || var[0] == '#') {
7429                                                         /* mimic bash message */
7430                                                         msg_and_die_if_script("$%s: cannot assign in this way", var);
7431                                                         val = NULL;
7432                                                 } else {
7433                                                         char *new_var = xasprintf("%s=%s", var, val);
7434                                                         set_local_var0(new_var);
7435                                                 }
7436                                         }
7437                                 }
7438                         }
7439                 } /* one of "-=+?" */
7440
7441                 *exp_saveptr = exp_save;
7442         } /* if (exp_op) */
7443
7444 #endif /* !__U_BOOT__ */
7445         arg[0] = arg0;
7446         *pp = p;
7447
7448         n = append_str_maybe_ifs_split(output, n, first_ch, val);
7449
7450         free(to_be_freed);
7451         return n;
7452 }
7453
7454 /* Expand all variable references in given string, adding words to list[]
7455  * at n, n+1,... positions. Return updated n (so that list[n] is next one
7456  * to be filled). This routine is extremely tricky: has to deal with
7457  * variables/parameters with whitespace, $* and $@, and constructs like
7458  * 'echo -$*-'. If you play here, you must run testsuite afterwards! */
7459 static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg)
7460 {
7461         /* output->o_expflags & EXP_FLAG_SINGLEWORD (0x80) if we are in
7462          * expansion of right-hand side of assignment == 1-element expand.
7463          */
7464         char cant_be_null = 0; /* only bit 0x80 matters */
7465         char *p;
7466
7467         debug_printf_expand("expand_vars_to_list: arg:'%s' singleword:%x\n", arg,
7468                         !!(output->o_expflags & EXP_FLAG_SINGLEWORD));
7469         debug_print_list("expand_vars_to_list[0]", output, n);
7470
7471         while ((p = strchr(arg, SPECIAL_VAR_SYMBOL)) != NULL) {
7472                 char first_ch;
7473 #if ENABLE_FEATURE_SH_MATH
7474                 char arith_buf[sizeof(arith_t)*3 + 2];
7475 #endif
7476
7477                 if (output->ended_in_ifs) {
7478                         o_addchr(output, '\0');
7479                         n = o_save_ptr(output, n);
7480                         output->ended_in_ifs = 0;
7481                 }
7482
7483                 o_addblock(output, arg, p - arg);
7484                 debug_print_list("expand_vars_to_list[1]", output, n);
7485                 arg = ++p;
7486                 p = strchr(p, SPECIAL_VAR_SYMBOL);
7487
7488                 /* Fetch special var name (if it is indeed one of them)
7489                  * and quote bit, force the bit on if singleword expansion -
7490                  * important for not getting v=$@ expand to many words. */
7491                 first_ch = arg[0] | (output->o_expflags & EXP_FLAG_SINGLEWORD);
7492
7493                 /* Is this variable quoted and thus expansion can't be null?
7494                  * "$@" is special. Even if quoted, it can still
7495                  * expand to nothing (not even an empty string),
7496                  * thus it is excluded. */
7497                 if ((first_ch & 0x7f) != '@')
7498                         cant_be_null |= first_ch;
7499
7500                 switch (first_ch & 0x7f) {
7501                 /* Highest bit in first_ch indicates that var is double-quoted */
7502                 case '*':
7503                 case '@': {
7504                         int i;
7505 #ifndef __U_BOOT__
7506                         if (!G.global_argv[1])
7507 #else /* __U_BOOT__ */
7508                         if (!G.global_argv || !G.global_argv[1])
7509 #endif /* __U_BOOT__ */
7510                                 break;
7511                         i = 1;
7512                         cant_be_null |= first_ch; /* do it for "$@" _now_, when we know it's not empty */
7513                         if (!(first_ch & 0x80)) { /* unquoted $* or $@ */
7514                                 while (G.global_argv[i]) {
7515                                         n = expand_on_ifs(output, n, G.global_argv[i]);
7516                                         debug_printf_expand("expand_vars_to_list: argv %d (last %d)\n", i, G.global_argc - 1);
7517                                         if (G.global_argv[i++][0] && G.global_argv[i]) {
7518                                                 /* this argv[] is not empty and not last:
7519                                                  * put terminating NUL, start new word */
7520                                                 o_addchr(output, '\0');
7521                                                 debug_print_list("expand_vars_to_list[2]", output, n);
7522                                                 n = o_save_ptr(output, n);
7523                                                 debug_print_list("expand_vars_to_list[3]", output, n);
7524                                         }
7525                                 }
7526                         } else
7527                         /* If EXP_FLAG_SINGLEWORD, we handle assignment 'a=....$@.....'
7528                          * and in this case should treat it like '$*' - see 'else...' below */
7529                         if (first_ch == (char)('@'|0x80)  /* quoted $@ */
7530                          && !(output->o_expflags & EXP_FLAG_SINGLEWORD) /* not v="$@" case */
7531                         ) {
7532                                 while (1) {
7533                                         o_addQstr(output, G.global_argv[i]);
7534                                         if (++i >= G.global_argc)
7535                                                 break;
7536                                         o_addchr(output, '\0');
7537                                         debug_print_list("expand_vars_to_list[4]", output, n);
7538                                         n = o_save_ptr(output, n);
7539                                 }
7540                         } else { /* quoted $* (or v="$@" case): add as one word */
7541                                 while (1) {
7542                                         o_addQstr(output, G.global_argv[i]);
7543                                         if (!G.global_argv[++i])
7544                                                 break;
7545                                         if (G.ifs[0])
7546                                                 o_addchr(output, G.ifs[0]);
7547                                 }
7548                                 output->has_quoted_part = 1;
7549                         }
7550                         break;
7551                 }
7552                 case SPECIAL_VAR_SYMBOL: {
7553                         /* <SPECIAL_VAR_SYMBOL><SPECIAL_VAR_SYMBOL> */
7554                         /* "Empty variable", used to make "" etc to not disappear */
7555                         output->has_quoted_part = 1;
7556                         cant_be_null = 0x80;
7557                         arg++;
7558                         break;
7559                 }
7560                 case SPECIAL_VAR_QUOTED_SVS:
7561                         /* <SPECIAL_VAR_SYMBOL><SPECIAL_VAR_QUOTED_SVS><SPECIAL_VAR_SYMBOL> */
7562                         /* "^C variable", represents literal ^C char (possible in scripts) */
7563                         o_addchr(output, SPECIAL_VAR_SYMBOL);
7564                         arg++;
7565                         break;
7566 #if ENABLE_HUSH_TICK
7567                 case '`': {
7568                         /* <SPECIAL_VAR_SYMBOL>`cmd<SPECIAL_VAR_SYMBOL> */
7569                         o_string subst_result = NULL_O_STRING;
7570
7571                         *p = '\0'; /* replace trailing <SPECIAL_VAR_SYMBOL> */
7572                         arg++;
7573                         /* Can't just stuff it into output o_string,
7574                          * expanded result may need to be globbed
7575                          * and $IFS-split */
7576                         debug_printf_subst("SUBST '%s' first_ch %x\n", arg, first_ch);
7577                         G.last_exitcode = process_command_subs(&subst_result, arg);
7578                         G.expand_exitcode = G.last_exitcode;
7579                         debug_printf_subst("SUBST RES:%d '%s'\n", G.last_exitcode, subst_result.data);
7580                         n = append_str_maybe_ifs_split(output, n, first_ch, subst_result.data);
7581                         o_free(&subst_result);
7582                         break;
7583                 }
7584 #endif
7585 #if ENABLE_FEATURE_SH_MATH
7586                 case '+': {
7587                         /* <SPECIAL_VAR_SYMBOL>+arith<SPECIAL_VAR_SYMBOL> */
7588                         arith_t res;
7589
7590                         arg++; /* skip '+' */
7591                         *p = '\0'; /* replace trailing <SPECIAL_VAR_SYMBOL> */
7592                         debug_printf_subst("ARITH '%s' first_ch %x\n", arg, first_ch);
7593                         res = expand_and_evaluate_arith(arg, NULL);
7594                         debug_printf_subst("ARITH RES '"ARITH_FMT"'\n", res);
7595                         sprintf(arith_buf, ARITH_FMT, res);
7596                         if (res < 0
7597                          && first_ch == (char)('+'|0x80)
7598                         /* && (output->o_expflags & EXP_FLAG_ESC_GLOB_CHARS) */
7599                         ) {
7600                                 /* Quoted negative ariths, like filename[0"$((-9))"],
7601                                  * should not be interpreted as glob ranges.
7602                                  * Convert leading '-' to '\-':
7603                                  */
7604                                 o_grow_by(output, 1);
7605                                 output->data[output->length++] = '\\';
7606                         }
7607                         o_addstr(output, arith_buf);
7608                         break;
7609                 }
7610 #endif
7611                 default:
7612                         /* <SPECIAL_VAR_SYMBOL>varname[ops]<SPECIAL_VAR_SYMBOL> */
7613                         n = expand_one_var(output, n, first_ch, arg, &p);
7614                         break;
7615                 } /* switch (char after <SPECIAL_VAR_SYMBOL>) */
7616
7617                 /* Restore NULL'ed SPECIAL_VAR_SYMBOL.
7618                  * Do the check to avoid writing to a const string. */
7619                 if (*p != SPECIAL_VAR_SYMBOL)
7620                         *p = SPECIAL_VAR_SYMBOL;
7621                 arg = ++p;
7622         } /* end of "while (SPECIAL_VAR_SYMBOL is found) ..." */
7623
7624         if (*arg) {
7625                 /* handle trailing string */
7626                 if (output->ended_in_ifs) {
7627                         o_addchr(output, '\0');
7628                         n = o_save_ptr(output, n);
7629                 }
7630                 debug_print_list("expand_vars_to_list[a]", output, n);
7631                 /* this part is literal, and it was already pre-quoted
7632                  * if needed (much earlier), do not use o_addQstr here!
7633                  */
7634                 o_addstr(output, arg);
7635                 debug_print_list("expand_vars_to_list[b]", output, n);
7636         } else
7637         if (output->length == o_get_last_ptr(output, n) /* expansion is empty */
7638          && !(cant_be_null & 0x80)   /* and all vars were not quoted */
7639          && !output->has_quoted_part
7640         ) {
7641                 n--;
7642                 /* allow to reuse list[n] later without re-growth */
7643                 output->has_empty_slot = 1;
7644         }
7645
7646         return n;
7647 }
7648
7649 static char **expand_variables(char **argv, unsigned expflags)
7650 {
7651         int n;
7652         char **list;
7653         o_string output = NULL_O_STRING;
7654
7655         output.o_expflags = expflags;
7656
7657         n = 0;
7658         for (;;) {
7659                 /* go to next list[n] */
7660                 output.ended_in_ifs = 0;
7661                 n = o_save_ptr(&output, n);
7662
7663                 if (!*argv)
7664                         break;
7665
7666                 /* expand argv[i] */
7667                 n = expand_vars_to_list(&output, n, *argv++);
7668                 /* if (!output->has_empty_slot) -- need this?? */
7669                         o_addchr(&output, '\0');
7670         }
7671         debug_print_list("expand_variables", &output, n);
7672
7673         /* output.data (malloced in one block) gets returned in "list" */
7674         list = o_finalize_list(&output, n);
7675         debug_print_strings("expand_variables[1]", list);
7676         return list;
7677 }
7678
7679 static char **expand_strvec_to_strvec(char **argv)
7680 {
7681         return expand_variables(argv, EXP_FLAG_GLOB | EXP_FLAG_ESC_GLOB_CHARS);
7682 }
7683
7684 #if defined(CMD_SINGLEWORD_NOGLOB) || defined(CMD_TEST2_SINGLEWORD_NOGLOB)
7685 static char **expand_strvec_to_strvec_singleword_noglob(char **argv)
7686 {
7687         return expand_variables(argv, EXP_FLAG_SINGLEWORD);
7688 }
7689 #endif
7690
7691 /* Used for expansion of right hand of assignments,
7692  * $((...)), heredocs, variable expansion parts.
7693  *
7694  * NB: should NOT do globbing!
7695  * "export v=/bin/c*; env | grep ^v=" outputs "v=/bin/c*"
7696  */
7697 static char *expand_string_to_string(const char *str, int EXP_flags, int do_unbackslash)
7698 {
7699 #if !BASH_PATTERN_SUBST && !ENABLE_HUSH_CASE
7700         const int do_unbackslash = 1;
7701         const int EXP_flags = EXP_FLAG_ESC_GLOB_CHARS;
7702 #endif
7703         char *argv[2], **list;
7704
7705         debug_printf_expand("string_to_string<='%s'\n", str);
7706         /* This is generally an optimization, but it also
7707          * handles "", which otherwise trips over !list[0] check below.
7708          * (is this ever happens that we actually get str="" here?)
7709          */
7710         if (!strchr(str, SPECIAL_VAR_SYMBOL) && !strchr(str, '\\')) {
7711                 //TODO: Can use on strings with \ too, just unbackslash() them?
7712                 debug_printf_expand("string_to_string(fast)=>'%s'\n", str);
7713                 return xstrdup(str);
7714         }
7715
7716         argv[0] = (char*)str;
7717         argv[1] = NULL;
7718         list = expand_variables(argv, EXP_flags | EXP_FLAG_SINGLEWORD);
7719         if (!list[0]) {
7720                 /* Example where it happens:
7721                  * x=; echo ${x:-"$@"}
7722                  */
7723                 ((char*)list)[0] = '\0';
7724         } else {
7725                 if (HUSH_DEBUG)
7726                         if (list[1])
7727                                 bb_simple_error_msg_and_die("BUG in varexp2");
7728                 /* actually, just move string 2*sizeof(char*) bytes back */
7729                 overlapping_strcpy((char*)list, list[0]);
7730                 if (do_unbackslash)
7731                         unbackslash((char*)list);
7732         }
7733         debug_printf_expand("string_to_string=>'%s'\n", (char*)list);
7734         return (char*)list;
7735 }
7736
7737 #if 0
7738 static char* expand_strvec_to_string(char **argv)
7739 {
7740         char **list;
7741
7742         list = expand_variables(argv, EXP_FLAG_SINGLEWORD);
7743         /* Convert all NULs to spaces */
7744         if (list[0]) {
7745                 int n = 1;
7746                 while (list[n]) {
7747                         if (HUSH_DEBUG)
7748                                 if (list[n-1] + strlen(list[n-1]) + 1 != list[n])
7749                                         bb_error_msg_and_die("BUG in varexp3");
7750                         /* bash uses ' ' regardless of $IFS contents */
7751                         list[n][-1] = ' ';
7752                         n++;
7753                 }
7754         }
7755         overlapping_strcpy((char*)list, list[0] ? list[0] : "");
7756         debug_printf_expand("strvec_to_string='%s'\n", (char*)list);
7757         return (char*)list;
7758 }
7759 #endif
7760
7761 #ifndef __U_BOOT__
7762 static char **expand_assignments(char **argv, int count)
7763 {
7764         int i;
7765         char **p;
7766
7767         G.expanded_assignments = p = NULL;
7768         /* Expand assignments into one string each */
7769         for (i = 0; i < count; i++) {
7770                 p = add_string_to_strings(p,
7771                         expand_string_to_string(argv[i],
7772                                 EXP_FLAG_ESC_GLOB_CHARS,
7773                                 /*unbackslash:*/ 1
7774                         )
7775                 );
7776                 G.expanded_assignments = p;
7777         }
7778         G.expanded_assignments = NULL;
7779         return p;
7780 }
7781
7782 static void switch_off_special_sigs(unsigned mask)
7783 {
7784         unsigned sig = 0;
7785         while ((mask >>= 1) != 0) {
7786                 sig++;
7787                 if (!(mask & 1))
7788                         continue;
7789 #if ENABLE_HUSH_TRAP
7790                 if (G_traps) {
7791                         if (G_traps[sig] && !G_traps[sig][0])
7792                                 /* trap is '', has to remain SIG_IGN */
7793                                 continue;
7794                         free(G_traps[sig]);
7795                         G_traps[sig] = NULL;
7796                 }
7797 #endif
7798                 /* We are here only if no trap or trap was not '' */
7799                 install_sighandler(sig, SIG_DFL);
7800         }
7801 }
7802 #endif /* !__U_BOOT__ */
7803
7804 #ifndef __U_BOOT__
7805 #if BB_MMU
7806 /* never called */
7807 void re_execute_shell(char ***to_free, const char *s,
7808                 char *g_argv0, char **g_argv,
7809                 char **builtin_argv) NORETURN;
7810
7811 static void reset_traps_to_defaults(void)
7812 {
7813         /* This function is always called in a child shell
7814          * after fork (not vfork, NOMMU doesn't use this function).
7815          */
7816         IF_HUSH_TRAP(unsigned sig;)
7817         unsigned mask;
7818
7819         /* Child shells are not interactive.
7820          * SIGTTIN/SIGTTOU/SIGTSTP should not have special handling.
7821          * Testcase: (while :; do :; done) + ^Z should background.
7822          * Same goes for SIGTERM, SIGHUP, SIGINT.
7823          */
7824         mask = (G.special_sig_mask & SPECIAL_INTERACTIVE_SIGS) | G_fatal_sig_mask;
7825         if (!G_traps && !mask)
7826                 return; /* already no traps and no special sigs */
7827
7828         /* Switch off special sigs */
7829         switch_off_special_sigs(mask);
7830 # if ENABLE_HUSH_JOB
7831         G_fatal_sig_mask = 0;
7832 # endif
7833         G.special_sig_mask &= ~SPECIAL_INTERACTIVE_SIGS;
7834         /* SIGQUIT,SIGCHLD and maybe SPECIAL_JOBSTOP_SIGS
7835          * remain set in G.special_sig_mask */
7836
7837 # if ENABLE_HUSH_TRAP
7838         if (!G_traps)
7839                 return;
7840
7841         /* Reset all sigs to default except ones with empty traps */
7842         for (sig = 0; sig < NSIG; sig++) {
7843                 if (!G_traps[sig])
7844                         continue; /* no trap: nothing to do */
7845                 if (!G_traps[sig][0])
7846                         continue; /* empty trap: has to remain SIG_IGN */
7847                 /* sig has non-empty trap, reset it: */
7848                 free(G_traps[sig]);
7849                 G_traps[sig] = NULL;
7850                 /* There is no signal for trap 0 (EXIT) */
7851                 if (sig == 0)
7852                         continue;
7853                 install_sighandler(sig, pick_sighandler(sig));
7854         }
7855 # endif
7856 }
7857
7858 #else /* !BB_MMU */
7859
7860 static void re_execute_shell(char ***to_free, const char *s,
7861                 char *g_argv0, char **g_argv,
7862                 char **builtin_argv) NORETURN;
7863 static void re_execute_shell(char ***to_free, const char *s,
7864                 char *g_argv0, char **g_argv,
7865                 char **builtin_argv)
7866 {
7867 # define NOMMU_HACK_FMT ("-$%x:%x:%x:%x:%x:%llx" IF_HUSH_LOOPS(":%x"))
7868         /* delims + 2 * (number of bytes in printed hex numbers) */
7869         char param_buf[sizeof(NOMMU_HACK_FMT) + 2 * (sizeof(int)*6 + sizeof(long long)*1)];
7870         char *heredoc_argv[4];
7871         struct variable *cur;
7872 # if ENABLE_HUSH_FUNCTIONS
7873         struct function *funcp;
7874 # endif
7875         char **argv, **pp;
7876         unsigned cnt;
7877         unsigned long long empty_trap_mask;
7878
7879         if (!g_argv0) { /* heredoc */
7880                 argv = heredoc_argv;
7881                 argv[0] = (char *) G.argv0_for_re_execing;
7882                 argv[1] = (char *) "-<";
7883                 argv[2] = (char *) s;
7884                 argv[3] = NULL;
7885                 pp = &argv[3]; /* used as pointer to empty environment */
7886                 goto do_exec;
7887         }
7888
7889         cnt = 0;
7890         pp = builtin_argv;
7891         if (pp) while (*pp++)
7892                 cnt++;
7893
7894         empty_trap_mask = 0;
7895         if (G_traps) {
7896                 int sig;
7897                 for (sig = 1; sig < NSIG; sig++) {
7898                         if (G_traps[sig] && !G_traps[sig][0])
7899                                 empty_trap_mask |= 1LL << sig;
7900                 }
7901         }
7902
7903         sprintf(param_buf, NOMMU_HACK_FMT
7904                         , (unsigned) G.root_pid
7905                         , (unsigned) G.root_ppid
7906                         , (unsigned) G.last_bg_pid
7907                         , (unsigned) G.last_exitcode
7908                         , cnt
7909                         , empty_trap_mask
7910                         IF_HUSH_LOOPS(, G.depth_of_loop)
7911                         );
7912 # undef NOMMU_HACK_FMT
7913         /* 1:hush 2:-$<pid>:<pid>:<exitcode>:<etc...> <vars...> <funcs...>
7914          * 3:-c 4:<cmd> 5:<arg0> <argN...> 6:NULL
7915          */
7916         cnt += 6;
7917         for (cur = G.top_var; cur; cur = cur->next) {
7918                 if (!cur->flg_export || cur->flg_read_only)
7919                         cnt += 2;
7920         }
7921 # if ENABLE_HUSH_LINENO_VAR
7922         cnt += 2;
7923 # endif
7924 # if ENABLE_HUSH_FUNCTIONS
7925         for (funcp = G.top_func; funcp; funcp = funcp->next)
7926                 cnt += 3;
7927 # endif
7928         pp = g_argv;
7929         while (*pp++)
7930                 cnt++;
7931         *to_free = argv = pp = xzalloc(sizeof(argv[0]) * cnt);
7932         *pp++ = (char *) G.argv0_for_re_execing;
7933         *pp++ = param_buf;
7934         for (cur = G.top_var; cur; cur = cur->next) {
7935                 if (strcmp(cur->varstr, hush_version_str) == 0)
7936                         continue;
7937                 if (cur->flg_read_only) {
7938                         *pp++ = (char *) "-R";
7939                         *pp++ = cur->varstr;
7940                 } else if (!cur->flg_export) {
7941                         *pp++ = (char *) "-V";
7942                         *pp++ = cur->varstr;
7943                 }
7944         }
7945 # if ENABLE_HUSH_LINENO_VAR
7946         *pp++ = (char *) "-L";
7947         *pp++ = utoa(G.execute_lineno);
7948 # endif
7949 # if ENABLE_HUSH_FUNCTIONS
7950         for (funcp = G.top_func; funcp; funcp = funcp->next) {
7951                 *pp++ = (char *) "-F";
7952                 *pp++ = funcp->name;
7953                 *pp++ = funcp->body_as_string;
7954         }
7955 # endif
7956         /* We can pass activated traps here. Say, -Tnn:trap_string
7957          *
7958          * However, POSIX says that subshells reset signals with traps
7959          * to SIG_DFL.
7960          * I tested bash-3.2 and it not only does that with true subshells
7961          * of the form ( list ), but with any forked children shells.
7962          * I set trap "echo W" WINCH; and then tried:
7963          *
7964          * { echo 1; sleep 20; echo 2; } &
7965          * while true; do echo 1; sleep 20; echo 2; break; done &
7966          * true | { echo 1; sleep 20; echo 2; } | cat
7967          *
7968          * In all these cases sending SIGWINCH to the child shell
7969          * did not run the trap. If I add trap "echo V" WINCH;
7970          * _inside_ group (just before echo 1), it works.
7971          *
7972          * I conclude it means we don't need to pass active traps here.
7973          */
7974         *pp++ = (char *) "-c";
7975         *pp++ = (char *) s;
7976         if (builtin_argv) {
7977                 while (*++builtin_argv)
7978                         *pp++ = *builtin_argv;
7979                 *pp++ = (char *) "";
7980         }
7981         *pp++ = g_argv0;
7982         while (*g_argv)
7983                 *pp++ = *g_argv++;
7984         /* *pp = NULL; - is already there */
7985         pp = environ;
7986
7987  do_exec:
7988         debug_printf_exec("re_execute_shell pid:%d cmd:'%s'\n", getpid(), s);
7989         /* Don't propagate SIG_IGN to the child */
7990         if (SPECIAL_JOBSTOP_SIGS != 0)
7991                 switch_off_special_sigs(G.special_sig_mask & SPECIAL_JOBSTOP_SIGS);
7992         execve(bb_busybox_exec_path, argv, pp);
7993         /* Fallback. Useful for init=/bin/hush usage etc */
7994         if (argv[0][0] == '/')
7995                 execve(argv[0], argv, pp);
7996         xfunc_error_retval = 127;
7997         bb_simple_error_msg_and_die("can't re-execute the shell");
7998 }
7999 #endif  /* !BB_MMU */
8000
8001 #endif /* !__U_BOOT__ */
8002
8003 static int run_and_free_list(struct pipe *pi);
8004
8005 /* Executing from string: eval, sh -c '...'
8006  *          or from file: /etc/profile, . file, sh <script>, sh (intereactive)
8007  * end_trigger controls how often we stop parsing
8008  * NUL: parse all, execute, return
8009  * ';': parse till ';' or newline, execute, repeat till EOF
8010  */
8011 #ifndef __U_BOOT__
8012 static void parse_and_run_stream(struct in_str *inp, int end_trigger)
8013 #else /* __U_BOOT__ */
8014 static int parse_and_run_stream(struct in_str *inp, int end_trigger)
8015 #endif /* __U_BOOT__ */
8016 {
8017         /* Why we need empty flag?
8018          * An obscure corner case "false; ``; echo $?":
8019          * empty command in `` should still set $? to 0.
8020          * But we can't just set $? to 0 at the start,
8021          * this breaks "false; echo `echo $?`" case.
8022          */
8023         bool empty = 1;
8024 #ifndef __U_BOOT__
8025         while (1) {
8026 #else /* __U_BOOT__ */
8027         do {
8028 #endif /* __U_BOOT__ */
8029                 struct pipe *pipe_list;
8030
8031 #if ENABLE_HUSH_INTERACTIVE
8032                 if (end_trigger == ';') {
8033                         G.promptmode = 0; /* PS1 */
8034                         debug_printf_prompt("%s promptmode=%d\n", __func__, G.promptmode);
8035                 }
8036 #endif
8037                 pipe_list = parse_stream(NULL, NULL, inp, end_trigger);
8038                 if (!pipe_list || pipe_list == ERR_PTR) { /* EOF/error */
8039                         /* If we are in "big" script
8040                          * (not in `cmd` or something similar)...
8041                          */
8042                         if (pipe_list == ERR_PTR && end_trigger == ';') {
8043                                 /* Discard cached input (rest of line) */
8044                                 int ch = inp->last_char;
8045                                 while (ch != EOF && ch != '\n') {
8046                                         //bb_error_msg("Discarded:'%c'", ch);
8047                                         ch = i_getch(inp);
8048                                 }
8049                                 /* Force prompt */
8050                                 inp->p = NULL;
8051                                 /* This stream isn't empty */
8052                                 empty = 0;
8053                                 continue;
8054                         }
8055                         if (!pipe_list && empty)
8056                                 G.last_exitcode = 0;
8057                         break;
8058                 }
8059                 debug_print_tree(pipe_list, 0);
8060                 debug_printf_exec("parse_and_run_stream: run_and_free_list\n");
8061 #ifndef __U_BOOT__
8062                 run_and_free_list(pipe_list);
8063 #else /* __U_BOOT__ */
8064                 int rcode = run_and_free_list(pipe_list);
8065                 /*
8066                  * We reset input string to not run the following command, so running
8067                  * 'exit; echo foo' does not print foo.
8068                  */
8069                 if (rcode <= EXIT_RET_CODE)
8070                         setup_file_in_str(inp);
8071 #endif /* __U_BOOT__ */
8072                 empty = 0;
8073                 if (G_flag_return_in_progress == 1)
8074                         break;
8075 #ifndef __U_BOOT__
8076         }
8077 #else /* __U_BOOT__ */
8078         /*
8079          * This do/while is needed by run_command to avoid looping on a command
8080          * with syntax error.
8081          */
8082         } while (!(G.run_command_flags & FLAG_EXIT_FROM_LOOP));
8083
8084         return G.last_exitcode;
8085 #endif /* __U_BOOT__ */
8086 }
8087
8088 #ifndef __U_BOOT__
8089 static void parse_and_run_string(const char *s)
8090 #else /* __U_BOOT__ */
8091 static int parse_and_run_string(const char *s)
8092 #endif /* __U_BOOT__ */
8093 {
8094         struct in_str input;
8095 #ifndef __U_BOOT__
8096         IF_HUSH_LINENO_VAR(unsigned sv = G.parse_lineno;)
8097 #else /* __U_BOOT__ */
8098         //IF_HUSH_LINENO_VAR(unsigned sv = G.parse_lineno;)
8099 #endif /* __U_BOOT__ */
8100
8101         setup_string_in_str(&input, s);
8102 #ifndef __U_BOOT__
8103         parse_and_run_stream(&input, '\0');
8104 #else /* __U_BOOT__ */
8105         return parse_and_run_stream(&input, '\0');
8106 #endif /* __U_BOOT__ */
8107 #ifndef __U_BOOT__
8108         IF_HUSH_LINENO_VAR(unsigned sv = G.parse_lineno;)
8109 #else /* __U_BOOT__ */
8110         //IF_HUSH_LINENO_VAR(unsigned sv = G.parse_lineno;)
8111 #endif /* __U_BOOT__ */
8112 }
8113
8114 #ifdef __U_BOOT__
8115 int parse_string_outer_modern(const char *cmd, int flags)
8116 {
8117         int ret;
8118         int old_flags;
8119
8120         /*
8121          * Keep old values of run_command to be able to restore them once
8122          * command was executed.
8123          */
8124         old_flags = G.run_command_flags;
8125         G.run_command_flags = flags;
8126
8127         ret = parse_and_run_string(cmd);
8128
8129         G.run_command_flags = old_flags;
8130
8131         return ret;
8132 }
8133 #endif /* __U_BOOT__ */
8134 #ifndef __U_BOOT__
8135 static void parse_and_run_file(HFILE *fp)
8136 #else /* __U_BOOT__ */
8137 void parse_and_run_file(void)
8138 #endif /* __U_BOOT__ */
8139 {
8140         struct in_str input;
8141 #ifndef __U_BOOT__
8142         IF_HUSH_LINENO_VAR(unsigned sv = G.parse_lineno;)
8143
8144         IF_HUSH_LINENO_VAR(G.parse_lineno = 1;)
8145         setup_file_in_str(&input, fp);
8146 #else /* __U_BOOT__ */
8147         setup_file_in_str(&input);
8148 #endif /* __U_BOOT__ */
8149         parse_and_run_stream(&input, ';');
8150 #ifndef __U_BOOT__
8151         IF_HUSH_LINENO_VAR(G.parse_lineno = sv;)
8152 #endif /* !__U_BOOT__ */
8153 }
8154
8155 #ifndef __U_BOOT__
8156 #if ENABLE_HUSH_TICK
8157 static int generate_stream_from_string(const char *s, pid_t *pid_p)
8158 {
8159         pid_t pid;
8160         int channel[2];
8161 # if !BB_MMU
8162         char **to_free = NULL;
8163 # endif
8164
8165         xpipe(channel);
8166         pid = BB_MMU ? xfork() : xvfork();
8167         if (pid == 0) { /* child */
8168                 disable_restore_tty_pgrp_on_exit();
8169                 /* Process substitution is not considered to be usual
8170                  * 'command execution'.
8171                  * SUSv3 says ctrl-Z should be ignored, ctrl-C should not.
8172                  */
8173                 bb_signals(0
8174                         + (1 << SIGTSTP)
8175                         + (1 << SIGTTIN)
8176                         + (1 << SIGTTOU)
8177                         , SIG_IGN);
8178                 close(channel[0]); /* NB: close _first_, then move fd! */
8179                 xmove_fd(channel[1], 1);
8180 # if ENABLE_HUSH_TRAP
8181                 /* Awful hack for `trap` or $(trap).
8182                  *
8183                  * http://www.opengroup.org/onlinepubs/009695399/utilities/trap.html
8184                  * contains an example where "trap" is executed in a subshell:
8185                  *
8186                  * save_traps=$(trap)
8187                  * ...
8188                  * eval "$save_traps"
8189                  *
8190                  * Standard does not say that "trap" in subshell shall print
8191                  * parent shell's traps. It only says that its output
8192                  * must have suitable form, but then, in the above example
8193                  * (which is not supposed to be normative), it implies that.
8194                  *
8195                  * bash (and probably other shell) does implement it
8196                  * (traps are reset to defaults, but "trap" still shows them),
8197                  * but as a result, "trap" logic is hopelessly messed up:
8198                  *
8199                  * # trap
8200                  * trap -- 'echo Ho' SIGWINCH  <--- we have a handler
8201                  * # (trap)        <--- trap is in subshell - no output (correct, traps are reset)
8202                  * # true | trap   <--- trap is in subshell - no output (ditto)
8203                  * # echo `true | trap`    <--- in subshell - output (but traps are reset!)
8204                  * trap -- 'echo Ho' SIGWINCH
8205                  * # echo `(trap)`         <--- in subshell in subshell - output
8206                  * trap -- 'echo Ho' SIGWINCH
8207                  * # echo `true | (trap)`  <--- in subshell in subshell in subshell - output!
8208                  * trap -- 'echo Ho' SIGWINCH
8209                  *
8210                  * The rules when to forget and when to not forget traps
8211                  * get really complex and nonsensical.
8212                  *
8213                  * Our solution: ONLY bare $(trap) or `trap` is special.
8214                  */
8215                 s = skip_whitespace(s);
8216                 if (is_prefixed_with(s, "trap")
8217                  && skip_whitespace(s + 4)[0] == '\0'
8218                 ) {
8219                         static const char *const argv[] ALIGN_PTR = { NULL, NULL };
8220                         builtin_trap((char**)argv);
8221                         fflush_all(); /* important */
8222                         _exit(0);
8223                 }
8224 # endif
8225 # if BB_MMU
8226                 /* Prevent it from trying to handle ctrl-z etc */
8227                 IF_HUSH_JOB(G.run_list_level = 1;)
8228                 CLEAR_RANDOM_T(&G.random_gen); /* or else $RANDOM repeats in child */
8229                 reset_traps_to_defaults();
8230                 IF_HUSH_MODE_X(G.x_mode_depth++;)
8231                 //bb_error_msg("%s: ++x_mode_depth=%d", __func__, G.x_mode_depth);
8232                 parse_and_run_string(s);
8233                 _exit(G.last_exitcode);
8234 # else
8235         /* We re-execute after vfork on NOMMU. This makes this script safe:
8236          * yes "0123456789012345678901234567890" | dd bs=32 count=64k >BIG
8237          * huge=`cat BIG` # was blocking here forever
8238          * echo OK
8239          */
8240                 re_execute_shell(&to_free,
8241                                 s,
8242                                 G.global_argv[0],
8243                                 G.global_argv + 1,
8244                                 NULL);
8245 # endif
8246         }
8247
8248         /* parent */
8249         *pid_p = pid;
8250 # if ENABLE_HUSH_FAST
8251         G.count_SIGCHLD++;
8252 //bb_error_msg("[%d] fork in generate_stream_from_string:"
8253 //              " G.count_SIGCHLD:%d G.handled_SIGCHLD:%d",
8254 //              getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
8255 # endif
8256         enable_restore_tty_pgrp_on_exit();
8257 # if !BB_MMU
8258         free(to_free);
8259 # endif
8260         close(channel[1]);
8261         return channel[0];
8262 }
8263
8264 /* Return code is exit status of the process that is run. */
8265 static int process_command_subs(o_string *dest, const char *s)
8266 {
8267         FILE *fp;
8268         pid_t pid;
8269         int status, ch, eol_cnt;
8270
8271         fp = xfdopen_for_read(generate_stream_from_string(s, &pid));
8272
8273         /* Now send results of command back into original context */
8274         eol_cnt = 0;
8275         while ((ch = getc(fp)) != EOF) {
8276                 if (ch == '\0')
8277                         continue;
8278                 if (ch == '\n') {
8279                         eol_cnt++;
8280                         continue;
8281                 }
8282                 while (eol_cnt) {
8283                         o_addchr(dest, '\n');
8284                         eol_cnt--;
8285                 }
8286                 o_addQchr(dest, ch);
8287         }
8288
8289         debug_printf("done reading from `cmd` pipe, closing it\n");
8290         fclose(fp);
8291         /* We need to extract exitcode. Test case
8292          * "true; echo `sleep 1; false` $?"
8293          * should print 1 */
8294         safe_waitpid(pid, &status, 0);
8295         debug_printf("child exited. returning its exitcode:%d\n", WEXITSTATUS(status));
8296         return WEXITSTATUS(status);
8297 }
8298 #endif /* ENABLE_HUSH_TICK */
8299
8300 static void setup_heredoc(struct redir_struct *redir)
8301 {
8302         struct fd_pair pair;
8303         pid_t pid;
8304         int len, written;
8305         /* the _body_ of heredoc (misleading field name) */
8306         const char *heredoc = redir->rd_filename;
8307         char *expanded;
8308 #if !BB_MMU
8309         char **to_free;
8310 #endif
8311
8312         expanded = NULL;
8313         if (!(redir->rd_dup & HEREDOC_QUOTED)) {
8314                 expanded = encode_then_expand_string(heredoc);
8315                 if (expanded)
8316                         heredoc = expanded;
8317         }
8318         len = strlen(heredoc);
8319
8320         close(redir->rd_fd); /* often saves dup2+close in xmove_fd */
8321         xpiped_pair(pair);
8322         xmove_fd(pair.rd, redir->rd_fd);
8323
8324         /* Try writing without forking. Newer kernels have
8325          * dynamically growing pipes. Must use non-blocking write! */
8326         ndelay_on(pair.wr);
8327         while (1) {
8328                 written = write(pair.wr, heredoc, len);
8329                 if (written <= 0)
8330                         break;
8331                 len -= written;
8332                 if (len == 0) {
8333                         close(pair.wr);
8334                         free(expanded);
8335                         return;
8336                 }
8337                 heredoc += written;
8338         }
8339         ndelay_off(pair.wr);
8340
8341         /* Okay, pipe buffer was not big enough */
8342         /* Note: we must not create a stray child (bastard? :)
8343          * for the unsuspecting parent process. Child creates a grandchild
8344          * and exits before parent execs the process which consumes heredoc
8345          * (that exec happens after we return from this function) */
8346 #if !BB_MMU
8347         to_free = NULL;
8348 #endif
8349         pid = xvfork();
8350         if (pid == 0) {
8351                 /* child */
8352                 disable_restore_tty_pgrp_on_exit();
8353                 pid = BB_MMU ? xfork() : xvfork();
8354                 if (pid != 0)
8355                         _exit(0);
8356                 /* grandchild */
8357                 close(redir->rd_fd); /* read side of the pipe */
8358 #if BB_MMU
8359                 full_write(pair.wr, heredoc, len); /* may loop or block */
8360                 _exit(0);
8361 #else
8362                 /* Delegate blocking writes to another process */
8363                 xmove_fd(pair.wr, STDOUT_FILENO);
8364                 re_execute_shell(&to_free, heredoc, NULL, NULL, NULL);
8365 #endif
8366         }
8367         /* parent */
8368 #if ENABLE_HUSH_FAST
8369         G.count_SIGCHLD++;
8370 //bb_error_msg("[%d] fork in setup_heredoc: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
8371 #endif
8372         enable_restore_tty_pgrp_on_exit();
8373 #if !BB_MMU
8374         free(to_free);
8375 #endif
8376         close(pair.wr);
8377         free(expanded);
8378         wait(NULL); /* wait till child has died */
8379 }
8380
8381 struct squirrel {
8382         int orig_fd;
8383         int moved_to;
8384         /* moved_to = n: fd was moved to n; restore back to orig_fd after redir */
8385         /* moved_to = -1: fd was opened by redirect; close orig_fd after redir */
8386 };
8387
8388 static struct squirrel *append_squirrel(struct squirrel *sq, int i, int orig, int moved)
8389 {
8390         sq = xrealloc(sq, (i + 2) * sizeof(sq[0]));
8391         sq[i].orig_fd = orig;
8392         sq[i].moved_to = moved;
8393         sq[i+1].orig_fd = -1; /* end marker */
8394         return sq;
8395 }
8396
8397 static struct squirrel *add_squirrel(struct squirrel *sq, int fd, int avoid_fd)
8398 {
8399         int moved_to;
8400         int i;
8401
8402         i = 0;
8403         if (sq) for (; sq[i].orig_fd >= 0; i++) {
8404                 /* If we collide with an already moved fd... */
8405                 if (fd == sq[i].moved_to) {
8406                         moved_to = dup_CLOEXEC(sq[i].moved_to, avoid_fd);
8407                         debug_printf_redir("redirect_fd %d: already busy, moving to %d\n", fd, moved_to);
8408                         if (moved_to < 0) {
8409                                 /* "echo 2>/dev/tty 10>&9999" testcase:
8410                                  * We move fd 2 to 10, then discover we need to move fd 10
8411                                  * (and not hit 9999) and the latter fails.
8412                                  */
8413                                 return NULL; /* fcntl failed */
8414                         }
8415                         sq[i].moved_to = moved_to;
8416                         return sq;
8417                 }
8418                 if (fd == sq[i].orig_fd) {
8419                         /* Example: echo Hello >/dev/null 1>&2 */
8420                         debug_printf_redir("redirect_fd %d: already moved\n", fd);
8421                         return sq;
8422                 }
8423         }
8424
8425         /* If this fd is open, we move and remember it; if it's closed, moved_to = -1 */
8426         moved_to = dup_CLOEXEC(fd, avoid_fd);
8427         debug_printf_redir("redirect_fd %d: previous fd is moved to %d (-1 if it was closed)\n", fd, moved_to);
8428         if (moved_to < 0 && errno != EBADF)
8429                 return NULL; /* fcntl failed (not because fd is closed) */
8430         return append_squirrel(sq, i, fd, moved_to);
8431 }
8432
8433 static struct squirrel *add_squirrel_closed(struct squirrel *sq, int fd)
8434 {
8435         int i;
8436
8437         i = 0;
8438         if (sq) for (; sq[i].orig_fd >= 0; i++) {
8439                 /* If we collide with an already moved fd... */
8440                 if (fd == sq[i].orig_fd) {
8441                         /* Examples:
8442                          * "echo 3>FILE 3>&- 3>FILE"
8443                          * "echo 3>&- 3>FILE"
8444                          * No need for last redirect to insert
8445                          * another "need to close 3" indicator.
8446                          */
8447                         debug_printf_redir("redirect_fd %d: already moved or closed\n", fd);
8448                         return sq;
8449                 }
8450         }
8451
8452         debug_printf_redir("redirect_fd %d: previous fd was closed\n", fd);
8453         return append_squirrel(sq, i, fd, -1);
8454 }
8455
8456 /* fd: redirect wants this fd to be used (e.g. 3>file).
8457  * Move all conflicting internally used fds,
8458  * and remember them so that we can restore them later.
8459  */
8460 static int save_fd_on_redirect(int fd, int avoid_fd, struct squirrel **sqp)
8461 {
8462         struct squirrel *new_squirrel;
8463
8464         if (avoid_fd < 9) /* the important case here is that it can be -1 */
8465                 avoid_fd = 9;
8466
8467 #if ENABLE_HUSH_INTERACTIVE
8468         if (fd != 0 /* don't trigger for G_interactive_fd == 0 (that's "not interactive" flag) */
8469          && fd == G_interactive_fd
8470         ) {
8471                 /* Testcase: "ls -l /proc/$$/fd 255>&-" should work */
8472                 G_interactive_fd = xdup_CLOEXEC_and_close(G_interactive_fd, avoid_fd);
8473                 debug_printf_redir("redirect_fd %d: matches interactive_fd, moving it to %d\n", fd, G_interactive_fd);
8474                 return 1; /* "we closed fd" */
8475         }
8476 #endif
8477         /* Are we called from setup_redirects(squirrel==NULL)
8478          * in redirect in a [v]forked child?
8479          */
8480         if (sqp == NULL) {
8481                 /* No need to move script fds.
8482                  * For NOMMU case, it's actively wrong: we'd change ->fd
8483                  * fields in memory for the parent, but parent's fds
8484                  * aren't moved, it would use wrong fd!
8485                  * Reproducer: "cmd 3>FILE" in script.
8486                  * If we would call move_HFILEs_on_redirect(), child would:
8487                  *  fcntl64(3, F_DUPFD_CLOEXEC, 10)   = 10
8488                  *  close(3)                          = 0
8489                  * and change ->fd to 10 if fd#3 is a script fd. WRONG.
8490                  */
8491                 //bb_error_msg("sqp == NULL: [v]forked child");
8492                 return 0;
8493         }
8494
8495         /* If this one of script's fds? */
8496         if (move_HFILEs_on_redirect(fd, avoid_fd))
8497                 return 1; /* yes. "we closed fd" (actually moved it) */
8498
8499         /* Are we called for "exec 3>FILE"? Came through
8500          * redirect_and_varexp_helper(squirrel=ERR_PTR) -> setup_redirects(ERR_PTR)
8501          * This case used to fail for this script:
8502          *  exec 3>FILE
8503          *  echo Ok
8504          *  ...100000 more lines...
8505          *  echo Ok
8506          * as follows:
8507          *  read(3, "exec 3>FILE\necho Ok\necho Ok"..., 1024) = 1024
8508          *  open("FILE", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 4
8509          *  dup2(4, 3)                        = 3
8510          *  ^^^^^^^^ oops, we lost fd#3 opened to our script!
8511          *  close(4)                          = 0
8512          *  write(1, "Ok\n", 3)               = 3
8513          *  ...                               = 3
8514          *  write(1, "Ok\n", 3)               = 3
8515          *  read(3, 0x94fbc08, 1024)          = -1 EBADF (Bad file descriptor)
8516          *  ^^^^^^^^ oops, wrong fd!!!
8517          * With this case separate from sqp == NULL and *after* move_HFILEs,
8518          * it now works:
8519          */
8520         if (sqp == ERR_PTR) {
8521                 /* Don't preserve redirected fds: exec is _meant_ to change these */
8522                 //bb_error_msg("sqp == ERR_PTR: exec >FILE");
8523                 return 0;
8524         }
8525
8526         /* Check whether it collides with any open fds (e.g. stdio), save fds as needed */
8527         new_squirrel = add_squirrel(*sqp, fd, avoid_fd);
8528         if (!new_squirrel)
8529                 return -1; /* redirect error */
8530         *sqp = new_squirrel;
8531         return 0; /* "we did not close fd" */
8532 }
8533
8534 static void restore_redirects(struct squirrel *sq)
8535 {
8536         if (sq) {
8537                 int i;
8538                 for (i = 0; sq[i].orig_fd >= 0; i++) {
8539                         if (sq[i].moved_to >= 0) {
8540                                 /* We simply die on error */
8541                                 debug_printf_redir("restoring redirected fd from %d to %d\n", sq[i].moved_to, sq[i].orig_fd);
8542                                 xmove_fd(sq[i].moved_to, sq[i].orig_fd);
8543                         } else {
8544                                 /* cmd1 9>FILE; cmd2_should_see_fd9_closed */
8545                                 debug_printf_redir("restoring redirected fd %d: closing it\n", sq[i].orig_fd);
8546                                 close(sq[i].orig_fd);
8547                         }
8548                 }
8549                 free(sq);
8550         }
8551         if (G.HFILE_stdin
8552          && G.HFILE_stdin->fd > STDIN_FILENO
8553         /* we compare > STDIN, not == STDIN, since hfgetc()
8554          * closes fd and sets ->fd to -1 if EOF is reached.
8555          * Testcase: echo 'pwd' | hush
8556          */
8557         ) {
8558                 /* Testcase: interactive "read r <FILE; echo $r; read r; echo $r".
8559                  * Redirect moves ->fd to e.g. 10,
8560                  * and it is not restored above (we do not restore script fds
8561                  * after redirects, we just use new, "moved" fds).
8562                  * However for stdin, get_user_input() -> read_line_input(),
8563                  * and read builtin, depend on fd == STDIN_FILENO.
8564                  */
8565                 debug_printf_redir("restoring %d to stdin\n", G.HFILE_stdin->fd);
8566                 xmove_fd(G.HFILE_stdin->fd, STDIN_FILENO);
8567                 G.HFILE_stdin->fd = STDIN_FILENO;
8568         }
8569
8570         /* If moved, G_interactive_fd stays on new fd, not restoring it */
8571 }
8572
8573 #if ENABLE_FEATURE_SH_STANDALONE && BB_MMU
8574 static void close_saved_fds_and_FILE_fds(void)
8575 {
8576         if (G_interactive_fd)
8577                 close(G_interactive_fd);
8578         close_all_HFILE_list();
8579 }
8580 #endif
8581
8582 static int internally_opened_fd(int fd, struct squirrel *sq)
8583 {
8584         int i;
8585
8586 #if ENABLE_HUSH_INTERACTIVE
8587         if (fd == G_interactive_fd)
8588                 return 1;
8589 #endif
8590         /* If this one of script's fds? */
8591         if (fd_in_HFILEs(fd))
8592                 return 1;
8593
8594         if (sq) for (i = 0; sq[i].orig_fd >= 0; i++) {
8595                 if (fd == sq[i].moved_to)
8596                         return 1;
8597         }
8598         return 0;
8599 }
8600
8601 /* sqp != NULL means we squirrel away copies of stdin, stdout,
8602  * and stderr if they are redirected.
8603  * If redirection fails, return 1. This will make caller
8604  * skip command execution and restore already created redirect fds.
8605  */
8606 static int setup_redirects(struct command *prog, struct squirrel **sqp)
8607 {
8608         struct redir_struct *redir;
8609
8610         for (redir = prog->redirects; redir; redir = redir->next) {
8611                 int newfd;
8612                 int closed;
8613
8614                 if (redir->rd_type == REDIRECT_HEREDOC2) {
8615                         /* "rd_fd<<HERE" case */
8616                         if (save_fd_on_redirect(redir->rd_fd, /*avoid:*/ 0, sqp) < 0)
8617                                 return 1;
8618                         /* for REDIRECT_HEREDOC2, rd_filename holds _contents_
8619                          * of the heredoc */
8620                         debug_printf_redir("set heredoc '%s'\n",
8621                                         redir->rd_filename);
8622                         setup_heredoc(redir);
8623                         continue;
8624                 }
8625
8626                 if (redir->rd_dup == REDIRFD_TO_FILE) {
8627                         /* "rd_fd<*>file" case (<*> is <,>,>>,<>) */
8628                         char *p;
8629                         int mode;
8630
8631                         if (redir->rd_filename == NULL) {
8632                                 /* Examples:
8633                                  * "cmd >" (no filename)
8634                                  * "cmd > <file" (2nd redirect starts too early)
8635                                  */
8636                                 syntax_error("invalid redirect");
8637                                 return 1;
8638                         }
8639                         mode = redir_table[redir->rd_type].mode;
8640                         p = expand_string_to_string(redir->rd_filename,
8641                                 EXP_FLAG_ESC_GLOB_CHARS, /*unbackslash:*/ 1);
8642                         newfd = open_or_warn(p, mode);
8643                         free(p);
8644                         if (newfd < 0) {
8645                                 /* Error message from open_or_warn can be lost
8646                                  * if stderr has been redirected, but bash
8647                                  * and ash both lose it as well
8648                                  * (though zsh doesn't!)
8649                                  */
8650                                 return 1;
8651                         }
8652                         if (newfd == redir->rd_fd && sqp
8653                          && sqp != ERR_PTR /* not a redirect in "exec" */
8654                         ) {
8655                                 /* open() gave us precisely the fd we wanted.
8656                                  * This means that this fd was not busy
8657                                  * (not opened to anywhere).
8658                                  * Remember to close it on restore:
8659                                  */
8660                                 *sqp = add_squirrel_closed(*sqp, newfd);
8661                                 debug_printf_redir("redir to previously closed fd %d\n", newfd);
8662                         }
8663                 } else {
8664                         /* "rd_fd>&rd_dup" or "rd_fd>&-" case */
8665                         newfd = redir->rd_dup;
8666                 }
8667
8668                 if (newfd == redir->rd_fd)
8669                         continue;
8670
8671                 /* if "N>FILE": move newfd to redir->rd_fd */
8672                 /* if "N>&M": dup newfd to redir->rd_fd */
8673                 /* if "N>&-": close redir->rd_fd (newfd is REDIRFD_CLOSE) */
8674
8675                 closed = save_fd_on_redirect(redir->rd_fd, /*avoid:*/ newfd, sqp);
8676                 if (closed < 0)
8677                         return 1; /* error */
8678                 if (newfd == REDIRFD_CLOSE) {
8679                         /* "N>&-" means "close me" */
8680                         if (!closed) {
8681                                 /* ^^^ optimization: saving may already
8682                                  * have closed it. If not... */
8683                                 close(redir->rd_fd);
8684                         }
8685                         /* Sometimes we do another close on restore, getting EBADF.
8686                          * Consider "echo 3>FILE 3>&-"
8687                          * first redirect remembers "need to close 3",
8688                          * and second redirect closes 3! Restore code then closes 3 again.
8689                          */
8690                 } else {
8691                         /* if newfd is a script fd or saved fd, do not allow to use it */
8692                         if (internally_opened_fd(newfd, sqp && sqp != ERR_PTR ? *sqp : NULL)) {
8693                                 bb_error_msg("fd#%d is not open", newfd);
8694                                 return 1;
8695                         }
8696                         if (dup2(newfd, redir->rd_fd) < 0) {
8697                                 /* "echo >&99" testcase */
8698                                 bb_perror_msg("dup2(%d,%d)", newfd, redir->rd_fd);
8699                                 return 1;
8700                         }
8701                         if (redir->rd_dup == REDIRFD_TO_FILE)
8702                                 /* "rd_fd > FILE" */
8703                                 close(newfd);
8704                         /* else: "rd_fd > rd_dup" */
8705                 }
8706         }
8707         return 0;
8708 }
8709
8710 static char *find_in_path(const char *arg)
8711 {
8712         char *ret = NULL;
8713         const char *PATH = get_local_var_value("PATH");
8714
8715         if (!PATH)
8716                 return NULL;
8717
8718         while (1) {
8719                 const char *end = strchrnul(PATH, ':');
8720                 int sz = end - PATH; /* must be int! */
8721
8722                 free(ret);
8723                 if (sz != 0) {
8724                         ret = xasprintf("%.*s/%s", sz, PATH, arg);
8725                 } else {
8726                         /* We have xxx::yyyy in $PATH,
8727                          * it means "use current dir" */
8728                         ret = xstrdup(arg);
8729                 }
8730                 if (access(ret, F_OK) == 0)
8731                         break;
8732
8733                 if (*end == '\0') {
8734                         free(ret);
8735                         return NULL;
8736                 }
8737                 PATH = end + 1;
8738         }
8739
8740         return ret;
8741 }
8742
8743 static const struct built_in_command *find_builtin_helper(const char *name,
8744                 const struct built_in_command *x,
8745                 const struct built_in_command *end)
8746 {
8747         while (x != end) {
8748                 if (strcmp(name, x->b_cmd) != 0) {
8749                         x++;
8750                         continue;
8751                 }
8752                 debug_printf_exec("found builtin '%s'\n", name);
8753                 return x;
8754         }
8755         return NULL;
8756 }
8757 static const struct built_in_command *find_builtin1(const char *name)
8758 {
8759         return find_builtin_helper(name, bltins1, &bltins1[ARRAY_SIZE(bltins1)]);
8760 }
8761 static const struct built_in_command *find_builtin(const char *name)
8762 {
8763         const struct built_in_command *x = find_builtin1(name);
8764         if (x)
8765                 return x;
8766         return find_builtin_helper(name, bltins2, &bltins2[ARRAY_SIZE(bltins2)]);
8767 }
8768
8769 #if ENABLE_HUSH_JOB && ENABLE_FEATURE_TAB_COMPLETION
8770 static const char * FAST_FUNC hush_command_name(int i)
8771 {
8772         if (/*i >= 0 && */ i < ARRAY_SIZE(bltins1)) {
8773                 return bltins1[i].b_cmd;
8774         }
8775         i -= ARRAY_SIZE(bltins1);
8776         if (i < ARRAY_SIZE(bltins2)) {
8777                 return bltins2[i].b_cmd;
8778         }
8779 # if ENABLE_HUSH_FUNCTIONS
8780         {
8781                 struct function *funcp;
8782                 i -= ARRAY_SIZE(bltins2);
8783                 for (funcp = G.top_func; funcp; funcp = funcp->next) {
8784                         if (--i < 0)
8785                                 return funcp->name;
8786                 }
8787         }
8788 # endif
8789         return NULL;
8790 }
8791 #endif
8792 #endif /* !__U_BOOT__ */
8793
8794 #ifndef __U_BOOT__
8795 static void remove_nested_vars(void)
8796 {
8797         struct variable *cur;
8798         struct variable **cur_pp;
8799
8800         cur_pp = &G.top_var;
8801         while ((cur = *cur_pp) != NULL) {
8802                 if (cur->var_nest_level <= G.var_nest_level) {
8803                         cur_pp = &cur->next;
8804                         continue;
8805                 }
8806                 /* Unexport */
8807                 if (cur->flg_export) {
8808                         debug_printf_env("unexporting nested '%s'/%u\n", cur->varstr, cur->var_nest_level);
8809                         bb_unsetenv(cur->varstr);
8810                 }
8811                 /* Remove from global list */
8812                 *cur_pp = cur->next;
8813                 /* Free */
8814                 if (!cur->max_len) {
8815                         debug_printf_env("freeing nested '%s'/%u\n", cur->varstr, cur->var_nest_level);
8816                         free(cur->varstr);
8817                 }
8818                 free(cur);
8819         }
8820 }
8821
8822 static void enter_var_nest_level(void)
8823 {
8824         G.var_nest_level++;
8825         debug_printf_env("var_nest_level++ %u\n", G.var_nest_level);
8826
8827         /* Try: f() { echo -n .; f; }; f
8828          * struct variable::var_nest_level is uint16_t,
8829          * thus limiting recursion to < 2^16.
8830          * In any case, with 8 Mbyte stack SEGV happens
8831          * not too long after 2^16 recursions anyway.
8832          */
8833         if (G.var_nest_level > 0xff00)
8834                 bb_error_msg_and_die("fatal recursion (depth %u)", G.var_nest_level);
8835 }
8836
8837 static void leave_var_nest_level(void)
8838 {
8839         G.var_nest_level--;
8840         debug_printf_env("var_nest_level-- %u\n", G.var_nest_level);
8841         if (HUSH_DEBUG && (int)G.var_nest_level < 0)
8842                 bb_simple_error_msg_and_die("BUG: nesting underflow");
8843
8844         remove_nested_vars();
8845 }
8846 #endif /* __U_BOOT__ */
8847
8848 #if ENABLE_HUSH_FUNCTIONS
8849 static struct function **find_function_slot(const char *name)
8850 {
8851         struct function *funcp;
8852         struct function **funcpp = &G.top_func;
8853
8854         while ((funcp = *funcpp) != NULL) {
8855                 if (strcmp(name, funcp->name) == 0) {
8856                         debug_printf_exec("found function '%s'\n", name);
8857                         break;
8858                 }
8859                 funcpp = &funcp->next;
8860         }
8861         return funcpp;
8862 }
8863
8864 static ALWAYS_INLINE const struct function *find_function(const char *name)
8865 {
8866         const struct function *funcp = *find_function_slot(name);
8867         return funcp;
8868 }
8869
8870 /* Note: takes ownership on name ptr */
8871 static struct function *new_function(char *name)
8872 {
8873         struct function **funcpp = find_function_slot(name);
8874         struct function *funcp = *funcpp;
8875
8876         if (funcp != NULL) {
8877                 struct command *cmd = funcp->parent_cmd;
8878                 debug_printf_exec("func %p parent_cmd %p\n", funcp, cmd);
8879                 if (!cmd) {
8880                         debug_printf_exec("freeing & replacing function '%s'\n", funcp->name);
8881                         free(funcp->name);
8882                         /* Note: if !funcp->body, do not free body_as_string!
8883                          * This is a special case of "-F name body" function:
8884                          * body_as_string was not malloced! */
8885                         if (funcp->body) {
8886                                 free_pipe_list(funcp->body);
8887 # if !BB_MMU
8888                                 free(funcp->body_as_string);
8889 # endif
8890                         }
8891                 } else {
8892                         debug_printf_exec("reinserting in tree & replacing function '%s'\n", funcp->name);
8893                         cmd->argv[0] = funcp->name;
8894                         cmd->group = funcp->body;
8895 # if !BB_MMU
8896                         cmd->group_as_string = funcp->body_as_string;
8897 # endif
8898                 }
8899         } else {
8900                 debug_printf_exec("remembering new function '%s'\n", name);
8901                 funcp = *funcpp = xzalloc(sizeof(*funcp));
8902                 /*funcp->next = NULL;*/
8903         }
8904
8905         funcp->name = name;
8906         return funcp;
8907 }
8908
8909 # if ENABLE_HUSH_UNSET
8910 static void unset_func(const char *name)
8911 {
8912         struct function **funcpp = find_function_slot(name);
8913         struct function *funcp = *funcpp;
8914
8915         if (funcp != NULL) {
8916                 debug_printf_exec("freeing function '%s'\n", funcp->name);
8917                 *funcpp = funcp->next;
8918                 /* funcp is unlinked now, deleting it.
8919                  * Note: if !funcp->body, the function was created by
8920                  * "-F name body", do not free ->body_as_string
8921                  * and ->name as they were not malloced. */
8922                 if (funcp->body) {
8923                         free_pipe_list(funcp->body);
8924                         free(funcp->name);
8925 #  if !BB_MMU
8926                         free(funcp->body_as_string);
8927 #  endif
8928                 }
8929                 free(funcp);
8930         }
8931 }
8932 # endif
8933
8934 # if BB_MMU
8935 #define exec_function(to_free, funcp, argv) \
8936         exec_function(funcp, argv)
8937 # endif
8938 static void exec_function(char ***to_free,
8939                 const struct function *funcp,
8940                 char **argv) NORETURN;
8941 static void exec_function(char ***to_free,
8942                 const struct function *funcp,
8943                 char **argv)
8944 {
8945 # if BB_MMU
8946         int n;
8947
8948         argv[0] = G.global_argv[0];
8949         G.global_argv = argv;
8950         G.global_argc = n = 1 + string_array_len(argv + 1);
8951
8952 // Example when we are here: "cmd | func"
8953 // func will run with saved-redirect fds open.
8954 // $ f() { echo /proc/self/fd/*; }
8955 // $ true | f
8956 // /proc/self/fd/0 /proc/self/fd/1 /proc/self/fd/2 /proc/self/fd/255 /proc/self/fd/3
8957 // stdio^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ G_interactive_fd^ DIR fd for glob
8958 // Same in script:
8959 // $ . ./SCRIPT
8960 // /proc/self/fd/0 /proc/self/fd/1 /proc/self/fd/2 /proc/self/fd/255 /proc/self/fd/3 /proc/self/fd/4
8961 // stdio^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ G_interactive_fd^ opened ./SCRIPT DIR fd for glob
8962 // They are CLOEXEC so external programs won't see them, but
8963 // for "more correctness" we might want to close those extra fds here:
8964 //?     close_saved_fds_and_FILE_fds();
8965
8966         /* "we are in a function, ok to use return" */
8967         G_flag_return_in_progress = -1;
8968         enter_var_nest_level();
8969         IF_HUSH_LOCAL(G.func_nest_level++;)
8970
8971         /* On MMU, funcp->body is always non-NULL */
8972         n = run_list(funcp->body);
8973         _exit(n);
8974 # else
8975 //?     close_saved_fds_and_FILE_fds();
8976
8977 //TODO: check whether "true | func_with_return" works
8978
8979         re_execute_shell(to_free,
8980                         funcp->body_as_string,
8981                         G.global_argv[0],
8982                         argv + 1,
8983                         NULL);
8984 # endif
8985 }
8986
8987 static int run_function(const struct function *funcp, char **argv)
8988 {
8989         int rc;
8990         save_arg_t sv;
8991         smallint sv_flg;
8992
8993         save_and_replace_G_args(&sv, argv);
8994
8995         /* "We are in function, ok to use return" */
8996         sv_flg = G_flag_return_in_progress;
8997         G_flag_return_in_progress = -1;
8998
8999         /* Make "local" variables properly shadow previous ones */
9000         IF_HUSH_LOCAL(enter_var_nest_level();)
9001         IF_HUSH_LOCAL(G.func_nest_level++;)
9002
9003         /* On MMU, funcp->body is always non-NULL */
9004 # if !BB_MMU
9005         if (!funcp->body) {
9006                 /* Function defined by -F */
9007                 parse_and_run_string(funcp->body_as_string);
9008                 rc = G.last_exitcode;
9009         } else
9010 # endif
9011         {
9012                 rc = run_list(funcp->body);
9013         }
9014
9015         IF_HUSH_LOCAL(G.func_nest_level--;)
9016         IF_HUSH_LOCAL(leave_var_nest_level();)
9017
9018         G_flag_return_in_progress = sv_flg;
9019 # if ENABLE_HUSH_TRAP
9020         debug_printf_exec("G.return_exitcode=-1\n");
9021         G.return_exitcode = -1; /* invalidate stashed return value */
9022 # endif
9023
9024         restore_G_args(&sv, argv);
9025
9026         return rc;
9027 }
9028 #endif /* ENABLE_HUSH_FUNCTIONS */
9029
9030 #ifndef __U_BOOT__
9031 #if BB_MMU
9032 #define exec_builtin(to_free, x, argv) \
9033         exec_builtin(x, argv)
9034 #else
9035 #define exec_builtin(to_free, x, argv) \
9036         exec_builtin(to_free, argv)
9037 #endif
9038 static void exec_builtin(char ***to_free,
9039                 const struct built_in_command *x,
9040                 char **argv) NORETURN;
9041 static void exec_builtin(char ***to_free,
9042                 const struct built_in_command *x,
9043                 char **argv)
9044 {
9045 #if BB_MMU
9046         int rcode;
9047 //?     close_saved_fds_and_FILE_fds();
9048         rcode = x->b_function(argv);
9049         fflush_all();
9050         _exit(rcode);
9051 #else
9052         fflush_all();
9053         /* On NOMMU, we must never block!
9054          * Example: { sleep 99 | read line; } & echo Ok
9055          */
9056         re_execute_shell(to_free,
9057                         argv[0],
9058                         G.global_argv[0],
9059                         G.global_argv + 1,
9060                         argv);
9061 #endif
9062 }
9063 #endif /* !__U_BOOT__ */
9064
9065 #ifndef __U_BOOT__
9066 static void execvp_or_die(char **argv) NORETURN;
9067 static void execvp_or_die(char **argv)
9068 {
9069         int e;
9070         debug_printf_exec("execing '%s'\n", argv[0]);
9071         /* Don't propagate SIG_IGN to the child */
9072         if (SPECIAL_JOBSTOP_SIGS != 0)
9073                 switch_off_special_sigs(G.special_sig_mask & SPECIAL_JOBSTOP_SIGS);
9074         execvp(argv[0], argv);
9075         e = 2;
9076         if (errno == EACCES) e = 126;
9077         if (errno == ENOENT) e = 127;
9078         bb_perror_msg("can't execute '%s'", argv[0]);
9079         _exit(e);
9080 }
9081
9082 #if ENABLE_HUSH_MODE_X
9083 static void x_mode_print_optionally_squoted(const char *str)
9084 {
9085         unsigned len;
9086         const char *cp;
9087
9088         cp = str;
9089
9090         /* the set of chars which-cause-string-to-be-squoted mimics bash */
9091         /* test a char with: bash -c 'set -x; echo "CH"' */
9092         if (str[strcspn(str, "\\\"'`$(){}[]<>;#&|~*?!^"
9093                         " " "\001\002\003\004\005\006\007"
9094                         "\010\011\012\013\014\015\016\017"
9095                         "\020\021\022\023\024\025\026\027"
9096                         "\030\031\032\033\034\035\036\037"
9097                         )
9098                 ] == '\0'
9099         ) {
9100                 /* string has no special chars */
9101                 x_mode_addstr(str);
9102                 return;
9103         }
9104
9105         cp = str;
9106         for (;;) {
9107                 /* print '....' up to EOL or first squote */
9108                 len = (int)(strchrnul(cp, '\'') - cp);
9109                 if (len != 0) {
9110                         x_mode_addchr('\'');
9111                         x_mode_addblock(cp, len);
9112                         x_mode_addchr('\'');
9113                         cp += len;
9114                 }
9115                 if (*cp == '\0')
9116                         break;
9117                 /* string contains squote(s), print them as \' */
9118                 x_mode_addchr('\\');
9119                 x_mode_addchr('\'');
9120                 cp++;
9121         }
9122 }
9123 static void dump_cmd_in_x_mode(char **argv)
9124 {
9125         if (G_x_mode && argv) {
9126                 unsigned n;
9127
9128                 /* "+[+++...][ cmd...]\n\0" */
9129                 x_mode_prefix();
9130                 n = 0;
9131                 while (argv[n]) {
9132                         x_mode_addchr(' ');
9133                         if (argv[n][0] == '\0') {
9134                                 x_mode_addchr('\'');
9135                                 x_mode_addchr('\'');
9136                         } else {
9137                                 x_mode_print_optionally_squoted(argv[n]);
9138                         }
9139                         n++;
9140                 }
9141                 x_mode_flush();
9142         }
9143 }
9144 #else
9145 # define dump_cmd_in_x_mode(argv) ((void)0)
9146 #endif
9147 #endif /* !__U_BOOT__ */
9148
9149 #ifndef __U_BOOT__
9150 #if ENABLE_HUSH_COMMAND
9151 static void if_command_vV_print_and_exit(char opt_vV, char *cmd, const char *explanation)
9152 {
9153         char *to_free;
9154
9155         if (!opt_vV)
9156                 return;
9157
9158         to_free = NULL;
9159         if (!explanation) {
9160                 char *path = getenv("PATH");
9161                 explanation = to_free = find_executable(cmd, &path); /* path == NULL is ok */
9162                 if (!explanation)
9163                         _exit(1); /* PROG was not found */
9164                 if (opt_vV != 'V')
9165                         cmd = to_free; /* -v PROG prints "/path/to/PROG" */
9166         }
9167         printf((opt_vV == 'V') ? "%s is %s\n" : "%s\n", cmd, explanation);
9168         free(to_free);
9169         fflush_all();
9170         _exit(0);
9171 }
9172 #else
9173 # define if_command_vV_print_and_exit(a,b,c) ((void)0)
9174 #endif
9175 #endif /* !__U_BOOT__ */
9176
9177 #if BB_MMU
9178 #define pseudo_exec_argv(nommu_save, argv, assignment_cnt, argv_expanded) \
9179         pseudo_exec_argv(argv, assignment_cnt, argv_expanded)
9180 #define pseudo_exec(nommu_save, command, argv_expanded) \
9181         pseudo_exec(command, argv_expanded)
9182 #endif
9183
9184 #ifndef __U_BOOT__
9185 /* Called after [v]fork() in run_pipe, or from builtin_exec.
9186  * Never returns.
9187  * Don't exit() here.  If you don't exec, use _exit instead.
9188  * The at_exit handlers apparently confuse the calling process,
9189  * in particular stdin handling. Not sure why? -- because of vfork! (vda)
9190  */
9191 static void pseudo_exec_argv(nommu_save_t *nommu_save,
9192                 char **argv, int assignment_cnt,
9193                 char **argv_expanded) NORETURN;
9194 static NOINLINE void pseudo_exec_argv(nommu_save_t *nommu_save,
9195                 char **argv, int assignment_cnt,
9196                 char **argv_expanded)
9197 {
9198         const struct built_in_command *x;
9199         struct variable **sv_shadowed;
9200         char **new_env;
9201         IF_HUSH_COMMAND(char opt_vV = 0;)
9202         IF_HUSH_FUNCTIONS(const struct function *funcp;)
9203
9204         new_env = expand_assignments(argv, assignment_cnt);
9205         dump_cmd_in_x_mode(new_env);
9206
9207         if (!argv[assignment_cnt]) {
9208                 /* Case when we are here: ... | var=val | ...
9209                  * (note that we do not exit early, i.e., do not optimize out
9210                  * expand_assignments(): think about ... | var=`sleep 1` | ...
9211                  */
9212                 free_strings(new_env);
9213                 _exit_SUCCESS();
9214         }
9215
9216         sv_shadowed = G.shadowed_vars_pp;
9217 #if BB_MMU
9218         G.shadowed_vars_pp = NULL; /* "don't save, free them instead" */
9219 #else
9220         G.shadowed_vars_pp = &nommu_save->old_vars;
9221         G.var_nest_level++;
9222 #endif
9223         set_vars_and_save_old(new_env);
9224         G.shadowed_vars_pp = sv_shadowed;
9225
9226         if (argv_expanded) {
9227                 argv = argv_expanded;
9228         } else {
9229                 argv = expand_strvec_to_strvec(argv + assignment_cnt);
9230 #if !BB_MMU
9231                 nommu_save->argv = argv;
9232 #endif
9233         }
9234         dump_cmd_in_x_mode(argv);
9235
9236 #if ENABLE_FEATURE_SH_STANDALONE || BB_MMU
9237         if (strchr(argv[0], '/') != NULL)
9238                 goto skip;
9239 #endif
9240
9241 #if ENABLE_HUSH_FUNCTIONS
9242         /* Check if the command matches any functions (this goes before bltins) */
9243         funcp = find_function(argv[0]);
9244         if (funcp)
9245                 exec_function(&nommu_save->argv_from_re_execing, funcp, argv);
9246 #endif
9247
9248 #if ENABLE_HUSH_COMMAND
9249         /* "command BAR": run BAR without looking it up among functions
9250          * "command -v BAR": print "BAR" or "/path/to/BAR"; or exit 1
9251          * "command -V BAR": print "BAR is {a function,a shell builtin,/path/to/BAR}"
9252          */
9253         while (strcmp(argv[0], "command") == 0 && argv[1]) {
9254                 char *p;
9255
9256                 argv++;
9257                 p = *argv;
9258                 if (p[0] != '-' || !p[1])
9259                         continue; /* bash allows "command command command [-OPT] BAR" */
9260
9261                 for (;;) {
9262                         p++;
9263                         switch (*p) {
9264                         case '\0':
9265                                 argv++;
9266                                 p = *argv;
9267                                 if (p[0] != '-' || !p[1])
9268                                         goto after_opts;
9269                                 continue; /* next arg is also -opts, process it too */
9270                         case 'v':
9271                         case 'V':
9272                                 opt_vV = *p;
9273                                 continue;
9274                         default:
9275                                 bb_error_msg_and_die("%s: %s: invalid option", "command", argv[0]);
9276                         }
9277                 }
9278         }
9279  after_opts:
9280 # if ENABLE_HUSH_FUNCTIONS
9281         if (opt_vV && find_function(argv[0]))
9282                 if_command_vV_print_and_exit(opt_vV, argv[0], "a function");
9283 # endif
9284 #endif
9285
9286         /* Check if the command matches any of the builtins.
9287          * Depending on context, this might be redundant.  But it's
9288          * easier to waste a few CPU cycles than it is to figure out
9289          * if this is one of those cases.
9290          */
9291         /* Why "BB_MMU ? :" difference in logic? -
9292          * On NOMMU, it is more expensive to re-execute shell
9293          * just in order to run echo or test builtin.
9294          * It's better to skip it here and run corresponding
9295          * non-builtin later. */
9296         x = BB_MMU ? find_builtin(argv[0]) : find_builtin1(argv[0]);
9297         if (x) {
9298                 if_command_vV_print_and_exit(opt_vV, argv[0], "a shell builtin");
9299                 exec_builtin(&nommu_save->argv_from_re_execing, x, argv);
9300         }
9301
9302 #if ENABLE_FEATURE_SH_STANDALONE
9303         /* Check if the command matches any busybox applets */
9304         {
9305                 int a = find_applet_by_name(argv[0]);
9306                 if (a >= 0) {
9307                         if_command_vV_print_and_exit(opt_vV, argv[0], "an applet");
9308 # if BB_MMU /* see above why on NOMMU it is not allowed */
9309                         if (APPLET_IS_NOEXEC(a)) {
9310                                 /* Do not leak open fds from opened script files etc.
9311                                  * Testcase: interactive "ls -l /proc/self/fd"
9312                                  * should not show tty fd open.
9313                                  */
9314                                 close_saved_fds_and_FILE_fds();
9315 //FIXME: should also close saved redir fds
9316 //This casuses test failures in
9317 //redir_children_should_not_see_saved_fd_2.tests
9318 //redir_children_should_not_see_saved_fd_3.tests
9319 //if you replace "busybox find" with just "find" in them
9320                                 /* Without this, "rm -i FILE" can't be ^C'ed: */
9321                                 switch_off_special_sigs(G.special_sig_mask);
9322                                 debug_printf_exec("running applet '%s'\n", argv[0]);
9323                                 run_noexec_applet_and_exit(a, argv[0], argv);
9324                         }
9325 # endif
9326                         /* Re-exec ourselves */
9327                         debug_printf_exec("re-execing applet '%s'\n", argv[0]);
9328                         /* Don't propagate SIG_IGN to the child */
9329                         if (SPECIAL_JOBSTOP_SIGS != 0)
9330                                 switch_off_special_sigs(G.special_sig_mask & SPECIAL_JOBSTOP_SIGS);
9331                         execv(bb_busybox_exec_path, argv);
9332                         /* If they called chroot or otherwise made the binary no longer
9333                          * executable, fall through */
9334                 }
9335         }
9336 #endif
9337
9338 #if ENABLE_FEATURE_SH_STANDALONE || BB_MMU
9339  skip:
9340 #endif
9341         if_command_vV_print_and_exit(opt_vV, argv[0], NULL);
9342         execvp_or_die(argv);
9343 }
9344
9345 /* Called after [v]fork() in run_pipe
9346  */
9347 static void pseudo_exec(nommu_save_t *nommu_save,
9348                 struct command *command,
9349                 char **argv_expanded) NORETURN;
9350 static void pseudo_exec(nommu_save_t *nommu_save,
9351                 struct command *command,
9352                 char **argv_expanded)
9353 {
9354 #if ENABLE_HUSH_FUNCTIONS
9355         if (command->cmd_type == CMD_FUNCDEF) {
9356                 /* Ignore funcdefs in pipes:
9357                  * true | f() { cmd }
9358                  */
9359                 _exit(0);
9360         }
9361 #endif
9362
9363         if (command->argv) {
9364                 pseudo_exec_argv(nommu_save, command->argv,
9365                                 command->assignment_cnt, argv_expanded);
9366         }
9367
9368         if (command->group) {
9369                 /* Cases when we are here:
9370                  * ( list )
9371                  * { list } &
9372                  * ... | ( list ) | ...
9373                  * ... | { list } | ...
9374                  */
9375 #if BB_MMU
9376                 int rcode;
9377                 debug_printf_exec("pseudo_exec: run_list\n");
9378                 reset_traps_to_defaults();
9379                 rcode = run_list(command->group);
9380                 /* OK to leak memory by not calling free_pipe_list,
9381                  * since this process is about to exit */
9382                 _exit(rcode);
9383 #else
9384                 re_execute_shell(&nommu_save->argv_from_re_execing,
9385                                 command->group_as_string,
9386                                 G.global_argv[0],
9387                                 G.global_argv + 1,
9388                                 NULL);
9389 #endif
9390         }
9391
9392         /* Case when we are here: ... | >file */
9393         debug_printf_exec("pseudo_exec'ed null command\n");
9394         _exit_SUCCESS();
9395 }
9396
9397 #if ENABLE_HUSH_JOB
9398 static const char *get_cmdtext(struct pipe *pi)
9399 {
9400         char **argv;
9401         char *p;
9402         int len;
9403
9404         /* This is subtle. ->cmdtext is created only on first backgrounding.
9405          * (Think "cat, <ctrl-z>, fg, <ctrl-z>, fg, <ctrl-z>...." here...)
9406          * On subsequent bg argv is trashed, but we won't use it */
9407         if (pi->cmdtext)
9408                 return pi->cmdtext;
9409
9410         argv = pi->cmds[0].argv;
9411         if (!argv) {
9412                 pi->cmdtext = xzalloc(1);
9413                 return pi->cmdtext;
9414         }
9415         len = 0;
9416         do {
9417                 len += strlen(*argv) + 1;
9418         } while (*++argv);
9419         p = xmalloc(len);
9420         pi->cmdtext = p;
9421         argv = pi->cmds[0].argv;
9422         do {
9423                 p = stpcpy(p, *argv);
9424                 *p++ = ' ';
9425         } while (*++argv);
9426         p[-1] = '\0';
9427         return pi->cmdtext;
9428 }
9429
9430 static void remove_job_from_table(struct pipe *pi)
9431 {
9432         struct pipe *prev_pipe;
9433
9434         if (pi == G.job_list) {
9435                 G.job_list = pi->next;
9436         } else {
9437                 prev_pipe = G.job_list;
9438                 while (prev_pipe->next != pi)
9439                         prev_pipe = prev_pipe->next;
9440                 prev_pipe->next = pi->next;
9441         }
9442         G.last_jobid = 0;
9443         if (G.job_list)
9444                 G.last_jobid = G.job_list->jobid;
9445 }
9446
9447 static void delete_finished_job(struct pipe *pi)
9448 {
9449         remove_job_from_table(pi);
9450         free_pipe(pi);
9451 }
9452
9453 static void clean_up_last_dead_job(void)
9454 {
9455         if (G.job_list && !G.job_list->alive_cmds)
9456                 delete_finished_job(G.job_list);
9457 }
9458
9459 static void insert_job_into_table(struct pipe *pi)
9460 {
9461         struct pipe *job, **jobp;
9462         int i;
9463
9464         clean_up_last_dead_job();
9465
9466         /* Find the end of the list, and find next job ID to use */
9467         i = 0;
9468         jobp = &G.job_list;
9469         while ((job = *jobp) != NULL) {
9470                 if (job->jobid > i)
9471                         i = job->jobid;
9472                 jobp = &job->next;
9473         }
9474         pi->jobid = i + 1;
9475
9476         /* Create a new job struct at the end */
9477         job = *jobp = xmemdup(pi, sizeof(*pi));
9478         job->next = NULL;
9479         job->cmds = xzalloc(sizeof(pi->cmds[0]) * pi->num_cmds);
9480         /* Cannot copy entire pi->cmds[] vector! This causes double frees */
9481         for (i = 0; i < pi->num_cmds; i++) {
9482                 job->cmds[i].pid = pi->cmds[i].pid;
9483                 /* all other fields are not used and stay zero */
9484         }
9485         job->cmdtext = xstrdup(get_cmdtext(pi));
9486
9487         if (G_interactive_fd)
9488                 printf("[%u] %u %s\n", job->jobid, (unsigned)job->cmds[0].pid, job->cmdtext);
9489         G.last_jobid = job->jobid;
9490 }
9491 #endif /* JOB */
9492
9493 static int job_exited_or_stopped(struct pipe *pi)
9494 {
9495         int rcode, i;
9496
9497         if (pi->alive_cmds != pi->stopped_cmds)
9498                 return -1;
9499
9500         /* All processes in fg pipe have exited or stopped */
9501         rcode = 0;
9502         i = pi->num_cmds;
9503         while (--i >= 0) {
9504                 rcode = pi->cmds[i].cmd_exitcode;
9505                 /* usually last process gives overall exitstatus,
9506                  * but with "set -o pipefail", last *failed* process does */
9507                 if (G.o_opt[OPT_O_PIPEFAIL] == 0 || rcode != 0)
9508                         break;
9509         }
9510         IF_HAS_KEYWORDS(if (pi->pi_inverted) rcode = !rcode;)
9511         return rcode;
9512 }
9513
9514 static int process_wait_result(struct pipe *fg_pipe, pid_t childpid, int status)
9515 {
9516 #if ENABLE_HUSH_JOB
9517         struct pipe *pi;
9518 #endif
9519         int i, dead;
9520
9521         dead = WIFEXITED(status) || WIFSIGNALED(status);
9522
9523 #if DEBUG_JOBS
9524         if (WIFSTOPPED(status))
9525                 debug_printf_jobs("pid %d stopped by sig %d (exitcode %d)\n",
9526                                 childpid, WSTOPSIG(status), WEXITSTATUS(status));
9527         if (WIFSIGNALED(status))
9528                 debug_printf_jobs("pid %d killed by sig %d (exitcode %d)\n",
9529                                 childpid, WTERMSIG(status), WEXITSTATUS(status));
9530         if (WIFEXITED(status))
9531                 debug_printf_jobs("pid %d exited, exitcode %d\n",
9532                                 childpid, WEXITSTATUS(status));
9533 #endif
9534         /* Were we asked to wait for a fg pipe? */
9535         if (fg_pipe) {
9536                 i = fg_pipe->num_cmds;
9537
9538                 while (--i >= 0) {
9539                         int rcode;
9540
9541                         debug_printf_jobs("check pid %d\n", fg_pipe->cmds[i].pid);
9542                         if (fg_pipe->cmds[i].pid != childpid)
9543                                 continue;
9544                         if (dead) {
9545                                 int ex;
9546                                 fg_pipe->cmds[i].pid = 0;
9547                                 fg_pipe->alive_cmds--;
9548                                 ex = WEXITSTATUS(status);
9549                                 /* bash prints killer signal's name for *last*
9550                                  * process in pipe (prints just newline for SIGINT/SIGPIPE).
9551                                  * Mimic this. Example: "sleep 5" + (^\ or kill -QUIT)
9552                                  */
9553                                 if (WIFSIGNALED(status)) {
9554                                         int sig = WTERMSIG(status);
9555 #if ENABLE_HUSH_JOB
9556                                         if (G.run_list_level == 1
9557                                         /* ^^^^^ Do not print in nested contexts, example:
9558                                          * echo `sleep 1; sh -c 'kill -9 $$'` - prints "137", NOT "Killed 137"
9559                                          */
9560                                          && i == fg_pipe->num_cmds-1
9561                                         ) {
9562                                                 /* strsignal() is for bash compat. ~600 bloat versus bbox's get_signame() */
9563                                                 puts(sig == SIGINT || sig == SIGPIPE ? "" : strsignal(sig));
9564                                         }
9565 #endif
9566                                         /* TODO: if (WCOREDUMP(status)) + " (core dumped)"; */
9567                                         /* MIPS has 128 sigs (1..128), if sig==128,
9568                                          * 128 + sig would result in exitcode 256 -> 0!
9569                                          */
9570                                         ex = 128 | sig;
9571                                 }
9572                                 fg_pipe->cmds[i].cmd_exitcode = ex;
9573                         } else {
9574                                 fg_pipe->stopped_cmds++;
9575                         }
9576                         debug_printf_jobs("fg_pipe: alive_cmds %d stopped_cmds %d\n",
9577                                         fg_pipe->alive_cmds, fg_pipe->stopped_cmds);
9578                         rcode = job_exited_or_stopped(fg_pipe);
9579                         if (rcode >= 0) {
9580 /* Note: *non-interactive* bash does not continue if all processes in fg pipe
9581  * are stopped. Testcase: "cat | cat" in a script (not on command line!)
9582  * and "killall -STOP cat" */
9583                                 if (G_interactive_fd) {
9584 #if ENABLE_HUSH_JOB
9585                                         if (fg_pipe->alive_cmds != 0)
9586                                                 insert_job_into_table(fg_pipe);
9587 #endif
9588                                         return rcode;
9589                                 }
9590                                 if (fg_pipe->alive_cmds == 0)
9591                                         return rcode;
9592                         }
9593                         /* There are still running processes in the fg_pipe */
9594                         return -1;
9595                 }
9596                 /* It wasn't in fg_pipe, look for process in bg pipes */
9597         }
9598
9599 #if ENABLE_HUSH_JOB
9600         /* We were asked to wait for bg or orphaned children */
9601         /* No need to remember exitcode in this case */
9602         for (pi = G.job_list; pi; pi = pi->next) {
9603                 for (i = 0; i < pi->num_cmds; i++) {
9604                         if (pi->cmds[i].pid == childpid)
9605                                 goto found_pi_and_prognum;
9606                 }
9607         }
9608         /* Happens when shell is used as init process (init=/bin/sh) */
9609         debug_printf("checkjobs: pid %d was not in our list!\n", childpid);
9610         return -1; /* this wasn't a process from fg_pipe */
9611
9612  found_pi_and_prognum:
9613         if (dead) {
9614                 /* child exited */
9615                 int rcode = WEXITSTATUS(status);
9616                 if (WIFSIGNALED(status))
9617                         /* NB: not 128 + sig, MIPS has sig 128 */
9618                         rcode = 128 | WTERMSIG(status);
9619                 pi->cmds[i].cmd_exitcode = rcode;
9620                 if (G.last_bg_pid == pi->cmds[i].pid)
9621                         G.last_bg_pid_exitcode = rcode;
9622                 pi->cmds[i].pid = 0;
9623                 pi->alive_cmds--;
9624                 if (!pi->alive_cmds) {
9625 # if ENABLE_HUSH_BASH_COMPAT
9626                         G.dead_job_exitcode = job_exited_or_stopped(pi);
9627 # endif
9628                         if (G_interactive_fd) {
9629                                 printf(JOB_STATUS_FORMAT, pi->jobid,
9630                                                 "Done", pi->cmdtext);
9631                                 delete_finished_job(pi);
9632                         } else {
9633 /*
9634  * bash deletes finished jobs from job table only in interactive mode,
9635  * after "jobs" cmd, or if pid of a new process matches one of the old ones
9636  * (see cleanup_dead_jobs(), delete_old_job(), J_NOTIFIED in bash source).
9637  * Testcase script: "(exit 3) & sleep 1; wait %1; echo $?" prints 3 in bash.
9638  * We only retain one "dead" job, if it's the single job on the list.
9639  * This covers most of real-world scenarios where this is useful.
9640  */
9641                                 if (pi != G.job_list)
9642                                         delete_finished_job(pi);
9643                         }
9644                 }
9645         } else {
9646                 /* child stopped */
9647                 pi->stopped_cmds++;
9648         }
9649 #endif
9650         return -1; /* this wasn't a process from fg_pipe */
9651 }
9652
9653 /* Check to see if any processes have exited -- if they have,
9654  * figure out why and see if a job has completed.
9655  *
9656  * If non-NULL fg_pipe: wait for its completion or stop.
9657  * Return its exitcode or zero if stopped.
9658  *
9659  * Alternatively (fg_pipe == NULL, waitfor_pid != 0):
9660  * waitpid(WNOHANG), if waitfor_pid exits or stops, return exitcode+1,
9661  * else return <0 if waitpid errors out (e.g. ECHILD: nothing to wait for)
9662  * or 0 if no children changed status.
9663  *
9664  * Alternatively (fg_pipe == NULL, waitfor_pid == 0),
9665  * return <0 if waitpid errors out (e.g. ECHILD: nothing to wait for)
9666  * or 0 if no children changed status.
9667  */
9668 static int checkjobs(struct pipe *fg_pipe, pid_t waitfor_pid)
9669 {
9670         int attributes;
9671         int status;
9672         int rcode = 0;
9673
9674         debug_printf_jobs("checkjobs %p\n", fg_pipe);
9675
9676         attributes = WUNTRACED;
9677         if (fg_pipe == NULL)
9678                 attributes |= WNOHANG;
9679
9680         errno = 0;
9681 #if ENABLE_HUSH_FAST
9682         if (G.handled_SIGCHLD == G.count_SIGCHLD) {
9683 //bb_error_msg("[%d] checkjobs: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d children?:%d fg_pipe:%p",
9684 //getpid(), G.count_SIGCHLD, G.handled_SIGCHLD, G.we_have_children, fg_pipe);
9685                 /* There was neither fork nor SIGCHLD since last waitpid */
9686                 /* Avoid doing waitpid syscall if possible */
9687                 if (!G.we_have_children) {
9688                         errno = ECHILD;
9689                         return -1;
9690                 }
9691                 if (fg_pipe == NULL) { /* is WNOHANG set? */
9692                         /* We have children, but they did not exit
9693                          * or stop yet (we saw no SIGCHLD) */
9694                         return 0;
9695                 }
9696                 /* else: !WNOHANG, waitpid will block, can't short-circuit */
9697         }
9698 #endif
9699
9700 /* Do we do this right?
9701  * bash-3.00# sleep 20 | false
9702  * <ctrl-Z pressed>
9703  * [3]+  Stopped          sleep 20 | false
9704  * bash-3.00# echo $?
9705  * 1   <========== bg pipe is not fully done, but exitcode is already known!
9706  * [hush 1.14.0: yes we do it right]
9707  */
9708         while (1) {
9709                 pid_t childpid;
9710 #if ENABLE_HUSH_FAST
9711                 int i;
9712                 i = G.count_SIGCHLD;
9713 #endif
9714                 childpid = waitpid(-1, &status, attributes);
9715                 if (childpid <= 0) {
9716                         if (childpid && errno != ECHILD)
9717                                 bb_simple_perror_msg("waitpid");
9718 #if ENABLE_HUSH_FAST
9719                         else { /* Until next SIGCHLD, waitpid's are useless */
9720                                 G.we_have_children = (childpid == 0);
9721                                 G.handled_SIGCHLD = i;
9722 //bb_error_msg("[%d] checkjobs: waitpid returned <= 0, G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
9723                         }
9724 #endif
9725                         /* ECHILD (no children), or 0 (no change in children status) */
9726                         rcode = childpid;
9727                         break;
9728                 }
9729                 rcode = process_wait_result(fg_pipe, childpid, status);
9730                 if (rcode >= 0) {
9731                         /* fg_pipe exited or stopped */
9732                         break;
9733                 }
9734                 if (childpid == waitfor_pid) { /* "wait PID" */
9735                         debug_printf_exec("childpid==waitfor_pid:%d status:0x%08x\n", childpid, status);
9736                         rcode = WEXITSTATUS(status);
9737                         if (WIFSIGNALED(status))
9738                                 rcode = 128 | WTERMSIG(status);
9739                         if (WIFSTOPPED(status))
9740                                 /* bash: "cmd & wait $!" and cmd stops: $? = 128 | stopsig */
9741                                 rcode = 128 | WSTOPSIG(status);
9742                         rcode++;
9743                         break; /* "wait PID" called us, give it exitcode+1 */
9744                 }
9745 #if ENABLE_HUSH_BASH_COMPAT
9746                 if (-1 == waitfor_pid /* "wait -n" (wait for any one job) */
9747                  && G.dead_job_exitcode >= 0 /* some job did finish */
9748                 ) {
9749                         debug_printf_exec("waitfor_pid:-1\n");
9750                         rcode = G.dead_job_exitcode + 1;
9751                         break;
9752                 }
9753 #endif
9754                 /* This wasn't one of our processes, or */
9755                 /* fg_pipe still has running processes, do waitpid again */
9756         } /* while (waitpid succeeds)... */
9757
9758         return rcode;
9759 }
9760
9761 #if ENABLE_HUSH_JOB
9762 static int checkjobs_and_fg_shell(struct pipe *fg_pipe)
9763 {
9764         pid_t p;
9765         int rcode = checkjobs(fg_pipe, 0 /*(no pid to wait for)*/);
9766         if (G_saved_tty_pgrp) {
9767                 /* Job finished, move the shell to the foreground */
9768                 p = getpgrp(); /* our process group id */
9769                 debug_printf_jobs("fg'ing ourself: getpgrp()=%d\n", (int)p);
9770                 tcsetpgrp(G_interactive_fd, p);
9771         }
9772         return rcode;
9773 }
9774 #endif
9775 #endif /* !__U_BOOT__ */
9776
9777 /* Start all the jobs, but don't wait for anything to finish.
9778  * See checkjobs().
9779  *
9780  * Return code is normally -1, when the caller has to wait for children
9781  * to finish to determine the exit status of the pipe.  If the pipe
9782  * is a simple builtin command, however, the action is done by the
9783  * time run_pipe returns, and the exit code is provided as the
9784  * return value.
9785  *
9786  * Returns -1 only if started some children. IOW: we have to
9787  * mask out retvals of builtins etc with 0xff!
9788  *
9789  * The only case when we do not need to [v]fork is when the pipe
9790  * is single, non-backgrounded, non-subshell command. Examples:
9791  * cmd ; ...   { list } ; ...
9792  * cmd && ...  { list } && ...
9793  * cmd || ...  { list } || ...
9794  * If it is, then we can run cmd as a builtin, NOFORK,
9795  * or (if SH_STANDALONE) an applet, and we can run the { list }
9796  * with run_list. If it isn't one of these, we fork and exec cmd.
9797  *
9798  * Cases when we must fork:
9799  * non-single:   cmd | cmd
9800  * backgrounded: cmd &     { list } &
9801  * subshell:     ( list ) [&]
9802  */
9803 static void set_G_ifs(void)
9804 {
9805         /* Testcase: set -- q w e; (IFS='' echo "$*"; IFS=''; echo "$*"); echo "$*"
9806          * Result should be 3 lines: q w e, qwe, q w e
9807          */
9808         if (G.ifs_whitespace != G.ifs)
9809                 free(G.ifs_whitespace);
9810         G.ifs = get_local_var_value("IFS");
9811         if (G.ifs) {
9812                 char *p;
9813                 G.ifs_whitespace = (char*)G.ifs;
9814                 p = skip_whitespace(G.ifs);
9815                 if (*p) {
9816                         /* Not all $IFS is whitespace */
9817                         char *d;
9818                         int len = p - G.ifs;
9819                         p = skip_non_whitespace(p);
9820                         G.ifs_whitespace = xmalloc(len + strlen(p) + 1); /* can overestimate */
9821                         d = mempcpy(G.ifs_whitespace, G.ifs, len);
9822                         while (*p) {
9823                                 if (isspace(*p))
9824                                         *d++ = *p;
9825                                 p++;
9826                         }
9827                         *d = '\0';
9828                 }
9829         } else {
9830                 G.ifs = defifs;
9831                 G.ifs_whitespace = (char*)G.ifs;
9832         }
9833 }
9834 #ifndef __U_BOOT__
9835 #if !ENABLE_HUSH_MODE_X
9836 #define redirect_and_varexp_helper(command, sqp, argv_expanded) \
9837         redirect_and_varexp_helper(command, sqp)
9838 #endif
9839 static int redirect_and_varexp_helper(
9840                 struct command *command,
9841                 struct squirrel **sqp,
9842                 char **argv_expanded)
9843 {
9844         /* Assignments occur before redirects. Try:
9845          * a=`sleep 1` sleep 2 3>/qwe/rty
9846          */
9847
9848         char **new_env = expand_assignments(command->argv, command->assignment_cnt);
9849         dump_cmd_in_x_mode(new_env);
9850         dump_cmd_in_x_mode(argv_expanded);
9851         /* this takes ownership of new_env[i] elements, and frees new_env: */
9852         set_vars_and_save_old(new_env);
9853
9854         return setup_redirects(command, sqp);
9855 }
9856 #endif /* !__U_BOOT__ */
9857
9858 static NOINLINE int run_pipe(struct pipe *pi)
9859 {
9860         static const char *const null_ptr = NULL;
9861
9862         int cmd_no;
9863 #ifndef __U_BOOT__
9864         int next_infd;
9865 #endif /* !__U_BOOT__ */
9866         struct command *command;
9867         char **argv_expanded;
9868         char **argv;
9869 #ifndef __U_BOOT__
9870         struct squirrel *squirrel = NULL;
9871 #endif /* !__U_BOOT__ */
9872         int rcode;
9873
9874 #ifdef __U_BOOT__
9875         /*
9876          * Set rcode here to avoid returning a garbage value in the middle of
9877          * the function.
9878          * Also, if an error occurs, rcode value would be changed and last
9879          * return will signal the error.
9880          */
9881         rcode = 0;
9882 #endif /* __U_BOOT__ */
9883
9884         debug_printf_exec("run_pipe start: members:%d\n", pi->num_cmds);
9885         debug_enter();
9886
9887         set_G_ifs();
9888
9889 #ifndef __U_BOOT__
9890         IF_HUSH_JOB(pi->pgrp = -1;)
9891         pi->stopped_cmds = 0;
9892 #endif /* !__U_BOOT__ */
9893         command = &pi->cmds[0];
9894         argv_expanded = NULL;
9895
9896 #ifndef __U_BOOT__
9897         if (pi->num_cmds != 1
9898          || pi->followup == PIPE_BG
9899          || command->cmd_type == CMD_SUBSHELL
9900         ) {
9901                 goto must_fork;
9902         }
9903
9904         pi->alive_cmds = 1;
9905 #endif /* !__U_BOOT__ */
9906
9907         debug_printf_exec(": group:%p argv:'%s'\n",
9908                 command->group, command->argv ? command->argv[0] : "NONE");
9909
9910         if (command->group) {
9911 #if ENABLE_HUSH_FUNCTIONS
9912                 if (command->cmd_type == CMD_FUNCDEF) {
9913                         /* "executing" func () { list } */
9914                         struct function *funcp;
9915
9916                         funcp = new_function(command->argv[0]);
9917                         /* funcp->name is already set to argv[0] */
9918                         funcp->body = command->group;
9919 # if !BB_MMU
9920                         funcp->body_as_string = command->group_as_string;
9921                         command->group_as_string = NULL;
9922 # endif
9923                         command->group = NULL;
9924                         command->argv[0] = NULL;
9925                         debug_printf_exec("cmd %p has child func at %p\n", command, funcp);
9926                         funcp->parent_cmd = command;
9927                         command->child_func = funcp;
9928
9929                         debug_printf_exec("run_pipe: return EXIT_SUCCESS\n");
9930                         debug_leave();
9931                         return EXIT_SUCCESS;
9932                 }
9933 #endif
9934                 /* { list } */
9935                 debug_printf_exec("non-subshell group\n");
9936                 rcode = 1; /* exitcode if redir failed */
9937 #ifndef __U_BOOT__
9938                 if (setup_redirects(command, &squirrel) == 0) {
9939 #endif /* !__U_BOOT__ */
9940                         debug_printf_exec(": run_list\n");
9941 //FIXME: we need to pass squirrel down into run_list()
9942 //for SH_STANDALONE case, or else this construct:
9943 // { find /proc/self/fd; true; } >FILE; cmd2
9944 //has no way of closing saved fd#1 for "find",
9945 //and in SH_STANDALONE mode, "find" is not execed,
9946 //therefore CLOEXEC on saved fd does not help.
9947                         rcode = run_list(command->group) & 0xff;
9948 #ifndef __U_BOOT__
9949                 }
9950                 restore_redirects(squirrel);
9951 #endif /* !__U_BOOT__ */
9952                 IF_HAS_KEYWORDS(if (pi->pi_inverted) rcode = !rcode;)
9953                 debug_leave();
9954                 debug_printf_exec("run_pipe: return %d\n", rcode);
9955                 return rcode;
9956         }
9957
9958         argv = command->argv ? command->argv : (char **) &null_ptr;
9959         {
9960 #ifndef __U_BOOT__
9961                 const struct built_in_command *x;
9962                 IF_HUSH_FUNCTIONS(const struct function *funcp;)
9963                 IF_NOT_HUSH_FUNCTIONS(enum { funcp = 0 };)
9964                 struct variable **sv_shadowed;
9965 #endif /* !__U_BOOT__ */
9966                 struct variable *old_vars;
9967
9968 #if ENABLE_HUSH_LINENO_VAR
9969                 G.execute_lineno = command->lineno;
9970 #endif
9971
9972                 if (argv[command->assignment_cnt] == NULL) {
9973                         /* Assignments, but no command.
9974                          * Ensure redirects take effect (that is, create files).
9975                          * Try "a=t >file"
9976                          */
9977                         unsigned i;
9978                         G.expand_exitcode = 0;
9979  only_assignments:
9980 #ifndef __U_BOOT__
9981                         rcode = setup_redirects(command, &squirrel);
9982                         restore_redirects(squirrel);
9983 #endif /* !__U_BOOT__ */
9984
9985                         /* Set shell variables */
9986                         i = 0;
9987                         while (i < command->assignment_cnt) {
9988                                 char *p = expand_string_to_string(argv[i],
9989                                                 EXP_FLAG_ESC_GLOB_CHARS,
9990                                                 /*unbackslash:*/ 1
9991                                 );
9992 #if ENABLE_HUSH_MODE_X
9993                                 if (G_x_mode) {
9994                                         char *eq;
9995                                         if (i == 0)
9996                                                 x_mode_prefix();
9997                                         x_mode_addchr(' ');
9998                                         eq = strchrnul(p, '=');
9999                                         if (*eq) eq++;
10000                                         x_mode_addblock(p, (eq - p));
10001                                         x_mode_print_optionally_squoted(eq);
10002                                         x_mode_flush();
10003                                 }
10004 #endif
10005                                 debug_printf_env("set shell var:'%s'->'%s'\n", *argv, p);
10006 #ifndef __U_BOOT__
10007                                 if (set_local_var0(p)) {
10008 #else /* __U_BOOT__ */
10009                                 if (set_local_var_modern(p, /*flag:*/ 0)) {
10010 #endif
10011                                         /* assignment to readonly var / putenv error? */
10012                                         rcode = 1;
10013                                 }
10014                                 i++;
10015                         }
10016                         /* Redirect error sets $? to 1. Otherwise,
10017                          * if evaluating assignment value set $?, retain it.
10018                          * Else, clear $?:
10019                          *  false; q=`exit 2`; echo $? - should print 2
10020                          *  false; x=1; echo $? - should print 0
10021                          * Because of the 2nd case, we can't just use G.last_exitcode.
10022                          */
10023                         if (rcode == 0)
10024                                 rcode = G.expand_exitcode;
10025                         IF_HAS_KEYWORDS(if (pi->pi_inverted) rcode = !rcode;)
10026                         debug_leave();
10027                         debug_printf_exec("run_pipe: return %d\n", rcode);
10028                         return rcode;
10029                 }
10030
10031                 /* Expand the rest into (possibly) many strings each */
10032 #if defined(CMD_TEST2_SINGLEWORD_NOGLOB)
10033                 if (command->cmd_type == CMD_TEST2_SINGLEWORD_NOGLOB)
10034                         argv_expanded = expand_strvec_to_strvec_singleword_noglob(argv + command->assignment_cnt);
10035                 else
10036 #endif
10037 #if defined(CMD_SINGLEWORD_NOGLOB)
10038                 if (command->cmd_type == CMD_SINGLEWORD_NOGLOB)
10039                         argv_expanded = expand_strvec_to_strvec_singleword_noglob(argv + command->assignment_cnt);
10040                 else
10041 #endif
10042                         argv_expanded = expand_strvec_to_strvec(argv + command->assignment_cnt);
10043
10044                 /* If someone gives us an empty string: `cmd with empty output` */
10045                 if (!argv_expanded[0]) {
10046                         free(argv_expanded);
10047                         /* `false` still has to set exitcode 1 */
10048                         G.expand_exitcode = G.last_exitcode;
10049                         goto only_assignments;
10050                 }
10051
10052                 old_vars = NULL;
10053 #ifndef __U_BOOT__
10054                 sv_shadowed = G.shadowed_vars_pp;
10055
10056                 /* Check if argv[0] matches any functions (this goes before bltins) */
10057                 IF_HUSH_FUNCTIONS(funcp = find_function(argv_expanded[0]);)
10058                 IF_HUSH_FUNCTIONS(x = NULL;)
10059                 IF_HUSH_FUNCTIONS(if (!funcp))
10060                         x = find_builtin(argv_expanded[0]);
10061                 if (x || funcp) {
10062                         if (x && x->b_function == builtin_exec && argv_expanded[1] == NULL) {
10063                                 debug_printf("exec with redirects only\n");
10064                                 /*
10065                                  * Variable assignments are executed, but then "forgotten":
10066                                  *  a=`sleep 1;echo A` exec 3>&-; echo $a
10067                                  * sleeps, but prints nothing.
10068                                  */
10069                                 enter_var_nest_level();
10070                                 G.shadowed_vars_pp = &old_vars;
10071                                 rcode = redirect_and_varexp_helper(command,
10072                                         /*squirrel:*/ ERR_PTR,
10073                                         argv_expanded
10074                                 );
10075                                 G.shadowed_vars_pp = sv_shadowed;
10076                                 /* rcode=1 can be if redir file can't be opened */
10077
10078                                 goto clean_up_and_ret1;
10079                         }
10080
10081                         /* Bump var nesting, or this will leak exported $a:
10082                          * a=b true; env | grep ^a=
10083                          */
10084                         enter_var_nest_level();
10085                         /* Collect all variables "shadowed" by helper
10086                          * (IOW: old vars overridden by "var1=val1 var2=val2 cmd..." syntax)
10087                          * into old_vars list:
10088                          */
10089                         G.shadowed_vars_pp = &old_vars;
10090                         rcode = redirect_and_varexp_helper(command, &squirrel, argv_expanded);
10091                         if (rcode == 0) {
10092                                 if (!funcp) {
10093                                         /* Do not collect *to old_vars list* vars shadowed
10094                                          * by e.g. "local VAR" builtin (collect them
10095                                          * in the previously nested list instead):
10096                                          * don't want them to be restored immediately
10097                                          * after "local" completes.
10098                                          */
10099                                         G.shadowed_vars_pp = sv_shadowed;
10100
10101                                         debug_printf_exec(": builtin '%s' '%s'...\n",
10102                                                 x->b_cmd, argv_expanded[1]);
10103                                         fflush_all();
10104                                         rcode = x->b_function(argv_expanded) & 0xff;
10105                                         fflush_all();
10106                                 }
10107 #if ENABLE_HUSH_FUNCTIONS
10108                                 else {
10109                                         debug_printf_exec(": function '%s' '%s'...\n",
10110                                                 funcp->name, argv_expanded[1]);
10111                                         rcode = run_function(funcp, argv_expanded) & 0xff;
10112                                         /*
10113                                          * But do collect *to old_vars list* vars shadowed
10114                                          * within function execution. To that end, restore
10115                                          * this pointer _after_ function run:
10116                                          */
10117                                         G.shadowed_vars_pp = sv_shadowed;
10118                                 }
10119 #endif
10120                         }
10121                 } else
10122                 if (ENABLE_FEATURE_SH_NOFORK && NUM_APPLETS > 1) {
10123                         int n = find_applet_by_name(argv_expanded[0]);
10124                         if (n < 0 || !APPLET_IS_NOFORK(n))
10125                                 goto must_fork;
10126
10127                         enter_var_nest_level();
10128                         /* Collect all variables "shadowed" by helper into old_vars list */
10129                         G.shadowed_vars_pp = &old_vars;
10130                         rcode = redirect_and_varexp_helper(command, &squirrel, argv_expanded);
10131                         G.shadowed_vars_pp = sv_shadowed;
10132
10133                         if (rcode == 0) {
10134                                 debug_printf_exec(": run_nofork_applet '%s' '%s'...\n",
10135                                         argv_expanded[0], argv_expanded[1]);
10136                                 /*
10137                                  * Note: signals (^C) can't interrupt here.
10138                                  * We remember them and they will be acted upon
10139                                  * after applet returns.
10140                                  * This makes applets which can run for a long time
10141                                  * and/or wait for user input ineligible for NOFORK:
10142                                  * for example, "yes" or "rm" (rm -i waits for input).
10143                                  */
10144                                 rcode = run_nofork_applet(n, argv_expanded);
10145                         }
10146                 } else
10147                         goto must_fork;
10148
10149                 restore_redirects(squirrel);
10150  clean_up_and_ret1:
10151                 leave_var_nest_level();
10152                 add_vars(old_vars);
10153
10154                 /*
10155                  * Try "usleep 99999999" + ^C + "echo $?"
10156                  * with FEATURE_SH_NOFORK=y.
10157                  */
10158                 if (!funcp) {
10159                         /* It was builtin or nofork.
10160                          * if this would be a real fork/execed program,
10161                          * it should have died if a fatal sig was received.
10162                          * But OTOH, there was no separate process,
10163                          * the sig was sent to _shell_, not to non-existing
10164                          * child.
10165                          * Let's just handle ^C only, this one is obvious:
10166                          * we aren't ok with exitcode 0 when ^C was pressed
10167                          * during builtin/nofork.
10168                          */
10169                         if (sigismember(&G.pending_set, SIGINT))
10170                                 rcode = 128 | SIGINT;
10171                 }
10172                 free(argv_expanded);
10173                 IF_HAS_KEYWORDS(if (pi->pi_inverted) rcode = !rcode;)
10174                 debug_leave();
10175                 debug_printf_exec("run_pipe return %d\n", rcode);
10176                 return rcode;
10177 #endif /* !__U_BOOT__ */
10178         }
10179
10180 #ifndef __U_BOOT__
10181  must_fork:
10182         /* NB: argv_expanded may already be created, and that
10183          * might include `cmd` runs! Do not rerun it! We *must*
10184          * use argv_expanded if it's non-NULL */
10185
10186         /* Going to fork a child per each pipe member */
10187         pi->alive_cmds = 0;
10188         next_infd = 0;
10189 #endif /* !__U_BOOT__ */
10190
10191         cmd_no = 0;
10192         while (cmd_no < pi->num_cmds) {
10193 #ifndef __U_BOOT__
10194                 struct fd_pair pipefds;
10195 #if !BB_MMU
10196                 int sv_var_nest_level = G.var_nest_level;
10197                 volatile nommu_save_t nommu_save;
10198                 nommu_save.old_vars = NULL;
10199                 nommu_save.argv = NULL;
10200                 nommu_save.argv_from_re_execing = NULL;
10201 #endif
10202 #endif /* !__U_BOOT__ */
10203                 command = &pi->cmds[cmd_no];
10204                 cmd_no++;
10205
10206 #ifdef __U_BOOT__
10207                 /* Replace argv and argc by expanded if it exists. */
10208                 if (argv_expanded) {
10209                         /*
10210                          * We need to save a pointer to argv, we will restore it
10211                          * later, so it will be freed when pipe is freed.
10212                          */
10213                         argv = command->argv;
10214
10215                         /*
10216                          * After expansion, there can be more or less argument, so we need to
10217                          * update argc, for example:
10218                          * - More arguments:
10219                          *   foo='bar quuz'
10220                          *   echo $foo
10221                          * - Less arguments:
10222                          *   echo $foo (if foo was never set)
10223                          */
10224                         command->argc = list_size(argv_expanded);
10225                         command->argv = argv_expanded;
10226                 }
10227 #endif /* __U_BOOT__ */
10228                         if (command->argv) {
10229                         debug_printf_exec(": pipe member '%s' '%s'...\n",
10230                                         command->argv[0], command->argv[1]);
10231                 } else {
10232                         debug_printf_exec(": pipe member with no argv\n");
10233                 }
10234
10235 #ifndef __U_BOOT__
10236                 /* pipes are inserted between pairs of commands */
10237                 pipefds.rd = 0;
10238                 pipefds.wr = 1;
10239                 if (cmd_no < pi->num_cmds)
10240                         xpiped_pair(pipefds);
10241
10242 #if ENABLE_HUSH_LINENO_VAR
10243                 G.execute_lineno = command->lineno;
10244 #endif
10245
10246                 command->pid = BB_MMU ? fork() : vfork();
10247                 if (!command->pid) { /* child */
10248 #if ENABLE_HUSH_JOB
10249                         disable_restore_tty_pgrp_on_exit();
10250                         CLEAR_RANDOM_T(&G.random_gen); /* or else $RANDOM repeats in child */
10251
10252                         /* Every child adds itself to new process group
10253                          * with pgid == pid_of_first_child_in_pipe */
10254                         if (G.run_list_level == 1 && G_interactive_fd) {
10255                                 pid_t pgrp;
10256                                 pgrp = pi->pgrp;
10257                                 if (pgrp < 0) /* true for 1st process only */
10258                                         pgrp = getpid();
10259                                 if (setpgid(0, pgrp) == 0
10260                                  && pi->followup != PIPE_BG
10261                                  && G_saved_tty_pgrp /* we have ctty */
10262                                 ) {
10263                                         /* We do it in *every* child, not just first,
10264                                          * to avoid races */
10265                                         tcsetpgrp(G_interactive_fd, pgrp);
10266                                 }
10267                         }
10268 #endif
10269                         if (pi->alive_cmds == 0 && pi->followup == PIPE_BG) {
10270                                 /* 1st cmd in backgrounded pipe
10271                                  * should have its stdin /dev/null'ed */
10272                                 close(0);
10273                                 if (open(bb_dev_null, O_RDONLY))
10274                                         xopen("/", O_RDONLY);
10275                         } else {
10276                                 xmove_fd(next_infd, 0);
10277                         }
10278                         xmove_fd(pipefds.wr, 1);
10279                         if (pipefds.rd > 1)
10280                                 close(pipefds.rd);
10281                         /* Like bash, explicit redirects override pipes,
10282                          * and the pipe fd (fd#1) is available for dup'ing:
10283                          * "cmd1 2>&1 | cmd2": fd#1 is duped to fd#2, thus stderr
10284                          * of cmd1 goes into pipe.
10285                          */
10286                         if (setup_redirects(command, NULL)) {
10287                                 /* Happens when redir file can't be opened:
10288                                  * $ hush -c 'echo FOO >&2 | echo BAR 3>/qwe/rty; echo BAZ'
10289                                  * FOO
10290                                  * hush: can't open '/qwe/rty': No such file or directory
10291                                  * BAZ
10292                                  * (echo BAR is not executed, it hits _exit(1) below)
10293                                  */
10294                                 _exit(1);
10295                         }
10296
10297                         /* Stores to nommu_save list of env vars putenv'ed
10298                          * (NOMMU, on MMU we don't need that) */
10299                         /* cast away volatility... */
10300                         pseudo_exec((nommu_save_t*) &nommu_save, command, argv_expanded);
10301                         /* pseudo_exec() does not return */
10302                 }
10303
10304                 /* parent or error */
10305 #if ENABLE_HUSH_FAST
10306                 G.count_SIGCHLD++;
10307 //bb_error_msg("[%d] fork in run_pipe: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
10308 #endif
10309                 enable_restore_tty_pgrp_on_exit();
10310 #if !BB_MMU
10311                 /* Clean up after vforked child */
10312                 free(nommu_save.argv);
10313                 free(nommu_save.argv_from_re_execing);
10314                 G.var_nest_level = sv_var_nest_level;
10315                 remove_nested_vars();
10316                 add_vars(nommu_save.old_vars);
10317 #endif
10318                 free(argv_expanded);
10319                 argv_expanded = NULL;
10320                 if (command->pid < 0) { /* [v]fork failed */
10321                         /* Clearly indicate, was it fork or vfork */
10322                         bb_simple_perror_msg(BB_MMU ? "vfork"+1 : "vfork");
10323                 } else {
10324                         pi->alive_cmds++;
10325 #if ENABLE_HUSH_JOB
10326                         /* Second and next children need to know pid of first one */
10327                         if (pi->pgrp < 0)
10328                                 pi->pgrp = command->pid;
10329 #endif
10330                 }
10331
10332                 if (cmd_no > 1)
10333                         close(next_infd);
10334                 if (cmd_no < pi->num_cmds)
10335                         close(pipefds.wr);
10336                 /* Pass read (output) pipe end to next iteration */
10337                 next_infd = pipefds.rd;
10338 #else /* __U_BOOT__ */
10339                 /* Process the command */
10340                 rcode = cmd_process(G.do_repeat ? CMD_FLAG_REPEAT : 0,
10341                                     command->argc, command->argv,
10342                                     &(G.flag_repeat), NULL);
10343
10344                 if (argv_expanded) {
10345                         /*
10346                          * expand_strvec_to_strvec() allocates memory to expand
10347                          * argv, we need to free it.
10348                          */
10349                         free(argv_expanded);
10350
10351                         /*
10352                          * We also restore command->argv to its original value
10353                          * so no memory leak happens.
10354                          */
10355                         command->argv = argv;
10356
10357                         /*
10358                          * NOTE argc exists only in U-Boot, so argv freeing does
10359                          * not rely on it as this code exists in BusyBox.
10360                          */
10361                 }
10362 #endif /* __U_BOOT__ */
10363         }
10364
10365 #ifndef __U_BOOT__
10366         if (!pi->alive_cmds) {
10367                 debug_leave();
10368                 debug_printf_exec("run_pipe return 1 (all forks failed, no children)\n");
10369                 return 1;
10370         }
10371 #endif /* __U_BOOT__ */
10372
10373         debug_leave();
10374 #ifndef __U_BOOT__
10375         debug_printf_exec("run_pipe return -1 (%u children started)\n", pi->alive_cmds);
10376         return -1;
10377 #else /* __U_BOOT__ */
10378         debug_printf_exec("run_pipe return %d\n", rcode);
10379         return rcode;
10380 #endif /* __U_BOOT__ */
10381 }
10382
10383 /* NB: called by pseudo_exec, and therefore must not modify any
10384  * global data until exec/_exit (we can be a child after vfork!) */
10385 static int run_list(struct pipe *pi)
10386 {
10387 #if ENABLE_HUSH_CASE
10388         char *case_word = NULL;
10389 #endif
10390 #if ENABLE_HUSH_LOOPS
10391         struct pipe *loop_top = NULL;
10392         char **for_lcur = NULL;
10393         char **for_list = NULL;
10394 #endif
10395         smallint last_followup;
10396         smalluint rcode;
10397 #if ENABLE_HUSH_IF || ENABLE_HUSH_CASE
10398         smalluint cond_code = 0;
10399 #else
10400         enum { cond_code = 0 };
10401 #endif
10402 #if HAS_KEYWORDS
10403         smallint rword;      /* RES_foo */
10404         smallint last_rword; /* ditto */
10405 #endif
10406
10407 #ifndef __U_BOOT__
10408         debug_printf_exec("run_list lvl %d start\n", G.run_list_level);
10409         debug_enter();
10410 #endif /* !__U_BOOT__ */
10411
10412         set_G_ifs();
10413
10414 #if ENABLE_HUSH_LOOPS
10415         /* Check syntax for "for" */
10416         {
10417                 struct pipe *cpipe;
10418                 for (cpipe = pi; cpipe; cpipe = cpipe->next) {
10419                         if (cpipe->res_word != RES_FOR && cpipe->res_word != RES_IN)
10420                                 continue;
10421                         /* current word is FOR or IN (BOLD in comments below) */
10422                         if (cpipe->next == NULL) {
10423                                 syntax_error("malformed for");
10424                                 debug_leave();
10425                                 debug_printf_exec("run_list lvl %d return 1\n", G.run_list_level);
10426                                 return 1;
10427                         }
10428                         /* "FOR v; do ..." and "for v IN a b; do..." are ok */
10429                         if (cpipe->next->res_word == RES_DO)
10430                                 continue;
10431                         /* next word is not "do". It must be "in" then ("FOR v in ...") */
10432                         if (cpipe->res_word == RES_IN /* "for v IN a b; not_do..."? */
10433                          || cpipe->next->res_word != RES_IN /* FOR v not_do_and_not_in..."? */
10434                         ) {
10435                                 syntax_error("malformed for");
10436                                 debug_leave();
10437                                 debug_printf_exec("run_list lvl %d return 1\n", G.run_list_level);
10438                                 return 1;
10439                         }
10440                 }
10441         }
10442 #endif
10443
10444         /* Past this point, all code paths should jump to ret: label
10445          * in order to return, no direct "return" statements please.
10446          * This helps to ensure that no memory is leaked. */
10447
10448 #if ENABLE_HUSH_JOB
10449         G.run_list_level++;
10450 #endif
10451
10452 #if HAS_KEYWORDS
10453         rword = RES_NONE;
10454         last_rword = RES_XXXX;
10455 #endif
10456         last_followup = PIPE_SEQ;
10457         rcode = G.last_exitcode;
10458
10459         /* Go through list of pipes, (maybe) executing them. */
10460 #ifndef __U_BOOT__
10461         for (; pi; pi = IF_HUSH_LOOPS(rword == RES_DONE ? loop_top : ) pi->next) {
10462 #else /* __U_BOOT__ */
10463         for (; pi; pi = rword == RES_DONE ? loop_top : pi->next) {
10464 #endif /* __U_BOOT__ */
10465                 int r;
10466                 int sv_errexit_depth;
10467
10468 #ifndef __U_BOOT__
10469                 if (G.flag_SIGINT)
10470                         break;
10471                 if (G_flag_return_in_progress == 1)
10472                         break;
10473 #endif /* !__U_BOOT__ */
10474
10475                 IF_HAS_KEYWORDS(rword = pi->res_word;)
10476                 debug_printf_exec(": rword:%d cond_code:%d last_rword:%d\n",
10477                                 rword, cond_code, last_rword);
10478
10479                 sv_errexit_depth = G.errexit_depth;
10480                 if (
10481 #if ENABLE_HUSH_IF
10482                     rword == RES_IF || rword == RES_ELIF ||
10483 #endif
10484                     pi->followup != PIPE_SEQ
10485                 ) {
10486                         G.errexit_depth++;
10487                 }
10488 #if ENABLE_HUSH_LOOPS
10489                 if ((rword == RES_WHILE || rword == RES_UNTIL || rword == RES_FOR)
10490                  && loop_top == NULL /* avoid bumping G.depth_of_loop twice */
10491                 ) {
10492                         /* start of a loop: remember where loop starts */
10493                         loop_top = pi;
10494                         G.depth_of_loop++;
10495                 }
10496 #endif
10497                 /* Still in the same "if...", "then..." or "do..." branch? */
10498                 if (IF_HAS_KEYWORDS(rword == last_rword &&) 1) {
10499                         if ((rcode == 0 && last_followup == PIPE_OR)
10500                          || (rcode != 0 && last_followup == PIPE_AND)
10501                         ) {
10502                                 /* It is "<true> || CMD" or "<false> && CMD"
10503                                  * and we should not execute CMD */
10504                                 debug_printf_exec("skipped cmd because of || or &&\n");
10505                                 last_followup = pi->followup;
10506                                 goto dont_check_jobs_but_continue;
10507                         }
10508                 }
10509                 last_followup = pi->followup;
10510 #if ENABLE_HUSH_IF
10511                 if (cond_code != 0) {
10512                         if (rword == RES_THEN) {
10513                                 /* if false; then ... fi has exitcode 0! */
10514                                 G.last_exitcode = rcode = EXIT_SUCCESS;
10515                                 /* "if <false> THEN cmd": skip cmd */
10516                                 debug_printf_exec("skipped THEN cmd because IF condition was false\n");
10517                                 last_rword = rword;
10518                                 continue;
10519                         }
10520                 } else {
10521                         if (rword == RES_ELSE
10522                          || (rword == RES_ELIF && last_rword != RES_ELIF)
10523                         ) {
10524                                 /* "if <true> then ... ELSE/ELIF cmd":
10525                                  * skip cmd and all following ones */
10526                                 debug_printf_exec("skipped ELSE/ELIF branch because IF condition was true\n");
10527                                 break;
10528                         }
10529                         //if (rword == RES_THEN): "if <true> THEN cmd", run cmd (fall through)
10530                 }
10531 #endif
10532                 IF_HAS_KEYWORDS(last_rword = rword;)
10533 #if ENABLE_HUSH_LOOPS
10534                 if (rword == RES_FOR) { /* && pi->num_cmds - always == 1 */
10535                         if (!for_lcur) {
10536                                 /* first loop through for */
10537
10538                                 static const char encoded_dollar_at[] ALIGN1 = {
10539                                         SPECIAL_VAR_SYMBOL, '@' | 0x80, SPECIAL_VAR_SYMBOL, '\0'
10540                                 }; /* encoded representation of "$@" */
10541                                 static const char *const encoded_dollar_at_argv[] ALIGN_PTR = {
10542                                         encoded_dollar_at, NULL
10543                                 }; /* argv list with one element: "$@" */
10544                                 char **vals;
10545
10546                                 G.last_exitcode = rcode = EXIT_SUCCESS;
10547                                 vals = (char**)encoded_dollar_at_argv;
10548                                 if (pi->next->res_word == RES_IN) {
10549                                         /* if no variable values after "in" we skip "for" */
10550                                         if (!pi->next->cmds[0].argv) {
10551                                                 debug_printf_exec(": null FOR: exitcode EXIT_SUCCESS\n");
10552                                                 break;
10553                                         }
10554                                         vals = pi->next->cmds[0].argv;
10555                                 } /* else: "for var; do..." -> assume "$@" list */
10556                                 /* create list of variable values */
10557                                 debug_print_strings("for_list made from", vals);
10558                                 for_list = expand_strvec_to_strvec(vals);
10559                                 for_lcur = for_list;
10560                                 debug_print_strings("for_list", for_list);
10561                         }
10562                         if (!*for_lcur) {
10563                                 /* "for" loop is over, clean up */
10564                                 free(for_list);
10565                                 for_list = NULL;
10566                                 for_lcur = NULL;
10567                                 break;
10568                         }
10569                         /* Insert next value from for_lcur */
10570                         /* note: *for_lcur already has quotes removed, $var expanded, etc */
10571 #ifndef __U_BOOT__
10572                         set_local_var_from_halves(pi->cmds[0].argv[0], *for_lcur++);
10573 #else /* __U_BOOT__ */
10574                         /* We cannot use xasprintf, so we emulate it. */
10575                         char *full_var;
10576                         char *var = pi->cmds[0].argv[0];
10577                         char *val = *for_lcur++;
10578
10579                         /* + 1 to take into account =. */
10580                         full_var = xmalloc(strlen(var) + strlen(val) + 1);
10581                         sprintf(full_var, "%s=%s", var, val);
10582
10583                         set_local_var_modern(full_var, /*flag:*/ 0);
10584 #endif /* __U_BOOT__ */
10585                         continue;
10586                 }
10587                 if (rword == RES_IN) {
10588                         continue; /* "for v IN list;..." - "in" has no cmds anyway */
10589                 }
10590                 if (rword == RES_DONE) {
10591                         continue; /* "done" has no cmds too */
10592                 }
10593 #endif
10594 #if ENABLE_HUSH_CASE
10595                 if (rword == RES_CASE) {
10596                         debug_printf_exec("CASE cond_code:%d\n", cond_code);
10597                         case_word = expand_string_to_string(pi->cmds->argv[0],
10598                                 EXP_FLAG_ESC_GLOB_CHARS, /*unbackslash:*/ 1);
10599                         debug_printf_exec("CASE word1:'%s'\n", case_word);
10600                         //unbackslash(case_word);
10601                         //debug_printf_exec("CASE word2:'%s'\n", case_word);
10602                         continue;
10603                 }
10604                 if (rword == RES_MATCH) {
10605                         char **argv;
10606
10607                         debug_printf_exec("MATCH cond_code:%d\n", cond_code);
10608                         if (!case_word) /* "case ... matched_word) ... WORD)": we executed selected branch, stop */
10609                                 break;
10610                         /* all prev words didn't match, does this one match? */
10611                         argv = pi->cmds->argv;
10612                         while (*argv) {
10613                                 char *pattern;
10614                                 debug_printf_exec("expand_string_to_string('%s')\n", *argv);
10615                                 pattern = expand_string_to_string(*argv,
10616                                                 EXP_FLAG_ESC_GLOB_CHARS,
10617                                                 /*unbackslash:*/ 0
10618                                 );
10619                                 /* TODO: which FNM_xxx flags to use? */
10620                                 cond_code = (fnmatch(pattern, case_word, /*flags:*/ 0) != 0);
10621                                 debug_printf_exec("cond_code=fnmatch(pattern:'%s',str:'%s'):%d\n",
10622                                                 pattern, case_word, cond_code);
10623                                 free(pattern);
10624                                 if (cond_code == 0) {
10625                                         /* match! we will execute this branch */
10626                                         free(case_word);
10627                                         case_word = NULL; /* make future "word)" stop */
10628                                         break;
10629                                 }
10630                                 argv++;
10631                         }
10632                         continue;
10633                 }
10634                 if (rword == RES_CASE_BODY) { /* inside of a case branch */
10635                         debug_printf_exec("CASE_BODY cond_code:%d\n", cond_code);
10636                         if (cond_code != 0)
10637                                 continue; /* not matched yet, skip this pipe */
10638                 }
10639                 if (rword == RES_ESAC) {
10640                         debug_printf_exec("ESAC cond_code:%d\n", cond_code);
10641                         if (case_word) {
10642                                 /* "case" did not match anything: still set $? (to 0) */
10643                                 G.last_exitcode = rcode = EXIT_SUCCESS;
10644                         }
10645                 }
10646 #endif
10647                 /* Just pressing <enter> in shell should check for jobs.
10648                  * OTOH, in non-interactive shell this is useless
10649                  * and only leads to extra job checks */
10650                 if (pi->num_cmds == 0) {
10651 #ifndef __U_BOOT__
10652                         if (G_interactive_fd)
10653                                 goto check_jobs_and_continue;
10654 #endif /* !__U_BOOT__ */
10655                         continue;
10656                 }
10657
10658                 /* After analyzing all keywords and conditions, we decided
10659                  * to execute this pipe. NB: have to do checkjobs(NULL)
10660                  * after run_pipe to collect any background children,
10661                  * even if list execution is to be stopped. */
10662                 debug_printf_exec(": run_pipe with %d members\n", pi->num_cmds);
10663 #ifndef __U_BOOT__
10664 #if ENABLE_HUSH_LOOPS
10665                 G.flag_break_continue = 0;
10666 #endif
10667 #endif /* !__U_BOOT__ */
10668 #ifndef __U_BOOT__
10669                 rcode = r = G.o_opt[OPT_O_NOEXEC] ? 0 : run_pipe(pi);
10670                 /* NB: rcode is a smalluint, r is int */
10671 #else /* __U_BOOT__ */
10672                 rcode = r = run_pipe(pi); /* NB: rcode is a smalluint, r is int */
10673                 if (r <= EXIT_RET_CODE) {
10674                         int previous_rcode = G.last_exitcode;
10675                         /*
10676                          * This magic is to get the exit code given by the user.
10677                          * Contrary to old shell code, we use + EXIT_RET_CODE as EXIT_RET_CODE
10678                          * equals -2.
10679                          */
10680                         G.last_exitcode = -r + EXIT_RET_CODE;
10681
10682                         /*
10683                          * This case deals with the following:
10684                          * => setenv inner 'echo entry inner; exit; echo inner done'
10685                          * => setenv outer 'echo entry outer; run inner; echo outer done'
10686                          * => run outer
10687                          * So, if we are in inner, we need to break and not run the other
10688                          * commands.
10689                          * Otherwise, we just continue in outer.
10690                          * As return code are propagated, we use the previous value to check if
10691                          * exit was just called or was propagated.
10692                          */
10693                         if (previous_rcode != r) {
10694                                 /*
10695                                  * If run from run_command, run_command_flags will be set, so we check
10696                                  * this to know if we are in main input shell.
10697                                  */
10698                                 if (!G.run_command_flags)
10699                                         printf("exit not allowed from main input shell.\n");
10700
10701                                 break;
10702                         }
10703                         continue;
10704                 }
10705 #endif /* __U_BOOT__ */
10706                 if (r != -1) {
10707                         /* We ran a builtin, function, or group.
10708                          * rcode is already known
10709                          * and we don't need to wait for anything. */
10710                         debug_printf_exec(": builtin/func exitcode %d\n", rcode);
10711                         G.last_exitcode = rcode;
10712 #ifndef __U_BOOT__
10713                         check_and_run_traps();
10714 #endif /* !__U_BOOT__ */
10715 #if ENABLE_HUSH_TRAP && ENABLE_HUSH_FUNCTIONS
10716                         rcode = G.last_exitcode; /* "return" in trap can change it, read back */
10717 #endif
10718 #ifndef __U_BOOT__
10719 #if ENABLE_HUSH_LOOPS
10720                         /* Was it "break" or "continue"? */
10721                         if (G.flag_break_continue) {
10722                                 smallint fbc = G.flag_break_continue;
10723                                 /* We might fall into outer *loop*,
10724                                  * don't want to break it too */
10725                                 if (loop_top) {
10726                                         G.depth_break_continue--;
10727                                         if (G.depth_break_continue == 0)
10728                                                 G.flag_break_continue = 0;
10729                                         /* else: e.g. "continue 2" should *break* once, *then* continue */
10730                                 } /* else: "while... do... { we are here (innermost list is not a loop!) };...done" */
10731                                 if (G.depth_break_continue != 0 || fbc == BC_BREAK) {
10732                                         checkjobs(NULL, 0 /*(no pid to wait for)*/);
10733                                         break;
10734                                 }
10735                                 /* "continue": simulate end of loop */
10736                                 rword = RES_DONE;
10737                                 continue;
10738                         }
10739 #endif
10740                         if (G_flag_return_in_progress == 1) {
10741                                 checkjobs(NULL, 0 /*(no pid to wait for)*/);
10742                                 break;
10743                         }
10744
10745                 } else if (pi->followup == PIPE_BG) {
10746                         /* What does bash do with attempts to background builtins? */
10747                         /* even bash 3.2 doesn't do that well with nested bg:
10748                          * try "{ { sleep 10; echo DEEP; } & echo HERE; } &".
10749                          * I'm NOT treating inner &'s as jobs */
10750 #if ENABLE_HUSH_JOB
10751                         if (G.run_list_level == 1)
10752                                 insert_job_into_table(pi);
10753 #endif
10754                         /* Last command's pid goes to $! */
10755                         G.last_bg_pid = pi->cmds[pi->num_cmds - 1].pid;
10756                         G.last_bg_pid_exitcode = 0;
10757                         debug_printf_exec(": cmd&: exitcode EXIT_SUCCESS\n");
10758 /* Check pi->pi_inverted? "! sleep 1 & echo $?": bash says 1. dash and ash say 0 */
10759                         rcode = EXIT_SUCCESS;
10760                         goto check_traps;
10761                 } else {
10762 #if ENABLE_HUSH_JOB
10763                         if (G.run_list_level == 1 && G_interactive_fd) {
10764                                 /* Waits for completion, then fg's main shell */
10765                                 rcode = checkjobs_and_fg_shell(pi);
10766                                 debug_printf_exec(": checkjobs_and_fg_shell exitcode %d\n", rcode);
10767                                 goto check_traps;
10768                         }
10769 #endif
10770                         /* This one just waits for completion */
10771                         rcode = checkjobs(pi, 0 /*(no pid to wait for)*/);
10772                         debug_printf_exec(": checkjobs exitcode %d\n", rcode);
10773  check_traps:
10774                         G.last_exitcode = rcode;
10775                         check_and_run_traps();
10776 #if ENABLE_HUSH_TRAP && ENABLE_HUSH_FUNCTIONS
10777                         rcode = G.last_exitcode; /* "return" in trap can change it, read back */
10778 #endif
10779                 }
10780 #endif /* !__U_BOOT__ */
10781
10782 #ifndef __U_BOOT__
10783                 /* Handle "set -e" */
10784                 if (rcode != 0 && G.o_opt[OPT_O_ERREXIT]) {
10785                         debug_printf_exec("ERREXIT:1 errexit_depth:%d\n", G.errexit_depth);
10786                         if (G.errexit_depth == 0)
10787                                 hush_exit(rcode);
10788                 }
10789 #else /* __U_BOOT__ */
10790                 } /* if (r != -1) */
10791 #endif /* __U_BOOT__ */
10792                 G.errexit_depth = sv_errexit_depth;
10793
10794                 /* Analyze how result affects subsequent commands */
10795 #if ENABLE_HUSH_IF
10796                 if (rword == RES_IF || rword == RES_ELIF) {
10797                         debug_printf_exec("cond_code=rcode:%d\n", rcode);
10798                         cond_code = rcode;
10799                 }
10800 #endif
10801 #ifndef __U_BOOT__
10802  check_jobs_and_continue:
10803                 checkjobs(NULL, 0 /*(no pid to wait for)*/);
10804 #endif /* !__U_BOOT__ */
10805  dont_check_jobs_but_continue: ;
10806 #if ENABLE_HUSH_LOOPS
10807                 /* Beware of "while false; true; do ..."! */
10808                 if (pi->next
10809                  && (pi->next->res_word == RES_DO || pi->next->res_word == RES_DONE)
10810                  /* check for RES_DONE is needed for "while ...; do \n done" case */
10811                 ) {
10812                         if (rword == RES_WHILE) {
10813                                 if (rcode) {
10814                                         /* "while false; do...done" - exitcode 0 */
10815                                         G.last_exitcode = rcode = EXIT_SUCCESS;
10816                                         debug_printf_exec(": while expr is false: breaking (exitcode:EXIT_SUCCESS)\n");
10817                                         break;
10818                                 }
10819                         }
10820                         if (rword == RES_UNTIL) {
10821                                 if (!rcode) {
10822                                         debug_printf_exec(": until expr is true: breaking\n");
10823                                         break;
10824                                 }
10825                         }
10826                 }
10827 #endif
10828         } /* for (pi) */
10829
10830 #if ENABLE_HUSH_JOB
10831         G.run_list_level--;
10832 #endif
10833 #if ENABLE_HUSH_LOOPS
10834         if (loop_top)
10835                 G.depth_of_loop--;
10836         free(for_list);
10837 #endif
10838 #if ENABLE_HUSH_CASE
10839         free(case_word);
10840 #endif
10841 #ifndef __U_BOOT__
10842         debug_leave();
10843         debug_printf_exec("run_list lvl %d return %d\n", G.run_list_level, rcode);
10844 #endif /* !__U_BOOT__ */
10845         return rcode;
10846 }
10847
10848 /* Select which version we will use */
10849 static int run_and_free_list(struct pipe *pi)
10850 {
10851         int rcode = 0;
10852         debug_printf_exec("run_and_free_list entered\n");
10853 #ifndef __U_BOOT__
10854         if (!G.o_opt[OPT_O_NOEXEC]) {
10855 #endif /* !__U_BOOT__ */
10856                 debug_printf_exec(": run_list: 1st pipe with %d cmds\n", pi->num_cmds);
10857                 rcode = run_list(pi);
10858 #ifndef __U_BOOT__
10859         }
10860 #endif /* !__U_BOOT__ */
10861         /* free_pipe_list has the side effect of clearing memory.
10862          * In the long run that function can be merged with run_list,
10863          * but doing that now would hobble the debugging effort. */
10864         free_pipe_list(pi);
10865         debug_printf_exec("run_and_free_list return %d\n", rcode);
10866         return rcode;
10867 }
10868
10869 #ifndef __U_BOOT__
10870 static void install_sighandlers(unsigned mask)
10871 {
10872         sighandler_t old_handler;
10873         unsigned sig = 0;
10874         while ((mask >>= 1) != 0) {
10875                 sig++;
10876                 if (!(mask & 1))
10877                         continue;
10878                 old_handler = install_sighandler(sig, pick_sighandler(sig));
10879                 /* POSIX allows shell to re-enable SIGCHLD
10880                  * even if it was SIG_IGN on entry.
10881                  * Therefore we skip IGN check for it:
10882                  */
10883                 if (sig == SIGCHLD)
10884                         continue;
10885                 /* Interactive bash re-enables SIGHUP which is SIG_IGNed on entry.
10886                  * Try:
10887                  * trap '' hup; bash; echo RET  # type "kill -hup $$", see SIGHUP having effect
10888                  * trap '' hup; bash -c 'kill -hup $$; echo ALIVE'  # here SIGHUP is SIG_IGNed
10889                  */
10890                 if (sig == SIGHUP && G_interactive_fd)
10891                         continue;
10892                 /* Unless one of the above signals, is it SIG_IGN? */
10893                 if (old_handler == SIG_IGN) {
10894                         /* oops... restore back to IGN, and record this fact */
10895                         install_sighandler(sig, old_handler);
10896 #if ENABLE_HUSH_TRAP
10897                         if (!G_traps)
10898                                 G_traps = xzalloc(sizeof(G_traps[0]) * NSIG);
10899                         free(G_traps[sig]);
10900                         G_traps[sig] = xzalloc(1); /* == xstrdup(""); */
10901 #endif
10902                 }
10903         }
10904 }
10905
10906 /* Called a few times only (or even once if "sh -c") */
10907 static void install_special_sighandlers(void)
10908 {
10909         unsigned mask;
10910
10911         /* Which signals are shell-special? */
10912         mask = (1 << SIGQUIT) | (1 << SIGCHLD);
10913         if (G_interactive_fd) {
10914                 mask |= SPECIAL_INTERACTIVE_SIGS;
10915                 if (G_saved_tty_pgrp) /* we have ctty, job control sigs work */
10916                         mask |= SPECIAL_JOBSTOP_SIGS;
10917         }
10918         /* Careful, do not re-install handlers we already installed */
10919         if (G.special_sig_mask != mask) {
10920                 unsigned diff = mask & ~G.special_sig_mask;
10921                 G.special_sig_mask = mask;
10922                 install_sighandlers(diff);
10923         }
10924 }
10925
10926 #if ENABLE_HUSH_JOB
10927 /* helper */
10928 /* Set handlers to restore tty pgrp and exit */
10929 static void install_fatal_sighandlers(void)
10930 {
10931         unsigned mask;
10932
10933         /* We will restore tty pgrp on these signals */
10934         mask = 0
10935                 /*+ (1 << SIGILL ) * HUSH_DEBUG*/
10936                 /*+ (1 << SIGFPE ) * HUSH_DEBUG*/
10937                 + (1 << SIGBUS ) * HUSH_DEBUG
10938                 + (1 << SIGSEGV) * HUSH_DEBUG
10939                 /*+ (1 << SIGTRAP) * HUSH_DEBUG*/
10940                 + (1 << SIGABRT)
10941         /* bash 3.2 seems to handle these just like 'fatal' ones */
10942                 + (1 << SIGPIPE)
10943                 + (1 << SIGALRM)
10944         /* if we are interactive, SIGHUP, SIGTERM and SIGINT are special sigs.
10945          * if we aren't interactive... but in this case
10946          * we never want to restore pgrp on exit, and this fn is not called
10947          */
10948                 /*+ (1 << SIGHUP )*/
10949                 /*+ (1 << SIGTERM)*/
10950                 /*+ (1 << SIGINT )*/
10951         ;
10952         G_fatal_sig_mask = mask;
10953
10954         install_sighandlers(mask);
10955 }
10956 #endif
10957
10958 static int set_mode(int state, char mode, const char *o_opt)
10959 {
10960         int idx;
10961         switch (mode) {
10962         case 'n':
10963                 /* set -n has no effect in interactive shell */
10964                 /* Try: while set -n; do echo $-; done */
10965                 if (!G_interactive_fd)
10966                         G.o_opt[OPT_O_NOEXEC] = state;
10967                 break;
10968         case 'x':
10969                 IF_HUSH_MODE_X(G_x_mode = state;)
10970                 IF_HUSH_MODE_X(if (G.x_mode_fd <= 0) G.x_mode_fd = dup_CLOEXEC(2, 10);)
10971                 break;
10972         case 'e':
10973                 G.o_opt[OPT_O_ERREXIT] = state;
10974                 break;
10975         case 'o':
10976                 if (!o_opt) {
10977                         /* "set -o" or "set +o" without parameter.
10978                          * in bash, set -o produces this output:
10979                          *  pipefail        off
10980                          * and set +o:
10981                          *  set +o pipefail
10982                          * We always use the second form.
10983                          */
10984                         const char *p = o_opt_strings;
10985                         idx = 0;
10986                         while (*p) {
10987                                 printf("set %co %s\n", (G.o_opt[idx] ? '-' : '+'), p);
10988                                 idx++;
10989                                 p += strlen(p) + 1;
10990                         }
10991                         break;
10992                 }
10993                 idx = index_in_strings(o_opt_strings, o_opt);
10994                 if (idx >= 0) {
10995                         G.o_opt[idx] = state;
10996                         break;
10997                 }
10998                 /* fall through to error */
10999         default:
11000                 return EXIT_FAILURE;
11001         }
11002         return EXIT_SUCCESS;
11003 }
11004
11005 int hush_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
11006 int hush_main(int argc, char **argv)
11007 {
11008         pid_t cached_getpid;
11009         enum {
11010                 OPT_login = (1 << 0),
11011         };
11012         unsigned flags;
11013 #if !BB_MMU
11014         unsigned builtin_argc = 0;
11015 #endif
11016         char **e;
11017         struct variable *cur_var;
11018         struct variable *shell_ver;
11019
11020         INIT_G();
11021         if (EXIT_SUCCESS != 0) /* if EXIT_SUCCESS == 0, it is already done */
11022                 G.last_exitcode = EXIT_SUCCESS;
11023 #if !BB_MMU
11024         /* "Big heredoc" support via "sh -< STRING" invocation.
11025          * Check it first (do not bother to run the usual init code,
11026          * it is not needed for this case).
11027          */
11028         if (argv[1]
11029          && argv[1][0] == '-' && argv[1][1] == '<' /*&& !argv[1][2]*/
11030          /*&& argv[2] && !argv[3] - we don't check some conditions */
11031         ) {
11032                 full_write1_str(argv[2]);
11033                 _exit(0);
11034         }
11035         G.argv0_for_re_execing = argv[0];
11036 #endif
11037 #if ENABLE_HUSH_TRAP
11038 # if ENABLE_HUSH_FUNCTIONS
11039         G.return_exitcode = -1;
11040 # endif
11041         G.pre_trap_exitcode = -1;
11042 #endif
11043
11044 #if ENABLE_HUSH_FAST
11045         G.count_SIGCHLD++; /* ensure it is != G.handled_SIGCHLD */
11046 #endif
11047
11048         cached_getpid = getpid();   /* for tcsetpgrp() during init */
11049         G.root_pid = cached_getpid; /* for $PID  (NOMMU can override via -$HEXPID:HEXPPID:...) */
11050         G.root_ppid = getppid();    /* for $PPID (NOMMU can override) */
11051
11052         /* Deal with HUSH_VERSION */
11053         debug_printf_env("unsetenv '%s'\n", "HUSH_VERSION");
11054         unsetenv("HUSH_VERSION"); /* in case it exists in initial env */
11055         shell_ver = xzalloc(sizeof(*shell_ver));
11056         shell_ver->flg_export = 1;
11057         shell_ver->flg_read_only = 1;
11058         /* Code which handles ${var<op>...} needs writable values for all variables,
11059          * therefore we xstrdup: */
11060         shell_ver->varstr = xstrdup(hush_version_str);
11061
11062         /* Create shell local variables from the values
11063          * currently living in the environment */
11064         G.top_var = shell_ver;
11065         cur_var = G.top_var;
11066         e = environ;
11067         if (e) while (*e) {
11068                 char *value = strchr(*e, '=');
11069                 if (value) { /* paranoia */
11070                         cur_var->next = xzalloc(sizeof(*cur_var));
11071                         cur_var = cur_var->next;
11072                         cur_var->varstr = *e;
11073                         cur_var->max_len = strlen(*e);
11074                         cur_var->flg_export = 1;
11075                 }
11076                 e++;
11077         }
11078         /* (Re)insert HUSH_VERSION into env (AFTER we scanned the env!) */
11079         debug_printf_env("putenv '%s'\n", shell_ver->varstr);
11080         putenv(shell_ver->varstr);
11081
11082         /* Export PWD */
11083         set_pwd_var(SETFLAG_EXPORT);
11084
11085 #if BASH_HOSTNAME_VAR
11086         /* Set (but not export) HOSTNAME unless already set */
11087         if (!get_local_var_value("HOSTNAME")) {
11088                 struct utsname uts;
11089                 uname(&uts);
11090                 set_local_var_from_halves("HOSTNAME", uts.nodename);
11091         }
11092 #endif
11093         /* IFS is not inherited from the parent environment */
11094         set_local_var_from_halves("IFS", defifs);
11095
11096         if (!get_local_var_value("PATH"))
11097                 set_local_var_from_halves("PATH", bb_default_root_path);
11098
11099         /* PS1/PS2 are set later, if we determine that we are interactive */
11100
11101         /* bash also exports SHLVL and _,
11102          * and sets (but doesn't export) the following variables:
11103          * BASH=/bin/bash
11104          * BASH_VERSINFO=([0]="3" [1]="2" [2]="0" [3]="1" [4]="release" [5]="i386-pc-linux-gnu")
11105          * BASH_VERSION='3.2.0(1)-release'
11106          * HOSTTYPE=i386
11107          * MACHTYPE=i386-pc-linux-gnu
11108          * OSTYPE=linux-gnu
11109          * PPID=<NNNNN> - we also do it elsewhere
11110          * EUID=<NNNNN>
11111          * UID=<NNNNN>
11112          * GROUPS=()
11113          * LINES=<NNN>
11114          * COLUMNS=<NNN>
11115          * BASH_ARGC=()
11116          * BASH_ARGV=()
11117          * BASH_LINENO=()
11118          * BASH_SOURCE=()
11119          * DIRSTACK=()
11120          * PIPESTATUS=([0]="0")
11121          * HISTFILE=/<xxx>/.bash_history
11122          * HISTFILESIZE=500
11123          * HISTSIZE=500
11124          * MAILCHECK=60
11125          * PATH=/usr/gnu/bin:/usr/local/bin:/bin:/usr/bin:.
11126          * SHELL=/bin/bash
11127          * SHELLOPTS=braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor
11128          * TERM=dumb
11129          * OPTERR=1
11130          * OPTIND=1
11131          * PS4='+ '
11132          */
11133
11134 #if NUM_SCRIPTS > 0
11135         if (argc < 0) {
11136                 char *script = get_script_content(-argc - 1);
11137                 G.global_argv = argv;
11138                 G.global_argc = string_array_len(argv);
11139                 //install_special_sighandlers(); - needed?
11140                 parse_and_run_string(script);
11141                 goto final_return;
11142         }
11143 #endif
11144
11145         /* Initialize some more globals to non-zero values */
11146         die_func = restore_ttypgrp_and__exit;
11147
11148         /* Shell is non-interactive at first. We need to call
11149          * install_special_sighandlers() if we are going to execute "sh <script>",
11150          * "sh -c <cmds>" or login shell's /etc/profile and friends.
11151          * If we later decide that we are interactive, we run install_special_sighandlers()
11152          * in order to intercept (more) signals.
11153          */
11154
11155         /* Parse options */
11156         /* http://www.opengroup.org/onlinepubs/9699919799/utilities/sh.html */
11157         flags = (argv[0] && argv[0][0] == '-') ? OPT_login : 0;
11158         while (1) {
11159                 int opt = getopt(argc, argv, "+" /* stop at 1st non-option */
11160                                 "cexinsl"
11161 #if !BB_MMU
11162                                 "$:R:V:"
11163 # if ENABLE_HUSH_LINENO_VAR
11164                                 "L:"
11165 # endif
11166 # if ENABLE_HUSH_FUNCTIONS
11167                                 "F:"
11168 # endif
11169 #endif
11170                 );
11171                 if (opt <= 0)
11172                         break;
11173                 switch (opt) {
11174                 case 'c':
11175                         /* Note: -c is not an option with param!
11176                          * "hush -c -l SCRIPT" is valid. "hush -cSCRIPT" is not.
11177                          */
11178                         G.opt_c = 1;
11179                         break;
11180                 case 'i':
11181                         /* Well, we cannot just declare interactiveness,
11182                          * we have to have some stuff (ctty, etc) */
11183                         /* G_interactive_fd++; */
11184 //There are a few cases where bash -i -c 'SCRIPT'
11185 //has visible effect (differs from bash -c 'SCRIPT'):
11186 //it ignores TERM:
11187 //      bash -i -c 'kill $$; echo ALIVE'
11188 //      ALIVE
11189 //it resets SIG_IGNed HUP to SIG_DFL:
11190 //      trap '' hup; bash -i -c 'kill -hup $$; echo ALIVE'
11191 //      Hangup   [the message is not printed by bash, it's the shell which started it]
11192 //is talkative about jobs and exiting:
11193 //      bash -i -c 'sleep 1 & exit'
11194 //      [1] 16170
11195 //      exit
11196 //includes $ENV file (only if run as "sh"):
11197 //      echo last >/tmp/ENV; ENV=/tmp/ENV sh -i -c 'echo HERE'
11198 //      last: cannot open /var/log/wtmp: No such file or directory
11199 //      HERE
11200 //(under "bash", it's the opposite: it runs $BASH_ENV file only *without* -i).
11201 //
11202 //ash -i -c 'sleep 3; sleep 3', on ^C, drops into a prompt instead of exiting
11203 //(this may be a bug, bash does not do this).
11204 //(ash -i -c 'sleep 3' won't show this, the last command gets auto-"exec"ed)
11205 //
11206 //None of the above feel like useful features people would rely on.
11207                         break;
11208                 case 's':
11209                         G.opt_s = 1;
11210                         break;
11211                 case 'l':
11212                         flags |= OPT_login;
11213                         break;
11214 #if !BB_MMU
11215                 case '$': {
11216                         unsigned long long empty_trap_mask;
11217
11218                         G.root_pid = bb_strtou(optarg, &optarg, 16);
11219                         optarg++;
11220                         G.root_ppid = bb_strtou(optarg, &optarg, 16);
11221                         optarg++;
11222                         G.last_bg_pid = bb_strtou(optarg, &optarg, 16);
11223                         optarg++;
11224                         G.last_exitcode = bb_strtou(optarg, &optarg, 16);
11225                         optarg++;
11226                         builtin_argc = bb_strtou(optarg, &optarg, 16);
11227                         optarg++;
11228                         empty_trap_mask = bb_strtoull(optarg, &optarg, 16);
11229                         if (empty_trap_mask != 0) {
11230                                 IF_HUSH_TRAP(int sig;)
11231                                 install_special_sighandlers();
11232 # if ENABLE_HUSH_TRAP
11233                                 G_traps = xzalloc(sizeof(G_traps[0]) * NSIG);
11234                                 for (sig = 1; sig < NSIG; sig++) {
11235                                         if (empty_trap_mask & (1LL << sig)) {
11236                                                 G_traps[sig] = xzalloc(1); /* == xstrdup(""); */
11237                                                 install_sighandler(sig, SIG_IGN);
11238                                         }
11239                                 }
11240 # endif
11241                         }
11242 # if ENABLE_HUSH_LOOPS
11243                         optarg++;
11244                         G.depth_of_loop = bb_strtou(optarg, &optarg, 16);
11245 # endif
11246                         /* Suppress "killed by signal" message, -$ hack is used
11247                          * for subshells: echo `sh -c 'kill -9 $$'`
11248                          * should be silent.
11249                          */
11250                         IF_HUSH_JOB(G.run_list_level = 1;)
11251 # if ENABLE_HUSH_FUNCTIONS
11252                         /* nommu uses re-exec trick for "... | func | ...",
11253                          * should allow "return".
11254                          * This accidentally allows returns in subshells.
11255                          */
11256                         G_flag_return_in_progress = -1;
11257 # endif
11258                         break;
11259                 }
11260                 case 'R':
11261                 case 'V':
11262                         set_local_var(xstrdup(optarg), opt == 'R' ? SETFLAG_MAKE_RO : 0);
11263                         break;
11264 # if ENABLE_HUSH_LINENO_VAR
11265                 case 'L':
11266                         G.parse_lineno = xatou(optarg);
11267                         break;
11268 # endif
11269 # if ENABLE_HUSH_FUNCTIONS
11270                 case 'F': {
11271                         struct function *funcp = new_function(optarg);
11272                         /* funcp->name is already set to optarg */
11273                         /* funcp->body is set to NULL. It's a special case. */
11274                         funcp->body_as_string = argv[optind];
11275                         optind++;
11276                         break;
11277                 }
11278 # endif
11279 #endif
11280                 /*case '?': invalid option encountered (set_mode('?') will fail) */
11281                 /*case 'n':*/
11282                 /*case 'x':*/
11283                 /*case 'e':*/
11284                 default:
11285                         if (set_mode(1, opt, NULL) == 0) /* no error */
11286                                 break;
11287                         bb_show_usage();
11288                 }
11289         } /* option parsing loop */
11290
11291         /* Skip options. Try "hush -l": $1 should not be "-l"! */
11292         G.global_argc = argc - (optind - 1);
11293         G.global_argv = argv + (optind - 1);
11294         G.global_argv[0] = argv[0];
11295
11296         /* If we are login shell... */
11297         if (flags & OPT_login) {
11298                 const char *hp = NULL;
11299                 HFILE *input;
11300
11301                 debug_printf("sourcing /etc/profile\n");
11302                 input = hfopen("/etc/profile");
11303  run_profile:
11304                 if (input != NULL) {
11305                         install_special_sighandlers();
11306                         parse_and_run_file(input);
11307                         hfclose(input);
11308                 }
11309                 /* bash: after sourcing /etc/profile,
11310                  * tries to source (in the given order):
11311                  * ~/.bash_profile, ~/.bash_login, ~/.profile,
11312                  * stopping on first found. --noprofile turns this off.
11313                  * bash also sources ~/.bash_logout on exit.
11314                  * If called as sh, skips .bash_XXX files.
11315                  */
11316                 if (!hp) { /* unless we looped on the "goto" already */
11317                         hp = get_local_var_value("HOME");
11318                         if (hp && hp[0]) {
11319                                 debug_printf("sourcing ~/.profile\n");
11320                                 hp = concat_path_file(hp, ".profile");
11321                                 input = hfopen(hp);
11322                                 free((char*)hp);
11323                                 goto run_profile;
11324                         }
11325                 }
11326         }
11327
11328 #ifndef __U_BOOT__
11329         /* -c takes effect *after* -l */
11330         if (G.opt_c) {
11331                 /* Possibilities:
11332                  * sh ... -c 'script'
11333                  * sh ... -c 'script' ARG0 [ARG1...]
11334                  * On NOMMU, if builtin_argc != 0,
11335                  * sh ... -c 'builtin' BARGV... "" ARG0 [ARG1...]
11336                  * "" needs to be replaced with NULL
11337                  * and BARGV vector fed to builtin function.
11338                  * Note: the form without ARG0 never happens:
11339                  * sh ... -c 'builtin' BARGV... ""
11340                  */
11341                 char *script;
11342
11343                 install_special_sighandlers();
11344
11345                 G.global_argc--;
11346                 G.global_argv++;
11347 #if !BB_MMU
11348                 if (builtin_argc) {
11349                         /* -c 'builtin' [BARGV...] "" ARG0 [ARG1...] */
11350                         const struct built_in_command *x;
11351                         x = find_builtin(G.global_argv[0]);
11352                         if (x) { /* paranoia */
11353                                 argv = G.global_argv;
11354                                 G.global_argc -= builtin_argc + 1; /* skip [BARGV...] "" */
11355                                 G.global_argv += builtin_argc + 1;
11356                                 G.global_argv[-1] = NULL; /* replace "" */
11357                                 G.last_exitcode = x->b_function(argv);
11358                         }
11359                         goto final_return;
11360                 }
11361 #endif
11362
11363                 script = G.global_argv[0];
11364                 if (!script)
11365                         bb_error_msg_and_die(bb_msg_requires_arg, "-c");
11366                 if (!G.global_argv[1]) {
11367                         /* -c 'script' (no params): prevent empty $0 */
11368                         G.global_argv[0] = argv[0];
11369                 } else { /* else -c 'script' ARG0 [ARG1...]: $0 is ARG0 */
11370                         G.global_argc--;
11371                         G.global_argv++;
11372                 }
11373                 parse_and_run_string(script);
11374                 goto final_return;
11375         }
11376
11377         /* -s is: hush -s ARGV1 ARGV2 (no SCRIPT) */
11378         if (!G.opt_s && G.global_argv[1]) {
11379                 HFILE *input;
11380                 /*
11381                  * "bash <script>" (which is never interactive (unless -i?))
11382                  * sources $BASH_ENV here (without scanning $PATH).
11383                  * If called as sh, does the same but with $ENV.
11384                  * Also NB, per POSIX, $ENV should undergo parameter expansion.
11385                  */
11386                 G.global_argc--;
11387                 G.global_argv++;
11388                 debug_printf("running script '%s'\n", G.global_argv[0]);
11389                 xfunc_error_retval = 127; /* for "hush /does/not/exist" case */
11390                 input = hfopen(G.global_argv[0]);
11391                 if (!input) {
11392                         bb_simple_perror_msg_and_die(G.global_argv[0]);
11393                 }
11394                 xfunc_error_retval = 1;
11395                 install_special_sighandlers();
11396                 parse_and_run_file(input);
11397 #if ENABLE_FEATURE_CLEAN_UP
11398                 hfclose(input);
11399 #endif
11400                 goto final_return;
11401         }
11402         /* "implicit" -s: bare interactive hush shows 's' in $- */
11403         G.opt_s = 1;
11404
11405 #endif /* __U_BOOT__ */
11406         /* Up to here, shell was non-interactive. Now it may become one.
11407          * NB: don't forget to (re)run install_special_sighandlers() as needed.
11408          */
11409
11410         /* A shell is interactive if the '-i' flag was given,
11411          * or if all of the following conditions are met:
11412          *    no -c command
11413          *    no arguments remaining or the -s flag given
11414          *    standard input is a terminal
11415          *    standard output is a terminal
11416          * Refer to Posix.2, the description of the 'sh' utility.
11417          */
11418 #if ENABLE_HUSH_JOB
11419         if (isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)) {
11420                 G_saved_tty_pgrp = tcgetpgrp(STDIN_FILENO);
11421                 debug_printf("saved_tty_pgrp:%d\n", G_saved_tty_pgrp);
11422                 if (G_saved_tty_pgrp < 0)
11423                         G_saved_tty_pgrp = 0;
11424
11425                 /* try to dup stdin to high fd#, >= 255 */
11426                 G_interactive_fd = dup_CLOEXEC(STDIN_FILENO, 254);
11427                 if (G_interactive_fd < 0) {
11428                         /* try to dup to any fd */
11429                         G_interactive_fd = dup_CLOEXEC(STDIN_FILENO, -1);
11430                         if (G_interactive_fd < 0) {
11431                                 /* give up */
11432                                 G_interactive_fd = 0;
11433                                 G_saved_tty_pgrp = 0;
11434                         }
11435                 }
11436         }
11437         debug_printf("interactive_fd:%d\n", G_interactive_fd);
11438         if (G_interactive_fd) {
11439                 if (G_saved_tty_pgrp) {
11440                         /* If we were run as 'hush &', sleep until we are
11441                          * in the foreground (tty pgrp == our pgrp).
11442                          * If we get started under a job aware app (like bash),
11443                          * make sure we are now in charge so we don't fight over
11444                          * who gets the foreground */
11445                         while (1) {
11446                                 pid_t shell_pgrp = getpgrp();
11447                                 G_saved_tty_pgrp = tcgetpgrp(G_interactive_fd);
11448                                 if (G_saved_tty_pgrp == shell_pgrp)
11449                                         break;
11450                                 /* send TTIN to ourself (should stop us) */
11451                                 kill(- shell_pgrp, SIGTTIN);
11452                         }
11453                 }
11454
11455                 /* Install more signal handlers */
11456                 install_special_sighandlers();
11457
11458                 if (G_saved_tty_pgrp) {
11459                         /* Set other signals to restore saved_tty_pgrp */
11460                         install_fatal_sighandlers();
11461                         /* Put ourselves in our own process group
11462                          * (bash, too, does this only if ctty is available) */
11463                         bb_setpgrp(); /* is the same as setpgid(our_pid, our_pid); */
11464                         /* Grab control of the terminal */
11465                         tcsetpgrp(G_interactive_fd, cached_getpid);
11466                 }
11467                 enable_restore_tty_pgrp_on_exit();
11468
11469 # if ENABLE_FEATURE_EDITING
11470                 G.line_input_state = new_line_input_t(FOR_SHELL);
11471 #  if ENABLE_FEATURE_TAB_COMPLETION
11472                 G.line_input_state->get_exe_name = hush_command_name;
11473 #  endif
11474 #  if EDITING_HAS_sh_get_var
11475                 G.line_input_state->sh_get_var = get_local_var_value;
11476 #  endif
11477 # endif
11478 # if ENABLE_HUSH_SAVEHISTORY && MAX_HISTORY > 0
11479                 {
11480                         const char *hp = get_local_var_value("HISTFILE");
11481                         if (!hp) {
11482                                 hp = get_local_var_value("HOME");
11483                                 if (hp)
11484                                         hp = concat_path_file(hp, ".hush_history");
11485                         } else {
11486                                 hp = xstrdup(hp);
11487                         }
11488                         if (hp) {
11489                                 G.line_input_state->hist_file = hp;
11490                                 //set_local_var(xasprintf("HISTFILE=%s", ...));
11491                         }
11492 #  if ENABLE_FEATURE_SH_HISTFILESIZE
11493                         hp = get_local_var_value("HISTFILESIZE");
11494                         G.line_input_state->max_history = size_from_HISTFILESIZE(hp);
11495 #  endif
11496                 }
11497 # endif
11498         } else {
11499                 install_special_sighandlers();
11500         }
11501 #elif ENABLE_HUSH_INTERACTIVE
11502         /* No job control compiled in, only prompt/line editing */
11503         if (isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)) {
11504                 G_interactive_fd = dup_CLOEXEC(STDIN_FILENO, 254);
11505                 if (G_interactive_fd < 0) {
11506                         /* try to dup to any fd */
11507                         G_interactive_fd = dup_CLOEXEC(STDIN_FILENO, -1);
11508                         if (G_interactive_fd < 0)
11509                                 /* give up */
11510                                 G_interactive_fd = 0;
11511                 }
11512         }
11513         install_special_sighandlers();
11514 #else
11515         /* We have interactiveness code disabled */
11516         install_special_sighandlers();
11517 #endif
11518         /* bash:
11519          * if interactive but not a login shell, sources ~/.bashrc
11520          * (--norc turns this off, --rcfile <file> overrides)
11521          */
11522
11523         if (G_interactive_fd) {
11524 #if ENABLE_HUSH_INTERACTIVE && ENABLE_FEATURE_EDITING_FANCY_PROMPT
11525                 /* Set (but not export) PS1/2 unless already set */
11526                 if (!get_local_var_value("PS1"))
11527                         set_local_var_from_halves("PS1", "\\w \\$ ");
11528                 if (!get_local_var_value("PS2"))
11529                         set_local_var_from_halves("PS2", "> ");
11530 #endif
11531                 if (!ENABLE_FEATURE_SH_EXTRA_QUIET) {
11532                         /* note: ash and hush share this string */
11533                         printf("\n\n%s %s\n"
11534                                 IF_HUSH_HELP("Enter 'help' for a list of built-in commands.\n")
11535                                 "\n",
11536                                 bb_banner,
11537                                 "hush - the humble shell"
11538                         );
11539                 }
11540         }
11541
11542         parse_and_run_file(hfopen(NULL)); /* stdin */
11543
11544  final_return:
11545         hush_exit(G.last_exitcode);
11546 }
11547
11548 /*
11549  * Built-ins
11550  */
11551 static int FAST_FUNC builtin_true(char **argv UNUSED_PARAM)
11552 {
11553         return 0;
11554 }
11555
11556 static int FAST_FUNC builtin_false(char **argv UNUSED_PARAM)
11557 {
11558         return 1;
11559 }
11560
11561 #if ENABLE_HUSH_TEST || ENABLE_HUSH_ECHO || ENABLE_HUSH_PRINTF || ENABLE_HUSH_KILL
11562 static NOINLINE int run_applet_main(char **argv, int (*applet_main_func)(int argc, char **argv))
11563 {
11564         int argc = string_array_len(argv);
11565         return applet_main_func(argc, argv);
11566 }
11567 #endif
11568 #if ENABLE_HUSH_TEST || BASH_TEST2
11569 static int FAST_FUNC builtin_test(char **argv)
11570 {
11571         return run_applet_main(argv, test_main);
11572 }
11573 #endif
11574 #if ENABLE_HUSH_ECHO
11575 static int FAST_FUNC builtin_echo(char **argv)
11576 {
11577         return run_applet_main(argv, echo_main);
11578 }
11579 #endif
11580 #if ENABLE_HUSH_PRINTF
11581 static int FAST_FUNC builtin_printf(char **argv)
11582 {
11583         return run_applet_main(argv, printf_main);
11584 }
11585 #endif
11586
11587 #if ENABLE_HUSH_HELP
11588 static int FAST_FUNC builtin_help(char **argv UNUSED_PARAM)
11589 {
11590         const struct built_in_command *x;
11591
11592         printf(
11593                 "Built-in commands:\n"
11594                 "------------------\n");
11595         for (x = bltins1; x != &bltins1[ARRAY_SIZE(bltins1)]; x++) {
11596                 if (x->b_descr)
11597                         printf("%-10s%s\n", x->b_cmd, x->b_descr);
11598         }
11599         return EXIT_SUCCESS;
11600 }
11601 #endif
11602
11603 #if MAX_HISTORY && ENABLE_FEATURE_EDITING
11604 static int FAST_FUNC builtin_history(char **argv UNUSED_PARAM)
11605 {
11606         show_history(G.line_input_state);
11607         return EXIT_SUCCESS;
11608 }
11609 #endif
11610
11611 static int FAST_FUNC builtin_cd(char **argv)
11612 {
11613         const char *newdir;
11614
11615         argv = skip_dash_dash(argv);
11616         newdir = argv[0];
11617         if (newdir == NULL) {
11618                 /* bash does nothing (exitcode 0) if HOME is ""; if it's unset,
11619                  * bash says "bash: cd: HOME not set" and does nothing
11620                  * (exitcode 1)
11621                  */
11622                 const char *home = get_local_var_value("HOME");
11623                 newdir = home ? home : "/";
11624         }
11625         if (chdir(newdir)) {
11626                 /* Mimic bash message exactly */
11627                 bb_perror_msg("cd: %s", newdir);
11628                 return EXIT_FAILURE;
11629         }
11630         /* Read current dir (get_cwd(1) is inside) and set PWD.
11631          * Note: do not enforce exporting. If PWD was unset or unexported,
11632          * set it again, but do not export. bash does the same.
11633          */
11634         set_pwd_var(/*flag:*/ 0);
11635         return EXIT_SUCCESS;
11636 }
11637
11638 static int FAST_FUNC builtin_pwd(char **argv UNUSED_PARAM)
11639 {
11640         puts(get_cwd(0));
11641         return EXIT_SUCCESS;
11642 }
11643
11644 static int FAST_FUNC builtin_eval(char **argv)
11645 {
11646         argv = skip_dash_dash(argv);
11647
11648         if (!argv[0])
11649                 return EXIT_SUCCESS;
11650
11651         IF_HUSH_MODE_X(G.x_mode_depth++;)
11652         //bb_error_msg("%s: ++x_mode_depth=%d", __func__, G.x_mode_depth);
11653         if (!argv[1]) {
11654                 /* bash:
11655                  * eval "echo Hi; done" ("done" is syntax error):
11656                  * "echo Hi" will not execute too.
11657                  */
11658                 parse_and_run_string(argv[0]);
11659         } else {
11660                 /* "The eval utility shall construct a command by
11661                  * concatenating arguments together, separating
11662                  * each with a <space> character."
11663                  */
11664                 char *str, *p;
11665                 unsigned len = 0;
11666                 char **pp = argv;
11667                 do
11668                         len += strlen(*pp) + 1;
11669                 while (*++pp);
11670                 str = p = xmalloc(len);
11671                 pp = argv;
11672                 for (;;) {
11673                         p = stpcpy(p, *pp);
11674                         pp++;
11675                         if (!*pp)
11676                                 break;
11677                         *p++ = ' ';
11678                 }
11679                 parse_and_run_string(str);
11680                 free(str);
11681         }
11682         IF_HUSH_MODE_X(G.x_mode_depth--;)
11683         //bb_error_msg("%s: --x_mode_depth=%d", __func__, G.x_mode_depth);
11684         return G.last_exitcode;
11685 }
11686
11687 static int FAST_FUNC builtin_exec(char **argv)
11688 {
11689         argv = skip_dash_dash(argv);
11690         if (argv[0] == NULL)
11691                 return EXIT_SUCCESS; /* bash does this */
11692
11693         /* Careful: we can end up here after [v]fork. Do not restore
11694          * tty pgrp then, only top-level shell process does that */
11695         if (G_saved_tty_pgrp && getpid() == G.root_pid)
11696                 tcsetpgrp(G_interactive_fd, G_saved_tty_pgrp);
11697
11698         /* Saved-redirect fds, script fds and G_interactive_fd are still
11699          * open here. However, they are all CLOEXEC, and execv below
11700          * closes them. Try interactive "exec ls -l /proc/self/fd",
11701          * it should show no extra open fds in the "ls" process.
11702          * If we'd try to run builtins/NOEXECs, this would need improving.
11703          */
11704         //close_saved_fds_and_FILE_fds();
11705
11706         /* TODO: if exec fails, bash does NOT exit! We do.
11707          * We'll need to undo trap cleanup (it's inside execvp_or_die)
11708          * and tcsetpgrp, and this is inherently racy.
11709          */
11710         execvp_or_die(argv);
11711 }
11712
11713 static int FAST_FUNC builtin_exit(char **argv)
11714 {
11715         debug_printf_exec("%s()\n", __func__);
11716
11717         /* interactive bash:
11718          * # trap "echo EEE" EXIT
11719          * # exit
11720          * exit
11721          * There are stopped jobs.
11722          * (if there are _stopped_ jobs, running ones don't count)
11723          * # exit
11724          * exit
11725          * EEE (then bash exits)
11726          *
11727          * TODO: we can use G.exiting = -1 as indicator "last cmd was exit"
11728          */
11729
11730         /* note: EXIT trap is run by hush_exit */
11731         argv = skip_dash_dash(argv);
11732         if (argv[0] == NULL) {
11733 #if ENABLE_HUSH_TRAP
11734                 if (G.pre_trap_exitcode >= 0) /* "exit" in trap uses $? from before the trap */
11735                         hush_exit(G.pre_trap_exitcode);
11736 #endif
11737                 hush_exit(G.last_exitcode);
11738         }
11739         /* mimic bash: exit 123abc == exit 255 + error msg */
11740         xfunc_error_retval = 255;
11741         /* bash: exit -2 == exit 254, no error msg */
11742         hush_exit(xatoi(argv[0]) & 0xff);
11743 }
11744
11745 #if ENABLE_HUSH_TYPE
11746 /* http://www.opengroup.org/onlinepubs/9699919799/utilities/type.html */
11747 static int FAST_FUNC builtin_type(char **argv)
11748 {
11749         int ret = EXIT_SUCCESS;
11750
11751         while (*++argv) {
11752                 const char *type;
11753                 char *path = NULL;
11754
11755                 if (0) {} /* make conditional compile easier below */
11756                 /*else if (find_alias(*argv))
11757                         type = "an alias";*/
11758 # if ENABLE_HUSH_FUNCTIONS
11759                 else if (find_function(*argv))
11760                         type = "a function";
11761 # endif
11762                 else if (find_builtin(*argv))
11763                         type = "a shell builtin";
11764                 else if ((path = find_in_path(*argv)) != NULL)
11765                         type = path;
11766                 else {
11767                         bb_error_msg("type: %s: not found", *argv);
11768                         ret = EXIT_FAILURE;
11769                         continue;
11770                 }
11771
11772                 printf("%s is %s\n", *argv, type);
11773                 free(path);
11774         }
11775
11776         return ret;
11777 }
11778 #endif
11779
11780 #if ENABLE_HUSH_READ
11781 /* Interruptibility of read builtin in bash
11782  * (tested on bash-4.2.8 by sending signals (not by ^C)):
11783  *
11784  * Empty trap makes read ignore corresponding signal, for any signal.
11785  *
11786  * SIGINT:
11787  * - terminates non-interactive shell;
11788  * - interrupts read in interactive shell;
11789  * if it has non-empty trap:
11790  * - executes trap and returns to command prompt in interactive shell;
11791  * - executes trap and returns to read in non-interactive shell;
11792  * SIGTERM:
11793  * - is ignored (does not interrupt) read in interactive shell;
11794  * - terminates non-interactive shell;
11795  * if it has non-empty trap:
11796  * - executes trap and returns to read;
11797  * SIGHUP:
11798  * - terminates shell (regardless of interactivity);
11799  * if it has non-empty trap:
11800  * - executes trap and returns to read;
11801  * SIGCHLD from children:
11802  * - does not interrupt read regardless of interactivity:
11803  *   try: sleep 1 & read x; echo $x
11804  */
11805 static int FAST_FUNC builtin_read(char **argv)
11806 {
11807         const char *r;
11808         struct builtin_read_params params;
11809
11810         memset(&params, 0, sizeof(params));
11811
11812         /* "!": do not abort on errors.
11813          * Option string must start with "sr" to match BUILTIN_READ_xxx
11814          */
11815         params.read_flags = getopt32(argv,
11816 # if BASH_READ_D
11817                 IF_NOT_HUSH_BASH_COMPAT("^")
11818                 "!srn:p:t:u:d:" IF_NOT_HUSH_BASH_COMPAT("\0" "-1"/*min 1 arg*/),
11819                 &params.opt_n, &params.opt_p, &params.opt_t, &params.opt_u, &params.opt_d
11820 # else
11821                 IF_NOT_HUSH_BASH_COMPAT("^")
11822                 "!srn:p:t:u:" IF_NOT_HUSH_BASH_COMPAT("\0" "-1"/*min 1 arg*/),
11823                 &params.opt_n, &params.opt_p, &params.opt_t, &params.opt_u
11824 # endif
11825 //TODO: print "read: need variable name"
11826 //for the case of !BASH "read" with no args (now it fails silently)
11827 //(or maybe extend getopt32() to emit a message if "-1" fails)
11828         );
11829         if ((uint32_t)params.read_flags == (uint32_t)-1)
11830                 return EXIT_FAILURE;
11831         argv += optind;
11832         params.argv = argv;
11833         params.setvar = set_local_var_from_halves;
11834         params.ifs = get_local_var_value("IFS"); /* can be NULL */
11835
11836  again:
11837         r = shell_builtin_read(&params);
11838
11839         if ((uintptr_t)r == 1 && errno == EINTR) {
11840                 unsigned sig = check_and_run_traps();
11841                 if (sig != SIGINT)
11842                         goto again;
11843         }
11844
11845         if ((uintptr_t)r > 1) {
11846                 bb_simple_error_msg(r);
11847                 r = (char*)(uintptr_t)1;
11848         }
11849
11850         return (uintptr_t)r;
11851 }
11852 #endif
11853
11854 #if ENABLE_HUSH_UMASK
11855 static int FAST_FUNC builtin_umask(char **argv)
11856 {
11857         int rc;
11858         mode_t mask;
11859
11860         rc = 1;
11861         mask = umask(0);
11862         argv = skip_dash_dash(argv);
11863         if (argv[0]) {
11864                 mode_t old_mask = mask;
11865
11866                 /* numeric umasks are taken as-is */
11867                 /* symbolic umasks are inverted: "umask a=rx" calls umask(222) */
11868                 if (!isdigit(argv[0][0]))
11869                         mask ^= 0777;
11870                 mask = bb_parse_mode(argv[0], mask);
11871                 if (!isdigit(argv[0][0]))
11872                         mask ^= 0777;
11873                 if ((unsigned)mask > 0777) {
11874                         mask = old_mask;
11875                         /* bash messages:
11876                          * bash: umask: 'q': invalid symbolic mode operator
11877                          * bash: umask: 999: octal number out of range
11878                          */
11879                         bb_error_msg("%s: invalid mode '%s'", "umask", argv[0]);
11880                         rc = 0;
11881                 }
11882         } else {
11883                 /* Mimic bash */
11884                 printf("%04o\n", (unsigned) mask);
11885                 /* fall through and restore mask which we set to 0 */
11886         }
11887         umask(mask);
11888
11889         return !rc; /* rc != 0 - success */
11890 }
11891 #endif
11892
11893 #if ENABLE_HUSH_EXPORT || ENABLE_HUSH_READONLY || ENABLE_HUSH_SET || ENABLE_HUSH_TRAP
11894 static void print_escaped(const char *s)
11895 {
11896 //TODO? bash "set" does not quote variables which contain only alnums and "%+,-./:=@_~",
11897 // (but "export" quotes all variables, even with only these chars).
11898 // I think quoting strings with %+,=~ looks better
11899 // (example: "set" printing var== instead of var='=' looks strange)
11900 // IOW: do not quote "-./:@_": / is used in pathnames, : in PATH, -._ often in file names, @ in emails
11901
11902         if (*s == '\'')
11903                 goto squote;
11904         do {
11905                 const char *p = strchrnul(s, '\'');
11906                 /* print 'xxxx', possibly just '' */
11907                 printf("'%.*s'", (int)(p - s), s);
11908                 if (*p == '\0')
11909                         break;
11910                 s = p;
11911  squote:
11912                 /* s points to '; print "'''...'''" */
11913                 putchar('"');
11914                 do putchar('\''); while (*++s == '\'');
11915                 putchar('"');
11916         } while (*s);
11917 }
11918 #endif
11919
11920 #if ENABLE_HUSH_EXPORT || ENABLE_HUSH_LOCAL || ENABLE_HUSH_READONLY
11921 static int helper_export_local(char **argv, unsigned flags)
11922 {
11923         do {
11924                 char *name = *argv;
11925                 const char *name_end = endofname(name);
11926
11927                 if (*name_end == '\0') {
11928                         struct variable *var, **vpp;
11929
11930                         vpp = get_ptr_to_local_var(name);
11931                         var = vpp ? *vpp : NULL;
11932
11933                         if (flags & SETFLAG_UNEXPORT) {
11934                                 /* export -n NAME (without =VALUE) */
11935                                 if (var) {
11936                                         var->flg_export = 0;
11937                                         debug_printf_env("%s: unsetenv '%s'\n", __func__, name);
11938                                         unsetenv(name);
11939                                 } /* else: export -n NOT_EXISTING_VAR: no-op */
11940                                 continue;
11941                         }
11942                         if (flags & SETFLAG_EXPORT) {
11943                                 /* export NAME (without =VALUE) */
11944                                 if (var) {
11945                                         var->flg_export = 1;
11946                                         debug_printf_env("%s: putenv '%s'\n", __func__, var->varstr);
11947                                         putenv(var->varstr);
11948                                         continue;
11949                                 }
11950                         }
11951                         if (flags & SETFLAG_MAKE_RO) {
11952                                 /* readonly NAME (without =VALUE) */
11953                                 if (var) {
11954                                         var->flg_read_only = 1;
11955                                         continue;
11956                                 }
11957                         }
11958 # if ENABLE_HUSH_LOCAL
11959                         /* Is this "local" bltin? */
11960                         if (!(flags & (SETFLAG_EXPORT|SETFLAG_UNEXPORT|SETFLAG_MAKE_RO))) {
11961                                 unsigned lvl = flags >> SETFLAG_VARLVL_SHIFT;
11962                                 if (var && var->var_nest_level == lvl) {
11963                                         /* "local x=abc; ...; local x" - ignore second local decl */
11964                                         continue;
11965                                 }
11966                         }
11967 # endif
11968                         /* Exporting non-existing variable.
11969                          * bash does not put it in environment,
11970                          * but remembers that it is exported,
11971                          * and does put it in env when it is set later.
11972                          * We just set it to "" and export.
11973                          */
11974                         /* Or, it's "local NAME" (without =VALUE).
11975                          * bash sets the value to "".
11976                          */
11977                         /* Or, it's "readonly NAME" (without =VALUE).
11978                          * bash remembers NAME and disallows its creation
11979                          * in the future.
11980                          */
11981                         name = xasprintf("%s=", name);
11982                 } else {
11983                         if (*name_end != '=') {
11984                                 bb_error_msg("'%s': bad variable name", name);
11985                                 /* do not parse following argv[]s: */
11986                                 return 1;
11987                         }
11988                         /* (Un)exporting/making local NAME=VALUE */
11989                         name = xstrdup(name);
11990                         /* Testcase: export PS1='\w \$ ' */
11991                         unbackslash(name);
11992                 }
11993                 debug_printf_env("%s: set_local_var('%s')\n", __func__, name);
11994                 if (set_local_var(name, flags))
11995                         return EXIT_FAILURE;
11996         } while (*++argv);
11997         return EXIT_SUCCESS;
11998 }
11999 #endif
12000
12001 #if ENABLE_HUSH_EXPORT
12002 static int FAST_FUNC builtin_export(char **argv)
12003 {
12004         unsigned opt_unexport;
12005
12006 # if ENABLE_HUSH_EXPORT_N
12007         /* "!": do not abort on errors */
12008         opt_unexport = getopt32(argv, "!n");
12009         if (opt_unexport == (uint32_t)-1)
12010                 return EXIT_FAILURE;
12011         argv += optind;
12012 # else
12013         opt_unexport = 0;
12014         argv++;
12015 # endif
12016
12017         if (argv[0] == NULL) {
12018                 char **e = environ;
12019                 if (e) {
12020                         while (*e) {
12021 # if 0
12022                                 puts(*e++);
12023 # else
12024                                 /* ash emits: export VAR='VAL'
12025                                  * bash: declare -x VAR="VAL"
12026                                  * we follow ash example */
12027                                 const char *s = *e++;
12028                                 const char *p = strchr(s, '=');
12029
12030                                 if (!p) /* wtf? take next variable */
12031                                         continue;
12032                                 /* "export VAR=" */
12033                                 printf("%s %.*s", "export", (int)(p - s) + 1, s);
12034                                 print_escaped(p + 1);
12035                                 putchar('\n');
12036 # endif
12037                         }
12038                         /*fflush_all(); - done after each builtin anyway */
12039                 }
12040                 return EXIT_SUCCESS;
12041         }
12042
12043         return helper_export_local(argv, opt_unexport ? SETFLAG_UNEXPORT : SETFLAG_EXPORT);
12044 }
12045 #endif
12046
12047 #if ENABLE_HUSH_LOCAL
12048 static int FAST_FUNC builtin_local(char **argv)
12049 {
12050         if (G.func_nest_level == 0) {
12051                 bb_error_msg("%s: not in a function", argv[0]);
12052                 return EXIT_FAILURE; /* bash compat */
12053         }
12054 //TODO? ash and bash support "local -" special form,
12055 //which saves/restores $- around function call (including async returns, such as ^C)
12056 //(IOW: it makes "set +/-..." effects local)
12057         argv++;
12058         /* Since all builtins run in a nested variable level,
12059          * need to use level - 1 here. Or else the variable will be removed at once
12060          * after builtin returns.
12061          */
12062         return helper_export_local(argv, (G.var_nest_level - 1) << SETFLAG_VARLVL_SHIFT);
12063 }
12064 #endif
12065
12066 #if ENABLE_HUSH_READONLY
12067 static int FAST_FUNC builtin_readonly(char **argv)
12068 {
12069         argv++;
12070         if (*argv == NULL) {
12071                 /* bash: readonly [-p]: list all readonly VARs
12072                  * (-p has no effect in bash)
12073                  */
12074                 struct variable *e;
12075                 for (e = G.top_var; e; e = e->next) {
12076                         if (e->flg_read_only) {
12077                                 const char *s = e->varstr;
12078                                 const char *p = strchr(s, '=');
12079
12080                                 if (!p) /* wtf? take next variable */
12081                                         continue;
12082                                 /* "readonly VAR=" */
12083                                 printf("%s %.*s", "readonly", (int)(p - s) + 1, s);
12084                                 print_escaped(p + 1);
12085                                 putchar('\n');
12086                         }
12087                 }
12088                 return EXIT_SUCCESS;
12089         }
12090         return helper_export_local(argv, SETFLAG_MAKE_RO);
12091 }
12092 #endif
12093
12094 #if ENABLE_HUSH_UNSET
12095 /* http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#unset */
12096 static int FAST_FUNC builtin_unset(char **argv)
12097 {
12098         int ret;
12099         unsigned opts;
12100
12101         /* "!": do not abort on errors */
12102         /* "+": stop at 1st non-option */
12103         opts = getopt32(argv, "!+vf");
12104         if (opts == (unsigned)-1)
12105                 return EXIT_FAILURE;
12106         if (opts == 3) {
12107                 bb_simple_error_msg("unset: -v and -f are exclusive");
12108                 return EXIT_FAILURE;
12109         }
12110         argv += optind;
12111
12112         ret = EXIT_SUCCESS;
12113         while (*argv) {
12114                 if (!(opts & 2)) { /* not -f */
12115                         if (unset_local_var(*argv)) {
12116                                 /* unset <nonexistent_var> doesn't fail.
12117                                  * Error is when one tries to unset RO var.
12118                                  * Message was printed by unset_local_var. */
12119                                 ret = EXIT_FAILURE;
12120                         }
12121                 }
12122 # if ENABLE_HUSH_FUNCTIONS
12123                 else {
12124                         unset_func(*argv);
12125                 }
12126 # endif
12127                 argv++;
12128         }
12129         return ret;
12130 }
12131 #endif
12132
12133 #if ENABLE_HUSH_SET
12134 /* http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#set
12135  * built-in 'set' handler
12136  * SUSv3 says:
12137  * set [-abCefhmnuvx] [-o option] [argument...]
12138  * set [+abCefhmnuvx] [+o option] [argument...]
12139  * set -- [argument...]
12140  * set -o
12141  * set +o
12142  * Implementations shall support the options in both their hyphen and
12143  * plus-sign forms. These options can also be specified as options to sh.
12144  * Examples:
12145  * Write out all variables and their values: set
12146  * Set $1, $2, and $3 and set "$#" to 3: set c a b
12147  * Turn on the -x and -v options: set -xv
12148  * Unset all positional parameters: set --
12149  * Set $1 to the value of x, even if it begins with '-' or '+': set -- "$x"
12150  * Set the positional parameters to the expansion of x, even if x expands
12151  * with a leading '-' or '+': set -- $x
12152  *
12153  * So far, we only support "set -- [argument...]" and some of the short names.
12154  */
12155 static int FAST_FUNC builtin_set(char **argv)
12156 {
12157         int n;
12158         char **pp, **g_argv;
12159         char *arg = *++argv;
12160
12161         if (arg == NULL) {
12162                 struct variable *e;
12163                 for (e = G.top_var; e; e = e->next) {
12164                         const char *s = e->varstr;
12165                         const char *p = strchr(s, '=');
12166
12167                         if (!p) /* wtf? take next variable */
12168                                 continue;
12169                         /* var= */
12170                         printf("%.*s", (int)(p - s) + 1, s);
12171                         print_escaped(p + 1);
12172                         putchar('\n');
12173                 }
12174                 return EXIT_SUCCESS;
12175         }
12176
12177         do {
12178                 if (strcmp(arg, "--") == 0) {
12179                         ++argv;
12180                         goto set_argv;
12181                 }
12182                 if (arg[0] != '+' && arg[0] != '-')
12183                         break;
12184                 for (n = 1; arg[n]; ++n) {
12185                         if (set_mode((arg[0] == '-'), arg[n], argv[1])) {
12186                                 bb_error_msg("%s: %s: invalid option", "set", arg);
12187                                 return EXIT_FAILURE;
12188                         }
12189                         if (arg[n] == 'o' && argv[1])
12190                                 argv++;
12191                 }
12192         } while ((arg = *++argv) != NULL);
12193         /* Now argv[0] is 1st argument */
12194
12195         if (arg == NULL)
12196                 return EXIT_SUCCESS;
12197  set_argv:
12198
12199         /* NB: G.global_argv[0] ($0) is never freed/changed */
12200         g_argv = G.global_argv;
12201         if (G.global_args_malloced) {
12202                 pp = g_argv;
12203                 while (*++pp)
12204                         free(*pp);
12205                 g_argv[1] = NULL;
12206         } else {
12207                 G.global_args_malloced = 1;
12208                 pp = xzalloc(sizeof(pp[0]) * 2);
12209                 pp[0] = g_argv[0]; /* retain $0 */
12210                 g_argv = pp;
12211         }
12212         /* This realloc's G.global_argv */
12213         G.global_argv = pp = add_strings_to_strings(g_argv, argv, /*dup:*/ 1);
12214
12215         G.global_argc = 1 + string_array_len(pp + 1);
12216
12217         return EXIT_SUCCESS;
12218 }
12219 #endif
12220
12221 static int FAST_FUNC builtin_shift(char **argv)
12222 {
12223         int n = 1;
12224         argv = skip_dash_dash(argv);
12225         if (argv[0]) {
12226                 n = bb_strtou(argv[0], NULL, 10);
12227                 if (errno || n < 0) {
12228                         /* shared string with ash.c */
12229                         bb_error_msg("Illegal number: %s", argv[0]);
12230                         /*
12231                          * ash aborts in this case.
12232                          * bash prints error message and set $? to 1.
12233                          * Interestingly, for "shift 99999" bash does not
12234                          * print error message, but does set $? to 1
12235                          * (and does no shifting at all).
12236                          */
12237                 }
12238         }
12239         if (n >= 0 && n < G.global_argc) {
12240                 if (G_global_args_malloced) {
12241                         int m = 1;
12242                         while (m <= n)
12243                                 free(G.global_argv[m++]);
12244                 }
12245                 G.global_argc -= n;
12246                 memmove(&G.global_argv[1], &G.global_argv[n+1],
12247                                 G.global_argc * sizeof(G.global_argv[0]));
12248                 return EXIT_SUCCESS;
12249         }
12250         return EXIT_FAILURE;
12251 }
12252
12253 #if ENABLE_HUSH_GETOPTS
12254 static int FAST_FUNC builtin_getopts(char **argv)
12255 {
12256 /* http://pubs.opengroup.org/onlinepubs/9699919799/utilities/getopts.html
12257
12258 TODO:
12259 If a required argument is not found, and getopts is not silent,
12260 a question mark (?) is placed in VAR, OPTARG is unset, and a
12261 diagnostic message is printed.  If getopts is silent, then a
12262 colon (:) is placed in VAR and OPTARG is set to the option
12263 character found.
12264
12265 Test that VAR is a valid variable name?
12266
12267 "Whenever the shell is invoked, OPTIND shall be initialized to 1"
12268 */
12269         char cbuf[2];
12270         const char *cp, *optstring, *var;
12271         int c, n, exitcode, my_opterr;
12272         unsigned count;
12273
12274         optstring = *++argv;
12275         if (!optstring || !(var = *++argv)) {
12276                 bb_simple_error_msg("usage: getopts OPTSTRING VAR [ARGS]");
12277                 return EXIT_FAILURE;
12278         }
12279
12280         if (argv[1])
12281                 argv[0] = G.global_argv[0]; /* for error messages in getopt() */
12282         else
12283                 argv = G.global_argv;
12284         cbuf[1] = '\0';
12285
12286         my_opterr = 0;
12287         if (optstring[0] != ':') {
12288                 cp = get_local_var_value("OPTERR");
12289                 /* 0 if "OPTERR=0", 1 otherwise */
12290                 my_opterr = (!cp || NOT_LONE_CHAR(cp, '0'));
12291         }
12292
12293         /* getopts stops on first non-option. Add "+" to force that */
12294         /*if (optstring[0] != '+')*/ {
12295                 char *s = alloca(strlen(optstring) + 2);
12296                 sprintf(s, "+%s", optstring);
12297                 optstring = s;
12298         }
12299
12300         /* Naively, now we should just
12301          *      cp = get_local_var_value("OPTIND");
12302          *      optind = cp ? atoi(cp) : 0;
12303          *      optarg = NULL;
12304          *      opterr = my_opterr;
12305          *      c = getopt(string_array_len(argv), argv, optstring);
12306          * and be done? Not so fast...
12307          * Unlike normal getopt() usage in C programs, here
12308          * each successive call will (usually) have the same argv[] CONTENTS,
12309          * but not the ADDRESSES. Worse yet, it's possible that between
12310          * invocations of "getopts", there will be calls to shell builtins
12311          * which use getopt() internally. Example:
12312          *      while getopts "abc" RES -a -bc -abc de; do
12313          *              unset -ff func
12314          *      done
12315          * This would not work correctly: getopt() call inside "unset"
12316          * modifies internal libc state which is tracking position in
12317          * multi-option strings ("-abc"). At best, it can skip options
12318          * or return the same option infinitely. With glibc implementation
12319          * of getopt(), it would use outright invalid pointers and return
12320          * garbage even _without_ "unset" mangling internal state.
12321          *
12322          * We resort to resetting getopt() state and calling it N times,
12323          * until we get Nth result (or failure).
12324          * (N == G.getopt_count is reset to 0 whenever OPTIND is [un]set).
12325          */
12326         GETOPT_RESET();
12327         count = 0;
12328         n = string_array_len(argv);
12329         do {
12330                 optarg = NULL;
12331                 opterr = (count < G.getopt_count) ? 0 : my_opterr;
12332                 c = getopt(n, argv, optstring);
12333                 if (c < 0)
12334                         break;
12335                 count++;
12336         } while (count <= G.getopt_count);
12337
12338         /* Set OPTIND. Prevent resetting of the magic counter! */
12339         set_local_var_from_halves("OPTIND", utoa(optind));
12340         G.getopt_count = count; /* "next time, give me N+1'th result" */
12341         GETOPT_RESET(); /* just in case */
12342
12343         /* Set OPTARG */
12344         /* Always set or unset, never left as-is, even on exit/error:
12345          * "If no option was found, or if the option that was found
12346          * does not have an option-argument, OPTARG shall be unset."
12347          */
12348         cp = optarg;
12349         if (c == '?') {
12350                 /* If ":optstring" and unknown option is seen,
12351                  * it is stored to OPTARG.
12352                  */
12353                 if (optstring[1] == ':') {
12354                         cbuf[0] = optopt;
12355                         cp = cbuf;
12356                 }
12357         }
12358         if (cp)
12359                 set_local_var_from_halves("OPTARG", cp);
12360         else
12361                 unset_local_var("OPTARG");
12362
12363         /* Convert -1 to "?" */
12364         exitcode = EXIT_SUCCESS;
12365         if (c < 0) { /* -1: end of options */
12366                 exitcode = EXIT_FAILURE;
12367                 c = '?';
12368         }
12369
12370         /* Set VAR */
12371         cbuf[0] = c;
12372         set_local_var_from_halves(var, cbuf);
12373
12374         return exitcode;
12375 }
12376 #endif
12377
12378 static int FAST_FUNC builtin_source(char **argv)
12379 {
12380         char *arg_path, *filename;
12381         HFILE *input;
12382         save_arg_t sv;
12383         char *args_need_save;
12384 #if ENABLE_HUSH_FUNCTIONS
12385         smallint sv_flg;
12386 #endif
12387
12388         argv = skip_dash_dash(argv);
12389         filename = argv[0];
12390         if (!filename) {
12391                 /* bash says: "bash: .: filename argument required" */
12392                 return 2; /* bash compat */
12393         }
12394         arg_path = NULL;
12395         if (!strchr(filename, '/')) {
12396                 arg_path = find_in_path(filename);
12397                 if (arg_path)
12398                         filename = arg_path;
12399                 else if (!ENABLE_HUSH_BASH_SOURCE_CURDIR) {
12400                         errno = ENOENT;
12401                         bb_simple_perror_msg(filename);
12402                         return EXIT_FAILURE;
12403                 }
12404         }
12405         input = hfopen(filename);
12406         free(arg_path);
12407         if (!input) {
12408                 bb_perror_msg("%s", filename);
12409                 /* POSIX: non-interactive shell should abort here,
12410                  * not merely fail. So far no one complained :)
12411                  */
12412                 return EXIT_FAILURE;
12413         }
12414
12415 #if ENABLE_HUSH_FUNCTIONS
12416         sv_flg = G_flag_return_in_progress;
12417         /* "we are inside sourced file, ok to use return" */
12418         G_flag_return_in_progress = -1;
12419 #endif
12420         args_need_save = argv[1]; /* used as a boolean variable */
12421         if (args_need_save)
12422                 save_and_replace_G_args(&sv, argv);
12423
12424         /* "false; . ./empty_line; echo Zero:$?" should print 0 */
12425         G.last_exitcode = 0;
12426         parse_and_run_file(input);
12427         hfclose(input);
12428
12429         if (args_need_save) /* can't use argv[1] instead: "shift" can mangle it */
12430                 restore_G_args(&sv, argv);
12431 #if ENABLE_HUSH_FUNCTIONS
12432         G_flag_return_in_progress = sv_flg;
12433 #endif
12434
12435         return G.last_exitcode;
12436 }
12437
12438 #if ENABLE_HUSH_TRAP
12439 static int FAST_FUNC builtin_trap(char **argv)
12440 {
12441         int sig;
12442         char *new_cmd;
12443
12444         if (!G_traps)
12445                 G_traps = xzalloc(sizeof(G_traps[0]) * NSIG);
12446
12447         argv++;
12448         if (!*argv) {
12449                 int i;
12450                 /* No args: print all trapped */
12451                 for (i = 0; i < NSIG; ++i) {
12452                         if (G_traps[i]) {
12453                                 printf("trap -- ");
12454                                 print_escaped(G_traps[i]);
12455                                 /* note: bash adds "SIG", but only if invoked
12456                                  * as "bash". If called as "sh", or if set -o posix,
12457                                  * then it prints short signal names.
12458                                  * We are printing short names: */
12459                                 printf(" %s\n", get_signame(i));
12460                         }
12461                 }
12462                 /*fflush_all(); - done after each builtin anyway */
12463                 return EXIT_SUCCESS;
12464         }
12465
12466         new_cmd = NULL;
12467         /* If first arg is a number: reset all specified signals */
12468         sig = bb_strtou(*argv, NULL, 10);
12469         if (errno == 0) {
12470                 int ret;
12471  process_sig_list:
12472                 ret = EXIT_SUCCESS;
12473                 while (*argv) {
12474                         sighandler_t handler;
12475
12476                         sig = get_signum(*argv++);
12477                         if (sig < 0) {
12478                                 ret = EXIT_FAILURE;
12479                                 /* Mimic bash message exactly */
12480                                 bb_error_msg("trap: %s: invalid signal specification", argv[-1]);
12481                                 continue;
12482                         }
12483
12484                         free(G_traps[sig]);
12485                         G_traps[sig] = xstrdup(new_cmd);
12486
12487                         debug_printf("trap: setting SIG%s (%i) to '%s'\n",
12488                                 get_signame(sig), sig, G_traps[sig]);
12489
12490                         /* There is no signal for 0 (EXIT) */
12491                         if (sig == 0)
12492                                 continue;
12493
12494                         if (new_cmd)
12495                                 handler = (new_cmd[0] ? record_pending_signo : SIG_IGN);
12496                         else
12497                                 /* We are removing trap handler */
12498                                 handler = pick_sighandler(sig);
12499                         install_sighandler(sig, handler);
12500                 }
12501                 return ret;
12502         }
12503
12504         if (!argv[1]) { /* no second arg */
12505                 bb_simple_error_msg("trap: invalid arguments");
12506                 return EXIT_FAILURE;
12507         }
12508
12509         /* First arg is "-": reset all specified to default */
12510         /* First arg is "--": skip it, the rest is "handler SIGs..." */
12511         /* Everything else: set arg as signal handler
12512          * (includes "" case, which ignores signal) */
12513         if (argv[0][0] == '-') {
12514                 if (argv[0][1] == '\0') { /* "-" */
12515                         /* new_cmd remains NULL: "reset these sigs" */
12516                         goto reset_traps;
12517                 }
12518                 if (argv[0][1] == '-' && argv[0][2] == '\0') { /* "--" */
12519                         argv++;
12520                 }
12521                 /* else: "-something", no special meaning */
12522         }
12523         new_cmd = *argv;
12524  reset_traps:
12525         argv++;
12526         goto process_sig_list;
12527 }
12528 #endif
12529
12530 #if ENABLE_HUSH_JOB
12531 static struct pipe *parse_jobspec(const char *str)
12532 {
12533         struct pipe *pi;
12534         unsigned jobnum;
12535
12536         if (sscanf(str, "%%%u", &jobnum) != 1) {
12537                 if (str[0] != '%'
12538                  || (str[1] != '%' && str[1] != '+' && str[1] != '\0')
12539                 ) {
12540                         bb_error_msg("bad argument '%s'", str);
12541                         return NULL;
12542                 }
12543                 /* It is "%%", "%+" or "%" - current job */
12544                 jobnum = G.last_jobid;
12545                 if (jobnum == 0) {
12546                         bb_simple_error_msg("no current job");
12547                         return NULL;
12548                 }
12549         }
12550         for (pi = G.job_list; pi; pi = pi->next) {
12551                 if (pi->jobid == jobnum) {
12552                         return pi;
12553                 }
12554         }
12555         bb_error_msg("%u: no such job", jobnum);
12556         return NULL;
12557 }
12558
12559 static int FAST_FUNC builtin_jobs(char **argv UNUSED_PARAM)
12560 {
12561         struct pipe *job;
12562         const char *status_string;
12563
12564         checkjobs(NULL, 0 /*(no pid to wait for)*/);
12565         for (job = G.job_list; job; job = job->next) {
12566                 if (job->alive_cmds == job->stopped_cmds)
12567                         status_string = "Stopped";
12568                 else
12569                         status_string = "Running";
12570
12571                 printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->cmdtext);
12572         }
12573
12574         clean_up_last_dead_job();
12575
12576         return EXIT_SUCCESS;
12577 }
12578
12579 /* built-in 'fg' and 'bg' handler */
12580 static int FAST_FUNC builtin_fg_bg(char **argv)
12581 {
12582         int i;
12583         struct pipe *pi;
12584
12585         if (!G_interactive_fd)
12586                 return EXIT_FAILURE;
12587
12588         /* If they gave us no args, assume they want the last backgrounded task */
12589         if (!argv[1]) {
12590                 for (pi = G.job_list; pi; pi = pi->next) {
12591                         if (pi->jobid == G.last_jobid) {
12592                                 goto found;
12593                         }
12594                 }
12595                 bb_error_msg("%s: no current job", argv[0]);
12596                 return EXIT_FAILURE;
12597         }
12598
12599         pi = parse_jobspec(argv[1]);
12600         if (!pi)
12601                 return EXIT_FAILURE;
12602  found:
12603         /* TODO: bash prints a string representation
12604          * of job being foregrounded (like "sleep 1 | cat") */
12605         if (argv[0][0] == 'f' && G_saved_tty_pgrp) {
12606                 /* Put the job into the foreground. */
12607                 tcsetpgrp(G_interactive_fd, pi->pgrp);
12608         }
12609
12610         /* Restart the processes in the job */
12611         debug_printf_jobs("reviving %d procs, pgrp %d\n", pi->num_cmds, pi->pgrp);
12612         for (i = 0; i < pi->num_cmds; i++) {
12613                 debug_printf_jobs("reviving pid %d\n", pi->cmds[i].pid);
12614         }
12615         pi->stopped_cmds = 0;
12616
12617         i = kill(- pi->pgrp, SIGCONT);
12618         if (i < 0) {
12619                 if (errno == ESRCH) {
12620                         delete_finished_job(pi);
12621                         return EXIT_SUCCESS;
12622                 }
12623                 bb_simple_perror_msg("kill (SIGCONT)");
12624         }
12625
12626         if (argv[0][0] == 'f') {
12627                 remove_job_from_table(pi); /* FG job shouldn't be in job table */
12628                 return checkjobs_and_fg_shell(pi);
12629         }
12630         return EXIT_SUCCESS;
12631 }
12632 #endif
12633
12634 #if ENABLE_HUSH_KILL
12635 static int FAST_FUNC builtin_kill(char **argv)
12636 {
12637         int ret = 0;
12638
12639 # if ENABLE_HUSH_JOB
12640         if (argv[1] && strcmp(argv[1], "-l") != 0) {
12641                 int i = 1;
12642
12643                 do {
12644                         struct pipe *pi;
12645                         char *dst;
12646                         int j, n;
12647
12648                         if (argv[i][0] != '%')
12649                                 continue;
12650                         /*
12651                          * "kill %N" - job kill
12652                          * Converting to pgrp / pid kill
12653                          */
12654                         pi = parse_jobspec(argv[i]);
12655                         if (!pi) {
12656                                 /* Eat bad jobspec */
12657                                 j = i;
12658                                 do {
12659                                         j++;
12660                                         argv[j - 1] = argv[j];
12661                                 } while (argv[j]);
12662                                 ret = 1;
12663                                 i--;
12664                                 continue;
12665                         }
12666                         /*
12667                          * In jobs started under job control, we signal
12668                          * entire process group by kill -PGRP_ID.
12669                          * This happens, f.e., in interactive shell.
12670                          *
12671                          * Otherwise, we signal each child via
12672                          * kill PID1 PID2 PID3.
12673                          * Testcases:
12674                          * sh -c 'sleep 1|sleep 1 & kill %1'
12675                          * sh -c 'true|sleep 2 & sleep 1; kill %1'
12676                          * sh -c 'true|sleep 1 & sleep 2; kill %1'
12677                          */
12678                         n = G_interactive_fd ? 1 : pi->num_cmds;
12679                         dst = alloca(n * sizeof(int)*4);
12680                         argv[i] = dst;
12681                         if (G_interactive_fd)
12682                                 dst += sprintf(dst, " -%u", (int)pi->pgrp);
12683                         else for (j = 0; j < n; j++) {
12684                                 struct command *cmd = &pi->cmds[j];
12685                                 /* Skip exited members of the job */
12686                                 if (cmd->pid == 0)
12687                                         continue;
12688                                 /*
12689                                  * kill_main has matching code to expect
12690                                  * leading space. Needed to not confuse
12691                                  * negative pids with "kill -SIGNAL_NO" syntax
12692                                  */
12693                                 dst += sprintf(dst, " %u", (int)cmd->pid);
12694                         }
12695                         *dst = '\0';
12696                 } while (argv[++i]);
12697         }
12698 # endif
12699
12700         if (argv[1] || ret == 0) {
12701                 ret = run_applet_main(argv, kill_main);
12702         }
12703         /* else: ret = 1, "kill %bad_jobspec" case */
12704         return ret;
12705 }
12706 #endif
12707
12708 #if ENABLE_HUSH_WAIT
12709 /* http://www.opengroup.org/onlinepubs/9699919799/utilities/wait.html */
12710 # if !ENABLE_HUSH_JOB
12711 #  define wait_for_child_or_signal(pipe,pid) wait_for_child_or_signal(pid)
12712 # endif
12713 static int wait_for_child_or_signal(struct pipe *waitfor_pipe, pid_t waitfor_pid)
12714 {
12715         int ret = 0;
12716         for (;;) {
12717                 int sig;
12718                 sigset_t oldset;
12719
12720                 if (!sigisemptyset(&G.pending_set))
12721                         goto check_sig;
12722
12723                 /* waitpid is not interruptible by SA_RESTARTed
12724                  * signals which we use. Thus, this ugly dance:
12725                  */
12726
12727                 /* Make sure possible SIGCHLD is stored in kernel's
12728                  * pending signal mask before we call waitpid.
12729                  * Or else we may race with SIGCHLD, lose it,
12730                  * and get stuck in sigsuspend...
12731                  */
12732                 sigfillset(&oldset); /* block all signals, remember old set */
12733                 sigprocmask2(SIG_SETMASK, &oldset);
12734
12735                 if (!sigisemptyset(&G.pending_set)) {
12736                         /* Crap! we raced with some signal! */
12737                         goto restore;
12738                 }
12739
12740                 /*errno = 0; - checkjobs does this */
12741 /* Can't pass waitfor_pipe into checkjobs(): it won't be interruptible */
12742                 ret = checkjobs(NULL, waitfor_pid); /* waitpid(WNOHANG) inside */
12743                 debug_printf_exec("checkjobs:%d\n", ret);
12744 # if ENABLE_HUSH_JOB
12745                 if (waitfor_pipe) {
12746                         int rcode = job_exited_or_stopped(waitfor_pipe);
12747                         debug_printf_exec("job_exited_or_stopped:%d\n", rcode);
12748                         if (rcode >= 0) {
12749                                 ret = rcode;
12750                                 sigprocmask(SIG_SETMASK, &oldset, NULL);
12751                                 break;
12752                         }
12753                 }
12754 # endif
12755                 /* if ECHILD, there are no children (ret is -1 or 0) */
12756                 /* if ret == 0, no children changed state */
12757                 /* if ret != 0, it's exitcode+1 of exited waitfor_pid child */
12758                 if (errno == ECHILD || ret) {
12759                         ret--;
12760                         if (ret < 0) /* if ECHILD, may need to fix "ret" */
12761                                 ret = 0;
12762 # if ENABLE_HUSH_BASH_COMPAT
12763                         if (waitfor_pid == -1 && errno == ECHILD) {
12764                                 /* exitcode of "wait -n" with no children is 127, not 0 */
12765                                 ret = 127;
12766                         }
12767 # endif
12768                         sigprocmask(SIG_SETMASK, &oldset, NULL);
12769                         break;
12770                 }
12771                 /* Wait for SIGCHLD or any other signal */
12772                 /* It is vitally important for sigsuspend that SIGCHLD has non-DFL handler! */
12773                 /* Note: sigsuspend invokes signal handler */
12774                 sigsuspend(&oldset);
12775                 /* ^^^ add "sigdelset(&oldset, SIGCHLD)" before sigsuspend
12776                  * to make sure SIGCHLD is not masked off?
12777                  * It was reported that this:
12778                  *      fn() { : | return; }
12779                  *      shopt -s lastpipe
12780                  *      fn
12781                  *      exec hush SCRIPT
12782                  * under bash 4.4.23 runs SCRIPT with SIGCHLD masked,
12783                  * making "wait" commands in SCRIPT block forever.
12784                  */
12785  restore:
12786                 sigprocmask(SIG_SETMASK, &oldset, NULL);
12787  check_sig:
12788                 /* So, did we get a signal? */
12789                 sig = check_and_run_traps();
12790                 if (sig /*&& sig != SIGCHLD - always true */) {
12791                         /* Do this for any (non-ignored) signal, not only for ^C */
12792                         ret = 128 | sig;
12793                         break;
12794                 }
12795                 /* SIGCHLD, or no signal, or ignored one, such as SIGQUIT. Repeat */
12796         }
12797         return ret;
12798 }
12799
12800 static int FAST_FUNC builtin_wait(char **argv)
12801 {
12802         int ret;
12803         int status;
12804
12805         argv = skip_dash_dash(argv);
12806 # if ENABLE_HUSH_BASH_COMPAT
12807         if (argv[0] && strcmp(argv[0], "-n") == 0) {
12808                 /* wait -n */
12809                 /* (bash accepts "wait -n PID" too and ignores PID) */
12810                 G.dead_job_exitcode = -1;
12811                 return wait_for_child_or_signal(NULL, -1 /*no job, wait for one job*/);
12812         }
12813 # endif
12814         if (argv[0] == NULL) {
12815                 /* Don't care about wait results */
12816                 /* Note 1: must wait until there are no more children */
12817                 /* Note 2: must be interruptible */
12818                 /* Examples:
12819                  * $ sleep 3 & sleep 6 & wait
12820                  * [1] 30934 sleep 3
12821                  * [2] 30935 sleep 6
12822                  * [1] Done                   sleep 3
12823                  * [2] Done                   sleep 6
12824                  * $ sleep 3 & sleep 6 & wait
12825                  * [1] 30936 sleep 3
12826                  * [2] 30937 sleep 6
12827                  * [1] Done                   sleep 3
12828                  * ^C <-- after ~4 sec from keyboard
12829                  * $
12830                  */
12831                 return wait_for_child_or_signal(NULL, 0 /*no job and no pid to wait for*/);
12832         }
12833
12834         do {
12835                 pid_t pid = bb_strtou(*argv, NULL, 10);
12836                 if (errno || pid <= 0) {
12837 # if ENABLE_HUSH_JOB
12838                         if (argv[0][0] == '%') {
12839                                 struct pipe *wait_pipe;
12840                                 ret = 127; /* bash compat for bad jobspecs */
12841                                 wait_pipe = parse_jobspec(*argv);
12842                                 if (wait_pipe) {
12843                                         ret = job_exited_or_stopped(wait_pipe);
12844                                         if (ret < 0) {
12845                                                 ret = wait_for_child_or_signal(wait_pipe, 0);
12846                                         } else {
12847                                                 /* waiting on "last dead job" removes it */
12848                                                 clean_up_last_dead_job();
12849                                         }
12850                                 }
12851                                 /* else: parse_jobspec() already emitted error msg */
12852                                 continue;
12853                         }
12854 # endif
12855                         /* mimic bash message */
12856                         bb_error_msg("wait: '%s': not a pid or valid job spec", *argv);
12857                         ret = EXIT_FAILURE;
12858                         continue; /* bash checks all argv[] */
12859                 }
12860
12861                 /* Do we have such child? */
12862                 ret = waitpid(pid, &status, WNOHANG);
12863                 if (ret < 0) {
12864                         /* No */
12865                         ret = 127;
12866                         if (errno == ECHILD) {
12867                                 if (pid == G.last_bg_pid) {
12868                                         /* "wait $!" but last bg task has already exited. Try:
12869                                          * (sleep 1; exit 3) & sleep 2; echo $?; wait $!; echo $?
12870                                          * In bash it prints exitcode 0, then 3.
12871                                          * In dash, it is 127.
12872                                          */
12873                                         ret = G.last_bg_pid_exitcode;
12874                                 } else {
12875                                         /* Example: "wait 1". mimic bash message */
12876                                         bb_error_msg("wait: pid %u is not a child of this shell", (unsigned)pid);
12877                                 }
12878                         } else {
12879                                 /* ??? */
12880                                 bb_perror_msg("wait %s", *argv);
12881                         }
12882                         continue; /* bash checks all argv[] */
12883                 }
12884                 if (ret == 0) {
12885                         /* Yes, and it still runs */
12886                         ret = wait_for_child_or_signal(NULL, pid);
12887                 } else {
12888                         /* Yes, and it just exited */
12889                         process_wait_result(NULL, pid, status);
12890                         ret = WEXITSTATUS(status);
12891                         if (WIFSIGNALED(status))
12892                                 ret = 128 | WTERMSIG(status);
12893                 }
12894         } while (*++argv);
12895
12896         return ret;
12897 }
12898 #endif
12899
12900 #if ENABLE_HUSH_LOOPS || ENABLE_HUSH_FUNCTIONS
12901 static unsigned parse_numeric_argv1(char **argv, unsigned def, unsigned def_min)
12902 {
12903         if (argv[1]) {
12904                 def = bb_strtou(argv[1], NULL, 10);
12905                 if (errno || def < def_min || argv[2]) {
12906                         bb_error_msg("%s: bad arguments", argv[0]);
12907                         def = UINT_MAX;
12908                 }
12909         }
12910         return def;
12911 }
12912 #endif
12913
12914 #if ENABLE_HUSH_LOOPS
12915 static int FAST_FUNC builtin_break(char **argv)
12916 {
12917         unsigned depth;
12918         if (G.depth_of_loop == 0) {
12919                 bb_error_msg("%s: only meaningful in a loop", argv[0]);
12920                 /* if we came from builtin_continue(), need to undo "= 1" */
12921                 G.flag_break_continue = 0;
12922                 return EXIT_SUCCESS; /* bash compat */
12923         }
12924         G.flag_break_continue++; /* BC_BREAK = 1, or BC_CONTINUE = 2 */
12925
12926         G.depth_break_continue = depth = parse_numeric_argv1(argv, 1, 1);
12927         if (depth == UINT_MAX)
12928                 G.flag_break_continue = BC_BREAK;
12929         if (G.depth_of_loop < depth)
12930                 G.depth_break_continue = G.depth_of_loop;
12931
12932         return EXIT_SUCCESS;
12933 }
12934
12935 static int FAST_FUNC builtin_continue(char **argv)
12936 {
12937         G.flag_break_continue = 1; /* BC_CONTINUE = 2 = 1+1 */
12938         return builtin_break(argv);
12939 }
12940 #endif
12941
12942 #if ENABLE_HUSH_FUNCTIONS
12943 static int FAST_FUNC builtin_return(char **argv)
12944 {
12945         int rc;
12946
12947         if (G_flag_return_in_progress != -1) {
12948                 bb_error_msg("%s: not in a function or sourced script", argv[0]);
12949                 return EXIT_FAILURE; /* bash compat */
12950         }
12951
12952         G_flag_return_in_progress = 1;
12953
12954         /* bash:
12955          * out of range: wraps around at 256, does not error out
12956          * non-numeric param:
12957          * f() { false; return qwe; }; f; echo $?
12958          * bash: return: qwe: numeric argument required  <== we do this
12959          * 255  <== we also do this
12960          */
12961         rc = parse_numeric_argv1(argv, G.last_exitcode, 0);
12962 # if ENABLE_HUSH_TRAP
12963         if (argv[1]) { /* "return ARG" inside a running trap sets $? */
12964                 debug_printf_exec("G.return_exitcode=%d\n", rc);
12965                 G.return_exitcode = rc;
12966         }
12967 # endif
12968         return rc;
12969 }
12970 #endif
12971
12972 #if ENABLE_HUSH_TIMES
12973 static int FAST_FUNC builtin_times(char **argv UNUSED_PARAM)
12974 {
12975         static const uint8_t times_tbl[] ALIGN1 = {
12976                 ' ',  offsetof(struct tms, tms_utime),
12977                 '\n', offsetof(struct tms, tms_stime),
12978                 ' ',  offsetof(struct tms, tms_cutime),
12979                 '\n', offsetof(struct tms, tms_cstime),
12980                 0
12981         };
12982         const uint8_t *p;
12983         unsigned clk_tck;
12984         struct tms buf;
12985
12986         clk_tck = bb_clk_tck();
12987
12988         times(&buf);
12989         p = times_tbl;
12990         do {
12991                 unsigned sec, frac;
12992                 unsigned long t;
12993                 t = *(clock_t *)(((char *) &buf) + p[1]);
12994                 sec = t / clk_tck;
12995                 frac = t % clk_tck;
12996                 printf("%um%u.%03us%c",
12997                         sec / 60, sec % 60,
12998                         (frac * 1000) / clk_tck,
12999                         p[0]);
13000                 p += 2;
13001         } while (*p);
13002
13003         return EXIT_SUCCESS;
13004 }
13005 #endif
13006
13007 #if ENABLE_HUSH_MEMLEAK
13008 static int FAST_FUNC builtin_memleak(char **argv UNUSED_PARAM)
13009 {
13010         void *p;
13011         unsigned long l;
13012
13013 # ifdef M_TRIM_THRESHOLD
13014         /* Optional. Reduces probability of false positives */
13015         malloc_trim(0);
13016 # endif
13017         /* Crude attempt to find where "free memory" starts,
13018          * sans fragmentation. */
13019         p = malloc(240);
13020         l = (unsigned long)p;
13021         free(p);
13022         p = malloc(3400);
13023         if (l < (unsigned long)p) l = (unsigned long)p;
13024         free(p);
13025
13026 # if 0  /* debug */
13027         {
13028                 struct mallinfo mi = mallinfo();
13029                 printf("top alloc:0x%lx malloced:%d+%d=%d\n", l,
13030                         mi.arena, mi.hblkhd, mi.arena + mi.hblkhd);
13031         }
13032 # endif
13033
13034         if (!G.memleak_value)
13035                 G.memleak_value = l;
13036
13037         l -= G.memleak_value;
13038         if ((long)l < 0)
13039                 l = 0;
13040         l /= 1024;
13041         if (l > 127)
13042                 l = 127;
13043
13044         /* Exitcode is "how many kilobytes we leaked since 1st call" */
13045         return l;
13046 }
13047 #endif
13048 #endif /* !__U_BOOT__ */
This page took 0.792544 seconds and 4 git commands to generate.