1 /* vi: set sw=4 ts=4: */
3 * ash shell port for busybox
5 * Copyright (c) 1989, 1991, 1993, 1994
6 * The Regents of the University of California. All rights reserved.
8 * Copyright (c) 1997-2005 Herbert Xu <herbert@gondor.apana.org.au>
9 * was re-ported from NetBSD and debianized.
12 * This code is derived from software contributed to Berkeley by
15 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
17 * Original BSD copyright notice is retained at the end of this file.
21 * rewrite arith.y to micro stack based cryptic algorithm by
22 * Copyright (c) 2001 Aaron Lehmann <aaronl@vitelus.com>
24 * Modified by Paul Mundt <lethal@linux-sh.org> (c) 2004 to support
27 * Modified by Vladimir Oleynik <dzo@simtreas.ru> (c) 2001-2005 to be
28 * used in busybox and size optimizations,
29 * rewrote arith (see notes to this), added locale support,
30 * rewrote dynamic variables.
35 * The follow should be set to reflect the type of system you have:
36 * JOBS -> 1 if you have Berkeley job control, 0 otherwise.
37 * define SYSV if you are running under System V.
38 * define DEBUG=1 to compile in debugging ('set -o debug' to turn on)
39 * define DEBUG=2 to compile in and turn on debugging.
41 * When debugging is on, debugging info will be written to ./trace and
42 * a quit signal will generate a core dump.
47 #if ENABLE_ASH_JOB_CONTROL
60 #if JOBS || ENABLE_ASH_READ_NCHARS
64 #if defined(__uClinux__)
65 #error "Do not even bother, ash will not run on uClinux"
69 #define TRACE(param) trace param
70 #define TRACEV(param) tracev param
78 static int *dash_errno;
80 #define errno (*dash_errno)
93 static int aliascmd(int, char **);
94 static int unaliascmd(int, char **);
95 static void printalias(const struct alias *);
99 /* ============ Shell options */
101 static const char *const optletters_optnames[] = {
122 #define optletters(n) optletters_optnames[(n)][0]
123 #define optnames(n) (&optletters_optnames[(n)][1])
125 #define NOPTS (sizeof(optletters_optnames)/sizeof(optletters_optnames[0]))
127 static char optlist[NOPTS];
129 #define eflag optlist[0]
130 #define fflag optlist[1]
131 #define Iflag optlist[2]
132 #define iflag optlist[3]
133 #define mflag optlist[4]
134 #define nflag optlist[5]
135 #define sflag optlist[6]
136 #define xflag optlist[7]
137 #define vflag optlist[8]
138 #define Cflag optlist[9]
139 #define aflag optlist[10]
140 #define bflag optlist[11]
141 #define uflag optlist[12]
142 #define viflag optlist[13]
144 #define nolog optlist[14]
145 #define debug optlist[15]
149 /* ============ Misc data */
151 static char nullstr[1]; /* zero length string */
152 static const char homestr[] = "HOME";
153 static const char snlfmt[] = "%s\n";
154 static const char illnum[] = "Illegal number: %s";
156 static int isloginsh;
157 /* pid of main shell */
159 /* shell level: 0 for the main shell, 1 for its children, and so on */
161 #define rootshell (!shlvl)
162 /* trap handler commands */
163 static char *trap[NSIG];
164 /* current value of signal */
165 static char sigmode[NSIG - 1];
166 /* indicates specified signal received */
167 static char gotsig[NSIG - 1];
168 static char *arg0; /* value of $0 */
171 /* ============ Interrupts / exceptions
173 * We enclose jmp_buf in a structure so that we can declare pointers to
174 * jump locations. The global variable handler contains the location to
175 * jump to when an exception occurs, and the global variable exception
176 * contains a code identifying the exception. To implement nested
177 * exception handlers, the user should save the value of handler on entry
178 * to an inner scope, set handler to point to a jmploc structure for the
179 * inner scope, and restore handler on exit from the scope.
184 static struct jmploc *exception_handler;
185 static int exception;
187 #define EXINT 0 /* SIGINT received */
188 #define EXERROR 1 /* a generic error */
189 #define EXSHELLPROC 2 /* execute a shell procedure */
190 #define EXEXEC 3 /* command execution failed */
191 #define EXEXIT 4 /* exit the shell */
192 #define EXSIG 5 /* trapped signal in wait(1) */
193 static volatile int suppressint;
194 static volatile sig_atomic_t intpending;
195 /* do we generate EXSIG events */
197 /* last pending signal */
198 static volatile sig_atomic_t pendingsigs;
201 * These macros allow the user to suspend the handling of interrupt signals
202 * over a period of time. This is similar to SIGHOLD to or sigblock, but
203 * much more efficient and portable. (But hacking the kernel is so much
204 * more fun than worrying about efficiency and portability. :-))
206 #define xbarrier() ({ __asm__ __volatile__ ("": : :"memory"); })
215 * Called to raise an exception. Since C doesn't include exceptions, we
216 * just do a longjmp to the exception handler. The type of exception is
217 * stored in the global variable "exception".
219 static void raise_exception(int) ATTRIBUTE_NORETURN;
221 raise_exception(int e)
224 if (exception_handler == NULL)
229 longjmp(exception_handler->loc, 1);
233 * Called from trap.c when a SIGINT is received. (If the user specifies
234 * that SIGINT is to be trapped or ignored using the trap builtin, then
235 * this routine is not called.) Suppressint is nonzero when interrupts
236 * are held using the INT_OFF macro. (The test for iflag is just
237 * defensive programming.)
239 static void raise_interrupt(void) ATTRIBUTE_NORETURN;
241 raise_interrupt(void)
247 if (gotsig[SIGINT - 1] && !trap[SIGINT]) {
248 if (!(rootshell && iflag)) {
249 signal(SIGINT, SIG_DFL);
258 #if ENABLE_ASH_OPTIMIZE_FOR_SIZE
259 static void int_on(void)
261 if (--suppressint == 0 && intpending) {
265 #define INT_ON int_on()
266 static void force_int_on(void)
272 #define FORCE_INT_ON force_int_on()
277 if (--suppressint == 0 && intpending) raise_interrupt(); \
280 #define FORCE_INT_ON \
284 if (intpending) raise_interrupt(); \
287 #endif /* ASH_OPTIMIZE_FOR_SIZE */
289 #define SAVE_INT(v) ((v) = suppressint)
291 #define RESTORE_INT(v) \
295 if (suppressint == 0 && intpending) raise_interrupt(); \
304 raise_exception(EXSIG); \
307 /* EXSIG is turned off by evalbltin(). */
310 /* ============ stdout/stderr output */
313 outstr(const char *p, FILE *file)
321 flush_stdout_stderr(void)
338 outcslow(int c, FILE *dest)
346 static int out1fmt(const char *, ...) __attribute__((__format__(__printf__,1,2)));
348 out1fmt(const char *fmt, ...)
355 r = vprintf(fmt, ap);
361 static int fmtstr(char *, size_t, const char *, ...) __attribute__((__format__(__printf__,3,4)));
363 fmtstr(char *outbuf, size_t length, const char *fmt, ...)
370 ret = vsnprintf(outbuf, length, fmt, ap);
377 out1str(const char *p)
383 out2str(const char *p)
390 /* ============ Parser data
392 * ash_vmsg() needs parsefile->fd, hence parsefile definition is moved up.
396 struct strlist *next;
401 struct strpush *prev; /* preceding string on stack */
405 struct alias *ap; /* if push was associated with an alias */
407 char *string; /* remember the string since it may change */
411 struct parsefile *prev; /* preceding file on stack */
412 int linno; /* current line */
413 int fd; /* file descriptor (or -1 if string) */
414 int nleft; /* number of chars left in this line */
415 int lleft; /* number of chars left in this buffer */
416 char *nextc; /* next char in buffer */
417 char *buf; /* input buffer */
418 struct strpush *strpush; /* for pushing strings at this level */
419 struct strpush basestrpush; /* so pushing one is fast */
422 static struct parsefile basepf; /* top level input file */
423 static struct parsefile *parsefile = &basepf; /* current input file */
424 static int startlinno; /* line # where last token started */
425 static char *commandname; /* currently executing command */
426 static struct strlist *cmdenviron; /* environment for builtin command */
427 static int exitstatus; /* exit status of last command */
428 static int back_exitstatus; /* exit status of backquoted command */
431 /* ============ Message printing */
434 ash_vmsg(const char *msg, va_list ap)
436 fprintf(stderr, "%s: ", arg0);
438 const char *fmt = (!iflag || parsefile->fd) ?
440 fprintf(stderr, fmt, commandname, startlinno);
442 vfprintf(stderr, msg, ap);
443 outcslow('\n', stderr);
447 * Exverror is called to raise the error exception. If the second argument
448 * is not NULL then error prints an error message using printf style
449 * formatting. It then raises the error exception.
451 static void ash_vmsg_and_raise(int, const char *, va_list) ATTRIBUTE_NORETURN;
453 ash_vmsg_and_raise(int cond, const char *msg, va_list ap)
457 TRACE(("ash_vmsg_and_raise(%d, \"", cond));
459 TRACE(("\") pid=%d\n", getpid()));
461 TRACE(("ash_vmsg_and_raise(%d, NULL) pid=%d\n", cond, getpid()));
466 flush_stdout_stderr();
467 raise_exception(cond);
471 static void ash_msg_and_raise_error(const char *, ...) ATTRIBUTE_NORETURN;
473 ash_msg_and_raise_error(const char *msg, ...)
478 ash_vmsg_and_raise(EXERROR, msg, ap);
483 static void ash_msg_and_raise(int, const char *, ...) ATTRIBUTE_NORETURN;
485 ash_msg_and_raise(int cond, const char *msg, ...)
490 ash_vmsg_and_raise(cond, msg, ap);
496 * error/warning routines for external builtins
499 ash_msg(const char *fmt, ...)
509 * Return a string describing an error. The returned string may be a
510 * pointer to a static buffer that will be overwritten on the next call.
511 * Action describes the operation that got the error.
514 errmsg(int e, const char *em)
516 if (e == ENOENT || e == ENOTDIR) {
523 /* ============ Memory allocation */
526 * It appears that grabstackstr() will barf with such alignments
527 * because stalloc() will return a string allocated in a new stackblock.
529 #define SHELL_ALIGN(nbytes) (((nbytes) + SHELL_SIZE) & ~SHELL_SIZE)
531 /* Most machines require the value returned from malloc to be aligned
532 * in some way. The following macro will get this right
533 * on many machines. */
534 SHELL_SIZE = sizeof(union {int i; char *cp; double d; }) - 1,
535 /* Minimum size of a block */
536 MINSIZE = SHELL_ALIGN(504),
540 struct stack_block *prev;
545 struct stack_block *stackp;
548 struct stackmark *marknext;
551 static struct stack_block stackbase;
552 static struct stack_block *stackp = &stackbase;
553 static struct stackmark *markp;
554 static char *stacknxt = stackbase.space;
555 static size_t stacknleft = MINSIZE;
556 static char *sstrend = stackbase.space + MINSIZE;
557 static int herefd = -1;
559 #define stackblock() ((void *)stacknxt)
560 #define stackblocksize() stacknleft
563 ckrealloc(void * p, size_t nbytes)
565 p = realloc(p, nbytes);
567 ash_msg_and_raise_error(bb_msg_memory_exhausted);
572 ckmalloc(size_t nbytes)
574 return ckrealloc(NULL, nbytes);
578 * Make a copy of a string in safe storage.
581 ckstrdup(const char *s)
585 ash_msg_and_raise_error(bb_msg_memory_exhausted);
590 * Parse trees for commands are allocated in lifo order, so we use a stack
591 * to make this more efficient, and also to avoid all sorts of exception
592 * handling code to handle interrupts in the middle of a parse.
594 * The size 504 was chosen because the Ultrix malloc handles that size
598 stalloc(size_t nbytes)
603 aligned = SHELL_ALIGN(nbytes);
604 if (aligned > stacknleft) {
607 struct stack_block *sp;
610 if (blocksize < MINSIZE)
612 len = sizeof(struct stack_block) - MINSIZE + blocksize;
614 ash_msg_and_raise_error(bb_msg_memory_exhausted);
618 stacknxt = sp->space;
619 stacknleft = blocksize;
620 sstrend = stacknxt + blocksize;
626 stacknleft -= aligned;
634 if (!p || (stacknxt < (char *)p) || ((char *)p < stackp->space)) {
635 write(2, "stunalloc\n", 10);
639 stacknleft += stacknxt - (char *)p;
644 * Like strdup but works with the ash stack.
647 ststrdup(const char *p)
649 size_t len = strlen(p) + 1;
650 return memcpy(stalloc(len), p, len);
654 setstackmark(struct stackmark *mark)
656 mark->stackp = stackp;
657 mark->stacknxt = stacknxt;
658 mark->stacknleft = stacknleft;
659 mark->marknext = markp;
664 popstackmark(struct stackmark *mark)
666 struct stack_block *sp;
669 markp = mark->marknext;
670 while (stackp != mark->stackp) {
675 stacknxt = mark->stacknxt;
676 stacknleft = mark->stacknleft;
677 sstrend = mark->stacknxt + mark->stacknleft;
682 * When the parser reads in a string, it wants to stick the string on the
683 * stack and only adjust the stack pointer when it knows how big the
684 * string is. Stackblock (defined in stack.h) returns a pointer to a block
685 * of space on top of the stack and stackblocklen returns the length of
686 * this block. Growstackblock will grow this space by at least one byte,
687 * possibly moving it (like realloc). Grabstackblock actually allocates the
688 * part of the block that has been used.
695 newlen = stacknleft * 2;
696 if (newlen < stacknleft)
697 ash_msg_and_raise_error(bb_msg_memory_exhausted);
701 if (stacknxt == stackp->space && stackp != &stackbase) {
702 struct stack_block *oldstackp;
703 struct stackmark *xmark;
704 struct stack_block *sp;
705 struct stack_block *prevstackp;
711 prevstackp = sp->prev;
712 grosslen = newlen + sizeof(struct stack_block) - MINSIZE;
713 sp = ckrealloc(sp, grosslen);
714 sp->prev = prevstackp;
716 stacknxt = sp->space;
718 sstrend = sp->space + newlen;
721 * Stack marks pointing to the start of the old block
722 * must be relocated to point to the new block
725 while (xmark != NULL && xmark->stackp == oldstackp) {
726 xmark->stackp = stackp;
727 xmark->stacknxt = stacknxt;
728 xmark->stacknleft = stacknleft;
729 xmark = xmark->marknext;
733 char *oldspace = stacknxt;
734 int oldlen = stacknleft;
735 char *p = stalloc(newlen);
737 /* free the space we just allocated */
738 stacknxt = memcpy(p, oldspace, oldlen);
739 stacknleft += newlen;
744 grabstackblock(size_t len)
746 len = SHELL_ALIGN(len);
752 * The following routines are somewhat easier to use than the above.
753 * The user declares a variable of type STACKSTR, which may be declared
754 * to be a register. The macro STARTSTACKSTR initializes things. Then
755 * the user uses the macro STPUTC to add characters to the string. In
756 * effect, STPUTC(c, p) is the same as *p++ = c except that the stack is
757 * grown as necessary. When the user is done, she can just leave the
758 * string there and refer to it using stackblock(). Or she can allocate
759 * the space for it using grabstackstr(). If it is necessary to allow
760 * someone else to use the stack temporarily and then continue to grow
761 * the string, the user should use grabstack to allocate the space, and
762 * then call ungrabstr(p) to return to the previous mode of operation.
764 * USTPUTC is like STPUTC except that it doesn't check for overflow.
765 * CHECKSTACKSPACE can be called before USTPUTC to ensure that there
766 * is space for at least one character.
771 size_t len = stackblocksize();
772 if (herefd >= 0 && len >= 1024) {
773 full_write(herefd, stackblock(), len);
777 return stackblock() + len;
781 * Called from CHECKSTRSPACE.
784 makestrspace(size_t newlen, char *p)
786 size_t len = p - stacknxt;
787 size_t size = stackblocksize();
792 size = stackblocksize();
798 return stackblock() + len;
802 stack_nputstr(const char *s, size_t n, char *p)
804 p = makestrspace(n, p);
805 p = memcpy(p, s, n) + n;
810 stack_putstr(const char *s, char *p)
812 return stack_nputstr(s, strlen(s), p);
816 _STPUTC(int c, char *p)
824 #define STARTSTACKSTR(p) ((p) = stackblock())
825 #define STPUTC(c, p) ((p) = _STPUTC((c), (p)))
826 #define CHECKSTRSPACE(n, p) \
830 size_t m = sstrend - q; \
832 (p) = makestrspace(l, q); \
835 #define USTPUTC(c, p) (*p++ = (c))
836 #define STACKSTRNUL(p) ((p) == sstrend ? (p = growstackstr(), *p = '\0') : (*p = '\0'))
837 #define STUNPUTC(p) (--p)
838 #define STTOPC(p) p[-1]
839 #define STADJUST(amount, p) (p += (amount))
841 #define grabstackstr(p) stalloc((char *)(p) - (char *)stackblock())
842 #define ungrabstackstr(s, p) stunalloc((s))
843 #define stackstrend() ((void *)sstrend)
846 /* ============ String helpers */
849 * prefix -- see if pfx is a prefix of string.
852 prefix(const char *string, const char *pfx)
855 if (*pfx++ != *string++)
858 return (char *) string;
862 * Check for a valid number. This should be elsewhere.
865 is_number(const char *p)
870 } while (*++p != '\0');
875 * Convert a string of digits to an integer, printing an error message on
879 number(const char *s)
882 ash_msg_and_raise_error(illnum, s);
887 * Produce a possibly single quoted string suitable as input to the shell.
888 * The return string is allocated on the stack.
891 single_quote(const char *s)
901 len = strchrnul(s, '\'') - s;
903 q = p = makestrspace(len + 3, p);
906 q = memcpy(q, s, len) + len;
912 len = strspn(s, "'");
916 q = p = makestrspace(len + 3, p);
919 q = memcpy(q, s, len) + len;
932 /* ============ ... */
934 static char **argptr; /* argument list for builtin commands */
935 static char *optionarg; /* set by nextopt (like getopt) */
936 static char *optptr; /* used by nextopt */
939 * XXX - should get rid of. have all builtins use getopt(3). the
940 * library getopt must have the BSD extension static variable "optreset"
941 * otherwise it can't be used within the shell safely.
943 * Standard option processing (a la getopt) for builtin routines. The
944 * only argument that is passed to nextopt is the option string; the
945 * other arguments are unnecessary. It return the character, or '\0' on
949 nextopt(const char *optstring)
956 if (p == NULL || *p == '\0') {
958 if (p == NULL || *p != '-' || *++p == '\0')
961 if (LONE_DASH(p)) /* check for "--" */
965 for (q = optstring; *q != c; ) {
967 ash_msg_and_raise_error("Illegal option -%c", c);
972 if (*p == '\0' && (p = *argptr++) == NULL)
973 ash_msg_and_raise_error("No arg for -%c option", c);
982 /* ============ Variables */
985 #define VEXPORT 0x01 /* variable is exported */
986 #define VREADONLY 0x02 /* variable cannot be modified */
987 #define VSTRFIXED 0x04 /* variable struct is statically allocated */
988 #define VTEXTFIXED 0x08 /* text is statically allocated */
989 #define VSTACK 0x10 /* text is allocated on the stack */
990 #define VUNSET 0x20 /* the variable is not set */
991 #define VNOFUNC 0x40 /* don't call the callback function */
992 #define VNOSET 0x80 /* do not set variable - just readonly test */
993 #define VNOSAVE 0x100 /* when text is on the heap before setvareq */
995 # define VDYNAMIC 0x200 /* dynamic variable */
1000 #if ENABLE_LOCALE_SUPPORT
1001 static void change_lc_all(const char *value);
1002 static void change_lc_ctype(const char *value);
1005 static const char defpathvar[] = "PATH=/usr/local/bin:/usr/bin:/sbin:/bin";
1007 static const char defifsvar[] = "IFS= \t\n";
1008 #define defifs (defifsvar + 4)
1010 static const char defifs[] = " \t\n";
1014 struct var *next; /* next entry in hash list */
1015 int flags; /* flags are defined above */
1016 const char *text; /* name=value */
1017 void (*func)(const char *); /* function to be called when */
1018 /* the variable gets set/unset */
1022 struct localvar *next; /* next local variable in list */
1023 struct var *vp; /* the variable that was made local */
1024 int flags; /* saved flags */
1025 const char *text; /* saved text */
1028 /* Forward decls for varinit[] */
1030 static void chkmail(void);
1031 static void changemail(const char *);
1033 static void changepath(const char *);
1034 #if ENABLE_ASH_GETOPTS
1035 static void getoptsreset(const char *);
1037 #if ENABLE_ASH_RANDOM_SUPPORT
1038 static void change_random(const char *);
1041 static struct var varinit[] = {
1043 { 0, VSTRFIXED|VTEXTFIXED, defifsvar, 0 },
1045 { 0, VSTRFIXED|VTEXTFIXED|VUNSET, "IFS\0", 0 },
1049 { 0, VSTRFIXED|VTEXTFIXED|VUNSET, "MAIL\0", changemail },
1050 { 0, VSTRFIXED|VTEXTFIXED|VUNSET, "MAILPATH\0", changemail },
1053 { 0, VSTRFIXED|VTEXTFIXED, defpathvar, changepath },
1054 { 0, VSTRFIXED|VTEXTFIXED, "PS1=$ ", 0 },
1055 { 0, VSTRFIXED|VTEXTFIXED, "PS2=> ", 0 },
1056 { 0, VSTRFIXED|VTEXTFIXED, "PS4=+ ", 0 },
1057 #if ENABLE_ASH_GETOPTS
1058 { 0, VSTRFIXED|VTEXTFIXED, "OPTIND=1", getoptsreset },
1060 #if ENABLE_ASH_RANDOM_SUPPORT
1061 {0, VSTRFIXED|VTEXTFIXED|VUNSET|VDYNAMIC, "RANDOM\0", change_random },
1063 #if ENABLE_LOCALE_SUPPORT
1064 {0, VSTRFIXED | VTEXTFIXED | VUNSET, "LC_ALL\0", change_lc_all },
1065 {0, VSTRFIXED | VTEXTFIXED | VUNSET, "LC_CTYPE\0", change_lc_ctype },
1067 #if ENABLE_FEATURE_EDITING_SAVEHISTORY
1068 {0, VSTRFIXED | VTEXTFIXED | VUNSET, "HISTFILE\0", NULL },
1072 #define vifs varinit[0]
1074 #define vmail (&vifs)[1]
1075 #define vmpath (&vmail)[1]
1079 #define vpath (&vmpath)[1]
1080 #define vps1 (&vpath)[1]
1081 #define vps2 (&vps1)[1]
1082 #define vps4 (&vps2)[1]
1083 #define voptind (&vps4)[1]
1084 #if ENABLE_ASH_GETOPTS
1085 #define vrandom (&voptind)[1]
1087 #define vrandom (&vps4)[1]
1089 #define defpath (defpathvar + 5)
1092 * The following macros access the values of the above variables.
1093 * They have to skip over the name. They return the null string
1094 * for unset variables.
1096 #define ifsval() (vifs.text + 4)
1097 #define ifsset() ((vifs.flags & VUNSET) == 0)
1098 #define mailval() (vmail.text + 5)
1099 #define mpathval() (vmpath.text + 9)
1100 #define pathval() (vpath.text + 5)
1101 #define ps1val() (vps1.text + 4)
1102 #define ps2val() (vps2.text + 4)
1103 #define ps4val() (vps4.text + 4)
1104 #define optindval() (voptind.text + 7)
1106 #define mpathset() ((vmpath.flags & VUNSET) == 0)
1108 static struct var **hashvar(const char *);
1110 static int loopnest; /* current loop nesting level */
1113 * The parsefile structure pointed to by the global variable parsefile
1114 * contains information about the current file being read.
1117 struct redirtab *next;
1122 static struct redirtab *redirlist;
1123 static int nullredirs;
1125 extern char **environ;
1127 static int preverrout_fd; /* save fd2 before print debug if xflag is set. */
1130 int nparam; /* # of positional parameters (without $0) */
1131 unsigned char malloc; /* if parameter list dynamically allocated */
1132 char **p; /* parameter list */
1133 #if ENABLE_ASH_GETOPTS
1134 int optind; /* next parameter to be processed by getopts */
1135 int optoff; /* used by getopts */
1139 static struct shparam shellparam; /* $@ current positional parameters */
1143 static struct var *vartab[VTABSIZE];
1145 #if ENABLE_ASH_GETOPTS
1147 getoptsreset(const char *value)
1149 shellparam.optind = number(value);
1150 shellparam.optoff = -1;
1154 #define is_name(c) ((c) == '_' || isalpha((unsigned char)(c)))
1155 #define is_in_name(c) ((c) == '_' || isalnum((unsigned char)(c)))
1158 * Return of a legal variable name (a letter or underscore followed by zero or
1159 * more letters, underscores, and digits).
1162 endofname(const char *name)
1170 if (!is_in_name(*p))
1177 * Compares two strings up to the first = or '\0'. The first
1178 * string must be terminated by '='; the second may be terminated by
1179 * either '=' or '\0'.
1182 varcmp(const char *p, const char *q)
1186 while ((c = *p) == (d = *q)) {
1201 varequal(const char *a, const char *b)
1203 return !varcmp(a, b);
1207 * Find the appropriate entry in the hash table from the name.
1209 static struct var **
1210 hashvar(const char *p)
1214 hashval = ((unsigned char) *p) << 4;
1215 while (*p && *p != '=')
1216 hashval += (unsigned char) *p++;
1217 return &vartab[hashval % VTABSIZE];
1221 vpcmp(const void *a, const void *b)
1223 return varcmp(*(const char **)a, *(const char **)b);
1227 * This routine initializes the builtin variables.
1237 * PS1 depends on uid
1239 #if ENABLE_FEATURE_EDITING && ENABLE_FEATURE_EDITING_FANCY_PROMPT
1240 vps1.text = "PS1=\\w \\$ ";
1243 vps1.text = "PS1=# ";
1246 end = vp + sizeof(varinit) / sizeof(varinit[0]);
1248 vpp = hashvar(vp->text);
1251 } while (++vp < end);
1254 static struct var **
1255 findvar(struct var **vpp, const char *name)
1257 for (; *vpp; vpp = &(*vpp)->next) {
1258 if (varequal((*vpp)->text, name)) {
1266 * Find the value of a variable. Returns NULL if not set.
1269 lookupvar(const char *name)
1273 v = *findvar(hashvar(name), name);
1277 * Dynamic variables are implemented roughly the same way they are
1278 * in bash. Namely, they're "special" so long as they aren't unset.
1279 * As soon as they're unset, they're no longer dynamic, and dynamic
1280 * lookup will no longer happen at that point. -- PFM.
1282 if ((v->flags & VDYNAMIC))
1285 if (!(v->flags & VUNSET))
1286 return strchrnul(v->text, '=') + 1;
1292 * Search the environment of a builtin command.
1295 bltinlookup(const char *name)
1299 for (sp = cmdenviron; sp; sp = sp->next) {
1300 if (varequal(sp->text, name))
1301 return strchrnul(sp->text, '=') + 1;
1303 return lookupvar(name);
1307 * Same as setvar except that the variable and value are passed in
1308 * the first argument as name=value. Since the first argument will
1309 * be actually stored in the table, it should not be a string that
1311 * Called with interrupts off.
1314 setvareq(char *s, int flags)
1316 struct var *vp, **vpp;
1319 flags |= (VEXPORT & (((unsigned) (1 - aflag)) - 1));
1320 vp = *findvar(vpp, s);
1322 if ((vp->flags & (VREADONLY|VDYNAMIC)) == VREADONLY) {
1325 if (flags & VNOSAVE)
1328 ash_msg_and_raise_error("%.*s: is read only", strchrnul(n, '=') - n, n);
1334 if (vp->func && (flags & VNOFUNC) == 0)
1335 (*vp->func)(strchrnul(s, '=') + 1);
1337 if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0)
1338 free((char*)vp->text);
1340 flags |= vp->flags & ~(VTEXTFIXED|VSTACK|VNOSAVE|VUNSET);
1345 vp = ckmalloc(sizeof(*vp));
1350 if (!(flags & (VTEXTFIXED|VSTACK|VNOSAVE)))
1357 * Set the value of a variable. The flags argument is ored with the
1358 * flags of the variable. If val is NULL, the variable is unset.
1361 setvar(const char *name, const char *val, int flags)
1368 q = endofname(name);
1369 p = strchrnul(q, '=');
1371 if (!namelen || p != q)
1372 ash_msg_and_raise_error("%.*s: bad variable name", namelen, name);
1377 vallen = strlen(val);
1380 nameeq = ckmalloc(namelen + vallen + 2);
1381 p = memcpy(nameeq, name, namelen) + namelen;
1384 p = memcpy(p, val, vallen) + vallen;
1387 setvareq(nameeq, flags | VNOSAVE);
1391 #if ENABLE_ASH_GETOPTS
1393 * Safe version of setvar, returns 1 on success 0 on failure.
1396 setvarsafe(const char *name, const char *val, int flags)
1399 volatile int saveint;
1400 struct jmploc *volatile savehandler = exception_handler;
1401 struct jmploc jmploc;
1404 if (setjmp(jmploc.loc))
1407 exception_handler = &jmploc;
1408 setvar(name, val, flags);
1411 exception_handler = savehandler;
1412 RESTORE_INT(saveint);
1418 * Unset the specified variable.
1421 unsetvar(const char *s)
1427 vpp = findvar(hashvar(s), s);
1431 int flags = vp->flags;
1434 if (flags & VREADONLY)
1437 vp->flags &= ~VDYNAMIC;
1441 if ((flags & VSTRFIXED) == 0) {
1443 if ((flags & (VTEXTFIXED|VSTACK)) == 0)
1444 free((char*)vp->text);
1450 vp->flags &= ~VEXPORT;
1460 * Process a linked list of variable assignments.
1463 listsetvar(struct strlist *list_set_var, int flags)
1465 struct strlist *lp = list_set_var;
1471 setvareq(lp->text, flags);
1472 } while ((lp = lp->next));
1477 * Generate a list of variables satisfying the given conditions.
1480 listvars(int on, int off, char ***end)
1491 for (vp = *vpp; vp; vp = vp->next) {
1492 if ((vp->flags & mask) == on) {
1493 if (ep == stackstrend())
1494 ep = growstackstr();
1495 *ep++ = (char *) vp->text;
1498 } while (++vpp < vartab + VTABSIZE);
1499 if (ep == stackstrend())
1500 ep = growstackstr();
1504 return grabstackstr(ep);
1508 /* ============ Path search helper
1510 * The variable path (passed by reference) should be set to the start
1511 * of the path before the first call; padvance will update
1512 * this value as it proceeds. Successive calls to padvance will return
1513 * the possible path expansions in sequence. If an option (indicated by
1514 * a percent sign) appears in the path entry then the global variable
1515 * pathopt will be set to point to it; otherwise pathopt will be set to
1518 static const char *pathopt; /* set by padvance */
1521 padvance(const char **path, const char *name)
1531 for (p = start; *p && *p != ':' && *p != '%'; p++);
1532 len = p - start + strlen(name) + 2; /* "2" is for '/' and '\0' */
1533 while (stackblocksize() < len)
1537 memcpy(q, start, p - start);
1545 while (*p && *p != ':') p++;
1551 return stalloc(len);
1555 /* ============ Prompt */
1557 static int doprompt; /* if set, prompt the user */
1558 static int needprompt; /* true if interactive and at start of line */
1560 #if ENABLE_FEATURE_EDITING
1561 static line_input_t *line_input_state;
1562 static const char *cmdedit_prompt;
1564 putprompt(const char *s)
1566 if (ENABLE_ASH_EXPAND_PRMT) {
1567 free((char*)cmdedit_prompt);
1568 cmdedit_prompt = xstrdup(s);
1575 putprompt(const char *s)
1581 #if ENABLE_ASH_EXPAND_PRMT
1582 /* expandstr() needs parsing machinery, so it is far away ahead... */
1583 static const char *expandstr(const char *ps);
1585 #define expandstr(s) s
1589 setprompt(int whichprompt)
1592 #if ENABLE_ASH_EXPAND_PRMT
1593 struct stackmark smark;
1598 switch (whichprompt) {
1608 #if ENABLE_ASH_EXPAND_PRMT
1609 setstackmark(&smark);
1610 stalloc(stackblocksize());
1612 putprompt(expandstr(prompt));
1613 #if ENABLE_ASH_EXPAND_PRMT
1614 popstackmark(&smark);
1619 /* ============ The cd and pwd commands */
1621 #define CD_PHYSICAL 1
1624 static int docd(const char *, int);
1626 static char *curdir = nullstr; /* current working directory */
1627 static char *physdir = nullstr; /* physical working directory */
1636 while ((i = nextopt("LP"))) {
1638 flags ^= CD_PHYSICAL;
1647 * Update curdir (the name of the current directory) in response to a
1651 updatepwd(const char *dir)
1658 cdcomppath = ststrdup(dir);
1661 if (curdir == nullstr)
1663 new = stack_putstr(curdir, new);
1665 new = makestrspace(strlen(dir) + 2, new);
1666 lim = stackblock() + 1;
1670 if (new > lim && *lim == '/')
1675 if (dir[1] == '/' && dir[2] != '/') {
1681 p = strtok(cdcomppath, "/");
1685 if (p[1] == '.' && p[2] == '\0') {
1692 } else if (p[1] == '\0')
1696 new = stack_putstr(p, new);
1704 return stackblock();
1708 * Find out what the current directory is. If we already know the current
1709 * directory, this routine returns immediately.
1714 char *dir = getcwd(0, 0);
1715 return dir ? dir : nullstr;
1719 setpwd(const char *val, int setold)
1723 oldcur = dir = curdir;
1726 setvar("OLDPWD", oldcur, VEXPORT);
1729 if (physdir != nullstr) {
1730 if (physdir != oldcur)
1734 if (oldcur == val || !val) {
1740 dir = ckstrdup(val);
1741 if (oldcur != dir && oldcur != nullstr) {
1746 setvar("PWD", dir, VEXPORT);
1749 static void hashcd(void);
1752 * Actually do the chdir. We also call hashcd to let the routines in exec.c
1753 * know that the current directory has changed.
1756 docd(const char *dest, int flags)
1758 const char *dir = 0;
1761 TRACE(("docd(\"%s\", %d) called\n", dest, flags));
1764 if (!(flags & CD_PHYSICAL)) {
1765 dir = updatepwd(dest);
1780 cdcmd(int argc, char **argv)
1792 dest = bltinlookup(homestr);
1793 else if (LONE_DASH(dest)) {
1794 dest = bltinlookup("OLDPWD");
1816 path = bltinlookup("CDPATH");
1825 p = padvance(&path, dest);
1826 if (stat(p, &statb) >= 0 && S_ISDIR(statb.st_mode)) {
1830 if (!docd(p, flags))
1835 ash_msg_and_raise_error("can't cd to %s", dest);
1838 if (flags & CD_PRINT)
1839 out1fmt(snlfmt, curdir);
1844 pwdcmd(int argc, char **argv)
1847 const char *dir = curdir;
1851 if (physdir == nullstr)
1855 out1fmt(snlfmt, dir);
1860 /* ============ Unsorted yet */
1866 struct strlist *list;
1867 struct strlist **lastp;
1873 #define EXP_FULL 0x1 /* perform word splitting & file globbing */
1874 #define EXP_TILDE 0x2 /* do normal tilde expansion */
1875 #define EXP_VARTILDE 0x4 /* expand tildes in an assignment */
1876 #define EXP_REDIR 0x8 /* file glob for a redirection (1 match only) */
1877 #define EXP_CASE 0x10 /* keeps quotes around for CASE pattern */
1878 #define EXP_RECORD 0x20 /* need to record arguments for ifs breakup */
1879 #define EXP_VARTILDE2 0x40 /* expand tildes after colons only */
1880 #define EXP_WORD 0x80 /* expand word in parameter expansion */
1881 #define EXP_QWORD 0x100 /* expand word in quoted parameter expansion */
1885 static void expandarg(union node *, struct arglist *, int);
1886 #define rmescapes(p) _rmescapes((p), 0)
1887 static char *_rmescapes(char *, int);
1888 static int casematch(union node *, char *);
1890 #if ENABLE_ASH_MATH_SUPPORT
1891 static void expari(int);
1898 struct backcmd { /* result of evalbackcmd */
1899 int fd; /* file descriptor to read from */
1900 char *buf; /* buffer */
1901 int nleft; /* number of chars in buffer */
1902 struct job *jp; /* job structure for command */
1906 * This file was generated by the mknodes program.
1941 union node *redirect;
1947 struct nodelist *cmdlist;
1953 union node *redirect;
1966 union node *elsepart;
1985 union node *pattern;
1993 struct nodelist *backquote;
2028 struct nredir nredir;
2029 struct nbinary nbinary;
2033 struct nclist nclist;
2042 struct nodelist *next;
2052 static void freefunc(struct funcnode *);
2055 /* control characters in argument strings */
2056 #define CTL_FIRST '\201' /* first 'special' character */
2057 #define CTLESC '\201' /* escape next character */
2058 #define CTLVAR '\202' /* variable defn */
2059 #define CTLENDVAR '\203'
2060 #define CTLBACKQ '\204'
2061 #define CTLQUOTE 01 /* ored with CTLBACKQ code if in quotes */
2062 /* CTLBACKQ | CTLQUOTE == '\205' */
2063 #define CTLARI '\206' /* arithmetic expression */
2064 #define CTLENDARI '\207'
2065 #define CTLQUOTEMARK '\210'
2066 #define CTL_LAST '\210' /* last 'special' character */
2068 /* variable substitution byte (follows CTLVAR) */
2069 #define VSTYPE 0x0f /* type of variable substitution */
2070 #define VSNUL 0x10 /* colon--treat the empty string as unset */
2071 #define VSQUOTE 0x80 /* inside double quotes--suppress splitting */
2073 /* values of VSTYPE field */
2074 #define VSNORMAL 0x1 /* normal variable: $var or ${var} */
2075 #define VSMINUS 0x2 /* ${var-text} */
2076 #define VSPLUS 0x3 /* ${var+text} */
2077 #define VSQUESTION 0x4 /* ${var?message} */
2078 #define VSASSIGN 0x5 /* ${var=text} */
2079 #define VSTRIMRIGHT 0x6 /* ${var%pattern} */
2080 #define VSTRIMRIGHTMAX 0x7 /* ${var%%pattern} */
2081 #define VSTRIMLEFT 0x8 /* ${var#pattern} */
2082 #define VSTRIMLEFTMAX 0x9 /* ${var##pattern} */
2083 #define VSLENGTH 0xa /* ${#var} */
2085 /* values of checkkwd variable */
2086 #define CHKALIAS 0x1
2090 #define IBUFSIZ (BUFSIZ + 1)
2093 * NEOF is returned by parsecmd when it encounters an end of file. It
2094 * must be distinct from NULL, so we use the address of a variable that
2095 * happens to be handy.
2097 static int plinno = 1; /* input line number */
2099 /* number of characters left in input buffer */
2100 static int parsenleft; /* copy of parsefile->nleft */
2101 static int parselleft; /* copy of parsefile->lleft */
2103 /* next character in input buffer */
2104 static char *parsenextc; /* copy of parsefile->nextc */
2106 #define basebuf bb_common_bufsiz1 /* buffer for top level input file */
2109 static int tokpushback; /* last token pushed back */
2110 #define NEOF ((union node *)&tokpushback)
2111 static int parsebackquote; /* nonzero if we are inside backquotes */
2112 static int lasttoken; /* last token read */
2113 static char *wordtext; /* text of last word returned by readtoken */
2114 static int checkkwd;
2115 static struct nodelist *backquotelist;
2116 static union node *redirnode;
2117 static struct heredoc *heredoc;
2118 static int quoteflag; /* set if (part of) last token was quoted */
2120 static void fixredir(union node *, const char *, int);
2121 static char *endofname(const char *);
2125 static const char spcstr[] = " ";
2126 static const char dolatstr[] = { CTLVAR, VSNORMAL|VSQUOTE, '@', '=', '\0' };
2128 #if !defined(__GNUC__) || (__GNUC__ == 2 && __GNUC_MINOR__ < 96)
2129 #define __builtin_expect(x, expected_value) (x)
2132 #define xlikely(x) __builtin_expect((x),1)
2147 #define TENDBQUOTE 12
2165 /* first char is indicating which tokens mark the end of a list */
2166 static const char *const tokname_array[] = {
2180 #define KWDOFFSET 13
2181 /* the following are keywords */
2203 static char buf[16];
2207 sprintf(buf + (tok >= TSEMI), "%s%c",
2208 tokname_array[tok] + 1, (tok >= TSEMI ? '"' : 0));
2212 /* Wrapper around strcmp for qsort/bsearch/... */
2214 pstrcmp(const void *a, const void *b)
2216 return strcmp((const char *) a, (*(const char *const *) b) + 1);
2219 static const char *const *
2220 findkwd(const char *s)
2222 return bsearch(s, tokname_array + KWDOFFSET,
2223 (sizeof(tokname_array) / sizeof(const char *)) - KWDOFFSET,
2224 sizeof(const char *), pstrcmp);
2227 /* Syntax classes */
2228 #define CWORD 0 /* character is nothing special */
2229 #define CNL 1 /* newline character */
2230 #define CBACK 2 /* a backslash character */
2231 #define CSQUOTE 3 /* single quote */
2232 #define CDQUOTE 4 /* double quote */
2233 #define CENDQUOTE 5 /* a terminating quote */
2234 #define CBQUOTE 6 /* backwards single quote */
2235 #define CVAR 7 /* a dollar sign */
2236 #define CENDVAR 8 /* a '}' character */
2237 #define CLP 9 /* a left paren in arithmetic */
2238 #define CRP 10 /* a right paren in arithmetic */
2239 #define CENDFILE 11 /* end of file */
2240 #define CCTL 12 /* like CWORD, except it must be escaped */
2241 #define CSPCL 13 /* these terminate a word */
2242 #define CIGN 14 /* character should be ignored */
2244 #if ENABLE_ASH_ALIAS
2248 #define PEOA_OR_PEOF PEOA
2252 #define PEOA_OR_PEOF PEOF
2255 /* C99 say: "char" declaration may be signed or unsigned default */
2256 #define SC2INT(chr2may_be_negative_int) (int)((signed char)chr2may_be_negative_int)
2259 * is_special(c) evaluates to 1 for c in "!#$*-0123456789?@"; 0 otherwise
2260 * (assuming ascii char codes, as the original implementation did)
2262 #define is_special(c) \
2263 ( (((unsigned int)c) - 33 < 32) \
2264 && ((0xc1ff920dUL >> (((unsigned int)c) - 33)) & 1))
2266 #define digit_val(c) ((c) - '0')
2269 * This file was generated by the mksyntax program.
2272 #if ENABLE_ASH_OPTIMIZE_FOR_SIZE
2273 #define USE_SIT_FUNCTION
2276 /* number syntax index */
2277 #define BASESYNTAX 0 /* not in quotes */
2278 #define DQSYNTAX 1 /* in double quotes */
2279 #define SQSYNTAX 2 /* in single quotes */
2280 #define ARISYNTAX 3 /* in arithmetic */
2282 #if ENABLE_ASH_MATH_SUPPORT
2283 static const char S_I_T[][4] = {
2284 #if ENABLE_ASH_ALIAS
2285 {CSPCL, CIGN, CIGN, CIGN}, /* 0, PEOA */
2287 {CSPCL, CWORD, CWORD, CWORD}, /* 1, ' ' */
2288 {CNL, CNL, CNL, CNL}, /* 2, \n */
2289 {CWORD, CCTL, CCTL, CWORD}, /* 3, !*-/:=?[]~ */
2290 {CDQUOTE, CENDQUOTE, CWORD, CWORD}, /* 4, '"' */
2291 {CVAR, CVAR, CWORD, CVAR}, /* 5, $ */
2292 {CSQUOTE, CWORD, CENDQUOTE, CWORD}, /* 6, "'" */
2293 {CSPCL, CWORD, CWORD, CLP}, /* 7, ( */
2294 {CSPCL, CWORD, CWORD, CRP}, /* 8, ) */
2295 {CBACK, CBACK, CCTL, CBACK}, /* 9, \ */
2296 {CBQUOTE, CBQUOTE, CWORD, CBQUOTE}, /* 10, ` */
2297 {CENDVAR, CENDVAR, CWORD, CENDVAR}, /* 11, } */
2298 #ifndef USE_SIT_FUNCTION
2299 {CENDFILE, CENDFILE, CENDFILE, CENDFILE}, /* 12, PEOF */
2300 {CWORD, CWORD, CWORD, CWORD}, /* 13, 0-9A-Za-z */
2301 {CCTL, CCTL, CCTL, CCTL} /* 14, CTLESC ... */
2305 static const char S_I_T[][3] = {
2306 #if ENABLE_ASH_ALIAS
2307 {CSPCL, CIGN, CIGN}, /* 0, PEOA */
2309 {CSPCL, CWORD, CWORD}, /* 1, ' ' */
2310 {CNL, CNL, CNL}, /* 2, \n */
2311 {CWORD, CCTL, CCTL}, /* 3, !*-/:=?[]~ */
2312 {CDQUOTE, CENDQUOTE, CWORD}, /* 4, '"' */
2313 {CVAR, CVAR, CWORD}, /* 5, $ */
2314 {CSQUOTE, CWORD, CENDQUOTE}, /* 6, "'" */
2315 {CSPCL, CWORD, CWORD}, /* 7, ( */
2316 {CSPCL, CWORD, CWORD}, /* 8, ) */
2317 {CBACK, CBACK, CCTL}, /* 9, \ */
2318 {CBQUOTE, CBQUOTE, CWORD}, /* 10, ` */
2319 {CENDVAR, CENDVAR, CWORD}, /* 11, } */
2320 #ifndef USE_SIT_FUNCTION
2321 {CENDFILE, CENDFILE, CENDFILE}, /* 12, PEOF */
2322 {CWORD, CWORD, CWORD}, /* 13, 0-9A-Za-z */
2323 {CCTL, CCTL, CCTL} /* 14, CTLESC ... */
2326 #endif /* ASH_MATH_SUPPORT */
2328 #ifdef USE_SIT_FUNCTION
2330 #define U_C(c) ((unsigned char)(c))
2333 SIT(int c, int syntax)
2335 static const char spec_symbls[] = "\t\n !\"$&'()*-/:;<=>?[\\]`|}~";
2336 #if ENABLE_ASH_ALIAS
2337 static const char syntax_index_table[] = {
2338 1, 2, 1, 3, 4, 5, 1, 6, /* "\t\n !\"$&'" */
2339 7, 8, 3, 3, 3, 3, 1, 1, /* "()*-/:;<" */
2340 3, 1, 3, 3, 9, 3, 10, 1, /* "=>?[\\]`|" */
2344 static const char syntax_index_table[] = {
2345 0, 1, 0, 2, 3, 4, 0, 5, /* "\t\n !\"$&'" */
2346 6, 7, 2, 2, 2, 2, 0, 0, /* "()*-/:;<" */
2347 2, 0, 2, 2, 8, 2, 9, 0, /* "=>?[\\]`|" */
2354 if (c == PEOF) /* 2^8+2 */
2356 #if ENABLE_ASH_ALIAS
2357 if (c == PEOA) /* 2^8+1 */
2361 if (U_C(c) >= U_C(CTLESC) && U_C(c) <= U_C(CTLQUOTEMARK))
2364 s = strchr(spec_symbls, c);
2365 if (s == NULL || *s == '\0')
2367 indx = syntax_index_table[(s - spec_symbls)];
2369 return S_I_T[indx][syntax];
2372 #else /* USE_SIT_FUNCTION */
2374 #define SIT(c, syntax) S_I_T[(int)syntax_index_table[((int)c)+SYNBASE]][syntax]
2376 #if ENABLE_ASH_ALIAS
2377 #define CSPCL_CIGN_CIGN_CIGN 0
2378 #define CSPCL_CWORD_CWORD_CWORD 1
2379 #define CNL_CNL_CNL_CNL 2
2380 #define CWORD_CCTL_CCTL_CWORD 3
2381 #define CDQUOTE_CENDQUOTE_CWORD_CWORD 4
2382 #define CVAR_CVAR_CWORD_CVAR 5
2383 #define CSQUOTE_CWORD_CENDQUOTE_CWORD 6
2384 #define CSPCL_CWORD_CWORD_CLP 7
2385 #define CSPCL_CWORD_CWORD_CRP 8
2386 #define CBACK_CBACK_CCTL_CBACK 9
2387 #define CBQUOTE_CBQUOTE_CWORD_CBQUOTE 10
2388 #define CENDVAR_CENDVAR_CWORD_CENDVAR 11
2389 #define CENDFILE_CENDFILE_CENDFILE_CENDFILE 12
2390 #define CWORD_CWORD_CWORD_CWORD 13
2391 #define CCTL_CCTL_CCTL_CCTL 14
2393 #define CSPCL_CWORD_CWORD_CWORD 0
2394 #define CNL_CNL_CNL_CNL 1
2395 #define CWORD_CCTL_CCTL_CWORD 2
2396 #define CDQUOTE_CENDQUOTE_CWORD_CWORD 3
2397 #define CVAR_CVAR_CWORD_CVAR 4
2398 #define CSQUOTE_CWORD_CENDQUOTE_CWORD 5
2399 #define CSPCL_CWORD_CWORD_CLP 6
2400 #define CSPCL_CWORD_CWORD_CRP 7
2401 #define CBACK_CBACK_CCTL_CBACK 8
2402 #define CBQUOTE_CBQUOTE_CWORD_CBQUOTE 9
2403 #define CENDVAR_CENDVAR_CWORD_CENDVAR 10
2404 #define CENDFILE_CENDFILE_CENDFILE_CENDFILE 11
2405 #define CWORD_CWORD_CWORD_CWORD 12
2406 #define CCTL_CCTL_CCTL_CCTL 13
2409 static const char syntax_index_table[258] = {
2410 /* BASESYNTAX_DQSYNTAX_SQSYNTAX_ARISYNTAX */
2411 /* 0 PEOF */ CENDFILE_CENDFILE_CENDFILE_CENDFILE,
2412 #if ENABLE_ASH_ALIAS
2413 /* 1 PEOA */ CSPCL_CIGN_CIGN_CIGN,
2415 /* 2 -128 0x80 */ CWORD_CWORD_CWORD_CWORD,
2416 /* 3 -127 CTLESC */ CCTL_CCTL_CCTL_CCTL,
2417 /* 4 -126 CTLVAR */ CCTL_CCTL_CCTL_CCTL,
2418 /* 5 -125 CTLENDVAR */ CCTL_CCTL_CCTL_CCTL,
2419 /* 6 -124 CTLBACKQ */ CCTL_CCTL_CCTL_CCTL,
2420 /* 7 -123 CTLQUOTE */ CCTL_CCTL_CCTL_CCTL,
2421 /* 8 -122 CTLARI */ CCTL_CCTL_CCTL_CCTL,
2422 /* 9 -121 CTLENDARI */ CCTL_CCTL_CCTL_CCTL,
2423 /* 10 -120 CTLQUOTEMARK */ CCTL_CCTL_CCTL_CCTL,
2424 /* 11 -119 */ CWORD_CWORD_CWORD_CWORD,
2425 /* 12 -118 */ CWORD_CWORD_CWORD_CWORD,
2426 /* 13 -117 */ CWORD_CWORD_CWORD_CWORD,
2427 /* 14 -116 */ CWORD_CWORD_CWORD_CWORD,
2428 /* 15 -115 */ CWORD_CWORD_CWORD_CWORD,
2429 /* 16 -114 */ CWORD_CWORD_CWORD_CWORD,
2430 /* 17 -113 */ CWORD_CWORD_CWORD_CWORD,
2431 /* 18 -112 */ CWORD_CWORD_CWORD_CWORD,
2432 /* 19 -111 */ CWORD_CWORD_CWORD_CWORD,
2433 /* 20 -110 */ CWORD_CWORD_CWORD_CWORD,
2434 /* 21 -109 */ CWORD_CWORD_CWORD_CWORD,
2435 /* 22 -108 */ CWORD_CWORD_CWORD_CWORD,
2436 /* 23 -107 */ CWORD_CWORD_CWORD_CWORD,
2437 /* 24 -106 */ CWORD_CWORD_CWORD_CWORD,
2438 /* 25 -105 */ CWORD_CWORD_CWORD_CWORD,
2439 /* 26 -104 */ CWORD_CWORD_CWORD_CWORD,
2440 /* 27 -103 */ CWORD_CWORD_CWORD_CWORD,
2441 /* 28 -102 */ CWORD_CWORD_CWORD_CWORD,
2442 /* 29 -101 */ CWORD_CWORD_CWORD_CWORD,
2443 /* 30 -100 */ CWORD_CWORD_CWORD_CWORD,
2444 /* 31 -99 */ CWORD_CWORD_CWORD_CWORD,
2445 /* 32 -98 */ CWORD_CWORD_CWORD_CWORD,
2446 /* 33 -97 */ CWORD_CWORD_CWORD_CWORD,
2447 /* 34 -96 */ CWORD_CWORD_CWORD_CWORD,
2448 /* 35 -95 */ CWORD_CWORD_CWORD_CWORD,
2449 /* 36 -94 */ CWORD_CWORD_CWORD_CWORD,
2450 /* 37 -93 */ CWORD_CWORD_CWORD_CWORD,
2451 /* 38 -92 */ CWORD_CWORD_CWORD_CWORD,
2452 /* 39 -91 */ CWORD_CWORD_CWORD_CWORD,
2453 /* 40 -90 */ CWORD_CWORD_CWORD_CWORD,
2454 /* 41 -89 */ CWORD_CWORD_CWORD_CWORD,
2455 /* 42 -88 */ CWORD_CWORD_CWORD_CWORD,
2456 /* 43 -87 */ CWORD_CWORD_CWORD_CWORD,
2457 /* 44 -86 */ CWORD_CWORD_CWORD_CWORD,
2458 /* 45 -85 */ CWORD_CWORD_CWORD_CWORD,
2459 /* 46 -84 */ CWORD_CWORD_CWORD_CWORD,
2460 /* 47 -83 */ CWORD_CWORD_CWORD_CWORD,
2461 /* 48 -82 */ CWORD_CWORD_CWORD_CWORD,
2462 /* 49 -81 */ CWORD_CWORD_CWORD_CWORD,
2463 /* 50 -80 */ CWORD_CWORD_CWORD_CWORD,
2464 /* 51 -79 */ CWORD_CWORD_CWORD_CWORD,
2465 /* 52 -78 */ CWORD_CWORD_CWORD_CWORD,
2466 /* 53 -77 */ CWORD_CWORD_CWORD_CWORD,
2467 /* 54 -76 */ CWORD_CWORD_CWORD_CWORD,
2468 /* 55 -75 */ CWORD_CWORD_CWORD_CWORD,
2469 /* 56 -74 */ CWORD_CWORD_CWORD_CWORD,
2470 /* 57 -73 */ CWORD_CWORD_CWORD_CWORD,
2471 /* 58 -72 */ CWORD_CWORD_CWORD_CWORD,
2472 /* 59 -71 */ CWORD_CWORD_CWORD_CWORD,
2473 /* 60 -70 */ CWORD_CWORD_CWORD_CWORD,
2474 /* 61 -69 */ CWORD_CWORD_CWORD_CWORD,
2475 /* 62 -68 */ CWORD_CWORD_CWORD_CWORD,
2476 /* 63 -67 */ CWORD_CWORD_CWORD_CWORD,
2477 /* 64 -66 */ CWORD_CWORD_CWORD_CWORD,
2478 /* 65 -65 */ CWORD_CWORD_CWORD_CWORD,
2479 /* 66 -64 */ CWORD_CWORD_CWORD_CWORD,
2480 /* 67 -63 */ CWORD_CWORD_CWORD_CWORD,
2481 /* 68 -62 */ CWORD_CWORD_CWORD_CWORD,
2482 /* 69 -61 */ CWORD_CWORD_CWORD_CWORD,
2483 /* 70 -60 */ CWORD_CWORD_CWORD_CWORD,
2484 /* 71 -59 */ CWORD_CWORD_CWORD_CWORD,
2485 /* 72 -58 */ CWORD_CWORD_CWORD_CWORD,
2486 /* 73 -57 */ CWORD_CWORD_CWORD_CWORD,
2487 /* 74 -56 */ CWORD_CWORD_CWORD_CWORD,
2488 /* 75 -55 */ CWORD_CWORD_CWORD_CWORD,
2489 /* 76 -54 */ CWORD_CWORD_CWORD_CWORD,
2490 /* 77 -53 */ CWORD_CWORD_CWORD_CWORD,
2491 /* 78 -52 */ CWORD_CWORD_CWORD_CWORD,
2492 /* 79 -51 */ CWORD_CWORD_CWORD_CWORD,
2493 /* 80 -50 */ CWORD_CWORD_CWORD_CWORD,
2494 /* 81 -49 */ CWORD_CWORD_CWORD_CWORD,
2495 /* 82 -48 */ CWORD_CWORD_CWORD_CWORD,
2496 /* 83 -47 */ CWORD_CWORD_CWORD_CWORD,
2497 /* 84 -46 */ CWORD_CWORD_CWORD_CWORD,
2498 /* 85 -45 */ CWORD_CWORD_CWORD_CWORD,
2499 /* 86 -44 */ CWORD_CWORD_CWORD_CWORD,
2500 /* 87 -43 */ CWORD_CWORD_CWORD_CWORD,
2501 /* 88 -42 */ CWORD_CWORD_CWORD_CWORD,
2502 /* 89 -41 */ CWORD_CWORD_CWORD_CWORD,
2503 /* 90 -40 */ CWORD_CWORD_CWORD_CWORD,
2504 /* 91 -39 */ CWORD_CWORD_CWORD_CWORD,
2505 /* 92 -38 */ CWORD_CWORD_CWORD_CWORD,
2506 /* 93 -37 */ CWORD_CWORD_CWORD_CWORD,
2507 /* 94 -36 */ CWORD_CWORD_CWORD_CWORD,
2508 /* 95 -35 */ CWORD_CWORD_CWORD_CWORD,
2509 /* 96 -34 */ CWORD_CWORD_CWORD_CWORD,
2510 /* 97 -33 */ CWORD_CWORD_CWORD_CWORD,
2511 /* 98 -32 */ CWORD_CWORD_CWORD_CWORD,
2512 /* 99 -31 */ CWORD_CWORD_CWORD_CWORD,
2513 /* 100 -30 */ CWORD_CWORD_CWORD_CWORD,
2514 /* 101 -29 */ CWORD_CWORD_CWORD_CWORD,
2515 /* 102 -28 */ CWORD_CWORD_CWORD_CWORD,
2516 /* 103 -27 */ CWORD_CWORD_CWORD_CWORD,
2517 /* 104 -26 */ CWORD_CWORD_CWORD_CWORD,
2518 /* 105 -25 */ CWORD_CWORD_CWORD_CWORD,
2519 /* 106 -24 */ CWORD_CWORD_CWORD_CWORD,
2520 /* 107 -23 */ CWORD_CWORD_CWORD_CWORD,
2521 /* 108 -22 */ CWORD_CWORD_CWORD_CWORD,
2522 /* 109 -21 */ CWORD_CWORD_CWORD_CWORD,
2523 /* 110 -20 */ CWORD_CWORD_CWORD_CWORD,
2524 /* 111 -19 */ CWORD_CWORD_CWORD_CWORD,
2525 /* 112 -18 */ CWORD_CWORD_CWORD_CWORD,
2526 /* 113 -17 */ CWORD_CWORD_CWORD_CWORD,
2527 /* 114 -16 */ CWORD_CWORD_CWORD_CWORD,
2528 /* 115 -15 */ CWORD_CWORD_CWORD_CWORD,
2529 /* 116 -14 */ CWORD_CWORD_CWORD_CWORD,
2530 /* 117 -13 */ CWORD_CWORD_CWORD_CWORD,
2531 /* 118 -12 */ CWORD_CWORD_CWORD_CWORD,
2532 /* 119 -11 */ CWORD_CWORD_CWORD_CWORD,
2533 /* 120 -10 */ CWORD_CWORD_CWORD_CWORD,
2534 /* 121 -9 */ CWORD_CWORD_CWORD_CWORD,
2535 /* 122 -8 */ CWORD_CWORD_CWORD_CWORD,
2536 /* 123 -7 */ CWORD_CWORD_CWORD_CWORD,
2537 /* 124 -6 */ CWORD_CWORD_CWORD_CWORD,
2538 /* 125 -5 */ CWORD_CWORD_CWORD_CWORD,
2539 /* 126 -4 */ CWORD_CWORD_CWORD_CWORD,
2540 /* 127 -3 */ CWORD_CWORD_CWORD_CWORD,
2541 /* 128 -2 */ CWORD_CWORD_CWORD_CWORD,
2542 /* 129 -1 */ CWORD_CWORD_CWORD_CWORD,
2543 /* 130 0 */ CWORD_CWORD_CWORD_CWORD,
2544 /* 131 1 */ CWORD_CWORD_CWORD_CWORD,
2545 /* 132 2 */ CWORD_CWORD_CWORD_CWORD,
2546 /* 133 3 */ CWORD_CWORD_CWORD_CWORD,
2547 /* 134 4 */ CWORD_CWORD_CWORD_CWORD,
2548 /* 135 5 */ CWORD_CWORD_CWORD_CWORD,
2549 /* 136 6 */ CWORD_CWORD_CWORD_CWORD,
2550 /* 137 7 */ CWORD_CWORD_CWORD_CWORD,
2551 /* 138 8 */ CWORD_CWORD_CWORD_CWORD,
2552 /* 139 9 "\t" */ CSPCL_CWORD_CWORD_CWORD,
2553 /* 140 10 "\n" */ CNL_CNL_CNL_CNL,
2554 /* 141 11 */ CWORD_CWORD_CWORD_CWORD,
2555 /* 142 12 */ CWORD_CWORD_CWORD_CWORD,
2556 /* 143 13 */ CWORD_CWORD_CWORD_CWORD,
2557 /* 144 14 */ CWORD_CWORD_CWORD_CWORD,
2558 /* 145 15 */ CWORD_CWORD_CWORD_CWORD,
2559 /* 146 16 */ CWORD_CWORD_CWORD_CWORD,
2560 /* 147 17 */ CWORD_CWORD_CWORD_CWORD,
2561 /* 148 18 */ CWORD_CWORD_CWORD_CWORD,
2562 /* 149 19 */ CWORD_CWORD_CWORD_CWORD,
2563 /* 150 20 */ CWORD_CWORD_CWORD_CWORD,
2564 /* 151 21 */ CWORD_CWORD_CWORD_CWORD,
2565 /* 152 22 */ CWORD_CWORD_CWORD_CWORD,
2566 /* 153 23 */ CWORD_CWORD_CWORD_CWORD,
2567 /* 154 24 */ CWORD_CWORD_CWORD_CWORD,
2568 /* 155 25 */ CWORD_CWORD_CWORD_CWORD,
2569 /* 156 26 */ CWORD_CWORD_CWORD_CWORD,
2570 /* 157 27 */ CWORD_CWORD_CWORD_CWORD,
2571 /* 158 28 */ CWORD_CWORD_CWORD_CWORD,
2572 /* 159 29 */ CWORD_CWORD_CWORD_CWORD,
2573 /* 160 30 */ CWORD_CWORD_CWORD_CWORD,
2574 /* 161 31 */ CWORD_CWORD_CWORD_CWORD,
2575 /* 162 32 " " */ CSPCL_CWORD_CWORD_CWORD,
2576 /* 163 33 "!" */ CWORD_CCTL_CCTL_CWORD,
2577 /* 164 34 """ */ CDQUOTE_CENDQUOTE_CWORD_CWORD,
2578 /* 165 35 "#" */ CWORD_CWORD_CWORD_CWORD,
2579 /* 166 36 "$" */ CVAR_CVAR_CWORD_CVAR,
2580 /* 167 37 "%" */ CWORD_CWORD_CWORD_CWORD,
2581 /* 168 38 "&" */ CSPCL_CWORD_CWORD_CWORD,
2582 /* 169 39 "'" */ CSQUOTE_CWORD_CENDQUOTE_CWORD,
2583 /* 170 40 "(" */ CSPCL_CWORD_CWORD_CLP,
2584 /* 171 41 ")" */ CSPCL_CWORD_CWORD_CRP,
2585 /* 172 42 "*" */ CWORD_CCTL_CCTL_CWORD,
2586 /* 173 43 "+" */ CWORD_CWORD_CWORD_CWORD,
2587 /* 174 44 "," */ CWORD_CWORD_CWORD_CWORD,
2588 /* 175 45 "-" */ CWORD_CCTL_CCTL_CWORD,
2589 /* 176 46 "." */ CWORD_CWORD_CWORD_CWORD,
2590 /* 177 47 "/" */ CWORD_CCTL_CCTL_CWORD,
2591 /* 178 48 "0" */ CWORD_CWORD_CWORD_CWORD,
2592 /* 179 49 "1" */ CWORD_CWORD_CWORD_CWORD,
2593 /* 180 50 "2" */ CWORD_CWORD_CWORD_CWORD,
2594 /* 181 51 "3" */ CWORD_CWORD_CWORD_CWORD,
2595 /* 182 52 "4" */ CWORD_CWORD_CWORD_CWORD,
2596 /* 183 53 "5" */ CWORD_CWORD_CWORD_CWORD,
2597 /* 184 54 "6" */ CWORD_CWORD_CWORD_CWORD,
2598 /* 185 55 "7" */ CWORD_CWORD_CWORD_CWORD,
2599 /* 186 56 "8" */ CWORD_CWORD_CWORD_CWORD,
2600 /* 187 57 "9" */ CWORD_CWORD_CWORD_CWORD,
2601 /* 188 58 ":" */ CWORD_CCTL_CCTL_CWORD,
2602 /* 189 59 ";" */ CSPCL_CWORD_CWORD_CWORD,
2603 /* 190 60 "<" */ CSPCL_CWORD_CWORD_CWORD,
2604 /* 191 61 "=" */ CWORD_CCTL_CCTL_CWORD,
2605 /* 192 62 ">" */ CSPCL_CWORD_CWORD_CWORD,
2606 /* 193 63 "?" */ CWORD_CCTL_CCTL_CWORD,
2607 /* 194 64 "@" */ CWORD_CWORD_CWORD_CWORD,
2608 /* 195 65 "A" */ CWORD_CWORD_CWORD_CWORD,
2609 /* 196 66 "B" */ CWORD_CWORD_CWORD_CWORD,
2610 /* 197 67 "C" */ CWORD_CWORD_CWORD_CWORD,
2611 /* 198 68 "D" */ CWORD_CWORD_CWORD_CWORD,
2612 /* 199 69 "E" */ CWORD_CWORD_CWORD_CWORD,
2613 /* 200 70 "F" */ CWORD_CWORD_CWORD_CWORD,
2614 /* 201 71 "G" */ CWORD_CWORD_CWORD_CWORD,
2615 /* 202 72 "H" */ CWORD_CWORD_CWORD_CWORD,
2616 /* 203 73 "I" */ CWORD_CWORD_CWORD_CWORD,
2617 /* 204 74 "J" */ CWORD_CWORD_CWORD_CWORD,
2618 /* 205 75 "K" */ CWORD_CWORD_CWORD_CWORD,
2619 /* 206 76 "L" */ CWORD_CWORD_CWORD_CWORD,
2620 /* 207 77 "M" */ CWORD_CWORD_CWORD_CWORD,
2621 /* 208 78 "N" */ CWORD_CWORD_CWORD_CWORD,
2622 /* 209 79 "O" */ CWORD_CWORD_CWORD_CWORD,
2623 /* 210 80 "P" */ CWORD_CWORD_CWORD_CWORD,
2624 /* 211 81 "Q" */ CWORD_CWORD_CWORD_CWORD,
2625 /* 212 82 "R" */ CWORD_CWORD_CWORD_CWORD,
2626 /* 213 83 "S" */ CWORD_CWORD_CWORD_CWORD,
2627 /* 214 84 "T" */ CWORD_CWORD_CWORD_CWORD,
2628 /* 215 85 "U" */ CWORD_CWORD_CWORD_CWORD,
2629 /* 216 86 "V" */ CWORD_CWORD_CWORD_CWORD,
2630 /* 217 87 "W" */ CWORD_CWORD_CWORD_CWORD,
2631 /* 218 88 "X" */ CWORD_CWORD_CWORD_CWORD,
2632 /* 219 89 "Y" */ CWORD_CWORD_CWORD_CWORD,
2633 /* 220 90 "Z" */ CWORD_CWORD_CWORD_CWORD,
2634 /* 221 91 "[" */ CWORD_CCTL_CCTL_CWORD,
2635 /* 222 92 "\" */ CBACK_CBACK_CCTL_CBACK,
2636 /* 223 93 "]" */ CWORD_CCTL_CCTL_CWORD,
2637 /* 224 94 "^" */ CWORD_CWORD_CWORD_CWORD,
2638 /* 225 95 "_" */ CWORD_CWORD_CWORD_CWORD,
2639 /* 226 96 "`" */ CBQUOTE_CBQUOTE_CWORD_CBQUOTE,
2640 /* 227 97 "a" */ CWORD_CWORD_CWORD_CWORD,
2641 /* 228 98 "b" */ CWORD_CWORD_CWORD_CWORD,
2642 /* 229 99 "c" */ CWORD_CWORD_CWORD_CWORD,
2643 /* 230 100 "d" */ CWORD_CWORD_CWORD_CWORD,
2644 /* 231 101 "e" */ CWORD_CWORD_CWORD_CWORD,
2645 /* 232 102 "f" */ CWORD_CWORD_CWORD_CWORD,
2646 /* 233 103 "g" */ CWORD_CWORD_CWORD_CWORD,
2647 /* 234 104 "h" */ CWORD_CWORD_CWORD_CWORD,
2648 /* 235 105 "i" */ CWORD_CWORD_CWORD_CWORD,
2649 /* 236 106 "j" */ CWORD_CWORD_CWORD_CWORD,
2650 /* 237 107 "k" */ CWORD_CWORD_CWORD_CWORD,
2651 /* 238 108 "l" */ CWORD_CWORD_CWORD_CWORD,
2652 /* 239 109 "m" */ CWORD_CWORD_CWORD_CWORD,
2653 /* 240 110 "n" */ CWORD_CWORD_CWORD_CWORD,
2654 /* 241 111 "o" */ CWORD_CWORD_CWORD_CWORD,
2655 /* 242 112 "p" */ CWORD_CWORD_CWORD_CWORD,
2656 /* 243 113 "q" */ CWORD_CWORD_CWORD_CWORD,
2657 /* 244 114 "r" */ CWORD_CWORD_CWORD_CWORD,
2658 /* 245 115 "s" */ CWORD_CWORD_CWORD_CWORD,
2659 /* 246 116 "t" */ CWORD_CWORD_CWORD_CWORD,
2660 /* 247 117 "u" */ CWORD_CWORD_CWORD_CWORD,
2661 /* 248 118 "v" */ CWORD_CWORD_CWORD_CWORD,
2662 /* 249 119 "w" */ CWORD_CWORD_CWORD_CWORD,
2663 /* 250 120 "x" */ CWORD_CWORD_CWORD_CWORD,
2664 /* 251 121 "y" */ CWORD_CWORD_CWORD_CWORD,
2665 /* 252 122 "z" */ CWORD_CWORD_CWORD_CWORD,
2666 /* 253 123 "{" */ CWORD_CWORD_CWORD_CWORD,
2667 /* 254 124 "|" */ CSPCL_CWORD_CWORD_CWORD,
2668 /* 255 125 "}" */ CENDVAR_CENDVAR_CWORD_CENDVAR,
2669 /* 256 126 "~" */ CWORD_CCTL_CCTL_CWORD,
2670 /* 257 127 */ CWORD_CWORD_CWORD_CWORD,
2673 #endif /* USE_SIT_FUNCTION */
2680 static int funcblocksize; /* size of structures in function */
2681 static int funcstringsize; /* size of strings in node */
2682 static void *funcblock; /* block to allocate function from */
2683 static char *funcstring; /* block to allocate strings from */
2685 static const short nodesize[26] = {
2686 SHELL_ALIGN(sizeof(struct ncmd)),
2687 SHELL_ALIGN(sizeof(struct npipe)),
2688 SHELL_ALIGN(sizeof(struct nredir)),
2689 SHELL_ALIGN(sizeof(struct nredir)),
2690 SHELL_ALIGN(sizeof(struct nredir)),
2691 SHELL_ALIGN(sizeof(struct nbinary)),
2692 SHELL_ALIGN(sizeof(struct nbinary)),
2693 SHELL_ALIGN(sizeof(struct nbinary)),
2694 SHELL_ALIGN(sizeof(struct nif)),
2695 SHELL_ALIGN(sizeof(struct nbinary)),
2696 SHELL_ALIGN(sizeof(struct nbinary)),
2697 SHELL_ALIGN(sizeof(struct nfor)),
2698 SHELL_ALIGN(sizeof(struct ncase)),
2699 SHELL_ALIGN(sizeof(struct nclist)),
2700 SHELL_ALIGN(sizeof(struct narg)),
2701 SHELL_ALIGN(sizeof(struct narg)),
2702 SHELL_ALIGN(sizeof(struct nfile)),
2703 SHELL_ALIGN(sizeof(struct nfile)),
2704 SHELL_ALIGN(sizeof(struct nfile)),
2705 SHELL_ALIGN(sizeof(struct nfile)),
2706 SHELL_ALIGN(sizeof(struct nfile)),
2707 SHELL_ALIGN(sizeof(struct ndup)),
2708 SHELL_ALIGN(sizeof(struct ndup)),
2709 SHELL_ALIGN(sizeof(struct nhere)),
2710 SHELL_ALIGN(sizeof(struct nhere)),
2711 SHELL_ALIGN(sizeof(struct nnot)),
2715 static void calcsize(union node *);
2716 static void sizenodelist(struct nodelist *);
2717 static union node *copynode(union node *);
2718 static struct nodelist *copynodelist(struct nodelist *);
2719 static char *nodeckstrdup(char *);
2722 static int evalskip; /* set if we are skipping commands */
2723 static int skipcount; /* number of levels to skip */
2724 static int funcnest; /* depth of function calls */
2726 /* reasons for skipping commands (see comment on breakcmd routine) */
2727 #define SKIPBREAK (1 << 0)
2728 #define SKIPCONT (1 << 1)
2729 #define SKIPFUNC (1 << 2)
2730 #define SKIPFILE (1 << 3)
2731 #define SKIPEVAL (1 << 4)
2734 * This file was generated by the mkbuiltins program.
2738 static int bgcmd(int, char **);
2740 static int breakcmd(int, char **);
2741 static int cdcmd(int, char **);
2742 #if ENABLE_ASH_CMDCMD
2743 static int commandcmd(int, char **);
2745 static int dotcmd(int, char **);
2746 static int evalcmd(int, char **);
2747 #if ENABLE_ASH_BUILTIN_ECHO
2748 static int echocmd(int, char **);
2750 #if ENABLE_ASH_BUILTIN_TEST
2751 static int testcmd(int, char **);
2753 static int execcmd(int, char **);
2754 static int exitcmd(int, char **);
2755 static int exportcmd(int, char **);
2756 static int falsecmd(int, char **);
2758 static int fgcmd(int, char **);
2760 #if ENABLE_ASH_GETOPTS
2761 static int getoptscmd(int, char **);
2763 static int hashcmd(int, char **);
2764 #if !ENABLE_FEATURE_SH_EXTRA_QUIET
2765 static int helpcmd(int argc, char **argv);
2768 static int jobscmd(int, char **);
2770 #if ENABLE_ASH_MATH_SUPPORT
2771 static int letcmd(int, char **);
2773 static int localcmd(int, char **);
2774 static int pwdcmd(int, char **);
2775 static int readcmd(int, char **);
2776 static int returncmd(int, char **);
2777 static int setcmd(int, char **);
2778 static int shiftcmd(int, char **);
2779 static int timescmd(int, char **);
2780 static int trapcmd(int, char **);
2781 static int truecmd(int, char **);
2782 static int typecmd(int, char **);
2783 static int umaskcmd(int, char **);
2784 static int unsetcmd(int, char **);
2785 static int waitcmd(int, char **);
2786 static int ulimitcmd(int, char **);
2788 static int killcmd(int, char **);
2793 /* values of cmdtype */
2794 #define CMDUNKNOWN -1 /* no entry in table for command */
2795 #define CMDNORMAL 0 /* command is an executable program */
2796 #define CMDFUNCTION 1 /* command is a shell function */
2797 #define CMDBUILTIN 2 /* command is a shell builtin */
2801 int (*builtin)(int, char **);
2802 /* unsigned flags; */
2806 #define COMMANDCMD (builtincmd + 5 + \
2807 2 * ENABLE_ASH_BUILTIN_TEST + \
2808 ENABLE_ASH_ALIAS + \
2809 ENABLE_ASH_JOB_CONTROL)
2810 #define EXECCMD (builtincmd + 7 + \
2811 2 * ENABLE_ASH_BUILTIN_TEST + \
2812 ENABLE_ASH_ALIAS + \
2813 ENABLE_ASH_JOB_CONTROL + \
2814 ENABLE_ASH_CMDCMD + \
2815 ENABLE_ASH_BUILTIN_ECHO)
2817 #define BUILTIN_NOSPEC "0"
2818 #define BUILTIN_SPECIAL "1"
2819 #define BUILTIN_REGULAR "2"
2820 #define BUILTIN_SPEC_REG "3"
2821 #define BUILTIN_ASSIGN "4"
2822 #define BUILTIN_SPEC_ASSG "5"
2823 #define BUILTIN_REG_ASSG "6"
2824 #define BUILTIN_SPEC_REG_ASSG "7"
2826 #define IS_BUILTIN_SPECIAL(builtincmd) ((builtincmd)->name[0] & 1)
2827 #define IS_BUILTIN_REGULAR(builtincmd) ((builtincmd)->name[0] & 2)
2828 #define IS_BUILTIN_ASSIGN(builtincmd) ((builtincmd)->name[0] & 4)
2830 /* make sure to keep these in proper order since it is searched via bsearch() */
2831 static const struct builtincmd builtincmd[] = {
2832 { BUILTIN_SPEC_REG ".", dotcmd },
2833 { BUILTIN_SPEC_REG ":", truecmd },
2834 #if ENABLE_ASH_BUILTIN_TEST
2835 { BUILTIN_REGULAR "[", testcmd },
2836 { BUILTIN_REGULAR "[[", testcmd },
2838 #if ENABLE_ASH_ALIAS
2839 { BUILTIN_REG_ASSG "alias", aliascmd },
2842 { BUILTIN_REGULAR "bg", bgcmd },
2844 { BUILTIN_SPEC_REG "break", breakcmd },
2845 { BUILTIN_REGULAR "cd", cdcmd },
2846 { BUILTIN_NOSPEC "chdir", cdcmd },
2847 #if ENABLE_ASH_CMDCMD
2848 { BUILTIN_REGULAR "command", commandcmd },
2850 { BUILTIN_SPEC_REG "continue", breakcmd },
2851 #if ENABLE_ASH_BUILTIN_ECHO
2852 { BUILTIN_REGULAR "echo", echocmd },
2854 { BUILTIN_SPEC_REG "eval", evalcmd },
2855 { BUILTIN_SPEC_REG "exec", execcmd },
2856 { BUILTIN_SPEC_REG "exit", exitcmd },
2857 { BUILTIN_SPEC_REG_ASSG "export", exportcmd },
2858 { BUILTIN_REGULAR "false", falsecmd },
2860 { BUILTIN_REGULAR "fg", fgcmd },
2862 #if ENABLE_ASH_GETOPTS
2863 { BUILTIN_REGULAR "getopts", getoptscmd },
2865 { BUILTIN_NOSPEC "hash", hashcmd },
2866 #if !ENABLE_FEATURE_SH_EXTRA_QUIET
2867 { BUILTIN_NOSPEC "help", helpcmd },
2870 { BUILTIN_REGULAR "jobs", jobscmd },
2871 { BUILTIN_REGULAR "kill", killcmd },
2873 #if ENABLE_ASH_MATH_SUPPORT
2874 { BUILTIN_NOSPEC "let", letcmd },
2876 { BUILTIN_ASSIGN "local", localcmd },
2877 { BUILTIN_NOSPEC "pwd", pwdcmd },
2878 { BUILTIN_REGULAR "read", readcmd },
2879 { BUILTIN_SPEC_REG_ASSG "readonly", exportcmd },
2880 { BUILTIN_SPEC_REG "return", returncmd },
2881 { BUILTIN_SPEC_REG "set", setcmd },
2882 { BUILTIN_SPEC_REG "shift", shiftcmd },
2883 { BUILTIN_SPEC_REG "source", dotcmd },
2884 #if ENABLE_ASH_BUILTIN_TEST
2885 { BUILTIN_REGULAR "test", testcmd },
2887 { BUILTIN_SPEC_REG "times", timescmd },
2888 { BUILTIN_SPEC_REG "trap", trapcmd },
2889 { BUILTIN_REGULAR "true", truecmd },
2890 { BUILTIN_NOSPEC "type", typecmd },
2891 { BUILTIN_NOSPEC "ulimit", ulimitcmd },
2892 { BUILTIN_REGULAR "umask", umaskcmd },
2893 #if ENABLE_ASH_ALIAS
2894 { BUILTIN_REGULAR "unalias", unaliascmd },
2896 { BUILTIN_SPEC_REG "unset", unsetcmd },
2897 { BUILTIN_REGULAR "wait", waitcmd },
2900 #define NUMBUILTINS (sizeof(builtincmd) / sizeof(builtincmd[0]))
2907 const struct builtincmd *cmd;
2908 struct funcnode *func;
2913 /* action to find_command() */
2914 #define DO_ERR 0x01 /* prints errors */
2915 #define DO_ABS 0x02 /* checks absolute paths */
2916 #define DO_NOFUNC 0x04 /* don't return shell functions, for command */
2917 #define DO_ALTPATH 0x08 /* using alternate path */
2918 #define DO_ALTBLTIN 0x20 /* %builtin in alt. path */
2920 static void shellexec(char **, const char *, int) ATTRIBUTE_NORETURN;
2921 static char *padvance(const char **, const char *);
2922 static void find_command(char *, struct cmdentry *, int, const char *);
2923 static struct builtincmd *find_builtin(const char *);
2924 static void defun(char *, union node *);
2925 static void unsetfunc(const char *);
2927 #if ENABLE_ASH_MATH_SUPPORT_64
2928 typedef int64_t arith_t;
2929 #define arith_t_type (long long)
2931 typedef long arith_t;
2932 #define arith_t_type (long)
2935 #if ENABLE_ASH_MATH_SUPPORT
2936 static arith_t dash_arith(const char *);
2937 static arith_t arith(const char *expr, int *perrcode);
2940 #if ENABLE_ASH_RANDOM_SUPPORT
2941 static unsigned long rseed;
2942 # ifndef DYNAMIC_VAR
2943 # define DYNAMIC_VAR
2947 /* PEOF (the end of file marker) */
2950 INPUT_PUSH_FILE = 1,
2951 INPUT_NOFILE_OK = 2,
2955 * The input line number. Input.c just defines this variable, and saves
2956 * and restores it when files are pushed and popped. The user of this
2957 * package must set its value.
2959 static void pungetc(void);
2960 static void pushstring(char *, void *);
2961 static void popstring(void);
2962 static void setinputfd(int, int);
2963 static void setinputstring(char *);
2964 static void popfile(void);
2965 static void popallfiles(void);
2966 static void closescript(void);
2971 /* Mode argument to forkshell. Don't change FORK_FG or FORK_BG. */
2974 #define FORK_NOJOB 2
2976 /* mode flags for showjob(s) */
2977 #define SHOW_PGID 0x01 /* only show pgid - for jobs -p */
2978 #define SHOW_PID 0x04 /* include process pid */
2979 #define SHOW_CHANGED 0x08 /* only jobs whose state has changed */
2983 * A job structure contains information about a job. A job is either a
2984 * single process or a set of processes contained in a pipeline. In the
2985 * latter case, pidlist will be non-NULL, and will point to a -1 terminated
2990 pid_t pid; /* process id */
2991 int status; /* last process status from wait() */
2992 char *cmd; /* text of command being run */
2996 struct procstat ps0; /* status of process */
2997 struct procstat *ps; /* status or processes when more than one */
2999 int stopstatus; /* status of a stopped job */
3002 nprocs: 16, /* number of processes */
3004 #define JOBRUNNING 0 /* at least one proc running */
3005 #define JOBSTOPPED 1 /* all procs are stopped */
3006 #define JOBDONE 2 /* all procs are completed */
3008 sigint: 1, /* job was killed by SIGINT */
3009 jobctl: 1, /* job running under job control */
3011 waited: 1, /* true if this entry has been waited for */
3012 used: 1, /* true if this entry is in used */
3013 changed: 1; /* true if status has changed */
3014 struct job *prev_job; /* previous job */
3017 static pid_t backgndpid; /* pid of last background process */
3018 static int job_warning; /* user was warned about stopped jobs */
3020 static int jobctl; /* true if doing job control */
3023 static struct job *makejob(union node *, int);
3024 static int forkshell(struct job *, union node *, int);
3025 static int waitforjob(struct job *);
3026 static int stoppedjobs(void);
3029 #define setjobctl(on) /* do nothing */
3031 static void setjobctl(int);
3032 static void showjobs(FILE *, int);
3038 static void readcmdfile(char *);
3044 #define DOLATSTRLEN 4
3046 static char *prefix(const char *, const char *);
3047 static int number(const char *);
3048 static int is_number(const char *);
3049 static char *single_quote(const char *);
3051 #define equal(s1, s2) (strcmp(s1, s2) == 0)
3052 #define scopy(s1, s2) ((void)strcpy(s2, s1))
3056 static char *minusc; /* argument to -c option */
3059 static void optschanged(void);
3060 static void setparam(char **);
3061 static void freeparam(volatile struct shparam *);
3062 static int shiftcmd(int, char **);
3063 static int setcmd(int, char **);
3064 static int nextopt(const char *);
3068 /* flags passed to redirect */
3069 #define REDIR_PUSH 01 /* save previous values of file descriptors */
3070 #define REDIR_SAVEFD2 03 /* set preverrout */
3072 static void redirect(union node *, int);
3073 static void popredir(int);
3074 static void clearredir(int);
3075 static int copyfd(int, int);
3076 static int redirectsafe(union node *, int);
3082 static void showtree(union node *);
3083 static void trace(const char *, ...);
3084 static void tracev(const char *, va_list);
3085 static void trargs(char **);
3086 static void trputc(int);
3087 static void trputs(const char *);
3088 static void opentrace(void);
3094 static void clear_traps(void);
3095 static void setsignal(int);
3096 static void ignoresig(int);
3097 static void onsig(int);
3098 static int dotrap(void);
3099 static void setinteractive(int);
3100 static void exitshell(void) ATTRIBUTE_NORETURN;
3103 static int is_safe_applet(char *name)
3105 /* It isn't a bug to have non-existent applet here... */
3106 /* ...just a waste of space... */
3107 static const char safe_applets[][8] = {
3111 USE_CHMOD (, "chmod" )
3112 USE_CHOWN (, "chown" )
3116 USE_ECHO (, "echo" )
3117 USE_FIND (, "find" )
3118 USE_HEXDUMP(, "hexdump")
3121 USE_MKDIR (, "mkdir" )
3123 USE_SORT (, "sort" )
3124 USE_TEST (, "test" )
3125 USE_TOUCH (, "touch" )
3126 USE_XARGS (, "xargs" )
3128 int n = sizeof(safe_applets) / sizeof(safe_applets[0]);
3130 for (i = 0; i < n; i++)
3131 if (strcmp(safe_applets[i], name) == 0)
3138 #if ENABLE_ASH_ALIAS
3139 static struct alias *atab[ATABSIZE];
3141 static void setalias(const char *, const char *);
3142 static struct alias *freealias(struct alias *);
3143 static struct alias **__lookupalias(const char *);
3146 setalias(const char *name, const char *val)
3148 struct alias *ap, **app;
3150 app = __lookupalias(name);
3154 if (!(ap->flag & ALIASINUSE)) {
3157 ap->val = ckstrdup(val);
3158 ap->flag &= ~ALIASDEAD;
3161 ap = ckmalloc(sizeof(struct alias));
3162 ap->name = ckstrdup(name);
3163 ap->val = ckstrdup(val);
3172 unalias(const char *name)
3176 app = __lookupalias(name);
3180 *app = freealias(*app);
3191 struct alias *ap, **app;
3195 for (i = 0; i < ATABSIZE; i++) {
3197 for (ap = *app; ap; ap = *app) {
3198 *app = freealias(*app);
3207 static struct alias *
3208 lookupalias(const char *name, int check)
3210 struct alias *ap = *__lookupalias(name);
3212 if (check && ap && (ap->flag & ALIASINUSE))
3218 * TODO - sort output
3221 aliascmd(int argc, char **argv)
3230 for (i = 0; i < ATABSIZE; i++)
3231 for (ap = atab[i]; ap; ap = ap->next) {
3236 while ((n = *++argv) != NULL) {
3237 v = strchr(n+1, '=');
3238 if (v == NULL) { /* n+1: funny ksh stuff */
3239 ap = *__lookupalias(n);
3241 fprintf(stderr, "%s: %s not found\n", "alias", n);
3255 unaliascmd(int argc, char **argv)
3259 while ((i = nextopt("a")) != '\0') {
3265 for (i = 0; *argptr; argptr++) {
3266 if (unalias(*argptr)) {
3267 fprintf(stderr, "%s: %s not found\n", "unalias", *argptr);
3275 static struct alias *
3276 freealias(struct alias *ap)
3280 if (ap->flag & ALIASINUSE) {
3281 ap->flag |= ALIASDEAD;
3293 printalias(const struct alias *ap)
3295 out1fmt("%s=%s\n", ap->name, single_quote(ap->val));
3298 static struct alias **
3299 __lookupalias(const char *name) {
3300 unsigned int hashval;
3307 ch = (unsigned char)*p;
3311 ch = (unsigned char)*++p;
3313 app = &atab[hashval % ATABSIZE];
3315 for (; *app; app = &(*app)->next) {
3316 if (equal(name, (*app)->name)) {
3323 #endif /* ASH_ALIAS */
3328 * Evaluate a command.
3331 /* flags in argument to evaltree */
3332 #define EV_EXIT 01 /* exit after evaluating tree */
3333 #define EV_TESTED 02 /* exit status is checked; ignore -e flag */
3334 #define EV_BACKCMD 04 /* command executing within back quotes */
3337 static void evalloop(union node *, int);
3338 static void evalfor(union node *, int);
3339 static void evalcase(union node *, int);
3340 static void evalsubshell(union node *, int);
3341 static void expredir(union node *);
3342 static void evalpipe(union node *, int);
3343 static void evalcommand(union node *, int);
3344 static int evalbltin(const struct builtincmd *, int, char **);
3345 static int evalfun(struct funcnode *, int, char **, int);
3346 static void prehash(union node *);
3347 static int bltincmd(int, char **);
3350 static const struct builtincmd bltin = {
3357 * Evaluate a parse tree. The value is left in the global variable
3361 evaltree(union node *n, int flags)
3364 void (*evalfn)(union node *, int);
3368 TRACE(("evaltree(NULL) called\n"));
3371 TRACE(("pid %d, evaltree(%p: %d, %d) called\n",
3372 getpid(), n, n->type, flags));
3376 out1fmt("Node type = %d\n", n->type);
3381 evaltree(n->nnot.com, EV_TESTED);
3382 status = !exitstatus;
3385 expredir(n->nredir.redirect);
3386 status = redirectsafe(n->nredir.redirect, REDIR_PUSH);
3388 evaltree(n->nredir.n, flags & EV_TESTED);
3389 status = exitstatus;
3394 evalfn = evalcommand;
3396 if (eflag && !(flags & EV_TESTED))
3408 evalfn = evalsubshell;
3420 #error NAND + 1 != NOR
3422 #if NOR + 1 != NSEMI
3423 #error NOR + 1 != NSEMI
3425 isor = n->type - NAND;
3428 (flags | ((isor >> 1) - 1)) & EV_TESTED
3430 if (!exitstatus == isor)
3442 evaltree(n->nif.test, EV_TESTED);
3445 if (exitstatus == 0) {
3448 } else if (n->nif.elsepart) {
3449 n = n->nif.elsepart;
3454 defun(n->narg.text, n->narg.next);
3458 exitstatus = status;
3462 if ((checkexit & exitstatus))
3463 evalskip |= SKIPEVAL;
3464 else if (pendingsigs && dotrap())
3467 if (flags & EV_EXIT) {
3469 raise_exception(EXEXIT);
3474 #if !defined(__alpha__) || (defined(__GNUC__) && __GNUC__ >= 3)
3477 void evaltreenr(union node *, int) __attribute__ ((alias("evaltree"),__noreturn__));
3481 evalloop(union node *n, int flags)
3491 evaltree(n->nbinary.ch1, EV_TESTED);
3494 if (evalskip == SKIPCONT && --skipcount <= 0) {
3498 if (evalskip == SKIPBREAK && --skipcount <= 0)
3503 if (n->type != NWHILE)
3507 evaltree(n->nbinary.ch2, flags);
3508 status = exitstatus;
3513 exitstatus = status;
3518 evalfor(union node *n, int flags)
3520 struct arglist arglist;
3523 struct stackmark smark;
3525 setstackmark(&smark);
3526 arglist.lastp = &arglist.list;
3527 for (argp = n->nfor.args; argp; argp = argp->narg.next) {
3528 expandarg(argp, &arglist, EXP_FULL | EXP_TILDE | EXP_RECORD);
3533 *arglist.lastp = NULL;
3538 for (sp = arglist.list; sp; sp = sp->next) {
3539 setvar(n->nfor.var, sp->text, 0);
3540 evaltree(n->nfor.body, flags);
3542 if (evalskip == SKIPCONT && --skipcount <= 0) {
3546 if (evalskip == SKIPBREAK && --skipcount <= 0)
3553 popstackmark(&smark);
3558 evalcase(union node *n, int flags)
3562 struct arglist arglist;
3563 struct stackmark smark;
3565 setstackmark(&smark);
3566 arglist.lastp = &arglist.list;
3567 expandarg(n->ncase.expr, &arglist, EXP_TILDE);
3569 for (cp = n->ncase.cases; cp && evalskip == 0; cp = cp->nclist.next) {
3570 for (patp = cp->nclist.pattern; patp; patp = patp->narg.next) {
3571 if (casematch(patp, arglist.list->text)) {
3572 if (evalskip == 0) {
3573 evaltree(cp->nclist.body, flags);
3580 popstackmark(&smark);
3585 * Kick off a subshell to evaluate a tree.
3588 evalsubshell(union node *n, int flags)
3591 int backgnd = (n->type == NBACKGND);
3594 expredir(n->nredir.redirect);
3595 if (!backgnd && flags & EV_EXIT && !trap[0])
3599 if (forkshell(jp, n, backgnd) == 0) {
3603 flags &=~ EV_TESTED;
3605 redirect(n->nredir.redirect, 0);
3606 evaltreenr(n->nredir.n, flags);
3611 status = waitforjob(jp);
3612 exitstatus = status;
3618 * Compute the names of the files in a redirection list.
3621 expredir(union node *n)
3625 for (redir = n; redir; redir = redir->nfile.next) {
3628 memset(&fn, 0, sizeof(fn));
3629 fn.lastp = &fn.list;
3630 switch (redir->type) {
3636 expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR);
3637 redir->nfile.expfname = fn.list->text;
3641 if (redir->ndup.vname) {
3642 expandarg(redir->ndup.vname, &fn, EXP_FULL | EXP_TILDE);
3643 if (fn.list == NULL)
3644 ash_msg_and_raise_error("redir error");
3645 fixredir(redir, fn.list->text, 1);
3654 * Evaluate a pipeline. All the processes in the pipeline are children
3655 * of the process creating the pipeline. (This differs from some versions
3656 * of the shell, which make the last process in a pipeline the parent
3660 evalpipe(union node *n, int flags)
3663 struct nodelist *lp;
3668 TRACE(("evalpipe(0x%lx) called\n", (long)n));
3670 for (lp = n->npipe.cmdlist; lp; lp = lp->next)
3674 jp = makejob(n, pipelen);
3676 for (lp = n->npipe.cmdlist; lp; lp = lp->next) {
3680 if (pipe(pip) < 0) {
3682 ash_msg_and_raise_error("Pipe call failed");
3685 if (forkshell(jp, lp->n, n->npipe.backgnd) == 0) {
3698 evaltreenr(lp->n, flags);
3706 if (n->npipe.backgnd == 0) {
3707 exitstatus = waitforjob(jp);
3708 TRACE(("evalpipe: job done exit status %d\n", exitstatus));
3715 * Execute a command inside back quotes. If it's a builtin command, we
3716 * want to save its output in a block obtained from malloc. Otherwise
3717 * we fork off a subprocess and get the output of the command via a pipe.
3718 * Should be called with interrupts off.
3721 evalbackcmd(union node *n, struct backcmd *result)
3733 saveherefd = herefd;
3741 ash_msg_and_raise_error("Pipe call failed");
3743 if (forkshell(jp, n, FORK_NOJOB) == 0) {
3752 evaltreenr(n, EV_EXIT);
3756 result->fd = pip[0];
3759 herefd = saveherefd;
3761 TRACE(("evalbackcmd done: fd=%d buf=0x%x nleft=%d jp=0x%x\n",
3762 result->fd, result->buf, result->nleft, result->jp));
3765 #if ENABLE_ASH_CMDCMD
3767 parse_command_args(char **argv, const char **path)
3780 if (c == '-' && !*cp) {
3790 /* run 'typecmd' for other options */
3793 } while ((c = *cp++));
3799 static int isassignment(const char *p)
3801 const char *q = endofname(p);
3808 * Execute a simple command.
3811 evalcommand(union node *cmd, int flags)
3813 struct stackmark smark;
3815 struct arglist arglist;
3816 struct arglist varlist;
3819 const struct strlist *sp;
3820 struct cmdentry cmdentry;
3828 struct builtincmd *bcmd;
3829 int pseudovarflag = 0;
3831 /* First expand the arguments. */
3832 TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags));
3833 setstackmark(&smark);
3834 back_exitstatus = 0;
3836 cmdentry.cmdtype = CMDBUILTIN;
3837 cmdentry.u.cmd = &bltin;
3838 varlist.lastp = &varlist.list;
3839 *varlist.lastp = NULL;
3840 arglist.lastp = &arglist.list;
3841 *arglist.lastp = NULL;
3844 if (cmd->ncmd.args) {
3845 bcmd = find_builtin(cmd->ncmd.args->narg.text);
3846 pseudovarflag = bcmd && IS_BUILTIN_ASSIGN(bcmd);
3849 for (argp = cmd->ncmd.args; argp; argp = argp->narg.next) {
3850 struct strlist **spp;
3852 spp = arglist.lastp;
3853 if (pseudovarflag && isassignment(argp->narg.text))
3854 expandarg(argp, &arglist, EXP_VARTILDE);
3856 expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
3858 for (sp = *spp; sp; sp = sp->next)
3862 argv = nargv = stalloc(sizeof(char *) * (argc + 1));
3863 for (sp = arglist.list; sp; sp = sp->next) {
3864 TRACE(("evalcommand arg: %s\n", sp->text));
3865 *nargv++ = sp->text;
3870 if (iflag && funcnest == 0 && argc > 0)
3871 lastarg = nargv[-1];
3874 expredir(cmd->ncmd.redirect);
3875 status = redirectsafe(cmd->ncmd.redirect, REDIR_PUSH|REDIR_SAVEFD2);
3878 for (argp = cmd->ncmd.assign; argp; argp = argp->narg.next) {
3879 struct strlist **spp;
3882 spp = varlist.lastp;
3883 expandarg(argp, &varlist, EXP_VARTILDE);
3886 * Modify the command lookup path, if a PATH= assignment
3890 if (varequal(p, path))
3894 /* Print the command if xflag is set. */
3897 const char *p = " %s";
3900 dprintf(preverrout_fd, p, expandstr(ps4val()));
3903 for (n = 0; n < 2; n++) {
3905 dprintf(preverrout_fd, p, sp->text);
3913 full_write(preverrout_fd, "\n", 1);
3919 /* Now locate the command. */
3921 const char *oldpath;
3922 int cmd_flag = DO_ERR;
3927 find_command(argv[0], &cmdentry, cmd_flag, path);
3928 if (cmdentry.cmdtype == CMDUNKNOWN) {
3934 /* implement bltin and command here */
3935 if (cmdentry.cmdtype != CMDBUILTIN)
3938 spclbltin = IS_BUILTIN_SPECIAL(cmdentry.u.cmd);
3939 if (cmdentry.u.cmd == EXECCMD)
3941 #if ENABLE_ASH_CMDCMD
3942 if (cmdentry.u.cmd == COMMANDCMD) {
3945 nargv = parse_command_args(argv, &path);
3948 argc -= nargv - argv;
3950 cmd_flag |= DO_NOFUNC;
3958 /* We have a redirection error. */
3960 raise_exception(EXERROR);
3962 exitstatus = status;
3966 /* Execute the command. */
3967 switch (cmdentry.cmdtype) {
3969 /* Fork off a child process if necessary. */
3970 if (!(flags & EV_EXIT) || trap[0]) {
3972 jp = makejob(cmd, 1);
3973 if (forkshell(jp, cmd, FORK_FG) != 0) {
3974 exitstatus = waitforjob(jp);
3980 listsetvar(varlist.list, VEXPORT|VSTACK);
3981 shellexec(argv, path, cmdentry.u.index);
3985 cmdenviron = varlist.list;
3987 struct strlist *list = cmdenviron;
3989 if (spclbltin > 0 || argc == 0) {
3991 if (cmd_is_exec && argc > 1)
3994 listsetvar(list, i);
3996 if (evalbltin(cmdentry.u.cmd, argc, argv)) {
4011 exit_status = j + 128;
4012 exitstatus = exit_status;
4014 if (i == EXINT || spclbltin > 0) {
4016 longjmp(exception_handler->loc, 1);
4023 listsetvar(varlist.list, 0);
4024 if (evalfun(cmdentry.u.func, argc, argv, flags))
4030 popredir(cmd_is_exec);
4032 /* dsl: I think this is intended to be used to support
4033 * '_' in 'vi' command mode during line editing...
4034 * However I implemented that within libedit itself.
4036 setvar("_", lastarg, 0);
4037 popstackmark(&smark);
4041 evalbltin(const struct builtincmd *cmd, int argc, char **argv)
4043 char *volatile savecmdname;
4044 struct jmploc *volatile savehandler;
4045 struct jmploc jmploc;
4048 savecmdname = commandname;
4049 i = setjmp(jmploc.loc);
4052 savehandler = exception_handler;
4053 exception_handler = &jmploc;
4054 commandname = argv[0];
4056 optptr = NULL; /* initialize nextopt */
4057 exitstatus = (*cmd->builtin)(argc, argv);
4058 flush_stdout_stderr();
4060 exitstatus |= ferror(stdout);
4062 commandname = savecmdname;
4064 exception_handler = savehandler;
4069 static struct localvar *localvars;
4072 * Called after a function returns.
4073 * Interrupts must be off.
4078 struct localvar *lvp;
4081 while ((lvp = localvars) != NULL) {
4082 localvars = lvp->next;
4084 TRACE(("poplocalvar %s", vp ? vp->text : "-"));
4085 if (vp == NULL) { /* $- saved */
4086 memcpy(optlist, lvp->text, sizeof(optlist));
4087 free((char*)lvp->text);
4089 } else if ((lvp->flags & (VUNSET|VSTRFIXED)) == VUNSET) {
4093 (*vp->func)(strchrnul(lvp->text, '=') + 1);
4094 if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0)
4095 free((char*)vp->text);
4096 vp->flags = lvp->flags;
4097 vp->text = lvp->text;
4104 evalfun(struct funcnode *func, int argc, char **argv, int flags)
4106 volatile struct shparam saveparam;
4107 struct localvar *volatile savelocalvars;
4108 struct jmploc *volatile savehandler;
4109 struct jmploc jmploc;
4112 saveparam = shellparam;
4113 savelocalvars = localvars;
4114 e = setjmp(jmploc.loc);
4119 savehandler = exception_handler;
4120 exception_handler = &jmploc;
4122 shellparam.malloc = 0;
4126 shellparam.nparam = argc - 1;
4127 shellparam.p = argv + 1;
4128 #if ENABLE_ASH_GETOPTS
4129 shellparam.optind = 1;
4130 shellparam.optoff = -1;
4132 evaltree(&func->n, flags & EV_TESTED);
4138 localvars = savelocalvars;
4139 freeparam(&shellparam);
4140 shellparam = saveparam;
4141 exception_handler = savehandler;
4143 evalskip &= ~SKIPFUNC;
4149 goodname(const char *p)
4151 return !*endofname(p);
4156 * Search for a command. This is called before we fork so that the
4157 * location of the command will be available in the parent as well as
4158 * the child. The check for "goodname" is an overly conservative
4159 * check that the name will not be subject to expansion.
4162 prehash(union node *n)
4164 struct cmdentry entry;
4166 if (n->type == NCMD && n->ncmd.args && goodname(n->ncmd.args->narg.text))
4167 find_command(n->ncmd.args->narg.text, &entry, 0, pathval());
4173 * Builtin commands. Builtin commands whose functions are closely
4174 * tied to evaluation are implemented here.
4181 bltincmd(int argc, char **argv)
4184 * Preserve exitstatus of a previous possible redirection
4187 return back_exitstatus;
4192 * Handle break and continue commands. Break, continue, and return are
4193 * all handled by setting the evalskip flag. The evaluation routines
4194 * above all check this flag, and if it is set they start skipping
4195 * commands rather than executing them. The variable skipcount is
4196 * the number of loops to break/continue, or the number of function
4197 * levels to return. (The latter is always 1.) It should probably
4198 * be an error to break out of more loops than exist, but it isn't
4199 * in the standard shell so we don't make it one here.
4203 breakcmd(int argc, char **argv)
4205 int n = argc > 1 ? number(argv[1]) : 1;
4208 ash_msg_and_raise_error(illnum, argv[1]);
4212 evalskip = (**argv == 'c')? SKIPCONT : SKIPBREAK;
4220 * The return command.
4223 returncmd(int argc, char **argv)
4226 * If called outside a function, do what ksh does;
4227 * skip the rest of the file.
4229 evalskip = funcnest ? SKIPFUNC : SKIPFILE;
4230 return argv[1] ? number(argv[1]) : exitstatus;
4235 falsecmd(int argc, char **argv)
4242 truecmd(int argc, char **argv)
4249 execcmd(int argc, char **argv)
4252 iflag = 0; /* exit on error */
4255 shellexec(argv + 1, pathval(), 0);
4264 * When commands are first encountered, they are entered in a hash table.
4265 * This ensures that a full path search will not have to be done for them
4266 * on each invocation.
4268 * We should investigate converting to a linear search, even though that
4269 * would make the command name "hash" a misnomer.
4272 #define CMDTABLESIZE 31 /* should be prime */
4273 #define ARB 1 /* actual size determined at run time */
4277 struct tblentry *next; /* next entry in hash chain */
4278 union param param; /* definition of builtin function */
4279 short cmdtype; /* index identifying command */
4280 char rehash; /* if set, cd done since entry created */
4281 char cmdname[ARB]; /* name of command */
4285 static struct tblentry *cmdtable[CMDTABLESIZE];
4286 static int builtinloc = -1; /* index in path of %builtin, or -1 */
4289 static void tryexec(char *, char **, char **);
4290 static void clearcmdentry(int);
4291 static struct tblentry *cmdlookup(const char *, int);
4292 static void delete_cmd_entry(void);
4296 * Exec a program. Never returns. If you change this routine, you may
4297 * have to change the find_command routine as well.
4299 #define environment() listvars(VEXPORT, VUNSET, 0)
4300 static void shellexec(char **, const char *, int) ATTRIBUTE_NORETURN;
4302 shellexec(char **argv, const char *path, int idx)
4310 envp = environment();
4311 if (strchr(argv[0], '/') || is_safe_applet(argv[0])
4312 #if ENABLE_FEATURE_SH_STANDALONE_SHELL
4313 || find_applet_by_name(argv[0])
4316 tryexec(argv[0], argv, envp);
4320 while ((cmdname = padvance(&path, argv[0])) != NULL) {
4321 if (--idx < 0 && pathopt == NULL) {
4322 tryexec(cmdname, argv, envp);
4323 if (errno != ENOENT && errno != ENOTDIR)
4330 /* Map to POSIX errors */
4342 exitstatus = exerrno;
4343 TRACE(("shellexec failed for %s, errno %d, suppressint %d\n",
4344 argv[0], e, suppressint ));
4345 ash_msg_and_raise(EXEXEC, "%s: %s", argv[0], errmsg(e, "not found"));
4351 tryexec(char *cmd, char **argv, char **envp)
4354 struct BB_applet *a;
4358 if (strchr(cmd, '/') == NULL
4359 && (a = find_applet_by_name(cmd)) != NULL
4360 && is_safe_applet(cmd)
4363 while (*c != NULL) {
4367 exit(a->main(argc, argv));
4369 #if ENABLE_FEATURE_SH_STANDALONE_SHELL
4370 if (find_applet_by_name(cmd) != NULL) {
4371 /* re-exec ourselves with the new arguments */
4372 execve(CONFIG_BUSYBOX_EXEC_PATH, argv, envp);
4373 /* If they called chroot or otherwise made the binary no longer
4374 * executable, fall through */
4381 execve(cmd, argv, envp);
4382 } while (errno == EINTR);
4384 execve(cmd, argv, envp);
4388 } else if (errno == ENOEXEC) {
4392 for (ap = argv; *ap; ap++)
4394 ap = new = ckmalloc((ap - argv + 2) * sizeof(char *));
4396 *ap = cmd = (char *)DEFAULT_SHELL;
4399 while ((*ap++ = *argv++))
4407 /*** Command hashing code ***/
4410 printentry(struct tblentry *cmdp)
4416 idx = cmdp->param.index;
4419 name = padvance(&path, cmdp->cmdname);
4421 } while (--idx >= 0);
4422 out1fmt("%s%s\n", name, (cmdp->rehash ? "*" : nullstr));
4427 hashcmd(int argc, char **argv)
4429 struct tblentry **pp;
4430 struct tblentry *cmdp;
4432 struct cmdentry entry;
4435 while ((c = nextopt("r")) != '\0') {
4439 if (*argptr == NULL) {
4440 for (pp = cmdtable; pp < &cmdtable[CMDTABLESIZE]; pp++) {
4441 for (cmdp = *pp; cmdp; cmdp = cmdp->next) {
4442 if (cmdp->cmdtype == CMDNORMAL)
4449 while ((name = *argptr) != NULL) {
4450 cmdp = cmdlookup(name, 0);
4452 && (cmdp->cmdtype == CMDNORMAL
4453 || (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0)))
4455 find_command(name, &entry, DO_ERR, pathval());
4456 if (entry.cmdtype == CMDUNKNOWN)
4465 * Resolve a command name. If you change this routine, you may have to
4466 * change the shellexec routine as well.
4469 find_command(char *name, struct cmdentry *entry, int act, const char *path)
4471 struct tblentry *cmdp;
4478 struct builtincmd *bcmd;
4480 /* If name contains a slash, don't use PATH or hash table */
4481 if (strchr(name, '/') != NULL) {
4482 entry->u.index = -1;
4484 while (stat(name, &statb) < 0) {
4489 entry->cmdtype = CMDUNKNOWN;
4493 entry->cmdtype = CMDNORMAL;
4497 #if ENABLE_FEATURE_SH_STANDALONE_SHELL
4498 if (find_applet_by_name(name)) {
4499 entry->cmdtype = CMDNORMAL;
4500 entry->u.index = -1;
4505 if (is_safe_applet(name)) {
4506 entry->cmdtype = CMDNORMAL;
4507 entry->u.index = -1;
4511 updatetbl = (path == pathval());
4514 if (strstr(path, "%builtin") != NULL)
4518 /* If name is in the table, check answer will be ok */
4519 cmdp = cmdlookup(name, 0);
4523 switch (cmdp->cmdtype) {
4541 } else if (cmdp->rehash == 0)
4542 /* if not invalidated by cd, we're done */
4546 /* If %builtin not in path, check for builtin next */
4547 bcmd = find_builtin(name);
4548 if (bcmd && (IS_BUILTIN_REGULAR(bcmd) || (
4549 act & DO_ALTPATH ? !(act & DO_ALTBLTIN) : builtinloc <= 0
4551 goto builtin_success;
4553 /* We have to search path. */
4554 prev = -1; /* where to start */
4555 if (cmdp && cmdp->rehash) { /* doing a rehash */
4556 if (cmdp->cmdtype == CMDBUILTIN)
4559 prev = cmdp->param.index;
4565 while ((fullname = padvance(&path, name)) != NULL) {
4566 stunalloc(fullname);
4569 if (prefix(pathopt, "builtin")) {
4571 goto builtin_success;
4573 } else if (!(act & DO_NOFUNC) &&
4574 prefix(pathopt, "func")) {
4577 /* ignore unimplemented options */
4581 /* if rehash, don't redo absolute path names */
4582 if (fullname[0] == '/' && idx <= prev) {
4585 TRACE(("searchexec \"%s\": no change\n", name));
4588 while (stat(fullname, &statb) < 0) {
4593 if (errno != ENOENT && errno != ENOTDIR)
4597 e = EACCES; /* if we fail, this will be the error */
4598 if (!S_ISREG(statb.st_mode))
4600 if (pathopt) { /* this is a %func directory */
4601 stalloc(strlen(fullname) + 1);
4602 readcmdfile(fullname);
4603 cmdp = cmdlookup(name, 0);
4604 if (cmdp == NULL || cmdp->cmdtype != CMDFUNCTION)
4605 ash_msg_and_raise_error("%s not defined in %s", name, fullname);
4606 stunalloc(fullname);
4609 TRACE(("searchexec \"%s\" returns \"%s\"\n", name, fullname));
4611 entry->cmdtype = CMDNORMAL;
4612 entry->u.index = idx;
4616 cmdp = cmdlookup(name, 1);
4617 cmdp->cmdtype = CMDNORMAL;
4618 cmdp->param.index = idx;
4623 /* We failed. If there was an entry for this command, delete it */
4624 if (cmdp && updatetbl)
4627 ash_msg("%s: %s", name, errmsg(e, "not found"));
4628 entry->cmdtype = CMDUNKNOWN;
4633 entry->cmdtype = CMDBUILTIN;
4634 entry->u.cmd = bcmd;
4638 cmdp = cmdlookup(name, 1);
4639 cmdp->cmdtype = CMDBUILTIN;
4640 cmdp->param.cmd = bcmd;
4644 entry->cmdtype = cmdp->cmdtype;
4645 entry->u = cmdp->param;
4650 * Search the table of builtin commands.
4652 static struct builtincmd *
4653 find_builtin(const char *name)
4655 struct builtincmd *bp;
4658 name, builtincmd, NUMBUILTINS, sizeof(struct builtincmd),
4666 * Called when a cd is done. Marks all commands so the next time they
4667 * are executed they will be rehashed.
4672 struct tblentry **pp;
4673 struct tblentry *cmdp;
4675 for (pp = cmdtable; pp < &cmdtable[CMDTABLESIZE]; pp++) {
4676 for (cmdp = *pp; cmdp; cmdp = cmdp->next) {
4677 if (cmdp->cmdtype == CMDNORMAL || (
4678 cmdp->cmdtype == CMDBUILTIN &&
4679 !(IS_BUILTIN_REGULAR(cmdp->param.cmd)) &&
4689 * Fix command hash table when PATH changed.
4690 * Called before PATH is changed. The argument is the new value of PATH;
4691 * pathval() still returns the old value at this point.
4692 * Called with interrupts off.
4695 changepath(const char *newval)
4697 const char *old, *new;
4704 firstchange = 9999; /* assume no change */
4710 if ((*old == '\0' && *new == ':')
4711 || (*old == ':' && *new == '\0'))
4713 old = new; /* ignore subsequent differences */
4717 if (*new == '%' && idx_bltin < 0 && prefix(new + 1, "builtin"))
4724 if (builtinloc < 0 && idx_bltin >= 0)
4725 builtinloc = idx_bltin; /* zap builtins */
4726 if (builtinloc >= 0 && idx_bltin < 0)
4728 clearcmdentry(firstchange);
4729 builtinloc = idx_bltin;
4734 * Clear out command entries. The argument specifies the first entry in
4735 * PATH which has changed.
4738 clearcmdentry(int firstchange)
4740 struct tblentry **tblp;
4741 struct tblentry **pp;
4742 struct tblentry *cmdp;
4745 for (tblp = cmdtable; tblp < &cmdtable[CMDTABLESIZE]; tblp++) {
4747 while ((cmdp = *pp) != NULL) {
4748 if ((cmdp->cmdtype == CMDNORMAL &&
4749 cmdp->param.index >= firstchange)
4750 || (cmdp->cmdtype == CMDBUILTIN &&
4751 builtinloc >= firstchange)
4765 * Locate a command in the command hash table. If "add" is nonzero,
4766 * add the command to the table if it is not already present. The
4767 * variable "lastcmdentry" is set to point to the address of the link
4768 * pointing to the entry, so that delete_cmd_entry can delete the
4771 * Interrupts must be off if called with add != 0.
4773 static struct tblentry **lastcmdentry;
4775 static struct tblentry *
4776 cmdlookup(const char *name, int add)
4778 unsigned int hashval;
4780 struct tblentry *cmdp;
4781 struct tblentry **pp;
4784 hashval = (unsigned char)*p << 4;
4786 hashval += (unsigned char)*p++;
4788 pp = &cmdtable[hashval % CMDTABLESIZE];
4789 for (cmdp = *pp; cmdp; cmdp = cmdp->next) {
4790 if (equal(cmdp->cmdname, name))
4794 if (add && cmdp == NULL) {
4795 cmdp = *pp = ckmalloc(sizeof(struct tblentry) - ARB
4796 + strlen(name) + 1);
4798 cmdp->cmdtype = CMDUNKNOWN;
4799 strcpy(cmdp->cmdname, name);
4807 * Delete the command entry returned on the last lookup.
4810 delete_cmd_entry(void)
4812 struct tblentry *cmdp;
4815 cmdp = *lastcmdentry;
4816 *lastcmdentry = cmdp->next;
4817 if (cmdp->cmdtype == CMDFUNCTION)
4818 freefunc(cmdp->param.func);
4825 * Add a new command entry, replacing any existing command entry for
4826 * the same name - except special builtins.
4828 static void addcmdentry(char *name, struct cmdentry *entry)
4830 struct tblentry *cmdp;
4832 cmdp = cmdlookup(name, 1);
4833 if (cmdp->cmdtype == CMDFUNCTION) {
4834 freefunc(cmdp->param.func);
4836 cmdp->cmdtype = entry->cmdtype;
4837 cmdp->param = entry->u;
4843 * Make a copy of a parse tree.
4845 static struct funcnode * copyfunc(union node *n)
4850 funcblocksize = offsetof(struct funcnode, n);
4853 blocksize = funcblocksize;
4854 f = ckmalloc(blocksize + funcstringsize);
4855 funcblock = (char *) f + offsetof(struct funcnode, n);
4856 funcstring = (char *) f + blocksize;
4864 * Define a shell function.
4867 defun(char *name, union node *func)
4869 struct cmdentry entry;
4872 entry.cmdtype = CMDFUNCTION;
4873 entry.u.func = copyfunc(func);
4874 addcmdentry(name, &entry);
4880 * Delete a function if it exists.
4883 unsetfunc(const char *name)
4885 struct tblentry *cmdp;
4887 cmdp = cmdlookup(name, 0);
4888 if (cmdp!= NULL && cmdp->cmdtype == CMDFUNCTION)
4893 * Locate and print what a word is...
4895 #if ENABLE_ASH_CMDCMD
4897 describe_command(char *command, int describe_command_verbose)
4899 #define describe_command_verbose 1
4901 describe_command(char *command)
4904 struct cmdentry entry;
4905 struct tblentry *cmdp;
4906 #if ENABLE_ASH_ALIAS
4907 const struct alias *ap;
4909 const char *path = pathval();
4911 if (describe_command_verbose) {
4915 /* First look at the keywords */
4916 if (findkwd(command)) {
4917 out1str(describe_command_verbose ? " is a shell keyword" : command);
4921 #if ENABLE_ASH_ALIAS
4922 /* Then look at the aliases */
4923 ap = lookupalias(command, 0);
4925 if (describe_command_verbose) {
4926 out1fmt(" is an alias for %s", ap->val);
4935 /* Then check if it is a tracked alias */
4936 cmdp = cmdlookup(command, 0);
4938 entry.cmdtype = cmdp->cmdtype;
4939 entry.u = cmdp->param;
4941 /* Finally use brute force */
4942 find_command(command, &entry, DO_ABS, path);
4945 switch (entry.cmdtype) {
4947 int j = entry.u.index;
4953 p = padvance(&path, command);
4957 if (describe_command_verbose) {
4959 (cmdp ? " a tracked alias for" : nullstr), p
4968 if (describe_command_verbose) {
4969 out1str(" is a shell function");
4976 if (describe_command_verbose) {
4977 out1fmt(" is a %sshell builtin",
4978 IS_BUILTIN_SPECIAL(entry.u.cmd) ?
4979 "special " : nullstr
4987 if (describe_command_verbose) {
4988 out1str(": not found\n");
4993 outstr("\n", stdout);
4998 typecmd(int argc, char **argv)
5003 for (i = 1; i < argc; i++) {
5004 #if ENABLE_ASH_CMDCMD
5005 err |= describe_command(argv[i], 1);
5007 err |= describe_command(argv[i]);
5013 #if ENABLE_ASH_CMDCMD
5015 commandcmd(int argc, char **argv)
5023 while ((c = nextopt("pvV")) != '\0')
5025 verify |= VERIFY_VERBOSE;
5027 verify |= VERIFY_BRIEF;
5033 return describe_command(*argptr, verify - VERIFY_BRIEF);
5042 * Routines to expand arguments to commands. We have to deal with
5043 * backquotes, shell variables, and file metacharacters.
5049 #define RMESCAPE_ALLOC 0x1 /* Allocate a new string */
5050 #define RMESCAPE_GLOB 0x2 /* Add backslashes for glob */
5051 #define RMESCAPE_QUOTED 0x4 /* Remove CTLESC unless in quotes */
5052 #define RMESCAPE_GROW 0x8 /* Grow strings instead of stalloc */
5053 #define RMESCAPE_HEAP 0x10 /* Malloc strings instead of stalloc */
5056 * Structure specifying which parts of the string should be searched
5057 * for IFS characters.
5061 struct ifsregion *next; /* next region in list */
5062 int begoff; /* offset of start of region */
5063 int endoff; /* offset of end of region */
5064 int nulonly; /* search for nul bytes only */
5067 /* output of current string */
5068 static char *expdest;
5069 /* list of back quote expressions */
5070 static struct nodelist *argbackq;
5071 /* first struct in list of ifs regions */
5072 static struct ifsregion ifsfirst;
5073 /* last struct in list */
5074 static struct ifsregion *ifslastp;
5075 /* holds expanded arg list */
5076 static struct arglist exparg;
5078 static void argstr(char *, int);
5079 static char *exptilde(char *, char *, int);
5080 static void expbackq(union node *, int, int);
5081 static const char *subevalvar(char *, char *, int, int, int, int, int);
5082 static char *evalvar(char *, int);
5083 static void strtodest(const char *, int, int);
5084 static void memtodest(const char *p, size_t len, int syntax, int quotes);
5085 static ssize_t varvalue(char *, int, int);
5086 static void recordregion(int, int, int);
5087 static void removerecordregions(int);
5088 static void ifsbreakup(char *, struct arglist *);
5089 static void ifsfree(void);
5090 static void expandmeta(struct strlist *, int);
5091 static int patmatch(char *, const char *);
5093 static int cvtnum(arith_t);
5094 static size_t esclen(const char *, const char *);
5095 static char *scanleft(char *, char *, char *, char *, int, int);
5096 static char *scanright(char *, char *, char *, char *, int, int);
5097 static void varunset(const char *, const char *, const char *, int) ATTRIBUTE_NORETURN;
5100 #define pmatch(a, b) !fnmatch((a), (b), 0)
5102 * Prepare a pattern for a expmeta (internal glob(3)) call.
5104 * Returns an stalloced string.
5107 static char * preglob(const char *pattern, int quoted, int flag)
5109 flag |= RMESCAPE_GLOB;
5111 flag |= RMESCAPE_QUOTED;
5113 return _rmescapes((char *)pattern, flag);
5118 esclen(const char *start, const char *p)
5122 while (p > start && *--p == CTLESC) {
5130 * Expand shell variables and backquotes inside a here document.
5133 static void expandhere(union node *arg, int fd)
5136 expandarg(arg, (struct arglist *)NULL, 0);
5137 full_write(fd, stackblock(), expdest - (char *)stackblock());
5142 * Perform variable substitution and command substitution on an argument,
5143 * placing the resulting list of arguments in arglist. If EXP_FULL is true,
5144 * perform splitting and file name expansion. When arglist is NULL, perform
5145 * here document expansion.
5148 expandarg(union node *arg, struct arglist *arglist, int flag)
5153 argbackq = arg->narg.backquote;
5154 STARTSTACKSTR(expdest);
5155 ifsfirst.next = NULL;
5157 argstr(arg->narg.text, flag);
5158 p = _STPUTC('\0', expdest);
5160 if (arglist == NULL) {
5161 return; /* here document expanded */
5163 p = grabstackstr(p);
5164 exparg.lastp = &exparg.list;
5168 if (flag & EXP_FULL) {
5169 ifsbreakup(p, &exparg);
5170 *exparg.lastp = NULL;
5171 exparg.lastp = &exparg.list;
5172 expandmeta(exparg.list, flag);
5174 if (flag & EXP_REDIR) /*XXX - for now, just remove escapes */
5176 sp = stalloc(sizeof(*sp));
5179 exparg.lastp = &sp->next;
5183 *exparg.lastp = NULL;
5185 *arglist->lastp = exparg.list;
5186 arglist->lastp = exparg.lastp;
5192 * Perform variable and command substitution. If EXP_FULL is set, output CTLESC
5193 * characters to allow for further processing. Otherwise treat
5194 * $@ like $* since no splitting will be performed.
5197 argstr(char *p, int flag)
5199 static const char spclchars[] = {
5207 CTLBACKQ | CTLQUOTE,
5208 #if ENABLE_ASH_MATH_SUPPORT
5213 const char *reject = spclchars;
5215 int quotes = flag & (EXP_FULL | EXP_CASE); /* do CTLESC */
5216 int breakall = flag & EXP_WORD;
5221 if (!(flag & EXP_VARTILDE)) {
5223 } else if (flag & EXP_VARTILDE2) {
5228 if (flag & EXP_TILDE) {
5234 if (*q == CTLESC && (flag & EXP_QWORD))
5237 p = exptilde(p, q, flag);
5240 startloc = expdest - (char *)stackblock();
5242 length += strcspn(p + length, reject);
5244 if (c && (!(c & 0x80)
5245 #if ENABLE_ASH_MATH_SUPPORT
5249 /* c == '=' || c == ':' || c == CTLENDARI */
5254 expdest = stack_nputstr(p, length, expdest);
5255 newloc = expdest - (char *)stackblock();
5256 if (breakall && !inquotes && newloc > startloc) {
5257 recordregion(startloc, newloc, 0);
5268 if (flag & EXP_VARTILDE2) {
5272 flag |= EXP_VARTILDE2;
5277 * sort of a hack - expand tildes in variable
5278 * assignments (after the first '=' and after ':'s).
5287 case CTLENDVAR: /* ??? */
5290 /* "$@" syntax adherence hack */
5293 !memcmp(p, dolatstr, DOLATSTRLEN) &&
5294 (p[4] == CTLQUOTEMARK || (
5295 p[4] == CTLENDVAR &&
5296 p[5] == CTLQUOTEMARK
5299 p = evalvar(p + 1, flag) + 1;
5302 inquotes = !inquotes;
5315 p = evalvar(p, flag);
5319 case CTLBACKQ|CTLQUOTE:
5320 expbackq(argbackq->n, c, quotes);
5321 argbackq = argbackq->next;
5323 #if ENABLE_ASH_MATH_SUPPORT
5336 exptilde(char *startp, char *p, int flag)
5342 int quotes = flag & (EXP_FULL | EXP_CASE);
5347 while ((c = *++p) != '\0') {
5354 if (flag & EXP_VARTILDE)
5364 if (*name == '\0') {
5365 home = lookupvar(homestr);
5367 pw = getpwnam(name);
5372 if (!home || !*home)
5375 startloc = expdest - (char *)stackblock();
5376 strtodest(home, SQSYNTAX, quotes);
5377 recordregion(startloc, expdest - (char *)stackblock(), 0);
5386 removerecordregions(int endoff)
5388 if (ifslastp == NULL)
5391 if (ifsfirst.endoff > endoff) {
5392 while (ifsfirst.next != NULL) {
5393 struct ifsregion *ifsp;
5395 ifsp = ifsfirst.next->next;
5396 free(ifsfirst.next);
5397 ifsfirst.next = ifsp;
5400 if (ifsfirst.begoff > endoff)
5403 ifslastp = &ifsfirst;
5404 ifsfirst.endoff = endoff;
5409 ifslastp = &ifsfirst;
5410 while (ifslastp->next && ifslastp->next->begoff < endoff)
5411 ifslastp=ifslastp->next;
5412 while (ifslastp->next != NULL) {
5413 struct ifsregion *ifsp;
5415 ifsp = ifslastp->next->next;
5416 free(ifslastp->next);
5417 ifslastp->next = ifsp;
5420 if (ifslastp->endoff > endoff)
5421 ifslastp->endoff = endoff;
5425 #if ENABLE_ASH_MATH_SUPPORT
5427 * Expand arithmetic expression. Backup to start of expression,
5428 * evaluate, place result in (backed up) result, adjust string position.
5441 * This routine is slightly over-complicated for
5442 * efficiency. Next we scan backwards looking for the
5443 * start of arithmetic.
5445 start = stackblock();
5452 while (*p != CTLARI) {
5456 ash_msg_and_raise_error("missing CTLARI (shouldn't happen)");
5461 esc = esclen(start, p);
5471 removerecordregions(begoff);
5480 len = cvtnum(dash_arith(p + 2));
5483 recordregion(begoff, begoff + len, 0);
5489 * Expand stuff in backwards quotes.
5492 expbackq(union node *cmd, int quoted, int quotes)
5500 int syntax = quoted? DQSYNTAX : BASESYNTAX;
5501 struct stackmark smark;
5504 setstackmark(&smark);
5506 startloc = dest - (char *)stackblock();
5508 evalbackcmd(cmd, (struct backcmd *) &in);
5509 popstackmark(&smark);
5516 memtodest(p, i, syntax, quotes);
5520 i = safe_read(in.fd, buf, sizeof(buf));
5521 TRACE(("expbackq: read returns %d\n", i));
5531 back_exitstatus = waitforjob(in.jp);
5535 /* Eat all trailing newlines */
5537 for (; dest > (char *)stackblock() && dest[-1] == '\n';)
5542 recordregion(startloc, dest - (char *)stackblock(), 0);
5543 TRACE(("evalbackq: size=%d: \"%.*s\"\n",
5544 (dest - (char *)stackblock()) - startloc,
5545 (dest - (char *)stackblock()) - startloc,
5546 stackblock() + startloc));
5551 scanleft(char *startp, char *rmesc, char *rmescend, char *str, int quotes,
5562 const char *s = loc2;
5568 match = pmatch(str, s);
5572 if (quotes && *loc == CTLESC)
5582 scanright(char *startp, char *rmesc, char *rmescend, char *str, int quotes,
5589 for (loc = str - 1, loc2 = rmescend; loc >= startp; loc2--) {
5592 const char *s = loc2;
5597 match = pmatch(str, s);
5604 esc = esclen(startp, loc);
5616 subevalvar(char *p, char *str, int strloc, int subtype, int startloc, int varflags, int quotes)
5620 int saveherefd = herefd;
5621 struct nodelist *saveargbackq = argbackq;
5623 char *rmesc, *rmescend;
5625 char *(*scan)(char *, char *, char *, char *, int , int);
5628 argstr(p, subtype != VSASSIGN && subtype != VSQUESTION ? EXP_CASE : 0);
5629 STPUTC('\0', expdest);
5630 herefd = saveherefd;
5631 argbackq = saveargbackq;
5632 startp = stackblock() + startloc;
5636 setvar(str, startp, 0);
5637 amount = startp - expdest;
5638 STADJUST(amount, expdest);
5642 varunset(p, str, startp, varflags);
5646 subtype -= VSTRIMRIGHT;
5648 if (subtype < 0 || subtype > 3)
5653 rmescend = stackblock() + strloc;
5655 rmesc = _rmescapes(startp, RMESCAPE_ALLOC | RMESCAPE_GROW);
5656 if (rmesc != startp) {
5658 startp = stackblock() + startloc;
5662 str = stackblock() + strloc;
5663 preglob(str, varflags & VSQUOTE, 0);
5665 /* zero = subtype == VSTRIMLEFT || subtype == VSTRIMLEFTMAX */
5666 zero = subtype >> 1;
5667 /* VSTRIMLEFT/VSTRIMRIGHTMAX -> scanleft */
5668 scan = (subtype & 1) ^ zero ? scanleft : scanright;
5670 loc = scan(startp, rmesc, rmescend, str, quotes, zero);
5673 memmove(startp, loc, str - loc);
5674 loc = startp + (str - loc) - 1;
5677 amount = loc - expdest;
5678 STADJUST(amount, expdest);
5685 * Expand a variable, and return a pointer to the next character in the
5689 evalvar(char *p, int flag)
5702 quotes = flag & (EXP_FULL | EXP_CASE);
5704 subtype = varflags & VSTYPE;
5705 quoted = varflags & VSQUOTE;
5707 easy = (!quoted || (*var == '@' && shellparam.nparam));
5708 startloc = expdest - (char *)stackblock();
5709 p = strchr(p, '=') + 1;
5712 varlen = varvalue(var, varflags, flag);
5713 if (varflags & VSNUL)
5716 if (subtype == VSPLUS) {
5717 varlen = -1 - varlen;
5721 if (subtype == VSMINUS) {
5725 p, flag | EXP_TILDE |
5726 (quoted ? EXP_QWORD : EXP_WORD)
5735 if (subtype == VSASSIGN || subtype == VSQUESTION) {
5737 if (subevalvar(p, var, 0, subtype, startloc, varflags, 0)) {
5740 * Remove any recorded regions beyond
5743 removerecordregions(startloc);
5753 if (varlen < 0 && uflag)
5754 varunset(p, var, 0, 0);
5756 if (subtype == VSLENGTH) {
5757 cvtnum(varlen > 0 ? varlen : 0);
5761 if (subtype == VSNORMAL) {
5765 recordregion(startloc, expdest - (char *)stackblock(), quoted);
5774 case VSTRIMRIGHTMAX:
5783 * Terminate the string and start recording the pattern
5786 STPUTC('\0', expdest);
5787 patloc = expdest - (char *)stackblock();
5788 if (subevalvar(p, NULL, patloc, subtype,
5789 startloc, varflags, quotes) == 0) {
5790 int amount = expdest - (
5791 (char *)stackblock() + patloc - 1
5793 STADJUST(-amount, expdest);
5795 /* Remove any recorded regions beyond start of variable */
5796 removerecordregions(startloc);
5801 if (subtype != VSNORMAL) { /* skip to end of alternative */
5807 else if (c == CTLBACKQ || c == (CTLBACKQ|CTLQUOTE)) {
5809 argbackq = argbackq->next;
5810 } else if (c == CTLVAR) {
5811 if ((*p++ & VSTYPE) != VSNORMAL)
5813 } else if (c == CTLENDVAR) {
5824 * Put a string on the stack.
5827 memtodest(const char *p, size_t len, int syntax, int quotes)
5831 q = makestrspace(len * 2, q);
5834 int c = SC2INT(*p++);
5837 if (quotes && (SIT(c, syntax) == CCTL || SIT(c, syntax) == CBACK))
5847 strtodest(const char *p, int syntax, int quotes)
5849 memtodest(p, strlen(p), syntax, quotes);
5854 * Add the value of a specialized variable to the stack string.
5857 varvalue(char *name, int varflags, int flags)
5867 int quoted = varflags & VSQUOTE;
5868 int subtype = varflags & VSTYPE;
5869 int quotes = flags & (EXP_FULL | EXP_CASE);
5871 if (quoted && (flags & EXP_FULL))
5872 sep = 1 << CHAR_BIT;
5874 syntax = quoted ? DQSYNTAX : BASESYNTAX;
5883 num = shellparam.nparam;
5893 p = makestrspace(NOPTS, expdest);
5894 for (i = NOPTS - 1; i >= 0; i--) {
5896 USTPUTC(optletters(i), p);
5907 sep = ifsset() ? SC2INT(ifsval()[0]) : ' ';
5908 if (quotes && (SIT(sep, syntax) == CCTL || SIT(sep, syntax) == CBACK))
5914 while ((p = *ap++)) {
5917 partlen = strlen(p);
5920 if (!(subtype == VSPLUS || subtype == VSLENGTH))
5921 memtodest(p, partlen, syntax, quotes);
5927 if (subtype == VSPLUS || subtype == VSLENGTH) {
5949 if (num < 0 || num > shellparam.nparam)
5951 p = num ? shellparam.p[num - 1] : arg0;
5954 p = lookupvar(name);
5960 if (!(subtype == VSPLUS || subtype == VSLENGTH))
5961 memtodest(p, len, syntax, quotes);
5965 if (subtype == VSPLUS || subtype == VSLENGTH)
5966 STADJUST(-len, expdest);
5972 * Record the fact that we have to scan this region of the
5973 * string for IFS characters.
5976 recordregion(int start, int end, int nulonly)
5978 struct ifsregion *ifsp;
5980 if (ifslastp == NULL) {
5984 ifsp = ckmalloc(sizeof(*ifsp));
5986 ifslastp->next = ifsp;
5990 ifslastp->begoff = start;
5991 ifslastp->endoff = end;
5992 ifslastp->nulonly = nulonly;
5997 * Break the argument string into pieces based upon IFS and add the
5998 * strings to the argument list. The regions of the string to be
5999 * searched for IFS characters have been stored by recordregion.
6002 ifsbreakup(char *string, struct arglist *arglist)
6004 struct ifsregion *ifsp;
6009 const char *ifs, *realifs;
6014 if (ifslastp != NULL) {
6017 realifs = ifsset() ? ifsval() : defifs;
6020 p = string + ifsp->begoff;
6021 nulonly = ifsp->nulonly;
6022 ifs = nulonly ? nullstr : realifs;
6024 while (p < string + ifsp->endoff) {
6028 if (strchr(ifs, *p)) {
6030 ifsspc = (strchr(defifs, *p) != NULL);
6031 /* Ignore IFS whitespace at start */
6032 if (q == start && ifsspc) {
6038 sp = stalloc(sizeof(*sp));
6040 *arglist->lastp = sp;
6041 arglist->lastp = &sp->next;
6045 if (p >= string + ifsp->endoff) {
6051 if (strchr(ifs, *p) == NULL ) {
6054 } else if (strchr(defifs, *p) == NULL) {
6070 } while ((ifsp = ifsp->next) != NULL);
6079 sp = stalloc(sizeof(*sp));
6081 *arglist->lastp = sp;
6082 arglist->lastp = &sp->next;
6088 struct ifsregion *p;
6093 struct ifsregion *ifsp;
6099 ifsfirst.next = NULL;
6103 static void expmeta(char *, char *);
6104 static struct strlist *expsort(struct strlist *);
6105 static struct strlist *msort(struct strlist *, int);
6107 static char *expdir;
6111 expandmeta(struct strlist *str, int flag)
6113 static const char metachars[] = {
6116 /* TODO - EXP_REDIR */
6119 struct strlist **savelastp;
6125 if (!strpbrk(str->text, metachars))
6127 savelastp = exparg.lastp;
6130 p = preglob(str->text, 0, RMESCAPE_ALLOC | RMESCAPE_HEAP);
6132 int i = strlen(str->text);
6133 expdir = ckmalloc(i < 2048 ? 2048 : i); /* XXX */
6141 if (exparg.lastp == savelastp) {
6146 *exparg.lastp = str;
6147 rmescapes(str->text);
6148 exparg.lastp = &str->next;
6150 *exparg.lastp = NULL;
6151 *savelastp = sp = expsort(*savelastp);
6152 while (sp->next != NULL)
6154 exparg.lastp = &sp->next;
6162 * Add a file name to the list.
6165 addfname(const char *name)
6169 sp = stalloc(sizeof(*sp));
6170 sp->text = ststrdup(name);
6172 exparg.lastp = &sp->next;
6177 * Do metacharacter (i.e. *, ?, [...]) expansion.
6180 expmeta(char *enddir, char *name)
6195 for (p = name; *p; p++) {
6196 if (*p == '*' || *p == '?')
6198 else if (*p == '[') {
6205 if (*q == '/' || *q == '\0')
6212 } else if (*p == '\\')
6214 else if (*p == '/') {
6221 if (metaflag == 0) { /* we've reached the end of the file name */
6222 if (enddir != expdir)
6230 if (metaflag == 0 || lstat(expdir, &statb) >= 0)
6241 } while (p < start);
6243 if (enddir == expdir) {
6245 } else if (enddir == expdir + 1 && *expdir == '/') {
6254 if (enddir != expdir)
6256 if (*endname == 0) {
6268 while (! intpending && (dp = readdir(dirp)) != NULL) {
6269 if (dp->d_name[0] == '.' && ! matchdot)
6271 if (pmatch(start, dp->d_name)) {
6273 scopy(dp->d_name, enddir);
6276 for (p = enddir, cp = dp->d_name; (*p++ = *cp++) != '\0';)
6279 expmeta(p, endname);
6290 * Sort the results of file name expansion. It calculates the number of
6291 * strings to sort and then calls msort (short for merge sort) to do the
6294 static struct strlist *
6295 expsort(struct strlist *str)
6301 for (sp = str; sp; sp = sp->next)
6303 return msort(str, len);
6307 static struct strlist *
6308 msort(struct strlist *list, int len)
6310 struct strlist *p, *q = NULL;
6311 struct strlist **lpp;
6319 for (n = half; --n >= 0; ) {
6323 q->next = NULL; /* terminate first half of list */
6324 q = msort(list, half); /* sort first half of list */
6325 p = msort(p, len - half); /* sort second half */
6328 #if ENABLE_LOCALE_SUPPORT
6329 if (strcoll(p->text, q->text) < 0)
6331 if (strcmp(p->text, q->text) < 0)
6356 * Returns true if the pattern matches the string.
6358 static int patmatch(char *pattern, const char *string)
6360 return pmatch(preglob(pattern, 0, 0), string);
6365 * Remove any CTLESC characters from a string.
6368 _rmescapes(char *str, int flag)
6371 static const char qchars[] = { CTLESC, CTLQUOTEMARK, 0 };
6376 p = strpbrk(str, qchars);
6382 if (flag & RMESCAPE_ALLOC) {
6383 size_t len = p - str;
6384 size_t fulllen = len + strlen(p) + 1;
6386 if (flag & RMESCAPE_GROW) {
6387 r = makestrspace(fulllen, expdest);
6388 } else if (flag & RMESCAPE_HEAP) {
6389 r = ckmalloc(fulllen);
6391 r = stalloc(fulllen);
6395 q = memcpy(q, str, len) + len;
6398 inquotes = (flag & RMESCAPE_QUOTED) ^ RMESCAPE_QUOTED;
6399 globbing = flag & RMESCAPE_GLOB;
6400 notescaped = globbing;
6402 if (*p == CTLQUOTEMARK) {
6403 inquotes = ~inquotes;
6405 notescaped = globbing;
6409 /* naked back slash */
6415 if (notescaped && inquotes && *p != '/') {
6419 notescaped = globbing;
6424 if (flag & RMESCAPE_GROW) {
6426 STADJUST(q - r + 1, expdest);
6433 * See if a pattern matches in a case statement.
6436 casematch(union node *pattern, char *val)
6438 struct stackmark smark;
6441 setstackmark(&smark);
6442 argbackq = pattern->narg.backquote;
6443 STARTSTACKSTR(expdest);
6445 argstr(pattern->narg.text, EXP_TILDE | EXP_CASE);
6446 STACKSTRNUL(expdest);
6447 result = patmatch(stackblock(), val);
6448 popstackmark(&smark);
6461 expdest = makestrspace(32, expdest);
6462 #if ENABLE_ASH_MATH_SUPPORT_64
6463 len = fmtstr(expdest, 32, "%lld", (long long) num);
6465 len = fmtstr(expdest, 32, "%ld", num);
6467 STADJUST(len, expdest);
6471 static void varunset(const char *, const char *, const char *, int) ATTRIBUTE_NORETURN;
6473 varunset(const char *end, const char *var, const char *umsg, int varflags)
6479 msg = "parameter not set";
6481 if (*end == CTLENDVAR) {
6482 if (varflags & VSNUL)
6487 ash_msg_and_raise_error("%.*s: %s%s", end - var - 1, var, msg, tail);
6494 * This implements the input routines used by the parser.
6497 #define EOF_NLEFT -99 /* value of parsenleft when EOF pushed back */
6499 static void pushfile(void);
6502 * Read a character from the script, returning PEOF on end of file.
6503 * Nul characters in the input are silently discarded.
6505 static int preadbuffer(void);
6506 #define pgetc_as_macro() (--parsenleft >= 0? SC2INT(*parsenextc++) : preadbuffer())
6508 #if ENABLE_ASH_OPTIMIZE_FOR_SIZE
6509 #define pgetc_macro() pgetc()
6513 return pgetc_as_macro();
6516 #define pgetc_macro() pgetc_as_macro()
6520 return pgetc_macro();
6525 * Same as pgetc(), but ignores PEOA.
6527 #if ENABLE_ASH_ALIAS
6535 } while (c == PEOA);
6542 return pgetc_macro();
6547 * Read a line from the script.
6550 pfgets(char *line, int len)
6556 while (--nleft > 0) {
6571 #if ENABLE_FEATURE_EDITING_VI
6572 #define setvimode(on) do { \
6573 if (on) line_input_state->flags |= VI_MODE; \
6574 else line_input_state->flags &= ~VI_MODE; \
6577 #define setvimode(on) viflag = 0 /* forcibly keep the option off */
6584 char *buf = parsefile->buf;
6588 #if ENABLE_FEATURE_EDITING
6589 if (!iflag || parsefile->fd)
6590 nr = safe_read(parsefile->fd, buf, BUFSIZ - 1);
6592 #if ENABLE_FEATURE_TAB_COMPLETION
6593 line_input_state->path_lookup = pathval();
6595 nr = read_line_input(cmdedit_prompt, buf, BUFSIZ, line_input_state);
6597 /* Ctrl+C pressed */
6606 if (nr < 0 && errno == 0) {
6607 /* Ctrl+D presend */
6612 nr = safe_read(parsefile->fd, buf, BUFSIZ - 1);
6616 if (parsefile->fd == 0 && errno == EWOULDBLOCK) {
6617 int flags = fcntl(0, F_GETFL, 0);
6618 if (flags >= 0 && flags & O_NONBLOCK) {
6619 flags &=~ O_NONBLOCK;
6620 if (fcntl(0, F_SETFL, flags) >= 0) {
6621 out2str("sh: turning off NDELAY mode\n");
6631 * Refill the input buffer and return the next input character:
6633 * 1) If a string was pushed back on the input, pop it;
6634 * 2) If an EOF was pushed back (parsenleft == EOF_NLEFT) or we are reading
6635 * from a string so we can't refill the buffer, return EOF.
6636 * 3) If the is more stuff in this buffer, use it else call read to fill it.
6637 * 4) Process input up to the next newline, deleting nul characters.
6646 while (parsefile->strpush) {
6647 #if ENABLE_ASH_ALIAS
6648 if (parsenleft == -1 && parsefile->strpush->ap &&
6649 parsenextc[-1] != ' ' && parsenextc[-1] != '\t') {
6654 if (--parsenleft >= 0)
6655 return SC2INT(*parsenextc++);
6657 if (parsenleft == EOF_NLEFT || parsefile->buf == NULL)
6659 flush_stdout_stderr();
6666 parselleft = parsenleft = EOF_NLEFT;
6673 /* delete nul characters */
6681 memmove(q, q + 1, more);
6685 parsenleft = q - parsenextc - 1;
6691 parsenleft = q - parsenextc - 1;
6703 out2str(parsenextc);
6708 return SC2INT(*parsenextc++);
6712 * Undo the last call to pgetc. Only one character may be pushed back.
6713 * PEOF may be pushed back.
6723 * Push a string back onto the input at this current parsefile level.
6724 * We handle aliases this way.
6727 pushstring(char *s, void *ap)
6734 /*dprintf("*** calling pushstring: %s, %d\n", s, len);*/
6735 if (parsefile->strpush) {
6736 sp = ckmalloc(sizeof(struct strpush));
6737 sp->prev = parsefile->strpush;
6738 parsefile->strpush = sp;
6740 sp = parsefile->strpush = &(parsefile->basestrpush);
6741 sp->prevstring = parsenextc;
6742 sp->prevnleft = parsenleft;
6743 #if ENABLE_ASH_ALIAS
6744 sp->ap = (struct alias *)ap;
6746 ((struct alias *)ap)->flag |= ALIASINUSE;
6758 struct strpush *sp = parsefile->strpush;
6761 #if ENABLE_ASH_ALIAS
6763 if (parsenextc[-1] == ' ' || parsenextc[-1] == '\t') {
6764 checkkwd |= CHKALIAS;
6766 if (sp->string != sp->ap->val) {
6769 sp->ap->flag &= ~ALIASINUSE;
6770 if (sp->ap->flag & ALIASDEAD) {
6771 unalias(sp->ap->name);
6775 parsenextc = sp->prevstring;
6776 parsenleft = sp->prevnleft;
6777 /*dprintf("*** calling popstring: restoring to '%s'\n", parsenextc);*/
6778 parsefile->strpush = sp->prev;
6779 if (sp != &(parsefile->basestrpush))
6786 * Set the input to take input from a file. If push is set, push the
6787 * old input onto the stack first.
6790 setinputfile(const char *fname, int flags)
6796 fd = open(fname, O_RDONLY);
6798 if (flags & INPUT_NOFILE_OK)
6800 ash_msg_and_raise_error("Can't open %s", fname);
6803 fd2 = copyfd(fd, 10);
6806 ash_msg_and_raise_error("Out of file descriptors");
6809 setinputfd(fd, flags & INPUT_PUSH_FILE);
6817 * Like setinputfile, but takes an open file descriptor. Call this with
6821 setinputfd(int fd, int push)
6823 (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
6829 if (parsefile->buf == NULL)
6830 parsefile->buf = ckmalloc(IBUFSIZ);
6831 parselleft = parsenleft = 0;
6837 * Like setinputfile, but takes input from a string.
6840 setinputstring(char *string)
6844 parsenextc = string;
6845 parsenleft = strlen(string);
6846 parsefile->buf = NULL;
6853 * To handle the "." command, a stack of input files is used. Pushfile
6854 * adds a new entry to the stack and popfile restores the previous level.
6859 struct parsefile *pf;
6861 parsefile->nleft = parsenleft;
6862 parsefile->lleft = parselleft;
6863 parsefile->nextc = parsenextc;
6864 parsefile->linno = plinno;
6865 pf = ckmalloc(sizeof(*pf));
6866 pf->prev = parsefile;
6869 pf->basestrpush.prev = NULL;
6877 struct parsefile *pf = parsefile;
6886 parsefile = pf->prev;
6888 parsenleft = parsefile->nleft;
6889 parselleft = parsefile->lleft;
6890 parsenextc = parsefile->nextc;
6891 plinno = parsefile->linno;
6897 * Return to top level.
6902 while (parsefile != &basepf)
6908 * Close the file(s) that the shell is reading commands from. Called
6909 * after a fork is done.
6915 if (parsefile->fd > 0) {
6916 close(parsefile->fd);
6923 /* mode flags for set_curjob */
6924 #define CUR_DELETE 2
6925 #define CUR_RUNNING 1
6926 #define CUR_STOPPED 0
6928 /* mode flags for dowait */
6929 #define DOWAIT_NORMAL 0
6930 #define DOWAIT_BLOCK 1
6933 static struct job *jobtab;
6935 static unsigned njobs;
6937 /* pgrp of shell on invocation */
6938 static int initialpgrp;
6939 static int ttyfd = -1;
6942 static struct job *curjob;
6943 /* number of presumed living untracked jobs */
6946 static void set_curjob(struct job *, unsigned);
6948 static int restartjob(struct job *, int);
6949 static void xtcsetpgrp(int, pid_t);
6950 static char *commandtext(union node *);
6951 static void cmdlist(union node *, int);
6952 static void cmdtxt(union node *);
6953 static void cmdputs(const char *);
6954 static void showpipe(struct job *, FILE *);
6956 static int sprint_status(char *, int, int);
6957 static void freejob(struct job *);
6958 static struct job *getjob(const char *, int);
6959 static struct job *growjobtab(void);
6960 static void forkchild(struct job *, union node *, int);
6961 static void forkparent(struct job *, union node *, int, pid_t);
6962 static int dowait(int, struct job *);
6963 static int getstatus(struct job *);
6966 set_curjob(struct job *jp, unsigned mode)
6969 struct job **jpp, **curp;
6971 /* first remove from list */
6972 jpp = curp = &curjob;
6977 jpp = &jp1->prev_job;
6979 *jpp = jp1->prev_job;
6981 /* Then re-insert in correct position */
6989 /* job being deleted */
6992 /* newly created job or backgrounded job,
6993 put after all stopped jobs. */
6997 if (!jp1 || jp1->state != JOBSTOPPED)
7000 jpp = &jp1->prev_job;
7006 /* newly stopped job - becomes curjob */
7007 jp->prev_job = *jpp;
7015 * Turn job control on and off.
7017 * Note: This code assumes that the third arg to ioctl is a character
7018 * pointer, which is true on Berkeley systems but not System V. Since
7019 * System V doesn't have job control yet, this isn't a problem now.
7021 * Called with interrupts off.
7029 if (on == jobctl || rootshell == 0)
7033 ofd = fd = open(_PATH_TTY, O_RDWR);
7035 /* BTW, bash will try to open(ttyname(0)) if open("/dev/tty") fails.
7036 * That sometimes helps to acquire controlling tty.
7037 * Obviously, a workaround for bugs when someone
7038 * failed to provide a controlling tty to bash! :) */
7040 while (!isatty(fd) && --fd >= 0)
7043 fd = fcntl(fd, F_DUPFD, 10);
7047 fcntl(fd, F_SETFD, FD_CLOEXEC);
7048 do { /* while we are in the background */
7049 pgrp = tcgetpgrp(fd);
7052 ash_msg("can't access tty; job control turned off");
7056 if (pgrp == getpgrp())
7067 xtcsetpgrp(fd, pgrp);
7069 /* turning job control off */
7072 xtcsetpgrp(fd, pgrp);
7086 killcmd(int argc, char **argv)
7096 ash_msg_and_raise_error(
7097 "Usage: kill [-s sigspec | -signum | -sigspec] [pid | job]... or\n"
7098 "kill -l [exitstatus]"
7102 if (**++argv == '-') {
7103 signo = get_signum(*argv + 1);
7107 while ((c = nextopt("ls:")) != '\0')
7117 signo = get_signum(optionarg);
7119 ash_msg_and_raise_error(
7120 "invalid signal number or name: %s",
7131 if (!list && signo < 0)
7134 if ((signo < 0 || !*argv) ^ list) {
7142 for (i = 1; i < NSIG; i++) {
7143 name = get_signame(i);
7145 out1fmt(snlfmt, name);
7149 name = get_signame(signo);
7150 if (!isdigit(*name))
7151 ash_msg_and_raise_error("invalid signal number or exit status: %s", *argptr);
7152 out1fmt(snlfmt, name);
7158 if (**argv == '%') {
7159 jp = getjob(*argv, 0);
7160 pid = -jp->ps[0].pid;
7162 pid = **argv == '-' ?
7163 -number(*argv + 1) : number(*argv);
7165 if (kill(pid, signo) != 0) {
7166 ash_msg("(%d) - %m", pid);
7177 jobno(const struct job *jp)
7179 return jp - jobtab + 1;
7185 fgcmd(int argc, char **argv)
7192 mode = (**argv == 'f') ? FORK_FG : FORK_BG;
7197 jp = getjob(*argv, 1);
7198 if (mode == FORK_BG) {
7199 set_curjob(jp, CUR_RUNNING);
7200 fprintf(out, "[%d] ", jobno(jp));
7202 outstr(jp->ps->cmd, out);
7204 retval = restartjob(jp, mode);
7205 } while (*argv && *++argv);
7209 static int bgcmd(int, char **) __attribute__((__alias__("fgcmd")));
7213 restartjob(struct job *jp, int mode)
7215 struct procstat *ps;
7221 if (jp->state == JOBDONE)
7223 jp->state = JOBRUNNING;
7225 if (mode == FORK_FG)
7226 xtcsetpgrp(ttyfd, pgid);
7227 killpg(pgid, SIGCONT);
7231 if (WIFSTOPPED(ps->status)) {
7234 } while (ps++, --i);
7236 status = (mode == FORK_FG) ? waitforjob(jp) : 0;
7243 sprint_status(char *s, int status, int sigonly)
7249 if (!WIFEXITED(status)) {
7251 if (WIFSTOPPED(status))
7252 st = WSTOPSIG(status);
7255 st = WTERMSIG(status);
7257 if (st == SIGINT || st == SIGPIPE)
7260 if (WIFSTOPPED(status))
7265 col = fmtstr(s, 32, strsignal(st));
7266 if (WCOREDUMP(status)) {
7267 col += fmtstr(s + col, 16, " (core dumped)");
7269 } else if (!sigonly) {
7270 st = WEXITSTATUS(status);
7272 col = fmtstr(s, 16, "Done(%d)", st);
7274 col = fmtstr(s, 16, "Done");
7282 showjob(FILE *out, struct job *jp, int mode)
7284 struct procstat *ps;
7285 struct procstat *psend;
7292 if (mode & SHOW_PGID) {
7293 /* just output process (group) id of pipeline */
7294 fprintf(out, "%d\n", ps->pid);
7298 col = fmtstr(s, 16, "[%d] ", jobno(jp));
7303 else if (curjob && jp == curjob->prev_job)
7306 if (mode & SHOW_PID)
7307 col += fmtstr(s + col, 16, "%d ", ps->pid);
7309 psend = ps + jp->nprocs;
7311 if (jp->state == JOBRUNNING) {
7312 scopy("Running", s + col);
7313 col += strlen("Running");
7315 int status = psend[-1].status;
7317 if (jp->state == JOBSTOPPED)
7318 status = jp->stopstatus;
7320 col += sprint_status(s + col, status, 0);
7326 /* for each process */
7327 col = fmtstr(s, 48, " |\n%*c%d ", indent, ' ', ps->pid) - 3;
7329 fprintf(out, "%s%*c%s",
7330 s, 33 - col >= 0 ? 33 - col : 0, ' ', ps->cmd
7332 if (!(mode & SHOW_PID)) {
7336 if (++ps == psend) {
7337 outcslow('\n', out);
7344 if (jp->state == JOBDONE) {
7345 TRACE(("showjob: freeing job %d\n", jobno(jp)));
7352 jobscmd(int argc, char **argv)
7358 while ((m = nextopt("lp")))
7368 showjob(out, getjob(*argv,0), mode);
7371 showjobs(out, mode);
7378 * Print a list of jobs. If "change" is nonzero, only print jobs whose
7379 * statuses have changed since the last call to showjobs.
7382 showjobs(FILE *out, int mode)
7386 TRACE(("showjobs(%x) called\n", mode));
7388 /* If not even one one job changed, there is nothing to do */
7389 while (dowait(DOWAIT_NORMAL, NULL) > 0)
7392 for (jp = curjob; jp; jp = jp->prev_job) {
7393 if (!(mode & SHOW_CHANGED) || jp->changed)
7394 showjob(out, jp, mode);
7401 * Mark a job structure as unused.
7404 freejob(struct job *jp)
7406 struct procstat *ps;
7410 for (i = jp->nprocs, ps = jp->ps; --i >= 0; ps++) {
7411 if (ps->cmd != nullstr)
7414 if (jp->ps != &jp->ps0)
7417 set_curjob(jp, CUR_DELETE);
7423 waitcmd(int argc, char **argv)
7436 /* wait for all jobs */
7441 /* no running procs */
7444 if (jp->state == JOBRUNNING)
7449 dowait(DOWAIT_BLOCK, 0);
7455 if (**argv != '%') {
7456 pid_t pid = number(*argv);
7460 if (job->ps[job->nprocs - 1].pid == pid)
7462 job = job->prev_job;
7468 job = getjob(*argv, 0);
7469 /* loop until process terminated or stopped */
7470 while (job->state == JOBRUNNING)
7471 dowait(DOWAIT_BLOCK, 0);
7473 retval = getstatus(job);
7484 * Convert a job name to a job structure.
7487 getjob(const char *name, int getctl)
7491 const char *err_msg = "No such job: %s";
7495 char *(*match)(const char *, const char *);
7510 if (c == '+' || c == '%') {
7512 err_msg = "No current job";
7514 } else if (c == '-') {
7517 err_msg = "No previous job";
7528 jp = jobtab + num - 1;
7545 if (match(jp->ps[0].cmd, p)) {
7549 err_msg = "%s: ambiguous";
7556 err_msg = "job %s not created under job control";
7557 if (getctl && jp->jobctl == 0)
7562 ash_msg_and_raise_error(err_msg, name);
7567 * Return a new job structure.
7568 * Called with interrupts off.
7572 makejob(union node *node, int nprocs)
7577 for (i = njobs, jp = jobtab; ; jp++) {
7584 if (jp->state != JOBDONE || !jp->waited)
7593 memset(jp, 0, sizeof(*jp));
7598 jp->prev_job = curjob;
7603 jp->ps = ckmalloc(nprocs * sizeof(struct procstat));
7605 TRACE(("makejob(0x%lx, %d) returns %%%d\n", (long)node, nprocs,
7615 struct job *jp, *jq;
7617 len = njobs * sizeof(*jp);
7619 jp = ckrealloc(jq, len + 4 * sizeof(*jp));
7621 offset = (char *)jp - (char *)jq;
7623 /* Relocate pointers */
7626 jq = (struct job *)((char *)jq + l);
7630 #define joff(p) ((struct job *)((char *)(p) + l))
7631 #define jmove(p) (p) = (void *)((char *)(p) + offset)
7632 if (xlikely(joff(jp)->ps == &jq->ps0))
7633 jmove(joff(jp)->ps);
7634 if (joff(jp)->prev_job)
7635 jmove(joff(jp)->prev_job);
7645 jp = (struct job *)((char *)jp + len);
7649 } while (--jq >= jp);
7655 * Fork off a subshell. If we are doing job control, give the subshell its
7656 * own process group. Jp is a job structure that the job is to be added to.
7657 * N is the command that will be evaluated by the child. Both jp and n may
7658 * be NULL. The mode parameter can be one of the following:
7659 * FORK_FG - Fork off a foreground process.
7660 * FORK_BG - Fork off a background process.
7661 * FORK_NOJOB - Like FORK_FG, but don't give the process its own
7662 * process group even if job control is on.
7664 * When job control is turned off, background processes have their standard
7665 * input redirected to /dev/null (except for the second and later processes
7668 * Called with interrupts off.
7670 static void forkchild(struct job *jp, union node *n, int mode)
7674 TRACE(("Child shell %d\n", getpid()));
7681 /* do job control only in root shell */
7683 if (mode != FORK_NOJOB && jp->jobctl && !oldlvl) {
7686 if (jp->nprocs == 0)
7689 pgrp = jp->ps[0].pid;
7690 /* This can fail because we are doing it in the parent also */
7691 (void)setpgid(0, pgrp);
7692 if (mode == FORK_FG)
7693 xtcsetpgrp(ttyfd, pgrp);
7698 if (mode == FORK_BG) {
7701 if (jp->nprocs == 0) {
7703 if (open(bb_dev_null, O_RDONLY) != 0)
7704 ash_msg_and_raise_error("Can't open %s", bb_dev_null);
7707 if (!oldlvl && iflag) {
7712 for (jp = curjob; jp; jp = jp->prev_job)
7717 static void forkparent(struct job *jp, union node *n, int mode, pid_t pid)
7719 TRACE(("In parent shell: child = %d\n", pid));
7721 while (jobless && dowait(DOWAIT_NORMAL, 0) > 0);
7726 if (mode != FORK_NOJOB && jp->jobctl) {
7729 if (jp->nprocs == 0)
7732 pgrp = jp->ps[0].pid;
7733 /* This can fail because we are doing it in the child also */
7734 (void)setpgid(pid, pgrp);
7737 if (mode == FORK_BG) {
7738 backgndpid = pid; /* set $! */
7739 set_curjob(jp, CUR_RUNNING);
7742 struct procstat *ps = &jp->ps[jp->nprocs++];
7748 ps->cmd = commandtext(n);
7754 forkshell(struct job *jp, union node *n, int mode)
7758 TRACE(("forkshell(%%%d, %p, %d) called\n", jobno(jp), n, mode));
7761 TRACE(("Fork failed, errno=%d", errno));
7764 ash_msg_and_raise_error("Cannot fork");
7767 forkchild(jp, n, mode);
7769 forkparent(jp, n, mode, pid);
7775 * Wait for job to finish.
7777 * Under job control we have the problem that while a child process is
7778 * running interrupts generated by the user are sent to the child but not
7779 * to the shell. This means that an infinite loop started by an inter-
7780 * active user may be hard to kill. With job control turned off, an
7781 * interactive user may place an interactive program inside a loop. If
7782 * the interactive program catches interrupts, the user doesn't want
7783 * these interrupts to also abort the loop. The approach we take here
7784 * is to have the shell ignore interrupt signals while waiting for a
7785 * foreground process to terminate, and then send itself an interrupt
7786 * signal if the child process was terminated by an interrupt signal.
7787 * Unfortunately, some programs want to do a bit of cleanup and then
7788 * exit on interrupt; unless these processes terminate themselves by
7789 * sending a signal to themselves (instead of calling exit) they will
7790 * confuse this approach.
7792 * Called with interrupts off.
7795 waitforjob(struct job *jp)
7799 TRACE(("waitforjob(%%%d) called\n", jobno(jp)));
7800 while (jp->state == JOBRUNNING) {
7801 dowait(DOWAIT_BLOCK, jp);
7806 xtcsetpgrp(ttyfd, rootpid);
7808 * This is truly gross.
7809 * If we're doing job control, then we did a TIOCSPGRP which
7810 * caused us (the shell) to no longer be in the controlling
7811 * session -- so we wouldn't have seen any ^C/SIGINT. So, we
7812 * intuit from the subprocess exit status whether a SIGINT
7813 * occurred, and if so interrupt ourselves. Yuck. - mycroft
7818 if (jp->state == JOBDONE)
7826 * Do a wait system call. If job control is compiled in, we accept
7827 * stopped processes. If block is zero, we return a value of zero
7828 * rather than blocking.
7830 * System V doesn't have a non-blocking wait system call. It does
7831 * have a SIGCLD signal that is sent to a process when one of it's
7832 * children dies. The obvious way to use SIGCLD would be to install
7833 * a handler for SIGCLD which simply bumped a counter when a SIGCLD
7834 * was received, and have waitproc bump another counter when it got
7835 * the status of a process. Waitproc would then know that a wait
7836 * system call would not block if the two counters were different.
7837 * This approach doesn't work because if a process has children that
7838 * have not been waited for, System V will send it a SIGCLD when it
7839 * installs a signal handler for SIGCLD. What this means is that when
7840 * a child exits, the shell will be sent SIGCLD signals continuously
7841 * until is runs out of stack space, unless it does a wait call before
7842 * restoring the signal handler. The code below takes advantage of
7843 * this (mis)feature by installing a signal handler for SIGCLD and
7844 * then checking to see whether it was called. If there are any
7845 * children to be waited for, it will be.
7847 * If neither SYSV nor BSD is defined, we don't implement nonblocking
7848 * waits at all. In this case, the user will not be informed when
7849 * a background process until the next time she runs a real program
7850 * (as opposed to running a builtin command or just typing return),
7851 * and the jobs command may give out of date information.
7853 static int waitproc(int block, int *status)
7863 return wait3(status, flags, (struct rusage *)NULL);
7868 * Wait for a process to terminate.
7871 dowait(int block, struct job *job)
7876 struct job *thisjob;
7879 TRACE(("dowait(%d) called\n", block));
7880 pid = waitproc(block, &status);
7881 TRACE(("wait returns pid %d, status=%d\n", pid, status));
7886 for (jp = curjob; jp; jp = jp->prev_job) {
7887 struct procstat *sp;
7888 struct procstat *spend;
7889 if (jp->state == JOBDONE)
7892 spend = jp->ps + jp->nprocs;
7895 if (sp->pid == pid) {
7896 TRACE(("Job %d: changing status of proc %d "
7897 "from 0x%x to 0x%x\n",
7898 jobno(jp), pid, sp->status, status));
7899 sp->status = status;
7902 if (sp->status == -1)
7905 if (state == JOBRUNNING)
7907 if (WIFSTOPPED(sp->status)) {
7908 jp->stopstatus = sp->status;
7912 } while (++sp < spend);
7917 if (!WIFSTOPPED(status))
7924 if (state != JOBRUNNING) {
7925 thisjob->changed = 1;
7927 if (thisjob->state != state) {
7928 TRACE(("Job %d: changing state from %d to %d\n",
7929 jobno(thisjob), thisjob->state, state));
7930 thisjob->state = state;
7932 if (state == JOBSTOPPED) {
7933 set_curjob(thisjob, CUR_STOPPED);
7942 if (thisjob && thisjob == job) {
7946 len = sprint_status(s, status, 1);
7958 * return 1 if there are stopped jobs, otherwise 0
7970 if (jp && jp->state == JOBSTOPPED) {
7971 out2str("You have stopped jobs.\n");
7981 * Return a string identifying a command (to be printed by the
7985 static char *cmdnextc;
7988 commandtext(union node *n)
7992 STARTSTACKSTR(cmdnextc);
7994 name = stackblock();
7995 TRACE(("commandtext: name %p, end %p\n\t\"%s\"\n",
7996 name, cmdnextc, cmdnextc));
7997 return ckstrdup(name);
8001 cmdtxt(union node *n)
8004 struct nodelist *lp;
8016 lp = n->npipe.cmdlist;
8034 cmdtxt(n->nbinary.ch1);
8050 cmdtxt(n->nif.test);
8053 if (n->nif.elsepart) {
8056 n = n->nif.elsepart;
8072 cmdtxt(n->nbinary.ch1);
8082 cmdputs(n->nfor.var);
8084 cmdlist(n->nfor.args, 1);
8089 cmdputs(n->narg.text);
8093 cmdlist(n->ncmd.args, 1);
8094 cmdlist(n->ncmd.redirect, 0);
8107 cmdputs(n->ncase.expr->narg.text);
8109 for (np = n->ncase.cases; np; np = np->nclist.next) {
8110 cmdtxt(np->nclist.pattern);
8112 cmdtxt(np->nclist.body);
8138 s[0] = n->nfile.fd + '0';
8142 if (n->type == NTOFD || n->type == NFROMFD) {
8143 s[0] = n->ndup.dupfd + '0';
8154 cmdlist(union node *np, int sep)
8156 for (; np; np = np->narg.next) {
8160 if (sep && np->narg.next)
8166 cmdputs(const char *s)
8168 const char *p, *str;
8169 char c, cc[2] = " ";
8173 static const char vstype[VSTYPE + 1][4] = {
8174 "", "}", "-", "+", "?", "=",
8175 "%", "%%", "#", "##"
8177 nextc = makestrspace((strlen(s) + 1) * 8, cmdnextc);
8179 while ((c = *p++) != 0) {
8187 if ((subtype & VSTYPE) == VSLENGTH)
8191 if (!(subtype & VSQUOTE) != !(quoted & 1)) {
8198 str = "\"}" + !(quoted & 1);
8205 case CTLBACKQ+CTLQUOTE:
8208 #if ENABLE_ASH_MATH_SUPPORT
8223 if ((subtype & VSTYPE) != VSNORMAL)
8225 str = vstype[subtype & VSTYPE];
8226 if (subtype & VSNUL)
8235 /* These can only happen inside quotes */
8248 while ((c = *str++)) {
8253 USTPUTC('"', nextc);
8261 showpipe(struct job *jp, FILE *out)
8263 struct procstat *sp;
8264 struct procstat *spend;
8266 spend = jp->ps + jp->nprocs;
8267 for (sp = jp->ps + 1; sp < spend; sp++)
8268 fprintf(out, " | %s", sp->cmd);
8269 outcslow('\n', out);
8270 flush_stdout_stderr();
8274 xtcsetpgrp(int fd, pid_t pgrp)
8276 if (tcsetpgrp(fd, pgrp))
8277 ash_msg_and_raise_error("Cannot set tty process group (%m)");
8282 getstatus(struct job *job)
8287 status = job->ps[job->nprocs - 1].status;
8288 retval = WEXITSTATUS(status);
8289 if (!WIFEXITED(status)) {
8291 retval = WSTOPSIG(status);
8292 if (!WIFSTOPPED(status))
8295 /* XXX: limits number of signals */
8296 retval = WTERMSIG(status);
8298 if (retval == SIGINT)
8304 TRACE(("getstatus: job %d, nproc %d, status %x, retval %x\n",
8305 jobno(job), job->nprocs, status, retval));
8313 * Routines to check for mail. (Perhaps make part of main.c?)
8316 #define MAXMBOXES 10
8318 /* times of mailboxes */
8319 static time_t mailtime[MAXMBOXES];
8320 /* Set if MAIL or MAILPATH is changed. */
8321 static int mail_var_path_changed;
8325 * Print appropriate message(s) if mail has arrived.
8326 * If mail_var_path_changed is set,
8327 * then the value of MAIL has mail_var_path_changed,
8328 * so we just update the values.
8337 struct stackmark smark;
8340 setstackmark(&smark);
8341 mpath = mpathset() ? mpathval() : mailval();
8342 for (mtp = mailtime; mtp < mailtime + MAXMBOXES; mtp++) {
8343 p = padvance(&mpath, nullstr);
8348 for (q = p; *q; q++);
8353 q[-1] = '\0'; /* delete trailing '/' */
8354 if (stat(p, &statb) < 0) {
8358 if (!mail_var_path_changed && statb.st_mtime != *mtp) {
8361 pathopt ? pathopt : "you have mail"
8364 *mtp = statb.st_mtime;
8366 mail_var_path_changed = 0;
8367 popstackmark(&smark);
8372 changemail(const char *val)
8374 mail_var_path_changed++;
8377 #endif /* ASH_MAIL */
8380 * Take commands from a file. To be compatible we should do a path
8381 * search for the file, which is necessary to find sub-commands.
8384 find_dot_file(char *name)
8387 const char *path = pathval();
8390 /* don't try this for absolute or relative paths */
8391 if (strchr(name, '/'))
8394 while ((fullname = padvance(&path, name)) != NULL) {
8395 if ((stat(fullname, &statb) == 0) && S_ISREG(statb.st_mode)) {
8397 * Don't bother freeing here, since it will
8398 * be freed by the caller.
8402 stunalloc(fullname);
8405 /* not found in the PATH */
8406 ash_msg_and_raise_error("%s: not found", name);
8411 calcsize(union node *n)
8415 funcblocksize += nodesize[n->type];
8418 calcsize(n->ncmd.redirect);
8419 calcsize(n->ncmd.args);
8420 calcsize(n->ncmd.assign);
8423 sizenodelist(n->npipe.cmdlist);
8428 calcsize(n->nredir.redirect);
8429 calcsize(n->nredir.n);
8436 calcsize(n->nbinary.ch2);
8437 calcsize(n->nbinary.ch1);
8440 calcsize(n->nif.elsepart);
8441 calcsize(n->nif.ifpart);
8442 calcsize(n->nif.test);
8445 funcstringsize += strlen(n->nfor.var) + 1;
8446 calcsize(n->nfor.body);
8447 calcsize(n->nfor.args);
8450 calcsize(n->ncase.cases);
8451 calcsize(n->ncase.expr);
8454 calcsize(n->nclist.body);
8455 calcsize(n->nclist.pattern);
8456 calcsize(n->nclist.next);
8460 sizenodelist(n->narg.backquote);
8461 funcstringsize += strlen(n->narg.text) + 1;
8462 calcsize(n->narg.next);
8469 calcsize(n->nfile.fname);
8470 calcsize(n->nfile.next);
8474 calcsize(n->ndup.vname);
8475 calcsize(n->ndup.next);
8479 calcsize(n->nhere.doc);
8480 calcsize(n->nhere.next);
8483 calcsize(n->nnot.com);
8490 sizenodelist(struct nodelist *lp)
8493 funcblocksize += SHELL_ALIGN(sizeof(struct nodelist));
8501 copynode(union node *n)
8508 funcblock = (char *) funcblock + nodesize[n->type];
8512 new->ncmd.redirect = copynode(n->ncmd.redirect);
8513 new->ncmd.args = copynode(n->ncmd.args);
8514 new->ncmd.assign = copynode(n->ncmd.assign);
8517 new->npipe.cmdlist = copynodelist(n->npipe.cmdlist);
8518 new->npipe.backgnd = n->npipe.backgnd;
8523 new->nredir.redirect = copynode(n->nredir.redirect);
8524 new->nredir.n = copynode(n->nredir.n);
8531 new->nbinary.ch2 = copynode(n->nbinary.ch2);
8532 new->nbinary.ch1 = copynode(n->nbinary.ch1);
8535 new->nif.elsepart = copynode(n->nif.elsepart);
8536 new->nif.ifpart = copynode(n->nif.ifpart);
8537 new->nif.test = copynode(n->nif.test);
8540 new->nfor.var = nodeckstrdup(n->nfor.var);
8541 new->nfor.body = copynode(n->nfor.body);
8542 new->nfor.args = copynode(n->nfor.args);
8545 new->ncase.cases = copynode(n->ncase.cases);
8546 new->ncase.expr = copynode(n->ncase.expr);
8549 new->nclist.body = copynode(n->nclist.body);
8550 new->nclist.pattern = copynode(n->nclist.pattern);
8551 new->nclist.next = copynode(n->nclist.next);
8555 new->narg.backquote = copynodelist(n->narg.backquote);
8556 new->narg.text = nodeckstrdup(n->narg.text);
8557 new->narg.next = copynode(n->narg.next);
8564 new->nfile.fname = copynode(n->nfile.fname);
8565 new->nfile.fd = n->nfile.fd;
8566 new->nfile.next = copynode(n->nfile.next);
8570 new->ndup.vname = copynode(n->ndup.vname);
8571 new->ndup.dupfd = n->ndup.dupfd;
8572 new->ndup.fd = n->ndup.fd;
8573 new->ndup.next = copynode(n->ndup.next);
8577 new->nhere.doc = copynode(n->nhere.doc);
8578 new->nhere.fd = n->nhere.fd;
8579 new->nhere.next = copynode(n->nhere.next);
8582 new->nnot.com = copynode(n->nnot.com);
8585 new->type = n->type;
8590 static struct nodelist *
8591 copynodelist(struct nodelist *lp)
8593 struct nodelist *start;
8594 struct nodelist **lpp;
8599 funcblock = (char *) funcblock + SHELL_ALIGN(sizeof(struct nodelist));
8600 (*lpp)->n = copynode(lp->n);
8602 lpp = &(*lpp)->next;
8610 nodeckstrdup(char *s)
8612 char *rtn = funcstring;
8614 strcpy(funcstring, s);
8615 funcstring += strlen(s) + 1;
8621 * Free a parse tree.
8624 freefunc(struct funcnode *f)
8626 if (f && --f->count < 0)
8637 setinteractive(iflag);
8643 minus_o(char *name, int val)
8648 for (i = 0; i < NOPTS; i++) {
8649 if (equal(name, optnames(i))) {
8654 ash_msg_and_raise_error("Illegal option -o %s", name);
8656 out1str("Current option settings\n");
8657 for (i = 0; i < NOPTS; i++)
8658 out1fmt("%-16s%s\n", optnames(i),
8659 optlist[i] ? "on" : "off");
8664 setoption(int flag, int val)
8668 for (i = 0; i < NOPTS; i++) {
8669 if (optletters(i) == flag) {
8674 ash_msg_and_raise_error("Illegal option -%c", flag);
8680 * Process shell options. The global variable argptr contains a pointer
8681 * to the argument list; we advance it past the options.
8684 options(int cmdline)
8692 while ((p = *argptr) != NULL) {
8697 if (p[0] == '\0' || LONE_DASH(p)) {
8699 /* "-" means turn off -x and -v */
8702 /* "--" means reset params */
8703 else if (*argptr == NULL)
8706 break; /* "-" or "--" terminates options */
8708 } else if (c == '+') {
8714 while ((c = *p++) != '\0') {
8715 if (c == 'c' && cmdline) {
8716 minusc = p; /* command is after shell args*/
8717 } else if (c == 'o') {
8718 minus_o(*argptr, val);
8721 } else if (cmdline && (c == '-')) { // long options
8722 if (strcmp(p, "login") == 0)
8734 * Set the shell parameters.
8737 setparam(char **argv)
8743 for (nparam = 0; argv[nparam]; nparam++);
8744 ap = newparam = ckmalloc((nparam + 1) * sizeof(*ap));
8746 *ap++ = ckstrdup(*argv++);
8749 freeparam(&shellparam);
8750 shellparam.malloc = 1;
8751 shellparam.nparam = nparam;
8752 shellparam.p = newparam;
8753 #if ENABLE_ASH_GETOPTS
8754 shellparam.optind = 1;
8755 shellparam.optoff = -1;
8761 * Free the list of positional parameters.
8764 freeparam(volatile struct shparam *param)
8768 if (param->malloc) {
8769 for (ap = param->p; *ap; ap++)
8777 * The shift builtin command.
8780 shiftcmd(int argc, char **argv)
8787 n = number(argv[1]);
8788 if (n > shellparam.nparam)
8789 ash_msg_and_raise_error("can't shift that many");
8791 shellparam.nparam -= n;
8792 for (ap1 = shellparam.p; --n >= 0; ap1++) {
8793 if (shellparam.malloc)
8797 while ((*ap2++ = *ap1++) != NULL);
8798 #if ENABLE_ASH_GETOPTS
8799 shellparam.optind = 1;
8800 shellparam.optoff = -1;
8808 * POSIX requires that 'set' (but not export or readonly) output the
8809 * variables in lexicographic order - by the locale's collating order (sigh).
8810 * Maybe we could keep them in an ordered balanced binary tree
8811 * instead of hashed lists.
8812 * For now just roll 'em through qsort for printing...
8815 showvars(const char *sep_prefix, int on, int off)
8820 ep = listvars(on, off, &epend);
8821 qsort(ep, epend - ep, sizeof(char *), vpcmp);
8823 sep = *sep_prefix ? spcstr : sep_prefix;
8825 for (; ep < epend; ep++) {
8829 p = strchrnul(*ep, '=');
8832 q = single_quote(++p);
8833 out1fmt("%s%s%.*s%s\n", sep_prefix, sep, (int)(p - *ep), *ep, q);
8839 * The set command builtin.
8842 setcmd(int argc, char **argv)
8845 return showvars(nullstr, 0, VUNSET);
8849 if (*argptr != NULL) {
8857 #if ENABLE_LOCALE_SUPPORT
8858 static void change_lc_all(const char *value)
8860 if (value && *value != '\0')
8861 setlocale(LC_ALL, value);
8864 static void change_lc_ctype(const char *value)
8866 if (value && *value != '\0')
8867 setlocale(LC_CTYPE, value);
8871 #if ENABLE_ASH_RANDOM_SUPPORT
8872 /* Roughly copied from bash.. */
8873 static void change_random(const char *value)
8875 if (value == NULL) {
8876 /* "get", generate */
8879 rseed = rseed * 1103515245 + 12345;
8880 sprintf(buf, "%d", (unsigned int)((rseed & 32767)));
8881 /* set without recursion */
8882 setvar(vrandom.text, buf, VNOFUNC);
8883 vrandom.flags &= ~VNOFUNC;
8886 rseed = strtoul(value, (char **)NULL, 10);
8892 #if ENABLE_ASH_GETOPTS
8894 getopts(char *optstr, char *optvar, char **optfirst, int *param_optind, int *optoff)
8903 if (*param_optind < 1)
8905 optnext = optfirst + *param_optind - 1;
8907 if (*param_optind <= 1 || *optoff < 0 || strlen(optnext[-1]) < *optoff)
8910 p = optnext[-1] + *optoff;
8911 if (p == NULL || *p == '\0') {
8912 /* Current word is done, advance */
8914 if (p == NULL || *p != '-' || *++p == '\0') {
8921 if (LONE_DASH(p)) /* check for "--" */
8926 for (q = optstr; *q != c; ) {
8928 if (optstr[0] == ':') {
8931 err |= setvarsafe("OPTARG", s, 0);
8933 fprintf(stderr, "Illegal option -%c\n", c);
8944 if (*p == '\0' && (p = *optnext) == NULL) {
8945 if (optstr[0] == ':') {
8948 err |= setvarsafe("OPTARG", s, 0);
8951 fprintf(stderr, "No arg for -%c option\n", c);
8960 err |= setvarsafe("OPTARG", p, 0);
8963 err |= setvarsafe("OPTARG", nullstr, 0);
8965 *optoff = p ? p - *(optnext - 1) : -1;
8966 *param_optind = optnext - optfirst + 1;
8967 fmtstr(s, sizeof(s), "%d", *param_optind);
8968 err |= setvarsafe("OPTIND", s, VNOFUNC);
8971 err |= setvarsafe(optvar, s, 0);
8975 flush_stdout_stderr();
8976 raise_exception(EXERROR);
8983 * The getopts builtin. Shellparam.optnext points to the next argument
8984 * to be processed. Shellparam.optptr points to the next character to
8985 * be processed in the current argument. If shellparam.optnext is NULL,
8986 * then it's the first time getopts has been called.
8989 getoptscmd(int argc, char **argv)
8994 ash_msg_and_raise_error("Usage: getopts optstring var [arg]");
8996 optbase = shellparam.p;
8997 if (shellparam.optind > shellparam.nparam + 1) {
8998 shellparam.optind = 1;
8999 shellparam.optoff = -1;
9003 if (shellparam.optind > argc - 2) {
9004 shellparam.optind = 1;
9005 shellparam.optoff = -1;
9009 return getopts(argv[1], argv[2], optbase, &shellparam.optind,
9010 &shellparam.optoff);
9012 #endif /* ASH_GETOPTS */
9015 /* ============ Shell parser */
9017 static void raise_error_syntax(const char *) ATTRIBUTE_NORETURN;
9019 raise_error_syntax(const char *msg)
9021 ash_msg_and_raise_error("Syntax error: %s", msg);
9026 * Called when an unexpected token is read during the parse. The argument
9027 * is the token that is expected, or -1 if more than one type of token can
9028 * occur at this point.
9030 static void raise_error_unexpected_syntax(int) ATTRIBUTE_NORETURN;
9032 raise_error_unexpected_syntax(int token)
9037 l = sprintf(msg, "%s unexpected", tokname(lasttoken));
9039 sprintf(msg + l, " (expecting %s)", tokname(token));
9040 raise_error_syntax(msg);
9044 #define EOFMARKLEN 79
9047 struct heredoc *next; /* next here document in list */
9048 union node *here; /* redirection node */
9049 char *eofmark; /* string indicating end of input */
9050 int striptabs; /* if set, strip leading tabs */
9053 static struct heredoc *heredoclist; /* list of here documents to read */
9055 /* parsing is heavily cross-recursive, need these forward decls */
9056 static union node *andor(void);
9057 static union node *pipeline(void);
9058 static union node *parse_command(void);
9059 static void parseheredoc(void);
9060 static char peektoken(void);
9061 static int readtoken(void);
9066 union node *n1, *n2, *n3;
9069 checkkwd = CHKNL | CHKKWD | CHKALIAS;
9070 if (nlflag == 2 && peektoken())
9076 if (tok == TBACKGND) {
9077 if (n2->type == NPIPE) {
9078 n2->npipe.backgnd = 1;
9080 if (n2->type != NREDIR) {
9081 n3 = stalloc(sizeof(struct nredir));
9083 n3->nredir.redirect = NULL;
9086 n2->type = NBACKGND;
9092 n3 = stalloc(sizeof(struct nbinary));
9094 n3->nbinary.ch1 = n1;
9095 n3->nbinary.ch2 = n2;
9111 checkkwd = CHKNL | CHKKWD | CHKALIAS;
9119 pungetc(); /* push back EOF on input */
9123 raise_error_unexpected_syntax(-1);
9133 union node *n1, *n2, *n3;
9141 } else if (t == TOR) {
9147 checkkwd = CHKNL | CHKKWD | CHKALIAS;
9149 n3 = stalloc(sizeof(struct nbinary));
9151 n3->nbinary.ch1 = n1;
9152 n3->nbinary.ch2 = n2;
9160 union node *n1, *n2, *pipenode;
9161 struct nodelist *lp, *prev;
9165 TRACE(("pipeline: entered\n"));
9166 if (readtoken() == TNOT) {
9168 checkkwd = CHKKWD | CHKALIAS;
9171 n1 = parse_command();
9172 if (readtoken() == TPIPE) {
9173 pipenode = stalloc(sizeof(struct npipe));
9174 pipenode->type = NPIPE;
9175 pipenode->npipe.backgnd = 0;
9176 lp = stalloc(sizeof(struct nodelist));
9177 pipenode->npipe.cmdlist = lp;
9181 lp = stalloc(sizeof(struct nodelist));
9182 checkkwd = CHKNL | CHKKWD | CHKALIAS;
9183 lp->n = parse_command();
9185 } while (readtoken() == TPIPE);
9191 n2 = stalloc(sizeof(struct nnot));
9204 n = stalloc(sizeof(struct narg));
9206 n->narg.next = NULL;
9207 n->narg.text = wordtext;
9208 n->narg.backquote = backquotelist;
9213 fixredir(union node *n, const char *text, int err)
9215 TRACE(("Fix redir %s %d\n", text, err));
9217 n->ndup.vname = NULL;
9219 if (isdigit(text[0]) && text[1] == '\0')
9220 n->ndup.dupfd = digit_val(text[0]);
9221 else if (LONE_DASH(text))
9225 raise_error_syntax("Bad fd number");
9226 n->ndup.vname = makename();
9231 * Returns true if the text contains nothing to expand (no dollar signs
9235 noexpand(char *text)
9241 while ((c = *p++) != '\0') {
9242 if (c == CTLQUOTEMARK)
9246 else if (SIT(c, BASESYNTAX) == CCTL)
9255 union node *n = redirnode;
9257 if (readtoken() != TWORD)
9258 raise_error_unexpected_syntax(-1);
9259 if (n->type == NHERE) {
9260 struct heredoc *here = heredoc;
9266 TRACE(("Here document %d\n", n->type));
9267 if (!noexpand(wordtext) || (i = strlen(wordtext)) == 0 || i > EOFMARKLEN)
9268 raise_error_syntax("Illegal eof marker for << redirection");
9269 rmescapes(wordtext);
9270 here->eofmark = wordtext;
9272 if (heredoclist == NULL)
9275 for (p = heredoclist; p->next; p = p->next);
9278 } else if (n->type == NTOFD || n->type == NFROMFD) {
9279 fixredir(n, wordtext, 0);
9281 n->nfile.fname = makename();
9288 union node *args, **app;
9289 union node *n = NULL;
9290 union node *vars, **vpp;
9291 union node **rpp, *redir;
9301 savecheckkwd = CHKALIAS;
9303 checkkwd = savecheckkwd;
9304 switch (readtoken()) {
9306 n = stalloc(sizeof(struct narg));
9308 n->narg.text = wordtext;
9309 n->narg.backquote = backquotelist;
9310 if (savecheckkwd && isassignment(wordtext)) {
9312 vpp = &n->narg.next;
9315 app = &n->narg.next;
9320 *rpp = n = redirnode;
9321 rpp = &n->nfile.next;
9322 parsefname(); /* read name of redirection file */
9325 if (args && app == &args->narg.next
9328 struct builtincmd *bcmd;
9331 /* We have a function */
9332 if (readtoken() != TRP)
9333 raise_error_unexpected_syntax(TRP);
9334 name = n->narg.text;
9336 || ((bcmd = find_builtin(name)) && IS_BUILTIN_SPECIAL(bcmd))
9338 raise_error_syntax("Bad function name");
9341 checkkwd = CHKNL | CHKKWD | CHKALIAS;
9342 n->narg.next = parse_command();
9355 n = stalloc(sizeof(struct ncmd));
9357 n->ncmd.args = args;
9358 n->ncmd.assign = vars;
9359 n->ncmd.redirect = redir;
9366 union node *n1, *n2;
9367 union node *ap, **app;
9368 union node *cp, **cpp;
9369 union node *redir, **rpp;
9376 switch (readtoken()) {
9378 raise_error_unexpected_syntax(-1);
9381 n1 = stalloc(sizeof(struct nif));
9383 n1->nif.test = list(0);
9384 if (readtoken() != TTHEN)
9385 raise_error_unexpected_syntax(TTHEN);
9386 n1->nif.ifpart = list(0);
9388 while (readtoken() == TELIF) {
9389 n2->nif.elsepart = stalloc(sizeof(struct nif));
9390 n2 = n2->nif.elsepart;
9392 n2->nif.test = list(0);
9393 if (readtoken() != TTHEN)
9394 raise_error_unexpected_syntax(TTHEN);
9395 n2->nif.ifpart = list(0);
9397 if (lasttoken == TELSE)
9398 n2->nif.elsepart = list(0);
9400 n2->nif.elsepart = NULL;
9408 n1 = stalloc(sizeof(struct nbinary));
9409 n1->type = (lasttoken == TWHILE) ? NWHILE : NUNTIL;
9410 n1->nbinary.ch1 = list(0);
9413 TRACE(("expecting DO got %s %s\n", tokname(got),
9414 got == TWORD ? wordtext : ""));
9415 raise_error_unexpected_syntax(TDO);
9417 n1->nbinary.ch2 = list(0);
9422 if (readtoken() != TWORD || quoteflag || ! goodname(wordtext))
9423 raise_error_syntax("Bad for loop variable");
9424 n1 = stalloc(sizeof(struct nfor));
9426 n1->nfor.var = wordtext;
9427 checkkwd = CHKKWD | CHKALIAS;
9428 if (readtoken() == TIN) {
9430 while (readtoken() == TWORD) {
9431 n2 = stalloc(sizeof(struct narg));
9433 n2->narg.text = wordtext;
9434 n2->narg.backquote = backquotelist;
9436 app = &n2->narg.next;
9440 if (lasttoken != TNL && lasttoken != TSEMI)
9441 raise_error_unexpected_syntax(-1);
9443 n2 = stalloc(sizeof(struct narg));
9445 n2->narg.text = (char *)dolatstr;
9446 n2->narg.backquote = NULL;
9447 n2->narg.next = NULL;
9450 * Newline or semicolon here is optional (but note
9451 * that the original Bourne shell only allowed NL).
9453 if (lasttoken != TNL && lasttoken != TSEMI)
9456 checkkwd = CHKNL | CHKKWD | CHKALIAS;
9457 if (readtoken() != TDO)
9458 raise_error_unexpected_syntax(TDO);
9459 n1->nfor.body = list(0);
9463 n1 = stalloc(sizeof(struct ncase));
9465 if (readtoken() != TWORD)
9466 raise_error_unexpected_syntax(TWORD);
9467 n1->ncase.expr = n2 = stalloc(sizeof(struct narg));
9469 n2->narg.text = wordtext;
9470 n2->narg.backquote = backquotelist;
9471 n2->narg.next = NULL;
9473 checkkwd = CHKKWD | CHKALIAS;
9474 } while (readtoken() == TNL);
9475 if (lasttoken != TIN)
9476 raise_error_unexpected_syntax(TIN);
9477 cpp = &n1->ncase.cases;
9479 checkkwd = CHKNL | CHKKWD;
9481 while (t != TESAC) {
9482 if (lasttoken == TLP)
9484 *cpp = cp = stalloc(sizeof(struct nclist));
9486 app = &cp->nclist.pattern;
9488 *app = ap = stalloc(sizeof(struct narg));
9490 ap->narg.text = wordtext;
9491 ap->narg.backquote = backquotelist;
9492 if (readtoken() != TPIPE)
9494 app = &ap->narg.next;
9497 ap->narg.next = NULL;
9498 if (lasttoken != TRP)
9499 raise_error_unexpected_syntax(TRP);
9500 cp->nclist.body = list(2);
9502 cpp = &cp->nclist.next;
9504 checkkwd = CHKNL | CHKKWD;
9508 raise_error_unexpected_syntax(TENDCASE);
9515 n1 = stalloc(sizeof(struct nredir));
9516 n1->type = NSUBSHELL;
9517 n1->nredir.n = list(0);
9518 n1->nredir.redirect = NULL;
9531 if (readtoken() != t)
9532 raise_error_unexpected_syntax(t);
9535 /* Now check for redirection which may follow command */
9536 checkkwd = CHKKWD | CHKALIAS;
9538 while (readtoken() == TREDIR) {
9539 *rpp = n2 = redirnode;
9540 rpp = &n2->nfile.next;
9546 if (n1->type != NSUBSHELL) {
9547 n2 = stalloc(sizeof(struct nredir));
9552 n1->nredir.redirect = redir;
9558 * If eofmark is NULL, read a word or a redirection symbol. If eofmark
9559 * is not NULL, read a here document. In the latter case, eofmark is the
9560 * word which marks the end of the document and striptabs is true if
9561 * leading tabs should be stripped from the document. The argument firstc
9562 * is the first character of the input token or document.
9564 * Because C does not have internal subroutines, I have simulated them
9565 * using goto's to implement the subroutine linkage. The following macros
9566 * will run code that appears at the end of readtoken1.
9569 #define CHECKEND() {goto checkend; checkend_return:;}
9570 #define PARSEREDIR() {goto parseredir; parseredir_return:;}
9571 #define PARSESUB() {goto parsesub; parsesub_return:;}
9572 #define PARSEBACKQOLD() {oldstyle = 1; goto parsebackq; parsebackq_oldreturn:;}
9573 #define PARSEBACKQNEW() {oldstyle = 0; goto parsebackq; parsebackq_newreturn:;}
9574 #define PARSEARITH() {goto parsearith; parsearith_return:;}
9577 readtoken1(int firstc, int syntax, char *eofmark, int striptabs)
9582 char line[EOFMARKLEN + 1];
9583 struct nodelist *bqlist = 0;
9586 int varnest = 0; /* levels of variables expansion */
9587 int arinest = 0; /* levels of arithmetic expansion */
9588 int parenlevel = 0; /* levels of parens in arithmetic */
9589 int dqvarnest = 0; /* levels of variables expansion within double quotes */
9591 int prevsyntax = 0; /* syntax before arithmetic */
9593 /* Avoid longjmp clobbering */
9606 startlinno = plinno;
9608 if (syntax == DQSYNTAX)
9618 loop: { /* for each line, until end of word */
9619 CHECKEND(); /* set c to PEOF if at end of here document */
9620 for (;;) { /* until end of line or end of word */
9621 CHECKSTRSPACE(4, out); /* permit 4 calls to USTPUTC */
9622 switch (SIT(c, syntax)) {
9623 case CNL: /* '\n' */
9624 if (syntax == BASESYNTAX)
9625 goto endword; /* exit outer loop */
9631 goto loop; /* continue outer loop */
9636 if (eofmark == NULL || dblquote)
9637 USTPUTC(CTLESC, out);
9640 case CBACK: /* backslash */
9643 USTPUTC(CTLESC, out);
9646 } else if (c == '\n') {
9651 c != '\\' && c != '`' &&
9656 USTPUTC(CTLESC, out);
9659 if (SIT(c, SQSYNTAX) == CCTL)
9660 USTPUTC(CTLESC, out);
9668 if (eofmark == NULL) {
9669 USTPUTC(CTLQUOTEMARK, out);
9677 if (eofmark != NULL && arinest == 0
9682 if (dqvarnest == 0) {
9683 syntax = BASESYNTAX;
9690 case CVAR: /* '$' */
9691 PARSESUB(); /* parse substitution */
9693 case CENDVAR: /* '}' */
9696 if (dqvarnest > 0) {
9699 USTPUTC(CTLENDVAR, out);
9704 #if ENABLE_ASH_MATH_SUPPORT
9705 case CLP: /* '(' in arithmetic */
9709 case CRP: /* ')' in arithmetic */
9710 if (parenlevel > 0) {
9714 if (pgetc() == ')') {
9715 if (--arinest == 0) {
9716 USTPUTC(CTLENDARI, out);
9717 syntax = prevsyntax;
9718 if (syntax == DQSYNTAX)
9727 * (don't 2nd guess - no error)
9735 case CBQUOTE: /* '`' */
9739 goto endword; /* exit outer loop */
9744 goto endword; /* exit outer loop */
9745 #if ENABLE_ASH_ALIAS
9755 #if ENABLE_ASH_MATH_SUPPORT
9756 if (syntax == ARISYNTAX)
9757 raise_error_syntax("Missing '))'");
9759 if (syntax != BASESYNTAX && ! parsebackquote && eofmark == NULL)
9760 raise_error_syntax("Unterminated quoted string");
9762 startlinno = plinno;
9764 raise_error_syntax("Missing '}'");
9767 len = out - (char *)stackblock();
9769 if (eofmark == NULL) {
9770 if ((c == '>' || c == '<')
9773 && (*out == '\0' || isdigit(*out))) {
9775 return lasttoken = TREDIR;
9781 backquotelist = bqlist;
9782 grabstackblock(len);
9786 /* end of readtoken routine */
9790 * Check to see whether we are at the end of the here document. When this
9791 * is called, c is set to the first character of the next input line. If
9792 * we are at the end of the here document, this routine sets the c to PEOF.
9796 #if ENABLE_ASH_ALIAS
9806 if (c == *eofmark) {
9807 if (pfgets(line, sizeof(line)) != NULL) {
9811 for (q = eofmark + 1; *q && *p == *q; p++, q++);
9812 if (*p == '\n' && *q == '\0') {
9815 needprompt = doprompt;
9817 pushstring(line, NULL);
9822 goto checkend_return;
9827 * Parse a redirection operator. The variable "out" points to a string
9828 * specifying the fd to be redirected. The variable "c" contains the
9829 * first character of the redirection operator.
9835 np = stalloc(sizeof(struct nfile));
9842 np->type = NCLOBBER;
9849 } else { /* c == '<' */
9854 if (sizeof(struct nfile) != sizeof(struct nhere)) {
9855 np = stalloc(sizeof(struct nhere));
9859 heredoc = stalloc(sizeof(struct heredoc));
9863 heredoc->striptabs = 1;
9865 heredoc->striptabs = 0;
9885 np->nfile.fd = digit_val(fd);
9887 goto parseredir_return;
9892 * Parse a substitution. At this point, we have read the dollar sign
9900 static const char types[] = "}-+?=";
9904 c <= PEOA_OR_PEOF ||
9905 (c != '(' && c != '{' && !is_name(c) && !is_special(c))
9909 } else if (c == '(') { /* $(command) or $((arith)) */
9910 if (pgetc() == '(') {
9911 #if ENABLE_ASH_MATH_SUPPORT
9914 raise_error_syntax("We unsupport $((arith))");
9921 USTPUTC(CTLVAR, out);
9922 typeloc = out - (char *)stackblock();
9923 USTPUTC(VSNORMAL, out);
9936 if (c > PEOA_OR_PEOF && is_name(c)) {
9940 } while (c > PEOA_OR_PEOF && is_in_name(c));
9941 } else if (isdigit(c)) {
9945 } while (isdigit(c));
9946 } else if (is_special(c)) {
9950 badsub: raise_error_syntax("Bad substitution");
9961 p = strchr(types, c);
9964 subtype = p - types + VSNORMAL;
9970 subtype = c == '#' ? VSTRIMLEFT :
9983 if (dblquote || arinest)
9985 *((char *)stackblock() + typeloc) = subtype | flags;
9986 if (subtype != VSNORMAL) {
9988 if (dblquote || arinest) {
9993 goto parsesub_return;
9998 * Called to parse command substitutions. Newstyle is set if the command
9999 * is enclosed inside $(...); nlpp is a pointer to the head of the linked
10000 * list of commands (passed by reference), and savelen is the number of
10001 * characters on the top of the stack which must be preserved.
10004 struct nodelist **nlpp;
10007 char *volatile str;
10008 struct jmploc jmploc;
10009 struct jmploc *volatile savehandler;
10011 int saveprompt = 0;
10013 (void) &saveprompt;
10016 savepbq = parsebackquote;
10017 if (setjmp(jmploc.loc)) {
10020 parsebackquote = 0;
10021 exception_handler = savehandler;
10022 longjmp(exception_handler->loc, 1);
10026 savelen = out - (char *)stackblock();
10028 str = ckmalloc(savelen);
10029 memcpy(str, stackblock(), savelen);
10031 savehandler = exception_handler;
10032 exception_handler = &jmploc;
10035 /* We must read until the closing backquote, giving special
10036 treatment to some slashes, and then push the string and
10037 reread it as input, interpreting it normally. */
10044 STARTSTACKSTR(pout);
10061 * If eating a newline, avoid putting
10062 * the newline into the new character
10063 * stream (via the STPUTC after the
10068 if (pc != '\\' && pc != '`' && pc != '$'
10069 && (!dblquote || pc != '"'))
10070 STPUTC('\\', pout);
10071 if (pc > PEOA_OR_PEOF) {
10077 #if ENABLE_ASH_ALIAS
10080 startlinno = plinno;
10081 raise_error_syntax("EOF in backquote substitution");
10085 needprompt = doprompt;
10094 STPUTC('\0', pout);
10095 psavelen = pout - (char *)stackblock();
10096 if (psavelen > 0) {
10097 pstr = grabstackstr(pout);
10098 setinputstring(pstr);
10103 nlpp = &(*nlpp)->next;
10104 *nlpp = stalloc(sizeof(**nlpp));
10105 (*nlpp)->next = NULL;
10106 parsebackquote = oldstyle;
10109 saveprompt = doprompt;
10116 doprompt = saveprompt;
10117 else if (readtoken() != TRP)
10118 raise_error_unexpected_syntax(TRP);
10123 * Start reading from old file again, ignoring any pushed back
10124 * tokens left from the backquote parsing
10129 while (stackblocksize() <= savelen)
10131 STARTSTACKSTR(out);
10133 memcpy(out, str, savelen);
10134 STADJUST(savelen, out);
10140 parsebackquote = savepbq;
10141 exception_handler = savehandler;
10142 if (arinest || dblquote)
10143 USTPUTC(CTLBACKQ | CTLQUOTE, out);
10145 USTPUTC(CTLBACKQ, out);
10147 goto parsebackq_oldreturn;
10148 goto parsebackq_newreturn;
10151 #if ENABLE_ASH_MATH_SUPPORT
10153 * Parse an arithmetic expansion (indicate start of one and set state)
10156 if (++arinest == 1) {
10157 prevsyntax = syntax;
10158 syntax = ARISYNTAX;
10159 USTPUTC(CTLARI, out);
10166 * we collapse embedded arithmetic expansion to
10167 * parenthesis, which should be equivalent
10171 goto parsearith_return;
10175 } /* end of readtoken */
10178 * Read the next input token.
10179 * If the token is a word, we set backquotelist to the list of cmds in
10180 * backquotes. We set quoteflag to true if any part of the word was
10182 * If the token is TREDIR, then we set redirnode to a structure containing
10184 * In all cases, the variable startlinno is set to the number of the line
10185 * on which the token starts.
10187 * [Change comment: here documents and internal procedures]
10188 * [Readtoken shouldn't have any arguments. Perhaps we should make the
10189 * word parsing code into a separate routine. In this case, readtoken
10190 * doesn't need to have any internal procedures, but parseword does.
10191 * We could also make parseoperator in essence the main routine, and
10192 * have parseword (readtoken1?) handle both words and redirection.]
10194 #define NEW_xxreadtoken
10195 #ifdef NEW_xxreadtoken
10196 /* singles must be first! */
10197 static const char xxreadtoken_chars[7] = { '\n', '(', ')', '&', '|', ';', 0 };
10199 static const char xxreadtoken_tokens[] = {
10200 TNL, TLP, TRP, /* only single occurrence allowed */
10201 TBACKGND, TPIPE, TSEMI, /* if single occurrence */
10202 TEOF, /* corresponds to trailing nul */
10203 TAND, TOR, TENDCASE, /* if double occurrence */
10206 #define xxreadtoken_doubles \
10207 (sizeof(xxreadtoken_tokens) - sizeof(xxreadtoken_chars))
10208 #define xxreadtoken_singles \
10209 (sizeof(xxreadtoken_chars) - xxreadtoken_doubles - 1)
10223 startlinno = plinno;
10224 for (;;) { /* until token or start of word found */
10227 if ((c != ' ') && (c != '\t')
10228 #if ENABLE_ASH_ALIAS
10233 while ((c = pgetc()) != '\n' && c != PEOF);
10235 } else if (c == '\\') {
10236 if (pgetc() != '\n') {
10240 startlinno = ++plinno;
10245 = xxreadtoken_chars + sizeof(xxreadtoken_chars) - 1;
10250 needprompt = doprompt;
10253 p = strchr(xxreadtoken_chars, c);
10256 return readtoken1(c, BASESYNTAX, (char *) NULL, 0);
10259 if (p - xxreadtoken_chars >= xxreadtoken_singles) {
10260 if (pgetc() == *p) { /* double occurrence? */
10261 p += xxreadtoken_doubles + 1;
10267 return lasttoken = xxreadtoken_tokens[p - xxreadtoken_chars];
10273 #define RETURN(token) return lasttoken = token
10286 startlinno = plinno;
10287 for (;;) { /* until token or start of word found */
10290 case ' ': case '\t':
10291 #if ENABLE_ASH_ALIAS
10296 while ((c = pgetc()) != '\n' && c != PEOF);
10300 if (pgetc() == '\n') {
10301 startlinno = ++plinno;
10310 needprompt = doprompt;
10315 if (pgetc() == '&')
10320 if (pgetc() == '|')
10325 if (pgetc() == ';')
10338 return readtoken1(c, BASESYNTAX, (char *)NULL, 0);
10341 #endif /* NEW_xxreadtoken */
10348 int alreadyseen = tokpushback;
10351 #if ENABLE_ASH_ALIAS
10360 if (checkkwd & CHKNL) {
10367 if (t != TWORD || quoteflag) {
10372 * check for keywords
10374 if (checkkwd & CHKKWD) {
10375 const char *const *pp;
10377 pp = findkwd(wordtext);
10379 lasttoken = t = pp - tokname_array;
10380 TRACE(("keyword %s recognized\n", tokname(t)));
10385 if (checkkwd & CHKALIAS) {
10386 #if ENABLE_ASH_ALIAS
10388 ap = lookupalias(wordtext, 1);
10391 pushstring(ap->val, ap);
10401 TRACE(("token %s %s\n", tokname(t), t == TWORD ? wordtext : ""));
10403 TRACE(("reread token %s %s\n", tokname(t), t == TWORD ? wordtext : ""));
10415 return tokname_array[t][0];
10419 * Read and parse a command. Returns NEOF on end of file. (NULL is a
10420 * valid parse tree indicating a blank line.)
10422 static union node *
10423 parsecmd(int interact)
10428 doprompt = interact;
10430 setprompt(doprompt);
10442 * Input any here documents.
10447 struct heredoc *here;
10450 here = heredoclist;
10457 readtoken1(pgetc(), here->here->type == NHERE? SQSYNTAX : DQSYNTAX,
10458 here->eofmark, here->striptabs);
10459 n = stalloc(sizeof(struct narg));
10460 n->narg.type = NARG;
10461 n->narg.next = NULL;
10462 n->narg.text = wordtext;
10463 n->narg.backquote = backquotelist;
10464 here->here->nhere.doc = n;
10471 * called by editline -- any expansions to the prompt
10472 * should be added here.
10474 #if ENABLE_ASH_EXPAND_PRMT
10475 static const char *
10476 expandstr(const char *ps)
10480 /* XXX Fix (char *) cast. */
10481 setinputstring((char *)ps);
10482 readtoken1(pgetc(), DQSYNTAX, nullstr, 0);
10485 n.narg.type = NARG;
10486 n.narg.next = NULL;
10487 n.narg.text = wordtext;
10488 n.narg.backquote = backquotelist;
10490 expandarg(&n, NULL, 0);
10491 return stackblock();
10497 * Execute a command or commands contained in a string.
10500 evalstring(char *s, int mask)
10503 struct stackmark smark;
10507 setstackmark(&smark);
10510 while ((n = parsecmd(0)) != NEOF) {
10512 popstackmark(&smark);
10525 * The eval command.
10528 evalcmd(int argc, char **argv)
10537 STARTSTACKSTR(concat);
10540 concat = stack_putstr(p, concat);
10544 STPUTC(' ', concat);
10546 STPUTC('\0', concat);
10547 p = grabstackstr(concat);
10549 evalstring(p, ~SKIPEVAL);
10556 * Read and execute commands. "Top" is nonzero for the top level command
10557 * loop; it turns on prompting if the shell is interactive.
10563 struct stackmark smark;
10567 TRACE(("cmdloop(%d) called\n", top));
10571 setstackmark(&smark);
10574 showjobs(stderr, SHOW_CHANGED);
10577 if (iflag && top) {
10579 #if ENABLE_ASH_MAIL
10583 n = parsecmd(inter);
10584 /* showtree(n); DEBUG */
10586 if (!top || numeof >= 50)
10588 if (!stoppedjobs()) {
10591 out2str("\nUse \"exit\" to leave shell.\n");
10594 } else if (nflag == 0) {
10595 job_warning = (job_warning == 2) ? 1 : 0;
10599 popstackmark(&smark);
10604 return skip & SKIPEVAL;
10611 dotcmd(int argc, char **argv)
10613 struct strlist *sp;
10614 volatile struct shparam saveparam;
10617 for (sp = cmdenviron; sp; sp = sp->next)
10618 setvareq(xstrdup(sp->text), VSTRFIXED | VTEXTFIXED);
10620 if (argc >= 2) { /* That's what SVR2 does */
10623 fullname = find_dot_file(argv[1]);
10626 saveparam = shellparam;
10627 shellparam.malloc = 0;
10628 shellparam.nparam = argc - 2;
10629 shellparam.p = argv + 2;
10632 setinputfile(fullname, INPUT_PUSH_FILE);
10633 commandname = fullname;
10638 freeparam(&shellparam);
10639 shellparam = saveparam;
10641 status = exitstatus;
10647 exitcmd(int argc, char **argv)
10652 exitstatus = number(argv[1]);
10653 raise_exception(EXEXIT);
10657 #if ENABLE_ASH_BUILTIN_ECHO
10659 echocmd(int argc, char **argv)
10661 return bb_echo(argv);
10665 #if ENABLE_ASH_BUILTIN_TEST
10667 testcmd(int argc, char **argv)
10669 return bb_test(argc, argv);
10674 * Read a file containing shell functions.
10677 readcmdfile(char *name)
10679 setinputfile(name, INPUT_PUSH_FILE);
10688 * Code for dealing with input/output redirection.
10691 #define EMPTY -2 /* marks an unused slot in redirtab */
10693 # define PIPESIZE 4096 /* amount of buffering in a pipe */
10695 # define PIPESIZE PIPE_BUF
10699 * Open a file in noclobber mode.
10700 * The code was copied from bash.
10703 noclobberopen(const char *fname)
10706 struct stat finfo, finfo2;
10709 * If the file exists and is a regular file, return an error
10712 r = stat(fname, &finfo);
10713 if (r == 0 && S_ISREG(finfo.st_mode)) {
10719 * If the file was not present (r != 0), make sure we open it
10720 * exclusively so that if it is created before we open it, our open
10721 * will fail. Make sure that we do not truncate an existing file.
10722 * Note that we don't turn on O_EXCL unless the stat failed -- if the
10723 * file was not a regular file, we leave O_EXCL off.
10726 return open(fname, O_WRONLY|O_CREAT|O_EXCL, 0666);
10727 fd = open(fname, O_WRONLY|O_CREAT, 0666);
10729 /* If the open failed, return the file descriptor right away. */
10734 * OK, the open succeeded, but the file may have been changed from a
10735 * non-regular file to a regular file between the stat and the open.
10736 * We are assuming that the O_EXCL open handles the case where FILENAME
10737 * did not exist and is symlinked to an existing file between the stat
10742 * If we can open it and fstat the file descriptor, and neither check
10743 * revealed that it was a regular file, and the file has not been
10744 * replaced, return the file descriptor.
10746 if (fstat(fd, &finfo2) == 0 && !S_ISREG(finfo2.st_mode)
10747 && finfo.st_dev == finfo2.st_dev && finfo.st_ino == finfo2.st_ino)
10750 /* The file has been replaced. badness. */
10758 * Handle here documents. Normally we fork off a process to write the
10759 * data to a pipe. If the document is short, we can stuff the data in
10760 * the pipe without forking.
10763 openhere(union node *redir)
10769 ash_msg_and_raise_error("Pipe call failed");
10770 if (redir->type == NHERE) {
10771 len = strlen(redir->nhere.doc->narg.text);
10772 if (len <= PIPESIZE) {
10773 full_write(pip[1], redir->nhere.doc->narg.text, len);
10777 if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) {
10779 signal(SIGINT, SIG_IGN);
10780 signal(SIGQUIT, SIG_IGN);
10781 signal(SIGHUP, SIG_IGN);
10783 signal(SIGTSTP, SIG_IGN);
10785 signal(SIGPIPE, SIG_DFL);
10786 if (redir->type == NHERE)
10787 full_write(pip[1], redir->nhere.doc->narg.text, len);
10789 expandhere(redir->nhere.doc, pip[1]);
10798 openredirect(union node *redir)
10803 switch (redir->nfile.type) {
10805 fname = redir->nfile.expfname;
10806 f = open(fname, O_RDONLY);
10811 fname = redir->nfile.expfname;
10812 f = open(fname, O_RDWR|O_CREAT|O_TRUNC, 0666);
10817 /* Take care of noclobber mode. */
10819 fname = redir->nfile.expfname;
10820 f = noclobberopen(fname);
10827 fname = redir->nfile.expfname;
10828 f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666);
10833 fname = redir->nfile.expfname;
10834 f = open(fname, O_WRONLY|O_CREAT|O_APPEND, 0666);
10842 /* Fall through to eliminate warning. */
10849 f = openhere(redir);
10855 ash_msg_and_raise_error("cannot create %s: %s", fname, errmsg(errno, "Directory nonexistent"));
10857 ash_msg_and_raise_error("cannot open %s: %s", fname, errmsg(errno, "No such file"));
10861 dupredirect(union node *redir, int f)
10863 int fd = redir->nfile.fd;
10865 if (redir->nfile.type == NTOFD || redir->nfile.type == NFROMFD) {
10866 if (redir->ndup.dupfd >= 0) { /* if not ">&-" */
10867 copyfd(redir->ndup.dupfd, fd);
10880 * Process a list of redirection commands. If the REDIR_PUSH flag is set,
10881 * old file descriptors are stashed away so that the redirection can be
10882 * undone by calling popredir. If the REDIR_BACKQ flag is set, then the
10883 * standard output, and the standard error if it becomes a duplicate of
10884 * stdout, is saved in memory.
10887 redirect(union node *redir, int flags)
10890 struct redirtab *sv;
10901 if (flags & REDIR_PUSH) {
10902 struct redirtab *q;
10903 q = ckmalloc(sizeof(struct redirtab));
10904 q->next = redirlist;
10906 q->nullredirs = nullredirs - 1;
10907 for (i = 0; i < 10; i++)
10908 q->renamed[i] = EMPTY;
10915 if ((n->nfile.type == NTOFD || n->nfile.type == NFROMFD)
10916 && n->ndup.dupfd == fd)
10917 continue; /* redirect from/to same file descriptor */
10919 newfd = openredirect(n);
10922 if (sv && *(p = &sv->renamed[fd]) == EMPTY) {
10923 i = fcntl(fd, F_DUPFD, 10);
10930 ash_msg_and_raise_error("%d: %m", fd);
10940 dupredirect(n, newfd);
10941 } while ((n = n->nfile.next));
10943 if (flags & REDIR_SAVEFD2 && sv && sv->renamed[2] >= 0)
10944 preverrout_fd = sv->renamed[2];
10949 * Undo the effects of the last redirection.
10954 struct redirtab *rp;
10957 if (--nullredirs >= 0)
10961 for (i = 0; i < 10; i++) {
10962 if (rp->renamed[i] != EMPTY) {
10965 copyfd(rp->renamed[i], i);
10967 close(rp->renamed[i]);
10970 redirlist = rp->next;
10971 nullredirs = rp->nullredirs;
10977 * Undo all redirections. Called on error or interrupt.
10981 * Discard all saved file descriptors.
10984 clearredir(int drop)
10996 * Copy a file descriptor to be >= to. Returns -1
10997 * if the source file descriptor is closed, EMPTY if there are no unused
10998 * file descriptors left.
11001 copyfd(int from, int to)
11005 newfd = fcntl(from, F_DUPFD, to);
11007 if (errno == EMFILE)
11009 ash_msg_and_raise_error("%d: %m", from);
11015 redirectsafe(union node *redir, int flags)
11018 volatile int saveint;
11019 struct jmploc *volatile savehandler = exception_handler;
11020 struct jmploc jmploc;
11023 err = setjmp(jmploc.loc) * 2;
11025 exception_handler = &jmploc;
11026 redirect(redir, flags);
11028 exception_handler = savehandler;
11029 if (err && exception != EXERROR)
11030 longjmp(exception_handler->loc, 1);
11031 RESTORE_INT(saveint);
11038 static void shtree(union node *, int, char *, FILE*);
11039 static void shcmd(union node *, FILE *);
11040 static void sharg(union node *, FILE *);
11041 static void indent(int, char *, FILE *);
11042 static void trstring(char *);
11045 showtree(union node *n)
11047 trputs("showtree called\n");
11048 shtree(n, 1, NULL, stdout);
11052 shtree(union node *n, int ind, char *pfx, FILE *fp)
11054 struct nodelist *lp;
11060 indent(ind, pfx, fp);
11071 shtree(n->nbinary.ch1, ind, NULL, fp);
11074 shtree(n->nbinary.ch2, ind, NULL, fp);
11082 for (lp = n->npipe.cmdlist; lp; lp = lp->next) {
11087 if (n->npipe.backgnd)
11093 fprintf(fp, "<node type %d>", n->type);
11101 shcmd(union node *cmd, FILE *fp)
11109 for (np = cmd->ncmd.args; np; np = np->narg.next) {
11115 for (np = cmd->ncmd.redirect; np; np = np->nfile.next) {
11118 switch (np->nfile.type) {
11119 case NTO: s = ">"; dftfd = 1; break;
11120 case NCLOBBER: s = ">|"; dftfd = 1; break;
11121 case NAPPEND: s = ">>"; dftfd = 1; break;
11122 case NTOFD: s = ">&"; dftfd = 1; break;
11123 case NFROM: s = "<"; dftfd = 0; break;
11124 case NFROMFD: s = "<&"; dftfd = 0; break;
11125 case NFROMTO: s = "<>"; dftfd = 0; break;
11126 default: s = "*error*"; dftfd = 0; break;
11128 if (np->nfile.fd != dftfd)
11129 fprintf(fp, "%d", np->nfile.fd);
11131 if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) {
11132 fprintf(fp, "%d", np->ndup.dupfd);
11134 sharg(np->nfile.fname, fp);
11141 sharg(union node *arg, FILE *fp)
11144 struct nodelist *bqlist;
11147 if (arg->type != NARG) {
11148 out1fmt("<node type %d>\n", arg->type);
11151 bqlist = arg->narg.backquote;
11152 for (p = arg->narg.text; *p; p++) {
11161 if (subtype == VSLENGTH)
11167 if (subtype & VSNUL)
11170 switch (subtype & VSTYPE) {
11189 case VSTRIMLEFTMAX:
11196 case VSTRIMRIGHTMAX:
11203 out1fmt("<subtype %d>", subtype);
11210 case CTLBACKQ|CTLQUOTE:
11213 shtree(bqlist->n, -1, NULL, fp);
11225 indent(int amount, char *pfx, FILE *fp)
11229 for (i = 0; i < amount; i++) {
11230 if (pfx && i == amount - 1)
11242 static FILE *tracefile;
11250 putc(c, tracefile);
11254 trace(const char *fmt, ...)
11261 (void) vfprintf(tracefile, fmt, va);
11266 tracev(const char *fmt, va_list va)
11270 (void) vfprintf(tracefile, fmt, va);
11275 trputs(const char *s)
11279 fputs(s, tracefile);
11291 putc('"', tracefile);
11292 for (p = s; *p; p++) {
11294 case '\n': c = 'n'; goto backslash;
11295 case '\t': c = 't'; goto backslash;
11296 case '\r': c = 'r'; goto backslash;
11297 case '"': c = '"'; goto backslash;
11298 case '\\': c = '\\'; goto backslash;
11299 case CTLESC: c = 'e'; goto backslash;
11300 case CTLVAR: c = 'v'; goto backslash;
11301 case CTLVAR+CTLQUOTE: c = 'V'; goto backslash;
11302 case CTLBACKQ: c = 'q'; goto backslash;
11303 case CTLBACKQ+CTLQUOTE: c = 'Q'; goto backslash;
11305 putc('\\', tracefile);
11306 putc(c, tracefile);
11309 if (*p >= ' ' && *p <= '~')
11310 putc(*p, tracefile);
11312 putc('\\', tracefile);
11313 putc(*p >> 6 & 03, tracefile);
11314 putc(*p >> 3 & 07, tracefile);
11315 putc(*p & 07, tracefile);
11320 putc('"', tracefile);
11332 putc(' ', tracefile);
11334 putc('\n', tracefile);
11350 /* leave open because libedit might be using it */
11353 scopy("./trace", s);
11355 if (!freopen(s, "a", tracefile)) {
11356 fprintf(stderr, "Can't re-open %s\n", s);
11361 tracefile = fopen(s, "a");
11362 if (tracefile == NULL) {
11363 fprintf(stderr, "Can't open %s\n", s);
11369 flags = fcntl(fileno(tracefile), F_GETFL, 0);
11371 fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND);
11373 setlinebuf(tracefile);
11374 fputs("\nTracing started.\n", tracefile);
11382 * Sigmode records the current value of the signal handlers for the various
11383 * modes. A value of zero means that the current handler is not known.
11384 * S_HARD_IGN indicates that the signal was ignored on entry to the shell,
11387 #define S_DFL 1 /* default signal handling (SIG_DFL) */
11388 #define S_CATCH 2 /* signal is caught */
11389 #define S_IGN 3 /* signal is ignored (SIG_IGN) */
11390 #define S_HARD_IGN 4 /* signal is ignored permenantly */
11391 #define S_RESET 5 /* temporary - to reset a hard ignored sig */
11395 * The trap builtin.
11398 trapcmd(int argc, char **argv)
11407 for (signo = 0; signo < NSIG; signo++) {
11408 if (trap[signo] != NULL) {
11411 sn = get_signame(signo);
11412 out1fmt("trap -- %s %s\n",
11413 single_quote(trap[signo]), sn);
11423 signo = get_signum(*ap);
11425 ash_msg_and_raise_error("%s: bad trap", *ap);
11428 if (LONE_DASH(action))
11431 action = ckstrdup(action);
11435 trap[signo] = action;
11446 * Clear traps on a fork.
11453 for (tp = trap; tp < &trap[NSIG]; tp++) {
11454 if (*tp && **tp) { /* trap not NULL or SIG_IGN */
11458 if (tp != &trap[0])
11459 setsignal(tp - trap);
11467 * Set the signal handler for the specified signal. The routine figures
11468 * out what it should be set to.
11471 setsignal(int signo)
11475 struct sigaction act;
11480 else if (*t != '\0')
11484 if (rootshell && action == S_DFL) {
11487 if (iflag || minusc || sflag == 0)
11510 t = &sigmode[signo - 1];
11514 * current setting unknown
11516 if (sigaction(signo, 0, &act) == -1) {
11518 * Pretend it worked; maybe we should give a warning
11519 * here, but other shells don't. We don't alter
11520 * sigmode, so that we retry every time.
11524 if (act.sa_handler == SIG_IGN) {
11526 && (signo == SIGTSTP || signo == SIGTTIN || signo == SIGTTOU)
11528 tsig = S_IGN; /* don't hard ignore these */
11532 tsig = S_RESET; /* force to be set */
11535 if (tsig == S_HARD_IGN || tsig == action)
11539 act.sa_handler = onsig;
11542 act.sa_handler = SIG_IGN;
11545 act.sa_handler = SIG_DFL;
11549 sigfillset(&act.sa_mask);
11550 sigaction(signo, &act, 0);
11558 ignoresig(int signo)
11560 if (sigmode[signo - 1] != S_IGN && sigmode[signo - 1] != S_HARD_IGN) {
11561 signal(signo, SIG_IGN);
11563 sigmode[signo - 1] = S_HARD_IGN;
11573 gotsig[signo - 1] = 1;
11574 pendingsigs = signo;
11576 if (exsig || (signo == SIGINT && !trap[SIGINT])) {
11585 * Called to execute a trap. Perhaps we should avoid entering new trap
11586 * handlers while we are executing a trap handler.
11597 savestatus = exitstatus;
11601 for (i = 0, q = gotsig; i < NSIG - 1; i++, q++) {
11609 skip = evalstring(p, SKIPEVAL);
11610 exitstatus = savestatus;
11619 * Controls whether the shell is interactive or not.
11622 setinteractive(int on)
11624 static int is_interactive;
11626 if (++on == is_interactive)
11628 is_interactive = on;
11630 setsignal(SIGQUIT);
11631 setsignal(SIGTERM);
11632 #if !ENABLE_FEATURE_SH_EXTRA_QUIET
11633 if (is_interactive > 1) {
11634 /* Looks like they want an interactive shell */
11635 static int do_banner;
11640 "%s Built-in shell (ash)\n"
11641 "Enter 'help' for a list of built-in commands."
11650 #if !ENABLE_FEATURE_SH_EXTRA_QUIET
11651 /*** List the available builtins ***/
11654 helpcmd(int argc, char **argv)
11658 out1fmt("\nBuilt-in commands:\n-------------------\n");
11659 for (col = 0, i = 0; i < NUMBUILTINS; i++) {
11660 col += out1fmt("%c%s", ((col == 0) ? '\t' : ' '),
11661 builtincmd[i].name + 1);
11667 #if ENABLE_FEATURE_SH_STANDALONE_SHELL
11668 for (i = 0; i < NUM_APPLETS; i++) {
11669 col += out1fmt("%c%s", ((col == 0) ? '\t' : ' '), applets[i].name);
11677 return EXIT_SUCCESS;
11679 #endif /* FEATURE_SH_EXTRA_QUIET */
11682 * Called to exit the shell.
11691 status = exitstatus;
11692 TRACE(("pid %d, exitshell(%d)\n", getpid(), status));
11693 if (setjmp(loc.loc)) {
11694 if (exception == EXEXIT)
11695 /* dash bug: it just does _exit(exitstatus) here
11696 * but we have to do setjobctl(0) first!
11697 * (bug is still not fixed in dash-0.5.3 - if you run dash
11698 * under Midnight Commander, on exit from dash MC is backgrounded) */
11699 status = exitstatus;
11702 exception_handler = &loc;
11708 flush_stdout_stderr();
11717 * The export and readonly commands.
11720 exportcmd(int argc, char **argv)
11726 int flag = argv[0][0] == 'r'? VREADONLY : VEXPORT;
11728 if (nextopt("p") != 'p') {
11733 p = strchr(name, '=');
11737 vp = *findvar(hashvar(name), name);
11743 setvar(name, p, flag);
11744 } while ((name = *++aptr) != NULL);
11748 showvars(argv[0], flag, 0);
11754 * Make a variable a local variable. When a variable is made local, it's
11755 * value and flags are saved in a localvar structure. The saved values
11756 * will be restored when the shell function returns. We handle the name
11757 * "-" as a special case.
11759 static void mklocal(char *name)
11761 struct localvar *lvp;
11766 lvp = ckmalloc(sizeof(struct localvar));
11767 if (LONE_DASH(name)) {
11769 p = ckmalloc(sizeof(optlist));
11770 lvp->text = memcpy(p, optlist, sizeof(optlist));
11775 vpp = hashvar(name);
11776 vp = *findvar(vpp, name);
11777 eq = strchr(name, '=');
11780 setvareq(name, VSTRFIXED);
11782 setvar(name, NULL, VSTRFIXED);
11783 vp = *vpp; /* the new variable */
11784 lvp->flags = VUNSET;
11786 lvp->text = vp->text;
11787 lvp->flags = vp->flags;
11788 vp->flags |= VSTRFIXED|VTEXTFIXED;
11794 lvp->next = localvars;
11801 * The "local" command.
11804 localcmd(int argc, char **argv)
11809 while ((name = *argv++) != NULL) {
11817 * The unset builtin command. We unset the function before we unset the
11818 * variable to allow a function to be unset when there is a readonly variable
11819 * with the same name.
11822 unsetcmd(int argc, char **argv)
11829 while ((i = nextopt("vf")) != '\0') {
11833 for (ap = argptr; *ap; ap++) {
11849 #include <sys/times.h>
11851 static const unsigned char timescmd_str[] = {
11852 ' ', offsetof(struct tms, tms_utime),
11853 '\n', offsetof(struct tms, tms_stime),
11854 ' ', offsetof(struct tms, tms_cutime),
11855 '\n', offsetof(struct tms, tms_cstime),
11859 static int timescmd(int ac, char **av)
11861 long int clk_tck, s, t;
11862 const unsigned char *p;
11865 clk_tck = sysconf(_SC_CLK_TCK);
11870 t = *(clock_t *)(((char *) &buf) + p[1]);
11872 out1fmt("%ldm%ld.%.3lds%c",
11874 ((t - s * clk_tck) * 1000) / clk_tck,
11876 } while (*(p += 2));
11881 #if ENABLE_ASH_MATH_SUPPORT
11883 dash_arith(const char *s)
11889 result = arith(s, &errcode);
11892 ash_msg_and_raise_error("exponent less than 0");
11893 else if (errcode == -2)
11894 ash_msg_and_raise_error("divide by zero");
11895 else if (errcode == -5)
11896 ash_msg_and_raise_error("expression recursion loop detected");
11898 raise_error_syntax(s);
11907 * The let builtin. partial stolen from GNU Bash, the Bourne Again SHell.
11908 * Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
11910 * Copyright (C) 2003 Vladimir Oleynik <dzo@simtreas.ru>
11913 letcmd(int argc, char **argv)
11920 ash_msg_and_raise_error("expression expected");
11921 for (ap = argv + 1; *ap; ap++) {
11922 i = dash_arith(*ap);
11927 #endif /* ASH_MATH_SUPPORT */
11932 * Miscellaneous builtins.
11937 #if defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 1
11938 typedef enum __rlimit_resource rlim_t;
11943 * The read builtin. The -e option causes backslashes to escape the
11944 * following character.
11946 * This uses unbuffered input, which may be avoidable in some cases.
11949 readcmd(int argc, char **argv)
11961 #if ENABLE_ASH_READ_NCHARS
11965 struct termios tty, old_tty;
11967 #if ENABLE_ASH_READ_TIMEOUT
11971 ts.tv_sec = ts.tv_usec = 0;
11976 #if ENABLE_ASH_READ_NCHARS && ENABLE_ASH_READ_TIMEOUT
11977 while ((i = nextopt("p:rt:n:s")) != '\0')
11978 #elif ENABLE_ASH_READ_NCHARS
11979 while ((i = nextopt("p:rn:s")) != '\0')
11980 #elif ENABLE_ASH_READ_TIMEOUT
11981 while ((i = nextopt("p:rt:")) != '\0')
11983 while ((i = nextopt("p:r")) != '\0')
11988 prompt = optionarg;
11990 #if ENABLE_ASH_READ_NCHARS
11992 nchars = strtol(optionarg, &p, 10);
11994 ash_msg_and_raise_error("invalid count");
11995 nch_flag = (nchars > 0);
12001 #if ENABLE_ASH_READ_TIMEOUT
12003 ts.tv_sec = strtol(optionarg, &p, 10);
12009 ts.tv_usec = strtol(p, &p2, 10);
12011 ash_msg_and_raise_error("invalid timeout");
12013 /* normalize to usec */
12015 ash_msg_and_raise_error("invalid timeout");
12016 while (scale++ < 6)
12020 ash_msg_and_raise_error("invalid timeout");
12022 if ( ! ts.tv_sec && ! ts.tv_usec)
12023 ash_msg_and_raise_error("invalid timeout");
12033 if (prompt && isatty(0)) {
12038 ash_msg_and_raise_error("arg count");
12039 ifs = bltinlookup("IFS");
12042 #if ENABLE_ASH_READ_NCHARS
12043 if (nch_flag || silent) {
12044 tcgetattr(0, &tty);
12047 tty.c_lflag &= ~ICANON;
12048 tty.c_cc[VMIN] = nchars;
12051 tty.c_lflag &= ~(ECHO|ECHOK|ECHONL);
12054 tcsetattr(0, TCSANOW, &tty);
12057 #if ENABLE_ASH_READ_TIMEOUT
12058 if (ts.tv_sec || ts.tv_usec) {
12062 i = select(FD_SETSIZE, &set, NULL, NULL, &ts);
12064 #if ENABLE_ASH_READ_NCHARS
12066 tcsetattr(0, TCSANOW, &old_tty);
12076 #if ENABLE_ASH_READ_NCHARS
12077 while (!nch_flag || nchars--)
12082 if (read(0, &c, 1) != 1) {
12094 if (!rflag && c == '\\') {
12100 if (startword && *ifs == ' ' && strchr(ifs, c)) {
12104 if (ap[1] != NULL && strchr(ifs, c) != NULL) {
12106 setvar(*ap, stackblock(), 0);
12115 #if ENABLE_ASH_READ_NCHARS
12116 if (nch_flag || silent)
12117 tcsetattr(0, TCSANOW, &old_tty);
12121 /* Remove trailing blanks */
12122 while ((char *)stackblock() <= --p && strchr(ifs, *p) != NULL)
12124 setvar(*ap, stackblock(), 0);
12125 while (*++ap != NULL)
12126 setvar(*ap, nullstr, 0);
12131 static int umaskcmd(int argc, char **argv)
12133 static const char permuser[3] = "ugo";
12134 static const char permmode[3] = "rwx";
12135 static const short int permmask[] = {
12136 S_IRUSR, S_IWUSR, S_IXUSR,
12137 S_IRGRP, S_IWGRP, S_IXGRP,
12138 S_IROTH, S_IWOTH, S_IXOTH
12144 int symbolic_mode = 0;
12146 while (nextopt("S") != '\0') {
12157 if (symbolic_mode) {
12161 for (i = 0; i < 3; i++) {
12164 *p++ = permuser[i];
12166 for (j = 0; j < 3; j++) {
12167 if ((mask & permmask[3 * i + j]) == 0) {
12168 *p++ = permmode[j];
12176 out1fmt("%.4o\n", mask);
12179 if (isdigit((unsigned char) *ap)) {
12182 if (*ap >= '8' || *ap < '0')
12183 ash_msg_and_raise_error(illnum, argv[1]);
12184 mask = (mask << 3) + (*ap - '0');
12185 } while (*++ap != '\0');
12188 mask = ~mask & 0777;
12189 if (!bb_parse_mode(ap, &mask)) {
12190 ash_msg_and_raise_error("Illegal mode: %s", ap);
12192 umask(~mask & 0777);
12201 * This code, originally by Doug Gwyn, Doug Kingston, Eric Gisin, and
12202 * Michael Rendell was ripped from pdksh 5.0.8 and hacked for use with
12203 * ash by J.T. Conklin.
12211 int factor; /* multiply by to get rlim_{cur,max} values */
12215 static const struct limits limits[] = {
12217 { "time(seconds)", RLIMIT_CPU, 1, 't' },
12219 #ifdef RLIMIT_FSIZE
12220 { "file(blocks)", RLIMIT_FSIZE, 512, 'f' },
12223 { "data(kbytes)", RLIMIT_DATA, 1024, 'd' },
12225 #ifdef RLIMIT_STACK
12226 { "stack(kbytes)", RLIMIT_STACK, 1024, 's' },
12229 { "coredump(blocks)", RLIMIT_CORE, 512, 'c' },
12232 { "memory(kbytes)", RLIMIT_RSS, 1024, 'm' },
12234 #ifdef RLIMIT_MEMLOCK
12235 { "locked memory(kbytes)", RLIMIT_MEMLOCK, 1024, 'l' },
12237 #ifdef RLIMIT_NPROC
12238 { "process", RLIMIT_NPROC, 1, 'p' },
12240 #ifdef RLIMIT_NOFILE
12241 { "nofiles", RLIMIT_NOFILE, 1, 'n' },
12244 { "vmemory(kbytes)", RLIMIT_AS, 1024, 'v' },
12246 #ifdef RLIMIT_LOCKS
12247 { "locks", RLIMIT_LOCKS, 1, 'w' },
12249 { (char *) 0, 0, 0, '\0' }
12252 enum limtype { SOFT = 0x1, HARD = 0x2 };
12254 static void printlim(enum limtype how, const struct rlimit *limit,
12255 const struct limits *l)
12259 val = limit->rlim_max;
12261 val = limit->rlim_cur;
12263 if (val == RLIM_INFINITY)
12264 out1fmt("unlimited\n");
12267 out1fmt("%lld\n", (long long) val);
12272 ulimitcmd(int argc, char **argv)
12276 enum limtype how = SOFT | HARD;
12277 const struct limits *l;
12280 struct rlimit limit;
12283 while ((optc = nextopt("HSa"
12287 #ifdef RLIMIT_FSIZE
12293 #ifdef RLIMIT_STACK
12302 #ifdef RLIMIT_MEMLOCK
12305 #ifdef RLIMIT_NPROC
12308 #ifdef RLIMIT_NOFILE
12314 #ifdef RLIMIT_LOCKS
12332 for (l = limits; l->option != what; l++)
12335 set = *argptr ? 1 : 0;
12339 if (all || argptr[1])
12340 ash_msg_and_raise_error("too many arguments");
12341 if (strncmp(p, "unlimited\n", 9) == 0)
12342 val = RLIM_INFINITY;
12346 while ((c = *p++) >= '0' && c <= '9') {
12347 val = (val * 10) + (long)(c - '0');
12348 if (val < (rlim_t) 0)
12352 ash_msg_and_raise_error("bad number");
12357 for (l = limits; l->name; l++) {
12358 getrlimit(l->cmd, &limit);
12359 out1fmt("%-20s ", l->name);
12360 printlim(how, &limit, l);
12365 getrlimit(l->cmd, &limit);
12368 limit.rlim_max = val;
12370 limit.rlim_cur = val;
12371 if (setrlimit(l->cmd, &limit) < 0)
12372 ash_msg_and_raise_error("error setting limit (%m)");
12374 printlim(how, &limit, l);
12380 #if ENABLE_ASH_MATH_SUPPORT
12382 /* Copyright (c) 2001 Aaron Lehmann <aaronl@vitelus.com>
12384 Permission is hereby granted, free of charge, to any person obtaining
12385 a copy of this software and associated documentation files (the
12386 "Software"), to deal in the Software without restriction, including
12387 without limitation the rights to use, copy, modify, merge, publish,
12388 distribute, sublicense, and/or sell copies of the Software, and to
12389 permit persons to whom the Software is furnished to do so, subject to
12390 the following conditions:
12392 The above copyright notice and this permission notice shall be
12393 included in all copies or substantial portions of the Software.
12395 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
12396 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
12397 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
12398 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
12399 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
12400 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
12401 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
12404 /* This is my infix parser/evaluator. It is optimized for size, intended
12405 * as a replacement for yacc-based parsers. However, it may well be faster
12406 * than a comparable parser written in yacc. The supported operators are
12407 * listed in #defines below. Parens, order of operations, and error handling
12408 * are supported. This code is thread safe. The exact expression format should
12409 * be that which POSIX specifies for shells. */
12411 /* The code uses a simple two-stack algorithm. See
12412 * http://www.onthenet.com.au/~grahamis/int2008/week02/lect02.html
12413 * for a detailed explanation of the infix-to-postfix algorithm on which
12414 * this is based (this code differs in that it applies operators immediately
12415 * to the stack instead of adding them to a queue to end up with an
12418 /* To use the routine, call it with an expression string and error return
12422 * Aug 24, 2001 Manuel Novoa III
12424 * Reduced the generated code size by about 30% (i386) and fixed several bugs.
12426 * 1) In arith_apply():
12427 * a) Cached values of *numptr and &(numptr[-1]).
12428 * b) Removed redundant test for zero denominator.
12431 * a) Eliminated redundant code for processing operator tokens by moving
12432 * to a table-based implementation. Also folded handling of parens
12434 * b) Combined all 3 loops which called arith_apply to reduce generated
12435 * code size at the cost of speed.
12437 * 3) The following expressions were treated as valid by the original code:
12438 * 1() , 0! , 1 ( *3 ) .
12439 * These bugs have been fixed by internally enclosing the expression in
12440 * parens and then checking that all binary ops and right parens are
12441 * preceded by a valid expression (NUM_TOKEN).
12443 * Note: It may be desirable to replace Aaron's test for whitespace with
12444 * ctype's isspace() if it is used by another busybox applet or if additional
12445 * whitespace chars should be considered. Look below the "#include"s for a
12446 * precompiler test.
12450 * Aug 26, 2001 Manuel Novoa III
12452 * Return 0 for null expressions. Pointed out by Vladimir Oleynik.
12454 * Merge in Aaron's comments previously posted to the busybox list,
12455 * modified slightly to take account of my changes to the code.
12460 * (C) 2003 Vladimir Oleynik <dzo@simtreas.ru>
12462 * - allow access to variable,
12463 * used recursive find value indirection (c=2*2; a="c"; $((a+=2)) produce 6)
12464 * - realize assign syntax (VAR=expr, +=, *= etc)
12465 * - realize exponentiation (** operator)
12466 * - realize comma separated - expr, expr
12467 * - realise ++expr --expr expr++ expr--
12468 * - realise expr ? expr : expr (but, second expr calculate always)
12469 * - allow hexadecimal and octal numbers
12470 * - was restored loses XOR operator
12471 * - remove one goto label, added three ;-)
12472 * - protect $((num num)) as true zero expr (Manuel`s error)
12473 * - always use special isspace(), see comment from bash ;-)
12477 #define arith_isspace(arithval) \
12478 (arithval == ' ' || arithval == '\n' || arithval == '\t')
12481 typedef unsigned char operator;
12483 /* An operator's token id is a bit of a bitfield. The lower 5 bits are the
12484 * precedence, and 3 high bits are an ID unique across operators of that
12485 * precedence. The ID portion is so that multiple operators can have the
12486 * same precedence, ensuring that the leftmost one is evaluated first.
12487 * Consider * and /. */
12489 #define tok_decl(prec,id) (((id)<<5)|(prec))
12490 #define PREC(op) ((op) & 0x1F)
12492 #define TOK_LPAREN tok_decl(0,0)
12494 #define TOK_COMMA tok_decl(1,0)
12496 #define TOK_ASSIGN tok_decl(2,0)
12497 #define TOK_AND_ASSIGN tok_decl(2,1)
12498 #define TOK_OR_ASSIGN tok_decl(2,2)
12499 #define TOK_XOR_ASSIGN tok_decl(2,3)
12500 #define TOK_PLUS_ASSIGN tok_decl(2,4)
12501 #define TOK_MINUS_ASSIGN tok_decl(2,5)
12502 #define TOK_LSHIFT_ASSIGN tok_decl(2,6)
12503 #define TOK_RSHIFT_ASSIGN tok_decl(2,7)
12505 #define TOK_MUL_ASSIGN tok_decl(3,0)
12506 #define TOK_DIV_ASSIGN tok_decl(3,1)
12507 #define TOK_REM_ASSIGN tok_decl(3,2)
12509 /* all assign is right associativity and precedence eq, but (7+3)<<5 > 256 */
12510 #define convert_prec_is_assing(prec) do { if (prec == 3) prec = 2; } while (0)
12512 /* conditional is right associativity too */
12513 #define TOK_CONDITIONAL tok_decl(4,0)
12514 #define TOK_CONDITIONAL_SEP tok_decl(4,1)
12516 #define TOK_OR tok_decl(5,0)
12518 #define TOK_AND tok_decl(6,0)
12520 #define TOK_BOR tok_decl(7,0)
12522 #define TOK_BXOR tok_decl(8,0)
12524 #define TOK_BAND tok_decl(9,0)
12526 #define TOK_EQ tok_decl(10,0)
12527 #define TOK_NE tok_decl(10,1)
12529 #define TOK_LT tok_decl(11,0)
12530 #define TOK_GT tok_decl(11,1)
12531 #define TOK_GE tok_decl(11,2)
12532 #define TOK_LE tok_decl(11,3)
12534 #define TOK_LSHIFT tok_decl(12,0)
12535 #define TOK_RSHIFT tok_decl(12,1)
12537 #define TOK_ADD tok_decl(13,0)
12538 #define TOK_SUB tok_decl(13,1)
12540 #define TOK_MUL tok_decl(14,0)
12541 #define TOK_DIV tok_decl(14,1)
12542 #define TOK_REM tok_decl(14,2)
12544 /* exponent is right associativity */
12545 #define TOK_EXPONENT tok_decl(15,1)
12547 /* For now unary operators. */
12548 #define UNARYPREC 16
12549 #define TOK_BNOT tok_decl(UNARYPREC,0)
12550 #define TOK_NOT tok_decl(UNARYPREC,1)
12552 #define TOK_UMINUS tok_decl(UNARYPREC+1,0)
12553 #define TOK_UPLUS tok_decl(UNARYPREC+1,1)
12555 #define PREC_PRE (UNARYPREC+2)
12557 #define TOK_PRE_INC tok_decl(PREC_PRE, 0)
12558 #define TOK_PRE_DEC tok_decl(PREC_PRE, 1)
12560 #define PREC_POST (UNARYPREC+3)
12562 #define TOK_POST_INC tok_decl(PREC_POST, 0)
12563 #define TOK_POST_DEC tok_decl(PREC_POST, 1)
12565 #define SPEC_PREC (UNARYPREC+4)
12567 #define TOK_NUM tok_decl(SPEC_PREC, 0)
12568 #define TOK_RPAREN tok_decl(SPEC_PREC, 1)
12570 #define NUMPTR (*numstackptr)
12572 static int tok_have_assign(operator op)
12574 operator prec = PREC(op);
12576 convert_prec_is_assing(prec);
12577 return (prec == PREC(TOK_ASSIGN) ||
12578 prec == PREC_PRE || prec == PREC_POST);
12581 static int is_right_associativity(operator prec)
12583 return (prec == PREC(TOK_ASSIGN) || prec == PREC(TOK_EXPONENT)
12584 || prec == PREC(TOK_CONDITIONAL));
12588 typedef struct ARITCH_VAR_NUM {
12590 arith_t contidional_second_val;
12591 char contidional_second_val_initialized;
12592 char *var; /* if NULL then is regular number,
12593 else is variable name */
12597 typedef struct CHK_VAR_RECURSIVE_LOOPED {
12599 struct CHK_VAR_RECURSIVE_LOOPED *next;
12600 } chk_var_recursive_looped_t;
12602 static chk_var_recursive_looped_t *prev_chk_var_recursive;
12605 static int arith_lookup_val(v_n_t *t)
12608 const char * p = lookupvar(t->var);
12613 /* recursive try as expression */
12614 chk_var_recursive_looped_t *cur;
12615 chk_var_recursive_looped_t cur_save;
12617 for (cur = prev_chk_var_recursive; cur; cur = cur->next) {
12618 if (strcmp(cur->var, t->var) == 0) {
12619 /* expression recursion loop detected */
12623 /* save current lookuped var name */
12624 cur = prev_chk_var_recursive;
12625 cur_save.var = t->var;
12626 cur_save.next = cur;
12627 prev_chk_var_recursive = &cur_save;
12629 t->val = arith (p, &errcode);
12630 /* restore previous ptr after recursiving */
12631 prev_chk_var_recursive = cur;
12634 /* allow undefined var as 0 */
12640 /* "applying" a token means performing it on the top elements on the integer
12641 * stack. For a unary operator it will only change the top element, but a
12642 * binary operator will pop two arguments and push a result */
12643 static int arith_apply(operator op, v_n_t *numstack, v_n_t **numstackptr)
12646 arith_t numptr_val, rez;
12647 int ret_arith_lookup_val;
12649 /* There is no operator that can work without arguments */
12650 if (NUMPTR == numstack) goto err;
12651 numptr_m1 = NUMPTR - 1;
12653 /* check operand is var with noninteger value */
12654 ret_arith_lookup_val = arith_lookup_val(numptr_m1);
12655 if (ret_arith_lookup_val)
12656 return ret_arith_lookup_val;
12658 rez = numptr_m1->val;
12659 if (op == TOK_UMINUS)
12661 else if (op == TOK_NOT)
12663 else if (op == TOK_BNOT)
12665 else if (op == TOK_POST_INC || op == TOK_PRE_INC)
12667 else if (op == TOK_POST_DEC || op == TOK_PRE_DEC)
12669 else if (op != TOK_UPLUS) {
12670 /* Binary operators */
12672 /* check and binary operators need two arguments */
12673 if (numptr_m1 == numstack) goto err;
12675 /* ... and they pop one */
12678 if (op == TOK_CONDITIONAL) {
12679 if (! numptr_m1->contidional_second_val_initialized) {
12680 /* protect $((expr1 ? expr2)) without ": expr" */
12683 rez = numptr_m1->contidional_second_val;
12684 } else if (numptr_m1->contidional_second_val_initialized) {
12685 /* protect $((expr1 : expr2)) without "expr ? " */
12688 numptr_m1 = NUMPTR - 1;
12689 if (op != TOK_ASSIGN) {
12690 /* check operand is var with noninteger value for not '=' */
12691 ret_arith_lookup_val = arith_lookup_val(numptr_m1);
12692 if (ret_arith_lookup_val)
12693 return ret_arith_lookup_val;
12695 if (op == TOK_CONDITIONAL) {
12696 numptr_m1->contidional_second_val = rez;
12698 rez = numptr_m1->val;
12699 if (op == TOK_BOR || op == TOK_OR_ASSIGN)
12701 else if (op == TOK_OR)
12702 rez = numptr_val || rez;
12703 else if (op == TOK_BAND || op == TOK_AND_ASSIGN)
12705 else if (op == TOK_BXOR || op == TOK_XOR_ASSIGN)
12707 else if (op == TOK_AND)
12708 rez = rez && numptr_val;
12709 else if (op == TOK_EQ)
12710 rez = (rez == numptr_val);
12711 else if (op == TOK_NE)
12712 rez = (rez != numptr_val);
12713 else if (op == TOK_GE)
12714 rez = (rez >= numptr_val);
12715 else if (op == TOK_RSHIFT || op == TOK_RSHIFT_ASSIGN)
12716 rez >>= numptr_val;
12717 else if (op == TOK_LSHIFT || op == TOK_LSHIFT_ASSIGN)
12718 rez <<= numptr_val;
12719 else if (op == TOK_GT)
12720 rez = (rez > numptr_val);
12721 else if (op == TOK_LT)
12722 rez = (rez < numptr_val);
12723 else if (op == TOK_LE)
12724 rez = (rez <= numptr_val);
12725 else if (op == TOK_MUL || op == TOK_MUL_ASSIGN)
12727 else if (op == TOK_ADD || op == TOK_PLUS_ASSIGN)
12729 else if (op == TOK_SUB || op == TOK_MINUS_ASSIGN)
12731 else if (op == TOK_ASSIGN || op == TOK_COMMA)
12733 else if (op == TOK_CONDITIONAL_SEP) {
12734 if (numptr_m1 == numstack) {
12735 /* protect $((expr : expr)) without "expr ? " */
12738 numptr_m1->contidional_second_val_initialized = op;
12739 numptr_m1->contidional_second_val = numptr_val;
12741 else if (op == TOK_CONDITIONAL) {
12743 numptr_val : numptr_m1->contidional_second_val;
12745 else if (op == TOK_EXPONENT) {
12746 if (numptr_val < 0)
12747 return -3; /* exponent less than 0 */
12752 while (numptr_val--)
12757 else if (numptr_val==0) /* zero divisor check */
12759 else if (op == TOK_DIV || op == TOK_DIV_ASSIGN)
12761 else if (op == TOK_REM || op == TOK_REM_ASSIGN)
12764 if (tok_have_assign(op)) {
12767 if (numptr_m1->var == NULL) {
12771 /* save to shell variable */
12772 #if ENABLE_ASH_MATH_SUPPORT_64
12773 snprintf(buf, sizeof(buf), "%lld", arith_t_type rez);
12775 snprintf(buf, sizeof(buf), "%ld", arith_t_type rez);
12777 setvar(numptr_m1->var, buf, 0);
12778 /* after saving, make previous value for v++ or v-- */
12779 if (op == TOK_POST_INC)
12781 else if (op == TOK_POST_DEC)
12784 numptr_m1->val = rez;
12785 /* protect geting var value, is number now */
12786 numptr_m1->var = NULL;
12792 /* longest must first */
12793 static const char op_tokens[] = {
12794 '<','<','=',0, TOK_LSHIFT_ASSIGN,
12795 '>','>','=',0, TOK_RSHIFT_ASSIGN,
12796 '<','<', 0, TOK_LSHIFT,
12797 '>','>', 0, TOK_RSHIFT,
12798 '|','|', 0, TOK_OR,
12799 '&','&', 0, TOK_AND,
12800 '!','=', 0, TOK_NE,
12801 '<','=', 0, TOK_LE,
12802 '>','=', 0, TOK_GE,
12803 '=','=', 0, TOK_EQ,
12804 '|','=', 0, TOK_OR_ASSIGN,
12805 '&','=', 0, TOK_AND_ASSIGN,
12806 '*','=', 0, TOK_MUL_ASSIGN,
12807 '/','=', 0, TOK_DIV_ASSIGN,
12808 '%','=', 0, TOK_REM_ASSIGN,
12809 '+','=', 0, TOK_PLUS_ASSIGN,
12810 '-','=', 0, TOK_MINUS_ASSIGN,
12811 '-','-', 0, TOK_POST_DEC,
12812 '^','=', 0, TOK_XOR_ASSIGN,
12813 '+','+', 0, TOK_POST_INC,
12814 '*','*', 0, TOK_EXPONENT,
12818 '=', 0, TOK_ASSIGN,
12830 '?', 0, TOK_CONDITIONAL,
12831 ':', 0, TOK_CONDITIONAL_SEP,
12832 ')', 0, TOK_RPAREN,
12833 '(', 0, TOK_LPAREN,
12837 #define endexpression &op_tokens[sizeof(op_tokens)-7]
12840 static arith_t arith(const char *expr, int *perrcode)
12842 char arithval; /* Current character under analysis */
12843 operator lasttok, op;
12846 const char *p = endexpression;
12849 size_t datasizes = strlen(expr) + 2;
12851 /* Stack of integers */
12852 /* The proof that there can be no more than strlen(startbuf)/2+1 integers
12853 * in any given correct or incorrect expression is left as an exercise to
12855 v_n_t *numstack = alloca(((datasizes)/2)*sizeof(v_n_t)),
12856 *numstackptr = numstack;
12857 /* Stack of operator tokens */
12858 operator *stack = alloca((datasizes) * sizeof(operator)),
12861 *stackptr++ = lasttok = TOK_LPAREN; /* start off with a left paren */
12862 *perrcode = errcode = 0;
12866 if (arithval == 0) {
12867 if (p == endexpression) {
12868 /* Null expression. */
12872 /* This is only reached after all tokens have been extracted from the
12873 * input stream. If there are still tokens on the operator stack, they
12874 * are to be applied in order. At the end, there should be a final
12875 * result on the integer stack */
12877 if (expr != endexpression + 1) {
12878 /* If we haven't done so already, */
12879 /* append a closing right paren */
12880 expr = endexpression;
12881 /* and let the loop process it. */
12884 /* At this point, we're done with the expression. */
12885 if (numstackptr != numstack+1) {
12886 /* ... but if there isn't, it's bad */
12888 return (*perrcode = -1);
12890 if (numstack->var) {
12891 /* expression is $((var)) only, lookup now */
12892 errcode = arith_lookup_val(numstack);
12895 *perrcode = errcode;
12896 return numstack->val;
12899 /* Continue processing the expression. */
12900 if (arith_isspace(arithval)) {
12901 /* Skip whitespace */
12904 p = endofname(expr);
12906 size_t var_name_size = (p-expr) + 1; /* trailing zero */
12908 numstackptr->var = alloca(var_name_size);
12909 safe_strncpy(numstackptr->var, expr, var_name_size);
12912 numstackptr->contidional_second_val_initialized = 0;
12917 if (isdigit(arithval)) {
12918 numstackptr->var = NULL;
12919 #if ENABLE_ASH_MATH_SUPPORT_64
12920 numstackptr->val = strtoll(expr, (char **) &expr, 0);
12922 numstackptr->val = strtol(expr, (char **) &expr, 0);
12926 for (p = op_tokens; ; p++) {
12930 /* strange operator not found */
12933 for (o = expr; *p && *o == *p; p++)
12940 /* skip tail uncompared token */
12943 /* skip zero delim */
12948 /* post grammar: a++ reduce to num */
12949 if (lasttok == TOK_POST_INC || lasttok == TOK_POST_DEC)
12952 /* Plus and minus are binary (not unary) _only_ if the last
12953 * token was as number, or a right paren (which pretends to be
12954 * a number, since it evaluates to one). Think about it.
12955 * It makes sense. */
12956 if (lasttok != TOK_NUM) {
12972 /* We don't want a unary operator to cause recursive descent on the
12973 * stack, because there can be many in a row and it could cause an
12974 * operator to be evaluated before its argument is pushed onto the
12975 * integer stack. */
12976 /* But for binary operators, "apply" everything on the operator
12977 * stack until we find an operator with a lesser priority than the
12978 * one we have just extracted. */
12979 /* Left paren is given the lowest priority so it will never be
12980 * "applied" in this way.
12981 * if associativity is right and priority eq, applied also skip
12984 if ((prec > 0 && prec < UNARYPREC) || prec == SPEC_PREC) {
12985 /* not left paren or unary */
12986 if (lasttok != TOK_NUM) {
12987 /* binary op must be preceded by a num */
12990 while (stackptr != stack) {
12991 if (op == TOK_RPAREN) {
12992 /* The algorithm employed here is simple: while we don't
12993 * hit an open paren nor the bottom of the stack, pop
12994 * tokens and apply them */
12995 if (stackptr[-1] == TOK_LPAREN) {
12997 /* Any operator directly after a */
12999 /* close paren should consider itself binary */
13003 operator prev_prec = PREC(stackptr[-1]);
13005 convert_prec_is_assing(prec);
13006 convert_prec_is_assing(prev_prec);
13007 if (prev_prec < prec)
13009 /* check right assoc */
13010 if (prev_prec == prec && is_right_associativity(prec))
13013 errcode = arith_apply(*--stackptr, numstack, &numstackptr);
13014 if (errcode) goto ret;
13016 if (op == TOK_RPAREN) {
13021 /* Push this operator to the stack and remember it. */
13022 *stackptr++ = lasttok = op;
13027 #endif /* ASH_MATH_SUPPORT */
13030 /* ============ main() and helpers
13032 * Main routine. We initialize things, parse the arguments, execute
13033 * profiles if we're a login shell, and then call cmdloop to execute
13034 * commands. The setjmp call sets up the location to jump to when an
13035 * exception occurs. When an exception occurs the variable "state"
13036 * is used to figure out how far we had gotten.
13039 static void init(void)
13041 /* from input.c: */
13042 basepf.nextc = basepf.buf = basebuf;
13045 signal(SIGCHLD, SIG_DFL);
13052 struct stat st1, st2;
13055 for (envp = environ; envp && *envp; envp++) {
13056 if (strchr(*envp, '=')) {
13057 setvareq(*envp, VEXPORT|VTEXTFIXED);
13061 snprintf(ppid, sizeof(ppid), "%d", (int) getppid());
13062 setvar("PPID", ppid, 0);
13064 p = lookupvar("PWD");
13066 if (*p != '/' || stat(p, &st1) || stat(".", &st2)
13067 || st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino)
13074 * Process the shell command line arguments.
13077 procargs(int argc, char **argv)
13080 const char *xminusc;
13087 for (i = 0; i < NOPTS; i++)
13093 if (*xargv == NULL) {
13095 ash_msg_and_raise_error(bb_msg_requires_arg, "-c");
13098 if (iflag == 2 && sflag == 1 && isatty(0) && isatty(1))
13102 for (i = 0; i < NOPTS; i++)
13103 if (optlist[i] == 2)
13108 /* POSIX 1003.2: first arg after -c cmd is $0, remainder $1... */
13113 } else if (!sflag) {
13114 setinputfile(*xargv, 0);
13117 commandname = arg0;
13120 shellparam.p = xargv;
13121 #if ENABLE_ASH_GETOPTS
13122 shellparam.optind = 1;
13123 shellparam.optoff = -1;
13125 /* assert(shellparam.malloc == 0 && shellparam.nparam == 0); */
13127 shellparam.nparam++;
13134 * Read /etc/profile or .profile.
13137 read_profile(const char *name)
13141 if (setinputfile(name, INPUT_PUSH_FILE | INPUT_NOFILE_OK) < 0)
13150 * This routine is called when an error or an interrupt occurs in an
13151 * interactive shell and control is returned to the main command loop.
13159 /* from input.c: */
13160 parselleft = parsenleft = 0; /* clear input buffer */
13162 /* from parser.c: */
13165 /* from redir.c: */
13170 static short profile_buf[16384];
13171 extern int etext();
13174 int ash_main(int argc, char **argv);
13175 int ash_main(int argc, char **argv)
13178 volatile int state;
13179 struct jmploc jmploc;
13180 struct stackmark smark;
13183 dash_errno = __errno_location();
13187 monitor(4, etext, profile_buf, sizeof(profile_buf), 50);
13190 #if ENABLE_FEATURE_EDITING
13191 line_input_state = new_line_input_t(FOR_SHELL | WITH_PATH_LOOKUP);
13194 if (setjmp(jmploc.loc)) {
13204 if (e == EXEXIT || s == 0 || iflag == 0 || shlvl)
13208 outcslow('\n', stderr);
13210 popstackmark(&smark);
13211 FORCE_INT_ON; /* enable interrupts */
13221 exception_handler = &jmploc;
13224 trputs("Shell args: ");
13227 rootpid = getpid();
13229 #if ENABLE_ASH_RANDOM_SUPPORT
13230 rseed = rootpid + time(NULL);
13233 setstackmark(&smark);
13234 procargs(argc, argv);
13235 #if ENABLE_FEATURE_EDITING_SAVEHISTORY
13237 const char *hp = lookupvar("HISTFILE");
13240 hp = lookupvar("HOME");
13242 char *defhp = concat_path_file(hp, ".ash_history");
13243 setvar("HISTFILE", defhp, 0);
13249 if (argv[0] && argv[0][0] == '-')
13253 read_profile("/etc/profile");
13256 read_profile(".profile");
13262 getuid() == geteuid() && getgid() == getegid() &&
13266 shinit = lookupvar("ENV");
13267 if (shinit != NULL && *shinit != '\0') {
13268 read_profile(shinit);
13274 evalstring(minusc, 0);
13276 if (sflag || minusc == NULL) {
13277 #if ENABLE_FEATURE_EDITING_SAVEHISTORY
13279 const char *hp = lookupvar("HISTFILE");
13282 line_input_state->hist_file = hp;
13285 state4: /* XXX ??? - why isn't this before the "if" statement */
13293 extern void _mcleanup(void);
13302 const char *applet_name = "debug stuff usage";
13303 int main(int argc, char **argv)
13305 return ash_main(argc, argv);
13311 * Copyright (c) 1989, 1991, 1993, 1994
13312 * The Regents of the University of California. All rights reserved.
13314 * This code is derived from software contributed to Berkeley by
13315 * Kenneth Almquist.
13317 * Redistribution and use in source and binary forms, with or without
13318 * modification, are permitted provided that the following conditions
13320 * 1. Redistributions of source code must retain the above copyright
13321 * notice, this list of conditions and the following disclaimer.
13322 * 2. Redistributions in binary form must reproduce the above copyright
13323 * notice, this list of conditions and the following disclaimer in the
13324 * documentation and/or other materials provided with the distribution.
13325 * 3. Neither the name of the University nor the names of its contributors
13326 * may be used to endorse or promote products derived from this software
13327 * without specific prior written permission.
13329 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
13330 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
13331 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
13332 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
13333 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
13334 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
13335 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
13336 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
13337 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
13338 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF