sheel: improve comments on signal handling
[oweals/busybox.git] / shell / ash.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * ash shell port for busybox
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Kenneth Almquist.
7  *
8  * Original BSD copyright notice is retained at the end of this file.
9  *
10  * Copyright (c) 1989, 1991, 1993, 1994
11  *      The Regents of the University of California.  All rights reserved.
12  *
13  * Copyright (c) 1997-2005 Herbert Xu <herbert@gondor.apana.org.au>
14  * was re-ported from NetBSD and debianized.
15  *
16  * Licensed under GPLv2 or later, see file LICENSE in this source tree.
17  */
18 //config:config ASH
19 //config:       bool "ash (77 kb)"
20 //config:       default y
21 //config:       depends on !NOMMU
22 //config:       help
23 //config:       The most complete and most pedantically correct shell included with
24 //config:       busybox. This shell is actually a derivative of the Debian 'dash'
25 //config:       shell (by Herbert Xu), which was created by porting the 'ash' shell
26 //config:       (written by Kenneth Almquist) from NetBSD.
27 //config:
28 //config:# ash options
29 //config:# note: Don't remove !NOMMU part in the next line; it would break
30 //config:# menuconfig's indenting.
31 //config:if !NOMMU && (ASH || SH_IS_ASH || BASH_IS_ASH)
32 //config:
33 //config:config ASH_OPTIMIZE_FOR_SIZE
34 //config:       bool "Optimize for size instead of speed"
35 //config:       default y
36 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
37 //config:
38 //config:config ASH_INTERNAL_GLOB
39 //config:       bool "Use internal glob() implementation"
40 //config:       default y       # Y is bigger, but because of uclibc glob() bug, let Y be default for now
41 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
42 //config:       help
43 //config:       Do not use glob() function from libc, use internal implementation.
44 //config:       Use this if you are getting "glob.h: No such file or directory"
45 //config:       or similar build errors.
46 //config:       Note that as of now (2017-01), uclibc and musl glob() both have bugs
47 //config:       which would break ash if you select N here.
48 //config:
49 //config:config ASH_BASH_COMPAT
50 //config:       bool "bash-compatible extensions"
51 //config:       default y
52 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
53 //config:
54 //config:config ASH_JOB_CONTROL
55 //config:       bool "Job control"
56 //config:       default y
57 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
58 //config:
59 //config:config ASH_ALIAS
60 //config:       bool "Alias support"
61 //config:       default y
62 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
63 //config:
64 //config:config ASH_RANDOM_SUPPORT
65 //config:       bool "Pseudorandom generator and $RANDOM variable"
66 //config:       default y
67 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
68 //config:       help
69 //config:       Enable pseudorandom generator and dynamic variable "$RANDOM".
70 //config:       Each read of "$RANDOM" will generate a new pseudorandom value.
71 //config:       You can reset the generator by using a specified start value.
72 //config:       After "unset RANDOM" the generator will switch off and this
73 //config:       variable will no longer have special treatment.
74 //config:
75 //config:config ASH_EXPAND_PRMT
76 //config:       bool "Expand prompt string"
77 //config:       default y
78 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
79 //config:       help
80 //config:       $PS# may contain volatile content, such as backquote commands.
81 //config:       This option recreates the prompt string from the environment
82 //config:       variable each time it is displayed.
83 //config:
84 //config:config ASH_IDLE_TIMEOUT
85 //config:       bool "Idle timeout variable $TMOUT"
86 //config:       default y
87 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
88 //config:       help
89 //config:       Enable bash-like auto-logout after $TMOUT seconds of idle time.
90 //config:
91 //config:config ASH_MAIL
92 //config:       bool "Check for new mail in interactive shell"
93 //config:       default y
94 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
95 //config:       help
96 //config:       Enable "check for new mail" function:
97 //config:       if set, $MAIL file and $MAILPATH list of files
98 //config:       are checked for mtime changes, and "you have mail"
99 //config:       message is printed if change is detected.
100 //config:
101 //config:config ASH_ECHO
102 //config:       bool "echo builtin"
103 //config:       default y
104 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
105 //config:
106 //config:config ASH_PRINTF
107 //config:       bool "printf builtin"
108 //config:       default y
109 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
110 //config:
111 //config:config ASH_TEST
112 //config:       bool "test builtin"
113 //config:       default y
114 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
115 //config:
116 //config:config ASH_HELP
117 //config:       bool "help builtin"
118 //config:       default y
119 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
120 //config:
121 //config:config ASH_GETOPTS
122 //config:       bool "getopts builtin"
123 //config:       default y
124 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
125 //config:
126 //config:config ASH_CMDCMD
127 //config:       bool "command builtin"
128 //config:       default y
129 //config:       depends on ASH || SH_IS_ASH || BASH_IS_ASH
130 //config:       help
131 //config:       Enable support for the 'command' builtin, which allows
132 //config:       you to run the specified command or builtin,
133 //config:       even when there is a function with the same name.
134 //config:
135 //config:endif # ash options
136
137 //applet:IF_ASH(APPLET(ash, BB_DIR_BIN, BB_SUID_DROP))
138 //                      APPLET_ODDNAME:name  main location    suid_type     help
139 //applet:IF_SH_IS_ASH(  APPLET_ODDNAME(sh,   ash, BB_DIR_BIN, BB_SUID_DROP, ash))
140 //applet:IF_BASH_IS_ASH(APPLET_ODDNAME(bash, ash, BB_DIR_BIN, BB_SUID_DROP, ash))
141
142 //kbuild:lib-$(CONFIG_ASH) += ash.o ash_ptr_hack.o shell_common.o
143 //kbuild:lib-$(CONFIG_SH_IS_ASH) += ash.o ash_ptr_hack.o shell_common.o
144 //kbuild:lib-$(CONFIG_BASH_IS_ASH) += ash.o ash_ptr_hack.o shell_common.o
145 //kbuild:lib-$(CONFIG_ASH_RANDOM_SUPPORT) += random.o
146
147 /*
148  * DEBUG=1 to compile in debugging ('set -o debug' turns on)
149  * DEBUG=2 to compile in and turn on debugging.
150  * When debugging is on ("set -o debug" was executed, or DEBUG=2),
151  * debugging info is written to ./trace, quit signal generates core dump.
152  */
153 #define DEBUG 0
154 /* Tweak debug output verbosity here */
155 #define DEBUG_TIME 0
156 #define DEBUG_PID 1
157 #define DEBUG_SIG 1
158 #define DEBUG_INTONOFF 0
159
160 #define PROFILE 0
161
162 #define JOBS ENABLE_ASH_JOB_CONTROL
163
164 #include <setjmp.h>
165 #include <fnmatch.h>
166 #include <sys/times.h>
167 #include <sys/utsname.h> /* for setting $HOSTNAME */
168 #include "busybox.h" /* for applet_names */
169
170 /* So far, all bash compat is controlled by one config option */
171 /* Separate defines document which part of code implements what */
172 /* function keyword */
173 #define    BASH_FUNCTION        ENABLE_ASH_BASH_COMPAT
174 #define IF_BASH_FUNCTION            IF_ASH_BASH_COMPAT
175 /* &>file */
176 #define    BASH_REDIR_OUTPUT    ENABLE_ASH_BASH_COMPAT
177 #define IF_BASH_REDIR_OUTPUT        IF_ASH_BASH_COMPAT
178 /* $'...' */
179 #define    BASH_DOLLAR_SQUOTE   ENABLE_ASH_BASH_COMPAT
180 #define IF_BASH_DOLLAR_SQUOTE       IF_ASH_BASH_COMPAT
181 #define    BASH_PATTERN_SUBST   ENABLE_ASH_BASH_COMPAT
182 #define IF_BASH_PATTERN_SUBST       IF_ASH_BASH_COMPAT
183 #define    BASH_SUBSTR          ENABLE_ASH_BASH_COMPAT
184 #define IF_BASH_SUBSTR              IF_ASH_BASH_COMPAT
185 /* [[ EXPR ]] */
186 #define    BASH_TEST2           (ENABLE_ASH_BASH_COMPAT * ENABLE_ASH_TEST)
187 #define    BASH_SOURCE          ENABLE_ASH_BASH_COMPAT
188 #define    BASH_PIPEFAIL        ENABLE_ASH_BASH_COMPAT
189 #define    BASH_HOSTNAME_VAR    ENABLE_ASH_BASH_COMPAT
190 #define    BASH_SHLVL_VAR       ENABLE_ASH_BASH_COMPAT
191
192 #if defined(__ANDROID_API__) && __ANDROID_API__ <= 24
193 /* Bionic at least up to version 24 has no glob() */
194 # undef  ENABLE_ASH_INTERNAL_GLOB
195 # define ENABLE_ASH_INTERNAL_GLOB 1
196 #endif
197
198 #if !ENABLE_ASH_INTERNAL_GLOB && defined(__UCLIBC__)
199 # error uClibc glob() is buggy, use ASH_INTERNAL_GLOB.
200 # error The bug is: for "$PWD"/<pattern> ash will escape e.g. dashes in "$PWD"
201 # error with backslash, even ones which do not need to be: "/a-b" -> "/a\-b"
202 # error glob() should unbackslash them and match. uClibc does not unbackslash,
203 # error fails to match dirname, subsequently not expanding <pattern> in it.
204 // Testcase:
205 // if (glob("/etc/polkit\\-1", 0, NULL, &pglob)) - this returns 0 on uclibc, no bug
206 // if (glob("/etc/polkit\\-1/*", 0, NULL, &pglob)) printf("uclibc bug!\n");
207 #endif
208
209 #if !ENABLE_ASH_INTERNAL_GLOB
210 # include <glob.h>
211 #endif
212
213 #include "unicode.h"
214 #include "shell_common.h"
215 #if ENABLE_FEATURE_SH_MATH
216 # include "math.h"
217 #else
218 typedef long arith_t;
219 # define ARITH_FMT "%ld"
220 #endif
221 #if ENABLE_ASH_RANDOM_SUPPORT
222 # include "random.h"
223 #else
224 # define CLEAR_RANDOM_T(rnd) ((void)0)
225 #endif
226
227 #include "NUM_APPLETS.h"
228 #if NUM_APPLETS == 1
229 /* STANDALONE does not make sense, and won't compile */
230 # undef CONFIG_FEATURE_SH_STANDALONE
231 # undef ENABLE_FEATURE_SH_STANDALONE
232 # undef IF_FEATURE_SH_STANDALONE
233 # undef IF_NOT_FEATURE_SH_STANDALONE
234 # define ENABLE_FEATURE_SH_STANDALONE 0
235 # define IF_FEATURE_SH_STANDALONE(...)
236 # define IF_NOT_FEATURE_SH_STANDALONE(...) __VA_ARGS__
237 #endif
238
239 #ifndef PIPE_BUF
240 # define PIPE_BUF 4096           /* amount of buffering in a pipe */
241 #endif
242
243 #if !BB_MMU
244 # error "Do not even bother, ash will not run on NOMMU machine"
245 #endif
246
247
248 /* ============ Hash table sizes. Configurable. */
249
250 #define VTABSIZE 39
251 #define ATABSIZE 39
252 #define CMDTABLESIZE 31         /* should be prime */
253
254
255 /* ============ Shell options */
256
257 static const char *const optletters_optnames[] = {
258         "e"   "errexit",
259         "f"   "noglob",
260         "I"   "ignoreeof",
261         "i"   "interactive",
262         "m"   "monitor",
263         "n"   "noexec",
264         "s"   "stdin",
265         "x"   "xtrace",
266         "v"   "verbose",
267         "C"   "noclobber",
268         "a"   "allexport",
269         "b"   "notify",
270         "u"   "nounset",
271         "\0"  "vi"
272 #if BASH_PIPEFAIL
273         ,"\0"  "pipefail"
274 #endif
275 #if DEBUG
276         ,"\0"  "nolog"
277         ,"\0"  "debug"
278 #endif
279 };
280
281 #define optletters(n)  optletters_optnames[n][0]
282 #define optnames(n)   (optletters_optnames[n] + 1)
283
284 enum { NOPTS = ARRAY_SIZE(optletters_optnames) };
285
286
287 /* ============ Misc data */
288
289 #define msg_illnum "Illegal number: %s"
290
291 /*
292  * We enclose jmp_buf in a structure so that we can declare pointers to
293  * jump locations.  The global variable handler contains the location to
294  * jump to when an exception occurs, and the global variable exception_type
295  * contains a code identifying the exception.  To implement nested
296  * exception handlers, the user should save the value of handler on entry
297  * to an inner scope, set handler to point to a jmploc structure for the
298  * inner scope, and restore handler on exit from the scope.
299  */
300 struct jmploc {
301         jmp_buf loc;
302 };
303
304 struct globals_misc {
305         uint8_t exitstatus;     /* exit status of last command */
306         uint8_t back_exitstatus;/* exit status of backquoted command */
307         smallint job_warning;   /* user was warned about stopped jobs (can be 2, 1 or 0). */
308         int rootpid;            /* pid of main shell */
309         /* shell level: 0 for the main shell, 1 for its children, and so on */
310         int shlvl;
311 #define rootshell (!shlvl)
312         char *minusc;  /* argument to -c option */
313
314         char *curdir; // = nullstr;     /* current working directory */
315         char *physdir; // = nullstr;    /* physical working directory */
316
317         char *arg0; /* value of $0 */
318
319         struct jmploc *exception_handler;
320
321         volatile int suppress_int; /* counter */
322         volatile /*sig_atomic_t*/ smallint pending_int; /* 1 = got SIGINT */
323         volatile /*sig_atomic_t*/ smallint got_sigchld; /* 1 = got SIGCHLD */
324         volatile /*sig_atomic_t*/ smallint pending_sig; /* last pending signal */
325         smallint exception_type; /* kind of exception (0..5) */
326         /* exceptions */
327 #define EXINT 0         /* SIGINT received */
328 #define EXERROR 1       /* a generic error */
329 #define EXEXIT 4        /* exit the shell */
330
331         char nullstr[1];        /* zero length string */
332
333         char optlist[NOPTS];
334 #define eflag optlist[0]
335 #define fflag optlist[1]
336 #define Iflag optlist[2]
337 #define iflag optlist[3]
338 #define mflag optlist[4]
339 #define nflag optlist[5]
340 #define sflag optlist[6]
341 #define xflag optlist[7]
342 #define vflag optlist[8]
343 #define Cflag optlist[9]
344 #define aflag optlist[10]
345 #define bflag optlist[11]
346 #define uflag optlist[12]
347 #define viflag optlist[13]
348 #if BASH_PIPEFAIL
349 # define pipefail optlist[14]
350 #else
351 # define pipefail 0
352 #endif
353 #if DEBUG
354 # define nolog optlist[14 + BASH_PIPEFAIL]
355 # define debug optlist[15 + BASH_PIPEFAIL]
356 #endif
357
358         /* trap handler commands */
359         /*
360          * Sigmode records the current value of the signal handlers for the various
361          * modes.  A value of zero means that the current handler is not known.
362          * S_HARD_IGN indicates that the signal was ignored on entry to the shell.
363          */
364         char sigmode[NSIG - 1];
365 #define S_DFL      1            /* default signal handling (SIG_DFL) */
366 #define S_CATCH    2            /* signal is caught */
367 #define S_IGN      3            /* signal is ignored (SIG_IGN) */
368 #define S_HARD_IGN 4            /* signal is ignored permanently */
369
370         /* indicates specified signal received */
371         uint8_t gotsig[NSIG - 1]; /* offset by 1: "signal" 0 is meaningless */
372         uint8_t may_have_traps; /* 0: definitely no traps are set, 1: some traps may be set */
373         char *trap[NSIG];
374         char **trap_ptr;        /* used only by "trap hack" */
375
376         /* Rarely referenced stuff */
377 #if ENABLE_ASH_RANDOM_SUPPORT
378         random_t random_gen;
379 #endif
380         pid_t backgndpid;        /* pid of last background process */
381 };
382 extern struct globals_misc *const ash_ptr_to_globals_misc;
383 #define G_misc (*ash_ptr_to_globals_misc)
384 #define exitstatus        (G_misc.exitstatus )
385 #define back_exitstatus   (G_misc.back_exitstatus )
386 #define job_warning       (G_misc.job_warning)
387 #define rootpid     (G_misc.rootpid    )
388 #define shlvl       (G_misc.shlvl      )
389 #define minusc      (G_misc.minusc     )
390 #define curdir      (G_misc.curdir     )
391 #define physdir     (G_misc.physdir    )
392 #define arg0        (G_misc.arg0       )
393 #define exception_handler (G_misc.exception_handler)
394 #define exception_type    (G_misc.exception_type   )
395 #define suppress_int      (G_misc.suppress_int     )
396 #define pending_int       (G_misc.pending_int      )
397 #define got_sigchld       (G_misc.got_sigchld      )
398 #define pending_sig       (G_misc.pending_sig      )
399 #define nullstr     (G_misc.nullstr    )
400 #define optlist     (G_misc.optlist    )
401 #define sigmode     (G_misc.sigmode    )
402 #define gotsig      (G_misc.gotsig     )
403 #define may_have_traps    (G_misc.may_have_traps   )
404 #define trap        (G_misc.trap       )
405 #define trap_ptr    (G_misc.trap_ptr   )
406 #define random_gen  (G_misc.random_gen )
407 #define backgndpid  (G_misc.backgndpid )
408 #define INIT_G_misc() do { \
409         (*(struct globals_misc**)&ash_ptr_to_globals_misc) = xzalloc(sizeof(G_misc)); \
410         barrier(); \
411         curdir = nullstr; \
412         physdir = nullstr; \
413         trap_ptr = trap; \
414 } while (0)
415
416
417 /* ============ DEBUG */
418 #if DEBUG
419 static void trace_printf(const char *fmt, ...);
420 static void trace_vprintf(const char *fmt, va_list va);
421 # define TRACE(param)    trace_printf param
422 # define TRACEV(param)   trace_vprintf param
423 # define close(fd) do { \
424         int dfd = (fd); \
425         if (close(dfd) < 0) \
426                 bb_error_msg("bug on %d: closing %d(0x%x)", \
427                         __LINE__, dfd, dfd); \
428 } while (0)
429 #else
430 # define TRACE(param)
431 # define TRACEV(param)
432 #endif
433
434
435 /* ============ Utility functions */
436 #define is_name(c)      ((c) == '_' || isalpha((unsigned char)(c)))
437 #define is_in_name(c)   ((c) == '_' || isalnum((unsigned char)(c)))
438
439 static int
440 isdigit_str9(const char *str)
441 {
442         int maxlen = 9 + 1; /* max 9 digits: 999999999 */
443         while (--maxlen && isdigit(*str))
444                 str++;
445         return (*str == '\0');
446 }
447
448 static const char *
449 var_end(const char *var)
450 {
451         while (*var)
452                 if (*var++ == '=')
453                         break;
454         return var;
455 }
456
457
458 /* ============ Interrupts / exceptions */
459
460 static void exitshell(void) NORETURN;
461
462 /*
463  * These macros allow the user to suspend the handling of interrupt signals
464  * over a period of time.  This is similar to SIGHOLD or to sigblock, but
465  * much more efficient and portable.  (But hacking the kernel is so much
466  * more fun than worrying about efficiency and portability. :-))
467  */
468 #if DEBUG_INTONOFF
469 # define INT_OFF do { \
470         TRACE(("%s:%d INT_OFF(%d)\n", __func__, __LINE__, suppress_int)); \
471         suppress_int++; \
472         barrier(); \
473 } while (0)
474 #else
475 # define INT_OFF do { \
476         suppress_int++; \
477         barrier(); \
478 } while (0)
479 #endif
480
481 /*
482  * Called to raise an exception.  Since C doesn't include exceptions, we
483  * just do a longjmp to the exception handler.  The type of exception is
484  * stored in the global variable "exception_type".
485  */
486 static void raise_exception(int) NORETURN;
487 static void
488 raise_exception(int e)
489 {
490 #if DEBUG
491         if (exception_handler == NULL)
492                 abort();
493 #endif
494         INT_OFF;
495         exception_type = e;
496         longjmp(exception_handler->loc, 1);
497 }
498 #if DEBUG
499 #define raise_exception(e) do { \
500         TRACE(("raising exception %d on line %d\n", (e), __LINE__)); \
501         raise_exception(e); \
502 } while (0)
503 #endif
504
505 /*
506  * Called when a SIGINT is received.  (If the user specifies
507  * that SIGINT is to be trapped or ignored using the trap builtin, then
508  * this routine is not called.)  Suppressint is nonzero when interrupts
509  * are held using the INT_OFF macro.  (The test for iflag is just
510  * defensive programming.)
511  */
512 static void raise_interrupt(void) NORETURN;
513 static void
514 raise_interrupt(void)
515 {
516         pending_int = 0;
517         /* Signal is not automatically unmasked after it is raised,
518          * do it ourself - unmask all signals */
519         sigprocmask_allsigs(SIG_UNBLOCK);
520         /* pending_sig = 0; - now done in signal_handler() */
521
522         if (!(rootshell && iflag)) {
523                 /* Kill ourself with SIGINT */
524                 signal(SIGINT, SIG_DFL);
525                 raise(SIGINT);
526         }
527         /* bash: ^C even on empty command line sets $? */
528         exitstatus = SIGINT + 128;
529         raise_exception(EXINT);
530         /* NOTREACHED */
531 }
532 #if DEBUG
533 #define raise_interrupt() do { \
534         TRACE(("raising interrupt on line %d\n", __LINE__)); \
535         raise_interrupt(); \
536 } while (0)
537 #endif
538
539 static IF_ASH_OPTIMIZE_FOR_SIZE(inline) void
540 int_on(void)
541 {
542         barrier();
543         if (--suppress_int == 0 && pending_int) {
544                 raise_interrupt();
545         }
546 }
547 #if DEBUG_INTONOFF
548 # define INT_ON do { \
549         TRACE(("%s:%d INT_ON(%d)\n", __func__, __LINE__, suppress_int-1)); \
550         int_on(); \
551 } while (0)
552 #else
553 # define INT_ON int_on()
554 #endif
555 static IF_ASH_OPTIMIZE_FOR_SIZE(inline) void
556 force_int_on(void)
557 {
558         barrier();
559         suppress_int = 0;
560         if (pending_int)
561                 raise_interrupt();
562 }
563 #define FORCE_INT_ON force_int_on()
564
565 #define SAVE_INT(v) ((v) = suppress_int)
566
567 #define RESTORE_INT(v) do { \
568         barrier(); \
569         suppress_int = (v); \
570         if (suppress_int == 0 && pending_int) \
571                 raise_interrupt(); \
572 } while (0)
573
574
575 /* ============ Stdout/stderr output */
576
577 static void
578 outstr(const char *p, FILE *file)
579 {
580         INT_OFF;
581         fputs(p, file);
582         INT_ON;
583 }
584
585 static void
586 flush_stdout_stderr(void)
587 {
588         INT_OFF;
589         fflush_all();
590         INT_ON;
591 }
592
593 /* Was called outcslow(c,FILE*), but c was always '\n' */
594 static void
595 newline_and_flush(FILE *dest)
596 {
597         INT_OFF;
598         putc('\n', dest);
599         fflush(dest);
600         INT_ON;
601 }
602
603 static int out1fmt(const char *, ...) __attribute__((__format__(__printf__,1,2)));
604 static int
605 out1fmt(const char *fmt, ...)
606 {
607         va_list ap;
608         int r;
609
610         INT_OFF;
611         va_start(ap, fmt);
612         r = vprintf(fmt, ap);
613         va_end(ap);
614         INT_ON;
615         return r;
616 }
617
618 static int fmtstr(char *, size_t, const char *, ...) __attribute__((__format__(__printf__,3,4)));
619 static int
620 fmtstr(char *outbuf, size_t length, const char *fmt, ...)
621 {
622         va_list ap;
623         int ret;
624
625         INT_OFF;
626         va_start(ap, fmt);
627         ret = vsnprintf(outbuf, length, fmt, ap);
628         va_end(ap);
629         INT_ON;
630         return ret;
631 }
632
633 static void
634 out1str(const char *p)
635 {
636         outstr(p, stdout);
637 }
638
639 static void
640 out2str(const char *p)
641 {
642         outstr(p, stderr);
643         flush_stdout_stderr();
644 }
645
646
647 /* ============ Parser structures */
648
649 /* control characters in argument strings */
650 #define CTL_FIRST CTLESC
651 #define CTLESC       ((unsigned char)'\201')    /* escape next character */
652 #define CTLVAR       ((unsigned char)'\202')    /* variable defn */
653 #define CTLENDVAR    ((unsigned char)'\203')
654 #define CTLBACKQ     ((unsigned char)'\204')
655 #define CTLARI       ((unsigned char)'\206')    /* arithmetic expression */
656 #define CTLENDARI    ((unsigned char)'\207')
657 #define CTLQUOTEMARK ((unsigned char)'\210')
658 #define CTL_LAST CTLQUOTEMARK
659
660 /* variable substitution byte (follows CTLVAR) */
661 #define VSTYPE  0x0f            /* type of variable substitution */
662 #define VSNUL   0x10            /* colon--treat the empty string as unset */
663
664 /* values of VSTYPE field */
665 #define VSNORMAL        0x1     /* normal variable:  $var or ${var} */
666 #define VSMINUS         0x2     /* ${var-text} */
667 #define VSPLUS          0x3     /* ${var+text} */
668 #define VSQUESTION      0x4     /* ${var?message} */
669 #define VSASSIGN        0x5     /* ${var=text} */
670 #define VSTRIMRIGHT     0x6     /* ${var%pattern} */
671 #define VSTRIMRIGHTMAX  0x7     /* ${var%%pattern} */
672 #define VSTRIMLEFT      0x8     /* ${var#pattern} */
673 #define VSTRIMLEFTMAX   0x9     /* ${var##pattern} */
674 #define VSLENGTH        0xa     /* ${#var} */
675 #if BASH_SUBSTR
676 #define VSSUBSTR        0xc     /* ${var:position:length} */
677 #endif
678 #if BASH_PATTERN_SUBST
679 #define VSREPLACE       0xd     /* ${var/pattern/replacement} */
680 #define VSREPLACEALL    0xe     /* ${var//pattern/replacement} */
681 #endif
682
683 static const char dolatstr[] ALIGN1 = {
684         CTLQUOTEMARK, CTLVAR, VSNORMAL, '@', '=', CTLQUOTEMARK, '\0'
685 };
686 #define DOLATSTRLEN 6
687
688 #define NCMD      0
689 #define NPIPE     1
690 #define NREDIR    2
691 #define NBACKGND  3
692 #define NSUBSHELL 4
693 #define NAND      5
694 #define NOR       6
695 #define NSEMI     7
696 #define NIF       8
697 #define NWHILE    9
698 #define NUNTIL   10
699 #define NFOR     11
700 #define NCASE    12
701 #define NCLIST   13
702 #define NDEFUN   14
703 #define NARG     15
704 #define NTO      16
705 #if BASH_REDIR_OUTPUT
706 #define NTO2     17
707 #endif
708 #define NCLOBBER 18
709 #define NFROM    19
710 #define NFROMTO  20
711 #define NAPPEND  21
712 #define NTOFD    22
713 #define NFROMFD  23
714 #define NHERE    24
715 #define NXHERE   25
716 #define NNOT     26
717 #define N_NUMBER 27
718
719 union node;
720
721 struct ncmd {
722         smallint type; /* Nxxxx */
723         union node *assign;
724         union node *args;
725         union node *redirect;
726 };
727
728 struct npipe {
729         smallint type;
730         smallint pipe_backgnd;
731         struct nodelist *cmdlist;
732 };
733
734 struct nredir {
735         smallint type;
736         union node *n;
737         union node *redirect;
738 };
739
740 struct nbinary {
741         smallint type;
742         union node *ch1;
743         union node *ch2;
744 };
745
746 struct nif {
747         smallint type;
748         union node *test;
749         union node *ifpart;
750         union node *elsepart;
751 };
752
753 struct nfor {
754         smallint type;
755         union node *args;
756         union node *body;
757         char *var;
758 };
759
760 struct ncase {
761         smallint type;
762         union node *expr;
763         union node *cases;
764 };
765
766 struct nclist {
767         smallint type;
768         union node *next;
769         union node *pattern;
770         union node *body;
771 };
772
773 struct narg {
774         smallint type;
775         union node *next;
776         char *text;
777         struct nodelist *backquote;
778 };
779
780 /* nfile and ndup layout must match!
781  * NTOFD (>&fdnum) uses ndup structure, but we may discover mid-flight
782  * that it is actually NTO2 (>&file), and change its type.
783  */
784 struct nfile {
785         smallint type;
786         union node *next;
787         int fd;
788         int _unused_dupfd;
789         union node *fname;
790         char *expfname;
791 };
792
793 struct ndup {
794         smallint type;
795         union node *next;
796         int fd;
797         int dupfd;
798         union node *vname;
799         char *_unused_expfname;
800 };
801
802 struct nhere {
803         smallint type;
804         union node *next;
805         int fd;
806         union node *doc;
807 };
808
809 struct nnot {
810         smallint type;
811         union node *com;
812 };
813
814 union node {
815         smallint type;
816         struct ncmd ncmd;
817         struct npipe npipe;
818         struct nredir nredir;
819         struct nbinary nbinary;
820         struct nif nif;
821         struct nfor nfor;
822         struct ncase ncase;
823         struct nclist nclist;
824         struct narg narg;
825         struct nfile nfile;
826         struct ndup ndup;
827         struct nhere nhere;
828         struct nnot nnot;
829 };
830
831 /*
832  * NODE_EOF is returned by parsecmd when it encounters an end of file.
833  * It must be distinct from NULL.
834  */
835 #define NODE_EOF ((union node *) -1L)
836
837 struct nodelist {
838         struct nodelist *next;
839         union node *n;
840 };
841
842 struct funcnode {
843         int count;
844         union node n;
845 };
846
847 /*
848  * Free a parse tree.
849  */
850 static void
851 freefunc(struct funcnode *f)
852 {
853         if (f && --f->count < 0)
854                 free(f);
855 }
856
857
858 /* ============ Debugging output */
859
860 #if DEBUG
861
862 static FILE *tracefile;
863
864 static void
865 trace_printf(const char *fmt, ...)
866 {
867         va_list va;
868
869         if (debug != 1)
870                 return;
871         if (DEBUG_TIME)
872                 fprintf(tracefile, "%u ", (int) time(NULL));
873         if (DEBUG_PID)
874                 fprintf(tracefile, "[%u] ", (int) getpid());
875         if (DEBUG_SIG)
876                 fprintf(tracefile, "pending s:%d i:%d(supp:%d) ", pending_sig, pending_int, suppress_int);
877         va_start(va, fmt);
878         vfprintf(tracefile, fmt, va);
879         va_end(va);
880 }
881
882 static void
883 trace_vprintf(const char *fmt, va_list va)
884 {
885         if (debug != 1)
886                 return;
887         vfprintf(tracefile, fmt, va);
888         fprintf(tracefile, "\n");
889 }
890
891 static void
892 trace_puts(const char *s)
893 {
894         if (debug != 1)
895                 return;
896         fputs(s, tracefile);
897 }
898
899 static void
900 trace_puts_quoted(char *s)
901 {
902         char *p;
903         char c;
904
905         if (debug != 1)
906                 return;
907         putc('"', tracefile);
908         for (p = s; *p; p++) {
909                 switch ((unsigned char)*p) {
910                 case '\n': c = 'n'; goto backslash;
911                 case '\t': c = 't'; goto backslash;
912                 case '\r': c = 'r'; goto backslash;
913                 case '\"': c = '\"'; goto backslash;
914                 case '\\': c = '\\'; goto backslash;
915                 case CTLESC: c = 'e'; goto backslash;
916                 case CTLVAR: c = 'v'; goto backslash;
917                 case CTLBACKQ: c = 'q'; goto backslash;
918  backslash:
919                         putc('\\', tracefile);
920                         putc(c, tracefile);
921                         break;
922                 default:
923                         if (*p >= ' ' && *p <= '~')
924                                 putc(*p, tracefile);
925                         else {
926                                 putc('\\', tracefile);
927                                 putc((*p >> 6) & 03, tracefile);
928                                 putc((*p >> 3) & 07, tracefile);
929                                 putc(*p & 07, tracefile);
930                         }
931                         break;
932                 }
933         }
934         putc('"', tracefile);
935 }
936
937 static void
938 trace_puts_args(char **ap)
939 {
940         if (debug != 1)
941                 return;
942         if (!*ap)
943                 return;
944         while (1) {
945                 trace_puts_quoted(*ap);
946                 if (!*++ap) {
947                         putc('\n', tracefile);
948                         break;
949                 }
950                 putc(' ', tracefile);
951         }
952 }
953
954 static void
955 opentrace(void)
956 {
957         char s[100];
958 #ifdef O_APPEND
959         int flags;
960 #endif
961
962         if (debug != 1) {
963                 if (tracefile)
964                         fflush(tracefile);
965                 /* leave open because libedit might be using it */
966                 return;
967         }
968         strcpy(s, "./trace");
969         if (tracefile) {
970                 if (!freopen(s, "a", tracefile)) {
971                         fprintf(stderr, "Can't re-open %s\n", s);
972                         debug = 0;
973                         return;
974                 }
975         } else {
976                 tracefile = fopen(s, "a");
977                 if (tracefile == NULL) {
978                         fprintf(stderr, "Can't open %s\n", s);
979                         debug = 0;
980                         return;
981                 }
982         }
983 #ifdef O_APPEND
984         flags = fcntl(fileno(tracefile), F_GETFL);
985         if (flags >= 0)
986                 fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND);
987 #endif
988         setlinebuf(tracefile);
989         fputs("\nTracing started.\n", tracefile);
990 }
991
992 static void
993 indent(int amount, char *pfx, FILE *fp)
994 {
995         int i;
996
997         for (i = 0; i < amount; i++) {
998                 if (pfx && i == amount - 1)
999                         fputs(pfx, fp);
1000                 putc('\t', fp);
1001         }
1002 }
1003
1004 /* little circular references here... */
1005 static void shtree(union node *n, int ind, char *pfx, FILE *fp);
1006
1007 static void
1008 sharg(union node *arg, FILE *fp)
1009 {
1010         char *p;
1011         struct nodelist *bqlist;
1012         unsigned char subtype;
1013
1014         if (arg->type != NARG) {
1015                 out1fmt("<node type %d>\n", arg->type);
1016                 abort();
1017         }
1018         bqlist = arg->narg.backquote;
1019         for (p = arg->narg.text; *p; p++) {
1020                 switch ((unsigned char)*p) {
1021                 case CTLESC:
1022                         p++;
1023                         putc(*p, fp);
1024                         break;
1025                 case CTLVAR:
1026                         putc('$', fp);
1027                         putc('{', fp);
1028                         subtype = *++p;
1029                         if (subtype == VSLENGTH)
1030                                 putc('#', fp);
1031
1032                         while (*p != '=') {
1033                                 putc(*p, fp);
1034                                 p++;
1035                         }
1036
1037                         if (subtype & VSNUL)
1038                                 putc(':', fp);
1039
1040                         switch (subtype & VSTYPE) {
1041                         case VSNORMAL:
1042                                 putc('}', fp);
1043                                 break;
1044                         case VSMINUS:
1045                                 putc('-', fp);
1046                                 break;
1047                         case VSPLUS:
1048                                 putc('+', fp);
1049                                 break;
1050                         case VSQUESTION:
1051                                 putc('?', fp);
1052                                 break;
1053                         case VSASSIGN:
1054                                 putc('=', fp);
1055                                 break;
1056                         case VSTRIMLEFT:
1057                                 putc('#', fp);
1058                                 break;
1059                         case VSTRIMLEFTMAX:
1060                                 putc('#', fp);
1061                                 putc('#', fp);
1062                                 break;
1063                         case VSTRIMRIGHT:
1064                                 putc('%', fp);
1065                                 break;
1066                         case VSTRIMRIGHTMAX:
1067                                 putc('%', fp);
1068                                 putc('%', fp);
1069                                 break;
1070                         case VSLENGTH:
1071                                 break;
1072                         default:
1073                                 out1fmt("<subtype %d>", subtype);
1074                         }
1075                         break;
1076                 case CTLENDVAR:
1077                         putc('}', fp);
1078                         break;
1079                 case CTLBACKQ:
1080                         putc('$', fp);
1081                         putc('(', fp);
1082                         shtree(bqlist->n, -1, NULL, fp);
1083                         putc(')', fp);
1084                         break;
1085                 default:
1086                         putc(*p, fp);
1087                         break;
1088                 }
1089         }
1090 }
1091
1092 static void
1093 shcmd(union node *cmd, FILE *fp)
1094 {
1095         union node *np;
1096         int first;
1097         const char *s;
1098         int dftfd;
1099
1100         first = 1;
1101         for (np = cmd->ncmd.args; np; np = np->narg.next) {
1102                 if (!first)
1103                         putc(' ', fp);
1104                 sharg(np, fp);
1105                 first = 0;
1106         }
1107         for (np = cmd->ncmd.redirect; np; np = np->nfile.next) {
1108                 if (!first)
1109                         putc(' ', fp);
1110                 dftfd = 0;
1111                 switch (np->nfile.type) {
1112                 case NTO:      s = ">>"+1; dftfd = 1; break;
1113                 case NCLOBBER: s = ">|"; dftfd = 1; break;
1114                 case NAPPEND:  s = ">>"; dftfd = 1; break;
1115 #if BASH_REDIR_OUTPUT
1116                 case NTO2:
1117 #endif
1118                 case NTOFD:    s = ">&"; dftfd = 1; break;
1119                 case NFROM:    s = "<"; break;
1120                 case NFROMFD:  s = "<&"; break;
1121                 case NFROMTO:  s = "<>"; break;
1122                 default:       s = "*error*"; break;
1123                 }
1124                 if (np->nfile.fd != dftfd)
1125                         fprintf(fp, "%d", np->nfile.fd);
1126                 fputs(s, fp);
1127                 if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) {
1128                         fprintf(fp, "%d", np->ndup.dupfd);
1129                 } else {
1130                         sharg(np->nfile.fname, fp);
1131                 }
1132                 first = 0;
1133         }
1134 }
1135
1136 static void
1137 shtree(union node *n, int ind, char *pfx, FILE *fp)
1138 {
1139         struct nodelist *lp;
1140         const char *s;
1141
1142         if (n == NULL)
1143                 return;
1144
1145         indent(ind, pfx, fp);
1146
1147         if (n == NODE_EOF) {
1148                 fputs("<EOF>", fp);
1149                 return;
1150         }
1151
1152         switch (n->type) {
1153         case NSEMI:
1154                 s = "; ";
1155                 goto binop;
1156         case NAND:
1157                 s = " && ";
1158                 goto binop;
1159         case NOR:
1160                 s = " || ";
1161  binop:
1162                 shtree(n->nbinary.ch1, ind, NULL, fp);
1163                 /* if (ind < 0) */
1164                         fputs(s, fp);
1165                 shtree(n->nbinary.ch2, ind, NULL, fp);
1166                 break;
1167         case NCMD:
1168                 shcmd(n, fp);
1169                 if (ind >= 0)
1170                         putc('\n', fp);
1171                 break;
1172         case NPIPE:
1173                 for (lp = n->npipe.cmdlist; lp; lp = lp->next) {
1174                         shtree(lp->n, 0, NULL, fp);
1175                         if (lp->next)
1176                                 fputs(" | ", fp);
1177                 }
1178                 if (n->npipe.pipe_backgnd)
1179                         fputs(" &", fp);
1180                 if (ind >= 0)
1181                         putc('\n', fp);
1182                 break;
1183         default:
1184                 fprintf(fp, "<node type %d>", n->type);
1185                 if (ind >= 0)
1186                         putc('\n', fp);
1187                 break;
1188         }
1189 }
1190
1191 static void
1192 showtree(union node *n)
1193 {
1194         trace_puts("showtree called\n");
1195         shtree(n, 1, NULL, stderr);
1196 }
1197
1198 #endif /* DEBUG */
1199
1200
1201 /* ============ Parser data */
1202
1203 /*
1204  * ash_vmsg() needs parsefile->fd, hence parsefile definition is moved up.
1205  */
1206 struct strlist {
1207         struct strlist *next;
1208         char *text;
1209 };
1210
1211 struct alias;
1212
1213 struct strpush {
1214         struct strpush *prev;   /* preceding string on stack */
1215         char *prev_string;
1216         int prev_left_in_line;
1217 #if ENABLE_ASH_ALIAS
1218         struct alias *ap;       /* if push was associated with an alias */
1219 #endif
1220         char *string;           /* remember the string since it may change */
1221
1222         /* Remember last two characters for pungetc. */
1223         int lastc[2];
1224
1225         /* Number of outstanding calls to pungetc. */
1226         int unget;
1227 };
1228
1229 struct parsefile {
1230         struct parsefile *prev; /* preceding file on stack */
1231         int linno;              /* current line */
1232         int pf_fd;              /* file descriptor (or -1 if string) */
1233         int left_in_line;       /* number of chars left in this line */
1234         int left_in_buffer;     /* number of chars left in this buffer past the line */
1235         char *next_to_pgetc;    /* next char in buffer */
1236         char *buf;              /* input buffer */
1237         struct strpush *strpush; /* for pushing strings at this level */
1238         struct strpush basestrpush; /* so pushing one is fast */
1239
1240         /* Remember last two characters for pungetc. */
1241         int lastc[2];
1242
1243         /* Number of outstanding calls to pungetc. */
1244         int unget;
1245 };
1246
1247 static struct parsefile basepf;        /* top level input file */
1248 static struct parsefile *g_parsefile = &basepf;  /* current input file */
1249 static int startlinno;                 /* line # where last token started */
1250 static char *commandname;              /* currently executing command */
1251
1252
1253 /* ============ Message printing */
1254
1255 static void
1256 ash_vmsg(const char *msg, va_list ap)
1257 {
1258         fprintf(stderr, "%s: ", arg0);
1259         if (commandname) {
1260                 if (strcmp(arg0, commandname))
1261                         fprintf(stderr, "%s: ", commandname);
1262                 if (!iflag || g_parsefile->pf_fd > 0)
1263                         fprintf(stderr, "line %d: ", startlinno);
1264         }
1265         vfprintf(stderr, msg, ap);
1266         newline_and_flush(stderr);
1267 }
1268
1269 /*
1270  * Exverror is called to raise the error exception.  If the second argument
1271  * is not NULL then error prints an error message using printf style
1272  * formatting.  It then raises the error exception.
1273  */
1274 static void ash_vmsg_and_raise(int, const char *, va_list) NORETURN;
1275 static void
1276 ash_vmsg_and_raise(int cond, const char *msg, va_list ap)
1277 {
1278 #if DEBUG
1279         if (msg) {
1280                 TRACE(("ash_vmsg_and_raise(%d):", cond));
1281                 TRACEV((msg, ap));
1282         } else
1283                 TRACE(("ash_vmsg_and_raise(%d):NULL\n", cond));
1284         if (msg)
1285 #endif
1286                 ash_vmsg(msg, ap);
1287
1288         flush_stdout_stderr();
1289         raise_exception(cond);
1290         /* NOTREACHED */
1291 }
1292
1293 static void ash_msg_and_raise_error(const char *, ...) NORETURN;
1294 static void
1295 ash_msg_and_raise_error(const char *msg, ...)
1296 {
1297         va_list ap;
1298
1299         exitstatus = 2;
1300
1301         va_start(ap, msg);
1302         ash_vmsg_and_raise(EXERROR, msg, ap);
1303         /* NOTREACHED */
1304         va_end(ap);
1305 }
1306
1307 /*
1308  * Use '%m' to append error string on platforms that support it, '%s' and
1309  * strerror() on those that don't.
1310  *
1311  * 'fmt' must be a string literal.
1312  */
1313 #ifdef HAVE_PRINTF_PERCENTM
1314 #define ash_msg_and_raise_perror(fmt, ...) ash_msg_and_raise_error(fmt ": %m", ##__VA_ARGS__)
1315 #else
1316 #define ash_msg_and_raise_perror(fmt, ...) ash_msg_and_raise_error(fmt ": %s", ##__VA_ARGS__, strerror(errno))
1317 #endif
1318
1319 static void raise_error_syntax(const char *) NORETURN;
1320 static void
1321 raise_error_syntax(const char *msg)
1322 {
1323         ash_msg_and_raise_error("syntax error: %s", msg);
1324         /* NOTREACHED */
1325 }
1326
1327 static void ash_msg_and_raise(int, const char *, ...) NORETURN;
1328 static void
1329 ash_msg_and_raise(int cond, const char *msg, ...)
1330 {
1331         va_list ap;
1332
1333         va_start(ap, msg);
1334         ash_vmsg_and_raise(cond, msg, ap);
1335         /* NOTREACHED */
1336         va_end(ap);
1337 }
1338
1339 /*
1340  * error/warning routines for external builtins
1341  */
1342 static void
1343 ash_msg(const char *fmt, ...)
1344 {
1345         va_list ap;
1346
1347         va_start(ap, fmt);
1348         ash_vmsg(fmt, ap);
1349         va_end(ap);
1350 }
1351
1352 /*
1353  * Return a string describing an error.  The returned string may be a
1354  * pointer to a static buffer that will be overwritten on the next call.
1355  * Action describes the operation that got the error.
1356  */
1357 static const char *
1358 errmsg(int e, const char *em)
1359 {
1360         if (e == ENOENT || e == ENOTDIR) {
1361                 return em;
1362         }
1363         return strerror(e);
1364 }
1365
1366
1367 /* ============ Memory allocation */
1368
1369 #if 0
1370 /* I consider these wrappers nearly useless:
1371  * ok, they return you to nearest exception handler, but
1372  * how much memory do you leak in the process, making
1373  * memory starvation worse?
1374  */
1375 static void *
1376 ckrealloc(void * p, size_t nbytes)
1377 {
1378         p = realloc(p, nbytes);
1379         if (!p)
1380                 ash_msg_and_raise_error(bb_msg_memory_exhausted);
1381         return p;
1382 }
1383
1384 static void *
1385 ckmalloc(size_t nbytes)
1386 {
1387         return ckrealloc(NULL, nbytes);
1388 }
1389
1390 static void *
1391 ckzalloc(size_t nbytes)
1392 {
1393         return memset(ckmalloc(nbytes), 0, nbytes);
1394 }
1395
1396 static char *
1397 ckstrdup(const char *s)
1398 {
1399         char *p = strdup(s);
1400         if (!p)
1401                 ash_msg_and_raise_error(bb_msg_memory_exhausted);
1402         return p;
1403 }
1404 #else
1405 /* Using bbox equivalents. They exit if out of memory */
1406 # define ckrealloc xrealloc
1407 # define ckmalloc  xmalloc
1408 # define ckzalloc  xzalloc
1409 # define ckstrdup  xstrdup
1410 #endif
1411
1412 /*
1413  * It appears that grabstackstr() will barf with such alignments
1414  * because stalloc() will return a string allocated in a new stackblock.
1415  */
1416 #define SHELL_ALIGN(nbytes) (((nbytes) + SHELL_SIZE) & ~SHELL_SIZE)
1417 enum {
1418         /* Most machines require the value returned from malloc to be aligned
1419          * in some way.  The following macro will get this right
1420          * on many machines.  */
1421         SHELL_SIZE = sizeof(union { int i; char *cp; double d; }) - 1,
1422         /* Minimum size of a block */
1423         MINSIZE = SHELL_ALIGN(504),
1424 };
1425
1426 struct stack_block {
1427         struct stack_block *prev;
1428         char space[MINSIZE];
1429 };
1430
1431 struct stackmark {
1432         struct stack_block *stackp;
1433         char *stacknxt;
1434         size_t stacknleft;
1435 };
1436
1437
1438 struct globals_memstack {
1439         struct stack_block *g_stackp; // = &stackbase;
1440         char *g_stacknxt; // = stackbase.space;
1441         char *sstrend; // = stackbase.space + MINSIZE;
1442         size_t g_stacknleft; // = MINSIZE;
1443         struct stack_block stackbase;
1444 };
1445 extern struct globals_memstack *const ash_ptr_to_globals_memstack;
1446 #define G_memstack (*ash_ptr_to_globals_memstack)
1447 #define g_stackp     (G_memstack.g_stackp    )
1448 #define g_stacknxt   (G_memstack.g_stacknxt  )
1449 #define sstrend      (G_memstack.sstrend     )
1450 #define g_stacknleft (G_memstack.g_stacknleft)
1451 #define stackbase    (G_memstack.stackbase   )
1452 #define INIT_G_memstack() do { \
1453         (*(struct globals_memstack**)&ash_ptr_to_globals_memstack) = xzalloc(sizeof(G_memstack)); \
1454         barrier(); \
1455         g_stackp = &stackbase; \
1456         g_stacknxt = stackbase.space; \
1457         g_stacknleft = MINSIZE; \
1458         sstrend = stackbase.space + MINSIZE; \
1459 } while (0)
1460
1461
1462 #define stackblock()     ((void *)g_stacknxt)
1463 #define stackblocksize() g_stacknleft
1464
1465 /*
1466  * Parse trees for commands are allocated in lifo order, so we use a stack
1467  * to make this more efficient, and also to avoid all sorts of exception
1468  * handling code to handle interrupts in the middle of a parse.
1469  *
1470  * The size 504 was chosen because the Ultrix malloc handles that size
1471  * well.
1472  */
1473 static void *
1474 stalloc(size_t nbytes)
1475 {
1476         char *p;
1477         size_t aligned;
1478
1479         aligned = SHELL_ALIGN(nbytes);
1480         if (aligned > g_stacknleft) {
1481                 size_t len;
1482                 size_t blocksize;
1483                 struct stack_block *sp;
1484
1485                 blocksize = aligned;
1486                 if (blocksize < MINSIZE)
1487                         blocksize = MINSIZE;
1488                 len = sizeof(struct stack_block) - MINSIZE + blocksize;
1489                 if (len < blocksize)
1490                         ash_msg_and_raise_error(bb_msg_memory_exhausted);
1491                 INT_OFF;
1492                 sp = ckmalloc(len);
1493                 sp->prev = g_stackp;
1494                 g_stacknxt = sp->space;
1495                 g_stacknleft = blocksize;
1496                 sstrend = g_stacknxt + blocksize;
1497                 g_stackp = sp;
1498                 INT_ON;
1499         }
1500         p = g_stacknxt;
1501         g_stacknxt += aligned;
1502         g_stacknleft -= aligned;
1503         return p;
1504 }
1505
1506 static void *
1507 stzalloc(size_t nbytes)
1508 {
1509         return memset(stalloc(nbytes), 0, nbytes);
1510 }
1511
1512 static void
1513 stunalloc(void *p)
1514 {
1515 #if DEBUG
1516         if (!p || (g_stacknxt < (char *)p) || ((char *)p < g_stackp->space)) {
1517                 write(STDERR_FILENO, "stunalloc\n", 10);
1518                 abort();
1519         }
1520 #endif
1521         g_stacknleft += g_stacknxt - (char *)p;
1522         g_stacknxt = p;
1523 }
1524
1525 /*
1526  * Like strdup but works with the ash stack.
1527  */
1528 static char *
1529 sstrdup(const char *p)
1530 {
1531         size_t len = strlen(p) + 1;
1532         return memcpy(stalloc(len), p, len);
1533 }
1534
1535 static inline void
1536 grabstackblock(size_t len)
1537 {
1538         stalloc(len);
1539 }
1540
1541 static void
1542 pushstackmark(struct stackmark *mark, size_t len)
1543 {
1544         mark->stackp = g_stackp;
1545         mark->stacknxt = g_stacknxt;
1546         mark->stacknleft = g_stacknleft;
1547         grabstackblock(len);
1548 }
1549
1550 static void
1551 setstackmark(struct stackmark *mark)
1552 {
1553         pushstackmark(mark, g_stacknxt == g_stackp->space && g_stackp != &stackbase);
1554 }
1555
1556 static void
1557 popstackmark(struct stackmark *mark)
1558 {
1559         struct stack_block *sp;
1560
1561         if (!mark->stackp)
1562                 return;
1563
1564         INT_OFF;
1565         while (g_stackp != mark->stackp) {
1566                 sp = g_stackp;
1567                 g_stackp = sp->prev;
1568                 free(sp);
1569         }
1570         g_stacknxt = mark->stacknxt;
1571         g_stacknleft = mark->stacknleft;
1572         sstrend = mark->stacknxt + mark->stacknleft;
1573         INT_ON;
1574 }
1575
1576 /*
1577  * When the parser reads in a string, it wants to stick the string on the
1578  * stack and only adjust the stack pointer when it knows how big the
1579  * string is.  Stackblock (defined in stack.h) returns a pointer to a block
1580  * of space on top of the stack and stackblocklen returns the length of
1581  * this block.  Growstackblock will grow this space by at least one byte,
1582  * possibly moving it (like realloc).  Grabstackblock actually allocates the
1583  * part of the block that has been used.
1584  */
1585 static void
1586 growstackblock(void)
1587 {
1588         size_t newlen;
1589
1590         newlen = g_stacknleft * 2;
1591         if (newlen < g_stacknleft)
1592                 ash_msg_and_raise_error(bb_msg_memory_exhausted);
1593         if (newlen < 128)
1594                 newlen += 128;
1595
1596         if (g_stacknxt == g_stackp->space && g_stackp != &stackbase) {
1597                 struct stack_block *sp;
1598                 struct stack_block *prevstackp;
1599                 size_t grosslen;
1600
1601                 INT_OFF;
1602                 sp = g_stackp;
1603                 prevstackp = sp->prev;
1604                 grosslen = newlen + sizeof(struct stack_block) - MINSIZE;
1605                 sp = ckrealloc(sp, grosslen);
1606                 sp->prev = prevstackp;
1607                 g_stackp = sp;
1608                 g_stacknxt = sp->space;
1609                 g_stacknleft = newlen;
1610                 sstrend = sp->space + newlen;
1611                 INT_ON;
1612         } else {
1613                 char *oldspace = g_stacknxt;
1614                 size_t oldlen = g_stacknleft;
1615                 char *p = stalloc(newlen);
1616
1617                 /* free the space we just allocated */
1618                 g_stacknxt = memcpy(p, oldspace, oldlen);
1619                 g_stacknleft += newlen;
1620         }
1621 }
1622
1623 /*
1624  * The following routines are somewhat easier to use than the above.
1625  * The user declares a variable of type STACKSTR, which may be declared
1626  * to be a register.  The macro STARTSTACKSTR initializes things.  Then
1627  * the user uses the macro STPUTC to add characters to the string.  In
1628  * effect, STPUTC(c, p) is the same as *p++ = c except that the stack is
1629  * grown as necessary.  When the user is done, she can just leave the
1630  * string there and refer to it using stackblock().  Or she can allocate
1631  * the space for it using grabstackstr().  If it is necessary to allow
1632  * someone else to use the stack temporarily and then continue to grow
1633  * the string, the user should use grabstack to allocate the space, and
1634  * then call ungrabstr(p) to return to the previous mode of operation.
1635  *
1636  * USTPUTC is like STPUTC except that it doesn't check for overflow.
1637  * CHECKSTACKSPACE can be called before USTPUTC to ensure that there
1638  * is space for at least one character.
1639  */
1640 static void *
1641 growstackstr(void)
1642 {
1643         size_t len = stackblocksize();
1644         growstackblock();
1645         return (char *)stackblock() + len;
1646 }
1647
1648 /*
1649  * Called from CHECKSTRSPACE.
1650  */
1651 static char *
1652 makestrspace(size_t newlen, char *p)
1653 {
1654         size_t len = p - g_stacknxt;
1655         size_t size;
1656
1657         for (;;) {
1658                 size_t nleft;
1659
1660                 size = stackblocksize();
1661                 nleft = size - len;
1662                 if (nleft >= newlen)
1663                         break;
1664                 growstackblock();
1665         }
1666         return (char *)stackblock() + len;
1667 }
1668
1669 static char *
1670 stack_nputstr(const char *s, size_t n, char *p)
1671 {
1672         p = makestrspace(n, p);
1673         p = (char *)mempcpy(p, s, n);
1674         return p;
1675 }
1676
1677 static char *
1678 stack_putstr(const char *s, char *p)
1679 {
1680         return stack_nputstr(s, strlen(s), p);
1681 }
1682
1683 static char *
1684 _STPUTC(int c, char *p)
1685 {
1686         if (p == sstrend)
1687                 p = growstackstr();
1688         *p++ = c;
1689         return p;
1690 }
1691
1692 #define STARTSTACKSTR(p)        ((p) = stackblock())
1693 #define STPUTC(c, p)            ((p) = _STPUTC((c), (p)))
1694 #define CHECKSTRSPACE(n, p) do { \
1695         char *q = (p); \
1696         size_t l = (n); \
1697         size_t m = sstrend - q; \
1698         if (l > m) \
1699                 (p) = makestrspace(l, q); \
1700 } while (0)
1701 #define USTPUTC(c, p)           (*(p)++ = (c))
1702 #define STACKSTRNUL(p) do { \
1703         if ((p) == sstrend) \
1704                 (p) = growstackstr(); \
1705         *(p) = '\0'; \
1706 } while (0)
1707 #define STUNPUTC(p)             (--(p))
1708 #define STTOPC(p)               ((p)[-1])
1709 #define STADJUST(amount, p)     ((p) += (amount))
1710
1711 #define grabstackstr(p)         stalloc((char *)(p) - (char *)stackblock())
1712 #define ungrabstackstr(s, p)    stunalloc(s)
1713 #define stackstrend()           ((void *)sstrend)
1714
1715
1716 /* ============ String helpers */
1717
1718 /*
1719  * prefix -- see if pfx is a prefix of string.
1720  */
1721 static char *
1722 prefix(const char *string, const char *pfx)
1723 {
1724         while (*pfx) {
1725                 if (*pfx++ != *string++)
1726                         return NULL;
1727         }
1728         return (char *) string;
1729 }
1730
1731 /*
1732  * Check for a valid number.  This should be elsewhere.
1733  */
1734 static int
1735 is_number(const char *p)
1736 {
1737         do {
1738                 if (!isdigit(*p))
1739                         return 0;
1740         } while (*++p != '\0');
1741         return 1;
1742 }
1743
1744 /*
1745  * Convert a string of digits to an integer, printing an error message on
1746  * failure.
1747  */
1748 static int
1749 number(const char *s)
1750 {
1751         if (!is_number(s))
1752                 ash_msg_and_raise_error(msg_illnum, s);
1753         return atoi(s);
1754 }
1755
1756 /*
1757  * Produce a single quoted string suitable as input to the shell.
1758  * The return string is allocated on the stack.
1759  */
1760 static char *
1761 single_quote(const char *s)
1762 {
1763         char *p;
1764
1765         STARTSTACKSTR(p);
1766
1767         do {
1768                 char *q;
1769                 size_t len;
1770
1771                 len = strchrnul(s, '\'') - s;
1772
1773                 q = p = makestrspace(len + 3, p);
1774
1775                 *q++ = '\'';
1776                 q = (char *)mempcpy(q, s, len);
1777                 *q++ = '\'';
1778                 s += len;
1779
1780                 STADJUST(q - p, p);
1781
1782                 if (*s != '\'')
1783                         break;
1784                 len = 0;
1785                 do len++; while (*++s == '\'');
1786
1787                 q = p = makestrspace(len + 3, p);
1788
1789                 *q++ = '"';
1790                 q = (char *)mempcpy(q, s - len, len);
1791                 *q++ = '"';
1792
1793                 STADJUST(q - p, p);
1794         } while (*s);
1795
1796         USTPUTC('\0', p);
1797
1798         return stackblock();
1799 }
1800
1801 /*
1802  * Produce a possibly single quoted string suitable as input to the shell.
1803  * If quoting was done, the return string is allocated on the stack,
1804  * otherwise a pointer to the original string is returned.
1805  */
1806 static const char *
1807 maybe_single_quote(const char *s)
1808 {
1809         const char *p = s;
1810
1811         while (*p) {
1812                 /* Assuming ACSII */
1813                 /* quote ctrl_chars space !"#$%&'()* */
1814                 if (*p < '+')
1815                         goto need_quoting;
1816                 /* quote ;<=>? */
1817                 if (*p >= ';' && *p <= '?')
1818                         goto need_quoting;
1819                 /* quote `[\ */
1820                 if (*p == '`')
1821                         goto need_quoting;
1822                 if (*p == '[')
1823                         goto need_quoting;
1824                 if (*p == '\\')
1825                         goto need_quoting;
1826                 /* quote {|}~ DEL and high bytes */
1827                 if (*p > 'z')
1828                         goto need_quoting;
1829                 /* Not quoting these: +,-./ 0-9 :@ A-Z ]^_ a-z */
1830                 /* TODO: maybe avoid quoting % */
1831                 p++;
1832         }
1833         return s;
1834
1835  need_quoting:
1836         return single_quote(s);
1837 }
1838
1839
1840 /* ============ nextopt */
1841
1842 static char **argptr;                  /* argument list for builtin commands */
1843 static char *optionarg;                /* set by nextopt (like getopt) */
1844 static char *optptr;                   /* used by nextopt */
1845
1846 /*
1847  * XXX - should get rid of. Have all builtins use getopt(3).
1848  * The library getopt must have the BSD extension static variable
1849  * "optreset", otherwise it can't be used within the shell safely.
1850  *
1851  * Standard option processing (a la getopt) for builtin routines.
1852  * The only argument that is passed to nextopt is the option string;
1853  * the other arguments are unnecessary. It returns the character,
1854  * or '\0' on end of input.
1855  */
1856 static int
1857 nextopt(const char *optstring)
1858 {
1859         char *p;
1860         const char *q;
1861         char c;
1862
1863         p = optptr;
1864         if (p == NULL || *p == '\0') {
1865                 /* We ate entire "-param", take next one */
1866                 p = *argptr;
1867                 if (p == NULL)
1868                         return '\0';
1869                 if (*p != '-')
1870                         return '\0';
1871                 if (*++p == '\0') /* just "-" ? */
1872                         return '\0';
1873                 argptr++;
1874                 if (LONE_DASH(p)) /* "--" ? */
1875                         return '\0';
1876                 /* p => next "-param" */
1877         }
1878         /* p => some option char in the middle of a "-param" */
1879         c = *p++;
1880         for (q = optstring; *q != c;) {
1881                 if (*q == '\0')
1882                         ash_msg_and_raise_error("illegal option -%c", c);
1883                 if (*++q == ':')
1884                         q++;
1885         }
1886         if (*++q == ':') {
1887                 if (*p == '\0') {
1888                         p = *argptr++;
1889                         if (p == NULL)
1890                                 ash_msg_and_raise_error("no arg for -%c option", c);
1891                 }
1892                 optionarg = p;
1893                 p = NULL;
1894         }
1895         optptr = p;
1896         return c;
1897 }
1898
1899
1900 /* ============ Shell variables */
1901
1902 /*
1903  * The parsefile structure pointed to by the global variable parsefile
1904  * contains information about the current file being read.
1905  */
1906 struct shparam {
1907         int nparam;             /* # of positional parameters (without $0) */
1908 #if ENABLE_ASH_GETOPTS
1909         int optind;             /* next parameter to be processed by getopts */
1910         int optoff;             /* used by getopts */
1911 #endif
1912         unsigned char malloced; /* if parameter list dynamically allocated */
1913         char **p;               /* parameter list */
1914 };
1915
1916 /*
1917  * Free the list of positional parameters.
1918  */
1919 static void
1920 freeparam(volatile struct shparam *param)
1921 {
1922         if (param->malloced) {
1923                 char **ap, **ap1;
1924                 ap = ap1 = param->p;
1925                 while (*ap)
1926                         free(*ap++);
1927                 free(ap1);
1928         }
1929 }
1930
1931 #if ENABLE_ASH_GETOPTS
1932 static void FAST_FUNC getoptsreset(const char *value);
1933 #endif
1934
1935 struct var {
1936         struct var *next;               /* next entry in hash list */
1937         int flags;                      /* flags are defined above */
1938         const char *var_text;           /* name=value */
1939         void (*var_func)(const char *) FAST_FUNC; /* function to be called when  */
1940                                         /* the variable gets set/unset */
1941 };
1942
1943 struct localvar {
1944         struct localvar *next;          /* next local variable in list */
1945         struct var *vp;                 /* the variable that was made local */
1946         int flags;                      /* saved flags */
1947         const char *text;               /* saved text */
1948 };
1949
1950 /* flags */
1951 #define VEXPORT         0x01    /* variable is exported */
1952 #define VREADONLY       0x02    /* variable cannot be modified */
1953 #define VSTRFIXED       0x04    /* variable struct is statically allocated */
1954 #define VTEXTFIXED      0x08    /* text is statically allocated */
1955 #define VSTACK          0x10    /* text is allocated on the stack */
1956 #define VUNSET          0x20    /* the variable is not set */
1957 #define VNOFUNC         0x40    /* don't call the callback function */
1958 #define VNOSET          0x80    /* do not set variable - just readonly test */
1959 #define VNOSAVE         0x100   /* when text is on the heap before setvareq */
1960 #if ENABLE_ASH_RANDOM_SUPPORT
1961 # define VDYNAMIC       0x200   /* dynamic variable */
1962 #else
1963 # define VDYNAMIC       0
1964 #endif
1965
1966
1967 /* Need to be before varinit_data[] */
1968 #if ENABLE_LOCALE_SUPPORT
1969 static void FAST_FUNC
1970 change_lc_all(const char *value)
1971 {
1972         if (value && *value != '\0')
1973                 setlocale(LC_ALL, value);
1974 }
1975 static void FAST_FUNC
1976 change_lc_ctype(const char *value)
1977 {
1978         if (value && *value != '\0')
1979                 setlocale(LC_CTYPE, value);
1980 }
1981 #endif
1982 #if ENABLE_ASH_MAIL
1983 static void chkmail(void);
1984 static void changemail(const char *var_value) FAST_FUNC;
1985 #else
1986 # define chkmail()  ((void)0)
1987 #endif
1988 static void changepath(const char *) FAST_FUNC;
1989 #if ENABLE_ASH_RANDOM_SUPPORT
1990 static void change_random(const char *) FAST_FUNC;
1991 #endif
1992
1993 static const struct {
1994         int flags;
1995         const char *var_text;
1996         void (*var_func)(const char *) FAST_FUNC;
1997 } varinit_data[] = {
1998         /*
1999          * Note: VEXPORT would not work correctly here for NOFORK applets:
2000          * some environment strings may be constant.
2001          */
2002         { VSTRFIXED|VTEXTFIXED       , defifsvar   , NULL            },
2003 #if ENABLE_ASH_MAIL
2004         { VSTRFIXED|VTEXTFIXED|VUNSET, "MAIL"      , changemail      },
2005         { VSTRFIXED|VTEXTFIXED|VUNSET, "MAILPATH"  , changemail      },
2006 #endif
2007         { VSTRFIXED|VTEXTFIXED       , bb_PATH_root_path, changepath },
2008         { VSTRFIXED|VTEXTFIXED       , "PS1=$ "    , NULL            },
2009         { VSTRFIXED|VTEXTFIXED       , "PS2=> "    , NULL            },
2010         { VSTRFIXED|VTEXTFIXED       , "PS4=+ "    , NULL            },
2011 #if ENABLE_ASH_GETOPTS
2012         { VSTRFIXED|VTEXTFIXED       , defoptindvar, getoptsreset    },
2013 #endif
2014 #if ENABLE_ASH_RANDOM_SUPPORT
2015         { VSTRFIXED|VTEXTFIXED|VUNSET|VDYNAMIC, "RANDOM", change_random },
2016 #endif
2017 #if ENABLE_LOCALE_SUPPORT
2018         { VSTRFIXED|VTEXTFIXED|VUNSET, "LC_ALL"    , change_lc_all   },
2019         { VSTRFIXED|VTEXTFIXED|VUNSET, "LC_CTYPE"  , change_lc_ctype },
2020 #endif
2021 #if ENABLE_FEATURE_EDITING_SAVEHISTORY
2022         { VSTRFIXED|VTEXTFIXED|VUNSET, "HISTFILE"  , NULL            },
2023 #endif
2024 };
2025
2026 struct redirtab;
2027
2028 struct globals_var {
2029         struct shparam shellparam;      /* $@ current positional parameters */
2030         struct redirtab *redirlist;
2031         int preverrout_fd;   /* stderr fd: usually 2, unless redirect moved it */
2032         struct var *vartab[VTABSIZE];
2033         struct var varinit[ARRAY_SIZE(varinit_data)];
2034 };
2035 extern struct globals_var *const ash_ptr_to_globals_var;
2036 #define G_var (*ash_ptr_to_globals_var)
2037 #define shellparam    (G_var.shellparam   )
2038 //#define redirlist     (G_var.redirlist    )
2039 #define preverrout_fd (G_var.preverrout_fd)
2040 #define vartab        (G_var.vartab       )
2041 #define varinit       (G_var.varinit      )
2042 #define INIT_G_var() do { \
2043         unsigned i; \
2044         (*(struct globals_var**)&ash_ptr_to_globals_var) = xzalloc(sizeof(G_var)); \
2045         barrier(); \
2046         for (i = 0; i < ARRAY_SIZE(varinit_data); i++) { \
2047                 varinit[i].flags    = varinit_data[i].flags; \
2048                 varinit[i].var_text = varinit_data[i].var_text; \
2049                 varinit[i].var_func = varinit_data[i].var_func; \
2050         } \
2051 } while (0)
2052
2053 #define vifs      varinit[0]
2054 #if ENABLE_ASH_MAIL
2055 # define vmail    (&vifs)[1]
2056 # define vmpath   (&vmail)[1]
2057 # define vpath    (&vmpath)[1]
2058 #else
2059 # define vpath    (&vifs)[1]
2060 #endif
2061 #define vps1      (&vpath)[1]
2062 #define vps2      (&vps1)[1]
2063 #define vps4      (&vps2)[1]
2064 #if ENABLE_ASH_GETOPTS
2065 # define voptind  (&vps4)[1]
2066 # if ENABLE_ASH_RANDOM_SUPPORT
2067 #  define vrandom (&voptind)[1]
2068 # endif
2069 #else
2070 # if ENABLE_ASH_RANDOM_SUPPORT
2071 #  define vrandom (&vps4)[1]
2072 # endif
2073 #endif
2074
2075 /*
2076  * The following macros access the values of the above variables.
2077  * They have to skip over the name.  They return the null string
2078  * for unset variables.
2079  */
2080 #define ifsval()        (vifs.var_text + 4)
2081 #define ifsset()        ((vifs.flags & VUNSET) == 0)
2082 #if ENABLE_ASH_MAIL
2083 # define mailval()      (vmail.var_text + 5)
2084 # define mpathval()     (vmpath.var_text + 9)
2085 # define mpathset()     ((vmpath.flags & VUNSET) == 0)
2086 #endif
2087 #define pathval()       (vpath.var_text + 5)
2088 #define ps1val()        (vps1.var_text + 4)
2089 #define ps2val()        (vps2.var_text + 4)
2090 #define ps4val()        (vps4.var_text + 4)
2091 #if ENABLE_ASH_GETOPTS
2092 # define optindval()    (voptind.var_text + 7)
2093 #endif
2094
2095 #if ENABLE_ASH_GETOPTS
2096 static void FAST_FUNC
2097 getoptsreset(const char *value)
2098 {
2099         shellparam.optind = number(value) ?: 1;
2100         shellparam.optoff = -1;
2101 }
2102 #endif
2103
2104 /*
2105  * Compares two strings up to the first = or '\0'.  The first
2106  * string must be terminated by '='; the second may be terminated by
2107  * either '=' or '\0'.
2108  */
2109 static int
2110 varcmp(const char *p, const char *q)
2111 {
2112         int c, d;
2113
2114         while ((c = *p) == (d = *q)) {
2115                 if (c == '\0' || c == '=')
2116                         goto out;
2117                 p++;
2118                 q++;
2119         }
2120         if (c == '=')
2121                 c = '\0';
2122         if (d == '=')
2123                 d = '\0';
2124  out:
2125         return c - d;
2126 }
2127
2128 /*
2129  * Find the appropriate entry in the hash table from the name.
2130  */
2131 static struct var **
2132 hashvar(const char *p)
2133 {
2134         unsigned hashval;
2135
2136         hashval = ((unsigned char) *p) << 4;
2137         while (*p && *p != '=')
2138                 hashval += (unsigned char) *p++;
2139         return &vartab[hashval % VTABSIZE];
2140 }
2141
2142 static int
2143 vpcmp(const void *a, const void *b)
2144 {
2145         return varcmp(*(const char **)a, *(const char **)b);
2146 }
2147
2148 /*
2149  * This routine initializes the builtin variables.
2150  */
2151 static void
2152 initvar(void)
2153 {
2154         struct var *vp;
2155         struct var *end;
2156         struct var **vpp;
2157
2158         /*
2159          * PS1 depends on uid
2160          */
2161 #if ENABLE_FEATURE_EDITING && ENABLE_FEATURE_EDITING_FANCY_PROMPT
2162         vps1.var_text = "PS1=\\w \\$ ";
2163 #else
2164         if (!geteuid())
2165                 vps1.var_text = "PS1=# ";
2166 #endif
2167         vp = varinit;
2168         end = vp + ARRAY_SIZE(varinit);
2169         do {
2170                 vpp = hashvar(vp->var_text);
2171                 vp->next = *vpp;
2172                 *vpp = vp;
2173         } while (++vp < end);
2174 }
2175
2176 static struct var **
2177 findvar(struct var **vpp, const char *name)
2178 {
2179         for (; *vpp; vpp = &(*vpp)->next) {
2180                 if (varcmp((*vpp)->var_text, name) == 0) {
2181                         break;
2182                 }
2183         }
2184         return vpp;
2185 }
2186
2187 /*
2188  * Find the value of a variable.  Returns NULL if not set.
2189  */
2190 static const char* FAST_FUNC
2191 lookupvar(const char *name)
2192 {
2193         struct var *v;
2194
2195         v = *findvar(hashvar(name), name);
2196         if (v) {
2197 #if ENABLE_ASH_RANDOM_SUPPORT
2198         /*
2199          * Dynamic variables are implemented roughly the same way they are
2200          * in bash. Namely, they're "special" so long as they aren't unset.
2201          * As soon as they're unset, they're no longer dynamic, and dynamic
2202          * lookup will no longer happen at that point. -- PFM.
2203          */
2204                 if (v->flags & VDYNAMIC)
2205                         v->var_func(NULL);
2206 #endif
2207                 if (!(v->flags & VUNSET))
2208                         return var_end(v->var_text);
2209         }
2210         return NULL;
2211 }
2212
2213 #if ENABLE_UNICODE_SUPPORT
2214 static void
2215 reinit_unicode_for_ash(void)
2216 {
2217         /* Unicode support should be activated even if LANG is set
2218          * _during_ shell execution, not only if it was set when
2219          * shell was started. Therefore, re-check LANG every time:
2220          */
2221         if (ENABLE_FEATURE_CHECK_UNICODE_IN_ENV
2222          || ENABLE_UNICODE_USING_LOCALE
2223         ) {
2224                 const char *s = lookupvar("LC_ALL");
2225                 if (!s) s = lookupvar("LC_CTYPE");
2226                 if (!s) s = lookupvar("LANG");
2227                 reinit_unicode(s);
2228         }
2229 }
2230 #else
2231 # define reinit_unicode_for_ash() ((void)0)
2232 #endif
2233
2234 /*
2235  * Search the environment of a builtin command.
2236  */
2237 static ALWAYS_INLINE const char *
2238 bltinlookup(const char *name)
2239 {
2240         return lookupvar(name);
2241 }
2242
2243 /*
2244  * Same as setvar except that the variable and value are passed in
2245  * the first argument as name=value.  Since the first argument will
2246  * be actually stored in the table, it should not be a string that
2247  * will go away.
2248  * Called with interrupts off.
2249  */
2250 static struct var *
2251 setvareq(char *s, int flags)
2252 {
2253         struct var *vp, **vpp;
2254
2255         vpp = hashvar(s);
2256         flags |= (VEXPORT & (((unsigned) (1 - aflag)) - 1));
2257         vpp = findvar(vpp, s);
2258         vp = *vpp;
2259         if (vp) {
2260                 if ((vp->flags & (VREADONLY|VDYNAMIC)) == VREADONLY) {
2261                         const char *n;
2262
2263                         if (flags & VNOSAVE)
2264                                 free(s);
2265                         n = vp->var_text;
2266                         exitstatus = 1;
2267                         ash_msg_and_raise_error("%.*s: is read only", strchrnul(n, '=') - n, n);
2268                 }
2269
2270                 if (flags & VNOSET)
2271                         goto out;
2272
2273                 if (vp->var_func && !(flags & VNOFUNC))
2274                         vp->var_func(var_end(s));
2275
2276                 if (!(vp->flags & (VTEXTFIXED|VSTACK)))
2277                         free((char*)vp->var_text);
2278
2279                 if (((flags & (VEXPORT|VREADONLY|VSTRFIXED|VUNSET)) | (vp->flags & VSTRFIXED)) == VUNSET) {
2280                         *vpp = vp->next;
2281                         free(vp);
2282  out_free:
2283                         if ((flags & (VTEXTFIXED|VSTACK|VNOSAVE)) == VNOSAVE)
2284                                 free(s);
2285                         goto out;
2286                 }
2287
2288                 flags |= vp->flags & ~(VTEXTFIXED|VSTACK|VNOSAVE|VUNSET);
2289         } else {
2290                 /* variable s is not found */
2291                 if (flags & VNOSET)
2292                         goto out;
2293                 if ((flags & (VEXPORT|VREADONLY|VSTRFIXED|VUNSET)) == VUNSET)
2294                         goto out_free;
2295                 vp = ckzalloc(sizeof(*vp));
2296                 vp->next = *vpp;
2297                 /*vp->func = NULL; - ckzalloc did it */
2298                 *vpp = vp;
2299         }
2300         if (!(flags & (VTEXTFIXED|VSTACK|VNOSAVE)))
2301                 s = ckstrdup(s);
2302         vp->var_text = s;
2303         vp->flags = flags;
2304
2305  out:
2306         return vp;
2307 }
2308
2309 /*
2310  * Set the value of a variable.  The flags argument is ored with the
2311  * flags of the variable.  If val is NULL, the variable is unset.
2312  */
2313 static struct var *
2314 setvar(const char *name, const char *val, int flags)
2315 {
2316         const char *q;
2317         char *p;
2318         char *nameeq;
2319         size_t namelen;
2320         size_t vallen;
2321         struct var *vp;
2322
2323         q = endofname(name);
2324         p = strchrnul(q, '=');
2325         namelen = p - name;
2326         if (!namelen || p != q)
2327                 ash_msg_and_raise_error("%.*s: bad variable name", namelen, name);
2328         vallen = 0;
2329         if (val == NULL) {
2330                 flags |= VUNSET;
2331         } else {
2332                 vallen = strlen(val);
2333         }
2334
2335         INT_OFF;
2336         nameeq = ckmalloc(namelen + vallen + 2);
2337         p = mempcpy(nameeq, name, namelen);
2338         if (val) {
2339                 *p++ = '=';
2340                 p = mempcpy(p, val, vallen);
2341         }
2342         *p = '\0';
2343         vp = setvareq(nameeq, flags | VNOSAVE);
2344         INT_ON;
2345
2346         return vp;
2347 }
2348
2349 static void FAST_FUNC
2350 setvar0(const char *name, const char *val)
2351 {
2352         setvar(name, val, 0);
2353 }
2354
2355 /*
2356  * Unset the specified variable.
2357  */
2358 static void
2359 unsetvar(const char *s)
2360 {
2361         setvar(s, NULL, 0);
2362 }
2363
2364 /*
2365  * Process a linked list of variable assignments.
2366  */
2367 static void
2368 listsetvar(struct strlist *list_set_var, int flags)
2369 {
2370         struct strlist *lp = list_set_var;
2371
2372         if (!lp)
2373                 return;
2374         INT_OFF;
2375         do {
2376                 setvareq(lp->text, flags);
2377                 lp = lp->next;
2378         } while (lp);
2379         INT_ON;
2380 }
2381
2382 /*
2383  * Generate a list of variables satisfying the given conditions.
2384  */
2385 static char **
2386 listvars(int on, int off, char ***end)
2387 {
2388         struct var **vpp;
2389         struct var *vp;
2390         char **ep;
2391         int mask;
2392
2393         STARTSTACKSTR(ep);
2394         vpp = vartab;
2395         mask = on | off;
2396         do {
2397                 for (vp = *vpp; vp; vp = vp->next) {
2398                         if ((vp->flags & mask) == on) {
2399                                 if (ep == stackstrend())
2400                                         ep = growstackstr();
2401                                 *ep++ = (char*)vp->var_text;
2402                         }
2403                 }
2404         } while (++vpp < vartab + VTABSIZE);
2405         if (ep == stackstrend())
2406                 ep = growstackstr();
2407         if (end)
2408                 *end = ep;
2409         *ep++ = NULL;
2410         return grabstackstr(ep);
2411 }
2412
2413
2414 /* ============ Path search helper
2415  *
2416  * The variable path (passed by reference) should be set to the start
2417  * of the path before the first call; path_advance will update
2418  * this value as it proceeds.  Successive calls to path_advance will return
2419  * the possible path expansions in sequence.  If an option (indicated by
2420  * a percent sign) appears in the path entry then the global variable
2421  * pathopt will be set to point to it; otherwise pathopt will be set to
2422  * NULL.
2423  */
2424 static const char *pathopt;     /* set by path_advance */
2425
2426 static char *
2427 path_advance(const char **path, const char *name)
2428 {
2429         const char *p;
2430         char *q;
2431         const char *start;
2432         size_t len;
2433
2434         if (*path == NULL)
2435                 return NULL;
2436         start = *path;
2437         for (p = start; *p && *p != ':' && *p != '%'; p++)
2438                 continue;
2439         len = p - start + strlen(name) + 2;     /* "2" is for '/' and '\0' */
2440         while (stackblocksize() < len)
2441                 growstackblock();
2442         q = stackblock();
2443         if (p != start) {
2444                 q = mempcpy(q, start, p - start);
2445                 *q++ = '/';
2446         }
2447         strcpy(q, name);
2448         pathopt = NULL;
2449         if (*p == '%') {
2450                 pathopt = ++p;
2451                 while (*p && *p != ':')
2452                         p++;
2453         }
2454         if (*p == ':')
2455                 *path = p + 1;
2456         else
2457                 *path = NULL;
2458         return stalloc(len);
2459 }
2460
2461
2462 /* ============ Prompt */
2463
2464 static smallint doprompt;                   /* if set, prompt the user */
2465 static smallint needprompt;                 /* true if interactive and at start of line */
2466
2467 #if ENABLE_FEATURE_EDITING
2468 static line_input_t *line_input_state;
2469 static const char *cmdedit_prompt;
2470 static void
2471 putprompt(const char *s)
2472 {
2473         if (ENABLE_ASH_EXPAND_PRMT) {
2474                 free((char*)cmdedit_prompt);
2475                 cmdedit_prompt = ckstrdup(s);
2476                 return;
2477         }
2478         cmdedit_prompt = s;
2479 }
2480 #else
2481 static void
2482 putprompt(const char *s)
2483 {
2484         out2str(s);
2485 }
2486 #endif
2487
2488 /* expandstr() needs parsing machinery, so it is far away ahead... */
2489 static const char *expandstr(const char *ps, int syntax_type);
2490 /* Values for syntax param */
2491 #define BASESYNTAX 0    /* not in quotes */
2492 #define DQSYNTAX   1    /* in double quotes */
2493 #define SQSYNTAX   2    /* in single quotes */
2494 #define ARISYNTAX  3    /* in arithmetic */
2495 #if ENABLE_ASH_EXPAND_PRMT
2496 # define PSSYNTAX  4    /* prompt. never passed to SIT() */
2497 #endif
2498 /* PSSYNTAX expansion is identical to DQSYNTAX, except keeping '\$' as '\$' */
2499
2500 /*
2501  * called by editline -- any expansions to the prompt should be added here.
2502  */
2503 static void
2504 setprompt_if(smallint do_set, int whichprompt)
2505 {
2506         const char *prompt;
2507         IF_ASH_EXPAND_PRMT(struct stackmark smark;)
2508
2509         if (!do_set)
2510                 return;
2511
2512         needprompt = 0;
2513
2514         switch (whichprompt) {
2515         case 1:
2516                 prompt = ps1val();
2517                 break;
2518         case 2:
2519                 prompt = ps2val();
2520                 break;
2521         default:                        /* 0 */
2522                 prompt = nullstr;
2523         }
2524 #if ENABLE_ASH_EXPAND_PRMT
2525         pushstackmark(&smark, stackblocksize());
2526         putprompt(expandstr(prompt, PSSYNTAX));
2527         popstackmark(&smark);
2528 #else
2529         putprompt(prompt);
2530 #endif
2531 }
2532
2533
2534 /* ============ The cd and pwd commands */
2535
2536 #define CD_PHYSICAL 1
2537 #define CD_PRINT 2
2538
2539 static int
2540 cdopt(void)
2541 {
2542         int flags = 0;
2543         int i, j;
2544
2545         j = 'L';
2546         while ((i = nextopt("LP")) != '\0') {
2547                 if (i != j) {
2548                         flags ^= CD_PHYSICAL;
2549                         j = i;
2550                 }
2551         }
2552
2553         return flags;
2554 }
2555
2556 /*
2557  * Update curdir (the name of the current directory) in response to a
2558  * cd command.
2559  */
2560 static const char *
2561 updatepwd(const char *dir)
2562 {
2563         char *new;
2564         char *p;
2565         char *cdcomppath;
2566         const char *lim;
2567
2568         cdcomppath = sstrdup(dir);
2569         STARTSTACKSTR(new);
2570         if (*dir != '/') {
2571                 if (curdir == nullstr)
2572                         return 0;
2573                 new = stack_putstr(curdir, new);
2574         }
2575         new = makestrspace(strlen(dir) + 2, new);
2576         lim = (char *)stackblock() + 1;
2577         if (*dir != '/') {
2578                 if (new[-1] != '/')
2579                         USTPUTC('/', new);
2580                 if (new > lim && *lim == '/')
2581                         lim++;
2582         } else {
2583                 USTPUTC('/', new);
2584                 cdcomppath++;
2585                 if (dir[1] == '/' && dir[2] != '/') {
2586                         USTPUTC('/', new);
2587                         cdcomppath++;
2588                         lim++;
2589                 }
2590         }
2591         p = strtok(cdcomppath, "/");
2592         while (p) {
2593                 switch (*p) {
2594                 case '.':
2595                         if (p[1] == '.' && p[2] == '\0') {
2596                                 while (new > lim) {
2597                                         STUNPUTC(new);
2598                                         if (new[-1] == '/')
2599                                                 break;
2600                                 }
2601                                 break;
2602                         }
2603                         if (p[1] == '\0')
2604                                 break;
2605                         /* fall through */
2606                 default:
2607                         new = stack_putstr(p, new);
2608                         USTPUTC('/', new);
2609                 }
2610                 p = strtok(NULL, "/");
2611         }
2612         if (new > lim)
2613                 STUNPUTC(new);
2614         *new = 0;
2615         return stackblock();
2616 }
2617
2618 /*
2619  * Find out what the current directory is. If we already know the current
2620  * directory, this routine returns immediately.
2621  */
2622 static char *
2623 getpwd(void)
2624 {
2625         char *dir = getcwd(NULL, 0); /* huh, using glibc extension? */
2626         return dir ? dir : nullstr;
2627 }
2628
2629 static void
2630 setpwd(const char *val, int setold)
2631 {
2632         char *oldcur, *dir;
2633
2634         oldcur = dir = curdir;
2635
2636         if (setold) {
2637                 setvar("OLDPWD", oldcur, VEXPORT);
2638         }
2639         INT_OFF;
2640         if (physdir != nullstr) {
2641                 if (physdir != oldcur)
2642                         free(physdir);
2643                 physdir = nullstr;
2644         }
2645         if (oldcur == val || !val) {
2646                 char *s = getpwd();
2647                 physdir = s;
2648                 if (!val)
2649                         dir = s;
2650         } else
2651                 dir = ckstrdup(val);
2652         if (oldcur != dir && oldcur != nullstr) {
2653                 free(oldcur);
2654         }
2655         curdir = dir;
2656         INT_ON;
2657         setvar("PWD", dir, VEXPORT);
2658 }
2659
2660 static void hashcd(void);
2661
2662 /*
2663  * Actually do the chdir.  We also call hashcd to let other routines
2664  * know that the current directory has changed.
2665  */
2666 static int
2667 docd(const char *dest, int flags)
2668 {
2669         const char *dir = NULL;
2670         int err;
2671
2672         TRACE(("docd(\"%s\", %d) called\n", dest, flags));
2673
2674         INT_OFF;
2675         if (!(flags & CD_PHYSICAL)) {
2676                 dir = updatepwd(dest);
2677                 if (dir)
2678                         dest = dir;
2679         }
2680         err = chdir(dest);
2681         if (err)
2682                 goto out;
2683         setpwd(dir, 1);
2684         hashcd();
2685  out:
2686         INT_ON;
2687         return err;
2688 }
2689
2690 static int FAST_FUNC
2691 cdcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
2692 {
2693         const char *dest;
2694         const char *path;
2695         const char *p;
2696         char c;
2697         struct stat statb;
2698         int flags;
2699
2700         flags = cdopt();
2701         dest = *argptr;
2702         if (!dest)
2703                 dest = bltinlookup("HOME");
2704         else if (LONE_DASH(dest)) {
2705                 dest = bltinlookup("OLDPWD");
2706                 flags |= CD_PRINT;
2707         }
2708         if (!dest)
2709                 dest = nullstr;
2710         if (*dest == '/')
2711                 goto step6;
2712         if (*dest == '.') {
2713                 c = dest[1];
2714  dotdot:
2715                 switch (c) {
2716                 case '\0':
2717                 case '/':
2718                         goto step6;
2719                 case '.':
2720                         c = dest[2];
2721                         if (c != '.')
2722                                 goto dotdot;
2723                 }
2724         }
2725         if (!*dest)
2726                 dest = ".";
2727         path = bltinlookup("CDPATH");
2728         while (path) {
2729                 c = *path;
2730                 p = path_advance(&path, dest);
2731                 if (stat(p, &statb) >= 0 && S_ISDIR(statb.st_mode)) {
2732                         if (c && c != ':')
2733                                 flags |= CD_PRINT;
2734  docd:
2735                         if (!docd(p, flags))
2736                                 goto out;
2737                         goto err;
2738                 }
2739         }
2740
2741  step6:
2742         p = dest;
2743         goto docd;
2744
2745  err:
2746         ash_msg_and_raise_error("can't cd to %s", dest);
2747         /* NOTREACHED */
2748  out:
2749         if (flags & CD_PRINT)
2750                 out1fmt("%s\n", curdir);
2751         return 0;
2752 }
2753
2754 static int FAST_FUNC
2755 pwdcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
2756 {
2757         int flags;
2758         const char *dir = curdir;
2759
2760         flags = cdopt();
2761         if (flags) {
2762                 if (physdir == nullstr)
2763                         setpwd(dir, 0);
2764                 dir = physdir;
2765         }
2766         out1fmt("%s\n", dir);
2767         return 0;
2768 }
2769
2770
2771 /* ============ ... */
2772
2773
2774 #define IBUFSIZ (ENABLE_FEATURE_EDITING ? CONFIG_FEATURE_EDITING_MAX_LEN : 1024)
2775
2776 /* Syntax classes */
2777 #define CWORD     0             /* character is nothing special */
2778 #define CNL       1             /* newline character */
2779 #define CBACK     2             /* a backslash character */
2780 #define CSQUOTE   3             /* single quote */
2781 #define CDQUOTE   4             /* double quote */
2782 #define CENDQUOTE 5             /* a terminating quote */
2783 #define CBQUOTE   6             /* backwards single quote */
2784 #define CVAR      7             /* a dollar sign */
2785 #define CENDVAR   8             /* a '}' character */
2786 #define CLP       9             /* a left paren in arithmetic */
2787 #define CRP      10             /* a right paren in arithmetic */
2788 #define CENDFILE 11             /* end of file */
2789 #define CCTL     12             /* like CWORD, except it must be escaped */
2790 #define CSPCL    13             /* these terminate a word */
2791 #define CIGN     14             /* character should be ignored */
2792
2793 #define PEOF     256
2794 #if ENABLE_ASH_ALIAS
2795 # define PEOA    257
2796 #endif
2797
2798 #define USE_SIT_FUNCTION ENABLE_ASH_OPTIMIZE_FOR_SIZE
2799
2800 #if ENABLE_FEATURE_SH_MATH
2801 # define SIT_ITEM(a,b,c,d) (a | (b << 4) | (c << 8) | (d << 12))
2802 #else
2803 # define SIT_ITEM(a,b,c,d) (a | (b << 4) | (c << 8))
2804 #endif
2805 static const uint16_t S_I_T[] ALIGN2 = {
2806 #if ENABLE_ASH_ALIAS
2807         SIT_ITEM(CSPCL   , CIGN     , CIGN , CIGN   ),    /* 0, PEOA */
2808 #endif
2809         SIT_ITEM(CSPCL   , CWORD    , CWORD, CWORD  ),    /* 1, ' ' */
2810         SIT_ITEM(CNL     , CNL      , CNL  , CNL    ),    /* 2, \n */
2811         SIT_ITEM(CWORD   , CCTL     , CCTL , CWORD  ),    /* 3, !*-/:=?[]~ */
2812         SIT_ITEM(CDQUOTE , CENDQUOTE, CWORD, CWORD  ),    /* 4, '"' */
2813         SIT_ITEM(CVAR    , CVAR     , CWORD, CVAR   ),    /* 5, $ */
2814         SIT_ITEM(CSQUOTE , CWORD    , CENDQUOTE, CWORD),  /* 6, "'" */
2815         SIT_ITEM(CSPCL   , CWORD    , CWORD, CLP    ),    /* 7, ( */
2816         SIT_ITEM(CSPCL   , CWORD    , CWORD, CRP    ),    /* 8, ) */
2817         SIT_ITEM(CBACK   , CBACK    , CCTL , CBACK  ),    /* 9, \ */
2818         SIT_ITEM(CBQUOTE , CBQUOTE  , CWORD, CBQUOTE),    /* 10, ` */
2819         SIT_ITEM(CENDVAR , CENDVAR  , CWORD, CENDVAR),    /* 11, } */
2820 #if !USE_SIT_FUNCTION
2821         SIT_ITEM(CENDFILE, CENDFILE , CENDFILE, CENDFILE),/* 12, PEOF */
2822         SIT_ITEM(CWORD   , CWORD    , CWORD, CWORD  ),    /* 13, 0-9A-Za-z */
2823         SIT_ITEM(CCTL    , CCTL     , CCTL , CCTL   )     /* 14, CTLESC ... */
2824 #endif
2825 #undef SIT_ITEM
2826 };
2827 /* Constants below must match table above */
2828 enum {
2829 #if ENABLE_ASH_ALIAS
2830         CSPCL_CIGN_CIGN_CIGN               , /*  0 */
2831 #endif
2832         CSPCL_CWORD_CWORD_CWORD            , /*  1 */
2833         CNL_CNL_CNL_CNL                    , /*  2 */
2834         CWORD_CCTL_CCTL_CWORD              , /*  3 */
2835         CDQUOTE_CENDQUOTE_CWORD_CWORD      , /*  4 */
2836         CVAR_CVAR_CWORD_CVAR               , /*  5 */
2837         CSQUOTE_CWORD_CENDQUOTE_CWORD      , /*  6 */
2838         CSPCL_CWORD_CWORD_CLP              , /*  7 */
2839         CSPCL_CWORD_CWORD_CRP              , /*  8 */
2840         CBACK_CBACK_CCTL_CBACK             , /*  9 */
2841         CBQUOTE_CBQUOTE_CWORD_CBQUOTE      , /* 10 */
2842         CENDVAR_CENDVAR_CWORD_CENDVAR      , /* 11 */
2843         CENDFILE_CENDFILE_CENDFILE_CENDFILE, /* 12 */
2844         CWORD_CWORD_CWORD_CWORD            , /* 13 */
2845         CCTL_CCTL_CCTL_CCTL                , /* 14 */
2846 };
2847
2848 /* c in SIT(c, syntax) must be an *unsigned char* or PEOA or PEOF,
2849  * caller must ensure proper cast on it if c is *char_ptr!
2850  */
2851 #if USE_SIT_FUNCTION
2852
2853 static int
2854 SIT(int c, int syntax)
2855 {
2856         /* Used to also have '/' in this string: "\t\n !\"$&'()*-/:;<=>?[\\]`|}~" */
2857         static const char spec_symbls[] ALIGN1 = "\t\n !\"$&'()*-:;<=>?[\\]`|}~";
2858         /*
2859          * This causes '/' to be prepended with CTLESC in dquoted string,
2860          * making "./file"* treated incorrectly because we feed
2861          * ".\/file*" string to glob(), confusing it (see expandmeta func).
2862          * The "homegrown" glob implementation is okay with that,
2863          * but glibc one isn't. With '/' always treated as CWORD,
2864          * both work fine.
2865          */
2866 # if ENABLE_ASH_ALIAS
2867         static const uint8_t syntax_index_table[] ALIGN1 = {
2868                 1, 2, 1, 3, 4, 5, 1, 6,         /* "\t\n !\"$&'" */
2869                 7, 8, 3, 3,/*3,*/3, 1, 1,       /* "()*-/:;<" */
2870                 3, 1, 3, 3, 9, 3, 10, 1,        /* "=>?[\\]`|" */
2871                 11, 3                           /* "}~" */
2872         };
2873 # else
2874         static const uint8_t syntax_index_table[] ALIGN1 = {
2875                 0, 1, 0, 2, 3, 4, 0, 5,         /* "\t\n !\"$&'" */
2876                 6, 7, 2, 2,/*2,*/2, 0, 0,       /* "()*-/:;<" */
2877                 2, 0, 2, 2, 8, 2, 9, 0,         /* "=>?[\\]`|" */
2878                 10, 2                           /* "}~" */
2879         };
2880 # endif
2881         const char *s;
2882         int indx;
2883
2884         if (c == PEOF)
2885                 return CENDFILE;
2886 # if ENABLE_ASH_ALIAS
2887         if (c == PEOA)
2888                 indx = 0;
2889         else
2890 # endif
2891         {
2892                 /* Cast is purely for paranoia here,
2893                  * just in case someone passed signed char to us */
2894                 if ((unsigned char)c >= CTL_FIRST
2895                  && (unsigned char)c <= CTL_LAST
2896                 ) {
2897                         return CCTL;
2898                 }
2899                 s = strchrnul(spec_symbls, c);
2900                 if (*s == '\0')
2901                         return CWORD;
2902                 indx = syntax_index_table[s - spec_symbls];
2903         }
2904         return (S_I_T[indx] >> (syntax*4)) & 0xf;
2905 }
2906
2907 #else   /* !USE_SIT_FUNCTION */
2908
2909 static const uint8_t syntax_index_table[] ALIGN1 = {
2910         /* BASESYNTAX_DQSYNTAX_SQSYNTAX_ARISYNTAX */
2911         /*   0      */ CWORD_CWORD_CWORD_CWORD,
2912         /*   1      */ CWORD_CWORD_CWORD_CWORD,
2913         /*   2      */ CWORD_CWORD_CWORD_CWORD,
2914         /*   3      */ CWORD_CWORD_CWORD_CWORD,
2915         /*   4      */ CWORD_CWORD_CWORD_CWORD,
2916         /*   5      */ CWORD_CWORD_CWORD_CWORD,
2917         /*   6      */ CWORD_CWORD_CWORD_CWORD,
2918         /*   7      */ CWORD_CWORD_CWORD_CWORD,
2919         /*   8      */ CWORD_CWORD_CWORD_CWORD,
2920         /*   9 "\t" */ CSPCL_CWORD_CWORD_CWORD,
2921         /*  10 "\n" */ CNL_CNL_CNL_CNL,
2922         /*  11      */ CWORD_CWORD_CWORD_CWORD,
2923         /*  12      */ CWORD_CWORD_CWORD_CWORD,
2924         /*  13      */ CWORD_CWORD_CWORD_CWORD,
2925         /*  14      */ CWORD_CWORD_CWORD_CWORD,
2926         /*  15      */ CWORD_CWORD_CWORD_CWORD,
2927         /*  16      */ CWORD_CWORD_CWORD_CWORD,
2928         /*  17      */ CWORD_CWORD_CWORD_CWORD,
2929         /*  18      */ CWORD_CWORD_CWORD_CWORD,
2930         /*  19      */ CWORD_CWORD_CWORD_CWORD,
2931         /*  20      */ CWORD_CWORD_CWORD_CWORD,
2932         /*  21      */ CWORD_CWORD_CWORD_CWORD,
2933         /*  22      */ CWORD_CWORD_CWORD_CWORD,
2934         /*  23      */ CWORD_CWORD_CWORD_CWORD,
2935         /*  24      */ CWORD_CWORD_CWORD_CWORD,
2936         /*  25      */ CWORD_CWORD_CWORD_CWORD,
2937         /*  26      */ CWORD_CWORD_CWORD_CWORD,
2938         /*  27      */ CWORD_CWORD_CWORD_CWORD,
2939         /*  28      */ CWORD_CWORD_CWORD_CWORD,
2940         /*  29      */ CWORD_CWORD_CWORD_CWORD,
2941         /*  30      */ CWORD_CWORD_CWORD_CWORD,
2942         /*  31      */ CWORD_CWORD_CWORD_CWORD,
2943         /*  32  " " */ CSPCL_CWORD_CWORD_CWORD,
2944         /*  33  "!" */ CWORD_CCTL_CCTL_CWORD,
2945         /*  34  """ */ CDQUOTE_CENDQUOTE_CWORD_CWORD,
2946         /*  35  "#" */ CWORD_CWORD_CWORD_CWORD,
2947         /*  36  "$" */ CVAR_CVAR_CWORD_CVAR,
2948         /*  37  "%" */ CWORD_CWORD_CWORD_CWORD,
2949         /*  38  "&" */ CSPCL_CWORD_CWORD_CWORD,
2950         /*  39  "'" */ CSQUOTE_CWORD_CENDQUOTE_CWORD,
2951         /*  40  "(" */ CSPCL_CWORD_CWORD_CLP,
2952         /*  41  ")" */ CSPCL_CWORD_CWORD_CRP,
2953         /*  42  "*" */ CWORD_CCTL_CCTL_CWORD,
2954         /*  43  "+" */ CWORD_CWORD_CWORD_CWORD,
2955         /*  44  "," */ CWORD_CWORD_CWORD_CWORD,
2956         /*  45  "-" */ CWORD_CCTL_CCTL_CWORD,
2957         /*  46  "." */ CWORD_CWORD_CWORD_CWORD,
2958 /* "/" was CWORD_CCTL_CCTL_CWORD, see comment in SIT() function why this is changed: */
2959         /*  47  "/" */ CWORD_CWORD_CWORD_CWORD,
2960         /*  48  "0" */ CWORD_CWORD_CWORD_CWORD,
2961         /*  49  "1" */ CWORD_CWORD_CWORD_CWORD,
2962         /*  50  "2" */ CWORD_CWORD_CWORD_CWORD,
2963         /*  51  "3" */ CWORD_CWORD_CWORD_CWORD,
2964         /*  52  "4" */ CWORD_CWORD_CWORD_CWORD,
2965         /*  53  "5" */ CWORD_CWORD_CWORD_CWORD,
2966         /*  54  "6" */ CWORD_CWORD_CWORD_CWORD,
2967         /*  55  "7" */ CWORD_CWORD_CWORD_CWORD,
2968         /*  56  "8" */ CWORD_CWORD_CWORD_CWORD,
2969         /*  57  "9" */ CWORD_CWORD_CWORD_CWORD,
2970         /*  58  ":" */ CWORD_CCTL_CCTL_CWORD,
2971         /*  59  ";" */ CSPCL_CWORD_CWORD_CWORD,
2972         /*  60  "<" */ CSPCL_CWORD_CWORD_CWORD,
2973         /*  61  "=" */ CWORD_CCTL_CCTL_CWORD,
2974         /*  62  ">" */ CSPCL_CWORD_CWORD_CWORD,
2975         /*  63  "?" */ CWORD_CCTL_CCTL_CWORD,
2976         /*  64  "@" */ CWORD_CWORD_CWORD_CWORD,
2977         /*  65  "A" */ CWORD_CWORD_CWORD_CWORD,
2978         /*  66  "B" */ CWORD_CWORD_CWORD_CWORD,
2979         /*  67  "C" */ CWORD_CWORD_CWORD_CWORD,
2980         /*  68  "D" */ CWORD_CWORD_CWORD_CWORD,
2981         /*  69  "E" */ CWORD_CWORD_CWORD_CWORD,
2982         /*  70  "F" */ CWORD_CWORD_CWORD_CWORD,
2983         /*  71  "G" */ CWORD_CWORD_CWORD_CWORD,
2984         /*  72  "H" */ CWORD_CWORD_CWORD_CWORD,
2985         /*  73  "I" */ CWORD_CWORD_CWORD_CWORD,
2986         /*  74  "J" */ CWORD_CWORD_CWORD_CWORD,
2987         /*  75  "K" */ CWORD_CWORD_CWORD_CWORD,
2988         /*  76  "L" */ CWORD_CWORD_CWORD_CWORD,
2989         /*  77  "M" */ CWORD_CWORD_CWORD_CWORD,
2990         /*  78  "N" */ CWORD_CWORD_CWORD_CWORD,
2991         /*  79  "O" */ CWORD_CWORD_CWORD_CWORD,
2992         /*  80  "P" */ CWORD_CWORD_CWORD_CWORD,
2993         /*  81  "Q" */ CWORD_CWORD_CWORD_CWORD,
2994         /*  82  "R" */ CWORD_CWORD_CWORD_CWORD,
2995         /*  83  "S" */ CWORD_CWORD_CWORD_CWORD,
2996         /*  84  "T" */ CWORD_CWORD_CWORD_CWORD,
2997         /*  85  "U" */ CWORD_CWORD_CWORD_CWORD,
2998         /*  86  "V" */ CWORD_CWORD_CWORD_CWORD,
2999         /*  87  "W" */ CWORD_CWORD_CWORD_CWORD,
3000         /*  88  "X" */ CWORD_CWORD_CWORD_CWORD,
3001         /*  89  "Y" */ CWORD_CWORD_CWORD_CWORD,
3002         /*  90  "Z" */ CWORD_CWORD_CWORD_CWORD,
3003         /*  91  "[" */ CWORD_CCTL_CCTL_CWORD,
3004         /*  92  "\" */ CBACK_CBACK_CCTL_CBACK,
3005         /*  93  "]" */ CWORD_CCTL_CCTL_CWORD,
3006         /*  94  "^" */ CWORD_CWORD_CWORD_CWORD,
3007         /*  95  "_" */ CWORD_CWORD_CWORD_CWORD,
3008         /*  96  "`" */ CBQUOTE_CBQUOTE_CWORD_CBQUOTE,
3009         /*  97  "a" */ CWORD_CWORD_CWORD_CWORD,
3010         /*  98  "b" */ CWORD_CWORD_CWORD_CWORD,
3011         /*  99  "c" */ CWORD_CWORD_CWORD_CWORD,
3012         /* 100  "d" */ CWORD_CWORD_CWORD_CWORD,
3013         /* 101  "e" */ CWORD_CWORD_CWORD_CWORD,
3014         /* 102  "f" */ CWORD_CWORD_CWORD_CWORD,
3015         /* 103  "g" */ CWORD_CWORD_CWORD_CWORD,
3016         /* 104  "h" */ CWORD_CWORD_CWORD_CWORD,
3017         /* 105  "i" */ CWORD_CWORD_CWORD_CWORD,
3018         /* 106  "j" */ CWORD_CWORD_CWORD_CWORD,
3019         /* 107  "k" */ CWORD_CWORD_CWORD_CWORD,
3020         /* 108  "l" */ CWORD_CWORD_CWORD_CWORD,
3021         /* 109  "m" */ CWORD_CWORD_CWORD_CWORD,
3022         /* 110  "n" */ CWORD_CWORD_CWORD_CWORD,
3023         /* 111  "o" */ CWORD_CWORD_CWORD_CWORD,
3024         /* 112  "p" */ CWORD_CWORD_CWORD_CWORD,
3025         /* 113  "q" */ CWORD_CWORD_CWORD_CWORD,
3026         /* 114  "r" */ CWORD_CWORD_CWORD_CWORD,
3027         /* 115  "s" */ CWORD_CWORD_CWORD_CWORD,
3028         /* 116  "t" */ CWORD_CWORD_CWORD_CWORD,
3029         /* 117  "u" */ CWORD_CWORD_CWORD_CWORD,
3030         /* 118  "v" */ CWORD_CWORD_CWORD_CWORD,
3031         /* 119  "w" */ CWORD_CWORD_CWORD_CWORD,
3032         /* 120  "x" */ CWORD_CWORD_CWORD_CWORD,
3033         /* 121  "y" */ CWORD_CWORD_CWORD_CWORD,
3034         /* 122  "z" */ CWORD_CWORD_CWORD_CWORD,
3035         /* 123  "{" */ CWORD_CWORD_CWORD_CWORD,
3036         /* 124  "|" */ CSPCL_CWORD_CWORD_CWORD,
3037         /* 125  "}" */ CENDVAR_CENDVAR_CWORD_CENDVAR,
3038         /* 126  "~" */ CWORD_CCTL_CCTL_CWORD,
3039         /* 127  del */ CWORD_CWORD_CWORD_CWORD,
3040         /* 128 0x80 */ CWORD_CWORD_CWORD_CWORD,
3041         /* 129 CTLESC       */ CCTL_CCTL_CCTL_CCTL,
3042         /* 130 CTLVAR       */ CCTL_CCTL_CCTL_CCTL,
3043         /* 131 CTLENDVAR    */ CCTL_CCTL_CCTL_CCTL,
3044         /* 132 CTLBACKQ     */ CCTL_CCTL_CCTL_CCTL,
3045         /* 133 CTLQUOTE     */ CCTL_CCTL_CCTL_CCTL,
3046         /* 134 CTLARI       */ CCTL_CCTL_CCTL_CCTL,
3047         /* 135 CTLENDARI    */ CCTL_CCTL_CCTL_CCTL,
3048         /* 136 CTLQUOTEMARK */ CCTL_CCTL_CCTL_CCTL,
3049         /* 137      */ CWORD_CWORD_CWORD_CWORD,
3050         /* 138      */ CWORD_CWORD_CWORD_CWORD,
3051         /* 139      */ CWORD_CWORD_CWORD_CWORD,
3052         /* 140      */ CWORD_CWORD_CWORD_CWORD,
3053         /* 141      */ CWORD_CWORD_CWORD_CWORD,
3054         /* 142      */ CWORD_CWORD_CWORD_CWORD,
3055         /* 143      */ CWORD_CWORD_CWORD_CWORD,
3056         /* 144      */ CWORD_CWORD_CWORD_CWORD,
3057         /* 145      */ CWORD_CWORD_CWORD_CWORD,
3058         /* 146      */ CWORD_CWORD_CWORD_CWORD,
3059         /* 147      */ CWORD_CWORD_CWORD_CWORD,
3060         /* 148      */ CWORD_CWORD_CWORD_CWORD,
3061         /* 149      */ CWORD_CWORD_CWORD_CWORD,
3062         /* 150      */ CWORD_CWORD_CWORD_CWORD,
3063         /* 151      */ CWORD_CWORD_CWORD_CWORD,
3064         /* 152      */ CWORD_CWORD_CWORD_CWORD,
3065         /* 153      */ CWORD_CWORD_CWORD_CWORD,
3066         /* 154      */ CWORD_CWORD_CWORD_CWORD,
3067         /* 155      */ CWORD_CWORD_CWORD_CWORD,
3068         /* 156      */ CWORD_CWORD_CWORD_CWORD,
3069         /* 157      */ CWORD_CWORD_CWORD_CWORD,
3070         /* 158      */ CWORD_CWORD_CWORD_CWORD,
3071         /* 159      */ CWORD_CWORD_CWORD_CWORD,
3072         /* 160      */ CWORD_CWORD_CWORD_CWORD,
3073         /* 161      */ CWORD_CWORD_CWORD_CWORD,
3074         /* 162      */ CWORD_CWORD_CWORD_CWORD,
3075         /* 163      */ CWORD_CWORD_CWORD_CWORD,
3076         /* 164      */ CWORD_CWORD_CWORD_CWORD,
3077         /* 165      */ CWORD_CWORD_CWORD_CWORD,
3078         /* 166      */ CWORD_CWORD_CWORD_CWORD,
3079         /* 167      */ CWORD_CWORD_CWORD_CWORD,
3080         /* 168      */ CWORD_CWORD_CWORD_CWORD,
3081         /* 169      */ CWORD_CWORD_CWORD_CWORD,
3082         /* 170      */ CWORD_CWORD_CWORD_CWORD,
3083         /* 171      */ CWORD_CWORD_CWORD_CWORD,
3084         /* 172      */ CWORD_CWORD_CWORD_CWORD,
3085         /* 173      */ CWORD_CWORD_CWORD_CWORD,
3086         /* 174      */ CWORD_CWORD_CWORD_CWORD,
3087         /* 175      */ CWORD_CWORD_CWORD_CWORD,
3088         /* 176      */ CWORD_CWORD_CWORD_CWORD,
3089         /* 177      */ CWORD_CWORD_CWORD_CWORD,
3090         /* 178      */ CWORD_CWORD_CWORD_CWORD,
3091         /* 179      */ CWORD_CWORD_CWORD_CWORD,
3092         /* 180      */ CWORD_CWORD_CWORD_CWORD,
3093         /* 181      */ CWORD_CWORD_CWORD_CWORD,
3094         /* 182      */ CWORD_CWORD_CWORD_CWORD,
3095         /* 183      */ CWORD_CWORD_CWORD_CWORD,
3096         /* 184      */ CWORD_CWORD_CWORD_CWORD,
3097         /* 185      */ CWORD_CWORD_CWORD_CWORD,
3098         /* 186      */ CWORD_CWORD_CWORD_CWORD,
3099         /* 187      */ CWORD_CWORD_CWORD_CWORD,
3100         /* 188      */ CWORD_CWORD_CWORD_CWORD,
3101         /* 189      */ CWORD_CWORD_CWORD_CWORD,
3102         /* 190      */ CWORD_CWORD_CWORD_CWORD,
3103         /* 191      */ CWORD_CWORD_CWORD_CWORD,
3104         /* 192      */ CWORD_CWORD_CWORD_CWORD,
3105         /* 193      */ CWORD_CWORD_CWORD_CWORD,
3106         /* 194      */ CWORD_CWORD_CWORD_CWORD,
3107         /* 195      */ CWORD_CWORD_CWORD_CWORD,
3108         /* 196      */ CWORD_CWORD_CWORD_CWORD,
3109         /* 197      */ CWORD_CWORD_CWORD_CWORD,
3110         /* 198      */ CWORD_CWORD_CWORD_CWORD,
3111         /* 199      */ CWORD_CWORD_CWORD_CWORD,
3112         /* 200      */ CWORD_CWORD_CWORD_CWORD,
3113         /* 201      */ CWORD_CWORD_CWORD_CWORD,
3114         /* 202      */ CWORD_CWORD_CWORD_CWORD,
3115         /* 203      */ CWORD_CWORD_CWORD_CWORD,
3116         /* 204      */ CWORD_CWORD_CWORD_CWORD,
3117         /* 205      */ CWORD_CWORD_CWORD_CWORD,
3118         /* 206      */ CWORD_CWORD_CWORD_CWORD,
3119         /* 207      */ CWORD_CWORD_CWORD_CWORD,
3120         /* 208      */ CWORD_CWORD_CWORD_CWORD,
3121         /* 209      */ CWORD_CWORD_CWORD_CWORD,
3122         /* 210      */ CWORD_CWORD_CWORD_CWORD,
3123         /* 211      */ CWORD_CWORD_CWORD_CWORD,
3124         /* 212      */ CWORD_CWORD_CWORD_CWORD,
3125         /* 213      */ CWORD_CWORD_CWORD_CWORD,
3126         /* 214      */ CWORD_CWORD_CWORD_CWORD,
3127         /* 215      */ CWORD_CWORD_CWORD_CWORD,
3128         /* 216      */ CWORD_CWORD_CWORD_CWORD,
3129         /* 217      */ CWORD_CWORD_CWORD_CWORD,
3130         /* 218      */ CWORD_CWORD_CWORD_CWORD,
3131         /* 219      */ CWORD_CWORD_CWORD_CWORD,
3132         /* 220      */ CWORD_CWORD_CWORD_CWORD,
3133         /* 221      */ CWORD_CWORD_CWORD_CWORD,
3134         /* 222      */ CWORD_CWORD_CWORD_CWORD,
3135         /* 223      */ CWORD_CWORD_CWORD_CWORD,
3136         /* 224      */ CWORD_CWORD_CWORD_CWORD,
3137         /* 225      */ CWORD_CWORD_CWORD_CWORD,
3138         /* 226      */ CWORD_CWORD_CWORD_CWORD,
3139         /* 227      */ CWORD_CWORD_CWORD_CWORD,
3140         /* 228      */ CWORD_CWORD_CWORD_CWORD,
3141         /* 229      */ CWORD_CWORD_CWORD_CWORD,
3142         /* 230      */ CWORD_CWORD_CWORD_CWORD,
3143         /* 231      */ CWORD_CWORD_CWORD_CWORD,
3144         /* 232      */ CWORD_CWORD_CWORD_CWORD,
3145         /* 233      */ CWORD_CWORD_CWORD_CWORD,
3146         /* 234      */ CWORD_CWORD_CWORD_CWORD,
3147         /* 235      */ CWORD_CWORD_CWORD_CWORD,
3148         /* 236      */ CWORD_CWORD_CWORD_CWORD,
3149         /* 237      */ CWORD_CWORD_CWORD_CWORD,
3150         /* 238      */ CWORD_CWORD_CWORD_CWORD,
3151         /* 239      */ CWORD_CWORD_CWORD_CWORD,
3152         /* 230      */ CWORD_CWORD_CWORD_CWORD,
3153         /* 241      */ CWORD_CWORD_CWORD_CWORD,
3154         /* 242      */ CWORD_CWORD_CWORD_CWORD,
3155         /* 243      */ CWORD_CWORD_CWORD_CWORD,
3156         /* 244      */ CWORD_CWORD_CWORD_CWORD,
3157         /* 245      */ CWORD_CWORD_CWORD_CWORD,
3158         /* 246      */ CWORD_CWORD_CWORD_CWORD,
3159         /* 247      */ CWORD_CWORD_CWORD_CWORD,
3160         /* 248      */ CWORD_CWORD_CWORD_CWORD,
3161         /* 249      */ CWORD_CWORD_CWORD_CWORD,
3162         /* 250      */ CWORD_CWORD_CWORD_CWORD,
3163         /* 251      */ CWORD_CWORD_CWORD_CWORD,
3164         /* 252      */ CWORD_CWORD_CWORD_CWORD,
3165         /* 253      */ CWORD_CWORD_CWORD_CWORD,
3166         /* 254      */ CWORD_CWORD_CWORD_CWORD,
3167         /* 255      */ CWORD_CWORD_CWORD_CWORD,
3168         /* PEOF */     CENDFILE_CENDFILE_CENDFILE_CENDFILE,
3169 # if ENABLE_ASH_ALIAS
3170         /* PEOA */     CSPCL_CIGN_CIGN_CIGN,
3171 # endif
3172 };
3173
3174 #if 1
3175 # define SIT(c, syntax) ((S_I_T[syntax_index_table[c]] >> ((syntax)*4)) & 0xf)
3176 #else /* debug version, caught one signed char bug */
3177 # define SIT(c, syntax) \
3178         ({ \
3179                 if ((c) < 0 || (c) > (PEOF + ENABLE_ASH_ALIAS)) \
3180                         bb_error_msg_and_die("line:%d c:%d", __LINE__, (c)); \
3181                 if ((syntax) < 0 || (syntax) > (2 + ENABLE_FEATURE_SH_MATH)) \
3182                         bb_error_msg_and_die("line:%d c:%d", __LINE__, (c)); \
3183                 ((S_I_T[syntax_index_table[c]] >> ((syntax)*4)) & 0xf); \
3184         })
3185 #endif
3186
3187 #endif  /* !USE_SIT_FUNCTION */
3188
3189
3190 /* ============ Alias handling */
3191
3192 #if ENABLE_ASH_ALIAS
3193
3194 #define ALIASINUSE 1
3195 #define ALIASDEAD  2
3196
3197 struct alias {
3198         struct alias *next;
3199         char *name;
3200         char *val;
3201         int flag;
3202 };
3203
3204
3205 static struct alias **atab; // [ATABSIZE];
3206 #define INIT_G_alias() do { \
3207         atab = xzalloc(ATABSIZE * sizeof(atab[0])); \
3208 } while (0)
3209
3210
3211 static struct alias **
3212 __lookupalias(const char *name)
3213 {
3214         unsigned int hashval;
3215         struct alias **app;
3216         const char *p;
3217         unsigned int ch;
3218
3219         p = name;
3220
3221         ch = (unsigned char)*p;
3222         hashval = ch << 4;
3223         while (ch) {
3224                 hashval += ch;
3225                 ch = (unsigned char)*++p;
3226         }
3227         app = &atab[hashval % ATABSIZE];
3228
3229         for (; *app; app = &(*app)->next) {
3230                 if (strcmp(name, (*app)->name) == 0) {
3231                         break;
3232                 }
3233         }
3234
3235         return app;
3236 }
3237
3238 static struct alias *
3239 lookupalias(const char *name, int check)
3240 {
3241         struct alias *ap = *__lookupalias(name);
3242
3243         if (check && ap && (ap->flag & ALIASINUSE))
3244                 return NULL;
3245         return ap;
3246 }
3247
3248 static struct alias *
3249 freealias(struct alias *ap)
3250 {
3251         struct alias *next;
3252
3253         if (ap->flag & ALIASINUSE) {
3254                 ap->flag |= ALIASDEAD;
3255                 return ap;
3256         }
3257
3258         next = ap->next;
3259         free(ap->name);
3260         free(ap->val);
3261         free(ap);
3262         return next;
3263 }
3264
3265 static void
3266 setalias(const char *name, const char *val)
3267 {
3268         struct alias *ap, **app;
3269
3270         app = __lookupalias(name);
3271         ap = *app;
3272         INT_OFF;
3273         if (ap) {
3274                 if (!(ap->flag & ALIASINUSE)) {
3275                         free(ap->val);
3276                 }
3277                 ap->val = ckstrdup(val);
3278                 ap->flag &= ~ALIASDEAD;
3279         } else {
3280                 /* not found */
3281                 ap = ckzalloc(sizeof(struct alias));
3282                 ap->name = ckstrdup(name);
3283                 ap->val = ckstrdup(val);
3284                 /*ap->flag = 0; - ckzalloc did it */
3285                 /*ap->next = NULL;*/
3286                 *app = ap;
3287         }
3288         INT_ON;
3289 }
3290
3291 static int
3292 unalias(const char *name)
3293 {
3294         struct alias **app;
3295
3296         app = __lookupalias(name);
3297
3298         if (*app) {
3299                 INT_OFF;
3300                 *app = freealias(*app);
3301                 INT_ON;
3302                 return 0;
3303         }
3304
3305         return 1;
3306 }
3307
3308 static void
3309 rmaliases(void)
3310 {
3311         struct alias *ap, **app;
3312         int i;
3313
3314         INT_OFF;
3315         for (i = 0; i < ATABSIZE; i++) {
3316                 app = &atab[i];
3317                 for (ap = *app; ap; ap = *app) {
3318                         *app = freealias(*app);
3319                         if (ap == *app) {
3320                                 app = &ap->next;
3321                         }
3322                 }
3323         }
3324         INT_ON;
3325 }
3326
3327 static void
3328 printalias(const struct alias *ap)
3329 {
3330         out1fmt("%s=%s\n", ap->name, single_quote(ap->val));
3331 }
3332
3333 /*
3334  * TODO - sort output
3335  */
3336 static int FAST_FUNC
3337 aliascmd(int argc UNUSED_PARAM, char **argv)
3338 {
3339         char *n, *v;
3340         int ret = 0;
3341         struct alias *ap;
3342
3343         if (!argv[1]) {
3344                 int i;
3345
3346                 for (i = 0; i < ATABSIZE; i++) {
3347                         for (ap = atab[i]; ap; ap = ap->next) {
3348                                 printalias(ap);
3349                         }
3350                 }
3351                 return 0;
3352         }
3353         while ((n = *++argv) != NULL) {
3354                 v = strchr(n+1, '=');
3355                 if (v == NULL) { /* n+1: funny ksh stuff */
3356                         ap = *__lookupalias(n);
3357                         if (ap == NULL) {
3358                                 fprintf(stderr, "%s: %s not found\n", "alias", n);
3359                                 ret = 1;
3360                         } else
3361                                 printalias(ap);
3362                 } else {
3363                         *v++ = '\0';
3364                         setalias(n, v);
3365                 }
3366         }
3367
3368         return ret;
3369 }
3370
3371 static int FAST_FUNC
3372 unaliascmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
3373 {
3374         int i;
3375
3376         while (nextopt("a") != '\0') {
3377                 rmaliases();
3378                 return 0;
3379         }
3380         for (i = 0; *argptr; argptr++) {
3381                 if (unalias(*argptr)) {
3382                         fprintf(stderr, "%s: %s not found\n", "unalias", *argptr);
3383                         i = 1;
3384                 }
3385         }
3386
3387         return i;
3388 }
3389
3390 #endif /* ASH_ALIAS */
3391
3392
3393 /* Mode argument to forkshell.  Don't change FORK_FG or FORK_BG. */
3394 #define FORK_FG    0
3395 #define FORK_BG    1
3396 #define FORK_NOJOB 2
3397
3398 /* mode flags for showjob(s) */
3399 #define SHOW_ONLY_PGID  0x01    /* show only pgid (jobs -p) */
3400 #define SHOW_PIDS       0x02    /* show individual pids, not just one line per job */
3401 #define SHOW_CHANGED    0x04    /* only jobs whose state has changed */
3402 #define SHOW_STDERR     0x08    /* print to stderr (else stdout) */
3403
3404 /*
3405  * A job structure contains information about a job.  A job is either a
3406  * single process or a set of processes contained in a pipeline.  In the
3407  * latter case, pidlist will be non-NULL, and will point to a -1 terminated
3408  * array of pids.
3409  */
3410 struct procstat {
3411         pid_t   ps_pid;         /* process id */
3412         int     ps_status;      /* last process status from wait() */
3413         char    *ps_cmd;        /* text of command being run */
3414 };
3415
3416 struct job {
3417         struct procstat ps0;    /* status of process */
3418         struct procstat *ps;    /* status or processes when more than one */
3419 #if JOBS
3420         int stopstatus;         /* status of a stopped job */
3421 #endif
3422         unsigned nprocs;        /* number of processes */
3423
3424 #define JOBRUNNING      0       /* at least one proc running */
3425 #define JOBSTOPPED      1       /* all procs are stopped */
3426 #define JOBDONE         2       /* all procs are completed */
3427         unsigned
3428                 state: 8,
3429 #if JOBS
3430                 sigint: 1,      /* job was killed by SIGINT */
3431                 jobctl: 1,      /* job running under job control */
3432 #endif
3433                 waited: 1,      /* true if this entry has been waited for */
3434                 used: 1,        /* true if this entry is in used */
3435                 changed: 1;     /* true if status has changed */
3436         struct job *prev_job;   /* previous job */
3437 };
3438
3439 static struct job *makejob(/*union node *,*/ int);
3440 static int forkshell(struct job *, union node *, int);
3441 static int waitforjob(struct job *);
3442
3443 #if !JOBS
3444 enum { doing_jobctl = 0 };
3445 #define setjobctl(on) do {} while (0)
3446 #else
3447 static smallint doing_jobctl; //references:8
3448 static void setjobctl(int);
3449 #endif
3450
3451 /*
3452  * Ignore a signal.
3453  */
3454 static void
3455 ignoresig(int signo)
3456 {
3457         /* Avoid unnecessary system calls. Is it already SIG_IGNed? */
3458         if (sigmode[signo - 1] != S_IGN && sigmode[signo - 1] != S_HARD_IGN) {
3459                 /* No, need to do it */
3460                 signal(signo, SIG_IGN);
3461         }
3462         sigmode[signo - 1] = S_HARD_IGN;
3463 }
3464
3465 /*
3466  * Only one usage site - in setsignal()
3467  */
3468 static void
3469 signal_handler(int signo)
3470 {
3471         if (signo == SIGCHLD) {
3472                 got_sigchld = 1;
3473                 if (!trap[SIGCHLD])
3474                         return;
3475         }
3476
3477         gotsig[signo - 1] = 1;
3478         pending_sig = signo;
3479
3480         if (signo == SIGINT && !trap[SIGINT]) {
3481                 if (!suppress_int) {
3482                         pending_sig = 0;
3483                         raise_interrupt(); /* does not return */
3484                 }
3485                 pending_int = 1;
3486         }
3487 }
3488
3489 /*
3490  * Set the signal handler for the specified signal.  The routine figures
3491  * out what it should be set to.
3492  */
3493 static void
3494 setsignal(int signo)
3495 {
3496         char *t;
3497         char cur_act, new_act;
3498         struct sigaction act;
3499
3500         t = trap[signo];
3501         new_act = S_DFL;
3502         if (t != NULL) { /* trap for this sig is set */
3503                 new_act = S_CATCH;
3504                 if (t[0] == '\0') /* trap is "": ignore this sig */
3505                         new_act = S_IGN;
3506         }
3507
3508         if (rootshell && new_act == S_DFL) {
3509                 switch (signo) {
3510                 case SIGINT:
3511                         if (iflag || minusc || sflag == 0)
3512                                 new_act = S_CATCH;
3513                         break;
3514                 case SIGQUIT:
3515 #if DEBUG
3516                         if (debug)
3517                                 break;
3518 #endif
3519                         /* man bash:
3520                          * "In all cases, bash ignores SIGQUIT. Non-builtin
3521                          * commands run by bash have signal handlers
3522                          * set to the values inherited by the shell
3523                          * from its parent". */
3524                         new_act = S_IGN;
3525                         break;
3526                 case SIGTERM:
3527                         if (iflag)
3528                                 new_act = S_IGN;
3529                         break;
3530 #if JOBS
3531                 case SIGTSTP:
3532                 case SIGTTOU:
3533                         if (mflag)
3534                                 new_act = S_IGN;
3535                         break;
3536 #endif
3537                 }
3538         }
3539         /* if !rootshell, we reset SIGQUIT to DFL,
3540          * whereas we have to restore it to what shell got on entry.
3541          * This is handled by the fact that if signal was IGNored on entry,
3542          * then cur_act is S_HARD_IGN and we never change its sigaction
3543          * (see code below).
3544          */
3545
3546         if (signo == SIGCHLD)
3547                 new_act = S_CATCH;
3548
3549         t = &sigmode[signo - 1];
3550         cur_act = *t;
3551         if (cur_act == 0) {
3552                 /* current setting is not yet known */
3553                 if (sigaction(signo, NULL, &act)) {
3554                         /* pretend it worked; maybe we should give a warning,
3555                          * but other shells don't. We don't alter sigmode,
3556                          * so we retry every time.
3557                          * btw, in Linux it never fails. --vda */
3558                         return;
3559                 }
3560                 if (act.sa_handler == SIG_IGN) {
3561                         cur_act = S_HARD_IGN;
3562                         if (mflag
3563                          && (signo == SIGTSTP || signo == SIGTTIN || signo == SIGTTOU)
3564                         ) {
3565                                 cur_act = S_IGN;   /* don't hard ignore these */
3566                         }
3567                 }
3568         }
3569         if (cur_act == S_HARD_IGN || cur_act == new_act)
3570                 return;
3571
3572         *t = new_act;
3573
3574         act.sa_handler = SIG_DFL;
3575         switch (new_act) {
3576         case S_CATCH:
3577                 act.sa_handler = signal_handler;
3578                 break;
3579         case S_IGN:
3580                 act.sa_handler = SIG_IGN;
3581                 break;
3582         }
3583         /* flags and mask matter only if !DFL and !IGN, but we do it
3584          * for all cases for more deterministic behavior:
3585          */
3586         act.sa_flags = 0; //TODO: why not SA_RESTART?
3587         sigfillset(&act.sa_mask);
3588
3589         sigaction_set(signo, &act);
3590 }
3591
3592 /* mode flags for set_curjob */
3593 #define CUR_DELETE 2
3594 #define CUR_RUNNING 1
3595 #define CUR_STOPPED 0
3596
3597 #if JOBS
3598 /* pgrp of shell on invocation */
3599 static int initialpgrp; //references:2
3600 static int ttyfd = -1; //5
3601 #endif
3602 /* array of jobs */
3603 static struct job *jobtab; //5
3604 /* size of array */
3605 static unsigned njobs; //4
3606 /* current job */
3607 static struct job *curjob; //lots
3608 /* number of presumed living untracked jobs */
3609 static int jobless; //4
3610
3611 #if 0
3612 /* Bash has a feature: it restores termios after a successful wait for
3613  * a foreground job which had at least one stopped or sigkilled member.
3614  * The probable rationale is that SIGSTOP and SIGKILL can preclude task from
3615  * properly restoring tty state. Should we do this too?
3616  * A reproducer: ^Z an interactive python:
3617  *
3618  * # python
3619  * Python 2.7.12 (...)
3620  * >>> ^Z
3621  *      { python leaves tty in -icanon -echo state. We do survive that... }
3622  *  [1]+  Stopped                    python
3623  *      { ...however, next program (python #2) does not survive it well: }
3624  * # python
3625  * Python 2.7.12 (...)
3626  * >>> Traceback (most recent call last):
3627  *      { above, I typed "qwerty<CR>", but -echo state is still in effect }
3628  *   File "<stdin>", line 1, in <module>
3629  * NameError: name 'qwerty' is not defined
3630  *
3631  * The implementation below is modeled on bash code and seems to work.
3632  * However, I'm not sure we should do this. For one: what if I'd fg
3633  * the stopped python instead? It'll be confused by "restored" tty state.
3634  */
3635 static struct termios shell_tty_info;
3636 static void
3637 get_tty_state(void)
3638 {
3639         if (rootshell && ttyfd >= 0)
3640                 tcgetattr(ttyfd, &shell_tty_info);
3641 }
3642 static void
3643 set_tty_state(void)
3644 {
3645         /* if (rootshell) - caller ensures this */
3646         if (ttyfd >= 0)
3647                 tcsetattr(ttyfd, TCSADRAIN, &shell_tty_info);
3648 }
3649 static int
3650 job_signal_status(struct job *jp)
3651 {
3652         int status;
3653         unsigned i;
3654         struct procstat *ps = jp->ps;
3655         for (i = 0; i < jp->nprocs; i++) {
3656                 status = ps[i].ps_status;
3657                 if (WIFSIGNALED(status) || WIFSTOPPED(status))
3658                         return status;
3659         }
3660         return 0;
3661 }
3662 static void
3663 restore_tty_if_stopped_or_signaled(struct job *jp)
3664 {
3665 //TODO: check what happens if we come from waitforjob() in expbackq()
3666         if (rootshell) {
3667                 int s = job_signal_status(jp);
3668                 if (s) /* WIFSIGNALED(s) || WIFSTOPPED(s) */
3669                         set_tty_state();
3670         }
3671 }
3672 #else
3673 # define get_tty_state() ((void)0)
3674 # define restore_tty_if_stopped_or_signaled(jp) ((void)0)
3675 #endif
3676
3677 static void
3678 set_curjob(struct job *jp, unsigned mode)
3679 {
3680         struct job *jp1;
3681         struct job **jpp, **curp;
3682
3683         /* first remove from list */
3684         jpp = curp = &curjob;
3685         while (1) {
3686                 jp1 = *jpp;
3687                 if (jp1 == jp)
3688                         break;
3689                 jpp = &jp1->prev_job;
3690         }
3691         *jpp = jp1->prev_job;
3692
3693         /* Then re-insert in correct position */
3694         jpp = curp;
3695         switch (mode) {
3696         default:
3697 #if DEBUG
3698                 abort();
3699 #endif
3700         case CUR_DELETE:
3701                 /* job being deleted */
3702                 break;
3703         case CUR_RUNNING:
3704                 /* newly created job or backgrounded job,
3705                  * put after all stopped jobs.
3706                  */
3707                 while (1) {
3708                         jp1 = *jpp;
3709 #if JOBS
3710                         if (!jp1 || jp1->state != JOBSTOPPED)
3711 #endif
3712                                 break;
3713                         jpp = &jp1->prev_job;
3714                 }
3715                 /* FALLTHROUGH */
3716 #if JOBS
3717         case CUR_STOPPED:
3718 #endif
3719                 /* newly stopped job - becomes curjob */
3720                 jp->prev_job = *jpp;
3721                 *jpp = jp;
3722                 break;
3723         }
3724 }
3725
3726 #if JOBS || DEBUG
3727 static int
3728 jobno(const struct job *jp)
3729 {
3730         return jp - jobtab + 1;
3731 }
3732 #endif
3733
3734 /*
3735  * Convert a job name to a job structure.
3736  */
3737 #if !JOBS
3738 #define getjob(name, getctl) getjob(name)
3739 #endif
3740 static struct job *
3741 getjob(const char *name, int getctl)
3742 {
3743         struct job *jp;
3744         struct job *found;
3745         const char *err_msg = "%s: no such job";
3746         unsigned num;
3747         int c;
3748         const char *p;
3749         char *(*match)(const char *, const char *);
3750
3751         jp = curjob;
3752         p = name;
3753         if (!p)
3754                 goto currentjob;
3755
3756         if (*p != '%')
3757                 goto err;
3758
3759         c = *++p;
3760         if (!c)
3761                 goto currentjob;
3762
3763         if (!p[1]) {
3764                 if (c == '+' || c == '%') {
3765  currentjob:
3766                         err_msg = "No current job";
3767                         goto check;
3768                 }
3769                 if (c == '-') {
3770                         if (jp)
3771                                 jp = jp->prev_job;
3772                         err_msg = "No previous job";
3773  check:
3774                         if (!jp)
3775                                 goto err;
3776                         goto gotit;
3777                 }
3778         }
3779
3780         if (is_number(p)) {
3781                 num = atoi(p);
3782                 if (num > 0 && num <= njobs) {
3783                         jp = jobtab + num - 1;
3784                         if (jp->used)
3785                                 goto gotit;
3786                         goto err;
3787                 }
3788         }
3789
3790         match = prefix;
3791         if (*p == '?') {
3792                 match = strstr;
3793                 p++;
3794         }
3795
3796         found = NULL;
3797         while (jp) {
3798                 if (match(jp->ps[0].ps_cmd, p)) {
3799                         if (found)
3800                                 goto err;
3801                         found = jp;
3802                         err_msg = "%s: ambiguous";
3803                 }
3804                 jp = jp->prev_job;
3805         }
3806         if (!found)
3807                 goto err;
3808         jp = found;
3809
3810  gotit:
3811 #if JOBS
3812         err_msg = "job %s not created under job control";
3813         if (getctl && jp->jobctl == 0)
3814                 goto err;
3815 #endif
3816         return jp;
3817  err:
3818         ash_msg_and_raise_error(err_msg, name);
3819 }
3820
3821 /*
3822  * Mark a job structure as unused.
3823  */
3824 static void
3825 freejob(struct job *jp)
3826 {
3827         struct procstat *ps;
3828         int i;
3829
3830         INT_OFF;
3831         for (i = jp->nprocs, ps = jp->ps; --i >= 0; ps++) {
3832                 if (ps->ps_cmd != nullstr)
3833                         free(ps->ps_cmd);
3834         }
3835         if (jp->ps != &jp->ps0)
3836                 free(jp->ps);
3837         jp->used = 0;
3838         set_curjob(jp, CUR_DELETE);
3839         INT_ON;
3840 }
3841
3842 #if JOBS
3843 static void
3844 xtcsetpgrp(int fd, pid_t pgrp)
3845 {
3846         if (tcsetpgrp(fd, pgrp))
3847                 ash_msg_and_raise_perror("can't set tty process group");
3848 }
3849
3850 /*
3851  * Turn job control on and off.
3852  *
3853  * Note:  This code assumes that the third arg to ioctl is a character
3854  * pointer, which is true on Berkeley systems but not System V.  Since
3855  * System V doesn't have job control yet, this isn't a problem now.
3856  *
3857  * Called with interrupts off.
3858  */
3859 static void
3860 setjobctl(int on)
3861 {
3862         int fd;
3863         int pgrp;
3864
3865         if (on == doing_jobctl || rootshell == 0)
3866                 return;
3867         if (on) {
3868                 int ofd;
3869                 ofd = fd = open(_PATH_TTY, O_RDWR);
3870                 if (fd < 0) {
3871         /* BTW, bash will try to open(ttyname(0)) if open("/dev/tty") fails.
3872          * That sometimes helps to acquire controlling tty.
3873          * Obviously, a workaround for bugs when someone
3874          * failed to provide a controlling tty to bash! :) */
3875                         fd = 2;
3876                         while (!isatty(fd))
3877                                 if (--fd < 0)
3878                                         goto out;
3879                 }
3880                 /* fd is a tty at this point */
3881                 fd = fcntl(fd, F_DUPFD, 10);
3882                 if (ofd >= 0) /* if it is "/dev/tty", close. If 0/1/2, don't */
3883                         close(ofd);
3884                 if (fd < 0)
3885                         goto out; /* F_DUPFD failed */
3886                 close_on_exec_on(fd);
3887                 while (1) { /* while we are in the background */
3888                         pgrp = tcgetpgrp(fd);
3889                         if (pgrp < 0) {
3890  out:
3891                                 ash_msg("can't access tty; job control turned off");
3892                                 mflag = on = 0;
3893                                 goto close;
3894                         }
3895                         if (pgrp == getpgrp())
3896                                 break;
3897                         killpg(0, SIGTTIN);
3898                 }
3899                 initialpgrp = pgrp;
3900
3901                 setsignal(SIGTSTP);
3902                 setsignal(SIGTTOU);
3903                 setsignal(SIGTTIN);
3904                 pgrp = rootpid;
3905                 setpgid(0, pgrp);
3906                 xtcsetpgrp(fd, pgrp);
3907         } else {
3908                 /* turning job control off */
3909                 fd = ttyfd;
3910                 pgrp = initialpgrp;
3911                 /* was xtcsetpgrp, but this can make exiting ash
3912                  * loop forever if pty is already deleted */
3913                 tcsetpgrp(fd, pgrp);
3914                 setpgid(0, pgrp);
3915                 setsignal(SIGTSTP);
3916                 setsignal(SIGTTOU);
3917                 setsignal(SIGTTIN);
3918  close:
3919                 if (fd >= 0)
3920                         close(fd);
3921                 fd = -1;
3922         }
3923         ttyfd = fd;
3924         doing_jobctl = on;
3925 }
3926
3927 static int FAST_FUNC
3928 killcmd(int argc, char **argv)
3929 {
3930         if (argv[1] && strcmp(argv[1], "-l") != 0) {
3931                 int i = 1;
3932                 do {
3933                         if (argv[i][0] == '%') {
3934                                 /*
3935                                  * "kill %N" - job kill
3936                                  * Converting to pgrp / pid kill
3937                                  */
3938                                 struct job *jp;
3939                                 char *dst;
3940                                 int j, n;
3941
3942                                 jp = getjob(argv[i], 0);
3943                                 /*
3944                                  * In jobs started under job control, we signal
3945                                  * entire process group by kill -PGRP_ID.
3946                                  * This happens, f.e., in interactive shell.
3947                                  *
3948                                  * Otherwise, we signal each child via
3949                                  * kill PID1 PID2 PID3.
3950                                  * Testcases:
3951                                  * sh -c 'sleep 1|sleep 1 & kill %1'
3952                                  * sh -c 'true|sleep 2 & sleep 1; kill %1'
3953                                  * sh -c 'true|sleep 1 & sleep 2; kill %1'
3954                                  */
3955                                 n = jp->nprocs; /* can't be 0 (I hope) */
3956                                 if (jp->jobctl)
3957                                         n = 1;
3958                                 dst = alloca(n * sizeof(int)*4);
3959                                 argv[i] = dst;
3960                                 for (j = 0; j < n; j++) {
3961                                         struct procstat *ps = &jp->ps[j];
3962                                         /* Skip non-running and not-stopped members
3963                                          * (i.e. dead members) of the job
3964                                          */
3965                                         if (ps->ps_status != -1 && !WIFSTOPPED(ps->ps_status))
3966                                                 continue;
3967                                         /*
3968                                          * kill_main has matching code to expect
3969                                          * leading space. Needed to not confuse
3970                                          * negative pids with "kill -SIGNAL_NO" syntax
3971                                          */
3972                                         dst += sprintf(dst, jp->jobctl ? " -%u" : " %u", (int)ps->ps_pid);
3973                                 }
3974                                 *dst = '\0';
3975                         }
3976                 } while (argv[++i]);
3977         }
3978         return kill_main(argc, argv);
3979 }
3980
3981 static void
3982 showpipe(struct job *jp /*, FILE *out*/)
3983 {
3984         struct procstat *ps;
3985         struct procstat *psend;
3986
3987         psend = jp->ps + jp->nprocs;
3988         for (ps = jp->ps + 1; ps < psend; ps++)
3989                 printf(" | %s", ps->ps_cmd);
3990         newline_and_flush(stdout);
3991         flush_stdout_stderr();
3992 }
3993
3994
3995 static int
3996 restartjob(struct job *jp, int mode)
3997 {
3998         struct procstat *ps;
3999         int i;
4000         int status;
4001         pid_t pgid;
4002
4003         INT_OFF;
4004         if (jp->state == JOBDONE)
4005                 goto out;
4006         jp->state = JOBRUNNING;
4007         pgid = jp->ps[0].ps_pid;
4008         if (mode == FORK_FG) {
4009                 get_tty_state();
4010                 xtcsetpgrp(ttyfd, pgid);
4011         }
4012         killpg(pgid, SIGCONT);
4013         ps = jp->ps;
4014         i = jp->nprocs;
4015         do {
4016                 if (WIFSTOPPED(ps->ps_status)) {
4017                         ps->ps_status = -1;
4018                 }
4019                 ps++;
4020         } while (--i);
4021  out:
4022         status = (mode == FORK_FG) ? waitforjob(jp) : 0;
4023         INT_ON;
4024         return status;
4025 }
4026
4027 static int FAST_FUNC
4028 fg_bgcmd(int argc UNUSED_PARAM, char **argv)
4029 {
4030         struct job *jp;
4031         int mode;
4032         int retval;
4033
4034         mode = (**argv == 'f') ? FORK_FG : FORK_BG;
4035         nextopt(nullstr);
4036         argv = argptr;
4037         do {
4038                 jp = getjob(*argv, 1);
4039                 if (mode == FORK_BG) {
4040                         set_curjob(jp, CUR_RUNNING);
4041                         printf("[%d] ", jobno(jp));
4042                 }
4043                 out1str(jp->ps[0].ps_cmd);
4044                 showpipe(jp /*, stdout*/);
4045                 retval = restartjob(jp, mode);
4046         } while (*argv && *++argv);
4047         return retval;
4048 }
4049 #endif
4050
4051 static int
4052 sprint_status48(char *s, int status, int sigonly)
4053 {
4054         int col;
4055         int st;
4056
4057         col = 0;
4058         if (!WIFEXITED(status)) {
4059 #if JOBS
4060                 if (WIFSTOPPED(status))
4061                         st = WSTOPSIG(status);
4062                 else
4063 #endif
4064                         st = WTERMSIG(status);
4065                 if (sigonly) {
4066                         if (st == SIGINT || st == SIGPIPE)
4067                                 goto out;
4068 #if JOBS
4069                         if (WIFSTOPPED(status))
4070                                 goto out;
4071 #endif
4072                 }
4073                 st &= 0x7f;
4074 //TODO: use bbox's get_signame? strsignal adds ~600 bytes to text+rodata
4075                 col = fmtstr(s, 32, strsignal(st));
4076                 if (WCOREDUMP(status)) {
4077                         strcpy(s + col, " (core dumped)");
4078                         col += sizeof(" (core dumped)")-1;
4079                 }
4080         } else if (!sigonly) {
4081                 st = WEXITSTATUS(status);
4082                 col = fmtstr(s, 16, (st ? "Done(%d)" : "Done"), st);
4083         }
4084  out:
4085         return col;
4086 }
4087
4088 static int
4089 wait_block_or_sig(int *status)
4090 {
4091         int pid;
4092
4093         do {
4094                 sigset_t mask;
4095
4096                 /* Poll all children for changes in their state */
4097                 got_sigchld = 0;
4098                 /* if job control is active, accept stopped processes too */
4099                 pid = waitpid(-1, status, doing_jobctl ? (WNOHANG|WUNTRACED) : WNOHANG);
4100                 if (pid != 0)
4101                         break; /* Error (e.g. EINTR, ECHILD) or pid */
4102
4103                 /* Children exist, but none are ready. Sleep until interesting signal */
4104 #if 1
4105                 sigfillset(&mask);
4106                 sigprocmask(SIG_SETMASK, &mask, &mask);
4107                 while (!got_sigchld && !pending_sig)
4108                         sigsuspend(&mask);
4109                 sigprocmask(SIG_SETMASK, &mask, NULL);
4110 #else /* unsafe: a signal can set pending_sig after check, but before pause() */
4111                 while (!got_sigchld && !pending_sig)
4112                         pause();
4113 #endif
4114
4115                 /* If it was SIGCHLD, poll children again */
4116         } while (got_sigchld);
4117
4118         return pid;
4119 }
4120
4121 #define DOWAIT_NONBLOCK 0
4122 #define DOWAIT_BLOCK    1
4123 #define DOWAIT_BLOCK_OR_SIG 2
4124
4125 static int
4126 dowait(int block, struct job *job)
4127 {
4128         int pid;
4129         int status;
4130         struct job *jp;
4131         struct job *thisjob = NULL;
4132
4133         TRACE(("dowait(0x%x) called\n", block));
4134
4135         /* It's wrong to call waitpid() outside of INT_OFF region:
4136          * signal can arrive just after syscall return and handler can
4137          * longjmp away, losing stop/exit notification processing.
4138          * Thus, for "jobs" builtin, and for waiting for a fg job,
4139          * we call waitpid() (blocking or non-blocking) inside INT_OFF.
4140          *
4141          * However, for "wait" builtin it is wrong to simply call waitpid()
4142          * in INT_OFF region: "wait" needs to wait for any running job
4143          * to change state, but should exit on any trap too.
4144          * In INT_OFF region, a signal just before syscall entry can set
4145          * pending_sig variables, but we can't check them, and we would
4146          * either enter a sleeping waitpid() (BUG), or need to busy-loop.
4147          *
4148          * Because of this, we run inside INT_OFF, but use a special routine
4149          * which combines waitpid() and sigsuspend().
4150          * This is the reason why we need to have a handler for SIGCHLD:
4151          * SIG_DFL handler does not wake sigsuspend().
4152          */
4153         INT_OFF;
4154         if (block == DOWAIT_BLOCK_OR_SIG) {
4155                 pid = wait_block_or_sig(&status);
4156         } else {
4157                 int wait_flags = 0;
4158                 if (block == DOWAIT_NONBLOCK)
4159                         wait_flags = WNOHANG;
4160                 /* if job control is active, accept stopped processes too */
4161                 if (doing_jobctl)
4162                         wait_flags |= WUNTRACED;
4163                 /* NB: _not_ safe_waitpid, we need to detect EINTR */
4164                 pid = waitpid(-1, &status, wait_flags);
4165         }
4166         TRACE(("wait returns pid=%d, status=0x%x, errno=%d(%s)\n",
4167                                 pid, status, errno, strerror(errno)));
4168         if (pid <= 0)
4169                 goto out;
4170
4171         thisjob = NULL;
4172         for (jp = curjob; jp; jp = jp->prev_job) {
4173                 int jobstate;
4174                 struct procstat *ps;
4175                 struct procstat *psend;
4176                 if (jp->state == JOBDONE)
4177                         continue;
4178                 jobstate = JOBDONE;
4179                 ps = jp->ps;
4180                 psend = ps + jp->nprocs;
4181                 do {
4182                         if (ps->ps_pid == pid) {
4183                                 TRACE(("Job %d: changing status of proc %d "
4184                                         "from 0x%x to 0x%x\n",
4185                                         jobno(jp), pid, ps->ps_status, status));
4186                                 ps->ps_status = status;
4187                                 thisjob = jp;
4188                         }
4189                         if (ps->ps_status == -1)
4190                                 jobstate = JOBRUNNING;
4191 #if JOBS
4192                         if (jobstate == JOBRUNNING)
4193                                 continue;
4194                         if (WIFSTOPPED(ps->ps_status)) {
4195                                 jp->stopstatus = ps->ps_status;
4196                                 jobstate = JOBSTOPPED;
4197                         }
4198 #endif
4199                 } while (++ps < psend);
4200                 if (!thisjob)
4201                         continue;
4202
4203                 /* Found the job where one of its processes changed its state.
4204                  * Is there at least one live and running process in this job? */
4205                 if (jobstate != JOBRUNNING) {
4206                         /* No. All live processes in the job are stopped
4207                          * (JOBSTOPPED) or there are no live processes (JOBDONE)
4208                          */
4209                         thisjob->changed = 1;
4210                         if (thisjob->state != jobstate) {
4211                                 TRACE(("Job %d: changing state from %d to %d\n",
4212                                         jobno(thisjob), thisjob->state, jobstate));
4213                                 thisjob->state = jobstate;
4214 #if JOBS
4215                                 if (jobstate == JOBSTOPPED)
4216                                         set_curjob(thisjob, CUR_STOPPED);
4217 #endif
4218                         }
4219                 }
4220                 goto out;
4221         }
4222         /* The process wasn't found in job list */
4223 #if JOBS
4224         if (!WIFSTOPPED(status))
4225                 jobless--;
4226 #endif
4227  out:
4228         INT_ON;
4229
4230         if (thisjob && thisjob == job) {
4231                 char s[48 + 1];
4232                 int len;
4233
4234                 len = sprint_status48(s, status, 1);
4235                 if (len) {
4236                         s[len] = '\n';
4237                         s[len + 1] = '\0';
4238                         out2str(s);
4239                 }
4240         }
4241         return pid;
4242 }
4243
4244 #if JOBS
4245 static void
4246 showjob(struct job *jp, int mode)
4247 {
4248         struct procstat *ps;
4249         struct procstat *psend;
4250         int col;
4251         int indent_col;
4252         char s[16 + 16 + 48];
4253         FILE *out = (mode & SHOW_STDERR ? stderr : stdout);
4254
4255         ps = jp->ps;
4256
4257         if (mode & SHOW_ONLY_PGID) { /* jobs -p */
4258                 /* just output process (group) id of pipeline */
4259                 fprintf(out, "%d\n", ps->ps_pid);
4260                 return;
4261         }
4262
4263         col = fmtstr(s, 16, "[%d]   ", jobno(jp));
4264         indent_col = col;
4265
4266         if (jp == curjob)
4267                 s[col - 3] = '+';
4268         else if (curjob && jp == curjob->prev_job)
4269                 s[col - 3] = '-';
4270
4271         if (mode & SHOW_PIDS)
4272                 col += fmtstr(s + col, 16, "%d ", ps->ps_pid);
4273
4274         psend = ps + jp->nprocs;
4275
4276         if (jp->state == JOBRUNNING) {
4277                 strcpy(s + col, "Running");
4278                 col += sizeof("Running") - 1;
4279         } else {
4280                 int status = psend[-1].ps_status;
4281                 if (jp->state == JOBSTOPPED)
4282                         status = jp->stopstatus;
4283                 col += sprint_status48(s + col, status, 0);
4284         }
4285         /* By now, "[JOBID]*  [maybe PID] STATUS" is printed */
4286
4287         /* This loop either prints "<cmd1> | <cmd2> | <cmd3>" line
4288          * or prints several "PID             | <cmdN>" lines,
4289          * depending on SHOW_PIDS bit.
4290          * We do not print status of individual processes
4291          * between PID and <cmdN>. bash does it, but not very well:
4292          * first line shows overall job status, not process status,
4293          * making it impossible to know 1st process status.
4294          */
4295         goto start;
4296         do {
4297                 /* for each process */
4298                 s[0] = '\0';
4299                 col = 33;
4300                 if (mode & SHOW_PIDS)
4301                         col = fmtstr(s, 48, "\n%*c%d ", indent_col, ' ', ps->ps_pid) - 1;
4302  start:
4303                 fprintf(out, "%s%*c%s%s",
4304                                 s,
4305                                 33 - col >= 0 ? 33 - col : 0, ' ',
4306                                 ps == jp->ps ? "" : "| ",
4307                                 ps->ps_cmd
4308                 );
4309         } while (++ps != psend);
4310         newline_and_flush(out);
4311
4312         jp->changed = 0;
4313
4314         if (jp->state == JOBDONE) {
4315                 TRACE(("showjob: freeing job %d\n", jobno(jp)));
4316                 freejob(jp);
4317         }
4318 }
4319
4320 /*
4321  * Print a list of jobs.  If "change" is nonzero, only print jobs whose
4322  * statuses have changed since the last call to showjobs.
4323  */
4324 static void
4325 showjobs(int mode)
4326 {
4327         struct job *jp;
4328
4329         TRACE(("showjobs(0x%x) called\n", mode));
4330
4331         /* Handle all finished jobs */
4332         while (dowait(DOWAIT_NONBLOCK, NULL) > 0)
4333                 continue;
4334
4335         for (jp = curjob; jp; jp = jp->prev_job) {
4336                 if (!(mode & SHOW_CHANGED) || jp->changed) {
4337                         showjob(jp, mode);
4338                 }
4339         }
4340 }
4341
4342 static int FAST_FUNC
4343 jobscmd(int argc UNUSED_PARAM, char **argv)
4344 {
4345         int mode, m;
4346
4347         mode = 0;
4348         while ((m = nextopt("lp")) != '\0') {
4349                 if (m == 'l')
4350                         mode |= SHOW_PIDS;
4351                 else
4352                         mode |= SHOW_ONLY_PGID;
4353         }
4354
4355         argv = argptr;
4356         if (*argv) {
4357                 do
4358                         showjob(getjob(*argv, 0), mode);
4359                 while (*++argv);
4360         } else {
4361                 showjobs(mode);
4362         }
4363
4364         return 0;
4365 }
4366 #endif /* JOBS */
4367
4368 /* Called only on finished or stopped jobs (no members are running) */
4369 static int
4370 getstatus(struct job *job)
4371 {
4372         int status;
4373         int retval;
4374         struct procstat *ps;
4375
4376         /* Fetch last member's status */
4377         ps = job->ps + job->nprocs - 1;
4378         status = ps->ps_status;
4379         if (pipefail) {
4380                 /* "set -o pipefail" mode: use last _nonzero_ status */
4381                 while (status == 0 && --ps >= job->ps)
4382                         status = ps->ps_status;
4383         }
4384
4385         retval = WEXITSTATUS(status);
4386         if (!WIFEXITED(status)) {
4387 #if JOBS
4388                 retval = WSTOPSIG(status);
4389                 if (!WIFSTOPPED(status))
4390 #endif
4391                 {
4392                         /* XXX: limits number of signals */
4393                         retval = WTERMSIG(status);
4394 #if JOBS
4395                         if (retval == SIGINT)
4396                                 job->sigint = 1;
4397 #endif
4398                 }
4399                 retval += 128;
4400         }
4401         TRACE(("getstatus: job %d, nproc %d, status 0x%x, retval 0x%x\n",
4402                 jobno(job), job->nprocs, status, retval));
4403         return retval;
4404 }
4405
4406 static int FAST_FUNC
4407 waitcmd(int argc UNUSED_PARAM, char **argv)
4408 {
4409         struct job *job;
4410         int retval;
4411         struct job *jp;
4412
4413         nextopt(nullstr);
4414         retval = 0;
4415
4416         argv = argptr;
4417         if (!*argv) {
4418                 /* wait for all jobs */
4419                 for (;;) {
4420                         jp = curjob;
4421                         while (1) {
4422                                 if (!jp) /* no running procs */
4423                                         goto ret;
4424                                 if (jp->state == JOBRUNNING)
4425                                         break;
4426                                 jp->waited = 1;
4427                                 jp = jp->prev_job;
4428                         }
4429         /* man bash:
4430          * "When bash is waiting for an asynchronous command via
4431          * the wait builtin, the reception of a signal for which a trap
4432          * has been set will cause the wait builtin to return immediately
4433          * with an exit status greater than 128, immediately after which
4434          * the trap is executed."
4435          */
4436                         dowait(DOWAIT_BLOCK_OR_SIG, NULL);
4437         /* if child sends us a signal *and immediately exits*,
4438          * dowait() returns pid > 0. Check this case,
4439          * not "if (dowait() < 0)"!
4440          */
4441                         if (pending_sig)
4442                                 goto sigout;
4443                 }
4444         }
4445
4446         retval = 127;
4447         do {
4448                 if (**argv != '%') {
4449                         pid_t pid = number(*argv);
4450                         job = curjob;
4451                         while (1) {
4452                                 if (!job)
4453                                         goto repeat;
4454                                 if (job->ps[job->nprocs - 1].ps_pid == pid)
4455                                         break;
4456                                 job = job->prev_job;
4457                         }
4458                 } else {
4459                         job = getjob(*argv, 0);
4460                 }
4461                 /* loop until process terminated or stopped */
4462                 while (job->state == JOBRUNNING) {
4463                         dowait(DOWAIT_BLOCK_OR_SIG, NULL);
4464                         if (pending_sig)
4465                                 goto sigout;
4466                 }
4467                 job->waited = 1;
4468                 retval = getstatus(job);
4469  repeat: ;
4470         } while (*++argv);
4471
4472  ret:
4473         return retval;
4474  sigout:
4475         retval = 128 + pending_sig;
4476         return retval;
4477 }
4478
4479 static struct job *
4480 growjobtab(void)
4481 {
4482         size_t len;
4483         ptrdiff_t offset;
4484         struct job *jp, *jq;
4485
4486         len = njobs * sizeof(*jp);
4487         jq = jobtab;
4488         jp = ckrealloc(jq, len + 4 * sizeof(*jp));
4489
4490         offset = (char *)jp - (char *)jq;
4491         if (offset) {
4492                 /* Relocate pointers */
4493                 size_t l = len;
4494
4495                 jq = (struct job *)((char *)jq + l);
4496                 while (l) {
4497                         l -= sizeof(*jp);
4498                         jq--;
4499 #define joff(p) ((struct job *)((char *)(p) + l))
4500 #define jmove(p) (p) = (void *)((char *)(p) + offset)
4501                         if (joff(jp)->ps == &jq->ps0)
4502                                 jmove(joff(jp)->ps);
4503                         if (joff(jp)->prev_job)
4504                                 jmove(joff(jp)->prev_job);
4505                 }
4506                 if (curjob)
4507                         jmove(curjob);
4508 #undef joff
4509 #undef jmove
4510         }
4511
4512         njobs += 4;
4513         jobtab = jp;
4514         jp = (struct job *)((char *)jp + len);
4515         jq = jp + 3;
4516         do {
4517                 jq->used = 0;
4518         } while (--jq >= jp);
4519         return jp;
4520 }
4521
4522 /*
4523  * Return a new job structure.
4524  * Called with interrupts off.
4525  */
4526 static struct job *
4527 makejob(/*union node *node,*/ int nprocs)
4528 {
4529         int i;
4530         struct job *jp;
4531
4532         for (i = njobs, jp = jobtab; ; jp++) {
4533                 if (--i < 0) {
4534                         jp = growjobtab();
4535                         break;
4536                 }
4537                 if (jp->used == 0)
4538                         break;
4539                 if (jp->state != JOBDONE || !jp->waited)
4540                         continue;
4541 #if JOBS
4542                 if (doing_jobctl)
4543                         continue;
4544 #endif
4545                 freejob(jp);
4546                 break;
4547         }
4548         memset(jp, 0, sizeof(*jp));
4549 #if JOBS
4550         /* jp->jobctl is a bitfield.
4551          * "jp->jobctl |= doing_jobctl" likely to give awful code */
4552         if (doing_jobctl)
4553                 jp->jobctl = 1;
4554 #endif
4555         jp->prev_job = curjob;
4556         curjob = jp;
4557         jp->used = 1;
4558         jp->ps = &jp->ps0;
4559         if (nprocs > 1) {
4560                 jp->ps = ckmalloc(nprocs * sizeof(struct procstat));
4561         }
4562         TRACE(("makejob(%d) returns %%%d\n", nprocs,
4563                                 jobno(jp)));
4564         return jp;
4565 }
4566
4567 #if JOBS
4568 /*
4569  * Return a string identifying a command (to be printed by the
4570  * jobs command).
4571  */
4572 static char *cmdnextc;
4573
4574 static void
4575 cmdputs(const char *s)
4576 {
4577         static const char vstype[VSTYPE + 1][3] = {
4578                 "", "}", "-", "+", "?", "=",
4579                 "%", "%%", "#", "##"
4580                 IF_BASH_SUBSTR(, ":")
4581                 IF_BASH_PATTERN_SUBST(, "/", "//")
4582         };
4583
4584         const char *p, *str;
4585         char cc[2];
4586         char *nextc;
4587         unsigned char c;
4588         unsigned char subtype = 0;
4589         int quoted = 0;
4590
4591         cc[1] = '\0';
4592         nextc = makestrspace((strlen(s) + 1) * 8, cmdnextc);
4593         p = s;
4594         while ((c = *p++) != '\0') {
4595                 str = NULL;
4596                 switch (c) {
4597                 case CTLESC:
4598                         c = *p++;
4599                         break;
4600                 case CTLVAR:
4601                         subtype = *p++;
4602                         if ((subtype & VSTYPE) == VSLENGTH)
4603                                 str = "${#";
4604                         else
4605                                 str = "${";
4606                         goto dostr;
4607                 case CTLENDVAR:
4608                         str = "\"}" + !(quoted & 1);
4609                         quoted >>= 1;
4610                         subtype = 0;
4611                         goto dostr;
4612                 case CTLBACKQ:
4613                         str = "$(...)";
4614                         goto dostr;
4615 #if ENABLE_FEATURE_SH_MATH
4616                 case CTLARI:
4617                         str = "$((";
4618                         goto dostr;
4619                 case CTLENDARI:
4620                         str = "))";
4621                         goto dostr;
4622 #endif
4623                 case CTLQUOTEMARK:
4624                         quoted ^= 1;
4625                         c = '"';
4626                         break;
4627                 case '=':
4628                         if (subtype == 0)
4629                                 break;
4630                         if ((subtype & VSTYPE) != VSNORMAL)
4631                                 quoted <<= 1;
4632                         str = vstype[subtype & VSTYPE];
4633                         if (subtype & VSNUL)
4634                                 c = ':';
4635                         else
4636                                 goto checkstr;
4637                         break;
4638                 case '\'':
4639                 case '\\':
4640                 case '"':
4641                 case '$':
4642                         /* These can only happen inside quotes */
4643                         cc[0] = c;
4644                         str = cc;
4645 //FIXME:
4646 // $ true $$ &
4647 // $ <cr>
4648 // [1]+  Done    true ${\$}   <<=== BUG: ${\$} is not a valid way to write $$ (${$} would be ok)
4649                         c = '\\';
4650                         break;
4651                 default:
4652                         break;
4653                 }
4654                 USTPUTC(c, nextc);
4655  checkstr:
4656                 if (!str)
4657                         continue;
4658  dostr:
4659                 while ((c = *str++) != '\0') {
4660                         USTPUTC(c, nextc);
4661                 }
4662         } /* while *p++ not NUL */
4663
4664         if (quoted & 1) {
4665                 USTPUTC('"', nextc);
4666         }
4667         *nextc = 0;
4668         cmdnextc = nextc;
4669 }
4670
4671 /* cmdtxt() and cmdlist() call each other */
4672 static void cmdtxt(union node *n);
4673
4674 static void
4675 cmdlist(union node *np, int sep)
4676 {
4677         for (; np; np = np->narg.next) {
4678                 if (!sep)
4679                         cmdputs(" ");
4680                 cmdtxt(np);
4681                 if (sep && np->narg.next)
4682                         cmdputs(" ");
4683         }
4684 }
4685
4686 static void
4687 cmdtxt(union node *n)
4688 {
4689         union node *np;
4690         struct nodelist *lp;
4691         const char *p;
4692
4693         if (!n)
4694                 return;
4695         switch (n->type) {
4696         default:
4697 #if DEBUG
4698                 abort();
4699 #endif
4700         case NPIPE:
4701                 lp = n->npipe.cmdlist;
4702                 for (;;) {
4703                         cmdtxt(lp->n);
4704                         lp = lp->next;
4705                         if (!lp)
4706                                 break;
4707                         cmdputs(" | ");
4708                 }
4709                 break;
4710         case NSEMI:
4711                 p = "; ";
4712                 goto binop;
4713         case NAND:
4714                 p = " && ";
4715                 goto binop;
4716         case NOR:
4717                 p = " || ";
4718  binop:
4719                 cmdtxt(n->nbinary.ch1);
4720                 cmdputs(p);
4721                 n = n->nbinary.ch2;
4722                 goto donode;
4723         case NREDIR:
4724         case NBACKGND:
4725                 n = n->nredir.n;
4726                 goto donode;
4727         case NNOT:
4728                 cmdputs("!");
4729                 n = n->nnot.com;
4730  donode:
4731                 cmdtxt(n);
4732                 break;
4733         case NIF:
4734                 cmdputs("if ");
4735                 cmdtxt(n->nif.test);
4736                 cmdputs("; then ");
4737                 if (n->nif.elsepart) {
4738                         cmdtxt(n->nif.ifpart);
4739                         cmdputs("; else ");
4740                         n = n->nif.elsepart;
4741                 } else {
4742                         n = n->nif.ifpart;
4743                 }
4744                 p = "; fi";
4745                 goto dotail;
4746         case NSUBSHELL:
4747                 cmdputs("(");
4748                 n = n->nredir.n;
4749                 p = ")";
4750                 goto dotail;
4751         case NWHILE:
4752                 p = "while ";
4753                 goto until;
4754         case NUNTIL:
4755                 p = "until ";
4756  until:
4757                 cmdputs(p);
4758                 cmdtxt(n->nbinary.ch1);
4759                 n = n->nbinary.ch2;
4760                 p = "; done";
4761  dodo:
4762                 cmdputs("; do ");
4763  dotail:
4764                 cmdtxt(n);
4765                 goto dotail2;
4766         case NFOR:
4767                 cmdputs("for ");
4768                 cmdputs(n->nfor.var);
4769                 cmdputs(" in ");
4770                 cmdlist(n->nfor.args, 1);
4771                 n = n->nfor.body;
4772                 p = "; done";
4773                 goto dodo;
4774         case NDEFUN:
4775                 cmdputs(n->narg.text);
4776                 p = "() { ... }";
4777                 goto dotail2;
4778         case NCMD:
4779                 cmdlist(n->ncmd.args, 1);
4780                 cmdlist(n->ncmd.redirect, 0);
4781                 break;
4782         case NARG:
4783                 p = n->narg.text;
4784  dotail2:
4785                 cmdputs(p);
4786                 break;
4787         case NHERE:
4788         case NXHERE:
4789                 p = "<<...";
4790                 goto dotail2;
4791         case NCASE:
4792                 cmdputs("case ");
4793                 cmdputs(n->ncase.expr->narg.text);
4794                 cmdputs(" in ");
4795                 for (np = n->ncase.cases; np; np = np->nclist.next) {
4796                         cmdtxt(np->nclist.pattern);
4797                         cmdputs(") ");
4798                         cmdtxt(np->nclist.body);
4799                         cmdputs(";; ");
4800                 }
4801                 p = "esac";
4802                 goto dotail2;
4803         case NTO:
4804                 p = ">";
4805                 goto redir;
4806         case NCLOBBER:
4807                 p = ">|";
4808                 goto redir;
4809         case NAPPEND:
4810                 p = ">>";
4811                 goto redir;
4812 #if BASH_REDIR_OUTPUT
4813         case NTO2:
4814 #endif
4815         case NTOFD:
4816                 p = ">&";
4817                 goto redir;
4818         case NFROM:
4819                 p = "<";
4820                 goto redir;
4821         case NFROMFD:
4822                 p = "<&";
4823                 goto redir;
4824         case NFROMTO:
4825                 p = "<>";
4826  redir:
4827                 cmdputs(utoa(n->nfile.fd));
4828                 cmdputs(p);
4829                 if (n->type == NTOFD || n->type == NFROMFD) {
4830                         if (n->ndup.dupfd >= 0)
4831                                 cmdputs(utoa(n->ndup.dupfd));
4832                         else
4833                                 cmdputs("-");
4834                         break;
4835                 }
4836                 n = n->nfile.fname;
4837                 goto donode;
4838         }
4839 }
4840
4841 static char *
4842 commandtext(union node *n)
4843 {
4844         char *name;
4845
4846         STARTSTACKSTR(cmdnextc);
4847         cmdtxt(n);
4848         name = stackblock();
4849         TRACE(("commandtext: name %p, end %p\n", name, cmdnextc));
4850         return ckstrdup(name);
4851 }
4852 #endif /* JOBS */
4853
4854 /*
4855  * Fork off a subshell.  If we are doing job control, give the subshell its
4856  * own process group.  Jp is a job structure that the job is to be added to.
4857  * N is the command that will be evaluated by the child.  Both jp and n may
4858  * be NULL.  The mode parameter can be one of the following:
4859  *      FORK_FG - Fork off a foreground process.
4860  *      FORK_BG - Fork off a background process.
4861  *      FORK_NOJOB - Like FORK_FG, but don't give the process its own
4862  *                   process group even if job control is on.
4863  *
4864  * When job control is turned off, background processes have their standard
4865  * input redirected to /dev/null (except for the second and later processes
4866  * in a pipeline).
4867  *
4868  * Called with interrupts off.
4869  */
4870 /*
4871  * Clear traps on a fork.
4872  */
4873 static void
4874 clear_traps(void)
4875 {
4876         char **tp;
4877
4878         INT_OFF;
4879         for (tp = trap; tp < &trap[NSIG]; tp++) {
4880                 if (*tp && **tp) {      /* trap not NULL or "" (SIG_IGN) */
4881                         if (trap_ptr == trap)
4882                                 free(*tp);
4883                         /* else: it "belongs" to trap_ptr vector, don't free */
4884                         *tp = NULL;
4885                         if ((tp - trap) != 0)
4886                                 setsignal(tp - trap);
4887                 }
4888         }
4889         may_have_traps = 0;
4890         INT_ON;
4891 }
4892
4893 /* Lives far away from here, needed for forkchild */
4894 static void closescript(void);
4895
4896 /* Called after fork(), in child */
4897 /* jp and n are NULL when called by openhere() for heredoc support */
4898 static NOINLINE void
4899 forkchild(struct job *jp, union node *n, int mode)
4900 {
4901         int oldlvl;
4902
4903         TRACE(("Child shell %d\n", getpid()));
4904         oldlvl = shlvl;
4905         shlvl++;
4906
4907         /* man bash: "Non-builtin commands run by bash have signal handlers
4908          * set to the values inherited by the shell from its parent".
4909          * Do we do it correctly? */
4910
4911         closescript();
4912
4913         if (mode == FORK_NOJOB          /* is it `xxx` ? */
4914          && n && n->type == NCMD        /* is it single cmd? */
4915         /* && n->ncmd.args->type == NARG - always true? */
4916          && n->ncmd.args && strcmp(n->ncmd.args->narg.text, "trap") == 0
4917          && n->ncmd.args->narg.next == NULL /* "trap" with no arguments */
4918         /* && n->ncmd.args->narg.backquote == NULL - do we need to check this? */
4919         ) {
4920                 TRACE(("Trap hack\n"));
4921                 /* Awful hack for `trap` or $(trap).
4922                  *
4923                  * http://www.opengroup.org/onlinepubs/009695399/utilities/trap.html
4924                  * contains an example where "trap" is executed in a subshell:
4925                  *
4926                  * save_traps=$(trap)
4927                  * ...
4928                  * eval "$save_traps"
4929                  *
4930                  * Standard does not say that "trap" in subshell shall print
4931                  * parent shell's traps. It only says that its output
4932                  * must have suitable form, but then, in the above example
4933                  * (which is not supposed to be normative), it implies that.
4934                  *
4935                  * bash (and probably other shell) does implement it
4936                  * (traps are reset to defaults, but "trap" still shows them),
4937                  * but as a result, "trap" logic is hopelessly messed up:
4938                  *
4939                  * # trap
4940                  * trap -- 'echo Ho' SIGWINCH  <--- we have a handler
4941                  * # (trap)        <--- trap is in subshell - no output (correct, traps are reset)
4942                  * # true | trap   <--- trap is in subshell - no output (ditto)
4943                  * # echo `true | trap`    <--- in subshell - output (but traps are reset!)
4944                  * trap -- 'echo Ho' SIGWINCH
4945                  * # echo `(trap)`         <--- in subshell in subshell - output
4946                  * trap -- 'echo Ho' SIGWINCH
4947                  * # echo `true | (trap)`  <--- in subshell in subshell in subshell - output!
4948                  * trap -- 'echo Ho' SIGWINCH
4949                  *
4950                  * The rules when to forget and when to not forget traps
4951                  * get really complex and nonsensical.
4952                  *
4953                  * Our solution: ONLY bare $(trap) or `trap` is special.
4954                  */
4955                 /* Save trap handler strings for trap builtin to print */
4956                 trap_ptr = xmemdup(trap, sizeof(trap));
4957                 /* Fall through into clearing traps */
4958         }
4959         clear_traps();
4960 #if JOBS
4961         /* do job control only in root shell */
4962         doing_jobctl = 0;
4963         if (mode != FORK_NOJOB && jp->jobctl && oldlvl == 0) {
4964                 pid_t pgrp;
4965
4966                 if (jp->nprocs == 0)
4967                         pgrp = getpid();
4968                 else
4969                         pgrp = jp->ps[0].ps_pid;
4970                 /* this can fail because we are doing it in the parent also */
4971                 setpgid(0, pgrp);
4972                 if (mode == FORK_FG)
4973                         xtcsetpgrp(ttyfd, pgrp);
4974                 setsignal(SIGTSTP);
4975                 setsignal(SIGTTOU);
4976         } else
4977 #endif
4978         if (mode == FORK_BG) {
4979                 /* man bash: "When job control is not in effect,
4980                  * asynchronous commands ignore SIGINT and SIGQUIT" */
4981                 ignoresig(SIGINT);
4982                 ignoresig(SIGQUIT);
4983                 if (jp->nprocs == 0) {
4984                         close(0);
4985                         if (open(bb_dev_null, O_RDONLY) != 0)
4986                                 ash_msg_and_raise_error("can't open '%s'", bb_dev_null);
4987                 }
4988         }
4989         if (oldlvl == 0) {
4990                 if (iflag) { /* why if iflag only? */
4991                         setsignal(SIGINT);
4992                         setsignal(SIGTERM);
4993                 }
4994                 /* man bash:
4995                  * "In all cases, bash ignores SIGQUIT. Non-builtin
4996                  * commands run by bash have signal handlers
4997                  * set to the values inherited by the shell
4998                  * from its parent".
4999                  * Take care of the second rule: */
5000                 setsignal(SIGQUIT);
5001         }
5002 #if JOBS
5003         if (n && n->type == NCMD
5004          && n->ncmd.args && strcmp(n->ncmd.args->narg.text, "jobs") == 0
5005         ) {
5006                 TRACE(("Job hack\n"));
5007                 /* "jobs": we do not want to clear job list for it,
5008                  * instead we remove only _its_ own_ job from job list.
5009                  * This makes "jobs .... | cat" more useful.
5010                  */
5011                 freejob(curjob);
5012                 return;
5013         }
5014 #endif
5015         for (jp = curjob; jp; jp = jp->prev_job)
5016                 freejob(jp);
5017         jobless = 0;
5018 }
5019
5020 /* Called after fork(), in parent */
5021 #if !JOBS
5022 #define forkparent(jp, n, mode, pid) forkparent(jp, mode, pid)
5023 #endif
5024 static void
5025 forkparent(struct job *jp, union node *n, int mode, pid_t pid)
5026 {
5027         TRACE(("In parent shell: child = %d\n", pid));
5028         if (!jp) {
5029                 /* jp is NULL when called by openhere() for heredoc support */
5030                 while (jobless && dowait(DOWAIT_NONBLOCK, NULL) > 0)
5031                         continue;
5032                 jobless++;
5033                 return;
5034         }
5035 #if JOBS
5036         if (mode != FORK_NOJOB && jp->jobctl) {
5037                 int pgrp;
5038
5039                 if (jp->nprocs == 0)
5040                         pgrp = pid;
5041                 else
5042                         pgrp = jp->ps[0].ps_pid;
5043                 /* This can fail because we are doing it in the child also */
5044                 setpgid(pid, pgrp);
5045         }
5046 #endif
5047         if (mode == FORK_BG) {
5048                 backgndpid = pid;               /* set $! */
5049                 set_curjob(jp, CUR_RUNNING);
5050         }
5051         if (jp) {
5052                 struct procstat *ps = &jp->ps[jp->nprocs++];
5053                 ps->ps_pid = pid;
5054                 ps->ps_status = -1;
5055                 ps->ps_cmd = nullstr;
5056 #if JOBS
5057                 if (doing_jobctl && n)
5058                         ps->ps_cmd = commandtext(n);
5059 #endif
5060         }
5061 }
5062
5063 /* jp and n are NULL when called by openhere() for heredoc support */
5064 static int
5065 forkshell(struct job *jp, union node *n, int mode)
5066 {
5067         int pid;
5068
5069         TRACE(("forkshell(%%%d, %p, %d) called\n", jobno(jp), n, mode));
5070         pid = fork();
5071         if (pid < 0) {
5072                 TRACE(("Fork failed, errno=%d", errno));
5073                 if (jp)
5074                         freejob(jp);
5075                 ash_msg_and_raise_error("can't fork");
5076         }
5077         if (pid == 0) {
5078                 CLEAR_RANDOM_T(&random_gen); /* or else $RANDOM repeats in child */
5079                 forkchild(jp, n, mode);
5080         } else {
5081                 forkparent(jp, n, mode, pid);
5082         }
5083         return pid;
5084 }
5085
5086 /*
5087  * Wait for job to finish.
5088  *
5089  * Under job control we have the problem that while a child process
5090  * is running interrupts generated by the user are sent to the child
5091  * but not to the shell.  This means that an infinite loop started by
5092  * an interactive user may be hard to kill.  With job control turned off,
5093  * an interactive user may place an interactive program inside a loop.
5094  * If the interactive program catches interrupts, the user doesn't want
5095  * these interrupts to also abort the loop.  The approach we take here
5096  * is to have the shell ignore interrupt signals while waiting for a
5097  * foreground process to terminate, and then send itself an interrupt
5098  * signal if the child process was terminated by an interrupt signal.
5099  * Unfortunately, some programs want to do a bit of cleanup and then
5100  * exit on interrupt; unless these processes terminate themselves by
5101  * sending a signal to themselves (instead of calling exit) they will
5102  * confuse this approach.
5103  *
5104  * Called with interrupts off.
5105  */
5106 static int
5107 waitforjob(struct job *jp)
5108 {
5109         int st;
5110
5111         TRACE(("waitforjob(%%%d) called\n", jobno(jp)));
5112
5113         INT_OFF;
5114         while (jp->state == JOBRUNNING) {
5115                 /* In non-interactive shells, we _can_ get
5116                  * a keyboard signal here and be EINTRed,
5117                  * but we just loop back, waiting for command to complete.
5118                  *
5119                  * man bash:
5120                  * "If bash is waiting for a command to complete and receives
5121                  * a signal for which a trap has been set, the trap
5122                  * will not be executed until the command completes."
5123                  *
5124                  * Reality is that even if trap is not set, bash
5125                  * will not act on the signal until command completes.
5126                  * Try this. sleep5intoff.c:
5127                  * #include <signal.h>
5128                  * #include <unistd.h>
5129                  * int main() {
5130                  *         sigset_t set;
5131                  *         sigemptyset(&set);
5132                  *         sigaddset(&set, SIGINT);
5133                  *         sigaddset(&set, SIGQUIT);
5134                  *         sigprocmask(SIG_BLOCK, &set, NULL);
5135                  *         sleep(5);
5136                  *         return 0;
5137                  * }
5138                  * $ bash -c './sleep5intoff; echo hi'
5139                  * ^C^C^C^C <--- pressing ^C once a second
5140                  * $ _
5141                  * $ bash -c './sleep5intoff; echo hi'
5142                  * ^\^\^\^\hi <--- pressing ^\ (SIGQUIT)
5143                  * $ _
5144                  */
5145                 dowait(DOWAIT_BLOCK, jp);
5146         }
5147         INT_ON;
5148
5149         st = getstatus(jp);
5150 #if JOBS
5151         if (jp->jobctl) {
5152                 xtcsetpgrp(ttyfd, rootpid);
5153                 restore_tty_if_stopped_or_signaled(jp);
5154
5155                 /*
5156                  * This is truly gross.
5157                  * If we're doing job control, then we did a TIOCSPGRP which
5158                  * caused us (the shell) to no longer be in the controlling
5159                  * session -- so we wouldn't have seen any ^C/SIGINT.  So, we
5160                  * intuit from the subprocess exit status whether a SIGINT
5161                  * occurred, and if so interrupt ourselves.  Yuck.  - mycroft
5162                  */
5163                 if (jp->sigint) /* TODO: do the same with all signals */
5164                         raise(SIGINT); /* ... by raise(jp->sig) instead? */
5165         }
5166         if (jp->state == JOBDONE)
5167 #endif
5168                 freejob(jp);
5169         return st;
5170 }
5171
5172 /*
5173  * return 1 if there are stopped jobs, otherwise 0
5174  */
5175 static int
5176 stoppedjobs(void)
5177 {
5178         struct job *jp;
5179         int retval;
5180
5181         retval = 0;
5182         if (job_warning)
5183                 goto out;
5184         jp = curjob;
5185         if (jp && jp->state == JOBSTOPPED) {
5186                 out2str("You have stopped jobs.\n");
5187                 job_warning = 2;
5188                 retval++;
5189         }
5190  out:
5191         return retval;
5192 }
5193
5194
5195 /*
5196  * Code for dealing with input/output redirection.
5197  */
5198
5199 #undef EMPTY
5200 #undef CLOSED
5201 #define EMPTY -2                /* marks an unused slot in redirtab */
5202 #define CLOSED -1               /* marks a slot of previously-closed fd */
5203
5204 /*
5205  * Handle here documents.  Normally we fork off a process to write the
5206  * data to a pipe.  If the document is short, we can stuff the data in
5207  * the pipe without forking.
5208  */
5209 /* openhere needs this forward reference */
5210 static void expandhere(union node *arg, int fd);
5211 static int
5212 openhere(union node *redir)
5213 {
5214         int pip[2];
5215         size_t len = 0;
5216
5217         if (pipe(pip) < 0)
5218                 ash_msg_and_raise_error("pipe call failed");
5219         if (redir->type == NHERE) {
5220                 len = strlen(redir->nhere.doc->narg.text);
5221                 if (len <= PIPE_BUF) {
5222                         full_write(pip[1], redir->nhere.doc->narg.text, len);
5223                         goto out;
5224                 }
5225         }
5226         if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) {
5227                 /* child */
5228                 close(pip[0]);
5229                 ignoresig(SIGINT);  //signal(SIGINT, SIG_IGN);
5230                 ignoresig(SIGQUIT); //signal(SIGQUIT, SIG_IGN);
5231                 ignoresig(SIGHUP);  //signal(SIGHUP, SIG_IGN);
5232                 ignoresig(SIGTSTP); //signal(SIGTSTP, SIG_IGN);
5233                 signal(SIGPIPE, SIG_DFL);
5234                 if (redir->type == NHERE)
5235                         full_write(pip[1], redir->nhere.doc->narg.text, len);
5236                 else /* NXHERE */
5237                         expandhere(redir->nhere.doc, pip[1]);
5238                 _exit(EXIT_SUCCESS);
5239         }
5240  out:
5241         close(pip[1]);
5242         return pip[0];
5243 }
5244
5245 static int
5246 openredirect(union node *redir)
5247 {
5248         struct stat sb;
5249         char *fname;
5250         int f;
5251
5252         switch (redir->nfile.type) {
5253 /* Can't happen, our single caller does this itself */
5254 //      case NTOFD:
5255 //      case NFROMFD:
5256 //              return -1;
5257         case NHERE:
5258         case NXHERE:
5259                 return openhere(redir);
5260         }
5261
5262         /* For N[X]HERE, reading redir->nfile.expfname would touch beyond
5263          * allocated space. Do it only when we know it is safe.
5264          */
5265         fname = redir->nfile.expfname;
5266
5267         switch (redir->nfile.type) {
5268         default:
5269 #if DEBUG
5270                 abort();
5271 #endif
5272         case NFROM:
5273                 f = open(fname, O_RDONLY);
5274                 if (f < 0)
5275                         goto eopen;
5276                 break;
5277         case NFROMTO:
5278                 f = open(fname, O_RDWR|O_CREAT, 0666);
5279                 if (f < 0)
5280                         goto ecreate;
5281                 break;
5282         case NTO:
5283 #if BASH_REDIR_OUTPUT
5284         case NTO2:
5285 #endif
5286                 /* Take care of noclobber mode. */
5287                 if (Cflag) {
5288                         if (stat(fname, &sb) < 0) {
5289                                 f = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0666);
5290                                 if (f < 0)
5291                                         goto ecreate;
5292                         } else if (!S_ISREG(sb.st_mode)) {
5293                                 f = open(fname, O_WRONLY, 0666);
5294                                 if (f < 0)
5295                                         goto ecreate;
5296                                 if (fstat(f, &sb) < 0 && S_ISREG(sb.st_mode)) {
5297                                         close(f);
5298                                         errno = EEXIST;
5299                                         goto ecreate;
5300                                 }
5301                         } else {
5302                                 errno = EEXIST;
5303                                 goto ecreate;
5304                         }
5305                         break;
5306                 }
5307                 /* FALLTHROUGH */
5308         case NCLOBBER:
5309                 f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666);
5310                 if (f < 0)
5311                         goto ecreate;
5312                 break;
5313         case NAPPEND:
5314                 f = open(fname, O_WRONLY|O_CREAT|O_APPEND, 0666);
5315                 if (f < 0)
5316                         goto ecreate;
5317                 break;
5318         }
5319
5320         return f;
5321  ecreate:
5322         ash_msg_and_raise_error("can't create %s: %s", fname, errmsg(errno, "nonexistent directory"));
5323  eopen:
5324         ash_msg_and_raise_error("can't open %s: %s", fname, errmsg(errno, "no such file"));
5325 }
5326
5327 /*
5328  * Copy a file descriptor to be >= 10. Throws exception on error.
5329  */
5330 static int
5331 savefd(int from)
5332 {
5333         int newfd;
5334         int err;
5335
5336         newfd = fcntl(from, F_DUPFD, 10);
5337         err = newfd < 0 ? errno : 0;
5338         if (err != EBADF) {
5339                 if (err)
5340                         ash_msg_and_raise_perror("%d", from);
5341                 close(from);
5342                 fcntl(newfd, F_SETFD, FD_CLOEXEC);
5343         }
5344
5345         return newfd;
5346 }
5347 static int
5348 dup2_or_raise(int from, int to)
5349 {
5350         int newfd;
5351
5352         newfd = (from != to) ? dup2(from, to) : to;
5353         if (newfd < 0) {
5354                 /* Happens when source fd is not open: try "echo >&99" */
5355                 ash_msg_and_raise_perror("%d", from);
5356         }
5357         return newfd;
5358 }
5359 static int
5360 fcntl_F_DUPFD(int fd, int avoid_fd)
5361 {
5362         int newfd;
5363  repeat:
5364         newfd = fcntl(fd, F_DUPFD, avoid_fd + 1);
5365         if (newfd < 0) {
5366                 if (errno == EBUSY)
5367                         goto repeat;
5368                 if (errno == EINTR)
5369                         goto repeat;
5370         }
5371         return newfd;
5372 }
5373 static int
5374 xdup_CLOEXEC_and_close(int fd, int avoid_fd)
5375 {
5376         int newfd;
5377  repeat:
5378         newfd = fcntl(fd, F_DUPFD, avoid_fd + 1);
5379         if (newfd < 0) {
5380                 if (errno == EBUSY)
5381                         goto repeat;
5382                 if (errno == EINTR)
5383                         goto repeat;
5384                 /* fd was not open? */
5385                 if (errno == EBADF)
5386                         return fd;
5387                 ash_msg_and_raise_perror("%d", newfd);
5388         }
5389         fcntl(newfd, F_SETFD, FD_CLOEXEC);
5390         close(fd);
5391         return newfd;
5392 }
5393
5394 /* Struct def and variable are moved down to the first usage site */
5395 struct squirrel {
5396         int orig_fd;
5397         int moved_to;
5398 };
5399 struct redirtab {
5400         struct redirtab *next;
5401         int pair_count;
5402         struct squirrel two_fd[];
5403 };
5404 #define redirlist (G_var.redirlist)
5405
5406 static void
5407 add_squirrel_closed(struct redirtab *sq, int fd)
5408 {
5409         int i;
5410
5411         if (!sq)
5412                 return;
5413
5414         for (i = 0; sq->two_fd[i].orig_fd != EMPTY; i++) {
5415                 /* If we collide with an already moved fd... */
5416                 if (fd == sq->two_fd[i].orig_fd) {
5417                         /* Examples:
5418                          * "echo 3>FILE 3>&- 3>FILE"
5419                          * "echo 3>&- 3>FILE"
5420                          * No need for last redirect to insert
5421                          * another "need to close 3" indicator.
5422                          */
5423                         TRACE(("redirect_fd %d: already moved or closed\n", fd));
5424                         return;
5425                 }
5426         }
5427         TRACE(("redirect_fd %d: previous fd was closed\n", fd));
5428         sq->two_fd[i].orig_fd = fd;
5429         sq->two_fd[i].moved_to = CLOSED;
5430 }
5431
5432 static int
5433 save_fd_on_redirect(int fd, int avoid_fd, struct redirtab *sq)
5434 {
5435         int i, new_fd;
5436
5437         if (avoid_fd < 9) /* the important case here is that it can be -1 */
5438                 avoid_fd = 9;
5439
5440 #if JOBS
5441         if (fd == ttyfd) {
5442                 /* Testcase: "ls -l /proc/$$/fd 10>&-" should work */
5443                 ttyfd = xdup_CLOEXEC_and_close(ttyfd, avoid_fd);
5444                 TRACE(("redirect_fd %d: matches ttyfd, moving it to %d\n", fd, ttyfd));
5445                 return 1; /* "we closed fd" */
5446         }
5447 #endif
5448         /* Are we called from redirect(0)? E.g. redirect
5449          * in a forked child. No need to save fds,
5450          * we aren't going to use them anymore, ok to trash.
5451          */
5452         if (!sq)
5453                 return 0;
5454
5455         /* If this one of script's fds? */
5456         if (fd != 0) {
5457                 struct parsefile *pf = g_parsefile;
5458                 while (pf) {
5459                         /* We skip fd == 0 case because of the following:
5460                          * $ ash  # running ash interactively
5461                          * $ . ./script.sh
5462                          * and in script.sh: "exec 9>&0".
5463                          * Even though top-level pf_fd _is_ 0,
5464                          * it's still ok to use it: "read" builtin uses it,
5465                          * why should we cripple "exec" builtin?
5466                          */
5467                         if (fd == pf->pf_fd) {
5468                                 pf->pf_fd = xdup_CLOEXEC_and_close(fd, avoid_fd);
5469                                 return 1; /* "we closed fd" */
5470                         }
5471                         pf = pf->prev;
5472                 }
5473         }
5474
5475         /* Check whether it collides with any open fds (e.g. stdio), save fds as needed */
5476
5477         /* First: do we collide with some already moved fds? */
5478         for (i = 0; sq->two_fd[i].orig_fd != EMPTY; i++) {
5479                 /* If we collide with an already moved fd... */
5480                 if (fd == sq->two_fd[i].moved_to) {
5481                         new_fd = fcntl_F_DUPFD(fd, avoid_fd);
5482                         sq->two_fd[i].moved_to = new_fd;
5483                         TRACE(("redirect_fd %d: already busy, moving to %d\n", fd, new_fd));
5484                         if (new_fd < 0) /* what? */
5485                                 xfunc_die();
5486                         return 0; /* "we did not close fd" */
5487                 }
5488                 if (fd == sq->two_fd[i].orig_fd) {
5489                         /* Example: echo Hello >/dev/null 1>&2 */
5490                         TRACE(("redirect_fd %d: already moved\n", fd));
5491                         return 0; /* "we did not close fd" */
5492                 }
5493         }
5494
5495         /* If this fd is open, we move and remember it; if it's closed, new_fd = CLOSED (-1) */
5496         new_fd = fcntl_F_DUPFD(fd, avoid_fd);
5497         TRACE(("redirect_fd %d: previous fd is moved to %d (-1 if it was closed)\n", fd, new_fd));
5498         if (new_fd < 0) {
5499                 if (errno != EBADF)
5500                         xfunc_die();
5501                 /* new_fd = CLOSED; - already is -1 */
5502         }
5503         sq->two_fd[i].moved_to = new_fd;
5504         sq->two_fd[i].orig_fd = fd;
5505
5506         /* if we move stderr, let "set -x" code know */
5507         if (fd == preverrout_fd)
5508                 preverrout_fd = new_fd;
5509
5510         return 0; /* "we did not close fd" */
5511 }
5512
5513 static int
5514 internally_opened_fd(int fd, struct redirtab *sq)
5515 {
5516         int i;
5517 #if JOBS
5518         if (fd == ttyfd)
5519                 return 1;
5520 #endif
5521         /* If this one of script's fds? */
5522         if (fd != 0) {
5523                 struct parsefile *pf = g_parsefile;
5524                 while (pf) {
5525                         if (fd == pf->pf_fd)
5526                                 return 1;
5527                         pf = pf->prev;
5528                 }
5529         }
5530
5531         if (sq) for (i = 0; i < sq->pair_count && sq->two_fd[i].orig_fd != EMPTY; i++) {
5532                 if (fd == sq->two_fd[i].moved_to)
5533                         return 1;
5534         }
5535         return 0;
5536 }
5537
5538 /*
5539  * Process a list of redirection commands.  If the REDIR_PUSH flag is set,
5540  * old file descriptors are stashed away so that the redirection can be
5541  * undone by calling popredir.
5542  */
5543 /* flags passed to redirect */
5544 #define REDIR_PUSH    01        /* save previous values of file descriptors */
5545 static void
5546 redirect(union node *redir, int flags)
5547 {
5548         struct redirtab *sv;
5549         int sv_pos;
5550
5551         if (!redir)
5552                 return;
5553
5554         sv_pos = 0;
5555         sv = NULL;
5556         INT_OFF;
5557         if (flags & REDIR_PUSH)
5558                 sv = redirlist;
5559         do {
5560                 int fd;
5561                 int newfd;
5562                 int close_fd;
5563                 int closed;
5564
5565                 fd = redir->nfile.fd;
5566                 if (redir->nfile.type == NTOFD || redir->nfile.type == NFROMFD) {
5567                         //bb_error_msg("doing %d > %d", fd, newfd);
5568                         newfd = redir->ndup.dupfd;
5569                         close_fd = -1;
5570                 } else {
5571                         newfd = openredirect(redir); /* always >= 0 */
5572                         if (fd == newfd) {
5573                                 /* open() gave us precisely the fd we wanted.
5574                                  * This means that this fd was not busy
5575                                  * (not opened to anywhere).
5576                                  * Remember to close it on restore:
5577                                  */
5578                                 add_squirrel_closed(sv, fd);
5579                                 continue;
5580                         }
5581                         close_fd = newfd;
5582                 }
5583
5584                 if (fd == newfd)
5585                         continue;
5586
5587                 /* if "N>FILE": move newfd to fd */
5588                 /* if "N>&M": dup newfd to fd */
5589                 /* if "N>&-": close fd (newfd is -1) */
5590
5591  IF_BASH_REDIR_OUTPUT(redirect_more:)
5592
5593                 closed = save_fd_on_redirect(fd, /*avoid:*/ newfd, sv);
5594                 if (newfd == -1) {
5595                         /* "N>&-" means "close me" */
5596                         if (!closed) {
5597                                 /* ^^^ optimization: saving may already
5598                                  * have closed it. If not... */
5599                                 close(fd);
5600                         }
5601                 } else {
5602                         /* if newfd is a script fd or saved fd, simulate EBADF */
5603                         if (internally_opened_fd(newfd, sv)) {
5604                                 errno = EBADF;
5605                                 ash_msg_and_raise_perror("%d", newfd);
5606                         }
5607                         dup2_or_raise(newfd, fd);
5608                         if (close_fd >= 0) /* "N>FILE" or ">&FILE" or heredoc? */
5609                                 close(close_fd);
5610 #if BASH_REDIR_OUTPUT
5611                         if (redir->nfile.type == NTO2 && fd == 1) {
5612                                 /* ">&FILE". we already redirected to 1, now copy 1 to 2 */
5613                                 fd = 2;
5614                                 newfd = 1;
5615                                 close_fd = -1;
5616                                 goto redirect_more;
5617                         }
5618 #endif
5619                 }
5620         } while ((redir = redir->nfile.next) != NULL);
5621         INT_ON;
5622
5623 //dash:#define REDIR_SAVEFD2 03        /* set preverrout */
5624 #define REDIR_SAVEFD2 0
5625         // dash has a bug: since REDIR_SAVEFD2=3 and REDIR_PUSH=1, this test
5626         // triggers for pure REDIR_PUSH too. Thus, this is done almost always,
5627         // not only for calls with flags containing REDIR_SAVEFD2.
5628         // We do this unconditionally (see save_fd_on_redirect()).
5629         //if ((flags & REDIR_SAVEFD2) && copied_fd2 >= 0)
5630         //      preverrout_fd = copied_fd2;
5631 }
5632
5633 static int
5634 redirectsafe(union node *redir, int flags)
5635 {
5636         int err;
5637         volatile int saveint;
5638         struct jmploc *volatile savehandler = exception_handler;
5639         struct jmploc jmploc;
5640
5641         SAVE_INT(saveint);
5642         /* "echo 9>/dev/null; echo >&9; echo result: $?" - result should be 1, not 2! */
5643         err = setjmp(jmploc.loc); /* was = setjmp(jmploc.loc) * 2; */
5644         if (!err) {
5645                 exception_handler = &jmploc;
5646                 redirect(redir, flags);
5647         }
5648         exception_handler = savehandler;
5649         if (err && exception_type != EXERROR)
5650                 longjmp(exception_handler->loc, 1);
5651         RESTORE_INT(saveint);
5652         return err;
5653 }
5654
5655 static struct redirtab*
5656 pushredir(union node *redir)
5657 {
5658         struct redirtab *sv;
5659         int i;
5660
5661         if (!redir)
5662                 return redirlist;
5663
5664         i = 0;
5665         do {
5666                 i++;
5667 #if BASH_REDIR_OUTPUT
5668                 if (redir->nfile.type == NTO2)
5669                         i++;
5670 #endif
5671                 redir = redir->nfile.next;
5672         } while (redir);
5673
5674         sv = ckzalloc(sizeof(*sv) + i * sizeof(sv->two_fd[0]));
5675         sv->pair_count = i;
5676         while (--i >= 0)
5677                 sv->two_fd[i].orig_fd = sv->two_fd[i].moved_to = EMPTY;
5678         sv->next = redirlist;
5679         redirlist = sv;
5680         return sv->next;
5681 }
5682
5683 /*
5684  * Undo the effects of the last redirection.
5685  */
5686 static void
5687 popredir(int drop)
5688 {
5689         struct redirtab *rp;
5690         int i;
5691
5692         if (redirlist == NULL)
5693                 return;
5694         INT_OFF;
5695         rp = redirlist;
5696         for (i = 0; i < rp->pair_count; i++) {
5697                 int fd = rp->two_fd[i].orig_fd;
5698                 int copy = rp->two_fd[i].moved_to;
5699                 if (copy == CLOSED) {
5700                         if (!drop)
5701                                 close(fd);
5702                         continue;
5703                 }
5704                 if (copy != EMPTY) {
5705                         if (!drop) {
5706                                 /*close(fd);*/
5707                                 dup2_or_raise(copy, fd);
5708                         }
5709                         close(copy);
5710                 }
5711         }
5712         redirlist = rp->next;
5713         free(rp);
5714         INT_ON;
5715 }
5716
5717 static void
5718 unwindredir(struct redirtab *stop)
5719 {
5720         while (redirlist != stop)
5721                 popredir(/*drop:*/ 0);
5722 }
5723
5724
5725 /* ============ Routines to expand arguments to commands
5726  *
5727  * We have to deal with backquotes, shell variables, and file metacharacters.
5728  */
5729
5730 #if ENABLE_FEATURE_SH_MATH
5731 static arith_t
5732 ash_arith(const char *s)
5733 {
5734         arith_state_t math_state;
5735         arith_t result;
5736
5737         math_state.lookupvar = lookupvar;
5738         math_state.setvar    = setvar0;
5739         //math_state.endofname = endofname;
5740
5741         INT_OFF;
5742         result = arith(&math_state, s);
5743         if (math_state.errmsg)
5744                 ash_msg_and_raise_error(math_state.errmsg);
5745         INT_ON;
5746
5747         return result;
5748 }
5749 #endif
5750
5751 /*
5752  * expandarg flags
5753  */
5754 #define EXP_FULL        0x1     /* perform word splitting & file globbing */
5755 #define EXP_TILDE       0x2     /* do normal tilde expansion */
5756 #define EXP_VARTILDE    0x4     /* expand tildes in an assignment */
5757 #define EXP_REDIR       0x8     /* file glob for a redirection (1 match only) */
5758 /* ^^^^^^^^^^^^^^ this is meant to support constructs such as "cmd >file*.txt"
5759  * POSIX says for this case:
5760  *  Pathname expansion shall not be performed on the word by a
5761  *  non-interactive shell; an interactive shell may perform it, but shall
5762  *  do so only when the expansion would result in one word.
5763  * Currently, our code complies to the above rule by never globbing
5764  * redirection filenames.
5765  * Bash performs globbing, unless it is non-interactive and in POSIX mode.
5766  * (this means that on a typical Linux distro, bash almost always
5767  * performs globbing, and thus diverges from what we do).
5768  */
5769 #define EXP_CASE        0x10    /* keeps quotes around for CASE pattern */
5770 #define EXP_QPAT        0x20    /* pattern in quoted parameter expansion */
5771 #define EXP_VARTILDE2   0x40    /* expand tildes after colons only */
5772 #define EXP_WORD        0x80    /* expand word in parameter expansion */
5773 #define EXP_QUOTED      0x100   /* expand word in double quotes */
5774 /*
5775  * rmescape() flags
5776  */
5777 #define RMESCAPE_ALLOC  0x1     /* Allocate a new string */
5778 #define RMESCAPE_GLOB   0x2     /* Add backslashes for glob */
5779 #define RMESCAPE_GROW   0x8     /* Grow strings instead of stalloc */
5780 #define RMESCAPE_HEAP   0x10    /* Malloc strings instead of stalloc */
5781 #define RMESCAPE_SLASH  0x20    /* Stop globbing after slash */
5782
5783 /* Add CTLESC when necessary. */
5784 #define QUOTES_ESC     (EXP_FULL | EXP_CASE | EXP_QPAT)
5785 /* Do not skip NUL characters. */
5786 #define QUOTES_KEEPNUL EXP_TILDE
5787
5788 /*
5789  * Structure specifying which parts of the string should be searched
5790  * for IFS characters.
5791  */
5792 struct ifsregion {
5793         struct ifsregion *next; /* next region in list */
5794         int begoff;             /* offset of start of region */
5795         int endoff;             /* offset of end of region */
5796         int nulonly;            /* search for nul bytes only */
5797 };
5798
5799 struct arglist {
5800         struct strlist *list;
5801         struct strlist **lastp;
5802 };
5803
5804 /* output of current string */
5805 static char *expdest;
5806 /* list of back quote expressions */
5807 static struct nodelist *argbackq;
5808 /* first struct in list of ifs regions */
5809 static struct ifsregion ifsfirst;
5810 /* last struct in list */
5811 static struct ifsregion *ifslastp;
5812 /* holds expanded arg list */
5813 static struct arglist exparg;
5814
5815 /*
5816  * Our own itoa().
5817  * cvtnum() is used even if math support is off (to prepare $? values and such).
5818  */
5819 static int
5820 cvtnum(arith_t num)
5821 {
5822         int len;
5823
5824         /* 32-bit and wider ints require buffer size of bytes*3 (or less) */
5825         len = sizeof(arith_t) * 3;
5826         /* If narrower: worst case, 1-byte ints: need 5 bytes: "-127<NUL>" */
5827         if (sizeof(arith_t) < 4) len += 2;
5828
5829         expdest = makestrspace(len, expdest);
5830         len = fmtstr(expdest, len, ARITH_FMT, num);
5831         STADJUST(len, expdest);
5832         return len;
5833 }
5834
5835 /*
5836  * Break the argument string into pieces based upon IFS and add the
5837  * strings to the argument list.  The regions of the string to be
5838  * searched for IFS characters have been stored by recordregion.
5839  */
5840 static void
5841 ifsbreakup(char *string, struct arglist *arglist)
5842 {
5843         struct ifsregion *ifsp;
5844         struct strlist *sp;
5845         char *start;
5846         char *p;
5847         char *q;
5848         const char *ifs, *realifs;
5849         int ifsspc;
5850         int nulonly;
5851
5852         start = string;
5853         if (ifslastp != NULL) {
5854                 ifsspc = 0;
5855                 nulonly = 0;
5856                 realifs = ifsset() ? ifsval() : defifs;
5857                 ifsp = &ifsfirst;
5858                 do {
5859                         p = string + ifsp->begoff;
5860                         nulonly = ifsp->nulonly;
5861                         ifs = nulonly ? nullstr : realifs;
5862                         ifsspc = 0;
5863                         while (p < string + ifsp->endoff) {
5864                                 q = p;
5865                                 if ((unsigned char)*p == CTLESC)
5866                                         p++;
5867                                 if (!strchr(ifs, *p)) {
5868                                         p++;
5869                                         continue;
5870                                 }
5871                                 if (!nulonly)
5872                                         ifsspc = (strchr(defifs, *p) != NULL);
5873                                 /* Ignore IFS whitespace at start */
5874                                 if (q == start && ifsspc) {
5875                                         p++;
5876                                         start = p;
5877                                         continue;
5878                                 }
5879                                 *q = '\0';
5880                                 sp = stzalloc(sizeof(*sp));
5881                                 sp->text = start;
5882                                 *arglist->lastp = sp;
5883                                 arglist->lastp = &sp->next;
5884                                 p++;
5885                                 if (!nulonly) {
5886                                         for (;;) {
5887                                                 if (p >= string + ifsp->endoff) {
5888                                                         break;
5889                                                 }
5890                                                 q = p;
5891                                                 if ((unsigned char)*p == CTLESC)
5892                                                         p++;
5893                                                 if (strchr(ifs, *p) == NULL) {
5894                                                         p = q;
5895                                                         break;
5896                                                 }
5897                                                 if (strchr(defifs, *p) == NULL) {
5898                                                         if (ifsspc) {
5899                                                                 p++;
5900                                                                 ifsspc = 0;
5901                                                         } else {
5902                                                                 p = q;
5903                                                                 break;
5904                                                         }
5905                                                 } else
5906                                                         p++;
5907                                         }
5908                                 }
5909                                 start = p;
5910                         } /* while */
5911                         ifsp = ifsp->next;
5912                 } while (ifsp != NULL);
5913                 if (nulonly)
5914                         goto add;
5915         }
5916
5917         if (!*start)
5918                 return;
5919
5920  add:
5921         sp = stzalloc(sizeof(*sp));
5922         sp->text = start;
5923         *arglist->lastp = sp;
5924         arglist->lastp = &sp->next;
5925 }
5926
5927 static void
5928 ifsfree(void)
5929 {
5930         struct ifsregion *p = ifsfirst.next;
5931
5932         if (!p)
5933                 goto out;
5934
5935         INT_OFF;
5936         do {
5937                 struct ifsregion *ifsp;
5938                 ifsp = p->next;
5939                 free(p);
5940                 p = ifsp;
5941         } while (p);
5942         ifsfirst.next = NULL;
5943         INT_ON;
5944  out:
5945         ifslastp = NULL;
5946 }
5947
5948 static size_t
5949 esclen(const char *start, const char *p)
5950 {
5951         size_t esc = 0;
5952
5953         while (p > start && (unsigned char)*--p == CTLESC) {
5954                 esc++;
5955         }
5956         return esc;
5957 }
5958
5959 /*
5960  * Remove any CTLESC characters from a string.
5961  */
5962 static char *
5963 rmescapes(char *str, int flag)
5964 {
5965         static const char qchars[] ALIGN1 = {
5966                 IF_BASH_PATTERN_SUBST('/',) CTLESC, CTLQUOTEMARK, '\0' };
5967
5968         char *p, *q, *r;
5969         unsigned inquotes;
5970         unsigned protect_against_glob;
5971         unsigned globbing;
5972         IF_BASH_PATTERN_SUBST(unsigned slash = flag & RMESCAPE_SLASH;)
5973
5974         p = strpbrk(str, qchars IF_BASH_PATTERN_SUBST(+ !slash));
5975         if (!p)
5976                 return str;
5977
5978         q = p;
5979         r = str;
5980         if (flag & RMESCAPE_ALLOC) {
5981                 size_t len = p - str;
5982                 size_t fulllen = len + strlen(p) + 1;
5983
5984                 if (flag & RMESCAPE_GROW) {
5985                         int strloc = str - (char *)stackblock();
5986                         r = makestrspace(fulllen, expdest);
5987                         /* p and str may be invalidated by makestrspace */
5988                         str = (char *)stackblock() + strloc;
5989                         p = str + len;
5990                 } else if (flag & RMESCAPE_HEAP) {
5991                         r = ckmalloc(fulllen);
5992                 } else {
5993                         r = stalloc(fulllen);
5994                 }
5995                 q = r;
5996                 if (len > 0) {
5997                         q = (char *)mempcpy(q, str, len);
5998                 }
5999         }
6000
6001         inquotes = 0;
6002         globbing = flag & RMESCAPE_GLOB;
6003         protect_against_glob = globbing;
6004         while (*p) {
6005                 if ((unsigned char)*p == CTLQUOTEMARK) {
6006 // Note: both inquotes and protect_against_glob only affect whether
6007 // CTLESC,<ch> gets converted to <ch> or to \<ch>
6008                         inquotes = ~inquotes;
6009                         p++;
6010                         protect_against_glob = globbing;
6011                         continue;
6012                 }
6013                 if ((unsigned char)*p == CTLESC) {
6014                         p++;
6015 #if DEBUG
6016                         if (*p == '\0')
6017                                 ash_msg_and_raise_error("CTLESC at EOL (shouldn't happen)");
6018 #endif
6019                         if (protect_against_glob) {
6020                                 /*
6021                                  * We used to trust glob() and fnmatch() to eat
6022                                  * superfluous escapes (\z where z has no
6023                                  * special meaning anyway). But this causes
6024                                  * bugs such as string of one greek letter rho
6025                                  * (unicode-encoded as two bytes "cf,81")
6026                                  * getting encoded as "cf,CTLESC,81"
6027                                  * and here, converted to "cf,\,81" -
6028                                  * which does not go well with some flavors
6029                                  * of fnmatch() in unicode locales
6030                                  * (for example, glibc <= 2.22).
6031                                  *
6032                                  * Lets add "\" only on the chars which need it.
6033                                  * Testcases for less obvious chars are shown.
6034                                  */
6035                                 if (*p == '*'
6036                                  || *p == '?'
6037                                  || *p == '['
6038                                  || *p == '\\' /* case '\' in \\ ) echo ok;; *) echo WRONG;; esac */
6039                                  || *p == ']' /* case ']' in [a\]] ) echo ok;; *) echo WRONG;; esac */
6040                                  || *p == '-' /* case '-' in [a\-c]) echo ok;; *) echo WRONG;; esac */
6041                                  || *p == '!' /* case '!' in [\!] ) echo ok;; *) echo WRONG;; esac */
6042                                 /* Some libc support [^negate], that's why "^" also needs love */
6043                                  || *p == '^' /* case '^' in [\^] ) echo ok;; *) echo WRONG;; esac */
6044                                 ) {
6045                                         *q++ = '\\';
6046                                 }
6047                         }
6048                 } else if (*p == '\\' && !inquotes) {
6049                         /* naked back slash */
6050                         protect_against_glob = 0;
6051                         goto copy;
6052                 }
6053 #if BASH_PATTERN_SUBST
6054                 else if (*p == '/' && slash) {
6055                         /* stop handling globbing and mark location of slash */
6056                         globbing = slash = 0;
6057                         *p = CTLESC;
6058                 }
6059 #endif
6060                 protect_against_glob = globbing;
6061  copy:
6062                 *q++ = *p++;
6063         }
6064         *q = '\0';
6065         if (flag & RMESCAPE_GROW) {
6066                 expdest = r;
6067                 STADJUST(q - r + 1, expdest);
6068         }
6069         return r;
6070 }
6071 #define pmatch(a, b) !fnmatch((a), (b), 0)
6072
6073 /*
6074  * Prepare a pattern for a expmeta (internal glob(3)) call.
6075  *
6076  * Returns an stalloced string.
6077  */
6078 static char *
6079 preglob(const char *pattern, int flag)
6080 {
6081         return rmescapes((char *)pattern, flag | RMESCAPE_GLOB);
6082 }
6083
6084 /*
6085  * Put a string on the stack.
6086  */
6087 static void
6088 memtodest(const char *p, size_t len, int syntax, int quotes)
6089 {
6090         char *q;
6091
6092         if (!len)
6093                 return;
6094
6095         q = makestrspace((quotes & QUOTES_ESC) ? len * 2 : len, expdest);
6096
6097         do {
6098                 unsigned char c = *p++;
6099                 if (c) {
6100                         if (quotes & QUOTES_ESC) {
6101                                 int n = SIT(c, syntax);
6102                                 if (n == CCTL
6103                                  || (((quotes & EXP_FULL) || syntax != BASESYNTAX)
6104                                      && n == CBACK
6105                                     )
6106                                 ) {
6107                                         USTPUTC(CTLESC, q);
6108                                 }
6109                         }
6110                 } else if (!(quotes & QUOTES_KEEPNUL))
6111                         continue;
6112                 USTPUTC(c, q);
6113         } while (--len);
6114
6115         expdest = q;
6116 }
6117
6118 static size_t
6119 strtodest(const char *p, int syntax, int quotes)
6120 {
6121         size_t len = strlen(p);
6122         memtodest(p, len, syntax, quotes);
6123         return len;
6124 }
6125
6126 /*
6127  * Record the fact that we have to scan this region of the
6128  * string for IFS characters.
6129  */
6130 static void
6131 recordregion(int start, int end, int nulonly)
6132 {
6133         struct ifsregion *ifsp;
6134
6135         if (ifslastp == NULL) {
6136                 ifsp = &ifsfirst;
6137         } else {
6138                 INT_OFF;
6139                 ifsp = ckzalloc(sizeof(*ifsp));
6140                 /*ifsp->next = NULL; - ckzalloc did it */
6141                 ifslastp->next = ifsp;
6142                 INT_ON;
6143         }
6144         ifslastp = ifsp;
6145         ifslastp->begoff = start;
6146         ifslastp->endoff = end;
6147         ifslastp->nulonly = nulonly;
6148 }
6149
6150 static void
6151 removerecordregions(int endoff)
6152 {
6153         if (ifslastp == NULL)
6154                 return;
6155
6156         if (ifsfirst.endoff > endoff) {
6157                 while (ifsfirst.next) {
6158                         struct ifsregion *ifsp;
6159                         INT_OFF;
6160                         ifsp = ifsfirst.next->next;
6161                         free(ifsfirst.next);
6162                         ifsfirst.next = ifsp;
6163                         INT_ON;
6164                 }
6165                 if (ifsfirst.begoff > endoff) {
6166                         ifslastp = NULL;
6167                 } else {
6168                         ifslastp = &ifsfirst;
6169                         ifsfirst.endoff = endoff;
6170                 }
6171                 return;
6172         }
6173
6174         ifslastp = &ifsfirst;
6175         while (ifslastp->next && ifslastp->next->begoff < endoff)
6176                 ifslastp = ifslastp->next;
6177         while (ifslastp->next) {
6178                 struct ifsregion *ifsp;
6179                 INT_OFF;
6180                 ifsp = ifslastp->next->next;
6181                 free(ifslastp->next);
6182                 ifslastp->next = ifsp;
6183                 INT_ON;
6184         }
6185         if (ifslastp->endoff > endoff)
6186                 ifslastp->endoff = endoff;
6187 }
6188
6189 static char *
6190 exptilde(char *startp, char *p, int flags)
6191 {
6192         unsigned char c;
6193         char *name;
6194         struct passwd *pw;
6195         const char *home;
6196         int quotes = flags & QUOTES_ESC;
6197
6198         name = p + 1;
6199
6200         while ((c = *++p) != '\0') {
6201                 switch (c) {
6202                 case CTLESC:
6203                         return startp;
6204                 case CTLQUOTEMARK:
6205                         return startp;
6206                 case ':':
6207                         if (flags & EXP_VARTILDE)
6208                                 goto done;
6209                         break;
6210                 case '/':
6211                 case CTLENDVAR:
6212                         goto done;
6213                 }
6214         }
6215  done:
6216         *p = '\0';
6217         if (*name == '\0') {
6218                 home = lookupvar("HOME");
6219         } else {
6220                 pw = getpwnam(name);
6221                 if (pw == NULL)
6222                         goto lose;
6223                 home = pw->pw_dir;
6224         }
6225         if (!home || !*home)
6226                 goto lose;
6227         *p = c;
6228         strtodest(home, SQSYNTAX, quotes);
6229         return p;
6230  lose:
6231         *p = c;
6232         return startp;
6233 }
6234
6235 /*
6236  * Execute a command inside back quotes.  If it's a builtin command, we
6237  * want to save its output in a block obtained from malloc.  Otherwise
6238  * we fork off a subprocess and get the output of the command via a pipe.
6239  * Should be called with interrupts off.
6240  */
6241 struct backcmd {                /* result of evalbackcmd */
6242         int fd;                 /* file descriptor to read from */
6243         int nleft;              /* number of chars in buffer */
6244         char *buf;              /* buffer */
6245         struct job *jp;         /* job structure for command */
6246 };
6247
6248 /* These forward decls are needed to use "eval" code for backticks handling: */
6249 /* flags in argument to evaltree */
6250 #define EV_EXIT    01           /* exit after evaluating tree */
6251 #define EV_TESTED  02           /* exit status is checked; ignore -e flag */
6252 static int evaltree(union node *, int);
6253
6254 /* An evaltree() which is known to never return.
6255  * Used to use an alias:
6256  * static int evaltreenr(union node *, int) __attribute__((alias("evaltree"),__noreturn__));
6257  * but clang was reported to "transfer" noreturn-ness to evaltree() as well.
6258  */
6259 static ALWAYS_INLINE NORETURN void
6260 evaltreenr(union node *n, int flags)
6261 {
6262         evaltree(n, flags);
6263         bb_unreachable(abort());
6264         /* NOTREACHED */
6265 }
6266
6267 static void FAST_FUNC
6268 evalbackcmd(union node *n, struct backcmd *result)
6269 {
6270         int pip[2];
6271         struct job *jp;
6272
6273         result->fd = -1;
6274         result->buf = NULL;
6275         result->nleft = 0;
6276         result->jp = NULL;
6277         if (n == NULL) {
6278                 goto out;
6279         }
6280
6281         if (pipe(pip) < 0)
6282                 ash_msg_and_raise_error("pipe call failed");
6283         jp = makejob(/*n,*/ 1);
6284         if (forkshell(jp, n, FORK_NOJOB) == 0) {
6285                 /* child */
6286                 FORCE_INT_ON;
6287                 close(pip[0]);
6288                 if (pip[1] != 1) {
6289                         /*close(1);*/
6290                         dup2_or_raise(pip[1], 1);
6291                         close(pip[1]);
6292                 }
6293 /* TODO: eflag clearing makes the following not abort:
6294  *  ash -c 'set -e; z=$(false;echo foo); echo $z'
6295  * which is what bash does (unless it is in POSIX mode).
6296  * dash deleted "eflag = 0" line in the commit
6297  *  Date: Mon, 28 Jun 2010 17:11:58 +1000
6298  *  [EVAL] Don't clear eflag in evalbackcmd
6299  * For now, preserve bash-like behavior, it seems to be somewhat more useful:
6300  */
6301                 eflag = 0;
6302                 ifsfree();
6303                 evaltreenr(n, EV_EXIT);
6304                 /* NOTREACHED */
6305         }
6306         /* parent */
6307         close(pip[1]);
6308         result->fd = pip[0];
6309         result->jp = jp;
6310
6311  out:
6312         TRACE(("evalbackcmd done: fd=%d buf=0x%x nleft=%d jp=0x%x\n",
6313                 result->fd, result->buf, result->nleft, result->jp));
6314 }
6315
6316 /*
6317  * Expand stuff in backwards quotes.
6318  */
6319 static void
6320 expbackq(union node *cmd, int flag)
6321 {
6322         struct backcmd in;
6323         int i;
6324         char buf[128];
6325         char *p;
6326         char *dest;
6327         int startloc;
6328         int syntax = flag & EXP_QUOTED ? DQSYNTAX : BASESYNTAX;
6329         struct stackmark smark;
6330
6331         INT_OFF;
6332         startloc = expdest - (char *)stackblock();
6333         pushstackmark(&smark, startloc);
6334         evalbackcmd(cmd, &in);
6335         popstackmark(&smark);
6336
6337         p = in.buf;
6338         i = in.nleft;
6339         if (i == 0)
6340                 goto read;
6341         for (;;) {
6342                 memtodest(p, i, syntax, flag & QUOTES_ESC);
6343  read:
6344                 if (in.fd < 0)
6345                         break;
6346                 i = nonblock_immune_read(in.fd, buf, sizeof(buf));
6347                 TRACE(("expbackq: read returns %d\n", i));
6348                 if (i <= 0)
6349                         break;
6350                 p = buf;
6351         }
6352
6353         free(in.buf);
6354         if (in.fd >= 0) {
6355                 close(in.fd);
6356                 back_exitstatus = waitforjob(in.jp);
6357         }
6358         INT_ON;
6359
6360         /* Eat all trailing newlines */
6361         dest = expdest;
6362         for (; dest > (char *)stackblock() && dest[-1] == '\n';)
6363                 STUNPUTC(dest);
6364         expdest = dest;
6365
6366         if (!(flag & EXP_QUOTED))
6367                 recordregion(startloc, dest - (char *)stackblock(), 0);
6368         TRACE(("evalbackq: size:%d:'%.*s'\n",
6369                 (int)((dest - (char *)stackblock()) - startloc),
6370                 (int)((dest - (char *)stackblock()) - startloc),
6371                 stackblock() + startloc));
6372 }
6373
6374 #if ENABLE_FEATURE_SH_MATH
6375 /*
6376  * Expand arithmetic expression.  Backup to start of expression,
6377  * evaluate, place result in (backed up) result, adjust string position.
6378  */
6379 static void
6380 expari(int flag)
6381 {
6382         char *p, *start;
6383         int begoff;
6384         int len;
6385
6386         /* ifsfree(); */
6387
6388         /*
6389          * This routine is slightly over-complicated for
6390          * efficiency.  Next we scan backwards looking for the
6391          * start of arithmetic.
6392          */
6393         start = stackblock();
6394         p = expdest - 1;
6395         *p = '\0';
6396         p--;
6397         while (1) {
6398                 int esc;
6399
6400                 while ((unsigned char)*p != CTLARI) {
6401                         p--;
6402 #if DEBUG
6403                         if (p < start) {
6404                                 ash_msg_and_raise_error("missing CTLARI (shouldn't happen)");
6405                         }
6406 #endif
6407                 }
6408
6409                 esc = esclen(start, p);
6410                 if (!(esc % 2)) {
6411                         break;
6412                 }
6413
6414                 p -= esc + 1;
6415         }
6416
6417         begoff = p - start;
6418
6419         removerecordregions(begoff);
6420
6421         expdest = p;
6422
6423         if (flag & QUOTES_ESC)
6424                 rmescapes(p + 1, 0);
6425
6426         len = cvtnum(ash_arith(p + 1));
6427
6428         if (!(flag & EXP_QUOTED))
6429                 recordregion(begoff, begoff + len, 0);
6430 }
6431 #endif
6432
6433 /* argstr needs it */
6434 static char *evalvar(char *p, int flags);
6435
6436 /*
6437  * Perform variable and command substitution.  If EXP_FULL is set, output CTLESC
6438  * characters to allow for further processing.  Otherwise treat
6439  * $@ like $* since no splitting will be performed.
6440  */
6441 static void
6442 argstr(char *p, int flags)
6443 {
6444         static const char spclchars[] ALIGN1 = {
6445                 '=',
6446                 ':',
6447                 CTLQUOTEMARK,
6448                 CTLENDVAR,
6449                 CTLESC,
6450                 CTLVAR,
6451                 CTLBACKQ,
6452 #if ENABLE_FEATURE_SH_MATH
6453                 CTLENDARI,
6454 #endif
6455                 '\0'
6456         };
6457         const char *reject = spclchars;
6458         int breakall = (flags & (EXP_WORD | EXP_QUOTED)) == EXP_WORD;
6459         int inquotes;
6460         size_t length;
6461         int startloc;
6462
6463         if (!(flags & EXP_VARTILDE)) {
6464                 reject += 2;
6465         } else if (flags & EXP_VARTILDE2) {
6466                 reject++;
6467         }
6468         inquotes = 0;
6469         length = 0;
6470         if (flags & EXP_TILDE) {
6471                 char *q;
6472
6473                 flags &= ~EXP_TILDE;
6474  tilde:
6475                 q = p;
6476                 if (*q == '~')
6477                         p = exptilde(p, q, flags);
6478         }
6479  start:
6480         startloc = expdest - (char *)stackblock();
6481         for (;;) {
6482                 unsigned char c;
6483
6484                 length += strcspn(p + length, reject);
6485                 c = p[length];
6486                 if (c) {
6487                         if (!(c & 0x80)
6488                         IF_FEATURE_SH_MATH(|| c == CTLENDARI)
6489                         ) {
6490                                 /* c == '=' || c == ':' || c == CTLENDARI */
6491                                 length++;
6492                         }
6493                 }
6494                 if (length > 0) {
6495                         int newloc;
6496                         expdest = stack_nputstr(p, length, expdest);
6497                         newloc = expdest - (char *)stackblock();
6498                         if (breakall && !inquotes && newloc > startloc) {
6499                                 recordregion(startloc, newloc, 0);
6500                         }
6501                         startloc = newloc;
6502                 }
6503                 p += length + 1;
6504                 length = 0;
6505
6506                 switch (c) {
6507                 case '\0':
6508                         goto breakloop;
6509                 case '=':
6510                         if (flags & EXP_VARTILDE2) {
6511                                 p--;
6512                                 continue;
6513                         }
6514                         flags |= EXP_VARTILDE2;
6515                         reject++;
6516                         /* fall through */
6517                 case ':':
6518                         /*
6519                          * sort of a hack - expand tildes in variable
6520                          * assignments (after the first '=' and after ':'s).
6521                          */
6522                         if (*--p == '~') {
6523                                 goto tilde;
6524                         }
6525                         continue;
6526                 }
6527
6528                 switch (c) {
6529                 case CTLENDVAR: /* ??? */
6530                         goto breakloop;
6531                 case CTLQUOTEMARK:
6532                         inquotes ^= EXP_QUOTED;
6533                         /* "$@" syntax adherence hack */
6534                         if (inquotes && !memcmp(p, dolatstr + 1, DOLATSTRLEN - 1)) {
6535                                 p = evalvar(p + 1, flags | inquotes) + 1;
6536                                 goto start;
6537                         }
6538  addquote:
6539                         if (flags & QUOTES_ESC) {
6540                                 p--;
6541                                 length++;
6542                                 startloc++;
6543                         }
6544                         break;
6545                 case CTLESC:
6546                         startloc++;
6547                         length++;
6548
6549                         /*
6550                          * Quoted parameter expansion pattern: remove quote
6551                          * unless inside inner quotes or we have a literal
6552                          * backslash.
6553                          */
6554                         if (((flags | inquotes) & (EXP_QPAT | EXP_QUOTED)) ==
6555                             EXP_QPAT && *p != '\\')
6556                                 break;
6557
6558                         goto addquote;
6559                 case CTLVAR:
6560                         TRACE(("argstr: evalvar('%s')\n", p));
6561                         p = evalvar(p, flags | inquotes);
6562                         TRACE(("argstr: evalvar:'%s'\n", (char *)stackblock()));
6563                         goto start;
6564                 case CTLBACKQ:
6565                         expbackq(argbackq->n, flags | inquotes);
6566                         argbackq = argbackq->next;
6567                         goto start;
6568 #if ENABLE_FEATURE_SH_MATH
6569                 case CTLENDARI:
6570                         p--;
6571                         expari(flags | inquotes);
6572                         goto start;
6573 #endif
6574                 }
6575         }
6576  breakloop: ;
6577 }
6578
6579 static char *
6580 scanleft(char *startp, char *rmesc, char *rmescend UNUSED_PARAM,
6581                 char *pattern, int quotes, int zero)
6582 {
6583         char *loc, *loc2;
6584         char c;
6585
6586         loc = startp;
6587         loc2 = rmesc;
6588         do {
6589                 int match;
6590                 const char *s = loc2;
6591
6592                 c = *loc2;
6593                 if (zero) {
6594                         *loc2 = '\0';
6595                         s = rmesc;
6596                 }
6597                 match = pmatch(pattern, s);
6598
6599                 *loc2 = c;
6600                 if (match)
6601                         return loc;
6602                 if (quotes && (unsigned char)*loc == CTLESC)
6603                         loc++;
6604                 loc++;
6605                 loc2++;
6606         } while (c);
6607         return NULL;
6608 }
6609
6610 static char *
6611 scanright(char *startp, char *rmesc, char *rmescend,
6612                 char *pattern, int quotes, int match_at_start)
6613 {
6614 #if !ENABLE_ASH_OPTIMIZE_FOR_SIZE
6615         int try2optimize = match_at_start;
6616 #endif
6617         int esc = 0;
6618         char *loc;
6619         char *loc2;
6620
6621         /* If we called by "${v/pattern/repl}" or "${v//pattern/repl}":
6622          * startp="escaped_value_of_v" rmesc="raw_value_of_v"
6623          * rmescend=""(ptr to NUL in rmesc) pattern="pattern" quotes=match_at_start=1
6624          * Logic:
6625          * loc starts at NUL at the end of startp, loc2 starts at the end of rmesc,
6626          * and on each iteration they go back two/one char until they reach the beginning.
6627          * We try to find a match in "raw_value_of_v", "raw_value_of_", "raw_value_of" etc.
6628          */
6629         /* TODO: document in what other circumstances we are called. */
6630
6631         for (loc = pattern - 1, loc2 = rmescend; loc >= startp; loc2--) {
6632                 int match;
6633                 char c = *loc2;
6634                 const char *s = loc2;
6635                 if (match_at_start) {
6636                         *loc2 = '\0';
6637                         s = rmesc;
6638                 }
6639                 match = pmatch(pattern, s);
6640                 //bb_error_msg("pmatch(pattern:'%s',s:'%s'):%d", pattern, s, match);
6641                 *loc2 = c;
6642                 if (match)
6643                         return loc;
6644 #if !ENABLE_ASH_OPTIMIZE_FOR_SIZE
6645                 if (try2optimize) {
6646                         /* Maybe we can optimize this:
6647                          * if pattern ends with unescaped *, we can avoid checking
6648                          * shorter strings: if "foo*" doesn't match "raw_value_of_v",
6649                          * it won't match truncated "raw_value_of_" strings too.
6650                          */
6651                         unsigned plen = strlen(pattern);
6652                         /* Does it end with "*"? */
6653                         if (plen != 0 && pattern[--plen] == '*') {
6654                                 /* "xxxx*" is not escaped */
6655                                 /* "xxx\*" is escaped */
6656                                 /* "xx\\*" is not escaped */
6657                                 /* "x\\\*" is escaped */
6658                                 int slashes = 0;
6659                                 while (plen != 0 && pattern[--plen] == '\\')
6660                                         slashes++;
6661                                 if (!(slashes & 1))
6662                                         break; /* ends with unescaped "*" */
6663                         }
6664                         try2optimize = 0;
6665                 }
6666 #endif
6667                 loc--;
6668                 if (quotes) {
6669                         if (--esc < 0) {
6670                                 esc = esclen(startp, loc);
6671                         }
6672                         if (esc % 2) {
6673                                 esc--;
6674                                 loc--;
6675                         }
6676                 }
6677         }
6678         return NULL;
6679 }
6680
6681 static void varunset(const char *, const char *, const char *, int) NORETURN;
6682 static void
6683 varunset(const char *end, const char *var, const char *umsg, int varflags)
6684 {
6685         const char *msg;
6686         const char *tail;
6687
6688         tail = nullstr;
6689         msg = "parameter not set";
6690         if (umsg) {
6691                 if ((unsigned char)*end == CTLENDVAR) {
6692                         if (varflags & VSNUL)
6693                                 tail = " or null";
6694                 } else {
6695                         msg = umsg;
6696                 }
6697         }
6698         ash_msg_and_raise_error("%.*s: %s%s", (int)(end - var - 1), var, msg, tail);
6699 }
6700
6701 static const char *
6702 subevalvar(char *p, char *varname, int strloc, int subtype,
6703                 int startloc, int varflags, int flag)
6704 {
6705         struct nodelist *saveargbackq = argbackq;
6706         int quotes = flag & QUOTES_ESC;
6707         char *startp;
6708         char *loc;
6709         char *rmesc, *rmescend;
6710         char *str;
6711         int amount, resetloc;
6712         IF_BASH_PATTERN_SUBST(int workloc;)
6713         IF_BASH_PATTERN_SUBST(char *repl = NULL;)
6714         int zero;
6715         char *(*scan)(char*, char*, char*, char*, int, int);
6716
6717         //bb_error_msg("subevalvar(p:'%s',varname:'%s',strloc:%d,subtype:%d,startloc:%d,varflags:%x,quotes:%d)",
6718         //              p, varname, strloc, subtype, startloc, varflags, quotes);
6719
6720         argstr(p, EXP_TILDE | (subtype != VSASSIGN && subtype != VSQUESTION ?
6721                         (flag & (EXP_QUOTED | EXP_QPAT) ? EXP_QPAT : EXP_CASE) : 0)
6722         );
6723         STPUTC('\0', expdest);
6724         argbackq = saveargbackq;
6725         startp = (char *)stackblock() + startloc;
6726
6727         switch (subtype) {
6728         case VSASSIGN:
6729                 setvar0(varname, startp);
6730                 amount = startp - expdest;
6731                 STADJUST(amount, expdest);
6732                 return startp;
6733
6734         case VSQUESTION:
6735                 varunset(p, varname, startp, varflags);
6736                 /* NOTREACHED */
6737
6738 #if BASH_SUBSTR
6739         case VSSUBSTR: {
6740                 int pos, len, orig_len;
6741                 char *colon;
6742
6743                 loc = str = stackblock() + strloc;
6744
6745 # if !ENABLE_FEATURE_SH_MATH
6746 #  define ash_arith number
6747 # endif
6748                 /* Read POS in ${var:POS:LEN} */
6749                 colon = strchr(loc, ':');
6750                 if (colon) *colon = '\0';
6751                 pos = ash_arith(loc);
6752                 if (colon) *colon = ':';
6753
6754                 /* Read LEN in ${var:POS:LEN} */
6755                 len = str - startp - 1;
6756                 /* *loc != '\0', guaranteed by parser */
6757                 if (quotes) {
6758                         char *ptr;
6759
6760                         /* Adjust the length by the number of escapes */
6761                         for (ptr = startp; ptr < (str - 1); ptr++) {
6762                                 if ((unsigned char)*ptr == CTLESC) {
6763                                         len--;
6764                                         ptr++;
6765                                 }
6766                         }
6767                 }
6768                 orig_len = len;
6769                 if (*loc++ == ':') {
6770                         /* ${var::LEN} */
6771                         len = ash_arith(loc);
6772                 } else {
6773                         /* Skip POS in ${var:POS:LEN} */
6774                         len = orig_len;
6775                         while (*loc && *loc != ':') {
6776                                 loc++;
6777                         }
6778                         if (*loc++ == ':') {
6779                                 len = ash_arith(loc);
6780                         }
6781                 }
6782 #  undef ash_arith
6783
6784                 if (pos < 0) {
6785                         /* ${VAR:$((-n)):l} starts n chars from the end */
6786                         pos = orig_len + pos;
6787                 }
6788                 if ((unsigned)pos >= orig_len) {
6789                         /* apart from obvious ${VAR:999999:l},
6790                          * covers ${VAR:$((-9999999)):l} - result is ""
6791                          * (bash compat)
6792                          */
6793                         pos = 0;
6794                         len = 0;
6795                 }
6796                 if (len < 0) {
6797                         /* ${VAR:N:-M} sets LEN to strlen()-M */
6798                         len = (orig_len - pos) + len;
6799                 }
6800                 if ((unsigned)len > (orig_len - pos))
6801                         len = orig_len - pos;
6802
6803                 for (str = startp; pos; str++, pos--) {
6804                         if (quotes && (unsigned char)*str == CTLESC)
6805                                 str++;
6806                 }
6807                 for (loc = startp; len; len--) {
6808                         if (quotes && (unsigned char)*str == CTLESC)
6809                                 *loc++ = *str++;
6810                         *loc++ = *str++;
6811                 }
6812                 *loc = '\0';
6813                 amount = loc - expdest;
6814                 STADJUST(amount, expdest);
6815                 return loc;
6816         }
6817 #endif /* BASH_SUBSTR */
6818         }
6819
6820         resetloc = expdest - (char *)stackblock();
6821
6822 #if BASH_PATTERN_SUBST
6823         /* We'll comeback here if we grow the stack while handling
6824          * a VSREPLACE or VSREPLACEALL, since our pointers into the
6825          * stack will need rebasing, and we'll need to remove our work
6826          * areas each time
6827          */
6828  restart:
6829 #endif
6830
6831         amount = expdest - ((char *)stackblock() + resetloc);
6832         STADJUST(-amount, expdest);
6833         startp = (char *)stackblock() + startloc;
6834
6835         rmesc = startp;
6836         rmescend = (char *)stackblock() + strloc;
6837         if (quotes) {
6838                 rmesc = rmescapes(startp, RMESCAPE_ALLOC | RMESCAPE_GROW);
6839                 if (rmesc != startp) {
6840                         rmescend = expdest;
6841                         startp = (char *)stackblock() + startloc;
6842                 }
6843         }
6844         rmescend--;
6845         str = (char *)stackblock() + strloc;
6846         /*
6847          * Example: v='a\bc'; echo ${v/\\b/_\\_\z_}
6848          * The result is a_\_z_c (not a\_\_z_c)!
6849          *
6850          * The search pattern and replace string treat backslashes differently!
6851          * RMESCAPE_SLASH causes preglob to work differently on the pattern
6852          * and string.  It's only used on the first call.
6853          */
6854         preglob(str, IF_BASH_PATTERN_SUBST(
6855                 (subtype == VSREPLACE || subtype == VSREPLACEALL) && !repl ?
6856                         RMESCAPE_SLASH : ) 0);
6857
6858 #if BASH_PATTERN_SUBST
6859         workloc = expdest - (char *)stackblock();
6860         if (subtype == VSREPLACE || subtype == VSREPLACEALL) {
6861                 int len;
6862                 char *idx, *end;
6863
6864                 if (!repl) {
6865                         repl = strchr(str, CTLESC);
6866                         if (repl)
6867                                 *repl++ = '\0';
6868                         else
6869                                 repl = nullstr;
6870                 }
6871                 //bb_error_msg("str:'%s' repl:'%s'", str, repl);
6872
6873                 /* If there's no pattern to match, return the expansion unmolested */
6874                 if (str[0] == '\0')
6875                         return NULL;
6876
6877                 len = 0;
6878                 idx = startp;
6879                 end = str - 1;
6880                 while (idx < end) {
6881  try_to_match:
6882                         loc = scanright(idx, rmesc, rmescend, str, quotes, 1);
6883                         //bb_error_msg("scanright('%s'):'%s'", str, loc);
6884                         if (!loc) {
6885                                 /* No match, advance */
6886                                 char *restart_detect = stackblock();
6887  skip_matching:
6888                                 STPUTC(*idx, expdest);
6889                                 if (quotes && (unsigned char)*idx == CTLESC) {
6890                                         idx++;
6891                                         len++;
6892                                         STPUTC(*idx, expdest);
6893                                 }
6894                                 if (stackblock() != restart_detect)
6895                                         goto restart;
6896                                 idx++;
6897                                 len++;
6898                                 rmesc++;
6899                                 /* continue; - prone to quadratic behavior, smarter code: */
6900                                 if (idx >= end)
6901                                         break;
6902                                 if (str[0] == '*') {
6903                                         /* Pattern is "*foo". If "*foo" does not match "long_string",
6904                                          * it would never match "ong_string" etc, no point in trying.
6905                                          */
6906                                         goto skip_matching;
6907                                 }
6908                                 goto try_to_match;
6909                         }
6910
6911                         if (subtype == VSREPLACEALL) {
6912                                 while (idx < loc) {
6913                                         if (quotes && (unsigned char)*idx == CTLESC)
6914                                                 idx++;
6915                                         idx++;
6916                                         rmesc++;
6917                                 }
6918                         } else {
6919                                 idx = loc;
6920                         }
6921
6922                         //bb_error_msg("repl:'%s'", repl);
6923                         for (loc = (char*)repl; *loc; loc++) {
6924                                 char *restart_detect = stackblock();
6925                                 if (quotes && *loc == '\\') {
6926                                         STPUTC(CTLESC, expdest);
6927                                         len++;
6928                                 }
6929                                 STPUTC(*loc, expdest);
6930                                 if (stackblock() != restart_detect)
6931                                         goto restart;
6932                                 len++;
6933                         }
6934
6935                         if (subtype == VSREPLACE) {
6936                                 //bb_error_msg("tail:'%s', quotes:%x", idx, quotes);
6937                                 while (*idx) {
6938                                         char *restart_detect = stackblock();
6939                                         STPUTC(*idx, expdest);
6940                                         if (stackblock() != restart_detect)
6941                                                 goto restart;
6942                                         len++;
6943                                         idx++;
6944                                 }
6945                                 break;
6946                         }
6947                 }
6948
6949                 /* We've put the replaced text into a buffer at workloc, now
6950                  * move it to the right place and adjust the stack.
6951                  */
6952                 STPUTC('\0', expdest);
6953                 startp = (char *)stackblock() + startloc;
6954                 memmove(startp, (char *)stackblock() + workloc, len + 1);
6955                 //bb_error_msg("startp:'%s'", startp);
6956                 amount = expdest - (startp + len);
6957                 STADJUST(-amount, expdest);
6958                 return startp;
6959         }
6960 #endif /* BASH_PATTERN_SUBST */
6961
6962         subtype -= VSTRIMRIGHT;
6963 #if DEBUG
6964         if (subtype < 0 || subtype > 7)
6965                 abort();
6966 #endif
6967         /* zero = (subtype == VSTRIMLEFT || subtype == VSTRIMLEFTMAX) */
6968         zero = subtype >> 1;
6969         /* VSTRIMLEFT/VSTRIMRIGHTMAX -> scanleft */
6970         scan = (subtype & 1) ^ zero ? scanleft : scanright;
6971
6972         loc = scan(startp, rmesc, rmescend, str, quotes, zero);
6973         if (loc) {
6974                 if (zero) {
6975                         memmove(startp, loc, str - loc);
6976                         loc = startp + (str - loc) - 1;
6977                 }
6978                 *loc = '\0';
6979                 amount = loc - expdest;
6980                 STADJUST(amount, expdest);
6981         }
6982         return loc;
6983 }
6984
6985 /*
6986  * Add the value of a specialized variable to the stack string.
6987  * name parameter (examples):
6988  * ash -c 'echo $1'      name:'1='
6989  * ash -c 'echo $qwe'    name:'qwe='
6990  * ash -c 'echo $$'      name:'$='
6991  * ash -c 'echo ${$}'    name:'$='
6992  * ash -c 'echo ${$##q}' name:'$=q'
6993  * ash -c 'echo ${#$}'   name:'$='
6994  * note: examples with bad shell syntax:
6995  * ash -c 'echo ${#$1}'  name:'$=1'
6996  * ash -c 'echo ${#1#}'  name:'1=#'
6997  */
6998 static NOINLINE ssize_t
6999 varvalue(char *name, int varflags, int flags, int *quotedp)
7000 {
7001         const char *p;
7002         int num;
7003         int i;
7004         ssize_t len = 0;
7005         int sep;
7006         int quoted = *quotedp;
7007         int subtype = varflags & VSTYPE;
7008         int discard = subtype == VSPLUS || subtype == VSLENGTH;
7009         int quotes = (discard ? 0 : (flags & QUOTES_ESC)) | QUOTES_KEEPNUL;
7010         int syntax;
7011
7012         sep = (flags & EXP_FULL) << CHAR_BIT;
7013         syntax = quoted ? DQSYNTAX : BASESYNTAX;
7014
7015         switch (*name) {
7016         case '$':
7017                 num = rootpid;
7018                 goto numvar;
7019         case '?':
7020                 num = exitstatus;
7021                 goto numvar;
7022         case '#':
7023                 num = shellparam.nparam;
7024                 goto numvar;
7025         case '!':
7026                 num = backgndpid;
7027                 if (num == 0)
7028                         return -1;
7029  numvar:
7030                 len = cvtnum(num);
7031                 goto check_1char_name;
7032         case '-':
7033                 expdest = makestrspace(NOPTS, expdest);
7034                 for (i = NOPTS - 1; i >= 0; i--) {
7035                         if (optlist[i]) {
7036                                 USTPUTC(optletters(i), expdest);
7037                                 len++;
7038                         }
7039                 }
7040  check_1char_name:
7041 #if 0
7042                 /* handles cases similar to ${#$1} */
7043                 if (name[2] != '\0')
7044                         raise_error_syntax("bad substitution");
7045 #endif
7046                 break;
7047         case '@':
7048                 if (quoted && sep)
7049                         goto param;
7050                 /* fall through */
7051         case '*': {
7052                 char **ap;
7053                 char sepc;
7054
7055                 if (quoted)
7056                         sep = 0;
7057                 sep |= ifsset() ? ifsval()[0] : ' ';
7058  param:
7059                 sepc = sep;
7060                 *quotedp = !sepc;
7061                 ap = shellparam.p;
7062                 if (!ap)
7063                         return -1;
7064                 while ((p = *ap++) != NULL) {
7065                         len += strtodest(p, syntax, quotes);
7066
7067                         if (*ap && sep) {
7068                                 len++;
7069                                 memtodest(&sepc, 1, syntax, quotes);
7070                         }
7071                 }
7072                 break;
7073         } /* case '*' */
7074         case '0':
7075         case '1':
7076         case '2':
7077         case '3':
7078         case '4':
7079         case '5':
7080         case '6':
7081         case '7':
7082         case '8':
7083         case '9':
7084                 num = atoi(name); /* number(name) fails on ${N#str} etc */
7085                 if (num < 0 || num > shellparam.nparam)
7086                         return -1;
7087                 p = num ? shellparam.p[num - 1] : arg0;
7088                 goto value;
7089         default:
7090                 /* NB: name has form "VAR=..." */
7091                 p = lookupvar(name);
7092  value:
7093                 if (!p)
7094                         return -1;
7095
7096                 len = strtodest(p, syntax, quotes);
7097 #if ENABLE_UNICODE_SUPPORT
7098                 if (subtype == VSLENGTH && len > 0) {
7099                         reinit_unicode_for_ash();
7100                         if (unicode_status == UNICODE_ON) {
7101                                 STADJUST(-len, expdest);
7102                                 discard = 0;
7103                                 len = unicode_strlen(p);
7104                         }
7105                 }
7106 #endif
7107                 break;
7108         }
7109
7110         if (discard)
7111                 STADJUST(-len, expdest);
7112         return len;
7113 }
7114
7115 /*
7116  * Expand a variable, and return a pointer to the next character in the
7117  * input string.
7118  */
7119 static char *
7120 evalvar(char *p, int flag)
7121 {
7122         char varflags;
7123         char subtype;
7124         int quoted;
7125         char easy;
7126         char *var;
7127         int patloc;
7128         int startloc;
7129         ssize_t varlen;
7130
7131         varflags = (unsigned char) *p++;
7132         subtype = varflags & VSTYPE;
7133
7134         if (!subtype)
7135                 raise_error_syntax("bad substitution");
7136
7137         quoted = flag & EXP_QUOTED;
7138         var = p;
7139         easy = (!quoted || (*var == '@' && shellparam.nparam));
7140         startloc = expdest - (char *)stackblock();
7141         p = strchr(p, '=') + 1; //TODO: use var_end(p)?
7142
7143  again:
7144         varlen = varvalue(var, varflags, flag, &quoted);
7145         if (varflags & VSNUL)
7146                 varlen--;
7147
7148         if (subtype == VSPLUS) {
7149                 varlen = -1 - varlen;
7150                 goto vsplus;
7151         }
7152
7153         if (subtype == VSMINUS) {
7154  vsplus:
7155                 if (varlen < 0) {
7156                         argstr(
7157                                 p,
7158                                 flag | EXP_TILDE | EXP_WORD
7159                         );
7160                         goto end;
7161                 }
7162                 goto record;
7163         }
7164
7165         if (subtype == VSASSIGN || subtype == VSQUESTION) {
7166                 if (varlen >= 0)
7167                         goto record;
7168
7169                 subevalvar(p, var, 0, subtype, startloc, varflags,
7170                            flag & ~QUOTES_ESC);
7171                 varflags &= ~VSNUL;
7172                 /*
7173                  * Remove any recorded regions beyond
7174                  * start of variable
7175                  */
7176                 removerecordregions(startloc);
7177                 goto again;
7178         }
7179
7180         if (varlen < 0 && uflag)
7181                 varunset(p, var, 0, 0);
7182
7183         if (subtype == VSLENGTH) {
7184                 cvtnum(varlen > 0 ? varlen : 0);
7185                 goto record;
7186         }
7187
7188         if (subtype == VSNORMAL) {
7189  record:
7190                 if (!easy)
7191                         goto end;
7192                 recordregion(startloc, expdest - (char *)stackblock(), quoted);
7193                 goto end;
7194         }
7195
7196 #if DEBUG
7197         switch (subtype) {
7198         case VSTRIMLEFT:
7199         case VSTRIMLEFTMAX:
7200         case VSTRIMRIGHT:
7201         case VSTRIMRIGHTMAX:
7202 #if BASH_SUBSTR
7203         case VSSUBSTR:
7204 #endif
7205 #if BASH_PATTERN_SUBST
7206         case VSREPLACE:
7207         case VSREPLACEALL:
7208 #endif
7209                 break;
7210         default:
7211                 abort();
7212         }
7213 #endif
7214
7215         if (varlen >= 0) {
7216                 /*
7217                  * Terminate the string and start recording the pattern
7218                  * right after it
7219                  */
7220                 STPUTC('\0', expdest);
7221                 patloc = expdest - (char *)stackblock();
7222                 if (NULL == subevalvar(p, /* varname: */ NULL, patloc, subtype,
7223                                 startloc, varflags, flag)) {
7224                         int amount = expdest - (
7225                                 (char *)stackblock() + patloc - 1
7226                         );
7227                         STADJUST(-amount, expdest);
7228                 }
7229                 /* Remove any recorded regions beyond start of variable */
7230                 removerecordregions(startloc);
7231                 goto record;
7232         }
7233
7234  end:
7235         if (subtype != VSNORMAL) {      /* skip to end of alternative */
7236                 int nesting = 1;
7237                 for (;;) {
7238                         unsigned char c = *p++;
7239                         if (c == CTLESC)
7240                                 p++;
7241                         else if (c == CTLBACKQ) {
7242                                 if (varlen >= 0)
7243                                         argbackq = argbackq->next;
7244                         } else if (c == CTLVAR) {
7245                                 if ((*p++ & VSTYPE) != VSNORMAL)
7246                                         nesting++;
7247                         } else if (c == CTLENDVAR) {
7248                                 if (--nesting == 0)
7249                                         break;
7250                         }
7251                 }
7252         }
7253         return p;
7254 }
7255
7256 /*
7257  * Add a file name to the list.
7258  */
7259 static void
7260 addfname(const char *name)
7261 {
7262         struct strlist *sp;
7263
7264         sp = stzalloc(sizeof(*sp));
7265         sp->text = sstrdup(name);
7266         *exparg.lastp = sp;
7267         exparg.lastp = &sp->next;
7268 }
7269
7270 /* Avoid glob() (and thus, stat() et al) for words like "echo" */
7271 static int
7272 hasmeta(const char *p)
7273 {
7274         static const char chars[] ALIGN1 = {
7275                 '*', '?', '[', '\\', CTLQUOTEMARK, CTLESC, 0
7276         };
7277
7278         for (;;) {
7279                 p = strpbrk(p, chars);
7280                 if (!p)
7281                         break;
7282                 switch ((unsigned char) *p) {
7283                 case CTLQUOTEMARK:
7284                         for (;;) {
7285                                 p++;
7286                                 if (*p == CTLQUOTEMARK)
7287                                         break;
7288                                 if (*p == CTLESC)
7289                                         p++;
7290                                 if (*p == '\0') /* huh? */
7291                                         return 0;
7292                         }
7293                         break;
7294                 case '\\':
7295                 case CTLESC:
7296                         p++;
7297                         if (*p == '\0')
7298                                 return 0;
7299                         break;
7300                 case '[':
7301                         if (!strchr(p + 1, ']')) {
7302                                 /* It's not a properly closed [] pattern,
7303                                  * but other metas may follow. Continue checking.
7304                                  * my[file* _is_ globbed by bash
7305                                  * and matches filenames like "my[file1".
7306                                  */
7307                                 break;
7308                         }
7309                         /* fallthrough */
7310                 default:
7311                 /* case '*': */
7312                 /* case '?': */
7313                         return 1;
7314                 }
7315                 p++;
7316         }
7317
7318         return 0;
7319 }
7320
7321 /* If we want to use glob() from libc... */
7322 #if !ENABLE_ASH_INTERNAL_GLOB
7323
7324 /* Add the result of glob() to the list */
7325 static void
7326 addglob(const glob_t *pglob)
7327 {
7328         char **p = pglob->gl_pathv;
7329
7330         do {
7331                 addfname(*p);
7332         } while (*++p);
7333 }
7334 static void
7335 expandmeta(struct strlist *str /*, int flag*/)
7336 {
7337         /* TODO - EXP_REDIR */
7338
7339         while (str) {
7340                 char *p;
7341                 glob_t pglob;
7342                 int i;
7343
7344                 if (fflag)
7345                         goto nometa;
7346
7347                 if (!hasmeta(str->text))
7348                         goto nometa;
7349
7350                 INT_OFF;
7351                 p = preglob(str->text, RMESCAPE_ALLOC | RMESCAPE_HEAP);
7352 // GLOB_NOMAGIC (GNU): if no *?[ chars in pattern, return it even if no match
7353 // GLOB_NOCHECK: if no match, return unchanged pattern (sans \* escapes?)
7354 //
7355 // glibc 2.24.90 glob(GLOB_NOMAGIC) does not remove backslashes used for escaping:
7356 // if you pass it "file\?", it returns "file\?", not "file?", if no match.
7357 // Which means you need to unescape the string, right? Not so fast:
7358 // if there _is_ a file named "file\?" (with backslash), it is returned
7359 // as "file\?" too (whichever pattern you used to find it, say, "file*").
7360 // You DON'T KNOW by looking at the result whether you need to unescape it.
7361 //
7362 // Worse, globbing of "file\?" in a directory with two files, "file?" and "file\?",
7363 // returns "file\?" - which is WRONG: "file\?" pattern matches "file?" file.
7364 // Without GLOB_NOMAGIC, this works correctly ("file?" is returned as a match).
7365 // With GLOB_NOMAGIC | GLOB_NOCHECK, this also works correctly.
7366 //              i = glob(p, GLOB_NOMAGIC | GLOB_NOCHECK, NULL, &pglob);
7367 //              i = glob(p, GLOB_NOMAGIC, NULL, &pglob);
7368                 i = glob(p, 0, NULL, &pglob);
7369                 //bb_error_msg("glob('%s'):%d '%s'...", p, i, pglob.gl_pathv ? pglob.gl_pathv[0] : "-");
7370                 if (p != str->text)
7371                         free(p);
7372                 switch (i) {
7373                 case 0:
7374 #if 0 // glibc 2.24.90 bug? Patterns like "*/file", when match, don't set GLOB_MAGCHAR
7375                         /* GLOB_MAGCHAR is set if *?[ chars were seen (GNU) */
7376                         if (!(pglob.gl_flags & GLOB_MAGCHAR))
7377                                 goto nometa2;
7378 #endif
7379                         addglob(&pglob);
7380                         globfree(&pglob);
7381                         INT_ON;
7382                         break;
7383                 case GLOB_NOMATCH:
7384  //nometa2:
7385                         globfree(&pglob);
7386                         INT_ON;
7387  nometa:
7388                         *exparg.lastp = str;
7389                         rmescapes(str->text, 0);
7390                         exparg.lastp = &str->next;
7391                         break;
7392                 default:        /* GLOB_NOSPACE */
7393                         globfree(&pglob);
7394                         INT_ON;
7395                         ash_msg_and_raise_error(bb_msg_memory_exhausted);
7396                 }
7397                 str = str->next;
7398         }
7399 }
7400
7401 #else
7402 /* ENABLE_ASH_INTERNAL_GLOB: Homegrown globbing code. (dash also has both, uses homegrown one.) */
7403
7404 /*
7405  * Do metacharacter (i.e. *, ?, [...]) expansion.
7406  */
7407 static void
7408 expmeta(char *expdir, char *enddir, char *name)
7409 {
7410         char *p;
7411         const char *cp;
7412         char *start;
7413         char *endname;
7414         int metaflag;
7415         struct stat statb;
7416         DIR *dirp;
7417         struct dirent *dp;
7418         int atend;
7419         int matchdot;
7420         int esc;
7421
7422         metaflag = 0;
7423         start = name;
7424         for (p = name; esc = 0, *p; p += esc + 1) {
7425                 if (*p == '*' || *p == '?')
7426                         metaflag = 1;
7427                 else if (*p == '[') {
7428                         char *q = p + 1;
7429                         if (*q == '!')
7430                                 q++;
7431                         for (;;) {
7432                                 if (*q == '\\')
7433                                         q++;
7434                                 if (*q == '/' || *q == '\0')
7435                                         break;
7436                                 if (*++q == ']') {
7437                                         metaflag = 1;
7438                                         break;
7439                                 }
7440                         }
7441                 } else {
7442                         if (*p == '\\')
7443                                 esc++;
7444                         if (p[esc] == '/') {
7445                                 if (metaflag)
7446                                         break;
7447                                 start = p + esc + 1;
7448                         }
7449                 }
7450         }
7451         if (metaflag == 0) {    /* we've reached the end of the file name */
7452                 if (enddir != expdir)
7453                         metaflag++;
7454                 p = name;
7455                 do {
7456                         if (*p == '\\')
7457                                 p++;
7458                         *enddir++ = *p;
7459                 } while (*p++);
7460                 if (metaflag == 0 || lstat(expdir, &statb) >= 0)
7461                         addfname(expdir);
7462                 return;
7463         }
7464         endname = p;
7465         if (name < start) {
7466                 p = name;
7467                 do {
7468                         if (*p == '\\')
7469                                 p++;
7470                         *enddir++ = *p++;
7471                 } while (p < start);
7472         }
7473         if (enddir == expdir) {
7474                 cp = ".";
7475         } else if (enddir == expdir + 1 && *expdir == '/') {
7476                 cp = "/";
7477         } else {
7478                 cp = expdir;
7479                 enddir[-1] = '\0';
7480         }
7481         dirp = opendir(cp);
7482         if (dirp == NULL)
7483                 return;
7484         if (enddir != expdir)
7485                 enddir[-1] = '/';
7486         if (*endname == 0) {
7487                 atend = 1;
7488         } else {
7489                 atend = 0;
7490                 *endname = '\0';
7491                 endname += esc + 1;
7492         }
7493         matchdot = 0;
7494         p = start;
7495         if (*p == '\\')
7496                 p++;
7497         if (*p == '.')
7498                 matchdot++;
7499         while (!pending_int && (dp = readdir(dirp)) != NULL) {
7500                 if (dp->d_name[0] == '.' && !matchdot)
7501                         continue;
7502                 if (pmatch(start, dp->d_name)) {
7503                         if (atend) {
7504                                 strcpy(enddir, dp->d_name);
7505                                 addfname(expdir);
7506                         } else {
7507                                 for (p = enddir, cp = dp->d_name; (*p++ = *cp++) != '\0';)
7508                                         continue;
7509                                 p[-1] = '/';
7510                                 expmeta(expdir, p, endname);
7511                         }
7512                 }
7513         }
7514         closedir(dirp);
7515         if (!atend)
7516                 endname[-esc - 1] = esc ? '\\' : '/';
7517 }
7518
7519 static struct strlist *
7520 msort(struct strlist *list, int len)
7521 {
7522         struct strlist *p, *q = NULL;
7523         struct strlist **lpp;
7524         int half;
7525         int n;
7526
7527         if (len <= 1)
7528                 return list;
7529         half = len >> 1;
7530         p = list;
7531         for (n = half; --n >= 0;) {
7532                 q = p;
7533                 p = p->next;
7534         }
7535         q->next = NULL;                 /* terminate first half of list */
7536         q = msort(list, half);          /* sort first half of list */
7537         p = msort(p, len - half);               /* sort second half */
7538         lpp = &list;
7539         for (;;) {
7540 #if ENABLE_LOCALE_SUPPORT
7541                 if (strcoll(p->text, q->text) < 0)
7542 #else
7543                 if (strcmp(p->text, q->text) < 0)
7544 #endif
7545                                                 {
7546                         *lpp = p;
7547                         lpp = &p->next;
7548                         p = *lpp;
7549                         if (p == NULL) {
7550                                 *lpp = q;
7551                                 break;
7552                         }
7553                 } else {
7554                         *lpp = q;
7555                         lpp = &q->next;
7556                         q = *lpp;
7557                         if (q == NULL) {
7558                                 *lpp = p;
7559                                 break;
7560                         }
7561                 }
7562         }
7563         return list;
7564 }
7565
7566 /*
7567  * Sort the results of file name expansion.  It calculates the number of
7568  * strings to sort and then calls msort (short for merge sort) to do the
7569  * work.
7570  */
7571 static struct strlist *
7572 expsort(struct strlist *str)
7573 {
7574         int len;
7575         struct strlist *sp;
7576
7577         len = 0;
7578         for (sp = str; sp; sp = sp->next)
7579                 len++;
7580         return msort(str, len);
7581 }
7582
7583 static void
7584 expandmeta(struct strlist *str /*, int flag*/)
7585 {
7586         /* TODO - EXP_REDIR */
7587
7588         while (str) {
7589                 char *expdir;
7590                 struct strlist **savelastp;
7591                 struct strlist *sp;
7592                 char *p;
7593
7594                 if (fflag)
7595                         goto nometa;
7596                 if (!hasmeta(str->text))
7597                         goto nometa;
7598                 savelastp = exparg.lastp;
7599
7600                 INT_OFF;
7601                 p = preglob(str->text, RMESCAPE_ALLOC | RMESCAPE_HEAP);
7602                 {
7603                         int i = strlen(str->text);
7604 //BUGGY estimation of how long expanded name can be
7605                         expdir = ckmalloc(i < 2048 ? 2048 : i+1);
7606                 }
7607                 expmeta(expdir, expdir, p);
7608                 free(expdir);
7609                 if (p != str->text)
7610                         free(p);
7611                 INT_ON;
7612                 if (exparg.lastp == savelastp) {
7613                         /*
7614                          * no matches
7615                          */
7616  nometa:
7617                         *exparg.lastp = str;
7618                         rmescapes(str->text, 0);
7619                         exparg.lastp = &str->next;
7620                 } else {
7621                         *exparg.lastp = NULL;
7622                         *savelastp = sp = expsort(*savelastp);
7623                         while (sp->next != NULL)
7624                                 sp = sp->next;
7625                         exparg.lastp = &sp->next;
7626                 }
7627                 str = str->next;
7628         }
7629 }
7630 #endif /* ENABLE_ASH_INTERNAL_GLOB */
7631
7632 /*
7633  * Perform variable substitution and command substitution on an argument,
7634  * placing the resulting list of arguments in arglist.  If EXP_FULL is true,
7635  * perform splitting and file name expansion.  When arglist is NULL, perform
7636  * here document expansion.
7637  */
7638 static void
7639 expandarg(union node *arg, struct arglist *arglist, int flag)
7640 {
7641         struct strlist *sp;
7642         char *p;
7643
7644         argbackq = arg->narg.backquote;
7645         STARTSTACKSTR(expdest);
7646         TRACE(("expandarg: argstr('%s',flags:%x)\n", arg->narg.text, flag));
7647         argstr(arg->narg.text, flag);
7648         p = _STPUTC('\0', expdest);
7649         expdest = p - 1;
7650         if (arglist == NULL) {
7651                 /* here document expanded */
7652                 goto out;
7653         }
7654         p = grabstackstr(p);
7655         TRACE(("expandarg: p:'%s'\n", p));
7656         exparg.lastp = &exparg.list;
7657         /*
7658          * TODO - EXP_REDIR
7659          */
7660         if (flag & EXP_FULL) {
7661                 ifsbreakup(p, &exparg);
7662                 *exparg.lastp = NULL;
7663                 exparg.lastp = &exparg.list;
7664                 expandmeta(exparg.list /*, flag*/);
7665         } else {
7666                 sp = stzalloc(sizeof(*sp));
7667                 sp->text = p;
7668                 *exparg.lastp = sp;
7669                 exparg.lastp = &sp->next;
7670         }
7671         *exparg.lastp = NULL;
7672         if (exparg.list) {
7673                 *arglist->lastp = exparg.list;
7674                 arglist->lastp = exparg.lastp;
7675         }
7676
7677  out:
7678         ifsfree();
7679 }
7680
7681 /*
7682  * Expand shell variables and backquotes inside a here document.
7683  */
7684 static void
7685 expandhere(union node *arg, int fd)
7686 {
7687         expandarg(arg, (struct arglist *)NULL, EXP_QUOTED);
7688         full_write(fd, stackblock(), expdest - (char *)stackblock());
7689 }
7690
7691 /*
7692  * Returns true if the pattern matches the string.
7693  */
7694 static int
7695 patmatch(char *pattern, const char *string)
7696 {
7697         char *p = preglob(pattern, 0);
7698         //bb_error_msg("fnmatch(pattern:'%s',str:'%s')", p, string);
7699         return pmatch(p, string);
7700 }
7701
7702 /*
7703  * See if a pattern matches in a case statement.
7704  */
7705 static int
7706 casematch(union node *pattern, char *val)
7707 {
7708         struct stackmark smark;
7709         int result;
7710
7711         setstackmark(&smark);
7712         argbackq = pattern->narg.backquote;
7713         STARTSTACKSTR(expdest);
7714         argstr(pattern->narg.text, EXP_TILDE | EXP_CASE);
7715         STACKSTRNUL(expdest);
7716         ifsfree();
7717         result = patmatch(stackblock(), val);
7718         popstackmark(&smark);
7719         return result;
7720 }
7721
7722
7723 /* ============ find_command */
7724
7725 struct builtincmd {
7726         const char *name;
7727         int (*builtin)(int, char **) FAST_FUNC;
7728         /* unsigned flags; */
7729 };
7730 #define IS_BUILTIN_SPECIAL(b) ((b)->name[0] & 1)
7731 /* "regular" builtins always take precedence over commands,
7732  * regardless of PATH=....%builtin... position */
7733 #define IS_BUILTIN_REGULAR(b) ((b)->name[0] & 2)
7734 #define IS_BUILTIN_ASSIGN(b)  ((b)->name[0] & 4)
7735
7736 struct cmdentry {
7737         smallint cmdtype;       /* CMDxxx */
7738         union param {
7739                 int index;
7740                 /* index >= 0 for commands without path (slashes) */
7741                 /* (TODO: what exactly does the value mean? PATH position?) */
7742                 /* index == -1 for commands with slashes */
7743                 /* index == (-2 - applet_no) for NOFORK applets */
7744                 const struct builtincmd *cmd;
7745                 struct funcnode *func;
7746         } u;
7747 };
7748 /* values of cmdtype */
7749 #define CMDUNKNOWN      -1      /* no entry in table for command */
7750 #define CMDNORMAL       0       /* command is an executable program */
7751 #define CMDFUNCTION     1       /* command is a shell function */
7752 #define CMDBUILTIN      2       /* command is a shell builtin */
7753
7754 /* action to find_command() */
7755 #define DO_ERR          0x01    /* prints errors */
7756 #define DO_ABS          0x02    /* checks absolute paths */
7757 #define DO_NOFUNC       0x04    /* don't return shell functions, for command */
7758 #define DO_ALTPATH      0x08    /* using alternate path */
7759 #define DO_ALTBLTIN     0x20    /* %builtin in alt. path */
7760
7761 static void find_command(char *, struct cmdentry *, int, const char *);
7762
7763
7764 /* ============ Hashing commands */
7765
7766 /*
7767  * When commands are first encountered, they are entered in a hash table.
7768  * This ensures that a full path search will not have to be done for them
7769  * on each invocation.
7770  *
7771  * We should investigate converting to a linear search, even though that
7772  * would make the command name "hash" a misnomer.
7773  */
7774
7775 struct tblentry {
7776         struct tblentry *next;  /* next entry in hash chain */
7777         union param param;      /* definition of builtin function */
7778         smallint cmdtype;       /* CMDxxx */
7779         char rehash;            /* if set, cd done since entry created */
7780         char cmdname[1];        /* name of command */
7781 };
7782
7783 static struct tblentry **cmdtable;
7784 #define INIT_G_cmdtable() do { \
7785         cmdtable = xzalloc(CMDTABLESIZE * sizeof(cmdtable[0])); \
7786 } while (0)
7787
7788 static int builtinloc = -1;     /* index in path of %builtin, or -1 */
7789
7790
7791 static void
7792 tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) const char *cmd, char **argv, char **envp)
7793 {
7794 #if ENABLE_FEATURE_SH_STANDALONE
7795         if (applet_no >= 0) {
7796                 if (APPLET_IS_NOEXEC(applet_no)) {
7797                         clearenv();
7798                         while (*envp)
7799                                 putenv(*envp++);
7800                         popredir(/*drop:*/ 1);
7801                         run_applet_no_and_exit(applet_no, cmd, argv);
7802                 }
7803                 /* re-exec ourselves with the new arguments */
7804                 execve(bb_busybox_exec_path, argv, envp);
7805                 /* If they called chroot or otherwise made the binary no longer
7806                  * executable, fall through */
7807         }
7808 #endif
7809
7810  repeat:
7811 #ifdef SYSV
7812         do {
7813                 execve(cmd, argv, envp);
7814         } while (errno == EINTR);
7815 #else
7816         execve(cmd, argv, envp);
7817 #endif
7818         if (cmd != bb_busybox_exec_path && errno == ENOEXEC) {
7819                 /* Run "cmd" as a shell script:
7820                  * http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html
7821                  * "If the execve() function fails with ENOEXEC, the shell
7822                  * shall execute a command equivalent to having a shell invoked
7823                  * with the command name as its first operand,
7824                  * with any remaining arguments passed to the new shell"
7825                  *
7826                  * That is, do not use $SHELL, user's shell, or /bin/sh;
7827                  * just call ourselves.
7828                  *
7829                  * Note that bash reads ~80 chars of the file, and if it sees
7830                  * a zero byte before it sees newline, it doesn't try to
7831                  * interpret it, but fails with "cannot execute binary file"
7832                  * message and exit code 126. For one, this prevents attempts
7833                  * to interpret foreign ELF binaries as shell scripts.
7834                  */
7835                 argv[0] = (char*) cmd;
7836                 cmd = bb_busybox_exec_path;
7837                 /* NB: this is only possible because all callers of shellexec()
7838                  * ensure that the argv[-1] slot exists!
7839                  */
7840                 argv--;
7841                 argv[0] = (char*) "ash";
7842                 goto repeat;
7843         }
7844 }
7845
7846 /*
7847  * Exec a program.  Never returns.  If you change this routine, you may
7848  * have to change the find_command routine as well.
7849  * argv[-1] must exist and be writable! See tryexec() for why.
7850  */
7851 static void shellexec(char *prog, char **argv, const char *path, int idx) NORETURN;
7852 static void shellexec(char *prog, char **argv, const char *path, int idx)
7853 {
7854         char *cmdname;
7855         int e;
7856         char **envp;
7857         int exerrno;
7858         int applet_no = -1; /* used only by FEATURE_SH_STANDALONE */
7859
7860         envp = listvars(VEXPORT, VUNSET, /*end:*/ NULL);
7861         if (strchr(prog, '/') != NULL
7862 #if ENABLE_FEATURE_SH_STANDALONE
7863          || (applet_no = find_applet_by_name(prog)) >= 0
7864 #endif
7865         ) {
7866                 tryexec(IF_FEATURE_SH_STANDALONE(applet_no,) prog, argv, envp);
7867                 if (applet_no >= 0) {
7868                         /* We tried execing ourself, but it didn't work.
7869                          * Maybe /proc/self/exe doesn't exist?
7870                          * Try $PATH search.
7871                          */
7872                         goto try_PATH;
7873                 }
7874                 e = errno;
7875         } else {
7876  try_PATH:
7877                 e = ENOENT;
7878                 while ((cmdname = path_advance(&path, prog)) != NULL) {
7879                         if (--idx < 0 && pathopt == NULL) {
7880                                 tryexec(IF_FEATURE_SH_STANDALONE(-1,) cmdname, argv, envp);
7881                                 if (errno != ENOENT && errno != ENOTDIR)
7882                                         e = errno;
7883                         }
7884                         stunalloc(cmdname);
7885                 }
7886         }
7887
7888         /* Map to POSIX errors */
7889         switch (e) {
7890         case EACCES:
7891                 exerrno = 126;
7892                 break;
7893         case ENOENT:
7894                 exerrno = 127;
7895                 break;
7896         default:
7897                 exerrno = 2;
7898                 break;
7899         }
7900         exitstatus = exerrno;
7901         TRACE(("shellexec failed for %s, errno %d, suppress_int %d\n",
7902                 prog, e, suppress_int));
7903         ash_msg_and_raise(EXEXIT, "%s: %s", prog, errmsg(e, "not found"));
7904         /* NOTREACHED */
7905 }
7906
7907 static void
7908 printentry(struct tblentry *cmdp)
7909 {
7910         int idx;
7911         const char *path;
7912         char *name;
7913
7914         idx = cmdp->param.index;
7915         path = pathval();
7916         do {
7917                 name = path_advance(&path, cmdp->cmdname);
7918                 stunalloc(name);
7919         } while (--idx >= 0);
7920         out1fmt("%s%s\n", name, (cmdp->rehash ? "*" : nullstr));
7921 }
7922
7923 /*
7924  * Clear out command entries.  The argument specifies the first entry in
7925  * PATH which has changed.
7926  */
7927 static void
7928 clearcmdentry(int firstchange)
7929 {
7930         struct tblentry **tblp;
7931         struct tblentry **pp;
7932         struct tblentry *cmdp;
7933
7934         INT_OFF;
7935         for (tblp = cmdtable; tblp < &cmdtable[CMDTABLESIZE]; tblp++) {
7936                 pp = tblp;
7937                 while ((cmdp = *pp) != NULL) {
7938                         if ((cmdp->cmdtype == CMDNORMAL &&
7939                              cmdp->param.index >= firstchange)
7940                          || (cmdp->cmdtype == CMDBUILTIN &&
7941                              builtinloc >= firstchange)
7942                         ) {
7943                                 *pp = cmdp->next;
7944                                 free(cmdp);
7945                         } else {
7946                                 pp = &cmdp->next;
7947                         }
7948                 }
7949         }
7950         INT_ON;
7951 }
7952
7953 /*
7954  * Locate a command in the command hash table.  If "add" is nonzero,
7955  * add the command to the table if it is not already present.  The
7956  * variable "lastcmdentry" is set to point to the address of the link
7957  * pointing to the entry, so that delete_cmd_entry can delete the
7958  * entry.
7959  *
7960  * Interrupts must be off if called with add != 0.
7961  */
7962 static struct tblentry **lastcmdentry;
7963
7964 static struct tblentry *
7965 cmdlookup(const char *name, int add)
7966 {
7967         unsigned int hashval;
7968         const char *p;
7969         struct tblentry *cmdp;
7970         struct tblentry **pp;
7971
7972         p = name;
7973         hashval = (unsigned char)*p << 4;
7974         while (*p)
7975                 hashval += (unsigned char)*p++;
7976         hashval &= 0x7FFF;
7977         pp = &cmdtable[hashval % CMDTABLESIZE];
7978         for (cmdp = *pp; cmdp; cmdp = cmdp->next) {
7979                 if (strcmp(cmdp->cmdname, name) == 0)
7980                         break;
7981                 pp = &cmdp->next;
7982         }
7983         if (add && cmdp == NULL) {
7984                 cmdp = *pp = ckzalloc(sizeof(struct tblentry)
7985                                 + strlen(name)
7986                                 /* + 1 - already done because
7987                                  * tblentry::cmdname is char[1] */);
7988                 /*cmdp->next = NULL; - ckzalloc did it */
7989                 cmdp->cmdtype = CMDUNKNOWN;
7990                 strcpy(cmdp->cmdname, name);
7991         }
7992         lastcmdentry = pp;
7993         return cmdp;
7994 }
7995
7996 /*
7997  * Delete the command entry returned on the last lookup.
7998  */
7999 static void
8000 delete_cmd_entry(void)
8001 {
8002         struct tblentry *cmdp;
8003
8004         INT_OFF;
8005         cmdp = *lastcmdentry;
8006         *lastcmdentry = cmdp->next;
8007         if (cmdp->cmdtype == CMDFUNCTION)
8008                 freefunc(cmdp->param.func);
8009         free(cmdp);
8010         INT_ON;
8011 }
8012
8013 /*
8014  * Add a new command entry, replacing any existing command entry for
8015  * the same name - except special builtins.
8016  */
8017 static void
8018 addcmdentry(char *name, struct cmdentry *entry)
8019 {
8020         struct tblentry *cmdp;
8021
8022         cmdp = cmdlookup(name, 1);
8023         if (cmdp->cmdtype == CMDFUNCTION) {
8024                 freefunc(cmdp->param.func);
8025         }
8026         cmdp->cmdtype = entry->cmdtype;
8027         cmdp->param = entry->u;
8028         cmdp->rehash = 0;
8029 }
8030
8031 static int FAST_FUNC
8032 hashcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
8033 {
8034         struct tblentry **pp;
8035         struct tblentry *cmdp;
8036         int c;
8037         struct cmdentry entry;
8038         char *name;
8039
8040         if (nextopt("r") != '\0') {
8041                 clearcmdentry(0);
8042                 return 0;
8043         }
8044
8045         if (*argptr == NULL) {
8046                 for (pp = cmdtable; pp < &cmdtable[CMDTABLESIZE]; pp++) {
8047                         for (cmdp = *pp; cmdp; cmdp = cmdp->next) {
8048                                 if (cmdp->cmdtype == CMDNORMAL)
8049                                         printentry(cmdp);
8050                         }
8051                 }
8052                 return 0;
8053         }
8054
8055         c = 0;
8056         while ((name = *argptr) != NULL) {
8057                 cmdp = cmdlookup(name, 0);
8058                 if (cmdp != NULL
8059                  && (cmdp->cmdtype == CMDNORMAL
8060                      || (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0))
8061                 ) {
8062                         delete_cmd_entry();
8063                 }
8064                 find_command(name, &entry, DO_ERR, pathval());
8065                 if (entry.cmdtype == CMDUNKNOWN)
8066                         c = 1;
8067                 argptr++;
8068         }
8069         return c;
8070 }
8071
8072 /*
8073  * Called when a cd is done.  Marks all commands so the next time they
8074  * are executed they will be rehashed.
8075  */
8076 static void
8077 hashcd(void)
8078 {
8079         struct tblentry **pp;
8080         struct tblentry *cmdp;
8081
8082         for (pp = cmdtable; pp < &cmdtable[CMDTABLESIZE]; pp++) {
8083                 for (cmdp = *pp; cmdp; cmdp = cmdp->next) {
8084                         if (cmdp->cmdtype == CMDNORMAL
8085                          || (cmdp->cmdtype == CMDBUILTIN
8086                              && !IS_BUILTIN_REGULAR(cmdp->param.cmd)
8087                              && builtinloc > 0)
8088                         ) {
8089                                 cmdp->rehash = 1;
8090                         }
8091                 }
8092         }
8093 }
8094
8095 /*
8096  * Fix command hash table when PATH changed.
8097  * Called before PATH is changed.  The argument is the new value of PATH;
8098  * pathval() still returns the old value at this point.
8099  * Called with interrupts off.
8100  */
8101 static void FAST_FUNC
8102 changepath(const char *new)
8103 {
8104         const char *old;
8105         int firstchange;
8106         int idx;
8107         int idx_bltin;
8108
8109         old = pathval();
8110         firstchange = 9999;     /* assume no change */
8111         idx = 0;
8112         idx_bltin = -1;
8113         for (;;) {
8114                 if (*old != *new) {
8115                         firstchange = idx;
8116                         if ((*old == '\0' && *new == ':')
8117                          || (*old == ':' && *new == '\0')
8118                         ) {
8119                                 firstchange++;
8120                         }
8121                         old = new;      /* ignore subsequent differences */
8122                 }
8123                 if (*new == '\0')
8124                         break;
8125                 if (*new == '%' && idx_bltin < 0 && prefix(new + 1, "builtin"))
8126                         idx_bltin = idx;
8127                 if (*new == ':')
8128                         idx++;
8129                 new++;
8130                 old++;
8131         }
8132         if (builtinloc < 0 && idx_bltin >= 0)
8133                 builtinloc = idx_bltin;             /* zap builtins */
8134         if (builtinloc >= 0 && idx_bltin < 0)
8135                 firstchange = 0;
8136         clearcmdentry(firstchange);
8137         builtinloc = idx_bltin;
8138 }
8139 enum {
8140         TEOF,
8141         TNL,
8142         TREDIR,
8143         TWORD,
8144         TSEMI,
8145         TBACKGND,
8146         TAND,
8147         TOR,
8148         TPIPE,
8149         TLP,
8150         TRP,
8151         TENDCASE,
8152         TENDBQUOTE,
8153         TNOT,
8154         TCASE,
8155         TDO,
8156         TDONE,
8157         TELIF,
8158         TELSE,
8159         TESAC,
8160         TFI,
8161         TFOR,
8162 #if BASH_FUNCTION
8163         TFUNCTION,
8164 #endif
8165         TIF,
8166         TIN,
8167         TTHEN,
8168         TUNTIL,
8169         TWHILE,
8170         TBEGIN,
8171         TEND
8172 };
8173 typedef smallint token_id_t;
8174
8175 /* Nth bit indicates if token marks the end of a list */
8176 enum {
8177         tokendlist = 0
8178         /*  0 */ | (1u << TEOF)
8179         /*  1 */ | (0u << TNL)
8180         /*  2 */ | (0u << TREDIR)
8181         /*  3 */ | (0u << TWORD)
8182         /*  4 */ | (0u << TSEMI)
8183         /*  5 */ | (0u << TBACKGND)
8184         /*  6 */ | (0u << TAND)
8185         /*  7 */ | (0u << TOR)
8186         /*  8 */ | (0u << TPIPE)
8187         /*  9 */ | (0u << TLP)
8188         /* 10 */ | (1u << TRP)
8189         /* 11 */ | (1u << TENDCASE)
8190         /* 12 */ | (1u << TENDBQUOTE)
8191         /* 13 */ | (0u << TNOT)
8192         /* 14 */ | (0u << TCASE)
8193         /* 15 */ | (1u << TDO)
8194         /* 16 */ | (1u << TDONE)
8195         /* 17 */ | (1u << TELIF)
8196         /* 18 */ | (1u << TELSE)
8197         /* 19 */ | (1u << TESAC)
8198         /* 20 */ | (1u << TFI)
8199         /* 21 */ | (0u << TFOR)
8200 #if BASH_FUNCTION
8201         /* 22 */ | (0u << TFUNCTION)
8202 #endif
8203         /* 23 */ | (0u << TIF)
8204         /* 24 */ | (0u << TIN)
8205         /* 25 */ | (1u << TTHEN)
8206         /* 26 */ | (0u << TUNTIL)
8207         /* 27 */ | (0u << TWHILE)
8208         /* 28 */ | (0u << TBEGIN)
8209         /* 29 */ | (1u << TEND)
8210         , /* thus far 29 bits used */
8211 };
8212
8213 static const char *const tokname_array[] = {
8214         "end of file",
8215         "newline",
8216         "redirection",
8217         "word",
8218         ";",
8219         "&",
8220         "&&",
8221         "||",
8222         "|",
8223         "(",
8224         ")",
8225         ";;",
8226         "`",
8227 #define KWDOFFSET 13
8228         /* the following are keywords */
8229         "!",
8230         "case",
8231         "do",
8232         "done",
8233         "elif",
8234         "else",
8235         "esac",
8236         "fi",
8237         "for",
8238 #if BASH_FUNCTION
8239         "function",
8240 #endif
8241         "if",
8242         "in",
8243         "then",
8244         "until",
8245         "while",
8246         "{",
8247         "}",
8248 };
8249
8250 /* Wrapper around strcmp for qsort/bsearch/... */
8251 static int
8252 pstrcmp(const void *a, const void *b)
8253 {
8254         return strcmp((char*)a, *(char**)b);
8255 }
8256
8257 static const char *const *
8258 findkwd(const char *s)
8259 {
8260         return bsearch(s, tokname_array + KWDOFFSET,
8261                         ARRAY_SIZE(tokname_array) - KWDOFFSET,
8262                         sizeof(tokname_array[0]), pstrcmp);
8263 }
8264
8265 /*
8266  * Locate and print what a word is...
8267  */
8268 static int
8269 describe_command(char *command, const char *path, int describe_command_verbose)
8270 {
8271         struct cmdentry entry;
8272 #if ENABLE_ASH_ALIAS
8273         const struct alias *ap;
8274 #endif
8275
8276         path = path ? path : pathval();
8277
8278         if (describe_command_verbose) {
8279                 out1str(command);
8280         }
8281
8282         /* First look at the keywords */
8283         if (findkwd(command)) {
8284                 out1str(describe_command_verbose ? " is a shell keyword" : command);
8285                 goto out;
8286         }
8287
8288 #if ENABLE_ASH_ALIAS
8289         /* Then look at the aliases */
8290         ap = lookupalias(command, 0);
8291         if (ap != NULL) {
8292                 if (!describe_command_verbose) {
8293                         out1str("alias ");
8294                         printalias(ap);
8295                         return 0;
8296                 }
8297                 out1fmt(" is an alias for %s", ap->val);
8298                 goto out;
8299         }
8300 #endif
8301         /* Brute force */
8302         find_command(command, &entry, DO_ABS, path);
8303
8304         switch (entry.cmdtype) {
8305         case CMDNORMAL: {
8306                 int j = entry.u.index;
8307                 char *p;
8308                 if (j < 0) {
8309                         p = command;
8310                 } else {
8311                         do {
8312                                 p = path_advance(&path, command);
8313                                 stunalloc(p);
8314                         } while (--j >= 0);
8315                 }
8316                 if (describe_command_verbose) {
8317                         out1fmt(" is %s", p);
8318                 } else {
8319                         out1str(p);
8320                 }
8321                 break;
8322         }
8323
8324         case CMDFUNCTION:
8325                 if (describe_command_verbose) {
8326                         out1str(" is a shell function");
8327                 } else {
8328                         out1str(command);
8329                 }
8330                 break;
8331
8332         case CMDBUILTIN:
8333                 if (describe_command_verbose) {
8334                         out1fmt(" is a %sshell builtin",
8335                                 IS_BUILTIN_SPECIAL(entry.u.cmd) ?
8336                                         "special " : nullstr
8337                         );
8338                 } else {
8339                         out1str(command);
8340                 }
8341                 break;
8342
8343         default:
8344                 if (describe_command_verbose) {
8345                         out1str(": not found\n");
8346                 }
8347                 return 127;
8348         }
8349  out:
8350         out1str("\n");
8351         return 0;
8352 }
8353
8354 static int FAST_FUNC
8355 typecmd(int argc UNUSED_PARAM, char **argv)
8356 {
8357         int i = 1;
8358         int err = 0;
8359         int verbose = 1;
8360
8361         /* type -p ... ? (we don't bother checking for 'p') */
8362         if (argv[1] && argv[1][0] == '-') {
8363                 i++;
8364                 verbose = 0;
8365         }
8366         while (argv[i]) {
8367                 err |= describe_command(argv[i++], NULL, verbose);
8368         }
8369         return err;
8370 }
8371
8372 #if ENABLE_ASH_CMDCMD
8373 /* Is it "command [-p] PROG ARGS" bltin, no other opts? Return ptr to "PROG" if yes */
8374 static char **
8375 parse_command_args(char **argv, const char **path)
8376 {
8377         char *cp, c;
8378
8379         for (;;) {
8380                 cp = *++argv;
8381                 if (!cp)
8382                         return NULL;
8383                 if (*cp++ != '-')
8384                         break;
8385                 c = *cp++;
8386                 if (!c)
8387                         break;
8388                 if (c == '-' && !*cp) {
8389                         if (!*++argv)
8390                                 return NULL;
8391                         break;
8392                 }
8393                 do {
8394                         switch (c) {
8395                         case 'p':
8396                                 *path = bb_default_path;
8397                                 break;
8398                         default:
8399                                 /* run 'typecmd' for other options */
8400                                 return NULL;
8401                         }
8402                         c = *cp++;
8403                 } while (c);
8404         }
8405         return argv;
8406 }
8407
8408 static int FAST_FUNC
8409 commandcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
8410 {
8411         char *cmd;
8412         int c;
8413         enum {
8414                 VERIFY_BRIEF = 1,
8415                 VERIFY_VERBOSE = 2,
8416         } verify = 0;
8417         const char *path = NULL;
8418
8419         /* "command [-p] PROG ARGS" (that is, without -V or -v)
8420          * never reaches this function.
8421          */
8422
8423         while ((c = nextopt("pvV")) != '\0')
8424                 if (c == 'V')
8425                         verify |= VERIFY_VERBOSE;
8426                 else if (c == 'v')
8427                         /*verify |= VERIFY_BRIEF*/;
8428 #if DEBUG
8429                 else if (c != 'p')
8430                         abort();
8431 #endif
8432                 else
8433                         path = bb_default_path;
8434
8435         /* Mimic bash: just "command -v" doesn't complain, it's a nop */
8436         cmd = *argptr;
8437         if (/*verify && */ cmd)
8438                 return describe_command(cmd, path, verify /* - VERIFY_BRIEF*/);
8439
8440         return 0;
8441 }
8442 #endif
8443
8444
8445 /*static int funcblocksize;     // size of structures in function */
8446 /*static int funcstringsize;    // size of strings in node */
8447 static void *funcblock;         /* block to allocate function from */
8448 static char *funcstring_end;    /* end of block to allocate strings from */
8449
8450 static const uint8_t nodesize[N_NUMBER] ALIGN1 = {
8451         [NCMD     ] = SHELL_ALIGN(sizeof(struct ncmd)),
8452         [NPIPE    ] = SHELL_ALIGN(sizeof(struct npipe)),
8453         [NREDIR   ] = SHELL_ALIGN(sizeof(struct nredir)),
8454         [NBACKGND ] = SHELL_ALIGN(sizeof(struct nredir)),
8455         [NSUBSHELL] = SHELL_ALIGN(sizeof(struct nredir)),
8456         [NAND     ] = SHELL_ALIGN(sizeof(struct nbinary)),
8457         [NOR      ] = SHELL_ALIGN(sizeof(struct nbinary)),
8458         [NSEMI    ] = SHELL_ALIGN(sizeof(struct nbinary)),
8459         [NIF      ] = SHELL_ALIGN(sizeof(struct nif)),
8460         [NWHILE   ] = SHELL_ALIGN(sizeof(struct nbinary)),
8461         [NUNTIL   ] = SHELL_ALIGN(sizeof(struct nbinary)),
8462         [NFOR     ] = SHELL_ALIGN(sizeof(struct nfor)),
8463         [NCASE    ] = SHELL_ALIGN(sizeof(struct ncase)),
8464         [NCLIST   ] = SHELL_ALIGN(sizeof(struct nclist)),
8465         [NDEFUN   ] = SHELL_ALIGN(sizeof(struct narg)),
8466         [NARG     ] = SHELL_ALIGN(sizeof(struct narg)),
8467         [NTO      ] = SHELL_ALIGN(sizeof(struct nfile)),
8468 #if BASH_REDIR_OUTPUT
8469         [NTO2     ] = SHELL_ALIGN(sizeof(struct nfile)),
8470 #endif
8471         [NCLOBBER ] = SHELL_ALIGN(sizeof(struct nfile)),
8472         [NFROM    ] = SHELL_ALIGN(sizeof(struct nfile)),
8473         [NFROMTO  ] = SHELL_ALIGN(sizeof(struct nfile)),
8474         [NAPPEND  ] = SHELL_ALIGN(sizeof(struct nfile)),
8475         [NTOFD    ] = SHELL_ALIGN(sizeof(struct ndup)),
8476         [NFROMFD  ] = SHELL_ALIGN(sizeof(struct ndup)),
8477         [NHERE    ] = SHELL_ALIGN(sizeof(struct nhere)),
8478         [NXHERE   ] = SHELL_ALIGN(sizeof(struct nhere)),
8479         [NNOT     ] = SHELL_ALIGN(sizeof(struct nnot)),
8480 };
8481
8482 static int calcsize(int funcblocksize, union node *n);
8483
8484 static int
8485 sizenodelist(int funcblocksize, struct nodelist *lp)
8486 {
8487         while (lp) {
8488                 funcblocksize += SHELL_ALIGN(sizeof(struct nodelist));
8489                 funcblocksize = calcsize(funcblocksize, lp->n);
8490                 lp = lp->next;
8491         }
8492         return funcblocksize;
8493 }
8494
8495 static int
8496 calcsize(int funcblocksize, union node *n)
8497 {
8498         if (n == NULL)
8499                 return funcblocksize;
8500         funcblocksize += nodesize[n->type];
8501         switch (n->type) {
8502         case NCMD:
8503                 funcblocksize = calcsize(funcblocksize, n->ncmd.redirect);
8504                 funcblocksize = calcsize(funcblocksize, n->ncmd.args);
8505                 funcblocksize = calcsize(funcblocksize, n->ncmd.assign);
8506                 break;
8507         case NPIPE:
8508                 funcblocksize = sizenodelist(funcblocksize, n->npipe.cmdlist);
8509                 break;
8510         case NREDIR:
8511         case NBACKGND:
8512         case NSUBSHELL:
8513                 funcblocksize = calcsize(funcblocksize, n->nredir.redirect);
8514                 funcblocksize = calcsize(funcblocksize, n->nredir.n);
8515                 break;
8516         case NAND:
8517         case NOR:
8518         case NSEMI:
8519         case NWHILE:
8520         case NUNTIL:
8521                 funcblocksize = calcsize(funcblocksize, n->nbinary.ch2);
8522                 funcblocksize = calcsize(funcblocksize, n->nbinary.ch1);
8523                 break;
8524         case NIF:
8525                 funcblocksize = calcsize(funcblocksize, n->nif.elsepart);
8526                 funcblocksize = calcsize(funcblocksize, n->nif.ifpart);
8527                 funcblocksize = calcsize(funcblocksize, n->nif.test);
8528                 break;
8529         case NFOR:
8530                 funcblocksize += SHELL_ALIGN(strlen(n->nfor.var) + 1); /* was funcstringsize += ... */
8531                 funcblocksize = calcsize(funcblocksize, n->nfor.body);
8532                 funcblocksize = calcsize(funcblocksize, n->nfor.args);
8533                 break;
8534         case NCASE:
8535                 funcblocksize = calcsize(funcblocksize, n->ncase.cases);
8536                 funcblocksize = calcsize(funcblocksize, n->ncase.expr);
8537                 break;
8538         case NCLIST:
8539                 funcblocksize = calcsize(funcblocksize, n->nclist.body);
8540                 funcblocksize = calcsize(funcblocksize, n->nclist.pattern);
8541                 funcblocksize = calcsize(funcblocksize, n->nclist.next);
8542                 break;
8543         case NDEFUN:
8544         case NARG:
8545                 funcblocksize = sizenodelist(funcblocksize, n->narg.backquote);
8546                 funcblocksize += SHELL_ALIGN(strlen(n->narg.text) + 1); /* was funcstringsize += ... */
8547                 funcblocksize = calcsize(funcblocksize, n->narg.next);
8548                 break;
8549         case NTO:
8550 #if BASH_REDIR_OUTPUT
8551         case NTO2:
8552 #endif
8553         case NCLOBBER:
8554         case NFROM:
8555         case NFROMTO:
8556         case NAPPEND:
8557                 funcblocksize = calcsize(funcblocksize, n->nfile.fname);
8558                 funcblocksize = calcsize(funcblocksize, n->nfile.next);
8559                 break;
8560         case NTOFD:
8561         case NFROMFD:
8562                 funcblocksize = calcsize(funcblocksize, n->ndup.vname);
8563                 funcblocksize = calcsize(funcblocksize, n->ndup.next);
8564         break;
8565         case NHERE:
8566         case NXHERE:
8567                 funcblocksize = calcsize(funcblocksize, n->nhere.doc);
8568                 funcblocksize = calcsize(funcblocksize, n->nhere.next);
8569                 break;
8570         case NNOT:
8571                 funcblocksize = calcsize(funcblocksize, n->nnot.com);
8572                 break;
8573         };
8574         return funcblocksize;
8575 }
8576
8577 static char *
8578 nodeckstrdup(char *s)
8579 {
8580         funcstring_end -= SHELL_ALIGN(strlen(s) + 1);
8581         return strcpy(funcstring_end, s);
8582 }
8583
8584 static union node *copynode(union node *);
8585
8586 static struct nodelist *
8587 copynodelist(struct nodelist *lp)
8588 {
8589         struct nodelist *start;
8590         struct nodelist **lpp;
8591
8592         lpp = &start;
8593         while (lp) {
8594                 *lpp = funcblock;
8595                 funcblock = (char *) funcblock + SHELL_ALIGN(sizeof(struct nodelist));
8596                 (*lpp)->n = copynode(lp->n);
8597                 lp = lp->next;
8598                 lpp = &(*lpp)->next;
8599         }
8600         *lpp = NULL;
8601         return start;
8602 }
8603
8604 static union node *
8605 copynode(union node *n)
8606 {
8607         union node *new;
8608
8609         if (n == NULL)
8610                 return NULL;
8611         new = funcblock;
8612         funcblock = (char *) funcblock + nodesize[n->type];
8613
8614         switch (n->type) {
8615         case NCMD:
8616                 new->ncmd.redirect = copynode(n->ncmd.redirect);
8617                 new->ncmd.args = copynode(n->ncmd.args);
8618                 new->ncmd.assign = copynode(n->ncmd.assign);
8619                 break;
8620         case NPIPE:
8621                 new->npipe.cmdlist = copynodelist(n->npipe.cmdlist);
8622                 new->npipe.pipe_backgnd = n->npipe.pipe_backgnd;
8623                 break;
8624         case NREDIR:
8625         case NBACKGND:
8626         case NSUBSHELL:
8627                 new->nredir.redirect = copynode(n->nredir.redirect);
8628                 new->nredir.n = copynode(n->nredir.n);
8629                 break;
8630         case NAND:
8631         case NOR:
8632         case NSEMI:
8633         case NWHILE:
8634         case NUNTIL:
8635                 new->nbinary.ch2 = copynode(n->nbinary.ch2);
8636                 new->nbinary.ch1 = copynode(n->nbinary.ch1);
8637                 break;
8638         case NIF:
8639                 new->nif.elsepart = copynode(n->nif.elsepart);
8640                 new->nif.ifpart = copynode(n->nif.ifpart);
8641                 new->nif.test = copynode(n->nif.test);
8642                 break;
8643         case NFOR:
8644                 new->nfor.var = nodeckstrdup(n->nfor.var);
8645                 new->nfor.body = copynode(n->nfor.body);
8646                 new->nfor.args = copynode(n->nfor.args);
8647                 break;
8648         case NCASE:
8649                 new->ncase.cases = copynode(n->ncase.cases);
8650                 new->ncase.expr = copynode(n->ncase.expr);
8651                 break;
8652         case NCLIST:
8653                 new->nclist.body = copynode(n->nclist.body);
8654                 new->nclist.pattern = copynode(n->nclist.pattern);
8655                 new->nclist.next = copynode(n->nclist.next);
8656                 break;
8657         case NDEFUN:
8658         case NARG:
8659                 new->narg.backquote = copynodelist(n->narg.backquote);
8660                 new->narg.text = nodeckstrdup(n->narg.text);
8661                 new->narg.next = copynode(n->narg.next);
8662                 break;
8663         case NTO:
8664 #if BASH_REDIR_OUTPUT
8665         case NTO2:
8666 #endif
8667         case NCLOBBER:
8668         case NFROM:
8669         case NFROMTO:
8670         case NAPPEND:
8671                 new->nfile.fname = copynode(n->nfile.fname);
8672                 new->nfile.fd = n->nfile.fd;
8673                 new->nfile.next = copynode(n->nfile.next);
8674                 break;
8675         case NTOFD:
8676         case NFROMFD:
8677                 new->ndup.vname = copynode(n->ndup.vname);
8678                 new->ndup.dupfd = n->ndup.dupfd;
8679                 new->ndup.fd = n->ndup.fd;
8680                 new->ndup.next = copynode(n->ndup.next);
8681                 break;
8682         case NHERE:
8683         case NXHERE:
8684                 new->nhere.doc = copynode(n->nhere.doc);
8685                 new->nhere.fd = n->nhere.fd;
8686                 new->nhere.next = copynode(n->nhere.next);
8687                 break;
8688         case NNOT:
8689                 new->nnot.com = copynode(n->nnot.com);
8690                 break;
8691         };
8692         new->type = n->type;
8693         return new;
8694 }
8695
8696 /*
8697  * Make a copy of a parse tree.
8698  */
8699 static struct funcnode *
8700 copyfunc(union node *n)
8701 {
8702         struct funcnode *f;
8703         size_t blocksize;
8704
8705         /*funcstringsize = 0;*/
8706         blocksize = offsetof(struct funcnode, n) + calcsize(0, n);
8707         f = ckzalloc(blocksize /* + funcstringsize */);
8708         funcblock = (char *) f + offsetof(struct funcnode, n);
8709         funcstring_end = (char *) f + blocksize;
8710         copynode(n);
8711         /* f->count = 0; - ckzalloc did it */
8712         return f;
8713 }
8714
8715 /*
8716  * Define a shell function.
8717  */
8718 static void
8719 defun(union node *func)
8720 {
8721         struct cmdentry entry;
8722
8723         INT_OFF;
8724         entry.cmdtype = CMDFUNCTION;
8725         entry.u.func = copyfunc(func);
8726         addcmdentry(func->narg.text, &entry);
8727         INT_ON;
8728 }
8729
8730 /* Reasons for skipping commands (see comment on breakcmd routine) */
8731 #define SKIPBREAK      (1 << 0)
8732 #define SKIPCONT       (1 << 1)
8733 #define SKIPFUNC       (1 << 2)
8734 static smallint evalskip;       /* set to SKIPxxx if we are skipping commands */
8735 static int skipcount;           /* number of levels to skip */
8736 static int funcnest;            /* depth of function calls */
8737 static int loopnest;            /* current loop nesting level */
8738
8739 /* Forward decl way out to parsing code - dotrap needs it */
8740 static int evalstring(char *s, int flags);
8741
8742 /* Called to execute a trap.
8743  * Single callsite - at the end of evaltree().
8744  * If we return non-zero, evaltree raises EXEXIT exception.
8745  *
8746  * Perhaps we should avoid entering new trap handlers
8747  * while we are executing a trap handler. [is it a TODO?]
8748  */
8749 static void
8750 dotrap(void)
8751 {
8752         uint8_t *g;
8753         int sig;
8754         uint8_t last_status;
8755
8756         if (!pending_sig)
8757                 return;
8758
8759         last_status = exitstatus;
8760         pending_sig = 0;
8761         barrier();
8762
8763         TRACE(("dotrap entered\n"));
8764         for (sig = 1, g = gotsig; sig < NSIG; sig++, g++) {
8765                 char *p;
8766
8767                 if (!*g)
8768                         continue;
8769
8770                 if (evalskip) {
8771                         pending_sig = sig;
8772                         break;
8773                 }
8774
8775                 p = trap[sig];
8776                 /* non-trapped SIGINT is handled separately by raise_interrupt,
8777                  * don't upset it by resetting gotsig[SIGINT-1] */
8778                 if (sig == SIGINT && !p)
8779                         continue;
8780
8781                 TRACE(("sig %d is active, will run handler '%s'\n", sig, p));
8782                 *g = 0;
8783                 if (!p)
8784                         continue;
8785                 evalstring(p, 0);
8786         }
8787         exitstatus = last_status;
8788         TRACE(("dotrap returns\n"));
8789 }
8790
8791 /* forward declarations - evaluation is fairly recursive business... */
8792 static int evalloop(union node *, int);
8793 static int evalfor(union node *, int);
8794 static int evalcase(union node *, int);
8795 static int evalsubshell(union node *, int);
8796 static void expredir(union node *);
8797 static int evalpipe(union node *, int);
8798 static int evalcommand(union node *, int);
8799 static int evalbltin(const struct builtincmd *, int, char **, int);
8800 static void prehash(union node *);
8801
8802 /*
8803  * Evaluate a parse tree.  The value is left in the global variable
8804  * exitstatus.
8805  */
8806 static int
8807 evaltree(union node *n, int flags)
8808 {
8809         int checkexit = 0;
8810         int (*evalfn)(union node *, int);
8811         int status = 0;
8812
8813         if (n == NULL) {
8814                 TRACE(("evaltree(NULL) called\n"));
8815                 goto out;
8816         }
8817         TRACE(("evaltree(%p: %d, %d) called\n", n, n->type, flags));
8818
8819         dotrap();
8820
8821         switch (n->type) {
8822         default:
8823 #if DEBUG
8824                 out1fmt("Node type = %d\n", n->type);
8825                 fflush_all();
8826                 break;
8827 #endif
8828         case NNOT:
8829                 status = !evaltree(n->nnot.com, EV_TESTED);
8830                 goto setstatus;
8831         case NREDIR:
8832                 expredir(n->nredir.redirect);
8833                 pushredir(n->nredir.redirect);
8834                 status = redirectsafe(n->nredir.redirect, REDIR_PUSH);
8835                 if (!status) {
8836                         status = evaltree(n->nredir.n, flags & EV_TESTED);
8837                 }
8838                 if (n->nredir.redirect)
8839                         popredir(/*drop:*/ 0);
8840                 goto setstatus;
8841         case NCMD:
8842                 evalfn = evalcommand;
8843  checkexit:
8844                 if (eflag && !(flags & EV_TESTED))
8845                         checkexit = ~0;
8846                 goto calleval;
8847         case NFOR:
8848                 evalfn = evalfor;
8849                 goto calleval;
8850         case NWHILE:
8851         case NUNTIL:
8852                 evalfn = evalloop;
8853                 goto calleval;
8854         case NSUBSHELL:
8855         case NBACKGND:
8856                 evalfn = evalsubshell;
8857                 goto checkexit;
8858         case NPIPE:
8859                 evalfn = evalpipe;
8860                 goto checkexit;
8861         case NCASE:
8862                 evalfn = evalcase;
8863                 goto calleval;
8864         case NAND:
8865         case NOR:
8866         case NSEMI: {
8867
8868 #if NAND + 1 != NOR
8869 #error NAND + 1 != NOR
8870 #endif
8871 #if NOR + 1 != NSEMI
8872 #error NOR + 1 != NSEMI
8873 #endif
8874                 unsigned is_or = n->type - NAND;
8875                 status = evaltree(
8876                         n->nbinary.ch1,
8877                         (flags | ((is_or >> 1) - 1)) & EV_TESTED
8878                 );
8879                 if ((!status) == is_or || evalskip)
8880                         break;
8881                 n = n->nbinary.ch2;
8882  evaln:
8883                 evalfn = evaltree;
8884  calleval:
8885                 status = evalfn(n, flags);
8886                 goto setstatus;
8887         }
8888         case NIF:
8889                 status = evaltree(n->nif.test, EV_TESTED);
8890                 if (evalskip)
8891                         break;
8892                 if (!status) {
8893                         n = n->nif.ifpart;
8894                         goto evaln;
8895                 }
8896                 if (n->nif.elsepart) {
8897                         n = n->nif.elsepart;
8898                         goto evaln;
8899                 }
8900                 status = 0;
8901                 goto setstatus;
8902         case NDEFUN:
8903                 defun(n);
8904                 /* Not necessary. To test it:
8905                  * "false; f() { qwerty; }; echo $?" should print 0.
8906                  */
8907                 /* status = 0; */
8908  setstatus:
8909                 exitstatus = status;
8910                 break;
8911         }
8912  out:
8913         /* Order of checks below is important:
8914          * signal handlers trigger before exit caused by "set -e".
8915          */
8916         dotrap();
8917
8918         if (checkexit & status)
8919                 raise_exception(EXEXIT);
8920         if (flags & EV_EXIT)
8921                 raise_exception(EXEXIT);
8922
8923         TRACE(("leaving evaltree (no interrupts)\n"));
8924         return exitstatus;
8925 }
8926
8927 static int
8928 skiploop(void)
8929 {
8930         int skip = evalskip;
8931
8932         switch (skip) {
8933         case 0:
8934                 break;
8935         case SKIPBREAK:
8936         case SKIPCONT:
8937                 if (--skipcount <= 0) {
8938                         evalskip = 0;
8939                         break;
8940                 }
8941                 skip = SKIPBREAK;
8942                 break;
8943         }
8944         return skip;
8945 }
8946
8947 static int
8948 evalloop(union node *n, int flags)
8949 {
8950         int skip;
8951         int status;
8952
8953         loopnest++;
8954         status = 0;
8955         flags &= EV_TESTED;
8956         do {
8957                 int i;
8958
8959                 i = evaltree(n->nbinary.ch1, EV_TESTED);
8960                 skip = skiploop();
8961                 if (skip == SKIPFUNC)
8962                         status = i;
8963                 if (skip)
8964                         continue;
8965                 if (n->type != NWHILE)
8966                         i = !i;
8967                 if (i != 0)
8968                         break;
8969                 status = evaltree(n->nbinary.ch2, flags);
8970                 skip = skiploop();
8971         } while (!(skip & ~SKIPCONT));
8972         loopnest--;
8973
8974         return status;
8975 }
8976
8977 static int
8978 evalfor(union node *n, int flags)
8979 {
8980         struct arglist arglist;
8981         union node *argp;
8982         struct strlist *sp;
8983         struct stackmark smark;
8984         int status = 0;
8985
8986         setstackmark(&smark);
8987         arglist.list = NULL;
8988         arglist.lastp = &arglist.list;
8989         for (argp = n->nfor.args; argp; argp = argp->narg.next) {
8990                 expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
8991         }
8992         *arglist.lastp = NULL;
8993
8994         loopnest++;
8995         flags &= EV_TESTED;
8996         for (sp = arglist.list; sp; sp = sp->next) {
8997                 setvar0(n->nfor.var, sp->text);
8998                 status = evaltree(n->nfor.body, flags);
8999                 if (skiploop() & ~SKIPCONT)
9000                         break;
9001         }
9002         loopnest--;
9003         popstackmark(&smark);
9004
9005         return status;
9006 }
9007
9008 static int
9009 evalcase(union node *n, int flags)
9010 {
9011         union node *cp;
9012         union node *patp;
9013         struct arglist arglist;
9014         struct stackmark smark;
9015         int status = 0;
9016
9017         setstackmark(&smark);
9018         arglist.list = NULL;
9019         arglist.lastp = &arglist.list;
9020         expandarg(n->ncase.expr, &arglist, EXP_TILDE);
9021         for (cp = n->ncase.cases; cp && evalskip == 0; cp = cp->nclist.next) {
9022                 for (patp = cp->nclist.pattern; patp; patp = patp->narg.next) {
9023                         if (casematch(patp, arglist.list->text)) {
9024                                 /* Ensure body is non-empty as otherwise
9025                                  * EV_EXIT may prevent us from setting the
9026                                  * exit status.
9027                                  */
9028                                 if (evalskip == 0 && cp->nclist.body) {
9029                                         status = evaltree(cp->nclist.body, flags);
9030                                 }
9031                                 goto out;
9032                         }
9033                 }
9034         }
9035  out:
9036         popstackmark(&smark);
9037
9038         return status;
9039 }
9040
9041 /*
9042  * Kick off a subshell to evaluate a tree.
9043  */
9044 static int
9045 evalsubshell(union node *n, int flags)
9046 {
9047         struct job *jp;
9048         int backgnd = (n->type == NBACKGND); /* FORK_BG(1) if yes, else FORK_FG(0) */
9049         int status;
9050
9051         expredir(n->nredir.redirect);
9052         if (!backgnd && (flags & EV_EXIT) && !may_have_traps)
9053                 goto nofork;
9054         INT_OFF;
9055         if (backgnd == FORK_FG)
9056                 get_tty_state();
9057         jp = makejob(/*n,*/ 1);
9058         if (forkshell(jp, n, backgnd) == 0) {
9059                 /* child */
9060                 INT_ON;
9061                 flags |= EV_EXIT;
9062                 if (backgnd)
9063                         flags &= ~EV_TESTED;
9064  nofork:
9065                 redirect(n->nredir.redirect, 0);
9066                 evaltreenr(n->nredir.n, flags);
9067                 /* never returns */
9068         }
9069         /* parent */
9070         status = 0;
9071         if (backgnd == FORK_FG)
9072                 status = waitforjob(jp);
9073         INT_ON;
9074         return status;
9075 }
9076
9077 /*
9078  * Compute the names of the files in a redirection list.
9079  */
9080 static void fixredir(union node *, const char *, int);
9081 static void
9082 expredir(union node *n)
9083 {
9084         union node *redir;
9085
9086         for (redir = n; redir; redir = redir->nfile.next) {
9087                 struct arglist fn;
9088
9089                 fn.list = NULL;
9090                 fn.lastp = &fn.list;
9091                 switch (redir->type) {
9092                 case NFROMTO:
9093                 case NFROM:
9094                 case NTO:
9095 #if BASH_REDIR_OUTPUT
9096                 case NTO2:
9097 #endif
9098                 case NCLOBBER:
9099                 case NAPPEND:
9100                         expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR);
9101                         TRACE(("expredir expanded to '%s'\n", fn.list->text));
9102 #if BASH_REDIR_OUTPUT
9103  store_expfname:
9104 #endif
9105 #if 0
9106 // By the design of stack allocator, the loop of this kind:
9107 //      while true; do while true; do break; done </dev/null; done
9108 // will look like a memory leak: ash plans to free expfname's
9109 // of "/dev/null" as soon as it finishes running the loop
9110 // (in this case, never).
9111 // This "fix" is wrong:
9112                         if (redir->nfile.expfname)
9113                                 stunalloc(redir->nfile.expfname);
9114 // It results in corrupted state of stacked allocations.
9115 #endif
9116                         redir->nfile.expfname = fn.list->text;
9117                         break;
9118                 case NFROMFD:
9119                 case NTOFD: /* >& */
9120                         if (redir->ndup.vname) {
9121                                 expandarg(redir->ndup.vname, &fn, EXP_FULL | EXP_TILDE);
9122                                 if (fn.list == NULL)
9123                                         ash_msg_and_raise_error("redir error");
9124 #if BASH_REDIR_OUTPUT
9125 //FIXME: we used expandarg with different args!
9126                                 if (!isdigit_str9(fn.list->text)) {
9127                                         /* >&file, not >&fd */
9128                                         if (redir->nfile.fd != 1) /* 123>&file - BAD */
9129                                                 ash_msg_and_raise_error("redir error");
9130                                         redir->type = NTO2;
9131                                         goto store_expfname;
9132                                 }
9133 #endif
9134                                 fixredir(redir, fn.list->text, 1);
9135                         }
9136                         break;
9137                 }
9138         }
9139 }
9140
9141 /*
9142  * Evaluate a pipeline.  All the processes in the pipeline are children
9143  * of the process creating the pipeline.  (This differs from some versions
9144  * of the shell, which make the last process in a pipeline the parent
9145  * of all the rest.)
9146  */
9147 static int
9148 evalpipe(union node *n, int flags)
9149 {
9150         struct job *jp;
9151         struct nodelist *lp;
9152         int pipelen;
9153         int prevfd;
9154         int pip[2];
9155         int status = 0;
9156
9157         TRACE(("evalpipe(0x%lx) called\n", (long)n));
9158         pipelen = 0;
9159         for (lp = n->npipe.cmdlist; lp; lp = lp->next)
9160                 pipelen++;
9161         flags |= EV_EXIT;
9162         INT_OFF;
9163         if (n->npipe.pipe_backgnd == 0)
9164                 get_tty_state();
9165         jp = makejob(/*n,*/ pipelen);
9166         prevfd = -1;
9167         for (lp = n->npipe.cmdlist; lp; lp = lp->next) {
9168                 prehash(lp->n);
9169                 pip[1] = -1;
9170                 if (lp->next) {
9171                         if (pipe(pip) < 0) {
9172                                 close(prevfd);
9173                                 ash_msg_and_raise_error("pipe call failed");
9174                         }
9175                 }
9176                 if (forkshell(jp, lp->n, n->npipe.pipe_backgnd) == 0) {
9177                         /* child */
9178                         INT_ON;
9179                         if (pip[1] >= 0) {
9180                                 close(pip[0]);
9181                         }
9182                         if (prevfd > 0) {
9183                                 dup2(prevfd, 0);
9184                                 close(prevfd);
9185                         }
9186                         if (pip[1] > 1) {
9187                                 dup2(pip[1], 1);
9188                                 close(pip[1]);
9189                         }
9190                         evaltreenr(lp->n, flags);
9191                         /* never returns */
9192                 }
9193                 /* parent */
9194                 if (prevfd >= 0)
9195                         close(prevfd);
9196                 prevfd = pip[0];
9197                 /* Don't want to trigger debugging */
9198                 if (pip[1] != -1)
9199                         close(pip[1]);
9200         }
9201         if (n->npipe.pipe_backgnd == 0) {
9202                 status = waitforjob(jp);
9203                 TRACE(("evalpipe:  job done exit status %d\n", status));
9204         }
9205         INT_ON;
9206
9207         return status;
9208 }
9209
9210 /*
9211  * Controls whether the shell is interactive or not.
9212  */
9213 static void
9214 setinteractive(int on)
9215 {
9216         static smallint is_interactive;
9217
9218         if (++on == is_interactive)
9219                 return;
9220         is_interactive = on;
9221         setsignal(SIGINT);
9222         setsignal(SIGQUIT);
9223         setsignal(SIGTERM);
9224 #if !ENABLE_FEATURE_SH_EXTRA_QUIET
9225         if (is_interactive > 1) {
9226                 /* Looks like they want an interactive shell */
9227                 static smallint did_banner;
9228
9229                 if (!did_banner) {
9230                         /* note: ash and hush share this string */
9231                         out1fmt("\n\n%s %s\n"
9232                                 IF_ASH_HELP("Enter 'help' for a list of built-in commands.\n")
9233                                 "\n",
9234                                 bb_banner,
9235                                 "built-in shell (ash)"
9236                         );
9237                         did_banner = 1;
9238                 }
9239         }
9240 #endif
9241 }
9242
9243 static void
9244 optschanged(void)
9245 {
9246 #if DEBUG
9247         opentrace();
9248 #endif
9249         setinteractive(iflag);
9250         setjobctl(mflag);
9251 #if ENABLE_FEATURE_EDITING_VI
9252         if (viflag)
9253                 line_input_state->flags |= VI_MODE;
9254         else
9255                 line_input_state->flags &= ~VI_MODE;
9256 #else
9257         viflag = 0; /* forcibly keep the option off */
9258 #endif
9259 }
9260
9261 struct localvar_list {
9262         struct localvar_list *next;
9263         struct localvar *lv;
9264 };
9265
9266 static struct localvar_list *localvar_stack;
9267
9268 /*
9269  * Called after a function returns.
9270  * Interrupts must be off.
9271  */
9272 static void
9273 poplocalvars(int keep)
9274 {
9275         struct localvar_list *ll;
9276         struct localvar *lvp, *next;
9277         struct var *vp;
9278
9279         INT_OFF;
9280         ll = localvar_stack;
9281         localvar_stack = ll->next;
9282
9283         next = ll->lv;
9284         free(ll);
9285
9286         while ((lvp = next) != NULL) {
9287                 next = lvp->next;
9288                 vp = lvp->vp;
9289                 TRACE(("poplocalvar %s\n", vp ? vp->var_text : "-"));
9290                 if (keep) {
9291                         int bits = VSTRFIXED;
9292
9293                         if (lvp->flags != VUNSET) {
9294                                 if (vp->var_text == lvp->text)
9295                                         bits |= VTEXTFIXED;
9296                                 else if (!(lvp->flags & (VTEXTFIXED|VSTACK)))
9297                                         free((char*)lvp->text);
9298                         }
9299
9300                         vp->flags &= ~bits;
9301                         vp->flags |= (lvp->flags & bits);
9302
9303                         if ((vp->flags &
9304                              (VEXPORT|VREADONLY|VSTRFIXED|VUNSET)) == VUNSET)
9305                                 unsetvar(vp->var_text);
9306                 } else if (vp == NULL) {        /* $- saved */
9307                         memcpy(optlist, lvp->text, sizeof(optlist));
9308                         free((char*)lvp->text);
9309                         optschanged();
9310                 } else if (lvp->flags == VUNSET) {
9311                         vp->flags &= ~(VSTRFIXED|VREADONLY);
9312                         unsetvar(vp->var_text);
9313                 } else {
9314                         if (vp->var_func)
9315                                 vp->var_func(var_end(lvp->text));
9316                         if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0)
9317                                 free((char*)vp->var_text);
9318                         vp->flags = lvp->flags;
9319                         vp->var_text = lvp->text;
9320                 }
9321                 free(lvp);
9322         }
9323         INT_ON;
9324 }
9325
9326 /*
9327  * Create a new localvar environment.
9328  */
9329 static struct localvar_list *
9330 pushlocalvars(void)
9331 {
9332         struct localvar_list *ll;
9333
9334         INT_OFF;
9335         ll = ckzalloc(sizeof(*ll));
9336         /*ll->lv = NULL; - zalloc did it */
9337         ll->next = localvar_stack;
9338         localvar_stack = ll;
9339         INT_ON;
9340
9341         return ll->next;
9342 }
9343
9344 static void
9345 unwindlocalvars(struct localvar_list *stop)
9346 {
9347         while (localvar_stack != stop)
9348                 poplocalvars(0);
9349 }
9350
9351 static int
9352 evalfun(struct funcnode *func, int argc, char **argv, int flags)
9353 {
9354         volatile struct shparam saveparam;
9355         struct jmploc *volatile savehandler;
9356         struct jmploc jmploc;
9357         int e;
9358
9359         saveparam = shellparam;
9360         savehandler = exception_handler;
9361         e = setjmp(jmploc.loc);
9362         if (e) {
9363                 goto funcdone;
9364         }
9365         INT_OFF;
9366         exception_handler = &jmploc;
9367         shellparam.malloced = 0;
9368         func->count++;
9369         funcnest++;
9370         INT_ON;
9371         shellparam.nparam = argc - 1;
9372         shellparam.p = argv + 1;
9373 #if ENABLE_ASH_GETOPTS
9374         shellparam.optind = 1;
9375         shellparam.optoff = -1;
9376 #endif
9377         pushlocalvars();
9378         evaltree(func->n.narg.next, flags & EV_TESTED);
9379         poplocalvars(0);
9380  funcdone:
9381         INT_OFF;
9382         funcnest--;
9383         freefunc(func);
9384         freeparam(&shellparam);
9385         shellparam = saveparam;
9386         exception_handler = savehandler;
9387         INT_ON;
9388         evalskip &= ~SKIPFUNC;
9389         return e;
9390 }
9391
9392 /*
9393  * Make a variable a local variable.  When a variable is made local, it's
9394  * value and flags are saved in a localvar structure.  The saved values
9395  * will be restored when the shell function returns.  We handle the name
9396  * "-" as a special case: it makes changes to "set +-options" local
9397  * (options will be restored on return from the function).
9398  */
9399 static void
9400 mklocal(char *name)
9401 {
9402         struct localvar *lvp;
9403         struct var **vpp;
9404         struct var *vp;
9405         char *eq = strchr(name, '=');
9406
9407         INT_OFF;
9408         /* Cater for duplicate "local". Examples:
9409          * x=0; f() { local x=1; echo $x; local x; echo $x; }; f; echo $x
9410          * x=0; f() { local x=1; echo $x; local x=2; echo $x; }; f; echo $x
9411          */
9412         lvp = localvar_stack->lv;
9413         while (lvp) {
9414                 if (lvp->vp && varcmp(lvp->vp->var_text, name) == 0) {
9415                         if (eq)
9416                                 setvareq(name, 0);
9417                         /* else:
9418                          * it's a duplicate "local VAR" declaration, do nothing
9419                          */
9420                         goto ret;
9421                 }
9422                 lvp = lvp->next;
9423         }
9424
9425         lvp = ckzalloc(sizeof(*lvp));
9426         if (LONE_DASH(name)) {
9427                 char *p;
9428                 p = ckmalloc(sizeof(optlist));
9429                 lvp->text = memcpy(p, optlist, sizeof(optlist));
9430                 vp = NULL;
9431         } else {
9432                 vpp = hashvar(name);
9433                 vp = *findvar(vpp, name);
9434                 if (vp == NULL) {
9435                         /* variable did not exist yet */
9436                         if (eq)
9437                                 vp = setvareq(name, VSTRFIXED);
9438                         else
9439                                 vp = setvar(name, NULL, VSTRFIXED);
9440                         lvp->flags = VUNSET;
9441                 } else {
9442                         lvp->text = vp->var_text;
9443                         lvp->flags = vp->flags;
9444                         /* make sure neither "struct var" nor string gets freed
9445                          * during (un)setting:
9446                          */
9447                         vp->flags |= VSTRFIXED|VTEXTFIXED;
9448                         if (eq)
9449                                 setvareq(name, 0);
9450                         else
9451                                 /* "local VAR" unsets VAR: */
9452                                 setvar0(name, NULL);
9453                 }
9454         }
9455         lvp->vp = vp;
9456         lvp->next = localvar_stack->lv;
9457         localvar_stack->lv = lvp;
9458  ret:
9459         INT_ON;
9460 }
9461
9462 /*
9463  * The "local" command.
9464  */
9465 static int FAST_FUNC
9466 localcmd(int argc UNUSED_PARAM, char **argv)
9467 {
9468         char *name;
9469
9470         if (!localvar_stack)
9471                 ash_msg_and_raise_error("not in a function");
9472
9473         argv = argptr;
9474         while ((name = *argv++) != NULL) {
9475                 mklocal(name);
9476         }
9477         return 0;
9478 }
9479
9480 static int FAST_FUNC
9481 falsecmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
9482 {
9483         return 1;
9484 }
9485
9486 static int FAST_FUNC
9487 truecmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
9488 {
9489         return 0;
9490 }
9491
9492 static int FAST_FUNC
9493 execcmd(int argc UNUSED_PARAM, char **argv)
9494 {
9495         optionarg = NULL;
9496         while (nextopt("a:") != '\0')
9497                 /* nextopt() sets optionarg to "-a ARGV0" */;
9498
9499         argv = argptr;
9500         if (argv[0]) {
9501                 char *prog;
9502
9503                 iflag = 0;              /* exit on error */
9504                 mflag = 0;
9505                 optschanged();
9506                 /* We should set up signals for "exec CMD"
9507                  * the same way as for "CMD" without "exec".
9508                  * But optschanged->setinteractive->setsignal
9509                  * still thought we are a root shell. Therefore, for example,
9510                  * SIGQUIT is still set to IGN. Fix it:
9511                  */
9512                 shlvl++;
9513                 setsignal(SIGQUIT);
9514                 /*setsignal(SIGTERM); - unnecessary because of iflag=0 */
9515                 /*setsignal(SIGTSTP); - unnecessary because of mflag=0 */
9516                 /*setsignal(SIGTTOU); - unnecessary because of mflag=0 */
9517
9518                 prog = argv[0];
9519                 if (optionarg)
9520                         argv[0] = optionarg;
9521                 shellexec(prog, argv, pathval(), 0);
9522                 /* NOTREACHED */
9523         }
9524         return 0;
9525 }
9526
9527 /*
9528  * The return command.
9529  */
9530 static int FAST_FUNC
9531 returncmd(int argc UNUSED_PARAM, char **argv)
9532 {
9533         /*
9534          * If called outside a function, do what ksh does;
9535          * skip the rest of the file.
9536          */
9537         evalskip = SKIPFUNC;
9538         return argv[1] ? number(argv[1]) : exitstatus;
9539 }
9540
9541 /* Forward declarations for builtintab[] */
9542 static int breakcmd(int, char **) FAST_FUNC;
9543 static int dotcmd(int, char **) FAST_FUNC;
9544 static int evalcmd(int, char **, int) FAST_FUNC;
9545 static int exitcmd(int, char **) FAST_FUNC;
9546 static int exportcmd(int, char **) FAST_FUNC;
9547 #if ENABLE_ASH_GETOPTS
9548 static int getoptscmd(int, char **) FAST_FUNC;
9549 #endif
9550 #if ENABLE_ASH_HELP
9551 static int helpcmd(int, char **) FAST_FUNC;
9552 #endif
9553 #if MAX_HISTORY
9554 static int historycmd(int, char **) FAST_FUNC;
9555 #endif
9556 #if ENABLE_FEATURE_SH_MATH
9557 static int letcmd(int, char **) FAST_FUNC;
9558 #endif
9559 static int readcmd(int, char **) FAST_FUNC;
9560 static int setcmd(int, char **) FAST_FUNC;
9561 static int shiftcmd(int, char **) FAST_FUNC;
9562 static int timescmd(int, char **) FAST_FUNC;
9563 static int trapcmd(int, char **) FAST_FUNC;
9564 static int umaskcmd(int, char **) FAST_FUNC;
9565 static int unsetcmd(int, char **) FAST_FUNC;
9566 static int ulimitcmd(int, char **) FAST_FUNC;
9567
9568 #define BUILTIN_NOSPEC          "0"
9569 #define BUILTIN_SPECIAL         "1"
9570 #define BUILTIN_REGULAR         "2"
9571 #define BUILTIN_SPEC_REG        "3"
9572 #define BUILTIN_ASSIGN          "4"
9573 #define BUILTIN_SPEC_ASSG       "5"
9574 #define BUILTIN_REG_ASSG        "6"
9575 #define BUILTIN_SPEC_REG_ASSG   "7"
9576
9577 /* Stubs for calling non-FAST_FUNC's */
9578 #if ENABLE_ASH_ECHO
9579 static int FAST_FUNC echocmd(int argc, char **argv)   { return echo_main(argc, argv); }
9580 #endif
9581 #if ENABLE_ASH_PRINTF
9582 static int FAST_FUNC printfcmd(int argc, char **argv) { return printf_main(argc, argv); }
9583 #endif
9584 #if ENABLE_ASH_TEST || BASH_TEST2
9585 static int FAST_FUNC testcmd(int argc, char **argv)   { return test_main(argc, argv); }
9586 #endif
9587
9588 /* Keep these in proper order since it is searched via bsearch() */
9589 static const struct builtincmd builtintab[] = {
9590         { BUILTIN_SPEC_REG      "."       , dotcmd     },
9591         { BUILTIN_SPEC_REG      ":"       , truecmd    },
9592 #if ENABLE_ASH_TEST
9593         { BUILTIN_REGULAR       "["       , testcmd    },
9594 #endif
9595 #if BASH_TEST2
9596         { BUILTIN_REGULAR       "[["      , testcmd    },
9597 #endif
9598 #if ENABLE_ASH_ALIAS
9599         { BUILTIN_REG_ASSG      "alias"   , aliascmd   },
9600 #endif
9601 #if JOBS
9602         { BUILTIN_REGULAR       "bg"      , fg_bgcmd   },
9603 #endif
9604         { BUILTIN_SPEC_REG      "break"   , breakcmd   },
9605         { BUILTIN_REGULAR       "cd"      , cdcmd      },
9606         { BUILTIN_NOSPEC        "chdir"   , cdcmd      },
9607 #if ENABLE_ASH_CMDCMD
9608         { BUILTIN_REGULAR       "command" , commandcmd },
9609 #endif
9610         { BUILTIN_SPEC_REG      "continue", breakcmd   },
9611 #if ENABLE_ASH_ECHO
9612         { BUILTIN_REGULAR       "echo"    , echocmd    },
9613 #endif
9614         { BUILTIN_SPEC_REG      "eval"    , NULL       }, /*evalcmd() has a differing prototype*/
9615         { BUILTIN_SPEC_REG      "exec"    , execcmd    },
9616         { BUILTIN_SPEC_REG      "exit"    , exitcmd    },
9617         { BUILTIN_SPEC_REG_ASSG "export"  , exportcmd  },
9618         { BUILTIN_REGULAR       "false"   , falsecmd   },
9619 #if JOBS
9620         { BUILTIN_REGULAR       "fg"      , fg_bgcmd   },
9621 #endif
9622 #if ENABLE_ASH_GETOPTS
9623         { BUILTIN_REGULAR       "getopts" , getoptscmd },
9624 #endif
9625         { BUILTIN_NOSPEC        "hash"    , hashcmd    },
9626 #if ENABLE_ASH_HELP
9627         { BUILTIN_NOSPEC        "help"    , helpcmd    },
9628 #endif
9629 #if MAX_HISTORY
9630         { BUILTIN_NOSPEC        "history" , historycmd },
9631 #endif
9632 #if JOBS
9633         { BUILTIN_REGULAR       "jobs"    , jobscmd    },
9634         { BUILTIN_REGULAR       "kill"    , killcmd    },
9635 #endif
9636 #if ENABLE_FEATURE_SH_MATH
9637         { BUILTIN_NOSPEC        "let"     , letcmd     },
9638 #endif
9639         { BUILTIN_SPEC_REG_ASSG "local"   , localcmd   },
9640 #if ENABLE_ASH_PRINTF
9641         { BUILTIN_REGULAR       "printf"  , printfcmd  },
9642 #endif
9643         { BUILTIN_NOSPEC        "pwd"     , pwdcmd     },
9644         { BUILTIN_REGULAR       "read"    , readcmd    },
9645         { BUILTIN_SPEC_REG_ASSG "readonly", exportcmd  },
9646         { BUILTIN_SPEC_REG      "return"  , returncmd  },
9647         { BUILTIN_SPEC_REG      "set"     , setcmd     },
9648         { BUILTIN_SPEC_REG      "shift"   , shiftcmd   },
9649 #if BASH_SOURCE
9650         { BUILTIN_SPEC_REG      "source"  , dotcmd     },
9651 #endif
9652 #if ENABLE_ASH_TEST
9653         { BUILTIN_REGULAR       "test"    , testcmd    },
9654 #endif
9655         { BUILTIN_SPEC_REG      "times"   , timescmd   },
9656         { BUILTIN_SPEC_REG      "trap"    , trapcmd    },
9657         { BUILTIN_REGULAR       "true"    , truecmd    },
9658         { BUILTIN_NOSPEC        "type"    , typecmd    },
9659         { BUILTIN_NOSPEC        "ulimit"  , ulimitcmd  },
9660         { BUILTIN_REGULAR       "umask"   , umaskcmd   },
9661 #if ENABLE_ASH_ALIAS
9662         { BUILTIN_REGULAR       "unalias" , unaliascmd },
9663 #endif
9664         { BUILTIN_SPEC_REG      "unset"   , unsetcmd   },
9665         { BUILTIN_REGULAR       "wait"    , waitcmd    },
9666 };
9667
9668 /* Should match the above table! */
9669 #define COMMANDCMD (builtintab + \
9670         /* . : */       2 + \
9671         /* [ */         1 * ENABLE_ASH_TEST + \
9672         /* [[ */        1 * BASH_TEST2 + \
9673         /* alias */     1 * ENABLE_ASH_ALIAS + \
9674         /* bg */        1 * ENABLE_ASH_JOB_CONTROL + \
9675         /* break cd cddir  */   3)
9676 #define EVALCMD (COMMANDCMD + \
9677         /* command */   1 * ENABLE_ASH_CMDCMD + \
9678         /* continue */  1 + \
9679         /* echo */      1 * ENABLE_ASH_ECHO + \
9680         0)
9681 #define EXECCMD (EVALCMD + \
9682         /* eval */      1)
9683
9684 /*
9685  * Search the table of builtin commands.
9686  */
9687 static int
9688 pstrcmp1(const void *a, const void *b)
9689 {
9690         return strcmp((char*)a, *(char**)b + 1);
9691 }
9692 static struct builtincmd *
9693 find_builtin(const char *name)
9694 {
9695         struct builtincmd *bp;
9696
9697         bp = bsearch(
9698                 name, builtintab, ARRAY_SIZE(builtintab), sizeof(builtintab[0]),
9699                 pstrcmp1
9700         );
9701         return bp;
9702 }
9703
9704 /*
9705  * Execute a simple command.
9706  */
9707 static int
9708 isassignment(const char *p)
9709 {
9710         const char *q = endofname(p);
9711         if (p == q)
9712                 return 0;
9713         return *q == '=';
9714 }
9715 static int FAST_FUNC
9716 bltincmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
9717 {
9718         /* Preserve exitstatus of a previous possible redirection
9719          * as POSIX mandates */
9720         return back_exitstatus;
9721 }
9722 static int
9723 evalcommand(union node *cmd, int flags)
9724 {
9725         static const struct builtincmd null_bltin = {
9726                 "\0\0", bltincmd /* why three NULs? */
9727         };
9728         struct localvar_list *localvar_stop;
9729         struct redirtab *redir_stop;
9730         struct stackmark smark;
9731         union node *argp;
9732         struct arglist arglist;
9733         struct arglist varlist;
9734         char **argv;
9735         int argc;
9736         const struct strlist *sp;
9737         struct cmdentry cmdentry;
9738         struct job *jp;
9739         char *lastarg;
9740         const char *path;
9741         int spclbltin;
9742         int status;
9743         char **nargv;
9744         smallint cmd_is_exec;
9745
9746         /* First expand the arguments. */
9747         TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags));
9748         setstackmark(&smark);
9749         localvar_stop = pushlocalvars();
9750         back_exitstatus = 0;
9751
9752         cmdentry.cmdtype = CMDBUILTIN;
9753         cmdentry.u.cmd = &null_bltin;
9754         varlist.lastp = &varlist.list;
9755         *varlist.lastp = NULL;
9756         arglist.lastp = &arglist.list;
9757         *arglist.lastp = NULL;
9758
9759         argc = 0;
9760         if (cmd->ncmd.args) {
9761                 struct builtincmd *bcmd;
9762                 smallint pseudovarflag;
9763
9764                 bcmd = find_builtin(cmd->ncmd.args->narg.text);
9765                 pseudovarflag = bcmd && IS_BUILTIN_ASSIGN(bcmd);
9766
9767                 for (argp = cmd->ncmd.args; argp; argp = argp->narg.next) {
9768                         struct strlist **spp;
9769
9770                         spp = arglist.lastp;
9771                         if (pseudovarflag && isassignment(argp->narg.text))
9772                                 expandarg(argp, &arglist, EXP_VARTILDE);
9773                         else
9774                                 expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
9775
9776                         for (sp = *spp; sp; sp = sp->next)
9777                                 argc++;
9778                 }
9779         }
9780
9781         /* Reserve one extra spot at the front for shellexec. */
9782         nargv = stalloc(sizeof(char *) * (argc + 2));
9783         argv = ++nargv;
9784         for (sp = arglist.list; sp; sp = sp->next) {
9785                 TRACE(("evalcommand arg: %s\n", sp->text));
9786                 *nargv++ = sp->text;
9787         }
9788         *nargv = NULL;
9789
9790         lastarg = NULL;
9791         if (iflag && funcnest == 0 && argc > 0)
9792                 lastarg = nargv[-1];
9793
9794         expredir(cmd->ncmd.redirect);
9795         redir_stop = pushredir(cmd->ncmd.redirect);
9796         preverrout_fd = 2;
9797         status = redirectsafe(cmd->ncmd.redirect, REDIR_PUSH | REDIR_SAVEFD2);
9798
9799         path = vpath.var_text;
9800         for (argp = cmd->ncmd.assign; argp; argp = argp->narg.next) {
9801                 struct strlist **spp;
9802                 char *p;
9803
9804                 spp = varlist.lastp;
9805                 expandarg(argp, &varlist, EXP_VARTILDE);
9806
9807                 mklocal((*spp)->text);
9808
9809                 /*
9810                  * Modify the command lookup path, if a PATH= assignment
9811                  * is present
9812                  */
9813                 p = (*spp)->text;
9814                 if (varcmp(p, path) == 0)
9815                         path = p;
9816         }
9817
9818         /* Print the command if xflag is set. */
9819         if (xflag) {
9820                 const char *pfx = "";
9821
9822                 fdprintf(preverrout_fd, "%s", expandstr(ps4val(), DQSYNTAX));
9823
9824                 sp = varlist.list;
9825                 while (sp) {
9826                         char *varval = sp->text;
9827                         char *eq = strchrnul(varval, '=');
9828                         if (*eq)
9829                                 eq++;
9830                         fdprintf(preverrout_fd, "%s%.*s%s",
9831                                 pfx,
9832                                 (int)(eq - varval), varval,
9833                                 maybe_single_quote(eq)
9834                         );
9835                         sp = sp->next;
9836                         pfx = " ";
9837                 }
9838
9839                 sp = arglist.list;
9840                 while (sp) {
9841                         fdprintf(preverrout_fd, "%s%s",
9842                                 pfx,
9843                                 /* always quote if matches reserved word: */
9844                                 findkwd(sp->text)
9845                                 ? single_quote(sp->text)
9846                                 : maybe_single_quote(sp->text)
9847                         );
9848                         sp = sp->next;
9849                         pfx = " ";
9850                 }
9851                 safe_write(preverrout_fd, "\n", 1);
9852         }
9853
9854         cmd_is_exec = 0;
9855         spclbltin = -1;
9856
9857         /* Now locate the command. */
9858         if (argc) {
9859                 int cmd_flag = DO_ERR;
9860 #if ENABLE_ASH_CMDCMD
9861                 const char *oldpath = path + 5;
9862 #endif
9863                 path += 5;
9864                 for (;;) {
9865                         find_command(argv[0], &cmdentry, cmd_flag, path);
9866                         if (cmdentry.cmdtype == CMDUNKNOWN) {
9867                                 flush_stdout_stderr();
9868                                 status = 127;
9869                                 goto bail;
9870                         }
9871
9872                         /* implement bltin and command here */
9873                         if (cmdentry.cmdtype != CMDBUILTIN)
9874                                 break;
9875                         if (spclbltin < 0)
9876                                 spclbltin = IS_BUILTIN_SPECIAL(cmdentry.u.cmd);
9877                         if (cmdentry.u.cmd == EXECCMD)
9878                                 cmd_is_exec = 1;
9879 #if ENABLE_ASH_CMDCMD
9880                         if (cmdentry.u.cmd == COMMANDCMD) {
9881                                 path = oldpath;
9882                                 nargv = parse_command_args(argv, &path);
9883                                 if (!nargv)
9884                                         break;
9885                                 /* It's "command [-p] PROG ARGS" (that is, no -Vv).
9886                                  * nargv => "PROG". path is updated if -p.
9887                                  */
9888                                 argc -= nargv - argv;
9889                                 argv = nargv;
9890                                 cmd_flag |= DO_NOFUNC;
9891                         } else
9892 #endif
9893                                 break;
9894                 }
9895         }
9896
9897         if (status) {
9898  bail:
9899                 exitstatus = status;
9900
9901                 /* We have a redirection error. */
9902                 if (spclbltin > 0)
9903                         raise_exception(EXERROR);
9904
9905                 goto out;
9906         }
9907
9908         /* Execute the command. */
9909         switch (cmdentry.cmdtype) {
9910         default: {
9911
9912 #if ENABLE_FEATURE_SH_NOFORK
9913 /* (1) BUG: if variables are set, we need to fork, or save/restore them
9914  *     around run_nofork_applet() call.
9915  * (2) Should this check also be done in forkshell()?
9916  *     (perhaps it should, so that "VAR=VAL nofork" at least avoids exec...)
9917  */
9918                 /* find_command() encodes applet_no as (-2 - applet_no) */
9919                 int applet_no = (- cmdentry.u.index - 2);
9920                 if (applet_no >= 0 && APPLET_IS_NOFORK(applet_no)) {
9921                         listsetvar(varlist.list, VEXPORT|VSTACK);
9922                         /* run <applet>_main() */
9923 //FIXME: do we need INT_OFF / INT_ON here?
9924 //wouldn't open files and allocations leak on ^C otherwise?
9925                         status = run_nofork_applet(applet_no, argv);
9926                         break;
9927                 }
9928 #endif
9929                 /* Can we avoid forking? For example, very last command
9930                  * in a script or a subshell does not need forking,
9931                  * we can just exec it.
9932                  */
9933                 if (!(flags & EV_EXIT) || may_have_traps) {
9934                         /* No, forking off a child is necessary */
9935                         INT_OFF;
9936                         get_tty_state();
9937                         jp = makejob(/*cmd,*/ 1);
9938                         if (forkshell(jp, cmd, FORK_FG) != 0) {
9939                                 /* parent */
9940                                 status = waitforjob(jp);
9941                                 INT_ON;
9942                                 TRACE(("forked child exited with %d\n", status));
9943                                 break;
9944                         }
9945                         /* child */
9946                         FORCE_INT_ON;
9947                         /* fall through to exec'ing external program */
9948                 }
9949                 listsetvar(varlist.list, VEXPORT|VSTACK);
9950                 shellexec(argv[0], argv, path, cmdentry.u.index);
9951                 /* NOTREACHED */
9952         } /* default */
9953         case CMDBUILTIN:
9954                 if (spclbltin > 0 || argc == 0) {
9955                         poplocalvars(1);
9956                         if (cmd_is_exec && argc > 1)
9957                                 listsetvar(varlist.list, VEXPORT);
9958                 }
9959
9960                 /* Tight loop with builtins only:
9961                  * "while kill -0 $child; do true; done"
9962                  * will never exit even if $child died, unless we do this
9963                  * to reap the zombie and make kill detect that it's gone: */
9964                 dowait(DOWAIT_NONBLOCK, NULL);
9965
9966                 if (evalbltin(cmdentry.u.cmd, argc, argv, flags)) {
9967                         if (exception_type == EXERROR && spclbltin <= 0) {
9968                                 FORCE_INT_ON;
9969                                 goto readstatus;
9970                         }
9971  raise:
9972                         longjmp(exception_handler->loc, 1);
9973                 }
9974                 goto readstatus;
9975
9976         case CMDFUNCTION:
9977                 poplocalvars(1);
9978                 /* See above for the rationale */
9979                 dowait(DOWAIT_NONBLOCK, NULL);
9980                 if (evalfun(cmdentry.u.func, argc, argv, flags))
9981                         goto raise;
9982  readstatus:
9983                 status = exitstatus;
9984                 break;
9985         } /* switch */
9986
9987  out:
9988         if (cmd->ncmd.redirect)
9989                 popredir(/*drop:*/ cmd_is_exec);
9990         unwindredir(redir_stop);
9991         unwindlocalvars(localvar_stop);
9992         if (lastarg) {
9993                 /* dsl: I think this is intended to be used to support
9994                  * '_' in 'vi' command mode during line editing...
9995                  * However I implemented that within libedit itself.
9996                  */
9997                 setvar0("_", lastarg);
9998         }
9999         popstackmark(&smark);
10000
10001         return status;
10002 }
10003
10004 static int
10005 evalbltin(const struct builtincmd *cmd, int argc, char **argv, int flags)
10006 {
10007         char *volatile savecmdname;
10008         struct jmploc *volatile savehandler;
10009         struct jmploc jmploc;
10010         int status;
10011         int i;
10012
10013         savecmdname = commandname;
10014         savehandler = exception_handler;
10015         i = setjmp(jmploc.loc);
10016         if (i)
10017                 goto cmddone;
10018         exception_handler = &jmploc;
10019         commandname = argv[0];
10020         argptr = argv + 1;
10021         optptr = NULL;                  /* initialize nextopt */
10022         if (cmd == EVALCMD)
10023                 status = evalcmd(argc, argv, flags);
10024         else
10025                 status = (*cmd->builtin)(argc, argv);
10026         flush_stdout_stderr();
10027         status |= ferror(stdout);
10028         exitstatus = status;
10029  cmddone:
10030         clearerr(stdout);
10031         commandname = savecmdname;
10032         exception_handler = savehandler;
10033
10034         return i;
10035 }
10036
10037 static int
10038 goodname(const char *p)
10039 {
10040         return endofname(p)[0] == '\0';
10041 }
10042
10043
10044 /*
10045  * Search for a command.  This is called before we fork so that the
10046  * location of the command will be available in the parent as well as
10047  * the child.  The check for "goodname" is an overly conservative
10048  * check that the name will not be subject to expansion.
10049  */
10050 static void
10051 prehash(union node *n)
10052 {
10053         struct cmdentry entry;
10054
10055         if (n->type == NCMD && n->ncmd.args && goodname(n->ncmd.args->narg.text))
10056                 find_command(n->ncmd.args->narg.text, &entry, 0, pathval());
10057 }
10058
10059
10060 /* ============ Builtin commands
10061  *
10062  * Builtin commands whose functions are closely tied to evaluation
10063  * are implemented here.
10064  */
10065
10066 /*
10067  * Handle break and continue commands.  Break, continue, and return are
10068  * all handled by setting the evalskip flag.  The evaluation routines
10069  * above all check this flag, and if it is set they start skipping
10070  * commands rather than executing them.  The variable skipcount is
10071  * the number of loops to break/continue, or the number of function
10072  * levels to return.  (The latter is always 1.)  It should probably
10073  * be an error to break out of more loops than exist, but it isn't
10074  * in the standard shell so we don't make it one here.
10075  */
10076 static int FAST_FUNC
10077 breakcmd(int argc UNUSED_PARAM, char **argv)
10078 {
10079         int n = argv[1] ? number(argv[1]) : 1;
10080
10081         if (n <= 0)
10082                 ash_msg_and_raise_error(msg_illnum, argv[1]);
10083         if (n > loopnest)
10084                 n = loopnest;
10085         if (n > 0) {
10086                 evalskip = (**argv == 'c') ? SKIPCONT : SKIPBREAK;
10087                 skipcount = n;
10088         }
10089         return 0;
10090 }
10091
10092
10093 /*
10094  * This implements the input routines used by the parser.
10095  */
10096
10097 enum {
10098         INPUT_PUSH_FILE = 1,
10099         INPUT_NOFILE_OK = 2,
10100 };
10101
10102 static smallint checkkwd;
10103 /* values of checkkwd variable */
10104 #define CHKALIAS        0x1
10105 #define CHKKWD          0x2
10106 #define CHKNL           0x4
10107 #define CHKEOFMARK      0x8
10108
10109 /*
10110  * Push a string back onto the input at this current parsefile level.
10111  * We handle aliases this way.
10112  */
10113 #if !ENABLE_ASH_ALIAS
10114 #define pushstring(s, ap) pushstring(s)
10115 #endif
10116 static void
10117 pushstring(char *s, struct alias *ap)
10118 {
10119         struct strpush *sp;
10120         int len;
10121
10122         len = strlen(s);
10123         INT_OFF;
10124         if (g_parsefile->strpush) {
10125                 sp = ckzalloc(sizeof(*sp));
10126                 sp->prev = g_parsefile->strpush;
10127         } else {
10128                 sp = &(g_parsefile->basestrpush);
10129         }
10130         g_parsefile->strpush = sp;
10131         sp->prev_string = g_parsefile->next_to_pgetc;
10132         sp->prev_left_in_line = g_parsefile->left_in_line;
10133         sp->unget = g_parsefile->unget;
10134         memcpy(sp->lastc, g_parsefile->lastc, sizeof(sp->lastc));
10135 #if ENABLE_ASH_ALIAS
10136         sp->ap = ap;
10137         if (ap) {
10138                 ap->flag |= ALIASINUSE;
10139                 sp->string = s;
10140         }
10141 #endif
10142         g_parsefile->next_to_pgetc = s;
10143         g_parsefile->left_in_line = len;
10144         g_parsefile->unget = 0;
10145         INT_ON;
10146 }
10147
10148 static void
10149 popstring(void)
10150 {
10151         struct strpush *sp = g_parsefile->strpush;
10152
10153         INT_OFF;
10154 #if ENABLE_ASH_ALIAS
10155         if (sp->ap) {
10156                 if (g_parsefile->next_to_pgetc[-1] == ' '
10157                  || g_parsefile->next_to_pgetc[-1] == '\t'
10158                 ) {
10159                         checkkwd |= CHKALIAS;
10160                 }
10161                 if (sp->string != sp->ap->val) {
10162                         free(sp->string);
10163                 }
10164                 sp->ap->flag &= ~ALIASINUSE;
10165                 if (sp->ap->flag & ALIASDEAD) {
10166                         unalias(sp->ap->name);
10167                 }
10168         }
10169 #endif
10170         g_parsefile->next_to_pgetc = sp->prev_string;
10171         g_parsefile->left_in_line = sp->prev_left_in_line;
10172         g_parsefile->unget = sp->unget;
10173         memcpy(g_parsefile->lastc, sp->lastc, sizeof(sp->lastc));
10174         g_parsefile->strpush = sp->prev;
10175         if (sp != &(g_parsefile->basestrpush))
10176                 free(sp);
10177         INT_ON;
10178 }
10179
10180 static int
10181 preadfd(void)
10182 {
10183         int nr;
10184         char *buf = g_parsefile->buf;
10185
10186         g_parsefile->next_to_pgetc = buf;
10187 #if ENABLE_FEATURE_EDITING
10188  retry:
10189         if (!iflag || g_parsefile->pf_fd != STDIN_FILENO)
10190                 nr = nonblock_immune_read(g_parsefile->pf_fd, buf, IBUFSIZ - 1);
10191         else {
10192 # if ENABLE_ASH_IDLE_TIMEOUT
10193                 int timeout = -1;
10194                 if (iflag) {
10195                         const char *tmout_var = lookupvar("TMOUT");
10196                         if (tmout_var) {
10197                                 timeout = atoi(tmout_var) * 1000;
10198                                 if (timeout <= 0)
10199                                         timeout = -1;
10200                         }
10201                 }
10202                 line_input_state->timeout = timeout;
10203 # endif
10204 # if ENABLE_FEATURE_TAB_COMPLETION
10205                 line_input_state->path_lookup = pathval();
10206 # endif
10207                 reinit_unicode_for_ash();
10208                 nr = read_line_input(line_input_state, cmdedit_prompt, buf, IBUFSIZ);
10209                 if (nr == 0) {
10210                         /* ^C pressed, "convert" to SIGINT */
10211                         write(STDOUT_FILENO, "^C", 2);
10212                         if (trap[SIGINT]) {
10213                                 buf[0] = '\n';
10214                                 buf[1] = '\0';
10215                                 raise(SIGINT);
10216                                 return 1;
10217                         }
10218                         exitstatus = 128 + SIGINT;
10219                         bb_putchar('\n');
10220                         goto retry;
10221                 }
10222                 if (nr < 0) {
10223                         if (errno == 0) {
10224                                 /* Ctrl+D pressed */
10225                                 nr = 0;
10226                         }
10227 # if ENABLE_ASH_IDLE_TIMEOUT
10228                         else if (errno == EAGAIN && timeout > 0) {
10229                                 puts("\007timed out waiting for input: auto-logout");
10230                                 exitshell();
10231                         }
10232 # endif
10233                 }
10234         }
10235 #else
10236         nr = nonblock_immune_read(g_parsefile->pf_fd, buf, IBUFSIZ - 1);
10237 #endif
10238
10239 #if 0 /* disabled: nonblock_immune_read() handles this problem */
10240         if (nr < 0) {
10241                 if (parsefile->fd == 0 && errno == EWOULDBLOCK) {
10242                         int flags = fcntl(0, F_GETFL);
10243                         if (flags >= 0 && (flags & O_NONBLOCK)) {
10244                                 flags &= ~O_NONBLOCK;
10245                                 if (fcntl(0, F_SETFL, flags) >= 0) {
10246                                         out2str("sh: turning off NDELAY mode\n");
10247                                         goto retry;
10248                                 }
10249                         }
10250                 }
10251         }
10252 #endif
10253         return nr;
10254 }
10255
10256 /*
10257  * Refill the input buffer and return the next input character:
10258  *
10259  * 1) If a string was pushed back on the input, pop it;
10260  * 2) If an EOF was pushed back (g_parsefile->left_in_line < -BIGNUM)
10261  *    or we are reading from a string so we can't refill the buffer,
10262  *    return EOF.
10263  * 3) If there is more stuff in this buffer, use it else call read to fill it.
10264  * 4) Process input up to the next newline, deleting nul characters.
10265  */
10266 //#define pgetc_debug(...) bb_error_msg(__VA_ARGS__)
10267 #define pgetc_debug(...) ((void)0)
10268 static int pgetc(void);
10269 static int
10270 preadbuffer(void)
10271 {
10272         char *q;
10273         int more;
10274
10275         if (g_parsefile->strpush) {
10276 #if ENABLE_ASH_ALIAS
10277                 if (g_parsefile->left_in_line == -1
10278                  && g_parsefile->strpush->ap
10279                  && g_parsefile->next_to_pgetc[-1] != ' '
10280                  && g_parsefile->next_to_pgetc[-1] != '\t'
10281                 ) {
10282                         pgetc_debug("preadbuffer PEOA");
10283                         return PEOA;
10284                 }
10285 #endif
10286                 popstring();
10287                 return pgetc();
10288         }
10289         /* on both branches above g_parsefile->left_in_line < 0.
10290          * "pgetc" needs refilling.
10291          */
10292
10293         /* -90 is our -BIGNUM. Below we use -99 to mark "EOF on read",
10294          * pungetc() may increment it a few times.
10295          * Assuming it won't increment it to less than -90.
10296          */
10297         if (g_parsefile->left_in_line < -90 || g_parsefile->buf == NULL) {
10298                 pgetc_debug("preadbuffer PEOF1");
10299                 /* even in failure keep left_in_line and next_to_pgetc
10300                  * in lock step, for correct multi-layer pungetc.
10301                  * left_in_line was decremented before preadbuffer(),
10302                  * must inc next_to_pgetc: */
10303                 g_parsefile->next_to_pgetc++;
10304                 return PEOF;
10305         }
10306
10307         more = g_parsefile->left_in_buffer;
10308         if (more <= 0) {
10309                 flush_stdout_stderr();
10310  again:
10311                 more = preadfd();
10312                 if (more <= 0) {
10313                         /* don't try reading again */
10314                         g_parsefile->left_in_line = -99;
10315                         pgetc_debug("preadbuffer PEOF2");
10316                         g_parsefile->next_to_pgetc++;
10317                         return PEOF;
10318                 }
10319         }
10320
10321         /* Find out where's the end of line.
10322          * Set g_parsefile->left_in_line
10323          * and g_parsefile->left_in_buffer acordingly.
10324          * NUL chars are deleted.
10325          */
10326         q = g_parsefile->next_to_pgetc;
10327         for (;;) {
10328                 char c;
10329
10330                 more--;
10331
10332                 c = *q;
10333                 if (c == '\0') {
10334                         memmove(q, q + 1, more);
10335                 } else {
10336                         q++;
10337                         if (c == '\n') {
10338                                 g_parsefile->left_in_line = q - g_parsefile->next_to_pgetc - 1;
10339                                 break;
10340                         }
10341                 }
10342
10343                 if (more <= 0) {
10344                         g_parsefile->left_in_line = q - g_parsefile->next_to_pgetc - 1;
10345                         if (g_parsefile->left_in_line < 0)
10346                                 goto again;
10347                         break;
10348                 }
10349         }
10350         g_parsefile->left_in_buffer = more;
10351
10352         if (vflag) {
10353                 char save = *q;
10354                 *q = '\0';
10355                 out2str(g_parsefile->next_to_pgetc);
10356                 *q = save;
10357         }
10358
10359         pgetc_debug("preadbuffer at %d:%p'%s'",
10360                         g_parsefile->left_in_line,
10361                         g_parsefile->next_to_pgetc,
10362                         g_parsefile->next_to_pgetc);
10363         return (unsigned char)*g_parsefile->next_to_pgetc++;
10364 }
10365
10366 static void
10367 nlprompt(void)
10368 {
10369         g_parsefile->linno++;
10370         setprompt_if(doprompt, 2);
10371 }
10372 static void
10373 nlnoprompt(void)
10374 {
10375         g_parsefile->linno++;
10376         needprompt = doprompt;
10377 }
10378
10379 static int
10380 pgetc(void)
10381 {
10382         int c;
10383
10384         pgetc_debug("pgetc at %d:%p'%s'",
10385                         g_parsefile->left_in_line,
10386                         g_parsefile->next_to_pgetc,
10387                         g_parsefile->next_to_pgetc);
10388         if (g_parsefile->unget)
10389                 return g_parsefile->lastc[--g_parsefile->unget];
10390
10391         if (--g_parsefile->left_in_line >= 0)
10392                 c = (unsigned char)*g_parsefile->next_to_pgetc++;
10393         else
10394                 c = preadbuffer();
10395
10396         g_parsefile->lastc[1] = g_parsefile->lastc[0];
10397         g_parsefile->lastc[0] = c;
10398
10399         return c;
10400 }
10401
10402 #if ENABLE_ASH_ALIAS
10403 static int
10404 pgetc_without_PEOA(void)
10405 {
10406         int c;
10407         do {
10408                 pgetc_debug("pgetc at %d:%p'%s'",
10409                                 g_parsefile->left_in_line,
10410                                 g_parsefile->next_to_pgetc,
10411                                 g_parsefile->next_to_pgetc);
10412                 c = pgetc();
10413         } while (c == PEOA);
10414         return c;
10415 }
10416 #else
10417 # define pgetc_without_PEOA() pgetc()
10418 #endif
10419
10420 /*
10421  * Undo a call to pgetc.  Only two characters may be pushed back.
10422  * PEOF may be pushed back.
10423  */
10424 static void
10425 pungetc(void)
10426 {
10427         g_parsefile->unget++;
10428 }
10429
10430 /* This one eats backslash+newline */
10431 static int
10432 pgetc_eatbnl(void)
10433 {
10434         int c;
10435
10436         while ((c = pgetc()) == '\\') {
10437                 if (pgetc() != '\n') {
10438                         pungetc();
10439                         break;
10440                 }
10441
10442                 nlprompt();
10443         }
10444
10445         return c;
10446 }
10447
10448 /*
10449  * To handle the "." command, a stack of input files is used.  Pushfile
10450  * adds a new entry to the stack and popfile restores the previous level.
10451  */
10452 static void
10453 pushfile(void)
10454 {
10455         struct parsefile *pf;
10456
10457         pf = ckzalloc(sizeof(*pf));
10458         pf->prev = g_parsefile;
10459         pf->pf_fd = -1;
10460         /*pf->strpush = NULL; - ckzalloc did it */
10461         /*pf->basestrpush.prev = NULL;*/
10462         /*pf->unget = 0;*/
10463         g_parsefile = pf;
10464 }
10465
10466 static void
10467 popfile(void)
10468 {
10469         struct parsefile *pf = g_parsefile;
10470
10471         if (pf == &basepf)
10472                 return;
10473
10474         INT_OFF;
10475         if (pf->pf_fd >= 0)
10476                 close(pf->pf_fd);
10477         free(pf->buf);
10478         while (pf->strpush)
10479                 popstring();
10480         g_parsefile = pf->prev;
10481         free(pf);
10482         INT_ON;
10483 }
10484
10485 /*
10486  * Return to top level.
10487  */
10488 static void
10489 popallfiles(void)
10490 {
10491         while (g_parsefile != &basepf)
10492                 popfile();
10493 }
10494
10495 /*
10496  * Close the file(s) that the shell is reading commands from.  Called
10497  * after a fork is done.
10498  */
10499 static void
10500 closescript(void)
10501 {
10502         popallfiles();
10503         if (g_parsefile->pf_fd > 0) {
10504                 close(g_parsefile->pf_fd);
10505                 g_parsefile->pf_fd = 0;
10506         }
10507 }
10508
10509 /*
10510  * Like setinputfile, but takes an open file descriptor.  Call this with
10511  * interrupts off.
10512  */
10513 static void
10514 setinputfd(int fd, int push)
10515 {
10516         if (push) {
10517                 pushfile();
10518                 g_parsefile->buf = NULL;
10519         }
10520         g_parsefile->pf_fd = fd;
10521         if (g_parsefile->buf == NULL)
10522                 g_parsefile->buf = ckmalloc(IBUFSIZ);
10523         g_parsefile->left_in_buffer = 0;
10524         g_parsefile->left_in_line = 0;
10525         g_parsefile->linno = 1;
10526 }
10527
10528 /*
10529  * Set the input to take input from a file.  If push is set, push the
10530  * old input onto the stack first.
10531  */
10532 static int
10533 setinputfile(const char *fname, int flags)
10534 {
10535         int fd;
10536
10537         INT_OFF;
10538         fd = open(fname, O_RDONLY);
10539         if (fd < 0) {
10540                 if (flags & INPUT_NOFILE_OK)
10541                         goto out;
10542                 exitstatus = 127;
10543                 ash_msg_and_raise_error("can't open '%s'", fname);
10544         }
10545         if (fd < 10)
10546                 fd = savefd(fd);
10547         else
10548                 close_on_exec_on(fd);
10549         setinputfd(fd, flags & INPUT_PUSH_FILE);
10550  out:
10551         INT_ON;
10552         return fd;
10553 }
10554
10555 /*
10556  * Like setinputfile, but takes input from a string.
10557  */
10558 static void
10559 setinputstring(char *string)
10560 {
10561         INT_OFF;
10562         pushfile();
10563         g_parsefile->next_to_pgetc = string;
10564         g_parsefile->left_in_line = strlen(string);
10565         g_parsefile->buf = NULL;
10566         g_parsefile->linno = 1;
10567         INT_ON;
10568 }
10569
10570
10571 /*
10572  * Routines to check for mail.
10573  */
10574
10575 #if ENABLE_ASH_MAIL
10576
10577 /* Hash of mtimes of mailboxes */
10578 static unsigned mailtime_hash;
10579 /* Set if MAIL or MAILPATH is changed. */
10580 static smallint mail_var_path_changed;
10581
10582 /*
10583  * Print appropriate message(s) if mail has arrived.
10584  * If mail_var_path_changed is set,
10585  * then the value of MAIL has mail_var_path_changed,
10586  * so we just update the values.
10587  */
10588 static void
10589 chkmail(void)
10590 {
10591         const char *mpath;
10592         char *p;
10593         char *q;
10594         unsigned new_hash;
10595         struct stackmark smark;
10596         struct stat statb;
10597
10598         setstackmark(&smark);
10599         mpath = mpathset() ? mpathval() : mailval();
10600         new_hash = 0;
10601         for (;;) {
10602                 p = path_advance(&mpath, nullstr);
10603                 if (p == NULL)
10604                         break;
10605                 if (*p == '\0')
10606                         continue;
10607                 for (q = p; *q; q++)
10608                         continue;
10609 #if DEBUG
10610                 if (q[-1] != '/')
10611                         abort();
10612 #endif
10613                 q[-1] = '\0';                   /* delete trailing '/' */
10614                 if (stat(p, &statb) < 0) {
10615                         continue;
10616                 }
10617                 /* Very simplistic "hash": just a sum of all mtimes */
10618                 new_hash += (unsigned)statb.st_mtime;
10619         }
10620         if (!mail_var_path_changed && mailtime_hash != new_hash) {
10621                 if (mailtime_hash != 0)
10622                         out2str("you have mail\n");
10623                 mailtime_hash = new_hash;
10624         }
10625         mail_var_path_changed = 0;
10626         popstackmark(&smark);
10627 }
10628
10629 static void FAST_FUNC
10630 changemail(const char *val UNUSED_PARAM)
10631 {
10632         mail_var_path_changed = 1;
10633 }
10634
10635 #endif /* ASH_MAIL */
10636
10637
10638 /* ============ ??? */
10639
10640 /*
10641  * Set the shell parameters.
10642  */
10643 static void
10644 setparam(char **argv)
10645 {
10646         char **newparam;
10647         char **ap;
10648         int nparam;
10649
10650         for (nparam = 0; argv[nparam]; nparam++)
10651                 continue;
10652         ap = newparam = ckmalloc((nparam + 1) * sizeof(*ap));
10653         while (*argv) {
10654                 *ap++ = ckstrdup(*argv++);
10655         }
10656         *ap = NULL;
10657         freeparam(&shellparam);
10658         shellparam.malloced = 1;
10659         shellparam.nparam = nparam;
10660         shellparam.p = newparam;
10661 #if ENABLE_ASH_GETOPTS
10662         shellparam.optind = 1;
10663         shellparam.optoff = -1;
10664 #endif
10665 }
10666
10667 /*
10668  * Process shell options.  The global variable argptr contains a pointer
10669  * to the argument list; we advance it past the options.
10670  *
10671  * SUSv3 section 2.8.1 "Consequences of Shell Errors" says:
10672  * For a non-interactive shell, an error condition encountered
10673  * by a special built-in ... shall cause the shell to write a diagnostic message
10674  * to standard error and exit as shown in the following table:
10675  * Error                                           Special Built-In
10676  * ...
10677  * Utility syntax error (option or operand error)  Shall exit
10678  * ...
10679  * However, in bug 1142 (http://busybox.net/bugs/view.php?id=1142)
10680  * we see that bash does not do that (set "finishes" with error code 1 instead,
10681  * and shell continues), and people rely on this behavior!
10682  * Testcase:
10683  * set -o barfoo 2>/dev/null
10684  * echo $?
10685  *
10686  * Oh well. Let's mimic that.
10687  */
10688 static int
10689 plus_minus_o(char *name, int val)
10690 {
10691         int i;
10692
10693         if (name) {
10694                 for (i = 0; i < NOPTS; i++) {
10695                         if (strcmp(name, optnames(i)) == 0) {
10696                                 optlist[i] = val;
10697                                 return 0;
10698                         }
10699                 }
10700                 ash_msg("illegal option %co %s", val ? '-' : '+', name);
10701                 return 1;
10702         }
10703         for (i = 0; i < NOPTS; i++) {
10704                 if (val) {
10705                         out1fmt("%-16s%s\n", optnames(i), optlist[i] ? "on" : "off");
10706                 } else {
10707                         out1fmt("set %co %s\n", optlist[i] ? '-' : '+', optnames(i));
10708                 }
10709         }
10710         return 0;
10711 }
10712 static void
10713 setoption(int flag, int val)
10714 {
10715         int i;
10716
10717         for (i = 0; i < NOPTS; i++) {
10718                 if (optletters(i) == flag) {
10719                         optlist[i] = val;
10720                         return;
10721                 }
10722         }
10723         ash_msg_and_raise_error("illegal option %c%c", val ? '-' : '+', flag);
10724         /* NOTREACHED */
10725 }
10726 static int
10727 options(int cmdline, int *login_sh)
10728 {
10729         char *p;
10730         int val;
10731         int c;
10732
10733         if (cmdline)
10734                 minusc = NULL;
10735         while ((p = *argptr) != NULL) {
10736                 c = *p++;
10737                 if (c != '-' && c != '+')
10738                         break;
10739                 argptr++;
10740                 val = 0; /* val = 0 if c == '+' */
10741                 if (c == '-') {
10742                         val = 1;
10743                         if (p[0] == '\0' || LONE_DASH(p)) {
10744                                 if (!cmdline) {
10745                                         /* "-" means turn off -x and -v */
10746                                         if (p[0] == '\0')
10747                                                 xflag = vflag = 0;
10748                                         /* "--" means reset params */
10749                                         else if (*argptr == NULL)
10750                                                 setparam(argptr);
10751                                 }
10752                                 break;    /* "-" or "--" terminates options */
10753                         }
10754                 }
10755                 /* first char was + or - */
10756                 while ((c = *p++) != '\0') {
10757                         /* bash 3.2 indeed handles -c CMD and +c CMD the same */
10758                         if (c == 'c' && cmdline) {
10759                                 minusc = p;     /* command is after shell args */
10760                         } else if (c == 'o') {
10761                                 if (plus_minus_o(*argptr, val)) {
10762                                         /* it already printed err message */
10763                                         return 1; /* error */
10764                                 }
10765                                 if (*argptr)
10766                                         argptr++;
10767                         } else if (cmdline && (c == 'l')) { /* -l or +l == --login */
10768                                 if (login_sh)
10769                                         *login_sh = 1;
10770                         /* bash does not accept +-login, we also won't */
10771                         } else if (cmdline && val && (c == '-')) { /* long options */
10772                                 if (strcmp(p, "login") == 0) {
10773                                         if (login_sh)
10774                                                 *login_sh = 1;
10775                                 }
10776                                 break;
10777                         } else {
10778                                 setoption(c, val);
10779                         }
10780                 }
10781         }
10782         return 0;
10783 }
10784
10785 /*
10786  * The shift builtin command.
10787  */
10788 static int FAST_FUNC
10789 shiftcmd(int argc UNUSED_PARAM, char **argv)
10790 {
10791         int n;
10792         char **ap1, **ap2;
10793
10794         n = 1;
10795         if (argv[1])
10796                 n = number(argv[1]);
10797         if (n > shellparam.nparam)
10798                 n = 0; /* bash compat, was = shellparam.nparam; */
10799         INT_OFF;
10800         shellparam.nparam -= n;
10801         for (ap1 = shellparam.p; --n >= 0; ap1++) {
10802                 if (shellparam.malloced)
10803                         free(*ap1);
10804         }
10805         ap2 = shellparam.p;
10806         while ((*ap2++ = *ap1++) != NULL)
10807                 continue;
10808 #if ENABLE_ASH_GETOPTS
10809         shellparam.optind = 1;
10810         shellparam.optoff = -1;
10811 #endif
10812         INT_ON;
10813         return 0;
10814 }
10815
10816 /*
10817  * POSIX requires that 'set' (but not export or readonly) output the
10818  * variables in lexicographic order - by the locale's collating order (sigh).
10819  * Maybe we could keep them in an ordered balanced binary tree
10820  * instead of hashed lists.
10821  * For now just roll 'em through qsort for printing...
10822  */
10823 static int
10824 showvars(const char *sep_prefix, int on, int off)
10825 {
10826         const char *sep;
10827         char **ep, **epend;
10828
10829         ep = listvars(on, off, &epend);
10830         qsort(ep, epend - ep, sizeof(char *), vpcmp);
10831
10832         sep = *sep_prefix ? " " : sep_prefix;
10833
10834         for (; ep < epend; ep++) {
10835                 const char *p;
10836                 const char *q;
10837
10838                 p = strchrnul(*ep, '=');
10839                 q = nullstr;
10840                 if (*p)
10841                         q = single_quote(++p);
10842                 out1fmt("%s%s%.*s%s\n", sep_prefix, sep, (int)(p - *ep), *ep, q);
10843         }
10844         return 0;
10845 }
10846
10847 /*
10848  * The set command builtin.
10849  */
10850 static int FAST_FUNC
10851 setcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
10852 {
10853         int retval;
10854
10855         if (!argv[1])
10856                 return showvars(nullstr, 0, VUNSET);
10857
10858         INT_OFF;
10859         retval = options(/*cmdline:*/ 0, NULL);
10860         if (retval == 0) { /* if no parse error... */
10861                 optschanged();
10862                 if (*argptr != NULL) {
10863                         setparam(argptr);
10864                 }
10865         }
10866         INT_ON;
10867         return retval;
10868 }
10869
10870 #if ENABLE_ASH_RANDOM_SUPPORT
10871 static void FAST_FUNC
10872 change_random(const char *value)
10873 {
10874         uint32_t t;
10875
10876         if (value == NULL) {
10877                 /* "get", generate */
10878                 t = next_random(&random_gen);
10879                 /* set without recursion */
10880                 setvar(vrandom.var_text, utoa(t), VNOFUNC);
10881                 vrandom.flags &= ~VNOFUNC;
10882         } else {
10883                 /* set/reset */
10884                 t = strtoul(value, NULL, 10);
10885                 INIT_RANDOM_T(&random_gen, (t ? t : 1), t);
10886         }
10887 }
10888 #endif
10889
10890 #if ENABLE_ASH_GETOPTS
10891 static int
10892 getopts(char *optstr, char *optvar, char **optfirst)
10893 {
10894         char *p, *q;
10895         char c = '?';
10896         int done = 0;
10897         char sbuf[2];
10898         char **optnext;
10899         int ind = shellparam.optind;
10900         int off = shellparam.optoff;
10901
10902         sbuf[1] = '\0';
10903
10904         shellparam.optind = -1;
10905         optnext = optfirst + ind - 1;
10906
10907         if (ind <= 1 || off < 0 || (int)strlen(optnext[-1]) < off)
10908                 p = NULL;
10909         else
10910                 p = optnext[-1] + off;
10911         if (p == NULL || *p == '\0') {
10912                 /* Current word is done, advance */
10913                 p = *optnext;
10914                 if (p == NULL || *p != '-' || *++p == '\0') {
10915  atend:
10916                         p = NULL;
10917                         done = 1;
10918                         goto out;
10919                 }
10920                 optnext++;
10921                 if (LONE_DASH(p))        /* check for "--" */
10922                         goto atend;
10923         }
10924
10925         c = *p++;
10926         for (q = optstr; *q != c;) {
10927                 if (*q == '\0') {
10928                         if (optstr[0] == ':') {
10929                                 sbuf[0] = c;
10930                                 /*sbuf[1] = '\0'; - already is */
10931                                 setvar0("OPTARG", sbuf);
10932                         } else {
10933                                 fprintf(stderr, "Illegal option -%c\n", c);
10934                                 unsetvar("OPTARG");
10935                         }
10936                         c = '?';
10937                         goto out;
10938                 }
10939                 if (*++q == ':')
10940                         q++;
10941         }
10942
10943         if (*++q == ':') {
10944                 if (*p == '\0' && (p = *optnext) == NULL) {
10945                         if (optstr[0] == ':') {
10946                                 sbuf[0] = c;
10947                                 /*sbuf[1] = '\0'; - already is */
10948                                 setvar0("OPTARG", sbuf);
10949                                 c = ':';
10950                         } else {
10951                                 fprintf(stderr, "No arg for -%c option\n", c);
10952                                 unsetvar("OPTARG");
10953                                 c = '?';
10954                         }
10955                         goto out;
10956                 }
10957
10958                 if (p == *optnext)
10959                         optnext++;
10960                 setvar0("OPTARG", p);
10961                 p = NULL;
10962         } else
10963                 setvar0("OPTARG", nullstr);
10964  out:
10965         ind = optnext - optfirst + 1;
10966         setvar("OPTIND", itoa(ind), VNOFUNC);
10967         sbuf[0] = c;
10968         /*sbuf[1] = '\0'; - already is */
10969         setvar0(optvar, sbuf);
10970
10971         shellparam.optoff = p ? p - *(optnext - 1) : -1;
10972         shellparam.optind = ind;
10973
10974         return done;
10975 }
10976
10977 /*
10978  * The getopts builtin.  Shellparam.optnext points to the next argument
10979  * to be processed.  Shellparam.optptr points to the next character to
10980  * be processed in the current argument.  If shellparam.optnext is NULL,
10981  * then it's the first time getopts has been called.
10982  */
10983 static int FAST_FUNC
10984 getoptscmd(int argc, char **argv)
10985 {
10986         char **optbase;
10987
10988         if (argc < 3)
10989                 ash_msg_and_raise_error("usage: getopts optstring var [arg]");
10990         if (argc == 3) {
10991                 optbase = shellparam.p;
10992                 if ((unsigned)shellparam.optind > shellparam.nparam + 1) {
10993                         shellparam.optind = 1;
10994                         shellparam.optoff = -1;
10995                 }
10996         } else {
10997                 optbase = &argv[3];
10998                 if ((unsigned)shellparam.optind > argc - 2) {
10999                         shellparam.optind = 1;
11000                         shellparam.optoff = -1;
11001                 }
11002         }
11003
11004         return getopts(argv[1], argv[2], optbase);
11005 }
11006 #endif /* ASH_GETOPTS */
11007
11008
11009 /* ============ Shell parser */
11010
11011 struct heredoc {
11012         struct heredoc *next;   /* next here document in list */
11013         union node *here;       /* redirection node */
11014         char *eofmark;          /* string indicating end of input */
11015         smallint striptabs;     /* if set, strip leading tabs */
11016 };
11017
11018 static smallint tokpushback;           /* last token pushed back */
11019 static smallint quoteflag;             /* set if (part of) last token was quoted */
11020 static token_id_t lasttoken;           /* last token read (integer id Txxx) */
11021 static struct heredoc *heredoclist;    /* list of here documents to read */
11022 static char *wordtext;                 /* text of last word returned by readtoken */
11023 static struct nodelist *backquotelist;
11024 static union node *redirnode;
11025 static struct heredoc *heredoc;
11026
11027 static const char *
11028 tokname(char *buf, int tok)
11029 {
11030         if (tok < TSEMI)
11031                 return tokname_array[tok];
11032         sprintf(buf, "\"%s\"", tokname_array[tok]);
11033         return buf;
11034 }
11035
11036 /* raise_error_unexpected_syntax:
11037  * Called when an unexpected token is read during the parse.  The argument
11038  * is the token that is expected, or -1 if more than one type of token can
11039  * occur at this point.
11040  */
11041 static void raise_error_unexpected_syntax(int) NORETURN;
11042 static void
11043 raise_error_unexpected_syntax(int token)
11044 {
11045         char msg[64];
11046         char buf[16];
11047         int l;
11048
11049         l = sprintf(msg, "unexpected %s", tokname(buf, lasttoken));
11050         if (token >= 0)
11051                 sprintf(msg + l, " (expecting %s)", tokname(buf, token));
11052         raise_error_syntax(msg);
11053         /* NOTREACHED */
11054 }
11055
11056 /* parsing is heavily cross-recursive, need these forward decls */
11057 static union node *andor(void);
11058 static union node *pipeline(void);
11059 static union node *parse_command(void);
11060 static void parseheredoc(void);
11061 static int peektoken(void);
11062 static int readtoken(void);
11063
11064 static union node *
11065 list(int nlflag)
11066 {
11067         union node *n1, *n2, *n3;
11068         int tok;
11069
11070         n1 = NULL;
11071         for (;;) {
11072                 switch (peektoken()) {
11073                 case TNL:
11074                         if (!(nlflag & 1))
11075                                 break;
11076                         parseheredoc();
11077                         return n1;
11078
11079                 case TEOF:
11080                         if (!n1 && (nlflag & 1))
11081                                 n1 = NODE_EOF;
11082                         parseheredoc();
11083                         return n1;
11084                 }
11085
11086                 checkkwd = CHKNL | CHKKWD | CHKALIAS;
11087                 if (nlflag == 2 && ((1 << peektoken()) & tokendlist))
11088                         return n1;
11089                 nlflag |= 2;
11090
11091                 n2 = andor();
11092                 tok = readtoken();
11093                 if (tok == TBACKGND) {
11094                         if (n2->type == NPIPE) {
11095                                 n2->npipe.pipe_backgnd = 1;
11096                         } else {
11097                                 if (n2->type != NREDIR) {
11098                                         n3 = stzalloc(sizeof(struct nredir));
11099                                         n3->nredir.n = n2;
11100                                         /*n3->nredir.redirect = NULL; - stzalloc did it */
11101                                         n2 = n3;
11102                                 }
11103                                 n2->type = NBACKGND;
11104                         }
11105                 }
11106                 if (n1 == NULL) {
11107                         n1 = n2;
11108                 } else {
11109                         n3 = stzalloc(sizeof(struct nbinary));
11110                         n3->type = NSEMI;
11111                         n3->nbinary.ch1 = n1;
11112                         n3->nbinary.ch2 = n2;
11113                         n1 = n3;
11114                 }
11115                 switch (tok) {
11116                 case TNL:
11117                 case TEOF:
11118                         tokpushback = 1;
11119                         /* fall through */
11120                 case TBACKGND:
11121                 case TSEMI:
11122                         break;
11123                 default:
11124                         if ((nlflag & 1))
11125                                 raise_error_unexpected_syntax(-1);
11126                         tokpushback = 1;
11127                         return n1;
11128                 }
11129         }
11130 }
11131
11132 static union node *
11133 andor(void)
11134 {
11135         union node *n1, *n2, *n3;
11136         int t;
11137
11138         n1 = pipeline();
11139         for (;;) {
11140                 t = readtoken();
11141                 if (t == TAND) {
11142                         t = NAND;
11143                 } else if (t == TOR) {
11144                         t = NOR;
11145                 } else {
11146                         tokpushback = 1;
11147                         return n1;
11148                 }
11149                 checkkwd = CHKNL | CHKKWD | CHKALIAS;
11150                 n2 = pipeline();
11151                 n3 = stzalloc(sizeof(struct nbinary));
11152                 n3->type = t;
11153                 n3->nbinary.ch1 = n1;
11154                 n3->nbinary.ch2 = n2;
11155                 n1 = n3;
11156         }
11157 }
11158
11159 static union node *
11160 pipeline(void)
11161 {
11162         union node *n1, *n2, *pipenode;
11163         struct nodelist *lp, *prev;
11164         int negate;
11165
11166         negate = 0;
11167         TRACE(("pipeline: entered\n"));
11168         if (readtoken() == TNOT) {
11169                 negate = !negate;
11170                 checkkwd = CHKKWD | CHKALIAS;
11171         } else
11172                 tokpushback = 1;
11173         n1 = parse_command();
11174         if (readtoken() == TPIPE) {
11175                 pipenode = stzalloc(sizeof(struct npipe));
11176                 pipenode->type = NPIPE;
11177                 /*pipenode->npipe.pipe_backgnd = 0; - stzalloc did it */
11178                 lp = stzalloc(sizeof(struct nodelist));
11179                 pipenode->npipe.cmdlist = lp;
11180                 lp->n = n1;
11181                 do {
11182                         prev = lp;
11183                         lp = stzalloc(sizeof(struct nodelist));
11184                         checkkwd = CHKNL | CHKKWD | CHKALIAS;
11185                         lp->n = parse_command();
11186                         prev->next = lp;
11187                 } while (readtoken() == TPIPE);
11188                 lp->next = NULL;
11189                 n1 = pipenode;
11190         }
11191         tokpushback = 1;
11192         if (negate) {
11193                 n2 = stzalloc(sizeof(struct nnot));
11194                 n2->type = NNOT;
11195                 n2->nnot.com = n1;
11196                 return n2;
11197         }
11198         return n1;
11199 }
11200
11201 static union node *
11202 makename(void)
11203 {
11204         union node *n;
11205
11206         n = stzalloc(sizeof(struct narg));
11207         n->type = NARG;
11208         /*n->narg.next = NULL; - stzalloc did it */
11209         n->narg.text = wordtext;
11210         n->narg.backquote = backquotelist;
11211         return n;
11212 }
11213
11214 static void
11215 fixredir(union node *n, const char *text, int err)
11216 {
11217         int fd;
11218
11219         TRACE(("Fix redir %s %d\n", text, err));
11220         if (!err)
11221                 n->ndup.vname = NULL;
11222
11223         fd = bb_strtou(text, NULL, 10);
11224         if (!errno && fd >= 0)
11225                 n->ndup.dupfd = fd;
11226         else if (LONE_DASH(text))
11227                 n->ndup.dupfd = -1;
11228         else {
11229                 if (err)
11230                         raise_error_syntax("bad fd number");
11231                 n->ndup.vname = makename();
11232         }
11233 }
11234
11235 static void
11236 parsefname(void)
11237 {
11238         union node *n = redirnode;
11239
11240         if (n->type == NHERE)
11241                 checkkwd = CHKEOFMARK;
11242         if (readtoken() != TWORD)
11243                 raise_error_unexpected_syntax(-1);
11244         if (n->type == NHERE) {
11245                 struct heredoc *here = heredoc;
11246                 struct heredoc *p;
11247
11248                 if (quoteflag == 0)
11249                         n->type = NXHERE;
11250                 TRACE(("Here document %d\n", n->type));
11251                 rmescapes(wordtext, 0);
11252                 here->eofmark = wordtext;
11253                 here->next = NULL;
11254                 if (heredoclist == NULL)
11255                         heredoclist = here;
11256                 else {
11257                         for (p = heredoclist; p->next; p = p->next)
11258                                 continue;
11259                         p->next = here;
11260                 }
11261         } else if (n->type == NTOFD || n->type == NFROMFD) {
11262                 fixredir(n, wordtext, 0);
11263         } else {
11264                 n->nfile.fname = makename();
11265         }
11266 }
11267
11268 static union node *
11269 simplecmd(void)
11270 {
11271         union node *args, **app;
11272         union node *n = NULL;
11273         union node *vars, **vpp;
11274         union node **rpp, *redir;
11275         int savecheckkwd;
11276 #if BASH_TEST2
11277         smallint double_brackets_flag = 0;
11278 #endif
11279         IF_BASH_FUNCTION(smallint function_flag = 0;)
11280
11281         args = NULL;
11282         app = &args;
11283         vars = NULL;
11284         vpp = &vars;
11285         redir = NULL;
11286         rpp = &redir;
11287
11288         savecheckkwd = CHKALIAS;
11289         for (;;) {
11290                 int t;
11291                 checkkwd = savecheckkwd;
11292                 t = readtoken();
11293                 switch (t) {
11294 #if BASH_FUNCTION
11295                 case TFUNCTION:
11296                         if (peektoken() != TWORD)
11297                                 raise_error_unexpected_syntax(TWORD);
11298                         function_flag = 1;
11299                         break;
11300 #endif
11301 #if BASH_TEST2
11302                 case TAND: /* "&&" */
11303                 case TOR: /* "||" */
11304                         if (!double_brackets_flag) {
11305                                 tokpushback = 1;
11306                                 goto out;
11307                         }
11308                         wordtext = (char *) (t == TAND ? "-a" : "-o");
11309 #endif
11310                 case TWORD:
11311                         n = stzalloc(sizeof(struct narg));
11312                         n->type = NARG;
11313                         /*n->narg.next = NULL; - stzalloc did it */
11314                         n->narg.text = wordtext;
11315 #if BASH_TEST2
11316                         if (strcmp("[[", wordtext) == 0)
11317                                 double_brackets_flag = 1;
11318                         else if (strcmp("]]", wordtext) == 0)
11319                                 double_brackets_flag = 0;
11320 #endif
11321                         n->narg.backquote = backquotelist;
11322                         if (savecheckkwd && isassignment(wordtext)) {
11323                                 *vpp = n;
11324                                 vpp = &n->narg.next;
11325                         } else {
11326                                 *app = n;
11327                                 app = &n->narg.next;
11328                                 savecheckkwd = 0;
11329                         }
11330 #if BASH_FUNCTION
11331                         if (function_flag) {
11332                                 checkkwd = CHKNL | CHKKWD;
11333                                 switch (peektoken()) {
11334                                 case TBEGIN:
11335                                 case TIF:
11336                                 case TCASE:
11337                                 case TUNTIL:
11338                                 case TWHILE:
11339                                 case TFOR:
11340                                         goto do_func;
11341                                 case TLP:
11342                                         function_flag = 0;
11343                                         break;
11344                                 case TWORD:
11345                                         if (strcmp("[[", wordtext) == 0)
11346                                                 goto do_func;
11347                                         /* fall through */
11348                                 default:
11349                                         raise_error_unexpected_syntax(-1);
11350                                 }
11351                         }
11352 #endif
11353                         break;
11354                 case TREDIR:
11355                         *rpp = n = redirnode;
11356                         rpp = &n->nfile.next;
11357                         parsefname();   /* read name of redirection file */
11358                         break;
11359                 case TLP:
11360  IF_BASH_FUNCTION(do_func:)
11361                         if (args && app == &args->narg.next
11362                          && !vars && !redir
11363                         ) {
11364                                 struct builtincmd *bcmd;
11365                                 const char *name;
11366
11367                                 /* We have a function */
11368                                 if (IF_BASH_FUNCTION(!function_flag &&) readtoken() != TRP)
11369                                         raise_error_unexpected_syntax(TRP);
11370                                 name = n->narg.text;
11371                                 if (!goodname(name)
11372                                  || ((bcmd = find_builtin(name)) && IS_BUILTIN_SPECIAL(bcmd))
11373                                 ) {
11374                                         raise_error_syntax("bad function name");
11375                                 }
11376                                 n->type = NDEFUN;
11377                                 checkkwd = CHKNL | CHKKWD | CHKALIAS;
11378                                 n->narg.next = parse_command();
11379                                 return n;
11380                         }
11381                         IF_BASH_FUNCTION(function_flag = 0;)
11382                         /* fall through */
11383                 default:
11384                         tokpushback = 1;
11385                         goto out;
11386                 }
11387         }
11388  out:
11389         *app = NULL;
11390         *vpp = NULL;
11391         *rpp = NULL;
11392         n = stzalloc(sizeof(struct ncmd));
11393         n->type = NCMD;
11394         n->ncmd.args = args;
11395         n->ncmd.assign = vars;
11396         n->ncmd.redirect = redir;
11397         return n;
11398 }
11399
11400 static union node *
11401 parse_command(void)
11402 {
11403         union node *n1, *n2;
11404         union node *ap, **app;
11405         union node *cp, **cpp;
11406         union node *redir, **rpp;
11407         union node **rpp2;
11408         int t;
11409
11410         redir = NULL;
11411         rpp2 = &redir;
11412
11413         switch (readtoken()) {
11414         default:
11415                 raise_error_unexpected_syntax(-1);
11416                 /* NOTREACHED */
11417         case TIF:
11418                 n1 = stzalloc(sizeof(struct nif));
11419                 n1->type = NIF;
11420                 n1->nif.test = list(0);
11421                 if (readtoken() != TTHEN)
11422                         raise_error_unexpected_syntax(TTHEN);
11423                 n1->nif.ifpart = list(0);
11424                 n2 = n1;
11425                 while (readtoken() == TELIF) {
11426                         n2->nif.elsepart = stzalloc(sizeof(struct nif));
11427                         n2 = n2->nif.elsepart;
11428                         n2->type = NIF;
11429                         n2->nif.test = list(0);
11430                         if (readtoken() != TTHEN)
11431                                 raise_error_unexpected_syntax(TTHEN);
11432                         n2->nif.ifpart = list(0);
11433                 }
11434                 if (lasttoken == TELSE)
11435                         n2->nif.elsepart = list(0);
11436                 else {
11437                         n2->nif.elsepart = NULL;
11438                         tokpushback = 1;
11439                 }
11440                 t = TFI;
11441                 break;
11442         case TWHILE:
11443         case TUNTIL: {
11444                 int got;
11445                 n1 = stzalloc(sizeof(struct nbinary));
11446                 n1->type = (lasttoken == TWHILE) ? NWHILE : NUNTIL;
11447                 n1->nbinary.ch1 = list(0);
11448                 got = readtoken();
11449                 if (got != TDO) {
11450                         TRACE(("expecting DO got '%s' %s\n", tokname_array[got],
11451                                         got == TWORD ? wordtext : ""));
11452                         raise_error_unexpected_syntax(TDO);
11453                 }
11454                 n1->nbinary.ch2 = list(0);
11455                 t = TDONE;
11456                 break;
11457         }
11458         case TFOR:
11459                 if (readtoken() != TWORD || quoteflag || !goodname(wordtext))
11460                         raise_error_syntax("bad for loop variable");
11461                 n1 = stzalloc(sizeof(struct nfor));
11462                 n1->type = NFOR;
11463                 n1->nfor.var = wordtext;
11464                 checkkwd = CHKNL | CHKKWD | CHKALIAS;
11465                 if (readtoken() == TIN) {
11466                         app = &ap;
11467                         while (readtoken() == TWORD) {
11468                                 n2 = stzalloc(sizeof(struct narg));
11469                                 n2->type = NARG;
11470                                 /*n2->narg.next = NULL; - stzalloc did it */
11471                                 n2->narg.text = wordtext;
11472                                 n2->narg.backquote = backquotelist;
11473                                 *app = n2;
11474                                 app = &n2->narg.next;
11475                         }
11476                         *app = NULL;
11477                         n1->nfor.args = ap;
11478                         if (lasttoken != TNL && lasttoken != TSEMI)
11479                                 raise_error_unexpected_syntax(-1);
11480                 } else {
11481                         n2 = stzalloc(sizeof(struct narg));
11482                         n2->type = NARG;
11483                         /*n2->narg.next = NULL; - stzalloc did it */
11484                         n2->narg.text = (char *)dolatstr;
11485                         /*n2->narg.backquote = NULL;*/
11486                         n1->nfor.args = n2;
11487                         /*
11488                          * Newline or semicolon here is optional (but note
11489                          * that the original Bourne shell only allowed NL).
11490                          */
11491                         if (lasttoken != TSEMI)
11492                                 tokpushback = 1;
11493                 }
11494                 checkkwd = CHKNL | CHKKWD | CHKALIAS;
11495                 if (readtoken() != TDO)
11496                         raise_error_unexpected_syntax(TDO);
11497                 n1->nfor.body = list(0);
11498                 t = TDONE;
11499                 break;
11500         case TCASE:
11501                 n1 = stzalloc(sizeof(struct ncase));
11502                 n1->type = NCASE;
11503                 if (readtoken() != TWORD)
11504                         raise_error_unexpected_syntax(TWORD);
11505                 n1->ncase.expr = n2 = stzalloc(sizeof(struct narg));
11506                 n2->type = NARG;
11507                 /*n2->narg.next = NULL; - stzalloc did it */
11508                 n2->narg.text = wordtext;
11509                 n2->narg.backquote = backquotelist;
11510                 checkkwd = CHKNL | CHKKWD | CHKALIAS;
11511                 if (readtoken() != TIN)
11512                         raise_error_unexpected_syntax(TIN);
11513                 cpp = &n1->ncase.cases;
11514  next_case:
11515                 checkkwd = CHKNL | CHKKWD;
11516                 t = readtoken();
11517                 while (t != TESAC) {
11518                         if (lasttoken == TLP)
11519                                 readtoken();
11520                         *cpp = cp = stzalloc(sizeof(struct nclist));
11521                         cp->type = NCLIST;
11522                         app = &cp->nclist.pattern;
11523                         for (;;) {
11524                                 *app = ap = stzalloc(sizeof(struct narg));
11525                                 ap->type = NARG;
11526                                 /*ap->narg.next = NULL; - stzalloc did it */
11527                                 ap->narg.text = wordtext;
11528                                 ap->narg.backquote = backquotelist;
11529                                 if (readtoken() != TPIPE)
11530                                         break;
11531                                 app = &ap->narg.next;
11532                                 readtoken();
11533                         }
11534                         //ap->narg.next = NULL;
11535                         if (lasttoken != TRP)
11536                                 raise_error_unexpected_syntax(TRP);
11537                         cp->nclist.body = list(2);
11538
11539                         cpp = &cp->nclist.next;
11540
11541                         checkkwd = CHKNL | CHKKWD;
11542                         t = readtoken();
11543                         if (t != TESAC) {
11544                                 if (t != TENDCASE)
11545                                         raise_error_unexpected_syntax(TENDCASE);
11546                                 goto next_case;
11547                         }
11548                 }
11549                 *cpp = NULL;
11550                 goto redir;
11551         case TLP:
11552                 n1 = stzalloc(sizeof(struct nredir));
11553                 n1->type = NSUBSHELL;
11554                 n1->nredir.n = list(0);
11555                 /*n1->nredir.redirect = NULL; - stzalloc did it */
11556                 t = TRP;
11557                 break;
11558         case TBEGIN:
11559                 n1 = list(0);
11560                 t = TEND;
11561                 break;
11562         IF_BASH_FUNCTION(case TFUNCTION:)
11563         case TWORD:
11564         case TREDIR:
11565                 tokpushback = 1;
11566                 return simplecmd();
11567         }
11568
11569         if (readtoken() != t)
11570                 raise_error_unexpected_syntax(t);
11571
11572  redir:
11573         /* Now check for redirection which may follow command */
11574         checkkwd = CHKKWD | CHKALIAS;
11575         rpp = rpp2;
11576         while (readtoken() == TREDIR) {
11577                 *rpp = n2 = redirnode;
11578                 rpp = &n2->nfile.next;
11579                 parsefname();
11580         }
11581         tokpushback = 1;
11582         *rpp = NULL;
11583         if (redir) {
11584                 if (n1->type != NSUBSHELL) {
11585                         n2 = stzalloc(sizeof(struct nredir));
11586                         n2->type = NREDIR;
11587                         n2->nredir.n = n1;
11588                         n1 = n2;
11589                 }
11590                 n1->nredir.redirect = redir;
11591         }
11592         return n1;
11593 }
11594
11595 #if BASH_DOLLAR_SQUOTE
11596 static int
11597 decode_dollar_squote(void)
11598 {
11599         static const char C_escapes[] ALIGN1 = "nrbtfav""x\\01234567";
11600         int c, cnt;
11601         char *p;
11602         char buf[4];
11603
11604         c = pgetc();
11605         p = strchr(C_escapes, c);
11606         if (p) {
11607                 buf[0] = c;
11608                 p = buf;
11609                 cnt = 3;
11610                 if ((unsigned char)(c - '0') <= 7) { /* \ooo */
11611                         do {
11612                                 c = pgetc();
11613                                 *++p = c;
11614                         } while ((unsigned char)(c - '0') <= 7 && --cnt);
11615                         pungetc();
11616                 } else if (c == 'x') { /* \xHH */
11617                         do {
11618                                 c = pgetc();
11619                                 *++p = c;
11620                         } while (isxdigit(c) && --cnt);
11621                         pungetc();
11622                         if (cnt == 3) { /* \x but next char is "bad" */
11623                                 c = 'x';
11624                                 goto unrecognized;
11625                         }
11626                 } else { /* simple seq like \\ or \t */
11627                         p++;
11628                 }
11629                 *p = '\0';
11630                 p = buf;
11631                 c = bb_process_escape_sequence((void*)&p);
11632         } else { /* unrecognized "\z": print both chars unless ' or " */
11633                 if (c != '\'' && c != '"') {
11634  unrecognized:
11635                         c |= 0x100; /* "please encode \, then me" */
11636                 }
11637         }
11638         return c;
11639 }
11640 #endif
11641
11642 /* Used by expandstr to get here-doc like behaviour. */
11643 #define FAKEEOFMARK ((char*)(uintptr_t)1)
11644
11645 static ALWAYS_INLINE int
11646 realeofmark(const char *eofmark)
11647 {
11648         return eofmark && eofmark != FAKEEOFMARK;
11649 }
11650
11651 /*
11652  * If eofmark is NULL, read a word or a redirection symbol.  If eofmark
11653  * is not NULL, read a here document.  In the latter case, eofmark is the
11654  * word which marks the end of the document and striptabs is true if
11655  * leading tabs should be stripped from the document.  The argument c
11656  * is the first character of the input token or document.
11657  *
11658  * Because C does not have internal subroutines, I have simulated them
11659  * using goto's to implement the subroutine linkage.  The following macros
11660  * will run code that appears at the end of readtoken1.
11661  */
11662 #define CHECKEND()      {goto checkend; checkend_return:;}
11663 #define PARSEREDIR()    {goto parseredir; parseredir_return:;}
11664 #define PARSESUB()      {goto parsesub; parsesub_return:;}
11665 #define PARSEBACKQOLD() {oldstyle = 1; goto parsebackq; parsebackq_oldreturn:;}
11666 #define PARSEBACKQNEW() {oldstyle = 0; goto parsebackq; parsebackq_newreturn:;}
11667 #define PARSEARITH()    {goto parsearith; parsearith_return:;}
11668 static int
11669 readtoken1(int c, int syntax, char *eofmark, int striptabs)
11670 {
11671         /* NB: syntax parameter fits into smallint */
11672         /* c parameter is an unsigned char or PEOF or PEOA */
11673         char *out;
11674         size_t len;
11675         struct nodelist *bqlist;
11676         smallint quotef;
11677         smallint dblquote;
11678         smallint oldstyle;
11679         IF_FEATURE_SH_MATH(smallint prevsyntax;) /* syntax before arithmetic */
11680         smallint pssyntax;   /* we are expanding a prompt string */
11681         int varnest;         /* levels of variables expansion */
11682         IF_FEATURE_SH_MATH(int arinest;)    /* levels of arithmetic expansion */
11683         IF_FEATURE_SH_MATH(int parenlevel;) /* levels of parens in arithmetic */
11684         int dqvarnest;       /* levels of variables expansion within double quotes */
11685
11686         IF_BASH_DOLLAR_SQUOTE(smallint bash_dollar_squote = 0;)
11687
11688         startlinno = g_parsefile->linno;
11689         bqlist = NULL;
11690         quotef = 0;
11691         IF_FEATURE_SH_MATH(prevsyntax = 0;)
11692 #if ENABLE_ASH_EXPAND_PRMT
11693         pssyntax = (syntax == PSSYNTAX);
11694         if (pssyntax)
11695                 syntax = DQSYNTAX;
11696 #else
11697         pssyntax = 0; /* constant */
11698 #endif
11699         dblquote = (syntax == DQSYNTAX);
11700         varnest = 0;
11701         IF_FEATURE_SH_MATH(arinest = 0;)
11702         IF_FEATURE_SH_MATH(parenlevel = 0;)
11703         dqvarnest = 0;
11704
11705         STARTSTACKSTR(out);
11706  loop:
11707         /* For each line, until end of word */
11708         CHECKEND();     /* set c to PEOF if at end of here document */
11709         for (;;) {      /* until end of line or end of word */
11710                 CHECKSTRSPACE(4, out);  /* permit 4 calls to USTPUTC */
11711                 switch (SIT(c, syntax)) {
11712                 case CNL:       /* '\n' */
11713                         if (syntax == BASESYNTAX)
11714                                 goto endword;   /* exit outer loop */
11715                         USTPUTC(c, out);
11716                         nlprompt();
11717                         c = pgetc();
11718                         goto loop;              /* continue outer loop */
11719                 case CWORD:
11720                         USTPUTC(c, out);
11721                         break;
11722                 case CCTL:
11723 #if BASH_DOLLAR_SQUOTE
11724                         if (c == '\\' && bash_dollar_squote) {
11725                                 c = decode_dollar_squote();
11726                                 if (c == '\0') {
11727                                         /* skip $'\000', $'\x00' (like bash) */
11728                                         break;
11729                                 }
11730                                 if (c & 0x100) {
11731                                         /* Unknown escape. Encode as '\z' */
11732                                         c = (unsigned char)c;
11733                                         if (eofmark == NULL || dblquote)
11734                                                 USTPUTC(CTLESC, out);
11735                                         USTPUTC('\\', out);
11736                                 }
11737                         }
11738 #endif
11739                         if (eofmark == NULL || dblquote)
11740                                 USTPUTC(CTLESC, out);
11741                         USTPUTC(c, out);
11742                         break;
11743                 case CBACK:     /* backslash */
11744                         c = pgetc_without_PEOA();
11745                         if (c == PEOF) {
11746                                 USTPUTC(CTLESC, out);
11747                                 USTPUTC('\\', out);
11748                                 pungetc();
11749                         } else if (c == '\n') {
11750                                 nlprompt();
11751                         } else {
11752                                 if (pssyntax && c == '$') {
11753                                         USTPUTC(CTLESC, out);
11754                                         USTPUTC('\\', out);
11755                                 }
11756                                 /* Backslash is retained if we are in "str" and next char isn't special */
11757                                 if (dblquote
11758                                  && c != '\\'
11759                                  && c != '`'
11760                                  && c != '$'
11761                                  && (c != '"' || eofmark != NULL)
11762                                 ) {
11763                                         USTPUTC('\\', out);
11764                                 }
11765                                 USTPUTC(CTLESC, out);
11766                                 USTPUTC(c, out);
11767                                 quotef = 1;
11768                         }
11769                         break;
11770                 case CSQUOTE:
11771                         syntax = SQSYNTAX;
11772  quotemark:
11773                         if (eofmark == NULL) {
11774                                 USTPUTC(CTLQUOTEMARK, out);
11775                         }
11776                         break;
11777                 case CDQUOTE:
11778                         syntax = DQSYNTAX;
11779                         dblquote = 1;
11780                         goto quotemark;
11781                 case CENDQUOTE:
11782                         IF_BASH_DOLLAR_SQUOTE(bash_dollar_squote = 0;)
11783                         if (eofmark != NULL && varnest == 0) {
11784                                 USTPUTC(c, out);
11785                         } else {
11786                                 if (dqvarnest == 0) {
11787                                         syntax = BASESYNTAX;
11788                                         dblquote = 0;
11789                                 }
11790                                 quotef = 1;
11791                                 goto quotemark;
11792                         }
11793                         break;
11794                 case CVAR:      /* '$' */
11795                         PARSESUB();             /* parse substitution */
11796                         break;
11797                 case CENDVAR:   /* '}' */
11798                         if (varnest > 0) {
11799                                 varnest--;
11800                                 if (dqvarnest > 0) {
11801                                         dqvarnest--;
11802                                 }
11803                                 c = CTLENDVAR;
11804                         }
11805                         USTPUTC(c, out);
11806                         break;
11807 #if ENABLE_FEATURE_SH_MATH
11808                 case CLP:       /* '(' in arithmetic */
11809                         parenlevel++;
11810                         USTPUTC(c, out);
11811                         break;
11812                 case CRP:       /* ')' in arithmetic */
11813                         if (parenlevel > 0) {
11814                                 parenlevel--;
11815                         } else {
11816                                 if (pgetc_eatbnl() == ')') {
11817                                         c = CTLENDARI;
11818                                         if (--arinest == 0) {
11819                                                 syntax = prevsyntax;
11820                                         }
11821                                 } else {
11822                                         /*
11823                                          * unbalanced parens
11824                                          * (don't 2nd guess - no error)
11825                                          */
11826                                         pungetc();
11827                                 }
11828                         }
11829                         USTPUTC(c, out);
11830                         break;
11831 #endif
11832                 case CBQUOTE:   /* '`' */
11833                         PARSEBACKQOLD();
11834                         break;
11835                 case CENDFILE:
11836                         goto endword;           /* exit outer loop */
11837                 case CIGN:
11838                         break;
11839                 default:
11840                         if (varnest == 0) {
11841 #if BASH_REDIR_OUTPUT
11842                                 if (c == '&') {
11843 //Can't call pgetc_eatbnl() here, this requires three-deep pungetc()
11844                                         if (pgetc() == '>')
11845                                                 c = 0x100 + '>'; /* flag &> */
11846                                         pungetc();
11847                                 }
11848 #endif
11849                                 goto endword;   /* exit outer loop */
11850                         }
11851                         IF_ASH_ALIAS(if (c != PEOA))
11852                                 USTPUTC(c, out);
11853                 }
11854                 c = pgetc();
11855         } /* for (;;) */
11856  endword:
11857
11858 #if ENABLE_FEATURE_SH_MATH
11859         if (syntax == ARISYNTAX)
11860                 raise_error_syntax("missing '))'");
11861 #endif
11862         if (syntax != BASESYNTAX && eofmark == NULL)
11863                 raise_error_syntax("unterminated quoted string");
11864         if (varnest != 0) {
11865                 startlinno = g_parsefile->linno;
11866                 /* { */
11867                 raise_error_syntax("missing '}'");
11868         }
11869         USTPUTC('\0', out);
11870         len = out - (char *)stackblock();
11871         out = stackblock();
11872         if (eofmark == NULL) {
11873                 if ((c == '>' || c == '<' IF_BASH_REDIR_OUTPUT( || c == 0x100 + '>'))
11874                  && quotef == 0
11875                 ) {
11876                         if (isdigit_str9(out)) {
11877                                 PARSEREDIR(); /* passed as params: out, c */
11878                                 lasttoken = TREDIR;
11879                                 return lasttoken;
11880                         }
11881                         /* else: non-number X seen, interpret it
11882                          * as "NNNX>file" = "NNNX >file" */
11883                 }
11884                 pungetc();
11885         }
11886         quoteflag = quotef;
11887         backquotelist = bqlist;
11888         grabstackblock(len);
11889         wordtext = out;
11890         lasttoken = TWORD;
11891         return lasttoken;
11892 /* end of readtoken routine */
11893
11894 /*
11895  * Check to see whether we are at the end of the here document.  When this
11896  * is called, c is set to the first character of the next input line.  If
11897  * we are at the end of the here document, this routine sets the c to PEOF.
11898  */
11899 checkend: {
11900         if (realeofmark(eofmark)) {
11901                 int markloc;
11902                 char *p;
11903
11904 #if ENABLE_ASH_ALIAS
11905                 if (c == PEOA)
11906                         c = pgetc_without_PEOA();
11907 #endif
11908                 if (striptabs) {
11909                         while (c == '\t') {
11910                                 c = pgetc_without_PEOA();
11911                         }
11912                 }
11913
11914                 markloc = out - (char *)stackblock();
11915                 for (p = eofmark; STPUTC(c, out), *p; p++) {
11916                         if (c != *p)
11917                                 goto more_heredoc;
11918
11919                         c = pgetc_without_PEOA();
11920                 }
11921
11922                 if (c == '\n' || c == PEOF) {
11923                         c = PEOF;
11924                         g_parsefile->linno++;
11925                         needprompt = doprompt;
11926                 } else {
11927                         int len_here;
11928
11929  more_heredoc:
11930                         p = (char *)stackblock() + markloc + 1;
11931                         len_here = out - p;
11932
11933                         if (len_here) {
11934                                 len_here -= (c >= PEOF);
11935                                 c = p[-1];
11936
11937                                 if (len_here) {
11938                                         char *str;
11939
11940                                         str = alloca(len_here + 1);
11941                                         *(char *)mempcpy(str, p, len_here) = '\0';
11942
11943                                         pushstring(str, NULL);
11944                                 }
11945                         }
11946                 }
11947
11948                 STADJUST((char *)stackblock() + markloc - out, out);
11949         }
11950         goto checkend_return;
11951 }
11952
11953 /*
11954  * Parse a redirection operator.  The variable "out" points to a string
11955  * specifying the fd to be redirected.  The variable "c" contains the
11956  * first character of the redirection operator.
11957  */
11958 parseredir: {
11959         /* out is already checked to be a valid number or "" */
11960         int fd = (*out == '\0' ? -1 : atoi(out));
11961         union node *np;
11962
11963         np = stzalloc(sizeof(struct nfile));
11964         if (c == '>') {
11965                 np->nfile.fd = 1;
11966                 c = pgetc();
11967                 if (c == '>')
11968                         np->type = NAPPEND;
11969                 else if (c == '|')
11970                         np->type = NCLOBBER;
11971                 else if (c == '&')
11972                         np->type = NTOFD;
11973                         /* it also can be NTO2 (>&file), but we can't figure it out yet */
11974                 else {
11975                         np->type = NTO;
11976                         pungetc();
11977                 }
11978         }
11979 #if BASH_REDIR_OUTPUT
11980         else if (c == 0x100 + '>') { /* this flags &> redirection */
11981                 np->nfile.fd = 1;
11982                 pgetc(); /* this is '>', no need to check */
11983                 np->type = NTO2;
11984         }
11985 #endif
11986         else { /* c == '<' */
11987                 /*np->nfile.fd = 0; - stzalloc did it */
11988                 c = pgetc();
11989                 switch (c) {
11990                 case '<':
11991                         if (sizeof(struct nfile) != sizeof(struct nhere)) {
11992                                 np = stzalloc(sizeof(struct nhere));
11993                                 /*np->nfile.fd = 0; - stzalloc did it */
11994                         }
11995                         np->type = NHERE;
11996                         heredoc = stzalloc(sizeof(struct heredoc));
11997                         heredoc->here = np;
11998                         c = pgetc();
11999                         if (c == '-') {
12000                                 heredoc->striptabs = 1;
12001                         } else {
12002                                 /*heredoc->striptabs = 0; - stzalloc did it */
12003                                 pungetc();
12004                         }
12005                         break;
12006
12007                 case '&':
12008                         np->type = NFROMFD;
12009                         break;
12010
12011                 case '>':
12012                         np->type = NFROMTO;
12013                         break;
12014
12015                 default:
12016                         np->type = NFROM;
12017                         pungetc();
12018                         break;
12019                 }
12020         }
12021         if (fd >= 0)
12022                 np->nfile.fd = fd;
12023         redirnode = np;
12024         goto parseredir_return;
12025 }
12026
12027 /*
12028  * Parse a substitution.  At this point, we have read the dollar sign
12029  * and nothing else.
12030  */
12031
12032 /* is_special(c) evaluates to 1 for c in "!#$*-0123456789?@"; 0 otherwise
12033  * (assuming ascii char codes, as the original implementation did) */
12034 #define is_special(c) \
12035         (((unsigned)(c) - 33 < 32) \
12036                         && ((0xc1ff920dU >> ((unsigned)(c) - 33)) & 1))
12037 parsesub: {
12038         unsigned char subtype;
12039         int typeloc;
12040
12041         c = pgetc_eatbnl();
12042         if ((checkkwd & CHKEOFMARK)
12043          || c > 255 /* PEOA or PEOF */
12044          || (c != '(' && c != '{' && !is_name(c) && !is_special(c))
12045         ) {
12046 #if BASH_DOLLAR_SQUOTE
12047                 if (syntax != DQSYNTAX && c == '\'')
12048                         bash_dollar_squote = 1;
12049                 else
12050 #endif
12051                         USTPUTC('$', out);
12052                 pungetc();
12053         } else if (c == '(') {
12054                 /* $(command) or $((arith)) */
12055                 if (pgetc_eatbnl() == '(') {
12056 #if ENABLE_FEATURE_SH_MATH
12057                         PARSEARITH();
12058 #else
12059                         raise_error_syntax("support for $((arith)) is disabled");
12060 #endif
12061                 } else {
12062                         pungetc();
12063                         PARSEBACKQNEW();
12064                 }
12065         } else {
12066                 /* $VAR, $<specialchar>, ${...}, or PEOA/PEOF */
12067                 USTPUTC(CTLVAR, out);
12068                 typeloc = out - (char *)stackblock();
12069                 STADJUST(1, out);
12070                 subtype = VSNORMAL;
12071                 if (c == '{') {
12072                         c = pgetc_eatbnl();
12073                         subtype = 0;
12074                 }
12075  varname:
12076                 if (is_name(c)) {
12077                         /* $[{[#]]NAME[}] */
12078                         do {
12079                                 STPUTC(c, out);
12080                                 c = pgetc_eatbnl();
12081                         } while (is_in_name(c));
12082                 } else if (isdigit(c)) {
12083                         /* $[{[#]]NUM[}] */
12084                         do {
12085                                 STPUTC(c, out);
12086                                 c = pgetc_eatbnl();
12087                         } while (isdigit(c));
12088                 } else if (is_special(c)) {
12089                         /* $[{[#]]<specialchar>[}] */
12090                         int cc = c;
12091
12092                         c = pgetc_eatbnl();
12093                         if (!subtype && cc == '#') {
12094                                 subtype = VSLENGTH;
12095                                 if (c == '_' || isalnum(c))
12096                                         goto varname;
12097                                 cc = c;
12098                                 c = pgetc_eatbnl();
12099                                 if (cc == '}' || c != '}') {
12100                                         pungetc();
12101                                         subtype = 0;
12102                                         c = cc;
12103                                         cc = '#';
12104                                 }
12105                         }
12106                         USTPUTC(cc, out);
12107                 } else {
12108                         goto badsub;
12109                 }
12110                 if (c != '}' && subtype == VSLENGTH) {
12111                         /* ${#VAR didn't end with } */
12112                         goto badsub;
12113                 }
12114
12115                 if (subtype == 0) {
12116                         static const char types[] ALIGN1 = "}-+?=";
12117                         /* ${VAR...} but not $VAR or ${#VAR} */
12118                         /* c == first char after VAR */
12119                         switch (c) {
12120                         case ':':
12121                                 c = pgetc_eatbnl();
12122 #if BASH_SUBSTR
12123                                 /* This check is only needed to not misinterpret
12124                                  * ${VAR:-WORD}, ${VAR:+WORD}, ${VAR:=WORD}, ${VAR:?WORD}
12125                                  * constructs.
12126                                  */
12127                                 if (!strchr(types, c)) {
12128                                         subtype = VSSUBSTR;
12129                                         pungetc();
12130                                         break; /* "goto badsub" is bigger (!) */
12131                                 }
12132 #endif
12133                                 subtype = VSNUL;
12134                                 /*FALLTHROUGH*/
12135                         default: {
12136                                 const char *p = strchr(types, c);
12137                                 if (p == NULL)
12138                                         break;
12139                                 subtype |= p - types + VSNORMAL;
12140                                 break;
12141                         }
12142                         case '%':
12143                         case '#': {
12144                                 int cc = c;
12145                                 subtype = (c == '#' ? VSTRIMLEFT : VSTRIMRIGHT);
12146                                 c = pgetc_eatbnl();
12147                                 if (c != cc)
12148                                         goto badsub;
12149                                 subtype++;
12150                                 break;
12151                         }
12152 #if BASH_PATTERN_SUBST
12153                         case '/':
12154                                 /* ${v/[/]pattern/repl} */
12155 //TODO: encode pattern and repl separately.
12156 // Currently ${v/$var_with_slash/repl} is horribly broken
12157                                 subtype = VSREPLACE;
12158                                 c = pgetc_eatbnl();
12159                                 if (c != '/')
12160                                         goto badsub;
12161                                 subtype++; /* VSREPLACEALL */
12162                                 break;
12163 #endif
12164                         }
12165                 } else {
12166  badsub:
12167                         pungetc();
12168                 }
12169                 ((unsigned char *)stackblock())[typeloc] = subtype;
12170                 if (subtype != VSNORMAL) {
12171                         varnest++;
12172                         if (dblquote)
12173                                 dqvarnest++;
12174                 }
12175                 STPUTC('=', out);
12176         }
12177         goto parsesub_return;
12178 }
12179
12180 /*
12181  * Called to parse command substitutions.  Newstyle is set if the command
12182  * is enclosed inside $(...); nlpp is a pointer to the head of the linked
12183  * list of commands (passed by reference), and savelen is the number of
12184  * characters on the top of the stack which must be preserved.
12185  */
12186 parsebackq: {
12187         struct nodelist **nlpp;
12188         union node *n;
12189         char *str;
12190         size_t savelen;
12191         smallint saveprompt = 0;
12192
12193         str = NULL;
12194         savelen = out - (char *)stackblock();
12195         if (savelen > 0) {
12196                 /*
12197                  * FIXME: this can allocate very large block on stack and SEGV.
12198                  * Example:
12199                  * echo "..<100kbytes>..`true` $(true) `true` ..."
12200                  * allocates 100kb for every command subst. With about
12201                  * a hundred command substitutions stack overflows.
12202                  * With larger prepended string, SEGV happens sooner.
12203                  */
12204                 str = alloca(savelen);
12205                 memcpy(str, stackblock(), savelen);
12206         }
12207
12208         if (oldstyle) {
12209                 /* We must read until the closing backquote, giving special
12210                  * treatment to some slashes, and then push the string and
12211                  * reread it as input, interpreting it normally.
12212                  */
12213                 char *pout;
12214                 size_t psavelen;
12215                 char *pstr;
12216
12217                 STARTSTACKSTR(pout);
12218                 for (;;) {
12219                         int pc;
12220
12221                         setprompt_if(needprompt, 2);
12222                         pc = pgetc();
12223                         switch (pc) {
12224                         case '`':
12225                                 goto done;
12226
12227                         case '\\':
12228                                 pc = pgetc();
12229                                 if (pc == '\n') {
12230                                         nlprompt();
12231                                         /*
12232                                          * If eating a newline, avoid putting
12233                                          * the newline into the new character
12234                                          * stream (via the STPUTC after the
12235                                          * switch).
12236                                          */
12237                                         continue;
12238                                 }
12239                                 if (pc != '\\' && pc != '`' && pc != '$'
12240                                  && (!dblquote || pc != '"')
12241                                 ) {
12242                                         STPUTC('\\', pout);
12243                                 }
12244                                 if (pc <= 255 /* not PEOA or PEOF */) {
12245                                         break;
12246                                 }
12247                                 /* fall through */
12248
12249                         case PEOF:
12250                         IF_ASH_ALIAS(case PEOA:)
12251                                 startlinno = g_parsefile->linno;
12252                                 raise_error_syntax("EOF in backquote substitution");
12253
12254                         case '\n':
12255                                 nlnoprompt();
12256                                 break;
12257
12258                         default:
12259                                 break;
12260                         }
12261                         STPUTC(pc, pout);
12262                 }
12263  done:
12264                 STPUTC('\0', pout);
12265                 psavelen = pout - (char *)stackblock();
12266                 if (psavelen > 0) {
12267                         pstr = grabstackstr(pout);
12268                         setinputstring(pstr);
12269                 }
12270         }
12271         nlpp = &bqlist;
12272         while (*nlpp)
12273                 nlpp = &(*nlpp)->next;
12274         *nlpp = stzalloc(sizeof(**nlpp));
12275         /* (*nlpp)->next = NULL; - stzalloc did it */
12276
12277         if (oldstyle) {
12278                 saveprompt = doprompt;
12279                 doprompt = 0;
12280         }
12281
12282         n = list(2);
12283
12284         if (oldstyle)
12285                 doprompt = saveprompt;
12286         else if (readtoken() != TRP)
12287                 raise_error_unexpected_syntax(TRP);
12288
12289         (*nlpp)->n = n;
12290         if (oldstyle) {
12291                 /*
12292                  * Start reading from old file again, ignoring any pushed back
12293                  * tokens left from the backquote parsing
12294                  */
12295                 popfile();
12296                 tokpushback = 0;
12297         }
12298         while (stackblocksize() <= savelen)
12299                 growstackblock();
12300         STARTSTACKSTR(out);
12301         if (str) {
12302                 memcpy(out, str, savelen);
12303                 STADJUST(savelen, out);
12304         }
12305         USTPUTC(CTLBACKQ, out);
12306         if (oldstyle)
12307                 goto parsebackq_oldreturn;
12308         goto parsebackq_newreturn;
12309 }
12310
12311 #if ENABLE_FEATURE_SH_MATH
12312 /*
12313  * Parse an arithmetic expansion (indicate start of one and set state)
12314  */
12315 parsearith: {
12316         if (++arinest == 1) {
12317                 prevsyntax = syntax;
12318                 syntax = ARISYNTAX;
12319         }
12320         USTPUTC(CTLARI, out);
12321         goto parsearith_return;
12322 }
12323 #endif
12324 } /* end of readtoken */
12325
12326 /*
12327  * Read the next input token.
12328  * If the token is a word, we set backquotelist to the list of cmds in
12329  *      backquotes.  We set quoteflag to true if any part of the word was
12330  *      quoted.
12331  * If the token is TREDIR, then we set redirnode to a structure containing
12332  *      the redirection.
12333  * In all cases, the variable startlinno is set to the number of the line
12334  *      on which the token starts.
12335  *
12336  * [Change comment:  here documents and internal procedures]
12337  * [Readtoken shouldn't have any arguments.  Perhaps we should make the
12338  *  word parsing code into a separate routine.  In this case, readtoken
12339  *  doesn't need to have any internal procedures, but parseword does.
12340  *  We could also make parseoperator in essence the main routine, and
12341  *  have parseword (readtoken1?) handle both words and redirection.]
12342  */
12343 #define NEW_xxreadtoken
12344 #ifdef NEW_xxreadtoken
12345 /* singles must be first! */
12346 static const char xxreadtoken_chars[7] ALIGN1 = {
12347         '\n', '(', ')', /* singles */
12348         '&', '|', ';',  /* doubles */
12349         0
12350 };
12351
12352 #define xxreadtoken_singles 3
12353 #define xxreadtoken_doubles 3
12354
12355 static const char xxreadtoken_tokens[] ALIGN1 = {
12356         TNL, TLP, TRP,          /* only single occurrence allowed */
12357         TBACKGND, TPIPE, TSEMI, /* if single occurrence */
12358         TEOF,                   /* corresponds to trailing nul */
12359         TAND, TOR, TENDCASE     /* if double occurrence */
12360 };
12361
12362 static int
12363 xxreadtoken(void)
12364 {
12365         int c;
12366
12367         if (tokpushback) {
12368                 tokpushback = 0;
12369                 return lasttoken;
12370         }
12371         setprompt_if(needprompt, 2);
12372         startlinno = g_parsefile->linno;
12373         for (;;) {                      /* until token or start of word found */
12374                 c = pgetc();
12375                 if (c == ' ' || c == '\t' IF_ASH_ALIAS( || c == PEOA))
12376                         continue;
12377
12378                 if (c == '#') {
12379                         while ((c = pgetc()) != '\n' && c != PEOF)
12380                                 continue;
12381                         pungetc();
12382                 } else if (c == '\\') {
12383                         if (pgetc() != '\n') {
12384                                 pungetc();
12385                                 break; /* return readtoken1(...) */
12386                         }
12387                         nlprompt();
12388                 } else {
12389                         const char *p;
12390
12391                         p = xxreadtoken_chars + sizeof(xxreadtoken_chars) - 1;
12392                         if (c != PEOF) {
12393                                 if (c == '\n') {
12394                                         nlnoprompt();
12395                                 }
12396
12397                                 p = strchr(xxreadtoken_chars, c);
12398                                 if (p == NULL)
12399                                         break; /* return readtoken1(...) */
12400
12401                                 if ((int)(p - xxreadtoken_chars) >= xxreadtoken_singles) {
12402                                         int cc = pgetc();
12403                                         if (cc == c) {    /* double occurrence? */
12404                                                 p += xxreadtoken_doubles + 1;
12405                                         } else {
12406                                                 pungetc();
12407 #if BASH_REDIR_OUTPUT
12408                                                 if (c == '&' && cc == '>') /* &> */
12409                                                         break; /* return readtoken1(...) */
12410 #endif
12411                                         }
12412                                 }
12413                         }
12414                         lasttoken = xxreadtoken_tokens[p - xxreadtoken_chars];
12415                         return lasttoken;
12416                 }
12417         } /* for (;;) */
12418
12419         return readtoken1(c, BASESYNTAX, (char *) NULL, 0);
12420 }
12421 #else /* old xxreadtoken */
12422 #define RETURN(token)   return lasttoken = token
12423 static int
12424 xxreadtoken(void)
12425 {
12426         int c;
12427
12428         if (tokpushback) {
12429                 tokpushback = 0;
12430                 return lasttoken;
12431         }
12432         setprompt_if(needprompt, 2);
12433         startlinno = g_parsefile->linno;
12434         for (;;) {      /* until token or start of word found */
12435                 c = pgetc();
12436                 switch (c) {
12437                 case ' ': case '\t':
12438                 IF_ASH_ALIAS(case PEOA:)
12439                         continue;
12440                 case '#':
12441                         while ((c = pgetc()) != '\n' && c != PEOF)
12442                                 continue;
12443                         pungetc();
12444                         continue;
12445                 case '\\':
12446                         if (pgetc() == '\n') {
12447                                 nlprompt();
12448                                 continue;
12449                         }
12450                         pungetc();
12451                         goto breakloop;
12452                 case '\n':
12453                         nlnoprompt();
12454                         RETURN(TNL);
12455                 case PEOF:
12456                         RETURN(TEOF);
12457                 case '&':
12458                         if (pgetc() == '&')
12459                                 RETURN(TAND);
12460                         pungetc();
12461                         RETURN(TBACKGND);
12462                 case '|':
12463                         if (pgetc() == '|')
12464                                 RETURN(TOR);
12465                         pungetc();
12466                         RETURN(TPIPE);
12467                 case ';':
12468                         if (pgetc() == ';')
12469                                 RETURN(TENDCASE);
12470                         pungetc();
12471                         RETURN(TSEMI);
12472                 case '(':
12473                         RETURN(TLP);
12474                 case ')':
12475                         RETURN(TRP);
12476                 default:
12477                         goto breakloop;
12478                 }
12479         }
12480  breakloop:
12481         return readtoken1(c, BASESYNTAX, (char *)NULL, 0);
12482 #undef RETURN
12483 }
12484 #endif /* old xxreadtoken */
12485
12486 static int
12487 readtoken(void)
12488 {
12489         int t;
12490         int kwd = checkkwd;
12491 #if DEBUG
12492         smallint alreadyseen = tokpushback;
12493 #endif
12494
12495 #if ENABLE_ASH_ALIAS
12496  top:
12497 #endif
12498
12499         t = xxreadtoken();
12500
12501         /*
12502          * eat newlines
12503          */
12504         if (kwd & CHKNL) {
12505                 while (t == TNL) {
12506                         parseheredoc();
12507                         t = xxreadtoken();
12508                 }
12509         }
12510
12511         if (t != TWORD || quoteflag) {
12512                 goto out;
12513         }
12514
12515         /*
12516          * check for keywords
12517          */
12518         if (kwd & CHKKWD) {
12519                 const char *const *pp;
12520
12521                 pp = findkwd(wordtext);
12522                 if (pp) {
12523                         lasttoken = t = pp - tokname_array;
12524                         TRACE(("keyword '%s' recognized\n", tokname_array[t]));
12525                         goto out;
12526                 }
12527         }
12528
12529         if (checkkwd & CHKALIAS) {
12530 #if ENABLE_ASH_ALIAS
12531                 struct alias *ap;
12532                 ap = lookupalias(wordtext, 1);
12533                 if (ap != NULL) {
12534                         if (*ap->val) {
12535                                 pushstring(ap->val, ap);
12536                         }
12537                         goto top;
12538                 }
12539 #endif
12540         }
12541  out:
12542         checkkwd = 0;
12543 #if DEBUG
12544         if (!alreadyseen)
12545                 TRACE(("token '%s' %s\n", tokname_array[t], t == TWORD ? wordtext : ""));
12546         else
12547                 TRACE(("reread token '%s' %s\n", tokname_array[t], t == TWORD ? wordtext : ""));
12548 #endif
12549         return t;
12550 }
12551
12552 static int
12553 peektoken(void)
12554 {
12555         int t;
12556
12557         t = readtoken();
12558         tokpushback = 1;
12559         return t;
12560 }
12561
12562 /*
12563  * Read and parse a command.  Returns NODE_EOF on end of file.
12564  * (NULL is a valid parse tree indicating a blank line.)
12565  */
12566 static union node *
12567 parsecmd(int interact)
12568 {
12569         tokpushback = 0;
12570         checkkwd = 0;
12571         heredoclist = 0;
12572         doprompt = interact;
12573         setprompt_if(doprompt, doprompt);
12574         needprompt = 0;
12575         return list(1);
12576 }
12577
12578 /*
12579  * Input any here documents.
12580  */
12581 static void
12582 parseheredoc(void)
12583 {
12584         struct heredoc *here;
12585         union node *n;
12586
12587         here = heredoclist;
12588         heredoclist = NULL;
12589
12590         while (here) {
12591                 setprompt_if(needprompt, 2);
12592                 readtoken1(pgetc(), here->here->type == NHERE ? SQSYNTAX : DQSYNTAX,
12593                                 here->eofmark, here->striptabs);
12594                 n = stzalloc(sizeof(struct narg));
12595                 n->narg.type = NARG;
12596                 /*n->narg.next = NULL; - stzalloc did it */
12597                 n->narg.text = wordtext;
12598                 n->narg.backquote = backquotelist;
12599                 here->here->nhere.doc = n;
12600                 here = here->next;
12601         }
12602 }
12603
12604
12605 static const char *
12606 expandstr(const char *ps, int syntax_type)
12607 {
12608         union node n;
12609         int saveprompt;
12610
12611         /* XXX Fix (char *) cast. */
12612         setinputstring((char *)ps);
12613
12614         saveprompt = doprompt;
12615         doprompt = 0;
12616         readtoken1(pgetc(), syntax_type, FAKEEOFMARK, 0);
12617         doprompt = saveprompt;
12618
12619         popfile();
12620
12621         n.narg.type = NARG;
12622         n.narg.next = NULL;
12623         n.narg.text = wordtext;
12624         n.narg.backquote = backquotelist;
12625
12626         expandarg(&n, NULL, EXP_QUOTED);
12627         return stackblock();
12628 }
12629
12630 static inline int
12631 parser_eof(void)
12632 {
12633         return tokpushback && lasttoken == TEOF;
12634 }
12635
12636 /*
12637  * Execute a command or commands contained in a string.
12638  */
12639 static int
12640 evalstring(char *s, int flags)
12641 {
12642         struct jmploc *volatile savehandler;
12643         struct jmploc jmploc;
12644         int ex;
12645
12646         union node *n;
12647         struct stackmark smark;
12648         int status;
12649
12650         s = sstrdup(s);
12651         setinputstring(s);
12652         setstackmark(&smark);
12653
12654         status = 0;
12655         /* On exception inside execution loop, we must popfile().
12656          * Try interactively:
12657          *      readonly a=a
12658          *      command eval "a=b"  # throws "is read only" error
12659          * "command BLTIN" is not supposed to abort (even in non-interactive use).
12660          * But if we skip popfile(), we hit EOF in eval's string, and exit.
12661          */
12662         savehandler = exception_handler;
12663         ex = setjmp(jmploc.loc);
12664         if (ex)
12665                 goto out;
12666         exception_handler = &jmploc;
12667
12668         while ((n = parsecmd(0)) != NODE_EOF) {
12669                 int i;
12670
12671                 i = evaltree(n, flags & ~(parser_eof() ? 0 : EV_EXIT));
12672                 if (n)
12673                         status = i;
12674                 popstackmark(&smark);
12675                 if (evalskip)
12676                         break;
12677         }
12678  out:
12679         popstackmark(&smark);
12680         popfile();
12681         stunalloc(s);
12682
12683         exception_handler = savehandler;
12684         if (ex)
12685                 longjmp(exception_handler->loc, ex);
12686
12687         return status;
12688 }
12689
12690 /*
12691  * The eval command.
12692  */
12693 static int FAST_FUNC
12694 evalcmd(int argc UNUSED_PARAM, char **argv, int flags)
12695 {
12696         char *p;
12697         char *concat;
12698
12699         if (argv[1]) {
12700                 p = argv[1];
12701                 argv += 2;
12702                 if (argv[0]) {
12703                         STARTSTACKSTR(concat);
12704                         for (;;) {
12705                                 concat = stack_putstr(p, concat);
12706                                 p = *argv++;
12707                                 if (p == NULL)
12708                                         break;
12709                                 STPUTC(' ', concat);
12710                         }
12711                         STPUTC('\0', concat);
12712                         p = grabstackstr(concat);
12713                 }
12714                 return evalstring(p, flags & EV_TESTED);
12715         }
12716         return 0;
12717 }
12718
12719 /*
12720  * Read and execute commands.
12721  * "Top" is nonzero for the top level command loop;
12722  * it turns on prompting if the shell is interactive.
12723  */
12724 static int
12725 cmdloop(int top)
12726 {
12727         union node *n;
12728         struct stackmark smark;
12729         int inter;
12730         int status = 0;
12731         int numeof = 0;
12732
12733         TRACE(("cmdloop(%d) called\n", top));
12734         for (;;) {
12735                 int skip;
12736
12737                 setstackmark(&smark);
12738 #if JOBS
12739                 if (doing_jobctl)
12740                         showjobs(SHOW_CHANGED|SHOW_STDERR);
12741 #endif
12742                 inter = 0;
12743                 if (iflag && top) {
12744                         inter++;
12745                         chkmail();
12746                 }
12747                 n = parsecmd(inter);
12748 #if DEBUG
12749                 if (DEBUG > 2 && debug && (n != NODE_EOF))
12750                         showtree(n);
12751 #endif
12752                 if (n == NODE_EOF) {
12753                         if (!top || numeof >= 50)
12754                                 break;
12755                         if (!stoppedjobs()) {
12756                                 if (!Iflag)
12757                                         break;
12758                                 out2str("\nUse \"exit\" to leave shell.\n");
12759                         }
12760                         numeof++;
12761                 } else if (nflag == 0) {
12762                         int i;
12763
12764                         /* job_warning can only be 2,1,0. Here 2->1, 1/0->0 */
12765                         job_warning >>= 1;
12766                         numeof = 0;
12767                         i = evaltree(n, 0);
12768                         if (n)
12769                                 status = i;
12770                 }
12771                 popstackmark(&smark);
12772                 skip = evalskip;
12773
12774                 if (skip) {
12775                         evalskip &= ~SKIPFUNC;
12776                         break;
12777                 }
12778         }
12779         return status;
12780 }
12781
12782 /*
12783  * Take commands from a file.  To be compatible we should do a path
12784  * search for the file, which is necessary to find sub-commands.
12785  */
12786 static char *
12787 find_dot_file(char *name)
12788 {
12789         char *fullname;
12790         const char *path = pathval();
12791         struct stat statb;
12792
12793         /* don't try this for absolute or relative paths */
12794         if (strchr(name, '/'))
12795                 return name;
12796
12797         while ((fullname = path_advance(&path, name)) != NULL) {
12798                 if ((stat(fullname, &statb) == 0) && S_ISREG(statb.st_mode)) {
12799                         /*
12800                          * Don't bother freeing here, since it will
12801                          * be freed by the caller.
12802                          */
12803                         return fullname;
12804                 }
12805                 if (fullname != name)
12806                         stunalloc(fullname);
12807         }
12808
12809         /* not found in the PATH */
12810         ash_msg_and_raise_error("%s: not found", name);
12811         /* NOTREACHED */
12812 }
12813
12814 static int FAST_FUNC
12815 dotcmd(int argc_ UNUSED_PARAM, char **argv_ UNUSED_PARAM)
12816 {
12817         /* "false; . empty_file; echo $?" should print 0, not 1: */
12818         int status = 0;
12819         char *fullname;
12820         char **argv;
12821         char *args_need_save;
12822         volatile struct shparam saveparam;
12823
12824 //???
12825 //      struct strlist *sp;
12826 //      for (sp = cmdenviron; sp; sp = sp->next)
12827 //              setvareq(ckstrdup(sp->text), VSTRFIXED | VTEXTFIXED);
12828
12829         nextopt(nullstr); /* handle possible "--" */
12830         argv = argptr;
12831
12832         if (!argv[0]) {
12833                 /* bash says: "bash: .: filename argument required" */
12834                 return 2; /* bash compat */
12835         }
12836
12837         /* This aborts if file isn't found, which is POSIXly correct.
12838          * bash returns exitcode 1 instead.
12839          */
12840         fullname = find_dot_file(argv[0]);
12841         argv++;
12842         args_need_save = argv[0];
12843         if (args_need_save) { /* ". FILE ARGS", and ARGS are not empty */
12844                 int argc;
12845                 saveparam = shellparam;
12846                 shellparam.malloced = 0;
12847                 argc = 1;
12848                 while (argv[argc])
12849                         argc++;
12850                 shellparam.nparam = argc;
12851                 shellparam.p = argv;
12852         };
12853
12854         /* This aborts if file can't be opened, which is POSIXly correct.
12855          * bash returns exitcode 1 instead.
12856          */
12857         setinputfile(fullname, INPUT_PUSH_FILE);
12858         commandname = fullname;
12859         status = cmdloop(0);
12860         popfile();
12861
12862         if (args_need_save) {
12863                 freeparam(&shellparam);
12864                 shellparam = saveparam;
12865         };
12866
12867         return status;
12868 }
12869
12870 static int FAST_FUNC
12871 exitcmd(int argc UNUSED_PARAM, char **argv)
12872 {
12873         if (stoppedjobs())
12874                 return 0;
12875         if (argv[1])
12876                 exitstatus = number(argv[1]);
12877         raise_exception(EXEXIT);
12878         /* NOTREACHED */
12879 }
12880
12881 /*
12882  * Read a file containing shell functions.
12883  */
12884 static void
12885 readcmdfile(char *name)
12886 {
12887         setinputfile(name, INPUT_PUSH_FILE);
12888         cmdloop(0);
12889         popfile();
12890 }
12891
12892
12893 /* ============ find_command inplementation */
12894
12895 /*
12896  * Resolve a command name.  If you change this routine, you may have to
12897  * change the shellexec routine as well.
12898  */
12899 static void
12900 find_command(char *name, struct cmdentry *entry, int act, const char *path)
12901 {
12902         struct tblentry *cmdp;
12903         int idx;
12904         int prev;
12905         char *fullname;
12906         struct stat statb;
12907         int e;
12908         int updatetbl;
12909         struct builtincmd *bcmd;
12910
12911         /* If name contains a slash, don't use PATH or hash table */
12912         if (strchr(name, '/') != NULL) {
12913                 entry->u.index = -1;
12914                 if (act & DO_ABS) {
12915                         while (stat(name, &statb) < 0) {
12916 #ifdef SYSV
12917                                 if (errno == EINTR)
12918                                         continue;
12919 #endif
12920                                 entry->cmdtype = CMDUNKNOWN;
12921                                 return;
12922                         }
12923                 }
12924                 entry->cmdtype = CMDNORMAL;
12925                 return;
12926         }
12927
12928 /* #if ENABLE_FEATURE_SH_STANDALONE... moved after builtin check */
12929
12930         updatetbl = (path == pathval());
12931         if (!updatetbl) {
12932                 act |= DO_ALTPATH;
12933                 if (strstr(path, "%builtin") != NULL)
12934                         act |= DO_ALTBLTIN;
12935         }
12936
12937         /* If name is in the table, check answer will be ok */
12938         cmdp = cmdlookup(name, 0);
12939         if (cmdp != NULL) {
12940                 int bit;
12941
12942                 switch (cmdp->cmdtype) {
12943                 default:
12944 #if DEBUG
12945                         abort();
12946 #endif
12947                 case CMDNORMAL:
12948                         bit = DO_ALTPATH;
12949                         break;
12950                 case CMDFUNCTION:
12951                         bit = DO_NOFUNC;
12952                         break;
12953                 case CMDBUILTIN:
12954                         bit = DO_ALTBLTIN;
12955                         break;
12956                 }
12957                 if (act & bit) {
12958                         updatetbl = 0;
12959                         cmdp = NULL;
12960                 } else if (cmdp->rehash == 0)
12961                         /* if not invalidated by cd, we're done */
12962                         goto success;
12963         }
12964
12965         /* If %builtin not in path, check for builtin next */
12966         bcmd = find_builtin(name);
12967         if (bcmd) {
12968                 if (IS_BUILTIN_REGULAR(bcmd))
12969                         goto builtin_success;
12970                 if (act & DO_ALTPATH) {
12971                         if (!(act & DO_ALTBLTIN))
12972                                 goto builtin_success;
12973                 } else if (builtinloc <= 0) {
12974                         goto builtin_success;
12975                 }
12976         }
12977
12978 #if ENABLE_FEATURE_SH_STANDALONE
12979         {
12980                 int applet_no = find_applet_by_name(name);
12981                 if (applet_no >= 0) {
12982                         entry->cmdtype = CMDNORMAL;
12983                         entry->u.index = -2 - applet_no;
12984                         return;
12985                 }
12986         }
12987 #endif
12988
12989         /* We have to search path. */
12990         prev = -1;              /* where to start */
12991         if (cmdp && cmdp->rehash) {     /* doing a rehash */
12992                 if (cmdp->cmdtype == CMDBUILTIN)
12993                         prev = builtinloc;
12994                 else
12995                         prev = cmdp->param.index;
12996         }
12997
12998         e = ENOENT;
12999         idx = -1;
13000  loop:
13001         while ((fullname = path_advance(&path, name)) != NULL) {
13002                 stunalloc(fullname);
13003                 /* NB: code below will still use fullname
13004                  * despite it being "unallocated" */
13005                 idx++;
13006                 if (pathopt) {
13007                         if (prefix(pathopt, "builtin")) {
13008                                 if (bcmd)
13009                                         goto builtin_success;
13010                                 continue;
13011                         }
13012                         if ((act & DO_NOFUNC)
13013                          || !prefix(pathopt, "func")
13014                         ) {     /* ignore unimplemented options */
13015                                 continue;
13016                         }
13017                 }
13018                 /* if rehash, don't redo absolute path names */
13019                 if (fullname[0] == '/' && idx <= prev) {
13020                         if (idx < prev)
13021                                 continue;
13022                         TRACE(("searchexec \"%s\": no change\n", name));
13023                         goto success;
13024                 }
13025                 while (stat(fullname, &statb) < 0) {
13026 #ifdef SYSV
13027                         if (errno == EINTR)
13028                                 continue;
13029 #endif
13030                         if (errno != ENOENT && errno != ENOTDIR)
13031                                 e = errno;
13032                         goto loop;
13033                 }
13034                 e = EACCES;     /* if we fail, this will be the error */
13035                 if (!S_ISREG(statb.st_mode))
13036                         continue;
13037                 if (pathopt) {          /* this is a %func directory */
13038                         stalloc(strlen(fullname) + 1);
13039                         /* NB: stalloc will return space pointed by fullname
13040                          * (because we don't have any intervening allocations
13041                          * between stunalloc above and this stalloc) */
13042                         readcmdfile(fullname);
13043                         cmdp = cmdlookup(name, 0);
13044                         if (cmdp == NULL || cmdp->cmdtype != CMDFUNCTION)
13045                                 ash_msg_and_raise_error("%s not defined in %s", name, fullname);
13046                         stunalloc(fullname);
13047                         goto success;
13048                 }
13049                 TRACE(("searchexec \"%s\" returns \"%s\"\n", name, fullname));
13050                 if (!updatetbl) {
13051                         entry->cmdtype = CMDNORMAL;
13052                         entry->u.index = idx;
13053                         return;
13054                 }
13055                 INT_OFF;
13056                 cmdp = cmdlookup(name, 1);
13057                 cmdp->cmdtype = CMDNORMAL;
13058                 cmdp->param.index = idx;
13059                 INT_ON;
13060                 goto success;
13061         }
13062
13063         /* We failed.  If there was an entry for this command, delete it */
13064         if (cmdp && updatetbl)
13065                 delete_cmd_entry();
13066         if (act & DO_ERR)
13067                 ash_msg("%s: %s", name, errmsg(e, "not found"));
13068         entry->cmdtype = CMDUNKNOWN;
13069         return;
13070
13071  builtin_success:
13072         if (!updatetbl) {
13073                 entry->cmdtype = CMDBUILTIN;
13074                 entry->u.cmd = bcmd;
13075                 return;
13076         }
13077         INT_OFF;
13078         cmdp = cmdlookup(name, 1);
13079         cmdp->cmdtype = CMDBUILTIN;
13080         cmdp->param.cmd = bcmd;
13081         INT_ON;
13082  success:
13083         cmdp->rehash = 0;
13084         entry->cmdtype = cmdp->cmdtype;
13085         entry->u = cmdp->param;
13086 }
13087
13088
13089 /*
13090  * The trap builtin.
13091  */
13092 static int FAST_FUNC
13093 trapcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
13094 {
13095         char *action;
13096         char **ap;
13097         int signo, exitcode;
13098
13099         nextopt(nullstr);
13100         ap = argptr;
13101         if (!*ap) {
13102                 for (signo = 0; signo < NSIG; signo++) {
13103                         char *tr = trap_ptr[signo];
13104                         if (tr) {
13105                                 /* note: bash adds "SIG", but only if invoked
13106                                  * as "bash". If called as "sh", or if set -o posix,
13107                                  * then it prints short signal names.
13108                                  * We are printing short names: */
13109                                 out1fmt("trap -- %s %s\n",
13110                                                 single_quote(tr),
13111                                                 get_signame(signo));
13112                 /* trap_ptr != trap only if we are in special-cased `trap` code.
13113                  * In this case, we will exit very soon, no need to free(). */
13114                                 /* if (trap_ptr != trap && tp[0]) */
13115                                 /*      free(tr); */
13116                         }
13117                 }
13118                 /*
13119                 if (trap_ptr != trap) {
13120                         free(trap_ptr);
13121                         trap_ptr = trap;
13122                 }
13123                 */
13124                 return 0;
13125         }
13126
13127         /* Why the second check?
13128          * "trap NUM [sig2]..." is the same as "trap - NUM [sig2]..."
13129          * In this case, NUM is signal no, not an action.
13130          */
13131         action = NULL;
13132         if (ap[1] && !is_number(ap[0]))
13133                 action = *ap++;
13134
13135         exitcode = 0;
13136         while (*ap) {
13137                 signo = get_signum(*ap);
13138                 if (signo < 0) {
13139                         /* Mimic bash message exactly */
13140                         ash_msg("%s: invalid signal specification", *ap);
13141                         exitcode = 1;
13142                         goto next;
13143                 }
13144                 INT_OFF;
13145                 if (action) {
13146                         if (LONE_DASH(action))
13147                                 action = NULL;
13148                         else {
13149                                 if (action[0]) /* not NULL and not "" and not "-" */
13150                                         may_have_traps = 1;
13151                                 action = ckstrdup(action);
13152                         }
13153                 }
13154                 free(trap[signo]);
13155                 trap[signo] = action;
13156                 if (signo != 0)
13157                         setsignal(signo);
13158                 INT_ON;
13159  next:
13160                 ap++;
13161         }
13162         return exitcode;
13163 }
13164
13165
13166 /* ============ Builtins */
13167
13168 #if ENABLE_ASH_HELP
13169 static int FAST_FUNC
13170 helpcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
13171 {
13172         unsigned col;
13173         unsigned i;
13174
13175         out1fmt(
13176                 "Built-in commands:\n"
13177                 "------------------\n");
13178         for (col = 0, i = 0; i < ARRAY_SIZE(builtintab); i++) {
13179                 col += out1fmt("%c%s", ((col == 0) ? '\t' : ' '),
13180                                         builtintab[i].name + 1);
13181                 if (col > 60) {
13182                         out1fmt("\n");
13183                         col = 0;
13184                 }
13185         }
13186 # if ENABLE_FEATURE_SH_STANDALONE
13187         {
13188                 const char *a = applet_names;
13189                 while (*a) {
13190                         col += out1fmt("%c%s", ((col == 0) ? '\t' : ' '), a);
13191                         if (col > 60) {
13192                                 out1fmt("\n");
13193                                 col = 0;
13194                         }
13195                         while (*a++ != '\0')
13196                                 continue;
13197                 }
13198         }
13199 # endif
13200         newline_and_flush(stdout);
13201         return EXIT_SUCCESS;
13202 }
13203 #endif
13204
13205 #if MAX_HISTORY
13206 static int FAST_FUNC
13207 historycmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
13208 {
13209         show_history(line_input_state);
13210         return EXIT_SUCCESS;
13211 }
13212 #endif
13213
13214 /*
13215  * The export and readonly commands.
13216  */
13217 static int FAST_FUNC
13218 exportcmd(int argc UNUSED_PARAM, char **argv)
13219 {
13220         struct var *vp;
13221         char *name;
13222         const char *p;
13223         char **aptr;
13224         char opt;
13225         int flag;
13226         int flag_off;
13227
13228         /* "readonly" in bash accepts, but ignores -n.
13229          * We do the same: it saves a conditional in nextopt's param.
13230          */
13231         flag_off = 0;
13232         while ((opt = nextopt("np")) != '\0') {
13233                 if (opt == 'n')
13234                         flag_off = VEXPORT;
13235         }
13236         flag = VEXPORT;
13237         if (argv[0][0] == 'r') {
13238                 flag = VREADONLY;
13239                 flag_off = 0; /* readonly ignores -n */
13240         }
13241         flag_off = ~flag_off;
13242
13243         /*if (opt_p_not_specified) - bash doesn't check this. Try "export -p NAME" */
13244         {
13245                 aptr = argptr;
13246                 name = *aptr;
13247                 if (name) {
13248                         do {
13249                                 p = strchr(name, '=');
13250                                 if (p != NULL) {
13251                                         p++;
13252                                 } else {
13253                                         vp = *findvar(hashvar(name), name);
13254                                         if (vp) {
13255                                                 vp->flags = ((vp->flags | flag) & flag_off);
13256                                                 continue;
13257                                         }
13258                                 }
13259                                 setvar(name, p, (flag & flag_off));
13260                         } while ((name = *++aptr) != NULL);
13261                         return 0;
13262                 }
13263         }
13264
13265         /* No arguments. Show the list of exported or readonly vars.
13266          * -n is ignored.
13267          */
13268         showvars(argv[0], flag, 0);
13269         return 0;
13270 }
13271
13272 /*
13273  * Delete a function if it exists.
13274  */
13275 static void
13276 unsetfunc(const char *name)
13277 {
13278         struct tblentry *cmdp;
13279
13280         cmdp = cmdlookup(name, 0);
13281         if (cmdp != NULL && cmdp->cmdtype == CMDFUNCTION)
13282                 delete_cmd_entry();
13283 }
13284
13285 /*
13286  * The unset builtin command.  We unset the function before we unset the
13287  * variable to allow a function to be unset when there is a readonly variable
13288  * with the same name.
13289  */
13290 static int FAST_FUNC
13291 unsetcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
13292 {
13293         char **ap;
13294         int i;
13295         int flag = 0;
13296
13297         while ((i = nextopt("vf")) != 0) {
13298                 flag = i;
13299         }
13300
13301         for (ap = argptr; *ap; ap++) {
13302                 if (flag != 'f') {
13303                         unsetvar(*ap);
13304                         continue;
13305                 }
13306                 if (flag != 'v')
13307                         unsetfunc(*ap);
13308         }
13309         return 0;
13310 }
13311
13312 static const unsigned char timescmd_str[] ALIGN1 = {
13313         ' ',  offsetof(struct tms, tms_utime),
13314         '\n', offsetof(struct tms, tms_stime),
13315         ' ',  offsetof(struct tms, tms_cutime),
13316         '\n', offsetof(struct tms, tms_cstime),
13317         0
13318 };
13319 static int FAST_FUNC
13320 timescmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
13321 {
13322         unsigned long clk_tck, s, t;
13323         const unsigned char *p;
13324         struct tms buf;
13325
13326         clk_tck = bb_clk_tck();
13327         times(&buf);
13328
13329         p = timescmd_str;
13330         do {
13331                 t = *(clock_t *)(((char *) &buf) + p[1]);
13332                 s = t / clk_tck;
13333                 t = t % clk_tck;
13334                 out1fmt("%lum%lu.%03lus%c",
13335                         s / 60, s % 60,
13336                         (t * 1000) / clk_tck,
13337                         p[0]);
13338                 p += 2;
13339         } while (*p);
13340
13341         return 0;
13342 }
13343
13344 #if ENABLE_FEATURE_SH_MATH
13345 /*
13346  * The let builtin. Partially stolen from GNU Bash, the Bourne Again SHell.
13347  * Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
13348  *
13349  * Copyright (C) 2003 Vladimir Oleynik <dzo@simtreas.ru>
13350  */
13351 static int FAST_FUNC
13352 letcmd(int argc UNUSED_PARAM, char **argv)
13353 {
13354         arith_t i;
13355
13356         argv++;
13357         if (!*argv)
13358                 ash_msg_and_raise_error("expression expected");
13359         do {
13360                 i = ash_arith(*argv);
13361         } while (*++argv);
13362
13363         return !i;
13364 }
13365 #endif
13366
13367 /*
13368  * The read builtin. Options:
13369  *      -r              Do not interpret '\' specially
13370  *      -s              Turn off echo (tty only)
13371  *      -n NCHARS       Read NCHARS max
13372  *      -p PROMPT       Display PROMPT on stderr (if input is from tty)
13373  *      -t SECONDS      Timeout after SECONDS (tty or pipe only)
13374  *      -u FD           Read from given FD instead of fd 0
13375  * This uses unbuffered input, which may be avoidable in some cases.
13376  * TODO: bash also has:
13377  *      -a ARRAY        Read into array[0],[1],etc
13378  *      -d DELIM        End on DELIM char, not newline
13379  *      -e              Use line editing (tty only)
13380  */
13381 static int FAST_FUNC
13382 readcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
13383 {
13384         char *opt_n = NULL;
13385         char *opt_p = NULL;
13386         char *opt_t = NULL;
13387         char *opt_u = NULL;
13388         int read_flags = 0;
13389         const char *r;
13390         int i;
13391
13392         while ((i = nextopt("p:u:rt:n:s")) != '\0') {
13393                 switch (i) {
13394                 case 'p':
13395                         opt_p = optionarg;
13396                         break;
13397                 case 'n':
13398                         opt_n = optionarg;
13399                         break;
13400                 case 's':
13401                         read_flags |= BUILTIN_READ_SILENT;
13402                         break;
13403                 case 't':
13404                         opt_t = optionarg;
13405                         break;
13406                 case 'r':
13407                         read_flags |= BUILTIN_READ_RAW;
13408                         break;
13409                 case 'u':
13410                         opt_u = optionarg;
13411                         break;
13412                 default:
13413                         break;
13414                 }
13415         }
13416
13417         /* "read -s" needs to save/restore termios, can't allow ^C
13418          * to jump out of it.
13419          */
13420  again:
13421         INT_OFF;
13422         r = shell_builtin_read(setvar0,
13423                 argptr,
13424                 bltinlookup("IFS"), /* can be NULL */
13425                 read_flags,
13426                 opt_n,
13427                 opt_p,
13428                 opt_t,
13429                 opt_u
13430         );
13431         INT_ON;
13432
13433         if ((uintptr_t)r == 1 && errno == EINTR) {
13434                 /* To get SIGCHLD: sleep 1 & read x; echo $x
13435                  * Correct behavior is to not exit "read"
13436                  */
13437                 if (pending_sig == 0)
13438                         goto again;
13439         }
13440
13441         if ((uintptr_t)r > 1)
13442                 ash_msg_and_raise_error(r);
13443
13444         return (uintptr_t)r;
13445 }
13446
13447 static int FAST_FUNC
13448 umaskcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
13449 {
13450         static const char permuser[3] ALIGN1 = "ogu";
13451
13452         mode_t mask;
13453         int symbolic_mode = 0;
13454
13455         while (nextopt("S") != '\0') {
13456                 symbolic_mode = 1;
13457         }
13458
13459         INT_OFF;
13460         mask = umask(0);
13461         umask(mask);
13462         INT_ON;
13463
13464         if (*argptr == NULL) {
13465                 if (symbolic_mode) {
13466                         char buf[sizeof(",u=rwx,g=rwx,o=rwx")];
13467                         char *p = buf;
13468                         int i;
13469
13470                         i = 2;
13471                         for (;;) {
13472                                 *p++ = ',';
13473                                 *p++ = permuser[i];
13474                                 *p++ = '=';
13475                                 /* mask is 0..0uuugggooo. i=2 selects uuu bits */
13476                                 if (!(mask & 0400)) *p++ = 'r';
13477                                 if (!(mask & 0200)) *p++ = 'w';
13478                                 if (!(mask & 0100)) *p++ = 'x';
13479                                 mask <<= 3;
13480                                 if (--i < 0)
13481                                         break;
13482                         }
13483                         *p = '\0';
13484                         puts(buf + 1);
13485                 } else {
13486                         out1fmt("%04o\n", mask);
13487                 }
13488         } else {
13489                 char *modestr = *argptr;
13490                 /* numeric umasks are taken as-is */
13491                 /* symbolic umasks are inverted: "umask a=rx" calls umask(222) */
13492                 if (!isdigit(modestr[0]))
13493                         mask ^= 0777;
13494                 mask = bb_parse_mode(modestr, mask);
13495                 if ((unsigned)mask > 0777) {
13496                         ash_msg_and_raise_error("illegal mode: %s", modestr);
13497                 }
13498                 if (!isdigit(modestr[0]))
13499                         mask ^= 0777;
13500                 umask(mask);
13501         }
13502         return 0;
13503 }
13504
13505 static int FAST_FUNC
13506 ulimitcmd(int argc UNUSED_PARAM, char **argv)
13507 {
13508         return shell_builtin_ulimit(argv);
13509 }
13510
13511 /* ============ main() and helpers */
13512
13513 /*
13514  * Called to exit the shell.
13515  */
13516 static void
13517 exitshell(void)
13518 {
13519         struct jmploc loc;
13520         char *p;
13521         int status;
13522
13523 #if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT
13524         save_history(line_input_state);
13525 #endif
13526         status = exitstatus;
13527         TRACE(("pid %d, exitshell(%d)\n", getpid(), status));
13528         if (setjmp(loc.loc)) {
13529                 if (exception_type == EXEXIT)
13530                         status = exitstatus;
13531                 goto out;
13532         }
13533         exception_handler = &loc;
13534         p = trap[0];
13535         if (p) {
13536                 trap[0] = NULL;
13537                 evalskip = 0;
13538                 evalstring(p, 0);
13539                 /*free(p); - we'll exit soon */
13540         }
13541  out:
13542         /* dash wraps setjobctl(0) in "if (setjmp(loc.loc) == 0) {...}".
13543          * our setjobctl(0) does not panic if tcsetpgrp fails inside it.
13544          */
13545         setjobctl(0);
13546         flush_stdout_stderr();
13547         _exit(status);
13548         /* NOTREACHED */
13549 }
13550
13551 /* Don't inline: conserve stack of caller from having our locals too */
13552 static NOINLINE void
13553 init(void)
13554 {
13555         /* we will never free this */
13556         basepf.next_to_pgetc = basepf.buf = ckmalloc(IBUFSIZ);
13557
13558         sigmode[SIGCHLD - 1] = S_DFL; /* ensure we install handler even if it is SIG_IGNed */
13559         setsignal(SIGCHLD);
13560
13561         /* bash re-enables SIGHUP which is SIG_IGNed on entry.
13562          * Try: "trap '' HUP; bash; echo RET" and type "kill -HUP $$"
13563          */
13564         signal(SIGHUP, SIG_DFL);
13565
13566         {
13567                 char **envp;
13568                 const char *p;
13569
13570                 initvar();
13571                 for (envp = environ; envp && *envp; envp++) {
13572                         p = endofname(*envp);
13573                         if (p != *envp && *p == '=') {
13574                                 setvareq(*envp, VEXPORT|VTEXTFIXED);
13575                         }
13576                 }
13577
13578                 setvareq((char*)defoptindvar, VTEXTFIXED);
13579
13580                 setvar0("PPID", utoa(getppid()));
13581 #if BASH_SHLVL_VAR
13582                 p = lookupvar("SHLVL");
13583                 setvar("SHLVL", utoa((p ? atoi(p) : 0) + 1), VEXPORT);
13584 #endif
13585 #if BASH_HOSTNAME_VAR
13586                 if (!lookupvar("HOSTNAME")) {
13587                         struct utsname uts;
13588                         uname(&uts);
13589                         setvar0("HOSTNAME", uts.nodename);
13590                 }
13591 #endif
13592                 p = lookupvar("PWD");
13593                 if (p) {
13594                         struct stat st1, st2;
13595                         if (p[0] != '/' || stat(p, &st1) || stat(".", &st2)
13596                          || st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino
13597                         ) {
13598                                 p = NULL;
13599                         }
13600                 }
13601                 setpwd(p, 0);
13602         }
13603 }
13604
13605
13606 //usage:#define ash_trivial_usage
13607 //usage:        "[-/+OPTIONS] [-/+o OPT]... [-c 'SCRIPT' [ARG0 [ARGS]] / FILE [ARGS]]"
13608 //usage:#define ash_full_usage "\n\n"
13609 //usage:        "Unix shell interpreter"
13610
13611 /*
13612  * Process the shell command line arguments.
13613  */
13614 static int
13615 procargs(char **argv)
13616 {
13617         int i;
13618         const char *xminusc;
13619         char **xargv;
13620         int login_sh;
13621
13622         xargv = argv;
13623         login_sh = xargv[0] && xargv[0][0] == '-';
13624         arg0 = xargv[0];
13625         /* if (xargv[0]) - mmm, this is always true! */
13626                 xargv++;
13627         for (i = 0; i < NOPTS; i++)
13628                 optlist[i] = 2;
13629         argptr = xargv;
13630         if (options(/*cmdline:*/ 1, &login_sh)) {
13631                 /* it already printed err message */
13632                 raise_exception(EXERROR);
13633         }
13634         xargv = argptr;
13635         xminusc = minusc;
13636         if (*xargv == NULL) {
13637                 if (xminusc)
13638                         ash_msg_and_raise_error(bb_msg_requires_arg, "-c");
13639                 sflag = 1;
13640         }
13641         if (iflag == 2 && sflag == 1 && isatty(0) && isatty(1))
13642                 iflag = 1;
13643         if (mflag == 2)
13644                 mflag = iflag;
13645         for (i = 0; i < NOPTS; i++)
13646                 if (optlist[i] == 2)
13647                         optlist[i] = 0;
13648 #if DEBUG == 2
13649         debug = 1;
13650 #endif
13651         /* POSIX 1003.2: first arg after "-c CMD" is $0, remainder $1... */
13652         if (xminusc) {
13653                 minusc = *xargv++;
13654                 if (*xargv)
13655                         goto setarg0;
13656         } else if (!sflag) {
13657                 setinputfile(*xargv, 0);
13658  setarg0:
13659                 arg0 = *xargv++;
13660                 commandname = arg0;
13661         }
13662
13663         shellparam.p = xargv;
13664 #if ENABLE_ASH_GETOPTS
13665         shellparam.optind = 1;
13666         shellparam.optoff = -1;
13667 #endif
13668         /* assert(shellparam.malloced == 0 && shellparam.nparam == 0); */
13669         while (*xargv) {
13670                 shellparam.nparam++;
13671                 xargv++;
13672         }
13673         optschanged();
13674
13675         return login_sh;
13676 }
13677
13678 /*
13679  * Read /etc/profile, ~/.profile, $ENV.
13680  */
13681 static void
13682 read_profile(const char *name)
13683 {
13684         name = expandstr(name, DQSYNTAX);
13685         if (setinputfile(name, INPUT_PUSH_FILE | INPUT_NOFILE_OK) < 0)
13686                 return;
13687         cmdloop(0);
13688         popfile();
13689 }
13690
13691 /*
13692  * This routine is called when an error or an interrupt occurs in an
13693  * interactive shell and control is returned to the main command loop.
13694  * (In dash, this function is auto-generated by build machinery).
13695  */
13696 static void
13697 reset(void)
13698 {
13699         /* from eval.c: */
13700         evalskip = 0;
13701         loopnest = 0;
13702
13703         /* from expand.c: */
13704         ifsfree();
13705
13706         /* from input.c: */
13707         g_parsefile->left_in_buffer = 0;
13708         g_parsefile->left_in_line = 0;      /* clear input buffer */
13709         popallfiles();
13710
13711         /* from redir.c: */
13712         unwindredir(NULL);
13713
13714         /* from var.c: */
13715         unwindlocalvars(NULL);
13716 }
13717
13718 #if PROFILE
13719 static short profile_buf[16384];
13720 extern int etext();
13721 #endif
13722
13723 /*
13724  * Main routine.  We initialize things, parse the arguments, execute
13725  * profiles if we're a login shell, and then call cmdloop to execute
13726  * commands.  The setjmp call sets up the location to jump to when an
13727  * exception occurs.  When an exception occurs the variable "state"
13728  * is used to figure out how far we had gotten.
13729  */
13730 int ash_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
13731 int ash_main(int argc UNUSED_PARAM, char **argv)
13732 {
13733         volatile smallint state;
13734         struct jmploc jmploc;
13735         struct stackmark smark;
13736         int login_sh;
13737
13738         /* Initialize global data */
13739         INIT_G_misc();
13740         INIT_G_memstack();
13741         INIT_G_var();
13742 #if ENABLE_ASH_ALIAS
13743         INIT_G_alias();
13744 #endif
13745         INIT_G_cmdtable();
13746
13747 #if PROFILE
13748         monitor(4, etext, profile_buf, sizeof(profile_buf), 50);
13749 #endif
13750
13751 #if ENABLE_FEATURE_EDITING
13752         line_input_state = new_line_input_t(FOR_SHELL | WITH_PATH_LOOKUP);
13753 #endif
13754         state = 0;
13755         if (setjmp(jmploc.loc)) {
13756                 smallint e;
13757                 smallint s;
13758
13759                 reset();
13760
13761                 e = exception_type;
13762                 s = state;
13763                 if (e == EXEXIT || s == 0 || iflag == 0 || shlvl) {
13764                         exitshell();
13765                 }
13766                 if (e == EXINT) {
13767                         newline_and_flush(stderr);
13768                 }
13769
13770                 popstackmark(&smark);
13771                 FORCE_INT_ON; /* enable interrupts */
13772                 if (s == 1)
13773                         goto state1;
13774                 if (s == 2)
13775                         goto state2;
13776                 if (s == 3)
13777                         goto state3;
13778                 goto state4;
13779         }
13780         exception_handler = &jmploc;
13781         rootpid = getpid();
13782
13783         init();
13784         setstackmark(&smark);
13785         login_sh = procargs(argv);
13786 #if DEBUG
13787         TRACE(("Shell args: "));
13788         trace_puts_args(argv);
13789 #endif
13790
13791         if (login_sh) {
13792                 const char *hp;
13793
13794                 state = 1;
13795                 read_profile("/etc/profile");
13796  state1:
13797                 state = 2;
13798                 hp = lookupvar("HOME");
13799                 if (hp)
13800                         read_profile("$HOME/.profile");
13801         }
13802  state2:
13803         state = 3;
13804         if (
13805 #ifndef linux
13806          getuid() == geteuid() && getgid() == getegid() &&
13807 #endif
13808          iflag
13809         ) {
13810                 const char *shinit = lookupvar("ENV");
13811                 if (shinit != NULL && *shinit != '\0')
13812                         read_profile(shinit);
13813         }
13814         popstackmark(&smark);
13815  state3:
13816         state = 4;
13817         if (minusc) {
13818                 /* evalstring pushes parsefile stack.
13819                  * Ensure we don't falsely claim that 0 (stdin)
13820                  * is one of stacked source fds.
13821                  * Testcase: ash -c 'exec 1>&0' must not complain. */
13822                 // if (!sflag) g_parsefile->pf_fd = -1;
13823                 // ^^ not necessary since now we special-case fd 0
13824                 // in save_fd_on_redirect()
13825                 evalstring(minusc, sflag ? 0 : EV_EXIT);
13826         }
13827
13828         if (sflag || minusc == NULL) {
13829 #if MAX_HISTORY > 0 && ENABLE_FEATURE_EDITING_SAVEHISTORY
13830                 if (iflag) {
13831                         const char *hp = lookupvar("HISTFILE");
13832                         if (!hp) {
13833                                 hp = lookupvar("HOME");
13834                                 if (hp) {
13835                                         INT_OFF;
13836                                         hp = concat_path_file(hp, ".ash_history");
13837                                         setvar0("HISTFILE", hp);
13838                                         free((char*)hp);
13839                                         INT_ON;
13840                                         hp = lookupvar("HISTFILE");
13841                                 }
13842                         }
13843                         if (hp)
13844                                 line_input_state->hist_file = hp;
13845 # if ENABLE_FEATURE_SH_HISTFILESIZE
13846                         hp = lookupvar("HISTFILESIZE");
13847                         line_input_state->max_history = size_from_HISTFILESIZE(hp);
13848 # endif
13849                 }
13850 #endif
13851  state4: /* XXX ??? - why isn't this before the "if" statement */
13852                 cmdloop(1);
13853         }
13854 #if PROFILE
13855         monitor(0);
13856 #endif
13857 #ifdef GPROF
13858         {
13859                 extern void _mcleanup(void);
13860                 _mcleanup();
13861         }
13862 #endif
13863         TRACE(("End of main reached\n"));
13864         exitshell();
13865         /* NOTREACHED */
13866 }
13867
13868
13869 /*-
13870  * Copyright (c) 1989, 1991, 1993, 1994
13871  *      The Regents of the University of California.  All rights reserved.
13872  *
13873  * This code is derived from software contributed to Berkeley by
13874  * Kenneth Almquist.
13875  *
13876  * Redistribution and use in source and binary forms, with or without
13877  * modification, are permitted provided that the following conditions
13878  * are met:
13879  * 1. Redistributions of source code must retain the above copyright
13880  *    notice, this list of conditions and the following disclaimer.
13881  * 2. Redistributions in binary form must reproduce the above copyright
13882  *    notice, this list of conditions and the following disclaimer in the
13883  *    documentation and/or other materials provided with the distribution.
13884  * 3. Neither the name of the University nor the names of its contributors
13885  *    may be used to endorse or promote products derived from this software
13886  *    without specific prior written permission.
13887  *
13888  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ''AS IS'' AND
13889  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
13890  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
13891  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
13892  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
13893  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
13894  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
13895  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
13896  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
13897  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
13898  * SUCH DAMAGE.
13899  */