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 static int bltincmd (int, char **);
1642 static int cdcmd (int, char **);
1643 static int breakcmd (int, char **);
1645 static int commandcmd (int, char **);
1647 static int dotcmd (int, char **);
1648 static int evalcmd (int, char **);
1649 static int execcmd (int, char **);
1650 static int exitcmd (int, char **);
1651 static int exportcmd (int, char **);
1652 static int histcmd (int, char **);
1653 static int hashcmd (int, char **);
1654 static int jobscmd (int, char **);
1655 static int localcmd (int, char **);
1657 static int pwdcmd (int, char **);
1659 static int readcmd (int, char **);
1660 static int returncmd (int, char **);
1661 static int setcmd (int, char **);
1662 static int setvarcmd (int, char **);
1663 static int shiftcmd (int, char **);
1664 static int trapcmd (int, char **);
1665 static int umaskcmd (int, char **);
1667 static int aliascmd (int, char **);
1668 static int unaliascmd (int, char **);
1670 static int unsetcmd (int, char **);
1671 static int waitcmd (int, char **);
1672 static int ulimitcmd (int, char **);
1673 static int timescmd (int, char **);
1674 #ifdef ASH_MATH_SUPPORT
1675 static int expcmd (int, char **);
1678 static int typecmd (int, char **);
1681 static int getoptscmd (int, char **);
1684 #ifndef BB_TRUE_FALSE
1685 # ifdef ASH_BBAPPS_AS_BUILTINS
1686 static int true_main (int, char **);
1687 static int false_main (int, char **);
1691 static void setpwd (const char *, int);
1694 #define BUILTIN_NOSPEC "0"
1695 #define BUILTIN_SPECIAL "1"
1696 #define BUILTIN_REGULAR "2"
1697 #define BUILTIN_ASSIGN "4"
1698 #define BUILTIN_SPEC_ASSG "5"
1699 #define BUILTIN_REG_ASSG "6"
1701 #define IS_BUILTIN_SPECIAL(builtincmd) ((builtincmd)->name[0] & 1)
1702 #define IS_BUILTIN_REGULAR(builtincmd) ((builtincmd)->name[0] & 2)
1703 #define IS_BUILTIN_ASSIGN(builtincmd) ((builtincmd)->name[0] & 4)
1707 int (*const builtinfunc) (int, char **);
1712 /* It is CRUCIAL that this listing be kept in ascii order, otherwise
1713 * the binary search in find_builtin() will stop working. If you value
1714 * your kneecaps, you'll be sure to *make sure* that any changes made
1715 * to this array result in the listing remaining in ascii order. You
1718 static const struct builtincmd builtincmds[] = {
1719 { BUILTIN_SPECIAL ".", dotcmd },
1720 { BUILTIN_SPECIAL ":", true_main },
1722 { BUILTIN_REG_ASSG "alias", aliascmd },
1725 { BUILTIN_REGULAR "bg", bgcmd },
1727 { BUILTIN_SPECIAL "break", breakcmd },
1728 { BUILTIN_SPECIAL "builtin", bltincmd }, /* Do not disable this builtin ever or bad things happen */
1729 { BUILTIN_REGULAR "cd", cdcmd },
1730 #ifdef ASH_BBAPPS_AS_BUILTINS
1731 { BUILTIN_NOSPEC "chdir", cdcmd },
1734 { BUILTIN_REGULAR "command", commandcmd },
1736 { BUILTIN_SPECIAL "continue", breakcmd },
1737 { BUILTIN_SPECIAL "eval", evalcmd },
1738 { BUILTIN_SPECIAL "exec", execcmd },
1739 { BUILTIN_SPECIAL "exit", exitcmd },
1740 #ifdef ASH_MATH_SUPPORT
1741 { BUILTIN_NOSPEC "exp", expcmd },
1743 { BUILTIN_SPEC_ASSG "export", exportcmd },
1744 #ifdef ASH_BBAPPS_AS_BUILTINS
1745 { BUILTIN_REGULAR "false", false_main },
1747 { BUILTIN_REGULAR "fc", histcmd },
1749 { BUILTIN_REGULAR "fg", fgcmd },
1752 { BUILTIN_REGULAR "getopts", getoptscmd },
1754 { BUILTIN_NOSPEC "hash", hashcmd },
1755 { BUILTIN_REGULAR "jobs", jobscmd },
1757 { BUILTIN_REGULAR "kill", killcmd },
1759 #ifdef ASH_MATH_SUPPORT
1760 { BUILTIN_NOSPEC "let", expcmd },
1762 { BUILTIN_ASSIGN "local", localcmd },
1764 { BUILTIN_NOSPEC "pwd", pwdcmd },
1766 { BUILTIN_REGULAR "read", readcmd },
1767 { BUILTIN_SPEC_ASSG "readonly", exportcmd },
1768 { BUILTIN_SPECIAL "return", returncmd },
1769 { BUILTIN_SPECIAL "set", setcmd },
1770 { BUILTIN_NOSPEC "setvar", setvarcmd },
1771 { BUILTIN_SPECIAL "shift", shiftcmd },
1772 { BUILTIN_SPECIAL "times", timescmd },
1773 { BUILTIN_SPECIAL "trap", trapcmd },
1774 #ifdef ASH_BBAPPS_AS_BUILTINS
1775 { BUILTIN_REGULAR "true", true_main },
1778 { BUILTIN_NOSPEC "type", typecmd },
1780 { BUILTIN_NOSPEC "ulimit", ulimitcmd },
1781 { BUILTIN_REGULAR "umask", umaskcmd },
1783 { BUILTIN_REGULAR "unalias", unaliascmd },
1785 { BUILTIN_SPECIAL "unset", unsetcmd },
1786 { BUILTIN_REGULAR "wait", waitcmd },
1788 #define NUMBUILTINS (sizeof (builtincmds) / sizeof (struct builtincmd) )
1790 static const struct builtincmd *DOTCMD = &builtincmds[0];
1791 static struct builtincmd *BLTINCMD;
1792 static struct builtincmd *EXECCMD;
1793 static struct builtincmd *EVALCMD;
1796 #define JOBSTOPPED 1 /* all procs are stopped */
1797 #define JOBDONE 2 /* all procs are completed */
1800 * A job structure contains information about a job. A job is either a
1801 * single process or a set of processes contained in a pipeline. In the
1802 * latter case, pidlist will be non-NULL, and will point to a -1 terminated
1807 pid_t pid; /* process id */
1808 int status; /* status flags (defined above) */
1809 char *cmd; /* text of command being run */
1813 static int job_warning; /* user was warned about stopped jobs */
1816 static void setjobctl(int enable);
1818 #define setjobctl(on) /* do nothing */
1823 struct procstat ps0; /* status of process */
1824 struct procstat *ps; /* status or processes when more than one */
1825 short nprocs; /* number of processes */
1826 short pgrp; /* process group of this job */
1827 char state; /* true if job is finished */
1828 char used; /* true if this entry is in used */
1829 char changed; /* true if status has changed */
1831 char jobctl; /* job running under job control */
1835 static struct job *jobtab; /* array of jobs */
1836 static int njobs; /* size of array */
1837 static int backgndpid = -1; /* pid of last background process */
1839 static int initialpgrp; /* pgrp of shell on invocation */
1840 static int curjob; /* current job */
1843 static int intreceived;
1845 static struct job *makejob (union node *, int);
1846 static int forkshell (struct job *, union node *, int);
1847 static int waitforjob (struct job *);
1849 static int docd (char *, int);
1850 static char *getcomponent (void);
1851 static void updatepwd (const char *);
1852 static void getpwd (void);
1854 static char *padvance (const char **, const char *);
1856 static char nullstr[1]; /* zero length string */
1857 static char *curdir = nullstr; /* current working directory */
1858 static char *cdcomppath;
1872 if ((dest = *argptr) == NULL && (dest = bltinlookup("HOME")) == NULL)
1873 error("HOME not set");
1876 if (dest[0] == '-' && dest[1] == '\0') {
1877 dest = bltinlookup("OLDPWD");
1878 if (!dest || !*dest) {
1887 if (*dest == '/' || (path = bltinlookup("CDPATH")) == NULL)
1889 while ((p = padvance(&path, dest)) != NULL) {
1890 if (stat(p, &statb) >= 0 && S_ISDIR(statb.st_mode)) {
1895 if (p[0] == '.' && p[1] == '/' && p[2] != '\0')
1897 print = strcmp(p, dest);
1899 if (docd(p, print) >= 0)
1904 error("can't cd to %s", dest);
1910 * Actually do the chdir. In an interactive shell, print the
1911 * directory name if "print" is nonzero.
1926 TRACE(("docd(\"%s\", %d) called\n", dest, print));
1929 * Check each component of the path. If we find a symlink or
1930 * something we can't stat, clear curdir to force a getcwd()
1931 * next time we get the value of the current directory.
1934 cdcomppath = sstrdup(dest);
1941 while ((q = getcomponent()) != NULL) {
1942 if (q[0] == '\0' || (q[0] == '.' && q[1] == '\0'))
1950 if (equal(component, ".."))
1953 if ((lstat(stackblock(), &statb) < 0)
1954 || (S_ISLNK(statb.st_mode))) {
1962 if (chdir(dest) < 0) {
1966 updatepwd(badstat ? NULL : dest);
1969 out1fmt(snlfmt, curdir);
1975 * Get the next component of the path name pointed to by cdcomppath.
1976 * This routine overwrites the string pointed to by cdcomppath.
1984 if ((p = cdcomppath) == NULL)
1987 while (*p != '/' && *p != '\0')
2001 * Update curdir (the name of the current directory) in response to a
2002 * cd command. We also call hashcd to let the routines in exec.c know
2003 * that the current directory has changed.
2006 static void hashcd (void);
2009 updatepwd(const char *dir)
2015 hashcd(); /* update command hash table */
2018 * If our argument is NULL, we don't know the current directory
2019 * any more because we traversed a symbolic link or something
2020 * we couldn't stat().
2022 if (dir == NULL || curdir == nullstr) {
2027 cdcomppath = sstrdup(dir);
2036 while ((p = getcomponent()) != NULL) {
2037 if (equal(p, "..")) {
2038 while (new > stackblock() && (STUNPUTC(new), *new) != '/');
2039 } else if (*p != '\0' && ! equal(p, ".")) {
2045 if (new == stackblock())
2048 setpwd(stackblock(), 1);
2058 out1fmt(snlfmt, curdir);
2064 * Find out what the current directory is. If we already know the current
2065 * directory, this routine returns immediately.
2070 curdir = xgetcwd(0);
2076 setpwd(const char *val, int setold)
2079 setvar("OLDPWD", curdir, VEXPORT);
2082 if (curdir != nullstr) {
2089 curdir = savestr(val);
2092 setvar("PWD", curdir, VEXPORT);
2096 * Errors and exceptions.
2100 * Code to handle exceptions in C.
2104 * We enclose jmp_buf in a structure so that we can declare pointers to
2105 * jump locations. The global variable handler contains the location to
2106 * jump to when an exception occurs, and the global variable exception
2107 * contains a code identifying the exeception. To implement nested
2108 * exception handlers, the user should save the value of handler on entry
2109 * to an inner scope, set handler to point to a jmploc structure for the
2110 * inner scope, and restore handler on exit from the scope.
2118 #define EXINT 0 /* SIGINT received */
2119 #define EXERROR 1 /* a generic error */
2120 #define EXSHELLPROC 2 /* execute a shell procedure */
2121 #define EXEXEC 3 /* command execution failed */
2123 static struct jmploc *handler;
2124 static int exception;
2126 static void exverror (int, const char *, va_list)
2127 __attribute__((__noreturn__));
2130 * Called to raise an exception. Since C doesn't include exceptions, we
2131 * just do a longjmp to the exception handler. The type of exception is
2132 * stored in the global variable "exception".
2135 static void exraise (int) __attribute__((__noreturn__));
2141 if (handler == NULL)
2145 longjmp(handler->loc, 1);
2150 * Called from trap.c when a SIGINT is received. (If the user specifies
2151 * that SIGINT is to be trapped or ignored using the trap builtin, then
2152 * this routine is not called.) Suppressint is nonzero when interrupts
2153 * are held using the INTOFF macro. The call to _exit is necessary because
2154 * there is a short period after a fork before the signal handlers are
2155 * set to the appropriate value for the child. (The test for iflag is
2156 * just defensive programming.)
2168 sigemptyset(&mysigset);
2169 sigprocmask(SIG_SETMASK, &mysigset, NULL);
2170 if (rootshell && iflag)
2173 signal(SIGINT, SIG_DFL);
2180 static char *commandname; /* currently executing command */
2183 * Exverror is called to raise the error exception. If the first argument
2184 * is not NULL then error prints an error message using printf style
2185 * formatting. It then raises the error exception.
2188 exverror(int cond, const char *msg, va_list ap)
2195 TRACE(("exverror(%d, \"%s\") pid=%d\n", cond, msg, getpid()));
2197 TRACE(("exverror(%d, NULL) pid=%d\n", cond, getpid()));
2201 outfmt(&errout, "%s: ", commandname);
2202 doformat(&errout, msg, ap);
2204 outc('\n', &errout);
2206 outcslow('\n', &errout);
2217 error(const char *msg, ...)
2232 msg = va_arg(ap, const char *);
2234 exverror(EXERROR, msg, ap);
2242 exerror(int cond, const char *msg, ...)
2258 cond = va_arg(ap, int);
2259 msg = va_arg(ap, const char *);
2261 exverror(cond, msg, ap);
2269 * Table of error messages.
2273 short errcode; /* error number */
2274 short action; /* operation which encountered the error */
2278 * Types of operations (passed to the errmsg routine).
2281 #define E_OPEN 01 /* opening a file */
2282 #define E_CREAT 02 /* creating a file */
2283 #define E_EXEC 04 /* executing a program */
2285 #define ALL (E_OPEN|E_CREAT|E_EXEC)
2287 static const struct errname errormsg[] = {
2292 { ENOENT, E_CREAT },
2294 { ENOTDIR, E_OPEN },
2295 { ENOTDIR, E_CREAT },
2296 { ENOTDIR, E_EXEC },
2298 { EEXIST, E_CREAT },
2337 { ELIBACC, E_EXEC },
2341 #define ERRNAME_SIZE (sizeof(errormsg)/sizeof(struct errname))
2344 * Return a string describing an error. The returned string may be a
2345 * pointer to a static buffer that will be overwritten on the next call.
2346 * Action describes the operation that got the error.
2350 errmsg(int e, int action)
2352 struct errname const *ep;
2353 static char buf[12];
2355 for (ep = errormsg ; ep < errormsg+ERRNAME_SIZE; ep++) {
2356 if (ep->errcode == e && (ep->action & action) != 0)
2360 fmtstr(buf, sizeof buf, "error %d", e);
2365 #ifndef ASH_BBAPPS_AS_BUILTINS
2368 if (--suppressint == 0 && intpending) {
2374 /* flags in argument to evaltree */
2375 #define EV_EXIT 01 /* exit after evaluating tree */
2376 #define EV_TESTED 02 /* exit status is checked; ignore -e flag */
2377 #define EV_BACKCMD 04 /* command executing within back quotes */
2379 static int evalskip; /* set if we are skipping commands */
2380 static int skipcount; /* number of levels to skip */
2381 static int loopnest; /* current loop nesting level */
2382 static int funcnest; /* depth of function calls */
2386 static struct strlist *cmdenviron; /* environment for builtin command */
2387 static int exitstatus; /* exit status of last command */
2388 static int oexitstatus; /* saved exit status */
2391 static void evalloop (union node *, int);
2392 static void evalfor (union node *, int);
2393 static void evalcase (union node *, int);
2394 static void evalsubshell (union node *, int);
2395 static void expredir (union node *);
2396 static void evalpipe (union node *);
2398 static void evalcommand (union node *, int, struct backcmd *);
2400 static void evalcommand (union node *, int);
2402 static void prehash (union node *);
2403 static void eprintlist (struct strlist *);
2405 static union node *parsecmd(int);
2407 * Called to reset things after an exception.
2411 * The eval commmand.
2413 static void evalstring (char *, int);
2427 STARTSTACKSTR(concat);
2431 STPUTC(*p++, concat);
2432 if ((p = *ap++) == NULL)
2434 STPUTC(' ', concat);
2436 STPUTC('\0', concat);
2437 p = grabstackstr(concat);
2439 evalstring(p, EV_TESTED);
2445 * Execute a command or commands contained in a string.
2448 static void evaltree (union node *, int);
2449 static void setinputstring (char *);
2450 static void popfile (void);
2451 static void setstackmark(struct stackmark *mark);
2452 static void popstackmark(struct stackmark *mark);
2456 evalstring(char *s, int flag)
2459 struct stackmark smark;
2461 setstackmark(&smark);
2463 while ((n = parsecmd(0)) != NEOF) {
2465 popstackmark(&smark);
2468 popstackmark(&smark);
2472 * Evaluate a parse tree. The value is left in the global variable
2475 static struct builtincmd *find_builtin (const char *);
2476 static void defun (char *, union node *);
2485 TRACE(("evaltree(NULL) called\n"));
2488 TRACE(("evaltree(0x%lx: %d) called\n", (long)n, n->type));
2491 evaltree(n->nbinary.ch1, flags & EV_TESTED);
2494 evaltree(n->nbinary.ch2, flags);
2497 evaltree(n->nbinary.ch1, EV_TESTED);
2498 if (evalskip || exitstatus != 0)
2500 evaltree(n->nbinary.ch2, flags);
2503 evaltree(n->nbinary.ch1, EV_TESTED);
2504 if (evalskip || exitstatus == 0)
2506 evaltree(n->nbinary.ch2, flags);
2509 expredir(n->nredir.redirect);
2510 redirect(n->nredir.redirect, REDIR_PUSH);
2511 evaltree(n->nredir.n, flags);
2515 evalsubshell(n, flags);
2518 evalsubshell(n, flags);
2521 evaltree(n->nif.test, EV_TESTED);
2524 if (exitstatus == 0)
2525 evaltree(n->nif.ifpart, flags);
2526 else if (n->nif.elsepart)
2527 evaltree(n->nif.elsepart, flags);
2543 struct builtincmd *bcmd;
2545 (bcmd = find_builtin(n->narg.text)) &&
2546 IS_BUILTIN_SPECIAL(bcmd)
2548 outfmt(out2, "%s is a special built-in\n", n->narg.text);
2552 defun(n->narg.text, n->narg.next);
2557 evaltree(n->nnot.com, EV_TESTED);
2558 exitstatus = !exitstatus;
2567 evalcommand(n, flags, (struct backcmd *)NULL);
2569 evalcommand(n, flags);
2575 out1fmt("Node type = %d\n", n->type);
2576 #ifndef USE_GLIBC_STDIO
2587 (checkexit && eflag && exitstatus && !(flags & EV_TESTED))
2589 exitshell(exitstatus);
2603 evaltree(n->nbinary.ch1, EV_TESTED);
2605 skipping: if (evalskip == SKIPCONT && --skipcount <= 0) {
2609 if (evalskip == SKIPBREAK && --skipcount <= 0)
2613 if (n->type == NWHILE) {
2614 if (exitstatus != 0)
2617 if (exitstatus == 0)
2620 evaltree(n->nbinary.ch2, flags & EV_TESTED);
2621 status = exitstatus;
2626 exitstatus = status;
2629 static void expandarg (union node *, struct arglist *, int);
2630 static void fixredir(union node *n, const char *text, int err);
2637 struct arglist arglist;
2640 struct stackmark smark;
2642 setstackmark(&smark);
2643 arglist.lastp = &arglist.list;
2644 for (argp = n->nfor.args ; argp ; argp = argp->narg.next) {
2645 oexitstatus = exitstatus;
2646 expandarg(argp, &arglist, EXP_FULL | EXP_TILDE | EXP_RECORD);
2650 *arglist.lastp = NULL;
2654 for (sp = arglist.list ; sp ; sp = sp->next) {
2655 setvar(n->nfor.var, sp->text, 0);
2656 evaltree(n->nfor.body, flags & EV_TESTED);
2658 if (evalskip == SKIPCONT && --skipcount <= 0) {
2662 if (evalskip == SKIPBREAK && --skipcount <= 0)
2669 popstackmark(&smark);
2680 struct arglist arglist;
2681 struct stackmark smark;
2683 setstackmark(&smark);
2684 arglist.lastp = &arglist.list;
2685 oexitstatus = exitstatus;
2686 expandarg(n->ncase.expr, &arglist, EXP_TILDE);
2687 for (cp = n->ncase.cases ; cp && evalskip == 0 ; cp = cp->nclist.next) {
2688 for (patp = cp->nclist.pattern ; patp ; patp = patp->narg.next) {
2689 if (casematch(patp, arglist.list->text)) {
2690 if (evalskip == 0) {
2691 evaltree(cp->nclist.body, flags);
2698 popstackmark(&smark);
2702 * Kick off a subshell to evaluate a tree.
2706 evalsubshell(n, flags)
2711 int backgnd = (n->type == NBACKGND);
2713 expredir(n->nredir.redirect);
2715 if (forkshell(jp, n, backgnd) == 0) {
2717 flags &=~ EV_TESTED;
2718 redirect(n->nredir.redirect, 0);
2719 evaltree(n->nredir.n, flags | EV_EXIT); /* never returns */
2723 exitstatus = waitforjob(jp);
2731 * Compute the names of the files in a redirection list.
2740 for (redir = n ; redir ; redir = redir->nfile.next) {
2742 fn.lastp = &fn.list;
2743 oexitstatus = exitstatus;
2744 switch (redir->type) {
2750 expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR);
2751 redir->nfile.expfname = fn.list->text;
2755 if (redir->ndup.vname) {
2756 expandarg(redir->ndup.vname, &fn, EXP_FULL | EXP_TILDE);
2757 fixredir(redir, fn.list->text, 1);
2765 * Evaluate a pipeline. All the processes in the pipeline are children
2766 * of the process creating the pipeline. (This differs from some versions
2767 * of the shell, which make the last process in a pipeline the parent
2776 struct nodelist *lp;
2781 TRACE(("evalpipe(0x%lx) called\n", (long)n));
2783 for (lp = n->npipe.cmdlist ; lp ; lp = lp->next)
2786 jp = makejob(n, pipelen);
2788 for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
2792 if (pipe(pip) < 0) {
2794 error("Pipe call failed");
2797 if (forkshell(jp, lp->n, n->npipe.backgnd) == 0) {
2801 dup_as_newfd(prevfd, 0);
2813 dup_as_newfd(pip[1], 1);
2817 evaltree(lp->n, EV_EXIT);
2825 if (n->npipe.backgnd == 0) {
2827 exitstatus = waitforjob(jp);
2828 TRACE(("evalpipe: job done exit status %d\n", exitstatus));
2836 * Execute a command inside back quotes. If it's a builtin command, we
2837 * want to save its output in a block obtained from malloc. Otherwise
2838 * we fork off a subprocess and get the output of the command via a pipe.
2839 * Should be called with interrupts off.
2843 evalbackcmd(union node *n, struct backcmd *result)
2847 struct stackmark smark; /* unnecessary */
2849 setstackmark(&smark);
2860 * For now we disable executing builtins in the same
2861 * context as the shell, because we are not keeping
2862 * enough state to recover from changes that are
2863 * supposed only to affect subshells. eg. echo "`cd /`"
2865 if (n->type == NCMD) {
2866 exitstatus = oexitstatus;
2867 evalcommand(n, EV_BACKCMD, result);
2873 error("Pipe call failed");
2875 if (forkshell(jp, n, FORK_NOJOB) == 0) {
2880 dup_as_newfd(pip[1], 1);
2884 evaltree(n, EV_EXIT);
2887 result->fd = pip[0];
2891 popstackmark(&smark);
2892 TRACE(("evalbackcmd done: fd=%d buf=0x%x nleft=%d jp=0x%x\n",
2893 result->fd, result->buf, result->nleft, result->jp));
2899 * Execute a simple command.
2902 static void find_command (const char *, struct cmdentry *, int, const char *);
2905 isassignment(const char *word) {
2906 if (!is_name(*word)) {
2911 } while (is_in_name(*word));
2912 return *word == '=';
2917 evalcommand(cmd, flags, backcmd)
2920 struct backcmd *backcmd;
2922 evalcommand(cmd, flags)
2927 struct stackmark smark;
2929 struct arglist arglist;
2930 struct arglist varlist;
2939 struct cmdentry cmdentry;
2941 char *volatile savecmdname;
2942 volatile struct shparam saveparam;
2943 struct localvar *volatile savelocalvars;
2947 const struct builtincmd *firstbltin;
2948 struct jmploc *volatile savehandler;
2949 struct jmploc jmploc;
2951 /* Avoid longjmp clobbering */
2958 /* First expand the arguments. */
2959 TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags));
2960 setstackmark(&smark);
2961 arglist.lastp = &arglist.list;
2962 varlist.lastp = &varlist.list;
2964 oexitstatus = exitstatus;
2967 for (argp = cmd->ncmd.assign; argp; argp = argp->narg.next) {
2968 expandarg(argp, &varlist, EXP_VARTILDE);
2971 argp = cmd->ncmd.args; argp && !arglist.list;
2972 argp = argp->narg.next
2974 expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
2977 struct builtincmd *bcmd;
2979 bcmd = find_builtin(arglist.list->text);
2980 pseudovarflag = bcmd && IS_BUILTIN_ASSIGN(bcmd);
2981 for (; argp; argp = argp->narg.next) {
2982 if (pseudovarflag && isassignment(argp->narg.text)) {
2983 expandarg(argp, &arglist, EXP_VARTILDE);
2986 expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
2989 *arglist.lastp = NULL;
2990 *varlist.lastp = NULL;
2991 expredir(cmd->ncmd.redirect);
2993 for (sp = arglist.list ; sp ; sp = sp->next)
2995 argv = stalloc(sizeof (char *) * (argc + 1));
2997 for (sp = arglist.list ; sp ; sp = sp->next) {
2998 TRACE(("evalcommand arg: %s\n", sp->text));
3003 if (iflag && funcnest == 0 && argc > 0)
3007 /* Print the command if xflag is set. */
3012 outcslow('+', &errout);
3014 eprintlist(varlist.list);
3015 eprintlist(arglist.list);
3017 outc('\n', &errout);
3020 outcslow('\n', &errout);
3024 /* Now locate the command. */
3026 cmdentry.cmdtype = CMDBUILTIN;
3027 firstbltin = cmdentry.u.cmd = BLTINCMD;
3029 const char *oldpath;
3030 int findflag = DO_ERR;
3034 * Modify the command lookup path, if a PATH= assignment
3037 for (sp = varlist.list ; sp ; sp = sp->next)
3038 if (varequal(sp->text, defpathvar)) {
3039 path = sp->text + 5;
3040 findflag |= DO_BRUTE;
3043 oldfindflag = findflag;
3046 find_command(argv[0], &cmdentry, findflag, path);
3047 if (cmdentry.cmdtype == CMDUNKNOWN) { /* command not found */
3054 /* implement bltin and command here */
3055 if (cmdentry.cmdtype != CMDBUILTIN) {
3059 firstbltin = cmdentry.u.cmd;
3061 if (cmdentry.u.cmd == BLTINCMD) {
3063 struct builtincmd *bcmd;
3068 if (!(bcmd = find_builtin(*argv))) {
3069 outfmt(&errout, "%s: not found\n", *argv);
3076 cmdentry.u.cmd = bcmd;
3077 if (bcmd != BLTINCMD)
3081 if (cmdentry.u.cmd == find_builtin("command")) {
3086 if (*argv[0] == '-') {
3087 if (!equal(argv[0], "-p")) {
3097 findflag |= DO_BRUTE;
3100 findflag = oldfindflag;
3102 findflag |= DO_NOFUN;
3110 /* Fork off a child process if necessary. */
3111 if (cmd->ncmd.backgnd
3112 || (cmdentry.cmdtype == CMDNORMAL && (flags & EV_EXIT) == 0)
3114 || ((flags & EV_BACKCMD) != 0
3115 && (cmdentry.cmdtype != CMDBUILTIN
3116 || cmdentry.u.bcmd == DOTCMD
3117 || cmdentry.u.bcmd == EVALCMD))
3120 jp = makejob(cmd, 1);
3121 mode = cmd->ncmd.backgnd;
3123 if (flags & EV_BACKCMD) {
3126 error("Pipe call failed");
3129 if (forkshell(jp, cmd, mode) != 0)
3130 goto parent; /* at end of routine */
3132 if (flags & EV_BACKCMD) {
3137 dup_as_newfd(pip[1], 1);
3145 /* This is the child process if a fork occurred. */
3146 /* Execute the command. */
3147 if (cmdentry.cmdtype == CMDFUNCTION) {
3149 trputs("Shell function: "); trargs(argv);
3151 exitstatus = oexitstatus;
3152 redirect(cmd->ncmd.redirect, REDIR_PUSH);
3153 saveparam = shellparam;
3154 shellparam.malloc = 0;
3155 shellparam.nparam = argc - 1;
3156 shellparam.p = argv + 1;
3158 savelocalvars = localvars;
3161 if (setjmp(jmploc.loc)) {
3162 if (exception == EXSHELLPROC) {
3163 freeparam((volatile struct shparam *)
3166 saveparam.optind = shellparam.optind;
3167 saveparam.optoff = shellparam.optoff;
3168 freeparam(&shellparam);
3169 shellparam = saveparam;
3172 localvars = savelocalvars;
3173 handler = savehandler;
3174 longjmp(handler->loc, 1);
3176 savehandler = handler;
3178 for (sp = varlist.list ; sp ; sp = sp->next)
3181 evaltree(cmdentry.u.func, flags & EV_TESTED);
3185 localvars = savelocalvars;
3186 saveparam.optind = shellparam.optind;
3187 saveparam.optoff = shellparam.optoff;
3188 freeparam(&shellparam);
3189 shellparam = saveparam;
3190 handler = savehandler;
3193 if (evalskip == SKIPFUNC) {
3197 if (flags & EV_EXIT)
3198 exitshell(exitstatus);
3199 } else if (cmdentry.cmdtype == CMDBUILTIN) {
3201 trputs("builtin command: "); trargs(argv);
3203 mode = (cmdentry.u.cmd == EXECCMD)? 0 : REDIR_PUSH;
3205 if (flags == EV_BACKCMD) {
3206 #ifdef USE_GLIBC_STDIO
3210 memout.nextc = memout.buf;
3211 memout.bufsize = 64;
3213 mode |= REDIR_BACKQ;
3216 redirect(cmd->ncmd.redirect, mode);
3217 savecmdname = commandname;
3218 if (IS_BUILTIN_SPECIAL(firstbltin)) {
3219 listsetvar(varlist.list);
3221 cmdenviron = varlist.list;
3224 if (setjmp(jmploc.loc)) {
3226 exitstatus = (e == EXINT)? SIGINT+128 : 2;
3229 savehandler = handler;
3231 commandname = argv[0];
3233 optptr = NULL; /* initialize nextopt */
3234 exitstatus = (*cmdentry.u.cmd->builtinfunc)(argc, argv);
3237 exitstatus |= outerr(out1);
3242 if (e != EXSHELLPROC) {
3243 commandname = savecmdname;
3244 if (flags & EV_EXIT)
3245 exitshell(exitstatus);
3247 handler = savehandler;
3249 if ((e != EXERROR && e != EXEXEC)
3250 || cmdentry.u.cmd == BLTINCMD
3251 || cmdentry.u.cmd == DOTCMD
3252 || cmdentry.u.cmd == EVALCMD
3253 || cmdentry.u.cmd == EXECCMD)
3257 if (cmdentry.u.cmd != EXECCMD)
3260 if (flags == EV_BACKCMD) {
3262 #ifdef USE_GLIBC_STDIO
3263 if (__closememout())
3264 error("__closememout() failed: %m");
3266 backcmd->buf = memout.buf;
3267 #ifdef USE_GLIBC_STDIO
3268 backcmd->nleft = memout.bufsize;
3270 backcmd->nleft = memout.nextc - memout.buf;
3278 trputs("normal command: "); trargs(argv);
3280 redirect(cmd->ncmd.redirect, 0);
3282 for (sp = varlist.list ; sp ; sp = sp->next)
3283 setvareq(sp->text, VEXPORT|VSTACK);
3284 envp = environment();
3285 shellexec(argv, envp, path, cmdentry.u.index);
3289 parent: /* parent process gets here (if we forked) */
3290 if (mode == 0) { /* argument to fork */
3292 exitstatus = waitforjob(jp);
3295 } else if (mode == 2) {
3296 backcmd->fd = pip[0];
3304 setvar("_", lastarg, 0);
3305 popstackmark(&smark);
3311 * Search for a command. This is called before we fork so that the
3312 * location of the command will be available in the parent as well as
3313 * the child. The check for "goodname" is an overly conservative
3314 * check that the name will not be subject to expansion.
3321 struct cmdentry entry;
3323 if (n->type == NCMD && n->ncmd.args)
3324 if (goodname(n->ncmd.args->narg.text))
3325 find_command(n->ncmd.args->narg.text, &entry, 0,
3332 * Builtin commands. Builtin commands whose functions are closely
3333 * tied to evaluation are implemented here.
3337 * No command given, or a bltin command with no arguments. Set the
3338 * specified variables.
3342 bltincmd(argc, argv)
3347 * Preserve exitstatus of a previous possible redirection
3355 * Handle break and continue commands. Break, continue, and return are
3356 * all handled by setting the evalskip flag. The evaluation routines
3357 * above all check this flag, and if it is set they start skipping
3358 * commands rather than executing them. The variable skipcount is
3359 * the number of loops to break/continue, or the number of function
3360 * levels to return. (The latter is always 1.) It should probably
3361 * be an error to break out of more loops than exist, but it isn't
3362 * in the standard shell so we don't make it one here.
3366 breakcmd(argc, argv)
3370 int n = argc > 1 ? number(argv[1]) : 1;
3375 evalskip = (**argv == 'c')? SKIPCONT : SKIPBREAK;
3383 * The return command.
3387 returncmd(argc, argv)
3391 int ret = argc > 1 ? number(argv[1]) : oexitstatus;
3394 evalskip = SKIPFUNC;
3399 /* Do what ksh does; skip the rest of the file */
3400 evalskip = SKIPFILE;
3407 #ifndef BB_TRUE_FALSE
3408 #ifdef ASH_BBAPPS_AS_BUILTINS
3410 false_main(argc, argv)
3419 true_main(argc, argv)
3429 * Controls whether the shell is interactive or not.
3432 static void setsignal(int signo);
3433 static void chkmail(int silent);
3437 setinteractive(int on)
3439 static int is_interactive;
3441 if (on == is_interactive)
3447 is_interactive = on;
3453 setinteractive(iflag);
3466 iflag = 0; /* exit on error */
3469 for (sp = cmdenviron; sp ; sp = sp->next)
3470 setvareq(sp->text, VEXPORT|VSTACK);
3471 shellexec(argv + 1, environment(), pathval(), 0);
3477 eprintlist(struct strlist *sp)
3479 for (; sp; sp = sp->next) {
3480 outfmt(&errout, " %s",sp->text);
3484 * When commands are first encountered, they are entered in a hash table.
3485 * This ensures that a full path search will not have to be done for them
3486 * on each invocation.
3488 * We should investigate converting to a linear search, even though that
3489 * would make the command name "hash" a misnomer.
3491 #define CMDTABLESIZE 31 /* should be prime */
3492 #define ARB 1 /* actual size determined at run time */
3497 struct tblentry *next; /* next entry in hash chain */
3498 union param param; /* definition of builtin function */
3499 short cmdtype; /* index identifying command */
3500 char rehash; /* if set, cd done since entry created */
3501 char cmdname[ARB]; /* name of command */
3505 static struct tblentry *cmdtable[CMDTABLESIZE];
3506 static int builtinloc = -1; /* index in path of %builtin, or -1 */
3507 static int exerrno = 0; /* Last exec error */
3510 static void tryexec (char *, char **, char **);
3511 static void printentry (struct tblentry *, int);
3512 static void clearcmdentry (int);
3513 static struct tblentry *cmdlookup (const char *, int);
3514 static void delete_cmd_entry (void);
3516 static int describe_command (char *, int);
3518 static int path_change (const char *, int *);
3522 * Exec a program. Never returns. If you change this routine, you may
3523 * have to change the find_command routine as well.
3526 static const char *pathopt; /* set by padvance */
3529 shellexec(argv, envp, path, idx)
3530 char **argv, **envp;
3537 if (strchr(argv[0], '/') != NULL) {
3538 tryexec(argv[0], argv, envp);
3542 while ((cmdname = padvance(&path, argv[0])) != NULL) {
3543 if (--idx < 0 && pathopt == NULL) {
3544 tryexec(cmdname, argv, envp);
3545 if (errno != ENOENT && errno != ENOTDIR)
3552 /* Map to POSIX errors */
3564 exerror(EXEXEC, "%s: %s", argv[0], errmsg(e, E_EXEC));
3569 * Clear traps on a fork.
3575 for (tp = trap ; tp < &trap[NSIG] ; tp++) {
3576 if (*tp && **tp) { /* trap not NULL or SIG_IGN */
3581 setsignal(tp - trap);
3589 initshellproc(void) {
3615 /* from options.c: */
3619 for (i = 0; i < NOPTS; i++)
3635 for (sm = sigmode ; sm < sigmode + NSIG - 1; sm++) {
3647 static int preadbuffer(void);
3648 static void pushfile (void);
3649 static int preadfd (void);
3652 * Read a character from the script, returning PEOF on end of file.
3653 * Nul characters in the input are silently discarded.
3656 #ifdef ASH_BBAPPS_AS_BUILTINS
3657 #define pgetc_macro() (--parsenleft >= 0? *parsenextc++ : preadbuffer())
3661 return pgetc_macro();
3667 return --parsenleft >= 0? *parsenextc++ : preadbuffer();
3673 return pgetc_macro();
3679 * Undo the last call to pgetc. Only one character may be pushed back.
3680 * PEOF may be pushed back.
3692 struct parsefile *pf = parsefile;
3701 parsefile = pf->prev;
3703 parsenleft = parsefile->nleft;
3704 parselleft = parsefile->lleft;
3705 parsenextc = parsefile->nextc;
3706 plinno = parsefile->linno;
3712 * Return to top level.
3717 while (parsefile != &basepf)
3722 * Close the file(s) that the shell is reading commands from. Called
3723 * after a fork is done.
3729 if (parsefile->fd > 0) {
3730 close(parsefile->fd);
3737 * Like setinputfile, but takes an open file descriptor. Call this with
3742 setinputfd(fd, push)
3745 (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
3751 while (parsefile->strpush)
3755 if (parsefile->buf == NULL)
3756 parsefile->buf = ckmalloc(BUFSIZ);
3757 parselleft = parsenleft = 0;
3763 * Set the input to take input from a file. If push is set, push the
3764 * old input onto the stack first.
3768 setinputfile(const char *fname, int push)
3774 if ((fd = open(fname, O_RDONLY)) < 0)
3775 error("Can't open %s", fname);
3777 myfileno2 = dup_as_newfd(fd, 10);
3780 error("Out of file descriptors");
3783 setinputfd(fd, push);
3789 tryexec(cmd, argv, envp)
3796 execve(cmd, argv, envp);
3801 setinputfile(cmd, 0);
3802 commandname = arg0 = savestr(argv[0]);
3804 exraise(EXSHELLPROC);
3809 static char *commandtext (const union node *);
3812 * Do a path search. The variable path (passed by reference) should be
3813 * set to the start of the path before the first call; padvance will update
3814 * this value as it proceeds. Successive calls to padvance will return
3815 * the possible path expansions in sequence. If an option (indicated by
3816 * a percent sign) appears in the path entry then the global variable
3817 * pathopt will be set to point to it; otherwise pathopt will be set to
3821 static const char *pathopt;
3823 static void growstackblock(void);
3827 padvance(const char **path, const char *name)
3837 for (p = start ; *p && *p != ':' && *p != '%' ; p++);
3838 len = p - start + strlen(name) + 2; /* "2" is for '/' and '\0' */
3839 while (stackblocksize() < len)
3843 memcpy(q, start, p - start);
3851 while (*p && *p != ':') p++;
3857 return stalloc(len);
3862 /*** Command hashing code ***/
3870 struct tblentry **pp;
3871 struct tblentry *cmdp;
3874 struct cmdentry entry;
3878 while ((c = nextopt("rv")) != '\0') {
3882 } else if (c == 'v') {
3886 if (*argptr == NULL) {
3887 for (pp = cmdtable ; pp < &cmdtable[CMDTABLESIZE] ; pp++) {
3888 for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) {
3889 if (cmdp->cmdtype != CMDBUILTIN) {
3890 printentry(cmdp, verbose);
3897 while ((name = *argptr) != NULL) {
3898 if ((cmdp = cmdlookup(name, 0)) != NULL
3899 && (cmdp->cmdtype == CMDNORMAL
3900 || (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0)))
3902 find_command(name, &entry, DO_ERR, pathval());
3903 if (entry.cmdtype == CMDUNKNOWN) c = 1;
3905 cmdp = cmdlookup(name, 0);
3906 if (cmdp) printentry(cmdp, verbose);
3916 printentry(cmdp, verbose)
3917 struct tblentry *cmdp;
3924 if (cmdp->cmdtype == CMDNORMAL) {
3925 idx = cmdp->param.index;
3928 name = padvance(&path, cmdp->cmdname);
3930 } while (--idx >= 0);
3932 } else if (cmdp->cmdtype == CMDBUILTIN) {
3933 out1fmt("builtin %s", cmdp->cmdname);
3934 } else if (cmdp->cmdtype == CMDFUNCTION) {
3935 out1fmt("function %s", cmdp->cmdname);
3938 name = commandtext(cmdp->param.func);
3939 out1fmt(" %s", name);
3945 error("internal error: cmdtype %d", cmdp->cmdtype);
3948 out1fmt(snlfmt, cmdp->rehash ? "*" : nullstr);
3954 * Resolve a command name. If you change this routine, you may have to
3955 * change the shellexec routine as well.
3958 static int prefix (const char *, const char *);
3961 find_command(const char *name, struct cmdentry *entry, int act, const char *path)
3963 struct tblentry *cmdp;
3973 struct builtincmd *bcmd;
3975 /* If name contains a slash, don't use the hash table */
3976 if (strchr(name, '/') != NULL) {
3978 while (stat(name, &statb) < 0) {
3979 if (errno != ENOENT && errno != ENOTDIR)
3981 entry->cmdtype = CMDUNKNOWN;
3982 entry->u.index = -1;
3985 entry->cmdtype = CMDNORMAL;
3986 entry->u.index = -1;
3989 entry->cmdtype = CMDNORMAL;
3995 if (act & DO_BRUTE) {
3996 firstchange = path_change(path, &bltin);
4002 /* If name is in the table, and not invalidated by cd, we're done */
4003 if ((cmdp = cmdlookup(name, 0)) != NULL && cmdp->rehash == 0) {
4004 if (cmdp->cmdtype == CMDFUNCTION) {
4005 if (act & DO_NOFUN) {
4010 } else if (act & DO_BRUTE) {
4011 if ((cmdp->cmdtype == CMDNORMAL &&
4012 cmdp->param.index >= firstchange) ||
4013 (cmdp->cmdtype == CMDBUILTIN &&
4014 ((builtinloc < 0 && bltin >= 0) ?
4015 bltin : builtinloc) >= firstchange)) {
4016 /* need to recompute the entry */
4025 bcmd = find_builtin(name);
4026 regular = bcmd && IS_BUILTIN_REGULAR(bcmd);
4029 if (cmdp && (cmdp->cmdtype == CMDBUILTIN)) {
4032 } else if (act & DO_BRUTE) {
4033 if (firstchange == 0) {
4038 /* If %builtin not in path, check for builtin next */
4039 if (regular || (bltin < 0 && bcmd)) {
4042 entry->cmdtype = CMDBUILTIN;
4043 entry->u.cmd = bcmd;
4047 cmdp = cmdlookup(name, 1);
4048 cmdp->cmdtype = CMDBUILTIN;
4049 cmdp->param.cmd = bcmd;
4054 /* We have to search path. */
4055 prev = -1; /* where to start */
4056 if (cmdp && cmdp->rehash) { /* doing a rehash */
4057 if (cmdp->cmdtype == CMDBUILTIN)
4060 prev = cmdp->param.index;
4066 while ((fullname = padvance(&path, name)) != NULL) {
4067 stunalloc(fullname);
4069 if (idx >= firstchange) {
4073 if (prefix("builtin", pathopt)) {
4074 if ((bcmd = find_builtin(name))) {
4078 } else if (!(act & DO_NOFUN) &&
4079 prefix("func", pathopt)) {
4082 continue; /* ignore unimplemented options */
4085 /* if rehash, don't redo absolute path names */
4086 if (fullname[0] == '/' && idx <= prev &&
4087 idx < firstchange) {
4090 TRACE(("searchexec \"%s\": no change\n", name));
4093 while (stat(fullname, &statb) < 0) {
4094 if (errno != ENOENT && errno != ENOTDIR)
4098 e = EACCES; /* if we fail, this will be the error */
4099 if (!S_ISREG(statb.st_mode))
4101 if (pathopt) { /* this is a %func directory */
4102 stalloc(strlen(fullname) + 1);
4103 readcmdfile(fullname);
4104 if ((cmdp = cmdlookup(name, 0)) == NULL || cmdp->cmdtype != CMDFUNCTION)
4105 error("%s not defined in %s", name, fullname);
4106 stunalloc(fullname);
4109 TRACE(("searchexec \"%s\" returns \"%s\"\n", name, fullname));
4110 /* If we aren't called with DO_BRUTE and cmdp is set, it must
4111 be a function and we're being called with DO_NOFUN */
4113 entry->cmdtype = CMDNORMAL;
4114 entry->u.index = idx;
4118 cmdp = cmdlookup(name, 1);
4119 cmdp->cmdtype = CMDNORMAL;
4120 cmdp->param.index = idx;
4125 /* We failed. If there was an entry for this command, delete it */
4126 if (cmdp && updatetbl)
4129 outfmt(out2, "%s: %s\n", name, errmsg(e, E_EXEC));
4130 entry->cmdtype = CMDUNKNOWN;
4135 entry->cmdtype = cmdp->cmdtype;
4136 entry->u = cmdp->param;
4142 * Search the table of builtin commands.
4146 bstrcmp(const void *name, const void *b)
4148 return strcmp((const char *)name, (*(const char *const *) b)+1);
4151 static struct builtincmd *
4152 find_builtin(const char *name)
4154 struct builtincmd *bp;
4156 bp = bsearch(name, builtincmds, NUMBUILTINS, sizeof(struct builtincmd),
4164 * Called when a cd is done. Marks all commands so the next time they
4165 * are executed they will be rehashed.
4170 struct tblentry **pp;
4171 struct tblentry *cmdp;
4173 for (pp = cmdtable ; pp < &cmdtable[CMDTABLESIZE] ; pp++) {
4174 for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) {
4175 if (cmdp->cmdtype == CMDNORMAL
4176 || (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0))
4185 * Called before PATH is changed. The argument is the new value of PATH;
4186 * pathval() still returns the old value at this point. Called with
4191 changepath(const char *newval)
4196 firstchange = path_change(newval, &bltin);
4197 if (builtinloc < 0 && bltin >= 0)
4198 builtinloc = bltin; /* zap builtins */
4199 clearcmdentry(firstchange);
4205 * Clear out command entries. The argument specifies the first entry in
4206 * PATH which has changed.
4210 clearcmdentry(firstchange)
4213 struct tblentry **tblp;
4214 struct tblentry **pp;
4215 struct tblentry *cmdp;
4218 for (tblp = cmdtable ; tblp < &cmdtable[CMDTABLESIZE] ; tblp++) {
4220 while ((cmdp = *pp) != NULL) {
4221 if ((cmdp->cmdtype == CMDNORMAL &&
4222 cmdp->param.index >= firstchange)
4223 || (cmdp->cmdtype == CMDBUILTIN &&
4224 builtinloc >= firstchange)) {
4236 * Free a parse tree.
4240 freefunc(union node *n)
4248 * Delete all functions.
4253 struct tblentry **tblp;
4254 struct tblentry **pp;
4255 struct tblentry *cmdp;
4258 for (tblp = cmdtable ; tblp < &cmdtable[CMDTABLESIZE] ; tblp++) {
4260 while ((cmdp = *pp) != NULL) {
4261 if (cmdp->cmdtype == CMDFUNCTION) {
4263 freefunc(cmdp->param.func);
4276 * Locate a command in the command hash table. If "add" is nonzero,
4277 * add the command to the table if it is not already present. The
4278 * variable "lastcmdentry" is set to point to the address of the link
4279 * pointing to the entry, so that delete_cmd_entry can delete the
4283 static struct tblentry **lastcmdentry;
4285 static struct tblentry *
4286 cmdlookup(const char *name, int add)
4290 struct tblentry *cmdp;
4291 struct tblentry **pp;
4298 pp = &cmdtable[hashval % CMDTABLESIZE];
4299 for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) {
4300 if (equal(cmdp->cmdname, name))
4304 if (add && cmdp == NULL) {
4306 cmdp = *pp = ckmalloc(sizeof (struct tblentry) - ARB
4307 + strlen(name) + 1);
4309 cmdp->cmdtype = CMDUNKNOWN;
4311 strcpy(cmdp->cmdname, name);
4319 * Delete the command entry returned on the last lookup.
4323 delete_cmd_entry() {
4324 struct tblentry *cmdp;
4327 cmdp = *lastcmdentry;
4328 *lastcmdentry = cmdp->next;
4336 * Add a new command entry, replacing any existing command entry for
4341 addcmdentry(char *name, struct cmdentry *entry)
4343 struct tblentry *cmdp;
4346 cmdp = cmdlookup(name, 1);
4347 if (cmdp->cmdtype == CMDFUNCTION) {
4348 freefunc(cmdp->param.func);
4350 cmdp->cmdtype = entry->cmdtype;
4351 cmdp->param = entry->u;
4357 * Define a shell function.
4360 static union node *copyfunc(union node *);
4363 defun(char *name, union node *func)
4365 struct cmdentry entry;
4367 entry.cmdtype = CMDFUNCTION;
4368 entry.u.func = copyfunc(func);
4369 addcmdentry(name, &entry);
4374 * Delete a function if it exists.
4378 unsetfunc(char *name)
4380 struct tblentry *cmdp;
4382 if ((cmdp = cmdlookup(name, 0)) != NULL && cmdp->cmdtype == CMDFUNCTION) {
4383 freefunc(cmdp->param.func);
4389 * Wrapper around strcmp for qsort/bsearch/...
4392 pstrcmp(const void *a, const void *b)
4394 return strcmp((const char *) a, *(const char *const *) b);
4398 * Find a keyword is in a sorted array.
4401 static const char *const *
4402 findkwd(const char *s)
4404 return bsearch(s, parsekwd, sizeof(parsekwd) / sizeof(const char *),
4405 sizeof(const char *), pstrcmp);
4410 * Locate and print what a word is...
4421 for (i = 1; i < argc; i++) {
4422 err |= describe_command(argv[i], 1);
4428 describe_command(char *command, int verbose)
4430 struct cmdentry entry;
4431 struct tblentry *cmdp;
4433 const struct alias *ap;
4435 const char *path = pathval();
4441 /* First look at the keywords */
4442 if (findkwd(command)) {
4443 out1str(verbose ? " is a shell keyword" : command);
4448 /* Then look at the aliases */
4449 if ((ap = lookupalias(command, 0)) != NULL) {
4451 out1fmt(" is an alias for %s", ap->val);
4458 /* Then check if it is a tracked alias */
4459 if ((cmdp = cmdlookup(command, 0)) != NULL) {
4460 entry.cmdtype = cmdp->cmdtype;
4461 entry.u = cmdp->param;
4463 /* Finally use brute force */
4464 find_command(command, &entry, DO_ABS, path);
4467 switch (entry.cmdtype) {
4469 int j = entry.u.index;
4475 p = padvance(&path, command);
4482 cmdp ? " a tracked alias for" : nullstr, p
4492 out1str(" is a shell function");
4501 " is a %sshell builtin",
4502 IS_BUILTIN_SPECIAL(entry.u.cmd) ?
4503 "special " : nullstr
4512 out1str(": not found\n");
4525 commandcmd(argc, argv)
4530 int default_path = 0;
4531 int verify_only = 0;
4532 int verbose_verify_only = 0;
4534 while ((c = nextopt("pvV")) != '\0')
4543 verbose_verify_only = 1;
4547 "command: nextopt returned character code 0%o\n", c);
4551 if (default_path + verify_only + verbose_verify_only > 1 ||
4554 "command [-p] command [arg ...]\n");
4556 "command {-v|-V} command\n");
4561 if (verify_only || verbose_verify_only) {
4562 return describe_command(*argptr, verbose_verify_only);
4571 path_change(newval, bltin)
4575 const char *old, *new;
4581 firstchange = 9999; /* assume no change */
4587 if ((*old == '\0' && *new == ':')
4588 || (*old == ':' && *new == '\0'))
4590 old = new; /* ignore subsequent differences */
4594 if (*new == '%' && *bltin < 0 && prefix("builtin", new + 1))
4601 if (builtinloc >= 0 && *bltin < 0)
4606 * Routines to expand arguments to commands. We have to deal with
4607 * backquotes, shell variables, and file metacharacters.
4612 #define RMESCAPE_ALLOC 0x1 /* Allocate a new string */
4613 #define RMESCAPE_GLOB 0x2 /* Add backslashes for glob */
4616 * Structure specifying which parts of the string should be searched
4617 * for IFS characters.
4621 struct ifsregion *next; /* next region in list */
4622 int begoff; /* offset of start of region */
4623 int endoff; /* offset of end of region */
4624 int nulonly; /* search for nul bytes only */
4628 static char *expdest; /* output of current string */
4629 static struct nodelist *argbackq; /* list of back quote expressions */
4630 static struct ifsregion ifsfirst; /* first struct in list of ifs regions */
4631 static struct ifsregion *ifslastp; /* last struct in list */
4632 static struct arglist exparg; /* holds expanded arg list */
4634 static void argstr (char *, int);
4635 static char *exptilde (char *, int);
4636 static void expbackq (union node *, int, int);
4637 static int subevalvar (char *, char *, int, int, int, int, int);
4638 static char *evalvar (char *, int);
4639 static int varisset (char *, int);
4640 static void strtodest (const char *, const char *, int);
4641 static void varvalue (char *, int, int);
4642 static void recordregion (int, int, int);
4643 static void removerecordregions (int);
4644 static void ifsbreakup (char *, struct arglist *);
4645 static void ifsfree (void);
4646 static void expandmeta (struct strlist *, int);
4647 #if defined(__GLIBC__) && !defined(FNMATCH_BROKEN)
4648 #define preglob(p) _rmescapes((p), RMESCAPE_ALLOC | RMESCAPE_GLOB)
4649 #if !defined(GLOB_BROKEN)
4650 static void addglob (const glob_t *);
4653 #if !(defined(__GLIBC__) && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN))
4654 static void expmeta (char *, char *);
4656 #if !(defined(__GLIBC__) && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN))
4657 static struct strlist *expsort (struct strlist *);
4658 static struct strlist *msort (struct strlist *, int);
4660 #if defined(__GLIBC__) && !defined(FNMATCH_BROKEN)
4661 static int patmatch (char *, char *, int);
4662 static int patmatch2 (char *, char *, int);
4664 static int pmatch (char *, char *, int);
4665 #define patmatch2 patmatch
4667 static char *cvtnum (int, char *);
4670 * Expand shell variables and backquotes inside a here document.
4673 /* arg: the document, fd: where to write the expanded version */
4675 expandhere(union node *arg, int fd)
4678 expandarg(arg, (struct arglist *)NULL, 0);
4679 xwrite(fd, stackblock(), expdest - stackblock());
4684 * Perform variable substitution and command substitution on an argument,
4685 * placing the resulting list of arguments in arglist. If EXP_FULL is true,
4686 * perform splitting and file name expansion. When arglist is NULL, perform
4687 * here document expansion.
4691 expandarg(arg, arglist, flag)
4693 struct arglist *arglist;
4699 argbackq = arg->narg.backquote;
4700 STARTSTACKSTR(expdest);
4701 ifsfirst.next = NULL;
4703 argstr(arg->narg.text, flag);
4704 if (arglist == NULL) {
4705 return; /* here document expanded */
4707 STPUTC('\0', expdest);
4708 p = grabstackstr(expdest);
4709 exparg.lastp = &exparg.list;
4713 if (flag & EXP_FULL) {
4714 ifsbreakup(p, &exparg);
4715 *exparg.lastp = NULL;
4716 exparg.lastp = &exparg.list;
4717 expandmeta(exparg.list, flag);
4719 if (flag & EXP_REDIR) /*XXX - for now, just remove escapes */
4721 sp = (struct strlist *)stalloc(sizeof (struct strlist));
4724 exparg.lastp = &sp->next;
4727 *exparg.lastp = NULL;
4729 *arglist->lastp = exparg.list;
4730 arglist->lastp = exparg.lastp;
4737 * Perform variable and command substitution. If EXP_FULL is set, output CTLESC
4738 * characters to allow for further processing. Otherwise treat
4739 * $@ like $* since no splitting will be performed.
4748 int quotes = flag & (EXP_FULL | EXP_CASE); /* do CTLESC */
4751 if (*p == '~' && (flag & (EXP_TILDE | EXP_VARTILDE)))
4752 p = exptilde(p, flag);
4756 case CTLENDVAR: /* ??? */
4759 /* "$@" syntax adherence hack */
4760 if (p[0] == CTLVAR && p[2] == '@' && p[3] == '=')
4762 if ((flag & EXP_FULL) != 0)
4772 p = evalvar(p, flag);
4775 case CTLBACKQ|CTLQUOTE:
4776 expbackq(argbackq->n, c & CTLQUOTE, flag);
4777 argbackq = argbackq->next;
4779 #ifdef ASH_MATH_SUPPORT
4787 * sort of a hack - expand tildes in variable
4788 * assignments (after the first '=' and after ':'s).
4791 if (flag & EXP_VARTILDE && *p == '~') {
4798 p = exptilde(p, flag);
4814 char c, *startp = p;
4817 int quotes = flag & (EXP_FULL | EXP_CASE);
4819 while ((c = *p) != '\0') {
4826 if (flag & EXP_VARTILDE)
4836 if (*(startp+1) == '\0') {
4837 if ((home = lookupvar("HOME")) == NULL)
4840 if ((pw = getpwnam(startp+1)) == NULL)
4847 strtodest(home, SQSYNTAX, quotes);
4856 removerecordregions(int endoff)
4858 if (ifslastp == NULL)
4861 if (ifsfirst.endoff > endoff) {
4862 while (ifsfirst.next != NULL) {
4863 struct ifsregion *ifsp;
4865 ifsp = ifsfirst.next->next;
4866 ckfree(ifsfirst.next);
4867 ifsfirst.next = ifsp;
4870 if (ifsfirst.begoff > endoff)
4873 ifslastp = &ifsfirst;
4874 ifsfirst.endoff = endoff;
4879 ifslastp = &ifsfirst;
4880 while (ifslastp->next && ifslastp->next->begoff < endoff)
4881 ifslastp=ifslastp->next;
4882 while (ifslastp->next != NULL) {
4883 struct ifsregion *ifsp;
4885 ifsp = ifslastp->next->next;
4886 ckfree(ifslastp->next);
4887 ifslastp->next = ifsp;
4890 if (ifslastp->endoff > endoff)
4891 ifslastp->endoff = endoff;
4895 #ifdef ASH_MATH_SUPPORT
4897 * Expand arithmetic expression. Backup to start of expression,
4898 * evaluate, place result in (backed up) result, adjust string position.
4906 int quotes = flag & (EXP_FULL | EXP_CASE);
4912 * This routine is slightly over-complicated for
4913 * efficiency. First we make sure there is
4914 * enough space for the result, which may be bigger
4915 * than the expression if we add exponentation. Next we
4916 * scan backwards looking for the start of arithmetic. If the
4917 * next previous character is a CTLESC character, then we
4918 * have to rescan starting from the beginning since CTLESC
4919 * characters have to be processed left to right.
4921 CHECKSTRSPACE(10, expdest);
4922 USTPUTC('\0', expdest);
4923 start = stackblock();
4925 while (*p != CTLARI && p >= start)
4928 error("missing CTLARI (shouldn't happen)");
4929 if (p > start && *(p-1) == CTLESC)
4930 for (p = start; *p != CTLARI; p++)
4939 removerecordregions(begoff);
4942 result = arith(p+2);
4943 fmtstr(p, 12, "%d", result);
4949 recordregion(begoff, p - 1 - start, 0);
4950 result = expdest - p + 1;
4951 STADJUST(-result, expdest);
4956 * Expand stuff in backwards quotes.
4960 expbackq(cmd, quoted, flag)
4965 volatile struct backcmd in;
4969 char *dest = expdest;
4970 volatile struct ifsregion saveifs;
4971 struct ifsregion *volatile savelastp;
4972 struct nodelist *volatile saveargbackq;
4974 int startloc = dest - stackblock();
4975 char const *syntax = quoted? DQSYNTAX : BASESYNTAX;
4976 volatile int saveherefd;
4977 int quotes = flag & (EXP_FULL | EXP_CASE);
4978 struct jmploc jmploc;
4979 struct jmploc *volatile savehandler;
4983 /* Avoid longjmp clobbering */
4994 savelastp = ifslastp;
4995 saveargbackq = argbackq;
4996 saveherefd = herefd;
4998 if ((ex = setjmp(jmploc.loc))) {
5001 savehandler = handler;
5004 p = grabstackstr(dest);
5005 evalbackcmd(cmd, (struct backcmd *) &in);
5006 ungrabstackstr(p, dest);
5010 ifslastp = savelastp;
5011 argbackq = saveargbackq;
5012 herefd = saveherefd;
5020 if (--in.nleft < 0) {
5023 while ((i = read(in.fd, buf, sizeof buf)) < 0 && errno == EINTR);
5024 TRACE(("expbackq: read returns %d\n", i));
5031 if (lastc != '\0') {
5032 if (quotes && syntax[(int)lastc] == CCTL)
5033 STPUTC(CTLESC, dest);
5034 STPUTC(lastc, dest);
5038 /* Eat all trailing newlines */
5039 for (; dest > stackblock() && dest[-1] == '\n';)
5048 exitstatus = waitforjob(in.jp);
5049 handler = savehandler;
5051 longjmp(handler->loc, 1);
5054 recordregion(startloc, dest - stackblock(), 0);
5055 TRACE(("evalbackq: size=%d: \"%.*s\"\n",
5056 (dest - stackblock()) - startloc,
5057 (dest - stackblock()) - startloc,
5058 stackblock() + startloc));
5064 subevalvar(p, str, strloc, subtype, startloc, varflags, quotes)
5077 int saveherefd = herefd;
5078 struct nodelist *saveargbackq = argbackq;
5082 argstr(p, subtype != VSASSIGN && subtype != VSQUESTION ? EXP_CASE : 0);
5083 STACKSTRNUL(expdest);
5084 herefd = saveherefd;
5085 argbackq = saveargbackq;
5086 startp = stackblock() + startloc;
5088 str = stackblock() + strloc;
5092 setvar(str, startp, 0);
5093 amount = startp - expdest;
5094 STADJUST(amount, expdest);
5101 if (*p != CTLENDVAR) {
5102 outfmt(&errout, snlfmt, startp);
5103 error((char *)NULL);
5105 error("%.*s: parameter %snot set", p - str - 1,
5106 str, (varflags & VSNUL) ? "null or "
5111 for (loc = startp; loc < str; loc++) {
5114 if (patmatch2(str, startp, quotes))
5117 if (quotes && *loc == CTLESC)
5123 for (loc = str - 1; loc >= startp;) {
5126 if (patmatch2(str, startp, quotes))
5130 if (quotes && loc > startp && *(loc - 1) == CTLESC) {
5131 for (q = startp; q < loc; q++)
5141 for (loc = str - 1; loc >= startp;) {
5142 if (patmatch2(str, loc, quotes))
5145 if (quotes && loc > startp && *(loc - 1) == CTLESC) {
5146 for (q = startp; q < loc; q++)
5155 case VSTRIMRIGHTMAX:
5156 for (loc = startp; loc < str - 1; loc++) {
5157 if (patmatch2(str, loc, quotes))
5159 if (quotes && *loc == CTLESC)
5172 amount = ((str - 1) - (loc - startp)) - expdest;
5173 STADJUST(amount, expdest);
5174 while (loc != str - 1)
5179 amount = loc - expdest;
5180 STADJUST(amount, expdest);
5181 STPUTC('\0', expdest);
5182 STADJUST(-1, expdest);
5188 * Expand a variable, and return a pointer to the next character in the
5208 int quotes = flag & (EXP_FULL | EXP_CASE);
5211 subtype = varflags & VSTYPE;
5216 p = strchr(p, '=') + 1;
5217 again: /* jump here after setting a variable with ${var=text} */
5219 set = varisset(var, varflags & VSNUL);
5222 val = lookupvar(var);
5223 if (val == NULL || ((varflags & VSNUL) && val[0] == '\0')) {
5230 startloc = expdest - stackblock();
5231 if (set && subtype != VSPLUS) {
5232 /* insert the value of the variable */
5234 varvalue(var, varflags & VSQUOTE, flag);
5235 if (subtype == VSLENGTH) {
5236 varlen = expdest - stackblock() - startloc;
5237 STADJUST(-varlen, expdest);
5240 if (subtype == VSLENGTH) {
5241 varlen = strlen(val);
5245 varflags & VSQUOTE ?
5246 DQSYNTAX : BASESYNTAX,
5253 if (subtype == VSPLUS)
5256 easy = ((varflags & VSQUOTE) == 0 ||
5257 (*var == '@' && shellparam.nparam != 1));
5262 expdest = cvtnum(varlen, expdest);
5269 recordregion(startloc, expdest - stackblock(),
5270 varflags & VSQUOTE);
5286 case VSTRIMRIGHTMAX:
5290 * Terminate the string and start recording the pattern
5293 STPUTC('\0', expdest);
5294 patloc = expdest - stackblock();
5295 if (subevalvar(p, NULL, patloc, subtype,
5296 startloc, varflags, quotes) == 0) {
5297 int amount = (expdest - stackblock() - patloc) + 1;
5298 STADJUST(-amount, expdest);
5300 /* Remove any recorded regions beyond start of variable */
5301 removerecordregions(startloc);
5307 if (subevalvar(p, var, 0, subtype, startloc,
5308 varflags, quotes)) {
5311 * Remove any recorded regions beyond
5314 removerecordregions(startloc);
5329 if (subtype != VSNORMAL) { /* skip to end of alternative */
5332 if ((c = *p++) == CTLESC)
5334 else if (c == CTLBACKQ || c == (CTLBACKQ|CTLQUOTE)) {
5336 argbackq = argbackq->next;
5337 } else if (c == CTLVAR) {
5338 if ((*p++ & VSTYPE) != VSNORMAL)
5340 } else if (c == CTLENDVAR) {
5350 * Test whether a specialized variable is set.
5354 varisset(name, nulok)
5359 return backgndpid != -1;
5360 else if (*name == '@' || *name == '*') {
5361 if (*shellparam.p == NULL)
5367 for (av = shellparam.p; *av; av++)
5372 } else if (is_digit(*name)) {
5374 int num = atoi(name);
5376 if (num > shellparam.nparam)
5382 ap = shellparam.p[num - 1];
5384 if (nulok && (ap == NULL || *ap == '\0'))
5391 * Put a string on the stack.
5395 strtodest(p, syntax, quotes)
5401 if (quotes && syntax[(int) *p] == CCTL)
5402 STPUTC(CTLESC, expdest);
5403 STPUTC(*p++, expdest);
5408 * Add the value of a specialized variable to the stack string.
5412 varvalue(name, quoted, flags)
5424 int allow_split = flags & EXP_FULL;
5425 int quotes = flags & (EXP_FULL | EXP_CASE);
5427 syntax = quoted ? DQSYNTAX : BASESYNTAX;
5436 num = shellparam.nparam;
5441 expdest = cvtnum(num, expdest);
5444 for (i = 0 ; i < NOPTS ; i++) {
5446 STPUTC(optent_letter(optlist[i]), expdest);
5450 if (allow_split && quoted) {
5451 sep = 1 << CHAR_BIT;
5456 sep = ifsset() ? ifsval()[0] : ' ';
5458 sepq = syntax[(int) sep] == CCTL;
5461 for (ap = shellparam.p ; (p = *ap++) != NULL ; ) {
5462 strtodest(p, syntax, quotes);
5465 STPUTC(CTLESC, expdest);
5466 STPUTC(sep, expdest);
5471 strtodest(arg0, syntax, quotes);
5475 if (num > 0 && num <= shellparam.nparam) {
5476 strtodest(shellparam.p[num - 1], syntax, quotes);
5484 * Record the fact that we have to scan this region of the
5485 * string for IFS characters.
5489 recordregion(start, end, nulonly)
5494 struct ifsregion *ifsp;
5496 if (ifslastp == NULL) {
5500 ifsp = (struct ifsregion *)ckmalloc(sizeof (struct ifsregion));
5502 ifslastp->next = ifsp;
5506 ifslastp->begoff = start;
5507 ifslastp->endoff = end;
5508 ifslastp->nulonly = nulonly;
5514 * Break the argument string into pieces based upon IFS and add the
5515 * strings to the argument list. The regions of the string to be
5516 * searched for IFS characters have been stored by recordregion.
5519 ifsbreakup(string, arglist)
5521 struct arglist *arglist;
5523 struct ifsregion *ifsp;
5528 const char *ifs, *realifs;
5536 realifs = ifsset() ? ifsval() : defifs;
5537 if (ifslastp != NULL) {
5540 p = string + ifsp->begoff;
5541 nulonly = ifsp->nulonly;
5542 ifs = nulonly ? nullstr : realifs;
5544 while (p < string + ifsp->endoff) {
5548 if (strchr(ifs, *p)) {
5550 ifsspc = (strchr(defifs, *p) != NULL);
5551 /* Ignore IFS whitespace at start */
5552 if (q == start && ifsspc) {
5558 sp = (struct strlist *)stalloc(sizeof *sp);
5560 *arglist->lastp = sp;
5561 arglist->lastp = &sp->next;
5565 if (p >= string + ifsp->endoff) {
5571 if (strchr(ifs, *p) == NULL ) {
5574 } else if (strchr(defifs, *p) == NULL) {
5590 } while ((ifsp = ifsp->next) != NULL);
5591 if (!(*start || (!ifsspc && start > string && nulonly))) {
5596 sp = (struct strlist *)stalloc(sizeof *sp);
5598 *arglist->lastp = sp;
5599 arglist->lastp = &sp->next;
5605 while (ifsfirst.next != NULL) {
5606 struct ifsregion *ifsp;
5608 ifsp = ifsfirst.next->next;
5609 ckfree(ifsfirst.next);
5610 ifsfirst.next = ifsp;
5614 ifsfirst.next = NULL;
5618 * Add a file name to the list.
5622 addfname(const char *name)
5628 sp = (struct strlist *)stalloc(sizeof *sp);
5631 exparg.lastp = &sp->next;
5635 * Expand shell metacharacters. At this point, the only control characters
5636 * should be escapes. The results are stored in the list exparg.
5639 #if defined(__GLIBC__) && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN)
5641 expandmeta(str, flag)
5642 struct strlist *str;
5647 /* TODO - EXP_REDIR */
5652 p = preglob(str->text);
5654 switch (glob(p, GLOB_NOMAGIC, 0, &pglob)) {
5656 if (!(pglob.gl_flags & GLOB_MAGCHAR))
5667 *exparg.lastp = str;
5668 rmescapes(str->text);
5669 exparg.lastp = &str->next;
5671 default: /* GLOB_NOSPACE */
5672 error("Out of space");
5680 * Add the result of glob(3) to the list.
5685 const glob_t *pglob;
5687 char **p = pglob->gl_pathv;
5695 #else /* defined(__GLIBC__) && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN) */
5696 static char *expdir;
5700 expandmeta(str, flag)
5701 struct strlist *str;
5705 struct strlist **savelastp;
5708 /* TODO - EXP_REDIR */
5714 for (;;) { /* fast check for meta chars */
5715 if ((c = *p++) == '\0')
5717 if (c == '*' || c == '?' || c == '[' || c == '!')
5720 savelastp = exparg.lastp;
5722 if (expdir == NULL) {
5723 int i = strlen(str->text);
5724 expdir = ckmalloc(i < 2048 ? 2048 : i); /* XXX */
5727 expmeta(expdir, str->text);
5731 if (exparg.lastp == savelastp) {
5736 *exparg.lastp = str;
5737 rmescapes(str->text);
5738 exparg.lastp = &str->next;
5740 *exparg.lastp = NULL;
5741 *savelastp = sp = expsort(*savelastp);
5742 while (sp->next != NULL)
5744 exparg.lastp = &sp->next;
5752 * Do metacharacter (i.e. *, ?, [...]) expansion.
5756 expmeta(enddir, name)
5774 for (p = name ; ; p++) {
5775 if (*p == '*' || *p == '?')
5777 else if (*p == '[') {
5782 while (*q == CTLQUOTEMARK)
5786 if (*q == '/' || *q == '\0')
5793 } else if (*p == '!' && p[1] == '!' && (p == name || p[-1] == '/')) {
5795 } else if (*p == '\0')
5797 else if (*p == CTLQUOTEMARK)
5799 else if (*p == CTLESC)
5807 if (metaflag == 0) { /* we've reached the end of the file name */
5808 if (enddir != expdir)
5810 for (p = name ; ; p++) {
5811 if (*p == CTLQUOTEMARK)
5819 if (metaflag == 0 || lstat(expdir, &statb) >= 0)
5824 if (start != name) {
5827 while (*p == CTLQUOTEMARK)
5834 if (enddir == expdir) {
5836 } else if (enddir == expdir + 1 && *expdir == '/') {
5842 if ((dirp = opendir(cp)) == NULL)
5844 if (enddir != expdir)
5846 if (*endname == 0) {
5854 while (*p == CTLQUOTEMARK)
5860 while (! int_pending() && (dp = readdir(dirp)) != NULL) {
5861 if (dp->d_name[0] == '.' && ! matchdot)
5863 if (patmatch(start, dp->d_name, 0)) {
5865 strcpy(enddir, dp->d_name);
5868 for (p = enddir, cp = dp->d_name;
5869 (*p++ = *cp++) != '\0';)
5872 expmeta(p, endname);
5880 #endif /* defined(__GLIBC__) && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN) */
5884 #if !(defined(__GLIBC__) && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN))
5886 * Sort the results of file name expansion. It calculates the number of
5887 * strings to sort and then calls msort (short for merge sort) to do the
5891 static struct strlist *
5893 struct strlist *str;
5899 for (sp = str ; sp ; sp = sp->next)
5901 return msort(str, len);
5905 static struct strlist *
5907 struct strlist *list;
5910 struct strlist *p, *q = NULL;
5911 struct strlist **lpp;
5919 for (n = half ; --n >= 0 ; ) {
5923 q->next = NULL; /* terminate first half of list */
5924 q = msort(list, half); /* sort first half of list */
5925 p = msort(p, len - half); /* sort second half */
5928 if (strcmp(p->text, q->text) < 0) {
5931 if ((p = *lpp) == NULL) {
5938 if ((q = *lpp) == NULL) {
5951 * Returns true if the pattern matches the string.
5954 #if defined(__GLIBC__) && !defined(FNMATCH_BROKEN)
5955 /* squoted: string might have quote chars */
5957 patmatch(char *pattern, char *string, int squoted)
5962 p = preglob(pattern);
5963 q = squoted ? _rmescapes(string, RMESCAPE_ALLOC) : string;
5965 return !fnmatch(p, q, 0);
5970 patmatch2(char *pattern, char *string, int squoted)
5976 p = grabstackstr(expdest);
5977 res = patmatch(pattern, string, squoted);
5978 ungrabstackstr(p, expdest);
5983 patmatch(char *pattern, char *string, int squoted) {
5984 return pmatch(pattern, string, squoted);
5989 pmatch(char *pattern, char *string, int squoted)
6001 if (squoted && *q == CTLESC)
6009 if (squoted && *q == CTLESC)
6016 while (c == CTLQUOTEMARK || c == '*')
6018 if (c != CTLESC && c != CTLQUOTEMARK &&
6019 c != '?' && c != '*' && c != '[') {
6021 if (squoted && *q == CTLESC &&
6026 if (squoted && *q == CTLESC)
6032 if (pmatch(p, q, squoted))
6034 if (squoted && *q == CTLESC)
6036 } while (*q++ != '\0');
6047 while (*endp == CTLQUOTEMARK)
6050 goto dft; /* no matching ] */
6051 if (*endp == CTLESC)
6063 if (squoted && chr == CTLESC)
6069 if (c == CTLQUOTEMARK)
6073 if (*p == '-' && p[1] != ']') {
6075 while (*p == CTLQUOTEMARK)
6079 if (chr >= c && chr <= *p)
6086 } while ((c = *p++) != ']');
6087 if (found == invert)
6092 if (squoted && *q == CTLESC)
6109 * Remove any CTLESC characters from a string.
6112 #if defined(__GLIBC__) && !defined(FNMATCH_BROKEN)
6114 _rmescapes(char *str, int flag)
6117 static const char qchars[] = { CTLESC, CTLQUOTEMARK, 0 };
6119 p = strpbrk(str, qchars);
6125 if (flag & RMESCAPE_ALLOC) {
6126 size_t len = p - str;
6127 q = r = stalloc(strlen(p) + len + 1);
6130 q = mempcpy(q, str, len);
6132 memcpy(q, str, len);
6138 if (*p == CTLQUOTEMARK) {
6144 if (flag & RMESCAPE_GLOB && *p != '/') {
6161 while (*p != CTLESC && *p != CTLQUOTEMARK) {
6167 if (*p == CTLQUOTEMARK) {
6182 * See if a pattern matches in a case statement.
6186 casematch(union node *pattern, const char *val)
6188 struct stackmark smark;
6192 setstackmark(&smark);
6193 argbackq = pattern->narg.backquote;
6194 STARTSTACKSTR(expdest);
6196 argstr(pattern->narg.text, EXP_TILDE | EXP_CASE);
6197 STPUTC('\0', expdest);
6198 p = grabstackstr(expdest);
6199 result = patmatch(p, (char *)val, 0);
6200 popstackmark(&smark);
6215 CHECKSTRSPACE(32, buf);
6216 len = sprintf(buf, "%d", num);
6221 * Editline and history functions (and glue).
6223 static int histcmd(argc, argv)
6227 error("not compiled with history support");
6232 static int whichprompt; /* 1 == PS1, 2 == PS2 */
6236 struct redirtab *next;
6240 static struct redirtab *redirlist;
6242 extern char **environ;
6247 * Initialization code.
6260 basepf.nextc = basepf.buf = basebuf;
6263 /* from output.c: */
6265 #ifdef USE_GLIBC_STDIO
6276 for (envp = environ ; *envp ; envp++) {
6277 if (strchr(*envp, '=')) {
6278 setvareq(*envp, VEXPORT|VTEXTFIXED);
6282 fmtstr(ppid, sizeof(ppid), "%d", (int) getppid());
6283 setvar("PPID", ppid, 0);
6290 * This routine is called when an error or an interrupt occurs in an
6291 * interactive shell and control is returned to the main command loop.
6295 /* 1 == check for aliases, 2 == also check for assignments */
6296 static int checkalias;
6311 if (exception != EXSHELLPROC)
6312 parselleft = parsenleft = 0; /* clear input buffer */
6316 /* from parser.c: */
6331 /* from output.c: */
6335 #ifdef USE_GLIBC_STDIO
6336 if (memout.stream != NULL)
6339 if (memout.buf != NULL) {
6349 * This file implements the input routines used by the parser.
6352 #ifdef BB_FEATURE_COMMAND_EDITING
6353 unsigned int shell_context;
6354 static const char * cmdedit_prompt;
6355 static inline void putprompt(const char *s) {
6359 static inline void putprompt(const char *s) {
6364 #define EOF_NLEFT -99 /* value of parsenleft when EOF pushed back */
6369 * Same as pgetc(), but ignores PEOA.
6379 } while (c == PEOA);
6383 static inline int pgetc2() { return pgetc_macro(); }
6387 * Read a line from the script.
6391 pfgets(char *line, int len)
6397 while (--nleft > 0) {
6416 char *buf = parsefile->buf;
6420 #ifdef BB_FEATURE_COMMAND_EDITING
6423 nr = read(parsefile->fd, buf, BUFSIZ - 1);
6426 cmdedit_read_input((char*)cmdedit_prompt, buf);
6428 } while (nr <=0 || shell_context);
6429 cmdedit_terminate();
6433 nr = read(parsefile->fd, buf, BUFSIZ - 1);
6439 if (parsefile->fd == 0 && errno == EWOULDBLOCK) {
6440 int flags = fcntl(0, F_GETFL, 0);
6441 if (flags >= 0 && flags & O_NONBLOCK) {
6442 flags &=~ O_NONBLOCK;
6443 if (fcntl(0, F_SETFL, flags) >= 0) {
6444 out2str("sh: turning off NDELAY mode\n");
6456 struct strpush *sp = parsefile->strpush;
6461 if (parsenextc[-1] == ' ' || parsenextc[-1] == '\t') {
6466 if (sp->string != sp->ap->val) {
6470 sp->ap->flag &= ~ALIASINUSE;
6471 if (sp->ap->flag & ALIASDEAD) {
6472 unalias(sp->ap->name);
6476 parsenextc = sp->prevstring;
6477 parsenleft = sp->prevnleft;
6478 /*dprintf("*** calling popstring: restoring to '%s'\n", parsenextc);*/
6479 parsefile->strpush = sp->prev;
6480 if (sp != &(parsefile->basestrpush))
6487 * Refill the input buffer and return the next input character:
6489 * 1) If a string was pushed back on the input, pop it;
6490 * 2) If an EOF was pushed back (parsenleft == EOF_NLEFT) or we are reading
6491 * from a string so we can't refill the buffer, return EOF.
6492 * 3) If the is more stuff in this buffer, use it else call read to fill it.
6493 * 4) Process input up to the next newline, deleting nul characters.
6503 while (parsefile->strpush) {
6505 if (parsenleft == -1 && parsefile->strpush->ap &&
6506 parsenextc[-1] != ' ' && parsenextc[-1] != '\t') {
6511 if (--parsenleft >= 0)
6512 return (*parsenextc++);
6514 if (parsenleft == EOF_NLEFT || parsefile->buf == NULL)
6522 if (parselleft <= 0) {
6523 if ((parselleft = preadfd()) <= 0) {
6524 parselleft = parsenleft = EOF_NLEFT;
6531 /* delete nul characters */
6532 for (more = 1; more;) {
6540 parsenleft = q - parsenextc;
6541 more = 0; /* Stop processing here */
6547 if (--parselleft <= 0 && more) {
6548 parsenleft = q - parsenextc - 1;
6559 out2str(parsenextc);
6567 return *parsenextc++;
6572 * Push a string back onto the input at this current parsefile level.
6573 * We handle aliases this way.
6576 pushstring(char *s, int len, void *ap)
6581 /*dprintf("*** calling pushstring: %s, %d\n", s, len);*/
6582 if (parsefile->strpush) {
6583 sp = ckmalloc(sizeof (struct strpush));
6584 sp->prev = parsefile->strpush;
6585 parsefile->strpush = sp;
6587 sp = parsefile->strpush = &(parsefile->basestrpush);
6588 sp->prevstring = parsenextc;
6589 sp->prevnleft = parsenleft;
6591 sp->ap = (struct alias *)ap;
6593 ((struct alias *)ap)->flag |= ALIASINUSE;
6606 * Like setinputfile, but takes input from a string.
6610 setinputstring(string)
6615 parsenextc = string;
6616 parsenleft = strlen(string);
6617 parsefile->buf = NULL;
6625 * To handle the "." command, a stack of input files is used. Pushfile
6626 * adds a new entry to the stack and popfile restores the previous level.
6631 struct parsefile *pf;
6633 parsefile->nleft = parsenleft;
6634 parsefile->lleft = parselleft;
6635 parsefile->nextc = parsenextc;
6636 parsefile->linno = plinno;
6637 pf = (struct parsefile *)ckmalloc(sizeof (struct parsefile));
6638 pf->prev = parsefile;
6641 pf->basestrpush.prev = NULL;
6646 static void restartjob (struct job *);
6648 static void freejob (struct job *);
6649 static struct job *getjob (const char *);
6650 static int dowait (int, struct job *);
6651 static int waitproc (int, int *);
6652 static void waitonint(int);
6656 * We keep track of whether or not fd0 has been redirected. This is for
6657 * background commands, where we want to redirect fd0 to /dev/null only
6658 * if it hasn't already been redirected.
6660 static int fd0_redirected = 0;
6662 /* Return true if fd 0 has already been redirected at least once. */
6664 fd0_redirected_p () {
6665 return fd0_redirected != 0;
6669 * We also keep track of where fileno2 goes.
6671 static int fileno2 = 2;
6673 static int openredirect (union node *);
6674 static void dupredirect (union node *, int, char[10 ]);
6675 static int openhere (union node *);
6676 static int noclobberopen (const char *);
6682 * Turn job control on and off.
6684 * Note: This code assumes that the third arg to ioctl is a character
6685 * pointer, which is true on Berkeley systems but not System V. Since
6686 * System V doesn't have job control yet, this isn't a problem now.
6691 static void setjobctl(int enable)
6693 #ifdef OLD_TTY_DRIVER
6697 if (enable == jobctl || rootshell == 0)
6700 do { /* while we are in the background */
6701 #ifdef OLD_TTY_DRIVER
6702 if (ioctl(fileno2, TIOCGPGRP, (char *)&initialpgrp) < 0) {
6704 initialpgrp = tcgetpgrp(fileno2);
6705 if (initialpgrp < 0) {
6707 out2str("sh: can't access tty; job cenabletrol turned off\n");
6711 if (initialpgrp == -1)
6712 initialpgrp = getpgrp();
6713 else if (initialpgrp != getpgrp()) {
6714 killpg(initialpgrp, SIGTTIN);
6718 #ifdef OLD_TTY_DRIVER
6719 if (ioctl(fileno2, TIOCGETD, (char *)&ldisc) < 0 || ldisc != NTTYDISC) {
6720 out2str("sh: need new tty driver to run job cenabletrol; job cenabletrol turned off\n");
6728 setpgid(0, rootpid);
6729 #ifdef OLD_TTY_DRIVER
6730 ioctl(fileno2, TIOCSPGRP, (char *)&rootpid);
6732 tcsetpgrp(fileno2, rootpid);
6734 } else { /* turning job cenabletrol off */
6735 setpgid(0, initialpgrp);
6736 #ifdef OLD_TTY_DRIVER
6737 ioctl(fileno2, TIOCSPGRP, (char *)&initialpgrp);
6739 tcsetpgrp(fileno2, initialpgrp);
6750 /* A translation list so we can be polite to our users. */
6751 static char *signal_names[NSIG + 2] = {
6837 "Usage: kill [-s sigspec | -signum | -sigspec] [pid | job]... or\n"
6838 "kill -l [exitstatus]"
6842 if (*argv[1] == '-') {
6843 signo = decode_signal(argv[1] + 1, 1);
6847 while ((c = nextopt("ls:")) != '\0')
6853 signo = decode_signal(optionarg, 1);
6856 "invalid signal number or name: %s",
6864 "nextopt returned character code 0%o", c);
6871 if (!list && signo < 0)
6874 if ((signo < 0 || !*argptr) ^ list) {
6881 for (i = 1; i < NSIG; i++) {
6882 out1fmt(snlfmt, signal_names[i] + 3);
6886 signo = atoi(*argptr);
6889 if (0 < signo && signo < NSIG)
6890 out1fmt(snlfmt, signal_names[signo] + 3);
6892 error("invalid signal number or exit status: %s",
6898 if (**argptr == '%') {
6899 jp = getjob(*argptr);
6900 if (jp->jobctl == 0)
6901 error("job %s not created under job control",
6903 pid = -jp->ps[0].pid;
6905 pid = atoi(*argptr);
6906 if (kill(pid, signo) != 0)
6907 error("%s: %m", *argptr);
6908 } while (*++argptr);
6922 jp = getjob(argv[1]);
6923 if (jp->jobctl == 0)
6924 error("job not created under job control");
6925 pgrp = jp->ps[0].pid;
6926 #ifdef OLD_TTY_DRIVER
6927 ioctl(fileno2, TIOCSPGRP, (char *)&pgrp);
6929 tcsetpgrp(fileno2, pgrp);
6933 status = waitforjob(jp);
6947 jp = getjob(*++argv);
6948 if (jp->jobctl == 0)
6949 error("job not created under job control");
6951 } while (--argc > 1);
6960 struct procstat *ps;
6963 if (jp->state == JOBDONE)
6966 killpg(jp->ps[0].pid, SIGCONT);
6967 for (ps = jp->ps, i = jp->nprocs ; --i >= 0 ; ps++) {
6968 if (WIFSTOPPED(ps->status)) {
6977 static void showjobs(int change);
6991 * Print a list of jobs. If "change" is nonzero, only print jobs whose
6992 * statuses have changed since the last call to showjobs.
6994 * If the shell is interrupted in the process of creating a job, the
6995 * result may be a job structure containing zero processes. Such structures
6996 * will be freed here.
7007 struct procstat *ps;
7011 TRACE(("showjobs(%d) called\n", change));
7012 while (dowait(0, (struct job *)NULL) > 0);
7013 for (jobno = 1, jp = jobtab ; jobno <= njobs ; jobno++, jp++) {
7016 if (jp->nprocs == 0) {
7020 if (change && ! jp->changed)
7022 procno = jp->nprocs;
7023 for (ps = jp->ps ; ; ps++) { /* for each process */
7025 fmtstr(s, 64, "[%d] %ld ", jobno,
7028 fmtstr(s, 64, " %ld ",
7033 if (ps->status == -1) {
7034 /* don't print anything */
7035 } else if (WIFEXITED(ps->status)) {
7036 fmtstr(s, 64, "Exit %d",
7037 WEXITSTATUS(ps->status));
7040 if (WIFSTOPPED(ps->status))
7041 i = WSTOPSIG(ps->status);
7042 else /* WIFSIGNALED(ps->status) */
7044 i = WTERMSIG(ps->status);
7045 if ((i & 0x7F) < NSIG && sys_siglist[i & 0x7F])
7046 strcpy(s, sys_siglist[i & 0x7F]);
7048 fmtstr(s, 64, "Signal %d", i & 0x7F);
7049 if (WCOREDUMP(ps->status))
7050 strcat(s, " (core dumped)");
7055 "%*c%s\n", 30 - col >= 0 ? 30 - col : 0, ' ',
7062 if (jp->state == JOBDONE) {
7070 * Mark a job structure as unused.
7077 struct procstat *ps;
7081 for (i = jp->nprocs, ps = jp->ps ; --i >= 0 ; ps++) {
7082 if (ps->cmd != nullstr)
7085 if (jp->ps != &jp->ps0)
7089 if (curjob == jp - jobtab + 1)
7108 job = getjob(*++argv);
7112 for (;;) { /* loop until process terminated or stopped */
7115 status = job->ps[job->nprocs - 1].status;
7121 if (WIFEXITED(status))
7122 retval = WEXITSTATUS(status);
7124 else if (WIFSTOPPED(status))
7125 retval = WSTOPSIG(status) + 128;
7128 /* XXX: limits number of signals */
7129 retval = WTERMSIG(status) + 128;
7134 for (jp = jobtab ; ; jp++) {
7135 if (jp >= jobtab + njobs) { /* no running procs */
7138 if (jp->used && jp->state == 0)
7142 if (dowait(2, 0) < 0 && errno == EINTR) {
7151 * Convert a job name to a job structure.
7155 getjob(const char *name)
7165 if ((jobno = curjob) == 0 || jobtab[jobno - 1].used == 0)
7166 error("No current job");
7167 return &jobtab[jobno - 1];
7169 error("No current job");
7171 } else if (name[0] == '%') {
7172 if (is_digit(name[1])) {
7173 jobno = number(name + 1);
7174 if (jobno > 0 && jobno <= njobs
7175 && jobtab[jobno - 1].used != 0)
7176 return &jobtab[jobno - 1];
7178 } else if (name[1] == '%' && name[2] == '\0') {
7182 struct job *found = NULL;
7183 for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) {
7184 if (jp->used && jp->nprocs > 0
7185 && prefix(name + 1, jp->ps[0].cmd)) {
7187 error("%s: ambiguous", name);
7194 } else if (is_number(name, &pid)) {
7195 for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) {
7196 if (jp->used && jp->nprocs > 0
7197 && jp->ps[jp->nprocs - 1].pid == pid)
7201 error("No such job: %s", name);
7208 * Return a new job structure,
7212 makejob(node, nprocs)
7219 for (i = njobs, jp = jobtab ; ; jp++) {
7223 jobtab = ckmalloc(4 * sizeof jobtab[0]);
7225 jp = ckmalloc((njobs + 4) * sizeof jobtab[0]);
7226 memcpy(jp, jobtab, njobs * sizeof jp[0]);
7227 /* Relocate `ps' pointers */
7228 for (i = 0; i < njobs; i++)
7229 if (jp[i].ps == &jobtab[i].ps0)
7230 jp[i].ps = &jp[i].ps0;
7234 jp = jobtab + njobs;
7235 for (i = 4 ; --i >= 0 ; jobtab[njobs++].used = 0);
7248 jp->jobctl = jobctl;
7251 jp->ps = ckmalloc(nprocs * sizeof (struct procstat));
7256 TRACE(("makejob(0x%lx, %d) returns %%%d\n", (long)node, nprocs,
7263 * Fork of a subshell. If we are doing job control, give the subshell its
7264 * own process group. Jp is a job structure that the job is to be added to.
7265 * N is the command that will be evaluated by the child. Both jp and n may
7266 * be NULL. The mode parameter can be one of the following:
7267 * FORK_FG - Fork off a foreground process.
7268 * FORK_BG - Fork off a background process.
7269 * FORK_NOJOB - Like FORK_FG, but don't give the process its own
7270 * process group even if job control is on.
7272 * When job control is turned off, background processes have their standard
7273 * input redirected to /dev/null (except for the second and later processes
7280 forkshell(struct job *jp, union node *n, int mode)
7284 const char *devnull = _PATH_DEVNULL;
7285 const char *nullerr = "Can't open %s";
7287 TRACE(("forkshell(%%%d, 0x%lx, %d) called\n", jp - jobtab, (long)n,
7292 TRACE(("Fork failed, errno=%d\n", errno));
7294 error("Cannot fork");
7301 TRACE(("Child shell %d\n", getpid()));
7302 wasroot = rootshell;
7308 jobctl = 0; /* do job control only in root shell */
7309 if (wasroot && mode != FORK_NOJOB && mflag) {
7310 if (jp == NULL || jp->nprocs == 0)
7313 pgrp = jp->ps[0].pid;
7315 if (mode == FORK_FG) {
7316 /*** this causes superfluous TIOCSPGRPS ***/
7317 #ifdef OLD_TTY_DRIVER
7318 if (ioctl(fileno2, TIOCSPGRP, (char *)&pgrp) < 0)
7319 error("TIOCSPGRP failed, errno=%d", errno);
7321 if (tcsetpgrp(fileno2, pgrp) < 0)
7322 error("tcsetpgrp failed, errno=%d", errno);
7327 } else if (mode == FORK_BG) {
7330 if ((jp == NULL || jp->nprocs == 0) &&
7331 ! fd0_redirected_p ()) {
7333 if (open(devnull, O_RDONLY) != 0)
7334 error(nullerr, devnull);
7338 if (mode == FORK_BG) {
7341 if ((jp == NULL || jp->nprocs == 0) &&
7342 ! fd0_redirected_p ()) {
7344 if (open(devnull, O_RDONLY) != 0)
7345 error(nullerr, devnull);
7349 for (i = njobs, p = jobtab ; --i >= 0 ; p++)
7352 if (wasroot && iflag) {
7359 if (rootshell && mode != FORK_NOJOB && mflag) {
7360 if (jp == NULL || jp->nprocs == 0)
7363 pgrp = jp->ps[0].pid;
7366 if (mode == FORK_BG)
7367 backgndpid = pid; /* set $! */
7369 struct procstat *ps = &jp->ps[jp->nprocs++];
7373 if (iflag && rootshell && n)
7374 ps->cmd = commandtext(n);
7377 TRACE(("In parent shell: child = %d\n", pid));
7384 * Wait for job to finish.
7386 * Under job control we have the problem that while a child process is
7387 * running interrupts generated by the user are sent to the child but not
7388 * to the shell. This means that an infinite loop started by an inter-
7389 * active user may be hard to kill. With job control turned off, an
7390 * interactive user may place an interactive program inside a loop. If
7391 * the interactive program catches interrupts, the user doesn't want
7392 * these interrupts to also abort the loop. The approach we take here
7393 * is to have the shell ignore interrupt signals while waiting for a
7394 * forground process to terminate, and then send itself an interrupt
7395 * signal if the child process was terminated by an interrupt signal.
7396 * Unfortunately, some programs want to do a bit of cleanup and then
7397 * exit on interrupt; unless these processes terminate themselves by
7398 * sending a signal to themselves (instead of calling exit) they will
7399 * confuse this approach.
7407 int mypgrp = getpgrp();
7411 struct sigaction act, oact;
7420 sigaction(SIGINT, 0, &act);
7421 act.sa_handler = waitonint;
7422 sigaction(SIGINT, &act, &oact);
7424 TRACE(("waitforjob(%%%d) called\n", jp - jobtab + 1));
7425 while (jp->state == 0) {
7433 sigaction(SIGINT, &oact, 0);
7434 if (intreceived && trap[SIGINT]) kill(getpid(), SIGINT);
7438 #ifdef OLD_TTY_DRIVER
7439 if (ioctl(fileno2, TIOCSPGRP, (char *)&mypgrp) < 0)
7440 error("TIOCSPGRP failed, errno=%d\n", errno);
7442 if (tcsetpgrp(fileno2, mypgrp) < 0)
7443 error("tcsetpgrp failed, errno=%d\n", errno);
7446 if (jp->state == JOBSTOPPED)
7447 curjob = jp - jobtab + 1;
7449 status = jp->ps[jp->nprocs - 1].status;
7450 /* convert to 8 bits */
7451 if (WIFEXITED(status))
7452 st = WEXITSTATUS(status);
7454 else if (WIFSTOPPED(status))
7455 st = WSTOPSIG(status) + 128;
7458 st = WTERMSIG(status) + 128;
7462 * This is truly gross.
7463 * If we're doing job control, then we did a TIOCSPGRP which
7464 * caused us (the shell) to no longer be in the controlling
7465 * session -- so we wouldn't have seen any ^C/SIGINT. So, we
7466 * intuit from the subprocess exit status whether a SIGINT
7467 * occured, and if so interrupt ourselves. Yuck. - mycroft
7469 if (WIFSIGNALED(status) && WTERMSIG(status) == SIGINT)
7472 if (jp->state == JOBDONE)
7483 * Wait for a process to terminate.
7493 struct procstat *sp;
7495 struct job *thisjob;
7501 TRACE(("dowait(%d) called\n", block));
7503 pid = waitproc(block, &status);
7504 TRACE(("wait returns %d, status=%d\n", pid, status));
7505 } while (!(block & 2) && pid == -1 && errno == EINTR);
7510 for (jp = jobtab ; jp < jobtab + njobs ; jp++) {
7514 for (sp = jp->ps ; sp < jp->ps + jp->nprocs ; sp++) {
7517 if (sp->pid == pid) {
7518 TRACE(("Changing status of proc %d from 0x%x to 0x%x\n", pid, sp->status, status));
7519 sp->status = status;
7522 if (sp->status == -1)
7524 else if (WIFSTOPPED(sp->status))
7527 if (stopped) { /* stopped or done */
7528 int state = done? JOBDONE : JOBSTOPPED;
7529 if (jp->state != state) {
7530 TRACE(("Job %d: changing state from %d to %d\n", jp - jobtab + 1, jp->state, state));
7533 if (done && curjob == jp - jobtab + 1)
7534 curjob = 0; /* no current job */
7541 if (! rootshell || ! iflag || (job && thisjob == job)) {
7542 core = WCOREDUMP(status);
7544 if (WIFSTOPPED(status)) sig = WSTOPSIG(status);
7547 if (WIFEXITED(status)) sig = 0;
7548 else sig = WTERMSIG(status);
7550 if (sig != 0 && sig != SIGINT && sig != SIGPIPE) {
7552 outfmt(out2, "%d: ", pid);
7554 if (sig == SIGTSTP && rootshell && iflag)
7555 outfmt(out2, "%%%ld ",
7556 (long)(job - jobtab + 1));
7558 if (sig < NSIG && sys_siglist[sig])
7559 out2str(sys_siglist[sig]);
7561 outfmt(out2, "Signal %d", sig);
7563 out2str(" - core dumped");
7569 TRACE(("Not printing status: status=%d, sig=%d\n",
7573 TRACE(("Not printing status, rootshell=%d, job=0x%x\n", rootshell, job));
7575 thisjob->changed = 1;
7583 * Do a wait system call. If job control is compiled in, we accept
7584 * stopped processes. If block is zero, we return a value of zero
7585 * rather than blocking.
7587 * System V doesn't have a non-blocking wait system call. It does
7588 * have a SIGCLD signal that is sent to a process when one of it's
7589 * children dies. The obvious way to use SIGCLD would be to install
7590 * a handler for SIGCLD which simply bumped a counter when a SIGCLD
7591 * was received, and have waitproc bump another counter when it got
7592 * the status of a process. Waitproc would then know that a wait
7593 * system call would not block if the two counters were different.
7594 * This approach doesn't work because if a process has children that
7595 * have not been waited for, System V will send it a SIGCLD when it
7596 * installs a signal handler for SIGCLD. What this means is that when
7597 * a child exits, the shell will be sent SIGCLD signals continuously
7598 * until is runs out of stack space, unless it does a wait call before
7599 * restoring the signal handler. The code below takes advantage of
7600 * this (mis)feature by installing a signal handler for SIGCLD and
7601 * then checking to see whether it was called. If there are any
7602 * children to be waited for, it will be.
7607 waitproc(block, status)
7620 return wait3(status, flags, (struct rusage *)NULL);
7624 * return 1 if there are stopped jobs, otherwise 0
7634 for (jobno = 1, jp = jobtab; jobno <= njobs; jobno++, jp++) {
7637 if (jp->state == JOBSTOPPED) {
7638 out2str("You have stopped jobs.\n");
7648 * Return a string identifying a command (to be printed by the
7652 static char *cmdnextc;
7653 static int cmdnleft;
7654 #define MAXCMDTEXT 200
7657 cmdputs(const char *s)
7668 while ((c = *p++) != '\0') {
7671 else if (c == CTLVAR) {
7676 } else if (c == '=' && subtype != 0) {
7677 *q++ = "}-+?="[(subtype & VSTYPE) - VSNORMAL];
7679 } else if (c == CTLENDVAR) {
7681 } else if (c == CTLBACKQ || c == CTLBACKQ+CTLQUOTE)
7682 cmdnleft++; /* ignore it */
7685 if (--cmdnleft <= 0) {
7697 cmdtxt(const union node *n)
7700 struct nodelist *lp;
7709 cmdtxt(n->nbinary.ch1);
7711 cmdtxt(n->nbinary.ch2);
7714 cmdtxt(n->nbinary.ch1);
7716 cmdtxt(n->nbinary.ch2);
7719 cmdtxt(n->nbinary.ch1);
7721 cmdtxt(n->nbinary.ch2);
7724 for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
7732 cmdtxt(n->nredir.n);
7737 cmdtxt(n->nredir.n);
7741 cmdtxt(n->nif.test);
7743 cmdtxt(n->nif.ifpart);
7752 cmdtxt(n->nbinary.ch1);
7754 cmdtxt(n->nbinary.ch2);
7759 cmdputs(n->nfor.var);
7764 cmdputs(n->ncase.expr->narg.text);
7768 cmdputs(n->narg.text);
7772 for (np = n->ncmd.args ; np ; np = np->narg.next) {
7777 for (np = n->ncmd.redirect ; np ; np = np->nfile.next) {
7783 cmdputs(n->narg.text);
7786 p = ">"; i = 1; goto redir;
7788 p = ">>"; i = 1; goto redir;
7790 p = ">&"; i = 1; goto redir;
7792 p = ">|"; i = 1; goto redir;
7794 p = "<"; i = 0; goto redir;
7796 p = "<&"; i = 0; goto redir;
7798 p = "<>"; i = 0; goto redir;
7800 if (n->nfile.fd != i) {
7801 s[0] = n->nfile.fd + '0';
7806 if (n->type == NTOFD || n->type == NFROMFD) {
7807 s[0] = n->ndup.dupfd + '0';
7811 cmdtxt(n->nfile.fname);
7826 commandtext(const union node *n)
7830 cmdnextc = name = ckmalloc(MAXCMDTEXT);
7831 cmdnleft = MAXCMDTEXT - 4;
7838 static void waitonint(int sig) {
7843 * Routines to check for mail. (Perhaps make part of main.c?)
7847 #define MAXMBOXES 10
7850 static int nmboxes; /* number of mailboxes */
7851 static time_t mailtime[MAXMBOXES]; /* times of mailboxes */
7856 * Print appropriate message(s) if mail has arrived. If the argument is
7857 * nozero, then the value of MAIL has changed, so we just update the
7868 struct stackmark smark;
7875 setstackmark(&smark);
7876 mpath = mpathset()? mpathval() : mailval();
7877 for (i = 0 ; i < nmboxes ; i++) {
7878 p = padvance(&mpath, nullstr);
7883 for (q = p ; *q ; q++);
7888 q[-1] = '\0'; /* delete trailing '/' */
7889 if (stat(p, &statb) < 0)
7891 if (statb.st_size > mailtime[i] && ! silent) {
7894 pathopt? pathopt : "you have mail"
7897 mailtime[i] = statb.st_size;
7900 popstackmark(&smark);
7906 static short profile_buf[16384];
7910 static void read_profile (const char *);
7911 static char *find_dot_file (char *);
7912 static void cmdloop (int);
7913 static void options (int);
7914 static void minus_o (char *, int);
7915 static void setoption (int, int);
7916 static void procargs (int, char **);
7920 * Main routine. We initialize things, parse the arguments, execute
7921 * profiles if we're a login shell, and then call cmdloop to execute
7922 * commands. The setjmp call sets up the location to jump to when an
7923 * exception occurs. When an exception occurs the variable "state"
7924 * is used to figure out how far we had gotten.
7928 shell_main(argc, argv)
7932 struct jmploc jmploc;
7933 struct stackmark smark;
7937 DOTCMD = find_builtin(".");
7938 BLTINCMD = find_builtin("builtin");
7939 EXECCMD = find_builtin("exec");
7940 EVALCMD = find_builtin("eval");
7943 monitor(4, etext, profile_buf, sizeof profile_buf, 50);
7945 #if defined(linux) || defined(__GNU__)
7946 signal(SIGCHLD, SIG_DFL);
7949 if (setjmp(jmploc.loc)) {
7952 * When a shell procedure is executed, we raise the
7953 * exception EXSHELLPROC to clean up before executing
7954 * the shell procedure.
7956 switch (exception) {
7965 exitstatus = exerrno;
7976 if (exception != EXSHELLPROC) {
7977 if (state == 0 || iflag == 0 || ! rootshell)
7978 exitshell(exitstatus);
7981 if (exception == EXINT) {
7987 popstackmark(&smark);
7988 FORCEINTON; /* enable interrupts */
7991 else if (state == 2)
7993 else if (state == 3)
8001 trputs("Shell args: "); trargs(argv);
8006 setstackmark(&smark);
8007 procargs(argc, argv);
8008 if (argv[0] && argv[0][0] == '-') {
8010 read_profile("/etc/profile");
8013 read_profile(".profile");
8018 if (getuid() == geteuid() && getgid() == getegid()) {
8020 if ((shinit = lookupvar("ENV")) != NULL && *shinit != '\0') {
8022 read_profile(shinit);
8029 if (sflag == 0 || minusc) {
8030 static int sigs[] = {
8031 SIGINT, SIGQUIT, SIGHUP,
8037 #define SIGSSIZE (sizeof(sigs)/sizeof(sigs[0]))
8040 for (i = 0; i < SIGSSIZE; i++)
8045 evalstring(minusc, 0);
8047 if (sflag || minusc == NULL) {
8048 state4: /* XXX ??? - why isn't this before the "if" statement */
8054 exitshell(exitstatus);
8060 * Read and execute commands. "Top" is nonzero for the top level command
8061 * loop; it turns on prompting if the shell is interactive.
8068 struct stackmark smark;
8072 TRACE(("cmdloop(%d) called\n", top));
8073 setstackmark(&smark);
8084 n = parsecmd(inter);
8085 /* showtree(n); DEBUG */
8087 if (!top || numeof >= 50)
8089 if (!stoppedjobs()) {
8092 out2str("\nUse \"exit\" to leave shell.\n");
8095 } else if (n != NULL && nflag == 0) {
8096 job_warning = (job_warning == 2) ? 1 : 0;
8100 popstackmark(&smark);
8101 setstackmark(&smark);
8102 if (evalskip == SKIPFILE) {
8107 popstackmark(&smark);
8113 * Read /etc/profile or .profile. Return on error.
8125 if ((fd = open(name, O_RDONLY)) >= 0)
8130 /* -q turns off -x and -v just when executing init files */
8133 xflag = 0, xflag_set = 1;
8135 vflag = 0, vflag_set = 1;
8150 * Read a file containing shell functions.
8154 readcmdfile(const char *name)
8159 if ((fd = open(name, O_RDONLY)) >= 0)
8162 error("Can't open %s", name);
8171 * Take commands from a file. To be compatable we should do a path
8172 * search for the file, which is necessary to find sub-commands.
8177 find_dot_file(mybasename)
8181 const char *path = pathval();
8184 /* don't try this for absolute or relative paths */
8185 if (strchr(mybasename, '/'))
8188 while ((fullname = padvance(&path, mybasename)) != NULL) {
8189 if ((stat(fullname, &statb) == 0) && S_ISREG(statb.st_mode)) {
8191 * Don't bother freeing here, since it will
8192 * be freed by the caller.
8196 stunalloc(fullname);
8199 /* not found in the PATH */
8200 error("%s: not found", mybasename);
8212 for (sp = cmdenviron; sp ; sp = sp->next)
8213 setvareq(savestr(sp->text), VSTRFIXED|VTEXTFIXED);
8215 if (argc >= 2) { /* That's what SVR2 does */
8217 struct stackmark smark;
8219 setstackmark(&smark);
8220 fullname = find_dot_file(argv[1]);
8221 setinputfile(fullname, 1);
8222 commandname = fullname;
8225 popstackmark(&smark);
8239 exitstatus = number(argv[1]);
8241 exitstatus = oexitstatus;
8242 exitshell(exitstatus);
8250 nbytes = ALIGN(nbytes);
8251 if (nbytes > stacknleft) {
8253 struct stack_block *sp;
8256 if (blocksize < MINSIZE)
8257 blocksize = MINSIZE;
8259 sp = ckmalloc(sizeof(struct stack_block) - MINSIZE + blocksize);
8261 stacknxt = sp->space;
8262 stacknleft = blocksize;
8268 stacknleft -= nbytes;
8274 stunalloc(pointer p)
8277 if (p == NULL) { /*DEBUG */
8278 write(2, "stunalloc\n", 10);
8282 if (!(stacknxt >= (char *)p && (char *)p >= stackp->space)) {
8285 stacknleft += stacknxt - (char *)p;
8291 setstackmark(struct stackmark *mark)
8293 mark->stackp = stackp;
8294 mark->stacknxt = stacknxt;
8295 mark->stacknleft = stacknleft;
8296 mark->marknext = markp;
8302 popstackmark(struct stackmark *mark)
8304 struct stack_block *sp;
8307 markp = mark->marknext;
8308 while (stackp != mark->stackp) {
8313 stacknxt = mark->stacknxt;
8314 stacknleft = mark->stacknleft;
8320 * When the parser reads in a string, it wants to stick the string on the
8321 * stack and only adjust the stack pointer when it knows how big the
8322 * string is. Stackblock (defined in stack.h) returns a pointer to a block
8323 * of space on top of the stack and stackblocklen returns the length of
8324 * this block. Growstackblock will grow this space by at least one byte,
8325 * possibly moving it (like realloc). Grabstackblock actually allocates the
8326 * part of the block that has been used.
8330 growstackblock(void) {
8332 int newlen = ALIGN(stacknleft * 2 + 100);
8333 char *oldspace = stacknxt;
8334 int oldlen = stacknleft;
8335 struct stack_block *sp;
8336 struct stack_block *oldstackp;
8338 if (stacknxt == stackp->space && stackp != &stackbase) {
8343 sp = ckrealloc((pointer)sp, sizeof(struct stack_block) - MINSIZE + newlen);
8346 stacknxt = sp->space;
8347 stacknleft = newlen;
8349 /* Stack marks pointing to the start of the old block
8350 * must be relocated to point to the new block
8352 struct stackmark *xmark;
8354 while (xmark != NULL && xmark->stackp == oldstackp) {
8355 xmark->stackp = stackp;
8356 xmark->stacknxt = stacknxt;
8357 xmark->stacknleft = stacknleft;
8358 xmark = xmark->marknext;
8363 p = stalloc(newlen);
8364 memcpy(p, oldspace, oldlen);
8365 stacknxt = p; /* free the space */
8366 stacknleft += newlen; /* we just allocated */
8373 grabstackblock(int len)
8383 * The following routines are somewhat easier to use that the above.
8384 * The user declares a variable of type STACKSTR, which may be declared
8385 * to be a register. The macro STARTSTACKSTR initializes things. Then
8386 * the user uses the macro STPUTC to add characters to the string. In
8387 * effect, STPUTC(c, p) is the same as *p++ = c except that the stack is
8388 * grown as necessary. When the user is done, she can just leave the
8389 * string there and refer to it using stackblock(). Or she can allocate
8390 * the space for it using grabstackstr(). If it is necessary to allow
8391 * someone else to use the stack temporarily and then continue to grow
8392 * the string, the user should use grabstack to allocate the space, and
8393 * then call ungrabstr(p) to return to the previous mode of operation.
8395 * USTPUTC is like STPUTC except that it doesn't check for overflow.
8396 * CHECKSTACKSPACE can be called before USTPUTC to ensure that there
8397 * is space for at least one character.
8402 growstackstr(void) {
8403 int len = stackblocksize();
8404 if (herefd >= 0 && len >= 1024) {
8405 xwrite(herefd, stackblock(), len);
8406 sstrnleft = len - 1;
8407 return stackblock();
8410 sstrnleft = stackblocksize() - len - 1;
8411 return stackblock() + len;
8416 * Called from CHECKSTRSPACE.
8420 makestrspace(size_t newlen) {
8421 int len = stackblocksize() - sstrnleft;
8424 sstrnleft = stackblocksize() - len;
8425 } while (sstrnleft < newlen);
8426 return stackblock() + len;
8432 ungrabstackstr(char *s, char *p)
8434 stacknleft += stacknxt - s;
8436 sstrnleft = stacknleft - (p - s);
8439 * Miscelaneous builtins.
8446 static mode_t getmode(const void *, mode_t);
8447 static void *setmode(const char *);
8449 #if !defined(__GLIBC__) || __GLIBC__ == 2 && __GLIBC_MINOR__ < 1
8450 typedef enum __rlimit_resource rlim_t;
8457 * The read builtin. The -e option causes backslashes to escape the
8458 * following character.
8460 * This uses unbuffered input, which may be avoidable in some cases.
8481 while ((i = nextopt("p:r")) != '\0') {
8487 if (prompt && isatty(0)) {
8491 if (*(ap = argptr) == NULL)
8493 if ((ifs = bltinlookup("IFS")) == NULL)
8500 if (read(0, &c, 1) != 1) {
8512 if (!rflag && c == '\\') {
8518 if (startword && *ifs == ' ' && strchr(ifs, c)) {
8522 if (backslash && c == '\\') {
8523 if (read(0, &c, 1) != 1) {
8528 } else if (ap[1] != NULL && strchr(ifs, c) != NULL) {
8530 setvar(*ap, stackblock(), 0);
8539 /* Remove trailing blanks */
8540 while (stackblock() <= --p && strchr(ifs, *p) != NULL)
8542 setvar(*ap, stackblock(), 0);
8543 while (*++ap != NULL)
8544 setvar(*ap, nullstr, 0);
8551 umaskcmd(argc, argv)
8558 int symbolic_mode = 0;
8560 while ((i = nextopt("S")) != '\0') {
8569 if ((ap = *argptr) == NULL) {
8570 if (symbolic_mode) {
8571 char u[4], g[4], o[4];
8574 if ((mask & S_IRUSR) == 0)
8576 if ((mask & S_IWUSR) == 0)
8578 if ((mask & S_IXUSR) == 0)
8583 if ((mask & S_IRGRP) == 0)
8585 if ((mask & S_IWGRP) == 0)
8587 if ((mask & S_IXGRP) == 0)
8592 if ((mask & S_IROTH) == 0)
8594 if ((mask & S_IWOTH) == 0)
8596 if ((mask & S_IXOTH) == 0)
8600 out1fmt("u=%s,g=%s,o=%s\n", u, g, o);
8602 out1fmt("%.4o\n", mask);
8605 if (isdigit((unsigned char)*ap)) {
8608 if (*ap >= '8' || *ap < '0')
8609 error("Illegal number: %s", argv[1]);
8610 mask = (mask << 3) + (*ap - '0');
8611 } while (*++ap != '\0');
8617 if ((set = setmode(ap)) != 0) {
8618 mask = getmode(set, ~mask & 0777);
8623 error("Illegal mode: %s", ap);
8625 umask(~mask & 0777);
8634 * This code, originally by Doug Gwyn, Doug Kingston, Eric Gisin, and
8635 * Michael Rendell was ripped from pdksh 5.0.8 and hacked for use with
8636 * ash by J.T. Conklin.
8644 int factor; /* multiply by to get rlim_{cur,max} values */
8648 static const struct limits limits[] = {
8650 { "time(seconds)", RLIMIT_CPU, 1, 't' },
8653 { "file(blocks)", RLIMIT_FSIZE, 512, 'f' },
8656 { "data(kbytes)", RLIMIT_DATA, 1024, 'd' },
8659 { "stack(kbytes)", RLIMIT_STACK, 1024, 's' },
8662 { "coredump(blocks)", RLIMIT_CORE, 512, 'c' },
8665 { "memory(kbytes)", RLIMIT_RSS, 1024, 'm' },
8667 #ifdef RLIMIT_MEMLOCK
8668 { "locked memory(kbytes)", RLIMIT_MEMLOCK, 1024, 'l' },
8671 { "process(processes)", RLIMIT_NPROC, 1, 'p' },
8673 #ifdef RLIMIT_NOFILE
8674 { "nofiles(descriptors)", RLIMIT_NOFILE, 1, 'n' },
8677 { "vmemory(kbytes)", RLIMIT_VMEM, 1024, 'v' },
8680 { "swap(kbytes)", RLIMIT_SWAP, 1024, 'w' },
8682 { (char *) 0, 0, 0, '\0' }
8686 ulimitcmd(argc, argv)
8692 enum { SOFT = 0x1, HARD = 0x2 }
8694 const struct limits *l;
8697 struct rlimit limit;
8700 while ((optc = nextopt("HSatfdsmcnpl")) != '\0')
8715 for (l = limits; l->name && l->option != what; l++)
8718 error("internal error (%c)", what);
8720 set = *argptr ? 1 : 0;
8724 if (all || argptr[1])
8725 error("too many arguments");
8726 if (strcmp(p, "unlimited") == 0)
8727 val = RLIM_INFINITY;
8731 while ((c = *p++) >= '0' && c <= '9')
8733 val = (val * 10) + (long)(c - '0');
8734 if (val < (rlim_t) 0)
8738 error("bad number");
8743 for (l = limits; l->name; l++) {
8744 getrlimit(l->cmd, &limit);
8746 val = limit.rlim_cur;
8747 else if (how & HARD)
8748 val = limit.rlim_max;
8750 out1fmt("%-20s ", l->name);
8751 if (val == RLIM_INFINITY)
8752 out1fmt("unlimited\n");
8756 out1fmt("%lld\n", (long long) val);
8762 getrlimit(l->cmd, &limit);
8765 limit.rlim_max = val;
8767 limit.rlim_cur = val;
8768 if (setrlimit(l->cmd, &limit) < 0)
8769 error("error setting limit (%m)");
8772 val = limit.rlim_cur;
8773 else if (how & HARD)
8774 val = limit.rlim_max;
8776 if (val == RLIM_INFINITY)
8777 out1fmt("unlimited\n");
8781 out1fmt("%lld\n", (long long) val);
8787 * prefix -- see if pfx is a prefix of string.
8796 if (*pfx++ != *string++)
8803 * Return true if s is a string of digits, and save munber in intptr
8808 is_number(const char *p, int *intptr)
8816 ret += digit_val(*p);
8818 } while (*p != '\0');
8825 * Convert a string of digits to an integer, printing an error message on
8830 number(const char *s)
8833 if (! is_number(s, &i))
8834 error("Illegal number: %s", s);
8839 * Produce a possibly single quoted string suitable as input to the shell.
8840 * The return string is allocated on the stack.
8844 single_quote(const char *s) {
8851 size_t len1, len1p, len2, len2p;
8853 len1 = strcspn(s, "'");
8854 len2 = strspn(s + len1, "'");
8856 len1p = len1 ? len1 + 2 : len1;
8868 CHECKSTRSPACE(len1p + len2p + 1, p);
8873 q = mempcpy(p + 1, s, len1);
8876 memcpy(p + 1, s, len1);
8893 *(char *) mempcpy(q + 1, s, len2) = '"';
8896 memcpy(q + 1, s, len2);
8902 STADJUST(len1p + len2p, p);
8907 return grabstackstr(p);
8911 * Like strdup but works with the ash stack.
8915 sstrdup(const char *p)
8917 size_t len = strlen(p) + 1;
8918 return memcpy(stalloc(len), p, len);
8923 * This file was generated by the mknodes program.
8927 * Routine for dealing with parsed shell commands.
8931 static int funcblocksize; /* size of structures in function */
8932 static int funcstringsize; /* size of strings in node */
8933 static pointer funcblock; /* block to allocate function from */
8934 static char *funcstring; /* block to allocate strings from */
8936 static const short nodesize[26] = {
8937 ALIGN(sizeof (struct nbinary)),
8938 ALIGN(sizeof (struct ncmd)),
8939 ALIGN(sizeof (struct npipe)),
8940 ALIGN(sizeof (struct nredir)),
8941 ALIGN(sizeof (struct nredir)),
8942 ALIGN(sizeof (struct nredir)),
8943 ALIGN(sizeof (struct nbinary)),
8944 ALIGN(sizeof (struct nbinary)),
8945 ALIGN(sizeof (struct nif)),
8946 ALIGN(sizeof (struct nbinary)),
8947 ALIGN(sizeof (struct nbinary)),
8948 ALIGN(sizeof (struct nfor)),
8949 ALIGN(sizeof (struct ncase)),
8950 ALIGN(sizeof (struct nclist)),
8951 ALIGN(sizeof (struct narg)),
8952 ALIGN(sizeof (struct narg)),
8953 ALIGN(sizeof (struct nfile)),
8954 ALIGN(sizeof (struct nfile)),
8955 ALIGN(sizeof (struct nfile)),
8956 ALIGN(sizeof (struct nfile)),
8957 ALIGN(sizeof (struct nfile)),
8958 ALIGN(sizeof (struct ndup)),
8959 ALIGN(sizeof (struct ndup)),
8960 ALIGN(sizeof (struct nhere)),
8961 ALIGN(sizeof (struct nhere)),
8962 ALIGN(sizeof (struct nnot)),
8966 static void calcsize (union node *);
8967 static void sizenodelist (struct nodelist *);
8968 static union node *copynode (union node *);
8969 static struct nodelist *copynodelist (struct nodelist *);
8970 static char *nodesavestr (char *);
8975 * Make a copy of a parse tree.
8979 copyfunc(union node *n)
8986 funcblock = ckmalloc(funcblocksize + funcstringsize);
8987 funcstring = (char *) funcblock + funcblocksize;
8999 funcblocksize += nodesize[n->type];
9006 calcsize(n->nbinary.ch2);
9007 calcsize(n->nbinary.ch1);
9010 calcsize(n->ncmd.redirect);
9011 calcsize(n->ncmd.args);
9012 calcsize(n->ncmd.assign);
9015 sizenodelist(n->npipe.cmdlist);
9020 calcsize(n->nredir.redirect);
9021 calcsize(n->nredir.n);
9024 calcsize(n->nif.elsepart);
9025 calcsize(n->nif.ifpart);
9026 calcsize(n->nif.test);
9029 funcstringsize += strlen(n->nfor.var) + 1;
9030 calcsize(n->nfor.body);
9031 calcsize(n->nfor.args);
9034 calcsize(n->ncase.cases);
9035 calcsize(n->ncase.expr);
9038 calcsize(n->nclist.body);
9039 calcsize(n->nclist.pattern);
9040 calcsize(n->nclist.next);
9044 sizenodelist(n->narg.backquote);
9045 funcstringsize += strlen(n->narg.text) + 1;
9046 calcsize(n->narg.next);
9053 calcsize(n->nfile.fname);
9054 calcsize(n->nfile.next);
9058 calcsize(n->ndup.vname);
9059 calcsize(n->ndup.next);
9063 calcsize(n->nhere.doc);
9064 calcsize(n->nhere.next);
9067 calcsize(n->nnot.com);
9076 struct nodelist *lp;
9079 funcblocksize += ALIGN(sizeof(struct nodelist));
9096 funcblock = (char *) funcblock + nodesize[n->type];
9103 new->nbinary.ch2 = copynode(n->nbinary.ch2);
9104 new->nbinary.ch1 = copynode(n->nbinary.ch1);
9107 new->ncmd.redirect = copynode(n->ncmd.redirect);
9108 new->ncmd.args = copynode(n->ncmd.args);
9109 new->ncmd.assign = copynode(n->ncmd.assign);
9110 new->ncmd.backgnd = n->ncmd.backgnd;
9113 new->npipe.cmdlist = copynodelist(n->npipe.cmdlist);
9114 new->npipe.backgnd = n->npipe.backgnd;
9119 new->nredir.redirect = copynode(n->nredir.redirect);
9120 new->nredir.n = copynode(n->nredir.n);
9123 new->nif.elsepart = copynode(n->nif.elsepart);
9124 new->nif.ifpart = copynode(n->nif.ifpart);
9125 new->nif.test = copynode(n->nif.test);
9128 new->nfor.var = nodesavestr(n->nfor.var);
9129 new->nfor.body = copynode(n->nfor.body);
9130 new->nfor.args = copynode(n->nfor.args);
9133 new->ncase.cases = copynode(n->ncase.cases);
9134 new->ncase.expr = copynode(n->ncase.expr);
9137 new->nclist.body = copynode(n->nclist.body);
9138 new->nclist.pattern = copynode(n->nclist.pattern);
9139 new->nclist.next = copynode(n->nclist.next);
9143 new->narg.backquote = copynodelist(n->narg.backquote);
9144 new->narg.text = nodesavestr(n->narg.text);
9145 new->narg.next = copynode(n->narg.next);
9152 new->nfile.fname = copynode(n->nfile.fname);
9153 new->nfile.fd = n->nfile.fd;
9154 new->nfile.next = copynode(n->nfile.next);
9158 new->ndup.vname = copynode(n->ndup.vname);
9159 new->ndup.dupfd = n->ndup.dupfd;
9160 new->ndup.fd = n->ndup.fd;
9161 new->ndup.next = copynode(n->ndup.next);
9165 new->nhere.doc = copynode(n->nhere.doc);
9166 new->nhere.fd = n->nhere.fd;
9167 new->nhere.next = copynode(n->nhere.next);
9170 new->nnot.com = copynode(n->nnot.com);
9173 new->type = n->type;
9178 static struct nodelist *
9180 struct nodelist *lp;
9182 struct nodelist *start;
9183 struct nodelist **lpp;
9188 funcblock = (char *) funcblock + ALIGN(sizeof(struct nodelist));
9189 (*lpp)->n = copynode(lp->n);
9191 lpp = &(*lpp)->next;
9204 char *rtn = funcstring;
9206 funcstring = stpcpy(funcstring, s) + 1;
9209 register char *p = s;
9210 register char *q = funcstring;
9211 char *rtn = funcstring;
9213 while ((*q++ = *p++) != '\0')
9221 static int getopts (char *, char *, char **, int *, int *);
9226 * Process the shell command line arguments.
9230 procargs(argc, argv)
9239 for (i = 0; i < NOPTS; i++)
9242 if (*argptr == NULL && minusc == NULL)
9244 if (iflag == 2 && sflag == 1 && isatty(0) && isatty(1))
9248 for (i = 0; i < NOPTS; i++)
9249 if (optent_val(i) == 2)
9252 if (sflag == 0 && minusc == NULL) {
9253 commandname = argv[0];
9255 setinputfile(arg0, 0);
9258 /* POSIX 1003.2: first arg after -c cmd is $0, remainder $1... */
9259 if (argptr && minusc && *argptr)
9262 shellparam.p = argptr;
9263 shellparam.optind = 1;
9264 shellparam.optoff = -1;
9265 /* assert(shellparam.malloc == 0 && shellparam.nparam == 0); */
9267 shellparam.nparam++;
9276 * Process shell options. The global variable argptr contains a pointer
9277 * to the argument list; we advance it past the options.
9290 while ((p = *argptr) != NULL) {
9292 if ((c = *p++) == '-') {
9294 if (p[0] == '\0' || (p[0] == '-' && p[1] == '\0')) {
9296 /* "-" means turn off -x and -v */
9299 /* "--" means reset params */
9300 else if (*argptr == NULL)
9303 break; /* "-" or "--" terminates options */
9305 } else if (c == '+') {
9311 while ((c = *p++) != '\0') {
9312 if (c == 'c' && cmdline) {
9314 #ifdef NOHACK /* removing this code allows sh -ce 'foo' for compat */
9318 if (q == NULL || minusc != NULL)
9319 error("Bad -c option");
9324 } else if (c == 'o') {
9325 minus_o(*argptr, val);
9343 out1str("Current option settings\n");
9344 for (i = 0; i < NOPTS; i++)
9345 out1fmt("%-16s%s\n", optent_name(optlist[i]),
9346 optent_val(i) ? "on" : "off");
9348 for (i = 0; i < NOPTS; i++)
9349 if (equal(name, optent_name(optlist[i]))) {
9350 setoption(optent_letter(optlist[i]), val);
9353 error("Illegal option -o %s", name);
9359 setoption(int flag, int val)
9363 for (i = 0; i < NOPTS; i++)
9364 if (optent_letter(optlist[i]) == flag) {
9365 optent_val(i) = val;
9367 /* #%$ hack for ksh semantics */
9370 else if (flag == 'E')
9375 error("Illegal option -%c", flag);
9382 * Set the shell parameters.
9386 setparam(char **argv)
9392 for (nparam = 0 ; argv[nparam] ; nparam++);
9393 ap = newparam = ckmalloc((nparam + 1) * sizeof *ap);
9395 *ap++ = savestr(*argv++);
9398 freeparam(&shellparam);
9399 shellparam.malloc = 1;
9400 shellparam.nparam = nparam;
9401 shellparam.p = newparam;
9402 shellparam.optind = 1;
9403 shellparam.optoff = -1;
9408 * Free the list of positional parameters.
9412 freeparam(volatile struct shparam *param)
9416 if (param->malloc) {
9417 for (ap = param->p ; *ap ; ap++)
9426 * The shift builtin command.
9430 shiftcmd(argc, argv)
9439 n = number(argv[1]);
9440 if (n > shellparam.nparam)
9441 error("can't shift that many");
9443 shellparam.nparam -= n;
9444 for (ap1 = shellparam.p ; --n >= 0 ; ap1++) {
9445 if (shellparam.malloc)
9449 while ((*ap2++ = *ap1++) != NULL);
9450 shellparam.optind = 1;
9451 shellparam.optoff = -1;
9459 * The set command builtin.
9468 return showvarscmd(argc, argv);
9472 if (*argptr != NULL) {
9481 getoptsreset(const char *value)
9483 shellparam.optind = number(value);
9484 shellparam.optoff = -1;
9487 #ifdef BB_LOCALE_SUPPORT
9488 static void change_lc_all(const char *value)
9490 if(value != 0 && *value != 0)
9491 setlocale(LC_ALL, value);
9494 static void change_lc_ctype(const char *value)
9496 if(value != 0 && *value != 0)
9497 setlocale(LC_CTYPE, value);
9504 * The getopts builtin. Shellparam.optnext points to the next argument
9505 * to be processed. Shellparam.optptr points to the next character to
9506 * be processed in the current argument. If shellparam.optnext is NULL,
9507 * then it's the first time getopts has been called.
9511 getoptscmd(argc, argv)
9518 error("Usage: getopts optstring var [arg]");
9519 else if (argc == 3) {
9520 optbase = shellparam.p;
9521 if (shellparam.optind > shellparam.nparam + 1) {
9522 shellparam.optind = 1;
9523 shellparam.optoff = -1;
9528 if (shellparam.optind > argc - 2) {
9529 shellparam.optind = 1;
9530 shellparam.optoff = -1;
9534 return getopts(argv[1], argv[2], optbase, &shellparam.optind,
9535 &shellparam.optoff);
9539 * Safe version of setvar, returns 1 on success 0 on failure.
9543 setvarsafe(name, val, flags)
9544 const char *name, *val;
9547 struct jmploc jmploc;
9548 struct jmploc *volatile savehandler = handler;
9554 if (setjmp(jmploc.loc))
9558 setvar(name, val, flags);
9560 handler = savehandler;
9565 getopts(optstr, optvar, optfirst, myoptind, optoff)
9577 char **optnext = optfirst + *myoptind - 1;
9579 if (*myoptind <= 1 || *optoff < 0 || !(*(optnext - 1)) ||
9580 strlen(*(optnext - 1)) < *optoff)
9583 p = *(optnext - 1) + *optoff;
9584 if (p == NULL || *p == '\0') {
9585 /* Current word is done, advance */
9586 if (optnext == NULL)
9589 if (p == NULL || *p != '-' || *++p == '\0') {
9591 *myoptind = optnext - optfirst + 1;
9597 if (p[0] == '-' && p[1] == '\0') /* check for "--" */
9602 for (q = optstr; *q != c; ) {
9604 if (optstr[0] == ':') {
9607 err |= setvarsafe("OPTARG", s, 0);
9610 outfmt(&errout, "Illegal option -%c\n", c);
9611 (void) unsetvar("OPTARG");
9621 if (*p == '\0' && (p = *optnext) == NULL) {
9622 if (optstr[0] == ':') {
9625 err |= setvarsafe("OPTARG", s, 0);
9629 outfmt(&errout, "No arg for -%c option\n", c);
9630 (void) unsetvar("OPTARG");
9638 setvarsafe("OPTARG", p, 0);
9642 setvarsafe("OPTARG", "", 0);
9643 *myoptind = optnext - optfirst + 1;
9650 *optoff = p ? p - *(optnext - 1) : -1;
9651 fmtstr(s, sizeof(s), "%d", *myoptind);
9652 err |= setvarsafe("OPTIND", s, VNOFUNC);
9655 err |= setvarsafe(optvar, s, 0);
9667 * XXX - should get rid of. have all builtins use getopt(3). the
9668 * library getopt must have the BSD extension static variable "optreset"
9669 * otherwise it can't be used within the shell safely.
9671 * Standard option processing (a la getopt) for builtin routines. The
9672 * only argument that is passed to nextopt is the option string; the
9673 * other arguments are unnecessary. It return the character, or '\0' on
9679 const char *optstring;
9685 if ((p = optptr) == NULL || *p == '\0') {
9687 if (p == NULL || *p != '-' || *++p == '\0')
9690 if (p[0] == '-' && p[1] == '\0') /* check for "--" */
9694 for (q = optstring ; *q != c ; ) {
9696 error("Illegal option -%c", c);
9701 if (*p == '\0' && (p = *argptr++) == NULL)
9702 error("No arg for -%c option", c);
9712 * Shell output routines. We use our own output routines because:
9713 * When a builtin command is interrupted we have to discard
9714 * any pending output.
9715 * When a builtin command appears in back quotes, we want to
9716 * save the output of the command in a region obtained
9717 * via malloc, rather than doing a fork and reading the
9718 * output of the command via a pipe.
9719 * Our output routines may be smaller than the stdio routines.
9724 #ifndef USE_GLIBC_STDIO
9725 static void __outstr (const char *, size_t, struct output*);
9729 #ifndef USE_GLIBC_STDIO
9731 __outstr(const char *p, size_t len, struct output *dest) {
9732 if (!dest->bufsize) {
9734 } else if (dest->buf == NULL) {
9735 if (len > dest->bufsize && dest->fd == MEM_OUT) {
9736 dest->bufsize = len;
9739 dest->buf = ckmalloc(dest->bufsize);
9740 dest->nextc = dest->buf;
9741 dest->nleft = dest->bufsize;
9743 } else if (dest->fd == MEM_OUT) {
9746 offset = dest->bufsize;
9748 if (dest->bufsize >= len) {
9749 dest->bufsize <<= 1;
9751 dest->bufsize += len;
9753 dest->buf = ckrealloc(dest->buf, dest->bufsize);
9754 dest->nleft = dest->bufsize - offset;
9755 dest->nextc = dest->buf + offset;
9761 if (len < dest->nleft) {
9763 memcpy(dest->nextc, p, len);
9768 if (xwrite(dest->fd, p, len) < len)
9769 dest->flags |= OUTPUT_ERR;
9775 outstr(const char *p, struct output *file)
9777 #ifdef USE_GLIBC_STDIO
9779 fputs(p, file->stream);
9788 if ((file->nleft -= len) > 0) {
9789 memcpy(file->nextc, p, len);
9793 __outstr(p, len, file);
9798 #ifndef USE_GLIBC_STDIO
9804 struct output *dest;
9806 __outstr(&c, 1, dest);
9822 struct output *dest;
9824 #ifdef USE_GLIBC_STDIO
9826 fflush(dest->stream);
9831 len = dest->nextc - dest->buf;
9832 if (dest->buf == NULL || !len || dest->fd < 0)
9834 dest->nextc = dest->buf;
9835 dest->nleft = dest->bufsize;
9836 if (xwrite(dest->fd, dest->buf, len) < len)
9837 dest->flags |= OUTPUT_ERR;
9857 outfmt(struct output *file, const char *fmt, ...)
9866 struct output *file;
9870 file = va_arg(ap, struct output *);
9871 fmt = va_arg(ap, const char *);
9875 doformat(file, fmt, ap);
9882 out1fmt(const char *fmt, ...)
9893 fmt = va_arg(ap, const char *);
9897 doformat(out1, fmt, ap);
9903 fmtstr(char *outbuf, size_t length, const char *fmt, ...)
9916 outbuf = va_arg(ap, char *);
9917 length = va_arg(ap, size_t);
9918 fmt = va_arg(ap, const char *);
9923 vsnprintf(outbuf, length, fmt, ap);
9927 #ifndef USE_GLIBC_STDIO
9930 doformat(struct output *dest, const char *f, va_list ap)
9939 nchars = vsnprintf(pm, size, f, ap);
9954 * Version of write which resumes after a signal is caught.
9958 xwrite(int fd, const char *buf, int nbytes)
9967 i = write(fd, buf, n);
9973 } else if (i == 0) {
9976 } else if (errno != EINTR) {
9983 #ifdef USE_GLIBC_STDIO
9984 static void initstreams() {
9985 output.stream = stdout;
9986 errout.stream = stderr;
9993 memout.stream = open_memstream(&memout.buf, &memout.bufsize);
10001 error = fclose(memout.stream);
10002 memout.stream = NULL;
10007 * Shell command parser.
10010 #define EOFMARKLEN 79
10015 struct heredoc *next; /* next here document in list */
10016 union node *here; /* redirection node */
10017 char *eofmark; /* string indicating end of input */
10018 int striptabs; /* if set, strip leading tabs */
10021 static struct heredoc *heredoclist; /* list of here documents to read */
10022 static int parsebackquote; /* nonzero if we are inside backquotes */
10023 static int doprompt; /* if set, prompt the user */
10024 static int needprompt; /* true if interactive and at start of line */
10025 static int lasttoken; /* last token read */
10027 static char *wordtext; /* text of last word returned by readtoken */
10029 static struct nodelist *backquotelist;
10030 static union node *redirnode;
10031 struct heredoc *heredoc;
10032 static int quoteflag; /* set if (part of) last token was quoted */
10033 static int startlinno; /* line # where last token started */
10036 static union node *list (int);
10037 static union node *andor (void);
10038 static union node *pipeline (void);
10039 static union node *command (void);
10040 static union node *simplecmd (void);
10041 static void parsefname (void);
10042 static void parseheredoc (void);
10043 static int peektoken (void);
10044 static int readtoken (void);
10045 static int xxreadtoken (void);
10046 static int readtoken1 (int, char const *, char *, int);
10047 static int noexpand (char *);
10048 static void synexpect (int) __attribute__((noreturn));
10049 static void synerror (const char *) __attribute__((noreturn));
10050 static void setprompt (int);
10054 * Read and parse a command. Returns NEOF on end of file. (NULL is a
10055 * valid parse tree indicating a blank line.)
10058 static union node *
10059 parsecmd(int interact)
10064 doprompt = interact;
10080 static union node *
10084 union node *n1, *n2, *n3;
10088 if (nlflag == 0 && tokendlist[peektoken()])
10094 if (tok == TBACKGND) {
10095 if (n2->type == NCMD || n2->type == NPIPE) {
10096 n2->ncmd.backgnd = 1;
10097 } else if (n2->type == NREDIR) {
10098 n2->type = NBACKGND;
10100 n3 = (union node *)stalloc(sizeof (struct nredir));
10101 n3->type = NBACKGND;
10103 n3->nredir.redirect = NULL;
10111 n3 = (union node *)stalloc(sizeof (struct nbinary));
10113 n3->nbinary.ch1 = n1;
10114 n3->nbinary.ch2 = n2;
10131 if (tokendlist[peektoken()])
10138 pungetc(); /* push back EOF on input */
10151 static union node *
10153 union node *n1, *n2, *n3;
10159 if ((t = readtoken()) == TAND) {
10161 } else if (t == TOR) {
10169 n3 = (union node *)stalloc(sizeof (struct nbinary));
10171 n3->nbinary.ch1 = n1;
10172 n3->nbinary.ch2 = n2;
10179 static union node *
10181 union node *n1, *n2, *pipenode;
10182 struct nodelist *lp, *prev;
10186 TRACE(("pipeline: entered\n"));
10187 if (readtoken() == TNOT) {
10193 if (readtoken() == TPIPE) {
10194 pipenode = (union node *)stalloc(sizeof (struct npipe));
10195 pipenode->type = NPIPE;
10196 pipenode->npipe.backgnd = 0;
10197 lp = (struct nodelist *)stalloc(sizeof (struct nodelist));
10198 pipenode->npipe.cmdlist = lp;
10202 lp = (struct nodelist *)stalloc(sizeof (struct nodelist));
10206 } while (readtoken() == TPIPE);
10212 n2 = (union node *)stalloc(sizeof (struct nnot));
10222 static union node *
10224 union node *n1, *n2;
10225 union node *ap, **app;
10226 union node *cp, **cpp;
10227 union node *redir, **rpp;
10234 switch (readtoken()) {
10236 n1 = (union node *)stalloc(sizeof (struct nif));
10238 n1->nif.test = list(0);
10239 if (readtoken() != TTHEN)
10241 n1->nif.ifpart = list(0);
10243 while (readtoken() == TELIF) {
10244 n2->nif.elsepart = (union node *)stalloc(sizeof (struct nif));
10245 n2 = n2->nif.elsepart;
10247 n2->nif.test = list(0);
10248 if (readtoken() != TTHEN)
10250 n2->nif.ifpart = list(0);
10252 if (lasttoken == TELSE)
10253 n2->nif.elsepart = list(0);
10255 n2->nif.elsepart = NULL;
10258 if (readtoken() != TFI)
10265 n1 = (union node *)stalloc(sizeof (struct nbinary));
10266 n1->type = (lasttoken == TWHILE)? NWHILE : NUNTIL;
10267 n1->nbinary.ch1 = list(0);
10268 if ((got=readtoken()) != TDO) {
10269 TRACE(("expecting DO got %s %s\n", tokname[got], got == TWORD ? wordtext : ""));
10272 n1->nbinary.ch2 = list(0);
10273 if (readtoken() != TDONE)
10279 if (readtoken() != TWORD || quoteflag || ! goodname(wordtext))
10280 synerror("Bad for loop variable");
10281 n1 = (union node *)stalloc(sizeof (struct nfor));
10283 n1->nfor.var = wordtext;
10285 if (readtoken() == TIN) {
10287 while (readtoken() == TWORD) {
10288 n2 = (union node *)stalloc(sizeof (struct narg));
10290 n2->narg.text = wordtext;
10291 n2->narg.backquote = backquotelist;
10293 app = &n2->narg.next;
10296 n1->nfor.args = ap;
10297 if (lasttoken != TNL && lasttoken != TSEMI)
10300 static char argvars[5] = {CTLVAR, VSNORMAL|VSQUOTE,
10302 n2 = (union node *)stalloc(sizeof (struct narg));
10304 n2->narg.text = argvars;
10305 n2->narg.backquote = NULL;
10306 n2->narg.next = NULL;
10307 n1->nfor.args = n2;
10309 * Newline or semicolon here is optional (but note
10310 * that the original Bourne shell only allowed NL).
10312 if (lasttoken != TNL && lasttoken != TSEMI)
10316 if (readtoken() != TDO)
10318 n1->nfor.body = list(0);
10319 if (readtoken() != TDONE)
10324 n1 = (union node *)stalloc(sizeof (struct ncase));
10326 if (readtoken() != TWORD)
10328 n1->ncase.expr = n2 = (union node *)stalloc(sizeof (struct narg));
10330 n2->narg.text = wordtext;
10331 n2->narg.backquote = backquotelist;
10332 n2->narg.next = NULL;
10335 } while (readtoken() == TNL);
10336 if (lasttoken != TIN)
10337 synerror("expecting \"in\"");
10338 cpp = &n1->ncase.cases;
10339 checkkwd = 2, readtoken();
10341 if (lasttoken == TLP)
10343 *cpp = cp = (union node *)stalloc(sizeof (struct nclist));
10345 app = &cp->nclist.pattern;
10347 *app = ap = (union node *)stalloc(sizeof (struct narg));
10349 ap->narg.text = wordtext;
10350 ap->narg.backquote = backquotelist;
10351 if (checkkwd = 2, readtoken() != TPIPE)
10353 app = &ap->narg.next;
10356 ap->narg.next = NULL;
10357 if (lasttoken != TRP)
10359 cp->nclist.body = list(0);
10362 if ((t = readtoken()) != TESAC) {
10364 synexpect(TENDCASE);
10366 checkkwd = 2, readtoken();
10368 cpp = &cp->nclist.next;
10369 } while(lasttoken != TESAC);
10374 n1 = (union node *)stalloc(sizeof (struct nredir));
10375 n1->type = NSUBSHELL;
10376 n1->nredir.n = list(0);
10377 n1->nredir.redirect = NULL;
10378 if (readtoken() != TRP)
10384 if (readtoken() != TEND)
10388 /* Handle an empty command like other simple commands. */
10397 * An empty command before a ; doesn't make much sense, and
10398 * should certainly be disallowed in the case of `if ;'.
10412 /* Now check for redirection which may follow command */
10413 while (readtoken() == TREDIR) {
10414 *rpp = n2 = redirnode;
10415 rpp = &n2->nfile.next;
10421 if (n1->type != NSUBSHELL) {
10422 n2 = (union node *)stalloc(sizeof (struct nredir));
10427 n1->nredir.redirect = redir;
10434 static union node *
10436 union node *args, **app;
10437 union node *n = NULL;
10438 union node *vars, **vpp;
10439 union node **rpp, *redir;
10452 switch (readtoken()) {
10455 n = (union node *)stalloc(sizeof (struct narg));
10457 n->narg.text = wordtext;
10458 n->narg.backquote = backquotelist;
10459 if (lasttoken == TWORD) {
10461 app = &n->narg.next;
10464 vpp = &n->narg.next;
10468 *rpp = n = redirnode;
10469 rpp = &n->nfile.next;
10470 parsefname(); /* read name of redirection file */
10474 args && app == &args->narg.next &&
10477 /* We have a function */
10478 if (readtoken() != TRP)
10482 n->narg.next = command();
10495 n = (union node *)stalloc(sizeof (struct ncmd));
10497 n->ncmd.backgnd = 0;
10498 n->ncmd.args = args;
10499 n->ncmd.assign = vars;
10500 n->ncmd.redirect = redir;
10504 static union node *
10508 n = (union node *)stalloc(sizeof (struct narg));
10510 n->narg.next = NULL;
10511 n->narg.text = wordtext;
10512 n->narg.backquote = backquotelist;
10516 static void fixredir(union node *n, const char *text, int err)
10518 TRACE(("Fix redir %s %d\n", text, err));
10520 n->ndup.vname = NULL;
10522 if (is_digit(text[0]) && text[1] == '\0')
10523 n->ndup.dupfd = digit_val(text[0]);
10524 else if (text[0] == '-' && text[1] == '\0')
10525 n->ndup.dupfd = -1;
10529 synerror("Bad fd number");
10531 n->ndup.vname = makename();
10538 union node *n = redirnode;
10540 if (readtoken() != TWORD)
10542 if (n->type == NHERE) {
10543 struct heredoc *here = heredoc;
10547 if (quoteflag == 0)
10549 TRACE(("Here document %d\n", n->type));
10550 if (here->striptabs) {
10551 while (*wordtext == '\t')
10554 if (! noexpand(wordtext) || (i = strlen(wordtext)) == 0 || i > EOFMARKLEN)
10555 synerror("Illegal eof marker for << redirection");
10556 rmescapes(wordtext);
10557 here->eofmark = wordtext;
10559 if (heredoclist == NULL)
10560 heredoclist = here;
10562 for (p = heredoclist ; p->next ; p = p->next);
10565 } else if (n->type == NTOFD || n->type == NFROMFD) {
10566 fixredir(n, wordtext, 0);
10568 n->nfile.fname = makename();
10574 * Input any here documents.
10579 struct heredoc *here;
10582 while (heredoclist) {
10583 here = heredoclist;
10584 heredoclist = here->next;
10589 readtoken1(pgetc(), here->here->type == NHERE? SQSYNTAX : DQSYNTAX,
10590 here->eofmark, here->striptabs);
10591 n = (union node *)stalloc(sizeof (struct narg));
10592 n->narg.type = NARG;
10593 n->narg.next = NULL;
10594 n->narg.text = wordtext;
10595 n->narg.backquote = backquotelist;
10596 here->here->nhere.doc = n;
10613 int savecheckkwd = checkkwd;
10614 int savecheckalias = checkalias;
10619 int alreadyseen = tokpushback;
10629 checkalias = savecheckalias;
10636 if (checkkwd == 2) {
10645 * check for keywords
10647 if (t == TWORD && !quoteflag)
10649 const char *const *pp;
10651 if ((pp = findkwd(wordtext))) {
10652 lasttoken = t = pp - parsekwd + KWDOFFSET;
10653 TRACE(("keyword %s recognized\n", tokname[t]));
10664 } else if (checkalias == 2 && isassignment(wordtext)) {
10665 lasttoken = t = TASSIGN;
10666 } else if (checkalias) {
10667 if (!quoteflag && (ap = lookupalias(wordtext, 1)) != NULL) {
10669 pushstring(ap->val, strlen(ap->val), ap);
10671 checkkwd = savecheckkwd;
10680 TRACE(("token %s %s\n", tokname[t], t == TWORD || t == TASSIGN ? wordtext : ""));
10682 TRACE(("reread token %s %s\n", tokname[t], t == TWORD || t == TASSIGN ? wordtext : ""));
10689 * Read the next input token.
10690 * If the token is a word, we set backquotelist to the list of cmds in
10691 * backquotes. We set quoteflag to true if any part of the word was
10693 * If the token is TREDIR, then we set redirnode to a structure containing
10695 * In all cases, the variable startlinno is set to the number of the line
10696 * on which the token starts.
10698 * [Change comment: here documents and internal procedures]
10699 * [Readtoken shouldn't have any arguments. Perhaps we should make the
10700 * word parsing code into a separate routine. In this case, readtoken
10701 * doesn't need to have any internal procedures, but parseword does.
10702 * We could also make parseoperator in essence the main routine, and
10703 * have parseword (readtoken1?) handle both words and redirection.]
10706 #define RETURN(token) return lasttoken = token
10720 startlinno = plinno;
10721 for (;;) { /* until token or start of word found */
10724 case ' ': case '\t':
10728 while ((c = pgetc()) != '\n' && c != PEOF);
10732 if (pgetc() == '\n') {
10733 startlinno = ++plinno;
10744 needprompt = doprompt;
10749 if (pgetc() == '&')
10754 if (pgetc() == '|')
10759 if (pgetc() == ';')
10772 return readtoken1(c, BASESYNTAX, (char *)NULL, 0);
10779 * If eofmark is NULL, read a word or a redirection symbol. If eofmark
10780 * is not NULL, read a here document. In the latter case, eofmark is the
10781 * word which marks the end of the document and striptabs is true if
10782 * leading tabs should be stripped from the document. The argument firstc
10783 * is the first character of the input token or document.
10785 * Because C does not have internal subroutines, I have simulated them
10786 * using goto's to implement the subroutine linkage. The following macros
10787 * will run code that appears at the end of readtoken1.
10790 #define CHECKEND() {goto checkend; checkend_return:;}
10791 #define PARSEREDIR() {goto parseredir; parseredir_return:;}
10792 #define PARSESUB() {goto parsesub; parsesub_return:;}
10793 #define PARSEBACKQOLD() {oldstyle = 1; goto parsebackq; parsebackq_oldreturn:;}
10794 #define PARSEBACKQNEW() {oldstyle = 0; goto parsebackq; parsebackq_newreturn:;}
10795 #define PARSEARITH() {goto parsearith; parsearith_return:;}
10798 readtoken1(firstc, syntax, eofmark, striptabs)
10800 char const *syntax;
10807 char line[EOFMARKLEN + 1];
10808 struct nodelist *bqlist;
10811 int varnest; /* levels of variables expansion */
10812 int arinest; /* levels of arithmetic expansion */
10813 int parenlevel; /* levels of parens in arithmetic */
10814 int dqvarnest; /* levels of variables expansion within double quotes */
10816 char const *prevsyntax; /* syntax before arithmetic */
10818 /* Avoid longjmp clobbering */
10824 (void) &parenlevel;
10827 (void) &prevsyntax;
10831 startlinno = plinno;
10833 if (syntax == DQSYNTAX)
10842 STARTSTACKSTR(out);
10843 loop: { /* for each line, until end of word */
10844 CHECKEND(); /* set c to PEOF if at end of here document */
10845 for (;;) { /* until end of line or end of word */
10846 CHECKSTRSPACE(3, out); /* permit 3 calls to USTPUTC */
10847 switch(syntax[c]) {
10848 case CNL: /* '\n' */
10849 if (syntax == BASESYNTAX)
10850 goto endword; /* exit outer loop */
10858 goto loop; /* continue outer loop */
10863 if ((eofmark == NULL || dblquote) &&
10865 USTPUTC(CTLESC, out);
10868 case CBACK: /* backslash */
10871 USTPUTC('\\', out);
10873 } else if (c == '\n') {
10879 if (dblquote && c != '\\' && c != '`' && c != '$'
10880 && (c != '"' || eofmark != NULL))
10881 USTPUTC('\\', out);
10882 if (SQSYNTAX[c] == CCTL)
10883 USTPUTC(CTLESC, out);
10884 else if (eofmark == NULL)
10885 USTPUTC(CTLQUOTEMARK, out);
10891 if (eofmark == NULL)
10892 USTPUTC(CTLQUOTEMARK, out);
10896 if (eofmark == NULL)
10897 USTPUTC(CTLQUOTEMARK, out);
10902 if (eofmark != NULL && arinest == 0 &&
10907 syntax = ARISYNTAX;
10909 } else if (eofmark == NULL &&
10911 syntax = BASESYNTAX;
10917 case CVAR: /* '$' */
10918 PARSESUB(); /* parse substitution */
10920 case CENDVAR: /* '}' */
10923 if (dqvarnest > 0) {
10926 USTPUTC(CTLENDVAR, out);
10931 #ifdef ASH_MATH_SUPPORT
10932 case CLP: /* '(' in arithmetic */
10936 case CRP: /* ')' in arithmetic */
10937 if (parenlevel > 0) {
10941 if (pgetc() == ')') {
10942 if (--arinest == 0) {
10943 USTPUTC(CTLENDARI, out);
10944 syntax = prevsyntax;
10945 if (syntax == DQSYNTAX)
10953 * unbalanced parens
10954 * (don't 2nd guess - no error)
10962 case CBQUOTE: /* '`' */
10966 goto endword; /* exit outer loop */
10971 goto endword; /* exit outer loop */
10980 if (syntax == ARISYNTAX)
10981 synerror("Missing '))'");
10982 if (syntax != BASESYNTAX && ! parsebackquote && eofmark == NULL)
10983 synerror("Unterminated quoted string");
10984 if (varnest != 0) {
10985 startlinno = plinno;
10986 synerror("Missing '}'");
10988 USTPUTC('\0', out);
10989 len = out - stackblock();
10990 out = stackblock();
10991 if (eofmark == NULL) {
10992 if ((c == '>' || c == '<')
10995 && (*out == '\0' || is_digit(*out))) {
10997 return lasttoken = TREDIR;
11002 quoteflag = quotef;
11003 backquotelist = bqlist;
11004 grabstackblock(len);
11006 return lasttoken = TWORD;
11007 /* end of readtoken routine */
11012 * Check to see whether we are at the end of the here document. When this
11013 * is called, c is set to the first character of the next input line. If
11014 * we are at the end of the here document, this routine sets the c to PEOF.
11025 while (c == '\t') {
11029 if (c == *eofmark) {
11030 if (pfgets(line, sizeof line) != NULL) {
11034 for (q = eofmark + 1 ; *q && *p == *q ; p++, q++);
11035 if (*p == '\n' && *q == '\0') {
11038 needprompt = doprompt;
11040 pushstring(line, strlen(line), NULL);
11045 goto checkend_return;
11050 * Parse a redirection operator. The variable "out" points to a string
11051 * specifying the fd to be redirected. The variable "c" contains the
11052 * first character of the redirection operator.
11059 np = (union node *)stalloc(sizeof (struct nfile));
11064 np->type = NAPPEND;
11073 } else { /* c == '<' */
11075 switch (c = pgetc()) {
11077 if (sizeof (struct nfile) != sizeof (struct nhere)) {
11078 np = (union node *)stalloc(sizeof (struct nhere));
11082 heredoc = (struct heredoc *)stalloc(sizeof (struct heredoc));
11083 heredoc->here = np;
11084 if ((c = pgetc()) == '-') {
11085 heredoc->striptabs = 1;
11087 heredoc->striptabs = 0;
11093 np->type = NFROMFD;
11097 np->type = NFROMTO;
11107 np->nfile.fd = digit_val(fd);
11109 goto parseredir_return;
11114 * Parse a substitution. At this point, we have read the dollar sign
11115 * and nothing else.
11123 static const char types[] = "}-+?=";
11128 (c != '(' && c != '{' && !is_name(c) && !is_special(c))
11132 } else if (c == '(') { /* $(command) or $((arith)) */
11133 if (pgetc() == '(') {
11140 USTPUTC(CTLVAR, out);
11141 typeloc = out - stackblock();
11142 USTPUTC(VSNORMAL, out);
11143 subtype = VSNORMAL;
11147 if ((c = pgetc()) == '}')
11150 subtype = VSLENGTH;
11155 if (c > PEOA && is_name(c)) {
11159 } while (c > PEOA && is_in_name(c));
11160 } else if (is_digit(c)) {
11164 } while (is_digit(c));
11166 else if (is_special(c)) {
11171 badsub: synerror("Bad substitution");
11175 if (subtype == 0) {
11182 p = strchr(types, c);
11185 subtype = p - types + VSNORMAL;
11191 subtype = c == '#' ? VSTRIMLEFT :
11204 if (dblquote || arinest)
11206 *(stackblock() + typeloc) = subtype | flags;
11207 if (subtype != VSNORMAL) {
11214 goto parsesub_return;
11219 * Called to parse command substitutions. Newstyle is set if the command
11220 * is enclosed inside $(...); nlpp is a pointer to the head of the linked
11221 * list of commands (passed by reference), and savelen is the number of
11222 * characters on the top of the stack which must be preserved.
11226 struct nodelist **nlpp;
11229 char *volatile str;
11230 struct jmploc jmploc;
11231 struct jmploc *volatile savehandler;
11235 (void) &saveprompt;
11238 savepbq = parsebackquote;
11239 if (setjmp(jmploc.loc)) {
11242 parsebackquote = 0;
11243 handler = savehandler;
11244 longjmp(handler->loc, 1);
11248 savelen = out - stackblock();
11250 str = ckmalloc(savelen);
11251 memcpy(str, stackblock(), savelen);
11253 savehandler = handler;
11257 /* We must read until the closing backquote, giving special
11258 treatment to some slashes, and then push the string and
11259 reread it as input, interpreting it normally. */
11266 STARTSTACKSTR(pout);
11272 switch (pc = pgetc()) {
11277 if ((pc = pgetc()) == '\n') {
11284 * If eating a newline, avoid putting
11285 * the newline into the new character
11286 * stream (via the STPUTC after the
11291 if (pc != '\\' && pc != '`' && pc != '$'
11292 && (!dblquote || pc != '"'))
11293 STPUTC('\\', pout);
11303 startlinno = plinno;
11304 synerror("EOF in backquote substitution");
11308 needprompt = doprompt;
11317 STPUTC('\0', pout);
11318 psavelen = pout - stackblock();
11319 if (psavelen > 0) {
11320 pstr = grabstackstr(pout);
11321 setinputstring(pstr);
11326 nlpp = &(*nlpp)->next;
11327 *nlpp = (struct nodelist *)stalloc(sizeof (struct nodelist));
11328 (*nlpp)->next = NULL;
11329 parsebackquote = oldstyle;
11332 saveprompt = doprompt;
11339 doprompt = saveprompt;
11341 if (readtoken() != TRP)
11348 * Start reading from old file again, ignoring any pushed back
11349 * tokens left from the backquote parsing
11354 while (stackblocksize() <= savelen)
11356 STARTSTACKSTR(out);
11358 memcpy(out, str, savelen);
11359 STADJUST(savelen, out);
11365 parsebackquote = savepbq;
11366 handler = savehandler;
11367 if (arinest || dblquote)
11368 USTPUTC(CTLBACKQ | CTLQUOTE, out);
11370 USTPUTC(CTLBACKQ, out);
11372 goto parsebackq_oldreturn;
11374 goto parsebackq_newreturn;
11378 * Parse an arithmetic expansion (indicate start of one and set state)
11382 if (++arinest == 1) {
11383 prevsyntax = syntax;
11384 syntax = ARISYNTAX;
11385 USTPUTC(CTLARI, out);
11392 * we collapse embedded arithmetic expansion to
11393 * parenthesis, which should be equivalent
11397 goto parsearith_return;
11400 } /* end of readtoken */
11404 * Returns true if the text contains nothing to expand (no dollar signs
11416 while ((c = *p++) != '\0') {
11417 if (c == CTLQUOTEMARK)
11421 else if (BASESYNTAX[(int)c] == CCTL)
11429 * Return true if the argument is a legal variable name (a letter or
11430 * underscore followed by zero or more letters, underscores, and digits).
11434 goodname(const char *name)
11442 if (! is_in_name(*p))
11450 * Called when an unexpected token is read during the parse. The argument
11451 * is the token that is expected, or -1 if more than one type of token can
11452 * occur at this point.
11462 fmtstr(msg, 64, "%s unexpected (expecting %s)",
11463 tokname[lasttoken], tokname[token]);
11465 fmtstr(msg, 64, "%s unexpected", tokname[lasttoken]);
11473 synerror(const char *msg)
11476 outfmt(&errout, "%s: %d: ", commandname, startlinno);
11477 outfmt(&errout, "Syntax error: %s\n", msg);
11478 error((char *)NULL);
11484 * called by editline -- any expansions to the prompt
11485 * should be added here.
11487 static const char *
11488 getprompt(void *unused)
11490 switch (whichprompt) {
11498 return "<internal prompt error>";
11503 setprompt(int which)
11505 whichprompt = which;
11506 putprompt(getprompt(NULL));
11511 * Code for dealing with input/output redirection.
11514 #define EMPTY -2 /* marks an unused slot in redirtab */
11516 # define PIPESIZE 4096 /* amount of buffering in a pipe */
11518 # define PIPESIZE PIPE_BUF
11524 * Process a list of redirection commands. If the REDIR_PUSH flag is set,
11525 * old file descriptors are stashed away so that the redirection can be
11526 * undone by calling popredir. If the REDIR_BACKQ flag is set, then the
11527 * standard output, and the standard error if it becomes a duplicate of
11528 * stdout, is saved in memory.
11532 redirect(redir, flags)
11537 struct redirtab *sv = NULL;
11542 char memory[10]; /* file descriptors to write to memory */
11544 for (i = 10 ; --i >= 0 ; )
11546 memory[1] = flags & REDIR_BACKQ;
11547 if (flags & REDIR_PUSH) {
11548 sv = ckmalloc(sizeof (struct redirtab));
11549 for (i = 0 ; i < 10 ; i++)
11550 sv->renamed[i] = EMPTY;
11551 sv->next = redirlist;
11554 for (n = redir ; n ; n = n->nfile.next) {
11557 if ((n->nfile.type == NTOFD || n->nfile.type == NFROMFD) &&
11558 n->ndup.dupfd == fd)
11559 continue; /* redirect from/to same file descriptor */
11562 newfd = openredirect(n);
11563 if (((flags & REDIR_PUSH) && sv->renamed[fd] == EMPTY) ||
11567 } else if ((i = fcntl(fd, F_DUPFD, 10)) == -1) {
11571 dupredirect(n, newfd, memory);
11581 error("%d: %m", fd);
11587 if (flags & REDIR_PUSH) {
11588 sv->renamed[fd] = i;
11590 if (fd == fileno2) {
11594 } else if (fd != newfd) {
11600 dupredirect(n, newfd, memory);
11611 openredirect(redir)
11617 switch (redir->nfile.type) {
11619 fname = redir->nfile.expfname;
11620 if ((f = open(fname, O_RDONLY)) < 0)
11624 fname = redir->nfile.expfname;
11625 if ((f = open(fname, O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0)
11629 /* Take care of noclobber mode. */
11631 fname = redir->nfile.expfname;
11632 if ((f = noclobberopen(fname)) < 0)
11637 fname = redir->nfile.expfname;
11639 if ((f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
11642 if ((f = creat(fname, 0666)) < 0)
11647 fname = redir->nfile.expfname;
11649 if ((f = open(fname, O_WRONLY|O_CREAT|O_APPEND, 0666)) < 0)
11652 if ((f = open(fname, O_WRONLY)) < 0
11653 && (f = creat(fname, 0666)) < 0)
11655 lseek(f, (off_t)0, 2);
11662 /* Fall through to eliminate warning. */
11669 f = openhere(redir);
11675 error("cannot create %s: %s", fname, errmsg(errno, E_CREAT));
11677 error("cannot open %s: %s", fname, errmsg(errno, E_OPEN));
11682 dupredirect(union node *redir, int f, char memory[10])
11684 int fd = redir->nfile.fd;
11687 if (redir->nfile.type == NTOFD || redir->nfile.type == NFROMFD) {
11688 if (redir->ndup.dupfd >= 0) { /* if not ">&-" */
11689 if (memory[redir->ndup.dupfd])
11692 dup_as_newfd(redir->ndup.dupfd, fd);
11698 dup_as_newfd(f, fd);
11706 * Handle here documents. Normally we fork off a process to write the
11707 * data to a pipe. If the document is short, we can stuff the data in
11708 * the pipe without forking.
11719 error("Pipe call failed");
11720 if (redir->type == NHERE) {
11721 len = strlen(redir->nhere.doc->narg.text);
11722 if (len <= PIPESIZE) {
11723 xwrite(pip[1], redir->nhere.doc->narg.text, len);
11727 if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) {
11729 signal(SIGINT, SIG_IGN);
11730 signal(SIGQUIT, SIG_IGN);
11731 signal(SIGHUP, SIG_IGN);
11733 signal(SIGTSTP, SIG_IGN);
11735 signal(SIGPIPE, SIG_DFL);
11736 if (redir->type == NHERE)
11737 xwrite(pip[1], redir->nhere.doc->narg.text, len);
11739 expandhere(redir->nhere.doc, pip[1]);
11749 * Undo the effects of the last redirection.
11755 struct redirtab *rp = redirlist;
11759 for (i = 0 ; i < 10 ; i++) {
11760 if (rp->renamed[i] != EMPTY) {
11764 if (rp->renamed[i] >= 0) {
11765 dup_as_newfd(rp->renamed[i], i);
11766 close(rp->renamed[i]);
11768 if (rp->renamed[i] == fileno2) {
11773 redirlist = rp->next;
11779 * Discard all saved file descriptors.
11784 struct redirtab *rp;
11787 for (rp = redirlist ; rp ; rp = rp->next) {
11788 for (i = 0 ; i < 10 ; i++) {
11789 if (rp->renamed[i] >= 0) {
11790 close(rp->renamed[i]);
11791 if (rp->renamed[i] == fileno2) {
11795 rp->renamed[i] = EMPTY;
11798 if (fileno2 != 2 && fileno2 >= 0) {
11806 * Copy a file descriptor to be >= to. Returns -1
11807 * if the source file descriptor is closed, EMPTY if there are no unused
11808 * file descriptors left.
11812 dup_as_newfd(from, to)
11818 newfd = fcntl(from, F_DUPFD, to);
11820 if (errno == EMFILE)
11823 error("%d: %m", from);
11829 * Open a file in noclobber mode.
11830 * The code was copied from bash.
11833 noclobberopen(const char *fname)
11836 struct stat finfo, finfo2;
11839 * If the file exists and is a regular file, return an error
11842 r = stat(fname, &finfo);
11843 if (r == 0 && S_ISREG(finfo.st_mode)) {
11849 * If the file was not present (r != 0), make sure we open it
11850 * exclusively so that if it is created before we open it, our open
11851 * will fail. Make sure that we do not truncate an existing file.
11852 * Note that we don't turn on O_EXCL unless the stat failed -- if the
11853 * file was not a regular file, we leave O_EXCL off.
11856 return open(fname, O_WRONLY|O_CREAT|O_EXCL, 0666);
11857 fd = open(fname, O_WRONLY|O_CREAT, 0666);
11859 /* If the open failed, return the file descriptor right away. */
11864 * OK, the open succeeded, but the file may have been changed from a
11865 * non-regular file to a regular file between the stat and the open.
11866 * We are assuming that the O_EXCL open handles the case where FILENAME
11867 * did not exist and is symlinked to an existing file between the stat
11872 * If we can open it and fstat the file descriptor, and neither check
11873 * revealed that it was a regular file, and the file has not been
11874 * replaced, return the file descriptor.
11876 if (fstat(fd, &finfo2) == 0 && !S_ISREG(finfo2.st_mode) &&
11877 finfo.st_dev == finfo2.st_dev && finfo.st_ino == finfo2.st_ino)
11880 /* The file has been replaced. badness. */
11885 /*#ifdef __weak_alias
11886 __weak_alias(getmode,_getmode)
11887 __weak_alias(setmode,_setmode)
11891 #define S_ISTXT __S_ISVTX
11894 #define SET_LEN 6 /* initial # of bitcmd struct to malloc */
11895 #define SET_LEN_INCR 4 /* # of bitcmd structs to add as needed */
11897 typedef struct bitcmd {
11903 #define CMD2_CLR 0x01
11904 #define CMD2_SET 0x02
11905 #define CMD2_GBITS 0x04
11906 #define CMD2_OBITS 0x08
11907 #define CMD2_UBITS 0x10
11909 static BITCMD *addcmd (BITCMD *, int, int, int, u_int);
11910 static void compress_mode (BITCMD *);
11911 #ifdef SETMODE_DEBUG
11912 static void dumpmode (BITCMD *);
11916 * Given the old mode and an array of bitcmd structures, apply the operations
11917 * described in the bitcmd structures to the old mode, and return the new mode.
11918 * Note that there is no '=' command; a strict assignment is just a '-' (clear
11919 * bits) followed by a '+' (set bits).
11922 getmode(bbox, omode)
11927 mode_t clrval, newmode, value;
11929 _DIAGASSERT(bbox != NULL);
11931 set = (const BITCMD *)bbox;
11933 for (value = 0;; set++)
11936 * When copying the user, group or other bits around, we "know"
11937 * where the bits are in the mode so that we can do shifts to
11938 * copy them around. If we don't use shifts, it gets real
11939 * grundgy with lots of single bit checks and bit sets.
11942 value = (newmode & S_IRWXU) >> 6;
11946 value = (newmode & S_IRWXG) >> 3;
11950 value = newmode & S_IRWXO;
11951 common: if (set->cmd2 & CMD2_CLR) {
11953 (set->cmd2 & CMD2_SET) ? S_IRWXO : value;
11954 if (set->cmd2 & CMD2_UBITS)
11955 newmode &= ~((clrval<<6) & set->bits);
11956 if (set->cmd2 & CMD2_GBITS)
11957 newmode &= ~((clrval<<3) & set->bits);
11958 if (set->cmd2 & CMD2_OBITS)
11959 newmode &= ~(clrval & set->bits);
11961 if (set->cmd2 & CMD2_SET) {
11962 if (set->cmd2 & CMD2_UBITS)
11963 newmode |= (value<<6) & set->bits;
11964 if (set->cmd2 & CMD2_GBITS)
11965 newmode |= (value<<3) & set->bits;
11966 if (set->cmd2 & CMD2_OBITS)
11967 newmode |= value & set->bits;
11972 newmode |= set->bits;
11976 newmode &= ~set->bits;
11980 if (omode & (S_IFDIR|S_IXUSR|S_IXGRP|S_IXOTH))
11981 newmode |= set->bits;
11986 #ifdef SETMODE_DEBUG
11987 (void)printf("getmode:%04o -> %04o\n", omode, newmode);
11993 #define ADDCMD(a, b, c, d) do { \
11994 if (set >= endset) { \
11996 setlen += SET_LEN_INCR; \
11997 newset = realloc(saveset, sizeof(BITCMD) * setlen); \
11998 if (newset == NULL) { \
12002 set = newset + (set - saveset); \
12003 saveset = newset; \
12004 endset = newset + (setlen - 2); \
12006 set = addcmd(set, (a), (b), (c), (d)); \
12007 } while (/*CONSTCOND*/0)
12009 #define STANDARD_BITS (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO)
12017 BITCMD *set, *saveset, *endset;
12018 sigset_t mysigset, sigoset;
12020 int equalopdone = 0; /* pacify gcc */
12021 int permXbits, setlen;
12027 * Get a copy of the mask for the permissions that are mask relative.
12028 * Flip the bits, we want what's not set. Since it's possible that
12029 * the caller is opening files inside a signal handler, protect them
12032 sigfillset(&mysigset);
12033 (void)sigprocmask(SIG_BLOCK, &mysigset, &sigoset);
12034 (void)umask(mask = umask(0));
12036 (void)sigprocmask(SIG_SETMASK, &sigoset, NULL);
12038 setlen = SET_LEN + 2;
12040 if ((set = malloc((u_int)(sizeof(BITCMD) * setlen))) == NULL)
12043 endset = set + (setlen - 2);
12046 * If an absolute number, get it and return; disallow non-octal digits
12049 if (isdigit((unsigned char)*p)) {
12050 perm = (mode_t)strtol(p, &ep, 8);
12051 if (*ep || perm & ~(STANDARD_BITS|S_ISTXT)) {
12055 ADDCMD('=', (STANDARD_BITS|S_ISTXT), perm, mask);
12061 * Build list of structures to set/clear/copy bits as described by
12062 * each clause of the symbolic mode.
12065 /* First, find out which bits might be modified. */
12066 for (who = 0;; ++p) {
12069 who |= STANDARD_BITS;
12072 who |= S_ISUID|S_IRWXU;
12075 who |= S_ISGID|S_IRWXG;
12085 getop: if ((op = *p++) != '+' && op != '-' && op != '=') {
12093 for (perm = 0, permXbits = 0;; ++p) {
12096 perm |= S_IRUSR|S_IRGRP|S_IROTH;
12100 * If specific bits where requested and
12101 * only "other" bits ignore set-id.
12103 if (who == 0 || (who & ~S_IRWXO))
12104 perm |= S_ISUID|S_ISGID;
12108 * If specific bits where requested and
12109 * only "other" bits ignore set-id.
12111 if (who == 0 || (who & ~S_IRWXO)) {
12117 perm |= S_IWUSR|S_IWGRP|S_IWOTH;
12120 permXbits = S_IXUSR|S_IXGRP|S_IXOTH;
12123 perm |= S_IXUSR|S_IXGRP|S_IXOTH;
12129 * When ever we hit 'u', 'g', or 'o', we have
12130 * to flush out any partial mode that we have,
12131 * and then do the copying of the mode bits.
12134 ADDCMD(op, who, perm, mask);
12139 if (op == '+' && permXbits) {
12140 ADDCMD('X', who, permXbits, mask);
12143 ADDCMD(*p, who, op, mask);
12148 * Add any permissions that we haven't already
12151 if (perm || (op == '=' && !equalopdone)) {
12154 ADDCMD(op, who, perm, mask);
12158 ADDCMD('X', who, permXbits, mask);
12172 #ifdef SETMODE_DEBUG
12173 (void)printf("Before compress_mode()\n");
12176 compress_mode(saveset);
12177 #ifdef SETMODE_DEBUG
12178 (void)printf("After compress_mode()\n");
12185 addcmd(set, op, who, oparg, mask)
12192 _DIAGASSERT(set != NULL);
12197 set->bits = who ? who : STANDARD_BITS;
12206 set->bits = (who ? who : mask) & oparg;
12214 set->cmd2 = ((who & S_IRUSR) ? CMD2_UBITS : 0) |
12215 ((who & S_IRGRP) ? CMD2_GBITS : 0) |
12216 ((who & S_IROTH) ? CMD2_OBITS : 0);
12217 set->bits = (mode_t)~0;
12219 set->cmd2 = CMD2_UBITS | CMD2_GBITS | CMD2_OBITS;
12224 set->cmd2 |= CMD2_SET;
12225 else if (oparg == '-')
12226 set->cmd2 |= CMD2_CLR;
12227 else if (oparg == '=')
12228 set->cmd2 |= CMD2_SET|CMD2_CLR;
12234 #ifdef SETMODE_DEBUG
12240 _DIAGASSERT(set != NULL);
12242 for (; set->cmd; ++set)
12243 (void)printf("cmd: '%c' bits %04o%s%s%s%s%s%s\n",
12244 set->cmd, set->bits, set->cmd2 ? " cmd2:" : "",
12245 set->cmd2 & CMD2_CLR ? " CLR" : "",
12246 set->cmd2 & CMD2_SET ? " SET" : "",
12247 set->cmd2 & CMD2_UBITS ? " UBITS" : "",
12248 set->cmd2 & CMD2_GBITS ? " GBITS" : "",
12249 set->cmd2 & CMD2_OBITS ? " OBITS" : "");
12254 * Given an array of bitcmd structures, compress by compacting consecutive
12255 * '+', '-' and 'X' commands into at most 3 commands, one of each. The 'u',
12256 * 'g' and 'o' commands continue to be separate. They could probably be
12257 * compacted, but it's not worth the effort.
12264 int setbits, clrbits, Xbits, op;
12266 _DIAGASSERT(set != NULL);
12268 for (nset = set;;) {
12269 /* Copy over any 'u', 'g' and 'o' commands. */
12270 while ((op = nset->cmd) != '+' && op != '-' && op != 'X') {
12276 for (setbits = clrbits = Xbits = 0;; nset++) {
12277 if ((op = nset->cmd) == '-') {
12278 clrbits |= nset->bits;
12279 setbits &= ~nset->bits;
12280 Xbits &= ~nset->bits;
12281 } else if (op == '+') {
12282 setbits |= nset->bits;
12283 clrbits &= ~nset->bits;
12284 Xbits &= ~nset->bits;
12285 } else if (op == 'X')
12286 Xbits |= nset->bits & ~setbits;
12293 set->bits = clrbits;
12299 set->bits = setbits;
12311 static void shtree (union node *, int, char *, FILE*);
12312 static void shcmd (union node *, FILE *);
12313 static void sharg (union node *, FILE *);
12314 static void indent (int, char *, FILE *);
12315 static void trstring (char *);
12322 trputs("showtree called\n");
12323 shtree(n, 1, NULL, stdout);
12328 shtree(n, ind, pfx, fp)
12334 struct nodelist *lp;
12340 indent(ind, pfx, fp);
12351 shtree(n->nbinary.ch1, ind, NULL, fp);
12354 shtree(n->nbinary.ch2, ind, NULL, fp);
12362 for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
12367 if (n->npipe.backgnd)
12373 fprintf(fp, "<node type %d>", n->type);
12393 for (np = cmd->ncmd.args ; np ; np = np->narg.next) {
12399 for (np = cmd->ncmd.redirect ; np ; np = np->nfile.next) {
12402 switch (np->nfile.type) {
12403 case NTO: s = ">"; dftfd = 1; break;
12404 case NAPPEND: s = ">>"; dftfd = 1; break;
12405 case NTOFD: s = ">&"; dftfd = 1; break;
12406 case NTOOV: s = ">|"; dftfd = 1; break;
12407 case NFROM: s = "<"; dftfd = 0; break;
12408 case NFROMFD: s = "<&"; dftfd = 0; break;
12409 case NFROMTO: s = "<>"; dftfd = 0; break;
12410 default: s = "*error*"; dftfd = 0; break;
12412 if (np->nfile.fd != dftfd)
12413 fprintf(fp, "%d", np->nfile.fd);
12415 if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) {
12416 fprintf(fp, "%d", np->ndup.dupfd);
12418 sharg(np->nfile.fname, fp);
12432 struct nodelist *bqlist;
12435 if (arg->type != NARG) {
12436 printf("<node type %d>\n", arg->type);
12440 bqlist = arg->narg.backquote;
12441 for (p = arg->narg.text ; *p ; p++) {
12450 if (subtype == VSLENGTH)
12456 if (subtype & VSNUL)
12459 switch (subtype & VSTYPE) {
12478 case VSTRIMLEFTMAX:
12485 case VSTRIMRIGHTMAX:
12492 printf("<subtype %d>", subtype);
12499 case CTLBACKQ|CTLQUOTE:
12502 shtree(bqlist->n, -1, NULL, fp);
12514 indent(amount, pfx, fp)
12521 for (i = 0 ; i < amount ; i++) {
12522 if (pfx && i == amount - 1)
12540 static int debug = 1;
12542 static int debug = 0;
12550 if (tracefile == NULL)
12552 putc(c, tracefile);
12558 trace(const char *fmt, ...)
12566 fmt = va_arg(va, char *);
12568 if (tracefile != NULL) {
12569 (void) vfprintf(tracefile, fmt, va);
12570 if (strchr(fmt, '\n'))
12571 (void) fflush(tracefile);
12581 if (tracefile == NULL)
12583 fputs(s, tracefile);
12584 if (strchr(s, '\n'))
12596 if (tracefile == NULL)
12598 putc('"', tracefile);
12599 for (p = s ; *p ; p++) {
12601 case '\n': c = 'n'; goto backslash;
12602 case '\t': c = 't'; goto backslash;
12603 case '\r': c = 'r'; goto backslash;
12604 case '"': c = '"'; goto backslash;
12605 case '\\': c = '\\'; goto backslash;
12606 case CTLESC: c = 'e'; goto backslash;
12607 case CTLVAR: c = 'v'; goto backslash;
12608 case CTLVAR+CTLQUOTE: c = 'V'; goto backslash;
12609 case CTLBACKQ: c = 'q'; goto backslash;
12610 case CTLBACKQ+CTLQUOTE: c = 'Q'; goto backslash;
12611 backslash: putc('\\', tracefile);
12612 putc(c, tracefile);
12615 if (*p >= ' ' && *p <= '~')
12616 putc(*p, tracefile);
12618 putc('\\', tracefile);
12619 putc(*p >> 6 & 03, tracefile);
12620 putc(*p >> 3 & 07, tracefile);
12621 putc(*p & 07, tracefile);
12626 putc('"', tracefile);
12634 if (tracefile == NULL)
12639 putc(' ', tracefile);
12641 putc('\n', tracefile);
12656 #ifdef not_this_way
12659 if ((p = getenv("HOME")) == NULL) {
12660 if (geteuid() == 0)
12666 strcat(s, "/trace");
12669 strcpy(s, "./trace");
12670 #endif /* not_this_way */
12671 if ((tracefile = fopen(s, "a")) == NULL) {
12672 fprintf(stderr, "Can't open %s\n", s);
12676 if ((flags = fcntl(fileno(tracefile), F_GETFL, 0)) >= 0)
12677 fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND);
12679 fputs("\nTracing started.\n", tracefile);
12686 * The trap builtin.
12690 trapcmd(argc, argv)
12699 for (signo = 0 ; signo < NSIG ; signo++) {
12700 if (trap[signo] != NULL) {
12703 p = single_quote(trap[signo]);
12704 out1fmt("trap -- %s %s\n", p,
12705 signal_names[signo] + (signo ? 3 : 0)
12718 if ((signo = decode_signal(*ap, 0)) < 0)
12719 error("%s: bad trap", *ap);
12722 if (action[0] == '-' && action[1] == '\0')
12725 action = savestr(action);
12728 ckfree(trap[signo]);
12729 trap[signo] = action;
12744 * Set the signal handler for the specified signal. The routine figures
12745 * out what it should be set to.
12749 setsignal(int signo)
12753 struct sigaction act;
12755 if ((t = trap[signo]) == NULL)
12757 else if (*t != '\0')
12761 if (rootshell && action == S_DFL) {
12764 if (iflag || minusc || sflag == 0)
12790 t = &sigmode[signo - 1];
12793 * current setting unknown
12795 if (sigaction(signo, 0, &act) == -1) {
12797 * Pretend it worked; maybe we should give a warning
12798 * here, but other shells don't. We don't alter
12799 * sigmode, so that we retry every time.
12803 if (act.sa_handler == SIG_IGN) {
12804 if (mflag && (signo == SIGTSTP ||
12805 signo == SIGTTIN || signo == SIGTTOU)) {
12806 *t = S_IGN; /* don't hard ignore these */
12810 *t = S_RESET; /* force to be set */
12813 if (*t == S_HARD_IGN || *t == action)
12817 act.sa_handler = onsig;
12820 act.sa_handler = SIG_IGN;
12823 act.sa_handler = SIG_DFL;
12827 sigemptyset(&act.sa_mask);
12828 sigaction(signo, &act, 0);
12839 if (sigmode[signo - 1] != S_IGN && sigmode[signo - 1] != S_HARD_IGN) {
12840 signal(signo, SIG_IGN);
12842 sigmode[signo - 1] = S_HARD_IGN;
12853 if (signo == SIGINT && trap[SIGINT] == NULL) {
12857 gotsig[signo - 1] = 1;
12863 * Called to execute a trap. Perhaps we should avoid entering new trap
12864 * handlers while we are executing a trap handler.
12874 for (i = 1 ; ; i++) {
12881 savestatus=exitstatus;
12882 evalstring(trap[i], 0);
12883 exitstatus=savestatus;
12890 * Called to exit the shell.
12894 exitshell(int status)
12896 struct jmploc loc1, loc2;
12899 TRACE(("exitshell(%d) pid=%d\n", status, getpid()));
12900 if (setjmp(loc1.loc)) {
12903 if (setjmp(loc2.loc)) {
12907 if ((p = trap[0]) != NULL && *p != '\0') {
12911 l1: handler = &loc2; /* probably unnecessary */
12920 static int decode_signal(const char *string, int minsig)
12924 if (is_number(string, &signo)) {
12925 if (signo >= NSIG) {
12935 for (; signo < NSIG; signo++) {
12936 if (!strcasecmp(string, &(signal_names[signo])[3])) {
12940 if (!strcasecmp(string, signal_names[signo])) {
12947 static struct var **hashvar (const char *);
12948 static void showvars (const char *, int, int);
12949 static struct var **findvar (struct var **, const char *);
12952 * Initialize the varable symbol tables and import the environment
12956 * This routine initializes the builtin variables. It is called when the
12957 * shell is initialized and again when a shell procedure is spawned.
12962 const struct varinit *ip;
12966 for (ip = varinit ; (vp = ip->var) != NULL ; ip++) {
12967 if ((vp->flags & VEXPORT) == 0) {
12968 vpp = hashvar(ip->text);
12971 vp->text = strdup(ip->text);
12972 vp->flags = ip->flags;
12973 vp->func = ip->func;
12977 * PS1 depends on uid
12979 if ((vps1.flags & VEXPORT) == 0) {
12980 vpp = hashvar("PS1=");
12983 vps1.text = strdup(geteuid() ? "PS1=$ " : "PS1=# ");
12984 vps1.flags = VSTRFIXED|VTEXTFIXED;
12989 * Set the value of a variable. The flags argument is ored with the
12990 * flags of the variable. If val is NULL, the variable is unset.
12994 setvar(name, val, flags)
12995 const char *name, *val;
13011 if (! is_in_name(*p)) {
13012 if (*p == '\0' || *p == '=')
13018 namelen = p - name;
13020 error("%.*s: bad variable name", namelen, name);
13021 len = namelen + 2; /* 2 is space for '=' and '\0' */
13025 len += vallen = strlen(val);
13028 nameeq = ckmalloc(len);
13029 memcpy(nameeq, name, namelen);
13030 nameeq[namelen] = '=';
13032 memcpy(nameeq + namelen + 1, val, vallen + 1);
13034 nameeq[namelen + 1] = '\0';
13036 setvareq(nameeq, flags);
13043 * Same as setvar except that the variable and value are passed in
13044 * the first argument as name=value. Since the first argument will
13045 * be actually stored in the table, it should not be a string that
13054 struct var *vp, **vpp;
13057 flags |= (VEXPORT & (((unsigned) (1 - aflag)) - 1));
13058 if ((vp = *findvar(vpp, s))) {
13059 if (vp->flags & VREADONLY) {
13060 size_t len = strchr(s, '=') - s;
13061 error("%.*s: is read only", len, s);
13065 if (vp->func && (flags & VNOFUNC) == 0)
13066 (*vp->func)(strchr(s, '=') + 1);
13068 if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0)
13071 vp->flags &= ~(VTEXTFIXED|VSTACK|VUNSET);
13072 vp->flags |= flags;
13076 * We could roll this to a function, to handle it as
13077 * a regular variable function callback, but why bother?
13079 if (iflag && (vp == &vmpath || (vp == &vmail && !mpathset())))
13085 vp = ckmalloc(sizeof (*vp));
13096 * Process a linked list of variable assignments.
13101 struct strlist *mylist;
13103 struct strlist *lp;
13106 for (lp = mylist ; lp ; lp = lp->next) {
13107 setvareq(savestr(lp->text), 0);
13115 * Find the value of a variable. Returns NULL if not set.
13124 if ((v = *findvar(hashvar(name), name)) && !(v->flags & VUNSET)) {
13125 return strchr(v->text, '=') + 1;
13133 * Search the environment of a builtin command.
13140 struct strlist *sp;
13142 for (sp = cmdenviron ; sp ; sp = sp->next) {
13143 if (varequal(sp->text, name))
13144 return strchr(sp->text, '=') + 1;
13146 return lookupvar(name);
13152 * Generate a list of exported variables. This routine is used to construct
13153 * the third argument to execve when executing a program.
13165 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
13166 for (vp = *vpp ; vp ; vp = vp->next)
13167 if (vp->flags & VEXPORT)
13170 ep = env = stalloc((nenv + 1) * sizeof *env);
13171 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
13172 for (vp = *vpp ; vp ; vp = vp->next)
13173 if (vp->flags & VEXPORT)
13182 * Called when a shell procedure is invoked to clear out nonexported
13183 * variables. It is also necessary to reallocate variables of with
13184 * VSTACK set since these are currently allocated on the stack.
13190 struct var *vp, **prev;
13192 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
13193 for (prev = vpp ; (vp = *prev) != NULL ; ) {
13194 if ((vp->flags & VEXPORT) == 0) {
13196 if ((vp->flags & VTEXTFIXED) == 0)
13198 if ((vp->flags & VSTRFIXED) == 0)
13201 if (vp->flags & VSTACK) {
13202 vp->text = savestr(vp->text);
13203 vp->flags &=~ VSTACK;
13215 * Command to list all variables which are set. Currently this command
13216 * is invoked from the set command when the set command is called without
13221 showvarscmd(argc, argv)
13225 showvars(nullstr, VUNSET, VUNSET);
13232 * The export and readonly commands.
13236 exportcmd(argc, argv)
13243 int flag = argv[0][0] == 'r'? VREADONLY : VEXPORT;
13246 listsetvar(cmdenviron);
13247 pflag = (nextopt("p") == 'p');
13248 if (argc > 1 && !pflag) {
13249 while ((name = *argptr++) != NULL) {
13250 if ((p = strchr(name, '=')) != NULL) {
13253 if ((vp = *findvar(hashvar(name), name))) {
13258 setvar(name, p, flag);
13262 showvars(argv[0], flag, 0);
13269 * The "local" command.
13272 /* funcnest nonzero if we are currently evaluating a function */
13275 localcmd(argc, argv)
13282 error("Not in a function");
13283 while ((name = *argptr++) != NULL) {
13291 * Make a variable a local variable. When a variable is made local, it's
13292 * value and flags are saved in a localvar structure. The saved values
13293 * will be restored when the shell function returns. We handle the name
13294 * "-" as a special case.
13301 struct localvar *lvp;
13306 lvp = ckmalloc(sizeof (struct localvar));
13307 if (name[0] == '-' && name[1] == '\0') {
13309 p = ckmalloc(sizeof optet_vals);
13310 lvp->text = memcpy(p, optet_vals, sizeof optet_vals);
13313 vpp = hashvar(name);
13314 vp = *findvar(vpp, name);
13316 if (strchr(name, '='))
13317 setvareq(savestr(name), VSTRFIXED);
13319 setvar(name, NULL, VSTRFIXED);
13320 vp = *vpp; /* the new variable */
13322 lvp->flags = VUNSET;
13324 lvp->text = vp->text;
13325 lvp->flags = vp->flags;
13326 vp->flags |= VSTRFIXED|VTEXTFIXED;
13327 if (strchr(name, '='))
13328 setvareq(savestr(name), 0);
13332 lvp->next = localvars;
13339 * Called after a function returns.
13344 struct localvar *lvp;
13347 while ((lvp = localvars) != NULL) {
13348 localvars = lvp->next;
13350 if (vp == NULL) { /* $- saved */
13351 memcpy(optet_vals, lvp->text, sizeof optet_vals);
13353 } else if ((lvp->flags & (VUNSET|VSTRFIXED)) == VUNSET) {
13354 (void)unsetvar(vp->text);
13356 if ((vp->flags & VTEXTFIXED) == 0)
13358 vp->flags = lvp->flags;
13359 vp->text = lvp->text;
13367 setvarcmd(argc, argv)
13372 return unsetcmd(argc, argv);
13373 else if (argc == 3)
13374 setvar(argv[1], argv[2], 0);
13376 error("List assignment not implemented");
13382 * The unset builtin command. We unset the function before we unset the
13383 * variable to allow a function to be unset when there is a readonly variable
13384 * with the same name.
13388 unsetcmd(argc, argv)
13398 while ((i = nextopt("vf")) != '\0') {
13404 if (flg_func == 0 && flg_var == 0)
13407 for (ap = argptr; *ap ; ap++) {
13411 ret |= unsetvar(*ap);
13418 * Unset the specified variable.
13428 vpp = findvar(hashvar(s), s);
13431 if (vp->flags & VREADONLY)
13434 if (*(strchr(vp->text, '=') + 1) != '\0')
13435 setvar(s, nullstr, 0);
13436 vp->flags &= ~VEXPORT;
13437 vp->flags |= VUNSET;
13438 if ((vp->flags & VSTRFIXED) == 0) {
13439 if ((vp->flags & VTEXTFIXED) == 0)
13454 * Find the appropriate entry in the hash table from the name.
13457 static struct var **
13461 unsigned int hashval;
13463 hashval = ((unsigned char) *p) << 4;
13464 while (*p && *p != '=')
13465 hashval += (unsigned char) *p++;
13466 return &vartab[hashval % VTABSIZE];
13472 * Returns true if the two strings specify the same varable. The first
13473 * variable name is terminated by '='; the second may be terminated by
13474 * either '=' or '\0'.
13481 while (*p == *q++) {
13485 if (*p == '=' && *(q - 1) == '\0')
13491 showvars(const char *myprefix, int mask, int xor)
13495 const char *sep = myprefix == nullstr ? myprefix : spcstr;
13497 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
13498 for (vp = *vpp ; vp ; vp = vp->next) {
13499 if ((vp->flags & mask) ^ xor) {
13503 p = strchr(vp->text, '=') + 1;
13504 len = p - vp->text;
13505 p = single_quote(p);
13508 "%s%s%.*s%s\n", myprefix, sep, len,
13517 static struct var **
13518 findvar(struct var **vpp, const char *name)
13520 for (; *vpp; vpp = &(*vpp)->next) {
13521 if (varequal((*vpp)->text, name)) {
13529 * Copyright (c) 1999 Herbert Xu <herbert@debian.org>
13530 * This file contains code for the times builtin.
13531 * $Id: ash.c,v 1.5 2001/07/05 05:24:12 andersen Exp $
13533 static int timescmd (int argc, char **argv)
13536 long int clk_tck = sysconf(_SC_CLK_TCK);
13539 printf("%dm%fs %dm%fs\n%dm%fs %dm%fs\n",
13540 (int) (buf.tms_utime / clk_tck / 60),
13541 ((double) buf.tms_utime) / clk_tck,
13542 (int) (buf.tms_stime / clk_tck / 60),
13543 ((double) buf.tms_stime) / clk_tck,
13544 (int) (buf.tms_cutime / clk_tck / 60),
13545 ((double) buf.tms_cutime) / clk_tck,
13546 (int) (buf.tms_cstime / clk_tck / 60),
13547 ((double) buf.tms_cstime) / clk_tck);
13553 * Copyright (c) 1989, 1991, 1993, 1994
13554 * The Regents of the University of California. All rights reserved.
13556 * This code is derived from software contributed to Berkeley by
13557 * Kenneth Almquist.
13559 * Redistribution and use in source and binary forms, with or without
13560 * modification, are permitted provided that the following conditions
13562 * 1. Redistributions of source code must retain the above copyright
13563 * notice, this list of conditions and the following disclaimer.
13564 * 2. Redistributions in binary form must reproduce the above copyright
13565 * notice, this list of conditions and the following disclaimer in the
13566 * documentation and/or other materials provided with the distribution.
13568 * 3. <BSD Advertising Clause omitted per the July 22, 1999 licensing change
13569 * ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change>
13571 * 4. Neither the name of the University nor the names of its contributors
13572 * may be used to endorse or promote products derived from this software
13573 * without specific prior written permission.
13575 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
13576 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
13577 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
13578 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
13579 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
13580 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
13581 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
13582 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
13583 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
13584 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF