1 /* vi: set sw=4 ts=4: */
3 * ash shell port for busybox
5 * Copyright (c) 1989, 1991, 1993, 1994
6 * The Regents of the University of California. All rights reserved.
8 * Copyright (c) 1997-2005 Herbert Xu <herbert@gondor.apana.org.au>
9 * was re-ported from NetBSD and debianized.
12 * This code is derived from software contributed to Berkeley by
15 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
17 * Original BSD copyright notice is retained at the end of this file.
21 * rewrite arith.y to micro stack based cryptic algorithm by
22 * Copyright (c) 2001 Aaron Lehmann <aaronl@vitelus.com>
24 * Modified by Paul Mundt <lethal@linux-sh.org> (c) 2004 to support
27 * Modified by Vladimir Oleynik <dzo@simtreas.ru> (c) 2001-2005 to be
28 * used in busybox and size optimizations,
29 * rewrote arith (see notes to this), added locale support,
30 * rewrote dynamic variables.
36 * The follow should be set to reflect the type of system you have:
37 * JOBS -> 1 if you have Berkeley job control, 0 otherwise.
38 * define SYSV if you are running under System V.
39 * define DEBUG=1 to compile in debugging ('set -o debug' to turn on)
40 * define DEBUG=2 to compile in and turn on debugging.
42 * When debugging is on, debugging info will be written to ./trace and
43 * a quit signal will generate a core dump.
56 #include <sys/types.h>
57 #include <sys/ioctl.h>
58 #include <sys/param.h>
59 #include <sys/resource.h>
88 #ifdef CONFIG_ASH_JOB_CONTROL
94 #if JOBS || defined(CONFIG_ASH_READ_NCHARS)
102 static int *dash_errno;
104 #define errno (*dash_errno)
107 #if defined(__uClinux__)
108 #error "Do not even bother, ash will not run on uClinux"
112 #define _DIAGASSERT(assert_expr) assert(assert_expr)
114 #define _DIAGASSERT(assert_expr)
118 #ifdef CONFIG_ASH_ALIAS
131 static struct alias *lookupalias(const char *, int);
132 static int aliascmd(int, char **);
133 static int unaliascmd(int, char **);
134 static void rmaliases(void);
135 static int unalias(const char *);
136 static void printalias(const struct alias *);
142 static void setpwd(const char *, int);
148 * Types of operations (passed to the errmsg routine).
152 static const char not_found_msg[] = "%s: not found";
155 #define E_OPEN "No such file" /* opening a file */
156 #define E_CREAT "Directory nonexistent" /* creating a file */
157 #define E_EXEC not_found_msg+4 /* executing a program */
160 * We enclose jmp_buf in a structure so that we can declare pointers to
161 * jump locations. The global variable handler contains the location to
162 * jump to when an exception occurs, and the global variable exception
163 * contains a code identifying the exception. To implement nested
164 * exception handlers, the user should save the value of handler on entry
165 * to an inner scope, set handler to point to a jmploc structure for the
166 * inner scope, and restore handler on exit from the scope.
173 static struct jmploc *handler;
174 static int exception;
175 static volatile int suppressint;
176 static volatile sig_atomic_t intpending;
179 #define EXINT 0 /* SIGINT received */
180 #define EXERROR 1 /* a generic error */
181 #define EXSHELLPROC 2 /* execute a shell procedure */
182 #define EXEXEC 3 /* command execution failed */
183 #define EXEXIT 4 /* exit the shell */
184 #define EXSIG 5 /* trapped signal in wait(1) */
187 /* do we generate EXSIG events */
189 /* last pending signal */
190 static volatile sig_atomic_t pendingsigs;
193 * These macros allow the user to suspend the handling of interrupt signals
194 * over a period of time. This is similar to SIGHOLD to or sigblock, but
195 * much more efficient and portable. (But hacking the kernel is so much
196 * more fun than worrying about efficiency and portability. :-))
199 #define xbarrier() ({ __asm__ __volatile__ ("": : :"memory"); })
206 #define SAVEINT(v) ((v) = suppressint)
207 #define RESTOREINT(v) \
210 if ((suppressint = (v)) == 0 && intpending) onint(); \
221 /* EXSIG is turned off by evalbltin(). */
224 static void exraise(int) ATTRIBUTE_NORETURN;
225 static void onint(void) ATTRIBUTE_NORETURN;
227 static void sh_error(const char *, ...) ATTRIBUTE_NORETURN;
228 static void exerror(int, const char *, ...) ATTRIBUTE_NORETURN;
230 static void sh_warnx(const char *, ...);
232 #ifdef CONFIG_ASH_OPTIMIZE_FOR_SIZE
235 if (--suppressint == 0 && intpending) {
239 #define INTON inton()
240 static void forceinton(void)
246 #define FORCEINTON forceinton()
251 if (--suppressint == 0 && intpending) onint(); \
258 if (intpending) onint(); \
261 #endif /* CONFIG_ASH_OPTIMIZE_FOR_SIZE */
266 struct strlist *next;
272 struct strlist *list;
273 struct strlist **lastp;
279 #define EXP_FULL 0x1 /* perform word splitting & file globbing */
280 #define EXP_TILDE 0x2 /* do normal tilde expansion */
281 #define EXP_VARTILDE 0x4 /* expand tildes in an assignment */
282 #define EXP_REDIR 0x8 /* file glob for a redirection (1 match only) */
283 #define EXP_CASE 0x10 /* keeps quotes around for CASE pattern */
284 #define EXP_RECORD 0x20 /* need to record arguments for ifs breakup */
285 #define EXP_VARTILDE2 0x40 /* expand tildes after colons only */
286 #define EXP_WORD 0x80 /* expand word in parameter expansion */
287 #define EXP_QWORD 0x100 /* expand word in quoted parameter expansion */
291 static void expandarg(union node *, struct arglist *, int);
292 #define rmescapes(p) _rmescapes((p), 0)
293 static char *_rmescapes(char *, int);
294 static int casematch(union node *, char *);
296 #ifdef CONFIG_ASH_MATH_SUPPORT
297 static void expari(int);
302 static char *commandname; /* currently executing command */
303 static struct strlist *cmdenviron; /* environment for builtin command */
304 static int exitstatus; /* exit status of last command */
305 static int back_exitstatus; /* exit status of backquoted command */
308 struct backcmd { /* result of evalbackcmd */
309 int fd; /* file descriptor to read from */
310 char *buf; /* buffer */
311 int nleft; /* number of chars in buffer */
312 struct job *jp; /* job structure for command */
316 * This file was generated by the mknodes program.
352 union node *redirect;
359 struct nodelist *cmdlist;
366 union node *redirect;
381 union node *elsepart;
412 struct nodelist *backquote;
452 struct nredir nredir;
453 struct nbinary nbinary;
457 struct nclist nclist;
467 struct nodelist *next;
478 static void freefunc(struct funcnode *);
481 /* control characters in argument strings */
482 #define CTL_FIRST '\201' /* first 'special' character */
483 #define CTLESC '\201' /* escape next character */
484 #define CTLVAR '\202' /* variable defn */
485 #define CTLENDVAR '\203'
486 #define CTLBACKQ '\204'
487 #define CTLQUOTE 01 /* ored with CTLBACKQ code if in quotes */
488 /* CTLBACKQ | CTLQUOTE == '\205' */
489 #define CTLARI '\206' /* arithmetic expression */
490 #define CTLENDARI '\207'
491 #define CTLQUOTEMARK '\210'
492 #define CTL_LAST '\210' /* last 'special' character */
494 /* variable substitution byte (follows CTLVAR) */
495 #define VSTYPE 0x0f /* type of variable substitution */
496 #define VSNUL 0x10 /* colon--treat the empty string as unset */
497 #define VSQUOTE 0x80 /* inside double quotes--suppress splitting */
499 /* values of VSTYPE field */
500 #define VSNORMAL 0x1 /* normal variable: $var or ${var} */
501 #define VSMINUS 0x2 /* ${var-text} */
502 #define VSPLUS 0x3 /* ${var+text} */
503 #define VSQUESTION 0x4 /* ${var?message} */
504 #define VSASSIGN 0x5 /* ${var=text} */
505 #define VSTRIMRIGHT 0x6 /* ${var%pattern} */
506 #define VSTRIMRIGHTMAX 0x7 /* ${var%%pattern} */
507 #define VSTRIMLEFT 0x8 /* ${var#pattern} */
508 #define VSTRIMLEFTMAX 0x9 /* ${var##pattern} */
509 #define VSLENGTH 0xa /* ${#var} */
511 /* values of checkkwd variable */
516 #define IBUFSIZ (BUFSIZ + 1)
519 * NEOF is returned by parsecmd when it encounters an end of file. It
520 * must be distinct from NULL, so we use the address of a variable that
521 * happens to be handy.
523 static int plinno = 1; /* input line number */
525 /* number of characters left in input buffer */
526 static int parsenleft; /* copy of parsefile->nleft */
527 static int parselleft; /* copy of parsefile->lleft */
529 /* next character in input buffer */
530 static char *parsenextc; /* copy of parsefile->nextc */
533 struct strpush *prev; /* preceding string on stack */
536 #ifdef CONFIG_ASH_ALIAS
537 struct alias *ap; /* if push was associated with an alias */
539 char *string; /* remember the string since it may change */
543 struct parsefile *prev; /* preceding file on stack */
544 int linno; /* current line */
545 int fd; /* file descriptor (or -1 if string) */
546 int nleft; /* number of chars left in this line */
547 int lleft; /* number of chars left in this buffer */
548 char *nextc; /* next char in buffer */
549 char *buf; /* input buffer */
550 struct strpush *strpush; /* for pushing strings at this level */
551 struct strpush basestrpush; /* so pushing one is fast */
554 static struct parsefile basepf; /* top level input file */
555 #define basebuf bb_common_bufsiz1 /* buffer for top level input file */
556 static struct parsefile *parsefile = &basepf; /* current input file */
559 static int tokpushback; /* last token pushed back */
560 #define NEOF ((union node *)&tokpushback)
561 static int parsebackquote; /* nonzero if we are inside backquotes */
562 static int doprompt; /* if set, prompt the user */
563 static int needprompt; /* true if interactive and at start of line */
564 static int lasttoken; /* last token read */
565 static char *wordtext; /* text of last word returned by readtoken */
567 static struct nodelist *backquotelist;
568 static union node *redirnode;
569 static struct heredoc *heredoc;
570 static int quoteflag; /* set if (part of) last token was quoted */
571 static int startlinno; /* line # where last token started */
573 static union node *parsecmd(int);
574 static void fixredir(union node *, const char *, int);
575 static const char *const *findkwd(const char *);
576 static char *endofname(const char *);
580 typedef void *pointer;
582 static char nullstr[1]; /* zero length string */
583 static const char spcstr[] = " ";
584 static const char snlfmt[] = "%s\n";
585 static const char dolatstr[] = { CTLVAR, VSNORMAL|VSQUOTE, '@', '=', '\0' };
586 static const char illnum[] = "Illegal number: %s";
587 static const char homestr[] = "HOME";
590 #define TRACE(param) trace param
591 #define TRACEV(param) tracev param
594 #define TRACEV(param)
597 #if !defined(__GNUC__) || (__GNUC__ == 2 && __GNUC_MINOR__ < 96)
598 #define __builtin_expect(x, expected_value) (x)
601 #define xlikely(x) __builtin_expect((x),1)
616 #define TENDBQUOTE 12
634 /* first char is indicating which tokens mark the end of a list */
635 static const char *const tokname_array[] = {
650 /* the following are keywords */
669 static const char *tokname(int tok)
675 sprintf(buf + (tok >= TSEMI), "%s%c",
676 tokname_array[tok] + 1, (tok >= TSEMI ? '"' : 0));
683 * Most machines require the value returned from malloc to be aligned
684 * in some way. The following macro will get this right on many machines.
687 #define SHELL_SIZE (sizeof(union {int i; char *cp; double d; }) - 1)
689 * It appears that grabstackstr() will barf with such alignments
690 * because stalloc() will return a string allocated in a new stackblock.
692 #define SHELL_ALIGN(nbytes) (((nbytes) + SHELL_SIZE) & ~SHELL_SIZE)
695 * This file was generated by the mksyntax program.
700 #define CWORD 0 /* character is nothing special */
701 #define CNL 1 /* newline character */
702 #define CBACK 2 /* a backslash character */
703 #define CSQUOTE 3 /* single quote */
704 #define CDQUOTE 4 /* double quote */
705 #define CENDQUOTE 5 /* a terminating quote */
706 #define CBQUOTE 6 /* backwards single quote */
707 #define CVAR 7 /* a dollar sign */
708 #define CENDVAR 8 /* a '}' character */
709 #define CLP 9 /* a left paren in arithmetic */
710 #define CRP 10 /* a right paren in arithmetic */
711 #define CENDFILE 11 /* end of file */
712 #define CCTL 12 /* like CWORD, except it must be escaped */
713 #define CSPCL 13 /* these terminate a word */
714 #define CIGN 14 /* character should be ignored */
716 #ifdef CONFIG_ASH_ALIAS
720 #define PEOA_OR_PEOF PEOA
724 #define PEOA_OR_PEOF PEOF
727 #define is_digit(c) ((unsigned)((c) - '0') <= 9)
728 #define is_name(c) ((c) == '_' || isalpha((unsigned char)(c)))
729 #define is_in_name(c) ((c) == '_' || isalnum((unsigned char)(c)))
732 * is_special(c) evaluates to 1 for c in "!#$*-0123456789?@"; 0 otherwise
733 * (assuming ascii char codes, as the original implementation did)
735 #define is_special(c) \
736 ( (((unsigned int)c) - 33 < 32) \
737 && ((0xc1ff920dUL >> (((unsigned int)c) - 33)) & 1))
739 #define digit_val(c) ((c) - '0')
742 * This file was generated by the mksyntax program.
745 #ifdef CONFIG_ASH_OPTIMIZE_FOR_SIZE
746 #define USE_SIT_FUNCTION
749 /* number syntax index */
750 #define BASESYNTAX 0 /* not in quotes */
751 #define DQSYNTAX 1 /* in double quotes */
752 #define SQSYNTAX 2 /* in single quotes */
753 #define ARISYNTAX 3 /* in arithmetic */
755 #ifdef CONFIG_ASH_MATH_SUPPORT
756 static const char S_I_T[][4] = {
757 #ifdef CONFIG_ASH_ALIAS
758 {CSPCL, CIGN, CIGN, CIGN}, /* 0, PEOA */
760 {CSPCL, CWORD, CWORD, CWORD}, /* 1, ' ' */
761 {CNL, CNL, CNL, CNL}, /* 2, \n */
762 {CWORD, CCTL, CCTL, CWORD}, /* 3, !*-/:=?[]~ */
763 {CDQUOTE, CENDQUOTE, CWORD, CWORD}, /* 4, '"' */
764 {CVAR, CVAR, CWORD, CVAR}, /* 5, $ */
765 {CSQUOTE, CWORD, CENDQUOTE, CWORD}, /* 6, "'" */
766 {CSPCL, CWORD, CWORD, CLP}, /* 7, ( */
767 {CSPCL, CWORD, CWORD, CRP}, /* 8, ) */
768 {CBACK, CBACK, CCTL, CBACK}, /* 9, \ */
769 {CBQUOTE, CBQUOTE, CWORD, CBQUOTE}, /* 10, ` */
770 {CENDVAR, CENDVAR, CWORD, CENDVAR}, /* 11, } */
771 #ifndef USE_SIT_FUNCTION
772 {CENDFILE, CENDFILE, CENDFILE, CENDFILE}, /* 12, PEOF */
773 {CWORD, CWORD, CWORD, CWORD}, /* 13, 0-9A-Za-z */
774 {CCTL, CCTL, CCTL, CCTL} /* 14, CTLESC ... */
778 static const char S_I_T[][3] = {
779 #ifdef CONFIG_ASH_ALIAS
780 {CSPCL, CIGN, CIGN}, /* 0, PEOA */
782 {CSPCL, CWORD, CWORD}, /* 1, ' ' */
783 {CNL, CNL, CNL}, /* 2, \n */
784 {CWORD, CCTL, CCTL}, /* 3, !*-/:=?[]~ */
785 {CDQUOTE, CENDQUOTE, CWORD}, /* 4, '"' */
786 {CVAR, CVAR, CWORD}, /* 5, $ */
787 {CSQUOTE, CWORD, CENDQUOTE}, /* 6, "'" */
788 {CSPCL, CWORD, CWORD}, /* 7, ( */
789 {CSPCL, CWORD, CWORD}, /* 8, ) */
790 {CBACK, CBACK, CCTL}, /* 9, \ */
791 {CBQUOTE, CBQUOTE, CWORD}, /* 10, ` */
792 {CENDVAR, CENDVAR, CWORD}, /* 11, } */
793 #ifndef USE_SIT_FUNCTION
794 {CENDFILE, CENDFILE, CENDFILE}, /* 12, PEOF */
795 {CWORD, CWORD, CWORD}, /* 13, 0-9A-Za-z */
796 {CCTL, CCTL, CCTL} /* 14, CTLESC ... */
799 #endif /* CONFIG_ASH_MATH_SUPPORT */
801 #ifdef USE_SIT_FUNCTION
803 #define U_C(c) ((unsigned char)(c))
805 static int SIT(int c, int syntax)
807 static const char spec_symbls[] = "\t\n !\"$&'()*-/:;<=>?[\\]`|}~";
808 #ifdef CONFIG_ASH_ALIAS
809 static const char syntax_index_table[] = {
810 1, 2, 1, 3, 4, 5, 1, 6, /* "\t\n !\"$&'" */
811 7, 8, 3, 3, 3, 3, 1, 1, /* "()*-/:;<" */
812 3, 1, 3, 3, 9, 3, 10, 1, /* "=>?[\\]`|" */
816 static const char syntax_index_table[] = {
817 0, 1, 0, 2, 3, 4, 0, 5, /* "\t\n !\"$&'" */
818 6, 7, 2, 2, 2, 2, 0, 0, /* "()*-/:;<" */
819 2, 0, 2, 2, 8, 2, 9, 0, /* "=>?[\\]`|" */
826 if (c == PEOF) /* 2^8+2 */
828 #ifdef CONFIG_ASH_ALIAS
829 if (c == PEOA) /* 2^8+1 */
833 if (U_C(c) >= U_C(CTLESC) && U_C(c) <= U_C(CTLQUOTEMARK))
836 s = strchr(spec_symbls, c);
837 if (s == 0 || *s == 0)
839 indx = syntax_index_table[(s - spec_symbls)];
841 return S_I_T[indx][syntax];
844 #else /* USE_SIT_FUNCTION */
846 #define SIT(c, syntax) S_I_T[(int)syntax_index_table[((int)c)+SYNBASE]][syntax]
848 #ifdef CONFIG_ASH_ALIAS
849 #define CSPCL_CIGN_CIGN_CIGN 0
850 #define CSPCL_CWORD_CWORD_CWORD 1
851 #define CNL_CNL_CNL_CNL 2
852 #define CWORD_CCTL_CCTL_CWORD 3
853 #define CDQUOTE_CENDQUOTE_CWORD_CWORD 4
854 #define CVAR_CVAR_CWORD_CVAR 5
855 #define CSQUOTE_CWORD_CENDQUOTE_CWORD 6
856 #define CSPCL_CWORD_CWORD_CLP 7
857 #define CSPCL_CWORD_CWORD_CRP 8
858 #define CBACK_CBACK_CCTL_CBACK 9
859 #define CBQUOTE_CBQUOTE_CWORD_CBQUOTE 10
860 #define CENDVAR_CENDVAR_CWORD_CENDVAR 11
861 #define CENDFILE_CENDFILE_CENDFILE_CENDFILE 12
862 #define CWORD_CWORD_CWORD_CWORD 13
863 #define CCTL_CCTL_CCTL_CCTL 14
865 #define CSPCL_CWORD_CWORD_CWORD 0
866 #define CNL_CNL_CNL_CNL 1
867 #define CWORD_CCTL_CCTL_CWORD 2
868 #define CDQUOTE_CENDQUOTE_CWORD_CWORD 3
869 #define CVAR_CVAR_CWORD_CVAR 4
870 #define CSQUOTE_CWORD_CENDQUOTE_CWORD 5
871 #define CSPCL_CWORD_CWORD_CLP 6
872 #define CSPCL_CWORD_CWORD_CRP 7
873 #define CBACK_CBACK_CCTL_CBACK 8
874 #define CBQUOTE_CBQUOTE_CWORD_CBQUOTE 9
875 #define CENDVAR_CENDVAR_CWORD_CENDVAR 10
876 #define CENDFILE_CENDFILE_CENDFILE_CENDFILE 11
877 #define CWORD_CWORD_CWORD_CWORD 12
878 #define CCTL_CCTL_CCTL_CCTL 13
881 static const char syntax_index_table[258] = {
882 /* BASESYNTAX_DQSYNTAX_SQSYNTAX_ARISYNTAX */
883 /* 0 PEOF */ CENDFILE_CENDFILE_CENDFILE_CENDFILE,
884 #ifdef CONFIG_ASH_ALIAS
885 /* 1 PEOA */ CSPCL_CIGN_CIGN_CIGN,
887 /* 2 -128 0x80 */ CWORD_CWORD_CWORD_CWORD,
888 /* 3 -127 CTLESC */ CCTL_CCTL_CCTL_CCTL,
889 /* 4 -126 CTLVAR */ CCTL_CCTL_CCTL_CCTL,
890 /* 5 -125 CTLENDVAR */ CCTL_CCTL_CCTL_CCTL,
891 /* 6 -124 CTLBACKQ */ CCTL_CCTL_CCTL_CCTL,
892 /* 7 -123 CTLQUOTE */ CCTL_CCTL_CCTL_CCTL,
893 /* 8 -122 CTLARI */ CCTL_CCTL_CCTL_CCTL,
894 /* 9 -121 CTLENDARI */ CCTL_CCTL_CCTL_CCTL,
895 /* 10 -120 CTLQUOTEMARK */ CCTL_CCTL_CCTL_CCTL,
896 /* 11 -119 */ CWORD_CWORD_CWORD_CWORD,
897 /* 12 -118 */ CWORD_CWORD_CWORD_CWORD,
898 /* 13 -117 */ CWORD_CWORD_CWORD_CWORD,
899 /* 14 -116 */ CWORD_CWORD_CWORD_CWORD,
900 /* 15 -115 */ CWORD_CWORD_CWORD_CWORD,
901 /* 16 -114 */ CWORD_CWORD_CWORD_CWORD,
902 /* 17 -113 */ CWORD_CWORD_CWORD_CWORD,
903 /* 18 -112 */ CWORD_CWORD_CWORD_CWORD,
904 /* 19 -111 */ CWORD_CWORD_CWORD_CWORD,
905 /* 20 -110 */ CWORD_CWORD_CWORD_CWORD,
906 /* 21 -109 */ CWORD_CWORD_CWORD_CWORD,
907 /* 22 -108 */ CWORD_CWORD_CWORD_CWORD,
908 /* 23 -107 */ CWORD_CWORD_CWORD_CWORD,
909 /* 24 -106 */ CWORD_CWORD_CWORD_CWORD,
910 /* 25 -105 */ CWORD_CWORD_CWORD_CWORD,
911 /* 26 -104 */ CWORD_CWORD_CWORD_CWORD,
912 /* 27 -103 */ CWORD_CWORD_CWORD_CWORD,
913 /* 28 -102 */ CWORD_CWORD_CWORD_CWORD,
914 /* 29 -101 */ CWORD_CWORD_CWORD_CWORD,
915 /* 30 -100 */ CWORD_CWORD_CWORD_CWORD,
916 /* 31 -99 */ CWORD_CWORD_CWORD_CWORD,
917 /* 32 -98 */ CWORD_CWORD_CWORD_CWORD,
918 /* 33 -97 */ CWORD_CWORD_CWORD_CWORD,
919 /* 34 -96 */ CWORD_CWORD_CWORD_CWORD,
920 /* 35 -95 */ CWORD_CWORD_CWORD_CWORD,
921 /* 36 -94 */ CWORD_CWORD_CWORD_CWORD,
922 /* 37 -93 */ CWORD_CWORD_CWORD_CWORD,
923 /* 38 -92 */ CWORD_CWORD_CWORD_CWORD,
924 /* 39 -91 */ CWORD_CWORD_CWORD_CWORD,
925 /* 40 -90 */ CWORD_CWORD_CWORD_CWORD,
926 /* 41 -89 */ CWORD_CWORD_CWORD_CWORD,
927 /* 42 -88 */ CWORD_CWORD_CWORD_CWORD,
928 /* 43 -87 */ CWORD_CWORD_CWORD_CWORD,
929 /* 44 -86 */ CWORD_CWORD_CWORD_CWORD,
930 /* 45 -85 */ CWORD_CWORD_CWORD_CWORD,
931 /* 46 -84 */ CWORD_CWORD_CWORD_CWORD,
932 /* 47 -83 */ CWORD_CWORD_CWORD_CWORD,
933 /* 48 -82 */ CWORD_CWORD_CWORD_CWORD,
934 /* 49 -81 */ CWORD_CWORD_CWORD_CWORD,
935 /* 50 -80 */ CWORD_CWORD_CWORD_CWORD,
936 /* 51 -79 */ CWORD_CWORD_CWORD_CWORD,
937 /* 52 -78 */ CWORD_CWORD_CWORD_CWORD,
938 /* 53 -77 */ CWORD_CWORD_CWORD_CWORD,
939 /* 54 -76 */ CWORD_CWORD_CWORD_CWORD,
940 /* 55 -75 */ CWORD_CWORD_CWORD_CWORD,
941 /* 56 -74 */ CWORD_CWORD_CWORD_CWORD,
942 /* 57 -73 */ CWORD_CWORD_CWORD_CWORD,
943 /* 58 -72 */ CWORD_CWORD_CWORD_CWORD,
944 /* 59 -71 */ CWORD_CWORD_CWORD_CWORD,
945 /* 60 -70 */ CWORD_CWORD_CWORD_CWORD,
946 /* 61 -69 */ CWORD_CWORD_CWORD_CWORD,
947 /* 62 -68 */ CWORD_CWORD_CWORD_CWORD,
948 /* 63 -67 */ CWORD_CWORD_CWORD_CWORD,
949 /* 64 -66 */ CWORD_CWORD_CWORD_CWORD,
950 /* 65 -65 */ CWORD_CWORD_CWORD_CWORD,
951 /* 66 -64 */ CWORD_CWORD_CWORD_CWORD,
952 /* 67 -63 */ CWORD_CWORD_CWORD_CWORD,
953 /* 68 -62 */ CWORD_CWORD_CWORD_CWORD,
954 /* 69 -61 */ CWORD_CWORD_CWORD_CWORD,
955 /* 70 -60 */ CWORD_CWORD_CWORD_CWORD,
956 /* 71 -59 */ CWORD_CWORD_CWORD_CWORD,
957 /* 72 -58 */ CWORD_CWORD_CWORD_CWORD,
958 /* 73 -57 */ CWORD_CWORD_CWORD_CWORD,
959 /* 74 -56 */ CWORD_CWORD_CWORD_CWORD,
960 /* 75 -55 */ CWORD_CWORD_CWORD_CWORD,
961 /* 76 -54 */ CWORD_CWORD_CWORD_CWORD,
962 /* 77 -53 */ CWORD_CWORD_CWORD_CWORD,
963 /* 78 -52 */ CWORD_CWORD_CWORD_CWORD,
964 /* 79 -51 */ CWORD_CWORD_CWORD_CWORD,
965 /* 80 -50 */ CWORD_CWORD_CWORD_CWORD,
966 /* 81 -49 */ CWORD_CWORD_CWORD_CWORD,
967 /* 82 -48 */ CWORD_CWORD_CWORD_CWORD,
968 /* 83 -47 */ CWORD_CWORD_CWORD_CWORD,
969 /* 84 -46 */ CWORD_CWORD_CWORD_CWORD,
970 /* 85 -45 */ CWORD_CWORD_CWORD_CWORD,
971 /* 86 -44 */ CWORD_CWORD_CWORD_CWORD,
972 /* 87 -43 */ CWORD_CWORD_CWORD_CWORD,
973 /* 88 -42 */ CWORD_CWORD_CWORD_CWORD,
974 /* 89 -41 */ CWORD_CWORD_CWORD_CWORD,
975 /* 90 -40 */ CWORD_CWORD_CWORD_CWORD,
976 /* 91 -39 */ CWORD_CWORD_CWORD_CWORD,
977 /* 92 -38 */ CWORD_CWORD_CWORD_CWORD,
978 /* 93 -37 */ CWORD_CWORD_CWORD_CWORD,
979 /* 94 -36 */ CWORD_CWORD_CWORD_CWORD,
980 /* 95 -35 */ CWORD_CWORD_CWORD_CWORD,
981 /* 96 -34 */ CWORD_CWORD_CWORD_CWORD,
982 /* 97 -33 */ CWORD_CWORD_CWORD_CWORD,
983 /* 98 -32 */ CWORD_CWORD_CWORD_CWORD,
984 /* 99 -31 */ CWORD_CWORD_CWORD_CWORD,
985 /* 100 -30 */ CWORD_CWORD_CWORD_CWORD,
986 /* 101 -29 */ CWORD_CWORD_CWORD_CWORD,
987 /* 102 -28 */ CWORD_CWORD_CWORD_CWORD,
988 /* 103 -27 */ CWORD_CWORD_CWORD_CWORD,
989 /* 104 -26 */ CWORD_CWORD_CWORD_CWORD,
990 /* 105 -25 */ CWORD_CWORD_CWORD_CWORD,
991 /* 106 -24 */ CWORD_CWORD_CWORD_CWORD,
992 /* 107 -23 */ CWORD_CWORD_CWORD_CWORD,
993 /* 108 -22 */ CWORD_CWORD_CWORD_CWORD,
994 /* 109 -21 */ CWORD_CWORD_CWORD_CWORD,
995 /* 110 -20 */ CWORD_CWORD_CWORD_CWORD,
996 /* 111 -19 */ CWORD_CWORD_CWORD_CWORD,
997 /* 112 -18 */ CWORD_CWORD_CWORD_CWORD,
998 /* 113 -17 */ CWORD_CWORD_CWORD_CWORD,
999 /* 114 -16 */ CWORD_CWORD_CWORD_CWORD,
1000 /* 115 -15 */ CWORD_CWORD_CWORD_CWORD,
1001 /* 116 -14 */ CWORD_CWORD_CWORD_CWORD,
1002 /* 117 -13 */ CWORD_CWORD_CWORD_CWORD,
1003 /* 118 -12 */ CWORD_CWORD_CWORD_CWORD,
1004 /* 119 -11 */ CWORD_CWORD_CWORD_CWORD,
1005 /* 120 -10 */ CWORD_CWORD_CWORD_CWORD,
1006 /* 121 -9 */ CWORD_CWORD_CWORD_CWORD,
1007 /* 122 -8 */ CWORD_CWORD_CWORD_CWORD,
1008 /* 123 -7 */ CWORD_CWORD_CWORD_CWORD,
1009 /* 124 -6 */ CWORD_CWORD_CWORD_CWORD,
1010 /* 125 -5 */ CWORD_CWORD_CWORD_CWORD,
1011 /* 126 -4 */ CWORD_CWORD_CWORD_CWORD,
1012 /* 127 -3 */ CWORD_CWORD_CWORD_CWORD,
1013 /* 128 -2 */ CWORD_CWORD_CWORD_CWORD,
1014 /* 129 -1 */ CWORD_CWORD_CWORD_CWORD,
1015 /* 130 0 */ CWORD_CWORD_CWORD_CWORD,
1016 /* 131 1 */ CWORD_CWORD_CWORD_CWORD,
1017 /* 132 2 */ CWORD_CWORD_CWORD_CWORD,
1018 /* 133 3 */ CWORD_CWORD_CWORD_CWORD,
1019 /* 134 4 */ CWORD_CWORD_CWORD_CWORD,
1020 /* 135 5 */ CWORD_CWORD_CWORD_CWORD,
1021 /* 136 6 */ CWORD_CWORD_CWORD_CWORD,
1022 /* 137 7 */ CWORD_CWORD_CWORD_CWORD,
1023 /* 138 8 */ CWORD_CWORD_CWORD_CWORD,
1024 /* 139 9 "\t" */ CSPCL_CWORD_CWORD_CWORD,
1025 /* 140 10 "\n" */ CNL_CNL_CNL_CNL,
1026 /* 141 11 */ CWORD_CWORD_CWORD_CWORD,
1027 /* 142 12 */ CWORD_CWORD_CWORD_CWORD,
1028 /* 143 13 */ CWORD_CWORD_CWORD_CWORD,
1029 /* 144 14 */ CWORD_CWORD_CWORD_CWORD,
1030 /* 145 15 */ CWORD_CWORD_CWORD_CWORD,
1031 /* 146 16 */ CWORD_CWORD_CWORD_CWORD,
1032 /* 147 17 */ CWORD_CWORD_CWORD_CWORD,
1033 /* 148 18 */ CWORD_CWORD_CWORD_CWORD,
1034 /* 149 19 */ CWORD_CWORD_CWORD_CWORD,
1035 /* 150 20 */ CWORD_CWORD_CWORD_CWORD,
1036 /* 151 21 */ CWORD_CWORD_CWORD_CWORD,
1037 /* 152 22 */ CWORD_CWORD_CWORD_CWORD,
1038 /* 153 23 */ CWORD_CWORD_CWORD_CWORD,
1039 /* 154 24 */ CWORD_CWORD_CWORD_CWORD,
1040 /* 155 25 */ CWORD_CWORD_CWORD_CWORD,
1041 /* 156 26 */ CWORD_CWORD_CWORD_CWORD,
1042 /* 157 27 */ CWORD_CWORD_CWORD_CWORD,
1043 /* 158 28 */ CWORD_CWORD_CWORD_CWORD,
1044 /* 159 29 */ CWORD_CWORD_CWORD_CWORD,
1045 /* 160 30 */ CWORD_CWORD_CWORD_CWORD,
1046 /* 161 31 */ CWORD_CWORD_CWORD_CWORD,
1047 /* 162 32 " " */ CSPCL_CWORD_CWORD_CWORD,
1048 /* 163 33 "!" */ CWORD_CCTL_CCTL_CWORD,
1049 /* 164 34 """ */ CDQUOTE_CENDQUOTE_CWORD_CWORD,
1050 /* 165 35 "#" */ CWORD_CWORD_CWORD_CWORD,
1051 /* 166 36 "$" */ CVAR_CVAR_CWORD_CVAR,
1052 /* 167 37 "%" */ CWORD_CWORD_CWORD_CWORD,
1053 /* 168 38 "&" */ CSPCL_CWORD_CWORD_CWORD,
1054 /* 169 39 "'" */ CSQUOTE_CWORD_CENDQUOTE_CWORD,
1055 /* 170 40 "(" */ CSPCL_CWORD_CWORD_CLP,
1056 /* 171 41 ")" */ CSPCL_CWORD_CWORD_CRP,
1057 /* 172 42 "*" */ CWORD_CCTL_CCTL_CWORD,
1058 /* 173 43 "+" */ CWORD_CWORD_CWORD_CWORD,
1059 /* 174 44 "," */ CWORD_CWORD_CWORD_CWORD,
1060 /* 175 45 "-" */ CWORD_CCTL_CCTL_CWORD,
1061 /* 176 46 "." */ CWORD_CWORD_CWORD_CWORD,
1062 /* 177 47 "/" */ CWORD_CCTL_CCTL_CWORD,
1063 /* 178 48 "0" */ CWORD_CWORD_CWORD_CWORD,
1064 /* 179 49 "1" */ CWORD_CWORD_CWORD_CWORD,
1065 /* 180 50 "2" */ CWORD_CWORD_CWORD_CWORD,
1066 /* 181 51 "3" */ CWORD_CWORD_CWORD_CWORD,
1067 /* 182 52 "4" */ CWORD_CWORD_CWORD_CWORD,
1068 /* 183 53 "5" */ CWORD_CWORD_CWORD_CWORD,
1069 /* 184 54 "6" */ CWORD_CWORD_CWORD_CWORD,
1070 /* 185 55 "7" */ CWORD_CWORD_CWORD_CWORD,
1071 /* 186 56 "8" */ CWORD_CWORD_CWORD_CWORD,
1072 /* 187 57 "9" */ CWORD_CWORD_CWORD_CWORD,
1073 /* 188 58 ":" */ CWORD_CCTL_CCTL_CWORD,
1074 /* 189 59 ";" */ CSPCL_CWORD_CWORD_CWORD,
1075 /* 190 60 "<" */ CSPCL_CWORD_CWORD_CWORD,
1076 /* 191 61 "=" */ CWORD_CCTL_CCTL_CWORD,
1077 /* 192 62 ">" */ CSPCL_CWORD_CWORD_CWORD,
1078 /* 193 63 "?" */ CWORD_CCTL_CCTL_CWORD,
1079 /* 194 64 "@" */ CWORD_CWORD_CWORD_CWORD,
1080 /* 195 65 "A" */ CWORD_CWORD_CWORD_CWORD,
1081 /* 196 66 "B" */ CWORD_CWORD_CWORD_CWORD,
1082 /* 197 67 "C" */ CWORD_CWORD_CWORD_CWORD,
1083 /* 198 68 "D" */ CWORD_CWORD_CWORD_CWORD,
1084 /* 199 69 "E" */ CWORD_CWORD_CWORD_CWORD,
1085 /* 200 70 "F" */ CWORD_CWORD_CWORD_CWORD,
1086 /* 201 71 "G" */ CWORD_CWORD_CWORD_CWORD,
1087 /* 202 72 "H" */ CWORD_CWORD_CWORD_CWORD,
1088 /* 203 73 "I" */ CWORD_CWORD_CWORD_CWORD,
1089 /* 204 74 "J" */ CWORD_CWORD_CWORD_CWORD,
1090 /* 205 75 "K" */ CWORD_CWORD_CWORD_CWORD,
1091 /* 206 76 "L" */ CWORD_CWORD_CWORD_CWORD,
1092 /* 207 77 "M" */ CWORD_CWORD_CWORD_CWORD,
1093 /* 208 78 "N" */ CWORD_CWORD_CWORD_CWORD,
1094 /* 209 79 "O" */ CWORD_CWORD_CWORD_CWORD,
1095 /* 210 80 "P" */ CWORD_CWORD_CWORD_CWORD,
1096 /* 211 81 "Q" */ CWORD_CWORD_CWORD_CWORD,
1097 /* 212 82 "R" */ CWORD_CWORD_CWORD_CWORD,
1098 /* 213 83 "S" */ CWORD_CWORD_CWORD_CWORD,
1099 /* 214 84 "T" */ CWORD_CWORD_CWORD_CWORD,
1100 /* 215 85 "U" */ CWORD_CWORD_CWORD_CWORD,
1101 /* 216 86 "V" */ CWORD_CWORD_CWORD_CWORD,
1102 /* 217 87 "W" */ CWORD_CWORD_CWORD_CWORD,
1103 /* 218 88 "X" */ CWORD_CWORD_CWORD_CWORD,
1104 /* 219 89 "Y" */ CWORD_CWORD_CWORD_CWORD,
1105 /* 220 90 "Z" */ CWORD_CWORD_CWORD_CWORD,
1106 /* 221 91 "[" */ CWORD_CCTL_CCTL_CWORD,
1107 /* 222 92 "\" */ CBACK_CBACK_CCTL_CBACK,
1108 /* 223 93 "]" */ CWORD_CCTL_CCTL_CWORD,
1109 /* 224 94 "^" */ CWORD_CWORD_CWORD_CWORD,
1110 /* 225 95 "_" */ CWORD_CWORD_CWORD_CWORD,
1111 /* 226 96 "`" */ CBQUOTE_CBQUOTE_CWORD_CBQUOTE,
1112 /* 227 97 "a" */ CWORD_CWORD_CWORD_CWORD,
1113 /* 228 98 "b" */ CWORD_CWORD_CWORD_CWORD,
1114 /* 229 99 "c" */ CWORD_CWORD_CWORD_CWORD,
1115 /* 230 100 "d" */ CWORD_CWORD_CWORD_CWORD,
1116 /* 231 101 "e" */ CWORD_CWORD_CWORD_CWORD,
1117 /* 232 102 "f" */ CWORD_CWORD_CWORD_CWORD,
1118 /* 233 103 "g" */ CWORD_CWORD_CWORD_CWORD,
1119 /* 234 104 "h" */ CWORD_CWORD_CWORD_CWORD,
1120 /* 235 105 "i" */ CWORD_CWORD_CWORD_CWORD,
1121 /* 236 106 "j" */ CWORD_CWORD_CWORD_CWORD,
1122 /* 237 107 "k" */ CWORD_CWORD_CWORD_CWORD,
1123 /* 238 108 "l" */ CWORD_CWORD_CWORD_CWORD,
1124 /* 239 109 "m" */ CWORD_CWORD_CWORD_CWORD,
1125 /* 240 110 "n" */ CWORD_CWORD_CWORD_CWORD,
1126 /* 241 111 "o" */ CWORD_CWORD_CWORD_CWORD,
1127 /* 242 112 "p" */ CWORD_CWORD_CWORD_CWORD,
1128 /* 243 113 "q" */ CWORD_CWORD_CWORD_CWORD,
1129 /* 244 114 "r" */ CWORD_CWORD_CWORD_CWORD,
1130 /* 245 115 "s" */ CWORD_CWORD_CWORD_CWORD,
1131 /* 246 116 "t" */ CWORD_CWORD_CWORD_CWORD,
1132 /* 247 117 "u" */ CWORD_CWORD_CWORD_CWORD,
1133 /* 248 118 "v" */ CWORD_CWORD_CWORD_CWORD,
1134 /* 249 119 "w" */ CWORD_CWORD_CWORD_CWORD,
1135 /* 250 120 "x" */ CWORD_CWORD_CWORD_CWORD,
1136 /* 251 121 "y" */ CWORD_CWORD_CWORD_CWORD,
1137 /* 252 122 "z" */ CWORD_CWORD_CWORD_CWORD,
1138 /* 253 123 "{" */ CWORD_CWORD_CWORD_CWORD,
1139 /* 254 124 "|" */ CSPCL_CWORD_CWORD_CWORD,
1140 /* 255 125 "}" */ CENDVAR_CENDVAR_CWORD_CENDVAR,
1141 /* 256 126 "~" */ CWORD_CCTL_CCTL_CWORD,
1142 /* 257 127 */ CWORD_CWORD_CWORD_CWORD,
1145 #endif /* USE_SIT_FUNCTION */
1152 static int funcblocksize; /* size of structures in function */
1153 static int funcstringsize; /* size of strings in node */
1154 static pointer funcblock; /* block to allocate function from */
1155 static char *funcstring; /* block to allocate strings from */
1157 static const short nodesize[26] = {
1158 SHELL_ALIGN(sizeof (struct ncmd)),
1159 SHELL_ALIGN(sizeof (struct npipe)),
1160 SHELL_ALIGN(sizeof (struct nredir)),
1161 SHELL_ALIGN(sizeof (struct nredir)),
1162 SHELL_ALIGN(sizeof (struct nredir)),
1163 SHELL_ALIGN(sizeof (struct nbinary)),
1164 SHELL_ALIGN(sizeof (struct nbinary)),
1165 SHELL_ALIGN(sizeof (struct nbinary)),
1166 SHELL_ALIGN(sizeof (struct nif)),
1167 SHELL_ALIGN(sizeof (struct nbinary)),
1168 SHELL_ALIGN(sizeof (struct nbinary)),
1169 SHELL_ALIGN(sizeof (struct nfor)),
1170 SHELL_ALIGN(sizeof (struct ncase)),
1171 SHELL_ALIGN(sizeof (struct nclist)),
1172 SHELL_ALIGN(sizeof (struct narg)),
1173 SHELL_ALIGN(sizeof (struct narg)),
1174 SHELL_ALIGN(sizeof (struct nfile)),
1175 SHELL_ALIGN(sizeof (struct nfile)),
1176 SHELL_ALIGN(sizeof (struct nfile)),
1177 SHELL_ALIGN(sizeof (struct nfile)),
1178 SHELL_ALIGN(sizeof (struct nfile)),
1179 SHELL_ALIGN(sizeof (struct ndup)),
1180 SHELL_ALIGN(sizeof (struct ndup)),
1181 SHELL_ALIGN(sizeof (struct nhere)),
1182 SHELL_ALIGN(sizeof (struct nhere)),
1183 SHELL_ALIGN(sizeof (struct nnot)),
1187 static void calcsize(union node *);
1188 static void sizenodelist(struct nodelist *);
1189 static union node *copynode(union node *);
1190 static struct nodelist *copynodelist(struct nodelist *);
1191 static char *nodesavestr(char *);
1194 static int evalstring(char *, int mask);
1195 union node; /* BLETCH for ansi C */
1196 static void evaltree(union node *, int);
1197 static void evalbackcmd(union node *, struct backcmd *);
1199 static int evalskip; /* set if we are skipping commands */
1200 static int skipcount; /* number of levels to skip */
1201 static int funcnest; /* depth of function calls */
1203 /* reasons for skipping commands (see comment on breakcmd routine) */
1204 #define SKIPBREAK (1 << 0)
1205 #define SKIPCONT (1 << 1)
1206 #define SKIPFUNC (1 << 2)
1207 #define SKIPFILE (1 << 3)
1208 #define SKIPEVAL (1 << 4)
1211 * This file was generated by the mkbuiltins program.
1215 static int bgcmd(int, char **);
1217 static int breakcmd(int, char **);
1218 static int cdcmd(int, char **);
1219 #ifdef CONFIG_ASH_CMDCMD
1220 static int commandcmd(int, char **);
1222 static int dotcmd(int, char **);
1223 static int evalcmd(int, char **);
1224 #ifdef CONFIG_ASH_BUILTIN_ECHO
1225 static int echocmd(int, char **);
1227 static int execcmd(int, char **);
1228 static int exitcmd(int, char **);
1229 static int exportcmd(int, char **);
1230 static int falsecmd(int, char **);
1232 static int fgcmd(int, char **);
1234 #ifdef CONFIG_ASH_GETOPTS
1235 static int getoptscmd(int, char **);
1237 static int hashcmd(int, char **);
1238 #ifndef CONFIG_FEATURE_SH_EXTRA_QUIET
1239 static int helpcmd(int argc, char **argv);
1242 static int jobscmd(int, char **);
1244 #ifdef CONFIG_ASH_MATH_SUPPORT
1245 static int letcmd(int, char **);
1247 static int localcmd(int, char **);
1248 static int pwdcmd(int, char **);
1249 static int readcmd(int, char **);
1250 static int returncmd(int, char **);
1251 static int setcmd(int, char **);
1252 static int shiftcmd(int, char **);
1253 static int timescmd(int, char **);
1254 static int trapcmd(int, char **);
1255 static int truecmd(int, char **);
1256 static int typecmd(int, char **);
1257 static int umaskcmd(int, char **);
1258 static int unsetcmd(int, char **);
1259 static int waitcmd(int, char **);
1260 static int ulimitcmd(int, char **);
1262 static int killcmd(int, char **);
1267 #ifdef CONFIG_ASH_MAIL
1268 static void chkmail(void);
1269 static void changemail(const char *);
1274 /* values of cmdtype */
1275 #define CMDUNKNOWN -1 /* no entry in table for command */
1276 #define CMDNORMAL 0 /* command is an executable program */
1277 #define CMDFUNCTION 1 /* command is a shell function */
1278 #define CMDBUILTIN 2 /* command is a shell builtin */
1282 int (*builtin)(int, char **);
1283 /* unsigned flags; */
1287 #define COMMANDCMD (builtincmd + 5 + \
1288 ENABLE_ASH_ALIAS + ENABLE_ASH_JOB_CONTROL)
1289 #define EXECCMD (builtincmd + 7 + \
1290 ENABLE_ASH_CMDCMD + ENABLE_ASH_ALIAS + \
1291 ENABLE_ASH_BUILTIN_ECHO + ENABLE_ASH_JOB_CONTROL)
1293 #define BUILTIN_NOSPEC "0"
1294 #define BUILTIN_SPECIAL "1"
1295 #define BUILTIN_REGULAR "2"
1296 #define BUILTIN_SPEC_REG "3"
1297 #define BUILTIN_ASSIGN "4"
1298 #define BUILTIN_SPEC_ASSG "5"
1299 #define BUILTIN_REG_ASSG "6"
1300 #define BUILTIN_SPEC_REG_ASSG "7"
1302 #define IS_BUILTIN_SPECIAL(builtincmd) ((builtincmd)->name[0] & 1)
1303 #define IS_BUILTIN_REGULAR(builtincmd) ((builtincmd)->name[0] & 2)
1304 #define IS_BUILTIN_ASSIGN(builtincmd) ((builtincmd)->name[0] & 4)
1306 static const struct builtincmd builtincmd[] = {
1307 { BUILTIN_SPEC_REG ".", dotcmd },
1308 { BUILTIN_SPEC_REG ":", truecmd },
1309 #ifdef CONFIG_ASH_ALIAS
1310 { BUILTIN_REG_ASSG "alias", aliascmd },
1313 { BUILTIN_REGULAR "bg", bgcmd },
1315 { BUILTIN_SPEC_REG "break", breakcmd },
1316 { BUILTIN_REGULAR "cd", cdcmd },
1317 { BUILTIN_NOSPEC "chdir", cdcmd },
1318 #ifdef CONFIG_ASH_CMDCMD
1319 { BUILTIN_REGULAR "command", commandcmd },
1321 { BUILTIN_SPEC_REG "continue", breakcmd },
1322 #ifdef CONFIG_ASH_BUILTIN_ECHO
1323 { BUILTIN_REGULAR "echo", echocmd },
1325 { BUILTIN_SPEC_REG "eval", evalcmd },
1326 { BUILTIN_SPEC_REG "exec", execcmd },
1327 { BUILTIN_SPEC_REG "exit", exitcmd },
1328 { BUILTIN_SPEC_REG_ASSG "export", exportcmd },
1329 { BUILTIN_REGULAR "false", falsecmd },
1331 { BUILTIN_REGULAR "fg", fgcmd },
1333 #ifdef CONFIG_ASH_GETOPTS
1334 { BUILTIN_REGULAR "getopts", getoptscmd },
1336 { BUILTIN_NOSPEC "hash", hashcmd },
1337 #ifndef CONFIG_FEATURE_SH_EXTRA_QUIET
1338 { BUILTIN_NOSPEC "help", helpcmd },
1341 { BUILTIN_REGULAR "jobs", jobscmd },
1342 { BUILTIN_REGULAR "kill", killcmd },
1344 #ifdef CONFIG_ASH_MATH_SUPPORT
1345 { BUILTIN_NOSPEC "let", letcmd },
1347 { BUILTIN_ASSIGN "local", localcmd },
1348 { BUILTIN_NOSPEC "pwd", pwdcmd },
1349 { BUILTIN_REGULAR "read", readcmd },
1350 { BUILTIN_SPEC_REG_ASSG "readonly", exportcmd },
1351 { BUILTIN_SPEC_REG "return", returncmd },
1352 { BUILTIN_SPEC_REG "set", setcmd },
1353 { BUILTIN_SPEC_REG "shift", shiftcmd },
1354 { BUILTIN_SPEC_REG "times", timescmd },
1355 { BUILTIN_SPEC_REG "trap", trapcmd },
1356 { BUILTIN_REGULAR "true", truecmd },
1357 { BUILTIN_NOSPEC "type", typecmd },
1358 { BUILTIN_NOSPEC "ulimit", ulimitcmd },
1359 { BUILTIN_REGULAR "umask", umaskcmd },
1360 #ifdef CONFIG_ASH_ALIAS
1361 { BUILTIN_REGULAR "unalias", unaliascmd },
1363 { BUILTIN_SPEC_REG "unset", unsetcmd },
1364 { BUILTIN_REGULAR "wait", waitcmd },
1367 #define NUMBUILTINS (sizeof (builtincmd) / sizeof (struct builtincmd) )
1375 const struct builtincmd *cmd;
1376 struct funcnode *func;
1381 /* action to find_command() */
1382 #define DO_ERR 0x01 /* prints errors */
1383 #define DO_ABS 0x02 /* checks absolute paths */
1384 #define DO_NOFUNC 0x04 /* don't return shell functions, for command */
1385 #define DO_ALTPATH 0x08 /* using alternate path */
1386 #define DO_ALTBLTIN 0x20 /* %builtin in alt. path */
1388 static const char *pathopt; /* set by padvance */
1390 static void shellexec(char **, const char *, int)
1392 static char *padvance(const char **, const char *);
1393 static void find_command(char *, struct cmdentry *, int, const char *);
1394 static struct builtincmd *find_builtin(const char *);
1395 static void hashcd(void);
1396 static void changepath(const char *);
1397 static void defun(char *, union node *);
1398 static void unsetfunc(const char *);
1400 #ifdef CONFIG_ASH_MATH_SUPPORT_64
1401 typedef int64_t arith_t;
1403 typedef long arith_t;
1406 #ifdef CONFIG_ASH_MATH_SUPPORT
1407 static arith_t dash_arith(const char *);
1408 static arith_t arith(const char *expr, int *perrcode);
1411 #ifdef CONFIG_ASH_RANDOM_SUPPORT
1412 static unsigned long rseed;
1413 static void change_random(const char *);
1414 # ifndef DYNAMIC_VAR
1415 # define DYNAMIC_VAR
1421 static void reset(void);
1430 #define VEXPORT 0x01 /* variable is exported */
1431 #define VREADONLY 0x02 /* variable cannot be modified */
1432 #define VSTRFIXED 0x04 /* variable struct is statically allocated */
1433 #define VTEXTFIXED 0x08 /* text is statically allocated */
1434 #define VSTACK 0x10 /* text is allocated on the stack */
1435 #define VUNSET 0x20 /* the variable is not set */
1436 #define VNOFUNC 0x40 /* don't call the callback function */
1437 #define VNOSET 0x80 /* do not set variable - just readonly test */
1438 #define VNOSAVE 0x100 /* when text is on the heap before setvareq */
1440 # define VDYNAMIC 0x200 /* dynamic variable */
1446 struct var *next; /* next entry in hash list */
1447 int flags; /* flags are defined above */
1448 const char *text; /* name=value */
1449 void (*func)(const char *); /* function to be called when */
1450 /* the variable gets set/unset */
1454 struct localvar *next; /* next local variable in list */
1455 struct var *vp; /* the variable that was made local */
1456 int flags; /* saved flags */
1457 const char *text; /* saved text */
1461 static struct localvar *localvars;
1467 #ifdef CONFIG_ASH_GETOPTS
1468 static void getoptsreset(const char *);
1471 #ifdef CONFIG_LOCALE_SUPPORT
1473 static void change_lc_all(const char *value);
1474 static void change_lc_ctype(const char *value);
1480 static const char defpathvar[] = "PATH=/usr/local/bin:/usr/bin:/sbin:/bin";
1482 static const char defifsvar[] = "IFS= \t\n";
1483 #define defifs (defifsvar + 4)
1485 static const char defifs[] = " \t\n";
1489 static struct var varinit[] = {
1491 { 0, VSTRFIXED|VTEXTFIXED, defifsvar, 0 },
1493 { 0, VSTRFIXED|VTEXTFIXED|VUNSET, "IFS\0", 0 },
1496 #ifdef CONFIG_ASH_MAIL
1497 { 0, VSTRFIXED|VTEXTFIXED|VUNSET, "MAIL\0", changemail },
1498 { 0, VSTRFIXED|VTEXTFIXED|VUNSET, "MAILPATH\0", changemail },
1501 { 0, VSTRFIXED|VTEXTFIXED, defpathvar, changepath },
1502 { 0, VSTRFIXED|VTEXTFIXED, "PS1=$ ", 0 },
1503 { 0, VSTRFIXED|VTEXTFIXED, "PS2=> ", 0 },
1504 { 0, VSTRFIXED|VTEXTFIXED, "PS4=+ ", 0 },
1505 #ifdef CONFIG_ASH_GETOPTS
1506 { 0, VSTRFIXED|VTEXTFIXED, "OPTIND=1", getoptsreset },
1508 #ifdef CONFIG_ASH_RANDOM_SUPPORT
1509 {0, VSTRFIXED|VTEXTFIXED|VUNSET|VDYNAMIC, "RANDOM\0", change_random },
1511 #ifdef CONFIG_LOCALE_SUPPORT
1512 {0, VSTRFIXED | VTEXTFIXED | VUNSET, "LC_ALL\0", change_lc_all },
1513 {0, VSTRFIXED | VTEXTFIXED | VUNSET, "LC_CTYPE\0", change_lc_ctype },
1515 #ifdef CONFIG_FEATURE_COMMAND_SAVEHISTORY
1516 {0, VSTRFIXED | VTEXTFIXED | VUNSET, "HISTFILE\0", NULL },
1520 #define vifs varinit[0]
1521 #ifdef CONFIG_ASH_MAIL
1522 #define vmail (&vifs)[1]
1523 #define vmpath (&vmail)[1]
1527 #define vpath (&vmpath)[1]
1528 #define vps1 (&vpath)[1]
1529 #define vps2 (&vps1)[1]
1530 #define vps4 (&vps2)[1]
1531 #define voptind (&vps4)[1]
1532 #ifdef CONFIG_ASH_GETOPTS
1533 #define vrandom (&voptind)[1]
1535 #define vrandom (&vps4)[1]
1537 #define defpath (defpathvar + 5)
1540 * The following macros access the values of the above variables.
1541 * They have to skip over the name. They return the null string
1542 * for unset variables.
1545 #define ifsval() (vifs.text + 4)
1546 #define ifsset() ((vifs.flags & VUNSET) == 0)
1547 #define mailval() (vmail.text + 5)
1548 #define mpathval() (vmpath.text + 9)
1549 #define pathval() (vpath.text + 5)
1550 #define ps1val() (vps1.text + 4)
1551 #define ps2val() (vps2.text + 4)
1552 #define ps4val() (vps4.text + 4)
1553 #define optindval() (voptind.text + 7)
1555 #define mpathset() ((vmpath.flags & VUNSET) == 0)
1557 static void setvar(const char *, const char *, int);
1558 static void setvareq(char *, int);
1559 static void listsetvar(struct strlist *, int);
1560 static char *lookupvar(const char *);
1561 static char *bltinlookup(const char *);
1562 static char **listvars(int, int, char ***);
1563 #define environment() listvars(VEXPORT, VUNSET, 0)
1564 static int showvars(const char *, int, int);
1565 static void poplocalvars(void);
1566 static int unsetvar(const char *);
1567 #ifdef CONFIG_ASH_GETOPTS
1568 static int setvarsafe(const char *, const char *, int);
1570 static int varcmp(const char *, const char *);
1571 static struct var **hashvar(const char *);
1574 static inline int varequal(const char *a, const char *b) {
1575 return !varcmp(a, b);
1579 static int loopnest; /* current loop nesting level */
1582 * The parsefile structure pointed to by the global variable parsefile
1583 * contains information about the current file being read.
1588 struct redirtab *next;
1593 static struct redirtab *redirlist;
1594 static int nullredirs;
1596 extern char **environ;
1601 static void outstr(const char *, FILE *);
1602 static void outcslow(int, FILE *);
1603 static void flushall(void);
1604 static void flusherr(void);
1605 static int out1fmt(const char *, ...)
1606 __attribute__((__format__(__printf__,1,2)));
1607 static int fmtstr(char *, size_t, const char *, ...)
1608 __attribute__((__format__(__printf__,3,4)));
1610 static int preverrout_fd; /* save fd2 before print debug if xflag is set. */
1613 static void out1str(const char *p)
1618 static void out2str(const char *p)
1625 * Initialization code.
1629 * This routine initializes the builtin variables.
1640 * PS1 depends on uid
1642 #if defined(CONFIG_FEATURE_COMMAND_EDITING) && defined(CONFIG_FEATURE_SH_FANCY_PROMPT)
1643 vps1.text = "PS1=\\w \\$ ";
1646 vps1.text = "PS1=# ";
1649 end = vp + sizeof(varinit) / sizeof(varinit[0]);
1651 vpp = hashvar(vp->text);
1654 } while (++vp < end);
1663 basepf.nextc = basepf.buf = basebuf;
1668 signal(SIGCHLD, SIG_DFL);
1676 struct stat st1, st2;
1679 for (envp = environ ; envp && *envp ; envp++) {
1680 if (strchr(*envp, '=')) {
1681 setvareq(*envp, VEXPORT|VTEXTFIXED);
1685 snprintf(ppid, sizeof(ppid), "%d", (int) getppid());
1686 setvar("PPID", ppid, 0);
1688 p = lookupvar("PWD");
1690 if (*p != '/' || stat(p, &st1) || stat(".", &st2) ||
1691 st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino)
1697 /* PEOF (the end of file marker) */
1700 INPUT_PUSH_FILE = 1,
1701 INPUT_NOFILE_OK = 2,
1705 * The input line number. Input.c just defines this variable, and saves
1706 * and restores it when files are pushed and popped. The user of this
1707 * package must set its value.
1710 static int pgetc(void);
1711 static int pgetc2(void);
1712 static int preadbuffer(void);
1713 static void pungetc(void);
1714 static void pushstring(char *, void *);
1715 static void popstring(void);
1716 static void setinputfd(int, int);
1717 static void setinputstring(char *);
1718 static void popfile(void);
1719 static void popallfiles(void);
1720 static void closescript(void);
1726 /* Mode argument to forkshell. Don't change FORK_FG or FORK_BG. */
1729 #define FORK_NOJOB 2
1731 /* mode flags for showjob(s) */
1732 #define SHOW_PGID 0x01 /* only show pgid - for jobs -p */
1733 #define SHOW_PID 0x04 /* include process pid */
1734 #define SHOW_CHANGED 0x08 /* only jobs whose state has changed */
1738 * A job structure contains information about a job. A job is either a
1739 * single process or a set of processes contained in a pipeline. In the
1740 * latter case, pidlist will be non-NULL, and will point to a -1 terminated
1745 pid_t pid; /* process id */
1746 int status; /* last process status from wait() */
1747 char *cmd; /* text of command being run */
1751 struct procstat ps0; /* status of process */
1752 struct procstat *ps; /* status or processes when more than one */
1754 int stopstatus; /* status of a stopped job */
1757 nprocs: 16, /* number of processes */
1759 #define JOBRUNNING 0 /* at least one proc running */
1760 #define JOBSTOPPED 1 /* all procs are stopped */
1761 #define JOBDONE 2 /* all procs are completed */
1763 sigint: 1, /* job was killed by SIGINT */
1764 jobctl: 1, /* job running under job control */
1766 waited: 1, /* true if this entry has been waited for */
1767 used: 1, /* true if this entry is in used */
1768 changed: 1; /* true if status has changed */
1769 struct job *prev_job; /* previous job */
1772 static pid_t backgndpid; /* pid of last background process */
1773 static int job_warning; /* user was warned about stopped jobs */
1775 static int jobctl; /* true if doing job control */
1778 static struct job *makejob(union node *, int);
1779 static int forkshell(struct job *, union node *, int);
1780 static int waitforjob(struct job *);
1781 static int stoppedjobs(void);
1784 #define setjobctl(on) /* do nothing */
1786 static void setjobctl(int);
1787 static void showjobs(FILE *, int);
1793 /* pid of main shell */
1795 /* shell level: 0 for the main shell, 1 for its children, and so on */
1797 #define rootshell (!shlvl)
1799 static void readcmdfile(char *);
1800 static int cmdloop(int);
1806 struct stack_block *stackp;
1809 struct stackmark *marknext;
1812 /* minimum size of a block */
1813 #define MINSIZE SHELL_ALIGN(504)
1815 struct stack_block {
1816 struct stack_block *prev;
1817 char space[MINSIZE];
1820 static struct stack_block stackbase;
1821 static struct stack_block *stackp = &stackbase;
1822 static struct stackmark *markp;
1823 static char *stacknxt = stackbase.space;
1824 static size_t stacknleft = MINSIZE;
1825 static char *sstrend = stackbase.space + MINSIZE;
1826 static int herefd = -1;
1829 static pointer ckmalloc(size_t);
1830 static pointer ckrealloc(pointer, size_t);
1831 static char *savestr(const char *);
1832 static pointer stalloc(size_t);
1833 static void stunalloc(pointer);
1834 static void setstackmark(struct stackmark *);
1835 static void popstackmark(struct stackmark *);
1836 static void growstackblock(void);
1837 static void *growstackstr(void);
1838 static char *makestrspace(size_t, char *);
1839 static char *stnputs(const char *, size_t, char *);
1840 static char *stputs(const char *, char *);
1843 static inline char *_STPUTC(int c, char *p) {
1850 #define stackblock() ((void *)stacknxt)
1851 #define stackblocksize() stacknleft
1852 #define STARTSTACKSTR(p) ((p) = stackblock())
1853 #define STPUTC(c, p) ((p) = _STPUTC((c), (p)))
1854 #define CHECKSTRSPACE(n, p) \
1858 size_t m = sstrend - q; \
1860 (p) = makestrspace(l, q); \
1863 #define USTPUTC(c, p) (*p++ = (c))
1864 #define STACKSTRNUL(p) ((p) == sstrend? (p = growstackstr(), *p = '\0') : (*p = '\0'))
1865 #define STUNPUTC(p) (--p)
1866 #define STTOPC(p) p[-1]
1867 #define STADJUST(amount, p) (p += (amount))
1869 #define grabstackstr(p) stalloc((char *)(p) - (char *)stackblock())
1870 #define ungrabstackstr(s, p) stunalloc((s))
1871 #define stackstrend() ((void *)sstrend)
1873 #define ckfree(p) free((pointer)(p))
1878 #define DOLATSTRLEN 4
1880 static char *prefix(const char *, const char *);
1881 static int number(const char *);
1882 static int is_number(const char *);
1883 static char *single_quote(const char *);
1884 static char *sstrdup(const char *);
1886 #define equal(s1, s2) (strcmp(s1, s2) == 0)
1887 #define scopy(s1, s2) ((void)strcpy(s2, s1))
1892 int nparam; /* # of positional parameters (without $0) */
1893 unsigned char malloc; /* if parameter list dynamically allocated */
1894 char **p; /* parameter list */
1895 #ifdef CONFIG_ASH_GETOPTS
1896 int optind; /* next parameter to be processed by getopts */
1897 int optoff; /* used by getopts */
1902 #define eflag optlist[0]
1903 #define fflag optlist[1]
1904 #define Iflag optlist[2]
1905 #define iflag optlist[3]
1906 #define mflag optlist[4]
1907 #define nflag optlist[5]
1908 #define sflag optlist[6]
1909 #define xflag optlist[7]
1910 #define vflag optlist[8]
1911 #define Cflag optlist[9]
1912 #define aflag optlist[10]
1913 #define bflag optlist[11]
1914 #define uflag optlist[12]
1915 #define viflag optlist[13]
1918 #define nolog optlist[14]
1919 #define debug optlist[15]
1922 #ifndef CONFIG_FEATURE_COMMAND_EDITING_VI
1923 #define setvimode(on) viflag = 0 /* forcibly keep the option off */
1929 static const char *const optletters_optnames[] = {
1950 #define optletters(n) optletters_optnames[(n)][0]
1951 #define optnames(n) (&optletters_optnames[(n)][1])
1953 #define NOPTS (sizeof(optletters_optnames)/sizeof(optletters_optnames[0]))
1955 static char optlist[NOPTS];
1958 static char *arg0; /* value of $0 */
1959 static struct shparam shellparam; /* $@ current positional parameters */
1960 static char **argptr; /* argument list for builtin commands */
1961 static char *optionarg; /* set by nextopt (like getopt) */
1962 static char *optptr; /* used by nextopt */
1964 static char *minusc; /* argument to -c option */
1967 static void procargs(int, char **);
1968 static void optschanged(void);
1969 static void setparam(char **);
1970 static void freeparam(volatile struct shparam *);
1971 static int shiftcmd(int, char **);
1972 static int setcmd(int, char **);
1973 static int nextopt(const char *);
1977 /* flags passed to redirect */
1978 #define REDIR_PUSH 01 /* save previous values of file descriptors */
1979 #define REDIR_SAVEFD2 03 /* set preverrout */
1982 static void redirect(union node *, int);
1983 static void popredir(int);
1984 static void clearredir(int);
1985 static int copyfd(int, int);
1986 static int redirectsafe(union node *, int);
1992 static void showtree(union node *);
1993 static void trace(const char *, ...);
1994 static void tracev(const char *, va_list);
1995 static void trargs(char **);
1996 static void trputc(int);
1997 static void trputs(const char *);
1998 static void opentrace(void);
2004 /* trap handler commands */
2005 static char *trap[NSIG];
2006 /* current value of signal */
2007 static char sigmode[NSIG - 1];
2008 /* indicates specified signal received */
2009 static char gotsig[NSIG - 1];
2011 static void clear_traps(void);
2012 static void setsignal(int);
2013 static void ignoresig(int);
2014 static void onsig(int);
2015 static int dotrap(void);
2016 static void setinteractive(int);
2017 static void exitshell(void) ATTRIBUTE_NORETURN;
2018 static int decode_signal(const char *, int);
2021 * This routine is called when an error or an interrupt occurs in an
2022 * interactive shell and control is returned to the main command loop.
2036 parselleft = parsenleft = 0; /* clear input buffer */
2040 /* from parser.c: */
2053 #ifdef CONFIG_ASH_ALIAS
2054 static struct alias *atab[ATABSIZE];
2056 static void setalias(const char *, const char *);
2057 static struct alias *freealias(struct alias *);
2058 static struct alias **__lookupalias(const char *);
2061 setalias(const char *name, const char *val)
2063 struct alias *ap, **app;
2065 app = __lookupalias(name);
2069 if (!(ap->flag & ALIASINUSE)) {
2072 ap->val = savestr(val);
2073 ap->flag &= ~ALIASDEAD;
2076 ap = ckmalloc(sizeof (struct alias));
2077 ap->name = savestr(name);
2078 ap->val = savestr(val);
2087 unalias(const char *name)
2091 app = __lookupalias(name);
2095 *app = freealias(*app);
2106 struct alias *ap, **app;
2110 for (i = 0; i < ATABSIZE; i++) {
2112 for (ap = *app; ap; ap = *app) {
2113 *app = freealias(*app);
2122 static struct alias *
2123 lookupalias(const char *name, int check)
2125 struct alias *ap = *__lookupalias(name);
2127 if (check && ap && (ap->flag & ALIASINUSE))
2133 * TODO - sort output
2136 aliascmd(int argc, char **argv)
2145 for (i = 0; i < ATABSIZE; i++)
2146 for (ap = atab[i]; ap; ap = ap->next) {
2151 while ((n = *++argv) != NULL) {
2152 if ((v = strchr(n+1, '=')) == NULL) { /* n+1: funny ksh stuff */
2153 if ((ap = *__lookupalias(n)) == NULL) {
2154 fprintf(stderr, "%s: %s not found\n", "alias", n);
2168 unaliascmd(int argc, char **argv)
2172 while ((i = nextopt("a")) != '\0') {
2178 for (i = 0; *argptr; argptr++) {
2179 if (unalias(*argptr)) {
2180 fprintf(stderr, "%s: %s not found\n", "unalias", *argptr);
2188 static struct alias *
2189 freealias(struct alias *ap) {
2192 if (ap->flag & ALIASINUSE) {
2193 ap->flag |= ALIASDEAD;
2205 printalias(const struct alias *ap) {
2206 out1fmt("%s=%s\n", ap->name, single_quote(ap->val));
2209 static struct alias **
2210 __lookupalias(const char *name) {
2211 unsigned int hashval;
2218 ch = (unsigned char)*p;
2222 ch = (unsigned char)*++p;
2224 app = &atab[hashval % ATABSIZE];
2226 for (; *app; app = &(*app)->next) {
2227 if (equal(name, (*app)->name)) {
2234 #endif /* CONFIG_ASH_ALIAS */
2240 * The cd and pwd commands.
2243 #define CD_PHYSICAL 1
2246 static int docd(const char *, int);
2247 static int cdopt(void);
2249 static char *curdir = nullstr; /* current working directory */
2250 static char *physdir = nullstr; /* physical working directory */
2259 while ((i = nextopt("LP"))) {
2261 flags ^= CD_PHYSICAL;
2270 cdcmd(int argc, char **argv)
2282 dest = bltinlookup(homestr);
2283 else if (dest[0] == '-' && dest[1] == '\0') {
2284 dest = bltinlookup("OLDPWD");
2306 if (!(path = bltinlookup("CDPATH"))) {
2314 p = padvance(&path, dest);
2315 if (stat(p, &statb) >= 0 && S_ISDIR(statb.st_mode)) {
2319 if (!docd(p, flags))
2324 sh_error("can't cd to %s", dest);
2327 if (flags & CD_PRINT)
2328 out1fmt(snlfmt, curdir);
2334 * Update curdir (the name of the current directory) in response to a
2338 static inline const char *
2339 updatepwd(const char *dir)
2346 cdcomppath = sstrdup(dir);
2349 if (curdir == nullstr)
2351 new = stputs(curdir, new);
2353 new = makestrspace(strlen(dir) + 2, new);
2354 lim = stackblock() + 1;
2358 if (new > lim && *lim == '/')
2363 if (dir[1] == '/' && dir[2] != '/') {
2369 p = strtok(cdcomppath, "/");
2373 if (p[1] == '.' && p[2] == '\0') {
2380 } else if (p[1] == '\0')
2384 new = stputs(p, new);
2392 return stackblock();
2396 * Actually do the chdir. We also call hashcd to let the routines in exec.c
2397 * know that the current directory has changed.
2401 docd(const char *dest, int flags)
2403 const char *dir = 0;
2406 TRACE(("docd(\"%s\", %d) called\n", dest, flags));
2409 if (!(flags & CD_PHYSICAL)) {
2410 dir = updatepwd(dest);
2425 * Find out what the current directory is. If we already know the current
2426 * directory, this routine returns immediately.
2428 static inline char *
2431 char *dir = getcwd(0, 0);
2432 return dir ? dir : nullstr;
2436 pwdcmd(int argc, char **argv)
2439 const char *dir = curdir;
2443 if (physdir == nullstr)
2447 out1fmt(snlfmt, dir);
2452 setpwd(const char *val, int setold)
2456 oldcur = dir = curdir;
2459 setvar("OLDPWD", oldcur, VEXPORT);
2462 if (physdir != nullstr) {
2463 if (physdir != oldcur)
2467 if (oldcur == val || !val) {
2474 if (oldcur != dir && oldcur != nullstr) {
2479 setvar("PWD", dir, VEXPORT);
2485 * Errors and exceptions.
2489 * Code to handle exceptions in C.
2494 static void exverror(int, const char *, va_list)
2498 * Called to raise an exception. Since C doesn't include exceptions, we
2499 * just do a longjmp to the exception handler. The type of exception is
2500 * stored in the global variable "exception".
2507 if (handler == NULL)
2513 longjmp(handler->loc, 1);
2518 * Called from trap.c when a SIGINT is received. (If the user specifies
2519 * that SIGINT is to be trapped or ignored using the trap builtin, then
2520 * this routine is not called.) Suppressint is nonzero when interrupts
2521 * are held using the INTOFF macro. (The test for iflag is just
2522 * defensive programming.)
2531 /* comment by vodz: its strange for me, this programm don`t use other
2536 if (gotsig[SIGINT - 1] && !trap[SIGINT]) {
2537 if (!(rootshell && iflag)) {
2538 signal(SIGINT, SIG_DFL);
2548 exvwarning(const char *msg, va_list ap)
2553 fprintf(errs, "%s: ", arg0);
2555 const char *fmt = (!iflag || parsefile->fd) ?
2556 "%s: %d: " : "%s: ";
2557 fprintf(errs, fmt, commandname, startlinno);
2559 vfprintf(errs, msg, ap);
2560 outcslow('\n', errs);
2564 * Exverror is called to raise the error exception. If the second argument
2565 * is not NULL then error prints an error message using printf style
2566 * formatting. It then raises the error exception.
2569 exverror(int cond, const char *msg, va_list ap)
2573 TRACE(("exverror(%d, \"", cond));
2575 TRACE(("\") pid=%d\n", getpid()));
2577 TRACE(("exverror(%d, NULL) pid=%d\n", cond, getpid()));
2580 exvwarning(msg, ap);
2589 sh_error(const char *msg, ...)
2594 exverror(EXERROR, msg, ap);
2601 exerror(int cond, const char *msg, ...)
2606 exverror(cond, msg, ap);
2612 * error/warning routines for external builtins
2616 sh_warnx(const char *fmt, ...)
2621 exvwarning(fmt, ap);
2627 * Return a string describing an error. The returned string may be a
2628 * pointer to a static buffer that will be overwritten on the next call.
2629 * Action describes the operation that got the error.
2633 errmsg(int e, const char *em)
2635 if(e == ENOENT || e == ENOTDIR) {
2646 * Evaluate a command.
2649 /* flags in argument to evaltree */
2650 #define EV_EXIT 01 /* exit after evaluating tree */
2651 #define EV_TESTED 02 /* exit status is checked; ignore -e flag */
2652 #define EV_BACKCMD 04 /* command executing within back quotes */
2655 static void evalloop(union node *, int);
2656 static void evalfor(union node *, int);
2657 static void evalcase(union node *, int);
2658 static void evalsubshell(union node *, int);
2659 static void expredir(union node *);
2660 static void evalpipe(union node *, int);
2661 static void evalcommand(union node *, int);
2662 static int evalbltin(const struct builtincmd *, int, char **);
2663 static int evalfun(struct funcnode *, int, char **, int);
2664 static void prehash(union node *);
2665 static int bltincmd(int, char **);
2668 static const struct builtincmd bltin = {
2674 * Called to reset things after an exception.
2682 evalcmd(int argc, char **argv)
2691 STARTSTACKSTR(concat);
2694 concat = stputs(p, concat);
2695 if ((p = *ap++) == NULL)
2697 STPUTC(' ', concat);
2699 STPUTC('\0', concat);
2700 p = grabstackstr(concat);
2702 evalstring(p, ~SKIPEVAL);
2710 * Execute a command or commands contained in a string.
2714 evalstring(char *s, int mask)
2717 struct stackmark smark;
2721 setstackmark(&smark);
2724 while ((n = parsecmd(0)) != NEOF) {
2726 popstackmark(&smark);
2741 * Evaluate a parse tree. The value is left in the global variable
2746 evaltree(union node *n, int flags)
2749 void (*evalfn)(union node *, int);
2753 TRACE(("evaltree(NULL) called\n"));
2756 TRACE(("pid %d, evaltree(%p: %d, %d) called\n",
2757 getpid(), n, n->type, flags));
2761 out1fmt("Node type = %d\n", n->type);
2766 evaltree(n->nnot.com, EV_TESTED);
2767 status = !exitstatus;
2770 expredir(n->nredir.redirect);
2771 status = redirectsafe(n->nredir.redirect, REDIR_PUSH);
2773 evaltree(n->nredir.n, flags & EV_TESTED);
2774 status = exitstatus;
2779 evalfn = evalcommand;
2781 if (eflag && !(flags & EV_TESTED))
2793 evalfn = evalsubshell;
2805 #error NAND + 1 != NOR
2807 #if NOR + 1 != NSEMI
2808 #error NOR + 1 != NSEMI
2810 isor = n->type - NAND;
2813 (flags | ((isor >> 1) - 1)) & EV_TESTED
2815 if (!exitstatus == isor)
2827 evaltree(n->nif.test, EV_TESTED);
2830 if (exitstatus == 0) {
2833 } else if (n->nif.elsepart) {
2834 n = n->nif.elsepart;
2839 defun(n->narg.text, n->narg.next);
2843 exitstatus = status;
2847 if ((checkexit & exitstatus))
2848 evalskip |= SKIPEVAL;
2849 else if (pendingsigs && dotrap())
2852 if (flags & EV_EXIT) {
2859 #if !defined(__alpha__) || (defined(__GNUC__) && __GNUC__ >= 3)
2862 void evaltreenr(union node *, int) __attribute__ ((alias("evaltree"),__noreturn__));
2866 evalloop(union node *n, int flags)
2876 evaltree(n->nbinary.ch1, EV_TESTED);
2878 skipping: if (evalskip == SKIPCONT && --skipcount <= 0) {
2882 if (evalskip == SKIPBREAK && --skipcount <= 0)
2887 if (n->type != NWHILE)
2891 evaltree(n->nbinary.ch2, flags);
2892 status = exitstatus;
2897 exitstatus = status;
2903 evalfor(union node *n, int flags)
2905 struct arglist arglist;
2908 struct stackmark smark;
2910 setstackmark(&smark);
2911 arglist.lastp = &arglist.list;
2912 for (argp = n->nfor.args ; argp ; argp = argp->narg.next) {
2913 expandarg(argp, &arglist, EXP_FULL | EXP_TILDE | EXP_RECORD);
2918 *arglist.lastp = NULL;
2923 for (sp = arglist.list ; sp ; sp = sp->next) {
2924 setvar(n->nfor.var, sp->text, 0);
2925 evaltree(n->nfor.body, flags);
2927 if (evalskip == SKIPCONT && --skipcount <= 0) {
2931 if (evalskip == SKIPBREAK && --skipcount <= 0)
2938 popstackmark(&smark);
2944 evalcase(union node *n, int flags)
2948 struct arglist arglist;
2949 struct stackmark smark;
2951 setstackmark(&smark);
2952 arglist.lastp = &arglist.list;
2953 expandarg(n->ncase.expr, &arglist, EXP_TILDE);
2955 for (cp = n->ncase.cases ; cp && evalskip == 0 ; cp = cp->nclist.next) {
2956 for (patp = cp->nclist.pattern ; patp ; patp = patp->narg.next) {
2957 if (casematch(patp, arglist.list->text)) {
2958 if (evalskip == 0) {
2959 evaltree(cp->nclist.body, flags);
2966 popstackmark(&smark);
2972 * Kick off a subshell to evaluate a tree.
2976 evalsubshell(union node *n, int flags)
2979 int backgnd = (n->type == NBACKGND);
2982 expredir(n->nredir.redirect);
2983 if (!backgnd && flags & EV_EXIT && !trap[0])
2987 if (forkshell(jp, n, backgnd) == 0) {
2991 flags &=~ EV_TESTED;
2993 redirect(n->nredir.redirect, 0);
2994 evaltreenr(n->nredir.n, flags);
2999 status = waitforjob(jp);
3000 exitstatus = status;
3007 * Compute the names of the files in a redirection list.
3011 expredir(union node *n)
3015 for (redir = n ; redir ; redir = redir->nfile.next) {
3017 fn.lastp = &fn.list;
3018 switch (redir->type) {
3024 expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR);
3025 redir->nfile.expfname = fn.list->text;
3029 if (redir->ndup.vname) {
3030 expandarg(redir->ndup.vname, &fn, EXP_FULL | EXP_TILDE);
3031 fixredir(redir, fn.list->text, 1);
3041 * Evaluate a pipeline. All the processes in the pipeline are children
3042 * of the process creating the pipeline. (This differs from some versions
3043 * of the shell, which make the last process in a pipeline the parent
3048 evalpipe(union node *n, int flags)
3051 struct nodelist *lp;
3056 TRACE(("evalpipe(0x%lx) called\n", (long)n));
3058 for (lp = n->npipe.cmdlist ; lp ; lp = lp->next)
3062 jp = makejob(n, pipelen);
3064 for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
3068 if (pipe(pip) < 0) {
3070 sh_error("Pipe call failed");
3073 if (forkshell(jp, lp->n, n->npipe.backgnd) == 0) {
3086 evaltreenr(lp->n, flags);
3094 if (n->npipe.backgnd == 0) {
3095 exitstatus = waitforjob(jp);
3096 TRACE(("evalpipe: job done exit status %d\n", exitstatus));
3104 * Execute a command inside back quotes. If it's a builtin command, we
3105 * want to save its output in a block obtained from malloc. Otherwise
3106 * we fork off a subprocess and get the output of the command via a pipe.
3107 * Should be called with interrupts off.
3111 evalbackcmd(union node *n, struct backcmd *result)
3123 saveherefd = herefd;
3131 sh_error("Pipe call failed");
3133 if (forkshell(jp, n, FORK_NOJOB) == 0) {
3142 evaltreenr(n, EV_EXIT);
3146 result->fd = pip[0];
3149 herefd = saveherefd;
3151 TRACE(("evalbackcmd done: fd=%d buf=0x%x nleft=%d jp=0x%x\n",
3152 result->fd, result->buf, result->nleft, result->jp));
3155 #ifdef CONFIG_ASH_CMDCMD
3156 static inline char **
3157 parse_command_args(char **argv, const char **path)
3169 if (c == '-' && !*cp) {
3179 /* run 'typecmd' for other options */
3182 } while ((c = *cp++));
3189 isassignment(const char *p)
3191 const char *q = endofname(p);
3197 #ifdef CONFIG_ASH_EXPAND_PRMT
3198 static const char *expandstr(const char *ps);
3200 #define expandstr(s) s
3204 * Execute a simple command.
3208 evalcommand(union node *cmd, int flags)
3210 struct stackmark smark;
3212 struct arglist arglist;
3213 struct arglist varlist;
3216 const struct strlist *sp;
3217 struct cmdentry cmdentry;
3225 struct builtincmd *bcmd;
3226 int pseudovarflag = 0;
3228 /* First expand the arguments. */
3229 TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags));
3230 setstackmark(&smark);
3231 back_exitstatus = 0;
3233 cmdentry.cmdtype = CMDBUILTIN;
3234 cmdentry.u.cmd = &bltin;
3235 varlist.lastp = &varlist.list;
3236 *varlist.lastp = NULL;
3237 arglist.lastp = &arglist.list;
3238 *arglist.lastp = NULL;
3243 bcmd = find_builtin(cmd->ncmd.args->narg.text);
3244 pseudovarflag = bcmd && IS_BUILTIN_ASSIGN(bcmd);
3247 for (argp = cmd->ncmd.args; argp; argp = argp->narg.next) {
3248 struct strlist **spp;
3250 spp = arglist.lastp;
3251 if (pseudovarflag && isassignment(argp->narg.text))
3252 expandarg(argp, &arglist, EXP_VARTILDE);
3254 expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
3256 for (sp = *spp; sp; sp = sp->next)
3260 argv = nargv = stalloc(sizeof (char *) * (argc + 1));
3261 for (sp = arglist.list ; sp ; sp = sp->next) {
3262 TRACE(("evalcommand arg: %s\n", sp->text));
3263 *nargv++ = sp->text;
3268 if (iflag && funcnest == 0 && argc > 0)
3269 lastarg = nargv[-1];
3272 expredir(cmd->ncmd.redirect);
3273 status = redirectsafe(cmd->ncmd.redirect, REDIR_PUSH|REDIR_SAVEFD2);
3276 for (argp = cmd->ncmd.assign; argp; argp = argp->narg.next) {
3277 struct strlist **spp;
3280 spp = varlist.lastp;
3281 expandarg(argp, &varlist, EXP_VARTILDE);
3284 * Modify the command lookup path, if a PATH= assignment
3288 if (varequal(p, path))
3292 /* Print the command if xflag is set. */
3295 const char *p = " %s";
3298 dprintf(preverrout_fd, p, expandstr(ps4val()));
3301 for(n = 0; n < 2; n++) {
3303 dprintf(preverrout_fd, p, sp->text);
3311 bb_full_write(preverrout_fd, "\n", 1);
3317 /* Now locate the command. */
3319 const char *oldpath;
3320 int cmd_flag = DO_ERR;
3325 find_command(argv[0], &cmdentry, cmd_flag, path);
3326 if (cmdentry.cmdtype == CMDUNKNOWN) {
3332 /* implement bltin and command here */
3333 if (cmdentry.cmdtype != CMDBUILTIN)
3336 spclbltin = IS_BUILTIN_SPECIAL(cmdentry.u.cmd);
3337 if (cmdentry.u.cmd == EXECCMD)
3339 #ifdef CONFIG_ASH_CMDCMD
3340 if (cmdentry.u.cmd == COMMANDCMD) {
3343 nargv = parse_command_args(argv, &path);
3346 argc -= nargv - argv;
3348 cmd_flag |= DO_NOFUNC;
3356 /* We have a redirection error. */
3360 exitstatus = status;
3364 /* Execute the command. */
3365 switch (cmdentry.cmdtype) {
3367 /* Fork off a child process if necessary. */
3368 if (!(flags & EV_EXIT) || trap[0]) {
3370 jp = makejob(cmd, 1);
3371 if (forkshell(jp, cmd, FORK_FG) != 0) {
3372 exitstatus = waitforjob(jp);
3378 listsetvar(varlist.list, VEXPORT|VSTACK);
3379 shellexec(argv, path, cmdentry.u.index);
3383 cmdenviron = varlist.list;
3385 struct strlist *list = cmdenviron;
3387 if (spclbltin > 0 || argc == 0) {
3389 if (cmd_is_exec && argc > 1)
3392 listsetvar(list, i);
3394 if (evalbltin(cmdentry.u.cmd, argc, argv)) {
3409 exit_status = j + 128;
3410 exitstatus = exit_status;
3412 if (i == EXINT || spclbltin > 0) {
3414 longjmp(handler->loc, 1);
3421 listsetvar(varlist.list, 0);
3422 if (evalfun(cmdentry.u.func, argc, argv, flags))
3428 popredir(cmd_is_exec);
3430 /* dsl: I think this is intended to be used to support
3431 * '_' in 'vi' command mode during line editing...
3432 * However I implemented that within libedit itself.
3434 setvar("_", lastarg, 0);
3435 popstackmark(&smark);
3439 evalbltin(const struct builtincmd *cmd, int argc, char **argv) {
3440 char *volatile savecmdname;
3441 struct jmploc *volatile savehandler;
3442 struct jmploc jmploc;
3445 savecmdname = commandname;
3446 if ((i = setjmp(jmploc.loc)))
3448 savehandler = handler;
3450 commandname = argv[0];
3452 optptr = NULL; /* initialize nextopt */
3453 exitstatus = (*cmd->builtin)(argc, argv);
3456 exitstatus |= ferror(stdout);
3457 commandname = savecmdname;
3459 handler = savehandler;
3465 evalfun(struct funcnode *func, int argc, char **argv, int flags)
3467 volatile struct shparam saveparam;
3468 struct localvar *volatile savelocalvars;
3469 struct jmploc *volatile savehandler;
3470 struct jmploc jmploc;
3473 saveparam = shellparam;
3474 savelocalvars = localvars;
3475 if ((e = setjmp(jmploc.loc))) {
3479 savehandler = handler;
3482 shellparam.malloc = 0;
3486 shellparam.nparam = argc - 1;
3487 shellparam.p = argv + 1;
3488 #ifdef CONFIG_ASH_GETOPTS
3489 shellparam.optind = 1;
3490 shellparam.optoff = -1;
3492 evaltree(&func->n, flags & EV_TESTED);
3498 localvars = savelocalvars;
3499 freeparam(&shellparam);
3500 shellparam = saveparam;
3501 handler = savehandler;
3503 evalskip &= ~SKIPFUNC;
3509 goodname(const char *p)
3511 return !*endofname(p);
3515 * Search for a command. This is called before we fork so that the
3516 * location of the command will be available in the parent as well as
3517 * the child. The check for "goodname" is an overly conservative
3518 * check that the name will not be subject to expansion.
3522 prehash(union node *n)
3524 struct cmdentry entry;
3526 if (n->type == NCMD && n->ncmd.args)
3527 if (goodname(n->ncmd.args->narg.text))
3528 find_command(n->ncmd.args->narg.text, &entry, 0,
3535 * Builtin commands. Builtin commands whose functions are closely
3536 * tied to evaluation are implemented here.
3544 bltincmd(int argc, char **argv)
3547 * Preserve exitstatus of a previous possible redirection
3550 return back_exitstatus;
3555 * Handle break and continue commands. Break, continue, and return are
3556 * all handled by setting the evalskip flag. The evaluation routines
3557 * above all check this flag, and if it is set they start skipping
3558 * commands rather than executing them. The variable skipcount is
3559 * the number of loops to break/continue, or the number of function
3560 * levels to return. (The latter is always 1.) It should probably
3561 * be an error to break out of more loops than exist, but it isn't
3562 * in the standard shell so we don't make it one here.
3566 breakcmd(int argc, char **argv)
3568 int n = argc > 1 ? number(argv[1]) : 1;
3571 sh_error(illnum, argv[1]);
3575 evalskip = (**argv == 'c')? SKIPCONT : SKIPBREAK;
3583 * The return command.
3587 returncmd(int argc, char **argv)
3590 * If called outside a function, do what ksh does;
3591 * skip the rest of the file.
3593 evalskip = funcnest ? SKIPFUNC : SKIPFILE;
3594 return argv[1] ? number(argv[1]) : exitstatus;
3599 falsecmd(int argc, char **argv)
3606 truecmd(int argc, char **argv)
3613 execcmd(int argc, char **argv)
3616 iflag = 0; /* exit on error */
3619 shellexec(argv + 1, pathval(), 0);
3628 * When commands are first encountered, they are entered in a hash table.
3629 * This ensures that a full path search will not have to be done for them
3630 * on each invocation.
3632 * We should investigate converting to a linear search, even though that
3633 * would make the command name "hash" a misnomer.
3636 #define CMDTABLESIZE 31 /* should be prime */
3637 #define ARB 1 /* actual size determined at run time */
3642 struct tblentry *next; /* next entry in hash chain */
3643 union param param; /* definition of builtin function */
3644 short cmdtype; /* index identifying command */
3645 char rehash; /* if set, cd done since entry created */
3646 char cmdname[ARB]; /* name of command */
3650 static struct tblentry *cmdtable[CMDTABLESIZE];
3651 static int builtinloc = -1; /* index in path of %builtin, or -1 */
3654 static void tryexec(char *, char **, char **);
3655 static void clearcmdentry(int);
3656 static struct tblentry *cmdlookup(const char *, int);
3657 static void delete_cmd_entry(void);
3661 * Exec a program. Never returns. If you change this routine, you may
3662 * have to change the find_command routine as well.
3666 shellexec(char **argv, const char *path, int idx)
3674 envp = environment();
3675 if (strchr(argv[0], '/') != NULL
3676 #ifdef CONFIG_FEATURE_SH_STANDALONE_SHELL
3677 || find_applet_by_name(argv[0])
3680 tryexec(argv[0], argv, envp);
3684 while ((cmdname = padvance(&path, argv[0])) != NULL) {
3685 if (--idx < 0 && pathopt == NULL) {
3686 tryexec(cmdname, argv, envp);
3687 if (errno != ENOENT && errno != ENOTDIR)
3694 /* Map to POSIX errors */
3706 exitstatus = exerrno;
3707 TRACE(("shellexec failed for %s, errno %d, suppressint %d\n",
3708 argv[0], e, suppressint ));
3709 exerror(EXEXEC, "%s: %s", argv[0], errmsg(e, E_EXEC));
3715 tryexec(char *cmd, char **argv, char **envp)
3718 #ifdef CONFIG_FEATURE_SH_STANDALONE_SHELL
3719 if(find_applet_by_name(cmd) != NULL) {
3720 /* re-exec ourselves with the new arguments */
3721 execve("/proc/self/exe",argv,envp);
3722 /* If proc isn't mounted, try hardcoded path to busybox binary*/
3723 execve("/bin/busybox",argv,envp);
3724 /* If they called chroot or otherwise made the binary no longer
3725 * executable, fall through */
3732 execve(cmd, argv, envp);
3733 } while (errno == EINTR);
3735 execve(cmd, argv, envp);
3739 } else if (errno == ENOEXEC) {
3743 for (ap = argv; *ap; ap++)
3745 ap = new = ckmalloc((ap - argv + 2) * sizeof(char *));
3747 *ap = cmd = (char *)DEFAULT_SHELL;
3750 while ((*ap++ = *argv++))
3760 * Do a path search. The variable path (passed by reference) should be
3761 * set to the start of the path before the first call; padvance will update
3762 * this value as it proceeds. Successive calls to padvance will return
3763 * the possible path expansions in sequence. If an option (indicated by
3764 * a percent sign) appears in the path entry then the global variable
3765 * pathopt will be set to point to it; otherwise pathopt will be set to
3770 padvance(const char **path, const char *name)
3780 for (p = start ; *p && *p != ':' && *p != '%' ; p++);
3781 len = p - start + strlen(name) + 2; /* "2" is for '/' and '\0' */
3782 while (stackblocksize() < len)
3786 memcpy(q, start, p - start);
3794 while (*p && *p != ':') p++;
3800 return stalloc(len);
3804 /*** Command hashing code ***/
3807 printentry(struct tblentry *cmdp)
3813 idx = cmdp->param.index;
3816 name = padvance(&path, cmdp->cmdname);
3818 } while (--idx >= 0);
3819 out1fmt("%s%s\n", name, (cmdp->rehash ? "*" : nullstr));
3824 hashcmd(int argc, char **argv)
3826 struct tblentry **pp;
3827 struct tblentry *cmdp;
3829 struct cmdentry entry;
3832 while ((c = nextopt("r")) != '\0') {
3836 if (*argptr == NULL) {
3837 for (pp = cmdtable ; pp < &cmdtable[CMDTABLESIZE] ; pp++) {
3838 for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) {
3839 if (cmdp->cmdtype == CMDNORMAL)
3846 while ((name = *argptr) != NULL) {
3847 if ((cmdp = cmdlookup(name, 0)) != NULL
3848 && (cmdp->cmdtype == CMDNORMAL
3849 || (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0)))
3851 find_command(name, &entry, DO_ERR, pathval());
3852 if (entry.cmdtype == CMDUNKNOWN)
3861 * Resolve a command name. If you change this routine, you may have to
3862 * change the shellexec routine as well.
3866 find_command(char *name, struct cmdentry *entry, int act, const char *path)
3868 struct tblentry *cmdp;
3875 struct builtincmd *bcmd;
3877 /* If name contains a slash, don't use PATH or hash table */
3878 if (strchr(name, '/') != NULL) {
3879 entry->u.index = -1;
3881 while (stat(name, &statb) < 0) {
3886 entry->cmdtype = CMDUNKNOWN;
3890 entry->cmdtype = CMDNORMAL;
3894 #ifdef CONFIG_FEATURE_SH_STANDALONE_SHELL
3895 if (find_applet_by_name(name)) {
3896 entry->cmdtype = CMDNORMAL;
3897 entry->u.index = -1;
3902 updatetbl = (path == pathval());
3905 if (strstr(path, "%builtin") != NULL)
3909 /* If name is in the table, check answer will be ok */
3910 if ((cmdp = cmdlookup(name, 0)) != NULL) {
3913 switch (cmdp->cmdtype) {
3931 } else if (cmdp->rehash == 0)
3932 /* if not invalidated by cd, we're done */
3936 /* If %builtin not in path, check for builtin next */
3937 bcmd = find_builtin(name);
3938 if (bcmd && (IS_BUILTIN_REGULAR(bcmd) || (
3939 act & DO_ALTPATH ? !(act & DO_ALTBLTIN) : builtinloc <= 0
3941 goto builtin_success;
3943 /* We have to search path. */
3944 prev = -1; /* where to start */
3945 if (cmdp && cmdp->rehash) { /* doing a rehash */
3946 if (cmdp->cmdtype == CMDBUILTIN)
3949 prev = cmdp->param.index;
3955 while ((fullname = padvance(&path, name)) != NULL) {
3956 stunalloc(fullname);
3959 if (prefix(pathopt, "builtin")) {
3961 goto builtin_success;
3963 } else if (!(act & DO_NOFUNC) &&
3964 prefix(pathopt, "func")) {
3967 /* ignore unimplemented options */
3971 /* if rehash, don't redo absolute path names */
3972 if (fullname[0] == '/' && idx <= prev) {
3975 TRACE(("searchexec \"%s\": no change\n", name));
3978 while (stat(fullname, &statb) < 0) {
3983 if (errno != ENOENT && errno != ENOTDIR)
3987 e = EACCES; /* if we fail, this will be the error */
3988 if (!S_ISREG(statb.st_mode))
3990 if (pathopt) { /* this is a %func directory */
3991 stalloc(strlen(fullname) + 1);
3992 readcmdfile(fullname);
3993 if ((cmdp = cmdlookup(name, 0)) == NULL ||
3994 cmdp->cmdtype != CMDFUNCTION)
3995 sh_error("%s not defined in %s", name, fullname);
3996 stunalloc(fullname);
3999 TRACE(("searchexec \"%s\" returns \"%s\"\n", name, fullname));
4001 entry->cmdtype = CMDNORMAL;
4002 entry->u.index = idx;
4006 cmdp = cmdlookup(name, 1);
4007 cmdp->cmdtype = CMDNORMAL;
4008 cmdp->param.index = idx;
4013 /* We failed. If there was an entry for this command, delete it */
4014 if (cmdp && updatetbl)
4017 sh_warnx("%s: %s", name, errmsg(e, E_EXEC));
4018 entry->cmdtype = CMDUNKNOWN;
4023 entry->cmdtype = CMDBUILTIN;
4024 entry->u.cmd = bcmd;
4028 cmdp = cmdlookup(name, 1);
4029 cmdp->cmdtype = CMDBUILTIN;
4030 cmdp->param.cmd = bcmd;
4034 entry->cmdtype = cmdp->cmdtype;
4035 entry->u = cmdp->param;
4040 * Wrapper around strcmp for qsort/bsearch/...
4042 static int pstrcmp(const void *a, const void *b)
4044 return strcmp((const char *) a, (*(const char *const *) b) + 1);
4048 * Search the table of builtin commands.
4051 static struct builtincmd *
4052 find_builtin(const char *name)
4054 struct builtincmd *bp;
4057 name, builtincmd, NUMBUILTINS, sizeof(struct builtincmd),
4066 * Called when a cd is done. Marks all commands so the next time they
4067 * are executed they will be rehashed.
4073 struct tblentry **pp;
4074 struct tblentry *cmdp;
4076 for (pp = cmdtable ; pp < &cmdtable[CMDTABLESIZE] ; pp++) {
4077 for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) {
4078 if (cmdp->cmdtype == CMDNORMAL || (
4079 cmdp->cmdtype == CMDBUILTIN &&
4080 !(IS_BUILTIN_REGULAR(cmdp->param.cmd)) &&
4091 * Fix command hash table when PATH changed.
4092 * Called before PATH is changed. The argument is the new value of PATH;
4093 * pathval() still returns the old value at this point.
4094 * Called with interrupts off.
4098 changepath(const char *newval)
4100 const char *old, *new;
4107 firstchange = 9999; /* assume no change */
4113 if ((*old == '\0' && *new == ':')
4114 || (*old == ':' && *new == '\0'))
4116 old = new; /* ignore subsequent differences */
4120 if (*new == '%' && idx_bltin < 0 && prefix(new + 1, "builtin"))
4127 if (builtinloc < 0 && idx_bltin >= 0)
4128 builtinloc = idx_bltin; /* zap builtins */
4129 if (builtinloc >= 0 && idx_bltin < 0)
4131 clearcmdentry(firstchange);
4132 builtinloc = idx_bltin;
4137 * Clear out command entries. The argument specifies the first entry in
4138 * PATH which has changed.
4142 clearcmdentry(int firstchange)
4144 struct tblentry **tblp;
4145 struct tblentry **pp;
4146 struct tblentry *cmdp;
4149 for (tblp = cmdtable ; tblp < &cmdtable[CMDTABLESIZE] ; tblp++) {
4151 while ((cmdp = *pp) != NULL) {
4152 if ((cmdp->cmdtype == CMDNORMAL &&
4153 cmdp->param.index >= firstchange)
4154 || (cmdp->cmdtype == CMDBUILTIN &&
4155 builtinloc >= firstchange)) {
4169 * Locate a command in the command hash table. If "add" is nonzero,
4170 * add the command to the table if it is not already present. The
4171 * variable "lastcmdentry" is set to point to the address of the link
4172 * pointing to the entry, so that delete_cmd_entry can delete the
4175 * Interrupts must be off if called with add != 0.
4178 static struct tblentry **lastcmdentry;
4181 static struct tblentry *
4182 cmdlookup(const char *name, int add)
4184 unsigned int hashval;
4186 struct tblentry *cmdp;
4187 struct tblentry **pp;
4190 hashval = (unsigned char)*p << 4;
4192 hashval += (unsigned char)*p++;
4194 pp = &cmdtable[hashval % CMDTABLESIZE];
4195 for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) {
4196 if (equal(cmdp->cmdname, name))
4200 if (add && cmdp == NULL) {
4201 cmdp = *pp = ckmalloc(sizeof (struct tblentry) - ARB
4202 + strlen(name) + 1);
4204 cmdp->cmdtype = CMDUNKNOWN;
4205 strcpy(cmdp->cmdname, name);
4212 * Delete the command entry returned on the last lookup.
4216 delete_cmd_entry(void)
4218 struct tblentry *cmdp;
4221 cmdp = *lastcmdentry;
4222 *lastcmdentry = cmdp->next;
4223 if (cmdp->cmdtype == CMDFUNCTION)
4224 freefunc(cmdp->param.func);
4231 * Add a new command entry, replacing any existing command entry for
4232 * the same name - except special builtins.
4236 addcmdentry(char *name, struct cmdentry *entry)
4238 struct tblentry *cmdp;
4240 cmdp = cmdlookup(name, 1);
4241 if (cmdp->cmdtype == CMDFUNCTION) {
4242 freefunc(cmdp->param.func);
4244 cmdp->cmdtype = entry->cmdtype;
4245 cmdp->param = entry->u;
4250 * Make a copy of a parse tree.
4253 static inline struct funcnode *
4254 copyfunc(union node *n)
4259 funcblocksize = offsetof(struct funcnode, n);
4262 blocksize = funcblocksize;
4263 f = ckmalloc(blocksize + funcstringsize);
4264 funcblock = (char *) f + offsetof(struct funcnode, n);
4265 funcstring = (char *) f + blocksize;
4272 * Define a shell function.
4276 defun(char *name, union node *func)
4278 struct cmdentry entry;
4281 entry.cmdtype = CMDFUNCTION;
4282 entry.u.func = copyfunc(func);
4283 addcmdentry(name, &entry);
4289 * Delete a function if it exists.
4293 unsetfunc(const char *name)
4295 struct tblentry *cmdp;
4297 if ((cmdp = cmdlookup(name, 0)) != NULL &&
4298 cmdp->cmdtype == CMDFUNCTION)
4303 * Locate and print what a word is...
4307 #ifdef CONFIG_ASH_CMDCMD
4309 describe_command(char *command, int describe_command_verbose)
4311 #define describe_command_verbose 1
4313 describe_command(char *command)
4316 struct cmdentry entry;
4317 struct tblentry *cmdp;
4318 #ifdef CONFIG_ASH_ALIAS
4319 const struct alias *ap;
4321 const char *path = pathval();
4323 if (describe_command_verbose) {
4327 /* First look at the keywords */
4328 if (findkwd(command)) {
4329 out1str(describe_command_verbose ? " is a shell keyword" : command);
4333 #ifdef CONFIG_ASH_ALIAS
4334 /* Then look at the aliases */
4335 if ((ap = lookupalias(command, 0)) != NULL) {
4336 if (describe_command_verbose) {
4337 out1fmt(" is an alias for %s", ap->val);
4346 /* Then check if it is a tracked alias */
4347 if ((cmdp = cmdlookup(command, 0)) != NULL) {
4348 entry.cmdtype = cmdp->cmdtype;
4349 entry.u = cmdp->param;
4351 /* Finally use brute force */
4352 find_command(command, &entry, DO_ABS, path);
4355 switch (entry.cmdtype) {
4357 int j = entry.u.index;
4363 p = padvance(&path, command);
4367 if (describe_command_verbose) {
4369 (cmdp ? " a tracked alias for" : nullstr), p
4378 if (describe_command_verbose) {
4379 out1str(" is a shell function");
4386 if (describe_command_verbose) {
4387 out1fmt(" is a %sshell builtin",
4388 IS_BUILTIN_SPECIAL(entry.u.cmd) ?
4389 "special " : nullstr
4397 if (describe_command_verbose) {
4398 out1str(": not found\n");
4404 outstr("\n", stdout);
4409 typecmd(int argc, char **argv)
4414 for (i = 1; i < argc; i++) {
4415 #ifdef CONFIG_ASH_CMDCMD
4416 err |= describe_command(argv[i], 1);
4418 err |= describe_command(argv[i]);
4424 #ifdef CONFIG_ASH_CMDCMD
4426 commandcmd(int argc, char **argv)
4434 while ((c = nextopt("pvV")) != '\0')
4436 verify |= VERIFY_VERBOSE;
4438 verify |= VERIFY_BRIEF;
4444 return describe_command(*argptr, verify - VERIFY_BRIEF);
4453 * Routines to expand arguments to commands. We have to deal with
4454 * backquotes, shell variables, and file metacharacters.
4460 #define RMESCAPE_ALLOC 0x1 /* Allocate a new string */
4461 #define RMESCAPE_GLOB 0x2 /* Add backslashes for glob */
4462 #define RMESCAPE_QUOTED 0x4 /* Remove CTLESC unless in quotes */
4463 #define RMESCAPE_GROW 0x8 /* Grow strings instead of stalloc */
4464 #define RMESCAPE_HEAP 0x10 /* Malloc strings instead of stalloc */
4467 * Structure specifying which parts of the string should be searched
4468 * for IFS characters.
4472 struct ifsregion *next; /* next region in list */
4473 int begoff; /* offset of start of region */
4474 int endoff; /* offset of end of region */
4475 int nulonly; /* search for nul bytes only */
4478 /* output of current string */
4479 static char *expdest;
4480 /* list of back quote expressions */
4481 static struct nodelist *argbackq;
4482 /* first struct in list of ifs regions */
4483 static struct ifsregion ifsfirst;
4484 /* last struct in list */
4485 static struct ifsregion *ifslastp;
4486 /* holds expanded arg list */
4487 static struct arglist exparg;
4489 static void argstr(char *, int);
4490 static char *exptilde(char *, char *, int);
4491 static void expbackq(union node *, int, int);
4492 static const char *subevalvar(char *, char *, int, int, int, int, int);
4493 static char *evalvar(char *, int);
4494 static void strtodest(const char *, int, int);
4495 static void memtodest(const char *p, size_t len, int syntax, int quotes);
4496 static ssize_t varvalue(char *, int, int);
4497 static void recordregion(int, int, int);
4498 static void removerecordregions(int);
4499 static void ifsbreakup(char *, struct arglist *);
4500 static void ifsfree(void);
4501 static void expandmeta(struct strlist *, int);
4502 static int patmatch(char *, const char *);
4504 static int cvtnum(arith_t);
4505 static size_t esclen(const char *, const char *);
4506 static char *scanleft(char *, char *, char *, char *, int, int);
4507 static char *scanright(char *, char *, char *, char *, int, int);
4508 static void varunset(const char *, const char *, const char *, int)
4512 #define pmatch(a, b) !fnmatch((a), (b), 0)
4514 * Prepare a pattern for a expmeta (internal glob(3)) call.
4516 * Returns an stalloced string.
4519 static inline char *
4520 preglob(const char *pattern, int quoted, int flag) {
4521 flag |= RMESCAPE_GLOB;
4523 flag |= RMESCAPE_QUOTED;
4525 return _rmescapes((char *)pattern, flag);
4530 esclen(const char *start, const char *p) {
4533 while (p > start && *--p == CTLESC) {
4541 * Expand shell variables and backquotes inside a here document.
4545 expandhere(union node *arg, int fd)
4548 expandarg(arg, (struct arglist *)NULL, 0);
4549 bb_full_write(fd, stackblock(), expdest - (char *)stackblock());
4554 * Perform variable substitution and command substitution on an argument,
4555 * placing the resulting list of arguments in arglist. If EXP_FULL is true,
4556 * perform splitting and file name expansion. When arglist is NULL, perform
4557 * here document expansion.
4561 expandarg(union node *arg, struct arglist *arglist, int flag)
4566 argbackq = arg->narg.backquote;
4567 STARTSTACKSTR(expdest);
4568 ifsfirst.next = NULL;
4570 argstr(arg->narg.text, flag);
4571 p = _STPUTC('\0', expdest);
4573 if (arglist == NULL) {
4574 return; /* here document expanded */
4576 p = grabstackstr(p);
4577 exparg.lastp = &exparg.list;
4581 if (flag & EXP_FULL) {
4582 ifsbreakup(p, &exparg);
4583 *exparg.lastp = NULL;
4584 exparg.lastp = &exparg.list;
4585 expandmeta(exparg.list, flag);
4587 if (flag & EXP_REDIR) /*XXX - for now, just remove escapes */
4589 sp = (struct strlist *)stalloc(sizeof (struct strlist));
4592 exparg.lastp = &sp->next;
4596 *exparg.lastp = NULL;
4598 *arglist->lastp = exparg.list;
4599 arglist->lastp = exparg.lastp;
4605 * Perform variable and command substitution. If EXP_FULL is set, output CTLESC
4606 * characters to allow for further processing. Otherwise treat
4607 * $@ like $* since no splitting will be performed.
4611 argstr(char *p, int flag)
4613 static const char spclchars[] = {
4621 CTLBACKQ | CTLQUOTE,
4622 #ifdef CONFIG_ASH_MATH_SUPPORT
4627 const char *reject = spclchars;
4629 int quotes = flag & (EXP_FULL | EXP_CASE); /* do CTLESC */
4630 int breakall = flag & EXP_WORD;
4635 if (!(flag & EXP_VARTILDE)) {
4637 } else if (flag & EXP_VARTILDE2) {
4642 if (flag & EXP_TILDE) {
4648 if (*q == CTLESC && (flag & EXP_QWORD))
4651 p = exptilde(p, q, flag);
4654 startloc = expdest - (char *)stackblock();
4656 length += strcspn(p + length, reject);
4658 if (c && (!(c & 0x80)
4659 #ifdef CONFIG_ASH_MATH_SUPPORT
4663 /* c == '=' || c == ':' || c == CTLENDARI */
4668 expdest = stnputs(p, length, expdest);
4669 newloc = expdest - (char *)stackblock();
4670 if (breakall && !inquotes && newloc > startloc) {
4671 recordregion(startloc, newloc, 0);
4682 if (flag & EXP_VARTILDE2) {
4686 flag |= EXP_VARTILDE2;
4691 * sort of a hack - expand tildes in variable
4692 * assignments (after the first '=' and after ':'s).
4701 case CTLENDVAR: /* ??? */
4704 /* "$@" syntax adherence hack */
4707 !memcmp(p, dolatstr, DOLATSTRLEN) &&
4708 (p[4] == CTLQUOTEMARK || (
4709 p[4] == CTLENDVAR &&
4710 p[5] == CTLQUOTEMARK
4713 p = evalvar(p + 1, flag) + 1;
4716 inquotes = !inquotes;
4729 p = evalvar(p, flag);
4733 case CTLBACKQ|CTLQUOTE:
4734 expbackq(argbackq->n, c, quotes);
4735 argbackq = argbackq->next;
4737 #ifdef CONFIG_ASH_MATH_SUPPORT
4750 exptilde(char *startp, char *p, int flag)
4756 int quotes = flag & (EXP_FULL | EXP_CASE);
4761 while ((c = *++p) != '\0') {
4768 if (flag & EXP_VARTILDE)
4778 if (*name == '\0') {
4779 home = lookupvar(homestr);
4781 if ((pw = getpwnam(name)) == NULL)
4785 if (!home || !*home)
4788 startloc = expdest - (char *)stackblock();
4789 strtodest(home, SQSYNTAX, quotes);
4790 recordregion(startloc, expdest - (char *)stackblock(), 0);
4799 removerecordregions(int endoff)
4801 if (ifslastp == NULL)
4804 if (ifsfirst.endoff > endoff) {
4805 while (ifsfirst.next != NULL) {
4806 struct ifsregion *ifsp;
4808 ifsp = ifsfirst.next->next;
4809 ckfree(ifsfirst.next);
4810 ifsfirst.next = ifsp;
4813 if (ifsfirst.begoff > endoff)
4816 ifslastp = &ifsfirst;
4817 ifsfirst.endoff = endoff;
4822 ifslastp = &ifsfirst;
4823 while (ifslastp->next && ifslastp->next->begoff < endoff)
4824 ifslastp=ifslastp->next;
4825 while (ifslastp->next != NULL) {
4826 struct ifsregion *ifsp;
4828 ifsp = ifslastp->next->next;
4829 ckfree(ifslastp->next);
4830 ifslastp->next = ifsp;
4833 if (ifslastp->endoff > endoff)
4834 ifslastp->endoff = endoff;
4838 #ifdef CONFIG_ASH_MATH_SUPPORT
4840 * Expand arithmetic expression. Backup to start of expression,
4841 * evaluate, place result in (backed up) result, adjust string position.
4854 * This routine is slightly over-complicated for
4855 * efficiency. Next we scan backwards looking for the
4856 * start of arithmetic.
4858 start = stackblock();
4865 while (*p != CTLARI) {
4869 sh_error("missing CTLARI (shouldn't happen)");
4874 esc = esclen(start, p);
4884 removerecordregions(begoff);
4893 len = cvtnum(dash_arith(p + 2));
4896 recordregion(begoff, begoff + len, 0);
4901 * Expand stuff in backwards quotes.
4905 expbackq(union node *cmd, int quoted, int quotes)
4913 int syntax = quoted? DQSYNTAX : BASESYNTAX;
4914 struct stackmark smark;
4917 setstackmark(&smark);
4919 startloc = dest - (char *)stackblock();
4921 evalbackcmd(cmd, (struct backcmd *) &in);
4922 popstackmark(&smark);
4929 memtodest(p, i, syntax, quotes);
4933 i = safe_read(in.fd, buf, sizeof buf);
4934 TRACE(("expbackq: read returns %d\n", i));
4944 back_exitstatus = waitforjob(in.jp);
4948 /* Eat all trailing newlines */
4950 for (; dest > (char *)stackblock() && dest[-1] == '\n';)
4955 recordregion(startloc, dest - (char *)stackblock(), 0);
4956 TRACE(("evalbackq: size=%d: \"%.*s\"\n",
4957 (dest - (char *)stackblock()) - startloc,
4958 (dest - (char *)stackblock()) - startloc,
4959 stackblock() + startloc));
4964 scanleft(char *startp, char *rmesc, char *rmescend, char *str, int quotes,
4975 const char *s = loc2;
4981 match = pmatch(str, s);
4985 if (quotes && *loc == CTLESC)
4995 scanright(char *startp, char *rmesc, char *rmescend, char *str, int quotes,
5002 for (loc = str - 1, loc2 = rmescend; loc >= startp; loc2--) {
5005 const char *s = loc2;
5010 match = pmatch(str, s);
5017 esc = esclen(startp, loc);
5029 subevalvar(char *p, char *str, int strloc, int subtype, int startloc, int varflags, int quotes)
5033 int saveherefd = herefd;
5034 struct nodelist *saveargbackq = argbackq;
5036 char *rmesc, *rmescend;
5038 char *(*scan)(char *, char *, char *, char *, int , int);
5041 argstr(p, subtype != VSASSIGN && subtype != VSQUESTION ? EXP_CASE : 0);
5042 STPUTC('\0', expdest);
5043 herefd = saveherefd;
5044 argbackq = saveargbackq;
5045 startp = stackblock() + startloc;
5049 setvar(str, startp, 0);
5050 amount = startp - expdest;
5051 STADJUST(amount, expdest);
5055 varunset(p, str, startp, varflags);
5059 subtype -= VSTRIMRIGHT;
5061 if (subtype < 0 || subtype > 3)
5066 rmescend = stackblock() + strloc;
5068 rmesc = _rmescapes(startp, RMESCAPE_ALLOC | RMESCAPE_GROW);
5069 if (rmesc != startp) {
5071 startp = stackblock() + startloc;
5075 str = stackblock() + strloc;
5076 preglob(str, varflags & VSQUOTE, 0);
5078 /* zero = subtype == VSTRIMLEFT || subtype == VSTRIMLEFTMAX */
5079 zero = subtype >> 1;
5080 /* VSTRIMLEFT/VSTRIMRIGHTMAX -> scanleft */
5081 scan = (subtype & 1) ^ zero ? scanleft : scanright;
5083 loc = scan(startp, rmesc, rmescend, str, quotes, zero);
5086 memmove(startp, loc, str - loc);
5087 loc = startp + (str - loc) - 1;
5090 amount = loc - expdest;
5091 STADJUST(amount, expdest);
5098 * Expand a variable, and return a pointer to the next character in the
5102 evalvar(char *p, int flag)
5115 quotes = flag & (EXP_FULL | EXP_CASE);
5117 subtype = varflags & VSTYPE;
5118 quoted = varflags & VSQUOTE;
5120 easy = (!quoted || (*var == '@' && shellparam.nparam));
5121 startloc = expdest - (char *)stackblock();
5122 p = strchr(p, '=') + 1;
5125 varlen = varvalue(var, varflags, flag);
5126 if (varflags & VSNUL)
5129 if (subtype == VSPLUS) {
5130 varlen = -1 - varlen;
5134 if (subtype == VSMINUS) {
5138 p, flag | EXP_TILDE |
5139 (quoted ? EXP_QWORD : EXP_WORD)
5148 if (subtype == VSASSIGN || subtype == VSQUESTION) {
5150 if (subevalvar(p, var, 0, subtype, startloc,
5154 * Remove any recorded regions beyond
5157 removerecordregions(startloc);
5167 if (varlen < 0 && uflag)
5168 varunset(p, var, 0, 0);
5170 if (subtype == VSLENGTH) {
5171 cvtnum(varlen > 0 ? varlen : 0);
5175 if (subtype == VSNORMAL) {
5179 recordregion(startloc, expdest - (char *)stackblock(), quoted);
5188 case VSTRIMRIGHTMAX:
5197 * Terminate the string and start recording the pattern
5200 STPUTC('\0', expdest);
5201 patloc = expdest - (char *)stackblock();
5202 if (subevalvar(p, NULL, patloc, subtype,
5203 startloc, varflags, quotes) == 0) {
5204 int amount = expdest - (
5205 (char *)stackblock() + patloc - 1
5207 STADJUST(-amount, expdest);
5209 /* Remove any recorded regions beyond start of variable */
5210 removerecordregions(startloc);
5215 if (subtype != VSNORMAL) { /* skip to end of alternative */
5218 if ((c = *p++) == CTLESC)
5220 else if (c == CTLBACKQ || c == (CTLBACKQ|CTLQUOTE)) {
5222 argbackq = argbackq->next;
5223 } else if (c == CTLVAR) {
5224 if ((*p++ & VSTYPE) != VSNORMAL)
5226 } else if (c == CTLENDVAR) {
5237 * Put a string on the stack.
5241 memtodest(const char *p, size_t len, int syntax, int quotes) {
5244 q = makestrspace(len * 2, q);
5250 if (quotes && (SIT(c, syntax) == CCTL || SIT(c, syntax) == CBACK))
5260 strtodest(const char *p, int syntax, int quotes)
5262 memtodest(p, strlen(p), syntax, quotes);
5267 * Add the value of a specialized variable to the stack string.
5271 varvalue(char *name, int varflags, int flags)
5281 int quoted = varflags & VSQUOTE;
5282 int subtype = varflags & VSTYPE;
5283 int quotes = flags & (EXP_FULL | EXP_CASE);
5285 if (quoted && (flags & EXP_FULL))
5286 sep = 1 << CHAR_BIT;
5288 syntax = quoted ? DQSYNTAX : BASESYNTAX;
5297 num = shellparam.nparam;
5307 p = makestrspace(NOPTS, expdest);
5308 for (i = NOPTS - 1; i >= 0; i--) {
5310 USTPUTC(optletters(i), p);
5321 sep = ifsset() ? ifsval()[0] : ' ';
5322 if (quotes && (SIT(sep, syntax) == CCTL || SIT(sep, syntax) == CBACK))
5325 if (!(ap = shellparam.p))
5327 while ((p = *ap++)) {
5330 partlen = strlen(p);
5333 if (!(subtype == VSPLUS || subtype == VSLENGTH))
5334 memtodest(p, partlen, syntax, quotes);
5340 if (subtype == VSPLUS || subtype == VSLENGTH) {
5362 if (num < 0 || num > shellparam.nparam)
5364 p = num ? shellparam.p[num - 1] : arg0;
5367 p = lookupvar(name);
5373 if (!(subtype == VSPLUS || subtype == VSLENGTH))
5374 memtodest(p, len, syntax, quotes);
5378 if (subtype == VSPLUS || subtype == VSLENGTH)
5379 STADJUST(-len, expdest);
5385 * Record the fact that we have to scan this region of the
5386 * string for IFS characters.
5390 recordregion(int start, int end, int nulonly)
5392 struct ifsregion *ifsp;
5394 if (ifslastp == NULL) {
5398 ifsp = (struct ifsregion *)ckmalloc(sizeof (struct ifsregion));
5400 ifslastp->next = ifsp;
5404 ifslastp->begoff = start;
5405 ifslastp->endoff = end;
5406 ifslastp->nulonly = nulonly;
5411 * Break the argument string into pieces based upon IFS and add the
5412 * strings to the argument list. The regions of the string to be
5413 * searched for IFS characters have been stored by recordregion.
5416 ifsbreakup(char *string, struct arglist *arglist)
5418 struct ifsregion *ifsp;
5423 const char *ifs, *realifs;
5429 if (ifslastp != NULL) {
5432 realifs = ifsset() ? ifsval() : defifs;
5435 p = string + ifsp->begoff;
5436 nulonly = ifsp->nulonly;
5437 ifs = nulonly ? nullstr : realifs;
5439 while (p < string + ifsp->endoff) {
5443 if (strchr(ifs, *p)) {
5445 ifsspc = (strchr(defifs, *p) != NULL);
5446 /* Ignore IFS whitespace at start */
5447 if (q == start && ifsspc) {
5453 sp = (struct strlist *)stalloc(sizeof *sp);
5455 *arglist->lastp = sp;
5456 arglist->lastp = &sp->next;
5460 if (p >= string + ifsp->endoff) {
5466 if (strchr(ifs, *p) == NULL ) {
5469 } else if (strchr(defifs, *p) == NULL) {
5485 } while ((ifsp = ifsp->next) != NULL);
5494 sp = (struct strlist *)stalloc(sizeof *sp);
5496 *arglist->lastp = sp;
5497 arglist->lastp = &sp->next;
5503 struct ifsregion *p;
5508 struct ifsregion *ifsp;
5514 ifsfirst.next = NULL;
5518 static void expmeta(char *, char *);
5519 static struct strlist *expsort(struct strlist *);
5520 static struct strlist *msort(struct strlist *, int);
5522 static char *expdir;
5526 expandmeta(struct strlist *str, int flag)
5528 static const char metachars[] = {
5531 /* TODO - EXP_REDIR */
5534 struct strlist **savelastp;
5540 if (!strpbrk(str->text, metachars))
5542 savelastp = exparg.lastp;
5545 p = preglob(str->text, 0, RMESCAPE_ALLOC | RMESCAPE_HEAP);
5547 int i = strlen(str->text);
5548 expdir = ckmalloc(i < 2048 ? 2048 : i); /* XXX */
5556 if (exparg.lastp == savelastp) {
5561 *exparg.lastp = str;
5562 rmescapes(str->text);
5563 exparg.lastp = &str->next;
5565 *exparg.lastp = NULL;
5566 *savelastp = sp = expsort(*savelastp);
5567 while (sp->next != NULL)
5569 exparg.lastp = &sp->next;
5576 * Add a file name to the list.
5580 addfname(const char *name)
5584 sp = (struct strlist *)stalloc(sizeof *sp);
5585 sp->text = sstrdup(name);
5587 exparg.lastp = &sp->next;
5592 * Do metacharacter (i.e. *, ?, [...]) expansion.
5596 expmeta(char *enddir, char *name)
5611 for (p = name; *p; p++) {
5612 if (*p == '*' || *p == '?')
5614 else if (*p == '[') {
5621 if (*q == '/' || *q == '\0')
5628 } else if (*p == '\\')
5630 else if (*p == '/') {
5637 if (metaflag == 0) { /* we've reached the end of the file name */
5638 if (enddir != expdir)
5646 if (metaflag == 0 || lstat(expdir, &statb) >= 0)
5657 } while (p < start);
5659 if (enddir == expdir) {
5661 } else if (enddir == expdir + 1 && *expdir == '/') {
5667 if ((dirp = opendir(cp)) == NULL)
5669 if (enddir != expdir)
5671 if (*endname == 0) {
5683 while (! intpending && (dp = readdir(dirp)) != NULL) {
5684 if (dp->d_name[0] == '.' && ! matchdot)
5686 if (pmatch(start, dp->d_name)) {
5688 scopy(dp->d_name, enddir);
5691 for (p = enddir, cp = dp->d_name;
5692 (*p++ = *cp++) != '\0';)
5695 expmeta(p, endname);
5705 * Sort the results of file name expansion. It calculates the number of
5706 * strings to sort and then calls msort (short for merge sort) to do the
5710 static struct strlist *
5711 expsort(struct strlist *str)
5717 for (sp = str ; sp ; sp = sp->next)
5719 return msort(str, len);
5723 static struct strlist *
5724 msort(struct strlist *list, int len)
5726 struct strlist *p, *q = NULL;
5727 struct strlist **lpp;
5735 for (n = half ; --n >= 0 ; ) {
5739 q->next = NULL; /* terminate first half of list */
5740 q = msort(list, half); /* sort first half of list */
5741 p = msort(p, len - half); /* sort second half */
5744 #ifdef CONFIG_LOCALE_SUPPORT
5745 if (strcoll(p->text, q->text) < 0)
5747 if (strcmp(p->text, q->text) < 0)
5752 if ((p = *lpp) == NULL) {
5759 if ((q = *lpp) == NULL) {
5770 * Returns true if the pattern matches the string.
5774 patmatch(char *pattern, const char *string)
5776 return pmatch(preglob(pattern, 0, 0), string);
5781 * Remove any CTLESC characters from a string.
5785 _rmescapes(char *str, int flag)
5788 static const char qchars[] = { CTLESC, CTLQUOTEMARK, 0 };
5793 p = strpbrk(str, qchars);
5799 if (flag & RMESCAPE_ALLOC) {
5800 size_t len = p - str;
5801 size_t fulllen = len + strlen(p) + 1;
5803 if (flag & RMESCAPE_GROW) {
5804 r = makestrspace(fulllen, expdest);
5805 } else if (flag & RMESCAPE_HEAP) {
5806 r = ckmalloc(fulllen);
5808 r = stalloc(fulllen);
5812 q = mempcpy(q, str, len);
5815 inquotes = (flag & RMESCAPE_QUOTED) ^ RMESCAPE_QUOTED;
5816 globbing = flag & RMESCAPE_GLOB;
5817 notescaped = globbing;
5819 if (*p == CTLQUOTEMARK) {
5820 inquotes = ~inquotes;
5822 notescaped = globbing;
5826 /* naked back slash */
5832 if (notescaped && inquotes && *p != '/') {
5836 notescaped = globbing;
5841 if (flag & RMESCAPE_GROW) {
5843 STADJUST(q - r + 1, expdest);
5850 * See if a pattern matches in a case statement.
5854 casematch(union node *pattern, char *val)
5856 struct stackmark smark;
5859 setstackmark(&smark);
5860 argbackq = pattern->narg.backquote;
5861 STARTSTACKSTR(expdest);
5863 argstr(pattern->narg.text, EXP_TILDE | EXP_CASE);
5864 STACKSTRNUL(expdest);
5865 result = patmatch(stackblock(), val);
5866 popstackmark(&smark);
5879 expdest = makestrspace(32, expdest);
5880 #ifdef CONFIG_ASH_MATH_SUPPORT_64
5881 len = fmtstr(expdest, 32, "%lld", (long long) num);
5883 len = fmtstr(expdest, 32, "%ld", num);
5885 STADJUST(len, expdest);
5890 varunset(const char *end, const char *var, const char *umsg, int varflags)
5896 msg = "parameter not set";
5898 if (*end == CTLENDVAR) {
5899 if (varflags & VSNUL)
5904 sh_error("%.*s: %s%s", end - var - 1, var, msg, tail);
5911 * This implements the input routines used by the parser.
5914 #define EOF_NLEFT -99 /* value of parsenleft when EOF pushed back */
5916 static void pushfile(void);
5919 * Read a character from the script, returning PEOF on end of file.
5920 * Nul characters in the input are silently discarded.
5923 #define pgetc_as_macro() (--parsenleft >= 0? *parsenextc++ : preadbuffer())
5925 #ifdef CONFIG_ASH_OPTIMIZE_FOR_SIZE
5926 #define pgetc_macro() pgetc()
5930 return pgetc_as_macro();
5933 #define pgetc_macro() pgetc_as_macro()
5937 return pgetc_macro();
5943 * Same as pgetc(), but ignores PEOA.
5945 #ifdef CONFIG_ASH_ALIAS
5946 static int pgetc2(void)
5952 } while (c == PEOA);
5956 static inline int pgetc2(void)
5958 return pgetc_macro();
5963 * Read a line from the script.
5966 static inline char *
5967 pfgets(char *line, int len)
5973 while (--nleft > 0) {
5990 #ifdef CONFIG_FEATURE_COMMAND_EDITING
5991 #ifdef CONFIG_ASH_EXPAND_PRMT
5992 static char *cmdedit_prompt;
5994 static const char *cmdedit_prompt;
5996 static inline void putprompt(const char *s)
5998 #ifdef CONFIG_ASH_EXPAND_PRMT
5999 free(cmdedit_prompt);
6000 cmdedit_prompt = bb_xstrdup(s);
6006 static inline void putprompt(const char *s)
6016 char *buf = parsefile->buf;
6020 #ifdef CONFIG_FEATURE_COMMAND_EDITING
6021 if (!iflag || parsefile->fd)
6022 nr = safe_read(parsefile->fd, buf, BUFSIZ - 1);
6024 #ifdef CONFIG_FEATURE_COMMAND_TAB_COMPLETION
6025 cmdedit_path_lookup = pathval();
6027 nr = cmdedit_read_input((char *) cmdedit_prompt, buf);
6029 /* Ctrl+C presend */
6038 if(nr < 0 && errno == 0) {
6039 /* Ctrl+D presend */
6044 nr = safe_read(parsefile->fd, buf, BUFSIZ - 1);
6048 if (parsefile->fd == 0 && errno == EWOULDBLOCK) {
6049 int flags = fcntl(0, F_GETFL, 0);
6050 if (flags >= 0 && flags & O_NONBLOCK) {
6051 flags &=~ O_NONBLOCK;
6052 if (fcntl(0, F_SETFL, flags) >= 0) {
6053 out2str("sh: turning off NDELAY mode\n");
6063 * Refill the input buffer and return the next input character:
6065 * 1) If a string was pushed back on the input, pop it;
6066 * 2) If an EOF was pushed back (parsenleft == EOF_NLEFT) or we are reading
6067 * from a string so we can't refill the buffer, return EOF.
6068 * 3) If the is more stuff in this buffer, use it else call read to fill it.
6069 * 4) Process input up to the next newline, deleting nul characters.
6079 while (parsefile->strpush) {
6080 #ifdef CONFIG_ASH_ALIAS
6081 if (parsenleft == -1 && parsefile->strpush->ap &&
6082 parsenextc[-1] != ' ' && parsenextc[-1] != '\t') {
6087 if (--parsenleft >= 0)
6088 return (*parsenextc++);
6090 if (parsenleft == EOF_NLEFT || parsefile->buf == NULL)
6097 if ((more = preadfd()) <= 0) {
6098 parselleft = parsenleft = EOF_NLEFT;
6105 /* delete nul characters */
6113 memmove(q, q + 1, more);
6117 parsenleft = q - parsenextc - 1;
6123 parsenleft = q - parsenextc - 1;
6135 out2str(parsenextc);
6140 return *parsenextc++;
6144 * Undo the last call to pgetc. Only one character may be pushed back.
6145 * PEOF may be pushed back.
6156 * Push a string back onto the input at this current parsefile level.
6157 * We handle aliases this way.
6160 pushstring(char *s, void *ap)
6167 /*dprintf("*** calling pushstring: %s, %d\n", s, len);*/
6168 if (parsefile->strpush) {
6169 sp = ckmalloc(sizeof (struct strpush));
6170 sp->prev = parsefile->strpush;
6171 parsefile->strpush = sp;
6173 sp = parsefile->strpush = &(parsefile->basestrpush);
6174 sp->prevstring = parsenextc;
6175 sp->prevnleft = parsenleft;
6176 #ifdef CONFIG_ASH_ALIAS
6177 sp->ap = (struct alias *)ap;
6179 ((struct alias *)ap)->flag |= ALIASINUSE;
6191 struct strpush *sp = parsefile->strpush;
6194 #ifdef CONFIG_ASH_ALIAS
6196 if (parsenextc[-1] == ' ' || parsenextc[-1] == '\t') {
6197 checkkwd |= CHKALIAS;
6199 if (sp->string != sp->ap->val) {
6202 sp->ap->flag &= ~ALIASINUSE;
6203 if (sp->ap->flag & ALIASDEAD) {
6204 unalias(sp->ap->name);
6208 parsenextc = sp->prevstring;
6209 parsenleft = sp->prevnleft;
6210 /*dprintf("*** calling popstring: restoring to '%s'\n", parsenextc);*/
6211 parsefile->strpush = sp->prev;
6212 if (sp != &(parsefile->basestrpush))
6218 * Set the input to take input from a file. If push is set, push the
6219 * old input onto the stack first.
6223 setinputfile(const char *fname, int flags)
6229 if ((fd = open(fname, O_RDONLY)) < 0) {
6230 if (flags & INPUT_NOFILE_OK)
6232 sh_error("Can't open %s", fname);
6235 fd2 = copyfd(fd, 10);
6238 sh_error("Out of file descriptors");
6241 setinputfd(fd, flags & INPUT_PUSH_FILE);
6249 * Like setinputfile, but takes an open file descriptor. Call this with
6254 setinputfd(int fd, int push)
6256 (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
6262 if (parsefile->buf == NULL)
6263 parsefile->buf = ckmalloc(IBUFSIZ);
6264 parselleft = parsenleft = 0;
6270 * Like setinputfile, but takes input from a string.
6274 setinputstring(char *string)
6278 parsenextc = string;
6279 parsenleft = strlen(string);
6280 parsefile->buf = NULL;
6287 * To handle the "." command, a stack of input files is used. Pushfile
6288 * adds a new entry to the stack and popfile restores the previous level.
6294 struct parsefile *pf;
6296 parsefile->nleft = parsenleft;
6297 parsefile->lleft = parselleft;
6298 parsefile->nextc = parsenextc;
6299 parsefile->linno = plinno;
6300 pf = (struct parsefile *)ckmalloc(sizeof (struct parsefile));
6301 pf->prev = parsefile;
6304 pf->basestrpush.prev = NULL;
6312 struct parsefile *pf = parsefile;
6321 parsefile = pf->prev;
6323 parsenleft = parsefile->nleft;
6324 parselleft = parsefile->lleft;
6325 parsenextc = parsefile->nextc;
6326 plinno = parsefile->linno;
6332 * Return to top level.
6338 while (parsefile != &basepf)
6344 * Close the file(s) that the shell is reading commands from. Called
6345 * after a fork is done.
6352 if (parsefile->fd > 0) {
6353 close(parsefile->fd);
6360 /* mode flags for set_curjob */
6361 #define CUR_DELETE 2
6362 #define CUR_RUNNING 1
6363 #define CUR_STOPPED 0
6365 /* mode flags for dowait */
6366 #define DOWAIT_NORMAL 0
6367 #define DOWAIT_BLOCK 1
6370 static struct job *jobtab;
6372 static unsigned njobs;
6374 /* pgrp of shell on invocation */
6375 static int initialpgrp;
6376 static int ttyfd = -1;
6379 static struct job *curjob;
6380 /* number of presumed living untracked jobs */
6383 static void set_curjob(struct job *, unsigned);
6385 static int restartjob(struct job *, int);
6386 static void xtcsetpgrp(int, pid_t);
6387 static char *commandtext(union node *);
6388 static void cmdlist(union node *, int);
6389 static void cmdtxt(union node *);
6390 static void cmdputs(const char *);
6391 static void showpipe(struct job *, FILE *);
6393 static int sprint_status(char *, int, int);
6394 static void freejob(struct job *);
6395 static struct job *getjob(const char *, int);
6396 static struct job *growjobtab(void);
6397 static void forkchild(struct job *, union node *, int);
6398 static void forkparent(struct job *, union node *, int, pid_t);
6399 static int dowait(int, struct job *);
6400 static int getstatus(struct job *);
6403 set_curjob(struct job *jp, unsigned mode)
6406 struct job **jpp, **curp;
6408 /* first remove from list */
6409 jpp = curp = &curjob;
6414 jpp = &jp1->prev_job;
6416 *jpp = jp1->prev_job;
6418 /* Then re-insert in correct position */
6426 /* job being deleted */
6429 /* newly created job or backgrounded job,
6430 put after all stopped jobs. */
6434 if (!jp1 || jp1->state != JOBSTOPPED)
6437 jpp = &jp1->prev_job;
6443 /* newly stopped job - becomes curjob */
6444 jp->prev_job = *jpp;
6452 * Turn job control on and off.
6454 * Note: This code assumes that the third arg to ioctl is a character
6455 * pointer, which is true on Berkeley systems but not System V. Since
6456 * System V doesn't have job control yet, this isn't a problem now.
6458 * Called with interrupts off.
6467 if (on == jobctl || rootshell == 0)
6471 ofd = fd = open(_PATH_TTY, O_RDWR);
6474 while (!isatty(fd) && --fd >= 0)
6477 fd = fcntl(fd, F_DUPFD, 10);
6481 fcntl(fd, F_SETFD, FD_CLOEXEC);
6482 do { /* while we are in the background */
6483 if ((pgrp = tcgetpgrp(fd)) < 0) {
6485 sh_warnx("can't access tty; job control turned off");
6489 if (pgrp == getpgrp())
6500 xtcsetpgrp(fd, pgrp);
6502 /* turning job control off */
6505 xtcsetpgrp(fd, pgrp);
6519 killcmd(int argc, char **argv)
6530 "Usage: kill [-s sigspec | -signum | -sigspec] [pid | job]... or\n"
6531 "kill -l [exitstatus]"
6535 if (**++argv == '-') {
6536 signo = decode_signal(*argv + 1, 1);
6540 while ((c = nextopt("ls:")) != '\0')
6550 signo = decode_signal(optionarg, 1);
6553 "invalid signal number or name: %s",
6564 if (!list && signo < 0)
6567 if ((signo < 0 || !*argv) ^ list) {
6575 for (i = 1; i < NSIG; i++) {
6576 name = u_signal_names(0, &i, 1);
6578 out1fmt(snlfmt, name);
6582 name = u_signal_names(*argptr, &signo, -1);
6584 out1fmt(snlfmt, name);
6586 sh_error("invalid signal number or exit status: %s", *argptr);
6592 if (**argv == '%') {
6593 jp = getjob(*argv, 0);
6594 pid = -jp->ps[0].pid;
6596 pid = **argv == '-' ?
6597 -number(*argv + 1) : number(*argv);
6599 if (kill(pid, signo) != 0) {
6600 sh_warnx("(%d) - %m", pid);
6609 #if defined(JOBS) || defined(DEBUG)
6611 jobno(const struct job *jp)
6613 return jp - jobtab + 1;
6619 fgcmd(int argc, char **argv)
6626 mode = (**argv == 'f') ? FORK_FG : FORK_BG;
6631 jp = getjob(*argv, 1);
6632 if (mode == FORK_BG) {
6633 set_curjob(jp, CUR_RUNNING);
6634 fprintf(out, "[%d] ", jobno(jp));
6636 outstr(jp->ps->cmd, out);
6638 retval = restartjob(jp, mode);
6639 } while (*argv && *++argv);
6643 static int bgcmd(int, char **) __attribute__((__alias__("fgcmd")));
6647 restartjob(struct job *jp, int mode)
6649 struct procstat *ps;
6655 if (jp->state == JOBDONE)
6657 jp->state = JOBRUNNING;
6659 if (mode == FORK_FG)
6660 xtcsetpgrp(ttyfd, pgid);
6661 killpg(pgid, SIGCONT);
6665 if (WIFSTOPPED(ps->status)) {
6668 } while (ps++, --i);
6670 status = (mode == FORK_FG) ? waitforjob(jp) : 0;
6677 sprint_status(char *s, int status, int sigonly)
6683 if (!WIFEXITED(status)) {
6685 if (WIFSTOPPED(status))
6686 st = WSTOPSIG(status);
6689 st = WTERMSIG(status);
6691 if (st == SIGINT || st == SIGPIPE)
6694 if (WIFSTOPPED(status))
6699 col = fmtstr(s, 32, strsignal(st));
6700 if (WCOREDUMP(status)) {
6701 col += fmtstr(s + col, 16, " (core dumped)");
6703 } else if (!sigonly) {
6704 st = WEXITSTATUS(status);
6706 col = fmtstr(s, 16, "Done(%d)", st);
6708 col = fmtstr(s, 16, "Done");
6717 showjob(FILE *out, struct job *jp, int mode)
6719 struct procstat *ps;
6720 struct procstat *psend;
6727 if (mode & SHOW_PGID) {
6728 /* just output process (group) id of pipeline */
6729 fprintf(out, "%d\n", ps->pid);
6733 col = fmtstr(s, 16, "[%d] ", jobno(jp));
6738 else if (curjob && jp == curjob->prev_job)
6741 if (mode & SHOW_PID)
6742 col += fmtstr(s + col, 16, "%d ", ps->pid);
6744 psend = ps + jp->nprocs;
6746 if (jp->state == JOBRUNNING) {
6747 scopy("Running", s + col);
6748 col += strlen("Running");
6750 int status = psend[-1].status;
6752 if (jp->state == JOBSTOPPED)
6753 status = jp->stopstatus;
6755 col += sprint_status(s + col, status, 0);
6761 /* for each process */
6762 col = fmtstr(s, 48, " |\n%*c%d ", indent, ' ', ps->pid) - 3;
6765 fprintf(out, "%s%*c%s",
6766 s, 33 - col >= 0 ? 33 - col : 0, ' ', ps->cmd
6768 if (!(mode & SHOW_PID)) {
6772 if (++ps == psend) {
6773 outcslow('\n', out);
6780 if (jp->state == JOBDONE) {
6781 TRACE(("showjob: freeing job %d\n", jobno(jp)));
6788 jobscmd(int argc, char **argv)
6794 while ((m = nextopt("lp")))
6804 showjob(out, getjob(*argv,0), mode);
6807 showjobs(out, mode);
6814 * Print a list of jobs. If "change" is nonzero, only print jobs whose
6815 * statuses have changed since the last call to showjobs.
6819 showjobs(FILE *out, int mode)
6823 TRACE(("showjobs(%x) called\n", mode));
6825 /* If not even one one job changed, there is nothing to do */
6826 while (dowait(DOWAIT_NORMAL, NULL) > 0)
6829 for (jp = curjob; jp; jp = jp->prev_job) {
6830 if (!(mode & SHOW_CHANGED) || jp->changed)
6831 showjob(out, jp, mode);
6837 * Mark a job structure as unused.
6841 freejob(struct job *jp)
6843 struct procstat *ps;
6847 for (i = jp->nprocs, ps = jp->ps ; --i >= 0 ; ps++) {
6848 if (ps->cmd != nullstr)
6851 if (jp->ps != &jp->ps0)
6854 set_curjob(jp, CUR_DELETE);
6860 waitcmd(int argc, char **argv)
6873 /* wait for all jobs */
6878 /* no running procs */
6881 if (jp->state == JOBRUNNING)
6886 dowait(DOWAIT_BLOCK, 0);
6892 if (**argv != '%') {
6893 pid_t pid = number(*argv);
6897 if (job->ps[job->nprocs - 1].pid == pid)
6899 job = job->prev_job;
6905 job = getjob(*argv, 0);
6906 /* loop until process terminated or stopped */
6907 while (job->state == JOBRUNNING)
6908 dowait(DOWAIT_BLOCK, 0);
6910 retval = getstatus(job);
6921 * Convert a job name to a job structure.
6925 getjob(const char *name, int getctl)
6929 const char *err_msg = "No such job: %s";
6933 char *(*match)(const char *, const char *);
6948 if (c == '+' || c == '%') {
6950 err_msg = "No current job";
6952 } else if (c == '-') {
6955 err_msg = "No previous job";
6966 jp = jobtab + num - 1;
6983 if (match(jp->ps[0].cmd, p)) {
6987 err_msg = "%s: ambiguous";
6994 err_msg = "job %s not created under job control";
6995 if (getctl && jp->jobctl == 0)
7000 sh_error(err_msg, name);
7005 * Return a new job structure.
7006 * Called with interrupts off.
7010 makejob(union node *node, int nprocs)
7015 for (i = njobs, jp = jobtab ; ; jp++) {
7022 if (jp->state != JOBDONE || !jp->waited)
7031 memset(jp, 0, sizeof(*jp));
7036 jp->prev_job = curjob;
7041 jp->ps = ckmalloc(nprocs * sizeof (struct procstat));
7043 TRACE(("makejob(0x%lx, %d) returns %%%d\n", (long)node, nprocs,
7053 struct job *jp, *jq;
7055 len = njobs * sizeof(*jp);
7057 jp = ckrealloc(jq, len + 4 * sizeof(*jp));
7059 offset = (char *)jp - (char *)jq;
7061 /* Relocate pointers */
7064 jq = (struct job *)((char *)jq + l);
7068 #define joff(p) ((struct job *)((char *)(p) + l))
7069 #define jmove(p) (p) = (void *)((char *)(p) + offset)
7070 if (xlikely(joff(jp)->ps == &jq->ps0))
7071 jmove(joff(jp)->ps);
7072 if (joff(jp)->prev_job)
7073 jmove(joff(jp)->prev_job);
7083 jp = (struct job *)((char *)jp + len);
7087 } while (--jq >= jp);
7093 * Fork off a subshell. If we are doing job control, give the subshell its
7094 * own process group. Jp is a job structure that the job is to be added to.
7095 * N is the command that will be evaluated by the child. Both jp and n may
7096 * be NULL. The mode parameter can be one of the following:
7097 * FORK_FG - Fork off a foreground process.
7098 * FORK_BG - Fork off a background process.
7099 * FORK_NOJOB - Like FORK_FG, but don't give the process its own
7100 * process group even if job control is on.
7102 * When job control is turned off, background processes have their standard
7103 * input redirected to /dev/null (except for the second and later processes
7106 * Called with interrupts off.
7110 forkchild(struct job *jp, union node *n, int mode)
7114 TRACE(("Child shell %d\n", getpid()));
7121 /* do job control only in root shell */
7123 if (mode != FORK_NOJOB && jp->jobctl && !oldlvl) {
7126 if (jp->nprocs == 0)
7129 pgrp = jp->ps[0].pid;
7130 /* This can fail because we are doing it in the parent also */
7131 (void)setpgid(0, pgrp);
7132 if (mode == FORK_FG)
7133 xtcsetpgrp(ttyfd, pgrp);
7138 if (mode == FORK_BG) {
7141 if (jp->nprocs == 0) {
7143 if (open(_PATH_DEVNULL, O_RDONLY) != 0)
7144 sh_error("Can't open %s", _PATH_DEVNULL);
7147 if (!oldlvl && iflag) {
7152 for (jp = curjob; jp; jp = jp->prev_job)
7158 forkparent(struct job *jp, union node *n, int mode, pid_t pid)
7160 TRACE(("In parent shell: child = %d\n", pid));
7162 while (jobless && dowait(DOWAIT_NORMAL, 0) > 0);
7167 if (mode != FORK_NOJOB && jp->jobctl) {
7170 if (jp->nprocs == 0)
7173 pgrp = jp->ps[0].pid;
7174 /* This can fail because we are doing it in the child also */
7175 (void)setpgid(pid, pgrp);
7178 if (mode == FORK_BG) {
7179 backgndpid = pid; /* set $! */
7180 set_curjob(jp, CUR_RUNNING);
7183 struct procstat *ps = &jp->ps[jp->nprocs++];
7189 ps->cmd = commandtext(n);
7195 forkshell(struct job *jp, union node *n, int mode)
7199 TRACE(("forkshell(%%%d, %p, %d) called\n", jobno(jp), n, mode));
7202 TRACE(("Fork failed, errno=%d", errno));
7205 sh_error("Cannot fork");
7208 forkchild(jp, n, mode);
7210 forkparent(jp, n, mode, pid);
7215 * Wait for job to finish.
7217 * Under job control we have the problem that while a child process is
7218 * running interrupts generated by the user are sent to the child but not
7219 * to the shell. This means that an infinite loop started by an inter-
7220 * active user may be hard to kill. With job control turned off, an
7221 * interactive user may place an interactive program inside a loop. If
7222 * the interactive program catches interrupts, the user doesn't want
7223 * these interrupts to also abort the loop. The approach we take here
7224 * is to have the shell ignore interrupt signals while waiting for a
7225 * foreground process to terminate, and then send itself an interrupt
7226 * signal if the child process was terminated by an interrupt signal.
7227 * Unfortunately, some programs want to do a bit of cleanup and then
7228 * exit on interrupt; unless these processes terminate themselves by
7229 * sending a signal to themselves (instead of calling exit) they will
7230 * confuse this approach.
7232 * Called with interrupts off.
7236 waitforjob(struct job *jp)
7240 TRACE(("waitforjob(%%%d) called\n", jobno(jp)));
7241 while (jp->state == JOBRUNNING) {
7242 dowait(DOWAIT_BLOCK, jp);
7247 xtcsetpgrp(ttyfd, rootpid);
7249 * This is truly gross.
7250 * If we're doing job control, then we did a TIOCSPGRP which
7251 * caused us (the shell) to no longer be in the controlling
7252 * session -- so we wouldn't have seen any ^C/SIGINT. So, we
7253 * intuit from the subprocess exit status whether a SIGINT
7254 * occurred, and if so interrupt ourselves. Yuck. - mycroft
7259 if (jp->state == JOBDONE)
7267 * Do a wait system call. If job control is compiled in, we accept
7268 * stopped processes. If block is zero, we return a value of zero
7269 * rather than blocking.
7271 * System V doesn't have a non-blocking wait system call. It does
7272 * have a SIGCLD signal that is sent to a process when one of it's
7273 * children dies. The obvious way to use SIGCLD would be to install
7274 * a handler for SIGCLD which simply bumped a counter when a SIGCLD
7275 * was received, and have waitproc bump another counter when it got
7276 * the status of a process. Waitproc would then know that a wait
7277 * system call would not block if the two counters were different.
7278 * This approach doesn't work because if a process has children that
7279 * have not been waited for, System V will send it a SIGCLD when it
7280 * installs a signal handler for SIGCLD. What this means is that when
7281 * a child exits, the shell will be sent SIGCLD signals continuously
7282 * until is runs out of stack space, unless it does a wait call before
7283 * restoring the signal handler. The code below takes advantage of
7284 * this (mis)feature by installing a signal handler for SIGCLD and
7285 * then checking to see whether it was called. If there are any
7286 * children to be waited for, it will be.
7288 * If neither SYSV nor BSD is defined, we don't implement nonblocking
7289 * waits at all. In this case, the user will not be informed when
7290 * a background process until the next time she runs a real program
7291 * (as opposed to running a builtin command or just typing return),
7292 * and the jobs command may give out of date information.
7296 waitproc(int block, int *status)
7306 return wait3(status, flags, (struct rusage *)NULL);
7310 * Wait for a process to terminate.
7314 dowait(int block, struct job *job)
7319 struct job *thisjob;
7322 TRACE(("dowait(%d) called\n", block));
7323 pid = waitproc(block, &status);
7324 TRACE(("wait returns pid %d, status=%d\n", pid, status));
7329 for (jp = curjob; jp; jp = jp->prev_job) {
7330 struct procstat *sp;
7331 struct procstat *spend;
7332 if (jp->state == JOBDONE)
7335 spend = jp->ps + jp->nprocs;
7338 if (sp->pid == pid) {
7339 TRACE(("Job %d: changing status of proc %d from 0x%x to 0x%x\n", jobno(jp), pid, sp->status, status));
7340 sp->status = status;
7343 if (sp->status == -1)
7346 if (state == JOBRUNNING)
7348 if (WIFSTOPPED(sp->status)) {
7349 jp->stopstatus = sp->status;
7353 } while (++sp < spend);
7358 if (!WIFSTOPPED(status))
7365 if (state != JOBRUNNING) {
7366 thisjob->changed = 1;
7368 if (thisjob->state != state) {
7369 TRACE(("Job %d: changing state from %d to %d\n", jobno(thisjob), thisjob->state, state));
7370 thisjob->state = state;
7372 if (state == JOBSTOPPED) {
7373 set_curjob(thisjob, CUR_STOPPED);
7382 if (thisjob && thisjob == job) {
7386 len = sprint_status(s, status, 1);
7398 * return 1 if there are stopped jobs, otherwise 0
7411 if (jp && jp->state == JOBSTOPPED) {
7412 out2str("You have stopped jobs.\n");
7422 * Return a string identifying a command (to be printed by the
7427 static char *cmdnextc;
7430 commandtext(union node *n)
7434 STARTSTACKSTR(cmdnextc);
7436 name = stackblock();
7437 TRACE(("commandtext: name %p, end %p\n\t\"%s\"\n",
7438 name, cmdnextc, cmdnextc));
7439 return savestr(name);
7443 cmdtxt(union node *n)
7446 struct nodelist *lp;
7458 lp = n->npipe.cmdlist;
7476 cmdtxt(n->nbinary.ch1);
7492 cmdtxt(n->nif.test);
7495 if (n->nif.elsepart) {
7498 n = n->nif.elsepart;
7514 cmdtxt(n->nbinary.ch1);
7524 cmdputs(n->nfor.var);
7526 cmdlist(n->nfor.args, 1);
7531 cmdputs(n->narg.text);
7535 cmdlist(n->ncmd.args, 1);
7536 cmdlist(n->ncmd.redirect, 0);
7549 cmdputs(n->ncase.expr->narg.text);
7551 for (np = n->ncase.cases; np; np = np->nclist.next) {
7552 cmdtxt(np->nclist.pattern);
7554 cmdtxt(np->nclist.body);
7580 s[0] = n->nfile.fd + '0';
7584 if (n->type == NTOFD || n->type == NFROMFD) {
7585 s[0] = n->ndup.dupfd + '0';
7596 cmdlist(union node *np, int sep)
7598 for (; np; np = np->narg.next) {
7602 if (sep && np->narg.next)
7608 cmdputs(const char *s)
7610 const char *p, *str;
7611 char c, cc[2] = " ";
7615 static const char vstype[VSTYPE + 1][4] = {
7616 "", "}", "-", "+", "?", "=",
7617 "%", "%%", "#", "##"
7619 nextc = makestrspace((strlen(s) + 1) * 8, cmdnextc);
7621 while ((c = *p++) != 0) {
7629 if ((subtype & VSTYPE) == VSLENGTH)
7633 if (!(subtype & VSQUOTE) != !(quoted & 1)) {
7640 str = "\"}" + !(quoted & 1);
7647 case CTLBACKQ+CTLQUOTE:
7650 #ifdef CONFIG_ASH_MATH_SUPPORT
7665 if ((subtype & VSTYPE) != VSNORMAL)
7667 str = vstype[subtype & VSTYPE];
7668 if (subtype & VSNUL)
7677 /* These can only happen inside quotes */
7690 while ((c = *str++)) {
7695 USTPUTC('"', nextc);
7703 showpipe(struct job *jp, FILE *out)
7705 struct procstat *sp;
7706 struct procstat *spend;
7708 spend = jp->ps + jp->nprocs;
7709 for (sp = jp->ps + 1; sp < spend; sp++)
7710 fprintf(out, " | %s", sp->cmd);
7711 outcslow('\n', out);
7716 xtcsetpgrp(int fd, pid_t pgrp)
7718 if (tcsetpgrp(fd, pgrp))
7719 sh_error("Cannot set tty process group (%m)");
7724 getstatus(struct job *job) {
7728 status = job->ps[job->nprocs - 1].status;
7729 retval = WEXITSTATUS(status);
7730 if (!WIFEXITED(status)) {
7732 retval = WSTOPSIG(status);
7733 if (!WIFSTOPPED(status))
7736 /* XXX: limits number of signals */
7737 retval = WTERMSIG(status);
7739 if (retval == SIGINT)
7745 TRACE(("getstatus: job %d, nproc %d, status %x, retval %x\n",
7746 jobno(job), job->nprocs, status, retval));
7750 #ifdef CONFIG_ASH_MAIL
7754 * Routines to check for mail. (Perhaps make part of main.c?)
7757 #define MAXMBOXES 10
7759 /* times of mailboxes */
7760 static time_t mailtime[MAXMBOXES];
7761 /* Set if MAIL or MAILPATH is changed. */
7762 static int mail_var_path_changed;
7767 * Print appropriate message(s) if mail has arrived.
7768 * If mail_var_path_changed is set,
7769 * then the value of MAIL has mail_var_path_changed,
7770 * so we just update the values.
7780 struct stackmark smark;
7783 setstackmark(&smark);
7784 mpath = mpathset() ? mpathval() : mailval();
7785 for (mtp = mailtime; mtp < mailtime + MAXMBOXES; mtp++) {
7786 p = padvance(&mpath, nullstr);
7791 for (q = p ; *q ; q++);
7796 q[-1] = '\0'; /* delete trailing '/' */
7797 if (stat(p, &statb) < 0) {
7801 if (!mail_var_path_changed && statb.st_mtime != *mtp) {
7804 pathopt ? pathopt : "you have mail"
7807 *mtp = statb.st_mtime;
7809 mail_var_path_changed = 0;
7810 popstackmark(&smark);
7815 changemail(const char *val)
7817 mail_var_path_changed++;
7820 #endif /* CONFIG_ASH_MAIL */
7826 static short profile_buf[16384];
7830 static int isloginsh;
7832 static void read_profile(const char *);
7835 * Main routine. We initialize things, parse the arguments, execute
7836 * profiles if we're a login shell, and then call cmdloop to execute
7837 * commands. The setjmp call sets up the location to jump to when an
7838 * exception occurs. When an exception occurs the variable "state"
7839 * is used to figure out how far we had gotten.
7843 ash_main(int argc, char **argv)
7847 struct jmploc jmploc;
7848 struct stackmark smark;
7851 dash_errno = __errno_location();
7855 monitor(4, etext, profile_buf, sizeof profile_buf, 50);
7858 if (setjmp(jmploc.loc)) {
7868 if (e == EXEXIT || s == 0 || iflag == 0 || shlvl)
7872 outcslow('\n', stderr);
7874 popstackmark(&smark);
7875 FORCEINTON; /* enable interrupts */
7888 trputs("Shell args: "); trargs(argv);
7892 #ifdef CONFIG_ASH_RANDOM_SUPPORT
7893 rseed = rootpid + ((time_t)time((time_t *)0));
7896 setstackmark(&smark);
7897 procargs(argc, argv);
7898 #ifdef CONFIG_FEATURE_COMMAND_SAVEHISTORY
7900 const char *hp = lookupvar("HISTFILE");
7903 hp = lookupvar("HOME");
7905 char *defhp = concat_path_file(hp, ".ash_history");
7906 setvar("HISTFILE", defhp, 0);
7912 if (argv[0] && argv[0][0] == '-')
7916 read_profile("/etc/profile");
7919 read_profile(".profile");
7925 getuid() == geteuid() && getgid() == getegid() &&
7929 if ((shinit = lookupvar("ENV")) != NULL && *shinit != '\0') {
7930 read_profile(shinit);
7936 evalstring(minusc, 0);
7938 if (sflag || minusc == NULL) {
7939 #ifdef CONFIG_FEATURE_COMMAND_SAVEHISTORY
7941 const char *hp = lookupvar("HISTFILE");
7944 load_history ( hp );
7947 state4: /* XXX ??? - why isn't this before the "if" statement */
7955 extern void _mcleanup(void);
7965 * Read and execute commands. "Top" is nonzero for the top level command
7966 * loop; it turns on prompting if the shell is interactive.
7973 struct stackmark smark;
7977 TRACE(("cmdloop(%d) called\n", top));
7981 setstackmark(&smark);
7984 showjobs(stderr, SHOW_CHANGED);
7989 #ifdef CONFIG_ASH_MAIL
7993 n = parsecmd(inter);
7994 /* showtree(n); DEBUG */
7996 if (!top || numeof >= 50)
7998 if (!stoppedjobs()) {
8001 out2str("\nUse \"exit\" to leave shell.\n");
8004 } else if (nflag == 0) {
8005 job_warning = (job_warning == 2) ? 1 : 0;
8009 popstackmark(&smark);
8014 return skip & SKIPEVAL;
8023 * Read /etc/profile or .profile. Return on error.
8027 read_profile(const char *name)
8031 if (setinputfile(name, INPUT_PUSH_FILE | INPUT_NOFILE_OK) < 0)
8043 * Read a file containing shell functions.
8047 readcmdfile(char *name)
8049 setinputfile(name, INPUT_PUSH_FILE);
8056 * Take commands from a file. To be compatible we should do a path
8057 * search for the file, which is necessary to find sub-commands.
8060 static inline char *
8061 find_dot_file(char *name)
8064 const char *path = pathval();
8067 /* don't try this for absolute or relative paths */
8068 if (strchr(name, '/'))
8071 while ((fullname = padvance(&path, name)) != NULL) {
8072 if ((stat(fullname, &statb) == 0) && S_ISREG(statb.st_mode)) {
8074 * Don't bother freeing here, since it will
8075 * be freed by the caller.
8079 stunalloc(fullname);
8082 /* not found in the PATH */
8083 sh_error(not_found_msg, name);
8087 static int dotcmd(int argc, char **argv)
8090 volatile struct shparam saveparam;
8093 for (sp = cmdenviron; sp; sp = sp->next)
8094 setvareq(bb_xstrdup(sp->text), VSTRFIXED | VTEXTFIXED);
8096 if (argc >= 2) { /* That's what SVR2 does */
8099 fullname = find_dot_file(argv[1]);
8102 saveparam = shellparam;
8103 shellparam.malloc = 0;
8104 shellparam.nparam = argc - 2;
8105 shellparam.p = argv + 2;
8108 setinputfile(fullname, INPUT_PUSH_FILE);
8109 commandname = fullname;
8114 freeparam(&shellparam);
8115 shellparam = saveparam;
8117 status = exitstatus;
8124 exitcmd(int argc, char **argv)
8129 exitstatus = number(argv[1]);
8134 #ifdef CONFIG_ASH_BUILTIN_ECHO
8136 echocmd(int argc, char **argv)
8138 return bb_echo(argc, argv);
8144 * Same for malloc, realloc, but returns an error when out of space.
8148 ckrealloc(pointer p, size_t nbytes)
8150 p = realloc(p, nbytes);
8152 sh_error(bb_msg_memory_exhausted);
8157 ckmalloc(size_t nbytes)
8159 return ckrealloc(NULL, nbytes);
8163 * Make a copy of a string in safe storage.
8167 savestr(const char *s)
8169 char *p = strdup(s);
8171 sh_error(bb_msg_memory_exhausted);
8177 * Parse trees for commands are allocated in lifo order, so we use a stack
8178 * to make this more efficient, and also to avoid all sorts of exception
8179 * handling code to handle interrupts in the middle of a parse.
8181 * The size 504 was chosen because the Ultrix malloc handles that size
8187 stalloc(size_t nbytes)
8192 aligned = SHELL_ALIGN(nbytes);
8193 if (aligned > stacknleft) {
8196 struct stack_block *sp;
8198 blocksize = aligned;
8199 if (blocksize < MINSIZE)
8200 blocksize = MINSIZE;
8201 len = sizeof(struct stack_block) - MINSIZE + blocksize;
8202 if (len < blocksize)
8203 sh_error(bb_msg_memory_exhausted);
8207 stacknxt = sp->space;
8208 stacknleft = blocksize;
8209 sstrend = stacknxt + blocksize;
8214 stacknxt += aligned;
8215 stacknleft -= aligned;
8221 stunalloc(pointer p)
8224 if (!p || (stacknxt < (char *)p) || ((char *)p < stackp->space)) {
8225 write(2, "stunalloc\n", 10);
8229 stacknleft += stacknxt - (char *)p;
8235 setstackmark(struct stackmark *mark)
8237 mark->stackp = stackp;
8238 mark->stacknxt = stacknxt;
8239 mark->stacknleft = stacknleft;
8240 mark->marknext = markp;
8246 popstackmark(struct stackmark *mark)
8248 struct stack_block *sp;
8251 markp = mark->marknext;
8252 while (stackp != mark->stackp) {
8257 stacknxt = mark->stacknxt;
8258 stacknleft = mark->stacknleft;
8259 sstrend = mark->stacknxt + mark->stacknleft;
8265 * When the parser reads in a string, it wants to stick the string on the
8266 * stack and only adjust the stack pointer when it knows how big the
8267 * string is. Stackblock (defined in stack.h) returns a pointer to a block
8268 * of space on top of the stack and stackblocklen returns the length of
8269 * this block. Growstackblock will grow this space by at least one byte,
8270 * possibly moving it (like realloc). Grabstackblock actually allocates the
8271 * part of the block that has been used.
8275 growstackblock(void)
8279 newlen = stacknleft * 2;
8280 if (newlen < stacknleft)
8281 sh_error(bb_msg_memory_exhausted);
8285 if (stacknxt == stackp->space && stackp != &stackbase) {
8286 struct stack_block *oldstackp;
8287 struct stackmark *xmark;
8288 struct stack_block *sp;
8289 struct stack_block *prevstackp;
8295 prevstackp = sp->prev;
8296 grosslen = newlen + sizeof(struct stack_block) - MINSIZE;
8297 sp = ckrealloc((pointer)sp, grosslen);
8298 sp->prev = prevstackp;
8300 stacknxt = sp->space;
8301 stacknleft = newlen;
8302 sstrend = sp->space + newlen;
8305 * Stack marks pointing to the start of the old block
8306 * must be relocated to point to the new block
8309 while (xmark != NULL && xmark->stackp == oldstackp) {
8310 xmark->stackp = stackp;
8311 xmark->stacknxt = stacknxt;
8312 xmark->stacknleft = stacknleft;
8313 xmark = xmark->marknext;
8317 char *oldspace = stacknxt;
8318 int oldlen = stacknleft;
8319 char *p = stalloc(newlen);
8321 /* free the space we just allocated */
8322 stacknxt = memcpy(p, oldspace, oldlen);
8323 stacknleft += newlen;
8328 grabstackblock(size_t len)
8330 len = SHELL_ALIGN(len);
8336 * The following routines are somewhat easier to use than the above.
8337 * The user declares a variable of type STACKSTR, which may be declared
8338 * to be a register. The macro STARTSTACKSTR initializes things. Then
8339 * the user uses the macro STPUTC to add characters to the string. In
8340 * effect, STPUTC(c, p) is the same as *p++ = c except that the stack is
8341 * grown as necessary. When the user is done, she can just leave the
8342 * string there and refer to it using stackblock(). Or she can allocate
8343 * the space for it using grabstackstr(). If it is necessary to allow
8344 * someone else to use the stack temporarily and then continue to grow
8345 * the string, the user should use grabstack to allocate the space, and
8346 * then call ungrabstr(p) to return to the previous mode of operation.
8348 * USTPUTC is like STPUTC except that it doesn't check for overflow.
8349 * CHECKSTACKSPACE can be called before USTPUTC to ensure that there
8350 * is space for at least one character.
8356 size_t len = stackblocksize();
8357 if (herefd >= 0 && len >= 1024) {
8358 bb_full_write(herefd, stackblock(), len);
8359 return stackblock();
8362 return stackblock() + len;
8366 * Called from CHECKSTRSPACE.
8370 makestrspace(size_t newlen, char *p)
8372 size_t len = p - stacknxt;
8373 size_t size = stackblocksize();
8378 size = stackblocksize();
8380 if (nleft >= newlen)
8384 return stackblock() + len;
8388 stnputs(const char *s, size_t n, char *p)
8390 p = makestrspace(n, p);
8391 p = mempcpy(p, s, n);
8396 stputs(const char *s, char *p)
8398 return stnputs(s, strlen(s), p);
8406 * number(s) Convert a string of digits to an integer.
8407 * is_number(s) Return true if s is a string of digits.
8411 * prefix -- see if pfx is a prefix of string.
8415 prefix(const char *string, const char *pfx)
8418 if (*pfx++ != *string++)
8421 return (char *) string;
8426 * Convert a string of digits to an integer, printing an error message on
8431 number(const char *s)
8435 sh_error(illnum, s);
8441 * Check for a valid number. This should be elsewhere.
8445 is_number(const char *p)
8450 } while (*++p != '\0');
8456 * Produce a possibly single quoted string suitable as input to the shell.
8457 * The return string is allocated on the stack.
8461 single_quote(const char *s) {
8470 len = strchrnul(s, '\'') - s;
8472 q = p = makestrspace(len + 3, p);
8475 q = mempcpy(q, s, len);
8481 len = strspn(s, "'");
8485 q = p = makestrspace(len + 3, p);
8488 q = mempcpy(q, s, len);
8497 return stackblock();
8501 * Like strdup but works with the ash stack.
8505 sstrdup(const char *p)
8507 size_t len = strlen(p) + 1;
8508 return memcpy(stalloc(len), p, len);
8513 calcsize(union node *n)
8517 funcblocksize += nodesize[n->type];
8520 calcsize(n->ncmd.redirect);
8521 calcsize(n->ncmd.args);
8522 calcsize(n->ncmd.assign);
8525 sizenodelist(n->npipe.cmdlist);
8530 calcsize(n->nredir.redirect);
8531 calcsize(n->nredir.n);
8538 calcsize(n->nbinary.ch2);
8539 calcsize(n->nbinary.ch1);
8542 calcsize(n->nif.elsepart);
8543 calcsize(n->nif.ifpart);
8544 calcsize(n->nif.test);
8547 funcstringsize += strlen(n->nfor.var) + 1;
8548 calcsize(n->nfor.body);
8549 calcsize(n->nfor.args);
8552 calcsize(n->ncase.cases);
8553 calcsize(n->ncase.expr);
8556 calcsize(n->nclist.body);
8557 calcsize(n->nclist.pattern);
8558 calcsize(n->nclist.next);
8562 sizenodelist(n->narg.backquote);
8563 funcstringsize += strlen(n->narg.text) + 1;
8564 calcsize(n->narg.next);
8571 calcsize(n->nfile.fname);
8572 calcsize(n->nfile.next);
8576 calcsize(n->ndup.vname);
8577 calcsize(n->ndup.next);
8581 calcsize(n->nhere.doc);
8582 calcsize(n->nhere.next);
8585 calcsize(n->nnot.com);
8592 sizenodelist(struct nodelist *lp)
8595 funcblocksize += SHELL_ALIGN(sizeof(struct nodelist));
8603 copynode(union node *n)
8610 funcblock = (char *) funcblock + nodesize[n->type];
8613 new->ncmd.redirect = copynode(n->ncmd.redirect);
8614 new->ncmd.args = copynode(n->ncmd.args);
8615 new->ncmd.assign = copynode(n->ncmd.assign);
8618 new->npipe.cmdlist = copynodelist(n->npipe.cmdlist);
8619 new->npipe.backgnd = n->npipe.backgnd;
8624 new->nredir.redirect = copynode(n->nredir.redirect);
8625 new->nredir.n = copynode(n->nredir.n);
8632 new->nbinary.ch2 = copynode(n->nbinary.ch2);
8633 new->nbinary.ch1 = copynode(n->nbinary.ch1);
8636 new->nif.elsepart = copynode(n->nif.elsepart);
8637 new->nif.ifpart = copynode(n->nif.ifpart);
8638 new->nif.test = copynode(n->nif.test);
8641 new->nfor.var = nodesavestr(n->nfor.var);
8642 new->nfor.body = copynode(n->nfor.body);
8643 new->nfor.args = copynode(n->nfor.args);
8646 new->ncase.cases = copynode(n->ncase.cases);
8647 new->ncase.expr = copynode(n->ncase.expr);
8650 new->nclist.body = copynode(n->nclist.body);
8651 new->nclist.pattern = copynode(n->nclist.pattern);
8652 new->nclist.next = copynode(n->nclist.next);
8656 new->narg.backquote = copynodelist(n->narg.backquote);
8657 new->narg.text = nodesavestr(n->narg.text);
8658 new->narg.next = copynode(n->narg.next);
8665 new->nfile.fname = copynode(n->nfile.fname);
8666 new->nfile.fd = n->nfile.fd;
8667 new->nfile.next = copynode(n->nfile.next);
8671 new->ndup.vname = copynode(n->ndup.vname);
8672 new->ndup.dupfd = n->ndup.dupfd;
8673 new->ndup.fd = n->ndup.fd;
8674 new->ndup.next = copynode(n->ndup.next);
8678 new->nhere.doc = copynode(n->nhere.doc);
8679 new->nhere.fd = n->nhere.fd;
8680 new->nhere.next = copynode(n->nhere.next);
8683 new->nnot.com = copynode(n->nnot.com);
8686 new->type = n->type;
8691 static struct nodelist *
8692 copynodelist(struct nodelist *lp)
8694 struct nodelist *start;
8695 struct nodelist **lpp;
8700 funcblock = (char *) funcblock +
8701 SHELL_ALIGN(sizeof(struct nodelist));
8702 (*lpp)->n = copynode(lp->n);
8704 lpp = &(*lpp)->next;
8712 nodesavestr(char *s)
8714 char *rtn = funcstring;
8716 funcstring = stpcpy(funcstring, s) + 1;
8722 * Free a parse tree.
8726 freefunc(struct funcnode *f)
8728 if (f && --f->count < 0)
8733 static void options(int);
8734 static void setoption(int, int);
8738 * Process the shell command line arguments.
8742 procargs(int argc, char **argv)
8745 const char *xminusc;
8752 for (i = 0; i < NOPTS; i++)
8758 if (*xargv == NULL) {
8760 sh_error("-c requires an argument");
8763 if (iflag == 2 && sflag == 1 && isatty(0) && isatty(1))
8767 for (i = 0; i < NOPTS; i++)
8768 if (optlist[i] == 2)
8773 /* POSIX 1003.2: first arg after -c cmd is $0, remainder $1... */
8778 } else if (!sflag) {
8779 setinputfile(*xargv, 0);
8785 shellparam.p = xargv;
8786 #ifdef CONFIG_ASH_GETOPTS
8787 shellparam.optind = 1;
8788 shellparam.optoff = -1;
8790 /* assert(shellparam.malloc == 0 && shellparam.nparam == 0); */
8792 shellparam.nparam++;
8805 setinteractive(iflag);
8811 minus_o(char *name, int val)
8816 out1str("Current option settings\n");
8817 for (i = 0; i < NOPTS; i++)
8818 out1fmt("%-16s%s\n", optnames(i),
8819 optlist[i] ? "on" : "off");
8821 for (i = 0; i < NOPTS; i++)
8822 if (equal(name, optnames(i))) {
8826 sh_error("Illegal option -o %s", name);
8831 * Process shell options. The global variable argptr contains a pointer
8832 * to the argument list; we advance it past the options.
8836 options(int cmdline)
8844 while ((p = *argptr) != NULL) {
8846 if ((c = *p++) == '-') {
8848 if (p[0] == '\0' || (p[0] == '-' && p[1] == '\0')) {
8850 /* "-" means turn off -x and -v */
8853 /* "--" means reset params */
8854 else if (*argptr == NULL)
8857 break; /* "-" or "--" terminates options */
8859 } else if (c == '+') {
8865 while ((c = *p++) != '\0') {
8866 if (c == 'c' && cmdline) {
8867 minusc = p; /* command is after shell args*/
8868 } else if (c == 'o') {
8869 minus_o(*argptr, val);
8872 } else if (cmdline && (c == '-')) { // long options
8873 if (strcmp(p, "login") == 0)
8885 setoption(int flag, int val)
8889 for (i = 0; i < NOPTS; i++)
8890 if (optletters(i) == flag) {
8894 sh_error("Illegal option -%c", flag);
8901 * Set the shell parameters.
8905 setparam(char **argv)
8911 for (nparam = 0 ; argv[nparam] ; nparam++);
8912 ap = newparam = ckmalloc((nparam + 1) * sizeof *ap);
8914 *ap++ = savestr(*argv++);
8917 freeparam(&shellparam);
8918 shellparam.malloc = 1;
8919 shellparam.nparam = nparam;
8920 shellparam.p = newparam;
8921 #ifdef CONFIG_ASH_GETOPTS
8922 shellparam.optind = 1;
8923 shellparam.optoff = -1;
8929 * Free the list of positional parameters.
8933 freeparam(volatile struct shparam *param)
8937 if (param->malloc) {
8938 for (ap = param->p ; *ap ; ap++)
8947 * The shift builtin command.
8951 shiftcmd(int argc, char **argv)
8958 n = number(argv[1]);
8959 if (n > shellparam.nparam)
8960 sh_error("can't shift that many");
8962 shellparam.nparam -= n;
8963 for (ap1 = shellparam.p ; --n >= 0 ; ap1++) {
8964 if (shellparam.malloc)
8968 while ((*ap2++ = *ap1++) != NULL);
8969 #ifdef CONFIG_ASH_GETOPTS
8970 shellparam.optind = 1;
8971 shellparam.optoff = -1;
8980 * The set command builtin.
8984 setcmd(int argc, char **argv)
8987 return showvars(nullstr, 0, VUNSET);
8991 if (*argptr != NULL) {
8999 #ifdef CONFIG_ASH_GETOPTS
9004 shellparam.optind = number(value);
9005 shellparam.optoff = -1;
9009 #ifdef CONFIG_LOCALE_SUPPORT
9010 static void change_lc_all(const char *value)
9012 if (value != 0 && *value != 0)
9013 setlocale(LC_ALL, value);
9016 static void change_lc_ctype(const char *value)
9018 if (value != 0 && *value != 0)
9019 setlocale(LC_CTYPE, value);
9024 #ifdef CONFIG_ASH_RANDOM_SUPPORT
9025 /* Roughly copied from bash.. */
9026 static void change_random(const char *value)
9029 /* "get", generate */
9032 rseed = rseed * 1103515245 + 12345;
9033 sprintf(buf, "%d", (unsigned int)((rseed & 32767)));
9034 /* set without recursion */
9035 setvar(vrandom.text, buf, VNOFUNC);
9036 vrandom.flags &= ~VNOFUNC;
9039 rseed = strtoul(value, (char **)NULL, 10);
9045 #ifdef CONFIG_ASH_GETOPTS
9047 getopts(char *optstr, char *optvar, char **optfirst, int *param_optind, int *optoff)
9056 if(*param_optind < 1)
9058 optnext = optfirst + *param_optind - 1;
9060 if (*param_optind <= 1 || *optoff < 0 || strlen(optnext[-1]) < *optoff)
9063 p = optnext[-1] + *optoff;
9064 if (p == NULL || *p == '\0') {
9065 /* Current word is done, advance */
9067 if (p == NULL || *p != '-' || *++p == '\0') {
9074 if (p[0] == '-' && p[1] == '\0') /* check for "--" */
9079 for (q = optstr; *q != c; ) {
9081 if (optstr[0] == ':') {
9084 err |= setvarsafe("OPTARG", s, 0);
9086 fprintf(stderr, "Illegal option -%c\n", c);
9087 (void) unsetvar("OPTARG");
9097 if (*p == '\0' && (p = *optnext) == NULL) {
9098 if (optstr[0] == ':') {
9101 err |= setvarsafe("OPTARG", s, 0);
9104 fprintf(stderr, "No arg for -%c option\n", c);
9105 (void) unsetvar("OPTARG");
9113 err |= setvarsafe("OPTARG", p, 0);
9116 err |= setvarsafe("OPTARG", nullstr, 0);
9119 *optoff = p ? p - *(optnext - 1) : -1;
9120 *param_optind = optnext - optfirst + 1;
9121 fmtstr(s, sizeof(s), "%d", *param_optind);
9122 err |= setvarsafe("OPTIND", s, VNOFUNC);
9125 err |= setvarsafe(optvar, s, 0);
9136 * The getopts builtin. Shellparam.optnext points to the next argument
9137 * to be processed. Shellparam.optptr points to the next character to
9138 * be processed in the current argument. If shellparam.optnext is NULL,
9139 * then it's the first time getopts has been called.
9143 getoptscmd(int argc, char **argv)
9148 sh_error("Usage: getopts optstring var [arg]");
9149 else if (argc == 3) {
9150 optbase = shellparam.p;
9151 if (shellparam.optind > shellparam.nparam + 1) {
9152 shellparam.optind = 1;
9153 shellparam.optoff = -1;
9158 if (shellparam.optind > argc - 2) {
9159 shellparam.optind = 1;
9160 shellparam.optoff = -1;
9164 return getopts(argv[1], argv[2], optbase, &shellparam.optind,
9165 &shellparam.optoff);
9167 #endif /* CONFIG_ASH_GETOPTS */
9170 * XXX - should get rid of. have all builtins use getopt(3). the
9171 * library getopt must have the BSD extension static variable "optreset"
9172 * otherwise it can't be used within the shell safely.
9174 * Standard option processing (a la getopt) for builtin routines. The
9175 * only argument that is passed to nextopt is the option string; the
9176 * other arguments are unnecessary. It return the character, or '\0' on
9181 nextopt(const char *optstring)
9187 if ((p = optptr) == NULL || *p == '\0') {
9189 if (p == NULL || *p != '-' || *++p == '\0')
9192 if (p[0] == '-' && p[1] == '\0') /* check for "--" */
9196 for (q = optstring ; *q != c ; ) {
9198 sh_error("Illegal option -%c", c);
9203 if (*p == '\0' && (p = *argptr++) == NULL)
9204 sh_error("No arg for -%c option", c);
9216 outstr(const char *p, FILE *file)
9241 outcslow(int c, FILE *dest)
9251 out1fmt(const char *fmt, ...)
9258 r = vprintf(fmt, ap);
9266 fmtstr(char *outbuf, size_t length, const char *fmt, ...)
9273 ret = vsnprintf(outbuf, length, fmt, ap);
9285 * Shell command parser.
9288 #define EOFMARKLEN 79
9292 struct heredoc *next; /* next here document in list */
9293 union node *here; /* redirection node */
9294 char *eofmark; /* string indicating end of input */
9295 int striptabs; /* if set, strip leading tabs */
9300 static struct heredoc *heredoclist; /* list of here documents to read */
9303 static union node *list(int);
9304 static union node *andor(void);
9305 static union node *pipeline(void);
9306 static union node *command(void);
9307 static union node *simplecmd(void);
9308 static union node *makename(void);
9309 static void parsefname(void);
9310 static void parseheredoc(void);
9311 static char peektoken(void);
9312 static int readtoken(void);
9313 static int xxreadtoken(void);
9314 static int readtoken1(int firstc, int syntax, char *eofmark, int striptabs);
9315 static int noexpand(char *);
9316 static void synexpect(int) ATTRIBUTE_NORETURN;
9317 static void synerror(const char *) ATTRIBUTE_NORETURN;
9318 static void setprompt(int);
9324 * Read and parse a command. Returns NEOF on end of file. (NULL is a
9325 * valid parse tree indicating a blank line.)
9329 parsecmd(int interact)
9334 doprompt = interact;
9336 setprompt(doprompt);
9351 union node *n1, *n2, *n3;
9354 checkkwd = CHKNL | CHKKWD | CHKALIAS;
9355 if (nlflag == 2 && peektoken())
9361 if (tok == TBACKGND) {
9362 if (n2->type == NPIPE) {
9363 n2->npipe.backgnd = 1;
9365 if (n2->type != NREDIR) {
9366 n3 = stalloc(sizeof(struct nredir));
9368 n3->nredir.redirect = NULL;
9371 n2->type = NBACKGND;
9378 n3 = (union node *)stalloc(sizeof (struct nbinary));
9380 n3->nbinary.ch1 = n1;
9381 n3->nbinary.ch2 = n2;
9397 checkkwd = CHKNL | CHKKWD | CHKALIAS;
9405 pungetc(); /* push back EOF on input */
9421 union node *n1, *n2, *n3;
9426 if ((t = readtoken()) == TAND) {
9428 } else if (t == TOR) {
9434 checkkwd = CHKNL | CHKKWD | CHKALIAS;
9436 n3 = (union node *)stalloc(sizeof (struct nbinary));
9438 n3->nbinary.ch1 = n1;
9439 n3->nbinary.ch2 = n2;
9449 union node *n1, *n2, *pipenode;
9450 struct nodelist *lp, *prev;
9454 TRACE(("pipeline: entered\n"));
9455 if (readtoken() == TNOT) {
9457 checkkwd = CHKKWD | CHKALIAS;
9461 if (readtoken() == TPIPE) {
9462 pipenode = (union node *)stalloc(sizeof (struct npipe));
9463 pipenode->type = NPIPE;
9464 pipenode->npipe.backgnd = 0;
9465 lp = (struct nodelist *)stalloc(sizeof (struct nodelist));
9466 pipenode->npipe.cmdlist = lp;
9470 lp = (struct nodelist *)stalloc(sizeof (struct nodelist));
9471 checkkwd = CHKNL | CHKKWD | CHKALIAS;
9474 } while (readtoken() == TPIPE);
9480 n2 = (union node *)stalloc(sizeof (struct nnot));
9493 union node *n1, *n2;
9494 union node *ap, **app;
9495 union node *cp, **cpp;
9496 union node *redir, **rpp;
9503 switch (readtoken()) {
9508 n1 = (union node *)stalloc(sizeof (struct nif));
9510 n1->nif.test = list(0);
9511 if (readtoken() != TTHEN)
9513 n1->nif.ifpart = list(0);
9515 while (readtoken() == TELIF) {
9516 n2->nif.elsepart = (union node *)stalloc(sizeof (struct nif));
9517 n2 = n2->nif.elsepart;
9519 n2->nif.test = list(0);
9520 if (readtoken() != TTHEN)
9522 n2->nif.ifpart = list(0);
9524 if (lasttoken == TELSE)
9525 n2->nif.elsepart = list(0);
9527 n2->nif.elsepart = NULL;
9535 n1 = (union node *)stalloc(sizeof (struct nbinary));
9536 n1->type = (lasttoken == TWHILE)? NWHILE : NUNTIL;
9537 n1->nbinary.ch1 = list(0);
9538 if ((got=readtoken()) != TDO) {
9539 TRACE(("expecting DO got %s %s\n", tokname(got), got == TWORD ? wordtext : ""));
9542 n1->nbinary.ch2 = list(0);
9547 if (readtoken() != TWORD || quoteflag || ! goodname(wordtext))
9548 synerror("Bad for loop variable");
9549 n1 = (union node *)stalloc(sizeof (struct nfor));
9551 n1->nfor.var = wordtext;
9552 checkkwd = CHKKWD | CHKALIAS;
9553 if (readtoken() == TIN) {
9555 while (readtoken() == TWORD) {
9556 n2 = (union node *)stalloc(sizeof (struct narg));
9558 n2->narg.text = wordtext;
9559 n2->narg.backquote = backquotelist;
9561 app = &n2->narg.next;
9565 if (lasttoken != TNL && lasttoken != TSEMI)
9568 n2 = (union node *)stalloc(sizeof (struct narg));
9570 n2->narg.text = (char *)dolatstr;
9571 n2->narg.backquote = NULL;
9572 n2->narg.next = NULL;
9575 * Newline or semicolon here is optional (but note
9576 * that the original Bourne shell only allowed NL).
9578 if (lasttoken != TNL && lasttoken != TSEMI)
9581 checkkwd = CHKNL | CHKKWD | CHKALIAS;
9582 if (readtoken() != TDO)
9584 n1->nfor.body = list(0);
9588 n1 = (union node *)stalloc(sizeof (struct ncase));
9590 if (readtoken() != TWORD)
9592 n1->ncase.expr = n2 = (union node *)stalloc(sizeof (struct narg));
9594 n2->narg.text = wordtext;
9595 n2->narg.backquote = backquotelist;
9596 n2->narg.next = NULL;
9598 checkkwd = CHKKWD | CHKALIAS;
9599 } while (readtoken() == TNL);
9600 if (lasttoken != TIN)
9602 cpp = &n1->ncase.cases;
9604 checkkwd = CHKNL | CHKKWD;
9607 if (lasttoken == TLP)
9609 *cpp = cp = (union node *)stalloc(sizeof (struct nclist));
9611 app = &cp->nclist.pattern;
9613 *app = ap = (union node *)stalloc(sizeof (struct narg));
9615 ap->narg.text = wordtext;
9616 ap->narg.backquote = backquotelist;
9617 if (readtoken() != TPIPE)
9619 app = &ap->narg.next;
9622 ap->narg.next = NULL;
9623 if (lasttoken != TRP)
9625 cp->nclist.body = list(2);
9627 cpp = &cp->nclist.next;
9629 checkkwd = CHKNL | CHKKWD;
9630 if ((t = readtoken()) != TESAC) {
9632 synexpect(TENDCASE);
9640 n1 = (union node *)stalloc(sizeof (struct nredir));
9641 n1->type = NSUBSHELL;
9642 n1->nredir.n = list(0);
9643 n1->nredir.redirect = NULL;
9656 if (readtoken() != t)
9660 /* Now check for redirection which may follow command */
9661 checkkwd = CHKKWD | CHKALIAS;
9663 while (readtoken() == TREDIR) {
9664 *rpp = n2 = redirnode;
9665 rpp = &n2->nfile.next;
9671 if (n1->type != NSUBSHELL) {
9672 n2 = (union node *)stalloc(sizeof (struct nredir));
9677 n1->nredir.redirect = redir;
9686 union node *args, **app;
9687 union node *n = NULL;
9688 union node *vars, **vpp;
9689 union node **rpp, *redir;
9699 savecheckkwd = CHKALIAS;
9701 checkkwd = savecheckkwd;
9702 switch (readtoken()) {
9704 n = (union node *)stalloc(sizeof (struct narg));
9706 n->narg.text = wordtext;
9707 n->narg.backquote = backquotelist;
9708 if (savecheckkwd && isassignment(wordtext)) {
9710 vpp = &n->narg.next;
9713 app = &n->narg.next;
9718 *rpp = n = redirnode;
9719 rpp = &n->nfile.next;
9720 parsefname(); /* read name of redirection file */
9724 args && app == &args->narg.next &&
9727 struct builtincmd *bcmd;
9730 /* We have a function */
9731 if (readtoken() != TRP)
9733 name = n->narg.text;
9735 !goodname(name) || (
9736 (bcmd = find_builtin(name)) &&
9737 IS_BUILTIN_SPECIAL(bcmd)
9740 synerror("Bad function name");
9742 checkkwd = CHKNL | CHKKWD | CHKALIAS;
9743 n->narg.next = command();
9756 n = (union node *)stalloc(sizeof (struct ncmd));
9758 n->ncmd.args = args;
9759 n->ncmd.assign = vars;
9760 n->ncmd.redirect = redir;
9769 n = (union node *)stalloc(sizeof (struct narg));
9771 n->narg.next = NULL;
9772 n->narg.text = wordtext;
9773 n->narg.backquote = backquotelist;
9777 void fixredir(union node *n, const char *text, int err)
9779 TRACE(("Fix redir %s %d\n", text, err));
9781 n->ndup.vname = NULL;
9783 if (is_digit(text[0]) && text[1] == '\0')
9784 n->ndup.dupfd = digit_val(text[0]);
9785 else if (text[0] == '-' && text[1] == '\0')
9790 synerror("Bad fd number");
9792 n->ndup.vname = makename();
9800 union node *n = redirnode;
9802 if (readtoken() != TWORD)
9804 if (n->type == NHERE) {
9805 struct heredoc *here = heredoc;
9811 TRACE(("Here document %d\n", n->type));
9812 if (! noexpand(wordtext) || (i = strlen(wordtext)) == 0 || i > EOFMARKLEN)
9813 synerror("Illegal eof marker for << redirection");
9814 rmescapes(wordtext);
9815 here->eofmark = wordtext;
9817 if (heredoclist == NULL)
9820 for (p = heredoclist ; p->next ; p = p->next);
9823 } else if (n->type == NTOFD || n->type == NFROMFD) {
9824 fixredir(n, wordtext, 0);
9826 n->nfile.fname = makename();
9832 * Input any here documents.
9838 struct heredoc *here;
9848 readtoken1(pgetc(), here->here->type == NHERE? SQSYNTAX : DQSYNTAX,
9849 here->eofmark, here->striptabs);
9850 n = (union node *)stalloc(sizeof (struct narg));
9851 n->narg.type = NARG;
9852 n->narg.next = NULL;
9853 n->narg.text = wordtext;
9854 n->narg.backquote = backquotelist;
9855 here->here->nhere.doc = n;
9860 static char peektoken(void)
9866 return tokname_array[t][0];
9874 int alreadyseen = tokpushback;
9877 #ifdef CONFIG_ASH_ALIAS
9886 if (checkkwd & CHKNL) {
9893 if (t != TWORD || quoteflag) {
9898 * check for keywords
9900 if (checkkwd & CHKKWD) {
9901 const char *const *pp;
9903 if ((pp = findkwd(wordtext))) {
9904 lasttoken = t = pp - tokname_array;
9905 TRACE(("keyword %s recognized\n", tokname(t)));
9910 if (checkkwd & CHKALIAS) {
9911 #ifdef CONFIG_ASH_ALIAS
9913 if ((ap = lookupalias(wordtext, 1)) != NULL) {
9915 pushstring(ap->val, ap);
9925 TRACE(("token %s %s\n", tokname(t), t == TWORD ? wordtext : ""));
9927 TRACE(("reread token %s %s\n", tokname(t), t == TWORD ? wordtext : ""));
9934 * Read the next input token.
9935 * If the token is a word, we set backquotelist to the list of cmds in
9936 * backquotes. We set quoteflag to true if any part of the word was
9938 * If the token is TREDIR, then we set redirnode to a structure containing
9940 * In all cases, the variable startlinno is set to the number of the line
9941 * on which the token starts.
9943 * [Change comment: here documents and internal procedures]
9944 * [Readtoken shouldn't have any arguments. Perhaps we should make the
9945 * word parsing code into a separate routine. In this case, readtoken
9946 * doesn't need to have any internal procedures, but parseword does.
9947 * We could also make parseoperator in essence the main routine, and
9948 * have parseword (readtoken1?) handle both words and redirection.]
9951 #define NEW_xxreadtoken
9952 #ifdef NEW_xxreadtoken
9954 /* singles must be first! */
9955 static const char xxreadtoken_chars[7] = { '\n', '(', ')', '&', '|', ';', 0 };
9957 static const char xxreadtoken_tokens[] = {
9958 TNL, TLP, TRP, /* only single occurrence allowed */
9959 TBACKGND, TPIPE, TSEMI, /* if single occurrence */
9960 TEOF, /* corresponds to trailing nul */
9961 TAND, TOR, TENDCASE, /* if double occurrence */
9964 #define xxreadtoken_doubles \
9965 (sizeof(xxreadtoken_tokens) - sizeof(xxreadtoken_chars))
9966 #define xxreadtoken_singles \
9967 (sizeof(xxreadtoken_chars) - xxreadtoken_doubles - 1)
9969 static int xxreadtoken()
9980 startlinno = plinno;
9981 for (;;) { /* until token or start of word found */
9984 if ((c != ' ') && (c != '\t')
9985 #ifdef CONFIG_ASH_ALIAS
9990 while ((c = pgetc()) != '\n' && c != PEOF);
9992 } else if (c == '\\') {
9993 if (pgetc() != '\n') {
9997 startlinno = ++plinno;
10002 = xxreadtoken_chars + sizeof(xxreadtoken_chars) - 1;
10007 needprompt = doprompt;
10010 p = strchr(xxreadtoken_chars, c);
10013 return readtoken1(c, BASESYNTAX, (char *) NULL, 0);
10016 if (p - xxreadtoken_chars >= xxreadtoken_singles) {
10017 if (pgetc() == *p) { /* double occurrence? */
10018 p += xxreadtoken_doubles + 1;
10025 return lasttoken = xxreadtoken_tokens[p - xxreadtoken_chars];
10033 #define RETURN(token) return lasttoken = token
10047 startlinno = plinno;
10048 for (;;) { /* until token or start of word found */
10051 case ' ': case '\t':
10052 #ifdef CONFIG_ASH_ALIAS
10057 while ((c = pgetc()) != '\n' && c != PEOF);
10061 if (pgetc() == '\n') {
10062 startlinno = ++plinno;
10071 needprompt = doprompt;
10076 if (pgetc() == '&')
10081 if (pgetc() == '|')
10086 if (pgetc() == ';')
10099 return readtoken1(c, BASESYNTAX, (char *)NULL, 0);
10102 #endif /* NEW_xxreadtoken */
10106 * If eofmark is NULL, read a word or a redirection symbol. If eofmark
10107 * is not NULL, read a here document. In the latter case, eofmark is the
10108 * word which marks the end of the document and striptabs is true if
10109 * leading tabs should be stripped from the document. The argument firstc
10110 * is the first character of the input token or document.
10112 * Because C does not have internal subroutines, I have simulated them
10113 * using goto's to implement the subroutine linkage. The following macros
10114 * will run code that appears at the end of readtoken1.
10117 #define CHECKEND() {goto checkend; checkend_return:;}
10118 #define PARSEREDIR() {goto parseredir; parseredir_return:;}
10119 #define PARSESUB() {goto parsesub; parsesub_return:;}
10120 #define PARSEBACKQOLD() {oldstyle = 1; goto parsebackq; parsebackq_oldreturn:;}
10121 #define PARSEBACKQNEW() {oldstyle = 0; goto parsebackq; parsebackq_newreturn:;}
10122 #define PARSEARITH() {goto parsearith; parsearith_return:;}
10125 readtoken1(int firstc, int syntax, char *eofmark, int striptabs)
10130 char line[EOFMARKLEN + 1];
10131 struct nodelist *bqlist;
10134 int varnest; /* levels of variables expansion */
10135 int arinest; /* levels of arithmetic expansion */
10136 int parenlevel; /* levels of parens in arithmetic */
10137 int dqvarnest; /* levels of variables expansion within double quotes */
10139 int prevsyntax; /* syntax before arithmetic */
10141 /* Avoid longjmp clobbering */
10147 (void) &parenlevel;
10150 (void) &prevsyntax;
10154 startlinno = plinno;
10156 if (syntax == DQSYNTAX)
10165 STARTSTACKSTR(out);
10166 loop: { /* for each line, until end of word */
10167 CHECKEND(); /* set c to PEOF if at end of here document */
10168 for (;;) { /* until end of line or end of word */
10169 CHECKSTRSPACE(4, out); /* permit 4 calls to USTPUTC */
10170 switch(SIT(c, syntax)) {
10171 case CNL: /* '\n' */
10172 if (syntax == BASESYNTAX)
10173 goto endword; /* exit outer loop */
10179 goto loop; /* continue outer loop */
10184 if (eofmark == NULL || dblquote)
10185 USTPUTC(CTLESC, out);
10188 case CBACK: /* backslash */
10191 USTPUTC(CTLESC, out);
10192 USTPUTC('\\', out);
10194 } else if (c == '\n') {
10200 c != '\\' && c != '`' &&
10206 USTPUTC(CTLESC, out);
10207 USTPUTC('\\', out);
10209 if (SIT(c, SQSYNTAX) == CCTL)
10210 USTPUTC(CTLESC, out);
10218 if (eofmark == NULL) {
10219 USTPUTC(CTLQUOTEMARK, out);
10227 if (eofmark != NULL && arinest == 0 &&
10231 if (dqvarnest == 0) {
10232 syntax = BASESYNTAX;
10239 case CVAR: /* '$' */
10240 PARSESUB(); /* parse substitution */
10242 case CENDVAR: /* '}' */
10245 if (dqvarnest > 0) {
10248 USTPUTC(CTLENDVAR, out);
10253 #ifdef CONFIG_ASH_MATH_SUPPORT
10254 case CLP: /* '(' in arithmetic */
10258 case CRP: /* ')' in arithmetic */
10259 if (parenlevel > 0) {
10263 if (pgetc() == ')') {
10264 if (--arinest == 0) {
10265 USTPUTC(CTLENDARI, out);
10266 syntax = prevsyntax;
10267 if (syntax == DQSYNTAX)
10275 * unbalanced parens
10276 * (don't 2nd guess - no error)
10284 case CBQUOTE: /* '`' */
10288 goto endword; /* exit outer loop */
10293 goto endword; /* exit outer loop */
10294 #ifdef CONFIG_ASH_ALIAS
10304 #ifdef CONFIG_ASH_MATH_SUPPORT
10305 if (syntax == ARISYNTAX)
10306 synerror("Missing '))'");
10308 if (syntax != BASESYNTAX && ! parsebackquote && eofmark == NULL)
10309 synerror("Unterminated quoted string");
10310 if (varnest != 0) {
10311 startlinno = plinno;
10313 synerror("Missing '}'");
10315 USTPUTC('\0', out);
10316 len = out - (char *)stackblock();
10317 out = stackblock();
10318 if (eofmark == NULL) {
10319 if ((c == '>' || c == '<')
10322 && (*out == '\0' || is_digit(*out))) {
10324 return lasttoken = TREDIR;
10329 quoteflag = quotef;
10330 backquotelist = bqlist;
10331 grabstackblock(len);
10333 return lasttoken = TWORD;
10334 /* end of readtoken routine */
10339 * Check to see whether we are at the end of the here document. When this
10340 * is called, c is set to the first character of the next input line. If
10341 * we are at the end of the here document, this routine sets the c to PEOF.
10346 #ifdef CONFIG_ASH_ALIAS
10352 while (c == '\t') {
10356 if (c == *eofmark) {
10357 if (pfgets(line, sizeof line) != NULL) {
10361 for (q = eofmark + 1 ; *q && *p == *q ; p++, q++);
10362 if (*p == '\n' && *q == '\0') {
10365 needprompt = doprompt;
10367 pushstring(line, NULL);
10372 goto checkend_return;
10377 * Parse a redirection operator. The variable "out" points to a string
10378 * specifying the fd to be redirected. The variable "c" contains the
10379 * first character of the redirection operator.
10386 np = (union node *)stalloc(sizeof (struct nfile));
10391 np->type = NAPPEND;
10393 np->type = NCLOBBER;
10400 } else { /* c == '<' */
10402 switch (c = pgetc()) {
10404 if (sizeof (struct nfile) != sizeof (struct nhere)) {
10405 np = (union node *)stalloc(sizeof (struct nhere));
10409 heredoc = (struct heredoc *)stalloc(sizeof (struct heredoc));
10410 heredoc->here = np;
10411 if ((c = pgetc()) == '-') {
10412 heredoc->striptabs = 1;
10414 heredoc->striptabs = 0;
10420 np->type = NFROMFD;
10424 np->type = NFROMTO;
10434 np->nfile.fd = digit_val(fd);
10436 goto parseredir_return;
10441 * Parse a substitution. At this point, we have read the dollar sign
10442 * and nothing else.
10450 static const char types[] = "}-+?=";
10454 c <= PEOA_OR_PEOF ||
10455 (c != '(' && c != '{' && !is_name(c) && !is_special(c))
10459 } else if (c == '(') { /* $(command) or $((arith)) */
10460 if (pgetc() == '(') {
10461 #ifdef CONFIG_ASH_MATH_SUPPORT
10464 synerror("We unsupport $((arith))");
10471 USTPUTC(CTLVAR, out);
10472 typeloc = out - (char *)stackblock();
10473 USTPUTC(VSNORMAL, out);
10474 subtype = VSNORMAL;
10478 if ((c = pgetc()) == '}')
10481 subtype = VSLENGTH;
10486 if (c > PEOA_OR_PEOF && is_name(c)) {
10490 } while (c > PEOA_OR_PEOF && is_in_name(c));
10491 } else if (is_digit(c)) {
10495 } while (is_digit(c));
10497 else if (is_special(c)) {
10502 badsub: synerror("Bad substitution");
10506 if (subtype == 0) {
10513 p = strchr(types, c);
10516 subtype = p - types + VSNORMAL;
10522 subtype = c == '#' ? VSTRIMLEFT :
10535 if (dblquote || arinest)
10537 *((char *)stackblock() + typeloc) = subtype | flags;
10538 if (subtype != VSNORMAL) {
10540 if (dblquote || arinest) {
10545 goto parsesub_return;
10550 * Called to parse command substitutions. Newstyle is set if the command
10551 * is enclosed inside $(...); nlpp is a pointer to the head of the linked
10552 * list of commands (passed by reference), and savelen is the number of
10553 * characters on the top of the stack which must be preserved.
10557 struct nodelist **nlpp;
10560 char *volatile str;
10561 struct jmploc jmploc;
10562 struct jmploc *volatile savehandler;
10566 (void) &saveprompt;
10569 savepbq = parsebackquote;
10570 if (setjmp(jmploc.loc)) {
10573 parsebackquote = 0;
10574 handler = savehandler;
10575 longjmp(handler->loc, 1);
10579 savelen = out - (char *)stackblock();
10581 str = ckmalloc(savelen);
10582 memcpy(str, stackblock(), savelen);
10584 savehandler = handler;
10588 /* We must read until the closing backquote, giving special
10589 treatment to some slashes, and then push the string and
10590 reread it as input, interpreting it normally. */
10597 STARTSTACKSTR(pout);
10602 switch (pc = pgetc()) {
10607 if ((pc = pgetc()) == '\n') {
10612 * If eating a newline, avoid putting
10613 * the newline into the new character
10614 * stream (via the STPUTC after the
10619 if (pc != '\\' && pc != '`' && pc != '$'
10620 && (!dblquote || pc != '"'))
10621 STPUTC('\\', pout);
10622 if (pc > PEOA_OR_PEOF) {
10628 #ifdef CONFIG_ASH_ALIAS
10631 startlinno = plinno;
10632 synerror("EOF in backquote substitution");
10636 needprompt = doprompt;
10645 STPUTC('\0', pout);
10646 psavelen = pout - (char *)stackblock();
10647 if (psavelen > 0) {
10648 pstr = grabstackstr(pout);
10649 setinputstring(pstr);
10654 nlpp = &(*nlpp)->next;
10655 *nlpp = (struct nodelist *)stalloc(sizeof (struct nodelist));
10656 (*nlpp)->next = NULL;
10657 parsebackquote = oldstyle;
10660 saveprompt = doprompt;
10667 doprompt = saveprompt;
10669 if (readtoken() != TRP)
10676 * Start reading from old file again, ignoring any pushed back
10677 * tokens left from the backquote parsing
10682 while (stackblocksize() <= savelen)
10684 STARTSTACKSTR(out);
10686 memcpy(out, str, savelen);
10687 STADJUST(savelen, out);
10693 parsebackquote = savepbq;
10694 handler = savehandler;
10695 if (arinest || dblquote)
10696 USTPUTC(CTLBACKQ | CTLQUOTE, out);
10698 USTPUTC(CTLBACKQ, out);
10700 goto parsebackq_oldreturn;
10702 goto parsebackq_newreturn;
10705 #ifdef CONFIG_ASH_MATH_SUPPORT
10707 * Parse an arithmetic expansion (indicate start of one and set state)
10711 if (++arinest == 1) {
10712 prevsyntax = syntax;
10713 syntax = ARISYNTAX;
10714 USTPUTC(CTLARI, out);
10721 * we collapse embedded arithmetic expansion to
10722 * parenthesis, which should be equivalent
10726 goto parsearith_return;
10730 } /* end of readtoken */
10735 * Returns true if the text contains nothing to expand (no dollar signs
10740 noexpand(char *text)
10746 while ((c = *p++) != '\0') {
10747 if (c == CTLQUOTEMARK)
10751 else if (SIT(c, BASESYNTAX) == CCTL)
10759 * Return of a legal variable name (a letter or underscore followed by zero or
10760 * more letters, underscores, and digits).
10764 endofname(const char *name)
10772 if (! is_in_name(*p))
10780 * Called when an unexpected token is read during the parse. The argument
10781 * is the token that is expected, or -1 if more than one type of token can
10782 * occur at this point.
10785 static void synexpect(int token)
10790 l = sprintf(msg, "%s unexpected", tokname(lasttoken));
10792 sprintf(msg + l, " (expecting %s)", tokname(token));
10798 synerror(const char *msg)
10800 sh_error("Syntax error: %s", msg);
10806 * called by editline -- any expansions to the prompt
10807 * should be added here.
10810 #ifdef CONFIG_ASH_EXPAND_PRMT
10811 static const char *
10812 expandstr(const char *ps)
10816 /* XXX Fix (char *) cast. */
10817 setinputstring((char *)ps);
10818 readtoken1(pgetc(), DQSYNTAX, nullstr, 0);
10821 n.narg.type = NARG;
10822 n.narg.next = NULL;
10823 n.narg.text = wordtext;
10824 n.narg.backquote = backquotelist;
10826 expandarg(&n, NULL, 0);
10827 return stackblock();
10831 static void setprompt(int whichprompt)
10833 const char *prompt;
10834 #ifdef CONFIG_ASH_EXPAND_PRMT
10835 struct stackmark smark;
10840 switch (whichprompt) {
10850 #ifdef CONFIG_ASH_EXPAND_PRMT
10851 setstackmark(&smark);
10852 stalloc(stackblocksize());
10854 putprompt(expandstr(prompt));
10855 #ifdef CONFIG_ASH_EXPAND_PRMT
10856 popstackmark(&smark);
10861 static const char *const *findkwd(const char *s)
10863 return bsearch(s, tokname_array + KWDOFFSET,
10864 (sizeof(tokname_array) / sizeof(const char *)) - KWDOFFSET,
10865 sizeof(const char *), pstrcmp);
10871 * Code for dealing with input/output redirection.
10874 #define EMPTY -2 /* marks an unused slot in redirtab */
10876 # define PIPESIZE 4096 /* amount of buffering in a pipe */
10878 # define PIPESIZE PIPE_BUF
10882 * Open a file in noclobber mode.
10883 * The code was copied from bash.
10886 noclobberopen(const char *fname)
10889 struct stat finfo, finfo2;
10892 * If the file exists and is a regular file, return an error
10895 r = stat(fname, &finfo);
10896 if (r == 0 && S_ISREG(finfo.st_mode)) {
10902 * If the file was not present (r != 0), make sure we open it
10903 * exclusively so that if it is created before we open it, our open
10904 * will fail. Make sure that we do not truncate an existing file.
10905 * Note that we don't turn on O_EXCL unless the stat failed -- if the
10906 * file was not a regular file, we leave O_EXCL off.
10909 return open(fname, O_WRONLY|O_CREAT|O_EXCL, 0666);
10910 fd = open(fname, O_WRONLY|O_CREAT, 0666);
10912 /* If the open failed, return the file descriptor right away. */
10917 * OK, the open succeeded, but the file may have been changed from a
10918 * non-regular file to a regular file between the stat and the open.
10919 * We are assuming that the O_EXCL open handles the case where FILENAME
10920 * did not exist and is symlinked to an existing file between the stat
10925 * If we can open it and fstat the file descriptor, and neither check
10926 * revealed that it was a regular file, and the file has not been
10927 * replaced, return the file descriptor.
10929 if (fstat(fd, &finfo2) == 0 && !S_ISREG(finfo2.st_mode) &&
10930 finfo.st_dev == finfo2.st_dev && finfo.st_ino == finfo2.st_ino)
10933 /* The file has been replaced. badness. */
10940 * Handle here documents. Normally we fork off a process to write the
10941 * data to a pipe. If the document is short, we can stuff the data in
10942 * the pipe without forking.
10946 openhere(union node *redir)
10952 sh_error("Pipe call failed");
10953 if (redir->type == NHERE) {
10954 len = strlen(redir->nhere.doc->narg.text);
10955 if (len <= PIPESIZE) {
10956 bb_full_write(pip[1], redir->nhere.doc->narg.text, len);
10960 if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) {
10962 signal(SIGINT, SIG_IGN);
10963 signal(SIGQUIT, SIG_IGN);
10964 signal(SIGHUP, SIG_IGN);
10966 signal(SIGTSTP, SIG_IGN);
10968 signal(SIGPIPE, SIG_DFL);
10969 if (redir->type == NHERE)
10970 bb_full_write(pip[1], redir->nhere.doc->narg.text, len);
10972 expandhere(redir->nhere.doc, pip[1]);
10981 openredirect(union node *redir)
10986 switch (redir->nfile.type) {
10988 fname = redir->nfile.expfname;
10989 if ((f = open(fname, O_RDONLY)) < 0)
10993 fname = redir->nfile.expfname;
10994 if ((f = open(fname, O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0)
10998 /* Take care of noclobber mode. */
11000 fname = redir->nfile.expfname;
11001 if ((f = noclobberopen(fname)) < 0)
11007 fname = redir->nfile.expfname;
11008 if ((f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
11012 fname = redir->nfile.expfname;
11013 if ((f = open(fname, O_WRONLY|O_CREAT|O_APPEND, 0666)) < 0)
11020 /* Fall through to eliminate warning. */
11027 f = openhere(redir);
11033 sh_error("cannot create %s: %s", fname, errmsg(errno, E_CREAT));
11035 sh_error("cannot open %s: %s", fname, errmsg(errno, E_OPEN));
11039 dupredirect(union node *redir, int f)
11041 int fd = redir->nfile.fd;
11043 if (redir->nfile.type == NTOFD || redir->nfile.type == NFROMFD) {
11044 if (redir->ndup.dupfd >= 0) { /* if not ">&-" */
11045 copyfd(redir->ndup.dupfd, fd);
11058 * Process a list of redirection commands. If the REDIR_PUSH flag is set,
11059 * old file descriptors are stashed away so that the redirection can be
11060 * undone by calling popredir. If the REDIR_BACKQ flag is set, then the
11061 * standard output, and the standard error if it becomes a duplicate of
11062 * stdout, is saved in memory.
11066 redirect(union node *redir, int flags)
11069 struct redirtab *sv;
11080 if (flags & REDIR_PUSH) {
11081 struct redirtab *q;
11082 q = ckmalloc(sizeof (struct redirtab));
11083 q->next = redirlist;
11085 q->nullredirs = nullredirs - 1;
11086 for (i = 0 ; i < 10 ; i++)
11087 q->renamed[i] = EMPTY;
11094 if ((n->nfile.type == NTOFD || n->nfile.type == NFROMFD) &&
11095 n->ndup.dupfd == fd)
11096 continue; /* redirect from/to same file descriptor */
11098 newfd = openredirect(n);
11101 if (sv && *(p = &sv->renamed[fd]) == EMPTY) {
11102 i = fcntl(fd, F_DUPFD, 10);
11109 sh_error("%d: %m", fd);
11119 dupredirect(n, newfd);
11120 } while ((n = n->nfile.next));
11122 if (flags & REDIR_SAVEFD2 && sv && sv->renamed[2] >= 0)
11123 preverrout_fd = sv->renamed[2];
11128 * Undo the effects of the last redirection.
11134 struct redirtab *rp;
11137 if (--nullredirs >= 0)
11141 for (i = 0 ; i < 10 ; i++) {
11142 if (rp->renamed[i] != EMPTY) {
11145 copyfd(rp->renamed[i], i);
11147 close(rp->renamed[i]);
11150 redirlist = rp->next;
11151 nullredirs = rp->nullredirs;
11157 * Undo all redirections. Called on error or interrupt.
11161 * Discard all saved file descriptors.
11165 clearredir(int drop)
11177 * Copy a file descriptor to be >= to. Returns -1
11178 * if the source file descriptor is closed, EMPTY if there are no unused
11179 * file descriptors left.
11183 copyfd(int from, int to)
11187 newfd = fcntl(from, F_DUPFD, to);
11189 if (errno == EMFILE)
11192 sh_error("%d: %m", from);
11199 redirectsafe(union node *redir, int flags)
11202 volatile int saveint;
11203 struct jmploc *volatile savehandler = handler;
11204 struct jmploc jmploc;
11207 if (!(err = setjmp(jmploc.loc) * 2)) {
11209 redirect(redir, flags);
11211 handler = savehandler;
11212 if (err && exception != EXERROR)
11213 longjmp(handler->loc, 1);
11214 RESTOREINT(saveint);
11221 static void shtree(union node *, int, char *, FILE*);
11222 static void shcmd(union node *, FILE *);
11223 static void sharg(union node *, FILE *);
11224 static void indent(int, char *, FILE *);
11225 static void trstring(char *);
11229 showtree(union node *n)
11231 trputs("showtree called\n");
11232 shtree(n, 1, NULL, stdout);
11237 shtree(union node *n, int ind, char *pfx, FILE *fp)
11239 struct nodelist *lp;
11245 indent(ind, pfx, fp);
11256 shtree(n->nbinary.ch1, ind, NULL, fp);
11259 shtree(n->nbinary.ch2, ind, NULL, fp);
11267 for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
11272 if (n->npipe.backgnd)
11278 fprintf(fp, "<node type %d>", n->type);
11287 shcmd(union node *cmd, FILE *fp)
11295 for (np = cmd->ncmd.args ; np ; np = np->narg.next) {
11301 for (np = cmd->ncmd.redirect ; np ; np = np->nfile.next) {
11304 switch (np->nfile.type) {
11305 case NTO: s = ">"; dftfd = 1; break;
11306 case NCLOBBER: s = ">|"; dftfd = 1; break;
11307 case NAPPEND: s = ">>"; dftfd = 1; break;
11308 case NTOFD: s = ">&"; dftfd = 1; break;
11309 case NFROM: s = "<"; dftfd = 0; break;
11310 case NFROMFD: s = "<&"; dftfd = 0; break;
11311 case NFROMTO: s = "<>"; dftfd = 0; break;
11312 default: s = "*error*"; dftfd = 0; break;
11314 if (np->nfile.fd != dftfd)
11315 fprintf(fp, "%d", np->nfile.fd);
11317 if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) {
11318 fprintf(fp, "%d", np->ndup.dupfd);
11320 sharg(np->nfile.fname, fp);
11329 sharg(union node *arg, FILE *fp)
11332 struct nodelist *bqlist;
11335 if (arg->type != NARG) {
11336 out1fmt("<node type %d>\n", arg->type);
11339 bqlist = arg->narg.backquote;
11340 for (p = arg->narg.text ; *p ; p++) {
11349 if (subtype == VSLENGTH)
11355 if (subtype & VSNUL)
11358 switch (subtype & VSTYPE) {
11377 case VSTRIMLEFTMAX:
11384 case VSTRIMRIGHTMAX:
11391 out1fmt("<subtype %d>", subtype);
11398 case CTLBACKQ|CTLQUOTE:
11401 shtree(bqlist->n, -1, NULL, fp);
11413 indent(int amount, char *pfx, FILE *fp)
11417 for (i = 0 ; i < amount ; i++) {
11418 if (pfx && i == amount - 1)
11439 putc(c, tracefile);
11443 trace(const char *fmt, ...)
11450 (void) vfprintf(tracefile, fmt, va);
11455 tracev(const char *fmt, va_list va)
11459 (void) vfprintf(tracefile, fmt, va);
11464 trputs(const char *s)
11468 fputs(s, tracefile);
11480 putc('"', tracefile);
11481 for (p = s ; *p ; p++) {
11483 case '\n': c = 'n'; goto backslash;
11484 case '\t': c = 't'; goto backslash;
11485 case '\r': c = 'r'; goto backslash;
11486 case '"': c = '"'; goto backslash;
11487 case '\\': c = '\\'; goto backslash;
11488 case CTLESC: c = 'e'; goto backslash;
11489 case CTLVAR: c = 'v'; goto backslash;
11490 case CTLVAR+CTLQUOTE: c = 'V'; goto backslash;
11491 case CTLBACKQ: c = 'q'; goto backslash;
11492 case CTLBACKQ+CTLQUOTE: c = 'Q'; goto backslash;
11493 backslash: putc('\\', tracefile);
11494 putc(c, tracefile);
11497 if (*p >= ' ' && *p <= '~')
11498 putc(*p, tracefile);
11500 putc('\\', tracefile);
11501 putc(*p >> 6 & 03, tracefile);
11502 putc(*p >> 3 & 07, tracefile);
11503 putc(*p & 07, tracefile);
11508 putc('"', tracefile);
11520 putc(' ', tracefile);
11522 putc('\n', tracefile);
11538 /* leave open because libedit might be using it */
11541 scopy("./trace", s);
11543 if (!freopen(s, "a", tracefile)) {
11544 fprintf(stderr, "Can't re-open %s\n", s);
11549 if ((tracefile = fopen(s, "a")) == NULL) {
11550 fprintf(stderr, "Can't open %s\n", s);
11556 if ((flags = fcntl(fileno(tracefile), F_GETFL, 0)) >= 0)
11557 fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND);
11559 setlinebuf(tracefile);
11560 fputs("\nTracing started.\n", tracefile);
11568 * Sigmode records the current value of the signal handlers for the various
11569 * modes. A value of zero means that the current handler is not known.
11570 * S_HARD_IGN indicates that the signal was ignored on entry to the shell,
11573 #define S_DFL 1 /* default signal handling (SIG_DFL) */
11574 #define S_CATCH 2 /* signal is caught */
11575 #define S_IGN 3 /* signal is ignored (SIG_IGN) */
11576 #define S_HARD_IGN 4 /* signal is ignored permenantly */
11577 #define S_RESET 5 /* temporary - to reset a hard ignored sig */
11582 * The trap builtin.
11586 trapcmd(int argc, char **argv)
11595 for (signo = 0 ; signo < NSIG ; signo++) {
11596 if (trap[signo] != NULL) {
11599 sn = u_signal_names(0, &signo, 0);
11602 out1fmt("trap -- %s %s\n",
11603 single_quote(trap[signo]), sn);
11613 if ((signo = decode_signal(*ap, 0)) < 0)
11614 sh_error("%s: bad trap", *ap);
11617 if (action[0] == '-' && action[1] == '\0')
11620 action = savestr(action);
11623 ckfree(trap[signo]);
11624 trap[signo] = action;
11635 * Clear traps on a fork.
11643 for (tp = trap ; tp < &trap[NSIG] ; tp++) {
11644 if (*tp && **tp) { /* trap not NULL or SIG_IGN */
11648 if (tp != &trap[0])
11649 setsignal(tp - trap);
11657 * Set the signal handler for the specified signal. The routine figures
11658 * out what it should be set to.
11662 setsignal(int signo)
11666 struct sigaction act;
11668 if ((t = trap[signo]) == NULL)
11670 else if (*t != '\0')
11674 if (rootshell && action == S_DFL) {
11677 if (iflag || minusc || sflag == 0)
11700 t = &sigmode[signo - 1];
11704 * current setting unknown
11706 if (sigaction(signo, 0, &act) == -1) {
11708 * Pretend it worked; maybe we should give a warning
11709 * here, but other shells don't. We don't alter
11710 * sigmode, so that we retry every time.
11714 if (act.sa_handler == SIG_IGN) {
11715 if (mflag && (signo == SIGTSTP ||
11716 signo == SIGTTIN || signo == SIGTTOU)) {
11717 tsig = S_IGN; /* don't hard ignore these */
11721 tsig = S_RESET; /* force to be set */
11724 if (tsig == S_HARD_IGN || tsig == action)
11728 act.sa_handler = onsig;
11731 act.sa_handler = SIG_IGN;
11734 act.sa_handler = SIG_DFL;
11738 sigfillset(&act.sa_mask);
11739 sigaction(signo, &act, 0);
11747 ignoresig(int signo)
11749 if (sigmode[signo - 1] != S_IGN && sigmode[signo - 1] != S_HARD_IGN) {
11750 signal(signo, SIG_IGN);
11752 sigmode[signo - 1] = S_HARD_IGN;
11763 gotsig[signo - 1] = 1;
11764 pendingsigs = signo;
11766 if (exsig || (signo == SIGINT && !trap[SIGINT])) {
11775 * Called to execute a trap. Perhaps we should avoid entering new trap
11776 * handlers while we are executing a trap handler.
11788 savestatus = exitstatus;
11792 for (i = 0, q = gotsig; i < NSIG - 1; i++, q++) {
11800 skip = evalstring(p, SKIPEVAL);
11801 exitstatus = savestatus;
11811 * Controls whether the shell is interactive or not.
11815 setinteractive(int on)
11817 static int is_interactive;
11819 if (++on == is_interactive)
11821 is_interactive = on;
11823 setsignal(SIGQUIT);
11824 setsignal(SIGTERM);
11825 #ifndef CONFIG_FEATURE_SH_EXTRA_QUIET
11826 if(is_interactive > 1) {
11827 /* Looks like they want an interactive shell */
11828 static int do_banner;
11832 "\n\n" BB_BANNER " Built-in shell (ash)\n"
11833 "Enter 'help' for a list of built-in commands.\n\n");
11841 #ifndef CONFIG_FEATURE_SH_EXTRA_QUIET
11842 /*** List the available builtins ***/
11844 static int helpcmd(int argc, char **argv)
11848 out1fmt("\nBuilt-in commands:\n-------------------\n");
11849 for (col = 0, i = 0; i < NUMBUILTINS; i++) {
11850 col += out1fmt("%c%s", ((col == 0) ? '\t' : ' '),
11851 builtincmd[i].name + 1);
11857 #ifdef CONFIG_FEATURE_SH_STANDALONE_SHELL
11859 extern const struct BB_applet applets[];
11860 extern const size_t NUM_APPLETS;
11862 for (i = 0; i < NUM_APPLETS; i++) {
11864 col += out1fmt("%c%s", ((col == 0) ? '\t' : ' '), applets[i].name);
11873 return EXIT_SUCCESS;
11875 #endif /* CONFIG_FEATURE_SH_EXTRA_QUIET */
11878 * Called to exit the shell.
11888 status = exitstatus;
11889 TRACE(("pid %d, exitshell(%d)\n", getpid(), status));
11890 if (setjmp(loc.loc)) {
11891 if (exception == EXEXIT)
11896 if ((p = trap[0])) {
11902 #ifdef CONFIG_FEATURE_COMMAND_SAVEHISTORY
11903 if (iflag && rootshell) {
11904 const char *hp = lookupvar("HISTFILE");
11907 save_history ( hp );
11915 static int decode_signal(const char *string, int minsig)
11918 const char *name = u_signal_names(string, &signo, minsig);
11920 return name ? signo : -1;
11925 static struct var *vartab[VTABSIZE];
11927 static int vpcmp(const void *, const void *);
11928 static struct var **findvar(struct var **, const char *);
11931 * Initialize the variable symbol tables and import the environment
11935 #ifdef CONFIG_ASH_GETOPTS
11937 * Safe version of setvar, returns 1 on success 0 on failure.
11941 setvarsafe(const char *name, const char *val, int flags)
11944 volatile int saveint;
11945 struct jmploc *volatile savehandler = handler;
11946 struct jmploc jmploc;
11949 if (setjmp(jmploc.loc))
11953 setvar(name, val, flags);
11956 handler = savehandler;
11957 RESTOREINT(saveint);
11963 * Set the value of a variable. The flags argument is ored with the
11964 * flags of the variable. If val is NULL, the variable is unset.
11968 setvar(const char *name, const char *val, int flags)
11975 q = endofname(name);
11976 p = strchrnul(q, '=');
11977 namelen = p - name;
11978 if (!namelen || p != q)
11979 sh_error("%.*s: bad variable name", namelen, name);
11984 vallen = strlen(val);
11987 p = mempcpy(nameeq = ckmalloc(namelen + vallen + 2), name, namelen);
11990 p = mempcpy(p, val, vallen);
11993 setvareq(nameeq, flags | VNOSAVE);
11999 * Same as setvar except that the variable and value are passed in
12000 * the first argument as name=value. Since the first argument will
12001 * be actually stored in the table, it should not be a string that
12003 * Called with interrupts off.
12007 setvareq(char *s, int flags)
12009 struct var *vp, **vpp;
12012 flags |= (VEXPORT & (((unsigned) (1 - aflag)) - 1));
12013 vp = *findvar(vpp, s);
12015 if ((vp->flags & (VREADONLY|VDYNAMIC)) == VREADONLY) {
12018 if (flags & VNOSAVE)
12021 sh_error("%.*s: is read only", strchrnul(n, '=') - n, n);
12024 if (flags & VNOSET)
12027 if (vp->func && (flags & VNOFUNC) == 0)
12028 (*vp->func)(strchrnul(s, '=') + 1);
12030 if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0)
12033 flags |= vp->flags & ~(VTEXTFIXED|VSTACK|VNOSAVE|VUNSET);
12035 if (flags & VNOSET)
12038 vp = ckmalloc(sizeof (*vp));
12043 if (!(flags & (VTEXTFIXED|VSTACK|VNOSAVE)))
12051 * Process a linked list of variable assignments.
12055 listsetvar(struct strlist *list_set_var, int flags)
12057 struct strlist *lp = list_set_var;
12063 setvareq(lp->text, flags);
12064 } while ((lp = lp->next));
12070 * Find the value of a variable. Returns NULL if not set.
12074 lookupvar(const char *name)
12078 if ((v = *findvar(hashvar(name), name))) {
12081 * Dynamic variables are implemented roughly the same way they are
12082 * in bash. Namely, they're "special" so long as they aren't unset.
12083 * As soon as they're unset, they're no longer dynamic, and dynamic
12084 * lookup will no longer happen at that point. -- PFM.
12086 if((v->flags & VDYNAMIC))
12089 if(!(v->flags & VUNSET))
12090 return strchrnul(v->text, '=') + 1;
12098 * Search the environment of a builtin command.
12102 bltinlookup(const char *name)
12104 struct strlist *sp;
12106 for (sp = cmdenviron ; sp ; sp = sp->next) {
12107 if (varequal(sp->text, name))
12108 return strchrnul(sp->text, '=') + 1;
12110 return lookupvar(name);
12115 * Generate a list of variables satisfying the given conditions.
12119 listvars(int on, int off, char ***end)
12130 for (vp = *vpp ; vp ; vp = vp->next)
12131 if ((vp->flags & mask) == on) {
12132 if (ep == stackstrend())
12133 ep = growstackstr();
12134 *ep++ = (char *) vp->text;
12136 } while (++vpp < vartab + VTABSIZE);
12137 if (ep == stackstrend())
12138 ep = growstackstr();
12142 return grabstackstr(ep);
12147 * POSIX requires that 'set' (but not export or readonly) output the
12148 * variables in lexicographic order - by the locale's collating order (sigh).
12149 * Maybe we could keep them in an ordered balanced binary tree
12150 * instead of hashed lists.
12151 * For now just roll 'em through qsort for printing...
12155 showvars(const char *sep_prefix, int on, int off)
12158 char **ep, **epend;
12160 ep = listvars(on, off, &epend);
12161 qsort(ep, epend - ep, sizeof(char *), vpcmp);
12163 sep = *sep_prefix ? spcstr : sep_prefix;
12165 for (; ep < epend; ep++) {
12169 p = strchrnul(*ep, '=');
12172 q = single_quote(++p);
12174 out1fmt("%s%s%.*s%s\n", sep_prefix, sep, (int)(p - *ep), *ep, q);
12183 * The export and readonly commands.
12187 exportcmd(int argc, char **argv)
12193 int flag = argv[0][0] == 'r'? VREADONLY : VEXPORT;
12196 notp = nextopt("p") - 'p';
12197 if (notp && ((name = *(aptr = argptr)))) {
12199 if ((p = strchr(name, '=')) != NULL) {
12202 if ((vp = *findvar(hashvar(name), name))) {
12207 setvar(name, p, flag);
12208 } while ((name = *++aptr) != NULL);
12210 showvars(argv[0], flag, 0);
12217 * Make a variable a local variable. When a variable is made local, it's
12218 * value and flags are saved in a localvar structure. The saved values
12219 * will be restored when the shell function returns. We handle the name
12220 * "-" as a special case.
12224 mklocal(char *name)
12226 struct localvar *lvp;
12231 lvp = ckmalloc(sizeof (struct localvar));
12232 if (name[0] == '-' && name[1] == '\0') {
12234 p = ckmalloc(sizeof(optlist));
12235 lvp->text = memcpy(p, optlist, sizeof(optlist));
12240 vpp = hashvar(name);
12241 vp = *findvar(vpp, name);
12242 eq = strchr(name, '=');
12245 setvareq(name, VSTRFIXED);
12247 setvar(name, NULL, VSTRFIXED);
12248 vp = *vpp; /* the new variable */
12249 lvp->flags = VUNSET;
12251 lvp->text = vp->text;
12252 lvp->flags = vp->flags;
12253 vp->flags |= VSTRFIXED|VTEXTFIXED;
12259 lvp->next = localvars;
12265 * The "local" command.
12269 localcmd(int argc, char **argv)
12274 while ((name = *argv++) != NULL) {
12282 * Called after a function returns.
12283 * Interrupts must be off.
12289 struct localvar *lvp;
12292 while ((lvp = localvars) != NULL) {
12293 localvars = lvp->next;
12295 TRACE(("poplocalvar %s", vp ? vp->text : "-"));
12296 if (vp == NULL) { /* $- saved */
12297 memcpy(optlist, lvp->text, sizeof(optlist));
12300 } else if ((lvp->flags & (VUNSET|VSTRFIXED)) == VUNSET) {
12301 unsetvar(vp->text);
12304 (*vp->func)(strchrnul(lvp->text, '=') + 1);
12305 if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0)
12307 vp->flags = lvp->flags;
12308 vp->text = lvp->text;
12316 * The unset builtin command. We unset the function before we unset the
12317 * variable to allow a function to be unset when there is a readonly variable
12318 * with the same name.
12322 unsetcmd(int argc, char **argv)
12329 while ((i = nextopt("vf")) != '\0') {
12333 for (ap = argptr; *ap ; ap++) {
12348 * Unset the specified variable.
12352 unsetvar(const char *s)
12358 vpp = findvar(hashvar(s), s);
12362 int flags = vp->flags;
12365 if (flags & VREADONLY)
12368 vp->flags &= ~VDYNAMIC;
12370 if (flags & VUNSET)
12372 if ((flags & VSTRFIXED) == 0) {
12374 if ((flags & (VTEXTFIXED|VSTACK)) == 0)
12381 vp->flags &= ~VEXPORT;
12394 * Find the appropriate entry in the hash table from the name.
12397 static struct var **
12398 hashvar(const char *p)
12400 unsigned int hashval;
12402 hashval = ((unsigned char) *p) << 4;
12403 while (*p && *p != '=')
12404 hashval += (unsigned char) *p++;
12405 return &vartab[hashval % VTABSIZE];
12411 * Compares two strings up to the first = or '\0'. The first
12412 * string must be terminated by '='; the second may be terminated by
12413 * either '=' or '\0'.
12417 varcmp(const char *p, const char *q)
12421 while ((c = *p) == (d = *q)) {
12422 if (!c || c == '=')
12436 vpcmp(const void *a, const void *b)
12438 return varcmp(*(const char **)a, *(const char **)b);
12441 static struct var **
12442 findvar(struct var **vpp, const char *name)
12444 for (; *vpp; vpp = &(*vpp)->next) {
12445 if (varequal((*vpp)->text, name)) {
12453 #include <sys/times.h>
12455 static const unsigned char timescmd_str[] = {
12456 ' ', offsetof(struct tms, tms_utime),
12457 '\n', offsetof(struct tms, tms_stime),
12458 ' ', offsetof(struct tms, tms_cutime),
12459 '\n', offsetof(struct tms, tms_cstime),
12463 static int timescmd(int ac, char **av)
12465 long int clk_tck, s, t;
12466 const unsigned char *p;
12469 clk_tck = sysconf(_SC_CLK_TCK);
12474 t = *(clock_t *)(((char *) &buf) + p[1]);
12476 out1fmt("%ldm%ld.%.3lds%c",
12478 ((t - s * clk_tck) * 1000) / clk_tck,
12480 } while (*(p += 2));
12485 #ifdef CONFIG_ASH_MATH_SUPPORT
12487 dash_arith(const char *s)
12493 result = arith(s, &errcode);
12496 sh_error("exponent less than 0");
12497 else if (errcode == -2)
12498 sh_error("divide by zero");
12499 else if (errcode == -5)
12500 sh_error("expression recursion loop detected");
12511 * The let builtin. partial stolen from GNU Bash, the Bourne Again SHell.
12512 * Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
12514 * Copyright (C) 2003 Vladimir Oleynik <dzo@simtreas.ru>
12518 letcmd(int argc, char **argv)
12525 sh_error("expression expected");
12526 for (ap = argv + 1; *ap; ap++) {
12527 i = dash_arith(*ap);
12532 #endif /* CONFIG_ASH_MATH_SUPPORT */
12537 * Miscellaneous builtins.
12543 #if __GLIBC__ == 2 && __GLIBC_MINOR__ < 1
12544 typedef enum __rlimit_resource rlim_t;
12550 * The read builtin. The -e option causes backslashes to escape the
12551 * following character.
12553 * This uses unbuffered input, which may be avoidable in some cases.
12557 readcmd(int argc, char **argv)
12569 #if defined(CONFIG_ASH_READ_NCHARS)
12573 struct termios tty, old_tty;
12575 #if defined(CONFIG_ASH_READ_TIMEOUT)
12579 ts.tv_sec = ts.tv_usec = 0;
12584 #if defined(CONFIG_ASH_READ_NCHARS) && defined(CONFIG_ASH_READ_TIMEOUT)
12585 while ((i = nextopt("p:rt:n:s")) != '\0')
12586 #elif defined(CONFIG_ASH_READ_NCHARS)
12587 while ((i = nextopt("p:rn:s")) != '\0')
12588 #elif defined(CONFIG_ASH_READ_TIMEOUT)
12589 while ((i = nextopt("p:rt:")) != '\0')
12591 while ((i = nextopt("p:r")) != '\0')
12596 prompt = optionarg;
12598 #if defined(CONFIG_ASH_READ_NCHARS)
12600 nchars = strtol(optionarg, &p, 10);
12602 sh_error("invalid count");
12603 nch_flag = (nchars > 0);
12609 #if defined(CONFIG_ASH_READ_TIMEOUT)
12611 ts.tv_sec = strtol(optionarg, &p, 10);
12617 ts.tv_usec = strtol(p, &p2, 10);
12619 sh_error("invalid timeout");
12621 /* normalize to usec */
12623 sh_error("invalid timeout");
12624 while (scale++ < 6)
12628 sh_error("invalid timeout");
12630 if ( ! ts.tv_sec && ! ts.tv_usec)
12631 sh_error("invalid timeout");
12641 if (prompt && isatty(0)) {
12644 if (*(ap = argptr) == NULL)
12645 sh_error("arg count");
12646 if ((ifs = bltinlookup("IFS")) == NULL)
12648 #if defined(CONFIG_ASH_READ_NCHARS)
12649 if (nch_flag || silent) {
12650 tcgetattr(0, &tty);
12653 tty.c_lflag &= ~ICANON;
12654 tty.c_cc[VMIN] = nchars;
12657 tty.c_lflag &= ~(ECHO|ECHOK|ECHONL);
12660 tcsetattr(0, TCSANOW, &tty);
12663 #if defined(CONFIG_ASH_READ_TIMEOUT)
12664 if (ts.tv_sec || ts.tv_usec) {
12668 i = select (FD_SETSIZE, &set, NULL, NULL, &ts);
12670 #if defined(CONFIG_ASH_READ_NCHARS)
12672 tcsetattr(0, TCSANOW, &old_tty);
12682 #if defined(CONFIG_ASH_READ_NCHARS)
12683 while (!nch_flag || nchars--)
12688 if (read(0, &c, 1) != 1) {
12700 if (!rflag && c == '\\') {
12706 if (startword && *ifs == ' ' && strchr(ifs, c)) {
12710 if (ap[1] != NULL && strchr(ifs, c) != NULL) {
12712 setvar(*ap, stackblock(), 0);
12721 #if defined(CONFIG_ASH_READ_NCHARS)
12722 if (nch_flag || silent)
12723 tcsetattr(0, TCSANOW, &old_tty);
12727 /* Remove trailing blanks */
12728 while ((char *)stackblock() <= --p && strchr(ifs, *p) != NULL)
12730 setvar(*ap, stackblock(), 0);
12731 while (*++ap != NULL)
12732 setvar(*ap, nullstr, 0);
12737 static int umaskcmd(int argc, char **argv)
12739 static const char permuser[3] = "ugo";
12740 static const char permmode[3] = "rwx";
12741 static const short int permmask[] = {
12742 S_IRUSR, S_IWUSR, S_IXUSR,
12743 S_IRGRP, S_IWGRP, S_IXGRP,
12744 S_IROTH, S_IWOTH, S_IXOTH
12750 int symbolic_mode = 0;
12752 while (nextopt("S") != '\0') {
12761 if ((ap = *argptr) == NULL) {
12762 if (symbolic_mode) {
12766 for (i = 0; i < 3; i++) {
12769 *p++ = permuser[i];
12771 for (j = 0; j < 3; j++) {
12772 if ((mask & permmask[3 * i + j]) == 0) {
12773 *p++ = permmode[j];
12781 out1fmt("%.4o\n", mask);
12784 if (is_digit((unsigned char) *ap)) {
12787 if (*ap >= '8' || *ap < '0')
12788 sh_error(illnum, argv[1]);
12789 mask = (mask << 3) + (*ap - '0');
12790 } while (*++ap != '\0');
12793 mask = ~mask & 0777;
12794 if (!bb_parse_mode(ap, &mask)) {
12795 sh_error("Illegal mode: %s", ap);
12797 umask(~mask & 0777);
12806 * This code, originally by Doug Gwyn, Doug Kingston, Eric Gisin, and
12807 * Michael Rendell was ripped from pdksh 5.0.8 and hacked for use with
12808 * ash by J.T. Conklin.
12816 int factor; /* multiply by to get rlim_{cur,max} values */
12820 static const struct limits limits[] = {
12822 { "time(seconds)", RLIMIT_CPU, 1, 't' },
12824 #ifdef RLIMIT_FSIZE
12825 { "file(blocks)", RLIMIT_FSIZE, 512, 'f' },
12828 { "data(kbytes)", RLIMIT_DATA, 1024, 'd' },
12830 #ifdef RLIMIT_STACK
12831 { "stack(kbytes)", RLIMIT_STACK, 1024, 's' },
12834 { "coredump(blocks)", RLIMIT_CORE, 512, 'c' },
12837 { "memory(kbytes)", RLIMIT_RSS, 1024, 'm' },
12839 #ifdef RLIMIT_MEMLOCK
12840 { "locked memory(kbytes)", RLIMIT_MEMLOCK, 1024, 'l' },
12842 #ifdef RLIMIT_NPROC
12843 { "process", RLIMIT_NPROC, 1, 'p' },
12845 #ifdef RLIMIT_NOFILE
12846 { "nofiles", RLIMIT_NOFILE, 1, 'n' },
12849 { "vmemory(kbytes)", RLIMIT_AS, 1024, 'v' },
12851 #ifdef RLIMIT_LOCKS
12852 { "locks", RLIMIT_LOCKS, 1, 'w' },
12854 { (char *) 0, 0, 0, '\0' }
12857 enum limtype { SOFT = 0x1, HARD = 0x2 };
12859 static void printlim(enum limtype how, const struct rlimit *limit,
12860 const struct limits *l)
12864 val = limit->rlim_max;
12866 val = limit->rlim_cur;
12868 if (val == RLIM_INFINITY)
12869 out1fmt("unlimited\n");
12872 out1fmt("%lld\n", (long long) val);
12877 ulimitcmd(int argc, char **argv)
12881 enum limtype how = SOFT | HARD;
12882 const struct limits *l;
12885 struct rlimit limit;
12888 while ((optc = nextopt("HSa"
12892 #ifdef RLIMIT_FSIZE
12898 #ifdef RLIMIT_STACK
12907 #ifdef RLIMIT_MEMLOCK
12910 #ifdef RLIMIT_NPROC
12913 #ifdef RLIMIT_NOFILE
12919 #ifdef RLIMIT_LOCKS
12937 for (l = limits; l->option != what; l++)
12940 set = *argptr ? 1 : 0;
12944 if (all || argptr[1])
12945 sh_error("too many arguments");
12946 if (strncmp(p, "unlimited\n", 9) == 0)
12947 val = RLIM_INFINITY;
12951 while ((c = *p++) >= '0' && c <= '9')
12953 val = (val * 10) + (long)(c - '0');
12954 if (val < (rlim_t) 0)
12958 sh_error("bad number");
12963 for (l = limits; l->name; l++) {
12964 getrlimit(l->cmd, &limit);
12965 out1fmt("%-20s ", l->name);
12966 printlim(how, &limit, l);
12971 getrlimit(l->cmd, &limit);
12974 limit.rlim_max = val;
12976 limit.rlim_cur = val;
12977 if (setrlimit(l->cmd, &limit) < 0)
12978 sh_error("error setting limit (%m)");
12980 printlim(how, &limit, l);
12986 #ifdef CONFIG_ASH_MATH_SUPPORT
12988 /* Copyright (c) 2001 Aaron Lehmann <aaronl@vitelus.com>
12990 Permission is hereby granted, free of charge, to any person obtaining
12991 a copy of this software and associated documentation files (the
12992 "Software"), to deal in the Software without restriction, including
12993 without limitation the rights to use, copy, modify, merge, publish,
12994 distribute, sublicense, and/or sell copies of the Software, and to
12995 permit persons to whom the Software is furnished to do so, subject to
12996 the following conditions:
12998 The above copyright notice and this permission notice shall be
12999 included in all copies or substantial portions of the Software.
13001 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13002 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
13003 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
13004 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
13005 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
13006 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
13007 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13010 /* This is my infix parser/evaluator. It is optimized for size, intended
13011 * as a replacement for yacc-based parsers. However, it may well be faster
13012 * than a comparable parser written in yacc. The supported operators are
13013 * listed in #defines below. Parens, order of operations, and error handling
13014 * are supported. This code is thread safe. The exact expression format should
13015 * be that which POSIX specifies for shells. */
13017 /* The code uses a simple two-stack algorithm. See
13018 * http://www.onthenet.com.au/~grahamis/int2008/week02/lect02.html
13019 * for a detailed explanation of the infix-to-postfix algorithm on which
13020 * this is based (this code differs in that it applies operators immediately
13021 * to the stack instead of adding them to a queue to end up with an
13024 /* To use the routine, call it with an expression string and error return
13028 * Aug 24, 2001 Manuel Novoa III
13030 * Reduced the generated code size by about 30% (i386) and fixed several bugs.
13032 * 1) In arith_apply():
13033 * a) Cached values of *numptr and &(numptr[-1]).
13034 * b) Removed redundant test for zero denominator.
13037 * a) Eliminated redundant code for processing operator tokens by moving
13038 * to a table-based implementation. Also folded handling of parens
13040 * b) Combined all 3 loops which called arith_apply to reduce generated
13041 * code size at the cost of speed.
13043 * 3) The following expressions were treated as valid by the original code:
13044 * 1() , 0! , 1 ( *3 ) .
13045 * These bugs have been fixed by internally enclosing the expression in
13046 * parens and then checking that all binary ops and right parens are
13047 * preceded by a valid expression (NUM_TOKEN).
13049 * Note: It may be desirable to replace Aaron's test for whitespace with
13050 * ctype's isspace() if it is used by another busybox applet or if additional
13051 * whitespace chars should be considered. Look below the "#include"s for a
13052 * precompiler test.
13056 * Aug 26, 2001 Manuel Novoa III
13058 * Return 0 for null expressions. Pointed out by Vladimir Oleynik.
13060 * Merge in Aaron's comments previously posted to the busybox list,
13061 * modified slightly to take account of my changes to the code.
13066 * (C) 2003 Vladimir Oleynik <dzo@simtreas.ru>
13068 * - allow access to variable,
13069 * used recursive find value indirection (c=2*2; a="c"; $((a+=2)) produce 6)
13070 * - realize assign syntax (VAR=expr, +=, *= etc)
13071 * - realize exponentiation (** operator)
13072 * - realize comma separated - expr, expr
13073 * - realise ++expr --expr expr++ expr--
13074 * - realise expr ? expr : expr (but, second expr calculate always)
13075 * - allow hexadecimal and octal numbers
13076 * - was restored loses XOR operator
13077 * - remove one goto label, added three ;-)
13078 * - protect $((num num)) as true zero expr (Manuel`s error)
13079 * - always use special isspace(), see comment from bash ;-)
13083 #define arith_isspace(arithval) \
13084 (arithval == ' ' || arithval == '\n' || arithval == '\t')
13087 typedef unsigned char operator;
13089 /* An operator's token id is a bit of a bitfield. The lower 5 bits are the
13090 * precedence, and 3 high bits are an ID unique across operators of that
13091 * precedence. The ID portion is so that multiple operators can have the
13092 * same precedence, ensuring that the leftmost one is evaluated first.
13093 * Consider * and /. */
13095 #define tok_decl(prec,id) (((id)<<5)|(prec))
13096 #define PREC(op) ((op) & 0x1F)
13098 #define TOK_LPAREN tok_decl(0,0)
13100 #define TOK_COMMA tok_decl(1,0)
13102 #define TOK_ASSIGN tok_decl(2,0)
13103 #define TOK_AND_ASSIGN tok_decl(2,1)
13104 #define TOK_OR_ASSIGN tok_decl(2,2)
13105 #define TOK_XOR_ASSIGN tok_decl(2,3)
13106 #define TOK_PLUS_ASSIGN tok_decl(2,4)
13107 #define TOK_MINUS_ASSIGN tok_decl(2,5)
13108 #define TOK_LSHIFT_ASSIGN tok_decl(2,6)
13109 #define TOK_RSHIFT_ASSIGN tok_decl(2,7)
13111 #define TOK_MUL_ASSIGN tok_decl(3,0)
13112 #define TOK_DIV_ASSIGN tok_decl(3,1)
13113 #define TOK_REM_ASSIGN tok_decl(3,2)
13115 /* all assign is right associativity and precedence eq, but (7+3)<<5 > 256 */
13116 #define convert_prec_is_assing(prec) do { if(prec == 3) prec = 2; } while(0)
13118 /* conditional is right associativity too */
13119 #define TOK_CONDITIONAL tok_decl(4,0)
13120 #define TOK_CONDITIONAL_SEP tok_decl(4,1)
13122 #define TOK_OR tok_decl(5,0)
13124 #define TOK_AND tok_decl(6,0)
13126 #define TOK_BOR tok_decl(7,0)
13128 #define TOK_BXOR tok_decl(8,0)
13130 #define TOK_BAND tok_decl(9,0)
13132 #define TOK_EQ tok_decl(10,0)
13133 #define TOK_NE tok_decl(10,1)
13135 #define TOK_LT tok_decl(11,0)
13136 #define TOK_GT tok_decl(11,1)
13137 #define TOK_GE tok_decl(11,2)
13138 #define TOK_LE tok_decl(11,3)
13140 #define TOK_LSHIFT tok_decl(12,0)
13141 #define TOK_RSHIFT tok_decl(12,1)
13143 #define TOK_ADD tok_decl(13,0)
13144 #define TOK_SUB tok_decl(13,1)
13146 #define TOK_MUL tok_decl(14,0)
13147 #define TOK_DIV tok_decl(14,1)
13148 #define TOK_REM tok_decl(14,2)
13150 /* exponent is right associativity */
13151 #define TOK_EXPONENT tok_decl(15,1)
13153 /* For now unary operators. */
13154 #define UNARYPREC 16
13155 #define TOK_BNOT tok_decl(UNARYPREC,0)
13156 #define TOK_NOT tok_decl(UNARYPREC,1)
13158 #define TOK_UMINUS tok_decl(UNARYPREC+1,0)
13159 #define TOK_UPLUS tok_decl(UNARYPREC+1,1)
13161 #define PREC_PRE (UNARYPREC+2)
13163 #define TOK_PRE_INC tok_decl(PREC_PRE, 0)
13164 #define TOK_PRE_DEC tok_decl(PREC_PRE, 1)
13166 #define PREC_POST (UNARYPREC+3)
13168 #define TOK_POST_INC tok_decl(PREC_POST, 0)
13169 #define TOK_POST_DEC tok_decl(PREC_POST, 1)
13171 #define SPEC_PREC (UNARYPREC+4)
13173 #define TOK_NUM tok_decl(SPEC_PREC, 0)
13174 #define TOK_RPAREN tok_decl(SPEC_PREC, 1)
13176 #define NUMPTR (*numstackptr)
13178 static inline int tok_have_assign(operator op)
13180 operator prec = PREC(op);
13182 convert_prec_is_assing(prec);
13183 return (prec == PREC(TOK_ASSIGN) ||
13184 prec == PREC_PRE || prec == PREC_POST);
13187 static inline int is_right_associativity(operator prec)
13189 return (prec == PREC(TOK_ASSIGN) || prec == PREC(TOK_EXPONENT) ||
13190 prec == PREC(TOK_CONDITIONAL));
13194 typedef struct ARITCH_VAR_NUM {
13196 arith_t contidional_second_val;
13197 char contidional_second_val_initialized;
13198 char *var; /* if NULL then is regular number,
13199 else is variable name */
13203 typedef struct CHK_VAR_RECURSIVE_LOOPED {
13205 struct CHK_VAR_RECURSIVE_LOOPED *next;
13206 } chk_var_recursive_looped_t;
13208 static chk_var_recursive_looped_t *prev_chk_var_recursive;
13211 static int arith_lookup_val(v_n_t *t)
13214 const char * p = lookupvar(t->var);
13219 /* recursive try as expression */
13220 chk_var_recursive_looped_t *cur;
13221 chk_var_recursive_looped_t cur_save;
13223 for(cur = prev_chk_var_recursive; cur; cur = cur->next) {
13224 if(strcmp(cur->var, t->var) == 0) {
13225 /* expression recursion loop detected */
13229 /* save current lookuped var name */
13230 cur = prev_chk_var_recursive;
13231 cur_save.var = t->var;
13232 cur_save.next = cur;
13233 prev_chk_var_recursive = &cur_save;
13235 t->val = arith (p, &errcode);
13236 /* restore previous ptr after recursiving */
13237 prev_chk_var_recursive = cur;
13240 /* allow undefined var as 0 */
13247 /* "applying" a token means performing it on the top elements on the integer
13248 * stack. For a unary operator it will only change the top element, but a
13249 * binary operator will pop two arguments and push a result */
13251 arith_apply(operator op, v_n_t *numstack, v_n_t **numstackptr)
13254 arith_t numptr_val, rez;
13255 int ret_arith_lookup_val;
13257 if (NUMPTR == numstack) goto err; /* There is no operator that can work
13258 without arguments */
13259 numptr_m1 = NUMPTR - 1;
13261 /* check operand is var with noninteger value */
13262 ret_arith_lookup_val = arith_lookup_val(numptr_m1);
13263 if(ret_arith_lookup_val)
13264 return ret_arith_lookup_val;
13266 rez = numptr_m1->val;
13267 if (op == TOK_UMINUS)
13269 else if (op == TOK_NOT)
13271 else if (op == TOK_BNOT)
13273 else if (op == TOK_POST_INC || op == TOK_PRE_INC)
13275 else if (op == TOK_POST_DEC || op == TOK_PRE_DEC)
13277 else if (op != TOK_UPLUS) {
13278 /* Binary operators */
13280 /* check and binary operators need two arguments */
13281 if (numptr_m1 == numstack) goto err;
13283 /* ... and they pop one */
13286 if (op == TOK_CONDITIONAL) {
13287 if(! numptr_m1->contidional_second_val_initialized) {
13288 /* protect $((expr1 ? expr2)) without ": expr" */
13291 rez = numptr_m1->contidional_second_val;
13292 } else if(numptr_m1->contidional_second_val_initialized) {
13293 /* protect $((expr1 : expr2)) without "expr ? " */
13296 numptr_m1 = NUMPTR - 1;
13297 if(op != TOK_ASSIGN) {
13298 /* check operand is var with noninteger value for not '=' */
13299 ret_arith_lookup_val = arith_lookup_val(numptr_m1);
13300 if(ret_arith_lookup_val)
13301 return ret_arith_lookup_val;
13303 if (op == TOK_CONDITIONAL) {
13304 numptr_m1->contidional_second_val = rez;
13306 rez = numptr_m1->val;
13307 if (op == TOK_BOR || op == TOK_OR_ASSIGN)
13309 else if (op == TOK_OR)
13310 rez = numptr_val || rez;
13311 else if (op == TOK_BAND || op == TOK_AND_ASSIGN)
13313 else if (op == TOK_BXOR || op == TOK_XOR_ASSIGN)
13315 else if (op == TOK_AND)
13316 rez = rez && numptr_val;
13317 else if (op == TOK_EQ)
13318 rez = (rez == numptr_val);
13319 else if (op == TOK_NE)
13320 rez = (rez != numptr_val);
13321 else if (op == TOK_GE)
13322 rez = (rez >= numptr_val);
13323 else if (op == TOK_RSHIFT || op == TOK_RSHIFT_ASSIGN)
13324 rez >>= numptr_val;
13325 else if (op == TOK_LSHIFT || op == TOK_LSHIFT_ASSIGN)
13326 rez <<= numptr_val;
13327 else if (op == TOK_GT)
13328 rez = (rez > numptr_val);
13329 else if (op == TOK_LT)
13330 rez = (rez < numptr_val);
13331 else if (op == TOK_LE)
13332 rez = (rez <= numptr_val);
13333 else if (op == TOK_MUL || op == TOK_MUL_ASSIGN)
13335 else if (op == TOK_ADD || op == TOK_PLUS_ASSIGN)
13337 else if (op == TOK_SUB || op == TOK_MINUS_ASSIGN)
13339 else if (op == TOK_ASSIGN || op == TOK_COMMA)
13341 else if (op == TOK_CONDITIONAL_SEP) {
13342 if (numptr_m1 == numstack) {
13343 /* protect $((expr : expr)) without "expr ? " */
13346 numptr_m1->contidional_second_val_initialized = op;
13347 numptr_m1->contidional_second_val = numptr_val;
13349 else if (op == TOK_CONDITIONAL) {
13351 numptr_val : numptr_m1->contidional_second_val;
13353 else if(op == TOK_EXPONENT) {
13355 return -3; /* exponent less than 0 */
13360 while(numptr_val--)
13365 else if(numptr_val==0) /* zero divisor check */
13367 else if (op == TOK_DIV || op == TOK_DIV_ASSIGN)
13369 else if (op == TOK_REM || op == TOK_REM_ASSIGN)
13372 if(tok_have_assign(op)) {
13375 if(numptr_m1->var == NULL) {
13379 /* save to shell variable */
13380 #ifdef CONFIG_ASH_MATH_SUPPORT_64
13381 snprintf(buf, sizeof(buf), "%lld", rez);
13383 snprintf(buf, sizeof(buf), "%ld", rez);
13385 setvar(numptr_m1->var, buf, 0);
13386 /* after saving, make previous value for v++ or v-- */
13387 if(op == TOK_POST_INC)
13389 else if(op == TOK_POST_DEC)
13392 numptr_m1->val = rez;
13393 /* protect geting var value, is number now */
13394 numptr_m1->var = NULL;
13399 /* longest must first */
13400 static const char op_tokens[] = {
13401 '<','<','=',0, TOK_LSHIFT_ASSIGN,
13402 '>','>','=',0, TOK_RSHIFT_ASSIGN,
13403 '<','<', 0, TOK_LSHIFT,
13404 '>','>', 0, TOK_RSHIFT,
13405 '|','|', 0, TOK_OR,
13406 '&','&', 0, TOK_AND,
13407 '!','=', 0, TOK_NE,
13408 '<','=', 0, TOK_LE,
13409 '>','=', 0, TOK_GE,
13410 '=','=', 0, TOK_EQ,
13411 '|','=', 0, TOK_OR_ASSIGN,
13412 '&','=', 0, TOK_AND_ASSIGN,
13413 '*','=', 0, TOK_MUL_ASSIGN,
13414 '/','=', 0, TOK_DIV_ASSIGN,
13415 '%','=', 0, TOK_REM_ASSIGN,
13416 '+','=', 0, TOK_PLUS_ASSIGN,
13417 '-','=', 0, TOK_MINUS_ASSIGN,
13418 '-','-', 0, TOK_POST_DEC,
13419 '^','=', 0, TOK_XOR_ASSIGN,
13420 '+','+', 0, TOK_POST_INC,
13421 '*','*', 0, TOK_EXPONENT,
13425 '=', 0, TOK_ASSIGN,
13437 '?', 0, TOK_CONDITIONAL,
13438 ':', 0, TOK_CONDITIONAL_SEP,
13439 ')', 0, TOK_RPAREN,
13440 '(', 0, TOK_LPAREN,
13444 #define endexpression &op_tokens[sizeof(op_tokens)-7]
13447 static arith_t arith (const char *expr, int *perrcode)
13449 register char arithval; /* Current character under analysis */
13450 operator lasttok, op;
13453 const char *p = endexpression;
13456 size_t datasizes = strlen(expr) + 2;
13458 /* Stack of integers */
13459 /* The proof that there can be no more than strlen(startbuf)/2+1 integers
13460 * in any given correct or incorrect expression is left as an exercise to
13462 v_n_t *numstack = alloca(((datasizes)/2)*sizeof(v_n_t)),
13463 *numstackptr = numstack;
13464 /* Stack of operator tokens */
13465 operator *stack = alloca((datasizes) * sizeof(operator)),
13468 *stackptr++ = lasttok = TOK_LPAREN; /* start off with a left paren */
13469 *perrcode = errcode = 0;
13472 if ((arithval = *expr) == 0) {
13473 if (p == endexpression) {
13474 /* Null expression. */
13478 /* This is only reached after all tokens have been extracted from the
13479 * input stream. If there are still tokens on the operator stack, they
13480 * are to be applied in order. At the end, there should be a final
13481 * result on the integer stack */
13483 if (expr != endexpression + 1) {
13484 /* If we haven't done so already, */
13485 /* append a closing right paren */
13486 expr = endexpression;
13487 /* and let the loop process it. */
13490 /* At this point, we're done with the expression. */
13491 if (numstackptr != numstack+1) {
13492 /* ... but if there isn't, it's bad */
13494 return (*perrcode = -1);
13496 if(numstack->var) {
13497 /* expression is $((var)) only, lookup now */
13498 errcode = arith_lookup_val(numstack);
13501 *perrcode = errcode;
13502 return numstack->val;
13504 /* Continue processing the expression. */
13505 if (arith_isspace(arithval)) {
13506 /* Skip whitespace */
13509 if((p = endofname(expr)) != expr) {
13510 size_t var_name_size = (p-expr) + 1; /* trailing zero */
13512 numstackptr->var = alloca(var_name_size);
13513 safe_strncpy(numstackptr->var, expr, var_name_size);
13516 numstackptr->contidional_second_val_initialized = 0;
13520 } else if (is_digit(arithval)) {
13521 numstackptr->var = NULL;
13522 #ifdef CONFIG_ASH_MATH_SUPPORT_64
13523 numstackptr->val = strtoll(expr, (char **) &expr, 0);
13525 numstackptr->val = strtol(expr, (char **) &expr, 0);
13529 for(p = op_tokens; ; p++) {
13533 /* strange operator not found */
13536 for(o = expr; *p && *o == *p; p++)
13543 /* skip tail uncompared token */
13546 /* skip zero delim */
13551 /* post grammar: a++ reduce to num */
13552 if(lasttok == TOK_POST_INC || lasttok == TOK_POST_DEC)
13555 /* Plus and minus are binary (not unary) _only_ if the last
13556 * token was as number, or a right paren (which pretends to be
13557 * a number, since it evaluates to one). Think about it.
13558 * It makes sense. */
13559 if (lasttok != TOK_NUM) {
13575 /* We don't want a unary operator to cause recursive descent on the
13576 * stack, because there can be many in a row and it could cause an
13577 * operator to be evaluated before its argument is pushed onto the
13578 * integer stack. */
13579 /* But for binary operators, "apply" everything on the operator
13580 * stack until we find an operator with a lesser priority than the
13581 * one we have just extracted. */
13582 /* Left paren is given the lowest priority so it will never be
13583 * "applied" in this way.
13584 * if associativity is right and priority eq, applied also skip
13587 if ((prec > 0 && prec < UNARYPREC) || prec == SPEC_PREC) {
13588 /* not left paren or unary */
13589 if (lasttok != TOK_NUM) {
13590 /* binary op must be preceded by a num */
13593 while (stackptr != stack) {
13594 if (op == TOK_RPAREN) {
13595 /* The algorithm employed here is simple: while we don't
13596 * hit an open paren nor the bottom of the stack, pop
13597 * tokens and apply them */
13598 if (stackptr[-1] == TOK_LPAREN) {
13600 /* Any operator directly after a */
13602 /* close paren should consider itself binary */
13606 operator prev_prec = PREC(stackptr[-1]);
13608 convert_prec_is_assing(prec);
13609 convert_prec_is_assing(prev_prec);
13610 if (prev_prec < prec)
13612 /* check right assoc */
13613 if(prev_prec == prec && is_right_associativity(prec))
13616 errcode = arith_apply(*--stackptr, numstack, &numstackptr);
13617 if(errcode) goto ret;
13619 if (op == TOK_RPAREN) {
13624 /* Push this operator to the stack and remember it. */
13625 *stackptr++ = lasttok = op;
13632 #endif /* CONFIG_ASH_MATH_SUPPORT */
13636 const char *bb_applet_name = "debug stuff usage";
13637 int main(int argc, char **argv)
13639 return ash_main(argc, argv);
13644 * Copyright (c) 1989, 1991, 1993, 1994
13645 * The Regents of the University of California. All rights reserved.
13647 * This code is derived from software contributed to Berkeley by
13648 * Kenneth Almquist.
13650 * Redistribution and use in source and binary forms, with or without
13651 * modification, are permitted provided that the following conditions
13653 * 1. Redistributions of source code must retain the above copyright
13654 * notice, this list of conditions and the following disclaimer.
13655 * 2. Redistributions in binary form must reproduce the above copyright
13656 * notice, this list of conditions and the following disclaimer in the
13657 * documentation and/or other materials provided with the distribution.
13658 * 3. Neither the name of the University nor the names of its contributors
13659 * may be used to endorse or promote products derived from this software
13660 * without specific prior written permission.
13662 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
13663 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
13664 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
13665 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
13666 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
13667 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
13668 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
13669 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
13670 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
13671 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF