a284b084d4268e21617ae237ec9677f6f430c57c
[oweals/busybox.git] / ash.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * ash shell port for busybox
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Kenneth Almquist.
7  *
8  * Original BSD copyright notice is retained at the end of this file.
9  *
10  * Copyright (c) 1989, 1991, 1993, 1994
11  *      The Regents of the University of California.  All rights reserved.
12  *
13  * Copyright (c) 1997-2005 Herbert Xu <herbert@gondor.apana.org.au>
14  * was re-ported from NetBSD and debianized.
15  *
16  * Licensed under GPLv2 or later, see file LICENSE in this source tree.
17  */
18 //config:config ASH
19 //config:       bool "ash (78 kb)"
20 //config:       default y
21 //config:       depends on !NOMMU
22 //config:       help
23 //config:       The most complete and most pedantically correct shell included with
24 //config:       busybox. This shell is actually a derivative of the Debian 'dash'
25 //config:       shell (by Herbert Xu), which was created by porting the 'ash' shell
26 //config:       (written by Kenneth Almquist) from NetBSD.
27 //config:
28 //config:# ash options
29 //config:# note: Don't remove !NOMMU part in the next line; it would break
30 //config:# menuconfig's indenting.
31 //config:if !NOMMU && (ASH || SH_IS_ASH || BASH_IS_ASH)
32 //config:
33 //config:config ASH_OPTIMIZE_FOR_SIZE
34 //config:       bool "Optimize for size instead of speed"
35 //config:       default y
36 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
37 //config:
38 //config:config ASH_INTERNAL_GLOB
39 //config:       bool "Use internal glob() implementation"
40 //config:       default y       # Y is bigger, but because of uclibc glob() bug, let Y be default for now
41 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
42 //config:       help
43 //config:       Do not use glob() function from libc, use internal implementation.
44 //config:       Use this if you are getting "glob.h: No such file or directory"
45 //config:       or similar build errors.
46 //config:       Note that as of now (2017-01), uclibc and musl glob() both have bugs
47 //config:       which would break ash if you select N here.
48 //config:
49 //config:config ASH_BASH_COMPAT
50 //config:       bool "bash-compatible extensions"
51 //config:       default y
52 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
53 //config:
54 //config:config ASH_BASH_SOURCE_CURDIR
55 //config:       bool "'source' and '.' builtins search current directory after $PATH"
56 //config:       default n   # do not encourage non-standard behavior
57 //config:       depends on ASH_BASH_COMPAT
58 //config:       help
59 //config:       This is not compliant with standards. Avoid if possible.
60 //config:
61 //config:config ASH_BASH_NOT_FOUND_HOOK
62 //config:       bool "command_not_found_handle hook support"
63 //config:       default y
64 //config:       depends on ASH_BASH_COMPAT
65 //config:       help
66 //config:       Enable support for the 'command_not_found_handle' hook function,
67 //config:       from GNU bash, which allows for alternative command not found
68 //config:       handling.
69 //config:
70 //config:config ASH_JOB_CONTROL
71 //config:       bool "Job control"
72 //config:       default y
73 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
74 //config:
75 //config:config ASH_ALIAS
76 //config:       bool "Alias support"
77 //config:       default y
78 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
79 //config:
80 //config:config ASH_RANDOM_SUPPORT
81 //config:       bool "Pseudorandom generator and $RANDOM variable"
82 //config:       default y
83 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
84 //config:       help
85 //config:       Enable pseudorandom generator and dynamic variable "$RANDOM".
86 //config:       Each read of "$RANDOM" will generate a new pseudorandom value.
87 //config:       You can reset the generator by using a specified start value.
88 //config:       After "unset RANDOM" the generator will switch off and this
89 //config:       variable will no longer have special treatment.
90 //config:
91 //config:config ASH_EXPAND_PRMT
92 //config:       bool "Expand prompt string"
93 //config:       default y
94 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
95 //config:       help
96 //config:       $PS# may contain volatile content, such as backquote commands.
97 //config:       This option recreates the prompt string from the environment
98 //config:       variable each time it is displayed.
99 //config:
100 //config:config ASH_IDLE_TIMEOUT
101 //config:       bool "Idle timeout variable $TMOUT"
102 //config:       default y
103 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
104 //config:       help
105 //config:       Enable bash-like auto-logout after $TMOUT seconds of idle time.
106 //config:
107 //config:config ASH_MAIL
108 //config:       bool "Check for new mail in interactive shell"
109 //config:       default y
110 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
111 //config:       help
112 //config:       Enable "check for new mail" function:
113 //config:       if set, $MAIL file and $MAILPATH list of files
114 //config:       are checked for mtime changes, and "you have mail"
115 //config:       message is printed if change is detected.
116 //config:
117 //config:config ASH_ECHO
118 //config:       bool "echo builtin"
119 //config:       default y
120 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
121 //config:
122 //config:config ASH_PRINTF
123 //config:       bool "printf builtin"
124 //config:       default y
125 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
126 //config:
127 //config:config ASH_TEST
128 //config:       bool "test builtin"
129 //config:       default y
130 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
131 //config:
132 //config:config ASH_HELP
133 //config:       bool "help builtin"
134 //config:       default y
135 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
136 //config:
137 //config:config ASH_GETOPTS
138 //config:       bool "getopts builtin"
139 //config:       default y
140 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
141 //config:
142 //config:config ASH_CMDCMD
143 //config:       bool "command builtin"
144 //config:       default y
145 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
146 //config:       help
147 //config:       Enable support for the 'command' builtin, which allows
148 //config:       you to run the specified command or builtin,
149 //config:       even when there is a function with the same name.
150 //config:
151 //config:endif # ash options
152
153 //applet:IF_ASH(APPLET(ash, BB_DIR_BIN, BB_SUID_DROP))
154 //                      APPLET_ODDNAME:name  main location    suid_type     help
155 //applet:IF_SH_IS_ASH(  APPLET_ODDNAME(sh,   ash, BB_DIR_BIN, BB_SUID_DROP, ash))
156 //applet:IF_BASH_IS_ASH(APPLET_ODDNAME(bash, ash, BB_DIR_BIN, BB_SUID_DROP, ash))
157
158 //kbuild:lib-$(CONFIG_ASH) += ash.o ash_ptr_hack.o shell_common.o
159 //kbuild:lib-$(CONFIG_SH_IS_ASH) += ash.o ash_ptr_hack.o shell_common.o
160 //kbuild:lib-$(CONFIG_BASH_IS_ASH) += ash.o ash_ptr_hack.o shell_common.o
161 //kbuild:lib-$(CONFIG_ASH_RANDOM_SUPPORT) += random.o
162
163 /*
164  * DEBUG=1 to compile in debugging ('set -o debug' turns on)
165  * DEBUG=2 to compile in and turn on debugging.
166  * When debugging is on ("set -o debug" was executed, or DEBUG=2),
167  * debugging info is written to ./trace, quit signal generates core dump.
168  */
169 #define DEBUG 0
170 /* Tweak debug output verbosity here */
171 #define DEBUG_TIME 0
172 #define DEBUG_PID 1
173 #define DEBUG_SIG 1
174 #define DEBUG_INTONOFF 0
175
176 #define PROFILE 0
177
178 #define JOBS ENABLE_ASH_JOB_CONTROL
179
180 #include <fnmatch.h>
181 #include <sys/times.h>
182 #include <sys/utsname.h> /* for setting $HOSTNAME */
183 #include "busybox.h" /* for applet_names */
184 #if ENABLE_FEATURE_SH_EMBEDDED_SCRIPTS
185 # include "embedded_scripts.h"
186 #else
187 # define NUM_SCRIPTS 0
188 #endif
189
190 /* So far, all bash compat is controlled by one config option */
191 /* Separate defines document which part of code implements what */
192 /* function keyword */
193 #define    BASH_FUNCTION        ENABLE_ASH_BASH_COMPAT
194 #define IF_BASH_FUNCTION            IF_ASH_BASH_COMPAT
195 /* &>file */
196 #define    BASH_REDIR_OUTPUT    ENABLE_ASH_BASH_COMPAT
197 #define IF_BASH_REDIR_OUTPUT        IF_ASH_BASH_COMPAT
198 /* $'...' */
199 #define    BASH_DOLLAR_SQUOTE   ENABLE_ASH_BASH_COMPAT
200 #define IF_BASH_DOLLAR_SQUOTE       IF_ASH_BASH_COMPAT
201 #define    BASH_PATTERN_SUBST   ENABLE_ASH_BASH_COMPAT
202 #define IF_BASH_PATTERN_SUBST       IF_ASH_BASH_COMPAT
203 #define    BASH_SUBSTR          ENABLE_ASH_BASH_COMPAT
204 #define IF_BASH_SUBSTR              IF_ASH_BASH_COMPAT
205 /* BASH_TEST2: [[ EXPR ]]
206  * Status of [[ support:
207  * We replace && and || with -a and -o
208  * TODO:
209  * singleword+noglob expansion:
210  *   v='a b'; [[ $v = 'a b' ]]; echo 0:$?
211  *   [[ /bin/n* ]]; echo 0:$?
212  * -a/-o are not AND/OR ops! (they are just strings)
213  * quoting needs to be considered (-f is an operator, "-f" and ""-f are not; etc)
214  * = is glob match operator, not equality operator: STR = GLOB
215  * (in GLOB, quoting is significant on char-by-char basis: a*cd"*")
216  * == same as =
217  * add =~ regex match operator: STR =~ REGEX
218  */
219 #define    BASH_TEST2           (ENABLE_ASH_BASH_COMPAT * ENABLE_ASH_TEST)
220 #define    BASH_SOURCE          ENABLE_ASH_BASH_COMPAT
221 #define    BASH_PIPEFAIL        ENABLE_ASH_BASH_COMPAT
222 #define    BASH_HOSTNAME_VAR    ENABLE_ASH_BASH_COMPAT
223 #define    BASH_SHLVL_VAR       ENABLE_ASH_BASH_COMPAT
224 #define    BASH_XTRACEFD        ENABLE_ASH_BASH_COMPAT
225 #define    BASH_READ_D          ENABLE_ASH_BASH_COMPAT
226 #define IF_BASH_READ_D              IF_ASH_BASH_COMPAT
227
228 #if defined(__ANDROID_API__) && __ANDROID_API__ <= 24
229 /* Bionic at least up to version 24 has no glob() */
230 # undef  ENABLE_ASH_INTERNAL_GLOB
231 # define ENABLE_ASH_INTERNAL_GLOB 1
232 #endif
233
234 #if !ENABLE_ASH_INTERNAL_GLOB && defined(__UCLIBC__)
235 # error uClibc glob() is buggy, use ASH_INTERNAL_GLOB.
236 # error The bug is: for "$PWD"/<pattern> ash will escape e.g. dashes in "$PWD"
237 # error with backslash, even ones which do not need to be: "/a-b" -> "/a\-b"
238 # error glob() should unbackslash them and match. uClibc does not unbackslash,
239 # error fails to match dirname, subsequently not expanding <pattern> in it.
240 // Testcase:
241 // if (glob("/etc/polkit\\-1", 0, NULL, &pglob)) - this returns 0 on uclibc, no bug
242 // if (glob("/etc/polkit\\-1/*", 0, NULL, &pglob)) printf("uclibc bug!\n");
243 #endif
244
245 #if !ENABLE_ASH_INTERNAL_GLOB
246 # include <glob.h>
247 #endif
248
249 #include "unicode.h"
250 #include "shell_common.h"
251 #if ENABLE_FEATURE_SH_MATH
252 # include "math.h"
253 #else
254 typedef long arith_t;
255 # define ARITH_FMT "%ld"
256 #endif
257 #if ENABLE_ASH_RANDOM_SUPPORT
258 # include "random.h"
259 #else
260 # define CLEAR_RANDOM_T(rnd) ((void)0)
261 #endif
262
263 #include "NUM_APPLETS.h"
264 #if NUM_APPLETS == 1
265 /* STANDALONE does not make sense, and won't compile */
266 # undef CONFIG_FEATURE_SH_STANDALONE
267 # undef ENABLE_FEATURE_SH_STANDALONE
268 # undef IF_FEATURE_SH_STANDALONE
269 # undef IF_NOT_FEATURE_SH_STANDALONE
270 # define ENABLE_FEATURE_SH_STANDALONE 0
271 # define IF_FEATURE_SH_STANDALONE(...)
272 # define IF_NOT_FEATURE_SH_STANDALONE(...) __VA_ARGS__
273 #endif
274
275 #ifndef F_DUPFD_CLOEXEC
276 # define F_DUPFD_CLOEXEC F_DUPFD
277 #endif
278 #ifndef O_CLOEXEC
279 # define O_CLOEXEC 0
280 #endif
281 #ifndef PIPE_BUF
282 # define PIPE_BUF 4096           /* amount of buffering in a pipe */
283 #endif
284
285 #if !BB_MMU
286 # error "Do not even bother, ash will not run on NOMMU machine"
287 #endif
288
289 /* We use a trick to have more optimized code (fewer pointer reloads):
290  *  ash.c:   extern struct globals *const ash_ptr_to_globals;
291  *  ash_ptr_hack.c: struct globals *ash_ptr_to_globals;
292  * This way, compiler in ash.c knows the pointer can not change.
293  *
294  * However, this may break on weird arches or toolchains. In this case,
295  * set "-DBB_GLOBAL_CONST=''" in CONFIG_EXTRA_CFLAGS to disable
296  * this optimization.
297  */
298 #ifndef BB_GLOBAL_CONST
299 # define BB_GLOBAL_CONST const
300 #endif
301
302
303 /* ============ Hash table sizes. Configurable. */
304
305 #define VTABSIZE 39
306 #define ATABSIZE 39
307 #define CMDTABLESIZE 31         /* should be prime */
308
309
310 /* ============ Shell options */
311
312 static const char *const optletters_optnames[] = {
313         "e"   "errexit",
314         "f"   "noglob",
315         "I"   "ignoreeof",
316         "i"   "interactive",
317         "m"   "monitor",
318         "n"   "noexec",
319         "s"   "stdin",
320         "x"   "xtrace",
321         "v"   "verbose",
322         "C"   "noclobber",
323         "a"   "allexport",
324         "b"   "notify",
325         "u"   "nounset",
326         "\0"  "vi"
327 #if BASH_PIPEFAIL
328         ,"\0"  "pipefail"
329 #endif
330 #if DEBUG
331         ,"\0"  "nolog"
332         ,"\0"  "debug"
333 #endif
334 };
335
336 #define optletters(n)  optletters_optnames[n][0]
337 #define optnames(n)   (optletters_optnames[n] + 1)
338
339 enum { NOPTS = ARRAY_SIZE(optletters_optnames) };
340
341
342 /* ============ Misc data */
343
344 #define msg_illnum "Illegal number: %s"
345
346 /*
347  * We enclose jmp_buf in a structure so that we can declare pointers to
348  * jump locations.  The global variable handler contains the location to
349  * jump to when an exception occurs, and the global variable exception_type
350  * contains a code identifying the exception.  To implement nested
351  * exception handlers, the user should save the value of handler on entry
352  * to an inner scope, set handler to point to a jmploc structure for the
353  * inner scope, and restore handler on exit from the scope.
354  */
355 struct jmploc {
356         jmp_buf loc;
357 };
358
359 struct globals_misc {
360         uint8_t exitstatus;     /* exit status of last command */
361         uint8_t back_exitstatus;/* exit status of backquoted command */
362         smallint job_warning;   /* user was warned about stopped jobs (can be 2, 1 or 0). */
363         int rootpid;            /* pid of main shell */
364         /* shell level: 0 for the main shell, 1 for its children, and so on */
365         int shlvl;
366 #define rootshell (!shlvl)
367         int errlinno;
368
369         char *minusc;  /* argument to -c option */
370
371         char *curdir; // = nullstr;     /* current working directory */
372         char *physdir; // = nullstr;    /* physical working directory */
373
374         char *arg0; /* value of $0 */
375
376         struct jmploc *exception_handler;
377
378         volatile int suppress_int; /* counter */
379         volatile /*sig_atomic_t*/ smallint pending_int; /* 1 = got SIGINT */
380         volatile /*sig_atomic_t*/ smallint got_sigchld; /* 1 = got SIGCHLD */
381         volatile /*sig_atomic_t*/ smallint pending_sig; /* last pending signal */
382         smallint exception_type; /* kind of exception (0..5) */
383         /* exceptions */
384 #define EXINT 0         /* SIGINT received */
385 #define EXERROR 1       /* a generic error */
386 #define EXEXIT 4        /* exit the shell */
387
388         char nullstr[1];        /* zero length string */
389
390         char optlist[NOPTS];
391 #define eflag optlist[0]
392 #define fflag optlist[1]
393 #define Iflag optlist[2]
394 #define iflag optlist[3]
395 #define mflag optlist[4]
396 #define nflag optlist[5]
397 #define sflag optlist[6]
398 #define xflag optlist[7]
399 #define vflag optlist[8]
400 #define Cflag optlist[9]
401 #define aflag optlist[10]
402 #define bflag optlist[11]
403 #define uflag optlist[12]
404 #define viflag optlist[13]
405 #if BASH_PIPEFAIL
406 # define pipefail optlist[14]
407 #else
408 # define pipefail 0
409 #endif
410 #if DEBUG
411 # define nolog optlist[14 + BASH_PIPEFAIL]
412 # define debug optlist[15 + BASH_PIPEFAIL]
413 #endif
414
415         /* trap handler commands */
416         /*
417          * Sigmode records the current value of the signal handlers for the various
418          * modes.  A value of zero means that the current handler is not known.
419          * S_HARD_IGN indicates that the signal was ignored on entry to the shell.
420          */
421         char sigmode[NSIG - 1];
422 #define S_DFL      1            /* default signal handling (SIG_DFL) */
423 #define S_CATCH    2            /* signal is caught */
424 #define S_IGN      3            /* signal is ignored (SIG_IGN) */
425 #define S_HARD_IGN 4            /* signal is ignored permanently (it was SIG_IGN on entry to shell) */
426
427         /* indicates specified signal received */
428         uint8_t gotsig[NSIG - 1]; /* offset by 1: "signal" 0 is meaningless */
429         uint8_t may_have_traps; /* 0: definitely no traps are set, 1: some traps may be set */
430         char *trap[NSIG];
431         char **trap_ptr;        /* used only by "trap hack" */
432
433         /* Rarely referenced stuff */
434 #if ENABLE_ASH_RANDOM_SUPPORT
435         random_t random_gen;
436 #endif
437         pid_t backgndpid;        /* pid of last background process */
438 };
439 extern struct globals_misc *BB_GLOBAL_CONST ash_ptr_to_globals_misc;
440 #define G_misc (*ash_ptr_to_globals_misc)
441 #define exitstatus        (G_misc.exitstatus )
442 #define back_exitstatus   (G_misc.back_exitstatus )
443 #define job_warning       (G_misc.job_warning)
444 #define rootpid     (G_misc.rootpid    )
445 #define shlvl       (G_misc.shlvl      )
446 #define errlinno    (G_misc.errlinno   )
447 #define minusc      (G_misc.minusc     )
448 #define curdir      (G_misc.curdir     )
449 #define physdir     (G_misc.physdir    )
450 #define arg0        (G_misc.arg0       )
451 #define exception_handler (G_misc.exception_handler)
452 #define exception_type    (G_misc.exception_type   )
453 #define suppress_int      (G_misc.suppress_int     )
454 #define pending_int       (G_misc.pending_int      )
455 #define got_sigchld       (G_misc.got_sigchld      )
456 #define pending_sig       (G_misc.pending_sig      )
457 #define nullstr     (G_misc.nullstr    )
458 #define optlist     (G_misc.optlist    )
459 #define sigmode     (G_misc.sigmode    )
460 #define gotsig      (G_misc.gotsig     )
461 #define may_have_traps    (G_misc.may_have_traps   )
462 #define trap        (G_misc.trap       )
463 #define trap_ptr    (G_misc.trap_ptr   )
464 #define random_gen  (G_misc.random_gen )
465 #define backgndpid  (G_misc.backgndpid )
466 #define INIT_G_misc() do { \
467         (*(struct globals_misc**)&ash_ptr_to_globals_misc) = xzalloc(sizeof(G_misc)); \
468         barrier(); \
469         curdir = nullstr; \
470         physdir = nullstr; \
471         trap_ptr = trap; \
472 } while (0)
473
474
475 /* ============ DEBUG */
476 #if DEBUG
477 static void trace_printf(const char *fmt, ...);
478 static void trace_vprintf(const char *fmt, va_list va);
479 # define TRACE(param)    trace_printf param
480 # define TRACEV(param)   trace_vprintf param
481 # define close(fd) do { \
482         int dfd = (fd); \
483         if (close(dfd) < 0) \
484                 bb_error_msg("bug on %d: closing %d(0x%x)", \
485                         __LINE__, dfd, dfd); \
486 } while (0)
487 #else
488 # define TRACE(param)
489 # define TRACEV(param)
490 #endif
491
492
493 /* ============ Utility functions */
494 #define is_name(c)      ((c) == '_' || isalpha((unsigned char)(c)))
495 #define is_in_name(c)   ((c) == '_' || isalnum((unsigned char)(c)))
496
497 static int
498 isdigit_str9(const char *str)
499 {
500         int maxlen = 9 + 1; /* max 9 digits: 999999999 */
501         while (--maxlen && isdigit(*str))
502                 str++;
503         return (*str == '\0');
504 }
505
506 static const char *
507 var_end(const char *var)
508 {
509         while (*var)
510                 if (*var++ == '=')
511                         break;
512         return var;
513 }
514
515
516 /* ============ Interrupts / exceptions */
517
518 static void exitshell(void) NORETURN;
519
520 /*
521  * These macros allow the user to suspend the handling of interrupt signals
522  * over a period of time.  This is similar to SIGHOLD or to sigblock, but
523  * much more efficient and portable.  (But hacking the kernel is so much
524  * more fun than worrying about efficiency and portability. :-))
525  */
526 #if DEBUG_INTONOFF
527 # define INT_OFF do { \
528         TRACE(("%s:%d INT_OFF(%d)\n", __func__, __LINE__, suppress_int)); \
529         suppress_int++; \
530         barrier(); \
531 } while (0)
532 #else
533 # define INT_OFF do { \
534         suppress_int++; \
535         barrier(); \
536 } while (0)
537 #endif
538
539 /*
540  * Called to raise an exception.  Since C doesn't include exceptions, we
541  * just do a longjmp to the exception handler.  The type of exception is
542  * stored in the global variable "exception_type".
543  */
544 static void raise_exception(int) NORETURN;
545 static void
546 raise_exception(int e)
547 {
548 #if DEBUG
549         if (exception_handler == NULL)
550                 abort();
551 #endif
552         INT_OFF;
553         exception_type = e;
554         longjmp(exception_handler->loc, 1);
555 }
556 #if DEBUG
557 #define raise_exception(e) do { \
558         TRACE(("raising exception %d on line %d\n", (e), __LINE__)); \
559         raise_exception(e); \
560 } while (0)
561 #endif
562
563 /*
564  * Called when a SIGINT is received.  (If the user specifies
565  * that SIGINT is to be trapped or ignored using the trap builtin, then
566  * this routine is not called.)  Suppressint is nonzero when interrupts
567  * are held using the INT_OFF macro.  (The test for iflag is just
568  * defensive programming.)
569  */
570 static void raise_interrupt(void) NORETURN;
571 static void
572 raise_interrupt(void)
573 {
574         pending_int = 0;
575         /* Signal is not automatically unmasked after it is raised,
576          * do it ourself - unmask all signals */
577         sigprocmask_allsigs(SIG_UNBLOCK);
578         /* pending_sig = 0; - now done in signal_handler() */
579
580         if (!(rootshell && iflag)) {
581                 /* Kill ourself with SIGINT */
582                 signal(SIGINT, SIG_DFL);
583                 raise(SIGINT);
584         }
585         /* bash: ^C even on empty command line sets $? */
586         exitstatus = SIGINT + 128;
587         raise_exception(EXINT);
588         /* NOTREACHED */
589 }
590 #if DEBUG
591 #define raise_interrupt() do { \
592         TRACE(("raising interrupt on line %d\n", __LINE__)); \
593         raise_interrupt(); \
594 } while (0)
595 #endif
596
597 static IF_ASH_OPTIMIZE_FOR_SIZE(inline) void
598 int_on(void)
599 {
600         barrier();
601         if (--suppress_int == 0 && pending_int) {
602                 raise_interrupt();
603         }
604 }
605 #if DEBUG_INTONOFF
606 # define INT_ON do { \
607         TRACE(("%s:%d INT_ON(%d)\n", __func__, __LINE__, suppress_int-1)); \
608         int_on(); \
609 } while (0)
610 #else
611 # define INT_ON int_on()
612 #endif
613 static IF_ASH_OPTIMIZE_FOR_SIZE(inline) void
614 force_int_on(void)
615 {
616         barrier();
617         suppress_int = 0;
618         if (pending_int)
619                 raise_interrupt();
620 }
621 #define FORCE_INT_ON force_int_on()
622
623 #define SAVE_INT(v) ((v) = suppress_int)
624
625 #define RESTORE_INT(v) do { \
626         barrier(); \
627         suppress_int = (v); \
628         if (suppress_int == 0 && pending_int) \
629                 raise_interrupt(); \
630 } while (0)
631
632
633 /* ============ Stdout/stderr output */
634
635 static void
636 outstr(const char *p, FILE *file)
637 {
638         INT_OFF;
639         fputs(p, file);
640         INT_ON;
641 }
642
643 static void
644 flush_stdout_stderr(void)
645 {
646         INT_OFF;
647         fflush_all();
648         INT_ON;
649 }
650
651 /* Was called outcslow(c,FILE*), but c was always '\n' */
652 static void
653 newline_and_flush(FILE *dest)
654 {
655         INT_OFF;
656         putc('\n', dest);
657         fflush(dest);
658         INT_ON;
659 }
660
661 static int out1fmt(const char *, ...) __attribute__((__format__(__printf__,1,2)));
662 static int
663 out1fmt(const char *fmt, ...)
664 {
665         va_list ap;
666         int r;
667
668         INT_OFF;
669         va_start(ap, fmt);
670         r = vprintf(fmt, ap);
671         va_end(ap);
672         INT_ON;
673         return r;
674 }
675
676 static int fmtstr(char *, size_t, const char *, ...) __attribute__((__format__(__printf__,3,4)));
677 static int
678 fmtstr(char *outbuf, size_t length, const char *fmt, ...)
679 {
680         va_list ap;
681         int ret;
682
683         INT_OFF;
684         va_start(ap, fmt);
685         ret = vsnprintf(outbuf, length, fmt, ap);
686         va_end(ap);
687         INT_ON;
688         return ret;
689 }
690
691 static void
692 out1str(const char *p)
693 {
694         outstr(p, stdout);
695 }
696
697 static void
698 out2str(const char *p)
699 {
700         outstr(p, stderr);
701         flush_stdout_stderr();
702 }
703
704
705 /* ============ Parser structures */
706
707 /* control characters in argument strings */
708 #define CTL_FIRST CTLESC
709 #define CTLESC       ((unsigned char)'\201')    /* escape next character */
710 #define CTLVAR       ((unsigned char)'\202')    /* variable defn */
711 #define CTLENDVAR    ((unsigned char)'\203')
712 #define CTLBACKQ     ((unsigned char)'\204')
713 #define CTLARI       ((unsigned char)'\206')    /* arithmetic expression */
714 #define CTLENDARI    ((unsigned char)'\207')
715 #define CTLQUOTEMARK ((unsigned char)'\210')
716 #define CTL_LAST CTLQUOTEMARK
717
718 /* variable substitution byte (follows CTLVAR) */
719 #define VSTYPE  0x0f            /* type of variable substitution */
720 #define VSNUL   0x10            /* colon--treat the empty string as unset */
721
722 /* values of VSTYPE field */
723 #define VSNORMAL        0x1     /* normal variable:  $var or ${var} */
724 #define VSMINUS         0x2     /* ${var-text} */
725 #define VSPLUS          0x3     /* ${var+text} */
726 #define VSQUESTION      0x4     /* ${var?message} */
727 #define VSASSIGN        0x5     /* ${var=text} */
728 #define VSTRIMRIGHT     0x6     /* ${var%pattern} */
729 #define VSTRIMRIGHTMAX  0x7     /* ${var%%pattern} */
730 #define VSTRIMLEFT      0x8     /* ${var#pattern} */
731 #define VSTRIMLEFTMAX   0x9     /* ${var##pattern} */
732 #define VSLENGTH        0xa     /* ${#var} */
733 #if BASH_SUBSTR
734 #define VSSUBSTR        0xc     /* ${var:position:length} */
735 #endif
736 #if BASH_PATTERN_SUBST
737 #define VSREPLACE       0xd     /* ${var/pattern/replacement} */
738 #define VSREPLACEALL    0xe     /* ${var//pattern/replacement} */
739 #endif
740
741 static const char dolatstr[] ALIGN1 = {
742         CTLQUOTEMARK, CTLVAR, VSNORMAL, '@', '=', CTLQUOTEMARK, '\0'
743 };
744 #define DOLATSTRLEN 6
745
746 #define NCMD      0
747 #define NPIPE     1
748 #define NREDIR    2
749 #define NBACKGND  3
750 #define NSUBSHELL 4
751 #define NAND      5
752 #define NOR       6
753 #define NSEMI     7
754 #define NIF       8
755 #define NWHILE    9
756 #define NUNTIL   10
757 #define NFOR     11
758 #define NCASE    12
759 #define NCLIST   13
760 #define NDEFUN   14
761 #define NARG     15
762 #define NTO      16
763 #if BASH_REDIR_OUTPUT
764 #define NTO2     17
765 #endif
766 #define NCLOBBER 18
767 #define NFROM    19
768 #define NFROMTO  20
769 #define NAPPEND  21
770 #define NTOFD    22
771 #define NFROMFD  23
772 #define NHERE    24
773 #define NXHERE   25
774 #define NNOT     26
775 #define N_NUMBER 27
776
777 union node;
778
779 struct ncmd {
780         smallint type; /* Nxxxx */
781         int linno;
782         union node *assign;
783         union node *args;
784         union node *redirect;
785 };
786
787 struct npipe {
788         smallint type;
789         smallint pipe_backgnd;
790         struct nodelist *cmdlist;
791 };
792
793 struct nredir {
794         smallint type;
795         int linno;
796         union node *n;
797         union node *redirect;
798 };
799
800 struct nbinary {
801         smallint type;
802         union node *ch1;
803         union node *ch2;
804 };
805
806 struct nif {
807         smallint type;
808         union node *test;
809         union node *ifpart;
810         union node *elsepart;
811 };
812
813 struct nfor {
814         smallint type;
815         int linno;
816         union node *args;
817         union node *body;
818         char *var;
819 };
820
821 struct ncase {
822         smallint type;
823         int linno;
824         union node *expr;
825         union node *cases;
826 };
827
828 struct nclist {
829         smallint type;
830         union node *next;
831         union node *pattern;
832         union node *body;
833 };
834
835 struct ndefun {
836         smallint type;
837         int linno;
838         char *text;
839         union node *body;
840 };
841
842 struct narg {
843         smallint type;
844         union node *next;
845         char *text;
846         struct nodelist *backquote;
847 };
848
849 /* nfile and ndup layout must match!
850  * NTOFD (>&fdnum) uses ndup structure, but we may discover mid-flight
851  * that it is actually NTO2 (>&file), and change its type.
852  */
853 struct nfile {
854         smallint type;
855         union node *next;
856         int fd;
857         int _unused_dupfd;
858         union node *fname;
859         char *expfname;
860 };
861
862 struct ndup {
863         smallint type;
864         union node *next;
865         int fd;
866         int dupfd;
867         union node *vname;
868         char *_unused_expfname;
869 };
870
871 struct nhere {
872         smallint type;
873         union node *next;
874         int fd;
875         union node *doc;
876 };
877
878 struct nnot {
879         smallint type;
880         union node *com;
881 };
882
883 union node {
884         smallint type;
885         struct ncmd ncmd;
886         struct npipe npipe;
887         struct nredir nredir;
888         struct nbinary nbinary;
889         struct nif nif;
890         struct nfor nfor;
891         struct ncase ncase;
892         struct nclist nclist;
893         struct ndefun ndefun;
894         struct narg narg;
895         struct nfile nfile;
896         struct ndup ndup;
897         struct nhere nhere;
898         struct nnot nnot;
899 };
900
901 /*
902  * NODE_EOF is returned by parsecmd when it encounters an end of file.
903  * It must be distinct from NULL.
904  */
905 #define NODE_EOF ((union node *) -1L)
906
907 struct nodelist {
908         struct nodelist *next;
909         union node *n;
910 };
911
912 struct funcnode {
913         int count;
914         union node n;
915 };
916
917 /*
918  * Free a parse tree.
919  */
920 static void
921 freefunc(struct funcnode *f)
922 {
923         if (f && --f->count < 0)
924                 free(f);
925 }
926
927
928 /* ============ Debugging output */
929
930 #if DEBUG
931
932 static FILE *tracefile;
933
934 static void
935 trace_printf(const char *fmt, ...)
936 {
937         va_list va;
938
939         if (debug != 1)
940                 return;
941         if (DEBUG_TIME)
942                 fprintf(tracefile, "%u ", (int) time(NULL));
943         if (DEBUG_PID)
944                 fprintf(tracefile, "[%u] ", (int) getpid());
945         if (DEBUG_SIG)
946                 fprintf(tracefile, "pending s:%d i:%d(supp:%d) ", pending_sig, pending_int, suppress_int);
947         va_start(va, fmt);
948         vfprintf(tracefile, fmt, va);
949         va_end(va);
950 }
951
952 static void
953 trace_vprintf(const char *fmt, va_list va)
954 {
955         if (debug != 1)
956                 return;
957         vfprintf(tracefile, fmt, va);
958         fprintf(tracefile, "\n");
959 }
960
961 static void
962 trace_puts(const char *s)
963 {
964         if (debug != 1)
965                 return;
966         fputs(s, tracefile);
967 }
968
969 static void
970 trace_puts_quoted(char *s)
971 {
972         char *p;
973         char c;
974
975         if (debug != 1)
976                 return;
977         putc('"', tracefile);
978         for (p = s; *p; p++) {
979                 switch ((unsigned char)*p) {
980                 case '\n': c = 'n'; goto backslash;
981                 case '\t': c = 't'; goto backslash;
982                 case '\r': c = 'r'; goto backslash;
983                 case '\"': c = '\"'; goto backslash;
984                 case '\\': c = '\\'; goto backslash;
985                 case CTLESC: c = 'e'; goto backslash;
986                 case CTLVAR: c = 'v'; goto backslash;
987                 case CTLBACKQ: c = 'q'; goto backslash;
988  backslash:
989                         putc('\\', tracefile);
990                         putc(c, tracefile);
991                         break;
992                 default:
993                         if (*p >= ' ' && *p <= '~')
994                                 putc(*p, tracefile);
995                         else {
996                                 putc('\\', tracefile);
997                                 putc((*p >> 6) & 03, tracefile);
998                                 putc((*p >> 3) & 07, tracefile);
999                                 putc(*p & 07, tracefile);
1000                         }
1001                         break;
1002                 }
1003         }
1004         putc('"', tracefile);
1005 }
1006
1007 static void
1008 trace_puts_args(char **ap)
1009 {
1010         if (debug != 1)
1011                 return;
1012         if (!*ap)
1013                 return;
1014         while (1) {
1015                 trace_puts_quoted(*ap);
1016                 if (!*++ap) {
1017                         putc('\n', tracefile);
1018                         break;
1019                 }
1020                 putc(' ', tracefile);
1021         }
1022 }
1023
1024 static void
1025 opentrace(void)
1026 {
1027         char s[100];
1028 #ifdef O_APPEND
1029         int flags;
1030 #endif
1031
1032         if (debug != 1) {
1033                 if (tracefile)
1034                         fflush(tracefile);
1035                 /* leave open because libedit might be using it */
1036                 return;
1037         }
1038         strcpy(s, "./trace");
1039         if (tracefile) {
1040                 if (!freopen(s, "a", tracefile)) {
1041                         fprintf(stderr, "Can't re-open %s\n", s);
1042                         debug = 0;
1043                         return;
1044                 }
1045         } else {
1046                 tracefile = fopen(s, "a");
1047                 if (tracefile == NULL) {
1048                         fprintf(stderr, "Can't open %s\n", s);
1049                         debug = 0;
1050                         return;
1051                 }
1052         }
1053 #ifdef O_APPEND
1054         flags = fcntl(fileno(tracefile), F_GETFL);
1055         if (flags >= 0)
1056                 fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND);
1057 #endif
1058         setlinebuf(tracefile);
1059         fputs("\nTracing started.\n", tracefile);
1060 }
1061
1062 static void
1063 indent(int amount, char *pfx, FILE *fp)
1064 {
1065         int i;
1066
1067         for (i = 0; i < amount; i++) {
1068                 if (pfx && i == amount - 1)
1069                         fputs(pfx, fp);
1070                 putc('\t', fp);
1071         }
1072 }
1073
1074 /* little circular references here... */
1075 static void shtree(union node *n, int ind, char *pfx, FILE *fp);
1076
1077 static void
1078 sharg(union node *arg, FILE *fp)
1079 {
1080         char *p;
1081         struct nodelist *bqlist;
1082         unsigned char subtype;
1083
1084         if (arg->type != NARG) {
1085                 out1fmt("<node type %d>\n", arg->type);
1086                 abort();
1087         }
1088         bqlist = arg->narg.backquote;
1089         for (p = arg->narg.text; *p; p++) {
1090                 switch ((unsigned char)*p) {
1091                 case CTLESC:
1092                         p++;
1093                         putc(*p, fp);
1094                         break;
1095                 case CTLVAR:
1096                         putc('$', fp);
1097                         putc('{', fp);
1098                         subtype = *++p;
1099                         if (subtype == VSLENGTH)
1100                                 putc('#', fp);
1101
1102                         while (*p != '=') {
1103                                 putc(*p, fp);
1104                                 p++;
1105                         }
1106
1107                         if (subtype & VSNUL)
1108                                 putc(':', fp);
1109
1110                         switch (subtype & VSTYPE) {
1111                         case VSNORMAL:
1112                                 putc('}', fp);
1113                                 break;
1114                         case VSMINUS:
1115                                 putc('-', fp);
1116                                 break;
1117                         case VSPLUS:
1118                                 putc('+', fp);
1119                                 break;
1120                         case VSQUESTION:
1121                                 putc('?', fp);
1122                                 break;
1123                         case VSASSIGN:
1124                                 putc('=', fp);
1125                                 break;
1126                         case VSTRIMLEFT:
1127                                 putc('#', fp);
1128                                 break;
1129                         case VSTRIMLEFTMAX:
1130                                 putc('#', fp);
1131                                 putc('#', fp);
1132                                 break;
1133                         case VSTRIMRIGHT:
1134                                 putc('%', fp);
1135                                 break;
1136                         case VSTRIMRIGHTMAX:
1137                                 putc('%', fp);
1138                                 putc('%', fp);
1139                                 break;
1140                         case VSLENGTH:
1141                                 break;
1142                         default:
1143                                 out1fmt("<subtype %d>", subtype);
1144                         }
1145                         break;
1146                 case CTLENDVAR:
1147                         putc('}', fp);
1148                         break;
1149                 case CTLBACKQ:
1150                         putc('$', fp);
1151                         putc('(', fp);
1152                         shtree(bqlist->n, -1, NULL, fp);
1153                         putc(')', fp);
1154                         break;
1155                 default:
1156                         putc(*p, fp);
1157                         break;
1158                 }
1159         }
1160 }
1161
1162 static void
1163 shcmd(union node *cmd, FILE *fp)
1164 {
1165         union node *np;
1166         int first;
1167         const char *s;
1168         int dftfd;
1169
1170         first = 1;
1171         for (np = cmd->ncmd.args; np; np = np->narg.next) {
1172                 if (!first)
1173                         putc(' ', fp);
1174                 sharg(np, fp);
1175                 first = 0;
1176         }
1177         for (np = cmd->ncmd.redirect; np; np = np->nfile.next) {
1178                 if (!first)
1179                         putc(' ', fp);
1180                 dftfd = 0;
1181                 switch (np->nfile.type) {
1182                 case NTO:      s = ">>"+1; dftfd = 1; break;
1183                 case NCLOBBER: s = ">|"; dftfd = 1; break;
1184                 case NAPPEND:  s = ">>"; dftfd = 1; break;
1185 #if BASH_REDIR_OUTPUT
1186                 case NTO2:
1187 #endif
1188                 case NTOFD:    s = ">&"; dftfd = 1; break;
1189                 case NFROM:    s = "<"; break;
1190                 case NFROMFD:  s = "<&"; break;
1191                 case NFROMTO:  s = "<>"; break;
1192                 default:       s = "*error*"; break;
1193                 }
1194                 if (np->nfile.fd != dftfd)
1195                         fprintf(fp, "%d", np->nfile.fd);
1196                 fputs(s, fp);
1197                 if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) {
1198                         fprintf(fp, "%d", np->ndup.dupfd);
1199                 } else {
1200                         sharg(np->nfile.fname, fp);
1201                 }
1202                 first = 0;
1203         }
1204 }
1205
1206 static void
1207 shtree(union node *n, int ind, char *pfx, FILE *fp)
1208 {
1209         struct nodelist *lp;
1210         const char *s;
1211
1212         if (n == NULL)
1213                 return;
1214
1215         indent(ind, pfx, fp);
1216
1217         if (n == NODE_EOF) {
1218                 fputs("<EOF>", fp);
1219                 return;
1220         }
1221
1222         switch (n->type) {
1223         case NSEMI:
1224                 s = "; ";
1225                 goto binop;
1226         case NAND:
1227                 s = " && ";
1228                 goto binop;
1229         case NOR:
1230                 s = " || ";
1231  binop:
1232                 shtree(n->nbinary.ch1, ind, NULL, fp);
1233                 /* if (ind < 0) */
1234                         fputs(s, fp);
1235                 shtree(n->nbinary.ch2, ind, NULL, fp);
1236                 break;
1237         case NCMD:
1238                 shcmd(n, fp);
1239                 if (ind >= 0)
1240                         putc('\n', fp);
1241                 break;
1242         case NPIPE:
1243                 for (lp = n->npipe.cmdlist; lp; lp = lp->next) {
1244                         shtree(lp->n, 0, NULL, fp);
1245                         if (lp->next)
1246                                 fputs(" | ", fp);
1247                 }
1248                 if (n->npipe.pipe_backgnd)
1249                         fputs(" &", fp);
1250                 if (ind >= 0)
1251                         putc('\n', fp);
1252                 break;
1253         default:
1254                 fprintf(fp, "<node type %d>", n->type);
1255                 if (ind >= 0)
1256                         putc('\n', fp);
1257                 break;
1258         }
1259 }
1260
1261 static void
1262 showtree(union node *n)
1263 {
1264         trace_puts("showtree called\n");
1265         shtree(n, 1, NULL, stderr);
1266 }
1267
1268 #endif /* DEBUG */
1269
1270
1271 /* ============ Parser data */
1272
1273 /*
1274  * ash_vmsg() needs parsefile->fd, hence parsefile definition is moved up.
1275  */
1276 struct strlist {
1277         struct strlist *next;
1278         char *text;
1279 };
1280
1281 struct alias;
1282
1283 struct strpush {
1284         struct strpush *prev;   /* preceding string on stack */
1285         char *prev_string;
1286         int prev_left_in_line;
1287 #if ENABLE_ASH_ALIAS
1288         struct alias *ap;       /* if push was associated with an alias */
1289 #endif
1290         char *string;           /* remember the string since it may change */
1291
1292         /* Remember last two characters for pungetc. */
1293         int lastc[2];
1294
1295         /* Number of outstanding calls to pungetc. */
1296         int unget;
1297 };
1298
1299 /*
1300  * The parsefile structure pointed to by the global variable parsefile
1301  * contains information about the current file being read.
1302  */
1303 struct parsefile {
1304         struct parsefile *prev; /* preceding file on stack */
1305         int linno;              /* current line */
1306         int pf_fd;              /* file descriptor (or -1 if string) */
1307         int left_in_line;       /* number of chars left in this line */
1308         int left_in_buffer;     /* number of chars left in this buffer past the line */
1309         char *next_to_pgetc;    /* next char in buffer */
1310         char *buf;              /* input buffer */
1311         struct strpush *strpush; /* for pushing strings at this level */
1312         struct strpush basestrpush; /* so pushing one is fast */
1313
1314         /* Remember last two characters for pungetc. */
1315         int lastc[2];
1316
1317         /* Number of outstanding calls to pungetc. */
1318         int unget;
1319 };
1320
1321 static struct parsefile basepf;        /* top level input file */
1322 static struct parsefile *g_parsefile = &basepf;  /* current input file */
1323 static char *commandname;              /* currently executing command */
1324
1325
1326 /* ============ Message printing */
1327
1328 static void
1329 ash_vmsg(const char *msg, va_list ap)
1330 {
1331         fprintf(stderr, "%s: ", arg0);
1332         if (commandname) {
1333                 if (strcmp(arg0, commandname))
1334                         fprintf(stderr, "%s: ", commandname);
1335                 if (!iflag || g_parsefile->pf_fd > 0)
1336                         fprintf(stderr, "line %d: ", errlinno);
1337         }
1338         vfprintf(stderr, msg, ap);
1339         newline_and_flush(stderr);
1340 }
1341
1342 /*
1343  * Exverror is called to raise the error exception.  If the second argument
1344  * is not NULL then error prints an error message using printf style
1345  * formatting.  It then raises the error exception.
1346  */
1347 static void ash_vmsg_and_raise(int, const char *, va_list) NORETURN;
1348 static void
1349 ash_vmsg_and_raise(int cond, const char *msg, va_list ap)
1350 {
1351 #if DEBUG
1352         if (msg) {
1353                 TRACE(("ash_vmsg_and_raise(%d):", cond));
1354                 TRACEV((msg, ap));
1355         } else
1356                 TRACE(("ash_vmsg_and_raise(%d):NULL\n", cond));
1357         if (msg)
1358 #endif
1359                 ash_vmsg(msg, ap);
1360
1361         flush_stdout_stderr();
1362         raise_exception(cond);
1363         /* NOTREACHED */
1364 }
1365
1366 static void ash_msg_and_raise_error(const char *, ...) NORETURN;
1367 static void
1368 ash_msg_and_raise_error(const char *msg, ...)
1369 {
1370         va_list ap;
1371
1372         exitstatus = 2;
1373
1374         va_start(ap, msg);
1375         ash_vmsg_and_raise(EXERROR, msg, ap);
1376         /* NOTREACHED */
1377         va_end(ap);
1378 }
1379
1380 /*
1381  * 'fmt' must be a string literal.
1382  */
1383 #define ash_msg_and_raise_perror(fmt, ...) ash_msg_and_raise_error(fmt ": "STRERROR_FMT, ##__VA_ARGS__ STRERROR_ERRNO)
1384
1385 static void raise_error_syntax(const char *) NORETURN;
1386 static void
1387 raise_error_syntax(const char *msg)
1388 {
1389         errlinno = g_parsefile->linno;
1390         ash_msg_and_raise_error("syntax error: %s", msg);
1391         /* NOTREACHED */
1392 }
1393
1394 static void ash_msg_and_raise(int, const char *, ...) NORETURN;
1395 static void
1396 ash_msg_and_raise(int cond, const char *msg, ...)
1397 {
1398         va_list ap;
1399
1400         va_start(ap, msg);
1401         ash_vmsg_and_raise(cond, msg, ap);
1402         /* NOTREACHED */
1403         va_end(ap);
1404 }
1405
1406 /*
1407  * error/warning routines for external builtins
1408  */
1409 static void
1410 ash_msg(const char *fmt, ...)
1411 {
1412         va_list ap;
1413
1414         va_start(ap, fmt);
1415         ash_vmsg(fmt, ap);
1416         va_end(ap);
1417 }
1418
1419 /*
1420  * Return a string describing an error.  The returned string may be a
1421  * pointer to a static buffer that will be overwritten on the next call.
1422  * Action describes the operation that got the error.
1423  */
1424 static const char *
1425 errmsg(int e, const char *em)
1426 {
1427         if (e == ENOENT || e == ENOTDIR) {
1428                 return em;
1429         }
1430         return strerror(e);
1431 }
1432
1433
1434 /* ============ Memory allocation */
1435
1436 #if 0
1437 /* I consider these wrappers nearly useless:
1438  * ok, they return you to nearest exception handler, but
1439  * how much memory do you leak in the process, making
1440  * memory starvation worse?
1441  */
1442 static void *
1443 ckrealloc(void * p, size_t nbytes)
1444 {
1445         p = realloc(p, nbytes);
1446         if (!p)
1447                 ash_msg_and_raise_error(bb_msg_memory_exhausted);
1448         return p;
1449 }
1450
1451 static void *
1452 ckmalloc(size_t nbytes)
1453 {
1454         return ckrealloc(NULL, nbytes);
1455 }
1456
1457 static void *
1458 ckzalloc(size_t nbytes)
1459 {
1460         return memset(ckmalloc(nbytes), 0, nbytes);
1461 }
1462
1463 static char *
1464 ckstrdup(const char *s)
1465 {
1466         char *p = strdup(s);
1467         if (!p)
1468                 ash_msg_and_raise_error(bb_msg_memory_exhausted);
1469         return p;
1470 }
1471 #else
1472 /* Using bbox equivalents. They exit if out of memory */
1473 # define ckrealloc xrealloc
1474 # define ckmalloc  xmalloc
1475 # define ckzalloc  xzalloc
1476 # define ckstrdup  xstrdup
1477 #endif
1478
1479 /*
1480  * It appears that grabstackstr() will barf with such alignments
1481  * because stalloc() will return a string allocated in a new stackblock.
1482  */
1483 #define SHELL_ALIGN(nbytes) (((nbytes) + SHELL_SIZE) & ~SHELL_SIZE)
1484 enum {
1485         /* Most machines require the value returned from malloc to be aligned
1486          * in some way.  The following macro will get this right
1487          * on many machines.  */
1488         SHELL_SIZE = sizeof(union { int i; char *cp; double d; }) - 1,
1489         /* Minimum size of a block */
1490         MINSIZE = SHELL_ALIGN(504),
1491 };
1492
1493 struct stack_block {
1494         struct stack_block *prev;
1495         char space[MINSIZE];
1496 };
1497
1498 struct stackmark {
1499         struct stack_block *stackp;
1500         char *stacknxt;
1501         size_t stacknleft;
1502 };
1503
1504
1505 struct globals_memstack {
1506         struct stack_block *g_stackp; // = &stackbase;
1507         char *g_stacknxt; // = stackbase.space;
1508         char *sstrend; // = stackbase.space + MINSIZE;
1509         size_t g_stacknleft; // = MINSIZE;
1510         struct stack_block stackbase;
1511 };
1512 extern struct globals_memstack *BB_GLOBAL_CONST ash_ptr_to_globals_memstack;
1513 #define G_memstack (*ash_ptr_to_globals_memstack)
1514 #define g_stackp     (G_memstack.g_stackp    )
1515 #define g_stacknxt   (G_memstack.g_stacknxt  )
1516 #define sstrend      (G_memstack.sstrend     )
1517 #define g_stacknleft (G_memstack.g_stacknleft)
1518 #define stackbase    (G_memstack.stackbase   )
1519 #define INIT_G_memstack() do { \
1520         (*(struct globals_memstack**)&ash_ptr_to_globals_memstack) = xzalloc(sizeof(G_memstack)); \
1521         barrier(); \
1522         g_stackp = &stackbase; \
1523         g_stacknxt = stackbase.space; \
1524         g_stacknleft = MINSIZE; \
1525         sstrend = stackbase.space + MINSIZE; \
1526 } while (0)
1527
1528
1529 #define stackblock()     ((void *)g_stacknxt)
1530 #define stackblocksize() g_stacknleft
1531
1532 /*
1533  * Parse trees for commands are allocated in lifo order, so we use a stack
1534  * to make this more efficient, and also to avoid all sorts of exception
1535  * handling code to handle interrupts in the middle of a parse.
1536  *
1537  * The size 504 was chosen because the Ultrix malloc handles that size
1538  * well.
1539  */
1540 static void *
1541 stalloc(size_t nbytes)
1542 {
1543         char *p;
1544         size_t aligned;
1545
1546         aligned = SHELL_ALIGN(nbytes);
1547         if (aligned > g_stacknleft) {
1548                 size_t len;
1549                 size_t blocksize;
1550                 struct stack_block *sp;
1551
1552                 blocksize = aligned;
1553                 if (blocksize < MINSIZE)
1554                         blocksize = MINSIZE;
1555                 len = sizeof(struct stack_block) - MINSIZE + blocksize;
1556                 if (len < blocksize)
1557                         ash_msg_and_raise_error(bb_msg_memory_exhausted);
1558                 INT_OFF;
1559                 sp = ckmalloc(len);
1560                 sp->prev = g_stackp;
1561                 g_stacknxt = sp->space;
1562                 g_stacknleft = blocksize;
1563                 sstrend = g_stacknxt + blocksize;
1564                 g_stackp = sp;
1565                 INT_ON;
1566         }
1567         p = g_stacknxt;
1568         g_stacknxt += aligned;
1569         g_stacknleft -= aligned;
1570         return p;
1571 }
1572
1573 static void *
1574 stzalloc(size_t nbytes)
1575 {
1576         return memset(stalloc(nbytes), 0, nbytes);
1577 }
1578
1579 static void
1580 stunalloc(void *p)
1581 {
1582 #if DEBUG
1583         if (!p || (g_stacknxt < (char *)p) || ((char *)p < g_stackp->space)) {
1584                 write(STDERR_FILENO, "stunalloc\n", 10);
1585                 abort();
1586         }
1587 #endif
1588         g_stacknleft += g_stacknxt - (char *)p;
1589         g_stacknxt = p;
1590 }
1591
1592 /*
1593  * Like strdup but works with the ash stack.
1594  */
1595 static char *
1596 sstrdup(const char *p)
1597 {
1598         size_t len = strlen(p) + 1;
1599         return memcpy(stalloc(len), p, len);
1600 }
1601
1602 static ALWAYS_INLINE void
1603 grabstackblock(size_t len)
1604 {
1605         stalloc(len);
1606 }
1607
1608 static void
1609 pushstackmark(struct stackmark *mark, size_t len)
1610 {
1611         mark->stackp = g_stackp;
1612         mark->stacknxt = g_stacknxt;
1613         mark->stacknleft = g_stacknleft;
1614         grabstackblock(len);
1615 }
1616
1617 static void
1618 setstackmark(struct stackmark *mark)
1619 {
1620         pushstackmark(mark, g_stacknxt == g_stackp->space && g_stackp != &stackbase);
1621 }
1622
1623 static void
1624 popstackmark(struct stackmark *mark)
1625 {
1626         struct stack_block *sp;
1627
1628         if (!mark->stackp)
1629                 return;
1630
1631         INT_OFF;
1632         while (g_stackp != mark->stackp) {
1633                 sp = g_stackp;
1634                 g_stackp = sp->prev;
1635                 free(sp);
1636         }
1637         g_stacknxt = mark->stacknxt;
1638         g_stacknleft = mark->stacknleft;
1639         sstrend = mark->stacknxt + mark->stacknleft;
1640         INT_ON;
1641 }
1642
1643 /*
1644  * When the parser reads in a string, it wants to stick the string on the
1645  * stack and only adjust the stack pointer when it knows how big the
1646  * string is.  Stackblock (defined in stack.h) returns a pointer to a block
1647  * of space on top of the stack and stackblocklen returns the length of
1648  * this block.  Growstackblock will grow this space by at least one byte,
1649  * possibly moving it (like realloc).  Grabstackblock actually allocates the
1650  * part of the block that has been used.
1651  */
1652 static void
1653 growstackblock(void)
1654 {
1655         size_t newlen;
1656
1657         newlen = g_stacknleft * 2;
1658         if (newlen < g_stacknleft)
1659                 ash_msg_and_raise_error(bb_msg_memory_exhausted);
1660         if (newlen < 128)
1661                 newlen += 128;
1662
1663         if (g_stacknxt == g_stackp->space && g_stackp != &stackbase) {
1664                 struct stack_block *sp;
1665                 struct stack_block *prevstackp;
1666                 size_t grosslen;
1667
1668                 INT_OFF;
1669                 sp = g_stackp;
1670                 prevstackp = sp->prev;
1671                 grosslen = newlen + sizeof(struct stack_block) - MINSIZE;
1672                 sp = ckrealloc(sp, grosslen);
1673                 sp->prev = prevstackp;
1674                 g_stackp = sp;
1675                 g_stacknxt = sp->space;
1676                 g_stacknleft = newlen;
1677                 sstrend = sp->space + newlen;
1678                 INT_ON;
1679         } else {
1680                 char *oldspace = g_stacknxt;
1681                 size_t oldlen = g_stacknleft;
1682                 char *p = stalloc(newlen);
1683
1684                 /* free the space we just allocated */
1685                 g_stacknxt = memcpy(p, oldspace, oldlen);
1686                 g_stacknleft += newlen;
1687         }
1688 }
1689
1690 /*
1691  * The following routines are somewhat easier to use than the above.
1692  * The user declares a variable of type STACKSTR, which may be declared
1693  * to be a register.  The macro STARTSTACKSTR initializes things.  Then
1694  * the user uses the macro STPUTC to add characters to the string.  In
1695  * effect, STPUTC(c, p) is the same as *p++ = c except that the stack is
1696  * grown as necessary.  When the user is done, she can just leave the
1697  * string there and refer to it using stackblock().  Or she can allocate
1698  * the space for it using grabstackstr().  If it is necessary to allow
1699  * someone else to use the stack temporarily and then continue to grow
1700  * the string, the user should use grabstack to allocate the space, and
1701  * then call ungrabstr(p) to return to the previous mode of operation.
1702  *
1703  * USTPUTC is like STPUTC except that it doesn't check for overflow.
1704  * CHECKSTACKSPACE can be called before USTPUTC to ensure that there
1705  * is space for at least one character.
1706  */
1707 static void *
1708 growstackstr(void)
1709 {
1710         size_t len = stackblocksize();
1711         growstackblock();
1712         return (char *)stackblock() + len;
1713 }
1714
1715 /*
1716  * Called from CHECKSTRSPACE.
1717  */
1718 static char *
1719 makestrspace(size_t newlen, char *p)
1720 {
1721         size_t len = p - g_stacknxt;
1722         size_t size;
1723
1724         for (;;) {
1725                 size_t nleft;
1726
1727                 size = stackblocksize();
1728                 nleft = size - len;
1729                 if (nleft >= newlen)
1730                         break;
1731                 growstackblock();
1732         }
1733         return (char *)stackblock() + len;
1734 }
1735
1736 static char *
1737 stack_nputstr(const char *s, size_t n, char *p)
1738 {
1739         p = makestrspace(n, p);
1740         p = (char *)mempcpy(p, s, n);
1741         return p;
1742 }
1743
1744 static char *
1745 stack_putstr(const char *s, char *p)
1746 {
1747         return stack_nputstr(s, strlen(s), p);
1748 }
1749
1750 static char *
1751 _STPUTC(int c, char *p)
1752 {
1753         if (p == sstrend)
1754                 p = growstackstr();
1755         *p++ = c;
1756         return p;
1757 }
1758
1759 #define STARTSTACKSTR(p)        ((p) = stackblock())
1760 #define STPUTC(c, p)            ((p) = _STPUTC((c), (p)))
1761 #define CHECKSTRSPACE(n, p) do { \
1762         char *q = (p); \
1763         size_t l = (n); \
1764         size_t m = sstrend - q; \
1765         if (l > m) \
1766                 (p) = makestrspace(l, q); \
1767 } while (0)
1768 #define USTPUTC(c, p)           (*(p)++ = (c))
1769 #define STACKSTRNUL(p) do { \
1770         if ((p) == sstrend) \
1771                 (p) = growstackstr(); \
1772         *(p) = '\0'; \
1773 } while (0)
1774 #define STUNPUTC(p)             (--(p))
1775 #define STTOPC(p)               ((p)[-1])
1776 #define STADJUST(amount, p)     ((p) += (amount))
1777
1778 #define grabstackstr(p)         stalloc((char *)(p) - (char *)stackblock())
1779 #define ungrabstackstr(s, p)    stunalloc(s)
1780 #define stackstrend()           ((void *)sstrend)
1781
1782
1783 /* ============ String helpers */
1784
1785 /*
1786  * prefix -- see if pfx is a prefix of string.
1787  */
1788 static char *
1789 prefix(const char *string, const char *pfx)
1790 {
1791         while (*pfx) {
1792                 if (*pfx++ != *string++)
1793                         return NULL;
1794         }
1795         return (char *) string;
1796 }
1797
1798 /*
1799  * Check for a valid number.  This should be elsewhere.
1800  */
1801 static int
1802 is_number(const char *p)
1803 {
1804         do {
1805                 if (!isdigit(*p))
1806                         return 0;
1807         } while (*++p != '\0');
1808         return 1;
1809 }
1810
1811 /*
1812  * Convert a string of digits to an integer, printing an error message on
1813  * failure.
1814  */
1815 static int
1816 number(const char *s)
1817 {
1818         if (!is_number(s))
1819                 ash_msg_and_raise_error(msg_illnum, s);
1820         return atoi(s);
1821 }
1822
1823 /*
1824  * Produce a single quoted string suitable as input to the shell.
1825  * The return string is allocated on the stack.
1826  */
1827 static char *
1828 single_quote(const char *s)
1829 {
1830         char *p;
1831
1832         STARTSTACKSTR(p);
1833
1834         do {
1835                 char *q;
1836                 size_t len;
1837
1838                 len = strchrnul(s, '\'') - s;
1839
1840                 q = p = makestrspace(len + 3, p);
1841
1842                 *q++ = '\'';
1843                 q = (char *)mempcpy(q, s, len);
1844                 *q++ = '\'';
1845                 s += len;
1846
1847                 STADJUST(q - p, p);
1848
1849                 if (*s != '\'')
1850                         break;
1851                 len = 0;
1852                 do len++; while (*++s == '\'');
1853
1854                 q = p = makestrspace(len + 3, p);
1855
1856                 *q++ = '"';
1857                 q = (char *)mempcpy(q, s - len, len);
1858                 *q++ = '"';
1859
1860                 STADJUST(q - p, p);
1861         } while (*s);
1862
1863         USTPUTC('\0', p);
1864
1865         return stackblock();
1866 }
1867
1868 /*
1869  * Produce a possibly single quoted string suitable as input to the shell.
1870  * If quoting was done, the return string is allocated on the stack,
1871  * otherwise a pointer to the original string is returned.
1872  */
1873 static const char *
1874 maybe_single_quote(const char *s)
1875 {
1876         const char *p = s;
1877
1878         while (*p) {
1879                 /* Assuming ACSII */
1880                 /* quote ctrl_chars space !"#$%&'()* */
1881                 if (*p < '+')
1882                         goto need_quoting;
1883                 /* quote ;<=>? */
1884                 if (*p >= ';' && *p <= '?')
1885                         goto need_quoting;
1886                 /* quote `[\ */
1887                 if (*p == '`')
1888                         goto need_quoting;
1889                 if (*p == '[')
1890                         goto need_quoting;
1891                 if (*p == '\\')
1892                         goto need_quoting;
1893                 /* quote {|}~ DEL and high bytes */
1894                 if (*p > 'z')
1895                         goto need_quoting;
1896                 /* Not quoting these: +,-./ 0-9 :@ A-Z ]^_ a-z */
1897                 /* TODO: maybe avoid quoting % */
1898                 p++;
1899         }
1900         return s;
1901
1902  need_quoting:
1903         return single_quote(s);
1904 }
1905
1906
1907 /* ============ nextopt */
1908
1909 static char **argptr;                  /* argument list for builtin commands */
1910 static char *optionarg;                /* set by nextopt (like getopt) */
1911 static char *optptr;                   /* used by nextopt */
1912
1913 /*
1914  * XXX - should get rid of. Have all builtins use getopt(3).
1915  * The library getopt must have the BSD extension static variable
1916  * "optreset", otherwise it can't be used within the shell safely.
1917  *
1918  * Standard option processing (a la getopt) for builtin routines.
1919  * The only argument that is passed to nextopt is the option string;
1920  * the other arguments are unnecessary. It returns the character,
1921  * or '\0' on end of input.
1922  */
1923 static int
1924 nextopt(const char *optstring)
1925 {
1926         char *p;
1927         const char *q;
1928         char c;
1929
1930         p = optptr;
1931         if (p == NULL || *p == '\0') {
1932                 /* We ate entire "-param", take next one */
1933                 p = *argptr;
1934                 if (p == NULL)
1935                         return '\0';
1936                 if (*p != '-')
1937                         return '\0';
1938                 if (*++p == '\0') /* just "-" ? */
1939                         return '\0';
1940                 argptr++;
1941                 if (LONE_DASH(p)) /* "--" ? */
1942                         return '\0';
1943                 /* p => next "-param" */
1944         }
1945         /* p => some option char in the middle of a "-param" */
1946         c = *p++;
1947         for (q = optstring; *q != c;) {
1948                 if (*q == '\0')
1949                         ash_msg_and_raise_error("illegal option -%c", c);
1950                 if (*++q == ':')
1951                         q++;
1952         }
1953         if (*++q == ':') {
1954                 if (*p == '\0') {
1955                         p = *argptr++;
1956                         if (p == NULL)
1957                                 ash_msg_and_raise_error("no arg for -%c option", c);
1958                 }
1959                 optionarg = p;
1960                 p = NULL;
1961         }
1962         optptr = p;
1963         return c;
1964 }
1965
1966
1967 /* ============ Shell variables */
1968
1969 struct shparam {
1970         int nparam;             /* # of positional parameters (without $0) */
1971 #if ENABLE_ASH_GETOPTS
1972         int optind;             /* next parameter to be processed by getopts */
1973         int optoff;             /* used by getopts */
1974 #endif
1975         unsigned char malloced; /* if parameter list dynamically allocated */
1976         char **p;               /* parameter list */
1977 };
1978
1979 /*
1980  * Free the list of positional parameters.
1981  */
1982 static void
1983 freeparam(volatile struct shparam *param)
1984 {
1985         if (param->malloced) {
1986                 char **ap, **ap1;
1987                 ap = ap1 = param->p;
1988                 while (*ap)
1989                         free(*ap++);
1990                 free(ap1);
1991         }
1992 }
1993
1994 #if ENABLE_ASH_GETOPTS
1995 static void FAST_FUNC getoptsreset(const char *value);
1996 #endif
1997
1998 struct var {
1999         struct var *next;               /* next entry in hash list */
2000         int flags;                      /* flags are defined above */
2001         const char *var_text;           /* name=value */
2002         void (*var_func)(const char *) FAST_FUNC; /* function to be called when  */
2003                                         /* the variable gets set/unset */
2004 };
2005
2006 struct localvar {
2007         struct localvar *next;          /* next local variable in list */
2008         struct var *vp;                 /* the variable that was made local */
2009         int flags;                      /* saved flags */
2010         const char *text;               /* saved text */
2011 };
2012
2013 /* flags */
2014 #define VEXPORT         0x01    /* variable is exported */
2015 #define VREADONLY       0x02    /* variable cannot be modified */
2016 #define VSTRFIXED       0x04    /* variable struct is statically allocated */
2017 #define VTEXTFIXED      0x08    /* text is statically allocated */
2018 #define VSTACK          0x10    /* text is allocated on the stack */
2019 #define VUNSET          0x20    /* the variable is not set */
2020 #define VNOFUNC         0x40    /* don't call the callback function */
2021 #define VNOSET          0x80    /* do not set variable - just readonly test */
2022 #define VNOSAVE         0x100   /* when text is on the heap before setvareq */
2023 #if ENABLE_ASH_RANDOM_SUPPORT
2024 # define VDYNAMIC       0x200   /* dynamic variable */
2025 #else
2026 # define VDYNAMIC       0
2027 #endif
2028
2029
2030 /* Need to be before varinit_data[] */
2031 #if ENABLE_LOCALE_SUPPORT
2032 static void FAST_FUNC
2033 change_lc_all(const char *value)
2034 {
2035         if (value && *value != '\0')
2036                 setlocale(LC_ALL, value);
2037 }
2038 static void FAST_FUNC
2039 change_lc_ctype(const char *value)
2040 {
2041         if (value && *value != '\0')
2042                 setlocale(LC_CTYPE, value);
2043 }
2044 #endif
2045 #if ENABLE_ASH_MAIL
2046 static void chkmail(void);
2047 static void changemail(const char *var_value) FAST_FUNC;
2048 #else
2049 # define chkmail()  ((void)0)
2050 #endif
2051 static void changepath(const char *) FAST_FUNC;
2052 #if ENABLE_ASH_RANDOM_SUPPORT
2053 static void change_random(const char *) FAST_FUNC;
2054 #endif
2055
2056 static const struct {
2057         int flags;
2058         const char *var_text;
2059         void (*var_func)(const char *) FAST_FUNC;
2060 } varinit_data[] = {
2061         /*
2062          * Note: VEXPORT would not work correctly here for NOFORK applets:
2063          * some environment strings may be constant.
2064          */
2065         { VSTRFIXED|VTEXTFIXED       , defifsvar   , NULL            },
2066 #if ENABLE_ASH_MAIL
2067         { VSTRFIXED|VTEXTFIXED|VUNSET, "MAIL"      , changemail      },
2068         { VSTRFIXED|VTEXTFIXED|VUNSET, "MAILPATH"  , changemail      },
2069 #endif
2070         { VSTRFIXED|VTEXTFIXED       , bb_PATH_root_path, changepath },
2071         { VSTRFIXED|VTEXTFIXED       , "PS1=$ "    , NULL            },
2072         { VSTRFIXED|VTEXTFIXED       , "PS2=> "    , NULL            },
2073         { VSTRFIXED|VTEXTFIXED       , "PS4=+ "    , NULL            },
2074 #if ENABLE_ASH_GETOPTS
2075         { VSTRFIXED|VTEXTFIXED       , defoptindvar, getoptsreset    },
2076 #endif
2077         { VSTRFIXED|VTEXTFIXED       , NULL /* inited to linenovar */, NULL },
2078 #if ENABLE_ASH_RANDOM_SUPPORT
2079         { VSTRFIXED|VTEXTFIXED|VUNSET|VDYNAMIC, "RANDOM", change_random },
2080 #endif
2081 #if ENABLE_LOCALE_SUPPORT
2082         { VSTRFIXED|VTEXTFIXED|VUNSET, "LC_ALL"    , change_lc_all   },
2083         { VSTRFIXED|VTEXTFIXED|VUNSET, "LC_CTYPE"  , change_lc_ctype },
2084 #endif
2085 #if ENABLE_FEATURE_EDITING_SAVEHISTORY
2086         { VSTRFIXED|VTEXTFIXED|VUNSET, "HISTFILE"  , NULL            },
2087 #endif
2088 };
2089
2090 struct redirtab;
2091
2092 struct globals_var {
2093         struct shparam shellparam;      /* $@ current positional parameters */
2094         struct redirtab *redirlist;
2095         int preverrout_fd;   /* stderr fd: usually 2, unless redirect moved it */
2096         struct var *vartab[VTABSIZE];
2097         struct var varinit[ARRAY_SIZE(varinit_data)];
2098         int lineno;
2099         char linenovar[sizeof("LINENO=") + sizeof(int)*3];
2100 };
2101 extern struct globals_var *BB_GLOBAL_CONST ash_ptr_to_globals_var;
2102 #define G_var (*ash_ptr_to_globals_var)
2103 #define shellparam    (G_var.shellparam   )
2104 //#define redirlist     (G_var.redirlist    )
2105 #define preverrout_fd (G_var.preverrout_fd)
2106 #define vartab        (G_var.vartab       )
2107 #define varinit       (G_var.varinit      )
2108 #define lineno        (G_var.lineno       )
2109 #define linenovar     (G_var.linenovar    )
2110 #define vifs      varinit[0]
2111 #if ENABLE_ASH_MAIL
2112 # define vmail    (&vifs)[1]
2113 # define vmpath   (&vmail)[1]
2114 # define vpath    (&vmpath)[1]
2115 #else
2116 # define vpath    (&vifs)[1]
2117 #endif
2118 #define vps1      (&vpath)[1]
2119 #define vps2      (&vps1)[1]
2120 #define vps4      (&vps2)[1]
2121 #if ENABLE_ASH_GETOPTS
2122 # define voptind  (&vps4)[1]
2123 # define vlineno  (&voptind)[1]
2124 # if ENABLE_ASH_RANDOM_SUPPORT
2125 #  define vrandom (&vlineno)[1]
2126 # endif
2127 #else
2128 # define vlineno  (&vps4)[1]
2129 # if ENABLE_ASH_RANDOM_SUPPORT
2130 #  define vrandom (&vlineno)[1]
2131 # endif
2132 #endif
2133 #define INIT_G_var() do { \
2134         unsigned i; \
2135         (*(struct globals_var**)&ash_ptr_to_globals_var) = xzalloc(sizeof(G_var)); \
2136         barrier(); \
2137         for (i = 0; i < ARRAY_SIZE(varinit_data); i++) { \
2138                 varinit[i].flags    = varinit_data[i].flags; \
2139                 varinit[i].var_text = varinit_data[i].var_text; \
2140                 varinit[i].var_func = varinit_data[i].var_func; \
2141         } \
2142         strcpy(linenovar, "LINENO="); \
2143         vlineno.var_text = linenovar; \
2144 } while (0)
2145
2146 /*
2147  * The following macros access the values of the above variables.
2148  * They have to skip over the name.  They return the null string
2149  * for unset variables.
2150  */
2151 #define ifsval()        (vifs.var_text + 4)
2152 #define ifsset()        ((vifs.flags & VUNSET) == 0)
2153 #if ENABLE_ASH_MAIL
2154 # define mailval()      (vmail.var_text + 5)
2155 # define mpathval()     (vmpath.var_text + 9)
2156 # define mpathset()     ((vmpath.flags & VUNSET) == 0)
2157 #endif
2158 #define pathval()       (vpath.var_text + 5)
2159 #define ps1val()        (vps1.var_text + 4)
2160 #define ps2val()        (vps2.var_text + 4)
2161 #define ps4val()        (vps4.var_text + 4)
2162 #if ENABLE_ASH_GETOPTS
2163 # define optindval()    (voptind.var_text + 7)
2164 #endif
2165
2166 #if ENABLE_ASH_GETOPTS
2167 static void FAST_FUNC
2168 getoptsreset(const char *value)
2169 {
2170         shellparam.optind = 1;
2171         if (is_number(value))
2172                 shellparam.optind = number(value) ?: 1;
2173         shellparam.optoff = -1;
2174 }
2175 #endif
2176
2177 /*
2178  * Compares two strings up to the first = or '\0'.  The first
2179  * string must be terminated by '='; the second may be terminated by
2180  * either '=' or '\0'.
2181  */
2182 static int
2183 varcmp(const char *p, const char *q)
2184 {
2185         int c, d;
2186
2187         while ((c = *p) == (d = *q)) {
2188                 if (c == '\0' || c == '=')
2189                         goto out;
2190                 p++;
2191                 q++;
2192         }
2193         if (c == '=')
2194                 c = '\0';
2195         if (d == '=')
2196                 d = '\0';
2197  out:
2198         return c - d;
2199 }
2200
2201 /*
2202  * Find the appropriate entry in the hash table from the name.
2203  */
2204 static struct var **
2205 hashvar(const char *p)
2206 {
2207         unsigned hashval;
2208
2209         hashval = ((unsigned char) *p) << 4;
2210         while (*p && *p != '=')
2211                 hashval += (unsigned char) *p++;
2212         return &vartab[hashval % VTABSIZE];
2213 }
2214
2215 static int
2216 vpcmp(const void *a, const void *b)
2217 {
2218         return varcmp(*(const char **)a, *(const char **)b);
2219 }
2220
2221 /*
2222  * This routine initializes the builtin variables.
2223  */
2224 static void
2225 initvar(void)
2226 {
2227         struct var *vp;
2228         struct var *end;
2229         struct var **vpp;
2230
2231         /*
2232          * PS1 depends on uid
2233          */
2234 #if ENABLE_FEATURE_EDITING && ENABLE_FEATURE_EDITING_FANCY_PROMPT
2235         vps1.var_text = "PS1=\\w \\$ ";
2236 #else
2237         if (!geteuid())
2238                 vps1.var_text = "PS1=# ";
2239 #endif
2240         vp = varinit;
2241         end = vp + ARRAY_SIZE(varinit);
2242         do {
2243                 vpp = hashvar(vp->var_text);
2244                 vp->next = *vpp;
2245                 *vpp = vp;
2246         } while (++vp < end);
2247 }
2248
2249 static struct var **
2250 findvar(struct var **vpp, const char *name)
2251 {
2252         for (; *vpp; vpp = &(*vpp)->next) {
2253                 if (varcmp((*vpp)->var_text, name) == 0) {
2254                         break;
2255                 }
2256         }
2257         return vpp;
2258 }
2259
2260 /*
2261  * Find the value of a variable.  Returns NULL if not set.
2262  */
2263 static const char* FAST_FUNC
2264 lookupvar(const char *name)
2265 {
2266         struct var *v;
2267
2268         v = *findvar(hashvar(name), name);
2269         if (v) {
2270 #if ENABLE_ASH_RANDOM_SUPPORT
2271         /*
2272          * Dynamic variables are implemented roughly the same way they are
2273          * in bash. Namely, they're "special" so long as they aren't unset.
2274          * As soon as they're unset, they're no longer dynamic, and dynamic
2275          * lookup will no longer happen at that point. -- PFM.
2276          */
2277                 if (v->flags & VDYNAMIC)
2278                         v->var_func(NULL);
2279 #endif
2280                 if (!(v->flags & VUNSET)) {
2281                         if (v == &vlineno && v->var_text == linenovar) {
2282                                 fmtstr(linenovar+7, sizeof(linenovar)-7, "%d", lineno);
2283                         }
2284                         return var_end(v->var_text);
2285                 }
2286         }
2287         return NULL;
2288 }
2289
2290 #if ENABLE_UNICODE_SUPPORT
2291 static void
2292 reinit_unicode_for_ash(void)
2293 {
2294         /* Unicode support should be activated even if LANG is set
2295          * _during_ shell execution, not only if it was set when
2296          * shell was started. Therefore, re-check LANG every time:
2297          */
2298         if (ENABLE_FEATURE_CHECK_UNICODE_IN_ENV
2299          || ENABLE_UNICODE_USING_LOCALE
2300         ) {
2301                 const char *s = lookupvar("LC_ALL");
2302                 if (!s) s = lookupvar("LC_CTYPE");
2303                 if (!s) s = lookupvar("LANG");
2304                 reinit_unicode(s);
2305         }
2306 }
2307 #else
2308 # define reinit_unicode_for_ash() ((void)0)
2309 #endif
2310
2311 /*
2312  * Search the environment of a builtin command.
2313  */
2314 static ALWAYS_INLINE const char *
2315 bltinlookup(const char *name)
2316 {
2317         return lookupvar(name);
2318 }
2319
2320 /*
2321  * Same as setvar except that the variable and value are passed in
2322  * the first argument as name=value.  Since the first argument will
2323  * be actually stored in the table, it should not be a string that
2324  * will go away.
2325  * Called with interrupts off.
2326  */
2327 static struct var *
2328 setvareq(char *s, int flags)
2329 {
2330         struct var *vp, **vpp;
2331
2332         vpp = hashvar(s);
2333         flags |= (VEXPORT & (((unsigned) (1 - aflag)) - 1));
2334         vpp = findvar(vpp, s);
2335         vp = *vpp;
2336         if (vp) {
2337                 if ((vp->flags & (VREADONLY|VDYNAMIC)) == VREADONLY) {
2338                         const char *n;
2339
2340                         if (flags & VNOSAVE)
2341                                 free(s);
2342                         n = vp->var_text;
2343                         exitstatus = 1;
2344                         ash_msg_and_raise_error("%.*s: is read only", strchrnul(n, '=') - n, n);
2345                 }
2346
2347                 if (flags & VNOSET)
2348                         goto out;
2349
2350                 if (vp->var_func && !(flags & VNOFUNC))
2351                         vp->var_func(var_end(s));
2352
2353                 if (!(vp->flags & (VTEXTFIXED|VSTACK)))
2354                         free((char*)vp->var_text);
2355
2356                 if (((flags & (VEXPORT|VREADONLY|VSTRFIXED|VUNSET)) | (vp->flags & VSTRFIXED)) == VUNSET) {
2357                         *vpp = vp->next;
2358                         free(vp);
2359  out_free:
2360                         if ((flags & (VTEXTFIXED|VSTACK|VNOSAVE)) == VNOSAVE)
2361                                 free(s);
2362                         goto out;
2363                 }
2364
2365                 flags |= vp->flags & ~(VTEXTFIXED|VSTACK|VNOSAVE|VUNSET);
2366         } else {
2367                 /* variable s is not found */
2368                 if (flags & VNOSET)
2369                         goto out;
2370                 if ((flags & (VEXPORT|VREADONLY|VSTRFIXED|VUNSET)) == VUNSET)
2371                         goto out_free;
2372                 vp = ckzalloc(sizeof(*vp));
2373                 vp->next = *vpp;
2374                 /*vp->func = NULL; - ckzalloc did it */
2375                 *vpp = vp;
2376         }
2377         if (!(flags & (VTEXTFIXED|VSTACK|VNOSAVE)))
2378                 s = ckstrdup(s);
2379         vp->var_text = s;
2380         vp->flags = flags;
2381
2382  out:
2383         return vp;
2384 }
2385
2386 /*
2387  * Set the value of a variable.  The flags argument is ored with the
2388  * flags of the variable.  If val is NULL, the variable is unset.
2389  */
2390 static struct var *
2391 setvar(const char *name, const char *val, int flags)
2392 {
2393         const char *q;
2394         char *p;
2395         char *nameeq;
2396         size_t namelen;
2397         size_t vallen;
2398         struct var *vp;
2399
2400         q = endofname(name);
2401         p = strchrnul(q, '=');
2402         namelen = p - name;
2403         if (!namelen || p != q)
2404                 ash_msg_and_raise_error("%.*s: bad variable name", namelen, name);
2405         vallen = 0;
2406         if (val == NULL) {
2407                 flags |= VUNSET;
2408         } else {
2409                 vallen = strlen(val);
2410         }
2411
2412         INT_OFF;
2413         nameeq = ckzalloc(namelen + vallen + 2);
2414         p = mempcpy(nameeq, name, namelen);
2415         if (val) {
2416                 *p++ = '=';
2417                 memcpy(p, val, vallen);
2418         }
2419         vp = setvareq(nameeq, flags | VNOSAVE);
2420         INT_ON;
2421
2422         return vp;
2423 }
2424
2425 static void FAST_FUNC
2426 setvar0(const char *name, const char *val)
2427 {
2428         setvar(name, val, 0);
2429 }
2430
2431 /*
2432  * Unset the specified variable.
2433  */
2434 static void
2435 unsetvar(const char *s)
2436 {
2437         setvar(s, NULL, 0);
2438 }
2439
2440 /*
2441  * Process a linked list of variable assignments.
2442  */
2443 static void
2444 listsetvar(struct strlist *list_set_var, int flags)
2445 {
2446         struct strlist *lp = list_set_var;
2447
2448         if (!lp)
2449                 return;
2450         INT_OFF;
2451         do {
2452                 setvareq(lp->text, flags);
2453                 lp = lp->next;
2454         } while (lp);
2455         INT_ON;
2456 }
2457
2458 /*
2459  * Generate a list of variables satisfying the given conditions.
2460  */
2461 #if !ENABLE_FEATURE_SH_NOFORK
2462 # define listvars(on, off, lp, end) listvars(on, off, end)
2463 #endif
2464 static char **
2465 listvars(int on, int off, struct strlist *lp, char ***end)
2466 {
2467         struct var **vpp;
2468         struct var *vp;
2469         char **ep;
2470         int mask;
2471
2472         STARTSTACKSTR(ep);
2473         vpp = vartab;
2474         mask = on | off;
2475         do {
2476                 for (vp = *vpp; vp; vp = vp->next) {
2477                         if ((vp->flags & mask) == on) {
2478 #if ENABLE_FEATURE_SH_NOFORK
2479                                 /* If variable with the same name is both
2480                                  * exported and temporarily set for a command:
2481                                  *  export ZVAR=5
2482                                  *  ZVAR=6 printenv
2483                                  * then "ZVAR=6" will be both in vartab and
2484                                  * lp lists. Do not pass it twice to printenv.
2485                                  */
2486                                 struct strlist *lp1 = lp;
2487                                 while (lp1) {
2488                                         if (strcmp(lp1->text, vp->var_text) == 0)
2489                                                 goto skip;
2490                                         lp1 = lp1->next;
2491                                 }
2492 #endif
2493                                 if (ep == stackstrend())
2494                                         ep = growstackstr();
2495                                 *ep++ = (char*)vp->var_text;
2496 #if ENABLE_FEATURE_SH_NOFORK
2497  skip: ;
2498 #endif
2499                         }
2500                 }
2501         } while (++vpp < vartab + VTABSIZE);
2502
2503 #if ENABLE_FEATURE_SH_NOFORK
2504         while (lp) {
2505                 if (ep == stackstrend())
2506                         ep = growstackstr();
2507                 *ep++ = lp->text;
2508                 lp = lp->next;
2509         }
2510 #endif
2511
2512         if (ep == stackstrend())
2513                 ep = growstackstr();
2514         if (end)
2515                 *end = ep;
2516         *ep++ = NULL;
2517         return grabstackstr(ep);
2518 }
2519
2520
2521 /* ============ Path search helper
2522  *
2523  * The variable path (passed by reference) should be set to the start
2524  * of the path before the first call; path_advance will update
2525  * this value as it proceeds.  Successive calls to path_advance will return
2526  * the possible path expansions in sequence.  If an option (indicated by
2527  * a percent sign) appears in the path entry then the global variable
2528  * pathopt will be set to point to it; otherwise pathopt will be set to
2529  * NULL.
2530  */
2531 static const char *pathopt;     /* set by path_advance */
2532
2533 static char *
2534 path_advance(const char **path, const char *name)
2535 {
2536         const char *p;
2537         char *q;
2538         const char *start;
2539         size_t len;
2540
2541         if (*path == NULL)
2542                 return NULL;
2543         start = *path;
2544         for (p = start; *p && *p != ':' && *p != '%'; p++)
2545                 continue;
2546         len = p - start + strlen(name) + 2;     /* "2" is for '/' and '\0' */
2547         while (stackblocksize() < len)
2548                 growstackblock();
2549         q = stackblock();
2550         if (p != start) {
2551                 q = mempcpy(q, start, p - start);
2552                 *q++ = '/';
2553         }
2554         strcpy(q, name);
2555         pathopt = NULL;
2556         if (*p == '%') {
2557                 pathopt = ++p;
2558                 while (*p && *p != ':')
2559                         p++;
2560         }
2561         if (*p == ':')
2562                 *path = p + 1;
2563         else
2564                 *path = NULL;
2565         return stalloc(len);
2566 }
2567
2568
2569 /* ============ Prompt */
2570
2571 static smallint doprompt;                   /* if set, prompt the user */
2572 static smallint needprompt;                 /* true if interactive and at start of line */
2573
2574 #if ENABLE_FEATURE_EDITING
2575 static line_input_t *line_input_state;
2576 static const char *cmdedit_prompt;
2577 static void
2578 putprompt(const char *s)
2579 {
2580         if (ENABLE_ASH_EXPAND_PRMT) {
2581                 free((char*)cmdedit_prompt);
2582                 cmdedit_prompt = ckstrdup(s);
2583                 return;
2584         }
2585         cmdedit_prompt = s;
2586 }
2587 #else
2588 static void
2589 putprompt(const char *s)
2590 {
2591         out2str(s);
2592 }
2593 #endif
2594
2595 /* expandstr() needs parsing machinery, so it is far away ahead... */
2596 static const char *expandstr(const char *ps, int syntax_type);
2597 /* Values for syntax param */
2598 #define BASESYNTAX 0    /* not in quotes */
2599 #define DQSYNTAX   1    /* in double quotes */
2600 #define SQSYNTAX   2    /* in single quotes */
2601 #define ARISYNTAX  3    /* in arithmetic */
2602 #if ENABLE_ASH_EXPAND_PRMT
2603 # define PSSYNTAX  4    /* prompt. never passed to SIT() */
2604 #endif
2605 /* PSSYNTAX expansion is identical to DQSYNTAX, except keeping '\$' as '\$' */
2606
2607 /*
2608  * called by editline -- any expansions to the prompt should be added here.
2609  */
2610 static void
2611 setprompt_if(smallint do_set, int whichprompt)
2612 {
2613         const char *prompt;
2614         IF_ASH_EXPAND_PRMT(struct stackmark smark;)
2615
2616         if (!do_set)
2617                 return;
2618
2619         needprompt = 0;
2620
2621         switch (whichprompt) {
2622         case 1:
2623                 prompt = ps1val();
2624                 break;
2625         case 2:
2626                 prompt = ps2val();
2627                 break;
2628         default:                        /* 0 */
2629                 prompt = nullstr;
2630         }
2631 #if ENABLE_ASH_EXPAND_PRMT
2632         pushstackmark(&smark, stackblocksize());
2633         putprompt(expandstr(prompt, PSSYNTAX));
2634         popstackmark(&smark);
2635 #else
2636         putprompt(prompt);
2637 #endif
2638 }
2639
2640
2641 /* ============ The cd and pwd commands */
2642
2643 #define CD_PHYSICAL 1
2644 #define CD_PRINT 2
2645
2646 static int
2647 cdopt(void)
2648 {
2649         int flags = 0;
2650         int i, j;
2651
2652         j = 'L';
2653         while ((i = nextopt("LP")) != '\0') {
2654                 if (i != j) {
2655                         flags ^= CD_PHYSICAL;
2656                         j = i;
2657                 }
2658         }
2659
2660         return flags;
2661 }
2662
2663 /*
2664  * Update curdir (the name of the current directory) in response to a
2665  * cd command.
2666  */
2667 static const char *
2668 updatepwd(const char *dir)
2669 {
2670         char *new;
2671         char *p;
2672         char *cdcomppath;
2673         const char *lim;
2674
2675         cdcomppath = sstrdup(dir);
2676         STARTSTACKSTR(new);
2677         if (*dir != '/') {
2678                 if (curdir == nullstr)
2679                         return 0;
2680                 new = stack_putstr(curdir, new);
2681         }
2682         new = makestrspace(strlen(dir) + 2, new);
2683         lim = (char *)stackblock() + 1;
2684         if (*dir != '/') {
2685                 if (new[-1] != '/')
2686                         USTPUTC('/', new);
2687                 if (new > lim && *lim == '/')
2688                         lim++;
2689         } else {
2690                 USTPUTC('/', new);
2691                 cdcomppath++;
2692                 if (dir[1] == '/' && dir[2] != '/') {
2693                         USTPUTC('/', new);
2694                         cdcomppath++;
2695                         lim++;
2696                 }
2697         }
2698         p = strtok(cdcomppath, "/");
2699         while (p) {
2700                 switch (*p) {
2701                 case '.':
2702                         if (p[1] == '.' && p[2] == '\0') {
2703                                 while (new > lim) {
2704                                         STUNPUTC(new);
2705                                         if (new[-1] == '/')
2706                                                 break;
2707                                 }
2708                                 break;
2709                         }
2710                         if (p[1] == '\0')
2711                                 break;
2712                         /* fall through */
2713                 default:
2714                         new = stack_putstr(p, new);
2715                         USTPUTC('/', new);
2716                 }
2717                 p = strtok(NULL, "/");
2718         }
2719         if (new > lim)
2720                 STUNPUTC(new);
2721         *new = 0;
2722         return stackblock();
2723 }
2724
2725 /*
2726  * Find out what the current directory is. If we already know the current
2727  * directory, this routine returns immediately.
2728  */
2729 static char *
2730 getpwd(void)
2731 {
2732         char *dir = getcwd(NULL, 0); /* huh, using glibc extension? */
2733         return dir ? dir : nullstr;
2734 }
2735
2736 static void
2737 setpwd(const char *val, int setold)
2738 {
2739         char *oldcur, *dir;
2740
2741         oldcur = dir = curdir;
2742
2743         if (setold) {
2744                 setvar("OLDPWD", oldcur, VEXPORT);
2745         }
2746         INT_OFF;
2747         if (physdir != nullstr) {
2748                 if (physdir != oldcur)
2749                         free(physdir);
2750                 physdir = nullstr;
2751         }
2752         if (oldcur == val || !val) {
2753                 char *s = getpwd();
2754                 physdir = s;
2755                 if (!val)
2756                         dir = s;
2757         } else
2758                 dir = ckstrdup(val);
2759         if (oldcur != dir && oldcur != nullstr) {
2760                 free(oldcur);
2761         }
2762         curdir = dir;
2763         INT_ON;
2764         setvar("PWD", dir, VEXPORT);
2765 }
2766
2767 static void hashcd(void);
2768
2769 /*
2770  * Actually do the chdir.  We also call hashcd to let other routines
2771  * know that the current directory has changed.
2772  */
2773 static int
2774 docd(const char *dest, int flags)
2775 {
2776         const char *dir = NULL;
2777         int err;
2778
2779         TRACE(("docd(\"%s\", %d) called\n", dest, flags));
2780
2781         INT_OFF;
2782         if (!(flags & CD_PHYSICAL)) {
2783                 dir = updatepwd(dest);
2784                 if (dir)
2785                         dest = dir;
2786         }
2787         err = chdir(dest);
2788         if (err)
2789                 goto out;
2790         setpwd(dir, 1);
2791         hashcd();
2792  out:
2793         INT_ON;
2794         return err;
2795 }
2796
2797 static int FAST_FUNC
2798 cdcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
2799 {
2800         const char *dest;
2801         const char *path;
2802         const char *p;
2803         char c;
2804         struct stat statb;
2805         int flags;
2806
2807         flags = cdopt();
2808         dest = *argptr;
2809         if (!dest)
2810                 dest = bltinlookup("HOME");
2811         else if (LONE_DASH(dest)) {
2812                 dest = bltinlookup("OLDPWD");
2813                 flags |= CD_PRINT;
2814         }
2815         if (!dest)
2816                 dest = nullstr;
2817         if (*dest == '/')
2818                 goto step6;
2819         if (*dest == '.') {
2820                 c = dest[1];
2821  dotdot:
2822                 switch (c) {
2823                 case '\0':
2824                 case '/':
2825                         goto step6;
2826                 case '.':
2827                         c = dest[2];
2828                         if (c != '.')
2829                                 goto dotdot;
2830                 }
2831         }
2832         if (!*dest)
2833                 dest = ".";
2834         path = bltinlookup("CDPATH");
2835         while (path) {
2836                 c = *path;
2837                 p = path_advance(&path, dest);
2838                 if (stat(p, &statb) >= 0 && S_ISDIR(statb.st_mode)) {
2839                         if (c && c != ':')
2840                                 flags |= CD_PRINT;
2841  docd:
2842                         if (!docd(p, flags))
2843                                 goto out;
2844                         goto err;
2845                 }
2846         }
2847
2848  step6:
2849         p = dest;
2850         goto docd;
2851
2852  err:
2853         ash_msg_and_raise_perror("can't cd to %s", dest);
2854         /* NOTREACHED */
2855  out:
2856         if (flags & CD_PRINT)
2857                 out1fmt("%s\n", curdir);
2858         return 0;
2859 }
2860
2861 static int FAST_FUNC
2862 pwdcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
2863 {
2864         int flags;
2865         const char *dir = curdir;
2866
2867         flags = cdopt();
2868         if (flags) {
2869                 if (physdir == nullstr)
2870                         setpwd(dir, 0);
2871                 dir = physdir;
2872         }
2873         out1fmt("%s\n", dir);
2874         return 0;
2875 }
2876
2877
2878 /* ============ ... */
2879
2880
2881 #define IBUFSIZ (ENABLE_FEATURE_EDITING ? CONFIG_FEATURE_EDITING_MAX_LEN : 1024)
2882
2883 /* Syntax classes */
2884 #define CWORD     0             /* character is nothing special */
2885 #define CNL       1             /* newline character */
2886 #define CBACK     2             /* a backslash character */
2887 #define CSQUOTE   3             /* single quote */
2888 #define CDQUOTE   4             /* double quote */
2889 #define CENDQUOTE 5             /* a terminating quote */
2890 #define CBQUOTE   6             /* backwards single quote */
2891 #define CVAR      7             /* a dollar sign */
2892 #define CENDVAR   8             /* a '}' character */
2893 #define CLP       9             /* a left paren in arithmetic */
2894 #define CRP      10             /* a right paren in arithmetic */
2895 #define CENDFILE 11             /* end of file */
2896 #define CCTL     12             /* like CWORD, except it must be escaped */
2897 #define CSPCL    13             /* these terminate a word */
2898 #define CIGN     14             /* character should be ignored */
2899
2900 #define PEOF     256
2901 #if ENABLE_ASH_ALIAS
2902 # define PEOA    257
2903 #endif
2904
2905 #define USE_SIT_FUNCTION ENABLE_ASH_OPTIMIZE_FOR_SIZE
2906
2907 #if ENABLE_FEATURE_SH_MATH
2908 # define SIT_ITEM(a,b,c,d) (a | (b << 4) | (c << 8) | (d << 12))
2909 #else
2910 # define SIT_ITEM(a,b,c,d) (a | (b << 4) | (c << 8))
2911 #endif
2912 static const uint16_t S_I_T[] ALIGN2 = {
2913 #if ENABLE_ASH_ALIAS
2914         SIT_ITEM(CSPCL   , CIGN     , CIGN , CIGN   ),    /* 0, PEOA */
2915 #endif
2916         SIT_ITEM(CSPCL   , CWORD    , CWORD, CWORD  ),    /* 1, ' ' */
2917         SIT_ITEM(CNL     , CNL      , CNL  , CNL    ),    /* 2, \n */
2918         SIT_ITEM(CWORD   , CCTL     , CCTL , CWORD  ),    /* 3, !*-/:=?[]~ */
2919         SIT_ITEM(CDQUOTE , CENDQUOTE, CWORD, CWORD  ),    /* 4, '"' */
2920         SIT_ITEM(CVAR    , CVAR     , CWORD, CVAR   ),    /* 5, $ */
2921         SIT_ITEM(CSQUOTE , CWORD    , CENDQUOTE, CWORD),  /* 6, "'" */
2922         SIT_ITEM(CSPCL   , CWORD    , CWORD, CLP    ),    /* 7, ( */
2923         SIT_ITEM(CSPCL   , CWORD    , CWORD, CRP    ),    /* 8, ) */
2924         SIT_ITEM(CBACK   , CBACK    , CCTL , CBACK  ),    /* 9, \ */
2925         SIT_ITEM(CBQUOTE , CBQUOTE  , CWORD, CBQUOTE),    /* 10, ` */
2926         SIT_ITEM(CENDVAR , CENDVAR  , CWORD, CENDVAR),    /* 11, } */
2927 #if !USE_SIT_FUNCTION
2928         SIT_ITEM(CENDFILE, CENDFILE , CENDFILE, CENDFILE),/* 12, PEOF */
2929         SIT_ITEM(CWORD   , CWORD    , CWORD, CWORD  ),    /* 13, 0-9A-Za-z */
2930         SIT_ITEM(CCTL    , CCTL     , CCTL , CCTL   )     /* 14, CTLESC ... */
2931 #endif
2932 #undef SIT_ITEM
2933 };
2934 /* Constants below must match table above */
2935 enum {
2936 #if ENABLE_ASH_ALIAS
2937         CSPCL_CIGN_CIGN_CIGN               , /*  0 */
2938 #endif
2939         CSPCL_CWORD_CWORD_CWORD            , /*  1 */
2940         CNL_CNL_CNL_CNL                    , /*  2 */
2941         CWORD_CCTL_CCTL_CWORD              , /*  3 */
2942         CDQUOTE_CENDQUOTE_CWORD_CWORD      , /*  4 */
2943         CVAR_CVAR_CWORD_CVAR               , /*  5 */
2944         CSQUOTE_CWORD_CENDQUOTE_CWORD      , /*  6 */
2945         CSPCL_CWORD_CWORD_CLP              , /*  7 */
2946         CSPCL_CWORD_CWORD_CRP              , /*  8 */
2947         CBACK_CBACK_CCTL_CBACK             , /*  9 */
2948         CBQUOTE_CBQUOTE_CWORD_CBQUOTE      , /* 10 */
2949         CENDVAR_CENDVAR_CWORD_CENDVAR      , /* 11 */
2950         CENDFILE_CENDFILE_CENDFILE_CENDFILE, /* 12 */
2951         CWORD_CWORD_CWORD_CWORD            , /* 13 */
2952         CCTL_CCTL_CCTL_CCTL                , /* 14 */
2953 };
2954
2955 /* c in SIT(c, syntax) must be an *unsigned char* or PEOA or PEOF,
2956  * caller must ensure proper cast on it if c is *char_ptr!
2957  */
2958 #if USE_SIT_FUNCTION
2959
2960 static int
2961 SIT(int c, int syntax)
2962 {
2963         /* Used to also have '/' in this string: "\t\n !\"$&'()*-/:;<=>?[\\]`|}~" */
2964         static const char spec_symbls[] ALIGN1 = "\t\n !\"$&'()*-:;<=>?[\\]`|}~";
2965         /*
2966          * This causes '/' to be prepended with CTLESC in dquoted string,
2967          * making "./file"* treated incorrectly because we feed
2968          * ".\/file*" string to glob(), confusing it (see expandmeta func).
2969          * The "homegrown" glob implementation is okay with that,
2970          * but glibc one isn't. With '/' always treated as CWORD,
2971          * both work fine.
2972          */
2973 # if ENABLE_ASH_ALIAS
2974         static const uint8_t syntax_index_table[] ALIGN1 = {
2975                 1, 2, 1, 3, 4, 5, 1, 6,         /* "\t\n !\"$&'" */
2976                 7, 8, 3, 3,/*3,*/3, 1, 1,       /* "()*-/:;<" */
2977                 3, 1, 3, 3, 9, 3, 10, 1,        /* "=>?[\\]`|" */
2978                 11, 3                           /* "}~" */
2979         };
2980 # else
2981         static const uint8_t syntax_index_table[] ALIGN1 = {
2982                 0, 1, 0, 2, 3, 4, 0, 5,         /* "\t\n !\"$&'" */
2983                 6, 7, 2, 2,/*2,*/2, 0, 0,       /* "()*-/:;<" */
2984                 2, 0, 2, 2, 8, 2, 9, 0,         /* "=>?[\\]`|" */
2985                 10, 2                           /* "}~" */
2986         };
2987 # endif
2988         const char *s;
2989         int indx;
2990
2991         if (c == PEOF)
2992                 return CENDFILE;
2993 # if ENABLE_ASH_ALIAS
2994         if (c == PEOA)
2995                 indx = 0;
2996         else
2997 # endif
2998         {
2999                 /* Cast is purely for paranoia here,
3000                  * just in case someone passed signed char to us */
3001                 if ((unsigned char)c >= CTL_FIRST
3002                  && (unsigned char)c <= CTL_LAST
3003                 ) {
3004                         return CCTL;
3005                 }
3006                 s = strchrnul(spec_symbls, c);
3007                 if (*s == '\0')
3008                         return CWORD;
3009                 indx = syntax_index_table[s - spec_symbls];
3010         }
3011         return (S_I_T[indx] >> (syntax*4)) & 0xf;
3012 }
3013
3014 #else   /* !USE_SIT_FUNCTION */
3015
3016 static const uint8_t syntax_index_table[] ALIGN1 = {
3017         /* BASESYNTAX_DQSYNTAX_SQSYNTAX_ARISYNTAX */
3018         /*   0      */ CWORD_CWORD_CWORD_CWORD,
3019         /*   1      */ CWORD_CWORD_CWORD_CWORD,
3020         /*   2      */ CWORD_CWORD_CWORD_CWORD,
3021         /*   3      */ CWORD_CWORD_CWORD_CWORD,
3022         /*   4      */ CWORD_CWORD_CWORD_CWORD,
3023         /*   5      */ CWORD_CWORD_CWORD_CWORD,
3024         /*   6      */ CWORD_CWORD_CWORD_CWORD,
3025         /*   7      */ CWORD_CWORD_CWORD_CWORD,
3026         /*   8      */ CWORD_CWORD_CWORD_CWORD,
3027         /*   9 "\t" */ CSPCL_CWORD_CWORD_CWORD,
3028         /*  10 "\n" */ CNL_CNL_CNL_CNL,
3029         /*  11      */ CWORD_CWORD_CWORD_CWORD,
3030         /*  12      */ CWORD_CWORD_CWORD_CWORD,
3031         /*  13      */ CWORD_CWORD_CWORD_CWORD,
3032         /*  14      */ CWORD_CWORD_CWORD_CWORD,
3033         /*  15      */ CWORD_CWORD_CWORD_CWORD,
3034         /*  16      */ CWORD_CWORD_CWORD_CWORD,
3035         /*  17      */ CWORD_CWORD_CWORD_CWORD,
3036         /*  18      */ CWORD_CWORD_CWORD_CWORD,
3037         /*  19      */ CWORD_CWORD_CWORD_CWORD,
3038         /*  20      */ CWORD_CWORD_CWORD_CWORD,
3039         /*  21      */ CWORD_CWORD_CWORD_CWORD,
3040         /*  22      */ CWORD_CWORD_CWORD_CWORD,
3041         /*  23      */ CWORD_CWORD_CWORD_CWORD,
3042         /*  24      */ CWORD_CWORD_CWORD_CWORD,
3043         /*  25      */ CWORD_CWORD_CWORD_CWORD,
3044         /*  26      */ CWORD_CWORD_CWORD_CWORD,
3045         /*  27      */ CWORD_CWORD_CWORD_CWORD,
3046         /*  28      */ CWORD_CWORD_CWORD_CWORD,
3047         /*  29      */ CWORD_CWORD_CWORD_CWORD,
3048         /*  30      */ CWORD_CWORD_CWORD_CWORD,
3049         /*  31      */ CWORD_CWORD_CWORD_CWORD,
3050         /*  32  " " */ CSPCL_CWORD_CWORD_CWORD,
3051         /*  33  "!" */ CWORD_CCTL_CCTL_CWORD,
3052         /*  34  """ */ CDQUOTE_CENDQUOTE_CWORD_CWORD,
3053         /*  35  "#" */ CWORD_CWORD_CWORD_CWORD,
3054         /*  36  "$" */ CVAR_CVAR_CWORD_CVAR,
3055         /*  37  "%" */ CWORD_CWORD_CWORD_CWORD,
3056         /*  38  "&" */ CSPCL_CWORD_CWORD_CWORD,
3057         /*  39  "'" */ CSQUOTE_CWORD_CENDQUOTE_CWORD,
3058         /*  40  "(" */ CSPCL_CWORD_CWORD_CLP,
3059         /*  41  ")" */ CSPCL_CWORD_CWORD_CRP,
3060         /*  42  "*" */ CWORD_CCTL_CCTL_CWORD,
3061         /*  43  "+" */ CWORD_CWORD_CWORD_CWORD,
3062         /*  44  "," */ CWORD_CWORD_CWORD_CWORD,
3063         /*  45  "-" */ CWORD_CCTL_CCTL_CWORD,
3064         /*  46  "." */ CWORD_CWORD_CWORD_CWORD,
3065 /* "/" was CWORD_CCTL_CCTL_CWORD, see comment in SIT() function why this is changed: */
3066         /*  47  "/" */ CWORD_CWORD_CWORD_CWORD,
3067         /*  48  "0" */ CWORD_CWORD_CWORD_CWORD,
3068         /*  49  "1" */ CWORD_CWORD_CWORD_CWORD,
3069         /*  50  "2" */ CWORD_CWORD_CWORD_CWORD,
3070         /*  51  "3" */ CWORD_CWORD_CWORD_CWORD,
3071         /*  52  "4" */ CWORD_CWORD_CWORD_CWORD,
3072         /*  53  "5" */ CWORD_CWORD_CWORD_CWORD,
3073         /*  54  "6" */ CWORD_CWORD_CWORD_CWORD,
3074         /*  55  "7" */ CWORD_CWORD_CWORD_CWORD,
3075         /*  56  "8" */ CWORD_CWORD_CWORD_CWORD,
3076         /*  57  "9" */ CWORD_CWORD_CWORD_CWORD,
3077         /*  58  ":" */ CWORD_CCTL_CCTL_CWORD,
3078         /*  59  ";" */ CSPCL_CWORD_CWORD_CWORD,
3079         /*  60  "<" */ CSPCL_CWORD_CWORD_CWORD,
3080         /*  61  "=" */ CWORD_CCTL_CCTL_CWORD,
3081         /*  62  ">" */ CSPCL_CWORD_CWORD_CWORD,
3082         /*  63  "?" */ CWORD_CCTL_CCTL_CWORD,
3083         /*  64  "@" */ CWORD_CWORD_CWORD_CWORD,
3084         /*  65  "A" */ CWORD_CWORD_CWORD_CWORD,
3085         /*  66  "B" */ CWORD_CWORD_CWORD_CWORD,
3086         /*  67  "C" */ CWORD_CWORD_CWORD_CWORD,
3087         /*  68  "D" */ CWORD_CWORD_CWORD_CWORD,
3088         /*  69  "E" */ CWORD_CWORD_CWORD_CWORD,
3089         /*  70  "F" */ CWORD_CWORD_CWORD_CWORD,
3090         /*  71  "G" */ CWORD_CWORD_CWORD_CWORD,
3091         /*  72  "H" */ CWORD_CWORD_CWORD_CWORD,
3092         /*  73  "I" */ CWORD_CWORD_CWORD_CWORD,
3093         /*  74  "J" */ CWORD_CWORD_CWORD_CWORD,
3094         /*  75  "K" */ CWORD_CWORD_CWORD_CWORD,
3095         /*  76  "L" */ CWORD_CWORD_CWORD_CWORD,
3096         /*  77  "M" */ CWORD_CWORD_CWORD_CWORD,
3097         /*  78  "N" */ CWORD_CWORD_CWORD_CWORD,
3098         /*  79  "O" */ CWORD_CWORD_CWORD_CWORD,
3099         /*  80  "P" */ CWORD_CWORD_CWORD_CWORD,
3100         /*  81  "Q" */ CWORD_CWORD_CWORD_CWORD,
3101         /*  82  "R" */ CWORD_CWORD_CWORD_CWORD,
3102         /*  83  "S" */ CWORD_CWORD_CWORD_CWORD,
3103         /*  84  "T" */ CWORD_CWORD_CWORD_CWORD,
3104         /*  85  "U" */ CWORD_CWORD_CWORD_CWORD,
3105         /*  86  "V" */ CWORD_CWORD_CWORD_CWORD,
3106         /*  87  "W" */ CWORD_CWORD_CWORD_CWORD,
3107         /*  88  "X" */ CWORD_CWORD_CWORD_CWORD,
3108         /*  89  "Y" */ CWORD_CWORD_CWORD_CWORD,
3109         /*  90  "Z" */ CWORD_CWORD_CWORD_CWORD,
3110         /*  91  "[" */ CWORD_CCTL_CCTL_CWORD,
3111         /*  92  "\" */ CBACK_CBACK_CCTL_CBACK,
3112         /*  93  "]" */ CWORD_CCTL_CCTL_CWORD,
3113         /*  94  "^" */ CWORD_CWORD_CWORD_CWORD,
3114         /*  95  "_" */ CWORD_CWORD_CWORD_CWORD,
3115         /*  96  "`" */ CBQUOTE_CBQUOTE_CWORD_CBQUOTE,
3116         /*  97  "a" */ CWORD_CWORD_CWORD_CWORD,
3117         /*  98  "b" */ CWORD_CWORD_CWORD_CWORD,
3118         /*  99  "c" */ CWORD_CWORD_CWORD_CWORD,
3119         /* 100  "d" */ CWORD_CWORD_CWORD_CWORD,
3120         /* 101  "e" */ CWORD_CWORD_CWORD_CWORD,
3121         /* 102  "f" */ CWORD_CWORD_CWORD_CWORD,
3122         /* 103  "g" */ CWORD_CWORD_CWORD_CWORD,
3123         /* 104  "h" */ CWORD_CWORD_CWORD_CWORD,
3124         /* 105  "i" */ CWORD_CWORD_CWORD_CWORD,
3125         /* 106  "j" */ CWORD_CWORD_CWORD_CWORD,
3126         /* 107  "k" */ CWORD_CWORD_CWORD_CWORD,
3127         /* 108  "l" */ CWORD_CWORD_CWORD_CWORD,
3128         /* 109  "m" */ CWORD_CWORD_CWORD_CWORD,
3129         /* 110  "n" */ CWORD_CWORD_CWORD_CWORD,
3130         /* 111  "o" */ CWORD_CWORD_CWORD_CWORD,
3131         /* 112  "p" */ CWORD_CWORD_CWORD_CWORD,
3132         /* 113  "q" */ CWORD_CWORD_CWORD_CWORD,
3133         /* 114  "r" */ CWORD_CWORD_CWORD_CWORD,
3134         /* 115  "s" */ CWORD_CWORD_CWORD_CWORD,
3135         /* 116  "t" */ CWORD_CWORD_CWORD_CWORD,
3136         /* 117  "u" */ CWORD_CWORD_CWORD_CWORD,
3137         /* 118  "v" */ CWORD_CWORD_CWORD_CWORD,
3138         /* 119  "w" */ CWORD_CWORD_CWORD_CWORD,
3139         /* 120  "x" */ CWORD_CWORD_CWORD_CWORD,
3140         /* 121  "y" */ CWORD_CWORD_CWORD_CWORD,
3141         /* 122  "z" */ CWORD_CWORD_CWORD_CWORD,
3142         /* 123  "{" */ CWORD_CWORD_CWORD_CWORD,
3143         /* 124  "|" */ CSPCL_CWORD_CWORD_CWORD,
3144         /* 125  "}" */ CENDVAR_CENDVAR_CWORD_CENDVAR,
3145         /* 126  "~" */ CWORD_CCTL_CCTL_CWORD,
3146         /* 127  del */ CWORD_CWORD_CWORD_CWORD,
3147         /* 128 0x80 */ CWORD_CWORD_CWORD_CWORD,
3148         /* 129 CTLESC       */ CCTL_CCTL_CCTL_CCTL,
3149         /* 130 CTLVAR       */ CCTL_CCTL_CCTL_CCTL,
3150         /* 131 CTLENDVAR    */ CCTL_CCTL_CCTL_CCTL,
3151         /* 132 CTLBACKQ     */ CCTL_CCTL_CCTL_CCTL,
3152         /* 133 CTLQUOTE     */ CCTL_CCTL_CCTL_CCTL,
3153         /* 134 CTLARI       */ CCTL_CCTL_CCTL_CCTL,
3154         /* 135 CTLENDARI    */ CCTL_CCTL_CCTL_CCTL,
3155         /* 136 CTLQUOTEMARK */ CCTL_CCTL_CCTL_CCTL,
3156         /* 137      */ CWORD_CWORD_CWORD_CWORD,
3157         /* 138      */ CWORD_CWORD_CWORD_CWORD,
3158         /* 139      */ CWORD_CWORD_CWORD_CWORD,
3159         /* 140      */ CWORD_CWORD_CWORD_CWORD,
3160         /* 141      */ CWORD_CWORD_CWORD_CWORD,
3161         /* 142      */ CWORD_CWORD_CWORD_CWORD,
3162         /* 143      */ CWORD_CWORD_CWORD_CWORD,
3163         /* 144      */ CWORD_CWORD_CWORD_CWORD,
3164         /* 145      */ CWORD_CWORD_CWORD_CWORD,
3165         /* 146      */ CWORD_CWORD_CWORD_CWORD,
3166         /* 147      */ CWORD_CWORD_CWORD_CWORD,
3167         /* 148      */ CWORD_CWORD_CWORD_CWORD,
3168         /* 149      */ CWORD_CWORD_CWORD_CWORD,
3169         /* 150      */ CWORD_CWORD_CWORD_CWORD,
3170         /* 151      */ CWORD_CWORD_CWORD_CWORD,
3171         /* 152      */ CWORD_CWORD_CWORD_CWORD,
3172         /* 153      */ CWORD_CWORD_CWORD_CWORD,
3173         /* 154      */ CWORD_CWORD_CWORD_CWORD,
3174         /* 155      */ CWORD_CWORD_CWORD_CWORD,
3175         /* 156      */ CWORD_CWORD_CWORD_CWORD,
3176         /* 157      */ CWORD_CWORD_CWORD_CWORD,
3177         /* 158      */ CWORD_CWORD_CWORD_CWORD,
3178         /* 159      */ CWORD_CWORD_CWORD_CWORD,
3179         /* 160      */ CWORD_CWORD_CWORD_CWORD,
3180         /* 161      */ CWORD_CWORD_CWORD_CWORD,
3181         /* 162      */ CWORD_CWORD_CWORD_CWORD,
3182         /* 163      */ CWORD_CWORD_CWORD_CWORD,
3183         /* 164      */ CWORD_CWORD_CWORD_CWORD,
3184         /* 165      */ CWORD_CWORD_CWORD_CWORD,
3185         /* 166      */ CWORD_CWORD_CWORD_CWORD,
3186         /* 167      */ CWORD_CWORD_CWORD_CWORD,
3187         /* 168      */ CWORD_CWORD_CWORD_CWORD,
3188         /* 169      */ CWORD_CWORD_CWORD_CWORD,
3189         /* 170      */ CWORD_CWORD_CWORD_CWORD,
3190         /* 171      */ CWORD_CWORD_CWORD_CWORD,
3191         /* 172      */ CWORD_CWORD_CWORD_CWORD,
3192         /* 173      */ CWORD_CWORD_CWORD_CWORD,
3193         /* 174      */ CWORD_CWORD_CWORD_CWORD,
3194         /* 175      */ CWORD_CWORD_CWORD_CWORD,
3195         /* 176      */ CWORD_CWORD_CWORD_CWORD,
3196         /* 177      */ CWORD_CWORD_CWORD_CWORD,
3197         /* 178      */ CWORD_CWORD_CWORD_CWORD,
3198         /* 179      */ CWORD_CWORD_CWORD_CWORD,
3199         /* 180      */ CWORD_CWORD_CWORD_CWORD,
3200         /* 181      */ CWORD_CWORD_CWORD_CWORD,
3201         /* 182      */ CWORD_CWORD_CWORD_CWORD,
3202         /* 183      */ CWORD_CWORD_CWORD_CWORD,
3203         /* 184      */ CWORD_CWORD_CWORD_CWORD,
3204         /* 185      */ CWORD_CWORD_CWORD_CWORD,
3205         /* 186      */ CWORD_CWORD_CWORD_CWORD,
3206         /* 187      */ CWORD_CWORD_CWORD_CWORD,
3207         /* 188      */ CWORD_CWORD_CWORD_CWORD,
3208         /* 189      */ CWORD_CWORD_CWORD_CWORD,
3209         /* 190      */ CWORD_CWORD_CWORD_CWORD,
3210         /* 191      */ CWORD_CWORD_CWORD_CWORD,
3211         /* 192      */ CWORD_CWORD_CWORD_CWORD,
3212         /* 193      */ CWORD_CWORD_CWORD_CWORD,
3213         /* 194      */ CWORD_CWORD_CWORD_CWORD,
3214         /* 195      */ CWORD_CWORD_CWORD_CWORD,
3215         /* 196      */ CWORD_CWORD_CWORD_CWORD,
3216         /* 197      */ CWORD_CWORD_CWORD_CWORD,
3217         /* 198      */ CWORD_CWORD_CWORD_CWORD,
3218         /* 199      */ CWORD_CWORD_CWORD_CWORD,
3219         /* 200      */ CWORD_CWORD_CWORD_CWORD,
3220         /* 201      */ CWORD_CWORD_CWORD_CWORD,
3221         /* 202      */ CWORD_CWORD_CWORD_CWORD,
3222         /* 203      */ CWORD_CWORD_CWORD_CWORD,
3223         /* 204      */ CWORD_CWORD_CWORD_CWORD,
3224         /* 205      */ CWORD_CWORD_CWORD_CWORD,
3225         /* 206      */ CWORD_CWORD_CWORD_CWORD,
3226         /* 207      */ CWORD_CWORD_CWORD_CWORD,
3227         /* 208      */ CWORD_CWORD_CWORD_CWORD,
3228         /* 209      */ CWORD_CWORD_CWORD_CWORD,
3229         /* 210      */ CWORD_CWORD_CWORD_CWORD,
3230         /* 211      */ CWORD_CWORD_CWORD_CWORD,
3231         /* 212      */ CWORD_CWORD_CWORD_CWORD,
3232         /* 213      */ CWORD_CWORD_CWORD_CWORD,
3233         /* 214      */ CWORD_CWORD_CWORD_CWORD,
3234         /* 215      */ CWORD_CWORD_CWORD_CWORD,
3235         /* 216      */ CWORD_CWORD_CWORD_CWORD,
3236         /* 217      */ CWORD_CWORD_CWORD_CWORD,
3237         /* 218      */ CWORD_CWORD_CWORD_CWORD,
3238         /* 219      */ CWORD_CWORD_CWORD_CWORD,
3239         /* 220      */ CWORD_CWORD_CWORD_CWORD,
3240         /* 221      */ CWORD_CWORD_CWORD_CWORD,
3241         /* 222      */ CWORD_CWORD_CWORD_CWORD,
3242         /* 223      */ CWORD_CWORD_CWORD_CWORD,
3243         /* 224      */ CWORD_CWORD_CWORD_CWORD,
3244         /* 225      */ CWORD_CWORD_CWORD_CWORD,
3245         /* 226      */ CWORD_CWORD_CWORD_CWORD,
3246         /* 227      */ CWORD_CWORD_CWORD_CWORD,
3247         /* 228      */ CWORD_CWORD_CWORD_CWORD,
3248         /* 229      */ CWORD_CWORD_CWORD_CWORD,
3249         /* 230      */ CWORD_CWORD_CWORD_CWORD,
3250         /* 231      */ CWORD_CWORD_CWORD_CWORD,
3251         /* 232      */ CWORD_CWORD_CWORD_CWORD,
3252         /* 233      */ CWORD_CWORD_CWORD_CWORD,
3253         /* 234      */ CWORD_CWORD_CWORD_CWORD,
3254         /* 235      */ CWORD_CWORD_CWORD_CWORD,
3255         /* 236      */ CWORD_CWORD_CWORD_CWORD,
3256         /* 237      */ CWORD_CWORD_CWORD_CWORD,
3257         /* 238      */ CWORD_CWORD_CWORD_CWORD,
3258         /* 239      */ CWORD_CWORD_CWORD_CWORD,
3259         /* 230      */ CWORD_CWORD_CWORD_CWORD,
3260         /* 241      */ CWORD_CWORD_CWORD_CWORD,
3261         /* 242      */ CWORD_CWORD_CWORD_CWORD,
3262         /* 243      */ CWORD_CWORD_CWORD_CWORD,
3263         /* 244      */ CWORD_CWORD_CWORD_CWORD,
3264         /* 245      */ CWORD_CWORD_CWORD_CWORD,
3265         /* 246      */ CWORD_CWORD_CWORD_CWORD,
3266         /* 247      */ CWORD_CWORD_CWORD_CWORD,
3267         /* 248      */ CWORD_CWORD_CWORD_CWORD,
3268         /* 249      */ CWORD_CWORD_CWORD_CWORD,
3269         /* 250      */ CWORD_CWORD_CWORD_CWORD,
3270         /* 251      */ CWORD_CWORD_CWORD_CWORD,
3271         /* 252      */ CWORD_CWORD_CWORD_CWORD,
3272         /* 253      */ CWORD_CWORD_CWORD_CWORD,
3273         /* 254      */ CWORD_CWORD_CWORD_CWORD,
3274         /* 255      */ CWORD_CWORD_CWORD_CWORD,
3275         /* PEOF */     CENDFILE_CENDFILE_CENDFILE_CENDFILE,
3276 # if ENABLE_ASH_ALIAS
3277         /* PEOA */     CSPCL_CIGN_CIGN_CIGN,
3278 # endif
3279 };
3280
3281 #if 1
3282 # define SIT(c, syntax) ((S_I_T[syntax_index_table[c]] >> ((syntax)*4)) & 0xf)
3283 #else /* debug version, caught one signed char bug */
3284 # define SIT(c, syntax) \
3285         ({ \
3286                 if ((c) < 0 || (c) > (PEOF + ENABLE_ASH_ALIAS)) \
3287                         bb_error_msg_and_die("line:%d c:%d", __LINE__, (c)); \
3288                 if ((syntax) < 0 || (syntax) > (2 + ENABLE_FEATURE_SH_MATH)) \
3289                         bb_error_msg_and_die("line:%d c:%d", __LINE__, (c)); \
3290                 ((S_I_T[syntax_index_table[c]] >> ((syntax)*4)) & 0xf); \
3291         })
3292 #endif
3293
3294 #endif  /* !USE_SIT_FUNCTION */
3295
3296
3297 /* ============ Alias handling */
3298
3299 #if ENABLE_ASH_ALIAS
3300
3301 #define ALIASINUSE 1
3302 #define ALIASDEAD  2
3303
3304 struct alias {
3305         struct alias *next;
3306         char *name;
3307         char *val;
3308         int flag;
3309 };
3310
3311
3312 static struct alias **atab; // [ATABSIZE];
3313 #define INIT_G_alias() do { \
3314         atab = xzalloc(ATABSIZE * sizeof(atab[0])); \
3315 } while (0)
3316
3317
3318 static struct alias **
3319 __lookupalias(const char *name)
3320 {
3321         unsigned int hashval;
3322         struct alias **app;
3323         const char *p;
3324         unsigned int ch;
3325
3326         p = name;
3327
3328         ch = (unsigned char)*p;
3329         hashval = ch << 4;
3330         while (ch) {
3331                 hashval += ch;
3332                 ch = (unsigned char)*++p;
3333         }
3334         app = &atab[hashval % ATABSIZE];
3335
3336         for (; *app; app = &(*app)->next) {
3337                 if (strcmp(name, (*app)->name) == 0) {
3338                         break;
3339                 }
3340         }
3341
3342         return app;
3343 }
3344
3345 static struct alias *
3346 lookupalias(const char *name, int check)
3347 {
3348         struct alias *ap = *__lookupalias(name);
3349
3350         if (check && ap && (ap->flag & ALIASINUSE))
3351                 return NULL;
3352         return ap;
3353 }
3354
3355 static struct alias *
3356 freealias(struct alias *ap)
3357 {
3358         struct alias *next;
3359
3360         if (ap->flag & ALIASINUSE) {
3361                 ap->flag |= ALIASDEAD;
3362                 return ap;
3363         }
3364
3365         next = ap->next;
3366         free(ap->name);
3367         free(ap->val);
3368         free(ap);
3369         return next;
3370 }
3371
3372 static void
3373 setalias(const char *name, const char *val)
3374 {
3375         struct alias *ap, **app;
3376
3377         app = __lookupalias(name);
3378         ap = *app;
3379         INT_OFF;
3380         if (ap) {
3381                 if (!(ap->flag & ALIASINUSE)) {
3382                         free(ap->val);
3383                 }
3384                 ap->val = ckstrdup(val);
3385                 ap->flag &= ~ALIASDEAD;
3386         } else {
3387                 /* not found */
3388                 ap = ckzalloc(sizeof(struct alias));
3389                 ap->name = ckstrdup(name);
3390                 ap->val = ckstrdup(val);
3391                 /*ap->flag = 0; - ckzalloc did it */
3392                 /*ap->next = NULL;*/
3393                 *app = ap;
3394         }
3395         INT_ON;
3396 }
3397
3398 static int
3399 unalias(const char *name)
3400 {
3401         struct alias **app;
3402
3403         app = __lookupalias(name);
3404
3405         if (*app) {
3406                 INT_OFF;
3407                 *app = freealias(*app);
3408                 INT_ON;
3409                 return 0;
3410         }
3411
3412         return 1;
3413 }
3414
3415 static void
3416 rmaliases(void)
3417 {
3418         struct alias *ap, **app;
3419         int i;
3420
3421         INT_OFF;
3422         for (i = 0; i < ATABSIZE; i++) {
3423                 app = &atab[i];
3424                 for (ap = *app; ap; ap = *app) {
3425                         *app = freealias(*app);
3426                         if (ap == *app) {
3427                                 app = &ap->next;
3428                         }
3429                 }
3430         }
3431         INT_ON;
3432 }
3433
3434 static void
3435 printalias(const struct alias *ap)
3436 {
3437         out1fmt("%s=%s\n", ap->name, single_quote(ap->val));
3438 }
3439
3440 /*
3441  * TODO - sort output
3442  */
3443 static int FAST_FUNC
3444 aliascmd(int argc UNUSED_PARAM, char **argv)
3445 {
3446         char *n, *v;
3447         int ret = 0;
3448         struct alias *ap;
3449
3450         if (!argv[1]) {
3451                 int i;
3452
3453                 for (i = 0; i < ATABSIZE; i++) {
3454                         for (ap = atab[i]; ap; ap = ap->next) {
3455                                 printalias(ap);
3456                         }
3457                 }
3458                 return 0;
3459         }
3460         while ((n = *++argv) != NULL) {
3461                 v = strchr(n+1, '=');
3462                 if (v == NULL) { /* n+1: funny ksh stuff */
3463                         ap = *__lookupalias(n);
3464                         if (ap == NULL) {
3465                                 fprintf(stderr, "%s: %s not found\n", "alias", n);
3466                                 ret = 1;
3467                         } else
3468                                 printalias(ap);
3469                 } else {
3470                         *v++ = '\0';
3471                         setalias(n, v);
3472                 }
3473         }
3474
3475         return ret;
3476 }
3477
3478 static int FAST_FUNC
3479 unaliascmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
3480 {
3481         int i;
3482
3483         while (nextopt("a") != '\0') {
3484                 rmaliases();
3485                 return 0;
3486         }
3487         for (i = 0; *argptr; argptr++) {
3488                 if (unalias(*argptr)) {
3489                         fprintf(stderr, "%s: %s not found\n", "unalias", *argptr);
3490                         i = 1;
3491                 }
3492         }
3493
3494         return i;
3495 }
3496
3497 #endif /* ASH_ALIAS */
3498
3499
3500 /* Mode argument to forkshell.  Don't change FORK_FG or FORK_BG. */
3501 #define FORK_FG    0
3502 #define FORK_BG    1
3503 #define FORK_NOJOB 2
3504
3505 /* mode flags for showjob(s) */
3506 #define SHOW_ONLY_PGID  0x01    /* show only pgid (jobs -p) */
3507 #define SHOW_PIDS       0x02    /* show individual pids, not just one line per job */
3508 #define SHOW_CHANGED    0x04    /* only jobs whose state has changed */
3509 #define SHOW_STDERR     0x08    /* print to stderr (else stdout) */
3510
3511 /*
3512  * A job structure contains information about a job.  A job is either a
3513  * single process or a set of processes contained in a pipeline.  In the
3514  * latter case, pidlist will be non-NULL, and will point to a -1 terminated
3515  * array of pids.
3516  */
3517 struct procstat {
3518         pid_t   ps_pid;         /* process id */
3519         int     ps_status;      /* last process status from wait() */
3520         char    *ps_cmd;        /* text of command being run */
3521 };
3522
3523 struct job {
3524         struct procstat ps0;    /* status of process */
3525         struct procstat *ps;    /* status or processes when more than one */
3526 #if JOBS
3527         int stopstatus;         /* status of a stopped job */
3528 #endif
3529         unsigned nprocs;        /* number of processes */
3530
3531 #define JOBRUNNING      0       /* at least one proc running */
3532 #define JOBSTOPPED      1       /* all procs are stopped */
3533 #define JOBDONE         2       /* all procs are completed */
3534         unsigned
3535                 state: 8,
3536 #if JOBS
3537                 sigint: 1,      /* job was killed by SIGINT */
3538                 jobctl: 1,      /* job running under job control */
3539 #endif
3540                 waited: 1,      /* true if this entry has been waited for */
3541                 used: 1,        /* true if this entry is in used */
3542                 changed: 1;     /* true if status has changed */
3543         struct job *prev_job;   /* previous job */
3544 };
3545
3546 static struct job *makejob(/*union node *,*/ int);
3547 static int forkshell(struct job *, union node *, int);
3548 static int waitforjob(struct job *);
3549
3550 #if !JOBS
3551 enum { doing_jobctl = 0 };
3552 #define setjobctl(on) do {} while (0)
3553 #else
3554 static smallint doing_jobctl; //references:8
3555 static void setjobctl(int);
3556 #endif
3557
3558 /*
3559  * Ignore a signal.
3560  */
3561 static void
3562 ignoresig(int signo)
3563 {
3564         /* Avoid unnecessary system calls. Is it already SIG_IGNed? */
3565         if (sigmode[signo - 1] != S_IGN && sigmode[signo - 1] != S_HARD_IGN) {
3566                 /* No, need to do it */
3567                 signal(signo, SIG_IGN);
3568         }
3569         sigmode[signo - 1] = S_HARD_IGN;
3570 }
3571
3572 /*
3573  * Only one usage site - in setsignal()
3574  */
3575 static void
3576 signal_handler(int signo)
3577 {
3578         if (signo == SIGCHLD) {
3579                 got_sigchld = 1;
3580                 if (!trap[SIGCHLD])
3581                         return;
3582         }
3583
3584         gotsig[signo - 1] = 1;
3585         pending_sig = signo;
3586
3587         if (signo == SIGINT && !trap[SIGINT]) {
3588                 if (!suppress_int) {
3589                         pending_sig = 0;
3590                         raise_interrupt(); /* does not return */
3591                 }
3592                 pending_int = 1;
3593         }
3594 }
3595
3596 /*
3597  * Set the signal handler for the specified signal.  The routine figures
3598  * out what it should be set to.
3599  */
3600 static void
3601 setsignal(int signo)
3602 {
3603         char *t;
3604         char cur_act, new_act;
3605         struct sigaction act;
3606
3607         t = trap[signo];
3608         new_act = S_DFL;
3609         if (t != NULL) { /* trap for this sig is set */
3610                 new_act = S_CATCH;
3611                 if (t[0] == '\0') /* trap is "": ignore this sig */
3612                         new_act = S_IGN;
3613         }
3614
3615         if (rootshell && new_act == S_DFL) {
3616                 switch (signo) {
3617                 case SIGINT:
3618                         if (iflag || minusc || sflag == 0)
3619                                 new_act = S_CATCH;
3620                         break;
3621                 case SIGQUIT:
3622 #if DEBUG
3623                         if (debug)
3624                                 break;
3625 #endif
3626                         /* man bash:
3627                          * "In all cases, bash ignores SIGQUIT. Non-builtin
3628                          * commands run by bash have signal handlers
3629                          * set to the values inherited by the shell
3630                          * from its parent". */
3631                         new_act = S_IGN;
3632                         break;
3633                 case SIGTERM:
3634                         if (iflag)
3635                                 new_act = S_IGN;
3636                         break;
3637 #if JOBS
3638                 case SIGTSTP:
3639                 case SIGTTOU:
3640                         if (mflag)
3641                                 new_act = S_IGN;
3642                         break;
3643 #endif
3644                 }
3645         }
3646         /* if !rootshell, we reset SIGQUIT to DFL,
3647          * whereas we have to restore it to what shell got on entry.
3648          * This is handled by the fact that if signal was IGNored on entry,
3649          * then cur_act is S_HARD_IGN and we never change its sigaction
3650          * (see code below).
3651          */
3652
3653         if (signo == SIGCHLD)
3654                 new_act = S_CATCH;
3655
3656         t = &sigmode[signo - 1];
3657         cur_act = *t;
3658         if (cur_act == 0) {
3659                 /* current setting is not yet known */
3660                 if (sigaction(signo, NULL, &act)) {
3661                         /* pretend it worked; maybe we should give a warning,
3662                          * but other shells don't. We don't alter sigmode,
3663                          * so we retry every time.
3664                          * btw, in Linux it never fails. --vda */
3665                         return;
3666                 }
3667                 if (act.sa_handler == SIG_IGN) {
3668                         cur_act = S_HARD_IGN;
3669                         if (mflag
3670                          && (signo == SIGTSTP || signo == SIGTTIN || signo == SIGTTOU)
3671                         ) {
3672                                 cur_act = S_IGN;   /* don't hard ignore these */
3673                         }
3674                 }
3675                 if (act.sa_handler == SIG_DFL && new_act == S_DFL) {
3676                         /* installing SIG_DFL over SIG_DFL is a no-op */
3677                         /* saves one sigaction call in each "sh -c SCRIPT" invocation */
3678                         *t = S_DFL;
3679                         return;
3680                 }
3681         }
3682         if (cur_act == S_HARD_IGN || cur_act == new_act)
3683                 return;
3684
3685         *t = new_act;
3686
3687         act.sa_handler = SIG_DFL;
3688         switch (new_act) {
3689         case S_CATCH:
3690                 act.sa_handler = signal_handler;
3691                 break;
3692         case S_IGN:
3693                 act.sa_handler = SIG_IGN;
3694                 break;
3695         }
3696         /* flags and mask matter only if !DFL and !IGN, but we do it
3697          * for all cases for more deterministic behavior:
3698          */
3699         act.sa_flags = 0; //TODO: why not SA_RESTART?
3700         sigfillset(&act.sa_mask);
3701
3702         sigaction_set(signo, &act);
3703 }
3704
3705 /* mode flags for set_curjob */
3706 #define CUR_DELETE 2
3707 #define CUR_RUNNING 1
3708 #define CUR_STOPPED 0
3709
3710 #if JOBS
3711 /* pgrp of shell on invocation */
3712 static int initialpgrp; //references:2
3713 static int ttyfd = -1; //5
3714 #endif
3715 /* array of jobs */
3716 static struct job *jobtab; //5
3717 /* size of array */
3718 static unsigned njobs; //4
3719 /* current job */
3720 static struct job *curjob; //lots
3721 /* number of presumed living untracked jobs */
3722 static int jobless; //4
3723
3724 #if 0
3725 /* Bash has a feature: it restores termios after a successful wait for
3726  * a foreground job which had at least one stopped or sigkilled member.
3727  * The probable rationale is that SIGSTOP and SIGKILL can preclude task from
3728  * properly restoring tty state. Should we do this too?
3729  * A reproducer: ^Z an interactive python:
3730  *
3731  * # python
3732  * Python 2.7.12 (...)
3733  * >>> ^Z
3734  *      { python leaves tty in -icanon -echo state. We do survive that... }
3735  *  [1]+  Stopped                    python
3736  *      { ...however, next program (python #2) does not survive it well: }
3737  * # python
3738  * Python 2.7.12 (...)
3739  * >>> Traceback (most recent call last):
3740  *      { above, I typed "qwerty<CR>", but -echo state is still in effect }
3741  *   File "<stdin>", line 1, in <module>
3742  * NameError: name 'qwerty' is not defined
3743  *
3744  * The implementation below is modeled on bash code and seems to work.
3745  * However, I'm not sure we should do this. For one: what if I'd fg
3746  * the stopped python instead? It'll be confused by "restored" tty state.
3747  */
3748 static struct termios shell_tty_info;
3749 static void
3750 get_tty_state(void)
3751 {
3752         if (rootshell && ttyfd >= 0)
3753                 tcgetattr(ttyfd, &shell_tty_info);
3754 }
3755 static void
3756 set_tty_state(void)
3757 {
3758         /* if (rootshell) - caller ensures this */
3759         if (ttyfd >= 0)
3760                 tcsetattr(ttyfd, TCSADRAIN, &shell_tty_info);
3761 }
3762 static int
3763 job_signal_status(struct job *jp)
3764 {
3765         int status;
3766         unsigned i;
3767         struct procstat *ps = jp->ps;
3768         for (i = 0; i < jp->nprocs; i++) {
3769                 status = ps[i].ps_status;
3770                 if (WIFSIGNALED(status) || WIFSTOPPED(status))
3771                         return status;
3772         }
3773         return 0;
3774 }
3775 static void
3776 restore_tty_if_stopped_or_signaled(struct job *jp)
3777 {
3778 //TODO: check what happens if we come from waitforjob() in expbackq()
3779         if (rootshell) {
3780                 int s = job_signal_status(jp);
3781                 if (s) /* WIFSIGNALED(s) || WIFSTOPPED(s) */
3782                         set_tty_state();
3783         }
3784 }
3785 #else
3786 # define get_tty_state() ((void)0)
3787 # define restore_tty_if_stopped_or_signaled(jp) ((void)0)
3788 #endif
3789
3790 static void
3791 set_curjob(struct job *jp, unsigned mode)
3792 {
3793         struct job *jp1;
3794         struct job **jpp, **curp;
3795
3796         /* first remove from list */
3797         jpp = curp = &curjob;
3798         while (1) {
3799                 jp1 = *jpp;
3800                 if (jp1 == jp)
3801                         break;
3802                 jpp = &jp1->prev_job;
3803         }
3804         *jpp = jp1->prev_job;
3805
3806         /* Then re-insert in correct position */
3807         jpp = curp;
3808         switch (mode) {
3809         default:
3810 #if DEBUG
3811                 abort();
3812 #endif
3813         case CUR_DELETE:
3814                 /* job being deleted */
3815                 break;
3816         case CUR_RUNNING:
3817                 /* newly created job or backgrounded job,
3818                  * put after all stopped jobs.
3819                  */
3820                 while (1) {
3821                         jp1 = *jpp;
3822 #if JOBS
3823                         if (!jp1 || jp1->state != JOBSTOPPED)
3824 #endif
3825                                 break;
3826                         jpp = &jp1->prev_job;
3827                 }
3828                 /* FALLTHROUGH */
3829 #if JOBS
3830         case CUR_STOPPED:
3831 #endif
3832                 /* newly stopped job - becomes curjob */
3833                 jp->prev_job = *jpp;
3834                 *jpp = jp;
3835                 break;
3836         }
3837 }
3838
3839 #if JOBS || DEBUG
3840 static int
3841 jobno(const struct job *jp)
3842 {
3843         return jp - jobtab + 1;
3844 }
3845 #endif
3846
3847 /*
3848  * Convert a job name to a job structure.
3849  */
3850 #if !JOBS
3851 #define getjob(name, getctl) getjob(name)
3852 #endif
3853 static struct job *
3854 getjob(const char *name, int getctl)
3855 {
3856         struct job *jp;
3857         struct job *found;
3858         const char *err_msg = "%s: no such job";
3859         unsigned num;
3860         int c;
3861         const char *p;
3862         char *(*match)(const char *, const char *);
3863
3864         jp = curjob;
3865         p = name;
3866         if (!p)
3867                 goto currentjob;
3868
3869         if (*p != '%')
3870                 goto err;
3871
3872         c = *++p;
3873         if (!c)
3874                 goto currentjob;
3875
3876         if (!p[1]) {
3877                 if (c == '+' || c == '%') {
3878  currentjob:
3879                         err_msg = "No current job";
3880                         goto check;
3881                 }
3882                 if (c == '-') {
3883                         if (jp)
3884                                 jp = jp->prev_job;
3885                         err_msg = "No previous job";
3886  check:
3887                         if (!jp)
3888                                 goto err;
3889                         goto gotit;
3890                 }
3891         }
3892
3893         if (is_number(p)) {
3894                 num = atoi(p);
3895                 if (num > 0 && num <= njobs) {
3896                         jp = jobtab + num - 1;
3897                         if (jp->used)
3898                                 goto gotit;
3899                         goto err;
3900                 }
3901         }
3902
3903         match = prefix;
3904         if (*p == '?') {
3905                 match = strstr;
3906                 p++;
3907         }
3908
3909         found = NULL;
3910         while (jp) {
3911                 if (match(jp->ps[0].ps_cmd, p)) {
3912                         if (found)
3913                                 goto err;
3914                         found = jp;
3915                         err_msg = "%s: ambiguous";
3916                 }
3917                 jp = jp->prev_job;
3918         }
3919         if (!found)
3920                 goto err;
3921         jp = found;
3922
3923  gotit:
3924 #if JOBS
3925         err_msg = "job %s not created under job control";
3926         if (getctl && jp->jobctl == 0)
3927                 goto err;
3928 #endif
3929         return jp;
3930  err:
3931         ash_msg_and_raise_error(err_msg, name);
3932 }
3933
3934 /*
3935  * Mark a job structure as unused.
3936  */
3937 static void
3938 freejob(struct job *jp)
3939 {
3940         struct procstat *ps;
3941         int i;
3942
3943         INT_OFF;
3944         for (i = jp->nprocs, ps = jp->ps; --i >= 0; ps++) {
3945                 if (ps->ps_cmd != nullstr)
3946                         free(ps->ps_cmd);
3947         }
3948         if (jp->ps != &jp->ps0)
3949                 free(jp->ps);
3950         jp->used = 0;
3951         set_curjob(jp, CUR_DELETE);
3952         INT_ON;
3953 }
3954
3955 #if JOBS
3956 static void
3957 xtcsetpgrp(int fd, pid_t pgrp)
3958 {
3959         if (tcsetpgrp(fd, pgrp))
3960                 ash_msg_and_raise_perror("can't set tty process group");
3961 }
3962
3963 /*
3964  * Turn job control on and off.
3965  *
3966  * Note:  This code assumes that the third arg to ioctl is a character
3967  * pointer, which is true on Berkeley systems but not System V.  Since
3968  * System V doesn't have job control yet, this isn't a problem now.
3969  *
3970  * Called with interrupts off.
3971  */
3972 static void
3973 setjobctl(int on)
3974 {
3975         int fd;
3976         int pgrp;
3977
3978         if (on == doing_jobctl || rootshell == 0)
3979                 return;
3980         if (on) {
3981                 int ofd;
3982                 ofd = fd = open(_PATH_TTY, O_RDWR);
3983                 if (fd < 0) {
3984         /* BTW, bash will try to open(ttyname(0)) if open("/dev/tty") fails.
3985          * That sometimes helps to acquire controlling tty.
3986          * Obviously, a workaround for bugs when someone
3987          * failed to provide a controlling tty to bash! :) */
3988                         fd = 2;
3989                         while (!isatty(fd))
3990                                 if (--fd < 0)
3991                                         goto out;
3992                 }
3993                 /* fd is a tty at this point */
3994                 fd = fcntl(fd, F_DUPFD_CLOEXEC, 10);
3995                 if (ofd >= 0) /* if it is "/dev/tty", close. If 0/1/2, don't */
3996                         close(ofd);
3997                 if (fd < 0)
3998                         goto out; /* F_DUPFD failed */
3999                 if (F_DUPFD_CLOEXEC == F_DUPFD) /* if old libc (w/o F_DUPFD_CLOEXEC) */
4000                         close_on_exec_on(fd);
4001                 while (1) { /* while we are in the background */
4002                         pgrp = tcgetpgrp(fd);
4003                         if (pgrp < 0) {
4004  out:
4005                                 ash_msg("can't access tty; job control turned off");
4006                                 mflag = on = 0;
4007                                 goto close;
4008                         }
4009                         if (pgrp == getpgrp())
4010                                 break;
4011                         killpg(0, SIGTTIN);
4012                 }
4013                 initialpgrp = pgrp;
4014
4015                 setsignal(SIGTSTP);
4016                 setsignal(SIGTTOU);
4017                 setsignal(SIGTTIN);
4018                 pgrp = rootpid;
4019                 setpgid(0, pgrp);
4020                 xtcsetpgrp(fd, pgrp);
4021         } else {
4022                 /* turning job control off */
4023                 fd = ttyfd;
4024                 pgrp = initialpgrp;
4025                 /* was xtcsetpgrp, but this can make exiting ash
4026                  * loop forever if pty is already deleted */
4027                 tcsetpgrp(fd, pgrp);
4028                 setpgid(0, pgrp);
4029                 setsignal(SIGTSTP);
4030                 setsignal(SIGTTOU);
4031                 setsignal(SIGTTIN);
4032  close:
4033                 if (fd >= 0)
4034                         close(fd);
4035                 fd = -1;
4036         }
4037         ttyfd = fd;
4038         doing_jobctl = on;
4039 }
4040
4041 static int FAST_FUNC
4042 killcmd(int argc, char **argv)
4043 {
4044         if (argv[1] && strcmp(argv[1], "-l") != 0) {
4045                 int i = 1;
4046                 do {
4047                         if (argv[i][0] == '%') {
4048                                 /*
4049                                  * "kill %N" - job kill
4050                                  * Converting to pgrp / pid kill
4051                                  */
4052                                 struct job *jp;
4053                                 char *dst;
4054                                 int j, n;
4055
4056                                 jp = getjob(argv[i], 0);
4057                                 /*
4058                                  * In jobs started under job control, we signal
4059                                  * entire process group by kill -PGRP_ID.
4060                                  * This happens, f.e., in interactive shell.
4061                                  *
4062                                  * Otherwise, we signal each child via
4063                                  * kill PID1 PID2 PID3.
4064                                  * Testcases:
4065                                  * sh -c 'sleep 1|sleep 1 & kill %1'
4066                                  * sh -c 'true|sleep 2 & sleep 1; kill %1'
4067                                  * sh -c 'true|sleep 1 & sleep 2; kill %1'
4068                                  */
4069                                 n = jp->nprocs; /* can't be 0 (I hope) */
4070                                 if (jp->jobctl)
4071                                         n = 1;
4072                                 dst = alloca(n * sizeof(int)*4);
4073                                 argv[i] = dst;
4074                                 for (j = 0; j < n; j++) {
4075                                         struct procstat *ps = &jp->ps[j];
4076                                         /* Skip non-running and not-stopped members
4077                                          * (i.e. dead members) of the job
4078                                          */
4079                                         if (ps->ps_status != -1 && !WIFSTOPPED(ps->ps_status))
4080                                                 continue;
4081                                         /*
4082                                          * kill_main has matching code to expect
4083                                          * leading space. Needed to not confuse
4084                                          * negative pids with "kill -SIGNAL_NO" syntax
4085                                          */
4086                                         dst += sprintf(dst, jp->jobctl ? " -%u" : " %u", (int)ps->ps_pid);
4087                                 }
4088                                 *dst = '\0';
4089                         }
4090                 } while (argv[++i]);
4091         }
4092         return kill_main(argc, argv);
4093 }
4094
4095 static void
4096 showpipe(struct job *jp /*, FILE *out*/)
4097 {
4098         struct procstat *ps;
4099         struct procstat *psend;
4100
4101         psend = jp->ps + jp->nprocs;
4102         for (ps = jp->ps + 1; ps < psend; ps++)
4103                 printf(" | %s", ps->ps_cmd);
4104         newline_and_flush(stdout);
4105         flush_stdout_stderr();
4106 }
4107
4108
4109 static int
4110 restartjob(struct job *jp, int mode)
4111 {
4112         struct procstat *ps;
4113         int i;
4114         int status;
4115         pid_t pgid;
4116
4117         INT_OFF;
4118         if (jp->state == JOBDONE)
4119                 goto out;
4120         jp->state = JOBRUNNING;
4121         pgid = jp->ps[0].ps_pid;
4122         if (mode == FORK_FG) {
4123                 get_tty_state();
4124                 xtcsetpgrp(ttyfd, pgid);
4125         }
4126         killpg(pgid, SIGCONT);
4127         ps = jp->ps;
4128         i = jp->nprocs;
4129         do {
4130                 if (WIFSTOPPED(ps->ps_status)) {
4131                         ps->ps_status = -1;
4132                 }
4133                 ps++;
4134         } while (--i);
4135  out:
4136         status = (mode == FORK_FG) ? waitforjob(jp) : 0;
4137         INT_ON;
4138         return status;
4139 }
4140
4141 static int FAST_FUNC
4142 fg_bgcmd(int argc UNUSED_PARAM, char **argv)
4143 {
4144         struct job *jp;
4145         int mode;
4146         int retval;
4147
4148         mode = (**argv == 'f') ? FORK_FG : FORK_BG;
4149         nextopt(nullstr);
4150         argv = argptr;
4151         do {
4152                 jp = getjob(*argv, 1);
4153                 if (mode == FORK_BG) {
4154                         set_curjob(jp, CUR_RUNNING);
4155                         printf("[%d] ", jobno(jp));
4156                 }
4157                 out1str(jp->ps[0].ps_cmd);
4158                 showpipe(jp /*, stdout*/);
4159                 retval = restartjob(jp, mode);
4160         } while (*argv && *++argv);
4161         return retval;
4162 }
4163 #endif
4164
4165 static int
4166 sprint_status48(char *s, int status, int sigonly)
4167 {
4168         int col;
4169         int st;
4170
4171         col = 0;
4172         if (!WIFEXITED(status)) {
4173 #if JOBS
4174                 if (WIFSTOPPED(status))
4175                         st = WSTOPSIG(status);
4176                 else
4177 #endif
4178                         st = WTERMSIG(status);
4179                 if (sigonly) {
4180                         if (st == SIGINT || st == SIGPIPE)
4181                                 goto out;
4182 #if JOBS
4183                         if (WIFSTOPPED(status))
4184                                 goto out;
4185 #endif
4186                 }
4187                 st &= 0x7f;
4188 //TODO: use bbox's get_signame? strsignal adds ~600 bytes to text+rodata
4189                 col = fmtstr(s, 32, strsignal(st));
4190                 if (WCOREDUMP(status)) {
4191                         strcpy(s + col, " (core dumped)");
4192                         col += sizeof(" (core dumped)")-1;
4193                 }
4194         } else if (!sigonly) {
4195                 st = WEXITSTATUS(status);
4196                 col = fmtstr(s, 16, (st ? "Done(%d)" : "Done"), st);
4197         }
4198  out:
4199         return col;
4200 }
4201
4202 static int
4203 wait_block_or_sig(int *status)
4204 {
4205         int pid;
4206
4207         do {
4208                 sigset_t mask;
4209
4210                 /* Poll all children for changes in their state */
4211                 got_sigchld = 0;
4212                 /* if job control is active, accept stopped processes too */
4213                 pid = waitpid(-1, status, doing_jobctl ? (WNOHANG|WUNTRACED) : WNOHANG);
4214                 if (pid != 0)
4215                         break; /* Error (e.g. EINTR, ECHILD) or pid */
4216
4217                 /* Children exist, but none are ready. Sleep until interesting signal */
4218 #if 1
4219                 sigfillset(&mask);
4220                 sigprocmask2(SIG_SETMASK, &mask); /* mask is updated */
4221                 while (!got_sigchld && !pending_sig)
4222                         sigsuspend(&mask);
4223                 sigprocmask(SIG_SETMASK, &mask, NULL);
4224 #else /* unsafe: a signal can set pending_sig after check, but before pause() */
4225                 while (!got_sigchld && !pending_sig)
4226                         pause();
4227 #endif
4228
4229                 /* If it was SIGCHLD, poll children again */
4230         } while (got_sigchld);
4231
4232         return pid;
4233 }
4234
4235 #define DOWAIT_NONBLOCK 0
4236 #define DOWAIT_BLOCK    1
4237 #define DOWAIT_BLOCK_OR_SIG 2
4238
4239 static int
4240 dowait(int block, struct job *job)
4241 {
4242         int pid;
4243         int status;
4244         struct job *jp;
4245         struct job *thisjob = NULL;
4246
4247         TRACE(("dowait(0x%x) called\n", block));
4248
4249         /* It's wrong to call waitpid() outside of INT_OFF region:
4250          * signal can arrive just after syscall return and handler can
4251          * longjmp away, losing stop/exit notification processing.
4252          * Thus, for "jobs" builtin, and for waiting for a fg job,
4253          * we call waitpid() (blocking or non-blocking) inside INT_OFF.
4254          *
4255          * However, for "wait" builtin it is wrong to simply call waitpid()
4256          * in INT_OFF region: "wait" needs to wait for any running job
4257          * to change state, but should exit on any trap too.
4258          * In INT_OFF region, a signal just before syscall entry can set
4259          * pending_sig variables, but we can't check them, and we would
4260          * either enter a sleeping waitpid() (BUG), or need to busy-loop.
4261          *
4262          * Because of this, we run inside INT_OFF, but use a special routine
4263          * which combines waitpid() and sigsuspend().
4264          * This is the reason why we need to have a handler for SIGCHLD:
4265          * SIG_DFL handler does not wake sigsuspend().
4266          */
4267         INT_OFF;
4268         if (block == DOWAIT_BLOCK_OR_SIG) {
4269                 pid = wait_block_or_sig(&status);
4270         } else {
4271                 int wait_flags = 0;
4272                 if (block == DOWAIT_NONBLOCK)
4273                         wait_flags = WNOHANG;
4274                 /* if job control is active, accept stopped processes too */
4275                 if (doing_jobctl)
4276                         wait_flags |= WUNTRACED;
4277                 /* NB: _not_ safe_waitpid, we need to detect EINTR */
4278                 pid = waitpid(-1, &status, wait_flags);
4279         }
4280         TRACE(("wait returns pid=%d, status=0x%x, errno=%d(%s)\n",
4281                                 pid, status, errno, strerror(errno)));
4282         if (pid <= 0)
4283                 goto out;
4284
4285         thisjob = NULL;
4286         for (jp = curjob; jp; jp = jp->prev_job) {
4287                 int jobstate;
4288                 struct procstat *ps;
4289                 struct procstat *psend;
4290                 if (jp->state == JOBDONE)
4291                         continue;
4292                 jobstate = JOBDONE;
4293                 ps = jp->ps;
4294                 psend = ps + jp->nprocs;
4295                 do {
4296                         if (ps->ps_pid == pid) {
4297                                 TRACE(("Job %d: changing status of proc %d "
4298                                         "from 0x%x to 0x%x\n",
4299                                         jobno(jp), pid, ps->ps_status, status));
4300                                 ps->ps_status = status;
4301                                 thisjob = jp;
4302                         }
4303                         if (ps->ps_status == -1)
4304                                 jobstate = JOBRUNNING;
4305 #if JOBS
4306                         if (jobstate == JOBRUNNING)
4307                                 continue;
4308                         if (WIFSTOPPED(ps->ps_status)) {
4309                                 jp->stopstatus = ps->ps_status;
4310                                 jobstate = JOBSTOPPED;
4311                         }
4312 #endif
4313                 } while (++ps < psend);
4314                 if (!thisjob)
4315                         continue;
4316
4317                 /* Found the job where one of its processes changed its state.
4318                  * Is there at least one live and running process in this job? */
4319                 if (jobstate != JOBRUNNING) {
4320                         /* No. All live processes in the job are stopped
4321                          * (JOBSTOPPED) or there are no live processes (JOBDONE)
4322                          */
4323                         thisjob->changed = 1;
4324                         if (thisjob->state != jobstate) {
4325                                 TRACE(("Job %d: changing state from %d to %d\n",
4326                                         jobno(thisjob), thisjob->state, jobstate));
4327                                 thisjob->state = jobstate;
4328 #if JOBS
4329                                 if (jobstate == JOBSTOPPED)
4330                                         set_curjob(thisjob, CUR_STOPPED);
4331 #endif
4332                         }
4333                 }
4334                 goto out;
4335         }
4336         /* The process wasn't found in job list */
4337 #if JOBS
4338         if (!WIFSTOPPED(status))
4339                 jobless--;
4340 #endif
4341  out:
4342         INT_ON;
4343
4344         if (thisjob && thisjob == job) {
4345                 char s[48 + 1];
4346                 int len;
4347
4348                 len = sprint_status48(s, status, 1);
4349                 if (len) {
4350                         s[len] = '\n';
4351                         s[len + 1] = '\0';
4352                         out2str(s);
4353                 }
4354         }
4355         return pid;
4356 }
4357
4358 #if JOBS
4359 static void
4360 showjob(struct job *jp, int mode)
4361 {
4362         struct procstat *ps;
4363         struct procstat *psend;
4364         int col;
4365         int indent_col;
4366         char s[16 + 16 + 48];
4367         FILE *out = (mode & SHOW_STDERR ? stderr : stdout);
4368
4369         ps = jp->ps;
4370
4371         if (mode & SHOW_ONLY_PGID) { /* jobs -p */
4372                 /* just output process (group) id of pipeline */
4373                 fprintf(out, "%d\n", ps->ps_pid);
4374                 return;
4375         }
4376
4377         col = fmtstr(s, 16, "[%d]   ", jobno(jp));
4378         indent_col = col;
4379
4380         if (jp == curjob)
4381                 s[col - 3] = '+';
4382         else if (curjob && jp == curjob->prev_job)
4383                 s[col - 3] = '-';
4384
4385         if (mode & SHOW_PIDS)
4386                 col += fmtstr(s + col, 16, "%d ", ps->ps_pid);
4387
4388         psend = ps + jp->nprocs;
4389
4390         if (jp->state == JOBRUNNING) {
4391                 strcpy(s + col, "Running");
4392                 col += sizeof("Running") - 1;
4393         } else {
4394                 int status = psend[-1].ps_status;
4395                 if (jp->state == JOBSTOPPED)
4396                         status = jp->stopstatus;
4397                 col += sprint_status48(s + col, status, 0);
4398         }
4399         /* By now, "[JOBID]*  [maybe PID] STATUS" is printed */
4400
4401         /* This loop either prints "<cmd1> | <cmd2> | <cmd3>" line
4402          * or prints several "PID             | <cmdN>" lines,
4403          * depending on SHOW_PIDS bit.
4404          * We do not print status of individual processes
4405          * between PID and <cmdN>. bash does it, but not very well:
4406          * first line shows overall job status, not process status,
4407          * making it impossible to know 1st process status.
4408          */
4409         goto start;
4410         do {
4411                 /* for each process */
4412                 s[0] = '\0';
4413                 col = 33;
4414                 if (mode & SHOW_PIDS)
4415                         col = fmtstr(s, 48, "\n%*c%d ", indent_col, ' ', ps->ps_pid) - 1;
4416  start:
4417                 fprintf(out, "%s%*c%s%s",
4418                                 s,
4419                                 33 - col >= 0 ? 33 - col : 0, ' ',
4420                                 ps == jp->ps ? "" : "| ",
4421                                 ps->ps_cmd
4422                 );
4423         } while (++ps != psend);
4424         newline_and_flush(out);
4425
4426         jp->changed = 0;
4427
4428         if (jp->state == JOBDONE) {
4429                 TRACE(("showjob: freeing job %d\n", jobno(jp)));
4430                 freejob(jp);
4431         }
4432 }
4433
4434 /*
4435  * Print a list of jobs.  If "change" is nonzero, only print jobs whose
4436  * statuses have changed since the last call to showjobs.
4437  */
4438 static void
4439 showjobs(int mode)
4440 {
4441         struct job *jp;
4442
4443         TRACE(("showjobs(0x%x) called\n", mode));
4444
4445         /* Handle all finished jobs */
4446         while (dowait(DOWAIT_NONBLOCK, NULL) > 0)
4447                 continue;
4448
4449         for (jp = curjob; jp; jp = jp->prev_job) {
4450                 if (!(mode & SHOW_CHANGED) || jp->changed) {
4451                         showjob(jp, mode);
4452                 }
4453         }
4454 }
4455
4456 static int FAST_FUNC
4457 jobscmd(int argc UNUSED_PARAM, char **argv)
4458 {
4459         int mode, m;
4460
4461         mode = 0;
4462         while ((m = nextopt("lp")) != '\0') {
4463                 if (m == 'l')
4464                         mode |= SHOW_PIDS;
4465                 else
4466                         mode |= SHOW_ONLY_PGID;
4467         }
4468
4469         argv = argptr;
4470         if (*argv) {
4471                 do
4472                         showjob(getjob(*argv, 0), mode);
4473                 while (*++argv);
4474         } else {
4475                 showjobs(mode);
4476         }
4477
4478         return 0;
4479 }
4480 #endif /* JOBS */
4481
4482 /* Called only on finished or stopped jobs (no members are running) */
4483 static int
4484 getstatus(struct job *job)
4485 {
4486         int status;
4487         int retval;
4488         struct procstat *ps;
4489
4490         /* Fetch last member's status */
4491         ps = job->ps + job->nprocs - 1;
4492         status = ps->ps_status;
4493         if (pipefail) {
4494                 /* "set -o pipefail" mode: use last _nonzero_ status */
4495                 while (status == 0 && --ps >= job->ps)
4496                         status = ps->ps_status;
4497         }
4498
4499         retval = WEXITSTATUS(status);
4500         if (!WIFEXITED(status)) {
4501 #if JOBS
4502                 retval = WSTOPSIG(status);
4503                 if (!WIFSTOPPED(status))
4504 #endif
4505                 {
4506                         /* XXX: limits number of signals */
4507                         retval = WTERMSIG(status);
4508 #if JOBS
4509                         if (retval == SIGINT)
4510                                 job->sigint = 1;
4511 #endif
4512                 }
4513                 retval += 128;
4514         }
4515         TRACE(("getstatus: job %d, nproc %d, status 0x%x, retval 0x%x\n",
4516                 jobno(job), job->nprocs, status, retval));
4517         return retval;
4518 }
4519
4520 static int FAST_FUNC
4521 waitcmd(int argc UNUSED_PARAM, char **argv)
4522 {
4523         struct job *job;
4524         int retval;
4525         struct job *jp;
4526
4527         nextopt(nullstr);
4528         retval = 0;
4529
4530         argv = argptr;
4531         if (!*argv) {
4532                 /* wait for all jobs */
4533                 for (;;) {
4534                         jp = curjob;
4535                         while (1) {
4536                                 if (!jp) /* no running procs */
4537                                         goto ret;
4538                                 if (jp->state == JOBRUNNING)
4539                                         break;
4540                                 jp->waited = 1;
4541                                 jp = jp->prev_job;
4542                         }
4543         /* man bash:
4544          * "When bash is waiting for an asynchronous command via
4545          * the wait builtin, the reception of a signal for which a trap
4546          * has been set will cause the wait builtin to return immediately
4547          * with an exit status greater than 128, immediately after which
4548          * the trap is executed."
4549          */
4550                         dowait(DOWAIT_BLOCK_OR_SIG, NULL);
4551         /* if child sends us a signal *and immediately exits*,
4552          * dowait() returns pid > 0. Check this case,
4553          * not "if (dowait() < 0)"!
4554          */
4555                         if (pending_sig)
4556                                 goto sigout;
4557                 }
4558         }
4559
4560         retval = 127;
4561         do {
4562                 if (**argv != '%') {
4563                         pid_t pid = number(*argv);
4564                         job = curjob;
4565                         while (1) {
4566                                 if (!job)
4567                                         goto repeat;
4568                                 if (job->ps[job->nprocs - 1].ps_pid == pid)
4569                                         break;
4570                                 job = job->prev_job;
4571                         }
4572                 } else {
4573                         job = getjob(*argv, 0);
4574                 }
4575                 /* loop until process terminated or stopped */
4576                 while (job->state == JOBRUNNING) {
4577                         dowait(DOWAIT_BLOCK_OR_SIG, NULL);
4578                         if (pending_sig)
4579                                 goto sigout;
4580                 }
4581                 job->waited = 1;
4582                 retval = getstatus(job);
4583  repeat: ;
4584         } while (*++argv);
4585
4586  ret:
4587         return retval;
4588  sigout:
4589         retval = 128 + pending_sig;
4590         return retval;
4591 }
4592
4593 static struct job *
4594 growjobtab(void)
4595 {
4596         size_t len;
4597         ptrdiff_t offset;
4598         struct job *jp, *jq;
4599
4600         len = njobs * sizeof(*jp);
4601         jq = jobtab;
4602         jp = ckrealloc(jq, len + 4 * sizeof(*jp));
4603
4604         offset = (char *)jp - (char *)jq;
4605         if (offset) {
4606                 /* Relocate pointers */
4607                 size_t l = len;
4608
4609                 jq = (struct job *)((char *)jq + l);
4610                 while (l) {
4611                         l -= sizeof(*jp);
4612                         jq--;
4613 #define joff(p) ((struct job *)((char *)(p) + l))
4614 #define jmove(p) (p) = (void *)((char *)(p) + offset)
4615                         if (joff(jp)->ps == &jq->ps0)
4616                                 jmove(joff(jp)->ps);
4617                         if (joff(jp)->prev_job)
4618                                 jmove(joff(jp)->prev_job);
4619                 }
4620                 if (curjob)
4621                         jmove(curjob);
4622 #undef joff
4623 #undef jmove
4624         }
4625
4626         njobs += 4;
4627         jobtab = jp;
4628         jp = (struct job *)((char *)jp + len);
4629         jq = jp + 3;
4630         do {
4631                 jq->used = 0;
4632         } while (--jq >= jp);
4633         return jp;
4634 }
4635
4636 /*
4637  * Return a new job structure.
4638  * Called with interrupts off.
4639  */
4640 static struct job *
4641 makejob(/*union node *node,*/ int nprocs)
4642 {
4643         int i;
4644         struct job *jp;
4645
4646         for (i = njobs, jp = jobtab; ; jp++) {
4647                 if (--i < 0) {
4648                         jp = growjobtab();
4649                         break;
4650                 }
4651                 if (jp->used == 0)
4652                         break;
4653                 if (jp->state != JOBDONE || !jp->waited)
4654                         continue;
4655 #if JOBS
4656                 if (doing_jobctl)
4657                         continue;
4658 #endif
4659                 freejob(jp);
4660                 break;
4661         }
4662         memset(jp, 0, sizeof(*jp));
4663 #if JOBS
4664         /* jp->jobctl is a bitfield.
4665          * "jp->jobctl |= doing_jobctl" likely to give awful code */
4666         if (doing_jobctl)
4667                 jp->jobctl = 1;
4668 #endif
4669         jp->prev_job = curjob;
4670         curjob = jp;
4671         jp->used = 1;
4672         jp->ps = &jp->ps0;
4673         if (nprocs > 1) {
4674                 jp->ps = ckmalloc(nprocs * sizeof(struct procstat));
4675         }
4676         TRACE(("makejob(%d) returns %%%d\n", nprocs,
4677                                 jobno(jp)));
4678         return jp;
4679 }
4680
4681 #if JOBS
4682 /*
4683  * Return a string identifying a command (to be printed by the
4684  * jobs command).
4685  */
4686 static char *cmdnextc;
4687
4688 static void
4689 cmdputs(const char *s)
4690 {
4691         static const char vstype[VSTYPE + 1][3] = {
4692                 "", "}", "-", "+", "?", "=",
4693                 "%", "%%", "#", "##"
4694                 IF_BASH_SUBSTR(, ":")
4695                 IF_BASH_PATTERN_SUBST(, "/", "//")
4696         };
4697
4698         const char *p, *str;
4699         char cc[2];
4700         char *nextc;
4701         unsigned char c;
4702         unsigned char subtype = 0;
4703         int quoted = 0;
4704
4705         cc[1] = '\0';
4706         nextc = makestrspace((strlen(s) + 1) * 8, cmdnextc);
4707         p = s;
4708         while ((c = *p++) != '\0') {
4709                 str = NULL;
4710                 switch (c) {
4711                 case CTLESC:
4712                         c = *p++;
4713                         break;
4714                 case CTLVAR:
4715                         subtype = *p++;
4716                         if ((subtype & VSTYPE) == VSLENGTH)
4717                                 str = "${#";
4718                         else
4719                                 str = "${";
4720                         goto dostr;
4721                 case CTLENDVAR:
4722                         str = "\"}" + !(quoted & 1);
4723                         quoted >>= 1;
4724                         subtype = 0;
4725                         goto dostr;
4726                 case CTLBACKQ:
4727                         str = "$(...)";
4728                         goto dostr;
4729 #if ENABLE_FEATURE_SH_MATH
4730                 case CTLARI:
4731                         str = "$((";
4732                         goto dostr;
4733                 case CTLENDARI:
4734                         str = "))";
4735                         goto dostr;
4736 #endif
4737                 case CTLQUOTEMARK:
4738                         quoted ^= 1;
4739                         c = '"';
4740                         break;
4741                 case '=':
4742                         if (subtype == 0)
4743                                 break;
4744                         if ((subtype & VSTYPE) != VSNORMAL)
4745                                 quoted <<= 1;
4746                         str = vstype[subtype & VSTYPE];
4747                         if (subtype & VSNUL)
4748                                 c = ':';
4749                         else
4750                                 goto checkstr;
4751                         break;
4752                 case '\'':
4753                 case '\\':
4754                 case '"':
4755                 case '$':
4756                         /* These can only happen inside quotes */
4757                         cc[0] = c;
4758                         str = cc;
4759 //FIXME:
4760 // $ true $$ &
4761 // $ <cr>
4762 // [1]+  Done    true ${\$}   <<=== BUG: ${\$} is not a valid way to write $$ (${$} would be ok)
4763                         c = '\\';
4764                         break;
4765                 default:
4766                         break;
4767                 }
4768                 USTPUTC(c, nextc);
4769  checkstr:
4770                 if (!str)
4771                         continue;
4772  dostr:
4773                 while ((c = *str++) != '\0') {
4774                         USTPUTC(c, nextc);
4775                 }
4776         } /* while *p++ not NUL */
4777
4778         if (quoted & 1) {
4779                 USTPUTC('"', nextc);
4780         }
4781         *nextc = 0;
4782         cmdnextc = nextc;
4783 }
4784
4785 /* cmdtxt() and cmdlist() call each other */
4786 static void cmdtxt(union node *n);
4787
4788 static void
4789 cmdlist(union node *np, int sep)
4790 {
4791         for (; np; np = np->narg.next) {
4792                 if (!sep)
4793                         cmdputs(" ");
4794                 cmdtxt(np);
4795                 if (sep && np->narg.next)
4796                         cmdputs(" ");
4797         }
4798 }
4799
4800 static void
4801 cmdtxt(union node *n)
4802 {
4803         union node *np;
4804         struct nodelist *lp;
4805         const char *p;
4806
4807         if (!n)
4808                 return;
4809         switch (n->type) {
4810         default:
4811 #if DEBUG
4812                 abort();
4813 #endif
4814         case NPIPE:
4815                 lp = n->npipe.cmdlist;
4816                 for (;;) {
4817                         cmdtxt(lp->n);
4818                         lp = lp->next;
4819                         if (!lp)
4820                                 break;
4821                         cmdputs(" | ");
4822                 }
4823                 break;
4824         case NSEMI:
4825                 p = "; ";
4826                 goto binop;
4827         case NAND:
4828                 p = " && ";
4829                 goto binop;
4830         case NOR:
4831                 p = " || ";
4832  binop:
4833                 cmdtxt(n->nbinary.ch1);
4834                 cmdputs(p);
4835                 n = n->nbinary.ch2;
4836                 goto donode;
4837         case NREDIR:
4838         case NBACKGND:
4839                 n = n->nredir.n;
4840                 goto donode;
4841         case NNOT:
4842                 cmdputs("!");
4843                 n = n->nnot.com;
4844  donode:
4845                 cmdtxt(n);
4846                 break;
4847         case NIF:
4848                 cmdputs("if ");
4849                 cmdtxt(n->nif.test);
4850                 cmdputs("; then ");
4851                 if (n->nif.elsepart) {
4852                         cmdtxt(n->nif.ifpart);
4853                         cmdputs("; else ");
4854                         n = n->nif.elsepart;
4855                 } else {
4856                         n = n->nif.ifpart;
4857                 }
4858                 p = "; fi";
4859                 goto dotail;
4860         case NSUBSHELL:
4861                 cmdputs("(");
4862                 n = n->nredir.n;
4863                 p = ")";
4864                 goto dotail;
4865         case NWHILE:
4866                 p = "while ";
4867                 goto until;
4868         case NUNTIL:
4869                 p = "until ";
4870  until:
4871                 cmdputs(p);
4872                 cmdtxt(n->nbinary.ch1);
4873                 n = n->nbinary.ch2;
4874                 p = "; done";
4875  dodo:
4876                 cmdputs("; do ");
4877  dotail:
4878                 cmdtxt(n);
4879                 goto dotail2;
4880         case NFOR:
4881                 cmdputs("for ");
4882                 cmdputs(n->nfor.var);
4883                 cmdputs(" in ");
4884                 cmdlist(n->nfor.args, 1);
4885                 n = n->nfor.body;
4886                 p = "; done";
4887                 goto dodo;
4888         case NDEFUN:
4889                 cmdputs(n->ndefun.text);
4890                 p = "() { ... }";
4891                 goto dotail2;
4892         case NCMD:
4893                 cmdlist(n->ncmd.args, 1);
4894                 cmdlist(n->ncmd.redirect, 0);
4895                 break;
4896         case NARG:
4897                 p = n->narg.text;
4898  dotail2:
4899                 cmdputs(p);
4900                 break;
4901         case NHERE:
4902         case NXHERE:
4903                 p = "<<...";
4904                 goto dotail2;
4905         case NCASE:
4906                 cmdputs("case ");
4907                 cmdputs(n->ncase.expr->narg.text);
4908                 cmdputs(" in ");
4909                 for (np = n->ncase.cases; np; np = np->nclist.next) {
4910                         cmdtxt(np->nclist.pattern);
4911                         cmdputs(") ");
4912                         cmdtxt(np->nclist.body);
4913                         cmdputs(";; ");
4914                 }
4915                 p = "esac";
4916                 goto dotail2;
4917         case NTO:
4918                 p = ">";
4919                 goto redir;
4920         case NCLOBBER:
4921                 p = ">|";
4922                 goto redir;
4923         case NAPPEND:
4924                 p = ">>";
4925                 goto redir;
4926 #if BASH_REDIR_OUTPUT
4927         case NTO2:
4928 #endif
4929         case NTOFD:
4930                 p = ">&";
4931                 goto redir;
4932         case NFROM:
4933                 p = "<";
4934                 goto redir;
4935         case NFROMFD:
4936                 p = "<&";
4937                 goto redir;
4938         case NFROMTO:
4939                 p = "<>";
4940  redir:
4941                 cmdputs(utoa(n->nfile.fd));
4942                 cmdputs(p);
4943                 if (n->type == NTOFD || n->type == NFROMFD) {
4944                         if (n->ndup.dupfd >= 0)
4945                                 cmdputs(utoa(n->ndup.dupfd));
4946                         else
4947                                 cmdputs("-");
4948                         break;
4949                 }
4950                 n = n->nfile.fname;
4951                 goto donode;
4952         }
4953 }
4954
4955 static char *
4956 commandtext(union node *n)
4957 {
4958         char *name;
4959
4960         STARTSTACKSTR(cmdnextc);
4961         cmdtxt(n);
4962         name = stackblock();
4963         TRACE(("commandtext: name %p, end %p\n", name, cmdnextc));
4964         return ckstrdup(name);
4965 }
4966 #endif /* JOBS */
4967
4968 /*
4969  * Fork off a subshell.  If we are doing job control, give the subshell its
4970  * own process group.  Jp is a job structure that the job is to be added to.
4971  * N is the command that will be evaluated by the child.  Both jp and n may
4972  * be NULL.  The mode parameter can be one of the following:
4973  *      FORK_FG - Fork off a foreground process.
4974  *      FORK_BG - Fork off a background process.
4975  *      FORK_NOJOB - Like FORK_FG, but don't give the process its own
4976  *                   process group even if job control is on.
4977  *
4978  * When job control is turned off, background processes have their standard
4979  * input redirected to /dev/null (except for the second and later processes
4980  * in a pipeline).
4981  *
4982  * Called with interrupts off.
4983  */
4984 /*
4985  * Clear traps on a fork.
4986  */
4987 static void
4988 clear_traps(void)
4989 {
4990         char **tp;
4991
4992         INT_OFF;
4993         for (tp = trap; tp < &trap[NSIG]; tp++) {
4994                 if (*tp && **tp) {      /* trap not NULL or "" (SIG_IGN) */
4995                         if (trap_ptr == trap)
4996                                 free(*tp);
4997                         /* else: it "belongs" to trap_ptr vector, don't free */
4998                         *tp = NULL;
4999                         if ((tp - trap) != 0)
5000                                 setsignal(tp - trap);
5001                 }
5002         }
5003         may_have_traps = 0;
5004         INT_ON;
5005 }
5006
5007 /* Lives far away from here, needed for forkchild */
5008 static void closescript(void);
5009
5010 /* Called after fork(), in child */
5011 /* jp and n are NULL when called by openhere() for heredoc support */
5012 static NOINLINE void
5013 forkchild(struct job *jp, union node *n, int mode)
5014 {
5015         int oldlvl;
5016
5017         TRACE(("Child shell %d\n", getpid()));
5018         oldlvl = shlvl;
5019         shlvl++;
5020
5021         /* man bash: "Non-builtin commands run by bash have signal handlers
5022          * set to the values inherited by the shell from its parent".
5023          * Do we do it correctly? */
5024
5025         closescript();
5026
5027         if (mode == FORK_NOJOB          /* is it `xxx` ? */
5028          && n && n->type == NCMD        /* is it single cmd? */
5029         /* && n->ncmd.args->type == NARG - always true? */
5030          && n->ncmd.args && strcmp(n->ncmd.args->narg.text, "trap") == 0
5031          && n->ncmd.args->narg.next == NULL /* "trap" with no arguments */
5032         /* && n->ncmd.args->narg.backquote == NULL - do we need to check this? */
5033         ) {
5034                 TRACE(("Trap hack\n"));
5035                 /* Awful hack for `trap` or $(trap).
5036                  *
5037                  * http://www.opengroup.org/onlinepubs/009695399/utilities/trap.html
5038                  * contains an example where "trap" is executed in a subshell:
5039                  *
5040                  * save_traps=$(trap)
5041                  * ...
5042                  * eval "$save_traps"
5043                  *
5044                  * Standard does not say that "trap" in subshell shall print
5045                  * parent shell's traps. It only says that its output
5046                  * must have suitable form, but then, in the above example
5047                  * (which is not supposed to be normative), it implies that.
5048                  *
5049                  * bash (and probably other shell) does implement it
5050                  * (traps are reset to defaults, but "trap" still shows them),
5051                  * but as a result, "trap" logic is hopelessly messed up:
5052                  *
5053                  * # trap
5054                  * trap -- 'echo Ho' SIGWINCH  <--- we have a handler
5055                  * # (trap)        <--- trap is in subshell - no output (correct, traps are reset)
5056                  * # true | trap   <--- trap is in subshell - no output (ditto)
5057                  * # echo `true | trap`    <--- in subshell - output (but traps are reset!)
5058                  * trap -- 'echo Ho' SIGWINCH
5059                  * # echo `(trap)`         <--- in subshell in subshell - output
5060                  * trap -- 'echo Ho' SIGWINCH
5061                  * # echo `true | (trap)`  <--- in subshell in subshell in subshell - output!
5062                  * trap -- 'echo Ho' SIGWINCH
5063                  *
5064                  * The rules when to forget and when to not forget traps
5065                  * get really complex and nonsensical.
5066                  *
5067                  * Our solution: ONLY bare $(trap) or `trap` is special.
5068                  */
5069                 /* Save trap handler strings for trap builtin to print */
5070                 trap_ptr = xmemdup(trap, sizeof(trap));
5071                 /* Fall through into clearing traps */
5072         }
5073         clear_traps();
5074 #if JOBS
5075         /* do job control only in root shell */
5076         doing_jobctl = 0;
5077         if (mode != FORK_NOJOB && jp->jobctl && oldlvl == 0) {
5078                 pid_t pgrp;
5079
5080                 if (jp->nprocs == 0)
5081                         pgrp = getpid();
5082                 else
5083                         pgrp = jp->ps[0].ps_pid;
5084                 /* this can fail because we are doing it in the parent also */
5085                 setpgid(0, pgrp);
5086                 if (mode == FORK_FG)
5087                         xtcsetpgrp(ttyfd, pgrp);
5088                 setsignal(SIGTSTP);
5089                 setsignal(SIGTTOU);
5090         } else
5091 #endif
5092         if (mode == FORK_BG) {
5093                 /* man bash: "When job control is not in effect,
5094                  * asynchronous commands ignore SIGINT and SIGQUIT" */
5095                 ignoresig(SIGINT);
5096                 ignoresig(SIGQUIT);
5097                 if (jp->nprocs == 0) {
5098                         close(0);
5099                         if (open(bb_dev_null, O_RDONLY) != 0)
5100                                 ash_msg_and_raise_perror("can't open '%s'", bb_dev_null);
5101                 }
5102         }
5103         if (oldlvl == 0) {
5104                 if (iflag) { /* why if iflag only? */
5105                         setsignal(SIGINT);
5106                         setsignal(SIGTERM);
5107                 }
5108                 /* man bash:
5109                  * "In all cases, bash ignores SIGQUIT. Non-builtin
5110                  * commands run by bash have signal handlers
5111                  * set to the values inherited by the shell
5112                  * from its parent".
5113                  * Take care of the second rule: */
5114                 setsignal(SIGQUIT);
5115         }
5116 #if JOBS
5117         if (n && n->type == NCMD
5118          && n->ncmd.args && strcmp(n->ncmd.args->narg.text, "jobs") == 0
5119         ) {
5120                 TRACE(("Job hack\n"));
5121                 /* "jobs": we do not want to clear job list for it,
5122                  * instead we remove only _its_ own_ job from job list.
5123                  * This makes "jobs .... | cat" more useful.
5124                  */
5125                 freejob(curjob);
5126                 return;
5127         }
5128 #endif
5129         for (jp = curjob; jp; jp = jp->prev_job)
5130                 freejob(jp);
5131         jobless = 0;
5132 }
5133
5134 /* Called after fork(), in parent */
5135 #if !JOBS
5136 #define forkparent(jp, n, mode, pid) forkparent(jp, mode, pid)
5137 #endif
5138 static void
5139 forkparent(struct job *jp, union node *n, int mode, pid_t pid)
5140 {
5141         TRACE(("In parent shell: child = %d\n", pid));
5142         if (!jp) {
5143                 /* jp is NULL when called by openhere() for heredoc support */
5144                 while (jobless && dowait(DOWAIT_NONBLOCK, NULL) > 0)
5145                         continue;
5146                 jobless++;
5147                 return;
5148         }
5149 #if JOBS
5150         if (mode != FORK_NOJOB && jp->jobctl) {
5151                 int pgrp;
5152
5153                 if (jp->nprocs == 0)
5154                         pgrp = pid;
5155                 else
5156                         pgrp = jp->ps[0].ps_pid;
5157                 /* This can fail because we are doing it in the child also */
5158                 setpgid(pid, pgrp);
5159         }
5160 #endif
5161         if (mode == FORK_BG) {
5162                 backgndpid = pid;               /* set $! */
5163                 set_curjob(jp, CUR_RUNNING);
5164         }
5165         if (jp) {
5166                 struct procstat *ps = &jp->ps[jp->nprocs++];
5167                 ps->ps_pid = pid;
5168                 ps->ps_status = -1;
5169                 ps->ps_cmd = nullstr;
5170 #if JOBS
5171                 if (doing_jobctl && n)
5172                         ps->ps_cmd = commandtext(n);
5173 #endif
5174         }
5175 }
5176
5177 /* jp and n are NULL when called by openhere() for heredoc support */
5178 static int
5179 forkshell(struct job *jp, union node *n, int mode)
5180 {
5181         int pid;
5182
5183         TRACE(("forkshell(%%%d, %p, %d) called\n", jobno(jp), n, mode));
5184         pid = fork();
5185         if (pid < 0) {
5186                 TRACE(("Fork failed, errno=%d", errno));
5187                 if (jp)
5188                         freejob(jp);
5189                 ash_msg_and_raise_perror("can't fork");
5190         }
5191         if (pid == 0) {
5192                 CLEAR_RANDOM_T(&random_gen); /* or else $RANDOM repeats in child */
5193                 forkchild(jp, n, mode);
5194         } else {
5195                 forkparent(jp, n, mode, pid);
5196         }
5197         return pid;
5198 }
5199
5200 /*
5201  * Wait for job to finish.
5202  *
5203  * Under job control we have the problem that while a child process
5204  * is running interrupts generated by the user are sent to the child
5205  * but not to the shell.  This means that an infinite loop started by
5206  * an interactive user may be hard to kill.  With job control turned off,
5207  * an interactive user may place an interactive program inside a loop.
5208  * If the interactive program catches interrupts, the user doesn't want
5209  * these interrupts to also abort the loop.  The approach we take here
5210  * is to have the shell ignore interrupt signals while waiting for a
5211  * foreground process to terminate, and then send itself an interrupt
5212  * signal if the child process was terminated by an interrupt signal.
5213  * Unfortunately, some programs want to do a bit of cleanup and then
5214  * exit on interrupt; unless these processes terminate themselves by
5215  * sending a signal to themselves (instead of calling exit) they will
5216  * confuse this approach.
5217  *
5218  * Called with interrupts off.
5219  */
5220 static int
5221 waitforjob(struct job *jp)
5222 {
5223         int st;
5224
5225         TRACE(("waitforjob(%%%d) called\n", jobno(jp)));
5226
5227         INT_OFF;
5228         while (jp->state == JOBRUNNING) {
5229                 /* In non-interactive shells, we _can_ get
5230                  * a keyboard signal here and be EINTRed,
5231                  * but we just loop back, waiting for command to complete.
5232                  *
5233                  * man bash:
5234                  * "If bash is waiting for a command to complete and receives
5235                  * a signal for which a trap has been set, the trap
5236                  * will not be executed until the command completes."
5237                  *
5238                  * Reality is that even if trap is not set, bash
5239                  * will not act on the signal until command completes.
5240                  * Try this. sleep5intoff.c:
5241                  * #include <signal.h>
5242                  * #include <unistd.h>
5243                  * int main() {
5244                  *         sigset_t set;
5245                  *         sigemptyset(&set);
5246                  *         sigaddset(&set, SIGINT);
5247                  *         sigaddset(&set, SIGQUIT);
5248                  *         sigprocmask(SIG_BLOCK, &set, NULL);
5249                  *         sleep(5);
5250                  *         return 0;
5251                  * }
5252                  * $ bash -c './sleep5intoff; echo hi'
5253                  * ^C^C^C^C <--- pressing ^C once a second
5254                  * $ _
5255                  * $ bash -c './sleep5intoff; echo hi'
5256                  * ^\^\^\^\hi <--- pressing ^\ (SIGQUIT)
5257                  * $ _
5258                  */
5259                 dowait(DOWAIT_BLOCK, jp);
5260         }
5261         INT_ON;
5262
5263         st = getstatus(jp);
5264 #if JOBS
5265         if (jp->jobctl) {
5266                 xtcsetpgrp(ttyfd, rootpid);
5267                 restore_tty_if_stopped_or_signaled(jp);
5268
5269                 /*
5270                  * This is truly gross.
5271                  * If we're doing job control, then we did a TIOCSPGRP which
5272                  * caused us (the shell) to no longer be in the controlling
5273                  * session -- so we wouldn't have seen any ^C/SIGINT.  So, we
5274                  * intuit from the subprocess exit status whether a SIGINT
5275                  * occurred, and if so interrupt ourselves.  Yuck.  - mycroft
5276                  */
5277                 if (jp->sigint) /* TODO: do the same with all signals */
5278                         raise(SIGINT); /* ... by raise(jp->sig) instead? */
5279         }
5280         if (jp->state == JOBDONE)
5281 #endif
5282                 freejob(jp);
5283         return st;
5284 }
5285
5286 /*
5287  * return 1 if there are stopped jobs, otherwise 0
5288  */
5289 static int
5290 stoppedjobs(void)
5291 {
5292         struct job *jp;
5293         int retval;
5294
5295         retval = 0;
5296         if (job_warning)
5297                 goto out;
5298         jp = curjob;
5299         if (jp && jp->state == JOBSTOPPED) {
5300                 out2str("You have stopped jobs.\n");
5301                 job_warning = 2;
5302                 retval++;
5303         }
5304  out:
5305         return retval;
5306 }
5307
5308
5309 /*
5310  * Code for dealing with input/output redirection.
5311  */
5312
5313 #undef EMPTY
5314 #undef CLOSED
5315 #define EMPTY -2                /* marks an unused slot in redirtab */
5316 #define CLOSED -1               /* marks a slot of previously-closed fd */
5317
5318 /*
5319  * Handle here documents.  Normally we fork off a process to write the
5320  * data to a pipe.  If the document is short, we can stuff the data in
5321  * the pipe without forking.
5322  */
5323 /* openhere needs this forward reference */
5324 static void expandhere(union node *arg, int fd);
5325 static int
5326 openhere(union node *redir)
5327 {
5328         int pip[2];
5329         size_t len = 0;
5330
5331         if (pipe(pip) < 0)
5332                 ash_msg_and_raise_perror("can't create pipe");
5333         if (redir->type == NHERE) {
5334                 len = strlen(redir->nhere.doc->narg.text);
5335                 if (len <= PIPE_BUF) {
5336                         full_write(pip[1], redir->nhere.doc->narg.text, len);
5337                         goto out;
5338                 }
5339         }
5340         if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) {
5341                 /* child */
5342                 close(pip[0]);
5343                 ignoresig(SIGINT);  //signal(SIGINT, SIG_IGN);
5344                 ignoresig(SIGQUIT); //signal(SIGQUIT, SIG_IGN);
5345                 ignoresig(SIGHUP);  //signal(SIGHUP, SIG_IGN);
5346                 ignoresig(SIGTSTP); //signal(SIGTSTP, SIG_IGN);
5347                 signal(SIGPIPE, SIG_DFL);
5348                 if (redir->type == NHERE)
5349                         full_write(pip[1], redir->nhere.doc->narg.text, len);
5350                 else /* NXHERE */
5351                         expandhere(redir->nhere.doc, pip[1]);
5352                 _exit(EXIT_SUCCESS);
5353         }
5354  out:
5355         close(pip[1]);
5356         return pip[0];
5357 }
5358
5359 static int
5360 openredirect(union node *redir)
5361 {
5362         struct stat sb;
5363         char *fname;
5364         int f;
5365
5366         switch (redir->nfile.type) {
5367 /* Can't happen, our single caller does this itself */
5368 //      case NTOFD:
5369 //      case NFROMFD:
5370 //              return -1;
5371         case NHERE:
5372         case NXHERE:
5373                 return openhere(redir);
5374         }
5375
5376         /* For N[X]HERE, reading redir->nfile.expfname would touch beyond
5377          * allocated space. Do it only when we know it is safe.
5378          */
5379         fname = redir->nfile.expfname;
5380
5381         switch (redir->nfile.type) {
5382         default:
5383 #if DEBUG
5384                 abort();
5385 #endif
5386         case NFROM:
5387                 f = open(fname, O_RDONLY);
5388                 if (f < 0)
5389                         goto eopen;
5390                 break;
5391         case NFROMTO:
5392                 f = open(fname, O_RDWR|O_CREAT, 0666);
5393                 if (f < 0)
5394                         goto ecreate;
5395                 break;
5396         case NTO:
5397 #if BASH_REDIR_OUTPUT
5398         case NTO2:
5399 #endif
5400                 /* Take care of noclobber mode. */
5401                 if (Cflag) {
5402                         if (stat(fname, &sb) < 0) {
5403                                 f = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0666);
5404                                 if (f < 0)
5405                                         goto ecreate;
5406                         } else if (!S_ISREG(sb.st_mode)) {
5407                                 f = open(fname, O_WRONLY, 0666);
5408                                 if (f < 0)
5409                                         goto ecreate;
5410                                 if (!fstat(f, &sb) && S_ISREG(sb.st_mode)) {
5411                                         close(f);
5412                                         errno = EEXIST;
5413                                         goto ecreate;
5414                                 }
5415                         } else {
5416                                 errno = EEXIST;
5417                                 goto ecreate;
5418                         }
5419                         break;
5420                 }
5421                 /* FALLTHROUGH */
5422         case NCLOBBER:
5423                 f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666);
5424                 if (f < 0)
5425                         goto ecreate;
5426                 break;
5427         case NAPPEND:
5428                 f = open(fname, O_WRONLY|O_CREAT|O_APPEND, 0666);
5429                 if (f < 0)
5430                         goto ecreate;
5431                 break;
5432         }
5433
5434         return f;
5435  ecreate:
5436         ash_msg_and_raise_error("can't create %s: %s", fname, errmsg(errno, "nonexistent directory"));
5437  eopen:
5438         ash_msg_and_raise_error("can't open %s: %s", fname, errmsg(errno, "no such file"));
5439 }
5440
5441 /*
5442  * Copy a file descriptor to be >= 10. Throws exception on error.
5443  */
5444 static int
5445 savefd(int from)
5446 {
5447         int newfd;
5448         int err;
5449
5450         newfd = fcntl(from, F_DUPFD_CLOEXEC, 10);
5451         err = newfd < 0 ? errno : 0;
5452         if (err != EBADF) {
5453                 if (err)
5454                         ash_msg_and_raise_perror("%d", from);
5455                 close(from);
5456                 if (F_DUPFD_CLOEXEC == F_DUPFD)
5457                         close_on_exec_on(newfd);
5458         }
5459
5460         return newfd;
5461 }
5462 static int
5463 dup2_or_raise(int from, int to)
5464 {
5465         int newfd;
5466
5467         newfd = (from != to) ? dup2(from, to) : to;
5468         if (newfd < 0) {
5469                 /* Happens when source fd is not open: try "echo >&99" */
5470                 ash_msg_and_raise_perror("%d", from);
5471         }
5472         return newfd;
5473 }
5474 static int
5475 dup_CLOEXEC(int fd, int avoid_fd)
5476 {
5477         int newfd;
5478  repeat:
5479         newfd = fcntl(fd, F_DUPFD_CLOEXEC, avoid_fd + 1);
5480         if (newfd >= 0) {
5481                 if (F_DUPFD_CLOEXEC == F_DUPFD) /* if old libc (w/o F_DUPFD_CLOEXEC) */
5482                         close_on_exec_on(newfd);
5483         } else { /* newfd < 0 */
5484                 if (errno == EBUSY)
5485                         goto repeat;
5486                 if (errno == EINTR)
5487                         goto repeat;
5488         }
5489         return newfd;
5490 }
5491 static int
5492 xdup_CLOEXEC_and_close(int fd, int avoid_fd)
5493 {
5494         int newfd;
5495  repeat:
5496         newfd = fcntl(fd, F_DUPFD_CLOEXEC, avoid_fd + 1);
5497         if (newfd < 0) {
5498                 if (errno == EBUSY)
5499                         goto repeat;
5500                 if (errno == EINTR)
5501                         goto repeat;
5502                 /* fd was not open? */
5503                 if (errno == EBADF)
5504                         return fd;
5505                 ash_msg_and_raise_perror("%d", newfd);
5506         }
5507         if (F_DUPFD_CLOEXEC == F_DUPFD)
5508                 close_on_exec_on(newfd);
5509         close(fd);
5510         return newfd;
5511 }
5512
5513 /* Struct def and variable are moved down to the first usage site */
5514 struct squirrel {
5515         int orig_fd;
5516         int moved_to;
5517 };
5518 struct redirtab {
5519         struct redirtab *next;
5520         int pair_count;
5521         struct squirrel two_fd[];
5522 };
5523 #define redirlist (G_var.redirlist)
5524
5525 static void
5526 add_squirrel_closed(struct redirtab *sq, int fd)
5527 {
5528         int i;
5529
5530         if (!sq)
5531                 return;
5532
5533         for (i = 0; sq->two_fd[i].orig_fd != EMPTY; i++) {
5534                 /* If we collide with an already moved fd... */
5535                 if (fd == sq->two_fd[i].orig_fd) {
5536                         /* Examples:
5537                          * "echo 3>FILE 3>&- 3>FILE"
5538                          * "echo 3>&- 3>FILE"
5539                          * No need for last redirect to insert
5540                          * another "need to close 3" indicator.
5541                          */
5542                         TRACE(("redirect_fd %d: already moved or closed\n", fd));
5543                         return;
5544                 }
5545         }
5546         TRACE(("redirect_fd %d: previous fd was closed\n", fd));
5547         sq->two_fd[i].orig_fd = fd;
5548         sq->two_fd[i].moved_to = CLOSED;
5549 }
5550
5551 static int
5552 save_fd_on_redirect(int fd, int avoid_fd, struct redirtab *sq)
5553 {
5554         int i, new_fd;
5555
5556         if (avoid_fd < 9) /* the important case here is that it can be -1 */
5557                 avoid_fd = 9;
5558
5559 #if JOBS
5560         if (fd == ttyfd) {
5561                 /* Testcase: "ls -l /proc/$$/fd 10>&-" should work */
5562                 ttyfd = xdup_CLOEXEC_and_close(ttyfd, avoid_fd);
5563                 TRACE(("redirect_fd %d: matches ttyfd, moving it to %d\n", fd, ttyfd));
5564                 return 1; /* "we closed fd" */
5565         }
5566 #endif
5567         /* Are we called from redirect(0)? E.g. redirect
5568          * in a forked child. No need to save fds,
5569          * we aren't going to use them anymore, ok to trash.
5570          */
5571         if (!sq)
5572                 return 0;
5573
5574         /* If this one of script's fds? */
5575         if (fd != 0) {
5576                 struct parsefile *pf = g_parsefile;
5577                 while (pf) {
5578                         /* We skip fd == 0 case because of the following:
5579                          * $ ash  # running ash interactively
5580                          * $ . ./script.sh
5581                          * and in script.sh: "exec 9>&0".
5582                          * Even though top-level pf_fd _is_ 0,
5583                          * it's still ok to use it: "read" builtin uses it,
5584                          * why should we cripple "exec" builtin?
5585                          */
5586                         if (fd == pf->pf_fd) {
5587                                 pf->pf_fd = xdup_CLOEXEC_and_close(fd, avoid_fd);
5588                                 return 1; /* "we closed fd" */
5589                         }
5590                         pf = pf->prev;
5591                 }
5592         }
5593
5594         /* Check whether it collides with any open fds (e.g. stdio), save fds as needed */
5595
5596         /* First: do we collide with some already moved fds? */
5597         for (i = 0; sq->two_fd[i].orig_fd != EMPTY; i++) {
5598                 /* If we collide with an already moved fd... */
5599                 if (fd == sq->two_fd[i].moved_to) {
5600                         new_fd = dup_CLOEXEC(fd, avoid_fd);
5601                         sq->two_fd[i].moved_to = new_fd;
5602                         TRACE(("redirect_fd %d: already busy, moving to %d\n", fd, new_fd));
5603                         if (new_fd < 0) /* what? */
5604                                 xfunc_die();
5605                         return 0; /* "we did not close fd" */
5606                 }
5607                 if (fd == sq->two_fd[i].orig_fd) {
5608                         /* Example: echo Hello >/dev/null 1>&2 */
5609                         TRACE(("redirect_fd %d: already moved\n", fd));
5610                         return 0; /* "we did not close fd" */
5611                 }
5612         }
5613
5614         /* If this fd is open, we move and remember it; if it's closed, new_fd = CLOSED (-1) */
5615         new_fd = dup_CLOEXEC(fd, avoid_fd);
5616         TRACE(("redirect_fd %d: previous fd is moved to %d (-1 if it was closed)\n", fd, new_fd));
5617         if (new_fd < 0) {
5618                 if (errno != EBADF)
5619                         xfunc_die();
5620                 /* new_fd = CLOSED; - already is -1 */
5621         }
5622         sq->two_fd[i].moved_to = new_fd;
5623         sq->two_fd[i].orig_fd = fd;
5624
5625         /* if we move stderr, let "set -x" code know */
5626         if (fd == preverrout_fd)
5627                 preverrout_fd = new_fd;
5628
5629         return 0; /* "we did not close fd" */
5630 }
5631
5632 static int
5633 internally_opened_fd(int fd, struct redirtab *sq)
5634 {
5635         int i;
5636 #if JOBS
5637         if (fd == ttyfd)
5638                 return 1;
5639 #endif
5640         /* If this one of script's fds? */
5641         if (fd != 0) {
5642                 struct parsefile *pf = g_parsefile;
5643                 while (pf) {
5644                         if (fd == pf->pf_fd)
5645                                 return 1;
5646                         pf = pf->prev;
5647                 }
5648         }
5649
5650         if (sq) for (i = 0; i < sq->pair_count && sq->two_fd[i].orig_fd != EMPTY; i++) {
5651                 if (fd == sq->two_fd[i].moved_to)
5652                         return 1;
5653         }
5654         return 0;
5655 }
5656
5657 /*
5658  * Process a list of redirection commands.  If the REDIR_PUSH flag is set,
5659  * old file descriptors are stashed away so that the redirection can be
5660  * undone by calling popredir.
5661  */
5662 /* flags passed to redirect */
5663 #define REDIR_PUSH    01        /* save previous values of file descriptors */
5664 static void
5665 redirect(union node *redir, int flags)
5666 {
5667         struct redirtab *sv;
5668
5669         if (!redir)
5670                 return;
5671
5672         sv = NULL;
5673         INT_OFF;
5674         if (flags & REDIR_PUSH)
5675                 sv = redirlist;
5676         do {
5677                 int fd;
5678                 int newfd;
5679                 int close_fd;
5680                 int closed;
5681
5682                 fd = redir->nfile.fd;
5683                 if (redir->nfile.type == NTOFD || redir->nfile.type == NFROMFD) {
5684                         //bb_error_msg("doing %d > %d", fd, newfd);
5685                         newfd = redir->ndup.dupfd;
5686                         close_fd = -1;
5687                 } else {
5688                         newfd = openredirect(redir); /* always >= 0 */
5689                         if (fd == newfd) {
5690                                 /* open() gave us precisely the fd we wanted.
5691                                  * This means that this fd was not busy
5692                                  * (not opened to anywhere).
5693                                  * Remember to close it on restore:
5694                                  */
5695                                 add_squirrel_closed(sv, fd);
5696                                 continue;
5697                         }
5698                         close_fd = newfd;
5699                 }
5700
5701                 if (fd == newfd)
5702                         continue;
5703
5704                 /* if "N>FILE": move newfd to fd */
5705                 /* if "N>&M": dup newfd to fd */
5706                 /* if "N>&-": close fd (newfd is -1) */
5707
5708  IF_BASH_REDIR_OUTPUT(redirect_more:)
5709
5710                 closed = save_fd_on_redirect(fd, /*avoid:*/ newfd, sv);
5711                 if (newfd == -1) {
5712                         /* "N>&-" means "close me" */
5713                         if (!closed) {
5714                                 /* ^^^ optimization: saving may already
5715                                  * have closed it. If not... */
5716                                 close(fd);
5717                         }
5718                 } else {
5719                         /* if newfd is a script fd or saved fd, simulate EBADF */
5720                         if (internally_opened_fd(newfd, sv)) {
5721                                 errno = EBADF;
5722                                 ash_msg_and_raise_perror("%d", newfd);
5723                         }
5724                         dup2_or_raise(newfd, fd);
5725                         if (close_fd >= 0) /* "N>FILE" or ">&FILE" or heredoc? */
5726                                 close(close_fd);
5727 #if BASH_REDIR_OUTPUT
5728                         if (redir->nfile.type == NTO2 && fd == 1) {
5729                                 /* ">&FILE". we already redirected to 1, now copy 1 to 2 */
5730                                 fd = 2;
5731                                 newfd = 1;
5732                                 close_fd = -1;
5733                                 goto redirect_more;
5734                         }
5735 #endif
5736                 }
5737         } while ((redir = redir->nfile.next) != NULL);
5738         INT_ON;
5739
5740 //dash:#define REDIR_SAVEFD2 03        /* set preverrout */
5741 #define REDIR_SAVEFD2 0
5742         // dash has a bug: since REDIR_SAVEFD2=3 and REDIR_PUSH=1, this test
5743         // triggers for pure REDIR_PUSH too. Thus, this is done almost always,
5744         // not only for calls with flags containing REDIR_SAVEFD2.
5745         // We do this unconditionally (see save_fd_on_redirect()).
5746         //if ((flags & REDIR_SAVEFD2) && copied_fd2 >= 0)
5747         //      preverrout_fd = copied_fd2;
5748 }
5749
5750 static int
5751 redirectsafe(union node *redir, int flags)
5752 {
5753         int err;
5754         volatile int saveint;
5755         struct jmploc *volatile savehandler = exception_handler;
5756         struct jmploc jmploc;
5757
5758         SAVE_INT(saveint);
5759         /* "echo 9>/dev/null; echo >&9; echo result: $?" - result should be 1, not 2! */
5760         err = setjmp(jmploc.loc); /* was = setjmp(jmploc.loc) * 2; */
5761         if (!err) {
5762                 exception_handler = &jmploc;
5763                 redirect(redir, flags);
5764         }
5765         exception_handler = savehandler;
5766         if (err && exception_type != EXERROR)
5767                 longjmp(exception_handler->loc, 1);
5768         RESTORE_INT(saveint);
5769         return err;
5770 }
5771
5772 static struct redirtab*
5773 pushredir(union node *redir)
5774 {
5775         struct redirtab *sv;
5776         int i;
5777
5778         if (!redir)
5779                 return redirlist;
5780
5781         i = 0;
5782         do {
5783                 i++;
5784 #if BASH_REDIR_OUTPUT
5785                 if (redir->nfile.type == NTO2)
5786                         i++;
5787 #endif
5788                 redir = redir->nfile.next;
5789         } while (redir);
5790
5791         sv = ckzalloc(sizeof(*sv) + i * sizeof(sv->two_fd[0]));
5792         sv->pair_count = i;
5793         while (--i >= 0)
5794                 sv->two_fd[i].orig_fd = sv->two_fd[i].moved_to = EMPTY;
5795         sv->next = redirlist;
5796         redirlist = sv;
5797         return sv->next;
5798 }
5799
5800 /*
5801  * Undo the effects of the last redirection.
5802  */
5803 static void
5804 popredir(int drop)
5805 {
5806         struct redirtab *rp;
5807         int i;
5808
5809         if (redirlist == NULL)
5810                 return;
5811         INT_OFF;
5812         rp = redirlist;
5813         for (i = 0; i < rp->pair_count; i++) {
5814                 int fd = rp->two_fd[i].orig_fd;
5815                 int copy = rp->two_fd[i].moved_to;
5816                 if (copy == CLOSED) {
5817                         if (!drop)
5818                                 close(fd);
5819                         continue;
5820                 }
5821                 if (copy != EMPTY) {
5822                         if (!drop) {
5823                                 /*close(fd);*/
5824                                 dup2_or_raise(copy, fd);
5825                         }
5826                         close(copy);
5827                 }
5828         }
5829         redirlist = rp->next;
5830         free(rp);
5831         INT_ON;
5832 }
5833
5834 static void
5835 unwindredir(struct redirtab *stop)
5836 {
5837         while (redirlist != stop)
5838                 popredir(/*drop:*/ 0);
5839 }
5840
5841
5842 /* ============ Routines to expand arguments to commands
5843  *
5844  * We have to deal with backquotes, shell variables, and file metacharacters.
5845  */
5846
5847 #if ENABLE_FEATURE_SH_MATH
5848 static arith_t
5849 ash_arith(const char *s)
5850 {
5851         arith_state_t math_state;
5852         arith_t result;
5853
5854         math_state.lookupvar = lookupvar;
5855         math_state.setvar    = setvar0;
5856         //math_state.endofname = endofname;
5857
5858         INT_OFF;
5859         result = arith(&math_state, s);
5860         if (math_state.errmsg)
5861                 ash_msg_and_raise_error(math_state.errmsg);
5862         INT_ON;
5863
5864         return result;
5865 }
5866 #endif
5867 #if BASH_SUBSTR
5868 # if ENABLE_FEATURE_SH_MATH
5869 static int substr_atoi(const char *s)
5870 {
5871         arith_t t = ash_arith(s);
5872         if (sizeof(t) > sizeof(int)) {
5873                 /* clamp very large or very large negative nums for ${v:N:M}:
5874                  * else "${v:0:0x100000001}" would work as "${v:0:1}"
5875                  */
5876                 if (t > INT_MAX)
5877                         t = INT_MAX;
5878                 if (t < INT_MIN)
5879                         t = INT_MIN;
5880         }
5881         return t;
5882 }
5883 # else
5884 #  define substr_atoi(s) number(s)
5885 # endif
5886 #endif
5887
5888 /*
5889  * expandarg flags
5890  */
5891 #define EXP_FULL        0x1     /* perform word splitting & file globbing */
5892 #define EXP_TILDE       0x2     /* do normal tilde expansion */
5893 #define EXP_VARTILDE    0x4     /* expand tildes in an assignment */
5894 #define EXP_REDIR       0x8     /* file glob for a redirection (1 match only) */
5895 /* ^^^^^^^^^^^^^^ this is meant to support constructs such as "cmd >file*.txt"
5896  * POSIX says for this case:
5897  *  Pathname expansion shall not be performed on the word by a
5898  *  non-interactive shell; an interactive shell may perform it, but shall
5899  *  do so only when the expansion would result in one word.
5900  * Currently, our code complies to the above rule by never globbing
5901  * redirection filenames.
5902  * Bash performs globbing, unless it is non-interactive and in POSIX mode.
5903  * (this means that on a typical Linux distro, bash almost always
5904  * performs globbing, and thus diverges from what we do).
5905  */
5906 #define EXP_CASE        0x10    /* keeps quotes around for CASE pattern */
5907 #define EXP_VARTILDE2   0x20    /* expand tildes after colons only */
5908 #define EXP_WORD        0x40    /* expand word in parameter expansion */
5909 #define EXP_QUOTED      0x100   /* expand word in double quotes */
5910 /*
5911  * rmescape() flags
5912  */
5913 #define RMESCAPE_ALLOC  0x1     /* Allocate a new string */
5914 #define RMESCAPE_GLOB   0x2     /* Add backslashes for glob */
5915 #define RMESCAPE_GROW   0x8     /* Grow strings instead of stalloc */
5916 #define RMESCAPE_HEAP   0x10    /* Malloc strings instead of stalloc */
5917
5918 /* Add CTLESC when necessary. */
5919 #define QUOTES_ESC     (EXP_FULL | EXP_CASE)
5920 /* Do not skip NUL characters. */
5921 #define QUOTES_KEEPNUL EXP_TILDE
5922
5923 /*
5924  * Structure specifying which parts of the string should be searched
5925  * for IFS characters.
5926  */
5927 struct ifsregion {
5928         struct ifsregion *next; /* next region in list */
5929         int begoff;             /* offset of start of region */
5930         int endoff;             /* offset of end of region */
5931         int nulonly;            /* search for nul bytes only */
5932 };
5933
5934 struct arglist {
5935         struct strlist *list;
5936         struct strlist **lastp;
5937 };
5938
5939 /* output of current string */
5940 static char *expdest;
5941 /* list of back quote expressions */
5942 static struct nodelist *argbackq;
5943 /* first struct in list of ifs regions */
5944 static struct ifsregion ifsfirst;
5945 /* last struct in list */
5946 static struct ifsregion *ifslastp;
5947 /* holds expanded arg list */
5948 static struct arglist exparg;
5949
5950 /*
5951  * Our own itoa().
5952  * cvtnum() is used even if math support is off (to prepare $? values and such).
5953  */
5954 static int
5955 cvtnum(arith_t num)
5956 {
5957         int len;
5958
5959         /* 32-bit and wider ints require buffer size of bytes*3 (or less) */
5960         len = sizeof(arith_t) * 3;
5961         /* If narrower: worst case, 1-byte ints: need 5 bytes: "-127<NUL>" */
5962         if (sizeof(arith_t) < 4) len += 2;
5963
5964         expdest = makestrspace(len, expdest);
5965         len = fmtstr(expdest, len, ARITH_FMT, num);
5966         STADJUST(len, expdest);
5967         return len;
5968 }
5969
5970 /*
5971  * Break the argument string into pieces based upon IFS and add the
5972  * strings to the argument list.  The regions of the string to be
5973  * searched for IFS characters have been stored by recordregion.
5974  */
5975 static void
5976 ifsbreakup(char *string, struct arglist *arglist)
5977 {
5978         struct ifsregion *ifsp;
5979         struct strlist *sp;
5980         char *start;
5981         char *p;
5982         char *q;
5983         const char *ifs, *realifs;
5984         int ifsspc;
5985         int nulonly;
5986
5987         start = string;
5988         if (ifslastp != NULL) {
5989                 ifsspc = 0;
5990                 nulonly = 0;
5991                 realifs = ifsset() ? ifsval() : defifs;
5992                 ifsp = &ifsfirst;
5993                 do {
5994                         int afternul;
5995
5996                         p = string + ifsp->begoff;
5997                         afternul = nulonly;
5998                         nulonly = ifsp->nulonly;
5999                         ifs = nulonly ? nullstr : realifs;
6000                         ifsspc = 0;
6001                         while (p < string + ifsp->endoff) {
6002                                 q = p;
6003                                 if ((unsigned char)*p == CTLESC)
6004                                         p++;
6005                                 if (!strchr(ifs, *p)) {
6006                                         p++;
6007                                         continue;
6008                                 }
6009                                 if (!(afternul || nulonly))
6010                                         ifsspc = (strchr(defifs, *p) != NULL);
6011                                 /* Ignore IFS whitespace at start */
6012                                 if (q == start && ifsspc) {
6013                                         p++;
6014                                         start = p;
6015                                         continue;
6016                                 }
6017                                 *q = '\0';
6018                                 sp = stzalloc(sizeof(*sp));
6019                                 sp->text = start;
6020                                 *arglist->lastp = sp;
6021                                 arglist->lastp = &sp->next;
6022                                 p++;
6023                                 if (!nulonly) {
6024                                         for (;;) {
6025                                                 if (p >= string + ifsp->endoff) {
6026                                                         break;
6027                                                 }
6028                                                 q = p;
6029                                                 if ((unsigned char)*p == CTLESC)
6030                                                         p++;
6031                                                 if (strchr(ifs, *p) == NULL) {
6032                                                         p = q;
6033                                                         break;
6034                                                 }
6035                                                 if (strchr(defifs, *p) == NULL) {
6036                                                         if (ifsspc) {
6037                                                                 p++;
6038                                                                 ifsspc = 0;
6039                                                         } else {
6040                                                                 p = q;
6041                                                                 break;
6042                                                         }
6043                                                 } else
6044                                                         p++;
6045                                         }
6046                                 }
6047                                 start = p;
6048                         } /* while */
6049                         ifsp = ifsp->next;
6050                 } while (ifsp != NULL);
6051                 if (nulonly)
6052                         goto add;
6053         }
6054
6055         if (!*start)
6056                 return;
6057
6058  add:
6059         sp = stzalloc(sizeof(*sp));
6060         sp->text = start;
6061         *arglist->lastp = sp;
6062         arglist->lastp = &sp->next;
6063 }
6064
6065 static void
6066 ifsfree(void)
6067 {
6068         struct ifsregion *p = ifsfirst.next;
6069
6070         if (!p)
6071                 goto out;
6072
6073         INT_OFF;
6074         do {
6075                 struct ifsregion *ifsp;
6076                 ifsp = p->next;
6077                 free(p);
6078                 p = ifsp;
6079         } while (p);
6080         ifsfirst.next = NULL;
6081         INT_ON;
6082  out:
6083         ifslastp = NULL;
6084 }
6085
6086 static size_t
6087 esclen(const char *start, const char *p)
6088 {
6089         size_t esc = 0;
6090
6091         while (p > start && (unsigned char)*--p == CTLESC) {
6092                 esc++;
6093         }
6094         return esc;
6095 }
6096
6097 /*
6098  * Remove any CTLESC characters from a string.
6099  */
6100 #if !BASH_PATTERN_SUBST
6101 #define rmescapes(str, flag, slash_position) \
6102         rmescapes(str, flag)
6103 #endif
6104 static char *
6105 rmescapes(char *str, int flag, int *slash_position)
6106 {
6107         static const char qchars[] ALIGN1 = {
6108                 IF_BASH_PATTERN_SUBST('/',) CTLESC, CTLQUOTEMARK, '\0' };
6109
6110         char *p, *q, *r;
6111         unsigned protect_against_glob;
6112         unsigned globbing;
6113
6114         p = strpbrk(str, qchars IF_BASH_PATTERN_SUBST(+ !slash_position));
6115         if (!p)
6116                 return str;
6117
6118         q = p;
6119         r = str;
6120         if (flag & RMESCAPE_ALLOC) {
6121                 size_t len = p - str;
6122                 size_t fulllen = len + strlen(p) + 1;
6123
6124                 if (flag & RMESCAPE_GROW) {
6125                         int strloc = str - (char *)stackblock();
6126                         r = makestrspace(fulllen, expdest);
6127                         /* p and str may be invalidated by makestrspace */
6128                         str = (char *)stackblock() + strloc;
6129                         p = str + len;
6130                 } else if (flag & RMESCAPE_HEAP) {
6131                         r = ckmalloc(fulllen);
6132                 } else {
6133                         r = stalloc(fulllen);
6134                 }
6135                 q = r;
6136                 if (len > 0) {
6137                         q = (char *)mempcpy(q, str, len);
6138                 }
6139         }
6140
6141         globbing = flag & RMESCAPE_GLOB;
6142         protect_against_glob = globbing;
6143         while (*p) {
6144                 if ((unsigned char)*p == CTLQUOTEMARK) {
6145 // Note: protect_against_glob only affect whether
6146 // CTLESC,<ch> gets converted to <ch> or to \<ch>
6147                         p++;
6148                         protect_against_glob = globbing;
6149                         continue;
6150                 }
6151                 if (*p == '\\') {
6152                         /* naked back slash */
6153                         protect_against_glob = 0;
6154                         goto copy;
6155                 }
6156                 if ((unsigned char)*p == CTLESC) {
6157                         p++;
6158 #if DEBUG
6159                         if (*p == '\0')
6160                                 ash_msg_and_raise_error("CTLESC at EOL (shouldn't happen)");
6161 #endif
6162                         if (protect_against_glob) {
6163                                 /*
6164                                  * We used to trust glob() and fnmatch() to eat
6165                                  * superfluous escapes (\z where z has no
6166                                  * special meaning anyway). But this causes
6167                                  * bugs such as string of one greek letter rho
6168                                  * (unicode-encoded as two bytes "cf,81")
6169                                  * getting encoded as "cf,CTLESC,81"
6170                                  * and here, converted to "cf,\,81" -
6171                                  * which does not go well with some flavors
6172                                  * of fnmatch() in unicode locales
6173                                  * (for example, glibc <= 2.22).
6174                                  *
6175                                  * Lets add "\" only on the chars which need it.
6176                                  * Testcases for less obvious chars are shown.
6177                                  */
6178                                 if (*p == '*'
6179                                  || *p == '?'
6180                                  || *p == '['
6181                                  || *p == '\\' /* case '\' in \\    ) echo ok;; *) echo WRONG;; esac */
6182                                  || *p == ']'  /* case ']' in [a\]] ) echo ok;; *) echo WRONG;; esac */
6183                                  || *p == '-'  /* case '-' in [a\-c]) echo ok;; *) echo WRONG;; esac */
6184                                  || *p == '!'  /* case '!' in [\!]  ) echo ok;; *) echo WRONG;; esac */
6185                                 /* Some libc support [^negate], that's why "^" also needs love */
6186                                  || *p == '^'  /* case '^' in [\^]  ) echo ok;; *) echo WRONG;; esac */
6187                                 ) {
6188                                         *q++ = '\\';
6189                                 }
6190                         }
6191                 }
6192 #if BASH_PATTERN_SUBST
6193                 else if (slash_position && p == str + *slash_position) {
6194                         /* stop handling globbing */
6195                         globbing = 0;
6196                         *slash_position = q - r;
6197                         slash_position = NULL;
6198                 }
6199 #endif
6200                 protect_against_glob = globbing;
6201  copy:
6202                 *q++ = *p++;
6203         }
6204         *q = '\0';
6205         if (flag & RMESCAPE_GROW) {
6206                 expdest = r;
6207                 STADJUST(q - r + 1, expdest);
6208         }
6209         return r;
6210 }
6211 #define pmatch(a, b) !fnmatch((a), (b), 0)
6212
6213 /*
6214  * Prepare a pattern for a expmeta (internal glob(3)) call.
6215  *
6216  * Returns an stalloced string.
6217  */
6218 static char *
6219 preglob(const char *pattern, int flag)
6220 {
6221         return rmescapes((char *)pattern, flag | RMESCAPE_GLOB, NULL);
6222 }
6223
6224 /*
6225  * Put a string on the stack.
6226  */
6227 static void
6228 memtodest(const char *p, size_t len, int syntax, int quotes)
6229 {
6230         char *q;
6231
6232         if (!len)
6233                 return;
6234
6235         q = makestrspace((quotes & QUOTES_ESC) ? len * 2 : len, expdest);
6236
6237         do {
6238                 unsigned char c = *p++;
6239                 if (c) {
6240                         if (quotes & QUOTES_ESC) {
6241                                 int n = SIT(c, syntax);
6242                                 if (n == CCTL
6243                                  || (syntax != BASESYNTAX && n == CBACK)
6244                                 ) {
6245                                         USTPUTC(CTLESC, q);
6246                                 }
6247                         }
6248                 } else if (!(quotes & QUOTES_KEEPNUL))
6249                         continue;
6250                 USTPUTC(c, q);
6251         } while (--len);
6252
6253         expdest = q;
6254 }
6255
6256 static size_t
6257 strtodest(const char *p, int syntax, int quotes)
6258 {
6259         size_t len = strlen(p);
6260         memtodest(p, len, syntax, quotes);
6261         return len;
6262 }
6263
6264 /*
6265  * Record the fact that we have to scan this region of the
6266  * string for IFS characters.
6267  */
6268 static void
6269 recordregion(int start, int end, int nulonly)
6270 {
6271         struct ifsregion *ifsp;
6272
6273         if (ifslastp == NULL) {
6274                 ifsp = &ifsfirst;
6275         } else {
6276                 INT_OFF;
6277                 ifsp = ckzalloc(sizeof(*ifsp));
6278                 /*ifsp->next = NULL; - ckzalloc did it */
6279                 ifslastp->next = ifsp;
6280                 INT_ON;
6281         }
6282         ifslastp = ifsp;
6283         ifslastp->begoff = start;
6284         ifslastp->endoff = end;
6285         ifslastp->nulonly = nulonly;
6286 }
6287
6288 static void
6289 removerecordregions(int endoff)
6290 {
6291         if (ifslastp == NULL)
6292                 return;
6293
6294         if (ifsfirst.endoff > endoff) {
6295                 while (ifsfirst.next) {
6296                         struct ifsregion *ifsp;
6297                         INT_OFF;
6298                         ifsp = ifsfirst.next->next;
6299                         free(ifsfirst.next);
6300                         ifsfirst.next = ifsp;
6301                         INT_ON;
6302                 }
6303                 if (ifsfirst.begoff > endoff) {
6304                         ifslastp = NULL;
6305                 } else {
6306                         ifslastp = &ifsfirst;
6307                         ifsfirst.endoff = endoff;
6308                 }
6309                 return;
6310         }
6311
6312         ifslastp = &ifsfirst;
6313         while (ifslastp->next && ifslastp->next->begoff < endoff)
6314                 ifslastp = ifslastp->next;
6315         while (ifslastp->next) {
6316                 struct ifsregion *ifsp;
6317                 INT_OFF;
6318                 ifsp = ifslastp->next->next;
6319                 free(ifslastp->next);
6320                 ifslastp->next = ifsp;
6321                 INT_ON;
6322         }
6323         if (ifslastp->endoff > endoff)
6324                 ifslastp->endoff = endoff;
6325 }
6326
6327 static char *
6328 exptilde(char *startp, char *p, int flags)
6329 {
6330         unsigned char c;
6331         char *name;
6332         struct passwd *pw;
6333         const char *home;
6334         int quotes = flags & QUOTES_ESC;
6335
6336         name = p + 1;
6337
6338         while ((c = *++p) != '\0') {
6339                 switch (c) {
6340                 case CTLESC:
6341                         return startp;
6342                 case CTLQUOTEMARK:
6343                         return startp;
6344                 case ':':
6345                         if (flags & EXP_VARTILDE)
6346                                 goto done;
6347                         break;
6348                 case '/':
6349                 case CTLENDVAR:
6350                         goto done;
6351                 }
6352         }
6353  done:
6354         *p = '\0';
6355         if (*name == '\0') {
6356                 home = lookupvar("HOME");
6357         } else {
6358                 pw = getpwnam(name);
6359                 if (pw == NULL)
6360                         goto lose;
6361                 home = pw->pw_dir;
6362         }
6363         if (!home || !*home)
6364                 goto lose;
6365         *p = c;
6366         strtodest(home, SQSYNTAX, quotes);
6367         return p;
6368  lose:
6369         *p = c;
6370         return startp;
6371 }
6372
6373 /*
6374  * Execute a command inside back quotes.  If it's a builtin command, we
6375  * want to save its output in a block obtained from malloc.  Otherwise
6376  * we fork off a subprocess and get the output of the command via a pipe.
6377  * Should be called with interrupts off.
6378  */
6379 struct backcmd {                /* result of evalbackcmd */
6380         int fd;                 /* file descriptor to read from */
6381         int nleft;              /* number of chars in buffer */
6382         char *buf;              /* buffer */
6383         struct job *jp;         /* job structure for command */
6384 };
6385
6386 /* These forward decls are needed to use "eval" code for backticks handling: */
6387 /* flags in argument to evaltree */
6388 #define EV_EXIT    01           /* exit after evaluating tree */
6389 #define EV_TESTED  02           /* exit status is checked; ignore -e flag */
6390 static int evaltree(union node *, int);
6391
6392 /* An evaltree() which is known to never return.
6393  * Used to use an alias:
6394  * static int evaltreenr(union node *, int) __attribute__((alias("evaltree"),__noreturn__));
6395  * but clang was reported to "transfer" noreturn-ness to evaltree() as well.
6396  */
6397 static ALWAYS_INLINE NORETURN void
6398 evaltreenr(union node *n, int flags)
6399 {
6400         evaltree(n, flags);
6401         bb_unreachable(abort());
6402         /* NOTREACHED */
6403 }
6404
6405 static void FAST_FUNC
6406 evalbackcmd(union node *n, struct backcmd *result)
6407 {
6408         int pip[2];
6409         struct job *jp;
6410
6411         result->fd = -1;
6412         result->buf = NULL;
6413         result->nleft = 0;
6414         result->jp = NULL;
6415         if (n == NULL) {
6416                 goto out;
6417         }
6418
6419         if (pipe(pip) < 0)
6420                 ash_msg_and_raise_perror("can't create pipe");
6421         jp = makejob(/*n,*/ 1);
6422         if (forkshell(jp, n, FORK_NOJOB) == 0) {
6423                 /* child */
6424                 FORCE_INT_ON;
6425                 close(pip[0]);
6426                 if (pip[1] != 1) {
6427                         /*close(1);*/
6428                         dup2_or_raise(pip[1], 1);
6429                         close(pip[1]);
6430                 }
6431 /* TODO: eflag clearing makes the following not abort:
6432  *  ash -c 'set -e; z=$(false;echo foo); echo $z'
6433  * which is what bash does (unless it is in POSIX mode).
6434  * dash deleted "eflag = 0" line in the commit
6435  *  Date: Mon, 28 Jun 2010 17:11:58 +1000
6436  *  [EVAL] Don't clear eflag in evalbackcmd
6437  * For now, preserve bash-like behavior, it seems to be somewhat more useful:
6438  */
6439                 eflag = 0;
6440                 ifsfree();
6441                 evaltreenr(n, EV_EXIT);
6442                 /* NOTREACHED */
6443         }
6444         /* parent */
6445         close(pip[1]);
6446         result->fd = pip[0];
6447         result->jp = jp;
6448
6449  out:
6450         TRACE(("evalbackcmd done: fd=%d buf=0x%x nleft=%d jp=0x%x\n",
6451                 result->fd, result->buf, result->nleft, result->jp));
6452 }
6453
6454 /*
6455  * Expand stuff in backwards quotes.
6456  */
6457 static void
6458 expbackq(union node *cmd, int flag)
6459 {
6460         struct backcmd in;
6461         int i;
6462         char buf[128];
6463         char *p;
6464         char *dest;
6465         int startloc;
6466         int syntax = flag & EXP_QUOTED ? DQSYNTAX : BASESYNTAX;
6467         struct stackmark smark;
6468
6469         INT_OFF;
6470         startloc = expdest - (char *)stackblock();
6471         pushstackmark(&smark, startloc);
6472         evalbackcmd(cmd, &in);
6473         popstackmark(&smark);
6474
6475         p = in.buf;
6476         i = in.nleft;
6477         if (i == 0)
6478                 goto read;
6479         for (;;) {
6480                 memtodest(p, i, syntax, flag & QUOTES_ESC);
6481  read:
6482                 if (in.fd < 0)
6483                         break;
6484                 i = nonblock_immune_read(in.fd, buf, sizeof(buf));
6485                 TRACE(("expbackq: read returns %d\n", i));
6486                 if (i <= 0)
6487                         break;
6488                 p = buf;
6489         }
6490
6491         free(in.buf);
6492         if (in.fd >= 0) {
6493                 close(in.fd);
6494                 back_exitstatus = waitforjob(in.jp);
6495         }
6496         INT_ON;
6497
6498         /* Eat all trailing newlines */
6499         dest = expdest;
6500         for (; dest > (char *)stackblock() && dest[-1] == '\n';)
6501                 STUNPUTC(dest);
6502         expdest = dest;
6503
6504         if (!(flag & EXP_QUOTED))
6505                 recordregion(startloc, dest - (char *)stackblock(), 0);
6506         TRACE(("evalbackq: size:%d:'%.*s'\n",
6507                 (int)((dest - (char *)stackblock()) - startloc),
6508                 (int)((dest - (char *)stackblock()) - startloc),
6509                 stackblock() + startloc));
6510 }
6511
6512 #if ENABLE_FEATURE_SH_MATH
6513 /*
6514  * Expand arithmetic expression.  Backup to start of expression,
6515  * evaluate, place result in (backed up) result, adjust string position.
6516  */
6517 static void
6518 expari(int flag)
6519 {
6520         char *p, *start;
6521         int begoff;
6522         int len;
6523
6524         /* ifsfree(); */
6525
6526         /*
6527          * This routine is slightly over-complicated for
6528          * efficiency.  Next we scan backwards looking for the
6529          * start of arithmetic.
6530          */
6531         start = stackblock();
6532         p = expdest - 1;
6533         *p = '\0';
6534         p--;
6535         while (1) {
6536                 int esc;
6537
6538                 while ((unsigned char)*p != CTLARI) {
6539                         p--;
6540 #if DEBUG
6541                         if (p < start) {
6542                                 ash_msg_and_raise_error("missing CTLARI (shouldn't happen)");
6543                         }
6544 #endif
6545                 }
6546
6547                 esc = esclen(start, p);
6548                 if (!(esc % 2)) {
6549                         break;
6550                 }
6551
6552                 p -= esc + 1;
6553         }
6554
6555         begoff = p - start;
6556
6557         removerecordregions(begoff);
6558
6559         expdest = p;
6560
6561         if (flag & QUOTES_ESC)
6562                 rmescapes(p + 1, 0, NULL);
6563
6564         len = cvtnum(ash_arith(p + 1));
6565
6566         if (!(flag & EXP_QUOTED))
6567                 recordregion(begoff, begoff + len, 0);
6568 }
6569 #endif
6570
6571 /* argstr needs it */
6572 static char *evalvar(char *p, int flags);
6573
6574 /*
6575  * Perform variable and command substitution.  If EXP_FULL is set, output CTLESC
6576  * characters to allow for further processing.  Otherwise treat
6577  * $@ like $* since no splitting will be performed.
6578  */
6579 static void
6580 argstr(char *p, int flags)
6581 {
6582         static const char spclchars[] ALIGN1 = {
6583                 '=',
6584                 ':',
6585                 CTLQUOTEMARK,
6586                 CTLENDVAR,
6587                 CTLESC,
6588                 CTLVAR,
6589                 CTLBACKQ,
6590 #if ENABLE_FEATURE_SH_MATH
6591                 CTLENDARI,
6592 #endif
6593                 '\0'
6594         };
6595         const char *reject = spclchars;
6596         int breakall = (flags & (EXP_WORD | EXP_QUOTED)) == EXP_WORD;
6597         int inquotes;
6598         size_t length;
6599         int startloc;
6600
6601         if (!(flags & EXP_VARTILDE)) {
6602                 reject += 2;
6603         } else if (flags & EXP_VARTILDE2) {
6604                 reject++;
6605         }
6606         inquotes = 0;
6607         length = 0;
6608         if (flags & EXP_TILDE) {
6609                 char *q;
6610
6611                 flags &= ~EXP_TILDE;
6612  tilde:
6613                 q = p;
6614                 if (*q == '~')
6615                         p = exptilde(p, q, flags);
6616         }
6617  start:
6618         startloc = expdest - (char *)stackblock();
6619         for (;;) {
6620                 unsigned char c;
6621
6622                 length += strcspn(p + length, reject);
6623                 c = p[length];
6624                 if (c) {
6625                         if (!(c & 0x80)
6626                         IF_FEATURE_SH_MATH(|| c == CTLENDARI)
6627                         ) {
6628                                 /* c == '=' || c == ':' || c == CTLENDARI */
6629                                 length++;
6630                         }
6631                 }
6632                 if (length > 0) {
6633                         int newloc;
6634                         expdest = stack_nputstr(p, length, expdest);
6635                         newloc = expdest - (char *)stackblock();
6636                         if (breakall && !inquotes && newloc > startloc) {
6637                                 recordregion(startloc, newloc, 0);
6638                         }
6639                         startloc = newloc;
6640                 }
6641                 p += length + 1;
6642                 length = 0;
6643
6644                 switch (c) {
6645                 case '\0':
6646                         goto breakloop;
6647                 case '=':
6648                         if (flags & EXP_VARTILDE2) {
6649                                 p--;
6650                                 continue;
6651                         }
6652                         flags |= EXP_VARTILDE2;
6653                         reject++;
6654                         /* fall through */
6655                 case ':':
6656                         /*
6657                          * sort of a hack - expand tildes in variable
6658                          * assignments (after the first '=' and after ':'s).
6659                          */
6660                         if (*--p == '~') {
6661                                 goto tilde;
6662                         }
6663                         continue;
6664                 }
6665
6666                 switch (c) {
6667                 case CTLENDVAR: /* ??? */
6668                         goto breakloop;
6669                 case CTLQUOTEMARK:
6670                         /* "$@" syntax adherence hack */
6671                         if (!inquotes && !memcmp(p, dolatstr + 1, DOLATSTRLEN - 1)) {
6672                                 p = evalvar(p + 1, flags | EXP_QUOTED) + 1;
6673                                 goto start;
6674                         }
6675                         inquotes ^= EXP_QUOTED;
6676  addquote:
6677                         if (flags & QUOTES_ESC) {
6678                                 p--;
6679                                 length++;
6680                                 startloc++;
6681                         }
6682                         break;
6683                 case CTLESC:
6684                         startloc++;
6685                         length++;
6686                         goto addquote;
6687                 case CTLVAR:
6688                         TRACE(("argstr: evalvar('%s')\n", p));
6689                         p = evalvar(p, flags | inquotes);
6690                         TRACE(("argstr: evalvar:'%s'\n", (char *)stackblock()));
6691                         goto start;
6692                 case CTLBACKQ:
6693                         expbackq(argbackq->n, flags | inquotes);
6694                         argbackq = argbackq->next;
6695                         goto start;
6696 #if ENABLE_FEATURE_SH_MATH
6697                 case CTLENDARI:
6698                         p--;
6699                         expari(flags | inquotes);
6700                         goto start;
6701 #endif
6702                 }
6703         }
6704  breakloop: ;
6705 }
6706
6707 static char *
6708 scanleft(char *startp, char *rmesc, char *rmescend UNUSED_PARAM,
6709                 char *pattern, int quotes, int zero)
6710 {
6711         char *loc, *loc2;
6712         char c;
6713
6714         loc = startp;
6715         loc2 = rmesc;
6716         do {
6717                 int match;
6718                 const char *s = loc2;
6719
6720                 c = *loc2;
6721                 if (zero) {
6722                         *loc2 = '\0';
6723                         s = rmesc;
6724                 }
6725                 match = pmatch(pattern, s);
6726
6727                 *loc2 = c;
6728                 if (match)
6729                         return loc;
6730                 if (quotes && (unsigned char)*loc == CTLESC)
6731                         loc++;
6732                 loc++;
6733                 loc2++;
6734         } while (c);
6735         return NULL;
6736 }
6737
6738 static char *
6739 scanright(char *startp, char *rmesc, char *rmescend,
6740                 char *pattern, int quotes, int match_at_start)
6741 {
6742 #if !ENABLE_ASH_OPTIMIZE_FOR_SIZE
6743         int try2optimize = match_at_start;
6744 #endif
6745         int esc = 0;
6746         char *loc;
6747         char *loc2;
6748
6749         /* If we called by "${v/pattern/repl}" or "${v//pattern/repl}":
6750          * startp="escaped_value_of_v" rmesc="raw_value_of_v"
6751          * rmescend=""(ptr to NUL in rmesc) pattern="pattern" quotes=match_at_start=1
6752          * Logic:
6753          * loc starts at NUL at the end of startp, loc2 starts at the end of rmesc,
6754          * and on each iteration they go back two/one char until they reach the beginning.
6755          * We try to find a match in "raw_value_of_v", "raw_value_of_", "raw_value_of" etc.
6756          */
6757         /* TODO: document in what other circumstances we are called. */
6758
6759         for (loc = pattern - 1, loc2 = rmescend; loc >= startp; loc2--) {
6760                 int match;
6761                 char c = *loc2;
6762                 const char *s = loc2;
6763                 if (match_at_start) {
6764                         *loc2 = '\0';
6765                         s = rmesc;
6766                 }
6767                 match = pmatch(pattern, s);
6768                 //bb_error_msg("pmatch(pattern:'%s',s:'%s'):%d", pattern, s, match);
6769                 *loc2 = c;
6770                 if (match)
6771                         return loc;
6772 #if !ENABLE_ASH_OPTIMIZE_FOR_SIZE
6773                 if (try2optimize) {
6774                         /* Maybe we can optimize this:
6775                          * if pattern ends with unescaped *, we can avoid checking
6776                          * shorter strings: if "foo*" doesn't match "raw_value_of_v",
6777                          * it won't match truncated "raw_value_of_" strings too.
6778                          */
6779                         unsigned plen = strlen(pattern);
6780                         /* Does it end with "*"? */
6781                         if (plen != 0 && pattern[--plen] == '*') {
6782                                 /* "xxxx*" is not escaped */
6783                                 /* "xxx\*" is escaped */
6784                                 /* "xx\\*" is not escaped */
6785                                 /* "x\\\*" is escaped */
6786                                 int slashes = 0;
6787                                 while (plen != 0 && pattern[--plen] == '\\')
6788                                         slashes++;
6789                                 if (!(slashes & 1))
6790                                         break; /* ends with unescaped "*" */
6791                         }
6792                         try2optimize = 0;
6793                 }
6794 #endif
6795                 loc--;
6796                 if (quotes) {
6797                         if (--esc < 0) {
6798                                 esc = esclen(startp, loc);
6799                         }
6800                         if (esc % 2) {
6801                                 esc--;
6802                                 loc--;
6803                         }
6804                 }
6805         }
6806         return NULL;
6807 }
6808
6809 static void varunset(const char *, const char *, const char *, int) NORETURN;
6810 static void
6811 varunset(const char *end, const char *var, const char *umsg, int varflags)
6812 {
6813         const char *msg;
6814         const char *tail;
6815
6816         tail = nullstr;
6817         msg = "parameter not set";
6818         if (umsg) {
6819                 if ((unsigned char)*end == CTLENDVAR) {
6820                         if (varflags & VSNUL)
6821                                 tail = " or null";
6822                 } else {
6823                         msg = umsg;
6824                 }
6825         }
6826         ash_msg_and_raise_error("%.*s: %s%s", (int)(end - var - 1), var, msg, tail);
6827 }
6828
6829 static const char *
6830 subevalvar(char *p, char *varname, int strloc, int subtype,
6831                 int startloc, int varflags, int flag)
6832 {
6833         struct nodelist *saveargbackq = argbackq;
6834         int quotes = flag & QUOTES_ESC;
6835         char *startp;
6836         char *loc;
6837         char *rmesc, *rmescend;
6838         char *str;
6839         int amount, resetloc;
6840         int argstr_flags;
6841         IF_BASH_PATTERN_SUBST(int workloc;)
6842         IF_BASH_PATTERN_SUBST(int slash_pos;)
6843         IF_BASH_PATTERN_SUBST(char *repl;)
6844         int zero;
6845         char *(*scan)(char*, char*, char*, char*, int, int);
6846
6847         //bb_error_msg("subevalvar(p:'%s',varname:'%s',strloc:%d,subtype:%d,startloc:%d,varflags:%x,quotes:%d)",
6848         //              p, varname, strloc, subtype, startloc, varflags, quotes);
6849
6850 #if BASH_PATTERN_SUBST
6851         /* For "${v/pattern/repl}", we must find the delimiter _before_
6852          * argstr() call expands possible variable references in pattern:
6853          * think about "v=a; a=a/; echo ${v/$a/r}" case.
6854          */
6855         repl = NULL;
6856         if (subtype == VSREPLACE || subtype == VSREPLACEALL) {
6857                 /* Find '/' and replace with NUL */
6858                 repl = p;
6859                 /* The pattern can't be empty.
6860                  * IOW: if the first char after "${v//" is a slash,
6861                  * it does not terminate the pattern - it's the first char of the pattern:
6862                  *  v=/dev/ram; echo ${v////-}  prints -dev-ram (pattern is "/")
6863                  *  v=/dev/ram; echo ${v///r/-} prints /dev-am  (pattern is "/r")
6864                  */
6865                 if (*repl == '/')
6866                         repl++;
6867                 for (;;) {
6868                         if (*repl == '\0') {
6869                                 repl = NULL;
6870                                 break;
6871                         }
6872                         if (*repl == '/') {
6873                                 *repl = '\0';
6874                                 break;
6875                         }
6876                         /* Handle escaped slashes, e.g. "${v/\//_}" (they are CTLESC'ed by this point) */
6877                         if ((unsigned char)*repl == CTLESC && repl[1])
6878                                 repl++;
6879                         repl++;
6880                 }
6881         }
6882 #endif
6883         argstr_flags = EXP_TILDE;
6884         if (subtype != VSASSIGN
6885          && subtype != VSQUESTION
6886 #if BASH_SUBSTR
6887          && subtype != VSSUBSTR
6888 #endif
6889         ) {
6890                 /* EXP_CASE keeps CTLESC's */
6891                 argstr_flags = EXP_TILDE | EXP_CASE;
6892         }
6893         argstr(p, argstr_flags);
6894         //bb_error_msg("str0:'%s'", (char *)stackblock() + strloc);
6895 #if BASH_PATTERN_SUBST
6896         slash_pos = -1;
6897         if (repl) {
6898                 slash_pos = expdest - ((char *)stackblock() + strloc);
6899                 STPUTC('/', expdest);
6900                 //bb_error_msg("repl+1:'%s'", repl + 1);
6901                 argstr(repl + 1, EXP_TILDE); /* EXP_TILDE: echo "${v/x/~}" expands ~ ! */
6902                 *repl = '/';
6903         }
6904 #endif
6905         STPUTC('\0', expdest);
6906         argbackq = saveargbackq;
6907         startp = (char *)stackblock() + startloc;
6908         //bb_error_msg("str1:'%s'", (char *)stackblock() + strloc);
6909
6910         switch (subtype) {
6911         case VSASSIGN:
6912                 setvar0(varname, startp);
6913                 amount = startp - expdest;
6914                 STADJUST(amount, expdest);
6915                 return startp;
6916
6917         case VSQUESTION:
6918                 varunset(p, varname, startp, varflags);
6919                 /* NOTREACHED */
6920
6921 #if BASH_SUBSTR
6922         case VSSUBSTR: {
6923                 int pos, len, orig_len;
6924                 char *colon;
6925
6926                 loc = str = stackblock() + strloc;
6927
6928                 /* Read POS in ${var:POS:LEN} */
6929                 colon = strchr(loc, ':');
6930                 if (colon) *colon = '\0';
6931                 pos = substr_atoi(loc);
6932                 if (colon) *colon = ':';
6933
6934                 /* Read LEN in ${var:POS:LEN} */
6935                 len = str - startp - 1;
6936                 /* *loc != '\0', guaranteed by parser */
6937                 if (quotes) {
6938                         char *ptr;
6939                         /* Adjust the length by the number of escapes */
6940                         for (ptr = startp; ptr < (str - 1); ptr++) {
6941                                 if ((unsigned char)*ptr == CTLESC) {
6942                                         len--;
6943                                         ptr++;
6944                                 }
6945                         }
6946                 }
6947                 orig_len = len;
6948                 if (*loc++ == ':') {
6949                         /* ${var::LEN} */
6950                         len = substr_atoi(loc);
6951                 } else {
6952                         /* Skip POS in ${var:POS:LEN} */
6953                         len = orig_len;
6954                         while (*loc && *loc != ':')
6955                                 loc++;
6956                         if (*loc++ == ':')
6957                                 len = substr_atoi(loc);
6958                 }
6959                 if (pos < 0) {
6960                         /* ${VAR:$((-n)):l} starts n chars from the end */
6961                         pos = orig_len + pos;
6962                 }
6963                 if ((unsigned)pos >= orig_len) {
6964                         /* apart from obvious ${VAR:999999:l},
6965                          * covers ${VAR:$((-9999999)):l} - result is ""
6966                          * (bash compat)
6967                          */
6968                         pos = 0;
6969                         len = 0;
6970                 }
6971                 if (len < 0) {
6972                         /* ${VAR:N:-M} sets LEN to strlen()-M */
6973                         len = (orig_len - pos) + len;
6974                 }
6975                 if ((unsigned)len > (orig_len - pos))
6976                         len = orig_len - pos;
6977
6978                 for (str = startp; pos; str++, pos--) {
6979                         if (quotes && (unsigned char)*str == CTLESC)
6980                                 str++;
6981                 }
6982                 for (loc = startp; len; len--) {
6983                         if (quotes && (unsigned char)*str == CTLESC)
6984                                 *loc++ = *str++;
6985                         *loc++ = *str++;
6986                 }
6987                 *loc = '\0';
6988                 amount = loc - expdest;
6989                 STADJUST(amount, expdest);
6990                 return loc;
6991         }
6992 #endif /* BASH_SUBSTR */
6993         }
6994
6995         resetloc = expdest - (char *)stackblock();
6996
6997 #if BASH_PATTERN_SUBST
6998         repl = NULL;
6999
7000         /* We'll comeback here if we grow the stack while handling
7001          * a VSREPLACE or VSREPLACEALL, since our pointers into the
7002          * stack will need rebasing, and we'll need to remove our work
7003          * areas each time
7004          */
7005  restart:
7006 #endif
7007
7008         amount = expdest - ((char *)stackblock() + resetloc);
7009         STADJUST(-amount, expdest);
7010         startp = (char *)stackblock() + startloc;
7011
7012         rmesc = startp;
7013         rmescend = (char *)stackblock() + strloc;
7014         //bb_error_msg("str7:'%s'", rmescend);
7015         if (quotes) {
7016 //TODO: how to handle slash_pos here if string changes (shortens?)
7017                 rmesc = rmescapes(startp, RMESCAPE_ALLOC | RMESCAPE_GROW, NULL);
7018                 if (rmesc != startp) {
7019                         rmescend = expdest;
7020                         startp = (char *)stackblock() + startloc;
7021                 }
7022         }
7023         rmescend--;
7024         str = (char *)stackblock() + strloc;
7025         /*
7026          * Example: v='a\bc'; echo ${v/\\b/_\\_\z_}
7027          * The result is a_\_z_c (not a\_\_z_c)!
7028          *
7029          * The search pattern and replace string treat backslashes differently!
7030          * "&slash_pos" causes rmescapes() to work differently on the pattern
7031          * and string.  It's only used on the first call.
7032          */
7033         //bb_error_msg("str8:'%s' slash_pos:%d", str, slash_pos);
7034         rmescapes(str, RMESCAPE_GLOB,
7035                 repl ? NULL : (slash_pos < 0 ? NULL : &slash_pos)
7036         );
7037
7038 #if BASH_PATTERN_SUBST
7039         workloc = expdest - (char *)stackblock();
7040         if (subtype == VSREPLACE || subtype == VSREPLACEALL) {
7041                 int len;
7042                 char *idx, *end;
7043
7044                 if (!repl) {
7045                         //bb_error_msg("str9:'%s' slash_pos:%d", str, slash_pos);
7046                         repl = nullstr;
7047                         if (slash_pos >= 0) {
7048                                 repl = str + slash_pos;
7049                                 *repl++ = '\0';
7050                         }
7051                 }
7052                 //bb_error_msg("str:'%s' repl:'%s'", str, repl);
7053
7054                 /* If there's no pattern to match, return the expansion unmolested */
7055                 if (str[0] == '\0')
7056                         return NULL;
7057
7058                 len = 0;
7059                 idx = startp;
7060                 end = str - 1;
7061                 while (idx < end) {
7062  try_to_match:
7063                         loc = scanright(idx, rmesc, rmescend, str, quotes, 1);
7064                         //bb_error_msg("scanright('%s'):'%s'", str, loc);
7065                         if (!loc) {
7066                                 /* No match, advance */
7067                                 char *restart_detect = stackblock();
7068  skip_matching:
7069                                 STPUTC(*idx, expdest);
7070                                 if (quotes && (unsigned char)*idx == CTLESC) {
7071                                         idx++;
7072                                         len++;
7073                                         STPUTC(*idx, expdest);
7074                                 }
7075                                 if (stackblock() != restart_detect)
7076                                         goto restart;
7077                                 idx++;
7078                                 len++;
7079                                 rmesc++;
7080                                 /* continue; - prone to quadratic behavior, smarter code: */
7081                                 if (idx >= end)
7082                                         break;
7083                                 if (str[0] == '*') {
7084                                         /* Pattern is "*foo". If "*foo" does not match "long_string",
7085                                          * it would never match "ong_string" etc, no point in trying.
7086                                          */
7087                                         goto skip_matching;
7088                                 }
7089                                 goto try_to_match;
7090                         }
7091
7092                         if (subtype == VSREPLACEALL) {
7093                                 while (idx < loc) {
7094                                         if (quotes && (unsigned char)*idx == CTLESC)
7095                                                 idx++;
7096                                         idx++;
7097                                         rmesc++;
7098                                 }
7099                         } else {
7100                                 idx = loc;
7101                         }
7102
7103                         //bb_error_msg("repl:'%s'", repl);
7104                         for (loc = (char*)repl; *loc; loc++) {
7105                                 char *restart_detect = stackblock();
7106                                 if (quotes && *loc == '\\') {
7107                                         STPUTC(CTLESC, expdest);
7108                                         len++;
7109                                 }
7110                                 STPUTC(*loc, expdest);
7111                                 if (stackblock() != restart_detect)
7112                                         goto restart;
7113                                 len++;
7114                         }
7115
7116                         if (subtype == VSREPLACE) {
7117                                 //bb_error_msg("tail:'%s', quotes:%x", idx, quotes);
7118                                 while (*idx) {
7119                                         char *restart_detect = stackblock();
7120                                         STPUTC(*idx, expdest);
7121                                         if (stackblock() != restart_detect)
7122                                                 goto restart;
7123                                         len++;
7124                                         idx++;
7125                                 }
7126                                 break;
7127                         }
7128                 }
7129
7130                 /* We've put the replaced text into a buffer at workloc, now
7131                  * move it to the right place and adjust the stack.
7132                  */
7133                 STPUTC('\0', expdest);
7134                 startp = (char *)stackblock() + startloc;
7135                 memmove(startp, (char *)stackblock() + workloc, len + 1);
7136                 //bb_error_msg("startp:'%s'", startp);
7137                 amount = expdest - (startp + len);
7138                 STADJUST(-amount, expdest);
7139                 return startp;
7140         }
7141 #endif /* BASH_PATTERN_SUBST */
7142
7143         subtype -= VSTRIMRIGHT;
7144 #if DEBUG
7145         if (subtype < 0 || subtype > 7)
7146                 abort();
7147 #endif
7148         /* zero = (subtype == VSTRIMLEFT || subtype == VSTRIMLEFTMAX) */
7149         zero = subtype >> 1;
7150         /* VSTRIMLEFT/VSTRIMRIGHTMAX -> scanleft */
7151         scan = (subtype & 1) ^ zero ? scanleft : scanright;
7152
7153         loc = scan(startp, rmesc, rmescend, str, quotes, zero);
7154         if (loc) {
7155                 if (zero) {
7156                         memmove(startp, loc, str - loc);
7157                         loc = startp + (str - loc) - 1;
7158                 }
7159                 *loc = '\0';
7160                 amount = loc - expdest;
7161                 STADJUST(amount, expdest);
7162         }
7163         return loc;
7164 }
7165
7166 /*
7167  * Add the value of a specialized variable to the stack string.
7168  * name parameter (examples):
7169  * ash -c 'echo $1'      name:'1='
7170  * ash -c 'echo $qwe'    name:'qwe='
7171  * ash -c 'echo $$'      name:'$='
7172  * ash -c 'echo ${$}'    name:'$='
7173  * ash -c 'echo ${$##q}' name:'$=q'
7174  * ash -c 'echo ${#$}'   name:'$='
7175  * note: examples with bad shell syntax:
7176  * ash -c 'echo ${#$1}'  name:'$=1'
7177  * ash -c 'echo ${#1#}'  name:'1=#'
7178  */
7179 static NOINLINE ssize_t
7180 varvalue(char *name, int varflags, int flags, int quoted)
7181 {
7182         const char *p;
7183         int num;
7184         int i;
7185         ssize_t len = 0;
7186         int sep;
7187         int subtype = varflags & VSTYPE;
7188         int discard = subtype == VSPLUS || subtype == VSLENGTH;
7189         int quotes = (discard ? 0 : (flags & QUOTES_ESC)) | QUOTES_KEEPNUL;
7190         int syntax;
7191
7192         sep = (flags & EXP_FULL) << CHAR_BIT;
7193         syntax = quoted ? DQSYNTAX : BASESYNTAX;
7194
7195         switch (*name) {
7196         case '$':
7197                 num = rootpid;
7198                 goto numvar;
7199         case '?':
7200                 num = exitstatus;
7201                 goto numvar;
7202         case '#':
7203                 num = shellparam.nparam;
7204                 goto numvar;
7205         case '!':
7206                 num = backgndpid;
7207                 if (num == 0)
7208                         return -1;
7209  numvar:
7210                 len = cvtnum(num);
7211                 goto check_1char_name;
7212         case '-':
7213                 expdest = makestrspace(NOPTS, expdest);
7214                 for (i = NOPTS - 1; i >= 0; i--) {
7215                         if (optlist[i] && optletters(i)) {
7216                                 USTPUTC(optletters(i), expdest);
7217                                 len++;
7218                         }
7219                 }
7220  check_1char_name:
7221 #if 0
7222                 /* handles cases similar to ${#$1} */
7223                 if (name[2] != '\0')
7224                         raise_error_syntax("bad substitution");
7225 #endif
7226                 break;
7227         case '@':
7228                 if (quoted && sep)
7229                         goto param;
7230                 /* fall through */
7231         case '*': {
7232                 char **ap;
7233                 char sepc;
7234                 char c;
7235
7236                 /* We will set c to 0 or ~0 depending on whether
7237                  * we're doing field splitting.  We won't do field
7238                  * splitting if either we're quoted or sep is zero.
7239                  *
7240                  * Instead of testing (quoted || !sep) the following
7241                  * trick optimises away any branches by using the
7242                  * fact that EXP_QUOTED (which is the only bit that
7243                  * can be set in quoted) is the same as EXP_FULL <<
7244                  * CHAR_BIT (which is the only bit that can be set
7245                  * in sep).
7246                  */
7247 #if EXP_QUOTED >> CHAR_BIT != EXP_FULL
7248 #error The following two lines expect EXP_QUOTED == EXP_FULL << CHAR_BIT
7249 #endif
7250                 c = !((quoted | ~sep) & EXP_QUOTED) - 1;
7251                 sep &= ~quoted;
7252                 sep |= ifsset() ? (unsigned char)(c & ifsval()[0]) : ' ';
7253  param:
7254                 sepc = sep;
7255                 ap = shellparam.p;
7256                 if (!ap)
7257                         return -1;
7258                 while ((p = *ap++) != NULL) {
7259                         len += strtodest(p, syntax, quotes);
7260
7261                         if (*ap && sep) {
7262                                 len++;
7263                                 memtodest(&sepc, 1, syntax, quotes);
7264                         }
7265                 }
7266                 break;
7267         } /* case '*' */
7268         case '0':
7269         case '1':
7270         case '2':
7271         case '3':
7272         case '4':
7273         case '5':
7274         case '6':
7275         case '7':
7276         case '8':
7277         case '9':
7278                 num = atoi(name); /* number(name) fails on ${N#str} etc */
7279                 if (num < 0 || num > shellparam.nparam)
7280                         return -1;
7281                 p = num ? shellparam.p[num - 1] : arg0;
7282                 goto value;
7283         default:
7284                 /* NB: name has form "VAR=..." */
7285                 p = lookupvar(name);
7286  value:
7287                 if (!p)
7288                         return -1;
7289
7290                 len = strtodest(p, syntax, quotes);
7291 #if ENABLE_UNICODE_SUPPORT
7292                 if (subtype == VSLENGTH && len > 0) {
7293                         reinit_unicode_for_ash();
7294                         if (unicode_status == UNICODE_ON) {
7295                                 STADJUST(-len, expdest);
7296                                 discard = 0;
7297                                 len = unicode_strlen(p);
7298                         }
7299                 }
7300 #endif
7301                 break;
7302         }
7303
7304         if (discard)
7305                 STADJUST(-len, expdest);
7306         return len;
7307 }
7308
7309 /*
7310  * Expand a variable, and return a pointer to the next character in the
7311  * input string.
7312  */
7313 static char *
7314 evalvar(char *p, int flag)
7315 {
7316         char varflags;
7317         char subtype;
7318         int quoted;
7319         char *var;
7320         int patloc;
7321         int startloc;
7322         ssize_t varlen;
7323
7324         varflags = (unsigned char) *p++;
7325         subtype = varflags & VSTYPE;
7326
7327         if (!subtype)
7328                 raise_error_syntax("bad substitution");
7329
7330         quoted = flag & EXP_QUOTED;
7331         var = p;
7332         startloc = expdest - (char *)stackblock();
7333         p = strchr(p, '=') + 1; //TODO: use var_end(p)?
7334
7335  again:
7336         varlen = varvalue(var, varflags, flag, quoted);
7337         if (varflags & VSNUL)
7338                 varlen--;
7339
7340         if (subtype == VSPLUS) {
7341                 varlen = -1 - varlen;
7342                 goto vsplus;
7343         }
7344
7345         if (subtype == VSMINUS) {
7346  vsplus:
7347                 if (varlen < 0) {
7348                         argstr(
7349                                 p,
7350                                 flag | EXP_TILDE | EXP_WORD
7351                         );
7352                         goto end;
7353                 }
7354                 goto record;
7355         }
7356
7357         if (subtype == VSASSIGN || subtype == VSQUESTION) {
7358                 if (varlen >= 0)
7359                         goto record;
7360
7361                 subevalvar(p, var, 0, subtype, startloc, varflags,
7362                            flag & ~QUOTES_ESC);
7363                 varflags &= ~VSNUL;
7364                 /*
7365                  * Remove any recorded regions beyond
7366                  * start of variable
7367                  */
7368                 removerecordregions(startloc);
7369                 goto again;
7370         }
7371
7372         if (varlen < 0 && uflag)
7373                 varunset(p, var, 0, 0);
7374
7375         if (subtype == VSLENGTH) {
7376                 cvtnum(varlen > 0 ? varlen : 0);
7377                 goto record;
7378         }
7379
7380         if (subtype == VSNORMAL) {
7381  record:
7382                 if (quoted) {
7383                         quoted = *var == '@' && shellparam.nparam;
7384                         if (!quoted)
7385                                 goto end;
7386                 }
7387                 recordregion(startloc, expdest - (char *)stackblock(), quoted);
7388                 goto end;
7389         }
7390
7391 #if DEBUG
7392         switch (subtype) {
7393         case VSTRIMLEFT:
7394         case VSTRIMLEFTMAX:
7395         case VSTRIMRIGHT:
7396         case VSTRIMRIGHTMAX:
7397 #if BASH_SUBSTR
7398         case VSSUBSTR:
7399 #endif
7400 #if BASH_PATTERN_SUBST
7401         case VSREPLACE:
7402         case VSREPLACEALL:
7403 #endif
7404                 break;
7405         default:
7406                 abort();
7407         }
7408 #endif
7409
7410         if (varlen >= 0) {
7411                 /*
7412                  * Terminate the string and start recording the pattern
7413                  * right after it
7414                  */
7415                 STPUTC('\0', expdest);
7416                 patloc = expdest - (char *)stackblock();
7417                 if (NULL == subevalvar(p, /* varname: */ NULL, patloc, subtype,
7418                                 startloc, varflags, flag)) {
7419                         int amount = expdest - (
7420                                 (char *)stackblock() + patloc - 1
7421                         );
7422                         STADJUST(-amount, expdest);
7423                 }
7424                 /* Remove any recorded regions beyond start of variable */
7425                 removerecordregions(startloc);
7426                 goto record;
7427         }
7428
7429  end:
7430         if (subtype != VSNORMAL) {      /* skip to end of alternative */
7431                 int nesting = 1;
7432                 for (;;) {
7433                         unsigned char c = *p++;
7434                         if (c == CTLESC)
7435                                 p++;
7436                         else if (c == CTLBACKQ) {
7437                                 if (varlen >= 0)
7438                                         argbackq = argbackq->next;
7439                         } else if (c == CTLVAR) {
7440                                 if ((*p++ & VSTYPE) != VSNORMAL)
7441                                         nesting++;
7442                         } else if (c == CTLENDVAR) {
7443                                 if (--nesting == 0)
7444                                         break;
7445                         }
7446                 }
7447         }
7448         return p;
7449 }
7450
7451 /*
7452  * Add a file name to the list.
7453  */
7454 static void
7455 addfname(const char *name)
7456 {
7457         struct strlist *sp;
7458
7459         sp = stzalloc(sizeof(*sp));
7460         sp->text = sstrdup(name);
7461         *exparg.lastp = sp;
7462         exparg.lastp = &sp->next;
7463 }
7464
7465 /* Avoid glob() (and thus, stat() et al) for words like "echo" */
7466 static int
7467 hasmeta(const char *p)
7468 {
7469         static const char chars[] ALIGN1 = {
7470                 '*', '?', '[', '\\', CTLQUOTEMARK, CTLESC, 0
7471         };
7472
7473         for (;;) {
7474                 p = strpbrk(p, chars);
7475                 if (!p)
7476                         break;
7477                 switch ((unsigned char)*p) {
7478                 case CTLQUOTEMARK:
7479                         for (;;) {
7480                                 p++;
7481                                 if ((unsigned char)*p == CTLQUOTEMARK)
7482                                         break;
7483                                 if ((unsigned char)*p == CTLESC)
7484                                         p++;
7485                                 if (*p == '\0') /* huh? */
7486                                         return 0;
7487                         }
7488                         break;
7489                 case '\\':
7490                 case CTLESC:
7491                         p++;
7492                         if (*p == '\0')
7493                                 return 0;
7494                         break;
7495                 case '[':
7496                         if (!strchr(p + 1, ']')) {
7497                                 /* It's not a properly closed [] pattern,
7498                                  * but other metas may follow. Continue checking.
7499                                  * my[file* _is_ globbed by bash
7500                                  * and matches filenames like "my[file1".
7501                                  */
7502                                 break;
7503                         }
7504                         /* fallthrough */
7505                 default:
7506                 /* case '*': */
7507                 /* case '?': */
7508                         return 1;
7509                 }
7510                 p++;
7511         }
7512
7513         return 0;
7514 }
7515
7516 /* If we want to use glob() from libc... */
7517 #if !ENABLE_ASH_INTERNAL_GLOB
7518
7519 /* Add the result of glob() to the list */
7520 static void
7521 addglob(const glob_t *pglob)
7522 {
7523         char **p = pglob->gl_pathv;
7524
7525         do {
7526                 addfname(*p);
7527         } while (*++p);
7528 }
7529 static void
7530 expandmeta(struct strlist *str /*, int flag*/)
7531 {
7532         /* TODO - EXP_REDIR */
7533
7534         while (str) {
7535                 char *p;
7536                 glob_t pglob;
7537                 int i;
7538
7539                 if (fflag)
7540                         goto nometa;
7541
7542                 if (!hasmeta(str->text))
7543                         goto nometa;
7544
7545                 INT_OFF;
7546                 p = preglob(str->text, RMESCAPE_ALLOC | RMESCAPE_HEAP);
7547 // GLOB_NOMAGIC (GNU): if no *?[ chars in pattern, return it even if no match
7548 // GLOB_NOCHECK: if no match, return unchanged pattern (sans \* escapes?)
7549 //
7550 // glibc 2.24.90 glob(GLOB_NOMAGIC) does not remove backslashes used for escaping:
7551 // if you pass it "file\?", it returns "file\?", not "file?", if no match.
7552 // Which means you need to unescape the string, right? Not so fast:
7553 // if there _is_ a file named "file\?" (with backslash), it is returned
7554 // as "file\?" too (whichever pattern you used to find it, say, "file*").
7555 // You DON'T KNOW by looking at the result whether you need to unescape it.
7556 //
7557 // Worse, globbing of "file\?" in a directory with two files, "file?" and "file\?",
7558 // returns "file\?" - which is WRONG: "file\?" pattern matches "file?" file.
7559 // Without GLOB_NOMAGIC, this works correctly ("file?" is returned as a match).
7560 // With GLOB_NOMAGIC | GLOB_NOCHECK, this also works correctly.
7561 //              i = glob(p, GLOB_NOMAGIC | GLOB_NOCHECK, NULL, &pglob);
7562 //              i = glob(p, GLOB_NOMAGIC, NULL, &pglob);
7563                 i = glob(p, 0, NULL, &pglob);
7564                 //bb_error_msg("glob('%s'):%d '%s'...", p, i, pglob.gl_pathv ? pglob.gl_pathv[0] : "-");
7565                 if (p != str->text)
7566                         free(p);
7567                 switch (i) {
7568                 case 0:
7569 #if 0 // glibc 2.24.90 bug? Patterns like "*/file", when match, don't set GLOB_MAGCHAR
7570                         /* GLOB_MAGCHAR is set if *?[ chars were seen (GNU) */
7571                         if (!(pglob.gl_flags & GLOB_MAGCHAR))
7572                                 goto nometa2;
7573 #endif
7574                         addglob(&pglob);
7575                         globfree(&pglob);
7576                         INT_ON;
7577                         break;
7578                 case GLOB_NOMATCH:
7579  //nometa2:
7580                         globfree(&pglob);
7581                         INT_ON;
7582  nometa:
7583                         *exparg.lastp = str;
7584                         rmescapes(str->text, 0, NULL);
7585                         exparg.lastp = &str->next;
7586                         break;
7587                 default:        /* GLOB_NOSPACE */
7588                         globfree(&pglob);
7589                         INT_ON;
7590                         ash_msg_and_raise_error(bb_msg_memory_exhausted);
7591                 }
7592                 str = str->next;
7593         }
7594 }
7595
7596 #else
7597 /* ENABLE_ASH_INTERNAL_GLOB: Homegrown globbing code. (dash also has both, uses homegrown one.) */
7598
7599 /*
7600  * Do metacharacter (i.e. *, ?, [...]) expansion.
7601  */
7602 typedef struct exp_t {
7603         char *dir;
7604         unsigned dir_max;
7605 } exp_t;
7606 static void
7607 expmeta(exp_t *exp, char *name, unsigned name_len, unsigned expdir_len)
7608 {
7609 #define expdir exp->dir
7610 #define expdir_max exp->dir_max
7611         char *enddir = expdir + expdir_len;
7612         char *p;
7613         const char *cp;
7614         char *start;
7615         char *endname;
7616         int metaflag;
7617         struct stat statb;
7618         DIR *dirp;
7619         struct dirent *dp;
7620         int atend;
7621         int matchdot;
7622         int esc;
7623
7624         metaflag = 0;
7625         start = name;
7626         for (p = name; esc = 0, *p; p += esc + 1) {
7627                 if (*p == '*' || *p == '?')
7628                         metaflag = 1;
7629                 else if (*p == '[') {
7630                         char *q = p + 1;
7631                         if (*q == '!')
7632                                 q++;
7633                         for (;;) {
7634                                 if (*q == '\\')
7635                                         q++;
7636                                 if (*q == '/' || *q == '\0')
7637                                         break;
7638                                 if (*++q == ']') {
7639                                         metaflag = 1;
7640                                         break;
7641                                 }
7642                         }
7643                 } else {
7644                         if (*p == '\\' && p[1])
7645                                 esc++;
7646                         if (p[esc] == '/') {
7647                                 if (metaflag)
7648                                         break;
7649                                 start = p + esc + 1;
7650                         }
7651                 }
7652         }
7653         if (metaflag == 0) {    /* we've reached the end of the file name */
7654                 if (!expdir_len)
7655                         return;
7656                 p = name;
7657                 do {
7658                         if (*p == '\\' && p[1])
7659                                 p++;
7660                         *enddir++ = *p;
7661                 } while (*p++);
7662                 if (lstat(expdir, &statb) == 0)
7663                         addfname(expdir);
7664                 return;
7665         }
7666         endname = p;
7667         if (name < start) {
7668                 p = name;
7669                 do {
7670                         if (*p == '\\' && p[1])
7671                                 p++;
7672                         *enddir++ = *p++;
7673                 } while (p < start);
7674         }
7675         *enddir = '\0';
7676         cp = expdir;
7677         expdir_len = enddir - cp;
7678         if (!expdir_len)
7679                 cp = ".";
7680         dirp = opendir(cp);
7681         if (dirp == NULL)
7682                 return;
7683         if (*endname == 0) {
7684                 atend = 1;
7685         } else {
7686                 atend = 0;
7687                 *endname = '\0';
7688                 endname += esc + 1;
7689         }
7690         name_len -= endname - name;
7691         matchdot = 0;
7692         p = start;
7693         if (*p == '\\')
7694                 p++;
7695         if (*p == '.')
7696                 matchdot++;
7697         while (!pending_int && (dp = readdir(dirp)) != NULL) {
7698                 if (dp->d_name[0] == '.' && !matchdot)
7699                         continue;
7700                 if (pmatch(start, dp->d_name)) {
7701                         if (atend) {
7702                                 strcpy(enddir, dp->d_name);
7703                                 addfname(expdir);
7704                         } else {
7705                                 unsigned offset;
7706                                 unsigned len;
7707
7708                                 p = stpcpy(enddir, dp->d_name);
7709                                 *p = '/';
7710
7711                                 offset = p - expdir + 1;
7712                                 len = offset + name_len + NAME_MAX;
7713                                 if (len > expdir_max) {
7714                                         len += PATH_MAX;
7715                                         expdir = ckrealloc(expdir, len);
7716                                         expdir_max = len;
7717                                 }
7718
7719                                 expmeta(exp, endname, name_len, offset);
7720                                 enddir = expdir + expdir_len;
7721                         }
7722                 }
7723         }
7724         closedir(dirp);
7725         if (!atend)
7726                 endname[-esc - 1] = esc ? '\\' : '/';
7727 #undef expdir
7728 #undef expdir_max
7729 }
7730
7731 static struct strlist *
7732 msort(struct strlist *list, int len)
7733 {
7734         struct strlist *p, *q = NULL;
7735         struct strlist **lpp;
7736         int half;
7737         int n;
7738
7739         if (len <= 1)
7740                 return list;
7741         half = len >> 1;
7742         p = list;
7743         for (n = half; --n >= 0;) {
7744                 q = p;
7745                 p = p->next;
7746         }
7747         q->next = NULL;                 /* terminate first half of list */
7748         q = msort(list, half);          /* sort first half of list */
7749         p = msort(p, len - half);               /* sort second half */
7750         lpp = &list;
7751         for (;;) {
7752 #if ENABLE_LOCALE_SUPPORT
7753                 if (strcoll(p->text, q->text) < 0)
7754 #else
7755                 if (strcmp(p->text, q->text) < 0)
7756 #endif
7757                                                 {
7758                         *lpp = p;
7759                         lpp = &p->next;
7760                         p = *lpp;
7761                         if (p == NULL) {
7762                                 *lpp = q;
7763                                 break;
7764                         }
7765                 } else {
7766                         *lpp = q;
7767                         lpp = &q->next;
7768                         q = *lpp;
7769                         if (q == NULL) {
7770                                 *lpp = p;
7771                                 break;
7772                         }
7773                 }
7774         }
7775         return list;
7776 }
7777
7778 /*
7779  * Sort the results of file name expansion.  It calculates the number of
7780  * strings to sort and then calls msort (short for merge sort) to do the
7781  * work.
7782  */
7783 static struct strlist *
7784 expsort(struct strlist *str)
7785 {
7786         int len;
7787         struct strlist *sp;
7788
7789         len = 0;
7790         for (sp = str; sp; sp = sp->next)
7791                 len++;
7792         return msort(str, len);
7793 }
7794
7795 static void
7796 expandmeta(struct strlist *str /*, int flag*/)
7797 {
7798         /* TODO - EXP_REDIR */
7799
7800         while (str) {
7801                 exp_t exp;
7802                 struct strlist **savelastp;
7803                 struct strlist *sp;
7804                 char *p;
7805                 unsigned len;
7806
7807                 if (fflag)
7808                         goto nometa;
7809                 if (!hasmeta(str->text))
7810                         goto nometa;
7811                 savelastp = exparg.lastp;
7812
7813                 INT_OFF;
7814                 p = preglob(str->text, RMESCAPE_ALLOC | RMESCAPE_HEAP);
7815                 len = strlen(p);
7816                 exp.dir_max = len + PATH_MAX;
7817                 exp.dir = ckmalloc(exp.dir_max);
7818
7819                 expmeta(&exp, p, len, 0);
7820                 free(exp.dir);
7821                 if (p != str->text)
7822                         free(p);
7823                 INT_ON;
7824                 if (exparg.lastp == savelastp) {
7825                         /*
7826                          * no matches
7827                          */
7828  nometa:
7829                         *exparg.lastp = str;
7830                         rmescapes(str->text, 0, NULL);
7831                         exparg.lastp = &str->next;
7832                 } else {
7833                         *exparg.lastp = NULL;
7834                         *savelastp = sp = expsort(*savelastp);
7835                         while (sp->next != NULL)
7836                                 sp = sp->next;
7837                         exparg.lastp = &sp->next;
7838                 }
7839                 str = str->next;
7840         }
7841 }
7842 #endif /* ENABLE_ASH_INTERNAL_GLOB */
7843
7844 /*
7845  * Perform variable substitution and command substitution on an argument,
7846  * placing the resulting list of arguments in arglist.  If EXP_FULL is true,
7847  * perform splitting and file name expansion.  When arglist is NULL, perform
7848  * here document expansion.
7849  */
7850 static void
7851 expandarg(union node *arg, struct arglist *arglist, int flag)
7852 {
7853         struct strlist *sp;
7854         char *p;
7855
7856         argbackq = arg->narg.backquote;
7857         STARTSTACKSTR(expdest);
7858         TRACE(("expandarg: argstr('%s',flags:%x)\n", arg->narg.text, flag));
7859         argstr(arg->narg.text, flag);
7860         p = _STPUTC('\0', expdest);
7861         expdest = p - 1;
7862         if (arglist == NULL) {
7863                 /* here document expanded */
7864                 goto out;
7865         }
7866         p = grabstackstr(p);
7867         TRACE(("expandarg: p:'%s'\n", p));
7868         exparg.lastp = &exparg.list;
7869         /*
7870          * TODO - EXP_REDIR
7871          */
7872         if (flag & EXP_FULL) {
7873                 ifsbreakup(p, &exparg);
7874                 *exparg.lastp = NULL;
7875                 exparg.lastp = &exparg.list;
7876                 expandmeta(exparg.list /*, flag*/);
7877         } else {
7878                 sp = stzalloc(sizeof(*sp));
7879                 sp->text = p;
7880                 *exparg.lastp = sp;
7881                 exparg.lastp = &sp->next;
7882         }
7883         *exparg.lastp = NULL;
7884         if (exparg.list) {
7885                 *arglist->lastp = exparg.list;
7886                 arglist->lastp = exparg.lastp;
7887         }
7888
7889  out:
7890         ifsfree();
7891 }
7892
7893 /*
7894  * Expand shell variables and backquotes inside a here document.
7895  */
7896 static void
7897 expandhere(union node *arg, int fd)
7898 {
7899         expandarg(arg, (struct arglist *)NULL, EXP_QUOTED);
7900         full_write(fd, stackblock(), expdest - (char *)stackblock());
7901 }
7902
7903 /*
7904  * Returns true if the pattern matches the string.
7905  */
7906 static int
7907 patmatch(char *pattern, const char *string)
7908 {
7909         char *p = preglob(pattern, 0);
7910         int r = pmatch(p, string);
7911         //bb_error_msg("!fnmatch(pattern:'%s',str:'%s',0):%d", p, string, r);
7912         return r;
7913 }
7914
7915 /*
7916  * See if a pattern matches in a case statement.
7917  */
7918 static int
7919 casematch(union node *pattern, char *val)
7920 {
7921         struct stackmark smark;
7922         int result;
7923
7924         setstackmark(&smark);
7925         argbackq = pattern->narg.backquote;
7926         STARTSTACKSTR(expdest);
7927         argstr(pattern->narg.text, EXP_TILDE | EXP_CASE);
7928         STACKSTRNUL(expdest);
7929         ifsfree();
7930         result = patmatch(stackblock(), val);
7931         popstackmark(&smark);
7932         return result;
7933 }
7934
7935
7936 /* ============ find_command */
7937
7938 struct builtincmd {
7939         const char *name;
7940         int (*builtin)(int, char **) FAST_FUNC;
7941         /* unsigned flags; */
7942 };
7943 #define IS_BUILTIN_SPECIAL(b) ((b)->name[0] & 1)
7944 /* "regular" builtins always take precedence over commands,
7945  * regardless of PATH=....%builtin... position */
7946 #define IS_BUILTIN_REGULAR(b) ((b)->name[0] & 2)
7947 #define IS_BUILTIN_ASSIGN(b)  ((b)->name[0] & 4)
7948
7949 struct cmdentry {
7950         smallint cmdtype;       /* CMDxxx */
7951         union param {
7952                 int index;
7953                 /* index >= 0 for commands without path (slashes) */
7954                 /* (TODO: what exactly does the value mean? PATH position?) */
7955                 /* index == -1 for commands with slashes */
7956                 /* index == (-2 - applet_no) for NOFORK applets */
7957                 const struct builtincmd *cmd;
7958                 struct funcnode *func;
7959         } u;
7960 };
7961 /* values of cmdtype */
7962 #define CMDUNKNOWN      -1      /* no entry in table for command */
7963 #define CMDNORMAL       0       /* command is an executable program */
7964 #define CMDFUNCTION     1       /* command is a shell function */
7965 #define CMDBUILTIN      2       /* command is a shell builtin */
7966
7967 /* action to find_command() */
7968 #define DO_ERR          0x01    /* prints errors */
7969 #define DO_ABS          0x02    /* checks absolute paths */
7970 #define DO_NOFUNC       0x04    /* don't return shell functions, for command */
7971 #define DO_ALTPATH      0x08    /* using alternate path */
7972 #define DO_ALTBLTIN     0x20    /* %builtin in alt. path */
7973
7974 static void find_command(char *, struct cmdentry *, int, const char *);
7975
7976
7977 /* ============ Hashing commands */
7978
7979 /*
7980  * When commands are first encountered, they are entered in a hash table.
7981  * This ensures that a full path search will not have to be done for them
7982  * on each invocation.
7983  *
7984  * We should investigate converting to a linear search, even though that
7985  * would make the command name "hash" a misnomer.
7986  */
7987
7988 struct tblentry {
7989         struct tblentry *next;  /* next entry in hash chain */
7990         union param param;      /* definition of builtin function */
7991         smallint cmdtype;       /* CMDxxx */
7992         char rehash;            /* if set, cd done since entry created */
7993         char cmdname[1];        /* name of command */
7994 };
7995
7996 static struct tblentry **cmdtable;
7997 #define INIT_G_cmdtable() do { \
7998         cmdtable = xzalloc(CMDTABLESIZE * sizeof(cmdtable[0])); \
7999 } while (0)
8000
8001 static int builtinloc = -1;     /* index in path of %builtin, or -1 */
8002
8003
8004 static void
8005 tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) const char *cmd, char **argv, char **envp)
8006 {
8007 #if ENABLE_FEATURE_SH_STANDALONE
8008         if (applet_no >= 0) {
8009                 if (APPLET_IS_NOEXEC(applet_no)) {
8010                         clearenv();
8011                         while (*envp)
8012                                 putenv(*envp++);
8013                         popredir(/*drop:*/ 1);
8014                         run_noexec_applet_and_exit(applet_no, cmd, argv);
8015                 }
8016                 /* re-exec ourselves with the new arguments */
8017                 execve(bb_busybox_exec_path, argv, envp);
8018                 /* If they called chroot or otherwise made the binary no longer
8019                  * executable, fall through */
8020         }
8021 #endif
8022
8023  repeat:
8024 #ifdef SYSV
8025         do {
8026                 execve(cmd, argv, envp);
8027         } while (errno == EINTR);
8028 #else
8029         execve(cmd, argv, envp);
8030 #endif
8031
8032         if (cmd != bb_busybox_exec_path && errno == ENOEXEC) {
8033                 /* Run "cmd" as a shell script:
8034                  * http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html
8035                  * "If the execve() function fails with ENOEXEC, the shell
8036                  * shall execute a command equivalent to having a shell invoked
8037                  * with the command name as its first operand,
8038                  * with any remaining arguments passed to the new shell"
8039                  *
8040                  * That is, do not use $SHELL, user's shell, or /bin/sh;
8041                  * just call ourselves.
8042                  *
8043                  * Note that bash reads ~80 chars of the file, and if it sees
8044                  * a zero byte before it sees newline, it doesn't try to
8045                  * interpret it, but fails with "cannot execute binary file"
8046                  * message and exit code 126. For one, this prevents attempts
8047                  * to interpret foreign ELF binaries as shell scripts.
8048                  */
8049                 argv[0] = (char*) cmd;
8050                 cmd = bb_busybox_exec_path;
8051                 /* NB: this is only possible because all callers of shellexec()
8052                  * ensure that the argv[-1] slot exists!
8053                  */
8054                 argv--;
8055                 argv[0] = (char*) "ash";
8056                 goto repeat;
8057         }
8058 }
8059
8060 /*
8061  * Exec a program.  Never returns.  If you change this routine, you may
8062  * have to change the find_command routine as well.
8063  * argv[-1] must exist and be writable! See tryexec() for why.
8064  */
8065 static void shellexec(char *prog, char **argv, const char *path, int idx) NORETURN;
8066 static void shellexec(char *prog, char **argv, const char *path, int idx)
8067 {
8068         char *cmdname;
8069         int e;
8070         char **envp;
8071         int exerrno;
8072         int applet_no = -1; /* used only by FEATURE_SH_STANDALONE */
8073
8074         envp = listvars(VEXPORT, VUNSET, /*strlist:*/ NULL, /*end:*/ NULL);
8075         if (strchr(prog, '/') != NULL
8076 #if ENABLE_FEATURE_SH_STANDALONE
8077          || (applet_no = find_applet_by_name(prog)) >= 0
8078 #endif
8079         ) {
8080                 tryexec(IF_FEATURE_SH_STANDALONE(applet_no,) prog, argv, envp);
8081                 if (applet_no >= 0) {
8082                         /* We tried execing ourself, but it didn't work.
8083                          * Maybe /proc/self/exe doesn't exist?
8084                          * Try $PATH search.
8085                          */
8086                         goto try_PATH;
8087                 }
8088                 e = errno;
8089         } else {
8090  try_PATH:
8091                 e = ENOENT;
8092                 while ((cmdname = path_advance(&path, prog)) != NULL) {
8093                         if (--idx < 0 && pathopt == NULL) {
8094                                 tryexec(IF_FEATURE_SH_STANDALONE(-1,) cmdname, argv, envp);
8095                                 if (errno != ENOENT && errno != ENOTDIR)
8096                                         e = errno;
8097                         }
8098                         stunalloc(cmdname);
8099                 }
8100         }
8101
8102         /* Map to POSIX errors */
8103         switch (e) {
8104         default:
8105                 exerrno = 126;
8106                 break;
8107         case ELOOP:
8108         case ENAMETOOLONG:
8109         case ENOENT:
8110         case ENOTDIR:
8111                 exerrno = 127;
8112                 break;
8113         }
8114         exitstatus = exerrno;
8115         TRACE(("shellexec failed for %s, errno %d, suppress_int %d\n",
8116                 prog, e, suppress_int));
8117         ash_msg_and_raise(EXEXIT, "%s: %s", prog, errmsg(e, "not found"));
8118         /* NOTREACHED */
8119 }
8120
8121 static void
8122 printentry(struct tblentry *cmdp)
8123 {
8124         int idx;
8125         const char *path;
8126         char *name;
8127
8128         idx = cmdp->param.index;
8129         path = pathval();
8130         do {
8131                 name = path_advance(&path, cmdp->cmdname);
8132                 stunalloc(name);
8133         } while (--idx >= 0);
8134         out1fmt("%s%s\n", name, (cmdp->rehash ? "*" : nullstr));
8135 }
8136
8137 /*
8138  * Clear out command entries.  The argument specifies the first entry in
8139  * PATH which has changed.
8140  */
8141 static void
8142 clearcmdentry(int firstchange)
8143 {
8144         struct tblentry **tblp;
8145         struct tblentry **pp;
8146         struct tblentry *cmdp;
8147
8148         INT_OFF;
8149         for (tblp = cmdtable; tblp < &cmdtable[CMDTABLESIZE]; tblp++) {
8150                 pp = tblp;
8151                 while ((cmdp = *pp) != NULL) {
8152                         if ((cmdp->cmdtype == CMDNORMAL &&
8153                              cmdp->param.index >= firstchange)
8154                          || (cmdp->cmdtype == CMDBUILTIN &&
8155                              builtinloc >= firstchange)
8156                         ) {
8157                                 *pp = cmdp->next;
8158                                 free(cmdp);
8159                         } else {
8160                                 pp = &cmdp->next;
8161                         }
8162                 }
8163         }
8164         INT_ON;
8165 }
8166
8167 /*
8168  * Locate a command in the command hash table.  If "add" is nonzero,
8169  * add the command to the table if it is not already present.  The
8170  * variable "lastcmdentry" is set to point to the address of the link
8171  * pointing to the entry, so that delete_cmd_entry can delete the
8172  * entry.
8173  *
8174  * Interrupts must be off if called with add != 0.
8175  */
8176 static struct tblentry **lastcmdentry;
8177
8178 static struct tblentry *
8179 cmdlookup(const char *name, int add)
8180 {
8181         unsigned int hashval;
8182         const char *p;
8183         struct tblentry *cmdp;
8184         struct tblentry **pp;
8185
8186         p = name;
8187         hashval = (unsigned char)*p << 4;
8188         while (*p)
8189                 hashval += (unsigned char)*p++;
8190         hashval &= 0x7FFF;
8191         pp = &cmdtable[hashval % CMDTABLESIZE];
8192         for (cmdp = *pp; cmdp; cmdp = cmdp->next) {
8193                 if (strcmp(cmdp->cmdname, name) == 0)
8194                         break;
8195                 pp = &cmdp->next;
8196         }
8197         if (add && cmdp == NULL) {
8198                 cmdp = *pp = ckzalloc(sizeof(struct tblentry)
8199                                 + strlen(name)
8200                                 /* + 1 - already done because
8201                                  * tblentry::cmdname is char[1] */);
8202                 /*cmdp->next = NULL; - ckzalloc did it */
8203                 cmdp->cmdtype = CMDUNKNOWN;
8204                 strcpy(cmdp->cmdname, name);
8205         }
8206         lastcmdentry = pp;
8207         return cmdp;
8208 }
8209
8210 /*
8211  * Delete the command entry returned on the last lookup.
8212  */
8213 static void
8214 delete_cmd_entry(void)
8215 {
8216         struct tblentry *cmdp;
8217
8218         INT_OFF;
8219         cmdp = *lastcmdentry;
8220         *lastcmdentry = cmdp->next;
8221         if (cmdp->cmdtype == CMDFUNCTION)
8222                 freefunc(cmdp->param.func);
8223         free(cmdp);
8224         INT_ON;
8225 }
8226
8227 /*
8228  * Add a new command entry, replacing any existing command entry for
8229  * the same name - except special builtins.
8230  */
8231 static void
8232 addcmdentry(char *name, struct cmdentry *entry)
8233 {
8234         struct tblentry *cmdp;
8235
8236         cmdp = cmdlookup(name, 1);
8237         if (cmdp->cmdtype == CMDFUNCTION) {
8238                 freefunc(cmdp->param.func);
8239         }
8240         cmdp->cmdtype = entry->cmdtype;
8241         cmdp->param = entry->u;
8242         cmdp->rehash = 0;
8243 }
8244
8245 static int FAST_FUNC
8246 hashcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
8247 {
8248         struct tblentry **pp;
8249         struct tblentry *cmdp;
8250         int c;
8251         struct cmdentry entry;
8252         char *name;
8253
8254         if (nextopt("r") != '\0') {
8255                 clearcmdentry(0);
8256                 return 0;
8257         }
8258
8259         if (*argptr == NULL) {
8260                 for (pp = cmdtable; pp < &cmdtable[CMDTABLESIZE]; pp++) {
8261                         for (cmdp = *pp; cmdp; cmdp = cmdp->next) {
8262                                 if (cmdp->cmdtype == CMDNORMAL)
8263                                         printentry(cmdp);
8264                         }
8265                 }
8266                 return 0;
8267         }
8268
8269         c = 0;
8270         while ((name = *argptr) != NULL) {
8271                 cmdp = cmdlookup(name, 0);
8272                 if (cmdp != NULL
8273                  && (cmdp->cmdtype == CMDNORMAL
8274                      || (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0))
8275                 ) {
8276                         delete_cmd_entry();
8277                 }
8278                 find_command(name, &entry, DO_ERR, pathval());
8279                 if (entry.cmdtype == CMDUNKNOWN)
8280                         c = 1;
8281                 argptr++;
8282         }
8283         return c;
8284 }
8285
8286 /*
8287  * Called when a cd is done.  Marks all commands so the next time they
8288  * are executed they will be rehashed.
8289  */
8290 static void
8291 hashcd(void)
8292 {
8293         struct tblentry **pp;
8294         struct tblentry *cmdp;
8295
8296         for (pp = cmdtable; pp < &cmdtable[CMDTABLESIZE]; pp++) {
8297                 for (cmdp = *pp; cmdp; cmdp = cmdp->next) {
8298                         if (cmdp->cmdtype == CMDNORMAL
8299                          || (cmdp->cmdtype == CMDBUILTIN
8300                              && !IS_BUILTIN_REGULAR(cmdp->param.cmd)
8301                              && builtinloc > 0)
8302                         ) {
8303                                 cmdp->rehash = 1;
8304                         }
8305                 }
8306         }
8307 }
8308
8309 /*
8310  * Fix command hash table when PATH changed.
8311  * Called before PATH is changed.  The argument is the new value of PATH;
8312  * pathval() still returns the old value at this point.
8313  * Called with interrupts off.
8314  */
8315 static void FAST_FUNC
8316 changepath(const char *new)
8317 {
8318         const char *old;
8319         int firstchange;
8320         int idx;
8321         int idx_bltin;
8322
8323         old = pathval();
8324         firstchange = 9999;     /* assume no change */
8325         idx = 0;
8326         idx_bltin = -1;
8327         for (;;) {
8328                 if (*old != *new) {
8329                         firstchange = idx;
8330                         if ((*old == '\0' && *new == ':')
8331                          || (*old == ':' && *new == '\0')
8332                         ) {
8333                                 firstchange++;
8334                         }
8335                         old = new;      /* ignore subsequent differences */
8336                 }
8337                 if (*new == '\0')
8338                         break;
8339                 if (*new == '%' && idx_bltin < 0 && prefix(new + 1, "builtin"))
8340                         idx_bltin = idx;
8341                 if (*new == ':')
8342                         idx++;
8343                 new++;
8344                 old++;
8345         }
8346         if (builtinloc < 0 && idx_bltin >= 0)
8347                 builtinloc = idx_bltin;             /* zap builtins */
8348         if (builtinloc >= 0 && idx_bltin < 0)
8349                 firstchange = 0;
8350         clearcmdentry(firstchange);
8351         builtinloc = idx_bltin;
8352 }
8353 enum {
8354         TEOF,
8355         TNL,
8356         TREDIR,
8357         TWORD,
8358         TSEMI,
8359         TBACKGND,
8360         TAND,
8361         TOR,
8362         TPIPE,
8363         TLP,
8364         TRP,
8365         TENDCASE,
8366         TENDBQUOTE,
8367         TNOT,
8368         TCASE,
8369         TDO,
8370         TDONE,
8371         TELIF,
8372         TELSE,
8373         TESAC,
8374         TFI,
8375         TFOR,
8376 #if BASH_FUNCTION
8377         TFUNCTION,
8378 #endif
8379         TIF,
8380         TIN,
8381         TTHEN,
8382         TUNTIL,
8383         TWHILE,
8384         TBEGIN,
8385         TEND
8386 };
8387 typedef smallint token_id_t;
8388
8389 /* Nth bit indicates if token marks the end of a list */
8390 enum {
8391         tokendlist = 0
8392         /*  0 */ | (1u << TEOF)
8393         /*  1 */ | (0u << TNL)
8394         /*  2 */ | (0u << TREDIR)
8395         /*  3 */ | (0u << TWORD)
8396         /*  4 */ | (0u << TSEMI)
8397         /*  5 */ | (0u << TBACKGND)
8398         /*  6 */ | (0u << TAND)
8399         /*  7 */ | (0u << TOR)
8400         /*  8 */ | (0u << TPIPE)
8401         /*  9 */ | (0u << TLP)
8402         /* 10 */ | (1u << TRP)
8403         /* 11 */ | (1u << TENDCASE)
8404         /* 12 */ | (1u << TENDBQUOTE)
8405         /* 13 */ | (0u << TNOT)
8406         /* 14 */ | (0u << TCASE)
8407         /* 15 */ | (1u << TDO)
8408         /* 16 */ | (1u << TDONE)
8409         /* 17 */ | (1u << TELIF)
8410         /* 18 */ | (1u << TELSE)
8411         /* 19 */ | (1u << TESAC)
8412         /* 20 */ | (1u << TFI)
8413         /* 21 */ | (0u << TFOR)
8414 #if BASH_FUNCTION
8415         /* 22 */ | (0u << TFUNCTION)
8416 #endif
8417         /* 23 */ | (0u << TIF)
8418         /* 24 */ | (0u << TIN)
8419         /* 25 */ | (1u << TTHEN)
8420         /* 26 */ | (0u << TUNTIL)
8421         /* 27 */ | (0u << TWHILE)
8422         /* 28 */ | (0u << TBEGIN)
8423         /* 29 */ | (1u << TEND)
8424         , /* thus far 29 bits used */
8425 };
8426
8427 static const char *const tokname_array[] = {
8428         "end of file",
8429         "newline",
8430         "redirection",
8431         "word",
8432         ";",
8433         "&",
8434         "&&",
8435         "||",
8436         "|",
8437         "(",
8438         ")",
8439         ";;",
8440         "`",
8441 #define KWDOFFSET 13
8442         /* the following are keywords */
8443         "!",
8444         "case",
8445         "do",
8446         "done",
8447         "elif",
8448         "else",
8449         "esac",
8450         "fi",
8451         "for",
8452 #if BASH_FUNCTION
8453         "function",
8454 #endif
8455         "if",
8456         "in",
8457         "then",
8458         "until",
8459         "while",
8460         "{",
8461         "}",
8462 };
8463
8464 /* Wrapper around strcmp for qsort/bsearch/... */
8465 static int
8466 pstrcmp(const void *a, const void *b)
8467 {
8468         return strcmp((char*)a, *(char**)b);
8469 }
8470
8471 static const char *const *
8472 findkwd(const char *s)
8473 {
8474         return bsearch(s, tokname_array + KWDOFFSET,
8475                         ARRAY_SIZE(tokname_array) - KWDOFFSET,
8476                         sizeof(tokname_array[0]), pstrcmp);
8477 }
8478
8479 /*
8480  * Locate and print what a word is...
8481  */
8482 static int
8483 describe_command(char *command, const char *path, int describe_command_verbose)
8484 {
8485         struct cmdentry entry;
8486 #if ENABLE_ASH_ALIAS
8487         const struct alias *ap;
8488 #endif
8489
8490         path = path ? path : pathval();
8491
8492         if (describe_command_verbose) {
8493                 out1str(command);
8494         }
8495
8496         /* First look at the keywords */
8497         if (findkwd(command)) {
8498                 out1str(describe_command_verbose ? " is a shell keyword" : command);
8499                 goto out;
8500         }
8501
8502 #if ENABLE_ASH_ALIAS
8503         /* Then look at the aliases */
8504         ap = lookupalias(command, 0);
8505         if (ap != NULL) {
8506                 if (!describe_command_verbose) {
8507                         out1str("alias ");
8508                         printalias(ap);
8509                         return 0;
8510                 }
8511                 out1fmt(" is an alias for %s", ap->val);
8512                 goto out;
8513         }
8514 #endif
8515         /* Brute force */
8516         find_command(command, &entry, DO_ABS, path);
8517
8518         switch (entry.cmdtype) {
8519         case CMDNORMAL: {
8520                 int j = entry.u.index;
8521                 char *p;
8522                 if (j < 0) {
8523                         p = command;
8524                 } else {
8525                         do {
8526                                 p = path_advance(&path, command);
8527                                 stunalloc(p);
8528                         } while (--j >= 0);
8529                 }
8530                 if (describe_command_verbose) {
8531                         out1fmt(" is %s", p);
8532                 } else {
8533                         out1str(p);
8534                 }
8535                 break;
8536         }
8537
8538         case CMDFUNCTION:
8539                 if (describe_command_verbose) {
8540                         /*out1str(" is a shell function");*/
8541                         out1str(" is a function"); /* bash says this */
8542                 } else {
8543                         out1str(command);
8544                 }
8545                 break;
8546
8547         case CMDBUILTIN:
8548                 if (describe_command_verbose) {
8549                         out1fmt(" is a %sshell builtin",
8550                                 IS_BUILTIN_SPECIAL(entry.u.cmd) ?
8551                                         "special " : nullstr
8552                         );
8553                 } else {
8554                         out1str(command);
8555                 }
8556                 break;
8557
8558         default:
8559                 if (describe_command_verbose) {
8560                         out1str(": not found\n");
8561                 }
8562                 return 127;
8563         }
8564  out:
8565         out1str("\n");
8566         return 0;
8567 }
8568
8569 static int FAST_FUNC
8570 typecmd(int argc UNUSED_PARAM, char **argv)
8571 {
8572         int i = 1;
8573         int err = 0;
8574         int verbose = 1;
8575
8576         /* type -p ... ? (we don't bother checking for 'p') */
8577         if (argv[1] && argv[1][0] == '-') {
8578                 i++;
8579                 verbose = 0;
8580         }
8581         while (argv[i]) {
8582                 err |= describe_command(argv[i++], NULL, verbose);
8583         }
8584         return err;
8585 }
8586
8587 #if ENABLE_ASH_CMDCMD
8588 /* Is it "command [-p] PROG ARGS" bltin, no other opts? Return ptr to "PROG" if yes */
8589 static char **
8590 parse_command_args(char **argv, const char **path)
8591 {
8592         char *cp, c;
8593
8594         for (;;) {
8595                 cp = *++argv;
8596                 if (!cp)
8597                         return NULL;
8598                 if (*cp++ != '-')
8599                         break;
8600                 c = *cp++;
8601                 if (!c)
8602                         break;
8603                 if (c == '-' && !*cp) {
8604                         if (!*++argv)
8605                                 return NULL;
8606                         break;
8607                 }
8608                 do {
8609                         switch (c) {
8610                         case 'p':
8611                                 *path = bb_default_path;
8612                                 break;
8613                         default:
8614                                 /* run 'typecmd' for other options */
8615                                 return NULL;
8616                         }
8617                         c = *cp++;
8618                 } while (c);
8619         }
8620         return argv;
8621 }
8622
8623 static int FAST_FUNC
8624 commandcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
8625 {
8626         char *cmd;
8627         int c;
8628         enum {
8629                 VERIFY_BRIEF = 1,
8630                 VERIFY_VERBOSE = 2,
8631         } verify = 0;
8632         const char *path = NULL;
8633
8634         /* "command [-p] PROG ARGS" (that is, without -V or -v)
8635          * never reaches this function.
8636          */
8637
8638         while ((c = nextopt("pvV")) != '\0')
8639                 if (c == 'V')
8640                         verify |= VERIFY_VERBOSE;
8641                 else if (c == 'v')
8642                         /*verify |= VERIFY_BRIEF*/;
8643 #if DEBUG
8644                 else if (c != 'p')
8645                         abort();
8646 #endif
8647                 else
8648                         path = bb_default_path;
8649
8650         /* Mimic bash: just "command -v" doesn't complain, it's a nop */
8651         cmd = *argptr;
8652         if (/*verify && */ cmd)
8653                 return describe_command(cmd, path, verify /* - VERIFY_BRIEF*/);
8654
8655         return 0;
8656 }
8657 #endif
8658
8659
8660 /*static int funcblocksize;     // size of structures in function */
8661 /*static int funcstringsize;    // size of strings in node */
8662 static void *funcblock;         /* block to allocate function from */
8663 static char *funcstring_end;    /* end of block to allocate strings from */
8664
8665 static const uint8_t nodesize[N_NUMBER] ALIGN1 = {
8666         [NCMD     ] = SHELL_ALIGN(sizeof(struct ncmd)),
8667         [NPIPE    ] = SHELL_ALIGN(sizeof(struct npipe)),
8668         [NREDIR   ] = SHELL_ALIGN(sizeof(struct nredir)),
8669         [NBACKGND ] = SHELL_ALIGN(sizeof(struct nredir)),
8670         [NSUBSHELL] = SHELL_ALIGN(sizeof(struct nredir)),
8671         [NAND     ] = SHELL_ALIGN(sizeof(struct nbinary)),
8672         [NOR      ] = SHELL_ALIGN(sizeof(struct nbinary)),
8673         [NSEMI    ] = SHELL_ALIGN(sizeof(struct nbinary)),
8674         [NIF      ] = SHELL_ALIGN(sizeof(struct nif)),
8675         [NWHILE   ] = SHELL_ALIGN(sizeof(struct nbinary)),
8676         [NUNTIL   ] = SHELL_ALIGN(sizeof(struct nbinary)),
8677         [NFOR     ] = SHELL_ALIGN(sizeof(struct nfor)),
8678         [NCASE    ] = SHELL_ALIGN(sizeof(struct ncase)),
8679         [NCLIST   ] = SHELL_ALIGN(sizeof(struct nclist)),
8680         [NDEFUN   ] = SHELL_ALIGN(sizeof(struct narg)),
8681         [NARG     ] = SHELL_ALIGN(sizeof(struct narg)),
8682         [NTO      ] = SHELL_ALIGN(sizeof(struct nfile)),
8683 #if BASH_REDIR_OUTPUT
8684         [NTO2     ] = SHELL_ALIGN(sizeof(struct nfile)),
8685 #endif
8686         [NCLOBBER ] = SHELL_ALIGN(sizeof(struct nfile)),
8687         [NFROM    ] = SHELL_ALIGN(sizeof(struct nfile)),
8688         [NFROMTO  ] = SHELL_ALIGN(sizeof(struct nfile)),
8689         [NAPPEND  ] = SHELL_ALIGN(sizeof(struct nfile)),
8690         [NTOFD    ] = SHELL_ALIGN(sizeof(struct ndup)),
8691         [NFROMFD  ] = SHELL_ALIGN(sizeof(struct ndup)),
8692         [NHERE    ] = SHELL_ALIGN(sizeof(struct nhere)),
8693         [NXHERE   ] = SHELL_ALIGN(sizeof(struct nhere)),
8694         [NNOT     ] = SHELL_ALIGN(sizeof(struct nnot)),
8695 };
8696
8697 static int calcsize(int funcblocksize, union node *n);
8698
8699 static int
8700 sizenodelist(int funcblocksize, struct nodelist *lp)
8701 {
8702         while (lp) {
8703                 funcblocksize += SHELL_ALIGN(sizeof(struct nodelist));
8704                 funcblocksize = calcsize(funcblocksize, lp->n);
8705                 lp = lp->next;
8706         }
8707         return funcblocksize;
8708 }
8709
8710 static int
8711 calcsize(int funcblocksize, union node *n)
8712 {
8713         if (n == NULL)
8714                 return funcblocksize;
8715         funcblocksize += nodesize[n->type];
8716         switch (n->type) {
8717         case NCMD:
8718                 funcblocksize = calcsize(funcblocksize, n->ncmd.redirect);
8719                 funcblocksize = calcsize(funcblocksize, n->ncmd.args);
8720                 funcblocksize = calcsize(funcblocksize, n->ncmd.assign);
8721                 break;
8722         case NPIPE:
8723                 funcblocksize = sizenodelist(funcblocksize, n->npipe.cmdlist);
8724                 break;
8725         case NREDIR:
8726         case NBACKGND:
8727         case NSUBSHELL:
8728                 funcblocksize = calcsize(funcblocksize, n->nredir.redirect);
8729                 funcblocksize = calcsize(funcblocksize, n->nredir.n);
8730                 break;
8731         case NAND:
8732         case NOR:
8733         case NSEMI:
8734         case NWHILE:
8735         case NUNTIL:
8736                 funcblocksize = calcsize(funcblocksize, n->nbinary.ch2);
8737                 funcblocksize = calcsize(funcblocksize, n->nbinary.ch1);
8738                 break;
8739         case NIF:
8740                 funcblocksize = calcsize(funcblocksize, n->nif.elsepart);
8741                 funcblocksize = calcsize(funcblocksize, n->nif.ifpart);
8742                 funcblocksize = calcsize(funcblocksize, n->nif.test);
8743                 break;
8744         case NFOR:
8745                 funcblocksize += SHELL_ALIGN(strlen(n->nfor.var) + 1); /* was funcstringsize += ... */
8746                 funcblocksize = calcsize(funcblocksize, n->nfor.body);
8747                 funcblocksize = calcsize(funcblocksize, n->nfor.args);
8748                 break;
8749         case NCASE:
8750                 funcblocksize = calcsize(funcblocksize, n->ncase.cases);
8751                 funcblocksize = calcsize(funcblocksize, n->ncase.expr);
8752                 break;
8753         case NCLIST:
8754                 funcblocksize = calcsize(funcblocksize, n->nclist.body);
8755                 funcblocksize = calcsize(funcblocksize, n->nclist.pattern);
8756                 funcblocksize = calcsize(funcblocksize, n->nclist.next);
8757                 break;
8758         case NDEFUN:
8759                 funcblocksize = calcsize(funcblocksize, n->ndefun.body);
8760                 funcblocksize += SHELL_ALIGN(strlen(n->ndefun.text) + 1);
8761                 break;
8762         case NARG:
8763                 funcblocksize = sizenodelist(funcblocksize, n->narg.backquote);
8764                 funcblocksize += SHELL_ALIGN(strlen(n->narg.text) + 1); /* was funcstringsize += ... */
8765                 funcblocksize = calcsize(funcblocksize, n->narg.next);
8766                 break;
8767         case NTO:
8768 #if BASH_REDIR_OUTPUT
8769         case NTO2:
8770 #endif
8771         case NCLOBBER:
8772         case NFROM:
8773         case NFROMTO:
8774         case NAPPEND:
8775                 funcblocksize = calcsize(funcblocksize, n->nfile.fname);
8776                 funcblocksize = calcsize(funcblocksize, n->nfile.next);
8777                 break;
8778         case NTOFD:
8779         case NFROMFD:
8780                 funcblocksize = calcsize(funcblocksize, n->ndup.vname);
8781                 funcblocksize = calcsize(funcblocksize, n->ndup.next);
8782         break;
8783         case NHERE:
8784         case NXHERE:
8785                 funcblocksize = calcsize(funcblocksize, n->nhere.doc);
8786                 funcblocksize = calcsize(funcblocksize, n->nhere.next);
8787                 break;
8788         case NNOT:
8789                 funcblocksize = calcsize(funcblocksize, n->nnot.com);
8790                 break;
8791         };
8792         return funcblocksize;
8793 }
8794
8795 static char *
8796 nodeckstrdup(char *s)
8797 {
8798         funcstring_end -= SHELL_ALIGN(strlen(s) + 1);
8799         return strcpy(funcstring_end, s);
8800 }
8801
8802 static union node *copynode(union node *);
8803
8804 static struct nodelist *
8805 copynodelist(struct nodelist *lp)
8806 {
8807         struct nodelist *start;
8808         struct nodelist **lpp;
8809
8810         lpp = &start;
8811         while (lp) {
8812                 *lpp = funcblock;
8813                 funcblock = (char *) funcblock + SHELL_ALIGN(sizeof(struct nodelist));
8814                 (*lpp)->n = copynode(lp->n);
8815                 lp = lp->next;
8816                 lpp = &(*lpp)->next;
8817         }
8818         *lpp = NULL;
8819         return start;
8820 }
8821
8822 static union node *
8823 copynode(union node *n)
8824 {
8825         union node *new;
8826
8827         if (n == NULL)
8828                 return NULL;
8829         new = funcblock;
8830         funcblock = (char *) funcblock + nodesize[n->type];
8831
8832         switch (n->type) {
8833         case NCMD:
8834                 new->ncmd.redirect = copynode(n->ncmd.redirect);
8835                 new->ncmd.args = copynode(n->ncmd.args);
8836                 new->ncmd.assign = copynode(n->ncmd.assign);
8837                 new->ncmd.linno = n->ncmd.linno;
8838                 break;
8839         case NPIPE:
8840                 new->npipe.cmdlist = copynodelist(n->npipe.cmdlist);
8841                 new->npipe.pipe_backgnd = n->npipe.pipe_backgnd;
8842                 break;
8843         case NREDIR:
8844         case NBACKGND:
8845         case NSUBSHELL:
8846                 new->nredir.redirect = copynode(n->nredir.redirect);
8847                 new->nredir.n = copynode(n->nredir.n);
8848                 new->nredir.linno = n->nredir.linno;
8849                 break;
8850         case NAND:
8851         case NOR:
8852         case NSEMI:
8853         case NWHILE:
8854         case NUNTIL:
8855                 new->nbinary.ch2 = copynode(n->nbinary.ch2);
8856                 new->nbinary.ch1 = copynode(n->nbinary.ch1);
8857                 break;
8858         case NIF:
8859                 new->nif.elsepart = copynode(n->nif.elsepart);
8860                 new->nif.ifpart = copynode(n->nif.ifpart);
8861                 new->nif.test = copynode(n->nif.test);
8862                 break;
8863         case NFOR:
8864                 new->nfor.var = nodeckstrdup(n->nfor.var);
8865                 new->nfor.body = copynode(n->nfor.body);
8866                 new->nfor.args = copynode(n->nfor.args);
8867                 new->nfor.linno = n->nfor.linno;
8868                 break;
8869         case NCASE:
8870                 new->ncase.cases = copynode(n->ncase.cases);
8871                 new->ncase.expr = copynode(n->ncase.expr);
8872                 new->ncase.linno = n->ncase.linno;
8873                 break;
8874         case NCLIST:
8875                 new->nclist.body = copynode(n->nclist.body);
8876                 new->nclist.pattern = copynode(n->nclist.pattern);
8877                 new->nclist.next = copynode(n->nclist.next);
8878                 break;
8879         case NDEFUN:
8880                 new->ndefun.body = copynode(n->ndefun.body);
8881                 new->ndefun.text = nodeckstrdup(n->ndefun.text);
8882                 new->ndefun.linno = n->ndefun.linno;
8883                 break;
8884         case NARG:
8885                 new->narg.backquote = copynodelist(n->narg.backquote);
8886                 new->narg.text = nodeckstrdup(n->narg.text);
8887                 new->narg.next = copynode(n->narg.next);
8888                 break;
8889         case NTO:
8890 #if BASH_REDIR_OUTPUT
8891         case NTO2:
8892 #endif
8893         case NCLOBBER:
8894         case NFROM:
8895         case NFROMTO:
8896         case NAPPEND:
8897                 new->nfile.fname = copynode(n->nfile.fname);
8898                 new->nfile.fd = n->nfile.fd;
8899                 new->nfile.next = copynode(n->nfile.next);
8900                 break;
8901         case NTOFD:
8902         case NFROMFD:
8903                 new->ndup.vname = copynode(n->ndup.vname);
8904                 new->ndup.dupfd = n->ndup.dupfd;
8905                 new->ndup.fd = n->ndup.fd;
8906                 new->ndup.next = copynode(n->ndup.next);
8907                 break;
8908         case NHERE:
8909         case NXHERE:
8910                 new->nhere.doc = copynode(n->nhere.doc);
8911                 new->nhere.fd = n->nhere.fd;
8912                 new->nhere.next = copynode(n->nhere.next);
8913                 break;
8914         case NNOT:
8915                 new->nnot.com = copynode(n->nnot.com);
8916                 break;
8917         };
8918         new->type = n->type;
8919         return new;
8920 }
8921
8922 /*
8923  * Make a copy of a parse tree.
8924  */
8925 static struct funcnode *
8926 copyfunc(union node *n)
8927 {
8928         struct funcnode *f;
8929         size_t blocksize;
8930
8931         /*funcstringsize = 0;*/
8932         blocksize = offsetof(struct funcnode, n) + calcsize(0, n);
8933         f = ckzalloc(blocksize /* + funcstringsize */);
8934         funcblock = (char *) f + offsetof(struct funcnode, n);
8935         funcstring_end = (char *) f + blocksize;
8936         copynode(n);
8937         /* f->count = 0; - ckzalloc did it */
8938         return f;
8939 }
8940
8941 /*
8942  * Define a shell function.
8943  */
8944 static void
8945 defun(union node *func)
8946 {
8947         struct cmdentry entry;
8948
8949         INT_OFF;
8950         entry.cmdtype = CMDFUNCTION;
8951         entry.u.func = copyfunc(func);
8952         addcmdentry(func->ndefun.text, &entry);
8953         INT_ON;
8954 }
8955
8956 /* Reasons for skipping commands (see comment on breakcmd routine) */
8957 #define SKIPBREAK      (1 << 0)
8958 #define SKIPCONT       (1 << 1)
8959 #define SKIPFUNC       (1 << 2)
8960 static smallint evalskip;       /* set to SKIPxxx if we are skipping commands */
8961 static int skipcount;           /* number of levels to skip */
8962 static int loopnest;            /* current loop nesting level */
8963 static int funcline;            /* starting line number of current function, or 0 if not in a function */
8964
8965 /* Forward decl way out to parsing code - dotrap needs it */
8966 static int evalstring(char *s, int flags);
8967
8968 /* Called to execute a trap.
8969  * Single callsite - at the end of evaltree().
8970  * If we return non-zero, evaltree raises EXEXIT exception.
8971  *
8972  * Perhaps we should avoid entering new trap handlers
8973  * while we are executing a trap handler. [is it a TODO?]
8974  */
8975 static void
8976 dotrap(void)
8977 {
8978         uint8_t *g;
8979         int sig;
8980         uint8_t last_status;
8981
8982         if (!pending_sig)
8983                 return;
8984
8985         last_status = exitstatus;
8986         pending_sig = 0;
8987         barrier();
8988
8989         TRACE(("dotrap entered\n"));
8990         for (sig = 1, g = gotsig; sig < NSIG; sig++, g++) {
8991                 char *p;
8992
8993                 if (!*g)
8994                         continue;
8995
8996                 if (evalskip) {
8997                         pending_sig = sig;
8998                         break;
8999                 }
9000
9001                 p = trap[sig];
9002                 /* non-trapped SIGINT is handled separately by raise_interrupt,
9003                  * don't upset it by resetting gotsig[SIGINT-1] */
9004                 if (sig == SIGINT && !p)
9005                         continue;
9006
9007                 TRACE(("sig %d is active, will run handler '%s'\n", sig, p));
9008                 *g = 0;
9009                 if (!p)
9010                         continue;
9011                 evalstring(p, 0);
9012         }
9013         exitstatus = last_status;
9014         TRACE(("dotrap returns\n"));
9015 }
9016
9017 /* forward declarations - evaluation is fairly recursive business... */
9018 static int evalloop(union node *, int);
9019 static int evalfor(union node *, int);
9020 static int evalcase(union node *, int);
9021 static int evalsubshell(union node *, int);
9022 static void expredir(union node *);
9023 static int evalpipe(union node *, int);
9024 static int evalcommand(union node *, int);
9025 static int evalbltin(const struct builtincmd *, int, char **, int);
9026 static void prehash(union node *);
9027
9028 /*
9029  * Evaluate a parse tree.  The value is left in the global variable
9030  * exitstatus.
9031  */
9032 static int
9033 evaltree(union node *n, int flags)
9034 {
9035         int checkexit = 0;
9036         int (*evalfn)(union node *, int);
9037         int status = 0;
9038
9039         if (n == NULL) {
9040                 TRACE(("evaltree(NULL) called\n"));
9041                 goto out;
9042         }
9043         TRACE(("evaltree(%p: %d, %d) called\n", n, n->type, flags));
9044
9045         dotrap();
9046
9047         switch (n->type) {
9048         default:
9049 #if DEBUG
9050                 out1fmt("Node type = %d\n", n->type);
9051                 fflush_all();
9052                 break;
9053 #endif
9054         case NNOT:
9055                 status = !evaltree(n->nnot.com, EV_TESTED);
9056                 goto setstatus;
9057         case NREDIR:
9058                 errlinno = lineno = n->nredir.linno;
9059                 if (funcline)
9060                         lineno -= funcline - 1;
9061                 expredir(n->nredir.redirect);
9062                 pushredir(n->nredir.redirect);
9063                 status = redirectsafe(n->nredir.redirect, REDIR_PUSH);
9064                 if (!status) {
9065                         status = evaltree(n->nredir.n, flags & EV_TESTED);
9066                 }
9067                 if (n->nredir.redirect)
9068                         popredir(/*drop:*/ 0);
9069                 goto setstatus;
9070         case NCMD:
9071                 evalfn = evalcommand;
9072  checkexit:
9073                 if (eflag && !(flags & EV_TESTED))
9074                         checkexit = ~0;
9075                 goto calleval;
9076         case NFOR:
9077                 evalfn = evalfor;
9078                 goto calleval;
9079         case NWHILE:
9080         case NUNTIL:
9081                 evalfn = evalloop;
9082                 goto calleval;
9083         case NSUBSHELL:
9084         case NBACKGND:
9085                 evalfn = evalsubshell;
9086                 goto checkexit;
9087         case NPIPE:
9088                 evalfn = evalpipe;
9089                 goto checkexit;
9090         case NCASE:
9091                 evalfn = evalcase;
9092                 goto calleval;
9093         case NAND:
9094         case NOR:
9095         case NSEMI: {
9096
9097 #if NAND + 1 != NOR
9098 #error NAND + 1 != NOR
9099 #endif
9100 #if NOR + 1 != NSEMI
9101 #error NOR + 1 != NSEMI
9102 #endif
9103                 unsigned is_or = n->type - NAND;
9104                 status = evaltree(
9105                         n->nbinary.ch1,
9106                         (flags | ((is_or >> 1) - 1)) & EV_TESTED
9107                 );
9108                 if ((!status) == is_or || evalskip)
9109                         break;
9110                 n = n->nbinary.ch2;
9111  evaln:
9112                 evalfn = evaltree;
9113  calleval:
9114                 status = evalfn(n, flags);
9115                 goto setstatus;
9116         }
9117         case NIF:
9118                 status = evaltree(n->nif.test, EV_TESTED);
9119                 if (evalskip)
9120                         break;
9121                 if (!status) {
9122                         n = n->nif.ifpart;
9123                         goto evaln;
9124                 }
9125                 if (n->nif.elsepart) {
9126                         n = n->nif.elsepart;
9127                         goto evaln;
9128                 }
9129                 status = 0;
9130                 goto setstatus;
9131         case NDEFUN:
9132                 defun(n);
9133                 /* Not necessary. To test it:
9134                  * "false; f() { qwerty; }; echo $?" should print 0.
9135                  */
9136                 /* status = 0; */
9137  setstatus:
9138                 exitstatus = status;
9139                 break;
9140         }
9141  out:
9142         /* Order of checks below is important:
9143          * signal handlers trigger before exit caused by "set -e".
9144          */
9145         dotrap();
9146
9147         if (checkexit & status)
9148                 raise_exception(EXEXIT);
9149         if (flags & EV_EXIT)
9150                 raise_exception(EXEXIT);
9151
9152         TRACE(("leaving evaltree (no interrupts)\n"));
9153         return exitstatus;
9154 }
9155
9156 static int
9157 skiploop(void)
9158 {
9159         int skip = evalskip;
9160
9161         switch (skip) {
9162         case 0:
9163                 break;
9164         case SKIPBREAK:
9165         case SKIPCONT:
9166                 if (--skipcount <= 0) {
9167                         evalskip = 0;
9168                         break;
9169                 }
9170                 skip = SKIPBREAK;
9171                 break;
9172         }
9173         return skip;
9174 }
9175
9176 static int
9177 evalloop(union node *n, int flags)
9178 {
9179         int skip;
9180         int status;
9181
9182         loopnest++;
9183         status = 0;
9184         flags &= EV_TESTED;
9185         do {
9186                 int i;
9187
9188                 i = evaltree(n->nbinary.ch1, EV_TESTED);
9189                 skip = skiploop();
9190                 if (skip == SKIPFUNC)
9191                         status = i;
9192                 if (skip)
9193                         continue;
9194                 if (n->type != NWHILE)
9195                         i = !i;
9196                 if (i != 0)
9197                         break;
9198                 status = evaltree(n->nbinary.ch2, flags);
9199                 skip = skiploop();
9200         } while (!(skip & ~SKIPCONT));
9201         loopnest--;
9202
9203         return status;
9204 }
9205
9206 static int
9207 evalfor(union node *n, int flags)
9208 {
9209         struct arglist arglist;
9210         union node *argp;
9211         struct strlist *sp;
9212         struct stackmark smark;
9213         int status = 0;
9214
9215         errlinno = lineno = n->ncase.linno;
9216         if (funcline)
9217                 lineno -= funcline - 1;
9218
9219         setstackmark(&smark);
9220         arglist.list = NULL;
9221         arglist.lastp = &arglist.list;
9222         for (argp = n->nfor.args; argp; argp = argp->narg.next) {
9223                 expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
9224         }
9225         *arglist.lastp = NULL;
9226
9227         loopnest++;
9228         flags &= EV_TESTED;
9229         for (sp = arglist.list; sp; sp = sp->next) {
9230                 setvar0(n->nfor.var, sp->text);
9231                 status = evaltree(n->nfor.body, flags);
9232                 if (skiploop() & ~SKIPCONT)
9233                         break;
9234         }
9235         loopnest--;
9236         popstackmark(&smark);
9237
9238         return status;
9239 }
9240
9241 static int
9242 evalcase(union node *n, int flags)
9243 {
9244         union node *cp;
9245         union node *patp;
9246         struct arglist arglist;
9247         struct stackmark smark;
9248         int status = 0;
9249
9250         errlinno = lineno = n->ncase.linno;
9251         if (funcline)
9252                 lineno -= funcline - 1;
9253
9254         setstackmark(&smark);
9255         arglist.list = NULL;
9256         arglist.lastp = &arglist.list;
9257         expandarg(n->ncase.expr, &arglist, EXP_TILDE);
9258         for (cp = n->ncase.cases; cp && evalskip == 0; cp = cp->nclist.next) {
9259                 for (patp = cp->nclist.pattern; patp; patp = patp->narg.next) {
9260                         if (casematch(patp, arglist.list->text)) {
9261                                 /* Ensure body is non-empty as otherwise
9262                                  * EV_EXIT may prevent us from setting the
9263                                  * exit status.
9264                                  */
9265                                 if (evalskip == 0 && cp->nclist.body) {
9266                                         status = evaltree(cp->nclist.body, flags);
9267                                 }
9268                                 goto out;
9269                         }
9270                 }
9271         }
9272  out:
9273         popstackmark(&smark);
9274
9275         return status;
9276 }
9277
9278 /*
9279  * Kick off a subshell to evaluate a tree.
9280  */
9281 static int
9282 evalsubshell(union node *n, int flags)
9283 {
9284         struct job *jp;
9285         int backgnd = (n->type == NBACKGND); /* FORK_BG(1) if yes, else FORK_FG(0) */
9286         int status;
9287
9288         errlinno = lineno = n->nredir.linno;
9289         if (funcline)
9290                 lineno -= funcline - 1;
9291
9292         expredir(n->nredir.redirect);
9293         if (!backgnd && (flags & EV_EXIT) && !may_have_traps)
9294                 goto nofork;
9295         INT_OFF;
9296         if (backgnd == FORK_FG)
9297                 get_tty_state();
9298         jp = makejob(/*n,*/ 1);
9299         if (forkshell(jp, n, backgnd) == 0) {
9300                 /* child */
9301                 INT_ON;
9302                 flags |= EV_EXIT;
9303                 if (backgnd)
9304                         flags &= ~EV_TESTED;
9305  nofork:
9306                 redirect(n->nredir.redirect, 0);
9307                 evaltreenr(n->nredir.n, flags);
9308                 /* never returns */
9309         }
9310         /* parent */
9311         status = 0;
9312         if (backgnd == FORK_FG)
9313                 status = waitforjob(jp);
9314         INT_ON;
9315         return status;
9316 }
9317
9318 /*
9319  * Compute the names of the files in a redirection list.
9320  */
9321 static void fixredir(union node *, const char *, int);
9322 static void
9323 expredir(union node *n)
9324 {
9325         union node *redir;
9326
9327         for (redir = n; redir; redir = redir->nfile.next) {
9328                 struct arglist fn;
9329
9330                 fn.list = NULL;
9331                 fn.lastp = &fn.list;
9332                 switch (redir->type) {
9333                 case NFROMTO:
9334                 case NFROM:
9335                 case NTO:
9336 #if BASH_REDIR_OUTPUT
9337                 case NTO2:
9338 #endif
9339                 case NCLOBBER:
9340                 case NAPPEND:
9341                         expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR);
9342                         TRACE(("expredir expanded to '%s'\n", fn.list->text));
9343 #if BASH_REDIR_OUTPUT
9344  store_expfname:
9345 #endif
9346 #if 0
9347 // By the design of stack allocator, the loop of this kind:
9348 //      while true; do while true; do break; done </dev/null; done
9349 // will look like a memory leak: ash plans to free expfname's
9350 // of "/dev/null" as soon as it finishes running the loop
9351 // (in this case, never).
9352 // This "fix" is wrong:
9353                         if (redir->nfile.expfname)
9354                                 stunalloc(redir->nfile.expfname);
9355 // It results in corrupted state of stacked allocations.
9356 #endif
9357                         redir->nfile.expfname = fn.list->text;
9358                         break;
9359                 case NFROMFD:
9360                 case NTOFD: /* >& */
9361                         if (redir->ndup.vname) {
9362                                 expandarg(redir->ndup.vname, &fn, EXP_FULL | EXP_TILDE);
9363                                 if (fn.list == NULL)
9364                                         ash_msg_and_raise_error("redir error");
9365 #if BASH_REDIR_OUTPUT
9366 //FIXME: we used expandarg with different args!
9367                                 if (!isdigit_str9(fn.list->text)) {
9368                                         /* >&file, not >&fd */
9369                                         if (redir->nfile.fd != 1) /* 123>&file - BAD */
9370                                                 ash_msg_and_raise_error("redir error");
9371                                         redir->type = NTO2;
9372                                         goto store_expfname;
9373                                 }
9374 #endif
9375                                 fixredir(redir, fn.list->text, 1);
9376                         }
9377                         break;
9378                 }
9379         }
9380 }
9381
9382 /*
9383  * Evaluate a pipeline.  All the processes in the pipeline are children
9384  * of the process creating the pipeline.  (This differs from some versions
9385  * of the shell, which make the last process in a pipeline the parent
9386  * of all the rest.)
9387  */
9388 static int
9389 evalpipe(union node *n, int flags)
9390 {
9391         struct job *jp;
9392         struct nodelist *lp;
9393         int pipelen;
9394         int prevfd;
9395         int pip[2];
9396         int status = 0;
9397
9398         TRACE(("evalpipe(0x%lx) called\n", (long)n));
9399         pipelen = 0;
9400         for (lp = n->npipe.cmdlist; lp; lp = lp->next)
9401                 pipelen++;
9402         flags |= EV_EXIT;
9403         INT_OFF;
9404         if (n->npipe.pipe_backgnd == 0)
9405                 get_tty_state();
9406         jp = makejob(/*n,*/ pipelen);
9407         prevfd = -1;
9408         for (lp = n->npipe.cmdlist; lp; lp = lp->next) {
9409                 prehash(lp->n);
9410                 pip[1] = -1;
9411                 if (lp->next) {
9412                         if (pipe(pip) < 0) {
9413                                 close(prevfd);
9414                                 ash_msg_and_raise_perror("can't create pipe");
9415                         }
9416                 }
9417                 if (forkshell(jp, lp->n, n->npipe.pipe_backgnd) == 0) {
9418                         /* child */
9419                         INT_ON;
9420                         if (pip[1] >= 0) {
9421                                 close(pip[0]);
9422                         }
9423                         if (prevfd > 0) {
9424                                 dup2(prevfd, 0);
9425                                 close(prevfd);
9426                         }
9427                         if (pip[1] > 1) {
9428                                 dup2(pip[1], 1);
9429                                 close(pip[1]);
9430                         }
9431                         evaltreenr(lp->n, flags);
9432                         /* never returns */
9433                 }
9434                 /* parent */
9435                 if (prevfd >= 0)
9436                         close(prevfd);
9437                 prevfd = pip[0];
9438                 /* Don't want to trigger debugging */
9439                 if (pip[1] != -1)
9440                         close(pip[1]);
9441         }
9442         if (n->npipe.pipe_backgnd == 0) {
9443                 status = waitforjob(jp);
9444                 TRACE(("evalpipe:  job done exit status %d\n", status));
9445         }
9446         INT_ON;
9447
9448         return status;
9449 }
9450
9451 /*
9452  * Controls whether the shell is interactive or not.
9453  */
9454 static void
9455 setinteractive(int on)
9456 {
9457         static smallint is_interactive;
9458
9459         if (++on == is_interactive)
9460                 return;
9461         is_interactive = on;
9462         setsignal(SIGINT);
9463         setsignal(SIGQUIT);
9464         setsignal(SIGTERM);
9465 #if !ENABLE_FEATURE_SH_EXTRA_QUIET
9466         if (is_interactive > 1) {
9467                 /* Looks like they want an interactive shell */
9468                 static smallint did_banner;
9469
9470                 if (!did_banner) {
9471                         /* note: ash and hush share this string */
9472                         out1fmt("\n\n%s %s\n"
9473                                 IF_ASH_HELP("Enter 'help' for a list of built-in commands.\n")
9474                                 "\n",
9475                                 bb_banner,
9476                                 "built-in shell (ash)"
9477                         );
9478                         did_banner = 1;
9479                 }
9480         }
9481 #endif
9482 }
9483
9484 static void
9485 optschanged(void)
9486 {
9487 #if DEBUG
9488         opentrace();
9489 #endif
9490         setinteractive(iflag);
9491         setjobctl(mflag);
9492 #if ENABLE_FEATURE_EDITING_VI
9493         if (viflag)
9494                 line_input_state->flags |= VI_MODE;
9495         else
9496                 line_input_state->flags &= ~VI_MODE;
9497 #else
9498         viflag = 0; /* forcibly keep the option off */
9499 #endif
9500 }
9501
9502 struct localvar_list {
9503         struct localvar_list *next;
9504         struct localvar *lv;
9505 };
9506
9507 static struct localvar_list *localvar_stack;
9508
9509 /*
9510  * Called after a function returns.
9511  * Interrupts must be off.
9512  */
9513 static void
9514 poplocalvars(int keep)
9515 {
9516         struct localvar_list *ll;
9517         struct localvar *lvp, *next;
9518         struct var *vp;
9519
9520         INT_OFF;
9521         ll = localvar_stack;
9522         localvar_stack = ll->next;
9523
9524         next = ll->lv;
9525         free(ll);
9526
9527         while ((lvp = next) != NULL) {
9528                 next = lvp->next;
9529                 vp = lvp->vp;
9530                 TRACE(("poplocalvar %s\n", vp ? vp->var_text : "-"));
9531                 if (keep) {
9532                         int bits = VSTRFIXED;
9533
9534                         if (lvp->flags != VUNSET) {
9535                                 if (vp->var_text == lvp->text)
9536                                         bits |= VTEXTFIXED;
9537                                 else if (!(lvp->flags & (VTEXTFIXED|VSTACK)))
9538                                         free((char*)lvp->text);
9539                         }
9540
9541                         vp->flags &= ~bits;
9542                         vp->flags |= (lvp->flags & bits);
9543
9544                         if ((vp->flags &
9545                              (VEXPORT|VREADONLY|VSTRFIXED|VUNSET)) == VUNSET)
9546                                 unsetvar(vp->var_text);
9547                 } else if (vp == NULL) {        /* $- saved */
9548                         memcpy(optlist, lvp->text, sizeof(optlist));
9549                         free((char*)lvp->text);
9550                         optschanged();
9551                 } else if (lvp->flags == VUNSET) {
9552                         vp->flags &= ~(VSTRFIXED|VREADONLY);
9553                         unsetvar(vp->var_text);
9554                 } else {
9555                         if (vp->var_func)
9556                                 vp->var_func(var_end(lvp->text));
9557                         if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0)
9558                                 free((char*)vp->var_text);
9559                         vp->flags = lvp->flags;
9560                         vp->var_text = lvp->text;
9561                 }
9562                 free(lvp);
9563         }
9564         INT_ON;
9565 }
9566
9567 /*
9568  * Create a new localvar environment.
9569  */
9570 static struct localvar_list *
9571 pushlocalvars(void)
9572 {
9573         struct localvar_list *ll;
9574
9575         INT_OFF;
9576         ll = ckzalloc(sizeof(*ll));
9577         /*ll->lv = NULL; - zalloc did it */
9578         ll->next = localvar_stack;
9579         localvar_stack = ll;
9580         INT_ON;
9581
9582         return ll->next;
9583 }
9584
9585 static void
9586 unwindlocalvars(struct localvar_list *stop)
9587 {
9588         while (localvar_stack != stop)
9589                 poplocalvars(0);
9590 }
9591
9592 static int
9593 evalfun(struct funcnode *func, int argc, char **argv, int flags)
9594 {
9595         volatile struct shparam saveparam;
9596         struct jmploc *volatile savehandler;
9597         struct jmploc jmploc;
9598         int e;
9599         int savefuncline;
9600
9601         saveparam = shellparam;
9602         savefuncline = funcline;
9603         savehandler = exception_handler;
9604         e = setjmp(jmploc.loc);
9605         if (e) {
9606                 goto funcdone;
9607         }
9608         INT_OFF;
9609         exception_handler = &jmploc;
9610         shellparam.malloced = 0;
9611         func->count++;
9612         funcline = func->n.ndefun.linno;
9613         INT_ON;
9614         shellparam.nparam = argc - 1;
9615         shellparam.p = argv + 1;
9616 #if ENABLE_ASH_GETOPTS
9617         shellparam.optind = 1;
9618         shellparam.optoff = -1;
9619 #endif
9620         evaltree(func->n.ndefun.body, flags & EV_TESTED);
9621  funcdone:
9622         INT_OFF;
9623         funcline = savefuncline;
9624         freefunc(func);
9625         freeparam(&shellparam);
9626         shellparam = saveparam;
9627         exception_handler = savehandler;
9628         INT_ON;
9629         evalskip &= ~SKIPFUNC;
9630         return e;
9631 }
9632
9633 /*
9634  * Make a variable a local variable.  When a variable is made local, it's
9635  * value and flags are saved in a localvar structure.  The saved values
9636  * will be restored when the shell function returns.  We handle the name
9637  * "-" as a special case: it makes changes to "set +-options" local
9638  * (options will be restored on return from the function).
9639  */
9640 static void
9641 mklocal(char *name)
9642 {
9643         struct localvar *lvp;
9644         struct var **vpp;
9645         struct var *vp;
9646         char *eq = strchr(name, '=');
9647
9648         INT_OFF;
9649         /* Cater for duplicate "local". Examples:
9650          * x=0; f() { local x=1; echo $x; local x; echo $x; }; f; echo $x
9651          * x=0; f() { local x=1; echo $x; local x=2; echo $x; }; f; echo $x
9652          */
9653         lvp = localvar_stack->lv;
9654         while (lvp) {
9655                 if (lvp->vp && varcmp(lvp->vp->var_text, name) == 0) {
9656                         if (eq)
9657                                 setvareq(name, 0);
9658                         /* else:
9659                          * it's a duplicate "local VAR" declaration, do nothing
9660                          */
9661                         goto ret;
9662                 }
9663                 lvp = lvp->next;
9664         }
9665
9666         lvp = ckzalloc(sizeof(*lvp));
9667         if (LONE_DASH(name)) {
9668                 char *p;
9669                 p = ckmalloc(sizeof(optlist));
9670                 lvp->text = memcpy(p, optlist, sizeof(optlist));
9671                 vp = NULL;
9672         } else {
9673                 vpp = hashvar(name);
9674                 vp = *findvar(vpp, name);
9675                 if (vp == NULL) {
9676                         /* variable did not exist yet */
9677                         if (eq)
9678                                 vp = setvareq(name, VSTRFIXED);
9679                         else
9680                                 vp = setvar(name, NULL, VSTRFIXED);
9681                         lvp->flags = VUNSET;
9682                 } else {
9683                         lvp->text = vp->var_text;
9684                         lvp->flags = vp->flags;
9685                         /* make sure neither "struct var" nor string gets freed
9686                          * during (un)setting:
9687                          */
9688                         vp->flags |= VSTRFIXED|VTEXTFIXED;
9689                         if (eq)
9690                                 setvareq(name, 0);
9691                         else
9692                                 /* "local VAR" unsets VAR: */
9693                                 setvar0(name, NULL);
9694                 }
9695         }
9696         lvp->vp = vp;
9697         lvp->next = localvar_stack->lv;
9698         localvar_stack->lv = lvp;
9699  ret:
9700         INT_ON;
9701 }
9702
9703 /*
9704  * The "local" command.
9705  */
9706 static int FAST_FUNC
9707 localcmd(int argc UNUSED_PARAM, char **argv)
9708 {
9709         char *name;
9710
9711         if (!localvar_stack)
9712                 ash_msg_and_raise_error("not in a function");
9713
9714         argv = argptr;
9715         while ((name = *argv++) != NULL) {
9716                 mklocal(name);
9717         }
9718         return 0;
9719 }
9720
9721 static int FAST_FUNC
9722 falsecmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
9723 {
9724         return 1;
9725 }
9726
9727 static int FAST_FUNC
9728 truecmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
9729 {
9730         return 0;
9731 }
9732
9733 static int FAST_FUNC
9734 execcmd(int argc UNUSED_PARAM, char **argv)
9735 {
9736         optionarg = NULL;
9737         while (nextopt("a:") != '\0')
9738                 /* nextopt() sets optionarg to "-a ARGV0" */;
9739
9740         argv = argptr;
9741         if (argv[0]) {
9742                 char *prog;
9743
9744                 iflag = 0;              /* exit on error */
9745                 mflag = 0;
9746                 optschanged();
9747                 /* We should set up signals for "exec CMD"
9748                  * the same way as for "CMD" without "exec".
9749                  * But optschanged->setinteractive->setsignal
9750                  * still thought we are a root shell. Therefore, for example,
9751                  * SIGQUIT is still set to IGN. Fix it:
9752                  */
9753                 shlvl++;
9754                 setsignal(SIGQUIT);
9755                 /*setsignal(SIGTERM); - unnecessary because of iflag=0 */
9756                 /*setsignal(SIGTSTP); - unnecessary because of mflag=0 */
9757                 /*setsignal(SIGTTOU); - unnecessary because of mflag=0 */
9758
9759                 prog = argv[0];
9760                 if (optionarg)
9761                         argv[0] = optionarg;
9762                 shellexec(prog, argv, pathval(), 0);
9763                 /* NOTREACHED */
9764         }
9765         return 0;
9766 }
9767
9768 /*
9769  * The return command.
9770  */
9771 static int FAST_FUNC
9772 returncmd(int argc UNUSED_PARAM, char **argv)
9773 {
9774         /*
9775          * If called outside a function, do what ksh does;
9776          * skip the rest of the file.
9777          */
9778         evalskip = SKIPFUNC;
9779         return argv[1] ? number(argv[1]) : exitstatus;
9780 }
9781
9782 /* Forward declarations for builtintab[] */
9783 static int breakcmd(int, char **) FAST_FUNC;
9784 static int dotcmd(int, char **) FAST_FUNC;
9785 static int evalcmd(int, char **, int) FAST_FUNC;
9786 static int exitcmd(int, char **) FAST_FUNC;
9787 static int exportcmd(int, char **) FAST_FUNC;
9788 #if ENABLE_ASH_GETOPTS
9789 static int getoptscmd(int, char **) FAST_FUNC;
9790 #endif
9791 #if ENABLE_ASH_HELP
9792 static int helpcmd(int, char **) FAST_FUNC;
9793 #endif
9794 #if MAX_HISTORY
9795 static int historycmd(int, char **) FAST_FUNC;
9796 #endif
9797 #if ENABLE_FEATURE_SH_MATH
9798 static int letcmd(int, char **) FAST_FUNC;
9799 #endif
9800 static int readcmd(int, char **) FAST_FUNC;
9801 static int setcmd(int, char **) FAST_FUNC;
9802 static int shiftcmd(int, char **) FAST_FUNC;
9803 static int timescmd(int, char **) FAST_FUNC;
9804 static int trapcmd(int, char **) FAST_FUNC;
9805 static int umaskcmd(int, char **) FAST_FUNC;
9806 static int unsetcmd(int, char **) FAST_FUNC;
9807 static int ulimitcmd(int, char **) FAST_FUNC;
9808
9809 #define BUILTIN_NOSPEC          "0"
9810 #define BUILTIN_SPECIAL         "1"
9811 #define BUILTIN_REGULAR         "2"
9812 #define BUILTIN_SPEC_REG        "3"
9813 #define BUILTIN_ASSIGN          "4"
9814 #define BUILTIN_SPEC_ASSG       "5"
9815 #define BUILTIN_REG_ASSG        "6"
9816 #define BUILTIN_SPEC_REG_ASSG   "7"
9817
9818 /* Stubs for calling non-FAST_FUNC's */
9819 #if ENABLE_ASH_ECHO
9820 static int FAST_FUNC echocmd(int argc, char **argv)   { return echo_main(argc, argv); }
9821 #endif
9822 #if ENABLE_ASH_PRINTF
9823 static int FAST_FUNC printfcmd(int argc, char **argv) { return printf_main(argc, argv); }
9824 #endif
9825 #if ENABLE_ASH_TEST || BASH_TEST2
9826 static int FAST_FUNC testcmd(int argc, char **argv)   { return test_main(argc, argv); }
9827 #endif
9828
9829 /* Keep these in proper order since it is searched via bsearch() */
9830 static const struct builtincmd builtintab[] = {
9831         { BUILTIN_SPEC_REG      "."       , dotcmd     },
9832         { BUILTIN_SPEC_REG      ":"       , truecmd    },
9833 #if ENABLE_ASH_TEST
9834         { BUILTIN_REGULAR       "["       , testcmd    },
9835 #endif
9836 #if BASH_TEST2
9837         { BUILTIN_REGULAR       "[["      , testcmd    },
9838 #endif
9839 #if ENABLE_ASH_ALIAS
9840         { BUILTIN_REG_ASSG      "alias"   , aliascmd   },
9841 #endif
9842 #if JOBS
9843         { BUILTIN_REGULAR       "bg"      , fg_bgcmd   },
9844 #endif
9845         { BUILTIN_SPEC_REG      "break"   , breakcmd   },
9846         { BUILTIN_REGULAR       "cd"      , cdcmd      },
9847         { BUILTIN_NOSPEC        "chdir"   , cdcmd      },
9848 #if ENABLE_ASH_CMDCMD
9849         { BUILTIN_REGULAR       "command" , commandcmd },
9850 #endif
9851         { BUILTIN_SPEC_REG      "continue", breakcmd   },
9852 #if ENABLE_ASH_ECHO
9853         { BUILTIN_REGULAR       "echo"    , echocmd    },
9854 #endif
9855         { BUILTIN_SPEC_REG      "eval"    , NULL       }, /*evalcmd() has a differing prototype*/
9856         { BUILTIN_SPEC_REG      "exec"    , execcmd    },
9857         { BUILTIN_SPEC_REG      "exit"    , exitcmd    },
9858         { BUILTIN_SPEC_REG_ASSG "export"  , exportcmd  },
9859         { BUILTIN_REGULAR       "false"   , falsecmd   },
9860 #if JOBS
9861         { BUILTIN_REGULAR       "fg"      , fg_bgcmd   },
9862 #endif
9863 #if ENABLE_ASH_GETOPTS
9864         { BUILTIN_REGULAR       "getopts" , getoptscmd },
9865 #endif
9866         { BUILTIN_NOSPEC        "hash"    , hashcmd    },
9867 #if ENABLE_ASH_HELP
9868         { BUILTIN_NOSPEC        "help"    , helpcmd    },
9869 #endif
9870 #if MAX_HISTORY
9871         { BUILTIN_NOSPEC        "history" , historycmd },
9872 #endif
9873 #if JOBS
9874         { BUILTIN_REGULAR       "jobs"    , jobscmd    },
9875         { BUILTIN_REGULAR       "kill"    , killcmd    },
9876 #endif
9877 #if ENABLE_FEATURE_SH_MATH
9878         { BUILTIN_NOSPEC        "let"     , letcmd     },
9879 #endif
9880         { BUILTIN_SPEC_REG_ASSG "local"   , localcmd   },
9881 #if ENABLE_ASH_PRINTF
9882         { BUILTIN_REGULAR       "printf"  , printfcmd  },
9883 #endif
9884         { BUILTIN_NOSPEC        "pwd"     , pwdcmd     },
9885         { BUILTIN_REGULAR       "read"    , readcmd    },
9886         { BUILTIN_SPEC_REG_ASSG "readonly", exportcmd  },
9887         { BUILTIN_SPEC_REG      "return"  , returncmd  },
9888         { BUILTIN_SPEC_REG      "set"     , setcmd     },
9889         { BUILTIN_SPEC_REG      "shift"   , shiftcmd   },
9890 #if BASH_SOURCE
9891         { BUILTIN_SPEC_REG      "source"  , dotcmd     },
9892 #endif
9893 #if ENABLE_ASH_TEST
9894         { BUILTIN_REGULAR       "test"    , testcmd    },
9895 #endif
9896         { BUILTIN_SPEC_REG      "times"   , timescmd   },
9897         { BUILTIN_SPEC_REG      "trap"    , trapcmd    },
9898         { BUILTIN_REGULAR       "true"    , truecmd    },
9899         { BUILTIN_NOSPEC        "type"    , typecmd    },
9900         { BUILTIN_NOSPEC        "ulimit"  , ulimitcmd  },
9901         { BUILTIN_REGULAR       "umask"   , umaskcmd   },
9902 #if ENABLE_ASH_ALIAS
9903         { BUILTIN_REGULAR       "unalias" , unaliascmd },
9904 #endif
9905         { BUILTIN_SPEC_REG      "unset"   , unsetcmd   },
9906         { BUILTIN_REGULAR       "wait"    , waitcmd    },
9907 };
9908
9909 /* Should match the above table! */
9910 #define COMMANDCMD (builtintab + \
9911         /* . : */       2 + \
9912         /* [ */         1 * ENABLE_ASH_TEST + \
9913         /* [[ */        1 * BASH_TEST2 + \
9914         /* alias */     1 * ENABLE_ASH_ALIAS + \
9915         /* bg */        1 * ENABLE_ASH_JOB_CONTROL + \
9916         /* break cd cddir  */   3)
9917 #define EVALCMD (COMMANDCMD + \
9918         /* command */   1 * ENABLE_ASH_CMDCMD + \
9919         /* continue */  1 + \
9920         /* echo */      1 * ENABLE_ASH_ECHO + \
9921         0)
9922 #define EXECCMD (EVALCMD + \
9923         /* eval */      1)
9924
9925 /*
9926  * Search the table of builtin commands.
9927  */
9928 static int
9929 pstrcmp1(const void *a, const void *b)
9930 {
9931         return strcmp((char*)a, *(char**)b + 1);
9932 }
9933 static struct builtincmd *
9934 find_builtin(const char *name)
9935 {
9936         struct builtincmd *bp;
9937
9938         bp = bsearch(
9939                 name, builtintab, ARRAY_SIZE(builtintab), sizeof(builtintab[0]),
9940                 pstrcmp1
9941         );
9942         return bp;
9943 }
9944
9945 /*
9946  * Execute a simple command.
9947  */
9948 static void unwindfiles(struct parsefile *stop);
9949 static int
9950 isassignment(const char *p)
9951 {
9952         const char *q = endofname(p);
9953         if (p == q)
9954                 return 0;
9955         return *q == '=';
9956 }
9957 static int FAST_FUNC
9958 bltincmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
9959 {
9960         /* Preserve exitstatus of a previous possible redirection
9961          * as POSIX mandates */
9962         return back_exitstatus;
9963 }
9964 static int
9965 evalcommand(union node *cmd, int flags)
9966 {
9967         static const struct builtincmd null_bltin = {
9968                 "\0\0", bltincmd /* why three NULs? */
9969         };
9970         struct localvar_list *localvar_stop;
9971         struct parsefile *file_stop;
9972         struct redirtab *redir_stop;
9973         struct stackmark smark;
9974         union node *argp;
9975         struct arglist arglist;
9976         struct arglist varlist;
9977         char **argv;
9978         int argc;
9979         const struct strlist *sp;
9980         struct cmdentry cmdentry;
9981         struct job *jp;
9982         char *lastarg;
9983         const char *path;
9984         int spclbltin;
9985         int status;
9986         char **nargv;
9987         smallint cmd_is_exec;
9988
9989         errlinno = lineno = cmd->ncmd.linno;
9990         if (funcline)
9991                 lineno -= funcline - 1;
9992
9993         /* First expand the arguments. */
9994         TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags));
9995         setstackmark(&smark);
9996         localvar_stop = pushlocalvars();
9997         file_stop = g_parsefile;
9998         back_exitstatus = 0;
9999
10000         cmdentry.cmdtype = CMDBUILTIN;
10001         cmdentry.u.cmd = &null_bltin;
10002         varlist.lastp = &varlist.list;
10003         *varlist.lastp = NULL;
10004         arglist.lastp = &arglist.list;
10005         *arglist.lastp = NULL;
10006
10007         argc = 0;
10008         if (cmd->ncmd.args) {
10009                 struct builtincmd *bcmd;
10010                 smallint pseudovarflag;
10011
10012                 bcmd = find_builtin(cmd->ncmd.args->narg.text);
10013                 pseudovarflag = bcmd && IS_BUILTIN_ASSIGN(bcmd);
10014
10015                 for (argp = cmd->ncmd.args; argp; argp = argp->narg.next) {
10016                         struct strlist **spp;
10017
10018                         spp = arglist.lastp;
10019                         if (pseudovarflag && isassignment(argp->narg.text))
10020                                 expandarg(argp, &arglist, EXP_VARTILDE);
10021                         else
10022                                 expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
10023
10024                         for (sp = *spp; sp; sp = sp->next)
10025                                 argc++;
10026                 }
10027         }
10028
10029         /* Reserve one extra spot at the front for shellexec. */
10030         nargv = stalloc(sizeof(char *) * (argc + 2));
10031         argv = ++nargv;
10032         for (sp = arglist.list; sp; sp = sp->next) {
10033                 TRACE(("evalcommand arg: %s\n", sp->text));
10034                 *nargv++ = sp->text;
10035         }
10036         *nargv = NULL;
10037
10038         lastarg = NULL;
10039         if (iflag && funcline == 0 && argc > 0)
10040                 lastarg = nargv[-1];
10041
10042         expredir(cmd->ncmd.redirect);
10043         redir_stop = pushredir(cmd->ncmd.redirect);
10044         preverrout_fd = 2;
10045         if (BASH_XTRACEFD && xflag) {
10046                 /* NB: bash closes fd == $BASH_XTRACEFD when it is changed.
10047                  * we do not emulate this. We only use its value.
10048                  */
10049                 const char *xtracefd = lookupvar("BASH_XTRACEFD");
10050                 if (xtracefd && is_number(xtracefd))
10051                         preverrout_fd = atoi(xtracefd);
10052
10053         }
10054         status = redirectsafe(cmd->ncmd.redirect, REDIR_PUSH | REDIR_SAVEFD2);
10055
10056         path = vpath.var_text;
10057         for (argp = cmd->ncmd.assign; argp; argp = argp->narg.next) {
10058                 struct strlist **spp;
10059                 char *p;
10060
10061                 spp = varlist.lastp;
10062                 expandarg(argp, &varlist, EXP_VARTILDE);
10063
10064                 mklocal((*spp)->text);
10065
10066                 /*
10067                  * Modify the command lookup path, if a PATH= assignment
10068                  * is present
10069                  */
10070                 p = (*spp)->text;
10071                 if (varcmp(p, path) == 0)
10072                         path = p;
10073         }
10074
10075         /* Print the command if xflag is set. */
10076         if (xflag) {
10077                 const char *pfx = "";
10078
10079                 fdprintf(preverrout_fd, "%s", expandstr(ps4val(), DQSYNTAX));
10080
10081                 sp = varlist.list;
10082                 while (sp) {
10083                         char *varval = sp->text;
10084                         char *eq = strchrnul(varval, '=');
10085                         if (*eq)
10086                                 eq++;
10087                         fdprintf(preverrout_fd, "%s%.*s%s",
10088                                 pfx,
10089                                 (int)(eq - varval), varval,
10090                                 maybe_single_quote(eq)
10091                         );
10092                         sp = sp->next;
10093                         pfx = " ";
10094                 }
10095
10096                 sp = arglist.list;
10097                 while (sp) {
10098                         fdprintf(preverrout_fd, "%s%s",
10099                                 pfx,
10100                                 /* always quote if matches reserved word: */
10101                                 findkwd(sp->text)
10102                                 ? single_quote(sp->text)
10103                                 : maybe_single_quote(sp->text)
10104                         );
10105                         sp = sp->next;
10106                         pfx = " ";
10107                 }
10108                 safe_write(preverrout_fd, "\n", 1);
10109         }
10110
10111         cmd_is_exec = 0;
10112         spclbltin = -1;
10113
10114         /* Now locate the command. */
10115         if (argc) {
10116                 int cmd_flag = DO_ERR;
10117 #if ENABLE_ASH_CMDCMD
10118                 const char *oldpath = path + 5;
10119 #endif
10120                 path += 5;
10121                 for (;;) {
10122                         find_command(argv[0], &cmdentry, cmd_flag, path);
10123                         if (cmdentry.cmdtype == CMDUNKNOWN) {
10124                                 flush_stdout_stderr();
10125                                 status = 127;
10126                                 goto bail;
10127                         }
10128
10129                         /* implement bltin and command here */
10130                         if (cmdentry.cmdtype != CMDBUILTIN)
10131                                 break;
10132                         if (spclbltin < 0)
10133                                 spclbltin = IS_BUILTIN_SPECIAL(cmdentry.u.cmd);
10134                         if (cmdentry.u.cmd == EXECCMD)
10135                                 cmd_is_exec = 1;
10136 #if ENABLE_ASH_CMDCMD
10137                         if (cmdentry.u.cmd == COMMANDCMD) {
10138                                 path = oldpath;
10139                                 nargv = parse_command_args(argv, &path);
10140                                 if (!nargv)
10141                                         break;
10142                                 /* It's "command [-p] PROG ARGS" (that is, no -Vv).
10143                                  * nargv => "PROG". path is updated if -p.
10144                                  */
10145                                 argc -= nargv - argv;
10146                                 argv = nargv;
10147                                 cmd_flag |= DO_NOFUNC;
10148                         } else
10149 #endif
10150                                 break;
10151                 }
10152         }
10153
10154         if (status) {
10155  bail:
10156                 exitstatus = status;
10157
10158                 /* We have a redirection error. */
10159                 if (spclbltin > 0)
10160                         raise_exception(EXERROR);
10161
10162                 goto out;
10163         }
10164
10165         /* Execute the command. */
10166         switch (cmdentry.cmdtype) {
10167         default: {
10168
10169 #if ENABLE_FEATURE_SH_STANDALONE \
10170  && ENABLE_FEATURE_SH_NOFORK \
10171  && NUM_APPLETS > 1
10172 /* (1) BUG: if variables are set, we need to fork, or save/restore them
10173  *     around run_nofork_applet() call.
10174  * (2) Should this check also be done in forkshell()?
10175  *     (perhaps it should, so that "VAR=VAL nofork" at least avoids exec...)
10176  */
10177                 /* find_command() encodes applet_no as (-2 - applet_no) */
10178                 int applet_no = (- cmdentry.u.index - 2);
10179                 if (applet_no >= 0 && APPLET_IS_NOFORK(applet_no)) {
10180                         char **sv_environ;
10181
10182                         INT_OFF;
10183                         sv_environ = environ;
10184                         environ = listvars(VEXPORT, VUNSET, varlist.list, /*end:*/ NULL);
10185                         /*
10186                          * Run <applet>_main().
10187                          * Signals (^C) can't interrupt here.
10188                          * Otherwise we can mangle stdio or malloc internal state.
10189                          * This makes applets which can run for a long time
10190                          * and/or wait for user input ineligible for NOFORK:
10191                          * for example, "yes" or "rm" (rm -i waits for input).
10192                          */
10193                         status = run_nofork_applet(applet_no, argv);
10194                         environ = sv_environ;
10195                         /*
10196                          * Try enabling NOFORK for "yes" applet.
10197                          * ^C _will_ stop it (write returns EINTR),
10198                          * but this causes stdout FILE to be stuck
10199                          * and needing clearerr(). What if other applets
10200                          * also can get EINTRs? Do we need to switch
10201                          * our signals to SA_RESTART?
10202                          */
10203                         /*clearerr(stdout);*/
10204                         INT_ON;
10205                         break;
10206                 }
10207 #endif
10208                 /* Can we avoid forking? For example, very last command
10209                  * in a script or a subshell does not need forking,
10210                  * we can just exec it.
10211                  */
10212                 if (!(flags & EV_EXIT) || may_have_traps) {
10213                         /* No, forking off a child is necessary */
10214                         INT_OFF;
10215                         get_tty_state();
10216                         jp = makejob(/*cmd,*/ 1);
10217                         if (forkshell(jp, cmd, FORK_FG) != 0) {
10218                                 /* parent */
10219                                 status = waitforjob(jp);
10220                                 INT_ON;
10221                                 TRACE(("forked child exited with %d\n", status));
10222                                 break;
10223                         }
10224                         /* child */
10225                         FORCE_INT_ON;
10226                         /* fall through to exec'ing external program */
10227                 }
10228                 listsetvar(varlist.list, VEXPORT|VSTACK);
10229                 shellexec(argv[0], argv, path, cmdentry.u.index);
10230                 /* NOTREACHED */
10231         } /* default */
10232         case CMDBUILTIN:
10233                 if (spclbltin > 0 || argc == 0) {
10234                         poplocalvars(1);
10235                         if (cmd_is_exec && argc > 1)
10236                                 listsetvar(varlist.list, VEXPORT);
10237                 }
10238
10239                 /* Tight loop with builtins only:
10240                  * "while kill -0 $child; do true; done"
10241                  * will never exit even if $child died, unless we do this
10242                  * to reap the zombie and make kill detect that it's gone: */
10243                 dowait(DOWAIT_NONBLOCK, NULL);
10244
10245                 if (evalbltin(cmdentry.u.cmd, argc, argv, flags)) {
10246                         if (exception_type == EXERROR && spclbltin <= 0) {
10247                                 FORCE_INT_ON;
10248                                 goto readstatus;
10249                         }
10250  raise:
10251                         longjmp(exception_handler->loc, 1);
10252                 }
10253                 goto readstatus;
10254
10255         case CMDFUNCTION:
10256                 /* See above for the rationale */
10257                 dowait(DOWAIT_NONBLOCK, NULL);
10258                 if (evalfun(cmdentry.u.func, argc, argv, flags))
10259                         goto raise;
10260  readstatus:
10261                 status = exitstatus;
10262                 break;
10263         } /* switch */
10264
10265  out:
10266         if (cmd->ncmd.redirect)
10267                 popredir(/*drop:*/ cmd_is_exec);
10268         unwindredir(redir_stop);
10269         unwindfiles(file_stop);
10270         unwindlocalvars(localvar_stop);
10271         if (lastarg) {
10272                 /* dsl: I think this is intended to be used to support
10273                  * '_' in 'vi' command mode during line editing...
10274                  * However I implemented that within libedit itself.
10275                  */
10276                 setvar0("_", lastarg);
10277         }
10278         popstackmark(&smark);
10279
10280         return status;
10281 }
10282
10283 static int
10284 evalbltin(const struct builtincmd *cmd, int argc, char **argv, int flags)
10285 {
10286         char *volatile savecmdname;
10287         struct jmploc *volatile savehandler;
10288         struct jmploc jmploc;
10289         int status;
10290         int i;
10291
10292         savecmdname = commandname;
10293         savehandler = exception_handler;
10294         i = setjmp(jmploc.loc);
10295         if (i)
10296                 goto cmddone;
10297         exception_handler = &jmploc;
10298         commandname = argv[0];
10299         argptr = argv + 1;
10300         optptr = NULL;                  /* initialize nextopt */
10301         if (cmd == EVALCMD)
10302                 status = evalcmd(argc, argv, flags);
10303         else
10304                 status = (*cmd->builtin)(argc, argv);
10305         flush_stdout_stderr();
10306         status |= ferror(stdout);
10307         exitstatus = status;
10308  cmddone:
10309         clearerr(stdout);
10310         commandname = savecmdname;
10311         exception_handler = savehandler;
10312
10313         return i;
10314 }
10315
10316 static int
10317 goodname(const char *p)
10318 {
10319         return endofname(p)[0] == '\0';
10320 }
10321
10322
10323 /*
10324  * Search for a command.  This is called before we fork so that the
10325  * location of the command will be available in the parent as well as
10326  * the child.  The check for "goodname" is an overly conservative
10327  * check that the name will not be subject to expansion.
10328  */
10329 static void
10330 prehash(union node *n)
10331 {
10332         struct cmdentry entry;
10333
10334         if (n->type == NCMD && n->ncmd.args && goodname(n->ncmd.args->narg.text))
10335                 find_command(n->ncmd.args->narg.text, &entry, 0, pathval());
10336 }
10337
10338
10339 /* ============ Builtin commands
10340  *
10341  * Builtin commands whose functions are closely tied to evaluation
10342  * are implemented here.
10343  */
10344
10345 /*
10346  * Handle break and continue commands.  Break, continue, and return are
10347  * all handled by setting the evalskip flag.  The evaluation routines
10348  * above all check this flag, and if it is set they start skipping
10349  * commands rather than executing them.  The variable skipcount is
10350  * the number of loops to break/continue, or the number of function
10351  * levels to return.  (The latter is always 1.)  It should probably
10352  * be an error to break out of more loops than exist, but it isn't
10353  * in the standard shell so we don't make it one here.
10354  */
10355 static int FAST_FUNC
10356 breakcmd(int argc UNUSED_PARAM, char **argv)
10357 {
10358         int n = argv[1] ? number(argv[1]) : 1;
10359
10360         if (n <= 0)
10361                 ash_msg_and_raise_error(msg_illnum, argv[1]);
10362         if (n > loopnest)
10363                 n = loopnest;
10364         if (n > 0) {
10365                 evalskip = (**argv == 'c') ? SKIPCONT : SKIPBREAK;
10366                 skipcount = n;
10367         }
10368         return 0;
10369 }
10370
10371
10372 /*
10373  * This implements the input routines used by the parser.
10374  */
10375
10376 enum {
10377         INPUT_PUSH_FILE = 1,
10378         INPUT_NOFILE_OK = 2,
10379 };
10380
10381 static smallint checkkwd;
10382 /* values of checkkwd variable */
10383 #define CHKALIAS        0x1
10384 #define CHKKWD          0x2
10385 #define CHKNL           0x4
10386 #define CHKEOFMARK      0x8
10387
10388 /*
10389  * Push a string back onto the input at this current parsefile level.
10390  * We handle aliases this way.
10391  */
10392 #if !ENABLE_ASH_ALIAS
10393 #define pushstring(s, ap) pushstring(s)
10394 #endif
10395 static void
10396 pushstring(char *s, struct alias *ap)
10397 {
10398         struct strpush *sp;
10399         int len;
10400
10401         len = strlen(s);
10402         INT_OFF;
10403         if (g_parsefile->strpush) {
10404                 sp = ckzalloc(sizeof(*sp));
10405                 sp->prev = g_parsefile->strpush;
10406         } else {
10407                 sp = &(g_parsefile->basestrpush);
10408         }
10409         g_parsefile->strpush = sp;
10410         sp->prev_string = g_parsefile->next_to_pgetc;
10411         sp->prev_left_in_line = g_parsefile->left_in_line;
10412         sp->unget = g_parsefile->unget;
10413         memcpy(sp->lastc, g_parsefile->lastc, sizeof(sp->lastc));
10414 #if ENABLE_ASH_ALIAS
10415         sp->ap = ap;
10416         if (ap) {
10417                 ap->flag |= ALIASINUSE;
10418                 sp->string = s;
10419         }
10420 #endif
10421         g_parsefile->next_to_pgetc = s;
10422         g_parsefile->left_in_line = len;
10423         g_parsefile->unget = 0;
10424         INT_ON;
10425 }
10426
10427 static void
10428 popstring(void)
10429 {
10430         struct strpush *sp = g_parsefile->strpush;
10431
10432         INT_OFF;
10433 #if ENABLE_ASH_ALIAS
10434         if (sp->ap) {
10435                 if (g_parsefile->next_to_pgetc[-1] == ' '
10436                  || g_parsefile->next_to_pgetc[-1] == '\t'
10437                 ) {
10438                         checkkwd |= CHKALIAS;
10439                 }
10440                 if (sp->string != sp->ap->val) {
10441                         free(sp->string);
10442                 }
10443                 sp->ap->flag &= ~ALIASINUSE;
10444                 if (sp->ap->flag & ALIASDEAD) {
10445                         unalias(sp->ap->name);
10446                 }
10447         }
10448 #endif
10449         g_parsefile->next_to_pgetc = sp->prev_string;
10450         g_parsefile->left_in_line = sp->prev_left_in_line;
10451         g_parsefile->unget = sp->unget;
10452         memcpy(g_parsefile->lastc, sp->lastc, sizeof(sp->lastc));
10453         g_parsefile->strpush = sp->prev;
10454         if (sp != &(g_parsefile->basestrpush))
10455                 free(sp);
10456         INT_ON;
10457 }
10458
10459 static int
10460 preadfd(void)
10461 {
10462         int nr;
10463         char *buf = g_parsefile->buf;
10464
10465         g_parsefile->next_to_pgetc = buf;
10466 #if ENABLE_FEATURE_EDITING
10467  retry:
10468         if (!iflag || g_parsefile->pf_fd != STDIN_FILENO)
10469                 nr = nonblock_immune_read(g_parsefile->pf_fd, buf, IBUFSIZ - 1);
10470         else {
10471 # if ENABLE_ASH_IDLE_TIMEOUT
10472                 int timeout = -1;
10473                 if (iflag) {
10474                         const char *tmout_var = lookupvar("TMOUT");
10475                         if (tmout_var) {
10476                                 timeout = atoi(tmout_var) * 1000;
10477                                 if (timeout <= 0)
10478                                         timeout = -1;
10479                         }
10480                 }
10481                 line_input_state->timeout = timeout;
10482 # endif
10483 # if ENABLE_FEATURE_TAB_COMPLETION
10484                 line_input_state->path_lookup = pathval();
10485 # endif
10486                 reinit_unicode_for_ash();
10487                 nr = read_line_input(line_input_state, cmdedit_prompt, buf, IBUFSIZ);
10488                 if (nr == 0) {
10489                         /* ^C pressed, "convert" to SIGINT */
10490                         write(STDOUT_FILENO, "^C", 2);
10491                         if (trap[SIGINT]) {
10492                                 buf[0] = '\n';
10493                                 buf[1] = '\0';
10494                                 raise(SIGINT);
10495                                 return 1;
10496                         }
10497                         exitstatus = 128 + SIGINT;
10498                         bb_putchar('\n');
10499                         goto retry;
10500                 }
10501                 if (nr < 0) {
10502                         if (errno == 0) {
10503                                 /* Ctrl+D pressed */
10504                                 nr = 0;
10505                         }
10506 # if ENABLE_ASH_IDLE_TIMEOUT
10507                         else if (errno == EAGAIN && timeout > 0) {
10508                                 puts("\007timed out waiting for input: auto-logout");
10509                                 exitshell();
10510                         }
10511 # endif
10512                 }
10513         }
10514 #else
10515         nr = nonblock_immune_read(g_parsefile->pf_fd, buf, IBUFSIZ - 1);
10516 #endif
10517
10518 #if 0 /* disabled: nonblock_immune_read() handles this problem */
10519         if (nr < 0) {
10520                 if (parsefile->fd == 0 && errno == EWOULDBLOCK) {
10521                         int flags = fcntl(0, F_GETFL);
10522                         if (flags >= 0 && (flags & O_NONBLOCK)) {
10523                                 flags &= ~O_NONBLOCK;
10524                                 if (fcntl(0, F_SETFL, flags) >= 0) {
10525                                         out2str("sh: turning off NDELAY mode\n");
10526                                         goto retry;
10527                                 }
10528                         }
10529                 }
10530         }
10531 #endif
10532         return nr;
10533 }
10534
10535 /*
10536  * Refill the input buffer and return the next input character:
10537  *
10538  * 1) If a string was pushed back on the input, pop it;
10539  * 2) If an EOF was pushed back (g_parsefile->left_in_line < -BIGNUM)
10540  *    or we are reading from a string so we can't refill the buffer,
10541  *    return EOF.
10542  * 3) If there is more stuff in this buffer, use it else call read to fill it.
10543  * 4) Process input up to the next newline, deleting nul characters.
10544  */
10545 //#define pgetc_debug(...) bb_error_msg(__VA_ARGS__)
10546 #define pgetc_debug(...) ((void)0)
10547 static int pgetc(void);
10548 static int
10549 preadbuffer(void)
10550 {
10551         char *q;
10552         int more;
10553
10554         if (g_parsefile->strpush) {
10555 #if ENABLE_ASH_ALIAS
10556                 if (g_parsefile->left_in_line == -1
10557                  && g_parsefile->strpush->ap
10558                  && g_parsefile->next_to_pgetc[-1] != ' '
10559                  && g_parsefile->next_to_pgetc[-1] != '\t'
10560                 ) {
10561                         pgetc_debug("preadbuffer PEOA");
10562                         return PEOA;
10563                 }
10564 #endif
10565                 popstring();
10566                 return pgetc();
10567         }
10568         /* on both branches above g_parsefile->left_in_line < 0.
10569          * "pgetc" needs refilling.
10570          */
10571
10572         /* -90 is our -BIGNUM. Below we use -99 to mark "EOF on read",
10573          * pungetc() may increment it a few times.
10574          * Assuming it won't increment it to less than -90.
10575          */
10576         if (g_parsefile->left_in_line < -90 || g_parsefile->buf == NULL) {
10577                 pgetc_debug("preadbuffer PEOF1");
10578                 /* even in failure keep left_in_line and next_to_pgetc
10579                  * in lock step, for correct multi-layer pungetc.
10580                  * left_in_line was decremented before preadbuffer(),
10581                  * must inc next_to_pgetc: */
10582                 g_parsefile->next_to_pgetc++;
10583                 return PEOF;
10584         }
10585
10586         more = g_parsefile->left_in_buffer;
10587         if (more <= 0) {
10588                 flush_stdout_stderr();
10589  again:
10590                 more = preadfd();
10591                 if (more <= 0) {
10592                         /* don't try reading again */
10593                         g_parsefile->left_in_line = -99;
10594                         pgetc_debug("preadbuffer PEOF2");
10595                         g_parsefile->next_to_pgetc++;
10596                         return PEOF;
10597                 }
10598         }
10599
10600         /* Find out where's the end of line.
10601          * Set g_parsefile->left_in_line
10602          * and g_parsefile->left_in_buffer acordingly.
10603          * NUL chars are deleted.
10604          */
10605         q = g_parsefile->next_to_pgetc;
10606         for (;;) {
10607                 char c;
10608
10609                 more--;
10610
10611                 c = *q;
10612                 if (c == '\0') {
10613                         memmove(q, q + 1, more);
10614                 } else {
10615                         q++;
10616                         if (c == '\n') {
10617                                 g_parsefile->left_in_line = q - g_parsefile->next_to_pgetc - 1;
10618                                 break;
10619                         }
10620                 }
10621
10622                 if (more <= 0) {
10623                         g_parsefile->left_in_line = q - g_parsefile->next_to_pgetc - 1;
10624                         if (g_parsefile->left_in_line < 0)
10625                                 goto again;
10626                         break;
10627                 }
10628         }
10629         g_parsefile->left_in_buffer = more;
10630
10631         if (vflag) {
10632                 char save = *q;
10633                 *q = '\0';
10634                 out2str(g_parsefile->next_to_pgetc);
10635                 *q = save;
10636         }
10637
10638         pgetc_debug("preadbuffer at %d:%p'%s'",
10639                         g_parsefile->left_in_line,
10640                         g_parsefile->next_to_pgetc,
10641                         g_parsefile->next_to_pgetc);
10642         return (unsigned char)*g_parsefile->next_to_pgetc++;
10643 }
10644
10645 static void
10646 nlprompt(void)
10647 {
10648         g_parsefile->linno++;
10649         setprompt_if(doprompt, 2);
10650 }
10651 static void
10652 nlnoprompt(void)
10653 {
10654         g_parsefile->linno++;
10655         needprompt = doprompt;
10656 }
10657
10658 static int
10659 pgetc(void)
10660 {
10661         int c;
10662
10663         pgetc_debug("pgetc at %d:%p'%s'",
10664                         g_parsefile->left_in_line,
10665                         g_parsefile->next_to_pgetc,
10666                         g_parsefile->next_to_pgetc);
10667         if (g_parsefile->unget)
10668                 return g_parsefile->lastc[--g_parsefile->unget];
10669
10670         if (--g_parsefile->left_in_line >= 0)
10671                 c = (unsigned char)*g_parsefile->next_to_pgetc++;
10672         else
10673                 c = preadbuffer();
10674
10675         g_parsefile->lastc[1] = g_parsefile->lastc[0];
10676         g_parsefile->lastc[0] = c;
10677
10678         return c;
10679 }
10680
10681 #if ENABLE_ASH_ALIAS
10682 static int
10683 pgetc_without_PEOA(void)
10684 {
10685         int c;
10686         do {
10687                 pgetc_debug("pgetc at %d:%p'%s'",
10688                                 g_parsefile->left_in_line,
10689                                 g_parsefile->next_to_pgetc,
10690                                 g_parsefile->next_to_pgetc);
10691                 c = pgetc();
10692         } while (c == PEOA);
10693         return c;
10694 }
10695 #else
10696 # define pgetc_without_PEOA() pgetc()
10697 #endif
10698
10699 /*
10700  * Undo a call to pgetc.  Only two characters may be pushed back.
10701  * PEOF may be pushed back.
10702  */
10703 static void
10704 pungetc(void)
10705 {
10706         g_parsefile->unget++;
10707 }
10708
10709 /* This one eats backslash+newline */
10710 static int
10711 pgetc_eatbnl(void)
10712 {
10713         int c;
10714
10715         while ((c = pgetc()) == '\\') {
10716                 if (pgetc() != '\n') {
10717                         pungetc();
10718                         break;
10719                 }
10720
10721                 nlprompt();
10722         }
10723
10724         return c;
10725 }
10726
10727 struct synstack {
10728         smalluint syntax;
10729         uint8_t innerdq   :1;
10730         uint8_t varpushed :1;
10731         uint8_t dblquote  :1;
10732         int varnest;            /* levels of variables expansion */
10733         int dqvarnest;          /* levels of variables expansion within double quotes */
10734         int parenlevel;         /* levels of parens in arithmetic */
10735         struct synstack *prev;
10736         struct synstack *next;
10737 };
10738
10739 static void
10740 synstack_push(struct synstack **stack, struct synstack *next, int syntax)
10741 {
10742         memset(next, 0, sizeof(*next));
10743         next->syntax = syntax;
10744         next->next = *stack;
10745         (*stack)->prev = next;
10746         *stack = next;
10747 }
10748
10749 static ALWAYS_INLINE void
10750 synstack_pop(struct synstack **stack)
10751 {
10752         *stack = (*stack)->next;
10753 }
10754
10755 /*
10756  * To handle the "." command, a stack of input files is used.  Pushfile
10757  * adds a new entry to the stack and popfile restores the previous level.
10758  */
10759 static void
10760 pushfile(void)
10761 {
10762         struct parsefile *pf;
10763
10764         pf = ckzalloc(sizeof(*pf));
10765         pf->prev = g_parsefile;
10766         pf->pf_fd = -1;
10767         /*pf->strpush = NULL; - ckzalloc did it */
10768         /*pf->basestrpush.prev = NULL;*/
10769         /*pf->unget = 0;*/
10770         g_parsefile = pf;
10771 }
10772
10773 static void
10774 popfile(void)
10775 {
10776         struct parsefile *pf = g_parsefile;
10777
10778         if (pf == &basepf)
10779                 return;
10780
10781         INT_OFF;
10782         if (pf->pf_fd >= 0)
10783                 close(pf->pf_fd);
10784         free(pf->buf);
10785         while (pf->strpush)
10786                 popstring();
10787         g_parsefile = pf->prev;
10788         free(pf);
10789         INT_ON;
10790 }
10791
10792 static void
10793 unwindfiles(struct parsefile *stop)
10794 {
10795         while (g_parsefile != stop)
10796                 popfile();
10797 }
10798
10799 /*
10800  * Return to top level.
10801  */
10802 static void
10803 popallfiles(void)
10804 {
10805         unwindfiles(&basepf);
10806 }
10807
10808 /*
10809  * Close the file(s) that the shell is reading commands from.  Called
10810  * after a fork is done.
10811  */
10812 static void
10813 closescript(void)
10814 {
10815         popallfiles();
10816         if (g_parsefile->pf_fd > 0) {
10817                 close(g_parsefile->pf_fd);
10818                 g_parsefile->pf_fd = 0;
10819         }
10820 }
10821
10822 /*
10823  * Like setinputfile, but takes an open file descriptor.  Call this with
10824  * interrupts off.
10825  */
10826 static void
10827 setinputfd(int fd, int push)
10828 {
10829         if (push) {
10830                 pushfile();
10831                 g_parsefile->buf = NULL;
10832         }
10833         g_parsefile->pf_fd = fd;
10834         if (g_parsefile->buf == NULL)
10835                 g_parsefile->buf = ckmalloc(IBUFSIZ);
10836         g_parsefile->left_in_buffer = 0;
10837         g_parsefile->left_in_line = 0;
10838         g_parsefile->linno = 1;
10839 }
10840
10841 /*
10842  * Set the input to take input from a file.  If push is set, push the
10843  * old input onto the stack first.
10844  */
10845 static int
10846 setinputfile(const char *fname, int flags)
10847 {
10848         int fd;
10849
10850         INT_OFF;
10851         fd = open(fname, O_RDONLY | O_CLOEXEC);
10852         if (fd < 0) {
10853                 if (flags & INPUT_NOFILE_OK)
10854                         goto out;
10855                 exitstatus = 127;
10856                 ash_msg_and_raise_perror("can't open '%s'", fname);
10857         }
10858         if (fd < 10)
10859                 fd = savefd(fd);
10860         else if (O_CLOEXEC == 0) /* old libc */
10861                 close_on_exec_on(fd);
10862
10863         setinputfd(fd, flags & INPUT_PUSH_FILE);
10864  out:
10865         INT_ON;
10866         return fd;
10867 }
10868
10869 /*
10870  * Like setinputfile, but takes input from a string.
10871  */
10872 static void
10873 setinputstring(char *string)
10874 {
10875         INT_OFF;
10876         pushfile();
10877         g_parsefile->next_to_pgetc = string;
10878         g_parsefile->left_in_line = strlen(string);
10879         g_parsefile->buf = NULL;
10880         g_parsefile->linno = 1;
10881         INT_ON;
10882 }
10883
10884
10885 /*
10886  * Routines to check for mail.
10887  */
10888
10889 #if ENABLE_ASH_MAIL
10890
10891 /* Hash of mtimes of mailboxes */
10892 static unsigned mailtime_hash;
10893 /* Set if MAIL or MAILPATH is changed. */
10894 static smallint mail_var_path_changed;
10895
10896 /*
10897  * Print appropriate message(s) if mail has arrived.
10898  * If mail_var_path_changed is set,
10899  * then the value of MAIL has mail_var_path_changed,
10900  * so we just update the values.
10901  */
10902 static void
10903 chkmail(void)
10904 {
10905         const char *mpath;
10906         char *p;
10907         char *q;
10908         unsigned new_hash;
10909         struct stackmark smark;
10910         struct stat statb;
10911
10912         setstackmark(&smark);
10913         mpath = mpathset() ? mpathval() : mailval();
10914         new_hash = 0;
10915         for (;;) {
10916                 p = path_advance(&mpath, nullstr);
10917                 if (p == NULL)
10918                         break;
10919                 if (*p == '\0')
10920                         continue;
10921                 for (q = p; *q; q++)
10922                         continue;
10923 #if DEBUG
10924                 if (q[-1] != '/')
10925                         abort();
10926 #endif
10927                 q[-1] = '\0';                   /* delete trailing '/' */
10928                 if (stat(p, &statb) < 0) {
10929                         continue;
10930                 }
10931                 /* Very simplistic "hash": just a sum of all mtimes */
10932                 new_hash += (unsigned)statb.st_mtime;
10933         }
10934         if (!mail_var_path_changed && mailtime_hash != new_hash) {
10935                 if (mailtime_hash != 0)
10936                         out2str("you have mail\n");
10937                 mailtime_hash = new_hash;
10938         }
10939         mail_var_path_changed = 0;
10940         popstackmark(&smark);
10941 }
10942
10943 static void FAST_FUNC
10944 changemail(const char *val UNUSED_PARAM)
10945 {
10946         mail_var_path_changed = 1;
10947 }
10948
10949 #endif /* ASH_MAIL */
10950
10951
10952 /* ============ ??? */
10953
10954 /*
10955  * Set the shell parameters.
10956  */
10957 static void
10958 setparam(char **argv)
10959 {
10960         char **newparam;
10961         char **ap;
10962         int nparam;
10963
10964         for (nparam = 0; argv[nparam]; nparam++)
10965                 continue;
10966         ap = newparam = ckmalloc((nparam + 1) * sizeof(*ap));
10967         while (*argv) {
10968                 *ap++ = ckstrdup(*argv++);
10969         }
10970         *ap = NULL;
10971         freeparam(&shellparam);
10972         shellparam.malloced = 1;
10973         shellparam.nparam = nparam;
10974         shellparam.p = newparam;
10975 #if ENABLE_ASH_GETOPTS
10976         shellparam.optind = 1;
10977         shellparam.optoff = -1;
10978 #endif
10979 }
10980
10981 /*
10982  * Process shell options.  The global variable argptr contains a pointer
10983  * to the argument list; we advance it past the options.
10984  *
10985  * SUSv3 section 2.8.1 "Consequences of Shell Errors" says:
10986  * For a non-interactive shell, an error condition encountered
10987  * by a special built-in ... shall cause the shell to write a diagnostic message
10988  * to standard error and exit as shown in the following table:
10989  * Error                                           Special Built-In
10990  * ...
10991  * Utility syntax error (option or operand error)  Shall exit
10992  * ...
10993  * However, in bug 1142 (http://busybox.net/bugs/view.php?id=1142)
10994  * we see that bash does not do that (set "finishes" with error code 1 instead,
10995  * and shell continues), and people rely on this behavior!
10996  * Testcase:
10997  * set -o barfoo 2>/dev/null
10998  * echo $?
10999  *
11000  * Oh well. Let's mimic that.
11001  */
11002 static int
11003 plus_minus_o(char *name, int val)
11004 {
11005         int i;
11006
11007         if (name) {
11008                 for (i = 0; i < NOPTS; i++) {
11009                         if (strcmp(name, optnames(i)) == 0) {
11010                                 optlist[i] = val;
11011                                 return 0;
11012                         }
11013                 }
11014                 ash_msg("illegal option %co %s", val ? '-' : '+', name);
11015                 return 1;
11016         }
11017         for (i = 0; i < NOPTS; i++) {
11018                 if (val) {
11019                         out1fmt("%-16s%s\n", optnames(i), optlist[i] ? "on" : "off");
11020                 } else {
11021                         out1fmt("set %co %s\n", optlist[i] ? '-' : '+', optnames(i));
11022                 }
11023         }
11024         return 0;
11025 }
11026 static void
11027 setoption(int flag, int val)
11028 {
11029         int i;
11030
11031         for (i = 0; i < NOPTS; i++) {
11032                 if (optletters(i) == flag) {
11033                         optlist[i] = val;
11034                         return;
11035                 }
11036         }
11037         ash_msg_and_raise_error("illegal option %c%c", val ? '-' : '+', flag);
11038         /* NOTREACHED */
11039 }
11040 static int
11041 options(int cmdline, int *login_sh)
11042 {
11043         char *p;
11044         int val;
11045         int c;
11046
11047         if (cmdline)
11048                 minusc = NULL;
11049         while ((p = *argptr) != NULL) {
11050                 c = *p++;
11051                 if (c != '-' && c != '+')
11052                         break;
11053                 argptr++;
11054                 val = 0; /* val = 0 if c == '+' */
11055                 if (c == '-') {
11056                         val = 1;
11057                         if (p[0] == '\0' || LONE_DASH(p)) {
11058                                 if (!cmdline) {
11059                                         /* "-" means turn off -x and -v */
11060                                         if (p[0] == '\0')
11061                                                 xflag = vflag = 0;
11062                                         /* "--" means reset params */
11063                                         else if (*argptr == NULL)
11064                                                 setparam(argptr);
11065                                 }
11066                                 break;    /* "-" or "--" terminates options */
11067                         }
11068                 }
11069                 /* first char was + or - */
11070                 while ((c = *p++) != '\0') {
11071                         /* bash 3.2 indeed handles -c CMD and +c CMD the same */
11072                         if (c == 'c' && cmdline) {
11073                                 minusc = p;     /* command is after shell args */
11074                         } else if (c == 'o') {
11075                                 if (plus_minus_o(*argptr, val)) {
11076                                         /* it already printed err message */
11077                                         return 1; /* error */
11078                                 }
11079                                 if (*argptr)
11080                                         argptr++;
11081                         } else if (cmdline && (c == 'l')) { /* -l or +l == --login */
11082                                 if (login_sh)
11083                                         *login_sh = 1;
11084                         /* bash does not accept +-login, we also won't */
11085                         } else if (cmdline && val && (c == '-')) { /* long options */
11086                                 if (strcmp(p, "login") == 0) {
11087                                         if (login_sh)
11088                                                 *login_sh = 1;
11089                                 }
11090                                 break;
11091                         } else {
11092                                 setoption(c, val);
11093                         }
11094                 }
11095         }
11096         return 0;
11097 }
11098
11099 /*
11100  * The shift builtin command.
11101  */
11102 static int FAST_FUNC
11103 shiftcmd(int argc UNUSED_PARAM, char **argv)
11104 {
11105         int n;
11106         char **ap1, **ap2;
11107
11108         n = 1;
11109         if (argv[1])
11110                 n = number(argv[1]);
11111         if (n > shellparam.nparam)
11112                 return 1;
11113         INT_OFF;
11114         shellparam.nparam -= n;
11115         for (ap1 = shellparam.p; --n >= 0; ap1++) {
11116                 if (shellparam.malloced)
11117                         free(*ap1);
11118         }
11119         ap2 = shellparam.p;
11120         while ((*ap2++ = *ap1++) != NULL)
11121                 continue;
11122 #if ENABLE_ASH_GETOPTS
11123         shellparam.optind = 1;
11124         shellparam.optoff = -1;
11125 #endif
11126         INT_ON;
11127         return 0;
11128 }
11129
11130 /*
11131  * POSIX requires that 'set' (but not export or readonly) output the
11132  * variables in lexicographic order - by the locale's collating order (sigh).
11133  * Maybe we could keep them in an ordered balanced binary tree
11134  * instead of hashed lists.
11135  * For now just roll 'em through qsort for printing...
11136  */
11137 static int
11138 showvars(const char *sep_prefix, int on, int off)
11139 {
11140         const char *sep;
11141         char **ep, **epend;
11142
11143         ep = listvars(on, off, /*strlist:*/ NULL, &epend);
11144         qsort(ep, epend - ep, sizeof(char *), vpcmp);
11145
11146         sep = *sep_prefix ? " " : sep_prefix;
11147
11148         for (; ep < epend; ep++) {
11149                 const char *p;
11150                 const char *q;
11151
11152                 p = endofname(*ep);
11153 /* Used to have simple "p = strchrnul(*ep, '=')" here instead, but this
11154  * makes "export -p" to have output not suitable for "eval":
11155  * import os
11156  * os.environ["test-test"]="test"
11157  * if os.fork() == 0:
11158  *   os.execv("ash", [ 'ash', '-c', 'eval $(export -p); echo OK' ])  # fixes this
11159  * os.execv("ash", [ 'ash', '-c', 'env | grep test-test' ])
11160  */
11161                 q = nullstr;
11162                 if (*p == '=')
11163                         q = single_quote(++p);
11164                 out1fmt("%s%s%.*s%s\n", sep_prefix, sep, (int)(p - *ep), *ep, q);
11165         }
11166         return 0;
11167 }
11168
11169 /*
11170  * The set command builtin.
11171  */
11172 static int FAST_FUNC
11173 setcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
11174 {
11175         int retval;
11176
11177         if (!argv[1])
11178                 return showvars(nullstr, 0, VUNSET);
11179
11180         INT_OFF;
11181         retval = options(/*cmdline:*/ 0, NULL);
11182         if (retval == 0) { /* if no parse error... */
11183                 optschanged();
11184                 if (*argptr != NULL) {
11185                         setparam(argptr);
11186                 }
11187         }
11188         INT_ON;
11189         return retval;
11190 }
11191
11192 #if ENABLE_ASH_RANDOM_SUPPORT
11193 static void FAST_FUNC
11194 change_random(const char *value)
11195 {
11196         uint32_t t;
11197
11198         if (value == NULL) {
11199                 /* "get", generate */
11200                 t = next_random(&random_gen);
11201                 /* set without recursion */
11202                 setvar(vrandom.var_text, utoa(t), VNOFUNC);
11203                 vrandom.flags &= ~VNOFUNC;
11204         } else {
11205                 /* set/reset */
11206                 t = strtoul(value, NULL, 10);
11207                 INIT_RANDOM_T(&random_gen, (t ? t : 1), t);
11208         }
11209 }
11210 #endif
11211
11212 #if ENABLE_ASH_GETOPTS
11213 static int
11214 getopts(char *optstr, char *optvar, char **optfirst)
11215 {
11216         char *p, *q;
11217         char c = '?';
11218         int done = 0;
11219         char sbuf[2];
11220         char **optnext;
11221         int ind = shellparam.optind;
11222         int off = shellparam.optoff;
11223
11224         sbuf[1] = '\0';
11225
11226         shellparam.optind = -1;
11227         optnext = optfirst + ind - 1;
11228
11229         if (ind <= 1 || off < 0 || (int)strlen(optnext[-1]) < off)
11230                 p = NULL;
11231         else
11232                 p = optnext[-1] + off;
11233         if (p == NULL || *p == '\0') {
11234                 /* Current word is done, advance */
11235                 p = *optnext;
11236                 if (p == NULL || *p != '-' || *++p == '\0') {
11237  atend:
11238                         unsetvar("OPTARG");
11239                         p = NULL;
11240                         done = 1;
11241                         goto out;
11242                 }
11243                 optnext++;
11244                 if (LONE_DASH(p))        /* check for "--" */
11245                         goto atend;
11246         }
11247
11248         c = *p++;
11249         for (q = optstr; *q != c;) {
11250                 if (*q == '\0') {
11251                         /* OPTERR is a bashism */
11252                         const char *cp = lookupvar("OPTERR");
11253                         if ((cp && LONE_CHAR(cp, '0'))
11254                          || (optstr[0] == ':')
11255                         ) {
11256                                 sbuf[0] = c;
11257                                 /*sbuf[1] = '\0'; - already is */
11258                                 setvar0("OPTARG", sbuf);
11259                         } else {
11260                                 fprintf(stderr, "Illegal option -%c\n", c);
11261                                 unsetvar("OPTARG");
11262                         }
11263                         c = '?';
11264                         goto out;
11265                 }
11266                 if (*++q == ':')
11267                         q++;
11268         }
11269
11270         if (*++q == ':') {
11271                 if (*p == '\0' && (p = *optnext) == NULL) {
11272                         /* OPTERR is a bashism */
11273                         const char *cp = lookupvar("OPTERR");
11274                         if ((cp && LONE_CHAR(cp, '0'))
11275                          || (optstr[0] == ':')
11276                         ) {
11277                                 sbuf[0] = c;
11278                                 /*sbuf[1] = '\0'; - already is */
11279                                 setvar0("OPTARG", sbuf);
11280                                 c = ':';
11281                         } else {
11282                                 fprintf(stderr, "No arg for -%c option\n", c);
11283                                 unsetvar("OPTARG");
11284                                 c = '?';
11285                         }
11286                         goto out;
11287                 }
11288
11289                 if (p == *optnext)
11290                         optnext++;
11291                 setvar0("OPTARG", p);
11292                 p = NULL;
11293         } else
11294                 setvar0("OPTARG", nullstr);
11295  out:
11296         ind = optnext - optfirst + 1;
11297         setvar("OPTIND", itoa(ind), VNOFUNC);
11298         sbuf[0] = c;
11299         /*sbuf[1] = '\0'; - already is */
11300         setvar0(optvar, sbuf);
11301
11302         shellparam.optoff = p ? p - *(optnext - 1) : -1;
11303         shellparam.optind = ind;
11304
11305         return done;
11306 }
11307
11308 /*
11309  * The getopts builtin.  Shellparam.optnext points to the next argument
11310  * to be processed.  Shellparam.optptr points to the next character to
11311  * be processed in the current argument.  If shellparam.optnext is NULL,
11312  * then it's the first time getopts has been called.
11313  */
11314 static int FAST_FUNC
11315 getoptscmd(int argc, char **argv)
11316 {
11317         char **optbase;
11318
11319         if (argc < 3)
11320                 ash_msg_and_raise_error("usage: getopts optstring var [arg]");
11321         if (argc == 3) {
11322                 optbase = shellparam.p;
11323                 if ((unsigned)shellparam.optind > shellparam.nparam + 1) {
11324                         shellparam.optind = 1;
11325                         shellparam.optoff = -1;
11326                 }
11327         } else {
11328                 optbase = &argv[3];
11329                 if ((unsigned)shellparam.optind > argc - 2) {
11330                         shellparam.optind = 1;
11331                         shellparam.optoff = -1;
11332                 }
11333         }
11334
11335         return getopts(argv[1], argv[2], optbase);
11336 }
11337 #endif /* ASH_GETOPTS */
11338
11339
11340 /* ============ Shell parser */
11341
11342 struct heredoc {
11343         struct heredoc *next;   /* next here document in list */
11344         union node *here;       /* redirection node */
11345         char *eofmark;          /* string indicating end of input */
11346         smallint striptabs;     /* if set, strip leading tabs */
11347 };
11348
11349 static smallint tokpushback;           /* last token pushed back */
11350 static smallint quoteflag;             /* set if (part of) last token was quoted */
11351 static token_id_t lasttoken;           /* last token read (integer id Txxx) */
11352 static struct heredoc *heredoclist;    /* list of here documents to read */
11353 static char *wordtext;                 /* text of last word returned by readtoken */
11354 static struct nodelist *backquotelist;
11355 static union node *redirnode;
11356 static struct heredoc *heredoc;
11357
11358 static const char *
11359 tokname(char *buf, int tok)
11360 {
11361         if (tok < TSEMI)
11362                 return tokname_array[tok];
11363         sprintf(buf, "\"%s\"", tokname_array[tok]);
11364         return buf;
11365 }
11366
11367 /* raise_error_unexpected_syntax:
11368  * Called when an unexpected token is read during the parse.  The argument
11369  * is the token that is expected, or -1 if more than one type of token can
11370  * occur at this point.
11371  */
11372 static void raise_error_unexpected_syntax(int) NORETURN;
11373 static void
11374 raise_error_unexpected_syntax(int token)
11375 {
11376         char msg[64];
11377         char buf[16];
11378         int l;
11379
11380         l = sprintf(msg, "unexpected %s", tokname(buf, lasttoken));
11381         if (token >= 0)
11382                 sprintf(msg + l, " (expecting %s)", tokname(buf, token));
11383         raise_error_syntax(msg);
11384         /* NOTREACHED */
11385 }
11386
11387 /* parsing is heavily cross-recursive, need these forward decls */
11388 static union node *andor(void);
11389 static union node *pipeline(void);
11390 static union node *parse_command(void);
11391 static void parseheredoc(void);
11392 static int peektoken(void);
11393 static int readtoken(void);
11394
11395 static union node *
11396 list(int nlflag)
11397 {
11398         union node *n1, *n2, *n3;
11399         int tok;
11400
11401         n1 = NULL;
11402         for (;;) {
11403                 switch (peektoken()) {
11404                 case TNL:
11405                         if (!(nlflag & 1))
11406                                 break;
11407                         parseheredoc();
11408                         return n1;
11409
11410                 case TEOF:
11411                         if (!n1 && (nlflag & 1))
11412                                 n1 = NODE_EOF;
11413                         parseheredoc();
11414                         return n1;
11415                 }
11416
11417                 checkkwd = CHKNL | CHKKWD | CHKALIAS;
11418                 if (nlflag == 2 && ((1 << peektoken()) & tokendlist))
11419                         return n1;
11420                 nlflag |= 2;
11421
11422                 n2 = andor();
11423                 tok = readtoken();
11424                 if (tok == TBACKGND) {
11425                         if (n2->type == NPIPE) {
11426                                 n2->npipe.pipe_backgnd = 1;
11427                         } else {
11428                                 if (n2->type != NREDIR) {
11429                                         n3 = stzalloc(sizeof(struct nredir));
11430                                         n3->nredir.n = n2;
11431                                         /*n3->nredir.redirect = NULL; - stzalloc did it */
11432                                         n2 = n3;
11433                                 }
11434                                 n2->type = NBACKGND;
11435                         }
11436                 }
11437                 if (n1 == NULL) {
11438                         n1 = n2;
11439                 } else {
11440                         n3 = stzalloc(sizeof(struct nbinary));
11441                         n3->type = NSEMI;
11442                         n3->nbinary.ch1 = n1;
11443                         n3->nbinary.ch2 = n2;
11444                         n1 = n3;
11445                 }
11446                 switch (tok) {
11447                 case TNL:
11448                 case TEOF:
11449                         tokpushback = 1;
11450                         /* fall through */
11451                 case TBACKGND:
11452                 case TSEMI:
11453                         break;
11454                 default:
11455                         if ((nlflag & 1))
11456                                 raise_error_unexpected_syntax(-1);
11457                         tokpushback = 1;
11458                         return n1;
11459                 }
11460         }
11461 }
11462
11463 static union node *
11464 andor(void)
11465 {
11466         union node *n1, *n2, *n3;
11467         int t;
11468
11469         n1 = pipeline();
11470         for (;;) {
11471                 t = readtoken();
11472                 if (t == TAND) {
11473                         t = NAND;
11474                 } else if (t == TOR) {
11475                         t = NOR;
11476                 } else {
11477                         tokpushback = 1;
11478                         return n1;
11479                 }
11480                 checkkwd = CHKNL | CHKKWD | CHKALIAS;
11481                 n2 = pipeline();
11482                 n3 = stzalloc(sizeof(struct nbinary));
11483                 n3->type = t;
11484                 n3->nbinary.ch1 = n1;
11485                 n3->nbinary.ch2 = n2;
11486                 n1 = n3;
11487         }
11488 }
11489
11490 static union node *
11491 pipeline(void)
11492 {
11493         union node *n1, *n2, *pipenode;
11494         struct nodelist *lp, *prev;
11495         int negate;
11496
11497         negate = 0;
11498         TRACE(("pipeline: entered\n"));
11499         if (readtoken() == TNOT) {
11500                 negate = !negate;
11501                 checkkwd = CHKKWD | CHKALIAS;
11502         } else
11503                 tokpushback = 1;
11504         n1 = parse_command();
11505         if (readtoken() == TPIPE) {
11506                 pipenode = stzalloc(sizeof(struct npipe));
11507                 pipenode->type = NPIPE;
11508                 /*pipenode->npipe.pipe_backgnd = 0; - stzalloc did it */
11509                 lp = stzalloc(sizeof(struct nodelist));
11510                 pipenode->npipe.cmdlist = lp;
11511                 lp->n = n1;
11512                 do {
11513                         prev = lp;
11514                         lp = stzalloc(sizeof(struct nodelist));
11515                         checkkwd = CHKNL | CHKKWD | CHKALIAS;
11516                         lp->n = parse_command();
11517                         prev->next = lp;
11518                 } while (readtoken() == TPIPE);
11519                 lp->next = NULL;
11520                 n1 = pipenode;
11521         }
11522         tokpushback = 1;
11523         if (negate) {
11524                 n2 = stzalloc(sizeof(struct nnot));
11525                 n2->type = NNOT;
11526                 n2->nnot.com = n1;
11527                 return n2;
11528         }
11529         return n1;
11530 }
11531
11532 static union node *
11533 makename(void)
11534 {
11535         union node *n;
11536
11537         n = stzalloc(sizeof(struct narg));
11538         n->type = NARG;
11539         /*n->narg.next = NULL; - stzalloc did it */
11540         n->narg.text = wordtext;
11541         n->narg.backquote = backquotelist;
11542         return n;
11543 }
11544
11545 static void
11546 fixredir(union node *n, const char *text, int err)
11547 {
11548         int fd;
11549
11550         TRACE(("Fix redir %s %d\n", text, err));
11551         if (!err)
11552                 n->ndup.vname = NULL;
11553
11554         fd = bb_strtou(text, NULL, 10);
11555         if (!errno && fd >= 0)
11556                 n->ndup.dupfd = fd;
11557         else if (LONE_DASH(text))
11558                 n->ndup.dupfd = -1;
11559         else {
11560                 if (err)
11561                         raise_error_syntax("bad fd number");
11562                 n->ndup.vname = makename();
11563         }
11564 }
11565
11566 static void
11567 parsefname(void)
11568 {
11569         union node *n = redirnode;
11570
11571         if (n->type == NHERE)
11572                 checkkwd = CHKEOFMARK;
11573         if (readtoken() != TWORD)
11574                 raise_error_unexpected_syntax(-1);
11575         if (n->type == NHERE) {
11576                 struct heredoc *here = heredoc;
11577                 struct heredoc *p;
11578
11579                 if (quoteflag == 0)
11580                         n->type = NXHERE;
11581                 TRACE(("Here document %d\n", n->type));
11582                 rmescapes(wordtext, 0, NULL);
11583                 here->eofmark = wordtext;
11584                 here->next = NULL;
11585                 if (heredoclist == NULL)
11586                         heredoclist = here;
11587                 else {
11588                         for (p = heredoclist; p->next; p = p->next)
11589                                 continue;
11590                         p->next = here;
11591                 }
11592         } else if (n->type == NTOFD || n->type == NFROMFD) {
11593                 fixredir(n, wordtext, 0);
11594         } else {
11595                 n->nfile.fname = makename();
11596         }
11597 }
11598
11599 static union node *
11600 simplecmd(void)
11601 {
11602         union node *args, **app;
11603         union node *n = NULL;
11604         union node *vars, **vpp;
11605         union node **rpp, *redir;
11606         int savecheckkwd;
11607         int savelinno;
11608 #if BASH_TEST2
11609         smallint double_brackets_flag = 0;
11610 #endif
11611         IF_BASH_FUNCTION(smallint function_flag = 0;)
11612
11613         args = NULL;
11614         app = &args;
11615         vars = NULL;
11616         vpp = &vars;
11617         redir = NULL;
11618         rpp = &redir;
11619
11620         savecheckkwd = CHKALIAS;
11621         savelinno = g_parsefile->linno;
11622         for (;;) {
11623                 int t;
11624                 checkkwd = savecheckkwd;
11625                 t = readtoken();
11626                 switch (t) {
11627 #if BASH_FUNCTION
11628                 case TFUNCTION:
11629                         if (peektoken() != TWORD)
11630                                 raise_error_unexpected_syntax(TWORD);
11631                         function_flag = 1;
11632                         break;
11633 #endif
11634 #if BASH_TEST2
11635                 case TAND: /* "&&" */
11636                 case TOR: /* "||" */
11637                         if (!double_brackets_flag) {
11638                                 tokpushback = 1;
11639                                 goto out;
11640                         }
11641                         wordtext = (char *) (t == TAND ? "-a" : "-o");
11642 #endif
11643                 case TWORD:
11644                         n = stzalloc(sizeof(struct narg));
11645                         n->type = NARG;
11646                         /*n->narg.next = NULL; - stzalloc did it */
11647                         n->narg.text = wordtext;
11648 #if BASH_TEST2
11649                         if (strcmp("[[", wordtext) == 0)
11650                                 double_brackets_flag = 1;
11651                         else if (strcmp("]]", wordtext) == 0)
11652                                 double_brackets_flag = 0;
11653 #endif
11654                         n->narg.backquote = backquotelist;
11655                         if (savecheckkwd && isassignment(wordtext)) {
11656                                 *vpp = n;
11657                                 vpp = &n->narg.next;
11658                         } else {
11659                                 *app = n;
11660                                 app = &n->narg.next;
11661                                 savecheckkwd = 0;
11662                         }
11663 #if BASH_FUNCTION
11664                         if (function_flag) {
11665                                 checkkwd = CHKNL | CHKKWD;
11666                                 switch (peektoken()) {
11667                                 case TBEGIN:
11668                                 case TIF:
11669                                 case TCASE:
11670                                 case TUNTIL:
11671                                 case TWHILE:
11672                                 case TFOR:
11673                                         goto do_func;
11674                                 case TLP:
11675                                         function_flag = 0;
11676                                         break;
11677 # if BASH_TEST2
11678                                 case TWORD:
11679                                         if (strcmp("[[", wordtext) == 0)
11680                                                 goto do_func;
11681                                         /* fall through */
11682 # endif
11683                                 default:
11684                                         raise_error_unexpected_syntax(-1);
11685                                 }
11686                         }
11687 #endif
11688                         break;
11689                 case TREDIR:
11690                         *rpp = n = redirnode;
11691                         rpp = &n->nfile.next;
11692                         parsefname();   /* read name of redirection file */
11693                         break;
11694                 case TLP:
11695  IF_BASH_FUNCTION(do_func:)
11696                         if (args && app == &args->narg.next
11697                          && !vars && !redir
11698                         ) {
11699                                 struct builtincmd *bcmd;
11700                                 const char *name;
11701
11702                                 /* We have a function */
11703                                 if (IF_BASH_FUNCTION(!function_flag &&) readtoken() != TRP)
11704                                         raise_error_unexpected_syntax(TRP);
11705                                 name = n->narg.text;
11706                                 if (!goodname(name)
11707                                  || ((bcmd = find_builtin(name)) && IS_BUILTIN_SPECIAL(bcmd))
11708                                 ) {
11709                                         raise_error_syntax("bad function name");
11710                                 }
11711                                 n->type = NDEFUN;
11712                                 checkkwd = CHKNL | CHKKWD | CHKALIAS;
11713                                 n->ndefun.text = n->narg.text;
11714                                 n->ndefun.linno = g_parsefile->linno;
11715                                 n->ndefun.body = parse_command();
11716                                 return n;
11717                         }
11718                         IF_BASH_FUNCTION(function_flag = 0;)
11719                         /* fall through */
11720                 default:
11721                         tokpushback = 1;
11722                         goto out;
11723                 }
11724         }
11725  out:
11726         *app = NULL;
11727         *vpp = NULL;
11728         *rpp = NULL;
11729         n = stzalloc(sizeof(struct ncmd));
11730         if (NCMD != 0)
11731                 n->type = NCMD;
11732         n->ncmd.linno = savelinno;
11733         n->ncmd.args = args;
11734         n->ncmd.assign = vars;
11735         n->ncmd.redirect = redir;
11736         return n;
11737 }
11738
11739 static union node *
11740 parse_command(void)
11741 {
11742         union node *n1, *n2;
11743         union node *ap, **app;
11744         union node *cp, **cpp;
11745         union node *redir, **rpp;
11746         union node **rpp2;
11747         int t;
11748         int savelinno;
11749
11750         redir = NULL;
11751         rpp2 = &redir;
11752
11753         savelinno = g_parsefile->linno;
11754
11755         switch (readtoken()) {
11756         default:
11757                 raise_error_unexpected_syntax(-1);
11758                 /* NOTREACHED */
11759         case TIF:
11760                 n1 = stzalloc(sizeof(struct nif));
11761                 n1->type = NIF;
11762                 n1->nif.test = list(0);
11763                 if (readtoken() != TTHEN)
11764                         raise_error_unexpected_syntax(TTHEN);
11765                 n1->nif.ifpart = list(0);
11766                 n2 = n1;
11767                 while (readtoken() == TELIF) {
11768                         n2->nif.elsepart = stzalloc(sizeof(struct nif));
11769                         n2 = n2->nif.elsepart;
11770                         n2->type = NIF;
11771                         n2->nif.test = list(0);
11772                         if (readtoken() != TTHEN)
11773                                 raise_error_unexpected_syntax(TTHEN);
11774                         n2->nif.ifpart = list(0);
11775                 }
11776                 if (lasttoken == TELSE)
11777                         n2->nif.elsepart = list(0);
11778                 else {
11779                         n2->nif.elsepart = NULL;
11780                         tokpushback = 1;
11781                 }
11782                 t = TFI;
11783                 break;
11784         case TWHILE:
11785         case TUNTIL: {
11786                 int got;
11787                 n1 = stzalloc(sizeof(struct nbinary));
11788                 n1->type = (lasttoken == TWHILE) ? NWHILE : NUNTIL;
11789                 n1->nbinary.ch1 = list(0);
11790                 got = readtoken();
11791                 if (got != TDO) {
11792                         TRACE(("expecting DO got '%s' %s\n", tokname_array[got],
11793                                         got == TWORD ? wordtext : ""));
11794                         raise_error_unexpected_syntax(TDO);
11795                 }
11796                 n1->nbinary.ch2 = list(0);
11797                 t = TDONE;
11798                 break;
11799         }
11800         case TFOR:
11801                 if (readtoken() != TWORD || quoteflag || !goodname(wordtext))
11802                         raise_error_syntax("bad for loop variable");
11803                 n1 = stzalloc(sizeof(struct nfor));
11804                 n1->type = NFOR;
11805                 n1->nfor.linno = savelinno;
11806                 n1->nfor.var = wordtext;
11807                 checkkwd = CHKNL | CHKKWD | CHKALIAS;
11808                 if (readtoken() == TIN) {
11809                         app = &ap;
11810                         while (readtoken() == TWORD) {
11811                                 n2 = stzalloc(sizeof(struct narg));
11812                                 n2->type = NARG;
11813                                 /*n2->narg.next = NULL; - stzalloc did it */
11814                                 n2->narg.text = wordtext;
11815                                 n2->narg.backquote = backquotelist;
11816                                 *app = n2;
11817                                 app = &n2->narg.next;
11818                         }
11819                         *app = NULL;
11820                         n1->nfor.args = ap;
11821                         if (lasttoken != TNL && lasttoken != TSEMI)
11822                                 raise_error_unexpected_syntax(-1);
11823                 } else {
11824                         n2 = stzalloc(sizeof(struct narg));
11825                         n2->type = NARG;
11826                         /*n2->narg.next = NULL; - stzalloc did it */
11827                         n2->narg.text = (char *)dolatstr;
11828                         /*n2->narg.backquote = NULL;*/
11829                         n1->nfor.args = n2;
11830                         /*
11831                          * Newline or semicolon here is optional (but note
11832                          * that the original Bourne shell only allowed NL).
11833                          */
11834                         if (lasttoken != TSEMI)
11835                                 tokpushback = 1;
11836                 }
11837                 checkkwd = CHKNL | CHKKWD | CHKALIAS;
11838                 if (readtoken() != TDO)
11839                         raise_error_unexpected_syntax(TDO);
11840                 n1->nfor.body = list(0);
11841                 t = TDONE;
11842                 break;
11843         case TCASE:
11844                 n1 = stzalloc(sizeof(struct ncase));
11845                 n1->type = NCASE;
11846                 n1->ncase.linno = savelinno;
11847                 if (readtoken() != TWORD)
11848                         raise_error_unexpected_syntax(TWORD);
11849                 n1->ncase.expr = n2 = stzalloc(sizeof(struct narg));
11850                 n2->type = NARG;
11851                 /*n2->narg.next = NULL; - stzalloc did it */
11852                 n2->narg.text = wordtext;
11853                 n2->narg.backquote = backquotelist;
11854                 checkkwd = CHKNL | CHKKWD | CHKALIAS;
11855                 if (readtoken() != TIN)
11856                         raise_error_unexpected_syntax(TIN);
11857                 cpp = &n1->ncase.cases;
11858  next_case:
11859                 checkkwd = CHKNL | CHKKWD;
11860                 t = readtoken();
11861                 while (t != TESAC) {
11862                         if (lasttoken == TLP)
11863                                 readtoken();
11864                         *cpp = cp = stzalloc(sizeof(struct nclist));
11865                         cp->type = NCLIST;
11866                         app = &cp->nclist.pattern;
11867                         for (;;) {
11868                                 *app = ap = stzalloc(sizeof(struct narg));
11869                                 ap->type = NARG;
11870                                 /*ap->narg.next = NULL; - stzalloc did it */
11871                                 ap->narg.text = wordtext;
11872                                 ap->narg.backquote = backquotelist;
11873                                 if (readtoken() != TPIPE)
11874                                         break;
11875                                 app = &ap->narg.next;
11876                                 readtoken();
11877                         }
11878                         //ap->narg.next = NULL;
11879                         if (lasttoken != TRP)
11880                                 raise_error_unexpected_syntax(TRP);
11881                         cp->nclist.body = list(2);
11882
11883                         cpp = &cp->nclist.next;
11884
11885                         checkkwd = CHKNL | CHKKWD;
11886                         t = readtoken();
11887                         if (t != TESAC) {
11888                                 if (t != TENDCASE)
11889                                         raise_error_unexpected_syntax(TENDCASE);
11890                                 goto next_case;
11891                         }
11892                 }
11893                 *cpp = NULL;
11894                 goto redir;
11895         case TLP:
11896                 n1 = stzalloc(sizeof(struct nredir));
11897                 n1->type = NSUBSHELL;
11898                 n1->nredir.linno = savelinno;
11899                 n1->nredir.n = list(0);
11900                 /*n1->nredir.redirect = NULL; - stzalloc did it */
11901                 t = TRP;
11902                 break;
11903         case TBEGIN:
11904                 n1 = list(0);
11905                 t = TEND;
11906                 break;
11907         IF_BASH_FUNCTION(case TFUNCTION:)
11908         case TWORD:
11909         case TREDIR:
11910                 tokpushback = 1;
11911                 return simplecmd();
11912         }
11913
11914         if (readtoken() != t)
11915                 raise_error_unexpected_syntax(t);
11916
11917  redir:
11918         /* Now check for redirection which may follow command */
11919         checkkwd = CHKKWD | CHKALIAS;
11920         rpp = rpp2;
11921         while (readtoken() == TREDIR) {
11922                 *rpp = n2 = redirnode;
11923                 rpp = &n2->nfile.next;
11924                 parsefname();
11925         }
11926         tokpushback = 1;
11927         *rpp = NULL;
11928         if (redir) {
11929                 if (n1->type != NSUBSHELL) {
11930                         n2 = stzalloc(sizeof(struct nredir));
11931                         n2->type = NREDIR;
11932                         n2->nredir.linno = savelinno;
11933                         n2->nredir.n = n1;
11934                         n1 = n2;
11935                 }
11936                 n1->nredir.redirect = redir;
11937         }
11938         return n1;
11939 }
11940
11941 #if BASH_DOLLAR_SQUOTE
11942 static int
11943 decode_dollar_squote(void)
11944 {
11945         static const char C_escapes[] ALIGN1 = "nrbtfav""x\\01234567";
11946         int c, cnt;
11947         char *p;
11948         char buf[4];
11949
11950         c = pgetc();
11951         p = strchr(C_escapes, c);
11952         if (p) {
11953                 buf[0] = c;
11954                 p = buf;
11955                 cnt = 3;
11956                 if ((unsigned char)(c - '0') <= 7) { /* \ooo */
11957                         do {
11958                                 c = pgetc();
11959                                 *++p = c;
11960                         } while ((unsigned char)(c - '0') <= 7 && --cnt);
11961                         pungetc();
11962                 } else if (c == 'x') { /* \xHH */
11963                         do {
11964                                 c = pgetc();
11965                                 *++p = c;
11966                         } while (isxdigit(c) && --cnt);
11967                         pungetc();
11968                         if (cnt == 3) { /* \x but next char is "bad" */
11969                                 c = 'x';
11970                                 goto unrecognized;
11971                         }
11972                 } else { /* simple seq like \\ or \t */
11973                         p++;
11974                 }
11975                 *p = '\0';
11976                 p = buf;
11977                 c = bb_process_escape_sequence((void*)&p);
11978         } else { /* unrecognized "\z": print both chars unless ' or " */
11979                 if (c != '\'' && c != '"') {
11980  unrecognized:
11981                         c |= 0x100; /* "please encode \, then me" */
11982                 }
11983         }
11984         return c;
11985 }
11986 #endif
11987
11988 /* Used by expandstr to get here-doc like behaviour. */
11989 #define FAKEEOFMARK ((char*)(uintptr_t)1)
11990
11991 static ALWAYS_INLINE int
11992 realeofmark(const char *eofmark)
11993 {
11994         return eofmark && eofmark != FAKEEOFMARK;
11995 }
11996
11997 /*
11998  * If eofmark is NULL, read a word or a redirection symbol.  If eofmark
11999  * is not NULL, read a here document.  In the latter case, eofmark is the
12000  * word which marks the end of the document and striptabs is true if
12001  * leading tabs should be stripped from the document.  The argument c
12002  * is the first character of the input token or document.
12003  *
12004  * Because C does not have internal subroutines, I have simulated them
12005  * using goto's to implement the subroutine linkage.  The following macros
12006  * will run code that appears at the end of readtoken1.
12007  */
12008 #define CHECKEND()      {goto checkend; checkend_return:;}
12009 #define PARSEREDIR()    {goto parseredir; parseredir_return:;}
12010 #define PARSESUB()      {goto parsesub; parsesub_return:;}
12011 #define PARSEBACKQOLD() {oldstyle = 1; goto parsebackq; parsebackq_oldreturn:;}
12012 #define PARSEBACKQNEW() {oldstyle = 0; goto parsebackq; parsebackq_newreturn:;}
12013 #define PARSEARITH()    {goto parsearith; parsearith_return:;}
12014 static int
12015 readtoken1(int c, int syntax, char *eofmark, int striptabs)
12016 {
12017         /* NB: syntax parameter fits into smallint */
12018         /* c parameter is an unsigned char or PEOF or PEOA */
12019         char *out;
12020         size_t len;
12021         struct nodelist *bqlist;
12022         smallint quotef;
12023         smallint oldstyle;
12024         smallint pssyntax;   /* we are expanding a prompt string */
12025         IF_BASH_DOLLAR_SQUOTE(smallint bash_dollar_squote = 0;)
12026         /* syntax stack */
12027         struct synstack synbase = { };
12028         struct synstack *synstack = &synbase;
12029
12030 #if ENABLE_ASH_EXPAND_PRMT
12031         pssyntax = (syntax == PSSYNTAX);
12032         if (pssyntax)
12033                 syntax = DQSYNTAX;
12034 #else
12035         pssyntax = 0; /* constant */
12036 #endif
12037         synstack->syntax = syntax;
12038
12039         if (syntax == DQSYNTAX)
12040                 synstack->dblquote = 1;
12041         quotef = 0;
12042         bqlist = NULL;
12043
12044         STARTSTACKSTR(out);
12045  loop:
12046         /* For each line, until end of word */
12047         CHECKEND();     /* set c to PEOF if at end of here document */
12048         for (;;) {      /* until end of line or end of word */
12049                 CHECKSTRSPACE(4, out);  /* permit 4 calls to USTPUTC */
12050                 switch (SIT(c, synstack->syntax)) {
12051                 case CNL:       /* '\n' */
12052                         if (synstack->syntax == BASESYNTAX
12053                          && !synstack->varnest
12054                         ) {
12055                                 goto endword;   /* exit outer loop */
12056                         }
12057                         USTPUTC(c, out);
12058                         nlprompt();
12059                         c = pgetc();
12060                         goto loop;              /* continue outer loop */
12061                 case CWORD:
12062                         USTPUTC(c, out);
12063                         break;
12064                 case CCTL:
12065 #if BASH_DOLLAR_SQUOTE
12066                         if (c == '\\' && bash_dollar_squote) {
12067                                 c = decode_dollar_squote();
12068                                 if (c == '\0') {
12069                                         /* skip $'\000', $'\x00' (like bash) */
12070                                         break;
12071                                 }
12072                                 if (c & 0x100) {
12073                                         /* Unknown escape. Encode as '\z' */
12074                                         c = (unsigned char)c;
12075                                         if (eofmark == NULL || synstack->dblquote)
12076                                                 USTPUTC(CTLESC, out);
12077                                         USTPUTC('\\', out);
12078                                 }
12079                         }
12080 #endif
12081                         if (!eofmark || synstack->dblquote || synstack->varnest)
12082                                 USTPUTC(CTLESC, out);
12083                         USTPUTC(c, out);
12084                         break;
12085                 case CBACK:     /* backslash */
12086                         c = pgetc_without_PEOA();
12087                         if (c == PEOF) {
12088                                 USTPUTC(CTLESC, out);
12089                                 USTPUTC('\\', out);
12090                                 pungetc();
12091                         } else if (c == '\n') {
12092                                 nlprompt();
12093                         } else {
12094                                 if (pssyntax && c == '$') {
12095                                         USTPUTC(CTLESC, out);
12096                                         USTPUTC('\\', out);
12097                                 }
12098                                 /* Backslash is retained if we are in "str"
12099                                  * and next char isn't dquote-special.
12100                                  */
12101                                 if (synstack->dblquote
12102                                  && c != '\\'
12103                                  && c != '`'
12104                                  && c != '$'
12105                                  && (c != '"' || (eofmark != NULL && !synstack->varnest))
12106                                  && (c != '}' || !synstack->varnest)
12107                                 ) {
12108                                         USTPUTC(CTLESC, out); /* protect '\' from glob */
12109                                         USTPUTC('\\', out);
12110                                 }
12111                                 USTPUTC(CTLESC, out);
12112                                 USTPUTC(c, out);
12113                                 quotef = 1;
12114                         }
12115                         break;
12116                 case CSQUOTE:
12117                         synstack->syntax = SQSYNTAX;
12118  quotemark:
12119                         if (eofmark == NULL) {
12120                                 USTPUTC(CTLQUOTEMARK, out);
12121                         }
12122                         break;
12123                 case CDQUOTE:
12124                         synstack->syntax = DQSYNTAX;
12125                         synstack->dblquote = 1;
12126  toggledq:
12127                         if (synstack->varnest)
12128                                 synstack->innerdq ^= 1;
12129                         goto quotemark;
12130                 case CENDQUOTE:
12131                         IF_BASH_DOLLAR_SQUOTE(bash_dollar_squote = 0;)
12132                         if (eofmark != NULL && synstack->varnest == 0) {
12133                                 USTPUTC(c, out);
12134                                 break;
12135                         }
12136
12137                         if (synstack->dqvarnest == 0) {
12138                                 synstack->syntax = BASESYNTAX;
12139                                 synstack->dblquote = 0;
12140                         }
12141
12142                         quotef = 1;
12143
12144                         if (c == '"')
12145                                 goto toggledq;
12146
12147                         goto quotemark;
12148                 case CVAR:      /* '$' */
12149                         PARSESUB();             /* parse substitution */
12150                         break;
12151                 case CENDVAR:   /* '}' */
12152                         if (!synstack->innerdq && synstack->varnest > 0) {
12153                                 if (!--synstack->varnest && synstack->varpushed)
12154                                         synstack_pop(&synstack);
12155                                 else if (synstack->dqvarnest > 0)
12156                                         synstack->dqvarnest--;
12157                                 c = CTLENDVAR;
12158                         }
12159                         USTPUTC(c, out);
12160                         break;
12161 #if ENABLE_FEATURE_SH_MATH
12162                 case CLP:       /* '(' in arithmetic */
12163                         synstack->parenlevel++;
12164                         USTPUTC(c, out);
12165                         break;
12166                 case CRP:       /* ')' in arithmetic */
12167                         if (synstack->parenlevel > 0) {
12168                                 synstack->parenlevel--;
12169                         } else {
12170                                 if (pgetc_eatbnl() == ')') {
12171                                         c = CTLENDARI;
12172                                         synstack_pop(&synstack);
12173                                 } else {
12174                                         /*
12175                                          * unbalanced parens
12176                                          * (don't 2nd guess - no error)
12177                                          */
12178                                         pungetc();
12179                                 }
12180                         }
12181                         USTPUTC(c, out);
12182                         break;
12183 #endif
12184                 case CBQUOTE:   /* '`' */
12185                         if (checkkwd & CHKEOFMARK) {
12186                                 quotef = 1;
12187                                 USTPUTC('`', out);
12188                                 break;
12189                         }
12190
12191                         PARSEBACKQOLD();
12192                         break;
12193                 case CENDFILE:
12194                         goto endword;           /* exit outer loop */
12195                 case CIGN:
12196                         break;
12197                 default:
12198                         if (synstack->varnest == 0) {
12199 #if BASH_REDIR_OUTPUT
12200                                 if (c == '&') {
12201 //Can't call pgetc_eatbnl() here, this requires three-deep pungetc()
12202                                         if (pgetc() == '>')
12203                                                 c = 0x100 + '>'; /* flag &> */
12204                                         pungetc();
12205                                 }
12206 #endif
12207                                 goto endword;   /* exit outer loop */
12208                         }
12209                         IF_ASH_ALIAS(if (c != PEOA))
12210                                 USTPUTC(c, out);
12211                 }
12212                 c = pgetc();
12213         } /* for (;;) */
12214  endword:
12215
12216 #if ENABLE_FEATURE_SH_MATH
12217         if (synstack->syntax == ARISYNTAX)
12218                 raise_error_syntax("missing '))'");
12219 #endif
12220         if (synstack->syntax != BASESYNTAX && eofmark == NULL)
12221                 raise_error_syntax("unterminated quoted string");
12222         if (synstack->varnest != 0) {
12223                 /* { */
12224                 raise_error_syntax("missing '}'");
12225         }
12226         USTPUTC('\0', out);
12227         len = out - (char *)stackblock();
12228         out = stackblock();
12229         if (eofmark == NULL) {
12230                 if ((c == '>' || c == '<' IF_BASH_REDIR_OUTPUT( || c == 0x100 + '>'))
12231                  && quotef == 0
12232                 ) {
12233                         if (isdigit_str9(out)) {
12234                                 PARSEREDIR(); /* passed as params: out, c */
12235                                 lasttoken = TREDIR;
12236                                 return lasttoken;
12237                         }
12238                         /* else: non-number X seen, interpret it
12239                          * as "NNNX>file" = "NNNX >file" */
12240                 }
12241                 pungetc();
12242         }
12243         quoteflag = quotef;
12244         backquotelist = bqlist;
12245         grabstackblock(len);
12246         wordtext = out;
12247         lasttoken = TWORD;
12248         return lasttoken;
12249 /* end of readtoken routine */
12250
12251 /*
12252  * Check to see whether we are at the end of the here document.  When this
12253  * is called, c is set to the first character of the next input line.  If
12254  * we are at the end of the here document, this routine sets the c to PEOF.
12255  */
12256 checkend: {
12257         if (realeofmark(eofmark)) {
12258                 int markloc;
12259                 char *p;
12260
12261 #if ENABLE_ASH_ALIAS
12262                 if (c == PEOA)
12263                         c = pgetc_without_PEOA();
12264 #endif
12265                 if (striptabs) {
12266                         while (c == '\t') {
12267                                 c = pgetc_without_PEOA();
12268                         }
12269                 }
12270
12271                 markloc = out - (char *)stackblock();
12272                 for (p = eofmark; STPUTC(c, out), *p; p++) {
12273                         if (c != *p)
12274                                 goto more_heredoc;
12275
12276                         c = pgetc_without_PEOA();
12277                 }
12278
12279                 if (c == '\n' || c == PEOF) {
12280                         c = PEOF;
12281                         g_parsefile->linno++;
12282                         needprompt = doprompt;
12283                 } else {
12284                         int len_here;
12285
12286  more_heredoc:
12287                         p = (char *)stackblock() + markloc + 1;
12288                         len_here = out - p;
12289
12290                         if (len_here) {
12291                                 len_here -= (c >= PEOF);
12292                                 c = p[-1];
12293
12294                                 if (len_here) {
12295                                         char *str;
12296
12297                                         str = alloca(len_here + 1);
12298                                         *(char *)mempcpy(str, p, len_here) = '\0';
12299
12300                                         pushstring(str, NULL);
12301                                 }
12302                         }
12303                 }
12304
12305                 STADJUST((char *)stackblock() + markloc - out, out);
12306         }
12307         goto checkend_return;
12308 }
12309
12310 /*
12311  * Parse a redirection operator.  The variable "out" points to a string
12312  * specifying the fd to be redirected.  The variable "c" contains the
12313  * first character of the redirection operator.
12314  */
12315 parseredir: {
12316         /* out is already checked to be a valid number or "" */
12317         int fd = (*out == '\0' ? -1 : atoi(out));
12318         union node *np;
12319
12320         np = stzalloc(sizeof(struct nfile));
12321         if (c == '>') {
12322                 np->nfile.fd = 1;
12323                 c = pgetc_eatbnl();
12324                 if (c == '>')
12325                         np->type = NAPPEND;
12326                 else if (c == '|')
12327                         np->type = NCLOBBER;
12328                 else if (c == '&')
12329                         np->type = NTOFD;
12330                         /* it also can be NTO2 (>&file), but we can't figure it out yet */
12331                 else {
12332                         np->type = NTO;
12333                         pungetc();
12334                 }
12335         }
12336 #if BASH_REDIR_OUTPUT
12337         else if (c == 0x100 + '>') { /* this flags &> redirection */
12338                 np->nfile.fd = 1;
12339                 pgetc(); /* this is '>', no need to check */
12340                 np->type = NTO2;
12341         }
12342 #endif
12343         else { /* c == '<' */
12344                 /*np->nfile.fd = 0; - stzalloc did it */
12345                 c = pgetc_eatbnl();
12346                 switch (c) {
12347                 case '<':
12348                         if (sizeof(struct nfile) != sizeof(struct nhere)) {
12349                                 np = stzalloc(sizeof(struct nhere));
12350                                 /*np->nfile.fd = 0; - stzalloc did it */
12351                         }
12352                         np->type = NHERE;
12353                         heredoc = stzalloc(sizeof(struct heredoc));
12354                         heredoc->here = np;
12355                         c = pgetc_eatbnl();
12356                         if (c == '-') {
12357                                 heredoc->striptabs = 1;
12358                         } else {
12359                                 /*heredoc->striptabs = 0; - stzalloc did it */
12360                                 pungetc();
12361                         }
12362                         break;
12363
12364                 case '&':
12365                         np->type = NFROMFD;
12366                         break;
12367
12368                 case '>':
12369                         np->type = NFROMTO;
12370                         break;
12371
12372                 default:
12373                         np->type = NFROM;
12374                         pungetc();
12375                         break;
12376                 }
12377         }
12378         if (fd >= 0)
12379                 np->nfile.fd = fd;
12380         redirnode = np;
12381         goto parseredir_return;
12382 }
12383
12384 /*
12385  * Parse a substitution.  At this point, we have read the dollar sign
12386  * and nothing else.
12387  */
12388
12389 /* is_special(c) evaluates to 1 for c in "!#$*-0123456789?@"; 0 otherwise
12390  * (assuming ascii char codes, as the original implementation did) */
12391 #define is_special(c) \
12392         (((unsigned)(c) - 33 < 32) \
12393                         && ((0xc1ff920dU >> ((unsigned)(c) - 33)) & 1))
12394 parsesub: {
12395         unsigned char subtype;
12396         int typeloc;
12397
12398         c = pgetc_eatbnl();
12399         if ((checkkwd & CHKEOFMARK)
12400          || c > 255 /* PEOA or PEOF */
12401          || (c != '(' && c != '{' && !is_name(c) && !is_special(c))
12402         ) {
12403 #if BASH_DOLLAR_SQUOTE
12404                 if (synstack->syntax != DQSYNTAX && c == '\'')
12405                         bash_dollar_squote = 1;
12406                 else
12407 #endif
12408                         USTPUTC('$', out);
12409                 pungetc();
12410         } else if (c == '(') {
12411                 /* $(command) or $((arith)) */
12412                 if (pgetc_eatbnl() == '(') {
12413 #if ENABLE_FEATURE_SH_MATH
12414                         PARSEARITH();
12415 #else
12416                         raise_error_syntax("support for $((arith)) is disabled");
12417 #endif
12418                 } else {
12419                         pungetc();
12420                         PARSEBACKQNEW();
12421                 }
12422         } else {
12423                 /* $VAR, $<specialchar>, ${...}, or PEOA/PEOF */
12424                 smalluint newsyn = synstack->syntax;
12425
12426                 USTPUTC(CTLVAR, out);
12427                 typeloc = out - (char *)stackblock();
12428                 STADJUST(1, out);
12429                 subtype = VSNORMAL;
12430                 if (c == '{') {
12431                         c = pgetc_eatbnl();
12432                         subtype = 0;
12433                 }
12434  varname:
12435                 if (is_name(c)) {
12436                         /* $[{[#]]NAME[}] */
12437                         do {
12438                                 STPUTC(c, out);
12439                                 c = pgetc_eatbnl();
12440                         } while (is_in_name(c));
12441                 } else if (isdigit(c)) {
12442                         /* $[{[#]]NUM[}] */
12443                         do {
12444                                 STPUTC(c, out);
12445                                 c = pgetc_eatbnl();
12446                         } while (isdigit(c));
12447                 } else if (c != '}') {
12448                         /* $[{[#]]<specialchar>[}] */
12449                         int cc = c;
12450
12451                         c = pgetc_eatbnl();
12452                         if (!subtype && cc == '#') {
12453                                 subtype = VSLENGTH;
12454                                 if (c == '_' || isalnum(c))
12455                                         goto varname;
12456                                 cc = c;
12457                                 c = pgetc_eatbnl();
12458                                 if (cc == '}' || c != '}') {
12459                                         pungetc();
12460                                         subtype = 0;
12461                                         c = cc;
12462                                         cc = '#';
12463                                 }
12464                         }
12465
12466                         if (!is_special(cc)) {
12467                                 if (subtype == VSLENGTH)
12468                                         subtype = 0;
12469                                 goto badsub;
12470                         }
12471
12472                         USTPUTC(cc, out);
12473                 } else
12474                         goto badsub;
12475
12476                 if (c != '}' && subtype == VSLENGTH) {
12477                         /* ${#VAR didn't end with } */
12478                         goto badsub;
12479                 }
12480
12481                 if (subtype == 0) {
12482                         static const char types[] ALIGN1 = "}-+?=";
12483                         /* ${VAR...} but not $VAR or ${#VAR} */
12484                         /* c == first char after VAR */
12485                         int cc = c;
12486
12487                         switch (c) {
12488                         case ':':
12489                                 c = pgetc_eatbnl();
12490 #if BASH_SUBSTR
12491                                 /* This check is only needed to not misinterpret
12492                                  * ${VAR:-WORD}, ${VAR:+WORD}, ${VAR:=WORD}, ${VAR:?WORD}
12493                                  * constructs.
12494                                  */
12495                                 if (!strchr(types, c)) {
12496                                         subtype = VSSUBSTR;
12497                                         pungetc();
12498                                         break; /* "goto badsub" is bigger (!) */
12499                                 }
12500 #endif
12501                                 subtype = VSNUL;
12502                                 /*FALLTHROUGH*/
12503                         default: {
12504                                 const char *p = strchr(types, c);
12505                                 if (p == NULL)
12506                                         break;
12507                                 subtype |= p - types + VSNORMAL;
12508                                 break;
12509                         }
12510                         case '%':
12511                         case '#':
12512                                 subtype = (c == '#' ? VSTRIMLEFT : VSTRIMRIGHT);
12513                                 c = pgetc_eatbnl();
12514                                 if (c == cc)
12515                                         subtype++;
12516                                 else
12517                                         pungetc();
12518
12519                                 newsyn = BASESYNTAX;
12520                                 break;
12521 #if BASH_PATTERN_SUBST
12522                         case '/':
12523                                 /* ${v/[/]pattern/repl} */
12524 //TODO: encode pattern and repl separately.
12525 // Currently cases like: v=1;echo ${v/$((1/1))/ONE}
12526 // are broken (should print "ONE")
12527                                 subtype = VSREPLACE;
12528                                 newsyn = BASESYNTAX;
12529                                 c = pgetc_eatbnl();
12530                                 if (c != '/')
12531                                         goto badsub;
12532                                 subtype++; /* VSREPLACEALL */
12533                                 break;
12534 #endif
12535                         }
12536                 } else {
12537  badsub:
12538                         pungetc();
12539                 }
12540
12541                 if (newsyn == ARISYNTAX)
12542                         newsyn = DQSYNTAX;
12543
12544                 if ((newsyn != synstack->syntax || synstack->innerdq)
12545                  && subtype != VSNORMAL
12546                 ) {
12547                         synstack_push(&synstack,
12548                                 synstack->prev ?: alloca(sizeof(*synstack)),
12549                                 newsyn);
12550
12551                         synstack->varpushed = 1;
12552                         synstack->dblquote = newsyn != BASESYNTAX;
12553                 }
12554
12555                 ((unsigned char *)stackblock())[typeloc] = subtype;
12556                 if (subtype != VSNORMAL) {
12557                         synstack->varnest++;
12558                         if (synstack->dblquote)
12559                                 synstack->dqvarnest++;
12560                 }
12561                 STPUTC('=', out);
12562         }
12563         goto parsesub_return;
12564 }
12565
12566 /*
12567  * Called to parse command substitutions.  Newstyle is set if the command
12568  * is enclosed inside $(...); nlpp is a pointer to the head of the linked
12569  * list of commands (passed by reference), and savelen is the number of
12570  * characters on the top of the stack which must be preserved.
12571  */
12572 parsebackq: {
12573         struct nodelist **nlpp;
12574         union node *n;
12575         char *str;
12576         size_t savelen;
12577         smallint saveprompt = 0;
12578
12579         str = NULL;
12580         savelen = out - (char *)stackblock();
12581         if (savelen > 0) {
12582                 /*
12583                  * FIXME: this can allocate very large block on stack and SEGV.
12584                  * Example:
12585                  * echo "..<100kbytes>..`true` $(true) `true` ..."
12586                  * allocates 100kb for every command subst. With about
12587                  * a hundred command substitutions stack overflows.
12588                  * With larger prepended string, SEGV happens sooner.
12589                  */
12590                 str = alloca(savelen);
12591                 memcpy(str, stackblock(), savelen);
12592         }
12593
12594         if (oldstyle) {
12595                 /* We must read until the closing backquote, giving special
12596                  * treatment to some slashes, and then push the string and
12597                  * reread it as input, interpreting it normally.
12598                  */
12599                 char *pout;
12600                 size_t psavelen;
12601                 char *pstr;
12602
12603                 STARTSTACKSTR(pout);
12604                 for (;;) {
12605                         int pc;
12606
12607                         setprompt_if(needprompt, 2);
12608                         pc = pgetc_eatbnl();
12609                         switch (pc) {
12610                         case '`':
12611                                 goto done;
12612
12613                         case '\\':
12614                                 pc = pgetc(); /* or pgetc_eatbnl()? why (example)? */
12615                                 if (pc != '\\' && pc != '`' && pc != '$'
12616                                  && (!synstack->dblquote || pc != '"')
12617                                 ) {
12618                                         STPUTC('\\', pout);
12619                                 }
12620                                 if (pc <= 255 /* not PEOA or PEOF */) {
12621                                         break;
12622                                 }
12623                                 /* fall through */
12624
12625                         case PEOF:
12626                         IF_ASH_ALIAS(case PEOA:)
12627                                 raise_error_syntax("EOF in backquote substitution");
12628
12629                         case '\n':
12630                                 nlnoprompt();
12631                                 break;
12632
12633                         default:
12634                                 break;
12635                         }
12636                         STPUTC(pc, pout);
12637                 }
12638  done:
12639                 STPUTC('\0', pout);
12640                 psavelen = pout - (char *)stackblock();
12641                 if (psavelen > 0) {
12642                         pstr = grabstackstr(pout);
12643                         setinputstring(pstr);
12644                 }
12645         }
12646         nlpp = &bqlist;
12647         while (*nlpp)
12648                 nlpp = &(*nlpp)->next;
12649         *nlpp = stzalloc(sizeof(**nlpp));
12650         /* (*nlpp)->next = NULL; - stzalloc did it */
12651
12652         if (oldstyle) {
12653                 saveprompt = doprompt;
12654                 doprompt = 0;
12655         }
12656
12657         n = list(2);
12658
12659         if (oldstyle)
12660                 doprompt = saveprompt;
12661         else if (readtoken() != TRP)
12662                 raise_error_unexpected_syntax(TRP);
12663
12664         (*nlpp)->n = n;
12665         if (oldstyle) {
12666                 /*
12667                  * Start reading from old file again, ignoring any pushed back
12668                  * tokens left from the backquote parsing
12669                  */
12670                 popfile();
12671                 tokpushback = 0;
12672         }
12673         while (stackblocksize() <= savelen)
12674                 growstackblock();
12675         STARTSTACKSTR(out);
12676         if (str) {
12677                 memcpy(out, str, savelen);
12678                 STADJUST(savelen, out);
12679         }
12680         USTPUTC(CTLBACKQ, out);
12681         if (oldstyle)
12682                 goto parsebackq_oldreturn;
12683         goto parsebackq_newreturn;
12684 }
12685
12686 #if ENABLE_FEATURE_SH_MATH
12687 /*
12688  * Parse an arithmetic expansion (indicate start of one and set state)
12689  */
12690 parsearith: {
12691
12692         synstack_push(&synstack,
12693                         synstack->prev ?: alloca(sizeof(*synstack)),
12694                         ARISYNTAX);
12695         synstack->dblquote = 1;
12696         USTPUTC(CTLARI, out);
12697         goto parsearith_return;
12698 }
12699 #endif
12700 } /* end of readtoken */
12701
12702 /*
12703  * Read the next input token.
12704  * If the token is a word, we set backquotelist to the list of cmds in
12705  *      backquotes.  We set quoteflag to true if any part of the word was
12706  *      quoted.
12707  * If the token is TREDIR, then we set redirnode to a structure containing
12708  *      the redirection.
12709  *
12710  * [Change comment:  here documents and internal procedures]
12711  * [Readtoken shouldn't have any arguments.  Perhaps we should make the
12712  *  word parsing code into a separate routine.  In this case, readtoken
12713  *  doesn't need to have any internal procedures, but parseword does.
12714  *  We could also make parseoperator in essence the main routine, and
12715  *  have parseword (readtoken1?) handle both words and redirection.]
12716  */
12717 #define NEW_xxreadtoken
12718 #ifdef NEW_xxreadtoken
12719 /* singles must be first! */
12720 static const char xxreadtoken_chars[7] ALIGN1 = {
12721         '\n', '(', ')', /* singles */
12722         '&', '|', ';',  /* doubles */
12723         0
12724 };
12725
12726 #define xxreadtoken_singles 3
12727 #define xxreadtoken_doubles 3
12728
12729 static const char xxreadtoken_tokens[] ALIGN1 = {
12730         TNL, TLP, TRP,          /* only single occurrence allowed */
12731         TBACKGND, TPIPE, TSEMI, /* if single occurrence */
12732         TEOF,                   /* corresponds to trailing nul */
12733         TAND, TOR, TENDCASE     /* if double occurrence */
12734 };
12735
12736 static int
12737 xxreadtoken(void)
12738 {
12739         int c;
12740
12741         if (tokpushback) {
12742                 tokpushback = 0;
12743                 return lasttoken;
12744         }
12745         setprompt_if(needprompt, 2);
12746         for (;;) {                      /* until token or start of word found */
12747                 c = pgetc_eatbnl();
12748                 if (c == ' ' || c == '\t' IF_ASH_ALIAS( || c == PEOA))
12749                         continue;
12750
12751                 if (c == '#') {
12752                         while ((c = pgetc()) != '\n' && c != PEOF)
12753                                 continue;
12754                         pungetc();
12755                 } else if (c == '\\') {
12756                         break; /* return readtoken1(...) */
12757                 } else {
12758                         const char *p;
12759
12760                         p = xxreadtoken_chars + sizeof(xxreadtoken_chars) - 1;
12761                         if (c != PEOF) {
12762                                 if (c == '\n') {
12763                                         nlnoprompt();
12764                                 }
12765
12766                                 p = strchr(xxreadtoken_chars, c);
12767                                 if (p == NULL)
12768                                         break; /* return readtoken1(...) */
12769
12770                                 if ((int)(p - xxreadtoken_chars) >= xxreadtoken_singles) {
12771                                         int cc = pgetc_eatbnl();
12772                                         if (cc == c) {    /* double occurrence? */
12773                                                 p += xxreadtoken_doubles + 1;
12774                                         } else {
12775                                                 pungetc();
12776 #if BASH_REDIR_OUTPUT
12777                                                 if (c == '&' && cc == '>') /* &> */
12778                                                         break; /* return readtoken1(...) */
12779 #endif
12780                                         }
12781                                 }
12782                         }
12783                         lasttoken = xxreadtoken_tokens[p - xxreadtoken_chars];
12784                         return lasttoken;
12785                 }
12786         } /* for (;;) */
12787
12788         return readtoken1(c, BASESYNTAX, (char *) NULL, 0);
12789 }
12790 #else /* old xxreadtoken */
12791 #define RETURN(token)   return lasttoken = token
12792 static int
12793 xxreadtoken(void)
12794 {
12795         int c;
12796
12797         if (tokpushback) {
12798                 tokpushback = 0;
12799                 return lasttoken;
12800         }
12801         setprompt_if(needprompt, 2);
12802         for (;;) {      /* until token or start of word found */
12803                 c = pgetc_eatbnl();
12804                 switch (c) {
12805                 case ' ': case '\t':
12806                 IF_ASH_ALIAS(case PEOA:)
12807                         continue;
12808                 case '#':
12809                         while ((c = pgetc()) != '\n' && c != PEOF)
12810                                 continue;
12811                         pungetc();
12812                         continue;
12813                 case '\n':
12814                         nlnoprompt();
12815                         RETURN(TNL);
12816                 case PEOF:
12817                         RETURN(TEOF);
12818                 case '&':
12819                         if (pgetc_eatbnl() == '&')
12820                                 RETURN(TAND);
12821                         pungetc();
12822                         RETURN(TBACKGND);
12823                 case '|':
12824                         if (pgetc_eatbnl() == '|')
12825                                 RETURN(TOR);
12826                         pungetc();
12827                         RETURN(TPIPE);
12828                 case ';':
12829                         if (pgetc_eatbnl() == ';')
12830                                 RETURN(TENDCASE);
12831                         pungetc();
12832                         RETURN(TSEMI);
12833                 case '(':
12834                         RETURN(TLP);
12835                 case ')':
12836                         RETURN(TRP);
12837                 }
12838                 break;
12839         }
12840         return readtoken1(c, BASESYNTAX, (char *)NULL, 0);
12841 #undef RETURN
12842 }
12843 #endif /* old xxreadtoken */
12844
12845 static int
12846 readtoken(void)
12847 {
12848         int t;
12849         int kwd = checkkwd;
12850 #if DEBUG
12851         smallint alreadyseen = tokpushback;
12852 #endif
12853
12854 #if ENABLE_ASH_ALIAS
12855  top:
12856 #endif
12857
12858         t = xxreadtoken();
12859
12860         /*
12861          * eat newlines
12862          */
12863         if (kwd & CHKNL) {
12864                 while (t == TNL) {
12865                         parseheredoc();
12866                         t = xxreadtoken();
12867                 }
12868         }
12869
12870         if (t != TWORD || quoteflag) {
12871                 goto out;
12872         }
12873
12874         /*
12875          * check for keywords
12876          */
12877         if (kwd & CHKKWD) {
12878                 const char *const *pp;
12879
12880                 pp = findkwd(wordtext);
12881                 if (pp) {
12882                         lasttoken = t = pp - tokname_array;
12883                         TRACE(("keyword '%s' recognized\n", tokname_array[t]));
12884                         goto out;
12885                 }
12886         }
12887
12888         if (checkkwd & CHKALIAS) {
12889 #if ENABLE_ASH_ALIAS
12890                 struct alias *ap;
12891                 ap = lookupalias(wordtext, 1);
12892                 if (ap != NULL) {
12893                         if (*ap->val) {
12894                                 pushstring(ap->val, ap);
12895                         }
12896                         goto top;
12897                 }
12898 #endif
12899         }
12900  out:
12901         checkkwd = 0;
12902 #if DEBUG
12903         if (!alreadyseen)
12904                 TRACE(("token '%s' %s\n", tokname_array[t], t == TWORD ? wordtext : ""));
12905         else
12906                 TRACE(("reread token '%s' %s\n", tokname_array[t], t == TWORD ? wordtext : ""));
12907 #endif
12908         return t;
12909 }
12910
12911 static int
12912 peektoken(void)
12913 {
12914         int t;
12915
12916         t = readtoken();
12917         tokpushback = 1;
12918         return t;
12919 }
12920
12921 /*
12922  * Read and parse a command.  Returns NODE_EOF on end of file.
12923  * (NULL is a valid parse tree indicating a blank line.)
12924  */
12925 static union node *
12926 parsecmd(int interact)
12927 {
12928         tokpushback = 0;
12929         checkkwd = 0;
12930         heredoclist = 0;
12931         doprompt = interact;
12932         setprompt_if(doprompt, doprompt);
12933         needprompt = 0;
12934         return list(1);
12935 }
12936
12937 /*
12938  * Input any here documents.
12939  */
12940 static void
12941 parseheredoc(void)
12942 {
12943         struct heredoc *here;
12944         union node *n;
12945
12946         here = heredoclist;
12947         heredoclist = NULL;
12948
12949         while (here) {
12950                 tokpushback = 0;
12951                 setprompt_if(needprompt, 2);
12952                 readtoken1(pgetc(), here->here->type == NHERE ? SQSYNTAX : DQSYNTAX,
12953                                 here->eofmark, here->striptabs);
12954                 n = stzalloc(sizeof(struct narg));
12955                 n->narg.type = NARG;
12956                 /*n->narg.next = NULL; - stzalloc did it */
12957                 n->narg.text = wordtext;
12958                 n->narg.backquote = backquotelist;
12959                 here->here->nhere.doc = n;
12960                 here = here->next;
12961         }
12962 }
12963
12964
12965 static const char *
12966 expandstr(const char *ps, int syntax_type)
12967 {
12968         union node n;
12969         int saveprompt;
12970
12971         /* XXX Fix (char *) cast. */
12972         setinputstring((char *)ps);
12973
12974         saveprompt = doprompt;
12975         doprompt = 0;
12976
12977         /* readtoken1() might die horribly.
12978          * Try a prompt with syntactically wrong command:
12979          * PS1='$(date "+%H:%M:%S) > '
12980          */
12981         {
12982                 volatile int saveint;
12983                 struct jmploc *volatile savehandler = exception_handler;
12984                 struct jmploc jmploc;
12985                 SAVE_INT(saveint);
12986                 if (setjmp(jmploc.loc) == 0) {
12987                         exception_handler = &jmploc;
12988                         readtoken1(pgetc(), syntax_type, FAKEEOFMARK, 0);
12989                 }
12990                 exception_handler = savehandler;
12991                 RESTORE_INT(saveint);
12992         }
12993
12994         doprompt = saveprompt;
12995
12996         popfile();
12997
12998         n.narg.type = NARG;
12999         n.narg.next = NULL;
13000         n.narg.text = wordtext;
13001         n.narg.backquote = backquotelist;
13002
13003         expandarg(&n, NULL, EXP_QUOTED);
13004         return stackblock();
13005 }
13006
13007 static inline int
13008 parser_eof(void)
13009 {
13010         return tokpushback && lasttoken == TEOF;
13011 }
13012
13013 /*
13014  * Execute a command or commands contained in a string.
13015  */
13016 static int
13017 evalstring(char *s, int flags)
13018 {
13019         struct jmploc *volatile savehandler;
13020         struct jmploc jmploc;
13021         int ex;
13022
13023         union node *n;
13024         struct stackmark smark;
13025         int status;
13026
13027         s = sstrdup(s);
13028         setinputstring(s);
13029         setstackmark(&smark);
13030
13031         status = 0;
13032         /* On exception inside execution loop, we must popfile().
13033          * Try interactively:
13034          *      readonly a=a
13035          *      command eval "a=b"  # throws "is read only" error
13036          * "command BLTIN" is not supposed to abort (even in non-interactive use).
13037          * But if we skip popfile(), we hit EOF in eval's string, and exit.
13038          */
13039         savehandler = exception_handler;
13040         ex = setjmp(jmploc.loc);
13041         if (ex)
13042                 goto out;
13043         exception_handler = &jmploc;
13044
13045         while ((n = parsecmd(0)) != NODE_EOF) {
13046                 int i;
13047
13048                 i = evaltree(n, flags & ~(parser_eof() ? 0 : EV_EXIT));
13049                 if (n)
13050                         status = i;
13051                 popstackmark(&smark);
13052                 if (evalskip)
13053                         break;
13054         }
13055  out:
13056         popstackmark(&smark);
13057         popfile();
13058         stunalloc(s);
13059
13060         exception_handler = savehandler;
13061         if (ex)
13062                 longjmp(exception_handler->loc, ex);
13063
13064         return status;
13065 }
13066
13067 /*
13068  * The eval command.
13069  */
13070 static int FAST_FUNC
13071 evalcmd(int argc UNUSED_PARAM, char **argv, int flags)
13072 {
13073         char *p;
13074         char *concat;
13075
13076         if (argv[1]) {
13077                 p = argv[1];
13078                 argv += 2;
13079                 if (argv[0]) {
13080                         STARTSTACKSTR(concat);
13081                         for (;;) {
13082                                 concat = stack_putstr(p, concat);
13083                                 p = *argv++;
13084                                 if (p == NULL)
13085                                         break;
13086                                 STPUTC(' ', concat);
13087                         }
13088                         STPUTC('\0', concat);
13089                         p = grabstackstr(concat);
13090                 }
13091                 return evalstring(p, flags & EV_TESTED);
13092         }
13093         return 0;
13094 }
13095
13096 /*
13097  * Read and execute commands.
13098  * "Top" is nonzero for the top level command loop;
13099  * it turns on prompting if the shell is interactive.
13100  */
13101 static int
13102 cmdloop(int top)
13103 {
13104         union node *n;
13105         struct stackmark smark;
13106         int inter;
13107         int status = 0;
13108         int numeof = 0;
13109
13110         TRACE(("cmdloop(%d) called\n", top));
13111         for (;;) {
13112                 int skip;
13113
13114                 setstackmark(&smark);
13115 #if JOBS
13116                 if (doing_jobctl)
13117                         showjobs(SHOW_CHANGED|SHOW_STDERR);
13118 #endif
13119                 inter = 0;
13120                 if (iflag && top) {
13121                         inter++;
13122                         chkmail();
13123                 }
13124                 n = parsecmd(inter);
13125 #if DEBUG
13126                 if (DEBUG > 2 && debug && (n != NODE_EOF))
13127                         showtree(n);
13128 #endif
13129                 if (n == NODE_EOF) {
13130                         if (!top || numeof >= 50)
13131                                 break;
13132                         if (!stoppedjobs()) {
13133                                 if (!Iflag)
13134                                         break;
13135                                 out2str("\nUse \"exit\" to leave shell.\n");
13136                         }
13137                         numeof++;
13138                 } else if (nflag == 0) {
13139                         int i;
13140
13141                         /* job_warning can only be 2,1,0. Here 2->1, 1/0->0 */
13142                         job_warning >>= 1;
13143                         numeof = 0;
13144                         i = evaltree(n, 0);
13145                         if (n)
13146                                 status = i;
13147                 }
13148                 popstackmark(&smark);
13149                 skip = evalskip;
13150
13151                 if (skip) {
13152                         evalskip &= ~SKIPFUNC;
13153                         break;
13154                 }
13155         }
13156         return status;
13157 }
13158
13159 /*
13160  * Take commands from a file.  To be compatible we should do a path
13161  * search for the file, which is necessary to find sub-commands.
13162  */
13163 static char *
13164 find_dot_file(char *name)
13165 {
13166         char *fullname;
13167         const char *path = pathval();
13168         struct stat statb;
13169
13170         /* don't try this for absolute or relative paths */
13171         if (strchr(name, '/'))
13172                 return name;
13173
13174         while ((fullname = path_advance(&path, name)) != NULL) {
13175                 if ((stat(fullname, &statb) == 0) && S_ISREG(statb.st_mode)) {
13176                         /*
13177                          * Don't bother freeing here, since it will
13178                          * be freed by the caller.
13179                          */
13180                         return fullname;
13181                 }
13182                 if (fullname != name)
13183                         stunalloc(fullname);
13184         }
13185         /* not found in PATH */
13186
13187 #if ENABLE_ASH_BASH_SOURCE_CURDIR
13188         return name;
13189 #else
13190         ash_msg_and_raise_error("%s: not found", name);
13191         /* NOTREACHED */
13192 #endif
13193 }
13194
13195 static int FAST_FUNC
13196 dotcmd(int argc_ UNUSED_PARAM, char **argv_ UNUSED_PARAM)
13197 {
13198         /* "false; . empty_file; echo $?" should print 0, not 1: */
13199         int status = 0;
13200         char *fullname;
13201         char **argv;
13202         char *args_need_save;
13203         volatile struct shparam saveparam;
13204
13205 //???
13206 //      struct strlist *sp;
13207 //      for (sp = cmdenviron; sp; sp = sp->next)
13208 //              setvareq(ckstrdup(sp->text), VSTRFIXED | VTEXTFIXED);
13209
13210         nextopt(nullstr); /* handle possible "--" */
13211         argv = argptr;
13212
13213         if (!argv[0]) {
13214                 /* bash says: "bash: .: filename argument required" */
13215                 return 2; /* bash compat */
13216         }
13217
13218         /* This aborts if file isn't found, which is POSIXly correct.
13219          * bash returns exitcode 1 instead.
13220          */
13221         fullname = find_dot_file(argv[0]);
13222         argv++;
13223         args_need_save = argv[0];
13224         if (args_need_save) { /* ". FILE ARGS", and ARGS are not empty */
13225                 int argc;
13226                 saveparam = shellparam;
13227                 shellparam.malloced = 0;
13228                 argc = 1;
13229                 while (argv[argc])
13230                         argc++;
13231                 shellparam.nparam = argc;
13232                 shellparam.p = argv;
13233         };
13234
13235         /* This aborts if file can't be opened, which is POSIXly correct.
13236          * bash returns exitcode 1 instead.
13237          */
13238         setinputfile(fullname, INPUT_PUSH_FILE);
13239         commandname = fullname;
13240         status = cmdloop(0);
13241         popfile();
13242
13243         if (args_need_save) {
13244                 freeparam(&shellparam);
13245                 shellparam = saveparam;
13246         };
13247
13248         return status;
13249 }
13250
13251 static int FAST_FUNC
13252 exitcmd(int argc UNUSED_PARAM, char **argv)
13253 {
13254         if (stoppedjobs())
13255                 return 0;
13256         if (argv[1])
13257                 exitstatus = number(argv[1]);
13258         raise_exception(EXEXIT);
13259         /* NOTREACHED */
13260 }
13261
13262 /*
13263  * Read a file containing shell functions.
13264  */
13265 static void
13266 readcmdfile(char *name)
13267 {
13268         setinputfile(name, INPUT_PUSH_FILE);
13269         cmdloop(0);
13270         popfile();
13271 }
13272
13273
13274 /* ============ find_command inplementation */
13275
13276 /*
13277  * Resolve a command name.  If you change this routine, you may have to
13278  * change the shellexec routine as well.
13279  */
13280 static void
13281 find_command(char *name, struct cmdentry *entry, int act, const char *path)
13282 {
13283         struct tblentry *cmdp;
13284         int idx;
13285         int prev;
13286         char *fullname;
13287         struct stat statb;
13288         int e;
13289         int updatetbl;
13290         struct builtincmd *bcmd;
13291
13292         /* If name contains a slash, don't use PATH or hash table */
13293         if (strchr(name, '/') != NULL) {
13294                 entry->u.index = -1;
13295                 if (act & DO_ABS) {
13296                         while (stat(name, &statb) < 0) {
13297 #ifdef SYSV
13298                                 if (errno == EINTR)
13299                                         continue;
13300 #endif
13301                                 entry->cmdtype = CMDUNKNOWN;
13302                                 return;
13303                         }
13304                 }
13305                 entry->cmdtype = CMDNORMAL;
13306                 return;
13307         }
13308
13309 /* #if ENABLE_FEATURE_SH_STANDALONE... moved after builtin check */
13310
13311         updatetbl = (path == pathval());
13312         if (!updatetbl) {
13313                 act |= DO_ALTPATH;
13314                 if (strstr(path, "%builtin") != NULL)
13315                         act |= DO_ALTBLTIN;
13316         }
13317
13318         /* If name is in the table, check answer will be ok */
13319         cmdp = cmdlookup(name, 0);
13320         if (cmdp != NULL) {
13321                 int bit;
13322
13323                 switch (cmdp->cmdtype) {
13324                 default:
13325 #if DEBUG
13326                         abort();
13327 #endif
13328                 case CMDNORMAL:
13329                         bit = DO_ALTPATH;
13330                         break;
13331                 case CMDFUNCTION:
13332                         bit = DO_NOFUNC;
13333                         break;
13334                 case CMDBUILTIN:
13335                         bit = DO_ALTBLTIN;
13336                         break;
13337                 }
13338                 if (act & bit) {
13339                         updatetbl = 0;
13340                         cmdp = NULL;
13341                 } else if (cmdp->rehash == 0)
13342                         /* if not invalidated by cd, we're done */
13343                         goto success;
13344         }
13345
13346         /* If %builtin not in path, check for builtin next */
13347         bcmd = find_builtin(name);
13348         if (bcmd) {
13349                 if (IS_BUILTIN_REGULAR(bcmd))
13350                         goto builtin_success;
13351                 if (act & DO_ALTPATH) {
13352                         if (!(act & DO_ALTBLTIN))
13353                                 goto builtin_success;
13354                 } else if (builtinloc <= 0) {
13355                         goto builtin_success;
13356                 }
13357         }
13358
13359 #if ENABLE_FEATURE_SH_STANDALONE
13360         {
13361                 int applet_no = find_applet_by_name(name);
13362                 if (applet_no >= 0) {
13363                         entry->cmdtype = CMDNORMAL;
13364                         entry->u.index = -2 - applet_no;
13365                         return;
13366                 }
13367         }
13368 #endif
13369
13370         /* We have to search path. */
13371         prev = -1;              /* where to start */
13372         if (cmdp && cmdp->rehash) {     /* doing a rehash */
13373                 if (cmdp->cmdtype == CMDBUILTIN)
13374                         prev = builtinloc;
13375                 else
13376                         prev = cmdp->param.index;
13377         }
13378
13379         e = ENOENT;
13380         idx = -1;
13381  loop:
13382         while ((fullname = path_advance(&path, name)) != NULL) {
13383                 stunalloc(fullname);
13384                 /* NB: code below will still use fullname
13385                  * despite it being "unallocated" */
13386                 idx++;
13387                 if (pathopt) {
13388                         if (prefix(pathopt, "builtin")) {
13389                                 if (bcmd)
13390                                         goto builtin_success;
13391                                 continue;
13392                         }
13393                         if ((act & DO_NOFUNC)
13394                          || !prefix(pathopt, "func")
13395                         ) {     /* ignore unimplemented options */
13396                                 continue;
13397                         }
13398                 }
13399                 /* if rehash, don't redo absolute path names */
13400                 if (fullname[0] == '/' && idx <= prev) {
13401                         if (idx < prev)
13402                                 continue;
13403                         TRACE(("searchexec \"%s\": no change\n", name));
13404                         goto success;
13405                 }
13406                 while (stat(fullname, &statb) < 0) {
13407 #ifdef SYSV
13408                         if (errno == EINTR)
13409                                 continue;
13410 #endif
13411                         if (errno != ENOENT && errno != ENOTDIR)
13412                                 e = errno;
13413                         goto loop;
13414                 }
13415                 e = EACCES;     /* if we fail, this will be the error */
13416                 if (!S_ISREG(statb.st_mode))
13417                         continue;
13418                 if (pathopt) {          /* this is a %func directory */
13419                         stalloc(strlen(fullname) + 1);
13420                         /* NB: stalloc will return space pointed by fullname
13421                          * (because we don't have any intervening allocations
13422                          * between stunalloc above and this stalloc) */
13423                         readcmdfile(fullname);
13424                         cmdp = cmdlookup(name, 0);
13425                         if (cmdp == NULL || cmdp->cmdtype != CMDFUNCTION)
13426                                 ash_msg_and_raise_error("%s not defined in %s", name, fullname);
13427                         stunalloc(fullname);
13428                         goto success;
13429                 }
13430                 TRACE(("searchexec \"%s\" returns \"%s\"\n", name, fullname));
13431                 if (!updatetbl) {
13432                         entry->cmdtype = CMDNORMAL;
13433                         entry->u.index = idx;
13434                         return;
13435                 }
13436                 INT_OFF;
13437                 cmdp = cmdlookup(name, 1);
13438                 cmdp->cmdtype = CMDNORMAL;
13439                 cmdp->param.index = idx;
13440                 INT_ON;
13441                 goto success;
13442         }
13443
13444         /* We failed.  If there was an entry for this command, delete it */
13445         if (cmdp && updatetbl)
13446                 delete_cmd_entry();
13447         if (act & DO_ERR) {
13448 #if ENABLE_ASH_BASH_NOT_FOUND_HOOK
13449                 struct tblentry *hookp = cmdlookup("command_not_found_handle", 0);
13450                 if (hookp && hookp->cmdtype == CMDFUNCTION) {
13451                         char *argv[3];
13452                         argv[0] = (char*) "command_not_found_handle";
13453                         argv[1] = name;
13454                         argv[2] = NULL;
13455                         evalfun(hookp->param.func, 2, argv, 0);
13456                         entry->cmdtype = CMDUNKNOWN;
13457                         return;
13458                 }
13459 #endif
13460                 ash_msg("%s: %s", name, errmsg(e, "not found"));
13461         }
13462         entry->cmdtype = CMDUNKNOWN;
13463         return;
13464
13465  builtin_success:
13466         if (!updatetbl) {
13467                 entry->cmdtype = CMDBUILTIN;
13468                 entry->u.cmd = bcmd;
13469                 return;
13470         }
13471         INT_OFF;
13472         cmdp = cmdlookup(name, 1);
13473         cmdp->cmdtype = CMDBUILTIN;
13474         cmdp->param.cmd = bcmd;
13475         INT_ON;
13476  success:
13477         cmdp->rehash = 0;
13478         entry->cmdtype = cmdp->cmdtype;
13479         entry->u = cmdp->param;
13480 }
13481
13482
13483 /*
13484  * The trap builtin.
13485  */
13486 static int FAST_FUNC
13487 trapcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
13488 {
13489         char *action;
13490         char **ap;
13491         int signo, exitcode;
13492
13493         nextopt(nullstr);
13494         ap = argptr;
13495         if (!*ap) {
13496                 for (signo = 0; signo < NSIG; signo++) {
13497                         char *tr = trap_ptr[signo];
13498                         if (tr) {
13499                                 /* note: bash adds "SIG", but only if invoked
13500                                  * as "bash". If called as "sh", or if set -o posix,
13501                                  * then it prints short signal names.
13502                                  * We are printing short names: */
13503                                 out1fmt("trap -- %s %s\n",
13504                                                 single_quote(tr),
13505                                                 get_signame(signo));
13506                 /* trap_ptr != trap only if we are in special-cased `trap` code.
13507                  * In this case, we will exit very soon, no need to free(). */
13508                                 /* if (trap_ptr != trap && tp[0]) */
13509                                 /*      free(tr); */
13510                         }
13511                 }
13512                 /*
13513                 if (trap_ptr != trap) {
13514                         free(trap_ptr);
13515                         trap_ptr = trap;
13516                 }
13517                 */
13518                 return 0;
13519         }
13520
13521         /* Why the second check?
13522          * "trap NUM [sig2]..." is the same as "trap - NUM [sig2]..."
13523          * In this case, NUM is signal no, not an action.
13524          */
13525         action = NULL;
13526         if (ap[1] && !is_number(ap[0]))
13527                 action = *ap++;
13528
13529         exitcode = 0;
13530         while (*ap) {
13531                 signo = get_signum(*ap);
13532                 if (signo < 0) {
13533                         /* Mimic bash message exactly */
13534                         ash_msg("%s: invalid signal specification", *ap);
13535                         exitcode = 1;
13536                         goto next;
13537                 }
13538                 INT_OFF;
13539                 if (action) {
13540                         if (LONE_DASH(action))
13541                                 action = NULL;
13542                         else {
13543                                 if (action[0]) /* not NULL and not "" and not "-" */
13544                                         may_have_traps = 1;
13545                                 action = ckstrdup(action);
13546                         }
13547                 }
13548                 free(trap[signo]);
13549                 trap[signo] = action;
13550                 if (signo != 0)
13551                         setsignal(signo);
13552                 INT_ON;
13553  next:
13554                 ap++;
13555         }
13556         return exitcode;
13557 }
13558
13559
13560 /* ============ Builtins */
13561
13562 #if ENABLE_ASH_HELP
13563 static int FAST_FUNC
13564 helpcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
13565 {
13566         unsigned col;
13567         unsigned i;
13568
13569         out1fmt(
13570                 "Built-in commands:\n"
13571                 "------------------\n");
13572         for (col = 0, i = 0; i < ARRAY_SIZE(builtintab); i++) {
13573                 col += out1fmt("%c%s", ((col == 0) ? '\t' : ' '),
13574                                         builtintab[i].name + 1);
13575                 if (col > 60) {
13576                         out1fmt("\n");
13577                         col = 0;
13578                 }
13579         }
13580 # if ENABLE_FEATURE_SH_STANDALONE
13581         {
13582                 const char *a = applet_names;
13583                 while (*a) {
13584                         col += out1fmt("%c%s", ((col == 0) ? '\t' : ' '), a);
13585                         if (col > 60) {
13586                                 out1fmt("\n");
13587                                 col = 0;
13588                         }
13589                         while (*a++ != '\0')
13590                                 continue;
13591                 }
13592         }
13593 # endif
13594         newline_and_flush(stdout);
13595         return EXIT_SUCCESS;
13596 }
13597 #endif
13598
13599 #if MAX_HISTORY
13600 static int FAST_FUNC
13601 historycmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
13602 {
13603         show_history(line_input_state);
13604         return EXIT_SUCCESS;
13605 }
13606 #endif
13607
13608 /*
13609  * The export and readonly commands.
13610  */
13611 static int FAST_FUNC
13612 exportcmd(int argc UNUSED_PARAM, char **argv)
13613 {
13614         struct var *vp;
13615         char *name;
13616         const char *p;
13617         char **aptr;
13618         char opt;
13619         int flag;
13620         int flag_off;
13621
13622         /* "readonly" in bash accepts, but ignores -n.
13623          * We do the same: it saves a conditional in nextopt's param.
13624          */
13625         flag_off = 0;
13626         while ((opt = nextopt("np")) != '\0') {
13627                 if (opt == 'n')
13628                         flag_off = VEXPORT;
13629         }
13630         flag = VEXPORT;
13631         if (argv[0][0] == 'r') {
13632                 flag = VREADONLY;
13633                 flag_off = 0; /* readonly ignores -n */
13634         }
13635         flag_off = ~flag_off;
13636
13637         /*if (opt_p_not_specified) - bash doesn't check this. Try "export -p NAME" */
13638         {
13639                 aptr = argptr;
13640                 name = *aptr;
13641                 if (name) {
13642                         do {
13643                                 p = strchr(name, '=');
13644                                 if (p != NULL) {
13645                                         p++;
13646                                 } else {
13647                                         vp = *findvar(hashvar(name), name);
13648                                         if (vp) {
13649                                                 vp->flags = ((vp->flags | flag) & flag_off);
13650                                                 continue;
13651                                         }
13652                                 }
13653                                 setvar(name, p, (flag & flag_off));
13654                         } while ((name = *++aptr) != NULL);
13655                         return 0;
13656                 }
13657         }
13658
13659         /* No arguments. Show the list of exported or readonly vars.
13660          * -n is ignored.
13661          */
13662         showvars(argv[0], flag, 0);
13663         return 0;
13664 }
13665
13666 /*
13667  * Delete a function if it exists.
13668  */
13669 static void
13670 unsetfunc(const char *name)
13671 {
13672         struct tblentry *cmdp;
13673
13674         cmdp = cmdlookup(name, 0);
13675         if (cmdp != NULL && cmdp->cmdtype == CMDFUNCTION)
13676                 delete_cmd_entry();
13677 }
13678
13679 /*
13680  * The unset builtin command.  We unset the function before we unset the
13681  * variable to allow a function to be unset when there is a readonly variable
13682  * with the same name.
13683  */
13684 static int FAST_FUNC
13685 unsetcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
13686 {
13687         char **ap;
13688         int i;
13689         int flag = 0;
13690
13691         while ((i = nextopt("vf")) != 0) {
13692                 flag = i;
13693         }
13694
13695         for (ap = argptr; *ap; ap++) {
13696                 if (flag != 'f') {
13697                         unsetvar(*ap);
13698                         continue;
13699                 }
13700                 if (flag != 'v')
13701                         unsetfunc(*ap);
13702         }
13703         return 0;
13704 }
13705
13706 static const unsigned char timescmd_str[] ALIGN1 = {
13707         ' ',  offsetof(struct tms, tms_utime),
13708         '\n', offsetof(struct tms, tms_stime),
13709         ' ',  offsetof(struct tms, tms_cutime),
13710         '\n', offsetof(struct tms, tms_cstime),
13711         0
13712 };
13713 static int FAST_FUNC
13714 timescmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
13715 {
13716         unsigned clk_tck;
13717         const unsigned char *p;
13718         struct tms buf;
13719
13720         clk_tck = bb_clk_tck();
13721
13722         times(&buf);
13723         p = timescmd_str;
13724         do {
13725                 unsigned sec, frac;
13726                 unsigned long t;
13727                 t = *(clock_t *)(((char *) &buf) + p[1]);
13728                 sec = t / clk_tck;
13729                 frac = t % clk_tck;
13730                 out1fmt("%um%u.%03us%c",
13731                         sec / 60, sec % 60,
13732                         (frac * 1000) / clk_tck,
13733                         p[0]);
13734                 p += 2;
13735         } while (*p);
13736
13737         return 0;
13738 }
13739
13740 #if ENABLE_FEATURE_SH_MATH
13741 /*
13742  * The let builtin. Partially stolen from GNU Bash, the Bourne Again SHell.
13743  * Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
13744  *
13745  * Copyright (C) 2003 Vladimir Oleynik <dzo@simtreas.ru>
13746  */
13747 static int FAST_FUNC
13748 letcmd(int argc UNUSED_PARAM, char **argv)
13749 {
13750         arith_t i;
13751
13752         argv++;
13753         if (!*argv)
13754                 ash_msg_and_raise_error("expression expected");
13755         do {
13756                 i = ash_arith(*argv);
13757         } while (*++argv);
13758
13759         return !i;
13760 }
13761 #endif
13762
13763 /*
13764  * The read builtin. Options:
13765  *      -r              Do not interpret '\' specially
13766  *      -s              Turn off echo (tty only)
13767  *      -n NCHARS       Read NCHARS max
13768  *      -p PROMPT       Display PROMPT on stderr (if input is from tty)
13769  *      -t SECONDS      Timeout after SECONDS (tty or pipe only)
13770  *      -u FD           Read from given FD instead of fd 0
13771  *      -d DELIM        End on DELIM char, not newline
13772  * This uses unbuffered input, which may be avoidable in some cases.
13773  * TODO: bash also has:
13774  *      -a ARRAY        Read into array[0],[1],etc
13775  *      -e              Use line editing (tty only)
13776  */
13777 static int FAST_FUNC
13778 readcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
13779 {
13780         struct builtin_read_params params;
13781         const char *r;
13782         int i;
13783
13784         memset(&params, 0, sizeof(params));
13785
13786         while ((i = nextopt("p:u:rt:n:sd:")) != '\0') {
13787                 switch (i) {
13788                 case 'p':
13789                         params.opt_p = optionarg;
13790                         break;
13791                 case 'n':
13792                         params.opt_n = optionarg;
13793                         break;
13794                 case 's':
13795                         params.read_flags |= BUILTIN_READ_SILENT;
13796                         break;
13797                 case 't':
13798                         params.opt_t = optionarg;
13799                         break;
13800                 case 'r':
13801                         params.read_flags |= BUILTIN_READ_RAW;
13802                         break;
13803                 case 'u':
13804                         params.opt_u = optionarg;
13805                         break;
13806 #if BASH_READ_D
13807                 case 'd':
13808                         params.opt_d = optionarg;
13809                         break;
13810 #endif
13811                 default:
13812                         break;
13813                 }
13814         }
13815
13816         params.argv = argptr;
13817         params.setvar = setvar0;
13818         params.ifs = bltinlookup("IFS"); /* can be NULL */
13819
13820         /* "read -s" needs to save/restore termios, can't allow ^C
13821          * to jump out of it.
13822          */
13823  again:
13824         INT_OFF;
13825         r = shell_builtin_read(&params);
13826         INT_ON;
13827
13828         if ((uintptr_t)r == 1 && errno == EINTR) {
13829                 /* To get SIGCHLD: sleep 1 & read x; echo $x
13830                  * Correct behavior is to not exit "read"
13831                  */
13832                 if (pending_sig == 0)
13833                         goto again;
13834         }
13835
13836         if ((uintptr_t)r > 1)
13837                 ash_msg_and_raise_error(r);
13838
13839         return (uintptr_t)r;
13840 }
13841
13842 static int FAST_FUNC
13843 umaskcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
13844 {
13845         static const char permuser[3] ALIGN1 = "ogu";
13846
13847         mode_t mask;
13848         int symbolic_mode = 0;
13849
13850         while (nextopt("S") != '\0') {
13851                 symbolic_mode = 1;
13852         }
13853
13854         INT_OFF;
13855         mask = umask(0);
13856         umask(mask);
13857         INT_ON;
13858
13859         if (*argptr == NULL) {
13860                 if (symbolic_mode) {
13861                         char buf[sizeof(",u=rwx,g=rwx,o=rwx")];
13862                         char *p = buf;
13863                         int i;
13864
13865                         i = 2;
13866                         for (;;) {
13867                                 *p++ = ',';
13868                                 *p++ = permuser[i];
13869                                 *p++ = '=';
13870                                 /* mask is 0..0uuugggooo. i=2 selects uuu bits */
13871                                 if (!(mask & 0400)) *p++ = 'r';
13872                                 if (!(mask & 0200)) *p++ = 'w';
13873                                 if (!(mask & 0100)) *p++ = 'x';
13874                                 mask <<= 3;
13875                                 if (--i < 0)
13876                                         break;
13877                         }
13878                         *p = '\0';
13879                         puts(buf + 1);
13880                 } else {
13881                         out1fmt("%04o\n", mask);
13882                 }
13883         } else {
13884                 char *modestr = *argptr;
13885                 /* numeric umasks are taken as-is */
13886                 /* symbolic umasks are inverted: "umask a=rx" calls umask(222) */
13887                 if (!isdigit(modestr[0]))
13888                         mask ^= 0777;
13889                 mask = bb_parse_mode(modestr, mask);
13890                 if ((unsigned)mask > 0777) {
13891                         ash_msg_and_raise_error("illegal mode: %s", modestr);
13892                 }
13893                 if (!isdigit(modestr[0]))
13894                         mask ^= 0777;
13895                 umask(mask);
13896         }
13897         return 0;
13898 }
13899
13900 static int FAST_FUNC
13901 ulimitcmd(int argc UNUSED_PARAM, char **argv)
13902 {
13903         return shell_builtin_ulimit(argv);
13904 }
13905
13906 /* ============ main() and helpers */
13907
13908 /*
13909  * Called to exit the shell.
13910  */
13911 static void
13912 exitshell(void)
13913 {
13914         struct jmploc loc;
13915         char *p;
13916         int status;
13917
13918 #if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT
13919         save_history(line_input_state);
13920 #endif
13921         status = exitstatus;
13922         TRACE(("pid %d, exitshell(%d)\n", getpid(), status));
13923         if (setjmp(loc.loc)) {
13924                 if (exception_type == EXEXIT)
13925                         status = exitstatus;
13926                 goto out;
13927         }
13928         exception_handler = &loc;
13929         p = trap[0];
13930         if (p) {
13931                 trap[0] = NULL;
13932                 evalskip = 0;
13933                 evalstring(p, 0);
13934                 /*free(p); - we'll exit soon */
13935         }
13936  out:
13937         /* dash wraps setjobctl(0) in "if (setjmp(loc.loc) == 0) {...}".
13938          * our setjobctl(0) does not panic if tcsetpgrp fails inside it.
13939          */
13940         setjobctl(0);
13941         flush_stdout_stderr();
13942         _exit(status);
13943         /* NOTREACHED */
13944 }
13945
13946 /* Don't inline: conserve stack of caller from having our locals too */
13947 static NOINLINE void
13948 init(void)
13949 {
13950         /* we will never free this */
13951         basepf.next_to_pgetc = basepf.buf = ckmalloc(IBUFSIZ);
13952         basepf.linno = 1;
13953
13954         sigmode[SIGCHLD - 1] = S_DFL; /* ensure we install handler even if it is SIG_IGNed */
13955         setsignal(SIGCHLD);
13956
13957         /* bash re-enables SIGHUP which is SIG_IGNed on entry.
13958          * Try: "trap '' HUP; bash; echo RET" and type "kill -HUP $$"
13959          */
13960         signal(SIGHUP, SIG_DFL);
13961
13962         {
13963                 char **envp;
13964                 const char *p;
13965
13966                 initvar();
13967                 for (envp = environ; envp && *envp; envp++) {
13968 /* Used to have
13969  *                      p = endofname(*envp);
13970  *                      if (p != *envp && *p == '=') {
13971  * here to weed out badly-named variables, but this breaks
13972  * scenarios where people do want them passed to children:
13973  * import os
13974  * os.environ["test-test"]="test"
13975  * if os.fork() == 0:
13976  *   os.execv("ash", [ 'ash', '-c', 'eval $(export -p); echo OK' ])  # fixes this
13977  * os.execv("ash", [ 'ash', '-c', 'env | grep test-test' ])  # breaks this
13978  */
13979                         if (strchr(*envp, '=')) {
13980                                 setvareq(*envp, VEXPORT|VTEXTFIXED);
13981                         }
13982                 }
13983
13984                 setvareq((char*)defifsvar, VTEXTFIXED);
13985                 setvareq((char*)defoptindvar, VTEXTFIXED);
13986
13987                 setvar0("PPID", utoa(getppid()));
13988 #if BASH_SHLVL_VAR
13989                 p = lookupvar("SHLVL");
13990                 setvar("SHLVL", utoa((p ? atoi(p) : 0) + 1), VEXPORT);
13991 #endif
13992 #if BASH_HOSTNAME_VAR
13993                 if (!lookupvar("HOSTNAME")) {
13994                         struct utsname uts;
13995                         uname(&uts);
13996                         setvar0("HOSTNAME", uts.nodename);
13997                 }
13998 #endif
13999                 p = lookupvar("PWD");
14000                 if (p) {
14001                         struct stat st1, st2;
14002                         if (p[0] != '/' || stat(p, &st1) || stat(".", &st2)
14003                          || st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino
14004                         ) {
14005                                 p = NULL;
14006                         }
14007                 }
14008                 setpwd(p, 0);
14009         }
14010 }
14011
14012
14013 //usage:#define ash_trivial_usage
14014 //usage:        "[-/+OPTIONS] [-/+o OPT]... [-c 'SCRIPT' [ARG0 [ARGS]] / FILE [ARGS] / -s [ARGS]]"
14015 //usage:#define ash_full_usage "\n\n"
14016 //usage:        "Unix shell interpreter"
14017
14018 /*
14019  * Process the shell command line arguments.
14020  */
14021 static int
14022 procargs(char **argv)
14023 {
14024         int i;
14025         const char *xminusc;
14026         char **xargv;
14027         int login_sh;
14028
14029         xargv = argv;
14030         login_sh = xargv[0] && xargv[0][0] == '-';
14031 #if NUM_SCRIPTS > 0
14032         if (minusc)
14033                 goto setarg0;
14034 #endif
14035         arg0 = xargv[0];
14036         /* if (xargv[0]) - mmm, this is always true! */
14037                 xargv++;
14038         argptr = xargv;
14039         for (i = 0; i < NOPTS; i++)
14040                 optlist[i] = 2;
14041         if (options(/*cmdline:*/ 1, &login_sh)) {
14042                 /* it already printed err message */
14043                 raise_exception(EXERROR);
14044         }
14045         xargv = argptr;
14046         xminusc = minusc;
14047         if (*xargv == NULL) {
14048                 if (xminusc)
14049                         ash_msg_and_raise_error(bb_msg_requires_arg, "-c");
14050                 sflag = 1;
14051         }
14052         if (iflag == 2 && sflag == 1 && isatty(0) && isatty(1))
14053                 iflag = 1;
14054         if (mflag == 2)
14055                 mflag = iflag;
14056         for (i = 0; i < NOPTS; i++)
14057                 if (optlist[i] == 2)
14058                         optlist[i] = 0;
14059 #if DEBUG == 2
14060         debug = 1;
14061 #endif
14062         /* POSIX 1003.2: first arg after "-c CMD" is $0, remainder $1... */
14063         if (xminusc) {
14064                 minusc = *xargv++;
14065                 if (*xargv)
14066                         goto setarg0;
14067         } else if (!sflag) {
14068                 setinputfile(*xargv, 0);
14069  setarg0:
14070                 arg0 = *xargv++;
14071                 commandname = arg0;
14072         }
14073
14074         shellparam.p = xargv;
14075 #if ENABLE_ASH_GETOPTS
14076         shellparam.optind = 1;
14077         shellparam.optoff = -1;
14078 #endif
14079         /* assert(shellparam.malloced == 0 && shellparam.nparam == 0); */
14080         while (*xargv) {
14081                 shellparam.nparam++;
14082                 xargv++;
14083         }
14084         optschanged();
14085
14086         return login_sh;
14087 }
14088
14089 /*
14090  * Read /etc/profile, ~/.profile, $ENV.
14091  */
14092 static void
14093 read_profile(const char *name)
14094 {
14095         name = expandstr(name, DQSYNTAX);
14096         if (setinputfile(name, INPUT_PUSH_FILE | INPUT_NOFILE_OK) < 0)
14097                 return;
14098         cmdloop(0);
14099         popfile();
14100 }
14101
14102 /*
14103  * This routine is called when an error or an interrupt occurs in an
14104  * interactive shell and control is returned to the main command loop.
14105  * (In dash, this function is auto-generated by build machinery).
14106  */
14107 static void
14108 reset(void)
14109 {
14110         /* from eval.c: */
14111         evalskip = 0;
14112         loopnest = 0;
14113
14114         /* from expand.c: */
14115         ifsfree();
14116
14117         /* from input.c: */
14118         g_parsefile->left_in_buffer = 0;
14119         g_parsefile->left_in_line = 0;      /* clear input buffer */
14120         popallfiles();
14121
14122         /* from redir.c: */
14123         unwindredir(NULL);
14124
14125         /* from var.c: */
14126         unwindlocalvars(NULL);
14127 }
14128
14129 #if PROFILE
14130 static short profile_buf[16384];
14131 extern int etext();
14132 #endif
14133
14134 /*
14135  * Main routine.  We initialize things, parse the arguments, execute
14136  * profiles if we're a login shell, and then call cmdloop to execute
14137  * commands.  The setjmp call sets up the location to jump to when an
14138  * exception occurs.  When an exception occurs the variable "state"
14139  * is used to figure out how far we had gotten.
14140  */
14141 int ash_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
14142 #if NUM_SCRIPTS > 0
14143 int ash_main(int argc, char **argv)
14144 #else
14145 int ash_main(int argc UNUSED_PARAM, char **argv)
14146 #endif
14147 /* note: 'argc' is used only if embedded scripts are enabled */
14148 {
14149         volatile smallint state;
14150         struct jmploc jmploc;
14151         struct stackmark smark;
14152         int login_sh;
14153
14154         /* Initialize global data */
14155         INIT_G_misc();
14156         INIT_G_memstack();
14157         INIT_G_var();
14158 #if ENABLE_ASH_ALIAS
14159         INIT_G_alias();
14160 #endif
14161         INIT_G_cmdtable();
14162
14163 #if PROFILE
14164         monitor(4, etext, profile_buf, sizeof(profile_buf), 50);
14165 #endif
14166
14167 #if ENABLE_FEATURE_EDITING
14168         line_input_state = new_line_input_t(FOR_SHELL | WITH_PATH_LOOKUP);
14169 #endif
14170         state = 0;
14171         if (setjmp(jmploc.loc)) {
14172                 smallint e;
14173                 smallint s;
14174
14175                 reset();
14176
14177                 e = exception_type;
14178                 s = state;
14179                 if (e == EXEXIT || s == 0 || iflag == 0 || shlvl) {
14180                         exitshell();
14181                 }
14182                 if (e == EXINT) {
14183                         newline_and_flush(stderr);
14184                 }
14185
14186                 popstackmark(&smark);
14187                 FORCE_INT_ON; /* enable interrupts */
14188                 if (s == 1)
14189                         goto state1;
14190                 if (s == 2)
14191                         goto state2;
14192                 if (s == 3)
14193                         goto state3;
14194                 goto state4;
14195         }
14196         exception_handler = &jmploc;
14197         rootpid = getpid();
14198
14199         init();
14200         setstackmark(&smark);
14201
14202 #if NUM_SCRIPTS > 0
14203         if (argc < 0)
14204                 /* Non-NULL minusc tells procargs that an embedded script is being run */
14205                 minusc = get_script_content(-argc - 1);
14206 #endif
14207         login_sh = procargs(argv);
14208 #if DEBUG
14209         TRACE(("Shell args: "));
14210         trace_puts_args(argv);
14211 #endif
14212
14213         if (login_sh) {
14214                 const char *hp;
14215
14216                 state = 1;
14217                 read_profile("/etc/profile");
14218  state1:
14219                 state = 2;
14220                 hp = lookupvar("HOME");
14221                 if (hp)
14222                         read_profile("$HOME/.profile");
14223         }
14224  state2:
14225         state = 3;
14226         if (
14227 #ifndef linux
14228          getuid() == geteuid() && getgid() == getegid() &&
14229 #endif
14230          iflag
14231         ) {
14232                 const char *shinit = lookupvar("ENV");
14233                 if (shinit != NULL && *shinit != '\0')
14234                         read_profile(shinit);
14235         }
14236         popstackmark(&smark);
14237  state3:
14238         state = 4;
14239         if (minusc) {
14240                 /* evalstring pushes parsefile stack.
14241                  * Ensure we don't falsely claim that 0 (stdin)
14242                  * is one of stacked source fds.
14243                  * Testcase: ash -c 'exec 1>&0' must not complain. */
14244                 // if (!sflag) g_parsefile->pf_fd = -1;
14245                 // ^^ not necessary since now we special-case fd 0
14246                 // in save_fd_on_redirect()
14247                 evalstring(minusc, sflag ? 0 : EV_EXIT);
14248         }
14249
14250         if (sflag || minusc == NULL) {
14251 #if MAX_HISTORY > 0 && ENABLE_FEATURE_EDITING_SAVEHISTORY
14252                 if (iflag) {
14253                         const char *hp = lookupvar("HISTFILE");
14254                         if (!hp) {
14255                                 hp = lookupvar("HOME");
14256                                 if (hp) {
14257                                         INT_OFF;
14258                                         hp = concat_path_file(hp, ".ash_history");
14259                                         setvar0("HISTFILE", hp);
14260                                         free((char*)hp);
14261                                         INT_ON;
14262                                         hp = lookupvar("HISTFILE");
14263                                 }
14264                         }
14265                         if (hp)
14266                                 line_input_state->hist_file = hp;
14267 # if ENABLE_FEATURE_SH_HISTFILESIZE
14268                         hp = lookupvar("HISTFILESIZE");
14269                         line_input_state->max_history = size_from_HISTFILESIZE(hp);
14270 # endif
14271                 }
14272 #endif
14273  state4: /* XXX ??? - why isn't this before the "if" statement */
14274                 cmdloop(1);
14275         }
14276 #if PROFILE
14277         monitor(0);
14278 #endif
14279 #ifdef GPROF
14280         {
14281                 extern void _mcleanup(void);
14282                 _mcleanup();
14283         }
14284 #endif
14285         TRACE(("End of main reached\n"));
14286         exitshell();
14287         /* NOTREACHED */
14288 }
14289
14290
14291 /*-
14292  * Copyright (c) 1989, 1991, 1993, 1994
14293  *      The Regents of the University of California.  All rights reserved.
14294  *
14295  * This code is derived from software contributed to Berkeley by
14296  * Kenneth Almquist.
14297  *
14298  * Redistribution and use in source and binary forms, with or without
14299  * modification, are permitted provided that the following conditions
14300  * are met:
14301  * 1. Redistributions of source code must retain the above copyright
14302  *    notice, this list of conditions and the following disclaimer.
14303  * 2. Redistributions in binary form must reproduce the above copyright
14304  *    notice, this list of conditions and the following disclaimer in the
14305  *    documentation and/or other materials provided with the distribution.
14306  * 3. Neither the name of the University nor the names of its contributors
14307  *    may be used to endorse or promote products derived from this software
14308  *    without specific prior written permission.
14309  *
14310  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ''AS IS'' AND
14311  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
14312  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
14313  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
14314  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
14315  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
14316  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
14317  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
14318  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
14319  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
14320  * SUCH DAMAGE.
14321  */