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 * This code is derived from software contributed to Berkeley by
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 * This version of ash is adapted from the source in Debian's ash 0.3.8-5
28 * Modified by Erik Andersen <andersee@debian.org> and
29 * Vladimir Oleynik <vodz@usa.net> to be used in busybox
32 * Original copyright notice is retained at the end of this file.
36 /* These defines allow you to adjust the feature set to be compiled
37 * into the ash shell. As a rule, enabling these options will make
38 * ash get bigger... With all of these options off, ash adds about
39 * 62k to busybox on an x86 system.*/
43 /* Enable job control. This allows you to run jobs in the background,
44 * which is great when ash is being used as an interactive shell, but
45 * it completely useless for is all you are doing is running scripts.
46 * This adds about 2.5k on an x86 system. */
49 /* This enables alias support in ash. If you want to support things
50 * like "alias ls='ls -l'" with ash, enable this. This is only useful
51 * when ash is used as an intractive shell. This adds about 1.5k */
54 /* If you need ash to act as a full Posix shell, with full math
55 * support, enable this. This option needs some work, since it
56 * doesn't compile right now... */
57 #undef ASH_MATH_SUPPORT
59 /* This shell builtin is used to indicate how the shell would interpret
60 * what you give it. This command is only useful when debugging, and
61 * is obsolete anyways. Adds about 670 bytes... You probably want to
62 * leave this disabled. */
65 /* Getopts is used by shell procedures to parse positional parameters.
66 * You probably want to leave this disabled, and use the busybox getopt
67 * applet if you want to do this sort of thing. There are some scripts
68 * out there that use it, so it you need it, enable. Most people will
69 * leave this disabled. This adds 1k on an x86 system. */
72 /* This allows you to override shell builtins and use whatever is on
73 * the filesystem. This is most useful when ash is acting as a
74 * standalone shell. Adds about 320 bytes. */
77 /* This makes a few common apps that are usually part of busybox
78 * anyways to be used as builtins. This may cause these builtins to be
79 * a little bit faster, but leaving this disabled will save you 2k. */
80 #undef ASH_BBAPPS_AS_BUILTINS
82 /* Enable this to compile in extra debugging noise. When debugging is
83 * on, debugging info will be written to $HOME/trace and a quit signal
84 * will generate a core dump. */
89 /* These are here to work with glibc -- Don't change these... */
109 #include <sysexits.h>
111 #include <sys/stat.h>
112 #include <sys/cdefs.h>
113 #include <sys/ioctl.h>
114 #include <sys/param.h>
115 #include <sys/resource.h>
116 #include <sys/time.h>
117 #include <sys/times.h>
118 #include <sys/types.h>
119 #include <sys/wait.h>
122 #if !defined(FNMATCH_BROKEN)
125 #if !defined(GLOB_BROKEN)
136 /* if BB_PWD is defined, then disable ASH_PWD to save space */
143 * This file was generated by the mksyntax program.
147 #define CWORD 0 /* character is nothing special */
148 #define CNL 1 /* newline character */
149 #define CBACK 2 /* a backslash character */
150 #define CSQUOTE 3 /* single quote */
151 #define CDQUOTE 4 /* double quote */
152 #define CENDQUOTE 5 /* a terminating quote */
153 #define CBQUOTE 6 /* backwards single quote */
154 #define CVAR 7 /* a dollar sign */
155 #define CENDVAR 8 /* a '}' character */
156 #define CLP 9 /* a left paren in arithmetic */
157 #define CRP 10 /* a right paren in arithmetic */
158 #define CENDFILE 11 /* end of file */
159 #define CCTL 12 /* like CWORD, except it must be escaped */
160 #define CSPCL 13 /* these terminate a word */
161 #define CIGN 14 /* character should be ignored */
163 /* Syntax classes for is_ functions */
164 #define ISDIGIT 01 /* a digit */
165 #define ISUPPER 02 /* an upper case letter */
166 #define ISLOWER 04 /* a lower case letter */
167 #define ISUNDER 010 /* an underscore */
168 #define ISSPECL 020 /* the name of a special parameter */
185 #define TENDBQUOTE 10
207 #define BASESYNTAX (basesyntax + SYNBASE)
208 #define DQSYNTAX (dqsyntax + SYNBASE)
209 #define SQSYNTAX (sqsyntax + SYNBASE)
210 #define ARISYNTAX (arisyntax + SYNBASE)
212 /* control characters in argument strings */
213 #define CTLESC '\201'
214 #define CTLVAR '\202'
215 #define CTLENDVAR '\203'
216 #define CTLBACKQ '\204'
217 #define CTLQUOTE 01 /* ored with CTLBACKQ code if in quotes */
218 /* CTLBACKQ | CTLQUOTE == '\205' */
219 #define CTLARI '\206'
220 #define CTLENDARI '\207'
221 #define CTLQUOTEMARK '\210'
223 #define is_digit(c) ((((unsigned char)(c)) - '0') <= 9)
224 #define is_alpha(c) (((c) < CTLESC || (c) > CTLENDARI) && isalpha((unsigned char) (c)))
225 #define is_name(c) (((c) < CTLESC || (c) > CTLENDARI) && ((c) == '_' || isalpha((unsigned char) (c))))
226 #define is_in_name(c) (((c) < CTLESC || (c) > CTLENDARI) && ((c) == '_' || isalnum((unsigned char) (c))))
227 #define is_special(c) ((is_type+SYNBASE)[c] & (ISSPECL|ISDIGIT))
228 #define digit_val(c) ((c) - '0')
231 #define _DIAGASSERT(x)
235 #define S_DFL 1 /* default signal handling (SIG_DFL) */
236 #define S_CATCH 2 /* signal is caught */
237 #define S_IGN 3 /* signal is ignored (SIG_IGN) */
238 #define S_HARD_IGN 4 /* signal is ignored permenantly */
239 #define S_RESET 5 /* temporary - to reset a hard ignored sig */
242 /* variable substitution byte (follows CTLVAR) */
243 #define VSTYPE 0x0f /* type of variable substitution */
244 #define VSNUL 0x10 /* colon--treat the empty string as unset */
245 #define VSQUOTE 0x80 /* inside double quotes--suppress splitting */
247 /* values of VSTYPE field */
248 #define VSNORMAL 0x1 /* normal variable: $var or ${var} */
249 #define VSMINUS 0x2 /* ${var-text} */
250 #define VSPLUS 0x3 /* ${var+text} */
251 #define VSQUESTION 0x4 /* ${var?message} */
252 #define VSASSIGN 0x5 /* ${var=text} */
253 #define VSTRIMLEFT 0x6 /* ${var#pattern} */
254 #define VSTRIMLEFTMAX 0x7 /* ${var##pattern} */
255 #define VSTRIMRIGHT 0x8 /* ${var%pattern} */
256 #define VSTRIMRIGHTMAX 0x9 /* ${var%%pattern} */
257 #define VSLENGTH 0xa /* ${#var} */
259 /* flags passed to redirect */
260 #define REDIR_PUSH 01 /* save previous values of file descriptors */
261 #define REDIR_BACKQ 02 /* save the command output in memory */
264 * BSD setjmp saves the signal mask, which violates ANSI C and takes time,
265 * so we use _setjmp instead.
268 #if !defined(__GLIBC__)
269 #define setjmp(jmploc) _setjmp(jmploc)
270 #define longjmp(jmploc, val) _longjmp(jmploc, val)
274 * Most machines require the value returned from malloc to be aligned
275 * in some way. The following macro will get this right on many machines.
284 #define ALIGN(nbytes) (((nbytes) + sizeof(union align) - 1) & ~(sizeof(union align) - 1))
287 #ifdef BB_LOCALE_SUPPORT
289 static void change_lc_all(const char *value);
290 static void change_lc_ctype(const char *value);
294 * These macros allow the user to suspend the handling of interrupt signals
295 * over a period of time. This is similar to SIGHOLD to or sigblock, but
296 * much more efficient and portable. (But hacking the kernel is so much
297 * more fun than worrying about efficiency and portability. :-))
300 static void onint (void);
301 static volatile int suppressint;
302 static volatile int intpending;
304 #define INTOFF suppressint++
305 #ifdef ASH_BBAPPS_AS_BUILTINS
306 #define INTON { if (--suppressint == 0 && intpending) onint(); }
308 static void __inton (void);
309 #define INTON __inton()
311 #define FORCEINTON {suppressint = 0; if (intpending) onint();}
312 #define CLEAR_PENDING_INT intpending = 0
313 #define int_pending() intpending
316 typedef void *pointer;
318 #define NULL (void *)0
321 static inline pointer ckmalloc (int sz) { return xmalloc(sz); }
322 static inline pointer ckrealloc(void *p, int sz) { return xrealloc(p, sz); }
323 static inline char * savestr (const char *s) { return xstrdup(s); }
325 static pointer stalloc (int);
326 static void stunalloc (pointer);
327 static void ungrabstackstr (char *, char *);
328 static char * growstackstr(void);
329 static char *sstrdup (const char *);
332 * Parse trees for commands are allocated in lifo order, so we use a stack
333 * to make this more efficient, and also to avoid all sorts of exception
334 * handling code to handle interrupts in the middle of a parse.
336 * The size 504 was chosen because the Ultrix malloc handles that size
340 #define MINSIZE 504 /* minimum size of a block */
344 struct stack_block *prev;
348 static struct stack_block stackbase;
349 static struct stack_block *stackp = &stackbase;
350 static struct stackmark *markp;
351 static char *stacknxt = stackbase.space;
352 static int stacknleft = MINSIZE;
355 #define equal(s1, s2) (strcmp(s1, s2) == 0)
357 #define stackblock() stacknxt
358 #define stackblocksize() stacknleft
359 #define STARTSTACKSTR(p) p = stackblock(), sstrnleft = stackblocksize()
360 #define STPUTC(c, p) (--sstrnleft >= 0? (*p++ = (c)) : (p = growstackstr(), *p++ = (c)))
361 #define CHECKSTRSPACE(n, p) { if (sstrnleft < n) p = makestrspace(n); }
362 #define USTPUTC(c, p) (--sstrnleft, *p++ = (c))
363 #define STACKSTRNUL(p) (sstrnleft == 0? (p = growstackstr(), *p = '\0') : (*p = '\0'))
364 #define STUNPUTC(p) (++sstrnleft, --p)
365 #define STTOPC(p) p[-1]
366 #define STADJUST(amount, p) (p += (amount), sstrnleft -= (amount))
367 #define grabstackstr(p) stalloc(stackblocksize() - sstrnleft)
369 #define ckfree(p) free((pointer)(p))
371 static char * makestrspace(size_t newlen);
374 #define TRACE(param) trace param
375 static void trace (const char *, ...);
376 static void trargs (char **);
377 static void showtree (union node *);
378 static void trputc (int);
379 static void trputs (const char *);
380 static void opentrace (void);
415 #define EXP_FULL 0x1 /* perform word splitting & file globbing */
416 #define EXP_TILDE 0x2 /* do normal tilde expansion */
417 #define EXP_VARTILDE 0x4 /* expand tildes in an assignment */
418 #define EXP_REDIR 0x8 /* file glob for a redirection (1 match only) */
419 #define EXP_CASE 0x10 /* keeps quotes around for CASE pattern */
420 #define EXP_RECORD 0x20 /* need to record arguments for ifs breakup */
425 static char optet_vals[NOPTS];
427 static const char * const optlist[NOPTS] = {
446 #define optent_name(optent) (optent+1)
447 #define optent_letter(optent) optent[0]
448 #define optent_val(optent) optet_vals[optent]
450 #define eflag optent_val(0)
451 #define fflag optent_val(1)
452 #define Iflag optent_val(2)
453 #define iflag optent_val(3)
454 #define mflag optent_val(4)
455 #define nflag optent_val(5)
456 #define sflag optent_val(6)
457 #define xflag optent_val(7)
458 #define vflag optent_val(8)
459 #define Vflag optent_val(9)
460 #define Eflag optent_val(10)
461 #define Cflag optent_val(11)
462 #define aflag optent_val(12)
463 #define bflag optent_val(13)
464 #define uflag optent_val(14)
465 #define qflag optent_val(15)
468 /* Mode argument to forkshell. Don't change FORK_FG or FORK_BG. */
486 union node *redirect;
493 struct nodelist *cmdlist;
500 union node *redirect;
508 union node *elsepart;
539 struct nodelist *backquote;
577 struct nbinary nbinary;
580 struct nredir nredir;
584 struct nclist nclist;
594 struct nodelist *next;
598 struct backcmd { /* result of evalbackcmd */
599 int fd; /* file descriptor to read from */
600 char *buf; /* buffer */
601 int nleft; /* number of chars in buffer */
602 struct job *jp; /* job structure for command */
610 const struct builtincmd *cmd;
615 struct strlist *next;
621 struct strlist *list;
622 struct strlist **lastp;
626 struct strpush *prev; /* preceding string on stack */
630 struct alias *ap; /* if push was associated with an alias */
632 char *string; /* remember the string since it may change */
636 struct parsefile *prev; /* preceding file on stack */
637 int linno; /* current line */
638 int fd; /* file descriptor (or -1 if string) */
639 int nleft; /* number of chars left in this line */
640 int lleft; /* number of chars left in this buffer */
641 char *nextc; /* next char in buffer */
642 char *buf; /* input buffer */
643 struct strpush *strpush; /* for pushing strings at this level */
644 struct strpush basestrpush; /* so pushing one is fast */
648 struct stack_block *stackp;
651 struct stackmark *marknext;
655 int nparam; /* # of positional parameters (without $0) */
656 unsigned char malloc; /* if parameter list dynamically allocated */
657 char **p; /* parameter list */
658 int optind; /* next parameter to be processed by getopts */
659 int optoff; /* used by getopts */
663 #ifdef USE_GLIBC_STDIO
674 #define OUTBUFSIZ BUFSIZ
675 #define MEM_OUT -3 /* output to dynamically allocated memory */
678 #ifdef USE_GLIBC_STDIO
679 static struct output output = {NULL, NULL, 0, NULL, 0, 1, 0};
680 static struct output errout = {NULL, NULL, 0, NULL, 0, 2, 0};
681 static struct output memout = {NULL, NULL, 0, NULL, 0, MEM_OUT, 0};
683 static struct output output = {NULL, 0, NULL, OUTBUFSIZ, 1, 0};
684 static struct output errout = {NULL, 0, NULL, 0, 2, 0};
685 static struct output memout = {NULL, 0, NULL, 0, MEM_OUT, 0};
687 static struct output *out1 = &output;
688 static struct output *out2 = &errout;
690 #ifndef USE_GLIBC_STDIO
691 static void outcslow (char, struct output *);
693 static void flushall (void);
694 static void flushout (struct output *);
695 static void freestdout (void);
696 static void outfmt (struct output *, const char *, ...)
697 __attribute__((__format__(__printf__,2,3)));
698 static void out1fmt (const char *, ...)
699 __attribute__((__format__(__printf__,1,2)));
700 static void fmtstr (char *, size_t, const char *, ...)
701 __attribute__((__format__(__printf__,3,4)));
702 #ifndef USE_GLIBC_STDIO
703 static void doformat (struct output *, const char *, va_list);
705 static int xwrite (int, const char *, int);
706 #ifdef USE_GLIBC_STDIO
707 static void initstreams (void);
708 static void openmemout (void);
709 static int __closememout (void);
712 static void outstr(const char *p, struct output *file);
714 #define OUTPUT_ERR 01 /* error occurred on output */
716 #ifdef USE_GLIBC_STDIO
717 #define outc(c, o) putc((c), (o)->stream)
718 #define doformat(d, f, a) vfprintf((d)->stream, (f), (a))
720 #define outc(c, file) (--(file)->nleft < 0? outcslow((c), (file)) : (*(file)->nextc = (c), (file)->nextc++))
722 #define out1c(c) outc((c), out1)
723 #define out2c(c) outc((c), out2)
724 #define out1str(s) outstr((s), out1)
725 #define out2str(s) outstr((s), out2)
726 #define outerr(f) ((f)->flags & OUTPUT_ERR)
728 /* syntax table used when not in quotes */
729 static const char basesyntax[257] = {
730 CENDFILE, CSPCL, CWORD, CCTL,
731 CCTL, CCTL, CCTL, CCTL,
732 CCTL, CCTL, CCTL, CWORD,
733 CWORD, CWORD, CWORD, CWORD,
734 CWORD, CWORD, CWORD, CWORD,
735 CWORD, CWORD, CWORD, CWORD,
736 CWORD, CWORD, CWORD, CWORD,
737 CWORD, CWORD, CWORD, CWORD,
738 CWORD, CWORD, CWORD, CWORD,
739 CWORD, CWORD, CWORD, CWORD,
740 CWORD, CWORD, CWORD, CWORD,
741 CWORD, CWORD, CWORD, CWORD,
742 CWORD, CWORD, CWORD, CWORD,
743 CWORD, CWORD, CWORD, CWORD,
744 CWORD, CWORD, CWORD, CWORD,
745 CWORD, CWORD, CWORD, CWORD,
746 CWORD, CWORD, CWORD, CWORD,
747 CWORD, CWORD, CWORD, CWORD,
748 CWORD, CWORD, CWORD, CWORD,
749 CWORD, CWORD, CWORD, CWORD,
750 CWORD, CWORD, CWORD, CWORD,
751 CWORD, CWORD, CWORD, CWORD,
752 CWORD, CWORD, CWORD, CWORD,
753 CWORD, CWORD, CWORD, CWORD,
754 CWORD, CWORD, CWORD, CWORD,
755 CWORD, CWORD, CWORD, CWORD,
756 CWORD, CWORD, CWORD, CWORD,
757 CWORD, CWORD, CWORD, CWORD,
758 CWORD, CWORD, CWORD, CWORD,
759 CWORD, CWORD, CWORD, CWORD,
760 CWORD, CWORD, CWORD, CWORD,
761 CWORD, CWORD, CWORD, CWORD,
762 CWORD, CWORD, CWORD, CWORD,
763 CWORD, CWORD, CWORD, CWORD,
764 CWORD, CWORD, CWORD, CSPCL,
765 CNL, CWORD, CWORD, CWORD,
766 CWORD, CWORD, CWORD, CWORD,
767 CWORD, CWORD, CWORD, CWORD,
768 CWORD, CWORD, CWORD, CWORD,
769 CWORD, CWORD, CWORD, CWORD,
770 CWORD, CWORD, CSPCL, CWORD,
771 CDQUOTE, CWORD, CVAR, CWORD,
772 CSPCL, CSQUOTE, CSPCL, CSPCL,
773 CWORD, CWORD, CWORD, CWORD,
774 CWORD, CWORD, CWORD, CWORD,
775 CWORD, CWORD, CWORD, CWORD,
776 CWORD, CWORD, CWORD, CWORD,
777 CWORD, CSPCL, CSPCL, CWORD,
778 CSPCL, CWORD, CWORD, CWORD,
779 CWORD, CWORD, CWORD, CWORD,
780 CWORD, CWORD, CWORD, CWORD,
781 CWORD, CWORD, CWORD, CWORD,
782 CWORD, CWORD, CWORD, CWORD,
783 CWORD, CWORD, CWORD, CWORD,
784 CWORD, CWORD, CWORD, CWORD,
785 CWORD, CWORD, CBACK, CWORD,
786 CWORD, CWORD, CBQUOTE, CWORD,
787 CWORD, CWORD, CWORD, CWORD,
788 CWORD, CWORD, CWORD, CWORD,
789 CWORD, CWORD, CWORD, CWORD,
790 CWORD, CWORD, CWORD, CWORD,
791 CWORD, CWORD, CWORD, CWORD,
792 CWORD, CWORD, CWORD, CWORD,
793 CWORD, CWORD, CSPCL, CENDVAR,
797 /* syntax table used when in double quotes */
798 static const char dqsyntax[257] = {
799 CENDFILE, CIGN, CWORD, CCTL,
800 CCTL, CCTL, CCTL, CCTL,
801 CCTL, CCTL, CCTL, CWORD,
802 CWORD, CWORD, CWORD, CWORD,
803 CWORD, CWORD, CWORD, CWORD,
804 CWORD, CWORD, CWORD, CWORD,
805 CWORD, CWORD, CWORD, CWORD,
806 CWORD, CWORD, CWORD, CWORD,
807 CWORD, CWORD, CWORD, CWORD,
808 CWORD, CWORD, CWORD, CWORD,
809 CWORD, CWORD, CWORD, CWORD,
810 CWORD, CWORD, CWORD, CWORD,
811 CWORD, CWORD, CWORD, CWORD,
812 CWORD, CWORD, CWORD, CWORD,
813 CWORD, CWORD, CWORD, CWORD,
814 CWORD, CWORD, CWORD, CWORD,
815 CWORD, CWORD, CWORD, CWORD,
816 CWORD, CWORD, CWORD, CWORD,
817 CWORD, CWORD, CWORD, CWORD,
818 CWORD, CWORD, CWORD, CWORD,
819 CWORD, CWORD, CWORD, CWORD,
820 CWORD, CWORD, CWORD, CWORD,
821 CWORD, CWORD, CWORD, CWORD,
822 CWORD, CWORD, CWORD, CWORD,
823 CWORD, CWORD, CWORD, CWORD,
824 CWORD, CWORD, CWORD, CWORD,
825 CWORD, CWORD, CWORD, CWORD,
826 CWORD, CWORD, CWORD, CWORD,
827 CWORD, CWORD, CWORD, CWORD,
828 CWORD, CWORD, CWORD, CWORD,
829 CWORD, CWORD, CWORD, CWORD,
830 CWORD, CWORD, CWORD, CWORD,
831 CWORD, CWORD, CWORD, CWORD,
832 CWORD, CWORD, CWORD, CWORD,
833 CWORD, CWORD, CWORD, CWORD,
834 CNL, CWORD, CWORD, CWORD,
835 CWORD, CWORD, CWORD, CWORD,
836 CWORD, CWORD, CWORD, CWORD,
837 CWORD, CWORD, CWORD, CWORD,
838 CWORD, CWORD, CWORD, CWORD,
839 CWORD, CWORD, CWORD, CCTL,
840 CENDQUOTE,CWORD, CVAR, CWORD,
841 CWORD, CWORD, CWORD, CWORD,
842 CCTL, CWORD, CWORD, CCTL,
843 CWORD, CCTL, CWORD, CWORD,
844 CWORD, CWORD, CWORD, CWORD,
845 CWORD, CWORD, CWORD, CWORD,
846 CCTL, CWORD, CWORD, CCTL,
847 CWORD, CCTL, CWORD, CWORD,
848 CWORD, CWORD, CWORD, CWORD,
849 CWORD, CWORD, CWORD, CWORD,
850 CWORD, CWORD, CWORD, CWORD,
851 CWORD, CWORD, CWORD, CWORD,
852 CWORD, CWORD, CWORD, CWORD,
853 CWORD, CWORD, CWORD, CWORD,
854 CWORD, CCTL, CBACK, CCTL,
855 CWORD, CWORD, CBQUOTE, CWORD,
856 CWORD, CWORD, CWORD, CWORD,
857 CWORD, CWORD, CWORD, CWORD,
858 CWORD, CWORD, CWORD, CWORD,
859 CWORD, CWORD, CWORD, CWORD,
860 CWORD, CWORD, CWORD, CWORD,
861 CWORD, CWORD, CWORD, CWORD,
862 CWORD, CWORD, CWORD, CENDVAR,
866 /* syntax table used when in single quotes */
867 static const char sqsyntax[257] = {
868 CENDFILE, CIGN, CWORD, CCTL,
869 CCTL, CCTL, CCTL, CCTL,
870 CCTL, CCTL, CCTL, CWORD,
871 CWORD, CWORD, CWORD, CWORD,
872 CWORD, CWORD, CWORD, CWORD,
873 CWORD, CWORD, CWORD, CWORD,
874 CWORD, CWORD, CWORD, CWORD,
875 CWORD, CWORD, CWORD, CWORD,
876 CWORD, CWORD, CWORD, CWORD,
877 CWORD, CWORD, CWORD, CWORD,
878 CWORD, CWORD, CWORD, CWORD,
879 CWORD, CWORD, CWORD, CWORD,
880 CWORD, CWORD, CWORD, CWORD,
881 CWORD, CWORD, CWORD, CWORD,
882 CWORD, CWORD, CWORD, CWORD,
883 CWORD, CWORD, CWORD, CWORD,
884 CWORD, CWORD, CWORD, CWORD,
885 CWORD, CWORD, CWORD, CWORD,
886 CWORD, CWORD, CWORD, CWORD,
887 CWORD, CWORD, CWORD, CWORD,
888 CWORD, CWORD, CWORD, CWORD,
889 CWORD, CWORD, CWORD, CWORD,
890 CWORD, CWORD, CWORD, CWORD,
891 CWORD, CWORD, CWORD, CWORD,
892 CWORD, CWORD, CWORD, CWORD,
893 CWORD, CWORD, CWORD, CWORD,
894 CWORD, CWORD, CWORD, CWORD,
895 CWORD, CWORD, CWORD, CWORD,
896 CWORD, CWORD, CWORD, CWORD,
897 CWORD, CWORD, CWORD, CWORD,
898 CWORD, CWORD, CWORD, CWORD,
899 CWORD, CWORD, CWORD, CWORD,
900 CWORD, CWORD, CWORD, CWORD,
901 CWORD, CWORD, CWORD, CWORD,
902 CWORD, CWORD, CWORD, CWORD,
903 CNL, CWORD, CWORD, CWORD,
904 CWORD, CWORD, CWORD, CWORD,
905 CWORD, CWORD, CWORD, CWORD,
906 CWORD, CWORD, CWORD, CWORD,
907 CWORD, CWORD, CWORD, CWORD,
908 CWORD, CWORD, CWORD, CCTL,
909 CWORD, CWORD, CWORD, CWORD,
910 CWORD, CENDQUOTE,CWORD, CWORD,
911 CCTL, CWORD, CWORD, CCTL,
912 CWORD, CCTL, CWORD, CWORD,
913 CWORD, CWORD, CWORD, CWORD,
914 CWORD, CWORD, CWORD, CWORD,
915 CCTL, CWORD, CWORD, CCTL,
916 CWORD, CCTL, CWORD, CWORD,
917 CWORD, CWORD, CWORD, CWORD,
918 CWORD, CWORD, CWORD, CWORD,
919 CWORD, CWORD, CWORD, CWORD,
920 CWORD, CWORD, CWORD, CWORD,
921 CWORD, CWORD, CWORD, CWORD,
922 CWORD, CWORD, CWORD, CWORD,
923 CWORD, CCTL, CCTL, CCTL,
924 CWORD, CWORD, CWORD, CWORD,
925 CWORD, CWORD, CWORD, CWORD,
926 CWORD, CWORD, CWORD, CWORD,
927 CWORD, CWORD, CWORD, CWORD,
928 CWORD, CWORD, CWORD, CWORD,
929 CWORD, CWORD, CWORD, CWORD,
930 CWORD, CWORD, CWORD, CWORD,
931 CWORD, CWORD, CWORD, CWORD,
935 /* syntax table used when in arithmetic */
936 static const char arisyntax[257] = {
937 CENDFILE, CIGN, CWORD, CCTL,
938 CCTL, CCTL, CCTL, CCTL,
939 CCTL, CCTL, CCTL, CWORD,
940 CWORD, CWORD, CWORD, CWORD,
941 CWORD, CWORD, CWORD, CWORD,
942 CWORD, CWORD, CWORD, CWORD,
943 CWORD, CWORD, CWORD, CWORD,
944 CWORD, CWORD, CWORD, CWORD,
945 CWORD, CWORD, CWORD, CWORD,
946 CWORD, CWORD, CWORD, CWORD,
947 CWORD, CWORD, CWORD, CWORD,
948 CWORD, CWORD, CWORD, CWORD,
949 CWORD, CWORD, CWORD, CWORD,
950 CWORD, CWORD, CWORD, CWORD,
951 CWORD, CWORD, CWORD, CWORD,
952 CWORD, CWORD, CWORD, CWORD,
953 CWORD, CWORD, CWORD, CWORD,
954 CWORD, CWORD, CWORD, CWORD,
955 CWORD, CWORD, CWORD, CWORD,
956 CWORD, CWORD, CWORD, CWORD,
957 CWORD, CWORD, CWORD, CWORD,
958 CWORD, CWORD, CWORD, CWORD,
959 CWORD, CWORD, CWORD, CWORD,
960 CWORD, CWORD, CWORD, CWORD,
961 CWORD, CWORD, CWORD, CWORD,
962 CWORD, CWORD, CWORD, CWORD,
963 CWORD, CWORD, CWORD, CWORD,
964 CWORD, CWORD, CWORD, CWORD,
965 CWORD, CWORD, CWORD, CWORD,
966 CWORD, CWORD, CWORD, CWORD,
967 CWORD, CWORD, CWORD, CWORD,
968 CWORD, CWORD, CWORD, CWORD,
969 CWORD, CWORD, CWORD, CWORD,
970 CWORD, CWORD, CWORD, CWORD,
971 CWORD, CWORD, CWORD, CWORD,
972 CNL, CWORD, CWORD, CWORD,
973 CWORD, CWORD, CWORD, CWORD,
974 CWORD, CWORD, CWORD, CWORD,
975 CWORD, CWORD, CWORD, CWORD,
976 CWORD, CWORD, CWORD, CWORD,
977 CWORD, CWORD, CWORD, CWORD,
978 CDQUOTE, CWORD, CVAR, CWORD,
979 CWORD, CSQUOTE, CLP, CRP,
980 CWORD, CWORD, CWORD, CWORD,
981 CWORD, CWORD, CWORD, CWORD,
982 CWORD, CWORD, CWORD, CWORD,
983 CWORD, CWORD, CWORD, CWORD,
984 CWORD, CWORD, CWORD, CWORD,
985 CWORD, CWORD, CWORD, CWORD,
986 CWORD, CWORD, CWORD, CWORD,
987 CWORD, CWORD, CWORD, CWORD,
988 CWORD, CWORD, CWORD, CWORD,
989 CWORD, CWORD, CWORD, CWORD,
990 CWORD, CWORD, CWORD, CWORD,
991 CWORD, CWORD, CWORD, CWORD,
992 CWORD, CWORD, CBACK, CWORD,
993 CWORD, CWORD, CBQUOTE, CWORD,
994 CWORD, CWORD, CWORD, CWORD,
995 CWORD, CWORD, CWORD, CWORD,
996 CWORD, CWORD, CWORD, CWORD,
997 CWORD, CWORD, CWORD, CWORD,
998 CWORD, CWORD, CWORD, CWORD,
999 CWORD, CWORD, CWORD, CWORD,
1000 CWORD, CWORD, CWORD, CENDVAR,
1004 /* character classification table */
1005 static const char is_type[257] = {
1047 0, ISSPECL, ISSPECL, 0,
1049 ISSPECL, 0, 0, ISSPECL,
1050 0, 0, ISDIGIT, ISDIGIT,
1051 ISDIGIT, ISDIGIT, ISDIGIT, ISDIGIT,
1052 ISDIGIT, ISDIGIT, ISDIGIT, ISDIGIT,
1054 0, ISSPECL, ISSPECL, ISUPPER,
1055 ISUPPER, ISUPPER, ISUPPER, ISUPPER,
1056 ISUPPER, ISUPPER, ISUPPER, ISUPPER,
1057 ISUPPER, ISUPPER, ISUPPER, ISUPPER,
1058 ISUPPER, ISUPPER, ISUPPER, ISUPPER,
1059 ISUPPER, ISUPPER, ISUPPER, ISUPPER,
1060 ISUPPER, ISUPPER, ISUPPER, ISUPPER,
1062 0, ISUNDER, 0, ISLOWER,
1063 ISLOWER, ISLOWER, ISLOWER, ISLOWER,
1064 ISLOWER, ISLOWER, ISLOWER, ISLOWER,
1065 ISLOWER, ISLOWER, ISLOWER, ISLOWER,
1066 ISLOWER, ISLOWER, ISLOWER, ISLOWER,
1067 ISLOWER, ISLOWER, ISLOWER, ISLOWER,
1068 ISLOWER, ISLOWER, ISLOWER, ISLOWER,
1073 /* Array indicating which tokens mark the end of a list */
1074 static const char tokendlist[] = {
1107 static const char *const tokname[] = {
1140 #define KWDOFFSET 14
1142 static const char *const parsekwd[] = {
1162 static int plinno = 1; /* input line number */
1164 static int parselleft; /* copy of parsefile->lleft */
1166 static struct parsefile basepf; /* top level input file */
1167 static char basebuf[BUFSIZ]; /* buffer for top level input file */
1168 static struct parsefile *parsefile = &basepf; /* current input file */
1171 * NEOF is returned by parsecmd when it encounters an end of file. It
1172 * must be distinct from NULL, so we use the address of a variable that
1173 * happens to be handy.
1176 static int tokpushback; /* last token pushed back */
1177 #define NEOF ((union node *)&tokpushback)
1178 static int checkkwd; /* 1 == check for kwds, 2 == also eat newlines */
1181 static void error (const char *, ...) __attribute__((__noreturn__));
1182 static void exerror (int, const char *, ...) __attribute__((__noreturn__));
1183 static void shellexec (char **, char **, const char *, int)
1184 __attribute__((noreturn));
1185 static void exitshell (int) __attribute__((noreturn));
1187 static int goodname(const char *);
1188 static void ignoresig (int);
1189 static void onsig (int);
1190 static void dotrap (void);
1191 static int decode_signal (const char *, int);
1193 static void shprocvar(void);
1194 static void deletefuncs(void);
1195 static void setparam (char **);
1196 static void freeparam (volatile struct shparam *);
1198 /* reasons for skipping commands (see comment on breakcmd routine) */
1204 /* values of cmdtype */
1205 #define CMDUNKNOWN -1 /* no entry in table for command */
1206 #define CMDNORMAL 0 /* command is an executable program */
1207 #define CMDBUILTIN 1 /* command is a shell builtin */
1208 #define CMDFUNCTION 2 /* command is a shell function */
1210 #define DO_ERR 1 /* find_command prints errors */
1211 #define DO_ABS 2 /* find_command checks absolute paths */
1212 #define DO_NOFUN 4 /* find_command ignores functions */
1213 #define DO_BRUTE 8 /* find_command ignores hash table */
1220 #define VEXPORT 0x01 /* variable is exported */
1221 #define VREADONLY 0x02 /* variable cannot be modified */
1222 #define VSTRFIXED 0x04 /* variable struct is staticly allocated */
1223 #define VTEXTFIXED 0x08 /* text is staticly allocated */
1224 #define VSTACK 0x10 /* text is allocated on the stack */
1225 #define VUNSET 0x20 /* the variable is not set */
1226 #define VNOFUNC 0x40 /* don't call the callback function */
1230 struct var *next; /* next entry in hash list */
1231 int flags; /* flags are defined above */
1232 char *text; /* name=value */
1233 void (*func) (const char *);
1234 /* function to be called when */
1235 /* the variable gets set/unset */
1239 struct localvar *next; /* next local variable in list */
1240 struct var *vp; /* the variable that was made local */
1241 int flags; /* saved flags */
1242 char *text; /* saved text */
1246 #if defined(__GLIBC__) && !defined(FNMATCH_BROKEN)
1247 #define rmescapes(p) _rmescapes((p), 0)
1248 static char *_rmescapes (char *, int);
1250 static void rmescapes (char *);
1253 static int casematch (union node *, const char *);
1254 static void clearredir(void);
1255 static void popstring(void);
1256 static void readcmdfile (const char *);
1258 static int number (const char *);
1259 static int is_number (const char *, int *num);
1260 static char *single_quote (const char *);
1261 static int nextopt (const char *);
1263 static void redirect (union node *, int);
1264 static void popredir (void);
1265 static int dup_as_newfd (int, int);
1267 static void changepath(const char *newval);
1268 static void getoptsreset(const char *value);
1271 static int parsenleft; /* copy of parsefile->nleft */
1272 static char *parsenextc; /* copy of parsefile->nextc */
1273 static int rootpid; /* pid of main shell */
1274 static int rootshell; /* true if we aren't a child of the main shell */
1276 static const char spcstr[] = " ";
1277 static const char snlfmt[] = "%s\n";
1279 static int sstrnleft;
1280 static int herefd = -1;
1282 static struct localvar *localvars;
1284 static struct var vifs;
1285 static struct var vmail;
1286 static struct var vmpath;
1287 static struct var vpath;
1288 static struct var vps1;
1289 static struct var vps2;
1290 static struct var voptind;
1291 #ifdef BB_LOCALE_SUPPORT
1292 static struct var vlc_all;
1293 static struct var vlc_ctype;
1300 void (*func) (const char *);
1303 static const char defpathvar[] =
1304 "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin";
1305 #define defpath (defpathvar + 5)
1308 static const char defifsvar[] = "IFS= \t\n";
1309 #define defifs (defifsvar + 4)
1311 static const char defifs[] = " \t\n";
1314 static const struct varinit varinit[] = {
1316 { &vifs, VSTRFIXED|VTEXTFIXED, defifsvar,
1318 { &vifs, VSTRFIXED|VTEXTFIXED|VUNSET, "IFS=",
1321 { &vmail, VSTRFIXED|VTEXTFIXED|VUNSET, "MAIL=",
1323 { &vmpath, VSTRFIXED|VTEXTFIXED|VUNSET, "MAILPATH=",
1325 { &vpath, VSTRFIXED|VTEXTFIXED, defpathvar,
1328 * vps1 depends on uid
1330 { &vps2, VSTRFIXED|VTEXTFIXED, "PS2=> ",
1332 { &voptind, VSTRFIXED|VTEXTFIXED, "OPTIND=1",
1334 #ifdef BB_LOCALE_SUPPORT
1335 { &vlc_all, VSTRFIXED|VTEXTFIXED|VUNSET, "LC_ALL=",
1337 { &vlc_ctype, VSTRFIXED|VTEXTFIXED|VUNSET, "LC_CTYPE=",
1346 static struct var *vartab[VTABSIZE];
1349 * The following macros access the values of the above variables.
1350 * They have to skip over the name. They return the null string
1351 * for unset variables.
1354 #define ifsval() (vifs.text + 4)
1355 #define ifsset() ((vifs.flags & VUNSET) == 0)
1356 #define mailval() (vmail.text + 5)
1357 #define mpathval() (vmpath.text + 9)
1358 #define pathval() (vpath.text + 5)
1359 #define ps1val() (vps1.text + 4)
1360 #define ps2val() (vps2.text + 4)
1361 #define optindval() (voptind.text + 7)
1363 #define mpathset() ((vmpath.flags & VUNSET) == 0)
1365 static void initvar (void);
1366 static void setvar (const char *, const char *, int);
1367 static void setvareq (char *, int);
1368 static void listsetvar (struct strlist *);
1369 static char *lookupvar (const char *);
1370 static char *bltinlookup (const char *);
1371 static char **environment (void);
1372 static int showvarscmd (int, char **);
1373 static void mklocal (char *);
1374 static void poplocalvars (void);
1375 static int unsetvar (const char *);
1376 static int varequal (const char *, const char *);
1379 static char *arg0; /* value of $0 */
1380 static struct shparam shellparam; /* current positional parameters */
1381 static char **argptr; /* argument list for builtin commands */
1382 static char *optionarg; /* set by nextopt (like getopt) */
1383 static char *optptr; /* used by nextopt */
1384 static char *minusc; /* argument to -c option */
1389 #define ALIASINUSE 1
1399 static struct alias *atab[ATABSIZE];
1401 static void setalias (char *, char *);
1402 static struct alias **hashalias (const char *);
1403 static struct alias *freealias (struct alias *);
1404 static struct alias **__lookupalias (const char *);
1410 struct alias *ap, **app;
1412 app = __lookupalias(name);
1416 if (!(ap->flag & ALIASINUSE)) {
1419 ap->val = savestr(val);
1420 ap->flag &= ~ALIASDEAD;
1423 ap = ckmalloc(sizeof (struct alias));
1424 ap->name = savestr(name);
1425 ap->val = savestr(val);
1438 app = __lookupalias(name);
1442 *app = freealias(*app);
1453 struct alias *ap, **app;
1457 for (i = 0; i < ATABSIZE; i++) {
1459 for (ap = *app; ap; ap = *app) {
1460 *app = freealias(*app);
1469 static struct alias *
1470 lookupalias(const char *name, int check)
1472 struct alias *ap = *__lookupalias(name);
1474 if (check && ap && (ap->flag & ALIASINUSE))
1480 printalias(const struct alias *ap) {
1483 p = single_quote(ap->val);
1484 out1fmt("alias %s=%s\n", ap->name, p);
1490 * TODO - sort output
1493 aliascmd(int argc, char **argv)
1502 for (i = 0; i < ATABSIZE; i++)
1503 for (ap = atab[i]; ap; ap = ap->next) {
1508 while ((n = *++argv) != NULL) {
1509 if ((v = strchr(n+1, '=')) == NULL) { /* n+1: funny ksh stuff */
1510 if ((ap = *__lookupalias(n)) == NULL) {
1511 outfmt(out2, "%s: %s not found\n", "alias", n);
1526 unaliascmd(int argc, char **argv)
1530 while ((i = nextopt("a")) != '\0') {
1536 for (i = 0; *argptr; argptr++) {
1537 if (unalias(*argptr)) {
1538 outfmt(out2, "%s: %s not found\n", "unalias", *argptr);
1546 static struct alias **
1550 unsigned int hashval;
1555 return &atab[hashval % ATABSIZE];
1558 static struct alias *
1559 freealias(struct alias *ap) {
1562 if (ap->flag & ALIASINUSE) {
1563 ap->flag |= ALIASDEAD;
1575 static struct alias **
1576 __lookupalias(const char *name) {
1577 struct alias **app = hashalias(name);
1579 for (; *app; app = &(*app)->next) {
1580 if (equal(name, (*app)->name)) {
1589 #ifdef ASH_MATH_SUPPORT
1590 /* The generated file arith.c has been snipped. If you want this
1591 * stuff back in, feel free to add it to your own copy. */
1592 #define ARITH_NUM 257
1593 #define ARITH_LPAREN 258
1594 #define ARITH_RPAREN 259
1595 #define ARITH_OR 260
1596 #define ARITH_AND 261
1597 #define ARITH_BOR 262
1598 #define ARITH_BXOR 263
1599 #define ARITH_BAND 264
1600 #define ARITH_EQ 265
1601 #define ARITH_NE 266
1602 #define ARITH_LT 267
1603 #define ARITH_GT 268
1604 #define ARITH_GE 269
1605 #define ARITH_LE 270
1606 #define ARITH_LSHIFT 271
1607 #define ARITH_RSHIFT 272
1608 #define ARITH_ADD 273
1609 #define ARITH_SUB 274
1610 #define ARITH_MUL 275
1611 #define ARITH_DIV 276
1612 #define ARITH_REM 277
1613 #define ARITH_UNARYMINUS 278
1614 #define ARITH_UNARYPLUS 279
1615 #define ARITH_NOT 280
1616 #define ARITH_BNOT 281
1618 static void expari (int);
1620 static int arith (const char *);
1621 static int expcmd (int , char **);
1622 static void arith_lex_reset (void);
1623 static int yylex (void);
1627 static char *trap[NSIG]; /* trap handler commands */
1628 static char sigmode[NSIG - 1]; /* current value of signal */
1629 static char gotsig[NSIG - 1]; /* indicates specified signal received */
1630 static int pendingsigs; /* indicates some signal received */
1633 * This file was generated by the mkbuiltins program.
1637 static int bgcmd (int, char **);
1638 static int fgcmd (int, char **);
1639 static int killcmd (int, char **);
1641 #ifdef ASH_BBAPPS_AS_BUILTINS
1642 static int bltincmd (int, char **);
1644 static int cdcmd (int, char **);
1645 static int breakcmd (int, char **);
1647 static int commandcmd (int, char **);
1649 static int dotcmd (int, char **);
1650 static int evalcmd (int, char **);
1651 static int execcmd (int, char **);
1652 static int exitcmd (int, char **);
1653 static int exportcmd (int, char **);
1654 static int histcmd (int, char **);
1655 static int hashcmd (int, char **);
1656 static int jobscmd (int, char **);
1657 static int localcmd (int, char **);
1659 static int pwdcmd (int, char **);
1661 static int readcmd (int, char **);
1662 static int returncmd (int, char **);
1663 static int setcmd (int, char **);
1664 static int setvarcmd (int, char **);
1665 static int shiftcmd (int, char **);
1666 static int trapcmd (int, char **);
1667 static int umaskcmd (int, char **);
1669 static int aliascmd (int, char **);
1670 static int unaliascmd (int, char **);
1672 static int unsetcmd (int, char **);
1673 static int waitcmd (int, char **);
1674 static int ulimitcmd (int, char **);
1675 static int timescmd (int, char **);
1676 #ifdef ASH_MATH_SUPPORT
1677 static int expcmd (int, char **);
1680 static int typecmd (int, char **);
1683 static int getoptscmd (int, char **);
1686 #ifndef BB_TRUE_FALSE
1687 # ifdef ASH_BBAPPS_AS_BUILTINS
1688 static int true_main (int, char **);
1689 static int false_main (int, char **);
1693 static void setpwd (const char *, int);
1696 #define BUILTIN_NOSPEC "0"
1697 #define BUILTIN_SPECIAL "1"
1698 #define BUILTIN_REGULAR "2"
1699 #define BUILTIN_ASSIGN "4"
1700 #define BUILTIN_SPEC_ASSG "5"
1701 #define BUILTIN_REG_ASSG "6"
1703 #define IS_BUILTIN_SPECIAL(builtincmd) ((builtincmd)->name[0] & 1)
1704 #define IS_BUILTIN_REGULAR(builtincmd) ((builtincmd)->name[0] & 2)
1705 #define IS_BUILTIN_ASSIGN(builtincmd) ((builtincmd)->name[0] & 4)
1709 int (*const builtinfunc) (int, char **);
1714 /* It is CRUCIAL that this listing be kept in ascii order, otherwise
1715 * the binary search in find_builtin() will stop working. If you value
1716 * your kneecaps, you'll be sure to *make sure* that any changes made
1717 * to this array result in the listing remaining in ascii order. You
1720 static const struct builtincmd builtincmds[] = {
1721 { BUILTIN_SPECIAL ".", dotcmd },
1722 { BUILTIN_SPECIAL ":", true_main },
1724 { BUILTIN_REG_ASSG "alias", aliascmd },
1727 { BUILTIN_REGULAR "bg", bgcmd },
1729 { BUILTIN_SPECIAL "break", breakcmd },
1730 #ifdef ASH_BBAPPS_AS_BUILTINS
1731 { BUILTIN_SPECIAL "builtin", bltincmd },
1733 { BUILTIN_REGULAR "cd", cdcmd },
1734 #ifdef ASH_BBAPPS_AS_BUILTINS
1735 { BUILTIN_NOSPEC "chdir", cdcmd },
1738 { BUILTIN_REGULAR "command", commandcmd },
1740 { BUILTIN_SPECIAL "continue", breakcmd },
1741 { BUILTIN_SPECIAL "eval", evalcmd },
1742 { BUILTIN_SPECIAL "exec", execcmd },
1743 { BUILTIN_SPECIAL "exit", exitcmd },
1744 #ifdef ASH_MATH_SUPPORT
1745 { BUILTIN_NOSPEC "exp", expcmd },
1747 { BUILTIN_SPEC_ASSG "export", exportcmd },
1748 #ifdef ASH_BBAPPS_AS_BUILTINS
1749 { BUILTIN_REGULAR "false", false_main },
1751 { BUILTIN_REGULAR "fc", histcmd },
1753 { BUILTIN_REGULAR "fg", fgcmd },
1756 { BUILTIN_REGULAR "getopts", getoptscmd },
1758 { BUILTIN_NOSPEC "hash", hashcmd },
1759 { BUILTIN_REGULAR "jobs", jobscmd },
1761 { BUILTIN_REGULAR "kill", killcmd },
1763 #ifdef ASH_MATH_SUPPORT
1764 { BUILTIN_NOSPEC "let", expcmd },
1766 { BUILTIN_ASSIGN "local", localcmd },
1768 { BUILTIN_NOSPEC "pwd", pwdcmd },
1770 { BUILTIN_REGULAR "read", readcmd },
1771 { BUILTIN_SPEC_ASSG "readonly", exportcmd },
1772 { BUILTIN_SPECIAL "return", returncmd },
1773 { BUILTIN_SPECIAL "set", setcmd },
1774 { BUILTIN_NOSPEC "setvar", setvarcmd },
1775 { BUILTIN_SPECIAL "shift", shiftcmd },
1776 { BUILTIN_SPECIAL "times", timescmd },
1777 { BUILTIN_SPECIAL "trap", trapcmd },
1778 #ifdef ASH_BBAPPS_AS_BUILTINS
1779 { BUILTIN_REGULAR "true", true_main },
1782 { BUILTIN_NOSPEC "type", typecmd },
1784 { BUILTIN_NOSPEC "ulimit", ulimitcmd },
1785 { BUILTIN_REGULAR "umask", umaskcmd },
1787 { BUILTIN_REGULAR "unalias", unaliascmd },
1789 { BUILTIN_SPECIAL "unset", unsetcmd },
1790 { BUILTIN_REGULAR "wait", waitcmd },
1792 #define NUMBUILTINS (sizeof (builtincmds) / sizeof (struct builtincmd) )
1794 static const struct builtincmd *DOTCMD = &builtincmds[0];
1795 static struct builtincmd *BLTINCMD;
1796 static struct builtincmd *EXECCMD;
1797 static struct builtincmd *EVALCMD;
1800 #define JOBSTOPPED 1 /* all procs are stopped */
1801 #define JOBDONE 2 /* all procs are completed */
1804 * A job structure contains information about a job. A job is either a
1805 * single process or a set of processes contained in a pipeline. In the
1806 * latter case, pidlist will be non-NULL, and will point to a -1 terminated
1811 pid_t pid; /* process id */
1812 int status; /* status flags (defined above) */
1813 char *cmd; /* text of command being run */
1817 static int job_warning; /* user was warned about stopped jobs */
1820 static void setjobctl(int enable);
1822 #define setjobctl(on) /* do nothing */
1827 struct procstat ps0; /* status of process */
1828 struct procstat *ps; /* status or processes when more than one */
1829 short nprocs; /* number of processes */
1830 short pgrp; /* process group of this job */
1831 char state; /* true if job is finished */
1832 char used; /* true if this entry is in used */
1833 char changed; /* true if status has changed */
1835 char jobctl; /* job running under job control */
1839 static struct job *jobtab; /* array of jobs */
1840 static int njobs; /* size of array */
1841 static int backgndpid = -1; /* pid of last background process */
1843 static int initialpgrp; /* pgrp of shell on invocation */
1844 static int curjob; /* current job */
1847 static int intreceived;
1849 static struct job *makejob (union node *, int);
1850 static int forkshell (struct job *, union node *, int);
1851 static int waitforjob (struct job *);
1853 static int docd (char *, int);
1854 static char *getcomponent (void);
1855 static void updatepwd (const char *);
1856 static void getpwd (void);
1858 static char *padvance (const char **, const char *);
1860 static char nullstr[1]; /* zero length string */
1861 static char *curdir = nullstr; /* current working directory */
1862 static char *cdcomppath;
1876 if ((dest = *argptr) == NULL && (dest = bltinlookup("HOME")) == NULL)
1877 error("HOME not set");
1880 if (dest[0] == '-' && dest[1] == '\0') {
1881 dest = bltinlookup("OLDPWD");
1882 if (!dest || !*dest) {
1891 if (*dest == '/' || (path = bltinlookup("CDPATH")) == NULL)
1893 while ((p = padvance(&path, dest)) != NULL) {
1894 if (stat(p, &statb) >= 0 && S_ISDIR(statb.st_mode)) {
1899 if (p[0] == '.' && p[1] == '/' && p[2] != '\0')
1901 print = strcmp(p, dest);
1903 if (docd(p, print) >= 0)
1908 error("can't cd to %s", dest);
1914 * Actually do the chdir. In an interactive shell, print the
1915 * directory name if "print" is nonzero.
1930 TRACE(("docd(\"%s\", %d) called\n", dest, print));
1933 * Check each component of the path. If we find a symlink or
1934 * something we can't stat, clear curdir to force a getcwd()
1935 * next time we get the value of the current directory.
1938 cdcomppath = sstrdup(dest);
1945 while ((q = getcomponent()) != NULL) {
1946 if (q[0] == '\0' || (q[0] == '.' && q[1] == '\0'))
1954 if (equal(component, ".."))
1957 if ((lstat(stackblock(), &statb) < 0)
1958 || (S_ISLNK(statb.st_mode))) {
1966 if (chdir(dest) < 0) {
1970 updatepwd(badstat ? NULL : dest);
1973 out1fmt(snlfmt, curdir);
1979 * Get the next component of the path name pointed to by cdcomppath.
1980 * This routine overwrites the string pointed to by cdcomppath.
1988 if ((p = cdcomppath) == NULL)
1991 while (*p != '/' && *p != '\0')
2005 * Update curdir (the name of the current directory) in response to a
2006 * cd command. We also call hashcd to let the routines in exec.c know
2007 * that the current directory has changed.
2010 static void hashcd (void);
2013 updatepwd(const char *dir)
2019 hashcd(); /* update command hash table */
2022 * If our argument is NULL, we don't know the current directory
2023 * any more because we traversed a symbolic link or something
2024 * we couldn't stat().
2026 if (dir == NULL || curdir == nullstr) {
2031 cdcomppath = sstrdup(dir);
2040 while ((p = getcomponent()) != NULL) {
2041 if (equal(p, "..")) {
2042 while (new > stackblock() && (STUNPUTC(new), *new) != '/');
2043 } else if (*p != '\0' && ! equal(p, ".")) {
2049 if (new == stackblock())
2052 setpwd(stackblock(), 1);
2062 out1fmt(snlfmt, curdir);
2068 * Find out what the current directory is. If we already know the current
2069 * directory, this routine returns immediately.
2074 curdir = xgetcwd(0);
2080 setpwd(const char *val, int setold)
2083 setvar("OLDPWD", curdir, VEXPORT);
2086 if (curdir != nullstr) {
2093 curdir = savestr(val);
2096 setvar("PWD", curdir, VEXPORT);
2100 * Errors and exceptions.
2104 * Code to handle exceptions in C.
2108 * We enclose jmp_buf in a structure so that we can declare pointers to
2109 * jump locations. The global variable handler contains the location to
2110 * jump to when an exception occurs, and the global variable exception
2111 * contains a code identifying the exeception. To implement nested
2112 * exception handlers, the user should save the value of handler on entry
2113 * to an inner scope, set handler to point to a jmploc structure for the
2114 * inner scope, and restore handler on exit from the scope.
2122 #define EXINT 0 /* SIGINT received */
2123 #define EXERROR 1 /* a generic error */
2124 #define EXSHELLPROC 2 /* execute a shell procedure */
2125 #define EXEXEC 3 /* command execution failed */
2127 static struct jmploc *handler;
2128 static int exception;
2130 static void exverror (int, const char *, va_list)
2131 __attribute__((__noreturn__));
2134 * Called to raise an exception. Since C doesn't include exceptions, we
2135 * just do a longjmp to the exception handler. The type of exception is
2136 * stored in the global variable "exception".
2139 static void exraise (int) __attribute__((__noreturn__));
2145 if (handler == NULL)
2149 longjmp(handler->loc, 1);
2154 * Called from trap.c when a SIGINT is received. (If the user specifies
2155 * that SIGINT is to be trapped or ignored using the trap builtin, then
2156 * this routine is not called.) Suppressint is nonzero when interrupts
2157 * are held using the INTOFF macro. The call to _exit is necessary because
2158 * there is a short period after a fork before the signal handlers are
2159 * set to the appropriate value for the child. (The test for iflag is
2160 * just defensive programming.)
2172 sigemptyset(&mysigset);
2173 sigprocmask(SIG_SETMASK, &mysigset, NULL);
2174 if (rootshell && iflag)
2177 signal(SIGINT, SIG_DFL);
2184 static char *commandname; /* currently executing command */
2187 * Exverror is called to raise the error exception. If the first argument
2188 * is not NULL then error prints an error message using printf style
2189 * formatting. It then raises the error exception.
2192 exverror(int cond, const char *msg, va_list ap)
2199 TRACE(("exverror(%d, \"%s\") pid=%d\n", cond, msg, getpid()));
2201 TRACE(("exverror(%d, NULL) pid=%d\n", cond, getpid()));
2205 outfmt(&errout, "%s: ", commandname);
2206 doformat(&errout, msg, ap);
2208 outc('\n', &errout);
2210 outcslow('\n', &errout);
2221 error(const char *msg, ...)
2236 msg = va_arg(ap, const char *);
2238 exverror(EXERROR, msg, ap);
2246 exerror(int cond, const char *msg, ...)
2262 cond = va_arg(ap, int);
2263 msg = va_arg(ap, const char *);
2265 exverror(cond, msg, ap);
2273 * Table of error messages.
2277 short errcode; /* error number */
2278 short action; /* operation which encountered the error */
2282 * Types of operations (passed to the errmsg routine).
2285 #define E_OPEN 01 /* opening a file */
2286 #define E_CREAT 02 /* creating a file */
2287 #define E_EXEC 04 /* executing a program */
2289 #define ALL (E_OPEN|E_CREAT|E_EXEC)
2291 static const struct errname errormsg[] = {
2296 { ENOENT, E_CREAT },
2298 { ENOTDIR, E_OPEN },
2299 { ENOTDIR, E_CREAT },
2300 { ENOTDIR, E_EXEC },
2302 { EEXIST, E_CREAT },
2341 { ELIBACC, E_EXEC },
2345 #define ERRNAME_SIZE (sizeof(errormsg)/sizeof(struct errname))
2348 * Return a string describing an error. The returned string may be a
2349 * pointer to a static buffer that will be overwritten on the next call.
2350 * Action describes the operation that got the error.
2354 errmsg(int e, int action)
2356 struct errname const *ep;
2357 static char buf[12];
2359 for (ep = errormsg ; ep < errormsg+ERRNAME_SIZE; ep++) {
2360 if (ep->errcode == e && (ep->action & action) != 0)
2364 fmtstr(buf, sizeof buf, "error %d", e);
2369 #ifndef ASH_BBAPPS_AS_BUILTINS
2372 if (--suppressint == 0 && intpending) {
2378 /* flags in argument to evaltree */
2379 #define EV_EXIT 01 /* exit after evaluating tree */
2380 #define EV_TESTED 02 /* exit status is checked; ignore -e flag */
2381 #define EV_BACKCMD 04 /* command executing within back quotes */
2383 static int evalskip; /* set if we are skipping commands */
2384 static int skipcount; /* number of levels to skip */
2385 static int loopnest; /* current loop nesting level */
2386 static int funcnest; /* depth of function calls */
2390 static struct strlist *cmdenviron; /* environment for builtin command */
2391 static int exitstatus; /* exit status of last command */
2392 static int oexitstatus; /* saved exit status */
2395 static void evalloop (union node *, int);
2396 static void evalfor (union node *, int);
2397 static void evalcase (union node *, int);
2398 static void evalsubshell (union node *, int);
2399 static void expredir (union node *);
2400 static void evalpipe (union node *);
2402 static void evalcommand (union node *, int, struct backcmd *);
2404 static void evalcommand (union node *, int);
2406 static void prehash (union node *);
2407 static void eprintlist (struct strlist *);
2409 static union node *parsecmd(int);
2411 * Called to reset things after an exception.
2415 * The eval commmand.
2417 static void evalstring (char *, int);
2431 STARTSTACKSTR(concat);
2435 STPUTC(*p++, concat);
2436 if ((p = *ap++) == NULL)
2438 STPUTC(' ', concat);
2440 STPUTC('\0', concat);
2441 p = grabstackstr(concat);
2443 evalstring(p, EV_TESTED);
2449 * Execute a command or commands contained in a string.
2452 static void evaltree (union node *, int);
2453 static void setinputstring (char *);
2454 static void popfile (void);
2455 static void setstackmark(struct stackmark *mark);
2456 static void popstackmark(struct stackmark *mark);
2460 evalstring(char *s, int flag)
2463 struct stackmark smark;
2465 setstackmark(&smark);
2467 while ((n = parsecmd(0)) != NEOF) {
2469 popstackmark(&smark);
2472 popstackmark(&smark);
2476 * Evaluate a parse tree. The value is left in the global variable
2479 static struct builtincmd *find_builtin (const char *);
2480 static void defun (char *, union node *);
2489 TRACE(("evaltree(NULL) called\n"));
2492 TRACE(("evaltree(0x%lx: %d) called\n", (long)n, n->type));
2495 evaltree(n->nbinary.ch1, flags & EV_TESTED);
2498 evaltree(n->nbinary.ch2, flags);
2501 evaltree(n->nbinary.ch1, EV_TESTED);
2502 if (evalskip || exitstatus != 0)
2504 evaltree(n->nbinary.ch2, flags);
2507 evaltree(n->nbinary.ch1, EV_TESTED);
2508 if (evalskip || exitstatus == 0)
2510 evaltree(n->nbinary.ch2, flags);
2513 expredir(n->nredir.redirect);
2514 redirect(n->nredir.redirect, REDIR_PUSH);
2515 evaltree(n->nredir.n, flags);
2519 evalsubshell(n, flags);
2522 evalsubshell(n, flags);
2525 evaltree(n->nif.test, EV_TESTED);
2528 if (exitstatus == 0)
2529 evaltree(n->nif.ifpart, flags);
2530 else if (n->nif.elsepart)
2531 evaltree(n->nif.elsepart, flags);
2547 struct builtincmd *bcmd;
2549 (bcmd = find_builtin(n->narg.text)) &&
2550 IS_BUILTIN_SPECIAL(bcmd)
2552 outfmt(out2, "%s is a special built-in\n", n->narg.text);
2556 defun(n->narg.text, n->narg.next);
2561 evaltree(n->nnot.com, EV_TESTED);
2562 exitstatus = !exitstatus;
2571 evalcommand(n, flags, (struct backcmd *)NULL);
2573 evalcommand(n, flags);
2579 out1fmt("Node type = %d\n", n->type);
2580 #ifndef USE_GLIBC_STDIO
2591 (checkexit && eflag && exitstatus && !(flags & EV_TESTED))
2593 exitshell(exitstatus);
2607 evaltree(n->nbinary.ch1, EV_TESTED);
2609 skipping: if (evalskip == SKIPCONT && --skipcount <= 0) {
2613 if (evalskip == SKIPBREAK && --skipcount <= 0)
2617 if (n->type == NWHILE) {
2618 if (exitstatus != 0)
2621 if (exitstatus == 0)
2624 evaltree(n->nbinary.ch2, flags & EV_TESTED);
2625 status = exitstatus;
2630 exitstatus = status;
2633 static void expandarg (union node *, struct arglist *, int);
2634 static void fixredir(union node *n, const char *text, int err);
2641 struct arglist arglist;
2644 struct stackmark smark;
2646 setstackmark(&smark);
2647 arglist.lastp = &arglist.list;
2648 for (argp = n->nfor.args ; argp ; argp = argp->narg.next) {
2649 oexitstatus = exitstatus;
2650 expandarg(argp, &arglist, EXP_FULL | EXP_TILDE | EXP_RECORD);
2654 *arglist.lastp = NULL;
2658 for (sp = arglist.list ; sp ; sp = sp->next) {
2659 setvar(n->nfor.var, sp->text, 0);
2660 evaltree(n->nfor.body, flags & EV_TESTED);
2662 if (evalskip == SKIPCONT && --skipcount <= 0) {
2666 if (evalskip == SKIPBREAK && --skipcount <= 0)
2673 popstackmark(&smark);
2684 struct arglist arglist;
2685 struct stackmark smark;
2687 setstackmark(&smark);
2688 arglist.lastp = &arglist.list;
2689 oexitstatus = exitstatus;
2690 expandarg(n->ncase.expr, &arglist, EXP_TILDE);
2691 for (cp = n->ncase.cases ; cp && evalskip == 0 ; cp = cp->nclist.next) {
2692 for (patp = cp->nclist.pattern ; patp ; patp = patp->narg.next) {
2693 if (casematch(patp, arglist.list->text)) {
2694 if (evalskip == 0) {
2695 evaltree(cp->nclist.body, flags);
2702 popstackmark(&smark);
2706 * Kick off a subshell to evaluate a tree.
2710 evalsubshell(n, flags)
2715 int backgnd = (n->type == NBACKGND);
2717 expredir(n->nredir.redirect);
2719 if (forkshell(jp, n, backgnd) == 0) {
2721 flags &=~ EV_TESTED;
2722 redirect(n->nredir.redirect, 0);
2723 evaltree(n->nredir.n, flags | EV_EXIT); /* never returns */
2727 exitstatus = waitforjob(jp);
2735 * Compute the names of the files in a redirection list.
2744 for (redir = n ; redir ; redir = redir->nfile.next) {
2746 fn.lastp = &fn.list;
2747 oexitstatus = exitstatus;
2748 switch (redir->type) {
2754 expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR);
2755 redir->nfile.expfname = fn.list->text;
2759 if (redir->ndup.vname) {
2760 expandarg(redir->ndup.vname, &fn, EXP_FULL | EXP_TILDE);
2761 fixredir(redir, fn.list->text, 1);
2769 * Evaluate a pipeline. All the processes in the pipeline are children
2770 * of the process creating the pipeline. (This differs from some versions
2771 * of the shell, which make the last process in a pipeline the parent
2780 struct nodelist *lp;
2785 TRACE(("evalpipe(0x%lx) called\n", (long)n));
2787 for (lp = n->npipe.cmdlist ; lp ; lp = lp->next)
2790 jp = makejob(n, pipelen);
2792 for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
2796 if (pipe(pip) < 0) {
2798 error("Pipe call failed");
2801 if (forkshell(jp, lp->n, n->npipe.backgnd) == 0) {
2805 dup_as_newfd(prevfd, 0);
2817 dup_as_newfd(pip[1], 1);
2821 evaltree(lp->n, EV_EXIT);
2829 if (n->npipe.backgnd == 0) {
2831 exitstatus = waitforjob(jp);
2832 TRACE(("evalpipe: job done exit status %d\n", exitstatus));
2840 * Execute a command inside back quotes. If it's a builtin command, we
2841 * want to save its output in a block obtained from malloc. Otherwise
2842 * we fork off a subprocess and get the output of the command via a pipe.
2843 * Should be called with interrupts off.
2847 evalbackcmd(union node *n, struct backcmd *result)
2851 struct stackmark smark; /* unnecessary */
2853 setstackmark(&smark);
2864 * For now we disable executing builtins in the same
2865 * context as the shell, because we are not keeping
2866 * enough state to recover from changes that are
2867 * supposed only to affect subshells. eg. echo "`cd /`"
2869 if (n->type == NCMD) {
2870 exitstatus = oexitstatus;
2871 evalcommand(n, EV_BACKCMD, result);
2877 error("Pipe call failed");
2879 if (forkshell(jp, n, FORK_NOJOB) == 0) {
2884 dup_as_newfd(pip[1], 1);
2888 evaltree(n, EV_EXIT);
2891 result->fd = pip[0];
2895 popstackmark(&smark);
2896 TRACE(("evalbackcmd done: fd=%d buf=0x%x nleft=%d jp=0x%x\n",
2897 result->fd, result->buf, result->nleft, result->jp));
2903 * Execute a simple command.
2906 static void find_command (const char *, struct cmdentry *, int, const char *);
2909 isassignment(const char *word) {
2910 if (!is_name(*word)) {
2915 } while (is_in_name(*word));
2916 return *word == '=';
2921 evalcommand(cmd, flags, backcmd)
2924 struct backcmd *backcmd;
2926 evalcommand(cmd, flags)
2931 struct stackmark smark;
2933 struct arglist arglist;
2934 struct arglist varlist;
2943 struct cmdentry cmdentry;
2945 char *volatile savecmdname;
2946 volatile struct shparam saveparam;
2947 struct localvar *volatile savelocalvars;
2951 const struct builtincmd *firstbltin;
2952 struct jmploc *volatile savehandler;
2953 struct jmploc jmploc;
2955 /* Avoid longjmp clobbering */
2962 /* First expand the arguments. */
2963 TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags));
2964 setstackmark(&smark);
2965 arglist.lastp = &arglist.list;
2966 varlist.lastp = &varlist.list;
2968 oexitstatus = exitstatus;
2971 for (argp = cmd->ncmd.assign; argp; argp = argp->narg.next) {
2972 expandarg(argp, &varlist, EXP_VARTILDE);
2975 argp = cmd->ncmd.args; argp && !arglist.list;
2976 argp = argp->narg.next
2978 expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
2981 struct builtincmd *bcmd;
2983 bcmd = find_builtin(arglist.list->text);
2984 pseudovarflag = bcmd && IS_BUILTIN_ASSIGN(bcmd);
2985 for (; argp; argp = argp->narg.next) {
2986 if (pseudovarflag && isassignment(argp->narg.text)) {
2987 expandarg(argp, &arglist, EXP_VARTILDE);
2990 expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
2993 *arglist.lastp = NULL;
2994 *varlist.lastp = NULL;
2995 expredir(cmd->ncmd.redirect);
2997 for (sp = arglist.list ; sp ; sp = sp->next)
2999 argv = stalloc(sizeof (char *) * (argc + 1));
3001 for (sp = arglist.list ; sp ; sp = sp->next) {
3002 TRACE(("evalcommand arg: %s\n", sp->text));
3007 if (iflag && funcnest == 0 && argc > 0)
3011 /* Print the command if xflag is set. */
3016 outcslow('+', &errout);
3018 eprintlist(varlist.list);
3019 eprintlist(arglist.list);
3021 outc('\n', &errout);
3024 outcslow('\n', &errout);
3028 /* Now locate the command. */
3030 cmdentry.cmdtype = CMDBUILTIN;
3031 firstbltin = cmdentry.u.cmd = BLTINCMD;
3033 const char *oldpath;
3034 int findflag = DO_ERR;
3038 * Modify the command lookup path, if a PATH= assignment
3041 for (sp = varlist.list ; sp ; sp = sp->next)
3042 if (varequal(sp->text, defpathvar)) {
3043 path = sp->text + 5;
3044 findflag |= DO_BRUTE;
3047 oldfindflag = findflag;
3050 find_command(argv[0], &cmdentry, findflag, path);
3051 if (cmdentry.cmdtype == CMDUNKNOWN) { /* command not found */
3058 /* implement bltin and command here */
3059 if (cmdentry.cmdtype != CMDBUILTIN) {
3063 firstbltin = cmdentry.u.cmd;
3065 if (cmdentry.u.cmd == BLTINCMD) {
3067 struct builtincmd *bcmd;
3072 if (!(bcmd = find_builtin(*argv))) {
3073 outfmt(&errout, "%s: not found\n", *argv);
3080 cmdentry.u.cmd = bcmd;
3081 if (bcmd != BLTINCMD)
3085 if (cmdentry.u.cmd == find_builtin("command")) {
3090 if (*argv[0] == '-') {
3091 if (!equal(argv[0], "-p")) {
3101 findflag |= DO_BRUTE;
3104 findflag = oldfindflag;
3106 findflag |= DO_NOFUN;
3114 /* Fork off a child process if necessary. */
3115 if (cmd->ncmd.backgnd
3116 || (cmdentry.cmdtype == CMDNORMAL && (flags & EV_EXIT) == 0)
3118 || ((flags & EV_BACKCMD) != 0
3119 && (cmdentry.cmdtype != CMDBUILTIN
3120 || cmdentry.u.bcmd == DOTCMD
3121 || cmdentry.u.bcmd == EVALCMD))
3124 jp = makejob(cmd, 1);
3125 mode = cmd->ncmd.backgnd;
3127 if (flags & EV_BACKCMD) {
3130 error("Pipe call failed");
3133 if (forkshell(jp, cmd, mode) != 0)
3134 goto parent; /* at end of routine */
3136 if (flags & EV_BACKCMD) {
3141 dup_as_newfd(pip[1], 1);
3149 /* This is the child process if a fork occurred. */
3150 /* Execute the command. */
3151 if (cmdentry.cmdtype == CMDFUNCTION) {
3153 trputs("Shell function: "); trargs(argv);
3155 exitstatus = oexitstatus;
3156 redirect(cmd->ncmd.redirect, REDIR_PUSH);
3157 saveparam = shellparam;
3158 shellparam.malloc = 0;
3159 shellparam.nparam = argc - 1;
3160 shellparam.p = argv + 1;
3162 savelocalvars = localvars;
3165 if (setjmp(jmploc.loc)) {
3166 if (exception == EXSHELLPROC) {
3167 freeparam((volatile struct shparam *)
3170 saveparam.optind = shellparam.optind;
3171 saveparam.optoff = shellparam.optoff;
3172 freeparam(&shellparam);
3173 shellparam = saveparam;
3176 localvars = savelocalvars;
3177 handler = savehandler;
3178 longjmp(handler->loc, 1);
3180 savehandler = handler;
3182 for (sp = varlist.list ; sp ; sp = sp->next)
3185 evaltree(cmdentry.u.func, flags & EV_TESTED);
3189 localvars = savelocalvars;
3190 saveparam.optind = shellparam.optind;
3191 saveparam.optoff = shellparam.optoff;
3192 freeparam(&shellparam);
3193 shellparam = saveparam;
3194 handler = savehandler;
3197 if (evalskip == SKIPFUNC) {
3201 if (flags & EV_EXIT)
3202 exitshell(exitstatus);
3203 } else if (cmdentry.cmdtype == CMDBUILTIN) {
3205 trputs("builtin command: "); trargs(argv);
3207 mode = (cmdentry.u.cmd == EXECCMD)? 0 : REDIR_PUSH;
3209 if (flags == EV_BACKCMD) {
3210 #ifdef USE_GLIBC_STDIO
3214 memout.nextc = memout.buf;
3215 memout.bufsize = 64;
3217 mode |= REDIR_BACKQ;
3220 redirect(cmd->ncmd.redirect, mode);
3221 savecmdname = commandname;
3222 if (IS_BUILTIN_SPECIAL(firstbltin)) {
3223 listsetvar(varlist.list);
3225 cmdenviron = varlist.list;
3228 if (setjmp(jmploc.loc)) {
3230 exitstatus = (e == EXINT)? SIGINT+128 : 2;
3233 savehandler = handler;
3235 commandname = argv[0];
3237 optptr = NULL; /* initialize nextopt */
3238 exitstatus = (*cmdentry.u.cmd->builtinfunc)(argc, argv);
3241 exitstatus |= outerr(out1);
3246 if (e != EXSHELLPROC) {
3247 commandname = savecmdname;
3248 if (flags & EV_EXIT)
3249 exitshell(exitstatus);
3251 handler = savehandler;
3253 if ((e != EXERROR && e != EXEXEC)
3254 || cmdentry.u.cmd == BLTINCMD
3255 || cmdentry.u.cmd == DOTCMD
3256 || cmdentry.u.cmd == EVALCMD
3257 || cmdentry.u.cmd == EXECCMD)
3261 if (cmdentry.u.cmd != EXECCMD)
3264 if (flags == EV_BACKCMD) {
3266 #ifdef USE_GLIBC_STDIO
3267 if (__closememout())
3268 error("__closememout() failed: %m");
3270 backcmd->buf = memout.buf;
3271 #ifdef USE_GLIBC_STDIO
3272 backcmd->nleft = memout.bufsize;
3274 backcmd->nleft = memout.nextc - memout.buf;
3282 trputs("normal command: "); trargs(argv);
3284 redirect(cmd->ncmd.redirect, 0);
3286 for (sp = varlist.list ; sp ; sp = sp->next)
3287 setvareq(sp->text, VEXPORT|VSTACK);
3288 envp = environment();
3289 shellexec(argv, envp, path, cmdentry.u.index);
3293 parent: /* parent process gets here (if we forked) */
3294 if (mode == 0) { /* argument to fork */
3296 exitstatus = waitforjob(jp);
3299 } else if (mode == 2) {
3300 backcmd->fd = pip[0];
3308 setvar("_", lastarg, 0);
3309 popstackmark(&smark);
3315 * Search for a command. This is called before we fork so that the
3316 * location of the command will be available in the parent as well as
3317 * the child. The check for "goodname" is an overly conservative
3318 * check that the name will not be subject to expansion.
3325 struct cmdentry entry;
3327 if (n->type == NCMD && n->ncmd.args)
3328 if (goodname(n->ncmd.args->narg.text))
3329 find_command(n->ncmd.args->narg.text, &entry, 0,
3336 * Builtin commands. Builtin commands whose functions are closely
3337 * tied to evaluation are implemented here.
3341 * No command given, or a bltin command with no arguments. Set the
3342 * specified variables.
3346 bltincmd(argc, argv)
3351 * Preserve exitstatus of a previous possible redirection
3359 * Handle break and continue commands. Break, continue, and return are
3360 * all handled by setting the evalskip flag. The evaluation routines
3361 * above all check this flag, and if it is set they start skipping
3362 * commands rather than executing them. The variable skipcount is
3363 * the number of loops to break/continue, or the number of function
3364 * levels to return. (The latter is always 1.) It should probably
3365 * be an error to break out of more loops than exist, but it isn't
3366 * in the standard shell so we don't make it one here.
3370 breakcmd(argc, argv)
3374 int n = argc > 1 ? number(argv[1]) : 1;
3379 evalskip = (**argv == 'c')? SKIPCONT : SKIPBREAK;
3387 * The return command.
3391 returncmd(argc, argv)
3395 int ret = argc > 1 ? number(argv[1]) : oexitstatus;
3398 evalskip = SKIPFUNC;
3403 /* Do what ksh does; skip the rest of the file */
3404 evalskip = SKIPFILE;
3411 #ifndef BB_TRUE_FALSE
3412 #ifdef ASH_BBAPPS_AS_BUILTINS
3414 false_main(argc, argv)
3423 true_main(argc, argv)
3433 * Controls whether the shell is interactive or not.
3436 static void setsignal(int signo);
3437 static void chkmail(int silent);
3441 setinteractive(int on)
3443 static int is_interactive;
3445 if (on == is_interactive)
3451 is_interactive = on;
3457 setinteractive(iflag);
3470 iflag = 0; /* exit on error */
3473 for (sp = cmdenviron; sp ; sp = sp->next)
3474 setvareq(sp->text, VEXPORT|VSTACK);
3475 shellexec(argv + 1, environment(), pathval(), 0);
3481 eprintlist(struct strlist *sp)
3483 for (; sp; sp = sp->next) {
3484 outfmt(&errout, " %s",sp->text);
3488 * When commands are first encountered, they are entered in a hash table.
3489 * This ensures that a full path search will not have to be done for them
3490 * on each invocation.
3492 * We should investigate converting to a linear search, even though that
3493 * would make the command name "hash" a misnomer.
3495 #define CMDTABLESIZE 31 /* should be prime */
3496 #define ARB 1 /* actual size determined at run time */
3501 struct tblentry *next; /* next entry in hash chain */
3502 union param param; /* definition of builtin function */
3503 short cmdtype; /* index identifying command */
3504 char rehash; /* if set, cd done since entry created */
3505 char cmdname[ARB]; /* name of command */
3509 static struct tblentry *cmdtable[CMDTABLESIZE];
3510 static int builtinloc = -1; /* index in path of %builtin, or -1 */
3511 static int exerrno = 0; /* Last exec error */
3514 static void tryexec (char *, char **, char **);
3515 static void printentry (struct tblentry *, int);
3516 static void clearcmdentry (int);
3517 static struct tblentry *cmdlookup (const char *, int);
3518 static void delete_cmd_entry (void);
3520 static int describe_command (char *, int);
3522 static int path_change (const char *, int *);
3526 * Exec a program. Never returns. If you change this routine, you may
3527 * have to change the find_command routine as well.
3530 static const char *pathopt; /* set by padvance */
3533 shellexec(argv, envp, path, idx)
3534 char **argv, **envp;
3541 if (strchr(argv[0], '/') != NULL) {
3542 tryexec(argv[0], argv, envp);
3546 while ((cmdname = padvance(&path, argv[0])) != NULL) {
3547 if (--idx < 0 && pathopt == NULL) {
3548 tryexec(cmdname, argv, envp);
3549 if (errno != ENOENT && errno != ENOTDIR)
3556 /* Map to POSIX errors */
3568 exerror(EXEXEC, "%s: %s", argv[0], errmsg(e, E_EXEC));
3573 * Clear traps on a fork.
3579 for (tp = trap ; tp < &trap[NSIG] ; tp++) {
3580 if (*tp && **tp) { /* trap not NULL or SIG_IGN */
3585 setsignal(tp - trap);
3593 initshellproc(void) {
3619 /* from options.c: */
3623 for (i = 0; i < NOPTS; i++)
3639 for (sm = sigmode ; sm < sigmode + NSIG - 1; sm++) {
3651 static int preadbuffer(void);
3652 static void pushfile (void);
3653 static int preadfd (void);
3656 * Read a character from the script, returning PEOF on end of file.
3657 * Nul characters in the input are silently discarded.
3660 #ifdef ASH_BBAPPS_AS_BUILTINS
3661 #define pgetc_macro() (--parsenleft >= 0? *parsenextc++ : preadbuffer())
3665 return pgetc_macro();
3671 return --parsenleft >= 0? *parsenextc++ : preadbuffer();
3677 return pgetc_macro();
3683 * Undo the last call to pgetc. Only one character may be pushed back.
3684 * PEOF may be pushed back.
3696 struct parsefile *pf = parsefile;
3705 parsefile = pf->prev;
3707 parsenleft = parsefile->nleft;
3708 parselleft = parsefile->lleft;
3709 parsenextc = parsefile->nextc;
3710 plinno = parsefile->linno;
3716 * Return to top level.
3721 while (parsefile != &basepf)
3726 * Close the file(s) that the shell is reading commands from. Called
3727 * after a fork is done.
3733 if (parsefile->fd > 0) {
3734 close(parsefile->fd);
3741 * Like setinputfile, but takes an open file descriptor. Call this with
3746 setinputfd(fd, push)
3749 (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
3755 while (parsefile->strpush)
3759 if (parsefile->buf == NULL)
3760 parsefile->buf = ckmalloc(BUFSIZ);
3761 parselleft = parsenleft = 0;
3767 * Set the input to take input from a file. If push is set, push the
3768 * old input onto the stack first.
3772 setinputfile(const char *fname, int push)
3778 if ((fd = open(fname, O_RDONLY)) < 0)
3779 error("Can't open %s", fname);
3781 myfileno2 = dup_as_newfd(fd, 10);
3784 error("Out of file descriptors");
3787 setinputfd(fd, push);
3793 tryexec(cmd, argv, envp)
3800 execve(cmd, argv, envp);
3805 setinputfile(cmd, 0);
3806 commandname = arg0 = savestr(argv[0]);
3808 exraise(EXSHELLPROC);
3813 static char *commandtext (const union node *);
3816 * Do a path search. The variable path (passed by reference) should be
3817 * set to the start of the path before the first call; padvance will update
3818 * this value as it proceeds. Successive calls to padvance will return
3819 * the possible path expansions in sequence. If an option (indicated by
3820 * a percent sign) appears in the path entry then the global variable
3821 * pathopt will be set to point to it; otherwise pathopt will be set to
3825 static const char *pathopt;
3827 static void growstackblock(void);
3831 padvance(const char **path, const char *name)
3841 for (p = start ; *p && *p != ':' && *p != '%' ; p++);
3842 len = p - start + strlen(name) + 2; /* "2" is for '/' and '\0' */
3843 while (stackblocksize() < len)
3847 memcpy(q, start, p - start);
3855 while (*p && *p != ':') p++;
3861 return stalloc(len);
3866 /*** Command hashing code ***/
3874 struct tblentry **pp;
3875 struct tblentry *cmdp;
3878 struct cmdentry entry;
3882 while ((c = nextopt("rv")) != '\0') {
3886 } else if (c == 'v') {
3890 if (*argptr == NULL) {
3891 for (pp = cmdtable ; pp < &cmdtable[CMDTABLESIZE] ; pp++) {
3892 for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) {
3893 if (cmdp->cmdtype != CMDBUILTIN) {
3894 printentry(cmdp, verbose);
3901 while ((name = *argptr) != NULL) {
3902 if ((cmdp = cmdlookup(name, 0)) != NULL
3903 && (cmdp->cmdtype == CMDNORMAL
3904 || (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0)))
3906 find_command(name, &entry, DO_ERR, pathval());
3907 if (entry.cmdtype == CMDUNKNOWN) c = 1;
3909 cmdp = cmdlookup(name, 0);
3910 if (cmdp) printentry(cmdp, verbose);
3920 printentry(cmdp, verbose)
3921 struct tblentry *cmdp;
3928 if (cmdp->cmdtype == CMDNORMAL) {
3929 idx = cmdp->param.index;
3932 name = padvance(&path, cmdp->cmdname);
3934 } while (--idx >= 0);
3936 } else if (cmdp->cmdtype == CMDBUILTIN) {
3937 out1fmt("builtin %s", cmdp->cmdname);
3938 } else if (cmdp->cmdtype == CMDFUNCTION) {
3939 out1fmt("function %s", cmdp->cmdname);
3942 name = commandtext(cmdp->param.func);
3943 out1fmt(" %s", name);
3949 error("internal error: cmdtype %d", cmdp->cmdtype);
3952 out1fmt(snlfmt, cmdp->rehash ? "*" : nullstr);
3958 * Resolve a command name. If you change this routine, you may have to
3959 * change the shellexec routine as well.
3962 static int prefix (const char *, const char *);
3965 find_command(const char *name, struct cmdentry *entry, int act, const char *path)
3967 struct tblentry *cmdp;
3977 struct builtincmd *bcmd;
3979 /* If name contains a slash, don't use the hash table */
3980 if (strchr(name, '/') != NULL) {
3982 while (stat(name, &statb) < 0) {
3983 if (errno != ENOENT && errno != ENOTDIR)
3985 entry->cmdtype = CMDUNKNOWN;
3986 entry->u.index = -1;
3989 entry->cmdtype = CMDNORMAL;
3990 entry->u.index = -1;
3993 entry->cmdtype = CMDNORMAL;
3999 if (act & DO_BRUTE) {
4000 firstchange = path_change(path, &bltin);
4006 /* If name is in the table, and not invalidated by cd, we're done */
4007 if ((cmdp = cmdlookup(name, 0)) != NULL && cmdp->rehash == 0) {
4008 if (cmdp->cmdtype == CMDFUNCTION) {
4009 if (act & DO_NOFUN) {
4014 } else if (act & DO_BRUTE) {
4015 if ((cmdp->cmdtype == CMDNORMAL &&
4016 cmdp->param.index >= firstchange) ||
4017 (cmdp->cmdtype == CMDBUILTIN &&
4018 ((builtinloc < 0 && bltin >= 0) ?
4019 bltin : builtinloc) >= firstchange)) {
4020 /* need to recompute the entry */
4029 bcmd = find_builtin(name);
4030 regular = bcmd && IS_BUILTIN_REGULAR(bcmd);
4033 if (cmdp && (cmdp->cmdtype == CMDBUILTIN)) {
4036 } else if (act & DO_BRUTE) {
4037 if (firstchange == 0) {
4042 /* If %builtin not in path, check for builtin next */
4043 if (regular || (bltin < 0 && bcmd)) {
4046 entry->cmdtype = CMDBUILTIN;
4047 entry->u.cmd = bcmd;
4051 cmdp = cmdlookup(name, 1);
4052 cmdp->cmdtype = CMDBUILTIN;
4053 cmdp->param.cmd = bcmd;
4058 /* We have to search path. */
4059 prev = -1; /* where to start */
4060 if (cmdp && cmdp->rehash) { /* doing a rehash */
4061 if (cmdp->cmdtype == CMDBUILTIN)
4064 prev = cmdp->param.index;
4070 while ((fullname = padvance(&path, name)) != NULL) {
4071 stunalloc(fullname);
4073 if (idx >= firstchange) {
4077 if (prefix("builtin", pathopt)) {
4078 if ((bcmd = find_builtin(name))) {
4082 } else if (!(act & DO_NOFUN) &&
4083 prefix("func", pathopt)) {
4086 continue; /* ignore unimplemented options */
4089 /* if rehash, don't redo absolute path names */
4090 if (fullname[0] == '/' && idx <= prev &&
4091 idx < firstchange) {
4094 TRACE(("searchexec \"%s\": no change\n", name));
4097 while (stat(fullname, &statb) < 0) {
4098 if (errno != ENOENT && errno != ENOTDIR)
4102 e = EACCES; /* if we fail, this will be the error */
4103 if (!S_ISREG(statb.st_mode))
4105 if (pathopt) { /* this is a %func directory */
4106 stalloc(strlen(fullname) + 1);
4107 readcmdfile(fullname);
4108 if ((cmdp = cmdlookup(name, 0)) == NULL || cmdp->cmdtype != CMDFUNCTION)
4109 error("%s not defined in %s", name, fullname);
4110 stunalloc(fullname);
4113 TRACE(("searchexec \"%s\" returns \"%s\"\n", name, fullname));
4114 /* If we aren't called with DO_BRUTE and cmdp is set, it must
4115 be a function and we're being called with DO_NOFUN */
4117 entry->cmdtype = CMDNORMAL;
4118 entry->u.index = idx;
4122 cmdp = cmdlookup(name, 1);
4123 cmdp->cmdtype = CMDNORMAL;
4124 cmdp->param.index = idx;
4129 /* We failed. If there was an entry for this command, delete it */
4130 if (cmdp && updatetbl)
4133 outfmt(out2, "%s: %s\n", name, errmsg(e, E_EXEC));
4134 entry->cmdtype = CMDUNKNOWN;
4139 entry->cmdtype = cmdp->cmdtype;
4140 entry->u = cmdp->param;
4146 * Search the table of builtin commands.
4150 bstrcmp(const void *name, const void *b)
4152 return strcmp((const char *)name, (*(const char *const *) b)+1);
4155 static struct builtincmd *
4156 find_builtin(const char *name)
4158 struct builtincmd *bp;
4160 bp = bsearch(name, builtincmds, NUMBUILTINS, sizeof(struct builtincmd),
4168 * Called when a cd is done. Marks all commands so the next time they
4169 * are executed they will be rehashed.
4174 struct tblentry **pp;
4175 struct tblentry *cmdp;
4177 for (pp = cmdtable ; pp < &cmdtable[CMDTABLESIZE] ; pp++) {
4178 for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) {
4179 if (cmdp->cmdtype == CMDNORMAL
4180 || (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0))
4189 * Called before PATH is changed. The argument is the new value of PATH;
4190 * pathval() still returns the old value at this point. Called with
4195 changepath(const char *newval)
4200 firstchange = path_change(newval, &bltin);
4201 if (builtinloc < 0 && bltin >= 0)
4202 builtinloc = bltin; /* zap builtins */
4203 clearcmdentry(firstchange);
4209 * Clear out command entries. The argument specifies the first entry in
4210 * PATH which has changed.
4214 clearcmdentry(firstchange)
4217 struct tblentry **tblp;
4218 struct tblentry **pp;
4219 struct tblentry *cmdp;
4222 for (tblp = cmdtable ; tblp < &cmdtable[CMDTABLESIZE] ; tblp++) {
4224 while ((cmdp = *pp) != NULL) {
4225 if ((cmdp->cmdtype == CMDNORMAL &&
4226 cmdp->param.index >= firstchange)
4227 || (cmdp->cmdtype == CMDBUILTIN &&
4228 builtinloc >= firstchange)) {
4240 * Free a parse tree.
4244 freefunc(union node *n)
4252 * Delete all functions.
4257 struct tblentry **tblp;
4258 struct tblentry **pp;
4259 struct tblentry *cmdp;
4262 for (tblp = cmdtable ; tblp < &cmdtable[CMDTABLESIZE] ; tblp++) {
4264 while ((cmdp = *pp) != NULL) {
4265 if (cmdp->cmdtype == CMDFUNCTION) {
4267 freefunc(cmdp->param.func);
4280 * Locate a command in the command hash table. If "add" is nonzero,
4281 * add the command to the table if it is not already present. The
4282 * variable "lastcmdentry" is set to point to the address of the link
4283 * pointing to the entry, so that delete_cmd_entry can delete the
4287 static struct tblentry **lastcmdentry;
4289 static struct tblentry *
4290 cmdlookup(const char *name, int add)
4294 struct tblentry *cmdp;
4295 struct tblentry **pp;
4302 pp = &cmdtable[hashval % CMDTABLESIZE];
4303 for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) {
4304 if (equal(cmdp->cmdname, name))
4308 if (add && cmdp == NULL) {
4310 cmdp = *pp = ckmalloc(sizeof (struct tblentry) - ARB
4311 + strlen(name) + 1);
4313 cmdp->cmdtype = CMDUNKNOWN;
4315 strcpy(cmdp->cmdname, name);
4323 * Delete the command entry returned on the last lookup.
4327 delete_cmd_entry() {
4328 struct tblentry *cmdp;
4331 cmdp = *lastcmdentry;
4332 *lastcmdentry = cmdp->next;
4340 * Add a new command entry, replacing any existing command entry for
4345 addcmdentry(char *name, struct cmdentry *entry)
4347 struct tblentry *cmdp;
4350 cmdp = cmdlookup(name, 1);
4351 if (cmdp->cmdtype == CMDFUNCTION) {
4352 freefunc(cmdp->param.func);
4354 cmdp->cmdtype = entry->cmdtype;
4355 cmdp->param = entry->u;
4361 * Define a shell function.
4364 static union node *copyfunc(union node *);
4367 defun(char *name, union node *func)
4369 struct cmdentry entry;
4371 entry.cmdtype = CMDFUNCTION;
4372 entry.u.func = copyfunc(func);
4373 addcmdentry(name, &entry);
4378 * Delete a function if it exists.
4382 unsetfunc(char *name)
4384 struct tblentry *cmdp;
4386 if ((cmdp = cmdlookup(name, 0)) != NULL && cmdp->cmdtype == CMDFUNCTION) {
4387 freefunc(cmdp->param.func);
4393 * Wrapper around strcmp for qsort/bsearch/...
4396 pstrcmp(const void *a, const void *b)
4398 return strcmp((const char *) a, *(const char *const *) b);
4402 * Find a keyword is in a sorted array.
4405 static const char *const *
4406 findkwd(const char *s)
4408 return bsearch(s, parsekwd, sizeof(parsekwd) / sizeof(const char *),
4409 sizeof(const char *), pstrcmp);
4414 * Locate and print what a word is...
4425 for (i = 1; i < argc; i++) {
4426 err |= describe_command(argv[i], 1);
4432 describe_command(char *command, int verbose)
4434 struct cmdentry entry;
4435 struct tblentry *cmdp;
4437 const struct alias *ap;
4439 const char *path = pathval();
4445 /* First look at the keywords */
4446 if (findkwd(command)) {
4447 out1str(verbose ? " is a shell keyword" : command);
4452 /* Then look at the aliases */
4453 if ((ap = lookupalias(command, 0)) != NULL) {
4455 out1fmt(" is an alias for %s", ap->val);
4462 /* Then check if it is a tracked alias */
4463 if ((cmdp = cmdlookup(command, 0)) != NULL) {
4464 entry.cmdtype = cmdp->cmdtype;
4465 entry.u = cmdp->param;
4467 /* Finally use brute force */
4468 find_command(command, &entry, DO_ABS, path);
4471 switch (entry.cmdtype) {
4473 int j = entry.u.index;
4479 p = padvance(&path, command);
4486 cmdp ? " a tracked alias for" : nullstr, p
4496 out1str(" is a shell function");
4505 " is a %sshell builtin",
4506 IS_BUILTIN_SPECIAL(entry.u.cmd) ?
4507 "special " : nullstr
4516 out1str(": not found\n");
4529 commandcmd(argc, argv)
4534 int default_path = 0;
4535 int verify_only = 0;
4536 int verbose_verify_only = 0;
4538 while ((c = nextopt("pvV")) != '\0')
4547 verbose_verify_only = 1;
4551 "command: nextopt returned character code 0%o\n", c);
4555 if (default_path + verify_only + verbose_verify_only > 1 ||
4558 "command [-p] command [arg ...]\n");
4560 "command {-v|-V} command\n");
4565 if (verify_only || verbose_verify_only) {
4566 return describe_command(*argptr, verbose_verify_only);
4575 path_change(newval, bltin)
4579 const char *old, *new;
4585 firstchange = 9999; /* assume no change */
4591 if ((*old == '\0' && *new == ':')
4592 || (*old == ':' && *new == '\0'))
4594 old = new; /* ignore subsequent differences */
4598 if (*new == '%' && *bltin < 0 && prefix("builtin", new + 1))
4605 if (builtinloc >= 0 && *bltin < 0)
4610 * Routines to expand arguments to commands. We have to deal with
4611 * backquotes, shell variables, and file metacharacters.
4616 #define RMESCAPE_ALLOC 0x1 /* Allocate a new string */
4617 #define RMESCAPE_GLOB 0x2 /* Add backslashes for glob */
4620 * Structure specifying which parts of the string should be searched
4621 * for IFS characters.
4625 struct ifsregion *next; /* next region in list */
4626 int begoff; /* offset of start of region */
4627 int endoff; /* offset of end of region */
4628 int nulonly; /* search for nul bytes only */
4632 static char *expdest; /* output of current string */
4633 static struct nodelist *argbackq; /* list of back quote expressions */
4634 static struct ifsregion ifsfirst; /* first struct in list of ifs regions */
4635 static struct ifsregion *ifslastp; /* last struct in list */
4636 static struct arglist exparg; /* holds expanded arg list */
4638 static void argstr (char *, int);
4639 static char *exptilde (char *, int);
4640 static void expbackq (union node *, int, int);
4641 static int subevalvar (char *, char *, int, int, int, int, int);
4642 static char *evalvar (char *, int);
4643 static int varisset (char *, int);
4644 static void strtodest (const char *, const char *, int);
4645 static void varvalue (char *, int, int);
4646 static void recordregion (int, int, int);
4647 static void removerecordregions (int);
4648 static void ifsbreakup (char *, struct arglist *);
4649 static void ifsfree (void);
4650 static void expandmeta (struct strlist *, int);
4651 #if defined(__GLIBC__) && !defined(FNMATCH_BROKEN)
4652 #define preglob(p) _rmescapes((p), RMESCAPE_ALLOC | RMESCAPE_GLOB)
4653 #if !defined(GLOB_BROKEN)
4654 static void addglob (const glob_t *);
4657 #if !(defined(__GLIBC__) && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN))
4658 static void expmeta (char *, char *);
4660 #if !(defined(__GLIBC__) && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN))
4661 static struct strlist *expsort (struct strlist *);
4662 static struct strlist *msort (struct strlist *, int);
4664 #if defined(__GLIBC__) && !defined(FNMATCH_BROKEN)
4665 static int patmatch (char *, char *, int);
4666 static int patmatch2 (char *, char *, int);
4668 static int pmatch (char *, char *, int);
4669 #define patmatch2 patmatch
4671 static char *cvtnum (int, char *);
4674 * Expand shell variables and backquotes inside a here document.
4677 /* arg: the document, fd: where to write the expanded version */
4679 expandhere(union node *arg, int fd)
4682 expandarg(arg, (struct arglist *)NULL, 0);
4683 xwrite(fd, stackblock(), expdest - stackblock());
4688 * Perform variable substitution and command substitution on an argument,
4689 * placing the resulting list of arguments in arglist. If EXP_FULL is true,
4690 * perform splitting and file name expansion. When arglist is NULL, perform
4691 * here document expansion.
4695 expandarg(arg, arglist, flag)
4697 struct arglist *arglist;
4703 argbackq = arg->narg.backquote;
4704 STARTSTACKSTR(expdest);
4705 ifsfirst.next = NULL;
4707 argstr(arg->narg.text, flag);
4708 if (arglist == NULL) {
4709 return; /* here document expanded */
4711 STPUTC('\0', expdest);
4712 p = grabstackstr(expdest);
4713 exparg.lastp = &exparg.list;
4717 if (flag & EXP_FULL) {
4718 ifsbreakup(p, &exparg);
4719 *exparg.lastp = NULL;
4720 exparg.lastp = &exparg.list;
4721 expandmeta(exparg.list, flag);
4723 if (flag & EXP_REDIR) /*XXX - for now, just remove escapes */
4725 sp = (struct strlist *)stalloc(sizeof (struct strlist));
4728 exparg.lastp = &sp->next;
4731 *exparg.lastp = NULL;
4733 *arglist->lastp = exparg.list;
4734 arglist->lastp = exparg.lastp;
4741 * Perform variable and command substitution. If EXP_FULL is set, output CTLESC
4742 * characters to allow for further processing. Otherwise treat
4743 * $@ like $* since no splitting will be performed.
4752 int quotes = flag & (EXP_FULL | EXP_CASE); /* do CTLESC */
4755 if (*p == '~' && (flag & (EXP_TILDE | EXP_VARTILDE)))
4756 p = exptilde(p, flag);
4760 case CTLENDVAR: /* ??? */
4763 /* "$@" syntax adherence hack */
4764 if (p[0] == CTLVAR && p[2] == '@' && p[3] == '=')
4766 if ((flag & EXP_FULL) != 0)
4776 p = evalvar(p, flag);
4779 case CTLBACKQ|CTLQUOTE:
4780 expbackq(argbackq->n, c & CTLQUOTE, flag);
4781 argbackq = argbackq->next;
4783 #ifdef ASH_MATH_SUPPORT
4791 * sort of a hack - expand tildes in variable
4792 * assignments (after the first '=' and after ':'s).
4795 if (flag & EXP_VARTILDE && *p == '~') {
4802 p = exptilde(p, flag);
4818 char c, *startp = p;
4821 int quotes = flag & (EXP_FULL | EXP_CASE);
4823 while ((c = *p) != '\0') {
4830 if (flag & EXP_VARTILDE)
4840 if (*(startp+1) == '\0') {
4841 if ((home = lookupvar("HOME")) == NULL)
4844 if ((pw = getpwnam(startp+1)) == NULL)
4851 strtodest(home, SQSYNTAX, quotes);
4860 removerecordregions(int endoff)
4862 if (ifslastp == NULL)
4865 if (ifsfirst.endoff > endoff) {
4866 while (ifsfirst.next != NULL) {
4867 struct ifsregion *ifsp;
4869 ifsp = ifsfirst.next->next;
4870 ckfree(ifsfirst.next);
4871 ifsfirst.next = ifsp;
4874 if (ifsfirst.begoff > endoff)
4877 ifslastp = &ifsfirst;
4878 ifsfirst.endoff = endoff;
4883 ifslastp = &ifsfirst;
4884 while (ifslastp->next && ifslastp->next->begoff < endoff)
4885 ifslastp=ifslastp->next;
4886 while (ifslastp->next != NULL) {
4887 struct ifsregion *ifsp;
4889 ifsp = ifslastp->next->next;
4890 ckfree(ifslastp->next);
4891 ifslastp->next = ifsp;
4894 if (ifslastp->endoff > endoff)
4895 ifslastp->endoff = endoff;
4899 #ifdef ASH_MATH_SUPPORT
4901 * Expand arithmetic expression. Backup to start of expression,
4902 * evaluate, place result in (backed up) result, adjust string position.
4910 int quotes = flag & (EXP_FULL | EXP_CASE);
4916 * This routine is slightly over-complicated for
4917 * efficiency. First we make sure there is
4918 * enough space for the result, which may be bigger
4919 * than the expression if we add exponentation. Next we
4920 * scan backwards looking for the start of arithmetic. If the
4921 * next previous character is a CTLESC character, then we
4922 * have to rescan starting from the beginning since CTLESC
4923 * characters have to be processed left to right.
4925 CHECKSTRSPACE(10, expdest);
4926 USTPUTC('\0', expdest);
4927 start = stackblock();
4929 while (*p != CTLARI && p >= start)
4932 error("missing CTLARI (shouldn't happen)");
4933 if (p > start && *(p-1) == CTLESC)
4934 for (p = start; *p != CTLARI; p++)
4943 removerecordregions(begoff);
4946 result = arith(p+2);
4947 fmtstr(p, 12, "%d", result);
4953 recordregion(begoff, p - 1 - start, 0);
4954 result = expdest - p + 1;
4955 STADJUST(-result, expdest);
4960 * Expand stuff in backwards quotes.
4964 expbackq(cmd, quoted, flag)
4969 volatile struct backcmd in;
4973 char *dest = expdest;
4974 volatile struct ifsregion saveifs;
4975 struct ifsregion *volatile savelastp;
4976 struct nodelist *volatile saveargbackq;
4978 int startloc = dest - stackblock();
4979 char const *syntax = quoted? DQSYNTAX : BASESYNTAX;
4980 volatile int saveherefd;
4981 int quotes = flag & (EXP_FULL | EXP_CASE);
4982 struct jmploc jmploc;
4983 struct jmploc *volatile savehandler;
4987 /* Avoid longjmp clobbering */
4998 savelastp = ifslastp;
4999 saveargbackq = argbackq;
5000 saveherefd = herefd;
5002 if ((ex = setjmp(jmploc.loc))) {
5005 savehandler = handler;
5008 p = grabstackstr(dest);
5009 evalbackcmd(cmd, (struct backcmd *) &in);
5010 ungrabstackstr(p, dest);
5014 ifslastp = savelastp;
5015 argbackq = saveargbackq;
5016 herefd = saveherefd;
5024 if (--in.nleft < 0) {
5027 while ((i = read(in.fd, buf, sizeof buf)) < 0 && errno == EINTR);
5028 TRACE(("expbackq: read returns %d\n", i));
5035 if (lastc != '\0') {
5036 if (quotes && syntax[(int)lastc] == CCTL)
5037 STPUTC(CTLESC, dest);
5038 STPUTC(lastc, dest);
5042 /* Eat all trailing newlines */
5043 for (; dest > stackblock() && dest[-1] == '\n';)
5052 exitstatus = waitforjob(in.jp);
5053 handler = savehandler;
5055 longjmp(handler->loc, 1);
5058 recordregion(startloc, dest - stackblock(), 0);
5059 TRACE(("evalbackq: size=%d: \"%.*s\"\n",
5060 (dest - stackblock()) - startloc,
5061 (dest - stackblock()) - startloc,
5062 stackblock() + startloc));
5068 subevalvar(p, str, strloc, subtype, startloc, varflags, quotes)
5081 int saveherefd = herefd;
5082 struct nodelist *saveargbackq = argbackq;
5086 argstr(p, subtype != VSASSIGN && subtype != VSQUESTION ? EXP_CASE : 0);
5087 STACKSTRNUL(expdest);
5088 herefd = saveherefd;
5089 argbackq = saveargbackq;
5090 startp = stackblock() + startloc;
5092 str = stackblock() + strloc;
5096 setvar(str, startp, 0);
5097 amount = startp - expdest;
5098 STADJUST(amount, expdest);
5105 if (*p != CTLENDVAR) {
5106 outfmt(&errout, snlfmt, startp);
5107 error((char *)NULL);
5109 error("%.*s: parameter %snot set", p - str - 1,
5110 str, (varflags & VSNUL) ? "null or "
5115 for (loc = startp; loc < str; loc++) {
5118 if (patmatch2(str, startp, quotes))
5121 if (quotes && *loc == CTLESC)
5127 for (loc = str - 1; loc >= startp;) {
5130 if (patmatch2(str, startp, quotes))
5134 if (quotes && loc > startp && *(loc - 1) == CTLESC) {
5135 for (q = startp; q < loc; q++)
5145 for (loc = str - 1; loc >= startp;) {
5146 if (patmatch2(str, loc, quotes))
5149 if (quotes && loc > startp && *(loc - 1) == CTLESC) {
5150 for (q = startp; q < loc; q++)
5159 case VSTRIMRIGHTMAX:
5160 for (loc = startp; loc < str - 1; loc++) {
5161 if (patmatch2(str, loc, quotes))
5163 if (quotes && *loc == CTLESC)
5176 amount = ((str - 1) - (loc - startp)) - expdest;
5177 STADJUST(amount, expdest);
5178 while (loc != str - 1)
5183 amount = loc - expdest;
5184 STADJUST(amount, expdest);
5185 STPUTC('\0', expdest);
5186 STADJUST(-1, expdest);
5192 * Expand a variable, and return a pointer to the next character in the
5212 int quotes = flag & (EXP_FULL | EXP_CASE);
5215 subtype = varflags & VSTYPE;
5220 p = strchr(p, '=') + 1;
5221 again: /* jump here after setting a variable with ${var=text} */
5223 set = varisset(var, varflags & VSNUL);
5226 val = lookupvar(var);
5227 if (val == NULL || ((varflags & VSNUL) && val[0] == '\0')) {
5234 startloc = expdest - stackblock();
5235 if (set && subtype != VSPLUS) {
5236 /* insert the value of the variable */
5238 varvalue(var, varflags & VSQUOTE, flag);
5239 if (subtype == VSLENGTH) {
5240 varlen = expdest - stackblock() - startloc;
5241 STADJUST(-varlen, expdest);
5244 if (subtype == VSLENGTH) {
5245 varlen = strlen(val);
5249 varflags & VSQUOTE ?
5250 DQSYNTAX : BASESYNTAX,
5257 if (subtype == VSPLUS)
5260 easy = ((varflags & VSQUOTE) == 0 ||
5261 (*var == '@' && shellparam.nparam != 1));
5266 expdest = cvtnum(varlen, expdest);
5273 recordregion(startloc, expdest - stackblock(),
5274 varflags & VSQUOTE);
5290 case VSTRIMRIGHTMAX:
5294 * Terminate the string and start recording the pattern
5297 STPUTC('\0', expdest);
5298 patloc = expdest - stackblock();
5299 if (subevalvar(p, NULL, patloc, subtype,
5300 startloc, varflags, quotes) == 0) {
5301 int amount = (expdest - stackblock() - patloc) + 1;
5302 STADJUST(-amount, expdest);
5304 /* Remove any recorded regions beyond start of variable */
5305 removerecordregions(startloc);
5311 if (subevalvar(p, var, 0, subtype, startloc,
5312 varflags, quotes)) {
5315 * Remove any recorded regions beyond
5318 removerecordregions(startloc);
5333 if (subtype != VSNORMAL) { /* skip to end of alternative */
5336 if ((c = *p++) == CTLESC)
5338 else if (c == CTLBACKQ || c == (CTLBACKQ|CTLQUOTE)) {
5340 argbackq = argbackq->next;
5341 } else if (c == CTLVAR) {
5342 if ((*p++ & VSTYPE) != VSNORMAL)
5344 } else if (c == CTLENDVAR) {
5354 * Test whether a specialized variable is set.
5358 varisset(name, nulok)
5363 return backgndpid != -1;
5364 else if (*name == '@' || *name == '*') {
5365 if (*shellparam.p == NULL)
5371 for (av = shellparam.p; *av; av++)
5376 } else if (is_digit(*name)) {
5378 int num = atoi(name);
5380 if (num > shellparam.nparam)
5386 ap = shellparam.p[num - 1];
5388 if (nulok && (ap == NULL || *ap == '\0'))
5395 * Put a string on the stack.
5399 strtodest(p, syntax, quotes)
5405 if (quotes && syntax[(int) *p] == CCTL)
5406 STPUTC(CTLESC, expdest);
5407 STPUTC(*p++, expdest);
5412 * Add the value of a specialized variable to the stack string.
5416 varvalue(name, quoted, flags)
5428 int allow_split = flags & EXP_FULL;
5429 int quotes = flags & (EXP_FULL | EXP_CASE);
5431 syntax = quoted ? DQSYNTAX : BASESYNTAX;
5440 num = shellparam.nparam;
5445 expdest = cvtnum(num, expdest);
5448 for (i = 0 ; i < NOPTS ; i++) {
5450 STPUTC(optent_letter(optlist[i]), expdest);
5454 if (allow_split && quoted) {
5455 sep = 1 << CHAR_BIT;
5460 sep = ifsset() ? ifsval()[0] : ' ';
5462 sepq = syntax[(int) sep] == CCTL;
5465 for (ap = shellparam.p ; (p = *ap++) != NULL ; ) {
5466 strtodest(p, syntax, quotes);
5469 STPUTC(CTLESC, expdest);
5470 STPUTC(sep, expdest);
5475 strtodest(arg0, syntax, quotes);
5479 if (num > 0 && num <= shellparam.nparam) {
5480 strtodest(shellparam.p[num - 1], syntax, quotes);
5488 * Record the fact that we have to scan this region of the
5489 * string for IFS characters.
5493 recordregion(start, end, nulonly)
5498 struct ifsregion *ifsp;
5500 if (ifslastp == NULL) {
5504 ifsp = (struct ifsregion *)ckmalloc(sizeof (struct ifsregion));
5506 ifslastp->next = ifsp;
5510 ifslastp->begoff = start;
5511 ifslastp->endoff = end;
5512 ifslastp->nulonly = nulonly;
5518 * Break the argument string into pieces based upon IFS and add the
5519 * strings to the argument list. The regions of the string to be
5520 * searched for IFS characters have been stored by recordregion.
5523 ifsbreakup(string, arglist)
5525 struct arglist *arglist;
5527 struct ifsregion *ifsp;
5532 const char *ifs, *realifs;
5540 realifs = ifsset() ? ifsval() : defifs;
5541 if (ifslastp != NULL) {
5544 p = string + ifsp->begoff;
5545 nulonly = ifsp->nulonly;
5546 ifs = nulonly ? nullstr : realifs;
5548 while (p < string + ifsp->endoff) {
5552 if (strchr(ifs, *p)) {
5554 ifsspc = (strchr(defifs, *p) != NULL);
5555 /* Ignore IFS whitespace at start */
5556 if (q == start && ifsspc) {
5562 sp = (struct strlist *)stalloc(sizeof *sp);
5564 *arglist->lastp = sp;
5565 arglist->lastp = &sp->next;
5569 if (p >= string + ifsp->endoff) {
5575 if (strchr(ifs, *p) == NULL ) {
5578 } else if (strchr(defifs, *p) == NULL) {
5594 } while ((ifsp = ifsp->next) != NULL);
5595 if (!(*start || (!ifsspc && start > string && nulonly))) {
5600 sp = (struct strlist *)stalloc(sizeof *sp);
5602 *arglist->lastp = sp;
5603 arglist->lastp = &sp->next;
5609 while (ifsfirst.next != NULL) {
5610 struct ifsregion *ifsp;
5612 ifsp = ifsfirst.next->next;
5613 ckfree(ifsfirst.next);
5614 ifsfirst.next = ifsp;
5618 ifsfirst.next = NULL;
5622 * Add a file name to the list.
5626 addfname(const char *name)
5632 sp = (struct strlist *)stalloc(sizeof *sp);
5635 exparg.lastp = &sp->next;
5639 * Expand shell metacharacters. At this point, the only control characters
5640 * should be escapes. The results are stored in the list exparg.
5643 #if defined(__GLIBC__) && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN)
5645 expandmeta(str, flag)
5646 struct strlist *str;
5651 /* TODO - EXP_REDIR */
5656 p = preglob(str->text);
5658 switch (glob(p, GLOB_NOMAGIC, 0, &pglob)) {
5660 if (!(pglob.gl_flags & GLOB_MAGCHAR))
5671 *exparg.lastp = str;
5672 rmescapes(str->text);
5673 exparg.lastp = &str->next;
5675 default: /* GLOB_NOSPACE */
5676 error("Out of space");
5684 * Add the result of glob(3) to the list.
5689 const glob_t *pglob;
5691 char **p = pglob->gl_pathv;
5699 #else /* defined(__GLIBC__) && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN) */
5700 static char *expdir;
5704 expandmeta(str, flag)
5705 struct strlist *str;
5709 struct strlist **savelastp;
5712 /* TODO - EXP_REDIR */
5718 for (;;) { /* fast check for meta chars */
5719 if ((c = *p++) == '\0')
5721 if (c == '*' || c == '?' || c == '[' || c == '!')
5724 savelastp = exparg.lastp;
5726 if (expdir == NULL) {
5727 int i = strlen(str->text);
5728 expdir = ckmalloc(i < 2048 ? 2048 : i); /* XXX */
5731 expmeta(expdir, str->text);
5735 if (exparg.lastp == savelastp) {
5740 *exparg.lastp = str;
5741 rmescapes(str->text);
5742 exparg.lastp = &str->next;
5744 *exparg.lastp = NULL;
5745 *savelastp = sp = expsort(*savelastp);
5746 while (sp->next != NULL)
5748 exparg.lastp = &sp->next;
5756 * Do metacharacter (i.e. *, ?, [...]) expansion.
5760 expmeta(enddir, name)
5778 for (p = name ; ; p++) {
5779 if (*p == '*' || *p == '?')
5781 else if (*p == '[') {
5786 while (*q == CTLQUOTEMARK)
5790 if (*q == '/' || *q == '\0')
5797 } else if (*p == '!' && p[1] == '!' && (p == name || p[-1] == '/')) {
5799 } else if (*p == '\0')
5801 else if (*p == CTLQUOTEMARK)
5803 else if (*p == CTLESC)
5811 if (metaflag == 0) { /* we've reached the end of the file name */
5812 if (enddir != expdir)
5814 for (p = name ; ; p++) {
5815 if (*p == CTLQUOTEMARK)
5823 if (metaflag == 0 || lstat(expdir, &statb) >= 0)
5828 if (start != name) {
5831 while (*p == CTLQUOTEMARK)
5838 if (enddir == expdir) {
5840 } else if (enddir == expdir + 1 && *expdir == '/') {
5846 if ((dirp = opendir(cp)) == NULL)
5848 if (enddir != expdir)
5850 if (*endname == 0) {
5858 while (*p == CTLQUOTEMARK)
5864 while (! int_pending() && (dp = readdir(dirp)) != NULL) {
5865 if (dp->d_name[0] == '.' && ! matchdot)
5867 if (patmatch(start, dp->d_name, 0)) {
5869 strcpy(enddir, dp->d_name);
5872 for (p = enddir, cp = dp->d_name;
5873 (*p++ = *cp++) != '\0';)
5876 expmeta(p, endname);
5884 #endif /* defined(__GLIBC__) && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN) */
5888 #if !(defined(__GLIBC__) && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN))
5890 * Sort the results of file name expansion. It calculates the number of
5891 * strings to sort and then calls msort (short for merge sort) to do the
5895 static struct strlist *
5897 struct strlist *str;
5903 for (sp = str ; sp ; sp = sp->next)
5905 return msort(str, len);
5909 static struct strlist *
5911 struct strlist *list;
5914 struct strlist *p, *q = NULL;
5915 struct strlist **lpp;
5923 for (n = half ; --n >= 0 ; ) {
5927 q->next = NULL; /* terminate first half of list */
5928 q = msort(list, half); /* sort first half of list */
5929 p = msort(p, len - half); /* sort second half */
5932 if (strcmp(p->text, q->text) < 0) {
5935 if ((p = *lpp) == NULL) {
5942 if ((q = *lpp) == NULL) {
5955 * Returns true if the pattern matches the string.
5958 #if defined(__GLIBC__) && !defined(FNMATCH_BROKEN)
5959 /* squoted: string might have quote chars */
5961 patmatch(char *pattern, char *string, int squoted)
5966 p = preglob(pattern);
5967 q = squoted ? _rmescapes(string, RMESCAPE_ALLOC) : string;
5969 return !fnmatch(p, q, 0);
5974 patmatch2(char *pattern, char *string, int squoted)
5980 p = grabstackstr(expdest);
5981 res = patmatch(pattern, string, squoted);
5982 ungrabstackstr(p, expdest);
5987 patmatch(char *pattern, char *string, int squoted) {
5988 return pmatch(pattern, string, squoted);
5993 pmatch(char *pattern, char *string, int squoted)
6005 if (squoted && *q == CTLESC)
6013 if (squoted && *q == CTLESC)
6020 while (c == CTLQUOTEMARK || c == '*')
6022 if (c != CTLESC && c != CTLQUOTEMARK &&
6023 c != '?' && c != '*' && c != '[') {
6025 if (squoted && *q == CTLESC &&
6030 if (squoted && *q == CTLESC)
6036 if (pmatch(p, q, squoted))
6038 if (squoted && *q == CTLESC)
6040 } while (*q++ != '\0');
6051 while (*endp == CTLQUOTEMARK)
6054 goto dft; /* no matching ] */
6055 if (*endp == CTLESC)
6067 if (squoted && chr == CTLESC)
6073 if (c == CTLQUOTEMARK)
6077 if (*p == '-' && p[1] != ']') {
6079 while (*p == CTLQUOTEMARK)
6083 if (chr >= c && chr <= *p)
6090 } while ((c = *p++) != ']');
6091 if (found == invert)
6096 if (squoted && *q == CTLESC)
6113 * Remove any CTLESC characters from a string.
6116 #if defined(__GLIBC__) && !defined(FNMATCH_BROKEN)
6118 _rmescapes(char *str, int flag)
6121 static const char qchars[] = { CTLESC, CTLQUOTEMARK, 0 };
6123 p = strpbrk(str, qchars);
6129 if (flag & RMESCAPE_ALLOC) {
6130 size_t len = p - str;
6131 q = r = stalloc(strlen(p) + len + 1);
6134 q = mempcpy(q, str, len);
6136 memcpy(q, str, len);
6142 if (*p == CTLQUOTEMARK) {
6148 if (flag & RMESCAPE_GLOB && *p != '/') {
6165 while (*p != CTLESC && *p != CTLQUOTEMARK) {
6171 if (*p == CTLQUOTEMARK) {
6186 * See if a pattern matches in a case statement.
6190 casematch(union node *pattern, const char *val)
6192 struct stackmark smark;
6196 setstackmark(&smark);
6197 argbackq = pattern->narg.backquote;
6198 STARTSTACKSTR(expdest);
6200 argstr(pattern->narg.text, EXP_TILDE | EXP_CASE);
6201 STPUTC('\0', expdest);
6202 p = grabstackstr(expdest);
6203 result = patmatch(p, (char *)val, 0);
6204 popstackmark(&smark);
6219 CHECKSTRSPACE(32, buf);
6220 len = sprintf(buf, "%d", num);
6225 * Editline and history functions (and glue).
6227 static int histcmd(argc, argv)
6231 error("not compiled with history support");
6236 static int whichprompt; /* 1 == PS1, 2 == PS2 */
6240 struct redirtab *next;
6244 static struct redirtab *redirlist;
6246 extern char **environ;
6251 * Initialization code.
6264 basepf.nextc = basepf.buf = basebuf;
6267 /* from output.c: */
6269 #ifdef USE_GLIBC_STDIO
6280 for (envp = environ ; *envp ; envp++) {
6281 if (strchr(*envp, '=')) {
6282 setvareq(*envp, VEXPORT|VTEXTFIXED);
6286 fmtstr(ppid, sizeof(ppid), "%d", (int) getppid());
6287 setvar("PPID", ppid, 0);
6294 * This routine is called when an error or an interrupt occurs in an
6295 * interactive shell and control is returned to the main command loop.
6299 /* 1 == check for aliases, 2 == also check for assignments */
6300 static int checkalias;
6315 if (exception != EXSHELLPROC)
6316 parselleft = parsenleft = 0; /* clear input buffer */
6320 /* from parser.c: */
6335 /* from output.c: */
6339 #ifdef USE_GLIBC_STDIO
6340 if (memout.stream != NULL)
6343 if (memout.buf != NULL) {
6353 * This file implements the input routines used by the parser.
6356 #ifdef BB_FEATURE_COMMAND_EDITING
6357 unsigned int shell_context;
6358 static const char * cmdedit_prompt;
6359 static inline void putprompt(const char *s) {
6363 static inline void putprompt(const char *s) {
6368 #define EOF_NLEFT -99 /* value of parsenleft when EOF pushed back */
6373 * Same as pgetc(), but ignores PEOA.
6383 } while (c == PEOA);
6387 static inline int pgetc2() { return pgetc_macro(); }
6391 * Read a line from the script.
6395 pfgets(char *line, int len)
6401 while (--nleft > 0) {
6420 char *buf = parsefile->buf;
6424 #ifdef BB_FEATURE_COMMAND_EDITING
6427 nr = read(parsefile->fd, buf, BUFSIZ - 1);
6430 cmdedit_read_input((char*)cmdedit_prompt, buf);
6432 } while (nr <=0 || shell_context);
6433 cmdedit_terminate();
6437 nr = read(parsefile->fd, buf, BUFSIZ - 1);
6443 if (parsefile->fd == 0 && errno == EWOULDBLOCK) {
6444 int flags = fcntl(0, F_GETFL, 0);
6445 if (flags >= 0 && flags & O_NONBLOCK) {
6446 flags &=~ O_NONBLOCK;
6447 if (fcntl(0, F_SETFL, flags) >= 0) {
6448 out2str("sh: turning off NDELAY mode\n");
6460 struct strpush *sp = parsefile->strpush;
6465 if (parsenextc[-1] == ' ' || parsenextc[-1] == '\t') {
6470 if (sp->string != sp->ap->val) {
6474 sp->ap->flag &= ~ALIASINUSE;
6475 if (sp->ap->flag & ALIASDEAD) {
6476 unalias(sp->ap->name);
6480 parsenextc = sp->prevstring;
6481 parsenleft = sp->prevnleft;
6482 /*dprintf("*** calling popstring: restoring to '%s'\n", parsenextc);*/
6483 parsefile->strpush = sp->prev;
6484 if (sp != &(parsefile->basestrpush))
6491 * Refill the input buffer and return the next input character:
6493 * 1) If a string was pushed back on the input, pop it;
6494 * 2) If an EOF was pushed back (parsenleft == EOF_NLEFT) or we are reading
6495 * from a string so we can't refill the buffer, return EOF.
6496 * 3) If the is more stuff in this buffer, use it else call read to fill it.
6497 * 4) Process input up to the next newline, deleting nul characters.
6507 while (parsefile->strpush) {
6509 if (parsenleft == -1 && parsefile->strpush->ap &&
6510 parsenextc[-1] != ' ' && parsenextc[-1] != '\t') {
6515 if (--parsenleft >= 0)
6516 return (*parsenextc++);
6518 if (parsenleft == EOF_NLEFT || parsefile->buf == NULL)
6526 if (parselleft <= 0) {
6527 if ((parselleft = preadfd()) <= 0) {
6528 parselleft = parsenleft = EOF_NLEFT;
6535 /* delete nul characters */
6536 for (more = 1; more;) {
6544 parsenleft = q - parsenextc;
6545 more = 0; /* Stop processing here */
6551 if (--parselleft <= 0 && more) {
6552 parsenleft = q - parsenextc - 1;
6563 out2str(parsenextc);
6571 return *parsenextc++;
6576 * Push a string back onto the input at this current parsefile level.
6577 * We handle aliases this way.
6580 pushstring(char *s, int len, void *ap)
6585 /*dprintf("*** calling pushstring: %s, %d\n", s, len);*/
6586 if (parsefile->strpush) {
6587 sp = ckmalloc(sizeof (struct strpush));
6588 sp->prev = parsefile->strpush;
6589 parsefile->strpush = sp;
6591 sp = parsefile->strpush = &(parsefile->basestrpush);
6592 sp->prevstring = parsenextc;
6593 sp->prevnleft = parsenleft;
6595 sp->ap = (struct alias *)ap;
6597 ((struct alias *)ap)->flag |= ALIASINUSE;
6610 * Like setinputfile, but takes input from a string.
6614 setinputstring(string)
6619 parsenextc = string;
6620 parsenleft = strlen(string);
6621 parsefile->buf = NULL;
6629 * To handle the "." command, a stack of input files is used. Pushfile
6630 * adds a new entry to the stack and popfile restores the previous level.
6635 struct parsefile *pf;
6637 parsefile->nleft = parsenleft;
6638 parsefile->lleft = parselleft;
6639 parsefile->nextc = parsenextc;
6640 parsefile->linno = plinno;
6641 pf = (struct parsefile *)ckmalloc(sizeof (struct parsefile));
6642 pf->prev = parsefile;
6645 pf->basestrpush.prev = NULL;
6650 static void restartjob (struct job *);
6652 static void freejob (struct job *);
6653 static struct job *getjob (const char *);
6654 static int dowait (int, struct job *);
6655 static int waitproc (int, int *);
6656 static void waitonint(int);
6660 * We keep track of whether or not fd0 has been redirected. This is for
6661 * background commands, where we want to redirect fd0 to /dev/null only
6662 * if it hasn't already been redirected.
6664 static int fd0_redirected = 0;
6666 /* Return true if fd 0 has already been redirected at least once. */
6668 fd0_redirected_p () {
6669 return fd0_redirected != 0;
6673 * We also keep track of where fileno2 goes.
6675 static int fileno2 = 2;
6677 static int openredirect (union node *);
6678 static void dupredirect (union node *, int, char[10 ]);
6679 static int openhere (union node *);
6680 static int noclobberopen (const char *);
6686 * Turn job control on and off.
6688 * Note: This code assumes that the third arg to ioctl is a character
6689 * pointer, which is true on Berkeley systems but not System V. Since
6690 * System V doesn't have job control yet, this isn't a problem now.
6695 static void setjobctl(int enable)
6697 #ifdef OLD_TTY_DRIVER
6701 if (enable == jobctl || rootshell == 0)
6704 do { /* while we are in the background */
6705 #ifdef OLD_TTY_DRIVER
6706 if (ioctl(fileno2, TIOCGPGRP, (char *)&initialpgrp) < 0) {
6708 initialpgrp = tcgetpgrp(fileno2);
6709 if (initialpgrp < 0) {
6711 out2str("sh: can't access tty; job cenabletrol turned off\n");
6715 if (initialpgrp == -1)
6716 initialpgrp = getpgrp();
6717 else if (initialpgrp != getpgrp()) {
6718 killpg(initialpgrp, SIGTTIN);
6722 #ifdef OLD_TTY_DRIVER
6723 if (ioctl(fileno2, TIOCGETD, (char *)&ldisc) < 0 || ldisc != NTTYDISC) {
6724 out2str("sh: need new tty driver to run job cenabletrol; job cenabletrol turned off\n");
6732 setpgid(0, rootpid);
6733 #ifdef OLD_TTY_DRIVER
6734 ioctl(fileno2, TIOCSPGRP, (char *)&rootpid);
6736 tcsetpgrp(fileno2, rootpid);
6738 } else { /* turning job cenabletrol off */
6739 setpgid(0, initialpgrp);
6740 #ifdef OLD_TTY_DRIVER
6741 ioctl(fileno2, TIOCSPGRP, (char *)&initialpgrp);
6743 tcsetpgrp(fileno2, initialpgrp);
6754 /* A translation list so we can be polite to our users. */
6755 static char *signal_names[NSIG + 2] = {
6841 "Usage: kill [-s sigspec | -signum | -sigspec] [pid | job]... or\n"
6842 "kill -l [exitstatus]"
6846 if (*argv[1] == '-') {
6847 signo = decode_signal(argv[1] + 1, 1);
6851 while ((c = nextopt("ls:")) != '\0')
6857 signo = decode_signal(optionarg, 1);
6860 "invalid signal number or name: %s",
6868 "nextopt returned character code 0%o", c);
6875 if (!list && signo < 0)
6878 if ((signo < 0 || !*argptr) ^ list) {
6885 for (i = 1; i < NSIG; i++) {
6886 out1fmt(snlfmt, signal_names[i] + 3);
6890 signo = atoi(*argptr);
6893 if (0 < signo && signo < NSIG)
6894 out1fmt(snlfmt, signal_names[signo] + 3);
6896 error("invalid signal number or exit status: %s",
6902 if (**argptr == '%') {
6903 jp = getjob(*argptr);
6904 if (jp->jobctl == 0)
6905 error("job %s not created under job control",
6907 pid = -jp->ps[0].pid;
6909 pid = atoi(*argptr);
6910 if (kill(pid, signo) != 0)
6911 error("%s: %m", *argptr);
6912 } while (*++argptr);
6926 jp = getjob(argv[1]);
6927 if (jp->jobctl == 0)
6928 error("job not created under job control");
6929 pgrp = jp->ps[0].pid;
6930 #ifdef OLD_TTY_DRIVER
6931 ioctl(fileno2, TIOCSPGRP, (char *)&pgrp);
6933 tcsetpgrp(fileno2, pgrp);
6937 status = waitforjob(jp);
6951 jp = getjob(*++argv);
6952 if (jp->jobctl == 0)
6953 error("job not created under job control");
6955 } while (--argc > 1);
6964 struct procstat *ps;
6967 if (jp->state == JOBDONE)
6970 killpg(jp->ps[0].pid, SIGCONT);
6971 for (ps = jp->ps, i = jp->nprocs ; --i >= 0 ; ps++) {
6972 if (WIFSTOPPED(ps->status)) {
6981 static void showjobs(int change);
6995 * Print a list of jobs. If "change" is nonzero, only print jobs whose
6996 * statuses have changed since the last call to showjobs.
6998 * If the shell is interrupted in the process of creating a job, the
6999 * result may be a job structure containing zero processes. Such structures
7000 * will be freed here.
7011 struct procstat *ps;
7015 TRACE(("showjobs(%d) called\n", change));
7016 while (dowait(0, (struct job *)NULL) > 0);
7017 for (jobno = 1, jp = jobtab ; jobno <= njobs ; jobno++, jp++) {
7020 if (jp->nprocs == 0) {
7024 if (change && ! jp->changed)
7026 procno = jp->nprocs;
7027 for (ps = jp->ps ; ; ps++) { /* for each process */
7029 fmtstr(s, 64, "[%d] %ld ", jobno,
7032 fmtstr(s, 64, " %ld ",
7037 if (ps->status == -1) {
7038 /* don't print anything */
7039 } else if (WIFEXITED(ps->status)) {
7040 fmtstr(s, 64, "Exit %d",
7041 WEXITSTATUS(ps->status));
7044 if (WIFSTOPPED(ps->status))
7045 i = WSTOPSIG(ps->status);
7046 else /* WIFSIGNALED(ps->status) */
7048 i = WTERMSIG(ps->status);
7049 if ((i & 0x7F) < NSIG && sys_siglist[i & 0x7F])
7050 strcpy(s, sys_siglist[i & 0x7F]);
7052 fmtstr(s, 64, "Signal %d", i & 0x7F);
7053 if (WCOREDUMP(ps->status))
7054 strcat(s, " (core dumped)");
7059 "%*c%s\n", 30 - col >= 0 ? 30 - col : 0, ' ',
7066 if (jp->state == JOBDONE) {
7074 * Mark a job structure as unused.
7081 struct procstat *ps;
7085 for (i = jp->nprocs, ps = jp->ps ; --i >= 0 ; ps++) {
7086 if (ps->cmd != nullstr)
7089 if (jp->ps != &jp->ps0)
7093 if (curjob == jp - jobtab + 1)
7112 job = getjob(*++argv);
7116 for (;;) { /* loop until process terminated or stopped */
7119 status = job->ps[job->nprocs - 1].status;
7125 if (WIFEXITED(status))
7126 retval = WEXITSTATUS(status);
7128 else if (WIFSTOPPED(status))
7129 retval = WSTOPSIG(status) + 128;
7132 /* XXX: limits number of signals */
7133 retval = WTERMSIG(status) + 128;
7138 for (jp = jobtab ; ; jp++) {
7139 if (jp >= jobtab + njobs) { /* no running procs */
7142 if (jp->used && jp->state == 0)
7146 if (dowait(2, 0) < 0 && errno == EINTR) {
7155 * Convert a job name to a job structure.
7159 getjob(const char *name)
7169 if ((jobno = curjob) == 0 || jobtab[jobno - 1].used == 0)
7170 error("No current job");
7171 return &jobtab[jobno - 1];
7173 error("No current job");
7175 } else if (name[0] == '%') {
7176 if (is_digit(name[1])) {
7177 jobno = number(name + 1);
7178 if (jobno > 0 && jobno <= njobs
7179 && jobtab[jobno - 1].used != 0)
7180 return &jobtab[jobno - 1];
7182 } else if (name[1] == '%' && name[2] == '\0') {
7186 struct job *found = NULL;
7187 for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) {
7188 if (jp->used && jp->nprocs > 0
7189 && prefix(name + 1, jp->ps[0].cmd)) {
7191 error("%s: ambiguous", name);
7198 } else if (is_number(name, &pid)) {
7199 for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) {
7200 if (jp->used && jp->nprocs > 0
7201 && jp->ps[jp->nprocs - 1].pid == pid)
7205 error("No such job: %s", name);
7212 * Return a new job structure,
7216 makejob(node, nprocs)
7223 for (i = njobs, jp = jobtab ; ; jp++) {
7227 jobtab = ckmalloc(4 * sizeof jobtab[0]);
7229 jp = ckmalloc((njobs + 4) * sizeof jobtab[0]);
7230 memcpy(jp, jobtab, njobs * sizeof jp[0]);
7231 /* Relocate `ps' pointers */
7232 for (i = 0; i < njobs; i++)
7233 if (jp[i].ps == &jobtab[i].ps0)
7234 jp[i].ps = &jp[i].ps0;
7238 jp = jobtab + njobs;
7239 for (i = 4 ; --i >= 0 ; jobtab[njobs++].used = 0);
7252 jp->jobctl = jobctl;
7255 jp->ps = ckmalloc(nprocs * sizeof (struct procstat));
7260 TRACE(("makejob(0x%lx, %d) returns %%%d\n", (long)node, nprocs,
7267 * Fork of a subshell. If we are doing job control, give the subshell its
7268 * own process group. Jp is a job structure that the job is to be added to.
7269 * N is the command that will be evaluated by the child. Both jp and n may
7270 * be NULL. The mode parameter can be one of the following:
7271 * FORK_FG - Fork off a foreground process.
7272 * FORK_BG - Fork off a background process.
7273 * FORK_NOJOB - Like FORK_FG, but don't give the process its own
7274 * process group even if job control is on.
7276 * When job control is turned off, background processes have their standard
7277 * input redirected to /dev/null (except for the second and later processes
7284 forkshell(struct job *jp, union node *n, int mode)
7288 const char *devnull = _PATH_DEVNULL;
7289 const char *nullerr = "Can't open %s";
7291 TRACE(("forkshell(%%%d, 0x%lx, %d) called\n", jp - jobtab, (long)n,
7296 TRACE(("Fork failed, errno=%d\n", errno));
7298 error("Cannot fork");
7305 TRACE(("Child shell %d\n", getpid()));
7306 wasroot = rootshell;
7312 jobctl = 0; /* do job control only in root shell */
7313 if (wasroot && mode != FORK_NOJOB && mflag) {
7314 if (jp == NULL || jp->nprocs == 0)
7317 pgrp = jp->ps[0].pid;
7319 if (mode == FORK_FG) {
7320 /*** this causes superfluous TIOCSPGRPS ***/
7321 #ifdef OLD_TTY_DRIVER
7322 if (ioctl(fileno2, TIOCSPGRP, (char *)&pgrp) < 0)
7323 error("TIOCSPGRP failed, errno=%d", errno);
7325 if (tcsetpgrp(fileno2, pgrp) < 0)
7326 error("tcsetpgrp failed, errno=%d", errno);
7331 } else if (mode == FORK_BG) {
7334 if ((jp == NULL || jp->nprocs == 0) &&
7335 ! fd0_redirected_p ()) {
7337 if (open(devnull, O_RDONLY) != 0)
7338 error(nullerr, devnull);
7342 if (mode == FORK_BG) {
7345 if ((jp == NULL || jp->nprocs == 0) &&
7346 ! fd0_redirected_p ()) {
7348 if (open(devnull, O_RDONLY) != 0)
7349 error(nullerr, devnull);
7353 for (i = njobs, p = jobtab ; --i >= 0 ; p++)
7356 if (wasroot && iflag) {
7363 if (rootshell && mode != FORK_NOJOB && mflag) {
7364 if (jp == NULL || jp->nprocs == 0)
7367 pgrp = jp->ps[0].pid;
7370 if (mode == FORK_BG)
7371 backgndpid = pid; /* set $! */
7373 struct procstat *ps = &jp->ps[jp->nprocs++];
7377 if (iflag && rootshell && n)
7378 ps->cmd = commandtext(n);
7381 TRACE(("In parent shell: child = %d\n", pid));
7388 * Wait for job to finish.
7390 * Under job control we have the problem that while a child process is
7391 * running interrupts generated by the user are sent to the child but not
7392 * to the shell. This means that an infinite loop started by an inter-
7393 * active user may be hard to kill. With job control turned off, an
7394 * interactive user may place an interactive program inside a loop. If
7395 * the interactive program catches interrupts, the user doesn't want
7396 * these interrupts to also abort the loop. The approach we take here
7397 * is to have the shell ignore interrupt signals while waiting for a
7398 * forground process to terminate, and then send itself an interrupt
7399 * signal if the child process was terminated by an interrupt signal.
7400 * Unfortunately, some programs want to do a bit of cleanup and then
7401 * exit on interrupt; unless these processes terminate themselves by
7402 * sending a signal to themselves (instead of calling exit) they will
7403 * confuse this approach.
7411 int mypgrp = getpgrp();
7415 struct sigaction act, oact;
7424 sigaction(SIGINT, 0, &act);
7425 act.sa_handler = waitonint;
7426 sigaction(SIGINT, &act, &oact);
7428 TRACE(("waitforjob(%%%d) called\n", jp - jobtab + 1));
7429 while (jp->state == 0) {
7437 sigaction(SIGINT, &oact, 0);
7438 if (intreceived && trap[SIGINT]) kill(getpid(), SIGINT);
7442 #ifdef OLD_TTY_DRIVER
7443 if (ioctl(fileno2, TIOCSPGRP, (char *)&mypgrp) < 0)
7444 error("TIOCSPGRP failed, errno=%d\n", errno);
7446 if (tcsetpgrp(fileno2, mypgrp) < 0)
7447 error("tcsetpgrp failed, errno=%d\n", errno);
7450 if (jp->state == JOBSTOPPED)
7451 curjob = jp - jobtab + 1;
7453 status = jp->ps[jp->nprocs - 1].status;
7454 /* convert to 8 bits */
7455 if (WIFEXITED(status))
7456 st = WEXITSTATUS(status);
7458 else if (WIFSTOPPED(status))
7459 st = WSTOPSIG(status) + 128;
7462 st = WTERMSIG(status) + 128;
7466 * This is truly gross.
7467 * If we're doing job control, then we did a TIOCSPGRP which
7468 * caused us (the shell) to no longer be in the controlling
7469 * session -- so we wouldn't have seen any ^C/SIGINT. So, we
7470 * intuit from the subprocess exit status whether a SIGINT
7471 * occured, and if so interrupt ourselves. Yuck. - mycroft
7473 if (WIFSIGNALED(status) && WTERMSIG(status) == SIGINT)
7476 if (jp->state == JOBDONE)
7487 * Wait for a process to terminate.
7497 struct procstat *sp;
7499 struct job *thisjob;
7505 TRACE(("dowait(%d) called\n", block));
7507 pid = waitproc(block, &status);
7508 TRACE(("wait returns %d, status=%d\n", pid, status));
7509 } while (!(block & 2) && pid == -1 && errno == EINTR);
7514 for (jp = jobtab ; jp < jobtab + njobs ; jp++) {
7518 for (sp = jp->ps ; sp < jp->ps + jp->nprocs ; sp++) {
7521 if (sp->pid == pid) {
7522 TRACE(("Changing status of proc %d from 0x%x to 0x%x\n", pid, sp->status, status));
7523 sp->status = status;
7526 if (sp->status == -1)
7528 else if (WIFSTOPPED(sp->status))
7531 if (stopped) { /* stopped or done */
7532 int state = done? JOBDONE : JOBSTOPPED;
7533 if (jp->state != state) {
7534 TRACE(("Job %d: changing state from %d to %d\n", jp - jobtab + 1, jp->state, state));
7537 if (done && curjob == jp - jobtab + 1)
7538 curjob = 0; /* no current job */
7545 if (! rootshell || ! iflag || (job && thisjob == job)) {
7546 core = WCOREDUMP(status);
7548 if (WIFSTOPPED(status)) sig = WSTOPSIG(status);
7551 if (WIFEXITED(status)) sig = 0;
7552 else sig = WTERMSIG(status);
7554 if (sig != 0 && sig != SIGINT && sig != SIGPIPE) {
7556 outfmt(out2, "%d: ", pid);
7558 if (sig == SIGTSTP && rootshell && iflag)
7559 outfmt(out2, "%%%ld ",
7560 (long)(job - jobtab + 1));
7562 if (sig < NSIG && sys_siglist[sig])
7563 out2str(sys_siglist[sig]);
7565 outfmt(out2, "Signal %d", sig);
7567 out2str(" - core dumped");
7573 TRACE(("Not printing status: status=%d, sig=%d\n",
7577 TRACE(("Not printing status, rootshell=%d, job=0x%x\n", rootshell, job));
7579 thisjob->changed = 1;
7587 * Do a wait system call. If job control is compiled in, we accept
7588 * stopped processes. If block is zero, we return a value of zero
7589 * rather than blocking.
7591 * System V doesn't have a non-blocking wait system call. It does
7592 * have a SIGCLD signal that is sent to a process when one of it's
7593 * children dies. The obvious way to use SIGCLD would be to install
7594 * a handler for SIGCLD which simply bumped a counter when a SIGCLD
7595 * was received, and have waitproc bump another counter when it got
7596 * the status of a process. Waitproc would then know that a wait
7597 * system call would not block if the two counters were different.
7598 * This approach doesn't work because if a process has children that
7599 * have not been waited for, System V will send it a SIGCLD when it
7600 * installs a signal handler for SIGCLD. What this means is that when
7601 * a child exits, the shell will be sent SIGCLD signals continuously
7602 * until is runs out of stack space, unless it does a wait call before
7603 * restoring the signal handler. The code below takes advantage of
7604 * this (mis)feature by installing a signal handler for SIGCLD and
7605 * then checking to see whether it was called. If there are any
7606 * children to be waited for, it will be.
7611 waitproc(block, status)
7624 return wait3(status, flags, (struct rusage *)NULL);
7628 * return 1 if there are stopped jobs, otherwise 0
7638 for (jobno = 1, jp = jobtab; jobno <= njobs; jobno++, jp++) {
7641 if (jp->state == JOBSTOPPED) {
7642 out2str("You have stopped jobs.\n");
7652 * Return a string identifying a command (to be printed by the
7656 static char *cmdnextc;
7657 static int cmdnleft;
7658 #define MAXCMDTEXT 200
7661 cmdputs(const char *s)
7672 while ((c = *p++) != '\0') {
7675 else if (c == CTLVAR) {
7680 } else if (c == '=' && subtype != 0) {
7681 *q++ = "}-+?="[(subtype & VSTYPE) - VSNORMAL];
7683 } else if (c == CTLENDVAR) {
7685 } else if (c == CTLBACKQ || c == CTLBACKQ+CTLQUOTE)
7686 cmdnleft++; /* ignore it */
7689 if (--cmdnleft <= 0) {
7701 cmdtxt(const union node *n)
7704 struct nodelist *lp;
7713 cmdtxt(n->nbinary.ch1);
7715 cmdtxt(n->nbinary.ch2);
7718 cmdtxt(n->nbinary.ch1);
7720 cmdtxt(n->nbinary.ch2);
7723 cmdtxt(n->nbinary.ch1);
7725 cmdtxt(n->nbinary.ch2);
7728 for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
7736 cmdtxt(n->nredir.n);
7741 cmdtxt(n->nredir.n);
7745 cmdtxt(n->nif.test);
7747 cmdtxt(n->nif.ifpart);
7756 cmdtxt(n->nbinary.ch1);
7758 cmdtxt(n->nbinary.ch2);
7763 cmdputs(n->nfor.var);
7768 cmdputs(n->ncase.expr->narg.text);
7772 cmdputs(n->narg.text);
7776 for (np = n->ncmd.args ; np ; np = np->narg.next) {
7781 for (np = n->ncmd.redirect ; np ; np = np->nfile.next) {
7787 cmdputs(n->narg.text);
7790 p = ">"; i = 1; goto redir;
7792 p = ">>"; i = 1; goto redir;
7794 p = ">&"; i = 1; goto redir;
7796 p = ">|"; i = 1; goto redir;
7798 p = "<"; i = 0; goto redir;
7800 p = "<&"; i = 0; goto redir;
7802 p = "<>"; i = 0; goto redir;
7804 if (n->nfile.fd != i) {
7805 s[0] = n->nfile.fd + '0';
7810 if (n->type == NTOFD || n->type == NFROMFD) {
7811 s[0] = n->ndup.dupfd + '0';
7815 cmdtxt(n->nfile.fname);
7830 commandtext(const union node *n)
7834 cmdnextc = name = ckmalloc(MAXCMDTEXT);
7835 cmdnleft = MAXCMDTEXT - 4;
7842 static void waitonint(int sig) {
7847 * Routines to check for mail. (Perhaps make part of main.c?)
7851 #define MAXMBOXES 10
7854 static int nmboxes; /* number of mailboxes */
7855 static time_t mailtime[MAXMBOXES]; /* times of mailboxes */
7860 * Print appropriate message(s) if mail has arrived. If the argument is
7861 * nozero, then the value of MAIL has changed, so we just update the
7872 struct stackmark smark;
7879 setstackmark(&smark);
7880 mpath = mpathset()? mpathval() : mailval();
7881 for (i = 0 ; i < nmboxes ; i++) {
7882 p = padvance(&mpath, nullstr);
7887 for (q = p ; *q ; q++);
7892 q[-1] = '\0'; /* delete trailing '/' */
7893 if (stat(p, &statb) < 0)
7895 if (statb.st_size > mailtime[i] && ! silent) {
7898 pathopt? pathopt : "you have mail"
7901 mailtime[i] = statb.st_size;
7904 popstackmark(&smark);
7910 static short profile_buf[16384];
7914 static void read_profile (const char *);
7915 static char *find_dot_file (char *);
7916 static void cmdloop (int);
7917 static void options (int);
7918 static void minus_o (char *, int);
7919 static void setoption (int, int);
7920 static void procargs (int, char **);
7924 * Main routine. We initialize things, parse the arguments, execute
7925 * profiles if we're a login shell, and then call cmdloop to execute
7926 * commands. The setjmp call sets up the location to jump to when an
7927 * exception occurs. When an exception occurs the variable "state"
7928 * is used to figure out how far we had gotten.
7932 shell_main(argc, argv)
7936 struct jmploc jmploc;
7937 struct stackmark smark;
7941 DOTCMD = find_builtin(".");
7942 BLTINCMD = find_builtin("builtin");
7943 EXECCMD = find_builtin("exec");
7944 EVALCMD = find_builtin("eval");
7947 monitor(4, etext, profile_buf, sizeof profile_buf, 50);
7949 #if defined(linux) || defined(__GNU__)
7950 signal(SIGCHLD, SIG_DFL);
7953 if (setjmp(jmploc.loc)) {
7956 * When a shell procedure is executed, we raise the
7957 * exception EXSHELLPROC to clean up before executing
7958 * the shell procedure.
7960 switch (exception) {
7969 exitstatus = exerrno;
7980 if (exception != EXSHELLPROC) {
7981 if (state == 0 || iflag == 0 || ! rootshell)
7982 exitshell(exitstatus);
7985 if (exception == EXINT) {
7991 popstackmark(&smark);
7992 FORCEINTON; /* enable interrupts */
7995 else if (state == 2)
7997 else if (state == 3)
8005 trputs("Shell args: "); trargs(argv);
8010 setstackmark(&smark);
8011 procargs(argc, argv);
8012 if (argv[0] && argv[0][0] == '-') {
8014 read_profile("/etc/profile");
8017 read_profile(".profile");
8022 if (getuid() == geteuid() && getgid() == getegid()) {
8024 if ((shinit = lookupvar("ENV")) != NULL && *shinit != '\0') {
8026 read_profile(shinit);
8033 if (sflag == 0 || minusc) {
8034 static int sigs[] = {
8035 SIGINT, SIGQUIT, SIGHUP,
8041 #define SIGSSIZE (sizeof(sigs)/sizeof(sigs[0]))
8044 for (i = 0; i < SIGSSIZE; i++)
8049 evalstring(minusc, 0);
8051 if (sflag || minusc == NULL) {
8052 state4: /* XXX ??? - why isn't this before the "if" statement */
8058 exitshell(exitstatus);
8064 * Read and execute commands. "Top" is nonzero for the top level command
8065 * loop; it turns on prompting if the shell is interactive.
8072 struct stackmark smark;
8076 TRACE(("cmdloop(%d) called\n", top));
8077 setstackmark(&smark);
8088 n = parsecmd(inter);
8089 /* showtree(n); DEBUG */
8091 if (!top || numeof >= 50)
8093 if (!stoppedjobs()) {
8096 out2str("\nUse \"exit\" to leave shell.\n");
8099 } else if (n != NULL && nflag == 0) {
8100 job_warning = (job_warning == 2) ? 1 : 0;
8104 popstackmark(&smark);
8105 setstackmark(&smark);
8106 if (evalskip == SKIPFILE) {
8111 popstackmark(&smark);
8117 * Read /etc/profile or .profile. Return on error.
8129 if ((fd = open(name, O_RDONLY)) >= 0)
8134 /* -q turns off -x and -v just when executing init files */
8137 xflag = 0, xflag_set = 1;
8139 vflag = 0, vflag_set = 1;
8154 * Read a file containing shell functions.
8158 readcmdfile(const char *name)
8163 if ((fd = open(name, O_RDONLY)) >= 0)
8166 error("Can't open %s", name);
8175 * Take commands from a file. To be compatable we should do a path
8176 * search for the file, which is necessary to find sub-commands.
8181 find_dot_file(mybasename)
8185 const char *path = pathval();
8188 /* don't try this for absolute or relative paths */
8189 if (strchr(mybasename, '/'))
8192 while ((fullname = padvance(&path, mybasename)) != NULL) {
8193 if ((stat(fullname, &statb) == 0) && S_ISREG(statb.st_mode)) {
8195 * Don't bother freeing here, since it will
8196 * be freed by the caller.
8200 stunalloc(fullname);
8203 /* not found in the PATH */
8204 error("%s: not found", mybasename);
8216 for (sp = cmdenviron; sp ; sp = sp->next)
8217 setvareq(savestr(sp->text), VSTRFIXED|VTEXTFIXED);
8219 if (argc >= 2) { /* That's what SVR2 does */
8221 struct stackmark smark;
8223 setstackmark(&smark);
8224 fullname = find_dot_file(argv[1]);
8225 setinputfile(fullname, 1);
8226 commandname = fullname;
8229 popstackmark(&smark);
8243 exitstatus = number(argv[1]);
8245 exitstatus = oexitstatus;
8246 exitshell(exitstatus);
8254 nbytes = ALIGN(nbytes);
8255 if (nbytes > stacknleft) {
8257 struct stack_block *sp;
8260 if (blocksize < MINSIZE)
8261 blocksize = MINSIZE;
8263 sp = ckmalloc(sizeof(struct stack_block) - MINSIZE + blocksize);
8265 stacknxt = sp->space;
8266 stacknleft = blocksize;
8272 stacknleft -= nbytes;
8278 stunalloc(pointer p)
8281 if (p == NULL) { /*DEBUG */
8282 write(2, "stunalloc\n", 10);
8286 if (!(stacknxt >= (char *)p && (char *)p >= stackp->space)) {
8289 stacknleft += stacknxt - (char *)p;
8295 setstackmark(struct stackmark *mark)
8297 mark->stackp = stackp;
8298 mark->stacknxt = stacknxt;
8299 mark->stacknleft = stacknleft;
8300 mark->marknext = markp;
8306 popstackmark(struct stackmark *mark)
8308 struct stack_block *sp;
8311 markp = mark->marknext;
8312 while (stackp != mark->stackp) {
8317 stacknxt = mark->stacknxt;
8318 stacknleft = mark->stacknleft;
8324 * When the parser reads in a string, it wants to stick the string on the
8325 * stack and only adjust the stack pointer when it knows how big the
8326 * string is. Stackblock (defined in stack.h) returns a pointer to a block
8327 * of space on top of the stack and stackblocklen returns the length of
8328 * this block. Growstackblock will grow this space by at least one byte,
8329 * possibly moving it (like realloc). Grabstackblock actually allocates the
8330 * part of the block that has been used.
8334 growstackblock(void) {
8336 int newlen = ALIGN(stacknleft * 2 + 100);
8337 char *oldspace = stacknxt;
8338 int oldlen = stacknleft;
8339 struct stack_block *sp;
8340 struct stack_block *oldstackp;
8342 if (stacknxt == stackp->space && stackp != &stackbase) {
8347 sp = ckrealloc((pointer)sp, sizeof(struct stack_block) - MINSIZE + newlen);
8350 stacknxt = sp->space;
8351 stacknleft = newlen;
8353 /* Stack marks pointing to the start of the old block
8354 * must be relocated to point to the new block
8356 struct stackmark *xmark;
8358 while (xmark != NULL && xmark->stackp == oldstackp) {
8359 xmark->stackp = stackp;
8360 xmark->stacknxt = stacknxt;
8361 xmark->stacknleft = stacknleft;
8362 xmark = xmark->marknext;
8367 p = stalloc(newlen);
8368 memcpy(p, oldspace, oldlen);
8369 stacknxt = p; /* free the space */
8370 stacknleft += newlen; /* we just allocated */
8377 grabstackblock(int len)
8387 * The following routines are somewhat easier to use that the above.
8388 * The user declares a variable of type STACKSTR, which may be declared
8389 * to be a register. The macro STARTSTACKSTR initializes things. Then
8390 * the user uses the macro STPUTC to add characters to the string. In
8391 * effect, STPUTC(c, p) is the same as *p++ = c except that the stack is
8392 * grown as necessary. When the user is done, she can just leave the
8393 * string there and refer to it using stackblock(). Or she can allocate
8394 * the space for it using grabstackstr(). If it is necessary to allow
8395 * someone else to use the stack temporarily and then continue to grow
8396 * the string, the user should use grabstack to allocate the space, and
8397 * then call ungrabstr(p) to return to the previous mode of operation.
8399 * USTPUTC is like STPUTC except that it doesn't check for overflow.
8400 * CHECKSTACKSPACE can be called before USTPUTC to ensure that there
8401 * is space for at least one character.
8406 growstackstr(void) {
8407 int len = stackblocksize();
8408 if (herefd >= 0 && len >= 1024) {
8409 xwrite(herefd, stackblock(), len);
8410 sstrnleft = len - 1;
8411 return stackblock();
8414 sstrnleft = stackblocksize() - len - 1;
8415 return stackblock() + len;
8420 * Called from CHECKSTRSPACE.
8424 makestrspace(size_t newlen) {
8425 int len = stackblocksize() - sstrnleft;
8428 sstrnleft = stackblocksize() - len;
8429 } while (sstrnleft < newlen);
8430 return stackblock() + len;
8436 ungrabstackstr(char *s, char *p)
8438 stacknleft += stacknxt - s;
8440 sstrnleft = stacknleft - (p - s);
8443 * Miscelaneous builtins.
8450 static mode_t getmode(const void *, mode_t);
8451 static void *setmode(const char *);
8453 #if !defined(__GLIBC__) || __GLIBC__ == 2 && __GLIBC_MINOR__ < 1
8454 typedef enum __rlimit_resource rlim_t;
8461 * The read builtin. The -e option causes backslashes to escape the
8462 * following character.
8464 * This uses unbuffered input, which may be avoidable in some cases.
8485 while ((i = nextopt("p:r")) != '\0') {
8491 if (prompt && isatty(0)) {
8495 if (*(ap = argptr) == NULL)
8497 if ((ifs = bltinlookup("IFS")) == NULL)
8504 if (read(0, &c, 1) != 1) {
8516 if (!rflag && c == '\\') {
8522 if (startword && *ifs == ' ' && strchr(ifs, c)) {
8526 if (backslash && c == '\\') {
8527 if (read(0, &c, 1) != 1) {
8532 } else if (ap[1] != NULL && strchr(ifs, c) != NULL) {
8534 setvar(*ap, stackblock(), 0);
8543 /* Remove trailing blanks */
8544 while (stackblock() <= --p && strchr(ifs, *p) != NULL)
8546 setvar(*ap, stackblock(), 0);
8547 while (*++ap != NULL)
8548 setvar(*ap, nullstr, 0);
8555 umaskcmd(argc, argv)
8562 int symbolic_mode = 0;
8564 while ((i = nextopt("S")) != '\0') {
8573 if ((ap = *argptr) == NULL) {
8574 if (symbolic_mode) {
8575 char u[4], g[4], o[4];
8578 if ((mask & S_IRUSR) == 0)
8580 if ((mask & S_IWUSR) == 0)
8582 if ((mask & S_IXUSR) == 0)
8587 if ((mask & S_IRGRP) == 0)
8589 if ((mask & S_IWGRP) == 0)
8591 if ((mask & S_IXGRP) == 0)
8596 if ((mask & S_IROTH) == 0)
8598 if ((mask & S_IWOTH) == 0)
8600 if ((mask & S_IXOTH) == 0)
8604 out1fmt("u=%s,g=%s,o=%s\n", u, g, o);
8606 out1fmt("%.4o\n", mask);
8609 if (isdigit((unsigned char)*ap)) {
8612 if (*ap >= '8' || *ap < '0')
8613 error("Illegal number: %s", argv[1]);
8614 mask = (mask << 3) + (*ap - '0');
8615 } while (*++ap != '\0');
8621 if ((set = setmode(ap)) != 0) {
8622 mask = getmode(set, ~mask & 0777);
8627 error("Illegal mode: %s", ap);
8629 umask(~mask & 0777);
8638 * This code, originally by Doug Gwyn, Doug Kingston, Eric Gisin, and
8639 * Michael Rendell was ripped from pdksh 5.0.8 and hacked for use with
8640 * ash by J.T. Conklin.
8648 int factor; /* multiply by to get rlim_{cur,max} values */
8652 static const struct limits limits[] = {
8654 { "time(seconds)", RLIMIT_CPU, 1, 't' },
8657 { "file(blocks)", RLIMIT_FSIZE, 512, 'f' },
8660 { "data(kbytes)", RLIMIT_DATA, 1024, 'd' },
8663 { "stack(kbytes)", RLIMIT_STACK, 1024, 's' },
8666 { "coredump(blocks)", RLIMIT_CORE, 512, 'c' },
8669 { "memory(kbytes)", RLIMIT_RSS, 1024, 'm' },
8671 #ifdef RLIMIT_MEMLOCK
8672 { "locked memory(kbytes)", RLIMIT_MEMLOCK, 1024, 'l' },
8675 { "process(processes)", RLIMIT_NPROC, 1, 'p' },
8677 #ifdef RLIMIT_NOFILE
8678 { "nofiles(descriptors)", RLIMIT_NOFILE, 1, 'n' },
8681 { "vmemory(kbytes)", RLIMIT_VMEM, 1024, 'v' },
8684 { "swap(kbytes)", RLIMIT_SWAP, 1024, 'w' },
8686 { (char *) 0, 0, 0, '\0' }
8690 ulimitcmd(argc, argv)
8696 enum { SOFT = 0x1, HARD = 0x2 }
8698 const struct limits *l;
8701 struct rlimit limit;
8704 while ((optc = nextopt("HSatfdsmcnpl")) != '\0')
8719 for (l = limits; l->name && l->option != what; l++)
8722 error("internal error (%c)", what);
8724 set = *argptr ? 1 : 0;
8728 if (all || argptr[1])
8729 error("too many arguments");
8730 if (strcmp(p, "unlimited") == 0)
8731 val = RLIM_INFINITY;
8735 while ((c = *p++) >= '0' && c <= '9')
8737 val = (val * 10) + (long)(c - '0');
8738 if (val < (rlim_t) 0)
8742 error("bad number");
8747 for (l = limits; l->name; l++) {
8748 getrlimit(l->cmd, &limit);
8750 val = limit.rlim_cur;
8751 else if (how & HARD)
8752 val = limit.rlim_max;
8754 out1fmt("%-20s ", l->name);
8755 if (val == RLIM_INFINITY)
8756 out1fmt("unlimited\n");
8760 out1fmt("%lld\n", (long long) val);
8766 getrlimit(l->cmd, &limit);
8769 limit.rlim_max = val;
8771 limit.rlim_cur = val;
8772 if (setrlimit(l->cmd, &limit) < 0)
8773 error("error setting limit (%m)");
8776 val = limit.rlim_cur;
8777 else if (how & HARD)
8778 val = limit.rlim_max;
8780 if (val == RLIM_INFINITY)
8781 out1fmt("unlimited\n");
8785 out1fmt("%lld\n", (long long) val);
8791 * prefix -- see if pfx is a prefix of string.
8800 if (*pfx++ != *string++)
8807 * Return true if s is a string of digits, and save munber in intptr
8812 is_number(const char *p, int *intptr)
8820 ret += digit_val(*p);
8822 } while (*p != '\0');
8829 * Convert a string of digits to an integer, printing an error message on
8834 number(const char *s)
8837 if (! is_number(s, &i))
8838 error("Illegal number: %s", s);
8843 * Produce a possibly single quoted string suitable as input to the shell.
8844 * The return string is allocated on the stack.
8848 single_quote(const char *s) {
8855 size_t len1, len1p, len2, len2p;
8857 len1 = strcspn(s, "'");
8858 len2 = strspn(s + len1, "'");
8860 len1p = len1 ? len1 + 2 : len1;
8872 CHECKSTRSPACE(len1p + len2p + 1, p);
8877 q = mempcpy(p + 1, s, len1);
8880 memcpy(p + 1, s, len1);
8897 *(char *) mempcpy(q + 1, s, len2) = '"';
8900 memcpy(q + 1, s, len2);
8906 STADJUST(len1p + len2p, p);
8911 return grabstackstr(p);
8915 * Like strdup but works with the ash stack.
8919 sstrdup(const char *p)
8921 size_t len = strlen(p) + 1;
8922 return memcpy(stalloc(len), p, len);
8927 * This file was generated by the mknodes program.
8931 * Routine for dealing with parsed shell commands.
8935 static int funcblocksize; /* size of structures in function */
8936 static int funcstringsize; /* size of strings in node */
8937 static pointer funcblock; /* block to allocate function from */
8938 static char *funcstring; /* block to allocate strings from */
8940 static const short nodesize[26] = {
8941 ALIGN(sizeof (struct nbinary)),
8942 ALIGN(sizeof (struct ncmd)),
8943 ALIGN(sizeof (struct npipe)),
8944 ALIGN(sizeof (struct nredir)),
8945 ALIGN(sizeof (struct nredir)),
8946 ALIGN(sizeof (struct nredir)),
8947 ALIGN(sizeof (struct nbinary)),
8948 ALIGN(sizeof (struct nbinary)),
8949 ALIGN(sizeof (struct nif)),
8950 ALIGN(sizeof (struct nbinary)),
8951 ALIGN(sizeof (struct nbinary)),
8952 ALIGN(sizeof (struct nfor)),
8953 ALIGN(sizeof (struct ncase)),
8954 ALIGN(sizeof (struct nclist)),
8955 ALIGN(sizeof (struct narg)),
8956 ALIGN(sizeof (struct narg)),
8957 ALIGN(sizeof (struct nfile)),
8958 ALIGN(sizeof (struct nfile)),
8959 ALIGN(sizeof (struct nfile)),
8960 ALIGN(sizeof (struct nfile)),
8961 ALIGN(sizeof (struct nfile)),
8962 ALIGN(sizeof (struct ndup)),
8963 ALIGN(sizeof (struct ndup)),
8964 ALIGN(sizeof (struct nhere)),
8965 ALIGN(sizeof (struct nhere)),
8966 ALIGN(sizeof (struct nnot)),
8970 static void calcsize (union node *);
8971 static void sizenodelist (struct nodelist *);
8972 static union node *copynode (union node *);
8973 static struct nodelist *copynodelist (struct nodelist *);
8974 static char *nodesavestr (char *);
8979 * Make a copy of a parse tree.
8983 copyfunc(union node *n)
8990 funcblock = ckmalloc(funcblocksize + funcstringsize);
8991 funcstring = (char *) funcblock + funcblocksize;
9003 funcblocksize += nodesize[n->type];
9010 calcsize(n->nbinary.ch2);
9011 calcsize(n->nbinary.ch1);
9014 calcsize(n->ncmd.redirect);
9015 calcsize(n->ncmd.args);
9016 calcsize(n->ncmd.assign);
9019 sizenodelist(n->npipe.cmdlist);
9024 calcsize(n->nredir.redirect);
9025 calcsize(n->nredir.n);
9028 calcsize(n->nif.elsepart);
9029 calcsize(n->nif.ifpart);
9030 calcsize(n->nif.test);
9033 funcstringsize += strlen(n->nfor.var) + 1;
9034 calcsize(n->nfor.body);
9035 calcsize(n->nfor.args);
9038 calcsize(n->ncase.cases);
9039 calcsize(n->ncase.expr);
9042 calcsize(n->nclist.body);
9043 calcsize(n->nclist.pattern);
9044 calcsize(n->nclist.next);
9048 sizenodelist(n->narg.backquote);
9049 funcstringsize += strlen(n->narg.text) + 1;
9050 calcsize(n->narg.next);
9057 calcsize(n->nfile.fname);
9058 calcsize(n->nfile.next);
9062 calcsize(n->ndup.vname);
9063 calcsize(n->ndup.next);
9067 calcsize(n->nhere.doc);
9068 calcsize(n->nhere.next);
9071 calcsize(n->nnot.com);
9080 struct nodelist *lp;
9083 funcblocksize += ALIGN(sizeof(struct nodelist));
9100 funcblock = (char *) funcblock + nodesize[n->type];
9107 new->nbinary.ch2 = copynode(n->nbinary.ch2);
9108 new->nbinary.ch1 = copynode(n->nbinary.ch1);
9111 new->ncmd.redirect = copynode(n->ncmd.redirect);
9112 new->ncmd.args = copynode(n->ncmd.args);
9113 new->ncmd.assign = copynode(n->ncmd.assign);
9114 new->ncmd.backgnd = n->ncmd.backgnd;
9117 new->npipe.cmdlist = copynodelist(n->npipe.cmdlist);
9118 new->npipe.backgnd = n->npipe.backgnd;
9123 new->nredir.redirect = copynode(n->nredir.redirect);
9124 new->nredir.n = copynode(n->nredir.n);
9127 new->nif.elsepart = copynode(n->nif.elsepart);
9128 new->nif.ifpart = copynode(n->nif.ifpart);
9129 new->nif.test = copynode(n->nif.test);
9132 new->nfor.var = nodesavestr(n->nfor.var);
9133 new->nfor.body = copynode(n->nfor.body);
9134 new->nfor.args = copynode(n->nfor.args);
9137 new->ncase.cases = copynode(n->ncase.cases);
9138 new->ncase.expr = copynode(n->ncase.expr);
9141 new->nclist.body = copynode(n->nclist.body);
9142 new->nclist.pattern = copynode(n->nclist.pattern);
9143 new->nclist.next = copynode(n->nclist.next);
9147 new->narg.backquote = copynodelist(n->narg.backquote);
9148 new->narg.text = nodesavestr(n->narg.text);
9149 new->narg.next = copynode(n->narg.next);
9156 new->nfile.fname = copynode(n->nfile.fname);
9157 new->nfile.fd = n->nfile.fd;
9158 new->nfile.next = copynode(n->nfile.next);
9162 new->ndup.vname = copynode(n->ndup.vname);
9163 new->ndup.dupfd = n->ndup.dupfd;
9164 new->ndup.fd = n->ndup.fd;
9165 new->ndup.next = copynode(n->ndup.next);
9169 new->nhere.doc = copynode(n->nhere.doc);
9170 new->nhere.fd = n->nhere.fd;
9171 new->nhere.next = copynode(n->nhere.next);
9174 new->nnot.com = copynode(n->nnot.com);
9177 new->type = n->type;
9182 static struct nodelist *
9184 struct nodelist *lp;
9186 struct nodelist *start;
9187 struct nodelist **lpp;
9192 funcblock = (char *) funcblock + ALIGN(sizeof(struct nodelist));
9193 (*lpp)->n = copynode(lp->n);
9195 lpp = &(*lpp)->next;
9208 char *rtn = funcstring;
9210 funcstring = stpcpy(funcstring, s) + 1;
9213 register char *p = s;
9214 register char *q = funcstring;
9215 char *rtn = funcstring;
9217 while ((*q++ = *p++) != '\0')
9225 static int getopts (char *, char *, char **, int *, int *);
9230 * Process the shell command line arguments.
9234 procargs(argc, argv)
9243 for (i = 0; i < NOPTS; i++)
9246 if (*argptr == NULL && minusc == NULL)
9248 if (iflag == 2 && sflag == 1 && isatty(0) && isatty(1))
9252 for (i = 0; i < NOPTS; i++)
9253 if (optent_val(i) == 2)
9256 if (sflag == 0 && minusc == NULL) {
9257 commandname = argv[0];
9259 setinputfile(arg0, 0);
9262 /* POSIX 1003.2: first arg after -c cmd is $0, remainder $1... */
9263 if (argptr && minusc && *argptr)
9266 shellparam.p = argptr;
9267 shellparam.optind = 1;
9268 shellparam.optoff = -1;
9269 /* assert(shellparam.malloc == 0 && shellparam.nparam == 0); */
9271 shellparam.nparam++;
9280 * Process shell options. The global variable argptr contains a pointer
9281 * to the argument list; we advance it past the options.
9294 while ((p = *argptr) != NULL) {
9296 if ((c = *p++) == '-') {
9298 if (p[0] == '\0' || (p[0] == '-' && p[1] == '\0')) {
9300 /* "-" means turn off -x and -v */
9303 /* "--" means reset params */
9304 else if (*argptr == NULL)
9307 break; /* "-" or "--" terminates options */
9309 } else if (c == '+') {
9315 while ((c = *p++) != '\0') {
9316 if (c == 'c' && cmdline) {
9318 #ifdef NOHACK /* removing this code allows sh -ce 'foo' for compat */
9322 if (q == NULL || minusc != NULL)
9323 error("Bad -c option");
9328 } else if (c == 'o') {
9329 minus_o(*argptr, val);
9347 out1str("Current option settings\n");
9348 for (i = 0; i < NOPTS; i++)
9349 out1fmt("%-16s%s\n", optent_name(optlist[i]),
9350 optent_val(i) ? "on" : "off");
9352 for (i = 0; i < NOPTS; i++)
9353 if (equal(name, optent_name(optlist[i]))) {
9354 setoption(optent_letter(optlist[i]), val);
9357 error("Illegal option -o %s", name);
9363 setoption(int flag, int val)
9367 for (i = 0; i < NOPTS; i++)
9368 if (optent_letter(optlist[i]) == flag) {
9369 optent_val(i) = val;
9371 /* #%$ hack for ksh semantics */
9374 else if (flag == 'E')
9379 error("Illegal option -%c", flag);
9386 * Set the shell parameters.
9390 setparam(char **argv)
9396 for (nparam = 0 ; argv[nparam] ; nparam++);
9397 ap = newparam = ckmalloc((nparam + 1) * sizeof *ap);
9399 *ap++ = savestr(*argv++);
9402 freeparam(&shellparam);
9403 shellparam.malloc = 1;
9404 shellparam.nparam = nparam;
9405 shellparam.p = newparam;
9406 shellparam.optind = 1;
9407 shellparam.optoff = -1;
9412 * Free the list of positional parameters.
9416 freeparam(volatile struct shparam *param)
9420 if (param->malloc) {
9421 for (ap = param->p ; *ap ; ap++)
9430 * The shift builtin command.
9434 shiftcmd(argc, argv)
9443 n = number(argv[1]);
9444 if (n > shellparam.nparam)
9445 error("can't shift that many");
9447 shellparam.nparam -= n;
9448 for (ap1 = shellparam.p ; --n >= 0 ; ap1++) {
9449 if (shellparam.malloc)
9453 while ((*ap2++ = *ap1++) != NULL);
9454 shellparam.optind = 1;
9455 shellparam.optoff = -1;
9463 * The set command builtin.
9472 return showvarscmd(argc, argv);
9476 if (*argptr != NULL) {
9485 getoptsreset(const char *value)
9487 shellparam.optind = number(value);
9488 shellparam.optoff = -1;
9491 #ifdef BB_LOCALE_SUPPORT
9492 static void change_lc_all(const char *value)
9494 if(value != 0 && *value != 0)
9495 setlocale(LC_ALL, value);
9498 static void change_lc_ctype(const char *value)
9500 if(value != 0 && *value != 0)
9501 setlocale(LC_CTYPE, value);
9508 * The getopts builtin. Shellparam.optnext points to the next argument
9509 * to be processed. Shellparam.optptr points to the next character to
9510 * be processed in the current argument. If shellparam.optnext is NULL,
9511 * then it's the first time getopts has been called.
9515 getoptscmd(argc, argv)
9522 error("Usage: getopts optstring var [arg]");
9523 else if (argc == 3) {
9524 optbase = shellparam.p;
9525 if (shellparam.optind > shellparam.nparam + 1) {
9526 shellparam.optind = 1;
9527 shellparam.optoff = -1;
9532 if (shellparam.optind > argc - 2) {
9533 shellparam.optind = 1;
9534 shellparam.optoff = -1;
9538 return getopts(argv[1], argv[2], optbase, &shellparam.optind,
9539 &shellparam.optoff);
9543 * Safe version of setvar, returns 1 on success 0 on failure.
9547 setvarsafe(name, val, flags)
9548 const char *name, *val;
9551 struct jmploc jmploc;
9552 struct jmploc *volatile savehandler = handler;
9558 if (setjmp(jmploc.loc))
9562 setvar(name, val, flags);
9564 handler = savehandler;
9569 getopts(optstr, optvar, optfirst, myoptind, optoff)
9581 char **optnext = optfirst + *myoptind - 1;
9583 if (*myoptind <= 1 || *optoff < 0 || !(*(optnext - 1)) ||
9584 strlen(*(optnext - 1)) < *optoff)
9587 p = *(optnext - 1) + *optoff;
9588 if (p == NULL || *p == '\0') {
9589 /* Current word is done, advance */
9590 if (optnext == NULL)
9593 if (p == NULL || *p != '-' || *++p == '\0') {
9595 *myoptind = optnext - optfirst + 1;
9601 if (p[0] == '-' && p[1] == '\0') /* check for "--" */
9606 for (q = optstr; *q != c; ) {
9608 if (optstr[0] == ':') {
9611 err |= setvarsafe("OPTARG", s, 0);
9614 outfmt(&errout, "Illegal option -%c\n", c);
9615 (void) unsetvar("OPTARG");
9625 if (*p == '\0' && (p = *optnext) == NULL) {
9626 if (optstr[0] == ':') {
9629 err |= setvarsafe("OPTARG", s, 0);
9633 outfmt(&errout, "No arg for -%c option\n", c);
9634 (void) unsetvar("OPTARG");
9642 setvarsafe("OPTARG", p, 0);
9646 setvarsafe("OPTARG", "", 0);
9647 *myoptind = optnext - optfirst + 1;
9654 *optoff = p ? p - *(optnext - 1) : -1;
9655 fmtstr(s, sizeof(s), "%d", *myoptind);
9656 err |= setvarsafe("OPTIND", s, VNOFUNC);
9659 err |= setvarsafe(optvar, s, 0);
9671 * XXX - should get rid of. have all builtins use getopt(3). the
9672 * library getopt must have the BSD extension static variable "optreset"
9673 * otherwise it can't be used within the shell safely.
9675 * Standard option processing (a la getopt) for builtin routines. The
9676 * only argument that is passed to nextopt is the option string; the
9677 * other arguments are unnecessary. It return the character, or '\0' on
9683 const char *optstring;
9689 if ((p = optptr) == NULL || *p == '\0') {
9691 if (p == NULL || *p != '-' || *++p == '\0')
9694 if (p[0] == '-' && p[1] == '\0') /* check for "--" */
9698 for (q = optstring ; *q != c ; ) {
9700 error("Illegal option -%c", c);
9705 if (*p == '\0' && (p = *argptr++) == NULL)
9706 error("No arg for -%c option", c);
9716 * Shell output routines. We use our own output routines because:
9717 * When a builtin command is interrupted we have to discard
9718 * any pending output.
9719 * When a builtin command appears in back quotes, we want to
9720 * save the output of the command in a region obtained
9721 * via malloc, rather than doing a fork and reading the
9722 * output of the command via a pipe.
9723 * Our output routines may be smaller than the stdio routines.
9728 #ifndef USE_GLIBC_STDIO
9729 static void __outstr (const char *, size_t, struct output*);
9733 #ifndef USE_GLIBC_STDIO
9735 __outstr(const char *p, size_t len, struct output *dest) {
9736 if (!dest->bufsize) {
9738 } else if (dest->buf == NULL) {
9739 if (len > dest->bufsize && dest->fd == MEM_OUT) {
9740 dest->bufsize = len;
9743 dest->buf = ckmalloc(dest->bufsize);
9744 dest->nextc = dest->buf;
9745 dest->nleft = dest->bufsize;
9747 } else if (dest->fd == MEM_OUT) {
9750 offset = dest->bufsize;
9752 if (dest->bufsize >= len) {
9753 dest->bufsize <<= 1;
9755 dest->bufsize += len;
9757 dest->buf = ckrealloc(dest->buf, dest->bufsize);
9758 dest->nleft = dest->bufsize - offset;
9759 dest->nextc = dest->buf + offset;
9765 if (len < dest->nleft) {
9767 memcpy(dest->nextc, p, len);
9772 if (xwrite(dest->fd, p, len) < len)
9773 dest->flags |= OUTPUT_ERR;
9779 outstr(const char *p, struct output *file)
9781 #ifdef USE_GLIBC_STDIO
9783 fputs(p, file->stream);
9792 if ((file->nleft -= len) > 0) {
9793 memcpy(file->nextc, p, len);
9797 __outstr(p, len, file);
9802 #ifndef USE_GLIBC_STDIO
9808 struct output *dest;
9810 __outstr(&c, 1, dest);
9826 struct output *dest;
9828 #ifdef USE_GLIBC_STDIO
9830 fflush(dest->stream);
9835 len = dest->nextc - dest->buf;
9836 if (dest->buf == NULL || !len || dest->fd < 0)
9838 dest->nextc = dest->buf;
9839 dest->nleft = dest->bufsize;
9840 if (xwrite(dest->fd, dest->buf, len) < len)
9841 dest->flags |= OUTPUT_ERR;
9861 outfmt(struct output *file, const char *fmt, ...)
9870 struct output *file;
9874 file = va_arg(ap, struct output *);
9875 fmt = va_arg(ap, const char *);
9879 doformat(file, fmt, ap);
9886 out1fmt(const char *fmt, ...)
9897 fmt = va_arg(ap, const char *);
9901 doformat(out1, fmt, ap);
9907 fmtstr(char *outbuf, size_t length, const char *fmt, ...)
9920 outbuf = va_arg(ap, char *);
9921 length = va_arg(ap, size_t);
9922 fmt = va_arg(ap, const char *);
9927 vsnprintf(outbuf, length, fmt, ap);
9931 #ifndef USE_GLIBC_STDIO
9934 doformat(struct output *dest, const char *f, va_list ap)
9943 nchars = vsnprintf(pm, size, f, ap);
9958 * Version of write which resumes after a signal is caught.
9962 xwrite(int fd, const char *buf, int nbytes)
9971 i = write(fd, buf, n);
9977 } else if (i == 0) {
9980 } else if (errno != EINTR) {
9987 #ifdef USE_GLIBC_STDIO
9988 static void initstreams() {
9989 output.stream = stdout;
9990 errout.stream = stderr;
9997 memout.stream = open_memstream(&memout.buf, &memout.bufsize);
10005 error = fclose(memout.stream);
10006 memout.stream = NULL;
10011 * Shell command parser.
10014 #define EOFMARKLEN 79
10019 struct heredoc *next; /* next here document in list */
10020 union node *here; /* redirection node */
10021 char *eofmark; /* string indicating end of input */
10022 int striptabs; /* if set, strip leading tabs */
10025 static struct heredoc *heredoclist; /* list of here documents to read */
10026 static int parsebackquote; /* nonzero if we are inside backquotes */
10027 static int doprompt; /* if set, prompt the user */
10028 static int needprompt; /* true if interactive and at start of line */
10029 static int lasttoken; /* last token read */
10031 static char *wordtext; /* text of last word returned by readtoken */
10033 static struct nodelist *backquotelist;
10034 static union node *redirnode;
10035 struct heredoc *heredoc;
10036 static int quoteflag; /* set if (part of) last token was quoted */
10037 static int startlinno; /* line # where last token started */
10040 static union node *list (int);
10041 static union node *andor (void);
10042 static union node *pipeline (void);
10043 static union node *command (void);
10044 static union node *simplecmd (void);
10045 static void parsefname (void);
10046 static void parseheredoc (void);
10047 static int peektoken (void);
10048 static int readtoken (void);
10049 static int xxreadtoken (void);
10050 static int readtoken1 (int, char const *, char *, int);
10051 static int noexpand (char *);
10052 static void synexpect (int) __attribute__((noreturn));
10053 static void synerror (const char *) __attribute__((noreturn));
10054 static void setprompt (int);
10058 * Read and parse a command. Returns NEOF on end of file. (NULL is a
10059 * valid parse tree indicating a blank line.)
10062 static union node *
10063 parsecmd(int interact)
10068 doprompt = interact;
10084 static union node *
10088 union node *n1, *n2, *n3;
10092 if (nlflag == 0 && tokendlist[peektoken()])
10098 if (tok == TBACKGND) {
10099 if (n2->type == NCMD || n2->type == NPIPE) {
10100 n2->ncmd.backgnd = 1;
10101 } else if (n2->type == NREDIR) {
10102 n2->type = NBACKGND;
10104 n3 = (union node *)stalloc(sizeof (struct nredir));
10105 n3->type = NBACKGND;
10107 n3->nredir.redirect = NULL;
10115 n3 = (union node *)stalloc(sizeof (struct nbinary));
10117 n3->nbinary.ch1 = n1;
10118 n3->nbinary.ch2 = n2;
10135 if (tokendlist[peektoken()])
10142 pungetc(); /* push back EOF on input */
10155 static union node *
10157 union node *n1, *n2, *n3;
10163 if ((t = readtoken()) == TAND) {
10165 } else if (t == TOR) {
10173 n3 = (union node *)stalloc(sizeof (struct nbinary));
10175 n3->nbinary.ch1 = n1;
10176 n3->nbinary.ch2 = n2;
10183 static union node *
10185 union node *n1, *n2, *pipenode;
10186 struct nodelist *lp, *prev;
10190 TRACE(("pipeline: entered\n"));
10191 if (readtoken() == TNOT) {
10197 if (readtoken() == TPIPE) {
10198 pipenode = (union node *)stalloc(sizeof (struct npipe));
10199 pipenode->type = NPIPE;
10200 pipenode->npipe.backgnd = 0;
10201 lp = (struct nodelist *)stalloc(sizeof (struct nodelist));
10202 pipenode->npipe.cmdlist = lp;
10206 lp = (struct nodelist *)stalloc(sizeof (struct nodelist));
10210 } while (readtoken() == TPIPE);
10216 n2 = (union node *)stalloc(sizeof (struct nnot));
10226 static union node *
10228 union node *n1, *n2;
10229 union node *ap, **app;
10230 union node *cp, **cpp;
10231 union node *redir, **rpp;
10238 switch (readtoken()) {
10240 n1 = (union node *)stalloc(sizeof (struct nif));
10242 n1->nif.test = list(0);
10243 if (readtoken() != TTHEN)
10245 n1->nif.ifpart = list(0);
10247 while (readtoken() == TELIF) {
10248 n2->nif.elsepart = (union node *)stalloc(sizeof (struct nif));
10249 n2 = n2->nif.elsepart;
10251 n2->nif.test = list(0);
10252 if (readtoken() != TTHEN)
10254 n2->nif.ifpart = list(0);
10256 if (lasttoken == TELSE)
10257 n2->nif.elsepart = list(0);
10259 n2->nif.elsepart = NULL;
10262 if (readtoken() != TFI)
10269 n1 = (union node *)stalloc(sizeof (struct nbinary));
10270 n1->type = (lasttoken == TWHILE)? NWHILE : NUNTIL;
10271 n1->nbinary.ch1 = list(0);
10272 if ((got=readtoken()) != TDO) {
10273 TRACE(("expecting DO got %s %s\n", tokname[got], got == TWORD ? wordtext : ""));
10276 n1->nbinary.ch2 = list(0);
10277 if (readtoken() != TDONE)
10283 if (readtoken() != TWORD || quoteflag || ! goodname(wordtext))
10284 synerror("Bad for loop variable");
10285 n1 = (union node *)stalloc(sizeof (struct nfor));
10287 n1->nfor.var = wordtext;
10289 if (readtoken() == TIN) {
10291 while (readtoken() == TWORD) {
10292 n2 = (union node *)stalloc(sizeof (struct narg));
10294 n2->narg.text = wordtext;
10295 n2->narg.backquote = backquotelist;
10297 app = &n2->narg.next;
10300 n1->nfor.args = ap;
10301 if (lasttoken != TNL && lasttoken != TSEMI)
10304 static char argvars[5] = {CTLVAR, VSNORMAL|VSQUOTE,
10306 n2 = (union node *)stalloc(sizeof (struct narg));
10308 n2->narg.text = argvars;
10309 n2->narg.backquote = NULL;
10310 n2->narg.next = NULL;
10311 n1->nfor.args = n2;
10313 * Newline or semicolon here is optional (but note
10314 * that the original Bourne shell only allowed NL).
10316 if (lasttoken != TNL && lasttoken != TSEMI)
10320 if (readtoken() != TDO)
10322 n1->nfor.body = list(0);
10323 if (readtoken() != TDONE)
10328 n1 = (union node *)stalloc(sizeof (struct ncase));
10330 if (readtoken() != TWORD)
10332 n1->ncase.expr = n2 = (union node *)stalloc(sizeof (struct narg));
10334 n2->narg.text = wordtext;
10335 n2->narg.backquote = backquotelist;
10336 n2->narg.next = NULL;
10339 } while (readtoken() == TNL);
10340 if (lasttoken != TIN)
10341 synerror("expecting \"in\"");
10342 cpp = &n1->ncase.cases;
10343 checkkwd = 2, readtoken();
10345 if (lasttoken == TLP)
10347 *cpp = cp = (union node *)stalloc(sizeof (struct nclist));
10349 app = &cp->nclist.pattern;
10351 *app = ap = (union node *)stalloc(sizeof (struct narg));
10353 ap->narg.text = wordtext;
10354 ap->narg.backquote = backquotelist;
10355 if (checkkwd = 2, readtoken() != TPIPE)
10357 app = &ap->narg.next;
10360 ap->narg.next = NULL;
10361 if (lasttoken != TRP)
10363 cp->nclist.body = list(0);
10366 if ((t = readtoken()) != TESAC) {
10368 synexpect(TENDCASE);
10370 checkkwd = 2, readtoken();
10372 cpp = &cp->nclist.next;
10373 } while(lasttoken != TESAC);
10378 n1 = (union node *)stalloc(sizeof (struct nredir));
10379 n1->type = NSUBSHELL;
10380 n1->nredir.n = list(0);
10381 n1->nredir.redirect = NULL;
10382 if (readtoken() != TRP)
10388 if (readtoken() != TEND)
10392 /* Handle an empty command like other simple commands. */
10401 * An empty command before a ; doesn't make much sense, and
10402 * should certainly be disallowed in the case of `if ;'.
10416 /* Now check for redirection which may follow command */
10417 while (readtoken() == TREDIR) {
10418 *rpp = n2 = redirnode;
10419 rpp = &n2->nfile.next;
10425 if (n1->type != NSUBSHELL) {
10426 n2 = (union node *)stalloc(sizeof (struct nredir));
10431 n1->nredir.redirect = redir;
10438 static union node *
10440 union node *args, **app;
10441 union node *n = NULL;
10442 union node *vars, **vpp;
10443 union node **rpp, *redir;
10456 switch (readtoken()) {
10459 n = (union node *)stalloc(sizeof (struct narg));
10461 n->narg.text = wordtext;
10462 n->narg.backquote = backquotelist;
10463 if (lasttoken == TWORD) {
10465 app = &n->narg.next;
10468 vpp = &n->narg.next;
10472 *rpp = n = redirnode;
10473 rpp = &n->nfile.next;
10474 parsefname(); /* read name of redirection file */
10478 args && app == &args->narg.next &&
10481 /* We have a function */
10482 if (readtoken() != TRP)
10486 n->narg.next = command();
10499 n = (union node *)stalloc(sizeof (struct ncmd));
10501 n->ncmd.backgnd = 0;
10502 n->ncmd.args = args;
10503 n->ncmd.assign = vars;
10504 n->ncmd.redirect = redir;
10508 static union node *
10512 n = (union node *)stalloc(sizeof (struct narg));
10514 n->narg.next = NULL;
10515 n->narg.text = wordtext;
10516 n->narg.backquote = backquotelist;
10520 static void fixredir(union node *n, const char *text, int err)
10522 TRACE(("Fix redir %s %d\n", text, err));
10524 n->ndup.vname = NULL;
10526 if (is_digit(text[0]) && text[1] == '\0')
10527 n->ndup.dupfd = digit_val(text[0]);
10528 else if (text[0] == '-' && text[1] == '\0')
10529 n->ndup.dupfd = -1;
10533 synerror("Bad fd number");
10535 n->ndup.vname = makename();
10542 union node *n = redirnode;
10544 if (readtoken() != TWORD)
10546 if (n->type == NHERE) {
10547 struct heredoc *here = heredoc;
10551 if (quoteflag == 0)
10553 TRACE(("Here document %d\n", n->type));
10554 if (here->striptabs) {
10555 while (*wordtext == '\t')
10558 if (! noexpand(wordtext) || (i = strlen(wordtext)) == 0 || i > EOFMARKLEN)
10559 synerror("Illegal eof marker for << redirection");
10560 rmescapes(wordtext);
10561 here->eofmark = wordtext;
10563 if (heredoclist == NULL)
10564 heredoclist = here;
10566 for (p = heredoclist ; p->next ; p = p->next);
10569 } else if (n->type == NTOFD || n->type == NFROMFD) {
10570 fixredir(n, wordtext, 0);
10572 n->nfile.fname = makename();
10578 * Input any here documents.
10583 struct heredoc *here;
10586 while (heredoclist) {
10587 here = heredoclist;
10588 heredoclist = here->next;
10593 readtoken1(pgetc(), here->here->type == NHERE? SQSYNTAX : DQSYNTAX,
10594 here->eofmark, here->striptabs);
10595 n = (union node *)stalloc(sizeof (struct narg));
10596 n->narg.type = NARG;
10597 n->narg.next = NULL;
10598 n->narg.text = wordtext;
10599 n->narg.backquote = backquotelist;
10600 here->here->nhere.doc = n;
10617 int savecheckkwd = checkkwd;
10618 int savecheckalias = checkalias;
10623 int alreadyseen = tokpushback;
10633 checkalias = savecheckalias;
10640 if (checkkwd == 2) {
10649 * check for keywords
10651 if (t == TWORD && !quoteflag)
10653 const char *const *pp;
10655 if ((pp = findkwd(wordtext))) {
10656 lasttoken = t = pp - parsekwd + KWDOFFSET;
10657 TRACE(("keyword %s recognized\n", tokname[t]));
10668 } else if (checkalias == 2 && isassignment(wordtext)) {
10669 lasttoken = t = TASSIGN;
10670 } else if (checkalias) {
10671 if (!quoteflag && (ap = lookupalias(wordtext, 1)) != NULL) {
10673 pushstring(ap->val, strlen(ap->val), ap);
10675 checkkwd = savecheckkwd;
10684 TRACE(("token %s %s\n", tokname[t], t == TWORD || t == TASSIGN ? wordtext : ""));
10686 TRACE(("reread token %s %s\n", tokname[t], t == TWORD || t == TASSIGN ? wordtext : ""));
10693 * Read the next input token.
10694 * If the token is a word, we set backquotelist to the list of cmds in
10695 * backquotes. We set quoteflag to true if any part of the word was
10697 * If the token is TREDIR, then we set redirnode to a structure containing
10699 * In all cases, the variable startlinno is set to the number of the line
10700 * on which the token starts.
10702 * [Change comment: here documents and internal procedures]
10703 * [Readtoken shouldn't have any arguments. Perhaps we should make the
10704 * word parsing code into a separate routine. In this case, readtoken
10705 * doesn't need to have any internal procedures, but parseword does.
10706 * We could also make parseoperator in essence the main routine, and
10707 * have parseword (readtoken1?) handle both words and redirection.]
10710 #define RETURN(token) return lasttoken = token
10724 startlinno = plinno;
10725 for (;;) { /* until token or start of word found */
10728 case ' ': case '\t':
10732 while ((c = pgetc()) != '\n' && c != PEOF);
10736 if (pgetc() == '\n') {
10737 startlinno = ++plinno;
10748 needprompt = doprompt;
10753 if (pgetc() == '&')
10758 if (pgetc() == '|')
10763 if (pgetc() == ';')
10776 return readtoken1(c, BASESYNTAX, (char *)NULL, 0);
10783 * If eofmark is NULL, read a word or a redirection symbol. If eofmark
10784 * is not NULL, read a here document. In the latter case, eofmark is the
10785 * word which marks the end of the document and striptabs is true if
10786 * leading tabs should be stripped from the document. The argument firstc
10787 * is the first character of the input token or document.
10789 * Because C does not have internal subroutines, I have simulated them
10790 * using goto's to implement the subroutine linkage. The following macros
10791 * will run code that appears at the end of readtoken1.
10794 #define CHECKEND() {goto checkend; checkend_return:;}
10795 #define PARSEREDIR() {goto parseredir; parseredir_return:;}
10796 #define PARSESUB() {goto parsesub; parsesub_return:;}
10797 #define PARSEBACKQOLD() {oldstyle = 1; goto parsebackq; parsebackq_oldreturn:;}
10798 #define PARSEBACKQNEW() {oldstyle = 0; goto parsebackq; parsebackq_newreturn:;}
10799 #define PARSEARITH() {goto parsearith; parsearith_return:;}
10802 readtoken1(firstc, syntax, eofmark, striptabs)
10804 char const *syntax;
10811 char line[EOFMARKLEN + 1];
10812 struct nodelist *bqlist;
10815 int varnest; /* levels of variables expansion */
10816 int arinest; /* levels of arithmetic expansion */
10817 int parenlevel; /* levels of parens in arithmetic */
10818 int dqvarnest; /* levels of variables expansion within double quotes */
10820 char const *prevsyntax; /* syntax before arithmetic */
10822 /* Avoid longjmp clobbering */
10828 (void) &parenlevel;
10831 (void) &prevsyntax;
10835 startlinno = plinno;
10837 if (syntax == DQSYNTAX)
10846 STARTSTACKSTR(out);
10847 loop: { /* for each line, until end of word */
10848 CHECKEND(); /* set c to PEOF if at end of here document */
10849 for (;;) { /* until end of line or end of word */
10850 CHECKSTRSPACE(3, out); /* permit 3 calls to USTPUTC */
10851 switch(syntax[c]) {
10852 case CNL: /* '\n' */
10853 if (syntax == BASESYNTAX)
10854 goto endword; /* exit outer loop */
10862 goto loop; /* continue outer loop */
10867 if ((eofmark == NULL || dblquote) &&
10869 USTPUTC(CTLESC, out);
10872 case CBACK: /* backslash */
10875 USTPUTC('\\', out);
10877 } else if (c == '\n') {
10883 if (dblquote && c != '\\' && c != '`' && c != '$'
10884 && (c != '"' || eofmark != NULL))
10885 USTPUTC('\\', out);
10886 if (SQSYNTAX[c] == CCTL)
10887 USTPUTC(CTLESC, out);
10888 else if (eofmark == NULL)
10889 USTPUTC(CTLQUOTEMARK, out);
10895 if (eofmark == NULL)
10896 USTPUTC(CTLQUOTEMARK, out);
10900 if (eofmark == NULL)
10901 USTPUTC(CTLQUOTEMARK, out);
10906 if (eofmark != NULL && arinest == 0 &&
10911 syntax = ARISYNTAX;
10913 } else if (eofmark == NULL &&
10915 syntax = BASESYNTAX;
10921 case CVAR: /* '$' */
10922 PARSESUB(); /* parse substitution */
10924 case CENDVAR: /* '}' */
10927 if (dqvarnest > 0) {
10930 USTPUTC(CTLENDVAR, out);
10935 #ifdef ASH_MATH_SUPPORT
10936 case CLP: /* '(' in arithmetic */
10940 case CRP: /* ')' in arithmetic */
10941 if (parenlevel > 0) {
10945 if (pgetc() == ')') {
10946 if (--arinest == 0) {
10947 USTPUTC(CTLENDARI, out);
10948 syntax = prevsyntax;
10949 if (syntax == DQSYNTAX)
10957 * unbalanced parens
10958 * (don't 2nd guess - no error)
10966 case CBQUOTE: /* '`' */
10970 goto endword; /* exit outer loop */
10975 goto endword; /* exit outer loop */
10984 if (syntax == ARISYNTAX)
10985 synerror("Missing '))'");
10986 if (syntax != BASESYNTAX && ! parsebackquote && eofmark == NULL)
10987 synerror("Unterminated quoted string");
10988 if (varnest != 0) {
10989 startlinno = plinno;
10990 synerror("Missing '}'");
10992 USTPUTC('\0', out);
10993 len = out - stackblock();
10994 out = stackblock();
10995 if (eofmark == NULL) {
10996 if ((c == '>' || c == '<')
10999 && (*out == '\0' || is_digit(*out))) {
11001 return lasttoken = TREDIR;
11006 quoteflag = quotef;
11007 backquotelist = bqlist;
11008 grabstackblock(len);
11010 return lasttoken = TWORD;
11011 /* end of readtoken routine */
11016 * Check to see whether we are at the end of the here document. When this
11017 * is called, c is set to the first character of the next input line. If
11018 * we are at the end of the here document, this routine sets the c to PEOF.
11029 while (c == '\t') {
11033 if (c == *eofmark) {
11034 if (pfgets(line, sizeof line) != NULL) {
11038 for (q = eofmark + 1 ; *q && *p == *q ; p++, q++);
11039 if (*p == '\n' && *q == '\0') {
11042 needprompt = doprompt;
11044 pushstring(line, strlen(line), NULL);
11049 goto checkend_return;
11054 * Parse a redirection operator. The variable "out" points to a string
11055 * specifying the fd to be redirected. The variable "c" contains the
11056 * first character of the redirection operator.
11063 np = (union node *)stalloc(sizeof (struct nfile));
11068 np->type = NAPPEND;
11077 } else { /* c == '<' */
11079 switch (c = pgetc()) {
11081 if (sizeof (struct nfile) != sizeof (struct nhere)) {
11082 np = (union node *)stalloc(sizeof (struct nhere));
11086 heredoc = (struct heredoc *)stalloc(sizeof (struct heredoc));
11087 heredoc->here = np;
11088 if ((c = pgetc()) == '-') {
11089 heredoc->striptabs = 1;
11091 heredoc->striptabs = 0;
11097 np->type = NFROMFD;
11101 np->type = NFROMTO;
11111 np->nfile.fd = digit_val(fd);
11113 goto parseredir_return;
11118 * Parse a substitution. At this point, we have read the dollar sign
11119 * and nothing else.
11127 static const char types[] = "}-+?=";
11132 (c != '(' && c != '{' && !is_name(c) && !is_special(c))
11136 } else if (c == '(') { /* $(command) or $((arith)) */
11137 if (pgetc() == '(') {
11144 USTPUTC(CTLVAR, out);
11145 typeloc = out - stackblock();
11146 USTPUTC(VSNORMAL, out);
11147 subtype = VSNORMAL;
11151 if ((c = pgetc()) == '}')
11154 subtype = VSLENGTH;
11159 if (c > PEOA && is_name(c)) {
11163 } while (c > PEOA && is_in_name(c));
11164 } else if (is_digit(c)) {
11168 } while (is_digit(c));
11170 else if (is_special(c)) {
11175 badsub: synerror("Bad substitution");
11179 if (subtype == 0) {
11186 p = strchr(types, c);
11189 subtype = p - types + VSNORMAL;
11195 subtype = c == '#' ? VSTRIMLEFT :
11208 if (dblquote || arinest)
11210 *(stackblock() + typeloc) = subtype | flags;
11211 if (subtype != VSNORMAL) {
11218 goto parsesub_return;
11223 * Called to parse command substitutions. Newstyle is set if the command
11224 * is enclosed inside $(...); nlpp is a pointer to the head of the linked
11225 * list of commands (passed by reference), and savelen is the number of
11226 * characters on the top of the stack which must be preserved.
11230 struct nodelist **nlpp;
11233 char *volatile str;
11234 struct jmploc jmploc;
11235 struct jmploc *volatile savehandler;
11239 (void) &saveprompt;
11242 savepbq = parsebackquote;
11243 if (setjmp(jmploc.loc)) {
11246 parsebackquote = 0;
11247 handler = savehandler;
11248 longjmp(handler->loc, 1);
11252 savelen = out - stackblock();
11254 str = ckmalloc(savelen);
11255 memcpy(str, stackblock(), savelen);
11257 savehandler = handler;
11261 /* We must read until the closing backquote, giving special
11262 treatment to some slashes, and then push the string and
11263 reread it as input, interpreting it normally. */
11270 STARTSTACKSTR(pout);
11276 switch (pc = pgetc()) {
11281 if ((pc = pgetc()) == '\n') {
11288 * If eating a newline, avoid putting
11289 * the newline into the new character
11290 * stream (via the STPUTC after the
11295 if (pc != '\\' && pc != '`' && pc != '$'
11296 && (!dblquote || pc != '"'))
11297 STPUTC('\\', pout);
11307 startlinno = plinno;
11308 synerror("EOF in backquote substitution");
11312 needprompt = doprompt;
11321 STPUTC('\0', pout);
11322 psavelen = pout - stackblock();
11323 if (psavelen > 0) {
11324 pstr = grabstackstr(pout);
11325 setinputstring(pstr);
11330 nlpp = &(*nlpp)->next;
11331 *nlpp = (struct nodelist *)stalloc(sizeof (struct nodelist));
11332 (*nlpp)->next = NULL;
11333 parsebackquote = oldstyle;
11336 saveprompt = doprompt;
11343 doprompt = saveprompt;
11345 if (readtoken() != TRP)
11352 * Start reading from old file again, ignoring any pushed back
11353 * tokens left from the backquote parsing
11358 while (stackblocksize() <= savelen)
11360 STARTSTACKSTR(out);
11362 memcpy(out, str, savelen);
11363 STADJUST(savelen, out);
11369 parsebackquote = savepbq;
11370 handler = savehandler;
11371 if (arinest || dblquote)
11372 USTPUTC(CTLBACKQ | CTLQUOTE, out);
11374 USTPUTC(CTLBACKQ, out);
11376 goto parsebackq_oldreturn;
11378 goto parsebackq_newreturn;
11382 * Parse an arithmetic expansion (indicate start of one and set state)
11386 if (++arinest == 1) {
11387 prevsyntax = syntax;
11388 syntax = ARISYNTAX;
11389 USTPUTC(CTLARI, out);
11396 * we collapse embedded arithmetic expansion to
11397 * parenthesis, which should be equivalent
11401 goto parsearith_return;
11404 } /* end of readtoken */
11408 * Returns true if the text contains nothing to expand (no dollar signs
11420 while ((c = *p++) != '\0') {
11421 if (c == CTLQUOTEMARK)
11425 else if (BASESYNTAX[(int)c] == CCTL)
11433 * Return true if the argument is a legal variable name (a letter or
11434 * underscore followed by zero or more letters, underscores, and digits).
11438 goodname(const char *name)
11446 if (! is_in_name(*p))
11454 * Called when an unexpected token is read during the parse. The argument
11455 * is the token that is expected, or -1 if more than one type of token can
11456 * occur at this point.
11466 fmtstr(msg, 64, "%s unexpected (expecting %s)",
11467 tokname[lasttoken], tokname[token]);
11469 fmtstr(msg, 64, "%s unexpected", tokname[lasttoken]);
11477 synerror(const char *msg)
11480 outfmt(&errout, "%s: %d: ", commandname, startlinno);
11481 outfmt(&errout, "Syntax error: %s\n", msg);
11482 error((char *)NULL);
11488 * called by editline -- any expansions to the prompt
11489 * should be added here.
11491 static const char *
11492 getprompt(void *unused)
11494 switch (whichprompt) {
11502 return "<internal prompt error>";
11507 setprompt(int which)
11509 whichprompt = which;
11510 putprompt(getprompt(NULL));
11515 * Code for dealing with input/output redirection.
11518 #define EMPTY -2 /* marks an unused slot in redirtab */
11520 # define PIPESIZE 4096 /* amount of buffering in a pipe */
11522 # define PIPESIZE PIPE_BUF
11528 * Process a list of redirection commands. If the REDIR_PUSH flag is set,
11529 * old file descriptors are stashed away so that the redirection can be
11530 * undone by calling popredir. If the REDIR_BACKQ flag is set, then the
11531 * standard output, and the standard error if it becomes a duplicate of
11532 * stdout, is saved in memory.
11536 redirect(redir, flags)
11541 struct redirtab *sv = NULL;
11546 char memory[10]; /* file descriptors to write to memory */
11548 for (i = 10 ; --i >= 0 ; )
11550 memory[1] = flags & REDIR_BACKQ;
11551 if (flags & REDIR_PUSH) {
11552 sv = ckmalloc(sizeof (struct redirtab));
11553 for (i = 0 ; i < 10 ; i++)
11554 sv->renamed[i] = EMPTY;
11555 sv->next = redirlist;
11558 for (n = redir ; n ; n = n->nfile.next) {
11561 if ((n->nfile.type == NTOFD || n->nfile.type == NFROMFD) &&
11562 n->ndup.dupfd == fd)
11563 continue; /* redirect from/to same file descriptor */
11566 newfd = openredirect(n);
11567 if (((flags & REDIR_PUSH) && sv->renamed[fd] == EMPTY) ||
11571 } else if ((i = fcntl(fd, F_DUPFD, 10)) == -1) {
11575 dupredirect(n, newfd, memory);
11585 error("%d: %m", fd);
11591 if (flags & REDIR_PUSH) {
11592 sv->renamed[fd] = i;
11594 if (fd == fileno2) {
11598 } else if (fd != newfd) {
11604 dupredirect(n, newfd, memory);
11615 openredirect(redir)
11621 switch (redir->nfile.type) {
11623 fname = redir->nfile.expfname;
11624 if ((f = open(fname, O_RDONLY)) < 0)
11628 fname = redir->nfile.expfname;
11629 if ((f = open(fname, O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0)
11633 /* Take care of noclobber mode. */
11635 fname = redir->nfile.expfname;
11636 if ((f = noclobberopen(fname)) < 0)
11641 fname = redir->nfile.expfname;
11643 if ((f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
11646 if ((f = creat(fname, 0666)) < 0)
11651 fname = redir->nfile.expfname;
11653 if ((f = open(fname, O_WRONLY|O_CREAT|O_APPEND, 0666)) < 0)
11656 if ((f = open(fname, O_WRONLY)) < 0
11657 && (f = creat(fname, 0666)) < 0)
11659 lseek(f, (off_t)0, 2);
11666 /* Fall through to eliminate warning. */
11673 f = openhere(redir);
11679 error("cannot create %s: %s", fname, errmsg(errno, E_CREAT));
11681 error("cannot open %s: %s", fname, errmsg(errno, E_OPEN));
11686 dupredirect(union node *redir, int f, char memory[10])
11688 int fd = redir->nfile.fd;
11691 if (redir->nfile.type == NTOFD || redir->nfile.type == NFROMFD) {
11692 if (redir->ndup.dupfd >= 0) { /* if not ">&-" */
11693 if (memory[redir->ndup.dupfd])
11696 dup_as_newfd(redir->ndup.dupfd, fd);
11702 dup_as_newfd(f, fd);
11710 * Handle here documents. Normally we fork off a process to write the
11711 * data to a pipe. If the document is short, we can stuff the data in
11712 * the pipe without forking.
11723 error("Pipe call failed");
11724 if (redir->type == NHERE) {
11725 len = strlen(redir->nhere.doc->narg.text);
11726 if (len <= PIPESIZE) {
11727 xwrite(pip[1], redir->nhere.doc->narg.text, len);
11731 if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) {
11733 signal(SIGINT, SIG_IGN);
11734 signal(SIGQUIT, SIG_IGN);
11735 signal(SIGHUP, SIG_IGN);
11737 signal(SIGTSTP, SIG_IGN);
11739 signal(SIGPIPE, SIG_DFL);
11740 if (redir->type == NHERE)
11741 xwrite(pip[1], redir->nhere.doc->narg.text, len);
11743 expandhere(redir->nhere.doc, pip[1]);
11753 * Undo the effects of the last redirection.
11759 struct redirtab *rp = redirlist;
11763 for (i = 0 ; i < 10 ; i++) {
11764 if (rp->renamed[i] != EMPTY) {
11768 if (rp->renamed[i] >= 0) {
11769 dup_as_newfd(rp->renamed[i], i);
11770 close(rp->renamed[i]);
11772 if (rp->renamed[i] == fileno2) {
11777 redirlist = rp->next;
11783 * Discard all saved file descriptors.
11788 struct redirtab *rp;
11791 for (rp = redirlist ; rp ; rp = rp->next) {
11792 for (i = 0 ; i < 10 ; i++) {
11793 if (rp->renamed[i] >= 0) {
11794 close(rp->renamed[i]);
11795 if (rp->renamed[i] == fileno2) {
11799 rp->renamed[i] = EMPTY;
11802 if (fileno2 != 2 && fileno2 >= 0) {
11810 * Copy a file descriptor to be >= to. Returns -1
11811 * if the source file descriptor is closed, EMPTY if there are no unused
11812 * file descriptors left.
11816 dup_as_newfd(from, to)
11822 newfd = fcntl(from, F_DUPFD, to);
11824 if (errno == EMFILE)
11827 error("%d: %m", from);
11833 * Open a file in noclobber mode.
11834 * The code was copied from bash.
11837 noclobberopen(const char *fname)
11840 struct stat finfo, finfo2;
11843 * If the file exists and is a regular file, return an error
11846 r = stat(fname, &finfo);
11847 if (r == 0 && S_ISREG(finfo.st_mode)) {
11853 * If the file was not present (r != 0), make sure we open it
11854 * exclusively so that if it is created before we open it, our open
11855 * will fail. Make sure that we do not truncate an existing file.
11856 * Note that we don't turn on O_EXCL unless the stat failed -- if the
11857 * file was not a regular file, we leave O_EXCL off.
11860 return open(fname, O_WRONLY|O_CREAT|O_EXCL, 0666);
11861 fd = open(fname, O_WRONLY|O_CREAT, 0666);
11863 /* If the open failed, return the file descriptor right away. */
11868 * OK, the open succeeded, but the file may have been changed from a
11869 * non-regular file to a regular file between the stat and the open.
11870 * We are assuming that the O_EXCL open handles the case where FILENAME
11871 * did not exist and is symlinked to an existing file between the stat
11876 * If we can open it and fstat the file descriptor, and neither check
11877 * revealed that it was a regular file, and the file has not been
11878 * replaced, return the file descriptor.
11880 if (fstat(fd, &finfo2) == 0 && !S_ISREG(finfo2.st_mode) &&
11881 finfo.st_dev == finfo2.st_dev && finfo.st_ino == finfo2.st_ino)
11884 /* The file has been replaced. badness. */
11889 /*#ifdef __weak_alias
11890 __weak_alias(getmode,_getmode)
11891 __weak_alias(setmode,_setmode)
11895 #define S_ISTXT __S_ISVTX
11898 #define SET_LEN 6 /* initial # of bitcmd struct to malloc */
11899 #define SET_LEN_INCR 4 /* # of bitcmd structs to add as needed */
11901 typedef struct bitcmd {
11907 #define CMD2_CLR 0x01
11908 #define CMD2_SET 0x02
11909 #define CMD2_GBITS 0x04
11910 #define CMD2_OBITS 0x08
11911 #define CMD2_UBITS 0x10
11913 static BITCMD *addcmd (BITCMD *, int, int, int, u_int);
11914 static void compress_mode (BITCMD *);
11915 #ifdef SETMODE_DEBUG
11916 static void dumpmode (BITCMD *);
11920 * Given the old mode and an array of bitcmd structures, apply the operations
11921 * described in the bitcmd structures to the old mode, and return the new mode.
11922 * Note that there is no '=' command; a strict assignment is just a '-' (clear
11923 * bits) followed by a '+' (set bits).
11926 getmode(bbox, omode)
11931 mode_t clrval, newmode, value;
11933 _DIAGASSERT(bbox != NULL);
11935 set = (const BITCMD *)bbox;
11937 for (value = 0;; set++)
11940 * When copying the user, group or other bits around, we "know"
11941 * where the bits are in the mode so that we can do shifts to
11942 * copy them around. If we don't use shifts, it gets real
11943 * grundgy with lots of single bit checks and bit sets.
11946 value = (newmode & S_IRWXU) >> 6;
11950 value = (newmode & S_IRWXG) >> 3;
11954 value = newmode & S_IRWXO;
11955 common: if (set->cmd2 & CMD2_CLR) {
11957 (set->cmd2 & CMD2_SET) ? S_IRWXO : value;
11958 if (set->cmd2 & CMD2_UBITS)
11959 newmode &= ~((clrval<<6) & set->bits);
11960 if (set->cmd2 & CMD2_GBITS)
11961 newmode &= ~((clrval<<3) & set->bits);
11962 if (set->cmd2 & CMD2_OBITS)
11963 newmode &= ~(clrval & set->bits);
11965 if (set->cmd2 & CMD2_SET) {
11966 if (set->cmd2 & CMD2_UBITS)
11967 newmode |= (value<<6) & set->bits;
11968 if (set->cmd2 & CMD2_GBITS)
11969 newmode |= (value<<3) & set->bits;
11970 if (set->cmd2 & CMD2_OBITS)
11971 newmode |= value & set->bits;
11976 newmode |= set->bits;
11980 newmode &= ~set->bits;
11984 if (omode & (S_IFDIR|S_IXUSR|S_IXGRP|S_IXOTH))
11985 newmode |= set->bits;
11990 #ifdef SETMODE_DEBUG
11991 (void)printf("getmode:%04o -> %04o\n", omode, newmode);
11997 #define ADDCMD(a, b, c, d) do { \
11998 if (set >= endset) { \
12000 setlen += SET_LEN_INCR; \
12001 newset = realloc(saveset, sizeof(BITCMD) * setlen); \
12002 if (newset == NULL) { \
12006 set = newset + (set - saveset); \
12007 saveset = newset; \
12008 endset = newset + (setlen - 2); \
12010 set = addcmd(set, (a), (b), (c), (d)); \
12011 } while (/*CONSTCOND*/0)
12013 #define STANDARD_BITS (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO)
12021 BITCMD *set, *saveset, *endset;
12022 sigset_t mysigset, sigoset;
12024 int equalopdone = 0; /* pacify gcc */
12025 int permXbits, setlen;
12031 * Get a copy of the mask for the permissions that are mask relative.
12032 * Flip the bits, we want what's not set. Since it's possible that
12033 * the caller is opening files inside a signal handler, protect them
12036 sigfillset(&mysigset);
12037 (void)sigprocmask(SIG_BLOCK, &mysigset, &sigoset);
12038 (void)umask(mask = umask(0));
12040 (void)sigprocmask(SIG_SETMASK, &sigoset, NULL);
12042 setlen = SET_LEN + 2;
12044 if ((set = malloc((u_int)(sizeof(BITCMD) * setlen))) == NULL)
12047 endset = set + (setlen - 2);
12050 * If an absolute number, get it and return; disallow non-octal digits
12053 if (isdigit((unsigned char)*p)) {
12054 perm = (mode_t)strtol(p, &ep, 8);
12055 if (*ep || perm & ~(STANDARD_BITS|S_ISTXT)) {
12059 ADDCMD('=', (STANDARD_BITS|S_ISTXT), perm, mask);
12065 * Build list of structures to set/clear/copy bits as described by
12066 * each clause of the symbolic mode.
12069 /* First, find out which bits might be modified. */
12070 for (who = 0;; ++p) {
12073 who |= STANDARD_BITS;
12076 who |= S_ISUID|S_IRWXU;
12079 who |= S_ISGID|S_IRWXG;
12089 getop: if ((op = *p++) != '+' && op != '-' && op != '=') {
12097 for (perm = 0, permXbits = 0;; ++p) {
12100 perm |= S_IRUSR|S_IRGRP|S_IROTH;
12104 * If specific bits where requested and
12105 * only "other" bits ignore set-id.
12107 if (who == 0 || (who & ~S_IRWXO))
12108 perm |= S_ISUID|S_ISGID;
12112 * If specific bits where requested and
12113 * only "other" bits ignore set-id.
12115 if (who == 0 || (who & ~S_IRWXO)) {
12121 perm |= S_IWUSR|S_IWGRP|S_IWOTH;
12124 permXbits = S_IXUSR|S_IXGRP|S_IXOTH;
12127 perm |= S_IXUSR|S_IXGRP|S_IXOTH;
12133 * When ever we hit 'u', 'g', or 'o', we have
12134 * to flush out any partial mode that we have,
12135 * and then do the copying of the mode bits.
12138 ADDCMD(op, who, perm, mask);
12143 if (op == '+' && permXbits) {
12144 ADDCMD('X', who, permXbits, mask);
12147 ADDCMD(*p, who, op, mask);
12152 * Add any permissions that we haven't already
12155 if (perm || (op == '=' && !equalopdone)) {
12158 ADDCMD(op, who, perm, mask);
12162 ADDCMD('X', who, permXbits, mask);
12176 #ifdef SETMODE_DEBUG
12177 (void)printf("Before compress_mode()\n");
12180 compress_mode(saveset);
12181 #ifdef SETMODE_DEBUG
12182 (void)printf("After compress_mode()\n");
12189 addcmd(set, op, who, oparg, mask)
12196 _DIAGASSERT(set != NULL);
12201 set->bits = who ? who : STANDARD_BITS;
12210 set->bits = (who ? who : mask) & oparg;
12218 set->cmd2 = ((who & S_IRUSR) ? CMD2_UBITS : 0) |
12219 ((who & S_IRGRP) ? CMD2_GBITS : 0) |
12220 ((who & S_IROTH) ? CMD2_OBITS : 0);
12221 set->bits = (mode_t)~0;
12223 set->cmd2 = CMD2_UBITS | CMD2_GBITS | CMD2_OBITS;
12228 set->cmd2 |= CMD2_SET;
12229 else if (oparg == '-')
12230 set->cmd2 |= CMD2_CLR;
12231 else if (oparg == '=')
12232 set->cmd2 |= CMD2_SET|CMD2_CLR;
12238 #ifdef SETMODE_DEBUG
12244 _DIAGASSERT(set != NULL);
12246 for (; set->cmd; ++set)
12247 (void)printf("cmd: '%c' bits %04o%s%s%s%s%s%s\n",
12248 set->cmd, set->bits, set->cmd2 ? " cmd2:" : "",
12249 set->cmd2 & CMD2_CLR ? " CLR" : "",
12250 set->cmd2 & CMD2_SET ? " SET" : "",
12251 set->cmd2 & CMD2_UBITS ? " UBITS" : "",
12252 set->cmd2 & CMD2_GBITS ? " GBITS" : "",
12253 set->cmd2 & CMD2_OBITS ? " OBITS" : "");
12258 * Given an array of bitcmd structures, compress by compacting consecutive
12259 * '+', '-' and 'X' commands into at most 3 commands, one of each. The 'u',
12260 * 'g' and 'o' commands continue to be separate. They could probably be
12261 * compacted, but it's not worth the effort.
12268 int setbits, clrbits, Xbits, op;
12270 _DIAGASSERT(set != NULL);
12272 for (nset = set;;) {
12273 /* Copy over any 'u', 'g' and 'o' commands. */
12274 while ((op = nset->cmd) != '+' && op != '-' && op != 'X') {
12280 for (setbits = clrbits = Xbits = 0;; nset++) {
12281 if ((op = nset->cmd) == '-') {
12282 clrbits |= nset->bits;
12283 setbits &= ~nset->bits;
12284 Xbits &= ~nset->bits;
12285 } else if (op == '+') {
12286 setbits |= nset->bits;
12287 clrbits &= ~nset->bits;
12288 Xbits &= ~nset->bits;
12289 } else if (op == 'X')
12290 Xbits |= nset->bits & ~setbits;
12297 set->bits = clrbits;
12303 set->bits = setbits;
12315 static void shtree (union node *, int, char *, FILE*);
12316 static void shcmd (union node *, FILE *);
12317 static void sharg (union node *, FILE *);
12318 static void indent (int, char *, FILE *);
12319 static void trstring (char *);
12326 trputs("showtree called\n");
12327 shtree(n, 1, NULL, stdout);
12332 shtree(n, ind, pfx, fp)
12338 struct nodelist *lp;
12344 indent(ind, pfx, fp);
12355 shtree(n->nbinary.ch1, ind, NULL, fp);
12358 shtree(n->nbinary.ch2, ind, NULL, fp);
12366 for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
12371 if (n->npipe.backgnd)
12377 fprintf(fp, "<node type %d>", n->type);
12397 for (np = cmd->ncmd.args ; np ; np = np->narg.next) {
12403 for (np = cmd->ncmd.redirect ; np ; np = np->nfile.next) {
12406 switch (np->nfile.type) {
12407 case NTO: s = ">"; dftfd = 1; break;
12408 case NAPPEND: s = ">>"; dftfd = 1; break;
12409 case NTOFD: s = ">&"; dftfd = 1; break;
12410 case NTOOV: s = ">|"; dftfd = 1; break;
12411 case NFROM: s = "<"; dftfd = 0; break;
12412 case NFROMFD: s = "<&"; dftfd = 0; break;
12413 case NFROMTO: s = "<>"; dftfd = 0; break;
12414 default: s = "*error*"; dftfd = 0; break;
12416 if (np->nfile.fd != dftfd)
12417 fprintf(fp, "%d", np->nfile.fd);
12419 if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) {
12420 fprintf(fp, "%d", np->ndup.dupfd);
12422 sharg(np->nfile.fname, fp);
12436 struct nodelist *bqlist;
12439 if (arg->type != NARG) {
12440 printf("<node type %d>\n", arg->type);
12444 bqlist = arg->narg.backquote;
12445 for (p = arg->narg.text ; *p ; p++) {
12454 if (subtype == VSLENGTH)
12460 if (subtype & VSNUL)
12463 switch (subtype & VSTYPE) {
12482 case VSTRIMLEFTMAX:
12489 case VSTRIMRIGHTMAX:
12496 printf("<subtype %d>", subtype);
12503 case CTLBACKQ|CTLQUOTE:
12506 shtree(bqlist->n, -1, NULL, fp);
12518 indent(amount, pfx, fp)
12525 for (i = 0 ; i < amount ; i++) {
12526 if (pfx && i == amount - 1)
12544 static int debug = 1;
12546 static int debug = 0;
12554 if (tracefile == NULL)
12556 putc(c, tracefile);
12562 trace(const char *fmt, ...)
12570 fmt = va_arg(va, char *);
12572 if (tracefile != NULL) {
12573 (void) vfprintf(tracefile, fmt, va);
12574 if (strchr(fmt, '\n'))
12575 (void) fflush(tracefile);
12585 if (tracefile == NULL)
12587 fputs(s, tracefile);
12588 if (strchr(s, '\n'))
12600 if (tracefile == NULL)
12602 putc('"', tracefile);
12603 for (p = s ; *p ; p++) {
12605 case '\n': c = 'n'; goto backslash;
12606 case '\t': c = 't'; goto backslash;
12607 case '\r': c = 'r'; goto backslash;
12608 case '"': c = '"'; goto backslash;
12609 case '\\': c = '\\'; goto backslash;
12610 case CTLESC: c = 'e'; goto backslash;
12611 case CTLVAR: c = 'v'; goto backslash;
12612 case CTLVAR+CTLQUOTE: c = 'V'; goto backslash;
12613 case CTLBACKQ: c = 'q'; goto backslash;
12614 case CTLBACKQ+CTLQUOTE: c = 'Q'; goto backslash;
12615 backslash: putc('\\', tracefile);
12616 putc(c, tracefile);
12619 if (*p >= ' ' && *p <= '~')
12620 putc(*p, tracefile);
12622 putc('\\', tracefile);
12623 putc(*p >> 6 & 03, tracefile);
12624 putc(*p >> 3 & 07, tracefile);
12625 putc(*p & 07, tracefile);
12630 putc('"', tracefile);
12638 if (tracefile == NULL)
12643 putc(' ', tracefile);
12645 putc('\n', tracefile);
12660 #ifdef not_this_way
12663 if ((p = getenv("HOME")) == NULL) {
12664 if (geteuid() == 0)
12670 strcat(s, "/trace");
12673 strcpy(s, "./trace");
12674 #endif /* not_this_way */
12675 if ((tracefile = fopen(s, "a")) == NULL) {
12676 fprintf(stderr, "Can't open %s\n", s);
12680 if ((flags = fcntl(fileno(tracefile), F_GETFL, 0)) >= 0)
12681 fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND);
12683 fputs("\nTracing started.\n", tracefile);
12690 * The trap builtin.
12694 trapcmd(argc, argv)
12703 for (signo = 0 ; signo < NSIG ; signo++) {
12704 if (trap[signo] != NULL) {
12707 p = single_quote(trap[signo]);
12708 out1fmt("trap -- %s %s\n", p,
12709 signal_names[signo] + (signo ? 3 : 0)
12722 if ((signo = decode_signal(*ap, 0)) < 0)
12723 error("%s: bad trap", *ap);
12726 if (action[0] == '-' && action[1] == '\0')
12729 action = savestr(action);
12732 ckfree(trap[signo]);
12733 trap[signo] = action;
12748 * Set the signal handler for the specified signal. The routine figures
12749 * out what it should be set to.
12753 setsignal(int signo)
12757 struct sigaction act;
12759 if ((t = trap[signo]) == NULL)
12761 else if (*t != '\0')
12765 if (rootshell && action == S_DFL) {
12768 if (iflag || minusc || sflag == 0)
12794 t = &sigmode[signo - 1];
12797 * current setting unknown
12799 if (sigaction(signo, 0, &act) == -1) {
12801 * Pretend it worked; maybe we should give a warning
12802 * here, but other shells don't. We don't alter
12803 * sigmode, so that we retry every time.
12807 if (act.sa_handler == SIG_IGN) {
12808 if (mflag && (signo == SIGTSTP ||
12809 signo == SIGTTIN || signo == SIGTTOU)) {
12810 *t = S_IGN; /* don't hard ignore these */
12814 *t = S_RESET; /* force to be set */
12817 if (*t == S_HARD_IGN || *t == action)
12821 act.sa_handler = onsig;
12824 act.sa_handler = SIG_IGN;
12827 act.sa_handler = SIG_DFL;
12831 sigemptyset(&act.sa_mask);
12832 sigaction(signo, &act, 0);
12843 if (sigmode[signo - 1] != S_IGN && sigmode[signo - 1] != S_HARD_IGN) {
12844 signal(signo, SIG_IGN);
12846 sigmode[signo - 1] = S_HARD_IGN;
12857 if (signo == SIGINT && trap[SIGINT] == NULL) {
12861 gotsig[signo - 1] = 1;
12867 * Called to execute a trap. Perhaps we should avoid entering new trap
12868 * handlers while we are executing a trap handler.
12878 for (i = 1 ; ; i++) {
12885 savestatus=exitstatus;
12886 evalstring(trap[i], 0);
12887 exitstatus=savestatus;
12894 * Called to exit the shell.
12898 exitshell(int status)
12900 struct jmploc loc1, loc2;
12903 TRACE(("exitshell(%d) pid=%d\n", status, getpid()));
12904 if (setjmp(loc1.loc)) {
12907 if (setjmp(loc2.loc)) {
12911 if ((p = trap[0]) != NULL && *p != '\0') {
12915 l1: handler = &loc2; /* probably unnecessary */
12924 static int decode_signal(const char *string, int minsig)
12928 if (is_number(string, &signo)) {
12929 if (signo >= NSIG) {
12939 for (; signo < NSIG; signo++) {
12940 if (!strcasecmp(string, &(signal_names[signo])[3])) {
12944 if (!strcasecmp(string, signal_names[signo])) {
12951 static struct var **hashvar (const char *);
12952 static void showvars (const char *, int, int);
12953 static struct var **findvar (struct var **, const char *);
12956 * Initialize the varable symbol tables and import the environment
12960 * This routine initializes the builtin variables. It is called when the
12961 * shell is initialized and again when a shell procedure is spawned.
12966 const struct varinit *ip;
12970 for (ip = varinit ; (vp = ip->var) != NULL ; ip++) {
12971 if ((vp->flags & VEXPORT) == 0) {
12972 vpp = hashvar(ip->text);
12975 vp->text = strdup(ip->text);
12976 vp->flags = ip->flags;
12977 vp->func = ip->func;
12981 * PS1 depends on uid
12983 if ((vps1.flags & VEXPORT) == 0) {
12984 vpp = hashvar("PS1=");
12987 vps1.text = strdup(geteuid() ? "PS1=$ " : "PS1=# ");
12988 vps1.flags = VSTRFIXED|VTEXTFIXED;
12993 * Set the value of a variable. The flags argument is ored with the
12994 * flags of the variable. If val is NULL, the variable is unset.
12998 setvar(name, val, flags)
12999 const char *name, *val;
13015 if (! is_in_name(*p)) {
13016 if (*p == '\0' || *p == '=')
13022 namelen = p - name;
13024 error("%.*s: bad variable name", namelen, name);
13025 len = namelen + 2; /* 2 is space for '=' and '\0' */
13029 len += vallen = strlen(val);
13032 nameeq = ckmalloc(len);
13033 memcpy(nameeq, name, namelen);
13034 nameeq[namelen] = '=';
13036 memcpy(nameeq + namelen + 1, val, vallen + 1);
13038 nameeq[namelen + 1] = '\0';
13040 setvareq(nameeq, flags);
13047 * Same as setvar except that the variable and value are passed in
13048 * the first argument as name=value. Since the first argument will
13049 * be actually stored in the table, it should not be a string that
13058 struct var *vp, **vpp;
13061 flags |= (VEXPORT & (((unsigned) (1 - aflag)) - 1));
13062 if ((vp = *findvar(vpp, s))) {
13063 if (vp->flags & VREADONLY) {
13064 size_t len = strchr(s, '=') - s;
13065 error("%.*s: is read only", len, s);
13069 if (vp->func && (flags & VNOFUNC) == 0)
13070 (*vp->func)(strchr(s, '=') + 1);
13072 if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0)
13075 vp->flags &= ~(VTEXTFIXED|VSTACK|VUNSET);
13076 vp->flags |= flags;
13080 * We could roll this to a function, to handle it as
13081 * a regular variable function callback, but why bother?
13083 if (iflag && (vp == &vmpath || (vp == &vmail && !mpathset())))
13089 vp = ckmalloc(sizeof (*vp));
13100 * Process a linked list of variable assignments.
13105 struct strlist *mylist;
13107 struct strlist *lp;
13110 for (lp = mylist ; lp ; lp = lp->next) {
13111 setvareq(savestr(lp->text), 0);
13119 * Find the value of a variable. Returns NULL if not set.
13128 if ((v = *findvar(hashvar(name), name)) && !(v->flags & VUNSET)) {
13129 return strchr(v->text, '=') + 1;
13137 * Search the environment of a builtin command.
13144 struct strlist *sp;
13146 for (sp = cmdenviron ; sp ; sp = sp->next) {
13147 if (varequal(sp->text, name))
13148 return strchr(sp->text, '=') + 1;
13150 return lookupvar(name);
13156 * Generate a list of exported variables. This routine is used to construct
13157 * the third argument to execve when executing a program.
13169 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
13170 for (vp = *vpp ; vp ; vp = vp->next)
13171 if (vp->flags & VEXPORT)
13174 ep = env = stalloc((nenv + 1) * sizeof *env);
13175 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
13176 for (vp = *vpp ; vp ; vp = vp->next)
13177 if (vp->flags & VEXPORT)
13186 * Called when a shell procedure is invoked to clear out nonexported
13187 * variables. It is also necessary to reallocate variables of with
13188 * VSTACK set since these are currently allocated on the stack.
13194 struct var *vp, **prev;
13196 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
13197 for (prev = vpp ; (vp = *prev) != NULL ; ) {
13198 if ((vp->flags & VEXPORT) == 0) {
13200 if ((vp->flags & VTEXTFIXED) == 0)
13202 if ((vp->flags & VSTRFIXED) == 0)
13205 if (vp->flags & VSTACK) {
13206 vp->text = savestr(vp->text);
13207 vp->flags &=~ VSTACK;
13219 * Command to list all variables which are set. Currently this command
13220 * is invoked from the set command when the set command is called without
13225 showvarscmd(argc, argv)
13229 showvars(nullstr, VUNSET, VUNSET);
13236 * The export and readonly commands.
13240 exportcmd(argc, argv)
13247 int flag = argv[0][0] == 'r'? VREADONLY : VEXPORT;
13250 listsetvar(cmdenviron);
13251 pflag = (nextopt("p") == 'p');
13252 if (argc > 1 && !pflag) {
13253 while ((name = *argptr++) != NULL) {
13254 if ((p = strchr(name, '=')) != NULL) {
13257 if ((vp = *findvar(hashvar(name), name))) {
13262 setvar(name, p, flag);
13266 showvars(argv[0], flag, 0);
13273 * The "local" command.
13276 /* funcnest nonzero if we are currently evaluating a function */
13279 localcmd(argc, argv)
13286 error("Not in a function");
13287 while ((name = *argptr++) != NULL) {
13295 * Make a variable a local variable. When a variable is made local, it's
13296 * value and flags are saved in a localvar structure. The saved values
13297 * will be restored when the shell function returns. We handle the name
13298 * "-" as a special case.
13305 struct localvar *lvp;
13310 lvp = ckmalloc(sizeof (struct localvar));
13311 if (name[0] == '-' && name[1] == '\0') {
13313 p = ckmalloc(sizeof optet_vals);
13314 lvp->text = memcpy(p, optet_vals, sizeof optet_vals);
13317 vpp = hashvar(name);
13318 vp = *findvar(vpp, name);
13320 if (strchr(name, '='))
13321 setvareq(savestr(name), VSTRFIXED);
13323 setvar(name, NULL, VSTRFIXED);
13324 vp = *vpp; /* the new variable */
13326 lvp->flags = VUNSET;
13328 lvp->text = vp->text;
13329 lvp->flags = vp->flags;
13330 vp->flags |= VSTRFIXED|VTEXTFIXED;
13331 if (strchr(name, '='))
13332 setvareq(savestr(name), 0);
13336 lvp->next = localvars;
13343 * Called after a function returns.
13348 struct localvar *lvp;
13351 while ((lvp = localvars) != NULL) {
13352 localvars = lvp->next;
13354 if (vp == NULL) { /* $- saved */
13355 memcpy(optet_vals, lvp->text, sizeof optet_vals);
13357 } else if ((lvp->flags & (VUNSET|VSTRFIXED)) == VUNSET) {
13358 (void)unsetvar(vp->text);
13360 if ((vp->flags & VTEXTFIXED) == 0)
13362 vp->flags = lvp->flags;
13363 vp->text = lvp->text;
13371 setvarcmd(argc, argv)
13376 return unsetcmd(argc, argv);
13377 else if (argc == 3)
13378 setvar(argv[1], argv[2], 0);
13380 error("List assignment not implemented");
13386 * The unset builtin command. We unset the function before we unset the
13387 * variable to allow a function to be unset when there is a readonly variable
13388 * with the same name.
13392 unsetcmd(argc, argv)
13402 while ((i = nextopt("vf")) != '\0') {
13408 if (flg_func == 0 && flg_var == 0)
13411 for (ap = argptr; *ap ; ap++) {
13415 ret |= unsetvar(*ap);
13422 * Unset the specified variable.
13432 vpp = findvar(hashvar(s), s);
13435 if (vp->flags & VREADONLY)
13438 if (*(strchr(vp->text, '=') + 1) != '\0')
13439 setvar(s, nullstr, 0);
13440 vp->flags &= ~VEXPORT;
13441 vp->flags |= VUNSET;
13442 if ((vp->flags & VSTRFIXED) == 0) {
13443 if ((vp->flags & VTEXTFIXED) == 0)
13458 * Find the appropriate entry in the hash table from the name.
13461 static struct var **
13465 unsigned int hashval;
13467 hashval = ((unsigned char) *p) << 4;
13468 while (*p && *p != '=')
13469 hashval += (unsigned char) *p++;
13470 return &vartab[hashval % VTABSIZE];
13476 * Returns true if the two strings specify the same varable. The first
13477 * variable name is terminated by '='; the second may be terminated by
13478 * either '=' or '\0'.
13485 while (*p == *q++) {
13489 if (*p == '=' && *(q - 1) == '\0')
13495 showvars(const char *myprefix, int mask, int xor)
13499 const char *sep = myprefix == nullstr ? myprefix : spcstr;
13501 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
13502 for (vp = *vpp ; vp ; vp = vp->next) {
13503 if ((vp->flags & mask) ^ xor) {
13507 p = strchr(vp->text, '=') + 1;
13508 len = p - vp->text;
13509 p = single_quote(p);
13512 "%s%s%.*s%s\n", myprefix, sep, len,
13521 static struct var **
13522 findvar(struct var **vpp, const char *name)
13524 for (; *vpp; vpp = &(*vpp)->next) {
13525 if (varequal((*vpp)->text, name)) {
13533 * Copyright (c) 1999 Herbert Xu <herbert@debian.org>
13534 * This file contains code for the times builtin.
13535 * $Id: ash.c,v 1.4 2001/07/02 17:27:21 andersen Exp $
13537 static int timescmd (int argc, char **argv)
13540 long int clk_tck = sysconf(_SC_CLK_TCK);
13543 printf("%dm%fs %dm%fs\n%dm%fs %dm%fs\n",
13544 (int) (buf.tms_utime / clk_tck / 60),
13545 ((double) buf.tms_utime) / clk_tck,
13546 (int) (buf.tms_stime / clk_tck / 60),
13547 ((double) buf.tms_stime) / clk_tck,
13548 (int) (buf.tms_cutime / clk_tck / 60),
13549 ((double) buf.tms_cutime) / clk_tck,
13550 (int) (buf.tms_cstime / clk_tck / 60),
13551 ((double) buf.tms_cstime) / clk_tck);
13557 * Copyright (c) 1989, 1991, 1993, 1994
13558 * The Regents of the University of California. All rights reserved.
13560 * This code is derived from software contributed to Berkeley by
13561 * Kenneth Almquist.
13563 * Redistribution and use in source and binary forms, with or without
13564 * modification, are permitted provided that the following conditions
13566 * 1. Redistributions of source code must retain the above copyright
13567 * notice, this list of conditions and the following disclaimer.
13568 * 2. Redistributions in binary form must reproduce the above copyright
13569 * notice, this list of conditions and the following disclaimer in the
13570 * documentation and/or other materials provided with the distribution.
13572 * 3. <BSD Advertising Clause omitted per the July 22, 1999 licensing change
13573 * ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change>
13575 * 4. Neither the name of the University nor the names of its contributors
13576 * may be used to endorse or promote products derived from this software
13577 * without specific prior written permission.
13579 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
13580 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
13581 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
13582 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
13583 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
13584 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
13585 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
13586 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
13587 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
13588 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF