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 <dzo@simtreas.ru> 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 i = safe_read(in.fd, buf, sizeof buf);
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.
6094 /* 1 == check for aliases, 2 == also check for assignments */
6095 static int checkalias; /* also used in no alias mode for check assignments */
6109 if (exception != EXSHELLPROC)
6110 parselleft = parsenleft = 0; /* clear input buffer */
6114 /* from parser.c: */
6132 * This file implements the input routines used by the parser.
6135 #ifdef BB_FEATURE_COMMAND_EDITING
6136 static const char * cmdedit_prompt;
6137 static inline void putprompt(const char *s) {
6141 static inline void putprompt(const char *s) {
6146 #define EOF_NLEFT -99 /* value of parsenleft when EOF pushed back */
6151 * Same as pgetc(), but ignores PEOA.
6161 } while (c == PEOA);
6165 static inline int pgetc2() { return pgetc_macro(); }
6169 * Read a line from the script.
6172 static inline char *
6173 pfgets(char *line, int len)
6179 while (--nleft > 0) {
6198 char *buf = parsefile->buf;
6202 #ifdef BB_FEATURE_COMMAND_EDITING
6205 nr = safe_read(parsefile->fd, buf, BUFSIZ - 1);
6207 cmdedit_read_input((char*)cmdedit_prompt, buf);
6212 nr = safe_read(parsefile->fd, buf, BUFSIZ - 1);
6216 if (parsefile->fd == 0 && errno == EWOULDBLOCK) {
6217 int flags = fcntl(0, F_GETFL, 0);
6218 if (flags >= 0 && flags & O_NONBLOCK) {
6219 flags &=~ O_NONBLOCK;
6220 if (fcntl(0, F_SETFL, flags) >= 0) {
6221 out2str("sh: turning off NDELAY mode\n");
6233 struct strpush *sp = parsefile->strpush;
6238 if (parsenextc[-1] == ' ' || parsenextc[-1] == '\t') {
6243 if (sp->string != sp->ap->val) {
6247 sp->ap->flag &= ~ALIASINUSE;
6248 if (sp->ap->flag & ALIASDEAD) {
6249 unalias(sp->ap->name);
6253 parsenextc = sp->prevstring;
6254 parsenleft = sp->prevnleft;
6255 /*dprintf("*** calling popstring: restoring to '%s'\n", parsenextc);*/
6256 parsefile->strpush = sp->prev;
6257 if (sp != &(parsefile->basestrpush))
6264 * Refill the input buffer and return the next input character:
6266 * 1) If a string was pushed back on the input, pop it;
6267 * 2) If an EOF was pushed back (parsenleft == EOF_NLEFT) or we are reading
6268 * from a string so we can't refill the buffer, return EOF.
6269 * 3) If the is more stuff in this buffer, use it else call read to fill it.
6270 * 4) Process input up to the next newline, deleting nul characters.
6280 while (parsefile->strpush) {
6282 if (parsenleft == -1 && parsefile->strpush->ap &&
6283 parsenextc[-1] != ' ' && parsenextc[-1] != '\t') {
6288 if (--parsenleft >= 0)
6289 return (*parsenextc++);
6291 if (parsenleft == EOF_NLEFT || parsefile->buf == NULL)
6296 if (parselleft <= 0) {
6297 if ((parselleft = preadfd()) <= 0) {
6298 parselleft = parsenleft = EOF_NLEFT;
6305 /* delete nul characters */
6306 for (more = 1; more;) {
6314 parsenleft = q - parsenextc;
6315 more = 0; /* Stop processing here */
6321 if (--parselleft <= 0 && more) {
6322 parsenleft = q - parsenextc - 1;
6333 out2str(parsenextc);
6338 return *parsenextc++;
6343 * Push a string back onto the input at this current parsefile level.
6344 * We handle aliases this way.
6347 pushstring(char *s, int len, void *ap)
6352 /*dprintf("*** calling pushstring: %s, %d\n", s, len);*/
6353 if (parsefile->strpush) {
6354 sp = ckmalloc(sizeof (struct strpush));
6355 sp->prev = parsefile->strpush;
6356 parsefile->strpush = sp;
6358 sp = parsefile->strpush = &(parsefile->basestrpush);
6359 sp->prevstring = parsenextc;
6360 sp->prevnleft = parsenleft;
6362 sp->ap = (struct alias *)ap;
6364 ((struct alias *)ap)->flag |= ALIASINUSE;
6375 * Like setinputfile, but takes input from a string.
6379 setinputstring(char *string)
6383 parsenextc = string;
6384 parsenleft = strlen(string);
6385 parsefile->buf = NULL;
6393 * To handle the "." command, a stack of input files is used. Pushfile
6394 * adds a new entry to the stack and popfile restores the previous level.
6399 struct parsefile *pf;
6401 parsefile->nleft = parsenleft;
6402 parsefile->lleft = parselleft;
6403 parsefile->nextc = parsenextc;
6404 parsefile->linno = plinno;
6405 pf = (struct parsefile *)ckmalloc(sizeof (struct parsefile));
6406 pf->prev = parsefile;
6409 pf->basestrpush.prev = NULL;
6414 static void restartjob (struct job *);
6416 static void freejob (struct job *);
6417 static struct job *getjob (const char *);
6418 static int dowait (int, struct job *);
6419 static void waitonint(int);
6423 * We keep track of whether or not fd0 has been redirected. This is for
6424 * background commands, where we want to redirect fd0 to /dev/null only
6425 * if it hasn't already been redirected.
6427 static int fd0_redirected = 0;
6429 /* Return true if fd 0 has already been redirected at least once. */
6431 fd0_redirected_p () {
6432 return fd0_redirected != 0;
6435 static void dupredirect (const union node *, int, int fd1dup);
6439 * Turn job control on and off.
6441 * Note: This code assumes that the third arg to ioctl is a character
6442 * pointer, which is true on Berkeley systems but not System V. Since
6443 * System V doesn't have job control yet, this isn't a problem now.
6448 static void setjobctl(int enable)
6450 #ifdef OLD_TTY_DRIVER
6454 if (enable == jobctl || rootshell == 0)
6457 do { /* while we are in the background */
6458 #ifdef OLD_TTY_DRIVER
6459 if (ioctl(2, TIOCGPGRP, (char *)&initialpgrp) < 0) {
6461 initialpgrp = tcgetpgrp(2);
6462 if (initialpgrp < 0) {
6464 out2str("sh: can't access tty; job control turned off\n");
6468 if (initialpgrp == -1)
6469 initialpgrp = getpgrp();
6470 else if (initialpgrp != getpgrp()) {
6471 killpg(initialpgrp, SIGTTIN);
6475 #ifdef OLD_TTY_DRIVER
6476 if (ioctl(2, TIOCGETD, (char *)&ldisc) < 0 || ldisc != NTTYDISC) {
6477 out2str("sh: need new tty driver to run job control; job control turned off\n");
6485 setpgid(0, rootpid);
6486 #ifdef OLD_TTY_DRIVER
6487 ioctl(2, TIOCSPGRP, (char *)&rootpid);
6489 tcsetpgrp(2, rootpid);
6491 } else { /* turning job control off */
6492 setpgid(0, initialpgrp);
6493 #ifdef OLD_TTY_DRIVER
6494 ioctl(2, TIOCSPGRP, (char *)&initialpgrp);
6496 tcsetpgrp(2, initialpgrp);
6507 /* A translation list so we can be polite to our users. */
6508 static char *signal_names[NSIG + 2] = {
6596 "Usage: kill [-s sigspec | -signum | -sigspec] [pid | job]... or\n"
6597 "kill -l [exitstatus]"
6601 if (*argv[1] == '-') {
6602 signo = decode_signal(argv[1] + 1, 1);
6606 while ((c = nextopt("ls:")) != '\0')
6612 signo = decode_signal(optionarg, 1);
6615 "invalid signal number or name: %s",
6623 "nextopt returned character code 0%o", c);
6630 if (!list && signo < 0)
6633 if ((signo < 0 || !*argptr) ^ list) {
6640 for (i = 1; i < NSIG; i++) {
6641 printf(snlfmt, signal_names[i] + 3);
6645 signo = atoi(*argptr);
6648 if (0 < signo && signo < NSIG)
6649 printf(snlfmt, signal_names[signo] + 3);
6651 error("invalid signal number or exit status: %s",
6657 if (**argptr == '%') {
6658 jp = getjob(*argptr);
6659 if (jp->jobctl == 0)
6660 error("job %s not created under job control",
6662 pid = -jp->ps[0].pid;
6664 pid = atoi(*argptr);
6665 if (kill(pid, signo) != 0)
6666 error("%s: %m", *argptr);
6667 } while (*++argptr);
6681 jp = getjob(argv[1]);
6682 if (jp->jobctl == 0)
6683 error("job not created under job control");
6684 pgrp = jp->ps[0].pid;
6685 #ifdef OLD_TTY_DRIVER
6686 ioctl(2, TIOCSPGRP, (char *)&pgrp);
6692 status = waitforjob(jp);
6706 jp = getjob(*++argv);
6707 if (jp->jobctl == 0)
6708 error("job not created under job control");
6710 } while (--argc > 1);
6719 struct procstat *ps;
6722 if (jp->state == JOBDONE)
6725 killpg(jp->ps[0].pid, SIGCONT);
6726 for (ps = jp->ps, i = jp->nprocs ; --i >= 0 ; ps++) {
6727 if (WIFSTOPPED(ps->status)) {
6736 static void showjobs(int change);
6750 * Print a list of jobs. If "change" is nonzero, only print jobs whose
6751 * statuses have changed since the last call to showjobs.
6753 * If the shell is interrupted in the process of creating a job, the
6754 * result may be a job structure containing zero processes. Such structures
6755 * will be freed here.
6766 struct procstat *ps;
6770 TRACE(("showjobs(%d) called\n", change));
6771 while (dowait(0, (struct job *)NULL) > 0);
6772 for (jobno = 1, jp = jobtab ; jobno <= njobs ; jobno++, jp++) {
6775 if (jp->nprocs == 0) {
6779 if (change && ! jp->changed)
6781 procno = jp->nprocs;
6782 for (ps = jp->ps ; ; ps++) { /* for each process */
6784 snprintf(s, 64, "[%d] %ld ", jobno,
6787 snprintf(s, 64, " %ld ",
6792 if (ps->status == -1) {
6793 /* don't print anything */
6794 } else if (WIFEXITED(ps->status)) {
6795 snprintf(s, 64, "Exit %d",
6796 WEXITSTATUS(ps->status));
6799 if (WIFSTOPPED(ps->status))
6800 i = WSTOPSIG(ps->status);
6801 else /* WIFSIGNALED(ps->status) */
6803 i = WTERMSIG(ps->status);
6804 if ((i & 0x7F) < NSIG && sys_siglist[i & 0x7F])
6805 strcpy(s, sys_siglist[i & 0x7F]);
6807 snprintf(s, 64, "Signal %d", i & 0x7F);
6808 if (WCOREDUMP(ps->status))
6809 strcat(s, " (core dumped)");
6814 "%*c%s\n", 30 - col >= 0 ? 30 - col : 0, ' ',
6821 if (jp->state == JOBDONE) {
6829 * Mark a job structure as unused.
6833 freejob(struct job *jp)
6835 const struct procstat *ps;
6839 for (i = jp->nprocs, ps = jp->ps ; --i >= 0 ; ps++) {
6840 if (ps->cmd != nullstr)
6843 if (jp->ps != &jp->ps0)
6847 if (curjob == jp - jobtab + 1)
6866 job = getjob(*++argv);
6870 for (;;) { /* loop until process terminated or stopped */
6873 status = job->ps[job->nprocs - 1].status;
6879 if (WIFEXITED(status))
6880 retval = WEXITSTATUS(status);
6882 else if (WIFSTOPPED(status))
6883 retval = WSTOPSIG(status) + 128;
6886 /* XXX: limits number of signals */
6887 retval = WTERMSIG(status) + 128;
6892 for (jp = jobtab ; ; jp++) {
6893 if (jp >= jobtab + njobs) { /* no running procs */
6896 if (jp->used && jp->state == 0)
6900 if (dowait(2, 0) < 0 && errno == EINTR) {
6909 * Convert a job name to a job structure.
6913 getjob(const char *name)
6923 if ((jobno = curjob) == 0 || jobtab[jobno - 1].used == 0)
6924 error("No current job");
6925 return &jobtab[jobno - 1];
6927 error("No current job");
6929 } else if (name[0] == '%') {
6930 if (is_digit(name[1])) {
6931 jobno = number(name + 1);
6932 if (jobno > 0 && jobno <= njobs
6933 && jobtab[jobno - 1].used != 0)
6934 return &jobtab[jobno - 1];
6936 } else if (name[1] == '%' && name[2] == '\0') {
6940 struct job *found = NULL;
6941 for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) {
6942 if (jp->used && jp->nprocs > 0
6943 && prefix(name + 1, jp->ps[0].cmd)) {
6945 error("%s: ambiguous", name);
6952 } else if (is_number(name, &pid)) {
6953 for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) {
6954 if (jp->used && jp->nprocs > 0
6955 && jp->ps[jp->nprocs - 1].pid == pid)
6959 error("No such job: %s", name);
6966 * Return a new job structure,
6970 makejob(const union node *node, int nprocs)
6975 for (i = njobs, jp = jobtab ; ; jp++) {
6979 jobtab = ckmalloc(4 * sizeof jobtab[0]);
6981 jp = ckmalloc((njobs + 4) * sizeof jobtab[0]);
6982 memcpy(jp, jobtab, njobs * sizeof jp[0]);
6983 /* Relocate `ps' pointers */
6984 for (i = 0; i < njobs; i++)
6985 if (jp[i].ps == &jobtab[i].ps0)
6986 jp[i].ps = &jp[i].ps0;
6990 jp = jobtab + njobs;
6991 for (i = 4 ; --i >= 0 ; jobtab[njobs++].used = 0);
7004 jp->jobctl = jobctl;
7007 jp->ps = ckmalloc(nprocs * sizeof (struct procstat));
7012 TRACE(("makejob(0x%lx, %d) returns %%%d\n", (long)node, nprocs,
7019 * Fork of a subshell. If we are doing job control, give the subshell its
7020 * own process group. Jp is a job structure that the job is to be added to.
7021 * N is the command that will be evaluated by the child. Both jp and n may
7022 * be NULL. The mode parameter can be one of the following:
7023 * FORK_FG - Fork off a foreground process.
7024 * FORK_BG - Fork off a background process.
7025 * FORK_NOJOB - Like FORK_FG, but don't give the process its own
7026 * process group even if job control is on.
7028 * When job control is turned off, background processes have their standard
7029 * input redirected to /dev/null (except for the second and later processes
7036 forkshell(struct job *jp, const union node *n, int mode)
7042 const char *devnull = _PATH_DEVNULL;
7043 const char *nullerr = "Can't open %s";
7045 TRACE(("forkshell(%%%d, 0x%lx, %d) called\n", jp - jobtab, (long)n,
7050 TRACE(("Fork failed, errno=%d\n", errno));
7052 error("Cannot fork");
7059 TRACE(("Child shell %d\n", getpid()));
7060 wasroot = rootshell;
7066 jobctl = 0; /* do job control only in root shell */
7067 if (wasroot && mode != FORK_NOJOB && mflag) {
7068 if (jp == NULL || jp->nprocs == 0)
7071 pgrp = jp->ps[0].pid;
7073 if (mode == FORK_FG) {
7074 /*** this causes superfluous TIOCSPGRPS ***/
7075 #ifdef OLD_TTY_DRIVER
7076 if (ioctl(2, TIOCSPGRP, (char *)&pgrp) < 0)
7077 error("TIOCSPGRP failed, errno=%d", errno);
7079 if (tcsetpgrp(2, pgrp) < 0)
7080 error("tcsetpgrp failed, errno=%d", errno);
7085 } else if (mode == FORK_BG) {
7088 if ((jp == NULL || jp->nprocs == 0) &&
7089 ! fd0_redirected_p ()) {
7091 if (open(devnull, O_RDONLY) != 0)
7092 error(nullerr, devnull);
7096 if (mode == FORK_BG) {
7099 if ((jp == NULL || jp->nprocs == 0) &&
7100 ! fd0_redirected_p ()) {
7102 if (open(devnull, O_RDONLY) != 0)
7103 error(nullerr, devnull);
7107 for (i = njobs, p = jobtab ; --i >= 0 ; p++)
7110 if (wasroot && iflag) {
7118 if (rootshell && mode != FORK_NOJOB && mflag) {
7119 if (jp == NULL || jp->nprocs == 0)
7122 pgrp = jp->ps[0].pid;
7126 if (mode == FORK_BG)
7127 backgndpid = pid; /* set $! */
7129 struct procstat *ps = &jp->ps[jp->nprocs++];
7133 if (iflag && rootshell && n)
7134 ps->cmd = commandtext(n);
7137 TRACE(("In parent shell: child = %d\n", pid));
7144 * Wait for job to finish.
7146 * Under job control we have the problem that while a child process is
7147 * running interrupts generated by the user are sent to the child but not
7148 * to the shell. This means that an infinite loop started by an inter-
7149 * active user may be hard to kill. With job control turned off, an
7150 * interactive user may place an interactive program inside a loop. If
7151 * the interactive program catches interrupts, the user doesn't want
7152 * these interrupts to also abort the loop. The approach we take here
7153 * is to have the shell ignore interrupt signals while waiting for a
7154 * forground process to terminate, and then send itself an interrupt
7155 * signal if the child process was terminated by an interrupt signal.
7156 * Unfortunately, some programs want to do a bit of cleanup and then
7157 * exit on interrupt; unless these processes terminate themselves by
7158 * sending a signal to themselves (instead of calling exit) they will
7159 * confuse this approach.
7163 waitforjob(struct job *jp)
7166 int mypgrp = getpgrp();
7170 struct sigaction act, oact;
7179 sigaction(SIGINT, 0, &act);
7180 act.sa_handler = waitonint;
7181 sigaction(SIGINT, &act, &oact);
7183 TRACE(("waitforjob(%%%d) called\n", jp - jobtab + 1));
7184 while (jp->state == 0) {
7192 sigaction(SIGINT, &oact, 0);
7193 if (intreceived && trap[SIGINT]) kill(getpid(), SIGINT);
7197 #ifdef OLD_TTY_DRIVER
7198 if (ioctl(2, TIOCSPGRP, (char *)&mypgrp) < 0)
7199 error("TIOCSPGRP failed, errno=%d\n", errno);
7201 if (tcsetpgrp(2, mypgrp) < 0)
7202 error("tcsetpgrp failed, errno=%d\n", errno);
7205 if (jp->state == JOBSTOPPED)
7206 curjob = jp - jobtab + 1;
7208 status = jp->ps[jp->nprocs - 1].status;
7209 /* convert to 8 bits */
7210 if (WIFEXITED(status))
7211 st = WEXITSTATUS(status);
7213 else if (WIFSTOPPED(status))
7214 st = WSTOPSIG(status) + 128;
7217 st = WTERMSIG(status) + 128;
7221 * This is truly gross.
7222 * If we're doing job control, then we did a TIOCSPGRP which
7223 * caused us (the shell) to no longer be in the controlling
7224 * session -- so we wouldn't have seen any ^C/SIGINT. So, we
7225 * intuit from the subprocess exit status whether a SIGINT
7226 * occured, and if so interrupt ourselves. Yuck. - mycroft
7228 if (WIFSIGNALED(status) && WTERMSIG(status) == SIGINT)
7231 if (jp->state == JOBDONE)
7242 * Wait for a process to terminate.
7246 * Do a wait system call. If job control is compiled in, we accept
7247 * stopped processes. If block is zero, we return a value of zero
7248 * rather than blocking.
7250 * System V doesn't have a non-blocking wait system call. It does
7251 * have a SIGCLD signal that is sent to a process when one of it's
7252 * children dies. The obvious way to use SIGCLD would be to install
7253 * a handler for SIGCLD which simply bumped a counter when a SIGCLD
7254 * was received, and have waitproc bump another counter when it got
7255 * the status of a process. Waitproc would then know that a wait
7256 * system call would not block if the two counters were different.
7257 * This approach doesn't work because if a process has children that
7258 * have not been waited for, System V will send it a SIGCLD when it
7259 * installs a signal handler for SIGCLD. What this means is that when
7260 * a child exits, the shell will be sent SIGCLD signals continuously
7261 * until is runs out of stack space, unless it does a wait call before
7262 * restoring the signal handler. The code below takes advantage of
7263 * this (mis)feature by installing a signal handler for SIGCLD and
7264 * then checking to see whether it was called. If there are any
7265 * children to be waited for, it will be.
7270 waitproc(int block, int *status)
7281 return wait3(status, flags, (struct rusage *)NULL);
7285 dowait(int block, struct job *job)
7289 struct procstat *sp;
7291 struct job *thisjob;
7297 TRACE(("dowait(%d) called\n", block));
7299 pid = waitproc(block, &status);
7300 TRACE(("wait returns %d, status=%d\n", pid, status));
7301 } while (!(block & 2) && pid == -1 && errno == EINTR);
7306 for (jp = jobtab ; jp < jobtab + njobs ; jp++) {
7310 for (sp = jp->ps ; sp < jp->ps + jp->nprocs ; sp++) {
7313 if (sp->pid == pid) {
7314 TRACE(("Changing status of proc %d from 0x%x to 0x%x\n", pid, sp->status, status));
7315 sp->status = status;
7318 if (sp->status == -1)
7320 else if (WIFSTOPPED(sp->status))
7323 if (stopped) { /* stopped or done */
7324 int state = done? JOBDONE : JOBSTOPPED;
7325 if (jp->state != state) {
7326 TRACE(("Job %d: changing state from %d to %d\n", jp - jobtab + 1, jp->state, state));
7329 if (done && curjob == jp - jobtab + 1)
7330 curjob = 0; /* no current job */
7337 if (! rootshell || ! iflag || (job && thisjob == job)) {
7338 core = WCOREDUMP(status);
7340 if (WIFSTOPPED(status)) sig = WSTOPSIG(status);
7343 if (WIFEXITED(status)) sig = 0;
7344 else sig = WTERMSIG(status);
7346 if (sig != 0 && sig != SIGINT && sig != SIGPIPE) {
7348 out2fmt("%d: ", pid);
7350 if (sig == SIGTSTP && rootshell && iflag)
7352 (long)(job - jobtab + 1));
7354 if (sig < NSIG && sys_siglist[sig])
7355 out2str(sys_siglist[sig]);
7357 out2fmt("Signal %d", sig);
7359 out2str(" - core dumped");
7362 TRACE(("Not printing status: status=%d, sig=%d\n",
7366 TRACE(("Not printing status, rootshell=%d, job=0x%x\n", rootshell, job));
7368 thisjob->changed = 1;
7377 * return 1 if there are stopped jobs, otherwise 0
7387 for (jobno = 1, jp = jobtab; jobno <= njobs; jobno++, jp++) {
7390 if (jp->state == JOBSTOPPED) {
7391 out2str("You have stopped jobs.\n");
7401 * Return a string identifying a command (to be printed by the
7405 static char *cmdnextc;
7406 static int cmdnleft;
7407 #define MAXCMDTEXT 200
7410 cmdputs(const char *s)
7421 while ((c = *p++) != '\0') {
7424 else if (c == CTLVAR) {
7429 } else if (c == '=' && subtype != 0) {
7430 *q++ = "}-+?="[(subtype & VSTYPE) - VSNORMAL];
7432 } else if (c == CTLENDVAR) {
7434 } else if (c == CTLBACKQ || c == CTLBACKQ+CTLQUOTE)
7435 cmdnleft++; /* ignore it */
7438 if (--cmdnleft <= 0) {
7450 cmdtxt(const union node *n)
7453 struct nodelist *lp;
7462 cmdtxt(n->nbinary.ch1);
7464 cmdtxt(n->nbinary.ch2);
7467 cmdtxt(n->nbinary.ch1);
7469 cmdtxt(n->nbinary.ch2);
7472 cmdtxt(n->nbinary.ch1);
7474 cmdtxt(n->nbinary.ch2);
7477 for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
7485 cmdtxt(n->nredir.n);
7490 cmdtxt(n->nredir.n);
7494 cmdtxt(n->nif.test);
7496 cmdtxt(n->nif.ifpart);
7505 cmdtxt(n->nbinary.ch1);
7507 cmdtxt(n->nbinary.ch2);
7512 cmdputs(n->nfor.var);
7517 cmdputs(n->ncase.expr->narg.text);
7521 cmdputs(n->narg.text);
7525 for (np = n->ncmd.args ; np ; np = np->narg.next) {
7530 for (np = n->ncmd.redirect ; np ; np = np->nfile.next) {
7536 cmdputs(n->narg.text);
7539 p = ">"; i = 1; goto redir;
7541 p = ">>"; i = 1; goto redir;
7543 p = ">&"; i = 1; goto redir;
7545 p = ">|"; i = 1; goto redir;
7547 p = "<"; i = 0; goto redir;
7549 p = "<&"; i = 0; goto redir;
7551 p = "<>"; i = 0; goto redir;
7553 if (n->nfile.fd != i) {
7554 s[0] = n->nfile.fd + '0';
7559 if (n->type == NTOFD || n->type == NFROMFD) {
7560 s[0] = n->ndup.dupfd + '0';
7564 cmdtxt(n->nfile.fname);
7579 commandtext(const union node *n)
7583 cmdnextc = name = ckmalloc(MAXCMDTEXT);
7584 cmdnleft = MAXCMDTEXT - 4;
7591 static void waitonint(int sig) {
7596 * Routines to check for mail. (Perhaps make part of main.c?)
7600 #define MAXMBOXES 10
7603 static int nmboxes; /* number of mailboxes */
7604 static time_t mailtime[MAXMBOXES]; /* times of mailboxes */
7609 * Print appropriate message(s) if mail has arrived. If the argument is
7610 * nozero, then the value of MAIL has changed, so we just update the
7621 struct stackmark smark;
7628 setstackmark(&smark);
7629 mpath = mpathset()? mpathval() : mailval();
7630 for (i = 0 ; i < nmboxes ; i++) {
7631 p = padvance(&mpath, nullstr);
7636 for (q = p ; *q ; q++);
7641 q[-1] = '\0'; /* delete trailing '/' */
7642 if (stat(p, &statb) < 0)
7644 if (statb.st_size > mailtime[i] && ! silent) {
7646 pathopt? pathopt : "you have mail");
7648 mailtime[i] = statb.st_size;
7651 popstackmark(&smark);
7657 static short profile_buf[16384];
7661 static void read_profile (const char *);
7662 static void cmdloop (int);
7663 static void options (int);
7664 static void setoption (int, int);
7665 static void procargs (int, char **);
7669 * Main routine. We initialize things, parse the arguments, execute
7670 * profiles if we're a login shell, and then call cmdloop to execute
7671 * commands. The setjmp call sets up the location to jump to when an
7672 * exception occurs. When an exception occurs the variable "state"
7673 * is used to figure out how far we had gotten.
7677 shell_main(argc, argv)
7681 struct jmploc jmploc;
7682 struct stackmark smark;
7686 BLTINCMD = find_builtin("builtin");
7687 EXECCMD = find_builtin("exec");
7688 EVALCMD = find_builtin("eval");
7690 #ifndef BB_FEATURE_SH_FANCY_PROMPT
7696 monitor(4, etext, profile_buf, sizeof profile_buf, 50);
7698 #if defined(linux) || defined(__GNU__)
7699 signal(SIGCHLD, SIG_DFL);
7702 if (setjmp(jmploc.loc)) {
7705 * When a shell procedure is executed, we raise the
7706 * exception EXSHELLPROC to clean up before executing
7707 * the shell procedure.
7709 switch (exception) {
7718 exitstatus = exerrno;
7729 if (exception != EXSHELLPROC) {
7730 if (state == 0 || iflag == 0 || ! rootshell)
7731 exitshell(exitstatus);
7734 if (exception == EXINT) {
7737 popstackmark(&smark);
7738 FORCEINTON; /* enable interrupts */
7741 else if (state == 2)
7743 else if (state == 3)
7751 trputs("Shell args: "); trargs(argv);
7756 setstackmark(&smark);
7757 procargs(argc, argv);
7758 if (argv[0] && argv[0][0] == '-') {
7760 read_profile("/etc/profile");
7763 read_profile(".profile");
7768 if (getuid() == geteuid() && getgid() == getegid()) {
7770 if ((shinit = lookupvar("ENV")) != NULL && *shinit != '\0') {
7772 read_profile(shinit);
7779 if (sflag == 0 || minusc) {
7780 static int sigs[] = {
7781 SIGINT, SIGQUIT, SIGHUP,
7787 #define SIGSSIZE (sizeof(sigs)/sizeof(sigs[0]))
7790 for (i = 0; i < SIGSSIZE; i++)
7795 evalstring(minusc, 0);
7797 if (sflag || minusc == NULL) {
7798 state4: /* XXX ??? - why isn't this before the "if" statement */
7804 exitshell(exitstatus);
7810 * Read and execute commands. "Top" is nonzero for the top level command
7811 * loop; it turns on prompting if the shell is interactive.
7818 struct stackmark smark;
7822 TRACE(("cmdloop(%d) called\n", top));
7823 setstackmark(&smark);
7834 n = parsecmd(inter);
7835 /* showtree(n); DEBUG */
7837 if (!top || numeof >= 50)
7839 if (!stoppedjobs()) {
7842 out2str("\nUse \"exit\" to leave shell.\n");
7845 } else if (n != NULL && nflag == 0) {
7846 job_warning = (job_warning == 2) ? 1 : 0;
7850 popstackmark(&smark);
7851 setstackmark(&smark);
7852 if (evalskip == SKIPFILE) {
7857 popstackmark(&smark);
7863 * Read /etc/profile or .profile. Return on error.
7875 if ((fd = open(name, O_RDONLY)) >= 0)
7880 /* -q turns off -x and -v just when executing init files */
7883 xflag = 0, xflag_set = 1;
7885 vflag = 0, vflag_set = 1;
7900 * Read a file containing shell functions.
7904 readcmdfile(const char *name)
7909 if ((fd = open(name, O_RDONLY)) >= 0)
7912 error("Can't open %s", name);
7921 * Take commands from a file. To be compatable we should do a path
7922 * search for the file, which is necessary to find sub-commands.
7926 static inline char *
7927 find_dot_file(mybasename)
7931 const char *path = pathval();
7934 /* don't try this for absolute or relative paths */
7935 if (strchr(mybasename, '/'))
7938 while ((fullname = padvance(&path, mybasename)) != NULL) {
7939 if ((stat(fullname, &statb) == 0) && S_ISREG(statb.st_mode)) {
7941 * Don't bother freeing here, since it will
7942 * be freed by the caller.
7946 stunalloc(fullname);
7949 /* not found in the PATH */
7950 error("%s: not found", mybasename);
7962 for (sp = cmdenviron; sp ; sp = sp->next)
7963 setvareq(savestr(sp->text), VSTRFIXED|VTEXTFIXED);
7965 if (argc >= 2) { /* That's what SVR2 does */
7967 struct stackmark smark;
7969 setstackmark(&smark);
7970 fullname = find_dot_file(argv[1]);
7971 setinputfile(fullname, 1);
7972 commandname = fullname;
7975 popstackmark(&smark);
7989 exitstatus = number(argv[1]);
7991 exitstatus = oexitstatus;
7992 exitshell(exitstatus);
8001 nbytes = ALIGN(nbytes);
8002 if (nbytes > stacknleft) {
8004 struct stack_block *sp;
8007 if (blocksize < MINSIZE)
8008 blocksize = MINSIZE;
8010 sp = ckmalloc(sizeof(struct stack_block) - MINSIZE + blocksize);
8012 stacknxt = sp->space;
8013 stacknleft = blocksize;
8019 stacknleft -= nbytes;
8025 stunalloc(pointer p)
8028 if (p == NULL) { /*DEBUG */
8029 write(2, "stunalloc\n", 10);
8033 if (!(stacknxt >= (char *)p && (char *)p >= stackp->space)) {
8036 stacknleft += stacknxt - (char *)p;
8042 setstackmark(struct stackmark *mark)
8044 mark->stackp = stackp;
8045 mark->stacknxt = stacknxt;
8046 mark->stacknleft = stacknleft;
8047 mark->marknext = markp;
8053 popstackmark(struct stackmark *mark)
8055 struct stack_block *sp;
8058 markp = mark->marknext;
8059 while (stackp != mark->stackp) {
8064 stacknxt = mark->stacknxt;
8065 stacknleft = mark->stacknleft;
8071 * When the parser reads in a string, it wants to stick the string on the
8072 * stack and only adjust the stack pointer when it knows how big the
8073 * string is. Stackblock (defined in stack.h) returns a pointer to a block
8074 * of space on top of the stack and stackblocklen returns the length of
8075 * this block. Growstackblock will grow this space by at least one byte,
8076 * possibly moving it (like realloc). Grabstackblock actually allocates the
8077 * part of the block that has been used.
8081 growstackblock(void) {
8083 int newlen = ALIGN(stacknleft * 2 + 100);
8084 char *oldspace = stacknxt;
8085 int oldlen = stacknleft;
8086 struct stack_block *sp;
8087 struct stack_block *oldstackp;
8089 if (stacknxt == stackp->space && stackp != &stackbase) {
8094 sp = ckrealloc((pointer)sp, sizeof(struct stack_block) - MINSIZE + newlen);
8097 stacknxt = sp->space;
8098 stacknleft = newlen;
8100 /* Stack marks pointing to the start of the old block
8101 * must be relocated to point to the new block
8103 struct stackmark *xmark;
8105 while (xmark != NULL && xmark->stackp == oldstackp) {
8106 xmark->stackp = stackp;
8107 xmark->stacknxt = stacknxt;
8108 xmark->stacknleft = stacknleft;
8109 xmark = xmark->marknext;
8114 p = stalloc(newlen);
8115 memcpy(p, oldspace, oldlen);
8116 stacknxt = p; /* free the space */
8117 stacknleft += newlen; /* we just allocated */
8124 grabstackblock(int len)
8134 * The following routines are somewhat easier to use that the above.
8135 * The user declares a variable of type STACKSTR, which may be declared
8136 * to be a register. The macro STARTSTACKSTR initializes things. Then
8137 * the user uses the macro STPUTC to add characters to the string. In
8138 * effect, STPUTC(c, p) is the same as *p++ = c except that the stack is
8139 * grown as necessary. When the user is done, she can just leave the
8140 * string there and refer to it using stackblock(). Or she can allocate
8141 * the space for it using grabstackstr(). If it is necessary to allow
8142 * someone else to use the stack temporarily and then continue to grow
8143 * the string, the user should use grabstack to allocate the space, and
8144 * then call ungrabstr(p) to return to the previous mode of operation.
8146 * USTPUTC is like STPUTC except that it doesn't check for overflow.
8147 * CHECKSTACKSPACE can be called before USTPUTC to ensure that there
8148 * is space for at least one character.
8153 growstackstr(void) {
8154 int len = stackblocksize();
8155 if (herefd >= 0 && len >= 1024) {
8156 xwrite(herefd, stackblock(), len);
8157 sstrnleft = len - 1;
8158 return stackblock();
8161 sstrnleft = stackblocksize() - len - 1;
8162 return stackblock() + len;
8167 * Called from CHECKSTRSPACE.
8171 makestrspace(size_t newlen) {
8172 int len = stackblocksize() - sstrnleft;
8175 sstrnleft = stackblocksize() - len;
8176 } while (sstrnleft < newlen);
8177 return stackblock() + len;
8183 ungrabstackstr(char *s, char *p)
8185 stacknleft += stacknxt - s;
8187 sstrnleft = stacknleft - (p - s);
8190 * Miscelaneous builtins.
8197 static mode_t getmode(const void *, mode_t);
8198 static void *setmode(const char *);
8201 #if !defined(__GLIBC__) || __GLIBC__ == 2 && __GLIBC_MINOR__ < 1
8202 typedef long rlim_t;
8208 * The read builtin. The -e option causes backslashes to escape the
8209 * following character.
8211 * This uses unbuffered input, which may be avoidable in some cases.
8232 while ((i = nextopt("p:r")) != '\0') {
8238 if (prompt && isatty(0)) {
8242 if (*(ap = argptr) == NULL)
8244 if ((ifs = bltinlookup("IFS")) == NULL)
8251 if (read(0, &c, 1) != 1) {
8263 if (!rflag && c == '\\') {
8269 if (startword && *ifs == ' ' && strchr(ifs, c)) {
8273 if (backslash && c == '\\') {
8274 if (read(0, &c, 1) != 1) {
8279 } else if (ap[1] != NULL && strchr(ifs, c) != NULL) {
8281 setvar(*ap, stackblock(), 0);
8290 /* Remove trailing blanks */
8291 while (stackblock() <= --p && strchr(ifs, *p) != NULL)
8293 setvar(*ap, stackblock(), 0);
8294 while (*++ap != NULL)
8295 setvar(*ap, nullstr, 0);
8302 umaskcmd(argc, argv)
8309 int symbolic_mode = 0;
8311 while (nextopt("S") != '\0') {
8320 if ((ap = *argptr) == NULL) {
8321 if (symbolic_mode) {
8322 char u[4], g[4], o[4];
8325 if ((mask & S_IRUSR) == 0)
8327 if ((mask & S_IWUSR) == 0)
8329 if ((mask & S_IXUSR) == 0)
8334 if ((mask & S_IRGRP) == 0)
8336 if ((mask & S_IWGRP) == 0)
8338 if ((mask & S_IXGRP) == 0)
8343 if ((mask & S_IROTH) == 0)
8345 if ((mask & S_IWOTH) == 0)
8347 if ((mask & S_IXOTH) == 0)
8351 printf("u=%s,g=%s,o=%s\n", u, g, o);
8353 printf("%.4o\n", mask);
8356 if (is_digit((unsigned char)*ap)) {
8359 if (*ap >= '8' || *ap < '0')
8360 error("Illegal number: %s", argv[1]);
8361 mask = (mask << 3) + (*ap - '0');
8362 } while (*++ap != '\0');
8368 if ((set = setmode(ap)) != 0) {
8369 mask = getmode(set, ~mask & 0777);
8374 error("Illegal mode: %s", ap);
8376 umask(~mask & 0777);
8385 * This code, originally by Doug Gwyn, Doug Kingston, Eric Gisin, and
8386 * Michael Rendell was ripped from pdksh 5.0.8 and hacked for use with
8387 * ash by J.T. Conklin.
8395 int factor; /* multiply by to get rlim_{cur,max} values */
8399 static const struct limits limits[] = {
8401 { "time(seconds)", RLIMIT_CPU, 1, 't' },
8404 { "file(blocks)", RLIMIT_FSIZE, 512, 'f' },
8407 { "data(kbytes)", RLIMIT_DATA, 1024, 'd' },
8410 { "stack(kbytes)", RLIMIT_STACK, 1024, 's' },
8413 { "coredump(blocks)", RLIMIT_CORE, 512, 'c' },
8416 { "memory(kbytes)", RLIMIT_RSS, 1024, 'm' },
8418 #ifdef RLIMIT_MEMLOCK
8419 { "locked memory(kbytes)", RLIMIT_MEMLOCK, 1024, 'l' },
8422 { "process(processes)", RLIMIT_NPROC, 1, 'p' },
8424 #ifdef RLIMIT_NOFILE
8425 { "nofiles(descriptors)", RLIMIT_NOFILE, 1, 'n' },
8428 { "vmemory(kbytes)", RLIMIT_VMEM, 1024, 'v' },
8431 { "swap(kbytes)", RLIMIT_SWAP, 1024, 'w' },
8433 { (char *) 0, 0, 0, '\0' }
8437 ulimitcmd(argc, argv)
8443 enum { SOFT = 0x1, HARD = 0x2 }
8445 const struct limits *l;
8448 struct rlimit limit;
8451 while ((optc = nextopt("HSatfdsmcnpl")) != '\0')
8466 for (l = limits; l->name && l->option != what; l++)
8469 error("internal error (%c)", what);
8471 set = *argptr ? 1 : 0;
8475 if (all || argptr[1])
8476 error("too many arguments");
8477 if (strcmp(p, "unlimited") == 0)
8478 val = RLIM_INFINITY;
8482 while ((c = *p++) >= '0' && c <= '9')
8484 val = (val * 10) + (long)(c - '0');
8485 if (val < (rlim_t) 0)
8489 error("bad number");
8494 for (l = limits; l->name; l++) {
8495 getrlimit(l->cmd, &limit);
8497 val = limit.rlim_cur;
8498 else if (how & HARD)
8499 val = limit.rlim_max;
8501 printf("%-20s ", l->name);
8502 if (val == RLIM_INFINITY)
8503 printf("unlimited\n");
8507 printf("%lld\n", (long long) val);
8513 getrlimit(l->cmd, &limit);
8516 limit.rlim_max = val;
8518 limit.rlim_cur = val;
8519 if (setrlimit(l->cmd, &limit) < 0)
8520 error("error setting limit (%m)");
8523 val = limit.rlim_cur;
8524 else if (how & HARD)
8525 val = limit.rlim_max;
8527 if (val == RLIM_INFINITY)
8528 printf("unlimited\n");
8532 printf("%lld\n", (long long) val);
8538 * prefix -- see if pfx is a prefix of string.
8542 prefix(char const *pfx, char const *string)
8545 if (*pfx++ != *string++)
8552 * Return true if s is a string of digits, and save munber in intptr
8557 is_number(const char *p, int *intptr)
8565 ret += digit_val(*p);
8567 } while (*p != '\0');
8574 * Convert a string of digits to an integer, printing an error message on
8579 number(const char *s)
8582 if (! is_number(s, &i))
8583 error("Illegal number: %s", s);
8588 * Produce a possibly single quoted string suitable as input to the shell.
8589 * The return string is allocated on the stack.
8593 single_quote(const char *s) {
8600 size_t len1, len1p, len2, len2p;
8602 len1 = strcspn(s, "'");
8603 len2 = strspn(s + len1, "'");
8605 len1p = len1 ? len1 + 2 : len1;
8617 CHECKSTRSPACE(len1p + len2p + 1, p);
8622 memcpy(p + 1, s, len1);
8638 memcpy(q + 1, s, len2);
8643 STADJUST(len1p + len2p, p);
8648 return grabstackstr(p);
8652 * Like strdup but works with the ash stack.
8656 sstrdup(const char *p)
8658 size_t len = strlen(p) + 1;
8659 return memcpy(stalloc(len), p, len);
8664 * Routine for dealing with parsed shell commands.
8668 static void sizenodelist (const struct nodelist *);
8669 static struct nodelist *copynodelist (const struct nodelist *);
8670 static char *nodesavestr (const char *);
8673 calcsize(const union node *n)
8677 funcblocksize += nodesize[n->type];
8684 calcsize(n->nbinary.ch2);
8685 calcsize(n->nbinary.ch1);
8688 calcsize(n->ncmd.redirect);
8689 calcsize(n->ncmd.args);
8690 calcsize(n->ncmd.assign);
8693 sizenodelist(n->npipe.cmdlist);
8698 calcsize(n->nredir.redirect);
8699 calcsize(n->nredir.n);
8702 calcsize(n->nif.elsepart);
8703 calcsize(n->nif.ifpart);
8704 calcsize(n->nif.test);
8707 funcstringsize += strlen(n->nfor.var) + 1;
8708 calcsize(n->nfor.body);
8709 calcsize(n->nfor.args);
8712 calcsize(n->ncase.cases);
8713 calcsize(n->ncase.expr);
8716 calcsize(n->nclist.body);
8717 calcsize(n->nclist.pattern);
8718 calcsize(n->nclist.next);
8722 sizenodelist(n->narg.backquote);
8723 funcstringsize += strlen(n->narg.text) + 1;
8724 calcsize(n->narg.next);
8731 calcsize(n->nfile.fname);
8732 calcsize(n->nfile.next);
8736 calcsize(n->ndup.vname);
8737 calcsize(n->ndup.next);
8741 calcsize(n->nhere.doc);
8742 calcsize(n->nhere.next);
8745 calcsize(n->nnot.com);
8751 sizenodelist(const struct nodelist *lp)
8754 funcblocksize += ALIGN(sizeof(struct nodelist));
8762 copynode(const union node *n)
8769 funcblock = (char *) funcblock + nodesize[n->type];
8776 new->nbinary.ch2 = copynode(n->nbinary.ch2);
8777 new->nbinary.ch1 = copynode(n->nbinary.ch1);
8780 new->ncmd.redirect = copynode(n->ncmd.redirect);
8781 new->ncmd.args = copynode(n->ncmd.args);
8782 new->ncmd.assign = copynode(n->ncmd.assign);
8783 new->ncmd.backgnd = n->ncmd.backgnd;
8786 new->npipe.cmdlist = copynodelist(n->npipe.cmdlist);
8787 new->npipe.backgnd = n->npipe.backgnd;
8792 new->nredir.redirect = copynode(n->nredir.redirect);
8793 new->nredir.n = copynode(n->nredir.n);
8796 new->nif.elsepart = copynode(n->nif.elsepart);
8797 new->nif.ifpart = copynode(n->nif.ifpart);
8798 new->nif.test = copynode(n->nif.test);
8801 new->nfor.var = nodesavestr(n->nfor.var);
8802 new->nfor.body = copynode(n->nfor.body);
8803 new->nfor.args = copynode(n->nfor.args);
8806 new->ncase.cases = copynode(n->ncase.cases);
8807 new->ncase.expr = copynode(n->ncase.expr);
8810 new->nclist.body = copynode(n->nclist.body);
8811 new->nclist.pattern = copynode(n->nclist.pattern);
8812 new->nclist.next = copynode(n->nclist.next);
8816 new->narg.backquote = copynodelist(n->narg.backquote);
8817 new->narg.text = nodesavestr(n->narg.text);
8818 new->narg.next = copynode(n->narg.next);
8825 new->nfile.fname = copynode(n->nfile.fname);
8826 new->nfile.fd = n->nfile.fd;
8827 new->nfile.next = copynode(n->nfile.next);
8831 new->ndup.vname = copynode(n->ndup.vname);
8832 new->ndup.dupfd = n->ndup.dupfd;
8833 new->ndup.fd = n->ndup.fd;
8834 new->ndup.next = copynode(n->ndup.next);
8838 new->nhere.doc = copynode(n->nhere.doc);
8839 new->nhere.fd = n->nhere.fd;
8840 new->nhere.next = copynode(n->nhere.next);
8843 new->nnot.com = copynode(n->nnot.com);
8846 new->type = n->type;
8851 static struct nodelist *
8852 copynodelist(const struct nodelist *lp)
8854 struct nodelist *start;
8855 struct nodelist **lpp;
8860 funcblock = (char *) funcblock + ALIGN(sizeof(struct nodelist));
8861 (*lpp)->n = copynode(lp->n);
8863 lpp = &(*lpp)->next;
8871 nodesavestr(const char *s)
8874 char *rtn = funcstring;
8876 funcstring = stpcpy(funcstring, s) + 1;
8880 char *q = funcstring;
8881 char *rtn = funcstring;
8883 while ((*q++ = *p++) != '\0')
8891 static int getopts (char *, char *, char **, int *, int *);
8896 * Process the shell command line arguments.
8900 procargs(argc, argv)
8909 for (i = 0; i < NOPTS; i++)
8912 if (*argptr == NULL && minusc == NULL)
8914 if (iflag == 2 && sflag == 1 && isatty(0) && isatty(1))
8918 for (i = 0; i < NOPTS; i++)
8919 if (optent_val(i) == 2)
8922 if (sflag == 0 && minusc == NULL) {
8923 commandname = argv[0];
8925 setinputfile(arg0, 0);
8928 /* POSIX 1003.2: first arg after -c cmd is $0, remainder $1... */
8929 if (argptr && minusc && *argptr)
8932 shellparam.p = argptr;
8933 shellparam.optind = 1;
8934 shellparam.optoff = -1;
8935 /* assert(shellparam.malloc == 0 && shellparam.nparam == 0); */
8937 shellparam.nparam++;
8946 * Process shell options. The global variable argptr contains a pointer
8947 * to the argument list; we advance it past the options.
8951 minus_o(const char *name, int val)
8956 out1str("Current option settings\n");
8957 for (i = 0; i < NOPTS; i++)
8958 printf("%-16s%s\n", optent_name(optlist[i]),
8959 optent_val(i) ? "on" : "off");
8961 for (i = 0; i < NOPTS; i++)
8962 if (equal(name, optent_name(optlist[i]))) {
8963 setoption(optent_letter(optlist[i]), val);
8966 error("Illegal option -o %s", name);
8972 options(int cmdline)
8980 while ((p = *argptr) != NULL) {
8982 if ((c = *p++) == '-') {
8984 if (p[0] == '\0' || (p[0] == '-' && p[1] == '\0')) {
8986 /* "-" means turn off -x and -v */
8989 /* "--" means reset params */
8990 else if (*argptr == NULL)
8993 break; /* "-" or "--" terminates options */
8995 } else if (c == '+') {
9001 while ((c = *p++) != '\0') {
9002 if (c == 'c' && cmdline) {
9004 #ifdef NOHACK /* removing this code allows sh -ce 'foo' for compat */
9008 if (q == NULL || minusc != NULL)
9009 error("Bad -c option");
9014 } else if (c == 'o') {
9015 minus_o(*argptr, val);
9027 setoption(int flag, int val)
9031 for (i = 0; i < NOPTS; i++)
9032 if (optent_letter(optlist[i]) == flag) {
9033 optent_val(i) = val;
9035 /* #%$ hack for ksh semantics */
9038 else if (flag == 'E')
9043 error("Illegal option -%c", flag);
9050 * Set the shell parameters.
9054 setparam(char **argv)
9060 for (nparam = 0 ; argv[nparam] ; nparam++);
9061 ap = newparam = ckmalloc((nparam + 1) * sizeof *ap);
9063 *ap++ = savestr(*argv++);
9066 freeparam(&shellparam);
9067 shellparam.malloc = 1;
9068 shellparam.nparam = nparam;
9069 shellparam.p = newparam;
9070 shellparam.optind = 1;
9071 shellparam.optoff = -1;
9076 * Free the list of positional parameters.
9080 freeparam(volatile struct shparam *param)
9084 if (param->malloc) {
9085 for (ap = param->p ; *ap ; ap++)
9094 * The shift builtin command.
9098 shiftcmd(argc, argv)
9107 n = number(argv[1]);
9108 if (n > shellparam.nparam)
9109 error("can't shift that many");
9111 shellparam.nparam -= n;
9112 for (ap1 = shellparam.p ; --n >= 0 ; ap1++) {
9113 if (shellparam.malloc)
9117 while ((*ap2++ = *ap1++) != NULL);
9118 shellparam.optind = 1;
9119 shellparam.optoff = -1;
9127 * The set command builtin.
9136 return showvarscmd(argc, argv);
9140 if (*argptr != NULL) {
9149 getoptsreset(const char *value)
9151 shellparam.optind = number(value);
9152 shellparam.optoff = -1;
9155 #ifdef BB_LOCALE_SUPPORT
9156 static void change_lc_all(const char *value)
9158 if(value != 0 && *value != 0)
9159 setlocale(LC_ALL, value);
9162 static void change_lc_ctype(const char *value)
9164 if(value != 0 && *value != 0)
9165 setlocale(LC_CTYPE, value);
9172 * The getopts builtin. Shellparam.optnext points to the next argument
9173 * to be processed. Shellparam.optptr points to the next character to
9174 * be processed in the current argument. If shellparam.optnext is NULL,
9175 * then it's the first time getopts has been called.
9179 getoptscmd(argc, argv)
9186 error("Usage: getopts optstring var [arg]");
9187 else if (argc == 3) {
9188 optbase = shellparam.p;
9189 if (shellparam.optind > shellparam.nparam + 1) {
9190 shellparam.optind = 1;
9191 shellparam.optoff = -1;
9196 if (shellparam.optind > argc - 2) {
9197 shellparam.optind = 1;
9198 shellparam.optoff = -1;
9202 return getopts(argv[1], argv[2], optbase, &shellparam.optind,
9203 &shellparam.optoff);
9207 * Safe version of setvar, returns 1 on success 0 on failure.
9211 setvarsafe(name, val, flags)
9212 const char *name, *val;
9215 struct jmploc jmploc;
9216 struct jmploc *volatile savehandler = handler;
9222 if (setjmp(jmploc.loc))
9226 setvar(name, val, flags);
9228 handler = savehandler;
9233 getopts(optstr, optvar, optfirst, myoptind, optoff)
9245 char **optnext = optfirst + *myoptind - 1;
9247 if (*myoptind <= 1 || *optoff < 0 || !(*(optnext - 1)) ||
9248 strlen(*(optnext - 1)) < *optoff)
9251 p = *(optnext - 1) + *optoff;
9252 if (p == NULL || *p == '\0') {
9253 /* Current word is done, advance */
9254 if (optnext == NULL)
9257 if (p == NULL || *p != '-' || *++p == '\0') {
9259 *myoptind = optnext - optfirst + 1;
9265 if (p[0] == '-' && p[1] == '\0') /* check for "--" */
9270 for (q = optstr; *q != c; ) {
9272 if (optstr[0] == ':') {
9275 err |= setvarsafe("OPTARG", s, 0);
9278 out2fmt("Illegal option -%c\n", c);
9279 (void) unsetvar("OPTARG");
9289 if (*p == '\0' && (p = *optnext) == NULL) {
9290 if (optstr[0] == ':') {
9293 err |= setvarsafe("OPTARG", s, 0);
9297 out2fmt("No arg for -%c option\n", c);
9298 (void) unsetvar("OPTARG");
9306 setvarsafe("OPTARG", p, 0);
9310 setvarsafe("OPTARG", "", 0);
9311 *myoptind = optnext - optfirst + 1;
9318 *optoff = p ? p - *(optnext - 1) : -1;
9319 snprintf(s, sizeof(s), "%d", *myoptind);
9320 err |= setvarsafe("OPTIND", s, VNOFUNC);
9323 err |= setvarsafe(optvar, s, 0);
9334 * XXX - should get rid of. have all builtins use getopt(3). the
9335 * library getopt must have the BSD extension static variable "optreset"
9336 * otherwise it can't be used within the shell safely.
9338 * Standard option processing (a la getopt) for builtin routines. The
9339 * only argument that is passed to nextopt is the option string; the
9340 * other arguments are unnecessary. It return the character, or '\0' on
9345 nextopt(const char *optstring)
9351 if ((p = optptr) == NULL || *p == '\0') {
9353 if (p == NULL || *p != '-' || *++p == '\0')
9356 if (p[0] == '-' && p[1] == '\0') /* check for "--" */
9360 for (q = optstring ; *q != c ; ) {
9362 error("Illegal option -%c", c);
9367 if (*p == '\0' && (p = *argptr++) == NULL)
9368 error("No arg for -%c option", c);
9385 out2fmt(const char *fmt, ...)
9389 vfprintf(stderr, fmt, ap);
9394 * Version of write which resumes after a signal is caught.
9398 xwrite(int fd, const char *buf, int nbytes)
9407 i = write(fd, buf, n);
9413 } else if (i == 0) {
9416 } else if (errno != EINTR) {
9424 * Shell command parser.
9427 #define EOFMARKLEN 79
9432 struct heredoc *next; /* next here document in list */
9433 union node *here; /* redirection node */
9434 char *eofmark; /* string indicating end of input */
9435 int striptabs; /* if set, strip leading tabs */
9438 static struct heredoc *heredoclist; /* list of here documents to read */
9439 static int parsebackquote; /* nonzero if we are inside backquotes */
9440 static int doprompt; /* if set, prompt the user */
9441 static int needprompt; /* true if interactive and at start of line */
9442 static int lasttoken; /* last token read */
9444 static char *wordtext; /* text of last word returned by readtoken */
9446 static struct nodelist *backquotelist;
9447 static union node *redirnode;
9448 struct heredoc *heredoc;
9449 static int quoteflag; /* set if (part of) last token was quoted */
9450 static int startlinno; /* line # where last token started */
9453 static union node *list (int);
9454 static union node *andor (void);
9455 static union node *pipeline (void);
9456 static union node *command (void);
9457 static union node *simplecmd (void);
9458 static void parsefname (void);
9459 static void parseheredoc (void);
9460 static int peektoken (void);
9461 static int readtoken (void);
9462 static int xxreadtoken (void);
9463 static int readtoken1 (int, char const *, char *, int);
9464 static int noexpand (char *);
9465 static void synexpect (int) __attribute__((noreturn));
9466 static void synerror (const char *) __attribute__((noreturn));
9467 static void setprompt (int);
9471 * Read and parse a command. Returns NEOF on end of file. (NULL is a
9472 * valid parse tree indicating a blank line.)
9476 parsecmd(int interact)
9481 doprompt = interact;
9501 union node *n1, *n2, *n3;
9505 if (nlflag == 0 && tokendlist[peektoken()])
9511 if (tok == TBACKGND) {
9512 if (n2->type == NCMD || n2->type == NPIPE) {
9513 n2->ncmd.backgnd = 1;
9514 } else if (n2->type == NREDIR) {
9515 n2->type = NBACKGND;
9517 n3 = (union node *)stalloc(sizeof (struct nredir));
9518 n3->type = NBACKGND;
9520 n3->nredir.redirect = NULL;
9528 n3 = (union node *)stalloc(sizeof (struct nbinary));
9530 n3->nbinary.ch1 = n1;
9531 n3->nbinary.ch2 = n2;
9548 if (tokendlist[peektoken()])
9555 pungetc(); /* push back EOF on input */
9570 union node *n1, *n2, *n3;
9576 if ((t = readtoken()) == TAND) {
9578 } else if (t == TOR) {
9586 n3 = (union node *)stalloc(sizeof (struct nbinary));
9588 n3->nbinary.ch1 = n1;
9589 n3->nbinary.ch2 = n2;
9598 union node *n1, *n2, *pipenode;
9599 struct nodelist *lp, *prev;
9603 TRACE(("pipeline: entered\n"));
9604 if (readtoken() == TNOT) {
9610 if (readtoken() == TPIPE) {
9611 pipenode = (union node *)stalloc(sizeof (struct npipe));
9612 pipenode->type = NPIPE;
9613 pipenode->npipe.backgnd = 0;
9614 lp = (struct nodelist *)stalloc(sizeof (struct nodelist));
9615 pipenode->npipe.cmdlist = lp;
9619 lp = (struct nodelist *)stalloc(sizeof (struct nodelist));
9623 } while (readtoken() == TPIPE);
9629 n2 = (union node *)stalloc(sizeof (struct nnot));
9641 union node *n1, *n2;
9642 union node *ap, **app;
9643 union node *cp, **cpp;
9644 union node *redir, **rpp;
9651 switch (readtoken()) {
9653 n1 = (union node *)stalloc(sizeof (struct nif));
9655 n1->nif.test = list(0);
9656 if (readtoken() != TTHEN)
9658 n1->nif.ifpart = list(0);
9660 while (readtoken() == TELIF) {
9661 n2->nif.elsepart = (union node *)stalloc(sizeof (struct nif));
9662 n2 = n2->nif.elsepart;
9664 n2->nif.test = list(0);
9665 if (readtoken() != TTHEN)
9667 n2->nif.ifpart = list(0);
9669 if (lasttoken == TELSE)
9670 n2->nif.elsepart = list(0);
9672 n2->nif.elsepart = NULL;
9675 if (readtoken() != TFI)
9682 n1 = (union node *)stalloc(sizeof (struct nbinary));
9683 n1->type = (lasttoken == TWHILE)? NWHILE : NUNTIL;
9684 n1->nbinary.ch1 = list(0);
9685 if ((got=readtoken()) != TDO) {
9686 TRACE(("expecting DO got %s %s\n", tokname[got], got == TWORD ? wordtext : ""));
9689 n1->nbinary.ch2 = list(0);
9690 if (readtoken() != TDONE)
9696 if (readtoken() != TWORD || quoteflag || ! goodname(wordtext))
9697 synerror("Bad for loop variable");
9698 n1 = (union node *)stalloc(sizeof (struct nfor));
9700 n1->nfor.var = wordtext;
9702 if (readtoken() == TIN) {
9704 while (readtoken() == TWORD) {
9705 n2 = (union node *)stalloc(sizeof (struct narg));
9707 n2->narg.text = wordtext;
9708 n2->narg.backquote = backquotelist;
9710 app = &n2->narg.next;
9714 if (lasttoken != TNL && lasttoken != TSEMI)
9717 static char argvars[5] = {CTLVAR, VSNORMAL|VSQUOTE,
9719 n2 = (union node *)stalloc(sizeof (struct narg));
9721 n2->narg.text = argvars;
9722 n2->narg.backquote = NULL;
9723 n2->narg.next = NULL;
9726 * Newline or semicolon here is optional (but note
9727 * that the original Bourne shell only allowed NL).
9729 if (lasttoken != TNL && lasttoken != TSEMI)
9733 if (readtoken() != TDO)
9735 n1->nfor.body = list(0);
9736 if (readtoken() != TDONE)
9741 n1 = (union node *)stalloc(sizeof (struct ncase));
9743 if (readtoken() != TWORD)
9745 n1->ncase.expr = n2 = (union node *)stalloc(sizeof (struct narg));
9747 n2->narg.text = wordtext;
9748 n2->narg.backquote = backquotelist;
9749 n2->narg.next = NULL;
9752 } while (readtoken() == TNL);
9753 if (lasttoken != TIN)
9754 synerror("expecting \"in\"");
9755 cpp = &n1->ncase.cases;
9756 checkkwd = 2, readtoken();
9758 if (lasttoken == TLP)
9760 *cpp = cp = (union node *)stalloc(sizeof (struct nclist));
9762 app = &cp->nclist.pattern;
9764 *app = ap = (union node *)stalloc(sizeof (struct narg));
9766 ap->narg.text = wordtext;
9767 ap->narg.backquote = backquotelist;
9768 if (checkkwd = 2, readtoken() != TPIPE)
9770 app = &ap->narg.next;
9773 ap->narg.next = NULL;
9774 if (lasttoken != TRP)
9776 cp->nclist.body = list(0);
9779 if ((t = readtoken()) != TESAC) {
9781 synexpect(TENDCASE);
9783 checkkwd = 2, readtoken();
9785 cpp = &cp->nclist.next;
9786 } while(lasttoken != TESAC);
9791 n1 = (union node *)stalloc(sizeof (struct nredir));
9792 n1->type = NSUBSHELL;
9793 n1->nredir.n = list(0);
9794 n1->nredir.redirect = NULL;
9795 if (readtoken() != TRP)
9801 if (readtoken() != TEND)
9805 /* Handle an empty command like other simple commands. */
9814 * An empty command before a ; doesn't make much sense, and
9815 * should certainly be disallowed in the case of `if ;'.
9829 /* Now check for redirection which may follow command */
9830 while (readtoken() == TREDIR) {
9831 *rpp = n2 = redirnode;
9832 rpp = &n2->nfile.next;
9838 if (n1->type != NSUBSHELL) {
9839 n2 = (union node *)stalloc(sizeof (struct nredir));
9844 n1->nredir.redirect = redir;
9853 union node *args, **app;
9854 union node *n = NULL;
9855 union node *vars, **vpp;
9856 union node **rpp, *redir;
9867 switch (readtoken()) {
9870 n = (union node *)stalloc(sizeof (struct narg));
9872 n->narg.text = wordtext;
9873 n->narg.backquote = backquotelist;
9874 if (lasttoken == TWORD) {
9876 app = &n->narg.next;
9879 vpp = &n->narg.next;
9883 *rpp = n = redirnode;
9884 rpp = &n->nfile.next;
9885 parsefname(); /* read name of redirection file */
9889 args && app == &args->narg.next &&
9892 /* We have a function */
9893 if (readtoken() != TRP)
9897 n->narg.next = command();
9910 n = (union node *)stalloc(sizeof (struct ncmd));
9912 n->ncmd.backgnd = 0;
9913 n->ncmd.args = args;
9914 n->ncmd.assign = vars;
9915 n->ncmd.redirect = redir;
9923 n = (union node *)stalloc(sizeof (struct narg));
9925 n->narg.next = NULL;
9926 n->narg.text = wordtext;
9927 n->narg.backquote = backquotelist;
9931 static void fixredir(union node *n, const char *text, int err)
9933 TRACE(("Fix redir %s %d\n", text, err));
9935 n->ndup.vname = NULL;
9937 if (is_digit(text[0]) && text[1] == '\0')
9938 n->ndup.dupfd = digit_val(text[0]);
9939 else if (text[0] == '-' && text[1] == '\0')
9944 synerror("Bad fd number");
9946 n->ndup.vname = makename();
9953 union node *n = redirnode;
9955 if (readtoken() != TWORD)
9957 if (n->type == NHERE) {
9958 struct heredoc *here = heredoc;
9964 TRACE(("Here document %d\n", n->type));
9965 if (here->striptabs) {
9966 while (*wordtext == '\t')
9969 if (! noexpand(wordtext) || (i = strlen(wordtext)) == 0 || i > EOFMARKLEN)
9970 synerror("Illegal eof marker for << redirection");
9971 rmescapes(wordtext);
9972 here->eofmark = wordtext;
9974 if (heredoclist == NULL)
9977 for (p = heredoclist ; p->next ; p = p->next);
9980 } else if (n->type == NTOFD || n->type == NFROMFD) {
9981 fixredir(n, wordtext, 0);
9983 n->nfile.fname = makename();
9989 * Input any here documents.
9994 struct heredoc *here;
9997 while (heredoclist) {
9999 heredoclist = here->next;
10004 readtoken1(pgetc(), here->here->type == NHERE? SQSYNTAX : DQSYNTAX,
10005 here->eofmark, here->striptabs);
10006 n = (union node *)stalloc(sizeof (struct narg));
10007 n->narg.type = NARG;
10008 n->narg.next = NULL;
10009 n->narg.text = wordtext;
10010 n->narg.backquote = backquotelist;
10011 here->here->nhere.doc = n;
10029 int savecheckalias = checkalias;
10030 int savecheckkwd = checkkwd;
10035 int alreadyseen = tokpushback;
10045 checkalias = savecheckalias;
10052 if (checkkwd == 2) {
10061 * check for keywords
10063 if (t == TWORD && !quoteflag)
10065 const char *const *pp;
10067 if ((pp = findkwd(wordtext))) {
10068 lasttoken = t = pp - parsekwd + KWDOFFSET;
10069 TRACE(("keyword %s recognized\n", tokname[t]));
10080 } else if (checkalias == 2 && isassignment(wordtext)) {
10081 lasttoken = t = TASSIGN;
10083 } else if (checkalias) {
10084 if (!quoteflag && (ap = lookupalias(wordtext, 1)) != NULL) {
10086 pushstring(ap->val, strlen(ap->val), ap);
10088 checkkwd = savecheckkwd;
10097 TRACE(("token %s %s\n", tokname[t], t == TWORD || t == TASSIGN ? wordtext : ""));
10099 TRACE(("reread token %s %s\n", tokname[t], t == TWORD || t == TASSIGN ? wordtext : ""));
10106 * Read the next input token.
10107 * If the token is a word, we set backquotelist to the list of cmds in
10108 * backquotes. We set quoteflag to true if any part of the word was
10110 * If the token is TREDIR, then we set redirnode to a structure containing
10112 * In all cases, the variable startlinno is set to the number of the line
10113 * on which the token starts.
10115 * [Change comment: here documents and internal procedures]
10116 * [Readtoken shouldn't have any arguments. Perhaps we should make the
10117 * word parsing code into a separate routine. In this case, readtoken
10118 * doesn't need to have any internal procedures, but parseword does.
10119 * We could also make parseoperator in essence the main routine, and
10120 * have parseword (readtoken1?) handle both words and redirection.]
10123 #define RETURN(token) return lasttoken = token
10137 startlinno = plinno;
10138 for (;;) { /* until token or start of word found */
10141 case ' ': case '\t':
10147 while ((c = pgetc()) != '\n' && c != PEOF);
10151 if (pgetc() == '\n') {
10152 startlinno = ++plinno;
10163 needprompt = doprompt;
10168 if (pgetc() == '&')
10173 if (pgetc() == '|')
10178 if (pgetc() == ';')
10191 return readtoken1(c, BASESYNTAX, (char *)NULL, 0);
10198 * If eofmark is NULL, read a word or a redirection symbol. If eofmark
10199 * is not NULL, read a here document. In the latter case, eofmark is the
10200 * word which marks the end of the document and striptabs is true if
10201 * leading tabs should be stripped from the document. The argument firstc
10202 * is the first character of the input token or document.
10204 * Because C does not have internal subroutines, I have simulated them
10205 * using goto's to implement the subroutine linkage. The following macros
10206 * will run code that appears at the end of readtoken1.
10209 #define CHECKEND() {goto checkend; checkend_return:;}
10210 #define PARSEREDIR() {goto parseredir; parseredir_return:;}
10211 #define PARSESUB() {goto parsesub; parsesub_return:;}
10212 #define PARSEBACKQOLD() {oldstyle = 1; goto parsebackq; parsebackq_oldreturn:;}
10213 #define PARSEBACKQNEW() {oldstyle = 0; goto parsebackq; parsebackq_newreturn:;}
10214 #define PARSEARITH() {goto parsearith; parsearith_return:;}
10217 readtoken1(firstc, syntax, eofmark, striptabs)
10219 char const *syntax;
10226 char line[EOFMARKLEN + 1];
10227 struct nodelist *bqlist;
10230 int varnest; /* levels of variables expansion */
10231 int arinest; /* levels of arithmetic expansion */
10232 int parenlevel; /* levels of parens in arithmetic */
10233 int dqvarnest; /* levels of variables expansion within double quotes */
10235 char const *prevsyntax; /* syntax before arithmetic */
10237 /* Avoid longjmp clobbering */
10243 (void) &parenlevel;
10246 (void) &prevsyntax;
10250 startlinno = plinno;
10252 if (syntax == DQSYNTAX)
10261 STARTSTACKSTR(out);
10262 loop: { /* for each line, until end of word */
10263 CHECKEND(); /* set c to PEOF if at end of here document */
10264 for (;;) { /* until end of line or end of word */
10265 CHECKSTRSPACE(3, out); /* permit 3 calls to USTPUTC */
10266 switch(syntax[c]) {
10267 case CNL: /* '\n' */
10268 if (syntax == BASESYNTAX)
10269 goto endword; /* exit outer loop */
10277 goto loop; /* continue outer loop */
10282 if ((eofmark == NULL || dblquote) &&
10284 USTPUTC(CTLESC, out);
10287 case CBACK: /* backslash */
10290 USTPUTC('\\', out);
10292 } else if (c == '\n') {
10298 if (dblquote && c != '\\' && c != '`' && c != '$'
10299 && (c != '"' || eofmark != NULL))
10300 USTPUTC('\\', out);
10301 if (SQSYNTAX[c] == CCTL)
10302 USTPUTC(CTLESC, out);
10303 else if (eofmark == NULL)
10304 USTPUTC(CTLQUOTEMARK, out);
10310 if (eofmark == NULL)
10311 USTPUTC(CTLQUOTEMARK, out);
10315 if (eofmark == NULL)
10316 USTPUTC(CTLQUOTEMARK, out);
10321 if (eofmark != NULL && arinest == 0 &&
10326 syntax = ARISYNTAX;
10328 } else if (eofmark == NULL &&
10330 syntax = BASESYNTAX;
10336 case CVAR: /* '$' */
10337 PARSESUB(); /* parse substitution */
10339 case CENDVAR: /* '}' */
10342 if (dqvarnest > 0) {
10345 USTPUTC(CTLENDVAR, out);
10350 #ifdef ASH_MATH_SUPPORT
10351 case CLP: /* '(' in arithmetic */
10355 case CRP: /* ')' in arithmetic */
10356 if (parenlevel > 0) {
10360 if (pgetc() == ')') {
10361 if (--arinest == 0) {
10362 USTPUTC(CTLENDARI, out);
10363 syntax = prevsyntax;
10364 if (syntax == DQSYNTAX)
10372 * unbalanced parens
10373 * (don't 2nd guess - no error)
10381 case CBQUOTE: /* '`' */
10385 goto endword; /* exit outer loop */
10390 goto endword; /* exit outer loop */
10401 if (syntax == ARISYNTAX)
10402 synerror("Missing '))'");
10403 if (syntax != BASESYNTAX && ! parsebackquote && eofmark == NULL)
10404 synerror("Unterminated quoted string");
10405 if (varnest != 0) {
10406 startlinno = plinno;
10407 synerror("Missing '}'");
10409 USTPUTC('\0', out);
10410 len = out - stackblock();
10411 out = stackblock();
10412 if (eofmark == NULL) {
10413 if ((c == '>' || c == '<')
10416 && (*out == '\0' || is_digit(*out))) {
10418 return lasttoken = TREDIR;
10423 quoteflag = quotef;
10424 backquotelist = bqlist;
10425 grabstackblock(len);
10427 return lasttoken = TWORD;
10428 /* end of readtoken routine */
10433 * Check to see whether we are at the end of the here document. When this
10434 * is called, c is set to the first character of the next input line. If
10435 * we are at the end of the here document, this routine sets the c to PEOF.
10446 while (c == '\t') {
10450 if (c == *eofmark) {
10451 if (pfgets(line, sizeof line) != NULL) {
10455 for (q = eofmark + 1 ; *q && *p == *q ; p++, q++);
10456 if (*p == '\n' && *q == '\0') {
10459 needprompt = doprompt;
10461 pushstring(line, strlen(line), NULL);
10466 goto checkend_return;
10471 * Parse a redirection operator. The variable "out" points to a string
10472 * specifying the fd to be redirected. The variable "c" contains the
10473 * first character of the redirection operator.
10480 np = (union node *)stalloc(sizeof (struct nfile));
10485 np->type = NAPPEND;
10494 } else { /* c == '<' */
10496 switch (c = pgetc()) {
10498 if (sizeof (struct nfile) != sizeof (struct nhere)) {
10499 np = (union node *)stalloc(sizeof (struct nhere));
10503 heredoc = (struct heredoc *)stalloc(sizeof (struct heredoc));
10504 heredoc->here = np;
10505 if ((c = pgetc()) == '-') {
10506 heredoc->striptabs = 1;
10508 heredoc->striptabs = 0;
10514 np->type = NFROMFD;
10518 np->type = NFROMTO;
10528 np->nfile.fd = digit_val(fd);
10530 goto parseredir_return;
10535 * Parse a substitution. At this point, we have read the dollar sign
10536 * and nothing else.
10544 static const char types[] = "}-+?=";
10549 (c != '(' && c != '{' && !is_name(c) && !is_special(c))
10553 } else if (c == '(') { /* $(command) or $((arith)) */
10554 if (pgetc() == '(') {
10561 USTPUTC(CTLVAR, out);
10562 typeloc = out - stackblock();
10563 USTPUTC(VSNORMAL, out);
10564 subtype = VSNORMAL;
10568 if ((c = pgetc()) == '}')
10571 subtype = VSLENGTH;
10576 if (c > PEOA && is_name(c)) {
10580 } while (c > PEOA && is_in_name(c));
10581 } else if (is_digit(c)) {
10585 } while (is_digit(c));
10587 else if (is_special(c)) {
10592 badsub: synerror("Bad substitution");
10596 if (subtype == 0) {
10603 p = strchr(types, c);
10606 subtype = p - types + VSNORMAL;
10612 subtype = c == '#' ? VSTRIMLEFT :
10625 if (dblquote || arinest)
10627 *(stackblock() + typeloc) = subtype | flags;
10628 if (subtype != VSNORMAL) {
10635 goto parsesub_return;
10640 * Called to parse command substitutions. Newstyle is set if the command
10641 * is enclosed inside $(...); nlpp is a pointer to the head of the linked
10642 * list of commands (passed by reference), and savelen is the number of
10643 * characters on the top of the stack which must be preserved.
10647 struct nodelist **nlpp;
10650 char *volatile str;
10651 struct jmploc jmploc;
10652 struct jmploc *volatile savehandler;
10656 (void) &saveprompt;
10659 savepbq = parsebackquote;
10660 if (setjmp(jmploc.loc)) {
10663 parsebackquote = 0;
10664 handler = savehandler;
10665 longjmp(handler->loc, 1);
10669 savelen = out - stackblock();
10671 str = ckmalloc(savelen);
10672 memcpy(str, stackblock(), savelen);
10674 savehandler = handler;
10678 /* We must read until the closing backquote, giving special
10679 treatment to some slashes, and then push the string and
10680 reread it as input, interpreting it normally. */
10687 STARTSTACKSTR(pout);
10693 switch (pc = pgetc()) {
10698 if ((pc = pgetc()) == '\n') {
10705 * If eating a newline, avoid putting
10706 * the newline into the new character
10707 * stream (via the STPUTC after the
10712 if (pc != '\\' && pc != '`' && pc != '$'
10713 && (!dblquote || pc != '"'))
10714 STPUTC('\\', pout);
10724 startlinno = plinno;
10725 synerror("EOF in backquote substitution");
10729 needprompt = doprompt;
10738 STPUTC('\0', pout);
10739 psavelen = pout - stackblock();
10740 if (psavelen > 0) {
10741 pstr = grabstackstr(pout);
10742 setinputstring(pstr);
10747 nlpp = &(*nlpp)->next;
10748 *nlpp = (struct nodelist *)stalloc(sizeof (struct nodelist));
10749 (*nlpp)->next = NULL;
10750 parsebackquote = oldstyle;
10753 saveprompt = doprompt;
10760 doprompt = saveprompt;
10762 if (readtoken() != TRP)
10769 * Start reading from old file again, ignoring any pushed back
10770 * tokens left from the backquote parsing
10775 while (stackblocksize() <= savelen)
10777 STARTSTACKSTR(out);
10779 memcpy(out, str, savelen);
10780 STADJUST(savelen, out);
10786 parsebackquote = savepbq;
10787 handler = savehandler;
10788 if (arinest || dblquote)
10789 USTPUTC(CTLBACKQ | CTLQUOTE, out);
10791 USTPUTC(CTLBACKQ, out);
10793 goto parsebackq_oldreturn;
10795 goto parsebackq_newreturn;
10799 * Parse an arithmetic expansion (indicate start of one and set state)
10803 if (++arinest == 1) {
10804 prevsyntax = syntax;
10805 syntax = ARISYNTAX;
10806 USTPUTC(CTLARI, out);
10813 * we collapse embedded arithmetic expansion to
10814 * parenthesis, which should be equivalent
10818 goto parsearith_return;
10821 } /* end of readtoken */
10825 * Returns true if the text contains nothing to expand (no dollar signs
10837 while ((c = *p++) != '\0') {
10838 if (c == CTLQUOTEMARK)
10842 else if (BASESYNTAX[(int)c] == CCTL)
10850 * Return true if the argument is a legal variable name (a letter or
10851 * underscore followed by zero or more letters, underscores, and digits).
10855 goodname(const char *name)
10863 if (! is_in_name(*p))
10871 * Called when an unexpected token is read during the parse. The argument
10872 * is the token that is expected, or -1 if more than one type of token can
10873 * occur at this point.
10883 snprintf(msg, 64, "%s unexpected (expecting %s)",
10884 tokname[lasttoken], tokname[token]);
10886 snprintf(msg, 64, "%s unexpected", tokname[lasttoken]);
10894 synerror(const char *msg)
10897 out2fmt("%s: %d: ", commandname, startlinno);
10898 out2fmt("Syntax error: %s\n", msg);
10899 error((char *)NULL);
10905 * called by editline -- any expansions to the prompt
10906 * should be added here.
10909 setprompt(int whichprompt)
10912 switch (whichprompt) {
10927 * Code for dealing with input/output redirection.
10930 #define EMPTY -2 /* marks an unused slot in redirtab */
10932 # define PIPESIZE 4096 /* amount of buffering in a pipe */
10934 # define PIPESIZE PIPE_BUF
10939 * Open a file in noclobber mode.
10940 * The code was copied from bash.
10943 noclobberopen(const char *fname)
10946 struct stat finfo, finfo2;
10949 * If the file exists and is a regular file, return an error
10952 r = stat(fname, &finfo);
10953 if (r == 0 && S_ISREG(finfo.st_mode)) {
10959 * If the file was not present (r != 0), make sure we open it
10960 * exclusively so that if it is created before we open it, our open
10961 * will fail. Make sure that we do not truncate an existing file.
10962 * Note that we don't turn on O_EXCL unless the stat failed -- if the
10963 * file was not a regular file, we leave O_EXCL off.
10966 return open(fname, O_WRONLY|O_CREAT|O_EXCL, 0666);
10967 fd = open(fname, O_WRONLY|O_CREAT, 0666);
10969 /* If the open failed, return the file descriptor right away. */
10974 * OK, the open succeeded, but the file may have been changed from a
10975 * non-regular file to a regular file between the stat and the open.
10976 * We are assuming that the O_EXCL open handles the case where FILENAME
10977 * did not exist and is symlinked to an existing file between the stat
10982 * If we can open it and fstat the file descriptor, and neither check
10983 * revealed that it was a regular file, and the file has not been
10984 * replaced, return the file descriptor.
10986 if (fstat(fd, &finfo2) == 0 && !S_ISREG(finfo2.st_mode) &&
10987 finfo.st_dev == finfo2.st_dev && finfo.st_ino == finfo2.st_ino)
10990 /* The file has been replaced. badness. */
10997 * Handle here documents. Normally we fork off a process to write the
10998 * data to a pipe. If the document is short, we can stuff the data in
10999 * the pipe without forking.
11003 openhere(const union node *redir)
11009 error("Pipe call failed");
11010 if (redir->type == NHERE) {
11011 len = strlen(redir->nhere.doc->narg.text);
11012 if (len <= PIPESIZE) {
11013 xwrite(pip[1], redir->nhere.doc->narg.text, len);
11017 if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) {
11019 signal(SIGINT, SIG_IGN);
11020 signal(SIGQUIT, SIG_IGN);
11021 signal(SIGHUP, SIG_IGN);
11023 signal(SIGTSTP, SIG_IGN);
11025 signal(SIGPIPE, SIG_DFL);
11026 if (redir->type == NHERE)
11027 xwrite(pip[1], redir->nhere.doc->narg.text, len);
11029 expandhere(redir->nhere.doc, pip[1]);
11039 openredirect(const union node *redir)
11044 switch (redir->nfile.type) {
11046 fname = redir->nfile.expfname;
11047 if ((f = open(fname, O_RDONLY)) < 0)
11051 fname = redir->nfile.expfname;
11052 if ((f = open(fname, O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0)
11056 /* Take care of noclobber mode. */
11058 fname = redir->nfile.expfname;
11059 if ((f = noclobberopen(fname)) < 0)
11064 fname = redir->nfile.expfname;
11066 if ((f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
11069 if ((f = creat(fname, 0666)) < 0)
11074 fname = redir->nfile.expfname;
11076 if ((f = open(fname, O_WRONLY|O_CREAT|O_APPEND, 0666)) < 0)
11079 if ((f = open(fname, O_WRONLY)) < 0
11080 && (f = creat(fname, 0666)) < 0)
11082 lseek(f, (off_t)0, 2);
11089 /* Fall through to eliminate warning. */
11096 f = openhere(redir);
11102 error("cannot create %s: %s", fname, errmsg(errno, E_CREAT));
11104 error("cannot open %s: %s", fname, errmsg(errno, E_OPEN));
11109 * Process a list of redirection commands. If the REDIR_PUSH flag is set,
11110 * old file descriptors are stashed away so that the redirection can be
11111 * undone by calling popredir. If the REDIR_BACKQ flag is set, then the
11112 * standard output, and the standard error if it becomes a duplicate of
11117 redirect(union node *redir, int flags)
11120 struct redirtab *sv = NULL;
11125 int fd1dup = flags & REDIR_BACKQ;; /* stdout `cmd` redir to pipe */
11127 if (flags & REDIR_PUSH) {
11128 sv = ckmalloc(sizeof (struct redirtab));
11129 for (i = 0 ; i < 10 ; i++)
11130 sv->renamed[i] = EMPTY;
11131 sv->next = redirlist;
11134 for (n = redir ; n ; n = n->nfile.next) {
11137 if ((n->nfile.type == NTOFD || n->nfile.type == NFROMFD) &&
11138 n->ndup.dupfd == fd)
11139 continue; /* redirect from/to same file descriptor */
11142 newfd = openredirect(n);
11143 if ((flags & REDIR_PUSH) && sv->renamed[fd] == EMPTY) {
11146 } else if ((i = fcntl(fd, F_DUPFD, 10)) == -1) {
11150 dupredirect(n, newfd, fd1dup);
11160 error("%d: %m", fd);
11166 if (flags & REDIR_PUSH) {
11167 sv->renamed[fd] = i;
11170 } else if (fd != newfd) {
11176 dupredirect(n, newfd, fd1dup);
11183 dupredirect(const union node *redir, int f, int fd1dup)
11185 int fd = redir->nfile.fd;
11189 if (redir->nfile.type == NTOFD || redir->nfile.type == NFROMFD) {
11190 if (redir->ndup.dupfd >= 0) { /* if not ">&-" */
11191 if (redir->ndup.dupfd!=1 || fd1dup!=1)
11192 dup_as_newfd(redir->ndup.dupfd, fd);
11198 dup_as_newfd(f, fd);
11207 * Undo the effects of the last redirection.
11213 struct redirtab *rp = redirlist;
11217 for (i = 0 ; i < 10 ; i++) {
11218 if (rp->renamed[i] != EMPTY) {
11222 if (rp->renamed[i] >= 0) {
11223 dup_as_newfd(rp->renamed[i], i);
11224 close(rp->renamed[i]);
11228 redirlist = rp->next;
11234 * Discard all saved file descriptors.
11239 struct redirtab *rp;
11242 for (rp = redirlist ; rp ; rp = rp->next) {
11243 for (i = 0 ; i < 10 ; i++) {
11244 if (rp->renamed[i] >= 0) {
11245 close(rp->renamed[i]);
11247 rp->renamed[i] = EMPTY;
11254 * Copy a file descriptor to be >= to. Returns -1
11255 * if the source file descriptor is closed, EMPTY if there are no unused
11256 * file descriptors left.
11260 dup_as_newfd(from, to)
11266 newfd = fcntl(from, F_DUPFD, to);
11268 if (errno == EMFILE)
11271 error("%d: %m", from);
11276 /*#ifdef __weak_alias
11277 __weak_alias(getmode,_getmode)
11278 __weak_alias(setmode,_setmode)
11282 #if defined(__GLIBC__) && __GLIBC__ >= 2
11283 #define S_ISTXT __S_ISVTX
11285 #define S_ISTXT S_ISVTX
11289 #define SET_LEN 6 /* initial # of bitcmd struct to malloc */
11290 #define SET_LEN_INCR 4 /* # of bitcmd structs to add as needed */
11292 typedef struct bitcmd {
11298 #define CMD2_CLR 0x01
11299 #define CMD2_SET 0x02
11300 #define CMD2_GBITS 0x04
11301 #define CMD2_OBITS 0x08
11302 #define CMD2_UBITS 0x10
11304 static BITCMD *addcmd (BITCMD *, int, int, int, u_int);
11305 static void compress_mode (BITCMD *);
11306 #ifdef SETMODE_DEBUG
11307 static void dumpmode (BITCMD *);
11311 * Given the old mode and an array of bitcmd structures, apply the operations
11312 * described in the bitcmd structures to the old mode, and return the new mode.
11313 * Note that there is no '=' command; a strict assignment is just a '-' (clear
11314 * bits) followed by a '+' (set bits).
11317 getmode(bbox, omode)
11322 mode_t clrval, newmode, value;
11324 _DIAGASSERT(bbox != NULL);
11326 set = (const BITCMD *)bbox;
11328 for (value = 0;; set++)
11331 * When copying the user, group or other bits around, we "know"
11332 * where the bits are in the mode so that we can do shifts to
11333 * copy them around. If we don't use shifts, it gets real
11334 * grundgy with lots of single bit checks and bit sets.
11337 value = (newmode & S_IRWXU) >> 6;
11341 value = (newmode & S_IRWXG) >> 3;
11345 value = newmode & S_IRWXO;
11346 common: if (set->cmd2 & CMD2_CLR) {
11348 (set->cmd2 & CMD2_SET) ? S_IRWXO : value;
11349 if (set->cmd2 & CMD2_UBITS)
11350 newmode &= ~((clrval<<6) & set->bits);
11351 if (set->cmd2 & CMD2_GBITS)
11352 newmode &= ~((clrval<<3) & set->bits);
11353 if (set->cmd2 & CMD2_OBITS)
11354 newmode &= ~(clrval & set->bits);
11356 if (set->cmd2 & CMD2_SET) {
11357 if (set->cmd2 & CMD2_UBITS)
11358 newmode |= (value<<6) & set->bits;
11359 if (set->cmd2 & CMD2_GBITS)
11360 newmode |= (value<<3) & set->bits;
11361 if (set->cmd2 & CMD2_OBITS)
11362 newmode |= value & set->bits;
11367 newmode |= set->bits;
11371 newmode &= ~set->bits;
11375 if (omode & (S_IFDIR|S_IXUSR|S_IXGRP|S_IXOTH))
11376 newmode |= set->bits;
11381 #ifdef SETMODE_DEBUG
11382 (void)printf("getmode:%04o -> %04o\n", omode, newmode);
11388 #define ADDCMD(a, b, c, d) do { \
11389 if (set >= endset) { \
11391 setlen += SET_LEN_INCR; \
11392 newset = realloc(saveset, sizeof(BITCMD) * setlen); \
11393 if (newset == NULL) { \
11397 set = newset + (set - saveset); \
11398 saveset = newset; \
11399 endset = newset + (setlen - 2); \
11401 set = addcmd(set, (a), (b), (c), (d)); \
11402 } while (/*CONSTCOND*/0)
11404 #define STANDARD_BITS (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO)
11412 BITCMD *set, *saveset, *endset;
11413 sigset_t mysigset, sigoset;
11415 int equalopdone = 0; /* pacify gcc */
11416 int permXbits, setlen;
11422 * Get a copy of the mask for the permissions that are mask relative.
11423 * Flip the bits, we want what's not set. Since it's possible that
11424 * the caller is opening files inside a signal handler, protect them
11427 sigfillset(&mysigset);
11428 (void)sigprocmask(SIG_BLOCK, &mysigset, &sigoset);
11429 (void)umask(mask = umask(0));
11431 (void)sigprocmask(SIG_SETMASK, &sigoset, NULL);
11433 setlen = SET_LEN + 2;
11435 if ((set = malloc((u_int)(sizeof(BITCMD) * setlen))) == NULL)
11438 endset = set + (setlen - 2);
11441 * If an absolute number, get it and return; disallow non-octal digits
11444 if (is_digit((unsigned char)*p)) {
11445 perm = (mode_t)strtol(p, &ep, 8);
11446 if (*ep || perm & ~(STANDARD_BITS|S_ISTXT)) {
11450 ADDCMD('=', (STANDARD_BITS|S_ISTXT), perm, mask);
11456 * Build list of structures to set/clear/copy bits as described by
11457 * each clause of the symbolic mode.
11460 /* First, find out which bits might be modified. */
11461 for (who = 0;; ++p) {
11464 who |= STANDARD_BITS;
11467 who |= S_ISUID|S_IRWXU;
11470 who |= S_ISGID|S_IRWXG;
11480 getop: if ((op = *p++) != '+' && op != '-' && op != '=') {
11488 for (perm = 0, permXbits = 0;; ++p) {
11491 perm |= S_IRUSR|S_IRGRP|S_IROTH;
11495 * If specific bits where requested and
11496 * only "other" bits ignore set-id.
11498 if (who == 0 || (who & ~S_IRWXO))
11499 perm |= S_ISUID|S_ISGID;
11503 * If specific bits where requested and
11504 * only "other" bits ignore set-id.
11506 if (who == 0 || (who & ~S_IRWXO)) {
11512 perm |= S_IWUSR|S_IWGRP|S_IWOTH;
11515 permXbits = S_IXUSR|S_IXGRP|S_IXOTH;
11518 perm |= S_IXUSR|S_IXGRP|S_IXOTH;
11524 * When ever we hit 'u', 'g', or 'o', we have
11525 * to flush out any partial mode that we have,
11526 * and then do the copying of the mode bits.
11529 ADDCMD(op, who, perm, mask);
11534 if (op == '+' && permXbits) {
11535 ADDCMD('X', who, permXbits, mask);
11538 ADDCMD(*p, who, op, mask);
11543 * Add any permissions that we haven't already
11546 if (perm || (op == '=' && !equalopdone)) {
11549 ADDCMD(op, who, perm, mask);
11553 ADDCMD('X', who, permXbits, mask);
11567 #ifdef SETMODE_DEBUG
11568 (void)printf("Before compress_mode()\n");
11571 compress_mode(saveset);
11572 #ifdef SETMODE_DEBUG
11573 (void)printf("After compress_mode()\n");
11580 addcmd(set, op, who, oparg, mask)
11587 _DIAGASSERT(set != NULL);
11592 set->bits = who ? who : STANDARD_BITS;
11601 set->bits = (who ? who : mask) & oparg;
11609 set->cmd2 = ((who & S_IRUSR) ? CMD2_UBITS : 0) |
11610 ((who & S_IRGRP) ? CMD2_GBITS : 0) |
11611 ((who & S_IROTH) ? CMD2_OBITS : 0);
11612 set->bits = (mode_t)~0;
11614 set->cmd2 = CMD2_UBITS | CMD2_GBITS | CMD2_OBITS;
11619 set->cmd2 |= CMD2_SET;
11620 else if (oparg == '-')
11621 set->cmd2 |= CMD2_CLR;
11622 else if (oparg == '=')
11623 set->cmd2 |= CMD2_SET|CMD2_CLR;
11629 #ifdef SETMODE_DEBUG
11635 _DIAGASSERT(set != NULL);
11637 for (; set->cmd; ++set)
11638 (void)printf("cmd: '%c' bits %04o%s%s%s%s%s%s\n",
11639 set->cmd, set->bits, set->cmd2 ? " cmd2:" : "",
11640 set->cmd2 & CMD2_CLR ? " CLR" : "",
11641 set->cmd2 & CMD2_SET ? " SET" : "",
11642 set->cmd2 & CMD2_UBITS ? " UBITS" : "",
11643 set->cmd2 & CMD2_GBITS ? " GBITS" : "",
11644 set->cmd2 & CMD2_OBITS ? " OBITS" : "");
11649 * Given an array of bitcmd structures, compress by compacting consecutive
11650 * '+', '-' and 'X' commands into at most 3 commands, one of each. The 'u',
11651 * 'g' and 'o' commands continue to be separate. They could probably be
11652 * compacted, but it's not worth the effort.
11659 int setbits, clrbits, Xbits, op;
11661 _DIAGASSERT(set != NULL);
11663 for (nset = set;;) {
11664 /* Copy over any 'u', 'g' and 'o' commands. */
11665 while ((op = nset->cmd) != '+' && op != '-' && op != 'X') {
11671 for (setbits = clrbits = Xbits = 0;; nset++) {
11672 if ((op = nset->cmd) == '-') {
11673 clrbits |= nset->bits;
11674 setbits &= ~nset->bits;
11675 Xbits &= ~nset->bits;
11676 } else if (op == '+') {
11677 setbits |= nset->bits;
11678 clrbits &= ~nset->bits;
11679 Xbits &= ~nset->bits;
11680 } else if (op == 'X')
11681 Xbits |= nset->bits & ~setbits;
11688 set->bits = clrbits;
11694 set->bits = setbits;
11706 static void shtree (union node *, int, char *, FILE*);
11707 static void shcmd (union node *, FILE *);
11708 static void sharg (union node *, FILE *);
11709 static void indent (int, char *, FILE *);
11710 static void trstring (char *);
11717 trputs("showtree called\n");
11718 shtree(n, 1, NULL, stdout);
11723 shtree(n, ind, pfx, fp)
11729 struct nodelist *lp;
11735 indent(ind, pfx, fp);
11746 shtree(n->nbinary.ch1, ind, NULL, fp);
11749 shtree(n->nbinary.ch2, ind, NULL, fp);
11757 for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
11762 if (n->npipe.backgnd)
11768 fprintf(fp, "<node type %d>", n->type);
11788 for (np = cmd->ncmd.args ; np ; np = np->narg.next) {
11794 for (np = cmd->ncmd.redirect ; np ; np = np->nfile.next) {
11797 switch (np->nfile.type) {
11798 case NTO: s = ">"; dftfd = 1; break;
11799 case NAPPEND: s = ">>"; dftfd = 1; break;
11800 case NTOFD: s = ">&"; dftfd = 1; break;
11801 case NTOOV: s = ">|"; dftfd = 1; break;
11802 case NFROM: s = "<"; dftfd = 0; break;
11803 case NFROMFD: s = "<&"; dftfd = 0; break;
11804 case NFROMTO: s = "<>"; dftfd = 0; break;
11805 default: s = "*error*"; dftfd = 0; break;
11807 if (np->nfile.fd != dftfd)
11808 fprintf(fp, "%d", np->nfile.fd);
11810 if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) {
11811 fprintf(fp, "%d", np->ndup.dupfd);
11813 sharg(np->nfile.fname, fp);
11827 struct nodelist *bqlist;
11830 if (arg->type != NARG) {
11831 printf("<node type %d>\n", arg->type);
11835 bqlist = arg->narg.backquote;
11836 for (p = arg->narg.text ; *p ; p++) {
11845 if (subtype == VSLENGTH)
11851 if (subtype & VSNUL)
11854 switch (subtype & VSTYPE) {
11873 case VSTRIMLEFTMAX:
11880 case VSTRIMRIGHTMAX:
11887 printf("<subtype %d>", subtype);
11894 case CTLBACKQ|CTLQUOTE:
11897 shtree(bqlist->n, -1, NULL, fp);
11909 indent(amount, pfx, fp)
11916 for (i = 0 ; i < amount ; i++) {
11917 if (pfx && i == amount - 1)
11935 static int debug = 1;
11937 static int debug = 0;
11945 if (tracefile == NULL)
11947 putc(c, tracefile);
11953 trace(const char *fmt, ...)
11961 fmt = va_arg(va, char *);
11963 if (tracefile != NULL) {
11964 (void) vfprintf(tracefile, fmt, va);
11965 if (strchr(fmt, '\n'))
11966 (void) fflush(tracefile);
11976 if (tracefile == NULL)
11978 fputs(s, tracefile);
11979 if (strchr(s, '\n'))
11991 if (tracefile == NULL)
11993 putc('"', tracefile);
11994 for (p = s ; *p ; p++) {
11996 case '\n': c = 'n'; goto backslash;
11997 case '\t': c = 't'; goto backslash;
11998 case '\r': c = 'r'; goto backslash;
11999 case '"': c = '"'; goto backslash;
12000 case '\\': c = '\\'; goto backslash;
12001 case CTLESC: c = 'e'; goto backslash;
12002 case CTLVAR: c = 'v'; goto backslash;
12003 case CTLVAR+CTLQUOTE: c = 'V'; goto backslash;
12004 case CTLBACKQ: c = 'q'; goto backslash;
12005 case CTLBACKQ+CTLQUOTE: c = 'Q'; goto backslash;
12006 backslash: putc('\\', tracefile);
12007 putc(c, tracefile);
12010 if (*p >= ' ' && *p <= '~')
12011 putc(*p, tracefile);
12013 putc('\\', tracefile);
12014 putc(*p >> 6 & 03, tracefile);
12015 putc(*p >> 3 & 07, tracefile);
12016 putc(*p & 07, tracefile);
12021 putc('"', tracefile);
12029 if (tracefile == NULL)
12034 putc(' ', tracefile);
12036 putc('\n', tracefile);
12051 #ifdef not_this_way
12054 if ((p = getenv("HOME")) == NULL) {
12055 if (geteuid() == 0)
12061 strcat(s, "/trace");
12064 strcpy(s, "./trace");
12065 #endif /* not_this_way */
12066 if ((tracefile = fopen(s, "a")) == NULL) {
12067 fprintf(stderr, "Can't open %s\n", s);
12071 if ((flags = fcntl(fileno(tracefile), F_GETFL, 0)) >= 0)
12072 fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND);
12074 fputs("\nTracing started.\n", tracefile);
12081 * The trap builtin.
12085 trapcmd(argc, argv)
12094 for (signo = 0 ; signo < NSIG ; signo++) {
12095 if (trap[signo] != NULL) {
12098 p = single_quote(trap[signo]);
12099 printf("trap -- %s %s\n", p,
12100 signal_names[signo] + (signo ? 3 : 0)
12113 if ((signo = decode_signal(*ap, 0)) < 0)
12114 error("%s: bad trap", *ap);
12117 if (action[0] == '-' && action[1] == '\0')
12120 action = savestr(action);
12123 ckfree(trap[signo]);
12124 trap[signo] = action;
12139 * Set the signal handler for the specified signal. The routine figures
12140 * out what it should be set to.
12144 setsignal(int signo)
12148 struct sigaction act;
12150 if ((t = trap[signo]) == NULL)
12152 else if (*t != '\0')
12156 if (rootshell && action == S_DFL) {
12159 if (iflag || minusc || sflag == 0)
12185 t = &sigmode[signo - 1];
12188 * current setting unknown
12190 if (sigaction(signo, 0, &act) == -1) {
12192 * Pretend it worked; maybe we should give a warning
12193 * here, but other shells don't. We don't alter
12194 * sigmode, so that we retry every time.
12198 if (act.sa_handler == SIG_IGN) {
12199 if (mflag && (signo == SIGTSTP ||
12200 signo == SIGTTIN || signo == SIGTTOU)) {
12201 *t = S_IGN; /* don't hard ignore these */
12205 *t = S_RESET; /* force to be set */
12208 if (*t == S_HARD_IGN || *t == action)
12212 act.sa_handler = onsig;
12215 act.sa_handler = SIG_IGN;
12218 act.sa_handler = SIG_DFL;
12222 sigemptyset(&act.sa_mask);
12223 sigaction(signo, &act, 0);
12234 if (sigmode[signo - 1] != S_IGN && sigmode[signo - 1] != S_HARD_IGN) {
12235 signal(signo, SIG_IGN);
12237 sigmode[signo - 1] = S_HARD_IGN;
12248 if (signo == SIGINT && trap[SIGINT] == NULL) {
12252 gotsig[signo - 1] = 1;
12258 * Called to execute a trap. Perhaps we should avoid entering new trap
12259 * handlers while we are executing a trap handler.
12269 for (i = 1 ; ; i++) {
12276 savestatus=exitstatus;
12277 evalstring(trap[i], 0);
12278 exitstatus=savestatus;
12285 * Called to exit the shell.
12289 exitshell(int status)
12291 struct jmploc loc1, loc2;
12294 TRACE(("exitshell(%d) pid=%d\n", status, getpid()));
12295 if (setjmp(loc1.loc)) {
12298 if (setjmp(loc2.loc)) {
12302 if ((p = trap[0]) != NULL && *p != '\0') {
12306 l1: handler = &loc2; /* probably unnecessary */
12315 static int decode_signal(const char *string, int minsig)
12319 if (is_number(string, &signo)) {
12320 if (signo >= NSIG) {
12330 for (; signo < NSIG; signo++) {
12331 if (!strcasecmp(string, &(signal_names[signo])[3])) {
12335 if (!strcasecmp(string, signal_names[signo])) {
12342 static struct var **hashvar (const char *);
12343 static void showvars (const char *, int, int);
12344 static struct var **findvar (struct var **, const char *);
12347 * Initialize the varable symbol tables and import the environment
12351 * This routine initializes the builtin variables. It is called when the
12352 * shell is initialized and again when a shell procedure is spawned.
12357 const struct varinit *ip;
12361 for (ip = varinit ; (vp = ip->var) != NULL ; ip++) {
12362 if ((vp->flags & VEXPORT) == 0) {
12363 vpp = hashvar(ip->text);
12366 vp->text = strdup(ip->text);
12367 vp->flags = ip->flags;
12368 vp->func = ip->func;
12372 * PS1 depends on uid
12374 if ((vps1.flags & VEXPORT) == 0) {
12375 vpp = hashvar("PS1=");
12378 vps1.text = strdup(geteuid() ? "PS1=$ " : "PS1=# ");
12379 vps1.flags = VSTRFIXED|VTEXTFIXED;
12384 * Set the value of a variable. The flags argument is ored with the
12385 * flags of the variable. If val is NULL, the variable is unset.
12389 setvar(name, val, flags)
12390 const char *name, *val;
12406 if (! is_in_name(*p)) {
12407 if (*p == '\0' || *p == '=')
12413 namelen = p - name;
12415 error("%.*s: bad variable name", namelen, name);
12416 len = namelen + 2; /* 2 is space for '=' and '\0' */
12420 len += vallen = strlen(val);
12423 nameeq = ckmalloc(len);
12424 memcpy(nameeq, name, namelen);
12425 nameeq[namelen] = '=';
12427 memcpy(nameeq + namelen + 1, val, vallen + 1);
12429 nameeq[namelen + 1] = '\0';
12431 setvareq(nameeq, flags);
12438 * Same as setvar except that the variable and value are passed in
12439 * the first argument as name=value. Since the first argument will
12440 * be actually stored in the table, it should not be a string that
12449 struct var *vp, **vpp;
12452 flags |= (VEXPORT & (((unsigned) (1 - aflag)) - 1));
12453 if ((vp = *findvar(vpp, s))) {
12454 if (vp->flags & VREADONLY) {
12455 size_t len = strchr(s, '=') - s;
12456 error("%.*s: is read only", len, s);
12460 if (vp->func && (flags & VNOFUNC) == 0)
12461 (*vp->func)(strchr(s, '=') + 1);
12463 if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0)
12466 vp->flags &= ~(VTEXTFIXED|VSTACK|VUNSET);
12467 vp->flags |= flags;
12471 * We could roll this to a function, to handle it as
12472 * a regular variable function callback, but why bother?
12474 if (iflag && (vp == &vmpath || (vp == &vmail && !mpathset())))
12480 vp = ckmalloc(sizeof (*vp));
12491 * Process a linked list of variable assignments.
12496 struct strlist *mylist;
12498 struct strlist *lp;
12501 for (lp = mylist ; lp ; lp = lp->next) {
12502 setvareq(savestr(lp->text), 0);
12510 * Find the value of a variable. Returns NULL if not set.
12513 static const char *
12519 if ((v = *findvar(hashvar(name), name)) && !(v->flags & VUNSET)) {
12520 return strchr(v->text, '=') + 1;
12528 * Search the environment of a builtin command.
12531 static const char *
12532 bltinlookup(const char *name)
12534 const struct strlist *sp;
12536 for (sp = cmdenviron ; sp ; sp = sp->next) {
12537 if (varequal(sp->text, name))
12538 return strchr(sp->text, '=') + 1;
12540 return lookupvar(name);
12546 * Generate a list of exported variables. This routine is used to construct
12547 * the third argument to execve when executing a program.
12559 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
12560 for (vp = *vpp ; vp ; vp = vp->next)
12561 if (vp->flags & VEXPORT)
12564 ep = env = stalloc((nenv + 1) * sizeof *env);
12565 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
12566 for (vp = *vpp ; vp ; vp = vp->next)
12567 if (vp->flags & VEXPORT)
12576 * Called when a shell procedure is invoked to clear out nonexported
12577 * variables. It is also necessary to reallocate variables of with
12578 * VSTACK set since these are currently allocated on the stack.
12584 struct var *vp, **prev;
12586 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
12587 for (prev = vpp ; (vp = *prev) != NULL ; ) {
12588 if ((vp->flags & VEXPORT) == 0) {
12590 if ((vp->flags & VTEXTFIXED) == 0)
12592 if ((vp->flags & VSTRFIXED) == 0)
12595 if (vp->flags & VSTACK) {
12596 vp->text = savestr(vp->text);
12597 vp->flags &=~ VSTACK;
12609 * Command to list all variables which are set. Currently this command
12610 * is invoked from the set command when the set command is called without
12615 showvarscmd(argc, argv)
12619 showvars(nullstr, VUNSET, VUNSET);
12626 * The export and readonly commands.
12630 exportcmd(argc, argv)
12637 int flag = argv[0][0] == 'r'? VREADONLY : VEXPORT;
12640 listsetvar(cmdenviron);
12641 pflag = (nextopt("p") == 'p');
12642 if (argc > 1 && !pflag) {
12643 while ((name = *argptr++) != NULL) {
12644 if ((p = strchr(name, '=')) != NULL) {
12647 if ((vp = *findvar(hashvar(name), name))) {
12652 setvar(name, p, flag);
12656 showvars(argv[0], flag, 0);
12663 * The "local" command.
12666 /* funcnest nonzero if we are currently evaluating a function */
12669 localcmd(argc, argv)
12676 error("Not in a function");
12677 while ((name = *argptr++) != NULL) {
12685 * Make a variable a local variable. When a variable is made local, it's
12686 * value and flags are saved in a localvar structure. The saved values
12687 * will be restored when the shell function returns. We handle the name
12688 * "-" as a special case.
12695 struct localvar *lvp;
12700 lvp = ckmalloc(sizeof (struct localvar));
12701 if (name[0] == '-' && name[1] == '\0') {
12703 p = ckmalloc(sizeof optet_vals);
12704 lvp->text = memcpy(p, optet_vals, sizeof optet_vals);
12707 vpp = hashvar(name);
12708 vp = *findvar(vpp, name);
12710 if (strchr(name, '='))
12711 setvareq(savestr(name), VSTRFIXED);
12713 setvar(name, NULL, VSTRFIXED);
12714 vp = *vpp; /* the new variable */
12716 lvp->flags = VUNSET;
12718 lvp->text = vp->text;
12719 lvp->flags = vp->flags;
12720 vp->flags |= VSTRFIXED|VTEXTFIXED;
12721 if (strchr(name, '='))
12722 setvareq(savestr(name), 0);
12726 lvp->next = localvars;
12733 * Called after a function returns.
12738 struct localvar *lvp;
12741 while ((lvp = localvars) != NULL) {
12742 localvars = lvp->next;
12744 if (vp == NULL) { /* $- saved */
12745 memcpy(optet_vals, lvp->text, sizeof optet_vals);
12747 } else if ((lvp->flags & (VUNSET|VSTRFIXED)) == VUNSET) {
12748 (void)unsetvar(vp->text);
12750 if ((vp->flags & VTEXTFIXED) == 0)
12752 vp->flags = lvp->flags;
12753 vp->text = lvp->text;
12761 setvarcmd(argc, argv)
12766 return unsetcmd(argc, argv);
12767 else if (argc == 3)
12768 setvar(argv[1], argv[2], 0);
12770 error("List assignment not implemented");
12776 * The unset builtin command. We unset the function before we unset the
12777 * variable to allow a function to be unset when there is a readonly variable
12778 * with the same name.
12782 unsetcmd(argc, argv)
12792 while ((i = nextopt("vf")) != '\0') {
12798 if (flg_func == 0 && flg_var == 0)
12801 for (ap = argptr; *ap ; ap++) {
12805 ret |= unsetvar(*ap);
12812 * Unset the specified variable.
12816 unsetvar(const char *s)
12821 vpp = findvar(hashvar(s), s);
12824 if (vp->flags & VREADONLY)
12827 if (*(strchr(vp->text, '=') + 1) != '\0')
12828 setvar(s, nullstr, 0);
12829 vp->flags &= ~VEXPORT;
12830 vp->flags |= VUNSET;
12831 if ((vp->flags & VSTRFIXED) == 0) {
12832 if ((vp->flags & VTEXTFIXED) == 0)
12847 * Find the appropriate entry in the hash table from the name.
12850 static struct var **
12851 hashvar(const char *p)
12853 unsigned int hashval;
12855 hashval = ((unsigned char) *p) << 4;
12856 while (*p && *p != '=')
12857 hashval += (unsigned char) *p++;
12858 return &vartab[hashval % VTABSIZE];
12864 * Returns true if the two strings specify the same varable. The first
12865 * variable name is terminated by '='; the second may be terminated by
12866 * either '=' or '\0'.
12870 varequal(const char *p, const char *q)
12872 while (*p == *q++) {
12876 if (*p == '=' && *(q - 1) == '\0')
12882 showvars(const char *myprefix, int mask, int xor)
12886 const char *sep = myprefix == nullstr ? myprefix : spcstr;
12888 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
12889 for (vp = *vpp ; vp ; vp = vp->next) {
12890 if ((vp->flags & mask) ^ xor) {
12894 p = strchr(vp->text, '=') + 1;
12895 len = p - vp->text;
12896 p = single_quote(p);
12898 printf("%s%s%.*s%s\n", myprefix, sep, len,
12906 static struct var **
12907 findvar(struct var **vpp, const char *name)
12909 for (; *vpp; vpp = &(*vpp)->next) {
12910 if (varequal((*vpp)->text, name)) {
12918 * Copyright (c) 1999 Herbert Xu <herbert@debian.org>
12919 * This file contains code for the times builtin.
12920 * $Id: ash.c,v 1.10 2001/07/12 20:26:31 andersen Exp $
12922 static int timescmd (int argc, char **argv)
12925 long int clk_tck = sysconf(_SC_CLK_TCK);
12928 printf("%dm%fs %dm%fs\n%dm%fs %dm%fs\n",
12929 (int) (buf.tms_utime / clk_tck / 60),
12930 ((double) buf.tms_utime) / clk_tck,
12931 (int) (buf.tms_stime / clk_tck / 60),
12932 ((double) buf.tms_stime) / clk_tck,
12933 (int) (buf.tms_cutime / clk_tck / 60),
12934 ((double) buf.tms_cutime) / clk_tck,
12935 (int) (buf.tms_cstime / clk_tck / 60),
12936 ((double) buf.tms_cstime) / clk_tck);
12942 * Copyright (c) 1989, 1991, 1993, 1994
12943 * The Regents of the University of California. All rights reserved.
12945 * This code is derived from software contributed to Berkeley by
12946 * Kenneth Almquist.
12948 * Redistribution and use in source and binary forms, with or without
12949 * modification, are permitted provided that the following conditions
12951 * 1. Redistributions of source code must retain the above copyright
12952 * notice, this list of conditions and the following disclaimer.
12953 * 2. Redistributions in binary form must reproduce the above copyright
12954 * notice, this list of conditions and the following disclaimer in the
12955 * documentation and/or other materials provided with the distribution.
12957 * 3. <BSD Advertising Clause omitted per the July 22, 1999 licensing change
12958 * ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change>
12960 * 4. Neither the name of the University nor the names of its contributors
12961 * may be used to endorse or promote products derived from this software
12962 * without specific prior written permission.
12964 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
12965 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
12966 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
12967 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
12968 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
12969 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
12970 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
12971 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
12972 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
12973 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF