ash: expand: Merge syntax/quotes in memtodest with flags
[oweals/busybox.git] / shell / ash.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * ash shell port for busybox
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Kenneth Almquist.
7  *
8  * Original BSD copyright notice is retained at the end of this file.
9  *
10  * Copyright (c) 1989, 1991, 1993, 1994
11  *      The Regents of the University of California.  All rights reserved.
12  *
13  * Copyright (c) 1997-2005 Herbert Xu <herbert@gondor.apana.org.au>
14  * was re-ported from NetBSD and debianized.
15  *
16  * Licensed under GPLv2 or later, see file LICENSE in this source tree.
17  */
18 //config:config ASH
19 //config:       bool "ash (78 kb)"
20 //config:       default y
21 //config:       depends on !NOMMU
22 //config:       help
23 //config:       The most complete and most pedantically correct shell included with
24 //config:       busybox. This shell is actually a derivative of the Debian 'dash'
25 //config:       shell (by Herbert Xu), which was created by porting the 'ash' shell
26 //config:       (written by Kenneth Almquist) from NetBSD.
27 //config:
28 //config:# ash options
29 //config:# note: Don't remove !NOMMU part in the next line; it would break
30 //config:# menuconfig's indenting.
31 //config:if !NOMMU && (ASH || SH_IS_ASH || BASH_IS_ASH)
32 //config:
33 //config:config ASH_OPTIMIZE_FOR_SIZE
34 //config:       bool "Optimize for size instead of speed"
35 //config:       default y
36 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
37 //config:
38 //config:config ASH_INTERNAL_GLOB
39 //config:       bool "Use internal glob() implementation"
40 //config:       default y       # Y is bigger, but because of uclibc glob() bug, let Y be default for now
41 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
42 //config:       help
43 //config:       Do not use glob() function from libc, use internal implementation.
44 //config:       Use this if you are getting "glob.h: No such file or directory"
45 //config:       or similar build errors.
46 //config:       Note that as of now (2017-01), uclibc and musl glob() both have bugs
47 //config:       which would break ash if you select N here.
48 //config:
49 //config:config ASH_BASH_COMPAT
50 //config:       bool "bash-compatible extensions"
51 //config:       default y
52 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
53 //config:
54 //config:config ASH_BASH_SOURCE_CURDIR
55 //config:       bool "'source' and '.' builtins search current directory after $PATH"
56 //config:       default n   # do not encourage non-standard behavior
57 //config:       depends on ASH_BASH_COMPAT
58 //config:       help
59 //config:       This is not compliant with standards. Avoid if possible.
60 //config:
61 //config:config ASH_BASH_NOT_FOUND_HOOK
62 //config:       bool "command_not_found_handle hook support"
63 //config:       default y
64 //config:       depends on ASH_BASH_COMPAT
65 //config:       help
66 //config:       Enable support for the 'command_not_found_handle' hook function,
67 //config:       from GNU bash, which allows for alternative command not found
68 //config:       handling.
69 //config:
70 //config:config ASH_JOB_CONTROL
71 //config:       bool "Job control"
72 //config:       default y
73 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
74 //config:
75 //config:config ASH_ALIAS
76 //config:       bool "Alias support"
77 //config:       default y
78 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
79 //config:
80 //config:config ASH_RANDOM_SUPPORT
81 //config:       bool "Pseudorandom generator and $RANDOM variable"
82 //config:       default y
83 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
84 //config:       help
85 //config:       Enable pseudorandom generator and dynamic variable "$RANDOM".
86 //config:       Each read of "$RANDOM" will generate a new pseudorandom value.
87 //config:       You can reset the generator by using a specified start value.
88 //config:       After "unset RANDOM" the generator will switch off and this
89 //config:       variable will no longer have special treatment.
90 //config:
91 //config:config ASH_EXPAND_PRMT
92 //config:       bool "Expand prompt string"
93 //config:       default y
94 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
95 //config:       help
96 //config:       $PS# may contain volatile content, such as backquote commands.
97 //config:       This option recreates the prompt string from the environment
98 //config:       variable each time it is displayed.
99 //config:
100 //config:config ASH_IDLE_TIMEOUT
101 //config:       bool "Idle timeout variable $TMOUT"
102 //config:       default y
103 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
104 //config:       help
105 //config:       Enable bash-like auto-logout after $TMOUT seconds of idle time.
106 //config:
107 //config:config ASH_MAIL
108 //config:       bool "Check for new mail in interactive shell"
109 //config:       default y
110 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
111 //config:       help
112 //config:       Enable "check for new mail" function:
113 //config:       if set, $MAIL file and $MAILPATH list of files
114 //config:       are checked for mtime changes, and "you have mail"
115 //config:       message is printed if change is detected.
116 //config:
117 //config:config ASH_ECHO
118 //config:       bool "echo builtin"
119 //config:       default y
120 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
121 //config:
122 //config:config ASH_PRINTF
123 //config:       bool "printf builtin"
124 //config:       default y
125 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
126 //config:
127 //config:config ASH_TEST
128 //config:       bool "test builtin"
129 //config:       default y
130 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
131 //config:
132 //config:config ASH_HELP
133 //config:       bool "help builtin"
134 //config:       default y
135 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
136 //config:
137 //config:config ASH_GETOPTS
138 //config:       bool "getopts builtin"
139 //config:       default y
140 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
141 //config:
142 //config:config ASH_CMDCMD
143 //config:       bool "command builtin"
144 //config:       default y
145 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
146 //config:       help
147 //config:       Enable support for the 'command' builtin, which allows
148 //config:       you to run the specified command or builtin,
149 //config:       even when there is a function with the same name.
150 //config:
151 //config:endif # ash options
152
153 //applet:IF_ASH(APPLET(ash, BB_DIR_BIN, BB_SUID_DROP))
154 //                      APPLET_ODDNAME:name  main location    suid_type     help
155 //applet:IF_SH_IS_ASH(  APPLET_ODDNAME(sh,   ash, BB_DIR_BIN, BB_SUID_DROP, ash))
156 //applet:IF_BASH_IS_ASH(APPLET_ODDNAME(bash, ash, BB_DIR_BIN, BB_SUID_DROP, ash))
157
158 //kbuild:lib-$(CONFIG_ASH) += ash.o ash_ptr_hack.o shell_common.o
159 //kbuild:lib-$(CONFIG_SH_IS_ASH) += ash.o ash_ptr_hack.o shell_common.o
160 //kbuild:lib-$(CONFIG_BASH_IS_ASH) += ash.o ash_ptr_hack.o shell_common.o
161 //kbuild:lib-$(CONFIG_ASH_RANDOM_SUPPORT) += random.o
162
163 /*
164  * DEBUG=1 to compile in debugging ('set -o debug' turns on)
165  * DEBUG=2 to compile in and turn on debugging.
166  * When debugging is on ("set -o debug" was executed, or DEBUG=2),
167  * debugging info is written to ./trace, quit signal generates core dump.
168  */
169 #define DEBUG 0
170 /* Tweak debug output verbosity here */
171 #define DEBUG_TIME 0
172 #define DEBUG_PID 1
173 #define DEBUG_SIG 1
174 #define DEBUG_INTONOFF 0
175
176 #define PROFILE 0
177
178 #define JOBS ENABLE_ASH_JOB_CONTROL
179
180 #include <fnmatch.h>
181 #include <sys/times.h>
182 #include <sys/utsname.h> /* for setting $HOSTNAME */
183 #include "busybox.h" /* for applet_names */
184 #if ENABLE_FEATURE_SH_EMBEDDED_SCRIPTS
185 # include "embedded_scripts.h"
186 #else
187 # define NUM_SCRIPTS 0
188 #endif
189
190 /* So far, all bash compat is controlled by one config option */
191 /* Separate defines document which part of code implements what */
192 /* function keyword */
193 #define    BASH_FUNCTION        ENABLE_ASH_BASH_COMPAT
194 #define IF_BASH_FUNCTION            IF_ASH_BASH_COMPAT
195 /* &>file */
196 #define    BASH_REDIR_OUTPUT    ENABLE_ASH_BASH_COMPAT
197 #define IF_BASH_REDIR_OUTPUT        IF_ASH_BASH_COMPAT
198 /* $'...' */
199 #define    BASH_DOLLAR_SQUOTE   ENABLE_ASH_BASH_COMPAT
200 #define IF_BASH_DOLLAR_SQUOTE       IF_ASH_BASH_COMPAT
201 #define    BASH_PATTERN_SUBST   ENABLE_ASH_BASH_COMPAT
202 #define IF_BASH_PATTERN_SUBST       IF_ASH_BASH_COMPAT
203 #define    BASH_SUBSTR          ENABLE_ASH_BASH_COMPAT
204 #define IF_BASH_SUBSTR              IF_ASH_BASH_COMPAT
205 /* BASH_TEST2: [[ EXPR ]]
206  * Status of [[ support:
207  * We replace && and || with -a and -o
208  * TODO:
209  * singleword+noglob expansion:
210  *   v='a b'; [[ $v = 'a b' ]]; echo 0:$?
211  *   [[ /bin/n* ]]; echo 0:$?
212  * -a/-o are not AND/OR ops! (they are just strings)
213  * quoting needs to be considered (-f is an operator, "-f" and ""-f are not; etc)
214  * = is glob match operator, not equality operator: STR = GLOB
215  * (in GLOB, quoting is significant on char-by-char basis: a*cd"*")
216  * == same as =
217  * add =~ regex match operator: STR =~ REGEX
218  */
219 #define    BASH_TEST2           (ENABLE_ASH_BASH_COMPAT * ENABLE_ASH_TEST)
220 #define    BASH_SOURCE          ENABLE_ASH_BASH_COMPAT
221 #define    BASH_PIPEFAIL        ENABLE_ASH_BASH_COMPAT
222 #define    BASH_HOSTNAME_VAR    ENABLE_ASH_BASH_COMPAT
223 #define    BASH_EPOCH_VARS      ENABLE_ASH_BASH_COMPAT
224 #define    BASH_SHLVL_VAR       ENABLE_ASH_BASH_COMPAT
225 #define    BASH_XTRACEFD        ENABLE_ASH_BASH_COMPAT
226 #define    BASH_READ_D          ENABLE_ASH_BASH_COMPAT
227 #define IF_BASH_READ_D              IF_ASH_BASH_COMPAT
228 #define    BASH_WAIT_N          ENABLE_ASH_BASH_COMPAT
229
230 #if defined(__ANDROID_API__) && __ANDROID_API__ <= 24
231 /* Bionic at least up to version 24 has no glob() */
232 # undef  ENABLE_ASH_INTERNAL_GLOB
233 # define ENABLE_ASH_INTERNAL_GLOB 1
234 #endif
235
236 #if !ENABLE_ASH_INTERNAL_GLOB && defined(__UCLIBC__)
237 # error uClibc glob() is buggy, use ASH_INTERNAL_GLOB.
238 # error The bug is: for "$PWD"/<pattern> ash will escape e.g. dashes in "$PWD"
239 # error with backslash, even ones which do not need to be: "/a-b" -> "/a\-b"
240 # error glob() should unbackslash them and match. uClibc does not unbackslash,
241 # error fails to match dirname, subsequently not expanding <pattern> in it.
242 // Testcase:
243 // if (glob("/etc/polkit\\-1", 0, NULL, &pglob)) - this returns 0 on uclibc, no bug
244 // if (glob("/etc/polkit\\-1/*", 0, NULL, &pglob)) printf("uclibc bug!\n");
245 #endif
246
247 #if !ENABLE_ASH_INTERNAL_GLOB
248 # include <glob.h>
249 #endif
250
251 #include "unicode.h"
252 #include "shell_common.h"
253 #if ENABLE_FEATURE_SH_MATH
254 # include "math.h"
255 #else
256 typedef long arith_t;
257 # define ARITH_FMT "%ld"
258 #endif
259 #if ENABLE_ASH_RANDOM_SUPPORT
260 # include "random.h"
261 #else
262 # define CLEAR_RANDOM_T(rnd) ((void)0)
263 #endif
264
265 #include "NUM_APPLETS.h"
266 #if NUM_APPLETS == 1
267 /* STANDALONE does not make sense, and won't compile */
268 # undef CONFIG_FEATURE_SH_STANDALONE
269 # undef ENABLE_FEATURE_SH_STANDALONE
270 # undef IF_FEATURE_SH_STANDALONE
271 # undef IF_NOT_FEATURE_SH_STANDALONE
272 # define ENABLE_FEATURE_SH_STANDALONE 0
273 # define IF_FEATURE_SH_STANDALONE(...)
274 # define IF_NOT_FEATURE_SH_STANDALONE(...) __VA_ARGS__
275 #endif
276
277 #ifndef F_DUPFD_CLOEXEC
278 # define F_DUPFD_CLOEXEC F_DUPFD
279 #endif
280 #ifndef O_CLOEXEC
281 # define O_CLOEXEC 0
282 #endif
283 #ifndef PIPE_BUF
284 # define PIPE_BUF 4096           /* amount of buffering in a pipe */
285 #endif
286
287 #if !BB_MMU
288 # error "Do not even bother, ash will not run on NOMMU machine"
289 #endif
290
291 /* We use a trick to have more optimized code (fewer pointer reloads):
292  *  ash.c:   extern struct globals *const ash_ptr_to_globals;
293  *  ash_ptr_hack.c: struct globals *ash_ptr_to_globals;
294  * This way, compiler in ash.c knows the pointer can not change.
295  *
296  * However, this may break on weird arches or toolchains. In this case,
297  * set "-DBB_GLOBAL_CONST=''" in CONFIG_EXTRA_CFLAGS to disable
298  * this optimization.
299  */
300 #ifndef BB_GLOBAL_CONST
301 # define BB_GLOBAL_CONST const
302 #endif
303
304
305 /* ============ Hash table sizes. Configurable. */
306
307 #define VTABSIZE 39
308 #define ATABSIZE 39
309 #define CMDTABLESIZE 31         /* should be prime */
310
311
312 /* ============ Shell options */
313
314 static const char *const optletters_optnames[] = {
315         "e"   "errexit",
316         "f"   "noglob",
317         "I"   "ignoreeof",
318 /* The below allowed this invocation:
319  * ash -c 'set -i; echo $-; sleep 5; echo $-'
320  * to be ^C-ed and get to interactive ash prompt.
321  * bash does not support such "set -i".
322  * In our code, this is denoted by empty long name:
323  */
324         "i"   "",
325         "m"   "monitor",
326         "n"   "noexec",
327 /* Ditto: bash has no "set -s" */
328         "s"   "",
329         "c"   "",
330         "x"   "xtrace",
331         "v"   "verbose",
332         "C"   "noclobber",
333         "a"   "allexport",
334         "b"   "notify",
335         "u"   "nounset",
336         "\0"  "vi"
337 #if BASH_PIPEFAIL
338         ,"\0"  "pipefail"
339 #endif
340 #if DEBUG
341         ,"\0"  "nolog"
342         ,"\0"  "debug"
343 #endif
344 };
345 //bash 4.4.23 also has these opts (with these defaults):
346 //braceexpand           on
347 //emacs                 on
348 //errtrace              off
349 //functrace             off
350 //hashall               on
351 //histexpand            off
352 //history               on
353 //interactive-comments  on
354 //keyword               off
355 //onecmd                off
356 //physical              off
357 //posix                 off
358 //privileged            off
359
360 #define optletters(n)  optletters_optnames[n][0]
361 #define optnames(n)   (optletters_optnames[n] + 1)
362
363 enum { NOPTS = ARRAY_SIZE(optletters_optnames) };
364
365
366 /* ============ Misc data */
367
368 #define msg_illnum "Illegal number: %s"
369
370 /*
371  * We enclose jmp_buf in a structure so that we can declare pointers to
372  * jump locations.  The global variable handler contains the location to
373  * jump to when an exception occurs, and the global variable exception_type
374  * contains a code identifying the exception.  To implement nested
375  * exception handlers, the user should save the value of handler on entry
376  * to an inner scope, set handler to point to a jmploc structure for the
377  * inner scope, and restore handler on exit from the scope.
378  */
379 struct jmploc {
380         jmp_buf loc;
381 };
382
383 struct globals_misc {
384         uint8_t exitstatus;     /* exit status of last command */
385         uint8_t back_exitstatus;/* exit status of backquoted command */
386         smallint job_warning;   /* user was warned about stopped jobs (can be 2, 1 or 0). */
387         int savestatus;         /* exit status of last command outside traps */
388         int rootpid;            /* pid of main shell */
389         /* shell level: 0 for the main shell, 1 for its children, and so on */
390         int shlvl;
391 #define rootshell (!shlvl)
392         int errlinno;
393
394         char *minusc;  /* argument to -c option */
395
396         char *curdir; // = nullstr;     /* current working directory */
397         char *physdir; // = nullstr;    /* physical working directory */
398
399         char *arg0; /* value of $0 */
400
401         struct jmploc *exception_handler;
402
403         volatile int suppress_int; /* counter */
404         volatile /*sig_atomic_t*/ smallint pending_int; /* 1 = got SIGINT */
405         volatile /*sig_atomic_t*/ smallint got_sigchld; /* 1 = got SIGCHLD */
406         volatile /*sig_atomic_t*/ smallint pending_sig; /* last pending signal */
407         smallint exception_type; /* kind of exception (0..5) */
408         /* exceptions */
409 #define EXINT 0         /* SIGINT received */
410 #define EXERROR 1       /* a generic error */
411 #define EXEXIT 4        /* exit the shell */
412
413         char nullstr[1];        /* zero length string */
414
415         char optlist[NOPTS];
416 #define eflag optlist[0]
417 #define fflag optlist[1]
418 #define Iflag optlist[2]
419 #define iflag optlist[3]
420 #define mflag optlist[4]
421 #define nflag optlist[5]
422 #define sflag optlist[6]
423 #define cflag optlist[7]
424 #define xflag optlist[8]
425 #define vflag optlist[9]
426 #define Cflag optlist[10]
427 #define aflag optlist[11]
428 #define bflag optlist[12]
429 #define uflag optlist[13]
430 #define viflag optlist[14]
431 #if BASH_PIPEFAIL
432 # define pipefail optlist[15]
433 #else
434 # define pipefail 0
435 #endif
436 #if DEBUG
437 # define nolog optlist[15 + BASH_PIPEFAIL]
438 # define debug optlist[16 + BASH_PIPEFAIL]
439 #endif
440
441         /* trap handler commands */
442         /*
443          * Sigmode records the current value of the signal handlers for the various
444          * modes.  A value of zero means that the current handler is not known.
445          * S_HARD_IGN indicates that the signal was ignored on entry to the shell.
446          */
447         char sigmode[NSIG - 1];
448 #define S_DFL      1            /* default signal handling (SIG_DFL) */
449 #define S_CATCH    2            /* signal is caught */
450 #define S_IGN      3            /* signal is ignored (SIG_IGN) */
451 #define S_HARD_IGN 4            /* signal is ignored permanently (it was SIG_IGN on entry to shell) */
452
453         /* indicates specified signal received */
454         uint8_t gotsig[NSIG - 1]; /* offset by 1: "signal" 0 is meaningless */
455         uint8_t may_have_traps; /* 0: definitely no traps are set, 1: some traps may be set */
456         char *trap[NSIG];
457         char **trap_ptr;        /* used only by "trap hack" */
458
459         /* Rarely referenced stuff */
460 #if ENABLE_ASH_RANDOM_SUPPORT
461         random_t random_gen;
462 #endif
463         pid_t backgndpid;        /* pid of last background process */
464 };
465 extern struct globals_misc *BB_GLOBAL_CONST ash_ptr_to_globals_misc;
466 #define G_misc (*ash_ptr_to_globals_misc)
467 #define exitstatus        (G_misc.exitstatus )
468 #define back_exitstatus   (G_misc.back_exitstatus )
469 #define job_warning       (G_misc.job_warning)
470 #define savestatus  (G_misc.savestatus )
471 #define rootpid     (G_misc.rootpid    )
472 #define shlvl       (G_misc.shlvl      )
473 #define errlinno    (G_misc.errlinno   )
474 #define minusc      (G_misc.minusc     )
475 #define curdir      (G_misc.curdir     )
476 #define physdir     (G_misc.physdir    )
477 #define arg0        (G_misc.arg0       )
478 #define exception_handler (G_misc.exception_handler)
479 #define exception_type    (G_misc.exception_type   )
480 #define suppress_int      (G_misc.suppress_int     )
481 #define pending_int       (G_misc.pending_int      )
482 #define got_sigchld       (G_misc.got_sigchld      )
483 #define pending_sig       (G_misc.pending_sig      )
484 #define nullstr     (G_misc.nullstr    )
485 #define optlist     (G_misc.optlist    )
486 #define sigmode     (G_misc.sigmode    )
487 #define gotsig      (G_misc.gotsig     )
488 #define may_have_traps    (G_misc.may_have_traps   )
489 #define trap        (G_misc.trap       )
490 #define trap_ptr    (G_misc.trap_ptr   )
491 #define random_gen  (G_misc.random_gen )
492 #define backgndpid  (G_misc.backgndpid )
493 #define INIT_G_misc() do { \
494         (*(struct globals_misc**)not_const_pp(&ash_ptr_to_globals_misc)) = xzalloc(sizeof(G_misc)); \
495         barrier(); \
496         savestatus = -1; \
497         curdir = nullstr; \
498         physdir = nullstr; \
499         trap_ptr = trap; \
500 } while (0)
501
502
503 /* ============ DEBUG */
504 #if DEBUG
505 static void trace_printf(const char *fmt, ...);
506 static void trace_vprintf(const char *fmt, va_list va);
507 # define TRACE(param)    trace_printf param
508 # define TRACEV(param)   trace_vprintf param
509 # define close(fd) do { \
510         int dfd = (fd); \
511         if (close(dfd) < 0) \
512                 bb_error_msg("bug on %d: closing %d(0x%x)", \
513                         __LINE__, dfd, dfd); \
514 } while (0)
515 #else
516 # define TRACE(param)
517 # define TRACEV(param)
518 #endif
519
520
521 /* ============ Utility functions */
522 #define is_name(c)      ((c) == '_' || isalpha((unsigned char)(c)))
523 #define is_in_name(c)   ((c) == '_' || isalnum((unsigned char)(c)))
524
525 static int
526 isdigit_str9(const char *str)
527 {
528         int maxlen = 9 + 1; /* max 9 digits: 999999999 */
529         while (--maxlen && isdigit(*str))
530                 str++;
531         return (*str == '\0');
532 }
533
534 static const char *
535 var_end(const char *var)
536 {
537         while (*var)
538                 if (*var++ == '=')
539                         break;
540         return var;
541 }
542
543
544 /* ============ Interrupts / exceptions */
545
546 static void exitshell(void) NORETURN;
547
548 /*
549  * These macros allow the user to suspend the handling of interrupt signals
550  * over a period of time.  This is similar to SIGHOLD or to sigblock, but
551  * much more efficient and portable.  (But hacking the kernel is so much
552  * more fun than worrying about efficiency and portability. :-))
553  */
554 #if DEBUG_INTONOFF
555 # define INT_OFF do { \
556         TRACE(("%s:%d INT_OFF(%d)\n", __func__, __LINE__, suppress_int)); \
557         suppress_int++; \
558         barrier(); \
559 } while (0)
560 #else
561 # define INT_OFF do { \
562         suppress_int++; \
563         barrier(); \
564 } while (0)
565 #endif
566
567 /*
568  * Called to raise an exception.  Since C doesn't include exceptions, we
569  * just do a longjmp to the exception handler.  The type of exception is
570  * stored in the global variable "exception_type".
571  */
572 static void raise_exception(int) NORETURN;
573 static void
574 raise_exception(int e)
575 {
576 #if DEBUG
577         if (exception_handler == NULL)
578                 abort();
579 #endif
580         INT_OFF;
581         exception_type = e;
582         longjmp(exception_handler->loc, 1);
583 }
584 #if DEBUG
585 #define raise_exception(e) do { \
586         TRACE(("raising exception %d on line %d\n", (e), __LINE__)); \
587         raise_exception(e); \
588 } while (0)
589 #endif
590
591 /*
592  * Called when a SIGINT is received.  (If the user specifies
593  * that SIGINT is to be trapped or ignored using the trap builtin, then
594  * this routine is not called.)  Suppressint is nonzero when interrupts
595  * are held using the INT_OFF macro.  (The test for iflag is just
596  * defensive programming.)
597  */
598 static void raise_interrupt(void) NORETURN;
599 static void
600 raise_interrupt(void)
601 {
602         pending_int = 0;
603         /* Signal is not automatically unmasked after it is raised,
604          * do it ourself - unmask all signals */
605         sigprocmask_allsigs(SIG_UNBLOCK);
606         /* pending_sig = 0; - now done in signal_handler() */
607
608         if (!(rootshell && iflag)) {
609                 /* Kill ourself with SIGINT */
610                 signal(SIGINT, SIG_DFL);
611                 raise(SIGINT);
612         }
613         /* bash: ^C even on empty command line sets $? */
614         exitstatus = SIGINT + 128;
615         raise_exception(EXINT);
616         /* NOTREACHED */
617 }
618 #if DEBUG
619 #define raise_interrupt() do { \
620         TRACE(("raising interrupt on line %d\n", __LINE__)); \
621         raise_interrupt(); \
622 } while (0)
623 #endif
624
625 static IF_ASH_OPTIMIZE_FOR_SIZE(inline) void
626 int_on(void)
627 {
628         barrier();
629         if (--suppress_int == 0 && pending_int) {
630                 raise_interrupt();
631         }
632 }
633 #if DEBUG_INTONOFF
634 # define INT_ON do { \
635         TRACE(("%s:%d INT_ON(%d)\n", __func__, __LINE__, suppress_int-1)); \
636         int_on(); \
637 } while (0)
638 #else
639 # define INT_ON int_on()
640 #endif
641 static IF_ASH_OPTIMIZE_FOR_SIZE(inline) void
642 force_int_on(void)
643 {
644         barrier();
645         suppress_int = 0;
646         if (pending_int)
647                 raise_interrupt();
648 }
649 #define FORCE_INT_ON force_int_on()
650
651 #define SAVE_INT(v) ((v) = suppress_int)
652
653 #define RESTORE_INT(v) do { \
654         barrier(); \
655         suppress_int = (v); \
656         if (suppress_int == 0 && pending_int) \
657                 raise_interrupt(); \
658 } while (0)
659
660
661 /* ============ Stdout/stderr output */
662
663 static void
664 outstr(const char *p, FILE *file)
665 {
666         INT_OFF;
667         fputs(p, file);
668         INT_ON;
669 }
670
671 static void
672 flush_stdout_stderr(void)
673 {
674         INT_OFF;
675         fflush_all();
676         INT_ON;
677 }
678
679 /* Was called outcslow(c,FILE*), but c was always '\n' */
680 static void
681 newline_and_flush(FILE *dest)
682 {
683         INT_OFF;
684         putc('\n', dest);
685         fflush(dest);
686         INT_ON;
687 }
688
689 static int out1fmt(const char *, ...) __attribute__((__format__(__printf__,1,2)));
690 static int
691 out1fmt(const char *fmt, ...)
692 {
693         va_list ap;
694         int r;
695
696         INT_OFF;
697         va_start(ap, fmt);
698         r = vprintf(fmt, ap);
699         va_end(ap);
700         INT_ON;
701         return r;
702 }
703
704 static int fmtstr(char *, size_t, const char *, ...) __attribute__((__format__(__printf__,3,4)));
705 static int
706 fmtstr(char *outbuf, size_t length, const char *fmt, ...)
707 {
708         va_list ap;
709         int ret;
710
711         INT_OFF;
712         va_start(ap, fmt);
713         ret = vsnprintf(outbuf, length, fmt, ap);
714         va_end(ap);
715         INT_ON;
716         return ret > (int)length ? length : ret;
717 }
718
719 static void
720 out1str(const char *p)
721 {
722         outstr(p, stdout);
723 }
724
725 static void
726 out2str(const char *p)
727 {
728         outstr(p, stderr);
729         flush_stdout_stderr();
730 }
731
732
733 /* ============ Parser structures */
734
735 /* control characters in argument strings */
736 #define CTL_FIRST CTLESC
737 #define CTLESC       ((unsigned char)'\201')    /* escape next character */
738 #define CTLVAR       ((unsigned char)'\202')    /* variable defn */
739 #define CTLENDVAR    ((unsigned char)'\203')
740 #define CTLBACKQ     ((unsigned char)'\204')
741 #define CTLARI       ((unsigned char)'\206')    /* arithmetic expression */
742 #define CTLENDARI    ((unsigned char)'\207')
743 #define CTLQUOTEMARK ((unsigned char)'\210')
744 #define CTL_LAST CTLQUOTEMARK
745
746 /* variable substitution byte (follows CTLVAR) */
747 #define VSTYPE  0x0f            /* type of variable substitution */
748 #define VSNUL   0x10            /* colon--treat the empty string as unset */
749
750 /* values of VSTYPE field */
751 #define VSNORMAL        0x1     /* normal variable:  $var or ${var} */
752 #define VSMINUS         0x2     /* ${var-text} */
753 #define VSPLUS          0x3     /* ${var+text} */
754 #define VSQUESTION      0x4     /* ${var?message} */
755 #define VSASSIGN        0x5     /* ${var=text} */
756 #define VSTRIMRIGHT     0x6     /* ${var%pattern} */
757 #define VSTRIMRIGHTMAX  0x7     /* ${var%%pattern} */
758 #define VSTRIMLEFT      0x8     /* ${var#pattern} */
759 #define VSTRIMLEFTMAX   0x9     /* ${var##pattern} */
760 #define VSLENGTH        0xa     /* ${#var} */
761 #if BASH_SUBSTR
762 #define VSSUBSTR        0xc     /* ${var:position:length} */
763 #endif
764 #if BASH_PATTERN_SUBST
765 #define VSREPLACE       0xd     /* ${var/pattern/replacement} */
766 #define VSREPLACEALL    0xe     /* ${var//pattern/replacement} */
767 #endif
768
769 static const char dolatstr[] ALIGN1 = {
770         CTLQUOTEMARK, CTLVAR, VSNORMAL, '@', '=', CTLQUOTEMARK, '\0'
771 };
772 #define DOLATSTRLEN 6
773
774 #define NCMD      0
775 #define NPIPE     1
776 #define NREDIR    2
777 #define NBACKGND  3
778 #define NSUBSHELL 4
779 #define NAND      5
780 #define NOR       6
781 #define NSEMI     7
782 #define NIF       8
783 #define NWHILE    9
784 #define NUNTIL   10
785 #define NFOR     11
786 #define NCASE    12
787 #define NCLIST   13
788 #define NDEFUN   14
789 #define NARG     15
790 #define NTO      16
791 #if BASH_REDIR_OUTPUT
792 #define NTO2     17
793 #endif
794 #define NCLOBBER 18
795 #define NFROM    19
796 #define NFROMTO  20
797 #define NAPPEND  21
798 #define NTOFD    22
799 #define NFROMFD  23
800 #define NHERE    24
801 #define NXHERE   25
802 #define NNOT     26
803 #define N_NUMBER 27
804
805 union node;
806
807 struct ncmd {
808         smallint type; /* Nxxxx */
809         int linno;
810         union node *assign;
811         union node *args;
812         union node *redirect;
813 };
814
815 struct npipe {
816         smallint type;
817         smallint pipe_backgnd;
818         struct nodelist *cmdlist;
819 };
820
821 struct nredir {
822         smallint type;
823         int linno;
824         union node *n;
825         union node *redirect;
826 };
827
828 struct nbinary {
829         smallint type;
830         union node *ch1;
831         union node *ch2;
832 };
833
834 struct nif {
835         smallint type;
836         union node *test;
837         union node *ifpart;
838         union node *elsepart;
839 };
840
841 struct nfor {
842         smallint type;
843         int linno;
844         union node *args;
845         union node *body;
846         char *var;
847 };
848
849 struct ncase {
850         smallint type;
851         int linno;
852         union node *expr;
853         union node *cases;
854 };
855
856 struct nclist {
857         smallint type;
858         union node *next;
859         union node *pattern;
860         union node *body;
861 };
862
863 struct ndefun {
864         smallint type;
865         int linno;
866         char *text;
867         union node *body;
868 };
869
870 struct narg {
871         smallint type;
872         union node *next;
873         char *text;
874         struct nodelist *backquote;
875 };
876
877 /* nfile and ndup layout must match!
878  * NTOFD (>&fdnum) uses ndup structure, but we may discover mid-flight
879  * that it is actually NTO2 (>&file), and change its type.
880  */
881 struct nfile {
882         smallint type;
883         union node *next;
884         int fd;
885         int _unused_dupfd;
886         union node *fname;
887         char *expfname;
888 };
889
890 struct ndup {
891         smallint type;
892         union node *next;
893         int fd;
894         int dupfd;
895         union node *vname;
896         char *_unused_expfname;
897 };
898
899 struct nhere {
900         smallint type;
901         union node *next;
902         int fd;
903         union node *doc;
904 };
905
906 struct nnot {
907         smallint type;
908         union node *com;
909 };
910
911 union node {
912         smallint type;
913         struct ncmd ncmd;
914         struct npipe npipe;
915         struct nredir nredir;
916         struct nbinary nbinary;
917         struct nif nif;
918         struct nfor nfor;
919         struct ncase ncase;
920         struct nclist nclist;
921         struct ndefun ndefun;
922         struct narg narg;
923         struct nfile nfile;
924         struct ndup ndup;
925         struct nhere nhere;
926         struct nnot nnot;
927 };
928
929 /*
930  * NODE_EOF is returned by parsecmd when it encounters an end of file.
931  * It must be distinct from NULL.
932  */
933 #define NODE_EOF ((union node *) -1L)
934
935 struct nodelist {
936         struct nodelist *next;
937         union node *n;
938 };
939
940 struct funcnode {
941         int count;
942         union node n;
943 };
944
945 /*
946  * Free a parse tree.
947  */
948 static void
949 freefunc(struct funcnode *f)
950 {
951         if (f && --f->count < 0)
952                 free(f);
953 }
954
955
956 /* ============ Debugging output */
957
958 #if DEBUG
959
960 static FILE *tracefile;
961
962 static void
963 trace_printf(const char *fmt, ...)
964 {
965         va_list va;
966
967         if (debug != 1)
968                 return;
969         if (DEBUG_TIME)
970                 fprintf(tracefile, "%u ", (int) time(NULL));
971         if (DEBUG_PID)
972                 fprintf(tracefile, "[%u] ", (int) getpid());
973         if (DEBUG_SIG)
974                 fprintf(tracefile, "pending s:%d i:%d(supp:%d) ", pending_sig, pending_int, suppress_int);
975         va_start(va, fmt);
976         vfprintf(tracefile, fmt, va);
977         va_end(va);
978 }
979
980 static void
981 trace_vprintf(const char *fmt, va_list va)
982 {
983         if (debug != 1)
984                 return;
985         vfprintf(tracefile, fmt, va);
986         fprintf(tracefile, "\n");
987 }
988
989 static void
990 trace_puts(const char *s)
991 {
992         if (debug != 1)
993                 return;
994         fputs(s, tracefile);
995 }
996
997 static void
998 trace_puts_quoted(char *s)
999 {
1000         char *p;
1001         char c;
1002
1003         if (debug != 1)
1004                 return;
1005         putc('"', tracefile);
1006         for (p = s; *p; p++) {
1007                 switch ((unsigned char)*p) {
1008                 case '\n': c = 'n'; goto backslash;
1009                 case '\t': c = 't'; goto backslash;
1010                 case '\r': c = 'r'; goto backslash;
1011                 case '\"': c = '\"'; goto backslash;
1012                 case '\\': c = '\\'; goto backslash;
1013                 case CTLESC: c = 'e'; goto backslash;
1014                 case CTLVAR: c = 'v'; goto backslash;
1015                 case CTLBACKQ: c = 'q'; goto backslash;
1016  backslash:
1017                         putc('\\', tracefile);
1018                         putc(c, tracefile);
1019                         break;
1020                 default:
1021                         if (*p >= ' ' && *p <= '~')
1022                                 putc(*p, tracefile);
1023                         else {
1024                                 putc('\\', tracefile);
1025                                 putc((*p >> 6) & 03, tracefile);
1026                                 putc((*p >> 3) & 07, tracefile);
1027                                 putc(*p & 07, tracefile);
1028                         }
1029                         break;
1030                 }
1031         }
1032         putc('"', tracefile);
1033 }
1034
1035 static void
1036 trace_puts_args(char **ap)
1037 {
1038         if (debug != 1)
1039                 return;
1040         if (!*ap)
1041                 return;
1042         while (1) {
1043                 trace_puts_quoted(*ap);
1044                 if (!*++ap) {
1045                         putc('\n', tracefile);
1046                         break;
1047                 }
1048                 putc(' ', tracefile);
1049         }
1050 }
1051
1052 static void
1053 opentrace(void)
1054 {
1055         char s[100];
1056 #ifdef O_APPEND
1057         int flags;
1058 #endif
1059
1060         if (debug != 1) {
1061                 if (tracefile)
1062                         fflush(tracefile);
1063                 /* leave open because libedit might be using it */
1064                 return;
1065         }
1066         strcpy(s, "./trace");
1067         if (tracefile) {
1068                 if (!freopen(s, "a", tracefile)) {
1069                         fprintf(stderr, "Can't re-open %s\n", s);
1070                         debug = 0;
1071                         return;
1072                 }
1073         } else {
1074                 tracefile = fopen(s, "a");
1075                 if (tracefile == NULL) {
1076                         fprintf(stderr, "Can't open %s\n", s);
1077                         debug = 0;
1078                         return;
1079                 }
1080         }
1081 #ifdef O_APPEND
1082         flags = fcntl(fileno(tracefile), F_GETFL);
1083         if (flags >= 0)
1084                 fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND);
1085 #endif
1086         setlinebuf(tracefile);
1087         fputs("\nTracing started.\n", tracefile);
1088 }
1089
1090 static void
1091 indent(int amount, char *pfx, FILE *fp)
1092 {
1093         int i;
1094
1095         for (i = 0; i < amount; i++) {
1096                 if (pfx && i == amount - 1)
1097                         fputs(pfx, fp);
1098                 putc('\t', fp);
1099         }
1100 }
1101
1102 /* little circular references here... */
1103 static void shtree(union node *n, int ind, char *pfx, FILE *fp);
1104
1105 static void
1106 sharg(union node *arg, FILE *fp)
1107 {
1108         char *p;
1109         struct nodelist *bqlist;
1110         unsigned char subtype;
1111
1112         if (arg->type != NARG) {
1113                 out1fmt("<node type %d>\n", arg->type);
1114                 abort();
1115         }
1116         bqlist = arg->narg.backquote;
1117         for (p = arg->narg.text; *p; p++) {
1118                 switch ((unsigned char)*p) {
1119                 case CTLESC:
1120                         p++;
1121                         putc(*p, fp);
1122                         break;
1123                 case CTLVAR:
1124                         putc('$', fp);
1125                         putc('{', fp);
1126                         subtype = *++p;
1127                         if (subtype == VSLENGTH)
1128                                 putc('#', fp);
1129
1130                         while (*p != '=') {
1131                                 putc(*p, fp);
1132                                 p++;
1133                         }
1134
1135                         if (subtype & VSNUL)
1136                                 putc(':', fp);
1137
1138                         switch (subtype & VSTYPE) {
1139                         case VSNORMAL:
1140                                 putc('}', fp);
1141                                 break;
1142                         case VSMINUS:
1143                                 putc('-', fp);
1144                                 break;
1145                         case VSPLUS:
1146                                 putc('+', fp);
1147                                 break;
1148                         case VSQUESTION:
1149                                 putc('?', fp);
1150                                 break;
1151                         case VSASSIGN:
1152                                 putc('=', fp);
1153                                 break;
1154                         case VSTRIMLEFT:
1155                                 putc('#', fp);
1156                                 break;
1157                         case VSTRIMLEFTMAX:
1158                                 putc('#', fp);
1159                                 putc('#', fp);
1160                                 break;
1161                         case VSTRIMRIGHT:
1162                                 putc('%', fp);
1163                                 break;
1164                         case VSTRIMRIGHTMAX:
1165                                 putc('%', fp);
1166                                 putc('%', fp);
1167                                 break;
1168                         case VSLENGTH:
1169                                 break;
1170                         default:
1171                                 out1fmt("<subtype %d>", subtype);
1172                         }
1173                         break;
1174                 case CTLENDVAR:
1175                         putc('}', fp);
1176                         break;
1177                 case CTLBACKQ:
1178                         putc('$', fp);
1179                         putc('(', fp);
1180                         shtree(bqlist->n, -1, NULL, fp);
1181                         putc(')', fp);
1182                         break;
1183                 default:
1184                         putc(*p, fp);
1185                         break;
1186                 }
1187         }
1188 }
1189
1190 static void
1191 shcmd(union node *cmd, FILE *fp)
1192 {
1193         union node *np;
1194         int first;
1195         const char *s;
1196         int dftfd;
1197
1198         first = 1;
1199         for (np = cmd->ncmd.args; np; np = np->narg.next) {
1200                 if (!first)
1201                         putc(' ', fp);
1202                 sharg(np, fp);
1203                 first = 0;
1204         }
1205         for (np = cmd->ncmd.redirect; np; np = np->nfile.next) {
1206                 if (!first)
1207                         putc(' ', fp);
1208                 dftfd = 0;
1209                 switch (np->nfile.type) {
1210                 case NTO:      s = ">>"+1; dftfd = 1; break;
1211                 case NCLOBBER: s = ">|"; dftfd = 1; break;
1212                 case NAPPEND:  s = ">>"; dftfd = 1; break;
1213 #if BASH_REDIR_OUTPUT
1214                 case NTO2:
1215 #endif
1216                 case NTOFD:    s = ">&"; dftfd = 1; break;
1217                 case NFROM:    s = "<"; break;
1218                 case NFROMFD:  s = "<&"; break;
1219                 case NFROMTO:  s = "<>"; break;
1220                 default:       s = "*error*"; break;
1221                 }
1222                 if (np->nfile.fd != dftfd)
1223                         fprintf(fp, "%d", np->nfile.fd);
1224                 fputs(s, fp);
1225                 if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) {
1226                         fprintf(fp, "%d", np->ndup.dupfd);
1227                 } else {
1228                         sharg(np->nfile.fname, fp);
1229                 }
1230                 first = 0;
1231         }
1232 }
1233
1234 static void
1235 shtree(union node *n, int ind, char *pfx, FILE *fp)
1236 {
1237         struct nodelist *lp;
1238         const char *s;
1239
1240         if (n == NULL)
1241                 return;
1242
1243         indent(ind, pfx, fp);
1244
1245         if (n == NODE_EOF) {
1246                 fputs("<EOF>", fp);
1247                 return;
1248         }
1249
1250         switch (n->type) {
1251         case NSEMI:
1252                 s = "; ";
1253                 goto binop;
1254         case NAND:
1255                 s = " && ";
1256                 goto binop;
1257         case NOR:
1258                 s = " || ";
1259  binop:
1260                 shtree(n->nbinary.ch1, ind, NULL, fp);
1261                 /* if (ind < 0) */
1262                         fputs(s, fp);
1263                 shtree(n->nbinary.ch2, ind, NULL, fp);
1264                 break;
1265         case NCMD:
1266                 shcmd(n, fp);
1267                 if (ind >= 0)
1268                         putc('\n', fp);
1269                 break;
1270         case NPIPE:
1271                 for (lp = n->npipe.cmdlist; lp; lp = lp->next) {
1272                         shtree(lp->n, 0, NULL, fp);
1273                         if (lp->next)
1274                                 fputs(" | ", fp);
1275                 }
1276                 if (n->npipe.pipe_backgnd)
1277                         fputs(" &", fp);
1278                 if (ind >= 0)
1279                         putc('\n', fp);
1280                 break;
1281         default:
1282                 fprintf(fp, "<node type %d>", n->type);
1283                 if (ind >= 0)
1284                         putc('\n', fp);
1285                 break;
1286         }
1287 }
1288
1289 static void
1290 showtree(union node *n)
1291 {
1292         trace_puts("showtree called\n");
1293         shtree(n, 1, NULL, stderr);
1294 }
1295
1296 #endif /* DEBUG */
1297
1298
1299 /* ============ Parser data */
1300
1301 /*
1302  * ash_vmsg() needs parsefile->fd, hence parsefile definition is moved up.
1303  */
1304 struct strlist {
1305         struct strlist *next;
1306         char *text;
1307 };
1308
1309 struct alias;
1310
1311 struct strpush {
1312         struct strpush *prev;   /* preceding string on stack */
1313         char *prev_string;
1314         int prev_left_in_line;
1315 #if ENABLE_ASH_ALIAS
1316         struct alias *ap;       /* if push was associated with an alias */
1317 #endif
1318         char *string;           /* remember the string since it may change */
1319
1320         /* Remember last two characters for pungetc. */
1321         int lastc[2];
1322
1323         /* Number of outstanding calls to pungetc. */
1324         int unget;
1325 };
1326
1327 /*
1328  * The parsefile structure pointed to by the global variable parsefile
1329  * contains information about the current file being read.
1330  */
1331 struct parsefile {
1332         struct parsefile *prev; /* preceding file on stack */
1333         int linno;              /* current line */
1334         int pf_fd;              /* file descriptor (or -1 if string) */
1335         int left_in_line;       /* number of chars left in this line */
1336         int left_in_buffer;     /* number of chars left in this buffer past the line */
1337         char *next_to_pgetc;    /* next char in buffer */
1338         char *buf;              /* input buffer */
1339         struct strpush *strpush; /* for pushing strings at this level */
1340         struct strpush basestrpush; /* so pushing one is fast */
1341
1342         /* Remember last two characters for pungetc. */
1343         int lastc[2];
1344
1345         /* Number of outstanding calls to pungetc. */
1346         int unget;
1347 };
1348
1349 static struct parsefile basepf;        /* top level input file */
1350 static struct parsefile *g_parsefile = &basepf;  /* current input file */
1351 static char *commandname;              /* currently executing command */
1352
1353
1354 /* ============ Message printing */
1355
1356 static void
1357 ash_vmsg(const char *msg, va_list ap)
1358 {
1359         fprintf(stderr, "%s: ", arg0);
1360         if (commandname) {
1361                 if (strcmp(arg0, commandname))
1362                         fprintf(stderr, "%s: ", commandname);
1363                 if (!iflag || g_parsefile->pf_fd > 0)
1364                         fprintf(stderr, "line %d: ", errlinno);
1365         }
1366         vfprintf(stderr, msg, ap);
1367         newline_and_flush(stderr);
1368 }
1369
1370 /*
1371  * Exverror is called to raise the error exception.  If the second argument
1372  * is not NULL then error prints an error message using printf style
1373  * formatting.  It then raises the error exception.
1374  */
1375 static void ash_vmsg_and_raise(int, const char *, va_list) NORETURN;
1376 static void
1377 ash_vmsg_and_raise(int cond, const char *msg, va_list ap)
1378 {
1379 #if DEBUG
1380         if (msg) {
1381                 TRACE(("ash_vmsg_and_raise(%d):", cond));
1382                 TRACEV((msg, ap));
1383         } else
1384                 TRACE(("ash_vmsg_and_raise(%d):NULL\n", cond));
1385         if (msg)
1386 #endif
1387                 ash_vmsg(msg, ap);
1388
1389         flush_stdout_stderr();
1390         raise_exception(cond);
1391         /* NOTREACHED */
1392 }
1393
1394 static void ash_msg_and_raise_error(const char *, ...) NORETURN;
1395 static void
1396 ash_msg_and_raise_error(const char *msg, ...)
1397 {
1398         va_list ap;
1399
1400         exitstatus = 2;
1401
1402         va_start(ap, msg);
1403         ash_vmsg_and_raise(EXERROR, msg, ap);
1404         /* NOTREACHED */
1405         va_end(ap);
1406 }
1407
1408 /*
1409  * 'fmt' must be a string literal.
1410  */
1411 #define ash_msg_and_raise_perror(fmt, ...) ash_msg_and_raise_error(fmt ": "STRERROR_FMT, ##__VA_ARGS__ STRERROR_ERRNO)
1412
1413 static void raise_error_syntax(const char *) NORETURN;
1414 static void
1415 raise_error_syntax(const char *msg)
1416 {
1417         errlinno = g_parsefile->linno;
1418         ash_msg_and_raise_error("syntax error: %s", msg);
1419         /* NOTREACHED */
1420 }
1421
1422 static void ash_msg_and_raise(int, const char *, ...) NORETURN;
1423 static void
1424 ash_msg_and_raise(int cond, const char *msg, ...)
1425 {
1426         va_list ap;
1427
1428         va_start(ap, msg);
1429         ash_vmsg_and_raise(cond, msg, ap);
1430         /* NOTREACHED */
1431         va_end(ap);
1432 }
1433
1434 /*
1435  * error/warning routines for external builtins
1436  */
1437 static void
1438 ash_msg(const char *fmt, ...)
1439 {
1440         va_list ap;
1441
1442         va_start(ap, fmt);
1443         ash_vmsg(fmt, ap);
1444         va_end(ap);
1445 }
1446
1447 /*
1448  * Return a string describing an error.  The returned string may be a
1449  * pointer to a static buffer that will be overwritten on the next call.
1450  * Action describes the operation that got the error.
1451  */
1452 static const char *
1453 errmsg(int e, const char *em)
1454 {
1455         if (e == ENOENT || e == ENOTDIR) {
1456                 return em;
1457         }
1458         return strerror(e);
1459 }
1460
1461
1462 /* ============ Memory allocation */
1463
1464 #if 0
1465 /* I consider these wrappers nearly useless:
1466  * ok, they return you to nearest exception handler, but
1467  * how much memory do you leak in the process, making
1468  * memory starvation worse?
1469  */
1470 static void *
1471 ckrealloc(void * p, size_t nbytes)
1472 {
1473         p = realloc(p, nbytes);
1474         if (!p)
1475                 ash_msg_and_raise_error(bb_msg_memory_exhausted);
1476         return p;
1477 }
1478
1479 static void *
1480 ckmalloc(size_t nbytes)
1481 {
1482         return ckrealloc(NULL, nbytes);
1483 }
1484
1485 static void *
1486 ckzalloc(size_t nbytes)
1487 {
1488         return memset(ckmalloc(nbytes), 0, nbytes);
1489 }
1490
1491 static char *
1492 ckstrdup(const char *s)
1493 {
1494         char *p = strdup(s);
1495         if (!p)
1496                 ash_msg_and_raise_error(bb_msg_memory_exhausted);
1497         return p;
1498 }
1499 #else
1500 /* Using bbox equivalents. They exit if out of memory */
1501 # define ckrealloc xrealloc
1502 # define ckmalloc  xmalloc
1503 # define ckzalloc  xzalloc
1504 # define ckstrdup  xstrdup
1505 #endif
1506
1507 /*
1508  * It appears that grabstackstr() will barf with such alignments
1509  * because stalloc() will return a string allocated in a new stackblock.
1510  */
1511 #define SHELL_ALIGN(nbytes) (((nbytes) + SHELL_SIZE) & ~SHELL_SIZE)
1512 enum {
1513         /* Most machines require the value returned from malloc to be aligned
1514          * in some way.  The following macro will get this right
1515          * on many machines.  */
1516         SHELL_SIZE = sizeof(union { int i; char *cp; double d; }) - 1,
1517         /* Minimum size of a block */
1518         MINSIZE = SHELL_ALIGN(504),
1519 };
1520
1521 struct stack_block {
1522         struct stack_block *prev;
1523         char space[MINSIZE];
1524 };
1525
1526 struct stackmark {
1527         struct stack_block *stackp;
1528         char *stacknxt;
1529         size_t stacknleft;
1530 };
1531
1532
1533 struct globals_memstack {
1534         struct stack_block *g_stackp; // = &stackbase;
1535         char *g_stacknxt; // = stackbase.space;
1536         char *sstrend; // = stackbase.space + MINSIZE;
1537         size_t g_stacknleft; // = MINSIZE;
1538         struct stack_block stackbase;
1539 };
1540 extern struct globals_memstack *BB_GLOBAL_CONST ash_ptr_to_globals_memstack;
1541 #define G_memstack (*ash_ptr_to_globals_memstack)
1542 #define g_stackp     (G_memstack.g_stackp    )
1543 #define g_stacknxt   (G_memstack.g_stacknxt  )
1544 #define sstrend      (G_memstack.sstrend     )
1545 #define g_stacknleft (G_memstack.g_stacknleft)
1546 #define stackbase    (G_memstack.stackbase   )
1547 #define INIT_G_memstack() do { \
1548         (*(struct globals_memstack**)not_const_pp(&ash_ptr_to_globals_memstack)) = xzalloc(sizeof(G_memstack)); \
1549         barrier(); \
1550         g_stackp = &stackbase; \
1551         g_stacknxt = stackbase.space; \
1552         g_stacknleft = MINSIZE; \
1553         sstrend = stackbase.space + MINSIZE; \
1554 } while (0)
1555
1556
1557 #define stackblock()     ((void *)g_stacknxt)
1558 #define stackblocksize() g_stacknleft
1559
1560 /*
1561  * Parse trees for commands are allocated in lifo order, so we use a stack
1562  * to make this more efficient, and also to avoid all sorts of exception
1563  * handling code to handle interrupts in the middle of a parse.
1564  *
1565  * The size 504 was chosen because the Ultrix malloc handles that size
1566  * well.
1567  */
1568 static void *
1569 stalloc(size_t nbytes)
1570 {
1571         char *p;
1572         size_t aligned;
1573
1574         aligned = SHELL_ALIGN(nbytes);
1575         if (aligned > g_stacknleft) {
1576                 size_t len;
1577                 size_t blocksize;
1578                 struct stack_block *sp;
1579
1580                 blocksize = aligned;
1581                 if (blocksize < MINSIZE)
1582                         blocksize = MINSIZE;
1583                 len = sizeof(struct stack_block) - MINSIZE + blocksize;
1584                 if (len < blocksize)
1585                         ash_msg_and_raise_error(bb_msg_memory_exhausted);
1586                 INT_OFF;
1587                 sp = ckmalloc(len);
1588                 sp->prev = g_stackp;
1589                 g_stacknxt = sp->space;
1590                 g_stacknleft = blocksize;
1591                 sstrend = g_stacknxt + blocksize;
1592                 g_stackp = sp;
1593                 INT_ON;
1594         }
1595         p = g_stacknxt;
1596         g_stacknxt += aligned;
1597         g_stacknleft -= aligned;
1598         return p;
1599 }
1600
1601 static void *
1602 stzalloc(size_t nbytes)
1603 {
1604         return memset(stalloc(nbytes), 0, nbytes);
1605 }
1606
1607 static void
1608 stunalloc(void *p)
1609 {
1610 #if DEBUG
1611         if (!p || (g_stacknxt < (char *)p) || ((char *)p < g_stackp->space)) {
1612                 write(STDERR_FILENO, "stunalloc\n", 10);
1613                 abort();
1614         }
1615 #endif
1616         g_stacknleft += g_stacknxt - (char *)p;
1617         g_stacknxt = p;
1618 }
1619
1620 /*
1621  * Like strdup but works with the ash stack.
1622  */
1623 static char *
1624 sstrdup(const char *p)
1625 {
1626         size_t len = strlen(p) + 1;
1627         return memcpy(stalloc(len), p, len);
1628 }
1629
1630 static ALWAYS_INLINE void
1631 grabstackblock(size_t len)
1632 {
1633         stalloc(len);
1634 }
1635
1636 static void
1637 pushstackmark(struct stackmark *mark, size_t len)
1638 {
1639         mark->stackp = g_stackp;
1640         mark->stacknxt = g_stacknxt;
1641         mark->stacknleft = g_stacknleft;
1642         grabstackblock(len);
1643 }
1644
1645 static void
1646 setstackmark(struct stackmark *mark)
1647 {
1648         pushstackmark(mark, g_stacknxt == g_stackp->space && g_stackp != &stackbase);
1649 }
1650
1651 static void
1652 popstackmark(struct stackmark *mark)
1653 {
1654         struct stack_block *sp;
1655
1656         if (!mark->stackp)
1657                 return;
1658
1659         INT_OFF;
1660         while (g_stackp != mark->stackp) {
1661                 sp = g_stackp;
1662                 g_stackp = sp->prev;
1663                 free(sp);
1664         }
1665         g_stacknxt = mark->stacknxt;
1666         g_stacknleft = mark->stacknleft;
1667         sstrend = mark->stacknxt + mark->stacknleft;
1668         INT_ON;
1669 }
1670
1671 /*
1672  * When the parser reads in a string, it wants to stick the string on the
1673  * stack and only adjust the stack pointer when it knows how big the
1674  * string is.  Stackblock (defined in stack.h) returns a pointer to a block
1675  * of space on top of the stack and stackblocklen returns the length of
1676  * this block.  Growstackblock will grow this space by at least one byte,
1677  * possibly moving it (like realloc).  Grabstackblock actually allocates the
1678  * part of the block that has been used.
1679  */
1680 static void
1681 growstackblock(void)
1682 {
1683         size_t newlen;
1684
1685         newlen = g_stacknleft * 2;
1686         if (newlen < g_stacknleft)
1687                 ash_msg_and_raise_error(bb_msg_memory_exhausted);
1688         if (newlen < 128)
1689                 newlen += 128;
1690
1691         if (g_stacknxt == g_stackp->space && g_stackp != &stackbase) {
1692                 struct stack_block *sp;
1693                 struct stack_block *prevstackp;
1694                 size_t grosslen;
1695
1696                 INT_OFF;
1697                 sp = g_stackp;
1698                 prevstackp = sp->prev;
1699                 grosslen = newlen + sizeof(struct stack_block) - MINSIZE;
1700                 sp = ckrealloc(sp, grosslen);
1701                 sp->prev = prevstackp;
1702                 g_stackp = sp;
1703                 g_stacknxt = sp->space;
1704                 g_stacknleft = newlen;
1705                 sstrend = sp->space + newlen;
1706                 INT_ON;
1707         } else {
1708                 char *oldspace = g_stacknxt;
1709                 size_t oldlen = g_stacknleft;
1710                 char *p = stalloc(newlen);
1711
1712                 /* free the space we just allocated */
1713                 g_stacknxt = memcpy(p, oldspace, oldlen);
1714                 g_stacknleft += newlen;
1715         }
1716 }
1717
1718 /*
1719  * The following routines are somewhat easier to use than the above.
1720  * The user declares a variable of type STACKSTR, which may be declared
1721  * to be a register.  The macro STARTSTACKSTR initializes things.  Then
1722  * the user uses the macro STPUTC to add characters to the string.  In
1723  * effect, STPUTC(c, p) is the same as *p++ = c except that the stack is
1724  * grown as necessary.  When the user is done, she can just leave the
1725  * string there and refer to it using stackblock().  Or she can allocate
1726  * the space for it using grabstackstr().  If it is necessary to allow
1727  * someone else to use the stack temporarily and then continue to grow
1728  * the string, the user should use grabstack to allocate the space, and
1729  * then call ungrabstr(p) to return to the previous mode of operation.
1730  *
1731  * USTPUTC is like STPUTC except that it doesn't check for overflow.
1732  * CHECKSTACKSPACE can be called before USTPUTC to ensure that there
1733  * is space for at least one character.
1734  */
1735 static void *
1736 growstackstr(void)
1737 {
1738         size_t len = stackblocksize();
1739         growstackblock();
1740         return (char *)stackblock() + len;
1741 }
1742
1743 static char *
1744 growstackto(size_t len)
1745 {
1746         while (stackblocksize() < len)
1747                 growstackblock();
1748
1749         return stackblock();
1750 }
1751
1752 /*
1753  * Called from CHECKSTRSPACE.
1754  */
1755 static char *
1756 makestrspace(size_t newlen, char *p)
1757 {
1758         size_t len = p - g_stacknxt;
1759
1760         return growstackto(len + newlen) + len;
1761 }
1762
1763 static char *
1764 stack_nputstr(const char *s, size_t n, char *p)
1765 {
1766         p = makestrspace(n, p);
1767         p = (char *)mempcpy(p, s, n);
1768         return p;
1769 }
1770
1771 static char *
1772 stack_putstr(const char *s, char *p)
1773 {
1774         return stack_nputstr(s, strlen(s), p);
1775 }
1776
1777 static char *
1778 _STPUTC(int c, char *p)
1779 {
1780         if (p == sstrend)
1781                 p = growstackstr();
1782         *p++ = c;
1783         return p;
1784 }
1785
1786 #define STARTSTACKSTR(p)        ((p) = stackblock())
1787 #define STPUTC(c, p)            ((p) = _STPUTC((c), (p)))
1788 #define CHECKSTRSPACE(n, p) do { \
1789         char *q = (p); \
1790         size_t l = (n); \
1791         size_t m = sstrend - q; \
1792         if (l > m) \
1793                 (p) = makestrspace(l, q); \
1794 } while (0)
1795 #define USTPUTC(c, p)           (*(p)++ = (c))
1796 #define STACKSTRNUL(p) do { \
1797         if ((p) == sstrend) \
1798                 (p) = growstackstr(); \
1799         *(p) = '\0'; \
1800 } while (0)
1801 #define STUNPUTC(p)             (--(p))
1802 #define STTOPC(p)               ((p)[-1])
1803 #define STADJUST(amount, p)     ((p) += (amount))
1804
1805 #define grabstackstr(p)         stalloc((char *)(p) - (char *)stackblock())
1806 #define ungrabstackstr(s, p)    stunalloc(s)
1807 #define stackstrend()           ((void *)sstrend)
1808
1809
1810 /* ============ String helpers */
1811
1812 /*
1813  * prefix -- see if pfx is a prefix of string.
1814  */
1815 static char *
1816 prefix(const char *string, const char *pfx)
1817 {
1818         while (*pfx) {
1819                 if (*pfx++ != *string++)
1820                         return NULL;
1821         }
1822         return (char *) string;
1823 }
1824
1825 /*
1826  * Check for a valid number.  This should be elsewhere.
1827  */
1828 static int
1829 is_number(const char *p)
1830 {
1831         do {
1832                 if (!isdigit(*p))
1833                         return 0;
1834         } while (*++p != '\0');
1835         return 1;
1836 }
1837
1838 /*
1839  * Convert a string of digits to an integer, printing an error message on
1840  * failure.
1841  */
1842 static int
1843 number(const char *s)
1844 {
1845         if (!is_number(s))
1846                 ash_msg_and_raise_error(msg_illnum, s);
1847         return atoi(s);
1848 }
1849
1850 /*
1851  * Produce a single quoted string suitable as input to the shell.
1852  * The return string is allocated on the stack.
1853  */
1854 static char *
1855 single_quote(const char *s)
1856 {
1857         char *p;
1858
1859         STARTSTACKSTR(p);
1860
1861         do {
1862                 char *q;
1863                 size_t len;
1864
1865                 len = strchrnul(s, '\'') - s;
1866
1867                 q = p = makestrspace(len + 3, p);
1868
1869                 *q++ = '\'';
1870                 q = (char *)mempcpy(q, s, len);
1871                 *q++ = '\'';
1872                 s += len;
1873
1874                 STADJUST(q - p, p);
1875
1876                 if (*s != '\'')
1877                         break;
1878                 len = 0;
1879                 do len++; while (*++s == '\'');
1880
1881                 q = p = makestrspace(len + 3, p);
1882
1883                 *q++ = '"';
1884                 q = (char *)mempcpy(q, s - len, len);
1885                 *q++ = '"';
1886
1887                 STADJUST(q - p, p);
1888         } while (*s);
1889
1890         USTPUTC('\0', p);
1891
1892         return stackblock();
1893 }
1894
1895 /*
1896  * Produce a possibly single quoted string suitable as input to the shell.
1897  * If quoting was done, the return string is allocated on the stack,
1898  * otherwise a pointer to the original string is returned.
1899  */
1900 static const char *
1901 maybe_single_quote(const char *s)
1902 {
1903         const char *p = s;
1904
1905         while (*p) {
1906                 /* Assuming ACSII */
1907                 /* quote ctrl_chars space !"#$%&'()* */
1908                 if (*p < '+')
1909                         goto need_quoting;
1910                 /* quote ;<=>? */
1911                 if (*p >= ';' && *p <= '?')
1912                         goto need_quoting;
1913                 /* quote `[\ */
1914                 if (*p == '`')
1915                         goto need_quoting;
1916                 if (*p == '[')
1917                         goto need_quoting;
1918                 if (*p == '\\')
1919                         goto need_quoting;
1920                 /* quote {|}~ DEL and high bytes */
1921                 if (*p > 'z')
1922                         goto need_quoting;
1923                 /* Not quoting these: +,-./ 0-9 :@ A-Z ]^_ a-z */
1924                 /* TODO: maybe avoid quoting % */
1925                 p++;
1926         }
1927         return s;
1928
1929  need_quoting:
1930         return single_quote(s);
1931 }
1932
1933
1934 /* ============ nextopt */
1935
1936 static char **argptr;                  /* argument list for builtin commands */
1937 static char *optionarg;                /* set by nextopt (like getopt) */
1938 static char *optptr;                   /* used by nextopt */
1939
1940 /*
1941  * XXX - should get rid of. Have all builtins use getopt(3).
1942  * The library getopt must have the BSD extension static variable
1943  * "optreset", otherwise it can't be used within the shell safely.
1944  *
1945  * Standard option processing (a la getopt) for builtin routines.
1946  * The only argument that is passed to nextopt is the option string;
1947  * the other arguments are unnecessary. It returns the character,
1948  * or '\0' on end of input.
1949  */
1950 static int
1951 nextopt(const char *optstring)
1952 {
1953         char *p;
1954         const char *q;
1955         char c;
1956
1957         p = optptr;
1958         if (p == NULL || *p == '\0') {
1959                 /* We ate entire "-param", take next one */
1960                 p = *argptr;
1961                 if (p == NULL)
1962                         return '\0';
1963                 if (*p != '-')
1964                         return '\0';
1965                 if (*++p == '\0') /* just "-" ? */
1966                         return '\0';
1967                 argptr++;
1968                 if (LONE_DASH(p)) /* "--" ? */
1969                         return '\0';
1970                 /* p => next "-param" */
1971         }
1972         /* p => some option char in the middle of a "-param" */
1973         c = *p++;
1974         for (q = optstring; *q != c;) {
1975                 if (*q == '\0')
1976                         ash_msg_and_raise_error("illegal option -%c", c);
1977                 if (*++q == ':')
1978                         q++;
1979         }
1980         if (*++q == ':') {
1981                 if (*p == '\0') {
1982                         p = *argptr++;
1983                         if (p == NULL)
1984                                 ash_msg_and_raise_error("no arg for -%c option", c);
1985                 }
1986                 optionarg = p;
1987                 p = NULL;
1988         }
1989         optptr = p;
1990         return c;
1991 }
1992
1993
1994 /* ============ Shell variables */
1995
1996 struct shparam {
1997         int nparam;             /* # of positional parameters (without $0) */
1998 #if ENABLE_ASH_GETOPTS
1999         int optind;             /* next parameter to be processed by getopts */
2000         int optoff;             /* used by getopts */
2001 #endif
2002         unsigned char malloced; /* if parameter list dynamically allocated */
2003         char **p;               /* parameter list */
2004 };
2005
2006 /*
2007  * Free the list of positional parameters.
2008  */
2009 static void
2010 freeparam(volatile struct shparam *param)
2011 {
2012         if (param->malloced) {
2013                 char **ap, **ap1;
2014                 ap = ap1 = param->p;
2015                 while (*ap)
2016                         free(*ap++);
2017                 free(ap1);
2018         }
2019 }
2020
2021 #if ENABLE_ASH_GETOPTS
2022 static void FAST_FUNC getoptsreset(const char *value);
2023 #endif
2024
2025 struct var {
2026         struct var *next;               /* next entry in hash list */
2027         int flags;                      /* flags are defined above */
2028         const char *var_text;           /* name=value */
2029         void (*var_func)(const char *) FAST_FUNC; /* function to be called when  */
2030                                         /* the variable gets set/unset */
2031 };
2032
2033 struct localvar {
2034         struct localvar *next;          /* next local variable in list */
2035         struct var *vp;                 /* the variable that was made local */
2036         int flags;                      /* saved flags */
2037         const char *text;               /* saved text */
2038 };
2039
2040 /* flags */
2041 #define VEXPORT         0x01    /* variable is exported */
2042 #define VREADONLY       0x02    /* variable cannot be modified */
2043 #define VSTRFIXED       0x04    /* variable struct is statically allocated */
2044 #define VTEXTFIXED      0x08    /* text is statically allocated */
2045 #define VSTACK          0x10    /* text is allocated on the stack */
2046 #define VUNSET          0x20    /* the variable is not set */
2047 #define VNOFUNC         0x40    /* don't call the callback function */
2048 #define VNOSET          0x80    /* do not set variable - just readonly test */
2049 #define VNOSAVE         0x100   /* when text is on the heap before setvareq */
2050 #if ENABLE_ASH_RANDOM_SUPPORT
2051 # define VDYNAMIC       0x200   /* dynamic variable */
2052 #else
2053 # define VDYNAMIC       0
2054 #endif
2055
2056
2057 /* Need to be before varinit_data[] */
2058 #if ENABLE_LOCALE_SUPPORT
2059 static void FAST_FUNC
2060 change_lc_all(const char *value)
2061 {
2062         if (value && *value != '\0')
2063                 setlocale(LC_ALL, value);
2064 }
2065 static void FAST_FUNC
2066 change_lc_ctype(const char *value)
2067 {
2068         if (value && *value != '\0')
2069                 setlocale(LC_CTYPE, value);
2070 }
2071 #endif
2072 #if ENABLE_ASH_MAIL
2073 static void chkmail(void);
2074 static void changemail(const char *var_value) FAST_FUNC;
2075 #else
2076 # define chkmail()  ((void)0)
2077 #endif
2078 static void changepath(const char *) FAST_FUNC;
2079 #if ENABLE_ASH_RANDOM_SUPPORT
2080 static void change_random(const char *) FAST_FUNC;
2081 #endif
2082 #if BASH_EPOCH_VARS
2083 static void change_seconds(const char *) FAST_FUNC;
2084 static void change_realtime(const char *) FAST_FUNC;
2085 #endif
2086
2087 static const struct {
2088         int flags;
2089         const char *var_text;
2090         void (*var_func)(const char *) FAST_FUNC;
2091 } varinit_data[] = {
2092         /*
2093          * Note: VEXPORT would not work correctly here for NOFORK applets:
2094          * some environment strings may be constant.
2095          */
2096         { VSTRFIXED|VTEXTFIXED       , defifsvar   , NULL            },
2097 #if ENABLE_ASH_MAIL
2098         { VSTRFIXED|VTEXTFIXED|VUNSET, "MAIL"      , changemail      },
2099         { VSTRFIXED|VTEXTFIXED|VUNSET, "MAILPATH"  , changemail      },
2100 #endif
2101         { VSTRFIXED|VTEXTFIXED       , bb_PATH_root_path, changepath },
2102         { VSTRFIXED|VTEXTFIXED       , "PS1=$ "    , NULL            },
2103         { VSTRFIXED|VTEXTFIXED       , "PS2=> "    , NULL            },
2104         { VSTRFIXED|VTEXTFIXED       , "PS4=+ "    , NULL            },
2105 #if ENABLE_ASH_GETOPTS
2106         { VSTRFIXED|VTEXTFIXED       , defoptindvar, getoptsreset    },
2107 #endif
2108         { VSTRFIXED|VTEXTFIXED       , NULL /* inited to linenovar */, NULL },
2109 #if ENABLE_ASH_RANDOM_SUPPORT
2110         { VSTRFIXED|VTEXTFIXED|VUNSET|VDYNAMIC, "RANDOM", change_random },
2111 #endif
2112 #if BASH_EPOCH_VARS
2113         { VSTRFIXED|VTEXTFIXED|VUNSET|VDYNAMIC, "EPOCHSECONDS", change_seconds },
2114         { VSTRFIXED|VTEXTFIXED|VUNSET|VDYNAMIC, "EPOCHREALTIME", change_realtime },
2115 #endif
2116 #if ENABLE_LOCALE_SUPPORT
2117         { VSTRFIXED|VTEXTFIXED|VUNSET, "LC_ALL"    , change_lc_all   },
2118         { VSTRFIXED|VTEXTFIXED|VUNSET, "LC_CTYPE"  , change_lc_ctype },
2119 #endif
2120 #if ENABLE_FEATURE_EDITING_SAVEHISTORY
2121         { VSTRFIXED|VTEXTFIXED|VUNSET, "HISTFILE"  , NULL            },
2122 #endif
2123 };
2124
2125 struct redirtab;
2126
2127 struct globals_var {
2128         struct shparam shellparam;      /* $@ current positional parameters */
2129         struct redirtab *redirlist;
2130         int preverrout_fd;   /* stderr fd: usually 2, unless redirect moved it */
2131         struct var *vartab[VTABSIZE];
2132         struct var varinit[ARRAY_SIZE(varinit_data)];
2133         int lineno;
2134         char linenovar[sizeof("LINENO=") + sizeof(int)*3];
2135 };
2136 extern struct globals_var *BB_GLOBAL_CONST ash_ptr_to_globals_var;
2137 #define G_var (*ash_ptr_to_globals_var)
2138 #define shellparam    (G_var.shellparam   )
2139 //#define redirlist     (G_var.redirlist    )
2140 #define preverrout_fd (G_var.preverrout_fd)
2141 #define vartab        (G_var.vartab       )
2142 #define varinit       (G_var.varinit      )
2143 #define lineno        (G_var.lineno       )
2144 #define linenovar     (G_var.linenovar    )
2145 #define vifs      varinit[0]
2146 #if ENABLE_ASH_MAIL
2147 # define vmail    varinit[1]
2148 # define vmpath   varinit[2]
2149 #endif
2150 #define VAR_OFFSET1 (ENABLE_ASH_MAIL*2)
2151 #define vpath     varinit[VAR_OFFSET1 + 1]
2152 #define vps1      varinit[VAR_OFFSET1 + 2]
2153 #define vps2      varinit[VAR_OFFSET1 + 3]
2154 #define vps4      varinit[VAR_OFFSET1 + 4]
2155 #if ENABLE_ASH_GETOPTS
2156 # define voptind  varinit[VAR_OFFSET1 + 5]
2157 #endif
2158 #define VAR_OFFSET2 (VAR_OFFSET1 + ENABLE_ASH_GETOPTS)
2159 #define vlineno   varinit[VAR_OFFSET2 + 5]
2160 #if ENABLE_ASH_RANDOM_SUPPORT
2161 # define vrandom  varinit[VAR_OFFSET2 + 6]
2162 #endif
2163 #define VAR_OFFSET3 (VAR_OFFSET2 + ENABLE_ASH_RANDOM_SUPPORT)
2164 #if BASH_EPOCH_VARS
2165 # define vepochs  varinit[VAR_OFFSET3 + 6]
2166 # define vepochr  varinit[VAR_OFFSET3 + 7]
2167 #endif
2168 #define INIT_G_var() do { \
2169         unsigned i; \
2170         (*(struct globals_var**)not_const_pp(&ash_ptr_to_globals_var)) = xzalloc(sizeof(G_var)); \
2171         barrier(); \
2172         for (i = 0; i < ARRAY_SIZE(varinit_data); i++) { \
2173                 varinit[i].flags    = varinit_data[i].flags; \
2174                 varinit[i].var_text = varinit_data[i].var_text; \
2175                 varinit[i].var_func = varinit_data[i].var_func; \
2176         } \
2177         strcpy(linenovar, "LINENO="); \
2178         vlineno.var_text = linenovar; \
2179 } while (0)
2180
2181 /*
2182  * The following macros access the values of the above variables.
2183  * They have to skip over the name.  They return the null string
2184  * for unset variables.
2185  */
2186 #define ifsval()        (vifs.var_text + 4)
2187 #define ifsset()        ((vifs.flags & VUNSET) == 0)
2188 #if ENABLE_ASH_MAIL
2189 # define mailval()      (vmail.var_text + 5)
2190 # define mpathval()     (vmpath.var_text + 9)
2191 # define mpathset()     ((vmpath.flags & VUNSET) == 0)
2192 #endif
2193 #define pathval()       (vpath.var_text + 5)
2194 #define ps1val()        (vps1.var_text + 4)
2195 #define ps2val()        (vps2.var_text + 4)
2196 #define ps4val()        (vps4.var_text + 4)
2197 #if ENABLE_ASH_GETOPTS
2198 # define optindval()    (voptind.var_text + 7)
2199 #endif
2200
2201 #if ENABLE_ASH_GETOPTS
2202 static void FAST_FUNC
2203 getoptsreset(const char *value)
2204 {
2205         shellparam.optind = 1;
2206         if (is_number(value))
2207                 shellparam.optind = number(value) ?: 1;
2208         shellparam.optoff = -1;
2209 }
2210 #endif
2211
2212 /*
2213  * Compares two strings up to the first = or '\0'.  The first
2214  * string must be terminated by '='; the second may be terminated by
2215  * either '=' or '\0'.
2216  */
2217 static int
2218 varcmp(const char *p, const char *q)
2219 {
2220         int c, d;
2221
2222         while ((c = *p) == (d = *q)) {
2223                 if (c == '\0' || c == '=')
2224                         goto out;
2225                 p++;
2226                 q++;
2227         }
2228         if (c == '=')
2229                 c = '\0';
2230         if (d == '=')
2231                 d = '\0';
2232  out:
2233         return c - d;
2234 }
2235
2236 /*
2237  * Find the appropriate entry in the hash table from the name.
2238  */
2239 static struct var **
2240 hashvar(const char *p)
2241 {
2242         unsigned hashval;
2243
2244         hashval = ((unsigned char) *p) << 4;
2245         while (*p && *p != '=')
2246                 hashval += (unsigned char) *p++;
2247         return &vartab[hashval % VTABSIZE];
2248 }
2249
2250 static int
2251 vpcmp(const void *a, const void *b)
2252 {
2253         return varcmp(*(const char **)a, *(const char **)b);
2254 }
2255
2256 /*
2257  * This routine initializes the builtin variables.
2258  */
2259 static void
2260 initvar(void)
2261 {
2262         struct var *vp;
2263         struct var *end;
2264         struct var **vpp;
2265
2266         /*
2267          * PS1 depends on uid
2268          */
2269 #if ENABLE_FEATURE_EDITING && ENABLE_FEATURE_EDITING_FANCY_PROMPT
2270         vps1.var_text = "PS1=\\w \\$ ";
2271 #else
2272         if (!geteuid())
2273                 vps1.var_text = "PS1=# ";
2274 #endif
2275         vp = varinit;
2276         end = vp + ARRAY_SIZE(varinit);
2277         do {
2278                 vpp = hashvar(vp->var_text);
2279                 vp->next = *vpp;
2280                 *vpp = vp;
2281         } while (++vp < end);
2282 }
2283
2284 static struct var **
2285 findvar(struct var **vpp, const char *name)
2286 {
2287         for (; *vpp; vpp = &(*vpp)->next) {
2288                 if (varcmp((*vpp)->var_text, name) == 0) {
2289                         break;
2290                 }
2291         }
2292         return vpp;
2293 }
2294
2295 /*
2296  * Find the value of a variable.  Returns NULL if not set.
2297  */
2298 static const char* FAST_FUNC
2299 lookupvar(const char *name)
2300 {
2301         struct var *v;
2302
2303         v = *findvar(hashvar(name), name);
2304         if (v) {
2305 #if ENABLE_ASH_RANDOM_SUPPORT || BASH_EPOCH_VARS
2306         /*
2307          * Dynamic variables are implemented roughly the same way they are
2308          * in bash. Namely, they're "special" so long as they aren't unset.
2309          * As soon as they're unset, they're no longer dynamic, and dynamic
2310          * lookup will no longer happen at that point. -- PFM.
2311          */
2312                 if (v->flags & VDYNAMIC)
2313                         v->var_func(NULL);
2314 #endif
2315                 if (!(v->flags & VUNSET)) {
2316                         if (v == &vlineno && v->var_text == linenovar) {
2317                                 fmtstr(linenovar+7, sizeof(linenovar)-7, "%d", lineno);
2318                         }
2319                         return var_end(v->var_text);
2320                 }
2321         }
2322         return NULL;
2323 }
2324
2325 #if ENABLE_UNICODE_SUPPORT
2326 static void
2327 reinit_unicode_for_ash(void)
2328 {
2329         /* Unicode support should be activated even if LANG is set
2330          * _during_ shell execution, not only if it was set when
2331          * shell was started. Therefore, re-check LANG every time:
2332          */
2333         if (ENABLE_FEATURE_CHECK_UNICODE_IN_ENV
2334          || ENABLE_UNICODE_USING_LOCALE
2335         ) {
2336                 const char *s = lookupvar("LC_ALL");
2337                 if (!s) s = lookupvar("LC_CTYPE");
2338                 if (!s) s = lookupvar("LANG");
2339                 reinit_unicode(s);
2340         }
2341 }
2342 #else
2343 # define reinit_unicode_for_ash() ((void)0)
2344 #endif
2345
2346 /*
2347  * Search the environment of a builtin command.
2348  */
2349 static ALWAYS_INLINE const char *
2350 bltinlookup(const char *name)
2351 {
2352         return lookupvar(name);
2353 }
2354
2355 /*
2356  * Same as setvar except that the variable and value are passed in
2357  * the first argument as name=value.  Since the first argument will
2358  * be actually stored in the table, it should not be a string that
2359  * will go away.
2360  * Called with interrupts off.
2361  */
2362 static struct var *
2363 setvareq(char *s, int flags)
2364 {
2365         struct var *vp, **vpp;
2366
2367         vpp = hashvar(s);
2368         flags |= (VEXPORT & (((unsigned) (1 - aflag)) - 1));
2369         vpp = findvar(vpp, s);
2370         vp = *vpp;
2371         if (vp) {
2372                 if ((vp->flags & (VREADONLY|VDYNAMIC)) == VREADONLY) {
2373                         const char *n;
2374
2375                         if (flags & VNOSAVE)
2376                                 free(s);
2377                         n = vp->var_text;
2378                         exitstatus = 1;
2379                         ash_msg_and_raise_error("%.*s: is read only", strchrnul(n, '=') - n, n);
2380                 }
2381
2382                 if (flags & VNOSET)
2383                         goto out;
2384
2385                 if (vp->var_func && !(flags & VNOFUNC))
2386                         vp->var_func(var_end(s));
2387
2388                 if (!(vp->flags & (VTEXTFIXED|VSTACK)))
2389                         free((char*)vp->var_text);
2390
2391                 if (((flags & (VEXPORT|VREADONLY|VSTRFIXED|VUNSET)) | (vp->flags & VSTRFIXED)) == VUNSET) {
2392                         *vpp = vp->next;
2393                         free(vp);
2394  out_free:
2395                         if ((flags & (VTEXTFIXED|VSTACK|VNOSAVE)) == VNOSAVE)
2396                                 free(s);
2397                         goto out;
2398                 }
2399
2400                 flags |= vp->flags & ~(VTEXTFIXED|VSTACK|VNOSAVE|VUNSET);
2401 #if ENABLE_ASH_RANDOM_SUPPORT || BASH_EPOCH_VARS
2402                 if (flags & VUNSET)
2403                         flags &= ~VDYNAMIC;
2404 #endif
2405         } else {
2406                 /* variable s is not found */
2407                 if (flags & VNOSET)
2408                         goto out;
2409                 if ((flags & (VEXPORT|VREADONLY|VSTRFIXED|VUNSET)) == VUNSET)
2410                         goto out_free;
2411                 vp = ckzalloc(sizeof(*vp));
2412                 vp->next = *vpp;
2413                 /*vp->func = NULL; - ckzalloc did it */
2414                 *vpp = vp;
2415         }
2416         if (!(flags & (VTEXTFIXED|VSTACK|VNOSAVE)))
2417                 s = ckstrdup(s);
2418         vp->var_text = s;
2419         vp->flags = flags;
2420
2421  out:
2422         return vp;
2423 }
2424
2425 /*
2426  * Set the value of a variable.  The flags argument is ored with the
2427  * flags of the variable.  If val is NULL, the variable is unset.
2428  */
2429 static struct var *
2430 setvar(const char *name, const char *val, int flags)
2431 {
2432         const char *q;
2433         char *p;
2434         char *nameeq;
2435         size_t namelen;
2436         size_t vallen;
2437         struct var *vp;
2438
2439         q = endofname(name);
2440         p = strchrnul(q, '=');
2441         namelen = p - name;
2442         if (!namelen || p != q)
2443                 ash_msg_and_raise_error("%.*s: bad variable name", namelen, name);
2444         vallen = 0;
2445         if (val == NULL) {
2446                 flags |= VUNSET;
2447         } else {
2448                 vallen = strlen(val);
2449         }
2450
2451         INT_OFF;
2452         nameeq = ckzalloc(namelen + vallen + 2);
2453         p = mempcpy(nameeq, name, namelen);
2454         if (val) {
2455                 *p++ = '=';
2456                 memcpy(p, val, vallen);
2457         }
2458         vp = setvareq(nameeq, flags | VNOSAVE);
2459         INT_ON;
2460
2461         return vp;
2462 }
2463
2464 static void FAST_FUNC
2465 setvar0(const char *name, const char *val)
2466 {
2467         setvar(name, val, 0);
2468 }
2469
2470 /*
2471  * Unset the specified variable.
2472  */
2473 static void
2474 unsetvar(const char *s)
2475 {
2476         setvar(s, NULL, 0);
2477 }
2478
2479 /*
2480  * Generate a list of variables satisfying the given conditions.
2481  */
2482 #if !ENABLE_FEATURE_SH_NOFORK
2483 # define listvars(on, off, lp, end) listvars(on, off, end)
2484 #endif
2485 static char **
2486 listvars(int on, int off, struct strlist *lp, char ***end)
2487 {
2488         struct var **vpp;
2489         struct var *vp;
2490         char **ep;
2491         int mask;
2492
2493         STARTSTACKSTR(ep);
2494         vpp = vartab;
2495         mask = on | off;
2496         do {
2497                 for (vp = *vpp; vp; vp = vp->next) {
2498                         if ((vp->flags & mask) == on) {
2499 #if ENABLE_FEATURE_SH_NOFORK
2500                                 /* If variable with the same name is both
2501                                  * exported and temporarily set for a command:
2502                                  *  export ZVAR=5
2503                                  *  ZVAR=6 printenv
2504                                  * then "ZVAR=6" will be both in vartab and
2505                                  * lp lists. Do not pass it twice to printenv.
2506                                  */
2507                                 struct strlist *lp1 = lp;
2508                                 while (lp1) {
2509                                         if (strcmp(lp1->text, vp->var_text) == 0)
2510                                                 goto skip;
2511                                         lp1 = lp1->next;
2512                                 }
2513 #endif
2514                                 if (ep == stackstrend())
2515                                         ep = growstackstr();
2516                                 *ep++ = (char*)vp->var_text;
2517 #if ENABLE_FEATURE_SH_NOFORK
2518  skip: ;
2519 #endif
2520                         }
2521                 }
2522         } while (++vpp < vartab + VTABSIZE);
2523
2524 #if ENABLE_FEATURE_SH_NOFORK
2525         while (lp) {
2526                 if (ep == stackstrend())
2527                         ep = growstackstr();
2528                 *ep++ = lp->text;
2529                 lp = lp->next;
2530         }
2531 #endif
2532
2533         if (ep == stackstrend())
2534                 ep = growstackstr();
2535         if (end)
2536                 *end = ep;
2537         *ep++ = NULL;
2538         return grabstackstr(ep);
2539 }
2540
2541
2542 /* ============ Path search helper */
2543 static const char *
2544 legal_pathopt(const char *opt, const char *term, int magic)
2545 {
2546         switch (magic) {
2547         case 0:
2548                 opt = NULL;
2549                 break;
2550
2551         case 1:
2552                 opt = prefix(opt, "builtin") ?: prefix(opt, "func");
2553                 break;
2554
2555         default:
2556                 opt += strcspn(opt, term);
2557                 break;
2558         }
2559
2560         if (opt && *opt == '%')
2561                 opt++;
2562
2563         return opt;
2564 }
2565
2566 /*
2567  * The variable path (passed by reference) should be set to the start
2568  * of the path before the first call; padvance will update
2569  * this value as it proceeds.  Successive calls to padvance will return
2570  * the possible path expansions in sequence.  If an option (indicated by
2571  * a percent sign) appears in the path entry then the global variable
2572  * pathopt will be set to point to it; otherwise pathopt will be set to
2573  * NULL.
2574  *
2575  * If magic is 0 then pathopt recognition will be disabled.  If magic is
2576  * 1 we shall recognise %builtin/%func.  Otherwise we shall accept any
2577  * pathopt.
2578  */
2579 static const char *pathopt;     /* set by padvance */
2580
2581 static int
2582 padvance_magic(const char **path, const char *name, int magic)
2583 {
2584         const char *term = "%:";
2585         const char *lpathopt;
2586         const char *p;
2587         char *q;
2588         const char *start;
2589         size_t qlen;
2590         size_t len;
2591
2592         if (*path == NULL)
2593                 return -1;
2594
2595         lpathopt = NULL;
2596         start = *path;
2597
2598         if (*start == '%' && (p = legal_pathopt(start + 1, term, magic))) {
2599                 lpathopt = start + 1;
2600                 start = p;
2601                 term = ":";
2602         }
2603
2604         len = strcspn(start, term);
2605         p = start + len;
2606
2607         if (*p == '%') {
2608                 size_t extra = strchrnul(p, ':') - p;
2609
2610                 if (legal_pathopt(p + 1, term, magic))
2611                         lpathopt = p + 1;
2612                 else
2613                         len += extra;
2614
2615                 p += extra;
2616         }
2617
2618         pathopt = lpathopt;
2619         *path = *p == ':' ? p + 1 : NULL;
2620
2621         /* "2" is for '/' and '\0' */
2622         qlen = len + strlen(name) + 2;
2623         q = growstackto(qlen);
2624
2625         if (len) {
2626                 q = mempcpy(q, start, len);
2627                 *q++ = '/';
2628         }
2629         strcpy(q, name);
2630
2631         return qlen;
2632 }
2633
2634 static int
2635 padvance(const char **path, const char *name)
2636 {
2637         return padvance_magic(path, name, 1);
2638 }
2639
2640
2641 /* ============ Prompt */
2642
2643 static smallint doprompt;                   /* if set, prompt the user */
2644 static smallint needprompt;                 /* true if interactive and at start of line */
2645
2646 #if ENABLE_FEATURE_EDITING
2647 static line_input_t *line_input_state;
2648 static const char *cmdedit_prompt;
2649 static void
2650 putprompt(const char *s)
2651 {
2652         if (ENABLE_ASH_EXPAND_PRMT) {
2653                 free((char*)cmdedit_prompt);
2654                 cmdedit_prompt = ckstrdup(s);
2655                 return;
2656         }
2657         cmdedit_prompt = s;
2658 }
2659 #else
2660 static void
2661 putprompt(const char *s)
2662 {
2663         out2str(s);
2664 }
2665 #endif
2666
2667 /* expandstr() needs parsing machinery, so it is far away ahead... */
2668 static const char *expandstr(const char *ps, int syntax_type);
2669 /* Values for syntax param */
2670 #define BASESYNTAX 0    /* not in quotes */
2671 #define DQSYNTAX   1    /* in double quotes */
2672 #define SQSYNTAX   2    /* in single quotes */
2673 #define ARISYNTAX  3    /* in arithmetic */
2674 #if ENABLE_ASH_EXPAND_PRMT
2675 # define PSSYNTAX  4    /* prompt. never passed to SIT() */
2676 #endif
2677 /* PSSYNTAX expansion is identical to DQSYNTAX, except keeping '\$' as '\$' */
2678
2679 /*
2680  * called by editline -- any expansions to the prompt should be added here.
2681  */
2682 static void
2683 setprompt_if(smallint do_set, int whichprompt)
2684 {
2685         const char *prompt;
2686         IF_ASH_EXPAND_PRMT(struct stackmark smark;)
2687
2688         if (!do_set)
2689                 return;
2690
2691         needprompt = 0;
2692
2693         switch (whichprompt) {
2694         case 1:
2695                 prompt = ps1val();
2696                 break;
2697         case 2:
2698                 prompt = ps2val();
2699                 break;
2700         default:                        /* 0 */
2701                 prompt = nullstr;
2702         }
2703 #if ENABLE_ASH_EXPAND_PRMT
2704         pushstackmark(&smark, stackblocksize());
2705         putprompt(expandstr(prompt, PSSYNTAX));
2706         popstackmark(&smark);
2707 #else
2708         putprompt(prompt);
2709 #endif
2710 }
2711
2712
2713 /* ============ The cd and pwd commands */
2714
2715 #define CD_PHYSICAL 1
2716 #define CD_PRINT 2
2717
2718 static int
2719 cdopt(void)
2720 {
2721         int flags = 0;
2722         int i, j;
2723
2724         j = 'L';
2725         while ((i = nextopt("LP")) != '\0') {
2726                 if (i != j) {
2727                         flags ^= CD_PHYSICAL;
2728                         j = i;
2729                 }
2730         }
2731
2732         return flags;
2733 }
2734
2735 /*
2736  * Update curdir (the name of the current directory) in response to a
2737  * cd command.
2738  */
2739 static const char *
2740 updatepwd(const char *dir)
2741 {
2742         char *new;
2743         char *p;
2744         char *cdcomppath;
2745         const char *lim;
2746
2747         cdcomppath = sstrdup(dir);
2748         STARTSTACKSTR(new);
2749         if (*dir != '/') {
2750                 if (curdir == nullstr)
2751                         return 0;
2752                 new = stack_putstr(curdir, new);
2753         }
2754         new = makestrspace(strlen(dir) + 2, new);
2755         lim = (char *)stackblock() + 1;
2756         if (*dir != '/') {
2757                 if (new[-1] != '/')
2758                         USTPUTC('/', new);
2759                 if (new > lim && *lim == '/')
2760                         lim++;
2761         } else {
2762                 USTPUTC('/', new);
2763                 cdcomppath++;
2764                 if (dir[1] == '/' && dir[2] != '/') {
2765                         USTPUTC('/', new);
2766                         cdcomppath++;
2767                         lim++;
2768                 }
2769         }
2770         p = strtok(cdcomppath, "/");
2771         while (p) {
2772                 switch (*p) {
2773                 case '.':
2774                         if (p[1] == '.' && p[2] == '\0') {
2775                                 while (new > lim) {
2776                                         STUNPUTC(new);
2777                                         if (new[-1] == '/')
2778                                                 break;
2779                                 }
2780                                 break;
2781                         }
2782                         if (p[1] == '\0')
2783                                 break;
2784                         /* fall through */
2785                 default:
2786                         new = stack_putstr(p, new);
2787                         USTPUTC('/', new);
2788                 }
2789                 p = strtok(NULL, "/");
2790         }
2791         if (new > lim)
2792                 STUNPUTC(new);
2793         *new = 0;
2794         return stackblock();
2795 }
2796
2797 /*
2798  * Find out what the current directory is. If we already know the current
2799  * directory, this routine returns immediately.
2800  */
2801 static char *
2802 getpwd(void)
2803 {
2804         char *dir = getcwd(NULL, 0); /* huh, using glibc extension? */
2805         return dir ? dir : nullstr;
2806 }
2807
2808 static void
2809 setpwd(const char *val, int setold)
2810 {
2811         char *oldcur, *dir;
2812
2813         oldcur = dir = curdir;
2814
2815         if (setold) {
2816                 setvar("OLDPWD", oldcur, VEXPORT);
2817         }
2818         INT_OFF;
2819         if (physdir != nullstr) {
2820                 if (physdir != oldcur)
2821                         free(physdir);
2822                 physdir = nullstr;
2823         }
2824         if (oldcur == val || !val) {
2825                 char *s = getpwd();
2826                 physdir = s;
2827                 if (!val)
2828                         dir = s;
2829         } else
2830                 dir = ckstrdup(val);
2831         if (oldcur != dir && oldcur != nullstr) {
2832                 free(oldcur);
2833         }
2834         curdir = dir;
2835         INT_ON;
2836         setvar("PWD", dir, VEXPORT);
2837 }
2838
2839 static void hashcd(void);
2840
2841 /*
2842  * Actually do the chdir.  We also call hashcd to let other routines
2843  * know that the current directory has changed.
2844  */
2845 static int
2846 docd(const char *dest, int flags)
2847 {
2848         const char *dir = NULL;
2849         int err;
2850
2851         TRACE(("docd(\"%s\", %d) called\n", dest, flags));
2852
2853         INT_OFF;
2854         if (!(flags & CD_PHYSICAL)) {
2855                 dir = updatepwd(dest);
2856                 if (dir)
2857                         dest = dir;
2858         }
2859         err = chdir(dest);
2860         if (err)
2861                 goto out;
2862         setpwd(dir, 1);
2863         hashcd();
2864  out:
2865         INT_ON;
2866         return err;
2867 }
2868
2869 static int FAST_FUNC
2870 cdcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
2871 {
2872         const char *dest;
2873         const char *path;
2874         const char *p;
2875         char c;
2876         struct stat statb;
2877         int flags;
2878         int len;
2879
2880         flags = cdopt();
2881         dest = *argptr;
2882         if (!dest)
2883                 dest = bltinlookup("HOME");
2884         else if (LONE_DASH(dest)) {
2885                 dest = bltinlookup("OLDPWD");
2886                 flags |= CD_PRINT;
2887         }
2888         if (!dest)
2889                 dest = nullstr;
2890         if (*dest == '/')
2891                 goto step6;
2892         if (*dest == '.') {
2893                 c = dest[1];
2894  dotdot:
2895                 switch (c) {
2896                 case '\0':
2897                 case '/':
2898                         goto step6;
2899                 case '.':
2900                         c = dest[2];
2901                         if (c != '.')
2902                                 goto dotdot;
2903                 }
2904         }
2905         if (!*dest)
2906                 dest = ".";
2907         path = bltinlookup("CDPATH");
2908         while (p = path, (len = padvance(&path, dest)) >= 0) {
2909                 c = *p;
2910                 p = stalloc(len);
2911
2912                 if (stat(p, &statb) >= 0 && S_ISDIR(statb.st_mode)) {
2913                         if (c && c != ':')
2914                                 flags |= CD_PRINT;
2915  docd:
2916                         if (!docd(p, flags))
2917                                 goto out;
2918                         goto err;
2919                 }
2920         }
2921
2922  step6:
2923         p = dest;
2924         goto docd;
2925
2926  err:
2927         ash_msg_and_raise_perror("can't cd to %s", dest);
2928         /* NOTREACHED */
2929  out:
2930         if (flags & CD_PRINT)
2931                 out1fmt("%s\n", curdir);
2932         return 0;
2933 }
2934
2935 static int FAST_FUNC
2936 pwdcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
2937 {
2938         int flags;
2939         const char *dir = curdir;
2940
2941         flags = cdopt();
2942         if (flags) {
2943                 if (physdir == nullstr)
2944                         setpwd(dir, 0);
2945                 dir = physdir;
2946         }
2947         out1fmt("%s\n", dir);
2948         return 0;
2949 }
2950
2951
2952 /* ============ ... */
2953
2954
2955 #define IBUFSIZ (ENABLE_FEATURE_EDITING ? CONFIG_FEATURE_EDITING_MAX_LEN : 1024)
2956
2957 /* Syntax classes */
2958 #define CWORD     0             /* character is nothing special */
2959 #define CNL       1             /* newline character */
2960 #define CBACK     2             /* a backslash character */
2961 #define CSQUOTE   3             /* single quote */
2962 #define CDQUOTE   4             /* double quote */
2963 #define CENDQUOTE 5             /* a terminating quote */
2964 #define CBQUOTE   6             /* backwards single quote */
2965 #define CVAR      7             /* a dollar sign */
2966 #define CENDVAR   8             /* a '}' character */
2967 #define CLP       9             /* a left paren in arithmetic */
2968 #define CRP      10             /* a right paren in arithmetic */
2969 #define CENDFILE 11             /* end of file */
2970 #define CCTL     12             /* like CWORD, except it must be escaped */
2971 #define CSPCL    13             /* these terminate a word */
2972 #define CIGN     14             /* character should be ignored */
2973
2974 #define PEOF     256
2975 #if ENABLE_ASH_ALIAS
2976 # define PEOA    257
2977 #endif
2978
2979 #define USE_SIT_FUNCTION ENABLE_ASH_OPTIMIZE_FOR_SIZE
2980
2981 #if ENABLE_FEATURE_SH_MATH
2982 # define SIT_ITEM(a,b,c,d) (a | (b << 4) | (c << 8) | (d << 12))
2983 #else
2984 # define SIT_ITEM(a,b,c,d) (a | (b << 4) | (c << 8))
2985 #endif
2986 static const uint16_t S_I_T[] ALIGN2 = {
2987 #if ENABLE_ASH_ALIAS
2988         SIT_ITEM(CSPCL   , CIGN     , CIGN , CIGN   ),    /* 0, PEOA */
2989 #endif
2990         SIT_ITEM(CSPCL   , CWORD    , CWORD, CWORD  ),    /* 1, ' ' */
2991         SIT_ITEM(CNL     , CNL      , CNL  , CNL    ),    /* 2, \n */
2992         SIT_ITEM(CWORD   , CCTL     , CCTL , CWORD  ),    /* 3, !*-/:=?[]~ */
2993         SIT_ITEM(CDQUOTE , CENDQUOTE, CWORD, CWORD  ),    /* 4, '"' */
2994         SIT_ITEM(CVAR    , CVAR     , CWORD, CVAR   ),    /* 5, $ */
2995         SIT_ITEM(CSQUOTE , CWORD    , CENDQUOTE, CWORD),  /* 6, "'" */
2996         SIT_ITEM(CSPCL   , CWORD    , CWORD, CLP    ),    /* 7, ( */
2997         SIT_ITEM(CSPCL   , CWORD    , CWORD, CRP    ),    /* 8, ) */
2998         SIT_ITEM(CBACK   , CBACK    , CCTL , CBACK  ),    /* 9, \ */
2999         SIT_ITEM(CBQUOTE , CBQUOTE  , CWORD, CBQUOTE),    /* 10, ` */
3000         SIT_ITEM(CENDVAR , CENDVAR  , CWORD, CENDVAR),    /* 11, } */
3001 #if !USE_SIT_FUNCTION
3002         SIT_ITEM(CENDFILE, CENDFILE , CENDFILE, CENDFILE),/* 12, PEOF */
3003         SIT_ITEM(CWORD   , CWORD    , CWORD, CWORD  ),    /* 13, 0-9A-Za-z */
3004         SIT_ITEM(CCTL    , CCTL     , CCTL , CCTL   )     /* 14, CTLESC ... */
3005 #endif
3006 #undef SIT_ITEM
3007 };
3008 /* Constants below must match table above */
3009 enum {
3010 #if ENABLE_ASH_ALIAS
3011         CSPCL_CIGN_CIGN_CIGN               , /*  0 */
3012 #endif
3013         CSPCL_CWORD_CWORD_CWORD            , /*  1 */
3014         CNL_CNL_CNL_CNL                    , /*  2 */
3015         CWORD_CCTL_CCTL_CWORD              , /*  3 */
3016         CDQUOTE_CENDQUOTE_CWORD_CWORD      , /*  4 */
3017         CVAR_CVAR_CWORD_CVAR               , /*  5 */
3018         CSQUOTE_CWORD_CENDQUOTE_CWORD      , /*  6 */
3019         CSPCL_CWORD_CWORD_CLP              , /*  7 */
3020         CSPCL_CWORD_CWORD_CRP              , /*  8 */
3021         CBACK_CBACK_CCTL_CBACK             , /*  9 */
3022         CBQUOTE_CBQUOTE_CWORD_CBQUOTE      , /* 10 */
3023         CENDVAR_CENDVAR_CWORD_CENDVAR      , /* 11 */
3024         CENDFILE_CENDFILE_CENDFILE_CENDFILE, /* 12 */
3025         CWORD_CWORD_CWORD_CWORD            , /* 13 */
3026         CCTL_CCTL_CCTL_CCTL                , /* 14 */
3027 };
3028
3029 /* c in SIT(c, syntax) must be an *unsigned char* or PEOA or PEOF,
3030  * caller must ensure proper cast on it if c is *char_ptr!
3031  */
3032 #if USE_SIT_FUNCTION
3033
3034 static int
3035 SIT(int c, int syntax)
3036 {
3037         /* Used to also have '/' in this string: "\t\n !\"$&'()*-/:;<=>?[\\]`|}~" */
3038         static const char spec_symbls[] ALIGN1 = "\t\n !\"$&'()*-:;<=>?[\\]`|}~";
3039         /*
3040          * This causes '/' to be prepended with CTLESC in dquoted string,
3041          * making "./file"* treated incorrectly because we feed
3042          * ".\/file*" string to glob(), confusing it (see expandmeta func).
3043          * The "homegrown" glob implementation is okay with that,
3044          * but glibc one isn't. With '/' always treated as CWORD,
3045          * both work fine.
3046          */
3047 # if ENABLE_ASH_ALIAS
3048         static const uint8_t syntax_index_table[] ALIGN1 = {
3049                 1, 2, 1, 3, 4, 5, 1, 6,         /* "\t\n !\"$&'" */
3050                 7, 8, 3, 3,/*3,*/3, 1, 1,       /* "()*-/:;<" */
3051                 3, 1, 3, 3, 9, 3, 10, 1,        /* "=>?[\\]`|" */
3052                 11, 3                           /* "}~" */
3053         };
3054 # else
3055         static const uint8_t syntax_index_table[] ALIGN1 = {
3056                 0, 1, 0, 2, 3, 4, 0, 5,         /* "\t\n !\"$&'" */
3057                 6, 7, 2, 2,/*2,*/2, 0, 0,       /* "()*-/:;<" */
3058                 2, 0, 2, 2, 8, 2, 9, 0,         /* "=>?[\\]`|" */
3059                 10, 2                           /* "}~" */
3060         };
3061 # endif
3062         const char *s;
3063         int indx;
3064
3065         if (c == PEOF)
3066                 return CENDFILE;
3067 # if ENABLE_ASH_ALIAS
3068         if (c == PEOA)
3069                 indx = 0;
3070         else
3071 # endif
3072         {
3073                 /* Cast is purely for paranoia here,
3074                  * just in case someone passed signed char to us */
3075                 if ((unsigned char)c >= CTL_FIRST
3076                  && (unsigned char)c <= CTL_LAST
3077                 ) {
3078                         return CCTL;
3079                 }
3080                 s = strchrnul(spec_symbls, c);
3081                 if (*s == '\0')
3082                         return CWORD;
3083                 indx = syntax_index_table[s - spec_symbls];
3084         }
3085         return (S_I_T[indx] >> (syntax*4)) & 0xf;
3086 }
3087
3088 #else   /* !USE_SIT_FUNCTION */
3089
3090 static const uint8_t syntax_index_table[] ALIGN1 = {
3091         /* BASESYNTAX_DQSYNTAX_SQSYNTAX_ARISYNTAX */
3092         /*   0      */ CWORD_CWORD_CWORD_CWORD,
3093         /*   1      */ CWORD_CWORD_CWORD_CWORD,
3094         /*   2      */ CWORD_CWORD_CWORD_CWORD,
3095         /*   3      */ CWORD_CWORD_CWORD_CWORD,
3096         /*   4      */ CWORD_CWORD_CWORD_CWORD,
3097         /*   5      */ CWORD_CWORD_CWORD_CWORD,
3098         /*   6      */ CWORD_CWORD_CWORD_CWORD,
3099         /*   7      */ CWORD_CWORD_CWORD_CWORD,
3100         /*   8      */ CWORD_CWORD_CWORD_CWORD,
3101         /*   9 "\t" */ CSPCL_CWORD_CWORD_CWORD,
3102         /*  10 "\n" */ CNL_CNL_CNL_CNL,
3103         /*  11      */ CWORD_CWORD_CWORD_CWORD,
3104         /*  12      */ CWORD_CWORD_CWORD_CWORD,
3105         /*  13      */ CWORD_CWORD_CWORD_CWORD,
3106         /*  14      */ CWORD_CWORD_CWORD_CWORD,
3107         /*  15      */ CWORD_CWORD_CWORD_CWORD,
3108         /*  16      */ CWORD_CWORD_CWORD_CWORD,
3109         /*  17      */ CWORD_CWORD_CWORD_CWORD,
3110         /*  18      */ CWORD_CWORD_CWORD_CWORD,
3111         /*  19      */ CWORD_CWORD_CWORD_CWORD,
3112         /*  20      */ CWORD_CWORD_CWORD_CWORD,
3113         /*  21      */ CWORD_CWORD_CWORD_CWORD,
3114         /*  22      */ CWORD_CWORD_CWORD_CWORD,
3115         /*  23      */ CWORD_CWORD_CWORD_CWORD,
3116         /*  24      */ CWORD_CWORD_CWORD_CWORD,
3117         /*  25      */ CWORD_CWORD_CWORD_CWORD,
3118         /*  26      */ CWORD_CWORD_CWORD_CWORD,
3119         /*  27      */ CWORD_CWORD_CWORD_CWORD,
3120         /*  28      */ CWORD_CWORD_CWORD_CWORD,
3121         /*  29      */ CWORD_CWORD_CWORD_CWORD,
3122         /*  30      */ CWORD_CWORD_CWORD_CWORD,
3123         /*  31      */ CWORD_CWORD_CWORD_CWORD,
3124         /*  32  " " */ CSPCL_CWORD_CWORD_CWORD,
3125         /*  33  "!" */ CWORD_CCTL_CCTL_CWORD,
3126         /*  34  """ */ CDQUOTE_CENDQUOTE_CWORD_CWORD,
3127         /*  35  "#" */ CWORD_CWORD_CWORD_CWORD,
3128         /*  36  "$" */ CVAR_CVAR_CWORD_CVAR,
3129         /*  37  "%" */ CWORD_CWORD_CWORD_CWORD,
3130         /*  38  "&" */ CSPCL_CWORD_CWORD_CWORD,
3131         /*  39  "'" */ CSQUOTE_CWORD_CENDQUOTE_CWORD,
3132         /*  40  "(" */ CSPCL_CWORD_CWORD_CLP,
3133         /*  41  ")" */ CSPCL_CWORD_CWORD_CRP,
3134         /*  42  "*" */ CWORD_CCTL_CCTL_CWORD,
3135         /*  43  "+" */ CWORD_CWORD_CWORD_CWORD,
3136         /*  44  "," */ CWORD_CWORD_CWORD_CWORD,
3137         /*  45  "-" */ CWORD_CCTL_CCTL_CWORD,
3138         /*  46  "." */ CWORD_CWORD_CWORD_CWORD,
3139 /* "/" was CWORD_CCTL_CCTL_CWORD, see comment in SIT() function why this is changed: */
3140         /*  47  "/" */ CWORD_CWORD_CWORD_CWORD,
3141         /*  48  "0" */ CWORD_CWORD_CWORD_CWORD,
3142         /*  49  "1" */ CWORD_CWORD_CWORD_CWORD,
3143         /*  50  "2" */ CWORD_CWORD_CWORD_CWORD,
3144         /*  51  "3" */ CWORD_CWORD_CWORD_CWORD,
3145         /*  52  "4" */ CWORD_CWORD_CWORD_CWORD,
3146         /*  53  "5" */ CWORD_CWORD_CWORD_CWORD,
3147         /*  54  "6" */ CWORD_CWORD_CWORD_CWORD,
3148         /*  55  "7" */ CWORD_CWORD_CWORD_CWORD,
3149         /*  56  "8" */ CWORD_CWORD_CWORD_CWORD,
3150         /*  57  "9" */ CWORD_CWORD_CWORD_CWORD,
3151         /*  58  ":" */ CWORD_CCTL_CCTL_CWORD,
3152         /*  59  ";" */ CSPCL_CWORD_CWORD_CWORD,
3153         /*  60  "<" */ CSPCL_CWORD_CWORD_CWORD,
3154         /*  61  "=" */ CWORD_CCTL_CCTL_CWORD,
3155         /*  62  ">" */ CSPCL_CWORD_CWORD_CWORD,
3156         /*  63  "?" */ CWORD_CCTL_CCTL_CWORD,
3157         /*  64  "@" */ CWORD_CWORD_CWORD_CWORD,
3158         /*  65  "A" */ CWORD_CWORD_CWORD_CWORD,
3159         /*  66  "B" */ CWORD_CWORD_CWORD_CWORD,
3160         /*  67  "C" */ CWORD_CWORD_CWORD_CWORD,
3161         /*  68  "D" */ CWORD_CWORD_CWORD_CWORD,
3162         /*  69  "E" */ CWORD_CWORD_CWORD_CWORD,
3163         /*  70  "F" */ CWORD_CWORD_CWORD_CWORD,
3164         /*  71  "G" */ CWORD_CWORD_CWORD_CWORD,
3165         /*  72  "H" */ CWORD_CWORD_CWORD_CWORD,
3166         /*  73  "I" */ CWORD_CWORD_CWORD_CWORD,
3167         /*  74  "J" */ CWORD_CWORD_CWORD_CWORD,
3168         /*  75  "K" */ CWORD_CWORD_CWORD_CWORD,
3169         /*  76  "L" */ CWORD_CWORD_CWORD_CWORD,
3170         /*  77  "M" */ CWORD_CWORD_CWORD_CWORD,
3171         /*  78  "N" */ CWORD_CWORD_CWORD_CWORD,
3172         /*  79  "O" */ CWORD_CWORD_CWORD_CWORD,
3173         /*  80  "P" */ CWORD_CWORD_CWORD_CWORD,
3174         /*  81  "Q" */ CWORD_CWORD_CWORD_CWORD,
3175         /*  82  "R" */ CWORD_CWORD_CWORD_CWORD,
3176         /*  83  "S" */ CWORD_CWORD_CWORD_CWORD,
3177         /*  84  "T" */ CWORD_CWORD_CWORD_CWORD,
3178         /*  85  "U" */ CWORD_CWORD_CWORD_CWORD,
3179         /*  86  "V" */ CWORD_CWORD_CWORD_CWORD,
3180         /*  87  "W" */ CWORD_CWORD_CWORD_CWORD,
3181         /*  88  "X" */ CWORD_CWORD_CWORD_CWORD,
3182         /*  89  "Y" */ CWORD_CWORD_CWORD_CWORD,
3183         /*  90  "Z" */ CWORD_CWORD_CWORD_CWORD,
3184         /*  91  "[" */ CWORD_CCTL_CCTL_CWORD,
3185         /*  92  "\" */ CBACK_CBACK_CCTL_CBACK,
3186         /*  93  "]" */ CWORD_CCTL_CCTL_CWORD,
3187         /*  94  "^" */ CWORD_CWORD_CWORD_CWORD,
3188         /*  95  "_" */ CWORD_CWORD_CWORD_CWORD,
3189         /*  96  "`" */ CBQUOTE_CBQUOTE_CWORD_CBQUOTE,
3190         /*  97  "a" */ CWORD_CWORD_CWORD_CWORD,
3191         /*  98  "b" */ CWORD_CWORD_CWORD_CWORD,
3192         /*  99  "c" */ CWORD_CWORD_CWORD_CWORD,
3193         /* 100  "d" */ CWORD_CWORD_CWORD_CWORD,
3194         /* 101  "e" */ CWORD_CWORD_CWORD_CWORD,
3195         /* 102  "f" */ CWORD_CWORD_CWORD_CWORD,
3196         /* 103  "g" */ CWORD_CWORD_CWORD_CWORD,
3197         /* 104  "h" */ CWORD_CWORD_CWORD_CWORD,
3198         /* 105  "i" */ CWORD_CWORD_CWORD_CWORD,
3199         /* 106  "j" */ CWORD_CWORD_CWORD_CWORD,
3200         /* 107  "k" */ CWORD_CWORD_CWORD_CWORD,
3201         /* 108  "l" */ CWORD_CWORD_CWORD_CWORD,
3202         /* 109  "m" */ CWORD_CWORD_CWORD_CWORD,
3203         /* 110  "n" */ CWORD_CWORD_CWORD_CWORD,
3204         /* 111  "o" */ CWORD_CWORD_CWORD_CWORD,
3205         /* 112  "p" */ CWORD_CWORD_CWORD_CWORD,
3206         /* 113  "q" */ CWORD_CWORD_CWORD_CWORD,
3207         /* 114  "r" */ CWORD_CWORD_CWORD_CWORD,
3208         /* 115  "s" */ CWORD_CWORD_CWORD_CWORD,
3209         /* 116  "t" */ CWORD_CWORD_CWORD_CWORD,
3210         /* 117  "u" */ CWORD_CWORD_CWORD_CWORD,
3211         /* 118  "v" */ CWORD_CWORD_CWORD_CWORD,
3212         /* 119  "w" */ CWORD_CWORD_CWORD_CWORD,
3213         /* 120  "x" */ CWORD_CWORD_CWORD_CWORD,
3214         /* 121  "y" */ CWORD_CWORD_CWORD_CWORD,
3215         /* 122  "z" */ CWORD_CWORD_CWORD_CWORD,
3216         /* 123  "{" */ CWORD_CWORD_CWORD_CWORD,
3217         /* 124  "|" */ CSPCL_CWORD_CWORD_CWORD,
3218         /* 125  "}" */ CENDVAR_CENDVAR_CWORD_CENDVAR,
3219         /* 126  "~" */ CWORD_CCTL_CCTL_CWORD,
3220         /* 127  del */ CWORD_CWORD_CWORD_CWORD,
3221         /* 128 0x80 */ CWORD_CWORD_CWORD_CWORD,
3222         /* 129 CTLESC       */ CCTL_CCTL_CCTL_CCTL,
3223         /* 130 CTLVAR       */ CCTL_CCTL_CCTL_CCTL,
3224         /* 131 CTLENDVAR    */ CCTL_CCTL_CCTL_CCTL,
3225         /* 132 CTLBACKQ     */ CCTL_CCTL_CCTL_CCTL,
3226         /* 133 CTLQUOTE     */ CCTL_CCTL_CCTL_CCTL,
3227         /* 134 CTLARI       */ CCTL_CCTL_CCTL_CCTL,
3228         /* 135 CTLENDARI    */ CCTL_CCTL_CCTL_CCTL,
3229         /* 136 CTLQUOTEMARK */ CCTL_CCTL_CCTL_CCTL,
3230         /* 137      */ CWORD_CWORD_CWORD_CWORD,
3231         /* 138      */ CWORD_CWORD_CWORD_CWORD,
3232         /* 139      */ CWORD_CWORD_CWORD_CWORD,
3233         /* 140      */ CWORD_CWORD_CWORD_CWORD,
3234         /* 141      */ CWORD_CWORD_CWORD_CWORD,
3235         /* 142      */ CWORD_CWORD_CWORD_CWORD,
3236         /* 143      */ CWORD_CWORD_CWORD_CWORD,
3237         /* 144      */ CWORD_CWORD_CWORD_CWORD,
3238         /* 145      */ CWORD_CWORD_CWORD_CWORD,
3239         /* 146      */ CWORD_CWORD_CWORD_CWORD,
3240         /* 147      */ CWORD_CWORD_CWORD_CWORD,
3241         /* 148      */ CWORD_CWORD_CWORD_CWORD,
3242         /* 149      */ CWORD_CWORD_CWORD_CWORD,
3243         /* 150      */ CWORD_CWORD_CWORD_CWORD,
3244         /* 151      */ CWORD_CWORD_CWORD_CWORD,
3245         /* 152      */ CWORD_CWORD_CWORD_CWORD,
3246         /* 153      */ CWORD_CWORD_CWORD_CWORD,
3247         /* 154      */ CWORD_CWORD_CWORD_CWORD,
3248         /* 155      */ CWORD_CWORD_CWORD_CWORD,
3249         /* 156      */ CWORD_CWORD_CWORD_CWORD,
3250         /* 157      */ CWORD_CWORD_CWORD_CWORD,
3251         /* 158      */ CWORD_CWORD_CWORD_CWORD,
3252         /* 159      */ CWORD_CWORD_CWORD_CWORD,
3253         /* 160      */ CWORD_CWORD_CWORD_CWORD,
3254         /* 161      */ CWORD_CWORD_CWORD_CWORD,
3255         /* 162      */ CWORD_CWORD_CWORD_CWORD,
3256         /* 163      */ CWORD_CWORD_CWORD_CWORD,
3257         /* 164      */ CWORD_CWORD_CWORD_CWORD,
3258         /* 165      */ CWORD_CWORD_CWORD_CWORD,
3259         /* 166      */ CWORD_CWORD_CWORD_CWORD,
3260         /* 167      */ CWORD_CWORD_CWORD_CWORD,
3261         /* 168      */ CWORD_CWORD_CWORD_CWORD,
3262         /* 169      */ CWORD_CWORD_CWORD_CWORD,
3263         /* 170      */ CWORD_CWORD_CWORD_CWORD,
3264         /* 171      */ CWORD_CWORD_CWORD_CWORD,
3265         /* 172      */ CWORD_CWORD_CWORD_CWORD,
3266         /* 173      */ CWORD_CWORD_CWORD_CWORD,
3267         /* 174      */ CWORD_CWORD_CWORD_CWORD,
3268         /* 175      */ CWORD_CWORD_CWORD_CWORD,
3269         /* 176      */ CWORD_CWORD_CWORD_CWORD,
3270         /* 177      */ CWORD_CWORD_CWORD_CWORD,
3271         /* 178      */ CWORD_CWORD_CWORD_CWORD,
3272         /* 179      */ CWORD_CWORD_CWORD_CWORD,
3273         /* 180      */ CWORD_CWORD_CWORD_CWORD,
3274         /* 181      */ CWORD_CWORD_CWORD_CWORD,
3275         /* 182      */ CWORD_CWORD_CWORD_CWORD,
3276         /* 183      */ CWORD_CWORD_CWORD_CWORD,
3277         /* 184      */ CWORD_CWORD_CWORD_CWORD,
3278         /* 185      */ CWORD_CWORD_CWORD_CWORD,
3279         /* 186      */ CWORD_CWORD_CWORD_CWORD,
3280         /* 187      */ CWORD_CWORD_CWORD_CWORD,
3281         /* 188      */ CWORD_CWORD_CWORD_CWORD,
3282         /* 189      */ CWORD_CWORD_CWORD_CWORD,
3283         /* 190      */ CWORD_CWORD_CWORD_CWORD,
3284         /* 191      */ CWORD_CWORD_CWORD_CWORD,
3285         /* 192      */ CWORD_CWORD_CWORD_CWORD,
3286         /* 193      */ CWORD_CWORD_CWORD_CWORD,
3287         /* 194      */ CWORD_CWORD_CWORD_CWORD,
3288         /* 195      */ CWORD_CWORD_CWORD_CWORD,
3289         /* 196      */ CWORD_CWORD_CWORD_CWORD,
3290         /* 197      */ CWORD_CWORD_CWORD_CWORD,
3291         /* 198      */ CWORD_CWORD_CWORD_CWORD,
3292         /* 199      */ CWORD_CWORD_CWORD_CWORD,
3293         /* 200      */ CWORD_CWORD_CWORD_CWORD,
3294         /* 201      */ CWORD_CWORD_CWORD_CWORD,
3295         /* 202      */ CWORD_CWORD_CWORD_CWORD,
3296         /* 203      */ CWORD_CWORD_CWORD_CWORD,
3297         /* 204      */ CWORD_CWORD_CWORD_CWORD,
3298         /* 205      */ CWORD_CWORD_CWORD_CWORD,
3299         /* 206      */ CWORD_CWORD_CWORD_CWORD,
3300         /* 207      */ CWORD_CWORD_CWORD_CWORD,
3301         /* 208      */ CWORD_CWORD_CWORD_CWORD,
3302         /* 209      */ CWORD_CWORD_CWORD_CWORD,
3303         /* 210      */ CWORD_CWORD_CWORD_CWORD,
3304         /* 211      */ CWORD_CWORD_CWORD_CWORD,
3305         /* 212      */ CWORD_CWORD_CWORD_CWORD,
3306         /* 213      */ CWORD_CWORD_CWORD_CWORD,
3307         /* 214      */ CWORD_CWORD_CWORD_CWORD,
3308         /* 215      */ CWORD_CWORD_CWORD_CWORD,
3309         /* 216      */ CWORD_CWORD_CWORD_CWORD,
3310         /* 217      */ CWORD_CWORD_CWORD_CWORD,
3311         /* 218      */ CWORD_CWORD_CWORD_CWORD,
3312         /* 219      */ CWORD_CWORD_CWORD_CWORD,
3313         /* 220      */ CWORD_CWORD_CWORD_CWORD,
3314         /* 221      */ CWORD_CWORD_CWORD_CWORD,
3315         /* 222      */ CWORD_CWORD_CWORD_CWORD,
3316         /* 223      */ CWORD_CWORD_CWORD_CWORD,
3317         /* 224      */ CWORD_CWORD_CWORD_CWORD,
3318         /* 225      */ CWORD_CWORD_CWORD_CWORD,
3319         /* 226      */ CWORD_CWORD_CWORD_CWORD,
3320         /* 227      */ CWORD_CWORD_CWORD_CWORD,
3321         /* 228      */ CWORD_CWORD_CWORD_CWORD,
3322         /* 229      */ CWORD_CWORD_CWORD_CWORD,
3323         /* 230      */ CWORD_CWORD_CWORD_CWORD,
3324         /* 231      */ CWORD_CWORD_CWORD_CWORD,
3325         /* 232      */ CWORD_CWORD_CWORD_CWORD,
3326         /* 233      */ CWORD_CWORD_CWORD_CWORD,
3327         /* 234      */ CWORD_CWORD_CWORD_CWORD,
3328         /* 235      */ CWORD_CWORD_CWORD_CWORD,
3329         /* 236      */ CWORD_CWORD_CWORD_CWORD,
3330         /* 237      */ CWORD_CWORD_CWORD_CWORD,
3331         /* 238      */ CWORD_CWORD_CWORD_CWORD,
3332         /* 239      */ CWORD_CWORD_CWORD_CWORD,
3333         /* 230      */ CWORD_CWORD_CWORD_CWORD,
3334         /* 241      */ CWORD_CWORD_CWORD_CWORD,
3335         /* 242      */ CWORD_CWORD_CWORD_CWORD,
3336         /* 243      */ CWORD_CWORD_CWORD_CWORD,
3337         /* 244      */ CWORD_CWORD_CWORD_CWORD,
3338         /* 245      */ CWORD_CWORD_CWORD_CWORD,
3339         /* 246      */ CWORD_CWORD_CWORD_CWORD,
3340         /* 247      */ CWORD_CWORD_CWORD_CWORD,
3341         /* 248      */ CWORD_CWORD_CWORD_CWORD,
3342         /* 249      */ CWORD_CWORD_CWORD_CWORD,
3343         /* 250      */ CWORD_CWORD_CWORD_CWORD,
3344         /* 251      */ CWORD_CWORD_CWORD_CWORD,
3345         /* 252      */ CWORD_CWORD_CWORD_CWORD,
3346         /* 253      */ CWORD_CWORD_CWORD_CWORD,
3347         /* 254      */ CWORD_CWORD_CWORD_CWORD,
3348         /* 255      */ CWORD_CWORD_CWORD_CWORD,
3349         /* PEOF */     CENDFILE_CENDFILE_CENDFILE_CENDFILE,
3350 # if ENABLE_ASH_ALIAS
3351         /* PEOA */     CSPCL_CIGN_CIGN_CIGN,
3352 # endif
3353 };
3354
3355 #if 1
3356 # define SIT(c, syntax) ((S_I_T[syntax_index_table[c]] >> ((syntax)*4)) & 0xf)
3357 #else /* debug version, caught one signed char bug */
3358 # define SIT(c, syntax) \
3359         ({ \
3360                 if ((c) < 0 || (c) > (PEOF + ENABLE_ASH_ALIAS)) \
3361                         bb_error_msg_and_die("line:%d c:%d", __LINE__, (c)); \
3362                 if ((syntax) < 0 || (syntax) > (2 + ENABLE_FEATURE_SH_MATH)) \
3363                         bb_error_msg_and_die("line:%d c:%d", __LINE__, (c)); \
3364                 ((S_I_T[syntax_index_table[c]] >> ((syntax)*4)) & 0xf); \
3365         })
3366 #endif
3367
3368 #endif  /* !USE_SIT_FUNCTION */
3369
3370
3371 /* ============ Alias handling */
3372
3373 #if ENABLE_ASH_ALIAS
3374
3375 #define ALIASINUSE 1
3376 #define ALIASDEAD  2
3377
3378 struct alias {
3379         struct alias *next;
3380         char *name;
3381         char *val;
3382         int flag;
3383 };
3384
3385
3386 static struct alias **atab; // [ATABSIZE];
3387 #define INIT_G_alias() do { \
3388         atab = xzalloc(ATABSIZE * sizeof(atab[0])); \
3389 } while (0)
3390
3391
3392 static struct alias **
3393 __lookupalias(const char *name)
3394 {
3395         unsigned int hashval;
3396         struct alias **app;
3397         const char *p;
3398         unsigned int ch;
3399
3400         p = name;
3401
3402         ch = (unsigned char)*p;
3403         hashval = ch << 4;
3404         while (ch) {
3405                 hashval += ch;
3406                 ch = (unsigned char)*++p;
3407         }
3408         app = &atab[hashval % ATABSIZE];
3409
3410         for (; *app; app = &(*app)->next) {
3411                 if (strcmp(name, (*app)->name) == 0) {
3412                         break;
3413                 }
3414         }
3415
3416         return app;
3417 }
3418
3419 static struct alias *
3420 lookupalias(const char *name, int check)
3421 {
3422         struct alias *ap = *__lookupalias(name);
3423
3424         if (check && ap && (ap->flag & ALIASINUSE))
3425                 return NULL;
3426         return ap;
3427 }
3428
3429 static struct alias *
3430 freealias(struct alias *ap)
3431 {
3432         struct alias *next;
3433
3434         if (ap->flag & ALIASINUSE) {
3435                 ap->flag |= ALIASDEAD;
3436                 return ap;
3437         }
3438
3439         next = ap->next;
3440         free(ap->name);
3441         free(ap->val);
3442         free(ap);
3443         return next;
3444 }
3445
3446 static void
3447 setalias(const char *name, const char *val)
3448 {
3449         struct alias *ap, **app;
3450
3451         app = __lookupalias(name);
3452         ap = *app;
3453         INT_OFF;
3454         if (ap) {
3455                 if (!(ap->flag & ALIASINUSE)) {
3456                         free(ap->val);
3457                 }
3458                 ap->val = ckstrdup(val);
3459                 ap->flag &= ~ALIASDEAD;
3460         } else {
3461                 /* not found */
3462                 ap = ckzalloc(sizeof(struct alias));
3463                 ap->name = ckstrdup(name);
3464                 ap->val = ckstrdup(val);
3465                 /*ap->flag = 0; - ckzalloc did it */
3466                 /*ap->next = NULL;*/
3467                 *app = ap;
3468         }
3469         INT_ON;
3470 }
3471
3472 static int
3473 unalias(const char *name)
3474 {
3475         struct alias **app;
3476
3477         app = __lookupalias(name);
3478
3479         if (*app) {
3480                 INT_OFF;
3481                 *app = freealias(*app);
3482                 INT_ON;
3483                 return 0;
3484         }
3485
3486         return 1;
3487 }
3488
3489 static void
3490 rmaliases(void)
3491 {
3492         struct alias *ap, **app;
3493         int i;
3494
3495         INT_OFF;
3496         for (i = 0; i < ATABSIZE; i++) {
3497                 app = &atab[i];
3498                 for (ap = *app; ap; ap = *app) {
3499                         *app = freealias(*app);
3500                         if (ap == *app) {
3501                                 app = &ap->next;
3502                         }
3503                 }
3504         }
3505         INT_ON;
3506 }
3507
3508 static void
3509 printalias(const struct alias *ap)
3510 {
3511         out1fmt("%s=%s\n", ap->name, single_quote(ap->val));
3512 }
3513
3514 /*
3515  * TODO - sort output
3516  */
3517 static int FAST_FUNC
3518 aliascmd(int argc UNUSED_PARAM, char **argv)
3519 {
3520         char *n, *v;
3521         int ret = 0;
3522         struct alias *ap;
3523
3524         if (!argv[1]) {
3525                 int i;
3526
3527                 for (i = 0; i < ATABSIZE; i++) {
3528                         for (ap = atab[i]; ap; ap = ap->next) {
3529                                 printalias(ap);
3530                         }
3531                 }
3532                 return 0;
3533         }
3534         while ((n = *++argv) != NULL) {
3535                 v = strchr(n+1, '=');
3536                 if (v == NULL) { /* n+1: funny ksh stuff */
3537                         ap = *__lookupalias(n);
3538                         if (ap == NULL) {
3539                                 fprintf(stderr, "%s: %s not found\n", "alias", n);
3540                                 ret = 1;
3541                         } else
3542                                 printalias(ap);
3543                 } else {
3544                         *v++ = '\0';
3545                         setalias(n, v);
3546                 }
3547         }
3548
3549         return ret;
3550 }
3551
3552 static int FAST_FUNC
3553 unaliascmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
3554 {
3555         int i;
3556
3557         while (nextopt("a") != '\0') {
3558                 rmaliases();
3559                 return 0;
3560         }
3561         for (i = 0; *argptr; argptr++) {
3562                 if (unalias(*argptr)) {
3563                         fprintf(stderr, "%s: %s not found\n", "unalias", *argptr);
3564                         i = 1;
3565                 }
3566         }
3567
3568         return i;
3569 }
3570
3571 #endif /* ASH_ALIAS */
3572
3573
3574 /* Mode argument to forkshell.  Don't change FORK_FG or FORK_BG. */
3575 #define FORK_FG    0
3576 #define FORK_BG    1
3577 #define FORK_NOJOB 2
3578
3579 /* mode flags for showjob(s) */
3580 #define SHOW_ONLY_PGID  0x01    /* show only pgid (jobs -p) */
3581 #define SHOW_PIDS       0x02    /* show individual pids, not just one line per job */
3582 #define SHOW_CHANGED    0x04    /* only jobs whose state has changed */
3583 #define SHOW_STDERR     0x08    /* print to stderr (else stdout) */
3584
3585 /*
3586  * A job structure contains information about a job.  A job is either a
3587  * single process or a set of processes contained in a pipeline.  In the
3588  * latter case, pidlist will be non-NULL, and will point to a -1 terminated
3589  * array of pids.
3590  */
3591 struct procstat {
3592         pid_t   ps_pid;         /* process id */
3593         int     ps_status;      /* last process status from wait() */
3594         char    *ps_cmd;        /* text of command being run */
3595 };
3596
3597 struct job {
3598         struct procstat ps0;    /* status of process */
3599         struct procstat *ps;    /* status of processes when more than one */
3600 #if JOBS
3601         int stopstatus;         /* status of a stopped job */
3602 #endif
3603         unsigned nprocs;        /* number of processes */
3604
3605 #define JOBRUNNING      0       /* at least one proc running */
3606 #define JOBSTOPPED      1       /* all procs are stopped */
3607 #define JOBDONE         2       /* all procs are completed */
3608         unsigned
3609                 state: 8,
3610 #if JOBS
3611                 sigint: 1,      /* job was killed by SIGINT */
3612                 jobctl: 1,      /* job running under job control */
3613 #endif
3614                 waited: 1,      /* true if this entry has been waited for */
3615                 used: 1,        /* true if this entry is in used */
3616                 changed: 1;     /* true if status has changed */
3617         struct job *prev_job;   /* previous job */
3618 };
3619
3620 static struct job *makejob(/*union node *,*/ int);
3621 static int forkshell(struct job *, union node *, int);
3622 static int waitforjob(struct job *);
3623
3624 #if !JOBS
3625 enum { doing_jobctl = 0 };
3626 #define setjobctl(on) do {} while (0)
3627 #else
3628 static smallint doing_jobctl; //references:8
3629 static void setjobctl(int);
3630 #endif
3631
3632 /*
3633  * Ignore a signal.
3634  */
3635 static void
3636 ignoresig(int signo)
3637 {
3638         /* Avoid unnecessary system calls. Is it already SIG_IGNed? */
3639         if (sigmode[signo - 1] != S_IGN && sigmode[signo - 1] != S_HARD_IGN) {
3640                 /* No, need to do it */
3641                 signal(signo, SIG_IGN);
3642         }
3643         sigmode[signo - 1] = S_HARD_IGN;
3644 }
3645
3646 /*
3647  * Only one usage site - in setsignal()
3648  */
3649 static void
3650 signal_handler(int signo)
3651 {
3652         if (signo == SIGCHLD) {
3653                 got_sigchld = 1;
3654                 if (!trap[SIGCHLD])
3655                         return;
3656         }
3657
3658         gotsig[signo - 1] = 1;
3659         pending_sig = signo;
3660
3661         if (signo == SIGINT && !trap[SIGINT]) {
3662                 if (!suppress_int) {
3663                         pending_sig = 0;
3664                         raise_interrupt(); /* does not return */
3665                 }
3666                 pending_int = 1;
3667         }
3668 }
3669
3670 /*
3671  * Set the signal handler for the specified signal.  The routine figures
3672  * out what it should be set to.
3673  */
3674 static void
3675 setsignal(int signo)
3676 {
3677         char *t;
3678         char cur_act, new_act;
3679         struct sigaction act;
3680
3681         t = trap[signo];
3682         new_act = S_DFL;
3683         if (t != NULL) { /* trap for this sig is set */
3684                 new_act = S_CATCH;
3685                 if (t[0] == '\0') /* trap is "": ignore this sig */
3686                         new_act = S_IGN;
3687         }
3688
3689         if (rootshell && new_act == S_DFL) {
3690                 switch (signo) {
3691                 case SIGINT:
3692                         if (iflag || minusc || sflag == 0)
3693                                 new_act = S_CATCH;
3694                         break;
3695                 case SIGQUIT:
3696 #if DEBUG
3697                         if (debug)
3698                                 break;
3699 #endif
3700                         /* man bash:
3701                          * "In all cases, bash ignores SIGQUIT. Non-builtin
3702                          * commands run by bash have signal handlers
3703                          * set to the values inherited by the shell
3704                          * from its parent". */
3705                         new_act = S_IGN;
3706                         break;
3707                 case SIGTERM:
3708                         if (iflag)
3709                                 new_act = S_IGN;
3710                         break;
3711 #if JOBS
3712                 case SIGTSTP:
3713                 case SIGTTOU:
3714                         if (mflag)
3715                                 new_act = S_IGN;
3716                         break;
3717 #endif
3718                 }
3719         }
3720         /* if !rootshell, we reset SIGQUIT to DFL,
3721          * whereas we have to restore it to what shell got on entry.
3722          * This is handled by the fact that if signal was IGNored on entry,
3723          * then cur_act is S_HARD_IGN and we never change its sigaction
3724          * (see code below).
3725          */
3726
3727         if (signo == SIGCHLD)
3728                 new_act = S_CATCH;
3729
3730         t = &sigmode[signo - 1];
3731         cur_act = *t;
3732         if (cur_act == 0) {
3733                 /* current setting is not yet known */
3734                 if (sigaction(signo, NULL, &act)) {
3735                         /* pretend it worked; maybe we should give a warning,
3736                          * but other shells don't. We don't alter sigmode,
3737                          * so we retry every time.
3738                          * btw, in Linux it never fails. --vda */
3739                         return;
3740                 }
3741                 if (act.sa_handler == SIG_IGN) {
3742                         cur_act = S_HARD_IGN;
3743                         if (mflag
3744                          && (signo == SIGTSTP || signo == SIGTTIN || signo == SIGTTOU)
3745                         ) {
3746                                 cur_act = S_IGN;   /* don't hard ignore these */
3747                         }
3748                 }
3749                 if (act.sa_handler == SIG_DFL && new_act == S_DFL) {
3750                         /* installing SIG_DFL over SIG_DFL is a no-op */
3751                         /* saves one sigaction call in each "sh -c SCRIPT" invocation */
3752                         *t = S_DFL;
3753                         return;
3754                 }
3755         }
3756         if (cur_act == S_HARD_IGN || cur_act == new_act)
3757                 return;
3758
3759         *t = new_act;
3760
3761         act.sa_handler = SIG_DFL;
3762         switch (new_act) {
3763         case S_CATCH:
3764                 act.sa_handler = signal_handler;
3765                 break;
3766         case S_IGN:
3767                 act.sa_handler = SIG_IGN;
3768                 break;
3769         }
3770         /* flags and mask matter only if !DFL and !IGN, but we do it
3771          * for all cases for more deterministic behavior:
3772          */
3773         act.sa_flags = 0; //TODO: why not SA_RESTART?
3774         sigfillset(&act.sa_mask);
3775
3776         sigaction_set(signo, &act);
3777 }
3778
3779 /* mode flags for set_curjob */
3780 #define CUR_DELETE 2
3781 #define CUR_RUNNING 1
3782 #define CUR_STOPPED 0
3783
3784 #if JOBS
3785 /* pgrp of shell on invocation */
3786 static int initialpgrp; //references:2
3787 static int ttyfd = -1; //5
3788 #endif
3789 /* array of jobs */
3790 static struct job *jobtab; //5
3791 /* size of array */
3792 static unsigned njobs; //4
3793 /* current job */
3794 static struct job *curjob; //lots
3795
3796 #if 0
3797 /* Bash has a feature: it restores termios after a successful wait for
3798  * a foreground job which had at least one stopped or sigkilled member.
3799  * The probable rationale is that SIGSTOP and SIGKILL can preclude task from
3800  * properly restoring tty state. Should we do this too?
3801  * A reproducer: ^Z an interactive python:
3802  *
3803  * # python
3804  * Python 2.7.12 (...)
3805  * >>> ^Z
3806  *      { python leaves tty in -icanon -echo state. We do survive that... }
3807  *  [1]+  Stopped                    python
3808  *      { ...however, next program (python #2) does not survive it well: }
3809  * # python
3810  * Python 2.7.12 (...)
3811  * >>> Traceback (most recent call last):
3812  *      { above, I typed "qwerty<CR>", but -echo state is still in effect }
3813  *   File "<stdin>", line 1, in <module>
3814  * NameError: name 'qwerty' is not defined
3815  *
3816  * The implementation below is modeled on bash code and seems to work.
3817  * However, I'm not sure we should do this. For one: what if I'd fg
3818  * the stopped python instead? It'll be confused by "restored" tty state.
3819  */
3820 static struct termios shell_tty_info;
3821 static void
3822 get_tty_state(void)
3823 {
3824         if (rootshell && ttyfd >= 0)
3825                 tcgetattr(ttyfd, &shell_tty_info);
3826 }
3827 static void
3828 set_tty_state(void)
3829 {
3830         /* if (rootshell) - caller ensures this */
3831         if (ttyfd >= 0)
3832                 tcsetattr(ttyfd, TCSADRAIN, &shell_tty_info);
3833 }
3834 static int
3835 job_signal_status(struct job *jp)
3836 {
3837         int status;
3838         unsigned i;
3839         struct procstat *ps = jp->ps;
3840         for (i = 0; i < jp->nprocs; i++) {
3841                 status = ps[i].ps_status;
3842                 if (WIFSIGNALED(status) || WIFSTOPPED(status))
3843                         return status;
3844         }
3845         return 0;
3846 }
3847 static void
3848 restore_tty_if_stopped_or_signaled(struct job *jp)
3849 {
3850 //TODO: check what happens if we come from waitforjob() in expbackq()
3851         if (rootshell) {
3852                 int s = job_signal_status(jp);
3853                 if (s) /* WIFSIGNALED(s) || WIFSTOPPED(s) */
3854                         set_tty_state();
3855         }
3856 }
3857 #else
3858 # define get_tty_state() ((void)0)
3859 # define restore_tty_if_stopped_or_signaled(jp) ((void)0)
3860 #endif
3861
3862 static void
3863 set_curjob(struct job *jp, unsigned mode)
3864 {
3865         struct job *jp1;
3866         struct job **jpp, **curp;
3867
3868         /* first remove from list */
3869         jpp = curp = &curjob;
3870         while (1) {
3871                 jp1 = *jpp;
3872                 if (jp1 == jp)
3873                         break;
3874                 jpp = &jp1->prev_job;
3875         }
3876         *jpp = jp1->prev_job;
3877
3878         /* Then re-insert in correct position */
3879         jpp = curp;
3880         switch (mode) {
3881         default:
3882 #if DEBUG
3883                 abort();
3884 #endif
3885         case CUR_DELETE:
3886                 /* job being deleted */
3887                 break;
3888         case CUR_RUNNING:
3889                 /* newly created job or backgrounded job,
3890                  * put after all stopped jobs.
3891                  */
3892                 while (1) {
3893                         jp1 = *jpp;
3894 #if JOBS
3895                         if (!jp1 || jp1->state != JOBSTOPPED)
3896 #endif
3897                                 break;
3898                         jpp = &jp1->prev_job;
3899                 }
3900                 /* FALLTHROUGH */
3901 #if JOBS
3902         case CUR_STOPPED:
3903 #endif
3904                 /* newly stopped job - becomes curjob */
3905                 jp->prev_job = *jpp;
3906                 *jpp = jp;
3907                 break;
3908         }
3909 }
3910
3911 #if JOBS || DEBUG
3912 static int
3913 jobno(const struct job *jp)
3914 {
3915         return jp - jobtab + 1;
3916 }
3917 #endif
3918
3919 /*
3920  * Convert a job name to a job structure.
3921  */
3922 #if !JOBS
3923 #define getjob(name, getctl) getjob(name)
3924 #endif
3925 static struct job *
3926 getjob(const char *name, int getctl)
3927 {
3928         struct job *jp;
3929         struct job *found;
3930         const char *err_msg = "%s: no such job";
3931         unsigned num;
3932         int c;
3933         const char *p;
3934         char *(*match)(const char *, const char *);
3935
3936         jp = curjob;
3937         p = name;
3938         if (!p)
3939                 goto currentjob;
3940
3941         if (*p != '%')
3942                 goto err;
3943
3944         c = *++p;
3945         if (!c)
3946                 goto currentjob;
3947
3948         if (!p[1]) {
3949                 if (c == '+' || c == '%') {
3950  currentjob:
3951                         err_msg = "No current job";
3952                         goto check;
3953                 }
3954                 if (c == '-') {
3955                         if (jp)
3956                                 jp = jp->prev_job;
3957                         err_msg = "No previous job";
3958  check:
3959                         if (!jp)
3960                                 goto err;
3961                         goto gotit;
3962                 }
3963         }
3964
3965         if (is_number(p)) {
3966                 num = atoi(p);
3967                 if (num > 0 && num <= njobs) {
3968                         jp = jobtab + num - 1;
3969                         if (jp->used)
3970                                 goto gotit;
3971                         goto err;
3972                 }
3973         }
3974
3975         match = prefix;
3976         if (*p == '?') {
3977                 match = strstr;
3978                 p++;
3979         }
3980
3981         found = NULL;
3982         while (jp) {
3983                 if (match(jp->ps[0].ps_cmd, p)) {
3984                         if (found)
3985                                 goto err;
3986                         found = jp;
3987                         err_msg = "%s: ambiguous";
3988                 }
3989                 jp = jp->prev_job;
3990         }
3991         if (!found)
3992                 goto err;
3993         jp = found;
3994
3995  gotit:
3996 #if JOBS
3997         err_msg = "job %s not created under job control";
3998         if (getctl && jp->jobctl == 0)
3999                 goto err;
4000 #endif
4001         return jp;
4002  err:
4003         ash_msg_and_raise_error(err_msg, name);
4004 }
4005
4006 /*
4007  * Mark a job structure as unused.
4008  */
4009 static void
4010 freejob(struct job *jp)
4011 {
4012         struct procstat *ps;
4013         int i;
4014
4015         INT_OFF;
4016         for (i = jp->nprocs, ps = jp->ps; --i >= 0; ps++) {
4017                 if (ps->ps_cmd != nullstr)
4018                         free(ps->ps_cmd);
4019         }
4020         if (jp->ps != &jp->ps0)
4021                 free(jp->ps);
4022         jp->used = 0;
4023         set_curjob(jp, CUR_DELETE);
4024         INT_ON;
4025 }
4026
4027 #if JOBS
4028 static void
4029 xtcsetpgrp(int fd, pid_t pgrp)
4030 {
4031         if (tcsetpgrp(fd, pgrp))
4032                 ash_msg_and_raise_perror("can't set tty process group");
4033 }
4034
4035 /*
4036  * Turn job control on and off.
4037  *
4038  * Note:  This code assumes that the third arg to ioctl is a character
4039  * pointer, which is true on Berkeley systems but not System V.  Since
4040  * System V doesn't have job control yet, this isn't a problem now.
4041  *
4042  * Called with interrupts off.
4043  */
4044 static void
4045 setjobctl(int on)
4046 {
4047         int fd;
4048         int pgrp;
4049
4050         if (on == doing_jobctl || rootshell == 0)
4051                 return;
4052         if (on) {
4053                 int ofd;
4054                 ofd = fd = open(_PATH_TTY, O_RDWR);
4055                 if (fd < 0) {
4056         /* BTW, bash will try to open(ttyname(0)) if open("/dev/tty") fails.
4057          * That sometimes helps to acquire controlling tty.
4058          * Obviously, a workaround for bugs when someone
4059          * failed to provide a controlling tty to bash! :) */
4060                         fd = 2;
4061                         while (!isatty(fd))
4062                                 if (--fd < 0)
4063                                         goto out;
4064                 }
4065                 /* fd is a tty at this point */
4066                 fd = fcntl(fd, F_DUPFD_CLOEXEC, 10);
4067                 if (ofd >= 0) /* if it is "/dev/tty", close. If 0/1/2, don't */
4068                         close(ofd);
4069                 if (fd < 0)
4070                         goto out; /* F_DUPFD failed */
4071                 if (F_DUPFD_CLOEXEC == F_DUPFD) /* if old libc (w/o F_DUPFD_CLOEXEC) */
4072                         close_on_exec_on(fd);
4073                 while (1) { /* while we are in the background */
4074                         pgrp = tcgetpgrp(fd);
4075                         if (pgrp < 0) {
4076  out:
4077                                 ash_msg("can't access tty; job control turned off");
4078                                 mflag = on = 0;
4079                                 goto close;
4080                         }
4081                         if (pgrp == getpgrp())
4082                                 break;
4083                         killpg(0, SIGTTIN);
4084                 }
4085                 initialpgrp = pgrp;
4086
4087                 setsignal(SIGTSTP);
4088                 setsignal(SIGTTOU);
4089                 setsignal(SIGTTIN);
4090                 pgrp = rootpid;
4091                 setpgid(0, pgrp);
4092                 xtcsetpgrp(fd, pgrp);
4093         } else {
4094                 /* turning job control off */
4095                 fd = ttyfd;
4096                 pgrp = initialpgrp;
4097                 /* was xtcsetpgrp, but this can make exiting ash
4098                  * loop forever if pty is already deleted */
4099                 tcsetpgrp(fd, pgrp);
4100                 setpgid(0, pgrp);
4101                 setsignal(SIGTSTP);
4102                 setsignal(SIGTTOU);
4103                 setsignal(SIGTTIN);
4104  close:
4105                 if (fd >= 0)
4106                         close(fd);
4107                 fd = -1;
4108         }
4109         ttyfd = fd;
4110         doing_jobctl = on;
4111 }
4112
4113 static int FAST_FUNC
4114 killcmd(int argc, char **argv)
4115 {
4116         if (argv[1] && strcmp(argv[1], "-l") != 0) {
4117                 int i = 1;
4118                 do {
4119                         if (argv[i][0] == '%') {
4120                                 /*
4121                                  * "kill %N" - job kill
4122                                  * Converting to pgrp / pid kill
4123                                  */
4124                                 struct job *jp;
4125                                 char *dst;
4126                                 int j, n;
4127
4128                                 jp = getjob(argv[i], 0);
4129                                 /*
4130                                  * In jobs started under job control, we signal
4131                                  * entire process group by kill -PGRP_ID.
4132                                  * This happens, f.e., in interactive shell.
4133                                  *
4134                                  * Otherwise, we signal each child via
4135                                  * kill PID1 PID2 PID3.
4136                                  * Testcases:
4137                                  * sh -c 'sleep 1|sleep 1 & kill %1'
4138                                  * sh -c 'true|sleep 2 & sleep 1; kill %1'
4139                                  * sh -c 'true|sleep 1 & sleep 2; kill %1'
4140                                  */
4141                                 n = jp->nprocs; /* can't be 0 (I hope) */
4142                                 if (jp->jobctl)
4143                                         n = 1;
4144                                 dst = alloca(n * sizeof(int)*4);
4145                                 argv[i] = dst;
4146                                 for (j = 0; j < n; j++) {
4147                                         struct procstat *ps = &jp->ps[j];
4148                                         /* Skip non-running and not-stopped members
4149                                          * (i.e. dead members) of the job
4150                                          */
4151                                         if (ps->ps_status != -1 && !WIFSTOPPED(ps->ps_status))
4152                                                 continue;
4153                                         /*
4154                                          * kill_main has matching code to expect
4155                                          * leading space. Needed to not confuse
4156                                          * negative pids with "kill -SIGNAL_NO" syntax
4157                                          */
4158                                         dst += sprintf(dst, jp->jobctl ? " -%u" : " %u", (int)ps->ps_pid);
4159                                 }
4160                                 *dst = '\0';
4161                         }
4162                 } while (argv[++i]);
4163         }
4164         return kill_main(argc, argv);
4165 }
4166
4167 static void
4168 showpipe(struct job *jp /*, FILE *out*/)
4169 {
4170         struct procstat *ps;
4171         struct procstat *psend;
4172
4173         psend = jp->ps + jp->nprocs;
4174         for (ps = jp->ps + 1; ps < psend; ps++)
4175                 printf(" | %s", ps->ps_cmd);
4176         newline_and_flush(stdout);
4177         flush_stdout_stderr();
4178 }
4179
4180
4181 static int
4182 restartjob(struct job *jp, int mode)
4183 {
4184         struct procstat *ps;
4185         int i;
4186         int status;
4187         pid_t pgid;
4188
4189         INT_OFF;
4190         if (jp->state == JOBDONE)
4191                 goto out;
4192         jp->state = JOBRUNNING;
4193         pgid = jp->ps[0].ps_pid;
4194         if (mode == FORK_FG) {
4195                 get_tty_state();
4196                 xtcsetpgrp(ttyfd, pgid);
4197         }
4198         killpg(pgid, SIGCONT);
4199         ps = jp->ps;
4200         i = jp->nprocs;
4201         do {
4202                 if (WIFSTOPPED(ps->ps_status)) {
4203                         ps->ps_status = -1;
4204                 }
4205                 ps++;
4206         } while (--i);
4207  out:
4208         status = (mode == FORK_FG) ? waitforjob(jp) : 0;
4209         INT_ON;
4210         return status;
4211 }
4212
4213 static int FAST_FUNC
4214 fg_bgcmd(int argc UNUSED_PARAM, char **argv)
4215 {
4216         struct job *jp;
4217         int mode;
4218         int retval;
4219
4220         mode = (**argv == 'f') ? FORK_FG : FORK_BG;
4221         nextopt(nullstr);
4222         argv = argptr;
4223         do {
4224                 jp = getjob(*argv, 1);
4225                 if (mode == FORK_BG) {
4226                         set_curjob(jp, CUR_RUNNING);
4227                         printf("[%d] ", jobno(jp));
4228                 }
4229                 out1str(jp->ps[0].ps_cmd);
4230                 showpipe(jp /*, stdout*/);
4231                 retval = restartjob(jp, mode);
4232         } while (*argv && *++argv);
4233         return retval;
4234 }
4235 #endif
4236
4237 static int
4238 sprint_status48(char *os, int status, int sigonly)
4239 {
4240         char *s = os;
4241         int st;
4242
4243         if (!WIFEXITED(status)) {
4244 #if JOBS
4245                 if (WIFSTOPPED(status))
4246                         st = WSTOPSIG(status);
4247                 else
4248 #endif
4249                         st = WTERMSIG(status);
4250                 if (sigonly) {
4251                         if (st == SIGINT || st == SIGPIPE)
4252                                 goto out;
4253 #if JOBS
4254                         if (WIFSTOPPED(status))
4255                                 goto out;
4256 #endif
4257                 }
4258                 st &= 0x7f;
4259 //TODO: use bbox's get_signame? strsignal adds ~600 bytes to text+rodata
4260                 //s = stpncpy(s, strsignal(st), 32); //not all libc have stpncpy()
4261                 s += fmtstr(s, 32, strsignal(st));
4262                 if (WCOREDUMP(status)) {
4263                         s = stpcpy(s, " (core dumped)");
4264                 }
4265         } else if (!sigonly) {
4266                 st = WEXITSTATUS(status);
4267                 s += fmtstr(s, 16, (st ? "Done(%d)" : "Done"), st);
4268         }
4269  out:
4270         return s - os;
4271 }
4272
4273 static int
4274 wait_block_or_sig(int *status)
4275 {
4276         int pid;
4277
4278         do {
4279                 sigset_t mask;
4280
4281                 /* Poll all children for changes in their state */
4282                 got_sigchld = 0;
4283                 /* if job control is active, accept stopped processes too */
4284                 pid = waitpid(-1, status, doing_jobctl ? (WNOHANG|WUNTRACED) : WNOHANG);
4285                 if (pid != 0)
4286                         break; /* Error (e.g. EINTR, ECHILD) or pid */
4287
4288                 /* Children exist, but none are ready. Sleep until interesting signal */
4289 #if 1
4290                 sigfillset(&mask);
4291                 sigprocmask2(SIG_SETMASK, &mask); /* mask is updated */
4292                 while (!got_sigchld && !pending_sig) {
4293                         sigsuspend(&mask);
4294                         /* ^^^ add "sigdelset(&mask, SIGCHLD);" before sigsuspend
4295                          * to make sure SIGCHLD is not masked off?
4296                          * It was reported that this:
4297                          *      fn() { : | return; }
4298                          *      shopt -s lastpipe
4299                          *      fn
4300                          *      exec ash SCRIPT
4301                          * under bash 4.4.23 runs SCRIPT with SIGCHLD masked,
4302                          * making "wait" commands in SCRIPT block forever.
4303                          */
4304                 }
4305                 sigprocmask(SIG_SETMASK, &mask, NULL);
4306 #else /* unsafe: a signal can set pending_sig after check, but before pause() */
4307                 while (!got_sigchld && !pending_sig)
4308                         pause();
4309 #endif
4310
4311                 /* If it was SIGCHLD, poll children again */
4312         } while (got_sigchld);
4313
4314         return pid;
4315 }
4316
4317 #define DOWAIT_NONBLOCK 0
4318 #define DOWAIT_BLOCK    1
4319 #define DOWAIT_BLOCK_OR_SIG 2
4320 #if BASH_WAIT_N
4321 # define DOWAIT_JOBSTATUS 0x10   /* OR this to get job's exitstatus instead of pid */
4322 #endif
4323
4324 static int
4325 waitone(int block, struct job *job)
4326 {
4327         int pid;
4328         int status;
4329         struct job *jp;
4330         struct job *thisjob;
4331 #if BASH_WAIT_N
4332         bool want_jobexitstatus = (block & DOWAIT_JOBSTATUS);
4333         block = (block & ~DOWAIT_JOBSTATUS);
4334 #endif
4335
4336         TRACE(("dowait(0x%x) called\n", block));
4337
4338         /* It's wrong to call waitpid() outside of INT_OFF region:
4339          * signal can arrive just after syscall return and handler can
4340          * longjmp away, losing stop/exit notification processing.
4341          * Thus, for "jobs" builtin, and for waiting for a fg job,
4342          * we call waitpid() (blocking or non-blocking) inside INT_OFF.
4343          *
4344          * However, for "wait" builtin it is wrong to simply call waitpid()
4345          * in INT_OFF region: "wait" needs to wait for any running job
4346          * to change state, but should exit on any trap too.
4347          * In INT_OFF region, a signal just before syscall entry can set
4348          * pending_sig variables, but we can't check them, and we would
4349          * either enter a sleeping waitpid() (BUG), or need to busy-loop.
4350          *
4351          * Because of this, we run inside INT_OFF, but use a special routine
4352          * which combines waitpid() and sigsuspend().
4353          * This is the reason why we need to have a handler for SIGCHLD:
4354          * SIG_DFL handler does not wake sigsuspend().
4355          */
4356         INT_OFF;
4357         if (block == DOWAIT_BLOCK_OR_SIG) {
4358                 pid = wait_block_or_sig(&status);
4359         } else {
4360                 int wait_flags = 0;
4361                 if (block == DOWAIT_NONBLOCK)
4362                         wait_flags = WNOHANG;
4363                 /* if job control is active, accept stopped processes too */
4364                 if (doing_jobctl)
4365                         wait_flags |= WUNTRACED;
4366                 /* NB: _not_ safe_waitpid, we need to detect EINTR */
4367                 pid = waitpid(-1, &status, wait_flags);
4368         }
4369         TRACE(("wait returns pid=%d, status=0x%x, errno=%d(%s)\n",
4370                                 pid, status, errno, strerror(errno)));
4371         thisjob = NULL;
4372         if (pid <= 0)
4373                 goto out;
4374
4375         for (jp = curjob; jp; jp = jp->prev_job) {
4376                 int jobstate;
4377                 struct procstat *ps;
4378                 struct procstat *psend;
4379                 if (jp->state == JOBDONE)
4380                         continue;
4381                 jobstate = JOBDONE;
4382                 ps = jp->ps;
4383                 psend = ps + jp->nprocs;
4384                 do {
4385                         if (ps->ps_pid == pid) {
4386                                 TRACE(("Job %d: changing status of proc %d "
4387                                         "from 0x%x to 0x%x\n",
4388                                         jobno(jp), pid, ps->ps_status, status));
4389                                 ps->ps_status = status;
4390                                 thisjob = jp;
4391                         }
4392                         if (ps->ps_status == -1)
4393                                 jobstate = JOBRUNNING;
4394 #if JOBS
4395                         if (jobstate == JOBRUNNING)
4396                                 continue;
4397                         if (WIFSTOPPED(ps->ps_status)) {
4398                                 jp->stopstatus = ps->ps_status;
4399                                 jobstate = JOBSTOPPED;
4400                         }
4401 #endif
4402                 } while (++ps < psend);
4403                 if (!thisjob)
4404                         continue;
4405
4406                 /* Found the job where one of its processes changed its state.
4407                  * Is there at least one live and running process in this job? */
4408                 if (jobstate != JOBRUNNING) {
4409                         /* No. All live processes in the job are stopped
4410                          * (JOBSTOPPED) or there are no live processes (JOBDONE)
4411                          */
4412                         thisjob->changed = 1;
4413                         if (thisjob->state != jobstate) {
4414                                 TRACE(("Job %d: changing state from %d to %d\n",
4415                                         jobno(thisjob), thisjob->state, jobstate));
4416                                 thisjob->state = jobstate;
4417 #if JOBS
4418                                 if (jobstate == JOBSTOPPED)
4419                                         set_curjob(thisjob, CUR_STOPPED);
4420 #endif
4421                         }
4422                 }
4423                 goto out;
4424         }
4425         /* The process wasn't found in job list */
4426  out:
4427         INT_ON;
4428
4429 #if BASH_WAIT_N
4430         if (want_jobexitstatus) {
4431                 pid = -1;
4432                 if (thisjob && thisjob->state == JOBDONE)
4433                         pid = thisjob->ps[thisjob->nprocs - 1].ps_status;
4434         }
4435 #endif
4436         if (thisjob && thisjob == job) {
4437                 char s[48 + 1];
4438                 int len;
4439
4440                 len = sprint_status48(s, status, 1);
4441                 if (len) {
4442                         s[len] = '\n';
4443                         s[len + 1] = '\0';
4444                         out2str(s);
4445                 }
4446         }
4447         return pid;
4448 }
4449
4450 static int
4451 dowait(int block, struct job *jp)
4452 {
4453         int pid = block == DOWAIT_NONBLOCK ? got_sigchld : 1;
4454
4455         while (jp ? jp->state == JOBRUNNING : pid > 0) {
4456                 if (!jp)
4457                         got_sigchld = 0;
4458                 pid = waitone(block, jp);
4459         }
4460
4461         return pid;
4462 }
4463
4464 #if JOBS
4465 static void
4466 showjob(struct job *jp, int mode)
4467 {
4468         struct procstat *ps;
4469         struct procstat *psend;
4470         int col;
4471         int indent_col;
4472         char s[16 + 16 + 48];
4473         FILE *out = (mode & SHOW_STDERR ? stderr : stdout);
4474
4475         ps = jp->ps;
4476
4477         if (mode & SHOW_ONLY_PGID) { /* jobs -p */
4478                 /* just output process (group) id of pipeline */
4479                 fprintf(out, "%d\n", ps->ps_pid);
4480                 return;
4481         }
4482
4483         col = fmtstr(s, 16, "[%d]   ", jobno(jp));
4484         indent_col = col;
4485
4486         if (jp == curjob)
4487                 s[col - 3] = '+';
4488         else if (curjob && jp == curjob->prev_job)
4489                 s[col - 3] = '-';
4490
4491         if (mode & SHOW_PIDS)
4492                 col += fmtstr(s + col, 16, "%d ", ps->ps_pid);
4493
4494         psend = ps + jp->nprocs;
4495
4496         if (jp->state == JOBRUNNING) {
4497                 strcpy(s + col, "Running");
4498                 col += sizeof("Running") - 1;
4499         } else {
4500                 int status = psend[-1].ps_status;
4501                 if (jp->state == JOBSTOPPED)
4502                         status = jp->stopstatus;
4503                 col += sprint_status48(s + col, status, 0);
4504         }
4505         /* By now, "[JOBID]*  [maybe PID] STATUS" is printed */
4506
4507         /* This loop either prints "<cmd1> | <cmd2> | <cmd3>" line
4508          * or prints several "PID             | <cmdN>" lines,
4509          * depending on SHOW_PIDS bit.
4510          * We do not print status of individual processes
4511          * between PID and <cmdN>. bash does it, but not very well:
4512          * first line shows overall job status, not process status,
4513          * making it impossible to know 1st process status.
4514          */
4515         goto start;
4516         do {
4517                 /* for each process */
4518                 s[0] = '\0';
4519                 col = 33;
4520                 if (mode & SHOW_PIDS)
4521                         col = fmtstr(s, 48, "\n%*c%d ", indent_col, ' ', ps->ps_pid) - 1;
4522  start:
4523                 fprintf(out, "%s%*c%s%s",
4524                                 s,
4525                                 33 - col >= 0 ? 33 - col : 0, ' ',
4526                                 ps == jp->ps ? "" : "| ",
4527                                 ps->ps_cmd
4528                 );
4529         } while (++ps != psend);
4530         newline_and_flush(out);
4531
4532         jp->changed = 0;
4533
4534         if (jp->state == JOBDONE) {
4535                 TRACE(("showjob: freeing job %d\n", jobno(jp)));
4536                 freejob(jp);
4537         }
4538 }
4539
4540 /*
4541  * Print a list of jobs.  If "change" is nonzero, only print jobs whose
4542  * statuses have changed since the last call to showjobs.
4543  */
4544 static void
4545 showjobs(int mode)
4546 {
4547         struct job *jp;
4548
4549         TRACE(("showjobs(0x%x) called\n", mode));
4550
4551         /* Handle all finished jobs */
4552         dowait(DOWAIT_NONBLOCK, NULL);
4553
4554         for (jp = curjob; jp; jp = jp->prev_job) {
4555                 if (!(mode & SHOW_CHANGED) || jp->changed) {
4556                         showjob(jp, mode);
4557                 }
4558         }
4559 }
4560
4561 static int FAST_FUNC
4562 jobscmd(int argc UNUSED_PARAM, char **argv)
4563 {
4564         int mode, m;
4565
4566         mode = 0;
4567         while ((m = nextopt("lp")) != '\0') {
4568                 if (m == 'l')
4569                         mode |= SHOW_PIDS;
4570                 else
4571                         mode |= SHOW_ONLY_PGID;
4572         }
4573
4574         argv = argptr;
4575         if (*argv) {
4576                 do
4577                         showjob(getjob(*argv, 0), mode);
4578                 while (*++argv);
4579         } else {
4580                 showjobs(mode);
4581         }
4582
4583         return 0;
4584 }
4585 #endif /* JOBS */
4586
4587 /* Called only on finished or stopped jobs (no members are running) */
4588 static int
4589 getstatus(struct job *job)
4590 {
4591         int status;
4592         int retval;
4593         struct procstat *ps;
4594
4595         /* Fetch last member's status */
4596         ps = job->ps + job->nprocs - 1;
4597         status = ps->ps_status;
4598         if (pipefail) {
4599                 /* "set -o pipefail" mode: use last _nonzero_ status */
4600                 while (status == 0 && --ps >= job->ps)
4601                         status = ps->ps_status;
4602         }
4603
4604         retval = WEXITSTATUS(status);
4605         if (!WIFEXITED(status)) {
4606 #if JOBS
4607                 retval = WSTOPSIG(status);
4608                 if (!WIFSTOPPED(status))
4609 #endif
4610                 {
4611                         /* XXX: limits number of signals */
4612                         retval = WTERMSIG(status);
4613 #if JOBS
4614                         if (retval == SIGINT)
4615                                 job->sigint = 1;
4616 #endif
4617                 }
4618                 retval += 128;
4619         }
4620         TRACE(("getstatus: job %d, nproc %d, status 0x%x, retval 0x%x\n",
4621                 jobno(job), job->nprocs, status, retval));
4622         return retval;
4623 }
4624
4625 static int FAST_FUNC
4626 waitcmd(int argc UNUSED_PARAM, char **argv)
4627 {
4628         struct job *job;
4629         int retval;
4630         struct job *jp;
4631 #if BASH_WAIT_N
4632         int status;
4633         char one = nextopt("n");
4634 #else
4635         nextopt(nullstr);
4636 #endif
4637         retval = 0;
4638
4639         argv = argptr;
4640         if (!argv[0]) {
4641                 /* wait for all jobs / one job if -n */
4642                 for (;;) {
4643                         jp = curjob;
4644 #if BASH_WAIT_N
4645                         if (one && !jp)
4646                                 /* exitcode of "wait -n" with nothing to wait for is 127, not 0 */
4647                                 retval = 127;
4648 #endif
4649                         while (1) {
4650                                 if (!jp) /* no running procs */
4651                                         goto ret;
4652                                 if (jp->state == JOBRUNNING)
4653                                         break;
4654                                 jp->waited = 1;
4655                                 jp = jp->prev_job;
4656                         }
4657         /* man bash:
4658          * "When bash is waiting for an asynchronous command via
4659          * the wait builtin, the reception of a signal for which a trap
4660          * has been set will cause the wait builtin to return immediately
4661          * with an exit status greater than 128, immediately after which
4662          * the trap is executed."
4663          */
4664 #if BASH_WAIT_N
4665                         status = dowait(DOWAIT_BLOCK_OR_SIG | DOWAIT_JOBSTATUS, NULL);
4666 #else
4667                         dowait(DOWAIT_BLOCK_OR_SIG, NULL);
4668 #endif
4669                         /* if child sends us a signal *and immediately exits*,
4670                          * dowait() returns pid > 0. Check this case,
4671                          * not "if (dowait() < 0)"!
4672                          */
4673                         if (pending_sig)
4674                                 goto sigout;
4675 #if BASH_WAIT_N
4676                         if (one) {
4677                                 /* wait -n waits for one _job_, not one _process_.
4678                                  *  date; sleep 3 & sleep 2 | sleep 1 & wait -n; date
4679                                  * should wait for 2 seconds. Not 1 or 3.
4680                                  */
4681                                 if (status != -1 && !WIFSTOPPED(status)) {
4682                                         retval = WEXITSTATUS(status);
4683                                         if (WIFSIGNALED(status))
4684                                                 retval = WTERMSIG(status) + 128;
4685                                         goto ret;
4686                                 }
4687                         }
4688 #endif
4689                 }
4690         }
4691
4692         retval = 127;
4693         do {
4694                 if (**argv != '%') {
4695                         pid_t pid = number(*argv);
4696                         job = curjob;
4697                         while (1) {
4698                                 if (!job)
4699                                         goto repeat;
4700                                 if (job->ps[job->nprocs - 1].ps_pid == pid)
4701                                         break;
4702                                 job = job->prev_job;
4703                         }
4704                 } else {
4705                         job = getjob(*argv, 0);
4706                 }
4707                 /* loop until process terminated or stopped */
4708                 dowait(DOWAIT_BLOCK_OR_SIG, NULL);
4709                 if (pending_sig)
4710                         goto sigout;
4711                 job->waited = 1;
4712                 retval = getstatus(job);
4713  repeat: ;
4714         } while (*++argv);
4715
4716  ret:
4717         return retval;
4718  sigout:
4719         retval = 128 + pending_sig;
4720         return retval;
4721 }
4722
4723 static struct job *
4724 growjobtab(void)
4725 {
4726         size_t len;
4727         ptrdiff_t offset;
4728         struct job *jp, *jq;
4729
4730         len = njobs * sizeof(*jp);
4731         jq = jobtab;
4732         jp = ckrealloc(jq, len + 4 * sizeof(*jp));
4733
4734         offset = (char *)jp - (char *)jq;
4735         if (offset) {
4736                 /* Relocate pointers */
4737                 size_t l = len;
4738
4739                 jq = (struct job *)((char *)jq + l);
4740                 while (l) {
4741                         l -= sizeof(*jp);
4742                         jq--;
4743 #define joff(p) ((struct job *)((char *)(p) + l))
4744 #define jmove(p) (p) = (void *)((char *)(p) + offset)
4745                         if (joff(jp)->ps == &jq->ps0)
4746                                 jmove(joff(jp)->ps);
4747                         if (joff(jp)->prev_job)
4748                                 jmove(joff(jp)->prev_job);
4749                 }
4750                 if (curjob)
4751                         jmove(curjob);
4752 #undef joff
4753 #undef jmove
4754         }
4755
4756         njobs += 4;
4757         jobtab = jp;
4758         jp = (struct job *)((char *)jp + len);
4759         jq = jp + 3;
4760         do {
4761                 jq->used = 0;
4762         } while (--jq >= jp);
4763         return jp;
4764 }
4765
4766 /*
4767  * Return a new job structure.
4768  * Called with interrupts off.
4769  */
4770 static struct job *
4771 makejob(/*union node *node,*/ int nprocs)
4772 {
4773         int i;
4774         struct job *jp;
4775
4776         for (i = njobs, jp = jobtab; ; jp++) {
4777                 if (--i < 0) {
4778                         jp = growjobtab();
4779                         break;
4780                 }
4781                 if (jp->used == 0)
4782                         break;
4783                 if (jp->state != JOBDONE || !jp->waited)
4784                         continue;
4785 #if JOBS
4786                 if (doing_jobctl)
4787                         continue;
4788 #endif
4789                 freejob(jp);
4790                 break;
4791         }
4792         memset(jp, 0, sizeof(*jp));
4793 #if JOBS
4794         /* jp->jobctl is a bitfield.
4795          * "jp->jobctl |= doing_jobctl" likely to give awful code */
4796         if (doing_jobctl)
4797                 jp->jobctl = 1;
4798 #endif
4799         jp->prev_job = curjob;
4800         curjob = jp;
4801         jp->used = 1;
4802         jp->ps = &jp->ps0;
4803         if (nprocs > 1) {
4804                 jp->ps = ckmalloc(nprocs * sizeof(struct procstat));
4805         }
4806         TRACE(("makejob(%d) returns %%%d\n", nprocs,
4807                                 jobno(jp)));
4808         return jp;
4809 }
4810
4811 #if JOBS
4812 /*
4813  * Return a string identifying a command (to be printed by the
4814  * jobs command).
4815  */
4816 static char *cmdnextc;
4817
4818 static void
4819 cmdputs(const char *s)
4820 {
4821         static const char vstype[VSTYPE + 1][3] = {
4822                 "", "}", "-", "+", "?", "=",
4823                 "%", "%%", "#", "##"
4824                 IF_BASH_SUBSTR(, ":")
4825                 IF_BASH_PATTERN_SUBST(, "/", "//")
4826         };
4827
4828         const char *p, *str;
4829         char cc[2];
4830         char *nextc;
4831         unsigned char c;
4832         unsigned char subtype = 0;
4833         int quoted = 0;
4834
4835         cc[1] = '\0';
4836         nextc = makestrspace((strlen(s) + 1) * 8, cmdnextc);
4837         p = s;
4838         while ((c = *p++) != '\0') {
4839                 str = NULL;
4840                 switch (c) {
4841                 case CTLESC:
4842                         c = *p++;
4843                         break;
4844                 case CTLVAR:
4845                         subtype = *p++;
4846                         if ((subtype & VSTYPE) == VSLENGTH)
4847                                 str = "${#";
4848                         else
4849                                 str = "${";
4850                         goto dostr;
4851                 case CTLENDVAR:
4852                         str = "\"}";
4853                         str += !(quoted & 1);
4854                         quoted >>= 1;
4855                         subtype = 0;
4856                         goto dostr;
4857                 case CTLBACKQ:
4858                         str = "$(...)";
4859                         goto dostr;
4860 #if ENABLE_FEATURE_SH_MATH
4861                 case CTLARI:
4862                         str = "$((";
4863                         goto dostr;
4864                 case CTLENDARI:
4865                         str = "))";
4866                         goto dostr;
4867 #endif
4868                 case CTLQUOTEMARK:
4869                         quoted ^= 1;
4870                         c = '"';
4871                         break;
4872                 case '=':
4873                         if (subtype == 0)
4874                                 break;
4875                         if ((subtype & VSTYPE) != VSNORMAL)
4876                                 quoted <<= 1;
4877                         str = vstype[subtype & VSTYPE];
4878                         if (subtype & VSNUL)
4879                                 c = ':';
4880                         else
4881                                 goto checkstr;
4882                         break;
4883                 case '\'':
4884                 case '\\':
4885                 case '"':
4886                 case '$':
4887                         /* These can only happen inside quotes */
4888                         cc[0] = c;
4889                         str = cc;
4890 //FIXME:
4891 // $ true $$ &
4892 // $ <cr>
4893 // [1]+  Done    true ${\$}   <<=== BUG: ${\$} is not a valid way to write $$ (${$} would be ok)
4894                         c = '\\';
4895                         break;
4896                 default:
4897                         break;
4898                 }
4899                 USTPUTC(c, nextc);
4900  checkstr:
4901                 if (!str)
4902                         continue;
4903  dostr:
4904                 while ((c = *str++) != '\0') {
4905                         USTPUTC(c, nextc);
4906                 }
4907         } /* while *p++ not NUL */
4908
4909         if (quoted & 1) {
4910                 USTPUTC('"', nextc);
4911         }
4912         *nextc = 0;
4913         cmdnextc = nextc;
4914 }
4915
4916 /* cmdtxt() and cmdlist() call each other */
4917 static void cmdtxt(union node *n);
4918
4919 static void
4920 cmdlist(union node *np, int sep)
4921 {
4922         for (; np; np = np->narg.next) {
4923                 if (!sep)
4924                         cmdputs(" ");
4925                 cmdtxt(np);
4926                 if (sep && np->narg.next)
4927                         cmdputs(" ");
4928         }
4929 }
4930
4931 static void
4932 cmdtxt(union node *n)
4933 {
4934         union node *np;
4935         struct nodelist *lp;
4936         const char *p;
4937
4938         if (!n)
4939                 return;
4940         switch (n->type) {
4941         default:
4942 #if DEBUG
4943                 abort();
4944 #endif
4945         case NPIPE:
4946                 lp = n->npipe.cmdlist;
4947                 for (;;) {
4948                         cmdtxt(lp->n);
4949                         lp = lp->next;
4950                         if (!lp)
4951                                 break;
4952                         cmdputs(" | ");
4953                 }
4954                 break;
4955         case NSEMI:
4956                 p = "; ";
4957                 goto binop;
4958         case NAND:
4959                 p = " && ";
4960                 goto binop;
4961         case NOR:
4962                 p = " || ";
4963  binop:
4964                 cmdtxt(n->nbinary.ch1);
4965                 cmdputs(p);
4966                 n = n->nbinary.ch2;
4967                 goto donode;
4968         case NREDIR:
4969         case NBACKGND:
4970                 n = n->nredir.n;
4971                 goto donode;
4972         case NNOT:
4973                 cmdputs("!");
4974                 n = n->nnot.com;
4975  donode:
4976                 cmdtxt(n);
4977                 break;
4978         case NIF:
4979                 cmdputs("if ");
4980                 cmdtxt(n->nif.test);
4981                 cmdputs("; then ");
4982                 if (n->nif.elsepart) {
4983                         cmdtxt(n->nif.ifpart);
4984                         cmdputs("; else ");
4985                         n = n->nif.elsepart;
4986                 } else {
4987                         n = n->nif.ifpart;
4988                 }
4989                 p = "; fi";
4990                 goto dotail;
4991         case NSUBSHELL:
4992                 cmdputs("(");
4993                 n = n->nredir.n;
4994                 p = ")";
4995                 goto dotail;
4996         case NWHILE:
4997                 p = "while ";
4998                 goto until;
4999         case NUNTIL:
5000                 p = "until ";
5001  until:
5002                 cmdputs(p);
5003                 cmdtxt(n->nbinary.ch1);
5004                 n = n->nbinary.ch2;
5005                 p = "; done";
5006  dodo:
5007                 cmdputs("; do ");
5008  dotail:
5009                 cmdtxt(n);
5010                 goto dotail2;
5011         case NFOR:
5012                 cmdputs("for ");
5013                 cmdputs(n->nfor.var);
5014                 cmdputs(" in ");
5015                 cmdlist(n->nfor.args, 1);
5016                 n = n->nfor.body;
5017                 p = "; done";
5018                 goto dodo;
5019         case NDEFUN:
5020                 cmdputs(n->ndefun.text);
5021                 p = "() { ... }";
5022                 goto dotail2;
5023         case NCMD:
5024                 cmdlist(n->ncmd.args, 1);
5025                 cmdlist(n->ncmd.redirect, 0);
5026                 break;
5027         case NARG:
5028                 p = n->narg.text;
5029  dotail2:
5030                 cmdputs(p);
5031                 break;
5032         case NHERE:
5033         case NXHERE:
5034                 p = "<<...";
5035                 goto dotail2;
5036         case NCASE:
5037                 cmdputs("case ");
5038                 cmdputs(n->ncase.expr->narg.text);
5039                 cmdputs(" in ");
5040                 for (np = n->ncase.cases; np; np = np->nclist.next) {
5041                         cmdtxt(np->nclist.pattern);
5042                         cmdputs(") ");
5043                         cmdtxt(np->nclist.body);
5044                         cmdputs(";; ");
5045                 }
5046                 p = "esac";
5047                 goto dotail2;
5048         case NTO:
5049                 p = ">";
5050                 goto redir;
5051         case NCLOBBER:
5052                 p = ">|";
5053                 goto redir;
5054         case NAPPEND:
5055                 p = ">>";
5056                 goto redir;
5057 #if BASH_REDIR_OUTPUT
5058         case NTO2:
5059 #endif
5060         case NTOFD:
5061                 p = ">&";
5062                 goto redir;
5063         case NFROM:
5064                 p = "<";
5065                 goto redir;
5066         case NFROMFD:
5067                 p = "<&";
5068                 goto redir;
5069         case NFROMTO:
5070                 p = "<>";
5071  redir:
5072                 cmdputs(utoa(n->nfile.fd));
5073                 cmdputs(p);
5074                 if (n->type == NTOFD || n->type == NFROMFD) {
5075                         if (n->ndup.dupfd >= 0)
5076                                 cmdputs(utoa(n->ndup.dupfd));
5077                         else
5078                                 cmdputs("-");
5079                         break;
5080                 }
5081                 n = n->nfile.fname;
5082                 goto donode;
5083         }
5084 }
5085
5086 static char *
5087 commandtext(union node *n)
5088 {
5089         char *name;
5090
5091         STARTSTACKSTR(cmdnextc);
5092         cmdtxt(n);
5093         name = stackblock();
5094         TRACE(("commandtext: name %p, end %p\n", name, cmdnextc));
5095         return ckstrdup(name);
5096 }
5097 #endif /* JOBS */
5098
5099 /*
5100  * Fork off a subshell.  If we are doing job control, give the subshell its
5101  * own process group.  Jp is a job structure that the job is to be added to.
5102  * N is the command that will be evaluated by the child.  Both jp and n may
5103  * be NULL.  The mode parameter can be one of the following:
5104  *      FORK_FG - Fork off a foreground process.
5105  *      FORK_BG - Fork off a background process.
5106  *      FORK_NOJOB - Like FORK_FG, but don't give the process its own
5107  *                   process group even if job control is on.
5108  *
5109  * When job control is turned off, background processes have their standard
5110  * input redirected to /dev/null (except for the second and later processes
5111  * in a pipeline).
5112  *
5113  * Called with interrupts off.
5114  */
5115 /*
5116  * Clear traps on a fork.
5117  */
5118 static void
5119 clear_traps(void)
5120 {
5121         char **tp;
5122
5123         INT_OFF;
5124         for (tp = trap; tp < &trap[NSIG]; tp++) {
5125                 if (*tp && **tp) {      /* trap not NULL or "" (SIG_IGN) */
5126                         if (trap_ptr == trap)
5127                                 free(*tp);
5128                         /* else: it "belongs" to trap_ptr vector, don't free */
5129                         *tp = NULL;
5130                         if ((tp - trap) != 0)
5131                                 setsignal(tp - trap);
5132                 }
5133         }
5134         may_have_traps = 0;
5135         INT_ON;
5136 }
5137
5138 /* Lives far away from here, needed for forkchild */
5139 static void closescript(void);
5140
5141 /* Called after fork(), in child */
5142 /* jp and n are NULL when called by openhere() for heredoc support */
5143 static NOINLINE void
5144 forkchild(struct job *jp, union node *n, int mode)
5145 {
5146         int oldlvl;
5147
5148         TRACE(("Child shell %d\n", getpid()));
5149         oldlvl = shlvl;
5150         shlvl++;
5151
5152         /* man bash: "Non-builtin commands run by bash have signal handlers
5153          * set to the values inherited by the shell from its parent".
5154          * Do we do it correctly? */
5155
5156         closescript();
5157
5158         if (mode == FORK_NOJOB          /* is it `xxx` ? */
5159          && n && n->type == NCMD        /* is it single cmd? */
5160         /* && n->ncmd.args->type == NARG - always true? */
5161          && n->ncmd.args && strcmp(n->ncmd.args->narg.text, "trap") == 0
5162          && n->ncmd.args->narg.next == NULL /* "trap" with no arguments */
5163         /* && n->ncmd.args->narg.backquote == NULL - do we need to check this? */
5164         ) {
5165                 TRACE(("Trap hack\n"));
5166                 /* Awful hack for `trap` or $(trap).
5167                  *
5168                  * http://www.opengroup.org/onlinepubs/009695399/utilities/trap.html
5169                  * contains an example where "trap" is executed in a subshell:
5170                  *
5171                  * save_traps=$(trap)
5172                  * ...
5173                  * eval "$save_traps"
5174                  *
5175                  * Standard does not say that "trap" in subshell shall print
5176                  * parent shell's traps. It only says that its output
5177                  * must have suitable form, but then, in the above example
5178                  * (which is not supposed to be normative), it implies that.
5179                  *
5180                  * bash (and probably other shell) does implement it
5181                  * (traps are reset to defaults, but "trap" still shows them),
5182                  * but as a result, "trap" logic is hopelessly messed up:
5183                  *
5184                  * # trap
5185                  * trap -- 'echo Ho' SIGWINCH  <--- we have a handler
5186                  * # (trap)        <--- trap is in subshell - no output (correct, traps are reset)
5187                  * # true | trap   <--- trap is in subshell - no output (ditto)
5188                  * # echo `true | trap`    <--- in subshell - output (but traps are reset!)
5189                  * trap -- 'echo Ho' SIGWINCH
5190                  * # echo `(trap)`         <--- in subshell in subshell - output
5191                  * trap -- 'echo Ho' SIGWINCH
5192                  * # echo `true | (trap)`  <--- in subshell in subshell in subshell - output!
5193                  * trap -- 'echo Ho' SIGWINCH
5194                  *
5195                  * The rules when to forget and when to not forget traps
5196                  * get really complex and nonsensical.
5197                  *
5198                  * Our solution: ONLY bare $(trap) or `trap` is special.
5199                  */
5200                 /* Save trap handler strings for trap builtin to print */
5201                 trap_ptr = xmemdup(trap, sizeof(trap));
5202                 /* Fall through into clearing traps */
5203         }
5204         clear_traps();
5205 #if JOBS
5206         /* do job control only in root shell */
5207         doing_jobctl = 0;
5208         if (mode != FORK_NOJOB && jp->jobctl && oldlvl == 0) {
5209                 pid_t pgrp;
5210
5211                 if (jp->nprocs == 0)
5212                         pgrp = getpid();
5213                 else
5214                         pgrp = jp->ps[0].ps_pid;
5215                 /* this can fail because we are doing it in the parent also */
5216                 setpgid(0, pgrp);
5217                 if (mode == FORK_FG)
5218                         xtcsetpgrp(ttyfd, pgrp);
5219                 setsignal(SIGTSTP);
5220                 setsignal(SIGTTOU);
5221         } else
5222 #endif
5223         if (mode == FORK_BG) {
5224                 /* man bash: "When job control is not in effect,
5225                  * asynchronous commands ignore SIGINT and SIGQUIT" */
5226                 ignoresig(SIGINT);
5227                 ignoresig(SIGQUIT);
5228                 if (jp->nprocs == 0) {
5229                         close(0);
5230                         if (open(bb_dev_null, O_RDONLY) != 0)
5231                                 ash_msg_and_raise_perror("can't open '%s'", bb_dev_null);
5232                 }
5233         }
5234         if (oldlvl == 0) {
5235                 if (iflag) { /* why if iflag only? */
5236                         setsignal(SIGINT);
5237                         setsignal(SIGTERM);
5238                 }
5239                 /* man bash:
5240                  * "In all cases, bash ignores SIGQUIT. Non-builtin
5241                  * commands run by bash have signal handlers
5242                  * set to the values inherited by the shell
5243                  * from its parent".
5244                  * Take care of the second rule: */
5245                 setsignal(SIGQUIT);
5246         }
5247 #if JOBS
5248         if (n && n->type == NCMD
5249          && n->ncmd.args && strcmp(n->ncmd.args->narg.text, "jobs") == 0
5250         ) {
5251                 TRACE(("Job hack\n"));
5252                 /* "jobs": we do not want to clear job list for it,
5253                  * instead we remove only _its_ own_ job from job list.
5254                  * This makes "jobs .... | cat" more useful.
5255                  */
5256                 freejob(curjob);
5257                 return;
5258         }
5259 #endif
5260         for (jp = curjob; jp; jp = jp->prev_job)
5261                 freejob(jp);
5262 }
5263
5264 /* Called after fork(), in parent */
5265 #if !JOBS
5266 #define forkparent(jp, n, mode, pid) forkparent(jp, mode, pid)
5267 #endif
5268 static void
5269 forkparent(struct job *jp, union node *n, int mode, pid_t pid)
5270 {
5271         TRACE(("In parent shell: child = %d\n", pid));
5272         if (!jp) /* jp is NULL when called by openhere() for heredoc support */
5273                 return;
5274 #if JOBS
5275         if (mode != FORK_NOJOB && jp->jobctl) {
5276                 int pgrp;
5277
5278                 if (jp->nprocs == 0)
5279                         pgrp = pid;
5280                 else
5281                         pgrp = jp->ps[0].ps_pid;
5282                 /* This can fail because we are doing it in the child also */
5283                 setpgid(pid, pgrp);
5284         }
5285 #endif
5286         if (mode == FORK_BG) {
5287                 backgndpid = pid;               /* set $! */
5288                 set_curjob(jp, CUR_RUNNING);
5289         }
5290         if (jp) {
5291                 struct procstat *ps = &jp->ps[jp->nprocs++];
5292                 ps->ps_pid = pid;
5293                 ps->ps_status = -1;
5294                 ps->ps_cmd = nullstr;
5295 #if JOBS
5296                 if (doing_jobctl && n)
5297                         ps->ps_cmd = commandtext(n);
5298 #endif
5299         }
5300 }
5301
5302 /* jp and n are NULL when called by openhere() for heredoc support */
5303 static int
5304 forkshell(struct job *jp, union node *n, int mode)
5305 {
5306         int pid;
5307
5308         TRACE(("forkshell(%%%d, %p, %d) called\n", jobno(jp), n, mode));
5309         pid = fork();
5310         if (pid < 0) {
5311                 TRACE(("Fork failed, errno=%d", errno));
5312                 if (jp)
5313                         freejob(jp);
5314                 ash_msg_and_raise_perror("can't fork");
5315         }
5316         if (pid == 0) {
5317                 CLEAR_RANDOM_T(&random_gen); /* or else $RANDOM repeats in child */
5318                 forkchild(jp, n, mode);
5319         } else {
5320                 forkparent(jp, n, mode, pid);
5321         }
5322         return pid;
5323 }
5324
5325 /*
5326  * Wait for job to finish.
5327  *
5328  * Under job control we have the problem that while a child process
5329  * is running interrupts generated by the user are sent to the child
5330  * but not to the shell.  This means that an infinite loop started by
5331  * an interactive user may be hard to kill.  With job control turned off,
5332  * an interactive user may place an interactive program inside a loop.
5333  * If the interactive program catches interrupts, the user doesn't want
5334  * these interrupts to also abort the loop.  The approach we take here
5335  * is to have the shell ignore interrupt signals while waiting for a
5336  * foreground process to terminate, and then send itself an interrupt
5337  * signal if the child process was terminated by an interrupt signal.
5338  * Unfortunately, some programs want to do a bit of cleanup and then
5339  * exit on interrupt; unless these processes terminate themselves by
5340  * sending a signal to themselves (instead of calling exit) they will
5341  * confuse this approach.
5342  *
5343  * Called with interrupts off.
5344  */
5345 static int
5346 waitforjob(struct job *jp)
5347 {
5348         int st;
5349
5350         TRACE(("waitforjob(%%%d) called\n", jp ? jobno(jp) : 0));
5351
5352         /* In non-interactive shells, we _can_ get
5353          * a keyboard signal here and be EINTRed, but we just loop
5354          * inside dowait(), waiting for command to complete.
5355          *
5356          * man bash:
5357          * "If bash is waiting for a command to complete and receives
5358          * a signal for which a trap has been set, the trap
5359          * will not be executed until the command completes."
5360          *
5361          * Reality is that even if trap is not set, bash
5362          * will not act on the signal until command completes.
5363          * Try this. sleep5intoff.c:
5364          * #include <signal.h>
5365          * #include <unistd.h>
5366          * int main() {
5367          *         sigset_t set;
5368          *         sigemptyset(&set);
5369          *         sigaddset(&set, SIGINT);
5370          *         sigaddset(&set, SIGQUIT);
5371          *         sigprocmask(SIG_BLOCK, &set, NULL);
5372          *         sleep(5);
5373          *         return 0;
5374          * }
5375          * $ bash -c './sleep5intoff; echo hi'
5376          * ^C^C^C^C <--- pressing ^C once a second
5377          * $ _
5378          * $ bash -c './sleep5intoff; echo hi'
5379          * ^\^\^\^\hi <--- pressing ^\ (SIGQUIT)
5380          * $ _
5381          */
5382         dowait(jp ? DOWAIT_BLOCK : DOWAIT_NONBLOCK, jp);
5383         if (!jp)
5384                 return exitstatus;
5385
5386         st = getstatus(jp);
5387 #if JOBS
5388         if (jp->jobctl) {
5389                 xtcsetpgrp(ttyfd, rootpid);
5390                 restore_tty_if_stopped_or_signaled(jp);
5391
5392                 /*
5393                  * This is truly gross.
5394                  * If we're doing job control, then we did a TIOCSPGRP which
5395                  * caused us (the shell) to no longer be in the controlling
5396                  * session -- so we wouldn't have seen any ^C/SIGINT.  So, we
5397                  * intuit from the subprocess exit status whether a SIGINT
5398                  * occurred, and if so interrupt ourselves.  Yuck.  - mycroft
5399                  */
5400                 if (jp->sigint) /* TODO: do the same with all signals */
5401                         raise(SIGINT); /* ... by raise(jp->sig) instead? */
5402         }
5403         if (jp->state == JOBDONE)
5404 #endif
5405                 freejob(jp);
5406         return st;
5407 }
5408
5409 /*
5410  * return 1 if there are stopped jobs, otherwise 0
5411  */
5412 static int
5413 stoppedjobs(void)
5414 {
5415         struct job *jp;
5416         int retval;
5417
5418         retval = 0;
5419         if (job_warning)
5420                 goto out;
5421         jp = curjob;
5422         if (jp && jp->state == JOBSTOPPED) {
5423                 out2str("You have stopped jobs.\n");
5424                 job_warning = 2;
5425                 retval++;
5426         }
5427  out:
5428         return retval;
5429 }
5430
5431
5432 /*
5433  * Code for dealing with input/output redirection.
5434  */
5435
5436 #undef EMPTY
5437 #undef CLOSED
5438 #define EMPTY -2                /* marks an unused slot in redirtab */
5439 #define CLOSED -1               /* marks a slot of previously-closed fd */
5440
5441 /*
5442  * Handle here documents.  Normally we fork off a process to write the
5443  * data to a pipe.  If the document is short, we can stuff the data in
5444  * the pipe without forking.
5445  */
5446 /* openhere needs this forward reference */
5447 static void expandhere(union node *arg, int fd);
5448 static int
5449 openhere(union node *redir)
5450 {
5451         int pip[2];
5452         size_t len = 0;
5453
5454         if (pipe(pip) < 0)
5455                 ash_msg_and_raise_perror("can't create pipe");
5456         if (redir->type == NHERE) {
5457                 len = strlen(redir->nhere.doc->narg.text);
5458                 if (len <= PIPE_BUF) {
5459                         full_write(pip[1], redir->nhere.doc->narg.text, len);
5460                         goto out;
5461                 }
5462         }
5463         if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) {
5464                 /* child */
5465                 close(pip[0]);
5466                 ignoresig(SIGINT);  //signal(SIGINT, SIG_IGN);
5467                 ignoresig(SIGQUIT); //signal(SIGQUIT, SIG_IGN);
5468                 ignoresig(SIGHUP);  //signal(SIGHUP, SIG_IGN);
5469                 ignoresig(SIGTSTP); //signal(SIGTSTP, SIG_IGN);
5470                 signal(SIGPIPE, SIG_DFL);
5471                 if (redir->type == NHERE)
5472                         full_write(pip[1], redir->nhere.doc->narg.text, len);
5473                 else /* NXHERE */
5474                         expandhere(redir->nhere.doc, pip[1]);
5475                 _exit(EXIT_SUCCESS);
5476         }
5477  out:
5478         close(pip[1]);
5479         return pip[0];
5480 }
5481
5482 static int
5483 openredirect(union node *redir)
5484 {
5485         struct stat sb;
5486         char *fname;
5487         int f;
5488
5489         switch (redir->nfile.type) {
5490 /* Can't happen, our single caller does this itself */
5491 //      case NTOFD:
5492 //      case NFROMFD:
5493 //              return -1;
5494         case NHERE:
5495         case NXHERE:
5496                 return openhere(redir);
5497         }
5498
5499         /* For N[X]HERE, reading redir->nfile.expfname would touch beyond
5500          * allocated space. Do it only when we know it is safe.
5501          */
5502         fname = redir->nfile.expfname;
5503
5504         switch (redir->nfile.type) {
5505         default:
5506 #if DEBUG
5507                 abort();
5508 #endif
5509         case NFROM:
5510                 f = open(fname, O_RDONLY);
5511                 if (f < 0)
5512                         goto eopen;
5513                 break;
5514         case NFROMTO:
5515                 f = open(fname, O_RDWR|O_CREAT, 0666);
5516                 if (f < 0)
5517                         goto ecreate;
5518                 break;
5519         case NTO:
5520 #if BASH_REDIR_OUTPUT
5521         case NTO2:
5522 #endif
5523                 /* Take care of noclobber mode. */
5524                 if (Cflag) {
5525                         if (stat(fname, &sb) < 0) {
5526                                 f = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0666);
5527                                 if (f < 0)
5528                                         goto ecreate;
5529                         } else if (!S_ISREG(sb.st_mode)) {
5530                                 f = open(fname, O_WRONLY, 0666);
5531                                 if (f < 0)
5532                                         goto ecreate;
5533                                 if (!fstat(f, &sb) && S_ISREG(sb.st_mode)) {
5534                                         close(f);
5535                                         errno = EEXIST;
5536                                         goto ecreate;
5537                                 }
5538                         } else {
5539                                 errno = EEXIST;
5540                                 goto ecreate;
5541                         }
5542                         break;
5543                 }
5544                 /* FALLTHROUGH */
5545         case NCLOBBER:
5546                 f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666);
5547                 if (f < 0)
5548                         goto ecreate;
5549                 break;
5550         case NAPPEND:
5551                 f = open(fname, O_WRONLY|O_CREAT|O_APPEND, 0666);
5552                 if (f < 0)
5553                         goto ecreate;
5554                 break;
5555         }
5556
5557         return f;
5558  ecreate:
5559         ash_msg_and_raise_error("can't create %s: %s", fname, errmsg(errno, "nonexistent directory"));
5560  eopen:
5561         ash_msg_and_raise_error("can't open %s: %s", fname, errmsg(errno, "no such file"));
5562 }
5563
5564 /*
5565  * Copy a file descriptor to be >= 10. Throws exception on error.
5566  */
5567 static int
5568 savefd(int from)
5569 {
5570         int newfd;
5571         int err;
5572
5573         newfd = fcntl(from, F_DUPFD_CLOEXEC, 10);
5574         err = newfd < 0 ? errno : 0;
5575         if (err != EBADF) {
5576                 if (err)
5577                         ash_msg_and_raise_perror("%d", from);
5578                 close(from);
5579                 if (F_DUPFD_CLOEXEC == F_DUPFD)
5580                         close_on_exec_on(newfd);
5581         }
5582
5583         return newfd;
5584 }
5585 static int
5586 dup2_or_raise(int from, int to)
5587 {
5588         int newfd;
5589
5590         newfd = (from != to) ? dup2(from, to) : to;
5591         if (newfd < 0) {
5592                 /* Happens when source fd is not open: try "echo >&99" */
5593                 ash_msg_and_raise_perror("%d", from);
5594         }
5595         return newfd;
5596 }
5597 static int
5598 dup_CLOEXEC(int fd, int avoid_fd)
5599 {
5600         int newfd;
5601  repeat:
5602         newfd = fcntl(fd, F_DUPFD_CLOEXEC, avoid_fd + 1);
5603         if (newfd >= 0) {
5604                 if (F_DUPFD_CLOEXEC == F_DUPFD) /* if old libc (w/o F_DUPFD_CLOEXEC) */
5605                         close_on_exec_on(newfd);
5606         } else { /* newfd < 0 */
5607                 if (errno == EBUSY)
5608                         goto repeat;
5609                 if (errno == EINTR)
5610                         goto repeat;
5611         }
5612         return newfd;
5613 }
5614 static int
5615 xdup_CLOEXEC_and_close(int fd, int avoid_fd)
5616 {
5617         int newfd;
5618  repeat:
5619         newfd = fcntl(fd, F_DUPFD_CLOEXEC, avoid_fd + 1);
5620         if (newfd < 0) {
5621                 if (errno == EBUSY)
5622                         goto repeat;
5623                 if (errno == EINTR)
5624                         goto repeat;
5625                 /* fd was not open? */
5626                 if (errno == EBADF)
5627                         return fd;
5628                 ash_msg_and_raise_perror("%d", newfd);
5629         }
5630         if (F_DUPFD_CLOEXEC == F_DUPFD)
5631                 close_on_exec_on(newfd);
5632         close(fd);
5633         return newfd;
5634 }
5635
5636 /* Struct def and variable are moved down to the first usage site */
5637 struct squirrel {
5638         int orig_fd;
5639         int moved_to;
5640 };
5641 struct redirtab {
5642         struct redirtab *next;
5643         int pair_count;
5644         struct squirrel two_fd[];
5645 };
5646 #define redirlist (G_var.redirlist)
5647
5648 static void
5649 add_squirrel_closed(struct redirtab *sq, int fd)
5650 {
5651         int i;
5652
5653         if (!sq)
5654                 return;
5655
5656         for (i = 0; sq->two_fd[i].orig_fd != EMPTY; i++) {
5657                 /* If we collide with an already moved fd... */
5658                 if (fd == sq->two_fd[i].orig_fd) {
5659                         /* Examples:
5660                          * "echo 3>FILE 3>&- 3>FILE"
5661                          * "echo 3>&- 3>FILE"
5662                          * No need for last redirect to insert
5663                          * another "need to close 3" indicator.
5664                          */
5665                         TRACE(("redirect_fd %d: already moved or closed\n", fd));
5666                         return;
5667                 }
5668         }
5669         TRACE(("redirect_fd %d: previous fd was closed\n", fd));
5670         sq->two_fd[i].orig_fd = fd;
5671         sq->two_fd[i].moved_to = CLOSED;
5672 }
5673
5674 static int
5675 save_fd_on_redirect(int fd, int avoid_fd, struct redirtab *sq)
5676 {
5677         int i, new_fd;
5678
5679         if (avoid_fd < 9) /* the important case here is that it can be -1 */
5680                 avoid_fd = 9;
5681
5682 #if JOBS
5683         if (fd == ttyfd) {
5684                 /* Testcase: "ls -l /proc/$$/fd 10>&-" should work */
5685                 ttyfd = xdup_CLOEXEC_and_close(ttyfd, avoid_fd);
5686                 TRACE(("redirect_fd %d: matches ttyfd, moving it to %d\n", fd, ttyfd));
5687                 return 1; /* "we closed fd" */
5688         }
5689 #endif
5690         /* Are we called from redirect(0)? E.g. redirect
5691          * in a forked child. No need to save fds,
5692          * we aren't going to use them anymore, ok to trash.
5693          */
5694         if (!sq)
5695                 return 0;
5696
5697         /* If this one of script's fds? */
5698         if (fd != 0) {
5699                 struct parsefile *pf = g_parsefile;
5700                 while (pf) {
5701                         /* We skip fd == 0 case because of the following:
5702                          * $ ash  # running ash interactively
5703                          * $ . ./script.sh
5704                          * and in script.sh: "exec 9>&0".
5705                          * Even though top-level pf_fd _is_ 0,
5706                          * it's still ok to use it: "read" builtin uses it,
5707                          * why should we cripple "exec" builtin?
5708                          */
5709                         if (fd == pf->pf_fd) {
5710                                 pf->pf_fd = xdup_CLOEXEC_and_close(fd, avoid_fd);
5711                                 return 1; /* "we closed fd" */
5712                         }
5713                         pf = pf->prev;
5714                 }
5715         }
5716
5717         /* Check whether it collides with any open fds (e.g. stdio), save fds as needed */
5718
5719         /* First: do we collide with some already moved fds? */
5720         for (i = 0; sq->two_fd[i].orig_fd != EMPTY; i++) {
5721                 /* If we collide with an already moved fd... */
5722                 if (fd == sq->two_fd[i].moved_to) {
5723                         new_fd = dup_CLOEXEC(fd, avoid_fd);
5724                         sq->two_fd[i].moved_to = new_fd;
5725                         TRACE(("redirect_fd %d: already busy, moving to %d\n", fd, new_fd));
5726                         if (new_fd < 0) /* what? */
5727                                 xfunc_die();
5728                         return 0; /* "we did not close fd" */
5729                 }
5730                 if (fd == sq->two_fd[i].orig_fd) {
5731                         /* Example: echo Hello >/dev/null 1>&2 */
5732                         TRACE(("redirect_fd %d: already moved\n", fd));
5733                         return 0; /* "we did not close fd" */
5734                 }
5735         }
5736
5737         /* If this fd is open, we move and remember it; if it's closed, new_fd = CLOSED (-1) */
5738         new_fd = dup_CLOEXEC(fd, avoid_fd);
5739         TRACE(("redirect_fd %d: previous fd is moved to %d (-1 if it was closed)\n", fd, new_fd));
5740         if (new_fd < 0) {
5741                 if (errno != EBADF)
5742                         xfunc_die();
5743                 /* new_fd = CLOSED; - already is -1 */
5744         }
5745         sq->two_fd[i].moved_to = new_fd;
5746         sq->two_fd[i].orig_fd = fd;
5747
5748         /* if we move stderr, let "set -x" code know */
5749         if (fd == preverrout_fd)
5750                 preverrout_fd = new_fd;
5751
5752         return 0; /* "we did not close fd" */
5753 }
5754
5755 static int
5756 internally_opened_fd(int fd, struct redirtab *sq)
5757 {
5758         int i;
5759 #if JOBS
5760         if (fd == ttyfd)
5761                 return 1;
5762 #endif
5763         /* If this one of script's fds? */
5764         if (fd != 0) {
5765                 struct parsefile *pf = g_parsefile;
5766                 while (pf) {
5767                         if (fd == pf->pf_fd)
5768                                 return 1;
5769                         pf = pf->prev;
5770                 }
5771         }
5772
5773         if (sq) for (i = 0; i < sq->pair_count && sq->two_fd[i].orig_fd != EMPTY; i++) {
5774                 if (fd == sq->two_fd[i].moved_to)
5775                         return 1;
5776         }
5777         return 0;
5778 }
5779
5780 /*
5781  * Process a list of redirection commands.  If the REDIR_PUSH flag is set,
5782  * old file descriptors are stashed away so that the redirection can be
5783  * undone by calling popredir.
5784  */
5785 /* flags passed to redirect */
5786 #define REDIR_PUSH    01        /* save previous values of file descriptors */
5787 static void
5788 redirect(union node *redir, int flags)
5789 {
5790         struct redirtab *sv;
5791
5792         if (!redir)
5793                 return;
5794
5795         sv = NULL;
5796         INT_OFF;
5797         if (flags & REDIR_PUSH)
5798                 sv = redirlist;
5799         do {
5800                 int fd;
5801                 int newfd;
5802                 int close_fd;
5803                 int closed;
5804
5805                 fd = redir->nfile.fd;
5806                 if (redir->nfile.type == NTOFD || redir->nfile.type == NFROMFD) {
5807                         //bb_error_msg("doing %d > %d", fd, newfd);
5808                         newfd = redir->ndup.dupfd;
5809                         close_fd = -1;
5810                 } else {
5811                         newfd = openredirect(redir); /* always >= 0 */
5812                         if (fd == newfd) {
5813                                 /* open() gave us precisely the fd we wanted.
5814                                  * This means that this fd was not busy
5815                                  * (not opened to anywhere).
5816                                  * Remember to close it on restore:
5817                                  */
5818                                 add_squirrel_closed(sv, fd);
5819                                 continue;
5820                         }
5821                         close_fd = newfd;
5822                 }
5823
5824                 if (fd == newfd)
5825                         continue;
5826
5827                 /* if "N>FILE": move newfd to fd */
5828                 /* if "N>&M": dup newfd to fd */
5829                 /* if "N>&-": close fd (newfd is -1) */
5830
5831  IF_BASH_REDIR_OUTPUT(redirect_more:)
5832
5833                 closed = save_fd_on_redirect(fd, /*avoid:*/ newfd, sv);
5834                 if (newfd == -1) {
5835                         /* "N>&-" means "close me" */
5836                         if (!closed) {
5837                                 /* ^^^ optimization: saving may already
5838                                  * have closed it. If not... */
5839                                 close(fd);
5840                         }
5841                 } else {
5842                         /* if newfd is a script fd or saved fd, simulate EBADF */
5843                         if (internally_opened_fd(newfd, sv)) {
5844                                 errno = EBADF;
5845                                 ash_msg_and_raise_perror("%d", newfd);
5846                         }
5847                         dup2_or_raise(newfd, fd);
5848                         if (close_fd >= 0) /* "N>FILE" or ">&FILE" or heredoc? */
5849                                 close(close_fd);
5850 #if BASH_REDIR_OUTPUT
5851                         if (redir->nfile.type == NTO2 && fd == 1) {
5852                                 /* ">&FILE". we already redirected to 1, now copy 1 to 2 */
5853                                 fd = 2;
5854                                 newfd = 1;
5855                                 close_fd = -1;
5856                                 goto redirect_more;
5857                         }
5858 #endif
5859                 }
5860         } while ((redir = redir->nfile.next) != NULL);
5861         INT_ON;
5862
5863 //dash:#define REDIR_SAVEFD2 03        /* set preverrout */
5864 #define REDIR_SAVEFD2 0
5865         // dash has a bug: since REDIR_SAVEFD2=3 and REDIR_PUSH=1, this test
5866         // triggers for pure REDIR_PUSH too. Thus, this is done almost always,
5867         // not only for calls with flags containing REDIR_SAVEFD2.
5868         // We do this unconditionally (see save_fd_on_redirect()).
5869         //if ((flags & REDIR_SAVEFD2) && copied_fd2 >= 0)
5870         //      preverrout_fd = copied_fd2;
5871 }
5872
5873 static int
5874 redirectsafe(union node *redir, int flags)
5875 {
5876         int err;
5877         volatile int saveint;
5878         struct jmploc *volatile savehandler = exception_handler;
5879         struct jmploc jmploc;
5880
5881         SAVE_INT(saveint);
5882         /* "echo 9>/dev/null; echo >&9; echo result: $?" - result should be 1, not 2! */
5883         err = setjmp(jmploc.loc); /* was = setjmp(jmploc.loc) * 2; */
5884         if (!err) {
5885                 exception_handler = &jmploc;
5886                 redirect(redir, flags);
5887         }
5888         exception_handler = savehandler;
5889         if (err && exception_type != EXERROR)
5890                 longjmp(exception_handler->loc, 1);
5891         RESTORE_INT(saveint);
5892         return err;
5893 }
5894
5895 static struct redirtab*
5896 pushredir(union node *redir)
5897 {
5898         struct redirtab *sv;
5899         int i;
5900
5901         if (!redir)
5902                 return redirlist;
5903
5904         i = 0;
5905         do {
5906                 i++;
5907 #if BASH_REDIR_OUTPUT
5908                 if (redir->nfile.type == NTO2)
5909                         i++;
5910 #endif
5911                 redir = redir->nfile.next;
5912         } while (redir);
5913
5914         sv = ckzalloc(sizeof(*sv) + i * sizeof(sv->two_fd[0]));
5915         sv->pair_count = i;
5916         while (--i >= 0)
5917                 sv->two_fd[i].orig_fd = sv->two_fd[i].moved_to = EMPTY;
5918         sv->next = redirlist;
5919         redirlist = sv;
5920         return sv->next;
5921 }
5922
5923 /*
5924  * Undo the effects of the last redirection.
5925  */
5926 static void
5927 popredir(int drop)
5928 {
5929         struct redirtab *rp;
5930         int i;
5931
5932         if (redirlist == NULL)
5933                 return;
5934         INT_OFF;
5935         rp = redirlist;
5936         for (i = 0; i < rp->pair_count; i++) {
5937                 int fd = rp->two_fd[i].orig_fd;
5938                 int copy = rp->two_fd[i].moved_to;
5939                 if (copy == CLOSED) {
5940                         if (!drop)
5941                                 close(fd);
5942                         continue;
5943                 }
5944                 if (copy != EMPTY) {
5945                         if (!drop) {
5946                                 /*close(fd);*/
5947                                 dup2_or_raise(copy, fd);
5948                         }
5949                         close(copy);
5950                 }
5951         }
5952         redirlist = rp->next;
5953         free(rp);
5954         INT_ON;
5955 }
5956
5957 static void
5958 unwindredir(struct redirtab *stop)
5959 {
5960         while (redirlist != stop)
5961                 popredir(/*drop:*/ 0);
5962 }
5963
5964
5965 /* ============ Routines to expand arguments to commands
5966  *
5967  * We have to deal with backquotes, shell variables, and file metacharacters.
5968  */
5969
5970 #if ENABLE_FEATURE_SH_MATH
5971 static arith_t
5972 ash_arith(const char *s)
5973 {
5974         arith_state_t math_state;
5975         arith_t result;
5976
5977         math_state.lookupvar = lookupvar;
5978         math_state.setvar    = setvar0;
5979         //math_state.endofname = endofname;
5980
5981         INT_OFF;
5982         result = arith(&math_state, s);
5983         if (math_state.errmsg)
5984                 ash_msg_and_raise_error(math_state.errmsg);
5985         INT_ON;
5986
5987         return result;
5988 }
5989 #endif
5990 #if BASH_SUBSTR
5991 # if ENABLE_FEATURE_SH_MATH
5992 static int substr_atoi(const char *s)
5993 {
5994         arith_t t = ash_arith(s);
5995         if (sizeof(t) > sizeof(int)) {
5996                 /* clamp very large or very large negative nums for ${v:N:M}:
5997                  * else "${v:0:0x100000001}" would work as "${v:0:1}"
5998                  */
5999                 if (t > INT_MAX)
6000                         t = INT_MAX;
6001                 if (t < INT_MIN)
6002                         t = INT_MIN;
6003         }
6004         return t;
6005 }
6006 # else
6007 #  define substr_atoi(s) number(s)
6008 # endif
6009 #endif
6010
6011 /*
6012  * expandarg flags
6013  */
6014 #define EXP_FULL        0x1     /* perform word splitting & file globbing */
6015 #define EXP_TILDE       0x2     /* do normal tilde expansion */
6016 #define EXP_VARTILDE    0x4     /* expand tildes in an assignment */
6017 #define EXP_REDIR       0x8     /* file glob for a redirection (1 match only) */
6018 /* ^^^^^^^^^^^^^^ this is meant to support constructs such as "cmd >file*.txt"
6019  * POSIX says for this case:
6020  *  Pathname expansion shall not be performed on the word by a
6021  *  non-interactive shell; an interactive shell may perform it, but shall
6022  *  do so only when the expansion would result in one word.
6023  * Currently, our code complies to the above rule by never globbing
6024  * redirection filenames.
6025  * Bash performs globbing, unless it is non-interactive and in POSIX mode.
6026  * (this means that on a typical Linux distro, bash almost always
6027  * performs globbing, and thus diverges from what we do).
6028  */
6029 #define EXP_CASE        0x10    /* keeps quotes around for CASE pattern */
6030 #define EXP_VARTILDE2   0x20    /* expand tildes after colons only */
6031 #define EXP_WORD        0x40    /* expand word in parameter expansion */
6032 #define EXP_QUOTED      0x100   /* expand word in double quotes */
6033 #define EXP_KEEPNUL     0x200   /* do not skip NUL characters */
6034
6035 /*
6036  * rmescape() flags
6037  */
6038 #define RMESCAPE_ALLOC  0x1     /* Allocate a new string */
6039 #define RMESCAPE_GLOB   0x2     /* Add backslashes for glob */
6040 #define RMESCAPE_GROW   0x8     /* Grow strings instead of stalloc */
6041 #define RMESCAPE_HEAP   0x10    /* Malloc strings instead of stalloc */
6042
6043 /* Add CTLESC when necessary. */
6044 #define QUOTES_ESC     (EXP_FULL | EXP_CASE)
6045
6046 /*
6047  * Structure specifying which parts of the string should be searched
6048  * for IFS characters.
6049  */
6050 struct ifsregion {
6051         struct ifsregion *next; /* next region in list */
6052         int begoff;             /* offset of start of region */
6053         int endoff;             /* offset of end of region */
6054         int nulonly;            /* search for nul bytes only */
6055 };
6056
6057 struct arglist {
6058         struct strlist *list;
6059         struct strlist **lastp;
6060 };
6061
6062 /* output of current string */
6063 static char *expdest;
6064 /* list of back quote expressions */
6065 static struct nodelist *argbackq;
6066 /* first struct in list of ifs regions */
6067 static struct ifsregion ifsfirst;
6068 /* last struct in list */
6069 static struct ifsregion *ifslastp;
6070 /* holds expanded arg list */
6071 static struct arglist exparg;
6072
6073 /*
6074  * Our own itoa().
6075  * cvtnum() is used even if math support is off (to prepare $? values and such).
6076  */
6077 static int
6078 cvtnum(arith_t num)
6079 {
6080         int len;
6081
6082         /* 32-bit and wider ints require buffer size of bytes*3 (or less) */
6083         len = sizeof(arith_t) * 3;
6084         /* If narrower: worst case, 1-byte ints: need 5 bytes: "-127<NUL>" */
6085         if (sizeof(arith_t) < 4) len += 2;
6086
6087         expdest = makestrspace(len, expdest);
6088         len = fmtstr(expdest, len, ARITH_FMT, num);
6089         STADJUST(len, expdest);
6090         return len;
6091 }
6092
6093 /*
6094  * Break the argument string into pieces based upon IFS and add the
6095  * strings to the argument list.  The regions of the string to be
6096  * searched for IFS characters have been stored by recordregion.
6097  */
6098 static void
6099 ifsbreakup(char *string, struct arglist *arglist)
6100 {
6101         struct ifsregion *ifsp;
6102         struct strlist *sp;
6103         char *start;
6104         char *p;
6105         char *q;
6106         const char *ifs, *realifs;
6107         int ifsspc;
6108         int nulonly;
6109
6110         start = string;
6111         if (ifslastp != NULL) {
6112                 ifsspc = 0;
6113                 nulonly = 0;
6114                 realifs = ifsset() ? ifsval() : defifs;
6115                 ifsp = &ifsfirst;
6116                 do {
6117                         int afternul;
6118
6119                         p = string + ifsp->begoff;
6120                         afternul = nulonly;
6121                         nulonly = ifsp->nulonly;
6122                         ifs = nulonly ? nullstr : realifs;
6123                         ifsspc = 0;
6124                         while (p < string + ifsp->endoff) {
6125                                 q = p;
6126                                 if ((unsigned char)*p == CTLESC)
6127                                         p++;
6128                                 if (!strchr(ifs, *p)) {
6129                                         p++;
6130                                         continue;
6131                                 }
6132                                 if (!(afternul || nulonly))
6133                                         ifsspc = (strchr(defifs, *p) != NULL);
6134                                 /* Ignore IFS whitespace at start */
6135                                 if (q == start && ifsspc) {
6136                                         p++;
6137                                         start = p;
6138                                         continue;
6139                                 }
6140                                 *q = '\0';
6141                                 sp = stzalloc(sizeof(*sp));
6142                                 sp->text = start;
6143                                 *arglist->lastp = sp;
6144                                 arglist->lastp = &sp->next;
6145                                 p++;
6146                                 if (!nulonly) {
6147                                         for (;;) {
6148                                                 if (p >= string + ifsp->endoff) {
6149                                                         break;
6150                                                 }
6151                                                 q = p;
6152                                                 if ((unsigned char)*p == CTLESC)
6153                                                         p++;
6154                                                 if (strchr(ifs, *p) == NULL) {
6155                                                         p = q;
6156                                                         break;
6157                                                 }
6158                                                 if (strchr(defifs, *p) == NULL) {
6159                                                         if (ifsspc) {
6160                                                                 p++;
6161                                                                 ifsspc = 0;
6162                                                         } else {
6163                                                                 p = q;
6164                                                                 break;
6165                                                         }
6166                                                 } else
6167                                                         p++;
6168                                         }
6169                                 }
6170                                 start = p;
6171                         } /* while */
6172                         ifsp = ifsp->next;
6173                 } while (ifsp != NULL);
6174                 if (nulonly)
6175                         goto add;
6176         }
6177
6178         if (!*start)
6179                 return;
6180
6181  add:
6182         sp = stzalloc(sizeof(*sp));
6183         sp->text = start;
6184         *arglist->lastp = sp;
6185         arglist->lastp = &sp->next;
6186 }
6187
6188 static void
6189 ifsfree(void)
6190 {
6191         struct ifsregion *p = ifsfirst.next;
6192
6193         if (!p)
6194                 goto out;
6195
6196         INT_OFF;
6197         do {
6198                 struct ifsregion *ifsp;
6199                 ifsp = p->next;
6200                 free(p);
6201                 p = ifsp;
6202         } while (p);
6203         ifsfirst.next = NULL;
6204         INT_ON;
6205  out:
6206         ifslastp = NULL;
6207 }
6208
6209 static size_t
6210 esclen(const char *start, const char *p)
6211 {
6212         size_t esc = 0;
6213
6214         while (p > start && (unsigned char)*--p == CTLESC) {
6215                 esc++;
6216         }
6217         return esc;
6218 }
6219
6220 /*
6221  * Remove any CTLESC characters from a string.
6222  */
6223 #if !BASH_PATTERN_SUBST
6224 #define rmescapes(str, flag, slash_position) \
6225         rmescapes(str, flag)
6226 #endif
6227 static char *
6228 rmescapes(char *str, int flag, int *slash_position)
6229 {
6230         static const char qchars[] ALIGN1 = {
6231                 IF_BASH_PATTERN_SUBST('/',) CTLESC, CTLQUOTEMARK, '\0' };
6232
6233         char *p, *q, *r;
6234         unsigned protect_against_glob;
6235         unsigned globbing;
6236
6237         p = strpbrk(str, qchars IF_BASH_PATTERN_SUBST(+ !slash_position));
6238         if (!p)
6239                 return str;
6240
6241         q = p;
6242         r = str;
6243         if (flag & RMESCAPE_ALLOC) {
6244                 size_t len = p - str;
6245                 size_t fulllen = len + strlen(p) + 1;
6246
6247                 if (flag & RMESCAPE_GROW) {
6248                         int strloc = str - (char *)stackblock();
6249                         r = makestrspace(fulllen, expdest);
6250                         /* p and str may be invalidated by makestrspace */
6251                         str = (char *)stackblock() + strloc;
6252                         p = str + len;
6253                 } else if (flag & RMESCAPE_HEAP) {
6254                         r = ckmalloc(fulllen);
6255                 } else {
6256                         r = stalloc(fulllen);
6257                 }
6258                 q = r;
6259                 if (len > 0) {
6260                         q = (char *)mempcpy(q, str, len);
6261                 }
6262         }
6263
6264         globbing = flag & RMESCAPE_GLOB;
6265         protect_against_glob = globbing;
6266         while (*p) {
6267                 if ((unsigned char)*p == CTLQUOTEMARK) {
6268 // Note: protect_against_glob only affect whether
6269 // CTLESC,<ch> gets converted to <ch> or to \<ch>
6270                         p++;
6271                         protect_against_glob = globbing;
6272                         continue;
6273                 }
6274                 if (*p == '\\') {
6275                         /* naked back slash */
6276                         protect_against_glob = 0;
6277                         goto copy;
6278                 }
6279                 if ((unsigned char)*p == CTLESC) {
6280                         p++;
6281 #if DEBUG
6282                         if (*p == '\0')
6283                                 ash_msg_and_raise_error("CTLESC at EOL (shouldn't happen)");
6284 #endif
6285                         if (protect_against_glob) {
6286                                 /*
6287                                  * We used to trust glob() and fnmatch() to eat
6288                                  * superfluous escapes (\z where z has no
6289                                  * special meaning anyway). But this causes
6290                                  * bugs such as string of one greek letter rho
6291                                  * (unicode-encoded as two bytes "cf,81")
6292                                  * getting encoded as "cf,CTLESC,81"
6293                                  * and here, converted to "cf,\,81" -
6294                                  * which does not go well with some flavors
6295                                  * of fnmatch() in unicode locales
6296                                  * (for example, glibc <= 2.22).
6297                                  *
6298                                  * Lets add "\" only on the chars which need it.
6299                                  * Testcases for less obvious chars are shown.
6300                                  */
6301                                 if (*p == '*'
6302                                  || *p == '?'
6303                                  || *p == '['
6304                                  || *p == '\\' /* case '\' in \\    ) echo ok;; *) echo WRONG;; esac */
6305                                  || *p == ']'  /* case ']' in [a\]] ) echo ok;; *) echo WRONG;; esac */
6306                                  || *p == '-'  /* case '-' in [a\-c]) echo ok;; *) echo WRONG;; esac */
6307                                  || *p == '!'  /* case '!' in [\!]  ) echo ok;; *) echo WRONG;; esac */
6308                                 /* Some libc support [^negate], that's why "^" also needs love */
6309                                  || *p == '^'  /* case '^' in [\^]  ) echo ok;; *) echo WRONG;; esac */
6310                                 ) {
6311                                         *q++ = '\\';
6312                                 }
6313                         }
6314                 }
6315 #if BASH_PATTERN_SUBST
6316                 else if (slash_position && p == str + *slash_position) {
6317                         /* stop handling globbing */
6318                         globbing = 0;
6319                         *slash_position = q - r;
6320                         slash_position = NULL;
6321                 }
6322 #endif
6323                 protect_against_glob = globbing;
6324  copy:
6325                 *q++ = *p++;
6326         }
6327         *q = '\0';
6328         if (flag & RMESCAPE_GROW) {
6329                 expdest = r;
6330                 STADJUST(q - r + 1, expdest);
6331         }
6332         return r;
6333 }
6334 #define pmatch(a, b) !fnmatch((a), (b), 0)
6335
6336 /*
6337  * Prepare a pattern for a expmeta (internal glob(3)) call.
6338  *
6339  * Returns an stalloced string.
6340  */
6341 static char *
6342 preglob(const char *pattern, int flag)
6343 {
6344         return rmescapes((char *)pattern, flag | RMESCAPE_GLOB, NULL);
6345 }
6346
6347 /*
6348  * Put a string on the stack.
6349  */
6350 static void
6351 memtodest(const char *p, size_t len, int flags)
6352 {
6353         int syntax = flags & EXP_QUOTED ? DQSYNTAX : BASESYNTAX;
6354         char *q;
6355
6356         if (!len)
6357                 return;
6358
6359         q = makestrspace(len * 2, expdest);
6360
6361         do {
6362                 unsigned char c = *p++;
6363                 if (c) {
6364                         if (flags & QUOTES_ESC) {
6365                                 int n = SIT(c, syntax);
6366                                 if (n == CCTL
6367                                  || ((flags & EXP_QUOTED) && n == CBACK)
6368                                 ) {
6369                                         USTPUTC(CTLESC, q);
6370                                 }
6371                         }
6372                 } else if (!(flags & EXP_KEEPNUL))
6373                         continue;
6374                 USTPUTC(c, q);
6375         } while (--len);
6376
6377         expdest = q;
6378 }
6379
6380 static size_t
6381 strtodest(const char *p, int flags)
6382 {
6383         size_t len = strlen(p);
6384         memtodest(p, len, flags);
6385         return len;
6386 }
6387
6388 /*
6389  * Record the fact that we have to scan this region of the
6390  * string for IFS characters.
6391  */
6392 static void
6393 recordregion(int start, int end, int nulonly)
6394 {
6395         struct ifsregion *ifsp;
6396
6397         if (ifslastp == NULL) {
6398                 ifsp = &ifsfirst;
6399         } else {
6400                 INT_OFF;
6401                 ifsp = ckzalloc(sizeof(*ifsp));
6402                 /*ifsp->next = NULL; - ckzalloc did it */
6403                 ifslastp->next = ifsp;
6404                 INT_ON;
6405         }
6406         ifslastp = ifsp;
6407         ifslastp->begoff = start;
6408         ifslastp->endoff = end;
6409         ifslastp->nulonly = nulonly;
6410 }
6411
6412 static void
6413 removerecordregions(int endoff)
6414 {
6415         if (ifslastp == NULL)
6416                 return;
6417
6418         if (ifsfirst.endoff > endoff) {
6419                 while (ifsfirst.next) {
6420                         struct ifsregion *ifsp;
6421                         INT_OFF;
6422                         ifsp = ifsfirst.next->next;
6423                         free(ifsfirst.next);
6424                         ifsfirst.next = ifsp;
6425                         INT_ON;
6426                 }
6427                 if (ifsfirst.begoff > endoff) {
6428                         ifslastp = NULL;
6429                 } else {
6430                         ifslastp = &ifsfirst;
6431                         ifsfirst.endoff = endoff;
6432                 }
6433                 return;
6434         }
6435
6436         ifslastp = &ifsfirst;
6437         while (ifslastp->next && ifslastp->next->begoff < endoff)
6438                 ifslastp = ifslastp->next;
6439         while (ifslastp->next) {
6440                 struct ifsregion *ifsp;
6441                 INT_OFF;
6442                 ifsp = ifslastp->next->next;
6443                 free(ifslastp->next);
6444                 ifslastp->next = ifsp;
6445                 INT_ON;
6446         }
6447         if (ifslastp->endoff > endoff)
6448                 ifslastp->endoff = endoff;
6449 }
6450
6451 static char *
6452 exptilde(char *startp, char *p, int flag)
6453 {
6454         unsigned char c;
6455         char *name;
6456         struct passwd *pw;
6457         const char *home;
6458
6459         name = p + 1;
6460
6461         while ((c = *++p) != '\0') {
6462                 switch (c) {
6463                 case CTLESC:
6464                         return startp;
6465                 case CTLQUOTEMARK:
6466                         return startp;
6467                 case ':':
6468                         if (flag & EXP_VARTILDE)
6469                                 goto done;
6470                         break;
6471                 case '/':
6472                 case CTLENDVAR:
6473                         goto done;
6474                 }
6475         }
6476  done:
6477         *p = '\0';
6478         if (*name == '\0') {
6479                 home = lookupvar("HOME");
6480         } else {
6481                 pw = getpwnam(name);
6482                 if (pw == NULL)
6483                         goto lose;
6484                 home = pw->pw_dir;
6485         }
6486         if (!home)
6487                 goto lose;
6488         *p = c;
6489         strtodest(home, flag | EXP_QUOTED);
6490         return p;
6491  lose:
6492         *p = c;
6493         return startp;
6494 }
6495
6496 /*
6497  * Execute a command inside back quotes.  If it's a builtin command, we
6498  * want to save its output in a block obtained from malloc.  Otherwise
6499  * we fork off a subprocess and get the output of the command via a pipe.
6500  * Should be called with interrupts off.
6501  */
6502 struct backcmd {                /* result of evalbackcmd */
6503         int fd;                 /* file descriptor to read from */
6504         int nleft;              /* number of chars in buffer */
6505         char *buf;              /* buffer */
6506         struct job *jp;         /* job structure for command */
6507 };
6508
6509 /* These forward decls are needed to use "eval" code for backticks handling: */
6510 /* flags in argument to evaltree */
6511 #define EV_EXIT    01           /* exit after evaluating tree */
6512 #define EV_TESTED  02           /* exit status is checked; ignore -e flag */
6513 static int evaltree(union node *, int);
6514
6515 /* An evaltree() which is known to never return.
6516  * Used to use an alias:
6517  * static int evaltreenr(union node *, int) __attribute__((alias("evaltree"),__noreturn__));
6518  * but clang was reported to "transfer" noreturn-ness to evaltree() as well.
6519  */
6520 static ALWAYS_INLINE NORETURN void
6521 evaltreenr(union node *n, int flags)
6522 {
6523         evaltree(n, flags);
6524         bb_unreachable(abort());
6525         /* NOTREACHED */
6526 }
6527
6528 static void FAST_FUNC
6529 evalbackcmd(union node *n, struct backcmd *result)
6530 {
6531         int pip[2];
6532         struct job *jp;
6533
6534         result->fd = -1;
6535         result->buf = NULL;
6536         result->nleft = 0;
6537         result->jp = NULL;
6538         if (n == NULL) {
6539                 goto out;
6540         }
6541
6542         if (pipe(pip) < 0)
6543                 ash_msg_and_raise_perror("can't create pipe");
6544         jp = makejob(/*n,*/ 1);
6545         if (forkshell(jp, n, FORK_NOJOB) == 0) {
6546                 /* child */
6547                 FORCE_INT_ON;
6548                 close(pip[0]);
6549                 if (pip[1] != 1) {
6550                         /*close(1);*/
6551                         dup2_or_raise(pip[1], 1);
6552                         close(pip[1]);
6553                 }
6554 /* TODO: eflag clearing makes the following not abort:
6555  *  ash -c 'set -e; z=$(false;echo foo); echo $z'
6556  * which is what bash does (unless it is in POSIX mode).
6557  * dash deleted "eflag = 0" line in the commit
6558  *  Date: Mon, 28 Jun 2010 17:11:58 +1000
6559  *  [EVAL] Don't clear eflag in evalbackcmd
6560  * For now, preserve bash-like behavior, it seems to be somewhat more useful:
6561  */
6562                 eflag = 0;
6563                 ifsfree();
6564                 evaltreenr(n, EV_EXIT);
6565                 /* NOTREACHED */
6566         }
6567         /* parent */
6568         close(pip[1]);
6569         result->fd = pip[0];
6570         result->jp = jp;
6571
6572  out:
6573         TRACE(("evalbackcmd done: fd=%d buf=0x%x nleft=%d jp=0x%x\n",
6574                 result->fd, result->buf, result->nleft, result->jp));
6575 }
6576
6577 /*
6578  * Expand stuff in backwards quotes.
6579  */
6580 static void
6581 expbackq(union node *cmd, int flag)
6582 {
6583         struct backcmd in;
6584         int i;
6585         char buf[128];
6586         char *p;
6587         char *dest;
6588         int startloc;
6589         struct stackmark smark;
6590
6591         INT_OFF;
6592         startloc = expdest - (char *)stackblock();
6593         pushstackmark(&smark, startloc);
6594         evalbackcmd(cmd, &in);
6595         popstackmark(&smark);
6596
6597         p = in.buf;
6598         i = in.nleft;
6599         if (i == 0)
6600                 goto read;
6601         for (;;) {
6602                 memtodest(p, i, flag);
6603  read:
6604                 if (in.fd < 0)
6605                         break;
6606                 i = nonblock_immune_read(in.fd, buf, sizeof(buf));
6607                 TRACE(("expbackq: read returns %d\n", i));
6608                 if (i <= 0)
6609                         break;
6610                 p = buf;
6611         }
6612
6613         free(in.buf);
6614         if (in.fd >= 0) {
6615                 close(in.fd);
6616                 back_exitstatus = waitforjob(in.jp);
6617         }
6618         INT_ON;
6619
6620         /* Eat all trailing newlines */
6621         dest = expdest;
6622         for (; dest > ((char *)stackblock() + startloc) && dest[-1] == '\n';)
6623                 STUNPUTC(dest);
6624         expdest = dest;
6625
6626         if (!(flag & EXP_QUOTED))
6627                 recordregion(startloc, dest - (char *)stackblock(), 0);
6628         TRACE(("evalbackq: size:%d:'%.*s'\n",
6629                 (int)((dest - (char *)stackblock()) - startloc),
6630                 (int)((dest - (char *)stackblock()) - startloc),
6631                 stackblock() + startloc));
6632 }
6633
6634 #if ENABLE_FEATURE_SH_MATH
6635 /*
6636  * Expand arithmetic expression.  Backup to start of expression,
6637  * evaluate, place result in (backed up) result, adjust string position.
6638  */
6639 static void
6640 expari(int flag)
6641 {
6642         char *p, *start;
6643         int begoff;
6644         int len;
6645
6646         /* ifsfree(); */
6647
6648         /*
6649          * This routine is slightly over-complicated for
6650          * efficiency.  Next we scan backwards looking for the
6651          * start of arithmetic.
6652          */
6653         start = stackblock();
6654         p = expdest - 1;
6655         *p = '\0';
6656         p--;
6657         while (1) {
6658                 int esc;
6659
6660                 while ((unsigned char)*p != CTLARI) {
6661                         p--;
6662 #if DEBUG
6663                         if (p < start) {
6664                                 ash_msg_and_raise_error("missing CTLARI (shouldn't happen)");
6665                         }
6666 #endif
6667                 }
6668
6669                 esc = esclen(start, p);
6670                 if (!(esc % 2)) {
6671                         break;
6672                 }
6673
6674                 p -= esc + 1;
6675         }
6676
6677         begoff = p - start;
6678
6679         removerecordregions(begoff);
6680
6681         expdest = p;
6682
6683         if (flag & QUOTES_ESC)
6684                 rmescapes(p + 1, 0, NULL);
6685
6686         len = cvtnum(ash_arith(p + 1));
6687
6688         if (!(flag & EXP_QUOTED))
6689                 recordregion(begoff, begoff + len, 0);
6690 }
6691 #endif
6692
6693 /* argstr needs it */
6694 static char *evalvar(char *p, int flags);
6695
6696 /*
6697  * Perform variable and command substitution.  If EXP_FULL is set, output CTLESC
6698  * characters to allow for further processing.  Otherwise treat
6699  * $@ like $* since no splitting will be performed.
6700  */
6701 static void
6702 argstr(char *p, int flags)
6703 {
6704         static const char spclchars[] ALIGN1 = {
6705                 '=',
6706                 ':',
6707                 CTLQUOTEMARK,
6708                 CTLENDVAR,
6709                 CTLESC,
6710                 CTLVAR,
6711                 CTLBACKQ,
6712 #if ENABLE_FEATURE_SH_MATH
6713                 CTLENDARI,
6714 #endif
6715                 '\0'
6716         };
6717         const char *reject = spclchars;
6718         int breakall = (flags & (EXP_WORD | EXP_QUOTED)) == EXP_WORD;
6719         int inquotes;
6720         size_t length;
6721         int startloc;
6722
6723         if (!(flags & EXP_VARTILDE)) {
6724                 reject += 2;
6725         } else if (flags & EXP_VARTILDE2) {
6726                 reject++;
6727         }
6728         inquotes = 0;
6729         length = 0;
6730         if (flags & EXP_TILDE) {
6731                 char *q;
6732
6733                 flags &= ~EXP_TILDE;
6734  tilde:
6735                 q = p;
6736                 if (*q == '~')
6737                         p = exptilde(p, q, flags);
6738         }
6739  start:
6740         startloc = expdest - (char *)stackblock();
6741         for (;;) {
6742                 unsigned char c;
6743
6744                 length += strcspn(p + length, reject);
6745                 c = p[length];
6746                 if (c) {
6747                         if (!(c & 0x80)
6748                         IF_FEATURE_SH_MATH(|| c == CTLENDARI)
6749                         ) {
6750                                 /* c == '=' || c == ':' || c == CTLENDARI */
6751                                 length++;
6752                         }
6753                 }
6754                 if (length > 0) {
6755                         int newloc;
6756                         expdest = stack_nputstr(p, length, expdest);
6757                         newloc = expdest - (char *)stackblock();
6758                         if (breakall && !inquotes && newloc > startloc) {
6759                                 recordregion(startloc, newloc, 0);
6760                         }
6761                         startloc = newloc;
6762                 }
6763                 p += length + 1;
6764                 length = 0;
6765
6766                 switch (c) {
6767                 case '\0':
6768                         goto breakloop;
6769                 case '=':
6770                         if (flags & EXP_VARTILDE2) {
6771                                 p--;
6772                                 continue;
6773                         }
6774                         flags |= EXP_VARTILDE2;
6775                         reject++;
6776                         /* fall through */
6777                 case ':':
6778                         /*
6779                          * sort of a hack - expand tildes in variable
6780                          * assignments (after the first '=' and after ':'s).
6781                          */
6782                         if (*--p == '~') {
6783                                 goto tilde;
6784                         }
6785                         continue;
6786                 }
6787
6788                 switch (c) {
6789                 case CTLENDVAR: /* ??? */
6790                         goto breakloop;
6791                 case CTLQUOTEMARK:
6792                         /* "$@" syntax adherence hack */
6793                         if (!inquotes && !memcmp(p, dolatstr + 1, DOLATSTRLEN - 1)) {
6794                                 p = evalvar(p + 1, flags | EXP_QUOTED) + 1;
6795                                 goto start;
6796                         }
6797                         inquotes ^= EXP_QUOTED;
6798  addquote:
6799                         if (flags & QUOTES_ESC) {
6800                                 p--;
6801                                 length++;
6802                                 startloc++;
6803                         }
6804                         break;
6805                 case CTLESC:
6806                         startloc++;
6807                         length++;
6808                         goto addquote;
6809                 case CTLVAR:
6810                         TRACE(("argstr: evalvar('%s')\n", p));
6811                         p = evalvar(p, flags | inquotes);
6812                         TRACE(("argstr: evalvar:'%s'\n", (char *)stackblock()));
6813                         goto start;
6814                 case CTLBACKQ:
6815                         expbackq(argbackq->n, flags | inquotes);
6816                         argbackq = argbackq->next;
6817                         goto start;
6818 #if ENABLE_FEATURE_SH_MATH
6819                 case CTLENDARI:
6820                         p--;
6821                         expari(flags | inquotes);
6822                         goto start;
6823 #endif
6824                 }
6825         }
6826  breakloop: ;
6827 }
6828
6829 static char *
6830 scanleft(char *startp, char *rmesc, char *rmescend UNUSED_PARAM,
6831                 char *pattern, int quotes, int zero)
6832 {
6833         char *loc, *loc2;
6834         char c;
6835
6836         loc = startp;
6837         loc2 = rmesc;
6838         do {
6839                 int match;
6840                 const char *s = loc2;
6841
6842                 c = *loc2;
6843                 if (zero) {
6844                         *loc2 = '\0';
6845                         s = rmesc;
6846                 }
6847                 match = pmatch(pattern, s);
6848
6849                 *loc2 = c;
6850                 if (match)
6851                         return loc;
6852                 if (quotes && (unsigned char)*loc == CTLESC)
6853                         loc++;
6854                 loc++;
6855                 loc2++;
6856         } while (c);
6857         return NULL;
6858 }
6859
6860 static char *
6861 scanright(char *startp, char *rmesc, char *rmescend,
6862                 char *pattern, int quotes, int match_at_start)
6863 {
6864 #if !ENABLE_ASH_OPTIMIZE_FOR_SIZE
6865         int try2optimize = match_at_start;
6866 #endif
6867         int esc = 0;
6868         char *loc;
6869         char *loc2;
6870
6871         /* If we called by "${v/pattern/repl}" or "${v//pattern/repl}":
6872          * startp="escaped_value_of_v" rmesc="raw_value_of_v"
6873          * rmescend=""(ptr to NUL in rmesc) pattern="pattern" quotes=match_at_start=1
6874          * Logic:
6875          * loc starts at NUL at the end of startp, loc2 starts at the end of rmesc,
6876          * and on each iteration they go back two/one char until they reach the beginning.
6877          * We try to find a match in "raw_value_of_v", "raw_value_of_", "raw_value_of" etc.
6878          */
6879         /* TODO: document in what other circumstances we are called. */
6880
6881         for (loc = pattern - 1, loc2 = rmescend; loc >= startp; loc2--) {
6882                 int match;
6883                 char c = *loc2;
6884                 const char *s = loc2;
6885                 if (match_at_start) {
6886                         *loc2 = '\0';
6887                         s = rmesc;
6888                 }
6889                 match = pmatch(pattern, s);
6890                 //bb_error_msg("pmatch(pattern:'%s',s:'%s'):%d", pattern, s, match);
6891                 *loc2 = c;
6892                 if (match)
6893                         return loc;
6894 #if !ENABLE_ASH_OPTIMIZE_FOR_SIZE
6895                 if (try2optimize) {
6896                         /* Maybe we can optimize this:
6897                          * if pattern ends with unescaped *, we can avoid checking
6898                          * shorter strings: if "foo*" doesn't match "raw_value_of_v",
6899                          * it won't match truncated "raw_value_of_" strings too.
6900                          */
6901                         unsigned plen = strlen(pattern);
6902                         /* Does it end with "*"? */
6903                         if (plen != 0 && pattern[--plen] == '*') {
6904                                 /* "xxxx*" is not escaped */
6905                                 /* "xxx\*" is escaped */
6906                                 /* "xx\\*" is not escaped */
6907                                 /* "x\\\*" is escaped */
6908                                 int slashes = 0;
6909                                 while (plen != 0 && pattern[--plen] == '\\')
6910                                         slashes++;
6911                                 if (!(slashes & 1))
6912                                         break; /* ends with unescaped "*" */
6913                         }
6914                         try2optimize = 0;
6915                 }
6916 #endif
6917                 loc--;
6918                 if (quotes) {
6919                         if (--esc < 0) {
6920                                 esc = esclen(startp, loc);
6921                         }
6922                         if (esc % 2) {
6923                                 esc--;
6924                                 loc--;
6925                         }
6926                 }
6927         }
6928         return NULL;
6929 }
6930
6931 static void varunset(const char *, const char *, const char *, int) NORETURN;
6932 static void
6933 varunset(const char *end, const char *var, const char *umsg, int varflags)
6934 {
6935         const char *msg;
6936         const char *tail;
6937
6938         tail = nullstr;
6939         msg = "parameter not set";
6940         if (umsg) {
6941                 if ((unsigned char)*end == CTLENDVAR) {
6942                         if (varflags & VSNUL)
6943                                 tail = " or null";
6944                 } else {
6945                         msg = umsg;
6946                 }
6947         }
6948         ash_msg_and_raise_error("%.*s: %s%s", (int)(end - var - 1), var, msg, tail);
6949 }
6950
6951 static const char *
6952 subevalvar(char *p, char *varname, int strloc, int subtype,
6953                 int startloc, int varflags, int flag)
6954 {
6955         struct nodelist *saveargbackq = argbackq;
6956         int quotes = flag & QUOTES_ESC;
6957         char *startp;
6958         char *loc;
6959         char *rmesc, *rmescend;
6960         char *str;
6961         int amount, resetloc;
6962         int argstr_flags;
6963         IF_BASH_PATTERN_SUBST(int workloc;)
6964         IF_BASH_PATTERN_SUBST(int slash_pos;)
6965         IF_BASH_PATTERN_SUBST(char *repl;)
6966         int zero;
6967         char *(*scan)(char*, char*, char*, char*, int, int);
6968
6969         //bb_error_msg("subevalvar(p:'%s',varname:'%s',strloc:%d,subtype:%d,startloc:%d,varflags:%x,quotes:%d)",
6970         //              p, varname, strloc, subtype, startloc, varflags, quotes);
6971
6972 #if BASH_PATTERN_SUBST
6973         /* For "${v/pattern/repl}", we must find the delimiter _before_
6974          * argstr() call expands possible variable references in pattern:
6975          * think about "v=a; a=a/; echo ${v/$a/r}" case.
6976          */
6977         repl = NULL;
6978         if (subtype == VSREPLACE || subtype == VSREPLACEALL) {
6979                 /* Find '/' and replace with NUL */
6980                 repl = p;
6981                 /* The pattern can't be empty.
6982                  * IOW: if the first char after "${v//" is a slash,
6983                  * it does not terminate the pattern - it's the first char of the pattern:
6984                  *  v=/dev/ram; echo ${v////-}  prints -dev-ram (pattern is "/")
6985                  *  v=/dev/ram; echo ${v///r/-} prints /dev-am  (pattern is "/r")
6986                  */
6987                 if (*repl == '/')
6988                         repl++;
6989                 for (;;) {
6990                         if (*repl == '\0') {
6991                                 repl = NULL;
6992                                 break;
6993                         }
6994                         if (*repl == '/') {
6995                                 *repl = '\0';
6996                                 break;
6997                         }
6998                         /* Handle escaped slashes, e.g. "${v/\//_}" (they are CTLESC'ed by this point) */
6999                         if ((unsigned char)*repl == CTLESC && repl[1])
7000                                 repl++;
7001                         repl++;
7002                 }
7003         }
7004 #endif
7005         argstr_flags = EXP_TILDE;
7006         if (subtype != VSASSIGN
7007          && subtype != VSQUESTION
7008 #if BASH_SUBSTR
7009          && subtype != VSSUBSTR
7010 #endif
7011         ) {
7012                 /* EXP_CASE keeps CTLESC's */
7013                 argstr_flags = EXP_TILDE | EXP_CASE;
7014         }
7015         argstr(p, argstr_flags);
7016         //bb_error_msg("str0:'%s'", (char *)stackblock() + strloc);
7017 #if BASH_PATTERN_SUBST
7018         slash_pos = -1;
7019         if (repl) {
7020                 slash_pos = expdest - ((char *)stackblock() + strloc);
7021                 STPUTC('/', expdest);
7022                 //bb_error_msg("repl+1:'%s'", repl + 1);
7023                 argstr(repl + 1, EXP_TILDE); /* EXP_TILDE: echo "${v/x/~}" expands ~ ! */
7024                 *repl = '/';
7025         }
7026 #endif
7027         STPUTC('\0', expdest);
7028         argbackq = saveargbackq;
7029         startp = (char *)stackblock() + startloc;
7030         //bb_error_msg("str1:'%s'", (char *)stackblock() + strloc);
7031
7032         switch (subtype) {
7033         case VSASSIGN:
7034                 setvar0(varname, startp);
7035                 amount = startp - expdest;
7036                 STADJUST(amount, expdest);
7037                 return startp;
7038
7039         case VSQUESTION:
7040                 varunset(p, varname, startp, varflags);
7041                 /* NOTREACHED */
7042
7043 #if BASH_SUBSTR
7044         case VSSUBSTR: {
7045                 int pos, len, orig_len;
7046                 char *colon;
7047
7048                 loc = str = stackblock() + strloc;
7049
7050                 /* Read POS in ${var:POS:LEN} */
7051                 colon = strchr(loc, ':');
7052                 if (colon) *colon = '\0';
7053                 pos = substr_atoi(loc);
7054                 if (colon) *colon = ':';
7055
7056                 /* Read LEN in ${var:POS:LEN} */
7057                 len = str - startp - 1;
7058                 /* *loc != '\0', guaranteed by parser */
7059                 if (quotes) {
7060                         char *ptr;
7061                         /* Adjust the length by the number of escapes */
7062                         for (ptr = startp; ptr < (str - 1); ptr++) {
7063                                 if ((unsigned char)*ptr == CTLESC) {
7064                                         len--;
7065                                         ptr++;
7066                                 }
7067                         }
7068                 }
7069                 orig_len = len;
7070                 if (*loc++ == ':') {
7071                         /* ${var::LEN} */
7072                         len = substr_atoi(loc);
7073                 } else {
7074                         /* Skip POS in ${var:POS:LEN} */
7075                         len = orig_len;
7076                         while (*loc && *loc != ':')
7077                                 loc++;
7078                         if (*loc++ == ':')
7079                                 len = substr_atoi(loc);
7080                 }
7081                 if (pos < 0) {
7082                         /* ${VAR:$((-n)):l} starts n chars from the end */
7083                         pos = orig_len + pos;
7084                 }
7085                 if ((unsigned)pos >= orig_len) {
7086                         /* apart from obvious ${VAR:999999:l},
7087                          * covers ${VAR:$((-9999999)):l} - result is ""
7088                          * (bash compat)
7089                          */
7090                         pos = 0;
7091                         len = 0;
7092                 }
7093                 if (len < 0) {
7094                         /* ${VAR:N:-M} sets LEN to strlen()-M */
7095                         len = (orig_len - pos) + len;
7096                 }
7097                 if ((unsigned)len > (orig_len - pos))
7098                         len = orig_len - pos;
7099
7100                 for (str = startp; pos; str++, pos--) {
7101                         if (quotes && (unsigned char)*str == CTLESC)
7102                                 str++;
7103                 }
7104                 for (loc = startp; len; len--) {
7105                         if (quotes && (unsigned char)*str == CTLESC)
7106                                 *loc++ = *str++;
7107                         *loc++ = *str++;
7108                 }
7109                 *loc = '\0';
7110                 amount = loc - expdest;
7111                 STADJUST(amount, expdest);
7112                 return loc;
7113         }
7114 #endif /* BASH_SUBSTR */
7115         }
7116
7117         resetloc = expdest - (char *)stackblock();
7118
7119 #if BASH_PATTERN_SUBST
7120         repl = NULL;
7121
7122         /* We'll comeback here if we grow the stack while handling
7123          * a VSREPLACE or VSREPLACEALL, since our pointers into the
7124          * stack will need rebasing, and we'll need to remove our work
7125          * areas each time
7126          */
7127  restart:
7128 #endif
7129
7130         amount = expdest - ((char *)stackblock() + resetloc);
7131         STADJUST(-amount, expdest);
7132         startp = (char *)stackblock() + startloc;
7133
7134         rmesc = startp;
7135         rmescend = (char *)stackblock() + strloc;
7136         //bb_error_msg("str7:'%s'", rmescend);
7137         if (quotes) {
7138 //TODO: how to handle slash_pos here if string changes (shortens?)
7139                 rmesc = rmescapes(startp, RMESCAPE_ALLOC | RMESCAPE_GROW, NULL);
7140                 if (rmesc != startp) {
7141                         rmescend = expdest;
7142                         startp = (char *)stackblock() + startloc;
7143                 }
7144         }
7145         rmescend--;
7146         str = (char *)stackblock() + strloc;
7147         /*
7148          * Example: v='a\bc'; echo ${v/\\b/_\\_\z_}
7149          * The result is a_\_z_c (not a\_\_z_c)!
7150          *
7151          * The search pattern and replace string treat backslashes differently!
7152          * "&slash_pos" causes rmescapes() to work differently on the pattern
7153          * and string.  It's only used on the first call.
7154          */
7155         //bb_error_msg("str8:'%s' slash_pos:%d", str, slash_pos);
7156         rmescapes(str, RMESCAPE_GLOB,
7157                 repl ? NULL : (slash_pos < 0 ? NULL : &slash_pos)
7158         );
7159
7160 #if BASH_PATTERN_SUBST
7161         workloc = expdest - (char *)stackblock();
7162         if (subtype == VSREPLACE || subtype == VSREPLACEALL) {
7163                 int len;
7164                 char *idx, *end;
7165
7166                 if (!repl) {
7167                         //bb_error_msg("str9:'%s' slash_pos:%d", str, slash_pos);
7168                         repl = nullstr;
7169                         if (slash_pos >= 0) {
7170                                 repl = str + slash_pos;
7171                                 *repl++ = '\0';
7172                         }
7173                 }
7174                 //bb_error_msg("str:'%s' repl:'%s'", str, repl);
7175
7176                 /* If there's no pattern to match, return the expansion unmolested */
7177                 if (str[0] == '\0')
7178                         return NULL;
7179
7180                 len = 0;
7181                 idx = startp;
7182                 end = str - 1;
7183                 while (idx < end) {
7184  try_to_match:
7185                         loc = scanright(idx, rmesc, rmescend, str, quotes, 1);
7186                         //bb_error_msg("scanright('%s'):'%s'", str, loc);
7187                         if (!loc) {
7188                                 /* No match, advance */
7189                                 char *restart_detect = stackblock();
7190  skip_matching:
7191                                 STPUTC(*idx, expdest);
7192                                 if (quotes && (unsigned char)*idx == CTLESC) {
7193                                         idx++;
7194                                         len++;
7195                                         STPUTC(*idx, expdest);
7196                                 }
7197                                 if (stackblock() != restart_detect)
7198                                         goto restart;
7199                                 idx++;
7200                                 len++;
7201                                 rmesc++;
7202                                 /* continue; - prone to quadratic behavior, smarter code: */
7203                                 if (idx >= end)
7204                                         break;
7205                                 if (str[0] == '*') {
7206                                         /* Pattern is "*foo". If "*foo" does not match "long_string",
7207                                          * it would never match "ong_string" etc, no point in trying.
7208                                          */
7209                                         goto skip_matching;
7210                                 }
7211                                 goto try_to_match;
7212                         }
7213
7214                         if (subtype == VSREPLACEALL) {
7215                                 while (idx < loc) {
7216                                         if (quotes && (unsigned char)*idx == CTLESC)
7217                                                 idx++;
7218                                         idx++;
7219                                         rmesc++;
7220                                 }
7221                         } else {
7222                                 idx = loc;
7223                         }
7224
7225                         //bb_error_msg("repl:'%s'", repl);
7226                         for (loc = (char*)repl; *loc; loc++) {
7227                                 char *restart_detect = stackblock();
7228                                 if (quotes && *loc == '\\') {
7229                                         STPUTC(CTLESC, expdest);
7230                                         len++;
7231                                 }
7232                                 STPUTC(*loc, expdest);
7233                                 if (stackblock() != restart_detect)
7234                                         goto restart;
7235                                 len++;
7236                         }
7237
7238                         if (subtype == VSREPLACE) {
7239                                 //bb_error_msg("tail:'%s', quotes:%x", idx, quotes);
7240                                 while (*idx) {
7241                                         char *restart_detect = stackblock();
7242                                         STPUTC(*idx, expdest);
7243                                         if (stackblock() != restart_detect)
7244                                                 goto restart;
7245                                         len++;
7246                                         idx++;
7247                                 }
7248                                 break;
7249                         }
7250                 }
7251
7252                 /* We've put the replaced text into a buffer at workloc, now
7253                  * move it to the right place and adjust the stack.
7254                  */
7255                 STPUTC('\0', expdest);
7256                 startp = (char *)stackblock() + startloc;
7257                 memmove(startp, (char *)stackblock() + workloc, len + 1);
7258                 //bb_error_msg("startp:'%s'", startp);
7259                 amount = expdest - (startp + len);
7260                 STADJUST(-amount, expdest);
7261                 return startp;
7262         }
7263 #endif /* BASH_PATTERN_SUBST */
7264
7265         subtype -= VSTRIMRIGHT;
7266 #if DEBUG
7267         if (subtype < 0 || subtype > 7)
7268                 abort();
7269 #endif
7270         /* zero = (subtype == VSTRIMLEFT || subtype == VSTRIMLEFTMAX) */
7271         zero = subtype >> 1;
7272         /* VSTRIMLEFT/VSTRIMRIGHTMAX -> scanleft */
7273         scan = (subtype & 1) ^ zero ? scanleft : scanright;
7274
7275         loc = scan(startp, rmesc, rmescend, str, quotes, zero);
7276         if (loc) {
7277                 if (zero) {
7278                         memmove(startp, loc, str - loc);
7279                         loc = startp + (str - loc) - 1;
7280                 }
7281                 *loc = '\0';
7282                 amount = loc - expdest;
7283                 STADJUST(amount, expdest);
7284         }
7285         return loc;
7286 }
7287
7288 /*
7289  * Add the value of a specialized variable to the stack string.
7290  * name parameter (examples):
7291  * ash -c 'echo $1'      name:'1='
7292  * ash -c 'echo $qwe'    name:'qwe='
7293  * ash -c 'echo $$'      name:'$='
7294  * ash -c 'echo ${$}'    name:'$='
7295  * ash -c 'echo ${$##q}' name:'$=q'
7296  * ash -c 'echo ${#$}'   name:'$='
7297  * note: examples with bad shell syntax:
7298  * ash -c 'echo ${#$1}'  name:'$=1'
7299  * ash -c 'echo ${#1#}'  name:'1=#'
7300  */
7301 static NOINLINE ssize_t
7302 varvalue(char *name, int varflags, int flags, int quoted)
7303 {
7304         const char *p;
7305         int num;
7306         int i;
7307         ssize_t len = 0;
7308         int sep;
7309         int subtype = varflags & VSTYPE;
7310         int discard = subtype == VSPLUS || subtype == VSLENGTH;
7311
7312         flags |= EXP_KEEPNUL;
7313         flags &= discard ? ~QUOTES_ESC : ~0;
7314         sep = (flags & EXP_FULL) << CHAR_BIT;
7315
7316         switch (*name) {
7317         case '$':
7318                 num = rootpid;
7319                 goto numvar;
7320         case '?':
7321                 num = exitstatus;
7322                 goto numvar;
7323         case '#':
7324                 num = shellparam.nparam;
7325                 goto numvar;
7326         case '!':
7327                 num = backgndpid;
7328                 if (num == 0)
7329                         return -1;
7330  numvar:
7331                 len = cvtnum(num);
7332                 goto check_1char_name;
7333         case '-':
7334                 expdest = makestrspace(NOPTS, expdest);
7335                 for (i = NOPTS - 1; i >= 0; i--) {
7336                         if (optlist[i] && optletters(i)) {
7337                                 USTPUTC(optletters(i), expdest);
7338                                 len++;
7339                         }
7340                 }
7341  check_1char_name:
7342 #if 0
7343                 /* handles cases similar to ${#$1} */
7344                 if (name[2] != '\0')
7345                         raise_error_syntax("bad substitution");
7346 #endif
7347                 break;
7348         case '@':
7349                 if (quoted && sep)
7350                         goto param;
7351                 /* fall through */
7352         case '*': {
7353                 char **ap;
7354                 char sepc;
7355                 char c;
7356
7357                 /* We will set c to 0 or ~0 depending on whether
7358                  * we're doing field splitting.  We won't do field
7359                  * splitting if either we're quoted or sep is zero.
7360                  *
7361                  * Instead of testing (quoted || !sep) the following
7362                  * trick optimises away any branches by using the
7363                  * fact that EXP_QUOTED (which is the only bit that
7364                  * can be set in quoted) is the same as EXP_FULL <<
7365                  * CHAR_BIT (which is the only bit that can be set
7366                  * in sep).
7367                  */
7368 #if EXP_QUOTED >> CHAR_BIT != EXP_FULL
7369 #error The following two lines expect EXP_QUOTED == EXP_FULL << CHAR_BIT
7370 #endif
7371                 c = !((quoted | ~sep) & EXP_QUOTED) - 1;
7372                 sep &= ~quoted;
7373                 sep |= ifsset() ? (unsigned char)(c & ifsval()[0]) : ' ';
7374  param:
7375                 sepc = sep;
7376                 ap = shellparam.p;
7377                 if (!ap)
7378                         return -1;
7379                 while ((p = *ap++) != NULL) {
7380                         len += strtodest(p, flags);
7381
7382                         if (*ap && sep) {
7383                                 len++;
7384                                 memtodest(&sepc, 1, flags);
7385                         }
7386                 }
7387                 break;
7388         } /* case '*' */
7389         case '0':
7390         case '1':
7391         case '2':
7392         case '3':
7393         case '4':
7394         case '5':
7395         case '6':
7396         case '7':
7397         case '8':
7398         case '9':
7399                 num = atoi(name); /* number(name) fails on ${N#str} etc */
7400                 if (num < 0 || num > shellparam.nparam)
7401                         return -1;
7402                 p = num ? shellparam.p[num - 1] : arg0;
7403                 goto value;
7404         default:
7405                 /* NB: name has form "VAR=..." */
7406                 p = lookupvar(name);
7407  value:
7408                 if (!p)
7409                         return -1;
7410
7411                 len = strtodest(p, flags);
7412 #if ENABLE_UNICODE_SUPPORT
7413                 if (subtype == VSLENGTH && len > 0) {
7414                         reinit_unicode_for_ash();
7415                         if (unicode_status == UNICODE_ON) {
7416                                 STADJUST(-len, expdest);
7417                                 discard = 0;
7418                                 len = unicode_strlen(p);
7419                         }
7420                 }
7421 #endif
7422                 break;
7423         }
7424
7425         if (discard)
7426                 STADJUST(-len, expdest);
7427         return len;
7428 }
7429
7430 /*
7431  * Expand a variable, and return a pointer to the next character in the
7432  * input string.
7433  */
7434 static char *
7435 evalvar(char *p, int flag)
7436 {
7437         char varflags;
7438         char subtype;
7439         int quoted;
7440         char *var;
7441         int patloc;
7442         int startloc;
7443         ssize_t varlen;
7444
7445         varflags = (unsigned char) *p++;
7446         subtype = varflags & VSTYPE;
7447
7448         if (!subtype)
7449                 raise_error_syntax("bad substitution");
7450
7451         quoted = flag & EXP_QUOTED;
7452         var = p;
7453         startloc = expdest - (char *)stackblock();
7454         p = strchr(p, '=') + 1; //TODO: use var_end(p)?
7455
7456  again:
7457         varlen = varvalue(var, varflags, flag, quoted);
7458         if (varflags & VSNUL)
7459                 varlen--;
7460
7461         if (subtype == VSPLUS) {
7462                 varlen = -1 - varlen;
7463                 goto vsplus;
7464         }
7465
7466         if (subtype == VSMINUS) {
7467  vsplus:
7468                 if (varlen < 0) {
7469                         argstr(
7470                                 p,
7471                                 flag | EXP_TILDE | EXP_WORD
7472                         );
7473                         goto end;
7474                 }
7475                 goto record;
7476         }
7477
7478         if (subtype == VSASSIGN || subtype == VSQUESTION) {
7479                 if (varlen >= 0)
7480                         goto record;
7481
7482                 subevalvar(p, var, 0, subtype, startloc, varflags,
7483                            flag & ~QUOTES_ESC);
7484                 varflags &= ~VSNUL;
7485                 /*
7486                  * Remove any recorded regions beyond
7487                  * start of variable
7488                  */
7489                 removerecordregions(startloc);
7490                 goto again;
7491         }
7492
7493         if (varlen < 0 && uflag)
7494                 varunset(p, var, 0, 0);
7495
7496         if (subtype == VSLENGTH) {
7497                 cvtnum(varlen > 0 ? varlen : 0);
7498                 goto record;
7499         }
7500
7501         if (subtype == VSNORMAL) {
7502  record:
7503                 if (quoted) {
7504                         quoted = *var == '@' && shellparam.nparam;
7505                         if (!quoted)
7506                                 goto end;
7507                 }
7508                 recordregion(startloc, expdest - (char *)stackblock(), quoted);
7509                 goto end;
7510         }
7511
7512 #if DEBUG
7513         switch (subtype) {
7514         case VSTRIMLEFT:
7515         case VSTRIMLEFTMAX:
7516         case VSTRIMRIGHT:
7517         case VSTRIMRIGHTMAX:
7518 #if BASH_SUBSTR
7519         case VSSUBSTR:
7520 #endif
7521 #if BASH_PATTERN_SUBST
7522         case VSREPLACE:
7523         case VSREPLACEALL:
7524 #endif
7525                 break;
7526         default:
7527                 abort();
7528         }
7529 #endif
7530
7531         if (varlen >= 0) {
7532                 /*
7533                  * Terminate the string and start recording the pattern
7534                  * right after it
7535                  */
7536                 STPUTC('\0', expdest);
7537                 patloc = expdest - (char *)stackblock();
7538                 if (NULL == subevalvar(p, /* varname: */ NULL, patloc, subtype,
7539                                 startloc, varflags, flag)) {
7540                         int amount = expdest - (
7541                                 (char *)stackblock() + patloc - 1
7542                         );
7543                         STADJUST(-amount, expdest);
7544                 }
7545                 /* Remove any recorded regions beyond start of variable */
7546                 removerecordregions(startloc);
7547                 goto record;
7548         }
7549
7550         varlen = 0;
7551
7552  end:
7553         if (subtype != VSNORMAL) {      /* skip to end of alternative */
7554                 int nesting = 1;
7555                 for (;;) {
7556                         unsigned char c = *p++;
7557                         if (c == CTLESC)
7558                                 p++;
7559                         else if (c == CTLBACKQ) {
7560                                 if (varlen >= 0)
7561                                         argbackq = argbackq->next;
7562                         } else if (c == CTLVAR) {
7563                                 if ((*p++ & VSTYPE) != VSNORMAL)
7564                                         nesting++;
7565                         } else if (c == CTLENDVAR) {
7566                                 if (--nesting == 0)
7567                                         break;
7568                         }
7569                 }
7570         }
7571         return p;
7572 }
7573
7574 /*
7575  * Add a file name to the list.
7576  */
7577 static void
7578 addfname(const char *name)
7579 {
7580         struct strlist *sp;
7581
7582         sp = stzalloc(sizeof(*sp));
7583         sp->text = sstrdup(name);
7584         *exparg.lastp = sp;
7585         exparg.lastp = &sp->next;
7586 }
7587
7588 /* Avoid glob() (and thus, stat() et al) for words like "echo" */
7589 static int
7590 hasmeta(const char *p)
7591 {
7592         static const char chars[] ALIGN1 = {
7593                 '*', '?', '[', '\\', CTLQUOTEMARK, CTLESC, 0
7594         };
7595
7596         for (;;) {
7597                 p = strpbrk(p, chars);
7598                 if (!p)
7599                         break;
7600                 switch ((unsigned char)*p) {
7601                 case CTLQUOTEMARK:
7602                         for (;;) {
7603                                 p++;
7604                                 if ((unsigned char)*p == CTLQUOTEMARK)
7605                                         break;
7606                                 if ((unsigned char)*p == CTLESC)
7607                                         p++;
7608                                 if (*p == '\0') /* huh? */
7609                                         return 0;
7610                         }
7611                         break;
7612                 case '\\':
7613                 case CTLESC:
7614                         p++;
7615                         if (*p == '\0')
7616                                 return 0;
7617                         break;
7618                 case '[':
7619                         if (!strchr(p + 1, ']')) {
7620                                 /* It's not a properly closed [] pattern,
7621                                  * but other metas may follow. Continue checking.
7622                                  * my[file* _is_ globbed by bash
7623                                  * and matches filenames like "my[file1".
7624                                  */
7625                                 break;
7626                         }
7627                         /* fallthrough */
7628                 default:
7629                 /* case '*': */
7630                 /* case '?': */
7631                         return 1;
7632                 }
7633                 p++;
7634         }
7635
7636         return 0;
7637 }
7638
7639 /* If we want to use glob() from libc... */
7640 #if !ENABLE_ASH_INTERNAL_GLOB
7641
7642 /* Add the result of glob() to the list */
7643 static void
7644 addglob(const glob_t *pglob)
7645 {
7646         char **p = pglob->gl_pathv;
7647
7648         do {
7649                 addfname(*p);
7650         } while (*++p);
7651 }
7652 static void
7653 expandmeta(struct strlist *str /*, int flag*/)
7654 {
7655         /* TODO - EXP_REDIR */
7656
7657         while (str) {
7658                 char *p;
7659                 glob_t pglob;
7660                 int i;
7661
7662                 if (fflag)
7663                         goto nometa;
7664
7665                 if (!hasmeta(str->text))
7666                         goto nometa;
7667
7668                 INT_OFF;
7669                 p = preglob(str->text, RMESCAPE_ALLOC | RMESCAPE_HEAP);
7670 // GLOB_NOMAGIC (GNU): if no *?[ chars in pattern, return it even if no match
7671 // GLOB_NOCHECK: if no match, return unchanged pattern (sans \* escapes?)
7672 //
7673 // glibc 2.24.90 glob(GLOB_NOMAGIC) does not remove backslashes used for escaping:
7674 // if you pass it "file\?", it returns "file\?", not "file?", if no match.
7675 // Which means you need to unescape the string, right? Not so fast:
7676 // if there _is_ a file named "file\?" (with backslash), it is returned
7677 // as "file\?" too (whichever pattern you used to find it, say, "file*").
7678 // You DON'T KNOW by looking at the result whether you need to unescape it.
7679 //
7680 // Worse, globbing of "file\?" in a directory with two files, "file?" and "file\?",
7681 // returns "file\?" - which is WRONG: "file\?" pattern matches "file?" file.
7682 // Without GLOB_NOMAGIC, this works correctly ("file?" is returned as a match).
7683 // With GLOB_NOMAGIC | GLOB_NOCHECK, this also works correctly.
7684 //              i = glob(p, GLOB_NOMAGIC | GLOB_NOCHECK, NULL, &pglob);
7685 //              i = glob(p, GLOB_NOMAGIC, NULL, &pglob);
7686                 i = glob(p, 0, NULL, &pglob);
7687                 //bb_error_msg("glob('%s'):%d '%s'...", p, i, pglob.gl_pathv ? pglob.gl_pathv[0] : "-");
7688                 if (p != str->text)
7689                         free(p);
7690                 switch (i) {
7691                 case 0:
7692 #if 0 // glibc 2.24.90 bug? Patterns like "*/file", when match, don't set GLOB_MAGCHAR
7693                         /* GLOB_MAGCHAR is set if *?[ chars were seen (GNU) */
7694                         if (!(pglob.gl_flags & GLOB_MAGCHAR))
7695                                 goto nometa2;
7696 #endif
7697                         addglob(&pglob);
7698                         globfree(&pglob);
7699                         INT_ON;
7700                         break;
7701                 case GLOB_NOMATCH:
7702  //nometa2:
7703                         globfree(&pglob);
7704                         INT_ON;
7705  nometa:
7706                         *exparg.lastp = str;
7707                         rmescapes(str->text, 0, NULL);
7708                         exparg.lastp = &str->next;
7709                         break;
7710                 default:        /* GLOB_NOSPACE */
7711                         globfree(&pglob);
7712                         INT_ON;
7713                         ash_msg_and_raise_error(bb_msg_memory_exhausted);
7714                 }
7715                 str = str->next;
7716         }
7717 }
7718
7719 #else
7720 /* ENABLE_ASH_INTERNAL_GLOB: Homegrown globbing code. (dash also has both, uses homegrown one.) */
7721
7722 /*
7723  * Do metacharacter (i.e. *, ?, [...]) expansion.
7724  */
7725 typedef struct exp_t {
7726         char *dir;
7727         unsigned dir_max;
7728 } exp_t;
7729 static void
7730 expmeta(exp_t *exp, char *name, unsigned name_len, unsigned expdir_len)
7731 {
7732 #define expdir exp->dir
7733 #define expdir_max exp->dir_max
7734         char *enddir = expdir + expdir_len;
7735         char *p;
7736         const char *cp;
7737         char *start;
7738         char *endname;
7739         int metaflag;
7740         struct stat statb;
7741         DIR *dirp;
7742         struct dirent *dp;
7743         int atend;
7744         int matchdot;
7745         int esc;
7746
7747         metaflag = 0;
7748         start = name;
7749         for (p = name; esc = 0, *p; p += esc + 1) {
7750                 if (*p == '*' || *p == '?')
7751                         metaflag = 1;
7752                 else if (*p == '[') {
7753                         char *q = p + 1;
7754                         if (*q == '!')
7755                                 q++;
7756                         for (;;) {
7757                                 if (*q == '\\')
7758                                         q++;
7759                                 if (*q == '/' || *q == '\0')
7760                                         break;
7761                                 if (*++q == ']') {
7762                                         metaflag = 1;
7763                                         break;
7764                                 }
7765                         }
7766                 } else {
7767                         if (*p == '\\' && p[1])
7768                                 esc++;
7769                         if (p[esc] == '/') {
7770                                 if (metaflag)
7771                                         break;
7772                                 start = p + esc + 1;
7773                         }
7774                 }
7775         }
7776         if (metaflag == 0) {    /* we've reached the end of the file name */
7777                 if (!expdir_len)
7778                         return;
7779                 p = name;
7780                 do {
7781                         if (*p == '\\' && p[1])
7782                                 p++;
7783                         *enddir++ = *p;
7784                 } while (*p++);
7785                 if (lstat(expdir, &statb) == 0)
7786                         addfname(expdir);
7787                 return;
7788         }
7789         endname = p;
7790         if (name < start) {
7791                 p = name;
7792                 do {
7793                         if (*p == '\\' && p[1])
7794                                 p++;
7795                         *enddir++ = *p++;
7796                 } while (p < start);
7797         }
7798         *enddir = '\0';
7799         cp = expdir;
7800         expdir_len = enddir - cp;
7801         if (!expdir_len)
7802                 cp = ".";
7803         dirp = opendir(cp);
7804         if (dirp == NULL)
7805                 return;
7806         if (*endname == 0) {
7807                 atend = 1;
7808         } else {
7809                 atend = 0;
7810                 *endname = '\0';
7811                 endname += esc + 1;
7812         }
7813         name_len -= endname - name;
7814         matchdot = 0;
7815         p = start;
7816         if (*p == '\\')
7817                 p++;
7818         if (*p == '.')
7819                 matchdot++;
7820         while (!pending_int && (dp = readdir(dirp)) != NULL) {
7821                 if (dp->d_name[0] == '.' && !matchdot)
7822                         continue;
7823                 if (pmatch(start, dp->d_name)) {
7824                         if (atend) {
7825                                 strcpy(enddir, dp->d_name);
7826                                 addfname(expdir);
7827                         } else {
7828                                 unsigned offset;
7829                                 unsigned len;
7830
7831                                 p = stpcpy(enddir, dp->d_name);
7832                                 *p = '/';
7833
7834                                 offset = p - expdir + 1;
7835                                 len = offset + name_len + NAME_MAX;
7836                                 if (len > expdir_max) {
7837                                         len += PATH_MAX;
7838                                         expdir = ckrealloc(expdir, len);
7839                                         expdir_max = len;
7840                                 }
7841
7842                                 expmeta(exp, endname, name_len, offset);
7843                                 enddir = expdir + expdir_len;
7844                         }
7845                 }
7846         }
7847         closedir(dirp);
7848         if (!atend)
7849                 endname[-esc - 1] = esc ? '\\' : '/';
7850 #undef expdir
7851 #undef expdir_max
7852 }
7853
7854 static struct strlist *
7855 msort(struct strlist *list, int len)
7856 {
7857         struct strlist *p, *q = NULL;
7858         struct strlist **lpp;
7859         int half;
7860         int n;
7861
7862         if (len <= 1)
7863                 return list;
7864         half = len >> 1;
7865         p = list;
7866         for (n = half; --n >= 0;) {
7867                 q = p;
7868                 p = p->next;
7869         }
7870         q->next = NULL;                 /* terminate first half of list */
7871         q = msort(list, half);          /* sort first half of list */
7872         p = msort(p, len - half);               /* sort second half */
7873         lpp = &list;
7874         for (;;) {
7875 #if ENABLE_LOCALE_SUPPORT
7876                 if (strcoll(p->text, q->text) < 0)
7877 #else
7878                 if (strcmp(p->text, q->text) < 0)
7879 #endif
7880                                                 {
7881                         *lpp = p;
7882                         lpp = &p->next;
7883                         p = *lpp;
7884                         if (p == NULL) {
7885                                 *lpp = q;
7886                                 break;
7887                         }
7888                 } else {
7889                         *lpp = q;
7890                         lpp = &q->next;
7891                         q = *lpp;
7892                         if (q == NULL) {
7893                                 *lpp = p;
7894                                 break;
7895                         }
7896                 }
7897         }
7898         return list;
7899 }
7900
7901 /*
7902  * Sort the results of file name expansion.  It calculates the number of
7903  * strings to sort and then calls msort (short for merge sort) to do the
7904  * work.
7905  */
7906 static struct strlist *
7907 expsort(struct strlist *str)
7908 {
7909         int len;
7910         struct strlist *sp;
7911
7912         len = 0;
7913         for (sp = str; sp; sp = sp->next)
7914                 len++;
7915         return msort(str, len);
7916 }
7917
7918 static void
7919 expandmeta(struct strlist *str /*, int flag*/)
7920 {
7921         /* TODO - EXP_REDIR */
7922
7923         while (str) {
7924                 exp_t exp;
7925                 struct strlist **savelastp;
7926                 struct strlist *sp;
7927                 char *p;
7928                 unsigned len;
7929
7930                 if (fflag)
7931                         goto nometa;
7932                 if (!hasmeta(str->text))
7933                         goto nometa;
7934                 savelastp = exparg.lastp;
7935
7936                 INT_OFF;
7937                 p = preglob(str->text, RMESCAPE_ALLOC | RMESCAPE_HEAP);
7938                 len = strlen(p);
7939                 exp.dir_max = len + PATH_MAX;
7940                 exp.dir = ckmalloc(exp.dir_max);
7941
7942                 expmeta(&exp, p, len, 0);
7943                 free(exp.dir);
7944                 if (p != str->text)
7945                         free(p);
7946                 INT_ON;
7947                 if (exparg.lastp == savelastp) {
7948                         /*
7949                          * no matches
7950                          */
7951  nometa:
7952                         *exparg.lastp = str;
7953                         rmescapes(str->text, 0, NULL);
7954                         exparg.lastp = &str->next;
7955                 } else {
7956                         *exparg.lastp = NULL;
7957                         *savelastp = sp = expsort(*savelastp);
7958                         while (sp->next != NULL)
7959                                 sp = sp->next;
7960                         exparg.lastp = &sp->next;
7961                 }
7962                 str = str->next;
7963         }
7964 }
7965 #endif /* ENABLE_ASH_INTERNAL_GLOB */
7966
7967 /*
7968  * Perform variable substitution and command substitution on an argument,
7969  * placing the resulting list of arguments in arglist.  If EXP_FULL is true,
7970  * perform splitting and file name expansion.  When arglist is NULL, perform
7971  * here document expansion.
7972  */
7973 static void
7974 expandarg(union node *arg, struct arglist *arglist, int flag)
7975 {
7976         struct strlist *sp;
7977         char *p;
7978
7979         argbackq = arg->narg.backquote;
7980         STARTSTACKSTR(expdest);
7981         TRACE(("expandarg: argstr('%s',flags:%x)\n", arg->narg.text, flag));
7982         argstr(arg->narg.text, flag);
7983         p = _STPUTC('\0', expdest);
7984         expdest = p - 1;
7985         if (arglist == NULL) {
7986                 /* here document expanded */
7987                 goto out;
7988         }
7989         p = grabstackstr(p);
7990         TRACE(("expandarg: p:'%s'\n", p));
7991         exparg.lastp = &exparg.list;
7992         /*
7993          * TODO - EXP_REDIR
7994          */
7995         if (flag & EXP_FULL) {
7996                 ifsbreakup(p, &exparg);
7997                 *exparg.lastp = NULL;
7998                 exparg.lastp = &exparg.list;
7999                 expandmeta(exparg.list /*, flag*/);
8000         } else {
8001                 sp = stzalloc(sizeof(*sp));
8002                 sp->text = p;
8003                 *exparg.lastp = sp;
8004                 exparg.lastp = &sp->next;
8005         }
8006         *exparg.lastp = NULL;
8007         if (exparg.list) {
8008                 *arglist->lastp = exparg.list;
8009                 arglist->lastp = exparg.lastp;
8010         }
8011
8012  out:
8013         ifsfree();
8014 }
8015
8016 /*
8017  * Expand shell variables and backquotes inside a here document.
8018  */
8019 static void
8020 expandhere(union node *arg, int fd)
8021 {
8022         expandarg(arg, (struct arglist *)NULL, EXP_QUOTED);
8023         full_write(fd, stackblock(), expdest - (char *)stackblock());
8024 }
8025
8026 /*
8027  * Returns true if the pattern matches the string.
8028  */
8029 static int
8030 patmatch(char *pattern, const char *string)
8031 {
8032         char *p = preglob(pattern, 0);
8033         int r = pmatch(p, string);
8034         //bb_error_msg("!fnmatch(pattern:'%s',str:'%s',0):%d", p, string, r);
8035         return r;
8036 }
8037
8038 /*
8039  * See if a pattern matches in a case statement.
8040  */
8041 static int
8042 casematch(union node *pattern, char *val)
8043 {
8044         struct stackmark smark;
8045         int result;
8046
8047         setstackmark(&smark);
8048         argbackq = pattern->narg.backquote;
8049         STARTSTACKSTR(expdest);
8050         argstr(pattern->narg.text, EXP_TILDE | EXP_CASE);
8051         STACKSTRNUL(expdest);
8052         ifsfree();
8053         result = patmatch(stackblock(), val);
8054         popstackmark(&smark);
8055         return result;
8056 }
8057
8058
8059 /* ============ find_command */
8060
8061 struct builtincmd {
8062         const char *name;
8063         int (*builtin)(int, char **) FAST_FUNC;
8064         /* unsigned flags; */
8065 };
8066 #define IS_BUILTIN_SPECIAL(b) ((b)->name[0] & 1)
8067 /* "regular" builtins always take precedence over commands,
8068  * regardless of PATH=....%builtin... position */
8069 #define IS_BUILTIN_REGULAR(b) ((b)->name[0] & 2)
8070 #define IS_BUILTIN_ASSIGN(b)  ((b)->name[0] & 4)
8071
8072 struct cmdentry {
8073         smallint cmdtype;       /* CMDxxx */
8074         union param {
8075                 int index;
8076                 /* index >= 0 for commands without path (slashes) */
8077                 /* (TODO: what exactly does the value mean? PATH position?) */
8078                 /* index == -1 for commands with slashes */
8079                 /* index == (-2 - applet_no) for NOFORK applets */
8080                 const struct builtincmd *cmd;
8081                 struct funcnode *func;
8082         } u;
8083 };
8084 /* values of cmdtype */
8085 #define CMDUNKNOWN      -1      /* no entry in table for command */
8086 #define CMDNORMAL       0       /* command is an executable program */
8087 #define CMDFUNCTION     1       /* command is a shell function */
8088 #define CMDBUILTIN      2       /* command is a shell builtin */
8089
8090 /* action to find_command() */
8091 #define DO_ERR          0x01    /* prints errors */
8092 #define DO_ABS          0x02    /* checks absolute paths */
8093 #define DO_NOFUNC       0x04    /* don't return shell functions, for command */
8094 #define DO_ALTPATH      0x08    /* using alternate path */
8095 #define DO_REGBLTIN     0x10    /* regular built-ins and functions only */
8096
8097 static void find_command(char *, struct cmdentry *, int, const char *);
8098
8099
8100 /* ============ Hashing commands */
8101
8102 /*
8103  * When commands are first encountered, they are entered in a hash table.
8104  * This ensures that a full path search will not have to be done for them
8105  * on each invocation.
8106  *
8107  * We should investigate converting to a linear search, even though that
8108  * would make the command name "hash" a misnomer.
8109  */
8110
8111 struct tblentry {
8112         struct tblentry *next;  /* next entry in hash chain */
8113         union param param;      /* definition of builtin function */
8114         smallint cmdtype;       /* CMDxxx */
8115         char rehash;            /* if set, cd done since entry created */
8116         char cmdname[1];        /* name of command */
8117 };
8118
8119 static struct tblentry **cmdtable;
8120 #define INIT_G_cmdtable() do { \
8121         cmdtable = xzalloc(CMDTABLESIZE * sizeof(cmdtable[0])); \
8122 } while (0)
8123
8124 static int builtinloc = -1;     /* index in path of %builtin, or -1 */
8125
8126
8127 static void
8128 tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) const char *cmd, char **argv, char **envp)
8129 {
8130 #if ENABLE_FEATURE_SH_STANDALONE
8131         if (applet_no >= 0) {
8132                 if (APPLET_IS_NOEXEC(applet_no)) {
8133                         clearenv();
8134                         while (*envp)
8135                                 putenv(*envp++);
8136                         popredir(/*drop:*/ 1);
8137                         run_noexec_applet_and_exit(applet_no, cmd, argv);
8138                 }
8139                 /* re-exec ourselves with the new arguments */
8140                 execve(bb_busybox_exec_path, argv, envp);
8141                 /* If they called chroot or otherwise made the binary no longer
8142                  * executable, fall through */
8143         }
8144 #endif
8145
8146  repeat:
8147 #ifdef SYSV
8148         do {
8149                 execve(cmd, argv, envp);
8150         } while (errno == EINTR);
8151 #else
8152         execve(cmd, argv, envp);
8153 #endif
8154
8155         if (cmd != bb_busybox_exec_path && errno == ENOEXEC) {
8156                 /* Run "cmd" as a shell script:
8157                  * http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html
8158                  * "If the execve() function fails with ENOEXEC, the shell
8159                  * shall execute a command equivalent to having a shell invoked
8160                  * with the command name as its first operand,
8161                  * with any remaining arguments passed to the new shell"
8162                  *
8163                  * That is, do not use $SHELL, user's shell, or /bin/sh;
8164                  * just call ourselves.
8165                  *
8166                  * Note that bash reads ~80 chars of the file, and if it sees
8167                  * a zero byte before it sees newline, it doesn't try to
8168                  * interpret it, but fails with "cannot execute binary file"
8169                  * message and exit code 126. For one, this prevents attempts
8170                  * to interpret foreign ELF binaries as shell scripts.
8171                  */
8172                 argv[0] = (char*) cmd;
8173                 cmd = bb_busybox_exec_path;
8174                 /* NB: this is only possible because all callers of shellexec()
8175                  * ensure that the argv[-1] slot exists!
8176                  */
8177                 argv--;
8178                 argv[0] = (char*) "ash";
8179                 goto repeat;
8180         }
8181 }
8182
8183 /*
8184  * Exec a program.  Never returns.  If you change this routine, you may
8185  * have to change the find_command routine as well.
8186  * argv[-1] must exist and be writable! See tryexec() for why.
8187  */
8188 static void shellexec(char *prog, char **argv, const char *path, int idx) NORETURN;
8189 static void shellexec(char *prog, char **argv, const char *path, int idx)
8190 {
8191         char *cmdname;
8192         int e;
8193         char **envp;
8194         int exerrno;
8195         int applet_no = -1; /* used only by FEATURE_SH_STANDALONE */
8196
8197         envp = listvars(VEXPORT, VUNSET, /*strlist:*/ NULL, /*end:*/ NULL);
8198         if (strchr(prog, '/') != NULL
8199 #if ENABLE_FEATURE_SH_STANDALONE
8200          || (applet_no = find_applet_by_name(prog)) >= 0
8201 #endif
8202         ) {
8203                 tryexec(IF_FEATURE_SH_STANDALONE(applet_no,) prog, argv, envp);
8204                 if (applet_no >= 0) {
8205                         /* We tried execing ourself, but it didn't work.
8206                          * Maybe /proc/self/exe doesn't exist?
8207                          * Try $PATH search.
8208                          */
8209                         goto try_PATH;
8210                 }
8211                 e = errno;
8212         } else {
8213  try_PATH:
8214                 e = ENOENT;
8215                 while (padvance(&path, argv[0]) >= 0) {
8216                         cmdname = stackblock();
8217                         if (--idx < 0 && pathopt == NULL) {
8218                                 tryexec(IF_FEATURE_SH_STANDALONE(-1,) cmdname, argv, envp);
8219                                 if (errno != ENOENT && errno != ENOTDIR)
8220                                         e = errno;
8221                         }
8222                 }
8223         }
8224
8225         /* Map to POSIX errors */
8226         switch (e) {
8227         default:
8228                 exerrno = 126;
8229                 break;
8230         case ELOOP:
8231         case ENAMETOOLONG:
8232         case ENOENT:
8233         case ENOTDIR:
8234                 exerrno = 127;
8235                 break;
8236         }
8237         exitstatus = exerrno;
8238         TRACE(("shellexec failed for %s, errno %d, suppress_int %d\n",
8239                 prog, e, suppress_int));
8240         ash_msg_and_raise(EXEXIT, "%s: %s", prog, errmsg(e, "not found"));
8241         /* NOTREACHED */
8242 }
8243
8244 static void
8245 printentry(struct tblentry *cmdp)
8246 {
8247         int idx;
8248         const char *path;
8249         char *name;
8250
8251         idx = cmdp->param.index;
8252         path = pathval();
8253         do {
8254                 padvance(&path, cmdp->cmdname);
8255         } while (--idx >= 0);
8256         name = stackblock();
8257         out1fmt("%s%s\n", name, (cmdp->rehash ? "*" : nullstr));
8258 }
8259
8260 /*
8261  * Clear out command entries.
8262  */
8263 static void
8264 clearcmdentry(void)
8265 {
8266         struct tblentry **tblp;
8267         struct tblentry **pp;
8268         struct tblentry *cmdp;
8269
8270         INT_OFF;
8271         for (tblp = cmdtable; tblp < &cmdtable[CMDTABLESIZE]; tblp++) {
8272                 pp = tblp;
8273                 while ((cmdp = *pp) != NULL) {
8274                         if (cmdp->cmdtype == CMDNORMAL
8275                          || (cmdp->cmdtype == CMDBUILTIN
8276                             && !IS_BUILTIN_REGULAR(cmdp->param.cmd)
8277                             && builtinloc > 0
8278                             )
8279                         ) {
8280                                 *pp = cmdp->next;
8281                                 free(cmdp);
8282                         } else {
8283                                 pp = &cmdp->next;
8284                         }
8285                 }
8286         }
8287         INT_ON;
8288 }
8289
8290 /*
8291  * Locate a command in the command hash table.  If "add" is nonzero,
8292  * add the command to the table if it is not already present.  The
8293  * variable "lastcmdentry" is set to point to the address of the link
8294  * pointing to the entry, so that delete_cmd_entry can delete the
8295  * entry.
8296  *
8297  * Interrupts must be off if called with add != 0.
8298  */
8299 static struct tblentry **lastcmdentry;
8300
8301 static struct tblentry *
8302 cmdlookup(const char *name, int add)
8303 {
8304         unsigned int hashval;
8305         const char *p;
8306         struct tblentry *cmdp;
8307         struct tblentry **pp;
8308
8309         p = name;
8310         hashval = (unsigned char)*p << 4;
8311         while (*p)
8312                 hashval += (unsigned char)*p++;
8313         hashval &= 0x7FFF;
8314         pp = &cmdtable[hashval % CMDTABLESIZE];
8315         for (cmdp = *pp; cmdp; cmdp = cmdp->next) {
8316                 if (strcmp(cmdp->cmdname, name) == 0)
8317                         break;
8318                 pp = &cmdp->next;
8319         }
8320         if (add && cmdp == NULL) {
8321                 cmdp = *pp = ckzalloc(sizeof(struct tblentry)
8322                                 + strlen(name)
8323                                 /* + 1 - already done because
8324                                  * tblentry::cmdname is char[1] */);
8325                 /*cmdp->next = NULL; - ckzalloc did it */
8326                 cmdp->cmdtype = CMDUNKNOWN;
8327                 strcpy(cmdp->cmdname, name);
8328         }
8329         lastcmdentry = pp;
8330         return cmdp;
8331 }
8332
8333 /*
8334  * Delete the command entry returned on the last lookup.
8335  */
8336 static void
8337 delete_cmd_entry(void)
8338 {
8339         struct tblentry *cmdp;
8340
8341         INT_OFF;
8342         cmdp = *lastcmdentry;
8343         *lastcmdentry = cmdp->next;
8344         if (cmdp->cmdtype == CMDFUNCTION)
8345                 freefunc(cmdp->param.func);
8346         free(cmdp);
8347         INT_ON;
8348 }
8349
8350 /*
8351  * Add a new command entry, replacing any existing command entry for
8352  * the same name - except special builtins.
8353  */
8354 static void
8355 addcmdentry(char *name, struct cmdentry *entry)
8356 {
8357         struct tblentry *cmdp;
8358
8359         cmdp = cmdlookup(name, 1);
8360         if (cmdp->cmdtype == CMDFUNCTION) {
8361                 freefunc(cmdp->param.func);
8362         }
8363         cmdp->cmdtype = entry->cmdtype;
8364         cmdp->param = entry->u;
8365         cmdp->rehash = 0;
8366 }
8367
8368 static int FAST_FUNC
8369 hashcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
8370 {
8371         struct tblentry **pp;
8372         struct tblentry *cmdp;
8373         int c;
8374         struct cmdentry entry;
8375         char *name;
8376
8377         if (nextopt("r") != '\0') {
8378                 clearcmdentry();
8379                 return 0;
8380         }
8381
8382         if (*argptr == NULL) {
8383                 for (pp = cmdtable; pp < &cmdtable[CMDTABLESIZE]; pp++) {
8384                         for (cmdp = *pp; cmdp; cmdp = cmdp->next) {
8385                                 if (cmdp->cmdtype == CMDNORMAL)
8386                                         printentry(cmdp);
8387                         }
8388                 }
8389                 return 0;
8390         }
8391
8392         c = 0;
8393         while ((name = *argptr) != NULL) {
8394                 cmdp = cmdlookup(name, 0);
8395                 if (cmdp != NULL
8396                  && (cmdp->cmdtype == CMDNORMAL
8397                     || (cmdp->cmdtype == CMDBUILTIN
8398                         && !IS_BUILTIN_REGULAR(cmdp->param.cmd)
8399                         && builtinloc > 0
8400                         )
8401                     )
8402                 ) {
8403                         delete_cmd_entry();
8404                 }
8405                 find_command(name, &entry, DO_ERR, pathval());
8406                 if (entry.cmdtype == CMDUNKNOWN)
8407                         c = 1;
8408                 argptr++;
8409         }
8410         return c;
8411 }
8412
8413 /*
8414  * Called when a cd is done.  Marks all commands so the next time they
8415  * are executed they will be rehashed.
8416  */
8417 static void
8418 hashcd(void)
8419 {
8420         struct tblentry **pp;
8421         struct tblentry *cmdp;
8422
8423         for (pp = cmdtable; pp < &cmdtable[CMDTABLESIZE]; pp++) {
8424                 for (cmdp = *pp; cmdp; cmdp = cmdp->next) {
8425                         if (cmdp->cmdtype == CMDNORMAL
8426                          || (cmdp->cmdtype == CMDBUILTIN
8427                              && !IS_BUILTIN_REGULAR(cmdp->param.cmd)
8428                              && builtinloc > 0)
8429                         ) {
8430                                 cmdp->rehash = 1;
8431                         }
8432                 }
8433         }
8434 }
8435
8436 /*
8437  * Fix command hash table when PATH changed.
8438  * Called before PATH is changed.  The argument is the new value of PATH;
8439  * pathval() still returns the old value at this point.
8440  * Called with interrupts off.
8441  */
8442 static void FAST_FUNC
8443 changepath(const char *newval)
8444 {
8445         const char *new;
8446         int idx;
8447         int bltin;
8448
8449         new = newval;
8450         idx = 0;
8451         bltin = -1;
8452         for (;;) {
8453                 if (*new == '%' && prefix(new + 1, "builtin")) {
8454                         bltin = idx;
8455                         break;
8456                 }
8457                 new = strchr(new, ':');
8458                 if (!new)
8459                         break;
8460                 idx++;
8461                 new++;
8462         }
8463         builtinloc = bltin;
8464         clearcmdentry();
8465 }
8466 enum {
8467         TEOF,
8468         TNL,
8469         TREDIR,
8470         TWORD,
8471         TSEMI,
8472         TBACKGND,
8473         TAND,
8474         TOR,
8475         TPIPE,
8476         TLP,
8477         TRP,
8478         TENDCASE,
8479         TENDBQUOTE,
8480         TNOT,
8481         TCASE,
8482         TDO,
8483         TDONE,
8484         TELIF,
8485         TELSE,
8486         TESAC,
8487         TFI,
8488         TFOR,
8489 #if BASH_FUNCTION
8490         TFUNCTION,
8491 #endif
8492         TIF,
8493         TIN,
8494         TTHEN,
8495         TUNTIL,
8496         TWHILE,
8497         TBEGIN,
8498         TEND
8499 };
8500 typedef smallint token_id_t;
8501
8502 /* Nth bit indicates if token marks the end of a list */
8503 enum {
8504         tokendlist = 0
8505         /*  0 */ | (1u << TEOF)
8506         /*  1 */ | (0u << TNL)
8507         /*  2 */ | (0u << TREDIR)
8508         /*  3 */ | (0u << TWORD)
8509         /*  4 */ | (0u << TSEMI)
8510         /*  5 */ | (0u << TBACKGND)
8511         /*  6 */ | (0u << TAND)
8512         /*  7 */ | (0u << TOR)
8513         /*  8 */ | (0u << TPIPE)
8514         /*  9 */ | (0u << TLP)
8515         /* 10 */ | (1u << TRP)
8516         /* 11 */ | (1u << TENDCASE)
8517         /* 12 */ | (1u << TENDBQUOTE)
8518         /* 13 */ | (0u << TNOT)
8519         /* 14 */ | (0u << TCASE)
8520         /* 15 */ | (1u << TDO)
8521         /* 16 */ | (1u << TDONE)
8522         /* 17 */ | (1u << TELIF)
8523         /* 18 */ | (1u << TELSE)
8524         /* 19 */ | (1u << TESAC)
8525         /* 20 */ | (1u << TFI)
8526         /* 21 */ | (0u << TFOR)
8527 #if BASH_FUNCTION
8528         /* 22 */ | (0u << TFUNCTION)
8529 #endif
8530         /* 23 */ | (0u << TIF)
8531         /* 24 */ | (0u << TIN)
8532         /* 25 */ | (1u << TTHEN)
8533         /* 26 */ | (0u << TUNTIL)
8534         /* 27 */ | (0u << TWHILE)
8535         /* 28 */ | (0u << TBEGIN)
8536         /* 29 */ | (1u << TEND)
8537         , /* thus far 29 bits used */
8538 };
8539
8540 static const char *const tokname_array[] = {
8541         "end of file",
8542         "newline",
8543         "redirection",
8544         "word",
8545         ";",
8546         "&",
8547         "&&",
8548         "||",
8549         "|",
8550         "(",
8551         ")",
8552         ";;",
8553         "`",
8554 #define KWDOFFSET 13
8555         /* the following are keywords */
8556         "!",
8557         "case",
8558         "do",
8559         "done",
8560         "elif",
8561         "else",
8562         "esac",
8563         "fi",
8564         "for",
8565 #if BASH_FUNCTION
8566         "function",
8567 #endif
8568         "if",
8569         "in",
8570         "then",
8571         "until",
8572         "while",
8573         "{",
8574         "}",
8575 };
8576
8577 /* Wrapper around strcmp for qsort/bsearch/... */
8578 static int
8579 pstrcmp(const void *a, const void *b)
8580 {
8581         return strcmp((char*)a, *(char**)b);
8582 }
8583
8584 static const char *const *
8585 findkwd(const char *s)
8586 {
8587         return bsearch(s, tokname_array + KWDOFFSET,
8588                         ARRAY_SIZE(tokname_array) - KWDOFFSET,
8589                         sizeof(tokname_array[0]), pstrcmp);
8590 }
8591
8592 /*
8593  * Locate and print what a word is...
8594  */
8595 static int
8596 describe_command(char *command, const char *path, int describe_command_verbose)
8597 {
8598         struct cmdentry entry;
8599 #if ENABLE_ASH_ALIAS
8600         const struct alias *ap;
8601 #endif
8602
8603         path = path ? path : pathval();
8604
8605         if (describe_command_verbose) {
8606                 out1str(command);
8607         }
8608
8609         /* First look at the keywords */
8610         if (findkwd(command)) {
8611                 out1str(describe_command_verbose ? " is a shell keyword" : command);
8612                 goto out;
8613         }
8614
8615 #if ENABLE_ASH_ALIAS
8616         /* Then look at the aliases */
8617         ap = lookupalias(command, 0);
8618         if (ap != NULL) {
8619                 if (!describe_command_verbose) {
8620                         out1str("alias ");
8621                         printalias(ap);
8622                         return 0;
8623                 }
8624                 out1fmt(" is an alias for %s", ap->val);
8625                 goto out;
8626         }
8627 #endif
8628         /* Brute force */
8629         find_command(command, &entry, DO_ABS, path);
8630
8631         switch (entry.cmdtype) {
8632         case CMDNORMAL: {
8633                 int j = entry.u.index;
8634                 char *p;
8635                 if (j < 0) {
8636                         p = command;
8637                 } else {
8638                         do {
8639                                 padvance(&path, command);
8640                         } while (--j >= 0);
8641                         p = stackblock();
8642                 }
8643                 if (describe_command_verbose) {
8644                         out1fmt(" is %s", p);
8645                 } else {
8646                         out1str(p);
8647                 }
8648                 break;
8649         }
8650
8651         case CMDFUNCTION:
8652                 if (describe_command_verbose) {
8653                         /*out1str(" is a shell function");*/
8654                         out1str(" is a function"); /* bash says this */
8655                 } else {
8656                         out1str(command);
8657                 }
8658                 break;
8659
8660         case CMDBUILTIN:
8661                 if (describe_command_verbose) {
8662                         out1fmt(" is a %sshell builtin",
8663                                 IS_BUILTIN_SPECIAL(entry.u.cmd) ?
8664                                         "special " : nullstr
8665                         );
8666                 } else {
8667                         out1str(command);
8668                 }
8669                 break;
8670
8671         default:
8672                 if (describe_command_verbose) {
8673                         out1str(": not found\n");
8674                 }
8675                 return 127;
8676         }
8677  out:
8678         out1str("\n");
8679         return 0;
8680 }
8681
8682 static int FAST_FUNC
8683 typecmd(int argc UNUSED_PARAM, char **argv)
8684 {
8685         int i = 1;
8686         int err = 0;
8687         int verbose = 1;
8688
8689         /* type -p ... ? (we don't bother checking for 'p') */
8690         if (argv[1] && argv[1][0] == '-') {
8691                 i++;
8692                 verbose = 0;
8693         }
8694         while (argv[i]) {
8695                 err |= describe_command(argv[i++], NULL, verbose);
8696         }
8697         return err;
8698 }
8699
8700 #if ENABLE_ASH_CMDCMD
8701 static struct strlist *
8702 fill_arglist(struct arglist *arglist, union node **argpp)
8703 {
8704         struct strlist **lastp = arglist->lastp;
8705         union node *argp;
8706
8707         while ((argp = *argpp) != NULL) {
8708                 expandarg(argp, arglist, EXP_FULL | EXP_TILDE);
8709                 *argpp = argp->narg.next;
8710                 if (*lastp)
8711                         break;
8712         }
8713
8714         return *lastp;
8715 }
8716
8717 /* Is it "command [-p] PROG ARGS" bltin, no other opts? Return ptr to "PROG" if yes */
8718 static int
8719 parse_command_args(struct arglist *arglist, union node **argpp, const char **path)
8720 {
8721         struct strlist *sp = arglist->list;
8722         char *cp, c;
8723
8724         for (;;) {
8725                 sp = sp->next ? sp->next : fill_arglist(arglist, argpp);
8726                 if (!sp)
8727                         return 0;
8728                 cp = sp->text;
8729                 if (*cp++ != '-')
8730                         break;
8731                 c = *cp++;
8732                 if (!c)
8733                         break;
8734                 if (c == '-' && !*cp) {
8735                         if (!sp->next && !fill_arglist(arglist, argpp))
8736                                 return 0;
8737                         sp = sp->next;
8738                         break;
8739                 }
8740                 do {
8741                         switch (c) {
8742                         case 'p':
8743                                 *path = bb_default_path;
8744                                 break;
8745                         default:
8746                                 /* run 'typecmd' for other options */
8747                                 return 0;
8748                         }
8749                         c = *cp++;
8750                 } while (c);
8751         }
8752
8753         arglist->list = sp;
8754         return DO_NOFUNC;
8755 }
8756
8757 static int FAST_FUNC
8758 commandcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
8759 {
8760         char *cmd;
8761         int c;
8762         enum {
8763                 VERIFY_BRIEF = 1,
8764                 VERIFY_VERBOSE = 2,
8765         } verify = 0;
8766         const char *path = NULL;
8767
8768         /* "command [-p] PROG ARGS" (that is, without -V or -v)
8769          * never reaches this function.
8770          */
8771
8772         while ((c = nextopt("pvV")) != '\0')
8773                 if (c == 'V')
8774                         verify |= VERIFY_VERBOSE;
8775                 else if (c == 'v')
8776                         /*verify |= VERIFY_BRIEF*/;
8777 #if DEBUG
8778                 else if (c != 'p')
8779                         abort();
8780 #endif
8781                 else
8782                         path = bb_default_path;
8783
8784         /* Mimic bash: just "command -v" doesn't complain, it's a nop */
8785         cmd = *argptr;
8786         if (/*verify && */ cmd)
8787                 return describe_command(cmd, path, verify /* - VERIFY_BRIEF*/);
8788
8789         return 0;
8790 }
8791 #endif
8792
8793
8794 /*static int funcblocksize;     // size of structures in function */
8795 /*static int funcstringsize;    // size of strings in node */
8796 static void *funcblock;         /* block to allocate function from */
8797 static char *funcstring_end;    /* end of block to allocate strings from */
8798
8799 static const uint8_t nodesize[N_NUMBER] ALIGN1 = {
8800         [NCMD     ] = SHELL_ALIGN(sizeof(struct ncmd)),
8801         [NPIPE    ] = SHELL_ALIGN(sizeof(struct npipe)),
8802         [NREDIR   ] = SHELL_ALIGN(sizeof(struct nredir)),
8803         [NBACKGND ] = SHELL_ALIGN(sizeof(struct nredir)),
8804         [NSUBSHELL] = SHELL_ALIGN(sizeof(struct nredir)),
8805         [NAND     ] = SHELL_ALIGN(sizeof(struct nbinary)),
8806         [NOR      ] = SHELL_ALIGN(sizeof(struct nbinary)),
8807         [NSEMI    ] = SHELL_ALIGN(sizeof(struct nbinary)),
8808         [NIF      ] = SHELL_ALIGN(sizeof(struct nif)),
8809         [NWHILE   ] = SHELL_ALIGN(sizeof(struct nbinary)),
8810         [NUNTIL   ] = SHELL_ALIGN(sizeof(struct nbinary)),
8811         [NFOR     ] = SHELL_ALIGN(sizeof(struct nfor)),
8812         [NCASE    ] = SHELL_ALIGN(sizeof(struct ncase)),
8813         [NCLIST   ] = SHELL_ALIGN(sizeof(struct nclist)),
8814         [NDEFUN   ] = SHELL_ALIGN(sizeof(struct narg)),
8815         [NARG     ] = SHELL_ALIGN(sizeof(struct narg)),
8816         [NTO      ] = SHELL_ALIGN(sizeof(struct nfile)),
8817 #if BASH_REDIR_OUTPUT
8818         [NTO2     ] = SHELL_ALIGN(sizeof(struct nfile)),
8819 #endif
8820         [NCLOBBER ] = SHELL_ALIGN(sizeof(struct nfile)),
8821         [NFROM    ] = SHELL_ALIGN(sizeof(struct nfile)),
8822         [NFROMTO  ] = SHELL_ALIGN(sizeof(struct nfile)),
8823         [NAPPEND  ] = SHELL_ALIGN(sizeof(struct nfile)),
8824         [NTOFD    ] = SHELL_ALIGN(sizeof(struct ndup)),
8825         [NFROMFD  ] = SHELL_ALIGN(sizeof(struct ndup)),
8826         [NHERE    ] = SHELL_ALIGN(sizeof(struct nhere)),
8827         [NXHERE   ] = SHELL_ALIGN(sizeof(struct nhere)),
8828         [NNOT     ] = SHELL_ALIGN(sizeof(struct nnot)),
8829 };
8830
8831 static int calcsize(int funcblocksize, union node *n);
8832
8833 static int
8834 sizenodelist(int funcblocksize, struct nodelist *lp)
8835 {
8836         while (lp) {
8837                 funcblocksize += SHELL_ALIGN(sizeof(struct nodelist));
8838                 funcblocksize = calcsize(funcblocksize, lp->n);
8839                 lp = lp->next;
8840         }
8841         return funcblocksize;
8842 }
8843
8844 static int
8845 calcsize(int funcblocksize, union node *n)
8846 {
8847         if (n == NULL)
8848                 return funcblocksize;
8849         funcblocksize += nodesize[n->type];
8850         switch (n->type) {
8851         case NCMD:
8852                 funcblocksize = calcsize(funcblocksize, n->ncmd.redirect);
8853                 funcblocksize = calcsize(funcblocksize, n->ncmd.args);
8854                 funcblocksize = calcsize(funcblocksize, n->ncmd.assign);
8855                 break;
8856         case NPIPE:
8857                 funcblocksize = sizenodelist(funcblocksize, n->npipe.cmdlist);
8858                 break;
8859         case NREDIR:
8860         case NBACKGND:
8861         case NSUBSHELL:
8862                 funcblocksize = calcsize(funcblocksize, n->nredir.redirect);
8863                 funcblocksize = calcsize(funcblocksize, n->nredir.n);
8864                 break;
8865         case NAND:
8866         case NOR:
8867         case NSEMI:
8868         case NWHILE:
8869         case NUNTIL:
8870                 funcblocksize = calcsize(funcblocksize, n->nbinary.ch2);
8871                 funcblocksize = calcsize(funcblocksize, n->nbinary.ch1);
8872                 break;
8873         case NIF:
8874                 funcblocksize = calcsize(funcblocksize, n->nif.elsepart);
8875                 funcblocksize = calcsize(funcblocksize, n->nif.ifpart);
8876                 funcblocksize = calcsize(funcblocksize, n->nif.test);
8877                 break;
8878         case NFOR:
8879                 funcblocksize += SHELL_ALIGN(strlen(n->nfor.var) + 1); /* was funcstringsize += ... */
8880                 funcblocksize = calcsize(funcblocksize, n->nfor.body);
8881                 funcblocksize = calcsize(funcblocksize, n->nfor.args);
8882                 break;
8883         case NCASE:
8884                 funcblocksize = calcsize(funcblocksize, n->ncase.cases);
8885                 funcblocksize = calcsize(funcblocksize, n->ncase.expr);
8886                 break;
8887         case NCLIST:
8888                 funcblocksize = calcsize(funcblocksize, n->nclist.body);
8889                 funcblocksize = calcsize(funcblocksize, n->nclist.pattern);
8890                 funcblocksize = calcsize(funcblocksize, n->nclist.next);
8891                 break;
8892         case NDEFUN:
8893                 funcblocksize = calcsize(funcblocksize, n->ndefun.body);
8894                 funcblocksize += SHELL_ALIGN(strlen(n->ndefun.text) + 1);
8895                 break;
8896         case NARG:
8897                 funcblocksize = sizenodelist(funcblocksize, n->narg.backquote);
8898                 funcblocksize += SHELL_ALIGN(strlen(n->narg.text) + 1); /* was funcstringsize += ... */
8899                 funcblocksize = calcsize(funcblocksize, n->narg.next);
8900                 break;
8901         case NTO:
8902 #if BASH_REDIR_OUTPUT
8903         case NTO2:
8904 #endif
8905         case NCLOBBER:
8906         case NFROM:
8907         case NFROMTO:
8908         case NAPPEND:
8909                 funcblocksize = calcsize(funcblocksize, n->nfile.fname);
8910                 funcblocksize = calcsize(funcblocksize, n->nfile.next);
8911                 break;
8912         case NTOFD:
8913         case NFROMFD:
8914                 funcblocksize = calcsize(funcblocksize, n->ndup.vname);
8915                 funcblocksize = calcsize(funcblocksize, n->ndup.next);
8916         break;
8917         case NHERE:
8918         case NXHERE:
8919                 funcblocksize = calcsize(funcblocksize, n->nhere.doc);
8920                 funcblocksize = calcsize(funcblocksize, n->nhere.next);
8921                 break;
8922         case NNOT:
8923                 funcblocksize = calcsize(funcblocksize, n->nnot.com);
8924                 break;
8925         };
8926         return funcblocksize;
8927 }
8928
8929 static char *
8930 nodeckstrdup(char *s)
8931 {
8932         funcstring_end -= SHELL_ALIGN(strlen(s) + 1);
8933         return strcpy(funcstring_end, s);
8934 }
8935
8936 static union node *copynode(union node *);
8937
8938 static struct nodelist *
8939 copynodelist(struct nodelist *lp)
8940 {
8941         struct nodelist *start;
8942         struct nodelist **lpp;
8943
8944         lpp = &start;
8945         while (lp) {
8946                 *lpp = funcblock;
8947                 funcblock = (char *) funcblock + SHELL_ALIGN(sizeof(struct nodelist));
8948                 (*lpp)->n = copynode(lp->n);
8949                 lp = lp->next;
8950                 lpp = &(*lpp)->next;
8951         }
8952         *lpp = NULL;
8953         return start;
8954 }
8955
8956 static union node *
8957 copynode(union node *n)
8958 {
8959         union node *new;
8960
8961         if (n == NULL)
8962                 return NULL;
8963         new = funcblock;
8964         funcblock = (char *) funcblock + nodesize[n->type];
8965
8966         switch (n->type) {
8967         case NCMD:
8968                 new->ncmd.redirect = copynode(n->ncmd.redirect);
8969                 new->ncmd.args = copynode(n->ncmd.args);
8970                 new->ncmd.assign = copynode(n->ncmd.assign);
8971                 new->ncmd.linno = n->ncmd.linno;
8972                 break;
8973         case NPIPE:
8974                 new->npipe.cmdlist = copynodelist(n->npipe.cmdlist);
8975                 new->npipe.pipe_backgnd = n->npipe.pipe_backgnd;
8976                 break;
8977         case NREDIR:
8978         case NBACKGND:
8979         case NSUBSHELL:
8980                 new->nredir.redirect = copynode(n->nredir.redirect);
8981                 new->nredir.n = copynode(n->nredir.n);
8982                 new->nredir.linno = n->nredir.linno;
8983                 break;
8984         case NAND:
8985         case NOR:
8986         case NSEMI:
8987         case NWHILE:
8988         case NUNTIL:
8989                 new->nbinary.ch2 = copynode(n->nbinary.ch2);
8990                 new->nbinary.ch1 = copynode(n->nbinary.ch1);
8991                 break;
8992         case NIF:
8993                 new->nif.elsepart = copynode(n->nif.elsepart);
8994                 new->nif.ifpart = copynode(n->nif.ifpart);
8995                 new->nif.test = copynode(n->nif.test);
8996                 break;
8997         case NFOR:
8998                 new->nfor.var = nodeckstrdup(n->nfor.var);
8999                 new->nfor.body = copynode(n->nfor.body);
9000                 new->nfor.args = copynode(n->nfor.args);
9001                 new->nfor.linno = n->nfor.linno;
9002                 break;
9003         case NCASE:
9004                 new->ncase.cases = copynode(n->ncase.cases);
9005                 new->ncase.expr = copynode(n->ncase.expr);
9006                 new->ncase.linno = n->ncase.linno;
9007                 break;
9008         case NCLIST:
9009                 new->nclist.body = copynode(n->nclist.body);
9010                 new->nclist.pattern = copynode(n->nclist.pattern);
9011                 new->nclist.next = copynode(n->nclist.next);
9012                 break;
9013         case NDEFUN:
9014                 new->ndefun.body = copynode(n->ndefun.body);
9015                 new->ndefun.text = nodeckstrdup(n->ndefun.text);
9016                 new->ndefun.linno = n->ndefun.linno;
9017                 break;
9018         case NARG:
9019                 new->narg.backquote = copynodelist(n->narg.backquote);
9020                 new->narg.text = nodeckstrdup(n->narg.text);
9021                 new->narg.next = copynode(n->narg.next);
9022                 break;
9023         case NTO:
9024 #if BASH_REDIR_OUTPUT
9025         case NTO2:
9026 #endif
9027         case NCLOBBER:
9028         case NFROM:
9029         case NFROMTO:
9030         case NAPPEND:
9031                 new->nfile.fname = copynode(n->nfile.fname);
9032                 new->nfile.fd = n->nfile.fd;
9033                 new->nfile.next = copynode(n->nfile.next);
9034                 break;
9035         case NTOFD:
9036         case NFROMFD:
9037                 new->ndup.vname = copynode(n->ndup.vname);
9038                 new->ndup.dupfd = n->ndup.dupfd;
9039                 new->ndup.fd = n->ndup.fd;
9040                 new->ndup.next = copynode(n->ndup.next);
9041                 break;
9042         case NHERE:
9043         case NXHERE:
9044                 new->nhere.doc = copynode(n->nhere.doc);
9045                 new->nhere.fd = n->nhere.fd;
9046                 new->nhere.next = copynode(n->nhere.next);
9047                 break;
9048         case NNOT:
9049                 new->nnot.com = copynode(n->nnot.com);
9050                 break;
9051         };
9052         new->type = n->type;
9053         return new;
9054 }
9055
9056 /*
9057  * Make a copy of a parse tree.
9058  */
9059 static struct funcnode *
9060 copyfunc(union node *n)
9061 {
9062         struct funcnode *f;
9063         size_t blocksize;
9064
9065         /*funcstringsize = 0;*/
9066         blocksize = offsetof(struct funcnode, n) + calcsize(0, n);
9067         f = ckzalloc(blocksize /* + funcstringsize */);
9068         funcblock = (char *) f + offsetof(struct funcnode, n);
9069         funcstring_end = (char *) f + blocksize;
9070         copynode(n);
9071         /* f->count = 0; - ckzalloc did it */
9072         return f;
9073 }
9074
9075 /*
9076  * Define a shell function.
9077  */
9078 static void
9079 defun(union node *func)
9080 {
9081         struct cmdentry entry;
9082
9083         INT_OFF;
9084         entry.cmdtype = CMDFUNCTION;
9085         entry.u.func = copyfunc(func);
9086         addcmdentry(func->ndefun.text, &entry);
9087         INT_ON;
9088 }
9089
9090 /* Reasons for skipping commands (see comment on breakcmd routine) */
9091 #define SKIPBREAK      (1 << 0)
9092 #define SKIPCONT       (1 << 1)
9093 #define SKIPFUNC       (1 << 2)
9094 static smallint evalskip;       /* set to SKIPxxx if we are skipping commands */
9095 static int skipcount;           /* number of levels to skip */
9096 static int loopnest;            /* current loop nesting level */
9097 static int funcline;            /* starting line number of current function, or 0 if not in a function */
9098
9099 /* Forward decl way out to parsing code - dotrap needs it */
9100 static int evalstring(char *s, int flags);
9101
9102 /* Called to execute a trap.
9103  * Single callsite - at the end of evaltree().
9104  * If we return non-zero, evaltree raises EXEXIT exception.
9105  *
9106  * Perhaps we should avoid entering new trap handlers
9107  * while we are executing a trap handler. [is it a TODO?]
9108  */
9109 static void
9110 dotrap(void)
9111 {
9112         uint8_t *g;
9113         int sig;
9114         int status, last_status;
9115
9116         if (!pending_sig)
9117                 return;
9118
9119         status = savestatus;
9120         last_status = status;
9121         if (status < 0) {
9122                 status = exitstatus;
9123                 savestatus = status;
9124         }
9125         pending_sig = 0;
9126         barrier();
9127
9128         TRACE(("dotrap entered\n"));
9129         for (sig = 1, g = gotsig; sig < NSIG; sig++, g++) {
9130                 char *p;
9131
9132                 if (!*g)
9133                         continue;
9134
9135                 if (evalskip) {
9136                         pending_sig = sig;
9137                         break;
9138                 }
9139
9140                 p = trap[sig];
9141                 /* non-trapped SIGINT is handled separately by raise_interrupt,
9142                  * don't upset it by resetting gotsig[SIGINT-1] */
9143                 if (sig == SIGINT && !p)
9144                         continue;
9145
9146                 TRACE(("sig %d is active, will run handler '%s'\n", sig, p));
9147                 *g = 0;
9148                 if (!p)
9149                         continue;
9150                 evalstring(p, 0);
9151                 exitstatus = status;
9152         }
9153
9154         savestatus = last_status;
9155         TRACE(("dotrap returns\n"));
9156 }
9157
9158 /* forward declarations - evaluation is fairly recursive business... */
9159 static int evalloop(union node *, int);
9160 static int evalfor(union node *, int);
9161 static int evalcase(union node *, int);
9162 static int evalsubshell(union node *, int);
9163 static void expredir(union node *);
9164 static int evalpipe(union node *, int);
9165 static int evalcommand(union node *, int);
9166 static int evalbltin(const struct builtincmd *, int, char **, int);
9167 static void prehash(union node *);
9168
9169 /*
9170  * Evaluate a parse tree.  The value is left in the global variable
9171  * exitstatus.
9172  */
9173 static int
9174 evaltree(union node *n, int flags)
9175 {
9176         int checkexit = 0;
9177         int (*evalfn)(union node *, int);
9178         struct stackmark smark;
9179         int status = 0;
9180
9181         setstackmark(&smark);
9182
9183         if (n == NULL) {
9184                 TRACE(("evaltree(NULL) called\n"));
9185                 goto out;
9186         }
9187         TRACE(("evaltree(%p: %d, %d) called\n", n, n->type, flags));
9188
9189         dotrap();
9190
9191         switch (n->type) {
9192         default:
9193 #if DEBUG
9194                 out1fmt("Node type = %d\n", n->type);
9195                 fflush_all();
9196                 break;
9197 #endif
9198         case NNOT:
9199                 status = !evaltree(n->nnot.com, EV_TESTED);
9200                 goto setstatus;
9201         case NREDIR:
9202                 errlinno = lineno = n->nredir.linno;
9203                 if (funcline)
9204                         lineno -= funcline - 1;
9205                 expredir(n->nredir.redirect);
9206                 pushredir(n->nredir.redirect);
9207                 status = redirectsafe(n->nredir.redirect, REDIR_PUSH);
9208                 if (!status) {
9209                         status = evaltree(n->nredir.n, flags & EV_TESTED);
9210                 }
9211                 if (n->nredir.redirect)
9212                         popredir(/*drop:*/ 0);
9213                 goto setstatus;
9214         case NCMD:
9215                 evalfn = evalcommand;
9216  checkexit:
9217                 if (eflag && !(flags & EV_TESTED))
9218                         checkexit = ~0;
9219                 goto calleval;
9220         case NFOR:
9221                 evalfn = evalfor;
9222                 goto calleval;
9223         case NWHILE:
9224         case NUNTIL:
9225                 evalfn = evalloop;
9226                 goto calleval;
9227         case NSUBSHELL:
9228         case NBACKGND:
9229                 evalfn = evalsubshell;
9230                 goto checkexit;
9231         case NPIPE:
9232                 evalfn = evalpipe;
9233                 goto checkexit;
9234         case NCASE:
9235                 evalfn = evalcase;
9236                 goto calleval;
9237         case NAND:
9238         case NOR:
9239         case NSEMI: {
9240
9241 #if NAND + 1 != NOR
9242 #error NAND + 1 != NOR
9243 #endif
9244 #if NOR + 1 != NSEMI
9245 #error NOR + 1 != NSEMI
9246 #endif
9247                 unsigned is_or = n->type - NAND;
9248                 status = evaltree(
9249                         n->nbinary.ch1,
9250                         (flags | ((is_or >> 1) - 1)) & EV_TESTED
9251                 );
9252                 if ((!status) == is_or || evalskip)
9253                         break;
9254                 n = n->nbinary.ch2;
9255  evaln:
9256                 evalfn = evaltree;
9257  calleval:
9258                 status = evalfn(n, flags);
9259                 goto setstatus;
9260         }
9261         case NIF:
9262                 status = evaltree(n->nif.test, EV_TESTED);
9263                 if (evalskip)
9264                         break;
9265                 if (!status) {
9266                         n = n->nif.ifpart;
9267                         goto evaln;
9268                 }
9269                 if (n->nif.elsepart) {
9270                         n = n->nif.elsepart;
9271                         goto evaln;
9272                 }
9273                 status = 0;
9274                 goto setstatus;
9275         case NDEFUN:
9276                 defun(n);
9277                 /* Not necessary. To test it:
9278                  * "false; f() { qwerty; }; echo $?" should print 0.
9279                  */
9280                 /* status = 0; */
9281  setstatus:
9282                 exitstatus = status;
9283                 break;
9284         }
9285  out:
9286         /* Order of checks below is important:
9287          * signal handlers trigger before exit caused by "set -e".
9288          */
9289         dotrap();
9290
9291         if (checkexit & status)
9292                 raise_exception(EXEXIT);
9293         if (flags & EV_EXIT)
9294                 raise_exception(EXEXIT);
9295
9296         popstackmark(&smark);
9297         TRACE(("leaving evaltree (no interrupts)\n"));
9298         return exitstatus;
9299 }
9300
9301 static int
9302 skiploop(void)
9303 {
9304         int skip = evalskip;
9305
9306         switch (skip) {
9307         case 0:
9308                 break;
9309         case SKIPBREAK:
9310         case SKIPCONT:
9311                 if (--skipcount <= 0) {
9312                         evalskip = 0;
9313                         break;
9314                 }
9315                 skip = SKIPBREAK;
9316                 break;
9317         }
9318         return skip;
9319 }
9320
9321 static int
9322 evalloop(union node *n, int flags)
9323 {
9324         int skip;
9325         int status;
9326
9327         loopnest++;
9328         status = 0;
9329         flags &= EV_TESTED;
9330         do {
9331                 int i;
9332
9333                 i = evaltree(n->nbinary.ch1, EV_TESTED);
9334                 skip = skiploop();
9335                 if (skip == SKIPFUNC)
9336                         status = i;
9337                 if (skip)
9338                         continue;
9339                 if (n->type != NWHILE)
9340                         i = !i;
9341                 if (i != 0)
9342                         break;
9343                 status = evaltree(n->nbinary.ch2, flags);
9344                 skip = skiploop();
9345         } while (!(skip & ~SKIPCONT));
9346         loopnest--;
9347
9348         return status;
9349 }
9350
9351 static int
9352 evalfor(union node *n, int flags)
9353 {
9354         struct arglist arglist;
9355         union node *argp;
9356         struct strlist *sp;
9357         int status = 0;
9358
9359         errlinno = lineno = n->ncase.linno;
9360         if (funcline)
9361                 lineno -= funcline - 1;
9362
9363         arglist.list = NULL;
9364         arglist.lastp = &arglist.list;
9365         for (argp = n->nfor.args; argp; argp = argp->narg.next) {
9366                 expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
9367         }
9368         *arglist.lastp = NULL;
9369
9370         loopnest++;
9371         flags &= EV_TESTED;
9372         for (sp = arglist.list; sp; sp = sp->next) {
9373                 setvar0(n->nfor.var, sp->text);
9374                 status = evaltree(n->nfor.body, flags);
9375                 if (skiploop() & ~SKIPCONT)
9376                         break;
9377         }
9378         loopnest--;
9379
9380         return status;
9381 }
9382
9383 static int
9384 evalcase(union node *n, int flags)
9385 {
9386         union node *cp;
9387         union node *patp;
9388         struct arglist arglist;
9389         int status = 0;
9390
9391         errlinno = lineno = n->ncase.linno;
9392         if (funcline)
9393                 lineno -= funcline - 1;
9394
9395         arglist.list = NULL;
9396         arglist.lastp = &arglist.list;
9397         expandarg(n->ncase.expr, &arglist, EXP_TILDE);
9398         for (cp = n->ncase.cases; cp && evalskip == 0; cp = cp->nclist.next) {
9399                 for (patp = cp->nclist.pattern; patp; patp = patp->narg.next) {
9400                         if (casematch(patp, arglist.list->text)) {
9401                                 /* Ensure body is non-empty as otherwise
9402                                  * EV_EXIT may prevent us from setting the
9403                                  * exit status.
9404                                  */
9405                                 if (evalskip == 0 && cp->nclist.body) {
9406                                         status = evaltree(cp->nclist.body, flags);
9407                                 }
9408                                 goto out;
9409                         }
9410                 }
9411         }
9412  out:
9413         return status;
9414 }
9415
9416 /*
9417  * Kick off a subshell to evaluate a tree.
9418  */
9419 static int
9420 evalsubshell(union node *n, int flags)
9421 {
9422         struct job *jp;
9423         int backgnd = (n->type == NBACKGND); /* FORK_BG(1) if yes, else FORK_FG(0) */
9424         int status;
9425
9426         errlinno = lineno = n->nredir.linno;
9427         if (funcline)
9428                 lineno -= funcline - 1;
9429
9430         expredir(n->nredir.redirect);
9431         if (!backgnd && (flags & EV_EXIT) && !may_have_traps)
9432                 goto nofork;
9433         INT_OFF;
9434         if (backgnd == FORK_FG)
9435                 get_tty_state();
9436         jp = makejob(/*n,*/ 1);
9437         if (forkshell(jp, n, backgnd) == 0) {
9438                 /* child */
9439                 INT_ON;
9440                 flags |= EV_EXIT;
9441                 if (backgnd)
9442                         flags &= ~EV_TESTED;
9443  nofork:
9444                 redirect(n->nredir.redirect, 0);
9445                 evaltreenr(n->nredir.n, flags);
9446                 /* never returns */
9447         }
9448         /* parent */
9449         status = 0;
9450         if (backgnd == FORK_FG)
9451                 status = waitforjob(jp);
9452         INT_ON;
9453         return status;
9454 }
9455
9456 /*
9457  * Compute the names of the files in a redirection list.
9458  */
9459 static void fixredir(union node *, const char *, int);
9460 static void
9461 expredir(union node *n)
9462 {
9463         union node *redir;
9464
9465         for (redir = n; redir; redir = redir->nfile.next) {
9466                 struct arglist fn;
9467
9468                 fn.list = NULL;
9469                 fn.lastp = &fn.list;
9470                 switch (redir->type) {
9471                 case NFROMTO:
9472                 case NFROM:
9473                 case NTO:
9474 #if BASH_REDIR_OUTPUT
9475                 case NTO2:
9476 #endif
9477                 case NCLOBBER:
9478                 case NAPPEND:
9479                         expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR);
9480                         TRACE(("expredir expanded to '%s'\n", fn.list->text));
9481 #if BASH_REDIR_OUTPUT
9482  store_expfname:
9483 #endif
9484 #if 0
9485 // By the design of stack allocator, the loop of this kind:
9486 //      while true; do while true; do break; done </dev/null; done
9487 // will look like a memory leak: ash plans to free expfname's
9488 // of "/dev/null" as soon as it finishes running the loop
9489 // (in this case, never).
9490 // This "fix" is wrong:
9491                         if (redir->nfile.expfname)
9492                                 stunalloc(redir->nfile.expfname);
9493 // It results in corrupted state of stacked allocations.
9494 #endif
9495                         redir->nfile.expfname = fn.list->text;
9496                         break;
9497                 case NFROMFD:
9498                 case NTOFD: /* >& */
9499                         if (redir->ndup.vname) {
9500                                 expandarg(redir->ndup.vname, &fn, EXP_TILDE | EXP_REDIR);
9501                                 if (fn.list == NULL)
9502                                         ash_msg_and_raise_error("redir error");
9503 #if BASH_REDIR_OUTPUT
9504                                 if (!isdigit_str9(fn.list->text)) {
9505                                         /* >&file, not >&fd */
9506                                         if (redir->nfile.fd != 1) /* 123>&file - BAD */
9507                                                 ash_msg_and_raise_error("redir error");
9508                                         redir->type = NTO2;
9509                                         goto store_expfname;
9510                                 }
9511 #endif
9512                                 fixredir(redir, fn.list->text, 1);
9513                         }
9514                         break;
9515                 }
9516         }
9517 }
9518
9519 /*
9520  * Evaluate a pipeline.  All the processes in the pipeline are children
9521  * of the process creating the pipeline.  (This differs from some versions
9522  * of the shell, which make the last process in a pipeline the parent
9523  * of all the rest.)
9524  */
9525 static int
9526 evalpipe(union node *n, int flags)
9527 {
9528         struct job *jp;
9529         struct nodelist *lp;
9530         int pipelen;
9531         int prevfd;
9532         int pip[2];
9533         int status = 0;
9534
9535         TRACE(("evalpipe(0x%lx) called\n", (long)n));
9536         pipelen = 0;
9537         for (lp = n->npipe.cmdlist; lp; lp = lp->next)
9538                 pipelen++;
9539         flags |= EV_EXIT;
9540         INT_OFF;
9541         if (n->npipe.pipe_backgnd == 0)
9542                 get_tty_state();
9543         jp = makejob(/*n,*/ pipelen);
9544         prevfd = -1;
9545         for (lp = n->npipe.cmdlist; lp; lp = lp->next) {
9546                 prehash(lp->n);
9547                 pip[1] = -1;
9548                 if (lp->next) {
9549                         if (pipe(pip) < 0) {
9550                                 close(prevfd);
9551                                 ash_msg_and_raise_perror("can't create pipe");
9552                         }
9553                 }
9554                 if (forkshell(jp, lp->n, n->npipe.pipe_backgnd) == 0) {
9555                         /* child */
9556                         INT_ON;
9557                         if (pip[1] >= 0) {
9558                                 close(pip[0]);
9559                         }
9560                         if (prevfd > 0) {
9561                                 dup2(prevfd, 0);
9562                                 close(prevfd);
9563                         }
9564                         if (pip[1] > 1) {
9565                                 dup2(pip[1], 1);
9566                                 close(pip[1]);
9567                         }
9568                         evaltreenr(lp->n, flags);
9569                         /* never returns */
9570                 }
9571                 /* parent */
9572                 if (prevfd >= 0)
9573                         close(prevfd);
9574                 prevfd = pip[0];
9575                 /* Don't want to trigger debugging */
9576                 if (pip[1] != -1)
9577                         close(pip[1]);
9578         }
9579         if (n->npipe.pipe_backgnd == 0) {
9580                 status = waitforjob(jp);
9581                 TRACE(("evalpipe:  job done exit status %d\n", status));
9582         }
9583         INT_ON;
9584
9585         return status;
9586 }
9587
9588 /* setinteractive needs this forward reference */
9589 #if EDITING_HAS_get_exe_name
9590 static const char *get_builtin_name(int i) FAST_FUNC;
9591 #endif
9592
9593 /*
9594  * Controls whether the shell is interactive or not.
9595  */
9596 static void
9597 setinteractive(int on)
9598 {
9599         static smallint is_interactive;
9600
9601         if (++on == is_interactive)
9602                 return;
9603         is_interactive = on;
9604         setsignal(SIGINT);
9605         setsignal(SIGQUIT);
9606         setsignal(SIGTERM);
9607         if (is_interactive > 1) {
9608 #if !ENABLE_FEATURE_SH_EXTRA_QUIET
9609                 /* Looks like they want an interactive shell */
9610                 static smallint did_banner;
9611
9612                 if (!did_banner) {
9613                         /* note: ash and hush share this string */
9614                         out1fmt("\n\n%s %s\n"
9615                                 IF_ASH_HELP("Enter 'help' for a list of built-in commands.\n")
9616                                 "\n",
9617                                 bb_banner,
9618                                 "built-in shell (ash)"
9619                         );
9620                         did_banner = 1;
9621                 }
9622 #endif
9623 #if ENABLE_FEATURE_EDITING
9624                 if (!line_input_state) {
9625                         line_input_state = new_line_input_t(FOR_SHELL | WITH_PATH_LOOKUP);
9626 # if EDITING_HAS_get_exe_name
9627                         line_input_state->get_exe_name = get_builtin_name;
9628 # endif
9629                 }
9630 #endif
9631         }
9632 }
9633
9634 static void
9635 optschanged(void)
9636 {
9637 #if DEBUG
9638         opentrace();
9639 #endif
9640         setinteractive(iflag);
9641         setjobctl(mflag);
9642 #if ENABLE_FEATURE_EDITING_VI
9643         if (line_input_state) {
9644                 if (viflag)
9645                         line_input_state->flags |= VI_MODE;
9646                 else
9647                         line_input_state->flags &= ~VI_MODE;
9648         }
9649 #else
9650         viflag = 0; /* forcibly keep the option off */
9651 #endif
9652 }
9653
9654 struct localvar_list {
9655         struct localvar_list *next;
9656         struct localvar *lv;
9657 };
9658
9659 static struct localvar_list *localvar_stack;
9660
9661 /*
9662  * Called after a function returns.
9663  * Interrupts must be off.
9664  */
9665 static void
9666 poplocalvars(int keep)
9667 {
9668         struct localvar_list *ll;
9669         struct localvar *lvp, *next;
9670         struct var *vp;
9671
9672         INT_OFF;
9673         ll = localvar_stack;
9674         localvar_stack = ll->next;
9675
9676         next = ll->lv;
9677         free(ll);
9678
9679         while ((lvp = next) != NULL) {
9680                 next = lvp->next;
9681                 vp = lvp->vp;
9682                 TRACE(("poplocalvar %s\n", vp ? vp->var_text : "-"));
9683                 if (keep) {
9684                         int bits = VSTRFIXED;
9685
9686                         if (lvp->flags != VUNSET) {
9687                                 if (vp->var_text == lvp->text)
9688                                         bits |= VTEXTFIXED;
9689                                 else if (!(lvp->flags & (VTEXTFIXED|VSTACK)))
9690                                         free((char*)lvp->text);
9691                         }
9692
9693                         vp->flags &= ~bits;
9694                         vp->flags |= (lvp->flags & bits);
9695
9696                         if ((vp->flags &
9697                              (VEXPORT|VREADONLY|VSTRFIXED|VUNSET)) == VUNSET)
9698                                 unsetvar(vp->var_text);
9699                 } else if (vp == NULL) {        /* $- saved */
9700                         memcpy(optlist, lvp->text, sizeof(optlist));
9701                         free((char*)lvp->text);
9702                         optschanged();
9703                 } else if (lvp->flags == VUNSET) {
9704                         vp->flags &= ~(VSTRFIXED|VREADONLY);
9705                         unsetvar(vp->var_text);
9706                 } else {
9707                         if (vp->var_func)
9708                                 vp->var_func(var_end(lvp->text));
9709                         if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0)
9710                                 free((char*)vp->var_text);
9711                         vp->flags = lvp->flags;
9712                         vp->var_text = lvp->text;
9713                 }
9714                 free(lvp);
9715         }
9716         INT_ON;
9717 }
9718
9719 /*
9720  * Create a new localvar environment.
9721  */
9722 static struct localvar_list *
9723 pushlocalvars(int push)
9724 {
9725         struct localvar_list *ll;
9726         struct localvar_list *top;
9727
9728         top = localvar_stack;
9729         if (!push)
9730                 goto out;
9731
9732         INT_OFF;
9733         ll = ckzalloc(sizeof(*ll));
9734         /*ll->lv = NULL; - zalloc did it */
9735         ll->next = top;
9736         localvar_stack = ll;
9737         INT_ON;
9738  out:
9739         return top;
9740 }
9741
9742 static void
9743 unwindlocalvars(struct localvar_list *stop)
9744 {
9745         while (localvar_stack != stop)
9746                 poplocalvars(0);
9747 }
9748
9749 static int
9750 evalfun(struct funcnode *func, int argc, char **argv, int flags)
9751 {
9752         volatile struct shparam saveparam;
9753         struct jmploc *volatile savehandler;
9754         struct jmploc jmploc;
9755         int e;
9756         int savefuncline;
9757
9758         saveparam = shellparam;
9759         savefuncline = funcline;
9760         savehandler = exception_handler;
9761         e = setjmp(jmploc.loc);
9762         if (e) {
9763                 goto funcdone;
9764         }
9765         INT_OFF;
9766         exception_handler = &jmploc;
9767         shellparam.malloced = 0;
9768         func->count++;
9769         funcline = func->n.ndefun.linno;
9770         INT_ON;
9771         shellparam.nparam = argc - 1;
9772         shellparam.p = argv + 1;
9773 #if ENABLE_ASH_GETOPTS
9774         shellparam.optind = 1;
9775         shellparam.optoff = -1;
9776 #endif
9777         evaltree(func->n.ndefun.body, flags & EV_TESTED);
9778  funcdone:
9779         INT_OFF;
9780         funcline = savefuncline;
9781         freefunc(func);
9782         freeparam(&shellparam);
9783         shellparam = saveparam;
9784         exception_handler = savehandler;
9785         INT_ON;
9786         evalskip &= ~SKIPFUNC;
9787         return e;
9788 }
9789
9790 /*
9791  * Make a variable a local variable.  When a variable is made local, it's
9792  * value and flags are saved in a localvar structure.  The saved values
9793  * will be restored when the shell function returns.  We handle the name
9794  * "-" as a special case: it makes changes to "set +-options" local
9795  * (options will be restored on return from the function).
9796  */
9797 static void
9798 mklocal(char *name, int flags)
9799 {
9800         struct localvar *lvp;
9801         struct var **vpp;
9802         struct var *vp;
9803         char *eq = strchr(name, '=');
9804
9805         INT_OFF;
9806         /* Cater for duplicate "local". Examples:
9807          * x=0; f() { local x=1; echo $x; local x; echo $x; }; f; echo $x
9808          * x=0; f() { local x=1; echo $x; local x=2; echo $x; }; f; echo $x
9809          */
9810         lvp = localvar_stack->lv;
9811         while (lvp) {
9812                 if (lvp->vp && varcmp(lvp->vp->var_text, name) == 0) {
9813                         if (eq)
9814                                 setvareq(name, 0);
9815                         /* else:
9816                          * it's a duplicate "local VAR" declaration, do nothing
9817                          */
9818                         goto ret;
9819                 }
9820                 lvp = lvp->next;
9821         }
9822
9823         lvp = ckzalloc(sizeof(*lvp));
9824         if (LONE_DASH(name)) {
9825                 char *p;
9826                 p = ckmalloc(sizeof(optlist));
9827                 lvp->text = memcpy(p, optlist, sizeof(optlist));
9828                 vp = NULL;
9829         } else {
9830                 vpp = hashvar(name);
9831                 vp = *findvar(vpp, name);
9832                 if (vp == NULL) {
9833                         /* variable did not exist yet */
9834                         if (eq)
9835                                 vp = setvareq(name, VSTRFIXED | flags);
9836                         else
9837                                 vp = setvar(name, NULL, VSTRFIXED | flags);
9838                         lvp->flags = VUNSET;
9839                 } else {
9840                         lvp->text = vp->var_text;
9841                         lvp->flags = vp->flags;
9842                         /* make sure neither "struct var" nor string gets freed
9843                          * during (un)setting:
9844                          */
9845                         vp->flags |= VSTRFIXED|VTEXTFIXED;
9846                         if (eq)
9847                                 setvareq(name, flags);
9848                         else
9849                                 /* "local VAR" unsets VAR: */
9850                                 setvar0(name, NULL);
9851                 }
9852         }
9853         lvp->vp = vp;
9854         lvp->next = localvar_stack->lv;
9855         localvar_stack->lv = lvp;
9856  ret:
9857         INT_ON;
9858 }
9859
9860 /*
9861  * The "local" command.
9862  */
9863 static int FAST_FUNC
9864 localcmd(int argc UNUSED_PARAM, char **argv)
9865 {
9866         char *name;
9867
9868         if (!localvar_stack)
9869                 ash_msg_and_raise_error("not in a function");
9870
9871         argv = argptr;
9872         while ((name = *argv++) != NULL) {
9873                 mklocal(name, 0);
9874         }
9875         return 0;
9876 }
9877
9878 static int FAST_FUNC
9879 falsecmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
9880 {
9881         return 1;
9882 }
9883
9884 static int FAST_FUNC
9885 truecmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
9886 {
9887         return 0;
9888 }
9889
9890 static int FAST_FUNC
9891 execcmd(int argc UNUSED_PARAM, char **argv)
9892 {
9893         optionarg = NULL;
9894         while (nextopt("a:") != '\0')
9895                 /* nextopt() sets optionarg to "-a ARGV0" */;
9896
9897         argv = argptr;
9898         if (argv[0]) {
9899                 char *prog;
9900
9901                 iflag = 0;              /* exit on error */
9902                 mflag = 0;
9903                 optschanged();
9904                 /* We should set up signals for "exec CMD"
9905                  * the same way as for "CMD" without "exec".
9906                  * But optschanged->setinteractive->setsignal
9907                  * still thought we are a root shell. Therefore, for example,
9908                  * SIGQUIT is still set to IGN. Fix it:
9909                  */
9910                 shlvl++;
9911                 setsignal(SIGQUIT);
9912                 /*setsignal(SIGTERM); - unnecessary because of iflag=0 */
9913                 /*setsignal(SIGTSTP); - unnecessary because of mflag=0 */
9914                 /*setsignal(SIGTTOU); - unnecessary because of mflag=0 */
9915
9916                 prog = argv[0];
9917                 if (optionarg)
9918                         argv[0] = optionarg;
9919                 shellexec(prog, argv, pathval(), 0);
9920                 /* NOTREACHED */
9921         }
9922         return 0;
9923 }
9924
9925 /*
9926  * The return command.
9927  */
9928 static int FAST_FUNC
9929 returncmd(int argc UNUSED_PARAM, char **argv)
9930 {
9931         /*
9932          * If called outside a function, do what ksh does;
9933          * skip the rest of the file.
9934          */
9935         evalskip = SKIPFUNC;
9936         return argv[1] ? number(argv[1]) : exitstatus;
9937 }
9938
9939 /* Forward declarations for builtintab[] */
9940 static int breakcmd(int, char **) FAST_FUNC;
9941 static int dotcmd(int, char **) FAST_FUNC;
9942 static int evalcmd(int, char **, int) FAST_FUNC;
9943 static int exitcmd(int, char **) FAST_FUNC;
9944 static int exportcmd(int, char **) FAST_FUNC;
9945 #if ENABLE_ASH_GETOPTS
9946 static int getoptscmd(int, char **) FAST_FUNC;
9947 #endif
9948 #if ENABLE_ASH_HELP
9949 static int helpcmd(int, char **) FAST_FUNC;
9950 #endif
9951 #if MAX_HISTORY
9952 static int historycmd(int, char **) FAST_FUNC;
9953 #endif
9954 #if ENABLE_FEATURE_SH_MATH
9955 static int letcmd(int, char **) FAST_FUNC;
9956 #endif
9957 static int readcmd(int, char **) FAST_FUNC;
9958 static int setcmd(int, char **) FAST_FUNC;
9959 static int shiftcmd(int, char **) FAST_FUNC;
9960 static int timescmd(int, char **) FAST_FUNC;
9961 static int trapcmd(int, char **) FAST_FUNC;
9962 static int umaskcmd(int, char **) FAST_FUNC;
9963 static int unsetcmd(int, char **) FAST_FUNC;
9964 static int ulimitcmd(int, char **) FAST_FUNC;
9965
9966 #define BUILTIN_NOSPEC          "0"
9967 #define BUILTIN_SPECIAL         "1"
9968 #define BUILTIN_REGULAR         "2"
9969 #define BUILTIN_SPEC_REG        "3"
9970 #define BUILTIN_ASSIGN          "4"
9971 #define BUILTIN_SPEC_ASSG       "5"
9972 #define BUILTIN_REG_ASSG        "6"
9973 #define BUILTIN_SPEC_REG_ASSG   "7"
9974
9975 /* Stubs for calling non-FAST_FUNC's */
9976 #if ENABLE_ASH_ECHO
9977 static int FAST_FUNC echocmd(int argc, char **argv)   { return echo_main(argc, argv); }
9978 #endif
9979 #if ENABLE_ASH_PRINTF
9980 static int FAST_FUNC printfcmd(int argc, char **argv) { return printf_main(argc, argv); }
9981 #endif
9982 #if ENABLE_ASH_TEST || BASH_TEST2
9983 static int FAST_FUNC testcmd(int argc, char **argv)   { return test_main(argc, argv); }
9984 #endif
9985
9986 /* Keep these in proper order since it is searched via bsearch() */
9987 static const struct builtincmd builtintab[] = {
9988         { BUILTIN_SPEC_REG      "."       , dotcmd     },
9989         { BUILTIN_SPEC_REG      ":"       , truecmd    },
9990 #if ENABLE_ASH_TEST
9991         { BUILTIN_REGULAR       "["       , testcmd    },
9992 #endif
9993 #if BASH_TEST2
9994         { BUILTIN_REGULAR       "[["      , testcmd    },
9995 #endif
9996 #if ENABLE_ASH_ALIAS
9997         { BUILTIN_REG_ASSG      "alias"   , aliascmd   },
9998 #endif
9999 #if JOBS
10000         { BUILTIN_REGULAR       "bg"      , fg_bgcmd   },
10001 #endif
10002         { BUILTIN_SPEC_REG      "break"   , breakcmd   },
10003         { BUILTIN_REGULAR       "cd"      , cdcmd      },
10004         { BUILTIN_NOSPEC        "chdir"   , cdcmd      },
10005 #if ENABLE_ASH_CMDCMD
10006         { BUILTIN_REGULAR       "command" , commandcmd },
10007 #endif
10008         { BUILTIN_SPEC_REG      "continue", breakcmd   },
10009 #if ENABLE_ASH_ECHO
10010         { BUILTIN_REGULAR       "echo"    , echocmd    },
10011 #endif
10012         { BUILTIN_SPEC_REG      "eval"    , NULL       }, /*evalcmd() has a differing prototype*/
10013         { BUILTIN_SPEC_REG      "exec"    , execcmd    },
10014         { BUILTIN_SPEC_REG      "exit"    , exitcmd    },
10015         { BUILTIN_SPEC_REG_ASSG "export"  , exportcmd  },
10016         { BUILTIN_REGULAR       "false"   , falsecmd   },
10017 #if JOBS
10018         { BUILTIN_REGULAR       "fg"      , fg_bgcmd   },
10019 #endif
10020 #if ENABLE_ASH_GETOPTS
10021         { BUILTIN_REGULAR       "getopts" , getoptscmd },
10022 #endif
10023         { BUILTIN_REGULAR       "hash"    , hashcmd    },
10024 #if ENABLE_ASH_HELP
10025         { BUILTIN_NOSPEC        "help"    , helpcmd    },
10026 #endif
10027 #if MAX_HISTORY
10028         { BUILTIN_NOSPEC        "history" , historycmd },
10029 #endif
10030 #if JOBS
10031         { BUILTIN_REGULAR       "jobs"    , jobscmd    },
10032         { BUILTIN_REGULAR       "kill"    , killcmd    },
10033 #endif
10034 #if ENABLE_FEATURE_SH_MATH
10035         { BUILTIN_NOSPEC        "let"     , letcmd     },
10036 #endif
10037         { BUILTIN_SPEC_REG_ASSG "local"   , localcmd   },
10038 #if ENABLE_ASH_PRINTF
10039         { BUILTIN_REGULAR       "printf"  , printfcmd  },
10040 #endif
10041         { BUILTIN_REGULAR       "pwd"     , pwdcmd     },
10042         { BUILTIN_REGULAR       "read"    , readcmd    },
10043         { BUILTIN_SPEC_REG_ASSG "readonly", exportcmd  },
10044         { BUILTIN_SPEC_REG      "return"  , returncmd  },
10045         { BUILTIN_SPEC_REG      "set"     , setcmd     },
10046         { BUILTIN_SPEC_REG      "shift"   , shiftcmd   },
10047 #if BASH_SOURCE
10048         { BUILTIN_SPEC_REG      "source"  , dotcmd     },
10049 #endif
10050 #if ENABLE_ASH_TEST
10051         { BUILTIN_REGULAR       "test"    , testcmd    },
10052 #endif
10053         { BUILTIN_SPEC_REG      "times"   , timescmd   },
10054         { BUILTIN_SPEC_REG      "trap"    , trapcmd    },
10055         { BUILTIN_REGULAR       "true"    , truecmd    },
10056         { BUILTIN_REGULAR       "type"    , typecmd    },
10057         { BUILTIN_REGULAR       "ulimit"  , ulimitcmd  },
10058         { BUILTIN_REGULAR       "umask"   , umaskcmd   },
10059 #if ENABLE_ASH_ALIAS
10060         { BUILTIN_REGULAR       "unalias" , unaliascmd },
10061 #endif
10062         { BUILTIN_SPEC_REG      "unset"   , unsetcmd   },
10063         { BUILTIN_REGULAR       "wait"    , waitcmd    },
10064 };
10065
10066 /* Should match the above table! */
10067 #define COMMANDCMD (builtintab + \
10068         /* . : */       2 + \
10069         /* [ */         1 * ENABLE_ASH_TEST + \
10070         /* [[ */        1 * BASH_TEST2 + \
10071         /* alias */     1 * ENABLE_ASH_ALIAS + \
10072         /* bg */        1 * ENABLE_ASH_JOB_CONTROL + \
10073         /* break cd cddir  */   3)
10074 #define EVALCMD (COMMANDCMD + \
10075         /* command */   1 * ENABLE_ASH_CMDCMD + \
10076         /* continue */  1 + \
10077         /* echo */      1 * ENABLE_ASH_ECHO + \
10078         0)
10079 #define EXECCMD (EVALCMD + \
10080         /* eval */      1)
10081
10082 /*
10083  * Search the table of builtin commands.
10084  */
10085 static int
10086 pstrcmp1(const void *a, const void *b)
10087 {
10088         return strcmp((char*)a, *(char**)b + 1);
10089 }
10090 static struct builtincmd *
10091 find_builtin(const char *name)
10092 {
10093         struct builtincmd *bp;
10094
10095         bp = bsearch(
10096                 name, builtintab, ARRAY_SIZE(builtintab), sizeof(builtintab[0]),
10097                 pstrcmp1
10098         );
10099         return bp;
10100 }
10101
10102 #if EDITING_HAS_get_exe_name
10103 static const char * FAST_FUNC
10104 get_builtin_name(int i)
10105 {
10106         return /*i >= 0 &&*/ i < ARRAY_SIZE(builtintab) ? builtintab[i].name + 1 : NULL;
10107 }
10108 #endif
10109
10110 /*
10111  * Execute a simple command.
10112  */
10113 static void unwindfiles(struct parsefile *stop);
10114 static int
10115 isassignment(const char *p)
10116 {
10117         const char *q = endofname(p);
10118         if (p == q)
10119                 return 0;
10120         return *q == '=';
10121 }
10122 static int FAST_FUNC
10123 bltincmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
10124 {
10125         /* Preserve exitstatus of a previous possible redirection
10126          * as POSIX mandates */
10127         return back_exitstatus;
10128 }
10129 static int
10130 evalcommand(union node *cmd, int flags)
10131 {
10132         static const struct builtincmd null_bltin = {
10133                 BUILTIN_REGULAR "", bltincmd
10134         };
10135         struct localvar_list *localvar_stop;
10136         struct parsefile *file_stop;
10137         struct redirtab *redir_stop;
10138         union node *argp;
10139         struct arglist arglist;
10140         struct arglist varlist;
10141         char **argv;
10142         int argc;
10143         struct strlist *osp;
10144         const struct strlist *sp;
10145         struct cmdentry cmdentry;
10146         struct job *jp;
10147         char *lastarg;
10148         const char *path;
10149         int spclbltin;
10150         int cmd_flag;
10151         int status;
10152         char **nargv;
10153         smallint cmd_is_exec;
10154         int vflags;
10155         int vlocal;
10156
10157         errlinno = lineno = cmd->ncmd.linno;
10158         if (funcline)
10159                 lineno -= funcline - 1;
10160
10161         /* First expand the arguments. */
10162         TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags));
10163         file_stop = g_parsefile;
10164         back_exitstatus = 0;
10165
10166         cmdentry.cmdtype = CMDBUILTIN;
10167         cmdentry.u.cmd = &null_bltin;
10168         varlist.lastp = &varlist.list;
10169         *varlist.lastp = NULL;
10170         arglist.lastp = &arglist.list;
10171         *arglist.lastp = NULL;
10172
10173         cmd_flag = 0;
10174         cmd_is_exec = 0;
10175         spclbltin = -1;
10176         vflags = 0;
10177         vlocal = 0;
10178         path = NULL;
10179
10180         argc = 0;
10181         argp = cmd->ncmd.args;
10182         osp = fill_arglist(&arglist, &argp);
10183         if (osp) {
10184                 int pseudovarflag = 0;
10185
10186                 for (;;) {
10187                         find_command(arglist.list->text, &cmdentry,
10188                                         cmd_flag | DO_REGBLTIN, pathval());
10189
10190                         vlocal++;
10191
10192                         /* implement bltin and command here */
10193                         if (cmdentry.cmdtype != CMDBUILTIN)
10194                                 break;
10195
10196                         pseudovarflag = IS_BUILTIN_ASSIGN(cmdentry.u.cmd);
10197                         if (spclbltin < 0) {
10198                                 spclbltin = IS_BUILTIN_SPECIAL(cmdentry.u.cmd);
10199                                 vlocal = !spclbltin;
10200                         }
10201                         cmd_is_exec = cmdentry.u.cmd == EXECCMD;
10202                         if (cmdentry.u.cmd != COMMANDCMD)
10203                                 break;
10204
10205                         cmd_flag = parse_command_args(&arglist, &argp, &path);
10206                         if (!cmd_flag)
10207                                 break;
10208                 }
10209
10210                 for (; argp; argp = argp->narg.next)
10211                         expandarg(argp, &arglist,
10212                                         pseudovarflag &&
10213                                         isassignment(argp->narg.text) ?
10214                                         EXP_VARTILDE : EXP_FULL | EXP_TILDE);
10215
10216                 for (sp = arglist.list; sp; sp = sp->next)
10217                         argc++;
10218
10219                 if (cmd_is_exec && argc > 1)
10220                         vflags = VEXPORT;
10221         }
10222
10223         localvar_stop = pushlocalvars(vlocal);
10224
10225         /* Reserve one extra spot at the front for shellexec. */
10226         nargv = stalloc(sizeof(char *) * (argc + 2));
10227         argv = ++nargv;
10228         for (sp = arglist.list; sp; sp = sp->next) {
10229                 TRACE(("evalcommand arg: %s\n", sp->text));
10230                 *nargv++ = sp->text;
10231         }
10232         *nargv = NULL;
10233
10234         lastarg = NULL;
10235         if (iflag && funcline == 0 && argc > 0)
10236                 lastarg = nargv[-1];
10237
10238         expredir(cmd->ncmd.redirect);
10239         redir_stop = pushredir(cmd->ncmd.redirect);
10240         preverrout_fd = 2;
10241         if (BASH_XTRACEFD && xflag) {
10242                 /* NB: bash closes fd == $BASH_XTRACEFD when it is changed.
10243                  * we do not emulate this. We only use its value.
10244                  */
10245                 const char *xtracefd = lookupvar("BASH_XTRACEFD");
10246                 if (xtracefd && is_number(xtracefd))
10247                         preverrout_fd = atoi(xtracefd);
10248
10249         }
10250         status = redirectsafe(cmd->ncmd.redirect, REDIR_PUSH | REDIR_SAVEFD2);
10251
10252         if (status) {
10253  bail:
10254                 exitstatus = status;
10255
10256                 /* We have a redirection error. */
10257                 if (spclbltin > 0)
10258                         raise_exception(EXERROR);
10259
10260                 goto out;
10261         }
10262
10263         for (argp = cmd->ncmd.assign; argp; argp = argp->narg.next) {
10264                 struct strlist **spp;
10265
10266                 spp = varlist.lastp;
10267                 expandarg(argp, &varlist, EXP_VARTILDE);
10268
10269                 if (vlocal)
10270                         mklocal((*spp)->text, VEXPORT);
10271                 else
10272                         setvareq((*spp)->text, vflags);
10273         }
10274
10275         /* Print the command if xflag is set. */
10276         if (xflag) {
10277                 const char *pfx = "";
10278
10279                 fdprintf(preverrout_fd, "%s", expandstr(ps4val(), DQSYNTAX));
10280
10281                 sp = varlist.list;
10282                 while (sp) {
10283                         char *varval = sp->text;
10284                         char *eq = strchrnul(varval, '=');
10285                         if (*eq)
10286                                 eq++;
10287                         fdprintf(preverrout_fd, "%s%.*s%s",
10288                                 pfx,
10289                                 (int)(eq - varval), varval,
10290                                 maybe_single_quote(eq)
10291                         );
10292                         sp = sp->next;
10293                         pfx = " ";
10294                 }
10295
10296                 sp = arglist.list;
10297                 while (sp) {
10298                         fdprintf(preverrout_fd, "%s%s",
10299                                 pfx,
10300                                 /* always quote if matches reserved word: */
10301                                 findkwd(sp->text)
10302                                 ? single_quote(sp->text)
10303                                 : maybe_single_quote(sp->text)
10304                         );
10305                         sp = sp->next;
10306                         pfx = " ";
10307                 }
10308                 safe_write(preverrout_fd, "\n", 1);
10309         }
10310
10311         /* Now locate the command. */
10312         if (cmdentry.cmdtype != CMDBUILTIN
10313          || !(IS_BUILTIN_REGULAR(cmdentry.u.cmd))
10314         ) {
10315                 path = path ? path : pathval();
10316                 find_command(argv[0], &cmdentry, cmd_flag | DO_ERR, path);
10317         }
10318
10319         jp = NULL;
10320
10321         /* Execute the command. */
10322         switch (cmdentry.cmdtype) {
10323         case CMDUNKNOWN:
10324                 status = 127;
10325                 flush_stdout_stderr();
10326                 goto bail;
10327
10328         default: {
10329
10330 #if ENABLE_FEATURE_SH_STANDALONE \
10331  && ENABLE_FEATURE_SH_NOFORK \
10332  && NUM_APPLETS > 1
10333 /* (1) BUG: if variables are set, we need to fork, or save/restore them
10334  *     around run_nofork_applet() call.
10335  * (2) Should this check also be done in forkshell()?
10336  *     (perhaps it should, so that "VAR=VAL nofork" at least avoids exec...)
10337  */
10338                 /* find_command() encodes applet_no as (-2 - applet_no) */
10339                 int applet_no = (- cmdentry.u.index - 2);
10340                 if (applet_no >= 0 && APPLET_IS_NOFORK(applet_no)) {
10341                         char **sv_environ;
10342
10343                         INT_OFF;
10344                         sv_environ = environ;
10345                         environ = listvars(VEXPORT, VUNSET, varlist.list, /*end:*/ NULL);
10346                         /*
10347                          * Run <applet>_main().
10348                          * Signals (^C) can't interrupt here.
10349                          * Otherwise we can mangle stdio or malloc internal state.
10350                          * This makes applets which can run for a long time
10351                          * and/or wait for user input ineligible for NOFORK:
10352                          * for example, "yes" or "rm" (rm -i waits for input).
10353                          */
10354                         status = run_nofork_applet(applet_no, argv);
10355                         environ = sv_environ;
10356                         /*
10357                          * Try enabling NOFORK for "yes" applet.
10358                          * ^C _will_ stop it (write returns EINTR),
10359                          * but this causes stdout FILE to be stuck
10360                          * and needing clearerr(). What if other applets
10361                          * also can get EINTRs? Do we need to switch
10362                          * our signals to SA_RESTART?
10363                          */
10364                         /*clearerr(stdout);*/
10365                         INT_ON;
10366                         break;
10367                 }
10368 #endif
10369                 /* Can we avoid forking? For example, very last command
10370                  * in a script or a subshell does not need forking,
10371                  * we can just exec it.
10372                  */
10373                 if (!(flags & EV_EXIT) || may_have_traps) {
10374                         /* No, forking off a child is necessary */
10375                         INT_OFF;
10376                         get_tty_state();
10377                         jp = makejob(/*cmd,*/ 1);
10378                         if (forkshell(jp, cmd, FORK_FG) != 0) {
10379                                 /* parent */
10380                                 TRACE(("forked child exited with %d\n", status));
10381                                 break;
10382                         }
10383                         /* child */
10384                         FORCE_INT_ON;
10385                         /* fall through to exec'ing external program */
10386                 }
10387                 shellexec(argv[0], argv, path, cmdentry.u.index);
10388                 /* NOTREACHED */
10389         } /* default */
10390         case CMDBUILTIN:
10391                 if (evalbltin(cmdentry.u.cmd, argc, argv, flags)
10392                  && !(exception_type == EXERROR && spclbltin <= 0)
10393                 ) {
10394  raise:
10395                         longjmp(exception_handler->loc, 1);
10396                 }
10397                 break;
10398
10399         case CMDFUNCTION:
10400                 if (evalfun(cmdentry.u.func, argc, argv, flags))
10401                         goto raise;
10402                 break;
10403         } /* switch */
10404
10405         status = waitforjob(jp);
10406         FORCE_INT_ON;
10407
10408  out:
10409         if (cmd->ncmd.redirect)
10410                 popredir(/*drop:*/ cmd_is_exec);
10411         unwindredir(redir_stop);
10412         unwindfiles(file_stop);
10413         unwindlocalvars(localvar_stop);
10414         if (lastarg) {
10415                 /* dsl: I think this is intended to be used to support
10416                  * '_' in 'vi' command mode during line editing...
10417                  * However I implemented that within libedit itself.
10418                  */
10419                 setvar0("_", lastarg);
10420         }
10421
10422         return status;
10423 }
10424
10425 static int
10426 evalbltin(const struct builtincmd *cmd, int argc, char **argv, int flags)
10427 {
10428         char *volatile savecmdname;
10429         struct jmploc *volatile savehandler;
10430         struct jmploc jmploc;
10431         int status;
10432         int i;
10433
10434         savecmdname = commandname;
10435         savehandler = exception_handler;
10436         i = setjmp(jmploc.loc);
10437         if (i)
10438                 goto cmddone;
10439         exception_handler = &jmploc;
10440         commandname = argv[0];
10441         argptr = argv + 1;
10442         optptr = NULL;                  /* initialize nextopt */
10443         if (cmd == EVALCMD)
10444                 status = evalcmd(argc, argv, flags);
10445         else
10446                 status = (*cmd->builtin)(argc, argv);
10447         flush_stdout_stderr();
10448         status |= ferror(stdout);
10449         exitstatus = status;
10450  cmddone:
10451         clearerr(stdout);
10452         commandname = savecmdname;
10453         exception_handler = savehandler;
10454
10455         return i;
10456 }
10457
10458 static int
10459 goodname(const char *p)
10460 {
10461         return endofname(p)[0] == '\0';
10462 }
10463
10464
10465 /*
10466  * Search for a command.  This is called before we fork so that the
10467  * location of the command will be available in the parent as well as
10468  * the child.  The check for "goodname" is an overly conservative
10469  * check that the name will not be subject to expansion.
10470  */
10471 static void
10472 prehash(union node *n)
10473 {
10474         struct cmdentry entry;
10475
10476         if (n->type == NCMD && n->ncmd.args && goodname(n->ncmd.args->narg.text))
10477                 find_command(n->ncmd.args->narg.text, &entry, 0, pathval());
10478 }
10479
10480
10481 /* ============ Builtin commands
10482  *
10483  * Builtin commands whose functions are closely tied to evaluation
10484  * are implemented here.
10485  */
10486
10487 /*
10488  * Handle break and continue commands.  Break, continue, and return are
10489  * all handled by setting the evalskip flag.  The evaluation routines
10490  * above all check this flag, and if it is set they start skipping
10491  * commands rather than executing them.  The variable skipcount is
10492  * the number of loops to break/continue, or the number of function
10493  * levels to return.  (The latter is always 1.)  It should probably
10494  * be an error to break out of more loops than exist, but it isn't
10495  * in the standard shell so we don't make it one here.
10496  */
10497 static int FAST_FUNC
10498 breakcmd(int argc UNUSED_PARAM, char **argv)
10499 {
10500         int n = argv[1] ? number(argv[1]) : 1;
10501
10502         if (n <= 0)
10503                 ash_msg_and_raise_error(msg_illnum, argv[1]);
10504         if (n > loopnest)
10505                 n = loopnest;
10506         if (n > 0) {
10507                 evalskip = (**argv == 'c') ? SKIPCONT : SKIPBREAK;
10508                 skipcount = n;
10509         }
10510         return 0;
10511 }
10512
10513
10514 /*
10515  * This implements the input routines used by the parser.
10516  */
10517
10518 enum {
10519         INPUT_PUSH_FILE = 1,
10520         INPUT_NOFILE_OK = 2,
10521 };
10522
10523 static smallint checkkwd;
10524 /* values of checkkwd variable */
10525 #define CHKALIAS        0x1
10526 #define CHKKWD          0x2
10527 #define CHKNL           0x4
10528 #define CHKEOFMARK      0x8
10529
10530 /*
10531  * Push a string back onto the input at this current parsefile level.
10532  * We handle aliases this way.
10533  */
10534 #if !ENABLE_ASH_ALIAS
10535 #define pushstring(s, ap) pushstring(s)
10536 #endif
10537 static void
10538 pushstring(char *s, struct alias *ap)
10539 {
10540         struct strpush *sp;
10541         int len;
10542
10543         len = strlen(s);
10544         INT_OFF;
10545         if (g_parsefile->strpush) {
10546                 sp = ckzalloc(sizeof(*sp));
10547                 sp->prev = g_parsefile->strpush;
10548         } else {
10549                 sp = &(g_parsefile->basestrpush);
10550         }
10551         g_parsefile->strpush = sp;
10552         sp->prev_string = g_parsefile->next_to_pgetc;
10553         sp->prev_left_in_line = g_parsefile->left_in_line;
10554         sp->unget = g_parsefile->unget;
10555         memcpy(sp->lastc, g_parsefile->lastc, sizeof(sp->lastc));
10556 #if ENABLE_ASH_ALIAS
10557         sp->ap = ap;
10558         if (ap) {
10559                 ap->flag |= ALIASINUSE;
10560                 sp->string = s;
10561         }
10562 #endif
10563         g_parsefile->next_to_pgetc = s;
10564         g_parsefile->left_in_line = len;
10565         g_parsefile->unget = 0;
10566         INT_ON;
10567 }
10568
10569 static void
10570 popstring(void)
10571 {
10572         struct strpush *sp = g_parsefile->strpush;
10573
10574         INT_OFF;
10575 #if ENABLE_ASH_ALIAS
10576         if (sp->ap) {
10577                 if (g_parsefile->next_to_pgetc[-1] == ' '
10578                  || g_parsefile->next_to_pgetc[-1] == '\t'
10579                 ) {
10580                         checkkwd |= CHKALIAS;
10581                 }
10582                 if (sp->string != sp->ap->val) {
10583                         free(sp->string);
10584                 }
10585                 sp->ap->flag &= ~ALIASINUSE;
10586                 if (sp->ap->flag & ALIASDEAD) {
10587                         unalias(sp->ap->name);
10588                 }
10589         }
10590 #endif
10591         g_parsefile->next_to_pgetc = sp->prev_string;
10592         g_parsefile->left_in_line = sp->prev_left_in_line;
10593         g_parsefile->unget = sp->unget;
10594         memcpy(g_parsefile->lastc, sp->lastc, sizeof(sp->lastc));
10595         g_parsefile->strpush = sp->prev;
10596         if (sp != &(g_parsefile->basestrpush))
10597                 free(sp);
10598         INT_ON;
10599 }
10600
10601 static int
10602 preadfd(void)
10603 {
10604         int nr;
10605         char *buf = g_parsefile->buf;
10606
10607         g_parsefile->next_to_pgetc = buf;
10608 #if ENABLE_FEATURE_EDITING
10609  retry:
10610         if (!iflag || g_parsefile->pf_fd != STDIN_FILENO)
10611                 nr = nonblock_immune_read(g_parsefile->pf_fd, buf, IBUFSIZ - 1);
10612         else {
10613 # if ENABLE_ASH_IDLE_TIMEOUT
10614                 int timeout = -1;
10615                 const char *tmout_var = lookupvar("TMOUT");
10616                 if (tmout_var) {
10617                         timeout = atoi(tmout_var) * 1000;
10618                         if (timeout <= 0)
10619                                 timeout = -1;
10620                 }
10621                 line_input_state->timeout = timeout;
10622 # endif
10623 # if ENABLE_FEATURE_TAB_COMPLETION
10624                 line_input_state->path_lookup = pathval();
10625 # endif
10626                 reinit_unicode_for_ash();
10627                 nr = read_line_input(line_input_state, cmdedit_prompt, buf, IBUFSIZ);
10628                 if (nr == 0) {
10629                         /* ^C pressed, "convert" to SIGINT */
10630                         write(STDOUT_FILENO, "^C", 2);
10631                         if (trap[SIGINT]) {
10632                                 buf[0] = '\n';
10633                                 buf[1] = '\0';
10634                                 raise(SIGINT);
10635                                 return 1;
10636                         }
10637                         exitstatus = 128 + SIGINT;
10638                         bb_putchar('\n');
10639                         goto retry;
10640                 }
10641                 if (nr < 0) {
10642                         if (errno == 0) {
10643                                 /* Ctrl+D pressed */
10644                                 nr = 0;
10645                         }
10646 # if ENABLE_ASH_IDLE_TIMEOUT
10647                         else if (errno == EAGAIN && timeout > 0) {
10648                                 puts("\007timed out waiting for input: auto-logout");
10649                                 exitshell();
10650                         }
10651 # endif
10652                 }
10653         }
10654 #else
10655         nr = nonblock_immune_read(g_parsefile->pf_fd, buf, IBUFSIZ - 1);
10656 #endif
10657
10658 #if 0 /* disabled: nonblock_immune_read() handles this problem */
10659         if (nr < 0) {
10660                 if (parsefile->fd == 0 && errno == EWOULDBLOCK) {
10661                         int flags = fcntl(0, F_GETFL);
10662                         if (flags >= 0 && (flags & O_NONBLOCK)) {
10663                                 flags &= ~O_NONBLOCK;
10664                                 if (fcntl(0, F_SETFL, flags) >= 0) {
10665                                         out2str("sh: turning off NDELAY mode\n");
10666                                         goto retry;
10667                                 }
10668                         }
10669                 }
10670         }
10671 #endif
10672         return nr;
10673 }
10674
10675 /*
10676  * Refill the input buffer and return the next input character:
10677  *
10678  * 1) If a string was pushed back on the input, pop it;
10679  * 2) If an EOF was pushed back (g_parsefile->left_in_line < -BIGNUM)
10680  *    or we are reading from a string so we can't refill the buffer,
10681  *    return EOF.
10682  * 3) If there is more stuff in this buffer, use it else call read to fill it.
10683  * 4) Process input up to the next newline, deleting nul characters.
10684  */
10685 //#define pgetc_debug(...) bb_error_msg(__VA_ARGS__)
10686 #define pgetc_debug(...) ((void)0)
10687 static int pgetc(void);
10688 static int
10689 preadbuffer(void)
10690 {
10691         char *q;
10692         int more;
10693
10694         if (g_parsefile->strpush) {
10695 #if ENABLE_ASH_ALIAS
10696                 if (g_parsefile->left_in_line == -1
10697                  && g_parsefile->strpush->ap
10698                  && g_parsefile->next_to_pgetc[-1] != ' '
10699                  && g_parsefile->next_to_pgetc[-1] != '\t'
10700                 ) {
10701                         pgetc_debug("preadbuffer PEOA");
10702                         return PEOA;
10703                 }
10704 #endif
10705                 popstring();
10706                 return pgetc();
10707         }
10708         /* on both branches above g_parsefile->left_in_line < 0.
10709          * "pgetc" needs refilling.
10710          */
10711
10712         /* -90 is our -BIGNUM. Below we use -99 to mark "EOF on read",
10713          * pungetc() may increment it a few times.
10714          * Assuming it won't increment it to less than -90.
10715          */
10716         if (g_parsefile->left_in_line < -90 || g_parsefile->buf == NULL) {
10717                 pgetc_debug("preadbuffer PEOF1");
10718                 /* even in failure keep left_in_line and next_to_pgetc
10719                  * in lock step, for correct multi-layer pungetc.
10720                  * left_in_line was decremented before preadbuffer(),
10721                  * must inc next_to_pgetc: */
10722                 g_parsefile->next_to_pgetc++;
10723                 return PEOF;
10724         }
10725
10726         more = g_parsefile->left_in_buffer;
10727         if (more <= 0) {
10728                 flush_stdout_stderr();
10729  again:
10730                 more = preadfd();
10731                 if (more <= 0) {
10732                         /* don't try reading again */
10733                         g_parsefile->left_in_line = -99;
10734                         pgetc_debug("preadbuffer PEOF2");
10735                         g_parsefile->next_to_pgetc++;
10736                         return PEOF;
10737                 }
10738         }
10739
10740         /* Find out where's the end of line.
10741          * Set g_parsefile->left_in_line
10742          * and g_parsefile->left_in_buffer acordingly.
10743          * NUL chars are deleted.
10744          */
10745         q = g_parsefile->next_to_pgetc;
10746         for (;;) {
10747                 char c;
10748
10749                 more--;
10750
10751                 c = *q;
10752                 if (c == '\0') {
10753                         memmove(q, q + 1, more);
10754                 } else {
10755                         q++;
10756                         if (c == '\n') {
10757                                 g_parsefile->left_in_line = q - g_parsefile->next_to_pgetc - 1;
10758                                 break;
10759                         }
10760                 }
10761
10762                 if (more <= 0) {
10763                         g_parsefile->left_in_line = q - g_parsefile->next_to_pgetc - 1;
10764                         if (g_parsefile->left_in_line < 0)
10765                                 goto again;
10766                         break;
10767                 }
10768         }
10769         g_parsefile->left_in_buffer = more;
10770
10771         if (vflag) {
10772                 char save = *q;
10773                 *q = '\0';
10774                 out2str(g_parsefile->next_to_pgetc);
10775                 *q = save;
10776         }
10777
10778         pgetc_debug("preadbuffer at %d:%p'%s'",
10779                         g_parsefile->left_in_line,
10780                         g_parsefile->next_to_pgetc,
10781                         g_parsefile->next_to_pgetc);
10782         return (unsigned char)*g_parsefile->next_to_pgetc++;
10783 }
10784
10785 static void
10786 nlprompt(void)
10787 {
10788         g_parsefile->linno++;
10789         setprompt_if(doprompt, 2);
10790 }
10791 static void
10792 nlnoprompt(void)
10793 {
10794         g_parsefile->linno++;
10795         needprompt = doprompt;
10796 }
10797
10798 static int
10799 pgetc(void)
10800 {
10801         int c;
10802
10803         pgetc_debug("pgetc at %d:%p'%s'",
10804                         g_parsefile->left_in_line,
10805                         g_parsefile->next_to_pgetc,
10806                         g_parsefile->next_to_pgetc);
10807         if (g_parsefile->unget)
10808                 return g_parsefile->lastc[--g_parsefile->unget];
10809
10810         if (--g_parsefile->left_in_line >= 0)
10811                 c = (unsigned char)*g_parsefile->next_to_pgetc++;
10812         else
10813                 c = preadbuffer();
10814
10815         g_parsefile->lastc[1] = g_parsefile->lastc[0];
10816         g_parsefile->lastc[0] = c;
10817
10818         return c;
10819 }
10820
10821 #if ENABLE_ASH_ALIAS
10822 static int
10823 pgetc_without_PEOA(void)
10824 {
10825         int c;
10826         do {
10827                 pgetc_debug("pgetc at %d:%p'%s'",
10828                                 g_parsefile->left_in_line,
10829                                 g_parsefile->next_to_pgetc,
10830                                 g_parsefile->next_to_pgetc);
10831                 c = pgetc();
10832         } while (c == PEOA);
10833         return c;
10834 }
10835 #else
10836 # define pgetc_without_PEOA() pgetc()
10837 #endif
10838
10839 /*
10840  * Undo a call to pgetc.  Only two characters may be pushed back.
10841  * PEOF may be pushed back.
10842  */
10843 static void
10844 pungetc(void)
10845 {
10846         g_parsefile->unget++;
10847 }
10848
10849 /* This one eats backslash+newline */
10850 static int
10851 pgetc_eatbnl(void)
10852 {
10853         int c;
10854
10855         while ((c = pgetc()) == '\\') {
10856                 if (pgetc() != '\n') {
10857                         pungetc();
10858                         break;
10859                 }
10860
10861                 nlprompt();
10862         }
10863
10864         return c;
10865 }
10866
10867 struct synstack {
10868         smalluint syntax;
10869         uint8_t innerdq   :1;
10870         uint8_t varpushed :1;
10871         uint8_t dblquote  :1;
10872         int varnest;            /* levels of variables expansion */
10873         int dqvarnest;          /* levels of variables expansion within double quotes */
10874         int parenlevel;         /* levels of parens in arithmetic */
10875         struct synstack *prev;
10876         struct synstack *next;
10877 };
10878
10879 static int
10880 pgetc_top(struct synstack *stack)
10881 {
10882         return stack->syntax == SQSYNTAX ? pgetc() : pgetc_eatbnl();
10883 }
10884
10885 static void
10886 synstack_push(struct synstack **stack, struct synstack *next, int syntax)
10887 {
10888         memset(next, 0, sizeof(*next));
10889         next->syntax = syntax;
10890         next->next = *stack;
10891         (*stack)->prev = next;
10892         *stack = next;
10893 }
10894
10895 static ALWAYS_INLINE void
10896 synstack_pop(struct synstack **stack)
10897 {
10898         *stack = (*stack)->next;
10899 }
10900
10901 /*
10902  * To handle the "." command, a stack of input files is used.  Pushfile
10903  * adds a new entry to the stack and popfile restores the previous level.
10904  */
10905 static void
10906 pushfile(void)
10907 {
10908         struct parsefile *pf;
10909
10910         pf = ckzalloc(sizeof(*pf));
10911         pf->prev = g_parsefile;
10912         pf->pf_fd = -1;
10913         /*pf->strpush = NULL; - ckzalloc did it */
10914         /*pf->basestrpush.prev = NULL;*/
10915         /*pf->unget = 0;*/
10916         g_parsefile = pf;
10917 }
10918
10919 static void
10920 popfile(void)
10921 {
10922         struct parsefile *pf = g_parsefile;
10923
10924         if (pf == &basepf)
10925                 return;
10926
10927         INT_OFF;
10928         if (pf->pf_fd >= 0)
10929                 close(pf->pf_fd);
10930         free(pf->buf);
10931         while (pf->strpush)
10932                 popstring();
10933         g_parsefile = pf->prev;
10934         free(pf);
10935         INT_ON;
10936 }
10937
10938 static void
10939 unwindfiles(struct parsefile *stop)
10940 {
10941         while (g_parsefile != stop)
10942                 popfile();
10943 }
10944
10945 /*
10946  * Return to top level.
10947  */
10948 static void
10949 popallfiles(void)
10950 {
10951         unwindfiles(&basepf);
10952 }
10953
10954 /*
10955  * Close the file(s) that the shell is reading commands from.  Called
10956  * after a fork is done.
10957  */
10958 static void
10959 closescript(void)
10960 {
10961         popallfiles();
10962         if (g_parsefile->pf_fd > 0) {
10963                 close(g_parsefile->pf_fd);
10964                 g_parsefile->pf_fd = 0;
10965         }
10966 }
10967
10968 /*
10969  * Like setinputfile, but takes an open file descriptor.  Call this with
10970  * interrupts off.
10971  */
10972 static void
10973 setinputfd(int fd, int push)
10974 {
10975         if (push) {
10976                 pushfile();
10977                 g_parsefile->buf = NULL;
10978         }
10979         g_parsefile->pf_fd = fd;
10980         if (g_parsefile->buf == NULL)
10981                 g_parsefile->buf = ckmalloc(IBUFSIZ);
10982         g_parsefile->left_in_buffer = 0;
10983         g_parsefile->left_in_line = 0;
10984         g_parsefile->linno = 1;
10985 }
10986
10987 /*
10988  * Set the input to take input from a file.  If push is set, push the
10989  * old input onto the stack first.
10990  */
10991 static int
10992 setinputfile(const char *fname, int flags)
10993 {
10994         int fd;
10995
10996         INT_OFF;
10997         fd = open(fname, O_RDONLY | O_CLOEXEC);
10998         if (fd < 0) {
10999                 if (flags & INPUT_NOFILE_OK)
11000                         goto out;
11001                 exitstatus = 127;
11002                 ash_msg_and_raise_perror("can't open '%s'", fname);
11003         }
11004         if (fd < 10)
11005                 fd = savefd(fd);
11006         else if (O_CLOEXEC == 0) /* old libc */
11007                 close_on_exec_on(fd);
11008
11009         setinputfd(fd, flags & INPUT_PUSH_FILE);
11010  out:
11011         INT_ON;
11012         return fd;
11013 }
11014
11015 /*
11016  * Like setinputfile, but takes input from a string.
11017  */
11018 static void
11019 setinputstring(char *string)
11020 {
11021         INT_OFF;
11022         pushfile();
11023         g_parsefile->next_to_pgetc = string;
11024         g_parsefile->left_in_line = strlen(string);
11025         g_parsefile->buf = NULL;
11026         g_parsefile->linno = 1;
11027         INT_ON;
11028 }
11029
11030
11031 /*
11032  * Routines to check for mail.
11033  */
11034
11035 #if ENABLE_ASH_MAIL
11036
11037 /* Hash of mtimes of mailboxes */
11038 static unsigned mailtime_hash;
11039 /* Set if MAIL or MAILPATH is changed. */
11040 static smallint mail_var_path_changed;
11041
11042 /*
11043  * Print appropriate message(s) if mail has arrived.
11044  * If mail_var_path_changed is set,
11045  * then the value of MAIL has mail_var_path_changed,
11046  * so we just update the values.
11047  */
11048 static void
11049 chkmail(void)
11050 {
11051         const char *mpath;
11052         char *p;
11053         char *q;
11054         unsigned new_hash;
11055         struct stackmark smark;
11056         struct stat statb;
11057
11058         setstackmark(&smark);
11059         mpath = mpathset() ? mpathval() : mailval();
11060         new_hash = 0;
11061         for (;;) {
11062                 int len;
11063
11064                 len = padvance_magic(&mpath, nullstr, 2);
11065                 if (!len)
11066                         break;
11067                 p = stackblock();
11068                         break;
11069                 if (*p == '\0')
11070                         continue;
11071                 for (q = p; *q; q++)
11072                         continue;
11073 #if DEBUG
11074                 if (q[-1] != '/')
11075                         abort();
11076 #endif
11077                 q[-1] = '\0';                   /* delete trailing '/' */
11078                 if (stat(p, &statb) < 0) {
11079                         continue;
11080                 }
11081                 /* Very simplistic "hash": just a sum of all mtimes */
11082                 new_hash += (unsigned)statb.st_mtime;
11083         }
11084         if (!mail_var_path_changed && mailtime_hash != new_hash) {
11085                 if (mailtime_hash != 0)
11086                         out2str("you have mail\n");
11087                 mailtime_hash = new_hash;
11088         }
11089         mail_var_path_changed = 0;
11090         popstackmark(&smark);
11091 }
11092
11093 static void FAST_FUNC
11094 changemail(const char *val UNUSED_PARAM)
11095 {
11096         mail_var_path_changed = 1;
11097 }
11098
11099 #endif /* ASH_MAIL */
11100
11101
11102 /* ============ ??? */
11103
11104 /*
11105  * Set the shell parameters.
11106  */
11107 static void
11108 setparam(char **argv)
11109 {
11110         char **newparam;
11111         char **ap;
11112         int nparam;
11113
11114         for (nparam = 0; argv[nparam]; nparam++)
11115                 continue;
11116         ap = newparam = ckmalloc((nparam + 1) * sizeof(*ap));
11117         while (*argv) {
11118                 *ap++ = ckstrdup(*argv++);
11119         }
11120         *ap = NULL;
11121         freeparam(&shellparam);
11122         shellparam.malloced = 1;
11123         shellparam.nparam = nparam;
11124         shellparam.p = newparam;
11125 #if ENABLE_ASH_GETOPTS
11126         shellparam.optind = 1;
11127         shellparam.optoff = -1;
11128 #endif
11129 }
11130
11131 /*
11132  * Process shell options.  The global variable argptr contains a pointer
11133  * to the argument list; we advance it past the options.
11134  *
11135  * SUSv3 section 2.8.1 "Consequences of Shell Errors" says:
11136  * For a non-interactive shell, an error condition encountered
11137  * by a special built-in ... shall cause the shell to write a diagnostic message
11138  * to standard error and exit as shown in the following table:
11139  * Error                                           Special Built-In
11140  * ...
11141  * Utility syntax error (option or operand error)  Shall exit
11142  * ...
11143  * However, in bug 1142 (http://busybox.net/bugs/view.php?id=1142)
11144  * we see that bash does not do that (set "finishes" with error code 1 instead,
11145  * and shell continues), and people rely on this behavior!
11146  * Testcase:
11147  * set -o barfoo 2>/dev/null
11148  * echo $?
11149  *
11150  * Oh well. Let's mimic that.
11151  */
11152 static int
11153 plus_minus_o(char *name, int val)
11154 {
11155         int i;
11156
11157         if (name) {
11158                 for (i = 0; i < NOPTS; i++) {
11159                         if (strcmp(name, optnames(i)) == 0) {
11160                                 optlist[i] = val;
11161                                 return 0;
11162                         }
11163                 }
11164                 ash_msg("illegal option %co %s", val ? '-' : '+', name);
11165                 return 1;
11166         }
11167         for (i = 0; i < NOPTS; i++) {
11168                 if (optnames(i)[0] == '\0')
11169                         continue;
11170                 if (val) {
11171                         out1fmt("%-16s%s\n", optnames(i), optlist[i] ? "on" : "off");
11172                 } else {
11173                         out1fmt("set %co %s\n", optlist[i] ? '-' : '+', optnames(i));
11174                 }
11175         }
11176         return 0;
11177 }
11178 static void
11179 setoption(int flag, int val)
11180 {
11181         int i;
11182
11183         for (i = 0; i < NOPTS; i++) {
11184                 if (optletters(i) == flag && optnames(i)[0] != '\0') {
11185                         optlist[i] = val;
11186                         return;
11187                 }
11188         }
11189         ash_msg_and_raise_error("illegal option %c%c", val ? '-' : '+', flag);
11190         /* NOTREACHED */
11191 }
11192 /* If login_sh is not NULL, we are called to parse command line opts,
11193  * not "set -opts"
11194  */
11195 static int
11196 options(int *login_sh)
11197 {
11198         char *p;
11199         int val;
11200         int c;
11201
11202         if (login_sh)
11203                 minusc = NULL;
11204         while ((p = *argptr) != NULL) {
11205                 c = *p++;
11206                 if (c != '-' && c != '+')
11207                         break;
11208                 argptr++;
11209                 val = 0; /* val = 0 if c == '+' */
11210                 if (c == '-') {
11211                         val = 1;
11212                         if (p[0] == '\0' || LONE_DASH(p)) {
11213                                 if (!login_sh) {
11214                                         /* "-" means turn off -x and -v */
11215                                         if (p[0] == '\0')
11216                                                 xflag = vflag = 0;
11217                                         /* "--" means reset params */
11218                                         else if (*argptr == NULL)
11219                                                 setparam(argptr);
11220                                 }
11221                                 break;    /* "-" or "--" terminates options */
11222                         }
11223                 }
11224                 /* first char was + or - */
11225                 while ((c = *p++) != '\0') {
11226                         if (login_sh) {
11227                                 /* bash 3.2 indeed handles -c CMD and +c CMD the same */
11228                                 if (c == 'c') {
11229                                         minusc = p; /* command is after shell args */
11230                                         cflag = 1;
11231                                         continue;
11232                                 }
11233                                 if (c == 's') { /* -s, +s */
11234                                         sflag = 1;
11235                                         continue;
11236                                 }
11237                                 if (c == 'i') { /* -i, +i */
11238                                         iflag = 1;
11239                                         continue;
11240                                 }
11241                                 if (c == 'l') {
11242                                         *login_sh = 1; /* -l or +l == --login */
11243                                         continue;
11244                                 }
11245                                 /* bash does not accept +-login, we also won't */
11246                                 if (val && (c == '-')) { /* long options */
11247                                         if (strcmp(p, "login") == 0) {
11248                                                 *login_sh = 1;
11249                                         }
11250                                         break;
11251                                 }
11252                         }
11253                         if (c == 'o') {
11254                                 if (plus_minus_o(*argptr, val)) {
11255                                         /* it already printed err message */
11256                                         return 1; /* error */
11257                                 }
11258                                 if (*argptr)
11259                                         argptr++;
11260                         } else {
11261                                 setoption(c, val);
11262                         }
11263                 }
11264         }
11265         return 0;
11266 }
11267
11268 /*
11269  * The shift builtin command.
11270  */
11271 static int FAST_FUNC
11272 shiftcmd(int argc UNUSED_PARAM, char **argv)
11273 {
11274         int n;
11275         char **ap1, **ap2;
11276
11277         n = 1;
11278         if (argv[1])
11279                 n = number(argv[1]);
11280         if (n > shellparam.nparam)
11281                 return 1;
11282         INT_OFF;
11283         shellparam.nparam -= n;
11284         for (ap1 = shellparam.p; --n >= 0; ap1++) {
11285                 if (shellparam.malloced)
11286                         free(*ap1);
11287         }
11288         ap2 = shellparam.p;
11289         while ((*ap2++ = *ap1++) != NULL)
11290                 continue;
11291 #if ENABLE_ASH_GETOPTS
11292         shellparam.optind = 1;
11293         shellparam.optoff = -1;
11294 #endif
11295         INT_ON;
11296         return 0;
11297 }
11298
11299 /*
11300  * POSIX requires that 'set' (but not export or readonly) output the
11301  * variables in lexicographic order - by the locale's collating order (sigh).
11302  * Maybe we could keep them in an ordered balanced binary tree
11303  * instead of hashed lists.
11304  * For now just roll 'em through qsort for printing...
11305  */
11306 static int
11307 showvars(const char *sep_prefix, int on, int off)
11308 {
11309         const char *sep;
11310         char **ep, **epend;
11311
11312         ep = listvars(on, off, /*strlist:*/ NULL, &epend);
11313         qsort(ep, epend - ep, sizeof(char *), vpcmp);
11314
11315         sep = *sep_prefix ? " " : sep_prefix;
11316
11317         for (; ep < epend; ep++) {
11318                 const char *p;
11319                 const char *q;
11320
11321                 p = endofname(*ep);
11322 /* Used to have simple "p = strchrnul(*ep, '=')" here instead, but this
11323  * makes "export -p" to have output not suitable for "eval":
11324  * import os
11325  * os.environ["test-test"]="test"
11326  * if os.fork() == 0:
11327  *   os.execv("ash", [ 'ash', '-c', 'eval $(export -p); echo OK' ])  # fixes this
11328  * os.execv("ash", [ 'ash', '-c', 'env | grep test-test' ])
11329  */
11330                 q = nullstr;
11331                 if (*p == '=')
11332                         q = single_quote(++p);
11333                 out1fmt("%s%s%.*s%s\n", sep_prefix, sep, (int)(p - *ep), *ep, q);
11334         }
11335         return 0;
11336 }
11337
11338 /*
11339  * The set command builtin.
11340  */
11341 static int FAST_FUNC
11342 setcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
11343 {
11344         int retval;
11345
11346         if (!argv[1])
11347                 return showvars(nullstr, 0, VUNSET);
11348
11349         INT_OFF;
11350         retval = options(/*login_sh:*/ NULL);
11351         if (retval == 0) { /* if no parse error... */
11352                 optschanged();
11353                 if (*argptr != NULL) {
11354                         setparam(argptr);
11355                 }
11356         }
11357         INT_ON;
11358         return retval;
11359 }
11360
11361 #if ENABLE_ASH_RANDOM_SUPPORT
11362 static void FAST_FUNC
11363 change_random(const char *value)
11364 {
11365         uint32_t t;
11366
11367         if (value == NULL) {
11368                 /* "get", generate */
11369                 t = next_random(&random_gen);
11370                 /* set without recursion */
11371                 setvar(vrandom.var_text, utoa(t), VNOFUNC);
11372                 vrandom.flags &= ~VNOFUNC;
11373         } else {
11374                 /* set/reset */
11375                 t = strtoul(value, NULL, 10);
11376                 INIT_RANDOM_T(&random_gen, (t ? t : 1), t);
11377         }
11378 }
11379 #endif
11380
11381 #if BASH_EPOCH_VARS
11382 static void FAST_FUNC
11383 change_epoch(struct var *vepoch, const char *fmt)
11384 {
11385         struct timeval tv;
11386         char buffer[sizeof("%lu.nnnnnn") + sizeof(long)*3];
11387
11388         gettimeofday(&tv, NULL);
11389         sprintf(buffer, fmt, (unsigned long)tv.tv_sec, (unsigned)tv.tv_usec);
11390         setvar(vepoch->var_text, buffer, VNOFUNC);
11391         vepoch->flags &= ~VNOFUNC;
11392 }
11393
11394 static void FAST_FUNC
11395 change_seconds(const char *value UNUSED_PARAM)
11396 {
11397         change_epoch(&vepochs, "%lu");
11398 }
11399
11400 static void FAST_FUNC
11401 change_realtime(const char *value UNUSED_PARAM)
11402 {
11403         change_epoch(&vepochr, "%lu.%06u");
11404 }
11405 #endif
11406
11407 #if ENABLE_ASH_GETOPTS
11408 static int
11409 getopts(char *optstr, char *optvar, char **optfirst)
11410 {
11411         char *p, *q;
11412         char c = '?';
11413         int done = 0;
11414         char sbuf[2];
11415         char **optnext;
11416         int ind = shellparam.optind;
11417         int off = shellparam.optoff;
11418
11419         sbuf[1] = '\0';
11420
11421         shellparam.optind = -1;
11422         optnext = optfirst + ind - 1;
11423
11424         if (ind <= 1 || off < 0 || (int)strlen(optnext[-1]) < off)
11425                 p = NULL;
11426         else
11427                 p = optnext[-1] + off;
11428         if (p == NULL || *p == '\0') {
11429                 /* Current word is done, advance */
11430                 p = *optnext;
11431                 if (p == NULL || *p != '-' || *++p == '\0') {
11432  atend:
11433                         unsetvar("OPTARG");
11434                         p = NULL;
11435                         done = 1;
11436                         goto out;
11437                 }
11438                 optnext++;
11439                 if (LONE_DASH(p))        /* check for "--" */
11440                         goto atend;
11441         }
11442
11443         c = *p++;
11444         for (q = optstr; *q != c;) {
11445                 if (*q == '\0') {
11446                         /* OPTERR is a bashism */
11447                         const char *cp = lookupvar("OPTERR");
11448                         if ((cp && LONE_CHAR(cp, '0'))
11449                          || (optstr[0] == ':')
11450                         ) {
11451                                 sbuf[0] = c;
11452                                 /*sbuf[1] = '\0'; - already is */
11453                                 setvar0("OPTARG", sbuf);
11454                         } else {
11455                                 fprintf(stderr, "Illegal option -%c\n", c);
11456                                 unsetvar("OPTARG");
11457                         }
11458                         c = '?';
11459                         goto out;
11460                 }
11461                 if (*++q == ':')
11462                         q++;
11463         }
11464
11465         if (*++q == ':') {
11466                 if (*p == '\0' && (p = *optnext) == NULL) {
11467                         /* OPTERR is a bashism */
11468                         const char *cp = lookupvar("OPTERR");
11469                         if ((cp && LONE_CHAR(cp, '0'))
11470                          || (optstr[0] == ':')
11471                         ) {
11472                                 sbuf[0] = c;
11473                                 /*sbuf[1] = '\0'; - already is */
11474                                 setvar0("OPTARG", sbuf);
11475                                 c = ':';
11476                         } else {
11477                                 fprintf(stderr, "No arg for -%c option\n", c);
11478                                 unsetvar("OPTARG");
11479                                 c = '?';
11480                         }
11481                         goto out;
11482                 }
11483
11484                 if (p == *optnext)
11485                         optnext++;
11486                 setvar0("OPTARG", p);
11487                 p = NULL;
11488         } else
11489                 setvar0("OPTARG", nullstr);
11490  out:
11491         ind = optnext - optfirst + 1;
11492         setvar("OPTIND", itoa(ind), VNOFUNC);
11493         sbuf[0] = c;
11494         /*sbuf[1] = '\0'; - already is */
11495         setvar0(optvar, sbuf);
11496
11497         shellparam.optoff = p ? p - *(optnext - 1) : -1;
11498         shellparam.optind = ind;
11499
11500         return done;
11501 }
11502
11503 /*
11504  * The getopts builtin.  Shellparam.optnext points to the next argument
11505  * to be processed.  Shellparam.optptr points to the next character to
11506  * be processed in the current argument.  If shellparam.optnext is NULL,
11507  * then it's the first time getopts has been called.
11508  */
11509 static int FAST_FUNC
11510 getoptscmd(int argc, char **argv)
11511 {
11512         char **optbase;
11513
11514         if (argc < 3)
11515                 ash_msg_and_raise_error("usage: getopts optstring var [arg]");
11516         if (argc == 3) {
11517                 optbase = shellparam.p;
11518                 if ((unsigned)shellparam.optind > shellparam.nparam + 1) {
11519                         shellparam.optind = 1;
11520                         shellparam.optoff = -1;
11521                 }
11522         } else {
11523                 optbase = &argv[3];
11524                 if ((unsigned)shellparam.optind > argc - 2) {
11525                         shellparam.optind = 1;
11526                         shellparam.optoff = -1;
11527                 }
11528         }
11529
11530         return getopts(argv[1], argv[2], optbase);
11531 }
11532 #endif /* ASH_GETOPTS */
11533
11534
11535 /* ============ Shell parser */
11536
11537 struct heredoc {
11538         struct heredoc *next;   /* next here document in list */
11539         union node *here;       /* redirection node */
11540         char *eofmark;          /* string indicating end of input */
11541         smallint striptabs;     /* if set, strip leading tabs */
11542 };
11543
11544 static smallint tokpushback;           /* last token pushed back */
11545 static smallint quoteflag;             /* set if (part of) last token was quoted */
11546 static token_id_t lasttoken;           /* last token read (integer id Txxx) */
11547 static struct heredoc *heredoclist;    /* list of here documents to read */
11548 static char *wordtext;                 /* text of last word returned by readtoken */
11549 static struct nodelist *backquotelist;
11550 static union node *redirnode;
11551 static struct heredoc *heredoc;
11552
11553 static const char *
11554 tokname(char *buf, int tok)
11555 {
11556         if (tok < TSEMI)
11557                 return tokname_array[tok];
11558         sprintf(buf, "\"%s\"", tokname_array[tok]);
11559         return buf;
11560 }
11561
11562 /* raise_error_unexpected_syntax:
11563  * Called when an unexpected token is read during the parse.  The argument
11564  * is the token that is expected, or -1 if more than one type of token can
11565  * occur at this point.
11566  */
11567 static void raise_error_unexpected_syntax(int) NORETURN;
11568 static void
11569 raise_error_unexpected_syntax(int token)
11570 {
11571         char msg[64];
11572         char buf[16];
11573         int l;
11574
11575         l = sprintf(msg, "unexpected %s", tokname(buf, lasttoken));
11576         if (token >= 0)
11577                 sprintf(msg + l, " (expecting %s)", tokname(buf, token));
11578         raise_error_syntax(msg);
11579         /* NOTREACHED */
11580 }
11581
11582 /* parsing is heavily cross-recursive, need these forward decls */
11583 static union node *andor(void);
11584 static union node *pipeline(void);
11585 static union node *parse_command(void);
11586 static void parseheredoc(void);
11587 static int peektoken(void);
11588 static int readtoken(void);
11589
11590 static union node *
11591 list(int nlflag)
11592 {
11593         union node *n1, *n2, *n3;
11594         int tok;
11595
11596         n1 = NULL;
11597         for (;;) {
11598                 switch (peektoken()) {
11599                 case TNL:
11600                         if (!(nlflag & 1))
11601                                 break;
11602                         parseheredoc();
11603                         return n1;
11604
11605                 case TEOF:
11606                         if (!n1 && (nlflag & 1))
11607                                 n1 = NODE_EOF;
11608                         parseheredoc();
11609                         return n1;
11610                 }
11611
11612                 checkkwd = CHKNL | CHKKWD | CHKALIAS;
11613                 if (nlflag == 2 && ((1 << peektoken()) & tokendlist))
11614                         return n1;
11615                 nlflag |= 2;
11616
11617                 n2 = andor();
11618                 tok = readtoken();
11619                 if (tok == TBACKGND) {
11620                         if (n2->type == NPIPE) {
11621                                 n2->npipe.pipe_backgnd = 1;
11622                         } else {
11623                                 if (n2->type != NREDIR) {
11624                                         n3 = stzalloc(sizeof(struct nredir));
11625                                         n3->nredir.n = n2;
11626                                         /*n3->nredir.redirect = NULL; - stzalloc did it */
11627                                         n2 = n3;
11628                                 }
11629                                 n2->type = NBACKGND;
11630                         }
11631                 }
11632                 if (n1 == NULL) {
11633                         n1 = n2;
11634                 } else {
11635                         n3 = stzalloc(sizeof(struct nbinary));
11636                         n3->type = NSEMI;
11637                         n3->nbinary.ch1 = n1;
11638                         n3->nbinary.ch2 = n2;
11639                         n1 = n3;
11640                 }
11641                 switch (tok) {
11642                 case TNL:
11643                 case TEOF:
11644                         tokpushback = 1;
11645                         /* fall through */
11646                 case TBACKGND:
11647                 case TSEMI:
11648                         break;
11649                 default:
11650                         if ((nlflag & 1))
11651                                 raise_error_unexpected_syntax(-1);
11652                         tokpushback = 1;
11653                         return n1;
11654                 }
11655         }
11656 }
11657
11658 static union node *
11659 andor(void)
11660 {
11661         union node *n1, *n2, *n3;
11662         int t;
11663
11664         n1 = pipeline();
11665         for (;;) {
11666                 t = readtoken();
11667                 if (t == TAND) {
11668                         t = NAND;
11669                 } else if (t == TOR) {
11670                         t = NOR;
11671                 } else {
11672                         tokpushback = 1;
11673                         return n1;
11674                 }
11675                 checkkwd = CHKNL | CHKKWD | CHKALIAS;
11676                 n2 = pipeline();
11677                 n3 = stzalloc(sizeof(struct nbinary));
11678                 n3->type = t;
11679                 n3->nbinary.ch1 = n1;
11680                 n3->nbinary.ch2 = n2;
11681                 n1 = n3;
11682         }
11683 }
11684
11685 static union node *
11686 pipeline(void)
11687 {
11688         union node *n1, *n2, *pipenode;
11689         struct nodelist *lp, *prev;
11690         int negate;
11691
11692         negate = 0;
11693         TRACE(("pipeline: entered\n"));
11694         if (readtoken() == TNOT) {
11695                 negate = !negate;
11696                 checkkwd = CHKKWD | CHKALIAS;
11697         } else
11698                 tokpushback = 1;
11699         n1 = parse_command();
11700         if (readtoken() == TPIPE) {
11701                 pipenode = stzalloc(sizeof(struct npipe));
11702                 pipenode->type = NPIPE;
11703                 /*pipenode->npipe.pipe_backgnd = 0; - stzalloc did it */
11704                 lp = stzalloc(sizeof(struct nodelist));
11705                 pipenode->npipe.cmdlist = lp;
11706                 lp->n = n1;
11707                 do {
11708                         prev = lp;
11709                         lp = stzalloc(sizeof(struct nodelist));
11710                         checkkwd = CHKNL | CHKKWD | CHKALIAS;
11711                         lp->n = parse_command();
11712                         prev->next = lp;
11713                 } while (readtoken() == TPIPE);
11714                 lp->next = NULL;
11715                 n1 = pipenode;
11716         }
11717         tokpushback = 1;
11718         if (negate) {
11719                 n2 = stzalloc(sizeof(struct nnot));
11720                 n2->type = NNOT;
11721                 n2->nnot.com = n1;
11722                 return n2;
11723         }
11724         return n1;
11725 }
11726
11727 static union node *
11728 makename(void)
11729 {
11730         union node *n;
11731
11732         n = stzalloc(sizeof(struct narg));
11733         n->type = NARG;
11734         /*n->narg.next = NULL; - stzalloc did it */
11735         n->narg.text = wordtext;
11736         n->narg.backquote = backquotelist;
11737         return n;
11738 }
11739
11740 static void
11741 fixredir(union node *n, const char *text, int err)
11742 {
11743         int fd;
11744
11745         TRACE(("Fix redir %s %d\n", text, err));
11746         if (!err)
11747                 n->ndup.vname = NULL;
11748
11749         fd = bb_strtou(text, NULL, 10);
11750         if (!errno && fd >= 0)
11751                 n->ndup.dupfd = fd;
11752         else if (LONE_DASH(text))
11753                 n->ndup.dupfd = -1;
11754         else {
11755                 if (err)
11756                         raise_error_syntax("bad fd number");
11757                 n->ndup.vname = makename();
11758         }
11759 }
11760
11761 static void
11762 parsefname(void)
11763 {
11764         union node *n = redirnode;
11765
11766         if (n->type == NHERE)
11767                 checkkwd = CHKEOFMARK;
11768         if (readtoken() != TWORD)
11769                 raise_error_unexpected_syntax(-1);
11770         if (n->type == NHERE) {
11771                 struct heredoc *here = heredoc;
11772                 struct heredoc *p;
11773
11774                 if (quoteflag == 0)
11775                         n->type = NXHERE;
11776                 TRACE(("Here document %d\n", n->type));
11777                 rmescapes(wordtext, 0, NULL);
11778                 here->eofmark = wordtext;
11779                 here->next = NULL;
11780                 if (heredoclist == NULL)
11781                         heredoclist = here;
11782                 else {
11783                         for (p = heredoclist; p->next; p = p->next)
11784                                 continue;
11785                         p->next = here;
11786                 }
11787         } else if (n->type == NTOFD || n->type == NFROMFD) {
11788                 fixredir(n, wordtext, 0);
11789         } else {
11790                 n->nfile.fname = makename();
11791         }
11792 }
11793
11794 static union node *
11795 simplecmd(void)
11796 {
11797         union node *args, **app;
11798         union node *n = NULL;
11799         union node *vars, **vpp;
11800         union node **rpp, *redir;
11801         int savecheckkwd;
11802         int savelinno;
11803 #if BASH_TEST2
11804         smallint double_brackets_flag = 0;
11805 #endif
11806         IF_BASH_FUNCTION(smallint function_flag = 0;)
11807
11808         args = NULL;
11809         app = &args;
11810         vars = NULL;
11811         vpp = &vars;
11812         redir = NULL;
11813         rpp = &redir;
11814
11815         savecheckkwd = CHKALIAS;
11816         savelinno = g_parsefile->linno;
11817         for (;;) {
11818                 int t;
11819                 checkkwd = savecheckkwd;
11820                 t = readtoken();
11821                 switch (t) {
11822 #if BASH_FUNCTION
11823                 case TFUNCTION:
11824                         if (peektoken() != TWORD)
11825                                 raise_error_unexpected_syntax(TWORD);
11826                         function_flag = 1;
11827                         break;
11828 #endif
11829 #if BASH_TEST2
11830                 case TAND: /* "&&" */
11831                 case TOR: /* "||" */
11832                         if (!double_brackets_flag) {
11833                                 tokpushback = 1;
11834                                 goto out;
11835                         }
11836                         wordtext = (char *) (t == TAND ? "-a" : "-o");
11837 #endif
11838                 case TWORD:
11839                         n = stzalloc(sizeof(struct narg));
11840                         n->type = NARG;
11841                         /*n->narg.next = NULL; - stzalloc did it */
11842                         n->narg.text = wordtext;
11843 #if BASH_TEST2
11844                         if (strcmp("[[", wordtext) == 0)
11845                                 double_brackets_flag = 1;
11846                         else if (strcmp("]]", wordtext) == 0)
11847                                 double_brackets_flag = 0;
11848 #endif
11849                         n->narg.backquote = backquotelist;
11850                         if (savecheckkwd && isassignment(wordtext)) {
11851                                 *vpp = n;
11852                                 vpp = &n->narg.next;
11853                         } else {
11854                                 *app = n;
11855                                 app = &n->narg.next;
11856                                 savecheckkwd = 0;
11857                         }
11858 #if BASH_FUNCTION
11859                         if (function_flag) {
11860                                 checkkwd = CHKNL | CHKKWD;
11861                                 switch (peektoken()) {
11862                                 case TBEGIN:
11863                                 case TIF:
11864                                 case TCASE:
11865                                 case TUNTIL:
11866                                 case TWHILE:
11867                                 case TFOR:
11868                                         goto do_func;
11869                                 case TLP:
11870                                         function_flag = 0;
11871                                         break;
11872 # if BASH_TEST2
11873                                 case TWORD:
11874                                         if (strcmp("[[", wordtext) == 0)
11875                                                 goto do_func;
11876                                         /* fall through */
11877 # endif
11878                                 default:
11879                                         raise_error_unexpected_syntax(-1);
11880                                 }
11881                         }
11882 #endif
11883                         break;
11884                 case TREDIR:
11885                         *rpp = n = redirnode;
11886                         rpp = &n->nfile.next;
11887                         parsefname();   /* read name of redirection file */
11888                         break;
11889                 case TLP:
11890  IF_BASH_FUNCTION(do_func:)
11891                         if (args && app == &args->narg.next
11892                          && !vars && !redir
11893                         ) {
11894                                 struct builtincmd *bcmd;
11895                                 const char *name;
11896
11897                                 /* We have a function */
11898                                 if (IF_BASH_FUNCTION(!function_flag &&) readtoken() != TRP)
11899                                         raise_error_unexpected_syntax(TRP);
11900                                 name = n->narg.text;
11901                                 if (!goodname(name)
11902                                  || ((bcmd = find_builtin(name)) && IS_BUILTIN_SPECIAL(bcmd))
11903                                 ) {
11904                                         raise_error_syntax("bad function name");
11905                                 }
11906                                 n->type = NDEFUN;
11907                                 checkkwd = CHKNL | CHKKWD | CHKALIAS;
11908                                 n->ndefun.text = n->narg.text;
11909                                 n->ndefun.linno = g_parsefile->linno;
11910                                 n->ndefun.body = parse_command();
11911                                 return n;
11912                         }
11913                         IF_BASH_FUNCTION(function_flag = 0;)
11914                         /* fall through */
11915                 default:
11916                         tokpushback = 1;
11917                         goto out;
11918                 }
11919         }
11920  out:
11921         *app = NULL;
11922         *vpp = NULL;
11923         *rpp = NULL;
11924         n = stzalloc(sizeof(struct ncmd));
11925         if (NCMD != 0)
11926                 n->type = NCMD;
11927         n->ncmd.linno = savelinno;
11928         n->ncmd.args = args;
11929         n->ncmd.assign = vars;
11930         n->ncmd.redirect = redir;
11931         return n;
11932 }
11933
11934 static union node *
11935 parse_command(void)
11936 {
11937         union node *n1, *n2;
11938         union node *ap, **app;
11939         union node *cp, **cpp;
11940         union node *redir, **rpp;
11941         union node **rpp2;
11942         int t;
11943         int savelinno;
11944
11945         redir = NULL;
11946         rpp2 = &redir;
11947
11948         savelinno = g_parsefile->linno;
11949
11950         switch (readtoken()) {
11951         default:
11952                 raise_error_unexpected_syntax(-1);
11953                 /* NOTREACHED */
11954         case TIF:
11955                 n1 = stzalloc(sizeof(struct nif));
11956                 n1->type = NIF;
11957                 n1->nif.test = list(0);
11958                 if (readtoken() != TTHEN)
11959                         raise_error_unexpected_syntax(TTHEN);
11960                 n1->nif.ifpart = list(0);
11961                 n2 = n1;
11962                 while (readtoken() == TELIF) {
11963                         n2->nif.elsepart = stzalloc(sizeof(struct nif));
11964                         n2 = n2->nif.elsepart;
11965                         n2->type = NIF;
11966                         n2->nif.test = list(0);
11967                         if (readtoken() != TTHEN)
11968                                 raise_error_unexpected_syntax(TTHEN);
11969                         n2->nif.ifpart = list(0);
11970                 }
11971                 if (lasttoken == TELSE)
11972                         n2->nif.elsepart = list(0);
11973                 else {
11974                         n2->nif.elsepart = NULL;
11975                         tokpushback = 1;
11976                 }
11977                 t = TFI;
11978                 break;
11979         case TWHILE:
11980         case TUNTIL: {
11981                 int got;
11982                 n1 = stzalloc(sizeof(struct nbinary));
11983                 n1->type = (lasttoken == TWHILE) ? NWHILE : NUNTIL;
11984                 n1->nbinary.ch1 = list(0);
11985                 got = readtoken();
11986                 if (got != TDO) {
11987                         TRACE(("expecting DO got '%s' %s\n", tokname_array[got],
11988                                         got == TWORD ? wordtext : ""));
11989                         raise_error_unexpected_syntax(TDO);
11990                 }
11991                 n1->nbinary.ch2 = list(0);
11992                 t = TDONE;
11993                 break;
11994         }
11995         case TFOR:
11996                 if (readtoken() != TWORD || quoteflag || !goodname(wordtext))
11997                         raise_error_syntax("bad for loop variable");
11998                 n1 = stzalloc(sizeof(struct nfor));
11999                 n1->type = NFOR;
12000                 n1->nfor.linno = savelinno;
12001                 n1->nfor.var = wordtext;
12002                 checkkwd = CHKNL | CHKKWD | CHKALIAS;
12003                 if (readtoken() == TIN) {
12004                         app = &ap;
12005                         while (readtoken() == TWORD) {
12006                                 n2 = stzalloc(sizeof(struct narg));
12007                                 n2->type = NARG;
12008                                 /*n2->narg.next = NULL; - stzalloc did it */
12009                                 n2->narg.text = wordtext;
12010                                 n2->narg.backquote = backquotelist;
12011                                 *app = n2;
12012                                 app = &n2->narg.next;
12013                         }
12014                         *app = NULL;
12015                         n1->nfor.args = ap;
12016                         if (lasttoken != TNL && lasttoken != TSEMI)
12017                                 raise_error_unexpected_syntax(-1);
12018                 } else {
12019                         n2 = stzalloc(sizeof(struct narg));
12020                         n2->type = NARG;
12021                         /*n2->narg.next = NULL; - stzalloc did it */
12022                         n2->narg.text = (char *)dolatstr;
12023                         /*n2->narg.backquote = NULL;*/
12024                         n1->nfor.args = n2;
12025                         /*
12026                          * Newline or semicolon here is optional (but note
12027                          * that the original Bourne shell only allowed NL).
12028                          */
12029                         if (lasttoken != TSEMI)
12030                                 tokpushback = 1;
12031                 }
12032                 checkkwd = CHKNL | CHKKWD | CHKALIAS;
12033                 if (readtoken() != TDO)
12034                         raise_error_unexpected_syntax(TDO);
12035                 n1->nfor.body = list(0);
12036                 t = TDONE;
12037                 break;
12038         case TCASE:
12039                 n1 = stzalloc(sizeof(struct ncase));
12040                 n1->type = NCASE;
12041                 n1->ncase.linno = savelinno;
12042                 if (readtoken() != TWORD)
12043                         raise_error_unexpected_syntax(TWORD);
12044                 n1->ncase.expr = n2 = stzalloc(sizeof(struct narg));
12045                 n2->type = NARG;
12046                 /*n2->narg.next = NULL; - stzalloc did it */
12047                 n2->narg.text = wordtext;
12048                 n2->narg.backquote = backquotelist;
12049                 checkkwd = CHKNL | CHKKWD | CHKALIAS;
12050                 if (readtoken() != TIN)
12051                         raise_error_unexpected_syntax(TIN);
12052                 cpp = &n1->ncase.cases;
12053  next_case:
12054                 checkkwd = CHKNL | CHKKWD;
12055                 t = readtoken();
12056                 while (t != TESAC) {
12057                         if (lasttoken == TLP)
12058                                 readtoken();
12059                         *cpp = cp = stzalloc(sizeof(struct nclist));
12060                         cp->type = NCLIST;
12061                         app = &cp->nclist.pattern;
12062                         for (;;) {
12063                                 *app = ap = stzalloc(sizeof(struct narg));
12064                                 ap->type = NARG;
12065                                 /*ap->narg.next = NULL; - stzalloc did it */
12066                                 ap->narg.text = wordtext;
12067                                 ap->narg.backquote = backquotelist;
12068                                 if (readtoken() != TPIPE)
12069                                         break;
12070                                 app = &ap->narg.next;
12071                                 readtoken();
12072                         }
12073                         //ap->narg.next = NULL;
12074                         if (lasttoken != TRP)
12075                                 raise_error_unexpected_syntax(TRP);
12076                         cp->nclist.body = list(2);
12077
12078                         cpp = &cp->nclist.next;
12079
12080                         checkkwd = CHKNL | CHKKWD;
12081                         t = readtoken();
12082                         if (t != TESAC) {
12083                                 if (t != TENDCASE)
12084                                         raise_error_unexpected_syntax(TENDCASE);
12085                                 goto next_case;
12086                         }
12087                 }
12088                 *cpp = NULL;
12089                 goto redir;
12090         case TLP:
12091                 n1 = stzalloc(sizeof(struct nredir));
12092                 n1->type = NSUBSHELL;
12093                 n1->nredir.linno = savelinno;
12094                 n1->nredir.n = list(0);
12095                 /*n1->nredir.redirect = NULL; - stzalloc did it */
12096                 t = TRP;
12097                 break;
12098         case TBEGIN:
12099                 n1 = list(0);
12100                 t = TEND;
12101                 break;
12102         IF_BASH_FUNCTION(case TFUNCTION:)
12103         case TWORD:
12104         case TREDIR:
12105                 tokpushback = 1;
12106                 return simplecmd();
12107         }
12108
12109         if (readtoken() != t)
12110                 raise_error_unexpected_syntax(t);
12111
12112  redir:
12113         /* Now check for redirection which may follow command */
12114         checkkwd = CHKKWD | CHKALIAS;
12115         rpp = rpp2;
12116         while (readtoken() == TREDIR) {
12117                 *rpp = n2 = redirnode;
12118                 rpp = &n2->nfile.next;
12119                 parsefname();
12120         }
12121         tokpushback = 1;
12122         *rpp = NULL;
12123         if (redir) {
12124                 if (n1->type != NSUBSHELL) {
12125                         n2 = stzalloc(sizeof(struct nredir));
12126                         n2->type = NREDIR;
12127                         n2->nredir.linno = savelinno;
12128                         n2->nredir.n = n1;
12129                         n1 = n2;
12130                 }
12131                 n1->nredir.redirect = redir;
12132         }
12133         return n1;
12134 }
12135
12136 #if BASH_DOLLAR_SQUOTE
12137 static int
12138 decode_dollar_squote(void)
12139 {
12140         static const char C_escapes[] ALIGN1 = "nrbtfav""x\\01234567";
12141         int c, cnt;
12142         char *p;
12143         char buf[4];
12144
12145         c = pgetc();
12146         p = strchr(C_escapes, c);
12147         if (p) {
12148                 buf[0] = c;
12149                 p = buf;
12150                 cnt = 3;
12151                 if ((unsigned char)(c - '0') <= 7) { /* \ooo */
12152                         do {
12153                                 c = pgetc();
12154                                 *++p = c;
12155                         } while ((unsigned char)(c - '0') <= 7 && --cnt);
12156                         pungetc();
12157                 } else if (c == 'x') { /* \xHH */
12158                         do {
12159                                 c = pgetc();
12160                                 *++p = c;
12161                         } while (isxdigit(c) && --cnt);
12162                         pungetc();
12163                         if (cnt == 3) { /* \x but next char is "bad" */
12164                                 c = 'x';
12165                                 goto unrecognized;
12166                         }
12167                 } else { /* simple seq like \\ or \t */
12168                         p++;
12169                 }
12170                 *p = '\0';
12171                 p = buf;
12172                 c = bb_process_escape_sequence((void*)&p);
12173         } else { /* unrecognized "\z": print both chars unless ' or " */
12174                 if (c != '\'' && c != '"') {
12175  unrecognized:
12176                         c |= 0x100; /* "please encode \, then me" */
12177                 }
12178         }
12179         return c;
12180 }
12181 #endif
12182
12183 /* Used by expandstr to get here-doc like behaviour. */
12184 #define FAKEEOFMARK ((char*)(uintptr_t)1)
12185
12186 static ALWAYS_INLINE int
12187 realeofmark(const char *eofmark)
12188 {
12189         return eofmark && eofmark != FAKEEOFMARK;
12190 }
12191
12192 /*
12193  * If eofmark is NULL, read a word or a redirection symbol.  If eofmark
12194  * is not NULL, read a here document.  In the latter case, eofmark is the
12195  * word which marks the end of the document and striptabs is true if
12196  * leading tabs should be stripped from the document.  The argument c
12197  * is the first character of the input token or document.
12198  *
12199  * Because C does not have internal subroutines, I have simulated them
12200  * using goto's to implement the subroutine linkage.  The following macros
12201  * will run code that appears at the end of readtoken1.
12202  */
12203 #define CHECKEND()      {goto checkend; checkend_return:;}
12204 #define PARSEREDIR()    {goto parseredir; parseredir_return:;}
12205 #define PARSESUB()      {goto parsesub; parsesub_return:;}
12206 #define PARSEBACKQOLD() {oldstyle = 1; goto parsebackq; parsebackq_oldreturn:;}
12207 #define PARSEBACKQNEW() {oldstyle = 0; goto parsebackq; parsebackq_newreturn:;}
12208 #define PARSEARITH()    {goto parsearith; parsearith_return:;}
12209 static int
12210 readtoken1(int c, int syntax, char *eofmark, int striptabs)
12211 {
12212         /* NB: syntax parameter fits into smallint */
12213         /* c parameter is an unsigned char or PEOF or PEOA */
12214         char *out;
12215         size_t len;
12216         struct nodelist *bqlist;
12217         smallint quotef;
12218         smallint oldstyle;
12219         smallint pssyntax;   /* we are expanding a prompt string */
12220         IF_BASH_DOLLAR_SQUOTE(smallint bash_dollar_squote = 0;)
12221         /* syntax stack */
12222         struct synstack synbase = { };
12223         struct synstack *synstack = &synbase;
12224
12225 #if ENABLE_ASH_EXPAND_PRMT
12226         pssyntax = (syntax == PSSYNTAX);
12227         if (pssyntax)
12228                 syntax = DQSYNTAX;
12229 #else
12230         pssyntax = 0; /* constant */
12231 #endif
12232         synstack->syntax = syntax;
12233
12234         if (syntax == DQSYNTAX)
12235                 synstack->dblquote = 1;
12236         quotef = 0;
12237         bqlist = NULL;
12238
12239         STARTSTACKSTR(out);
12240  loop:
12241         /* For each line, until end of word */
12242         CHECKEND();     /* set c to PEOF if at end of here document */
12243         for (;;) {      /* until end of line or end of word */
12244                 CHECKSTRSPACE(4, out);  /* permit 4 calls to USTPUTC */
12245                 switch (SIT(c, synstack->syntax)) {
12246                 case CNL:       /* '\n' */
12247                         if (synstack->syntax == BASESYNTAX
12248                          && !synstack->varnest
12249                         ) {
12250                                 goto endword;   /* exit outer loop */
12251                         }
12252                         USTPUTC(c, out);
12253                         nlprompt();
12254                         c = pgetc_top(synstack);
12255                         goto loop;              /* continue outer loop */
12256                 case CWORD:
12257                         USTPUTC(c, out);
12258                         break;
12259                 case CCTL:
12260 #if BASH_DOLLAR_SQUOTE
12261                         if (c == '\\' && bash_dollar_squote) {
12262                                 c = decode_dollar_squote();
12263                                 if (c == '\0') {
12264                                         /* skip $'\000', $'\x00' (like bash) */
12265                                         break;
12266                                 }
12267                                 if (c & 0x100) {
12268                                         /* Unknown escape. Encode as '\z' */
12269                                         c = (unsigned char)c;
12270                                         if (eofmark == NULL || synstack->dblquote)
12271                                                 USTPUTC(CTLESC, out);
12272                                         USTPUTC('\\', out);
12273                                 }
12274                         }
12275 #endif
12276                         if (!eofmark || synstack->dblquote || synstack->varnest)
12277                                 USTPUTC(CTLESC, out);
12278                         USTPUTC(c, out);
12279                         break;
12280                 case CBACK:     /* backslash */
12281                         c = pgetc_without_PEOA();
12282                         if (c == PEOF) {
12283                                 USTPUTC(CTLESC, out);
12284                                 USTPUTC('\\', out);
12285                                 pungetc();
12286                         } else {
12287                                 if (pssyntax && c == '$') {
12288                                         USTPUTC(CTLESC, out);
12289                                         USTPUTC('\\', out);
12290                                 }
12291                                 /* Backslash is retained if we are in "str"
12292                                  * and next char isn't dquote-special.
12293                                  */
12294                                 if (synstack->dblquote
12295                                  && c != '\\'
12296                                  && c != '`'
12297                                  && c != '$'
12298                                  && (c != '"' || (eofmark != NULL && !synstack->varnest))
12299                                  && (c != '}' || !synstack->varnest)
12300                                 ) {
12301                                         USTPUTC(CTLESC, out); /* protect '\' from glob */
12302                                         USTPUTC('\\', out);
12303                                 }
12304                                 USTPUTC(CTLESC, out);
12305                                 USTPUTC(c, out);
12306                                 quotef = 1;
12307                         }
12308                         break;
12309                 case CSQUOTE:
12310                         synstack->syntax = SQSYNTAX;
12311  quotemark:
12312                         if (eofmark == NULL) {
12313                                 USTPUTC(CTLQUOTEMARK, out);
12314                         }
12315                         break;
12316                 case CDQUOTE:
12317                         synstack->syntax = DQSYNTAX;
12318                         synstack->dblquote = 1;
12319  toggledq:
12320                         if (synstack->varnest)
12321                                 synstack->innerdq ^= 1;
12322                         goto quotemark;
12323                 case CENDQUOTE:
12324                         IF_BASH_DOLLAR_SQUOTE(bash_dollar_squote = 0;)
12325                         if (eofmark != NULL && synstack->varnest == 0) {
12326                                 USTPUTC(c, out);
12327                                 break;
12328                         }
12329
12330                         if (synstack->dqvarnest == 0) {
12331                                 synstack->syntax = BASESYNTAX;
12332                                 synstack->dblquote = 0;
12333                         }
12334
12335                         quotef = 1;
12336
12337                         if (c == '"')
12338                                 goto toggledq;
12339
12340                         goto quotemark;
12341                 case CVAR:      /* '$' */
12342                         PARSESUB();             /* parse substitution */
12343                         break;
12344                 case CENDVAR:   /* '}' */
12345                         if (!synstack->innerdq && synstack->varnest > 0) {
12346                                 if (!--synstack->varnest && synstack->varpushed)
12347                                         synstack_pop(&synstack);
12348                                 else if (synstack->dqvarnest > 0)
12349                                         synstack->dqvarnest--;
12350                                 c = CTLENDVAR;
12351                         }
12352                         USTPUTC(c, out);
12353                         break;
12354 #if ENABLE_FEATURE_SH_MATH
12355                 case CLP:       /* '(' in arithmetic */
12356                         synstack->parenlevel++;
12357                         USTPUTC(c, out);
12358                         break;
12359                 case CRP:       /* ')' in arithmetic */
12360                         if (synstack->parenlevel > 0) {
12361                                 synstack->parenlevel--;
12362                         } else {
12363                                 if (pgetc_eatbnl() == ')') {
12364                                         c = CTLENDARI;
12365                                         synstack_pop(&synstack);
12366                                 } else {
12367                                         /*
12368                                          * unbalanced parens
12369                                          * (don't 2nd guess - no error)
12370                                          */
12371                                         pungetc();
12372                                 }
12373                         }
12374                         USTPUTC(c, out);
12375                         break;
12376 #endif
12377                 case CBQUOTE:   /* '`' */
12378                         if (checkkwd & CHKEOFMARK) {
12379                                 quotef = 1;
12380                                 USTPUTC('`', out);
12381                                 break;
12382                         }
12383
12384                         PARSEBACKQOLD();
12385                         break;
12386                 case CENDFILE:
12387                         goto endword;           /* exit outer loop */
12388                 case CIGN:
12389                         break;
12390                 default:
12391                         if (synstack->varnest == 0) {
12392 #if BASH_REDIR_OUTPUT
12393                                 if (c == '&') {
12394 //Can't call pgetc_eatbnl() here, this requires three-deep pungetc()
12395                                         if (pgetc() == '>')
12396                                                 c = 0x100 + '>'; /* flag &> */
12397                                         pungetc();
12398                                 }
12399 #endif
12400                                 goto endword;   /* exit outer loop */
12401                         }
12402                         IF_ASH_ALIAS(if (c != PEOA))
12403                                 USTPUTC(c, out);
12404                 }
12405                 c = pgetc_top(synstack);
12406         } /* for (;;) */
12407  endword:
12408
12409 #if ENABLE_FEATURE_SH_MATH
12410         if (synstack->syntax == ARISYNTAX)
12411                 raise_error_syntax("missing '))'");
12412 #endif
12413         if (synstack->syntax != BASESYNTAX && eofmark == NULL)
12414                 raise_error_syntax("unterminated quoted string");
12415         if (synstack->varnest != 0) {
12416                 /* { */
12417                 raise_error_syntax("missing '}'");
12418         }
12419         USTPUTC('\0', out);
12420         len = out - (char *)stackblock();
12421         out = stackblock();
12422         if (eofmark == NULL) {
12423                 if ((c == '>' || c == '<' IF_BASH_REDIR_OUTPUT( || c == 0x100 + '>'))
12424                  && quotef == 0
12425                 ) {
12426                         if (isdigit_str9(out)) {
12427                                 PARSEREDIR(); /* passed as params: out, c */
12428                                 lasttoken = TREDIR;
12429                                 return lasttoken;
12430                         }
12431                         /* else: non-number X seen, interpret it
12432                          * as "NNNX>file" = "NNNX >file" */
12433                 }
12434                 pungetc();
12435         }
12436         quoteflag = quotef;
12437         backquotelist = bqlist;
12438         grabstackblock(len);
12439         wordtext = out;
12440         lasttoken = TWORD;
12441         return lasttoken;
12442 /* end of readtoken routine */
12443
12444 /*
12445  * Check to see whether we are at the end of the here document.  When this
12446  * is called, c is set to the first character of the next input line.  If
12447  * we are at the end of the here document, this routine sets the c to PEOF.
12448  */
12449 checkend: {
12450         if (realeofmark(eofmark)) {
12451                 int markloc;
12452                 char *p;
12453
12454 #if ENABLE_ASH_ALIAS
12455                 if (c == PEOA)
12456                         c = pgetc_without_PEOA();
12457 #endif
12458                 if (striptabs) {
12459                         while (c == '\t') {
12460                                 c = pgetc_without_PEOA();
12461                         }
12462                 }
12463
12464                 markloc = out - (char *)stackblock();
12465                 for (p = eofmark; STPUTC(c, out), *p; p++) {
12466                         if (c != *p)
12467                                 goto more_heredoc;
12468                         /* FIXME: fails for backslash-newlined terminator:
12469                          * cat <<EOF
12470                          * ...
12471                          * EO\
12472                          * F
12473                          * (see heredoc_bkslash_newline2.tests)
12474                          */
12475                         c = pgetc_without_PEOA();
12476                 }
12477
12478                 if (c == '\n' || c == PEOF) {
12479                         c = PEOF;
12480                         g_parsefile->linno++;
12481                         needprompt = doprompt;
12482                 } else {
12483                         int len_here;
12484
12485  more_heredoc:
12486                         p = (char *)stackblock() + markloc + 1;
12487                         len_here = out - p;
12488
12489                         if (len_here) {
12490                                 len_here -= (c >= PEOF);
12491                                 c = p[-1];
12492
12493                                 if (len_here) {
12494                                         char *str;
12495
12496                                         str = alloca(len_here + 1);
12497                                         *(char *)mempcpy(str, p, len_here) = '\0';
12498
12499                                         pushstring(str, NULL);
12500                                 }
12501                         }
12502                 }
12503
12504                 STADJUST((char *)stackblock() + markloc - out, out);
12505         }
12506         goto checkend_return;
12507 }
12508
12509 /*
12510  * Parse a redirection operator.  The variable "out" points to a string
12511  * specifying the fd to be redirected.  The variable "c" contains the
12512  * first character of the redirection operator.
12513  */
12514 parseredir: {
12515         /* out is already checked to be a valid number or "" */
12516         int fd = (*out == '\0' ? -1 : atoi(out));
12517         union node *np;
12518
12519         np = stzalloc(sizeof(struct nfile));
12520         if (c == '>') {
12521                 np->nfile.fd = 1;
12522                 c = pgetc_eatbnl();
12523                 if (c == '>')
12524                         np->type = NAPPEND;
12525                 else if (c == '|')
12526                         np->type = NCLOBBER;
12527                 else if (c == '&')
12528                         np->type = NTOFD;
12529                         /* it also can be NTO2 (>&file), but we can't figure it out yet */
12530                 else {
12531                         np->type = NTO;
12532                         pungetc();
12533                 }
12534         }
12535 #if BASH_REDIR_OUTPUT
12536         else if (c == 0x100 + '>') { /* this flags &> redirection */
12537                 np->nfile.fd = 1;
12538                 pgetc(); /* this is '>', no need to check */
12539                 np->type = NTO2;
12540         }
12541 #endif
12542         else { /* c == '<' */
12543                 /*np->nfile.fd = 0; - stzalloc did it */
12544                 c = pgetc_eatbnl();
12545                 switch (c) {
12546                 case '<':
12547                         if (sizeof(struct nfile) != sizeof(struct nhere)) {
12548                                 np = stzalloc(sizeof(struct nhere));
12549                                 /*np->nfile.fd = 0; - stzalloc did it */
12550                         }
12551                         np->type = NHERE;
12552                         heredoc = stzalloc(sizeof(struct heredoc));
12553                         heredoc->here = np;
12554                         c = pgetc_eatbnl();
12555                         if (c == '-') {
12556                                 heredoc->striptabs = 1;
12557                         } else {
12558                                 /*heredoc->striptabs = 0; - stzalloc did it */
12559                                 pungetc();
12560                         }
12561                         break;
12562
12563                 case '&':
12564                         np->type = NFROMFD;
12565                         break;
12566
12567                 case '>':
12568                         np->type = NFROMTO;
12569                         break;
12570
12571                 default:
12572                         np->type = NFROM;
12573                         pungetc();
12574                         break;
12575                 }
12576         }
12577         if (fd >= 0)
12578                 np->nfile.fd = fd;
12579         redirnode = np;
12580         goto parseredir_return;
12581 }
12582
12583 /*
12584  * Parse a substitution.  At this point, we have read the dollar sign
12585  * and nothing else.
12586  */
12587
12588 /* is_special(c) evaluates to 1 for c in "!#$*-0123456789?@"; 0 otherwise
12589  * (assuming ascii char codes, as the original implementation did) */
12590 #define is_special(c) \
12591         (((unsigned)(c) - 33 < 32) \
12592                         && ((0xc1ff920dU >> ((unsigned)(c) - 33)) & 1))
12593 parsesub: {
12594         unsigned char subtype;
12595         int typeloc;
12596
12597         c = pgetc_eatbnl();
12598         if ((checkkwd & CHKEOFMARK)
12599          || c > 255 /* PEOA or PEOF */
12600          || (c != '(' && c != '{' && !is_name(c) && !is_special(c))
12601         ) {
12602 #if BASH_DOLLAR_SQUOTE
12603                 if (synstack->syntax != DQSYNTAX && c == '\'')
12604                         bash_dollar_squote = 1;
12605                 else
12606 #endif
12607                         USTPUTC('$', out);
12608                 pungetc();
12609         } else if (c == '(') {
12610                 /* $(command) or $((arith)) */
12611                 if (pgetc_eatbnl() == '(') {
12612 #if ENABLE_FEATURE_SH_MATH
12613                         PARSEARITH();
12614 #else
12615                         raise_error_syntax("support for $((arith)) is disabled");
12616 #endif
12617                 } else {
12618                         pungetc();
12619                         PARSEBACKQNEW();
12620                 }
12621         } else {
12622                 /* $VAR, $<specialchar>, ${...}, or PEOA/PEOF */
12623                 smalluint newsyn = synstack->syntax;
12624
12625                 USTPUTC(CTLVAR, out);
12626                 typeloc = out - (char *)stackblock();
12627                 STADJUST(1, out);
12628                 subtype = VSNORMAL;
12629                 if (c == '{') {
12630                         c = pgetc_eatbnl();
12631                         subtype = 0;
12632                 }
12633  varname:
12634                 if (is_name(c)) {
12635                         /* $[{[#]]NAME[}] */
12636                         do {
12637                                 STPUTC(c, out);
12638                                 c = pgetc_eatbnl();
12639                         } while (is_in_name(c));
12640                 } else if (isdigit(c)) {
12641                         /* $[{[#]]NUM[}] */
12642                         do {
12643                                 STPUTC(c, out);
12644                                 c = pgetc_eatbnl();
12645                         } while (!subtype && isdigit(c));
12646                 } else if (c != '}') {
12647                         /* $[{[#]]<specialchar>[}] */
12648                         int cc = c;
12649
12650                         c = pgetc_eatbnl();
12651                         if (!subtype && cc == '#') {
12652                                 subtype = VSLENGTH;
12653                                 if (c == '_' || isalnum(c))
12654                                         goto varname;
12655                                 cc = c;
12656                                 c = pgetc_eatbnl();
12657                                 if (cc == '}' || c != '}') {
12658                                         pungetc();
12659                                         subtype = 0;
12660                                         c = cc;
12661                                         cc = '#';
12662                                 }
12663                         }
12664
12665                         if (!is_special(cc)) {
12666                                 if (subtype == VSLENGTH)
12667                                         subtype = 0;
12668                                 goto badsub;
12669                         }
12670
12671                         USTPUTC(cc, out);
12672                 } else
12673                         goto badsub;
12674
12675                 if (c != '}' && subtype == VSLENGTH) {
12676                         /* ${#VAR didn't end with } */
12677                         goto badsub;
12678                 }
12679
12680                 if (subtype == 0) {
12681                         static const char types[] ALIGN1 = "}-+?=";
12682                         /* ${VAR...} but not $VAR or ${#VAR} */
12683                         /* c == first char after VAR */
12684                         int cc = c;
12685
12686                         switch (c) {
12687                         case ':':
12688                                 c = pgetc_eatbnl();
12689 #if BASH_SUBSTR
12690                                 /* This check is only needed to not misinterpret
12691                                  * ${VAR:-WORD}, ${VAR:+WORD}, ${VAR:=WORD}, ${VAR:?WORD}
12692                                  * constructs.
12693                                  */
12694                                 if (!strchr(types, c)) {
12695                                         subtype = VSSUBSTR;
12696                                         pungetc();
12697                                         break; /* "goto badsub" is bigger (!) */
12698                                 }
12699 #endif
12700                                 subtype = VSNUL;
12701                                 /*FALLTHROUGH*/
12702                         default: {
12703                                 const char *p = strchr(types, c);
12704                                 if (p == NULL)
12705                                         break;
12706                                 subtype |= p - types + VSNORMAL;
12707                                 break;
12708                         }
12709                         case '%':
12710                         case '#':
12711                                 subtype = (c == '#' ? VSTRIMLEFT : VSTRIMRIGHT);
12712                                 c = pgetc_eatbnl();
12713                                 if (c == cc)
12714                                         subtype++;
12715                                 else
12716                                         pungetc();
12717
12718                                 newsyn = BASESYNTAX;
12719                                 break;
12720 #if BASH_PATTERN_SUBST
12721                         case '/':
12722                                 /* ${v/[/]pattern/repl} */
12723 //TODO: encode pattern and repl separately.
12724 // Currently cases like: v=1;echo ${v/$((1/1))/ONE}
12725 // are broken (should print "ONE")
12726                                 subtype = VSREPLACE;
12727                                 newsyn = BASESYNTAX;
12728                                 c = pgetc_eatbnl();
12729                                 if (c != '/')
12730                                         goto badsub;
12731                                 subtype++; /* VSREPLACEALL */
12732                                 break;
12733 #endif
12734                         }
12735                 } else {
12736  badsub:
12737                         pungetc();
12738                 }
12739
12740                 if (newsyn == ARISYNTAX)
12741                         newsyn = DQSYNTAX;
12742
12743                 if ((newsyn != synstack->syntax || synstack->innerdq)
12744                  && subtype != VSNORMAL
12745                 ) {
12746                         synstack_push(&synstack,
12747                                 synstack->prev ?: alloca(sizeof(*synstack)),
12748                                 newsyn);
12749
12750                         synstack->varpushed = 1;
12751                         synstack->dblquote = newsyn != BASESYNTAX;
12752                 }
12753
12754                 ((unsigned char *)stackblock())[typeloc] = subtype;
12755                 if (subtype != VSNORMAL) {
12756                         synstack->varnest++;
12757                         if (synstack->dblquote)
12758                                 synstack->dqvarnest++;
12759                 }
12760                 STPUTC('=', out);
12761         }
12762         goto parsesub_return;
12763 }
12764
12765 /*
12766  * Called to parse command substitutions.  Newstyle is set if the command
12767  * is enclosed inside $(...); nlpp is a pointer to the head of the linked
12768  * list of commands (passed by reference), and savelen is the number of
12769  * characters on the top of the stack which must be preserved.
12770  */
12771 parsebackq: {
12772         struct nodelist **nlpp;
12773         union node *n;
12774         char *str;
12775         size_t savelen;
12776         struct heredoc *saveheredoclist;
12777         smallint saveprompt = 0;
12778
12779         str = NULL;
12780         savelen = out - (char *)stackblock();
12781         if (savelen > 0) {
12782                 /*
12783                  * FIXME: this can allocate very large block on stack and SEGV.
12784                  * Example:
12785                  * echo "..<100kbytes>..`true` $(true) `true` ..."
12786                  * allocates 100kb for every command subst. With about
12787                  * a hundred command substitutions stack overflows.
12788                  * With larger prepended string, SEGV happens sooner.
12789                  */
12790                 str = alloca(savelen);
12791                 memcpy(str, stackblock(), savelen);
12792         }
12793
12794         if (oldstyle) {
12795                 /* We must read until the closing backquote, giving special
12796                  * treatment to some slashes, and then push the string and
12797                  * reread it as input, interpreting it normally.
12798                  */
12799                 char *pout;
12800                 size_t psavelen;
12801                 char *pstr;
12802
12803                 STARTSTACKSTR(pout);
12804                 for (;;) {
12805                         int pc;
12806
12807                         setprompt_if(needprompt, 2);
12808                         pc = pgetc_eatbnl();
12809                         switch (pc) {
12810                         case '`':
12811                                 goto done;
12812
12813                         case '\\':
12814                                 pc = pgetc(); /* or pgetc_eatbnl()? why (example)? */
12815                                 if (pc != '\\' && pc != '`' && pc != '$'
12816                                  && (!synstack->dblquote || pc != '"')
12817                                 ) {
12818                                         STPUTC('\\', pout);
12819                                 }
12820                                 if (pc <= 255 /* not PEOA or PEOF */) {
12821                                         break;
12822                                 }
12823                                 /* fall through */
12824
12825                         case PEOF:
12826                         IF_ASH_ALIAS(case PEOA:)
12827                                 raise_error_syntax("EOF in backquote substitution");
12828
12829                         case '\n':
12830                                 nlnoprompt();
12831                                 break;
12832
12833                         default:
12834                                 break;
12835                         }
12836                         STPUTC(pc, pout);
12837                 }
12838  done:
12839                 STPUTC('\0', pout);
12840                 psavelen = pout - (char *)stackblock();
12841                 if (psavelen > 0) {
12842                         pstr = grabstackstr(pout);
12843                         setinputstring(pstr);
12844                 }
12845         }
12846         nlpp = &bqlist;
12847         while (*nlpp)
12848                 nlpp = &(*nlpp)->next;
12849         *nlpp = stzalloc(sizeof(**nlpp));
12850         /* (*nlpp)->next = NULL; - stzalloc did it */
12851
12852         saveheredoclist = heredoclist;
12853         heredoclist = NULL;
12854
12855         if (oldstyle) {
12856                 saveprompt = doprompt;
12857                 doprompt = 0;
12858         }
12859
12860         n = list(2);
12861
12862         if (oldstyle)
12863                 doprompt = saveprompt;
12864         else {
12865                 if (readtoken() != TRP)
12866                         raise_error_unexpected_syntax(TRP);
12867                 setinputstring(nullstr);
12868                 parseheredoc();
12869         }
12870
12871         heredoclist = saveheredoclist;
12872
12873         (*nlpp)->n = n;
12874         /* Start reading from old file again. */
12875         popfile();
12876         /* Ignore any pushed back tokens left from the backquote parsing. */
12877         if (oldstyle)
12878                 tokpushback = 0;
12879         out = growstackto(savelen + 1);
12880         if (str) {
12881                 memcpy(out, str, savelen);
12882                 STADJUST(savelen, out);
12883         }
12884         USTPUTC(CTLBACKQ, out);
12885         if (oldstyle)
12886                 goto parsebackq_oldreturn;
12887         goto parsebackq_newreturn;
12888 }
12889
12890 #if ENABLE_FEATURE_SH_MATH
12891 /*
12892  * Parse an arithmetic expansion (indicate start of one and set state)
12893  */
12894 parsearith: {
12895
12896         synstack_push(&synstack,
12897                         synstack->prev ?: alloca(sizeof(*synstack)),
12898                         ARISYNTAX);
12899         synstack->dblquote = 1;
12900         USTPUTC(CTLARI, out);
12901         goto parsearith_return;
12902 }
12903 #endif
12904 } /* end of readtoken */
12905
12906 /*
12907  * Read the next input token.
12908  * If the token is a word, we set backquotelist to the list of cmds in
12909  *      backquotes.  We set quoteflag to true if any part of the word was
12910  *      quoted.
12911  * If the token is TREDIR, then we set redirnode to a structure containing
12912  *      the redirection.
12913  *
12914  * [Change comment:  here documents and internal procedures]
12915  * [Readtoken shouldn't have any arguments.  Perhaps we should make the
12916  *  word parsing code into a separate routine.  In this case, readtoken
12917  *  doesn't need to have any internal procedures, but parseword does.
12918  *  We could also make parseoperator in essence the main routine, and
12919  *  have parseword (readtoken1?) handle both words and redirection.]
12920  */
12921 #define NEW_xxreadtoken
12922 #ifdef NEW_xxreadtoken
12923 /* singles must be first! */
12924 static const char xxreadtoken_chars[7] ALIGN1 = {
12925         '\n', '(', ')', /* singles */
12926         '&', '|', ';',  /* doubles */
12927         0
12928 };
12929
12930 #define xxreadtoken_singles 3
12931 #define xxreadtoken_doubles 3
12932
12933 static const char xxreadtoken_tokens[] ALIGN1 = {
12934         TNL, TLP, TRP,          /* only single occurrence allowed */
12935         TBACKGND, TPIPE, TSEMI, /* if single occurrence */
12936         TEOF,                   /* corresponds to trailing nul */
12937         TAND, TOR, TENDCASE     /* if double occurrence */
12938 };
12939
12940 static int
12941 xxreadtoken(void)
12942 {
12943         int c;
12944
12945         if (tokpushback) {
12946                 tokpushback = 0;
12947                 return lasttoken;
12948         }
12949         setprompt_if(needprompt, 2);
12950         for (;;) {                      /* until token or start of word found */
12951                 c = pgetc_eatbnl();
12952                 if (c == ' ' || c == '\t' IF_ASH_ALIAS( || c == PEOA))
12953                         continue;
12954
12955                 if (c == '#') {
12956                         while ((c = pgetc()) != '\n' && c != PEOF)
12957                                 continue;
12958                         pungetc();
12959                 } else if (c == '\\') {
12960                         break; /* return readtoken1(...) */
12961                 } else {
12962                         const char *p;
12963
12964                         p = xxreadtoken_chars + sizeof(xxreadtoken_chars) - 1;
12965                         if (c != PEOF) {
12966                                 if (c == '\n') {
12967                                         nlnoprompt();
12968                                 }
12969
12970                                 p = strchr(xxreadtoken_chars, c);
12971                                 if (p == NULL)
12972                                         break; /* return readtoken1(...) */
12973
12974                                 if ((int)(p - xxreadtoken_chars) >= xxreadtoken_singles) {
12975                                         int cc = pgetc_eatbnl();
12976                                         if (cc == c) {    /* double occurrence? */
12977                                                 p += xxreadtoken_doubles + 1;
12978                                         } else {
12979                                                 pungetc();
12980 #if BASH_REDIR_OUTPUT
12981                                                 if (c == '&' && cc == '>') /* &> */
12982                                                         break; /* return readtoken1(...) */
12983 #endif
12984                                         }
12985                                 }
12986                         }
12987                         lasttoken = xxreadtoken_tokens[p - xxreadtoken_chars];
12988                         return lasttoken;
12989                 }
12990         } /* for (;;) */
12991
12992         return readtoken1(c, BASESYNTAX, (char *) NULL, 0);
12993 }
12994 #else /* old xxreadtoken */
12995 #define RETURN(token)   return lasttoken = token
12996 static int
12997 xxreadtoken(void)
12998 {
12999         int c;
13000
13001         if (tokpushback) {
13002                 tokpushback = 0;
13003                 return lasttoken;
13004         }
13005         setprompt_if(needprompt, 2);
13006         for (;;) {      /* until token or start of word found */
13007                 c = pgetc_eatbnl();
13008                 switch (c) {
13009                 case ' ': case '\t':
13010                 IF_ASH_ALIAS(case PEOA:)
13011                         continue;
13012                 case '#':
13013                         while ((c = pgetc()) != '\n' && c != PEOF)
13014                                 continue;
13015                         pungetc();
13016                         continue;
13017                 case '\n':
13018                         nlnoprompt();
13019                         RETURN(TNL);
13020                 case PEOF:
13021                         RETURN(TEOF);
13022                 case '&':
13023                         if (pgetc_eatbnl() == '&')
13024                                 RETURN(TAND);
13025                         pungetc();
13026                         RETURN(TBACKGND);
13027                 case '|':
13028                         if (pgetc_eatbnl() == '|')
13029                                 RETURN(TOR);
13030                         pungetc();
13031                         RETURN(TPIPE);
13032                 case ';':
13033                         if (pgetc_eatbnl() == ';')
13034                                 RETURN(TENDCASE);
13035                         pungetc();
13036                         RETURN(TSEMI);
13037                 case '(':
13038                         RETURN(TLP);
13039                 case ')':
13040                         RETURN(TRP);
13041                 }
13042                 break;
13043         }
13044         return readtoken1(c, BASESYNTAX, (char *)NULL, 0);
13045 #undef RETURN
13046 }
13047 #endif /* old xxreadtoken */
13048
13049 static int
13050 readtoken(void)
13051 {
13052         int t;
13053         int kwd = checkkwd;
13054 #if DEBUG
13055         smallint alreadyseen = tokpushback;
13056 #endif
13057
13058 #if ENABLE_ASH_ALIAS
13059  top:
13060 #endif
13061
13062         t = xxreadtoken();
13063
13064         /*
13065          * eat newlines
13066          */
13067         if (kwd & CHKNL) {
13068                 while (t == TNL) {
13069                         parseheredoc();
13070                         t = xxreadtoken();
13071                 }
13072         }
13073
13074         if (t != TWORD || quoteflag) {
13075                 goto out;
13076         }
13077
13078         /*
13079          * check for keywords
13080          */
13081         if (kwd & CHKKWD) {
13082                 const char *const *pp;
13083
13084                 pp = findkwd(wordtext);
13085                 if (pp) {
13086                         lasttoken = t = pp - tokname_array;
13087                         TRACE(("keyword '%s' recognized\n", tokname_array[t]));
13088                         goto out;
13089                 }
13090         }
13091
13092         if (checkkwd & CHKALIAS) {
13093 #if ENABLE_ASH_ALIAS
13094                 struct alias *ap;
13095                 ap = lookupalias(wordtext, 1);
13096                 if (ap != NULL) {
13097                         if (*ap->val) {
13098                                 pushstring(ap->val, ap);
13099                         }
13100                         goto top;
13101                 }
13102 #endif
13103         }
13104  out:
13105         checkkwd = 0;
13106 #if DEBUG
13107         if (!alreadyseen)
13108                 TRACE(("token '%s' %s\n", tokname_array[t], t == TWORD ? wordtext : ""));
13109         else
13110                 TRACE(("reread token '%s' %s\n", tokname_array[t], t == TWORD ? wordtext : ""));
13111 #endif
13112         return t;
13113 }
13114
13115 static int
13116 peektoken(void)
13117 {
13118         int t;
13119
13120         t = readtoken();
13121         tokpushback = 1;
13122         return t;
13123 }
13124
13125 /*
13126  * Read and parse a command.  Returns NODE_EOF on end of file.
13127  * (NULL is a valid parse tree indicating a blank line.)
13128  */
13129 static union node *
13130 parsecmd(int interact)
13131 {
13132         tokpushback = 0;
13133         checkkwd = 0;
13134         heredoclist = 0;
13135         doprompt = interact;
13136         setprompt_if(doprompt, doprompt);
13137         needprompt = 0;
13138         return list(1);
13139 }
13140
13141 /*
13142  * Input any here documents.
13143  */
13144 static void
13145 parseheredoc(void)
13146 {
13147         struct heredoc *here;
13148         union node *n;
13149
13150         here = heredoclist;
13151         heredoclist = NULL;
13152
13153         while (here) {
13154                 tokpushback = 0;
13155                 setprompt_if(needprompt, 2);
13156                 if (here->here->type == NHERE)
13157                         readtoken1(pgetc(), SQSYNTAX, here->eofmark, here->striptabs);
13158                 else
13159                         readtoken1(pgetc_eatbnl(), DQSYNTAX, here->eofmark, here->striptabs);
13160                 n = stzalloc(sizeof(struct narg));
13161                 n->narg.type = NARG;
13162                 /*n->narg.next = NULL; - stzalloc did it */
13163                 n->narg.text = wordtext;
13164                 n->narg.backquote = backquotelist;
13165                 here->here->nhere.doc = n;
13166                 here = here->next;
13167         }
13168 }
13169
13170
13171 static const char *
13172 expandstr(const char *ps, int syntax_type)
13173 {
13174         union node n;
13175         int saveprompt;
13176         struct parsefile *file_stop = g_parsefile;
13177         volatile int saveint;
13178         struct jmploc *volatile savehandler = exception_handler;
13179         struct jmploc jmploc;
13180         const char *volatile result;
13181         int err;
13182
13183         /* XXX Fix (char *) cast. */
13184         setinputstring((char *)ps);
13185
13186         saveprompt = doprompt;
13187         doprompt = 0;
13188         result = ps;
13189
13190         SAVE_INT(saveint);
13191         err = setjmp(jmploc.loc);
13192         if (err)
13193                 goto out;
13194
13195         /* readtoken1() might die horribly.
13196          * Try a prompt with syntactically wrong command:
13197          * PS1='$(date "+%H:%M:%S) > '
13198          */
13199         exception_handler = &jmploc;
13200         readtoken1(pgetc(), syntax_type, FAKEEOFMARK, 0);
13201
13202         n.narg.type = NARG;
13203         n.narg.next = NULL;
13204         n.narg.text = wordtext;
13205         n.narg.backquote = backquotelist;
13206
13207         /* expandarg() might fail too:
13208          * PS1='$((123+))'
13209          */
13210         expandarg(&n, NULL, EXP_QUOTED);
13211         result = stackblock();
13212
13213 out:
13214         exception_handler = savehandler;
13215         if (err && exception_type != EXERROR)
13216                 longjmp(exception_handler->loc, 1);
13217         RESTORE_INT(saveint);
13218
13219         doprompt = saveprompt;
13220         /* Try: PS1='`xxx(`' */
13221         unwindfiles(file_stop);
13222
13223         return result;
13224 }
13225
13226 static inline int
13227 parser_eof(void)
13228 {
13229         return tokpushback && lasttoken == TEOF;
13230 }
13231
13232 /*
13233  * Execute a command or commands contained in a string.
13234  */
13235 static int
13236 evalstring(char *s, int flags)
13237 {
13238         struct jmploc *volatile savehandler;
13239         struct jmploc jmploc;
13240         int ex;
13241
13242         union node *n;
13243         struct stackmark smark;
13244         int status;
13245
13246         s = sstrdup(s);
13247         setinputstring(s);
13248         setstackmark(&smark);
13249
13250         status = 0;
13251         /* On exception inside execution loop, we must popfile().
13252          * Try interactively:
13253          *      readonly a=a
13254          *      command eval "a=b"  # throws "is read only" error
13255          * "command BLTIN" is not supposed to abort (even in non-interactive use).
13256          * But if we skip popfile(), we hit EOF in eval's string, and exit.
13257          */
13258         savehandler = exception_handler;
13259         ex = setjmp(jmploc.loc);
13260         if (ex)
13261                 goto out;
13262         exception_handler = &jmploc;
13263
13264         while ((n = parsecmd(0)) != NODE_EOF) {
13265                 int i;
13266
13267                 i = evaltree(n, flags & ~(parser_eof() ? 0 : EV_EXIT));
13268                 if (n)
13269                         status = i;
13270                 popstackmark(&smark);
13271                 if (evalskip)
13272                         break;
13273         }
13274  out:
13275         popstackmark(&smark);
13276         popfile();
13277         stunalloc(s);
13278
13279         exception_handler = savehandler;
13280         if (ex)
13281                 longjmp(exception_handler->loc, ex);
13282
13283         return status;
13284 }
13285
13286 /*
13287  * The eval command.
13288  */
13289 static int FAST_FUNC
13290 evalcmd(int argc UNUSED_PARAM, char **argv, int flags)
13291 {
13292         char *p;
13293         char *concat;
13294
13295         if (argv[1]) {
13296                 p = argv[1];
13297                 argv += 2;
13298                 if (argv[0]) {
13299                         STARTSTACKSTR(concat);
13300                         for (;;) {
13301                                 concat = stack_putstr(p, concat);
13302                                 p = *argv++;
13303                                 if (p == NULL)
13304                                         break;
13305                                 STPUTC(' ', concat);
13306                         }
13307                         STPUTC('\0', concat);
13308                         p = grabstackstr(concat);
13309                 }
13310                 return evalstring(p, flags & EV_TESTED);
13311         }
13312         return 0;
13313 }
13314
13315 /*
13316  * Read and execute commands.
13317  * "Top" is nonzero for the top level command loop;
13318  * it turns on prompting if the shell is interactive.
13319  */
13320 static int
13321 cmdloop(int top)
13322 {
13323         union node *n;
13324         struct stackmark smark;
13325         int inter;
13326         int status = 0;
13327         int numeof = 0;
13328
13329         TRACE(("cmdloop(%d) called\n", top));
13330         for (;;) {
13331                 int skip;
13332
13333                 setstackmark(&smark);
13334 #if JOBS
13335                 if (doing_jobctl)
13336                         showjobs(SHOW_CHANGED|SHOW_STDERR);
13337 #endif
13338                 inter = 0;
13339                 if (iflag && top) {
13340                         inter++;
13341                         chkmail();
13342                 }
13343                 n = parsecmd(inter);
13344 #if DEBUG
13345                 if (DEBUG > 2 && debug && (n != NODE_EOF))
13346                         showtree(n);
13347 #endif
13348                 if (n == NODE_EOF) {
13349                         if (!top || numeof >= 50)
13350                                 break;
13351                         if (!stoppedjobs()) {
13352                                 if (!Iflag) {
13353                                         if (iflag) {
13354                                                 newline_and_flush(stderr);
13355                                         }
13356                                         break;
13357                                 }
13358                                 out2str("\nUse \"exit\" to leave shell.\n");
13359                         }
13360                         numeof++;
13361                 } else if (nflag == 0) {
13362                         int i;
13363
13364                         /* job_warning can only be 2,1,0. Here 2->1, 1/0->0 */
13365                         job_warning >>= 1;
13366                         numeof = 0;
13367                         i = evaltree(n, 0);
13368                         if (n)
13369                                 status = i;
13370                 }
13371                 popstackmark(&smark);
13372                 skip = evalskip;
13373
13374                 if (skip) {
13375                         evalskip &= ~SKIPFUNC;
13376                         break;
13377                 }
13378         }
13379         return status;
13380 }
13381
13382 /*
13383  * Take commands from a file.  To be compatible we should do a path
13384  * search for the file, which is necessary to find sub-commands.
13385  */
13386 static char *
13387 find_dot_file(char *basename)
13388 {
13389         char *fullname;
13390         const char *path = pathval();
13391         struct stat statb;
13392         int len;
13393
13394         /* don't try this for absolute or relative paths */
13395         if (strchr(basename, '/'))
13396                 return basename;
13397
13398         while ((len = padvance(&path, basename)) >= 0) {
13399                 fullname = stackblock();
13400                 if ((!pathopt || *pathopt == 'f')
13401                  && !stat(fullname, &statb) && S_ISREG(statb.st_mode)
13402                 ) {
13403                         /* This will be freed by the caller. */
13404                         return stalloc(len);
13405                 }
13406         }
13407         /* not found in PATH */
13408
13409 #if ENABLE_ASH_BASH_SOURCE_CURDIR
13410         return basename;
13411 #else
13412         ash_msg_and_raise_error("%s: not found", basename);
13413         /* NOTREACHED */
13414 #endif
13415 }
13416
13417 static int FAST_FUNC
13418 dotcmd(int argc_ UNUSED_PARAM, char **argv_ UNUSED_PARAM)
13419 {
13420         /* "false; . empty_file; echo $?" should print 0, not 1: */
13421         int status = 0;
13422         char *fullname;
13423         char **argv;
13424         char *args_need_save;
13425         volatile struct shparam saveparam;
13426
13427 //???
13428 //      struct strlist *sp;
13429 //      for (sp = cmdenviron; sp; sp = sp->next)
13430 //              setvareq(ckstrdup(sp->text), VSTRFIXED | VTEXTFIXED);
13431
13432         nextopt(nullstr); /* handle possible "--" */
13433         argv = argptr;
13434
13435         if (!argv[0]) {
13436                 /* bash says: "bash: .: filename argument required" */
13437                 return 2; /* bash compat */
13438         }
13439
13440         /* This aborts if file isn't found, which is POSIXly correct.
13441          * bash returns exitcode 1 instead.
13442          */
13443         fullname = find_dot_file(argv[0]);
13444         argv++;
13445         args_need_save = argv[0];
13446         if (args_need_save) { /* ". FILE ARGS", and ARGS are not empty */
13447                 int argc;
13448                 saveparam = shellparam;
13449                 shellparam.malloced = 0;
13450                 argc = 1;
13451                 while (argv[argc])
13452                         argc++;
13453                 shellparam.nparam = argc;
13454                 shellparam.p = argv;
13455         };
13456
13457         /* This aborts if file can't be opened, which is POSIXly correct.
13458          * bash returns exitcode 1 instead.
13459          */
13460         setinputfile(fullname, INPUT_PUSH_FILE);
13461         commandname = fullname;
13462         status = cmdloop(0);
13463         popfile();
13464
13465         if (args_need_save) {
13466                 freeparam(&shellparam);
13467                 shellparam = saveparam;
13468         };
13469
13470         return status;
13471 }
13472
13473 static int FAST_FUNC
13474 exitcmd(int argc UNUSED_PARAM, char **argv)
13475 {
13476         if (stoppedjobs())
13477                 return 0;
13478
13479         if (argv[1])
13480                 savestatus = number(argv[1]);
13481
13482         raise_exception(EXEXIT);
13483         /* NOTREACHED */
13484 }
13485
13486 /*
13487  * Read a file containing shell functions.
13488  */
13489 static void
13490 readcmdfile(char *name)
13491 {
13492         setinputfile(name, INPUT_PUSH_FILE);
13493         cmdloop(0);
13494         popfile();
13495 }
13496
13497
13498 /* ============ find_command inplementation */
13499
13500 /*
13501  * Resolve a command name.  If you change this routine, you may have to
13502  * change the shellexec routine as well.
13503  */
13504 static void
13505 find_command(char *name, struct cmdentry *entry, int act, const char *path)
13506 {
13507         struct tblentry *cmdp;
13508         int idx;
13509         int prev;
13510         char *fullname;
13511         struct stat statb;
13512         int e;
13513         int updatetbl;
13514         struct builtincmd *bcmd;
13515         int len;
13516
13517         /* If name contains a slash, don't use PATH or hash table */
13518         if (strchr(name, '/') != NULL) {
13519                 entry->u.index = -1;
13520                 if (act & DO_ABS) {
13521                         while (stat(name, &statb) < 0) {
13522 #ifdef SYSV
13523                                 if (errno == EINTR)
13524                                         continue;
13525 #endif
13526                                 entry->cmdtype = CMDUNKNOWN;
13527                                 return;
13528                         }
13529                 }
13530                 entry->cmdtype = CMDNORMAL;
13531                 return;
13532         }
13533
13534 /* #if ENABLE_FEATURE_SH_STANDALONE... moved after builtin check */
13535
13536         updatetbl = (path == pathval());
13537         if (!updatetbl)
13538                 act |= DO_ALTPATH;
13539
13540         /* If name is in the table, check answer will be ok */
13541         cmdp = cmdlookup(name, 0);
13542         if (cmdp != NULL) {
13543                 int bit;
13544
13545                 switch (cmdp->cmdtype) {
13546                 default:
13547 #if DEBUG
13548                         abort();
13549 #endif
13550                 case CMDNORMAL:
13551                         bit = DO_ALTPATH | DO_REGBLTIN;
13552                         break;
13553                 case CMDFUNCTION:
13554                         bit = DO_NOFUNC;
13555                         break;
13556                 case CMDBUILTIN:
13557                         bit = IS_BUILTIN_REGULAR(cmdp->param.cmd) ? 0 : DO_REGBLTIN;
13558                         break;
13559                 }
13560                 if (act & bit) {
13561                         if (act & bit & DO_REGBLTIN)
13562                                 goto fail;
13563
13564                         updatetbl = 0;
13565                         cmdp = NULL;
13566                 } else if (cmdp->rehash == 0)
13567                         /* if not invalidated by cd, we're done */
13568                         goto success;
13569         }
13570
13571         /* If %builtin not in path, check for builtin next */
13572         bcmd = find_builtin(name);
13573         if (bcmd) {
13574                 if (IS_BUILTIN_REGULAR(bcmd))
13575                         goto builtin_success;
13576                 if (act & DO_ALTPATH)
13577                         goto builtin_success;
13578                 if (builtinloc <= 0)
13579                         goto builtin_success;
13580         }
13581
13582         if (act & DO_REGBLTIN)
13583                 goto fail;
13584
13585 #if ENABLE_FEATURE_SH_STANDALONE
13586         {
13587                 int applet_no = find_applet_by_name(name);
13588                 if (applet_no >= 0) {
13589                         entry->cmdtype = CMDNORMAL;
13590                         entry->u.index = -2 - applet_no;
13591                         return;
13592                 }
13593         }
13594 #endif
13595
13596         /* We have to search path. */
13597         prev = -1;              /* where to start */
13598         if (cmdp && cmdp->rehash) {     /* doing a rehash */
13599                 if (cmdp->cmdtype == CMDBUILTIN)
13600                         prev = builtinloc;
13601                 else
13602                         prev = cmdp->param.index;
13603         }
13604
13605         e = ENOENT;
13606         idx = -1;
13607  loop:
13608         while ((len = padvance(&path, name)) >= 0) {
13609                 const char *lpathopt = pathopt;
13610
13611                 fullname = stackblock();
13612                 idx++;
13613                 if (lpathopt) {
13614                         if (*lpathopt == 'b') {
13615                                 if (bcmd)
13616                                         goto builtin_success;
13617                                 continue;
13618                         } else if (!(act & DO_NOFUNC)) {
13619                                 /* handled below */
13620                         } else {
13621                                 /* ignore unimplemented options */
13622                                 continue;
13623                         }
13624                 }
13625                 /* if rehash, don't redo absolute path names */
13626                 if (fullname[0] == '/' && idx <= prev) {
13627                         if (idx < prev)
13628                                 continue;
13629                         TRACE(("searchexec \"%s\": no change\n", name));
13630                         goto success;
13631                 }
13632                 while (stat(fullname, &statb) < 0) {
13633 #ifdef SYSV
13634                         if (errno == EINTR)
13635                                 continue;
13636 #endif
13637                         if (errno != ENOENT && errno != ENOTDIR)
13638                                 e = errno;
13639                         goto loop;
13640                 }
13641                 e = EACCES;     /* if we fail, this will be the error */
13642                 if (!S_ISREG(statb.st_mode))
13643                         continue;
13644                 if (lpathopt) {          /* this is a %func directory */
13645                         stalloc(len);
13646                         /* NB: stalloc will return space pointed by fullname
13647                          * (because we don't have any intervening allocations
13648                          * between stunalloc above and this stalloc) */
13649                         readcmdfile(fullname);
13650                         cmdp = cmdlookup(name, 0);
13651                         if (cmdp == NULL || cmdp->cmdtype != CMDFUNCTION)
13652                                 ash_msg_and_raise_error("%s not defined in %s", name, fullname);
13653                         stunalloc(fullname);
13654                         goto success;
13655                 }
13656                 TRACE(("searchexec \"%s\" returns \"%s\"\n", name, fullname));
13657                 if (!updatetbl) {
13658                         entry->cmdtype = CMDNORMAL;
13659                         entry->u.index = idx;
13660                         return;
13661                 }
13662                 INT_OFF;
13663                 cmdp = cmdlookup(name, 1);
13664                 cmdp->cmdtype = CMDNORMAL;
13665                 cmdp->param.index = idx;
13666                 INT_ON;
13667                 goto success;
13668         }
13669
13670         /* We failed.  If there was an entry for this command, delete it */
13671         if (cmdp && updatetbl)
13672                 delete_cmd_entry();
13673         if (act & DO_ERR) {
13674 #if ENABLE_ASH_BASH_NOT_FOUND_HOOK
13675                 struct tblentry *hookp = cmdlookup("command_not_found_handle", 0);
13676                 if (hookp && hookp->cmdtype == CMDFUNCTION) {
13677                         char *argv[3];
13678                         argv[0] = (char*) "command_not_found_handle";
13679                         argv[1] = name;
13680                         argv[2] = NULL;
13681                         evalfun(hookp->param.func, 2, argv, 0);
13682                         entry->cmdtype = CMDUNKNOWN;
13683                         return;
13684                 }
13685 #endif
13686                 ash_msg("%s: %s", name, errmsg(e, "not found"));
13687         }
13688  fail:
13689         entry->cmdtype = CMDUNKNOWN;
13690         return;
13691
13692  builtin_success:
13693         if (!updatetbl) {
13694                 entry->cmdtype = CMDBUILTIN;
13695                 entry->u.cmd = bcmd;
13696                 return;
13697         }
13698         INT_OFF;
13699         cmdp = cmdlookup(name, 1);
13700         cmdp->cmdtype = CMDBUILTIN;
13701         cmdp->param.cmd = bcmd;
13702         INT_ON;
13703  success:
13704         cmdp->rehash = 0;
13705         entry->cmdtype = cmdp->cmdtype;
13706         entry->u = cmdp->param;
13707 }
13708
13709
13710 /*
13711  * The trap builtin.
13712  */
13713 static int FAST_FUNC
13714 trapcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
13715 {
13716         char *action;
13717         char **ap;
13718         int signo, exitcode;
13719
13720         nextopt(nullstr);
13721         ap = argptr;
13722         if (!*ap) {
13723                 for (signo = 0; signo < NSIG; signo++) {
13724                         char *tr = trap_ptr[signo];
13725                         if (tr) {
13726                                 /* note: bash adds "SIG", but only if invoked
13727                                  * as "bash". If called as "sh", or if set -o posix,
13728                                  * then it prints short signal names.
13729                                  * We are printing short names: */
13730                                 out1fmt("trap -- %s %s\n",
13731                                                 single_quote(tr),
13732                                                 get_signame(signo));
13733                 /* trap_ptr != trap only if we are in special-cased `trap` code.
13734                  * In this case, we will exit very soon, no need to free(). */
13735                                 /* if (trap_ptr != trap && tp[0]) */
13736                                 /*      free(tr); */
13737                         }
13738                 }
13739                 /*
13740                 if (trap_ptr != trap) {
13741                         free(trap_ptr);
13742                         trap_ptr = trap;
13743                 }
13744                 */
13745                 return 0;
13746         }
13747
13748         /* Why the second check?
13749          * "trap NUM [sig2]..." is the same as "trap - NUM [sig2]..."
13750          * In this case, NUM is signal no, not an action.
13751          */
13752         action = NULL;
13753         if (ap[1] && !is_number(ap[0]))
13754                 action = *ap++;
13755
13756         exitcode = 0;
13757         while (*ap) {
13758                 signo = get_signum(*ap);
13759                 if (signo < 0) {
13760                         /* Mimic bash message exactly */
13761                         ash_msg("%s: invalid signal specification", *ap);
13762                         exitcode = 1;
13763                         goto next;
13764                 }
13765                 INT_OFF;
13766                 if (action) {
13767                         if (LONE_DASH(action))
13768                                 action = NULL;
13769                         else {
13770                                 if (action[0]) /* not NULL and not "" and not "-" */
13771                                         may_have_traps = 1;
13772                                 action = ckstrdup(action);
13773                         }
13774                 }
13775                 free(trap[signo]);
13776                 trap[signo] = action;
13777                 if (signo != 0)
13778                         setsignal(signo);
13779                 INT_ON;
13780  next:
13781                 ap++;
13782         }
13783         return exitcode;
13784 }
13785
13786
13787 /* ============ Builtins */
13788
13789 #if ENABLE_ASH_HELP
13790 static int FAST_FUNC
13791 helpcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
13792 {
13793         unsigned col;
13794         unsigned i;
13795
13796         out1fmt(
13797                 "Built-in commands:\n"
13798                 "------------------\n");
13799         for (col = 0, i = 0; i < ARRAY_SIZE(builtintab); i++) {
13800                 col += out1fmt("%c%s", ((col == 0) ? '\t' : ' '),
13801                                         builtintab[i].name + 1);
13802                 if (col > 60) {
13803                         out1fmt("\n");
13804                         col = 0;
13805                 }
13806         }
13807 # if ENABLE_FEATURE_SH_STANDALONE
13808         {
13809                 const char *a = applet_names;
13810                 while (*a) {
13811                         col += out1fmt("%c%s", ((col == 0) ? '\t' : ' '), a);
13812                         if (col > 60) {
13813                                 out1fmt("\n");
13814                                 col = 0;
13815                         }
13816                         while (*a++ != '\0')
13817                                 continue;
13818                 }
13819         }
13820 # endif
13821         newline_and_flush(stdout);
13822         return EXIT_SUCCESS;
13823 }
13824 #endif
13825
13826 #if MAX_HISTORY
13827 static int FAST_FUNC
13828 historycmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
13829 {
13830         if (line_input_state)
13831                 show_history(line_input_state);
13832         return EXIT_SUCCESS;
13833 }
13834 #endif
13835
13836 /*
13837  * The export and readonly commands.
13838  */
13839 static int FAST_FUNC
13840 exportcmd(int argc UNUSED_PARAM, char **argv)
13841 {
13842         struct var *vp;
13843         char *name;
13844         const char *p;
13845         char **aptr;
13846         char opt;
13847         int flag;
13848         int flag_off;
13849
13850         /* "readonly" in bash accepts, but ignores -n.
13851          * We do the same: it saves a conditional in nextopt's param.
13852          */
13853         flag_off = 0;
13854         while ((opt = nextopt("np")) != '\0') {
13855                 if (opt == 'n')
13856                         flag_off = VEXPORT;
13857         }
13858         flag = VEXPORT;
13859         if (argv[0][0] == 'r') {
13860                 flag = VREADONLY;
13861                 flag_off = 0; /* readonly ignores -n */
13862         }
13863         flag_off = ~flag_off;
13864
13865         /*if (opt_p_not_specified) - bash doesn't check this. Try "export -p NAME" */
13866         {
13867                 aptr = argptr;
13868                 name = *aptr;
13869                 if (name) {
13870                         do {
13871                                 p = strchr(name, '=');
13872                                 if (p != NULL) {
13873                                         p++;
13874                                 } else {
13875                                         vp = *findvar(hashvar(name), name);
13876                                         if (vp) {
13877                                                 vp->flags = ((vp->flags | flag) & flag_off);
13878                                                 continue;
13879                                         }
13880                                 }
13881                                 setvar(name, p, (flag & flag_off));
13882                         } while ((name = *++aptr) != NULL);
13883                         return 0;
13884                 }
13885         }
13886
13887         /* No arguments. Show the list of exported or readonly vars.
13888          * -n is ignored.
13889          */
13890         showvars(argv[0], flag, 0);
13891         return 0;
13892 }
13893
13894 /*
13895  * Delete a function if it exists.
13896  */
13897 static void
13898 unsetfunc(const char *name)
13899 {
13900         struct tblentry *cmdp;
13901
13902         cmdp = cmdlookup(name, 0);
13903         if (cmdp != NULL && cmdp->cmdtype == CMDFUNCTION)
13904                 delete_cmd_entry();
13905 }
13906
13907 /*
13908  * The unset builtin command.  We unset the function before we unset the
13909  * variable to allow a function to be unset when there is a readonly variable
13910  * with the same name.
13911  */
13912 static int FAST_FUNC
13913 unsetcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
13914 {
13915         char **ap;
13916         int i;
13917         int flag = 0;
13918
13919         while ((i = nextopt("vf")) != 0) {
13920                 flag = i;
13921         }
13922
13923         for (ap = argptr; *ap; ap++) {
13924                 if (flag != 'f') {
13925                         unsetvar(*ap);
13926                         continue;
13927                 }
13928                 if (flag != 'v')
13929                         unsetfunc(*ap);
13930         }
13931         return 0;
13932 }
13933
13934 static const unsigned char timescmd_str[] ALIGN1 = {
13935         ' ',  offsetof(struct tms, tms_utime),
13936         '\n', offsetof(struct tms, tms_stime),
13937         ' ',  offsetof(struct tms, tms_cutime),
13938         '\n', offsetof(struct tms, tms_cstime),
13939         0
13940 };
13941 static int FAST_FUNC
13942 timescmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
13943 {
13944         unsigned clk_tck;
13945         const unsigned char *p;
13946         struct tms buf;
13947
13948         clk_tck = bb_clk_tck();
13949
13950         times(&buf);
13951         p = timescmd_str;
13952         do {
13953                 unsigned sec, frac;
13954                 unsigned long t;
13955                 t = *(clock_t *)(((char *) &buf) + p[1]);
13956                 sec = t / clk_tck;
13957                 frac = t % clk_tck;
13958                 out1fmt("%um%u.%03us%c",
13959                         sec / 60, sec % 60,
13960                         (frac * 1000) / clk_tck,
13961                         p[0]);
13962                 p += 2;
13963         } while (*p);
13964
13965         return 0;
13966 }
13967
13968 #if ENABLE_FEATURE_SH_MATH
13969 /*
13970  * The let builtin. Partially stolen from GNU Bash, the Bourne Again SHell.
13971  * Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
13972  *
13973  * Copyright (C) 2003 Vladimir Oleynik <dzo@simtreas.ru>
13974  */
13975 static int FAST_FUNC
13976 letcmd(int argc UNUSED_PARAM, char **argv)
13977 {
13978         arith_t i;
13979
13980         argv++;
13981         if (!*argv)
13982                 ash_msg_and_raise_error("expression expected");
13983         do {
13984                 i = ash_arith(*argv);
13985         } while (*++argv);
13986
13987         return !i;
13988 }
13989 #endif
13990
13991 /*
13992  * The read builtin. Options:
13993  *      -r              Do not interpret '\' specially
13994  *      -s              Turn off echo (tty only)
13995  *      -n NCHARS       Read NCHARS max
13996  *      -p PROMPT       Display PROMPT on stderr (if input is from tty)
13997  *      -t SECONDS      Timeout after SECONDS (tty or pipe only)
13998  *      -u FD           Read from given FD instead of fd 0
13999  *      -d DELIM        End on DELIM char, not newline
14000  * This uses unbuffered input, which may be avoidable in some cases.
14001  * TODO: bash also has:
14002  *      -a ARRAY        Read into array[0],[1],etc
14003  *      -e              Use line editing (tty only)
14004  */
14005 static int FAST_FUNC
14006 readcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
14007 {
14008         struct builtin_read_params params;
14009         const char *r;
14010         int i;
14011
14012         memset(&params, 0, sizeof(params));
14013
14014         while ((i = nextopt("p:u:rt:n:sd:")) != '\0') {
14015                 switch (i) {
14016                 case 'p':
14017                         params.opt_p = optionarg;
14018                         break;
14019                 case 'n':
14020                         params.opt_n = optionarg;
14021                         break;
14022                 case 's':
14023                         params.read_flags |= BUILTIN_READ_SILENT;
14024                         break;
14025                 case 't':
14026                         params.opt_t = optionarg;
14027                         break;
14028                 case 'r':
14029                         params.read_flags |= BUILTIN_READ_RAW;
14030                         break;
14031                 case 'u':
14032                         params.opt_u = optionarg;
14033                         break;
14034 #if BASH_READ_D
14035                 case 'd':
14036                         params.opt_d = optionarg;
14037                         break;
14038 #endif
14039                 default:
14040                         break;
14041                 }
14042         }
14043
14044         params.argv = argptr;
14045         params.setvar = setvar0;
14046         params.ifs = bltinlookup("IFS"); /* can be NULL */
14047
14048         /* "read -s" needs to save/restore termios, can't allow ^C
14049          * to jump out of it.
14050          */
14051  again:
14052         INT_OFF;
14053         r = shell_builtin_read(&params);
14054         INT_ON;
14055
14056         if ((uintptr_t)r == 1 && errno == EINTR) {
14057                 /* To get SIGCHLD: sleep 1 & read x; echo $x
14058                  * Correct behavior is to not exit "read"
14059                  */
14060                 if (pending_sig == 0)
14061                         goto again;
14062         }
14063
14064         if ((uintptr_t)r > 1)
14065                 ash_msg_and_raise_error(r);
14066
14067         return (uintptr_t)r;
14068 }
14069
14070 static int FAST_FUNC
14071 umaskcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
14072 {
14073         static const char permuser[3] ALIGN1 = "ogu";
14074
14075         mode_t mask;
14076         int symbolic_mode = 0;
14077
14078         while (nextopt("S") != '\0') {
14079                 symbolic_mode = 1;
14080         }
14081
14082         INT_OFF;
14083         mask = umask(0);
14084         umask(mask);
14085         INT_ON;
14086
14087         if (*argptr == NULL) {
14088                 if (symbolic_mode) {
14089                         char buf[sizeof(",u=rwx,g=rwx,o=rwx")];
14090                         char *p = buf;
14091                         int i;
14092
14093                         i = 2;
14094                         for (;;) {
14095                                 *p++ = ',';
14096                                 *p++ = permuser[i];
14097                                 *p++ = '=';
14098                                 /* mask is 0..0uuugggooo. i=2 selects uuu bits */
14099                                 if (!(mask & 0400)) *p++ = 'r';
14100                                 if (!(mask & 0200)) *p++ = 'w';
14101                                 if (!(mask & 0100)) *p++ = 'x';
14102                                 mask <<= 3;
14103                                 if (--i < 0)
14104                                         break;
14105                         }
14106                         *p = '\0';
14107                         puts(buf + 1);
14108                 } else {
14109                         out1fmt("%04o\n", mask);
14110                 }
14111         } else {
14112                 char *modestr = *argptr;
14113                 /* numeric umasks are taken as-is */
14114                 /* symbolic umasks are inverted: "umask a=rx" calls umask(222) */
14115                 if (!isdigit(modestr[0]))
14116                         mask ^= 0777;
14117                 mask = bb_parse_mode(modestr, mask);
14118                 if ((unsigned)mask > 0777) {
14119                         ash_msg_and_raise_error("illegal mode: %s", modestr);
14120                 }
14121                 if (!isdigit(modestr[0]))
14122                         mask ^= 0777;
14123                 umask(mask);
14124         }
14125         return 0;
14126 }
14127
14128 static int FAST_FUNC
14129 ulimitcmd(int argc UNUSED_PARAM, char **argv)
14130 {
14131         return shell_builtin_ulimit(argv);
14132 }
14133
14134 /* ============ main() and helpers */
14135
14136 /*
14137  * Called to exit the shell.
14138  */
14139 static void
14140 exitshell(void)
14141 {
14142         struct jmploc loc;
14143         char *p;
14144
14145 #if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT
14146         if (line_input_state)
14147                 save_history(line_input_state);
14148 #endif
14149         savestatus = exitstatus;
14150         TRACE(("pid %d, exitshell(%d)\n", getpid(), savestatus));
14151         if (setjmp(loc.loc))
14152                 goto out;
14153         exception_handler = &loc;
14154         p = trap[0];
14155         if (p) {
14156                 trap[0] = NULL;
14157                 evalskip = 0;
14158                 evalstring(p, 0);
14159                 /*free(p); - we'll exit soon */
14160         }
14161  out:
14162         /* dash wraps setjobctl(0) in "if (setjmp(loc.loc) == 0) {...}".
14163          * our setjobctl(0) does not panic if tcsetpgrp fails inside it.
14164          */
14165         setjobctl(0);
14166         flush_stdout_stderr();
14167         _exit(savestatus);
14168         /* NOTREACHED */
14169 }
14170
14171 /* Don't inline: conserve stack of caller from having our locals too */
14172 static NOINLINE void
14173 init(void)
14174 {
14175         /* we will never free this */
14176         basepf.next_to_pgetc = basepf.buf = ckmalloc(IBUFSIZ);
14177         basepf.linno = 1;
14178
14179         sigmode[SIGCHLD - 1] = S_DFL; /* ensure we install handler even if it is SIG_IGNed */
14180         setsignal(SIGCHLD);
14181
14182         {
14183                 char **envp;
14184                 const char *p;
14185
14186                 initvar();
14187                 for (envp = environ; envp && *envp; envp++) {
14188 /* Used to have
14189  *                      p = endofname(*envp);
14190  *                      if (p != *envp && *p == '=') {
14191  * here to weed out badly-named variables, but this breaks
14192  * scenarios where people do want them passed to children:
14193  * import os
14194  * os.environ["test-test"]="test"
14195  * if os.fork() == 0:
14196  *   os.execv("ash", [ 'ash', '-c', 'eval $(export -p); echo OK' ])  # fixes this
14197  * os.execv("ash", [ 'ash', '-c', 'env | grep test-test' ])  # breaks this
14198  */
14199                         if (strchr(*envp, '=')) {
14200                                 setvareq(*envp, VEXPORT|VTEXTFIXED);
14201                         }
14202                 }
14203
14204                 setvareq((char*)defifsvar, VTEXTFIXED);
14205                 setvareq((char*)defoptindvar, VTEXTFIXED);
14206
14207                 setvar0("PPID", utoa(getppid()));
14208 #if BASH_SHLVL_VAR
14209                 p = lookupvar("SHLVL");
14210                 setvar("SHLVL", utoa((p ? atoi(p) : 0) + 1), VEXPORT);
14211 #endif
14212 #if BASH_HOSTNAME_VAR
14213                 if (!lookupvar("HOSTNAME")) {
14214                         struct utsname uts;
14215                         uname(&uts);
14216                         setvar0("HOSTNAME", uts.nodename);
14217                 }
14218 #endif
14219                 p = lookupvar("PWD");
14220                 if (p) {
14221                         struct stat st1, st2;
14222                         if (p[0] != '/' || stat(p, &st1) || stat(".", &st2)
14223                          || st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino
14224                         ) {
14225                                 p = NULL;
14226                         }
14227                 }
14228                 setpwd(p, 0);
14229         }
14230 }
14231
14232
14233 //usage:#define ash_trivial_usage
14234 //usage:        "[-/+OPTIONS] [-/+o OPT]... [-c 'SCRIPT' [ARG0 [ARGS]] / FILE [ARGS] / -s [ARGS]]"
14235 //usage:#define ash_full_usage "\n\n"
14236 //usage:        "Unix shell interpreter"
14237
14238 /*
14239  * Process the shell command line arguments.
14240  */
14241 static int
14242 procargs(char **argv)
14243 {
14244         int i;
14245         const char *xminusc;
14246         char **xargv;
14247         int login_sh;
14248
14249         xargv = argv;
14250         login_sh = xargv[0] && xargv[0][0] == '-';
14251 #if NUM_SCRIPTS > 0
14252         if (minusc)
14253                 goto setarg0;
14254 #endif
14255         arg0 = xargv[0];
14256         /* if (xargv[0]) - mmm, this is always true! */
14257                 xargv++;
14258         argptr = xargv;
14259         for (i = 0; i < NOPTS; i++)
14260                 optlist[i] = 2;
14261         if (options(&login_sh)) {
14262                 /* it already printed err message */
14263                 raise_exception(EXERROR);
14264         }
14265         xargv = argptr;
14266         xminusc = minusc;
14267         if (*xargv == NULL) {
14268                 if (xminusc)
14269                         ash_msg_and_raise_error(bb_msg_requires_arg, "-c");
14270                 sflag = 1;
14271         }
14272         if (iflag == 2 /* no explicit -i given */
14273          && sflag == 1 /* -s given (or implied) */
14274          && !minusc /* bash compat: ash -sc 'echo $-' is not interactive (dash is) */
14275          && isatty(0) && isatty(1) /* we are on tty */
14276         ) {
14277                 iflag = 1;
14278         }
14279         if (mflag == 2)
14280                 mflag = iflag;
14281         for (i = 0; i < NOPTS; i++)
14282                 if (optlist[i] == 2)
14283                         optlist[i] = 0;
14284 #if DEBUG == 2
14285         debug = 1;
14286 #endif
14287         /* POSIX 1003.2: first arg after "-c CMD" is $0, remainder $1... */
14288         if (xminusc) {
14289                 minusc = *xargv++;
14290                 if (*xargv)
14291                         goto setarg0;
14292         } else if (!sflag) {
14293                 setinputfile(*xargv, 0);
14294  setarg0:
14295                 arg0 = *xargv++;
14296                 commandname = arg0;
14297         }
14298
14299         shellparam.p = xargv;
14300 #if ENABLE_ASH_GETOPTS
14301         shellparam.optind = 1;
14302         shellparam.optoff = -1;
14303 #endif
14304         /* assert(shellparam.malloced == 0 && shellparam.nparam == 0); */
14305         while (*xargv) {
14306                 shellparam.nparam++;
14307                 xargv++;
14308         }
14309         optschanged();
14310
14311         return login_sh;
14312 }
14313
14314 /*
14315  * Read /etc/profile, ~/.profile, $ENV.
14316  */
14317 static void
14318 read_profile(const char *name)
14319 {
14320         name = expandstr(name, DQSYNTAX);
14321         if (setinputfile(name, INPUT_PUSH_FILE | INPUT_NOFILE_OK) < 0)
14322                 return;
14323         cmdloop(0);
14324         popfile();
14325 }
14326
14327 /*
14328  * This routine is called when an error or an interrupt occurs in an
14329  * interactive shell and control is returned to the main command loop
14330  * but prior to exitshell.
14331  */
14332 static void
14333 exitreset(void)
14334 {
14335         /* from eval.c: */
14336         evalskip = 0;
14337         loopnest = 0;
14338         if (savestatus >= 0) {
14339                 exitstatus = savestatus;
14340                 savestatus = -1;
14341         }
14342
14343         /* from expand.c: */
14344         ifsfree();
14345
14346         /* from redir.c: */
14347         unwindredir(NULL);
14348 }
14349
14350 /*
14351  * This routine is called when an error or an interrupt occurs in an
14352  * interactive shell and control is returned to the main command loop.
14353  * (In dash, this function is auto-generated by build machinery).
14354  */
14355 static void
14356 reset(void)
14357 {
14358         /* from input.c: */
14359         g_parsefile->left_in_buffer = 0;
14360         g_parsefile->left_in_line = 0;      /* clear input buffer */
14361         popallfiles();
14362
14363         /* from var.c: */
14364         unwindlocalvars(NULL);
14365 }
14366
14367 #if PROFILE
14368 static short profile_buf[16384];
14369 extern int etext();
14370 #endif
14371
14372 /*
14373  * Main routine.  We initialize things, parse the arguments, execute
14374  * profiles if we're a login shell, and then call cmdloop to execute
14375  * commands.  The setjmp call sets up the location to jump to when an
14376  * exception occurs.  When an exception occurs the variable "state"
14377  * is used to figure out how far we had gotten.
14378  */
14379 int ash_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
14380 #if NUM_SCRIPTS > 0
14381 int ash_main(int argc, char **argv)
14382 #else
14383 int ash_main(int argc UNUSED_PARAM, char **argv)
14384 #endif
14385 /* note: 'argc' is used only if embedded scripts are enabled */
14386 {
14387         volatile smallint state;
14388         struct jmploc jmploc;
14389         struct stackmark smark;
14390         int login_sh;
14391
14392         /* Initialize global data */
14393         INIT_G_misc();
14394         INIT_G_memstack();
14395         INIT_G_var();
14396 #if ENABLE_ASH_ALIAS
14397         INIT_G_alias();
14398 #endif
14399         INIT_G_cmdtable();
14400
14401 #if PROFILE
14402         monitor(4, etext, profile_buf, sizeof(profile_buf), 50);
14403 #endif
14404
14405         state = 0;
14406         if (setjmp(jmploc.loc)) {
14407                 smallint e;
14408                 smallint s;
14409
14410                 exitreset();
14411
14412                 e = exception_type;
14413                 s = state;
14414                 if (e == EXEXIT || s == 0 || iflag == 0 || shlvl) {
14415                         exitshell();
14416                 }
14417
14418                 reset();
14419
14420                 if (e == EXINT) {
14421                         newline_and_flush(stderr);
14422                 }
14423
14424                 popstackmark(&smark);
14425                 FORCE_INT_ON; /* enable interrupts */
14426                 if (s == 1)
14427                         goto state1;
14428                 if (s == 2)
14429                         goto state2;
14430                 if (s == 3)
14431                         goto state3;
14432                 goto state4;
14433         }
14434         exception_handler = &jmploc;
14435         rootpid = getpid();
14436
14437         init();
14438         setstackmark(&smark);
14439
14440 #if NUM_SCRIPTS > 0
14441         if (argc < 0)
14442                 /* Non-NULL minusc tells procargs that an embedded script is being run */
14443                 minusc = get_script_content(-argc - 1);
14444 #endif
14445         login_sh = procargs(argv);
14446 #if DEBUG
14447         TRACE(("Shell args: "));
14448         trace_puts_args(argv);
14449 #endif
14450
14451         if (login_sh) {
14452                 const char *hp;
14453
14454                 state = 1;
14455                 read_profile("/etc/profile");
14456  state1:
14457                 state = 2;
14458                 hp = lookupvar("HOME");
14459                 if (hp)
14460                         read_profile("$HOME/.profile");
14461         }
14462  state2:
14463         state = 3;
14464         if (
14465 #ifndef linux
14466          getuid() == geteuid() && getgid() == getegid() &&
14467 #endif
14468          iflag
14469         ) {
14470                 const char *shinit = lookupvar("ENV");
14471                 if (shinit != NULL && *shinit != '\0')
14472                         read_profile(shinit);
14473         }
14474         popstackmark(&smark);
14475  state3:
14476         state = 4;
14477         if (minusc) {
14478                 /* evalstring pushes parsefile stack.
14479                  * Ensure we don't falsely claim that 0 (stdin)
14480                  * is one of stacked source fds.
14481                  * Testcase: ash -c 'exec 1>&0' must not complain. */
14482
14483                 // if (!sflag) g_parsefile->pf_fd = -1;
14484                 // ^^ not necessary since now we special-case fd 0
14485                 // in save_fd_on_redirect()
14486
14487                 // dash: evalstring(minusc, sflag ? 0 : EV_EXIT);
14488                 // The above makes
14489                 //  ash -sc 'echo $-'
14490                 // continue reading input from stdin after running 'echo'.
14491                 // bash does not do this: it prints "hBcs" and exits.
14492                 evalstring(minusc, EV_EXIT);
14493         }
14494
14495         if (sflag || minusc == NULL) {
14496 #if MAX_HISTORY > 0 && ENABLE_FEATURE_EDITING_SAVEHISTORY
14497                 if (iflag) {
14498                         const char *hp = lookupvar("HISTFILE");
14499                         if (!hp) {
14500                                 hp = lookupvar("HOME");
14501                                 if (hp) {
14502                                         INT_OFF;
14503                                         hp = concat_path_file(hp, ".ash_history");
14504                                         setvar0("HISTFILE", hp);
14505                                         free((char*)hp);
14506                                         INT_ON;
14507                                         hp = lookupvar("HISTFILE");
14508                                 }
14509                         }
14510                         if (hp)
14511                                 line_input_state->hist_file = hp;
14512 # if ENABLE_FEATURE_SH_HISTFILESIZE
14513                         hp = lookupvar("HISTFILESIZE");
14514                         line_input_state->max_history = size_from_HISTFILESIZE(hp);
14515 # endif
14516                 }
14517 #endif
14518  state4: /* XXX ??? - why isn't this before the "if" statement */
14519
14520                 /* Interactive bash re-enables SIGHUP which is SIG_IGNed on entry.
14521                  * Try:
14522                  * trap '' hup; bash; echo RET  # type "kill -hup $$", see SIGHUP having effect
14523                  * trap '' hup; bash -c 'kill -hup $$; echo ALIVE'  # here SIGHUP is SIG_IGNed
14524                  */
14525                 signal(SIGHUP, SIG_DFL);
14526
14527                 cmdloop(1);
14528         }
14529 #if PROFILE
14530         monitor(0);
14531 #endif
14532 #ifdef GPROF
14533         {
14534                 extern void _mcleanup(void);
14535                 _mcleanup();
14536         }
14537 #endif
14538         TRACE(("End of main reached\n"));
14539         exitshell();
14540         /* NOTREACHED */
14541 }
14542
14543
14544 /*-
14545  * Copyright (c) 1989, 1991, 1993, 1994
14546  *      The Regents of the University of California.  All rights reserved.
14547  *
14548  * This code is derived from software contributed to Berkeley by
14549  * Kenneth Almquist.
14550  *
14551  * Redistribution and use in source and binary forms, with or without
14552  * modification, are permitted provided that the following conditions
14553  * are met:
14554  * 1. Redistributions of source code must retain the above copyright
14555  *    notice, this list of conditions and the following disclaimer.
14556  * 2. Redistributions in binary form must reproduce the above copyright
14557  *    notice, this list of conditions and the following disclaimer in the
14558  *    documentation and/or other materials provided with the distribution.
14559  * 3. Neither the name of the University nor the names of its contributors
14560  *    may be used to endorse or promote products derived from this software
14561  *    without specific prior written permission.
14562  *
14563  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ''AS IS'' AND
14564  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
14565  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
14566  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
14567  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
14568  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
14569  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
14570  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
14571  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
14572  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
14573  * SUCH DAMAGE.
14574  */