3adb6d0d23f41592a0b9548d5ef9e18ec0389572
[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 (77 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:config ASH_EMBEDDED_SCRIPTS
152 //config:       bool "Embed scripts in the binary"
153 //config:       default y
154 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
155 //config:       help
156 //config:       Allow scripts to be compressed and embedded in the busybox
157 //config:       binary. The scripts should be placed in the 'embed' directory
158 //config:       at build time. Like applets, scripts can be run as
159 //config:       'busybox SCRIPT ...' or by linking their name to the binary.
160 //config:
161 //config:endif # ash options
162
163 //applet:IF_ASH(APPLET(ash, BB_DIR_BIN, BB_SUID_DROP))
164 //                      APPLET_ODDNAME:name  main location    suid_type     help
165 //applet:IF_SH_IS_ASH(  APPLET_ODDNAME(sh,   ash, BB_DIR_BIN, BB_SUID_DROP, ash))
166 //applet:IF_BASH_IS_ASH(APPLET_ODDNAME(bash, ash, BB_DIR_BIN, BB_SUID_DROP, ash))
167
168 //kbuild:lib-$(CONFIG_ASH) += ash.o ash_ptr_hack.o shell_common.o
169 //kbuild:lib-$(CONFIG_SH_IS_ASH) += ash.o ash_ptr_hack.o shell_common.o
170 //kbuild:lib-$(CONFIG_BASH_IS_ASH) += ash.o ash_ptr_hack.o shell_common.o
171 //kbuild:lib-$(CONFIG_ASH_RANDOM_SUPPORT) += random.o
172
173 /*
174  * DEBUG=1 to compile in debugging ('set -o debug' turns on)
175  * DEBUG=2 to compile in and turn on debugging.
176  * When debugging is on ("set -o debug" was executed, or DEBUG=2),
177  * debugging info is written to ./trace, quit signal generates core dump.
178  */
179 #define DEBUG 0
180 /* Tweak debug output verbosity here */
181 #define DEBUG_TIME 0
182 #define DEBUG_PID 1
183 #define DEBUG_SIG 1
184 #define DEBUG_INTONOFF 0
185
186 #define PROFILE 0
187
188 #define JOBS ENABLE_ASH_JOB_CONTROL
189
190 #include <fnmatch.h>
191 #include <sys/times.h>
192 #include <sys/utsname.h> /* for setting $HOSTNAME */
193 #include "busybox.h" /* for applet_names */
194 #if ENABLE_ASH_EMBEDDED_SCRIPTS
195 # include "embedded_scripts.h"
196 #else
197 # define NUM_SCRIPTS 0
198 #endif
199
200 /* So far, all bash compat is controlled by one config option */
201 /* Separate defines document which part of code implements what */
202 /* function keyword */
203 #define    BASH_FUNCTION        ENABLE_ASH_BASH_COMPAT
204 #define IF_BASH_FUNCTION            IF_ASH_BASH_COMPAT
205 /* &>file */
206 #define    BASH_REDIR_OUTPUT    ENABLE_ASH_BASH_COMPAT
207 #define IF_BASH_REDIR_OUTPUT        IF_ASH_BASH_COMPAT
208 /* $'...' */
209 #define    BASH_DOLLAR_SQUOTE   ENABLE_ASH_BASH_COMPAT
210 #define IF_BASH_DOLLAR_SQUOTE       IF_ASH_BASH_COMPAT
211 #define    BASH_PATTERN_SUBST   ENABLE_ASH_BASH_COMPAT
212 #define IF_BASH_PATTERN_SUBST       IF_ASH_BASH_COMPAT
213 #define    BASH_SUBSTR          ENABLE_ASH_BASH_COMPAT
214 #define IF_BASH_SUBSTR              IF_ASH_BASH_COMPAT
215 /* BASH_TEST2: [[ EXPR ]]
216  * Status of [[ support:
217  * We replace && and || with -a and -o
218  * TODO:
219  * singleword+noglob expansion:
220  *   v='a b'; [[ $v = 'a b' ]]; echo 0:$?
221  *   [[ /bin/n* ]]; echo 0:$?
222  * -a/-o are not AND/OR ops! (they are just strings)
223  * quoting needs to be considered (-f is an operator, "-f" and ""-f are not; etc)
224  * = is glob match operator, not equality operator: STR = GLOB
225  * (in GLOB, quoting is significant on char-by-char basis: a*cd"*")
226  * == same as =
227  * add =~ regex match operator: STR =~ REGEX
228  */
229 #define    BASH_TEST2           (ENABLE_ASH_BASH_COMPAT * ENABLE_ASH_TEST)
230 #define    BASH_SOURCE          ENABLE_ASH_BASH_COMPAT
231 #define    BASH_PIPEFAIL        ENABLE_ASH_BASH_COMPAT
232 #define    BASH_HOSTNAME_VAR    ENABLE_ASH_BASH_COMPAT
233 #define    BASH_SHLVL_VAR       ENABLE_ASH_BASH_COMPAT
234 #define    BASH_XTRACEFD        ENABLE_ASH_BASH_COMPAT
235 #define    BASH_READ_D          ENABLE_ASH_BASH_COMPAT
236 #define IF_BASH_READ_D              IF_ASH_BASH_COMPAT
237
238 #if defined(__ANDROID_API__) && __ANDROID_API__ <= 24
239 /* Bionic at least up to version 24 has no glob() */
240 # undef  ENABLE_ASH_INTERNAL_GLOB
241 # define ENABLE_ASH_INTERNAL_GLOB 1
242 #endif
243
244 #if !ENABLE_ASH_INTERNAL_GLOB && defined(__UCLIBC__)
245 # error uClibc glob() is buggy, use ASH_INTERNAL_GLOB.
246 # error The bug is: for "$PWD"/<pattern> ash will escape e.g. dashes in "$PWD"
247 # error with backslash, even ones which do not need to be: "/a-b" -> "/a\-b"
248 # error glob() should unbackslash them and match. uClibc does not unbackslash,
249 # error fails to match dirname, subsequently not expanding <pattern> in it.
250 // Testcase:
251 // if (glob("/etc/polkit\\-1", 0, NULL, &pglob)) - this returns 0 on uclibc, no bug
252 // if (glob("/etc/polkit\\-1/*", 0, NULL, &pglob)) printf("uclibc bug!\n");
253 #endif
254
255 #if !ENABLE_ASH_INTERNAL_GLOB
256 # include <glob.h>
257 #endif
258
259 #include "unicode.h"
260 #include "shell_common.h"
261 #if ENABLE_FEATURE_SH_MATH
262 # include "math.h"
263 #else
264 typedef long arith_t;
265 # define ARITH_FMT "%ld"
266 #endif
267 #if ENABLE_ASH_RANDOM_SUPPORT
268 # include "random.h"
269 #else
270 # define CLEAR_RANDOM_T(rnd) ((void)0)
271 #endif
272
273 #include "NUM_APPLETS.h"
274 #if NUM_APPLETS == 1
275 /* STANDALONE does not make sense, and won't compile */
276 # undef CONFIG_FEATURE_SH_STANDALONE
277 # undef ENABLE_FEATURE_SH_STANDALONE
278 # undef IF_FEATURE_SH_STANDALONE
279 # undef IF_NOT_FEATURE_SH_STANDALONE
280 # define ENABLE_FEATURE_SH_STANDALONE 0
281 # define IF_FEATURE_SH_STANDALONE(...)
282 # define IF_NOT_FEATURE_SH_STANDALONE(...) __VA_ARGS__
283 #endif
284
285 #ifndef F_DUPFD_CLOEXEC
286 # define F_DUPFD_CLOEXEC F_DUPFD
287 #endif
288 #ifndef O_CLOEXEC
289 # define O_CLOEXEC 0
290 #endif
291 #ifndef PIPE_BUF
292 # define PIPE_BUF 4096           /* amount of buffering in a pipe */
293 #endif
294
295 #if !BB_MMU
296 # error "Do not even bother, ash will not run on NOMMU machine"
297 #endif
298
299 /* We use a trick to have more optimized code (fewer pointer reloads):
300  *  ash.c:   extern struct globals *const ash_ptr_to_globals;
301  *  ash_ptr_hack.c: struct globals *ash_ptr_to_globals;
302  * This way, compiler in ash.c knows the pointer can not change.
303  *
304  * However, this may break on weird arches or toolchains. In this case,
305  * set "-DBB_GLOBAL_CONST=''" in CONFIG_EXTRA_CFLAGS to disable
306  * this optimization.
307  */
308 #ifndef BB_GLOBAL_CONST
309 # define BB_GLOBAL_CONST const
310 #endif
311
312
313 /* ============ Hash table sizes. Configurable. */
314
315 #define VTABSIZE 39
316 #define ATABSIZE 39
317 #define CMDTABLESIZE 31         /* should be prime */
318
319
320 /* ============ Shell options */
321
322 static const char *const optletters_optnames[] = {
323         "e"   "errexit",
324         "f"   "noglob",
325         "I"   "ignoreeof",
326         "i"   "interactive",
327         "m"   "monitor",
328         "n"   "noexec",
329         "s"   "stdin",
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
346 #define optletters(n)  optletters_optnames[n][0]
347 #define optnames(n)   (optletters_optnames[n] + 1)
348
349 enum { NOPTS = ARRAY_SIZE(optletters_optnames) };
350
351
352 /* ============ Misc data */
353
354 #define msg_illnum "Illegal number: %s"
355
356 /*
357  * We enclose jmp_buf in a structure so that we can declare pointers to
358  * jump locations.  The global variable handler contains the location to
359  * jump to when an exception occurs, and the global variable exception_type
360  * contains a code identifying the exception.  To implement nested
361  * exception handlers, the user should save the value of handler on entry
362  * to an inner scope, set handler to point to a jmploc structure for the
363  * inner scope, and restore handler on exit from the scope.
364  */
365 struct jmploc {
366         jmp_buf loc;
367 };
368
369 struct globals_misc {
370         uint8_t exitstatus;     /* exit status of last command */
371         uint8_t back_exitstatus;/* exit status of backquoted command */
372         smallint job_warning;   /* user was warned about stopped jobs (can be 2, 1 or 0). */
373         int rootpid;            /* pid of main shell */
374         /* shell level: 0 for the main shell, 1 for its children, and so on */
375         int shlvl;
376 #define rootshell (!shlvl)
377         int errlinno;
378
379         char *minusc;  /* argument to -c option */
380
381         char *curdir; // = nullstr;     /* current working directory */
382         char *physdir; // = nullstr;    /* physical working directory */
383
384         char *arg0; /* value of $0 */
385
386         struct jmploc *exception_handler;
387
388         volatile int suppress_int; /* counter */
389         volatile /*sig_atomic_t*/ smallint pending_int; /* 1 = got SIGINT */
390         volatile /*sig_atomic_t*/ smallint got_sigchld; /* 1 = got SIGCHLD */
391         volatile /*sig_atomic_t*/ smallint pending_sig; /* last pending signal */
392         smallint exception_type; /* kind of exception (0..5) */
393         /* exceptions */
394 #define EXINT 0         /* SIGINT received */
395 #define EXERROR 1       /* a generic error */
396 #define EXEXIT 4        /* exit the shell */
397
398         char nullstr[1];        /* zero length string */
399
400         char optlist[NOPTS];
401 #define eflag optlist[0]
402 #define fflag optlist[1]
403 #define Iflag optlist[2]
404 #define iflag optlist[3]
405 #define mflag optlist[4]
406 #define nflag optlist[5]
407 #define sflag optlist[6]
408 #define xflag optlist[7]
409 #define vflag optlist[8]
410 #define Cflag optlist[9]
411 #define aflag optlist[10]
412 #define bflag optlist[11]
413 #define uflag optlist[12]
414 #define viflag optlist[13]
415 #if BASH_PIPEFAIL
416 # define pipefail optlist[14]
417 #else
418 # define pipefail 0
419 #endif
420 #if DEBUG
421 # define nolog optlist[14 + BASH_PIPEFAIL]
422 # define debug optlist[15 + BASH_PIPEFAIL]
423 #endif
424
425         /* trap handler commands */
426         /*
427          * Sigmode records the current value of the signal handlers for the various
428          * modes.  A value of zero means that the current handler is not known.
429          * S_HARD_IGN indicates that the signal was ignored on entry to the shell.
430          */
431         char sigmode[NSIG - 1];
432 #define S_DFL      1            /* default signal handling (SIG_DFL) */
433 #define S_CATCH    2            /* signal is caught */
434 #define S_IGN      3            /* signal is ignored (SIG_IGN) */
435 #define S_HARD_IGN 4            /* signal is ignored permanently (it was SIG_IGN on entry to shell) */
436
437         /* indicates specified signal received */
438         uint8_t gotsig[NSIG - 1]; /* offset by 1: "signal" 0 is meaningless */
439         uint8_t may_have_traps; /* 0: definitely no traps are set, 1: some traps may be set */
440         char *trap[NSIG];
441         char **trap_ptr;        /* used only by "trap hack" */
442
443         /* Rarely referenced stuff */
444 #if ENABLE_ASH_RANDOM_SUPPORT
445         random_t random_gen;
446 #endif
447         pid_t backgndpid;        /* pid of last background process */
448 };
449 extern struct globals_misc *BB_GLOBAL_CONST ash_ptr_to_globals_misc;
450 #define G_misc (*ash_ptr_to_globals_misc)
451 #define exitstatus        (G_misc.exitstatus )
452 #define back_exitstatus   (G_misc.back_exitstatus )
453 #define job_warning       (G_misc.job_warning)
454 #define rootpid     (G_misc.rootpid    )
455 #define shlvl       (G_misc.shlvl      )
456 #define errlinno    (G_misc.errlinno   )
457 #define minusc      (G_misc.minusc     )
458 #define curdir      (G_misc.curdir     )
459 #define physdir     (G_misc.physdir    )
460 #define arg0        (G_misc.arg0       )
461 #define exception_handler (G_misc.exception_handler)
462 #define exception_type    (G_misc.exception_type   )
463 #define suppress_int      (G_misc.suppress_int     )
464 #define pending_int       (G_misc.pending_int      )
465 #define got_sigchld       (G_misc.got_sigchld      )
466 #define pending_sig       (G_misc.pending_sig      )
467 #define nullstr     (G_misc.nullstr    )
468 #define optlist     (G_misc.optlist    )
469 #define sigmode     (G_misc.sigmode    )
470 #define gotsig      (G_misc.gotsig     )
471 #define may_have_traps    (G_misc.may_have_traps   )
472 #define trap        (G_misc.trap       )
473 #define trap_ptr    (G_misc.trap_ptr   )
474 #define random_gen  (G_misc.random_gen )
475 #define backgndpid  (G_misc.backgndpid )
476 #define INIT_G_misc() do { \
477         (*(struct globals_misc**)&ash_ptr_to_globals_misc) = xzalloc(sizeof(G_misc)); \
478         barrier(); \
479         curdir = nullstr; \
480         physdir = nullstr; \
481         trap_ptr = trap; \
482 } while (0)
483
484
485 /* ============ DEBUG */
486 #if DEBUG
487 static void trace_printf(const char *fmt, ...);
488 static void trace_vprintf(const char *fmt, va_list va);
489 # define TRACE(param)    trace_printf param
490 # define TRACEV(param)   trace_vprintf param
491 # define close(fd) do { \
492         int dfd = (fd); \
493         if (close(dfd) < 0) \
494                 bb_error_msg("bug on %d: closing %d(0x%x)", \
495                         __LINE__, dfd, dfd); \
496 } while (0)
497 #else
498 # define TRACE(param)
499 # define TRACEV(param)
500 #endif
501
502
503 /* ============ Utility functions */
504 #define is_name(c)      ((c) == '_' || isalpha((unsigned char)(c)))
505 #define is_in_name(c)   ((c) == '_' || isalnum((unsigned char)(c)))
506
507 static int
508 isdigit_str9(const char *str)
509 {
510         int maxlen = 9 + 1; /* max 9 digits: 999999999 */
511         while (--maxlen && isdigit(*str))
512                 str++;
513         return (*str == '\0');
514 }
515
516 static const char *
517 var_end(const char *var)
518 {
519         while (*var)
520                 if (*var++ == '=')
521                         break;
522         return var;
523 }
524
525
526 /* ============ Interrupts / exceptions */
527
528 static void exitshell(void) NORETURN;
529
530 /*
531  * These macros allow the user to suspend the handling of interrupt signals
532  * over a period of time.  This is similar to SIGHOLD or to sigblock, but
533  * much more efficient and portable.  (But hacking the kernel is so much
534  * more fun than worrying about efficiency and portability. :-))
535  */
536 #if DEBUG_INTONOFF
537 # define INT_OFF do { \
538         TRACE(("%s:%d INT_OFF(%d)\n", __func__, __LINE__, suppress_int)); \
539         suppress_int++; \
540         barrier(); \
541 } while (0)
542 #else
543 # define INT_OFF do { \
544         suppress_int++; \
545         barrier(); \
546 } while (0)
547 #endif
548
549 /*
550  * Called to raise an exception.  Since C doesn't include exceptions, we
551  * just do a longjmp to the exception handler.  The type of exception is
552  * stored in the global variable "exception_type".
553  */
554 static void raise_exception(int) NORETURN;
555 static void
556 raise_exception(int e)
557 {
558 #if DEBUG
559         if (exception_handler == NULL)
560                 abort();
561 #endif
562         INT_OFF;
563         exception_type = e;
564         longjmp(exception_handler->loc, 1);
565 }
566 #if DEBUG
567 #define raise_exception(e) do { \
568         TRACE(("raising exception %d on line %d\n", (e), __LINE__)); \
569         raise_exception(e); \
570 } while (0)
571 #endif
572
573 /*
574  * Called when a SIGINT is received.  (If the user specifies
575  * that SIGINT is to be trapped or ignored using the trap builtin, then
576  * this routine is not called.)  Suppressint is nonzero when interrupts
577  * are held using the INT_OFF macro.  (The test for iflag is just
578  * defensive programming.)
579  */
580 static void raise_interrupt(void) NORETURN;
581 static void
582 raise_interrupt(void)
583 {
584         pending_int = 0;
585         /* Signal is not automatically unmasked after it is raised,
586          * do it ourself - unmask all signals */
587         sigprocmask_allsigs(SIG_UNBLOCK);
588         /* pending_sig = 0; - now done in signal_handler() */
589
590         if (!(rootshell && iflag)) {
591                 /* Kill ourself with SIGINT */
592                 signal(SIGINT, SIG_DFL);
593                 raise(SIGINT);
594         }
595         /* bash: ^C even on empty command line sets $? */
596         exitstatus = SIGINT + 128;
597         raise_exception(EXINT);
598         /* NOTREACHED */
599 }
600 #if DEBUG
601 #define raise_interrupt() do { \
602         TRACE(("raising interrupt on line %d\n", __LINE__)); \
603         raise_interrupt(); \
604 } while (0)
605 #endif
606
607 static IF_ASH_OPTIMIZE_FOR_SIZE(inline) void
608 int_on(void)
609 {
610         barrier();
611         if (--suppress_int == 0 && pending_int) {
612                 raise_interrupt();
613         }
614 }
615 #if DEBUG_INTONOFF
616 # define INT_ON do { \
617         TRACE(("%s:%d INT_ON(%d)\n", __func__, __LINE__, suppress_int-1)); \
618         int_on(); \
619 } while (0)
620 #else
621 # define INT_ON int_on()
622 #endif
623 static IF_ASH_OPTIMIZE_FOR_SIZE(inline) void
624 force_int_on(void)
625 {
626         barrier();
627         suppress_int = 0;
628         if (pending_int)
629                 raise_interrupt();
630 }
631 #define FORCE_INT_ON force_int_on()
632
633 #define SAVE_INT(v) ((v) = suppress_int)
634
635 #define RESTORE_INT(v) do { \
636         barrier(); \
637         suppress_int = (v); \
638         if (suppress_int == 0 && pending_int) \
639                 raise_interrupt(); \
640 } while (0)
641
642
643 /* ============ Stdout/stderr output */
644
645 static void
646 outstr(const char *p, FILE *file)
647 {
648         INT_OFF;
649         fputs(p, file);
650         INT_ON;
651 }
652
653 static void
654 flush_stdout_stderr(void)
655 {
656         INT_OFF;
657         fflush_all();
658         INT_ON;
659 }
660
661 /* Was called outcslow(c,FILE*), but c was always '\n' */
662 static void
663 newline_and_flush(FILE *dest)
664 {
665         INT_OFF;
666         putc('\n', dest);
667         fflush(dest);
668         INT_ON;
669 }
670
671 static int out1fmt(const char *, ...) __attribute__((__format__(__printf__,1,2)));
672 static int
673 out1fmt(const char *fmt, ...)
674 {
675         va_list ap;
676         int r;
677
678         INT_OFF;
679         va_start(ap, fmt);
680         r = vprintf(fmt, ap);
681         va_end(ap);
682         INT_ON;
683         return r;
684 }
685
686 static int fmtstr(char *, size_t, const char *, ...) __attribute__((__format__(__printf__,3,4)));
687 static int
688 fmtstr(char *outbuf, size_t length, const char *fmt, ...)
689 {
690         va_list ap;
691         int ret;
692
693         INT_OFF;
694         va_start(ap, fmt);
695         ret = vsnprintf(outbuf, length, fmt, ap);
696         va_end(ap);
697         INT_ON;
698         return ret;
699 }
700
701 static void
702 out1str(const char *p)
703 {
704         outstr(p, stdout);
705 }
706
707 static void
708 out2str(const char *p)
709 {
710         outstr(p, stderr);
711         flush_stdout_stderr();
712 }
713
714
715 /* ============ Parser structures */
716
717 /* control characters in argument strings */
718 #define CTL_FIRST CTLESC
719 #define CTLESC       ((unsigned char)'\201')    /* escape next character */
720 #define CTLVAR       ((unsigned char)'\202')    /* variable defn */
721 #define CTLENDVAR    ((unsigned char)'\203')
722 #define CTLBACKQ     ((unsigned char)'\204')
723 #define CTLARI       ((unsigned char)'\206')    /* arithmetic expression */
724 #define CTLENDARI    ((unsigned char)'\207')
725 #define CTLQUOTEMARK ((unsigned char)'\210')
726 #define CTL_LAST CTLQUOTEMARK
727
728 /* variable substitution byte (follows CTLVAR) */
729 #define VSTYPE  0x0f            /* type of variable substitution */
730 #define VSNUL   0x10            /* colon--treat the empty string as unset */
731
732 /* values of VSTYPE field */
733 #define VSNORMAL        0x1     /* normal variable:  $var or ${var} */
734 #define VSMINUS         0x2     /* ${var-text} */
735 #define VSPLUS          0x3     /* ${var+text} */
736 #define VSQUESTION      0x4     /* ${var?message} */
737 #define VSASSIGN        0x5     /* ${var=text} */
738 #define VSTRIMRIGHT     0x6     /* ${var%pattern} */
739 #define VSTRIMRIGHTMAX  0x7     /* ${var%%pattern} */
740 #define VSTRIMLEFT      0x8     /* ${var#pattern} */
741 #define VSTRIMLEFTMAX   0x9     /* ${var##pattern} */
742 #define VSLENGTH        0xa     /* ${#var} */
743 #if BASH_SUBSTR
744 #define VSSUBSTR        0xc     /* ${var:position:length} */
745 #endif
746 #if BASH_PATTERN_SUBST
747 #define VSREPLACE       0xd     /* ${var/pattern/replacement} */
748 #define VSREPLACEALL    0xe     /* ${var//pattern/replacement} */
749 #endif
750
751 static const char dolatstr[] ALIGN1 = {
752         CTLQUOTEMARK, CTLVAR, VSNORMAL, '@', '=', CTLQUOTEMARK, '\0'
753 };
754 #define DOLATSTRLEN 6
755
756 #define NCMD      0
757 #define NPIPE     1
758 #define NREDIR    2
759 #define NBACKGND  3
760 #define NSUBSHELL 4
761 #define NAND      5
762 #define NOR       6
763 #define NSEMI     7
764 #define NIF       8
765 #define NWHILE    9
766 #define NUNTIL   10
767 #define NFOR     11
768 #define NCASE    12
769 #define NCLIST   13
770 #define NDEFUN   14
771 #define NARG     15
772 #define NTO      16
773 #if BASH_REDIR_OUTPUT
774 #define NTO2     17
775 #endif
776 #define NCLOBBER 18
777 #define NFROM    19
778 #define NFROMTO  20
779 #define NAPPEND  21
780 #define NTOFD    22
781 #define NFROMFD  23
782 #define NHERE    24
783 #define NXHERE   25
784 #define NNOT     26
785 #define N_NUMBER 27
786
787 union node;
788
789 struct ncmd {
790         smallint type; /* Nxxxx */
791         int linno;
792         union node *assign;
793         union node *args;
794         union node *redirect;
795 };
796
797 struct npipe {
798         smallint type;
799         smallint pipe_backgnd;
800         struct nodelist *cmdlist;
801 };
802
803 struct nredir {
804         smallint type;
805         int linno;
806         union node *n;
807         union node *redirect;
808 };
809
810 struct nbinary {
811         smallint type;
812         union node *ch1;
813         union node *ch2;
814 };
815
816 struct nif {
817         smallint type;
818         union node *test;
819         union node *ifpart;
820         union node *elsepart;
821 };
822
823 struct nfor {
824         smallint type;
825         int linno;
826         union node *args;
827         union node *body;
828         char *var;
829 };
830
831 struct ncase {
832         smallint type;
833         int linno;
834         union node *expr;
835         union node *cases;
836 };
837
838 struct nclist {
839         smallint type;
840         union node *next;
841         union node *pattern;
842         union node *body;
843 };
844
845 struct ndefun {
846         smallint type;
847         int linno;
848         char *text;
849         union node *body;
850 };
851
852 struct narg {
853         smallint type;
854         union node *next;
855         char *text;
856         struct nodelist *backquote;
857 };
858
859 /* nfile and ndup layout must match!
860  * NTOFD (>&fdnum) uses ndup structure, but we may discover mid-flight
861  * that it is actually NTO2 (>&file), and change its type.
862  */
863 struct nfile {
864         smallint type;
865         union node *next;
866         int fd;
867         int _unused_dupfd;
868         union node *fname;
869         char *expfname;
870 };
871
872 struct ndup {
873         smallint type;
874         union node *next;
875         int fd;
876         int dupfd;
877         union node *vname;
878         char *_unused_expfname;
879 };
880
881 struct nhere {
882         smallint type;
883         union node *next;
884         int fd;
885         union node *doc;
886 };
887
888 struct nnot {
889         smallint type;
890         union node *com;
891 };
892
893 union node {
894         smallint type;
895         struct ncmd ncmd;
896         struct npipe npipe;
897         struct nredir nredir;
898         struct nbinary nbinary;
899         struct nif nif;
900         struct nfor nfor;
901         struct ncase ncase;
902         struct nclist nclist;
903         struct ndefun ndefun;
904         struct narg narg;
905         struct nfile nfile;
906         struct ndup ndup;
907         struct nhere nhere;
908         struct nnot nnot;
909 };
910
911 /*
912  * NODE_EOF is returned by parsecmd when it encounters an end of file.
913  * It must be distinct from NULL.
914  */
915 #define NODE_EOF ((union node *) -1L)
916
917 struct nodelist {
918         struct nodelist *next;
919         union node *n;
920 };
921
922 struct funcnode {
923         int count;
924         union node n;
925 };
926
927 /*
928  * Free a parse tree.
929  */
930 static void
931 freefunc(struct funcnode *f)
932 {
933         if (f && --f->count < 0)
934                 free(f);
935 }
936
937
938 /* ============ Debugging output */
939
940 #if DEBUG
941
942 static FILE *tracefile;
943
944 static void
945 trace_printf(const char *fmt, ...)
946 {
947         va_list va;
948
949         if (debug != 1)
950                 return;
951         if (DEBUG_TIME)
952                 fprintf(tracefile, "%u ", (int) time(NULL));
953         if (DEBUG_PID)
954                 fprintf(tracefile, "[%u] ", (int) getpid());
955         if (DEBUG_SIG)
956                 fprintf(tracefile, "pending s:%d i:%d(supp:%d) ", pending_sig, pending_int, suppress_int);
957         va_start(va, fmt);
958         vfprintf(tracefile, fmt, va);
959         va_end(va);
960 }
961
962 static void
963 trace_vprintf(const char *fmt, va_list va)
964 {
965         if (debug != 1)
966                 return;
967         vfprintf(tracefile, fmt, va);
968         fprintf(tracefile, "\n");
969 }
970
971 static void
972 trace_puts(const char *s)
973 {
974         if (debug != 1)
975                 return;
976         fputs(s, tracefile);
977 }
978
979 static void
980 trace_puts_quoted(char *s)
981 {
982         char *p;
983         char c;
984
985         if (debug != 1)
986                 return;
987         putc('"', tracefile);
988         for (p = s; *p; p++) {
989                 switch ((unsigned char)*p) {
990                 case '\n': c = 'n'; goto backslash;
991                 case '\t': c = 't'; goto backslash;
992                 case '\r': c = 'r'; goto backslash;
993                 case '\"': c = '\"'; goto backslash;
994                 case '\\': c = '\\'; goto backslash;
995                 case CTLESC: c = 'e'; goto backslash;
996                 case CTLVAR: c = 'v'; goto backslash;
997                 case CTLBACKQ: c = 'q'; goto backslash;
998  backslash:
999                         putc('\\', tracefile);
1000                         putc(c, tracefile);
1001                         break;
1002                 default:
1003                         if (*p >= ' ' && *p <= '~')
1004                                 putc(*p, tracefile);
1005                         else {
1006                                 putc('\\', tracefile);
1007                                 putc((*p >> 6) & 03, tracefile);
1008                                 putc((*p >> 3) & 07, tracefile);
1009                                 putc(*p & 07, tracefile);
1010                         }
1011                         break;
1012                 }
1013         }
1014         putc('"', tracefile);
1015 }
1016
1017 static void
1018 trace_puts_args(char **ap)
1019 {
1020         if (debug != 1)
1021                 return;
1022         if (!*ap)
1023                 return;
1024         while (1) {
1025                 trace_puts_quoted(*ap);
1026                 if (!*++ap) {
1027                         putc('\n', tracefile);
1028                         break;
1029                 }
1030                 putc(' ', tracefile);
1031         }
1032 }
1033
1034 static void
1035 opentrace(void)
1036 {
1037         char s[100];
1038 #ifdef O_APPEND
1039         int flags;
1040 #endif
1041
1042         if (debug != 1) {
1043                 if (tracefile)
1044                         fflush(tracefile);
1045                 /* leave open because libedit might be using it */
1046                 return;
1047         }
1048         strcpy(s, "./trace");
1049         if (tracefile) {
1050                 if (!freopen(s, "a", tracefile)) {
1051                         fprintf(stderr, "Can't re-open %s\n", s);
1052                         debug = 0;
1053                         return;
1054                 }
1055         } else {
1056                 tracefile = fopen(s, "a");
1057                 if (tracefile == NULL) {
1058                         fprintf(stderr, "Can't open %s\n", s);
1059                         debug = 0;
1060                         return;
1061                 }
1062         }
1063 #ifdef O_APPEND
1064         flags = fcntl(fileno(tracefile), F_GETFL);
1065         if (flags >= 0)
1066                 fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND);
1067 #endif
1068         setlinebuf(tracefile);
1069         fputs("\nTracing started.\n", tracefile);
1070 }
1071
1072 static void
1073 indent(int amount, char *pfx, FILE *fp)
1074 {
1075         int i;
1076
1077         for (i = 0; i < amount; i++) {
1078                 if (pfx && i == amount - 1)
1079                         fputs(pfx, fp);
1080                 putc('\t', fp);
1081         }
1082 }
1083
1084 /* little circular references here... */
1085 static void shtree(union node *n, int ind, char *pfx, FILE *fp);
1086
1087 static void
1088 sharg(union node *arg, FILE *fp)
1089 {
1090         char *p;
1091         struct nodelist *bqlist;
1092         unsigned char subtype;
1093
1094         if (arg->type != NARG) {
1095                 out1fmt("<node type %d>\n", arg->type);
1096                 abort();
1097         }
1098         bqlist = arg->narg.backquote;
1099         for (p = arg->narg.text; *p; p++) {
1100                 switch ((unsigned char)*p) {
1101                 case CTLESC:
1102                         p++;
1103                         putc(*p, fp);
1104                         break;
1105                 case CTLVAR:
1106                         putc('$', fp);
1107                         putc('{', fp);
1108                         subtype = *++p;
1109                         if (subtype == VSLENGTH)
1110                                 putc('#', fp);
1111
1112                         while (*p != '=') {
1113                                 putc(*p, fp);
1114                                 p++;
1115                         }
1116
1117                         if (subtype & VSNUL)
1118                                 putc(':', fp);
1119
1120                         switch (subtype & VSTYPE) {
1121                         case VSNORMAL:
1122                                 putc('}', fp);
1123                                 break;
1124                         case VSMINUS:
1125                                 putc('-', fp);
1126                                 break;
1127                         case VSPLUS:
1128                                 putc('+', fp);
1129                                 break;
1130                         case VSQUESTION:
1131                                 putc('?', fp);
1132                                 break;
1133                         case VSASSIGN:
1134                                 putc('=', fp);
1135                                 break;
1136                         case VSTRIMLEFT:
1137                                 putc('#', fp);
1138                                 break;
1139                         case VSTRIMLEFTMAX:
1140                                 putc('#', fp);
1141                                 putc('#', fp);
1142                                 break;
1143                         case VSTRIMRIGHT:
1144                                 putc('%', fp);
1145                                 break;
1146                         case VSTRIMRIGHTMAX:
1147                                 putc('%', fp);
1148                                 putc('%', fp);
1149                                 break;
1150                         case VSLENGTH:
1151                                 break;
1152                         default:
1153                                 out1fmt("<subtype %d>", subtype);
1154                         }
1155                         break;
1156                 case CTLENDVAR:
1157                         putc('}', fp);
1158                         break;
1159                 case CTLBACKQ:
1160                         putc('$', fp);
1161                         putc('(', fp);
1162                         shtree(bqlist->n, -1, NULL, fp);
1163                         putc(')', fp);
1164                         break;
1165                 default:
1166                         putc(*p, fp);
1167                         break;
1168                 }
1169         }
1170 }
1171
1172 static void
1173 shcmd(union node *cmd, FILE *fp)
1174 {
1175         union node *np;
1176         int first;
1177         const char *s;
1178         int dftfd;
1179
1180         first = 1;
1181         for (np = cmd->ncmd.args; np; np = np->narg.next) {
1182                 if (!first)
1183                         putc(' ', fp);
1184                 sharg(np, fp);
1185                 first = 0;
1186         }
1187         for (np = cmd->ncmd.redirect; np; np = np->nfile.next) {
1188                 if (!first)
1189                         putc(' ', fp);
1190                 dftfd = 0;
1191                 switch (np->nfile.type) {
1192                 case NTO:      s = ">>"+1; dftfd = 1; break;
1193                 case NCLOBBER: s = ">|"; dftfd = 1; break;
1194                 case NAPPEND:  s = ">>"; dftfd = 1; break;
1195 #if BASH_REDIR_OUTPUT
1196                 case NTO2:
1197 #endif
1198                 case NTOFD:    s = ">&"; dftfd = 1; break;
1199                 case NFROM:    s = "<"; break;
1200                 case NFROMFD:  s = "<&"; break;
1201                 case NFROMTO:  s = "<>"; break;
1202                 default:       s = "*error*"; break;
1203                 }
1204                 if (np->nfile.fd != dftfd)
1205                         fprintf(fp, "%d", np->nfile.fd);
1206                 fputs(s, fp);
1207                 if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) {
1208                         fprintf(fp, "%d", np->ndup.dupfd);
1209                 } else {
1210                         sharg(np->nfile.fname, fp);
1211                 }
1212                 first = 0;
1213         }
1214 }
1215
1216 static void
1217 shtree(union node *n, int ind, char *pfx, FILE *fp)
1218 {
1219         struct nodelist *lp;
1220         const char *s;
1221
1222         if (n == NULL)
1223                 return;
1224
1225         indent(ind, pfx, fp);
1226
1227         if (n == NODE_EOF) {
1228                 fputs("<EOF>", fp);
1229                 return;
1230         }
1231
1232         switch (n->type) {
1233         case NSEMI:
1234                 s = "; ";
1235                 goto binop;
1236         case NAND:
1237                 s = " && ";
1238                 goto binop;
1239         case NOR:
1240                 s = " || ";
1241  binop:
1242                 shtree(n->nbinary.ch1, ind, NULL, fp);
1243                 /* if (ind < 0) */
1244                         fputs(s, fp);
1245                 shtree(n->nbinary.ch2, ind, NULL, fp);
1246                 break;
1247         case NCMD:
1248                 shcmd(n, fp);
1249                 if (ind >= 0)
1250                         putc('\n', fp);
1251                 break;
1252         case NPIPE:
1253                 for (lp = n->npipe.cmdlist; lp; lp = lp->next) {
1254                         shtree(lp->n, 0, NULL, fp);
1255                         if (lp->next)
1256                                 fputs(" | ", fp);
1257                 }
1258                 if (n->npipe.pipe_backgnd)
1259                         fputs(" &", fp);
1260                 if (ind >= 0)
1261                         putc('\n', fp);
1262                 break;
1263         default:
1264                 fprintf(fp, "<node type %d>", n->type);
1265                 if (ind >= 0)
1266                         putc('\n', fp);
1267                 break;
1268         }
1269 }
1270
1271 static void
1272 showtree(union node *n)
1273 {
1274         trace_puts("showtree called\n");
1275         shtree(n, 1, NULL, stderr);
1276 }
1277
1278 #endif /* DEBUG */
1279
1280
1281 /* ============ Parser data */
1282
1283 /*
1284  * ash_vmsg() needs parsefile->fd, hence parsefile definition is moved up.
1285  */
1286 struct strlist {
1287         struct strlist *next;
1288         char *text;
1289 };
1290
1291 struct alias;
1292
1293 struct strpush {
1294         struct strpush *prev;   /* preceding string on stack */
1295         char *prev_string;
1296         int prev_left_in_line;
1297 #if ENABLE_ASH_ALIAS
1298         struct alias *ap;       /* if push was associated with an alias */
1299 #endif
1300         char *string;           /* remember the string since it may change */
1301
1302         /* Remember last two characters for pungetc. */
1303         int lastc[2];
1304
1305         /* Number of outstanding calls to pungetc. */
1306         int unget;
1307 };
1308
1309 /*
1310  * The parsefile structure pointed to by the global variable parsefile
1311  * contains information about the current file being read.
1312  */
1313 struct parsefile {
1314         struct parsefile *prev; /* preceding file on stack */
1315         int linno;              /* current line */
1316         int pf_fd;              /* file descriptor (or -1 if string) */
1317         int left_in_line;       /* number of chars left in this line */
1318         int left_in_buffer;     /* number of chars left in this buffer past the line */
1319         char *next_to_pgetc;    /* next char in buffer */
1320         char *buf;              /* input buffer */
1321         struct strpush *strpush; /* for pushing strings at this level */
1322         struct strpush basestrpush; /* so pushing one is fast */
1323
1324         /* Remember last two characters for pungetc. */
1325         int lastc[2];
1326
1327         /* Number of outstanding calls to pungetc. */
1328         int unget;
1329 };
1330
1331 static struct parsefile basepf;        /* top level input file */
1332 static struct parsefile *g_parsefile = &basepf;  /* current input file */
1333 static char *commandname;              /* currently executing command */
1334
1335
1336 /* ============ Message printing */
1337
1338 static void
1339 ash_vmsg(const char *msg, va_list ap)
1340 {
1341         fprintf(stderr, "%s: ", arg0);
1342         if (commandname) {
1343                 if (strcmp(arg0, commandname))
1344                         fprintf(stderr, "%s: ", commandname);
1345                 if (!iflag || g_parsefile->pf_fd > 0)
1346                         fprintf(stderr, "line %d: ", errlinno);
1347         }
1348         vfprintf(stderr, msg, ap);
1349         newline_and_flush(stderr);
1350 }
1351
1352 /*
1353  * Exverror is called to raise the error exception.  If the second argument
1354  * is not NULL then error prints an error message using printf style
1355  * formatting.  It then raises the error exception.
1356  */
1357 static void ash_vmsg_and_raise(int, const char *, va_list) NORETURN;
1358 static void
1359 ash_vmsg_and_raise(int cond, const char *msg, va_list ap)
1360 {
1361 #if DEBUG
1362         if (msg) {
1363                 TRACE(("ash_vmsg_and_raise(%d):", cond));
1364                 TRACEV((msg, ap));
1365         } else
1366                 TRACE(("ash_vmsg_and_raise(%d):NULL\n", cond));
1367         if (msg)
1368 #endif
1369                 ash_vmsg(msg, ap);
1370
1371         flush_stdout_stderr();
1372         raise_exception(cond);
1373         /* NOTREACHED */
1374 }
1375
1376 static void ash_msg_and_raise_error(const char *, ...) NORETURN;
1377 static void
1378 ash_msg_and_raise_error(const char *msg, ...)
1379 {
1380         va_list ap;
1381
1382         exitstatus = 2;
1383
1384         va_start(ap, msg);
1385         ash_vmsg_and_raise(EXERROR, msg, ap);
1386         /* NOTREACHED */
1387         va_end(ap);
1388 }
1389
1390 /*
1391  * 'fmt' must be a string literal.
1392  */
1393 #define ash_msg_and_raise_perror(fmt, ...) ash_msg_and_raise_error(fmt ": "STRERROR_FMT, ##__VA_ARGS__ STRERROR_ERRNO)
1394
1395 static void raise_error_syntax(const char *) NORETURN;
1396 static void
1397 raise_error_syntax(const char *msg)
1398 {
1399         errlinno = g_parsefile->linno;
1400         ash_msg_and_raise_error("syntax error: %s", msg);
1401         /* NOTREACHED */
1402 }
1403
1404 static void ash_msg_and_raise(int, const char *, ...) NORETURN;
1405 static void
1406 ash_msg_and_raise(int cond, const char *msg, ...)
1407 {
1408         va_list ap;
1409
1410         va_start(ap, msg);
1411         ash_vmsg_and_raise(cond, msg, ap);
1412         /* NOTREACHED */
1413         va_end(ap);
1414 }
1415
1416 /*
1417  * error/warning routines for external builtins
1418  */
1419 static void
1420 ash_msg(const char *fmt, ...)
1421 {
1422         va_list ap;
1423
1424         va_start(ap, fmt);
1425         ash_vmsg(fmt, ap);
1426         va_end(ap);
1427 }
1428
1429 /*
1430  * Return a string describing an error.  The returned string may be a
1431  * pointer to a static buffer that will be overwritten on the next call.
1432  * Action describes the operation that got the error.
1433  */
1434 static const char *
1435 errmsg(int e, const char *em)
1436 {
1437         if (e == ENOENT || e == ENOTDIR) {
1438                 return em;
1439         }
1440         return strerror(e);
1441 }
1442
1443
1444 /* ============ Memory allocation */
1445
1446 #if 0
1447 /* I consider these wrappers nearly useless:
1448  * ok, they return you to nearest exception handler, but
1449  * how much memory do you leak in the process, making
1450  * memory starvation worse?
1451  */
1452 static void *
1453 ckrealloc(void * p, size_t nbytes)
1454 {
1455         p = realloc(p, nbytes);
1456         if (!p)
1457                 ash_msg_and_raise_error(bb_msg_memory_exhausted);
1458         return p;
1459 }
1460
1461 static void *
1462 ckmalloc(size_t nbytes)
1463 {
1464         return ckrealloc(NULL, nbytes);
1465 }
1466
1467 static void *
1468 ckzalloc(size_t nbytes)
1469 {
1470         return memset(ckmalloc(nbytes), 0, nbytes);
1471 }
1472
1473 static char *
1474 ckstrdup(const char *s)
1475 {
1476         char *p = strdup(s);
1477         if (!p)
1478                 ash_msg_and_raise_error(bb_msg_memory_exhausted);
1479         return p;
1480 }
1481 #else
1482 /* Using bbox equivalents. They exit if out of memory */
1483 # define ckrealloc xrealloc
1484 # define ckmalloc  xmalloc
1485 # define ckzalloc  xzalloc
1486 # define ckstrdup  xstrdup
1487 #endif
1488
1489 /*
1490  * It appears that grabstackstr() will barf with such alignments
1491  * because stalloc() will return a string allocated in a new stackblock.
1492  */
1493 #define SHELL_ALIGN(nbytes) (((nbytes) + SHELL_SIZE) & ~SHELL_SIZE)
1494 enum {
1495         /* Most machines require the value returned from malloc to be aligned
1496          * in some way.  The following macro will get this right
1497          * on many machines.  */
1498         SHELL_SIZE = sizeof(union { int i; char *cp; double d; }) - 1,
1499         /* Minimum size of a block */
1500         MINSIZE = SHELL_ALIGN(504),
1501 };
1502
1503 struct stack_block {
1504         struct stack_block *prev;
1505         char space[MINSIZE];
1506 };
1507
1508 struct stackmark {
1509         struct stack_block *stackp;
1510         char *stacknxt;
1511         size_t stacknleft;
1512 };
1513
1514
1515 struct globals_memstack {
1516         struct stack_block *g_stackp; // = &stackbase;
1517         char *g_stacknxt; // = stackbase.space;
1518         char *sstrend; // = stackbase.space + MINSIZE;
1519         size_t g_stacknleft; // = MINSIZE;
1520         struct stack_block stackbase;
1521 };
1522 extern struct globals_memstack *BB_GLOBAL_CONST ash_ptr_to_globals_memstack;
1523 #define G_memstack (*ash_ptr_to_globals_memstack)
1524 #define g_stackp     (G_memstack.g_stackp    )
1525 #define g_stacknxt   (G_memstack.g_stacknxt  )
1526 #define sstrend      (G_memstack.sstrend     )
1527 #define g_stacknleft (G_memstack.g_stacknleft)
1528 #define stackbase    (G_memstack.stackbase   )
1529 #define INIT_G_memstack() do { \
1530         (*(struct globals_memstack**)&ash_ptr_to_globals_memstack) = xzalloc(sizeof(G_memstack)); \
1531         barrier(); \
1532         g_stackp = &stackbase; \
1533         g_stacknxt = stackbase.space; \
1534         g_stacknleft = MINSIZE; \
1535         sstrend = stackbase.space + MINSIZE; \
1536 } while (0)
1537
1538
1539 #define stackblock()     ((void *)g_stacknxt)
1540 #define stackblocksize() g_stacknleft
1541
1542 /*
1543  * Parse trees for commands are allocated in lifo order, so we use a stack
1544  * to make this more efficient, and also to avoid all sorts of exception
1545  * handling code to handle interrupts in the middle of a parse.
1546  *
1547  * The size 504 was chosen because the Ultrix malloc handles that size
1548  * well.
1549  */
1550 static void *
1551 stalloc(size_t nbytes)
1552 {
1553         char *p;
1554         size_t aligned;
1555
1556         aligned = SHELL_ALIGN(nbytes);
1557         if (aligned > g_stacknleft) {
1558                 size_t len;
1559                 size_t blocksize;
1560                 struct stack_block *sp;
1561
1562                 blocksize = aligned;
1563                 if (blocksize < MINSIZE)
1564                         blocksize = MINSIZE;
1565                 len = sizeof(struct stack_block) - MINSIZE + blocksize;
1566                 if (len < blocksize)
1567                         ash_msg_and_raise_error(bb_msg_memory_exhausted);
1568                 INT_OFF;
1569                 sp = ckmalloc(len);
1570                 sp->prev = g_stackp;
1571                 g_stacknxt = sp->space;
1572                 g_stacknleft = blocksize;
1573                 sstrend = g_stacknxt + blocksize;
1574                 g_stackp = sp;
1575                 INT_ON;
1576         }
1577         p = g_stacknxt;
1578         g_stacknxt += aligned;
1579         g_stacknleft -= aligned;
1580         return p;
1581 }
1582
1583 static void *
1584 stzalloc(size_t nbytes)
1585 {
1586         return memset(stalloc(nbytes), 0, nbytes);
1587 }
1588
1589 static void
1590 stunalloc(void *p)
1591 {
1592 #if DEBUG
1593         if (!p || (g_stacknxt < (char *)p) || ((char *)p < g_stackp->space)) {
1594                 write(STDERR_FILENO, "stunalloc\n", 10);
1595                 abort();
1596         }
1597 #endif
1598         g_stacknleft += g_stacknxt - (char *)p;
1599         g_stacknxt = p;
1600 }
1601
1602 /*
1603  * Like strdup but works with the ash stack.
1604  */
1605 static char *
1606 sstrdup(const char *p)
1607 {
1608         size_t len = strlen(p) + 1;
1609         return memcpy(stalloc(len), p, len);
1610 }
1611
1612 static ALWAYS_INLINE void
1613 grabstackblock(size_t len)
1614 {
1615         stalloc(len);
1616 }
1617
1618 static void
1619 pushstackmark(struct stackmark *mark, size_t len)
1620 {
1621         mark->stackp = g_stackp;
1622         mark->stacknxt = g_stacknxt;
1623         mark->stacknleft = g_stacknleft;
1624         grabstackblock(len);
1625 }
1626
1627 static void
1628 setstackmark(struct stackmark *mark)
1629 {
1630         pushstackmark(mark, g_stacknxt == g_stackp->space && g_stackp != &stackbase);
1631 }
1632
1633 static void
1634 popstackmark(struct stackmark *mark)
1635 {
1636         struct stack_block *sp;
1637
1638         if (!mark->stackp)
1639                 return;
1640
1641         INT_OFF;
1642         while (g_stackp != mark->stackp) {
1643                 sp = g_stackp;
1644                 g_stackp = sp->prev;
1645                 free(sp);
1646         }
1647         g_stacknxt = mark->stacknxt;
1648         g_stacknleft = mark->stacknleft;
1649         sstrend = mark->stacknxt + mark->stacknleft;
1650         INT_ON;
1651 }
1652
1653 /*
1654  * When the parser reads in a string, it wants to stick the string on the
1655  * stack and only adjust the stack pointer when it knows how big the
1656  * string is.  Stackblock (defined in stack.h) returns a pointer to a block
1657  * of space on top of the stack and stackblocklen returns the length of
1658  * this block.  Growstackblock will grow this space by at least one byte,
1659  * possibly moving it (like realloc).  Grabstackblock actually allocates the
1660  * part of the block that has been used.
1661  */
1662 static void
1663 growstackblock(void)
1664 {
1665         size_t newlen;
1666
1667         newlen = g_stacknleft * 2;
1668         if (newlen < g_stacknleft)
1669                 ash_msg_and_raise_error(bb_msg_memory_exhausted);
1670         if (newlen < 128)
1671                 newlen += 128;
1672
1673         if (g_stacknxt == g_stackp->space && g_stackp != &stackbase) {
1674                 struct stack_block *sp;
1675                 struct stack_block *prevstackp;
1676                 size_t grosslen;
1677
1678                 INT_OFF;
1679                 sp = g_stackp;
1680                 prevstackp = sp->prev;
1681                 grosslen = newlen + sizeof(struct stack_block) - MINSIZE;
1682                 sp = ckrealloc(sp, grosslen);
1683                 sp->prev = prevstackp;
1684                 g_stackp = sp;
1685                 g_stacknxt = sp->space;
1686                 g_stacknleft = newlen;
1687                 sstrend = sp->space + newlen;
1688                 INT_ON;
1689         } else {
1690                 char *oldspace = g_stacknxt;
1691                 size_t oldlen = g_stacknleft;
1692                 char *p = stalloc(newlen);
1693
1694                 /* free the space we just allocated */
1695                 g_stacknxt = memcpy(p, oldspace, oldlen);
1696                 g_stacknleft += newlen;
1697         }
1698 }
1699
1700 /*
1701  * The following routines are somewhat easier to use than the above.
1702  * The user declares a variable of type STACKSTR, which may be declared
1703  * to be a register.  The macro STARTSTACKSTR initializes things.  Then
1704  * the user uses the macro STPUTC to add characters to the string.  In
1705  * effect, STPUTC(c, p) is the same as *p++ = c except that the stack is
1706  * grown as necessary.  When the user is done, she can just leave the
1707  * string there and refer to it using stackblock().  Or she can allocate
1708  * the space for it using grabstackstr().  If it is necessary to allow
1709  * someone else to use the stack temporarily and then continue to grow
1710  * the string, the user should use grabstack to allocate the space, and
1711  * then call ungrabstr(p) to return to the previous mode of operation.
1712  *
1713  * USTPUTC is like STPUTC except that it doesn't check for overflow.
1714  * CHECKSTACKSPACE can be called before USTPUTC to ensure that there
1715  * is space for at least one character.
1716  */
1717 static void *
1718 growstackstr(void)
1719 {
1720         size_t len = stackblocksize();
1721         growstackblock();
1722         return (char *)stackblock() + len;
1723 }
1724
1725 /*
1726  * Called from CHECKSTRSPACE.
1727  */
1728 static char *
1729 makestrspace(size_t newlen, char *p)
1730 {
1731         size_t len = p - g_stacknxt;
1732         size_t size;
1733
1734         for (;;) {
1735                 size_t nleft;
1736
1737                 size = stackblocksize();
1738                 nleft = size - len;
1739                 if (nleft >= newlen)
1740                         break;
1741                 growstackblock();
1742         }
1743         return (char *)stackblock() + len;
1744 }
1745
1746 static char *
1747 stack_nputstr(const char *s, size_t n, char *p)
1748 {
1749         p = makestrspace(n, p);
1750         p = (char *)mempcpy(p, s, n);
1751         return p;
1752 }
1753
1754 static char *
1755 stack_putstr(const char *s, char *p)
1756 {
1757         return stack_nputstr(s, strlen(s), p);
1758 }
1759
1760 static char *
1761 _STPUTC(int c, char *p)
1762 {
1763         if (p == sstrend)
1764                 p = growstackstr();
1765         *p++ = c;
1766         return p;
1767 }
1768
1769 #define STARTSTACKSTR(p)        ((p) = stackblock())
1770 #define STPUTC(c, p)            ((p) = _STPUTC((c), (p)))
1771 #define CHECKSTRSPACE(n, p) do { \
1772         char *q = (p); \
1773         size_t l = (n); \
1774         size_t m = sstrend - q; \
1775         if (l > m) \
1776                 (p) = makestrspace(l, q); \
1777 } while (0)
1778 #define USTPUTC(c, p)           (*(p)++ = (c))
1779 #define STACKSTRNUL(p) do { \
1780         if ((p) == sstrend) \
1781                 (p) = growstackstr(); \
1782         *(p) = '\0'; \
1783 } while (0)
1784 #define STUNPUTC(p)             (--(p))
1785 #define STTOPC(p)               ((p)[-1])
1786 #define STADJUST(amount, p)     ((p) += (amount))
1787
1788 #define grabstackstr(p)         stalloc((char *)(p) - (char *)stackblock())
1789 #define ungrabstackstr(s, p)    stunalloc(s)
1790 #define stackstrend()           ((void *)sstrend)
1791
1792
1793 /* ============ String helpers */
1794
1795 /*
1796  * prefix -- see if pfx is a prefix of string.
1797  */
1798 static char *
1799 prefix(const char *string, const char *pfx)
1800 {
1801         while (*pfx) {
1802                 if (*pfx++ != *string++)
1803                         return NULL;
1804         }
1805         return (char *) string;
1806 }
1807
1808 /*
1809  * Check for a valid number.  This should be elsewhere.
1810  */
1811 static int
1812 is_number(const char *p)
1813 {
1814         do {
1815                 if (!isdigit(*p))
1816                         return 0;
1817         } while (*++p != '\0');
1818         return 1;
1819 }
1820
1821 /*
1822  * Convert a string of digits to an integer, printing an error message on
1823  * failure.
1824  */
1825 static int
1826 number(const char *s)
1827 {
1828         if (!is_number(s))
1829                 ash_msg_and_raise_error(msg_illnum, s);
1830         return atoi(s);
1831 }
1832
1833 /*
1834  * Produce a single quoted string suitable as input to the shell.
1835  * The return string is allocated on the stack.
1836  */
1837 static char *
1838 single_quote(const char *s)
1839 {
1840         char *p;
1841
1842         STARTSTACKSTR(p);
1843
1844         do {
1845                 char *q;
1846                 size_t len;
1847
1848                 len = strchrnul(s, '\'') - s;
1849
1850                 q = p = makestrspace(len + 3, p);
1851
1852                 *q++ = '\'';
1853                 q = (char *)mempcpy(q, s, len);
1854                 *q++ = '\'';
1855                 s += len;
1856
1857                 STADJUST(q - p, p);
1858
1859                 if (*s != '\'')
1860                         break;
1861                 len = 0;
1862                 do len++; while (*++s == '\'');
1863
1864                 q = p = makestrspace(len + 3, p);
1865
1866                 *q++ = '"';
1867                 q = (char *)mempcpy(q, s - len, len);
1868                 *q++ = '"';
1869
1870                 STADJUST(q - p, p);
1871         } while (*s);
1872
1873         USTPUTC('\0', p);
1874
1875         return stackblock();
1876 }
1877
1878 /*
1879  * Produce a possibly single quoted string suitable as input to the shell.
1880  * If quoting was done, the return string is allocated on the stack,
1881  * otherwise a pointer to the original string is returned.
1882  */
1883 static const char *
1884 maybe_single_quote(const char *s)
1885 {
1886         const char *p = s;
1887
1888         while (*p) {
1889                 /* Assuming ACSII */
1890                 /* quote ctrl_chars space !"#$%&'()* */
1891                 if (*p < '+')
1892                         goto need_quoting;
1893                 /* quote ;<=>? */
1894                 if (*p >= ';' && *p <= '?')
1895                         goto need_quoting;
1896                 /* quote `[\ */
1897                 if (*p == '`')
1898                         goto need_quoting;
1899                 if (*p == '[')
1900                         goto need_quoting;
1901                 if (*p == '\\')
1902                         goto need_quoting;
1903                 /* quote {|}~ DEL and high bytes */
1904                 if (*p > 'z')
1905                         goto need_quoting;
1906                 /* Not quoting these: +,-./ 0-9 :@ A-Z ]^_ a-z */
1907                 /* TODO: maybe avoid quoting % */
1908                 p++;
1909         }
1910         return s;
1911
1912  need_quoting:
1913         return single_quote(s);
1914 }
1915
1916
1917 /* ============ nextopt */
1918
1919 static char **argptr;                  /* argument list for builtin commands */
1920 static char *optionarg;                /* set by nextopt (like getopt) */
1921 static char *optptr;                   /* used by nextopt */
1922
1923 /*
1924  * XXX - should get rid of. Have all builtins use getopt(3).
1925  * The library getopt must have the BSD extension static variable
1926  * "optreset", otherwise it can't be used within the shell safely.
1927  *
1928  * Standard option processing (a la getopt) for builtin routines.
1929  * The only argument that is passed to nextopt is the option string;
1930  * the other arguments are unnecessary. It returns the character,
1931  * or '\0' on end of input.
1932  */
1933 static int
1934 nextopt(const char *optstring)
1935 {
1936         char *p;
1937         const char *q;
1938         char c;
1939
1940         p = optptr;
1941         if (p == NULL || *p == '\0') {
1942                 /* We ate entire "-param", take next one */
1943                 p = *argptr;
1944                 if (p == NULL)
1945                         return '\0';
1946                 if (*p != '-')
1947                         return '\0';
1948                 if (*++p == '\0') /* just "-" ? */
1949                         return '\0';
1950                 argptr++;
1951                 if (LONE_DASH(p)) /* "--" ? */
1952                         return '\0';
1953                 /* p => next "-param" */
1954         }
1955         /* p => some option char in the middle of a "-param" */
1956         c = *p++;
1957         for (q = optstring; *q != c;) {
1958                 if (*q == '\0')
1959                         ash_msg_and_raise_error("illegal option -%c", c);
1960                 if (*++q == ':')
1961                         q++;
1962         }
1963         if (*++q == ':') {
1964                 if (*p == '\0') {
1965                         p = *argptr++;
1966                         if (p == NULL)
1967                                 ash_msg_and_raise_error("no arg for -%c option", c);
1968                 }
1969                 optionarg = p;
1970                 p = NULL;
1971         }
1972         optptr = p;
1973         return c;
1974 }
1975
1976
1977 /* ============ Shell variables */
1978
1979 struct shparam {
1980         int nparam;             /* # of positional parameters (without $0) */
1981 #if ENABLE_ASH_GETOPTS
1982         int optind;             /* next parameter to be processed by getopts */
1983         int optoff;             /* used by getopts */
1984 #endif
1985         unsigned char malloced; /* if parameter list dynamically allocated */
1986         char **p;               /* parameter list */
1987 };
1988
1989 /*
1990  * Free the list of positional parameters.
1991  */
1992 static void
1993 freeparam(volatile struct shparam *param)
1994 {
1995         if (param->malloced) {
1996                 char **ap, **ap1;
1997                 ap = ap1 = param->p;
1998                 while (*ap)
1999                         free(*ap++);
2000                 free(ap1);
2001         }
2002 }
2003
2004 #if ENABLE_ASH_GETOPTS
2005 static void FAST_FUNC getoptsreset(const char *value);
2006 #endif
2007
2008 struct var {
2009         struct var *next;               /* next entry in hash list */
2010         int flags;                      /* flags are defined above */
2011         const char *var_text;           /* name=value */
2012         void (*var_func)(const char *) FAST_FUNC; /* function to be called when  */
2013                                         /* the variable gets set/unset */
2014 };
2015
2016 struct localvar {
2017         struct localvar *next;          /* next local variable in list */
2018         struct var *vp;                 /* the variable that was made local */
2019         int flags;                      /* saved flags */
2020         const char *text;               /* saved text */
2021 };
2022
2023 /* flags */
2024 #define VEXPORT         0x01    /* variable is exported */
2025 #define VREADONLY       0x02    /* variable cannot be modified */
2026 #define VSTRFIXED       0x04    /* variable struct is statically allocated */
2027 #define VTEXTFIXED      0x08    /* text is statically allocated */
2028 #define VSTACK          0x10    /* text is allocated on the stack */
2029 #define VUNSET          0x20    /* the variable is not set */
2030 #define VNOFUNC         0x40    /* don't call the callback function */
2031 #define VNOSET          0x80    /* do not set variable - just readonly test */
2032 #define VNOSAVE         0x100   /* when text is on the heap before setvareq */
2033 #if ENABLE_ASH_RANDOM_SUPPORT
2034 # define VDYNAMIC       0x200   /* dynamic variable */
2035 #else
2036 # define VDYNAMIC       0
2037 #endif
2038
2039
2040 /* Need to be before varinit_data[] */
2041 #if ENABLE_LOCALE_SUPPORT
2042 static void FAST_FUNC
2043 change_lc_all(const char *value)
2044 {
2045         if (value && *value != '\0')
2046                 setlocale(LC_ALL, value);
2047 }
2048 static void FAST_FUNC
2049 change_lc_ctype(const char *value)
2050 {
2051         if (value && *value != '\0')
2052                 setlocale(LC_CTYPE, value);
2053 }
2054 #endif
2055 #if ENABLE_ASH_MAIL
2056 static void chkmail(void);
2057 static void changemail(const char *var_value) FAST_FUNC;
2058 #else
2059 # define chkmail()  ((void)0)
2060 #endif
2061 static void changepath(const char *) FAST_FUNC;
2062 #if ENABLE_ASH_RANDOM_SUPPORT
2063 static void change_random(const char *) FAST_FUNC;
2064 #endif
2065
2066 static const struct {
2067         int flags;
2068         const char *var_text;
2069         void (*var_func)(const char *) FAST_FUNC;
2070 } varinit_data[] = {
2071         /*
2072          * Note: VEXPORT would not work correctly here for NOFORK applets:
2073          * some environment strings may be constant.
2074          */
2075         { VSTRFIXED|VTEXTFIXED       , defifsvar   , NULL            },
2076 #if ENABLE_ASH_MAIL
2077         { VSTRFIXED|VTEXTFIXED|VUNSET, "MAIL"      , changemail      },
2078         { VSTRFIXED|VTEXTFIXED|VUNSET, "MAILPATH"  , changemail      },
2079 #endif
2080         { VSTRFIXED|VTEXTFIXED       , bb_PATH_root_path, changepath },
2081         { VSTRFIXED|VTEXTFIXED       , "PS1=$ "    , NULL            },
2082         { VSTRFIXED|VTEXTFIXED       , "PS2=> "    , NULL            },
2083         { VSTRFIXED|VTEXTFIXED       , "PS4=+ "    , NULL            },
2084 #if ENABLE_ASH_GETOPTS
2085         { VSTRFIXED|VTEXTFIXED       , defoptindvar, getoptsreset    },
2086 #endif
2087         { VSTRFIXED|VTEXTFIXED       , NULL /* inited to linenovar */, NULL },
2088 #if ENABLE_ASH_RANDOM_SUPPORT
2089         { VSTRFIXED|VTEXTFIXED|VUNSET|VDYNAMIC, "RANDOM", change_random },
2090 #endif
2091 #if ENABLE_LOCALE_SUPPORT
2092         { VSTRFIXED|VTEXTFIXED|VUNSET, "LC_ALL"    , change_lc_all   },
2093         { VSTRFIXED|VTEXTFIXED|VUNSET, "LC_CTYPE"  , change_lc_ctype },
2094 #endif
2095 #if ENABLE_FEATURE_EDITING_SAVEHISTORY
2096         { VSTRFIXED|VTEXTFIXED|VUNSET, "HISTFILE"  , NULL            },
2097 #endif
2098 };
2099
2100 struct redirtab;
2101
2102 struct globals_var {
2103         struct shparam shellparam;      /* $@ current positional parameters */
2104         struct redirtab *redirlist;
2105         int preverrout_fd;   /* stderr fd: usually 2, unless redirect moved it */
2106         struct var *vartab[VTABSIZE];
2107         struct var varinit[ARRAY_SIZE(varinit_data)];
2108         int lineno;
2109         char linenovar[sizeof("LINENO=") + sizeof(int)*3];
2110 };
2111 extern struct globals_var *BB_GLOBAL_CONST ash_ptr_to_globals_var;
2112 #define G_var (*ash_ptr_to_globals_var)
2113 #define shellparam    (G_var.shellparam   )
2114 //#define redirlist     (G_var.redirlist    )
2115 #define preverrout_fd (G_var.preverrout_fd)
2116 #define vartab        (G_var.vartab       )
2117 #define varinit       (G_var.varinit      )
2118 #define lineno        (G_var.lineno       )
2119 #define linenovar     (G_var.linenovar    )
2120 #define vifs      varinit[0]
2121 #if ENABLE_ASH_MAIL
2122 # define vmail    (&vifs)[1]
2123 # define vmpath   (&vmail)[1]
2124 # define vpath    (&vmpath)[1]
2125 #else
2126 # define vpath    (&vifs)[1]
2127 #endif
2128 #define vps1      (&vpath)[1]
2129 #define vps2      (&vps1)[1]
2130 #define vps4      (&vps2)[1]
2131 #if ENABLE_ASH_GETOPTS
2132 # define voptind  (&vps4)[1]
2133 # define vlineno  (&voptind)[1]
2134 # if ENABLE_ASH_RANDOM_SUPPORT
2135 #  define vrandom (&vlineno)[1]
2136 # endif
2137 #else
2138 # define vlineno  (&vps4)[1]
2139 # if ENABLE_ASH_RANDOM_SUPPORT
2140 #  define vrandom (&vlineno)[1]
2141 # endif
2142 #endif
2143 #define INIT_G_var() do { \
2144         unsigned i; \
2145         (*(struct globals_var**)&ash_ptr_to_globals_var) = xzalloc(sizeof(G_var)); \
2146         barrier(); \
2147         for (i = 0; i < ARRAY_SIZE(varinit_data); i++) { \
2148                 varinit[i].flags    = varinit_data[i].flags; \
2149                 varinit[i].var_text = varinit_data[i].var_text; \
2150                 varinit[i].var_func = varinit_data[i].var_func; \
2151         } \
2152         strcpy(linenovar, "LINENO="); \
2153         vlineno.var_text = linenovar; \
2154 } while (0)
2155
2156 /*
2157  * The following macros access the values of the above variables.
2158  * They have to skip over the name.  They return the null string
2159  * for unset variables.
2160  */
2161 #define ifsval()        (vifs.var_text + 4)
2162 #define ifsset()        ((vifs.flags & VUNSET) == 0)
2163 #if ENABLE_ASH_MAIL
2164 # define mailval()      (vmail.var_text + 5)
2165 # define mpathval()     (vmpath.var_text + 9)
2166 # define mpathset()     ((vmpath.flags & VUNSET) == 0)
2167 #endif
2168 #define pathval()       (vpath.var_text + 5)
2169 #define ps1val()        (vps1.var_text + 4)
2170 #define ps2val()        (vps2.var_text + 4)
2171 #define ps4val()        (vps4.var_text + 4)
2172 #if ENABLE_ASH_GETOPTS
2173 # define optindval()    (voptind.var_text + 7)
2174 #endif
2175
2176 #if ENABLE_ASH_GETOPTS
2177 static void FAST_FUNC
2178 getoptsreset(const char *value)
2179 {
2180         shellparam.optind = 1;
2181         if (is_number(value))
2182                 shellparam.optind = number(value) ?: 1;
2183         shellparam.optoff = -1;
2184 }
2185 #endif
2186
2187 /*
2188  * Compares two strings up to the first = or '\0'.  The first
2189  * string must be terminated by '='; the second may be terminated by
2190  * either '=' or '\0'.
2191  */
2192 static int
2193 varcmp(const char *p, const char *q)
2194 {
2195         int c, d;
2196
2197         while ((c = *p) == (d = *q)) {
2198                 if (c == '\0' || c == '=')
2199                         goto out;
2200                 p++;
2201                 q++;
2202         }
2203         if (c == '=')
2204                 c = '\0';
2205         if (d == '=')
2206                 d = '\0';
2207  out:
2208         return c - d;
2209 }
2210
2211 /*
2212  * Find the appropriate entry in the hash table from the name.
2213  */
2214 static struct var **
2215 hashvar(const char *p)
2216 {
2217         unsigned hashval;
2218
2219         hashval = ((unsigned char) *p) << 4;
2220         while (*p && *p != '=')
2221                 hashval += (unsigned char) *p++;
2222         return &vartab[hashval % VTABSIZE];
2223 }
2224
2225 static int
2226 vpcmp(const void *a, const void *b)
2227 {
2228         return varcmp(*(const char **)a, *(const char **)b);
2229 }
2230
2231 /*
2232  * This routine initializes the builtin variables.
2233  */
2234 static void
2235 initvar(void)
2236 {
2237         struct var *vp;
2238         struct var *end;
2239         struct var **vpp;
2240
2241         /*
2242          * PS1 depends on uid
2243          */
2244 #if ENABLE_FEATURE_EDITING && ENABLE_FEATURE_EDITING_FANCY_PROMPT
2245         vps1.var_text = "PS1=\\w \\$ ";
2246 #else
2247         if (!geteuid())
2248                 vps1.var_text = "PS1=# ";
2249 #endif
2250         vp = varinit;
2251         end = vp + ARRAY_SIZE(varinit);
2252         do {
2253                 vpp = hashvar(vp->var_text);
2254                 vp->next = *vpp;
2255                 *vpp = vp;
2256         } while (++vp < end);
2257 }
2258
2259 static struct var **
2260 findvar(struct var **vpp, const char *name)
2261 {
2262         for (; *vpp; vpp = &(*vpp)->next) {
2263                 if (varcmp((*vpp)->var_text, name) == 0) {
2264                         break;
2265                 }
2266         }
2267         return vpp;
2268 }
2269
2270 /*
2271  * Find the value of a variable.  Returns NULL if not set.
2272  */
2273 static const char* FAST_FUNC
2274 lookupvar(const char *name)
2275 {
2276         struct var *v;
2277
2278         v = *findvar(hashvar(name), name);
2279         if (v) {
2280 #if ENABLE_ASH_RANDOM_SUPPORT
2281         /*
2282          * Dynamic variables are implemented roughly the same way they are
2283          * in bash. Namely, they're "special" so long as they aren't unset.
2284          * As soon as they're unset, they're no longer dynamic, and dynamic
2285          * lookup will no longer happen at that point. -- PFM.
2286          */
2287                 if (v->flags & VDYNAMIC)
2288                         v->var_func(NULL);
2289 #endif
2290                 if (!(v->flags & VUNSET)) {
2291                         if (v == &vlineno && v->var_text == linenovar) {
2292                                 fmtstr(linenovar+7, sizeof(linenovar)-7, "%d", lineno);
2293                         }
2294                         return var_end(v->var_text);
2295                 }
2296         }
2297         return NULL;
2298 }
2299
2300 #if ENABLE_UNICODE_SUPPORT
2301 static void
2302 reinit_unicode_for_ash(void)
2303 {
2304         /* Unicode support should be activated even if LANG is set
2305          * _during_ shell execution, not only if it was set when
2306          * shell was started. Therefore, re-check LANG every time:
2307          */
2308         if (ENABLE_FEATURE_CHECK_UNICODE_IN_ENV
2309          || ENABLE_UNICODE_USING_LOCALE
2310         ) {
2311                 const char *s = lookupvar("LC_ALL");
2312                 if (!s) s = lookupvar("LC_CTYPE");
2313                 if (!s) s = lookupvar("LANG");
2314                 reinit_unicode(s);
2315         }
2316 }
2317 #else
2318 # define reinit_unicode_for_ash() ((void)0)
2319 #endif
2320
2321 /*
2322  * Search the environment of a builtin command.
2323  */
2324 static ALWAYS_INLINE const char *
2325 bltinlookup(const char *name)
2326 {
2327         return lookupvar(name);
2328 }
2329
2330 /*
2331  * Same as setvar except that the variable and value are passed in
2332  * the first argument as name=value.  Since the first argument will
2333  * be actually stored in the table, it should not be a string that
2334  * will go away.
2335  * Called with interrupts off.
2336  */
2337 static struct var *
2338 setvareq(char *s, int flags)
2339 {
2340         struct var *vp, **vpp;
2341
2342         vpp = hashvar(s);
2343         flags |= (VEXPORT & (((unsigned) (1 - aflag)) - 1));
2344         vpp = findvar(vpp, s);
2345         vp = *vpp;
2346         if (vp) {
2347                 if ((vp->flags & (VREADONLY|VDYNAMIC)) == VREADONLY) {
2348                         const char *n;
2349
2350                         if (flags & VNOSAVE)
2351                                 free(s);
2352                         n = vp->var_text;
2353                         exitstatus = 1;
2354                         ash_msg_and_raise_error("%.*s: is read only", strchrnul(n, '=') - n, n);
2355                 }
2356
2357                 if (flags & VNOSET)
2358                         goto out;
2359
2360                 if (vp->var_func && !(flags & VNOFUNC))
2361                         vp->var_func(var_end(s));
2362
2363                 if (!(vp->flags & (VTEXTFIXED|VSTACK)))
2364                         free((char*)vp->var_text);
2365
2366                 if (((flags & (VEXPORT|VREADONLY|VSTRFIXED|VUNSET)) | (vp->flags & VSTRFIXED)) == VUNSET) {
2367                         *vpp = vp->next;
2368                         free(vp);
2369  out_free:
2370                         if ((flags & (VTEXTFIXED|VSTACK|VNOSAVE)) == VNOSAVE)
2371                                 free(s);
2372                         goto out;
2373                 }
2374
2375                 flags |= vp->flags & ~(VTEXTFIXED|VSTACK|VNOSAVE|VUNSET);
2376         } else {
2377                 /* variable s is not found */
2378                 if (flags & VNOSET)
2379                         goto out;
2380                 if ((flags & (VEXPORT|VREADONLY|VSTRFIXED|VUNSET)) == VUNSET)
2381                         goto out_free;
2382                 vp = ckzalloc(sizeof(*vp));
2383                 vp->next = *vpp;
2384                 /*vp->func = NULL; - ckzalloc did it */
2385                 *vpp = vp;
2386         }
2387         if (!(flags & (VTEXTFIXED|VSTACK|VNOSAVE)))
2388                 s = ckstrdup(s);
2389         vp->var_text = s;
2390         vp->flags = flags;
2391
2392  out:
2393         return vp;
2394 }
2395
2396 /*
2397  * Set the value of a variable.  The flags argument is ored with the
2398  * flags of the variable.  If val is NULL, the variable is unset.
2399  */
2400 static struct var *
2401 setvar(const char *name, const char *val, int flags)
2402 {
2403         const char *q;
2404         char *p;
2405         char *nameeq;
2406         size_t namelen;
2407         size_t vallen;
2408         struct var *vp;
2409
2410         q = endofname(name);
2411         p = strchrnul(q, '=');
2412         namelen = p - name;
2413         if (!namelen || p != q)
2414                 ash_msg_and_raise_error("%.*s: bad variable name", namelen, name);
2415         vallen = 0;
2416         if (val == NULL) {
2417                 flags |= VUNSET;
2418         } else {
2419                 vallen = strlen(val);
2420         }
2421
2422         INT_OFF;
2423         nameeq = ckmalloc(namelen + vallen + 2);
2424         p = mempcpy(nameeq, name, namelen);
2425         if (val) {
2426                 *p++ = '=';
2427                 p = mempcpy(p, val, vallen);
2428         }
2429         *p = '\0';
2430         vp = setvareq(nameeq, flags | VNOSAVE);
2431         INT_ON;
2432
2433         return vp;
2434 }
2435
2436 static void FAST_FUNC
2437 setvar0(const char *name, const char *val)
2438 {
2439         setvar(name, val, 0);
2440 }
2441
2442 /*
2443  * Unset the specified variable.
2444  */
2445 static void
2446 unsetvar(const char *s)
2447 {
2448         setvar(s, NULL, 0);
2449 }
2450
2451 /*
2452  * Process a linked list of variable assignments.
2453  */
2454 static void
2455 listsetvar(struct strlist *list_set_var, int flags)
2456 {
2457         struct strlist *lp = list_set_var;
2458
2459         if (!lp)
2460                 return;
2461         INT_OFF;
2462         do {
2463                 setvareq(lp->text, flags);
2464                 lp = lp->next;
2465         } while (lp);
2466         INT_ON;
2467 }
2468
2469 /*
2470  * Generate a list of variables satisfying the given conditions.
2471  */
2472 #if !ENABLE_FEATURE_SH_NOFORK
2473 # define listvars(on, off, lp, end) listvars(on, off, end)
2474 #endif
2475 static char **
2476 listvars(int on, int off, struct strlist *lp, char ***end)
2477 {
2478         struct var **vpp;
2479         struct var *vp;
2480         char **ep;
2481         int mask;
2482
2483         STARTSTACKSTR(ep);
2484         vpp = vartab;
2485         mask = on | off;
2486         do {
2487                 for (vp = *vpp; vp; vp = vp->next) {
2488                         if ((vp->flags & mask) == on) {
2489 #if ENABLE_FEATURE_SH_NOFORK
2490                                 /* If variable with the same name is both
2491                                  * exported and temporarily set for a command:
2492                                  *  export ZVAR=5
2493                                  *  ZVAR=6 printenv
2494                                  * then "ZVAR=6" will be both in vartab and
2495                                  * lp lists. Do not pass it twice to printenv.
2496                                  */
2497                                 struct strlist *lp1 = lp;
2498                                 while (lp1) {
2499                                         if (strcmp(lp1->text, vp->var_text) == 0)
2500                                                 goto skip;
2501                                         lp1 = lp1->next;
2502                                 }
2503 #endif
2504                                 if (ep == stackstrend())
2505                                         ep = growstackstr();
2506                                 *ep++ = (char*)vp->var_text;
2507 #if ENABLE_FEATURE_SH_NOFORK
2508  skip: ;
2509 #endif
2510                         }
2511                 }
2512         } while (++vpp < vartab + VTABSIZE);
2513
2514 #if ENABLE_FEATURE_SH_NOFORK
2515         while (lp) {
2516                 if (ep == stackstrend())
2517                         ep = growstackstr();
2518                 *ep++ = lp->text;
2519                 lp = lp->next;
2520         }
2521 #endif
2522
2523         if (ep == stackstrend())
2524                 ep = growstackstr();
2525         if (end)
2526                 *end = ep;
2527         *ep++ = NULL;
2528         return grabstackstr(ep);
2529 }
2530
2531
2532 /* ============ Path search helper
2533  *
2534  * The variable path (passed by reference) should be set to the start
2535  * of the path before the first call; path_advance will update
2536  * this value as it proceeds.  Successive calls to path_advance will return
2537  * the possible path expansions in sequence.  If an option (indicated by
2538  * a percent sign) appears in the path entry then the global variable
2539  * pathopt will be set to point to it; otherwise pathopt will be set to
2540  * NULL.
2541  */
2542 static const char *pathopt;     /* set by path_advance */
2543
2544 static char *
2545 path_advance(const char **path, const char *name)
2546 {
2547         const char *p;
2548         char *q;
2549         const char *start;
2550         size_t len;
2551
2552         if (*path == NULL)
2553                 return NULL;
2554         start = *path;
2555         for (p = start; *p && *p != ':' && *p != '%'; p++)
2556                 continue;
2557         len = p - start + strlen(name) + 2;     /* "2" is for '/' and '\0' */
2558         while (stackblocksize() < len)
2559                 growstackblock();
2560         q = stackblock();
2561         if (p != start) {
2562                 q = mempcpy(q, start, p - start);
2563                 *q++ = '/';
2564         }
2565         strcpy(q, name);
2566         pathopt = NULL;
2567         if (*p == '%') {
2568                 pathopt = ++p;
2569                 while (*p && *p != ':')
2570                         p++;
2571         }
2572         if (*p == ':')
2573                 *path = p + 1;
2574         else
2575                 *path = NULL;
2576         return stalloc(len);
2577 }
2578
2579
2580 /* ============ Prompt */
2581
2582 static smallint doprompt;                   /* if set, prompt the user */
2583 static smallint needprompt;                 /* true if interactive and at start of line */
2584
2585 #if ENABLE_FEATURE_EDITING
2586 static line_input_t *line_input_state;
2587 static const char *cmdedit_prompt;
2588 static void
2589 putprompt(const char *s)
2590 {
2591         if (ENABLE_ASH_EXPAND_PRMT) {
2592                 free((char*)cmdedit_prompt);
2593                 cmdedit_prompt = ckstrdup(s);
2594                 return;
2595         }
2596         cmdedit_prompt = s;
2597 }
2598 #else
2599 static void
2600 putprompt(const char *s)
2601 {
2602         out2str(s);
2603 }
2604 #endif
2605
2606 /* expandstr() needs parsing machinery, so it is far away ahead... */
2607 static const char *expandstr(const char *ps, int syntax_type);
2608 /* Values for syntax param */
2609 #define BASESYNTAX 0    /* not in quotes */
2610 #define DQSYNTAX   1    /* in double quotes */
2611 #define SQSYNTAX   2    /* in single quotes */
2612 #define ARISYNTAX  3    /* in arithmetic */
2613 #if ENABLE_ASH_EXPAND_PRMT
2614 # define PSSYNTAX  4    /* prompt. never passed to SIT() */
2615 #endif
2616 /* PSSYNTAX expansion is identical to DQSYNTAX, except keeping '\$' as '\$' */
2617
2618 /*
2619  * called by editline -- any expansions to the prompt should be added here.
2620  */
2621 static void
2622 setprompt_if(smallint do_set, int whichprompt)
2623 {
2624         const char *prompt;
2625         IF_ASH_EXPAND_PRMT(struct stackmark smark;)
2626
2627         if (!do_set)
2628                 return;
2629
2630         needprompt = 0;
2631
2632         switch (whichprompt) {
2633         case 1:
2634                 prompt = ps1val();
2635                 break;
2636         case 2:
2637                 prompt = ps2val();
2638                 break;
2639         default:                        /* 0 */
2640                 prompt = nullstr;
2641         }
2642 #if ENABLE_ASH_EXPAND_PRMT
2643         pushstackmark(&smark, stackblocksize());
2644         putprompt(expandstr(prompt, PSSYNTAX));
2645         popstackmark(&smark);
2646 #else
2647         putprompt(prompt);
2648 #endif
2649 }
2650
2651
2652 /* ============ The cd and pwd commands */
2653
2654 #define CD_PHYSICAL 1
2655 #define CD_PRINT 2
2656
2657 static int
2658 cdopt(void)
2659 {
2660         int flags = 0;
2661         int i, j;
2662
2663         j = 'L';
2664         while ((i = nextopt("LP")) != '\0') {
2665                 if (i != j) {
2666                         flags ^= CD_PHYSICAL;
2667                         j = i;
2668                 }
2669         }
2670
2671         return flags;
2672 }
2673
2674 /*
2675  * Update curdir (the name of the current directory) in response to a
2676  * cd command.
2677  */
2678 static const char *
2679 updatepwd(const char *dir)
2680 {
2681         char *new;
2682         char *p;
2683         char *cdcomppath;
2684         const char *lim;
2685
2686         cdcomppath = sstrdup(dir);
2687         STARTSTACKSTR(new);
2688         if (*dir != '/') {
2689                 if (curdir == nullstr)
2690                         return 0;
2691                 new = stack_putstr(curdir, new);
2692         }
2693         new = makestrspace(strlen(dir) + 2, new);
2694         lim = (char *)stackblock() + 1;
2695         if (*dir != '/') {
2696                 if (new[-1] != '/')
2697                         USTPUTC('/', new);
2698                 if (new > lim && *lim == '/')
2699                         lim++;
2700         } else {
2701                 USTPUTC('/', new);
2702                 cdcomppath++;
2703                 if (dir[1] == '/' && dir[2] != '/') {
2704                         USTPUTC('/', new);
2705                         cdcomppath++;
2706                         lim++;
2707                 }
2708         }
2709         p = strtok(cdcomppath, "/");
2710         while (p) {
2711                 switch (*p) {
2712                 case '.':
2713                         if (p[1] == '.' && p[2] == '\0') {
2714                                 while (new > lim) {
2715                                         STUNPUTC(new);
2716                                         if (new[-1] == '/')
2717                                                 break;
2718                                 }
2719                                 break;
2720                         }
2721                         if (p[1] == '\0')
2722                                 break;
2723                         /* fall through */
2724                 default:
2725                         new = stack_putstr(p, new);
2726                         USTPUTC('/', new);
2727                 }
2728                 p = strtok(NULL, "/");
2729         }
2730         if (new > lim)
2731                 STUNPUTC(new);
2732         *new = 0;
2733         return stackblock();
2734 }
2735
2736 /*
2737  * Find out what the current directory is. If we already know the current
2738  * directory, this routine returns immediately.
2739  */
2740 static char *
2741 getpwd(void)
2742 {
2743         char *dir = getcwd(NULL, 0); /* huh, using glibc extension? */
2744         return dir ? dir : nullstr;
2745 }
2746
2747 static void
2748 setpwd(const char *val, int setold)
2749 {
2750         char *oldcur, *dir;
2751
2752         oldcur = dir = curdir;
2753
2754         if (setold) {
2755                 setvar("OLDPWD", oldcur, VEXPORT);
2756         }
2757         INT_OFF;
2758         if (physdir != nullstr) {
2759                 if (physdir != oldcur)
2760                         free(physdir);
2761                 physdir = nullstr;
2762         }
2763         if (oldcur == val || !val) {
2764                 char *s = getpwd();
2765                 physdir = s;
2766                 if (!val)
2767                         dir = s;
2768         } else
2769                 dir = ckstrdup(val);
2770         if (oldcur != dir && oldcur != nullstr) {
2771                 free(oldcur);
2772         }
2773         curdir = dir;
2774         INT_ON;
2775         setvar("PWD", dir, VEXPORT);
2776 }
2777
2778 static void hashcd(void);
2779
2780 /*
2781  * Actually do the chdir.  We also call hashcd to let other routines
2782  * know that the current directory has changed.
2783  */
2784 static int
2785 docd(const char *dest, int flags)
2786 {
2787         const char *dir = NULL;
2788         int err;
2789
2790         TRACE(("docd(\"%s\", %d) called\n", dest, flags));
2791
2792         INT_OFF;
2793         if (!(flags & CD_PHYSICAL)) {
2794                 dir = updatepwd(dest);
2795                 if (dir)
2796                         dest = dir;
2797         }
2798         err = chdir(dest);
2799         if (err)
2800                 goto out;
2801         setpwd(dir, 1);
2802         hashcd();
2803  out:
2804         INT_ON;
2805         return err;
2806 }
2807
2808 static int FAST_FUNC
2809 cdcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
2810 {
2811         const char *dest;
2812         const char *path;
2813         const char *p;
2814         char c;
2815         struct stat statb;
2816         int flags;
2817
2818         flags = cdopt();
2819         dest = *argptr;
2820         if (!dest)
2821                 dest = bltinlookup("HOME");
2822         else if (LONE_DASH(dest)) {
2823                 dest = bltinlookup("OLDPWD");
2824                 flags |= CD_PRINT;
2825         }
2826         if (!dest)
2827                 dest = nullstr;
2828         if (*dest == '/')
2829                 goto step6;
2830         if (*dest == '.') {
2831                 c = dest[1];
2832  dotdot:
2833                 switch (c) {
2834                 case '\0':
2835                 case '/':
2836                         goto step6;
2837                 case '.':
2838                         c = dest[2];
2839                         if (c != '.')
2840                                 goto dotdot;
2841                 }
2842         }
2843         if (!*dest)
2844                 dest = ".";
2845         path = bltinlookup("CDPATH");
2846         while (path) {
2847                 c = *path;
2848                 p = path_advance(&path, dest);
2849                 if (stat(p, &statb) >= 0 && S_ISDIR(statb.st_mode)) {
2850                         if (c && c != ':')
2851                                 flags |= CD_PRINT;
2852  docd:
2853                         if (!docd(p, flags))
2854                                 goto out;
2855                         goto err;
2856                 }
2857         }
2858
2859  step6:
2860         p = dest;
2861         goto docd;
2862
2863  err:
2864         ash_msg_and_raise_perror("can't cd to %s", dest);
2865         /* NOTREACHED */
2866  out:
2867         if (flags & CD_PRINT)
2868                 out1fmt("%s\n", curdir);
2869         return 0;
2870 }
2871
2872 static int FAST_FUNC
2873 pwdcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
2874 {
2875         int flags;
2876         const char *dir = curdir;
2877
2878         flags = cdopt();
2879         if (flags) {
2880                 if (physdir == nullstr)
2881                         setpwd(dir, 0);
2882                 dir = physdir;
2883         }
2884         out1fmt("%s\n", dir);
2885         return 0;
2886 }
2887
2888
2889 /* ============ ... */
2890
2891
2892 #define IBUFSIZ (ENABLE_FEATURE_EDITING ? CONFIG_FEATURE_EDITING_MAX_LEN : 1024)
2893
2894 /* Syntax classes */
2895 #define CWORD     0             /* character is nothing special */
2896 #define CNL       1             /* newline character */
2897 #define CBACK     2             /* a backslash character */
2898 #define CSQUOTE   3             /* single quote */
2899 #define CDQUOTE   4             /* double quote */
2900 #define CENDQUOTE 5             /* a terminating quote */
2901 #define CBQUOTE   6             /* backwards single quote */
2902 #define CVAR      7             /* a dollar sign */
2903 #define CENDVAR   8             /* a '}' character */
2904 #define CLP       9             /* a left paren in arithmetic */
2905 #define CRP      10             /* a right paren in arithmetic */
2906 #define CENDFILE 11             /* end of file */
2907 #define CCTL     12             /* like CWORD, except it must be escaped */
2908 #define CSPCL    13             /* these terminate a word */
2909 #define CIGN     14             /* character should be ignored */
2910
2911 #define PEOF     256
2912 #if ENABLE_ASH_ALIAS
2913 # define PEOA    257
2914 #endif
2915
2916 #define USE_SIT_FUNCTION ENABLE_ASH_OPTIMIZE_FOR_SIZE
2917
2918 #if ENABLE_FEATURE_SH_MATH
2919 # define SIT_ITEM(a,b,c,d) (a | (b << 4) | (c << 8) | (d << 12))
2920 #else
2921 # define SIT_ITEM(a,b,c,d) (a | (b << 4) | (c << 8))
2922 #endif
2923 static const uint16_t S_I_T[] ALIGN2 = {
2924 #if ENABLE_ASH_ALIAS
2925         SIT_ITEM(CSPCL   , CIGN     , CIGN , CIGN   ),    /* 0, PEOA */
2926 #endif
2927         SIT_ITEM(CSPCL   , CWORD    , CWORD, CWORD  ),    /* 1, ' ' */
2928         SIT_ITEM(CNL     , CNL      , CNL  , CNL    ),    /* 2, \n */
2929         SIT_ITEM(CWORD   , CCTL     , CCTL , CWORD  ),    /* 3, !*-/:=?[]~ */
2930         SIT_ITEM(CDQUOTE , CENDQUOTE, CWORD, CWORD  ),    /* 4, '"' */
2931         SIT_ITEM(CVAR    , CVAR     , CWORD, CVAR   ),    /* 5, $ */
2932         SIT_ITEM(CSQUOTE , CWORD    , CENDQUOTE, CWORD),  /* 6, "'" */
2933         SIT_ITEM(CSPCL   , CWORD    , CWORD, CLP    ),    /* 7, ( */
2934         SIT_ITEM(CSPCL   , CWORD    , CWORD, CRP    ),    /* 8, ) */
2935         SIT_ITEM(CBACK   , CBACK    , CCTL , CBACK  ),    /* 9, \ */
2936         SIT_ITEM(CBQUOTE , CBQUOTE  , CWORD, CBQUOTE),    /* 10, ` */
2937         SIT_ITEM(CENDVAR , CENDVAR  , CWORD, CENDVAR),    /* 11, } */
2938 #if !USE_SIT_FUNCTION
2939         SIT_ITEM(CENDFILE, CENDFILE , CENDFILE, CENDFILE),/* 12, PEOF */
2940         SIT_ITEM(CWORD   , CWORD    , CWORD, CWORD  ),    /* 13, 0-9A-Za-z */
2941         SIT_ITEM(CCTL    , CCTL     , CCTL , CCTL   )     /* 14, CTLESC ... */
2942 #endif
2943 #undef SIT_ITEM
2944 };
2945 /* Constants below must match table above */
2946 enum {
2947 #if ENABLE_ASH_ALIAS
2948         CSPCL_CIGN_CIGN_CIGN               , /*  0 */
2949 #endif
2950         CSPCL_CWORD_CWORD_CWORD            , /*  1 */
2951         CNL_CNL_CNL_CNL                    , /*  2 */
2952         CWORD_CCTL_CCTL_CWORD              , /*  3 */
2953         CDQUOTE_CENDQUOTE_CWORD_CWORD      , /*  4 */
2954         CVAR_CVAR_CWORD_CVAR               , /*  5 */
2955         CSQUOTE_CWORD_CENDQUOTE_CWORD      , /*  6 */
2956         CSPCL_CWORD_CWORD_CLP              , /*  7 */
2957         CSPCL_CWORD_CWORD_CRP              , /*  8 */
2958         CBACK_CBACK_CCTL_CBACK             , /*  9 */
2959         CBQUOTE_CBQUOTE_CWORD_CBQUOTE      , /* 10 */
2960         CENDVAR_CENDVAR_CWORD_CENDVAR      , /* 11 */
2961         CENDFILE_CENDFILE_CENDFILE_CENDFILE, /* 12 */
2962         CWORD_CWORD_CWORD_CWORD            , /* 13 */
2963         CCTL_CCTL_CCTL_CCTL                , /* 14 */
2964 };
2965
2966 /* c in SIT(c, syntax) must be an *unsigned char* or PEOA or PEOF,
2967  * caller must ensure proper cast on it if c is *char_ptr!
2968  */
2969 #if USE_SIT_FUNCTION
2970
2971 static int
2972 SIT(int c, int syntax)
2973 {
2974         /* Used to also have '/' in this string: "\t\n !\"$&'()*-/:;<=>?[\\]`|}~" */
2975         static const char spec_symbls[] ALIGN1 = "\t\n !\"$&'()*-:;<=>?[\\]`|}~";
2976         /*
2977          * This causes '/' to be prepended with CTLESC in dquoted string,
2978          * making "./file"* treated incorrectly because we feed
2979          * ".\/file*" string to glob(), confusing it (see expandmeta func).
2980          * The "homegrown" glob implementation is okay with that,
2981          * but glibc one isn't. With '/' always treated as CWORD,
2982          * both work fine.
2983          */
2984 # if ENABLE_ASH_ALIAS
2985         static const uint8_t syntax_index_table[] ALIGN1 = {
2986                 1, 2, 1, 3, 4, 5, 1, 6,         /* "\t\n !\"$&'" */
2987                 7, 8, 3, 3,/*3,*/3, 1, 1,       /* "()*-/:;<" */
2988                 3, 1, 3, 3, 9, 3, 10, 1,        /* "=>?[\\]`|" */
2989                 11, 3                           /* "}~" */
2990         };
2991 # else
2992         static const uint8_t syntax_index_table[] ALIGN1 = {
2993                 0, 1, 0, 2, 3, 4, 0, 5,         /* "\t\n !\"$&'" */
2994                 6, 7, 2, 2,/*2,*/2, 0, 0,       /* "()*-/:;<" */
2995                 2, 0, 2, 2, 8, 2, 9, 0,         /* "=>?[\\]`|" */
2996                 10, 2                           /* "}~" */
2997         };
2998 # endif
2999         const char *s;
3000         int indx;
3001
3002         if (c == PEOF)
3003                 return CENDFILE;
3004 # if ENABLE_ASH_ALIAS
3005         if (c == PEOA)
3006                 indx = 0;
3007         else
3008 # endif
3009         {
3010                 /* Cast is purely for paranoia here,
3011                  * just in case someone passed signed char to us */
3012                 if ((unsigned char)c >= CTL_FIRST
3013                  && (unsigned char)c <= CTL_LAST
3014                 ) {
3015                         return CCTL;
3016                 }
3017                 s = strchrnul(spec_symbls, c);
3018                 if (*s == '\0')
3019                         return CWORD;
3020                 indx = syntax_index_table[s - spec_symbls];
3021         }
3022         return (S_I_T[indx] >> (syntax*4)) & 0xf;
3023 }
3024
3025 #else   /* !USE_SIT_FUNCTION */
3026
3027 static const uint8_t syntax_index_table[] ALIGN1 = {
3028         /* BASESYNTAX_DQSYNTAX_SQSYNTAX_ARISYNTAX */
3029         /*   0      */ CWORD_CWORD_CWORD_CWORD,
3030         /*   1      */ CWORD_CWORD_CWORD_CWORD,
3031         /*   2      */ CWORD_CWORD_CWORD_CWORD,
3032         /*   3      */ CWORD_CWORD_CWORD_CWORD,
3033         /*   4      */ CWORD_CWORD_CWORD_CWORD,
3034         /*   5      */ CWORD_CWORD_CWORD_CWORD,
3035         /*   6      */ CWORD_CWORD_CWORD_CWORD,
3036         /*   7      */ CWORD_CWORD_CWORD_CWORD,
3037         /*   8      */ CWORD_CWORD_CWORD_CWORD,
3038         /*   9 "\t" */ CSPCL_CWORD_CWORD_CWORD,
3039         /*  10 "\n" */ CNL_CNL_CNL_CNL,
3040         /*  11      */ CWORD_CWORD_CWORD_CWORD,
3041         /*  12      */ CWORD_CWORD_CWORD_CWORD,
3042         /*  13      */ CWORD_CWORD_CWORD_CWORD,
3043         /*  14      */ CWORD_CWORD_CWORD_CWORD,
3044         /*  15      */ CWORD_CWORD_CWORD_CWORD,
3045         /*  16      */ CWORD_CWORD_CWORD_CWORD,
3046         /*  17      */ CWORD_CWORD_CWORD_CWORD,
3047         /*  18      */ CWORD_CWORD_CWORD_CWORD,
3048         /*  19      */ CWORD_CWORD_CWORD_CWORD,
3049         /*  20      */ CWORD_CWORD_CWORD_CWORD,
3050         /*  21      */ CWORD_CWORD_CWORD_CWORD,
3051         /*  22      */ CWORD_CWORD_CWORD_CWORD,
3052         /*  23      */ CWORD_CWORD_CWORD_CWORD,
3053         /*  24      */ CWORD_CWORD_CWORD_CWORD,
3054         /*  25      */ CWORD_CWORD_CWORD_CWORD,
3055         /*  26      */ CWORD_CWORD_CWORD_CWORD,
3056         /*  27      */ CWORD_CWORD_CWORD_CWORD,
3057         /*  28      */ CWORD_CWORD_CWORD_CWORD,
3058         /*  29      */ CWORD_CWORD_CWORD_CWORD,
3059         /*  30      */ CWORD_CWORD_CWORD_CWORD,
3060         /*  31      */ CWORD_CWORD_CWORD_CWORD,
3061         /*  32  " " */ CSPCL_CWORD_CWORD_CWORD,
3062         /*  33  "!" */ CWORD_CCTL_CCTL_CWORD,
3063         /*  34  """ */ CDQUOTE_CENDQUOTE_CWORD_CWORD,
3064         /*  35  "#" */ CWORD_CWORD_CWORD_CWORD,
3065         /*  36  "$" */ CVAR_CVAR_CWORD_CVAR,
3066         /*  37  "%" */ CWORD_CWORD_CWORD_CWORD,
3067         /*  38  "&" */ CSPCL_CWORD_CWORD_CWORD,
3068         /*  39  "'" */ CSQUOTE_CWORD_CENDQUOTE_CWORD,
3069         /*  40  "(" */ CSPCL_CWORD_CWORD_CLP,
3070         /*  41  ")" */ CSPCL_CWORD_CWORD_CRP,
3071         /*  42  "*" */ CWORD_CCTL_CCTL_CWORD,
3072         /*  43  "+" */ CWORD_CWORD_CWORD_CWORD,
3073         /*  44  "," */ CWORD_CWORD_CWORD_CWORD,
3074         /*  45  "-" */ CWORD_CCTL_CCTL_CWORD,
3075         /*  46  "." */ CWORD_CWORD_CWORD_CWORD,
3076 /* "/" was CWORD_CCTL_CCTL_CWORD, see comment in SIT() function why this is changed: */
3077         /*  47  "/" */ CWORD_CWORD_CWORD_CWORD,
3078         /*  48  "0" */ CWORD_CWORD_CWORD_CWORD,
3079         /*  49  "1" */ CWORD_CWORD_CWORD_CWORD,
3080         /*  50  "2" */ CWORD_CWORD_CWORD_CWORD,
3081         /*  51  "3" */ CWORD_CWORD_CWORD_CWORD,
3082         /*  52  "4" */ CWORD_CWORD_CWORD_CWORD,
3083         /*  53  "5" */ CWORD_CWORD_CWORD_CWORD,
3084         /*  54  "6" */ CWORD_CWORD_CWORD_CWORD,
3085         /*  55  "7" */ CWORD_CWORD_CWORD_CWORD,
3086         /*  56  "8" */ CWORD_CWORD_CWORD_CWORD,
3087         /*  57  "9" */ CWORD_CWORD_CWORD_CWORD,
3088         /*  58  ":" */ CWORD_CCTL_CCTL_CWORD,
3089         /*  59  ";" */ CSPCL_CWORD_CWORD_CWORD,
3090         /*  60  "<" */ CSPCL_CWORD_CWORD_CWORD,
3091         /*  61  "=" */ CWORD_CCTL_CCTL_CWORD,
3092         /*  62  ">" */ CSPCL_CWORD_CWORD_CWORD,
3093         /*  63  "?" */ CWORD_CCTL_CCTL_CWORD,
3094         /*  64  "@" */ CWORD_CWORD_CWORD_CWORD,
3095         /*  65  "A" */ CWORD_CWORD_CWORD_CWORD,
3096         /*  66  "B" */ CWORD_CWORD_CWORD_CWORD,
3097         /*  67  "C" */ CWORD_CWORD_CWORD_CWORD,
3098         /*  68  "D" */ CWORD_CWORD_CWORD_CWORD,
3099         /*  69  "E" */ CWORD_CWORD_CWORD_CWORD,
3100         /*  70  "F" */ CWORD_CWORD_CWORD_CWORD,
3101         /*  71  "G" */ CWORD_CWORD_CWORD_CWORD,
3102         /*  72  "H" */ CWORD_CWORD_CWORD_CWORD,
3103         /*  73  "I" */ CWORD_CWORD_CWORD_CWORD,
3104         /*  74  "J" */ CWORD_CWORD_CWORD_CWORD,
3105         /*  75  "K" */ CWORD_CWORD_CWORD_CWORD,
3106         /*  76  "L" */ CWORD_CWORD_CWORD_CWORD,
3107         /*  77  "M" */ CWORD_CWORD_CWORD_CWORD,
3108         /*  78  "N" */ CWORD_CWORD_CWORD_CWORD,
3109         /*  79  "O" */ CWORD_CWORD_CWORD_CWORD,
3110         /*  80  "P" */ CWORD_CWORD_CWORD_CWORD,
3111         /*  81  "Q" */ CWORD_CWORD_CWORD_CWORD,
3112         /*  82  "R" */ CWORD_CWORD_CWORD_CWORD,
3113         /*  83  "S" */ CWORD_CWORD_CWORD_CWORD,
3114         /*  84  "T" */ CWORD_CWORD_CWORD_CWORD,
3115         /*  85  "U" */ CWORD_CWORD_CWORD_CWORD,
3116         /*  86  "V" */ CWORD_CWORD_CWORD_CWORD,
3117         /*  87  "W" */ CWORD_CWORD_CWORD_CWORD,
3118         /*  88  "X" */ CWORD_CWORD_CWORD_CWORD,
3119         /*  89  "Y" */ CWORD_CWORD_CWORD_CWORD,
3120         /*  90  "Z" */ CWORD_CWORD_CWORD_CWORD,
3121         /*  91  "[" */ CWORD_CCTL_CCTL_CWORD,
3122         /*  92  "\" */ CBACK_CBACK_CCTL_CBACK,
3123         /*  93  "]" */ CWORD_CCTL_CCTL_CWORD,
3124         /*  94  "^" */ CWORD_CWORD_CWORD_CWORD,
3125         /*  95  "_" */ CWORD_CWORD_CWORD_CWORD,
3126         /*  96  "`" */ CBQUOTE_CBQUOTE_CWORD_CBQUOTE,
3127         /*  97  "a" */ CWORD_CWORD_CWORD_CWORD,
3128         /*  98  "b" */ CWORD_CWORD_CWORD_CWORD,
3129         /*  99  "c" */ CWORD_CWORD_CWORD_CWORD,
3130         /* 100  "d" */ CWORD_CWORD_CWORD_CWORD,
3131         /* 101  "e" */ CWORD_CWORD_CWORD_CWORD,
3132         /* 102  "f" */ CWORD_CWORD_CWORD_CWORD,
3133         /* 103  "g" */ CWORD_CWORD_CWORD_CWORD,
3134         /* 104  "h" */ CWORD_CWORD_CWORD_CWORD,
3135         /* 105  "i" */ CWORD_CWORD_CWORD_CWORD,
3136         /* 106  "j" */ CWORD_CWORD_CWORD_CWORD,
3137         /* 107  "k" */ CWORD_CWORD_CWORD_CWORD,
3138         /* 108  "l" */ CWORD_CWORD_CWORD_CWORD,
3139         /* 109  "m" */ CWORD_CWORD_CWORD_CWORD,
3140         /* 110  "n" */ CWORD_CWORD_CWORD_CWORD,
3141         /* 111  "o" */ CWORD_CWORD_CWORD_CWORD,
3142         /* 112  "p" */ CWORD_CWORD_CWORD_CWORD,
3143         /* 113  "q" */ CWORD_CWORD_CWORD_CWORD,
3144         /* 114  "r" */ CWORD_CWORD_CWORD_CWORD,
3145         /* 115  "s" */ CWORD_CWORD_CWORD_CWORD,
3146         /* 116  "t" */ CWORD_CWORD_CWORD_CWORD,
3147         /* 117  "u" */ CWORD_CWORD_CWORD_CWORD,
3148         /* 118  "v" */ CWORD_CWORD_CWORD_CWORD,
3149         /* 119  "w" */ CWORD_CWORD_CWORD_CWORD,
3150         /* 120  "x" */ CWORD_CWORD_CWORD_CWORD,
3151         /* 121  "y" */ CWORD_CWORD_CWORD_CWORD,
3152         /* 122  "z" */ CWORD_CWORD_CWORD_CWORD,
3153         /* 123  "{" */ CWORD_CWORD_CWORD_CWORD,
3154         /* 124  "|" */ CSPCL_CWORD_CWORD_CWORD,
3155         /* 125  "}" */ CENDVAR_CENDVAR_CWORD_CENDVAR,
3156         /* 126  "~" */ CWORD_CCTL_CCTL_CWORD,
3157         /* 127  del */ CWORD_CWORD_CWORD_CWORD,
3158         /* 128 0x80 */ CWORD_CWORD_CWORD_CWORD,
3159         /* 129 CTLESC       */ CCTL_CCTL_CCTL_CCTL,
3160         /* 130 CTLVAR       */ CCTL_CCTL_CCTL_CCTL,
3161         /* 131 CTLENDVAR    */ CCTL_CCTL_CCTL_CCTL,
3162         /* 132 CTLBACKQ     */ CCTL_CCTL_CCTL_CCTL,
3163         /* 133 CTLQUOTE     */ CCTL_CCTL_CCTL_CCTL,
3164         /* 134 CTLARI       */ CCTL_CCTL_CCTL_CCTL,
3165         /* 135 CTLENDARI    */ CCTL_CCTL_CCTL_CCTL,
3166         /* 136 CTLQUOTEMARK */ CCTL_CCTL_CCTL_CCTL,
3167         /* 137      */ CWORD_CWORD_CWORD_CWORD,
3168         /* 138      */ CWORD_CWORD_CWORD_CWORD,
3169         /* 139      */ CWORD_CWORD_CWORD_CWORD,
3170         /* 140      */ CWORD_CWORD_CWORD_CWORD,
3171         /* 141      */ CWORD_CWORD_CWORD_CWORD,
3172         /* 142      */ CWORD_CWORD_CWORD_CWORD,
3173         /* 143      */ CWORD_CWORD_CWORD_CWORD,
3174         /* 144      */ CWORD_CWORD_CWORD_CWORD,
3175         /* 145      */ CWORD_CWORD_CWORD_CWORD,
3176         /* 146      */ CWORD_CWORD_CWORD_CWORD,
3177         /* 147      */ CWORD_CWORD_CWORD_CWORD,
3178         /* 148      */ CWORD_CWORD_CWORD_CWORD,
3179         /* 149      */ CWORD_CWORD_CWORD_CWORD,
3180         /* 150      */ CWORD_CWORD_CWORD_CWORD,
3181         /* 151      */ CWORD_CWORD_CWORD_CWORD,
3182         /* 152      */ CWORD_CWORD_CWORD_CWORD,
3183         /* 153      */ CWORD_CWORD_CWORD_CWORD,
3184         /* 154      */ CWORD_CWORD_CWORD_CWORD,
3185         /* 155      */ CWORD_CWORD_CWORD_CWORD,
3186         /* 156      */ CWORD_CWORD_CWORD_CWORD,
3187         /* 157      */ CWORD_CWORD_CWORD_CWORD,
3188         /* 158      */ CWORD_CWORD_CWORD_CWORD,
3189         /* 159      */ CWORD_CWORD_CWORD_CWORD,
3190         /* 160      */ CWORD_CWORD_CWORD_CWORD,
3191         /* 161      */ CWORD_CWORD_CWORD_CWORD,
3192         /* 162      */ CWORD_CWORD_CWORD_CWORD,
3193         /* 163      */ CWORD_CWORD_CWORD_CWORD,
3194         /* 164      */ CWORD_CWORD_CWORD_CWORD,
3195         /* 165      */ CWORD_CWORD_CWORD_CWORD,
3196         /* 166      */ CWORD_CWORD_CWORD_CWORD,
3197         /* 167      */ CWORD_CWORD_CWORD_CWORD,
3198         /* 168      */ CWORD_CWORD_CWORD_CWORD,
3199         /* 169      */ CWORD_CWORD_CWORD_CWORD,
3200         /* 170      */ CWORD_CWORD_CWORD_CWORD,
3201         /* 171      */ CWORD_CWORD_CWORD_CWORD,
3202         /* 172      */ CWORD_CWORD_CWORD_CWORD,
3203         /* 173      */ CWORD_CWORD_CWORD_CWORD,
3204         /* 174      */ CWORD_CWORD_CWORD_CWORD,
3205         /* 175      */ CWORD_CWORD_CWORD_CWORD,
3206         /* 176      */ CWORD_CWORD_CWORD_CWORD,
3207         /* 177      */ CWORD_CWORD_CWORD_CWORD,
3208         /* 178      */ CWORD_CWORD_CWORD_CWORD,
3209         /* 179      */ CWORD_CWORD_CWORD_CWORD,
3210         /* 180      */ CWORD_CWORD_CWORD_CWORD,
3211         /* 181      */ CWORD_CWORD_CWORD_CWORD,
3212         /* 182      */ CWORD_CWORD_CWORD_CWORD,
3213         /* 183      */ CWORD_CWORD_CWORD_CWORD,
3214         /* 184      */ CWORD_CWORD_CWORD_CWORD,
3215         /* 185      */ CWORD_CWORD_CWORD_CWORD,
3216         /* 186      */ CWORD_CWORD_CWORD_CWORD,
3217         /* 187      */ CWORD_CWORD_CWORD_CWORD,
3218         /* 188      */ CWORD_CWORD_CWORD_CWORD,
3219         /* 189      */ CWORD_CWORD_CWORD_CWORD,
3220         /* 190      */ CWORD_CWORD_CWORD_CWORD,
3221         /* 191      */ CWORD_CWORD_CWORD_CWORD,
3222         /* 192      */ CWORD_CWORD_CWORD_CWORD,
3223         /* 193      */ CWORD_CWORD_CWORD_CWORD,
3224         /* 194      */ CWORD_CWORD_CWORD_CWORD,
3225         /* 195      */ CWORD_CWORD_CWORD_CWORD,
3226         /* 196      */ CWORD_CWORD_CWORD_CWORD,
3227         /* 197      */ CWORD_CWORD_CWORD_CWORD,
3228         /* 198      */ CWORD_CWORD_CWORD_CWORD,
3229         /* 199      */ CWORD_CWORD_CWORD_CWORD,
3230         /* 200      */ CWORD_CWORD_CWORD_CWORD,
3231         /* 201      */ CWORD_CWORD_CWORD_CWORD,
3232         /* 202      */ CWORD_CWORD_CWORD_CWORD,
3233         /* 203      */ CWORD_CWORD_CWORD_CWORD,
3234         /* 204      */ CWORD_CWORD_CWORD_CWORD,
3235         /* 205      */ CWORD_CWORD_CWORD_CWORD,
3236         /* 206      */ CWORD_CWORD_CWORD_CWORD,
3237         /* 207      */ CWORD_CWORD_CWORD_CWORD,
3238         /* 208      */ CWORD_CWORD_CWORD_CWORD,
3239         /* 209      */ CWORD_CWORD_CWORD_CWORD,
3240         /* 210      */ CWORD_CWORD_CWORD_CWORD,
3241         /* 211      */ CWORD_CWORD_CWORD_CWORD,
3242         /* 212      */ CWORD_CWORD_CWORD_CWORD,
3243         /* 213      */ CWORD_CWORD_CWORD_CWORD,
3244         /* 214      */ CWORD_CWORD_CWORD_CWORD,
3245         /* 215      */ CWORD_CWORD_CWORD_CWORD,
3246         /* 216      */ CWORD_CWORD_CWORD_CWORD,
3247         /* 217      */ CWORD_CWORD_CWORD_CWORD,
3248         /* 218      */ CWORD_CWORD_CWORD_CWORD,
3249         /* 219      */ CWORD_CWORD_CWORD_CWORD,
3250         /* 220      */ CWORD_CWORD_CWORD_CWORD,
3251         /* 221      */ CWORD_CWORD_CWORD_CWORD,
3252         /* 222      */ CWORD_CWORD_CWORD_CWORD,
3253         /* 223      */ CWORD_CWORD_CWORD_CWORD,
3254         /* 224      */ CWORD_CWORD_CWORD_CWORD,
3255         /* 225      */ CWORD_CWORD_CWORD_CWORD,
3256         /* 226      */ CWORD_CWORD_CWORD_CWORD,
3257         /* 227      */ CWORD_CWORD_CWORD_CWORD,
3258         /* 228      */ CWORD_CWORD_CWORD_CWORD,
3259         /* 229      */ CWORD_CWORD_CWORD_CWORD,
3260         /* 230      */ CWORD_CWORD_CWORD_CWORD,
3261         /* 231      */ CWORD_CWORD_CWORD_CWORD,
3262         /* 232      */ CWORD_CWORD_CWORD_CWORD,
3263         /* 233      */ CWORD_CWORD_CWORD_CWORD,
3264         /* 234      */ CWORD_CWORD_CWORD_CWORD,
3265         /* 235      */ CWORD_CWORD_CWORD_CWORD,
3266         /* 236      */ CWORD_CWORD_CWORD_CWORD,
3267         /* 237      */ CWORD_CWORD_CWORD_CWORD,
3268         /* 238      */ CWORD_CWORD_CWORD_CWORD,
3269         /* 239      */ CWORD_CWORD_CWORD_CWORD,
3270         /* 230      */ CWORD_CWORD_CWORD_CWORD,
3271         /* 241      */ CWORD_CWORD_CWORD_CWORD,
3272         /* 242      */ CWORD_CWORD_CWORD_CWORD,
3273         /* 243      */ CWORD_CWORD_CWORD_CWORD,
3274         /* 244      */ CWORD_CWORD_CWORD_CWORD,
3275         /* 245      */ CWORD_CWORD_CWORD_CWORD,
3276         /* 246      */ CWORD_CWORD_CWORD_CWORD,
3277         /* 247      */ CWORD_CWORD_CWORD_CWORD,
3278         /* 248      */ CWORD_CWORD_CWORD_CWORD,
3279         /* 249      */ CWORD_CWORD_CWORD_CWORD,
3280         /* 250      */ CWORD_CWORD_CWORD_CWORD,
3281         /* 251      */ CWORD_CWORD_CWORD_CWORD,
3282         /* 252      */ CWORD_CWORD_CWORD_CWORD,
3283         /* 253      */ CWORD_CWORD_CWORD_CWORD,
3284         /* 254      */ CWORD_CWORD_CWORD_CWORD,
3285         /* 255      */ CWORD_CWORD_CWORD_CWORD,
3286         /* PEOF */     CENDFILE_CENDFILE_CENDFILE_CENDFILE,
3287 # if ENABLE_ASH_ALIAS
3288         /* PEOA */     CSPCL_CIGN_CIGN_CIGN,
3289 # endif
3290 };
3291
3292 #if 1
3293 # define SIT(c, syntax) ((S_I_T[syntax_index_table[c]] >> ((syntax)*4)) & 0xf)
3294 #else /* debug version, caught one signed char bug */
3295 # define SIT(c, syntax) \
3296         ({ \
3297                 if ((c) < 0 || (c) > (PEOF + ENABLE_ASH_ALIAS)) \
3298                         bb_error_msg_and_die("line:%d c:%d", __LINE__, (c)); \
3299                 if ((syntax) < 0 || (syntax) > (2 + ENABLE_FEATURE_SH_MATH)) \
3300                         bb_error_msg_and_die("line:%d c:%d", __LINE__, (c)); \
3301                 ((S_I_T[syntax_index_table[c]] >> ((syntax)*4)) & 0xf); \
3302         })
3303 #endif
3304
3305 #endif  /* !USE_SIT_FUNCTION */
3306
3307
3308 /* ============ Alias handling */
3309
3310 #if ENABLE_ASH_ALIAS
3311
3312 #define ALIASINUSE 1
3313 #define ALIASDEAD  2
3314
3315 struct alias {
3316         struct alias *next;
3317         char *name;
3318         char *val;
3319         int flag;
3320 };
3321
3322
3323 static struct alias **atab; // [ATABSIZE];
3324 #define INIT_G_alias() do { \
3325         atab = xzalloc(ATABSIZE * sizeof(atab[0])); \
3326 } while (0)
3327
3328
3329 static struct alias **
3330 __lookupalias(const char *name)
3331 {
3332         unsigned int hashval;
3333         struct alias **app;
3334         const char *p;
3335         unsigned int ch;
3336
3337         p = name;
3338
3339         ch = (unsigned char)*p;
3340         hashval = ch << 4;
3341         while (ch) {
3342                 hashval += ch;
3343                 ch = (unsigned char)*++p;
3344         }
3345         app = &atab[hashval % ATABSIZE];
3346
3347         for (; *app; app = &(*app)->next) {
3348                 if (strcmp(name, (*app)->name) == 0) {
3349                         break;
3350                 }
3351         }
3352
3353         return app;
3354 }
3355
3356 static struct alias *
3357 lookupalias(const char *name, int check)
3358 {
3359         struct alias *ap = *__lookupalias(name);
3360
3361         if (check && ap && (ap->flag & ALIASINUSE))
3362                 return NULL;
3363         return ap;
3364 }
3365
3366 static struct alias *
3367 freealias(struct alias *ap)
3368 {
3369         struct alias *next;
3370
3371         if (ap->flag & ALIASINUSE) {
3372                 ap->flag |= ALIASDEAD;
3373                 return ap;
3374         }
3375
3376         next = ap->next;
3377         free(ap->name);
3378         free(ap->val);
3379         free(ap);
3380         return next;
3381 }
3382
3383 static void
3384 setalias(const char *name, const char *val)
3385 {
3386         struct alias *ap, **app;
3387
3388         app = __lookupalias(name);
3389         ap = *app;
3390         INT_OFF;
3391         if (ap) {
3392                 if (!(ap->flag & ALIASINUSE)) {
3393                         free(ap->val);
3394                 }
3395                 ap->val = ckstrdup(val);
3396                 ap->flag &= ~ALIASDEAD;
3397         } else {
3398                 /* not found */
3399                 ap = ckzalloc(sizeof(struct alias));
3400                 ap->name = ckstrdup(name);
3401                 ap->val = ckstrdup(val);
3402                 /*ap->flag = 0; - ckzalloc did it */
3403                 /*ap->next = NULL;*/
3404                 *app = ap;
3405         }
3406         INT_ON;
3407 }
3408
3409 static int
3410 unalias(const char *name)
3411 {
3412         struct alias **app;
3413
3414         app = __lookupalias(name);
3415
3416         if (*app) {
3417                 INT_OFF;
3418                 *app = freealias(*app);
3419                 INT_ON;
3420                 return 0;
3421         }
3422
3423         return 1;
3424 }
3425
3426 static void
3427 rmaliases(void)
3428 {
3429         struct alias *ap, **app;
3430         int i;
3431
3432         INT_OFF;
3433         for (i = 0; i < ATABSIZE; i++) {
3434                 app = &atab[i];
3435                 for (ap = *app; ap; ap = *app) {
3436                         *app = freealias(*app);
3437                         if (ap == *app) {
3438                                 app = &ap->next;
3439                         }
3440                 }
3441         }
3442         INT_ON;
3443 }
3444
3445 static void
3446 printalias(const struct alias *ap)
3447 {
3448         out1fmt("%s=%s\n", ap->name, single_quote(ap->val));
3449 }
3450
3451 /*
3452  * TODO - sort output
3453  */
3454 static int FAST_FUNC
3455 aliascmd(int argc UNUSED_PARAM, char **argv)
3456 {
3457         char *n, *v;
3458         int ret = 0;
3459         struct alias *ap;
3460
3461         if (!argv[1]) {
3462                 int i;
3463
3464                 for (i = 0; i < ATABSIZE; i++) {
3465                         for (ap = atab[i]; ap; ap = ap->next) {
3466                                 printalias(ap);
3467                         }
3468                 }
3469                 return 0;
3470         }
3471         while ((n = *++argv) != NULL) {
3472                 v = strchr(n+1, '=');
3473                 if (v == NULL) { /* n+1: funny ksh stuff */
3474                         ap = *__lookupalias(n);
3475                         if (ap == NULL) {
3476                                 fprintf(stderr, "%s: %s not found\n", "alias", n);
3477                                 ret = 1;
3478                         } else
3479                                 printalias(ap);
3480                 } else {
3481                         *v++ = '\0';
3482                         setalias(n, v);
3483                 }
3484         }
3485
3486         return ret;
3487 }
3488
3489 static int FAST_FUNC
3490 unaliascmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
3491 {
3492         int i;
3493
3494         while (nextopt("a") != '\0') {
3495                 rmaliases();
3496                 return 0;
3497         }
3498         for (i = 0; *argptr; argptr++) {
3499                 if (unalias(*argptr)) {
3500                         fprintf(stderr, "%s: %s not found\n", "unalias", *argptr);
3501                         i = 1;
3502                 }
3503         }
3504
3505         return i;
3506 }
3507
3508 #endif /* ASH_ALIAS */
3509
3510
3511 /* Mode argument to forkshell.  Don't change FORK_FG or FORK_BG. */
3512 #define FORK_FG    0
3513 #define FORK_BG    1
3514 #define FORK_NOJOB 2
3515
3516 /* mode flags for showjob(s) */
3517 #define SHOW_ONLY_PGID  0x01    /* show only pgid (jobs -p) */
3518 #define SHOW_PIDS       0x02    /* show individual pids, not just one line per job */
3519 #define SHOW_CHANGED    0x04    /* only jobs whose state has changed */
3520 #define SHOW_STDERR     0x08    /* print to stderr (else stdout) */
3521
3522 /*
3523  * A job structure contains information about a job.  A job is either a
3524  * single process or a set of processes contained in a pipeline.  In the
3525  * latter case, pidlist will be non-NULL, and will point to a -1 terminated
3526  * array of pids.
3527  */
3528 struct procstat {
3529         pid_t   ps_pid;         /* process id */
3530         int     ps_status;      /* last process status from wait() */
3531         char    *ps_cmd;        /* text of command being run */
3532 };
3533
3534 struct job {
3535         struct procstat ps0;    /* status of process */
3536         struct procstat *ps;    /* status or processes when more than one */
3537 #if JOBS
3538         int stopstatus;         /* status of a stopped job */
3539 #endif
3540         unsigned nprocs;        /* number of processes */
3541
3542 #define JOBRUNNING      0       /* at least one proc running */
3543 #define JOBSTOPPED      1       /* all procs are stopped */
3544 #define JOBDONE         2       /* all procs are completed */
3545         unsigned
3546                 state: 8,
3547 #if JOBS
3548                 sigint: 1,      /* job was killed by SIGINT */
3549                 jobctl: 1,      /* job running under job control */
3550 #endif
3551                 waited: 1,      /* true if this entry has been waited for */
3552                 used: 1,        /* true if this entry is in used */
3553                 changed: 1;     /* true if status has changed */
3554         struct job *prev_job;   /* previous job */
3555 };
3556
3557 static struct job *makejob(/*union node *,*/ int);
3558 static int forkshell(struct job *, union node *, int);
3559 static int waitforjob(struct job *);
3560
3561 #if !JOBS
3562 enum { doing_jobctl = 0 };
3563 #define setjobctl(on) do {} while (0)
3564 #else
3565 static smallint doing_jobctl; //references:8
3566 static void setjobctl(int);
3567 #endif
3568
3569 /*
3570  * Ignore a signal.
3571  */
3572 static void
3573 ignoresig(int signo)
3574 {
3575         /* Avoid unnecessary system calls. Is it already SIG_IGNed? */
3576         if (sigmode[signo - 1] != S_IGN && sigmode[signo - 1] != S_HARD_IGN) {
3577                 /* No, need to do it */
3578                 signal(signo, SIG_IGN);
3579         }
3580         sigmode[signo - 1] = S_HARD_IGN;
3581 }
3582
3583 /*
3584  * Only one usage site - in setsignal()
3585  */
3586 static void
3587 signal_handler(int signo)
3588 {
3589         if (signo == SIGCHLD) {
3590                 got_sigchld = 1;
3591                 if (!trap[SIGCHLD])
3592                         return;
3593         }
3594
3595         gotsig[signo - 1] = 1;
3596         pending_sig = signo;
3597
3598         if (signo == SIGINT && !trap[SIGINT]) {
3599                 if (!suppress_int) {
3600                         pending_sig = 0;
3601                         raise_interrupt(); /* does not return */
3602                 }
3603                 pending_int = 1;
3604         }
3605 }
3606
3607 /*
3608  * Set the signal handler for the specified signal.  The routine figures
3609  * out what it should be set to.
3610  */
3611 static void
3612 setsignal(int signo)
3613 {
3614         char *t;
3615         char cur_act, new_act;
3616         struct sigaction act;
3617
3618         t = trap[signo];
3619         new_act = S_DFL;
3620         if (t != NULL) { /* trap for this sig is set */
3621                 new_act = S_CATCH;
3622                 if (t[0] == '\0') /* trap is "": ignore this sig */
3623                         new_act = S_IGN;
3624         }
3625
3626         if (rootshell && new_act == S_DFL) {
3627                 switch (signo) {
3628                 case SIGINT:
3629                         if (iflag || minusc || sflag == 0)
3630                                 new_act = S_CATCH;
3631                         break;
3632                 case SIGQUIT:
3633 #if DEBUG
3634                         if (debug)
3635                                 break;
3636 #endif
3637                         /* man bash:
3638                          * "In all cases, bash ignores SIGQUIT. Non-builtin
3639                          * commands run by bash have signal handlers
3640                          * set to the values inherited by the shell
3641                          * from its parent". */
3642                         new_act = S_IGN;
3643                         break;
3644                 case SIGTERM:
3645                         if (iflag)
3646                                 new_act = S_IGN;
3647                         break;
3648 #if JOBS
3649                 case SIGTSTP:
3650                 case SIGTTOU:
3651                         if (mflag)
3652                                 new_act = S_IGN;
3653                         break;
3654 #endif
3655                 }
3656         }
3657         /* if !rootshell, we reset SIGQUIT to DFL,
3658          * whereas we have to restore it to what shell got on entry.
3659          * This is handled by the fact that if signal was IGNored on entry,
3660          * then cur_act is S_HARD_IGN and we never change its sigaction
3661          * (see code below).
3662          */
3663
3664         if (signo == SIGCHLD)
3665                 new_act = S_CATCH;
3666
3667         t = &sigmode[signo - 1];
3668         cur_act = *t;
3669         if (cur_act == 0) {
3670                 /* current setting is not yet known */
3671                 if (sigaction(signo, NULL, &act)) {
3672                         /* pretend it worked; maybe we should give a warning,
3673                          * but other shells don't. We don't alter sigmode,
3674                          * so we retry every time.
3675                          * btw, in Linux it never fails. --vda */
3676                         return;
3677                 }
3678                 if (act.sa_handler == SIG_IGN) {
3679                         cur_act = S_HARD_IGN;
3680                         if (mflag
3681                          && (signo == SIGTSTP || signo == SIGTTIN || signo == SIGTTOU)
3682                         ) {
3683                                 cur_act = S_IGN;   /* don't hard ignore these */
3684                         }
3685                 }
3686                 if (act.sa_handler == SIG_DFL && new_act == S_DFL) {
3687                         /* installing SIG_DFL over SIG_DFL is a no-op */
3688                         /* saves one sigaction call in each "sh -c SCRIPT" invocation */
3689                         *t = S_DFL;
3690                         return;
3691                 }
3692         }
3693         if (cur_act == S_HARD_IGN || cur_act == new_act)
3694                 return;
3695
3696         *t = new_act;
3697
3698         act.sa_handler = SIG_DFL;
3699         switch (new_act) {
3700         case S_CATCH:
3701                 act.sa_handler = signal_handler;
3702                 break;
3703         case S_IGN:
3704                 act.sa_handler = SIG_IGN;
3705                 break;
3706         }
3707         /* flags and mask matter only if !DFL and !IGN, but we do it
3708          * for all cases for more deterministic behavior:
3709          */
3710         act.sa_flags = 0; //TODO: why not SA_RESTART?
3711         sigfillset(&act.sa_mask);
3712
3713         sigaction_set(signo, &act);
3714 }
3715
3716 /* mode flags for set_curjob */
3717 #define CUR_DELETE 2
3718 #define CUR_RUNNING 1
3719 #define CUR_STOPPED 0
3720
3721 #if JOBS
3722 /* pgrp of shell on invocation */
3723 static int initialpgrp; //references:2
3724 static int ttyfd = -1; //5
3725 #endif
3726 /* array of jobs */
3727 static struct job *jobtab; //5
3728 /* size of array */
3729 static unsigned njobs; //4
3730 /* current job */
3731 static struct job *curjob; //lots
3732 /* number of presumed living untracked jobs */
3733 static int jobless; //4
3734
3735 #if 0
3736 /* Bash has a feature: it restores termios after a successful wait for
3737  * a foreground job which had at least one stopped or sigkilled member.
3738  * The probable rationale is that SIGSTOP and SIGKILL can preclude task from
3739  * properly restoring tty state. Should we do this too?
3740  * A reproducer: ^Z an interactive python:
3741  *
3742  * # python
3743  * Python 2.7.12 (...)
3744  * >>> ^Z
3745  *      { python leaves tty in -icanon -echo state. We do survive that... }
3746  *  [1]+  Stopped                    python
3747  *      { ...however, next program (python #2) does not survive it well: }
3748  * # python
3749  * Python 2.7.12 (...)
3750  * >>> Traceback (most recent call last):
3751  *      { above, I typed "qwerty<CR>", but -echo state is still in effect }
3752  *   File "<stdin>", line 1, in <module>
3753  * NameError: name 'qwerty' is not defined
3754  *
3755  * The implementation below is modeled on bash code and seems to work.
3756  * However, I'm not sure we should do this. For one: what if I'd fg
3757  * the stopped python instead? It'll be confused by "restored" tty state.
3758  */
3759 static struct termios shell_tty_info;
3760 static void
3761 get_tty_state(void)
3762 {
3763         if (rootshell && ttyfd >= 0)
3764                 tcgetattr(ttyfd, &shell_tty_info);
3765 }
3766 static void
3767 set_tty_state(void)
3768 {
3769         /* if (rootshell) - caller ensures this */
3770         if (ttyfd >= 0)
3771                 tcsetattr(ttyfd, TCSADRAIN, &shell_tty_info);
3772 }
3773 static int
3774 job_signal_status(struct job *jp)
3775 {
3776         int status;
3777         unsigned i;
3778         struct procstat *ps = jp->ps;
3779         for (i = 0; i < jp->nprocs; i++) {
3780                 status = ps[i].ps_status;
3781                 if (WIFSIGNALED(status) || WIFSTOPPED(status))
3782                         return status;
3783         }
3784         return 0;
3785 }
3786 static void
3787 restore_tty_if_stopped_or_signaled(struct job *jp)
3788 {
3789 //TODO: check what happens if we come from waitforjob() in expbackq()
3790         if (rootshell) {
3791                 int s = job_signal_status(jp);
3792                 if (s) /* WIFSIGNALED(s) || WIFSTOPPED(s) */
3793                         set_tty_state();
3794         }
3795 }
3796 #else
3797 # define get_tty_state() ((void)0)
3798 # define restore_tty_if_stopped_or_signaled(jp) ((void)0)
3799 #endif
3800
3801 static void
3802 set_curjob(struct job *jp, unsigned mode)
3803 {
3804         struct job *jp1;
3805         struct job **jpp, **curp;
3806
3807         /* first remove from list */
3808         jpp = curp = &curjob;
3809         while (1) {
3810                 jp1 = *jpp;
3811                 if (jp1 == jp)
3812                         break;
3813                 jpp = &jp1->prev_job;
3814         }
3815         *jpp = jp1->prev_job;
3816
3817         /* Then re-insert in correct position */
3818         jpp = curp;
3819         switch (mode) {
3820         default:
3821 #if DEBUG
3822                 abort();
3823 #endif
3824         case CUR_DELETE:
3825                 /* job being deleted */
3826                 break;
3827         case CUR_RUNNING:
3828                 /* newly created job or backgrounded job,
3829                  * put after all stopped jobs.
3830                  */
3831                 while (1) {
3832                         jp1 = *jpp;
3833 #if JOBS
3834                         if (!jp1 || jp1->state != JOBSTOPPED)
3835 #endif
3836                                 break;
3837                         jpp = &jp1->prev_job;
3838                 }
3839                 /* FALLTHROUGH */
3840 #if JOBS
3841         case CUR_STOPPED:
3842 #endif
3843                 /* newly stopped job - becomes curjob */
3844                 jp->prev_job = *jpp;
3845                 *jpp = jp;
3846                 break;
3847         }
3848 }
3849
3850 #if JOBS || DEBUG
3851 static int
3852 jobno(const struct job *jp)
3853 {
3854         return jp - jobtab + 1;
3855 }
3856 #endif
3857
3858 /*
3859  * Convert a job name to a job structure.
3860  */
3861 #if !JOBS
3862 #define getjob(name, getctl) getjob(name)
3863 #endif
3864 static struct job *
3865 getjob(const char *name, int getctl)
3866 {
3867         struct job *jp;
3868         struct job *found;
3869         const char *err_msg = "%s: no such job";
3870         unsigned num;
3871         int c;
3872         const char *p;
3873         char *(*match)(const char *, const char *);
3874
3875         jp = curjob;
3876         p = name;
3877         if (!p)
3878                 goto currentjob;
3879
3880         if (*p != '%')
3881                 goto err;
3882
3883         c = *++p;
3884         if (!c)
3885                 goto currentjob;
3886
3887         if (!p[1]) {
3888                 if (c == '+' || c == '%') {
3889  currentjob:
3890                         err_msg = "No current job";
3891                         goto check;
3892                 }
3893                 if (c == '-') {
3894                         if (jp)
3895                                 jp = jp->prev_job;
3896                         err_msg = "No previous job";
3897  check:
3898                         if (!jp)
3899                                 goto err;
3900                         goto gotit;
3901                 }
3902         }
3903
3904         if (is_number(p)) {
3905                 num = atoi(p);
3906                 if (num > 0 && num <= njobs) {
3907                         jp = jobtab + num - 1;
3908                         if (jp->used)
3909                                 goto gotit;
3910                         goto err;
3911                 }
3912         }
3913
3914         match = prefix;
3915         if (*p == '?') {
3916                 match = strstr;
3917                 p++;
3918         }
3919
3920         found = NULL;
3921         while (jp) {
3922                 if (match(jp->ps[0].ps_cmd, p)) {
3923                         if (found)
3924                                 goto err;
3925                         found = jp;
3926                         err_msg = "%s: ambiguous";
3927                 }
3928                 jp = jp->prev_job;
3929         }
3930         if (!found)
3931                 goto err;
3932         jp = found;
3933
3934  gotit:
3935 #if JOBS
3936         err_msg = "job %s not created under job control";
3937         if (getctl && jp->jobctl == 0)
3938                 goto err;
3939 #endif
3940         return jp;
3941  err:
3942         ash_msg_and_raise_error(err_msg, name);
3943 }
3944
3945 /*
3946  * Mark a job structure as unused.
3947  */
3948 static void
3949 freejob(struct job *jp)
3950 {
3951         struct procstat *ps;
3952         int i;
3953
3954         INT_OFF;
3955         for (i = jp->nprocs, ps = jp->ps; --i >= 0; ps++) {
3956                 if (ps->ps_cmd != nullstr)
3957                         free(ps->ps_cmd);
3958         }
3959         if (jp->ps != &jp->ps0)
3960                 free(jp->ps);
3961         jp->used = 0;
3962         set_curjob(jp, CUR_DELETE);
3963         INT_ON;
3964 }
3965
3966 #if JOBS
3967 static void
3968 xtcsetpgrp(int fd, pid_t pgrp)
3969 {
3970         if (tcsetpgrp(fd, pgrp))
3971                 ash_msg_and_raise_perror("can't set tty process group");
3972 }
3973
3974 /*
3975  * Turn job control on and off.
3976  *
3977  * Note:  This code assumes that the third arg to ioctl is a character
3978  * pointer, which is true on Berkeley systems but not System V.  Since
3979  * System V doesn't have job control yet, this isn't a problem now.
3980  *
3981  * Called with interrupts off.
3982  */
3983 static void
3984 setjobctl(int on)
3985 {
3986         int fd;
3987         int pgrp;
3988
3989         if (on == doing_jobctl || rootshell == 0)
3990                 return;
3991         if (on) {
3992                 int ofd;
3993                 ofd = fd = open(_PATH_TTY, O_RDWR);
3994                 if (fd < 0) {
3995         /* BTW, bash will try to open(ttyname(0)) if open("/dev/tty") fails.
3996          * That sometimes helps to acquire controlling tty.
3997          * Obviously, a workaround for bugs when someone
3998          * failed to provide a controlling tty to bash! :) */
3999                         fd = 2;
4000                         while (!isatty(fd))
4001                                 if (--fd < 0)
4002                                         goto out;
4003                 }
4004                 /* fd is a tty at this point */
4005                 fd = fcntl(fd, F_DUPFD_CLOEXEC, 10);
4006                 if (ofd >= 0) /* if it is "/dev/tty", close. If 0/1/2, don't */
4007                         close(ofd);
4008                 if (fd < 0)
4009                         goto out; /* F_DUPFD failed */
4010                 if (F_DUPFD_CLOEXEC == F_DUPFD) /* if old libc (w/o F_DUPFD_CLOEXEC) */
4011                         close_on_exec_on(fd);
4012                 while (1) { /* while we are in the background */
4013                         pgrp = tcgetpgrp(fd);
4014                         if (pgrp < 0) {
4015  out:
4016                                 ash_msg("can't access tty; job control turned off");
4017                                 mflag = on = 0;
4018                                 goto close;
4019                         }
4020                         if (pgrp == getpgrp())
4021                                 break;
4022                         killpg(0, SIGTTIN);
4023                 }
4024                 initialpgrp = pgrp;
4025
4026                 setsignal(SIGTSTP);
4027                 setsignal(SIGTTOU);
4028                 setsignal(SIGTTIN);
4029                 pgrp = rootpid;
4030                 setpgid(0, pgrp);
4031                 xtcsetpgrp(fd, pgrp);
4032         } else {
4033                 /* turning job control off */
4034                 fd = ttyfd;
4035                 pgrp = initialpgrp;
4036                 /* was xtcsetpgrp, but this can make exiting ash
4037                  * loop forever if pty is already deleted */
4038                 tcsetpgrp(fd, pgrp);
4039                 setpgid(0, pgrp);
4040                 setsignal(SIGTSTP);
4041                 setsignal(SIGTTOU);
4042                 setsignal(SIGTTIN);
4043  close:
4044                 if (fd >= 0)
4045                         close(fd);
4046                 fd = -1;
4047         }
4048         ttyfd = fd;
4049         doing_jobctl = on;
4050 }
4051
4052 static int FAST_FUNC
4053 killcmd(int argc, char **argv)
4054 {
4055         if (argv[1] && strcmp(argv[1], "-l") != 0) {
4056                 int i = 1;
4057                 do {
4058                         if (argv[i][0] == '%') {
4059                                 /*
4060                                  * "kill %N" - job kill
4061                                  * Converting to pgrp / pid kill
4062                                  */
4063                                 struct job *jp;
4064                                 char *dst;
4065                                 int j, n;
4066
4067                                 jp = getjob(argv[i], 0);
4068                                 /*
4069                                  * In jobs started under job control, we signal
4070                                  * entire process group by kill -PGRP_ID.
4071                                  * This happens, f.e., in interactive shell.
4072                                  *
4073                                  * Otherwise, we signal each child via
4074                                  * kill PID1 PID2 PID3.
4075                                  * Testcases:
4076                                  * sh -c 'sleep 1|sleep 1 & kill %1'
4077                                  * sh -c 'true|sleep 2 & sleep 1; kill %1'
4078                                  * sh -c 'true|sleep 1 & sleep 2; kill %1'
4079                                  */
4080                                 n = jp->nprocs; /* can't be 0 (I hope) */
4081                                 if (jp->jobctl)
4082                                         n = 1;
4083                                 dst = alloca(n * sizeof(int)*4);
4084                                 argv[i] = dst;
4085                                 for (j = 0; j < n; j++) {
4086                                         struct procstat *ps = &jp->ps[j];
4087                                         /* Skip non-running and not-stopped members
4088                                          * (i.e. dead members) of the job
4089                                          */
4090                                         if (ps->ps_status != -1 && !WIFSTOPPED(ps->ps_status))
4091                                                 continue;
4092                                         /*
4093                                          * kill_main has matching code to expect
4094                                          * leading space. Needed to not confuse
4095                                          * negative pids with "kill -SIGNAL_NO" syntax
4096                                          */
4097                                         dst += sprintf(dst, jp->jobctl ? " -%u" : " %u", (int)ps->ps_pid);
4098                                 }
4099                                 *dst = '\0';
4100                         }
4101                 } while (argv[++i]);
4102         }
4103         return kill_main(argc, argv);
4104 }
4105
4106 static void
4107 showpipe(struct job *jp /*, FILE *out*/)
4108 {
4109         struct procstat *ps;
4110         struct procstat *psend;
4111
4112         psend = jp->ps + jp->nprocs;
4113         for (ps = jp->ps + 1; ps < psend; ps++)
4114                 printf(" | %s", ps->ps_cmd);
4115         newline_and_flush(stdout);
4116         flush_stdout_stderr();
4117 }
4118
4119
4120 static int
4121 restartjob(struct job *jp, int mode)
4122 {
4123         struct procstat *ps;
4124         int i;
4125         int status;
4126         pid_t pgid;
4127
4128         INT_OFF;
4129         if (jp->state == JOBDONE)
4130                 goto out;
4131         jp->state = JOBRUNNING;
4132         pgid = jp->ps[0].ps_pid;
4133         if (mode == FORK_FG) {
4134                 get_tty_state();
4135                 xtcsetpgrp(ttyfd, pgid);
4136         }
4137         killpg(pgid, SIGCONT);
4138         ps = jp->ps;
4139         i = jp->nprocs;
4140         do {
4141                 if (WIFSTOPPED(ps->ps_status)) {
4142                         ps->ps_status = -1;
4143                 }
4144                 ps++;
4145         } while (--i);
4146  out:
4147         status = (mode == FORK_FG) ? waitforjob(jp) : 0;
4148         INT_ON;
4149         return status;
4150 }
4151
4152 static int FAST_FUNC
4153 fg_bgcmd(int argc UNUSED_PARAM, char **argv)
4154 {
4155         struct job *jp;
4156         int mode;
4157         int retval;
4158
4159         mode = (**argv == 'f') ? FORK_FG : FORK_BG;
4160         nextopt(nullstr);
4161         argv = argptr;
4162         do {
4163                 jp = getjob(*argv, 1);
4164                 if (mode == FORK_BG) {
4165                         set_curjob(jp, CUR_RUNNING);
4166                         printf("[%d] ", jobno(jp));
4167                 }
4168                 out1str(jp->ps[0].ps_cmd);
4169                 showpipe(jp /*, stdout*/);
4170                 retval = restartjob(jp, mode);
4171         } while (*argv && *++argv);
4172         return retval;
4173 }
4174 #endif
4175
4176 static int
4177 sprint_status48(char *s, int status, int sigonly)
4178 {
4179         int col;
4180         int st;
4181
4182         col = 0;
4183         if (!WIFEXITED(status)) {
4184 #if JOBS
4185                 if (WIFSTOPPED(status))
4186                         st = WSTOPSIG(status);
4187                 else
4188 #endif
4189                         st = WTERMSIG(status);
4190                 if (sigonly) {
4191                         if (st == SIGINT || st == SIGPIPE)
4192                                 goto out;
4193 #if JOBS
4194                         if (WIFSTOPPED(status))
4195                                 goto out;
4196 #endif
4197                 }
4198                 st &= 0x7f;
4199 //TODO: use bbox's get_signame? strsignal adds ~600 bytes to text+rodata
4200                 col = fmtstr(s, 32, strsignal(st));
4201                 if (WCOREDUMP(status)) {
4202                         strcpy(s + col, " (core dumped)");
4203                         col += sizeof(" (core dumped)")-1;
4204                 }
4205         } else if (!sigonly) {
4206                 st = WEXITSTATUS(status);
4207                 col = fmtstr(s, 16, (st ? "Done(%d)" : "Done"), st);
4208         }
4209  out:
4210         return col;
4211 }
4212
4213 static int
4214 wait_block_or_sig(int *status)
4215 {
4216         int pid;
4217
4218         do {
4219                 sigset_t mask;
4220
4221                 /* Poll all children for changes in their state */
4222                 got_sigchld = 0;
4223                 /* if job control is active, accept stopped processes too */
4224                 pid = waitpid(-1, status, doing_jobctl ? (WNOHANG|WUNTRACED) : WNOHANG);
4225                 if (pid != 0)
4226                         break; /* Error (e.g. EINTR, ECHILD) or pid */
4227
4228                 /* Children exist, but none are ready. Sleep until interesting signal */
4229 #if 1
4230                 sigfillset(&mask);
4231                 sigprocmask(SIG_SETMASK, &mask, &mask);
4232                 while (!got_sigchld && !pending_sig)
4233                         sigsuspend(&mask);
4234                 sigprocmask(SIG_SETMASK, &mask, NULL);
4235 #else /* unsafe: a signal can set pending_sig after check, but before pause() */
4236                 while (!got_sigchld && !pending_sig)
4237                         pause();
4238 #endif
4239
4240                 /* If it was SIGCHLD, poll children again */
4241         } while (got_sigchld);
4242
4243         return pid;
4244 }
4245
4246 #define DOWAIT_NONBLOCK 0
4247 #define DOWAIT_BLOCK    1
4248 #define DOWAIT_BLOCK_OR_SIG 2
4249
4250 static int
4251 dowait(int block, struct job *job)
4252 {
4253         int pid;
4254         int status;
4255         struct job *jp;
4256         struct job *thisjob = NULL;
4257
4258         TRACE(("dowait(0x%x) called\n", block));
4259
4260         /* It's wrong to call waitpid() outside of INT_OFF region:
4261          * signal can arrive just after syscall return and handler can
4262          * longjmp away, losing stop/exit notification processing.
4263          * Thus, for "jobs" builtin, and for waiting for a fg job,
4264          * we call waitpid() (blocking or non-blocking) inside INT_OFF.
4265          *
4266          * However, for "wait" builtin it is wrong to simply call waitpid()
4267          * in INT_OFF region: "wait" needs to wait for any running job
4268          * to change state, but should exit on any trap too.
4269          * In INT_OFF region, a signal just before syscall entry can set
4270          * pending_sig variables, but we can't check them, and we would
4271          * either enter a sleeping waitpid() (BUG), or need to busy-loop.
4272          *
4273          * Because of this, we run inside INT_OFF, but use a special routine
4274          * which combines waitpid() and sigsuspend().
4275          * This is the reason why we need to have a handler for SIGCHLD:
4276          * SIG_DFL handler does not wake sigsuspend().
4277          */
4278         INT_OFF;
4279         if (block == DOWAIT_BLOCK_OR_SIG) {
4280                 pid = wait_block_or_sig(&status);
4281         } else {
4282                 int wait_flags = 0;
4283                 if (block == DOWAIT_NONBLOCK)
4284                         wait_flags = WNOHANG;
4285                 /* if job control is active, accept stopped processes too */
4286                 if (doing_jobctl)
4287                         wait_flags |= WUNTRACED;
4288                 /* NB: _not_ safe_waitpid, we need to detect EINTR */
4289                 pid = waitpid(-1, &status, wait_flags);
4290         }
4291         TRACE(("wait returns pid=%d, status=0x%x, errno=%d(%s)\n",
4292                                 pid, status, errno, strerror(errno)));
4293         if (pid <= 0)
4294                 goto out;
4295
4296         thisjob = NULL;
4297         for (jp = curjob; jp; jp = jp->prev_job) {
4298                 int jobstate;
4299                 struct procstat *ps;
4300                 struct procstat *psend;
4301                 if (jp->state == JOBDONE)
4302                         continue;
4303                 jobstate = JOBDONE;
4304                 ps = jp->ps;
4305                 psend = ps + jp->nprocs;
4306                 do {
4307                         if (ps->ps_pid == pid) {
4308                                 TRACE(("Job %d: changing status of proc %d "
4309                                         "from 0x%x to 0x%x\n",
4310                                         jobno(jp), pid, ps->ps_status, status));
4311                                 ps->ps_status = status;
4312                                 thisjob = jp;
4313                         }
4314                         if (ps->ps_status == -1)
4315                                 jobstate = JOBRUNNING;
4316 #if JOBS
4317                         if (jobstate == JOBRUNNING)
4318                                 continue;
4319                         if (WIFSTOPPED(ps->ps_status)) {
4320                                 jp->stopstatus = ps->ps_status;
4321                                 jobstate = JOBSTOPPED;
4322                         }
4323 #endif
4324                 } while (++ps < psend);
4325                 if (!thisjob)
4326                         continue;
4327
4328                 /* Found the job where one of its processes changed its state.
4329                  * Is there at least one live and running process in this job? */
4330                 if (jobstate != JOBRUNNING) {
4331                         /* No. All live processes in the job are stopped
4332                          * (JOBSTOPPED) or there are no live processes (JOBDONE)
4333                          */
4334                         thisjob->changed = 1;
4335                         if (thisjob->state != jobstate) {
4336                                 TRACE(("Job %d: changing state from %d to %d\n",
4337                                         jobno(thisjob), thisjob->state, jobstate));
4338                                 thisjob->state = jobstate;
4339 #if JOBS
4340                                 if (jobstate == JOBSTOPPED)
4341                                         set_curjob(thisjob, CUR_STOPPED);
4342 #endif
4343                         }
4344                 }
4345                 goto out;
4346         }
4347         /* The process wasn't found in job list */
4348 #if JOBS
4349         if (!WIFSTOPPED(status))
4350                 jobless--;
4351 #endif
4352  out:
4353         INT_ON;
4354
4355         if (thisjob && thisjob == job) {
4356                 char s[48 + 1];
4357                 int len;
4358
4359                 len = sprint_status48(s, status, 1);
4360                 if (len) {
4361                         s[len] = '\n';
4362                         s[len + 1] = '\0';
4363                         out2str(s);
4364                 }
4365         }
4366         return pid;
4367 }
4368
4369 #if JOBS
4370 static void
4371 showjob(struct job *jp, int mode)
4372 {
4373         struct procstat *ps;
4374         struct procstat *psend;
4375         int col;
4376         int indent_col;
4377         char s[16 + 16 + 48];
4378         FILE *out = (mode & SHOW_STDERR ? stderr : stdout);
4379
4380         ps = jp->ps;
4381
4382         if (mode & SHOW_ONLY_PGID) { /* jobs -p */
4383                 /* just output process (group) id of pipeline */
4384                 fprintf(out, "%d\n", ps->ps_pid);
4385                 return;
4386         }
4387
4388         col = fmtstr(s, 16, "[%d]   ", jobno(jp));
4389         indent_col = col;
4390
4391         if (jp == curjob)
4392                 s[col - 3] = '+';
4393         else if (curjob && jp == curjob->prev_job)
4394                 s[col - 3] = '-';
4395
4396         if (mode & SHOW_PIDS)
4397                 col += fmtstr(s + col, 16, "%d ", ps->ps_pid);
4398
4399         psend = ps + jp->nprocs;
4400
4401         if (jp->state == JOBRUNNING) {
4402                 strcpy(s + col, "Running");
4403                 col += sizeof("Running") - 1;
4404         } else {
4405                 int status = psend[-1].ps_status;
4406                 if (jp->state == JOBSTOPPED)
4407                         status = jp->stopstatus;
4408                 col += sprint_status48(s + col, status, 0);
4409         }
4410         /* By now, "[JOBID]*  [maybe PID] STATUS" is printed */
4411
4412         /* This loop either prints "<cmd1> | <cmd2> | <cmd3>" line
4413          * or prints several "PID             | <cmdN>" lines,
4414          * depending on SHOW_PIDS bit.
4415          * We do not print status of individual processes
4416          * between PID and <cmdN>. bash does it, but not very well:
4417          * first line shows overall job status, not process status,
4418          * making it impossible to know 1st process status.
4419          */
4420         goto start;
4421         do {
4422                 /* for each process */
4423                 s[0] = '\0';
4424                 col = 33;
4425                 if (mode & SHOW_PIDS)
4426                         col = fmtstr(s, 48, "\n%*c%d ", indent_col, ' ', ps->ps_pid) - 1;
4427  start:
4428                 fprintf(out, "%s%*c%s%s",
4429                                 s,
4430                                 33 - col >= 0 ? 33 - col : 0, ' ',
4431                                 ps == jp->ps ? "" : "| ",
4432                                 ps->ps_cmd
4433                 );
4434         } while (++ps != psend);
4435         newline_and_flush(out);
4436
4437         jp->changed = 0;
4438
4439         if (jp->state == JOBDONE) {
4440                 TRACE(("showjob: freeing job %d\n", jobno(jp)));
4441                 freejob(jp);
4442         }
4443 }
4444
4445 /*
4446  * Print a list of jobs.  If "change" is nonzero, only print jobs whose
4447  * statuses have changed since the last call to showjobs.
4448  */
4449 static void
4450 showjobs(int mode)
4451 {
4452         struct job *jp;
4453
4454         TRACE(("showjobs(0x%x) called\n", mode));
4455
4456         /* Handle all finished jobs */
4457         while (dowait(DOWAIT_NONBLOCK, NULL) > 0)
4458                 continue;
4459
4460         for (jp = curjob; jp; jp = jp->prev_job) {
4461                 if (!(mode & SHOW_CHANGED) || jp->changed) {
4462                         showjob(jp, mode);
4463                 }
4464         }
4465 }
4466
4467 static int FAST_FUNC
4468 jobscmd(int argc UNUSED_PARAM, char **argv)
4469 {
4470         int mode, m;
4471
4472         mode = 0;
4473         while ((m = nextopt("lp")) != '\0') {
4474                 if (m == 'l')
4475                         mode |= SHOW_PIDS;
4476                 else
4477                         mode |= SHOW_ONLY_PGID;
4478         }
4479
4480         argv = argptr;
4481         if (*argv) {
4482                 do
4483                         showjob(getjob(*argv, 0), mode);
4484                 while (*++argv);
4485         } else {
4486                 showjobs(mode);
4487         }
4488
4489         return 0;
4490 }
4491 #endif /* JOBS */
4492
4493 /* Called only on finished or stopped jobs (no members are running) */
4494 static int
4495 getstatus(struct job *job)
4496 {
4497         int status;
4498         int retval;
4499         struct procstat *ps;
4500
4501         /* Fetch last member's status */
4502         ps = job->ps + job->nprocs - 1;
4503         status = ps->ps_status;
4504         if (pipefail) {
4505                 /* "set -o pipefail" mode: use last _nonzero_ status */
4506                 while (status == 0 && --ps >= job->ps)
4507                         status = ps->ps_status;
4508         }
4509
4510         retval = WEXITSTATUS(status);
4511         if (!WIFEXITED(status)) {
4512 #if JOBS
4513                 retval = WSTOPSIG(status);
4514                 if (!WIFSTOPPED(status))
4515 #endif
4516                 {
4517                         /* XXX: limits number of signals */
4518                         retval = WTERMSIG(status);
4519 #if JOBS
4520                         if (retval == SIGINT)
4521                                 job->sigint = 1;
4522 #endif
4523                 }
4524                 retval += 128;
4525         }
4526         TRACE(("getstatus: job %d, nproc %d, status 0x%x, retval 0x%x\n",
4527                 jobno(job), job->nprocs, status, retval));
4528         return retval;
4529 }
4530
4531 static int FAST_FUNC
4532 waitcmd(int argc UNUSED_PARAM, char **argv)
4533 {
4534         struct job *job;
4535         int retval;
4536         struct job *jp;
4537
4538         nextopt(nullstr);
4539         retval = 0;
4540
4541         argv = argptr;
4542         if (!*argv) {
4543                 /* wait for all jobs */
4544                 for (;;) {
4545                         jp = curjob;
4546                         while (1) {
4547                                 if (!jp) /* no running procs */
4548                                         goto ret;
4549                                 if (jp->state == JOBRUNNING)
4550                                         break;
4551                                 jp->waited = 1;
4552                                 jp = jp->prev_job;
4553                         }
4554         /* man bash:
4555          * "When bash is waiting for an asynchronous command via
4556          * the wait builtin, the reception of a signal for which a trap
4557          * has been set will cause the wait builtin to return immediately
4558          * with an exit status greater than 128, immediately after which
4559          * the trap is executed."
4560          */
4561                         dowait(DOWAIT_BLOCK_OR_SIG, NULL);
4562         /* if child sends us a signal *and immediately exits*,
4563          * dowait() returns pid > 0. Check this case,
4564          * not "if (dowait() < 0)"!
4565          */
4566                         if (pending_sig)
4567                                 goto sigout;
4568                 }
4569         }
4570
4571         retval = 127;
4572         do {
4573                 if (**argv != '%') {
4574                         pid_t pid = number(*argv);
4575                         job = curjob;
4576                         while (1) {
4577                                 if (!job)
4578                                         goto repeat;
4579                                 if (job->ps[job->nprocs - 1].ps_pid == pid)
4580                                         break;
4581                                 job = job->prev_job;
4582                         }
4583                 } else {
4584                         job = getjob(*argv, 0);
4585                 }
4586                 /* loop until process terminated or stopped */
4587                 while (job->state == JOBRUNNING) {
4588                         dowait(DOWAIT_BLOCK_OR_SIG, NULL);
4589                         if (pending_sig)
4590                                 goto sigout;
4591                 }
4592                 job->waited = 1;
4593                 retval = getstatus(job);
4594  repeat: ;
4595         } while (*++argv);
4596
4597  ret:
4598         return retval;
4599  sigout:
4600         retval = 128 + pending_sig;
4601         return retval;
4602 }
4603
4604 static struct job *
4605 growjobtab(void)
4606 {
4607         size_t len;
4608         ptrdiff_t offset;
4609         struct job *jp, *jq;
4610
4611         len = njobs * sizeof(*jp);
4612         jq = jobtab;
4613         jp = ckrealloc(jq, len + 4 * sizeof(*jp));
4614
4615         offset = (char *)jp - (char *)jq;
4616         if (offset) {
4617                 /* Relocate pointers */
4618                 size_t l = len;
4619
4620                 jq = (struct job *)((char *)jq + l);
4621                 while (l) {
4622                         l -= sizeof(*jp);
4623                         jq--;
4624 #define joff(p) ((struct job *)((char *)(p) + l))
4625 #define jmove(p) (p) = (void *)((char *)(p) + offset)
4626                         if (joff(jp)->ps == &jq->ps0)
4627                                 jmove(joff(jp)->ps);
4628                         if (joff(jp)->prev_job)
4629                                 jmove(joff(jp)->prev_job);
4630                 }
4631                 if (curjob)
4632                         jmove(curjob);
4633 #undef joff
4634 #undef jmove
4635         }
4636
4637         njobs += 4;
4638         jobtab = jp;
4639         jp = (struct job *)((char *)jp + len);
4640         jq = jp + 3;
4641         do {
4642                 jq->used = 0;
4643         } while (--jq >= jp);
4644         return jp;
4645 }
4646
4647 /*
4648  * Return a new job structure.
4649  * Called with interrupts off.
4650  */
4651 static struct job *
4652 makejob(/*union node *node,*/ int nprocs)
4653 {
4654         int i;
4655         struct job *jp;
4656
4657         for (i = njobs, jp = jobtab; ; jp++) {
4658                 if (--i < 0) {
4659                         jp = growjobtab();
4660                         break;
4661                 }
4662                 if (jp->used == 0)
4663                         break;
4664                 if (jp->state != JOBDONE || !jp->waited)
4665                         continue;
4666 #if JOBS
4667                 if (doing_jobctl)
4668                         continue;
4669 #endif
4670                 freejob(jp);
4671                 break;
4672         }
4673         memset(jp, 0, sizeof(*jp));
4674 #if JOBS
4675         /* jp->jobctl is a bitfield.
4676          * "jp->jobctl |= doing_jobctl" likely to give awful code */
4677         if (doing_jobctl)
4678                 jp->jobctl = 1;
4679 #endif
4680         jp->prev_job = curjob;
4681         curjob = jp;
4682         jp->used = 1;
4683         jp->ps = &jp->ps0;
4684         if (nprocs > 1) {
4685                 jp->ps = ckmalloc(nprocs * sizeof(struct procstat));
4686         }
4687         TRACE(("makejob(%d) returns %%%d\n", nprocs,
4688                                 jobno(jp)));
4689         return jp;
4690 }
4691
4692 #if JOBS
4693 /*
4694  * Return a string identifying a command (to be printed by the
4695  * jobs command).
4696  */
4697 static char *cmdnextc;
4698
4699 static void
4700 cmdputs(const char *s)
4701 {
4702         static const char vstype[VSTYPE + 1][3] = {
4703                 "", "}", "-", "+", "?", "=",
4704                 "%", "%%", "#", "##"
4705                 IF_BASH_SUBSTR(, ":")
4706                 IF_BASH_PATTERN_SUBST(, "/", "//")
4707         };
4708
4709         const char *p, *str;
4710         char cc[2];
4711         char *nextc;
4712         unsigned char c;
4713         unsigned char subtype = 0;
4714         int quoted = 0;
4715
4716         cc[1] = '\0';
4717         nextc = makestrspace((strlen(s) + 1) * 8, cmdnextc);
4718         p = s;
4719         while ((c = *p++) != '\0') {
4720                 str = NULL;
4721                 switch (c) {
4722                 case CTLESC:
4723                         c = *p++;
4724                         break;
4725                 case CTLVAR:
4726                         subtype = *p++;
4727                         if ((subtype & VSTYPE) == VSLENGTH)
4728                                 str = "${#";
4729                         else
4730                                 str = "${";
4731                         goto dostr;
4732                 case CTLENDVAR:
4733                         str = "\"}" + !(quoted & 1);
4734                         quoted >>= 1;
4735                         subtype = 0;
4736                         goto dostr;
4737                 case CTLBACKQ:
4738                         str = "$(...)";
4739                         goto dostr;
4740 #if ENABLE_FEATURE_SH_MATH
4741                 case CTLARI:
4742                         str = "$((";
4743                         goto dostr;
4744                 case CTLENDARI:
4745                         str = "))";
4746                         goto dostr;
4747 #endif
4748                 case CTLQUOTEMARK:
4749                         quoted ^= 1;
4750                         c = '"';
4751                         break;
4752                 case '=':
4753                         if (subtype == 0)
4754                                 break;
4755                         if ((subtype & VSTYPE) != VSNORMAL)
4756                                 quoted <<= 1;
4757                         str = vstype[subtype & VSTYPE];
4758                         if (subtype & VSNUL)
4759                                 c = ':';
4760                         else
4761                                 goto checkstr;
4762                         break;
4763                 case '\'':
4764                 case '\\':
4765                 case '"':
4766                 case '$':
4767                         /* These can only happen inside quotes */
4768                         cc[0] = c;
4769                         str = cc;
4770 //FIXME:
4771 // $ true $$ &
4772 // $ <cr>
4773 // [1]+  Done    true ${\$}   <<=== BUG: ${\$} is not a valid way to write $$ (${$} would be ok)
4774                         c = '\\';
4775                         break;
4776                 default:
4777                         break;
4778                 }
4779                 USTPUTC(c, nextc);
4780  checkstr:
4781                 if (!str)
4782                         continue;
4783  dostr:
4784                 while ((c = *str++) != '\0') {
4785                         USTPUTC(c, nextc);
4786                 }
4787         } /* while *p++ not NUL */
4788
4789         if (quoted & 1) {
4790                 USTPUTC('"', nextc);
4791         }
4792         *nextc = 0;
4793         cmdnextc = nextc;
4794 }
4795
4796 /* cmdtxt() and cmdlist() call each other */
4797 static void cmdtxt(union node *n);
4798
4799 static void
4800 cmdlist(union node *np, int sep)
4801 {
4802         for (; np; np = np->narg.next) {
4803                 if (!sep)
4804                         cmdputs(" ");
4805                 cmdtxt(np);
4806                 if (sep && np->narg.next)
4807                         cmdputs(" ");
4808         }
4809 }
4810
4811 static void
4812 cmdtxt(union node *n)
4813 {
4814         union node *np;
4815         struct nodelist *lp;
4816         const char *p;
4817
4818         if (!n)
4819                 return;
4820         switch (n->type) {
4821         default:
4822 #if DEBUG
4823                 abort();
4824 #endif
4825         case NPIPE:
4826                 lp = n->npipe.cmdlist;
4827                 for (;;) {
4828                         cmdtxt(lp->n);
4829                         lp = lp->next;
4830                         if (!lp)
4831                                 break;
4832                         cmdputs(" | ");
4833                 }
4834                 break;
4835         case NSEMI:
4836                 p = "; ";
4837                 goto binop;
4838         case NAND:
4839                 p = " && ";
4840                 goto binop;
4841         case NOR:
4842                 p = " || ";
4843  binop:
4844                 cmdtxt(n->nbinary.ch1);
4845                 cmdputs(p);
4846                 n = n->nbinary.ch2;
4847                 goto donode;
4848         case NREDIR:
4849         case NBACKGND:
4850                 n = n->nredir.n;
4851                 goto donode;
4852         case NNOT:
4853                 cmdputs("!");
4854                 n = n->nnot.com;
4855  donode:
4856                 cmdtxt(n);
4857                 break;
4858         case NIF:
4859                 cmdputs("if ");
4860                 cmdtxt(n->nif.test);
4861                 cmdputs("; then ");
4862                 if (n->nif.elsepart) {
4863                         cmdtxt(n->nif.ifpart);
4864                         cmdputs("; else ");
4865                         n = n->nif.elsepart;
4866                 } else {
4867                         n = n->nif.ifpart;
4868                 }
4869                 p = "; fi";
4870                 goto dotail;
4871         case NSUBSHELL:
4872                 cmdputs("(");
4873                 n = n->nredir.n;
4874                 p = ")";
4875                 goto dotail;
4876         case NWHILE:
4877                 p = "while ";
4878                 goto until;
4879         case NUNTIL:
4880                 p = "until ";
4881  until:
4882                 cmdputs(p);
4883                 cmdtxt(n->nbinary.ch1);
4884                 n = n->nbinary.ch2;
4885                 p = "; done";
4886  dodo:
4887                 cmdputs("; do ");
4888  dotail:
4889                 cmdtxt(n);
4890                 goto dotail2;
4891         case NFOR:
4892                 cmdputs("for ");
4893                 cmdputs(n->nfor.var);
4894                 cmdputs(" in ");
4895                 cmdlist(n->nfor.args, 1);
4896                 n = n->nfor.body;
4897                 p = "; done";
4898                 goto dodo;
4899         case NDEFUN:
4900                 cmdputs(n->ndefun.text);
4901                 p = "() { ... }";
4902                 goto dotail2;
4903         case NCMD:
4904                 cmdlist(n->ncmd.args, 1);
4905                 cmdlist(n->ncmd.redirect, 0);
4906                 break;
4907         case NARG:
4908                 p = n->narg.text;
4909  dotail2:
4910                 cmdputs(p);
4911                 break;
4912         case NHERE:
4913         case NXHERE:
4914                 p = "<<...";
4915                 goto dotail2;
4916         case NCASE:
4917                 cmdputs("case ");
4918                 cmdputs(n->ncase.expr->narg.text);
4919                 cmdputs(" in ");
4920                 for (np = n->ncase.cases; np; np = np->nclist.next) {
4921                         cmdtxt(np->nclist.pattern);
4922                         cmdputs(") ");
4923                         cmdtxt(np->nclist.body);
4924                         cmdputs(";; ");
4925                 }
4926                 p = "esac";
4927                 goto dotail2;
4928         case NTO:
4929                 p = ">";
4930                 goto redir;
4931         case NCLOBBER:
4932                 p = ">|";
4933                 goto redir;
4934         case NAPPEND:
4935                 p = ">>";
4936                 goto redir;
4937 #if BASH_REDIR_OUTPUT
4938         case NTO2:
4939 #endif
4940         case NTOFD:
4941                 p = ">&";
4942                 goto redir;
4943         case NFROM:
4944                 p = "<";
4945                 goto redir;
4946         case NFROMFD:
4947                 p = "<&";
4948                 goto redir;
4949         case NFROMTO:
4950                 p = "<>";
4951  redir:
4952                 cmdputs(utoa(n->nfile.fd));
4953                 cmdputs(p);
4954                 if (n->type == NTOFD || n->type == NFROMFD) {
4955                         if (n->ndup.dupfd >= 0)
4956                                 cmdputs(utoa(n->ndup.dupfd));
4957                         else
4958                                 cmdputs("-");
4959                         break;
4960                 }
4961                 n = n->nfile.fname;
4962                 goto donode;
4963         }
4964 }
4965
4966 static char *
4967 commandtext(union node *n)
4968 {
4969         char *name;
4970
4971         STARTSTACKSTR(cmdnextc);
4972         cmdtxt(n);
4973         name = stackblock();
4974         TRACE(("commandtext: name %p, end %p\n", name, cmdnextc));
4975         return ckstrdup(name);
4976 }
4977 #endif /* JOBS */
4978
4979 /*
4980  * Fork off a subshell.  If we are doing job control, give the subshell its
4981  * own process group.  Jp is a job structure that the job is to be added to.
4982  * N is the command that will be evaluated by the child.  Both jp and n may
4983  * be NULL.  The mode parameter can be one of the following:
4984  *      FORK_FG - Fork off a foreground process.
4985  *      FORK_BG - Fork off a background process.
4986  *      FORK_NOJOB - Like FORK_FG, but don't give the process its own
4987  *                   process group even if job control is on.
4988  *
4989  * When job control is turned off, background processes have their standard
4990  * input redirected to /dev/null (except for the second and later processes
4991  * in a pipeline).
4992  *
4993  * Called with interrupts off.
4994  */
4995 /*
4996  * Clear traps on a fork.
4997  */
4998 static void
4999 clear_traps(void)
5000 {
5001         char **tp;
5002
5003         INT_OFF;
5004         for (tp = trap; tp < &trap[NSIG]; tp++) {
5005                 if (*tp && **tp) {      /* trap not NULL or "" (SIG_IGN) */
5006                         if (trap_ptr == trap)
5007                                 free(*tp);
5008                         /* else: it "belongs" to trap_ptr vector, don't free */
5009                         *tp = NULL;
5010                         if ((tp - trap) != 0)
5011                                 setsignal(tp - trap);
5012                 }
5013         }
5014         may_have_traps = 0;
5015         INT_ON;
5016 }
5017
5018 /* Lives far away from here, needed for forkchild */
5019 static void closescript(void);
5020
5021 /* Called after fork(), in child */
5022 /* jp and n are NULL when called by openhere() for heredoc support */
5023 static NOINLINE void
5024 forkchild(struct job *jp, union node *n, int mode)
5025 {
5026         int oldlvl;
5027
5028         TRACE(("Child shell %d\n", getpid()));
5029         oldlvl = shlvl;
5030         shlvl++;
5031
5032         /* man bash: "Non-builtin commands run by bash have signal handlers
5033          * set to the values inherited by the shell from its parent".
5034          * Do we do it correctly? */
5035
5036         closescript();
5037
5038         if (mode == FORK_NOJOB          /* is it `xxx` ? */
5039          && n && n->type == NCMD        /* is it single cmd? */
5040         /* && n->ncmd.args->type == NARG - always true? */
5041          && n->ncmd.args && strcmp(n->ncmd.args->narg.text, "trap") == 0
5042          && n->ncmd.args->narg.next == NULL /* "trap" with no arguments */
5043         /* && n->ncmd.args->narg.backquote == NULL - do we need to check this? */
5044         ) {
5045                 TRACE(("Trap hack\n"));
5046                 /* Awful hack for `trap` or $(trap).
5047                  *
5048                  * http://www.opengroup.org/onlinepubs/009695399/utilities/trap.html
5049                  * contains an example where "trap" is executed in a subshell:
5050                  *
5051                  * save_traps=$(trap)
5052                  * ...
5053                  * eval "$save_traps"
5054                  *
5055                  * Standard does not say that "trap" in subshell shall print
5056                  * parent shell's traps. It only says that its output
5057                  * must have suitable form, but then, in the above example
5058                  * (which is not supposed to be normative), it implies that.
5059                  *
5060                  * bash (and probably other shell) does implement it
5061                  * (traps are reset to defaults, but "trap" still shows them),
5062                  * but as a result, "trap" logic is hopelessly messed up:
5063                  *
5064                  * # trap
5065                  * trap -- 'echo Ho' SIGWINCH  <--- we have a handler
5066                  * # (trap)        <--- trap is in subshell - no output (correct, traps are reset)
5067                  * # true | trap   <--- trap is in subshell - no output (ditto)
5068                  * # echo `true | trap`    <--- in subshell - output (but traps are reset!)
5069                  * trap -- 'echo Ho' SIGWINCH
5070                  * # echo `(trap)`         <--- in subshell in subshell - output
5071                  * trap -- 'echo Ho' SIGWINCH
5072                  * # echo `true | (trap)`  <--- in subshell in subshell in subshell - output!
5073                  * trap -- 'echo Ho' SIGWINCH
5074                  *
5075                  * The rules when to forget and when to not forget traps
5076                  * get really complex and nonsensical.
5077                  *
5078                  * Our solution: ONLY bare $(trap) or `trap` is special.
5079                  */
5080                 /* Save trap handler strings for trap builtin to print */
5081                 trap_ptr = xmemdup(trap, sizeof(trap));
5082                 /* Fall through into clearing traps */
5083         }
5084         clear_traps();
5085 #if JOBS
5086         /* do job control only in root shell */
5087         doing_jobctl = 0;
5088         if (mode != FORK_NOJOB && jp->jobctl && oldlvl == 0) {
5089                 pid_t pgrp;
5090
5091                 if (jp->nprocs == 0)
5092                         pgrp = getpid();
5093                 else
5094                         pgrp = jp->ps[0].ps_pid;
5095                 /* this can fail because we are doing it in the parent also */
5096                 setpgid(0, pgrp);
5097                 if (mode == FORK_FG)
5098                         xtcsetpgrp(ttyfd, pgrp);
5099                 setsignal(SIGTSTP);
5100                 setsignal(SIGTTOU);
5101         } else
5102 #endif
5103         if (mode == FORK_BG) {
5104                 /* man bash: "When job control is not in effect,
5105                  * asynchronous commands ignore SIGINT and SIGQUIT" */
5106                 ignoresig(SIGINT);
5107                 ignoresig(SIGQUIT);
5108                 if (jp->nprocs == 0) {
5109                         close(0);
5110                         if (open(bb_dev_null, O_RDONLY) != 0)
5111                                 ash_msg_and_raise_perror("can't open '%s'", bb_dev_null);
5112                 }
5113         }
5114         if (oldlvl == 0) {
5115                 if (iflag) { /* why if iflag only? */
5116                         setsignal(SIGINT);
5117                         setsignal(SIGTERM);
5118                 }
5119                 /* man bash:
5120                  * "In all cases, bash ignores SIGQUIT. Non-builtin
5121                  * commands run by bash have signal handlers
5122                  * set to the values inherited by the shell
5123                  * from its parent".
5124                  * Take care of the second rule: */
5125                 setsignal(SIGQUIT);
5126         }
5127 #if JOBS
5128         if (n && n->type == NCMD
5129          && n->ncmd.args && strcmp(n->ncmd.args->narg.text, "jobs") == 0
5130         ) {
5131                 TRACE(("Job hack\n"));
5132                 /* "jobs": we do not want to clear job list for it,
5133                  * instead we remove only _its_ own_ job from job list.
5134                  * This makes "jobs .... | cat" more useful.
5135                  */
5136                 freejob(curjob);
5137                 return;
5138         }
5139 #endif
5140         for (jp = curjob; jp; jp = jp->prev_job)
5141                 freejob(jp);
5142         jobless = 0;
5143 }
5144
5145 /* Called after fork(), in parent */
5146 #if !JOBS
5147 #define forkparent(jp, n, mode, pid) forkparent(jp, mode, pid)
5148 #endif
5149 static void
5150 forkparent(struct job *jp, union node *n, int mode, pid_t pid)
5151 {
5152         TRACE(("In parent shell: child = %d\n", pid));
5153         if (!jp) {
5154                 /* jp is NULL when called by openhere() for heredoc support */
5155                 while (jobless && dowait(DOWAIT_NONBLOCK, NULL) > 0)
5156                         continue;
5157                 jobless++;
5158                 return;
5159         }
5160 #if JOBS
5161         if (mode != FORK_NOJOB && jp->jobctl) {
5162                 int pgrp;
5163
5164                 if (jp->nprocs == 0)
5165                         pgrp = pid;
5166                 else
5167                         pgrp = jp->ps[0].ps_pid;
5168                 /* This can fail because we are doing it in the child also */
5169                 setpgid(pid, pgrp);
5170         }
5171 #endif
5172         if (mode == FORK_BG) {
5173                 backgndpid = pid;               /* set $! */
5174                 set_curjob(jp, CUR_RUNNING);
5175         }
5176         if (jp) {
5177                 struct procstat *ps = &jp->ps[jp->nprocs++];
5178                 ps->ps_pid = pid;
5179                 ps->ps_status = -1;
5180                 ps->ps_cmd = nullstr;
5181 #if JOBS
5182                 if (doing_jobctl && n)
5183                         ps->ps_cmd = commandtext(n);
5184 #endif
5185         }
5186 }
5187
5188 /* jp and n are NULL when called by openhere() for heredoc support */
5189 static int
5190 forkshell(struct job *jp, union node *n, int mode)
5191 {
5192         int pid;
5193
5194         TRACE(("forkshell(%%%d, %p, %d) called\n", jobno(jp), n, mode));
5195         pid = fork();
5196         if (pid < 0) {
5197                 TRACE(("Fork failed, errno=%d", errno));
5198                 if (jp)
5199                         freejob(jp);
5200                 ash_msg_and_raise_perror("can't fork");
5201         }
5202         if (pid == 0) {
5203                 CLEAR_RANDOM_T(&random_gen); /* or else $RANDOM repeats in child */
5204                 forkchild(jp, n, mode);
5205         } else {
5206                 forkparent(jp, n, mode, pid);
5207         }
5208         return pid;
5209 }
5210
5211 /*
5212  * Wait for job to finish.
5213  *
5214  * Under job control we have the problem that while a child process
5215  * is running interrupts generated by the user are sent to the child
5216  * but not to the shell.  This means that an infinite loop started by
5217  * an interactive user may be hard to kill.  With job control turned off,
5218  * an interactive user may place an interactive program inside a loop.
5219  * If the interactive program catches interrupts, the user doesn't want
5220  * these interrupts to also abort the loop.  The approach we take here
5221  * is to have the shell ignore interrupt signals while waiting for a
5222  * foreground process to terminate, and then send itself an interrupt
5223  * signal if the child process was terminated by an interrupt signal.
5224  * Unfortunately, some programs want to do a bit of cleanup and then
5225  * exit on interrupt; unless these processes terminate themselves by
5226  * sending a signal to themselves (instead of calling exit) they will
5227  * confuse this approach.
5228  *
5229  * Called with interrupts off.
5230  */
5231 static int
5232 waitforjob(struct job *jp)
5233 {
5234         int st;
5235
5236         TRACE(("waitforjob(%%%d) called\n", jobno(jp)));
5237
5238         INT_OFF;
5239         while (jp->state == JOBRUNNING) {
5240                 /* In non-interactive shells, we _can_ get
5241                  * a keyboard signal here and be EINTRed,
5242                  * but we just loop back, waiting for command to complete.
5243                  *
5244                  * man bash:
5245                  * "If bash is waiting for a command to complete and receives
5246                  * a signal for which a trap has been set, the trap
5247                  * will not be executed until the command completes."
5248                  *
5249                  * Reality is that even if trap is not set, bash
5250                  * will not act on the signal until command completes.
5251                  * Try this. sleep5intoff.c:
5252                  * #include <signal.h>
5253                  * #include <unistd.h>
5254                  * int main() {
5255                  *         sigset_t set;
5256                  *         sigemptyset(&set);
5257                  *         sigaddset(&set, SIGINT);
5258                  *         sigaddset(&set, SIGQUIT);
5259                  *         sigprocmask(SIG_BLOCK, &set, NULL);
5260                  *         sleep(5);
5261                  *         return 0;
5262                  * }
5263                  * $ bash -c './sleep5intoff; echo hi'
5264                  * ^C^C^C^C <--- pressing ^C once a second
5265                  * $ _
5266                  * $ bash -c './sleep5intoff; echo hi'
5267                  * ^\^\^\^\hi <--- pressing ^\ (SIGQUIT)
5268                  * $ _
5269                  */
5270                 dowait(DOWAIT_BLOCK, jp);
5271         }
5272         INT_ON;
5273
5274         st = getstatus(jp);
5275 #if JOBS
5276         if (jp->jobctl) {
5277                 xtcsetpgrp(ttyfd, rootpid);
5278                 restore_tty_if_stopped_or_signaled(jp);
5279
5280                 /*
5281                  * This is truly gross.
5282                  * If we're doing job control, then we did a TIOCSPGRP which
5283                  * caused us (the shell) to no longer be in the controlling
5284                  * session -- so we wouldn't have seen any ^C/SIGINT.  So, we
5285                  * intuit from the subprocess exit status whether a SIGINT
5286                  * occurred, and if so interrupt ourselves.  Yuck.  - mycroft
5287                  */
5288                 if (jp->sigint) /* TODO: do the same with all signals */
5289                         raise(SIGINT); /* ... by raise(jp->sig) instead? */
5290         }
5291         if (jp->state == JOBDONE)
5292 #endif
5293                 freejob(jp);
5294         return st;
5295 }
5296
5297 /*
5298  * return 1 if there are stopped jobs, otherwise 0
5299  */
5300 static int
5301 stoppedjobs(void)
5302 {
5303         struct job *jp;
5304         int retval;
5305
5306         retval = 0;
5307         if (job_warning)
5308                 goto out;
5309         jp = curjob;
5310         if (jp && jp->state == JOBSTOPPED) {
5311                 out2str("You have stopped jobs.\n");
5312                 job_warning = 2;
5313                 retval++;
5314         }
5315  out:
5316         return retval;
5317 }
5318
5319
5320 /*
5321  * Code for dealing with input/output redirection.
5322  */
5323
5324 #undef EMPTY
5325 #undef CLOSED
5326 #define EMPTY -2                /* marks an unused slot in redirtab */
5327 #define CLOSED -1               /* marks a slot of previously-closed fd */
5328
5329 /*
5330  * Handle here documents.  Normally we fork off a process to write the
5331  * data to a pipe.  If the document is short, we can stuff the data in
5332  * the pipe without forking.
5333  */
5334 /* openhere needs this forward reference */
5335 static void expandhere(union node *arg, int fd);
5336 static int
5337 openhere(union node *redir)
5338 {
5339         int pip[2];
5340         size_t len = 0;
5341
5342         if (pipe(pip) < 0)
5343                 ash_msg_and_raise_perror("can't create pipe");
5344         if (redir->type == NHERE) {
5345                 len = strlen(redir->nhere.doc->narg.text);
5346                 if (len <= PIPE_BUF) {
5347                         full_write(pip[1], redir->nhere.doc->narg.text, len);
5348                         goto out;
5349                 }
5350         }
5351         if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) {
5352                 /* child */
5353                 close(pip[0]);
5354                 ignoresig(SIGINT);  //signal(SIGINT, SIG_IGN);
5355                 ignoresig(SIGQUIT); //signal(SIGQUIT, SIG_IGN);
5356                 ignoresig(SIGHUP);  //signal(SIGHUP, SIG_IGN);
5357                 ignoresig(SIGTSTP); //signal(SIGTSTP, SIG_IGN);
5358                 signal(SIGPIPE, SIG_DFL);
5359                 if (redir->type == NHERE)
5360                         full_write(pip[1], redir->nhere.doc->narg.text, len);
5361                 else /* NXHERE */
5362                         expandhere(redir->nhere.doc, pip[1]);
5363                 _exit(EXIT_SUCCESS);
5364         }
5365  out:
5366         close(pip[1]);
5367         return pip[0];
5368 }
5369
5370 static int
5371 openredirect(union node *redir)
5372 {
5373         struct stat sb;
5374         char *fname;
5375         int f;
5376
5377         switch (redir->nfile.type) {
5378 /* Can't happen, our single caller does this itself */
5379 //      case NTOFD:
5380 //      case NFROMFD:
5381 //              return -1;
5382         case NHERE:
5383         case NXHERE:
5384                 return openhere(redir);
5385         }
5386
5387         /* For N[X]HERE, reading redir->nfile.expfname would touch beyond
5388          * allocated space. Do it only when we know it is safe.
5389          */
5390         fname = redir->nfile.expfname;
5391
5392         switch (redir->nfile.type) {
5393         default:
5394 #if DEBUG
5395                 abort();
5396 #endif
5397         case NFROM:
5398                 f = open(fname, O_RDONLY);
5399                 if (f < 0)
5400                         goto eopen;
5401                 break;
5402         case NFROMTO:
5403                 f = open(fname, O_RDWR|O_CREAT, 0666);
5404                 if (f < 0)
5405                         goto ecreate;
5406                 break;
5407         case NTO:
5408 #if BASH_REDIR_OUTPUT
5409         case NTO2:
5410 #endif
5411                 /* Take care of noclobber mode. */
5412                 if (Cflag) {
5413                         if (stat(fname, &sb) < 0) {
5414                                 f = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0666);
5415                                 if (f < 0)
5416                                         goto ecreate;
5417                         } else if (!S_ISREG(sb.st_mode)) {
5418                                 f = open(fname, O_WRONLY, 0666);
5419                                 if (f < 0)
5420                                         goto ecreate;
5421                                 if (!fstat(f, &sb) && S_ISREG(sb.st_mode)) {
5422                                         close(f);
5423                                         errno = EEXIST;
5424                                         goto ecreate;
5425                                 }
5426                         } else {
5427                                 errno = EEXIST;
5428                                 goto ecreate;
5429                         }
5430                         break;
5431                 }
5432                 /* FALLTHROUGH */
5433         case NCLOBBER:
5434                 f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666);
5435                 if (f < 0)
5436                         goto ecreate;
5437                 break;
5438         case NAPPEND:
5439                 f = open(fname, O_WRONLY|O_CREAT|O_APPEND, 0666);
5440                 if (f < 0)
5441                         goto ecreate;
5442                 break;
5443         }
5444
5445         return f;
5446  ecreate:
5447         ash_msg_and_raise_error("can't create %s: %s", fname, errmsg(errno, "nonexistent directory"));
5448  eopen:
5449         ash_msg_and_raise_error("can't open %s: %s", fname, errmsg(errno, "no such file"));
5450 }
5451
5452 /*
5453  * Copy a file descriptor to be >= 10. Throws exception on error.
5454  */
5455 static int
5456 savefd(int from)
5457 {
5458         int newfd;
5459         int err;
5460
5461         newfd = fcntl(from, F_DUPFD_CLOEXEC, 10);
5462         err = newfd < 0 ? errno : 0;
5463         if (err != EBADF) {
5464                 if (err)
5465                         ash_msg_and_raise_perror("%d", from);
5466                 close(from);
5467                 if (F_DUPFD_CLOEXEC == F_DUPFD)
5468                         close_on_exec_on(newfd);
5469         }
5470
5471         return newfd;
5472 }
5473 static int
5474 dup2_or_raise(int from, int to)
5475 {
5476         int newfd;
5477
5478         newfd = (from != to) ? dup2(from, to) : to;
5479         if (newfd < 0) {
5480                 /* Happens when source fd is not open: try "echo >&99" */
5481                 ash_msg_and_raise_perror("%d", from);
5482         }
5483         return newfd;
5484 }
5485 static int
5486 dup_CLOEXEC(int fd, int avoid_fd)
5487 {
5488         int newfd;
5489  repeat:
5490         newfd = fcntl(fd, F_DUPFD_CLOEXEC, avoid_fd + 1);
5491         if (newfd >= 0) {
5492                 if (F_DUPFD_CLOEXEC == F_DUPFD) /* if old libc (w/o F_DUPFD_CLOEXEC) */
5493                         close_on_exec_on(newfd);
5494         } else { /* newfd < 0 */
5495                 if (errno == EBUSY)
5496                         goto repeat;
5497                 if (errno == EINTR)
5498                         goto repeat;
5499         }
5500         return newfd;
5501 }
5502 static int
5503 xdup_CLOEXEC_and_close(int fd, int avoid_fd)
5504 {
5505         int newfd;
5506  repeat:
5507         newfd = fcntl(fd, F_DUPFD_CLOEXEC, avoid_fd + 1);
5508         if (newfd < 0) {
5509                 if (errno == EBUSY)
5510                         goto repeat;
5511                 if (errno == EINTR)
5512                         goto repeat;
5513                 /* fd was not open? */
5514                 if (errno == EBADF)
5515                         return fd;
5516                 ash_msg_and_raise_perror("%d", newfd);
5517         }
5518         if (F_DUPFD_CLOEXEC == F_DUPFD)
5519                 close_on_exec_on(newfd);
5520         close(fd);
5521         return newfd;
5522 }
5523
5524 /* Struct def and variable are moved down to the first usage site */
5525 struct squirrel {
5526         int orig_fd;
5527         int moved_to;
5528 };
5529 struct redirtab {
5530         struct redirtab *next;
5531         int pair_count;
5532         struct squirrel two_fd[];
5533 };
5534 #define redirlist (G_var.redirlist)
5535
5536 static void
5537 add_squirrel_closed(struct redirtab *sq, int fd)
5538 {
5539         int i;
5540
5541         if (!sq)
5542                 return;
5543
5544         for (i = 0; sq->two_fd[i].orig_fd != EMPTY; i++) {
5545                 /* If we collide with an already moved fd... */
5546                 if (fd == sq->two_fd[i].orig_fd) {
5547                         /* Examples:
5548                          * "echo 3>FILE 3>&- 3>FILE"
5549                          * "echo 3>&- 3>FILE"
5550                          * No need for last redirect to insert
5551                          * another "need to close 3" indicator.
5552                          */
5553                         TRACE(("redirect_fd %d: already moved or closed\n", fd));
5554                         return;
5555                 }
5556         }
5557         TRACE(("redirect_fd %d: previous fd was closed\n", fd));
5558         sq->two_fd[i].orig_fd = fd;
5559         sq->two_fd[i].moved_to = CLOSED;
5560 }
5561
5562 static int
5563 save_fd_on_redirect(int fd, int avoid_fd, struct redirtab *sq)
5564 {
5565         int i, new_fd;
5566
5567         if (avoid_fd < 9) /* the important case here is that it can be -1 */
5568                 avoid_fd = 9;
5569
5570 #if JOBS
5571         if (fd == ttyfd) {
5572                 /* Testcase: "ls -l /proc/$$/fd 10>&-" should work */
5573                 ttyfd = xdup_CLOEXEC_and_close(ttyfd, avoid_fd);
5574                 TRACE(("redirect_fd %d: matches ttyfd, moving it to %d\n", fd, ttyfd));
5575                 return 1; /* "we closed fd" */
5576         }
5577 #endif
5578         /* Are we called from redirect(0)? E.g. redirect
5579          * in a forked child. No need to save fds,
5580          * we aren't going to use them anymore, ok to trash.
5581          */
5582         if (!sq)
5583                 return 0;
5584
5585         /* If this one of script's fds? */
5586         if (fd != 0) {
5587                 struct parsefile *pf = g_parsefile;
5588                 while (pf) {
5589                         /* We skip fd == 0 case because of the following:
5590                          * $ ash  # running ash interactively
5591                          * $ . ./script.sh
5592                          * and in script.sh: "exec 9>&0".
5593                          * Even though top-level pf_fd _is_ 0,
5594                          * it's still ok to use it: "read" builtin uses it,
5595                          * why should we cripple "exec" builtin?
5596                          */
5597                         if (fd == pf->pf_fd) {
5598                                 pf->pf_fd = xdup_CLOEXEC_and_close(fd, avoid_fd);
5599                                 return 1; /* "we closed fd" */
5600                         }
5601                         pf = pf->prev;
5602                 }
5603         }
5604
5605         /* Check whether it collides with any open fds (e.g. stdio), save fds as needed */
5606
5607         /* First: do we collide with some already moved fds? */
5608         for (i = 0; sq->two_fd[i].orig_fd != EMPTY; i++) {
5609                 /* If we collide with an already moved fd... */
5610                 if (fd == sq->two_fd[i].moved_to) {
5611                         new_fd = dup_CLOEXEC(fd, avoid_fd);
5612                         sq->two_fd[i].moved_to = new_fd;
5613                         TRACE(("redirect_fd %d: already busy, moving to %d\n", fd, new_fd));
5614                         if (new_fd < 0) /* what? */
5615                                 xfunc_die();
5616                         return 0; /* "we did not close fd" */
5617                 }
5618                 if (fd == sq->two_fd[i].orig_fd) {
5619                         /* Example: echo Hello >/dev/null 1>&2 */
5620                         TRACE(("redirect_fd %d: already moved\n", fd));
5621                         return 0; /* "we did not close fd" */
5622                 }
5623         }
5624
5625         /* If this fd is open, we move and remember it; if it's closed, new_fd = CLOSED (-1) */
5626         new_fd = dup_CLOEXEC(fd, avoid_fd);
5627         TRACE(("redirect_fd %d: previous fd is moved to %d (-1 if it was closed)\n", fd, new_fd));
5628         if (new_fd < 0) {
5629                 if (errno != EBADF)
5630                         xfunc_die();
5631                 /* new_fd = CLOSED; - already is -1 */
5632         }
5633         sq->two_fd[i].moved_to = new_fd;
5634         sq->two_fd[i].orig_fd = fd;
5635
5636         /* if we move stderr, let "set -x" code know */
5637         if (fd == preverrout_fd)
5638                 preverrout_fd = new_fd;
5639
5640         return 0; /* "we did not close fd" */
5641 }
5642
5643 static int
5644 internally_opened_fd(int fd, struct redirtab *sq)
5645 {
5646         int i;
5647 #if JOBS
5648         if (fd == ttyfd)
5649                 return 1;
5650 #endif
5651         /* If this one of script's fds? */
5652         if (fd != 0) {
5653                 struct parsefile *pf = g_parsefile;
5654                 while (pf) {
5655                         if (fd == pf->pf_fd)
5656                                 return 1;
5657                         pf = pf->prev;
5658                 }
5659         }
5660
5661         if (sq) for (i = 0; i < sq->pair_count && sq->two_fd[i].orig_fd != EMPTY; i++) {
5662                 if (fd == sq->two_fd[i].moved_to)
5663                         return 1;
5664         }
5665         return 0;
5666 }
5667
5668 /*
5669  * Process a list of redirection commands.  If the REDIR_PUSH flag is set,
5670  * old file descriptors are stashed away so that the redirection can be
5671  * undone by calling popredir.
5672  */
5673 /* flags passed to redirect */
5674 #define REDIR_PUSH    01        /* save previous values of file descriptors */
5675 static void
5676 redirect(union node *redir, int flags)
5677 {
5678         struct redirtab *sv;
5679
5680         if (!redir)
5681                 return;
5682
5683         sv = NULL;
5684         INT_OFF;
5685         if (flags & REDIR_PUSH)
5686                 sv = redirlist;
5687         do {
5688                 int fd;
5689                 int newfd;
5690                 int close_fd;
5691                 int closed;
5692
5693                 fd = redir->nfile.fd;
5694                 if (redir->nfile.type == NTOFD || redir->nfile.type == NFROMFD) {
5695                         //bb_error_msg("doing %d > %d", fd, newfd);
5696                         newfd = redir->ndup.dupfd;
5697                         close_fd = -1;
5698                 } else {
5699                         newfd = openredirect(redir); /* always >= 0 */
5700                         if (fd == newfd) {
5701                                 /* open() gave us precisely the fd we wanted.
5702                                  * This means that this fd was not busy
5703                                  * (not opened to anywhere).
5704                                  * Remember to close it on restore:
5705                                  */
5706                                 add_squirrel_closed(sv, fd);
5707                                 continue;
5708                         }
5709                         close_fd = newfd;
5710                 }
5711
5712                 if (fd == newfd)
5713                         continue;
5714
5715                 /* if "N>FILE": move newfd to fd */
5716                 /* if "N>&M": dup newfd to fd */
5717                 /* if "N>&-": close fd (newfd is -1) */
5718
5719  IF_BASH_REDIR_OUTPUT(redirect_more:)
5720
5721                 closed = save_fd_on_redirect(fd, /*avoid:*/ newfd, sv);
5722                 if (newfd == -1) {
5723                         /* "N>&-" means "close me" */
5724                         if (!closed) {
5725                                 /* ^^^ optimization: saving may already
5726                                  * have closed it. If not... */
5727                                 close(fd);
5728                         }
5729                 } else {
5730                         /* if newfd is a script fd or saved fd, simulate EBADF */
5731                         if (internally_opened_fd(newfd, sv)) {
5732                                 errno = EBADF;
5733                                 ash_msg_and_raise_perror("%d", newfd);
5734                         }
5735                         dup2_or_raise(newfd, fd);
5736                         if (close_fd >= 0) /* "N>FILE" or ">&FILE" or heredoc? */
5737                                 close(close_fd);
5738 #if BASH_REDIR_OUTPUT
5739                         if (redir->nfile.type == NTO2 && fd == 1) {
5740                                 /* ">&FILE". we already redirected to 1, now copy 1 to 2 */
5741                                 fd = 2;
5742                                 newfd = 1;
5743                                 close_fd = -1;
5744                                 goto redirect_more;
5745                         }
5746 #endif
5747                 }
5748         } while ((redir = redir->nfile.next) != NULL);
5749         INT_ON;
5750
5751 //dash:#define REDIR_SAVEFD2 03        /* set preverrout */
5752 #define REDIR_SAVEFD2 0
5753         // dash has a bug: since REDIR_SAVEFD2=3 and REDIR_PUSH=1, this test
5754         // triggers for pure REDIR_PUSH too. Thus, this is done almost always,
5755         // not only for calls with flags containing REDIR_SAVEFD2.
5756         // We do this unconditionally (see save_fd_on_redirect()).
5757         //if ((flags & REDIR_SAVEFD2) && copied_fd2 >= 0)
5758         //      preverrout_fd = copied_fd2;
5759 }
5760
5761 static int
5762 redirectsafe(union node *redir, int flags)
5763 {
5764         int err;
5765         volatile int saveint;
5766         struct jmploc *volatile savehandler = exception_handler;
5767         struct jmploc jmploc;
5768
5769         SAVE_INT(saveint);
5770         /* "echo 9>/dev/null; echo >&9; echo result: $?" - result should be 1, not 2! */
5771         err = setjmp(jmploc.loc); /* was = setjmp(jmploc.loc) * 2; */
5772         if (!err) {
5773                 exception_handler = &jmploc;
5774                 redirect(redir, flags);
5775         }
5776         exception_handler = savehandler;
5777         if (err && exception_type != EXERROR)
5778                 longjmp(exception_handler->loc, 1);
5779         RESTORE_INT(saveint);
5780         return err;
5781 }
5782
5783 static struct redirtab*
5784 pushredir(union node *redir)
5785 {
5786         struct redirtab *sv;
5787         int i;
5788
5789         if (!redir)
5790                 return redirlist;
5791
5792         i = 0;
5793         do {
5794                 i++;
5795 #if BASH_REDIR_OUTPUT
5796                 if (redir->nfile.type == NTO2)
5797                         i++;
5798 #endif
5799                 redir = redir->nfile.next;
5800         } while (redir);
5801
5802         sv = ckzalloc(sizeof(*sv) + i * sizeof(sv->two_fd[0]));
5803         sv->pair_count = i;
5804         while (--i >= 0)
5805                 sv->two_fd[i].orig_fd = sv->two_fd[i].moved_to = EMPTY;
5806         sv->next = redirlist;
5807         redirlist = sv;
5808         return sv->next;
5809 }
5810
5811 /*
5812  * Undo the effects of the last redirection.
5813  */
5814 static void
5815 popredir(int drop)
5816 {
5817         struct redirtab *rp;
5818         int i;
5819
5820         if (redirlist == NULL)
5821                 return;
5822         INT_OFF;
5823         rp = redirlist;
5824         for (i = 0; i < rp->pair_count; i++) {
5825                 int fd = rp->two_fd[i].orig_fd;
5826                 int copy = rp->two_fd[i].moved_to;
5827                 if (copy == CLOSED) {
5828                         if (!drop)
5829                                 close(fd);
5830                         continue;
5831                 }
5832                 if (copy != EMPTY) {
5833                         if (!drop) {
5834                                 /*close(fd);*/
5835                                 dup2_or_raise(copy, fd);
5836                         }
5837                         close(copy);
5838                 }
5839         }
5840         redirlist = rp->next;
5841         free(rp);
5842         INT_ON;
5843 }
5844
5845 static void
5846 unwindredir(struct redirtab *stop)
5847 {
5848         while (redirlist != stop)
5849                 popredir(/*drop:*/ 0);
5850 }
5851
5852
5853 /* ============ Routines to expand arguments to commands
5854  *
5855  * We have to deal with backquotes, shell variables, and file metacharacters.
5856  */
5857
5858 #if ENABLE_FEATURE_SH_MATH
5859 static arith_t
5860 ash_arith(const char *s)
5861 {
5862         arith_state_t math_state;
5863         arith_t result;
5864
5865         math_state.lookupvar = lookupvar;
5866         math_state.setvar    = setvar0;
5867         //math_state.endofname = endofname;
5868
5869         INT_OFF;
5870         result = arith(&math_state, s);
5871         if (math_state.errmsg)
5872                 ash_msg_and_raise_error(math_state.errmsg);
5873         INT_ON;
5874
5875         return result;
5876 }
5877 #endif
5878 #if BASH_SUBSTR
5879 # if ENABLE_FEATURE_SH_MATH
5880 static int substr_atoi(const char *s)
5881 {
5882         arith_t t = ash_arith(s);
5883         if (sizeof(t) > sizeof(int)) {
5884                 /* clamp very large or very large negative nums for ${v:N:M}:
5885                  * else "${v:0:0x100000001}" would work as "${v:0:1}"
5886                  */
5887                 if (t > INT_MAX)
5888                         t = INT_MAX;
5889                 if (t < INT_MIN)
5890                         t = INT_MIN;
5891         }
5892         return t;
5893 }
5894 # else
5895 #  define substr_atoi(s) number(s)
5896 # endif
5897 #endif
5898
5899 /*
5900  * expandarg flags
5901  */
5902 #define EXP_FULL        0x1     /* perform word splitting & file globbing */
5903 #define EXP_TILDE       0x2     /* do normal tilde expansion */
5904 #define EXP_VARTILDE    0x4     /* expand tildes in an assignment */
5905 #define EXP_REDIR       0x8     /* file glob for a redirection (1 match only) */
5906 /* ^^^^^^^^^^^^^^ this is meant to support constructs such as "cmd >file*.txt"
5907  * POSIX says for this case:
5908  *  Pathname expansion shall not be performed on the word by a
5909  *  non-interactive shell; an interactive shell may perform it, but shall
5910  *  do so only when the expansion would result in one word.
5911  * Currently, our code complies to the above rule by never globbing
5912  * redirection filenames.
5913  * Bash performs globbing, unless it is non-interactive and in POSIX mode.
5914  * (this means that on a typical Linux distro, bash almost always
5915  * performs globbing, and thus diverges from what we do).
5916  */
5917 #define EXP_CASE        0x10    /* keeps quotes around for CASE pattern */
5918 #define EXP_VARTILDE2   0x20    /* expand tildes after colons only */
5919 #define EXP_WORD        0x40    /* expand word in parameter expansion */
5920 #define EXP_QUOTED      0x100   /* expand word in double quotes */
5921 /*
5922  * rmescape() flags
5923  */
5924 #define RMESCAPE_ALLOC  0x1     /* Allocate a new string */
5925 #define RMESCAPE_GLOB   0x2     /* Add backslashes for glob */
5926 #define RMESCAPE_GROW   0x8     /* Grow strings instead of stalloc */
5927 #define RMESCAPE_HEAP   0x10    /* Malloc strings instead of stalloc */
5928
5929 /* Add CTLESC when necessary. */
5930 #define QUOTES_ESC     (EXP_FULL | EXP_CASE)
5931 /* Do not skip NUL characters. */
5932 #define QUOTES_KEEPNUL EXP_TILDE
5933
5934 /*
5935  * Structure specifying which parts of the string should be searched
5936  * for IFS characters.
5937  */
5938 struct ifsregion {
5939         struct ifsregion *next; /* next region in list */
5940         int begoff;             /* offset of start of region */
5941         int endoff;             /* offset of end of region */
5942         int nulonly;            /* search for nul bytes only */
5943 };
5944
5945 struct arglist {
5946         struct strlist *list;
5947         struct strlist **lastp;
5948 };
5949
5950 /* output of current string */
5951 static char *expdest;
5952 /* list of back quote expressions */
5953 static struct nodelist *argbackq;
5954 /* first struct in list of ifs regions */
5955 static struct ifsregion ifsfirst;
5956 /* last struct in list */
5957 static struct ifsregion *ifslastp;
5958 /* holds expanded arg list */
5959 static struct arglist exparg;
5960
5961 /*
5962  * Our own itoa().
5963  * cvtnum() is used even if math support is off (to prepare $? values and such).
5964  */
5965 static int
5966 cvtnum(arith_t num)
5967 {
5968         int len;
5969
5970         /* 32-bit and wider ints require buffer size of bytes*3 (or less) */
5971         len = sizeof(arith_t) * 3;
5972         /* If narrower: worst case, 1-byte ints: need 5 bytes: "-127<NUL>" */
5973         if (sizeof(arith_t) < 4) len += 2;
5974
5975         expdest = makestrspace(len, expdest);
5976         len = fmtstr(expdest, len, ARITH_FMT, num);
5977         STADJUST(len, expdest);
5978         return len;
5979 }
5980
5981 /*
5982  * Break the argument string into pieces based upon IFS and add the
5983  * strings to the argument list.  The regions of the string to be
5984  * searched for IFS characters have been stored by recordregion.
5985  */
5986 static void
5987 ifsbreakup(char *string, struct arglist *arglist)
5988 {
5989         struct ifsregion *ifsp;
5990         struct strlist *sp;
5991         char *start;
5992         char *p;
5993         char *q;
5994         const char *ifs, *realifs;
5995         int ifsspc;
5996         int nulonly;
5997
5998         start = string;
5999         if (ifslastp != NULL) {
6000                 ifsspc = 0;
6001                 nulonly = 0;
6002                 realifs = ifsset() ? ifsval() : defifs;
6003                 ifsp = &ifsfirst;
6004                 do {
6005                         int afternul;
6006
6007                         p = string + ifsp->begoff;
6008                         afternul = nulonly;
6009                         nulonly = ifsp->nulonly;
6010                         ifs = nulonly ? nullstr : realifs;
6011                         ifsspc = 0;
6012                         while (p < string + ifsp->endoff) {
6013                                 q = p;
6014                                 if ((unsigned char)*p == CTLESC)
6015                                         p++;
6016                                 if (!strchr(ifs, *p)) {
6017                                         p++;
6018                                         continue;
6019                                 }
6020                                 if (!(afternul || nulonly))
6021                                         ifsspc = (strchr(defifs, *p) != NULL);
6022                                 /* Ignore IFS whitespace at start */
6023                                 if (q == start && ifsspc) {
6024                                         p++;
6025                                         start = p;
6026                                         continue;
6027                                 }
6028                                 *q = '\0';
6029                                 sp = stzalloc(sizeof(*sp));
6030                                 sp->text = start;
6031                                 *arglist->lastp = sp;
6032                                 arglist->lastp = &sp->next;
6033                                 p++;
6034                                 if (!nulonly) {
6035                                         for (;;) {
6036                                                 if (p >= string + ifsp->endoff) {
6037                                                         break;
6038                                                 }
6039                                                 q = p;
6040                                                 if ((unsigned char)*p == CTLESC)
6041                                                         p++;
6042                                                 if (strchr(ifs, *p) == NULL) {
6043                                                         p = q;
6044                                                         break;
6045                                                 }
6046                                                 if (strchr(defifs, *p) == NULL) {
6047                                                         if (ifsspc) {
6048                                                                 p++;
6049                                                                 ifsspc = 0;
6050                                                         } else {
6051                                                                 p = q;
6052                                                                 break;
6053                                                         }
6054                                                 } else
6055                                                         p++;
6056                                         }
6057                                 }
6058                                 start = p;
6059                         } /* while */
6060                         ifsp = ifsp->next;
6061                 } while (ifsp != NULL);
6062                 if (nulonly)
6063                         goto add;
6064         }
6065
6066         if (!*start)
6067                 return;
6068
6069  add:
6070         sp = stzalloc(sizeof(*sp));
6071         sp->text = start;
6072         *arglist->lastp = sp;
6073         arglist->lastp = &sp->next;
6074 }
6075
6076 static void
6077 ifsfree(void)
6078 {
6079         struct ifsregion *p = ifsfirst.next;
6080
6081         if (!p)
6082                 goto out;
6083
6084         INT_OFF;
6085         do {
6086                 struct ifsregion *ifsp;
6087                 ifsp = p->next;
6088                 free(p);
6089                 p = ifsp;
6090         } while (p);
6091         ifsfirst.next = NULL;
6092         INT_ON;
6093  out:
6094         ifslastp = NULL;
6095 }
6096
6097 static size_t
6098 esclen(const char *start, const char *p)
6099 {
6100         size_t esc = 0;
6101
6102         while (p > start && (unsigned char)*--p == CTLESC) {
6103                 esc++;
6104         }
6105         return esc;
6106 }
6107
6108 /*
6109  * Remove any CTLESC characters from a string.
6110  */
6111 #if !BASH_PATTERN_SUBST
6112 #define rmescapes(str, flag, slash_position) \
6113         rmescapes(str, flag)
6114 #endif
6115 static char *
6116 rmescapes(char *str, int flag, int *slash_position)
6117 {
6118         static const char qchars[] ALIGN1 = {
6119                 IF_BASH_PATTERN_SUBST('/',) CTLESC, CTLQUOTEMARK, '\0' };
6120
6121         char *p, *q, *r;
6122         unsigned protect_against_glob;
6123         unsigned globbing;
6124
6125         p = strpbrk(str, qchars IF_BASH_PATTERN_SUBST(+ !slash_position));
6126         if (!p)
6127                 return str;
6128
6129         q = p;
6130         r = str;
6131         if (flag & RMESCAPE_ALLOC) {
6132                 size_t len = p - str;
6133                 size_t fulllen = len + strlen(p) + 1;
6134
6135                 if (flag & RMESCAPE_GROW) {
6136                         int strloc = str - (char *)stackblock();
6137                         r = makestrspace(fulllen, expdest);
6138                         /* p and str may be invalidated by makestrspace */
6139                         str = (char *)stackblock() + strloc;
6140                         p = str + len;
6141                 } else if (flag & RMESCAPE_HEAP) {
6142                         r = ckmalloc(fulllen);
6143                 } else {
6144                         r = stalloc(fulllen);
6145                 }
6146                 q = r;
6147                 if (len > 0) {
6148                         q = (char *)mempcpy(q, str, len);
6149                 }
6150         }
6151
6152         globbing = flag & RMESCAPE_GLOB;
6153         protect_against_glob = globbing;
6154         while (*p) {
6155                 if ((unsigned char)*p == CTLQUOTEMARK) {
6156 // Note: protect_against_glob only affect whether
6157 // CTLESC,<ch> gets converted to <ch> or to \<ch>
6158                         p++;
6159                         protect_against_glob = globbing;
6160                         continue;
6161                 }
6162                 if (*p == '\\') {
6163                         /* naked back slash */
6164                         protect_against_glob = 0;
6165                         goto copy;
6166                 }
6167                 if ((unsigned char)*p == CTLESC) {
6168                         p++;
6169 #if DEBUG
6170                         if (*p == '\0')
6171                                 ash_msg_and_raise_error("CTLESC at EOL (shouldn't happen)");
6172 #endif
6173                         if (protect_against_glob) {
6174                                 /*
6175                                  * We used to trust glob() and fnmatch() to eat
6176                                  * superfluous escapes (\z where z has no
6177                                  * special meaning anyway). But this causes
6178                                  * bugs such as string of one greek letter rho
6179                                  * (unicode-encoded as two bytes "cf,81")
6180                                  * getting encoded as "cf,CTLESC,81"
6181                                  * and here, converted to "cf,\,81" -
6182                                  * which does not go well with some flavors
6183                                  * of fnmatch() in unicode locales
6184                                  * (for example, glibc <= 2.22).
6185                                  *
6186                                  * Lets add "\" only on the chars which need it.
6187                                  * Testcases for less obvious chars are shown.
6188                                  */
6189                                 if (*p == '*'
6190                                  || *p == '?'
6191                                  || *p == '['
6192                                  || *p == '\\' /* case '\' in \\    ) echo ok;; *) echo WRONG;; esac */
6193                                  || *p == ']'  /* case ']' in [a\]] ) echo ok;; *) echo WRONG;; esac */
6194                                  || *p == '-'  /* case '-' in [a\-c]) echo ok;; *) echo WRONG;; esac */
6195                                  || *p == '!'  /* case '!' in [\!]  ) echo ok;; *) echo WRONG;; esac */
6196                                 /* Some libc support [^negate], that's why "^" also needs love */
6197                                  || *p == '^'  /* case '^' in [\^]  ) echo ok;; *) echo WRONG;; esac */
6198                                 ) {
6199                                         *q++ = '\\';
6200                                 }
6201                         }
6202                 }
6203 #if BASH_PATTERN_SUBST
6204                 else if (slash_position && p == str + *slash_position) {
6205                         /* stop handling globbing */
6206                         globbing = 0;
6207                         *slash_position = q - r;
6208                         slash_position = NULL;
6209                 }
6210 #endif
6211                 protect_against_glob = globbing;
6212  copy:
6213                 *q++ = *p++;
6214         }
6215         *q = '\0';
6216         if (flag & RMESCAPE_GROW) {
6217                 expdest = r;
6218                 STADJUST(q - r + 1, expdest);
6219         }
6220         return r;
6221 }
6222 #define pmatch(a, b) !fnmatch((a), (b), 0)
6223
6224 /*
6225  * Prepare a pattern for a expmeta (internal glob(3)) call.
6226  *
6227  * Returns an stalloced string.
6228  */
6229 static char *
6230 preglob(const char *pattern, int flag)
6231 {
6232         return rmescapes((char *)pattern, flag | RMESCAPE_GLOB, NULL);
6233 }
6234
6235 /*
6236  * Put a string on the stack.
6237  */
6238 static void
6239 memtodest(const char *p, size_t len, int syntax, int quotes)
6240 {
6241         char *q;
6242
6243         if (!len)
6244                 return;
6245
6246         q = makestrspace((quotes & QUOTES_ESC) ? len * 2 : len, expdest);
6247
6248         do {
6249                 unsigned char c = *p++;
6250                 if (c) {
6251                         if (quotes & QUOTES_ESC) {
6252                                 int n = SIT(c, syntax);
6253                                 if (n == CCTL
6254                                  || (syntax != BASESYNTAX && n == CBACK)
6255                                 ) {
6256                                         USTPUTC(CTLESC, q);
6257                                 }
6258                         }
6259                 } else if (!(quotes & QUOTES_KEEPNUL))
6260                         continue;
6261                 USTPUTC(c, q);
6262         } while (--len);
6263
6264         expdest = q;
6265 }
6266
6267 static size_t
6268 strtodest(const char *p, int syntax, int quotes)
6269 {
6270         size_t len = strlen(p);
6271         memtodest(p, len, syntax, quotes);
6272         return len;
6273 }
6274
6275 /*
6276  * Record the fact that we have to scan this region of the
6277  * string for IFS characters.
6278  */
6279 static void
6280 recordregion(int start, int end, int nulonly)
6281 {
6282         struct ifsregion *ifsp;
6283
6284         if (ifslastp == NULL) {
6285                 ifsp = &ifsfirst;
6286         } else {
6287                 INT_OFF;
6288                 ifsp = ckzalloc(sizeof(*ifsp));
6289                 /*ifsp->next = NULL; - ckzalloc did it */
6290                 ifslastp->next = ifsp;
6291                 INT_ON;
6292         }
6293         ifslastp = ifsp;
6294         ifslastp->begoff = start;
6295         ifslastp->endoff = end;
6296         ifslastp->nulonly = nulonly;
6297 }
6298
6299 static void
6300 removerecordregions(int endoff)
6301 {
6302         if (ifslastp == NULL)
6303                 return;
6304
6305         if (ifsfirst.endoff > endoff) {
6306                 while (ifsfirst.next) {
6307                         struct ifsregion *ifsp;
6308                         INT_OFF;
6309                         ifsp = ifsfirst.next->next;
6310                         free(ifsfirst.next);
6311                         ifsfirst.next = ifsp;
6312                         INT_ON;
6313                 }
6314                 if (ifsfirst.begoff > endoff) {
6315                         ifslastp = NULL;
6316                 } else {
6317                         ifslastp = &ifsfirst;
6318                         ifsfirst.endoff = endoff;
6319                 }
6320                 return;
6321         }
6322
6323         ifslastp = &ifsfirst;
6324         while (ifslastp->next && ifslastp->next->begoff < endoff)
6325                 ifslastp = ifslastp->next;
6326         while (ifslastp->next) {
6327                 struct ifsregion *ifsp;
6328                 INT_OFF;
6329                 ifsp = ifslastp->next->next;
6330                 free(ifslastp->next);
6331                 ifslastp->next = ifsp;
6332                 INT_ON;
6333         }
6334         if (ifslastp->endoff > endoff)
6335                 ifslastp->endoff = endoff;
6336 }
6337
6338 static char *
6339 exptilde(char *startp, char *p, int flags)
6340 {
6341         unsigned char c;
6342         char *name;
6343         struct passwd *pw;
6344         const char *home;
6345         int quotes = flags & QUOTES_ESC;
6346
6347         name = p + 1;
6348
6349         while ((c = *++p) != '\0') {
6350                 switch (c) {
6351                 case CTLESC:
6352                         return startp;
6353                 case CTLQUOTEMARK:
6354                         return startp;
6355                 case ':':
6356                         if (flags & EXP_VARTILDE)
6357                                 goto done;
6358                         break;
6359                 case '/':
6360                 case CTLENDVAR:
6361                         goto done;
6362                 }
6363         }
6364  done:
6365         *p = '\0';
6366         if (*name == '\0') {
6367                 home = lookupvar("HOME");
6368         } else {
6369                 pw = getpwnam(name);
6370                 if (pw == NULL)
6371                         goto lose;
6372                 home = pw->pw_dir;
6373         }
6374         if (!home || !*home)
6375                 goto lose;
6376         *p = c;
6377         strtodest(home, SQSYNTAX, quotes);
6378         return p;
6379  lose:
6380         *p = c;
6381         return startp;
6382 }
6383
6384 /*
6385  * Execute a command inside back quotes.  If it's a builtin command, we
6386  * want to save its output in a block obtained from malloc.  Otherwise
6387  * we fork off a subprocess and get the output of the command via a pipe.
6388  * Should be called with interrupts off.
6389  */
6390 struct backcmd {                /* result of evalbackcmd */
6391         int fd;                 /* file descriptor to read from */
6392         int nleft;              /* number of chars in buffer */
6393         char *buf;              /* buffer */
6394         struct job *jp;         /* job structure for command */
6395 };
6396
6397 /* These forward decls are needed to use "eval" code for backticks handling: */
6398 /* flags in argument to evaltree */
6399 #define EV_EXIT    01           /* exit after evaluating tree */
6400 #define EV_TESTED  02           /* exit status is checked; ignore -e flag */
6401 static int evaltree(union node *, int);
6402
6403 /* An evaltree() which is known to never return.
6404  * Used to use an alias:
6405  * static int evaltreenr(union node *, int) __attribute__((alias("evaltree"),__noreturn__));
6406  * but clang was reported to "transfer" noreturn-ness to evaltree() as well.
6407  */
6408 static ALWAYS_INLINE NORETURN void
6409 evaltreenr(union node *n, int flags)
6410 {
6411         evaltree(n, flags);
6412         bb_unreachable(abort());
6413         /* NOTREACHED */
6414 }
6415
6416 static void FAST_FUNC
6417 evalbackcmd(union node *n, struct backcmd *result)
6418 {
6419         int pip[2];
6420         struct job *jp;
6421
6422         result->fd = -1;
6423         result->buf = NULL;
6424         result->nleft = 0;
6425         result->jp = NULL;
6426         if (n == NULL) {
6427                 goto out;
6428         }
6429
6430         if (pipe(pip) < 0)
6431                 ash_msg_and_raise_perror("can't create pipe");
6432         jp = makejob(/*n,*/ 1);
6433         if (forkshell(jp, n, FORK_NOJOB) == 0) {
6434                 /* child */
6435                 FORCE_INT_ON;
6436                 close(pip[0]);
6437                 if (pip[1] != 1) {
6438                         /*close(1);*/
6439                         dup2_or_raise(pip[1], 1);
6440                         close(pip[1]);
6441                 }
6442 /* TODO: eflag clearing makes the following not abort:
6443  *  ash -c 'set -e; z=$(false;echo foo); echo $z'
6444  * which is what bash does (unless it is in POSIX mode).
6445  * dash deleted "eflag = 0" line in the commit
6446  *  Date: Mon, 28 Jun 2010 17:11:58 +1000
6447  *  [EVAL] Don't clear eflag in evalbackcmd
6448  * For now, preserve bash-like behavior, it seems to be somewhat more useful:
6449  */
6450                 eflag = 0;
6451                 ifsfree();
6452                 evaltreenr(n, EV_EXIT);
6453                 /* NOTREACHED */
6454         }
6455         /* parent */
6456         close(pip[1]);
6457         result->fd = pip[0];
6458         result->jp = jp;
6459
6460  out:
6461         TRACE(("evalbackcmd done: fd=%d buf=0x%x nleft=%d jp=0x%x\n",
6462                 result->fd, result->buf, result->nleft, result->jp));
6463 }
6464
6465 /*
6466  * Expand stuff in backwards quotes.
6467  */
6468 static void
6469 expbackq(union node *cmd, int flag)
6470 {
6471         struct backcmd in;
6472         int i;
6473         char buf[128];
6474         char *p;
6475         char *dest;
6476         int startloc;
6477         int syntax = flag & EXP_QUOTED ? DQSYNTAX : BASESYNTAX;
6478         struct stackmark smark;
6479
6480         INT_OFF;
6481         startloc = expdest - (char *)stackblock();
6482         pushstackmark(&smark, startloc);
6483         evalbackcmd(cmd, &in);
6484         popstackmark(&smark);
6485
6486         p = in.buf;
6487         i = in.nleft;
6488         if (i == 0)
6489                 goto read;
6490         for (;;) {
6491                 memtodest(p, i, syntax, flag & QUOTES_ESC);
6492  read:
6493                 if (in.fd < 0)
6494                         break;
6495                 i = nonblock_immune_read(in.fd, buf, sizeof(buf));
6496                 TRACE(("expbackq: read returns %d\n", i));
6497                 if (i <= 0)
6498                         break;
6499                 p = buf;
6500         }
6501
6502         free(in.buf);
6503         if (in.fd >= 0) {
6504                 close(in.fd);
6505                 back_exitstatus = waitforjob(in.jp);
6506         }
6507         INT_ON;
6508
6509         /* Eat all trailing newlines */
6510         dest = expdest;
6511         for (; dest > (char *)stackblock() && dest[-1] == '\n';)
6512                 STUNPUTC(dest);
6513         expdest = dest;
6514
6515         if (!(flag & EXP_QUOTED))
6516                 recordregion(startloc, dest - (char *)stackblock(), 0);
6517         TRACE(("evalbackq: size:%d:'%.*s'\n",
6518                 (int)((dest - (char *)stackblock()) - startloc),
6519                 (int)((dest - (char *)stackblock()) - startloc),
6520                 stackblock() + startloc));
6521 }
6522
6523 #if ENABLE_FEATURE_SH_MATH
6524 /*
6525  * Expand arithmetic expression.  Backup to start of expression,
6526  * evaluate, place result in (backed up) result, adjust string position.
6527  */
6528 static void
6529 expari(int flag)
6530 {
6531         char *p, *start;
6532         int begoff;
6533         int len;
6534
6535         /* ifsfree(); */
6536
6537         /*
6538          * This routine is slightly over-complicated for
6539          * efficiency.  Next we scan backwards looking for the
6540          * start of arithmetic.
6541          */
6542         start = stackblock();
6543         p = expdest - 1;
6544         *p = '\0';
6545         p--;
6546         while (1) {
6547                 int esc;
6548
6549                 while ((unsigned char)*p != CTLARI) {
6550                         p--;
6551 #if DEBUG
6552                         if (p < start) {
6553                                 ash_msg_and_raise_error("missing CTLARI (shouldn't happen)");
6554                         }
6555 #endif
6556                 }
6557
6558                 esc = esclen(start, p);
6559                 if (!(esc % 2)) {
6560                         break;
6561                 }
6562
6563                 p -= esc + 1;
6564         }
6565
6566         begoff = p - start;
6567
6568         removerecordregions(begoff);
6569
6570         expdest = p;
6571
6572         if (flag & QUOTES_ESC)
6573                 rmescapes(p + 1, 0, NULL);
6574
6575         len = cvtnum(ash_arith(p + 1));
6576
6577         if (!(flag & EXP_QUOTED))
6578                 recordregion(begoff, begoff + len, 0);
6579 }
6580 #endif
6581
6582 /* argstr needs it */
6583 static char *evalvar(char *p, int flags);
6584
6585 /*
6586  * Perform variable and command substitution.  If EXP_FULL is set, output CTLESC
6587  * characters to allow for further processing.  Otherwise treat
6588  * $@ like $* since no splitting will be performed.
6589  */
6590 static void
6591 argstr(char *p, int flags)
6592 {
6593         static const char spclchars[] ALIGN1 = {
6594                 '=',
6595                 ':',
6596                 CTLQUOTEMARK,
6597                 CTLENDVAR,
6598                 CTLESC,
6599                 CTLVAR,
6600                 CTLBACKQ,
6601 #if ENABLE_FEATURE_SH_MATH
6602                 CTLENDARI,
6603 #endif
6604                 '\0'
6605         };
6606         const char *reject = spclchars;
6607         int breakall = (flags & (EXP_WORD | EXP_QUOTED)) == EXP_WORD;
6608         int inquotes;
6609         size_t length;
6610         int startloc;
6611
6612         if (!(flags & EXP_VARTILDE)) {
6613                 reject += 2;
6614         } else if (flags & EXP_VARTILDE2) {
6615                 reject++;
6616         }
6617         inquotes = 0;
6618         length = 0;
6619         if (flags & EXP_TILDE) {
6620                 char *q;
6621
6622                 flags &= ~EXP_TILDE;
6623  tilde:
6624                 q = p;
6625                 if (*q == '~')
6626                         p = exptilde(p, q, flags);
6627         }
6628  start:
6629         startloc = expdest - (char *)stackblock();
6630         for (;;) {
6631                 unsigned char c;
6632
6633                 length += strcspn(p + length, reject);
6634                 c = p[length];
6635                 if (c) {
6636                         if (!(c & 0x80)
6637                         IF_FEATURE_SH_MATH(|| c == CTLENDARI)
6638                         ) {
6639                                 /* c == '=' || c == ':' || c == CTLENDARI */
6640                                 length++;
6641                         }
6642                 }
6643                 if (length > 0) {
6644                         int newloc;
6645                         expdest = stack_nputstr(p, length, expdest);
6646                         newloc = expdest - (char *)stackblock();
6647                         if (breakall && !inquotes && newloc > startloc) {
6648                                 recordregion(startloc, newloc, 0);
6649                         }
6650                         startloc = newloc;
6651                 }
6652                 p += length + 1;
6653                 length = 0;
6654
6655                 switch (c) {
6656                 case '\0':
6657                         goto breakloop;
6658                 case '=':
6659                         if (flags & EXP_VARTILDE2) {
6660                                 p--;
6661                                 continue;
6662                         }
6663                         flags |= EXP_VARTILDE2;
6664                         reject++;
6665                         /* fall through */
6666                 case ':':
6667                         /*
6668                          * sort of a hack - expand tildes in variable
6669                          * assignments (after the first '=' and after ':'s).
6670                          */
6671                         if (*--p == '~') {
6672                                 goto tilde;
6673                         }
6674                         continue;
6675                 }
6676
6677                 switch (c) {
6678                 case CTLENDVAR: /* ??? */
6679                         goto breakloop;
6680                 case CTLQUOTEMARK:
6681                         /* "$@" syntax adherence hack */
6682                         if (!inquotes && !memcmp(p, dolatstr + 1, DOLATSTRLEN - 1)) {
6683                                 p = evalvar(p + 1, flags | EXP_QUOTED) + 1;
6684                                 goto start;
6685                         }
6686                         inquotes ^= EXP_QUOTED;
6687  addquote:
6688                         if (flags & QUOTES_ESC) {
6689                                 p--;
6690                                 length++;
6691                                 startloc++;
6692                         }
6693                         break;
6694                 case CTLESC:
6695                         startloc++;
6696                         length++;
6697                         goto addquote;
6698                 case CTLVAR:
6699                         TRACE(("argstr: evalvar('%s')\n", p));
6700                         p = evalvar(p, flags | inquotes);
6701                         TRACE(("argstr: evalvar:'%s'\n", (char *)stackblock()));
6702                         goto start;
6703                 case CTLBACKQ:
6704                         expbackq(argbackq->n, flags | inquotes);
6705                         argbackq = argbackq->next;
6706                         goto start;
6707 #if ENABLE_FEATURE_SH_MATH
6708                 case CTLENDARI:
6709                         p--;
6710                         expari(flags | inquotes);
6711                         goto start;
6712 #endif
6713                 }
6714         }
6715  breakloop: ;
6716 }
6717
6718 static char *
6719 scanleft(char *startp, char *rmesc, char *rmescend UNUSED_PARAM,
6720                 char *pattern, int quotes, int zero)
6721 {
6722         char *loc, *loc2;
6723         char c;
6724
6725         loc = startp;
6726         loc2 = rmesc;
6727         do {
6728                 int match;
6729                 const char *s = loc2;
6730
6731                 c = *loc2;
6732                 if (zero) {
6733                         *loc2 = '\0';
6734                         s = rmesc;
6735                 }
6736                 match = pmatch(pattern, s);
6737
6738                 *loc2 = c;
6739                 if (match)
6740                         return loc;
6741                 if (quotes && (unsigned char)*loc == CTLESC)
6742                         loc++;
6743                 loc++;
6744                 loc2++;
6745         } while (c);
6746         return NULL;
6747 }
6748
6749 static char *
6750 scanright(char *startp, char *rmesc, char *rmescend,
6751                 char *pattern, int quotes, int match_at_start)
6752 {
6753 #if !ENABLE_ASH_OPTIMIZE_FOR_SIZE
6754         int try2optimize = match_at_start;
6755 #endif
6756         int esc = 0;
6757         char *loc;
6758         char *loc2;
6759
6760         /* If we called by "${v/pattern/repl}" or "${v//pattern/repl}":
6761          * startp="escaped_value_of_v" rmesc="raw_value_of_v"
6762          * rmescend=""(ptr to NUL in rmesc) pattern="pattern" quotes=match_at_start=1
6763          * Logic:
6764          * loc starts at NUL at the end of startp, loc2 starts at the end of rmesc,
6765          * and on each iteration they go back two/one char until they reach the beginning.
6766          * We try to find a match in "raw_value_of_v", "raw_value_of_", "raw_value_of" etc.
6767          */
6768         /* TODO: document in what other circumstances we are called. */
6769
6770         for (loc = pattern - 1, loc2 = rmescend; loc >= startp; loc2--) {
6771                 int match;
6772                 char c = *loc2;
6773                 const char *s = loc2;
6774                 if (match_at_start) {
6775                         *loc2 = '\0';
6776                         s = rmesc;
6777                 }
6778                 match = pmatch(pattern, s);
6779                 //bb_error_msg("pmatch(pattern:'%s',s:'%s'):%d", pattern, s, match);
6780                 *loc2 = c;
6781                 if (match)
6782                         return loc;
6783 #if !ENABLE_ASH_OPTIMIZE_FOR_SIZE
6784                 if (try2optimize) {
6785                         /* Maybe we can optimize this:
6786                          * if pattern ends with unescaped *, we can avoid checking
6787                          * shorter strings: if "foo*" doesn't match "raw_value_of_v",
6788                          * it won't match truncated "raw_value_of_" strings too.
6789                          */
6790                         unsigned plen = strlen(pattern);
6791                         /* Does it end with "*"? */
6792                         if (plen != 0 && pattern[--plen] == '*') {
6793                                 /* "xxxx*" is not escaped */
6794                                 /* "xxx\*" is escaped */
6795                                 /* "xx\\*" is not escaped */
6796                                 /* "x\\\*" is escaped */
6797                                 int slashes = 0;
6798                                 while (plen != 0 && pattern[--plen] == '\\')
6799                                         slashes++;
6800                                 if (!(slashes & 1))
6801                                         break; /* ends with unescaped "*" */
6802                         }
6803                         try2optimize = 0;
6804                 }
6805 #endif
6806                 loc--;
6807                 if (quotes) {
6808                         if (--esc < 0) {
6809                                 esc = esclen(startp, loc);
6810                         }
6811                         if (esc % 2) {
6812                                 esc--;
6813                                 loc--;
6814                         }
6815                 }
6816         }
6817         return NULL;
6818 }
6819
6820 static void varunset(const char *, const char *, const char *, int) NORETURN;
6821 static void
6822 varunset(const char *end, const char *var, const char *umsg, int varflags)
6823 {
6824         const char *msg;
6825         const char *tail;
6826
6827         tail = nullstr;
6828         msg = "parameter not set";
6829         if (umsg) {
6830                 if ((unsigned char)*end == CTLENDVAR) {
6831                         if (varflags & VSNUL)
6832                                 tail = " or null";
6833                 } else {
6834                         msg = umsg;
6835                 }
6836         }
6837         ash_msg_and_raise_error("%.*s: %s%s", (int)(end - var - 1), var, msg, tail);
6838 }
6839
6840 static const char *
6841 subevalvar(char *p, char *varname, int strloc, int subtype,
6842                 int startloc, int varflags, int flag)
6843 {
6844         struct nodelist *saveargbackq = argbackq;
6845         int quotes = flag & QUOTES_ESC;
6846         char *startp;
6847         char *loc;
6848         char *rmesc, *rmescend;
6849         char *str;
6850         int amount, resetloc;
6851         int argstr_flags;
6852         IF_BASH_PATTERN_SUBST(int workloc;)
6853         IF_BASH_PATTERN_SUBST(int slash_pos;)
6854         IF_BASH_PATTERN_SUBST(char *repl;)
6855         int zero;
6856         char *(*scan)(char*, char*, char*, char*, int, int);
6857
6858         //bb_error_msg("subevalvar(p:'%s',varname:'%s',strloc:%d,subtype:%d,startloc:%d,varflags:%x,quotes:%d)",
6859         //              p, varname, strloc, subtype, startloc, varflags, quotes);
6860
6861 #if BASH_PATTERN_SUBST
6862         /* For "${v/pattern/repl}", we must find the delimiter _before_
6863          * argstr() call expands possible variable references in pattern:
6864          * think about "v=a; a=a/; echo ${v/$a/r}" case.
6865          */
6866         repl = NULL;
6867         if (subtype == VSREPLACE || subtype == VSREPLACEALL) {
6868                 /* Find '/' and replace with NUL */
6869                 repl = p;
6870                 /* The pattern can't be empty.
6871                  * IOW: if the first char after "${v//" is a slash,
6872                  * it does not terminate the pattern - it's the first char of the pattern:
6873                  *  v=/dev/ram; echo ${v////-}  prints -dev-ram (pattern is "/")
6874                  *  v=/dev/ram; echo ${v///r/-} prints /dev-am  (pattern is "/r")
6875                  */
6876                 if (*repl == '/')
6877                         repl++;
6878                 for (;;) {
6879                         if (*repl == '\0') {
6880                                 repl = NULL;
6881                                 break;
6882                         }
6883                         if (*repl == '/') {
6884                                 *repl = '\0';
6885                                 break;
6886                         }
6887                         /* Handle escaped slashes, e.g. "${v/\//_}" (they are CTLESC'ed by this point) */
6888                         if ((unsigned char)*repl == CTLESC && repl[1])
6889                                 repl++;
6890                         repl++;
6891                 }
6892         }
6893 #endif
6894         argstr_flags = EXP_TILDE;
6895         if (subtype != VSASSIGN
6896          && subtype != VSQUESTION
6897 #if BASH_SUBSTR
6898          && subtype != VSSUBSTR
6899 #endif
6900         ) {
6901                 /* EXP_CASE keeps CTLESC's */
6902                 argstr_flags = EXP_TILDE | EXP_CASE;
6903         }
6904         argstr(p, argstr_flags);
6905         //bb_error_msg("str0:'%s'", (char *)stackblock() + strloc);
6906 #if BASH_PATTERN_SUBST
6907         slash_pos = -1;
6908         if (repl) {
6909                 slash_pos = expdest - ((char *)stackblock() + strloc);
6910                 STPUTC('/', expdest);
6911                 //bb_error_msg("repl+1:'%s'", repl + 1);
6912                 argstr(repl + 1, EXP_TILDE); /* EXP_TILDE: echo "${v/x/~}" expands ~ ! */
6913                 *repl = '/';
6914         }
6915 #endif
6916         STPUTC('\0', expdest);
6917         argbackq = saveargbackq;
6918         startp = (char *)stackblock() + startloc;
6919         //bb_error_msg("str1:'%s'", (char *)stackblock() + strloc);
6920
6921         switch (subtype) {
6922         case VSASSIGN:
6923                 setvar0(varname, startp);
6924                 amount = startp - expdest;
6925                 STADJUST(amount, expdest);
6926                 return startp;
6927
6928         case VSQUESTION:
6929                 varunset(p, varname, startp, varflags);
6930                 /* NOTREACHED */
6931
6932 #if BASH_SUBSTR
6933         case VSSUBSTR: {
6934                 int pos, len, orig_len;
6935                 char *colon;
6936
6937                 loc = str = stackblock() + strloc;
6938
6939                 /* Read POS in ${var:POS:LEN} */
6940                 colon = strchr(loc, ':');
6941                 if (colon) *colon = '\0';
6942                 pos = substr_atoi(loc);
6943                 if (colon) *colon = ':';
6944
6945                 /* Read LEN in ${var:POS:LEN} */
6946                 len = str - startp - 1;
6947                 /* *loc != '\0', guaranteed by parser */
6948                 if (quotes) {
6949                         char *ptr;
6950                         /* Adjust the length by the number of escapes */
6951                         for (ptr = startp; ptr < (str - 1); ptr++) {
6952                                 if ((unsigned char)*ptr == CTLESC) {
6953                                         len--;
6954                                         ptr++;
6955                                 }
6956                         }
6957                 }
6958                 orig_len = len;
6959                 if (*loc++ == ':') {
6960                         /* ${var::LEN} */
6961                         len = substr_atoi(loc);
6962                 } else {
6963                         /* Skip POS in ${var:POS:LEN} */
6964                         len = orig_len;
6965                         while (*loc && *loc != ':')
6966                                 loc++;
6967                         if (*loc++ == ':')
6968                                 len = substr_atoi(loc);
6969                 }
6970                 if (pos < 0) {
6971                         /* ${VAR:$((-n)):l} starts n chars from the end */
6972                         pos = orig_len + pos;
6973                 }
6974                 if ((unsigned)pos >= orig_len) {
6975                         /* apart from obvious ${VAR:999999:l},
6976                          * covers ${VAR:$((-9999999)):l} - result is ""
6977                          * (bash compat)
6978                          */
6979                         pos = 0;
6980                         len = 0;
6981                 }
6982                 if (len < 0) {
6983                         /* ${VAR:N:-M} sets LEN to strlen()-M */
6984                         len = (orig_len - pos) + len;
6985                 }
6986                 if ((unsigned)len > (orig_len - pos))
6987                         len = orig_len - pos;
6988
6989                 for (str = startp; pos; str++, pos--) {
6990                         if (quotes && (unsigned char)*str == CTLESC)
6991                                 str++;
6992                 }
6993                 for (loc = startp; len; len--) {
6994                         if (quotes && (unsigned char)*str == CTLESC)
6995                                 *loc++ = *str++;
6996                         *loc++ = *str++;
6997                 }
6998                 *loc = '\0';
6999                 amount = loc - expdest;
7000                 STADJUST(amount, expdest);
7001                 return loc;
7002         }
7003 #endif /* BASH_SUBSTR */
7004         }
7005
7006         resetloc = expdest - (char *)stackblock();
7007
7008 #if BASH_PATTERN_SUBST
7009         repl = NULL;
7010
7011         /* We'll comeback here if we grow the stack while handling
7012          * a VSREPLACE or VSREPLACEALL, since our pointers into the
7013          * stack will need rebasing, and we'll need to remove our work
7014          * areas each time
7015          */
7016  restart:
7017 #endif
7018
7019         amount = expdest - ((char *)stackblock() + resetloc);
7020         STADJUST(-amount, expdest);
7021         startp = (char *)stackblock() + startloc;
7022
7023         rmesc = startp;
7024         rmescend = (char *)stackblock() + strloc;
7025         //bb_error_msg("str7:'%s'", rmescend);
7026         if (quotes) {
7027 //TODO: how to handle slash_pos here if string changes (shortens?)
7028                 rmesc = rmescapes(startp, RMESCAPE_ALLOC | RMESCAPE_GROW, NULL);
7029                 if (rmesc != startp) {
7030                         rmescend = expdest;
7031                         startp = (char *)stackblock() + startloc;
7032                 }
7033         }
7034         rmescend--;
7035         str = (char *)stackblock() + strloc;
7036         /*
7037          * Example: v='a\bc'; echo ${v/\\b/_\\_\z_}
7038          * The result is a_\_z_c (not a\_\_z_c)!
7039          *
7040          * The search pattern and replace string treat backslashes differently!
7041          * "&slash_pos" causes rmescapes() to work differently on the pattern
7042          * and string.  It's only used on the first call.
7043          */
7044         //bb_error_msg("str8:'%s' slash_pos:%d", str, slash_pos);
7045         rmescapes(str, RMESCAPE_GLOB,
7046                 repl ? NULL : (slash_pos < 0 ? NULL : &slash_pos)
7047         );
7048
7049 #if BASH_PATTERN_SUBST
7050         workloc = expdest - (char *)stackblock();
7051         if (subtype == VSREPLACE || subtype == VSREPLACEALL) {
7052                 int len;
7053                 char *idx, *end;
7054
7055                 if (!repl) {
7056                         //bb_error_msg("str9:'%s' slash_pos:%d", str, slash_pos);
7057                         repl = nullstr;
7058                         if (slash_pos >= 0) {
7059                                 repl = str + slash_pos;
7060                                 *repl++ = '\0';
7061                         }
7062                 }
7063                 //bb_error_msg("str:'%s' repl:'%s'", str, repl);
7064
7065                 /* If there's no pattern to match, return the expansion unmolested */
7066                 if (str[0] == '\0')
7067                         return NULL;
7068
7069                 len = 0;
7070                 idx = startp;
7071                 end = str - 1;
7072                 while (idx < end) {
7073  try_to_match:
7074                         loc = scanright(idx, rmesc, rmescend, str, quotes, 1);
7075                         //bb_error_msg("scanright('%s'):'%s'", str, loc);
7076                         if (!loc) {
7077                                 /* No match, advance */
7078                                 char *restart_detect = stackblock();
7079  skip_matching:
7080                                 STPUTC(*idx, expdest);
7081                                 if (quotes && (unsigned char)*idx == CTLESC) {
7082                                         idx++;
7083                                         len++;
7084                                         STPUTC(*idx, expdest);
7085                                 }
7086                                 if (stackblock() != restart_detect)
7087                                         goto restart;
7088                                 idx++;
7089                                 len++;
7090                                 rmesc++;
7091                                 /* continue; - prone to quadratic behavior, smarter code: */
7092                                 if (idx >= end)
7093                                         break;
7094                                 if (str[0] == '*') {
7095                                         /* Pattern is "*foo". If "*foo" does not match "long_string",
7096                                          * it would never match "ong_string" etc, no point in trying.
7097                                          */
7098                                         goto skip_matching;
7099                                 }
7100                                 goto try_to_match;
7101                         }
7102
7103                         if (subtype == VSREPLACEALL) {
7104                                 while (idx < loc) {
7105                                         if (quotes && (unsigned char)*idx == CTLESC)
7106                                                 idx++;
7107                                         idx++;
7108                                         rmesc++;
7109                                 }
7110                         } else {
7111                                 idx = loc;
7112                         }
7113
7114                         //bb_error_msg("repl:'%s'", repl);
7115                         for (loc = (char*)repl; *loc; loc++) {
7116                                 char *restart_detect = stackblock();
7117                                 if (quotes && *loc == '\\') {
7118                                         STPUTC(CTLESC, expdest);
7119                                         len++;
7120                                 }
7121                                 STPUTC(*loc, expdest);
7122                                 if (stackblock() != restart_detect)
7123                                         goto restart;
7124                                 len++;
7125                         }
7126
7127                         if (subtype == VSREPLACE) {
7128                                 //bb_error_msg("tail:'%s', quotes:%x", idx, quotes);
7129                                 while (*idx) {
7130                                         char *restart_detect = stackblock();
7131                                         STPUTC(*idx, expdest);
7132                                         if (stackblock() != restart_detect)
7133                                                 goto restart;
7134                                         len++;
7135                                         idx++;
7136                                 }
7137                                 break;
7138                         }
7139                 }
7140
7141                 /* We've put the replaced text into a buffer at workloc, now
7142                  * move it to the right place and adjust the stack.
7143                  */
7144                 STPUTC('\0', expdest);
7145                 startp = (char *)stackblock() + startloc;
7146                 memmove(startp, (char *)stackblock() + workloc, len + 1);
7147                 //bb_error_msg("startp:'%s'", startp);
7148                 amount = expdest - (startp + len);
7149                 STADJUST(-amount, expdest);
7150                 return startp;
7151         }
7152 #endif /* BASH_PATTERN_SUBST */
7153
7154         subtype -= VSTRIMRIGHT;
7155 #if DEBUG
7156         if (subtype < 0 || subtype > 7)
7157                 abort();
7158 #endif
7159         /* zero = (subtype == VSTRIMLEFT || subtype == VSTRIMLEFTMAX) */
7160         zero = subtype >> 1;
7161         /* VSTRIMLEFT/VSTRIMRIGHTMAX -> scanleft */
7162         scan = (subtype & 1) ^ zero ? scanleft : scanright;
7163
7164         loc = scan(startp, rmesc, rmescend, str, quotes, zero);
7165         if (loc) {
7166                 if (zero) {
7167                         memmove(startp, loc, str - loc);
7168                         loc = startp + (str - loc) - 1;
7169                 }
7170                 *loc = '\0';
7171                 amount = loc - expdest;
7172                 STADJUST(amount, expdest);
7173         }
7174         return loc;
7175 }
7176
7177 /*
7178  * Add the value of a specialized variable to the stack string.
7179  * name parameter (examples):
7180  * ash -c 'echo $1'      name:'1='
7181  * ash -c 'echo $qwe'    name:'qwe='
7182  * ash -c 'echo $$'      name:'$='
7183  * ash -c 'echo ${$}'    name:'$='
7184  * ash -c 'echo ${$##q}' name:'$=q'
7185  * ash -c 'echo ${#$}'   name:'$='
7186  * note: examples with bad shell syntax:
7187  * ash -c 'echo ${#$1}'  name:'$=1'
7188  * ash -c 'echo ${#1#}'  name:'1=#'
7189  */
7190 static NOINLINE ssize_t
7191 varvalue(char *name, int varflags, int flags, int quoted)
7192 {
7193         const char *p;
7194         int num;
7195         int i;
7196         ssize_t len = 0;
7197         int sep;
7198         int subtype = varflags & VSTYPE;
7199         int discard = subtype == VSPLUS || subtype == VSLENGTH;
7200         int quotes = (discard ? 0 : (flags & QUOTES_ESC)) | QUOTES_KEEPNUL;
7201         int syntax;
7202
7203         sep = (flags & EXP_FULL) << CHAR_BIT;
7204         syntax = quoted ? DQSYNTAX : BASESYNTAX;
7205
7206         switch (*name) {
7207         case '$':
7208                 num = rootpid;
7209                 goto numvar;
7210         case '?':
7211                 num = exitstatus;
7212                 goto numvar;
7213         case '#':
7214                 num = shellparam.nparam;
7215                 goto numvar;
7216         case '!':
7217                 num = backgndpid;
7218                 if (num == 0)
7219                         return -1;
7220  numvar:
7221                 len = cvtnum(num);
7222                 goto check_1char_name;
7223         case '-':
7224                 expdest = makestrspace(NOPTS, expdest);
7225                 for (i = NOPTS - 1; i >= 0; i--) {
7226                         if (optlist[i] && optletters(i)) {
7227                                 USTPUTC(optletters(i), expdest);
7228                                 len++;
7229                         }
7230                 }
7231  check_1char_name:
7232 #if 0
7233                 /* handles cases similar to ${#$1} */
7234                 if (name[2] != '\0')
7235                         raise_error_syntax("bad substitution");
7236 #endif
7237                 break;
7238         case '@':
7239                 if (quoted && sep)
7240                         goto param;
7241                 /* fall through */
7242         case '*': {
7243                 char **ap;
7244                 char sepc;
7245                 char c;
7246
7247                 /* We will set c to 0 or ~0 depending on whether
7248                  * we're doing field splitting.  We won't do field
7249                  * splitting if either we're quoted or sep is zero.
7250                  *
7251                  * Instead of testing (quoted || !sep) the following
7252                  * trick optimises away any branches by using the
7253                  * fact that EXP_QUOTED (which is the only bit that
7254                  * can be set in quoted) is the same as EXP_FULL <<
7255                  * CHAR_BIT (which is the only bit that can be set
7256                  * in sep).
7257                  */
7258 #if EXP_QUOTED >> CHAR_BIT != EXP_FULL
7259 #error The following two lines expect EXP_QUOTED == EXP_FULL << CHAR_BIT
7260 #endif
7261                 c = !((quoted | ~sep) & EXP_QUOTED) - 1;
7262                 sep &= ~quoted;
7263                 sep |= ifsset() ? (unsigned char)(c & ifsval()[0]) : ' ';
7264  param:
7265                 sepc = sep;
7266                 ap = shellparam.p;
7267                 if (!ap)
7268                         return -1;
7269                 while ((p = *ap++) != NULL) {
7270                         len += strtodest(p, syntax, quotes);
7271
7272                         if (*ap && sep) {
7273                                 len++;
7274                                 memtodest(&sepc, 1, syntax, quotes);
7275                         }
7276                 }
7277                 break;
7278         } /* case '*' */
7279         case '0':
7280         case '1':
7281         case '2':
7282         case '3':
7283         case '4':
7284         case '5':
7285         case '6':
7286         case '7':
7287         case '8':
7288         case '9':
7289                 num = atoi(name); /* number(name) fails on ${N#str} etc */
7290                 if (num < 0 || num > shellparam.nparam)
7291                         return -1;
7292                 p = num ? shellparam.p[num - 1] : arg0;
7293                 goto value;
7294         default:
7295                 /* NB: name has form "VAR=..." */
7296                 p = lookupvar(name);
7297  value:
7298                 if (!p)
7299                         return -1;
7300
7301                 len = strtodest(p, syntax, quotes);
7302 #if ENABLE_UNICODE_SUPPORT
7303                 if (subtype == VSLENGTH && len > 0) {
7304                         reinit_unicode_for_ash();
7305                         if (unicode_status == UNICODE_ON) {
7306                                 STADJUST(-len, expdest);
7307                                 discard = 0;
7308                                 len = unicode_strlen(p);
7309                         }
7310                 }
7311 #endif
7312                 break;
7313         }
7314
7315         if (discard)
7316                 STADJUST(-len, expdest);
7317         return len;
7318 }
7319
7320 /*
7321  * Expand a variable, and return a pointer to the next character in the
7322  * input string.
7323  */
7324 static char *
7325 evalvar(char *p, int flag)
7326 {
7327         char varflags;
7328         char subtype;
7329         int quoted;
7330         char *var;
7331         int patloc;
7332         int startloc;
7333         ssize_t varlen;
7334
7335         varflags = (unsigned char) *p++;
7336         subtype = varflags & VSTYPE;
7337
7338         if (!subtype)
7339                 raise_error_syntax("bad substitution");
7340
7341         quoted = flag & EXP_QUOTED;
7342         var = p;
7343         startloc = expdest - (char *)stackblock();
7344         p = strchr(p, '=') + 1; //TODO: use var_end(p)?
7345
7346  again:
7347         varlen = varvalue(var, varflags, flag, quoted);
7348         if (varflags & VSNUL)
7349                 varlen--;
7350
7351         if (subtype == VSPLUS) {
7352                 varlen = -1 - varlen;
7353                 goto vsplus;
7354         }
7355
7356         if (subtype == VSMINUS) {
7357  vsplus:
7358                 if (varlen < 0) {
7359                         argstr(
7360                                 p,
7361                                 flag | EXP_TILDE | EXP_WORD
7362                         );
7363                         goto end;
7364                 }
7365                 goto record;
7366         }
7367
7368         if (subtype == VSASSIGN || subtype == VSQUESTION) {
7369                 if (varlen >= 0)
7370                         goto record;
7371
7372                 subevalvar(p, var, 0, subtype, startloc, varflags,
7373                            flag & ~QUOTES_ESC);
7374                 varflags &= ~VSNUL;
7375                 /*
7376                  * Remove any recorded regions beyond
7377                  * start of variable
7378                  */
7379                 removerecordregions(startloc);
7380                 goto again;
7381         }
7382
7383         if (varlen < 0 && uflag)
7384                 varunset(p, var, 0, 0);
7385
7386         if (subtype == VSLENGTH) {
7387                 cvtnum(varlen > 0 ? varlen : 0);
7388                 goto record;
7389         }
7390
7391         if (subtype == VSNORMAL) {
7392  record:
7393                 if (quoted) {
7394                         quoted = *var == '@' && shellparam.nparam;
7395                         if (!quoted)
7396                                 goto end;
7397                 }
7398                 recordregion(startloc, expdest - (char *)stackblock(), quoted);
7399                 goto end;
7400         }
7401
7402 #if DEBUG
7403         switch (subtype) {
7404         case VSTRIMLEFT:
7405         case VSTRIMLEFTMAX:
7406         case VSTRIMRIGHT:
7407         case VSTRIMRIGHTMAX:
7408 #if BASH_SUBSTR
7409         case VSSUBSTR:
7410 #endif
7411 #if BASH_PATTERN_SUBST
7412         case VSREPLACE:
7413         case VSREPLACEALL:
7414 #endif
7415                 break;
7416         default:
7417                 abort();
7418         }
7419 #endif
7420
7421         if (varlen >= 0) {
7422                 /*
7423                  * Terminate the string and start recording the pattern
7424                  * right after it
7425                  */
7426                 STPUTC('\0', expdest);
7427                 patloc = expdest - (char *)stackblock();
7428                 if (NULL == subevalvar(p, /* varname: */ NULL, patloc, subtype,
7429                                 startloc, varflags, flag)) {
7430                         int amount = expdest - (
7431                                 (char *)stackblock() + patloc - 1
7432                         );
7433                         STADJUST(-amount, expdest);
7434                 }
7435                 /* Remove any recorded regions beyond start of variable */
7436                 removerecordregions(startloc);
7437                 goto record;
7438         }
7439
7440  end:
7441         if (subtype != VSNORMAL) {      /* skip to end of alternative */
7442                 int nesting = 1;
7443                 for (;;) {
7444                         unsigned char c = *p++;
7445                         if (c == CTLESC)
7446                                 p++;
7447                         else if (c == CTLBACKQ) {
7448                                 if (varlen >= 0)
7449                                         argbackq = argbackq->next;
7450                         } else if (c == CTLVAR) {
7451                                 if ((*p++ & VSTYPE) != VSNORMAL)
7452                                         nesting++;
7453                         } else if (c == CTLENDVAR) {
7454                                 if (--nesting == 0)
7455                                         break;
7456                         }
7457                 }
7458         }
7459         return p;
7460 }
7461
7462 /*
7463  * Add a file name to the list.
7464  */
7465 static void
7466 addfname(const char *name)
7467 {
7468         struct strlist *sp;
7469
7470         sp = stzalloc(sizeof(*sp));
7471         sp->text = sstrdup(name);
7472         *exparg.lastp = sp;
7473         exparg.lastp = &sp->next;
7474 }
7475
7476 /* Avoid glob() (and thus, stat() et al) for words like "echo" */
7477 static int
7478 hasmeta(const char *p)
7479 {
7480         static const char chars[] ALIGN1 = {
7481                 '*', '?', '[', '\\', CTLQUOTEMARK, CTLESC, 0
7482         };
7483
7484         for (;;) {
7485                 p = strpbrk(p, chars);
7486                 if (!p)
7487                         break;
7488                 switch ((unsigned char)*p) {
7489                 case CTLQUOTEMARK:
7490                         for (;;) {
7491                                 p++;
7492                                 if ((unsigned char)*p == CTLQUOTEMARK)
7493                                         break;
7494                                 if ((unsigned char)*p == CTLESC)
7495                                         p++;
7496                                 if (*p == '\0') /* huh? */
7497                                         return 0;
7498                         }
7499                         break;
7500                 case '\\':
7501                 case CTLESC:
7502                         p++;
7503                         if (*p == '\0')
7504                                 return 0;
7505                         break;
7506                 case '[':
7507                         if (!strchr(p + 1, ']')) {
7508                                 /* It's not a properly closed [] pattern,
7509                                  * but other metas may follow. Continue checking.
7510                                  * my[file* _is_ globbed by bash
7511                                  * and matches filenames like "my[file1".
7512                                  */
7513                                 break;
7514                         }
7515                         /* fallthrough */
7516                 default:
7517                 /* case '*': */
7518                 /* case '?': */
7519                         return 1;
7520                 }
7521                 p++;
7522         }
7523
7524         return 0;
7525 }
7526
7527 /* If we want to use glob() from libc... */
7528 #if !ENABLE_ASH_INTERNAL_GLOB
7529
7530 /* Add the result of glob() to the list */
7531 static void
7532 addglob(const glob_t *pglob)
7533 {
7534         char **p = pglob->gl_pathv;
7535
7536         do {
7537                 addfname(*p);
7538         } while (*++p);
7539 }
7540 static void
7541 expandmeta(struct strlist *str /*, int flag*/)
7542 {
7543         /* TODO - EXP_REDIR */
7544
7545         while (str) {
7546                 char *p;
7547                 glob_t pglob;
7548                 int i;
7549
7550                 if (fflag)
7551                         goto nometa;
7552
7553                 if (!hasmeta(str->text))
7554                         goto nometa;
7555
7556                 INT_OFF;
7557                 p = preglob(str->text, RMESCAPE_ALLOC | RMESCAPE_HEAP);
7558 // GLOB_NOMAGIC (GNU): if no *?[ chars in pattern, return it even if no match
7559 // GLOB_NOCHECK: if no match, return unchanged pattern (sans \* escapes?)
7560 //
7561 // glibc 2.24.90 glob(GLOB_NOMAGIC) does not remove backslashes used for escaping:
7562 // if you pass it "file\?", it returns "file\?", not "file?", if no match.
7563 // Which means you need to unescape the string, right? Not so fast:
7564 // if there _is_ a file named "file\?" (with backslash), it is returned
7565 // as "file\?" too (whichever pattern you used to find it, say, "file*").
7566 // You DON'T KNOW by looking at the result whether you need to unescape it.
7567 //
7568 // Worse, globbing of "file\?" in a directory with two files, "file?" and "file\?",
7569 // returns "file\?" - which is WRONG: "file\?" pattern matches "file?" file.
7570 // Without GLOB_NOMAGIC, this works correctly ("file?" is returned as a match).
7571 // With GLOB_NOMAGIC | GLOB_NOCHECK, this also works correctly.
7572 //              i = glob(p, GLOB_NOMAGIC | GLOB_NOCHECK, NULL, &pglob);
7573 //              i = glob(p, GLOB_NOMAGIC, NULL, &pglob);
7574                 i = glob(p, 0, NULL, &pglob);
7575                 //bb_error_msg("glob('%s'):%d '%s'...", p, i, pglob.gl_pathv ? pglob.gl_pathv[0] : "-");
7576                 if (p != str->text)
7577                         free(p);
7578                 switch (i) {
7579                 case 0:
7580 #if 0 // glibc 2.24.90 bug? Patterns like "*/file", when match, don't set GLOB_MAGCHAR
7581                         /* GLOB_MAGCHAR is set if *?[ chars were seen (GNU) */
7582                         if (!(pglob.gl_flags & GLOB_MAGCHAR))
7583                                 goto nometa2;
7584 #endif
7585                         addglob(&pglob);
7586                         globfree(&pglob);
7587                         INT_ON;
7588                         break;
7589                 case GLOB_NOMATCH:
7590  //nometa2:
7591                         globfree(&pglob);
7592                         INT_ON;
7593  nometa:
7594                         *exparg.lastp = str;
7595                         rmescapes(str->text, 0, NULL);
7596                         exparg.lastp = &str->next;
7597                         break;
7598                 default:        /* GLOB_NOSPACE */
7599                         globfree(&pglob);
7600                         INT_ON;
7601                         ash_msg_and_raise_error(bb_msg_memory_exhausted);
7602                 }
7603                 str = str->next;
7604         }
7605 }
7606
7607 #else
7608 /* ENABLE_ASH_INTERNAL_GLOB: Homegrown globbing code. (dash also has both, uses homegrown one.) */
7609
7610 /*
7611  * Do metacharacter (i.e. *, ?, [...]) expansion.
7612  */
7613 typedef struct exp_t {
7614         char *dir;
7615         unsigned dir_max;
7616 } exp_t;
7617 static void
7618 expmeta(exp_t *exp, char *name, unsigned name_len, unsigned expdir_len)
7619 {
7620 #define expdir exp->dir
7621 #define expdir_max exp->dir_max
7622         char *enddir = expdir + expdir_len;
7623         char *p;
7624         const char *cp;
7625         char *start;
7626         char *endname;
7627         int metaflag;
7628         struct stat statb;
7629         DIR *dirp;
7630         struct dirent *dp;
7631         int atend;
7632         int matchdot;
7633         int esc;
7634
7635         metaflag = 0;
7636         start = name;
7637         for (p = name; esc = 0, *p; p += esc + 1) {
7638                 if (*p == '*' || *p == '?')
7639                         metaflag = 1;
7640                 else if (*p == '[') {
7641                         char *q = p + 1;
7642                         if (*q == '!')
7643                                 q++;
7644                         for (;;) {
7645                                 if (*q == '\\')
7646                                         q++;
7647                                 if (*q == '/' || *q == '\0')
7648                                         break;
7649                                 if (*++q == ']') {
7650                                         metaflag = 1;
7651                                         break;
7652                                 }
7653                         }
7654                 } else {
7655                         if (*p == '\\' && p[1])
7656                                 esc++;
7657                         if (p[esc] == '/') {
7658                                 if (metaflag)
7659                                         break;
7660                                 start = p + esc + 1;
7661                         }
7662                 }
7663         }
7664         if (metaflag == 0) {    /* we've reached the end of the file name */
7665                 if (!expdir_len)
7666                         return;
7667                 p = name;
7668                 do {
7669                         if (*p == '\\' && p[1])
7670                                 p++;
7671                         *enddir++ = *p;
7672                 } while (*p++);
7673                 if (lstat(expdir, &statb) == 0)
7674                         addfname(expdir);
7675                 return;
7676         }
7677         endname = p;
7678         if (name < start) {
7679                 p = name;
7680                 do {
7681                         if (*p == '\\' && p[1])
7682                                 p++;
7683                         *enddir++ = *p++;
7684                 } while (p < start);
7685         }
7686         *enddir = '\0';
7687         cp = expdir;
7688         expdir_len = enddir - cp;
7689         if (!expdir_len)
7690                 cp = ".";
7691         dirp = opendir(cp);
7692         if (dirp == NULL)
7693                 return;
7694         if (*endname == 0) {
7695                 atend = 1;
7696         } else {
7697                 atend = 0;
7698                 *endname = '\0';
7699                 endname += esc + 1;
7700         }
7701         name_len -= endname - name;
7702         matchdot = 0;
7703         p = start;
7704         if (*p == '\\')
7705                 p++;
7706         if (*p == '.')
7707                 matchdot++;
7708         while (!pending_int && (dp = readdir(dirp)) != NULL) {
7709                 if (dp->d_name[0] == '.' && !matchdot)
7710                         continue;
7711                 if (pmatch(start, dp->d_name)) {
7712                         if (atend) {
7713                                 strcpy(enddir, dp->d_name);
7714                                 addfname(expdir);
7715                         } else {
7716                                 unsigned offset;
7717                                 unsigned len;
7718
7719                                 p = stpcpy(enddir, dp->d_name);
7720                                 *p = '/';
7721
7722                                 offset = p - expdir + 1;
7723                                 len = offset + name_len + NAME_MAX;
7724                                 if (len > expdir_max) {
7725                                         len += PATH_MAX;
7726                                         expdir = ckrealloc(expdir, len);
7727                                         expdir_max = len;
7728                                 }
7729
7730                                 expmeta(exp, endname, name_len, offset);
7731                                 enddir = expdir + expdir_len;
7732                         }
7733                 }
7734         }
7735         closedir(dirp);
7736         if (!atend)
7737                 endname[-esc - 1] = esc ? '\\' : '/';
7738 #undef expdir
7739 #undef expdir_max
7740 }
7741
7742 static struct strlist *
7743 msort(struct strlist *list, int len)
7744 {
7745         struct strlist *p, *q = NULL;
7746         struct strlist **lpp;
7747         int half;
7748         int n;
7749
7750         if (len <= 1)
7751                 return list;
7752         half = len >> 1;
7753         p = list;
7754         for (n = half; --n >= 0;) {
7755                 q = p;
7756                 p = p->next;
7757         }
7758         q->next = NULL;                 /* terminate first half of list */
7759         q = msort(list, half);          /* sort first half of list */
7760         p = msort(p, len - half);               /* sort second half */
7761         lpp = &list;
7762         for (;;) {
7763 #if ENABLE_LOCALE_SUPPORT
7764                 if (strcoll(p->text, q->text) < 0)
7765 #else
7766                 if (strcmp(p->text, q->text) < 0)
7767 #endif
7768                                                 {
7769                         *lpp = p;
7770                         lpp = &p->next;
7771                         p = *lpp;
7772                         if (p == NULL) {
7773                                 *lpp = q;
7774                                 break;
7775                         }
7776                 } else {
7777                         *lpp = q;
7778                         lpp = &q->next;
7779                         q = *lpp;
7780                         if (q == NULL) {
7781                                 *lpp = p;
7782                                 break;
7783                         }
7784                 }
7785         }
7786         return list;
7787 }
7788
7789 /*
7790  * Sort the results of file name expansion.  It calculates the number of
7791  * strings to sort and then calls msort (short for merge sort) to do the
7792  * work.
7793  */
7794 static struct strlist *
7795 expsort(struct strlist *str)
7796 {
7797         int len;
7798         struct strlist *sp;
7799
7800         len = 0;
7801         for (sp = str; sp; sp = sp->next)
7802                 len++;
7803         return msort(str, len);
7804 }
7805
7806 static void
7807 expandmeta(struct strlist *str /*, int flag*/)
7808 {
7809         /* TODO - EXP_REDIR */
7810
7811         while (str) {
7812                 exp_t exp;
7813                 struct strlist **savelastp;
7814                 struct strlist *sp;
7815                 char *p;
7816                 unsigned len;
7817
7818                 if (fflag)
7819                         goto nometa;
7820                 if (!hasmeta(str->text))
7821                         goto nometa;
7822                 savelastp = exparg.lastp;
7823
7824                 INT_OFF;
7825                 p = preglob(str->text, RMESCAPE_ALLOC | RMESCAPE_HEAP);
7826                 len = strlen(p);
7827                 exp.dir_max = len + PATH_MAX;
7828                 exp.dir = ckmalloc(exp.dir_max);
7829
7830                 expmeta(&exp, p, len, 0);
7831                 free(exp.dir);
7832                 if (p != str->text)
7833                         free(p);
7834                 INT_ON;
7835                 if (exparg.lastp == savelastp) {
7836                         /*
7837                          * no matches
7838                          */
7839  nometa:
7840                         *exparg.lastp = str;
7841                         rmescapes(str->text, 0, NULL);
7842                         exparg.lastp = &str->next;
7843                 } else {
7844                         *exparg.lastp = NULL;
7845                         *savelastp = sp = expsort(*savelastp);
7846                         while (sp->next != NULL)
7847                                 sp = sp->next;
7848                         exparg.lastp = &sp->next;
7849                 }
7850                 str = str->next;
7851         }
7852 }
7853 #endif /* ENABLE_ASH_INTERNAL_GLOB */
7854
7855 /*
7856  * Perform variable substitution and command substitution on an argument,
7857  * placing the resulting list of arguments in arglist.  If EXP_FULL is true,
7858  * perform splitting and file name expansion.  When arglist is NULL, perform
7859  * here document expansion.
7860  */
7861 static void
7862 expandarg(union node *arg, struct arglist *arglist, int flag)
7863 {
7864         struct strlist *sp;
7865         char *p;
7866
7867         argbackq = arg->narg.backquote;
7868         STARTSTACKSTR(expdest);
7869         TRACE(("expandarg: argstr('%s',flags:%x)\n", arg->narg.text, flag));
7870         argstr(arg->narg.text, flag);
7871         p = _STPUTC('\0', expdest);
7872         expdest = p - 1;
7873         if (arglist == NULL) {
7874                 /* here document expanded */
7875                 goto out;
7876         }
7877         p = grabstackstr(p);
7878         TRACE(("expandarg: p:'%s'\n", p));
7879         exparg.lastp = &exparg.list;
7880         /*
7881          * TODO - EXP_REDIR
7882          */
7883         if (flag & EXP_FULL) {
7884                 ifsbreakup(p, &exparg);
7885                 *exparg.lastp = NULL;
7886                 exparg.lastp = &exparg.list;
7887                 expandmeta(exparg.list /*, flag*/);
7888         } else {
7889                 sp = stzalloc(sizeof(*sp));
7890                 sp->text = p;
7891                 *exparg.lastp = sp;
7892                 exparg.lastp = &sp->next;
7893         }
7894         *exparg.lastp = NULL;
7895         if (exparg.list) {
7896                 *arglist->lastp = exparg.list;
7897                 arglist->lastp = exparg.lastp;
7898         }
7899
7900  out:
7901         ifsfree();
7902 }
7903
7904 /*
7905  * Expand shell variables and backquotes inside a here document.
7906  */
7907 static void
7908 expandhere(union node *arg, int fd)
7909 {
7910         expandarg(arg, (struct arglist *)NULL, EXP_QUOTED);
7911         full_write(fd, stackblock(), expdest - (char *)stackblock());
7912 }
7913
7914 /*
7915  * Returns true if the pattern matches the string.
7916  */
7917 static int
7918 patmatch(char *pattern, const char *string)
7919 {
7920         char *p = preglob(pattern, 0);
7921         int r = pmatch(p, string);
7922         //bb_error_msg("!fnmatch(pattern:'%s',str:'%s',0):%d", p, string, r);
7923         return r;
7924 }
7925
7926 /*
7927  * See if a pattern matches in a case statement.
7928  */
7929 static int
7930 casematch(union node *pattern, char *val)
7931 {
7932         struct stackmark smark;
7933         int result;
7934
7935         setstackmark(&smark);
7936         argbackq = pattern->narg.backquote;
7937         STARTSTACKSTR(expdest);
7938         argstr(pattern->narg.text, EXP_TILDE | EXP_CASE);
7939         STACKSTRNUL(expdest);
7940         ifsfree();
7941         result = patmatch(stackblock(), val);
7942         popstackmark(&smark);
7943         return result;
7944 }
7945
7946
7947 /* ============ find_command */
7948
7949 struct builtincmd {
7950         const char *name;
7951         int (*builtin)(int, char **) FAST_FUNC;
7952         /* unsigned flags; */
7953 };
7954 #define IS_BUILTIN_SPECIAL(b) ((b)->name[0] & 1)
7955 /* "regular" builtins always take precedence over commands,
7956  * regardless of PATH=....%builtin... position */
7957 #define IS_BUILTIN_REGULAR(b) ((b)->name[0] & 2)
7958 #define IS_BUILTIN_ASSIGN(b)  ((b)->name[0] & 4)
7959
7960 struct cmdentry {
7961         smallint cmdtype;       /* CMDxxx */
7962         union param {
7963                 int index;
7964                 /* index >= 0 for commands without path (slashes) */
7965                 /* (TODO: what exactly does the value mean? PATH position?) */
7966                 /* index == -1 for commands with slashes */
7967                 /* index == (-2 - applet_no) for NOFORK applets */
7968                 const struct builtincmd *cmd;
7969                 struct funcnode *func;
7970         } u;
7971 };
7972 /* values of cmdtype */
7973 #define CMDUNKNOWN      -1      /* no entry in table for command */
7974 #define CMDNORMAL       0       /* command is an executable program */
7975 #define CMDFUNCTION     1       /* command is a shell function */
7976 #define CMDBUILTIN      2       /* command is a shell builtin */
7977
7978 /* action to find_command() */
7979 #define DO_ERR          0x01    /* prints errors */
7980 #define DO_ABS          0x02    /* checks absolute paths */
7981 #define DO_NOFUNC       0x04    /* don't return shell functions, for command */
7982 #define DO_ALTPATH      0x08    /* using alternate path */
7983 #define DO_ALTBLTIN     0x20    /* %builtin in alt. path */
7984
7985 static void find_command(char *, struct cmdentry *, int, const char *);
7986
7987
7988 /* ============ Hashing commands */
7989
7990 /*
7991  * When commands are first encountered, they are entered in a hash table.
7992  * This ensures that a full path search will not have to be done for them
7993  * on each invocation.
7994  *
7995  * We should investigate converting to a linear search, even though that
7996  * would make the command name "hash" a misnomer.
7997  */
7998
7999 struct tblentry {
8000         struct tblentry *next;  /* next entry in hash chain */
8001         union param param;      /* definition of builtin function */
8002         smallint cmdtype;       /* CMDxxx */
8003         char rehash;            /* if set, cd done since entry created */
8004         char cmdname[1];        /* name of command */
8005 };
8006
8007 static struct tblentry **cmdtable;
8008 #define INIT_G_cmdtable() do { \
8009         cmdtable = xzalloc(CMDTABLESIZE * sizeof(cmdtable[0])); \
8010 } while (0)
8011
8012 static int builtinloc = -1;     /* index in path of %builtin, or -1 */
8013
8014
8015 static void
8016 tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) const char *cmd, char **argv, char **envp)
8017 {
8018 #if ENABLE_FEATURE_SH_STANDALONE
8019         if (applet_no >= 0) {
8020                 if (APPLET_IS_NOEXEC(applet_no)) {
8021                         clearenv();
8022                         while (*envp)
8023                                 putenv(*envp++);
8024                         popredir(/*drop:*/ 1);
8025                         run_noexec_applet_and_exit(applet_no, cmd, argv);
8026                 }
8027                 /* re-exec ourselves with the new arguments */
8028                 execve(bb_busybox_exec_path, argv, envp);
8029                 /* If they called chroot or otherwise made the binary no longer
8030                  * executable, fall through */
8031         }
8032 #endif
8033
8034  repeat:
8035 #ifdef SYSV
8036         do {
8037                 execve(cmd, argv, envp);
8038         } while (errno == EINTR);
8039 #else
8040         execve(cmd, argv, envp);
8041 #endif
8042         if (cmd != bb_busybox_exec_path && errno == ENOEXEC) {
8043                 /* Run "cmd" as a shell script:
8044                  * http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html
8045                  * "If the execve() function fails with ENOEXEC, the shell
8046                  * shall execute a command equivalent to having a shell invoked
8047                  * with the command name as its first operand,
8048                  * with any remaining arguments passed to the new shell"
8049                  *
8050                  * That is, do not use $SHELL, user's shell, or /bin/sh;
8051                  * just call ourselves.
8052                  *
8053                  * Note that bash reads ~80 chars of the file, and if it sees
8054                  * a zero byte before it sees newline, it doesn't try to
8055                  * interpret it, but fails with "cannot execute binary file"
8056                  * message and exit code 126. For one, this prevents attempts
8057                  * to interpret foreign ELF binaries as shell scripts.
8058                  */
8059                 argv[0] = (char*) cmd;
8060                 cmd = bb_busybox_exec_path;
8061                 /* NB: this is only possible because all callers of shellexec()
8062                  * ensure that the argv[-1] slot exists!
8063                  */
8064                 argv--;
8065                 argv[0] = (char*) "ash";
8066                 goto repeat;
8067         }
8068 }
8069
8070 /*
8071  * Exec a program.  Never returns.  If you change this routine, you may
8072  * have to change the find_command routine as well.
8073  * argv[-1] must exist and be writable! See tryexec() for why.
8074  */
8075 static void shellexec(char *prog, char **argv, const char *path, int idx) NORETURN;
8076 static void shellexec(char *prog, char **argv, const char *path, int idx)
8077 {
8078         char *cmdname;
8079         int e;
8080         char **envp;
8081         int exerrno;
8082         int applet_no = -1; /* used only by FEATURE_SH_STANDALONE */
8083
8084         envp = listvars(VEXPORT, VUNSET, /*strlist:*/ NULL, /*end:*/ NULL);
8085         if (strchr(prog, '/') != NULL
8086 #if ENABLE_FEATURE_SH_STANDALONE
8087          || (applet_no = find_applet_by_name(prog)) >= 0
8088 #endif
8089         ) {
8090                 tryexec(IF_FEATURE_SH_STANDALONE(applet_no,) prog, argv, envp);
8091                 if (applet_no >= 0) {
8092                         /* We tried execing ourself, but it didn't work.
8093                          * Maybe /proc/self/exe doesn't exist?
8094                          * Try $PATH search.
8095                          */
8096                         goto try_PATH;
8097                 }
8098                 e = errno;
8099         } else {
8100  try_PATH:
8101                 e = ENOENT;
8102                 while ((cmdname = path_advance(&path, prog)) != NULL) {
8103                         if (--idx < 0 && pathopt == NULL) {
8104                                 tryexec(IF_FEATURE_SH_STANDALONE(-1,) cmdname, argv, envp);
8105                                 if (errno != ENOENT && errno != ENOTDIR)
8106                                         e = errno;
8107                         }
8108                         stunalloc(cmdname);
8109                 }
8110         }
8111
8112         /* Map to POSIX errors */
8113         switch (e) {
8114         default:
8115                 exerrno = 126;
8116                 break;
8117         case ELOOP:
8118         case ENAMETOOLONG:
8119         case ENOENT:
8120         case ENOTDIR:
8121                 exerrno = 127;
8122                 break;
8123         }
8124         exitstatus = exerrno;
8125         TRACE(("shellexec failed for %s, errno %d, suppress_int %d\n",
8126                 prog, e, suppress_int));
8127         ash_msg_and_raise(EXEXIT, "%s: %s", prog, errmsg(e, "not found"));
8128         /* NOTREACHED */
8129 }
8130
8131 static void
8132 printentry(struct tblentry *cmdp)
8133 {
8134         int idx;
8135         const char *path;
8136         char *name;
8137
8138         idx = cmdp->param.index;
8139         path = pathval();
8140         do {
8141                 name = path_advance(&path, cmdp->cmdname);
8142                 stunalloc(name);
8143         } while (--idx >= 0);
8144         out1fmt("%s%s\n", name, (cmdp->rehash ? "*" : nullstr));
8145 }
8146
8147 /*
8148  * Clear out command entries.  The argument specifies the first entry in
8149  * PATH which has changed.
8150  */
8151 static void
8152 clearcmdentry(int firstchange)
8153 {
8154         struct tblentry **tblp;
8155         struct tblentry **pp;
8156         struct tblentry *cmdp;
8157
8158         INT_OFF;
8159         for (tblp = cmdtable; tblp < &cmdtable[CMDTABLESIZE]; tblp++) {
8160                 pp = tblp;
8161                 while ((cmdp = *pp) != NULL) {
8162                         if ((cmdp->cmdtype == CMDNORMAL &&
8163                              cmdp->param.index >= firstchange)
8164                          || (cmdp->cmdtype == CMDBUILTIN &&
8165                              builtinloc >= firstchange)
8166                         ) {
8167                                 *pp = cmdp->next;
8168                                 free(cmdp);
8169                         } else {
8170                                 pp = &cmdp->next;
8171                         }
8172                 }
8173         }
8174         INT_ON;
8175 }
8176
8177 /*
8178  * Locate a command in the command hash table.  If "add" is nonzero,
8179  * add the command to the table if it is not already present.  The
8180  * variable "lastcmdentry" is set to point to the address of the link
8181  * pointing to the entry, so that delete_cmd_entry can delete the
8182  * entry.
8183  *
8184  * Interrupts must be off if called with add != 0.
8185  */
8186 static struct tblentry **lastcmdentry;
8187
8188 static struct tblentry *
8189 cmdlookup(const char *name, int add)
8190 {
8191         unsigned int hashval;
8192         const char *p;
8193         struct tblentry *cmdp;
8194         struct tblentry **pp;
8195
8196         p = name;
8197         hashval = (unsigned char)*p << 4;
8198         while (*p)
8199                 hashval += (unsigned char)*p++;
8200         hashval &= 0x7FFF;
8201         pp = &cmdtable[hashval % CMDTABLESIZE];
8202         for (cmdp = *pp; cmdp; cmdp = cmdp->next) {
8203                 if (strcmp(cmdp->cmdname, name) == 0)
8204                         break;
8205                 pp = &cmdp->next;
8206         }
8207         if (add && cmdp == NULL) {
8208                 cmdp = *pp = ckzalloc(sizeof(struct tblentry)
8209                                 + strlen(name)
8210                                 /* + 1 - already done because
8211                                  * tblentry::cmdname is char[1] */);
8212                 /*cmdp->next = NULL; - ckzalloc did it */
8213                 cmdp->cmdtype = CMDUNKNOWN;
8214                 strcpy(cmdp->cmdname, name);
8215         }
8216         lastcmdentry = pp;
8217         return cmdp;
8218 }
8219
8220 /*
8221  * Delete the command entry returned on the last lookup.
8222  */
8223 static void
8224 delete_cmd_entry(void)
8225 {
8226         struct tblentry *cmdp;
8227
8228         INT_OFF;
8229         cmdp = *lastcmdentry;
8230         *lastcmdentry = cmdp->next;
8231         if (cmdp->cmdtype == CMDFUNCTION)
8232                 freefunc(cmdp->param.func);
8233         free(cmdp);
8234         INT_ON;
8235 }
8236
8237 /*
8238  * Add a new command entry, replacing any existing command entry for
8239  * the same name - except special builtins.
8240  */
8241 static void
8242 addcmdentry(char *name, struct cmdentry *entry)
8243 {
8244         struct tblentry *cmdp;
8245
8246         cmdp = cmdlookup(name, 1);
8247         if (cmdp->cmdtype == CMDFUNCTION) {
8248                 freefunc(cmdp->param.func);
8249         }
8250         cmdp->cmdtype = entry->cmdtype;
8251         cmdp->param = entry->u;
8252         cmdp->rehash = 0;
8253 }
8254
8255 static int FAST_FUNC
8256 hashcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
8257 {
8258         struct tblentry **pp;
8259         struct tblentry *cmdp;
8260         int c;
8261         struct cmdentry entry;
8262         char *name;
8263
8264         if (nextopt("r") != '\0') {
8265                 clearcmdentry(0);
8266                 return 0;
8267         }
8268
8269         if (*argptr == NULL) {
8270                 for (pp = cmdtable; pp < &cmdtable[CMDTABLESIZE]; pp++) {
8271                         for (cmdp = *pp; cmdp; cmdp = cmdp->next) {
8272                                 if (cmdp->cmdtype == CMDNORMAL)
8273                                         printentry(cmdp);
8274                         }
8275                 }
8276                 return 0;
8277         }
8278
8279         c = 0;
8280         while ((name = *argptr) != NULL) {
8281                 cmdp = cmdlookup(name, 0);
8282                 if (cmdp != NULL
8283                  && (cmdp->cmdtype == CMDNORMAL
8284                      || (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0))
8285                 ) {
8286                         delete_cmd_entry();
8287                 }
8288                 find_command(name, &entry, DO_ERR, pathval());
8289                 if (entry.cmdtype == CMDUNKNOWN)
8290                         c = 1;
8291                 argptr++;
8292         }
8293         return c;
8294 }
8295
8296 /*
8297  * Called when a cd is done.  Marks all commands so the next time they
8298  * are executed they will be rehashed.
8299  */
8300 static void
8301 hashcd(void)
8302 {
8303         struct tblentry **pp;
8304         struct tblentry *cmdp;
8305
8306         for (pp = cmdtable; pp < &cmdtable[CMDTABLESIZE]; pp++) {
8307                 for (cmdp = *pp; cmdp; cmdp = cmdp->next) {
8308                         if (cmdp->cmdtype == CMDNORMAL
8309                          || (cmdp->cmdtype == CMDBUILTIN
8310                              && !IS_BUILTIN_REGULAR(cmdp->param.cmd)
8311                              && builtinloc > 0)
8312                         ) {
8313                                 cmdp->rehash = 1;
8314                         }
8315                 }
8316         }
8317 }
8318
8319 /*
8320  * Fix command hash table when PATH changed.
8321  * Called before PATH is changed.  The argument is the new value of PATH;
8322  * pathval() still returns the old value at this point.
8323  * Called with interrupts off.
8324  */
8325 static void FAST_FUNC
8326 changepath(const char *new)
8327 {
8328         const char *old;
8329         int firstchange;
8330         int idx;
8331         int idx_bltin;
8332
8333         old = pathval();
8334         firstchange = 9999;     /* assume no change */
8335         idx = 0;
8336         idx_bltin = -1;
8337         for (;;) {
8338                 if (*old != *new) {
8339                         firstchange = idx;
8340                         if ((*old == '\0' && *new == ':')
8341                          || (*old == ':' && *new == '\0')
8342                         ) {
8343                                 firstchange++;
8344                         }
8345                         old = new;      /* ignore subsequent differences */
8346                 }
8347                 if (*new == '\0')
8348                         break;
8349                 if (*new == '%' && idx_bltin < 0 && prefix(new + 1, "builtin"))
8350                         idx_bltin = idx;
8351                 if (*new == ':')
8352                         idx++;
8353                 new++;
8354                 old++;
8355         }
8356         if (builtinloc < 0 && idx_bltin >= 0)
8357                 builtinloc = idx_bltin;             /* zap builtins */
8358         if (builtinloc >= 0 && idx_bltin < 0)
8359                 firstchange = 0;
8360         clearcmdentry(firstchange);
8361         builtinloc = idx_bltin;
8362 }
8363 enum {
8364         TEOF,
8365         TNL,
8366         TREDIR,
8367         TWORD,
8368         TSEMI,
8369         TBACKGND,
8370         TAND,
8371         TOR,
8372         TPIPE,
8373         TLP,
8374         TRP,
8375         TENDCASE,
8376         TENDBQUOTE,
8377         TNOT,
8378         TCASE,
8379         TDO,
8380         TDONE,
8381         TELIF,
8382         TELSE,
8383         TESAC,
8384         TFI,
8385         TFOR,
8386 #if BASH_FUNCTION
8387         TFUNCTION,
8388 #endif
8389         TIF,
8390         TIN,
8391         TTHEN,
8392         TUNTIL,
8393         TWHILE,
8394         TBEGIN,
8395         TEND
8396 };
8397 typedef smallint token_id_t;
8398
8399 /* Nth bit indicates if token marks the end of a list */
8400 enum {
8401         tokendlist = 0
8402         /*  0 */ | (1u << TEOF)
8403         /*  1 */ | (0u << TNL)
8404         /*  2 */ | (0u << TREDIR)
8405         /*  3 */ | (0u << TWORD)
8406         /*  4 */ | (0u << TSEMI)
8407         /*  5 */ | (0u << TBACKGND)
8408         /*  6 */ | (0u << TAND)
8409         /*  7 */ | (0u << TOR)
8410         /*  8 */ | (0u << TPIPE)
8411         /*  9 */ | (0u << TLP)
8412         /* 10 */ | (1u << TRP)
8413         /* 11 */ | (1u << TENDCASE)
8414         /* 12 */ | (1u << TENDBQUOTE)
8415         /* 13 */ | (0u << TNOT)
8416         /* 14 */ | (0u << TCASE)
8417         /* 15 */ | (1u << TDO)
8418         /* 16 */ | (1u << TDONE)
8419         /* 17 */ | (1u << TELIF)
8420         /* 18 */ | (1u << TELSE)
8421         /* 19 */ | (1u << TESAC)
8422         /* 20 */ | (1u << TFI)
8423         /* 21 */ | (0u << TFOR)
8424 #if BASH_FUNCTION
8425         /* 22 */ | (0u << TFUNCTION)
8426 #endif
8427         /* 23 */ | (0u << TIF)
8428         /* 24 */ | (0u << TIN)
8429         /* 25 */ | (1u << TTHEN)
8430         /* 26 */ | (0u << TUNTIL)
8431         /* 27 */ | (0u << TWHILE)
8432         /* 28 */ | (0u << TBEGIN)
8433         /* 29 */ | (1u << TEND)
8434         , /* thus far 29 bits used */
8435 };
8436
8437 static const char *const tokname_array[] = {
8438         "end of file",
8439         "newline",
8440         "redirection",
8441         "word",
8442         ";",
8443         "&",
8444         "&&",
8445         "||",
8446         "|",
8447         "(",
8448         ")",
8449         ";;",
8450         "`",
8451 #define KWDOFFSET 13
8452         /* the following are keywords */
8453         "!",
8454         "case",
8455         "do",
8456         "done",
8457         "elif",
8458         "else",
8459         "esac",
8460         "fi",
8461         "for",
8462 #if BASH_FUNCTION
8463         "function",
8464 #endif
8465         "if",
8466         "in",
8467         "then",
8468         "until",
8469         "while",
8470         "{",
8471         "}",
8472 };
8473
8474 /* Wrapper around strcmp for qsort/bsearch/... */
8475 static int
8476 pstrcmp(const void *a, const void *b)
8477 {
8478         return strcmp((char*)a, *(char**)b);
8479 }
8480
8481 static const char *const *
8482 findkwd(const char *s)
8483 {
8484         return bsearch(s, tokname_array + KWDOFFSET,
8485                         ARRAY_SIZE(tokname_array) - KWDOFFSET,
8486                         sizeof(tokname_array[0]), pstrcmp);
8487 }
8488
8489 /*
8490  * Locate and print what a word is...
8491  */
8492 static int
8493 describe_command(char *command, const char *path, int describe_command_verbose)
8494 {
8495         struct cmdentry entry;
8496 #if ENABLE_ASH_ALIAS
8497         const struct alias *ap;
8498 #endif
8499
8500         path = path ? path : pathval();
8501
8502         if (describe_command_verbose) {
8503                 out1str(command);
8504         }
8505
8506         /* First look at the keywords */
8507         if (findkwd(command)) {
8508                 out1str(describe_command_verbose ? " is a shell keyword" : command);
8509                 goto out;
8510         }
8511
8512 #if ENABLE_ASH_ALIAS
8513         /* Then look at the aliases */
8514         ap = lookupalias(command, 0);
8515         if (ap != NULL) {
8516                 if (!describe_command_verbose) {
8517                         out1str("alias ");
8518                         printalias(ap);
8519                         return 0;
8520                 }
8521                 out1fmt(" is an alias for %s", ap->val);
8522                 goto out;
8523         }
8524 #endif
8525         /* Brute force */
8526         find_command(command, &entry, DO_ABS, path);
8527
8528         switch (entry.cmdtype) {
8529         case CMDNORMAL: {
8530                 int j = entry.u.index;
8531                 char *p;
8532                 if (j < 0) {
8533                         p = command;
8534                 } else {
8535                         do {
8536                                 p = path_advance(&path, command);
8537                                 stunalloc(p);
8538                         } while (--j >= 0);
8539                 }
8540                 if (describe_command_verbose) {
8541                         out1fmt(" is %s", p);
8542                 } else {
8543                         out1str(p);
8544                 }
8545                 break;
8546         }
8547
8548         case CMDFUNCTION:
8549                 if (describe_command_verbose) {
8550                         /*out1str(" is a shell function");*/
8551                         out1str(" is a function"); /* bash says this */
8552                 } else {
8553                         out1str(command);
8554                 }
8555                 break;
8556
8557         case CMDBUILTIN:
8558                 if (describe_command_verbose) {
8559                         out1fmt(" is a %sshell builtin",
8560                                 IS_BUILTIN_SPECIAL(entry.u.cmd) ?
8561                                         "special " : nullstr
8562                         );
8563                 } else {
8564                         out1str(command);
8565                 }
8566                 break;
8567
8568         default:
8569                 if (describe_command_verbose) {
8570                         out1str(": not found\n");
8571                 }
8572                 return 127;
8573         }
8574  out:
8575         out1str("\n");
8576         return 0;
8577 }
8578
8579 static int FAST_FUNC
8580 typecmd(int argc UNUSED_PARAM, char **argv)
8581 {
8582         int i = 1;
8583         int err = 0;
8584         int verbose = 1;
8585
8586         /* type -p ... ? (we don't bother checking for 'p') */
8587         if (argv[1] && argv[1][0] == '-') {
8588                 i++;
8589                 verbose = 0;
8590         }
8591         while (argv[i]) {
8592                 err |= describe_command(argv[i++], NULL, verbose);
8593         }
8594         return err;
8595 }
8596
8597 #if ENABLE_ASH_CMDCMD
8598 /* Is it "command [-p] PROG ARGS" bltin, no other opts? Return ptr to "PROG" if yes */
8599 static char **
8600 parse_command_args(char **argv, const char **path)
8601 {
8602         char *cp, c;
8603
8604         for (;;) {
8605                 cp = *++argv;
8606                 if (!cp)
8607                         return NULL;
8608                 if (*cp++ != '-')
8609                         break;
8610                 c = *cp++;
8611                 if (!c)
8612                         break;
8613                 if (c == '-' && !*cp) {
8614                         if (!*++argv)
8615                                 return NULL;
8616                         break;
8617                 }
8618                 do {
8619                         switch (c) {
8620                         case 'p':
8621                                 *path = bb_default_path;
8622                                 break;
8623                         default:
8624                                 /* run 'typecmd' for other options */
8625                                 return NULL;
8626                         }
8627                         c = *cp++;
8628                 } while (c);
8629         }
8630         return argv;
8631 }
8632
8633 static int FAST_FUNC
8634 commandcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
8635 {
8636         char *cmd;
8637         int c;
8638         enum {
8639                 VERIFY_BRIEF = 1,
8640                 VERIFY_VERBOSE = 2,
8641         } verify = 0;
8642         const char *path = NULL;
8643
8644         /* "command [-p] PROG ARGS" (that is, without -V or -v)
8645          * never reaches this function.
8646          */
8647
8648         while ((c = nextopt("pvV")) != '\0')
8649                 if (c == 'V')
8650                         verify |= VERIFY_VERBOSE;
8651                 else if (c == 'v')
8652                         /*verify |= VERIFY_BRIEF*/;
8653 #if DEBUG
8654                 else if (c != 'p')
8655                         abort();
8656 #endif
8657                 else
8658                         path = bb_default_path;
8659
8660         /* Mimic bash: just "command -v" doesn't complain, it's a nop */
8661         cmd = *argptr;
8662         if (/*verify && */ cmd)
8663                 return describe_command(cmd, path, verify /* - VERIFY_BRIEF*/);
8664
8665         return 0;
8666 }
8667 #endif
8668
8669
8670 /*static int funcblocksize;     // size of structures in function */
8671 /*static int funcstringsize;    // size of strings in node */
8672 static void *funcblock;         /* block to allocate function from */
8673 static char *funcstring_end;    /* end of block to allocate strings from */
8674
8675 static const uint8_t nodesize[N_NUMBER] ALIGN1 = {
8676         [NCMD     ] = SHELL_ALIGN(sizeof(struct ncmd)),
8677         [NPIPE    ] = SHELL_ALIGN(sizeof(struct npipe)),
8678         [NREDIR   ] = SHELL_ALIGN(sizeof(struct nredir)),
8679         [NBACKGND ] = SHELL_ALIGN(sizeof(struct nredir)),
8680         [NSUBSHELL] = SHELL_ALIGN(sizeof(struct nredir)),
8681         [NAND     ] = SHELL_ALIGN(sizeof(struct nbinary)),
8682         [NOR      ] = SHELL_ALIGN(sizeof(struct nbinary)),
8683         [NSEMI    ] = SHELL_ALIGN(sizeof(struct nbinary)),
8684         [NIF      ] = SHELL_ALIGN(sizeof(struct nif)),
8685         [NWHILE   ] = SHELL_ALIGN(sizeof(struct nbinary)),
8686         [NUNTIL   ] = SHELL_ALIGN(sizeof(struct nbinary)),
8687         [NFOR     ] = SHELL_ALIGN(sizeof(struct nfor)),
8688         [NCASE    ] = SHELL_ALIGN(sizeof(struct ncase)),
8689         [NCLIST   ] = SHELL_ALIGN(sizeof(struct nclist)),
8690         [NDEFUN   ] = SHELL_ALIGN(sizeof(struct narg)),
8691         [NARG     ] = SHELL_ALIGN(sizeof(struct narg)),
8692         [NTO      ] = SHELL_ALIGN(sizeof(struct nfile)),
8693 #if BASH_REDIR_OUTPUT
8694         [NTO2     ] = SHELL_ALIGN(sizeof(struct nfile)),
8695 #endif
8696         [NCLOBBER ] = SHELL_ALIGN(sizeof(struct nfile)),
8697         [NFROM    ] = SHELL_ALIGN(sizeof(struct nfile)),
8698         [NFROMTO  ] = SHELL_ALIGN(sizeof(struct nfile)),
8699         [NAPPEND  ] = SHELL_ALIGN(sizeof(struct nfile)),
8700         [NTOFD    ] = SHELL_ALIGN(sizeof(struct ndup)),
8701         [NFROMFD  ] = SHELL_ALIGN(sizeof(struct ndup)),
8702         [NHERE    ] = SHELL_ALIGN(sizeof(struct nhere)),
8703         [NXHERE   ] = SHELL_ALIGN(sizeof(struct nhere)),
8704         [NNOT     ] = SHELL_ALIGN(sizeof(struct nnot)),
8705 };
8706
8707 static int calcsize(int funcblocksize, union node *n);
8708
8709 static int
8710 sizenodelist(int funcblocksize, struct nodelist *lp)
8711 {
8712         while (lp) {
8713                 funcblocksize += SHELL_ALIGN(sizeof(struct nodelist));
8714                 funcblocksize = calcsize(funcblocksize, lp->n);
8715                 lp = lp->next;
8716         }
8717         return funcblocksize;
8718 }
8719
8720 static int
8721 calcsize(int funcblocksize, union node *n)
8722 {
8723         if (n == NULL)
8724                 return funcblocksize;
8725         funcblocksize += nodesize[n->type];
8726         switch (n->type) {
8727         case NCMD:
8728                 funcblocksize = calcsize(funcblocksize, n->ncmd.redirect);
8729                 funcblocksize = calcsize(funcblocksize, n->ncmd.args);
8730                 funcblocksize = calcsize(funcblocksize, n->ncmd.assign);
8731                 break;
8732         case NPIPE:
8733                 funcblocksize = sizenodelist(funcblocksize, n->npipe.cmdlist);
8734                 break;
8735         case NREDIR:
8736         case NBACKGND:
8737         case NSUBSHELL:
8738                 funcblocksize = calcsize(funcblocksize, n->nredir.redirect);
8739                 funcblocksize = calcsize(funcblocksize, n->nredir.n);
8740                 break;
8741         case NAND:
8742         case NOR:
8743         case NSEMI:
8744         case NWHILE:
8745         case NUNTIL:
8746                 funcblocksize = calcsize(funcblocksize, n->nbinary.ch2);
8747                 funcblocksize = calcsize(funcblocksize, n->nbinary.ch1);
8748                 break;
8749         case NIF:
8750                 funcblocksize = calcsize(funcblocksize, n->nif.elsepart);
8751                 funcblocksize = calcsize(funcblocksize, n->nif.ifpart);
8752                 funcblocksize = calcsize(funcblocksize, n->nif.test);
8753                 break;
8754         case NFOR:
8755                 funcblocksize += SHELL_ALIGN(strlen(n->nfor.var) + 1); /* was funcstringsize += ... */
8756                 funcblocksize = calcsize(funcblocksize, n->nfor.body);
8757                 funcblocksize = calcsize(funcblocksize, n->nfor.args);
8758                 break;
8759         case NCASE:
8760                 funcblocksize = calcsize(funcblocksize, n->ncase.cases);
8761                 funcblocksize = calcsize(funcblocksize, n->ncase.expr);
8762                 break;
8763         case NCLIST:
8764                 funcblocksize = calcsize(funcblocksize, n->nclist.body);
8765                 funcblocksize = calcsize(funcblocksize, n->nclist.pattern);
8766                 funcblocksize = calcsize(funcblocksize, n->nclist.next);
8767                 break;
8768         case NDEFUN:
8769                 funcblocksize = calcsize(funcblocksize, n->ndefun.body);
8770                 funcblocksize += SHELL_ALIGN(strlen(n->ndefun.text) + 1);
8771                 break;
8772         case NARG:
8773                 funcblocksize = sizenodelist(funcblocksize, n->narg.backquote);
8774                 funcblocksize += SHELL_ALIGN(strlen(n->narg.text) + 1); /* was funcstringsize += ... */
8775                 funcblocksize = calcsize(funcblocksize, n->narg.next);
8776                 break;
8777         case NTO:
8778 #if BASH_REDIR_OUTPUT
8779         case NTO2:
8780 #endif
8781         case NCLOBBER:
8782         case NFROM:
8783         case NFROMTO:
8784         case NAPPEND:
8785                 funcblocksize = calcsize(funcblocksize, n->nfile.fname);
8786                 funcblocksize = calcsize(funcblocksize, n->nfile.next);
8787                 break;
8788         case NTOFD:
8789         case NFROMFD:
8790                 funcblocksize = calcsize(funcblocksize, n->ndup.vname);
8791                 funcblocksize = calcsize(funcblocksize, n->ndup.next);
8792         break;
8793         case NHERE:
8794         case NXHERE:
8795                 funcblocksize = calcsize(funcblocksize, n->nhere.doc);
8796                 funcblocksize = calcsize(funcblocksize, n->nhere.next);
8797                 break;
8798         case NNOT:
8799                 funcblocksize = calcsize(funcblocksize, n->nnot.com);
8800                 break;
8801         };
8802         return funcblocksize;
8803 }
8804
8805 static char *
8806 nodeckstrdup(char *s)
8807 {
8808         funcstring_end -= SHELL_ALIGN(strlen(s) + 1);
8809         return strcpy(funcstring_end, s);
8810 }
8811
8812 static union node *copynode(union node *);
8813
8814 static struct nodelist *
8815 copynodelist(struct nodelist *lp)
8816 {
8817         struct nodelist *start;
8818         struct nodelist **lpp;
8819
8820         lpp = &start;
8821         while (lp) {
8822                 *lpp = funcblock;
8823                 funcblock = (char *) funcblock + SHELL_ALIGN(sizeof(struct nodelist));
8824                 (*lpp)->n = copynode(lp->n);
8825                 lp = lp->next;
8826                 lpp = &(*lpp)->next;
8827         }
8828         *lpp = NULL;
8829         return start;
8830 }
8831
8832 static union node *
8833 copynode(union node *n)
8834 {
8835         union node *new;
8836
8837         if (n == NULL)
8838                 return NULL;
8839         new = funcblock;
8840         funcblock = (char *) funcblock + nodesize[n->type];
8841
8842         switch (n->type) {
8843         case NCMD:
8844                 new->ncmd.redirect = copynode(n->ncmd.redirect);
8845                 new->ncmd.args = copynode(n->ncmd.args);
8846                 new->ncmd.assign = copynode(n->ncmd.assign);
8847                 new->ncmd.linno = n->ncmd.linno;
8848                 break;
8849         case NPIPE:
8850                 new->npipe.cmdlist = copynodelist(n->npipe.cmdlist);
8851                 new->npipe.pipe_backgnd = n->npipe.pipe_backgnd;
8852                 break;
8853         case NREDIR:
8854         case NBACKGND:
8855         case NSUBSHELL:
8856                 new->nredir.redirect = copynode(n->nredir.redirect);
8857                 new->nredir.n = copynode(n->nredir.n);
8858                 new->nredir.linno = n->nredir.linno;
8859                 break;
8860         case NAND:
8861         case NOR:
8862         case NSEMI:
8863         case NWHILE:
8864         case NUNTIL:
8865                 new->nbinary.ch2 = copynode(n->nbinary.ch2);
8866                 new->nbinary.ch1 = copynode(n->nbinary.ch1);
8867                 break;
8868         case NIF:
8869                 new->nif.elsepart = copynode(n->nif.elsepart);
8870                 new->nif.ifpart = copynode(n->nif.ifpart);
8871                 new->nif.test = copynode(n->nif.test);
8872                 break;
8873         case NFOR:
8874                 new->nfor.var = nodeckstrdup(n->nfor.var);
8875                 new->nfor.body = copynode(n->nfor.body);
8876                 new->nfor.args = copynode(n->nfor.args);
8877                 new->nfor.linno = n->nfor.linno;
8878                 break;
8879         case NCASE:
8880                 new->ncase.cases = copynode(n->ncase.cases);
8881                 new->ncase.expr = copynode(n->ncase.expr);
8882                 new->ncase.linno = n->ncase.linno;
8883                 break;
8884         case NCLIST:
8885                 new->nclist.body = copynode(n->nclist.body);
8886                 new->nclist.pattern = copynode(n->nclist.pattern);
8887                 new->nclist.next = copynode(n->nclist.next);
8888                 break;
8889         case NDEFUN:
8890                 new->ndefun.body = copynode(n->ndefun.body);
8891                 new->ndefun.text = nodeckstrdup(n->ndefun.text);
8892                 new->ndefun.linno = n->ndefun.linno;
8893                 break;
8894         case NARG:
8895                 new->narg.backquote = copynodelist(n->narg.backquote);
8896                 new->narg.text = nodeckstrdup(n->narg.text);
8897                 new->narg.next = copynode(n->narg.next);
8898                 break;
8899         case NTO:
8900 #if BASH_REDIR_OUTPUT
8901         case NTO2:
8902 #endif
8903         case NCLOBBER:
8904         case NFROM:
8905         case NFROMTO:
8906         case NAPPEND:
8907                 new->nfile.fname = copynode(n->nfile.fname);
8908                 new->nfile.fd = n->nfile.fd;
8909                 new->nfile.next = copynode(n->nfile.next);
8910                 break;
8911         case NTOFD:
8912         case NFROMFD:
8913                 new->ndup.vname = copynode(n->ndup.vname);
8914                 new->ndup.dupfd = n->ndup.dupfd;
8915                 new->ndup.fd = n->ndup.fd;
8916                 new->ndup.next = copynode(n->ndup.next);
8917                 break;
8918         case NHERE:
8919         case NXHERE:
8920                 new->nhere.doc = copynode(n->nhere.doc);
8921                 new->nhere.fd = n->nhere.fd;
8922                 new->nhere.next = copynode(n->nhere.next);
8923                 break;
8924         case NNOT:
8925                 new->nnot.com = copynode(n->nnot.com);
8926                 break;
8927         };
8928         new->type = n->type;
8929         return new;
8930 }
8931
8932 /*
8933  * Make a copy of a parse tree.
8934  */
8935 static struct funcnode *
8936 copyfunc(union node *n)
8937 {
8938         struct funcnode *f;
8939         size_t blocksize;
8940
8941         /*funcstringsize = 0;*/
8942         blocksize = offsetof(struct funcnode, n) + calcsize(0, n);
8943         f = ckzalloc(blocksize /* + funcstringsize */);
8944         funcblock = (char *) f + offsetof(struct funcnode, n);
8945         funcstring_end = (char *) f + blocksize;
8946         copynode(n);
8947         /* f->count = 0; - ckzalloc did it */
8948         return f;
8949 }
8950
8951 /*
8952  * Define a shell function.
8953  */
8954 static void
8955 defun(union node *func)
8956 {
8957         struct cmdentry entry;
8958
8959         INT_OFF;
8960         entry.cmdtype = CMDFUNCTION;
8961         entry.u.func = copyfunc(func);
8962         addcmdentry(func->ndefun.text, &entry);
8963         INT_ON;
8964 }
8965
8966 /* Reasons for skipping commands (see comment on breakcmd routine) */
8967 #define SKIPBREAK      (1 << 0)
8968 #define SKIPCONT       (1 << 1)
8969 #define SKIPFUNC       (1 << 2)
8970 static smallint evalskip;       /* set to SKIPxxx if we are skipping commands */
8971 static int skipcount;           /* number of levels to skip */
8972 static int loopnest;            /* current loop nesting level */
8973 static int funcline;            /* starting line number of current function, or 0 if not in a function */
8974
8975 /* Forward decl way out to parsing code - dotrap needs it */
8976 static int evalstring(char *s, int flags);
8977
8978 /* Called to execute a trap.
8979  * Single callsite - at the end of evaltree().
8980  * If we return non-zero, evaltree raises EXEXIT exception.
8981  *
8982  * Perhaps we should avoid entering new trap handlers
8983  * while we are executing a trap handler. [is it a TODO?]
8984  */
8985 static void
8986 dotrap(void)
8987 {
8988         uint8_t *g;
8989         int sig;
8990         uint8_t last_status;
8991
8992         if (!pending_sig)
8993                 return;
8994
8995         last_status = exitstatus;
8996         pending_sig = 0;
8997         barrier();
8998
8999         TRACE(("dotrap entered\n"));
9000         for (sig = 1, g = gotsig; sig < NSIG; sig++, g++) {
9001                 char *p;
9002
9003                 if (!*g)
9004                         continue;
9005
9006                 if (evalskip) {
9007                         pending_sig = sig;
9008                         break;
9009                 }
9010
9011                 p = trap[sig];
9012                 /* non-trapped SIGINT is handled separately by raise_interrupt,
9013                  * don't upset it by resetting gotsig[SIGINT-1] */
9014                 if (sig == SIGINT && !p)
9015                         continue;
9016
9017                 TRACE(("sig %d is active, will run handler '%s'\n", sig, p));
9018                 *g = 0;
9019                 if (!p)
9020                         continue;
9021                 evalstring(p, 0);
9022         }
9023         exitstatus = last_status;
9024         TRACE(("dotrap returns\n"));
9025 }
9026
9027 /* forward declarations - evaluation is fairly recursive business... */
9028 static int evalloop(union node *, int);
9029 static int evalfor(union node *, int);
9030 static int evalcase(union node *, int);
9031 static int evalsubshell(union node *, int);
9032 static void expredir(union node *);
9033 static int evalpipe(union node *, int);
9034 static int evalcommand(union node *, int);
9035 static int evalbltin(const struct builtincmd *, int, char **, int);
9036 static void prehash(union node *);
9037
9038 /*
9039  * Evaluate a parse tree.  The value is left in the global variable
9040  * exitstatus.
9041  */
9042 static int
9043 evaltree(union node *n, int flags)
9044 {
9045         int checkexit = 0;
9046         int (*evalfn)(union node *, int);
9047         int status = 0;
9048
9049         if (n == NULL) {
9050                 TRACE(("evaltree(NULL) called\n"));
9051                 goto out;
9052         }
9053         TRACE(("evaltree(%p: %d, %d) called\n", n, n->type, flags));
9054
9055         dotrap();
9056
9057         switch (n->type) {
9058         default:
9059 #if DEBUG
9060                 out1fmt("Node type = %d\n", n->type);
9061                 fflush_all();
9062                 break;
9063 #endif
9064         case NNOT:
9065                 status = !evaltree(n->nnot.com, EV_TESTED);
9066                 goto setstatus;
9067         case NREDIR:
9068                 errlinno = lineno = n->nredir.linno;
9069                 if (funcline)
9070                         lineno -= funcline - 1;
9071                 expredir(n->nredir.redirect);
9072                 pushredir(n->nredir.redirect);
9073                 status = redirectsafe(n->nredir.redirect, REDIR_PUSH);
9074                 if (!status) {
9075                         status = evaltree(n->nredir.n, flags & EV_TESTED);
9076                 }
9077                 if (n->nredir.redirect)
9078                         popredir(/*drop:*/ 0);
9079                 goto setstatus;
9080         case NCMD:
9081                 evalfn = evalcommand;
9082  checkexit:
9083                 if (eflag && !(flags & EV_TESTED))
9084                         checkexit = ~0;
9085                 goto calleval;
9086         case NFOR:
9087                 evalfn = evalfor;
9088                 goto calleval;
9089         case NWHILE:
9090         case NUNTIL:
9091                 evalfn = evalloop;
9092                 goto calleval;
9093         case NSUBSHELL:
9094         case NBACKGND:
9095                 evalfn = evalsubshell;
9096                 goto checkexit;
9097         case NPIPE:
9098                 evalfn = evalpipe;
9099                 goto checkexit;
9100         case NCASE:
9101                 evalfn = evalcase;
9102                 goto calleval;
9103         case NAND:
9104         case NOR:
9105         case NSEMI: {
9106
9107 #if NAND + 1 != NOR
9108 #error NAND + 1 != NOR
9109 #endif
9110 #if NOR + 1 != NSEMI
9111 #error NOR + 1 != NSEMI
9112 #endif
9113                 unsigned is_or = n->type - NAND;
9114                 status = evaltree(
9115                         n->nbinary.ch1,
9116                         (flags | ((is_or >> 1) - 1)) & EV_TESTED
9117                 );
9118                 if ((!status) == is_or || evalskip)
9119                         break;
9120                 n = n->nbinary.ch2;
9121  evaln:
9122                 evalfn = evaltree;
9123  calleval:
9124                 status = evalfn(n, flags);
9125                 goto setstatus;
9126         }
9127         case NIF:
9128                 status = evaltree(n->nif.test, EV_TESTED);
9129                 if (evalskip)
9130                         break;
9131                 if (!status) {
9132                         n = n->nif.ifpart;
9133                         goto evaln;
9134                 }
9135                 if (n->nif.elsepart) {
9136                         n = n->nif.elsepart;
9137                         goto evaln;
9138                 }
9139                 status = 0;
9140                 goto setstatus;
9141         case NDEFUN:
9142                 defun(n);
9143                 /* Not necessary. To test it:
9144                  * "false; f() { qwerty; }; echo $?" should print 0.
9145                  */
9146                 /* status = 0; */
9147  setstatus:
9148                 exitstatus = status;
9149                 break;
9150         }
9151  out:
9152         /* Order of checks below is important:
9153          * signal handlers trigger before exit caused by "set -e".
9154          */
9155         dotrap();
9156
9157         if (checkexit & status)
9158                 raise_exception(EXEXIT);
9159         if (flags & EV_EXIT)
9160                 raise_exception(EXEXIT);
9161
9162         TRACE(("leaving evaltree (no interrupts)\n"));
9163         return exitstatus;
9164 }
9165
9166 static int
9167 skiploop(void)
9168 {
9169         int skip = evalskip;
9170
9171         switch (skip) {
9172         case 0:
9173                 break;
9174         case SKIPBREAK:
9175         case SKIPCONT:
9176                 if (--skipcount <= 0) {
9177                         evalskip = 0;
9178                         break;
9179                 }
9180                 skip = SKIPBREAK;
9181                 break;
9182         }
9183         return skip;
9184 }
9185
9186 static int
9187 evalloop(union node *n, int flags)
9188 {
9189         int skip;
9190         int status;
9191
9192         loopnest++;
9193         status = 0;
9194         flags &= EV_TESTED;
9195         do {
9196                 int i;
9197
9198                 i = evaltree(n->nbinary.ch1, EV_TESTED);
9199                 skip = skiploop();
9200                 if (skip == SKIPFUNC)
9201                         status = i;
9202                 if (skip)
9203                         continue;
9204                 if (n->type != NWHILE)
9205                         i = !i;
9206                 if (i != 0)
9207                         break;
9208                 status = evaltree(n->nbinary.ch2, flags);
9209                 skip = skiploop();
9210         } while (!(skip & ~SKIPCONT));
9211         loopnest--;
9212
9213         return status;
9214 }
9215
9216 static int
9217 evalfor(union node *n, int flags)
9218 {
9219         struct arglist arglist;
9220         union node *argp;
9221         struct strlist *sp;
9222         struct stackmark smark;
9223         int status = 0;
9224
9225         errlinno = lineno = n->ncase.linno;
9226         if (funcline)
9227                 lineno -= funcline - 1;
9228
9229         setstackmark(&smark);
9230         arglist.list = NULL;
9231         arglist.lastp = &arglist.list;
9232         for (argp = n->nfor.args; argp; argp = argp->narg.next) {
9233                 expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
9234         }
9235         *arglist.lastp = NULL;
9236
9237         loopnest++;
9238         flags &= EV_TESTED;
9239         for (sp = arglist.list; sp; sp = sp->next) {
9240                 setvar0(n->nfor.var, sp->text);
9241                 status = evaltree(n->nfor.body, flags);
9242                 if (skiploop() & ~SKIPCONT)
9243                         break;
9244         }
9245         loopnest--;
9246         popstackmark(&smark);
9247
9248         return status;
9249 }
9250
9251 static int
9252 evalcase(union node *n, int flags)
9253 {
9254         union node *cp;
9255         union node *patp;
9256         struct arglist arglist;
9257         struct stackmark smark;
9258         int status = 0;
9259
9260         errlinno = lineno = n->ncase.linno;
9261         if (funcline)
9262                 lineno -= funcline - 1;
9263
9264         setstackmark(&smark);
9265         arglist.list = NULL;
9266         arglist.lastp = &arglist.list;
9267         expandarg(n->ncase.expr, &arglist, EXP_TILDE);
9268         for (cp = n->ncase.cases; cp && evalskip == 0; cp = cp->nclist.next) {
9269                 for (patp = cp->nclist.pattern; patp; patp = patp->narg.next) {
9270                         if (casematch(patp, arglist.list->text)) {
9271                                 /* Ensure body is non-empty as otherwise
9272                                  * EV_EXIT may prevent us from setting the
9273                                  * exit status.
9274                                  */
9275                                 if (evalskip == 0 && cp->nclist.body) {
9276                                         status = evaltree(cp->nclist.body, flags);
9277                                 }
9278                                 goto out;
9279                         }
9280                 }
9281         }
9282  out:
9283         popstackmark(&smark);
9284
9285         return status;
9286 }
9287
9288 /*
9289  * Kick off a subshell to evaluate a tree.
9290  */
9291 static int
9292 evalsubshell(union node *n, int flags)
9293 {
9294         struct job *jp;
9295         int backgnd = (n->type == NBACKGND); /* FORK_BG(1) if yes, else FORK_FG(0) */
9296         int status;
9297
9298         errlinno = lineno = n->nredir.linno;
9299         if (funcline)
9300                 lineno -= funcline - 1;
9301
9302         expredir(n->nredir.redirect);
9303         if (!backgnd && (flags & EV_EXIT) && !may_have_traps)
9304                 goto nofork;
9305         INT_OFF;
9306         if (backgnd == FORK_FG)
9307                 get_tty_state();
9308         jp = makejob(/*n,*/ 1);
9309         if (forkshell(jp, n, backgnd) == 0) {
9310                 /* child */
9311                 INT_ON;
9312                 flags |= EV_EXIT;
9313                 if (backgnd)
9314                         flags &= ~EV_TESTED;
9315  nofork:
9316                 redirect(n->nredir.redirect, 0);
9317                 evaltreenr(n->nredir.n, flags);
9318                 /* never returns */
9319         }
9320         /* parent */
9321         status = 0;
9322         if (backgnd == FORK_FG)
9323                 status = waitforjob(jp);
9324         INT_ON;
9325         return status;
9326 }
9327
9328 /*
9329  * Compute the names of the files in a redirection list.
9330  */
9331 static void fixredir(union node *, const char *, int);
9332 static void
9333 expredir(union node *n)
9334 {
9335         union node *redir;
9336
9337         for (redir = n; redir; redir = redir->nfile.next) {
9338                 struct arglist fn;
9339
9340                 fn.list = NULL;
9341                 fn.lastp = &fn.list;
9342                 switch (redir->type) {
9343                 case NFROMTO:
9344                 case NFROM:
9345                 case NTO:
9346 #if BASH_REDIR_OUTPUT
9347                 case NTO2:
9348 #endif
9349                 case NCLOBBER:
9350                 case NAPPEND:
9351                         expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR);
9352                         TRACE(("expredir expanded to '%s'\n", fn.list->text));
9353 #if BASH_REDIR_OUTPUT
9354  store_expfname:
9355 #endif
9356 #if 0
9357 // By the design of stack allocator, the loop of this kind:
9358 //      while true; do while true; do break; done </dev/null; done
9359 // will look like a memory leak: ash plans to free expfname's
9360 // of "/dev/null" as soon as it finishes running the loop
9361 // (in this case, never).
9362 // This "fix" is wrong:
9363                         if (redir->nfile.expfname)
9364                                 stunalloc(redir->nfile.expfname);
9365 // It results in corrupted state of stacked allocations.
9366 #endif
9367                         redir->nfile.expfname = fn.list->text;
9368                         break;
9369                 case NFROMFD:
9370                 case NTOFD: /* >& */
9371                         if (redir->ndup.vname) {
9372                                 expandarg(redir->ndup.vname, &fn, EXP_FULL | EXP_TILDE);
9373                                 if (fn.list == NULL)
9374                                         ash_msg_and_raise_error("redir error");
9375 #if BASH_REDIR_OUTPUT
9376 //FIXME: we used expandarg with different args!
9377                                 if (!isdigit_str9(fn.list->text)) {
9378                                         /* >&file, not >&fd */
9379                                         if (redir->nfile.fd != 1) /* 123>&file - BAD */
9380                                                 ash_msg_and_raise_error("redir error");
9381                                         redir->type = NTO2;
9382                                         goto store_expfname;
9383                                 }
9384 #endif
9385                                 fixredir(redir, fn.list->text, 1);
9386                         }
9387                         break;
9388                 }
9389         }
9390 }
9391
9392 /*
9393  * Evaluate a pipeline.  All the processes in the pipeline are children
9394  * of the process creating the pipeline.  (This differs from some versions
9395  * of the shell, which make the last process in a pipeline the parent
9396  * of all the rest.)
9397  */
9398 static int
9399 evalpipe(union node *n, int flags)
9400 {
9401         struct job *jp;
9402         struct nodelist *lp;
9403         int pipelen;
9404         int prevfd;
9405         int pip[2];
9406         int status = 0;
9407
9408         TRACE(("evalpipe(0x%lx) called\n", (long)n));
9409         pipelen = 0;
9410         for (lp = n->npipe.cmdlist; lp; lp = lp->next)
9411                 pipelen++;
9412         flags |= EV_EXIT;
9413         INT_OFF;
9414         if (n->npipe.pipe_backgnd == 0)
9415                 get_tty_state();
9416         jp = makejob(/*n,*/ pipelen);
9417         prevfd = -1;
9418         for (lp = n->npipe.cmdlist; lp; lp = lp->next) {
9419                 prehash(lp->n);
9420                 pip[1] = -1;
9421                 if (lp->next) {
9422                         if (pipe(pip) < 0) {
9423                                 close(prevfd);
9424                                 ash_msg_and_raise_perror("can't create pipe");
9425                         }
9426                 }
9427                 if (forkshell(jp, lp->n, n->npipe.pipe_backgnd) == 0) {
9428                         /* child */
9429                         INT_ON;
9430                         if (pip[1] >= 0) {
9431                                 close(pip[0]);
9432                         }
9433                         if (prevfd > 0) {
9434                                 dup2(prevfd, 0);
9435                                 close(prevfd);
9436                         }
9437                         if (pip[1] > 1) {
9438                                 dup2(pip[1], 1);
9439                                 close(pip[1]);
9440                         }
9441                         evaltreenr(lp->n, flags);
9442                         /* never returns */
9443                 }
9444                 /* parent */
9445                 if (prevfd >= 0)
9446                         close(prevfd);
9447                 prevfd = pip[0];
9448                 /* Don't want to trigger debugging */
9449                 if (pip[1] != -1)
9450                         close(pip[1]);
9451         }
9452         if (n->npipe.pipe_backgnd == 0) {
9453                 status = waitforjob(jp);
9454                 TRACE(("evalpipe:  job done exit status %d\n", status));
9455         }
9456         INT_ON;
9457
9458         return status;
9459 }
9460
9461 /*
9462  * Controls whether the shell is interactive or not.
9463  */
9464 static void
9465 setinteractive(int on)
9466 {
9467         static smallint is_interactive;
9468
9469         if (++on == is_interactive)
9470                 return;
9471         is_interactive = on;
9472         setsignal(SIGINT);
9473         setsignal(SIGQUIT);
9474         setsignal(SIGTERM);
9475 #if !ENABLE_FEATURE_SH_EXTRA_QUIET
9476         if (is_interactive > 1) {
9477                 /* Looks like they want an interactive shell */
9478                 static smallint did_banner;
9479
9480                 if (!did_banner) {
9481                         /* note: ash and hush share this string */
9482                         out1fmt("\n\n%s %s\n"
9483                                 IF_ASH_HELP("Enter 'help' for a list of built-in commands.\n")
9484                                 "\n",
9485                                 bb_banner,
9486                                 "built-in shell (ash)"
9487                         );
9488                         did_banner = 1;
9489                 }
9490         }
9491 #endif
9492 }
9493
9494 static void
9495 optschanged(void)
9496 {
9497 #if DEBUG
9498         opentrace();
9499 #endif
9500         setinteractive(iflag);
9501         setjobctl(mflag);
9502 #if ENABLE_FEATURE_EDITING_VI
9503         if (viflag)
9504                 line_input_state->flags |= VI_MODE;
9505         else
9506                 line_input_state->flags &= ~VI_MODE;
9507 #else
9508         viflag = 0; /* forcibly keep the option off */
9509 #endif
9510 }
9511
9512 struct localvar_list {
9513         struct localvar_list *next;
9514         struct localvar *lv;
9515 };
9516
9517 static struct localvar_list *localvar_stack;
9518
9519 /*
9520  * Called after a function returns.
9521  * Interrupts must be off.
9522  */
9523 static void
9524 poplocalvars(int keep)
9525 {
9526         struct localvar_list *ll;
9527         struct localvar *lvp, *next;
9528         struct var *vp;
9529
9530         INT_OFF;
9531         ll = localvar_stack;
9532         localvar_stack = ll->next;
9533
9534         next = ll->lv;
9535         free(ll);
9536
9537         while ((lvp = next) != NULL) {
9538                 next = lvp->next;
9539                 vp = lvp->vp;
9540                 TRACE(("poplocalvar %s\n", vp ? vp->var_text : "-"));
9541                 if (keep) {
9542                         int bits = VSTRFIXED;
9543
9544                         if (lvp->flags != VUNSET) {
9545                                 if (vp->var_text == lvp->text)
9546                                         bits |= VTEXTFIXED;
9547                                 else if (!(lvp->flags & (VTEXTFIXED|VSTACK)))
9548                                         free((char*)lvp->text);
9549                         }
9550
9551                         vp->flags &= ~bits;
9552                         vp->flags |= (lvp->flags & bits);
9553
9554                         if ((vp->flags &
9555                              (VEXPORT|VREADONLY|VSTRFIXED|VUNSET)) == VUNSET)
9556                                 unsetvar(vp->var_text);
9557                 } else if (vp == NULL) {        /* $- saved */
9558                         memcpy(optlist, lvp->text, sizeof(optlist));
9559                         free((char*)lvp->text);
9560                         optschanged();
9561                 } else if (lvp->flags == VUNSET) {
9562                         vp->flags &= ~(VSTRFIXED|VREADONLY);
9563                         unsetvar(vp->var_text);
9564                 } else {
9565                         if (vp->var_func)
9566                                 vp->var_func(var_end(lvp->text));
9567                         if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0)
9568                                 free((char*)vp->var_text);
9569                         vp->flags = lvp->flags;
9570                         vp->var_text = lvp->text;
9571                 }
9572                 free(lvp);
9573         }
9574         INT_ON;
9575 }
9576
9577 /*
9578  * Create a new localvar environment.
9579  */
9580 static struct localvar_list *
9581 pushlocalvars(void)
9582 {
9583         struct localvar_list *ll;
9584
9585         INT_OFF;
9586         ll = ckzalloc(sizeof(*ll));
9587         /*ll->lv = NULL; - zalloc did it */
9588         ll->next = localvar_stack;
9589         localvar_stack = ll;
9590         INT_ON;
9591
9592         return ll->next;
9593 }
9594
9595 static void
9596 unwindlocalvars(struct localvar_list *stop)
9597 {
9598         while (localvar_stack != stop)
9599                 poplocalvars(0);
9600 }
9601
9602 static int
9603 evalfun(struct funcnode *func, int argc, char **argv, int flags)
9604 {
9605         volatile struct shparam saveparam;
9606         struct jmploc *volatile savehandler;
9607         struct jmploc jmploc;
9608         int e;
9609         int savefuncline;
9610
9611         saveparam = shellparam;
9612         savefuncline = funcline;
9613         savehandler = exception_handler;
9614         e = setjmp(jmploc.loc);
9615         if (e) {
9616                 goto funcdone;
9617         }
9618         INT_OFF;
9619         exception_handler = &jmploc;
9620         shellparam.malloced = 0;
9621         func->count++;
9622         funcline = func->n.ndefun.linno;
9623         INT_ON;
9624         shellparam.nparam = argc - 1;
9625         shellparam.p = argv + 1;
9626 #if ENABLE_ASH_GETOPTS
9627         shellparam.optind = 1;
9628         shellparam.optoff = -1;
9629 #endif
9630         evaltree(func->n.ndefun.body, flags & EV_TESTED);
9631  funcdone:
9632         INT_OFF;
9633         funcline = savefuncline;
9634         freefunc(func);
9635         freeparam(&shellparam);
9636         shellparam = saveparam;
9637         exception_handler = savehandler;
9638         INT_ON;
9639         evalskip &= ~SKIPFUNC;
9640         return e;
9641 }
9642
9643 /*
9644  * Make a variable a local variable.  When a variable is made local, it's
9645  * value and flags are saved in a localvar structure.  The saved values
9646  * will be restored when the shell function returns.  We handle the name
9647  * "-" as a special case: it makes changes to "set +-options" local
9648  * (options will be restored on return from the function).
9649  */
9650 static void
9651 mklocal(char *name)
9652 {
9653         struct localvar *lvp;
9654         struct var **vpp;
9655         struct var *vp;
9656         char *eq = strchr(name, '=');
9657
9658         INT_OFF;
9659         /* Cater for duplicate "local". Examples:
9660          * x=0; f() { local x=1; echo $x; local x; echo $x; }; f; echo $x
9661          * x=0; f() { local x=1; echo $x; local x=2; echo $x; }; f; echo $x
9662          */
9663         lvp = localvar_stack->lv;
9664         while (lvp) {
9665                 if (lvp->vp && varcmp(lvp->vp->var_text, name) == 0) {
9666                         if (eq)
9667                                 setvareq(name, 0);
9668                         /* else:
9669                          * it's a duplicate "local VAR" declaration, do nothing
9670                          */
9671                         goto ret;
9672                 }
9673                 lvp = lvp->next;
9674         }
9675
9676         lvp = ckzalloc(sizeof(*lvp));
9677         if (LONE_DASH(name)) {
9678                 char *p;
9679                 p = ckmalloc(sizeof(optlist));
9680                 lvp->text = memcpy(p, optlist, sizeof(optlist));
9681                 vp = NULL;
9682         } else {
9683                 vpp = hashvar(name);
9684                 vp = *findvar(vpp, name);
9685                 if (vp == NULL) {
9686                         /* variable did not exist yet */
9687                         if (eq)
9688                                 vp = setvareq(name, VSTRFIXED);
9689                         else
9690                                 vp = setvar(name, NULL, VSTRFIXED);
9691                         lvp->flags = VUNSET;
9692                 } else {
9693                         lvp->text = vp->var_text;
9694                         lvp->flags = vp->flags;
9695                         /* make sure neither "struct var" nor string gets freed
9696                          * during (un)setting:
9697                          */
9698                         vp->flags |= VSTRFIXED|VTEXTFIXED;
9699                         if (eq)
9700                                 setvareq(name, 0);
9701                         else
9702                                 /* "local VAR" unsets VAR: */
9703                                 setvar0(name, NULL);
9704                 }
9705         }
9706         lvp->vp = vp;
9707         lvp->next = localvar_stack->lv;
9708         localvar_stack->lv = lvp;
9709  ret:
9710         INT_ON;
9711 }
9712
9713 /*
9714  * The "local" command.
9715  */
9716 static int FAST_FUNC
9717 localcmd(int argc UNUSED_PARAM, char **argv)
9718 {
9719         char *name;
9720
9721         if (!localvar_stack)
9722                 ash_msg_and_raise_error("not in a function");
9723
9724         argv = argptr;
9725         while ((name = *argv++) != NULL) {
9726                 mklocal(name);
9727         }
9728         return 0;
9729 }
9730
9731 static int FAST_FUNC
9732 falsecmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
9733 {
9734         return 1;
9735 }
9736
9737 static int FAST_FUNC
9738 truecmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
9739 {
9740         return 0;
9741 }
9742
9743 static int FAST_FUNC
9744 execcmd(int argc UNUSED_PARAM, char **argv)
9745 {
9746         optionarg = NULL;
9747         while (nextopt("a:") != '\0')
9748                 /* nextopt() sets optionarg to "-a ARGV0" */;
9749
9750         argv = argptr;
9751         if (argv[0]) {
9752                 char *prog;
9753
9754                 iflag = 0;              /* exit on error */
9755                 mflag = 0;
9756                 optschanged();
9757                 /* We should set up signals for "exec CMD"
9758                  * the same way as for "CMD" without "exec".
9759                  * But optschanged->setinteractive->setsignal
9760                  * still thought we are a root shell. Therefore, for example,
9761                  * SIGQUIT is still set to IGN. Fix it:
9762                  */
9763                 shlvl++;
9764                 setsignal(SIGQUIT);
9765                 /*setsignal(SIGTERM); - unnecessary because of iflag=0 */
9766                 /*setsignal(SIGTSTP); - unnecessary because of mflag=0 */
9767                 /*setsignal(SIGTTOU); - unnecessary because of mflag=0 */
9768
9769                 prog = argv[0];
9770                 if (optionarg)
9771                         argv[0] = optionarg;
9772                 shellexec(prog, argv, pathval(), 0);
9773                 /* NOTREACHED */
9774         }
9775         return 0;
9776 }
9777
9778 /*
9779  * The return command.
9780  */
9781 static int FAST_FUNC
9782 returncmd(int argc UNUSED_PARAM, char **argv)
9783 {
9784         /*
9785          * If called outside a function, do what ksh does;
9786          * skip the rest of the file.
9787          */
9788         evalskip = SKIPFUNC;
9789         return argv[1] ? number(argv[1]) : exitstatus;
9790 }
9791
9792 /* Forward declarations for builtintab[] */
9793 static int breakcmd(int, char **) FAST_FUNC;
9794 static int dotcmd(int, char **) FAST_FUNC;
9795 static int evalcmd(int, char **, int) FAST_FUNC;
9796 static int exitcmd(int, char **) FAST_FUNC;
9797 static int exportcmd(int, char **) FAST_FUNC;
9798 #if ENABLE_ASH_GETOPTS
9799 static int getoptscmd(int, char **) FAST_FUNC;
9800 #endif
9801 #if ENABLE_ASH_HELP
9802 static int helpcmd(int, char **) FAST_FUNC;
9803 #endif
9804 #if MAX_HISTORY
9805 static int historycmd(int, char **) FAST_FUNC;
9806 #endif
9807 #if ENABLE_FEATURE_SH_MATH
9808 static int letcmd(int, char **) FAST_FUNC;
9809 #endif
9810 static int readcmd(int, char **) FAST_FUNC;
9811 static int setcmd(int, char **) FAST_FUNC;
9812 static int shiftcmd(int, char **) FAST_FUNC;
9813 static int timescmd(int, char **) FAST_FUNC;
9814 static int trapcmd(int, char **) FAST_FUNC;
9815 static int umaskcmd(int, char **) FAST_FUNC;
9816 static int unsetcmd(int, char **) FAST_FUNC;
9817 static int ulimitcmd(int, char **) FAST_FUNC;
9818
9819 #define BUILTIN_NOSPEC          "0"
9820 #define BUILTIN_SPECIAL         "1"
9821 #define BUILTIN_REGULAR         "2"
9822 #define BUILTIN_SPEC_REG        "3"
9823 #define BUILTIN_ASSIGN          "4"
9824 #define BUILTIN_SPEC_ASSG       "5"
9825 #define BUILTIN_REG_ASSG        "6"
9826 #define BUILTIN_SPEC_REG_ASSG   "7"
9827
9828 /* Stubs for calling non-FAST_FUNC's */
9829 #if ENABLE_ASH_ECHO
9830 static int FAST_FUNC echocmd(int argc, char **argv)   { return echo_main(argc, argv); }
9831 #endif
9832 #if ENABLE_ASH_PRINTF
9833 static int FAST_FUNC printfcmd(int argc, char **argv) { return printf_main(argc, argv); }
9834 #endif
9835 #if ENABLE_ASH_TEST || BASH_TEST2
9836 static int FAST_FUNC testcmd(int argc, char **argv)   { return test_main(argc, argv); }
9837 #endif
9838
9839 /* Keep these in proper order since it is searched via bsearch() */
9840 static const struct builtincmd builtintab[] = {
9841         { BUILTIN_SPEC_REG      "."       , dotcmd     },
9842         { BUILTIN_SPEC_REG      ":"       , truecmd    },
9843 #if ENABLE_ASH_TEST
9844         { BUILTIN_REGULAR       "["       , testcmd    },
9845 #endif
9846 #if BASH_TEST2
9847         { BUILTIN_REGULAR       "[["      , testcmd    },
9848 #endif
9849 #if ENABLE_ASH_ALIAS
9850         { BUILTIN_REG_ASSG      "alias"   , aliascmd   },
9851 #endif
9852 #if JOBS
9853         { BUILTIN_REGULAR       "bg"      , fg_bgcmd   },
9854 #endif
9855         { BUILTIN_SPEC_REG      "break"   , breakcmd   },
9856         { BUILTIN_REGULAR       "cd"      , cdcmd      },
9857         { BUILTIN_NOSPEC        "chdir"   , cdcmd      },
9858 #if ENABLE_ASH_CMDCMD
9859         { BUILTIN_REGULAR       "command" , commandcmd },
9860 #endif
9861         { BUILTIN_SPEC_REG      "continue", breakcmd   },
9862 #if ENABLE_ASH_ECHO
9863         { BUILTIN_REGULAR       "echo"    , echocmd    },
9864 #endif
9865         { BUILTIN_SPEC_REG      "eval"    , NULL       }, /*evalcmd() has a differing prototype*/
9866         { BUILTIN_SPEC_REG      "exec"    , execcmd    },
9867         { BUILTIN_SPEC_REG      "exit"    , exitcmd    },
9868         { BUILTIN_SPEC_REG_ASSG "export"  , exportcmd  },
9869         { BUILTIN_REGULAR       "false"   , falsecmd   },
9870 #if JOBS
9871         { BUILTIN_REGULAR       "fg"      , fg_bgcmd   },
9872 #endif
9873 #if ENABLE_ASH_GETOPTS
9874         { BUILTIN_REGULAR       "getopts" , getoptscmd },
9875 #endif
9876         { BUILTIN_NOSPEC        "hash"    , hashcmd    },
9877 #if ENABLE_ASH_HELP
9878         { BUILTIN_NOSPEC        "help"    , helpcmd    },
9879 #endif
9880 #if MAX_HISTORY
9881         { BUILTIN_NOSPEC        "history" , historycmd },
9882 #endif
9883 #if JOBS
9884         { BUILTIN_REGULAR       "jobs"    , jobscmd    },
9885         { BUILTIN_REGULAR       "kill"    , killcmd    },
9886 #endif
9887 #if ENABLE_FEATURE_SH_MATH
9888         { BUILTIN_NOSPEC        "let"     , letcmd     },
9889 #endif
9890         { BUILTIN_SPEC_REG_ASSG "local"   , localcmd   },
9891 #if ENABLE_ASH_PRINTF
9892         { BUILTIN_REGULAR       "printf"  , printfcmd  },
9893 #endif
9894         { BUILTIN_NOSPEC        "pwd"     , pwdcmd     },
9895         { BUILTIN_REGULAR       "read"    , readcmd    },
9896         { BUILTIN_SPEC_REG_ASSG "readonly", exportcmd  },
9897         { BUILTIN_SPEC_REG      "return"  , returncmd  },
9898         { BUILTIN_SPEC_REG      "set"     , setcmd     },
9899         { BUILTIN_SPEC_REG      "shift"   , shiftcmd   },
9900 #if BASH_SOURCE
9901         { BUILTIN_SPEC_REG      "source"  , dotcmd     },
9902 #endif
9903 #if ENABLE_ASH_TEST
9904         { BUILTIN_REGULAR       "test"    , testcmd    },
9905 #endif
9906         { BUILTIN_SPEC_REG      "times"   , timescmd   },
9907         { BUILTIN_SPEC_REG      "trap"    , trapcmd    },
9908         { BUILTIN_REGULAR       "true"    , truecmd    },
9909         { BUILTIN_NOSPEC        "type"    , typecmd    },
9910         { BUILTIN_NOSPEC        "ulimit"  , ulimitcmd  },
9911         { BUILTIN_REGULAR       "umask"   , umaskcmd   },
9912 #if ENABLE_ASH_ALIAS
9913         { BUILTIN_REGULAR       "unalias" , unaliascmd },
9914 #endif
9915         { BUILTIN_SPEC_REG      "unset"   , unsetcmd   },
9916         { BUILTIN_REGULAR       "wait"    , waitcmd    },
9917 };
9918
9919 /* Should match the above table! */
9920 #define COMMANDCMD (builtintab + \
9921         /* . : */       2 + \
9922         /* [ */         1 * ENABLE_ASH_TEST + \
9923         /* [[ */        1 * BASH_TEST2 + \
9924         /* alias */     1 * ENABLE_ASH_ALIAS + \
9925         /* bg */        1 * ENABLE_ASH_JOB_CONTROL + \
9926         /* break cd cddir  */   3)
9927 #define EVALCMD (COMMANDCMD + \
9928         /* command */   1 * ENABLE_ASH_CMDCMD + \
9929         /* continue */  1 + \
9930         /* echo */      1 * ENABLE_ASH_ECHO + \
9931         0)
9932 #define EXECCMD (EVALCMD + \
9933         /* eval */      1)
9934
9935 /*
9936  * Search the table of builtin commands.
9937  */
9938 static int
9939 pstrcmp1(const void *a, const void *b)
9940 {
9941         return strcmp((char*)a, *(char**)b + 1);
9942 }
9943 static struct builtincmd *
9944 find_builtin(const char *name)
9945 {
9946         struct builtincmd *bp;
9947
9948         bp = bsearch(
9949                 name, builtintab, ARRAY_SIZE(builtintab), sizeof(builtintab[0]),
9950                 pstrcmp1
9951         );
9952         return bp;
9953 }
9954
9955 /*
9956  * Execute a simple command.
9957  */
9958 static void unwindfiles(struct parsefile *stop);
9959 static int
9960 isassignment(const char *p)
9961 {
9962         const char *q = endofname(p);
9963         if (p == q)
9964                 return 0;
9965         return *q == '=';
9966 }
9967 static int FAST_FUNC
9968 bltincmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
9969 {
9970         /* Preserve exitstatus of a previous possible redirection
9971          * as POSIX mandates */
9972         return back_exitstatus;
9973 }
9974 static int
9975 evalcommand(union node *cmd, int flags)
9976 {
9977         static const struct builtincmd null_bltin = {
9978                 "\0\0", bltincmd /* why three NULs? */
9979         };
9980         struct localvar_list *localvar_stop;
9981         struct parsefile *file_stop;
9982         struct redirtab *redir_stop;
9983         struct stackmark smark;
9984         union node *argp;
9985         struct arglist arglist;
9986         struct arglist varlist;
9987         char **argv;
9988         int argc;
9989         const struct strlist *sp;
9990         struct cmdentry cmdentry;
9991         struct job *jp;
9992         char *lastarg;
9993         const char *path;
9994         int spclbltin;
9995         int status;
9996         char **nargv;
9997         smallint cmd_is_exec;
9998
9999         errlinno = lineno = cmd->ncmd.linno;
10000         if (funcline)
10001                 lineno -= funcline - 1;
10002
10003         /* First expand the arguments. */
10004         TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags));
10005         setstackmark(&smark);
10006         localvar_stop = pushlocalvars();
10007         file_stop = g_parsefile;
10008         back_exitstatus = 0;
10009
10010         cmdentry.cmdtype = CMDBUILTIN;
10011         cmdentry.u.cmd = &null_bltin;
10012         varlist.lastp = &varlist.list;
10013         *varlist.lastp = NULL;
10014         arglist.lastp = &arglist.list;
10015         *arglist.lastp = NULL;
10016
10017         argc = 0;
10018         if (cmd->ncmd.args) {
10019                 struct builtincmd *bcmd;
10020                 smallint pseudovarflag;
10021
10022                 bcmd = find_builtin(cmd->ncmd.args->narg.text);
10023                 pseudovarflag = bcmd && IS_BUILTIN_ASSIGN(bcmd);
10024
10025                 for (argp = cmd->ncmd.args; argp; argp = argp->narg.next) {
10026                         struct strlist **spp;
10027
10028                         spp = arglist.lastp;
10029                         if (pseudovarflag && isassignment(argp->narg.text))
10030                                 expandarg(argp, &arglist, EXP_VARTILDE);
10031                         else
10032                                 expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
10033
10034                         for (sp = *spp; sp; sp = sp->next)
10035                                 argc++;
10036                 }
10037         }
10038
10039         /* Reserve one extra spot at the front for shellexec. */
10040         nargv = stalloc(sizeof(char *) * (argc + 2));
10041         argv = ++nargv;
10042         for (sp = arglist.list; sp; sp = sp->next) {
10043                 TRACE(("evalcommand arg: %s\n", sp->text));
10044                 *nargv++ = sp->text;
10045         }
10046         *nargv = NULL;
10047
10048         lastarg = NULL;
10049         if (iflag && funcline == 0 && argc > 0)
10050                 lastarg = nargv[-1];
10051
10052         expredir(cmd->ncmd.redirect);
10053         redir_stop = pushredir(cmd->ncmd.redirect);
10054         preverrout_fd = 2;
10055         if (BASH_XTRACEFD && xflag) {
10056                 /* NB: bash closes fd == $BASH_XTRACEFD when it is changed.
10057                  * we do not emulate this. We only use its value.
10058                  */
10059                 const char *xtracefd = lookupvar("BASH_XTRACEFD");
10060                 if (xtracefd && is_number(xtracefd))
10061                         preverrout_fd = atoi(xtracefd);
10062
10063         }
10064         status = redirectsafe(cmd->ncmd.redirect, REDIR_PUSH | REDIR_SAVEFD2);
10065
10066         path = vpath.var_text;
10067         for (argp = cmd->ncmd.assign; argp; argp = argp->narg.next) {
10068                 struct strlist **spp;
10069                 char *p;
10070
10071                 spp = varlist.lastp;
10072                 expandarg(argp, &varlist, EXP_VARTILDE);
10073
10074                 mklocal((*spp)->text);
10075
10076                 /*
10077                  * Modify the command lookup path, if a PATH= assignment
10078                  * is present
10079                  */
10080                 p = (*spp)->text;
10081                 if (varcmp(p, path) == 0)
10082                         path = p;
10083         }
10084
10085         /* Print the command if xflag is set. */
10086         if (xflag) {
10087                 const char *pfx = "";
10088
10089                 fdprintf(preverrout_fd, "%s", expandstr(ps4val(), DQSYNTAX));
10090
10091                 sp = varlist.list;
10092                 while (sp) {
10093                         char *varval = sp->text;
10094                         char *eq = strchrnul(varval, '=');
10095                         if (*eq)
10096                                 eq++;
10097                         fdprintf(preverrout_fd, "%s%.*s%s",
10098                                 pfx,
10099                                 (int)(eq - varval), varval,
10100                                 maybe_single_quote(eq)
10101                         );
10102                         sp = sp->next;
10103                         pfx = " ";
10104                 }
10105
10106                 sp = arglist.list;
10107                 while (sp) {
10108                         fdprintf(preverrout_fd, "%s%s",
10109                                 pfx,
10110                                 /* always quote if matches reserved word: */
10111                                 findkwd(sp->text)
10112                                 ? single_quote(sp->text)
10113                                 : maybe_single_quote(sp->text)
10114                         );
10115                         sp = sp->next;
10116                         pfx = " ";
10117                 }
10118                 safe_write(preverrout_fd, "\n", 1);
10119         }
10120
10121         cmd_is_exec = 0;
10122         spclbltin = -1;
10123
10124         /* Now locate the command. */
10125         if (argc) {
10126                 int cmd_flag = DO_ERR;
10127 #if ENABLE_ASH_CMDCMD
10128                 const char *oldpath = path + 5;
10129 #endif
10130                 path += 5;
10131                 for (;;) {
10132                         find_command(argv[0], &cmdentry, cmd_flag, path);
10133                         if (cmdentry.cmdtype == CMDUNKNOWN) {
10134                                 flush_stdout_stderr();
10135                                 status = 127;
10136                                 goto bail;
10137                         }
10138
10139                         /* implement bltin and command here */
10140                         if (cmdentry.cmdtype != CMDBUILTIN)
10141                                 break;
10142                         if (spclbltin < 0)
10143                                 spclbltin = IS_BUILTIN_SPECIAL(cmdentry.u.cmd);
10144                         if (cmdentry.u.cmd == EXECCMD)
10145                                 cmd_is_exec = 1;
10146 #if ENABLE_ASH_CMDCMD
10147                         if (cmdentry.u.cmd == COMMANDCMD) {
10148                                 path = oldpath;
10149                                 nargv = parse_command_args(argv, &path);
10150                                 if (!nargv)
10151                                         break;
10152                                 /* It's "command [-p] PROG ARGS" (that is, no -Vv).
10153                                  * nargv => "PROG". path is updated if -p.
10154                                  */
10155                                 argc -= nargv - argv;
10156                                 argv = nargv;
10157                                 cmd_flag |= DO_NOFUNC;
10158                         } else
10159 #endif
10160                                 break;
10161                 }
10162         }
10163
10164         if (status) {
10165  bail:
10166                 exitstatus = status;
10167
10168                 /* We have a redirection error. */
10169                 if (spclbltin > 0)
10170                         raise_exception(EXERROR);
10171
10172                 goto out;
10173         }
10174
10175         /* Execute the command. */
10176         switch (cmdentry.cmdtype) {
10177         default: {
10178
10179 #if ENABLE_FEATURE_SH_STANDALONE \
10180  && ENABLE_FEATURE_SH_NOFORK \
10181  && NUM_APPLETS > 1
10182 /* (1) BUG: if variables are set, we need to fork, or save/restore them
10183  *     around run_nofork_applet() call.
10184  * (2) Should this check also be done in forkshell()?
10185  *     (perhaps it should, so that "VAR=VAL nofork" at least avoids exec...)
10186  */
10187                 /* find_command() encodes applet_no as (-2 - applet_no) */
10188                 int applet_no = (- cmdentry.u.index - 2);
10189                 if (applet_no >= 0 && APPLET_IS_NOFORK(applet_no)) {
10190                         char **sv_environ;
10191
10192                         INT_OFF;
10193                         sv_environ = environ;
10194                         environ = listvars(VEXPORT, VUNSET, varlist.list, /*end:*/ NULL);
10195                         /*
10196                          * Run <applet>_main().
10197                          * Signals (^C) can't interrupt here.
10198                          * Otherwise we can mangle stdio or malloc internal state.
10199                          * This makes applets which can run for a long time
10200                          * and/or wait for user input ineligible for NOFORK:
10201                          * for example, "yes" or "rm" (rm -i waits for input).
10202                          */
10203                         status = run_nofork_applet(applet_no, argv);
10204                         environ = sv_environ;
10205                         /*
10206                          * Try enabling NOFORK for "yes" applet.
10207                          * ^C _will_ stop it (write returns EINTR),
10208                          * but this causes stdout FILE to be stuck
10209                          * and needing clearerr(). What if other applets
10210                          * also can get EINTRs? Do we need to switch
10211                          * our signals to SA_RESTART?
10212                          */
10213                         /*clearerr(stdout);*/
10214                         INT_ON;
10215                         break;
10216                 }
10217 #endif
10218                 /* Can we avoid forking? For example, very last command
10219                  * in a script or a subshell does not need forking,
10220                  * we can just exec it.
10221                  */
10222                 if (!(flags & EV_EXIT) || may_have_traps) {
10223                         /* No, forking off a child is necessary */
10224                         INT_OFF;
10225                         get_tty_state();
10226                         jp = makejob(/*cmd,*/ 1);
10227                         if (forkshell(jp, cmd, FORK_FG) != 0) {
10228                                 /* parent */
10229                                 status = waitforjob(jp);
10230                                 INT_ON;
10231                                 TRACE(("forked child exited with %d\n", status));
10232                                 break;
10233                         }
10234                         /* child */
10235                         FORCE_INT_ON;
10236                         /* fall through to exec'ing external program */
10237                 }
10238                 listsetvar(varlist.list, VEXPORT|VSTACK);
10239                 shellexec(argv[0], argv, path, cmdentry.u.index);
10240                 /* NOTREACHED */
10241         } /* default */
10242         case CMDBUILTIN:
10243                 if (spclbltin > 0 || argc == 0) {
10244                         poplocalvars(1);
10245                         if (cmd_is_exec && argc > 1)
10246                                 listsetvar(varlist.list, VEXPORT);
10247                 }
10248
10249                 /* Tight loop with builtins only:
10250                  * "while kill -0 $child; do true; done"
10251                  * will never exit even if $child died, unless we do this
10252                  * to reap the zombie and make kill detect that it's gone: */
10253                 dowait(DOWAIT_NONBLOCK, NULL);
10254
10255                 if (evalbltin(cmdentry.u.cmd, argc, argv, flags)) {
10256                         if (exception_type == EXERROR && spclbltin <= 0) {
10257                                 FORCE_INT_ON;
10258                                 goto readstatus;
10259                         }
10260  raise:
10261                         longjmp(exception_handler->loc, 1);
10262                 }
10263                 goto readstatus;
10264
10265         case CMDFUNCTION:
10266                 /* See above for the rationale */
10267                 dowait(DOWAIT_NONBLOCK, NULL);
10268                 if (evalfun(cmdentry.u.func, argc, argv, flags))
10269                         goto raise;
10270  readstatus:
10271                 status = exitstatus;
10272                 break;
10273         } /* switch */
10274
10275  out:
10276         if (cmd->ncmd.redirect)
10277                 popredir(/*drop:*/ cmd_is_exec);
10278         unwindredir(redir_stop);
10279         unwindfiles(file_stop);
10280         unwindlocalvars(localvar_stop);
10281         if (lastarg) {
10282                 /* dsl: I think this is intended to be used to support
10283                  * '_' in 'vi' command mode during line editing...
10284                  * However I implemented that within libedit itself.
10285                  */
10286                 setvar0("_", lastarg);
10287         }
10288         popstackmark(&smark);
10289
10290         return status;
10291 }
10292
10293 static int
10294 evalbltin(const struct builtincmd *cmd, int argc, char **argv, int flags)
10295 {
10296         char *volatile savecmdname;
10297         struct jmploc *volatile savehandler;
10298         struct jmploc jmploc;
10299         int status;
10300         int i;
10301
10302         savecmdname = commandname;
10303         savehandler = exception_handler;
10304         i = setjmp(jmploc.loc);
10305         if (i)
10306                 goto cmddone;
10307         exception_handler = &jmploc;
10308         commandname = argv[0];
10309         argptr = argv + 1;
10310         optptr = NULL;                  /* initialize nextopt */
10311         if (cmd == EVALCMD)
10312                 status = evalcmd(argc, argv, flags);
10313         else
10314                 status = (*cmd->builtin)(argc, argv);
10315         flush_stdout_stderr();
10316         status |= ferror(stdout);
10317         exitstatus = status;
10318  cmddone:
10319         clearerr(stdout);
10320         commandname = savecmdname;
10321         exception_handler = savehandler;
10322
10323         return i;
10324 }
10325
10326 static int
10327 goodname(const char *p)
10328 {
10329         return endofname(p)[0] == '\0';
10330 }
10331
10332
10333 /*
10334  * Search for a command.  This is called before we fork so that the
10335  * location of the command will be available in the parent as well as
10336  * the child.  The check for "goodname" is an overly conservative
10337  * check that the name will not be subject to expansion.
10338  */
10339 static void
10340 prehash(union node *n)
10341 {
10342         struct cmdentry entry;
10343
10344         if (n->type == NCMD && n->ncmd.args && goodname(n->ncmd.args->narg.text))
10345                 find_command(n->ncmd.args->narg.text, &entry, 0, pathval());
10346 }
10347
10348
10349 /* ============ Builtin commands
10350  *
10351  * Builtin commands whose functions are closely tied to evaluation
10352  * are implemented here.
10353  */
10354
10355 /*
10356  * Handle break and continue commands.  Break, continue, and return are
10357  * all handled by setting the evalskip flag.  The evaluation routines
10358  * above all check this flag, and if it is set they start skipping
10359  * commands rather than executing them.  The variable skipcount is
10360  * the number of loops to break/continue, or the number of function
10361  * levels to return.  (The latter is always 1.)  It should probably
10362  * be an error to break out of more loops than exist, but it isn't
10363  * in the standard shell so we don't make it one here.
10364  */
10365 static int FAST_FUNC
10366 breakcmd(int argc UNUSED_PARAM, char **argv)
10367 {
10368         int n = argv[1] ? number(argv[1]) : 1;
10369
10370         if (n <= 0)
10371                 ash_msg_and_raise_error(msg_illnum, argv[1]);
10372         if (n > loopnest)
10373                 n = loopnest;
10374         if (n > 0) {
10375                 evalskip = (**argv == 'c') ? SKIPCONT : SKIPBREAK;
10376                 skipcount = n;
10377         }
10378         return 0;
10379 }
10380
10381
10382 /*
10383  * This implements the input routines used by the parser.
10384  */
10385
10386 enum {
10387         INPUT_PUSH_FILE = 1,
10388         INPUT_NOFILE_OK = 2,
10389 };
10390
10391 static smallint checkkwd;
10392 /* values of checkkwd variable */
10393 #define CHKALIAS        0x1
10394 #define CHKKWD          0x2
10395 #define CHKNL           0x4
10396 #define CHKEOFMARK      0x8
10397
10398 /*
10399  * Push a string back onto the input at this current parsefile level.
10400  * We handle aliases this way.
10401  */
10402 #if !ENABLE_ASH_ALIAS
10403 #define pushstring(s, ap) pushstring(s)
10404 #endif
10405 static void
10406 pushstring(char *s, struct alias *ap)
10407 {
10408         struct strpush *sp;
10409         int len;
10410
10411         len = strlen(s);
10412         INT_OFF;
10413         if (g_parsefile->strpush) {
10414                 sp = ckzalloc(sizeof(*sp));
10415                 sp->prev = g_parsefile->strpush;
10416         } else {
10417                 sp = &(g_parsefile->basestrpush);
10418         }
10419         g_parsefile->strpush = sp;
10420         sp->prev_string = g_parsefile->next_to_pgetc;
10421         sp->prev_left_in_line = g_parsefile->left_in_line;
10422         sp->unget = g_parsefile->unget;
10423         memcpy(sp->lastc, g_parsefile->lastc, sizeof(sp->lastc));
10424 #if ENABLE_ASH_ALIAS
10425         sp->ap = ap;
10426         if (ap) {
10427                 ap->flag |= ALIASINUSE;
10428                 sp->string = s;
10429         }
10430 #endif
10431         g_parsefile->next_to_pgetc = s;
10432         g_parsefile->left_in_line = len;
10433         g_parsefile->unget = 0;
10434         INT_ON;
10435 }
10436
10437 static void
10438 popstring(void)
10439 {
10440         struct strpush *sp = g_parsefile->strpush;
10441
10442         INT_OFF;
10443 #if ENABLE_ASH_ALIAS
10444         if (sp->ap) {
10445                 if (g_parsefile->next_to_pgetc[-1] == ' '
10446                  || g_parsefile->next_to_pgetc[-1] == '\t'
10447                 ) {
10448                         checkkwd |= CHKALIAS;
10449                 }
10450                 if (sp->string != sp->ap->val) {
10451                         free(sp->string);
10452                 }
10453                 sp->ap->flag &= ~ALIASINUSE;
10454                 if (sp->ap->flag & ALIASDEAD) {
10455                         unalias(sp->ap->name);
10456                 }
10457         }
10458 #endif
10459         g_parsefile->next_to_pgetc = sp->prev_string;
10460         g_parsefile->left_in_line = sp->prev_left_in_line;
10461         g_parsefile->unget = sp->unget;
10462         memcpy(g_parsefile->lastc, sp->lastc, sizeof(sp->lastc));
10463         g_parsefile->strpush = sp->prev;
10464         if (sp != &(g_parsefile->basestrpush))
10465                 free(sp);
10466         INT_ON;
10467 }
10468
10469 static int
10470 preadfd(void)
10471 {
10472         int nr;
10473         char *buf = g_parsefile->buf;
10474
10475         g_parsefile->next_to_pgetc = buf;
10476 #if ENABLE_FEATURE_EDITING
10477  retry:
10478         if (!iflag || g_parsefile->pf_fd != STDIN_FILENO)
10479                 nr = nonblock_immune_read(g_parsefile->pf_fd, buf, IBUFSIZ - 1);
10480         else {
10481 # if ENABLE_ASH_IDLE_TIMEOUT
10482                 int timeout = -1;
10483                 if (iflag) {
10484                         const char *tmout_var = lookupvar("TMOUT");
10485                         if (tmout_var) {
10486                                 timeout = atoi(tmout_var) * 1000;
10487                                 if (timeout <= 0)
10488                                         timeout = -1;
10489                         }
10490                 }
10491                 line_input_state->timeout = timeout;
10492 # endif
10493 # if ENABLE_FEATURE_TAB_COMPLETION
10494                 line_input_state->path_lookup = pathval();
10495 # endif
10496                 reinit_unicode_for_ash();
10497                 nr = read_line_input(line_input_state, cmdedit_prompt, buf, IBUFSIZ);
10498                 if (nr == 0) {
10499                         /* ^C pressed, "convert" to SIGINT */
10500                         write(STDOUT_FILENO, "^C", 2);
10501                         if (trap[SIGINT]) {
10502                                 buf[0] = '\n';
10503                                 buf[1] = '\0';
10504                                 raise(SIGINT);
10505                                 return 1;
10506                         }
10507                         exitstatus = 128 + SIGINT;
10508                         bb_putchar('\n');
10509                         goto retry;
10510                 }
10511                 if (nr < 0) {
10512                         if (errno == 0) {
10513                                 /* Ctrl+D pressed */
10514                                 nr = 0;
10515                         }
10516 # if ENABLE_ASH_IDLE_TIMEOUT
10517                         else if (errno == EAGAIN && timeout > 0) {
10518                                 puts("\007timed out waiting for input: auto-logout");
10519                                 exitshell();
10520                         }
10521 # endif
10522                 }
10523         }
10524 #else
10525         nr = nonblock_immune_read(g_parsefile->pf_fd, buf, IBUFSIZ - 1);
10526 #endif
10527
10528 #if 0 /* disabled: nonblock_immune_read() handles this problem */
10529         if (nr < 0) {
10530                 if (parsefile->fd == 0 && errno == EWOULDBLOCK) {
10531                         int flags = fcntl(0, F_GETFL);
10532                         if (flags >= 0 && (flags & O_NONBLOCK)) {
10533                                 flags &= ~O_NONBLOCK;
10534                                 if (fcntl(0, F_SETFL, flags) >= 0) {
10535                                         out2str("sh: turning off NDELAY mode\n");
10536                                         goto retry;
10537                                 }
10538                         }
10539                 }
10540         }
10541 #endif
10542         return nr;
10543 }
10544
10545 /*
10546  * Refill the input buffer and return the next input character:
10547  *
10548  * 1) If a string was pushed back on the input, pop it;
10549  * 2) If an EOF was pushed back (g_parsefile->left_in_line < -BIGNUM)
10550  *    or we are reading from a string so we can't refill the buffer,
10551  *    return EOF.
10552  * 3) If there is more stuff in this buffer, use it else call read to fill it.
10553  * 4) Process input up to the next newline, deleting nul characters.
10554  */
10555 //#define pgetc_debug(...) bb_error_msg(__VA_ARGS__)
10556 #define pgetc_debug(...) ((void)0)
10557 static int pgetc(void);
10558 static int
10559 preadbuffer(void)
10560 {
10561         char *q;
10562         int more;
10563
10564         if (g_parsefile->strpush) {
10565 #if ENABLE_ASH_ALIAS
10566                 if (g_parsefile->left_in_line == -1
10567                  && g_parsefile->strpush->ap
10568                  && g_parsefile->next_to_pgetc[-1] != ' '
10569                  && g_parsefile->next_to_pgetc[-1] != '\t'
10570                 ) {
10571                         pgetc_debug("preadbuffer PEOA");
10572                         return PEOA;
10573                 }
10574 #endif
10575                 popstring();
10576                 return pgetc();
10577         }
10578         /* on both branches above g_parsefile->left_in_line < 0.
10579          * "pgetc" needs refilling.
10580          */
10581
10582         /* -90 is our -BIGNUM. Below we use -99 to mark "EOF on read",
10583          * pungetc() may increment it a few times.
10584          * Assuming it won't increment it to less than -90.
10585          */
10586         if (g_parsefile->left_in_line < -90 || g_parsefile->buf == NULL) {
10587                 pgetc_debug("preadbuffer PEOF1");
10588                 /* even in failure keep left_in_line and next_to_pgetc
10589                  * in lock step, for correct multi-layer pungetc.
10590                  * left_in_line was decremented before preadbuffer(),
10591                  * must inc next_to_pgetc: */
10592                 g_parsefile->next_to_pgetc++;
10593                 return PEOF;
10594         }
10595
10596         more = g_parsefile->left_in_buffer;
10597         if (more <= 0) {
10598                 flush_stdout_stderr();
10599  again:
10600                 more = preadfd();
10601                 if (more <= 0) {
10602                         /* don't try reading again */
10603                         g_parsefile->left_in_line = -99;
10604                         pgetc_debug("preadbuffer PEOF2");
10605                         g_parsefile->next_to_pgetc++;
10606                         return PEOF;
10607                 }
10608         }
10609
10610         /* Find out where's the end of line.
10611          * Set g_parsefile->left_in_line
10612          * and g_parsefile->left_in_buffer acordingly.
10613          * NUL chars are deleted.
10614          */
10615         q = g_parsefile->next_to_pgetc;
10616         for (;;) {
10617                 char c;
10618
10619                 more--;
10620
10621                 c = *q;
10622                 if (c == '\0') {
10623                         memmove(q, q + 1, more);
10624                 } else {
10625                         q++;
10626                         if (c == '\n') {
10627                                 g_parsefile->left_in_line = q - g_parsefile->next_to_pgetc - 1;
10628                                 break;
10629                         }
10630                 }
10631
10632                 if (more <= 0) {
10633                         g_parsefile->left_in_line = q - g_parsefile->next_to_pgetc - 1;
10634                         if (g_parsefile->left_in_line < 0)
10635                                 goto again;
10636                         break;
10637                 }
10638         }
10639         g_parsefile->left_in_buffer = more;
10640
10641         if (vflag) {
10642                 char save = *q;
10643                 *q = '\0';
10644                 out2str(g_parsefile->next_to_pgetc);
10645                 *q = save;
10646         }
10647
10648         pgetc_debug("preadbuffer at %d:%p'%s'",
10649                         g_parsefile->left_in_line,
10650                         g_parsefile->next_to_pgetc,
10651                         g_parsefile->next_to_pgetc);
10652         return (unsigned char)*g_parsefile->next_to_pgetc++;
10653 }
10654
10655 static void
10656 nlprompt(void)
10657 {
10658         g_parsefile->linno++;
10659         setprompt_if(doprompt, 2);
10660 }
10661 static void
10662 nlnoprompt(void)
10663 {
10664         g_parsefile->linno++;
10665         needprompt = doprompt;
10666 }
10667
10668 static int
10669 pgetc(void)
10670 {
10671         int c;
10672
10673         pgetc_debug("pgetc at %d:%p'%s'",
10674                         g_parsefile->left_in_line,
10675                         g_parsefile->next_to_pgetc,
10676                         g_parsefile->next_to_pgetc);
10677         if (g_parsefile->unget)
10678                 return g_parsefile->lastc[--g_parsefile->unget];
10679
10680         if (--g_parsefile->left_in_line >= 0)
10681                 c = (unsigned char)*g_parsefile->next_to_pgetc++;
10682         else
10683                 c = preadbuffer();
10684
10685         g_parsefile->lastc[1] = g_parsefile->lastc[0];
10686         g_parsefile->lastc[0] = c;
10687
10688         return c;
10689 }
10690
10691 #if ENABLE_ASH_ALIAS
10692 static int
10693 pgetc_without_PEOA(void)
10694 {
10695         int c;
10696         do {
10697                 pgetc_debug("pgetc at %d:%p'%s'",
10698                                 g_parsefile->left_in_line,
10699                                 g_parsefile->next_to_pgetc,
10700                                 g_parsefile->next_to_pgetc);
10701                 c = pgetc();
10702         } while (c == PEOA);
10703         return c;
10704 }
10705 #else
10706 # define pgetc_without_PEOA() pgetc()
10707 #endif
10708
10709 /*
10710  * Undo a call to pgetc.  Only two characters may be pushed back.
10711  * PEOF may be pushed back.
10712  */
10713 static void
10714 pungetc(void)
10715 {
10716         g_parsefile->unget++;
10717 }
10718
10719 /* This one eats backslash+newline */
10720 static int
10721 pgetc_eatbnl(void)
10722 {
10723         int c;
10724
10725         while ((c = pgetc()) == '\\') {
10726                 if (pgetc() != '\n') {
10727                         pungetc();
10728                         break;
10729                 }
10730
10731                 nlprompt();
10732         }
10733
10734         return c;
10735 }
10736
10737 struct synstack {
10738         smalluint syntax;
10739         uint8_t innerdq   :1;
10740         uint8_t varpushed :1;
10741         uint8_t dblquote  :1;
10742         int varnest;            /* levels of variables expansion */
10743         int dqvarnest;          /* levels of variables expansion within double quotes */
10744         int parenlevel;         /* levels of parens in arithmetic */
10745         struct synstack *prev;
10746         struct synstack *next;
10747 };
10748
10749 static void
10750 synstack_push(struct synstack **stack, struct synstack *next, int syntax)
10751 {
10752         memset(next, 0, sizeof(*next));
10753         next->syntax = syntax;
10754         next->next = *stack;
10755         (*stack)->prev = next;
10756         *stack = next;
10757 }
10758
10759 static ALWAYS_INLINE void
10760 synstack_pop(struct synstack **stack)
10761 {
10762         *stack = (*stack)->next;
10763 }
10764
10765 /*
10766  * To handle the "." command, a stack of input files is used.  Pushfile
10767  * adds a new entry to the stack and popfile restores the previous level.
10768  */
10769 static void
10770 pushfile(void)
10771 {
10772         struct parsefile *pf;
10773
10774         pf = ckzalloc(sizeof(*pf));
10775         pf->prev = g_parsefile;
10776         pf->pf_fd = -1;
10777         /*pf->strpush = NULL; - ckzalloc did it */
10778         /*pf->basestrpush.prev = NULL;*/
10779         /*pf->unget = 0;*/
10780         g_parsefile = pf;
10781 }
10782
10783 static void
10784 popfile(void)
10785 {
10786         struct parsefile *pf = g_parsefile;
10787
10788         if (pf == &basepf)
10789                 return;
10790
10791         INT_OFF;
10792         if (pf->pf_fd >= 0)
10793                 close(pf->pf_fd);
10794         free(pf->buf);
10795         while (pf->strpush)
10796                 popstring();
10797         g_parsefile = pf->prev;
10798         free(pf);
10799         INT_ON;
10800 }
10801
10802 static void
10803 unwindfiles(struct parsefile *stop)
10804 {
10805         while (g_parsefile != stop)
10806                 popfile();
10807 }
10808
10809 /*
10810  * Return to top level.
10811  */
10812 static void
10813 popallfiles(void)
10814 {
10815         unwindfiles(&basepf);
10816 }
10817
10818 /*
10819  * Close the file(s) that the shell is reading commands from.  Called
10820  * after a fork is done.
10821  */
10822 static void
10823 closescript(void)
10824 {
10825         popallfiles();
10826         if (g_parsefile->pf_fd > 0) {
10827                 close(g_parsefile->pf_fd);
10828                 g_parsefile->pf_fd = 0;
10829         }
10830 }
10831
10832 /*
10833  * Like setinputfile, but takes an open file descriptor.  Call this with
10834  * interrupts off.
10835  */
10836 static void
10837 setinputfd(int fd, int push)
10838 {
10839         if (push) {
10840                 pushfile();
10841                 g_parsefile->buf = NULL;
10842         }
10843         g_parsefile->pf_fd = fd;
10844         if (g_parsefile->buf == NULL)
10845                 g_parsefile->buf = ckmalloc(IBUFSIZ);
10846         g_parsefile->left_in_buffer = 0;
10847         g_parsefile->left_in_line = 0;
10848         g_parsefile->linno = 1;
10849 }
10850
10851 /*
10852  * Set the input to take input from a file.  If push is set, push the
10853  * old input onto the stack first.
10854  */
10855 static int
10856 setinputfile(const char *fname, int flags)
10857 {
10858         int fd;
10859
10860         INT_OFF;
10861         fd = open(fname, O_RDONLY | O_CLOEXEC);
10862         if (fd < 0) {
10863                 if (flags & INPUT_NOFILE_OK)
10864                         goto out;
10865                 exitstatus = 127;
10866                 ash_msg_and_raise_perror("can't open '%s'", fname);
10867         }
10868         if (fd < 10)
10869                 fd = savefd(fd);
10870         else if (O_CLOEXEC == 0) /* old libc */
10871                 close_on_exec_on(fd);
10872
10873         setinputfd(fd, flags & INPUT_PUSH_FILE);
10874  out:
10875         INT_ON;
10876         return fd;
10877 }
10878
10879 /*
10880  * Like setinputfile, but takes input from a string.
10881  */
10882 static void
10883 setinputstring(char *string)
10884 {
10885         INT_OFF;
10886         pushfile();
10887         g_parsefile->next_to_pgetc = string;
10888         g_parsefile->left_in_line = strlen(string);
10889         g_parsefile->buf = NULL;
10890         g_parsefile->linno = 1;
10891         INT_ON;
10892 }
10893
10894
10895 /*
10896  * Routines to check for mail.
10897  */
10898
10899 #if ENABLE_ASH_MAIL
10900
10901 /* Hash of mtimes of mailboxes */
10902 static unsigned mailtime_hash;
10903 /* Set if MAIL or MAILPATH is changed. */
10904 static smallint mail_var_path_changed;
10905
10906 /*
10907  * Print appropriate message(s) if mail has arrived.
10908  * If mail_var_path_changed is set,
10909  * then the value of MAIL has mail_var_path_changed,
10910  * so we just update the values.
10911  */
10912 static void
10913 chkmail(void)
10914 {
10915         const char *mpath;
10916         char *p;
10917         char *q;
10918         unsigned new_hash;
10919         struct stackmark smark;
10920         struct stat statb;
10921
10922         setstackmark(&smark);
10923         mpath = mpathset() ? mpathval() : mailval();
10924         new_hash = 0;
10925         for (;;) {
10926                 p = path_advance(&mpath, nullstr);
10927                 if (p == NULL)
10928                         break;
10929                 if (*p == '\0')
10930                         continue;
10931                 for (q = p; *q; q++)
10932                         continue;
10933 #if DEBUG
10934                 if (q[-1] != '/')
10935                         abort();
10936 #endif
10937                 q[-1] = '\0';                   /* delete trailing '/' */
10938                 if (stat(p, &statb) < 0) {
10939                         continue;
10940                 }
10941                 /* Very simplistic "hash": just a sum of all mtimes */
10942                 new_hash += (unsigned)statb.st_mtime;
10943         }
10944         if (!mail_var_path_changed && mailtime_hash != new_hash) {
10945                 if (mailtime_hash != 0)
10946                         out2str("you have mail\n");
10947                 mailtime_hash = new_hash;
10948         }
10949         mail_var_path_changed = 0;
10950         popstackmark(&smark);
10951 }
10952
10953 static void FAST_FUNC
10954 changemail(const char *val UNUSED_PARAM)
10955 {
10956         mail_var_path_changed = 1;
10957 }
10958
10959 #endif /* ASH_MAIL */
10960
10961
10962 /* ============ ??? */
10963
10964 /*
10965  * Set the shell parameters.
10966  */
10967 static void
10968 setparam(char **argv)
10969 {
10970         char **newparam;
10971         char **ap;
10972         int nparam;
10973
10974         for (nparam = 0; argv[nparam]; nparam++)
10975                 continue;
10976         ap = newparam = ckmalloc((nparam + 1) * sizeof(*ap));
10977         while (*argv) {
10978                 *ap++ = ckstrdup(*argv++);
10979         }
10980         *ap = NULL;
10981         freeparam(&shellparam);
10982         shellparam.malloced = 1;
10983         shellparam.nparam = nparam;
10984         shellparam.p = newparam;
10985 #if ENABLE_ASH_GETOPTS
10986         shellparam.optind = 1;
10987         shellparam.optoff = -1;
10988 #endif
10989 }
10990
10991 /*
10992  * Process shell options.  The global variable argptr contains a pointer
10993  * to the argument list; we advance it past the options.
10994  *
10995  * SUSv3 section 2.8.1 "Consequences of Shell Errors" says:
10996  * For a non-interactive shell, an error condition encountered
10997  * by a special built-in ... shall cause the shell to write a diagnostic message
10998  * to standard error and exit as shown in the following table:
10999  * Error                                           Special Built-In
11000  * ...
11001  * Utility syntax error (option or operand error)  Shall exit
11002  * ...
11003  * However, in bug 1142 (http://busybox.net/bugs/view.php?id=1142)
11004  * we see that bash does not do that (set "finishes" with error code 1 instead,
11005  * and shell continues), and people rely on this behavior!
11006  * Testcase:
11007  * set -o barfoo 2>/dev/null
11008  * echo $?
11009  *
11010  * Oh well. Let's mimic that.
11011  */
11012 static int
11013 plus_minus_o(char *name, int val)
11014 {
11015         int i;
11016
11017         if (name) {
11018                 for (i = 0; i < NOPTS; i++) {
11019                         if (strcmp(name, optnames(i)) == 0) {
11020                                 optlist[i] = val;
11021                                 return 0;
11022                         }
11023                 }
11024                 ash_msg("illegal option %co %s", val ? '-' : '+', name);
11025                 return 1;
11026         }
11027         for (i = 0; i < NOPTS; i++) {
11028                 if (val) {
11029                         out1fmt("%-16s%s\n", optnames(i), optlist[i] ? "on" : "off");
11030                 } else {
11031                         out1fmt("set %co %s\n", optlist[i] ? '-' : '+', optnames(i));
11032                 }
11033         }
11034         return 0;
11035 }
11036 static void
11037 setoption(int flag, int val)
11038 {
11039         int i;
11040
11041         for (i = 0; i < NOPTS; i++) {
11042                 if (optletters(i) == flag) {
11043                         optlist[i] = val;
11044                         return;
11045                 }
11046         }
11047         ash_msg_and_raise_error("illegal option %c%c", val ? '-' : '+', flag);
11048         /* NOTREACHED */
11049 }
11050 static int
11051 options(int cmdline, int *login_sh)
11052 {
11053         char *p;
11054         int val;
11055         int c;
11056
11057         if (cmdline)
11058                 minusc = NULL;
11059         while ((p = *argptr) != NULL) {
11060                 c = *p++;
11061                 if (c != '-' && c != '+')
11062                         break;
11063                 argptr++;
11064                 val = 0; /* val = 0 if c == '+' */
11065                 if (c == '-') {
11066                         val = 1;
11067                         if (p[0] == '\0' || LONE_DASH(p)) {
11068                                 if (!cmdline) {
11069                                         /* "-" means turn off -x and -v */
11070                                         if (p[0] == '\0')
11071                                                 xflag = vflag = 0;
11072                                         /* "--" means reset params */
11073                                         else if (*argptr == NULL)
11074                                                 setparam(argptr);
11075                                 }
11076                                 break;    /* "-" or "--" terminates options */
11077                         }
11078                 }
11079                 /* first char was + or - */
11080                 while ((c = *p++) != '\0') {
11081                         /* bash 3.2 indeed handles -c CMD and +c CMD the same */
11082                         if (c == 'c' && cmdline) {
11083                                 minusc = p;     /* command is after shell args */
11084                         } else if (c == 'o') {
11085                                 if (plus_minus_o(*argptr, val)) {
11086                                         /* it already printed err message */
11087                                         return 1; /* error */
11088                                 }
11089                                 if (*argptr)
11090                                         argptr++;
11091                         } else if (cmdline && (c == 'l')) { /* -l or +l == --login */
11092                                 if (login_sh)
11093                                         *login_sh = 1;
11094                         /* bash does not accept +-login, we also won't */
11095                         } else if (cmdline && val && (c == '-')) { /* long options */
11096                                 if (strcmp(p, "login") == 0) {
11097                                         if (login_sh)
11098                                                 *login_sh = 1;
11099                                 }
11100                                 break;
11101                         } else {
11102                                 setoption(c, val);
11103                         }
11104                 }
11105         }
11106         return 0;
11107 }
11108
11109 /*
11110  * The shift builtin command.
11111  */
11112 static int FAST_FUNC
11113 shiftcmd(int argc UNUSED_PARAM, char **argv)
11114 {
11115         int n;
11116         char **ap1, **ap2;
11117
11118         n = 1;
11119         if (argv[1])
11120                 n = number(argv[1]);
11121         if (n > shellparam.nparam)
11122                 return 1;
11123         INT_OFF;
11124         shellparam.nparam -= n;
11125         for (ap1 = shellparam.p; --n >= 0; ap1++) {
11126                 if (shellparam.malloced)
11127                         free(*ap1);
11128         }
11129         ap2 = shellparam.p;
11130         while ((*ap2++ = *ap1++) != NULL)
11131                 continue;
11132 #if ENABLE_ASH_GETOPTS
11133         shellparam.optind = 1;
11134         shellparam.optoff = -1;
11135 #endif
11136         INT_ON;
11137         return 0;
11138 }
11139
11140 /*
11141  * POSIX requires that 'set' (but not export or readonly) output the
11142  * variables in lexicographic order - by the locale's collating order (sigh).
11143  * Maybe we could keep them in an ordered balanced binary tree
11144  * instead of hashed lists.
11145  * For now just roll 'em through qsort for printing...
11146  */
11147 static int
11148 showvars(const char *sep_prefix, int on, int off)
11149 {
11150         const char *sep;
11151         char **ep, **epend;
11152
11153         ep = listvars(on, off, /*strlist:*/ NULL, &epend);
11154         qsort(ep, epend - ep, sizeof(char *), vpcmp);
11155
11156         sep = *sep_prefix ? " " : sep_prefix;
11157
11158         for (; ep < epend; ep++) {
11159                 const char *p;
11160                 const char *q;
11161
11162                 p = endofname(*ep);
11163 /* Used to have simple "p = strchrnul(*ep, '=')" here instead, but this
11164  * makes "export -p" to have output not suitable for "eval":
11165  * import os
11166  * os.environ["test-test"]="test"
11167  * if os.fork() == 0:
11168  *   os.execv("ash", [ 'ash', '-c', 'eval $(export -p); echo OK' ])  # fixes this
11169  * os.execv("ash", [ 'ash', '-c', 'env | grep test-test' ])
11170  */
11171                 q = nullstr;
11172                 if (*p == '=')
11173                         q = single_quote(++p);
11174                 out1fmt("%s%s%.*s%s\n", sep_prefix, sep, (int)(p - *ep), *ep, q);
11175         }
11176         return 0;
11177 }
11178
11179 /*
11180  * The set command builtin.
11181  */
11182 static int FAST_FUNC
11183 setcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
11184 {
11185         int retval;
11186
11187         if (!argv[1])
11188                 return showvars(nullstr, 0, VUNSET);
11189
11190         INT_OFF;
11191         retval = options(/*cmdline:*/ 0, NULL);
11192         if (retval == 0) { /* if no parse error... */
11193                 optschanged();
11194                 if (*argptr != NULL) {
11195                         setparam(argptr);
11196                 }
11197         }
11198         INT_ON;
11199         return retval;
11200 }
11201
11202 #if ENABLE_ASH_RANDOM_SUPPORT
11203 static void FAST_FUNC
11204 change_random(const char *value)
11205 {
11206         uint32_t t;
11207
11208         if (value == NULL) {
11209                 /* "get", generate */
11210                 t = next_random(&random_gen);
11211                 /* set without recursion */
11212                 setvar(vrandom.var_text, utoa(t), VNOFUNC);
11213                 vrandom.flags &= ~VNOFUNC;
11214         } else {
11215                 /* set/reset */
11216                 t = strtoul(value, NULL, 10);
11217                 INIT_RANDOM_T(&random_gen, (t ? t : 1), t);
11218         }
11219 }
11220 #endif
11221
11222 #if ENABLE_ASH_GETOPTS
11223 static int
11224 getopts(char *optstr, char *optvar, char **optfirst)
11225 {
11226         char *p, *q;
11227         char c = '?';
11228         int done = 0;
11229         char sbuf[2];
11230         char **optnext;
11231         int ind = shellparam.optind;
11232         int off = shellparam.optoff;
11233
11234         sbuf[1] = '\0';
11235
11236         shellparam.optind = -1;
11237         optnext = optfirst + ind - 1;
11238
11239         if (ind <= 1 || off < 0 || (int)strlen(optnext[-1]) < off)
11240                 p = NULL;
11241         else
11242                 p = optnext[-1] + off;
11243         if (p == NULL || *p == '\0') {
11244                 /* Current word is done, advance */
11245                 p = *optnext;
11246                 if (p == NULL || *p != '-' || *++p == '\0') {
11247  atend:
11248                         unsetvar("OPTARG");
11249                         p = NULL;
11250                         done = 1;
11251                         goto out;
11252                 }
11253                 optnext++;
11254                 if (LONE_DASH(p))        /* check for "--" */
11255                         goto atend;
11256         }
11257
11258         c = *p++;
11259         for (q = optstr; *q != c;) {
11260                 if (*q == '\0') {
11261                         /* OPTERR is a bashism */
11262                         const char *cp = lookupvar("OPTERR");
11263                         if ((cp && LONE_CHAR(cp, '0'))
11264                          || (optstr[0] == ':')
11265                         ) {
11266                                 sbuf[0] = c;
11267                                 /*sbuf[1] = '\0'; - already is */
11268                                 setvar0("OPTARG", sbuf);
11269                         } else {
11270                                 fprintf(stderr, "Illegal option -%c\n", c);
11271                                 unsetvar("OPTARG");
11272                         }
11273                         c = '?';
11274                         goto out;
11275                 }
11276                 if (*++q == ':')
11277                         q++;
11278         }
11279
11280         if (*++q == ':') {
11281                 if (*p == '\0' && (p = *optnext) == NULL) {
11282                         /* OPTERR is a bashism */
11283                         const char *cp = lookupvar("OPTERR");
11284                         if ((cp && LONE_CHAR(cp, '0'))
11285                          || (optstr[0] == ':')
11286                         ) {
11287                                 sbuf[0] = c;
11288                                 /*sbuf[1] = '\0'; - already is */
11289                                 setvar0("OPTARG", sbuf);
11290                                 c = ':';
11291                         } else {
11292                                 fprintf(stderr, "No arg for -%c option\n", c);
11293                                 unsetvar("OPTARG");
11294                                 c = '?';
11295                         }
11296                         goto out;
11297                 }
11298
11299                 if (p == *optnext)
11300                         optnext++;
11301                 setvar0("OPTARG", p);
11302                 p = NULL;
11303         } else
11304                 setvar0("OPTARG", nullstr);
11305  out:
11306         ind = optnext - optfirst + 1;
11307         setvar("OPTIND", itoa(ind), VNOFUNC);
11308         sbuf[0] = c;
11309         /*sbuf[1] = '\0'; - already is */
11310         setvar0(optvar, sbuf);
11311
11312         shellparam.optoff = p ? p - *(optnext - 1) : -1;
11313         shellparam.optind = ind;
11314
11315         return done;
11316 }
11317
11318 /*
11319  * The getopts builtin.  Shellparam.optnext points to the next argument
11320  * to be processed.  Shellparam.optptr points to the next character to
11321  * be processed in the current argument.  If shellparam.optnext is NULL,
11322  * then it's the first time getopts has been called.
11323  */
11324 static int FAST_FUNC
11325 getoptscmd(int argc, char **argv)
11326 {
11327         char **optbase;
11328
11329         if (argc < 3)
11330                 ash_msg_and_raise_error("usage: getopts optstring var [arg]");
11331         if (argc == 3) {
11332                 optbase = shellparam.p;
11333                 if ((unsigned)shellparam.optind > shellparam.nparam + 1) {
11334                         shellparam.optind = 1;
11335                         shellparam.optoff = -1;
11336                 }
11337         } else {
11338                 optbase = &argv[3];
11339                 if ((unsigned)shellparam.optind > argc - 2) {
11340                         shellparam.optind = 1;
11341                         shellparam.optoff = -1;
11342                 }
11343         }
11344
11345         return getopts(argv[1], argv[2], optbase);
11346 }
11347 #endif /* ASH_GETOPTS */
11348
11349
11350 /* ============ Shell parser */
11351
11352 struct heredoc {
11353         struct heredoc *next;   /* next here document in list */
11354         union node *here;       /* redirection node */
11355         char *eofmark;          /* string indicating end of input */
11356         smallint striptabs;     /* if set, strip leading tabs */
11357 };
11358
11359 static smallint tokpushback;           /* last token pushed back */
11360 static smallint quoteflag;             /* set if (part of) last token was quoted */
11361 static token_id_t lasttoken;           /* last token read (integer id Txxx) */
11362 static struct heredoc *heredoclist;    /* list of here documents to read */
11363 static char *wordtext;                 /* text of last word returned by readtoken */
11364 static struct nodelist *backquotelist;
11365 static union node *redirnode;
11366 static struct heredoc *heredoc;
11367
11368 static const char *
11369 tokname(char *buf, int tok)
11370 {
11371         if (tok < TSEMI)
11372                 return tokname_array[tok];
11373         sprintf(buf, "\"%s\"", tokname_array[tok]);
11374         return buf;
11375 }
11376
11377 /* raise_error_unexpected_syntax:
11378  * Called when an unexpected token is read during the parse.  The argument
11379  * is the token that is expected, or -1 if more than one type of token can
11380  * occur at this point.
11381  */
11382 static void raise_error_unexpected_syntax(int) NORETURN;
11383 static void
11384 raise_error_unexpected_syntax(int token)
11385 {
11386         char msg[64];
11387         char buf[16];
11388         int l;
11389
11390         l = sprintf(msg, "unexpected %s", tokname(buf, lasttoken));
11391         if (token >= 0)
11392                 sprintf(msg + l, " (expecting %s)", tokname(buf, token));
11393         raise_error_syntax(msg);
11394         /* NOTREACHED */
11395 }
11396
11397 /* parsing is heavily cross-recursive, need these forward decls */
11398 static union node *andor(void);
11399 static union node *pipeline(void);
11400 static union node *parse_command(void);
11401 static void parseheredoc(void);
11402 static int peektoken(void);
11403 static int readtoken(void);
11404
11405 static union node *
11406 list(int nlflag)
11407 {
11408         union node *n1, *n2, *n3;
11409         int tok;
11410
11411         n1 = NULL;
11412         for (;;) {
11413                 switch (peektoken()) {
11414                 case TNL:
11415                         if (!(nlflag & 1))
11416                                 break;
11417                         parseheredoc();
11418                         return n1;
11419
11420                 case TEOF:
11421                         if (!n1 && (nlflag & 1))
11422                                 n1 = NODE_EOF;
11423                         parseheredoc();
11424                         return n1;
11425                 }
11426
11427                 checkkwd = CHKNL | CHKKWD | CHKALIAS;
11428                 if (nlflag == 2 && ((1 << peektoken()) & tokendlist))
11429                         return n1;
11430                 nlflag |= 2;
11431
11432                 n2 = andor();
11433                 tok = readtoken();
11434                 if (tok == TBACKGND) {
11435                         if (n2->type == NPIPE) {
11436                                 n2->npipe.pipe_backgnd = 1;
11437                         } else {
11438                                 if (n2->type != NREDIR) {
11439                                         n3 = stzalloc(sizeof(struct nredir));
11440                                         n3->nredir.n = n2;
11441                                         /*n3->nredir.redirect = NULL; - stzalloc did it */
11442                                         n2 = n3;
11443                                 }
11444                                 n2->type = NBACKGND;
11445                         }
11446                 }
11447                 if (n1 == NULL) {
11448                         n1 = n2;
11449                 } else {
11450                         n3 = stzalloc(sizeof(struct nbinary));
11451                         n3->type = NSEMI;
11452                         n3->nbinary.ch1 = n1;
11453                         n3->nbinary.ch2 = n2;
11454                         n1 = n3;
11455                 }
11456                 switch (tok) {
11457                 case TNL:
11458                 case TEOF:
11459                         tokpushback = 1;
11460                         /* fall through */
11461                 case TBACKGND:
11462                 case TSEMI:
11463                         break;
11464                 default:
11465                         if ((nlflag & 1))
11466                                 raise_error_unexpected_syntax(-1);
11467                         tokpushback = 1;
11468                         return n1;
11469                 }
11470         }
11471 }
11472
11473 static union node *
11474 andor(void)
11475 {
11476         union node *n1, *n2, *n3;
11477         int t;
11478
11479         n1 = pipeline();
11480         for (;;) {
11481                 t = readtoken();
11482                 if (t == TAND) {
11483                         t = NAND;
11484                 } else if (t == TOR) {
11485                         t = NOR;
11486                 } else {
11487                         tokpushback = 1;
11488                         return n1;
11489                 }
11490                 checkkwd = CHKNL | CHKKWD | CHKALIAS;
11491                 n2 = pipeline();
11492                 n3 = stzalloc(sizeof(struct nbinary));
11493                 n3->type = t;
11494                 n3->nbinary.ch1 = n1;
11495                 n3->nbinary.ch2 = n2;
11496                 n1 = n3;
11497         }
11498 }
11499
11500 static union node *
11501 pipeline(void)
11502 {
11503         union node *n1, *n2, *pipenode;
11504         struct nodelist *lp, *prev;
11505         int negate;
11506
11507         negate = 0;
11508         TRACE(("pipeline: entered\n"));
11509         if (readtoken() == TNOT) {
11510                 negate = !negate;
11511                 checkkwd = CHKKWD | CHKALIAS;
11512         } else
11513                 tokpushback = 1;
11514         n1 = parse_command();
11515         if (readtoken() == TPIPE) {
11516                 pipenode = stzalloc(sizeof(struct npipe));
11517                 pipenode->type = NPIPE;
11518                 /*pipenode->npipe.pipe_backgnd = 0; - stzalloc did it */
11519                 lp = stzalloc(sizeof(struct nodelist));
11520                 pipenode->npipe.cmdlist = lp;
11521                 lp->n = n1;
11522                 do {
11523                         prev = lp;
11524                         lp = stzalloc(sizeof(struct nodelist));
11525                         checkkwd = CHKNL | CHKKWD | CHKALIAS;
11526                         lp->n = parse_command();
11527                         prev->next = lp;
11528                 } while (readtoken() == TPIPE);
11529                 lp->next = NULL;
11530                 n1 = pipenode;
11531         }
11532         tokpushback = 1;
11533         if (negate) {
11534                 n2 = stzalloc(sizeof(struct nnot));
11535                 n2->type = NNOT;
11536                 n2->nnot.com = n1;
11537                 return n2;
11538         }
11539         return n1;
11540 }
11541
11542 static union node *
11543 makename(void)
11544 {
11545         union node *n;
11546
11547         n = stzalloc(sizeof(struct narg));
11548         n->type = NARG;
11549         /*n->narg.next = NULL; - stzalloc did it */
11550         n->narg.text = wordtext;
11551         n->narg.backquote = backquotelist;
11552         return n;
11553 }
11554
11555 static void
11556 fixredir(union node *n, const char *text, int err)
11557 {
11558         int fd;
11559
11560         TRACE(("Fix redir %s %d\n", text, err));
11561         if (!err)
11562                 n->ndup.vname = NULL;
11563
11564         fd = bb_strtou(text, NULL, 10);
11565         if (!errno && fd >= 0)
11566                 n->ndup.dupfd = fd;
11567         else if (LONE_DASH(text))
11568                 n->ndup.dupfd = -1;
11569         else {
11570                 if (err)
11571                         raise_error_syntax("bad fd number");
11572                 n->ndup.vname = makename();
11573         }
11574 }
11575
11576 static void
11577 parsefname(void)
11578 {
11579         union node *n = redirnode;
11580
11581         if (n->type == NHERE)
11582                 checkkwd = CHKEOFMARK;
11583         if (readtoken() != TWORD)
11584                 raise_error_unexpected_syntax(-1);
11585         if (n->type == NHERE) {
11586                 struct heredoc *here = heredoc;
11587                 struct heredoc *p;
11588
11589                 if (quoteflag == 0)
11590                         n->type = NXHERE;
11591                 TRACE(("Here document %d\n", n->type));
11592                 rmescapes(wordtext, 0, NULL);
11593                 here->eofmark = wordtext;
11594                 here->next = NULL;
11595                 if (heredoclist == NULL)
11596                         heredoclist = here;
11597                 else {
11598                         for (p = heredoclist; p->next; p = p->next)
11599                                 continue;
11600                         p->next = here;
11601                 }
11602         } else if (n->type == NTOFD || n->type == NFROMFD) {
11603                 fixredir(n, wordtext, 0);
11604         } else {
11605                 n->nfile.fname = makename();
11606         }
11607 }
11608
11609 static union node *
11610 simplecmd(void)
11611 {
11612         union node *args, **app;
11613         union node *n = NULL;
11614         union node *vars, **vpp;
11615         union node **rpp, *redir;
11616         int savecheckkwd;
11617         int savelinno;
11618 #if BASH_TEST2
11619         smallint double_brackets_flag = 0;
11620 #endif
11621         IF_BASH_FUNCTION(smallint function_flag = 0;)
11622
11623         args = NULL;
11624         app = &args;
11625         vars = NULL;
11626         vpp = &vars;
11627         redir = NULL;
11628         rpp = &redir;
11629
11630         savecheckkwd = CHKALIAS;
11631         savelinno = g_parsefile->linno;
11632         for (;;) {
11633                 int t;
11634                 checkkwd = savecheckkwd;
11635                 t = readtoken();
11636                 switch (t) {
11637 #if BASH_FUNCTION
11638                 case TFUNCTION:
11639                         if (peektoken() != TWORD)
11640                                 raise_error_unexpected_syntax(TWORD);
11641                         function_flag = 1;
11642                         break;
11643 #endif
11644 #if BASH_TEST2
11645                 case TAND: /* "&&" */
11646                 case TOR: /* "||" */
11647                         if (!double_brackets_flag) {
11648                                 tokpushback = 1;
11649                                 goto out;
11650                         }
11651                         wordtext = (char *) (t == TAND ? "-a" : "-o");
11652 #endif
11653                 case TWORD:
11654                         n = stzalloc(sizeof(struct narg));
11655                         n->type = NARG;
11656                         /*n->narg.next = NULL; - stzalloc did it */
11657                         n->narg.text = wordtext;
11658 #if BASH_TEST2
11659                         if (strcmp("[[", wordtext) == 0)
11660                                 double_brackets_flag = 1;
11661                         else if (strcmp("]]", wordtext) == 0)
11662                                 double_brackets_flag = 0;
11663 #endif
11664                         n->narg.backquote = backquotelist;
11665                         if (savecheckkwd && isassignment(wordtext)) {
11666                                 *vpp = n;
11667                                 vpp = &n->narg.next;
11668                         } else {
11669                                 *app = n;
11670                                 app = &n->narg.next;
11671                                 savecheckkwd = 0;
11672                         }
11673 #if BASH_FUNCTION
11674                         if (function_flag) {
11675                                 checkkwd = CHKNL | CHKKWD;
11676                                 switch (peektoken()) {
11677                                 case TBEGIN:
11678                                 case TIF:
11679                                 case TCASE:
11680                                 case TUNTIL:
11681                                 case TWHILE:
11682                                 case TFOR:
11683                                         goto do_func;
11684                                 case TLP:
11685                                         function_flag = 0;
11686                                         break;
11687 # if BASH_TEST2
11688                                 case TWORD:
11689                                         if (strcmp("[[", wordtext) == 0)
11690                                                 goto do_func;
11691                                         /* fall through */
11692 # endif
11693                                 default:
11694                                         raise_error_unexpected_syntax(-1);
11695                                 }
11696                         }
11697 #endif
11698                         break;
11699                 case TREDIR:
11700                         *rpp = n = redirnode;
11701                         rpp = &n->nfile.next;
11702                         parsefname();   /* read name of redirection file */
11703                         break;
11704                 case TLP:
11705  IF_BASH_FUNCTION(do_func:)
11706                         if (args && app == &args->narg.next
11707                          && !vars && !redir
11708                         ) {
11709                                 struct builtincmd *bcmd;
11710                                 const char *name;
11711
11712                                 /* We have a function */
11713                                 if (IF_BASH_FUNCTION(!function_flag &&) readtoken() != TRP)
11714                                         raise_error_unexpected_syntax(TRP);
11715                                 name = n->narg.text;
11716                                 if (!goodname(name)
11717                                  || ((bcmd = find_builtin(name)) && IS_BUILTIN_SPECIAL(bcmd))
11718                                 ) {
11719                                         raise_error_syntax("bad function name");
11720                                 }
11721                                 n->type = NDEFUN;
11722                                 checkkwd = CHKNL | CHKKWD | CHKALIAS;
11723                                 n->ndefun.text = n->narg.text;
11724                                 n->ndefun.linno = g_parsefile->linno;
11725                                 n->ndefun.body = parse_command();
11726                                 return n;
11727                         }
11728                         IF_BASH_FUNCTION(function_flag = 0;)
11729                         /* fall through */
11730                 default:
11731                         tokpushback = 1;
11732                         goto out;
11733                 }
11734         }
11735  out:
11736         *app = NULL;
11737         *vpp = NULL;
11738         *rpp = NULL;
11739         n = stzalloc(sizeof(struct ncmd));
11740         if (NCMD != 0)
11741                 n->type = NCMD;
11742         n->ncmd.linno = savelinno;
11743         n->ncmd.args = args;
11744         n->ncmd.assign = vars;
11745         n->ncmd.redirect = redir;
11746         return n;
11747 }
11748
11749 static union node *
11750 parse_command(void)
11751 {
11752         union node *n1, *n2;
11753         union node *ap, **app;
11754         union node *cp, **cpp;
11755         union node *redir, **rpp;
11756         union node **rpp2;
11757         int t;
11758         int savelinno;
11759
11760         redir = NULL;
11761         rpp2 = &redir;
11762
11763         savelinno = g_parsefile->linno;
11764
11765         switch (readtoken()) {
11766         default:
11767                 raise_error_unexpected_syntax(-1);
11768                 /* NOTREACHED */
11769         case TIF:
11770                 n1 = stzalloc(sizeof(struct nif));
11771                 n1->type = NIF;
11772                 n1->nif.test = list(0);
11773                 if (readtoken() != TTHEN)
11774                         raise_error_unexpected_syntax(TTHEN);
11775                 n1->nif.ifpart = list(0);
11776                 n2 = n1;
11777                 while (readtoken() == TELIF) {
11778                         n2->nif.elsepart = stzalloc(sizeof(struct nif));
11779                         n2 = n2->nif.elsepart;
11780                         n2->type = NIF;
11781                         n2->nif.test = list(0);
11782                         if (readtoken() != TTHEN)
11783                                 raise_error_unexpected_syntax(TTHEN);
11784                         n2->nif.ifpart = list(0);
11785                 }
11786                 if (lasttoken == TELSE)
11787                         n2->nif.elsepart = list(0);
11788                 else {
11789                         n2->nif.elsepart = NULL;
11790                         tokpushback = 1;
11791                 }
11792                 t = TFI;
11793                 break;
11794         case TWHILE:
11795         case TUNTIL: {
11796                 int got;
11797                 n1 = stzalloc(sizeof(struct nbinary));
11798                 n1->type = (lasttoken == TWHILE) ? NWHILE : NUNTIL;
11799                 n1->nbinary.ch1 = list(0);
11800                 got = readtoken();
11801                 if (got != TDO) {
11802                         TRACE(("expecting DO got '%s' %s\n", tokname_array[got],
11803                                         got == TWORD ? wordtext : ""));
11804                         raise_error_unexpected_syntax(TDO);
11805                 }
11806                 n1->nbinary.ch2 = list(0);
11807                 t = TDONE;
11808                 break;
11809         }
11810         case TFOR:
11811                 if (readtoken() != TWORD || quoteflag || !goodname(wordtext))
11812                         raise_error_syntax("bad for loop variable");
11813                 n1 = stzalloc(sizeof(struct nfor));
11814                 n1->type = NFOR;
11815                 n1->nfor.linno = savelinno;
11816                 n1->nfor.var = wordtext;
11817                 checkkwd = CHKNL | CHKKWD | CHKALIAS;
11818                 if (readtoken() == TIN) {
11819                         app = &ap;
11820                         while (readtoken() == TWORD) {
11821                                 n2 = stzalloc(sizeof(struct narg));
11822                                 n2->type = NARG;
11823                                 /*n2->narg.next = NULL; - stzalloc did it */
11824                                 n2->narg.text = wordtext;
11825                                 n2->narg.backquote = backquotelist;
11826                                 *app = n2;
11827                                 app = &n2->narg.next;
11828                         }
11829                         *app = NULL;
11830                         n1->nfor.args = ap;
11831                         if (lasttoken != TNL && lasttoken != TSEMI)
11832                                 raise_error_unexpected_syntax(-1);
11833                 } else {
11834                         n2 = stzalloc(sizeof(struct narg));
11835                         n2->type = NARG;
11836                         /*n2->narg.next = NULL; - stzalloc did it */
11837                         n2->narg.text = (char *)dolatstr;
11838                         /*n2->narg.backquote = NULL;*/
11839                         n1->nfor.args = n2;
11840                         /*
11841                          * Newline or semicolon here is optional (but note
11842                          * that the original Bourne shell only allowed NL).
11843                          */
11844                         if (lasttoken != TSEMI)
11845                                 tokpushback = 1;
11846                 }
11847                 checkkwd = CHKNL | CHKKWD | CHKALIAS;
11848                 if (readtoken() != TDO)
11849                         raise_error_unexpected_syntax(TDO);
11850                 n1->nfor.body = list(0);
11851                 t = TDONE;
11852                 break;
11853         case TCASE:
11854                 n1 = stzalloc(sizeof(struct ncase));
11855                 n1->type = NCASE;
11856                 n1->ncase.linno = savelinno;
11857                 if (readtoken() != TWORD)
11858                         raise_error_unexpected_syntax(TWORD);
11859                 n1->ncase.expr = n2 = stzalloc(sizeof(struct narg));
11860                 n2->type = NARG;
11861                 /*n2->narg.next = NULL; - stzalloc did it */
11862                 n2->narg.text = wordtext;
11863                 n2->narg.backquote = backquotelist;
11864                 checkkwd = CHKNL | CHKKWD | CHKALIAS;
11865                 if (readtoken() != TIN)
11866                         raise_error_unexpected_syntax(TIN);
11867                 cpp = &n1->ncase.cases;
11868  next_case:
11869                 checkkwd = CHKNL | CHKKWD;
11870                 t = readtoken();
11871                 while (t != TESAC) {
11872                         if (lasttoken == TLP)
11873                                 readtoken();
11874                         *cpp = cp = stzalloc(sizeof(struct nclist));
11875                         cp->type = NCLIST;
11876                         app = &cp->nclist.pattern;
11877                         for (;;) {
11878                                 *app = ap = stzalloc(sizeof(struct narg));
11879                                 ap->type = NARG;
11880                                 /*ap->narg.next = NULL; - stzalloc did it */
11881                                 ap->narg.text = wordtext;
11882                                 ap->narg.backquote = backquotelist;
11883                                 if (readtoken() != TPIPE)
11884                                         break;
11885                                 app = &ap->narg.next;
11886                                 readtoken();
11887                         }
11888                         //ap->narg.next = NULL;
11889                         if (lasttoken != TRP)
11890                                 raise_error_unexpected_syntax(TRP);
11891                         cp->nclist.body = list(2);
11892
11893                         cpp = &cp->nclist.next;
11894
11895                         checkkwd = CHKNL | CHKKWD;
11896                         t = readtoken();
11897                         if (t != TESAC) {
11898                                 if (t != TENDCASE)
11899                                         raise_error_unexpected_syntax(TENDCASE);
11900                                 goto next_case;
11901                         }
11902                 }
11903                 *cpp = NULL;
11904                 goto redir;
11905         case TLP:
11906                 n1 = stzalloc(sizeof(struct nredir));
11907                 n1->type = NSUBSHELL;
11908                 n1->nredir.linno = savelinno;
11909                 n1->nredir.n = list(0);
11910                 /*n1->nredir.redirect = NULL; - stzalloc did it */
11911                 t = TRP;
11912                 break;
11913         case TBEGIN:
11914                 n1 = list(0);
11915                 t = TEND;
11916                 break;
11917         IF_BASH_FUNCTION(case TFUNCTION:)
11918         case TWORD:
11919         case TREDIR:
11920                 tokpushback = 1;
11921                 return simplecmd();
11922         }
11923
11924         if (readtoken() != t)
11925                 raise_error_unexpected_syntax(t);
11926
11927  redir:
11928         /* Now check for redirection which may follow command */
11929         checkkwd = CHKKWD | CHKALIAS;
11930         rpp = rpp2;
11931         while (readtoken() == TREDIR) {
11932                 *rpp = n2 = redirnode;
11933                 rpp = &n2->nfile.next;
11934                 parsefname();
11935         }
11936         tokpushback = 1;
11937         *rpp = NULL;
11938         if (redir) {
11939                 if (n1->type != NSUBSHELL) {
11940                         n2 = stzalloc(sizeof(struct nredir));
11941                         n2->type = NREDIR;
11942                         n2->nredir.linno = savelinno;
11943                         n2->nredir.n = n1;
11944                         n1 = n2;
11945                 }
11946                 n1->nredir.redirect = redir;
11947         }
11948         return n1;
11949 }
11950
11951 #if BASH_DOLLAR_SQUOTE
11952 static int
11953 decode_dollar_squote(void)
11954 {
11955         static const char C_escapes[] ALIGN1 = "nrbtfav""x\\01234567";
11956         int c, cnt;
11957         char *p;
11958         char buf[4];
11959
11960         c = pgetc();
11961         p = strchr(C_escapes, c);
11962         if (p) {
11963                 buf[0] = c;
11964                 p = buf;
11965                 cnt = 3;
11966                 if ((unsigned char)(c - '0') <= 7) { /* \ooo */
11967                         do {
11968                                 c = pgetc();
11969                                 *++p = c;
11970                         } while ((unsigned char)(c - '0') <= 7 && --cnt);
11971                         pungetc();
11972                 } else if (c == 'x') { /* \xHH */
11973                         do {
11974                                 c = pgetc();
11975                                 *++p = c;
11976                         } while (isxdigit(c) && --cnt);
11977                         pungetc();
11978                         if (cnt == 3) { /* \x but next char is "bad" */
11979                                 c = 'x';
11980                                 goto unrecognized;
11981                         }
11982                 } else { /* simple seq like \\ or \t */
11983                         p++;
11984                 }
11985                 *p = '\0';
11986                 p = buf;
11987                 c = bb_process_escape_sequence((void*)&p);
11988         } else { /* unrecognized "\z": print both chars unless ' or " */
11989                 if (c != '\'' && c != '"') {
11990  unrecognized:
11991                         c |= 0x100; /* "please encode \, then me" */
11992                 }
11993         }
11994         return c;
11995 }
11996 #endif
11997
11998 /* Used by expandstr to get here-doc like behaviour. */
11999 #define FAKEEOFMARK ((char*)(uintptr_t)1)
12000
12001 static ALWAYS_INLINE int
12002 realeofmark(const char *eofmark)
12003 {
12004         return eofmark && eofmark != FAKEEOFMARK;
12005 }
12006
12007 /*
12008  * If eofmark is NULL, read a word or a redirection symbol.  If eofmark
12009  * is not NULL, read a here document.  In the latter case, eofmark is the
12010  * word which marks the end of the document and striptabs is true if
12011  * leading tabs should be stripped from the document.  The argument c
12012  * is the first character of the input token or document.
12013  *
12014  * Because C does not have internal subroutines, I have simulated them
12015  * using goto's to implement the subroutine linkage.  The following macros
12016  * will run code that appears at the end of readtoken1.
12017  */
12018 #define CHECKEND()      {goto checkend; checkend_return:;}
12019 #define PARSEREDIR()    {goto parseredir; parseredir_return:;}
12020 #define PARSESUB()      {goto parsesub; parsesub_return:;}
12021 #define PARSEBACKQOLD() {oldstyle = 1; goto parsebackq; parsebackq_oldreturn:;}
12022 #define PARSEBACKQNEW() {oldstyle = 0; goto parsebackq; parsebackq_newreturn:;}
12023 #define PARSEARITH()    {goto parsearith; parsearith_return:;}
12024 static int
12025 readtoken1(int c, int syntax, char *eofmark, int striptabs)
12026 {
12027         /* NB: syntax parameter fits into smallint */
12028         /* c parameter is an unsigned char or PEOF or PEOA */
12029         char *out;
12030         size_t len;
12031         struct nodelist *bqlist;
12032         smallint quotef;
12033         smallint oldstyle;
12034         smallint pssyntax;   /* we are expanding a prompt string */
12035         IF_BASH_DOLLAR_SQUOTE(smallint bash_dollar_squote = 0;)
12036         /* syntax stack */
12037         struct synstack synbase = { };
12038         struct synstack *synstack = &synbase;
12039
12040 #if ENABLE_ASH_EXPAND_PRMT
12041         pssyntax = (syntax == PSSYNTAX);
12042         if (pssyntax)
12043                 syntax = DQSYNTAX;
12044 #else
12045         pssyntax = 0; /* constant */
12046 #endif
12047         synstack->syntax = syntax;
12048
12049         if (syntax == DQSYNTAX)
12050                 synstack->dblquote = 1;
12051         quotef = 0;
12052         bqlist = NULL;
12053
12054         STARTSTACKSTR(out);
12055  loop:
12056         /* For each line, until end of word */
12057         CHECKEND();     /* set c to PEOF if at end of here document */
12058         for (;;) {      /* until end of line or end of word */
12059                 CHECKSTRSPACE(4, out);  /* permit 4 calls to USTPUTC */
12060                 switch (SIT(c, synstack->syntax)) {
12061                 case CNL:       /* '\n' */
12062                         if (synstack->syntax == BASESYNTAX
12063                          && !synstack->varnest
12064                         ) {
12065                                 goto endword;   /* exit outer loop */
12066                         }
12067                         USTPUTC(c, out);
12068                         nlprompt();
12069                         c = pgetc();
12070                         goto loop;              /* continue outer loop */
12071                 case CWORD:
12072                         USTPUTC(c, out);
12073                         break;
12074                 case CCTL:
12075 #if BASH_DOLLAR_SQUOTE
12076                         if (c == '\\' && bash_dollar_squote) {
12077                                 c = decode_dollar_squote();
12078                                 if (c == '\0') {
12079                                         /* skip $'\000', $'\x00' (like bash) */
12080                                         break;
12081                                 }
12082                                 if (c & 0x100) {
12083                                         /* Unknown escape. Encode as '\z' */
12084                                         c = (unsigned char)c;
12085                                         if (eofmark == NULL || synstack->dblquote)
12086                                                 USTPUTC(CTLESC, out);
12087                                         USTPUTC('\\', out);
12088                                 }
12089                         }
12090 #endif
12091                         if (!eofmark || synstack->dblquote || synstack->varnest)
12092                                 USTPUTC(CTLESC, out);
12093                         USTPUTC(c, out);
12094                         break;
12095                 case CBACK:     /* backslash */
12096                         c = pgetc_without_PEOA();
12097                         if (c == PEOF) {
12098                                 USTPUTC(CTLESC, out);
12099                                 USTPUTC('\\', out);
12100                                 pungetc();
12101                         } else if (c == '\n') {
12102                                 nlprompt();
12103                         } else {
12104                                 if (pssyntax && c == '$') {
12105                                         USTPUTC(CTLESC, out);
12106                                         USTPUTC('\\', out);
12107                                 }
12108                                 /* Backslash is retained if we are in "str"
12109                                  * and next char isn't dquote-special.
12110                                  */
12111                                 if (synstack->dblquote
12112                                  && c != '\\'
12113                                  && c != '`'
12114                                  && c != '$'
12115                                  && (c != '"' || (eofmark != NULL && !synstack->varnest))
12116                                  && (c != '}' || !synstack->varnest)
12117                                 ) {
12118                                         USTPUTC(CTLESC, out); /* protect '\' from glob */
12119                                         USTPUTC('\\', out);
12120                                 }
12121                                 USTPUTC(CTLESC, out);
12122                                 USTPUTC(c, out);
12123                                 quotef = 1;
12124                         }
12125                         break;
12126                 case CSQUOTE:
12127                         synstack->syntax = SQSYNTAX;
12128  quotemark:
12129                         if (eofmark == NULL) {
12130                                 USTPUTC(CTLQUOTEMARK, out);
12131                         }
12132                         break;
12133                 case CDQUOTE:
12134                         synstack->syntax = DQSYNTAX;
12135                         synstack->dblquote = 1;
12136  toggledq:
12137                         if (synstack->varnest)
12138                                 synstack->innerdq ^= 1;
12139                         goto quotemark;
12140                 case CENDQUOTE:
12141                         IF_BASH_DOLLAR_SQUOTE(bash_dollar_squote = 0;)
12142                         if (eofmark != NULL && synstack->varnest == 0) {
12143                                 USTPUTC(c, out);
12144                                 break;
12145                         }
12146
12147                         if (synstack->dqvarnest == 0) {
12148                                 synstack->syntax = BASESYNTAX;
12149                                 synstack->dblquote = 0;
12150                         }
12151
12152                         quotef = 1;
12153
12154                         if (c == '"')
12155                                 goto toggledq;
12156
12157                         goto quotemark;
12158                 case CVAR:      /* '$' */
12159                         PARSESUB();             /* parse substitution */
12160                         break;
12161                 case CENDVAR:   /* '}' */
12162                         if (!synstack->innerdq && synstack->varnest > 0) {
12163                                 if (!--synstack->varnest && synstack->varpushed)
12164                                         synstack_pop(&synstack);
12165                                 else if (synstack->dqvarnest > 0)
12166                                         synstack->dqvarnest--;
12167                                 c = CTLENDVAR;
12168                         }
12169                         USTPUTC(c, out);
12170                         break;
12171 #if ENABLE_FEATURE_SH_MATH
12172                 case CLP:       /* '(' in arithmetic */
12173                         synstack->parenlevel++;
12174                         USTPUTC(c, out);
12175                         break;
12176                 case CRP:       /* ')' in arithmetic */
12177                         if (synstack->parenlevel > 0) {
12178                                 synstack->parenlevel--;
12179                         } else {
12180                                 if (pgetc_eatbnl() == ')') {
12181                                         c = CTLENDARI;
12182                                         synstack_pop(&synstack);
12183                                 } else {
12184                                         /*
12185                                          * unbalanced parens
12186                                          * (don't 2nd guess - no error)
12187                                          */
12188                                         pungetc();
12189                                 }
12190                         }
12191                         USTPUTC(c, out);
12192                         break;
12193 #endif
12194                 case CBQUOTE:   /* '`' */
12195                         if (checkkwd & CHKEOFMARK) {
12196                                 quotef = 1;
12197                                 USTPUTC('`', out);
12198                                 break;
12199                         }
12200
12201                         PARSEBACKQOLD();
12202                         break;
12203                 case CENDFILE:
12204                         goto endword;           /* exit outer loop */
12205                 case CIGN:
12206                         break;
12207                 default:
12208                         if (synstack->varnest == 0) {
12209 #if BASH_REDIR_OUTPUT
12210                                 if (c == '&') {
12211 //Can't call pgetc_eatbnl() here, this requires three-deep pungetc()
12212                                         if (pgetc() == '>')
12213                                                 c = 0x100 + '>'; /* flag &> */
12214                                         pungetc();
12215                                 }
12216 #endif
12217                                 goto endword;   /* exit outer loop */
12218                         }
12219                         IF_ASH_ALIAS(if (c != PEOA))
12220                                 USTPUTC(c, out);
12221                 }
12222                 c = pgetc();
12223         } /* for (;;) */
12224  endword:
12225
12226 #if ENABLE_FEATURE_SH_MATH
12227         if (synstack->syntax == ARISYNTAX)
12228                 raise_error_syntax("missing '))'");
12229 #endif
12230         if (synstack->syntax != BASESYNTAX && eofmark == NULL)
12231                 raise_error_syntax("unterminated quoted string");
12232         if (synstack->varnest != 0) {
12233                 /* { */
12234                 raise_error_syntax("missing '}'");
12235         }
12236         USTPUTC('\0', out);
12237         len = out - (char *)stackblock();
12238         out = stackblock();
12239         if (eofmark == NULL) {
12240                 if ((c == '>' || c == '<' IF_BASH_REDIR_OUTPUT( || c == 0x100 + '>'))
12241                  && quotef == 0
12242                 ) {
12243                         if (isdigit_str9(out)) {
12244                                 PARSEREDIR(); /* passed as params: out, c */
12245                                 lasttoken = TREDIR;
12246                                 return lasttoken;
12247                         }
12248                         /* else: non-number X seen, interpret it
12249                          * as "NNNX>file" = "NNNX >file" */
12250                 }
12251                 pungetc();
12252         }
12253         quoteflag = quotef;
12254         backquotelist = bqlist;
12255         grabstackblock(len);
12256         wordtext = out;
12257         lasttoken = TWORD;
12258         return lasttoken;
12259 /* end of readtoken routine */
12260
12261 /*
12262  * Check to see whether we are at the end of the here document.  When this
12263  * is called, c is set to the first character of the next input line.  If
12264  * we are at the end of the here document, this routine sets the c to PEOF.
12265  */
12266 checkend: {
12267         if (realeofmark(eofmark)) {
12268                 int markloc;
12269                 char *p;
12270
12271 #if ENABLE_ASH_ALIAS
12272                 if (c == PEOA)
12273                         c = pgetc_without_PEOA();
12274 #endif
12275                 if (striptabs) {
12276                         while (c == '\t') {
12277                                 c = pgetc_without_PEOA();
12278                         }
12279                 }
12280
12281                 markloc = out - (char *)stackblock();
12282                 for (p = eofmark; STPUTC(c, out), *p; p++) {
12283                         if (c != *p)
12284                                 goto more_heredoc;
12285
12286                         c = pgetc_without_PEOA();
12287                 }
12288
12289                 if (c == '\n' || c == PEOF) {
12290                         c = PEOF;
12291                         g_parsefile->linno++;
12292                         needprompt = doprompt;
12293                 } else {
12294                         int len_here;
12295
12296  more_heredoc:
12297                         p = (char *)stackblock() + markloc + 1;
12298                         len_here = out - p;
12299
12300                         if (len_here) {
12301                                 len_here -= (c >= PEOF);
12302                                 c = p[-1];
12303
12304                                 if (len_here) {
12305                                         char *str;
12306
12307                                         str = alloca(len_here + 1);
12308                                         *(char *)mempcpy(str, p, len_here) = '\0';
12309
12310                                         pushstring(str, NULL);
12311                                 }
12312                         }
12313                 }
12314
12315                 STADJUST((char *)stackblock() + markloc - out, out);
12316         }
12317         goto checkend_return;
12318 }
12319
12320 /*
12321  * Parse a redirection operator.  The variable "out" points to a string
12322  * specifying the fd to be redirected.  The variable "c" contains the
12323  * first character of the redirection operator.
12324  */
12325 parseredir: {
12326         /* out is already checked to be a valid number or "" */
12327         int fd = (*out == '\0' ? -1 : atoi(out));
12328         union node *np;
12329
12330         np = stzalloc(sizeof(struct nfile));
12331         if (c == '>') {
12332                 np->nfile.fd = 1;
12333                 c = pgetc_eatbnl();
12334                 if (c == '>')
12335                         np->type = NAPPEND;
12336                 else if (c == '|')
12337                         np->type = NCLOBBER;
12338                 else if (c == '&')
12339                         np->type = NTOFD;
12340                         /* it also can be NTO2 (>&file), but we can't figure it out yet */
12341                 else {
12342                         np->type = NTO;
12343                         pungetc();
12344                 }
12345         }
12346 #if BASH_REDIR_OUTPUT
12347         else if (c == 0x100 + '>') { /* this flags &> redirection */
12348                 np->nfile.fd = 1;
12349                 pgetc(); /* this is '>', no need to check */
12350                 np->type = NTO2;
12351         }
12352 #endif
12353         else { /* c == '<' */
12354                 /*np->nfile.fd = 0; - stzalloc did it */
12355                 c = pgetc_eatbnl();
12356                 switch (c) {
12357                 case '<':
12358                         if (sizeof(struct nfile) != sizeof(struct nhere)) {
12359                                 np = stzalloc(sizeof(struct nhere));
12360                                 /*np->nfile.fd = 0; - stzalloc did it */
12361                         }
12362                         np->type = NHERE;
12363                         heredoc = stzalloc(sizeof(struct heredoc));
12364                         heredoc->here = np;
12365                         c = pgetc_eatbnl();
12366                         if (c == '-') {
12367                                 heredoc->striptabs = 1;
12368                         } else {
12369                                 /*heredoc->striptabs = 0; - stzalloc did it */
12370                                 pungetc();
12371                         }
12372                         break;
12373
12374                 case '&':
12375                         np->type = NFROMFD;
12376                         break;
12377
12378                 case '>':
12379                         np->type = NFROMTO;
12380                         break;
12381
12382                 default:
12383                         np->type = NFROM;
12384                         pungetc();
12385                         break;
12386                 }
12387         }
12388         if (fd >= 0)
12389                 np->nfile.fd = fd;
12390         redirnode = np;
12391         goto parseredir_return;
12392 }
12393
12394 /*
12395  * Parse a substitution.  At this point, we have read the dollar sign
12396  * and nothing else.
12397  */
12398
12399 /* is_special(c) evaluates to 1 for c in "!#$*-0123456789?@"; 0 otherwise
12400  * (assuming ascii char codes, as the original implementation did) */
12401 #define is_special(c) \
12402         (((unsigned)(c) - 33 < 32) \
12403                         && ((0xc1ff920dU >> ((unsigned)(c) - 33)) & 1))
12404 parsesub: {
12405         unsigned char subtype;
12406         int typeloc;
12407
12408         c = pgetc_eatbnl();
12409         if ((checkkwd & CHKEOFMARK)
12410          || c > 255 /* PEOA or PEOF */
12411          || (c != '(' && c != '{' && !is_name(c) && !is_special(c))
12412         ) {
12413 #if BASH_DOLLAR_SQUOTE
12414                 if (synstack->syntax != DQSYNTAX && c == '\'')
12415                         bash_dollar_squote = 1;
12416                 else
12417 #endif
12418                         USTPUTC('$', out);
12419                 pungetc();
12420         } else if (c == '(') {
12421                 /* $(command) or $((arith)) */
12422                 if (pgetc_eatbnl() == '(') {
12423 #if ENABLE_FEATURE_SH_MATH
12424                         PARSEARITH();
12425 #else
12426                         raise_error_syntax("support for $((arith)) is disabled");
12427 #endif
12428                 } else {
12429                         pungetc();
12430                         PARSEBACKQNEW();
12431                 }
12432         } else {
12433                 /* $VAR, $<specialchar>, ${...}, or PEOA/PEOF */
12434                 smalluint newsyn = synstack->syntax;
12435
12436                 USTPUTC(CTLVAR, out);
12437                 typeloc = out - (char *)stackblock();
12438                 STADJUST(1, out);
12439                 subtype = VSNORMAL;
12440                 if (c == '{') {
12441                         c = pgetc_eatbnl();
12442                         subtype = 0;
12443                 }
12444  varname:
12445                 if (is_name(c)) {
12446                         /* $[{[#]]NAME[}] */
12447                         do {
12448                                 STPUTC(c, out);
12449                                 c = pgetc_eatbnl();
12450                         } while (is_in_name(c));
12451                 } else if (isdigit(c)) {
12452                         /* $[{[#]]NUM[}] */
12453                         do {
12454                                 STPUTC(c, out);
12455                                 c = pgetc_eatbnl();
12456                         } while (isdigit(c));
12457                 } else if (c != '}') {
12458                         /* $[{[#]]<specialchar>[}] */
12459                         int cc = c;
12460
12461                         c = pgetc_eatbnl();
12462                         if (!subtype && cc == '#') {
12463                                 subtype = VSLENGTH;
12464                                 if (c == '_' || isalnum(c))
12465                                         goto varname;
12466                                 cc = c;
12467                                 c = pgetc_eatbnl();
12468                                 if (cc == '}' || c != '}') {
12469                                         pungetc();
12470                                         subtype = 0;
12471                                         c = cc;
12472                                         cc = '#';
12473                                 }
12474                         }
12475
12476                         if (!is_special(cc)) {
12477                                 if (subtype == VSLENGTH)
12478                                         subtype = 0;
12479                                 goto badsub;
12480                         }
12481
12482                         USTPUTC(cc, out);
12483                 } else
12484                         goto badsub;
12485
12486                 if (c != '}' && subtype == VSLENGTH) {
12487                         /* ${#VAR didn't end with } */
12488                         goto badsub;
12489                 }
12490
12491                 if (subtype == 0) {
12492                         static const char types[] ALIGN1 = "}-+?=";
12493                         /* ${VAR...} but not $VAR or ${#VAR} */
12494                         /* c == first char after VAR */
12495                         int cc = c;
12496
12497                         switch (c) {
12498                         case ':':
12499                                 c = pgetc_eatbnl();
12500 #if BASH_SUBSTR
12501                                 /* This check is only needed to not misinterpret
12502                                  * ${VAR:-WORD}, ${VAR:+WORD}, ${VAR:=WORD}, ${VAR:?WORD}
12503                                  * constructs.
12504                                  */
12505                                 if (!strchr(types, c)) {
12506                                         subtype = VSSUBSTR;
12507                                         pungetc();
12508                                         break; /* "goto badsub" is bigger (!) */
12509                                 }
12510 #endif
12511                                 subtype = VSNUL;
12512                                 /*FALLTHROUGH*/
12513                         default: {
12514                                 const char *p = strchr(types, c);
12515                                 if (p == NULL)
12516                                         break;
12517                                 subtype |= p - types + VSNORMAL;
12518                                 break;
12519                         }
12520                         case '%':
12521                         case '#':
12522                                 subtype = (c == '#' ? VSTRIMLEFT : VSTRIMRIGHT);
12523                                 c = pgetc_eatbnl();
12524                                 if (c == cc)
12525                                         subtype++;
12526                                 else
12527                                         pungetc();
12528
12529                                 newsyn = BASESYNTAX;
12530                                 break;
12531 #if BASH_PATTERN_SUBST
12532                         case '/':
12533                                 /* ${v/[/]pattern/repl} */
12534 //TODO: encode pattern and repl separately.
12535 // Currently cases like: v=1;echo ${v/$((1/1))/ONE}
12536 // are broken (should print "ONE")
12537                                 subtype = VSREPLACE;
12538                                 newsyn = BASESYNTAX;
12539                                 c = pgetc_eatbnl();
12540                                 if (c != '/')
12541                                         goto badsub;
12542                                 subtype++; /* VSREPLACEALL */
12543                                 break;
12544 #endif
12545                         }
12546                 } else {
12547  badsub:
12548                         pungetc();
12549                 }
12550
12551                 if (newsyn == ARISYNTAX)
12552                         newsyn = DQSYNTAX;
12553
12554                 if ((newsyn != synstack->syntax || synstack->innerdq)
12555                  && subtype != VSNORMAL
12556                 ) {
12557                         synstack_push(&synstack,
12558                                 synstack->prev ?: alloca(sizeof(*synstack)),
12559                                 newsyn);
12560
12561                         synstack->varpushed = 1;
12562                         synstack->dblquote = newsyn != BASESYNTAX;
12563                 }
12564
12565                 ((unsigned char *)stackblock())[typeloc] = subtype;
12566                 if (subtype != VSNORMAL) {
12567                         synstack->varnest++;
12568                         if (synstack->dblquote)
12569                                 synstack->dqvarnest++;
12570                 }
12571                 STPUTC('=', out);
12572         }
12573         goto parsesub_return;
12574 }
12575
12576 /*
12577  * Called to parse command substitutions.  Newstyle is set if the command
12578  * is enclosed inside $(...); nlpp is a pointer to the head of the linked
12579  * list of commands (passed by reference), and savelen is the number of
12580  * characters on the top of the stack which must be preserved.
12581  */
12582 parsebackq: {
12583         struct nodelist **nlpp;
12584         union node *n;
12585         char *str;
12586         size_t savelen;
12587         smallint saveprompt = 0;
12588
12589         str = NULL;
12590         savelen = out - (char *)stackblock();
12591         if (savelen > 0) {
12592                 /*
12593                  * FIXME: this can allocate very large block on stack and SEGV.
12594                  * Example:
12595                  * echo "..<100kbytes>..`true` $(true) `true` ..."
12596                  * allocates 100kb for every command subst. With about
12597                  * a hundred command substitutions stack overflows.
12598                  * With larger prepended string, SEGV happens sooner.
12599                  */
12600                 str = alloca(savelen);
12601                 memcpy(str, stackblock(), savelen);
12602         }
12603
12604         if (oldstyle) {
12605                 /* We must read until the closing backquote, giving special
12606                  * treatment to some slashes, and then push the string and
12607                  * reread it as input, interpreting it normally.
12608                  */
12609                 char *pout;
12610                 size_t psavelen;
12611                 char *pstr;
12612
12613                 STARTSTACKSTR(pout);
12614                 for (;;) {
12615                         int pc;
12616
12617                         setprompt_if(needprompt, 2);
12618                         pc = pgetc_eatbnl();
12619                         switch (pc) {
12620                         case '`':
12621                                 goto done;
12622
12623                         case '\\':
12624                                 pc = pgetc(); /* or pgetc_eatbnl()? why (example)? */
12625                                 if (pc != '\\' && pc != '`' && pc != '$'
12626                                  && (!synstack->dblquote || pc != '"')
12627                                 ) {
12628                                         STPUTC('\\', pout);
12629                                 }
12630                                 if (pc <= 255 /* not PEOA or PEOF */) {
12631                                         break;
12632                                 }
12633                                 /* fall through */
12634
12635                         case PEOF:
12636                         IF_ASH_ALIAS(case PEOA:)
12637                                 raise_error_syntax("EOF in backquote substitution");
12638
12639                         case '\n':
12640                                 nlnoprompt();
12641                                 break;
12642
12643                         default:
12644                                 break;
12645                         }
12646                         STPUTC(pc, pout);
12647                 }
12648  done:
12649                 STPUTC('\0', pout);
12650                 psavelen = pout - (char *)stackblock();
12651                 if (psavelen > 0) {
12652                         pstr = grabstackstr(pout);
12653                         setinputstring(pstr);
12654                 }
12655         }
12656         nlpp = &bqlist;
12657         while (*nlpp)
12658                 nlpp = &(*nlpp)->next;
12659         *nlpp = stzalloc(sizeof(**nlpp));
12660         /* (*nlpp)->next = NULL; - stzalloc did it */
12661
12662         if (oldstyle) {
12663                 saveprompt = doprompt;
12664                 doprompt = 0;
12665         }
12666
12667         n = list(2);
12668
12669         if (oldstyle)
12670                 doprompt = saveprompt;
12671         else if (readtoken() != TRP)
12672                 raise_error_unexpected_syntax(TRP);
12673
12674         (*nlpp)->n = n;
12675         if (oldstyle) {
12676                 /*
12677                  * Start reading from old file again, ignoring any pushed back
12678                  * tokens left from the backquote parsing
12679                  */
12680                 popfile();
12681                 tokpushback = 0;
12682         }
12683         while (stackblocksize() <= savelen)
12684                 growstackblock();
12685         STARTSTACKSTR(out);
12686         if (str) {
12687                 memcpy(out, str, savelen);
12688                 STADJUST(savelen, out);
12689         }
12690         USTPUTC(CTLBACKQ, out);
12691         if (oldstyle)
12692                 goto parsebackq_oldreturn;
12693         goto parsebackq_newreturn;
12694 }
12695
12696 #if ENABLE_FEATURE_SH_MATH
12697 /*
12698  * Parse an arithmetic expansion (indicate start of one and set state)
12699  */
12700 parsearith: {
12701
12702         synstack_push(&synstack,
12703                         synstack->prev ?: alloca(sizeof(*synstack)),
12704                         ARISYNTAX);
12705         synstack->dblquote = 1;
12706         USTPUTC(CTLARI, out);
12707         goto parsearith_return;
12708 }
12709 #endif
12710 } /* end of readtoken */
12711
12712 /*
12713  * Read the next input token.
12714  * If the token is a word, we set backquotelist to the list of cmds in
12715  *      backquotes.  We set quoteflag to true if any part of the word was
12716  *      quoted.
12717  * If the token is TREDIR, then we set redirnode to a structure containing
12718  *      the redirection.
12719  *
12720  * [Change comment:  here documents and internal procedures]
12721  * [Readtoken shouldn't have any arguments.  Perhaps we should make the
12722  *  word parsing code into a separate routine.  In this case, readtoken
12723  *  doesn't need to have any internal procedures, but parseword does.
12724  *  We could also make parseoperator in essence the main routine, and
12725  *  have parseword (readtoken1?) handle both words and redirection.]
12726  */
12727 #define NEW_xxreadtoken
12728 #ifdef NEW_xxreadtoken
12729 /* singles must be first! */
12730 static const char xxreadtoken_chars[7] ALIGN1 = {
12731         '\n', '(', ')', /* singles */
12732         '&', '|', ';',  /* doubles */
12733         0
12734 };
12735
12736 #define xxreadtoken_singles 3
12737 #define xxreadtoken_doubles 3
12738
12739 static const char xxreadtoken_tokens[] ALIGN1 = {
12740         TNL, TLP, TRP,          /* only single occurrence allowed */
12741         TBACKGND, TPIPE, TSEMI, /* if single occurrence */
12742         TEOF,                   /* corresponds to trailing nul */
12743         TAND, TOR, TENDCASE     /* if double occurrence */
12744 };
12745
12746 static int
12747 xxreadtoken(void)
12748 {
12749         int c;
12750
12751         if (tokpushback) {
12752                 tokpushback = 0;
12753                 return lasttoken;
12754         }
12755         setprompt_if(needprompt, 2);
12756         for (;;) {                      /* until token or start of word found */
12757                 c = pgetc_eatbnl();
12758                 if (c == ' ' || c == '\t' IF_ASH_ALIAS( || c == PEOA))
12759                         continue;
12760
12761                 if (c == '#') {
12762                         while ((c = pgetc()) != '\n' && c != PEOF)
12763                                 continue;
12764                         pungetc();
12765                 } else if (c == '\\') {
12766                         break; /* return readtoken1(...) */
12767                 } else {
12768                         const char *p;
12769
12770                         p = xxreadtoken_chars + sizeof(xxreadtoken_chars) - 1;
12771                         if (c != PEOF) {
12772                                 if (c == '\n') {
12773                                         nlnoprompt();
12774                                 }
12775
12776                                 p = strchr(xxreadtoken_chars, c);
12777                                 if (p == NULL)
12778                                         break; /* return readtoken1(...) */
12779
12780                                 if ((int)(p - xxreadtoken_chars) >= xxreadtoken_singles) {
12781                                         int cc = pgetc_eatbnl();
12782                                         if (cc == c) {    /* double occurrence? */
12783                                                 p += xxreadtoken_doubles + 1;
12784                                         } else {
12785                                                 pungetc();
12786 #if BASH_REDIR_OUTPUT
12787                                                 if (c == '&' && cc == '>') /* &> */
12788                                                         break; /* return readtoken1(...) */
12789 #endif
12790                                         }
12791                                 }
12792                         }
12793                         lasttoken = xxreadtoken_tokens[p - xxreadtoken_chars];
12794                         return lasttoken;
12795                 }
12796         } /* for (;;) */
12797
12798         return readtoken1(c, BASESYNTAX, (char *) NULL, 0);
12799 }
12800 #else /* old xxreadtoken */
12801 #define RETURN(token)   return lasttoken = token
12802 static int
12803 xxreadtoken(void)
12804 {
12805         int c;
12806
12807         if (tokpushback) {
12808                 tokpushback = 0;
12809                 return lasttoken;
12810         }
12811         setprompt_if(needprompt, 2);
12812         for (;;) {      /* until token or start of word found */
12813                 c = pgetc_eatbnl();
12814                 switch (c) {
12815                 case ' ': case '\t':
12816                 IF_ASH_ALIAS(case PEOA:)
12817                         continue;
12818                 case '#':
12819                         while ((c = pgetc()) != '\n' && c != PEOF)
12820                                 continue;
12821                         pungetc();
12822                         continue;
12823                 case '\n':
12824                         nlnoprompt();
12825                         RETURN(TNL);
12826                 case PEOF:
12827                         RETURN(TEOF);
12828                 case '&':
12829                         if (pgetc_eatbnl() == '&')
12830                                 RETURN(TAND);
12831                         pungetc();
12832                         RETURN(TBACKGND);
12833                 case '|':
12834                         if (pgetc_eatbnl() == '|')
12835                                 RETURN(TOR);
12836                         pungetc();
12837                         RETURN(TPIPE);
12838                 case ';':
12839                         if (pgetc_eatbnl() == ';')
12840                                 RETURN(TENDCASE);
12841                         pungetc();
12842                         RETURN(TSEMI);
12843                 case '(':
12844                         RETURN(TLP);
12845                 case ')':
12846                         RETURN(TRP);
12847                 }
12848                 break;
12849         }
12850         return readtoken1(c, BASESYNTAX, (char *)NULL, 0);
12851 #undef RETURN
12852 }
12853 #endif /* old xxreadtoken */
12854
12855 static int
12856 readtoken(void)
12857 {
12858         int t;
12859         int kwd = checkkwd;
12860 #if DEBUG
12861         smallint alreadyseen = tokpushback;
12862 #endif
12863
12864 #if ENABLE_ASH_ALIAS
12865  top:
12866 #endif
12867
12868         t = xxreadtoken();
12869
12870         /*
12871          * eat newlines
12872          */
12873         if (kwd & CHKNL) {
12874                 while (t == TNL) {
12875                         parseheredoc();
12876                         t = xxreadtoken();
12877                 }
12878         }
12879
12880         if (t != TWORD || quoteflag) {
12881                 goto out;
12882         }
12883
12884         /*
12885          * check for keywords
12886          */
12887         if (kwd & CHKKWD) {
12888                 const char *const *pp;
12889
12890                 pp = findkwd(wordtext);
12891                 if (pp) {
12892                         lasttoken = t = pp - tokname_array;
12893                         TRACE(("keyword '%s' recognized\n", tokname_array[t]));
12894                         goto out;
12895                 }
12896         }
12897
12898         if (checkkwd & CHKALIAS) {
12899 #if ENABLE_ASH_ALIAS
12900                 struct alias *ap;
12901                 ap = lookupalias(wordtext, 1);
12902                 if (ap != NULL) {
12903                         if (*ap->val) {
12904                                 pushstring(ap->val, ap);
12905                         }
12906                         goto top;
12907                 }
12908 #endif
12909         }
12910  out:
12911         checkkwd = 0;
12912 #if DEBUG
12913         if (!alreadyseen)
12914                 TRACE(("token '%s' %s\n", tokname_array[t], t == TWORD ? wordtext : ""));
12915         else
12916                 TRACE(("reread token '%s' %s\n", tokname_array[t], t == TWORD ? wordtext : ""));
12917 #endif
12918         return t;
12919 }
12920
12921 static int
12922 peektoken(void)
12923 {
12924         int t;
12925
12926         t = readtoken();
12927         tokpushback = 1;
12928         return t;
12929 }
12930
12931 /*
12932  * Read and parse a command.  Returns NODE_EOF on end of file.
12933  * (NULL is a valid parse tree indicating a blank line.)
12934  */
12935 static union node *
12936 parsecmd(int interact)
12937 {
12938         tokpushback = 0;
12939         checkkwd = 0;
12940         heredoclist = 0;
12941         doprompt = interact;
12942         setprompt_if(doprompt, doprompt);
12943         needprompt = 0;
12944         return list(1);
12945 }
12946
12947 /*
12948  * Input any here documents.
12949  */
12950 static void
12951 parseheredoc(void)
12952 {
12953         struct heredoc *here;
12954         union node *n;
12955
12956         here = heredoclist;
12957         heredoclist = NULL;
12958
12959         while (here) {
12960                 setprompt_if(needprompt, 2);
12961                 readtoken1(pgetc(), here->here->type == NHERE ? SQSYNTAX : DQSYNTAX,
12962                                 here->eofmark, here->striptabs);
12963                 n = stzalloc(sizeof(struct narg));
12964                 n->narg.type = NARG;
12965                 /*n->narg.next = NULL; - stzalloc did it */
12966                 n->narg.text = wordtext;
12967                 n->narg.backquote = backquotelist;
12968                 here->here->nhere.doc = n;
12969                 here = here->next;
12970         }
12971 }
12972
12973
12974 static const char *
12975 expandstr(const char *ps, int syntax_type)
12976 {
12977         union node n;
12978         int saveprompt;
12979
12980         /* XXX Fix (char *) cast. */
12981         setinputstring((char *)ps);
12982
12983         saveprompt = doprompt;
12984         doprompt = 0;
12985
12986         /* readtoken1() might die horribly.
12987          * Try a prompt with syntactically wrong command:
12988          * PS1='$(date "+%H:%M:%S) > '
12989          */
12990         {
12991                 volatile int saveint;
12992                 struct jmploc *volatile savehandler = exception_handler;
12993                 struct jmploc jmploc;
12994                 SAVE_INT(saveint);
12995                 if (setjmp(jmploc.loc) == 0) {
12996                         exception_handler = &jmploc;
12997                         readtoken1(pgetc(), syntax_type, FAKEEOFMARK, 0);
12998                 }
12999                 exception_handler = savehandler;
13000                 RESTORE_INT(saveint);
13001         }
13002
13003         doprompt = saveprompt;
13004
13005         popfile();
13006
13007         n.narg.type = NARG;
13008         n.narg.next = NULL;
13009         n.narg.text = wordtext;
13010         n.narg.backquote = backquotelist;
13011
13012         expandarg(&n, NULL, EXP_QUOTED);
13013         return stackblock();
13014 }
13015
13016 static inline int
13017 parser_eof(void)
13018 {
13019         return tokpushback && lasttoken == TEOF;
13020 }
13021
13022 /*
13023  * Execute a command or commands contained in a string.
13024  */
13025 static int
13026 evalstring(char *s, int flags)
13027 {
13028         struct jmploc *volatile savehandler;
13029         struct jmploc jmploc;
13030         int ex;
13031
13032         union node *n;
13033         struct stackmark smark;
13034         int status;
13035
13036         s = sstrdup(s);
13037         setinputstring(s);
13038         setstackmark(&smark);
13039
13040         status = 0;
13041         /* On exception inside execution loop, we must popfile().
13042          * Try interactively:
13043          *      readonly a=a
13044          *      command eval "a=b"  # throws "is read only" error
13045          * "command BLTIN" is not supposed to abort (even in non-interactive use).
13046          * But if we skip popfile(), we hit EOF in eval's string, and exit.
13047          */
13048         savehandler = exception_handler;
13049         ex = setjmp(jmploc.loc);
13050         if (ex)
13051                 goto out;
13052         exception_handler = &jmploc;
13053
13054         while ((n = parsecmd(0)) != NODE_EOF) {
13055                 int i;
13056
13057                 i = evaltree(n, flags & ~(parser_eof() ? 0 : EV_EXIT));
13058                 if (n)
13059                         status = i;
13060                 popstackmark(&smark);
13061                 if (evalskip)
13062                         break;
13063         }
13064  out:
13065         popstackmark(&smark);
13066         popfile();
13067         stunalloc(s);
13068
13069         exception_handler = savehandler;
13070         if (ex)
13071                 longjmp(exception_handler->loc, ex);
13072
13073         return status;
13074 }
13075
13076 /*
13077  * The eval command.
13078  */
13079 static int FAST_FUNC
13080 evalcmd(int argc UNUSED_PARAM, char **argv, int flags)
13081 {
13082         char *p;
13083         char *concat;
13084
13085         if (argv[1]) {
13086                 p = argv[1];
13087                 argv += 2;
13088                 if (argv[0]) {
13089                         STARTSTACKSTR(concat);
13090                         for (;;) {
13091                                 concat = stack_putstr(p, concat);
13092                                 p = *argv++;
13093                                 if (p == NULL)
13094                                         break;
13095                                 STPUTC(' ', concat);
13096                         }
13097                         STPUTC('\0', concat);
13098                         p = grabstackstr(concat);
13099                 }
13100                 return evalstring(p, flags & EV_TESTED);
13101         }
13102         return 0;
13103 }
13104
13105 /*
13106  * Read and execute commands.
13107  * "Top" is nonzero for the top level command loop;
13108  * it turns on prompting if the shell is interactive.
13109  */
13110 static int
13111 cmdloop(int top)
13112 {
13113         union node *n;
13114         struct stackmark smark;
13115         int inter;
13116         int status = 0;
13117         int numeof = 0;
13118
13119         TRACE(("cmdloop(%d) called\n", top));
13120         for (;;) {
13121                 int skip;
13122
13123                 setstackmark(&smark);
13124 #if JOBS
13125                 if (doing_jobctl)
13126                         showjobs(SHOW_CHANGED|SHOW_STDERR);
13127 #endif
13128                 inter = 0;
13129                 if (iflag && top) {
13130                         inter++;
13131                         chkmail();
13132                 }
13133                 n = parsecmd(inter);
13134 #if DEBUG
13135                 if (DEBUG > 2 && debug && (n != NODE_EOF))
13136                         showtree(n);
13137 #endif
13138                 if (n == NODE_EOF) {
13139                         if (!top || numeof >= 50)
13140                                 break;
13141                         if (!stoppedjobs()) {
13142                                 if (!Iflag)
13143                                         break;
13144                                 out2str("\nUse \"exit\" to leave shell.\n");
13145                         }
13146                         numeof++;
13147                 } else if (nflag == 0) {
13148                         int i;
13149
13150                         /* job_warning can only be 2,1,0. Here 2->1, 1/0->0 */
13151                         job_warning >>= 1;
13152                         numeof = 0;
13153                         i = evaltree(n, 0);
13154                         if (n)
13155                                 status = i;
13156                 }
13157                 popstackmark(&smark);
13158                 skip = evalskip;
13159
13160                 if (skip) {
13161                         evalskip &= ~SKIPFUNC;
13162                         break;
13163                 }
13164         }
13165         return status;
13166 }
13167
13168 /*
13169  * Take commands from a file.  To be compatible we should do a path
13170  * search for the file, which is necessary to find sub-commands.
13171  */
13172 static char *
13173 find_dot_file(char *name)
13174 {
13175         char *fullname;
13176         const char *path = pathval();
13177         struct stat statb;
13178
13179         /* don't try this for absolute or relative paths */
13180         if (strchr(name, '/'))
13181                 return name;
13182
13183         while ((fullname = path_advance(&path, name)) != NULL) {
13184                 if ((stat(fullname, &statb) == 0) && S_ISREG(statb.st_mode)) {
13185                         /*
13186                          * Don't bother freeing here, since it will
13187                          * be freed by the caller.
13188                          */
13189                         return fullname;
13190                 }
13191                 if (fullname != name)
13192                         stunalloc(fullname);
13193         }
13194         /* not found in PATH */
13195
13196 #if ENABLE_ASH_BASH_SOURCE_CURDIR
13197         return name;
13198 #else
13199         ash_msg_and_raise_error("%s: not found", name);
13200         /* NOTREACHED */
13201 #endif
13202 }
13203
13204 static int FAST_FUNC
13205 dotcmd(int argc_ UNUSED_PARAM, char **argv_ UNUSED_PARAM)
13206 {
13207         /* "false; . empty_file; echo $?" should print 0, not 1: */
13208         int status = 0;
13209         char *fullname;
13210         char **argv;
13211         char *args_need_save;
13212         volatile struct shparam saveparam;
13213
13214 //???
13215 //      struct strlist *sp;
13216 //      for (sp = cmdenviron; sp; sp = sp->next)
13217 //              setvareq(ckstrdup(sp->text), VSTRFIXED | VTEXTFIXED);
13218
13219         nextopt(nullstr); /* handle possible "--" */
13220         argv = argptr;
13221
13222         if (!argv[0]) {
13223                 /* bash says: "bash: .: filename argument required" */
13224                 return 2; /* bash compat */
13225         }
13226
13227         /* This aborts if file isn't found, which is POSIXly correct.
13228          * bash returns exitcode 1 instead.
13229          */
13230         fullname = find_dot_file(argv[0]);
13231         argv++;
13232         args_need_save = argv[0];
13233         if (args_need_save) { /* ". FILE ARGS", and ARGS are not empty */
13234                 int argc;
13235                 saveparam = shellparam;
13236                 shellparam.malloced = 0;
13237                 argc = 1;
13238                 while (argv[argc])
13239                         argc++;
13240                 shellparam.nparam = argc;
13241                 shellparam.p = argv;
13242         };
13243
13244         /* This aborts if file can't be opened, which is POSIXly correct.
13245          * bash returns exitcode 1 instead.
13246          */
13247         setinputfile(fullname, INPUT_PUSH_FILE);
13248         commandname = fullname;
13249         status = cmdloop(0);
13250         popfile();
13251
13252         if (args_need_save) {
13253                 freeparam(&shellparam);
13254                 shellparam = saveparam;
13255         };
13256
13257         return status;
13258 }
13259
13260 static int FAST_FUNC
13261 exitcmd(int argc UNUSED_PARAM, char **argv)
13262 {
13263         if (stoppedjobs())
13264                 return 0;
13265         if (argv[1])
13266                 exitstatus = number(argv[1]);
13267         raise_exception(EXEXIT);
13268         /* NOTREACHED */
13269 }
13270
13271 /*
13272  * Read a file containing shell functions.
13273  */
13274 static void
13275 readcmdfile(char *name)
13276 {
13277         setinputfile(name, INPUT_PUSH_FILE);
13278         cmdloop(0);
13279         popfile();
13280 }
13281
13282
13283 /* ============ find_command inplementation */
13284
13285 /*
13286  * Resolve a command name.  If you change this routine, you may have to
13287  * change the shellexec routine as well.
13288  */
13289 static void
13290 find_command(char *name, struct cmdentry *entry, int act, const char *path)
13291 {
13292         struct tblentry *cmdp;
13293         int idx;
13294         int prev;
13295         char *fullname;
13296         struct stat statb;
13297         int e;
13298         int updatetbl;
13299         struct builtincmd *bcmd;
13300
13301         /* If name contains a slash, don't use PATH or hash table */
13302         if (strchr(name, '/') != NULL) {
13303                 entry->u.index = -1;
13304                 if (act & DO_ABS) {
13305                         while (stat(name, &statb) < 0) {
13306 #ifdef SYSV
13307                                 if (errno == EINTR)
13308                                         continue;
13309 #endif
13310                                 entry->cmdtype = CMDUNKNOWN;
13311                                 return;
13312                         }
13313                 }
13314                 entry->cmdtype = CMDNORMAL;
13315                 return;
13316         }
13317
13318 /* #if ENABLE_FEATURE_SH_STANDALONE... moved after builtin check */
13319
13320         updatetbl = (path == pathval());
13321         if (!updatetbl) {
13322                 act |= DO_ALTPATH;
13323                 if (strstr(path, "%builtin") != NULL)
13324                         act |= DO_ALTBLTIN;
13325         }
13326
13327         /* If name is in the table, check answer will be ok */
13328         cmdp = cmdlookup(name, 0);
13329         if (cmdp != NULL) {
13330                 int bit;
13331
13332                 switch (cmdp->cmdtype) {
13333                 default:
13334 #if DEBUG
13335                         abort();
13336 #endif
13337                 case CMDNORMAL:
13338                         bit = DO_ALTPATH;
13339                         break;
13340                 case CMDFUNCTION:
13341                         bit = DO_NOFUNC;
13342                         break;
13343                 case CMDBUILTIN:
13344                         bit = DO_ALTBLTIN;
13345                         break;
13346                 }
13347                 if (act & bit) {
13348                         updatetbl = 0;
13349                         cmdp = NULL;
13350                 } else if (cmdp->rehash == 0)
13351                         /* if not invalidated by cd, we're done */
13352                         goto success;
13353         }
13354
13355         /* If %builtin not in path, check for builtin next */
13356         bcmd = find_builtin(name);
13357         if (bcmd) {
13358                 if (IS_BUILTIN_REGULAR(bcmd))
13359                         goto builtin_success;
13360                 if (act & DO_ALTPATH) {
13361                         if (!(act & DO_ALTBLTIN))
13362                                 goto builtin_success;
13363                 } else if (builtinloc <= 0) {
13364                         goto builtin_success;
13365                 }
13366         }
13367
13368 #if ENABLE_FEATURE_SH_STANDALONE
13369         {
13370                 int applet_no = find_applet_by_name(name);
13371                 if (applet_no >= 0) {
13372                         entry->cmdtype = CMDNORMAL;
13373                         entry->u.index = -2 - applet_no;
13374                         return;
13375                 }
13376         }
13377 #endif
13378
13379         /* We have to search path. */
13380         prev = -1;              /* where to start */
13381         if (cmdp && cmdp->rehash) {     /* doing a rehash */
13382                 if (cmdp->cmdtype == CMDBUILTIN)
13383                         prev = builtinloc;
13384                 else
13385                         prev = cmdp->param.index;
13386         }
13387
13388         e = ENOENT;
13389         idx = -1;
13390  loop:
13391         while ((fullname = path_advance(&path, name)) != NULL) {
13392                 stunalloc(fullname);
13393                 /* NB: code below will still use fullname
13394                  * despite it being "unallocated" */
13395                 idx++;
13396                 if (pathopt) {
13397                         if (prefix(pathopt, "builtin")) {
13398                                 if (bcmd)
13399                                         goto builtin_success;
13400                                 continue;
13401                         }
13402                         if ((act & DO_NOFUNC)
13403                          || !prefix(pathopt, "func")
13404                         ) {     /* ignore unimplemented options */
13405                                 continue;
13406                         }
13407                 }
13408                 /* if rehash, don't redo absolute path names */
13409                 if (fullname[0] == '/' && idx <= prev) {
13410                         if (idx < prev)
13411                                 continue;
13412                         TRACE(("searchexec \"%s\": no change\n", name));
13413                         goto success;
13414                 }
13415                 while (stat(fullname, &statb) < 0) {
13416 #ifdef SYSV
13417                         if (errno == EINTR)
13418                                 continue;
13419 #endif
13420                         if (errno != ENOENT && errno != ENOTDIR)
13421                                 e = errno;
13422                         goto loop;
13423                 }
13424                 e = EACCES;     /* if we fail, this will be the error */
13425                 if (!S_ISREG(statb.st_mode))
13426                         continue;
13427                 if (pathopt) {          /* this is a %func directory */
13428                         stalloc(strlen(fullname) + 1);
13429                         /* NB: stalloc will return space pointed by fullname
13430                          * (because we don't have any intervening allocations
13431                          * between stunalloc above and this stalloc) */
13432                         readcmdfile(fullname);
13433                         cmdp = cmdlookup(name, 0);
13434                         if (cmdp == NULL || cmdp->cmdtype != CMDFUNCTION)
13435                                 ash_msg_and_raise_error("%s not defined in %s", name, fullname);
13436                         stunalloc(fullname);
13437                         goto success;
13438                 }
13439                 TRACE(("searchexec \"%s\" returns \"%s\"\n", name, fullname));
13440                 if (!updatetbl) {
13441                         entry->cmdtype = CMDNORMAL;
13442                         entry->u.index = idx;
13443                         return;
13444                 }
13445                 INT_OFF;
13446                 cmdp = cmdlookup(name, 1);
13447                 cmdp->cmdtype = CMDNORMAL;
13448                 cmdp->param.index = idx;
13449                 INT_ON;
13450                 goto success;
13451         }
13452
13453         /* We failed.  If there was an entry for this command, delete it */
13454         if (cmdp && updatetbl)
13455                 delete_cmd_entry();
13456         if (act & DO_ERR) {
13457 #if ENABLE_ASH_BASH_NOT_FOUND_HOOK
13458                 struct tblentry *hookp = cmdlookup("command_not_found_handle", 0);
13459                 if (hookp && hookp->cmdtype == CMDFUNCTION) {
13460                         char *argv[3];
13461                         argv[0] = (char*) "command_not_found_handle";
13462                         argv[1] = name;
13463                         argv[2] = NULL;
13464                         evalfun(hookp->param.func, 2, argv, 0);
13465                         entry->cmdtype = CMDUNKNOWN;
13466                         return;
13467                 }
13468 #endif
13469                 ash_msg("%s: %s", name, errmsg(e, "not found"));
13470         }
13471         entry->cmdtype = CMDUNKNOWN;
13472         return;
13473
13474  builtin_success:
13475         if (!updatetbl) {
13476                 entry->cmdtype = CMDBUILTIN;
13477                 entry->u.cmd = bcmd;
13478                 return;
13479         }
13480         INT_OFF;
13481         cmdp = cmdlookup(name, 1);
13482         cmdp->cmdtype = CMDBUILTIN;
13483         cmdp->param.cmd = bcmd;
13484         INT_ON;
13485  success:
13486         cmdp->rehash = 0;
13487         entry->cmdtype = cmdp->cmdtype;
13488         entry->u = cmdp->param;
13489 }
13490
13491
13492 /*
13493  * The trap builtin.
13494  */
13495 static int FAST_FUNC
13496 trapcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
13497 {
13498         char *action;
13499         char **ap;
13500         int signo, exitcode;
13501
13502         nextopt(nullstr);
13503         ap = argptr;
13504         if (!*ap) {
13505                 for (signo = 0; signo < NSIG; signo++) {
13506                         char *tr = trap_ptr[signo];
13507                         if (tr) {
13508                                 /* note: bash adds "SIG", but only if invoked
13509                                  * as "bash". If called as "sh", or if set -o posix,
13510                                  * then it prints short signal names.
13511                                  * We are printing short names: */
13512                                 out1fmt("trap -- %s %s\n",
13513                                                 single_quote(tr),
13514                                                 get_signame(signo));
13515                 /* trap_ptr != trap only if we are in special-cased `trap` code.
13516                  * In this case, we will exit very soon, no need to free(). */
13517                                 /* if (trap_ptr != trap && tp[0]) */
13518                                 /*      free(tr); */
13519                         }
13520                 }
13521                 /*
13522                 if (trap_ptr != trap) {
13523                         free(trap_ptr);
13524                         trap_ptr = trap;
13525                 }
13526                 */
13527                 return 0;
13528         }
13529
13530         /* Why the second check?
13531          * "trap NUM [sig2]..." is the same as "trap - NUM [sig2]..."
13532          * In this case, NUM is signal no, not an action.
13533          */
13534         action = NULL;
13535         if (ap[1] && !is_number(ap[0]))
13536                 action = *ap++;
13537
13538         exitcode = 0;
13539         while (*ap) {
13540                 signo = get_signum(*ap);
13541                 if (signo < 0) {
13542                         /* Mimic bash message exactly */
13543                         ash_msg("%s: invalid signal specification", *ap);
13544                         exitcode = 1;
13545                         goto next;
13546                 }
13547                 INT_OFF;
13548                 if (action) {
13549                         if (LONE_DASH(action))
13550                                 action = NULL;
13551                         else {
13552                                 if (action[0]) /* not NULL and not "" and not "-" */
13553                                         may_have_traps = 1;
13554                                 action = ckstrdup(action);
13555                         }
13556                 }
13557                 free(trap[signo]);
13558                 trap[signo] = action;
13559                 if (signo != 0)
13560                         setsignal(signo);
13561                 INT_ON;
13562  next:
13563                 ap++;
13564         }
13565         return exitcode;
13566 }
13567
13568
13569 /* ============ Builtins */
13570
13571 #if ENABLE_ASH_HELP
13572 static int FAST_FUNC
13573 helpcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
13574 {
13575         unsigned col;
13576         unsigned i;
13577
13578         out1fmt(
13579                 "Built-in commands:\n"
13580                 "------------------\n");
13581         for (col = 0, i = 0; i < ARRAY_SIZE(builtintab); i++) {
13582                 col += out1fmt("%c%s", ((col == 0) ? '\t' : ' '),
13583                                         builtintab[i].name + 1);
13584                 if (col > 60) {
13585                         out1fmt("\n");
13586                         col = 0;
13587                 }
13588         }
13589 # if ENABLE_FEATURE_SH_STANDALONE
13590         {
13591                 const char *a = applet_names;
13592                 while (*a) {
13593                         col += out1fmt("%c%s", ((col == 0) ? '\t' : ' '), a);
13594                         if (col > 60) {
13595                                 out1fmt("\n");
13596                                 col = 0;
13597                         }
13598                         while (*a++ != '\0')
13599                                 continue;
13600                 }
13601         }
13602 # endif
13603         newline_and_flush(stdout);
13604         return EXIT_SUCCESS;
13605 }
13606 #endif
13607
13608 #if MAX_HISTORY
13609 static int FAST_FUNC
13610 historycmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
13611 {
13612         show_history(line_input_state);
13613         return EXIT_SUCCESS;
13614 }
13615 #endif
13616
13617 /*
13618  * The export and readonly commands.
13619  */
13620 static int FAST_FUNC
13621 exportcmd(int argc UNUSED_PARAM, char **argv)
13622 {
13623         struct var *vp;
13624         char *name;
13625         const char *p;
13626         char **aptr;
13627         char opt;
13628         int flag;
13629         int flag_off;
13630
13631         /* "readonly" in bash accepts, but ignores -n.
13632          * We do the same: it saves a conditional in nextopt's param.
13633          */
13634         flag_off = 0;
13635         while ((opt = nextopt("np")) != '\0') {
13636                 if (opt == 'n')
13637                         flag_off = VEXPORT;
13638         }
13639         flag = VEXPORT;
13640         if (argv[0][0] == 'r') {
13641                 flag = VREADONLY;
13642                 flag_off = 0; /* readonly ignores -n */
13643         }
13644         flag_off = ~flag_off;
13645
13646         /*if (opt_p_not_specified) - bash doesn't check this. Try "export -p NAME" */
13647         {
13648                 aptr = argptr;
13649                 name = *aptr;
13650                 if (name) {
13651                         do {
13652                                 p = strchr(name, '=');
13653                                 if (p != NULL) {
13654                                         p++;
13655                                 } else {
13656                                         vp = *findvar(hashvar(name), name);
13657                                         if (vp) {
13658                                                 vp->flags = ((vp->flags | flag) & flag_off);
13659                                                 continue;
13660                                         }
13661                                 }
13662                                 setvar(name, p, (flag & flag_off));
13663                         } while ((name = *++aptr) != NULL);
13664                         return 0;
13665                 }
13666         }
13667
13668         /* No arguments. Show the list of exported or readonly vars.
13669          * -n is ignored.
13670          */
13671         showvars(argv[0], flag, 0);
13672         return 0;
13673 }
13674
13675 /*
13676  * Delete a function if it exists.
13677  */
13678 static void
13679 unsetfunc(const char *name)
13680 {
13681         struct tblentry *cmdp;
13682
13683         cmdp = cmdlookup(name, 0);
13684         if (cmdp != NULL && cmdp->cmdtype == CMDFUNCTION)
13685                 delete_cmd_entry();
13686 }
13687
13688 /*
13689  * The unset builtin command.  We unset the function before we unset the
13690  * variable to allow a function to be unset when there is a readonly variable
13691  * with the same name.
13692  */
13693 static int FAST_FUNC
13694 unsetcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
13695 {
13696         char **ap;
13697         int i;
13698         int flag = 0;
13699
13700         while ((i = nextopt("vf")) != 0) {
13701                 flag = i;
13702         }
13703
13704         for (ap = argptr; *ap; ap++) {
13705                 if (flag != 'f') {
13706                         unsetvar(*ap);
13707                         continue;
13708                 }
13709                 if (flag != 'v')
13710                         unsetfunc(*ap);
13711         }
13712         return 0;
13713 }
13714
13715 static const unsigned char timescmd_str[] ALIGN1 = {
13716         ' ',  offsetof(struct tms, tms_utime),
13717         '\n', offsetof(struct tms, tms_stime),
13718         ' ',  offsetof(struct tms, tms_cutime),
13719         '\n', offsetof(struct tms, tms_cstime),
13720         0
13721 };
13722 static int FAST_FUNC
13723 timescmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
13724 {
13725         unsigned clk_tck;
13726         const unsigned char *p;
13727         struct tms buf;
13728
13729         clk_tck = bb_clk_tck();
13730
13731         times(&buf);
13732         p = timescmd_str;
13733         do {
13734                 unsigned sec, frac;
13735                 unsigned long t;
13736                 t = *(clock_t *)(((char *) &buf) + p[1]);
13737                 sec = t / clk_tck;
13738                 frac = t % clk_tck;
13739                 out1fmt("%um%u.%03us%c",
13740                         sec / 60, sec % 60,
13741                         (frac * 1000) / clk_tck,
13742                         p[0]);
13743                 p += 2;
13744         } while (*p);
13745
13746         return 0;
13747 }
13748
13749 #if ENABLE_FEATURE_SH_MATH
13750 /*
13751  * The let builtin. Partially stolen from GNU Bash, the Bourne Again SHell.
13752  * Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
13753  *
13754  * Copyright (C) 2003 Vladimir Oleynik <dzo@simtreas.ru>
13755  */
13756 static int FAST_FUNC
13757 letcmd(int argc UNUSED_PARAM, char **argv)
13758 {
13759         arith_t i;
13760
13761         argv++;
13762         if (!*argv)
13763                 ash_msg_and_raise_error("expression expected");
13764         do {
13765                 i = ash_arith(*argv);
13766         } while (*++argv);
13767
13768         return !i;
13769 }
13770 #endif
13771
13772 /*
13773  * The read builtin. Options:
13774  *      -r              Do not interpret '\' specially
13775  *      -s              Turn off echo (tty only)
13776  *      -n NCHARS       Read NCHARS max
13777  *      -p PROMPT       Display PROMPT on stderr (if input is from tty)
13778  *      -t SECONDS      Timeout after SECONDS (tty or pipe only)
13779  *      -u FD           Read from given FD instead of fd 0
13780  *      -d DELIM        End on DELIM char, not newline
13781  * This uses unbuffered input, which may be avoidable in some cases.
13782  * TODO: bash also has:
13783  *      -a ARRAY        Read into array[0],[1],etc
13784  *      -e              Use line editing (tty only)
13785  */
13786 static int FAST_FUNC
13787 readcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
13788 {
13789         struct builtin_read_params params;
13790         const char *r;
13791         int i;
13792
13793         memset(&params, 0, sizeof(params));
13794
13795         while ((i = nextopt("p:u:rt:n:sd:")) != '\0') {
13796                 switch (i) {
13797                 case 'p':
13798                         params.opt_p = optionarg;
13799                         break;
13800                 case 'n':
13801                         params.opt_n = optionarg;
13802                         break;
13803                 case 's':
13804                         params.read_flags |= BUILTIN_READ_SILENT;
13805                         break;
13806                 case 't':
13807                         params.opt_t = optionarg;
13808                         break;
13809                 case 'r':
13810                         params.read_flags |= BUILTIN_READ_RAW;
13811                         break;
13812                 case 'u':
13813                         params.opt_u = optionarg;
13814                         break;
13815 #if BASH_READ_D
13816                 case 'd':
13817                         params.opt_d = optionarg;
13818                         break;
13819 #endif
13820                 default:
13821                         break;
13822                 }
13823         }
13824
13825         params.argv = argptr;
13826         params.setvar = setvar0;
13827         params.ifs = bltinlookup("IFS"); /* can be NULL */
13828
13829         /* "read -s" needs to save/restore termios, can't allow ^C
13830          * to jump out of it.
13831          */
13832  again:
13833         INT_OFF;
13834         r = shell_builtin_read(&params);
13835         INT_ON;
13836
13837         if ((uintptr_t)r == 1 && errno == EINTR) {
13838                 /* To get SIGCHLD: sleep 1 & read x; echo $x
13839                  * Correct behavior is to not exit "read"
13840                  */
13841                 if (pending_sig == 0)
13842                         goto again;
13843         }
13844
13845         if ((uintptr_t)r > 1)
13846                 ash_msg_and_raise_error(r);
13847
13848         return (uintptr_t)r;
13849 }
13850
13851 static int FAST_FUNC
13852 umaskcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
13853 {
13854         static const char permuser[3] ALIGN1 = "ogu";
13855
13856         mode_t mask;
13857         int symbolic_mode = 0;
13858
13859         while (nextopt("S") != '\0') {
13860                 symbolic_mode = 1;
13861         }
13862
13863         INT_OFF;
13864         mask = umask(0);
13865         umask(mask);
13866         INT_ON;
13867
13868         if (*argptr == NULL) {
13869                 if (symbolic_mode) {
13870                         char buf[sizeof(",u=rwx,g=rwx,o=rwx")];
13871                         char *p = buf;
13872                         int i;
13873
13874                         i = 2;
13875                         for (;;) {
13876                                 *p++ = ',';
13877                                 *p++ = permuser[i];
13878                                 *p++ = '=';
13879                                 /* mask is 0..0uuugggooo. i=2 selects uuu bits */
13880                                 if (!(mask & 0400)) *p++ = 'r';
13881                                 if (!(mask & 0200)) *p++ = 'w';
13882                                 if (!(mask & 0100)) *p++ = 'x';
13883                                 mask <<= 3;
13884                                 if (--i < 0)
13885                                         break;
13886                         }
13887                         *p = '\0';
13888                         puts(buf + 1);
13889                 } else {
13890                         out1fmt("%04o\n", mask);
13891                 }
13892         } else {
13893                 char *modestr = *argptr;
13894                 /* numeric umasks are taken as-is */
13895                 /* symbolic umasks are inverted: "umask a=rx" calls umask(222) */
13896                 if (!isdigit(modestr[0]))
13897                         mask ^= 0777;
13898                 mask = bb_parse_mode(modestr, mask);
13899                 if ((unsigned)mask > 0777) {
13900                         ash_msg_and_raise_error("illegal mode: %s", modestr);
13901                 }
13902                 if (!isdigit(modestr[0]))
13903                         mask ^= 0777;
13904                 umask(mask);
13905         }
13906         return 0;
13907 }
13908
13909 static int FAST_FUNC
13910 ulimitcmd(int argc UNUSED_PARAM, char **argv)
13911 {
13912         return shell_builtin_ulimit(argv);
13913 }
13914
13915 /* ============ main() and helpers */
13916
13917 /*
13918  * Called to exit the shell.
13919  */
13920 static void
13921 exitshell(void)
13922 {
13923         struct jmploc loc;
13924         char *p;
13925         int status;
13926
13927 #if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT
13928         save_history(line_input_state);
13929 #endif
13930         status = exitstatus;
13931         TRACE(("pid %d, exitshell(%d)\n", getpid(), status));
13932         if (setjmp(loc.loc)) {
13933                 if (exception_type == EXEXIT)
13934                         status = exitstatus;
13935                 goto out;
13936         }
13937         exception_handler = &loc;
13938         p = trap[0];
13939         if (p) {
13940                 trap[0] = NULL;
13941                 evalskip = 0;
13942                 evalstring(p, 0);
13943                 /*free(p); - we'll exit soon */
13944         }
13945  out:
13946         /* dash wraps setjobctl(0) in "if (setjmp(loc.loc) == 0) {...}".
13947          * our setjobctl(0) does not panic if tcsetpgrp fails inside it.
13948          */
13949         setjobctl(0);
13950         flush_stdout_stderr();
13951         _exit(status);
13952         /* NOTREACHED */
13953 }
13954
13955 /* Don't inline: conserve stack of caller from having our locals too */
13956 static NOINLINE void
13957 init(void)
13958 {
13959         /* we will never free this */
13960         basepf.next_to_pgetc = basepf.buf = ckmalloc(IBUFSIZ);
13961         basepf.linno = 1;
13962
13963         sigmode[SIGCHLD - 1] = S_DFL; /* ensure we install handler even if it is SIG_IGNed */
13964         setsignal(SIGCHLD);
13965
13966         /* bash re-enables SIGHUP which is SIG_IGNed on entry.
13967          * Try: "trap '' HUP; bash; echo RET" and type "kill -HUP $$"
13968          */
13969         signal(SIGHUP, SIG_DFL);
13970
13971         {
13972                 char **envp;
13973                 const char *p;
13974
13975                 initvar();
13976                 for (envp = environ; envp && *envp; envp++) {
13977 /* Used to have
13978  *                      p = endofname(*envp);
13979  *                      if (p != *envp && *p == '=') {
13980  * here to weed out badly-named variables, but this breaks
13981  * scenarios where people do want them passed to children:
13982  * import os
13983  * os.environ["test-test"]="test"
13984  * if os.fork() == 0:
13985  *   os.execv("ash", [ 'ash', '-c', 'eval $(export -p); echo OK' ])  # fixes this
13986  * os.execv("ash", [ 'ash', '-c', 'env | grep test-test' ])  # breaks this
13987  */
13988                         if (strchr(*envp, '=')) {
13989                                 setvareq(*envp, VEXPORT|VTEXTFIXED);
13990                         }
13991                 }
13992
13993                 setvareq((char*)defifsvar, VTEXTFIXED);
13994                 setvareq((char*)defoptindvar, VTEXTFIXED);
13995
13996                 setvar0("PPID", utoa(getppid()));
13997 #if BASH_SHLVL_VAR
13998                 p = lookupvar("SHLVL");
13999                 setvar("SHLVL", utoa((p ? atoi(p) : 0) + 1), VEXPORT);
14000 #endif
14001 #if BASH_HOSTNAME_VAR
14002                 if (!lookupvar("HOSTNAME")) {
14003                         struct utsname uts;
14004                         uname(&uts);
14005                         setvar0("HOSTNAME", uts.nodename);
14006                 }
14007 #endif
14008                 p = lookupvar("PWD");
14009                 if (p) {
14010                         struct stat st1, st2;
14011                         if (p[0] != '/' || stat(p, &st1) || stat(".", &st2)
14012                          || st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino
14013                         ) {
14014                                 p = NULL;
14015                         }
14016                 }
14017                 setpwd(p, 0);
14018         }
14019 }
14020
14021
14022 //usage:#define ash_trivial_usage
14023 //usage:        "[-/+OPTIONS] [-/+o OPT]... [-c 'SCRIPT' [ARG0 [ARGS]] / FILE [ARGS] / -s [ARGS]]"
14024 //usage:#define ash_full_usage "\n\n"
14025 //usage:        "Unix shell interpreter"
14026
14027 /*
14028  * Process the shell command line arguments.
14029  */
14030 static int
14031 procargs(char **argv)
14032 {
14033         int i;
14034         const char *xminusc;
14035         char **xargv;
14036         int login_sh;
14037
14038         xargv = argv;
14039 #if NUM_SCRIPTS > 0
14040         if (minusc)
14041                 goto setarg0;
14042 #endif
14043         login_sh = xargv[0] && xargv[0][0] == '-';
14044         arg0 = xargv[0];
14045         /* if (xargv[0]) - mmm, this is always true! */
14046                 xargv++;
14047         argptr = xargv;
14048         for (i = 0; i < NOPTS; i++)
14049                 optlist[i] = 2;
14050         if (options(/*cmdline:*/ 1, &login_sh)) {
14051                 /* it already printed err message */
14052                 raise_exception(EXERROR);
14053         }
14054         xargv = argptr;
14055         xminusc = minusc;
14056         if (*xargv == NULL) {
14057                 if (xminusc)
14058                         ash_msg_and_raise_error(bb_msg_requires_arg, "-c");
14059                 sflag = 1;
14060         }
14061         if (iflag == 2 && sflag == 1 && isatty(0) && isatty(1))
14062                 iflag = 1;
14063         if (mflag == 2)
14064                 mflag = iflag;
14065         for (i = 0; i < NOPTS; i++)
14066                 if (optlist[i] == 2)
14067                         optlist[i] = 0;
14068 #if DEBUG == 2
14069         debug = 1;
14070 #endif
14071         /* POSIX 1003.2: first arg after "-c CMD" is $0, remainder $1... */
14072         if (xminusc) {
14073                 minusc = *xargv++;
14074                 if (*xargv)
14075                         goto setarg0;
14076         } else if (!sflag) {
14077                 setinputfile(*xargv, 0);
14078  setarg0:
14079                 arg0 = *xargv++;
14080                 commandname = arg0;
14081         }
14082
14083         shellparam.p = xargv;
14084 #if ENABLE_ASH_GETOPTS
14085         shellparam.optind = 1;
14086         shellparam.optoff = -1;
14087 #endif
14088         /* assert(shellparam.malloced == 0 && shellparam.nparam == 0); */
14089         while (*xargv) {
14090                 shellparam.nparam++;
14091                 xargv++;
14092         }
14093         optschanged();
14094
14095         return login_sh;
14096 }
14097
14098 /*
14099  * Read /etc/profile, ~/.profile, $ENV.
14100  */
14101 static void
14102 read_profile(const char *name)
14103 {
14104         name = expandstr(name, DQSYNTAX);
14105         if (setinputfile(name, INPUT_PUSH_FILE | INPUT_NOFILE_OK) < 0)
14106                 return;
14107         cmdloop(0);
14108         popfile();
14109 }
14110
14111 /*
14112  * This routine is called when an error or an interrupt occurs in an
14113  * interactive shell and control is returned to the main command loop.
14114  * (In dash, this function is auto-generated by build machinery).
14115  */
14116 static void
14117 reset(void)
14118 {
14119         /* from eval.c: */
14120         evalskip = 0;
14121         loopnest = 0;
14122
14123         /* from expand.c: */
14124         ifsfree();
14125
14126         /* from input.c: */
14127         g_parsefile->left_in_buffer = 0;
14128         g_parsefile->left_in_line = 0;      /* clear input buffer */
14129         popallfiles();
14130
14131         /* from redir.c: */
14132         unwindredir(NULL);
14133
14134         /* from var.c: */
14135         unwindlocalvars(NULL);
14136 }
14137
14138 #if PROFILE
14139 static short profile_buf[16384];
14140 extern int etext();
14141 #endif
14142
14143 /*
14144  * Main routine.  We initialize things, parse the arguments, execute
14145  * profiles if we're a login shell, and then call cmdloop to execute
14146  * commands.  The setjmp call sets up the location to jump to when an
14147  * exception occurs.  When an exception occurs the variable "state"
14148  * is used to figure out how far we had gotten.
14149  */
14150 int ash_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
14151 int ash_main(int argc UNUSED_PARAM, char **argv)
14152 /* note: 'argc' is used only if embedded scripts are enabled */
14153 {
14154         volatile smallint state;
14155         struct jmploc jmploc;
14156         struct stackmark smark;
14157         int login_sh;
14158
14159         /* Initialize global data */
14160         INIT_G_misc();
14161         INIT_G_memstack();
14162         INIT_G_var();
14163 #if ENABLE_ASH_ALIAS
14164         INIT_G_alias();
14165 #endif
14166         INIT_G_cmdtable();
14167
14168 #if PROFILE
14169         monitor(4, etext, profile_buf, sizeof(profile_buf), 50);
14170 #endif
14171
14172 #if ENABLE_FEATURE_EDITING
14173         line_input_state = new_line_input_t(FOR_SHELL | WITH_PATH_LOOKUP);
14174 #endif
14175         state = 0;
14176         if (setjmp(jmploc.loc)) {
14177                 smallint e;
14178                 smallint s;
14179
14180                 reset();
14181
14182                 e = exception_type;
14183                 s = state;
14184                 if (e == EXEXIT || s == 0 || iflag == 0 || shlvl) {
14185                         exitshell();
14186                 }
14187                 if (e == EXINT) {
14188                         newline_and_flush(stderr);
14189                 }
14190
14191                 popstackmark(&smark);
14192                 FORCE_INT_ON; /* enable interrupts */
14193                 if (s == 1)
14194                         goto state1;
14195                 if (s == 2)
14196                         goto state2;
14197                 if (s == 3)
14198                         goto state3;
14199                 goto state4;
14200         }
14201         exception_handler = &jmploc;
14202         rootpid = getpid();
14203
14204         init();
14205         setstackmark(&smark);
14206
14207 #if NUM_SCRIPTS > 0
14208         if (argc < 0)
14209                 /* Non-NULL minusc tells procargs that an embedded script is being run */
14210                 minusc = get_script_content(-argc - 1);
14211 #endif
14212         login_sh = procargs(argv);
14213 #if DEBUG
14214         TRACE(("Shell args: "));
14215         trace_puts_args(argv);
14216 #endif
14217
14218         if (login_sh) {
14219                 const char *hp;
14220
14221                 state = 1;
14222                 read_profile("/etc/profile");
14223  state1:
14224                 state = 2;
14225                 hp = lookupvar("HOME");
14226                 if (hp)
14227                         read_profile("$HOME/.profile");
14228         }
14229  state2:
14230         state = 3;
14231         if (
14232 #ifndef linux
14233          getuid() == geteuid() && getgid() == getegid() &&
14234 #endif
14235          iflag
14236         ) {
14237                 const char *shinit = lookupvar("ENV");
14238                 if (shinit != NULL && *shinit != '\0')
14239                         read_profile(shinit);
14240         }
14241         popstackmark(&smark);
14242  state3:
14243         state = 4;
14244         if (minusc) {
14245                 /* evalstring pushes parsefile stack.
14246                  * Ensure we don't falsely claim that 0 (stdin)
14247                  * is one of stacked source fds.
14248                  * Testcase: ash -c 'exec 1>&0' must not complain. */
14249                 // if (!sflag) g_parsefile->pf_fd = -1;
14250                 // ^^ not necessary since now we special-case fd 0
14251                 // in save_fd_on_redirect()
14252                 evalstring(minusc, sflag ? 0 : EV_EXIT);
14253         }
14254
14255         if (sflag || minusc == NULL) {
14256 #if MAX_HISTORY > 0 && ENABLE_FEATURE_EDITING_SAVEHISTORY
14257                 if (iflag) {
14258                         const char *hp = lookupvar("HISTFILE");
14259                         if (!hp) {
14260                                 hp = lookupvar("HOME");
14261                                 if (hp) {
14262                                         INT_OFF;
14263                                         hp = concat_path_file(hp, ".ash_history");
14264                                         setvar0("HISTFILE", hp);
14265                                         free((char*)hp);
14266                                         INT_ON;
14267                                         hp = lookupvar("HISTFILE");
14268                                 }
14269                         }
14270                         if (hp)
14271                                 line_input_state->hist_file = hp;
14272 # if ENABLE_FEATURE_SH_HISTFILESIZE
14273                         hp = lookupvar("HISTFILESIZE");
14274                         line_input_state->max_history = size_from_HISTFILESIZE(hp);
14275 # endif
14276                 }
14277 #endif
14278  state4: /* XXX ??? - why isn't this before the "if" statement */
14279                 cmdloop(1);
14280         }
14281 #if PROFILE
14282         monitor(0);
14283 #endif
14284 #ifdef GPROF
14285         {
14286                 extern void _mcleanup(void);
14287                 _mcleanup();
14288         }
14289 #endif
14290         TRACE(("End of main reached\n"));
14291         exitshell();
14292         /* NOTREACHED */
14293 }
14294
14295
14296 /*-
14297  * Copyright (c) 1989, 1991, 1993, 1994
14298  *      The Regents of the University of California.  All rights reserved.
14299  *
14300  * This code is derived from software contributed to Berkeley by
14301  * Kenneth Almquist.
14302  *
14303  * Redistribution and use in source and binary forms, with or without
14304  * modification, are permitted provided that the following conditions
14305  * are met:
14306  * 1. Redistributions of source code must retain the above copyright
14307  *    notice, this list of conditions and the following disclaimer.
14308  * 2. Redistributions in binary form must reproduce the above copyright
14309  *    notice, this list of conditions and the following disclaimer in the
14310  *    documentation and/or other materials provided with the distribution.
14311  * 3. Neither the name of the University nor the names of its contributors
14312  *    may be used to endorse or promote products derived from this software
14313  *    without specific prior written permission.
14314  *
14315  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ''AS IS'' AND
14316  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
14317  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
14318  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
14319  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
14320  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
14321  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
14322  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
14323  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
14324  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
14325  * SUCH DAMAGE.
14326  */