1 /* vi: set sw=4 ts=4: */
3 * ash shell port for busybox
5 * Copyright (c) 1989, 1991, 1993, 1994
6 * The Regents of the University of California. All rights reserved.
8 * This code is derived from software contributed to Berkeley by
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 * This version of ash is adapted from the source in Debian's ash 0.3.8-5
28 * Modified by Erik Andersen <andersee@debian.org> and
29 * Vladimir Oleynik <vodz@usa.net> to be used in busybox
32 * Original copyright notice is retained at the end of this file.
36 /* These defines allow you to adjust the feature set to be compiled
37 * into the ash shell. As a rule, enabling these options will make
38 * ash get bigger... With all of these options off, ash adds about
39 * 60k to busybox on an x86 system.*/
42 /* Enable job control. This allows you to run jobs in the background,
43 * which is great when ash is being used as an interactive shell, but
44 * it completely useless for is all you are doing is running scripts.
45 * This adds about 2.5k on an x86 system. */
48 /* This enables alias support in ash. If you want to support things
49 * like "alias ls='ls -l'" with ash, enable this. This is only useful
50 * when ash is used as an intractive shell. This adds about 1.5k */
53 /* If you need ash to act as a full Posix shell, with full math
54 * support, enable this. This option needs some work, since it
55 * doesn't compile right now... */
56 #undef ASH_MATH_SUPPORT
58 /* Getopts is used by shell procedures to parse positional parameters.
59 * You probably want to leave this disabled, and use the busybox getopt
60 * applet if you want to do this sort of thing. There are some scripts
61 * out there that use it, so it you need it, enable. Most people will
62 * leave this disabled. This adds 1k on an x86 system. */
65 /* This allows you to override shell builtins and use whatever is on
66 * the filesystem. This is most useful when ash is acting as a
67 * standalone shell. Adds about 272 bytes. */
71 /* Optimize size vs speed as size */
72 #define ASH_OPTIMIZE_FOR_SIZE
74 /* Enable this to compile in extra debugging noise. When debugging is
75 * on, debugging info will be written to $HOME/trace and a quit signal
76 * will generate a core dump. */
79 /* These are here to work with glibc -- Don't change these... */
100 #include <sys/stat.h>
101 #include <sys/cdefs.h>
102 #include <sys/ioctl.h>
103 #include <sys/param.h>
104 #include <sys/resource.h>
105 #include <sys/time.h>
106 #include <sys/times.h>
107 #include <sys/types.h>
108 #include <sys/wait.h>
111 #if !defined(FNMATCH_BROKEN)
114 #if !defined(GLOB_BROKEN)
126 * This file was generated by the mksyntax program.
130 #define CWORD 0 /* character is nothing special */
131 #define CNL 1 /* newline character */
132 #define CBACK 2 /* a backslash character */
133 #define CSQUOTE 3 /* single quote */
134 #define CDQUOTE 4 /* double quote */
135 #define CENDQUOTE 5 /* a terminating quote */
136 #define CBQUOTE 6 /* backwards single quote */
137 #define CVAR 7 /* a dollar sign */
138 #define CENDVAR 8 /* a '}' character */
139 #define CLP 9 /* a left paren in arithmetic */
140 #define CRP 10 /* a right paren in arithmetic */
141 #define CENDFILE 11 /* end of file */
142 #define CCTL 12 /* like CWORD, except it must be escaped */
143 #define CSPCL 13 /* these terminate a word */
144 #define CIGN 14 /* character should be ignored */
146 /* Syntax classes for is_ functions */
147 #define ISDIGIT 01 /* a digit */
148 #define ISUPPER 02 /* an upper case letter */
149 #define ISLOWER 04 /* a lower case letter */
150 #define ISUNDER 010 /* an underscore */
151 #define ISSPECL 020 /* the name of a special parameter */
168 #define TENDBQUOTE 10
190 #define BASESYNTAX (basesyntax + SYNBASE)
191 #define DQSYNTAX (dqsyntax + SYNBASE)
192 #define SQSYNTAX (sqsyntax + SYNBASE)
193 #define ARISYNTAX (arisyntax + SYNBASE)
195 /* control characters in argument strings */
196 #define CTLESC '\201'
197 #define CTLVAR '\202'
198 #define CTLENDVAR '\203'
199 #define CTLBACKQ '\204'
200 #define CTLQUOTE 01 /* ored with CTLBACKQ code if in quotes */
201 /* CTLBACKQ | CTLQUOTE == '\205' */
202 #define CTLARI '\206'
203 #define CTLENDARI '\207'
204 #define CTLQUOTEMARK '\210'
206 #define is_digit(c) ((c)>='0' && (c)<='9')
207 #define is_alpha(c) (((c) < CTLESC || (c) > CTLENDARI) && isalpha((unsigned char) (c)))
208 #define is_name(c) (((c) < CTLESC || (c) > CTLENDARI) && ((c) == '_' || isalpha((unsigned char) (c))))
209 #define is_in_name(c) (((c) < CTLESC || (c) > CTLENDARI) && ((c) == '_' || isalnum((unsigned char) (c))))
210 #define is_special(c) ((is_type+SYNBASE)[c] & (ISSPECL|ISDIGIT))
211 #define digit_val(c) ((c) - '0')
214 #define _DIAGASSERT(x)
218 #define S_DFL 1 /* default signal handling (SIG_DFL) */
219 #define S_CATCH 2 /* signal is caught */
220 #define S_IGN 3 /* signal is ignored (SIG_IGN) */
221 #define S_HARD_IGN 4 /* signal is ignored permenantly */
222 #define S_RESET 5 /* temporary - to reset a hard ignored sig */
225 /* variable substitution byte (follows CTLVAR) */
226 #define VSTYPE 0x0f /* type of variable substitution */
227 #define VSNUL 0x10 /* colon--treat the empty string as unset */
228 #define VSQUOTE 0x80 /* inside double quotes--suppress splitting */
230 /* values of VSTYPE field */
231 #define VSNORMAL 0x1 /* normal variable: $var or ${var} */
232 #define VSMINUS 0x2 /* ${var-text} */
233 #define VSPLUS 0x3 /* ${var+text} */
234 #define VSQUESTION 0x4 /* ${var?message} */
235 #define VSASSIGN 0x5 /* ${var=text} */
236 #define VSTRIMLEFT 0x6 /* ${var#pattern} */
237 #define VSTRIMLEFTMAX 0x7 /* ${var##pattern} */
238 #define VSTRIMRIGHT 0x8 /* ${var%pattern} */
239 #define VSTRIMRIGHTMAX 0x9 /* ${var%%pattern} */
240 #define VSLENGTH 0xa /* ${#var} */
242 /* flags passed to redirect */
243 #define REDIR_PUSH 01 /* save previous values of file descriptors */
244 #define REDIR_BACKQ 02 /* save the command output to pipe */
247 * BSD setjmp saves the signal mask, which violates ANSI C and takes time,
248 * so we use _setjmp instead.
252 #define setjmp(jmploc) _setjmp(jmploc)
253 #define longjmp(jmploc, val) _longjmp(jmploc, val)
257 * Most machines require the value returned from malloc to be aligned
258 * in some way. The following macro will get this right on many machines.
267 #define ALIGN(nbytes) (((nbytes) + sizeof(union align) - 1) & ~(sizeof(union align) - 1))
270 #ifdef BB_LOCALE_SUPPORT
272 static void change_lc_all(const char *value);
273 static void change_lc_ctype(const char *value);
277 * These macros allow the user to suspend the handling of interrupt signals
278 * over a period of time. This is similar to SIGHOLD to or sigblock, but
279 * much more efficient and portable. (But hacking the kernel is so much
280 * more fun than worrying about efficiency and portability. :-))
283 static void onint (void);
284 static volatile int suppressint;
285 static volatile int intpending;
287 #define INTOFF suppressint++
288 #ifndef ASH_OPTIMIZE_FOR_SIZE
289 #define INTON { if (--suppressint == 0 && intpending) onint(); }
290 #define FORCEINTON {suppressint = 0; if (intpending) onint();}
292 static void __inton (void);
293 static void forceinton (void);
294 #define INTON __inton()
295 #define FORCEINTON forceinton()
298 #define CLEAR_PENDING_INT intpending = 0
299 #define int_pending() intpending
302 typedef void *pointer;
304 #define NULL (void *)0
307 static inline pointer ckmalloc (int sz) { return xmalloc(sz); }
308 static inline pointer ckrealloc(void *p, int sz) { return xrealloc(p, sz); }
309 static inline char * savestr (const char *s) { return xstrdup(s); }
311 static pointer stalloc (int);
312 static void stunalloc (pointer);
313 static void ungrabstackstr (char *, char *);
314 static char * growstackstr(void);
315 static char * makestrspace(size_t newlen);
316 static char *sstrdup (const char *);
319 * Parse trees for commands are allocated in lifo order, so we use a stack
320 * to make this more efficient, and also to avoid all sorts of exception
321 * handling code to handle interrupts in the middle of a parse.
323 * The size 504 was chosen because the Ultrix malloc handles that size
327 #define MINSIZE 504 /* minimum size of a block */
331 struct stack_block *prev;
335 static struct stack_block stackbase;
336 static struct stack_block *stackp = &stackbase;
337 static struct stackmark *markp;
338 static char *stacknxt = stackbase.space;
339 static int stacknleft = MINSIZE;
342 #define equal(s1, s2) (strcmp(s1, s2) == 0)
344 #define stackblock() stacknxt
345 #define stackblocksize() stacknleft
346 #define STARTSTACKSTR(p) p = stackblock(), sstrnleft = stackblocksize()
348 #define STPUTC(c, p) (--sstrnleft >= 0? (*p++ = (c)) : (p = growstackstr(), *p++ = (c)))
349 #define CHECKSTRSPACE(n, p) { if (sstrnleft < n) p = makestrspace(n); }
350 #define STACKSTRNUL(p) (sstrnleft == 0? (p = growstackstr(), *p = '\0') : (*p = '\0'))
353 #define USTPUTC(c, p) (--sstrnleft, *p++ = (c))
354 #define STUNPUTC(p) (++sstrnleft, --p)
355 #define STTOPC(p) p[-1]
356 #define STADJUST(amount, p) (p += (amount), sstrnleft -= (amount))
357 #define grabstackstr(p) stalloc(stackblocksize() - sstrnleft)
359 #define ckfree(p) free((pointer)(p))
363 #define TRACE(param) trace param
364 static void trace (const char *, ...);
365 static void trargs (char **);
366 static void showtree (union node *);
367 static void trputc (int);
368 static void trputs (const char *);
369 static void opentrace (void);
404 #define EXP_FULL 0x1 /* perform word splitting & file globbing */
405 #define EXP_TILDE 0x2 /* do normal tilde expansion */
406 #define EXP_VARTILDE 0x4 /* expand tildes in an assignment */
407 #define EXP_REDIR 0x8 /* file glob for a redirection (1 match only) */
408 #define EXP_CASE 0x10 /* keeps quotes around for CASE pattern */
409 #define EXP_RECORD 0x20 /* need to record arguments for ifs breakup */
414 static char optet_vals[NOPTS];
416 static const char * const optlist[NOPTS] = {
435 #define optent_name(optent) (optent+1)
436 #define optent_letter(optent) optent[0]
437 #define optent_val(optent) optet_vals[optent]
439 #define eflag optent_val(0)
440 #define fflag optent_val(1)
441 #define Iflag optent_val(2)
442 #define iflag optent_val(3)
443 #define mflag optent_val(4)
444 #define nflag optent_val(5)
445 #define sflag optent_val(6)
446 #define xflag optent_val(7)
447 #define vflag optent_val(8)
448 #define Vflag optent_val(9)
449 #define Eflag optent_val(10)
450 #define Cflag optent_val(11)
451 #define aflag optent_val(12)
452 #define bflag optent_val(13)
453 #define uflag optent_val(14)
454 #define qflag optent_val(15)
457 /* Mode argument to forkshell. Don't change FORK_FG or FORK_BG. */
475 union node *redirect;
482 struct nodelist *cmdlist;
489 union node *redirect;
497 union node *elsepart;
528 struct nodelist *backquote;
566 struct nbinary nbinary;
569 struct nredir nredir;
573 struct nclist nclist;
583 struct nodelist *next;
587 struct backcmd { /* result of evalbackcmd */
588 int fd; /* file descriptor to read from */
589 char *buf; /* buffer */
590 int nleft; /* number of chars in buffer */
591 struct job *jp; /* job structure for command */
599 const struct builtincmd *cmd;
604 struct strlist *next;
610 struct strlist *list;
611 struct strlist **lastp;
615 struct strpush *prev; /* preceding string on stack */
619 struct alias *ap; /* if push was associated with an alias */
621 char *string; /* remember the string since it may change */
625 struct parsefile *prev; /* preceding file on stack */
626 int linno; /* current line */
627 int fd; /* file descriptor (or -1 if string) */
628 int nleft; /* number of chars left in this line */
629 int lleft; /* number of chars left in this buffer */
630 char *nextc; /* next char in buffer */
631 char *buf; /* input buffer */
632 struct strpush *strpush; /* for pushing strings at this level */
633 struct strpush basestrpush; /* so pushing one is fast */
637 struct stack_block *stackp;
640 struct stackmark *marknext;
644 int nparam; /* # of positional parameters (without $0) */
645 unsigned char malloc; /* if parameter list dynamically allocated */
646 char **p; /* parameter list */
647 int optind; /* next parameter to be processed by getopts */
648 int optoff; /* used by getopts */
652 * When commands are first encountered, they are entered in a hash table.
653 * This ensures that a full path search will not have to be done for them
654 * on each invocation.
656 * We should investigate converting to a linear search, even though that
657 * would make the command name "hash" a misnomer.
659 #define CMDTABLESIZE 31 /* should be prime */
660 #define ARB 1 /* actual size determined at run time */
665 struct tblentry *next; /* next entry in hash chain */
666 union param param; /* definition of builtin function */
667 short cmdtype; /* index identifying command */
668 char rehash; /* if set, cd done since entry created */
669 char cmdname[ARB]; /* name of command */
673 static struct tblentry *cmdtable[CMDTABLESIZE];
674 static int builtinloc = -1; /* index in path of %builtin, or -1 */
675 static int exerrno = 0; /* Last exec error */
678 static void tryexec (char *, char **, char **);
679 static void printentry (struct tblentry *, int);
680 static void clearcmdentry (int);
681 static struct tblentry *cmdlookup (const char *, int);
682 static void delete_cmd_entry (void);
683 static int path_change (const char *, int *);
686 static void flushall (void);
687 static void out2fmt (const char *, ...)
688 __attribute__((__format__(__printf__,1,2)));
689 static int xwrite (int, const char *, int);
691 static void outstr (const char *p, FILE *file) { fputs(p, file); }
692 static void out1str(const char *p) { outstr(p, stdout); }
693 static void out2str(const char *p) { outstr(p, stderr); }
695 #ifndef ASH_OPTIMIZE_FOR_SIZE
696 #define out2c(c) putc((c), stderr)
698 static void out2c(int c) { putc(c, stderr); }
701 /* syntax table used when not in quotes */
702 static const char basesyntax[257] = {
703 CENDFILE, CSPCL, CWORD, CCTL,
704 CCTL, CCTL, CCTL, CCTL,
705 CCTL, CCTL, CCTL, CWORD,
706 CWORD, CWORD, CWORD, CWORD,
707 CWORD, CWORD, CWORD, CWORD,
708 CWORD, CWORD, CWORD, CWORD,
709 CWORD, CWORD, CWORD, CWORD,
710 CWORD, CWORD, CWORD, CWORD,
711 CWORD, CWORD, CWORD, CWORD,
712 CWORD, CWORD, CWORD, CWORD,
713 CWORD, CWORD, CWORD, CWORD,
714 CWORD, CWORD, CWORD, CWORD,
715 CWORD, CWORD, CWORD, CWORD,
716 CWORD, CWORD, CWORD, CWORD,
717 CWORD, CWORD, CWORD, CWORD,
718 CWORD, CWORD, CWORD, CWORD,
719 CWORD, CWORD, CWORD, CWORD,
720 CWORD, CWORD, CWORD, CWORD,
721 CWORD, CWORD, CWORD, CWORD,
722 CWORD, CWORD, CWORD, CWORD,
723 CWORD, CWORD, CWORD, CWORD,
724 CWORD, CWORD, CWORD, CWORD,
725 CWORD, CWORD, CWORD, CWORD,
726 CWORD, CWORD, CWORD, CWORD,
727 CWORD, CWORD, CWORD, CWORD,
728 CWORD, CWORD, CWORD, CWORD,
729 CWORD, CWORD, CWORD, CWORD,
730 CWORD, CWORD, CWORD, CWORD,
731 CWORD, CWORD, CWORD, CWORD,
732 CWORD, CWORD, CWORD, CWORD,
733 CWORD, CWORD, CWORD, CWORD,
734 CWORD, CWORD, CWORD, CWORD,
735 CWORD, CWORD, CWORD, CWORD,
736 CWORD, CWORD, CWORD, CWORD,
737 CWORD, CWORD, CWORD, CSPCL,
738 CNL, CWORD, CWORD, CWORD,
739 CWORD, CWORD, CWORD, CWORD,
740 CWORD, CWORD, CWORD, CWORD,
741 CWORD, CWORD, CWORD, CWORD,
742 CWORD, CWORD, CWORD, CWORD,
743 CWORD, CWORD, CSPCL, CWORD,
744 CDQUOTE, CWORD, CVAR, CWORD,
745 CSPCL, CSQUOTE, CSPCL, CSPCL,
746 CWORD, CWORD, CWORD, CWORD,
747 CWORD, CWORD, CWORD, CWORD,
748 CWORD, CWORD, CWORD, CWORD,
749 CWORD, CWORD, CWORD, CWORD,
750 CWORD, CSPCL, CSPCL, CWORD,
751 CSPCL, CWORD, CWORD, CWORD,
752 CWORD, CWORD, CWORD, CWORD,
753 CWORD, CWORD, CWORD, CWORD,
754 CWORD, CWORD, CWORD, CWORD,
755 CWORD, CWORD, CWORD, CWORD,
756 CWORD, CWORD, CWORD, CWORD,
757 CWORD, CWORD, CWORD, CWORD,
758 CWORD, CWORD, CBACK, CWORD,
759 CWORD, CWORD, CBQUOTE, CWORD,
760 CWORD, CWORD, CWORD, CWORD,
761 CWORD, CWORD, CWORD, CWORD,
762 CWORD, CWORD, CWORD, CWORD,
763 CWORD, CWORD, CWORD, CWORD,
764 CWORD, CWORD, CWORD, CWORD,
765 CWORD, CWORD, CWORD, CWORD,
766 CWORD, CWORD, CSPCL, CENDVAR,
770 /* syntax table used when in double quotes */
771 static const char dqsyntax[257] = {
772 CENDFILE, CIGN, CWORD, CCTL,
773 CCTL, CCTL, CCTL, CCTL,
774 CCTL, CCTL, CCTL, CWORD,
775 CWORD, CWORD, CWORD, CWORD,
776 CWORD, CWORD, CWORD, CWORD,
777 CWORD, CWORD, CWORD, CWORD,
778 CWORD, CWORD, CWORD, CWORD,
779 CWORD, CWORD, CWORD, CWORD,
780 CWORD, CWORD, CWORD, CWORD,
781 CWORD, CWORD, CWORD, CWORD,
782 CWORD, CWORD, CWORD, CWORD,
783 CWORD, CWORD, CWORD, CWORD,
784 CWORD, CWORD, CWORD, CWORD,
785 CWORD, CWORD, CWORD, CWORD,
786 CWORD, CWORD, CWORD, CWORD,
787 CWORD, CWORD, CWORD, CWORD,
788 CWORD, CWORD, CWORD, CWORD,
789 CWORD, CWORD, CWORD, CWORD,
790 CWORD, CWORD, CWORD, CWORD,
791 CWORD, CWORD, CWORD, CWORD,
792 CWORD, CWORD, CWORD, CWORD,
793 CWORD, CWORD, CWORD, CWORD,
794 CWORD, CWORD, CWORD, CWORD,
795 CWORD, CWORD, CWORD, CWORD,
796 CWORD, CWORD, CWORD, CWORD,
797 CWORD, CWORD, CWORD, CWORD,
798 CWORD, CWORD, CWORD, CWORD,
799 CWORD, CWORD, CWORD, CWORD,
800 CWORD, CWORD, CWORD, CWORD,
801 CWORD, CWORD, CWORD, CWORD,
802 CWORD, CWORD, CWORD, CWORD,
803 CWORD, CWORD, CWORD, CWORD,
804 CWORD, CWORD, CWORD, CWORD,
805 CWORD, CWORD, CWORD, CWORD,
806 CWORD, CWORD, CWORD, CWORD,
807 CNL, CWORD, CWORD, CWORD,
808 CWORD, CWORD, CWORD, CWORD,
809 CWORD, CWORD, CWORD, CWORD,
810 CWORD, CWORD, CWORD, CWORD,
811 CWORD, CWORD, CWORD, CWORD,
812 CWORD, CWORD, CWORD, CCTL,
813 CENDQUOTE,CWORD, CVAR, CWORD,
814 CWORD, CWORD, CWORD, CWORD,
815 CCTL, CWORD, CWORD, CCTL,
816 CWORD, CCTL, CWORD, CWORD,
817 CWORD, CWORD, CWORD, CWORD,
818 CWORD, CWORD, CWORD, CWORD,
819 CCTL, CWORD, CWORD, CCTL,
820 CWORD, CCTL, CWORD, CWORD,
821 CWORD, CWORD, CWORD, CWORD,
822 CWORD, CWORD, CWORD, CWORD,
823 CWORD, CWORD, CWORD, CWORD,
824 CWORD, CWORD, CWORD, CWORD,
825 CWORD, CWORD, CWORD, CWORD,
826 CWORD, CWORD, CWORD, CWORD,
827 CWORD, CCTL, CBACK, CCTL,
828 CWORD, CWORD, CBQUOTE, CWORD,
829 CWORD, CWORD, CWORD, CWORD,
830 CWORD, CWORD, CWORD, CWORD,
831 CWORD, CWORD, CWORD, CWORD,
832 CWORD, CWORD, CWORD, CWORD,
833 CWORD, CWORD, CWORD, CWORD,
834 CWORD, CWORD, CWORD, CWORD,
835 CWORD, CWORD, CWORD, CENDVAR,
839 /* syntax table used when in single quotes */
840 static const char sqsyntax[257] = {
841 CENDFILE, CIGN, CWORD, CCTL,
842 CCTL, CCTL, CCTL, CCTL,
843 CCTL, CCTL, CCTL, CWORD,
844 CWORD, CWORD, CWORD, CWORD,
845 CWORD, CWORD, CWORD, CWORD,
846 CWORD, CWORD, CWORD, CWORD,
847 CWORD, CWORD, CWORD, CWORD,
848 CWORD, CWORD, CWORD, CWORD,
849 CWORD, CWORD, CWORD, CWORD,
850 CWORD, CWORD, CWORD, CWORD,
851 CWORD, CWORD, CWORD, CWORD,
852 CWORD, CWORD, CWORD, CWORD,
853 CWORD, CWORD, CWORD, CWORD,
854 CWORD, CWORD, CWORD, CWORD,
855 CWORD, CWORD, CWORD, CWORD,
856 CWORD, CWORD, CWORD, CWORD,
857 CWORD, CWORD, CWORD, CWORD,
858 CWORD, CWORD, CWORD, CWORD,
859 CWORD, CWORD, CWORD, CWORD,
860 CWORD, CWORD, CWORD, CWORD,
861 CWORD, CWORD, CWORD, CWORD,
862 CWORD, CWORD, CWORD, CWORD,
863 CWORD, CWORD, CWORD, CWORD,
864 CWORD, CWORD, CWORD, CWORD,
865 CWORD, CWORD, CWORD, CWORD,
866 CWORD, CWORD, CWORD, CWORD,
867 CWORD, CWORD, CWORD, CWORD,
868 CWORD, CWORD, CWORD, CWORD,
869 CWORD, CWORD, CWORD, CWORD,
870 CWORD, CWORD, CWORD, CWORD,
871 CWORD, CWORD, CWORD, CWORD,
872 CWORD, CWORD, CWORD, CWORD,
873 CWORD, CWORD, CWORD, CWORD,
874 CWORD, CWORD, CWORD, CWORD,
875 CWORD, CWORD, CWORD, CWORD,
876 CNL, CWORD, CWORD, CWORD,
877 CWORD, CWORD, CWORD, CWORD,
878 CWORD, CWORD, CWORD, CWORD,
879 CWORD, CWORD, CWORD, CWORD,
880 CWORD, CWORD, CWORD, CWORD,
881 CWORD, CWORD, CWORD, CCTL,
882 CWORD, CWORD, CWORD, CWORD,
883 CWORD, CENDQUOTE,CWORD, CWORD,
884 CCTL, CWORD, CWORD, CCTL,
885 CWORD, CCTL, CWORD, CWORD,
886 CWORD, CWORD, CWORD, CWORD,
887 CWORD, CWORD, CWORD, CWORD,
888 CCTL, CWORD, CWORD, CCTL,
889 CWORD, CCTL, CWORD, CWORD,
890 CWORD, CWORD, CWORD, CWORD,
891 CWORD, CWORD, CWORD, CWORD,
892 CWORD, CWORD, CWORD, CWORD,
893 CWORD, CWORD, CWORD, CWORD,
894 CWORD, CWORD, CWORD, CWORD,
895 CWORD, CWORD, CWORD, CWORD,
896 CWORD, CCTL, CCTL, CCTL,
897 CWORD, CWORD, CWORD, CWORD,
898 CWORD, CWORD, CWORD, CWORD,
899 CWORD, CWORD, CWORD, CWORD,
900 CWORD, CWORD, CWORD, CWORD,
901 CWORD, CWORD, CWORD, CWORD,
902 CWORD, CWORD, CWORD, CWORD,
903 CWORD, CWORD, CWORD, CWORD,
904 CWORD, CWORD, CWORD, CWORD,
908 /* syntax table used when in arithmetic */
909 static const char arisyntax[257] = {
910 CENDFILE, CIGN, CWORD, CCTL,
911 CCTL, CCTL, CCTL, CCTL,
912 CCTL, CCTL, CCTL, CWORD,
913 CWORD, CWORD, CWORD, CWORD,
914 CWORD, CWORD, CWORD, CWORD,
915 CWORD, CWORD, CWORD, CWORD,
916 CWORD, CWORD, CWORD, CWORD,
917 CWORD, CWORD, CWORD, CWORD,
918 CWORD, CWORD, CWORD, CWORD,
919 CWORD, CWORD, CWORD, CWORD,
920 CWORD, CWORD, CWORD, CWORD,
921 CWORD, CWORD, CWORD, CWORD,
922 CWORD, CWORD, CWORD, CWORD,
923 CWORD, CWORD, CWORD, CWORD,
924 CWORD, CWORD, CWORD, CWORD,
925 CWORD, CWORD, CWORD, CWORD,
926 CWORD, CWORD, CWORD, CWORD,
927 CWORD, CWORD, CWORD, CWORD,
928 CWORD, CWORD, CWORD, CWORD,
929 CWORD, CWORD, CWORD, CWORD,
930 CWORD, CWORD, CWORD, CWORD,
931 CWORD, CWORD, CWORD, CWORD,
932 CWORD, CWORD, CWORD, CWORD,
933 CWORD, CWORD, CWORD, CWORD,
934 CWORD, CWORD, CWORD, CWORD,
935 CWORD, CWORD, CWORD, CWORD,
936 CWORD, CWORD, CWORD, CWORD,
937 CWORD, CWORD, CWORD, CWORD,
938 CWORD, CWORD, CWORD, CWORD,
939 CWORD, CWORD, CWORD, CWORD,
940 CWORD, CWORD, CWORD, CWORD,
941 CWORD, CWORD, CWORD, CWORD,
942 CWORD, CWORD, CWORD, CWORD,
943 CWORD, CWORD, CWORD, CWORD,
944 CWORD, CWORD, CWORD, CWORD,
945 CNL, CWORD, CWORD, CWORD,
946 CWORD, CWORD, CWORD, CWORD,
947 CWORD, CWORD, CWORD, CWORD,
948 CWORD, CWORD, CWORD, CWORD,
949 CWORD, CWORD, CWORD, CWORD,
950 CWORD, CWORD, CWORD, CWORD,
951 CDQUOTE, CWORD, CVAR, CWORD,
952 CWORD, CSQUOTE, CLP, CRP,
953 CWORD, CWORD, CWORD, CWORD,
954 CWORD, CWORD, CWORD, CWORD,
955 CWORD, CWORD, CWORD, CWORD,
956 CWORD, CWORD, CWORD, CWORD,
957 CWORD, CWORD, CWORD, CWORD,
958 CWORD, CWORD, CWORD, CWORD,
959 CWORD, CWORD, CWORD, CWORD,
960 CWORD, CWORD, CWORD, CWORD,
961 CWORD, CWORD, CWORD, CWORD,
962 CWORD, CWORD, CWORD, CWORD,
963 CWORD, CWORD, CWORD, CWORD,
964 CWORD, CWORD, CWORD, CWORD,
965 CWORD, CWORD, CBACK, CWORD,
966 CWORD, CWORD, CBQUOTE, CWORD,
967 CWORD, CWORD, CWORD, CWORD,
968 CWORD, CWORD, CWORD, CWORD,
969 CWORD, CWORD, CWORD, CWORD,
970 CWORD, CWORD, CWORD, CWORD,
971 CWORD, CWORD, CWORD, CWORD,
972 CWORD, CWORD, CWORD, CWORD,
973 CWORD, CWORD, CWORD, CENDVAR,
977 /* character classification table */
978 static const char is_type[257] = {
1020 0, ISSPECL, ISSPECL, 0,
1022 ISSPECL, 0, 0, ISSPECL,
1023 0, 0, ISDIGIT, ISDIGIT,
1024 ISDIGIT, ISDIGIT, ISDIGIT, ISDIGIT,
1025 ISDIGIT, ISDIGIT, ISDIGIT, ISDIGIT,
1027 0, ISSPECL, ISSPECL, ISUPPER,
1028 ISUPPER, ISUPPER, ISUPPER, ISUPPER,
1029 ISUPPER, ISUPPER, ISUPPER, ISUPPER,
1030 ISUPPER, ISUPPER, ISUPPER, ISUPPER,
1031 ISUPPER, ISUPPER, ISUPPER, ISUPPER,
1032 ISUPPER, ISUPPER, ISUPPER, ISUPPER,
1033 ISUPPER, ISUPPER, ISUPPER, ISUPPER,
1035 0, ISUNDER, 0, ISLOWER,
1036 ISLOWER, ISLOWER, ISLOWER, ISLOWER,
1037 ISLOWER, ISLOWER, ISLOWER, ISLOWER,
1038 ISLOWER, ISLOWER, ISLOWER, ISLOWER,
1039 ISLOWER, ISLOWER, ISLOWER, ISLOWER,
1040 ISLOWER, ISLOWER, ISLOWER, ISLOWER,
1041 ISLOWER, ISLOWER, ISLOWER, ISLOWER,
1046 /* Array indicating which tokens mark the end of a list */
1047 static const char tokendlist[] = {
1080 static const char *const tokname[] = {
1113 #define KWDOFFSET 14
1115 static const char *const parsekwd[] = {
1135 static int plinno = 1; /* input line number */
1137 static int parselleft; /* copy of parsefile->lleft */
1139 static struct parsefile basepf; /* top level input file */
1140 static char basebuf[BUFSIZ]; /* buffer for top level input file */
1141 static struct parsefile *parsefile = &basepf; /* current input file */
1144 * NEOF is returned by parsecmd when it encounters an end of file. It
1145 * must be distinct from NULL, so we use the address of a variable that
1146 * happens to be handy.
1149 static int tokpushback; /* last token pushed back */
1150 #define NEOF ((union node *)&tokpushback)
1151 static int checkkwd; /* 1 == check for kwds, 2 == also eat newlines */
1154 static void error (const char *, ...) __attribute__((__noreturn__));
1155 static void exerror (int, const char *, ...) __attribute__((__noreturn__));
1156 static void shellexec (char **, char **, const char *, int)
1157 __attribute__((noreturn));
1158 static void exitshell (int) __attribute__((noreturn));
1160 static int goodname(const char *);
1161 static void ignoresig (int);
1162 static void onsig (int);
1163 static void dotrap (void);
1164 static int decode_signal (const char *, int);
1166 static void shprocvar(void);
1167 static void deletefuncs(void);
1168 static void setparam (char **);
1169 static void freeparam (volatile struct shparam *);
1171 /* reasons for skipping commands (see comment on breakcmd routine) */
1177 /* values of cmdtype */
1178 #define CMDUNKNOWN -1 /* no entry in table for command */
1179 #define CMDNORMAL 0 /* command is an executable program */
1180 #define CMDBUILTIN 1 /* command is a shell builtin */
1181 #define CMDFUNCTION 2 /* command is a shell function */
1183 #define DO_ERR 1 /* find_command prints errors */
1184 #define DO_ABS 2 /* find_command checks absolute paths */
1185 #define DO_NOFUN 4 /* find_command ignores functions */
1186 #define DO_BRUTE 8 /* find_command ignores hash table */
1193 #define VEXPORT 0x01 /* variable is exported */
1194 #define VREADONLY 0x02 /* variable cannot be modified */
1195 #define VSTRFIXED 0x04 /* variable struct is staticly allocated */
1196 #define VTEXTFIXED 0x08 /* text is staticly allocated */
1197 #define VSTACK 0x10 /* text is allocated on the stack */
1198 #define VUNSET 0x20 /* the variable is not set */
1199 #define VNOFUNC 0x40 /* don't call the callback function */
1203 struct var *next; /* next entry in hash list */
1204 int flags; /* flags are defined above */
1205 char *text; /* name=value */
1206 void (*func) (const char *);
1207 /* function to be called when */
1208 /* the variable gets set/unset */
1212 struct localvar *next; /* next local variable in list */
1213 struct var *vp; /* the variable that was made local */
1214 int flags; /* saved flags */
1215 char *text; /* saved text */
1219 #if defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN)
1220 #define rmescapes(p) _rmescapes((p), 0)
1221 static char *_rmescapes (char *, int);
1223 static void rmescapes (char *);
1226 static int casematch (union node *, const char *);
1227 static void clearredir(void);
1228 static void popstring(void);
1229 static void readcmdfile (const char *);
1231 static int number (const char *);
1232 static int is_number (const char *, int *num);
1233 static char *single_quote (const char *);
1234 static int nextopt (const char *);
1236 static void redirect (union node *, int);
1237 static void popredir (void);
1238 static int dup_as_newfd (int, int);
1240 static void changepath(const char *newval);
1241 static void getoptsreset(const char *value);
1244 static int parsenleft; /* copy of parsefile->nleft */
1245 static char *parsenextc; /* copy of parsefile->nextc */
1246 static int rootpid; /* pid of main shell */
1247 static int rootshell; /* true if we aren't a child of the main shell */
1249 static const char spcstr[] = " ";
1250 static const char snlfmt[] = "%s\n";
1252 static int sstrnleft;
1253 static int herefd = -1;
1255 static struct localvar *localvars;
1257 static struct var vifs;
1258 static struct var vmail;
1259 static struct var vmpath;
1260 static struct var vpath;
1261 static struct var vps1;
1262 static struct var vps2;
1263 static struct var voptind;
1264 #ifdef BB_LOCALE_SUPPORT
1265 static struct var vlc_all;
1266 static struct var vlc_ctype;
1273 void (*func) (const char *);
1276 static const char defpathvar[] =
1277 "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin";
1278 #define defpath (defpathvar + 5)
1281 static const char defifsvar[] = "IFS= \t\n";
1282 #define defifs (defifsvar + 4)
1284 static const char defifs[] = " \t\n";
1287 static const struct varinit varinit[] = {
1289 { &vifs, VSTRFIXED|VTEXTFIXED, defifsvar,
1291 { &vifs, VSTRFIXED|VTEXTFIXED|VUNSET, "IFS=",
1294 { &vmail, VSTRFIXED|VTEXTFIXED|VUNSET, "MAIL=",
1296 { &vmpath, VSTRFIXED|VTEXTFIXED|VUNSET, "MAILPATH=",
1298 { &vpath, VSTRFIXED|VTEXTFIXED, defpathvar,
1301 * vps1 depends on uid
1303 { &vps2, VSTRFIXED|VTEXTFIXED, "PS2=> ",
1305 { &voptind, VSTRFIXED|VTEXTFIXED, "OPTIND=1",
1307 #ifdef BB_LOCALE_SUPPORT
1308 { &vlc_all, VSTRFIXED|VTEXTFIXED|VUNSET, "LC_ALL=",
1310 { &vlc_ctype, VSTRFIXED|VTEXTFIXED|VUNSET, "LC_CTYPE=",
1319 static struct var *vartab[VTABSIZE];
1322 * The following macros access the values of the above variables.
1323 * They have to skip over the name. They return the null string
1324 * for unset variables.
1327 #define ifsval() (vifs.text + 4)
1328 #define ifsset() ((vifs.flags & VUNSET) == 0)
1329 #define mailval() (vmail.text + 5)
1330 #define mpathval() (vmpath.text + 9)
1331 #define pathval() (vpath.text + 5)
1332 #define ps1val() (vps1.text + 4)
1333 #define ps2val() (vps2.text + 4)
1334 #define optindval() (voptind.text + 7)
1336 #define mpathset() ((vmpath.flags & VUNSET) == 0)
1338 static void initvar (void);
1339 static void setvar (const char *, const char *, int);
1340 static void setvareq (char *, int);
1341 static void listsetvar (struct strlist *);
1342 static const char *lookupvar (const char *);
1343 static const char *bltinlookup (const char *);
1344 static char **environment (void);
1345 static int showvarscmd (int, char **);
1346 static void mklocal (char *);
1347 static void poplocalvars (void);
1348 static int unsetvar (const char *);
1349 static int varequal (const char *, const char *);
1352 static char *arg0; /* value of $0 */
1353 static struct shparam shellparam; /* current positional parameters */
1354 static char **argptr; /* argument list for builtin commands */
1355 static char *optionarg; /* set by nextopt (like getopt) */
1356 static char *optptr; /* used by nextopt */
1357 static char *minusc; /* argument to -c option */
1362 #define ALIASINUSE 1
1374 static struct alias *atab[ATABSIZE];
1376 static void setalias (char *, char *);
1377 static struct alias **hashalias (const char *);
1378 static struct alias *freealias (struct alias *);
1379 static struct alias **__lookupalias (const char *);
1385 struct alias *ap, **app;
1387 app = __lookupalias(name);
1391 if (!(ap->flag & ALIASINUSE)) {
1394 ap->val = savestr(val);
1395 ap->flag &= ~ALIASDEAD;
1398 ap = ckmalloc(sizeof (struct alias));
1399 ap->name = savestr(name);
1400 ap->val = savestr(val);
1413 app = __lookupalias(name);
1417 *app = freealias(*app);
1428 struct alias *ap, **app;
1432 for (i = 0; i < ATABSIZE; i++) {
1434 for (ap = *app; ap; ap = *app) {
1435 *app = freealias(*app);
1444 static struct alias *
1445 lookupalias(const char *name, int check)
1447 struct alias *ap = *__lookupalias(name);
1449 if (check && ap && (ap->flag & ALIASINUSE))
1455 printalias(const struct alias *ap) {
1458 p = single_quote(ap->val);
1459 printf("alias %s=%s\n", ap->name, p);
1465 * TODO - sort output
1468 aliascmd(int argc, char **argv)
1477 for (i = 0; i < ATABSIZE; i++)
1478 for (ap = atab[i]; ap; ap = ap->next) {
1483 while ((n = *++argv) != NULL) {
1484 if ((v = strchr(n+1, '=')) == NULL) { /* n+1: funny ksh stuff */
1485 if ((ap = *__lookupalias(n)) == NULL) {
1486 out2fmt("%s: %s not found\n", "alias", n);
1501 unaliascmd(int argc, char **argv)
1505 while ((i = nextopt("a")) != '\0') {
1511 for (i = 0; *argptr; argptr++) {
1512 if (unalias(*argptr)) {
1513 out2fmt("%s: %s not found\n", "unalias", *argptr);
1521 static struct alias **
1525 unsigned int hashval;
1530 return &atab[hashval % ATABSIZE];
1533 static struct alias *
1534 freealias(struct alias *ap) {
1537 if (ap->flag & ALIASINUSE) {
1538 ap->flag |= ALIASDEAD;
1550 static struct alias **
1551 __lookupalias(const char *name) {
1552 struct alias **app = hashalias(name);
1554 for (; *app; app = &(*app)->next) {
1555 if (equal(name, (*app)->name)) {
1564 #ifdef ASH_MATH_SUPPORT
1565 /* The generated file arith.c has been snipped. If you want this
1566 * stuff back in, feel free to add it to your own copy. */
1567 #define ARITH_NUM 257
1568 #define ARITH_LPAREN 258
1569 #define ARITH_RPAREN 259
1570 #define ARITH_OR 260
1571 #define ARITH_AND 261
1572 #define ARITH_BOR 262
1573 #define ARITH_BXOR 263
1574 #define ARITH_BAND 264
1575 #define ARITH_EQ 265
1576 #define ARITH_NE 266
1577 #define ARITH_LT 267
1578 #define ARITH_GT 268
1579 #define ARITH_GE 269
1580 #define ARITH_LE 270
1581 #define ARITH_LSHIFT 271
1582 #define ARITH_RSHIFT 272
1583 #define ARITH_ADD 273
1584 #define ARITH_SUB 274
1585 #define ARITH_MUL 275
1586 #define ARITH_DIV 276
1587 #define ARITH_REM 277
1588 #define ARITH_UNARYMINUS 278
1589 #define ARITH_UNARYPLUS 279
1590 #define ARITH_NOT 280
1591 #define ARITH_BNOT 281
1593 static void expari (int);
1595 static int arith (const char *);
1596 static int expcmd (int , char **);
1597 static void arith_lex_reset (void);
1598 static int yylex (void);
1602 static char *trap[NSIG]; /* trap handler commands */
1603 static char sigmode[NSIG - 1]; /* current value of signal */
1604 static char gotsig[NSIG - 1]; /* indicates specified signal received */
1605 static int pendingsigs; /* indicates some signal received */
1608 * This file was generated by the mkbuiltins program.
1612 static int bgcmd (int, char **);
1613 static int fgcmd (int, char **);
1614 static int killcmd (int, char **);
1616 static int bltincmd (int, char **);
1617 static int cdcmd (int, char **);
1618 static int breakcmd (int, char **);
1620 static int commandcmd (int, char **);
1622 static int dotcmd (int, char **);
1623 static int evalcmd (int, char **);
1624 static int execcmd (int, char **);
1625 static int exitcmd (int, char **);
1626 static int exportcmd (int, char **);
1627 static int histcmd (int, char **);
1628 static int hashcmd (int, char **);
1629 static int helpcmd (int, char **);
1630 static int jobscmd (int, char **);
1631 static int localcmd (int, char **);
1633 static int pwdcmd (int, char **);
1635 static int readcmd (int, char **);
1636 static int returncmd (int, char **);
1637 static int setcmd (int, char **);
1638 static int setvarcmd (int, char **);
1639 static int shiftcmd (int, char **);
1640 static int trapcmd (int, char **);
1641 static int umaskcmd (int, char **);
1643 static int aliascmd (int, char **);
1644 static int unaliascmd (int, char **);
1646 static int unsetcmd (int, char **);
1647 static int waitcmd (int, char **);
1648 static int ulimitcmd (int, char **);
1649 static int timescmd (int, char **);
1650 #ifdef ASH_MATH_SUPPORT
1651 static int expcmd (int, char **);
1653 static int typecmd (int, char **);
1655 static int getoptscmd (int, char **);
1658 #ifndef BB_TRUE_FALSE
1659 static int true_main (int, char **);
1660 static int false_main (int, char **);
1663 static void setpwd (const char *, int);
1666 #define BUILTIN_NOSPEC "0"
1667 #define BUILTIN_SPECIAL "1"
1668 #define BUILTIN_REGULAR "2"
1669 #define BUILTIN_ASSIGN "4"
1670 #define BUILTIN_SPEC_ASSG "5"
1671 #define BUILTIN_REG_ASSG "6"
1673 #define IS_BUILTIN_SPECIAL(builtincmd) ((builtincmd)->name[0] & 1)
1674 #define IS_BUILTIN_REGULAR(builtincmd) ((builtincmd)->name[0] & 2)
1675 #define IS_BUILTIN_ASSIGN(builtincmd) ((builtincmd)->name[0] & 4)
1679 int (*const builtinfunc) (int, char **);
1684 /* It is CRUCIAL that this listing be kept in ascii order, otherwise
1685 * the binary search in find_builtin() will stop working. If you value
1686 * your kneecaps, you'll be sure to *make sure* that any changes made
1687 * to this array result in the listing remaining in ascii order. You
1690 static const struct builtincmd builtincmds[] = {
1691 { BUILTIN_SPECIAL ".", dotcmd }, /* first, see declare DOTCMD */
1692 { BUILTIN_SPECIAL ":", true_main },
1694 { BUILTIN_REG_ASSG "alias", aliascmd },
1697 { BUILTIN_REGULAR "bg", bgcmd },
1699 { BUILTIN_SPECIAL "break", breakcmd },
1700 { BUILTIN_SPECIAL "builtin", bltincmd },
1701 { BUILTIN_REGULAR "cd", cdcmd },
1702 { BUILTIN_NOSPEC "chdir", cdcmd },
1704 { BUILTIN_REGULAR "command", commandcmd },
1706 { BUILTIN_SPECIAL "continue", breakcmd },
1707 { BUILTIN_SPECIAL "eval", evalcmd },
1708 { BUILTIN_SPECIAL "exec", execcmd },
1709 { BUILTIN_SPECIAL "exit", exitcmd },
1710 #ifdef ASH_MATH_SUPPORT
1711 { BUILTIN_NOSPEC "exp", expcmd },
1713 { BUILTIN_SPEC_ASSG "export", exportcmd },
1714 { BUILTIN_REGULAR "false", false_main },
1715 { BUILTIN_REGULAR "fc", histcmd },
1717 { BUILTIN_REGULAR "fg", fgcmd },
1720 { BUILTIN_REGULAR "getopts", getoptscmd },
1722 { BUILTIN_NOSPEC "hash", hashcmd },
1723 { BUILTIN_NOSPEC "help", helpcmd },
1724 { BUILTIN_REGULAR "jobs", jobscmd },
1726 { BUILTIN_REGULAR "kill", killcmd },
1728 #ifdef ASH_MATH_SUPPORT
1729 { BUILTIN_NOSPEC "let", expcmd },
1731 { BUILTIN_ASSIGN "local", localcmd },
1733 { BUILTIN_NOSPEC "pwd", pwdcmd },
1735 { BUILTIN_REGULAR "read", readcmd },
1736 { BUILTIN_SPEC_ASSG "readonly", exportcmd },
1737 { BUILTIN_SPECIAL "return", returncmd },
1738 { BUILTIN_SPECIAL "set", setcmd },
1739 { BUILTIN_NOSPEC "setvar", setvarcmd },
1740 { BUILTIN_SPECIAL "shift", shiftcmd },
1741 { BUILTIN_SPECIAL "times", timescmd },
1742 { BUILTIN_SPECIAL "trap", trapcmd },
1743 { BUILTIN_REGULAR "true", true_main },
1744 { BUILTIN_NOSPEC "type", typecmd },
1745 { BUILTIN_NOSPEC "ulimit", ulimitcmd },
1746 { BUILTIN_REGULAR "umask", umaskcmd },
1748 { BUILTIN_REGULAR "unalias", unaliascmd },
1750 { BUILTIN_SPECIAL "unset", unsetcmd },
1751 { BUILTIN_REGULAR "wait", waitcmd },
1753 #define NUMBUILTINS (sizeof (builtincmds) / sizeof (struct builtincmd) )
1755 static const struct builtincmd *DOTCMD = &builtincmds[0];
1756 static struct builtincmd *BLTINCMD;
1757 static struct builtincmd *EXECCMD;
1758 static struct builtincmd *EVALCMD;
1761 #define JOBSTOPPED 1 /* all procs are stopped */
1762 #define JOBDONE 2 /* all procs are completed */
1765 * A job structure contains information about a job. A job is either a
1766 * single process or a set of processes contained in a pipeline. In the
1767 * latter case, pidlist will be non-NULL, and will point to a -1 terminated
1772 pid_t pid; /* process id */
1773 int status; /* status flags (defined above) */
1774 char *cmd; /* text of command being run */
1778 static int job_warning; /* user was warned about stopped jobs */
1781 static void setjobctl(int enable);
1783 #define setjobctl(on) /* do nothing */
1788 struct procstat ps0; /* status of process */
1789 struct procstat *ps; /* status or processes when more than one */
1790 short nprocs; /* number of processes */
1791 short pgrp; /* process group of this job */
1792 char state; /* true if job is finished */
1793 char used; /* true if this entry is in used */
1794 char changed; /* true if status has changed */
1796 char jobctl; /* job running under job control */
1800 static struct job *jobtab; /* array of jobs */
1801 static int njobs; /* size of array */
1802 static int backgndpid = -1; /* pid of last background process */
1804 static int initialpgrp; /* pgrp of shell on invocation */
1805 static int curjob; /* current job */
1808 static int intreceived;
1810 static struct job *makejob (const union node *, int);
1811 static int forkshell (struct job *, const union node *, int);
1812 static int waitforjob (struct job *);
1814 static int docd (char *, int);
1815 static char *getcomponent (void);
1816 static void updatepwd (const char *);
1817 static void getpwd (void);
1819 static char *padvance (const char **, const char *);
1821 static char nullstr[1]; /* zero length string */
1822 static char *curdir = nullstr; /* current working directory */
1823 static char *cdcomppath;
1837 if ((dest = *argptr) == NULL && (dest = bltinlookup("HOME")) == NULL)
1838 error("HOME not set");
1841 if (dest[0] == '-' && dest[1] == '\0') {
1842 dest = bltinlookup("OLDPWD");
1843 if (!dest || !*dest) {
1852 if (*dest == '/' || (path = bltinlookup("CDPATH")) == NULL)
1854 while ((p = padvance(&path, dest)) != NULL) {
1855 if (stat(p, &statb) >= 0 && S_ISDIR(statb.st_mode)) {
1860 if (p[0] == '.' && p[1] == '/' && p[2] != '\0')
1862 print = strcmp(p, dest);
1864 if (docd(p, print) >= 0)
1869 error("can't cd to %s", dest);
1875 * Actually do the chdir. In an interactive shell, print the
1876 * directory name if "print" is nonzero.
1891 TRACE(("docd(\"%s\", %d) called\n", dest, print));
1894 * Check each component of the path. If we find a symlink or
1895 * something we can't stat, clear curdir to force a getcwd()
1896 * next time we get the value of the current directory.
1899 cdcomppath = sstrdup(dest);
1906 while ((q = getcomponent()) != NULL) {
1907 if (q[0] == '\0' || (q[0] == '.' && q[1] == '\0'))
1915 if (equal(component, ".."))
1918 if ((lstat(stackblock(), &statb) < 0)
1919 || (S_ISLNK(statb.st_mode))) {
1927 if (chdir(dest) < 0) {
1931 updatepwd(badstat ? NULL : dest);
1934 printf(snlfmt, curdir);
1940 * Get the next component of the path name pointed to by cdcomppath.
1941 * This routine overwrites the string pointed to by cdcomppath.
1949 if ((p = cdcomppath) == NULL)
1952 while (*p != '/' && *p != '\0')
1966 * Update curdir (the name of the current directory) in response to a
1967 * cd command. We also call hashcd to let the routines in exec.c know
1968 * that the current directory has changed.
1971 static void hashcd (void);
1974 updatepwd(const char *dir)
1980 hashcd(); /* update command hash table */
1983 * If our argument is NULL, we don't know the current directory
1984 * any more because we traversed a symbolic link or something
1985 * we couldn't stat().
1987 if (dir == NULL || curdir == nullstr) {
1992 cdcomppath = sstrdup(dir);
2001 while ((p = getcomponent()) != NULL) {
2002 if (equal(p, "..")) {
2003 while (new > stackblock() && (STUNPUTC(new), *new) != '/');
2004 } else if (*p != '\0' && ! equal(p, ".")) {
2010 if (new == stackblock())
2013 setpwd(stackblock(), 1);
2023 printf(snlfmt, curdir);
2029 * Find out what the current directory is. If we already know the current
2030 * directory, this routine returns immediately.
2035 curdir = xgetcwd(0);
2041 setpwd(const char *val, int setold)
2044 setvar("OLDPWD", curdir, VEXPORT);
2047 if (curdir != nullstr) {
2054 curdir = savestr(val);
2057 setvar("PWD", curdir, VEXPORT);
2061 * Errors and exceptions.
2065 * Code to handle exceptions in C.
2069 * We enclose jmp_buf in a structure so that we can declare pointers to
2070 * jump locations. The global variable handler contains the location to
2071 * jump to when an exception occurs, and the global variable exception
2072 * contains a code identifying the exeception. To implement nested
2073 * exception handlers, the user should save the value of handler on entry
2074 * to an inner scope, set handler to point to a jmploc structure for the
2075 * inner scope, and restore handler on exit from the scope.
2083 #define EXINT 0 /* SIGINT received */
2084 #define EXERROR 1 /* a generic error */
2085 #define EXSHELLPROC 2 /* execute a shell procedure */
2086 #define EXEXEC 3 /* command execution failed */
2088 static struct jmploc *handler;
2089 static int exception;
2091 static void exverror (int, const char *, va_list)
2092 __attribute__((__noreturn__));
2095 * Called to raise an exception. Since C doesn't include exceptions, we
2096 * just do a longjmp to the exception handler. The type of exception is
2097 * stored in the global variable "exception".
2100 static void exraise (int) __attribute__((__noreturn__));
2106 if (handler == NULL)
2111 longjmp(handler->loc, 1);
2116 * Called from trap.c when a SIGINT is received. (If the user specifies
2117 * that SIGINT is to be trapped or ignored using the trap builtin, then
2118 * this routine is not called.) Suppressint is nonzero when interrupts
2119 * are held using the INTOFF macro. The call to _exit is necessary because
2120 * there is a short period after a fork before the signal handlers are
2121 * set to the appropriate value for the child. (The test for iflag is
2122 * just defensive programming.)
2134 sigemptyset(&mysigset);
2135 sigprocmask(SIG_SETMASK, &mysigset, NULL);
2136 if (rootshell && iflag)
2139 signal(SIGINT, SIG_DFL);
2146 static char *commandname; /* currently executing command */
2149 * Exverror is called to raise the error exception. If the first argument
2150 * is not NULL then error prints an error message using printf style
2151 * formatting. It then raises the error exception.
2154 exverror(int cond, const char *msg, va_list ap)
2161 TRACE(("exverror(%d, \"%s\") pid=%d\n", cond, msg, getpid()));
2163 TRACE(("exverror(%d, NULL) pid=%d\n", cond, getpid()));
2167 out2fmt("%s: ", commandname);
2168 vfprintf(stderr, msg, ap);
2178 error(const char *msg, ...)
2193 msg = va_arg(ap, const char *);
2195 exverror(EXERROR, msg, ap);
2203 exerror(int cond, const char *msg, ...)
2219 cond = va_arg(ap, int);
2220 msg = va_arg(ap, const char *);
2222 exverror(cond, msg, ap);
2230 * Table of error messages.
2234 short errcode; /* error number */
2235 char action; /* operation which encountered the error */
2239 * Types of operations (passed to the errmsg routine).
2242 #define E_OPEN 01 /* opening a file */
2243 #define E_CREAT 02 /* creating a file */
2244 #define E_EXEC 04 /* executing a program */
2246 #define ALL (E_OPEN|E_CREAT|E_EXEC)
2248 static const struct errname errormsg[] = {
2253 { ENOENT, E_CREAT },
2255 { ENOTDIR, E_OPEN },
2256 { ENOTDIR, E_CREAT },
2257 { ENOTDIR, E_EXEC },
2259 { EEXIST, E_CREAT },
2298 { ELIBACC, E_EXEC },
2302 #define ERRNAME_SIZE (sizeof(errormsg)/sizeof(struct errname))
2305 * Return a string describing an error. The returned string may be a
2306 * pointer to a static buffer that will be overwritten on the next call.
2307 * Action describes the operation that got the error.
2311 errmsg(int e, int action)
2313 struct errname const *ep;
2314 static char buf[12];
2316 for (ep = errormsg ; ep < errormsg+ERRNAME_SIZE; ep++) {
2317 if (ep->errcode == e && (ep->action & action) != 0)
2321 snprintf(buf, sizeof buf, "error %d", e);
2326 #ifdef ASH_OPTIMIZE_FOR_SIZE
2329 if (--suppressint == 0 && intpending) {
2333 static void forceinton (void) {
2340 /* flags in argument to evaltree */
2341 #define EV_EXIT 01 /* exit after evaluating tree */
2342 #define EV_TESTED 02 /* exit status is checked; ignore -e flag */
2343 #define EV_BACKCMD 04 /* command executing within back quotes */
2345 static int evalskip; /* set if we are skipping commands */
2346 static int skipcount; /* number of levels to skip */
2347 static int loopnest; /* current loop nesting level */
2348 static int funcnest; /* depth of function calls */
2351 static struct strlist *cmdenviron; /* environment for builtin command */
2352 static int exitstatus; /* exit status of last command */
2353 static int oexitstatus; /* saved exit status */
2355 static void evalsubshell (const union node *, int);
2356 static void expredir (union node *);
2357 static void prehash (union node *);
2358 static void eprintlist (struct strlist *);
2360 static union node *parsecmd(int);
2362 * Called to reset things after an exception.
2366 * The eval commmand.
2368 static void evalstring (char *, int);
2382 STARTSTACKSTR(concat);
2386 STPUTC(*p++, concat);
2387 if ((p = *ap++) == NULL)
2389 STPUTC(' ', concat);
2391 STPUTC('\0', concat);
2392 p = grabstackstr(concat);
2394 evalstring(p, EV_TESTED);
2400 * Execute a command or commands contained in a string.
2403 static void evaltree (union node *, int);
2404 static void setinputstring (char *);
2405 static void popfile (void);
2406 static void setstackmark(struct stackmark *mark);
2407 static void popstackmark(struct stackmark *mark);
2411 evalstring(char *s, int flag)
2414 struct stackmark smark;
2416 setstackmark(&smark);
2418 while ((n = parsecmd(0)) != NEOF) {
2420 popstackmark(&smark);
2423 popstackmark(&smark);
2426 static struct builtincmd *find_builtin (const char *);
2427 static void expandarg (union node *, struct arglist *, int);
2428 static void calcsize (const union node *);
2429 static union node *copynode (const union node *);
2432 * Make a copy of a parse tree.
2435 static int funcblocksize; /* size of structures in function */
2436 static int funcstringsize; /* size of strings in node */
2437 static pointer funcblock; /* block to allocate function from */
2438 static char *funcstring; /* block to allocate strings from */
2441 static inline union node *
2442 copyfunc(union node *n)
2449 funcblock = ckmalloc(funcblocksize + funcstringsize);
2450 funcstring = (char *) funcblock + funcblocksize;
2455 * Free a parse tree.
2459 freefunc(union node *n)
2467 * Add a new command entry, replacing any existing command entry for
2472 addcmdentry(char *name, struct cmdentry *entry)
2474 struct tblentry *cmdp;
2477 cmdp = cmdlookup(name, 1);
2478 if (cmdp->cmdtype == CMDFUNCTION) {
2479 freefunc(cmdp->param.func);
2481 cmdp->cmdtype = entry->cmdtype;
2482 cmdp->param = entry->u;
2487 evalloop(const union node *n, int flags)
2494 evaltree(n->nbinary.ch1, EV_TESTED);
2496 skipping: if (evalskip == SKIPCONT && --skipcount <= 0) {
2500 if (evalskip == SKIPBREAK && --skipcount <= 0)
2504 if (n->type == NWHILE) {
2505 if (exitstatus != 0)
2508 if (exitstatus == 0)
2511 evaltree(n->nbinary.ch2, flags & EV_TESTED);
2512 status = exitstatus;
2517 exitstatus = status;
2521 evalfor(const union node *n, int flags)
2523 struct arglist arglist;
2526 struct stackmark smark;
2528 setstackmark(&smark);
2529 arglist.lastp = &arglist.list;
2530 for (argp = n->nfor.args ; argp ; argp = argp->narg.next) {
2531 oexitstatus = exitstatus;
2532 expandarg(argp, &arglist, EXP_FULL | EXP_TILDE | EXP_RECORD);
2536 *arglist.lastp = NULL;
2540 for (sp = arglist.list ; sp ; sp = sp->next) {
2541 setvar(n->nfor.var, sp->text, 0);
2542 evaltree(n->nfor.body, flags & EV_TESTED);
2544 if (evalskip == SKIPCONT && --skipcount <= 0) {
2548 if (evalskip == SKIPBREAK && --skipcount <= 0)
2555 popstackmark(&smark);
2559 evalcase(const union node *n, int flags)
2563 struct arglist arglist;
2564 struct stackmark smark;
2566 setstackmark(&smark);
2567 arglist.lastp = &arglist.list;
2568 oexitstatus = exitstatus;
2569 expandarg(n->ncase.expr, &arglist, EXP_TILDE);
2570 for (cp = n->ncase.cases ; cp && evalskip == 0 ; cp = cp->nclist.next) {
2571 for (patp = cp->nclist.pattern ; patp ; patp = patp->narg.next) {
2572 if (casematch(patp, arglist.list->text)) {
2573 if (evalskip == 0) {
2574 evaltree(cp->nclist.body, flags);
2581 popstackmark(&smark);
2585 * Evaluate a pipeline. All the processes in the pipeline are children
2586 * of the process creating the pipeline. (This differs from some versions
2587 * of the shell, which make the last process in a pipeline the parent
2596 struct nodelist *lp;
2601 TRACE(("evalpipe(0x%lx) called\n", (long)n));
2603 for (lp = n->npipe.cmdlist ; lp ; lp = lp->next)
2606 jp = makejob(n, pipelen);
2608 for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
2612 if (pipe(pip) < 0) {
2614 error("Pipe call failed");
2617 if (forkshell(jp, lp->n, n->npipe.backgnd) == 0) {
2621 dup_as_newfd(prevfd, 0);
2633 dup_as_newfd(pip[1], 1);
2637 evaltree(lp->n, EV_EXIT);
2645 if (n->npipe.backgnd == 0) {
2647 exitstatus = waitforjob(jp);
2648 TRACE(("evalpipe: job done exit status %d\n", exitstatus));
2653 static void find_command (const char *, struct cmdentry *, int, const char *);
2656 isassignment(const char *word) {
2657 if (!is_name(*word)) {
2662 } while (is_in_name(*word));
2663 return *word == '=';
2668 evalcommand(union node *cmd, int flags)
2670 struct stackmark smark;
2672 struct arglist arglist;
2673 struct arglist varlist;
2679 struct cmdentry cmdentry;
2681 char *volatile savecmdname;
2682 volatile struct shparam saveparam;
2683 struct localvar *volatile savelocalvars;
2687 const struct builtincmd *firstbltin;
2688 struct jmploc *volatile savehandler;
2689 struct jmploc jmploc;
2691 /* Avoid longjmp clobbering */
2698 /* First expand the arguments. */
2699 TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags));
2700 setstackmark(&smark);
2701 arglist.lastp = &arglist.list;
2702 varlist.lastp = &varlist.list;
2704 oexitstatus = exitstatus;
2707 for (argp = cmd->ncmd.assign; argp; argp = argp->narg.next) {
2708 expandarg(argp, &varlist, EXP_VARTILDE);
2711 argp = cmd->ncmd.args; argp && !arglist.list;
2712 argp = argp->narg.next
2714 expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
2717 struct builtincmd *bcmd;
2719 bcmd = find_builtin(arglist.list->text);
2720 pseudovarflag = bcmd && IS_BUILTIN_ASSIGN(bcmd);
2721 for (; argp; argp = argp->narg.next) {
2722 if (pseudovarflag && isassignment(argp->narg.text)) {
2723 expandarg(argp, &arglist, EXP_VARTILDE);
2726 expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
2729 *arglist.lastp = NULL;
2730 *varlist.lastp = NULL;
2731 expredir(cmd->ncmd.redirect);
2733 for (sp = arglist.list ; sp ; sp = sp->next)
2735 argv = stalloc(sizeof (char *) * (argc + 1));
2737 for (sp = arglist.list ; sp ; sp = sp->next) {
2738 TRACE(("evalcommand arg: %s\n", sp->text));
2743 if (iflag && funcnest == 0 && argc > 0)
2747 /* Print the command if xflag is set. */
2750 eprintlist(varlist.list);
2751 eprintlist(arglist.list);
2755 /* Now locate the command. */
2757 cmdentry.cmdtype = CMDBUILTIN;
2758 firstbltin = cmdentry.u.cmd = BLTINCMD;
2760 const char *oldpath;
2761 int findflag = DO_ERR;
2765 * Modify the command lookup path, if a PATH= assignment
2768 for (sp = varlist.list ; sp ; sp = sp->next)
2769 if (varequal(sp->text, defpathvar)) {
2770 path = sp->text + 5;
2771 findflag |= DO_BRUTE;
2774 oldfindflag = findflag;
2777 find_command(argv[0], &cmdentry, findflag, path);
2778 if (cmdentry.cmdtype == CMDUNKNOWN) { /* command not found */
2782 /* implement bltin and command here */
2783 if (cmdentry.cmdtype != CMDBUILTIN) {
2787 firstbltin = cmdentry.u.cmd;
2789 if (cmdentry.u.cmd == BLTINCMD) {
2791 struct builtincmd *bcmd;
2796 if (!(bcmd = find_builtin(*argv))) {
2797 out2fmt("%s: not found\n", *argv);
2801 cmdentry.u.cmd = bcmd;
2802 if (bcmd != BLTINCMD)
2806 if (cmdentry.u.cmd == find_builtin("command")) {
2811 if (*argv[0] == '-') {
2812 if (!equal(argv[0], "-p")) {
2822 findflag |= DO_BRUTE;
2825 findflag = oldfindflag;
2827 findflag |= DO_NOFUN;
2835 /* Fork off a child process if necessary. */
2836 if (cmd->ncmd.backgnd
2837 || (cmdentry.cmdtype == CMDNORMAL && (flags & EV_EXIT) == 0)
2839 jp = makejob(cmd, 1);
2840 mode = cmd->ncmd.backgnd;
2841 if (forkshell(jp, cmd, mode) != 0)
2842 goto parent; /* at end of routine */
2846 /* This is the child process if a fork occurred. */
2847 /* Execute the command. */
2848 if (cmdentry.cmdtype == CMDFUNCTION) {
2850 trputs("Shell function: "); trargs(argv);
2852 exitstatus = oexitstatus;
2853 redirect(cmd->ncmd.redirect, REDIR_PUSH);
2854 saveparam = shellparam;
2855 shellparam.malloc = 0;
2856 shellparam.nparam = argc - 1;
2857 shellparam.p = argv + 1;
2859 savelocalvars = localvars;
2862 if (setjmp(jmploc.loc)) {
2863 if (exception == EXSHELLPROC) {
2864 freeparam((volatile struct shparam *)
2867 saveparam.optind = shellparam.optind;
2868 saveparam.optoff = shellparam.optoff;
2869 freeparam(&shellparam);
2870 shellparam = saveparam;
2873 localvars = savelocalvars;
2874 handler = savehandler;
2875 longjmp(handler->loc, 1);
2877 savehandler = handler;
2879 for (sp = varlist.list ; sp ; sp = sp->next)
2882 evaltree(cmdentry.u.func, flags & EV_TESTED);
2886 localvars = savelocalvars;
2887 saveparam.optind = shellparam.optind;
2888 saveparam.optoff = shellparam.optoff;
2889 freeparam(&shellparam);
2890 shellparam = saveparam;
2891 handler = savehandler;
2894 if (evalskip == SKIPFUNC) {
2898 if (flags & EV_EXIT)
2899 exitshell(exitstatus);
2900 } else if (cmdentry.cmdtype == CMDBUILTIN) {
2902 trputs("builtin command: "); trargs(argv);
2904 mode = (cmdentry.u.cmd == EXECCMD)? 0 : REDIR_PUSH;
2905 redirect(cmd->ncmd.redirect, mode);
2906 savecmdname = commandname;
2907 if (IS_BUILTIN_SPECIAL(firstbltin)) {
2908 listsetvar(varlist.list);
2910 cmdenviron = varlist.list;
2913 if (setjmp(jmploc.loc)) {
2915 exitstatus = (e == EXINT)? SIGINT+128 : 2;
2918 savehandler = handler;
2920 commandname = argv[0];
2922 optptr = NULL; /* initialize nextopt */
2923 exitstatus = (*cmdentry.u.cmd->builtinfunc)(argc, argv);
2927 if (e != EXSHELLPROC) {
2928 commandname = savecmdname;
2929 if (flags & EV_EXIT)
2930 exitshell(exitstatus);
2932 handler = savehandler;
2934 if ((e != EXERROR && e != EXEXEC)
2935 || cmdentry.u.cmd == BLTINCMD
2936 || cmdentry.u.cmd == DOTCMD
2937 || cmdentry.u.cmd == EVALCMD
2938 || cmdentry.u.cmd == EXECCMD)
2942 if (cmdentry.u.cmd != EXECCMD)
2946 trputs("normal command: "); trargs(argv);
2948 redirect(cmd->ncmd.redirect, 0);
2950 for (sp = varlist.list ; sp ; sp = sp->next)
2951 setvareq(sp->text, VEXPORT|VSTACK);
2952 envp = environment();
2953 shellexec(argv, envp, path, cmdentry.u.index);
2957 parent: /* parent process gets here (if we forked) */
2958 if (mode == 0) { /* argument to fork */
2960 exitstatus = waitforjob(jp);
2966 setvar("_", lastarg, 0);
2967 popstackmark(&smark);
2971 * Evaluate a parse tree. The value is left in the global variable
2981 TRACE(("evaltree(NULL) called\n"));
2984 TRACE(("evaltree(0x%lx: %d) called\n", (long)n, n->type));
2987 evaltree(n->nbinary.ch1, flags & EV_TESTED);
2990 evaltree(n->nbinary.ch2, flags);
2993 evaltree(n->nbinary.ch1, EV_TESTED);
2994 if (evalskip || exitstatus != 0)
2996 evaltree(n->nbinary.ch2, flags);
2999 evaltree(n->nbinary.ch1, EV_TESTED);
3000 if (evalskip || exitstatus == 0)
3002 evaltree(n->nbinary.ch2, flags);
3005 expredir(n->nredir.redirect);
3006 redirect(n->nredir.redirect, REDIR_PUSH);
3007 evaltree(n->nredir.n, flags);
3011 evalsubshell(n, flags);
3014 evalsubshell(n, flags);
3017 evaltree(n->nif.test, EV_TESTED);
3020 if (exitstatus == 0)
3021 evaltree(n->nif.ifpart, flags);
3022 else if (n->nif.elsepart)
3023 evaltree(n->nif.elsepart, flags);
3039 struct builtincmd *bcmd;
3040 struct cmdentry entry;
3042 (bcmd = find_builtin(n->narg.text)) &&
3043 IS_BUILTIN_SPECIAL(bcmd)
3045 out2fmt("%s is a special built-in\n", n->narg.text);
3049 entry.cmdtype = CMDFUNCTION;
3050 entry.u.func = copyfunc(n->narg.next);
3051 addcmdentry(n->narg.text, &entry);
3056 evaltree(n->nnot.com, EV_TESTED);
3057 exitstatus = !exitstatus;
3065 evalcommand(n, flags);
3070 printf("Node type = %d\n", n->type);
3079 (checkexit && eflag && exitstatus && !(flags & EV_TESTED))
3081 exitshell(exitstatus);
3085 * Kick off a subshell to evaluate a tree.
3089 evalsubshell(const union node *n, int flags)
3092 int backgnd = (n->type == NBACKGND);
3094 expredir(n->nredir.redirect);
3096 if (forkshell(jp, n, backgnd) == 0) {
3098 flags &=~ EV_TESTED;
3099 redirect(n->nredir.redirect, 0);
3100 evaltree(n->nredir.n, flags | EV_EXIT); /* never returns */
3104 exitstatus = waitforjob(jp);
3110 * Compute the names of the files in a redirection list.
3113 static void fixredir(union node *n, const char *text, int err);
3116 expredir(union node *n)
3120 for (redir = n ; redir ; redir = redir->nfile.next) {
3122 fn.lastp = &fn.list;
3123 oexitstatus = exitstatus;
3124 switch (redir->type) {
3130 expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR);
3131 redir->nfile.expfname = fn.list->text;
3135 if (redir->ndup.vname) {
3136 expandarg(redir->ndup.vname, &fn, EXP_FULL | EXP_TILDE);
3137 fixredir(redir, fn.list->text, 1);
3146 * Execute a command inside back quotes. If it's a builtin command, we
3147 * want to save its output in a block obtained from malloc. Otherwise
3148 * we fork off a subprocess and get the output of the command via a pipe.
3149 * Should be called with interrupts off.
3153 evalbackcmd(union node *n, struct backcmd *result)
3157 struct stackmark smark; /* unnecessary */
3159 setstackmark(&smark);
3170 error("Pipe call failed");
3172 if (forkshell(jp, n, FORK_NOJOB) == 0) {
3177 dup_as_newfd(pip[1], 1);
3181 evaltree(n, EV_EXIT);
3184 result->fd = pip[0];
3187 popstackmark(&smark);
3188 TRACE(("evalbackcmd done: fd=%d buf=0x%x nleft=%d jp=0x%x\n",
3189 result->fd, result->buf, result->nleft, result->jp));
3194 * Execute a simple command.
3198 * Search for a command. This is called before we fork so that the
3199 * location of the command will be available in the parent as well as
3200 * the child. The check for "goodname" is an overly conservative
3201 * check that the name will not be subject to expansion.
3208 struct cmdentry entry;
3210 if (n->type == NCMD && n->ncmd.args)
3211 if (goodname(n->ncmd.args->narg.text))
3212 find_command(n->ncmd.args->narg.text, &entry, 0,
3218 * Builtin commands. Builtin commands whose functions are closely
3219 * tied to evaluation are implemented here.
3223 * No command given, or a bltin command with no arguments. Set the
3224 * specified variables.
3228 bltincmd(argc, argv)
3233 * Preserve exitstatus of a previous possible redirection
3241 * Handle break and continue commands. Break, continue, and return are
3242 * all handled by setting the evalskip flag. The evaluation routines
3243 * above all check this flag, and if it is set they start skipping
3244 * commands rather than executing them. The variable skipcount is
3245 * the number of loops to break/continue, or the number of function
3246 * levels to return. (The latter is always 1.) It should probably
3247 * be an error to break out of more loops than exist, but it isn't
3248 * in the standard shell so we don't make it one here.
3252 breakcmd(argc, argv)
3256 int n = argc > 1 ? number(argv[1]) : 1;
3261 evalskip = (**argv == 'c')? SKIPCONT : SKIPBREAK;
3269 * The return command.
3273 returncmd(argc, argv)
3277 int ret = argc > 1 ? number(argv[1]) : oexitstatus;
3280 evalskip = SKIPFUNC;
3285 /* Do what ksh does; skip the rest of the file */
3286 evalskip = SKIPFILE;
3293 #ifndef BB_TRUE_FALSE
3295 false_main(argc, argv)
3304 true_main(argc, argv)
3313 * Controls whether the shell is interactive or not.
3316 static void setsignal(int signo);
3317 static void chkmail(int silent);
3321 setinteractive(int on)
3323 static int is_interactive;
3324 static int do_banner=0;
3326 if (on == is_interactive)
3332 is_interactive = on;
3333 if (do_banner==0 && is_interactive) {
3334 /* Looks like they want an interactive shell */
3335 printf( "\n\n" BB_BANNER " Built-in shell (ash)\n");
3336 printf( "Enter 'help' for a list of built-in commands.\n\n");
3344 setinteractive(iflag);
3357 iflag = 0; /* exit on error */
3360 for (sp = cmdenviron; sp ; sp = sp->next)
3361 setvareq(sp->text, VEXPORT|VSTACK);
3362 shellexec(argv + 1, environment(), pathval(), 0);
3368 eprintlist(struct strlist *sp)
3370 for (; sp; sp = sp->next) {
3371 out2fmt(" %s",sp->text);
3376 * Exec a program. Never returns. If you change this routine, you may
3377 * have to change the find_command routine as well.
3380 static const char *pathopt; /* set by padvance */
3383 shellexec(argv, envp, path, idx)
3384 char **argv, **envp;
3391 if (strchr(argv[0], '/') != NULL) {
3392 tryexec(argv[0], argv, envp);
3396 while ((cmdname = padvance(&path, argv[0])) != NULL) {
3397 if (--idx < 0 && pathopt == NULL) {
3398 tryexec(cmdname, argv, envp);
3399 if (errno != ENOENT && errno != ENOTDIR)
3406 /* Map to POSIX errors */
3418 exerror(EXEXEC, "%s: %s", argv[0], errmsg(e, E_EXEC));
3423 * Clear traps on a fork.
3429 for (tp = trap ; tp < &trap[NSIG] ; tp++) {
3430 if (*tp && **tp) { /* trap not NULL or SIG_IGN */
3435 setsignal(tp - trap);
3443 initshellproc(void) {
3469 /* from options.c: */
3473 for (i = 0; i < NOPTS; i++)
3489 for (sm = sigmode ; sm < sigmode + NSIG - 1; sm++) {
3501 static int preadbuffer(void);
3502 static void pushfile (void);
3505 * Read a character from the script, returning PEOF on end of file.
3506 * Nul characters in the input are silently discarded.
3509 #ifndef ASH_OPTIMIZE_FOR_SIZE
3510 #define pgetc_macro() (--parsenleft >= 0? *parsenextc++ : preadbuffer())
3514 return pgetc_macro();
3520 return --parsenleft >= 0? *parsenextc++ : preadbuffer();
3526 return pgetc_macro();
3532 * Undo the last call to pgetc. Only one character may be pushed back.
3533 * PEOF may be pushed back.
3545 struct parsefile *pf = parsefile;
3554 parsefile = pf->prev;
3556 parsenleft = parsefile->nleft;
3557 parselleft = parsefile->lleft;
3558 parsenextc = parsefile->nextc;
3559 plinno = parsefile->linno;
3565 * Return to top level.
3570 while (parsefile != &basepf)
3575 * Close the file(s) that the shell is reading commands from. Called
3576 * after a fork is done.
3582 if (parsefile->fd > 0) {
3583 close(parsefile->fd);
3590 * Like setinputfile, but takes an open file descriptor. Call this with
3595 setinputfd(fd, push)
3598 (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
3604 while (parsefile->strpush)
3608 if (parsefile->buf == NULL)
3609 parsefile->buf = ckmalloc(BUFSIZ);
3610 parselleft = parsenleft = 0;
3616 * Set the input to take input from a file. If push is set, push the
3617 * old input onto the stack first.
3621 setinputfile(const char *fname, int push)
3627 if ((fd = open(fname, O_RDONLY)) < 0)
3628 error("Can't open %s", fname);
3630 myfileno2 = dup_as_newfd(fd, 10);
3633 error("Out of file descriptors");
3636 setinputfd(fd, push);
3642 tryexec(char *cmd, char **argv, char **envp)
3646 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
3650 #ifdef BB_FEATURE_SH_APPLETS_ALWAYS_WIN
3651 name = get_last_path_component(name);
3654 for(argc_l=0;*argv_l!=NULL; argv_l++, argc_l++)
3657 for(argc_l=0;*argv_l!=NULL; argv_l++, argc_l++)
3659 run_applet_by_name(name, argc_l, argv);
3661 execve(cmd, argv, envp);
3666 setinputfile(cmd, 0);
3667 commandname = arg0 = savestr(argv[0]);
3669 exraise(EXSHELLPROC);
3674 static char *commandtext (const union node *);
3677 * Do a path search. The variable path (passed by reference) should be
3678 * set to the start of the path before the first call; padvance will update
3679 * this value as it proceeds. Successive calls to padvance will return
3680 * the possible path expansions in sequence. If an option (indicated by
3681 * a percent sign) appears in the path entry then the global variable
3682 * pathopt will be set to point to it; otherwise pathopt will be set to
3686 static const char *pathopt;
3688 static void growstackblock(void);
3692 padvance(const char **path, const char *name)
3702 for (p = start ; *p && *p != ':' && *p != '%' ; p++);
3703 len = p - start + strlen(name) + 2; /* "2" is for '/' and '\0' */
3704 while (stackblocksize() < len)
3708 memcpy(q, start, p - start);
3716 while (*p && *p != ':') p++;
3722 return stalloc(len);
3726 * Wrapper around strcmp for qsort/bsearch/...
3729 pstrcmp(const void *a, const void *b)
3731 return strcmp((const char *) a, *(const char *const *) b);
3735 * Find a keyword is in a sorted array.
3738 static const char *const *
3739 findkwd(const char *s)
3741 return bsearch(s, parsekwd, sizeof(parsekwd) / sizeof(const char *),
3742 sizeof(const char *), pstrcmp);
3746 /*** Command hashing code ***/
3754 struct tblentry **pp;
3755 struct tblentry *cmdp;
3758 struct cmdentry entry;
3761 const struct alias *ap;
3765 while ((c = nextopt("rvV")) != '\0') {
3769 } else if (c == 'v' || c == 'V') {
3773 if (*argptr == NULL) {
3774 for (pp = cmdtable ; pp < &cmdtable[CMDTABLESIZE] ; pp++) {
3775 for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) {
3776 if (cmdp->cmdtype != CMDBUILTIN) {
3777 printentry(cmdp, verbose);
3784 while ((name = *argptr++) != NULL) {
3785 if ((cmdp = cmdlookup(name, 0)) != NULL
3786 && (cmdp->cmdtype == CMDNORMAL
3787 || (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0)))
3790 /* Then look at the aliases */
3791 if ((ap = lookupalias(name, 0)) != NULL) {
3793 printf("%s is an alias for %s\n", name, ap->val);
3799 /* First look at the keywords */
3800 if (findkwd(name)!=0) {
3802 printf("%s is a shell keyword\n", name);
3804 printf(snlfmt, name);
3808 find_command(name, &entry, DO_ERR, pathval());
3809 if (entry.cmdtype == CMDUNKNOWN) c = 1;
3811 cmdp = cmdlookup(name, 0);
3812 if (cmdp) printentry(cmdp, verbose=='v');
3820 printentry(cmdp, verbose)
3821 struct tblentry *cmdp;
3828 printf("%s%s", cmdp->cmdname, (verbose ? " is " : ""));
3829 if (cmdp->cmdtype == CMDNORMAL) {
3830 idx = cmdp->param.index;
3833 name = padvance(&path, cmdp->cmdname);
3835 } while (--idx >= 0);
3838 } else if (cmdp->cmdtype == CMDBUILTIN) {
3840 out1str("a shell builtin");
3841 } else if (cmdp->cmdtype == CMDFUNCTION) {
3844 out1str("a function\n");
3845 name = commandtext(cmdp->param.func);
3846 printf("%s() {\n %s\n}", cmdp->cmdname, name);
3852 error("internal error: cmdtype %d", cmdp->cmdtype);
3855 printf(snlfmt, cmdp->rehash ? "*" : nullstr);
3860 /*** List the available builtins ***/
3863 static int helpcmd(int argc, char** argv)
3867 printf("\nBuilt-in commands:\n-------------------\n");
3868 for (col=0, i=0; i < NUMBUILTINS; i++) {
3869 col += printf("%c%s", ((col == 0) ? '\t' : ' '),
3870 builtincmds[i].name+1);
3876 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
3878 extern const struct BB_applet applets[];
3879 extern const size_t NUM_APPLETS;
3881 for (i=0; i < NUM_APPLETS; i++) {
3883 col += printf("%c%s", ((col == 0) ? '\t' : ' '),
3893 return EXIT_SUCCESS;
3897 * Resolve a command name. If you change this routine, you may have to
3898 * change the shellexec routine as well.
3901 static int prefix (const char *, const char *);
3904 find_command(const char *name, struct cmdentry *entry, int act, const char *path)
3906 struct tblentry *cmdp;
3916 struct builtincmd *bcmd;
3918 /* If name contains a slash, don't use the hash table */
3919 if (strchr(name, '/') != NULL) {
3921 while (stat(name, &statb) < 0) {
3922 if (errno != ENOENT && errno != ENOTDIR)
3924 entry->cmdtype = CMDUNKNOWN;
3925 entry->u.index = -1;
3928 entry->cmdtype = CMDNORMAL;
3929 entry->u.index = -1;
3932 entry->cmdtype = CMDNORMAL;
3938 if (act & DO_BRUTE) {
3939 firstchange = path_change(path, &bltin);