005d87ecfae64e534ca2529f4b347cf224965325
[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: */
408 #define EXINT 0         /* SIGINT received */
409 #define EXERROR 1       /* a generic error */
410 #define EXEND 3         /* exit the shell */
411 #define EXEXIT 4        /* exit the shell via exitcmd */
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(size_t min)
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         min = SHELL_ALIGN(min | 128);
1689         if (newlen < min)
1690                 newlen += min;
1691
1692         if (g_stacknxt == g_stackp->space && g_stackp != &stackbase) {
1693                 struct stack_block *sp;
1694                 struct stack_block *prevstackp;
1695                 size_t grosslen;
1696
1697                 INT_OFF;
1698                 sp = g_stackp;
1699                 prevstackp = sp->prev;
1700                 grosslen = newlen + sizeof(struct stack_block) - MINSIZE;
1701                 sp = ckrealloc(sp, grosslen);
1702                 sp->prev = prevstackp;
1703                 g_stackp = sp;
1704                 g_stacknxt = sp->space;
1705                 g_stacknleft = newlen;
1706                 sstrend = sp->space + newlen;
1707                 INT_ON;
1708         } else {
1709                 char *oldspace = g_stacknxt;
1710                 size_t oldlen = g_stacknleft;
1711                 char *p = stalloc(newlen);
1712
1713                 /* free the space we just allocated */
1714                 g_stacknxt = memcpy(p, oldspace, oldlen);
1715                 g_stacknleft += newlen;
1716         }
1717 }
1718
1719 /*
1720  * The following routines are somewhat easier to use than the above.
1721  * The user declares a variable of type STACKSTR, which may be declared
1722  * to be a register.  The macro STARTSTACKSTR initializes things.  Then
1723  * the user uses the macro STPUTC to add characters to the string.  In
1724  * effect, STPUTC(c, p) is the same as *p++ = c except that the stack is
1725  * grown as necessary.  When the user is done, she can just leave the
1726  * string there and refer to it using stackblock().  Or she can allocate
1727  * the space for it using grabstackstr().  If it is necessary to allow
1728  * someone else to use the stack temporarily and then continue to grow
1729  * the string, the user should use grabstack to allocate the space, and
1730  * then call ungrabstr(p) to return to the previous mode of operation.
1731  *
1732  * USTPUTC is like STPUTC except that it doesn't check for overflow.
1733  * CHECKSTACKSPACE can be called before USTPUTC to ensure that there
1734  * is space for at least one character.
1735  */
1736 static void *
1737 growstackstr(void)
1738 {
1739         size_t len = stackblocksize();
1740         growstackblock(0);
1741         return (char *)stackblock() + len;
1742 }
1743
1744 static char *
1745 growstackto(size_t len)
1746 {
1747         if (stackblocksize() < len)
1748                 growstackblock(len);
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  * Break the argument string into pieces based upon IFS and add the
6075  * strings to the argument list.  The regions of the string to be
6076  * searched for IFS characters have been stored by recordregion.
6077  */
6078 static void
6079 ifsbreakup(char *string, struct arglist *arglist)
6080 {
6081         struct ifsregion *ifsp;
6082         struct strlist *sp;
6083         char *start;
6084         char *p;
6085         char *q;
6086         const char *ifs, *realifs;
6087         int ifsspc;
6088         int nulonly;
6089
6090         start = string;
6091         if (ifslastp != NULL) {
6092                 ifsspc = 0;
6093                 nulonly = 0;
6094                 realifs = ifsset() ? ifsval() : defifs;
6095                 ifsp = &ifsfirst;
6096                 do {
6097                         int afternul;
6098
6099                         p = string + ifsp->begoff;
6100                         afternul = nulonly;
6101                         nulonly = ifsp->nulonly;
6102                         ifs = nulonly ? nullstr : realifs;
6103                         ifsspc = 0;
6104                         while (p < string + ifsp->endoff) {
6105                                 q = p;
6106                                 if ((unsigned char)*p == CTLESC)
6107                                         p++;
6108                                 if (!strchr(ifs, *p)) {
6109                                         p++;
6110                                         continue;
6111                                 }
6112                                 if (!(afternul || nulonly))
6113                                         ifsspc = (strchr(defifs, *p) != NULL);
6114                                 /* Ignore IFS whitespace at start */
6115                                 if (q == start && ifsspc) {
6116                                         p++;
6117                                         start = p;
6118                                         continue;
6119                                 }
6120                                 *q = '\0';
6121                                 sp = stzalloc(sizeof(*sp));
6122                                 sp->text = start;
6123                                 *arglist->lastp = sp;
6124                                 arglist->lastp = &sp->next;
6125                                 p++;
6126                                 if (!nulonly) {
6127                                         for (;;) {
6128                                                 if (p >= string + ifsp->endoff) {
6129                                                         break;
6130                                                 }
6131                                                 q = p;
6132                                                 if ((unsigned char)*p == CTLESC)
6133                                                         p++;
6134                                                 if (strchr(ifs, *p) == NULL) {
6135                                                         p = q;
6136                                                         break;
6137                                                 }
6138                                                 if (strchr(defifs, *p) == NULL) {
6139                                                         if (ifsspc) {
6140                                                                 p++;
6141                                                                 ifsspc = 0;
6142                                                         } else {
6143                                                                 p = q;
6144                                                                 break;
6145                                                         }
6146                                                 } else
6147                                                         p++;
6148                                         }
6149                                 }
6150                                 start = p;
6151                         } /* while */
6152                         ifsp = ifsp->next;
6153                 } while (ifsp != NULL);
6154                 if (nulonly)
6155                         goto add;
6156         }
6157
6158         if (!*start)
6159                 return;
6160
6161  add:
6162         sp = stzalloc(sizeof(*sp));
6163         sp->text = start;
6164         *arglist->lastp = sp;
6165         arglist->lastp = &sp->next;
6166 }
6167
6168 static void
6169 ifsfree(void)
6170 {
6171         struct ifsregion *p = ifsfirst.next;
6172
6173         if (!p)
6174                 goto out;
6175
6176         INT_OFF;
6177         do {
6178                 struct ifsregion *ifsp;
6179                 ifsp = p->next;
6180                 free(p);
6181                 p = ifsp;
6182         } while (p);
6183         ifsfirst.next = NULL;
6184         INT_ON;
6185  out:
6186         ifslastp = NULL;
6187 }
6188
6189 static size_t
6190 esclen(const char *start, const char *p)
6191 {
6192         size_t esc = 0;
6193
6194         while (p > start && (unsigned char)*--p == CTLESC) {
6195                 esc++;
6196         }
6197         return esc;
6198 }
6199
6200 /*
6201  * Remove any CTLESC characters from a string.
6202  */
6203 #if !BASH_PATTERN_SUBST
6204 #define rmescapes(str, flag, slash_position) \
6205         rmescapes(str, flag)
6206 #endif
6207 static char *
6208 rmescapes(char *str, int flag, int *slash_position)
6209 {
6210         static const char qchars[] ALIGN1 = {
6211                 IF_BASH_PATTERN_SUBST('/',) CTLESC, CTLQUOTEMARK, '\0' };
6212
6213         char *p, *q, *r;
6214         unsigned protect_against_glob;
6215         unsigned globbing;
6216
6217         p = strpbrk(str, qchars IF_BASH_PATTERN_SUBST(+ !slash_position));
6218         if (!p)
6219                 return str;
6220
6221         q = p;
6222         r = str;
6223         if (flag & RMESCAPE_ALLOC) {
6224                 size_t len = p - str;
6225                 size_t fulllen = len + strlen(p) + 1;
6226
6227                 if (flag & RMESCAPE_GROW) {
6228                         int strloc = str - (char *)stackblock();
6229                         r = makestrspace(fulllen, expdest);
6230                         /* p and str may be invalidated by makestrspace */
6231                         str = (char *)stackblock() + strloc;
6232                         p = str + len;
6233                 } else if (flag & RMESCAPE_HEAP) {
6234                         r = ckmalloc(fulllen);
6235                 } else {
6236                         r = stalloc(fulllen);
6237                 }
6238                 q = r;
6239                 if (len > 0) {
6240                         q = (char *)mempcpy(q, str, len);
6241                 }
6242         }
6243
6244         globbing = flag & RMESCAPE_GLOB;
6245         protect_against_glob = globbing;
6246         while (*p) {
6247                 if ((unsigned char)*p == CTLQUOTEMARK) {
6248 // Note: protect_against_glob only affect whether
6249 // CTLESC,<ch> gets converted to <ch> or to \<ch>
6250                         p++;
6251                         protect_against_glob = globbing;
6252                         continue;
6253                 }
6254                 if (*p == '\\') {
6255                         /* naked back slash */
6256                         protect_against_glob = 0;
6257                         goto copy;
6258                 }
6259                 if ((unsigned char)*p == CTLESC) {
6260                         p++;
6261 #if DEBUG
6262                         if (*p == '\0')
6263                                 ash_msg_and_raise_error("CTLESC at EOL (shouldn't happen)");
6264 #endif
6265                         if (protect_against_glob) {
6266                                 /*
6267                                  * We used to trust glob() and fnmatch() to eat
6268                                  * superfluous escapes (\z where z has no
6269                                  * special meaning anyway). But this causes
6270                                  * bugs such as string of one greek letter rho
6271                                  * (unicode-encoded as two bytes "cf,81")
6272                                  * getting encoded as "cf,CTLESC,81"
6273                                  * and here, converted to "cf,\,81" -
6274                                  * which does not go well with some flavors
6275                                  * of fnmatch() in unicode locales
6276                                  * (for example, glibc <= 2.22).
6277                                  *
6278                                  * Lets add "\" only on the chars which need it.
6279                                  * Testcases for less obvious chars are shown.
6280                                  */
6281                                 if (*p == '*'
6282                                  || *p == '?'
6283                                  || *p == '['
6284                                  || *p == '\\' /* case '\' in \\    ) echo ok;; *) echo WRONG;; esac */
6285                                  || *p == ']'  /* case ']' in [a\]] ) echo ok;; *) echo WRONG;; esac */
6286                                  || *p == '-'  /* case '-' in [a\-c]) echo ok;; *) echo WRONG;; esac */
6287                                  || *p == '!'  /* case '!' in [\!]  ) echo ok;; *) echo WRONG;; esac */
6288                                 /* Some libc support [^negate], that's why "^" also needs love */
6289                                  || *p == '^'  /* case '^' in [\^]  ) echo ok;; *) echo WRONG;; esac */
6290                                 ) {
6291                                         *q++ = '\\';
6292                                 }
6293                         }
6294                 }
6295 #if BASH_PATTERN_SUBST
6296                 else if (slash_position && p == str + *slash_position) {
6297                         /* stop handling globbing */
6298                         globbing = 0;
6299                         *slash_position = q - r;
6300                         slash_position = NULL;
6301                 }
6302 #endif
6303                 protect_against_glob = globbing;
6304  copy:
6305                 *q++ = *p++;
6306         }
6307         *q = '\0';
6308         if (flag & RMESCAPE_GROW) {
6309                 expdest = r;
6310                 STADJUST(q - r + 1, expdest);
6311         }
6312         return r;
6313 }
6314 #define pmatch(a, b) !fnmatch((a), (b), 0)
6315
6316 /*
6317  * Prepare a pattern for a expmeta (internal glob(3)) call.
6318  *
6319  * Returns an stalloced string.
6320  */
6321 static char *
6322 preglob(const char *pattern, int flag)
6323 {
6324         return rmescapes((char *)pattern, flag | RMESCAPE_GLOB, NULL);
6325 }
6326
6327 /*
6328  * Put a string on the stack.
6329  */
6330 static size_t
6331 memtodest(const char *p, size_t len, int flags)
6332 {
6333         int syntax = flags & EXP_QUOTED ? DQSYNTAX : BASESYNTAX;
6334         char *q;
6335         char *s;
6336
6337         if (!len)
6338                 return 0;
6339
6340         q = makestrspace(len * 2, expdest);
6341         s = q;
6342
6343         do {
6344                 unsigned char c = *p++;
6345                 if (c) {
6346                         if (flags & QUOTES_ESC) {
6347                                 int n = SIT(c, syntax);
6348                                 if (n == CCTL
6349                                  || ((flags & EXP_QUOTED) && n == CBACK)
6350                                 ) {
6351                                         USTPUTC(CTLESC, q);
6352                                 }
6353                         }
6354                 } else if (!(flags & EXP_KEEPNUL))
6355                         continue;
6356                 USTPUTC(c, q);
6357         } while (--len);
6358
6359         expdest = q;
6360         return q - s;
6361 }
6362
6363 static size_t
6364 strtodest(const char *p, int flags)
6365 {
6366         size_t len = strlen(p);
6367         memtodest(p, len, flags);
6368         return len;
6369 }
6370
6371 /*
6372  * Our own itoa().
6373  * cvtnum() is used even if math support is off (to prepare $? values and such).
6374  */
6375 static int
6376 cvtnum(arith_t num, int flags)
6377 {
6378         /* 32-bit and wider ints require buffer size of bytes*3 (or less) */
6379         /* If narrower: worst case, 1-byte ints: need 5 bytes: "-127<NUL>" */
6380         int len = (sizeof(arith_t) >= 4) ? sizeof(arith_t) * 3 : sizeof(arith_t) * 3 + 2;
6381         char buf[len];
6382
6383         len = fmtstr(buf, len, ARITH_FMT, num);
6384         return memtodest(buf, len, flags);
6385 }
6386
6387 /*
6388  * Record the fact that we have to scan this region of the
6389  * string for IFS characters.
6390  */
6391 static void
6392 recordregion(int start, int end, int nulonly)
6393 {
6394         struct ifsregion *ifsp;
6395
6396         if (ifslastp == NULL) {
6397                 ifsp = &ifsfirst;
6398         } else {
6399                 INT_OFF;
6400                 ifsp = ckzalloc(sizeof(*ifsp));
6401                 /*ifsp->next = NULL; - ckzalloc did it */
6402                 ifslastp->next = ifsp;
6403                 INT_ON;
6404         }
6405         ifslastp = ifsp;
6406         ifslastp->begoff = start;
6407         ifslastp->endoff = end;
6408         ifslastp->nulonly = nulonly;
6409 }
6410
6411 static void
6412 removerecordregions(int endoff)
6413 {
6414         if (ifslastp == NULL)
6415                 return;
6416
6417         if (ifsfirst.endoff > endoff) {
6418                 while (ifsfirst.next) {
6419                         struct ifsregion *ifsp;
6420                         INT_OFF;
6421                         ifsp = ifsfirst.next->next;
6422                         free(ifsfirst.next);
6423                         ifsfirst.next = ifsp;
6424                         INT_ON;
6425                 }
6426                 if (ifsfirst.begoff > endoff) {
6427                         ifslastp = NULL;
6428                 } else {
6429                         ifslastp = &ifsfirst;
6430                         ifsfirst.endoff = endoff;
6431                 }
6432                 return;
6433         }
6434
6435         ifslastp = &ifsfirst;
6436         while (ifslastp->next && ifslastp->next->begoff < endoff)
6437                 ifslastp = ifslastp->next;
6438         while (ifslastp->next) {
6439                 struct ifsregion *ifsp;
6440                 INT_OFF;
6441                 ifsp = ifslastp->next->next;
6442                 free(ifslastp->next);
6443                 ifslastp->next = ifsp;
6444                 INT_ON;
6445         }
6446         if (ifslastp->endoff > endoff)
6447                 ifslastp->endoff = endoff;
6448 }
6449
6450 static char *
6451 exptilde(char *startp, char *p, int flag)
6452 {
6453         unsigned char c;
6454         char *name;
6455         struct passwd *pw;
6456         const char *home;
6457
6458         name = p + 1;
6459
6460         while ((c = *++p) != '\0') {
6461                 switch (c) {
6462                 case CTLESC:
6463                         return startp;
6464                 case CTLQUOTEMARK:
6465                         return startp;
6466                 case ':':
6467                         if (flag & EXP_VARTILDE)
6468                                 goto done;
6469                         break;
6470                 case '/':
6471                 case CTLENDVAR:
6472                         goto done;
6473                 }
6474         }
6475  done:
6476         *p = '\0';
6477         if (*name == '\0') {
6478                 home = lookupvar("HOME");
6479         } else {
6480                 pw = getpwnam(name);
6481                 if (pw == NULL)
6482                         goto lose;
6483                 home = pw->pw_dir;
6484         }
6485         if (!home)
6486                 goto lose;
6487         *p = c;
6488         strtodest(home, flag | EXP_QUOTED);
6489         return p;
6490  lose:
6491         *p = c;
6492         return startp;
6493 }
6494
6495 /*
6496  * Execute a command inside back quotes.  If it's a builtin command, we
6497  * want to save its output in a block obtained from malloc.  Otherwise
6498  * we fork off a subprocess and get the output of the command via a pipe.
6499  * Should be called with interrupts off.
6500  */
6501 struct backcmd {                /* result of evalbackcmd */
6502         int fd;                 /* file descriptor to read from */
6503         int nleft;              /* number of chars in buffer */
6504         char *buf;              /* buffer */
6505         struct job *jp;         /* job structure for command */
6506 };
6507
6508 /* These forward decls are needed to use "eval" code for backticks handling: */
6509 /* flags in argument to evaltree */
6510 #define EV_EXIT    01           /* exit after evaluating tree */
6511 #define EV_TESTED  02           /* exit status is checked; ignore -e flag */
6512 static int evaltree(union node *, int);
6513
6514 /* An evaltree() which is known to never return.
6515  * Used to use an alias:
6516  * static int evaltreenr(union node *, int) __attribute__((alias("evaltree"),__noreturn__));
6517  * but clang was reported to "transfer" noreturn-ness to evaltree() as well.
6518  */
6519 static ALWAYS_INLINE NORETURN void
6520 evaltreenr(union node *n, int flags)
6521 {
6522         evaltree(n, flags);
6523         bb_unreachable(abort());
6524         /* NOTREACHED */
6525 }
6526
6527 static void FAST_FUNC
6528 evalbackcmd(union node *n, struct backcmd *result)
6529 {
6530         int pip[2];
6531         struct job *jp;
6532
6533         result->fd = -1;
6534         result->buf = NULL;
6535         result->nleft = 0;
6536         result->jp = NULL;
6537         if (n == NULL) {
6538                 goto out;
6539         }
6540
6541         if (pipe(pip) < 0)
6542                 ash_msg_and_raise_perror("can't create pipe");
6543         jp = makejob(/*n,*/ 1);
6544         if (forkshell(jp, n, FORK_NOJOB) == 0) {
6545                 /* child */
6546                 FORCE_INT_ON;
6547                 close(pip[0]);
6548                 if (pip[1] != 1) {
6549                         /*close(1);*/
6550                         dup2_or_raise(pip[1], 1);
6551                         close(pip[1]);
6552                 }
6553 /* TODO: eflag clearing makes the following not abort:
6554  *  ash -c 'set -e; z=$(false;echo foo); echo $z'
6555  * which is what bash does (unless it is in POSIX mode).
6556  * dash deleted "eflag = 0" line in the commit
6557  *  Date: Mon, 28 Jun 2010 17:11:58 +1000
6558  *  [EVAL] Don't clear eflag in evalbackcmd
6559  * For now, preserve bash-like behavior, it seems to be somewhat more useful:
6560  */
6561                 eflag = 0;
6562                 ifsfree();
6563                 evaltreenr(n, EV_EXIT);
6564                 /* NOTREACHED */
6565         }
6566         /* parent */
6567         close(pip[1]);
6568         result->fd = pip[0];
6569         result->jp = jp;
6570
6571  out:
6572         TRACE(("evalbackcmd done: fd=%d buf=0x%x nleft=%d jp=0x%x\n",
6573                 result->fd, result->buf, result->nleft, result->jp));
6574 }
6575
6576 /*
6577  * Expand stuff in backwards quotes.
6578  */
6579 static void
6580 expbackq(union node *cmd, int flag)
6581 {
6582         struct backcmd in;
6583         int i;
6584         char buf[128];
6585         char *p;
6586         char *dest;
6587         int startloc;
6588         struct stackmark smark;
6589
6590         INT_OFF;
6591         startloc = expdest - (char *)stackblock();
6592         pushstackmark(&smark, startloc);
6593         evalbackcmd(cmd, &in);
6594         popstackmark(&smark);
6595
6596         p = in.buf;
6597         i = in.nleft;
6598         if (i == 0)
6599                 goto read;
6600         for (;;) {
6601                 memtodest(p, i, flag);
6602  read:
6603                 if (in.fd < 0)
6604                         break;
6605                 i = nonblock_immune_read(in.fd, buf, sizeof(buf));
6606                 TRACE(("expbackq: read returns %d\n", i));
6607                 if (i <= 0)
6608                         break;
6609                 p = buf;
6610         }
6611
6612         free(in.buf);
6613         if (in.fd >= 0) {
6614                 close(in.fd);
6615                 back_exitstatus = waitforjob(in.jp);
6616         }
6617         INT_ON;
6618
6619         /* Eat all trailing newlines */
6620         dest = expdest;
6621         for (; dest > ((char *)stackblock() + startloc) && dest[-1] == '\n';)
6622                 STUNPUTC(dest);
6623         expdest = dest;
6624
6625         if (!(flag & EXP_QUOTED))
6626                 recordregion(startloc, dest - (char *)stackblock(), 0);
6627         TRACE(("evalbackq: size:%d:'%.*s'\n",
6628                 (int)((dest - (char *)stackblock()) - startloc),
6629                 (int)((dest - (char *)stackblock()) - startloc),
6630                 stackblock() + startloc));
6631 }
6632
6633 #if ENABLE_FEATURE_SH_MATH
6634 /*
6635  * Expand arithmetic expression.  Backup to start of expression,
6636  * evaluate, place result in (backed up) result, adjust string position.
6637  */
6638 static void
6639 expari(int flag)
6640 {
6641         char *p, *start;
6642         int begoff;
6643         int len;
6644
6645         /* ifsfree(); */
6646
6647         /*
6648          * This routine is slightly over-complicated for
6649          * efficiency.  Next we scan backwards looking for the
6650          * start of arithmetic.
6651          */
6652         start = stackblock();
6653         p = expdest - 1;
6654         *p = '\0';
6655         p--;
6656         while (1) {
6657                 int esc;
6658
6659                 while ((unsigned char)*p != CTLARI) {
6660                         p--;
6661 #if DEBUG
6662                         if (p < start) {
6663                                 ash_msg_and_raise_error("missing CTLARI (shouldn't happen)");
6664                         }
6665 #endif
6666                 }
6667
6668                 esc = esclen(start, p);
6669                 if (!(esc % 2)) {
6670                         break;
6671                 }
6672
6673                 p -= esc + 1;
6674         }
6675
6676         begoff = p - start;
6677
6678         removerecordregions(begoff);
6679
6680         expdest = p;
6681
6682         if (flag & QUOTES_ESC)
6683                 rmescapes(p + 1, 0, NULL);
6684
6685         len = cvtnum(ash_arith(p + 1), flag);
6686
6687         if (!(flag & EXP_QUOTED))
6688                 recordregion(begoff, begoff + len, 0);
6689 }
6690 #endif
6691
6692 /* argstr needs it */
6693 static char *evalvar(char *p, int flags);
6694
6695 /*
6696  * Perform variable and command substitution.  If EXP_FULL is set, output CTLESC
6697  * characters to allow for further processing.  Otherwise treat
6698  * $@ like $* since no splitting will be performed.
6699  */
6700 static void
6701 argstr(char *p, int flags)
6702 {
6703         static const char spclchars[] ALIGN1 = {
6704                 '=',
6705                 ':',
6706                 CTLQUOTEMARK,
6707                 CTLENDVAR,
6708                 CTLESC,
6709                 CTLVAR,
6710                 CTLBACKQ,
6711 #if ENABLE_FEATURE_SH_MATH
6712                 CTLENDARI,
6713 #endif
6714                 '\0'
6715         };
6716         const char *reject = spclchars;
6717         int breakall = (flags & (EXP_WORD | EXP_QUOTED)) == EXP_WORD;
6718         int inquotes;
6719         size_t length;
6720         int startloc;
6721
6722         if (!(flags & EXP_VARTILDE)) {
6723                 reject += 2;
6724         } else if (flags & EXP_VARTILDE2) {
6725                 reject++;
6726         }
6727         inquotes = 0;
6728         length = 0;
6729         if (flags & EXP_TILDE) {
6730                 char *q;
6731
6732                 flags &= ~EXP_TILDE;
6733  tilde:
6734                 q = p;
6735                 if (*q == '~')
6736                         p = exptilde(p, q, flags);
6737         }
6738  start:
6739         startloc = expdest - (char *)stackblock();
6740         for (;;) {
6741                 unsigned char c;
6742
6743                 length += strcspn(p + length, reject);
6744                 c = p[length];
6745                 if (c) {
6746                         if (!(c & 0x80)
6747                         IF_FEATURE_SH_MATH(|| c == CTLENDARI)
6748                         ) {
6749                                 /* c == '=' || c == ':' || c == CTLENDARI */
6750                                 length++;
6751                         }
6752                 }
6753                 if (length > 0) {
6754                         int newloc;
6755                         expdest = stack_nputstr(p, length, expdest);
6756                         newloc = expdest - (char *)stackblock();
6757                         if (breakall && !inquotes && newloc > startloc) {
6758                                 recordregion(startloc, newloc, 0);
6759                         }
6760                         startloc = newloc;
6761                 }
6762                 p += length + 1;
6763                 length = 0;
6764
6765                 switch (c) {
6766                 case '\0':
6767                         goto breakloop;
6768                 case '=':
6769                         if (flags & EXP_VARTILDE2) {
6770                                 p--;
6771                                 continue;
6772                         }
6773                         flags |= EXP_VARTILDE2;
6774                         reject++;
6775                         /* fall through */
6776                 case ':':
6777                         /*
6778                          * sort of a hack - expand tildes in variable
6779                          * assignments (after the first '=' and after ':'s).
6780                          */
6781                         if (*--p == '~') {
6782                                 goto tilde;
6783                         }
6784                         continue;
6785                 }
6786
6787                 switch (c) {
6788                 case CTLENDVAR: /* ??? */
6789                         goto breakloop;
6790                 case CTLQUOTEMARK:
6791                         /* "$@" syntax adherence hack */
6792                         if (!inquotes && !memcmp(p, dolatstr + 1, DOLATSTRLEN - 1)) {
6793                                 p = evalvar(p + 1, flags | EXP_QUOTED) + 1;
6794                                 goto start;
6795                         }
6796                         inquotes ^= EXP_QUOTED;
6797  addquote:
6798                         if (flags & QUOTES_ESC) {
6799                                 p--;
6800                                 length++;
6801                                 startloc++;
6802                         }
6803                         break;
6804                 case CTLESC:
6805                         startloc++;
6806                         length++;
6807                         goto addquote;
6808                 case CTLVAR:
6809                         TRACE(("argstr: evalvar('%s')\n", p));
6810                         p = evalvar(p, flags | inquotes);
6811                         TRACE(("argstr: evalvar:'%s'\n", (char *)stackblock()));
6812                         goto start;
6813                 case CTLBACKQ:
6814                         expbackq(argbackq->n, flags | inquotes);
6815                         argbackq = argbackq->next;
6816                         goto start;
6817 #if ENABLE_FEATURE_SH_MATH
6818                 case CTLENDARI:
6819                         p--;
6820                         expari(flags | inquotes);
6821                         goto start;
6822 #endif
6823                 }
6824         }
6825  breakloop: ;
6826 }
6827
6828 static char *
6829 scanleft(char *startp, char *rmesc, char *rmescend UNUSED_PARAM,
6830                 char *pattern, int quotes, int zero)
6831 {
6832         char *loc, *loc2;
6833         char c;
6834
6835         loc = startp;
6836         loc2 = rmesc;
6837         do {
6838                 int match;
6839                 const char *s = loc2;
6840
6841                 c = *loc2;
6842                 if (zero) {
6843                         *loc2 = '\0';
6844                         s = rmesc;
6845                 }
6846                 match = pmatch(pattern, s);
6847
6848                 *loc2 = c;
6849                 if (match)
6850                         return loc;
6851                 if (quotes && (unsigned char)*loc == CTLESC)
6852                         loc++;
6853                 loc++;
6854                 loc2++;
6855         } while (c);
6856         return NULL;
6857 }
6858
6859 static char *
6860 scanright(char *startp, char *rmesc, char *rmescend,
6861                 char *pattern, int quotes, int match_at_start)
6862 {
6863 #if !ENABLE_ASH_OPTIMIZE_FOR_SIZE
6864         int try2optimize = match_at_start;
6865 #endif
6866         int esc = 0;
6867         char *loc;
6868         char *loc2;
6869
6870         /* If we called by "${v/pattern/repl}" or "${v//pattern/repl}":
6871          * startp="escaped_value_of_v" rmesc="raw_value_of_v"
6872          * rmescend=""(ptr to NUL in rmesc) pattern="pattern" quotes=match_at_start=1
6873          * Logic:
6874          * loc starts at NUL at the end of startp, loc2 starts at the end of rmesc,
6875          * and on each iteration they go back two/one char until they reach the beginning.
6876          * We try to find a match in "raw_value_of_v", "raw_value_of_", "raw_value_of" etc.
6877          */
6878         /* TODO: document in what other circumstances we are called. */
6879
6880         for (loc = pattern - 1, loc2 = rmescend; loc >= startp; loc2--) {
6881                 int match;
6882                 char c = *loc2;
6883                 const char *s = loc2;
6884                 if (match_at_start) {
6885                         *loc2 = '\0';
6886                         s = rmesc;
6887                 }
6888                 match = pmatch(pattern, s);
6889                 //bb_error_msg("pmatch(pattern:'%s',s:'%s'):%d", pattern, s, match);
6890                 *loc2 = c;
6891                 if (match)
6892                         return loc;
6893 #if !ENABLE_ASH_OPTIMIZE_FOR_SIZE
6894                 if (try2optimize) {
6895                         /* Maybe we can optimize this:
6896                          * if pattern ends with unescaped *, we can avoid checking
6897                          * shorter strings: if "foo*" doesn't match "raw_value_of_v",
6898                          * it won't match truncated "raw_value_of_" strings too.
6899                          */
6900                         unsigned plen = strlen(pattern);
6901                         /* Does it end with "*"? */
6902                         if (plen != 0 && pattern[--plen] == '*') {
6903                                 /* "xxxx*" is not escaped */
6904                                 /* "xxx\*" is escaped */
6905                                 /* "xx\\*" is not escaped */
6906                                 /* "x\\\*" is escaped */
6907                                 int slashes = 0;
6908                                 while (plen != 0 && pattern[--plen] == '\\')
6909                                         slashes++;
6910                                 if (!(slashes & 1))
6911                                         break; /* ends with unescaped "*" */
6912                         }
6913                         try2optimize = 0;
6914                 }
6915 #endif
6916                 loc--;
6917                 if (quotes) {
6918                         if (--esc < 0) {
6919                                 esc = esclen(startp, loc);
6920                         }
6921                         if (esc % 2) {
6922                                 esc--;
6923                                 loc--;
6924                         }
6925                 }
6926         }
6927         return NULL;
6928 }
6929
6930 static void varunset(const char *, const char *, const char *, int) NORETURN;
6931 static void
6932 varunset(const char *end, const char *var, const char *umsg, int varflags)
6933 {
6934         const char *msg;
6935         const char *tail;
6936
6937         tail = nullstr;
6938         msg = "parameter not set";
6939         if (umsg) {
6940                 if ((unsigned char)*end == CTLENDVAR) {
6941                         if (varflags & VSNUL)
6942                                 tail = " or null";
6943                 } else {
6944                         msg = umsg;
6945                 }
6946         }
6947         ash_msg_and_raise_error("%.*s: %s%s", (int)(end - var - 1), var, msg, tail);
6948 }
6949
6950 static const char *
6951 subevalvar(char *p, char *varname, int strloc, int subtype,
6952                 int startloc, int varflags, int flag)
6953 {
6954         struct nodelist *saveargbackq = argbackq;
6955         int quotes = flag & QUOTES_ESC;
6956         char *startp;
6957         char *loc;
6958         char *rmesc, *rmescend;
6959         char *str;
6960         int amount, resetloc;
6961         int argstr_flags;
6962         IF_BASH_PATTERN_SUBST(int workloc;)
6963         IF_BASH_PATTERN_SUBST(int slash_pos;)
6964         IF_BASH_PATTERN_SUBST(char *repl;)
6965         int zero;
6966         char *(*scan)(char*, char*, char*, char*, int, int);
6967
6968         //bb_error_msg("subevalvar(p:'%s',varname:'%s',strloc:%d,subtype:%d,startloc:%d,varflags:%x,quotes:%d)",
6969         //              p, varname, strloc, subtype, startloc, varflags, quotes);
6970
6971 #if BASH_PATTERN_SUBST
6972         /* For "${v/pattern/repl}", we must find the delimiter _before_
6973          * argstr() call expands possible variable references in pattern:
6974          * think about "v=a; a=a/; echo ${v/$a/r}" case.
6975          */
6976         repl = NULL;
6977         if (subtype == VSREPLACE || subtype == VSREPLACEALL) {
6978                 /* Find '/' and replace with NUL */
6979                 repl = p;
6980                 /* The pattern can't be empty.
6981                  * IOW: if the first char after "${v//" is a slash,
6982                  * it does not terminate the pattern - it's the first char of the pattern:
6983                  *  v=/dev/ram; echo ${v////-}  prints -dev-ram (pattern is "/")
6984                  *  v=/dev/ram; echo ${v///r/-} prints /dev-am  (pattern is "/r")
6985                  */
6986                 if (*repl == '/')
6987                         repl++;
6988                 for (;;) {
6989                         if (*repl == '\0') {
6990                                 repl = NULL;
6991                                 break;
6992                         }
6993                         if (*repl == '/') {
6994                                 *repl = '\0';
6995                                 break;
6996                         }
6997                         /* Handle escaped slashes, e.g. "${v/\//_}" (they are CTLESC'ed by this point) */
6998                         if ((unsigned char)*repl == CTLESC && repl[1])
6999                                 repl++;
7000                         repl++;
7001                 }
7002         }
7003 #endif
7004         argstr_flags = EXP_TILDE;
7005         if (subtype != VSASSIGN
7006          && subtype != VSQUESTION
7007 #if BASH_SUBSTR
7008          && subtype != VSSUBSTR
7009 #endif
7010         ) {
7011                 /* EXP_CASE keeps CTLESC's */
7012                 argstr_flags = EXP_TILDE | EXP_CASE;
7013         }
7014         argstr(p, argstr_flags);
7015         //bb_error_msg("str0:'%s'", (char *)stackblock() + strloc);
7016 #if BASH_PATTERN_SUBST
7017         slash_pos = -1;
7018         if (repl) {
7019                 slash_pos = expdest - ((char *)stackblock() + strloc);
7020                 STPUTC('/', expdest);
7021                 //bb_error_msg("repl+1:'%s'", repl + 1);
7022                 argstr(repl + 1, EXP_TILDE); /* EXP_TILDE: echo "${v/x/~}" expands ~ ! */
7023                 *repl = '/';
7024         }
7025 #endif
7026         STPUTC('\0', expdest);
7027         argbackq = saveargbackq;
7028         startp = (char *)stackblock() + startloc;
7029         //bb_error_msg("str1:'%s'", (char *)stackblock() + strloc);
7030
7031         switch (subtype) {
7032         case VSASSIGN:
7033                 setvar0(varname, startp);
7034                 amount = startp - expdest;
7035                 STADJUST(amount, expdest);
7036                 return startp;
7037
7038         case VSQUESTION:
7039                 varunset(p, varname, startp, varflags);
7040                 /* NOTREACHED */
7041
7042 #if BASH_SUBSTR
7043         case VSSUBSTR: {
7044                 int pos, len, orig_len;
7045                 char *colon;
7046
7047                 loc = str = stackblock() + strloc;
7048
7049                 /* Read POS in ${var:POS:LEN} */
7050                 colon = strchr(loc, ':');
7051                 if (colon) *colon = '\0';
7052                 pos = substr_atoi(loc);
7053                 if (colon) *colon = ':';
7054
7055                 /* Read LEN in ${var:POS:LEN} */
7056                 len = str - startp - 1;
7057                 /* *loc != '\0', guaranteed by parser */
7058                 if (quotes) {
7059                         char *ptr;
7060                         /* Adjust the length by the number of escapes */
7061                         for (ptr = startp; ptr < (str - 1); ptr++) {
7062                                 if ((unsigned char)*ptr == CTLESC) {
7063                                         len--;
7064                                         ptr++;
7065                                 }
7066                         }
7067                 }
7068                 orig_len = len;
7069                 if (*loc++ == ':') {
7070                         /* ${var::LEN} */
7071                         len = substr_atoi(loc);
7072                 } else {
7073                         /* Skip POS in ${var:POS:LEN} */
7074                         len = orig_len;
7075                         while (*loc && *loc != ':')
7076                                 loc++;
7077                         if (*loc++ == ':')
7078                                 len = substr_atoi(loc);
7079                 }
7080                 if (pos < 0) {
7081                         /* ${VAR:$((-n)):l} starts n chars from the end */
7082                         pos = orig_len + pos;
7083                 }
7084                 if ((unsigned)pos >= orig_len) {
7085                         /* apart from obvious ${VAR:999999:l},
7086                          * covers ${VAR:$((-9999999)):l} - result is ""
7087                          * (bash compat)
7088                          */
7089                         pos = 0;
7090                         len = 0;
7091                 }
7092                 if (len < 0) {
7093                         /* ${VAR:N:-M} sets LEN to strlen()-M */
7094                         len = (orig_len - pos) + len;
7095                 }
7096                 if ((unsigned)len > (orig_len - pos))
7097                         len = orig_len - pos;
7098
7099                 for (str = startp; pos; str++, pos--) {
7100                         if (quotes && (unsigned char)*str == CTLESC)
7101                                 str++;
7102                 }
7103                 for (loc = startp; len; len--) {
7104                         if (quotes && (unsigned char)*str == CTLESC)
7105                                 *loc++ = *str++;
7106                         *loc++ = *str++;
7107                 }
7108                 *loc = '\0';
7109                 amount = loc - expdest;
7110                 STADJUST(amount, expdest);
7111                 return loc;
7112         }
7113 #endif /* BASH_SUBSTR */
7114         }
7115
7116         resetloc = expdest - (char *)stackblock();
7117
7118 #if BASH_PATTERN_SUBST
7119         repl = NULL;
7120
7121         /* We'll comeback here if we grow the stack while handling
7122          * a VSREPLACE or VSREPLACEALL, since our pointers into the
7123          * stack will need rebasing, and we'll need to remove our work
7124          * areas each time
7125          */
7126  restart:
7127 #endif
7128
7129         amount = expdest - ((char *)stackblock() + resetloc);
7130         STADJUST(-amount, expdest);
7131         startp = (char *)stackblock() + startloc;
7132
7133         rmesc = startp;
7134         rmescend = (char *)stackblock() + strloc;
7135         //bb_error_msg("str7:'%s'", rmescend);
7136         if (quotes) {
7137 //TODO: how to handle slash_pos here if string changes (shortens?)
7138                 rmesc = rmescapes(startp, RMESCAPE_ALLOC | RMESCAPE_GROW, NULL);
7139                 if (rmesc != startp) {
7140                         rmescend = expdest;
7141                         startp = (char *)stackblock() + startloc;
7142                 }
7143         }
7144         rmescend--;
7145         str = (char *)stackblock() + strloc;
7146         /*
7147          * Example: v='a\bc'; echo ${v/\\b/_\\_\z_}
7148          * The result is a_\_z_c (not a\_\_z_c)!
7149          *
7150          * The search pattern and replace string treat backslashes differently!
7151          * "&slash_pos" causes rmescapes() to work differently on the pattern
7152          * and string.  It's only used on the first call.
7153          */
7154         //bb_error_msg("str8:'%s' slash_pos:%d", str, slash_pos);
7155         rmescapes(str, RMESCAPE_GLOB,
7156                 repl ? NULL : (slash_pos < 0 ? NULL : &slash_pos)
7157         );
7158
7159 #if BASH_PATTERN_SUBST
7160         workloc = expdest - (char *)stackblock();
7161         if (subtype == VSREPLACE || subtype == VSREPLACEALL) {
7162                 int len;
7163                 char *idx, *end;
7164
7165                 if (!repl) {
7166                         //bb_error_msg("str9:'%s' slash_pos:%d", str, slash_pos);
7167                         repl = nullstr;
7168                         if (slash_pos >= 0) {
7169                                 repl = str + slash_pos;
7170                                 *repl++ = '\0';
7171                         }
7172                 }
7173                 //bb_error_msg("str:'%s' repl:'%s'", str, repl);
7174
7175                 /* If there's no pattern to match, return the expansion unmolested */
7176                 if (str[0] == '\0')
7177                         return NULL;
7178
7179                 len = 0;
7180                 idx = startp;
7181                 end = str - 1;
7182                 while (idx < end) {
7183  try_to_match:
7184                         loc = scanright(idx, rmesc, rmescend, str, quotes, 1);
7185                         //bb_error_msg("scanright('%s'):'%s'", str, loc);
7186                         if (!loc) {
7187                                 /* No match, advance */
7188                                 char *restart_detect = stackblock();
7189  skip_matching:
7190                                 STPUTC(*idx, expdest);
7191                                 if (quotes && (unsigned char)*idx == CTLESC) {
7192                                         idx++;
7193                                         len++;
7194                                         STPUTC(*idx, expdest);
7195                                 }
7196                                 if (stackblock() != restart_detect)
7197                                         goto restart;
7198                                 idx++;
7199                                 len++;
7200                                 rmesc++;
7201                                 /* continue; - prone to quadratic behavior, smarter code: */
7202                                 if (idx >= end)
7203                                         break;
7204                                 if (str[0] == '*') {
7205                                         /* Pattern is "*foo". If "*foo" does not match "long_string",
7206                                          * it would never match "ong_string" etc, no point in trying.
7207                                          */
7208                                         goto skip_matching;
7209                                 }
7210                                 goto try_to_match;
7211                         }
7212
7213                         if (subtype == VSREPLACEALL) {
7214                                 while (idx < loc) {
7215                                         if (quotes && (unsigned char)*idx == CTLESC)
7216                                                 idx++;
7217                                         idx++;
7218                                         rmesc++;
7219                                 }
7220                         } else {
7221                                 idx = loc;
7222                         }
7223
7224                         //bb_error_msg("repl:'%s'", repl);
7225                         for (loc = (char*)repl; *loc; loc++) {
7226                                 char *restart_detect = stackblock();
7227                                 if (quotes && *loc == '\\') {
7228                                         STPUTC(CTLESC, expdest);
7229                                         len++;
7230                                 }
7231                                 STPUTC(*loc, expdest);
7232                                 if (stackblock() != restart_detect)
7233                                         goto restart;
7234                                 len++;
7235                         }
7236
7237                         if (subtype == VSREPLACE) {
7238                                 //bb_error_msg("tail:'%s', quotes:%x", idx, quotes);
7239                                 while (*idx) {
7240                                         char *restart_detect = stackblock();
7241                                         STPUTC(*idx, expdest);
7242                                         if (stackblock() != restart_detect)
7243                                                 goto restart;
7244                                         len++;
7245                                         idx++;
7246                                 }
7247                                 break;
7248                         }
7249                 }
7250
7251                 /* We've put the replaced text into a buffer at workloc, now
7252                  * move it to the right place and adjust the stack.
7253                  */
7254                 STPUTC('\0', expdest);
7255                 startp = (char *)stackblock() + startloc;
7256                 memmove(startp, (char *)stackblock() + workloc, len + 1);
7257                 //bb_error_msg("startp:'%s'", startp);
7258                 amount = expdest - (startp + len);
7259                 STADJUST(-amount, expdest);
7260                 return startp;
7261         }
7262 #endif /* BASH_PATTERN_SUBST */
7263
7264         subtype -= VSTRIMRIGHT;
7265 #if DEBUG
7266         if (subtype < 0 || subtype > 7)
7267                 abort();
7268 #endif
7269         /* zero = (subtype == VSTRIMLEFT || subtype == VSTRIMLEFTMAX) */
7270         zero = subtype >> 1;
7271         /* VSTRIMLEFT/VSTRIMRIGHTMAX -> scanleft */
7272         scan = (subtype & 1) ^ zero ? scanleft : scanright;
7273
7274         loc = scan(startp, rmesc, rmescend, str, quotes, zero);
7275         if (loc) {
7276                 if (zero) {
7277                         memmove(startp, loc, str - loc);
7278                         loc = startp + (str - loc) - 1;
7279                 }
7280                 *loc = '\0';
7281                 amount = loc - expdest;
7282                 STADJUST(amount, expdest);
7283         }
7284         return loc;
7285 }
7286
7287 /*
7288  * Add the value of a specialized variable to the stack string.
7289  * name parameter (examples):
7290  * ash -c 'echo $1'      name:'1='
7291  * ash -c 'echo $qwe'    name:'qwe='
7292  * ash -c 'echo $$'      name:'$='
7293  * ash -c 'echo ${$}'    name:'$='
7294  * ash -c 'echo ${$##q}' name:'$=q'
7295  * ash -c 'echo ${#$}'   name:'$='
7296  * note: examples with bad shell syntax:
7297  * ash -c 'echo ${#$1}'  name:'$=1'
7298  * ash -c 'echo ${#1#}'  name:'1=#'
7299  */
7300 static NOINLINE ssize_t
7301 varvalue(char *name, int varflags, int flags, int quoted)
7302 {
7303         const char *p;
7304         int num;
7305         int i;
7306         ssize_t len = 0;
7307         int sep;
7308         int subtype = varflags & VSTYPE;
7309         int discard = subtype == VSPLUS || subtype == VSLENGTH;
7310
7311         flags |= EXP_KEEPNUL;
7312         flags &= discard ? ~QUOTES_ESC : ~0;
7313         sep = (flags & EXP_FULL) << CHAR_BIT;
7314
7315         switch (*name) {
7316         case '$':
7317                 num = rootpid;
7318                 goto numvar;
7319         case '?':
7320                 num = exitstatus;
7321                 goto numvar;
7322         case '#':
7323                 num = shellparam.nparam;
7324                 goto numvar;
7325         case '!':
7326                 num = backgndpid;
7327                 if (num == 0)
7328                         return -1;
7329  numvar:
7330                 len = cvtnum(num, flags);
7331                 goto check_1char_name;
7332         case '-':
7333                 expdest = makestrspace(NOPTS, expdest);
7334                 for (i = NOPTS - 1; i >= 0; i--) {
7335                         if (optlist[i] && optletters(i)) {
7336                                 USTPUTC(optletters(i), expdest);
7337                                 len++;
7338                         }
7339                 }
7340  check_1char_name:
7341 #if 0
7342                 /* handles cases similar to ${#$1} */
7343                 if (name[2] != '\0')
7344                         raise_error_syntax("bad substitution");
7345 #endif
7346                 break;
7347         case '@':
7348                 if (quoted && sep)
7349                         goto param;
7350                 /* fall through */
7351         case '*': {
7352                 char **ap;
7353                 char sepc;
7354                 char c;
7355
7356                 /* We will set c to 0 or ~0 depending on whether
7357                  * we're doing field splitting.  We won't do field
7358                  * splitting if either we're quoted or sep is zero.
7359                  *
7360                  * Instead of testing (quoted || !sep) the following
7361                  * trick optimises away any branches by using the
7362                  * fact that EXP_QUOTED (which is the only bit that
7363                  * can be set in quoted) is the same as EXP_FULL <<
7364                  * CHAR_BIT (which is the only bit that can be set
7365                  * in sep).
7366                  */
7367 #if EXP_QUOTED >> CHAR_BIT != EXP_FULL
7368 #error The following two lines expect EXP_QUOTED == EXP_FULL << CHAR_BIT
7369 #endif
7370                 c = !((quoted | ~sep) & EXP_QUOTED) - 1;
7371                 sep &= ~quoted;
7372                 sep |= ifsset() ? (unsigned char)(c & ifsval()[0]) : ' ';
7373  param:
7374                 sepc = sep;
7375                 ap = shellparam.p;
7376                 if (!ap)
7377                         return -1;
7378                 while ((p = *ap++) != NULL) {
7379                         len += strtodest(p, flags);
7380
7381                         if (*ap && sep) {
7382                                 len++;
7383                                 memtodest(&sepc, 1, flags);
7384                         }
7385                 }
7386                 break;
7387         } /* case '*' */
7388         case '0':
7389         case '1':
7390         case '2':
7391         case '3':
7392         case '4':
7393         case '5':
7394         case '6':
7395         case '7':
7396         case '8':
7397         case '9':
7398                 num = atoi(name); /* number(name) fails on ${N#str} etc */
7399                 if (num < 0 || num > shellparam.nparam)
7400                         return -1;
7401                 p = num ? shellparam.p[num - 1] : arg0;
7402                 goto value;
7403         default:
7404                 /* NB: name has form "VAR=..." */
7405                 p = lookupvar(name);
7406  value:
7407                 if (!p)
7408                         return -1;
7409
7410                 len = strtodest(p, flags);
7411 #if ENABLE_UNICODE_SUPPORT
7412                 if (subtype == VSLENGTH && len > 0) {
7413                         reinit_unicode_for_ash();
7414                         if (unicode_status == UNICODE_ON) {
7415                                 STADJUST(-len, expdest);
7416                                 discard = 0;
7417                                 len = unicode_strlen(p);
7418                         }
7419                 }
7420 #endif
7421                 break;
7422         }
7423
7424         if (discard)
7425                 STADJUST(-len, expdest);
7426         return len;
7427 }
7428
7429 /*
7430  * Expand a variable, and return a pointer to the next character in the
7431  * input string.
7432  */
7433 static char *
7434 evalvar(char *p, int flag)
7435 {
7436         char varflags;
7437         char subtype;
7438         int quoted;
7439         char *var;
7440         int patloc;
7441         int startloc;
7442         ssize_t varlen;
7443
7444         varflags = (unsigned char) *p++;
7445         subtype = varflags & VSTYPE;
7446
7447         if (!subtype)
7448                 raise_error_syntax("bad substitution");
7449
7450         quoted = flag & EXP_QUOTED;
7451         var = p;
7452         startloc = expdest - (char *)stackblock();
7453         p = strchr(p, '=') + 1; //TODO: use var_end(p)?
7454
7455  again:
7456         varlen = varvalue(var, varflags, flag, quoted);
7457         if (varflags & VSNUL)
7458                 varlen--;
7459
7460         if (subtype == VSPLUS) {
7461                 varlen = -1 - varlen;
7462                 goto vsplus;
7463         }
7464
7465         if (subtype == VSMINUS) {
7466  vsplus:
7467                 if (varlen < 0) {
7468                         argstr(
7469                                 p,
7470                                 flag | EXP_TILDE | EXP_WORD
7471                         );
7472                         goto end;
7473                 }
7474                 goto record;
7475         }
7476
7477         if (subtype == VSASSIGN || subtype == VSQUESTION) {
7478                 if (varlen >= 0)
7479                         goto record;
7480
7481                 subevalvar(p, var, 0, subtype, startloc, varflags,
7482                            flag & ~QUOTES_ESC);
7483                 varflags &= ~VSNUL;
7484                 /*
7485                  * Remove any recorded regions beyond
7486                  * start of variable
7487                  */
7488                 removerecordregions(startloc);
7489                 goto again;
7490         }
7491
7492         if (varlen < 0 && uflag)
7493                 varunset(p, var, 0, 0);
7494
7495         if (subtype == VSLENGTH) {
7496                 cvtnum(varlen > 0 ? varlen : 0, flag);
7497                 goto record;
7498         }
7499
7500         if (subtype == VSNORMAL) {
7501  record:
7502                 if (quoted) {
7503                         quoted = *var == '@' && shellparam.nparam;
7504                         if (!quoted)
7505                                 goto end;
7506                 }
7507                 recordregion(startloc, expdest - (char *)stackblock(), quoted);
7508                 goto end;
7509         }
7510
7511 #if DEBUG
7512         switch (subtype) {
7513         case VSTRIMLEFT:
7514         case VSTRIMLEFTMAX:
7515         case VSTRIMRIGHT:
7516         case VSTRIMRIGHTMAX:
7517 #if BASH_SUBSTR
7518         case VSSUBSTR:
7519 #endif
7520 #if BASH_PATTERN_SUBST
7521         case VSREPLACE:
7522         case VSREPLACEALL:
7523 #endif
7524                 break;
7525         default:
7526                 abort();
7527         }
7528 #endif
7529
7530         if (varlen >= 0) {
7531                 /*
7532                  * Terminate the string and start recording the pattern
7533                  * right after it
7534                  */
7535                 STPUTC('\0', expdest);
7536                 patloc = expdest - (char *)stackblock();
7537                 if (NULL == subevalvar(p, /* varname: */ NULL, patloc, subtype,
7538                                 startloc, varflags, flag)) {
7539                         int amount = expdest - (
7540                                 (char *)stackblock() + patloc - 1
7541                         );
7542                         STADJUST(-amount, expdest);
7543                 }
7544                 /* Remove any recorded regions beyond start of variable */
7545                 removerecordregions(startloc);
7546                 goto record;
7547         }
7548
7549         varlen = 0;
7550
7551  end:
7552         if (subtype != VSNORMAL) {      /* skip to end of alternative */
7553                 int nesting = 1;
7554                 for (;;) {
7555                         unsigned char c = *p++;
7556                         if (c == CTLESC)
7557                                 p++;
7558                         else if (c == CTLBACKQ) {
7559                                 if (varlen >= 0)
7560                                         argbackq = argbackq->next;
7561                         } else if (c == CTLVAR) {
7562                                 if ((*p++ & VSTYPE) != VSNORMAL)
7563                                         nesting++;
7564                         } else if (c == CTLENDVAR) {
7565                                 if (--nesting == 0)
7566                                         break;
7567                         }
7568                 }
7569         }
7570         return p;
7571 }
7572
7573 /*
7574  * Add a file name to the list.
7575  */
7576 static void
7577 addfname(const char *name)
7578 {
7579         struct strlist *sp;
7580
7581         sp = stzalloc(sizeof(*sp));
7582         sp->text = sstrdup(name);
7583         *exparg.lastp = sp;
7584         exparg.lastp = &sp->next;
7585 }
7586
7587 /* Avoid glob() (and thus, stat() et al) for words like "echo" */
7588 static int
7589 hasmeta(const char *p)
7590 {
7591         static const char chars[] ALIGN1 = {
7592                 '*', '?', '[', '\\', CTLQUOTEMARK, CTLESC, 0
7593         };
7594
7595         for (;;) {
7596                 p = strpbrk(p, chars);
7597                 if (!p)
7598                         break;
7599                 switch ((unsigned char)*p) {
7600                 case CTLQUOTEMARK:
7601                         for (;;) {
7602                                 p++;
7603                                 if ((unsigned char)*p == CTLQUOTEMARK)
7604                                         break;
7605                                 if ((unsigned char)*p == CTLESC)
7606                                         p++;
7607                                 if (*p == '\0') /* huh? */
7608                                         return 0;
7609                         }
7610                         break;
7611                 case '\\':
7612                 case CTLESC:
7613                         p++;
7614                         if (*p == '\0')
7615                                 return 0;
7616                         break;
7617                 case '[':
7618                         if (!strchr(p + 1, ']')) {
7619                                 /* It's not a properly closed [] pattern,
7620                                  * but other metas may follow. Continue checking.
7621                                  * my[file* _is_ globbed by bash
7622                                  * and matches filenames like "my[file1".
7623                                  */
7624                                 break;
7625                         }
7626                         /* fallthrough */
7627                 default:
7628                 /* case '*': */
7629                 /* case '?': */
7630                         return 1;
7631                 }
7632                 p++;
7633         }
7634
7635         return 0;
7636 }
7637
7638 /* If we want to use glob() from libc... */
7639 #if !ENABLE_ASH_INTERNAL_GLOB
7640
7641 /* Add the result of glob() to the list */
7642 static void
7643 addglob(const glob_t *pglob)
7644 {
7645         char **p = pglob->gl_pathv;
7646
7647         do {
7648                 addfname(*p);
7649         } while (*++p);
7650 }
7651 static void
7652 expandmeta(struct strlist *str /*, int flag*/)
7653 {
7654         /* TODO - EXP_REDIR */
7655
7656         while (str) {
7657                 char *p;
7658                 glob_t pglob;
7659                 int i;
7660
7661                 if (fflag)
7662                         goto nometa;
7663
7664                 if (!hasmeta(str->text))
7665                         goto nometa;
7666
7667                 INT_OFF;
7668                 p = preglob(str->text, RMESCAPE_ALLOC | RMESCAPE_HEAP);
7669 // GLOB_NOMAGIC (GNU): if no *?[ chars in pattern, return it even if no match
7670 // GLOB_NOCHECK: if no match, return unchanged pattern (sans \* escapes?)
7671 //
7672 // glibc 2.24.90 glob(GLOB_NOMAGIC) does not remove backslashes used for escaping:
7673 // if you pass it "file\?", it returns "file\?", not "file?", if no match.
7674 // Which means you need to unescape the string, right? Not so fast:
7675 // if there _is_ a file named "file\?" (with backslash), it is returned
7676 // as "file\?" too (whichever pattern you used to find it, say, "file*").
7677 // You DON'T KNOW by looking at the result whether you need to unescape it.
7678 //
7679 // Worse, globbing of "file\?" in a directory with two files, "file?" and "file\?",
7680 // returns "file\?" - which is WRONG: "file\?" pattern matches "file?" file.
7681 // Without GLOB_NOMAGIC, this works correctly ("file?" is returned as a match).
7682 // With GLOB_NOMAGIC | GLOB_NOCHECK, this also works correctly.
7683 //              i = glob(p, GLOB_NOMAGIC | GLOB_NOCHECK, NULL, &pglob);
7684 //              i = glob(p, GLOB_NOMAGIC, NULL, &pglob);
7685                 i = glob(p, 0, NULL, &pglob);
7686                 //bb_error_msg("glob('%s'):%d '%s'...", p, i, pglob.gl_pathv ? pglob.gl_pathv[0] : "-");
7687                 if (p != str->text)
7688                         free(p);
7689                 switch (i) {
7690                 case 0:
7691 #if 0 // glibc 2.24.90 bug? Patterns like "*/file", when match, don't set GLOB_MAGCHAR
7692                         /* GLOB_MAGCHAR is set if *?[ chars were seen (GNU) */
7693                         if (!(pglob.gl_flags & GLOB_MAGCHAR))
7694                                 goto nometa2;
7695 #endif
7696                         addglob(&pglob);
7697                         globfree(&pglob);
7698                         INT_ON;
7699                         break;
7700                 case GLOB_NOMATCH:
7701  //nometa2:
7702                         globfree(&pglob);
7703                         INT_ON;
7704  nometa:
7705                         *exparg.lastp = str;
7706                         rmescapes(str->text, 0, NULL);
7707                         exparg.lastp = &str->next;
7708                         break;
7709                 default:        /* GLOB_NOSPACE */
7710                         globfree(&pglob);
7711                         INT_ON;
7712                         ash_msg_and_raise_error(bb_msg_memory_exhausted);
7713                 }
7714                 str = str->next;
7715         }
7716 }
7717
7718 #else
7719 /* ENABLE_ASH_INTERNAL_GLOB: Homegrown globbing code. (dash also has both, uses homegrown one.) */
7720
7721 /*
7722  * Do metacharacter (i.e. *, ?, [...]) expansion.
7723  */
7724 typedef struct exp_t {
7725         char *dir;
7726         unsigned dir_max;
7727 } exp_t;
7728 static void
7729 expmeta(exp_t *exp, char *name, unsigned name_len, unsigned expdir_len)
7730 {
7731 #define expdir exp->dir
7732 #define expdir_max exp->dir_max
7733         char *enddir = expdir + expdir_len;
7734         char *p;
7735         const char *cp;
7736         char *start;
7737         char *endname;
7738         int metaflag;
7739         struct stat statb;
7740         DIR *dirp;
7741         struct dirent *dp;
7742         int atend;
7743         int matchdot;
7744         int esc;
7745
7746         metaflag = 0;
7747         start = name;
7748         for (p = name; esc = 0, *p; p += esc + 1) {
7749                 if (*p == '*' || *p == '?')
7750                         metaflag = 1;
7751                 else if (*p == '[') {
7752                         char *q = p + 1;
7753                         if (*q == '!')
7754                                 q++;
7755                         for (;;) {
7756                                 if (*q == '\\')
7757                                         q++;
7758                                 if (*q == '/' || *q == '\0')
7759                                         break;
7760                                 if (*++q == ']') {
7761                                         metaflag = 1;
7762                                         break;
7763                                 }
7764                         }
7765                 } else {
7766                         if (*p == '\\' && p[1])
7767                                 esc++;
7768                         if (p[esc] == '/') {
7769                                 if (metaflag)
7770                                         break;
7771                                 start = p + esc + 1;
7772                         }
7773                 }
7774         }
7775         if (metaflag == 0) {    /* we've reached the end of the file name */
7776                 if (!expdir_len)
7777                         return;
7778                 p = name;
7779                 do {
7780                         if (*p == '\\' && p[1])
7781                                 p++;
7782                         *enddir++ = *p;
7783                 } while (*p++);
7784                 if (lstat(expdir, &statb) == 0)
7785                         addfname(expdir);
7786                 return;
7787         }
7788         endname = p;
7789         if (name < start) {
7790                 p = name;
7791                 do {
7792                         if (*p == '\\' && p[1])
7793                                 p++;
7794                         *enddir++ = *p++;
7795                 } while (p < start);
7796         }
7797         *enddir = '\0';
7798         cp = expdir;
7799         expdir_len = enddir - cp;
7800         if (!expdir_len)
7801                 cp = ".";
7802         dirp = opendir(cp);
7803         if (dirp == NULL)
7804                 return;
7805         if (*endname == 0) {
7806                 atend = 1;
7807         } else {
7808                 atend = 0;
7809                 *endname = '\0';
7810                 endname += esc + 1;
7811         }
7812         name_len -= endname - name;
7813         matchdot = 0;
7814         p = start;
7815         if (*p == '\\')
7816                 p++;
7817         if (*p == '.')
7818                 matchdot++;
7819         while (!pending_int && (dp = readdir(dirp)) != NULL) {
7820                 if (dp->d_name[0] == '.' && !matchdot)
7821                         continue;
7822                 if (pmatch(start, dp->d_name)) {
7823                         if (atend) {
7824                                 strcpy(enddir, dp->d_name);
7825                                 addfname(expdir);
7826                         } else {
7827                                 unsigned offset;
7828                                 unsigned len;
7829
7830                                 p = stpcpy(enddir, dp->d_name);
7831                                 *p = '/';
7832
7833                                 offset = p - expdir + 1;
7834                                 len = offset + name_len + NAME_MAX;
7835                                 if (len > expdir_max) {
7836                                         len += PATH_MAX;
7837                                         expdir = ckrealloc(expdir, len);
7838                                         expdir_max = len;
7839                                 }
7840
7841                                 expmeta(exp, endname, name_len, offset);
7842                                 enddir = expdir + expdir_len;
7843                         }
7844                 }
7845         }
7846         closedir(dirp);
7847         if (!atend)
7848                 endname[-esc - 1] = esc ? '\\' : '/';
7849 #undef expdir
7850 #undef expdir_max
7851 }
7852
7853 static struct strlist *
7854 msort(struct strlist *list, int len)
7855 {
7856         struct strlist *p, *q = NULL;
7857         struct strlist **lpp;
7858         int half;
7859         int n;
7860
7861         if (len <= 1)
7862                 return list;
7863         half = len >> 1;
7864         p = list;
7865         for (n = half; --n >= 0;) {
7866                 q = p;
7867                 p = p->next;
7868         }
7869         q->next = NULL;                 /* terminate first half of list */
7870         q = msort(list, half);          /* sort first half of list */
7871         p = msort(p, len - half);               /* sort second half */
7872         lpp = &list;
7873         for (;;) {
7874 #if ENABLE_LOCALE_SUPPORT
7875                 if (strcoll(p->text, q->text) < 0)
7876 #else
7877                 if (strcmp(p->text, q->text) < 0)
7878 #endif
7879                                                 {
7880                         *lpp = p;
7881                         lpp = &p->next;
7882                         p = *lpp;
7883                         if (p == NULL) {
7884                                 *lpp = q;
7885                                 break;
7886                         }
7887                 } else {
7888                         *lpp = q;
7889                         lpp = &q->next;
7890                         q = *lpp;
7891                         if (q == NULL) {
7892                                 *lpp = p;
7893                                 break;
7894                         }
7895                 }
7896         }
7897         return list;
7898 }
7899
7900 /*
7901  * Sort the results of file name expansion.  It calculates the number of
7902  * strings to sort and then calls msort (short for merge sort) to do the
7903  * work.
7904  */
7905 static struct strlist *
7906 expsort(struct strlist *str)
7907 {
7908         int len;
7909         struct strlist *sp;
7910
7911         len = 0;
7912         for (sp = str; sp; sp = sp->next)
7913                 len++;
7914         return msort(str, len);
7915 }
7916
7917 static void
7918 expandmeta(struct strlist *str /*, int flag*/)
7919 {
7920         /* TODO - EXP_REDIR */
7921
7922         while (str) {
7923                 exp_t exp;
7924                 struct strlist **savelastp;
7925                 struct strlist *sp;
7926                 char *p;
7927                 unsigned len;
7928
7929                 if (fflag)
7930                         goto nometa;
7931                 if (!hasmeta(str->text))
7932                         goto nometa;
7933                 savelastp = exparg.lastp;
7934
7935                 INT_OFF;
7936                 p = preglob(str->text, RMESCAPE_ALLOC | RMESCAPE_HEAP);
7937                 len = strlen(p);
7938                 exp.dir_max = len + PATH_MAX;
7939                 exp.dir = ckmalloc(exp.dir_max);
7940
7941                 expmeta(&exp, p, len, 0);
7942                 free(exp.dir);
7943                 if (p != str->text)
7944                         free(p);
7945                 INT_ON;
7946                 if (exparg.lastp == savelastp) {
7947                         /*
7948                          * no matches
7949                          */
7950  nometa:
7951                         *exparg.lastp = str;
7952                         rmescapes(str->text, 0, NULL);
7953                         exparg.lastp = &str->next;
7954                 } else {
7955                         *exparg.lastp = NULL;
7956                         *savelastp = sp = expsort(*savelastp);
7957                         while (sp->next != NULL)
7958                                 sp = sp->next;
7959                         exparg.lastp = &sp->next;
7960                 }
7961                 str = str->next;
7962         }
7963 }
7964 #endif /* ENABLE_ASH_INTERNAL_GLOB */
7965
7966 /*
7967  * Perform variable substitution and command substitution on an argument,
7968  * placing the resulting list of arguments in arglist.  If EXP_FULL is true,
7969  * perform splitting and file name expansion.  When arglist is NULL, perform
7970  * here document expansion.
7971  */
7972 static void
7973 expandarg(union node *arg, struct arglist *arglist, int flag)
7974 {
7975         struct strlist *sp;
7976         char *p;
7977
7978         argbackq = arg->narg.backquote;
7979         STARTSTACKSTR(expdest);
7980         TRACE(("expandarg: argstr('%s',flags:%x)\n", arg->narg.text, flag));
7981         argstr(arg->narg.text, flag);
7982         p = _STPUTC('\0', expdest);
7983         expdest = p - 1;
7984         if (arglist == NULL) {
7985                 /* here document expanded */
7986                 goto out;
7987         }
7988         p = grabstackstr(p);
7989         TRACE(("expandarg: p:'%s'\n", p));
7990         exparg.lastp = &exparg.list;
7991         /*
7992          * TODO - EXP_REDIR
7993          */
7994         if (flag & EXP_FULL) {
7995                 ifsbreakup(p, &exparg);
7996                 *exparg.lastp = NULL;
7997                 exparg.lastp = &exparg.list;
7998                 expandmeta(exparg.list /*, flag*/);
7999         } else {
8000                 sp = stzalloc(sizeof(*sp));
8001                 sp->text = p;
8002                 *exparg.lastp = sp;
8003                 exparg.lastp = &sp->next;
8004         }
8005         *exparg.lastp = NULL;
8006         if (exparg.list) {
8007                 *arglist->lastp = exparg.list;
8008                 arglist->lastp = exparg.lastp;
8009         }
8010
8011  out:
8012         ifsfree();
8013 }
8014
8015 /*
8016  * Expand shell variables and backquotes inside a here document.
8017  */
8018 static void
8019 expandhere(union node *arg, int fd)
8020 {
8021         expandarg(arg, (struct arglist *)NULL, EXP_QUOTED);
8022         full_write(fd, stackblock(), expdest - (char *)stackblock());
8023 }
8024
8025 /*
8026  * Returns true if the pattern matches the string.
8027  */
8028 static int
8029 patmatch(char *pattern, const char *string)
8030 {
8031         char *p = preglob(pattern, 0);
8032         int r = pmatch(p, string);
8033         //bb_error_msg("!fnmatch(pattern:'%s',str:'%s',0):%d", p, string, r);
8034         return r;
8035 }
8036
8037 /*
8038  * See if a pattern matches in a case statement.
8039  */
8040 static int
8041 casematch(union node *pattern, char *val)
8042 {
8043         struct stackmark smark;
8044         int result;
8045
8046         setstackmark(&smark);
8047         argbackq = pattern->narg.backquote;
8048         STARTSTACKSTR(expdest);
8049         argstr(pattern->narg.text, EXP_TILDE | EXP_CASE);
8050         STACKSTRNUL(expdest);
8051         ifsfree();
8052         result = patmatch(stackblock(), val);
8053         popstackmark(&smark);
8054         return result;
8055 }
8056
8057
8058 /* ============ find_command */
8059
8060 struct builtincmd {
8061         const char *name;
8062         int (*builtin)(int, char **) FAST_FUNC;
8063         /* unsigned flags; */
8064 };
8065 #define IS_BUILTIN_SPECIAL(b) ((b)->name[0] & 1)
8066 /* "regular" builtins always take precedence over commands,
8067  * regardless of PATH=....%builtin... position */
8068 #define IS_BUILTIN_REGULAR(b) ((b)->name[0] & 2)
8069 #define IS_BUILTIN_ASSIGN(b)  ((b)->name[0] & 4)
8070
8071 struct cmdentry {
8072         smallint cmdtype;       /* CMDxxx */
8073         union param {
8074                 int index;
8075                 /* index >= 0 for commands without path (slashes) */
8076                 /* (TODO: what exactly does the value mean? PATH position?) */
8077                 /* index == -1 for commands with slashes */
8078                 /* index == (-2 - applet_no) for NOFORK applets */
8079                 const struct builtincmd *cmd;
8080                 struct funcnode *func;
8081         } u;
8082 };
8083 /* values of cmdtype */
8084 #define CMDUNKNOWN      -1      /* no entry in table for command */
8085 #define CMDNORMAL       0       /* command is an executable program */
8086 #define CMDFUNCTION     1       /* command is a shell function */
8087 #define CMDBUILTIN      2       /* command is a shell builtin */
8088
8089 /* action to find_command() */
8090 #define DO_ERR          0x01    /* prints errors */
8091 #define DO_ABS          0x02    /* checks absolute paths */
8092 #define DO_NOFUNC       0x04    /* don't return shell functions, for command */
8093 #define DO_ALTPATH      0x08    /* using alternate path */
8094 #define DO_REGBLTIN     0x10    /* regular built-ins and functions only */
8095
8096 static void find_command(char *, struct cmdentry *, int, const char *);
8097
8098
8099 /* ============ Hashing commands */
8100
8101 /*
8102  * When commands are first encountered, they are entered in a hash table.
8103  * This ensures that a full path search will not have to be done for them
8104  * on each invocation.
8105  *
8106  * We should investigate converting to a linear search, even though that
8107  * would make the command name "hash" a misnomer.
8108  */
8109
8110 struct tblentry {
8111         struct tblentry *next;  /* next entry in hash chain */
8112         union param param;      /* definition of builtin function */
8113         smallint cmdtype;       /* CMDxxx */
8114         char rehash;            /* if set, cd done since entry created */
8115         char cmdname[1];        /* name of command */
8116 };
8117
8118 static struct tblentry **cmdtable;
8119 #define INIT_G_cmdtable() do { \
8120         cmdtable = xzalloc(CMDTABLESIZE * sizeof(cmdtable[0])); \
8121 } while (0)
8122
8123 static int builtinloc = -1;     /* index in path of %builtin, or -1 */
8124
8125
8126 static void
8127 tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) const char *cmd, char **argv, char **envp)
8128 {
8129 #if ENABLE_FEATURE_SH_STANDALONE
8130         if (applet_no >= 0) {
8131                 if (APPLET_IS_NOEXEC(applet_no)) {
8132                         clearenv();
8133                         while (*envp)
8134                                 putenv(*envp++);
8135                         popredir(/*drop:*/ 1);
8136                         run_noexec_applet_and_exit(applet_no, cmd, argv);
8137                 }
8138                 /* re-exec ourselves with the new arguments */
8139                 execve(bb_busybox_exec_path, argv, envp);
8140                 /* If they called chroot or otherwise made the binary no longer
8141                  * executable, fall through */
8142         }
8143 #endif
8144
8145  repeat:
8146 #ifdef SYSV
8147         do {
8148                 execve(cmd, argv, envp);
8149         } while (errno == EINTR);
8150 #else
8151         execve(cmd, argv, envp);
8152 #endif
8153
8154         if (cmd != bb_busybox_exec_path && errno == ENOEXEC) {
8155                 /* Run "cmd" as a shell script:
8156                  * http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html
8157                  * "If the execve() function fails with ENOEXEC, the shell
8158                  * shall execute a command equivalent to having a shell invoked
8159                  * with the command name as its first operand,
8160                  * with any remaining arguments passed to the new shell"
8161                  *
8162                  * That is, do not use $SHELL, user's shell, or /bin/sh;
8163                  * just call ourselves.
8164                  *
8165                  * Note that bash reads ~80 chars of the file, and if it sees
8166                  * a zero byte before it sees newline, it doesn't try to
8167                  * interpret it, but fails with "cannot execute binary file"
8168                  * message and exit code 126. For one, this prevents attempts
8169                  * to interpret foreign ELF binaries as shell scripts.
8170                  */
8171                 argv[0] = (char*) cmd;
8172                 cmd = bb_busybox_exec_path;
8173                 /* NB: this is only possible because all callers of shellexec()
8174                  * ensure that the argv[-1] slot exists!
8175                  */
8176                 argv--;
8177                 argv[0] = (char*) "ash";
8178                 goto repeat;
8179         }
8180 }
8181
8182 /*
8183  * Exec a program.  Never returns.  If you change this routine, you may
8184  * have to change the find_command routine as well.
8185  * argv[-1] must exist and be writable! See tryexec() for why.
8186  */
8187 static void shellexec(char *prog, char **argv, const char *path, int idx) NORETURN;
8188 static void shellexec(char *prog, char **argv, const char *path, int idx)
8189 {
8190         char *cmdname;
8191         int e;
8192         char **envp;
8193         int exerrno;
8194         int applet_no = -1; /* used only by FEATURE_SH_STANDALONE */
8195
8196         envp = listvars(VEXPORT, VUNSET, /*strlist:*/ NULL, /*end:*/ NULL);
8197         if (strchr(prog, '/') != NULL
8198 #if ENABLE_FEATURE_SH_STANDALONE
8199          || (applet_no = find_applet_by_name(prog)) >= 0
8200 #endif
8201         ) {
8202                 tryexec(IF_FEATURE_SH_STANDALONE(applet_no,) prog, argv, envp);
8203                 if (applet_no >= 0) {
8204                         /* We tried execing ourself, but it didn't work.
8205                          * Maybe /proc/self/exe doesn't exist?
8206                          * Try $PATH search.
8207                          */
8208                         goto try_PATH;
8209                 }
8210                 e = errno;
8211         } else {
8212  try_PATH:
8213                 e = ENOENT;
8214                 while (padvance(&path, argv[0]) >= 0) {
8215                         cmdname = stackblock();
8216                         if (--idx < 0 && pathopt == NULL) {
8217                                 tryexec(IF_FEATURE_SH_STANDALONE(-1,) cmdname, argv, envp);
8218                                 if (errno != ENOENT && errno != ENOTDIR)
8219                                         e = errno;
8220                         }
8221                 }
8222         }
8223
8224         /* Map to POSIX errors */
8225         switch (e) {
8226         default:
8227                 exerrno = 126;
8228                 break;
8229         case ELOOP:
8230         case ENAMETOOLONG:
8231         case ENOENT:
8232         case ENOTDIR:
8233                 exerrno = 127;
8234                 break;
8235         }
8236         exitstatus = exerrno;
8237         TRACE(("shellexec failed for %s, errno %d, suppress_int %d\n",
8238                 prog, e, suppress_int));
8239         ash_msg_and_raise(EXEND, "%s: %s", prog, errmsg(e, "not found"));
8240         /* NOTREACHED */
8241 }
8242
8243 static void
8244 printentry(struct tblentry *cmdp)
8245 {
8246         int idx;
8247         const char *path;
8248         char *name;
8249
8250         idx = cmdp->param.index;
8251         path = pathval();
8252         do {
8253                 padvance(&path, cmdp->cmdname);
8254         } while (--idx >= 0);
8255         name = stackblock();
8256         out1fmt("%s%s\n", name, (cmdp->rehash ? "*" : nullstr));
8257 }
8258
8259 /*
8260  * Clear out command entries.
8261  */
8262 static void
8263 clearcmdentry(void)
8264 {
8265         struct tblentry **tblp;
8266         struct tblentry **pp;
8267         struct tblentry *cmdp;
8268
8269         INT_OFF;
8270         for (tblp = cmdtable; tblp < &cmdtable[CMDTABLESIZE]; tblp++) {
8271                 pp = tblp;
8272                 while ((cmdp = *pp) != NULL) {
8273                         if (cmdp->cmdtype == CMDNORMAL
8274                          || (cmdp->cmdtype == CMDBUILTIN
8275                             && !IS_BUILTIN_REGULAR(cmdp->param.cmd)
8276                             && builtinloc > 0
8277                             )
8278                         ) {
8279                                 *pp = cmdp->next;
8280                                 free(cmdp);
8281                         } else {
8282                                 pp = &cmdp->next;
8283                         }
8284                 }
8285         }
8286         INT_ON;
8287 }
8288
8289 /*
8290  * Locate a command in the command hash table.  If "add" is nonzero,
8291  * add the command to the table if it is not already present.  The
8292  * variable "lastcmdentry" is set to point to the address of the link
8293  * pointing to the entry, so that delete_cmd_entry can delete the
8294  * entry.
8295  *
8296  * Interrupts must be off if called with add != 0.
8297  */
8298 static struct tblentry **lastcmdentry;
8299
8300 static struct tblentry *
8301 cmdlookup(const char *name, int add)
8302 {
8303         unsigned int hashval;
8304         const char *p;
8305         struct tblentry *cmdp;
8306         struct tblentry **pp;
8307
8308         p = name;
8309         hashval = (unsigned char)*p << 4;
8310         while (*p)
8311                 hashval += (unsigned char)*p++;
8312         hashval &= 0x7FFF;
8313         pp = &cmdtable[hashval % CMDTABLESIZE];
8314         for (cmdp = *pp; cmdp; cmdp = cmdp->next) {
8315                 if (strcmp(cmdp->cmdname, name) == 0)
8316                         break;
8317                 pp = &cmdp->next;
8318         }
8319         if (add && cmdp == NULL) {
8320                 cmdp = *pp = ckzalloc(sizeof(struct tblentry)
8321                                 + strlen(name)
8322                                 /* + 1 - already done because
8323                                  * tblentry::cmdname is char[1] */);
8324                 /*cmdp->next = NULL; - ckzalloc did it */
8325                 cmdp->cmdtype = CMDUNKNOWN;
8326                 strcpy(cmdp->cmdname, name);
8327         }
8328         lastcmdentry = pp;
8329         return cmdp;
8330 }
8331
8332 /*
8333  * Delete the command entry returned on the last lookup.
8334  */
8335 static void
8336 delete_cmd_entry(void)
8337 {
8338         struct tblentry *cmdp;
8339
8340         INT_OFF;
8341         cmdp = *lastcmdentry;
8342         *lastcmdentry = cmdp->next;
8343         if (cmdp->cmdtype == CMDFUNCTION)
8344                 freefunc(cmdp->param.func);
8345         free(cmdp);
8346         INT_ON;
8347 }
8348
8349 /*
8350  * Add a new command entry, replacing any existing command entry for
8351  * the same name - except special builtins.
8352  */
8353 static void
8354 addcmdentry(char *name, struct cmdentry *entry)
8355 {
8356         struct tblentry *cmdp;
8357
8358         cmdp = cmdlookup(name, 1);
8359         if (cmdp->cmdtype == CMDFUNCTION) {
8360                 freefunc(cmdp->param.func);
8361         }
8362         cmdp->cmdtype = entry->cmdtype;
8363         cmdp->param = entry->u;
8364         cmdp->rehash = 0;
8365 }
8366
8367 static int FAST_FUNC
8368 hashcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
8369 {
8370         struct tblentry **pp;
8371         struct tblentry *cmdp;
8372         int c;
8373         struct cmdentry entry;
8374         char *name;
8375
8376         if (nextopt("r") != '\0') {
8377                 clearcmdentry();
8378                 return 0;
8379         }
8380
8381         if (*argptr == NULL) {
8382                 for (pp = cmdtable; pp < &cmdtable[CMDTABLESIZE]; pp++) {
8383                         for (cmdp = *pp; cmdp; cmdp = cmdp->next) {
8384                                 if (cmdp->cmdtype == CMDNORMAL)
8385                                         printentry(cmdp);
8386                         }
8387                 }
8388                 return 0;
8389         }
8390
8391         c = 0;
8392         while ((name = *argptr) != NULL) {
8393                 cmdp = cmdlookup(name, 0);
8394                 if (cmdp != NULL
8395                  && (cmdp->cmdtype == CMDNORMAL
8396                     || (cmdp->cmdtype == CMDBUILTIN
8397                         && !IS_BUILTIN_REGULAR(cmdp->param.cmd)
8398                         && builtinloc > 0
8399                         )
8400                     )
8401                 ) {
8402                         delete_cmd_entry();
8403                 }
8404                 find_command(name, &entry, DO_ERR, pathval());
8405                 if (entry.cmdtype == CMDUNKNOWN)
8406                         c = 1;
8407                 argptr++;
8408         }
8409         return c;
8410 }
8411
8412 /*
8413  * Called when a cd is done.  Marks all commands so the next time they
8414  * are executed they will be rehashed.
8415  */
8416 static void
8417 hashcd(void)
8418 {
8419         struct tblentry **pp;
8420         struct tblentry *cmdp;
8421
8422         for (pp = cmdtable; pp < &cmdtable[CMDTABLESIZE]; pp++) {
8423                 for (cmdp = *pp; cmdp; cmdp = cmdp->next) {
8424                         if (cmdp->cmdtype == CMDNORMAL
8425                          || (cmdp->cmdtype == CMDBUILTIN
8426                              && !IS_BUILTIN_REGULAR(cmdp->param.cmd)
8427                              && builtinloc > 0)
8428                         ) {
8429                                 cmdp->rehash = 1;
8430                         }
8431                 }
8432         }
8433 }
8434
8435 /*
8436  * Fix command hash table when PATH changed.
8437  * Called before PATH is changed.  The argument is the new value of PATH;
8438  * pathval() still returns the old value at this point.
8439  * Called with interrupts off.
8440  */
8441 static void FAST_FUNC
8442 changepath(const char *newval)
8443 {
8444         const char *new;
8445         int idx;
8446         int bltin;
8447
8448         new = newval;
8449         idx = 0;
8450         bltin = -1;
8451         for (;;) {
8452                 if (*new == '%' && prefix(new + 1, "builtin")) {
8453                         bltin = idx;
8454                         break;
8455                 }
8456                 new = strchr(new, ':');
8457                 if (!new)
8458                         break;
8459                 idx++;
8460                 new++;
8461         }
8462         builtinloc = bltin;
8463         clearcmdentry();
8464 }
8465 enum {
8466         TEOF,
8467         TNL,
8468         TREDIR,
8469         TWORD,
8470         TSEMI,
8471         TBACKGND,
8472         TAND,
8473         TOR,
8474         TPIPE,
8475         TLP,
8476         TRP,
8477         TENDCASE,
8478         TENDBQUOTE,
8479         TNOT,
8480         TCASE,
8481         TDO,
8482         TDONE,
8483         TELIF,
8484         TELSE,
8485         TESAC,
8486         TFI,
8487         TFOR,
8488 #if BASH_FUNCTION
8489         TFUNCTION,
8490 #endif
8491         TIF,
8492         TIN,
8493         TTHEN,
8494         TUNTIL,
8495         TWHILE,
8496         TBEGIN,
8497         TEND
8498 };
8499 typedef smallint token_id_t;
8500
8501 /* Nth bit indicates if token marks the end of a list */
8502 enum {
8503         tokendlist = 0
8504         /*  0 */ | (1u << TEOF)
8505         /*  1 */ | (0u << TNL)
8506         /*  2 */ | (0u << TREDIR)
8507         /*  3 */ | (0u << TWORD)
8508         /*  4 */ | (0u << TSEMI)
8509         /*  5 */ | (0u << TBACKGND)
8510         /*  6 */ | (0u << TAND)
8511         /*  7 */ | (0u << TOR)
8512         /*  8 */ | (0u << TPIPE)
8513         /*  9 */ | (0u << TLP)
8514         /* 10 */ | (1u << TRP)
8515         /* 11 */ | (1u << TENDCASE)
8516         /* 12 */ | (1u << TENDBQUOTE)
8517         /* 13 */ | (0u << TNOT)
8518         /* 14 */ | (0u << TCASE)
8519         /* 15 */ | (1u << TDO)
8520         /* 16 */ | (1u << TDONE)
8521         /* 17 */ | (1u << TELIF)
8522         /* 18 */ | (1u << TELSE)
8523         /* 19 */ | (1u << TESAC)
8524         /* 20 */ | (1u << TFI)
8525         /* 21 */ | (0u << TFOR)
8526 #if BASH_FUNCTION
8527         /* 22 */ | (0u << TFUNCTION)
8528 #endif
8529         /* 23 */ | (0u << TIF)
8530         /* 24 */ | (0u << TIN)
8531         /* 25 */ | (1u << TTHEN)
8532         /* 26 */ | (0u << TUNTIL)
8533         /* 27 */ | (0u << TWHILE)
8534         /* 28 */ | (0u << TBEGIN)
8535         /* 29 */ | (1u << TEND)
8536         , /* thus far 29 bits used */
8537 };
8538
8539 static const char *const tokname_array[] = {
8540         "end of file",
8541         "newline",
8542         "redirection",
8543         "word",
8544         ";",
8545         "&",
8546         "&&",
8547         "||",
8548         "|",
8549         "(",
8550         ")",
8551         ";;",
8552         "`",
8553 #define KWDOFFSET 13
8554         /* the following are keywords */
8555         "!",
8556         "case",
8557         "do",
8558         "done",
8559         "elif",
8560         "else",
8561         "esac",
8562         "fi",
8563         "for",
8564 #if BASH_FUNCTION
8565         "function",
8566 #endif
8567         "if",
8568         "in",
8569         "then",
8570         "until",
8571         "while",
8572         "{",
8573         "}",
8574 };
8575
8576 /* Wrapper around strcmp for qsort/bsearch/... */
8577 static int
8578 pstrcmp(const void *a, const void *b)
8579 {
8580         return strcmp((char*)a, *(char**)b);
8581 }
8582
8583 static const char *const *
8584 findkwd(const char *s)
8585 {
8586         return bsearch(s, tokname_array + KWDOFFSET,
8587                         ARRAY_SIZE(tokname_array) - KWDOFFSET,
8588                         sizeof(tokname_array[0]), pstrcmp);
8589 }
8590
8591 /*
8592  * Locate and print what a word is...
8593  */
8594 static int
8595 describe_command(char *command, const char *path, int describe_command_verbose)
8596 {
8597         struct cmdentry entry;
8598 #if ENABLE_ASH_ALIAS
8599         const struct alias *ap;
8600 #endif
8601
8602         path = path ? path : pathval();
8603
8604         if (describe_command_verbose) {
8605                 out1str(command);
8606         }
8607
8608         /* First look at the keywords */
8609         if (findkwd(command)) {
8610                 out1str(describe_command_verbose ? " is a shell keyword" : command);
8611                 goto out;
8612         }
8613
8614 #if ENABLE_ASH_ALIAS
8615         /* Then look at the aliases */
8616         ap = lookupalias(command, 0);
8617         if (ap != NULL) {
8618                 if (!describe_command_verbose) {
8619                         out1str("alias ");
8620                         printalias(ap);
8621                         return 0;
8622                 }
8623                 out1fmt(" is an alias for %s", ap->val);
8624                 goto out;
8625         }
8626 #endif
8627         /* Brute force */
8628         find_command(command, &entry, DO_ABS, path);
8629
8630         switch (entry.cmdtype) {
8631         case CMDNORMAL: {
8632                 int j = entry.u.index;
8633                 char *p;
8634                 if (j < 0) {
8635                         p = command;
8636                 } else {
8637                         do {
8638                                 padvance(&path, command);
8639                         } while (--j >= 0);
8640                         p = stackblock();
8641                 }
8642                 if (describe_command_verbose) {
8643                         out1fmt(" is %s", p);
8644                 } else {
8645                         out1str(p);
8646                 }
8647                 break;
8648         }
8649
8650         case CMDFUNCTION:
8651                 if (describe_command_verbose) {
8652                         /*out1str(" is a shell function");*/
8653                         out1str(" is a function"); /* bash says this */
8654                 } else {
8655                         out1str(command);
8656                 }
8657                 break;
8658
8659         case CMDBUILTIN:
8660                 if (describe_command_verbose) {
8661                         out1fmt(" is a %sshell builtin",
8662                                 IS_BUILTIN_SPECIAL(entry.u.cmd) ?
8663                                         "special " : nullstr
8664                         );
8665                 } else {
8666                         out1str(command);
8667                 }
8668                 break;
8669
8670         default:
8671                 if (describe_command_verbose) {
8672                         out1str(": not found\n");
8673                 }
8674                 return 127;
8675         }
8676  out:
8677         out1str("\n");
8678         return 0;
8679 }
8680
8681 static int FAST_FUNC
8682 typecmd(int argc UNUSED_PARAM, char **argv)
8683 {
8684         int i = 1;
8685         int err = 0;
8686         int verbose = 1;
8687
8688         /* type -p ... ? (we don't bother checking for 'p') */
8689         if (argv[1] && argv[1][0] == '-') {
8690                 i++;
8691                 verbose = 0;
8692         }
8693         while (argv[i]) {
8694                 err |= describe_command(argv[i++], NULL, verbose);
8695         }
8696         return err;
8697 }
8698
8699 #if ENABLE_ASH_CMDCMD
8700 static struct strlist *
8701 fill_arglist(struct arglist *arglist, union node **argpp)
8702 {
8703         struct strlist **lastp = arglist->lastp;
8704         union node *argp;
8705
8706         while ((argp = *argpp) != NULL) {
8707                 expandarg(argp, arglist, EXP_FULL | EXP_TILDE);
8708                 *argpp = argp->narg.next;
8709                 if (*lastp)
8710                         break;
8711         }
8712
8713         return *lastp;
8714 }
8715
8716 /* Is it "command [-p] PROG ARGS" bltin, no other opts? Return ptr to "PROG" if yes */
8717 static int
8718 parse_command_args(struct arglist *arglist, union node **argpp, const char **path)
8719 {
8720         struct strlist *sp = arglist->list;
8721         char *cp, c;
8722
8723         for (;;) {
8724                 sp = sp->next ? sp->next : fill_arglist(arglist, argpp);
8725                 if (!sp)
8726                         return 0;
8727                 cp = sp->text;
8728                 if (*cp++ != '-')
8729                         break;
8730                 c = *cp++;
8731                 if (!c)
8732                         break;
8733                 if (c == '-' && !*cp) {
8734                         if (!sp->next && !fill_arglist(arglist, argpp))
8735                                 return 0;
8736                         sp = sp->next;
8737                         break;
8738                 }
8739                 do {
8740                         switch (c) {
8741                         case 'p':
8742                                 *path = bb_default_path;
8743                                 break;
8744                         default:
8745                                 /* run 'typecmd' for other options */
8746                                 return 0;
8747                         }
8748                         c = *cp++;
8749                 } while (c);
8750         }
8751
8752         arglist->list = sp;
8753         return DO_NOFUNC;
8754 }
8755
8756 static int FAST_FUNC
8757 commandcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
8758 {
8759         char *cmd;
8760         int c;
8761         enum {
8762                 VERIFY_BRIEF = 1,
8763                 VERIFY_VERBOSE = 2,
8764         } verify = 0;
8765         const char *path = NULL;
8766
8767         /* "command [-p] PROG ARGS" (that is, without -V or -v)
8768          * never reaches this function.
8769          */
8770
8771         while ((c = nextopt("pvV")) != '\0')
8772                 if (c == 'V')
8773                         verify |= VERIFY_VERBOSE;
8774                 else if (c == 'v')
8775                         /*verify |= VERIFY_BRIEF*/;
8776 #if DEBUG
8777                 else if (c != 'p')
8778                         abort();
8779 #endif
8780                 else
8781                         path = bb_default_path;
8782
8783         /* Mimic bash: just "command -v" doesn't complain, it's a nop */
8784         cmd = *argptr;
8785         if (/*verify && */ cmd)
8786                 return describe_command(cmd, path, verify /* - VERIFY_BRIEF*/);
8787
8788         return 0;
8789 }
8790 #endif
8791
8792
8793 /*static int funcblocksize;     // size of structures in function */
8794 /*static int funcstringsize;    // size of strings in node */
8795 static void *funcblock;         /* block to allocate function from */
8796 static char *funcstring_end;    /* end of block to allocate strings from */
8797
8798 static const uint8_t nodesize[N_NUMBER] ALIGN1 = {
8799         [NCMD     ] = SHELL_ALIGN(sizeof(struct ncmd)),
8800         [NPIPE    ] = SHELL_ALIGN(sizeof(struct npipe)),
8801         [NREDIR   ] = SHELL_ALIGN(sizeof(struct nredir)),
8802         [NBACKGND ] = SHELL_ALIGN(sizeof(struct nredir)),
8803         [NSUBSHELL] = SHELL_ALIGN(sizeof(struct nredir)),
8804         [NAND     ] = SHELL_ALIGN(sizeof(struct nbinary)),
8805         [NOR      ] = SHELL_ALIGN(sizeof(struct nbinary)),
8806         [NSEMI    ] = SHELL_ALIGN(sizeof(struct nbinary)),
8807         [NIF      ] = SHELL_ALIGN(sizeof(struct nif)),
8808         [NWHILE   ] = SHELL_ALIGN(sizeof(struct nbinary)),
8809         [NUNTIL   ] = SHELL_ALIGN(sizeof(struct nbinary)),
8810         [NFOR     ] = SHELL_ALIGN(sizeof(struct nfor)),
8811         [NCASE    ] = SHELL_ALIGN(sizeof(struct ncase)),
8812         [NCLIST   ] = SHELL_ALIGN(sizeof(struct nclist)),
8813         [NDEFUN   ] = SHELL_ALIGN(sizeof(struct narg)),
8814         [NARG     ] = SHELL_ALIGN(sizeof(struct narg)),
8815         [NTO      ] = SHELL_ALIGN(sizeof(struct nfile)),
8816 #if BASH_REDIR_OUTPUT
8817         [NTO2     ] = SHELL_ALIGN(sizeof(struct nfile)),
8818 #endif
8819         [NCLOBBER ] = SHELL_ALIGN(sizeof(struct nfile)),
8820         [NFROM    ] = SHELL_ALIGN(sizeof(struct nfile)),
8821         [NFROMTO  ] = SHELL_ALIGN(sizeof(struct nfile)),
8822         [NAPPEND  ] = SHELL_ALIGN(sizeof(struct nfile)),
8823         [NTOFD    ] = SHELL_ALIGN(sizeof(struct ndup)),
8824         [NFROMFD  ] = SHELL_ALIGN(sizeof(struct ndup)),
8825         [NHERE    ] = SHELL_ALIGN(sizeof(struct nhere)),
8826         [NXHERE   ] = SHELL_ALIGN(sizeof(struct nhere)),
8827         [NNOT     ] = SHELL_ALIGN(sizeof(struct nnot)),
8828 };
8829
8830 static int calcsize(int funcblocksize, union node *n);
8831
8832 static int
8833 sizenodelist(int funcblocksize, struct nodelist *lp)
8834 {
8835         while (lp) {
8836                 funcblocksize += SHELL_ALIGN(sizeof(struct nodelist));
8837                 funcblocksize = calcsize(funcblocksize, lp->n);
8838                 lp = lp->next;
8839         }
8840         return funcblocksize;
8841 }
8842
8843 static int
8844 calcsize(int funcblocksize, union node *n)
8845 {
8846         if (n == NULL)
8847                 return funcblocksize;
8848         funcblocksize += nodesize[n->type];
8849         switch (n->type) {
8850         case NCMD:
8851                 funcblocksize = calcsize(funcblocksize, n->ncmd.redirect);
8852                 funcblocksize = calcsize(funcblocksize, n->ncmd.args);
8853                 funcblocksize = calcsize(funcblocksize, n->ncmd.assign);
8854                 break;
8855         case NPIPE:
8856                 funcblocksize = sizenodelist(funcblocksize, n->npipe.cmdlist);
8857                 break;
8858         case NREDIR:
8859         case NBACKGND:
8860         case NSUBSHELL:
8861                 funcblocksize = calcsize(funcblocksize, n->nredir.redirect);
8862                 funcblocksize = calcsize(funcblocksize, n->nredir.n);
8863                 break;
8864         case NAND:
8865         case NOR:
8866         case NSEMI:
8867         case NWHILE:
8868         case NUNTIL:
8869                 funcblocksize = calcsize(funcblocksize, n->nbinary.ch2);
8870                 funcblocksize = calcsize(funcblocksize, n->nbinary.ch1);
8871                 break;
8872         case NIF:
8873                 funcblocksize = calcsize(funcblocksize, n->nif.elsepart);
8874                 funcblocksize = calcsize(funcblocksize, n->nif.ifpart);
8875                 funcblocksize = calcsize(funcblocksize, n->nif.test);
8876                 break;
8877         case NFOR:
8878                 funcblocksize += SHELL_ALIGN(strlen(n->nfor.var) + 1); /* was funcstringsize += ... */
8879                 funcblocksize = calcsize(funcblocksize, n->nfor.body);
8880                 funcblocksize = calcsize(funcblocksize, n->nfor.args);
8881                 break;
8882         case NCASE:
8883                 funcblocksize = calcsize(funcblocksize, n->ncase.cases);
8884                 funcblocksize = calcsize(funcblocksize, n->ncase.expr);
8885                 break;
8886         case NCLIST:
8887                 funcblocksize = calcsize(funcblocksize, n->nclist.body);
8888                 funcblocksize = calcsize(funcblocksize, n->nclist.pattern);
8889                 funcblocksize = calcsize(funcblocksize, n->nclist.next);
8890                 break;
8891         case NDEFUN:
8892                 funcblocksize = calcsize(funcblocksize, n->ndefun.body);
8893                 funcblocksize += SHELL_ALIGN(strlen(n->ndefun.text) + 1);
8894                 break;
8895         case NARG:
8896                 funcblocksize = sizenodelist(funcblocksize, n->narg.backquote);
8897                 funcblocksize += SHELL_ALIGN(strlen(n->narg.text) + 1); /* was funcstringsize += ... */
8898                 funcblocksize = calcsize(funcblocksize, n->narg.next);
8899                 break;
8900         case NTO:
8901 #if BASH_REDIR_OUTPUT
8902         case NTO2:
8903 #endif
8904         case NCLOBBER:
8905         case NFROM:
8906         case NFROMTO:
8907         case NAPPEND:
8908                 funcblocksize = calcsize(funcblocksize, n->nfile.fname);
8909                 funcblocksize = calcsize(funcblocksize, n->nfile.next);
8910                 break;
8911         case NTOFD:
8912         case NFROMFD:
8913                 funcblocksize = calcsize(funcblocksize, n->ndup.vname);
8914                 funcblocksize = calcsize(funcblocksize, n->ndup.next);
8915         break;
8916         case NHERE:
8917         case NXHERE:
8918                 funcblocksize = calcsize(funcblocksize, n->nhere.doc);
8919                 funcblocksize = calcsize(funcblocksize, n->nhere.next);
8920                 break;
8921         case NNOT:
8922                 funcblocksize = calcsize(funcblocksize, n->nnot.com);
8923                 break;
8924         };
8925         return funcblocksize;
8926 }
8927
8928 static char *
8929 nodeckstrdup(char *s)
8930 {
8931         funcstring_end -= SHELL_ALIGN(strlen(s) + 1);
8932         return strcpy(funcstring_end, s);
8933 }
8934
8935 static union node *copynode(union node *);
8936
8937 static struct nodelist *
8938 copynodelist(struct nodelist *lp)
8939 {
8940         struct nodelist *start;
8941         struct nodelist **lpp;
8942
8943         lpp = &start;
8944         while (lp) {
8945                 *lpp = funcblock;
8946                 funcblock = (char *) funcblock + SHELL_ALIGN(sizeof(struct nodelist));
8947                 (*lpp)->n = copynode(lp->n);
8948                 lp = lp->next;
8949                 lpp = &(*lpp)->next;
8950         }
8951         *lpp = NULL;
8952         return start;
8953 }
8954
8955 static union node *
8956 copynode(union node *n)
8957 {
8958         union node *new;
8959
8960         if (n == NULL)
8961                 return NULL;
8962         new = funcblock;
8963         funcblock = (char *) funcblock + nodesize[n->type];
8964
8965         switch (n->type) {
8966         case NCMD:
8967                 new->ncmd.redirect = copynode(n->ncmd.redirect);
8968                 new->ncmd.args = copynode(n->ncmd.args);
8969                 new->ncmd.assign = copynode(n->ncmd.assign);
8970                 new->ncmd.linno = n->ncmd.linno;
8971                 break;
8972         case NPIPE:
8973                 new->npipe.cmdlist = copynodelist(n->npipe.cmdlist);
8974                 new->npipe.pipe_backgnd = n->npipe.pipe_backgnd;
8975                 break;
8976         case NREDIR:
8977         case NBACKGND:
8978         case NSUBSHELL:
8979                 new->nredir.redirect = copynode(n->nredir.redirect);
8980                 new->nredir.n = copynode(n->nredir.n);
8981                 new->nredir.linno = n->nredir.linno;
8982                 break;
8983         case NAND:
8984         case NOR:
8985         case NSEMI:
8986         case NWHILE:
8987         case NUNTIL:
8988                 new->nbinary.ch2 = copynode(n->nbinary.ch2);
8989                 new->nbinary.ch1 = copynode(n->nbinary.ch1);
8990                 break;
8991         case NIF:
8992                 new->nif.elsepart = copynode(n->nif.elsepart);
8993                 new->nif.ifpart = copynode(n->nif.ifpart);
8994                 new->nif.test = copynode(n->nif.test);
8995                 break;
8996         case NFOR:
8997                 new->nfor.var = nodeckstrdup(n->nfor.var);
8998                 new->nfor.body = copynode(n->nfor.body);
8999                 new->nfor.args = copynode(n->nfor.args);
9000                 new->nfor.linno = n->nfor.linno;
9001                 break;
9002         case NCASE:
9003                 new->ncase.cases = copynode(n->ncase.cases);
9004                 new->ncase.expr = copynode(n->ncase.expr);
9005                 new->ncase.linno = n->ncase.linno;
9006                 break;
9007         case NCLIST:
9008                 new->nclist.body = copynode(n->nclist.body);
9009                 new->nclist.pattern = copynode(n->nclist.pattern);
9010                 new->nclist.next = copynode(n->nclist.next);
9011                 break;
9012         case NDEFUN:
9013                 new->ndefun.body = copynode(n->ndefun.body);
9014                 new->ndefun.text = nodeckstrdup(n->ndefun.text);
9015                 new->ndefun.linno = n->ndefun.linno;
9016                 break;
9017         case NARG:
9018                 new->narg.backquote = copynodelist(n->narg.backquote);
9019                 new->narg.text = nodeckstrdup(n->narg.text);
9020                 new->narg.next = copynode(n->narg.next);
9021                 break;
9022         case NTO:
9023 #if BASH_REDIR_OUTPUT
9024         case NTO2:
9025 #endif
9026         case NCLOBBER:
9027         case NFROM:
9028         case NFROMTO:
9029         case NAPPEND:
9030                 new->nfile.fname = copynode(n->nfile.fname);
9031                 new->nfile.fd = n->nfile.fd;
9032                 new->nfile.next = copynode(n->nfile.next);
9033                 break;
9034         case NTOFD:
9035         case NFROMFD:
9036                 new->ndup.vname = copynode(n->ndup.vname);
9037                 new->ndup.dupfd = n->ndup.dupfd;
9038                 new->ndup.fd = n->ndup.fd;
9039                 new->ndup.next = copynode(n->ndup.next);
9040                 break;
9041         case NHERE:
9042         case NXHERE:
9043                 new->nhere.doc = copynode(n->nhere.doc);
9044                 new->nhere.fd = n->nhere.fd;
9045                 new->nhere.next = copynode(n->nhere.next);
9046                 break;
9047         case NNOT:
9048                 new->nnot.com = copynode(n->nnot.com);
9049                 break;
9050         };
9051         new->type = n->type;
9052         return new;
9053 }
9054
9055 /*
9056  * Make a copy of a parse tree.
9057  */
9058 static struct funcnode *
9059 copyfunc(union node *n)
9060 {
9061         struct funcnode *f;
9062         size_t blocksize;
9063
9064         /*funcstringsize = 0;*/
9065         blocksize = offsetof(struct funcnode, n) + calcsize(0, n);
9066         f = ckzalloc(blocksize /* + funcstringsize */);
9067         funcblock = (char *) f + offsetof(struct funcnode, n);
9068         funcstring_end = (char *) f + blocksize;
9069         copynode(n);
9070         /* f->count = 0; - ckzalloc did it */
9071         return f;
9072 }
9073
9074 /*
9075  * Define a shell function.
9076  */
9077 static void
9078 defun(union node *func)
9079 {
9080         struct cmdentry entry;
9081
9082         INT_OFF;
9083         entry.cmdtype = CMDFUNCTION;
9084         entry.u.func = copyfunc(func);
9085         addcmdentry(func->ndefun.text, &entry);
9086         INT_ON;
9087 }
9088
9089 /* Reasons for skipping commands (see comment on breakcmd routine) */
9090 #define SKIPBREAK      (1 << 0)
9091 #define SKIPCONT       (1 << 1)
9092 #define SKIPFUNC       (1 << 2)
9093 #define SKIPFUNCDEF    (1 << 3)
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                 if (evalskip != SKIPFUNC)
9152                         exitstatus = status;
9153         }
9154
9155         savestatus = last_status;
9156         TRACE(("dotrap returns\n"));
9157 }
9158
9159 /* forward declarations - evaluation is fairly recursive business... */
9160 static int evalloop(union node *, int);
9161 static int evalfor(union node *, int);
9162 static int evalcase(union node *, int);
9163 static int evalsubshell(union node *, int);
9164 static void expredir(union node *);
9165 static int evalpipe(union node *, int);
9166 static int evalcommand(union node *, int);
9167 static int evalbltin(const struct builtincmd *, int, char **, int);
9168 static void prehash(union node *);
9169
9170 /*
9171  * Evaluate a parse tree.  The value is left in the global variable
9172  * exitstatus.
9173  */
9174 static int
9175 evaltree(union node *n, int flags)
9176 {
9177         int checkexit = 0;
9178         int (*evalfn)(union node *, int);
9179         struct stackmark smark;
9180         int status = 0;
9181
9182         setstackmark(&smark);
9183
9184         if (n == NULL) {
9185                 TRACE(("evaltree(NULL) called\n"));
9186                 goto out;
9187         }
9188         TRACE(("evaltree(%p: %d, %d) called\n", n, n->type, flags));
9189
9190         dotrap();
9191
9192         switch (n->type) {
9193         default:
9194 #if DEBUG
9195                 out1fmt("Node type = %d\n", n->type);
9196                 fflush_all();
9197                 break;
9198 #endif
9199         case NNOT:
9200                 status = !evaltree(n->nnot.com, EV_TESTED);
9201                 goto setstatus;
9202         case NREDIR:
9203                 errlinno = lineno = n->nredir.linno;
9204                 if (funcline)
9205                         lineno -= funcline - 1;
9206                 expredir(n->nredir.redirect);
9207                 pushredir(n->nredir.redirect);
9208                 status = redirectsafe(n->nredir.redirect, REDIR_PUSH);
9209                 if (!status) {
9210                         status = evaltree(n->nredir.n, flags & EV_TESTED);
9211                 }
9212                 if (n->nredir.redirect)
9213                         popredir(/*drop:*/ 0);
9214                 goto setstatus;
9215         case NCMD:
9216                 evalfn = evalcommand;
9217  checkexit:
9218                 if (eflag && !(flags & EV_TESTED))
9219                         checkexit = ~0;
9220                 goto calleval;
9221         case NFOR:
9222                 evalfn = evalfor;
9223                 goto calleval;
9224         case NWHILE:
9225         case NUNTIL:
9226                 evalfn = evalloop;
9227                 goto calleval;
9228         case NSUBSHELL:
9229         case NBACKGND:
9230                 evalfn = evalsubshell;
9231                 goto checkexit;
9232         case NPIPE:
9233                 evalfn = evalpipe;
9234                 goto checkexit;
9235         case NCASE:
9236                 evalfn = evalcase;
9237                 goto calleval;
9238         case NAND:
9239         case NOR:
9240         case NSEMI: {
9241
9242 #if NAND + 1 != NOR
9243 #error NAND + 1 != NOR
9244 #endif
9245 #if NOR + 1 != NSEMI
9246 #error NOR + 1 != NSEMI
9247 #endif
9248                 unsigned is_or = n->type - NAND;
9249                 status = evaltree(
9250                         n->nbinary.ch1,
9251                         (flags | ((is_or >> 1) - 1)) & EV_TESTED
9252                 );
9253                 if ((!status) == is_or || evalskip)
9254                         break;
9255                 n = n->nbinary.ch2;
9256  evaln:
9257                 evalfn = evaltree;
9258  calleval:
9259                 status = evalfn(n, flags);
9260                 goto setstatus;
9261         }
9262         case NIF:
9263                 status = evaltree(n->nif.test, EV_TESTED);
9264                 if (evalskip)
9265                         break;
9266                 if (!status) {
9267                         n = n->nif.ifpart;
9268                         goto evaln;
9269                 }
9270                 if (n->nif.elsepart) {
9271                         n = n->nif.elsepart;
9272                         goto evaln;
9273                 }
9274                 status = 0;
9275                 goto setstatus;
9276         case NDEFUN:
9277                 defun(n);
9278                 /* Not necessary. To test it:
9279                  * "false; f() { qwerty; }; echo $?" should print 0.
9280                  */
9281                 /* status = 0; */
9282  setstatus:
9283                 exitstatus = status;
9284                 break;
9285         }
9286  out:
9287         /* Order of checks below is important:
9288          * signal handlers trigger before exit caused by "set -e".
9289          */
9290         dotrap();
9291
9292         if (checkexit & status)
9293                 raise_exception(EXEND);
9294         if (flags & EV_EXIT)
9295                 raise_exception(EXEND);
9296
9297         popstackmark(&smark);
9298         TRACE(("leaving evaltree (no interrupts)\n"));
9299         return exitstatus;
9300 }
9301
9302 static int
9303 skiploop(void)
9304 {
9305         int skip = evalskip;
9306
9307         switch (skip) {
9308         case 0:
9309                 break;
9310         case SKIPBREAK:
9311         case SKIPCONT:
9312                 if (--skipcount <= 0) {
9313                         evalskip = 0;
9314                         break;
9315                 }
9316                 skip = SKIPBREAK;
9317                 break;
9318         }
9319         return skip;
9320 }
9321
9322 static int
9323 evalloop(union node *n, int flags)
9324 {
9325         int skip;
9326         int status;
9327
9328         loopnest++;
9329         status = 0;
9330         flags &= EV_TESTED;
9331         do {
9332                 int i;
9333
9334                 i = evaltree(n->nbinary.ch1, EV_TESTED);
9335                 skip = skiploop();
9336                 if (skip == SKIPFUNC)
9337                         status = i;
9338                 if (skip)
9339                         continue;
9340                 if (n->type != NWHILE)
9341                         i = !i;
9342                 if (i != 0)
9343                         break;
9344                 status = evaltree(n->nbinary.ch2, flags);
9345                 skip = skiploop();
9346         } while (!(skip & ~SKIPCONT));
9347         loopnest--;
9348
9349         return status;
9350 }
9351
9352 static int
9353 evalfor(union node *n, int flags)
9354 {
9355         struct arglist arglist;
9356         union node *argp;
9357         struct strlist *sp;
9358         int status = 0;
9359
9360         errlinno = lineno = n->ncase.linno;
9361         if (funcline)
9362                 lineno -= funcline - 1;
9363
9364         arglist.list = NULL;
9365         arglist.lastp = &arglist.list;
9366         for (argp = n->nfor.args; argp; argp = argp->narg.next) {
9367                 expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
9368         }
9369         *arglist.lastp = NULL;
9370
9371         loopnest++;
9372         flags &= EV_TESTED;
9373         for (sp = arglist.list; sp; sp = sp->next) {
9374                 setvar0(n->nfor.var, sp->text);
9375                 status = evaltree(n->nfor.body, flags);
9376                 if (skiploop() & ~SKIPCONT)
9377                         break;
9378         }
9379         loopnest--;
9380
9381         return status;
9382 }
9383
9384 static int
9385 evalcase(union node *n, int flags)
9386 {
9387         union node *cp;
9388         union node *patp;
9389         struct arglist arglist;
9390         int status = 0;
9391
9392         errlinno = lineno = n->ncase.linno;
9393         if (funcline)
9394                 lineno -= funcline - 1;
9395
9396         arglist.list = NULL;
9397         arglist.lastp = &arglist.list;
9398         expandarg(n->ncase.expr, &arglist, EXP_TILDE);
9399         for (cp = n->ncase.cases; cp && evalskip == 0; cp = cp->nclist.next) {
9400                 for (patp = cp->nclist.pattern; patp; patp = patp->narg.next) {
9401                         if (casematch(patp, arglist.list->text)) {
9402                                 /* Ensure body is non-empty as otherwise
9403                                  * EV_EXIT may prevent us from setting the
9404                                  * exit status.
9405                                  */
9406                                 if (evalskip == 0 && cp->nclist.body) {
9407                                         status = evaltree(cp->nclist.body, flags);
9408                                 }
9409                                 goto out;
9410                         }
9411                 }
9412         }
9413  out:
9414         return status;
9415 }
9416
9417 /*
9418  * Kick off a subshell to evaluate a tree.
9419  */
9420 static int
9421 evalsubshell(union node *n, int flags)
9422 {
9423         struct job *jp;
9424         int backgnd = (n->type == NBACKGND); /* FORK_BG(1) if yes, else FORK_FG(0) */
9425         int status;
9426
9427         errlinno = lineno = n->nredir.linno;
9428         if (funcline)
9429                 lineno -= funcline - 1;
9430
9431         expredir(n->nredir.redirect);
9432         if (!backgnd && (flags & EV_EXIT) && !may_have_traps)
9433                 goto nofork;
9434         INT_OFF;
9435         if (backgnd == FORK_FG)
9436                 get_tty_state();
9437         jp = makejob(/*n,*/ 1);
9438         if (forkshell(jp, n, backgnd) == 0) {
9439                 /* child */
9440                 INT_ON;
9441                 flags |= EV_EXIT;
9442                 if (backgnd)
9443                         flags &= ~EV_TESTED;
9444  nofork:
9445                 redirect(n->nredir.redirect, 0);
9446                 evaltreenr(n->nredir.n, flags);
9447                 /* never returns */
9448         }
9449         /* parent */
9450         status = 0;
9451         if (backgnd == FORK_FG)
9452                 status = waitforjob(jp);
9453         INT_ON;
9454         return status;
9455 }
9456
9457 /*
9458  * Compute the names of the files in a redirection list.
9459  */
9460 static void fixredir(union node *, const char *, int);
9461 static void
9462 expredir(union node *n)
9463 {
9464         union node *redir;
9465
9466         for (redir = n; redir; redir = redir->nfile.next) {
9467                 struct arglist fn;
9468
9469                 fn.list = NULL;
9470                 fn.lastp = &fn.list;
9471                 switch (redir->type) {
9472                 case NFROMTO:
9473                 case NFROM:
9474                 case NTO:
9475 #if BASH_REDIR_OUTPUT
9476                 case NTO2:
9477 #endif
9478                 case NCLOBBER:
9479                 case NAPPEND:
9480                         expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR);
9481                         TRACE(("expredir expanded to '%s'\n", fn.list->text));
9482 #if BASH_REDIR_OUTPUT
9483  store_expfname:
9484 #endif
9485 #if 0
9486 // By the design of stack allocator, the loop of this kind:
9487 //      while true; do while true; do break; done </dev/null; done
9488 // will look like a memory leak: ash plans to free expfname's
9489 // of "/dev/null" as soon as it finishes running the loop
9490 // (in this case, never).
9491 // This "fix" is wrong:
9492                         if (redir->nfile.expfname)
9493                                 stunalloc(redir->nfile.expfname);
9494 // It results in corrupted state of stacked allocations.
9495 #endif
9496                         redir->nfile.expfname = fn.list->text;
9497                         break;
9498                 case NFROMFD:
9499                 case NTOFD: /* >& */
9500                         if (redir->ndup.vname) {
9501                                 expandarg(redir->ndup.vname, &fn, EXP_TILDE | EXP_REDIR);
9502                                 if (fn.list == NULL)
9503                                         ash_msg_and_raise_error("redir error");
9504 #if BASH_REDIR_OUTPUT
9505                                 if (!isdigit_str9(fn.list->text)) {
9506                                         /* >&file, not >&fd */
9507                                         if (redir->nfile.fd != 1) /* 123>&file - BAD */
9508                                                 ash_msg_and_raise_error("redir error");
9509                                         redir->type = NTO2;
9510                                         goto store_expfname;
9511                                 }
9512 #endif
9513                                 fixredir(redir, fn.list->text, 1);
9514                         }
9515                         break;
9516                 }
9517         }
9518 }
9519
9520 /*
9521  * Evaluate a pipeline.  All the processes in the pipeline are children
9522  * of the process creating the pipeline.  (This differs from some versions
9523  * of the shell, which make the last process in a pipeline the parent
9524  * of all the rest.)
9525  */
9526 static int
9527 evalpipe(union node *n, int flags)
9528 {
9529         struct job *jp;
9530         struct nodelist *lp;
9531         int pipelen;
9532         int prevfd;
9533         int pip[2];
9534         int status = 0;
9535
9536         TRACE(("evalpipe(0x%lx) called\n", (long)n));
9537         pipelen = 0;
9538         for (lp = n->npipe.cmdlist; lp; lp = lp->next)
9539                 pipelen++;
9540         flags |= EV_EXIT;
9541         INT_OFF;
9542         if (n->npipe.pipe_backgnd == 0)
9543                 get_tty_state();
9544         jp = makejob(/*n,*/ pipelen);
9545         prevfd = -1;
9546         for (lp = n->npipe.cmdlist; lp; lp = lp->next) {
9547                 prehash(lp->n);
9548                 pip[1] = -1;
9549                 if (lp->next) {
9550                         if (pipe(pip) < 0) {
9551                                 close(prevfd);
9552                                 ash_msg_and_raise_perror("can't create pipe");
9553                         }
9554                 }
9555                 if (forkshell(jp, lp->n, n->npipe.pipe_backgnd) == 0) {
9556                         /* child */
9557                         INT_ON;
9558                         if (pip[1] >= 0) {
9559                                 close(pip[0]);
9560                         }
9561                         if (prevfd > 0) {
9562                                 dup2(prevfd, 0);
9563                                 close(prevfd);
9564                         }
9565                         if (pip[1] > 1) {
9566                                 dup2(pip[1], 1);
9567                                 close(pip[1]);
9568                         }
9569                         evaltreenr(lp->n, flags);
9570                         /* never returns */
9571                 }
9572                 /* parent */
9573                 if (prevfd >= 0)
9574                         close(prevfd);
9575                 prevfd = pip[0];
9576                 /* Don't want to trigger debugging */
9577                 if (pip[1] != -1)
9578                         close(pip[1]);
9579         }
9580         if (n->npipe.pipe_backgnd == 0) {
9581                 status = waitforjob(jp);
9582                 TRACE(("evalpipe:  job done exit status %d\n", status));
9583         }
9584         INT_ON;
9585
9586         return status;
9587 }
9588
9589 /* setinteractive needs this forward reference */
9590 #if EDITING_HAS_get_exe_name
9591 static const char *get_builtin_name(int i) FAST_FUNC;
9592 #endif
9593
9594 /*
9595  * Controls whether the shell is interactive or not.
9596  */
9597 static void
9598 setinteractive(int on)
9599 {
9600         static smallint is_interactive;
9601
9602         if (++on == is_interactive)
9603                 return;
9604         is_interactive = on;
9605         setsignal(SIGINT);
9606         setsignal(SIGQUIT);
9607         setsignal(SIGTERM);
9608         if (is_interactive > 1) {
9609 #if !ENABLE_FEATURE_SH_EXTRA_QUIET
9610                 /* Looks like they want an interactive shell */
9611                 static smallint did_banner;
9612
9613                 if (!did_banner) {
9614                         /* note: ash and hush share this string */
9615                         out1fmt("\n\n%s %s\n"
9616                                 IF_ASH_HELP("Enter 'help' for a list of built-in commands.\n")
9617                                 "\n",
9618                                 bb_banner,
9619                                 "built-in shell (ash)"
9620                         );
9621                         did_banner = 1;
9622                 }
9623 #endif
9624 #if ENABLE_FEATURE_EDITING
9625                 if (!line_input_state) {
9626                         line_input_state = new_line_input_t(FOR_SHELL | WITH_PATH_LOOKUP);
9627 # if EDITING_HAS_get_exe_name
9628                         line_input_state->get_exe_name = get_builtin_name;
9629 # endif
9630                 }
9631 #endif
9632         }
9633 }
9634
9635 static void
9636 optschanged(void)
9637 {
9638 #if DEBUG
9639         opentrace();
9640 #endif
9641         setinteractive(iflag);
9642         setjobctl(mflag);
9643 #if ENABLE_FEATURE_EDITING_VI
9644         if (line_input_state) {
9645                 if (viflag)
9646                         line_input_state->flags |= VI_MODE;
9647                 else
9648                         line_input_state->flags &= ~VI_MODE;
9649         }
9650 #else
9651         viflag = 0; /* forcibly keep the option off */
9652 #endif
9653 }
9654
9655 struct localvar_list {
9656         struct localvar_list *next;
9657         struct localvar *lv;
9658 };
9659
9660 static struct localvar_list *localvar_stack;
9661
9662 /*
9663  * Called after a function returns.
9664  * Interrupts must be off.
9665  */
9666 static void
9667 poplocalvars(int keep)
9668 {
9669         struct localvar_list *ll;
9670         struct localvar *lvp, *next;
9671         struct var *vp;
9672
9673         INT_OFF;
9674         ll = localvar_stack;
9675         localvar_stack = ll->next;
9676
9677         next = ll->lv;
9678         free(ll);
9679
9680         while ((lvp = next) != NULL) {
9681                 next = lvp->next;
9682                 vp = lvp->vp;
9683                 TRACE(("poplocalvar %s\n", vp ? vp->var_text : "-"));
9684                 if (keep) {
9685                         int bits = VSTRFIXED;
9686
9687                         if (lvp->flags != VUNSET) {
9688                                 if (vp->var_text == lvp->text)
9689                                         bits |= VTEXTFIXED;
9690                                 else if (!(lvp->flags & (VTEXTFIXED|VSTACK)))
9691                                         free((char*)lvp->text);
9692                         }
9693
9694                         vp->flags &= ~bits;
9695                         vp->flags |= (lvp->flags & bits);
9696
9697                         if ((vp->flags &
9698                              (VEXPORT|VREADONLY|VSTRFIXED|VUNSET)) == VUNSET)
9699                                 unsetvar(vp->var_text);
9700                 } else if (vp == NULL) {        /* $- saved */
9701                         memcpy(optlist, lvp->text, sizeof(optlist));
9702                         free((char*)lvp->text);
9703                         optschanged();
9704                 } else if (lvp->flags == VUNSET) {
9705                         vp->flags &= ~(VSTRFIXED|VREADONLY);
9706                         unsetvar(vp->var_text);
9707                 } else {
9708                         if (vp->var_func)
9709                                 vp->var_func(var_end(lvp->text));
9710                         if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0)
9711                                 free((char*)vp->var_text);
9712                         vp->flags = lvp->flags;
9713                         vp->var_text = lvp->text;
9714                 }
9715                 free(lvp);
9716         }
9717         INT_ON;
9718 }
9719
9720 /*
9721  * Create a new localvar environment.
9722  */
9723 static struct localvar_list *
9724 pushlocalvars(int push)
9725 {
9726         struct localvar_list *ll;
9727         struct localvar_list *top;
9728
9729         top = localvar_stack;
9730         if (!push)
9731                 goto out;
9732
9733         INT_OFF;
9734         ll = ckzalloc(sizeof(*ll));
9735         /*ll->lv = NULL; - zalloc did it */
9736         ll->next = top;
9737         localvar_stack = ll;
9738         INT_ON;
9739  out:
9740         return top;
9741 }
9742
9743 static void
9744 unwindlocalvars(struct localvar_list *stop)
9745 {
9746         while (localvar_stack != stop)
9747                 poplocalvars(0);
9748 }
9749
9750 static int
9751 evalfun(struct funcnode *func, int argc, char **argv, int flags)
9752 {
9753         volatile struct shparam saveparam;
9754         struct jmploc *volatile savehandler;
9755         struct jmploc jmploc;
9756         int e;
9757         int savefuncline;
9758
9759         saveparam = shellparam;
9760         savefuncline = funcline;
9761         savehandler = exception_handler;
9762         e = setjmp(jmploc.loc);
9763         if (e) {
9764                 goto funcdone;
9765         }
9766         INT_OFF;
9767         exception_handler = &jmploc;
9768         shellparam.malloced = 0;
9769         func->count++;
9770         funcline = func->n.ndefun.linno;
9771         INT_ON;
9772         shellparam.nparam = argc - 1;
9773         shellparam.p = argv + 1;
9774 #if ENABLE_ASH_GETOPTS
9775         shellparam.optind = 1;
9776         shellparam.optoff = -1;
9777 #endif
9778         evaltree(func->n.ndefun.body, flags & EV_TESTED);
9779  funcdone:
9780         INT_OFF;
9781         funcline = savefuncline;
9782         freefunc(func);
9783         freeparam(&shellparam);
9784         shellparam = saveparam;
9785         exception_handler = savehandler;
9786         INT_ON;
9787         evalskip &= ~(SKIPFUNC | SKIPFUNCDEF);
9788         return e;
9789 }
9790
9791 /*
9792  * Make a variable a local variable.  When a variable is made local, it's
9793  * value and flags are saved in a localvar structure.  The saved values
9794  * will be restored when the shell function returns.  We handle the name
9795  * "-" as a special case: it makes changes to "set +-options" local
9796  * (options will be restored on return from the function).
9797  */
9798 static void
9799 mklocal(char *name, int flags)
9800 {
9801         struct localvar *lvp;
9802         struct var **vpp;
9803         struct var *vp;
9804         char *eq = strchr(name, '=');
9805
9806         INT_OFF;
9807         /* Cater for duplicate "local". Examples:
9808          * x=0; f() { local x=1; echo $x; local x; echo $x; }; f; echo $x
9809          * x=0; f() { local x=1; echo $x; local x=2; echo $x; }; f; echo $x
9810          */
9811         lvp = localvar_stack->lv;
9812         while (lvp) {
9813                 if (lvp->vp && varcmp(lvp->vp->var_text, name) == 0) {
9814                         if (eq)
9815                                 setvareq(name, 0);
9816                         /* else:
9817                          * it's a duplicate "local VAR" declaration, do nothing
9818                          */
9819                         goto ret;
9820                 }
9821                 lvp = lvp->next;
9822         }
9823
9824         lvp = ckzalloc(sizeof(*lvp));
9825         if (LONE_DASH(name)) {
9826                 char *p;
9827                 p = ckmalloc(sizeof(optlist));
9828                 lvp->text = memcpy(p, optlist, sizeof(optlist));
9829                 vp = NULL;
9830         } else {
9831                 vpp = hashvar(name);
9832                 vp = *findvar(vpp, name);
9833                 if (vp == NULL) {
9834                         /* variable did not exist yet */
9835                         if (eq)
9836                                 vp = setvareq(name, VSTRFIXED | flags);
9837                         else
9838                                 vp = setvar(name, NULL, VSTRFIXED | flags);
9839                         lvp->flags = VUNSET;
9840                 } else {
9841                         lvp->text = vp->var_text;
9842                         lvp->flags = vp->flags;
9843                         /* make sure neither "struct var" nor string gets freed
9844                          * during (un)setting:
9845                          */
9846                         vp->flags |= VSTRFIXED|VTEXTFIXED;
9847                         if (eq)
9848                                 setvareq(name, flags);
9849                         else
9850                                 /* "local VAR" unsets VAR: */
9851                                 setvar0(name, NULL);
9852                 }
9853         }
9854         lvp->vp = vp;
9855         lvp->next = localvar_stack->lv;
9856         localvar_stack->lv = lvp;
9857  ret:
9858         INT_ON;
9859 }
9860
9861 /*
9862  * The "local" command.
9863  */
9864 static int FAST_FUNC
9865 localcmd(int argc UNUSED_PARAM, char **argv)
9866 {
9867         char *name;
9868
9869         if (!localvar_stack)
9870                 ash_msg_and_raise_error("not in a function");
9871
9872         argv = argptr;
9873         while ((name = *argv++) != NULL) {
9874                 mklocal(name, 0);
9875         }
9876         return 0;
9877 }
9878
9879 static int FAST_FUNC
9880 falsecmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
9881 {
9882         return 1;
9883 }
9884
9885 static int FAST_FUNC
9886 truecmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
9887 {
9888         return 0;
9889 }
9890
9891 static int FAST_FUNC
9892 execcmd(int argc UNUSED_PARAM, char **argv)
9893 {
9894         optionarg = NULL;
9895         while (nextopt("a:") != '\0')
9896                 /* nextopt() sets optionarg to "-a ARGV0" */;
9897
9898         argv = argptr;
9899         if (argv[0]) {
9900                 char *prog;
9901
9902                 iflag = 0;              /* exit on error */
9903                 mflag = 0;
9904                 optschanged();
9905                 /* We should set up signals for "exec CMD"
9906                  * the same way as for "CMD" without "exec".
9907                  * But optschanged->setinteractive->setsignal
9908                  * still thought we are a root shell. Therefore, for example,
9909                  * SIGQUIT is still set to IGN. Fix it:
9910                  */
9911                 shlvl++;
9912                 setsignal(SIGQUIT);
9913                 /*setsignal(SIGTERM); - unnecessary because of iflag=0 */
9914                 /*setsignal(SIGTSTP); - unnecessary because of mflag=0 */
9915                 /*setsignal(SIGTTOU); - unnecessary because of mflag=0 */
9916
9917                 prog = argv[0];
9918                 if (optionarg)
9919                         argv[0] = optionarg;
9920                 shellexec(prog, argv, pathval(), 0);
9921                 /* NOTREACHED */
9922         }
9923         return 0;
9924 }
9925
9926 /*
9927  * The return command.
9928  */
9929 static int FAST_FUNC
9930 returncmd(int argc UNUSED_PARAM, char **argv)
9931 {
9932         int skip;
9933         int status;
9934
9935         /*
9936          * If called outside a function, do what ksh does;
9937          * skip the rest of the file.
9938          */
9939         if (argv[1]) {
9940                 skip = SKIPFUNC;
9941                 status = number(argv[1]);
9942         } else {
9943                 skip = SKIPFUNCDEF;
9944                 status = exitstatus;
9945         }
9946         evalskip = skip;
9947
9948         return status;
9949 }
9950
9951 /* Forward declarations for builtintab[] */
9952 static int breakcmd(int, char **) FAST_FUNC;
9953 static int dotcmd(int, char **) FAST_FUNC;
9954 static int evalcmd(int, char **, int) FAST_FUNC;
9955 static int exitcmd(int, char **) FAST_FUNC;
9956 static int exportcmd(int, char **) FAST_FUNC;
9957 #if ENABLE_ASH_GETOPTS
9958 static int getoptscmd(int, char **) FAST_FUNC;
9959 #endif
9960 #if ENABLE_ASH_HELP
9961 static int helpcmd(int, char **) FAST_FUNC;
9962 #endif
9963 #if MAX_HISTORY
9964 static int historycmd(int, char **) FAST_FUNC;
9965 #endif
9966 #if ENABLE_FEATURE_SH_MATH
9967 static int letcmd(int, char **) FAST_FUNC;
9968 #endif
9969 static int readcmd(int, char **) FAST_FUNC;
9970 static int setcmd(int, char **) FAST_FUNC;
9971 static int shiftcmd(int, char **) FAST_FUNC;
9972 static int timescmd(int, char **) FAST_FUNC;
9973 static int trapcmd(int, char **) FAST_FUNC;
9974 static int umaskcmd(int, char **) FAST_FUNC;
9975 static int unsetcmd(int, char **) FAST_FUNC;
9976 static int ulimitcmd(int, char **) FAST_FUNC;
9977
9978 #define BUILTIN_NOSPEC          "0"
9979 #define BUILTIN_SPECIAL         "1"
9980 #define BUILTIN_REGULAR         "2"
9981 #define BUILTIN_SPEC_REG        "3"
9982 #define BUILTIN_ASSIGN          "4"
9983 #define BUILTIN_SPEC_ASSG       "5"
9984 #define BUILTIN_REG_ASSG        "6"
9985 #define BUILTIN_SPEC_REG_ASSG   "7"
9986
9987 /* Stubs for calling non-FAST_FUNC's */
9988 #if ENABLE_ASH_ECHO
9989 static int FAST_FUNC echocmd(int argc, char **argv)   { return echo_main(argc, argv); }
9990 #endif
9991 #if ENABLE_ASH_PRINTF
9992 static int FAST_FUNC printfcmd(int argc, char **argv) { return printf_main(argc, argv); }
9993 #endif
9994 #if ENABLE_ASH_TEST || BASH_TEST2
9995 static int FAST_FUNC testcmd(int argc, char **argv)   { return test_main(argc, argv); }
9996 #endif
9997
9998 /* Keep these in proper order since it is searched via bsearch() */
9999 static const struct builtincmd builtintab[] = {
10000         { BUILTIN_SPEC_REG      "."       , dotcmd     },
10001         { BUILTIN_SPEC_REG      ":"       , truecmd    },
10002 #if ENABLE_ASH_TEST
10003         { BUILTIN_REGULAR       "["       , testcmd    },
10004 #endif
10005 #if BASH_TEST2
10006         { BUILTIN_REGULAR       "[["      , testcmd    },
10007 #endif
10008 #if ENABLE_ASH_ALIAS
10009         { BUILTIN_REG_ASSG      "alias"   , aliascmd   },
10010 #endif
10011 #if JOBS
10012         { BUILTIN_REGULAR       "bg"      , fg_bgcmd   },
10013 #endif
10014         { BUILTIN_SPEC_REG      "break"   , breakcmd   },
10015         { BUILTIN_REGULAR       "cd"      , cdcmd      },
10016         { BUILTIN_NOSPEC        "chdir"   , cdcmd      },
10017 #if ENABLE_ASH_CMDCMD
10018         { BUILTIN_REGULAR       "command" , commandcmd },
10019 #endif
10020         { BUILTIN_SPEC_REG      "continue", breakcmd   },
10021 #if ENABLE_ASH_ECHO
10022         { BUILTIN_REGULAR       "echo"    , echocmd    },
10023 #endif
10024         { BUILTIN_SPEC_REG      "eval"    , NULL       }, /*evalcmd() has a differing prototype*/
10025         { BUILTIN_SPEC_REG      "exec"    , execcmd    },
10026         { BUILTIN_SPEC_REG      "exit"    , exitcmd    },
10027         { BUILTIN_SPEC_REG_ASSG "export"  , exportcmd  },
10028         { BUILTIN_REGULAR       "false"   , falsecmd   },
10029 #if JOBS
10030         { BUILTIN_REGULAR       "fg"      , fg_bgcmd   },
10031 #endif
10032 #if ENABLE_ASH_GETOPTS
10033         { BUILTIN_REGULAR       "getopts" , getoptscmd },
10034 #endif
10035         { BUILTIN_REGULAR       "hash"    , hashcmd    },
10036 #if ENABLE_ASH_HELP
10037         { BUILTIN_NOSPEC        "help"    , helpcmd    },
10038 #endif
10039 #if MAX_HISTORY
10040         { BUILTIN_NOSPEC        "history" , historycmd },
10041 #endif
10042 #if JOBS
10043         { BUILTIN_REGULAR       "jobs"    , jobscmd    },
10044         { BUILTIN_REGULAR       "kill"    , killcmd    },
10045 #endif
10046 #if ENABLE_FEATURE_SH_MATH
10047         { BUILTIN_NOSPEC        "let"     , letcmd     },
10048 #endif
10049         { BUILTIN_SPEC_REG_ASSG "local"   , localcmd   },
10050 #if ENABLE_ASH_PRINTF
10051         { BUILTIN_REGULAR       "printf"  , printfcmd  },
10052 #endif
10053         { BUILTIN_REGULAR       "pwd"     , pwdcmd     },
10054         { BUILTIN_REGULAR       "read"    , readcmd    },
10055         { BUILTIN_SPEC_REG_ASSG "readonly", exportcmd  },
10056         { BUILTIN_SPEC_REG      "return"  , returncmd  },
10057         { BUILTIN_SPEC_REG      "set"     , setcmd     },
10058         { BUILTIN_SPEC_REG      "shift"   , shiftcmd   },
10059 #if BASH_SOURCE
10060         { BUILTIN_SPEC_REG      "source"  , dotcmd     },
10061 #endif
10062 #if ENABLE_ASH_TEST
10063         { BUILTIN_REGULAR       "test"    , testcmd    },
10064 #endif
10065         { BUILTIN_SPEC_REG      "times"   , timescmd   },
10066         { BUILTIN_SPEC_REG      "trap"    , trapcmd    },
10067         { BUILTIN_REGULAR       "true"    , truecmd    },
10068         { BUILTIN_REGULAR       "type"    , typecmd    },
10069         { BUILTIN_REGULAR       "ulimit"  , ulimitcmd  },
10070         { BUILTIN_REGULAR       "umask"   , umaskcmd   },
10071 #if ENABLE_ASH_ALIAS
10072         { BUILTIN_REGULAR       "unalias" , unaliascmd },
10073 #endif
10074         { BUILTIN_SPEC_REG      "unset"   , unsetcmd   },
10075         { BUILTIN_REGULAR       "wait"    , waitcmd    },
10076 };
10077
10078 /* Should match the above table! */
10079 #define COMMANDCMD (builtintab + \
10080         /* . : */       2 + \
10081         /* [ */         1 * ENABLE_ASH_TEST + \
10082         /* [[ */        1 * BASH_TEST2 + \
10083         /* alias */     1 * ENABLE_ASH_ALIAS + \
10084         /* bg */        1 * ENABLE_ASH_JOB_CONTROL + \
10085         /* break cd cddir  */   3)
10086 #define EVALCMD (COMMANDCMD + \
10087         /* command */   1 * ENABLE_ASH_CMDCMD + \
10088         /* continue */  1 + \
10089         /* echo */      1 * ENABLE_ASH_ECHO + \
10090         0)
10091 #define EXECCMD (EVALCMD + \
10092         /* eval */      1)
10093
10094 /*
10095  * Search the table of builtin commands.
10096  */
10097 static int
10098 pstrcmp1(const void *a, const void *b)
10099 {
10100         return strcmp((char*)a, *(char**)b + 1);
10101 }
10102 static struct builtincmd *
10103 find_builtin(const char *name)
10104 {
10105         struct builtincmd *bp;
10106
10107         bp = bsearch(
10108                 name, builtintab, ARRAY_SIZE(builtintab), sizeof(builtintab[0]),
10109                 pstrcmp1
10110         );
10111         return bp;
10112 }
10113
10114 #if EDITING_HAS_get_exe_name
10115 static const char * FAST_FUNC
10116 get_builtin_name(int i)
10117 {
10118         return /*i >= 0 &&*/ i < ARRAY_SIZE(builtintab) ? builtintab[i].name + 1 : NULL;
10119 }
10120 #endif
10121
10122 /*
10123  * Execute a simple command.
10124  */
10125 static void unwindfiles(struct parsefile *stop);
10126 static int
10127 isassignment(const char *p)
10128 {
10129         const char *q = endofname(p);
10130         if (p == q)
10131                 return 0;
10132         return *q == '=';
10133 }
10134 static int FAST_FUNC
10135 bltincmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
10136 {
10137         /* Preserve exitstatus of a previous possible redirection
10138          * as POSIX mandates */
10139         return back_exitstatus;
10140 }
10141 static int
10142 evalcommand(union node *cmd, int flags)
10143 {
10144         static const struct builtincmd null_bltin = {
10145                 BUILTIN_REGULAR "", bltincmd
10146         };
10147         struct localvar_list *localvar_stop;
10148         struct parsefile *file_stop;
10149         struct redirtab *redir_stop;
10150         union node *argp;
10151         struct arglist arglist;
10152         struct arglist varlist;
10153         char **argv;
10154         int argc;
10155         struct strlist *osp;
10156         const struct strlist *sp;
10157         struct cmdentry cmdentry;
10158         struct job *jp;
10159         char *lastarg;
10160         const char *path;
10161         int spclbltin;
10162         int cmd_flag;
10163         int status;
10164         char **nargv;
10165         smallint cmd_is_exec;
10166         int vflags;
10167         int vlocal;
10168
10169         errlinno = lineno = cmd->ncmd.linno;
10170         if (funcline)
10171                 lineno -= funcline - 1;
10172
10173         /* First expand the arguments. */
10174         TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags));
10175         file_stop = g_parsefile;
10176         back_exitstatus = 0;
10177
10178         cmdentry.cmdtype = CMDBUILTIN;
10179         cmdentry.u.cmd = &null_bltin;
10180         varlist.lastp = &varlist.list;
10181         *varlist.lastp = NULL;
10182         arglist.lastp = &arglist.list;
10183         *arglist.lastp = NULL;
10184
10185         cmd_flag = 0;
10186         cmd_is_exec = 0;
10187         spclbltin = -1;
10188         vflags = 0;
10189         vlocal = 0;
10190         path = NULL;
10191
10192         argc = 0;
10193         argp = cmd->ncmd.args;
10194         osp = fill_arglist(&arglist, &argp);
10195         if (osp) {
10196                 int pseudovarflag = 0;
10197
10198                 for (;;) {
10199                         find_command(arglist.list->text, &cmdentry,
10200                                         cmd_flag | DO_REGBLTIN, pathval());
10201
10202                         vlocal++;
10203
10204                         /* implement bltin and command here */
10205                         if (cmdentry.cmdtype != CMDBUILTIN)
10206                                 break;
10207
10208                         pseudovarflag = IS_BUILTIN_ASSIGN(cmdentry.u.cmd);
10209                         if (spclbltin < 0) {
10210                                 spclbltin = IS_BUILTIN_SPECIAL(cmdentry.u.cmd);
10211                                 vlocal = !spclbltin;
10212                         }
10213                         cmd_is_exec = cmdentry.u.cmd == EXECCMD;
10214                         if (cmdentry.u.cmd != COMMANDCMD)
10215                                 break;
10216
10217                         cmd_flag = parse_command_args(&arglist, &argp, &path);
10218                         if (!cmd_flag)
10219                                 break;
10220                 }
10221
10222                 for (; argp; argp = argp->narg.next)
10223                         expandarg(argp, &arglist,
10224                                         pseudovarflag &&
10225                                         isassignment(argp->narg.text) ?
10226                                         EXP_VARTILDE : EXP_FULL | EXP_TILDE);
10227
10228                 for (sp = arglist.list; sp; sp = sp->next)
10229                         argc++;
10230
10231                 if (cmd_is_exec && argc > 1)
10232                         vflags = VEXPORT;
10233         }
10234
10235         localvar_stop = pushlocalvars(vlocal);
10236
10237         /* Reserve one extra spot at the front for shellexec. */
10238         nargv = stalloc(sizeof(char *) * (argc + 2));
10239         argv = ++nargv;
10240         for (sp = arglist.list; sp; sp = sp->next) {
10241                 TRACE(("evalcommand arg: %s\n", sp->text));
10242                 *nargv++ = sp->text;
10243         }
10244         *nargv = NULL;
10245
10246         lastarg = NULL;
10247         if (iflag && funcline == 0 && argc > 0)
10248                 lastarg = nargv[-1];
10249
10250         expredir(cmd->ncmd.redirect);
10251         redir_stop = pushredir(cmd->ncmd.redirect);
10252         preverrout_fd = 2;
10253         if (BASH_XTRACEFD && xflag) {
10254                 /* NB: bash closes fd == $BASH_XTRACEFD when it is changed.
10255                  * we do not emulate this. We only use its value.
10256                  */
10257                 const char *xtracefd = lookupvar("BASH_XTRACEFD");
10258                 if (xtracefd && is_number(xtracefd))
10259                         preverrout_fd = atoi(xtracefd);
10260
10261         }
10262         status = redirectsafe(cmd->ncmd.redirect, REDIR_PUSH | REDIR_SAVEFD2);
10263
10264         if (status) {
10265  bail:
10266                 exitstatus = status;
10267
10268                 /* We have a redirection error. */
10269                 if (spclbltin > 0)
10270                         raise_exception(EXERROR);
10271
10272                 goto out;
10273         }
10274
10275         for (argp = cmd->ncmd.assign; argp; argp = argp->narg.next) {
10276                 struct strlist **spp;
10277
10278                 spp = varlist.lastp;
10279                 expandarg(argp, &varlist, EXP_VARTILDE);
10280
10281                 if (vlocal)
10282                         mklocal((*spp)->text, VEXPORT);
10283                 else
10284                         setvareq((*spp)->text, vflags);
10285         }
10286
10287         /* Print the command if xflag is set. */
10288         if (xflag) {
10289                 const char *pfx = "";
10290
10291                 fdprintf(preverrout_fd, "%s", expandstr(ps4val(), DQSYNTAX));
10292
10293                 sp = varlist.list;
10294                 while (sp) {
10295                         char *varval = sp->text;
10296                         char *eq = strchrnul(varval, '=');
10297                         if (*eq)
10298                                 eq++;
10299                         fdprintf(preverrout_fd, "%s%.*s%s",
10300                                 pfx,
10301                                 (int)(eq - varval), varval,
10302                                 maybe_single_quote(eq)
10303                         );
10304                         sp = sp->next;
10305                         pfx = " ";
10306                 }
10307
10308                 sp = arglist.list;
10309                 while (sp) {
10310                         fdprintf(preverrout_fd, "%s%s",
10311                                 pfx,
10312                                 /* always quote if matches reserved word: */
10313                                 findkwd(sp->text)
10314                                 ? single_quote(sp->text)
10315                                 : maybe_single_quote(sp->text)
10316                         );
10317                         sp = sp->next;
10318                         pfx = " ";
10319                 }
10320                 safe_write(preverrout_fd, "\n", 1);
10321         }
10322
10323         /* Now locate the command. */
10324         if (cmdentry.cmdtype != CMDBUILTIN
10325          || !(IS_BUILTIN_REGULAR(cmdentry.u.cmd))
10326         ) {
10327                 path = path ? path : pathval();
10328                 find_command(argv[0], &cmdentry, cmd_flag | DO_ERR, path);
10329         }
10330
10331         jp = NULL;
10332
10333         /* Execute the command. */
10334         switch (cmdentry.cmdtype) {
10335         case CMDUNKNOWN:
10336                 status = 127;
10337                 flush_stdout_stderr();
10338                 goto bail;
10339
10340         default: {
10341
10342 #if ENABLE_FEATURE_SH_STANDALONE \
10343  && ENABLE_FEATURE_SH_NOFORK \
10344  && NUM_APPLETS > 1
10345 /* (1) BUG: if variables are set, we need to fork, or save/restore them
10346  *     around run_nofork_applet() call.
10347  * (2) Should this check also be done in forkshell()?
10348  *     (perhaps it should, so that "VAR=VAL nofork" at least avoids exec...)
10349  */
10350                 /* find_command() encodes applet_no as (-2 - applet_no) */
10351                 int applet_no = (- cmdentry.u.index - 2);
10352                 if (applet_no >= 0 && APPLET_IS_NOFORK(applet_no)) {
10353                         char **sv_environ;
10354
10355                         INT_OFF;
10356                         sv_environ = environ;
10357                         environ = listvars(VEXPORT, VUNSET, varlist.list, /*end:*/ NULL);
10358                         /*
10359                          * Run <applet>_main().
10360                          * Signals (^C) can't interrupt here.
10361                          * Otherwise we can mangle stdio or malloc internal state.
10362                          * This makes applets which can run for a long time
10363                          * and/or wait for user input ineligible for NOFORK:
10364                          * for example, "yes" or "rm" (rm -i waits for input).
10365                          */
10366                         exitstatus = run_nofork_applet(applet_no, argv);
10367                         environ = sv_environ;
10368                         /*
10369                          * Try enabling NOFORK for "yes" applet.
10370                          * ^C _will_ stop it (write returns EINTR),
10371                          * but this causes stdout FILE to be stuck
10372                          * and needing clearerr(). What if other applets
10373                          * also can get EINTRs? Do we need to switch
10374                          * our signals to SA_RESTART?
10375                          */
10376                         /*clearerr(stdout);*/
10377                         INT_ON;
10378                         break;
10379                 }
10380 #endif
10381                 /* Can we avoid forking? For example, very last command
10382                  * in a script or a subshell does not need forking,
10383                  * we can just exec it.
10384                  */
10385                 if (!(flags & EV_EXIT) || may_have_traps) {
10386                         /* No, forking off a child is necessary */
10387                         INT_OFF;
10388                         get_tty_state();
10389                         jp = makejob(/*cmd,*/ 1);
10390                         if (forkshell(jp, cmd, FORK_FG) != 0) {
10391                                 /* parent */
10392                                 TRACE(("forked child exited with %d\n", status));
10393                                 break;
10394                         }
10395                         /* child */
10396                         FORCE_INT_ON;
10397                         /* fall through to exec'ing external program */
10398                 }
10399                 shellexec(argv[0], argv, path, cmdentry.u.index);
10400                 /* NOTREACHED */
10401         } /* default */
10402         case CMDBUILTIN:
10403                 if (evalbltin(cmdentry.u.cmd, argc, argv, flags)
10404                  && !(exception_type == EXERROR && spclbltin <= 0)
10405                 ) {
10406  raise:
10407                         longjmp(exception_handler->loc, 1);
10408                 }
10409                 break;
10410
10411         case CMDFUNCTION:
10412                 if (evalfun(cmdentry.u.func, argc, argv, flags))
10413                         goto raise;
10414                 break;
10415         } /* switch */
10416
10417         status = waitforjob(jp);
10418         FORCE_INT_ON;
10419
10420  out:
10421         if (cmd->ncmd.redirect)
10422                 popredir(/*drop:*/ cmd_is_exec);
10423         unwindredir(redir_stop);
10424         unwindfiles(file_stop);
10425         unwindlocalvars(localvar_stop);
10426         if (lastarg) {
10427                 /* dsl: I think this is intended to be used to support
10428                  * '_' in 'vi' command mode during line editing...
10429                  * However I implemented that within libedit itself.
10430                  */
10431                 setvar0("_", lastarg);
10432         }
10433
10434         return status;
10435 }
10436
10437 static int
10438 evalbltin(const struct builtincmd *cmd, int argc, char **argv, int flags)
10439 {
10440         char *volatile savecmdname;
10441         struct jmploc *volatile savehandler;
10442         struct jmploc jmploc;
10443         int status;
10444         int i;
10445
10446         savecmdname = commandname;
10447         savehandler = exception_handler;
10448         i = setjmp(jmploc.loc);
10449         if (i)
10450                 goto cmddone;
10451         exception_handler = &jmploc;
10452         commandname = argv[0];
10453         argptr = argv + 1;
10454         optptr = NULL;                  /* initialize nextopt */
10455         if (cmd == EVALCMD)
10456                 status = evalcmd(argc, argv, flags);
10457         else
10458                 status = (*cmd->builtin)(argc, argv);
10459         flush_stdout_stderr();
10460         status |= ferror(stdout);
10461         exitstatus = status;
10462  cmddone:
10463         clearerr(stdout);
10464         commandname = savecmdname;
10465         exception_handler = savehandler;
10466
10467         return i;
10468 }
10469
10470 static int
10471 goodname(const char *p)
10472 {
10473         return endofname(p)[0] == '\0';
10474 }
10475
10476
10477 /*
10478  * Search for a command.  This is called before we fork so that the
10479  * location of the command will be available in the parent as well as
10480  * the child.  The check for "goodname" is an overly conservative
10481  * check that the name will not be subject to expansion.
10482  */
10483 static void
10484 prehash(union node *n)
10485 {
10486         struct cmdentry entry;
10487
10488         if (n->type == NCMD && n->ncmd.args && goodname(n->ncmd.args->narg.text))
10489                 find_command(n->ncmd.args->narg.text, &entry, 0, pathval());
10490 }
10491
10492
10493 /* ============ Builtin commands
10494  *
10495  * Builtin commands whose functions are closely tied to evaluation
10496  * are implemented here.
10497  */
10498
10499 /*
10500  * Handle break and continue commands.  Break, continue, and return are
10501  * all handled by setting the evalskip flag.  The evaluation routines
10502  * above all check this flag, and if it is set they start skipping
10503  * commands rather than executing them.  The variable skipcount is
10504  * the number of loops to break/continue, or the number of function
10505  * levels to return.  (The latter is always 1.)  It should probably
10506  * be an error to break out of more loops than exist, but it isn't
10507  * in the standard shell so we don't make it one here.
10508  */
10509 static int FAST_FUNC
10510 breakcmd(int argc UNUSED_PARAM, char **argv)
10511 {
10512         int n = argv[1] ? number(argv[1]) : 1;
10513
10514         if (n <= 0)
10515                 ash_msg_and_raise_error(msg_illnum, argv[1]);
10516         if (n > loopnest)
10517                 n = loopnest;
10518         if (n > 0) {
10519                 evalskip = (**argv == 'c') ? SKIPCONT : SKIPBREAK;
10520                 skipcount = n;
10521         }
10522         return 0;
10523 }
10524
10525
10526 /*
10527  * This implements the input routines used by the parser.
10528  */
10529
10530 enum {
10531         INPUT_PUSH_FILE = 1,
10532         INPUT_NOFILE_OK = 2,
10533 };
10534
10535 static smallint checkkwd;
10536 /* values of checkkwd variable */
10537 #define CHKALIAS        0x1
10538 #define CHKKWD          0x2
10539 #define CHKNL           0x4
10540 #define CHKEOFMARK      0x8
10541
10542 /*
10543  * Push a string back onto the input at this current parsefile level.
10544  * We handle aliases this way.
10545  */
10546 #if !ENABLE_ASH_ALIAS
10547 #define pushstring(s, ap) pushstring(s)
10548 #endif
10549 static void
10550 pushstring(char *s, struct alias *ap)
10551 {
10552         struct strpush *sp;
10553         int len;
10554
10555         len = strlen(s);
10556         INT_OFF;
10557         if (g_parsefile->strpush) {
10558                 sp = ckzalloc(sizeof(*sp));
10559                 sp->prev = g_parsefile->strpush;
10560         } else {
10561                 sp = &(g_parsefile->basestrpush);
10562         }
10563         g_parsefile->strpush = sp;
10564         sp->prev_string = g_parsefile->next_to_pgetc;
10565         sp->prev_left_in_line = g_parsefile->left_in_line;
10566         sp->unget = g_parsefile->unget;
10567         memcpy(sp->lastc, g_parsefile->lastc, sizeof(sp->lastc));
10568 #if ENABLE_ASH_ALIAS
10569         sp->ap = ap;
10570         if (ap) {
10571                 ap->flag |= ALIASINUSE;
10572                 sp->string = s;
10573         }
10574 #endif
10575         g_parsefile->next_to_pgetc = s;
10576         g_parsefile->left_in_line = len;
10577         g_parsefile->unget = 0;
10578         INT_ON;
10579 }
10580
10581 static void
10582 popstring(void)
10583 {
10584         struct strpush *sp = g_parsefile->strpush;
10585
10586         INT_OFF;
10587 #if ENABLE_ASH_ALIAS
10588         if (sp->ap) {
10589                 if (g_parsefile->next_to_pgetc[-1] == ' '
10590                  || g_parsefile->next_to_pgetc[-1] == '\t'
10591                 ) {
10592                         checkkwd |= CHKALIAS;
10593                 }
10594                 if (sp->string != sp->ap->val) {
10595                         free(sp->string);
10596                 }
10597                 sp->ap->flag &= ~ALIASINUSE;
10598                 if (sp->ap->flag & ALIASDEAD) {
10599                         unalias(sp->ap->name);
10600                 }
10601         }
10602 #endif
10603         g_parsefile->next_to_pgetc = sp->prev_string;
10604         g_parsefile->left_in_line = sp->prev_left_in_line;
10605         g_parsefile->unget = sp->unget;
10606         memcpy(g_parsefile->lastc, sp->lastc, sizeof(sp->lastc));
10607         g_parsefile->strpush = sp->prev;
10608         if (sp != &(g_parsefile->basestrpush))
10609                 free(sp);
10610         INT_ON;
10611 }
10612
10613 static int
10614 preadfd(void)
10615 {
10616         int nr;
10617         char *buf = g_parsefile->buf;
10618
10619         g_parsefile->next_to_pgetc = buf;
10620 #if ENABLE_FEATURE_EDITING
10621  retry:
10622         if (!iflag || g_parsefile->pf_fd != STDIN_FILENO)
10623                 nr = nonblock_immune_read(g_parsefile->pf_fd, buf, IBUFSIZ - 1);
10624         else {
10625 # if ENABLE_ASH_IDLE_TIMEOUT
10626                 int timeout = -1;
10627                 const char *tmout_var = lookupvar("TMOUT");
10628                 if (tmout_var) {
10629                         timeout = atoi(tmout_var) * 1000;
10630                         if (timeout <= 0)
10631                                 timeout = -1;
10632                 }
10633                 line_input_state->timeout = timeout;
10634 # endif
10635 # if ENABLE_FEATURE_TAB_COMPLETION
10636                 line_input_state->path_lookup = pathval();
10637 # endif
10638                 reinit_unicode_for_ash();
10639                 nr = read_line_input(line_input_state, cmdedit_prompt, buf, IBUFSIZ);
10640                 if (nr == 0) {
10641                         /* ^C pressed, "convert" to SIGINT */
10642                         write(STDOUT_FILENO, "^C", 2);
10643                         if (trap[SIGINT]) {
10644                                 buf[0] = '\n';
10645                                 buf[1] = '\0';
10646                                 raise(SIGINT);
10647                                 return 1;
10648                         }
10649                         exitstatus = 128 + SIGINT;
10650                         bb_putchar('\n');
10651                         goto retry;
10652                 }
10653                 if (nr < 0) {
10654                         if (errno == 0) {
10655                                 /* Ctrl+D pressed */
10656                                 nr = 0;
10657                         }
10658 # if ENABLE_ASH_IDLE_TIMEOUT
10659                         else if (errno == EAGAIN && timeout > 0) {
10660                                 puts("\007timed out waiting for input: auto-logout");
10661                                 exitshell();
10662                         }
10663 # endif
10664                 }
10665         }
10666 #else
10667         nr = nonblock_immune_read(g_parsefile->pf_fd, buf, IBUFSIZ - 1);
10668 #endif
10669
10670 #if 0 /* disabled: nonblock_immune_read() handles this problem */
10671         if (nr < 0) {
10672                 if (parsefile->fd == 0 && errno == EWOULDBLOCK) {
10673                         int flags = fcntl(0, F_GETFL);
10674                         if (flags >= 0 && (flags & O_NONBLOCK)) {
10675                                 flags &= ~O_NONBLOCK;
10676                                 if (fcntl(0, F_SETFL, flags) >= 0) {
10677                                         out2str("sh: turning off NDELAY mode\n");
10678                                         goto retry;
10679                                 }
10680                         }
10681                 }
10682         }
10683 #endif
10684         return nr;
10685 }
10686
10687 /*
10688  * Refill the input buffer and return the next input character:
10689  *
10690  * 1) If a string was pushed back on the input, pop it;
10691  * 2) If an EOF was pushed back (g_parsefile->left_in_line < -BIGNUM)
10692  *    or we are reading from a string so we can't refill the buffer,
10693  *    return EOF.
10694  * 3) If there is more stuff in this buffer, use it else call read to fill it.
10695  * 4) Process input up to the next newline, deleting nul characters.
10696  */
10697 //#define pgetc_debug(...) bb_error_msg(__VA_ARGS__)
10698 #define pgetc_debug(...) ((void)0)
10699 static int pgetc(void);
10700 static int
10701 preadbuffer(void)
10702 {
10703         char *q;
10704         int more;
10705
10706         if (g_parsefile->strpush) {
10707 #if ENABLE_ASH_ALIAS
10708                 if (g_parsefile->left_in_line == -1
10709                  && g_parsefile->strpush->ap
10710                  && g_parsefile->next_to_pgetc[-1] != ' '
10711                  && g_parsefile->next_to_pgetc[-1] != '\t'
10712                 ) {
10713                         pgetc_debug("preadbuffer PEOA");
10714                         return PEOA;
10715                 }
10716 #endif
10717                 popstring();
10718                 return pgetc();
10719         }
10720         /* on both branches above g_parsefile->left_in_line < 0.
10721          * "pgetc" needs refilling.
10722          */
10723
10724         /* -90 is our -BIGNUM. Below we use -99 to mark "EOF on read",
10725          * pungetc() may increment it a few times.
10726          * Assuming it won't increment it to less than -90.
10727          */
10728         if (g_parsefile->left_in_line < -90 || g_parsefile->buf == NULL) {
10729                 pgetc_debug("preadbuffer PEOF1");
10730                 /* even in failure keep left_in_line and next_to_pgetc
10731                  * in lock step, for correct multi-layer pungetc.
10732                  * left_in_line was decremented before preadbuffer(),
10733                  * must inc next_to_pgetc: */
10734                 g_parsefile->next_to_pgetc++;
10735                 return PEOF;
10736         }
10737
10738         more = g_parsefile->left_in_buffer;
10739         if (more <= 0) {
10740                 flush_stdout_stderr();
10741  again:
10742                 more = preadfd();
10743                 if (more <= 0) {
10744                         /* don't try reading again */
10745                         g_parsefile->left_in_line = -99;
10746                         pgetc_debug("preadbuffer PEOF2");
10747                         g_parsefile->next_to_pgetc++;
10748                         return PEOF;
10749                 }
10750         }
10751
10752         /* Find out where's the end of line.
10753          * Set g_parsefile->left_in_line
10754          * and g_parsefile->left_in_buffer acordingly.
10755          * NUL chars are deleted.
10756          */
10757         q = g_parsefile->next_to_pgetc;
10758         for (;;) {
10759                 char c;
10760
10761                 more--;
10762
10763                 c = *q;
10764                 if (c == '\0') {
10765                         memmove(q, q + 1, more);
10766                 } else {
10767                         q++;
10768                         if (c == '\n') {
10769                                 g_parsefile->left_in_line = q - g_parsefile->next_to_pgetc - 1;
10770                                 break;
10771                         }
10772                 }
10773
10774                 if (more <= 0) {
10775                         g_parsefile->left_in_line = q - g_parsefile->next_to_pgetc - 1;
10776                         if (g_parsefile->left_in_line < 0)
10777                                 goto again;
10778                         break;
10779                 }
10780         }
10781         g_parsefile->left_in_buffer = more;
10782
10783         if (vflag) {
10784                 char save = *q;
10785                 *q = '\0';
10786                 out2str(g_parsefile->next_to_pgetc);
10787                 *q = save;
10788         }
10789
10790         pgetc_debug("preadbuffer at %d:%p'%s'",
10791                         g_parsefile->left_in_line,
10792                         g_parsefile->next_to_pgetc,
10793                         g_parsefile->next_to_pgetc);
10794         return (unsigned char)*g_parsefile->next_to_pgetc++;
10795 }
10796
10797 static void
10798 nlprompt(void)
10799 {
10800         g_parsefile->linno++;
10801         setprompt_if(doprompt, 2);
10802 }
10803 static void
10804 nlnoprompt(void)
10805 {
10806         g_parsefile->linno++;
10807         needprompt = doprompt;
10808 }
10809
10810 static int
10811 pgetc(void)
10812 {
10813         int c;
10814
10815         pgetc_debug("pgetc at %d:%p'%s'",
10816                         g_parsefile->left_in_line,
10817                         g_parsefile->next_to_pgetc,
10818                         g_parsefile->next_to_pgetc);
10819         if (g_parsefile->unget)
10820                 return g_parsefile->lastc[--g_parsefile->unget];
10821
10822         if (--g_parsefile->left_in_line >= 0)
10823                 c = (unsigned char)*g_parsefile->next_to_pgetc++;
10824         else
10825                 c = preadbuffer();
10826
10827         g_parsefile->lastc[1] = g_parsefile->lastc[0];
10828         g_parsefile->lastc[0] = c;
10829
10830         return c;
10831 }
10832
10833 #if ENABLE_ASH_ALIAS
10834 static int
10835 pgetc_without_PEOA(void)
10836 {
10837         int c;
10838         do {
10839                 pgetc_debug("pgetc at %d:%p'%s'",
10840                                 g_parsefile->left_in_line,
10841                                 g_parsefile->next_to_pgetc,
10842                                 g_parsefile->next_to_pgetc);
10843                 c = pgetc();
10844         } while (c == PEOA);
10845         return c;
10846 }
10847 #else
10848 # define pgetc_without_PEOA() pgetc()
10849 #endif
10850
10851 /*
10852  * Undo a call to pgetc.  Only two characters may be pushed back.
10853  * PEOF may be pushed back.
10854  */
10855 static void
10856 pungetc(void)
10857 {
10858         g_parsefile->unget++;
10859 }
10860
10861 /* This one eats backslash+newline */
10862 static int
10863 pgetc_eatbnl(void)
10864 {
10865         int c;
10866
10867         while ((c = pgetc()) == '\\') {
10868                 if (pgetc() != '\n') {
10869                         pungetc();
10870                         break;
10871                 }
10872
10873                 nlprompt();
10874         }
10875
10876         return c;
10877 }
10878
10879 struct synstack {
10880         smalluint syntax;
10881         uint8_t innerdq   :1;
10882         uint8_t varpushed :1;
10883         uint8_t dblquote  :1;
10884         int varnest;            /* levels of variables expansion */
10885         int dqvarnest;          /* levels of variables expansion within double quotes */
10886         int parenlevel;         /* levels of parens in arithmetic */
10887         struct synstack *prev;
10888         struct synstack *next;
10889 };
10890
10891 static int
10892 pgetc_top(struct synstack *stack)
10893 {
10894         return stack->syntax == SQSYNTAX ? pgetc() : pgetc_eatbnl();
10895 }
10896
10897 static void
10898 synstack_push(struct synstack **stack, struct synstack *next, int syntax)
10899 {
10900         memset(next, 0, sizeof(*next));
10901         next->syntax = syntax;
10902         next->next = *stack;
10903         (*stack)->prev = next;
10904         *stack = next;
10905 }
10906
10907 static ALWAYS_INLINE void
10908 synstack_pop(struct synstack **stack)
10909 {
10910         *stack = (*stack)->next;
10911 }
10912
10913 /*
10914  * To handle the "." command, a stack of input files is used.  Pushfile
10915  * adds a new entry to the stack and popfile restores the previous level.
10916  */
10917 static void
10918 pushfile(void)
10919 {
10920         struct parsefile *pf;
10921
10922         pf = ckzalloc(sizeof(*pf));
10923         pf->prev = g_parsefile;
10924         pf->pf_fd = -1;
10925         /*pf->strpush = NULL; - ckzalloc did it */
10926         /*pf->basestrpush.prev = NULL;*/
10927         /*pf->unget = 0;*/
10928         g_parsefile = pf;
10929 }
10930
10931 static void
10932 popfile(void)
10933 {
10934         struct parsefile *pf = g_parsefile;
10935
10936         if (pf == &basepf)
10937                 return;
10938
10939         INT_OFF;
10940         if (pf->pf_fd >= 0)
10941                 close(pf->pf_fd);
10942         free(pf->buf);
10943         while (pf->strpush)
10944                 popstring();
10945         g_parsefile = pf->prev;
10946         free(pf);
10947         INT_ON;
10948 }
10949
10950 static void
10951 unwindfiles(struct parsefile *stop)
10952 {
10953         while (g_parsefile != stop)
10954                 popfile();
10955 }
10956
10957 /*
10958  * Return to top level.
10959  */
10960 static void
10961 popallfiles(void)
10962 {
10963         unwindfiles(&basepf);
10964 }
10965
10966 /*
10967  * Close the file(s) that the shell is reading commands from.  Called
10968  * after a fork is done.
10969  */
10970 static void
10971 closescript(void)
10972 {
10973         popallfiles();
10974         if (g_parsefile->pf_fd > 0) {
10975                 close(g_parsefile->pf_fd);
10976                 g_parsefile->pf_fd = 0;
10977         }
10978 }
10979
10980 /*
10981  * Like setinputfile, but takes an open file descriptor.  Call this with
10982  * interrupts off.
10983  */
10984 static void
10985 setinputfd(int fd, int push)
10986 {
10987         if (push) {
10988                 pushfile();
10989                 g_parsefile->buf = NULL;
10990         }
10991         g_parsefile->pf_fd = fd;
10992         if (g_parsefile->buf == NULL)
10993                 g_parsefile->buf = ckmalloc(IBUFSIZ);
10994         g_parsefile->left_in_buffer = 0;
10995         g_parsefile->left_in_line = 0;
10996         g_parsefile->linno = 1;
10997 }
10998
10999 /*
11000  * Set the input to take input from a file.  If push is set, push the
11001  * old input onto the stack first.
11002  */
11003 static int
11004 setinputfile(const char *fname, int flags)
11005 {
11006         int fd;
11007
11008         INT_OFF;
11009         fd = open(fname, O_RDONLY | O_CLOEXEC);
11010         if (fd < 0) {
11011                 if (flags & INPUT_NOFILE_OK)
11012                         goto out;
11013                 exitstatus = 127;
11014                 ash_msg_and_raise_perror("can't open '%s'", fname);
11015         }
11016         if (fd < 10)
11017                 fd = savefd(fd);
11018         else if (O_CLOEXEC == 0) /* old libc */
11019                 close_on_exec_on(fd);
11020
11021         setinputfd(fd, flags & INPUT_PUSH_FILE);
11022  out:
11023         INT_ON;
11024         return fd;
11025 }
11026
11027 /*
11028  * Like setinputfile, but takes input from a string.
11029  */
11030 static void
11031 setinputstring(char *string)
11032 {
11033         INT_OFF;
11034         pushfile();
11035         g_parsefile->next_to_pgetc = string;
11036         g_parsefile->left_in_line = strlen(string);
11037         g_parsefile->buf = NULL;
11038         g_parsefile->linno = 1;
11039         INT_ON;
11040 }
11041
11042
11043 /*
11044  * Routines to check for mail.
11045  */
11046
11047 #if ENABLE_ASH_MAIL
11048
11049 /* Hash of mtimes of mailboxes */
11050 static unsigned mailtime_hash;
11051 /* Set if MAIL or MAILPATH is changed. */
11052 static smallint mail_var_path_changed;
11053
11054 /*
11055  * Print appropriate message(s) if mail has arrived.
11056  * If mail_var_path_changed is set,
11057  * then the value of MAIL has mail_var_path_changed,
11058  * so we just update the values.
11059  */
11060 static void
11061 chkmail(void)
11062 {
11063         const char *mpath;
11064         char *p;
11065         char *q;
11066         unsigned new_hash;
11067         struct stackmark smark;
11068         struct stat statb;
11069
11070         setstackmark(&smark);
11071         mpath = mpathset() ? mpathval() : mailval();
11072         new_hash = 0;
11073         for (;;) {
11074                 int len;
11075
11076                 len = padvance_magic(&mpath, nullstr, 2);
11077                 if (!len)
11078                         break;
11079                 p = stackblock();
11080                         break;
11081                 if (*p == '\0')
11082                         continue;
11083                 for (q = p; *q; q++)
11084                         continue;
11085 #if DEBUG
11086                 if (q[-1] != '/')
11087                         abort();
11088 #endif
11089                 q[-1] = '\0';                   /* delete trailing '/' */
11090                 if (stat(p, &statb) < 0) {
11091                         continue;
11092                 }
11093                 /* Very simplistic "hash": just a sum of all mtimes */
11094                 new_hash += (unsigned)statb.st_mtime;
11095         }
11096         if (!mail_var_path_changed && mailtime_hash != new_hash) {
11097                 if (mailtime_hash != 0)
11098                         out2str("you have mail\n");
11099                 mailtime_hash = new_hash;
11100         }
11101         mail_var_path_changed = 0;
11102         popstackmark(&smark);
11103 }
11104
11105 static void FAST_FUNC
11106 changemail(const char *val UNUSED_PARAM)
11107 {
11108         mail_var_path_changed = 1;
11109 }
11110
11111 #endif /* ASH_MAIL */
11112
11113
11114 /* ============ ??? */
11115
11116 /*
11117  * Set the shell parameters.
11118  */
11119 static void
11120 setparam(char **argv)
11121 {
11122         char **newparam;
11123         char **ap;
11124         int nparam;
11125
11126         for (nparam = 0; argv[nparam]; nparam++)
11127                 continue;
11128         ap = newparam = ckmalloc((nparam + 1) * sizeof(*ap));
11129         while (*argv) {
11130                 *ap++ = ckstrdup(*argv++);
11131         }
11132         *ap = NULL;
11133         freeparam(&shellparam);
11134         shellparam.malloced = 1;
11135         shellparam.nparam = nparam;
11136         shellparam.p = newparam;
11137 #if ENABLE_ASH_GETOPTS
11138         shellparam.optind = 1;
11139         shellparam.optoff = -1;
11140 #endif
11141 }
11142
11143 /*
11144  * Process shell options.  The global variable argptr contains a pointer
11145  * to the argument list; we advance it past the options.
11146  *
11147  * SUSv3 section 2.8.1 "Consequences of Shell Errors" says:
11148  * For a non-interactive shell, an error condition encountered
11149  * by a special built-in ... shall cause the shell to write a diagnostic message
11150  * to standard error and exit as shown in the following table:
11151  * Error                                           Special Built-In
11152  * ...
11153  * Utility syntax error (option or operand error)  Shall exit
11154  * ...
11155  * However, in bug 1142 (http://busybox.net/bugs/view.php?id=1142)
11156  * we see that bash does not do that (set "finishes" with error code 1 instead,
11157  * and shell continues), and people rely on this behavior!
11158  * Testcase:
11159  * set -o barfoo 2>/dev/null
11160  * echo $?
11161  *
11162  * Oh well. Let's mimic that.
11163  */
11164 static int
11165 plus_minus_o(char *name, int val)
11166 {
11167         int i;
11168
11169         if (name) {
11170                 for (i = 0; i < NOPTS; i++) {
11171                         if (strcmp(name, optnames(i)) == 0) {
11172                                 optlist[i] = val;
11173                                 return 0;
11174                         }
11175                 }
11176                 ash_msg("illegal option %co %s", val ? '-' : '+', name);
11177                 return 1;
11178         }
11179         for (i = 0; i < NOPTS; i++) {
11180                 if (optnames(i)[0] == '\0')
11181                         continue;
11182                 if (val) {
11183                         out1fmt("%-16s%s\n", optnames(i), optlist[i] ? "on" : "off");
11184                 } else {
11185                         out1fmt("set %co %s\n", optlist[i] ? '-' : '+', optnames(i));
11186                 }
11187         }
11188         return 0;
11189 }
11190 static void
11191 setoption(int flag, int val)
11192 {
11193         int i;
11194
11195         for (i = 0; i < NOPTS; i++) {
11196                 if (optletters(i) == flag && optnames(i)[0] != '\0') {
11197                         optlist[i] = val;
11198                         return;
11199                 }
11200         }
11201         ash_msg_and_raise_error("illegal option %c%c", val ? '-' : '+', flag);
11202         /* NOTREACHED */
11203 }
11204 /* If login_sh is not NULL, we are called to parse command line opts,
11205  * not "set -opts"
11206  */
11207 static int
11208 options(int *login_sh)
11209 {
11210         char *p;
11211         int val;
11212         int c;
11213
11214         if (login_sh)
11215                 minusc = NULL;
11216         while ((p = *argptr) != NULL) {
11217                 c = *p++;
11218                 if (c != '-' && c != '+')
11219                         break;
11220                 argptr++;
11221                 val = 0; /* val = 0 if c == '+' */
11222                 if (c == '-') {
11223                         val = 1;
11224                         if (p[0] == '\0' || LONE_DASH(p)) {
11225                                 if (!login_sh) {
11226                                         /* "-" means turn off -x and -v */
11227                                         if (p[0] == '\0')
11228                                                 xflag = vflag = 0;
11229                                         /* "--" means reset params */
11230                                         else if (*argptr == NULL)
11231                                                 setparam(argptr);
11232                                 }
11233                                 break;    /* "-" or "--" terminates options */
11234                         }
11235                 }
11236                 /* first char was + or - */
11237                 while ((c = *p++) != '\0') {
11238                         if (login_sh) {
11239                                 /* bash 3.2 indeed handles -c CMD and +c CMD the same */
11240                                 if (c == 'c') {
11241                                         minusc = p; /* command is after shell args */
11242                                         cflag = 1;
11243                                         continue;
11244                                 }
11245                                 if (c == 's') { /* -s, +s */
11246                                         sflag = 1;
11247                                         continue;
11248                                 }
11249                                 if (c == 'i') { /* -i, +i */
11250                                         iflag = 1;
11251                                         continue;
11252                                 }
11253                                 if (c == 'l') {
11254                                         *login_sh = 1; /* -l or +l == --login */
11255                                         continue;
11256                                 }
11257                                 /* bash does not accept +-login, we also won't */
11258                                 if (val && (c == '-')) { /* long options */
11259                                         if (strcmp(p, "login") == 0) {
11260                                                 *login_sh = 1;
11261                                         }
11262                                         break;
11263                                 }
11264                         }
11265                         if (c == 'o') {
11266                                 if (plus_minus_o(*argptr, val)) {
11267                                         /* it already printed err message */
11268                                         return 1; /* error */
11269                                 }
11270                                 if (*argptr)
11271                                         argptr++;
11272                         } else {
11273                                 setoption(c, val);
11274                         }
11275                 }
11276         }
11277         return 0;
11278 }
11279
11280 /*
11281  * The shift builtin command.
11282  */
11283 static int FAST_FUNC
11284 shiftcmd(int argc UNUSED_PARAM, char **argv)
11285 {
11286         int n;
11287         char **ap1, **ap2;
11288
11289         n = 1;
11290         if (argv[1])
11291                 n = number(argv[1]);
11292         if (n > shellparam.nparam)
11293                 return 1;
11294         INT_OFF;
11295         shellparam.nparam -= n;
11296         for (ap1 = shellparam.p; --n >= 0; ap1++) {
11297                 if (shellparam.malloced)
11298                         free(*ap1);
11299         }
11300         ap2 = shellparam.p;
11301         while ((*ap2++ = *ap1++) != NULL)
11302                 continue;
11303 #if ENABLE_ASH_GETOPTS
11304         shellparam.optind = 1;
11305         shellparam.optoff = -1;
11306 #endif
11307         INT_ON;
11308         return 0;
11309 }
11310
11311 /*
11312  * POSIX requires that 'set' (but not export or readonly) output the
11313  * variables in lexicographic order - by the locale's collating order (sigh).
11314  * Maybe we could keep them in an ordered balanced binary tree
11315  * instead of hashed lists.
11316  * For now just roll 'em through qsort for printing...
11317  */
11318 static int
11319 showvars(const char *sep_prefix, int on, int off)
11320 {
11321         const char *sep;
11322         char **ep, **epend;
11323
11324         ep = listvars(on, off, /*strlist:*/ NULL, &epend);
11325         qsort(ep, epend - ep, sizeof(char *), vpcmp);
11326
11327         sep = *sep_prefix ? " " : sep_prefix;
11328
11329         for (; ep < epend; ep++) {
11330                 const char *p;
11331                 const char *q;
11332
11333                 p = endofname(*ep);
11334 /* Used to have simple "p = strchrnul(*ep, '=')" here instead, but this
11335  * makes "export -p" to have output not suitable for "eval":
11336  * import os
11337  * os.environ["test-test"]="test"
11338  * if os.fork() == 0:
11339  *   os.execv("ash", [ 'ash', '-c', 'eval $(export -p); echo OK' ])  # fixes this
11340  * os.execv("ash", [ 'ash', '-c', 'env | grep test-test' ])
11341  */
11342                 q = nullstr;
11343                 if (*p == '=')
11344                         q = single_quote(++p);
11345                 out1fmt("%s%s%.*s%s\n", sep_prefix, sep, (int)(p - *ep), *ep, q);
11346         }
11347         return 0;
11348 }
11349
11350 /*
11351  * The set command builtin.
11352  */
11353 static int FAST_FUNC
11354 setcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
11355 {
11356         int retval;
11357
11358         if (!argv[1])
11359                 return showvars(nullstr, 0, VUNSET);
11360
11361         INT_OFF;
11362         retval = options(/*login_sh:*/ NULL);
11363         if (retval == 0) { /* if no parse error... */
11364                 optschanged();
11365                 if (*argptr != NULL) {
11366                         setparam(argptr);
11367                 }
11368         }
11369         INT_ON;
11370         return retval;
11371 }
11372
11373 #if ENABLE_ASH_RANDOM_SUPPORT
11374 static void FAST_FUNC
11375 change_random(const char *value)
11376 {
11377         uint32_t t;
11378
11379         if (value == NULL) {
11380                 /* "get", generate */
11381                 t = next_random(&random_gen);
11382                 /* set without recursion */
11383                 setvar(vrandom.var_text, utoa(t), VNOFUNC);
11384                 vrandom.flags &= ~VNOFUNC;
11385         } else {
11386                 /* set/reset */
11387                 t = strtoul(value, NULL, 10);
11388                 INIT_RANDOM_T(&random_gen, (t ? t : 1), t);
11389         }
11390 }
11391 #endif
11392
11393 #if BASH_EPOCH_VARS
11394 static void FAST_FUNC
11395 change_epoch(struct var *vepoch, const char *fmt)
11396 {
11397         struct timeval tv;
11398         char buffer[sizeof("%lu.nnnnnn") + sizeof(long)*3];
11399
11400         gettimeofday(&tv, NULL);
11401         sprintf(buffer, fmt, (unsigned long)tv.tv_sec, (unsigned)tv.tv_usec);
11402         setvar(vepoch->var_text, buffer, VNOFUNC);
11403         vepoch->flags &= ~VNOFUNC;
11404 }
11405
11406 static void FAST_FUNC
11407 change_seconds(const char *value UNUSED_PARAM)
11408 {
11409         change_epoch(&vepochs, "%lu");
11410 }
11411
11412 static void FAST_FUNC
11413 change_realtime(const char *value UNUSED_PARAM)
11414 {
11415         change_epoch(&vepochr, "%lu.%06u");
11416 }
11417 #endif
11418
11419 #if ENABLE_ASH_GETOPTS
11420 static int
11421 getopts(char *optstr, char *optvar, char **optfirst)
11422 {
11423         char *p, *q;
11424         char c = '?';
11425         int done = 0;
11426         char sbuf[2];
11427         char **optnext;
11428         int ind = shellparam.optind;
11429         int off = shellparam.optoff;
11430
11431         sbuf[1] = '\0';
11432
11433         shellparam.optind = -1;
11434         optnext = optfirst + ind - 1;
11435
11436         if (ind <= 1 || off < 0 || (int)strlen(optnext[-1]) < off)
11437                 p = NULL;
11438         else
11439                 p = optnext[-1] + off;
11440         if (p == NULL || *p == '\0') {
11441                 /* Current word is done, advance */
11442                 p = *optnext;
11443                 if (p == NULL || *p != '-' || *++p == '\0') {
11444  atend:
11445                         unsetvar("OPTARG");
11446                         p = NULL;
11447                         done = 1;
11448                         goto out;
11449                 }
11450                 optnext++;
11451                 if (LONE_DASH(p))        /* check for "--" */
11452                         goto atend;
11453         }
11454
11455         c = *p++;
11456         for (q = optstr; *q != c;) {
11457                 if (*q == '\0') {
11458                         /* OPTERR is a bashism */
11459                         const char *cp = lookupvar("OPTERR");
11460                         if ((cp && LONE_CHAR(cp, '0'))
11461                          || (optstr[0] == ':')
11462                         ) {
11463                                 sbuf[0] = c;
11464                                 /*sbuf[1] = '\0'; - already is */
11465                                 setvar0("OPTARG", sbuf);
11466                         } else {
11467                                 fprintf(stderr, "Illegal option -%c\n", c);
11468                                 unsetvar("OPTARG");
11469                         }
11470                         c = '?';
11471                         goto out;
11472                 }
11473                 if (*++q == ':')
11474                         q++;
11475         }
11476
11477         if (*++q == ':') {
11478                 if (*p == '\0' && (p = *optnext) == NULL) {
11479                         /* OPTERR is a bashism */
11480                         const char *cp = lookupvar("OPTERR");
11481                         if ((cp && LONE_CHAR(cp, '0'))
11482                          || (optstr[0] == ':')
11483                         ) {
11484                                 sbuf[0] = c;
11485                                 /*sbuf[1] = '\0'; - already is */
11486                                 setvar0("OPTARG", sbuf);
11487                                 c = ':';
11488                         } else {
11489                                 fprintf(stderr, "No arg for -%c option\n", c);
11490                                 unsetvar("OPTARG");
11491                                 c = '?';
11492                         }
11493                         goto out;
11494                 }
11495
11496                 if (p == *optnext)
11497                         optnext++;
11498                 setvar0("OPTARG", p);
11499                 p = NULL;
11500         } else
11501                 setvar0("OPTARG", nullstr);
11502  out:
11503         ind = optnext - optfirst + 1;
11504         setvar("OPTIND", itoa(ind), VNOFUNC);
11505         sbuf[0] = c;
11506         /*sbuf[1] = '\0'; - already is */
11507         setvar0(optvar, sbuf);
11508
11509         shellparam.optoff = p ? p - *(optnext - 1) : -1;
11510         shellparam.optind = ind;
11511
11512         return done;
11513 }
11514
11515 /*
11516  * The getopts builtin.  Shellparam.optnext points to the next argument
11517  * to be processed.  Shellparam.optptr points to the next character to
11518  * be processed in the current argument.  If shellparam.optnext is NULL,
11519  * then it's the first time getopts has been called.
11520  */
11521 static int FAST_FUNC
11522 getoptscmd(int argc, char **argv)
11523 {
11524         char **optbase;
11525
11526         if (argc < 3)
11527                 ash_msg_and_raise_error("usage: getopts optstring var [arg]");
11528         if (argc == 3) {
11529                 optbase = shellparam.p;
11530                 if ((unsigned)shellparam.optind > shellparam.nparam + 1) {
11531                         shellparam.optind = 1;
11532                         shellparam.optoff = -1;
11533                 }
11534         } else {
11535                 optbase = &argv[3];
11536                 if ((unsigned)shellparam.optind > argc - 2) {
11537                         shellparam.optind = 1;
11538                         shellparam.optoff = -1;
11539                 }
11540         }
11541
11542         return getopts(argv[1], argv[2], optbase);
11543 }
11544 #endif /* ASH_GETOPTS */
11545
11546
11547 /* ============ Shell parser */
11548
11549 struct heredoc {
11550         struct heredoc *next;   /* next here document in list */
11551         union node *here;       /* redirection node */
11552         char *eofmark;          /* string indicating end of input */
11553         smallint striptabs;     /* if set, strip leading tabs */
11554 };
11555
11556 static smallint tokpushback;           /* last token pushed back */
11557 static smallint quoteflag;             /* set if (part of) last token was quoted */
11558 static token_id_t lasttoken;           /* last token read (integer id Txxx) */
11559 static struct heredoc *heredoclist;    /* list of here documents to read */
11560 static char *wordtext;                 /* text of last word returned by readtoken */
11561 static struct nodelist *backquotelist;
11562 static union node *redirnode;
11563 static struct heredoc *heredoc;
11564
11565 static const char *
11566 tokname(char *buf, int tok)
11567 {
11568         if (tok < TSEMI)
11569                 return tokname_array[tok];
11570         sprintf(buf, "\"%s\"", tokname_array[tok]);
11571         return buf;
11572 }
11573
11574 /* raise_error_unexpected_syntax:
11575  * Called when an unexpected token is read during the parse.  The argument
11576  * is the token that is expected, or -1 if more than one type of token can
11577  * occur at this point.
11578  */
11579 static void raise_error_unexpected_syntax(int) NORETURN;
11580 static void
11581 raise_error_unexpected_syntax(int token)
11582 {
11583         char msg[64];
11584         char buf[16];
11585         int l;
11586
11587         l = sprintf(msg, "unexpected %s", tokname(buf, lasttoken));
11588         if (token >= 0)
11589                 sprintf(msg + l, " (expecting %s)", tokname(buf, token));
11590         raise_error_syntax(msg);
11591         /* NOTREACHED */
11592 }
11593
11594 /* parsing is heavily cross-recursive, need these forward decls */
11595 static union node *andor(void);
11596 static union node *pipeline(void);
11597 static union node *parse_command(void);
11598 static void parseheredoc(void);
11599 static int peektoken(void);
11600 static int readtoken(void);
11601
11602 static union node *
11603 list(int nlflag)
11604 {
11605         union node *n1, *n2, *n3;
11606         int tok;
11607
11608         n1 = NULL;
11609         for (;;) {
11610                 switch (peektoken()) {
11611                 case TNL:
11612                         if (!(nlflag & 1))
11613                                 break;
11614                         parseheredoc();
11615                         return n1;
11616
11617                 case TEOF:
11618                         if (!n1 && (nlflag & 1))
11619                                 n1 = NODE_EOF;
11620                         parseheredoc();
11621                         return n1;
11622                 }
11623
11624                 checkkwd = CHKNL | CHKKWD | CHKALIAS;
11625                 if (nlflag == 2 && ((1 << peektoken()) & tokendlist))
11626                         return n1;
11627                 nlflag |= 2;
11628
11629                 n2 = andor();
11630                 tok = readtoken();
11631                 if (tok == TBACKGND) {
11632                         if (n2->type == NPIPE) {
11633                                 n2->npipe.pipe_backgnd = 1;
11634                         } else {
11635                                 if (n2->type != NREDIR) {
11636                                         n3 = stzalloc(sizeof(struct nredir));
11637                                         n3->nredir.n = n2;
11638                                         /*n3->nredir.redirect = NULL; - stzalloc did it */
11639                                         n2 = n3;
11640                                 }
11641                                 n2->type = NBACKGND;
11642                         }
11643                 }
11644                 if (n1 == NULL) {
11645                         n1 = n2;
11646                 } else {
11647                         n3 = stzalloc(sizeof(struct nbinary));
11648                         n3->type = NSEMI;
11649                         n3->nbinary.ch1 = n1;
11650                         n3->nbinary.ch2 = n2;
11651                         n1 = n3;
11652                 }
11653                 switch (tok) {
11654                 case TNL:
11655                 case TEOF:
11656                         tokpushback = 1;
11657                         /* fall through */
11658                 case TBACKGND:
11659                 case TSEMI:
11660                         break;
11661                 default:
11662                         if ((nlflag & 1))
11663                                 raise_error_unexpected_syntax(-1);
11664                         tokpushback = 1;
11665                         return n1;
11666                 }
11667         }
11668 }
11669
11670 static union node *
11671 andor(void)
11672 {
11673         union node *n1, *n2, *n3;
11674         int t;
11675
11676         n1 = pipeline();
11677         for (;;) {
11678                 t = readtoken();
11679                 if (t == TAND) {
11680                         t = NAND;
11681                 } else if (t == TOR) {
11682                         t = NOR;
11683                 } else {
11684                         tokpushback = 1;
11685                         return n1;
11686                 }
11687                 checkkwd = CHKNL | CHKKWD | CHKALIAS;
11688                 n2 = pipeline();
11689                 n3 = stzalloc(sizeof(struct nbinary));
11690                 n3->type = t;
11691                 n3->nbinary.ch1 = n1;
11692                 n3->nbinary.ch2 = n2;
11693                 n1 = n3;
11694         }
11695 }
11696
11697 static union node *
11698 pipeline(void)
11699 {
11700         union node *n1, *n2, *pipenode;
11701         struct nodelist *lp, *prev;
11702         int negate;
11703
11704         negate = 0;
11705         TRACE(("pipeline: entered\n"));
11706         if (readtoken() == TNOT) {
11707                 negate = !negate;
11708                 checkkwd = CHKKWD | CHKALIAS;
11709         } else
11710                 tokpushback = 1;
11711         n1 = parse_command();
11712         if (readtoken() == TPIPE) {
11713                 pipenode = stzalloc(sizeof(struct npipe));
11714                 pipenode->type = NPIPE;
11715                 /*pipenode->npipe.pipe_backgnd = 0; - stzalloc did it */
11716                 lp = stzalloc(sizeof(struct nodelist));
11717                 pipenode->npipe.cmdlist = lp;
11718                 lp->n = n1;
11719                 do {
11720                         prev = lp;
11721                         lp = stzalloc(sizeof(struct nodelist));
11722                         checkkwd = CHKNL | CHKKWD | CHKALIAS;
11723                         lp->n = parse_command();
11724                         prev->next = lp;
11725                 } while (readtoken() == TPIPE);
11726                 lp->next = NULL;
11727                 n1 = pipenode;
11728         }
11729         tokpushback = 1;
11730         if (negate) {
11731                 n2 = stzalloc(sizeof(struct nnot));
11732                 n2->type = NNOT;
11733                 n2->nnot.com = n1;
11734                 return n2;
11735         }
11736         return n1;
11737 }
11738
11739 static union node *
11740 makename(void)
11741 {
11742         union node *n;
11743
11744         n = stzalloc(sizeof(struct narg));
11745         n->type = NARG;
11746         /*n->narg.next = NULL; - stzalloc did it */
11747         n->narg.text = wordtext;
11748         n->narg.backquote = backquotelist;
11749         return n;
11750 }
11751
11752 static void
11753 fixredir(union node *n, const char *text, int err)
11754 {
11755         int fd;
11756
11757         TRACE(("Fix redir %s %d\n", text, err));
11758         if (!err)
11759                 n->ndup.vname = NULL;
11760
11761         fd = bb_strtou(text, NULL, 10);
11762         if (!errno && fd >= 0)
11763                 n->ndup.dupfd = fd;
11764         else if (LONE_DASH(text))
11765                 n->ndup.dupfd = -1;
11766         else {
11767                 if (err)
11768                         raise_error_syntax("bad fd number");
11769                 n->ndup.vname = makename();
11770         }
11771 }
11772
11773 static void
11774 parsefname(void)
11775 {
11776         union node *n = redirnode;
11777
11778         if (n->type == NHERE)
11779                 checkkwd = CHKEOFMARK;
11780         if (readtoken() != TWORD)
11781                 raise_error_unexpected_syntax(-1);
11782         if (n->type == NHERE) {
11783                 struct heredoc *here = heredoc;
11784                 struct heredoc *p;
11785
11786                 if (quoteflag == 0)
11787                         n->type = NXHERE;
11788                 TRACE(("Here document %d\n", n->type));
11789                 rmescapes(wordtext, 0, NULL);
11790                 here->eofmark = wordtext;
11791                 here->next = NULL;
11792                 if (heredoclist == NULL)
11793                         heredoclist = here;
11794                 else {
11795                         for (p = heredoclist; p->next; p = p->next)
11796                                 continue;
11797                         p->next = here;
11798                 }
11799         } else if (n->type == NTOFD || n->type == NFROMFD) {
11800                 fixredir(n, wordtext, 0);
11801         } else {
11802                 n->nfile.fname = makename();
11803         }
11804 }
11805
11806 static union node *
11807 simplecmd(void)
11808 {
11809         union node *args, **app;
11810         union node *n = NULL;
11811         union node *vars, **vpp;
11812         union node **rpp, *redir;
11813         int savecheckkwd;
11814         int savelinno;
11815 #if BASH_TEST2
11816         smallint double_brackets_flag = 0;
11817 #endif
11818         IF_BASH_FUNCTION(smallint function_flag = 0;)
11819
11820         args = NULL;
11821         app = &args;
11822         vars = NULL;
11823         vpp = &vars;
11824         redir = NULL;
11825         rpp = &redir;
11826
11827         savecheckkwd = CHKALIAS;
11828         savelinno = g_parsefile->linno;
11829         for (;;) {
11830                 int t;
11831                 checkkwd = savecheckkwd;
11832                 t = readtoken();
11833                 switch (t) {
11834 #if BASH_FUNCTION
11835                 case TFUNCTION:
11836                         if (peektoken() != TWORD)
11837                                 raise_error_unexpected_syntax(TWORD);
11838                         function_flag = 1;
11839                         break;
11840 #endif
11841 #if BASH_TEST2
11842                 case TAND: /* "&&" */
11843                 case TOR: /* "||" */
11844                         if (!double_brackets_flag) {
11845                                 tokpushback = 1;
11846                                 goto out;
11847                         }
11848                         wordtext = (char *) (t == TAND ? "-a" : "-o");
11849 #endif
11850                 case TWORD:
11851                         n = stzalloc(sizeof(struct narg));
11852                         n->type = NARG;
11853                         /*n->narg.next = NULL; - stzalloc did it */
11854                         n->narg.text = wordtext;
11855 #if BASH_TEST2
11856                         if (strcmp("[[", wordtext) == 0)
11857                                 double_brackets_flag = 1;
11858                         else if (strcmp("]]", wordtext) == 0)
11859                                 double_brackets_flag = 0;
11860 #endif
11861                         n->narg.backquote = backquotelist;
11862                         if (savecheckkwd && isassignment(wordtext)) {
11863                                 *vpp = n;
11864                                 vpp = &n->narg.next;
11865                         } else {
11866                                 *app = n;
11867                                 app = &n->narg.next;
11868                                 savecheckkwd = 0;
11869                         }
11870 #if BASH_FUNCTION
11871                         if (function_flag) {
11872                                 checkkwd = CHKNL | CHKKWD;
11873                                 switch (peektoken()) {
11874                                 case TBEGIN:
11875                                 case TIF:
11876                                 case TCASE:
11877                                 case TUNTIL:
11878                                 case TWHILE:
11879                                 case TFOR:
11880                                         goto do_func;
11881                                 case TLP:
11882                                         function_flag = 0;
11883                                         break;
11884 # if BASH_TEST2
11885                                 case TWORD:
11886                                         if (strcmp("[[", wordtext) == 0)
11887                                                 goto do_func;
11888                                         /* fall through */
11889 # endif
11890                                 default:
11891                                         raise_error_unexpected_syntax(-1);
11892                                 }
11893                         }
11894 #endif
11895                         break;
11896                 case TREDIR:
11897                         *rpp = n = redirnode;
11898                         rpp = &n->nfile.next;
11899                         parsefname();   /* read name of redirection file */
11900                         break;
11901                 case TLP:
11902  IF_BASH_FUNCTION(do_func:)
11903                         if (args && app == &args->narg.next
11904                          && !vars && !redir
11905                         ) {
11906                                 struct builtincmd *bcmd;
11907                                 const char *name;
11908
11909                                 /* We have a function */
11910                                 if (IF_BASH_FUNCTION(!function_flag &&) readtoken() != TRP)
11911                                         raise_error_unexpected_syntax(TRP);
11912                                 name = n->narg.text;
11913                                 if (!goodname(name)
11914                                  || ((bcmd = find_builtin(name)) && IS_BUILTIN_SPECIAL(bcmd))
11915                                 ) {
11916                                         raise_error_syntax("bad function name");
11917                                 }
11918                                 n->type = NDEFUN;
11919                                 checkkwd = CHKNL | CHKKWD | CHKALIAS;
11920                                 n->ndefun.text = n->narg.text;
11921                                 n->ndefun.linno = g_parsefile->linno;
11922                                 n->ndefun.body = parse_command();
11923                                 return n;
11924                         }
11925                         IF_BASH_FUNCTION(function_flag = 0;)
11926                         /* fall through */
11927                 default:
11928                         tokpushback = 1;
11929                         goto out;
11930                 }
11931         }
11932  out:
11933         *app = NULL;
11934         *vpp = NULL;
11935         *rpp = NULL;
11936         n = stzalloc(sizeof(struct ncmd));
11937         if (NCMD != 0)
11938                 n->type = NCMD;
11939         n->ncmd.linno = savelinno;
11940         n->ncmd.args = args;
11941         n->ncmd.assign = vars;
11942         n->ncmd.redirect = redir;
11943         return n;
11944 }
11945
11946 static union node *
11947 parse_command(void)
11948 {
11949         union node *n1, *n2;
11950         union node *ap, **app;
11951         union node *cp, **cpp;
11952         union node *redir, **rpp;
11953         union node **rpp2;
11954         int t;
11955         int savelinno;
11956
11957         redir = NULL;
11958         rpp2 = &redir;
11959
11960         savelinno = g_parsefile->linno;
11961
11962         switch (readtoken()) {
11963         default:
11964                 raise_error_unexpected_syntax(-1);
11965                 /* NOTREACHED */
11966         case TIF:
11967                 n1 = stzalloc(sizeof(struct nif));
11968                 n1->type = NIF;
11969                 n1->nif.test = list(0);
11970                 if (readtoken() != TTHEN)
11971                         raise_error_unexpected_syntax(TTHEN);
11972                 n1->nif.ifpart = list(0);
11973                 n2 = n1;
11974                 while (readtoken() == TELIF) {
11975                         n2->nif.elsepart = stzalloc(sizeof(struct nif));
11976                         n2 = n2->nif.elsepart;
11977                         n2->type = NIF;
11978                         n2->nif.test = list(0);
11979                         if (readtoken() != TTHEN)
11980                                 raise_error_unexpected_syntax(TTHEN);
11981                         n2->nif.ifpart = list(0);
11982                 }
11983                 if (lasttoken == TELSE)
11984                         n2->nif.elsepart = list(0);
11985                 else {
11986                         n2->nif.elsepart = NULL;
11987                         tokpushback = 1;
11988                 }
11989                 t = TFI;
11990                 break;
11991         case TWHILE:
11992         case TUNTIL: {
11993                 int got;
11994                 n1 = stzalloc(sizeof(struct nbinary));
11995                 n1->type = (lasttoken == TWHILE) ? NWHILE : NUNTIL;
11996                 n1->nbinary.ch1 = list(0);
11997                 got = readtoken();
11998                 if (got != TDO) {
11999                         TRACE(("expecting DO got '%s' %s\n", tokname_array[got],
12000                                         got == TWORD ? wordtext : ""));
12001                         raise_error_unexpected_syntax(TDO);
12002                 }
12003                 n1->nbinary.ch2 = list(0);
12004                 t = TDONE;
12005                 break;
12006         }
12007         case TFOR:
12008                 if (readtoken() != TWORD || quoteflag || !goodname(wordtext))
12009                         raise_error_syntax("bad for loop variable");
12010                 n1 = stzalloc(sizeof(struct nfor));
12011                 n1->type = NFOR;
12012                 n1->nfor.linno = savelinno;
12013                 n1->nfor.var = wordtext;
12014                 checkkwd = CHKNL | CHKKWD | CHKALIAS;
12015                 if (readtoken() == TIN) {
12016                         app = &ap;
12017                         while (readtoken() == TWORD) {
12018                                 n2 = stzalloc(sizeof(struct narg));
12019                                 n2->type = NARG;
12020                                 /*n2->narg.next = NULL; - stzalloc did it */
12021                                 n2->narg.text = wordtext;
12022                                 n2->narg.backquote = backquotelist;
12023                                 *app = n2;
12024                                 app = &n2->narg.next;
12025                         }
12026                         *app = NULL;
12027                         n1->nfor.args = ap;
12028                         if (lasttoken != TNL && lasttoken != TSEMI)
12029                                 raise_error_unexpected_syntax(-1);
12030                 } else {
12031                         n2 = stzalloc(sizeof(struct narg));
12032                         n2->type = NARG;
12033                         /*n2->narg.next = NULL; - stzalloc did it */
12034                         n2->narg.text = (char *)dolatstr;
12035                         /*n2->narg.backquote = NULL;*/
12036                         n1->nfor.args = n2;
12037                         /*
12038                          * Newline or semicolon here is optional (but note
12039                          * that the original Bourne shell only allowed NL).
12040                          */
12041                         if (lasttoken != TSEMI)
12042                                 tokpushback = 1;
12043                 }
12044                 checkkwd = CHKNL | CHKKWD | CHKALIAS;
12045                 if (readtoken() != TDO)
12046                         raise_error_unexpected_syntax(TDO);
12047                 n1->nfor.body = list(0);
12048                 t = TDONE;
12049                 break;
12050         case TCASE:
12051                 n1 = stzalloc(sizeof(struct ncase));
12052                 n1->type = NCASE;
12053                 n1->ncase.linno = savelinno;
12054                 if (readtoken() != TWORD)
12055                         raise_error_unexpected_syntax(TWORD);
12056                 n1->ncase.expr = n2 = stzalloc(sizeof(struct narg));
12057                 n2->type = NARG;
12058                 /*n2->narg.next = NULL; - stzalloc did it */
12059                 n2->narg.text = wordtext;
12060                 n2->narg.backquote = backquotelist;
12061                 checkkwd = CHKNL | CHKKWD | CHKALIAS;
12062                 if (readtoken() != TIN)
12063                         raise_error_unexpected_syntax(TIN);
12064                 cpp = &n1->ncase.cases;
12065  next_case:
12066                 checkkwd = CHKNL | CHKKWD;
12067                 t = readtoken();
12068                 while (t != TESAC) {
12069                         if (lasttoken == TLP)
12070                                 readtoken();
12071                         *cpp = cp = stzalloc(sizeof(struct nclist));
12072                         cp->type = NCLIST;
12073                         app = &cp->nclist.pattern;
12074                         for (;;) {
12075                                 *app = ap = stzalloc(sizeof(struct narg));
12076                                 ap->type = NARG;
12077                                 /*ap->narg.next = NULL; - stzalloc did it */
12078                                 ap->narg.text = wordtext;
12079                                 ap->narg.backquote = backquotelist;
12080                                 if (readtoken() != TPIPE)
12081                                         break;
12082                                 app = &ap->narg.next;
12083                                 readtoken();
12084                         }
12085                         //ap->narg.next = NULL;
12086                         if (lasttoken != TRP)
12087                                 raise_error_unexpected_syntax(TRP);
12088                         cp->nclist.body = list(2);
12089
12090                         cpp = &cp->nclist.next;
12091
12092                         checkkwd = CHKNL | CHKKWD;
12093                         t = readtoken();
12094                         if (t != TESAC) {
12095                                 if (t != TENDCASE)
12096                                         raise_error_unexpected_syntax(TENDCASE);
12097                                 goto next_case;
12098                         }
12099                 }
12100                 *cpp = NULL;
12101                 goto redir;
12102         case TLP:
12103                 n1 = stzalloc(sizeof(struct nredir));
12104                 n1->type = NSUBSHELL;
12105                 n1->nredir.linno = savelinno;
12106                 n1->nredir.n = list(0);
12107                 /*n1->nredir.redirect = NULL; - stzalloc did it */
12108                 t = TRP;
12109                 break;
12110         case TBEGIN:
12111                 n1 = list(0);
12112                 t = TEND;
12113                 break;
12114         IF_BASH_FUNCTION(case TFUNCTION:)
12115         case TWORD:
12116         case TREDIR:
12117                 tokpushback = 1;
12118                 return simplecmd();
12119         }
12120
12121         if (readtoken() != t)
12122                 raise_error_unexpected_syntax(t);
12123
12124  redir:
12125         /* Now check for redirection which may follow command */
12126         checkkwd = CHKKWD | CHKALIAS;
12127         rpp = rpp2;
12128         while (readtoken() == TREDIR) {
12129                 *rpp = n2 = redirnode;
12130                 rpp = &n2->nfile.next;
12131                 parsefname();
12132         }
12133         tokpushback = 1;
12134         *rpp = NULL;
12135         if (redir) {
12136                 if (n1->type != NSUBSHELL) {
12137                         n2 = stzalloc(sizeof(struct nredir));
12138                         n2->type = NREDIR;
12139                         n2->nredir.linno = savelinno;
12140                         n2->nredir.n = n1;
12141                         n1 = n2;
12142                 }
12143                 n1->nredir.redirect = redir;
12144         }
12145         return n1;
12146 }
12147
12148 #if BASH_DOLLAR_SQUOTE
12149 static int
12150 decode_dollar_squote(void)
12151 {
12152         static const char C_escapes[] ALIGN1 = "nrbtfav""x\\01234567";
12153         int c, cnt;
12154         char *p;
12155         char buf[4];
12156
12157         c = pgetc();
12158         p = strchr(C_escapes, c);
12159         if (p) {
12160                 buf[0] = c;
12161                 p = buf;
12162                 cnt = 3;
12163                 if ((unsigned char)(c - '0') <= 7) { /* \ooo */
12164                         do {
12165                                 c = pgetc();
12166                                 *++p = c;
12167                         } while ((unsigned char)(c - '0') <= 7 && --cnt);
12168                         pungetc();
12169                 } else if (c == 'x') { /* \xHH */
12170                         do {
12171                                 c = pgetc();
12172                                 *++p = c;
12173                         } while (isxdigit(c) && --cnt);
12174                         pungetc();
12175                         if (cnt == 3) { /* \x but next char is "bad" */
12176                                 c = 'x';
12177                                 goto unrecognized;
12178                         }
12179                 } else { /* simple seq like \\ or \t */
12180                         p++;
12181                 }
12182                 *p = '\0';
12183                 p = buf;
12184                 c = bb_process_escape_sequence((void*)&p);
12185         } else { /* unrecognized "\z": print both chars unless ' or " */
12186                 if (c != '\'' && c != '"') {
12187  unrecognized:
12188                         c |= 0x100; /* "please encode \, then me" */
12189                 }
12190         }
12191         return c;
12192 }
12193 #endif
12194
12195 /* Used by expandstr to get here-doc like behaviour. */
12196 #define FAKEEOFMARK ((char*)(uintptr_t)1)
12197
12198 static ALWAYS_INLINE int
12199 realeofmark(const char *eofmark)
12200 {
12201         return eofmark && eofmark != FAKEEOFMARK;
12202 }
12203
12204 /*
12205  * If eofmark is NULL, read a word or a redirection symbol.  If eofmark
12206  * is not NULL, read a here document.  In the latter case, eofmark is the
12207  * word which marks the end of the document and striptabs is true if
12208  * leading tabs should be stripped from the document.  The argument c
12209  * is the first character of the input token or document.
12210  *
12211  * Because C does not have internal subroutines, I have simulated them
12212  * using goto's to implement the subroutine linkage.  The following macros
12213  * will run code that appears at the end of readtoken1.
12214  */
12215 #define CHECKEND()      {goto checkend; checkend_return:;}
12216 #define PARSEREDIR()    {goto parseredir; parseredir_return:;}
12217 #define PARSESUB()      {goto parsesub; parsesub_return:;}
12218 #define PARSEBACKQOLD() {oldstyle = 1; goto parsebackq; parsebackq_oldreturn:;}
12219 #define PARSEBACKQNEW() {oldstyle = 0; goto parsebackq; parsebackq_newreturn:;}
12220 #define PARSEARITH()    {goto parsearith; parsearith_return:;}
12221 static int
12222 readtoken1(int c, int syntax, char *eofmark, int striptabs)
12223 {
12224         /* NB: syntax parameter fits into smallint */
12225         /* c parameter is an unsigned char or PEOF or PEOA */
12226         char *out;
12227         size_t len;
12228         struct nodelist *bqlist;
12229         smallint quotef;
12230         smallint oldstyle;
12231         smallint pssyntax;   /* we are expanding a prompt string */
12232         IF_BASH_DOLLAR_SQUOTE(smallint bash_dollar_squote = 0;)
12233         /* syntax stack */
12234         struct synstack synbase = { };
12235         struct synstack *synstack = &synbase;
12236
12237 #if ENABLE_ASH_EXPAND_PRMT
12238         pssyntax = (syntax == PSSYNTAX);
12239         if (pssyntax)
12240                 syntax = DQSYNTAX;
12241 #else
12242         pssyntax = 0; /* constant */
12243 #endif
12244         synstack->syntax = syntax;
12245
12246         if (syntax == DQSYNTAX)
12247                 synstack->dblquote = 1;
12248         quotef = 0;
12249         bqlist = NULL;
12250
12251         STARTSTACKSTR(out);
12252  loop:
12253         /* For each line, until end of word */
12254         CHECKEND();     /* set c to PEOF if at end of here document */
12255         for (;;) {      /* until end of line or end of word */
12256                 CHECKSTRSPACE(4, out);  /* permit 4 calls to USTPUTC */
12257                 switch (SIT(c, synstack->syntax)) {
12258                 case CNL:       /* '\n' */
12259                         if (synstack->syntax == BASESYNTAX
12260                          && !synstack->varnest
12261                         ) {
12262                                 goto endword;   /* exit outer loop */
12263                         }
12264                         USTPUTC(c, out);
12265                         nlprompt();
12266                         c = pgetc_top(synstack);
12267                         goto loop;              /* continue outer loop */
12268                 case CWORD:
12269                         USTPUTC(c, out);
12270                         break;
12271                 case CCTL:
12272 #if BASH_DOLLAR_SQUOTE
12273                         if (c == '\\' && bash_dollar_squote) {
12274                                 c = decode_dollar_squote();
12275                                 if (c == '\0') {
12276                                         /* skip $'\000', $'\x00' (like bash) */
12277                                         break;
12278                                 }
12279                                 if (c & 0x100) {
12280                                         /* Unknown escape. Encode as '\z' */
12281                                         c = (unsigned char)c;
12282                                         if (eofmark == NULL || synstack->dblquote)
12283                                                 USTPUTC(CTLESC, out);
12284                                         USTPUTC('\\', out);
12285                                 }
12286                         }
12287 #endif
12288                         if (!eofmark || synstack->dblquote || synstack->varnest)
12289                                 USTPUTC(CTLESC, out);
12290                         USTPUTC(c, out);
12291                         break;
12292                 case CBACK:     /* backslash */
12293                         c = pgetc_without_PEOA();
12294                         if (c == PEOF) {
12295                                 USTPUTC(CTLESC, out);
12296                                 USTPUTC('\\', out);
12297                                 pungetc();
12298                         } else {
12299                                 if (pssyntax && c == '$') {
12300                                         USTPUTC(CTLESC, out);
12301                                         USTPUTC('\\', out);
12302                                 }
12303                                 /* Backslash is retained if we are in "str"
12304                                  * and next char isn't dquote-special.
12305                                  */
12306                                 if (synstack->dblquote
12307                                  && c != '\\'
12308                                  && c != '`'
12309                                  && c != '$'
12310                                  && (c != '"' || (eofmark != NULL && !synstack->varnest))
12311                                  && (c != '}' || !synstack->varnest)
12312                                 ) {
12313                                         USTPUTC(CTLESC, out); /* protect '\' from glob */
12314                                         USTPUTC('\\', out);
12315                                 }
12316                                 USTPUTC(CTLESC, out);
12317                                 USTPUTC(c, out);
12318                                 quotef = 1;
12319                         }
12320                         break;
12321                 case CSQUOTE:
12322                         synstack->syntax = SQSYNTAX;
12323  quotemark:
12324                         if (eofmark == NULL) {
12325                                 USTPUTC(CTLQUOTEMARK, out);
12326                         }
12327                         break;
12328                 case CDQUOTE:
12329                         synstack->syntax = DQSYNTAX;
12330                         synstack->dblquote = 1;
12331  toggledq:
12332                         if (synstack->varnest)
12333                                 synstack->innerdq ^= 1;
12334                         goto quotemark;
12335                 case CENDQUOTE:
12336                         IF_BASH_DOLLAR_SQUOTE(bash_dollar_squote = 0;)
12337                         if (eofmark != NULL && synstack->varnest == 0) {
12338                                 USTPUTC(c, out);
12339                                 break;
12340                         }
12341
12342                         if (synstack->dqvarnest == 0) {
12343                                 synstack->syntax = BASESYNTAX;
12344                                 synstack->dblquote = 0;
12345                         }
12346
12347                         quotef = 1;
12348
12349                         if (c == '"')
12350                                 goto toggledq;
12351
12352                         goto quotemark;
12353                 case CVAR:      /* '$' */
12354                         PARSESUB();             /* parse substitution */
12355                         break;
12356                 case CENDVAR:   /* '}' */
12357                         if (!synstack->innerdq && synstack->varnest > 0) {
12358                                 if (!--synstack->varnest && synstack->varpushed)
12359                                         synstack_pop(&synstack);
12360                                 else if (synstack->dqvarnest > 0)
12361                                         synstack->dqvarnest--;
12362                                 c = CTLENDVAR;
12363                         }
12364                         USTPUTC(c, out);
12365                         break;
12366 #if ENABLE_FEATURE_SH_MATH
12367                 case CLP:       /* '(' in arithmetic */
12368                         synstack->parenlevel++;
12369                         USTPUTC(c, out);
12370                         break;
12371                 case CRP:       /* ')' in arithmetic */
12372                         if (synstack->parenlevel > 0) {
12373                                 synstack->parenlevel--;
12374                         } else {
12375                                 if (pgetc_eatbnl() == ')') {
12376                                         c = CTLENDARI;
12377                                         synstack_pop(&synstack);
12378                                 } else {
12379                                         /*
12380                                          * unbalanced parens
12381                                          * (don't 2nd guess - no error)
12382                                          */
12383                                         pungetc();
12384                                 }
12385                         }
12386                         USTPUTC(c, out);
12387                         break;
12388 #endif
12389                 case CBQUOTE:   /* '`' */
12390                         if (checkkwd & CHKEOFMARK) {
12391                                 quotef = 1;
12392                                 USTPUTC('`', out);
12393                                 break;
12394                         }
12395
12396                         PARSEBACKQOLD();
12397                         break;
12398                 case CENDFILE:
12399                         goto endword;           /* exit outer loop */
12400                 case CIGN:
12401                         break;
12402                 default:
12403                         if (synstack->varnest == 0) {
12404 #if BASH_REDIR_OUTPUT
12405                                 if (c == '&') {
12406 //Can't call pgetc_eatbnl() here, this requires three-deep pungetc()
12407                                         if (pgetc() == '>')
12408                                                 c = 0x100 + '>'; /* flag &> */
12409                                         pungetc();
12410                                 }
12411 #endif
12412                                 goto endword;   /* exit outer loop */
12413                         }
12414                         IF_ASH_ALIAS(if (c != PEOA))
12415                                 USTPUTC(c, out);
12416                 }
12417                 c = pgetc_top(synstack);
12418         } /* for (;;) */
12419  endword:
12420
12421 #if ENABLE_FEATURE_SH_MATH
12422         if (synstack->syntax == ARISYNTAX)
12423                 raise_error_syntax("missing '))'");
12424 #endif
12425         if (synstack->syntax != BASESYNTAX && eofmark == NULL)
12426                 raise_error_syntax("unterminated quoted string");
12427         if (synstack->varnest != 0) {
12428                 /* { */
12429                 raise_error_syntax("missing '}'");
12430         }
12431         USTPUTC('\0', out);
12432         len = out - (char *)stackblock();
12433         out = stackblock();
12434         if (eofmark == NULL) {
12435                 if ((c == '>' || c == '<' IF_BASH_REDIR_OUTPUT( || c == 0x100 + '>'))
12436                  && quotef == 0
12437                 ) {
12438                         if (isdigit_str9(out)) {
12439                                 PARSEREDIR(); /* passed as params: out, c */
12440                                 lasttoken = TREDIR;
12441                                 return lasttoken;
12442                         }
12443                         /* else: non-number X seen, interpret it
12444                          * as "NNNX>file" = "NNNX >file" */
12445                 }
12446                 pungetc();
12447         }
12448         quoteflag = quotef;
12449         backquotelist = bqlist;
12450         grabstackblock(len);
12451         wordtext = out;
12452         lasttoken = TWORD;
12453         return lasttoken;
12454 /* end of readtoken routine */
12455
12456 /*
12457  * Check to see whether we are at the end of the here document.  When this
12458  * is called, c is set to the first character of the next input line.  If
12459  * we are at the end of the here document, this routine sets the c to PEOF.
12460  */
12461 checkend: {
12462         if (realeofmark(eofmark)) {
12463                 int markloc;
12464                 char *p;
12465
12466 #if ENABLE_ASH_ALIAS
12467                 if (c == PEOA)
12468                         c = pgetc_without_PEOA();
12469 #endif
12470                 if (striptabs) {
12471                         while (c == '\t') {
12472                                 c = pgetc_without_PEOA();
12473                         }
12474                 }
12475
12476                 markloc = out - (char *)stackblock();
12477                 for (p = eofmark; STPUTC(c, out), *p; p++) {
12478                         if (c != *p)
12479                                 goto more_heredoc;
12480                         /* FIXME: fails for backslash-newlined terminator:
12481                          * cat <<EOF
12482                          * ...
12483                          * EO\
12484                          * F
12485                          * (see heredoc_bkslash_newline2.tests)
12486                          */
12487                         c = pgetc_without_PEOA();
12488                 }
12489
12490                 if (c == '\n' || c == PEOF) {
12491                         c = PEOF;
12492                         g_parsefile->linno++;
12493                         needprompt = doprompt;
12494                 } else {
12495                         int len_here;
12496
12497  more_heredoc:
12498                         p = (char *)stackblock() + markloc + 1;
12499                         len_here = out - p;
12500
12501                         if (len_here) {
12502                                 len_here -= (c >= PEOF);
12503                                 c = p[-1];
12504
12505                                 if (len_here) {
12506                                         char *str;
12507
12508                                         str = alloca(len_here + 1);
12509                                         *(char *)mempcpy(str, p, len_here) = '\0';
12510
12511                                         pushstring(str, NULL);
12512                                 }
12513                         }
12514                 }
12515
12516                 STADJUST((char *)stackblock() + markloc - out, out);
12517         }
12518         goto checkend_return;
12519 }
12520
12521 /*
12522  * Parse a redirection operator.  The variable "out" points to a string
12523  * specifying the fd to be redirected.  The variable "c" contains the
12524  * first character of the redirection operator.
12525  */
12526 parseredir: {
12527         /* out is already checked to be a valid number or "" */
12528         int fd = (*out == '\0' ? -1 : atoi(out));
12529         union node *np;
12530
12531         np = stzalloc(sizeof(struct nfile));
12532         if (c == '>') {
12533                 np->nfile.fd = 1;
12534                 c = pgetc_eatbnl();
12535                 if (c == '>')
12536                         np->type = NAPPEND;
12537                 else if (c == '|')
12538                         np->type = NCLOBBER;
12539                 else if (c == '&')
12540                         np->type = NTOFD;
12541                         /* it also can be NTO2 (>&file), but we can't figure it out yet */
12542                 else {
12543                         np->type = NTO;
12544                         pungetc();
12545                 }
12546         }
12547 #if BASH_REDIR_OUTPUT
12548         else if (c == 0x100 + '>') { /* this flags &> redirection */
12549                 np->nfile.fd = 1;
12550                 pgetc(); /* this is '>', no need to check */
12551                 np->type = NTO2;
12552         }
12553 #endif
12554         else { /* c == '<' */
12555                 /*np->nfile.fd = 0; - stzalloc did it */
12556                 c = pgetc_eatbnl();
12557                 switch (c) {
12558                 case '<':
12559                         if (sizeof(struct nfile) != sizeof(struct nhere)) {
12560                                 np = stzalloc(sizeof(struct nhere));
12561                                 /*np->nfile.fd = 0; - stzalloc did it */
12562                         }
12563                         np->type = NHERE;
12564                         heredoc = stzalloc(sizeof(struct heredoc));
12565                         heredoc->here = np;
12566                         c = pgetc_eatbnl();
12567                         if (c == '-') {
12568                                 heredoc->striptabs = 1;
12569                         } else {
12570                                 /*heredoc->striptabs = 0; - stzalloc did it */
12571                                 pungetc();
12572                         }
12573                         break;
12574
12575                 case '&':
12576                         np->type = NFROMFD;
12577                         break;
12578
12579                 case '>':
12580                         np->type = NFROMTO;
12581                         break;
12582
12583                 default:
12584                         np->type = NFROM;
12585                         pungetc();
12586                         break;
12587                 }
12588         }
12589         if (fd >= 0)
12590                 np->nfile.fd = fd;
12591         redirnode = np;
12592         goto parseredir_return;
12593 }
12594
12595 /*
12596  * Parse a substitution.  At this point, we have read the dollar sign
12597  * and nothing else.
12598  */
12599
12600 /* is_special(c) evaluates to 1 for c in "!#$*-0123456789?@"; 0 otherwise
12601  * (assuming ascii char codes, as the original implementation did) */
12602 #define is_special(c) \
12603         (((unsigned)(c) - 33 < 32) \
12604                         && ((0xc1ff920dU >> ((unsigned)(c) - 33)) & 1))
12605 parsesub: {
12606         unsigned char subtype;
12607         int typeloc;
12608
12609         c = pgetc_eatbnl();
12610         if ((checkkwd & CHKEOFMARK)
12611          || c > 255 /* PEOA or PEOF */
12612          || (c != '(' && c != '{' && !is_name(c) && !is_special(c))
12613         ) {
12614 #if BASH_DOLLAR_SQUOTE
12615                 if (synstack->syntax != DQSYNTAX && c == '\'')
12616                         bash_dollar_squote = 1;
12617                 else
12618 #endif
12619                         USTPUTC('$', out);
12620                 pungetc();
12621         } else if (c == '(') {
12622                 /* $(command) or $((arith)) */
12623                 if (pgetc_eatbnl() == '(') {
12624 #if ENABLE_FEATURE_SH_MATH
12625                         PARSEARITH();
12626 #else
12627                         raise_error_syntax("support for $((arith)) is disabled");
12628 #endif
12629                 } else {
12630                         pungetc();
12631                         PARSEBACKQNEW();
12632                 }
12633         } else {
12634                 /* $VAR, $<specialchar>, ${...}, or PEOA/PEOF */
12635                 smalluint newsyn = synstack->syntax;
12636
12637                 USTPUTC(CTLVAR, out);
12638                 typeloc = out - (char *)stackblock();
12639                 STADJUST(1, out);
12640                 subtype = VSNORMAL;
12641                 if (c == '{') {
12642                         c = pgetc_eatbnl();
12643                         subtype = 0;
12644                 }
12645  varname:
12646                 if (is_name(c)) {
12647                         /* $[{[#]]NAME[}] */
12648                         do {
12649                                 STPUTC(c, out);
12650                                 c = pgetc_eatbnl();
12651                         } while (is_in_name(c));
12652                 } else if (isdigit(c)) {
12653                         /* $[{[#]]NUM[}] */
12654                         do {
12655                                 STPUTC(c, out);
12656                                 c = pgetc_eatbnl();
12657                         } while (!subtype && isdigit(c));
12658                 } else if (c != '}') {
12659                         /* $[{[#]]<specialchar>[}] */
12660                         int cc = c;
12661
12662                         c = pgetc_eatbnl();
12663                         if (!subtype && cc == '#') {
12664                                 subtype = VSLENGTH;
12665                                 if (c == '_' || isalnum(c))
12666                                         goto varname;
12667                                 cc = c;
12668                                 c = pgetc_eatbnl();
12669                                 if (cc == '}' || c != '}') {
12670                                         pungetc();
12671                                         subtype = 0;
12672                                         c = cc;
12673                                         cc = '#';
12674                                 }
12675                         }
12676
12677                         if (!is_special(cc)) {
12678                                 if (subtype == VSLENGTH)
12679                                         subtype = 0;
12680                                 goto badsub;
12681                         }
12682
12683                         USTPUTC(cc, out);
12684                 } else
12685                         goto badsub;
12686
12687                 if (c != '}' && subtype == VSLENGTH) {
12688                         /* ${#VAR didn't end with } */
12689                         goto badsub;
12690                 }
12691
12692                 if (subtype == 0) {
12693                         static const char types[] ALIGN1 = "}-+?=";
12694                         /* ${VAR...} but not $VAR or ${#VAR} */
12695                         /* c == first char after VAR */
12696                         int cc = c;
12697
12698                         switch (c) {
12699                         case ':':
12700                                 c = pgetc_eatbnl();
12701 #if BASH_SUBSTR
12702                                 /* This check is only needed to not misinterpret
12703                                  * ${VAR:-WORD}, ${VAR:+WORD}, ${VAR:=WORD}, ${VAR:?WORD}
12704                                  * constructs.
12705                                  */
12706                                 if (!strchr(types, c)) {
12707                                         subtype = VSSUBSTR;
12708                                         pungetc();
12709                                         break; /* "goto badsub" is bigger (!) */
12710                                 }
12711 #endif
12712                                 subtype = VSNUL;
12713                                 /*FALLTHROUGH*/
12714                         default: {
12715                                 const char *p = strchr(types, c);
12716                                 if (p == NULL)
12717                                         break;
12718                                 subtype |= p - types + VSNORMAL;
12719                                 break;
12720                         }
12721                         case '%':
12722                         case '#':
12723                                 subtype = (c == '#' ? VSTRIMLEFT : VSTRIMRIGHT);
12724                                 c = pgetc_eatbnl();
12725                                 if (c == cc)
12726                                         subtype++;
12727                                 else
12728                                         pungetc();
12729
12730                                 newsyn = BASESYNTAX;
12731                                 break;
12732 #if BASH_PATTERN_SUBST
12733                         case '/':
12734                                 /* ${v/[/]pattern/repl} */
12735 //TODO: encode pattern and repl separately.
12736 // Currently cases like: v=1;echo ${v/$((1/1))/ONE}
12737 // are broken (should print "ONE")
12738                                 subtype = VSREPLACE;
12739                                 newsyn = BASESYNTAX;
12740                                 c = pgetc_eatbnl();
12741                                 if (c != '/')
12742                                         goto badsub;
12743                                 subtype++; /* VSREPLACEALL */
12744                                 break;
12745 #endif
12746                         }
12747                 } else {
12748  badsub:
12749                         pungetc();
12750                 }
12751
12752                 if (newsyn == ARISYNTAX)
12753                         newsyn = DQSYNTAX;
12754
12755                 if ((newsyn != synstack->syntax || synstack->innerdq)
12756                  && subtype != VSNORMAL
12757                 ) {
12758                         synstack_push(&synstack,
12759                                 synstack->prev ?: alloca(sizeof(*synstack)),
12760                                 newsyn);
12761
12762                         synstack->varpushed = 1;
12763                         synstack->dblquote = newsyn != BASESYNTAX;
12764                 }
12765
12766                 ((unsigned char *)stackblock())[typeloc] = subtype;
12767                 if (subtype != VSNORMAL) {
12768                         synstack->varnest++;
12769                         if (synstack->dblquote)
12770                                 synstack->dqvarnest++;
12771                 }
12772                 STPUTC('=', out);
12773         }
12774         goto parsesub_return;
12775 }
12776
12777 /*
12778  * Called to parse command substitutions.  Newstyle is set if the command
12779  * is enclosed inside $(...); nlpp is a pointer to the head of the linked
12780  * list of commands (passed by reference), and savelen is the number of
12781  * characters on the top of the stack which must be preserved.
12782  */
12783 parsebackq: {
12784         struct nodelist **nlpp;
12785         union node *n;
12786         char *str;
12787         size_t savelen;
12788         struct heredoc *saveheredoclist;
12789         smallint saveprompt = 0;
12790
12791         str = NULL;
12792         savelen = out - (char *)stackblock();
12793         if (savelen > 0) {
12794                 /*
12795                  * FIXME: this can allocate very large block on stack and SEGV.
12796                  * Example:
12797                  * echo "..<100kbytes>..`true` $(true) `true` ..."
12798                  * allocates 100kb for every command subst. With about
12799                  * a hundred command substitutions stack overflows.
12800                  * With larger prepended string, SEGV happens sooner.
12801                  */
12802                 str = alloca(savelen);
12803                 memcpy(str, stackblock(), savelen);
12804         }
12805
12806         if (oldstyle) {
12807                 /* We must read until the closing backquote, giving special
12808                  * treatment to some slashes, and then push the string and
12809                  * reread it as input, interpreting it normally.
12810                  */
12811                 char *pout;
12812                 size_t psavelen;
12813                 char *pstr;
12814
12815                 STARTSTACKSTR(pout);
12816                 for (;;) {
12817                         int pc;
12818
12819                         setprompt_if(needprompt, 2);
12820                         pc = pgetc_eatbnl();
12821                         switch (pc) {
12822                         case '`':
12823                                 goto done;
12824
12825                         case '\\':
12826                                 pc = pgetc(); /* or pgetc_eatbnl()? why (example)? */
12827                                 if (pc != '\\' && pc != '`' && pc != '$'
12828                                  && (!synstack->dblquote || pc != '"')
12829                                 ) {
12830                                         STPUTC('\\', pout);
12831                                 }
12832                                 if (pc <= 255 /* not PEOA or PEOF */) {
12833                                         break;
12834                                 }
12835                                 /* fall through */
12836
12837                         case PEOF:
12838                         IF_ASH_ALIAS(case PEOA:)
12839                                 raise_error_syntax("EOF in backquote substitution");
12840
12841                         case '\n':
12842                                 nlnoprompt();
12843                                 break;
12844
12845                         default:
12846                                 break;
12847                         }
12848                         STPUTC(pc, pout);
12849                 }
12850  done:
12851                 STPUTC('\0', pout);
12852                 psavelen = pout - (char *)stackblock();
12853                 if (psavelen > 0) {
12854                         pstr = grabstackstr(pout);
12855                         setinputstring(pstr);
12856                 }
12857         }
12858         nlpp = &bqlist;
12859         while (*nlpp)
12860                 nlpp = &(*nlpp)->next;
12861         *nlpp = stzalloc(sizeof(**nlpp));
12862         /* (*nlpp)->next = NULL; - stzalloc did it */
12863
12864         saveheredoclist = heredoclist;
12865         heredoclist = NULL;
12866
12867         if (oldstyle) {
12868                 saveprompt = doprompt;
12869                 doprompt = 0;
12870         }
12871
12872         n = list(2);
12873
12874         if (oldstyle)
12875                 doprompt = saveprompt;
12876         else {
12877                 if (readtoken() != TRP)
12878                         raise_error_unexpected_syntax(TRP);
12879                 setinputstring(nullstr);
12880                 parseheredoc();
12881         }
12882
12883         heredoclist = saveheredoclist;
12884
12885         (*nlpp)->n = n;
12886         /* Start reading from old file again. */
12887         popfile();
12888         /* Ignore any pushed back tokens left from the backquote parsing. */
12889         if (oldstyle)
12890                 tokpushback = 0;
12891         out = growstackto(savelen + 1);
12892         if (str) {
12893                 memcpy(out, str, savelen);
12894                 STADJUST(savelen, out);
12895         }
12896         USTPUTC(CTLBACKQ, out);
12897         if (oldstyle)
12898                 goto parsebackq_oldreturn;
12899         goto parsebackq_newreturn;
12900 }
12901
12902 #if ENABLE_FEATURE_SH_MATH
12903 /*
12904  * Parse an arithmetic expansion (indicate start of one and set state)
12905  */
12906 parsearith: {
12907
12908         synstack_push(&synstack,
12909                         synstack->prev ?: alloca(sizeof(*synstack)),
12910                         ARISYNTAX);
12911         synstack->dblquote = 1;
12912         USTPUTC(CTLARI, out);
12913         goto parsearith_return;
12914 }
12915 #endif
12916 } /* end of readtoken */
12917
12918 /*
12919  * Read the next input token.
12920  * If the token is a word, we set backquotelist to the list of cmds in
12921  *      backquotes.  We set quoteflag to true if any part of the word was
12922  *      quoted.
12923  * If the token is TREDIR, then we set redirnode to a structure containing
12924  *      the redirection.
12925  *
12926  * [Change comment:  here documents and internal procedures]
12927  * [Readtoken shouldn't have any arguments.  Perhaps we should make the
12928  *  word parsing code into a separate routine.  In this case, readtoken
12929  *  doesn't need to have any internal procedures, but parseword does.
12930  *  We could also make parseoperator in essence the main routine, and
12931  *  have parseword (readtoken1?) handle both words and redirection.]
12932  */
12933 #define NEW_xxreadtoken
12934 #ifdef NEW_xxreadtoken
12935 /* singles must be first! */
12936 static const char xxreadtoken_chars[7] ALIGN1 = {
12937         '\n', '(', ')', /* singles */
12938         '&', '|', ';',  /* doubles */
12939         0
12940 };
12941
12942 #define xxreadtoken_singles 3
12943 #define xxreadtoken_doubles 3
12944
12945 static const char xxreadtoken_tokens[] ALIGN1 = {
12946         TNL, TLP, TRP,          /* only single occurrence allowed */
12947         TBACKGND, TPIPE, TSEMI, /* if single occurrence */
12948         TEOF,                   /* corresponds to trailing nul */
12949         TAND, TOR, TENDCASE     /* if double occurrence */
12950 };
12951
12952 static int
12953 xxreadtoken(void)
12954 {
12955         int c;
12956
12957         if (tokpushback) {
12958                 tokpushback = 0;
12959                 return lasttoken;
12960         }
12961         setprompt_if(needprompt, 2);
12962         for (;;) {                      /* until token or start of word found */
12963                 c = pgetc_eatbnl();
12964                 if (c == ' ' || c == '\t' IF_ASH_ALIAS( || c == PEOA))
12965                         continue;
12966
12967                 if (c == '#') {
12968                         while ((c = pgetc()) != '\n' && c != PEOF)
12969                                 continue;
12970                         pungetc();
12971                 } else if (c == '\\') {
12972                         break; /* return readtoken1(...) */
12973                 } else {
12974                         const char *p;
12975
12976                         p = xxreadtoken_chars + sizeof(xxreadtoken_chars) - 1;
12977                         if (c != PEOF) {
12978                                 if (c == '\n') {
12979                                         nlnoprompt();
12980                                 }
12981
12982                                 p = strchr(xxreadtoken_chars, c);
12983                                 if (p == NULL)
12984                                         break; /* return readtoken1(...) */
12985
12986                                 if ((int)(p - xxreadtoken_chars) >= xxreadtoken_singles) {
12987                                         int cc = pgetc_eatbnl();
12988                                         if (cc == c) {    /* double occurrence? */
12989                                                 p += xxreadtoken_doubles + 1;
12990                                         } else {
12991                                                 pungetc();
12992 #if BASH_REDIR_OUTPUT
12993                                                 if (c == '&' && cc == '>') /* &> */
12994                                                         break; /* return readtoken1(...) */
12995 #endif
12996                                         }
12997                                 }
12998                         }
12999                         lasttoken = xxreadtoken_tokens[p - xxreadtoken_chars];
13000                         return lasttoken;
13001                 }
13002         } /* for (;;) */
13003
13004         return readtoken1(c, BASESYNTAX, (char *) NULL, 0);
13005 }
13006 #else /* old xxreadtoken */
13007 #define RETURN(token)   return lasttoken = token
13008 static int
13009 xxreadtoken(void)
13010 {
13011         int c;
13012
13013         if (tokpushback) {
13014                 tokpushback = 0;
13015                 return lasttoken;
13016         }
13017         setprompt_if(needprompt, 2);
13018         for (;;) {      /* until token or start of word found */
13019                 c = pgetc_eatbnl();
13020                 switch (c) {
13021                 case ' ': case '\t':
13022                 IF_ASH_ALIAS(case PEOA:)
13023                         continue;
13024                 case '#':
13025                         while ((c = pgetc()) != '\n' && c != PEOF)
13026                                 continue;
13027                         pungetc();
13028                         continue;
13029                 case '\n':
13030                         nlnoprompt();
13031                         RETURN(TNL);
13032                 case PEOF:
13033                         RETURN(TEOF);
13034                 case '&':
13035                         if (pgetc_eatbnl() == '&')
13036                                 RETURN(TAND);
13037                         pungetc();
13038                         RETURN(TBACKGND);
13039                 case '|':
13040                         if (pgetc_eatbnl() == '|')
13041                                 RETURN(TOR);
13042                         pungetc();
13043                         RETURN(TPIPE);
13044                 case ';':
13045                         if (pgetc_eatbnl() == ';')
13046                                 RETURN(TENDCASE);
13047                         pungetc();
13048                         RETURN(TSEMI);
13049                 case '(':
13050                         RETURN(TLP);
13051                 case ')':
13052                         RETURN(TRP);
13053                 }
13054                 break;
13055         }
13056         return readtoken1(c, BASESYNTAX, (char *)NULL, 0);
13057 #undef RETURN
13058 }
13059 #endif /* old xxreadtoken */
13060
13061 static int
13062 readtoken(void)
13063 {
13064         int t;
13065         int kwd = checkkwd;
13066 #if DEBUG
13067         smallint alreadyseen = tokpushback;
13068 #endif
13069
13070 #if ENABLE_ASH_ALIAS
13071  top:
13072 #endif
13073
13074         t = xxreadtoken();
13075
13076         /*
13077          * eat newlines
13078          */
13079         if (kwd & CHKNL) {
13080                 while (t == TNL) {
13081                         parseheredoc();
13082                         t = xxreadtoken();
13083                 }
13084         }
13085
13086         if (t != TWORD || quoteflag) {
13087                 goto out;
13088         }
13089
13090         /*
13091          * check for keywords
13092          */
13093         if (kwd & CHKKWD) {
13094                 const char *const *pp;
13095
13096                 pp = findkwd(wordtext);
13097                 if (pp) {
13098                         lasttoken = t = pp - tokname_array;
13099                         TRACE(("keyword '%s' recognized\n", tokname_array[t]));
13100                         goto out;
13101                 }
13102         }
13103
13104         if (checkkwd & CHKALIAS) {
13105 #if ENABLE_ASH_ALIAS
13106                 struct alias *ap;
13107                 ap = lookupalias(wordtext, 1);
13108                 if (ap != NULL) {
13109                         if (*ap->val) {
13110                                 pushstring(ap->val, ap);
13111                         }
13112                         goto top;
13113                 }
13114 #endif
13115         }
13116  out:
13117         checkkwd = 0;
13118 #if DEBUG
13119         if (!alreadyseen)
13120                 TRACE(("token '%s' %s\n", tokname_array[t], t == TWORD ? wordtext : ""));
13121         else
13122                 TRACE(("reread token '%s' %s\n", tokname_array[t], t == TWORD ? wordtext : ""));
13123 #endif
13124         return t;
13125 }
13126
13127 static int
13128 peektoken(void)
13129 {
13130         int t;
13131
13132         t = readtoken();
13133         tokpushback = 1;
13134         return t;
13135 }
13136
13137 /*
13138  * Read and parse a command.  Returns NODE_EOF on end of file.
13139  * (NULL is a valid parse tree indicating a blank line.)
13140  */
13141 static union node *
13142 parsecmd(int interact)
13143 {
13144         tokpushback = 0;
13145         checkkwd = 0;
13146         heredoclist = 0;
13147         doprompt = interact;
13148         setprompt_if(doprompt, doprompt);
13149         needprompt = 0;
13150         return list(1);
13151 }
13152
13153 /*
13154  * Input any here documents.
13155  */
13156 static void
13157 parseheredoc(void)
13158 {
13159         struct heredoc *here;
13160         union node *n;
13161
13162         here = heredoclist;
13163         heredoclist = NULL;
13164
13165         while (here) {
13166                 tokpushback = 0;
13167                 setprompt_if(needprompt, 2);
13168                 if (here->here->type == NHERE)
13169                         readtoken1(pgetc(), SQSYNTAX, here->eofmark, here->striptabs);
13170                 else
13171                         readtoken1(pgetc_eatbnl(), DQSYNTAX, here->eofmark, here->striptabs);
13172                 n = stzalloc(sizeof(struct narg));
13173                 n->narg.type = NARG;
13174                 /*n->narg.next = NULL; - stzalloc did it */
13175                 n->narg.text = wordtext;
13176                 n->narg.backquote = backquotelist;
13177                 here->here->nhere.doc = n;
13178                 here = here->next;
13179         }
13180 }
13181
13182
13183 static const char *
13184 expandstr(const char *ps, int syntax_type)
13185 {
13186         union node n;
13187         int saveprompt;
13188         struct parsefile *file_stop = g_parsefile;
13189         volatile int saveint;
13190         struct jmploc *volatile savehandler = exception_handler;
13191         struct jmploc jmploc;
13192         const char *volatile result;
13193         int err;
13194
13195         /* XXX Fix (char *) cast. */
13196         setinputstring((char *)ps);
13197
13198         saveprompt = doprompt;
13199         doprompt = 0;
13200         result = ps;
13201
13202         SAVE_INT(saveint);
13203         err = setjmp(jmploc.loc);
13204         if (err)
13205                 goto out;
13206
13207         /* readtoken1() might die horribly.
13208          * Try a prompt with syntactically wrong command:
13209          * PS1='$(date "+%H:%M:%S) > '
13210          */
13211         exception_handler = &jmploc;
13212         readtoken1(pgetc(), syntax_type, FAKEEOFMARK, 0);
13213
13214         n.narg.type = NARG;
13215         n.narg.next = NULL;
13216         n.narg.text = wordtext;
13217         n.narg.backquote = backquotelist;
13218
13219         /* expandarg() might fail too:
13220          * PS1='$((123+))'
13221          */
13222         expandarg(&n, NULL, EXP_QUOTED);
13223         result = stackblock();
13224
13225 out:
13226         exception_handler = savehandler;
13227         if (err && exception_type != EXERROR)
13228                 longjmp(exception_handler->loc, 1);
13229         RESTORE_INT(saveint);
13230
13231         doprompt = saveprompt;
13232         /* Try: PS1='`xxx(`' */
13233         unwindfiles(file_stop);
13234
13235         return result;
13236 }
13237
13238 static inline int
13239 parser_eof(void)
13240 {
13241         return tokpushback && lasttoken == TEOF;
13242 }
13243
13244 /*
13245  * Execute a command or commands contained in a string.
13246  */
13247 static int
13248 evalstring(char *s, int flags)
13249 {
13250         struct jmploc *volatile savehandler;
13251         struct jmploc jmploc;
13252         int ex;
13253
13254         union node *n;
13255         struct stackmark smark;
13256         int status;
13257
13258         s = sstrdup(s);
13259         setinputstring(s);
13260         setstackmark(&smark);
13261
13262         status = 0;
13263         /* On exception inside execution loop, we must popfile().
13264          * Try interactively:
13265          *      readonly a=a
13266          *      command eval "a=b"  # throws "is read only" error
13267          * "command BLTIN" is not supposed to abort (even in non-interactive use).
13268          * But if we skip popfile(), we hit EOF in eval's string, and exit.
13269          */
13270         savehandler = exception_handler;
13271         ex = setjmp(jmploc.loc);
13272         if (ex)
13273                 goto out;
13274         exception_handler = &jmploc;
13275
13276         while ((n = parsecmd(0)) != NODE_EOF) {
13277                 int i;
13278
13279                 i = evaltree(n, flags & ~(parser_eof() ? 0 : EV_EXIT));
13280                 if (n)
13281                         status = i;
13282                 popstackmark(&smark);
13283                 if (evalskip)
13284                         break;
13285         }
13286  out:
13287         popstackmark(&smark);
13288         popfile();
13289         stunalloc(s);
13290
13291         exception_handler = savehandler;
13292         if (ex)
13293                 longjmp(exception_handler->loc, ex);
13294
13295         return status;
13296 }
13297
13298 /*
13299  * The eval command.
13300  */
13301 static int FAST_FUNC
13302 evalcmd(int argc UNUSED_PARAM, char **argv, int flags)
13303 {
13304         char *p;
13305         char *concat;
13306
13307         if (argv[1]) {
13308                 p = argv[1];
13309                 argv += 2;
13310                 if (argv[0]) {
13311                         STARTSTACKSTR(concat);
13312                         for (;;) {
13313                                 concat = stack_putstr(p, concat);
13314                                 p = *argv++;
13315                                 if (p == NULL)
13316                                         break;
13317                                 STPUTC(' ', concat);
13318                         }
13319                         STPUTC('\0', concat);
13320                         p = grabstackstr(concat);
13321                 }
13322                 return evalstring(p, flags & EV_TESTED);
13323         }
13324         return 0;
13325 }
13326
13327 /*
13328  * Read and execute commands.
13329  * "Top" is nonzero for the top level command loop;
13330  * it turns on prompting if the shell is interactive.
13331  */
13332 static int
13333 cmdloop(int top)
13334 {
13335         union node *n;
13336         struct stackmark smark;
13337         int inter;
13338         int status = 0;
13339         int numeof = 0;
13340
13341         TRACE(("cmdloop(%d) called\n", top));
13342         for (;;) {
13343                 int skip;
13344
13345                 setstackmark(&smark);
13346 #if JOBS
13347                 if (doing_jobctl)
13348                         showjobs(SHOW_CHANGED|SHOW_STDERR);
13349 #endif
13350                 inter = 0;
13351                 if (iflag && top) {
13352                         inter++;
13353                         chkmail();
13354                 }
13355                 n = parsecmd(inter);
13356 #if DEBUG
13357                 if (DEBUG > 2 && debug && (n != NODE_EOF))
13358                         showtree(n);
13359 #endif
13360                 if (n == NODE_EOF) {
13361                         if (!top || numeof >= 50)
13362                                 break;
13363                         if (!stoppedjobs()) {
13364                                 if (!Iflag) {
13365                                         if (iflag) {
13366                                                 newline_and_flush(stderr);
13367                                         }
13368                                         break;
13369                                 }
13370                                 out2str("\nUse \"exit\" to leave shell.\n");
13371                         }
13372                         numeof++;
13373                 } else if (nflag == 0) {
13374                         int i;
13375
13376                         /* job_warning can only be 2,1,0. Here 2->1, 1/0->0 */
13377                         job_warning >>= 1;
13378                         numeof = 0;
13379                         i = evaltree(n, 0);
13380                         if (n)
13381                                 status = i;
13382                 }
13383                 popstackmark(&smark);
13384                 skip = evalskip;
13385
13386                 if (skip) {
13387                         evalskip &= ~(SKIPFUNC | SKIPFUNCDEF);
13388                         break;
13389                 }
13390         }
13391         return status;
13392 }
13393
13394 /*
13395  * Take commands from a file.  To be compatible we should do a path
13396  * search for the file, which is necessary to find sub-commands.
13397  */
13398 static char *
13399 find_dot_file(char *basename)
13400 {
13401         char *fullname;
13402         const char *path = pathval();
13403         struct stat statb;
13404         int len;
13405
13406         /* don't try this for absolute or relative paths */
13407         if (strchr(basename, '/'))
13408                 return basename;
13409
13410         while ((len = padvance(&path, basename)) >= 0) {
13411                 fullname = stackblock();
13412                 if ((!pathopt || *pathopt == 'f')
13413                  && !stat(fullname, &statb) && S_ISREG(statb.st_mode)
13414                 ) {
13415                         /* This will be freed by the caller. */
13416                         return stalloc(len);
13417                 }
13418         }
13419         /* not found in PATH */
13420
13421 #if ENABLE_ASH_BASH_SOURCE_CURDIR
13422         return basename;
13423 #else
13424         ash_msg_and_raise_error("%s: not found", basename);
13425         /* NOTREACHED */
13426 #endif
13427 }
13428
13429 static int FAST_FUNC
13430 dotcmd(int argc_ UNUSED_PARAM, char **argv_ UNUSED_PARAM)
13431 {
13432         /* "false; . empty_file; echo $?" should print 0, not 1: */
13433         int status = 0;
13434         char *fullname;
13435         char **argv;
13436         char *args_need_save;
13437         volatile struct shparam saveparam;
13438
13439 //???
13440 //      struct strlist *sp;
13441 //      for (sp = cmdenviron; sp; sp = sp->next)
13442 //              setvareq(ckstrdup(sp->text), VSTRFIXED | VTEXTFIXED);
13443
13444         nextopt(nullstr); /* handle possible "--" */
13445         argv = argptr;
13446
13447         if (!argv[0]) {
13448                 /* bash says: "bash: .: filename argument required" */
13449                 return 2; /* bash compat */
13450         }
13451
13452         /* This aborts if file isn't found, which is POSIXly correct.
13453          * bash returns exitcode 1 instead.
13454          */
13455         fullname = find_dot_file(argv[0]);
13456         argv++;
13457         args_need_save = argv[0];
13458         if (args_need_save) { /* ". FILE ARGS", and ARGS are not empty */
13459                 int argc;
13460                 saveparam = shellparam;
13461                 shellparam.malloced = 0;
13462                 argc = 1;
13463                 while (argv[argc])
13464                         argc++;
13465                 shellparam.nparam = argc;
13466                 shellparam.p = argv;
13467         };
13468
13469         /* This aborts if file can't be opened, which is POSIXly correct.
13470          * bash returns exitcode 1 instead.
13471          */
13472         setinputfile(fullname, INPUT_PUSH_FILE);
13473         commandname = fullname;
13474         status = cmdloop(0);
13475         popfile();
13476
13477         if (args_need_save) {
13478                 freeparam(&shellparam);
13479                 shellparam = saveparam;
13480         };
13481
13482         return status;
13483 }
13484
13485 static int FAST_FUNC
13486 exitcmd(int argc UNUSED_PARAM, char **argv)
13487 {
13488         if (stoppedjobs())
13489                 return 0;
13490
13491         if (argv[1])
13492                 savestatus = number(argv[1]);
13493
13494         raise_exception(EXEXIT);
13495         /* NOTREACHED */
13496 }
13497
13498 /*
13499  * Read a file containing shell functions.
13500  */
13501 static void
13502 readcmdfile(char *name)
13503 {
13504         setinputfile(name, INPUT_PUSH_FILE);
13505         cmdloop(0);
13506         popfile();
13507 }
13508
13509
13510 /* ============ find_command inplementation */
13511
13512 /*
13513  * Resolve a command name.  If you change this routine, you may have to
13514  * change the shellexec routine as well.
13515  */
13516 static void
13517 find_command(char *name, struct cmdentry *entry, int act, const char *path)
13518 {
13519         struct tblentry *cmdp;
13520         int idx;
13521         int prev;
13522         char *fullname;
13523         struct stat statb;
13524         int e;
13525         int updatetbl;
13526         struct builtincmd *bcmd;
13527         int len;
13528
13529         /* If name contains a slash, don't use PATH or hash table */
13530         if (strchr(name, '/') != NULL) {
13531                 entry->u.index = -1;
13532                 if (act & DO_ABS) {
13533                         while (stat(name, &statb) < 0) {
13534 #ifdef SYSV
13535                                 if (errno == EINTR)
13536                                         continue;
13537 #endif
13538                                 entry->cmdtype = CMDUNKNOWN;
13539                                 return;
13540                         }
13541                 }
13542                 entry->cmdtype = CMDNORMAL;
13543                 return;
13544         }
13545
13546 /* #if ENABLE_FEATURE_SH_STANDALONE... moved after builtin check */
13547
13548         updatetbl = (path == pathval());
13549         if (!updatetbl)
13550                 act |= DO_ALTPATH;
13551
13552         /* If name is in the table, check answer will be ok */
13553         cmdp = cmdlookup(name, 0);
13554         if (cmdp != NULL) {
13555                 int bit;
13556
13557                 switch (cmdp->cmdtype) {
13558                 default:
13559 #if DEBUG
13560                         abort();
13561 #endif
13562                 case CMDNORMAL:
13563                         bit = DO_ALTPATH | DO_REGBLTIN;
13564                         break;
13565                 case CMDFUNCTION:
13566                         bit = DO_NOFUNC;
13567                         break;
13568                 case CMDBUILTIN:
13569                         bit = IS_BUILTIN_REGULAR(cmdp->param.cmd) ? 0 : DO_REGBLTIN;
13570                         break;
13571                 }
13572                 if (act & bit) {
13573                         if (act & bit & DO_REGBLTIN)
13574                                 goto fail;
13575
13576                         updatetbl = 0;
13577                         cmdp = NULL;
13578                 } else if (cmdp->rehash == 0)
13579                         /* if not invalidated by cd, we're done */
13580                         goto success;
13581         }
13582
13583         /* If %builtin not in path, check for builtin next */
13584         bcmd = find_builtin(name);
13585         if (bcmd) {
13586                 if (IS_BUILTIN_REGULAR(bcmd))
13587                         goto builtin_success;
13588                 if (act & DO_ALTPATH)
13589                         goto builtin_success;
13590                 if (builtinloc <= 0)
13591                         goto builtin_success;
13592         }
13593
13594         if (act & DO_REGBLTIN)
13595                 goto fail;
13596
13597 #if ENABLE_FEATURE_SH_STANDALONE
13598         {
13599                 int applet_no = find_applet_by_name(name);
13600                 if (applet_no >= 0) {
13601                         entry->cmdtype = CMDNORMAL;
13602                         entry->u.index = -2 - applet_no;
13603                         return;
13604                 }
13605         }
13606 #endif
13607
13608         /* We have to search path. */
13609         prev = -1;              /* where to start */
13610         if (cmdp && cmdp->rehash) {     /* doing a rehash */
13611                 if (cmdp->cmdtype == CMDBUILTIN)
13612                         prev = builtinloc;
13613                 else
13614                         prev = cmdp->param.index;
13615         }
13616
13617         e = ENOENT;
13618         idx = -1;
13619  loop:
13620         while ((len = padvance(&path, name)) >= 0) {
13621                 const char *lpathopt = pathopt;
13622
13623                 fullname = stackblock();
13624                 idx++;
13625                 if (lpathopt) {
13626                         if (*lpathopt == 'b') {
13627                                 if (bcmd)
13628                                         goto builtin_success;
13629                                 continue;
13630                         } else if (!(act & DO_NOFUNC)) {
13631                                 /* handled below */
13632                         } else {
13633                                 /* ignore unimplemented options */
13634                                 continue;
13635                         }
13636                 }
13637                 /* if rehash, don't redo absolute path names */
13638                 if (fullname[0] == '/' && idx <= prev) {
13639                         if (idx < prev)
13640                                 continue;
13641                         TRACE(("searchexec \"%s\": no change\n", name));
13642                         goto success;
13643                 }
13644                 while (stat(fullname, &statb) < 0) {
13645 #ifdef SYSV
13646                         if (errno == EINTR)
13647                                 continue;
13648 #endif
13649                         if (errno != ENOENT && errno != ENOTDIR)
13650                                 e = errno;
13651                         goto loop;
13652                 }
13653                 e = EACCES;     /* if we fail, this will be the error */
13654                 if (!S_ISREG(statb.st_mode))
13655                         continue;
13656                 if (lpathopt) {          /* this is a %func directory */
13657                         stalloc(len);
13658                         /* NB: stalloc will return space pointed by fullname
13659                          * (because we don't have any intervening allocations
13660                          * between stunalloc above and this stalloc) */
13661                         readcmdfile(fullname);
13662                         cmdp = cmdlookup(name, 0);
13663                         if (cmdp == NULL || cmdp->cmdtype != CMDFUNCTION)
13664                                 ash_msg_and_raise_error("%s not defined in %s", name, fullname);
13665                         stunalloc(fullname);
13666                         goto success;
13667                 }
13668                 TRACE(("searchexec \"%s\" returns \"%s\"\n", name, fullname));
13669                 if (!updatetbl) {
13670                         entry->cmdtype = CMDNORMAL;
13671                         entry->u.index = idx;
13672                         return;
13673                 }
13674                 INT_OFF;
13675                 cmdp = cmdlookup(name, 1);
13676                 cmdp->cmdtype = CMDNORMAL;
13677                 cmdp->param.index = idx;
13678                 INT_ON;
13679                 goto success;
13680         }
13681
13682         /* We failed.  If there was an entry for this command, delete it */
13683         if (cmdp && updatetbl)
13684                 delete_cmd_entry();
13685         if (act & DO_ERR) {
13686 #if ENABLE_ASH_BASH_NOT_FOUND_HOOK
13687                 struct tblentry *hookp = cmdlookup("command_not_found_handle", 0);
13688                 if (hookp && hookp->cmdtype == CMDFUNCTION) {
13689                         char *argv[3];
13690                         argv[0] = (char*) "command_not_found_handle";
13691                         argv[1] = name;
13692                         argv[2] = NULL;
13693                         evalfun(hookp->param.func, 2, argv, 0);
13694                         entry->cmdtype = CMDUNKNOWN;
13695                         return;
13696                 }
13697 #endif
13698                 ash_msg("%s: %s", name, errmsg(e, "not found"));
13699         }
13700  fail:
13701         entry->cmdtype = CMDUNKNOWN;
13702         return;
13703
13704  builtin_success:
13705         if (!updatetbl) {
13706                 entry->cmdtype = CMDBUILTIN;
13707                 entry->u.cmd = bcmd;
13708                 return;
13709         }
13710         INT_OFF;
13711         cmdp = cmdlookup(name, 1);
13712         cmdp->cmdtype = CMDBUILTIN;
13713         cmdp->param.cmd = bcmd;
13714         INT_ON;
13715  success:
13716         cmdp->rehash = 0;
13717         entry->cmdtype = cmdp->cmdtype;
13718         entry->u = cmdp->param;
13719 }
13720
13721
13722 /*
13723  * The trap builtin.
13724  */
13725 static int FAST_FUNC
13726 trapcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
13727 {
13728         char *action;
13729         char **ap;
13730         int signo, exitcode;
13731
13732         nextopt(nullstr);
13733         ap = argptr;
13734         if (!*ap) {
13735                 for (signo = 0; signo < NSIG; signo++) {
13736                         char *tr = trap_ptr[signo];
13737                         if (tr) {
13738                                 /* note: bash adds "SIG", but only if invoked
13739                                  * as "bash". If called as "sh", or if set -o posix,
13740                                  * then it prints short signal names.
13741                                  * We are printing short names: */
13742                                 out1fmt("trap -- %s %s\n",
13743                                                 single_quote(tr),
13744                                                 get_signame(signo));
13745                 /* trap_ptr != trap only if we are in special-cased `trap` code.
13746                  * In this case, we will exit very soon, no need to free(). */
13747                                 /* if (trap_ptr != trap && tp[0]) */
13748                                 /*      free(tr); */
13749                         }
13750                 }
13751                 /*
13752                 if (trap_ptr != trap) {
13753                         free(trap_ptr);
13754                         trap_ptr = trap;
13755                 }
13756                 */
13757                 return 0;
13758         }
13759
13760         /* Why the second check?
13761          * "trap NUM [sig2]..." is the same as "trap - NUM [sig2]..."
13762          * In this case, NUM is signal no, not an action.
13763          */
13764         action = NULL;
13765         if (ap[1] && !is_number(ap[0]))
13766                 action = *ap++;
13767
13768         exitcode = 0;
13769         while (*ap) {
13770                 signo = get_signum(*ap);
13771                 if (signo < 0) {
13772                         /* Mimic bash message exactly */
13773                         ash_msg("%s: invalid signal specification", *ap);
13774                         exitcode = 1;
13775                         goto next;
13776                 }
13777                 INT_OFF;
13778                 if (action) {
13779                         if (LONE_DASH(action))
13780                                 action = NULL;
13781                         else {
13782                                 if (action[0]) /* not NULL and not "" and not "-" */
13783                                         may_have_traps = 1;
13784                                 action = ckstrdup(action);
13785                         }
13786                 }
13787                 free(trap[signo]);
13788                 trap[signo] = action;
13789                 if (signo != 0)
13790                         setsignal(signo);
13791                 INT_ON;
13792  next:
13793                 ap++;
13794         }
13795         return exitcode;
13796 }
13797
13798
13799 /* ============ Builtins */
13800
13801 #if ENABLE_ASH_HELP
13802 static int FAST_FUNC
13803 helpcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
13804 {
13805         unsigned col;
13806         unsigned i;
13807
13808         out1fmt(
13809                 "Built-in commands:\n"
13810                 "------------------\n");
13811         for (col = 0, i = 0; i < ARRAY_SIZE(builtintab); i++) {
13812                 col += out1fmt("%c%s", ((col == 0) ? '\t' : ' '),
13813                                         builtintab[i].name + 1);
13814                 if (col > 60) {
13815                         out1fmt("\n");
13816                         col = 0;
13817                 }
13818         }
13819 # if ENABLE_FEATURE_SH_STANDALONE
13820         {
13821                 const char *a = applet_names;
13822                 while (*a) {
13823                         col += out1fmt("%c%s", ((col == 0) ? '\t' : ' '), a);
13824                         if (col > 60) {
13825                                 out1fmt("\n");
13826                                 col = 0;
13827                         }
13828                         while (*a++ != '\0')
13829                                 continue;
13830                 }
13831         }
13832 # endif
13833         newline_and_flush(stdout);
13834         return EXIT_SUCCESS;
13835 }
13836 #endif
13837
13838 #if MAX_HISTORY
13839 static int FAST_FUNC
13840 historycmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
13841 {
13842         if (line_input_state)
13843                 show_history(line_input_state);
13844         return EXIT_SUCCESS;
13845 }
13846 #endif
13847
13848 /*
13849  * The export and readonly commands.
13850  */
13851 static int FAST_FUNC
13852 exportcmd(int argc UNUSED_PARAM, char **argv)
13853 {
13854         struct var *vp;
13855         char *name;
13856         const char *p;
13857         char **aptr;
13858         char opt;
13859         int flag;
13860         int flag_off;
13861
13862         /* "readonly" in bash accepts, but ignores -n.
13863          * We do the same: it saves a conditional in nextopt's param.
13864          */
13865         flag_off = 0;
13866         while ((opt = nextopt("np")) != '\0') {
13867                 if (opt == 'n')
13868                         flag_off = VEXPORT;
13869         }
13870         flag = VEXPORT;
13871         if (argv[0][0] == 'r') {
13872                 flag = VREADONLY;
13873                 flag_off = 0; /* readonly ignores -n */
13874         }
13875         flag_off = ~flag_off;
13876
13877         /*if (opt_p_not_specified) - bash doesn't check this. Try "export -p NAME" */
13878         {
13879                 aptr = argptr;
13880                 name = *aptr;
13881                 if (name) {
13882                         do {
13883                                 p = strchr(name, '=');
13884                                 if (p != NULL) {
13885                                         p++;
13886                                 } else {
13887                                         vp = *findvar(hashvar(name), name);
13888                                         if (vp) {
13889                                                 vp->flags = ((vp->flags | flag) & flag_off);
13890                                                 continue;
13891                                         }
13892                                 }
13893                                 setvar(name, p, (flag & flag_off));
13894                         } while ((name = *++aptr) != NULL);
13895                         return 0;
13896                 }
13897         }
13898
13899         /* No arguments. Show the list of exported or readonly vars.
13900          * -n is ignored.
13901          */
13902         showvars(argv[0], flag, 0);
13903         return 0;
13904 }
13905
13906 /*
13907  * Delete a function if it exists.
13908  */
13909 static void
13910 unsetfunc(const char *name)
13911 {
13912         struct tblentry *cmdp;
13913
13914         cmdp = cmdlookup(name, 0);
13915         if (cmdp != NULL && cmdp->cmdtype == CMDFUNCTION)
13916                 delete_cmd_entry();
13917 }
13918
13919 /*
13920  * The unset builtin command.  We unset the function before we unset the
13921  * variable to allow a function to be unset when there is a readonly variable
13922  * with the same name.
13923  */
13924 static int FAST_FUNC
13925 unsetcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
13926 {
13927         char **ap;
13928         int i;
13929         int flag = 0;
13930
13931         while ((i = nextopt("vf")) != 0) {
13932                 flag = i;
13933         }
13934
13935         for (ap = argptr; *ap; ap++) {
13936                 if (flag != 'f') {
13937                         unsetvar(*ap);
13938                         continue;
13939                 }
13940                 if (flag != 'v')
13941                         unsetfunc(*ap);
13942         }
13943         return 0;
13944 }
13945
13946 static const unsigned char timescmd_str[] ALIGN1 = {
13947         ' ',  offsetof(struct tms, tms_utime),
13948         '\n', offsetof(struct tms, tms_stime),
13949         ' ',  offsetof(struct tms, tms_cutime),
13950         '\n', offsetof(struct tms, tms_cstime),
13951         0
13952 };
13953 static int FAST_FUNC
13954 timescmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
13955 {
13956         unsigned clk_tck;
13957         const unsigned char *p;
13958         struct tms buf;
13959
13960         clk_tck = bb_clk_tck();
13961
13962         times(&buf);
13963         p = timescmd_str;
13964         do {
13965                 unsigned sec, frac;
13966                 unsigned long t;
13967                 t = *(clock_t *)(((char *) &buf) + p[1]);
13968                 sec = t / clk_tck;
13969                 frac = t % clk_tck;
13970                 out1fmt("%um%u.%03us%c",
13971                         sec / 60, sec % 60,
13972                         (frac * 1000) / clk_tck,
13973                         p[0]);
13974                 p += 2;
13975         } while (*p);
13976
13977         return 0;
13978 }
13979
13980 #if ENABLE_FEATURE_SH_MATH
13981 /*
13982  * The let builtin. Partially stolen from GNU Bash, the Bourne Again SHell.
13983  * Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
13984  *
13985  * Copyright (C) 2003 Vladimir Oleynik <dzo@simtreas.ru>
13986  */
13987 static int FAST_FUNC
13988 letcmd(int argc UNUSED_PARAM, char **argv)
13989 {
13990         arith_t i;
13991
13992         argv++;
13993         if (!*argv)
13994                 ash_msg_and_raise_error("expression expected");
13995         do {
13996                 i = ash_arith(*argv);
13997         } while (*++argv);
13998
13999         return !i;
14000 }
14001 #endif
14002
14003 /*
14004  * The read builtin. Options:
14005  *      -r              Do not interpret '\' specially
14006  *      -s              Turn off echo (tty only)
14007  *      -n NCHARS       Read NCHARS max
14008  *      -p PROMPT       Display PROMPT on stderr (if input is from tty)
14009  *      -t SECONDS      Timeout after SECONDS (tty or pipe only)
14010  *      -u FD           Read from given FD instead of fd 0
14011  *      -d DELIM        End on DELIM char, not newline
14012  * This uses unbuffered input, which may be avoidable in some cases.
14013  * TODO: bash also has:
14014  *      -a ARRAY        Read into array[0],[1],etc
14015  *      -e              Use line editing (tty only)
14016  */
14017 static int FAST_FUNC
14018 readcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
14019 {
14020         struct builtin_read_params params;
14021         const char *r;
14022         int i;
14023
14024         memset(&params, 0, sizeof(params));
14025
14026         while ((i = nextopt("p:u:rt:n:sd:")) != '\0') {
14027                 switch (i) {
14028                 case 'p':
14029                         params.opt_p = optionarg;
14030                         break;
14031                 case 'n':
14032                         params.opt_n = optionarg;
14033                         break;
14034                 case 's':
14035                         params.read_flags |= BUILTIN_READ_SILENT;
14036                         break;
14037                 case 't':
14038                         params.opt_t = optionarg;
14039                         break;
14040                 case 'r':
14041                         params.read_flags |= BUILTIN_READ_RAW;
14042                         break;
14043                 case 'u':
14044                         params.opt_u = optionarg;
14045                         break;
14046 #if BASH_READ_D
14047                 case 'd':
14048                         params.opt_d = optionarg;
14049                         break;
14050 #endif
14051                 default:
14052                         break;
14053                 }
14054         }
14055
14056         params.argv = argptr;
14057         params.setvar = setvar0;
14058         params.ifs = bltinlookup("IFS"); /* can be NULL */
14059
14060         /* "read -s" needs to save/restore termios, can't allow ^C
14061          * to jump out of it.
14062          */
14063  again:
14064         INT_OFF;
14065         r = shell_builtin_read(&params);
14066         INT_ON;
14067
14068         if ((uintptr_t)r == 1 && errno == EINTR) {
14069                 /* To get SIGCHLD: sleep 1 & read x; echo $x
14070                  * Correct behavior is to not exit "read"
14071                  */
14072                 if (pending_sig == 0)
14073                         goto again;
14074         }
14075
14076         if ((uintptr_t)r > 1)
14077                 ash_msg_and_raise_error(r);
14078
14079         return (uintptr_t)r;
14080 }
14081
14082 static int FAST_FUNC
14083 umaskcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
14084 {
14085         static const char permuser[3] ALIGN1 = "ogu";
14086
14087         mode_t mask;
14088         int symbolic_mode = 0;
14089
14090         while (nextopt("S") != '\0') {
14091                 symbolic_mode = 1;
14092         }
14093
14094         INT_OFF;
14095         mask = umask(0);
14096         umask(mask);
14097         INT_ON;
14098
14099         if (*argptr == NULL) {
14100                 if (symbolic_mode) {
14101                         char buf[sizeof(",u=rwx,g=rwx,o=rwx")];
14102                         char *p = buf;
14103                         int i;
14104
14105                         i = 2;
14106                         for (;;) {
14107                                 *p++ = ',';
14108                                 *p++ = permuser[i];
14109                                 *p++ = '=';
14110                                 /* mask is 0..0uuugggooo. i=2 selects uuu bits */
14111                                 if (!(mask & 0400)) *p++ = 'r';
14112                                 if (!(mask & 0200)) *p++ = 'w';
14113                                 if (!(mask & 0100)) *p++ = 'x';
14114                                 mask <<= 3;
14115                                 if (--i < 0)
14116                                         break;
14117                         }
14118                         *p = '\0';
14119                         puts(buf + 1);
14120                 } else {
14121                         out1fmt("%04o\n", mask);
14122                 }
14123         } else {
14124                 char *modestr = *argptr;
14125                 /* numeric umasks are taken as-is */
14126                 /* symbolic umasks are inverted: "umask a=rx" calls umask(222) */
14127                 if (!isdigit(modestr[0]))
14128                         mask ^= 0777;
14129                 mask = bb_parse_mode(modestr, mask);
14130                 if ((unsigned)mask > 0777) {
14131                         ash_msg_and_raise_error("illegal mode: %s", modestr);
14132                 }
14133                 if (!isdigit(modestr[0]))
14134                         mask ^= 0777;
14135                 umask(mask);
14136         }
14137         return 0;
14138 }
14139
14140 static int FAST_FUNC
14141 ulimitcmd(int argc UNUSED_PARAM, char **argv)
14142 {
14143         return shell_builtin_ulimit(argv);
14144 }
14145
14146 /* ============ main() and helpers */
14147
14148 /*
14149  * This routine is called when an error or an interrupt occurs in an
14150  * interactive shell and control is returned to the main command loop
14151  * but prior to exitshell.
14152  */
14153 static void
14154 exitreset(void)
14155 {
14156         /* from eval.c: */
14157         if (savestatus >= 0) {
14158                 if (exception_type == EXEXIT || evalskip == SKIPFUNCDEF)
14159                         exitstatus = savestatus;
14160                 savestatus = -1;
14161         }
14162         evalskip = 0;
14163         loopnest = 0;
14164
14165         /* from expand.c: */
14166         ifsfree();
14167
14168         /* from redir.c: */
14169         unwindredir(NULL);
14170 }
14171
14172 /*
14173  * This routine is called when an error or an interrupt occurs in an
14174  * interactive shell and control is returned to the main command loop.
14175  * (In dash, this function is auto-generated by build machinery).
14176  */
14177 static void
14178 reset(void)
14179 {
14180         /* from input.c: */
14181         g_parsefile->left_in_buffer = 0;
14182         g_parsefile->left_in_line = 0;      /* clear input buffer */
14183         popallfiles();
14184
14185         /* from var.c: */
14186         unwindlocalvars(NULL);
14187 }
14188
14189 /*
14190  * Called to exit the shell.
14191  */
14192 static void
14193 exitshell(void)
14194 {
14195         struct jmploc loc;
14196         char *p;
14197
14198 #if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT
14199         if (line_input_state)
14200                 save_history(line_input_state);
14201 #endif
14202         savestatus = exitstatus;
14203         TRACE(("pid %d, exitshell(%d)\n", getpid(), savestatus));
14204         if (setjmp(loc.loc))
14205                 goto out;
14206         exception_handler = &loc;
14207         p = trap[0];
14208         if (p) {
14209                 trap[0] = NULL;
14210                 evalskip = 0;
14211                 evalstring(p, 0);
14212                 evalskip = SKIPFUNCDEF;
14213                 /*free(p); - we'll exit soon */
14214         }
14215  out:
14216         exitreset();
14217         /* dash wraps setjobctl(0) in "if (setjmp(loc.loc) == 0) {...}".
14218          * our setjobctl(0) does not panic if tcsetpgrp fails inside it.
14219          */
14220         setjobctl(0);
14221         flush_stdout_stderr();
14222         _exit(exitstatus);
14223         /* NOTREACHED */
14224 }
14225
14226 /* Don't inline: conserve stack of caller from having our locals too */
14227 static NOINLINE void
14228 init(void)
14229 {
14230         /* we will never free this */
14231         basepf.next_to_pgetc = basepf.buf = ckmalloc(IBUFSIZ);
14232         basepf.linno = 1;
14233
14234         sigmode[SIGCHLD - 1] = S_DFL; /* ensure we install handler even if it is SIG_IGNed */
14235         setsignal(SIGCHLD);
14236
14237         {
14238                 char **envp;
14239                 const char *p;
14240
14241                 initvar();
14242                 for (envp = environ; envp && *envp; envp++) {
14243 /* Used to have
14244  *                      p = endofname(*envp);
14245  *                      if (p != *envp && *p == '=') {
14246  * here to weed out badly-named variables, but this breaks
14247  * scenarios where people do want them passed to children:
14248  * import os
14249  * os.environ["test-test"]="test"
14250  * if os.fork() == 0:
14251  *   os.execv("ash", [ 'ash', '-c', 'eval $(export -p); echo OK' ])  # fixes this
14252  * os.execv("ash", [ 'ash', '-c', 'env | grep test-test' ])  # breaks this
14253  */
14254                         if (strchr(*envp, '=')) {
14255                                 setvareq(*envp, VEXPORT|VTEXTFIXED);
14256                         }
14257                 }
14258
14259                 setvareq((char*)defifsvar, VTEXTFIXED);
14260                 setvareq((char*)defoptindvar, VTEXTFIXED);
14261
14262                 setvar0("PPID", utoa(getppid()));
14263 #if BASH_SHLVL_VAR
14264                 p = lookupvar("SHLVL");
14265                 setvar("SHLVL", utoa((p ? atoi(p) : 0) + 1), VEXPORT);
14266 #endif
14267 #if BASH_HOSTNAME_VAR
14268                 if (!lookupvar("HOSTNAME")) {
14269                         struct utsname uts;
14270                         uname(&uts);
14271                         setvar0("HOSTNAME", uts.nodename);
14272                 }
14273 #endif
14274                 p = lookupvar("PWD");
14275                 if (p) {
14276                         struct stat st1, st2;
14277                         if (p[0] != '/' || stat(p, &st1) || stat(".", &st2)
14278                          || st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino
14279                         ) {
14280                                 p = NULL;
14281                         }
14282                 }
14283                 setpwd(p, 0);
14284         }
14285 }
14286
14287
14288 //usage:#define ash_trivial_usage
14289 //usage:        "[-/+OPTIONS] [-/+o OPT]... [-c 'SCRIPT' [ARG0 [ARGS]] / FILE [ARGS] / -s [ARGS]]"
14290 //usage:#define ash_full_usage "\n\n"
14291 //usage:        "Unix shell interpreter"
14292
14293 /*
14294  * Process the shell command line arguments.
14295  */
14296 static int
14297 procargs(char **argv)
14298 {
14299         int i;
14300         const char *xminusc;
14301         char **xargv;
14302         int login_sh;
14303
14304         xargv = argv;
14305         login_sh = xargv[0] && xargv[0][0] == '-';
14306 #if NUM_SCRIPTS > 0
14307         if (minusc)
14308                 goto setarg0;
14309 #endif
14310         arg0 = xargv[0];
14311         /* if (xargv[0]) - mmm, this is always true! */
14312                 xargv++;
14313         argptr = xargv;
14314         for (i = 0; i < NOPTS; i++)
14315                 optlist[i] = 2;
14316         if (options(&login_sh)) {
14317                 /* it already printed err message */
14318                 raise_exception(EXERROR);
14319         }
14320         xargv = argptr;
14321         xminusc = minusc;
14322         if (*xargv == NULL) {
14323                 if (xminusc)
14324                         ash_msg_and_raise_error(bb_msg_requires_arg, "-c");
14325                 sflag = 1;
14326         }
14327         if (iflag == 2 /* no explicit -i given */
14328          && sflag == 1 /* -s given (or implied) */
14329          && !minusc /* bash compat: ash -sc 'echo $-' is not interactive (dash is) */
14330          && isatty(0) && isatty(1) /* we are on tty */
14331         ) {
14332                 iflag = 1;
14333         }
14334         if (mflag == 2)
14335                 mflag = iflag;
14336         for (i = 0; i < NOPTS; i++)
14337                 if (optlist[i] == 2)
14338                         optlist[i] = 0;
14339 #if DEBUG == 2
14340         debug = 1;
14341 #endif
14342         /* POSIX 1003.2: first arg after "-c CMD" is $0, remainder $1... */
14343         if (xminusc) {
14344                 minusc = *xargv++;
14345                 if (*xargv)
14346                         goto setarg0;
14347         } else if (!sflag) {
14348                 setinputfile(*xargv, 0);
14349  setarg0:
14350                 arg0 = *xargv++;
14351                 commandname = arg0;
14352         }
14353
14354         shellparam.p = xargv;
14355 #if ENABLE_ASH_GETOPTS
14356         shellparam.optind = 1;
14357         shellparam.optoff = -1;
14358 #endif
14359         /* assert(shellparam.malloced == 0 && shellparam.nparam == 0); */
14360         while (*xargv) {
14361                 shellparam.nparam++;
14362                 xargv++;
14363         }
14364         optschanged();
14365
14366         return login_sh;
14367 }
14368
14369 /*
14370  * Read /etc/profile, ~/.profile, $ENV.
14371  */
14372 static void
14373 read_profile(const char *name)
14374 {
14375         name = expandstr(name, DQSYNTAX);
14376         if (setinputfile(name, INPUT_PUSH_FILE | INPUT_NOFILE_OK) < 0)
14377                 return;
14378         cmdloop(0);
14379         popfile();
14380 }
14381
14382 #if PROFILE
14383 static short profile_buf[16384];
14384 extern int etext();
14385 #endif
14386
14387 /*
14388  * Main routine.  We initialize things, parse the arguments, execute
14389  * profiles if we're a login shell, and then call cmdloop to execute
14390  * commands.  The setjmp call sets up the location to jump to when an
14391  * exception occurs.  When an exception occurs the variable "state"
14392  * is used to figure out how far we had gotten.
14393  */
14394 int ash_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
14395 #if NUM_SCRIPTS > 0
14396 int ash_main(int argc, char **argv)
14397 #else
14398 int ash_main(int argc UNUSED_PARAM, char **argv)
14399 #endif
14400 /* note: 'argc' is used only if embedded scripts are enabled */
14401 {
14402         volatile smallint state;
14403         struct jmploc jmploc;
14404         struct stackmark smark;
14405         int login_sh;
14406
14407         /* Initialize global data */
14408         INIT_G_misc();
14409         INIT_G_memstack();
14410         INIT_G_var();
14411 #if ENABLE_ASH_ALIAS
14412         INIT_G_alias();
14413 #endif
14414         INIT_G_cmdtable();
14415
14416 #if PROFILE
14417         monitor(4, etext, profile_buf, sizeof(profile_buf), 50);
14418 #endif
14419
14420         state = 0;
14421         if (setjmp(jmploc.loc)) {
14422                 smallint e;
14423                 smallint s;
14424
14425                 exitreset();
14426
14427                 e = exception_type;
14428                 s = state;
14429                 if (e == EXEND || e == EXEXIT || s == 0 || iflag == 0 || shlvl) {
14430                         exitshell();
14431                 }
14432
14433                 reset();
14434
14435                 if (e == EXINT) {
14436                         newline_and_flush(stderr);
14437                 }
14438
14439                 popstackmark(&smark);
14440                 FORCE_INT_ON; /* enable interrupts */
14441                 if (s == 1)
14442                         goto state1;
14443                 if (s == 2)
14444                         goto state2;
14445                 if (s == 3)
14446                         goto state3;
14447                 goto state4;
14448         }
14449         exception_handler = &jmploc;
14450         rootpid = getpid();
14451
14452         init();
14453         setstackmark(&smark);
14454
14455 #if NUM_SCRIPTS > 0
14456         if (argc < 0)
14457                 /* Non-NULL minusc tells procargs that an embedded script is being run */
14458                 minusc = get_script_content(-argc - 1);
14459 #endif
14460         login_sh = procargs(argv);
14461 #if DEBUG
14462         TRACE(("Shell args: "));
14463         trace_puts_args(argv);
14464 #endif
14465
14466         if (login_sh) {
14467                 const char *hp;
14468
14469                 state = 1;
14470                 read_profile("/etc/profile");
14471  state1:
14472                 state = 2;
14473                 hp = lookupvar("HOME");
14474                 if (hp)
14475                         read_profile("$HOME/.profile");
14476         }
14477  state2:
14478         state = 3;
14479         if (
14480 #ifndef linux
14481          getuid() == geteuid() && getgid() == getegid() &&
14482 #endif
14483          iflag
14484         ) {
14485                 const char *shinit = lookupvar("ENV");
14486                 if (shinit != NULL && *shinit != '\0')
14487                         read_profile(shinit);
14488         }
14489         popstackmark(&smark);
14490  state3:
14491         state = 4;
14492         if (minusc) {
14493                 /* evalstring pushes parsefile stack.
14494                  * Ensure we don't falsely claim that 0 (stdin)
14495                  * is one of stacked source fds.
14496                  * Testcase: ash -c 'exec 1>&0' must not complain. */
14497
14498                 // if (!sflag) g_parsefile->pf_fd = -1;
14499                 // ^^ not necessary since now we special-case fd 0
14500                 // in save_fd_on_redirect()
14501
14502                 // dash: evalstring(minusc, sflag ? 0 : EV_EXIT);
14503                 // The above makes
14504                 //  ash -sc 'echo $-'
14505                 // continue reading input from stdin after running 'echo'.
14506                 // bash does not do this: it prints "hBcs" and exits.
14507                 evalstring(minusc, EV_EXIT);
14508         }
14509
14510         if (sflag || minusc == NULL) {
14511 #if MAX_HISTORY > 0 && ENABLE_FEATURE_EDITING_SAVEHISTORY
14512                 if (iflag) {
14513                         const char *hp = lookupvar("HISTFILE");
14514                         if (!hp) {
14515                                 hp = lookupvar("HOME");
14516                                 if (hp) {
14517                                         INT_OFF;
14518                                         hp = concat_path_file(hp, ".ash_history");
14519                                         setvar0("HISTFILE", hp);
14520                                         free((char*)hp);
14521                                         INT_ON;
14522                                         hp = lookupvar("HISTFILE");
14523                                 }
14524                         }
14525                         if (hp)
14526                                 line_input_state->hist_file = hp;
14527 # if ENABLE_FEATURE_SH_HISTFILESIZE
14528                         hp = lookupvar("HISTFILESIZE");
14529                         line_input_state->max_history = size_from_HISTFILESIZE(hp);
14530 # endif
14531                 }
14532 #endif
14533  state4: /* XXX ??? - why isn't this before the "if" statement */
14534
14535                 /* Interactive bash re-enables SIGHUP which is SIG_IGNed on entry.
14536                  * Try:
14537                  * trap '' hup; bash; echo RET  # type "kill -hup $$", see SIGHUP having effect
14538                  * trap '' hup; bash -c 'kill -hup $$; echo ALIVE'  # here SIGHUP is SIG_IGNed
14539                  */
14540                 signal(SIGHUP, SIG_DFL);
14541
14542                 cmdloop(1);
14543         }
14544 #if PROFILE
14545         monitor(0);
14546 #endif
14547 #ifdef GPROF
14548         {
14549                 extern void _mcleanup(void);
14550                 _mcleanup();
14551         }
14552 #endif
14553         TRACE(("End of main reached\n"));
14554         exitshell();
14555         /* NOTREACHED */
14556 }
14557
14558
14559 /*-
14560  * Copyright (c) 1989, 1991, 1993, 1994
14561  *      The Regents of the University of California.  All rights reserved.
14562  *
14563  * This code is derived from software contributed to Berkeley by
14564  * Kenneth Almquist.
14565  *
14566  * Redistribution and use in source and binary forms, with or without
14567  * modification, are permitted provided that the following conditions
14568  * are met:
14569  * 1. Redistributions of source code must retain the above copyright
14570  *    notice, this list of conditions and the following disclaimer.
14571  * 2. Redistributions in binary form must reproduce the above copyright
14572  *    notice, this list of conditions and the following disclaimer in the
14573  *    documentation and/or other materials provided with the distribution.
14574  * 3. Neither the name of the University nor the names of its contributors
14575  *    may be used to endorse or promote products derived from this software
14576  *    without specific prior written permission.
14577  *
14578  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ''AS IS'' AND
14579  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
14580  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
14581  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
14582  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
14583  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
14584  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
14585  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
14586  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
14587  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
14588  * SUCH DAMAGE.
14589  */