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);
3945 /* If name is in the table, and not invalidated by cd, we're done */
3946 if ((cmdp = cmdlookup(name, 0)) != NULL && cmdp->rehash == 0) {
3947 if (cmdp->cmdtype == CMDFUNCTION) {
3948 if (act & DO_NOFUN) {
3953 } else if (act & DO_BRUTE) {
3954 if ((cmdp->cmdtype == CMDNORMAL &&
3955 cmdp->param.index >= firstchange) ||
3956 (cmdp->cmdtype == CMDBUILTIN &&
3957 ((builtinloc < 0 && bltin >= 0) ?
3958 bltin : builtinloc) >= firstchange)) {
3959 /* need to recompute the entry */
3968 bcmd = find_builtin(name);
3969 regular = bcmd && IS_BUILTIN_REGULAR(bcmd);
3972 if (cmdp && (cmdp->cmdtype == CMDBUILTIN)) {
3975 } else if (act & DO_BRUTE) {
3976 if (firstchange == 0) {
3981 /* If %builtin not in path, check for builtin next */
3982 if (regular || (bltin < 0 && bcmd)) {
3985 entry->cmdtype = CMDBUILTIN;
3986 entry->u.cmd = bcmd;
3990 cmdp = cmdlookup(name, 1);
3991 cmdp->cmdtype = CMDBUILTIN;
3992 cmdp->param.cmd = bcmd;
3997 /* We have to search path. */
3998 prev = -1; /* where to start */
3999 if (cmdp && cmdp->rehash) { /* doing a rehash */
4000 if (cmdp->cmdtype == CMDBUILTIN)
4003 prev = cmdp->param.index;
4009 while ((fullname = padvance(&path, name)) != NULL) {
4010 stunalloc(fullname);
4012 if (idx >= firstchange) {
4016 if (prefix("builtin", pathopt)) {
4017 if ((bcmd = find_builtin(name))) {
4021 } else if (!(act & DO_NOFUN) &&
4022 prefix("func", pathopt)) {
4025 continue; /* ignore unimplemented options */
4028 /* if rehash, don't redo absolute path names */
4029 if (fullname[0] == '/' && idx <= prev &&
4030 idx < firstchange) {
4033 TRACE(("searchexec \"%s\": no change\n", name));
4036 while (stat(fullname, &statb) < 0) {
4037 if (errno != ENOENT && errno != ENOTDIR)
4041 e = EACCES; /* if we fail, this will be the error */
4042 if (!S_ISREG(statb.st_mode))
4044 if (pathopt) { /* this is a %func directory */
4045 stalloc(strlen(fullname) + 1);
4046 readcmdfile(fullname);
4047 if ((cmdp = cmdlookup(name, 0)) == NULL || cmdp->cmdtype != CMDFUNCTION)
4048 error("%s not defined in %s", name, fullname);
4049 stunalloc(fullname);
4052 TRACE(("searchexec \"%s\" returns \"%s\"\n", name, fullname));
4053 /* If we aren't called with DO_BRUTE and cmdp is set, it must
4054 be a function and we're being called with DO_NOFUN */
4056 entry->cmdtype = CMDNORMAL;
4057 entry->u.index = idx;
4061 cmdp = cmdlookup(name, 1);
4062 cmdp->cmdtype = CMDNORMAL;
4063 cmdp->param.index = idx;
4068 /* We failed. If there was an entry for this command, delete it */
4069 if (cmdp && updatetbl)
4072 out2fmt("%s: %s\n", name, errmsg(e, E_EXEC));
4073 entry->cmdtype = CMDUNKNOWN;
4078 entry->cmdtype = cmdp->cmdtype;
4079 entry->u = cmdp->param;
4085 * Search the table of builtin commands.
4089 bstrcmp(const void *name, const void *b)
4091 return strcmp((const char *)name, (*(const char *const *) b)+1);
4094 static struct builtincmd *
4095 find_builtin(const char *name)
4097 struct builtincmd *bp;
4099 bp = bsearch(name, builtincmds, NUMBUILTINS, sizeof(struct builtincmd),
4107 * Called when a cd is done. Marks all commands so the next time they
4108 * are executed they will be rehashed.
4113 struct tblentry **pp;
4114 struct tblentry *cmdp;
4116 for (pp = cmdtable ; pp < &cmdtable[CMDTABLESIZE] ; pp++) {
4117 for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) {
4118 if (cmdp->cmdtype == CMDNORMAL
4119 || (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0))
4128 * Called before PATH is changed. The argument is the new value of PATH;
4129 * pathval() still returns the old value at this point. Called with
4134 changepath(const char *newval)
4139 firstchange = path_change(newval, &bltin);
4140 if (builtinloc < 0 && bltin >= 0)
4141 builtinloc = bltin; /* zap builtins */
4142 clearcmdentry(firstchange);
4148 * Clear out command entries. The argument specifies the first entry in
4149 * PATH which has changed.
4153 clearcmdentry(firstchange)
4156 struct tblentry **tblp;
4157 struct tblentry **pp;
4158 struct tblentry *cmdp;
4161 for (tblp = cmdtable ; tblp < &cmdtable[CMDTABLESIZE] ; tblp++) {
4163 while ((cmdp = *pp) != NULL) {
4164 if ((cmdp->cmdtype == CMDNORMAL &&
4165 cmdp->param.index >= firstchange)
4166 || (cmdp->cmdtype == CMDBUILTIN &&
4167 builtinloc >= firstchange)) {
4180 * Delete all functions.
4185 struct tblentry **tblp;
4186 struct tblentry **pp;
4187 struct tblentry *cmdp;
4190 for (tblp = cmdtable ; tblp < &cmdtable[CMDTABLESIZE] ; tblp++) {
4192 while ((cmdp = *pp) != NULL) {
4193 if (cmdp->cmdtype == CMDFUNCTION) {
4195 freefunc(cmdp->param.func);
4208 * Locate a command in the command hash table. If "add" is nonzero,
4209 * add the command to the table if it is not already present. The
4210 * variable "lastcmdentry" is set to point to the address of the link
4211 * pointing to the entry, so that delete_cmd_entry can delete the
4215 static struct tblentry **lastcmdentry;
4217 static struct tblentry *
4218 cmdlookup(const char *name, int add)
4222 struct tblentry *cmdp;
4223 struct tblentry **pp;
4230 pp = &cmdtable[hashval % CMDTABLESIZE];
4231 for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) {
4232 if (equal(cmdp->cmdname, name))
4236 if (add && cmdp == NULL) {
4238 cmdp = *pp = ckmalloc(sizeof (struct tblentry) - ARB
4239 + strlen(name) + 1);
4241 cmdp->cmdtype = CMDUNKNOWN;
4243 strcpy(cmdp->cmdname, name);
4251 * Delete the command entry returned on the last lookup.
4255 delete_cmd_entry() {
4256 struct tblentry *cmdp;
4259 cmdp = *lastcmdentry;
4260 *lastcmdentry = cmdp->next;
4269 static const short nodesize[26] = {
4270 ALIGN(sizeof (struct nbinary)),
4271 ALIGN(sizeof (struct ncmd)),
4272 ALIGN(sizeof (struct npipe)),
4273 ALIGN(sizeof (struct nredir)),
4274 ALIGN(sizeof (struct nredir)),
4275 ALIGN(sizeof (struct nredir)),
4276 ALIGN(sizeof (struct nbinary)),
4277 ALIGN(sizeof (struct nbinary)),
4278 ALIGN(sizeof (struct nif)),
4279 ALIGN(sizeof (struct nbinary)),
4280 ALIGN(sizeof (struct nbinary)),
4281 ALIGN(sizeof (struct nfor)),
4282 ALIGN(sizeof (struct ncase)),
4283 ALIGN(sizeof (struct nclist)),
4284 ALIGN(sizeof (struct narg)),
4285 ALIGN(sizeof (struct narg)),
4286 ALIGN(sizeof (struct nfile)),
4287 ALIGN(sizeof (struct nfile)),
4288 ALIGN(sizeof (struct nfile)),
4289 ALIGN(sizeof (struct nfile)),
4290 ALIGN(sizeof (struct nfile)),
4291 ALIGN(sizeof (struct ndup)),
4292 ALIGN(sizeof (struct ndup)),
4293 ALIGN(sizeof (struct nhere)),
4294 ALIGN(sizeof (struct nhere)),
4295 ALIGN(sizeof (struct nnot)),
4301 * Delete a function if it exists.
4305 unsetfunc(char *name)
4307 struct tblentry *cmdp;
4309 if ((cmdp = cmdlookup(name, 0)) != NULL && cmdp->cmdtype == CMDFUNCTION) {
4310 freefunc(cmdp->param.func);
4317 * Locate and print what a word is...
4321 typecmd(int argc, char **argv)
4329 for (i = 1; i < argc; i++) {
4330 argv_a[0] = argv[i];
4333 err |= hashcmd(argc, argv);
4340 commandcmd(argc, argv)
4345 int default_path = 0;
4346 int verify_only = 0;
4347 int verbose_verify_only = 0;
4349 while ((c = nextopt("pvV")) != '\0')
4358 verbose_verify_only = 1;
4362 if (default_path + verify_only + verbose_verify_only > 1 ||
4365 "command [-p] command [arg ...]\n"
4366 "command {-v|-V} command\n");
4370 if (verify_only || verbose_verify_only) {
4374 argv_a[0] = *argptr;
4376 optptr = verbose_verify_only ? "v" : "V"; /* reverse special */
4377 return hashcmd(argc, argv);
4385 path_change(newval, bltin)
4389 const char *old, *new;
4395 firstchange = 9999; /* assume no change */
4401 if ((*old == '\0' && *new == ':')
4402 || (*old == ':' && *new == '\0'))
4404 old = new; /* ignore subsequent differences */
4408 if (*new == '%' && *bltin < 0 && prefix("builtin", new + 1))
4415 if (builtinloc >= 0 && *bltin < 0)
4420 * Routines to expand arguments to commands. We have to deal with
4421 * backquotes, shell variables, and file metacharacters.
4426 #define RMESCAPE_ALLOC 0x1 /* Allocate a new string */
4427 #define RMESCAPE_GLOB 0x2 /* Add backslashes for glob */
4430 * Structure specifying which parts of the string should be searched
4431 * for IFS characters.
4435 struct ifsregion *next; /* next region in list */
4436 int begoff; /* offset of start of region */
4437 int endoff; /* offset of end of region */
4438 int nulonly; /* search for nul bytes only */
4442 static char *expdest; /* output of current string */
4443 static struct nodelist *argbackq; /* list of back quote expressions */
4444 static struct ifsregion ifsfirst; /* first struct in list of ifs regions */
4445 static struct ifsregion *ifslastp; /* last struct in list */
4446 static struct arglist exparg; /* holds expanded arg list */
4448 static void argstr (char *, int);
4449 static char *exptilde (char *, int);
4450 static void expbackq (union node *, int, int);
4451 static int subevalvar (char *, char *, int, int, int, int, int);
4452 static int varisset (char *, int);
4453 static void strtodest (const char *, const char *, int);
4454 static void varvalue (char *, int, int);
4455 static void recordregion (int, int, int);
4456 static void removerecordregions (int);
4457 static void ifsbreakup (char *, struct arglist *);
4458 static void ifsfree (void);
4459 static void expandmeta (struct strlist *, int);
4460 #if defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN)
4461 #define preglob(p) _rmescapes((p), RMESCAPE_ALLOC | RMESCAPE_GLOB)
4462 #if !defined(GLOB_BROKEN)
4463 static void addglob (const glob_t *);
4466 #if !(defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN))
4467 static void expmeta (char *, char *);
4469 #if !(defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN))
4470 static struct strlist *expsort (struct strlist *);
4471 static struct strlist *msort (struct strlist *, int);
4473 static int patmatch (char *, char *, int);
4474 #if defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN)
4475 static int patmatch2 (char *, char *, int);
4477 static int pmatch (char *, char *, int);
4478 #define patmatch2 patmatch
4480 static char *cvtnum (int, char *);
4483 * Expand shell variables and backquotes inside a here document.
4486 /* arg: the document, fd: where to write the expanded version */
4488 expandhere(union node *arg, int fd)
4491 expandarg(arg, (struct arglist *)NULL, 0);
4492 xwrite(fd, stackblock(), expdest - stackblock());
4497 * Perform variable substitution and command substitution on an argument,
4498 * placing the resulting list of arguments in arglist. If EXP_FULL is true,
4499 * perform splitting and file name expansion. When arglist is NULL, perform
4500 * here document expansion.
4504 expandarg(arg, arglist, flag)
4506 struct arglist *arglist;
4512 argbackq = arg->narg.backquote;
4513 STARTSTACKSTR(expdest);
4514 ifsfirst.next = NULL;
4516 argstr(arg->narg.text, flag);
4517 if (arglist == NULL) {
4518 return; /* here document expanded */
4520 STPUTC('\0', expdest);
4521 p = grabstackstr(expdest);
4522 exparg.lastp = &exparg.list;
4526 if (flag & EXP_FULL) {
4527 ifsbreakup(p, &exparg);
4528 *exparg.lastp = NULL;
4529 exparg.lastp = &exparg.list;
4530 expandmeta(exparg.list, flag);
4532 if (flag & EXP_REDIR) /*XXX - for now, just remove escapes */
4534 sp = (struct strlist *)stalloc(sizeof (struct strlist));
4537 exparg.lastp = &sp->next;
4540 *exparg.lastp = NULL;
4542 *arglist->lastp = exparg.list;
4543 arglist->lastp = exparg.lastp;
4549 * Expand a variable, and return a pointer to the next character in the
4553 static inline char *
4569 int quotes = flag & (EXP_FULL | EXP_CASE);
4572 subtype = varflags & VSTYPE;
4577 p = strchr(p, '=') + 1;
4578 again: /* jump here after setting a variable with ${var=text} */
4580 set = varisset(var, varflags & VSNUL);
4583 val = lookupvar(var);
4584 if (val == NULL || ((varflags & VSNUL) && val[0] == '\0')) {
4591 startloc = expdest - stackblock();
4592 if (set && subtype != VSPLUS) {
4593 /* insert the value of the variable */
4595 varvalue(var, varflags & VSQUOTE, flag);
4596 if (subtype == VSLENGTH) {
4597 varlen = expdest - stackblock() - startloc;
4598 STADJUST(-varlen, expdest);
4601 if (subtype == VSLENGTH) {
4602 varlen = strlen(val);
4606 varflags & VSQUOTE ?
4607 DQSYNTAX : BASESYNTAX,
4614 if (subtype == VSPLUS)
4617 easy = ((varflags & VSQUOTE) == 0 ||
4618 (*var == '@' && shellparam.nparam != 1));
4623 expdest = cvtnum(varlen, expdest);
4630 recordregion(startloc, expdest - stackblock(),
4631 varflags & VSQUOTE);
4647 case VSTRIMRIGHTMAX:
4651 * Terminate the string and start recording the pattern
4654 STPUTC('\0', expdest);
4655 patloc = expdest - stackblock();
4656 if (subevalvar(p, NULL, patloc, subtype,
4657 startloc, varflags, quotes) == 0) {
4658 int amount = (expdest - stackblock() - patloc) + 1;
4659 STADJUST(-amount, expdest);
4661 /* Remove any recorded regions beyond start of variable */
4662 removerecordregions(startloc);
4668 if (subevalvar(p, var, 0, subtype, startloc,
4669 varflags, quotes)) {
4672 * Remove any recorded regions beyond
4675 removerecordregions(startloc);
4690 if (subtype != VSNORMAL) { /* skip to end of alternative */
4693 if ((c = *p++) == CTLESC)
4695 else if (c == CTLBACKQ || c == (CTLBACKQ|CTLQUOTE)) {
4697 argbackq = argbackq->next;
4698 } else if (c == CTLVAR) {
4699 if ((*p++ & VSTYPE) != VSNORMAL)
4701 } else if (c == CTLENDVAR) {
4712 * Perform variable and command substitution. If EXP_FULL is set, output CTLESC
4713 * characters to allow for further processing. Otherwise treat
4714 * $@ like $* since no splitting will be performed.
4723 int quotes = flag & (EXP_FULL | EXP_CASE); /* do CTLESC */
4726 if (*p == '~' && (flag & (EXP_TILDE | EXP_VARTILDE)))
4727 p = exptilde(p, flag);
4731 case CTLENDVAR: /* ??? */
4734 /* "$@" syntax adherence hack */
4735 if (p[0] == CTLVAR && p[2] == '@' && p[3] == '=')
4737 if ((flag & EXP_FULL) != 0)
4747 p = evalvar(p, flag);
4750 case CTLBACKQ|CTLQUOTE:
4751 expbackq(argbackq->n, c & CTLQUOTE, flag);
4752 argbackq = argbackq->next;
4754 #ifdef ASH_MATH_SUPPORT
4762 * sort of a hack - expand tildes in variable
4763 * assignments (after the first '=' and after ':'s).
4766 if (flag & EXP_VARTILDE && *p == '~') {
4773 p = exptilde(p, flag);
4789 char c, *startp = p;
4792 int quotes = flag & (EXP_FULL | EXP_CASE);
4794 while ((c = *p) != '\0') {
4801 if (flag & EXP_VARTILDE)
4811 if (*(startp+1) == '\0') {
4812 if ((home = lookupvar("HOME")) == NULL)
4815 if ((pw = getpwnam(startp+1)) == NULL)
4822 strtodest(home, SQSYNTAX, quotes);
4831 removerecordregions(int endoff)
4833 if (ifslastp == NULL)
4836 if (ifsfirst.endoff > endoff) {
4837 while (ifsfirst.next != NULL) {
4838 struct ifsregion *ifsp;
4840 ifsp = ifsfirst.next->next;
4841 ckfree(ifsfirst.next);
4842 ifsfirst.next = ifsp;
4845 if (ifsfirst.begoff > endoff)
4848 ifslastp = &ifsfirst;
4849 ifsfirst.endoff = endoff;
4854 ifslastp = &ifsfirst;
4855 while (ifslastp->next && ifslastp->next->begoff < endoff)
4856 ifslastp=ifslastp->next;
4857 while (ifslastp->next != NULL) {
4858 struct ifsregion *ifsp;
4860 ifsp = ifslastp->next->next;
4861 ckfree(ifslastp->next);
4862 ifslastp->next = ifsp;
4865 if (ifslastp->endoff > endoff)
4866 ifslastp->endoff = endoff;
4870 #ifdef ASH_MATH_SUPPORT
4872 * Expand arithmetic expression. Backup to start of expression,
4873 * evaluate, place result in (backed up) result, adjust string position.
4881 int quotes = flag & (EXP_FULL | EXP_CASE);
4887 * This routine is slightly over-complicated for
4888 * efficiency. First we make sure there is
4889 * enough space for the result, which may be bigger
4890 * than the expression if we add exponentation. Next we
4891 * scan backwards looking for the start of arithmetic. If the
4892 * next previous character is a CTLESC character, then we
4893 * have to rescan starting from the beginning since CTLESC
4894 * characters have to be processed left to right.
4896 CHECKSTRSPACE(10, expdest);
4897 USTPUTC('\0', expdest);
4898 start = stackblock();
4900 while (*p != CTLARI && p >= start)
4903 error("missing CTLARI (shouldn't happen)");
4904 if (p > start && *(p-1) == CTLESC)
4905 for (p = start; *p != CTLARI; p++)
4914 removerecordregions(begoff);
4917 result = arith(p+2);
4918 snprintf(p, 12, "%d", result);
4924 recordregion(begoff, p - 1 - start, 0);
4925 result = expdest - p + 1;
4926 STADJUST(-result, expdest);
4931 * Expand stuff in backwards quotes.
4935 expbackq(cmd, quoted, flag)
4940 volatile struct backcmd in;
4944 char *dest = expdest;
4945 volatile struct ifsregion saveifs;
4946 struct ifsregion *volatile savelastp;
4947 struct nodelist *volatile saveargbackq;
4949 int startloc = dest - stackblock();
4950 char const *syntax = quoted? DQSYNTAX : BASESYNTAX;
4951 volatile int saveherefd;
4952 int quotes = flag & (EXP_FULL | EXP_CASE);
4953 struct jmploc jmploc;
4954 struct jmploc *volatile savehandler;
4958 /* Avoid longjmp clobbering */
4969 savelastp = ifslastp;
4970 saveargbackq = argbackq;
4971 saveherefd = herefd;
4973 if ((ex = setjmp(jmploc.loc))) {
4976 savehandler = handler;
4979 p = grabstackstr(dest);
4980 evalbackcmd(cmd, (struct backcmd *) &in);
4981 ungrabstackstr(p, dest);
4985 ifslastp = savelastp;
4986 argbackq = saveargbackq;
4987 herefd = saveherefd;
4995 if (--in.nleft < 0) {
4998 while ((i = read(in.fd, buf, sizeof buf)) < 0 && errno == EINTR);
4999 TRACE(("expbackq: read returns %d\n", i));
5006 if (lastc != '\0') {
5007 if (quotes && syntax[(int)lastc] == CCTL)
5008 STPUTC(CTLESC, dest);
5009 STPUTC(lastc, dest);
5013 /* Eat all trailing newlines */
5014 for (; dest > stackblock() && dest[-1] == '\n';)
5023 exitstatus = waitforjob(in.jp);
5024 handler = savehandler;
5026 longjmp(handler->loc, 1);
5029 recordregion(startloc, dest - stackblock(), 0);
5030 TRACE(("evalbackq: size=%d: \"%.*s\"\n",
5031 (dest - stackblock()) - startloc,
5032 (dest - stackblock()) - startloc,
5033 stackblock() + startloc));
5039 subevalvar(p, str, strloc, subtype, startloc, varflags, quotes)
5052 int saveherefd = herefd;
5053 struct nodelist *saveargbackq = argbackq;
5057 argstr(p, subtype != VSASSIGN && subtype != VSQUESTION ? EXP_CASE : 0);
5058 STACKSTRNUL(expdest);
5059 herefd = saveherefd;
5060 argbackq = saveargbackq;
5061 startp = stackblock() + startloc;
5063 str = stackblock() + strloc;
5067 setvar(str, startp, 0);
5068 amount = startp - expdest;
5069 STADJUST(amount, expdest);
5076 if (*p != CTLENDVAR) {
5077 out2fmt(snlfmt, startp);
5078 error((char *)NULL);
5080 error("%.*s: parameter %snot set", p - str - 1,
5081 str, (varflags & VSNUL) ? "null or "
5086 for (loc = startp; loc < str; loc++) {
5089 if (patmatch2(str, startp, quotes))
5092 if (quotes && *loc == CTLESC)
5098 for (loc = str - 1; loc >= startp;) {
5101 if (patmatch2(str, startp, quotes))
5105 if (quotes && loc > startp && *(loc - 1) == CTLESC) {
5106 for (q = startp; q < loc; q++)
5116 for (loc = str - 1; loc >= startp;) {
5117 if (patmatch2(str, loc, quotes))
5120 if (quotes && loc > startp && *(loc - 1) == CTLESC) {
5121 for (q = startp; q < loc; q++)
5130 case VSTRIMRIGHTMAX:
5131 for (loc = startp; loc < str - 1; loc++) {
5132 if (patmatch2(str, loc, quotes))
5134 if (quotes && *loc == CTLESC)
5147 amount = ((str - 1) - (loc - startp)) - expdest;
5148 STADJUST(amount, expdest);
5149 while (loc != str - 1)
5154 amount = loc - expdest;
5155 STADJUST(amount, expdest);
5156 STPUTC('\0', expdest);
5157 STADJUST(-1, expdest);
5163 * Test whether a specialized variable is set.
5167 varisset(name, nulok)
5172 return backgndpid != -1;
5173 else if (*name == '@' || *name == '*') {
5174 if (*shellparam.p == NULL)
5180 for (av = shellparam.p; *av; av++)
5185 } else if (is_digit(*name)) {
5187 int num = atoi(name);
5189 if (num > shellparam.nparam)
5195 ap = shellparam.p[num - 1];
5197 if (nulok && (ap == NULL || *ap == '\0'))
5204 * Put a string on the stack.
5208 strtodest(p, syntax, quotes)
5214 if (quotes && syntax[(int) *p] == CCTL)
5215 STPUTC(CTLESC, expdest);
5216 STPUTC(*p++, expdest);
5221 * Add the value of a specialized variable to the stack string.
5225 varvalue(name, quoted, flags)
5237 int allow_split = flags & EXP_FULL;
5238 int quotes = flags & (EXP_FULL | EXP_CASE);
5240 syntax = quoted ? DQSYNTAX : BASESYNTAX;
5249 num = shellparam.nparam;
5254 expdest = cvtnum(num, expdest);
5257 for (i = 0 ; i < NOPTS ; i++) {
5259 STPUTC(optent_letter(optlist[i]), expdest);
5263 if (allow_split && quoted) {
5264 sep = 1 << CHAR_BIT;
5269 sep = ifsset() ? ifsval()[0] : ' ';
5271 sepq = syntax[(int) sep] == CCTL;
5274 for (ap = shellparam.p ; (p = *ap++) != NULL ; ) {
5275 strtodest(p, syntax, quotes);
5278 STPUTC(CTLESC, expdest);
5279 STPUTC(sep, expdest);
5284 strtodest(arg0, syntax, quotes);
5288 if (num > 0 && num <= shellparam.nparam) {
5289 strtodest(shellparam.p[num - 1], syntax, quotes);
5297 * Record the fact that we have to scan this region of the
5298 * string for IFS characters.
5302 recordregion(start, end, nulonly)
5307 struct ifsregion *ifsp;
5309 if (ifslastp == NULL) {
5313 ifsp = (struct ifsregion *)ckmalloc(sizeof (struct ifsregion));
5315 ifslastp->next = ifsp;
5319 ifslastp->begoff = start;
5320 ifslastp->endoff = end;
5321 ifslastp->nulonly = nulonly;
5327 * Break the argument string into pieces based upon IFS and add the
5328 * strings to the argument list. The regions of the string to be
5329 * searched for IFS characters have been stored by recordregion.
5332 ifsbreakup(string, arglist)
5334 struct arglist *arglist;
5336 struct ifsregion *ifsp;
5341 const char *ifs, *realifs;
5349 realifs = ifsset() ? ifsval() : defifs;
5350 if (ifslastp != NULL) {
5353 p = string + ifsp->begoff;
5354 nulonly = ifsp->nulonly;
5355 ifs = nulonly ? nullstr : realifs;
5357 while (p < string + ifsp->endoff) {
5361 if (strchr(ifs, *p)) {
5363 ifsspc = (strchr(defifs, *p) != NULL);
5364 /* Ignore IFS whitespace at start */
5365 if (q == start && ifsspc) {
5371 sp = (struct strlist *)stalloc(sizeof *sp);
5373 *arglist->lastp = sp;
5374 arglist->lastp = &sp->next;
5378 if (p >= string + ifsp->endoff) {
5384 if (strchr(ifs, *p) == NULL ) {
5387 } else if (strchr(defifs, *p) == NULL) {
5403 } while ((ifsp = ifsp->next) != NULL);
5404 if (!(*start || (!ifsspc && start > string && nulonly))) {
5409 sp = (struct strlist *)stalloc(sizeof *sp);
5411 *arglist->lastp = sp;
5412 arglist->lastp = &sp->next;
5418 while (ifsfirst.next != NULL) {
5419 struct ifsregion *ifsp;
5421 ifsp = ifsfirst.next->next;
5422 ckfree(ifsfirst.next);
5423 ifsfirst.next = ifsp;
5427 ifsfirst.next = NULL;
5431 * Add a file name to the list.
5435 addfname(const char *name)
5441 sp = (struct strlist *)stalloc(sizeof *sp);
5444 exparg.lastp = &sp->next;
5448 * Expand shell metacharacters. At this point, the only control characters
5449 * should be escapes. The results are stored in the list exparg.
5452 #if defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN)
5454 expandmeta(str, flag)
5455 struct strlist *str;
5460 /* TODO - EXP_REDIR */
5465 p = preglob(str->text);
5467 switch (glob(p, GLOB_NOMAGIC, 0, &pglob)) {
5469 if (!(pglob.gl_flags & GLOB_MAGCHAR))
5480 *exparg.lastp = str;
5481 rmescapes(str->text);
5482 exparg.lastp = &str->next;
5484 default: /* GLOB_NOSPACE */
5485 error("Out of space");
5493 * Add the result of glob(3) to the list.
5498 const glob_t *pglob;
5500 char **p = pglob->gl_pathv;
5508 #else /* defined(__GLIBC__) && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN) */
5509 static char *expdir;
5513 expandmeta(str, flag)
5514 struct strlist *str;
5518 struct strlist **savelastp;
5521 /* TODO - EXP_REDIR */
5527 for (;;) { /* fast check for meta chars */
5528 if ((c = *p++) == '\0')
5530 if (c == '*' || c == '?' || c == '[' || c == '!')
5533 savelastp = exparg.lastp;
5535 if (expdir == NULL) {
5536 int i = strlen(str->text);
5537 expdir = ckmalloc(i < 2048 ? 2048 : i); /* XXX */
5540 expmeta(expdir, str->text);
5544 if (exparg.lastp == savelastp) {
5549 *exparg.lastp = str;
5550 rmescapes(str->text);
5551 exparg.lastp = &str->next;
5553 *exparg.lastp = NULL;
5554 *savelastp = sp = expsort(*savelastp);
5555 while (sp->next != NULL)
5557 exparg.lastp = &sp->next;
5565 * Do metacharacter (i.e. *, ?, [...]) expansion.
5569 expmeta(enddir, name)
5587 for (p = name ; ; p++) {
5588 if (*p == '*' || *p == '?')
5590 else if (*p == '[') {
5595 while (*q == CTLQUOTEMARK)
5599 if (*q == '/' || *q == '\0')
5606 } else if (*p == '!' && p[1] == '!' && (p == name || p[-1] == '/')) {
5608 } else if (*p == '\0')
5610 else if (*p == CTLQUOTEMARK)
5612 else if (*p == CTLESC)
5620 if (metaflag == 0) { /* we've reached the end of the file name */
5621 if (enddir != expdir)
5623 for (p = name ; ; p++) {
5624 if (*p == CTLQUOTEMARK)
5632 if (metaflag == 0 || lstat(expdir, &statb) >= 0)
5637 if (start != name) {
5640 while (*p == CTLQUOTEMARK)
5647 if (enddir == expdir) {
5649 } else if (enddir == expdir + 1 && *expdir == '/') {
5655 if ((dirp = opendir(cp)) == NULL)
5657 if (enddir != expdir)
5659 if (*endname == 0) {
5667 while (*p == CTLQUOTEMARK)
5673 while (! int_pending() && (dp = readdir(dirp)) != NULL) {
5674 if (dp->d_name[0] == '.' && ! matchdot)
5676 if (patmatch(start, dp->d_name, 0)) {
5678 strcpy(enddir, dp->d_name);
5681 for (p = enddir, cp = dp->d_name;
5682 (*p++ = *cp++) != '\0';)
5685 expmeta(p, endname);
5693 #endif /* defined(__GLIBC__) && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN) */
5697 #if !(defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN))
5699 * Sort the results of file name expansion. It calculates the number of
5700 * strings to sort and then calls msort (short for merge sort) to do the
5704 static struct strlist *
5706 struct strlist *str;
5712 for (sp = str ; sp ; sp = sp->next)
5714 return msort(str, len);
5718 static struct strlist *
5720 struct strlist *list;
5723 struct strlist *p, *q = NULL;
5724 struct strlist **lpp;
5732 for (n = half ; --n >= 0 ; ) {
5736 q->next = NULL; /* terminate first half of list */
5737 q = msort(list, half); /* sort first half of list */
5738 p = msort(p, len - half); /* sort second half */
5741 if (strcmp(p->text, q->text) < 0) {
5744 if ((p = *lpp) == NULL) {
5751 if ((q = *lpp) == NULL) {
5764 * Returns true if the pattern matches the string.
5767 #if defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN)
5768 /* squoted: string might have quote chars */
5770 patmatch(char *pattern, char *string, int squoted)
5775 p = preglob(pattern);
5776 q = squoted ? _rmescapes(string, RMESCAPE_ALLOC) : string;
5778 return !fnmatch(p, q, 0);
5783 patmatch2(char *pattern, char *string, int squoted)
5789 p = grabstackstr(expdest);
5790 res = patmatch(pattern, string, squoted);
5791 ungrabstackstr(p, expdest);
5796 patmatch(char *pattern, char *string, int squoted) {
5797 return pmatch(pattern, string, squoted);
5802 pmatch(char *pattern, char *string, int squoted)
5814 if (squoted && *q == CTLESC)
5822 if (squoted && *q == CTLESC)
5829 while (c == CTLQUOTEMARK || c == '*')
5831 if (c != CTLESC && c != CTLQUOTEMARK &&
5832 c != '?' && c != '*' && c != '[') {
5834 if (squoted && *q == CTLESC &&
5839 if (squoted && *q == CTLESC)
5845 if (pmatch(p, q, squoted))
5847 if (squoted && *q == CTLESC)
5849 } while (*q++ != '\0');
5860 while (*endp == CTLQUOTEMARK)
5863 goto dft; /* no matching ] */
5864 if (*endp == CTLESC)
5876 if (squoted && chr == CTLESC)
5882 if (c == CTLQUOTEMARK)
5886 if (*p == '-' && p[1] != ']') {
5888 while (*p == CTLQUOTEMARK)
5892 if (chr >= c && chr <= *p)
5899 } while ((c = *p++) != ']');
5900 if (found == invert)
5905 if (squoted && *q == CTLESC)
5922 * Remove any CTLESC characters from a string.
5925 #if defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN)
5927 _rmescapes(char *str, int flag)
5930 static const char qchars[] = { CTLESC, CTLQUOTEMARK, 0 };
5932 p = strpbrk(str, qchars);
5938 if (flag & RMESCAPE_ALLOC) {
5939 size_t len = p - str;
5940 q = r = stalloc(strlen(p) + len + 1);
5942 memcpy(q, str, len);
5947 if (*p == CTLQUOTEMARK) {
5953 if (flag & RMESCAPE_GLOB && *p != '/') {
5970 while (*p != CTLESC && *p != CTLQUOTEMARK) {
5976 if (*p == CTLQUOTEMARK) {
5991 * See if a pattern matches in a case statement.
5995 casematch(union node *pattern, const char *val)
5997 struct stackmark smark;
6001 setstackmark(&smark);
6002 argbackq = pattern->narg.backquote;
6003 STARTSTACKSTR(expdest);
6005 argstr(pattern->narg.text, EXP_TILDE | EXP_CASE);
6006 STPUTC('\0', expdest);
6007 p = grabstackstr(expdest);
6008 result = patmatch(p, (char *)val, 0);
6009 popstackmark(&smark);
6024 CHECKSTRSPACE(32, buf);
6025 len = sprintf(buf, "%d", num);
6030 * Editline and history functions (and glue).
6032 static int histcmd(argc, argv)
6036 error("not compiled with history support");
6042 struct redirtab *next;
6043 /* short renamed[10]; *//* Current ash support only 0-9 descriptors */
6047 static struct redirtab *redirlist;
6049 extern char **environ;
6054 * Initialization code.
6067 basepf.nextc = basepf.buf = basebuf;
6076 for (envp = environ ; *envp ; envp++) {
6077 if (strchr(*envp, '=')) {
6078 setvareq(*envp, VEXPORT|VTEXTFIXED);
6082 snprintf(ppid, sizeof(ppid), "%d", (int) getppid());
6083 setvar("PPID", ppid, 0);
6090 * This routine is called when an error or an interrupt occurs in an
6091 * interactive shell and control is returned to the main command loop.
6095 /* 1 == check for aliases, 2 == also check for assignments */
6096 static int checkalias;
6111 if (exception != EXSHELLPROC)
6112 parselleft = parsenleft = 0; /* clear input buffer */
6116 /* from parser.c: */
6136 * This file implements the input routines used by the parser.
6139 #ifdef BB_FEATURE_COMMAND_EDITING
6140 unsigned int shell_context;
6141 static const char * cmdedit_prompt;
6142 static inline void putprompt(const char *s) {
6146 static inline void putprompt(const char *s) {
6151 #define EOF_NLEFT -99 /* value of parsenleft when EOF pushed back */
6156 * Same as pgetc(), but ignores PEOA.
6166 } while (c == PEOA);
6170 static inline int pgetc2() { return pgetc_macro(); }
6174 * Read a line from the script.
6177 static inline char *
6178 pfgets(char *line, int len)
6184 while (--nleft > 0) {
6203 char *buf = parsefile->buf;
6207 #ifdef BB_FEATURE_COMMAND_EDITING
6210 nr = read(parsefile->fd, buf, BUFSIZ - 1);
6213 cmdedit_read_input((char*)cmdedit_prompt, buf);
6215 } while (nr <=0 || shell_context);
6216 cmdedit_terminate();
6220 nr = read(parsefile->fd, buf, BUFSIZ - 1);
6226 if (parsefile->fd == 0 && errno == EWOULDBLOCK) {
6227 int flags = fcntl(0, F_GETFL, 0);
6228 if (flags >= 0 && flags & O_NONBLOCK) {
6229 flags &=~ O_NONBLOCK;
6230 if (fcntl(0, F_SETFL, flags) >= 0) {
6231 out2str("sh: turning off NDELAY mode\n");
6243 struct strpush *sp = parsefile->strpush;
6248 if (parsenextc[-1] == ' ' || parsenextc[-1] == '\t') {
6253 if (sp->string != sp->ap->val) {
6257 sp->ap->flag &= ~ALIASINUSE;
6258 if (sp->ap->flag & ALIASDEAD) {
6259 unalias(sp->ap->name);
6263 parsenextc = sp->prevstring;
6264 parsenleft = sp->prevnleft;
6265 /*dprintf("*** calling popstring: restoring to '%s'\n", parsenextc);*/
6266 parsefile->strpush = sp->prev;
6267 if (sp != &(parsefile->basestrpush))
6274 * Refill the input buffer and return the next input character:
6276 * 1) If a string was pushed back on the input, pop it;
6277 * 2) If an EOF was pushed back (parsenleft == EOF_NLEFT) or we are reading
6278 * from a string so we can't refill the buffer, return EOF.
6279 * 3) If the is more stuff in this buffer, use it else call read to fill it.
6280 * 4) Process input up to the next newline, deleting nul characters.
6290 while (parsefile->strpush) {
6292 if (parsenleft == -1 && parsefile->strpush->ap &&
6293 parsenextc[-1] != ' ' && parsenextc[-1] != '\t') {
6298 if (--parsenleft >= 0)
6299 return (*parsenextc++);
6301 if (parsenleft == EOF_NLEFT || parsefile->buf == NULL)
6306 if (parselleft <= 0) {
6307 if ((parselleft = preadfd()) <= 0) {
6308 parselleft = parsenleft = EOF_NLEFT;
6315 /* delete nul characters */
6316 for (more = 1; more;) {
6324 parsenleft = q - parsenextc;
6325 more = 0; /* Stop processing here */
6331 if (--parselleft <= 0 && more) {
6332 parsenleft = q - parsenextc - 1;
6343 out2str(parsenextc);
6348 return *parsenextc++;
6353 * Push a string back onto the input at this current parsefile level.
6354 * We handle aliases this way.
6357 pushstring(char *s, int len, void *ap)
6362 /*dprintf("*** calling pushstring: %s, %d\n", s, len);*/
6363 if (parsefile->strpush) {
6364 sp = ckmalloc(sizeof (struct strpush));
6365 sp->prev = parsefile->strpush;
6366 parsefile->strpush = sp;
6368 sp = parsefile->strpush = &(parsefile->basestrpush);
6369 sp->prevstring = parsenextc;
6370 sp->prevnleft = parsenleft;
6372 sp->ap = (struct alias *)ap;
6374 ((struct alias *)ap)->flag |= ALIASINUSE;
6385 * Like setinputfile, but takes input from a string.
6389 setinputstring(char *string)
6393 parsenextc = string;
6394 parsenleft = strlen(string);
6395 parsefile->buf = NULL;
6403 * To handle the "." command, a stack of input files is used. Pushfile
6404 * adds a new entry to the stack and popfile restores the previous level.
6409 struct parsefile *pf;
6411 parsefile->nleft = parsenleft;
6412 parsefile->lleft = parselleft;
6413 parsefile->nextc = parsenextc;
6414 parsefile->linno = plinno;
6415 pf = (struct parsefile *)ckmalloc(sizeof (struct parsefile));
6416 pf->prev = parsefile;
6419 pf->basestrpush.prev = NULL;
6424 static void restartjob (struct job *);
6426 static void freejob (struct job *);
6427 static struct job *getjob (const char *);
6428 static int dowait (int, struct job *);
6429 static void waitonint(int);
6433 * We keep track of whether or not fd0 has been redirected. This is for
6434 * background commands, where we want to redirect fd0 to /dev/null only
6435 * if it hasn't already been redirected.
6437 static int fd0_redirected = 0;
6439 /* Return true if fd 0 has already been redirected at least once. */
6441 fd0_redirected_p () {
6442 return fd0_redirected != 0;
6445 static void dupredirect (const union node *, int, int fd1dup);
6449 * Turn job control on and off.
6451 * Note: This code assumes that the third arg to ioctl is a character
6452 * pointer, which is true on Berkeley systems but not System V. Since
6453 * System V doesn't have job control yet, this isn't a problem now.
6458 static void setjobctl(int enable)
6460 #ifdef OLD_TTY_DRIVER
6464 if (enable == jobctl || rootshell == 0)
6467 do { /* while we are in the background */
6468 #ifdef OLD_TTY_DRIVER
6469 if (ioctl(2, TIOCGPGRP, (char *)&initialpgrp) < 0) {
6471 initialpgrp = tcgetpgrp(2);
6472 if (initialpgrp < 0) {
6474 out2str("sh: can't access tty; job control turned off\n");
6478 if (initialpgrp == -1)
6479 initialpgrp = getpgrp();
6480 else if (initialpgrp != getpgrp()) {
6481 killpg(initialpgrp, SIGTTIN);
6485 #ifdef OLD_TTY_DRIVER
6486 if (ioctl(2, TIOCGETD, (char *)&ldisc) < 0 || ldisc != NTTYDISC) {
6487 out2str("sh: need new tty driver to run job control; job control turned off\n");
6495 setpgid(0, rootpid);
6496 #ifdef OLD_TTY_DRIVER
6497 ioctl(2, TIOCSPGRP, (char *)&rootpid);
6499 tcsetpgrp(2, rootpid);
6501 } else { /* turning job control off */
6502 setpgid(0, initialpgrp);
6503 #ifdef OLD_TTY_DRIVER
6504 ioctl(2, TIOCSPGRP, (char *)&initialpgrp);
6506 tcsetpgrp(2, initialpgrp);
6517 /* A translation list so we can be polite to our users. */
6518 static char *signal_names[NSIG + 2] = {
6606 "Usage: kill [-s sigspec | -signum | -sigspec] [pid | job]... or\n"
6607 "kill -l [exitstatus]"
6611 if (*argv[1] == '-') {
6612 signo = decode_signal(argv[1] + 1, 1);
6616 while ((c = nextopt("ls:")) != '\0')
6622 signo = decode_signal(optionarg, 1);
6625 "invalid signal number or name: %s",
6633 "nextopt returned character code 0%o", c);
6640 if (!list && signo < 0)
6643 if ((signo < 0 || !*argptr) ^ list) {
6650 for (i = 1; i < NSIG; i++) {
6651 printf(snlfmt, signal_names[i] + 3);
6655 signo = atoi(*argptr);
6658 if (0 < signo && signo < NSIG)
6659 printf(snlfmt, signal_names[signo] + 3);
6661 error("invalid signal number or exit status: %s",
6667 if (**argptr == '%') {
6668 jp = getjob(*argptr);
6669 if (jp->jobctl == 0)
6670 error("job %s not created under job control",
6672 pid = -jp->ps[0].pid;
6674 pid = atoi(*argptr);
6675 if (kill(pid, signo) != 0)
6676 error("%s: %m", *argptr);
6677 } while (*++argptr);
6691 jp = getjob(argv[1]);
6692 if (jp->jobctl == 0)
6693 error("job not created under job control");
6694 pgrp = jp->ps[0].pid;
6695 #ifdef OLD_TTY_DRIVER
6696 ioctl(2, TIOCSPGRP, (char *)&pgrp);
6702 status = waitforjob(jp);
6716 jp = getjob(*++argv);
6717 if (jp->jobctl == 0)
6718 error("job not created under job control");
6720 } while (--argc > 1);
6729 struct procstat *ps;
6732 if (jp->state == JOBDONE)
6735 killpg(jp->ps[0].pid, SIGCONT);
6736 for (ps = jp->ps, i = jp->nprocs ; --i >= 0 ; ps++) {
6737 if (WIFSTOPPED(ps->status)) {
6746 static void showjobs(int change);
6760 * Print a list of jobs. If "change" is nonzero, only print jobs whose
6761 * statuses have changed since the last call to showjobs.
6763 * If the shell is interrupted in the process of creating a job, the
6764 * result may be a job structure containing zero processes. Such structures
6765 * will be freed here.
6776 struct procstat *ps;
6780 TRACE(("showjobs(%d) called\n", change));
6781 while (dowait(0, (struct job *)NULL) > 0);
6782 for (jobno = 1, jp = jobtab ; jobno <= njobs ; jobno++, jp++) {
6785 if (jp->nprocs == 0) {
6789 if (change && ! jp->changed)
6791 procno = jp->nprocs;
6792 for (ps = jp->ps ; ; ps++) { /* for each process */
6794 snprintf(s, 64, "[%d] %ld ", jobno,
6797 snprintf(s, 64, " %ld ",
6802 if (ps->status == -1) {
6803 /* don't print anything */
6804 } else if (WIFEXITED(ps->status)) {
6805 snprintf(s, 64, "Exit %d",
6806 WEXITSTATUS(ps->status));
6809 if (WIFSTOPPED(ps->status))
6810 i = WSTOPSIG(ps->status);
6811 else /* WIFSIGNALED(ps->status) */
6813 i = WTERMSIG(ps->status);
6814 if ((i & 0x7F) < NSIG && sys_siglist[i & 0x7F])
6815 strcpy(s, sys_siglist[i & 0x7F]);
6817 snprintf(s, 64, "Signal %d", i & 0x7F);
6818 if (WCOREDUMP(ps->status))
6819 strcat(s, " (core dumped)");
6824 "%*c%s\n", 30 - col >= 0 ? 30 - col : 0, ' ',
6831 if (jp->state == JOBDONE) {
6839 * Mark a job structure as unused.
6843 freejob(struct job *jp)
6845 const struct procstat *ps;
6849 for (i = jp->nprocs, ps = jp->ps ; --i >= 0 ; ps++) {
6850 if (ps->cmd != nullstr)
6853 if (jp->ps != &jp->ps0)
6857 if (curjob == jp - jobtab + 1)
6876 job = getjob(*++argv);
6880 for (;;) { /* loop until process terminated or stopped */
6883 status = job->ps[job->nprocs - 1].status;
6889 if (WIFEXITED(status))
6890 retval = WEXITSTATUS(status);
6892 else if (WIFSTOPPED(status))
6893 retval = WSTOPSIG(status) + 128;
6896 /* XXX: limits number of signals */
6897 retval = WTERMSIG(status) + 128;
6902 for (jp = jobtab ; ; jp++) {
6903 if (jp >= jobtab + njobs) { /* no running procs */
6906 if (jp->used && jp->state == 0)
6910 if (dowait(2, 0) < 0 && errno == EINTR) {
6919 * Convert a job name to a job structure.
6923 getjob(const char *name)
6933 if ((jobno = curjob) == 0 || jobtab[jobno - 1].used == 0)
6934 error("No current job");
6935 return &jobtab[jobno - 1];
6937 error("No current job");
6939 } else if (name[0] == '%') {
6940 if (is_digit(name[1])) {
6941 jobno = number(name + 1);
6942 if (jobno > 0 && jobno <= njobs
6943 && jobtab[jobno - 1].used != 0)
6944 return &jobtab[jobno - 1];
6946 } else if (name[1] == '%' && name[2] == '\0') {
6950 struct job *found = NULL;
6951 for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) {
6952 if (jp->used && jp->nprocs > 0
6953 && prefix(name + 1, jp->ps[0].cmd)) {
6955 error("%s: ambiguous", name);
6962 } else if (is_number(name, &pid)) {
6963 for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) {
6964 if (jp->used && jp->nprocs > 0
6965 && jp->ps[jp->nprocs - 1].pid == pid)
6969 error("No such job: %s", name);
6976 * Return a new job structure,
6980 makejob(const union node *node, int nprocs)
6985 for (i = njobs, jp = jobtab ; ; jp++) {
6989 jobtab = ckmalloc(4 * sizeof jobtab[0]);
6991 jp = ckmalloc((njobs + 4) * sizeof jobtab[0]);
6992 memcpy(jp, jobtab, njobs * sizeof jp[0]);
6993 /* Relocate `ps' pointers */
6994 for (i = 0; i < njobs; i++)
6995 if (jp[i].ps == &jobtab[i].ps0)
6996 jp[i].ps = &jp[i].ps0;
7000 jp = jobtab + njobs;
7001 for (i = 4 ; --i >= 0 ; jobtab[njobs++].used = 0);
7014 jp->jobctl = jobctl;
7017 jp->ps = ckmalloc(nprocs * sizeof (struct procstat));
7022 TRACE(("makejob(0x%lx, %d) returns %%%d\n", (long)node, nprocs,
7029 * Fork of a subshell. If we are doing job control, give the subshell its
7030 * own process group. Jp is a job structure that the job is to be added to.
7031 * N is the command that will be evaluated by the child. Both jp and n may
7032 * be NULL. The mode parameter can be one of the following:
7033 * FORK_FG - Fork off a foreground process.
7034 * FORK_BG - Fork off a background process.
7035 * FORK_NOJOB - Like FORK_FG, but don't give the process its own
7036 * process group even if job control is on.
7038 * When job control is turned off, background processes have their standard
7039 * input redirected to /dev/null (except for the second and later processes
7046 forkshell(struct job *jp, const union node *n, int mode)
7052 const char *devnull = _PATH_DEVNULL;
7053 const char *nullerr = "Can't open %s";
7055 TRACE(("forkshell(%%%d, 0x%lx, %d) called\n", jp - jobtab, (long)n,
7060 TRACE(("Fork failed, errno=%d\n", errno));
7062 error("Cannot fork");
7069 TRACE(("Child shell %d\n", getpid()));
7070 wasroot = rootshell;
7076 jobctl = 0; /* do job control only in root shell */
7077 if (wasroot && mode != FORK_NOJOB && mflag) {
7078 if (jp == NULL || jp->nprocs == 0)
7081 pgrp = jp->ps[0].pid;
7083 if (mode == FORK_FG) {
7084 /*** this causes superfluous TIOCSPGRPS ***/
7085 #ifdef OLD_TTY_DRIVER
7086 if (ioctl(2, TIOCSPGRP, (char *)&pgrp) < 0)
7087 error("TIOCSPGRP failed, errno=%d", errno);
7089 if (tcsetpgrp(2, pgrp) < 0)
7090 error("tcsetpgrp failed, errno=%d", errno);
7095 } else if (mode == FORK_BG) {
7098 if ((jp == NULL || jp->nprocs == 0) &&
7099 ! fd0_redirected_p ()) {
7101 if (open(devnull, O_RDONLY) != 0)
7102 error(nullerr, devnull);
7106 if (mode == FORK_BG) {
7109 if ((jp == NULL || jp->nprocs == 0) &&
7110 ! fd0_redirected_p ()) {
7112 if (open(devnull, O_RDONLY) != 0)
7113 error(nullerr, devnull);
7117 for (i = njobs, p = jobtab ; --i >= 0 ; p++)
7120 if (wasroot && iflag) {
7128 if (rootshell && mode != FORK_NOJOB && mflag) {
7129 if (jp == NULL || jp->nprocs == 0)
7132 pgrp = jp->ps[0].pid;
7136 if (mode == FORK_BG)
7137 backgndpid = pid; /* set $! */
7139 struct procstat *ps = &jp->ps[jp->nprocs++];
7143 if (iflag && rootshell && n)
7144 ps->cmd = commandtext(n);
7147 TRACE(("In parent shell: child = %d\n", pid));
7154 * Wait for job to finish.
7156 * Under job control we have the problem that while a child process is
7157 * running interrupts generated by the user are sent to the child but not
7158 * to the shell. This means that an infinite loop started by an inter-
7159 * active user may be hard to kill. With job control turned off, an
7160 * interactive user may place an interactive program inside a loop. If
7161 * the interactive program catches interrupts, the user doesn't want
7162 * these interrupts to also abort the loop. The approach we take here
7163 * is to have the shell ignore interrupt signals while waiting for a
7164 * forground process to terminate, and then send itself an interrupt
7165 * signal if the child process was terminated by an interrupt signal.
7166 * Unfortunately, some programs want to do a bit of cleanup and then
7167 * exit on interrupt; unless these processes terminate themselves by
7168 * sending a signal to themselves (instead of calling exit) they will
7169 * confuse this approach.
7173 waitforjob(struct job *jp)
7176 int mypgrp = getpgrp();
7180 struct sigaction act, oact;
7189 sigaction(SIGINT, 0, &act);
7190 act.sa_handler = waitonint;
7191 sigaction(SIGINT, &act, &oact);
7193 TRACE(("waitforjob(%%%d) called\n", jp - jobtab + 1));
7194 while (jp->state == 0) {
7202 sigaction(SIGINT, &oact, 0);
7203 if (intreceived && trap[SIGINT]) kill(getpid(), SIGINT);
7207 #ifdef OLD_TTY_DRIVER
7208 if (ioctl(2, TIOCSPGRP, (char *)&mypgrp) < 0)
7209 error("TIOCSPGRP failed, errno=%d\n", errno);
7211 if (tcsetpgrp(2, mypgrp) < 0)
7212 error("tcsetpgrp failed, errno=%d\n", errno);
7215 if (jp->state == JOBSTOPPED)
7216 curjob = jp - jobtab + 1;
7218 status = jp->ps[jp->nprocs - 1].status;
7219 /* convert to 8 bits */
7220 if (WIFEXITED(status))
7221 st = WEXITSTATUS(status);
7223 else if (WIFSTOPPED(status))
7224 st = WSTOPSIG(status) + 128;
7227 st = WTERMSIG(status) + 128;
7231 * This is truly gross.
7232 * If we're doing job control, then we did a TIOCSPGRP which
7233 * caused us (the shell) to no longer be in the controlling
7234 * session -- so we wouldn't have seen any ^C/SIGINT. So, we
7235 * intuit from the subprocess exit status whether a SIGINT
7236 * occured, and if so interrupt ourselves. Yuck. - mycroft
7238 if (WIFSIGNALED(status) && WTERMSIG(status) == SIGINT)
7241 if (jp->state == JOBDONE)
7252 * Wait for a process to terminate.
7256 * Do a wait system call. If job control is compiled in, we accept
7257 * stopped processes. If block is zero, we return a value of zero
7258 * rather than blocking.
7260 * System V doesn't have a non-blocking wait system call. It does
7261 * have a SIGCLD signal that is sent to a process when one of it's
7262 * children dies. The obvious way to use SIGCLD would be to install
7263 * a handler for SIGCLD which simply bumped a counter when a SIGCLD
7264 * was received, and have waitproc bump another counter when it got
7265 * the status of a process. Waitproc would then know that a wait
7266 * system call would not block if the two counters were different.
7267 * This approach doesn't work because if a process has children that
7268 * have not been waited for, System V will send it a SIGCLD when it
7269 * installs a signal handler for SIGCLD. What this means is that when
7270 * a child exits, the shell will be sent SIGCLD signals continuously
7271 * until is runs out of stack space, unless it does a wait call before
7272 * restoring the signal handler. The code below takes advantage of
7273 * this (mis)feature by installing a signal handler for SIGCLD and
7274 * then checking to see whether it was called. If there are any
7275 * children to be waited for, it will be.
7280 waitproc(int block, int *status)
7291 return wait3(status, flags, (struct rusage *)NULL);
7295 dowait(int block, struct job *job)
7299 struct procstat *sp;
7301 struct job *thisjob;
7307 TRACE(("dowait(%d) called\n", block));
7309 pid = waitproc(block, &status);
7310 TRACE(("wait returns %d, status=%d\n", pid, status));
7311 } while (!(block & 2) && pid == -1 && errno == EINTR);
7316 for (jp = jobtab ; jp < jobtab + njobs ; jp++) {
7320 for (sp = jp->ps ; sp < jp->ps + jp->nprocs ; sp++) {
7323 if (sp->pid == pid) {
7324 TRACE(("Changing status of proc %d from 0x%x to 0x%x\n", pid, sp->status, status));
7325 sp->status = status;
7328 if (sp->status == -1)
7330 else if (WIFSTOPPED(sp->status))
7333 if (stopped) { /* stopped or done */
7334 int state = done? JOBDONE : JOBSTOPPED;
7335 if (jp->state != state) {
7336 TRACE(("Job %d: changing state from %d to %d\n", jp - jobtab + 1, jp->state, state));
7339 if (done && curjob == jp - jobtab + 1)
7340 curjob = 0; /* no current job */
7347 if (! rootshell || ! iflag || (job && thisjob == job)) {
7348 core = WCOREDUMP(status);
7350 if (WIFSTOPPED(status)) sig = WSTOPSIG(status);
7353 if (WIFEXITED(status)) sig = 0;
7354 else sig = WTERMSIG(status);
7356 if (sig != 0 && sig != SIGINT && sig != SIGPIPE) {
7358 out2fmt("%d: ", pid);
7360 if (sig == SIGTSTP && rootshell && iflag)
7362 (long)(job - jobtab + 1));
7364 if (sig < NSIG && sys_siglist[sig])
7365 out2str(sys_siglist[sig]);
7367 out2fmt("Signal %d", sig);
7369 out2str(" - core dumped");
7372 TRACE(("Not printing status: status=%d, sig=%d\n",
7376 TRACE(("Not printing status, rootshell=%d, job=0x%x\n", rootshell, job));
7378 thisjob->changed = 1;
7387 * return 1 if there are stopped jobs, otherwise 0
7397 for (jobno = 1, jp = jobtab; jobno <= njobs; jobno++, jp++) {
7400 if (jp->state == JOBSTOPPED) {
7401 out2str("You have stopped jobs.\n");
7411 * Return a string identifying a command (to be printed by the
7415 static char *cmdnextc;
7416 static int cmdnleft;
7417 #define MAXCMDTEXT 200
7420 cmdputs(const char *s)
7431 while ((c = *p++) != '\0') {
7434 else if (c == CTLVAR) {
7439 } else if (c == '=' && subtype != 0) {
7440 *q++ = "}-+?="[(subtype & VSTYPE) - VSNORMAL];
7442 } else if (c == CTLENDVAR) {
7444 } else if (c == CTLBACKQ || c == CTLBACKQ+CTLQUOTE)
7445 cmdnleft++; /* ignore it */
7448 if (--cmdnleft <= 0) {
7460 cmdtxt(const union node *n)
7463 struct nodelist *lp;
7472 cmdtxt(n->nbinary.ch1);
7474 cmdtxt(n->nbinary.ch2);
7477 cmdtxt(n->nbinary.ch1);
7479 cmdtxt(n->nbinary.ch2);
7482 cmdtxt(n->nbinary.ch1);
7484 cmdtxt(n->nbinary.ch2);
7487 for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
7495 cmdtxt(n->nredir.n);
7500 cmdtxt(n->nredir.n);
7504 cmdtxt(n->nif.test);
7506 cmdtxt(n->nif.ifpart);
7515 cmdtxt(n->nbinary.ch1);
7517 cmdtxt(n->nbinary.ch2);
7522 cmdputs(n->nfor.var);
7527 cmdputs(n->ncase.expr->narg.text);
7531 cmdputs(n->narg.text);
7535 for (np = n->ncmd.args ; np ; np = np->narg.next) {
7540 for (np = n->ncmd.redirect ; np ; np = np->nfile.next) {
7546 cmdputs(n->narg.text);
7549 p = ">"; i = 1; goto redir;
7551 p = ">>"; i = 1; goto redir;
7553 p = ">&"; i = 1; goto redir;
7555 p = ">|"; i = 1; goto redir;
7557 p = "<"; i = 0; goto redir;
7559 p = "<&"; i = 0; goto redir;
7561 p = "<>"; i = 0; goto redir;
7563 if (n->nfile.fd != i) {
7564 s[0] = n->nfile.fd + '0';
7569 if (n->type == NTOFD || n->type == NFROMFD) {
7570 s[0] = n->ndup.dupfd + '0';
7574 cmdtxt(n->nfile.fname);
7589 commandtext(const union node *n)
7593 cmdnextc = name = ckmalloc(MAXCMDTEXT);
7594 cmdnleft = MAXCMDTEXT - 4;
7601 static void waitonint(int sig) {
7606 * Routines to check for mail. (Perhaps make part of main.c?)
7610 #define MAXMBOXES 10
7613 static int nmboxes; /* number of mailboxes */
7614 static time_t mailtime[MAXMBOXES]; /* times of mailboxes */
7619 * Print appropriate message(s) if mail has arrived. If the argument is
7620 * nozero, then the value of MAIL has changed, so we just update the
7631 struct stackmark smark;
7638 setstackmark(&smark);
7639 mpath = mpathset()? mpathval() : mailval();
7640 for (i = 0 ; i < nmboxes ; i++) {
7641 p = padvance(&mpath, nullstr);
7646 for (q = p ; *q ; q++);
7651 q[-1] = '\0'; /* delete trailing '/' */
7652 if (stat(p, &statb) < 0)
7654 if (statb.st_size > mailtime[i] && ! silent) {
7656 pathopt? pathopt : "you have mail");
7658 mailtime[i] = statb.st_size;
7661 popstackmark(&smark);
7667 static short profile_buf[16384];
7671 static void read_profile (const char *);
7672 static void cmdloop (int);
7673 static void options (int);
7674 static void setoption (int, int);
7675 static void procargs (int, char **);
7679 * Main routine. We initialize things, parse the arguments, execute
7680 * profiles if we're a login shell, and then call cmdloop to execute
7681 * commands. The setjmp call sets up the location to jump to when an
7682 * exception occurs. When an exception occurs the variable "state"
7683 * is used to figure out how far we had gotten.
7687 shell_main(argc, argv)
7691 struct jmploc jmploc;
7692 struct stackmark smark;
7696 BLTINCMD = find_builtin("builtin");
7697 EXECCMD = find_builtin("exec");
7698 EVALCMD = find_builtin("eval");
7700 #ifndef BB_FEATURE_SH_FANCY_PROMPT
7706 monitor(4, etext, profile_buf, sizeof profile_buf, 50);
7708 #if defined(linux) || defined(__GNU__)
7709 signal(SIGCHLD, SIG_DFL);
7712 if (setjmp(jmploc.loc)) {
7715 * When a shell procedure is executed, we raise the
7716 * exception EXSHELLPROC to clean up before executing
7717 * the shell procedure.
7719 switch (exception) {
7728 exitstatus = exerrno;
7739 if (exception != EXSHELLPROC) {
7740 if (state == 0 || iflag == 0 || ! rootshell)
7741 exitshell(exitstatus);
7744 if (exception == EXINT) {
7747 popstackmark(&smark);
7748 FORCEINTON; /* enable interrupts */
7751 else if (state == 2)
7753 else if (state == 3)
7761 trputs("Shell args: "); trargs(argv);
7766 setstackmark(&smark);
7767 procargs(argc, argv);
7768 if (argv[0] && argv[0][0] == '-') {
7770 read_profile("/etc/profile");
7773 read_profile(".profile");
7778 if (getuid() == geteuid() && getgid() == getegid()) {
7780 if ((shinit = lookupvar("ENV")) != NULL && *shinit != '\0') {
7782 read_profile(shinit);
7789 if (sflag == 0 || minusc) {
7790 static int sigs[] = {
7791 SIGINT, SIGQUIT, SIGHUP,
7797 #define SIGSSIZE (sizeof(sigs)/sizeof(sigs[0]))
7800 for (i = 0; i < SIGSSIZE; i++)
7805 evalstring(minusc, 0);
7807 if (sflag || minusc == NULL) {
7808 state4: /* XXX ??? - why isn't this before the "if" statement */
7814 exitshell(exitstatus);
7820 * Read and execute commands. "Top" is nonzero for the top level command
7821 * loop; it turns on prompting if the shell is interactive.
7828 struct stackmark smark;
7832 TRACE(("cmdloop(%d) called\n", top));
7833 setstackmark(&smark);
7844 n = parsecmd(inter);
7845 /* showtree(n); DEBUG */
7847 if (!top || numeof >= 50)
7849 if (!stoppedjobs()) {
7852 out2str("\nUse \"exit\" to leave shell.\n");
7855 } else if (n != NULL && nflag == 0) {
7856 job_warning = (job_warning == 2) ? 1 : 0;
7860 popstackmark(&smark);
7861 setstackmark(&smark);
7862 if (evalskip == SKIPFILE) {
7867 popstackmark(&smark);
7873 * Read /etc/profile or .profile. Return on error.
7885 if ((fd = open(name, O_RDONLY)) >= 0)
7890 /* -q turns off -x and -v just when executing init files */
7893 xflag = 0, xflag_set = 1;
7895 vflag = 0, vflag_set = 1;
7910 * Read a file containing shell functions.
7914 readcmdfile(const char *name)
7919 if ((fd = open(name, O_RDONLY)) >= 0)
7922 error("Can't open %s", name);
7931 * Take commands from a file. To be compatable we should do a path
7932 * search for the file, which is necessary to find sub-commands.
7936 static inline char *
7937 find_dot_file(mybasename)
7941 const char *path = pathval();
7944 /* don't try this for absolute or relative paths */
7945 if (strchr(mybasename, '/'))
7948 while ((fullname = padvance(&path, mybasename)) != NULL) {
7949 if ((stat(fullname, &statb) == 0) && S_ISREG(statb.st_mode)) {
7951 * Don't bother freeing here, since it will
7952 * be freed by the caller.
7956 stunalloc(fullname);
7959 /* not found in the PATH */
7960 error("%s: not found", mybasename);
7972 for (sp = cmdenviron; sp ; sp = sp->next)
7973 setvareq(savestr(sp->text), VSTRFIXED|VTEXTFIXED);
7975 if (argc >= 2) { /* That's what SVR2 does */
7977 struct stackmark smark;
7979 setstackmark(&smark);
7980 fullname = find_dot_file(argv[1]);
7981 setinputfile(fullname, 1);
7982 commandname = fullname;
7985 popstackmark(&smark);
7999 exitstatus = number(argv[1]);
8001 exitstatus = oexitstatus;
8002 exitshell(exitstatus);
8011 nbytes = ALIGN(nbytes);
8012 if (nbytes > stacknleft) {
8014 struct stack_block *sp;
8017 if (blocksize < MINSIZE)
8018 blocksize = MINSIZE;
8020 sp = ckmalloc(sizeof(struct stack_block) - MINSIZE + blocksize);
8022 stacknxt = sp->space;
8023 stacknleft = blocksize;
8029 stacknleft -= nbytes;
8035 stunalloc(pointer p)
8038 if (p == NULL) { /*DEBUG */
8039 write(2, "stunalloc\n", 10);
8043 if (!(stacknxt >= (char *)p && (char *)p >= stackp->space)) {
8046 stacknleft += stacknxt - (char *)p;
8052 setstackmark(struct stackmark *mark)
8054 mark->stackp = stackp;
8055 mark->stacknxt = stacknxt;
8056 mark->stacknleft = stacknleft;
8057 mark->marknext = markp;
8063 popstackmark(struct stackmark *mark)
8065 struct stack_block *sp;
8068 markp = mark->marknext;
8069 while (stackp != mark->stackp) {
8074 stacknxt = mark->stacknxt;
8075 stacknleft = mark->stacknleft;
8081 * When the parser reads in a string, it wants to stick the string on the
8082 * stack and only adjust the stack pointer when it knows how big the
8083 * string is. Stackblock (defined in stack.h) returns a pointer to a block
8084 * of space on top of the stack and stackblocklen returns the length of
8085 * this block. Growstackblock will grow this space by at least one byte,
8086 * possibly moving it (like realloc). Grabstackblock actually allocates the
8087 * part of the block that has been used.
8091 growstackblock(void) {
8093 int newlen = ALIGN(stacknleft * 2 + 100);
8094 char *oldspace = stacknxt;
8095 int oldlen = stacknleft;
8096 struct stack_block *sp;
8097 struct stack_block *oldstackp;
8099 if (stacknxt == stackp->space && stackp != &stackbase) {
8104 sp = ckrealloc((pointer)sp, sizeof(struct stack_block) - MINSIZE + newlen);
8107 stacknxt = sp->space;
8108 stacknleft = newlen;
8110 /* Stack marks pointing to the start of the old block
8111 * must be relocated to point to the new block
8113 struct stackmark *xmark;
8115 while (xmark != NULL && xmark->stackp == oldstackp) {
8116 xmark->stackp = stackp;
8117 xmark->stacknxt = stacknxt;
8118 xmark->stacknleft = stacknleft;
8119 xmark = xmark->marknext;
8124 p = stalloc(newlen);
8125 memcpy(p, oldspace, oldlen);
8126 stacknxt = p; /* free the space */
8127 stacknleft += newlen; /* we just allocated */
8134 grabstackblock(int len)
8144 * The following routines are somewhat easier to use that the above.
8145 * The user declares a variable of type STACKSTR, which may be declared
8146 * to be a register. The macro STARTSTACKSTR initializes things. Then
8147 * the user uses the macro STPUTC to add characters to the string. In
8148 * effect, STPUTC(c, p) is the same as *p++ = c except that the stack is
8149 * grown as necessary. When the user is done, she can just leave the
8150 * string there and refer to it using stackblock(). Or she can allocate
8151 * the space for it using grabstackstr(). If it is necessary to allow
8152 * someone else to use the stack temporarily and then continue to grow
8153 * the string, the user should use grabstack to allocate the space, and
8154 * then call ungrabstr(p) to return to the previous mode of operation.
8156 * USTPUTC is like STPUTC except that it doesn't check for overflow.
8157 * CHECKSTACKSPACE can be called before USTPUTC to ensure that there
8158 * is space for at least one character.
8163 growstackstr(void) {
8164 int len = stackblocksize();
8165 if (herefd >= 0 && len >= 1024) {
8166 xwrite(herefd, stackblock(), len);
8167 sstrnleft = len - 1;
8168 return stackblock();
8171 sstrnleft = stackblocksize() - len - 1;
8172 return stackblock() + len;
8177 * Called from CHECKSTRSPACE.
8181 makestrspace(size_t newlen) {
8182 int len = stackblocksize() - sstrnleft;
8185 sstrnleft = stackblocksize() - len;
8186 } while (sstrnleft < newlen);
8187 return stackblock() + len;
8193 ungrabstackstr(char *s, char *p)
8195 stacknleft += stacknxt - s;
8197 sstrnleft = stacknleft - (p - s);
8200 * Miscelaneous builtins.
8207 static mode_t getmode(const void *, mode_t);
8208 static void *setmode(const char *);
8211 #if !defined(__GLIBC__) || __GLIBC__ == 2 && __GLIBC_MINOR__ < 1
8212 typedef long rlim_t;
8218 * The read builtin. The -e option causes backslashes to escape the
8219 * following character.
8221 * This uses unbuffered input, which may be avoidable in some cases.
8242 while ((i = nextopt("p:r")) != '\0') {
8248 if (prompt && isatty(0)) {
8252 if (*(ap = argptr) == NULL)
8254 if ((ifs = bltinlookup("IFS")) == NULL)
8261 if (read(0, &c, 1) != 1) {
8273 if (!rflag && c == '\\') {
8279 if (startword && *ifs == ' ' && strchr(ifs, c)) {
8283 if (backslash && c == '\\') {
8284 if (read(0, &c, 1) != 1) {
8289 } else if (ap[1] != NULL && strchr(ifs, c) != NULL) {
8291 setvar(*ap, stackblock(), 0);
8300 /* Remove trailing blanks */
8301 while (stackblock() <= --p && strchr(ifs, *p) != NULL)
8303 setvar(*ap, stackblock(), 0);
8304 while (*++ap != NULL)
8305 setvar(*ap, nullstr, 0);
8312 umaskcmd(argc, argv)
8319 int symbolic_mode = 0;
8321 while (nextopt("S") != '\0') {
8330 if ((ap = *argptr) == NULL) {
8331 if (symbolic_mode) {
8332 char u[4], g[4], o[4];
8335 if ((mask & S_IRUSR) == 0)
8337 if ((mask & S_IWUSR) == 0)
8339 if ((mask & S_IXUSR) == 0)
8344 if ((mask & S_IRGRP) == 0)
8346 if ((mask & S_IWGRP) == 0)
8348 if ((mask & S_IXGRP) == 0)
8353 if ((mask & S_IROTH) == 0)
8355 if ((mask & S_IWOTH) == 0)
8357 if ((mask & S_IXOTH) == 0)
8361 printf("u=%s,g=%s,o=%s\n", u, g, o);
8363 printf("%.4o\n", mask);
8366 if (is_digit((unsigned char)*ap)) {
8369 if (*ap >= '8' || *ap < '0')
8370 error("Illegal number: %s", argv[1]);
8371 mask = (mask << 3) + (*ap - '0');
8372 } while (*++ap != '\0');
8378 if ((set = setmode(ap)) != 0) {
8379 mask = getmode(set, ~mask & 0777);
8384 error("Illegal mode: %s", ap);
8386 umask(~mask & 0777);
8395 * This code, originally by Doug Gwyn, Doug Kingston, Eric Gisin, and
8396 * Michael Rendell was ripped from pdksh 5.0.8 and hacked for use with
8397 * ash by J.T. Conklin.
8405 int factor; /* multiply by to get rlim_{cur,max} values */
8409 static const struct limits limits[] = {
8411 { "time(seconds)", RLIMIT_CPU, 1, 't' },
8414 { "file(blocks)", RLIMIT_FSIZE, 512, 'f' },
8417 { "data(kbytes)", RLIMIT_DATA, 1024, 'd' },
8420 { "stack(kbytes)", RLIMIT_STACK, 1024, 's' },
8423 { "coredump(blocks)", RLIMIT_CORE, 512, 'c' },
8426 { "memory(kbytes)", RLIMIT_RSS, 1024, 'm' },
8428 #ifdef RLIMIT_MEMLOCK
8429 { "locked memory(kbytes)", RLIMIT_MEMLOCK, 1024, 'l' },
8432 { "process(processes)", RLIMIT_NPROC, 1, 'p' },
8434 #ifdef RLIMIT_NOFILE
8435 { "nofiles(descriptors)", RLIMIT_NOFILE, 1, 'n' },
8438 { "vmemory(kbytes)", RLIMIT_VMEM, 1024, 'v' },
8441 { "swap(kbytes)", RLIMIT_SWAP, 1024, 'w' },
8443 { (char *) 0, 0, 0, '\0' }
8447 ulimitcmd(argc, argv)
8453 enum { SOFT = 0x1, HARD = 0x2 }
8455 const struct limits *l;
8458 struct rlimit limit;
8461 while ((optc = nextopt("HSatfdsmcnpl")) != '\0')
8476 for (l = limits; l->name && l->option != what; l++)
8479 error("internal error (%c)", what);
8481 set = *argptr ? 1 : 0;
8485 if (all || argptr[1])
8486 error("too many arguments");
8487 if (strcmp(p, "unlimited") == 0)
8488 val = RLIM_INFINITY;
8492 while ((c = *p++) >= '0' && c <= '9')
8494 val = (val * 10) + (long)(c - '0');
8495 if (val < (rlim_t) 0)
8499 error("bad number");
8504 for (l = limits; l->name; l++) {
8505 getrlimit(l->cmd, &limit);
8507 val = limit.rlim_cur;
8508 else if (how & HARD)
8509 val = limit.rlim_max;
8511 printf("%-20s ", l->name);
8512 if (val == RLIM_INFINITY)
8513 printf("unlimited\n");
8517 printf("%lld\n", (long long) val);
8523 getrlimit(l->cmd, &limit);
8526 limit.rlim_max = val;
8528 limit.rlim_cur = val;
8529 if (setrlimit(l->cmd, &limit) < 0)
8530 error("error setting limit (%m)");
8533 val = limit.rlim_cur;
8534 else if (how & HARD)
8535 val = limit.rlim_max;
8537 if (val == RLIM_INFINITY)
8538 printf("unlimited\n");
8542 printf("%lld\n", (long long) val);
8548 * prefix -- see if pfx is a prefix of string.
8552 prefix(char const *pfx, char const *string)
8555 if (*pfx++ != *string++)
8562 * Return true if s is a string of digits, and save munber in intptr
8567 is_number(const char *p, int *intptr)
8575 ret += digit_val(*p);
8577 } while (*p != '\0');
8584 * Convert a string of digits to an integer, printing an error message on
8589 number(const char *s)
8592 if (! is_number(s, &i))
8593 error("Illegal number: %s", s);
8598 * Produce a possibly single quoted string suitable as input to the shell.
8599 * The return string is allocated on the stack.
8603 single_quote(const char *s) {
8610 size_t len1, len1p, len2, len2p;
8612 len1 = strcspn(s, "'");
8613 len2 = strspn(s + len1, "'");
8615 len1p = len1 ? len1 + 2 : len1;
8627 CHECKSTRSPACE(len1p + len2p + 1, p);
8632 memcpy(p + 1, s, len1);
8648 memcpy(q + 1, s, len2);
8653 STADJUST(len1p + len2p, p);
8658 return grabstackstr(p);
8662 * Like strdup but works with the ash stack.
8666 sstrdup(const char *p)
8668 size_t len = strlen(p) + 1;
8669 return memcpy(stalloc(len), p, len);
8674 * Routine for dealing with parsed shell commands.
8678 static void sizenodelist (const struct nodelist *);
8679 static struct nodelist *copynodelist (const struct nodelist *);
8680 static char *nodesavestr (const char *);
8683 calcsize(const union node *n)
8687 funcblocksize += nodesize[n->type];
8694 calcsize(n->nbinary.ch2);
8695 calcsize(n->nbinary.ch1);
8698 calcsize(n->ncmd.redirect);
8699 calcsize(n->ncmd.args);
8700 calcsize(n->ncmd.assign);
8703 sizenodelist(n->npipe.cmdlist);
8708 calcsize(n->nredir.redirect);
8709 calcsize(n->nredir.n);
8712 calcsize(n->nif.elsepart);
8713 calcsize(n->nif.ifpart);
8714 calcsize(n->nif.test);
8717 funcstringsize += strlen(n->nfor.var) + 1;
8718 calcsize(n->nfor.body);
8719 calcsize(n->nfor.args);
8722 calcsize(n->ncase.cases);
8723 calcsize(n->ncase.expr);
8726 calcsize(n->nclist.body);
8727 calcsize(n->nclist.pattern);
8728 calcsize(n->nclist.next);
8732 sizenodelist(n->narg.backquote);
8733 funcstringsize += strlen(n->narg.text) + 1;
8734 calcsize(n->narg.next);
8741 calcsize(n->nfile.fname);
8742 calcsize(n->nfile.next);
8746 calcsize(n->ndup.vname);
8747 calcsize(n->ndup.next);
8751 calcsize(n->nhere.doc);
8752 calcsize(n->nhere.next);
8755 calcsize(n->nnot.com);
8761 sizenodelist(const struct nodelist *lp)
8764 funcblocksize += ALIGN(sizeof(struct nodelist));
8772 copynode(const union node *n)
8779 funcblock = (char *) funcblock + nodesize[n->type];
8786 new->nbinary.ch2 = copynode(n->nbinary.ch2);
8787 new->nbinary.ch1 = copynode(n->nbinary.ch1);
8790 new->ncmd.redirect = copynode(n->ncmd.redirect);
8791 new->ncmd.args = copynode(n->ncmd.args);
8792 new->ncmd.assign = copynode(n->ncmd.assign);
8793 new->ncmd.backgnd = n->ncmd.backgnd;
8796 new->npipe.cmdlist = copynodelist(n->npipe.cmdlist);
8797 new->npipe.backgnd = n->npipe.backgnd;
8802 new->nredir.redirect = copynode(n->nredir.redirect);
8803 new->nredir.n = copynode(n->nredir.n);
8806 new->nif.elsepart = copynode(n->nif.elsepart);
8807 new->nif.ifpart = copynode(n->nif.ifpart);
8808 new->nif.test = copynode(n->nif.test);
8811 new->nfor.var = nodesavestr(n->nfor.var);
8812 new->nfor.body = copynode(n->nfor.body);
8813 new->nfor.args = copynode(n->nfor.args);
8816 new->ncase.cases = copynode(n->ncase.cases);
8817 new->ncase.expr = copynode(n->ncase.expr);
8820 new->nclist.body = copynode(n->nclist.body);
8821 new->nclist.pattern = copynode(n->nclist.pattern);
8822 new->nclist.next = copynode(n->nclist.next);
8826 new->narg.backquote = copynodelist(n->narg.backquote);
8827 new->narg.text = nodesavestr(n->narg.text);
8828 new->narg.next = copynode(n->narg.next);
8835 new->nfile.fname = copynode(n->nfile.fname);
8836 new->nfile.fd = n->nfile.fd;
8837 new->nfile.next = copynode(n->nfile.next);
8841 new->ndup.vname = copynode(n->ndup.vname);
8842 new->ndup.dupfd = n->ndup.dupfd;
8843 new->ndup.fd = n->ndup.fd;
8844 new->ndup.next = copynode(n->ndup.next);
8848 new->nhere.doc = copynode(n->nhere.doc);
8849 new->nhere.fd = n->nhere.fd;
8850 new->nhere.next = copynode(n->nhere.next);
8853 new->nnot.com = copynode(n->nnot.com);
8856 new->type = n->type;
8861 static struct nodelist *
8862 copynodelist(const struct nodelist *lp)
8864 struct nodelist *start;
8865 struct nodelist **lpp;
8870 funcblock = (char *) funcblock + ALIGN(sizeof(struct nodelist));
8871 (*lpp)->n = copynode(lp->n);
8873 lpp = &(*lpp)->next;
8881 nodesavestr(const char *s)
8884 char *rtn = funcstring;
8886 funcstring = stpcpy(funcstring, s) + 1;
8890 char *q = funcstring;
8891 char *rtn = funcstring;
8893 while ((*q++ = *p++) != '\0')
8901 static int getopts (char *, char *, char **, int *, int *);
8906 * Process the shell command line arguments.
8910 procargs(argc, argv)
8919 for (i = 0; i < NOPTS; i++)
8922 if (*argptr == NULL && minusc == NULL)
8924 if (iflag == 2 && sflag == 1 && isatty(0) && isatty(1))
8928 for (i = 0; i < NOPTS; i++)
8929 if (optent_val(i) == 2)
8932 if (sflag == 0 && minusc == NULL) {
8933 commandname = argv[0];
8935 setinputfile(arg0, 0);
8938 /* POSIX 1003.2: first arg after -c cmd is $0, remainder $1... */
8939 if (argptr && minusc && *argptr)
8942 shellparam.p = argptr;
8943 shellparam.optind = 1;
8944 shellparam.optoff = -1;
8945 /* assert(shellparam.malloc == 0 && shellparam.nparam == 0); */
8947 shellparam.nparam++;
8956 * Process shell options. The global variable argptr contains a pointer
8957 * to the argument list; we advance it past the options.
8961 minus_o(const char *name, int val)
8966 out1str("Current option settings\n");
8967 for (i = 0; i < NOPTS; i++)
8968 printf("%-16s%s\n", optent_name(optlist[i]),
8969 optent_val(i) ? "on" : "off");
8971 for (i = 0; i < NOPTS; i++)
8972 if (equal(name, optent_name(optlist[i]))) {
8973 setoption(optent_letter(optlist[i]), val);
8976 error("Illegal option -o %s", name);
8982 options(int cmdline)
8990 while ((p = *argptr) != NULL) {
8992 if ((c = *p++) == '-') {
8994 if (p[0] == '\0' || (p[0] == '-' && p[1] == '\0')) {
8996 /* "-" means turn off -x and -v */
8999 /* "--" means reset params */
9000 else if (*argptr == NULL)
9003 break; /* "-" or "--" terminates options */
9005 } else if (c == '+') {
9011 while ((c = *p++) != '\0') {
9012 if (c == 'c' && cmdline) {
9014 #ifdef NOHACK /* removing this code allows sh -ce 'foo' for compat */
9018 if (q == NULL || minusc != NULL)
9019 error("Bad -c option");
9024 } else if (c == 'o') {
9025 minus_o(*argptr, val);
9037 setoption(int flag, int val)
9041 for (i = 0; i < NOPTS; i++)
9042 if (optent_letter(optlist[i]) == flag) {
9043 optent_val(i) = val;
9045 /* #%$ hack for ksh semantics */
9048 else if (flag == 'E')
9053 error("Illegal option -%c", flag);
9060 * Set the shell parameters.
9064 setparam(char **argv)
9070 for (nparam = 0 ; argv[nparam] ; nparam++);
9071 ap = newparam = ckmalloc((nparam + 1) * sizeof *ap);
9073 *ap++ = savestr(*argv++);
9076 freeparam(&shellparam);
9077 shellparam.malloc = 1;
9078 shellparam.nparam = nparam;
9079 shellparam.p = newparam;
9080 shellparam.optind = 1;
9081 shellparam.optoff = -1;
9086 * Free the list of positional parameters.
9090 freeparam(volatile struct shparam *param)
9094 if (param->malloc) {
9095 for (ap = param->p ; *ap ; ap++)
9104 * The shift builtin command.
9108 shiftcmd(argc, argv)
9117 n = number(argv[1]);
9118 if (n > shellparam.nparam)
9119 error("can't shift that many");
9121 shellparam.nparam -= n;
9122 for (ap1 = shellparam.p ; --n >= 0 ; ap1++) {
9123 if (shellparam.malloc)
9127 while ((*ap2++ = *ap1++) != NULL);
9128 shellparam.optind = 1;
9129 shellparam.optoff = -1;
9137 * The set command builtin.
9146 return showvarscmd(argc, argv);
9150 if (*argptr != NULL) {
9159 getoptsreset(const char *value)
9161 shellparam.optind = number(value);
9162 shellparam.optoff = -1;
9165 #ifdef BB_LOCALE_SUPPORT
9166 static void change_lc_all(const char *value)
9168 if(value != 0 && *value != 0)
9169 setlocale(LC_ALL, value);
9172 static void change_lc_ctype(const char *value)
9174 if(value != 0 && *value != 0)
9175 setlocale(LC_CTYPE, value);
9182 * The getopts builtin. Shellparam.optnext points to the next argument
9183 * to be processed. Shellparam.optptr points to the next character to
9184 * be processed in the current argument. If shellparam.optnext is NULL,
9185 * then it's the first time getopts has been called.
9189 getoptscmd(argc, argv)
9196 error("Usage: getopts optstring var [arg]");
9197 else if (argc == 3) {
9198 optbase = shellparam.p;
9199 if (shellparam.optind > shellparam.nparam + 1) {
9200 shellparam.optind = 1;
9201 shellparam.optoff = -1;
9206 if (shellparam.optind > argc - 2) {
9207 shellparam.optind = 1;
9208 shellparam.optoff = -1;
9212 return getopts(argv[1], argv[2], optbase, &shellparam.optind,
9213 &shellparam.optoff);
9217 * Safe version of setvar, returns 1 on success 0 on failure.
9221 setvarsafe(name, val, flags)
9222 const char *name, *val;
9225 struct jmploc jmploc;
9226 struct jmploc *volatile savehandler = handler;
9232 if (setjmp(jmploc.loc))
9236 setvar(name, val, flags);
9238 handler = savehandler;
9243 getopts(optstr, optvar, optfirst, myoptind, optoff)
9255 char **optnext = optfirst + *myoptind - 1;
9257 if (*myoptind <= 1 || *optoff < 0 || !(*(optnext - 1)) ||
9258 strlen(*(optnext - 1)) < *optoff)
9261 p = *(optnext - 1) + *optoff;
9262 if (p == NULL || *p == '\0') {
9263 /* Current word is done, advance */
9264 if (optnext == NULL)
9267 if (p == NULL || *p != '-' || *++p == '\0') {
9269 *myoptind = optnext - optfirst + 1;
9275 if (p[0] == '-' && p[1] == '\0') /* check for "--" */
9280 for (q = optstr; *q != c; ) {
9282 if (optstr[0] == ':') {
9285 err |= setvarsafe("OPTARG", s, 0);
9288 out2fmt("Illegal option -%c\n", c);
9289 (void) unsetvar("OPTARG");
9299 if (*p == '\0' && (p = *optnext) == NULL) {
9300 if (optstr[0] == ':') {
9303 err |= setvarsafe("OPTARG", s, 0);
9307 out2fmt("No arg for -%c option\n", c);
9308 (void) unsetvar("OPTARG");
9316 setvarsafe("OPTARG", p, 0);
9320 setvarsafe("OPTARG", "", 0);
9321 *myoptind = optnext - optfirst + 1;
9328 *optoff = p ? p - *(optnext - 1) : -1;
9329 snprintf(s, sizeof(s), "%d", *myoptind);
9330 err |= setvarsafe("OPTIND", s, VNOFUNC);
9333 err |= setvarsafe(optvar, s, 0);
9344 * XXX - should get rid of. have all builtins use getopt(3). the
9345 * library getopt must have the BSD extension static variable "optreset"
9346 * otherwise it can't be used within the shell safely.
9348 * Standard option processing (a la getopt) for builtin routines. The
9349 * only argument that is passed to nextopt is the option string; the
9350 * other arguments are unnecessary. It return the character, or '\0' on
9355 nextopt(const char *optstring)
9361 if ((p = optptr) == NULL || *p == '\0') {
9363 if (p == NULL || *p != '-' || *++p == '\0')
9366 if (p[0] == '-' && p[1] == '\0') /* check for "--" */
9370 for (q = optstring ; *q != c ; ) {
9372 error("Illegal option -%c", c);
9377 if (*p == '\0' && (p = *argptr++) == NULL)
9378 error("No arg for -%c option", c);
9395 out2fmt(const char *fmt, ...)
9399 vfprintf(stderr, fmt, ap);
9404 * Version of write which resumes after a signal is caught.
9408 xwrite(int fd, const char *buf, int nbytes)
9417 i = write(fd, buf, n);
9423 } else if (i == 0) {
9426 } else if (errno != EINTR) {
9434 * Shell command parser.
9437 #define EOFMARKLEN 79
9442 struct heredoc *next; /* next here document in list */
9443 union node *here; /* redirection node */
9444 char *eofmark; /* string indicating end of input */
9445 int striptabs; /* if set, strip leading tabs */
9448 static struct heredoc *heredoclist; /* list of here documents to read */
9449 static int parsebackquote; /* nonzero if we are inside backquotes */
9450 static int doprompt; /* if set, prompt the user */
9451 static int needprompt; /* true if interactive and at start of line */
9452 static int lasttoken; /* last token read */
9454 static char *wordtext; /* text of last word returned by readtoken */
9456 static struct nodelist *backquotelist;
9457 static union node *redirnode;
9458 struct heredoc *heredoc;
9459 static int quoteflag; /* set if (part of) last token was quoted */
9460 static int startlinno; /* line # where last token started */
9463 static union node *list (int);
9464 static union node *andor (void);
9465 static union node *pipeline (void);
9466 static union node *command (void);
9467 static union node *simplecmd (void);
9468 static void parsefname (void);
9469 static void parseheredoc (void);
9470 static int peektoken (void);
9471 static int readtoken (void);
9472 static int xxreadtoken (void);
9473 static int readtoken1 (int, char const *, char *, int);
9474 static int noexpand (char *);
9475 static void synexpect (int) __attribute__((noreturn));
9476 static void synerror (const char *) __attribute__((noreturn));
9477 static void setprompt (int);
9481 * Read and parse a command. Returns NEOF on end of file. (NULL is a
9482 * valid parse tree indicating a blank line.)
9486 parsecmd(int interact)
9491 doprompt = interact;
9511 union node *n1, *n2, *n3;
9515 if (nlflag == 0 && tokendlist[peektoken()])
9521 if (tok == TBACKGND) {
9522 if (n2->type == NCMD || n2->type == NPIPE) {
9523 n2->ncmd.backgnd = 1;
9524 } else if (n2->type == NREDIR) {
9525 n2->type = NBACKGND;
9527 n3 = (union node *)stalloc(sizeof (struct nredir));
9528 n3->type = NBACKGND;
9530 n3->nredir.redirect = NULL;
9538 n3 = (union node *)stalloc(sizeof (struct nbinary));
9540 n3->nbinary.ch1 = n1;
9541 n3->nbinary.ch2 = n2;
9558 if (tokendlist[peektoken()])
9565 pungetc(); /* push back EOF on input */
9580 union node *n1, *n2, *n3;
9586 if ((t = readtoken()) == TAND) {
9588 } else if (t == TOR) {
9596 n3 = (union node *)stalloc(sizeof (struct nbinary));
9598 n3->nbinary.ch1 = n1;
9599 n3->nbinary.ch2 = n2;
9608 union node *n1, *n2, *pipenode;
9609 struct nodelist *lp, *prev;
9613 TRACE(("pipeline: entered\n"));
9614 if (readtoken() == TNOT) {
9620 if (readtoken() == TPIPE) {
9621 pipenode = (union node *)stalloc(sizeof (struct npipe));
9622 pipenode->type = NPIPE;
9623 pipenode->npipe.backgnd = 0;
9624 lp = (struct nodelist *)stalloc(sizeof (struct nodelist));
9625 pipenode->npipe.cmdlist = lp;
9629 lp = (struct nodelist *)stalloc(sizeof (struct nodelist));
9633 } while (readtoken() == TPIPE);
9639 n2 = (union node *)stalloc(sizeof (struct nnot));
9651 union node *n1, *n2;
9652 union node *ap, **app;
9653 union node *cp, **cpp;
9654 union node *redir, **rpp;
9661 switch (readtoken()) {
9663 n1 = (union node *)stalloc(sizeof (struct nif));
9665 n1->nif.test = list(0);
9666 if (readtoken() != TTHEN)
9668 n1->nif.ifpart = list(0);
9670 while (readtoken() == TELIF) {
9671 n2->nif.elsepart = (union node *)stalloc(sizeof (struct nif));
9672 n2 = n2->nif.elsepart;
9674 n2->nif.test = list(0);
9675 if (readtoken() != TTHEN)
9677 n2->nif.ifpart = list(0);
9679 if (lasttoken == TELSE)
9680 n2->nif.elsepart = list(0);
9682 n2->nif.elsepart = NULL;
9685 if (readtoken() != TFI)
9692 n1 = (union node *)stalloc(sizeof (struct nbinary));
9693 n1->type = (lasttoken == TWHILE)? NWHILE : NUNTIL;
9694 n1->nbinary.ch1 = list(0);
9695 if ((got=readtoken()) != TDO) {
9696 TRACE(("expecting DO got %s %s\n", tokname[got], got == TWORD ? wordtext : ""));
9699 n1->nbinary.ch2 = list(0);
9700 if (readtoken() != TDONE)
9706 if (readtoken() != TWORD || quoteflag || ! goodname(wordtext))
9707 synerror("Bad for loop variable");
9708 n1 = (union node *)stalloc(sizeof (struct nfor));
9710 n1->nfor.var = wordtext;
9712 if (readtoken() == TIN) {
9714 while (readtoken() == TWORD) {
9715 n2 = (union node *)stalloc(sizeof (struct narg));
9717 n2->narg.text = wordtext;
9718 n2->narg.backquote = backquotelist;
9720 app = &n2->narg.next;
9724 if (lasttoken != TNL && lasttoken != TSEMI)
9727 static char argvars[5] = {CTLVAR, VSNORMAL|VSQUOTE,
9729 n2 = (union node *)stalloc(sizeof (struct narg));
9731 n2->narg.text = argvars;
9732 n2->narg.backquote = NULL;
9733 n2->narg.next = NULL;
9736 * Newline or semicolon here is optional (but note
9737 * that the original Bourne shell only allowed NL).
9739 if (lasttoken != TNL && lasttoken != TSEMI)
9743 if (readtoken() != TDO)
9745 n1->nfor.body = list(0);
9746 if (readtoken() != TDONE)
9751 n1 = (union node *)stalloc(sizeof (struct ncase));
9753 if (readtoken() != TWORD)
9755 n1->ncase.expr = n2 = (union node *)stalloc(sizeof (struct narg));
9757 n2->narg.text = wordtext;
9758 n2->narg.backquote = backquotelist;
9759 n2->narg.next = NULL;
9762 } while (readtoken() == TNL);
9763 if (lasttoken != TIN)
9764 synerror("expecting \"in\"");
9765 cpp = &n1->ncase.cases;
9766 checkkwd = 2, readtoken();
9768 if (lasttoken == TLP)
9770 *cpp = cp = (union node *)stalloc(sizeof (struct nclist));
9772 app = &cp->nclist.pattern;
9774 *app = ap = (union node *)stalloc(sizeof (struct narg));
9776 ap->narg.text = wordtext;
9777 ap->narg.backquote = backquotelist;
9778 if (checkkwd = 2, readtoken() != TPIPE)
9780 app = &ap->narg.next;
9783 ap->narg.next = NULL;
9784 if (lasttoken != TRP)
9786 cp->nclist.body = list(0);
9789 if ((t = readtoken()) != TESAC) {
9791 synexpect(TENDCASE);
9793 checkkwd = 2, readtoken();
9795 cpp = &cp->nclist.next;
9796 } while(lasttoken != TESAC);
9801 n1 = (union node *)stalloc(sizeof (struct nredir));
9802 n1->type = NSUBSHELL;
9803 n1->nredir.n = list(0);
9804 n1->nredir.redirect = NULL;
9805 if (readtoken() != TRP)
9811 if (readtoken() != TEND)
9815 /* Handle an empty command like other simple commands. */
9824 * An empty command before a ; doesn't make much sense, and
9825 * should certainly be disallowed in the case of `if ;'.
9839 /* Now check for redirection which may follow command */
9840 while (readtoken() == TREDIR) {
9841 *rpp = n2 = redirnode;
9842 rpp = &n2->nfile.next;
9848 if (n1->type != NSUBSHELL) {
9849 n2 = (union node *)stalloc(sizeof (struct nredir));
9854 n1->nredir.redirect = redir;
9863 union node *args, **app;
9864 union node *n = NULL;
9865 union node *vars, **vpp;
9866 union node **rpp, *redir;
9879 switch (readtoken()) {
9882 n = (union node *)stalloc(sizeof (struct narg));
9884 n->narg.text = wordtext;
9885 n->narg.backquote = backquotelist;
9886 if (lasttoken == TWORD) {
9888 app = &n->narg.next;
9891 vpp = &n->narg.next;
9895 *rpp = n = redirnode;
9896 rpp = &n->nfile.next;
9897 parsefname(); /* read name of redirection file */
9901 args && app == &args->narg.next &&
9904 /* We have a function */
9905 if (readtoken() != TRP)
9909 n->narg.next = command();
9922 n = (union node *)stalloc(sizeof (struct ncmd));
9924 n->ncmd.backgnd = 0;
9925 n->ncmd.args = args;
9926 n->ncmd.assign = vars;
9927 n->ncmd.redirect = redir;
9935 n = (union node *)stalloc(sizeof (struct narg));
9937 n->narg.next = NULL;
9938 n->narg.text = wordtext;
9939 n->narg.backquote = backquotelist;
9943 static void fixredir(union node *n, const char *text, int err)
9945 TRACE(("Fix redir %s %d\n", text, err));
9947 n->ndup.vname = NULL;
9949 if (is_digit(text[0]) && text[1] == '\0')
9950 n->ndup.dupfd = digit_val(text[0]);
9951 else if (text[0] == '-' && text[1] == '\0')
9956 synerror("Bad fd number");
9958 n->ndup.vname = makename();
9965 union node *n = redirnode;
9967 if (readtoken() != TWORD)
9969 if (n->type == NHERE) {
9970 struct heredoc *here = heredoc;
9976 TRACE(("Here document %d\n", n->type));
9977 if (here->striptabs) {
9978 while (*wordtext == '\t')
9981 if (! noexpand(wordtext) || (i = strlen(wordtext)) == 0 || i > EOFMARKLEN)
9982 synerror("Illegal eof marker for << redirection");
9983 rmescapes(wordtext);
9984 here->eofmark = wordtext;
9986 if (heredoclist == NULL)
9989 for (p = heredoclist ; p->next ; p = p->next);
9992 } else if (n->type == NTOFD || n->type == NFROMFD) {
9993 fixredir(n, wordtext, 0);
9995 n->nfile.fname = makename();
10001 * Input any here documents.
10006 struct heredoc *here;
10009 while (heredoclist) {
10010 here = heredoclist;
10011 heredoclist = here->next;
10016 readtoken1(pgetc(), here->here->type == NHERE? SQSYNTAX : DQSYNTAX,
10017 here->eofmark, here->striptabs);
10018 n = (union node *)stalloc(sizeof (struct narg));
10019 n->narg.type = NARG;
10020 n->narg.next = NULL;
10021 n->narg.text = wordtext;
10022 n->narg.backquote = backquotelist;
10023 here->here->nhere.doc = n;
10040 int savecheckkwd = checkkwd;
10041 int savecheckalias = checkalias;
10046 int alreadyseen = tokpushback;
10056 checkalias = savecheckalias;
10063 if (checkkwd == 2) {
10072 * check for keywords
10074 if (t == TWORD && !quoteflag)
10076 const char *const *pp;
10078 if ((pp = findkwd(wordtext))) {
10079 lasttoken = t = pp - parsekwd + KWDOFFSET;
10080 TRACE(("keyword %s recognized\n", tokname[t]));
10091 } else if (checkalias == 2 && isassignment(wordtext)) {
10092 lasttoken = t = TASSIGN;
10093 } else if (checkalias) {
10094 if (!quoteflag && (ap = lookupalias(wordtext, 1)) != NULL) {
10096 pushstring(ap->val, strlen(ap->val), ap);
10098 checkkwd = savecheckkwd;
10107 TRACE(("token %s %s\n", tokname[t], t == TWORD || t == TASSIGN ? wordtext : ""));
10109 TRACE(("reread token %s %s\n", tokname[t], t == TWORD || t == TASSIGN ? wordtext : ""));
10116 * Read the next input token.
10117 * If the token is a word, we set backquotelist to the list of cmds in
10118 * backquotes. We set quoteflag to true if any part of the word was
10120 * If the token is TREDIR, then we set redirnode to a structure containing
10122 * In all cases, the variable startlinno is set to the number of the line
10123 * on which the token starts.
10125 * [Change comment: here documents and internal procedures]
10126 * [Readtoken shouldn't have any arguments. Perhaps we should make the
10127 * word parsing code into a separate routine. In this case, readtoken
10128 * doesn't need to have any internal procedures, but parseword does.
10129 * We could also make parseoperator in essence the main routine, and
10130 * have parseword (readtoken1?) handle both words and redirection.]
10133 #define RETURN(token) return lasttoken = token
10147 startlinno = plinno;
10148 for (;;) { /* until token or start of word found */
10151 case ' ': case '\t':
10157 while ((c = pgetc()) != '\n' && c != PEOF);
10161 if (pgetc() == '\n') {
10162 startlinno = ++plinno;
10173 needprompt = doprompt;
10178 if (pgetc() == '&')
10183 if (pgetc() == '|')
10188 if (pgetc() == ';')
10201 return readtoken1(c, BASESYNTAX, (char *)NULL, 0);
10208 * If eofmark is NULL, read a word or a redirection symbol. If eofmark
10209 * is not NULL, read a here document. In the latter case, eofmark is the
10210 * word which marks the end of the document and striptabs is true if
10211 * leading tabs should be stripped from the document. The argument firstc
10212 * is the first character of the input token or document.
10214 * Because C does not have internal subroutines, I have simulated them
10215 * using goto's to implement the subroutine linkage. The following macros
10216 * will run code that appears at the end of readtoken1.
10219 #define CHECKEND() {goto checkend; checkend_return:;}
10220 #define PARSEREDIR() {goto parseredir; parseredir_return:;}
10221 #define PARSESUB() {goto parsesub; parsesub_return:;}
10222 #define PARSEBACKQOLD() {oldstyle = 1; goto parsebackq; parsebackq_oldreturn:;}
10223 #define PARSEBACKQNEW() {oldstyle = 0; goto parsebackq; parsebackq_newreturn:;}
10224 #define PARSEARITH() {goto parsearith; parsearith_return:;}
10227 readtoken1(firstc, syntax, eofmark, striptabs)
10229 char const *syntax;
10236 char line[EOFMARKLEN + 1];
10237 struct nodelist *bqlist;
10240 int varnest; /* levels of variables expansion */
10241 int arinest; /* levels of arithmetic expansion */
10242 int parenlevel; /* levels of parens in arithmetic */
10243 int dqvarnest; /* levels of variables expansion within double quotes */
10245 char const *prevsyntax; /* syntax before arithmetic */
10247 /* Avoid longjmp clobbering */
10253 (void) &parenlevel;
10256 (void) &prevsyntax;
10260 startlinno = plinno;
10262 if (syntax == DQSYNTAX)
10271 STARTSTACKSTR(out);
10272 loop: { /* for each line, until end of word */
10273 CHECKEND(); /* set c to PEOF if at end of here document */
10274 for (;;) { /* until end of line or end of word */
10275 CHECKSTRSPACE(3, out); /* permit 3 calls to USTPUTC */
10276 switch(syntax[c]) {
10277 case CNL: /* '\n' */
10278 if (syntax == BASESYNTAX)
10279 goto endword; /* exit outer loop */
10287 goto loop; /* continue outer loop */
10292 if ((eofmark == NULL || dblquote) &&
10294 USTPUTC(CTLESC, out);
10297 case CBACK: /* backslash */
10300 USTPUTC('\\', out);
10302 } else if (c == '\n') {
10308 if (dblquote && c != '\\' && c != '`' && c != '$'
10309 && (c != '"' || eofmark != NULL))
10310 USTPUTC('\\', out);
10311 if (SQSYNTAX[c] == CCTL)
10312 USTPUTC(CTLESC, out);
10313 else if (eofmark == NULL)
10314 USTPUTC(CTLQUOTEMARK, out);
10320 if (eofmark == NULL)
10321 USTPUTC(CTLQUOTEMARK, out);
10325 if (eofmark == NULL)
10326 USTPUTC(CTLQUOTEMARK, out);
10331 if (eofmark != NULL && arinest == 0 &&
10336 syntax = ARISYNTAX;
10338 } else if (eofmark == NULL &&
10340 syntax = BASESYNTAX;
10346 case CVAR: /* '$' */
10347 PARSESUB(); /* parse substitution */
10349 case CENDVAR: /* '}' */
10352 if (dqvarnest > 0) {
10355 USTPUTC(CTLENDVAR, out);
10360 #ifdef ASH_MATH_SUPPORT
10361 case CLP: /* '(' in arithmetic */
10365 case CRP: /* ')' in arithmetic */
10366 if (parenlevel > 0) {
10370 if (pgetc() == ')') {
10371 if (--arinest == 0) {
10372 USTPUTC(CTLENDARI, out);
10373 syntax = prevsyntax;
10374 if (syntax == DQSYNTAX)
10382 * unbalanced parens
10383 * (don't 2nd guess - no error)
10391 case CBQUOTE: /* '`' */
10395 goto endword; /* exit outer loop */
10400 goto endword; /* exit outer loop */
10411 if (syntax == ARISYNTAX)
10412 synerror("Missing '))'");
10413 if (syntax != BASESYNTAX && ! parsebackquote && eofmark == NULL)
10414 synerror("Unterminated quoted string");
10415 if (varnest != 0) {
10416 startlinno = plinno;
10417 synerror("Missing '}'");
10419 USTPUTC('\0', out);
10420 len = out - stackblock();
10421 out = stackblock();
10422 if (eofmark == NULL) {
10423 if ((c == '>' || c == '<')
10426 && (*out == '\0' || is_digit(*out))) {
10428 return lasttoken = TREDIR;
10433 quoteflag = quotef;
10434 backquotelist = bqlist;
10435 grabstackblock(len);
10437 return lasttoken = TWORD;
10438 /* end of readtoken routine */
10443 * Check to see whether we are at the end of the here document. When this
10444 * is called, c is set to the first character of the next input line. If
10445 * we are at the end of the here document, this routine sets the c to PEOF.
10456 while (c == '\t') {
10460 if (c == *eofmark) {
10461 if (pfgets(line, sizeof line) != NULL) {
10465 for (q = eofmark + 1 ; *q && *p == *q ; p++, q++);
10466 if (*p == '\n' && *q == '\0') {
10469 needprompt = doprompt;
10471 pushstring(line, strlen(line), NULL);
10476 goto checkend_return;
10481 * Parse a redirection operator. The variable "out" points to a string
10482 * specifying the fd to be redirected. The variable "c" contains the
10483 * first character of the redirection operator.
10490 np = (union node *)stalloc(sizeof (struct nfile));
10495 np->type = NAPPEND;
10504 } else { /* c == '<' */
10506 switch (c = pgetc()) {
10508 if (sizeof (struct nfile) != sizeof (struct nhere)) {
10509 np = (union node *)stalloc(sizeof (struct nhere));
10513 heredoc = (struct heredoc *)stalloc(sizeof (struct heredoc));
10514 heredoc->here = np;
10515 if ((c = pgetc()) == '-') {
10516 heredoc->striptabs = 1;
10518 heredoc->striptabs = 0;
10524 np->type = NFROMFD;
10528 np->type = NFROMTO;
10538 np->nfile.fd = digit_val(fd);
10540 goto parseredir_return;
10545 * Parse a substitution. At this point, we have read the dollar sign
10546 * and nothing else.
10554 static const char types[] = "}-+?=";
10559 (c != '(' && c != '{' && !is_name(c) && !is_special(c))
10563 } else if (c == '(') { /* $(command) or $((arith)) */
10564 if (pgetc() == '(') {
10571 USTPUTC(CTLVAR, out);
10572 typeloc = out - stackblock();
10573 USTPUTC(VSNORMAL, out);
10574 subtype = VSNORMAL;
10578 if ((c = pgetc()) == '}')
10581 subtype = VSLENGTH;
10586 if (c > PEOA && is_name(c)) {
10590 } while (c > PEOA && is_in_name(c));
10591 } else if (is_digit(c)) {
10595 } while (is_digit(c));
10597 else if (is_special(c)) {
10602 badsub: synerror("Bad substitution");
10606 if (subtype == 0) {
10613 p = strchr(types, c);
10616 subtype = p - types + VSNORMAL;
10622 subtype = c == '#' ? VSTRIMLEFT :
10635 if (dblquote || arinest)
10637 *(stackblock() + typeloc) = subtype | flags;
10638 if (subtype != VSNORMAL) {
10645 goto parsesub_return;
10650 * Called to parse command substitutions. Newstyle is set if the command
10651 * is enclosed inside $(...); nlpp is a pointer to the head of the linked
10652 * list of commands (passed by reference), and savelen is the number of
10653 * characters on the top of the stack which must be preserved.
10657 struct nodelist **nlpp;
10660 char *volatile str;
10661 struct jmploc jmploc;
10662 struct jmploc *volatile savehandler;
10666 (void) &saveprompt;
10669 savepbq = parsebackquote;
10670 if (setjmp(jmploc.loc)) {
10673 parsebackquote = 0;
10674 handler = savehandler;
10675 longjmp(handler->loc, 1);
10679 savelen = out - stackblock();
10681 str = ckmalloc(savelen);
10682 memcpy(str, stackblock(), savelen);
10684 savehandler = handler;
10688 /* We must read until the closing backquote, giving special
10689 treatment to some slashes, and then push the string and
10690 reread it as input, interpreting it normally. */
10697 STARTSTACKSTR(pout);
10703 switch (pc = pgetc()) {
10708 if ((pc = pgetc()) == '\n') {
10715 * If eating a newline, avoid putting
10716 * the newline into the new character
10717 * stream (via the STPUTC after the
10722 if (pc != '\\' && pc != '`' && pc != '$'
10723 && (!dblquote || pc != '"'))
10724 STPUTC('\\', pout);
10734 startlinno = plinno;
10735 synerror("EOF in backquote substitution");
10739 needprompt = doprompt;
10748 STPUTC('\0', pout);
10749 psavelen = pout - stackblock();
10750 if (psavelen > 0) {
10751 pstr = grabstackstr(pout);
10752 setinputstring(pstr);
10757 nlpp = &(*nlpp)->next;
10758 *nlpp = (struct nodelist *)stalloc(sizeof (struct nodelist));
10759 (*nlpp)->next = NULL;
10760 parsebackquote = oldstyle;
10763 saveprompt = doprompt;
10770 doprompt = saveprompt;
10772 if (readtoken() != TRP)
10779 * Start reading from old file again, ignoring any pushed back
10780 * tokens left from the backquote parsing
10785 while (stackblocksize() <= savelen)
10787 STARTSTACKSTR(out);
10789 memcpy(out, str, savelen);
10790 STADJUST(savelen, out);
10796 parsebackquote = savepbq;
10797 handler = savehandler;
10798 if (arinest || dblquote)
10799 USTPUTC(CTLBACKQ | CTLQUOTE, out);
10801 USTPUTC(CTLBACKQ, out);
10803 goto parsebackq_oldreturn;
10805 goto parsebackq_newreturn;
10809 * Parse an arithmetic expansion (indicate start of one and set state)
10813 if (++arinest == 1) {
10814 prevsyntax = syntax;
10815 syntax = ARISYNTAX;
10816 USTPUTC(CTLARI, out);
10823 * we collapse embedded arithmetic expansion to
10824 * parenthesis, which should be equivalent
10828 goto parsearith_return;
10831 } /* end of readtoken */
10835 * Returns true if the text contains nothing to expand (no dollar signs
10847 while ((c = *p++) != '\0') {
10848 if (c == CTLQUOTEMARK)
10852 else if (BASESYNTAX[(int)c] == CCTL)
10860 * Return true if the argument is a legal variable name (a letter or
10861 * underscore followed by zero or more letters, underscores, and digits).
10865 goodname(const char *name)
10873 if (! is_in_name(*p))
10881 * Called when an unexpected token is read during the parse. The argument
10882 * is the token that is expected, or -1 if more than one type of token can
10883 * occur at this point.
10893 snprintf(msg, 64, "%s unexpected (expecting %s)",
10894 tokname[lasttoken], tokname[token]);
10896 snprintf(msg, 64, "%s unexpected", tokname[lasttoken]);
10904 synerror(const char *msg)
10907 out2fmt("%s: %d: ", commandname, startlinno);
10908 out2fmt("Syntax error: %s\n", msg);
10909 error((char *)NULL);
10915 * called by editline -- any expansions to the prompt
10916 * should be added here.
10919 setprompt(int whichprompt)
10922 switch (whichprompt) {
10937 * Code for dealing with input/output redirection.
10940 #define EMPTY -2 /* marks an unused slot in redirtab */
10942 # define PIPESIZE 4096 /* amount of buffering in a pipe */
10944 # define PIPESIZE PIPE_BUF
10949 * Open a file in noclobber mode.
10950 * The code was copied from bash.
10953 noclobberopen(const char *fname)
10956 struct stat finfo, finfo2;
10959 * If the file exists and is a regular file, return an error
10962 r = stat(fname, &finfo);
10963 if (r == 0 && S_ISREG(finfo.st_mode)) {
10969 * If the file was not present (r != 0), make sure we open it
10970 * exclusively so that if it is created before we open it, our open
10971 * will fail. Make sure that we do not truncate an existing file.
10972 * Note that we don't turn on O_EXCL unless the stat failed -- if the
10973 * file was not a regular file, we leave O_EXCL off.
10976 return open(fname, O_WRONLY|O_CREAT|O_EXCL, 0666);
10977 fd = open(fname, O_WRONLY|O_CREAT, 0666);
10979 /* If the open failed, return the file descriptor right away. */
10984 * OK, the open succeeded, but the file may have been changed from a
10985 * non-regular file to a regular file between the stat and the open.
10986 * We are assuming that the O_EXCL open handles the case where FILENAME
10987 * did not exist and is symlinked to an existing file between the stat
10992 * If we can open it and fstat the file descriptor, and neither check
10993 * revealed that it was a regular file, and the file has not been
10994 * replaced, return the file descriptor.
10996 if (fstat(fd, &finfo2) == 0 && !S_ISREG(finfo2.st_mode) &&
10997 finfo.st_dev == finfo2.st_dev && finfo.st_ino == finfo2.st_ino)
11000 /* The file has been replaced. badness. */
11007 * Handle here documents. Normally we fork off a process to write the
11008 * data to a pipe. If the document is short, we can stuff the data in
11009 * the pipe without forking.
11013 openhere(const union node *redir)
11019 error("Pipe call failed");
11020 if (redir->type == NHERE) {
11021 len = strlen(redir->nhere.doc->narg.text);
11022 if (len <= PIPESIZE) {
11023 xwrite(pip[1], redir->nhere.doc->narg.text, len);
11027 if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) {
11029 signal(SIGINT, SIG_IGN);
11030 signal(SIGQUIT, SIG_IGN);
11031 signal(SIGHUP, SIG_IGN);
11033 signal(SIGTSTP, SIG_IGN);
11035 signal(SIGPIPE, SIG_DFL);
11036 if (redir->type == NHERE)
11037 xwrite(pip[1], redir->nhere.doc->narg.text, len);
11039 expandhere(redir->nhere.doc, pip[1]);
11049 openredirect(const union node *redir)
11054 switch (redir->nfile.type) {
11056 fname = redir->nfile.expfname;
11057 if ((f = open(fname, O_RDONLY)) < 0)
11061 fname = redir->nfile.expfname;
11062 if ((f = open(fname, O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0)
11066 /* Take care of noclobber mode. */
11068 fname = redir->nfile.expfname;
11069 if ((f = noclobberopen(fname)) < 0)
11074 fname = redir->nfile.expfname;
11076 if ((f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
11079 if ((f = creat(fname, 0666)) < 0)
11084 fname = redir->nfile.expfname;
11086 if ((f = open(fname, O_WRONLY|O_CREAT|O_APPEND, 0666)) < 0)
11089 if ((f = open(fname, O_WRONLY)) < 0
11090 && (f = creat(fname, 0666)) < 0)
11092 lseek(f, (off_t)0, 2);
11099 /* Fall through to eliminate warning. */
11106 f = openhere(redir);
11112 error("cannot create %s: %s", fname, errmsg(errno, E_CREAT));
11114 error("cannot open %s: %s", fname, errmsg(errno, E_OPEN));
11119 * Process a list of redirection commands. If the REDIR_PUSH flag is set,
11120 * old file descriptors are stashed away so that the redirection can be
11121 * undone by calling popredir. If the REDIR_BACKQ flag is set, then the
11122 * standard output, and the standard error if it becomes a duplicate of
11127 redirect(union node *redir, int flags)
11130 struct redirtab *sv = NULL;
11135 int fd1dup = flags & REDIR_BACKQ;; /* stdout `cmd` redir to pipe */
11137 if (flags & REDIR_PUSH) {
11138 sv = ckmalloc(sizeof (struct redirtab));
11139 for (i = 0 ; i < 10 ; i++)
11140 sv->renamed[i] = EMPTY;
11141 sv->next = redirlist;
11144 for (n = redir ; n ; n = n->nfile.next) {
11147 if ((n->nfile.type == NTOFD || n->nfile.type == NFROMFD) &&
11148 n->ndup.dupfd == fd)
11149 continue; /* redirect from/to same file descriptor */
11152 newfd = openredirect(n);
11153 if ((flags & REDIR_PUSH) && sv->renamed[fd] == EMPTY) {
11156 } else if ((i = fcntl(fd, F_DUPFD, 10)) == -1) {
11160 dupredirect(n, newfd, fd1dup);
11170 error("%d: %m", fd);
11176 if (flags & REDIR_PUSH) {
11177 sv->renamed[fd] = i;
11180 } else if (fd != newfd) {
11186 dupredirect(n, newfd, fd1dup);
11193 dupredirect(const union node *redir, int f, int fd1dup)
11195 int fd = redir->nfile.fd;
11199 if (redir->nfile.type == NTOFD || redir->nfile.type == NFROMFD) {
11200 if (redir->ndup.dupfd >= 0) { /* if not ">&-" */
11201 if (redir->ndup.dupfd!=1 || fd1dup!=1)
11202 dup_as_newfd(redir->ndup.dupfd, fd);
11208 dup_as_newfd(f, fd);
11217 * Undo the effects of the last redirection.
11223 struct redirtab *rp = redirlist;
11227 for (i = 0 ; i < 10 ; i++) {
11228 if (rp->renamed[i] != EMPTY) {
11232 if (rp->renamed[i] >= 0) {
11233 dup_as_newfd(rp->renamed[i], i);
11234 close(rp->renamed[i]);
11238 redirlist = rp->next;
11244 * Discard all saved file descriptors.
11249 struct redirtab *rp;
11252 for (rp = redirlist ; rp ; rp = rp->next) {
11253 for (i = 0 ; i < 10 ; i++) {
11254 if (rp->renamed[i] >= 0) {
11255 close(rp->renamed[i]);
11257 rp->renamed[i] = EMPTY;
11264 * Copy a file descriptor to be >= to. Returns -1
11265 * if the source file descriptor is closed, EMPTY if there are no unused
11266 * file descriptors left.
11270 dup_as_newfd(from, to)
11276 newfd = fcntl(from, F_DUPFD, to);
11278 if (errno == EMFILE)
11281 error("%d: %m", from);
11286 /*#ifdef __weak_alias
11287 __weak_alias(getmode,_getmode)
11288 __weak_alias(setmode,_setmode)
11292 #if defined(__GLIBC__) && __GLIBC__ >= 2
11293 #define S_ISTXT __S_ISVTX
11295 #define S_ISTXT S_ISVTX
11299 #define SET_LEN 6 /* initial # of bitcmd struct to malloc */
11300 #define SET_LEN_INCR 4 /* # of bitcmd structs to add as needed */
11302 typedef struct bitcmd {
11308 #define CMD2_CLR 0x01
11309 #define CMD2_SET 0x02
11310 #define CMD2_GBITS 0x04
11311 #define CMD2_OBITS 0x08
11312 #define CMD2_UBITS 0x10
11314 static BITCMD *addcmd (BITCMD *, int, int, int, u_int);
11315 static void compress_mode (BITCMD *);
11316 #ifdef SETMODE_DEBUG
11317 static void dumpmode (BITCMD *);
11321 * Given the old mode and an array of bitcmd structures, apply the operations
11322 * described in the bitcmd structures to the old mode, and return the new mode.
11323 * Note that there is no '=' command; a strict assignment is just a '-' (clear
11324 * bits) followed by a '+' (set bits).
11327 getmode(bbox, omode)
11332 mode_t clrval, newmode, value;
11334 _DIAGASSERT(bbox != NULL);
11336 set = (const BITCMD *)bbox;
11338 for (value = 0;; set++)
11341 * When copying the user, group or other bits around, we "know"
11342 * where the bits are in the mode so that we can do shifts to
11343 * copy them around. If we don't use shifts, it gets real
11344 * grundgy with lots of single bit checks and bit sets.
11347 value = (newmode & S_IRWXU) >> 6;
11351 value = (newmode & S_IRWXG) >> 3;
11355 value = newmode & S_IRWXO;
11356 common: if (set->cmd2 & CMD2_CLR) {
11358 (set->cmd2 & CMD2_SET) ? S_IRWXO : value;
11359 if (set->cmd2 & CMD2_UBITS)
11360 newmode &= ~((clrval<<6) & set->bits);
11361 if (set->cmd2 & CMD2_GBITS)
11362 newmode &= ~((clrval<<3) & set->bits);
11363 if (set->cmd2 & CMD2_OBITS)
11364 newmode &= ~(clrval & set->bits);
11366 if (set->cmd2 & CMD2_SET) {
11367 if (set->cmd2 & CMD2_UBITS)
11368 newmode |= (value<<6) & set->bits;
11369 if (set->cmd2 & CMD2_GBITS)
11370 newmode |= (value<<3) & set->bits;
11371 if (set->cmd2 & CMD2_OBITS)
11372 newmode |= value & set->bits;
11377 newmode |= set->bits;
11381 newmode &= ~set->bits;
11385 if (omode & (S_IFDIR|S_IXUSR|S_IXGRP|S_IXOTH))
11386 newmode |= set->bits;
11391 #ifdef SETMODE_DEBUG
11392 (void)printf("getmode:%04o -> %04o\n", omode, newmode);
11398 #define ADDCMD(a, b, c, d) do { \
11399 if (set >= endset) { \
11401 setlen += SET_LEN_INCR; \
11402 newset = realloc(saveset, sizeof(BITCMD) * setlen); \
11403 if (newset == NULL) { \
11407 set = newset + (set - saveset); \
11408 saveset = newset; \
11409 endset = newset + (setlen - 2); \
11411 set = addcmd(set, (a), (b), (c), (d)); \
11412 } while (/*CONSTCOND*/0)
11414 #define STANDARD_BITS (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO)
11422 BITCMD *set, *saveset, *endset;
11423 sigset_t mysigset, sigoset;
11425 int equalopdone = 0; /* pacify gcc */
11426 int permXbits, setlen;
11432 * Get a copy of the mask for the permissions that are mask relative.
11433 * Flip the bits, we want what's not set. Since it's possible that
11434 * the caller is opening files inside a signal handler, protect them
11437 sigfillset(&mysigset);
11438 (void)sigprocmask(SIG_BLOCK, &mysigset, &sigoset);
11439 (void)umask(mask = umask(0));
11441 (void)sigprocmask(SIG_SETMASK, &sigoset, NULL);
11443 setlen = SET_LEN + 2;
11445 if ((set = malloc((u_int)(sizeof(BITCMD) * setlen))) == NULL)
11448 endset = set + (setlen - 2);
11451 * If an absolute number, get it and return; disallow non-octal digits
11454 if (is_digit((unsigned char)*p)) {
11455 perm = (mode_t)strtol(p, &ep, 8);
11456 if (*ep || perm & ~(STANDARD_BITS|S_ISTXT)) {
11460 ADDCMD('=', (STANDARD_BITS|S_ISTXT), perm, mask);
11466 * Build list of structures to set/clear/copy bits as described by
11467 * each clause of the symbolic mode.
11470 /* First, find out which bits might be modified. */
11471 for (who = 0;; ++p) {
11474 who |= STANDARD_BITS;
11477 who |= S_ISUID|S_IRWXU;
11480 who |= S_ISGID|S_IRWXG;
11490 getop: if ((op = *p++) != '+' && op != '-' && op != '=') {
11498 for (perm = 0, permXbits = 0;; ++p) {
11501 perm |= S_IRUSR|S_IRGRP|S_IROTH;
11505 * If specific bits where requested and
11506 * only "other" bits ignore set-id.
11508 if (who == 0 || (who & ~S_IRWXO))
11509 perm |= S_ISUID|S_ISGID;
11513 * If specific bits where requested and
11514 * only "other" bits ignore set-id.
11516 if (who == 0 || (who & ~S_IRWXO)) {
11522 perm |= S_IWUSR|S_IWGRP|S_IWOTH;
11525 permXbits = S_IXUSR|S_IXGRP|S_IXOTH;
11528 perm |= S_IXUSR|S_IXGRP|S_IXOTH;
11534 * When ever we hit 'u', 'g', or 'o', we have
11535 * to flush out any partial mode that we have,
11536 * and then do the copying of the mode bits.
11539 ADDCMD(op, who, perm, mask);
11544 if (op == '+' && permXbits) {
11545 ADDCMD('X', who, permXbits, mask);
11548 ADDCMD(*p, who, op, mask);
11553 * Add any permissions that we haven't already
11556 if (perm || (op == '=' && !equalopdone)) {
11559 ADDCMD(op, who, perm, mask);
11563 ADDCMD('X', who, permXbits, mask);
11577 #ifdef SETMODE_DEBUG
11578 (void)printf("Before compress_mode()\n");
11581 compress_mode(saveset);
11582 #ifdef SETMODE_DEBUG
11583 (void)printf("After compress_mode()\n");
11590 addcmd(set, op, who, oparg, mask)
11597 _DIAGASSERT(set != NULL);
11602 set->bits = who ? who : STANDARD_BITS;
11611 set->bits = (who ? who : mask) & oparg;
11619 set->cmd2 = ((who & S_IRUSR) ? CMD2_UBITS : 0) |
11620 ((who & S_IRGRP) ? CMD2_GBITS : 0) |
11621 ((who & S_IROTH) ? CMD2_OBITS : 0);
11622 set->bits = (mode_t)~0;
11624 set->cmd2 = CMD2_UBITS | CMD2_GBITS | CMD2_OBITS;
11629 set->cmd2 |= CMD2_SET;
11630 else if (oparg == '-')
11631 set->cmd2 |= CMD2_CLR;
11632 else if (oparg == '=')
11633 set->cmd2 |= CMD2_SET|CMD2_CLR;
11639 #ifdef SETMODE_DEBUG
11645 _DIAGASSERT(set != NULL);
11647 for (; set->cmd; ++set)
11648 (void)printf("cmd: '%c' bits %04o%s%s%s%s%s%s\n",
11649 set->cmd, set->bits, set->cmd2 ? " cmd2:" : "",
11650 set->cmd2 & CMD2_CLR ? " CLR" : "",
11651 set->cmd2 & CMD2_SET ? " SET" : "",
11652 set->cmd2 & CMD2_UBITS ? " UBITS" : "",
11653 set->cmd2 & CMD2_GBITS ? " GBITS" : "",
11654 set->cmd2 & CMD2_OBITS ? " OBITS" : "");
11659 * Given an array of bitcmd structures, compress by compacting consecutive
11660 * '+', '-' and 'X' commands into at most 3 commands, one of each. The 'u',
11661 * 'g' and 'o' commands continue to be separate. They could probably be
11662 * compacted, but it's not worth the effort.
11669 int setbits, clrbits, Xbits, op;
11671 _DIAGASSERT(set != NULL);
11673 for (nset = set;;) {
11674 /* Copy over any 'u', 'g' and 'o' commands. */
11675 while ((op = nset->cmd) != '+' && op != '-' && op != 'X') {
11681 for (setbits = clrbits = Xbits = 0;; nset++) {
11682 if ((op = nset->cmd) == '-') {
11683 clrbits |= nset->bits;
11684 setbits &= ~nset->bits;
11685 Xbits &= ~nset->bits;
11686 } else if (op == '+') {
11687 setbits |= nset->bits;
11688 clrbits &= ~nset->bits;
11689 Xbits &= ~nset->bits;
11690 } else if (op == 'X')
11691 Xbits |= nset->bits & ~setbits;
11698 set->bits = clrbits;
11704 set->bits = setbits;
11716 static void shtree (union node *, int, char *, FILE*);
11717 static void shcmd (union node *, FILE *);
11718 static void sharg (union node *, FILE *);
11719 static void indent (int, char *, FILE *);
11720 static void trstring (char *);
11727 trputs("showtree called\n");
11728 shtree(n, 1, NULL, stdout);
11733 shtree(n, ind, pfx, fp)
11739 struct nodelist *lp;
11745 indent(ind, pfx, fp);
11756 shtree(n->nbinary.ch1, ind, NULL, fp);
11759 shtree(n->nbinary.ch2, ind, NULL, fp);
11767 for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
11772 if (n->npipe.backgnd)
11778 fprintf(fp, "<node type %d>", n->type);
11798 for (np = cmd->ncmd.args ; np ; np = np->narg.next) {
11804 for (np = cmd->ncmd.redirect ; np ; np = np->nfile.next) {
11807 switch (np->nfile.type) {
11808 case NTO: s = ">"; dftfd = 1; break;
11809 case NAPPEND: s = ">>"; dftfd = 1; break;
11810 case NTOFD: s = ">&"; dftfd = 1; break;
11811 case NTOOV: s = ">|"; dftfd = 1; break;
11812 case NFROM: s = "<"; dftfd = 0; break;
11813 case NFROMFD: s = "<&"; dftfd = 0; break;
11814 case NFROMTO: s = "<>"; dftfd = 0; break;
11815 default: s = "*error*"; dftfd = 0; break;
11817 if (np->nfile.fd != dftfd)
11818 fprintf(fp, "%d", np->nfile.fd);
11820 if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) {
11821 fprintf(fp, "%d", np->ndup.dupfd);
11823 sharg(np->nfile.fname, fp);
11837 struct nodelist *bqlist;
11840 if (arg->type != NARG) {
11841 printf("<node type %d>\n", arg->type);
11845 bqlist = arg->narg.backquote;
11846 for (p = arg->narg.text ; *p ; p++) {
11855 if (subtype == VSLENGTH)
11861 if (subtype & VSNUL)
11864 switch (subtype & VSTYPE) {
11883 case VSTRIMLEFTMAX:
11890 case VSTRIMRIGHTMAX:
11897 printf("<subtype %d>", subtype);
11904 case CTLBACKQ|CTLQUOTE:
11907 shtree(bqlist->n, -1, NULL, fp);
11919 indent(amount, pfx, fp)
11926 for (i = 0 ; i < amount ; i++) {
11927 if (pfx && i == amount - 1)
11945 static int debug = 1;
11947 static int debug = 0;
11955 if (tracefile == NULL)
11957 putc(c, tracefile);
11963 trace(const char *fmt, ...)
11971 fmt = va_arg(va, char *);
11973 if (tracefile != NULL) {
11974 (void) vfprintf(tracefile, fmt, va);
11975 if (strchr(fmt, '\n'))
11976 (void) fflush(tracefile);
11986 if (tracefile == NULL)
11988 fputs(s, tracefile);
11989 if (strchr(s, '\n'))
12001 if (tracefile == NULL)
12003 putc('"', tracefile);
12004 for (p = s ; *p ; p++) {
12006 case '\n': c = 'n'; goto backslash;
12007 case '\t': c = 't'; goto backslash;
12008 case '\r': c = 'r'; goto backslash;
12009 case '"': c = '"'; goto backslash;
12010 case '\\': c = '\\'; goto backslash;
12011 case CTLESC: c = 'e'; goto backslash;
12012 case CTLVAR: c = 'v'; goto backslash;
12013 case CTLVAR+CTLQUOTE: c = 'V'; goto backslash;
12014 case CTLBACKQ: c = 'q'; goto backslash;
12015 case CTLBACKQ+CTLQUOTE: c = 'Q'; goto backslash;
12016 backslash: putc('\\', tracefile);
12017 putc(c, tracefile);
12020 if (*p >= ' ' && *p <= '~')
12021 putc(*p, tracefile);
12023 putc('\\', tracefile);
12024 putc(*p >> 6 & 03, tracefile);
12025 putc(*p >> 3 & 07, tracefile);
12026 putc(*p & 07, tracefile);
12031 putc('"', tracefile);
12039 if (tracefile == NULL)
12044 putc(' ', tracefile);
12046 putc('\n', tracefile);
12061 #ifdef not_this_way
12064 if ((p = getenv("HOME")) == NULL) {
12065 if (geteuid() == 0)
12071 strcat(s, "/trace");
12074 strcpy(s, "./trace");
12075 #endif /* not_this_way */
12076 if ((tracefile = fopen(s, "a")) == NULL) {
12077 fprintf(stderr, "Can't open %s\n", s);
12081 if ((flags = fcntl(fileno(tracefile), F_GETFL, 0)) >= 0)
12082 fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND);
12084 fputs("\nTracing started.\n", tracefile);
12091 * The trap builtin.
12095 trapcmd(argc, argv)
12104 for (signo = 0 ; signo < NSIG ; signo++) {
12105 if (trap[signo] != NULL) {
12108 p = single_quote(trap[signo]);
12109 printf("trap -- %s %s\n", p,
12110 signal_names[signo] + (signo ? 3 : 0)
12123 if ((signo = decode_signal(*ap, 0)) < 0)
12124 error("%s: bad trap", *ap);
12127 if (action[0] == '-' && action[1] == '\0')
12130 action = savestr(action);
12133 ckfree(trap[signo]);
12134 trap[signo] = action;
12149 * Set the signal handler for the specified signal. The routine figures
12150 * out what it should be set to.
12154 setsignal(int signo)
12158 struct sigaction act;
12160 if ((t = trap[signo]) == NULL)
12162 else if (*t != '\0')
12166 if (rootshell && action == S_DFL) {
12169 if (iflag || minusc || sflag == 0)
12195 t = &sigmode[signo - 1];
12198 * current setting unknown
12200 if (sigaction(signo, 0, &act) == -1) {
12202 * Pretend it worked; maybe we should give a warning
12203 * here, but other shells don't. We don't alter
12204 * sigmode, so that we retry every time.
12208 if (act.sa_handler == SIG_IGN) {
12209 if (mflag && (signo == SIGTSTP ||
12210 signo == SIGTTIN || signo == SIGTTOU)) {
12211 *t = S_IGN; /* don't hard ignore these */
12215 *t = S_RESET; /* force to be set */
12218 if (*t == S_HARD_IGN || *t == action)
12222 act.sa_handler = onsig;
12225 act.sa_handler = SIG_IGN;
12228 act.sa_handler = SIG_DFL;
12232 sigemptyset(&act.sa_mask);
12233 sigaction(signo, &act, 0);
12244 if (sigmode[signo - 1] != S_IGN && sigmode[signo - 1] != S_HARD_IGN) {
12245 signal(signo, SIG_IGN);
12247 sigmode[signo - 1] = S_HARD_IGN;
12258 if (signo == SIGINT && trap[SIGINT] == NULL) {
12262 gotsig[signo - 1] = 1;
12268 * Called to execute a trap. Perhaps we should avoid entering new trap
12269 * handlers while we are executing a trap handler.
12279 for (i = 1 ; ; i++) {
12286 savestatus=exitstatus;
12287 evalstring(trap[i], 0);
12288 exitstatus=savestatus;
12295 * Called to exit the shell.
12299 exitshell(int status)
12301 struct jmploc loc1, loc2;
12304 TRACE(("exitshell(%d) pid=%d\n", status, getpid()));
12305 if (setjmp(loc1.loc)) {
12308 if (setjmp(loc2.loc)) {
12312 if ((p = trap[0]) != NULL && *p != '\0') {
12316 l1: handler = &loc2; /* probably unnecessary */
12325 static int decode_signal(const char *string, int minsig)
12329 if (is_number(string, &signo)) {
12330 if (signo >= NSIG) {
12340 for (; signo < NSIG; signo++) {
12341 if (!strcasecmp(string, &(signal_names[signo])[3])) {
12345 if (!strcasecmp(string, signal_names[signo])) {
12352 static struct var **hashvar (const char *);
12353 static void showvars (const char *, int, int);
12354 static struct var **findvar (struct var **, const char *);
12357 * Initialize the varable symbol tables and import the environment
12361 * This routine initializes the builtin variables. It is called when the
12362 * shell is initialized and again when a shell procedure is spawned.
12367 const struct varinit *ip;
12371 for (ip = varinit ; (vp = ip->var) != NULL ; ip++) {
12372 if ((vp->flags & VEXPORT) == 0) {
12373 vpp = hashvar(ip->text);
12376 vp->text = strdup(ip->text);
12377 vp->flags = ip->flags;
12378 vp->func = ip->func;
12382 * PS1 depends on uid
12384 if ((vps1.flags & VEXPORT) == 0) {
12385 vpp = hashvar("PS1=");
12388 vps1.text = strdup(geteuid() ? "PS1=$ " : "PS1=# ");
12389 vps1.flags = VSTRFIXED|VTEXTFIXED;
12394 * Set the value of a variable. The flags argument is ored with the
12395 * flags of the variable. If val is NULL, the variable is unset.
12399 setvar(name, val, flags)
12400 const char *name, *val;
12416 if (! is_in_name(*p)) {
12417 if (*p == '\0' || *p == '=')
12423 namelen = p - name;
12425 error("%.*s: bad variable name", namelen, name);
12426 len = namelen + 2; /* 2 is space for '=' and '\0' */
12430 len += vallen = strlen(val);
12433 nameeq = ckmalloc(len);
12434 memcpy(nameeq, name, namelen);
12435 nameeq[namelen] = '=';
12437 memcpy(nameeq + namelen + 1, val, vallen + 1);
12439 nameeq[namelen + 1] = '\0';
12441 setvareq(nameeq, flags);
12448 * Same as setvar except that the variable and value are passed in
12449 * the first argument as name=value. Since the first argument will
12450 * be actually stored in the table, it should not be a string that
12459 struct var *vp, **vpp;
12462 flags |= (VEXPORT & (((unsigned) (1 - aflag)) - 1));
12463 if ((vp = *findvar(vpp, s))) {
12464 if (vp->flags & VREADONLY) {
12465 size_t len = strchr(s, '=') - s;
12466 error("%.*s: is read only", len, s);
12470 if (vp->func && (flags & VNOFUNC) == 0)
12471 (*vp->func)(strchr(s, '=') + 1);
12473 if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0)
12476 vp->flags &= ~(VTEXTFIXED|VSTACK|VUNSET);
12477 vp->flags |= flags;
12481 * We could roll this to a function, to handle it as
12482 * a regular variable function callback, but why bother?
12484 if (iflag && (vp == &vmpath || (vp == &vmail && !mpathset())))
12490 vp = ckmalloc(sizeof (*vp));
12501 * Process a linked list of variable assignments.
12506 struct strlist *mylist;
12508 struct strlist *lp;
12511 for (lp = mylist ; lp ; lp = lp->next) {
12512 setvareq(savestr(lp->text), 0);
12520 * Find the value of a variable. Returns NULL if not set.
12523 static const char *
12529 if ((v = *findvar(hashvar(name), name)) && !(v->flags & VUNSET)) {
12530 return strchr(v->text, '=') + 1;
12538 * Search the environment of a builtin command.
12541 static const char *
12542 bltinlookup(const char *name)
12544 const struct strlist *sp;
12546 for (sp = cmdenviron ; sp ; sp = sp->next) {
12547 if (varequal(sp->text, name))
12548 return strchr(sp->text, '=') + 1;
12550 return lookupvar(name);
12556 * Generate a list of exported variables. This routine is used to construct
12557 * the third argument to execve when executing a program.
12569 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
12570 for (vp = *vpp ; vp ; vp = vp->next)
12571 if (vp->flags & VEXPORT)
12574 ep = env = stalloc((nenv + 1) * sizeof *env);
12575 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
12576 for (vp = *vpp ; vp ; vp = vp->next)
12577 if (vp->flags & VEXPORT)
12586 * Called when a shell procedure is invoked to clear out nonexported
12587 * variables. It is also necessary to reallocate variables of with
12588 * VSTACK set since these are currently allocated on the stack.
12594 struct var *vp, **prev;
12596 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
12597 for (prev = vpp ; (vp = *prev) != NULL ; ) {
12598 if ((vp->flags & VEXPORT) == 0) {
12600 if ((vp->flags & VTEXTFIXED) == 0)
12602 if ((vp->flags & VSTRFIXED) == 0)
12605 if (vp->flags & VSTACK) {
12606 vp->text = savestr(vp->text);
12607 vp->flags &=~ VSTACK;
12619 * Command to list all variables which are set. Currently this command
12620 * is invoked from the set command when the set command is called without
12625 showvarscmd(argc, argv)
12629 showvars(nullstr, VUNSET, VUNSET);
12636 * The export and readonly commands.
12640 exportcmd(argc, argv)
12647 int flag = argv[0][0] == 'r'? VREADONLY : VEXPORT;
12650 listsetvar(cmdenviron);
12651 pflag = (nextopt("p") == 'p');
12652 if (argc > 1 && !pflag) {
12653 while ((name = *argptr++) != NULL) {
12654 if ((p = strchr(name, '=')) != NULL) {
12657 if ((vp = *findvar(hashvar(name), name))) {
12662 setvar(name, p, flag);
12666 showvars(argv[0], flag, 0);
12673 * The "local" command.
12676 /* funcnest nonzero if we are currently evaluating a function */
12679 localcmd(argc, argv)
12686 error("Not in a function");
12687 while ((name = *argptr++) != NULL) {
12695 * Make a variable a local variable. When a variable is made local, it's
12696 * value and flags are saved in a localvar structure. The saved values
12697 * will be restored when the shell function returns. We handle the name
12698 * "-" as a special case.
12705 struct localvar *lvp;
12710 lvp = ckmalloc(sizeof (struct localvar));
12711 if (name[0] == '-' && name[1] == '\0') {
12713 p = ckmalloc(sizeof optet_vals);
12714 lvp->text = memcpy(p, optet_vals, sizeof optet_vals);
12717 vpp = hashvar(name);
12718 vp = *findvar(vpp, name);
12720 if (strchr(name, '='))
12721 setvareq(savestr(name), VSTRFIXED);
12723 setvar(name, NULL, VSTRFIXED);
12724 vp = *vpp; /* the new variable */
12726 lvp->flags = VUNSET;
12728 lvp->text = vp->text;
12729 lvp->flags = vp->flags;
12730 vp->flags |= VSTRFIXED|VTEXTFIXED;
12731 if (strchr(name, '='))
12732 setvareq(savestr(name), 0);
12736 lvp->next = localvars;
12743 * Called after a function returns.
12748 struct localvar *lvp;
12751 while ((lvp = localvars) != NULL) {
12752 localvars = lvp->next;
12754 if (vp == NULL) { /* $- saved */
12755 memcpy(optet_vals, lvp->text, sizeof optet_vals);
12757 } else if ((lvp->flags & (VUNSET|VSTRFIXED)) == VUNSET) {
12758 (void)unsetvar(vp->text);
12760 if ((vp->flags & VTEXTFIXED) == 0)
12762 vp->flags = lvp->flags;
12763 vp->text = lvp->text;
12771 setvarcmd(argc, argv)
12776 return unsetcmd(argc, argv);
12777 else if (argc == 3)
12778 setvar(argv[1], argv[2], 0);
12780 error("List assignment not implemented");
12786 * The unset builtin command. We unset the function before we unset the
12787 * variable to allow a function to be unset when there is a readonly variable
12788 * with the same name.
12792 unsetcmd(argc, argv)
12802 while ((i = nextopt("vf")) != '\0') {
12808 if (flg_func == 0 && flg_var == 0)
12811 for (ap = argptr; *ap ; ap++) {
12815 ret |= unsetvar(*ap);
12822 * Unset the specified variable.
12826 unsetvar(const char *s)
12831 vpp = findvar(hashvar(s), s);
12834 if (vp->flags & VREADONLY)
12837 if (*(strchr(vp->text, '=') + 1) != '\0')
12838 setvar(s, nullstr, 0);
12839 vp->flags &= ~VEXPORT;
12840 vp->flags |= VUNSET;
12841 if ((vp->flags & VSTRFIXED) == 0) {
12842 if ((vp->flags & VTEXTFIXED) == 0)
12857 * Find the appropriate entry in the hash table from the name.
12860 static struct var **
12861 hashvar(const char *p)
12863 unsigned int hashval;
12865 hashval = ((unsigned char) *p) << 4;
12866 while (*p && *p != '=')
12867 hashval += (unsigned char) *p++;
12868 return &vartab[hashval % VTABSIZE];
12874 * Returns true if the two strings specify the same varable. The first
12875 * variable name is terminated by '='; the second may be terminated by
12876 * either '=' or '\0'.
12880 varequal(const char *p, const char *q)
12882 while (*p == *q++) {
12886 if (*p == '=' && *(q - 1) == '\0')
12892 showvars(const char *myprefix, int mask, int xor)
12896 const char *sep = myprefix == nullstr ? myprefix : spcstr;
12898 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
12899 for (vp = *vpp ; vp ; vp = vp->next) {
12900 if ((vp->flags & mask) ^ xor) {
12904 p = strchr(vp->text, '=') + 1;
12905 len = p - vp->text;
12906 p = single_quote(p);
12908 printf("%s%s%.*s%s\n", myprefix, sep, len,
12916 static struct var **
12917 findvar(struct var **vpp, const char *name)
12919 for (; *vpp; vpp = &(*vpp)->next) {
12920 if (varequal((*vpp)->text, name)) {
12928 * Copyright (c) 1999 Herbert Xu <herbert@debian.org>
12929 * This file contains code for the times builtin.
12930 * $Id: ash.c,v 1.9 2001/07/10 16:57:09 andersen Exp $
12932 static int timescmd (int argc, char **argv)
12935 long int clk_tck = sysconf(_SC_CLK_TCK);
12938 printf("%dm%fs %dm%fs\n%dm%fs %dm%fs\n",
12939 (int) (buf.tms_utime / clk_tck / 60),
12940 ((double) buf.tms_utime) / clk_tck,
12941 (int) (buf.tms_stime / clk_tck / 60),
12942 ((double) buf.tms_stime) / clk_tck,
12943 (int) (buf.tms_cutime / clk_tck / 60),
12944 ((double) buf.tms_cutime) / clk_tck,
12945 (int) (buf.tms_cstime / clk_tck / 60),
12946 ((double) buf.tms_cstime) / clk_tck);
12952 * Copyright (c) 1989, 1991, 1993, 1994
12953 * The Regents of the University of California. All rights reserved.
12955 * This code is derived from software contributed to Berkeley by
12956 * Kenneth Almquist.
12958 * Redistribution and use in source and binary forms, with or without
12959 * modification, are permitted provided that the following conditions
12961 * 1. Redistributions of source code must retain the above copyright
12962 * notice, this list of conditions and the following disclaimer.
12963 * 2. Redistributions in binary form must reproduce the above copyright
12964 * notice, this list of conditions and the following disclaimer in the
12965 * documentation and/or other materials provided with the distribution.
12967 * 3. <BSD Advertising Clause omitted per the July 22, 1999 licensing change
12968 * ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change>
12970 * 4. Neither the name of the University nor the names of its contributors
12971 * may be used to endorse or promote products derived from this software
12972 * without specific prior written permission.
12974 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
12975 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
12976 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
12977 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
12978 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
12979 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
12980 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
12981 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
12982 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
12983 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF