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 adds a bit over 2k an x86 system. */
55 #define ASH_MATH_SUPPORT
57 /* Getopts is used by shell procedures to parse positional parameters.
58 * You probably want to leave this disabled, and use the busybox getopt
59 * applet if you want to do this sort of thing. There are some scripts
60 * out there that use it, so it you need it, enable. Most people will
61 * leave this disabled. This adds 1k on an x86 system. */
64 /* This allows you to override shell builtins and use whatever is on
65 * the filesystem. This is most useful when ash is acting as a
66 * standalone shell. Adds about 272 bytes. */
70 /* Optimize size vs speed as size */
71 #define ASH_OPTIMIZE_FOR_SIZE
73 /* Enable this to compile in extra debugging noise. When debugging is
74 * on, debugging info will be written to $HOME/trace and a quit signal
75 * will generate a core dump. */
78 /* 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 replaced with a custom hand
1566 * written implementation written by Aaron Lehmann <aaronl@vitelus.com>.
1567 * This is now part of libbb, so that it can be used by all the shells
1569 #define ARITH_NUM 257
1570 #define ARITH_LPAREN 258
1571 #define ARITH_RPAREN 259
1572 #define ARITH_OR 260
1573 #define ARITH_AND 261
1574 #define ARITH_BOR 262
1575 #define ARITH_BXOR 263
1576 #define ARITH_BAND 264
1577 #define ARITH_EQ 265
1578 #define ARITH_NE 266
1579 #define ARITH_LT 267
1580 #define ARITH_GT 268
1581 #define ARITH_GE 269
1582 #define ARITH_LE 270
1583 #define ARITH_LSHIFT 271
1584 #define ARITH_RSHIFT 272
1585 #define ARITH_ADD 273
1586 #define ARITH_SUB 274
1587 #define ARITH_MUL 275
1588 #define ARITH_DIV 276
1589 #define ARITH_REM 277
1590 #define ARITH_UNARYMINUS 278
1591 #define ARITH_UNARYPLUS 279
1592 #define ARITH_NOT 280
1593 #define ARITH_BNOT 281
1595 static void expari (int);
1598 static char *trap[NSIG]; /* trap handler commands */
1599 static char sigmode[NSIG - 1]; /* current value of signal */
1600 static char gotsig[NSIG - 1]; /* indicates specified signal received */
1601 static int pendingsigs; /* indicates some signal received */
1604 * This file was generated by the mkbuiltins program.
1608 static int bgcmd (int, char **);
1609 static int fgcmd (int, char **);
1610 static int killcmd (int, char **);
1612 static int bltincmd (int, char **);
1613 static int cdcmd (int, char **);
1614 static int breakcmd (int, char **);
1616 static int commandcmd (int, char **);
1618 static int dotcmd (int, char **);
1619 static int evalcmd (int, char **);
1620 static int execcmd (int, char **);
1621 static int exitcmd (int, char **);
1622 static int exportcmd (int, char **);
1623 static int histcmd (int, char **);
1624 static int hashcmd (int, char **);
1625 static int helpcmd (int, char **);
1626 static int jobscmd (int, char **);
1627 static int localcmd (int, char **);
1629 static int pwdcmd (int, char **);
1631 static int readcmd (int, char **);
1632 static int returncmd (int, char **);
1633 static int setcmd (int, char **);
1634 static int setvarcmd (int, char **);
1635 static int shiftcmd (int, char **);
1636 static int trapcmd (int, char **);
1637 static int umaskcmd (int, char **);
1639 static int aliascmd (int, char **);
1640 static int unaliascmd (int, char **);
1642 static int unsetcmd (int, char **);
1643 static int waitcmd (int, char **);
1644 static int ulimitcmd (int, char **);
1645 static int timescmd (int, char **);
1646 #ifdef ASH_MATH_SUPPORT
1647 static int letcmd (int, char **);
1649 static int typecmd (int, char **);
1651 static int getoptscmd (int, char **);
1654 #ifndef BB_TRUE_FALSE
1655 static int true_main (int, char **);
1656 static int false_main (int, char **);
1659 static void setpwd (const char *, int);
1662 #define BUILTIN_NOSPEC "0"
1663 #define BUILTIN_SPECIAL "1"
1664 #define BUILTIN_REGULAR "2"
1665 #define BUILTIN_ASSIGN "4"
1666 #define BUILTIN_SPEC_ASSG "5"
1667 #define BUILTIN_REG_ASSG "6"
1669 #define IS_BUILTIN_SPECIAL(builtincmd) ((builtincmd)->name[0] & 1)
1670 #define IS_BUILTIN_REGULAR(builtincmd) ((builtincmd)->name[0] & 2)
1671 #define IS_BUILTIN_ASSIGN(builtincmd) ((builtincmd)->name[0] & 4)
1675 int (*const builtinfunc) (int, char **);
1680 /* It is CRUCIAL that this listing be kept in ascii order, otherwise
1681 * the binary search in find_builtin() will stop working. If you value
1682 * your kneecaps, you'll be sure to *make sure* that any changes made
1683 * to this array result in the listing remaining in ascii order. You
1686 static const struct builtincmd builtincmds[] = {
1687 { BUILTIN_SPECIAL ".", dotcmd }, /* first, see declare DOTCMD */
1688 { BUILTIN_SPECIAL ":", true_main },
1690 { BUILTIN_REG_ASSG "alias", aliascmd },
1693 { BUILTIN_REGULAR "bg", bgcmd },
1695 { BUILTIN_SPECIAL "break", breakcmd },
1696 { BUILTIN_SPECIAL "builtin", bltincmd },
1697 { BUILTIN_REGULAR "cd", cdcmd },
1698 { BUILTIN_NOSPEC "chdir", cdcmd },
1700 { BUILTIN_REGULAR "command", commandcmd },
1702 { BUILTIN_SPECIAL "continue", breakcmd },
1703 { BUILTIN_SPECIAL "eval", evalcmd },
1704 { BUILTIN_SPECIAL "exec", execcmd },
1705 { BUILTIN_SPECIAL "exit", exitcmd },
1706 { BUILTIN_SPEC_ASSG "export", exportcmd },
1707 { BUILTIN_REGULAR "false", false_main },
1708 { BUILTIN_REGULAR "fc", histcmd },
1710 { BUILTIN_REGULAR "fg", fgcmd },
1713 { BUILTIN_REGULAR "getopts", getoptscmd },
1715 { BUILTIN_NOSPEC "hash", hashcmd },
1716 { BUILTIN_NOSPEC "help", helpcmd },
1717 { BUILTIN_REGULAR "jobs", jobscmd },
1719 { BUILTIN_REGULAR "kill", killcmd },
1721 #ifdef ASH_MATH_SUPPORT
1722 { BUILTIN_REGULAR "let", letcmd },
1724 { BUILTIN_ASSIGN "local", localcmd },
1726 { BUILTIN_NOSPEC "pwd", pwdcmd },
1728 { BUILTIN_REGULAR "read", readcmd },
1729 { BUILTIN_SPEC_ASSG "readonly", exportcmd },
1730 { BUILTIN_SPECIAL "return", returncmd },
1731 { BUILTIN_SPECIAL "set", setcmd },
1732 { BUILTIN_NOSPEC "setvar", setvarcmd },
1733 { BUILTIN_SPECIAL "shift", shiftcmd },
1734 { BUILTIN_SPECIAL "times", timescmd },
1735 { BUILTIN_SPECIAL "trap", trapcmd },
1736 { BUILTIN_REGULAR "true", true_main },
1737 { BUILTIN_NOSPEC "type", typecmd },
1738 { BUILTIN_NOSPEC "ulimit", ulimitcmd },
1739 { BUILTIN_REGULAR "umask", umaskcmd },
1741 { BUILTIN_REGULAR "unalias", unaliascmd },
1743 { BUILTIN_SPECIAL "unset", unsetcmd },
1744 { BUILTIN_REGULAR "wait", waitcmd },
1746 #define NUMBUILTINS (sizeof (builtincmds) / sizeof (struct builtincmd) )
1748 static const struct builtincmd *DOTCMD = &builtincmds[0];
1749 static struct builtincmd *BLTINCMD;
1750 static struct builtincmd *EXECCMD;
1751 static struct builtincmd *EVALCMD;
1754 #define JOBSTOPPED 1 /* all procs are stopped */
1755 #define JOBDONE 2 /* all procs are completed */
1758 * A job structure contains information about a job. A job is either a
1759 * single process or a set of processes contained in a pipeline. In the
1760 * latter case, pidlist will be non-NULL, and will point to a -1 terminated
1765 pid_t pid; /* process id */
1766 int status; /* status flags (defined above) */
1767 char *cmd; /* text of command being run */
1771 static int job_warning; /* user was warned about stopped jobs */
1774 static void setjobctl(int enable);
1776 #define setjobctl(on) /* do nothing */
1781 struct procstat ps0; /* status of process */
1782 struct procstat *ps; /* status or processes when more than one */
1783 short nprocs; /* number of processes */
1784 short pgrp; /* process group of this job */
1785 char state; /* true if job is finished */
1786 char used; /* true if this entry is in used */
1787 char changed; /* true if status has changed */
1789 char jobctl; /* job running under job control */
1793 static struct job *jobtab; /* array of jobs */
1794 static int njobs; /* size of array */
1795 static int backgndpid = -1; /* pid of last background process */
1797 static int initialpgrp; /* pgrp of shell on invocation */
1798 static int curjob; /* current job */
1801 static int intreceived;
1803 static struct job *makejob (const union node *, int);
1804 static int forkshell (struct job *, const union node *, int);
1805 static int waitforjob (struct job *);
1807 static int docd (char *, int);
1808 static char *getcomponent (void);
1809 static void updatepwd (const char *);
1810 static void getpwd (void);
1812 static char *padvance (const char **, const char *);
1814 static char nullstr[1]; /* zero length string */
1815 static char *curdir = nullstr; /* current working directory */
1816 static char *cdcomppath;
1830 if ((dest = *argptr) == NULL && (dest = bltinlookup("HOME")) == NULL)
1831 error("HOME not set");
1834 if (dest[0] == '-' && dest[1] == '\0') {
1835 dest = bltinlookup("OLDPWD");
1836 if (!dest || !*dest) {
1845 if (*dest == '/' || (path = bltinlookup("CDPATH")) == NULL)
1847 while ((p = padvance(&path, dest)) != NULL) {
1848 if (stat(p, &statb) >= 0 && S_ISDIR(statb.st_mode)) {
1853 if (p[0] == '.' && p[1] == '/' && p[2] != '\0')
1855 print = strcmp(p, dest);
1857 if (docd(p, print) >= 0)
1862 error("can't cd to %s", dest);
1868 * Actually do the chdir. In an interactive shell, print the
1869 * directory name if "print" is nonzero.
1884 TRACE(("docd(\"%s\", %d) called\n", dest, print));
1887 * Check each component of the path. If we find a symlink or
1888 * something we can't stat, clear curdir to force a getcwd()
1889 * next time we get the value of the current directory.
1892 cdcomppath = sstrdup(dest);
1899 while ((q = getcomponent()) != NULL) {
1900 if (q[0] == '\0' || (q[0] == '.' && q[1] == '\0'))
1908 if (equal(component, ".."))
1911 if ((lstat(stackblock(), &statb) < 0)
1912 || (S_ISLNK(statb.st_mode))) {
1920 if (chdir(dest) < 0) {
1924 updatepwd(badstat ? NULL : dest);
1927 printf(snlfmt, curdir);
1933 * Get the next component of the path name pointed to by cdcomppath.
1934 * This routine overwrites the string pointed to by cdcomppath.
1942 if ((p = cdcomppath) == NULL)
1945 while (*p != '/' && *p != '\0')
1959 * Update curdir (the name of the current directory) in response to a
1960 * cd command. We also call hashcd to let the routines in exec.c know
1961 * that the current directory has changed.
1964 static void hashcd (void);
1967 updatepwd(const char *dir)
1973 hashcd(); /* update command hash table */
1976 * If our argument is NULL, we don't know the current directory
1977 * any more because we traversed a symbolic link or something
1978 * we couldn't stat().
1980 if (dir == NULL || curdir == nullstr) {
1985 cdcomppath = sstrdup(dir);
1994 while ((p = getcomponent()) != NULL) {
1995 if (equal(p, "..")) {
1996 while (new > stackblock() && (STUNPUTC(new), *new) != '/');
1997 } else if (*p != '\0' && ! equal(p, ".")) {
2003 if (new == stackblock())
2006 setpwd(stackblock(), 1);
2016 printf(snlfmt, curdir);
2022 * Find out what the current directory is. If we already know the current
2023 * directory, this routine returns immediately.
2028 curdir = xgetcwd(0);
2034 setpwd(const char *val, int setold)
2037 setvar("OLDPWD", curdir, VEXPORT);
2040 if (curdir != nullstr) {
2047 curdir = savestr(val);
2050 setvar("PWD", curdir, VEXPORT);
2054 * Errors and exceptions.
2058 * Code to handle exceptions in C.
2062 * We enclose jmp_buf in a structure so that we can declare pointers to
2063 * jump locations. The global variable handler contains the location to
2064 * jump to when an exception occurs, and the global variable exception
2065 * contains a code identifying the exeception. To implement nested
2066 * exception handlers, the user should save the value of handler on entry
2067 * to an inner scope, set handler to point to a jmploc structure for the
2068 * inner scope, and restore handler on exit from the scope.
2076 #define EXINT 0 /* SIGINT received */
2077 #define EXERROR 1 /* a generic error */
2078 #define EXSHELLPROC 2 /* execute a shell procedure */
2079 #define EXEXEC 3 /* command execution failed */
2081 static struct jmploc *handler;
2082 static int exception;
2084 static void exverror (int, const char *, va_list)
2085 __attribute__((__noreturn__));
2088 * Called to raise an exception. Since C doesn't include exceptions, we
2089 * just do a longjmp to the exception handler. The type of exception is
2090 * stored in the global variable "exception".
2093 static void exraise (int) __attribute__((__noreturn__));
2099 if (handler == NULL)
2104 longjmp(handler->loc, 1);
2109 * Called from trap.c when a SIGINT is received. (If the user specifies
2110 * that SIGINT is to be trapped or ignored using the trap builtin, then
2111 * this routine is not called.) Suppressint is nonzero when interrupts
2112 * are held using the INTOFF macro. The call to _exit is necessary because
2113 * there is a short period after a fork before the signal handlers are
2114 * set to the appropriate value for the child. (The test for iflag is
2115 * just defensive programming.)
2127 sigemptyset(&mysigset);
2128 sigprocmask(SIG_SETMASK, &mysigset, NULL);
2129 if (rootshell && iflag)
2132 signal(SIGINT, SIG_DFL);
2139 static char *commandname; /* currently executing command */
2142 * Exverror is called to raise the error exception. If the first argument
2143 * is not NULL then error prints an error message using printf style
2144 * formatting. It then raises the error exception.
2147 exverror(int cond, const char *msg, va_list ap)
2154 TRACE(("exverror(%d, \"%s\") pid=%d\n", cond, msg, getpid()));
2156 TRACE(("exverror(%d, NULL) pid=%d\n", cond, getpid()));
2160 out2fmt("%s: ", commandname);
2161 vfprintf(stderr, msg, ap);
2170 error(const char *msg, ...)
2174 exverror(EXERROR, msg, ap);
2181 exerror(int cond, const char *msg, ...)
2185 exverror(cond, msg, ap);
2193 * Table of error messages.
2197 short errcode; /* error number */
2198 char action; /* operation which encountered the error */
2202 * Types of operations (passed to the errmsg routine).
2205 #define E_OPEN 01 /* opening a file */
2206 #define E_CREAT 02 /* creating a file */
2207 #define E_EXEC 04 /* executing a program */
2209 #define ALL (E_OPEN|E_CREAT|E_EXEC)
2211 static const struct errname errormsg[] = {
2216 { ENOENT, E_CREAT },
2218 { ENOTDIR, E_OPEN },
2219 { ENOTDIR, E_CREAT },
2220 { ENOTDIR, E_EXEC },
2222 { EEXIST, E_CREAT },
2261 { ELIBACC, E_EXEC },
2265 #define ERRNAME_SIZE (sizeof(errormsg)/sizeof(struct errname))
2268 * Return a string describing an error. The returned string may be a
2269 * pointer to a static buffer that will be overwritten on the next call.
2270 * Action describes the operation that got the error.
2274 errmsg(int e, int action)
2276 struct errname const *ep;
2277 static char buf[12];
2279 for (ep = errormsg ; ep < errormsg+ERRNAME_SIZE; ep++) {
2280 if (ep->errcode == e && (ep->action & action) != 0)
2284 snprintf(buf, sizeof buf, "error %d", e);
2289 #ifdef ASH_OPTIMIZE_FOR_SIZE
2292 if (--suppressint == 0 && intpending) {
2296 static void forceinton (void) {
2303 /* flags in argument to evaltree */
2304 #define EV_EXIT 01 /* exit after evaluating tree */
2305 #define EV_TESTED 02 /* exit status is checked; ignore -e flag */
2306 #define EV_BACKCMD 04 /* command executing within back quotes */
2308 static int evalskip; /* set if we are skipping commands */
2309 static int skipcount; /* number of levels to skip */
2310 static int loopnest; /* current loop nesting level */
2311 static int funcnest; /* depth of function calls */
2314 static struct strlist *cmdenviron; /* environment for builtin command */
2315 static int exitstatus; /* exit status of last command */
2316 static int oexitstatus; /* saved exit status */
2318 static void evalsubshell (const union node *, int);
2319 static void expredir (union node *);
2320 static void prehash (union node *);
2321 static void eprintlist (struct strlist *);
2323 static union node *parsecmd(int);
2325 * Called to reset things after an exception.
2329 * The eval commmand.
2331 static void evalstring (char *, int);
2345 STARTSTACKSTR(concat);
2349 STPUTC(*p++, concat);
2350 if ((p = *ap++) == NULL)
2352 STPUTC(' ', concat);
2354 STPUTC('\0', concat);
2355 p = grabstackstr(concat);
2357 evalstring(p, EV_TESTED);
2363 * Execute a command or commands contained in a string.
2366 static void evaltree (union node *, int);
2367 static void setinputstring (char *);
2368 static void popfile (void);
2369 static void setstackmark(struct stackmark *mark);
2370 static void popstackmark(struct stackmark *mark);
2374 evalstring(char *s, int flag)
2377 struct stackmark smark;
2379 setstackmark(&smark);
2381 while ((n = parsecmd(0)) != NEOF) {
2383 popstackmark(&smark);
2386 popstackmark(&smark);
2389 static struct builtincmd *find_builtin (const char *);
2390 static void expandarg (union node *, struct arglist *, int);
2391 static void calcsize (const union node *);
2392 static union node *copynode (const union node *);
2395 * Make a copy of a parse tree.
2398 static int funcblocksize; /* size of structures in function */
2399 static int funcstringsize; /* size of strings in node */
2400 static pointer funcblock; /* block to allocate function from */
2401 static char *funcstring; /* block to allocate strings from */
2404 static inline union node *
2405 copyfunc(union node *n)
2412 funcblock = ckmalloc(funcblocksize + funcstringsize);
2413 funcstring = (char *) funcblock + funcblocksize;
2418 * Free a parse tree.
2422 freefunc(union node *n)
2430 * Add a new command entry, replacing any existing command entry for
2435 addcmdentry(char *name, struct cmdentry *entry)
2437 struct tblentry *cmdp;
2440 cmdp = cmdlookup(name, 1);
2441 if (cmdp->cmdtype == CMDFUNCTION) {
2442 freefunc(cmdp->param.func);
2444 cmdp->cmdtype = entry->cmdtype;
2445 cmdp->param = entry->u;
2450 evalloop(const union node *n, int flags)
2457 evaltree(n->nbinary.ch1, EV_TESTED);
2459 skipping: if (evalskip == SKIPCONT && --skipcount <= 0) {
2463 if (evalskip == SKIPBREAK && --skipcount <= 0)
2467 if (n->type == NWHILE) {
2468 if (exitstatus != 0)
2471 if (exitstatus == 0)
2474 evaltree(n->nbinary.ch2, flags & EV_TESTED);
2475 status = exitstatus;
2480 exitstatus = status;
2484 evalfor(const union node *n, int flags)
2486 struct arglist arglist;
2489 struct stackmark smark;
2491 setstackmark(&smark);
2492 arglist.lastp = &arglist.list;
2493 for (argp = n->nfor.args ; argp ; argp = argp->narg.next) {
2494 oexitstatus = exitstatus;
2495 expandarg(argp, &arglist, EXP_FULL | EXP_TILDE | EXP_RECORD);
2499 *arglist.lastp = NULL;
2503 for (sp = arglist.list ; sp ; sp = sp->next) {
2504 setvar(n->nfor.var, sp->text, 0);
2505 evaltree(n->nfor.body, flags & EV_TESTED);
2507 if (evalskip == SKIPCONT && --skipcount <= 0) {
2511 if (evalskip == SKIPBREAK && --skipcount <= 0)
2518 popstackmark(&smark);
2522 evalcase(const union node *n, int flags)
2526 struct arglist arglist;
2527 struct stackmark smark;
2529 setstackmark(&smark);
2530 arglist.lastp = &arglist.list;
2531 oexitstatus = exitstatus;
2532 expandarg(n->ncase.expr, &arglist, EXP_TILDE);
2533 for (cp = n->ncase.cases ; cp && evalskip == 0 ; cp = cp->nclist.next) {
2534 for (patp = cp->nclist.pattern ; patp ; patp = patp->narg.next) {
2535 if (casematch(patp, arglist.list->text)) {
2536 if (evalskip == 0) {
2537 evaltree(cp->nclist.body, flags);
2544 popstackmark(&smark);
2548 * Evaluate a pipeline. All the processes in the pipeline are children
2549 * of the process creating the pipeline. (This differs from some versions
2550 * of the shell, which make the last process in a pipeline the parent
2559 struct nodelist *lp;
2564 TRACE(("evalpipe(0x%lx) called\n", (long)n));
2566 for (lp = n->npipe.cmdlist ; lp ; lp = lp->next)
2569 jp = makejob(n, pipelen);
2571 for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
2575 if (pipe(pip) < 0) {
2577 error("Pipe call failed");
2580 if (forkshell(jp, lp->n, n->npipe.backgnd) == 0) {
2584 dup_as_newfd(prevfd, 0);
2596 dup_as_newfd(pip[1], 1);
2600 evaltree(lp->n, EV_EXIT);
2608 if (n->npipe.backgnd == 0) {
2610 exitstatus = waitforjob(jp);
2611 TRACE(("evalpipe: job done exit status %d\n", exitstatus));
2616 static void find_command (const char *, struct cmdentry *, int, const char *);
2619 isassignment(const char *word) {
2620 if (!is_name(*word)) {
2625 } while (is_in_name(*word));
2626 return *word == '=';
2631 evalcommand(union node *cmd, int flags)
2633 struct stackmark smark;
2635 struct arglist arglist;
2636 struct arglist varlist;
2642 struct cmdentry cmdentry;
2644 char *volatile savecmdname;
2645 volatile struct shparam saveparam;
2646 struct localvar *volatile savelocalvars;
2650 const struct builtincmd *firstbltin;
2651 struct jmploc *volatile savehandler;
2652 struct jmploc jmploc;
2654 /* Avoid longjmp clobbering */
2661 /* First expand the arguments. */
2662 TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags));
2663 setstackmark(&smark);
2664 arglist.lastp = &arglist.list;
2665 varlist.lastp = &varlist.list;
2667 oexitstatus = exitstatus;
2670 for (argp = cmd->ncmd.assign; argp; argp = argp->narg.next) {
2671 expandarg(argp, &varlist, EXP_VARTILDE);
2674 argp = cmd->ncmd.args; argp && !arglist.list;
2675 argp = argp->narg.next
2677 expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
2680 struct builtincmd *bcmd;
2682 bcmd = find_builtin(arglist.list->text);
2683 pseudovarflag = bcmd && IS_BUILTIN_ASSIGN(bcmd);
2684 for (; argp; argp = argp->narg.next) {
2685 if (pseudovarflag && isassignment(argp->narg.text)) {
2686 expandarg(argp, &arglist, EXP_VARTILDE);
2689 expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
2692 *arglist.lastp = NULL;
2693 *varlist.lastp = NULL;
2694 expredir(cmd->ncmd.redirect);
2696 for (sp = arglist.list ; sp ; sp = sp->next)
2698 argv = stalloc(sizeof (char *) * (argc + 1));
2700 for (sp = arglist.list ; sp ; sp = sp->next) {
2701 TRACE(("evalcommand arg: %s\n", sp->text));
2706 if (iflag && funcnest == 0 && argc > 0)
2710 /* Print the command if xflag is set. */
2713 eprintlist(varlist.list);
2714 eprintlist(arglist.list);
2718 /* Now locate the command. */
2720 cmdentry.cmdtype = CMDBUILTIN;
2721 firstbltin = cmdentry.u.cmd = BLTINCMD;
2723 const char *oldpath;
2724 int findflag = DO_ERR;
2728 * Modify the command lookup path, if a PATH= assignment
2731 for (sp = varlist.list ; sp ; sp = sp->next)
2732 if (varequal(sp->text, defpathvar)) {
2733 path = sp->text + 5;
2734 findflag |= DO_BRUTE;
2737 oldfindflag = findflag;
2740 find_command(argv[0], &cmdentry, findflag, path);
2741 if (cmdentry.cmdtype == CMDUNKNOWN) { /* command not found */
2745 /* implement bltin and command here */
2746 if (cmdentry.cmdtype != CMDBUILTIN) {
2750 firstbltin = cmdentry.u.cmd;
2752 if (cmdentry.u.cmd == BLTINCMD) {
2754 struct builtincmd *bcmd;
2759 if (!(bcmd = find_builtin(*argv))) {
2760 out2fmt("%s: not found\n", *argv);
2764 cmdentry.u.cmd = bcmd;
2765 if (bcmd != BLTINCMD)
2769 if (cmdentry.u.cmd == find_builtin("command")) {
2774 if (*argv[0] == '-') {
2775 if (!equal(argv[0], "-p")) {
2785 findflag |= DO_BRUTE;
2788 findflag = oldfindflag;
2790 findflag |= DO_NOFUN;
2798 /* Fork off a child process if necessary. */
2799 if (cmd->ncmd.backgnd
2800 || (cmdentry.cmdtype == CMDNORMAL && (flags & EV_EXIT) == 0)
2802 jp = makejob(cmd, 1);
2803 mode = cmd->ncmd.backgnd;
2804 if (forkshell(jp, cmd, mode) != 0)
2805 goto parent; /* at end of routine */
2809 /* This is the child process if a fork occurred. */
2810 /* Execute the command. */
2811 if (cmdentry.cmdtype == CMDFUNCTION) {
2813 trputs("Shell function: "); trargs(argv);
2815 exitstatus = oexitstatus;
2816 redirect(cmd->ncmd.redirect, REDIR_PUSH);
2817 saveparam = shellparam;
2818 shellparam.malloc = 0;
2819 shellparam.nparam = argc - 1;
2820 shellparam.p = argv + 1;
2822 savelocalvars = localvars;
2825 if (setjmp(jmploc.loc)) {
2826 if (exception == EXSHELLPROC) {
2827 freeparam((volatile struct shparam *)
2830 saveparam.optind = shellparam.optind;
2831 saveparam.optoff = shellparam.optoff;
2832 freeparam(&shellparam);
2833 shellparam = saveparam;
2836 localvars = savelocalvars;
2837 handler = savehandler;
2838 longjmp(handler->loc, 1);
2840 savehandler = handler;
2842 for (sp = varlist.list ; sp ; sp = sp->next)
2845 evaltree(cmdentry.u.func, flags & EV_TESTED);
2849 localvars = savelocalvars;
2850 saveparam.optind = shellparam.optind;
2851 saveparam.optoff = shellparam.optoff;
2852 freeparam(&shellparam);
2853 shellparam = saveparam;
2854 handler = savehandler;
2857 if (evalskip == SKIPFUNC) {
2861 if (flags & EV_EXIT)
2862 exitshell(exitstatus);
2863 } else if (cmdentry.cmdtype == CMDBUILTIN) {
2865 trputs("builtin command: "); trargs(argv);
2867 mode = (cmdentry.u.cmd == EXECCMD)? 0 : REDIR_PUSH;
2868 redirect(cmd->ncmd.redirect, mode);
2869 savecmdname = commandname;
2870 if (IS_BUILTIN_SPECIAL(firstbltin)) {
2871 listsetvar(varlist.list);
2873 cmdenviron = varlist.list;
2876 if (setjmp(jmploc.loc)) {
2878 exitstatus = (e == EXINT)? SIGINT+128 : 2;
2881 savehandler = handler;
2883 commandname = argv[0];
2885 optptr = NULL; /* initialize nextopt */
2886 exitstatus = (*cmdentry.u.cmd->builtinfunc)(argc, argv);
2890 if (e != EXSHELLPROC) {
2891 commandname = savecmdname;
2892 if (flags & EV_EXIT)
2893 exitshell(exitstatus);
2895 handler = savehandler;
2897 if ((e != EXERROR && e != EXEXEC)
2898 || cmdentry.u.cmd == BLTINCMD
2899 || cmdentry.u.cmd == DOTCMD
2900 || cmdentry.u.cmd == EVALCMD
2901 || cmdentry.u.cmd == EXECCMD)
2905 if (cmdentry.u.cmd != EXECCMD)
2909 trputs("normal command: "); trargs(argv);
2911 redirect(cmd->ncmd.redirect, 0);
2913 for (sp = varlist.list ; sp ; sp = sp->next)
2914 setvareq(sp->text, VEXPORT|VSTACK);
2915 envp = environment();
2916 shellexec(argv, envp, path, cmdentry.u.index);
2920 parent: /* parent process gets here (if we forked) */
2921 if (mode == 0) { /* argument to fork */
2923 exitstatus = waitforjob(jp);
2929 setvar("_", lastarg, 0);
2930 popstackmark(&smark);
2934 * Evaluate a parse tree. The value is left in the global variable
2944 TRACE(("evaltree(NULL) called\n"));
2947 TRACE(("evaltree(0x%lx: %d) called\n", (long)n, n->type));
2950 evaltree(n->nbinary.ch1, flags & EV_TESTED);
2953 evaltree(n->nbinary.ch2, flags);
2956 evaltree(n->nbinary.ch1, EV_TESTED);
2957 if (evalskip || exitstatus != 0)
2959 evaltree(n->nbinary.ch2, flags);
2962 evaltree(n->nbinary.ch1, EV_TESTED);
2963 if (evalskip || exitstatus == 0)
2965 evaltree(n->nbinary.ch2, flags);
2968 expredir(n->nredir.redirect);
2969 redirect(n->nredir.redirect, REDIR_PUSH);
2970 evaltree(n->nredir.n, flags);
2974 evalsubshell(n, flags);
2977 evalsubshell(n, flags);
2980 evaltree(n->nif.test, EV_TESTED);
2983 if (exitstatus == 0)
2984 evaltree(n->nif.ifpart, flags);
2985 else if (n->nif.elsepart)
2986 evaltree(n->nif.elsepart, flags);
3002 struct builtincmd *bcmd;
3003 struct cmdentry entry;
3005 (bcmd = find_builtin(n->narg.text)) &&
3006 IS_BUILTIN_SPECIAL(bcmd)
3008 out2fmt("%s is a special built-in\n", n->narg.text);
3012 entry.cmdtype = CMDFUNCTION;
3013 entry.u.func = copyfunc(n->narg.next);
3014 addcmdentry(n->narg.text, &entry);
3019 evaltree(n->nnot.com, EV_TESTED);
3020 exitstatus = !exitstatus;
3028 evalcommand(n, flags);
3033 printf("Node type = %d\n", n->type);
3042 (checkexit && eflag && exitstatus && !(flags & EV_TESTED))
3044 exitshell(exitstatus);
3048 * Kick off a subshell to evaluate a tree.
3052 evalsubshell(const union node *n, int flags)
3055 int backgnd = (n->type == NBACKGND);
3057 expredir(n->nredir.redirect);
3059 if (forkshell(jp, n, backgnd) == 0) {
3061 flags &=~ EV_TESTED;
3062 redirect(n->nredir.redirect, 0);
3063 evaltree(n->nredir.n, flags | EV_EXIT); /* never returns */
3067 exitstatus = waitforjob(jp);
3073 * Compute the names of the files in a redirection list.
3076 static void fixredir(union node *n, const char *text, int err);
3079 expredir(union node *n)
3083 for (redir = n ; redir ; redir = redir->nfile.next) {
3085 fn.lastp = &fn.list;
3086 oexitstatus = exitstatus;
3087 switch (redir->type) {
3093 expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR);
3094 redir->nfile.expfname = fn.list->text;
3098 if (redir->ndup.vname) {
3099 expandarg(redir->ndup.vname, &fn, EXP_FULL | EXP_TILDE);
3100 fixredir(redir, fn.list->text, 1);
3109 * Execute a command inside back quotes. If it's a builtin command, we
3110 * want to save its output in a block obtained from malloc. Otherwise
3111 * we fork off a subprocess and get the output of the command via a pipe.
3112 * Should be called with interrupts off.
3116 evalbackcmd(union node *n, struct backcmd *result)
3120 struct stackmark smark; /* unnecessary */
3122 setstackmark(&smark);
3133 error("Pipe call failed");
3135 if (forkshell(jp, n, FORK_NOJOB) == 0) {
3140 dup_as_newfd(pip[1], 1);
3144 evaltree(n, EV_EXIT);
3147 result->fd = pip[0];
3150 popstackmark(&smark);
3151 TRACE(("evalbackcmd done: fd=%d buf=0x%x nleft=%d jp=0x%x\n",
3152 result->fd, result->buf, result->nleft, result->jp));
3157 * Execute a simple command.
3161 * Search for a command. This is called before we fork so that the
3162 * location of the command will be available in the parent as well as
3163 * the child. The check for "goodname" is an overly conservative
3164 * check that the name will not be subject to expansion.
3171 struct cmdentry entry;
3173 if (n->type == NCMD && n->ncmd.args)
3174 if (goodname(n->ncmd.args->narg.text))
3175 find_command(n->ncmd.args->narg.text, &entry, 0,
3181 * Builtin commands. Builtin commands whose functions are closely
3182 * tied to evaluation are implemented here.
3186 * No command given, or a bltin command with no arguments. Set the
3187 * specified variables.
3191 bltincmd(argc, argv)
3196 * Preserve exitstatus of a previous possible redirection
3204 * Handle break and continue commands. Break, continue, and return are
3205 * all handled by setting the evalskip flag. The evaluation routines
3206 * above all check this flag, and if it is set they start skipping
3207 * commands rather than executing them. The variable skipcount is
3208 * the number of loops to break/continue, or the number of function
3209 * levels to return. (The latter is always 1.) It should probably
3210 * be an error to break out of more loops than exist, but it isn't
3211 * in the standard shell so we don't make it one here.
3215 breakcmd(argc, argv)
3219 int n = argc > 1 ? number(argv[1]) : 1;
3224 evalskip = (**argv == 'c')? SKIPCONT : SKIPBREAK;
3232 * The return command.
3236 returncmd(argc, argv)
3240 int ret = argc > 1 ? number(argv[1]) : oexitstatus;
3243 evalskip = SKIPFUNC;
3248 /* Do what ksh does; skip the rest of the file */
3249 evalskip = SKIPFILE;
3256 #ifndef BB_TRUE_FALSE
3258 false_main(argc, argv)
3267 true_main(argc, argv)
3276 * Controls whether the shell is interactive or not.
3279 static void setsignal(int signo);
3280 static void chkmail(int silent);
3284 setinteractive(int on)
3286 static int is_interactive;
3287 static int do_banner=0;
3289 if (on == is_interactive)
3295 is_interactive = on;
3296 if (do_banner==0 && is_interactive) {
3297 /* Looks like they want an interactive shell */
3298 printf( "\n\n" BB_BANNER " Built-in shell (ash)\n");
3299 printf( "Enter 'help' for a list of built-in commands.\n\n");
3307 setinteractive(iflag);
3320 iflag = 0; /* exit on error */
3323 for (sp = cmdenviron; sp ; sp = sp->next)
3324 setvareq(sp->text, VEXPORT|VSTACK);
3325 shellexec(argv + 1, environment(), pathval(), 0);
3331 eprintlist(struct strlist *sp)
3333 for (; sp; sp = sp->next) {
3334 out2fmt(" %s",sp->text);
3339 * Exec a program. Never returns. If you change this routine, you may
3340 * have to change the find_command routine as well.
3343 static const char *pathopt; /* set by padvance */
3346 shellexec(argv, envp, path, idx)
3347 char **argv, **envp;
3354 if (strchr(argv[0], '/') != NULL) {
3355 tryexec(argv[0], argv, envp);
3359 while ((cmdname = padvance(&path, argv[0])) != NULL) {
3360 if (--idx < 0 && pathopt == NULL) {
3361 tryexec(cmdname, argv, envp);
3362 if (errno != ENOENT && errno != ENOTDIR)
3369 /* Map to POSIX errors */
3381 exerror(EXEXEC, "%s: %s", argv[0], errmsg(e, E_EXEC));
3386 * Clear traps on a fork.
3392 for (tp = trap ; tp < &trap[NSIG] ; tp++) {
3393 if (*tp && **tp) { /* trap not NULL or SIG_IGN */
3398 setsignal(tp - trap);
3406 initshellproc(void) {
3432 /* from options.c: */
3436 for (i = 0; i < NOPTS; i++)
3452 for (sm = sigmode ; sm < sigmode + NSIG - 1; sm++) {
3464 static int preadbuffer(void);
3465 static void pushfile (void);
3468 * Read a character from the script, returning PEOF on end of file.
3469 * Nul characters in the input are silently discarded.
3472 #ifndef ASH_OPTIMIZE_FOR_SIZE
3473 #define pgetc_macro() (--parsenleft >= 0? *parsenextc++ : preadbuffer())
3477 return pgetc_macro();
3483 return --parsenleft >= 0? *parsenextc++ : preadbuffer();
3489 return pgetc_macro();
3495 * Undo the last call to pgetc. Only one character may be pushed back.
3496 * PEOF may be pushed back.
3508 struct parsefile *pf = parsefile;
3517 parsefile = pf->prev;
3519 parsenleft = parsefile->nleft;
3520 parselleft = parsefile->lleft;
3521 parsenextc = parsefile->nextc;
3522 plinno = parsefile->linno;
3528 * Return to top level.
3533 while (parsefile != &basepf)
3538 * Close the file(s) that the shell is reading commands from. Called
3539 * after a fork is done.
3545 if (parsefile->fd > 0) {
3546 close(parsefile->fd);
3553 * Like setinputfile, but takes an open file descriptor. Call this with
3558 setinputfd(fd, push)
3561 (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
3567 while (parsefile->strpush)
3571 if (parsefile->buf == NULL)
3572 parsefile->buf = ckmalloc(BUFSIZ);
3573 parselleft = parsenleft = 0;
3579 * Set the input to take input from a file. If push is set, push the
3580 * old input onto the stack first.
3584 setinputfile(const char *fname, int push)
3590 if ((fd = open(fname, O_RDONLY)) < 0)
3591 error("Can't open %s", fname);
3593 myfileno2 = dup_as_newfd(fd, 10);
3596 error("Out of file descriptors");
3599 setinputfd(fd, push);
3605 tryexec(char *cmd, char **argv, char **envp)
3609 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
3613 #ifdef BB_FEATURE_SH_APPLETS_ALWAYS_WIN
3614 name = get_last_path_component(name);
3617 for(argc_l=0;*argv_l!=NULL; argv_l++, argc_l++)
3620 for(argc_l=0;*argv_l!=NULL; argv_l++, argc_l++)
3622 run_applet_by_name(name, argc_l, argv);
3624 execve(cmd, argv, envp);
3629 setinputfile(cmd, 0);
3630 commandname = arg0 = savestr(argv[0]);
3632 exraise(EXSHELLPROC);
3637 static char *commandtext (const union node *);
3640 * Do a path search. The variable path (passed by reference) should be
3641 * set to the start of the path before the first call; padvance will update
3642 * this value as it proceeds. Successive calls to padvance will return
3643 * the possible path expansions in sequence. If an option (indicated by
3644 * a percent sign) appears in the path entry then the global variable
3645 * pathopt will be set to point to it; otherwise pathopt will be set to
3649 static const char *pathopt;
3651 static void growstackblock(void);
3655 padvance(const char **path, const char *name)
3665 for (p = start ; *p && *p != ':' && *p != '%' ; p++);
3666 len = p - start + strlen(name) + 2; /* "2" is for '/' and '\0' */
3667 while (stackblocksize() < len)
3671 memcpy(q, start, p - start);
3679 while (*p && *p != ':') p++;
3685 return stalloc(len);
3689 * Wrapper around strcmp for qsort/bsearch/...
3692 pstrcmp(const void *a, const void *b)
3694 return strcmp((const char *) a, *(const char *const *) b);
3698 * Find a keyword is in a sorted array.
3701 static const char *const *
3702 findkwd(const char *s)
3704 return bsearch(s, parsekwd, sizeof(parsekwd) / sizeof(const char *),
3705 sizeof(const char *), pstrcmp);
3709 /*** Command hashing code ***/
3717 struct tblentry **pp;
3718 struct tblentry *cmdp;
3721 struct cmdentry entry;
3724 const struct alias *ap;
3728 while ((c = nextopt("rvV")) != '\0') {
3732 } else if (c == 'v' || c == 'V') {
3736 if (*argptr == NULL) {
3737 for (pp = cmdtable ; pp < &cmdtable[CMDTABLESIZE] ; pp++) {
3738 for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) {
3739 if (cmdp->cmdtype != CMDBUILTIN) {
3740 printentry(cmdp, verbose);
3747 while ((name = *argptr++) != NULL) {
3748 if ((cmdp = cmdlookup(name, 0)) != NULL
3749 && (cmdp->cmdtype == CMDNORMAL
3750 || (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0)))
3753 /* Then look at the aliases */
3754 if ((ap = lookupalias(name, 0)) != NULL) {
3756 printf("%s is an alias for %s\n", name, ap->val);
3762 /* First look at the keywords */
3763 if (findkwd(name)!=0) {
3765 printf("%s is a shell keyword\n", name);
3767 printf(snlfmt, name);
3771 find_command(name, &entry, DO_ERR, pathval());
3772 if (entry.cmdtype == CMDUNKNOWN) c = 1;
3774 cmdp = cmdlookup(name, 0);
3775 if (cmdp) printentry(cmdp, verbose=='v');
3783 printentry(cmdp, verbose)
3784 struct tblentry *cmdp;
3791 printf("%s%s", cmdp->cmdname, (verbose ? " is " : ""));
3792 if (cmdp->cmdtype == CMDNORMAL) {
3793 idx = cmdp->param.index;
3796 name = padvance(&path, cmdp->cmdname);
3798 } while (--idx >= 0);
3801 } else if (cmdp->cmdtype == CMDBUILTIN) {
3803 out1str("a shell builtin");
3804 } else if (cmdp->cmdtype == CMDFUNCTION) {
3807 out1str("a function\n");
3808 name = commandtext(cmdp->param.func);
3809 printf("%s() {\n %s\n}", cmdp->cmdname, name);
3815 error("internal error: cmdtype %d", cmdp->cmdtype);
3818 printf(snlfmt, cmdp->rehash ? "*" : nullstr);
3823 /*** List the available builtins ***/
3826 static int helpcmd(int argc, char** argv)
3830 printf("\nBuilt-in commands:\n-------------------\n");
3831 for (col=0, i=0; i < NUMBUILTINS; i++) {
3832 col += printf("%c%s", ((col == 0) ? '\t' : ' '),
3833 builtincmds[i].name+1);
3839 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
3841 extern const struct BB_applet applets[];
3842 extern const size_t NUM_APPLETS;
3844 for (i=0; i < NUM_APPLETS; i++) {
3846 col += printf("%c%s", ((col == 0) ? '\t' : ' '),
3856 return EXIT_SUCCESS;
3860 * Resolve a command name. If you change this routine, you may have to
3861 * change the shellexec routine as well.
3864 static int prefix (const char *, const char *);
3867 find_command(const char *name, struct cmdentry *entry, int act, const char *path)
3869 struct tblentry *cmdp;
3879 struct builtincmd *bcmd;
3881 /* If name contains a slash, don't use the hash table */
3882 if (strchr(name, '/') != NULL) {
3884 while (stat(name, &statb) < 0) {
3885 if (errno != ENOENT && errno != ENOTDIR)
3887 entry->cmdtype = CMDUNKNOWN;
3888 entry->u.index = -1;
3891 entry->cmdtype = CMDNORMAL;
3892 entry->u.index = -1;
3895 entry->cmdtype = CMDNORMAL;
3901 if (act & DO_BRUTE) {
3902 firstchange = path_change(path, &bltin);
3908 /* If name is in the table, and not invalidated by cd, we're done */
3909 if ((cmdp = cmdlookup(name, 0)) != NULL && cmdp->rehash == 0) {
3910 if (cmdp->cmdtype == CMDFUNCTION) {
3911 if (act & DO_NOFUN) {
3916 } else if (act & DO_BRUTE) {
3917 if ((cmdp->cmdtype == CMDNORMAL &&
3918 cmdp->param.index >= firstchange) ||
3919 (cmdp->cmdtype == CMDBUILTIN &&
3920 ((builtinloc < 0 && bltin >= 0) ?
3921 bltin : builtinloc) >= firstchange)) {
3922 /* need to recompute the entry */
3931 bcmd = find_builtin(name);
3932 regular = bcmd && IS_BUILTIN_REGULAR(bcmd);
3935 if (cmdp && (cmdp->cmdtype == CMDBUILTIN)) {
3938 } else if (act & DO_BRUTE) {
3939 if (firstchange == 0) {
3944 /* If %builtin not in path, check for builtin next */
3945 if (regular || (bltin < 0 && bcmd)) {
3948 entry->cmdtype = CMDBUILTIN;
3949 entry->u.cmd = bcmd;
3953 cmdp = cmdlookup(name, 1);
3954 cmdp->cmdtype = CMDBUILTIN;
3955 cmdp->param.cmd = bcmd;
3960 /* We have to search path. */
3961 prev = -1; /* where to start */
3962 if (cmdp && cmdp->rehash) { /* doing a rehash */
3963 if (cmdp->cmdtype == CMDBUILTIN)
3966 prev = cmdp->param.index;
3972 while ((fullname = padvance(&path, name)) != NULL) {
3973 stunalloc(fullname);
3975 if (idx >= firstchange) {
3979 if (prefix("builtin", pathopt)) {
3980 if ((bcmd = find_builtin(name))) {
3984 } else if (!(act & DO_NOFUN) &&
3985 prefix("func", pathopt)) {
3988 continue; /* ignore unimplemented options */
3991 /* if rehash, don't redo absolute path names */
3992 if (fullname[0] == '/' && idx <= prev &&
3993 idx < firstchange) {
3996 TRACE(("searchexec \"%s\": no change\n", name));
3999 while (stat(fullname, &statb) < 0) {
4000 if (errno != ENOENT && errno != ENOTDIR)
4004 e = EACCES; /* if we fail, this will be the error */
4005 if (!S_ISREG(statb.st_mode))
4007 if (pathopt) { /* this is a %func directory */
4008 stalloc(strlen(fullname) + 1);
4009 readcmdfile(fullname);
4010 if ((cmdp = cmdlookup(name, 0)) == NULL || cmdp->cmdtype != CMDFUNCTION)
4011 error("%s not defined in %s", name, fullname);
4012 stunalloc(fullname);
4015 TRACE(("searchexec \"%s\" returns \"%s\"\n", name, fullname));
4016 /* If we aren't called with DO_BRUTE and cmdp is set, it must
4017 be a function and we're being called with DO_NOFUN */
4019 entry->cmdtype = CMDNORMAL;
4020 entry->u.index = idx;
4024 cmdp = cmdlookup(name, 1);
4025 cmdp->cmdtype = CMDNORMAL;
4026 cmdp->param.index = idx;
4031 /* We failed. If there was an entry for this command, delete it */
4032 if (cmdp && updatetbl)
4035 out2fmt("%s: %s\n", name, errmsg(e, E_EXEC));
4036 entry->cmdtype = CMDUNKNOWN;
4041 entry->cmdtype = cmdp->cmdtype;
4042 entry->u = cmdp->param;
4048 * Search the table of builtin commands.
4052 bstrcmp(const void *name, const void *b)
4054 return strcmp((const char *)name, (*(const char *const *) b)+1);
4057 static struct builtincmd *
4058 find_builtin(const char *name)
4060 struct builtincmd *bp;
4062 bp = bsearch(name, builtincmds, NUMBUILTINS, sizeof(struct builtincmd),
4070 * Called when a cd is done. Marks all commands so the next time they
4071 * are executed they will be rehashed.
4076 struct tblentry **pp;
4077 struct tblentry *cmdp;
4079 for (pp = cmdtable ; pp < &cmdtable[CMDTABLESIZE] ; pp++) {
4080 for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) {
4081 if (cmdp->cmdtype == CMDNORMAL
4082 || (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0))
4091 * Called before PATH is changed. The argument is the new value of PATH;
4092 * pathval() still returns the old value at this point. Called with
4097 changepath(const char *newval)
4102 firstchange = path_change(newval, &bltin);
4103 if (builtinloc < 0 && bltin >= 0)
4104 builtinloc = bltin; /* zap builtins */
4105 clearcmdentry(firstchange);
4111 * Clear out command entries. The argument specifies the first entry in
4112 * PATH which has changed.
4116 clearcmdentry(firstchange)
4119 struct tblentry **tblp;
4120 struct tblentry **pp;
4121 struct tblentry *cmdp;
4124 for (tblp = cmdtable ; tblp < &cmdtable[CMDTABLESIZE] ; tblp++) {
4126 while ((cmdp = *pp) != NULL) {
4127 if ((cmdp->cmdtype == CMDNORMAL &&
4128 cmdp->param.index >= firstchange)
4129 || (cmdp->cmdtype == CMDBUILTIN &&
4130 builtinloc >= firstchange)) {
4143 * Delete all functions.
4148 struct tblentry **tblp;
4149 struct tblentry **pp;
4150 struct tblentry *cmdp;
4153 for (tblp = cmdtable ; tblp < &cmdtable[CMDTABLESIZE] ; tblp++) {
4155 while ((cmdp = *pp) != NULL) {
4156 if (cmdp->cmdtype == CMDFUNCTION) {
4158 freefunc(cmdp->param.func);
4171 * Locate a command in the command hash table. If "add" is nonzero,
4172 * add the command to the table if it is not already present. The
4173 * variable "lastcmdentry" is set to point to the address of the link
4174 * pointing to the entry, so that delete_cmd_entry can delete the
4178 static struct tblentry **lastcmdentry;
4180 static struct tblentry *
4181 cmdlookup(const char *name, int add)
4185 struct tblentry *cmdp;
4186 struct tblentry **pp;
4193 pp = &cmdtable[hashval % CMDTABLESIZE];
4194 for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) {
4195 if (equal(cmdp->cmdname, name))
4199 if (add && cmdp == NULL) {
4201 cmdp = *pp = ckmalloc(sizeof (struct tblentry) - ARB
4202 + strlen(name) + 1);
4204 cmdp->cmdtype = CMDUNKNOWN;
4206 strcpy(cmdp->cmdname, name);
4214 * Delete the command entry returned on the last lookup.
4218 delete_cmd_entry() {
4219 struct tblentry *cmdp;
4222 cmdp = *lastcmdentry;
4223 *lastcmdentry = cmdp->next;
4232 static const short nodesize[26] = {
4233 ALIGN(sizeof (struct nbinary)),
4234 ALIGN(sizeof (struct ncmd)),
4235 ALIGN(sizeof (struct npipe)),
4236 ALIGN(sizeof (struct nredir)),
4237 ALIGN(sizeof (struct nredir)),
4238 ALIGN(sizeof (struct nredir)),
4239 ALIGN(sizeof (struct nbinary)),
4240 ALIGN(sizeof (struct nbinary)),
4241 ALIGN(sizeof (struct nif)),
4242 ALIGN(sizeof (struct nbinary)),
4243 ALIGN(sizeof (struct nbinary)),
4244 ALIGN(sizeof (struct nfor)),
4245 ALIGN(sizeof (struct ncase)),
4246 ALIGN(sizeof (struct nclist)),
4247 ALIGN(sizeof (struct narg)),
4248 ALIGN(sizeof (struct narg)),
4249 ALIGN(sizeof (struct nfile)),
4250 ALIGN(sizeof (struct nfile)),
4251 ALIGN(sizeof (struct nfile)),
4252 ALIGN(sizeof (struct nfile)),
4253 ALIGN(sizeof (struct nfile)),
4254 ALIGN(sizeof (struct ndup)),
4255 ALIGN(sizeof (struct ndup)),
4256 ALIGN(sizeof (struct nhere)),
4257 ALIGN(sizeof (struct nhere)),
4258 ALIGN(sizeof (struct nnot)),
4264 * Delete a function if it exists.
4268 unsetfunc(char *name)
4270 struct tblentry *cmdp;
4272 if ((cmdp = cmdlookup(name, 0)) != NULL && cmdp->cmdtype == CMDFUNCTION) {
4273 freefunc(cmdp->param.func);
4280 * Locate and print what a word is...
4284 typecmd(int argc, char **argv)
4292 for (i = 1; i < argc; i++) {
4293 argv_a[0] = argv[i];
4296 err |= hashcmd(argc, argv);
4303 commandcmd(argc, argv)
4308 int default_path = 0;
4309 int verify_only = 0;
4310 int verbose_verify_only = 0;
4312 while ((c = nextopt("pvV")) != '\0')
4321 verbose_verify_only = 1;
4325 if (default_path + verify_only + verbose_verify_only > 1 ||
4328 "command [-p] command [arg ...]\n"
4329 "command {-v|-V} command\n");
4333 if (verify_only || verbose_verify_only) {
4337 argv_a[0] = *argptr;
4339 optptr = verbose_verify_only ? "v" : "V"; /* reverse special */
4340 return hashcmd(argc, argv);
4348 path_change(newval, bltin)
4352 const char *old, *new;
4358 firstchange = 9999; /* assume no change */
4364 if ((*old == '\0' && *new == ':')
4365 || (*old == ':' && *new == '\0'))
4367 old = new; /* ignore subsequent differences */
4371 if (*new == '%' && *bltin < 0 && prefix("builtin", new + 1))
4378 if (builtinloc >= 0 && *bltin < 0)
4383 * Routines to expand arguments to commands. We have to deal with
4384 * backquotes, shell variables, and file metacharacters.
4389 #define RMESCAPE_ALLOC 0x1 /* Allocate a new string */
4390 #define RMESCAPE_GLOB 0x2 /* Add backslashes for glob */
4393 * Structure specifying which parts of the string should be searched
4394 * for IFS characters.
4398 struct ifsregion *next; /* next region in list */
4399 int begoff; /* offset of start of region */
4400 int endoff; /* offset of end of region */
4401 int nulonly; /* search for nul bytes only */
4405 static char *expdest; /* output of current string */
4406 static struct nodelist *argbackq; /* list of back quote expressions */
4407 static struct ifsregion ifsfirst; /* first struct in list of ifs regions */
4408 static struct ifsregion *ifslastp; /* last struct in list */
4409 static struct arglist exparg; /* holds expanded arg list */
4411 static void argstr (char *, int);
4412 static char *exptilde (char *, int);
4413 static void expbackq (union node *, int, int);
4414 static int subevalvar (char *, char *, int, int, int, int, int);
4415 static int varisset (char *, int);
4416 static void strtodest (const char *, const char *, int);
4417 static void varvalue (char *, int, int);
4418 static void recordregion (int, int, int);
4419 static void removerecordregions (int);
4420 static void ifsbreakup (char *, struct arglist *);
4421 static void ifsfree (void);
4422 static void expandmeta (struct strlist *, int);
4423 #if defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN)
4424 #define preglob(p) _rmescapes((p), RMESCAPE_ALLOC | RMESCAPE_GLOB)
4425 #if !defined(GLOB_BROKEN)
4426 static void addglob (const glob_t *);
4429 #if !(defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN))
4430 static void expmeta (char *, char *);
4432 #if !(defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN))
4433 static struct strlist *expsort (struct strlist *);
4434 static struct strlist *msort (struct strlist *, int);
4436 static int patmatch (char *, char *, int);
4437 #if defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN)
4438 static int patmatch2 (char *, char *, int);
4440 static int pmatch (char *, char *, int);
4441 #define patmatch2 patmatch
4443 static char *cvtnum (int, char *);
4446 * Expand shell variables and backquotes inside a here document.
4449 /* arg: the document, fd: where to write the expanded version */
4451 expandhere(union node *arg, int fd)
4454 expandarg(arg, (struct arglist *)NULL, 0);
4455 xwrite(fd, stackblock(), expdest - stackblock());
4460 * Perform variable substitution and command substitution on an argument,
4461 * placing the resulting list of arguments in arglist. If EXP_FULL is true,
4462 * perform splitting and file name expansion. When arglist is NULL, perform
4463 * here document expansion.
4467 expandarg(arg, arglist, flag)
4469 struct arglist *arglist;
4475 argbackq = arg->narg.backquote;
4476 STARTSTACKSTR(expdest);
4477 ifsfirst.next = NULL;
4479 argstr(arg->narg.text, flag);
4480 if (arglist == NULL) {
4481 return; /* here document expanded */
4483 STPUTC('\0', expdest);
4484 p = grabstackstr(expdest);
4485 exparg.lastp = &exparg.list;
4489 if (flag & EXP_FULL) {
4490 ifsbreakup(p, &exparg);
4491 *exparg.lastp = NULL;
4492 exparg.lastp = &exparg.list;
4493 expandmeta(exparg.list, flag);
4495 if (flag & EXP_REDIR) /*XXX - for now, just remove escapes */
4497 sp = (struct strlist *)stalloc(sizeof (struct strlist));
4500 exparg.lastp = &sp->next;
4503 *exparg.lastp = NULL;
4505 *arglist->lastp = exparg.list;
4506 arglist->lastp = exparg.lastp;
4512 * Expand a variable, and return a pointer to the next character in the
4516 static inline char *
4532 int quotes = flag & (EXP_FULL | EXP_CASE);
4535 subtype = varflags & VSTYPE;
4540 p = strchr(p, '=') + 1;
4541 again: /* jump here after setting a variable with ${var=text} */
4543 set = varisset(var, varflags & VSNUL);
4546 val = lookupvar(var);
4547 if (val == NULL || ((varflags & VSNUL) && val[0] == '\0')) {
4554 startloc = expdest - stackblock();
4555 if (set && subtype != VSPLUS) {
4556 /* insert the value of the variable */
4558 varvalue(var, varflags & VSQUOTE, flag);
4559 if (subtype == VSLENGTH) {
4560 varlen = expdest - stackblock() - startloc;
4561 STADJUST(-varlen, expdest);
4564 if (subtype == VSLENGTH) {
4565 varlen = strlen(val);
4569 varflags & VSQUOTE ?
4570 DQSYNTAX : BASESYNTAX,
4577 if (subtype == VSPLUS)
4580 easy = ((varflags & VSQUOTE) == 0 ||
4581 (*var == '@' && shellparam.nparam != 1));
4586 expdest = cvtnum(varlen, expdest);
4593 recordregion(startloc, expdest - stackblock(),
4594 varflags & VSQUOTE);
4610 case VSTRIMRIGHTMAX:
4614 * Terminate the string and start recording the pattern
4617 STPUTC('\0', expdest);
4618 patloc = expdest - stackblock();
4619 if (subevalvar(p, NULL, patloc, subtype,
4620 startloc, varflags, quotes) == 0) {
4621 int amount = (expdest - stackblock() - patloc) + 1;
4622 STADJUST(-amount, expdest);
4624 /* Remove any recorded regions beyond start of variable */
4625 removerecordregions(startloc);
4631 if (subevalvar(p, var, 0, subtype, startloc,
4632 varflags, quotes)) {
4635 * Remove any recorded regions beyond
4638 removerecordregions(startloc);
4653 if (subtype != VSNORMAL) { /* skip to end of alternative */
4656 if ((c = *p++) == CTLESC)
4658 else if (c == CTLBACKQ || c == (CTLBACKQ|CTLQUOTE)) {
4660 argbackq = argbackq->next;
4661 } else if (c == CTLVAR) {
4662 if ((*p++ & VSTYPE) != VSNORMAL)
4664 } else if (c == CTLENDVAR) {
4675 * Perform variable and command substitution. If EXP_FULL is set, output CTLESC
4676 * characters to allow for further processing. Otherwise treat
4677 * $@ like $* since no splitting will be performed.
4686 int quotes = flag & (EXP_FULL | EXP_CASE); /* do CTLESC */
4689 if (*p == '~' && (flag & (EXP_TILDE | EXP_VARTILDE)))
4690 p = exptilde(p, flag);
4694 case CTLENDVAR: /* ??? */
4697 /* "$@" syntax adherence hack */
4698 if (p[0] == CTLVAR && p[2] == '@' && p[3] == '=')
4700 if ((flag & EXP_FULL) != 0)
4710 p = evalvar(p, flag);
4713 case CTLBACKQ|CTLQUOTE:
4714 expbackq(argbackq->n, c & CTLQUOTE, flag);
4715 argbackq = argbackq->next;
4717 #ifdef ASH_MATH_SUPPORT
4725 * sort of a hack - expand tildes in variable
4726 * assignments (after the first '=' and after ':'s).
4729 if (flag & EXP_VARTILDE && *p == '~') {
4736 p = exptilde(p, flag);
4752 char c, *startp = p;
4755 int quotes = flag & (EXP_FULL | EXP_CASE);
4757 while ((c = *p) != '\0') {
4764 if (flag & EXP_VARTILDE)
4774 if (*(startp+1) == '\0') {
4775 if ((home = lookupvar("HOME")) == NULL)
4778 if ((pw = getpwnam(startp+1)) == NULL)
4785 strtodest(home, SQSYNTAX, quotes);
4794 removerecordregions(int endoff)
4796 if (ifslastp == NULL)
4799 if (ifsfirst.endoff > endoff) {
4800 while (ifsfirst.next != NULL) {
4801 struct ifsregion *ifsp;
4803 ifsp = ifsfirst.next->next;
4804 ckfree(ifsfirst.next);
4805 ifsfirst.next = ifsp;
4808 if (ifsfirst.begoff > endoff)
4811 ifslastp = &ifsfirst;
4812 ifsfirst.endoff = endoff;
4817 ifslastp = &ifsfirst;
4818 while (ifslastp->next && ifslastp->next->begoff < endoff)
4819 ifslastp=ifslastp->next;
4820 while (ifslastp->next != NULL) {
4821 struct ifsregion *ifsp;
4823 ifsp = ifslastp->next->next;
4824 ckfree(ifslastp->next);
4825 ifslastp->next = ifsp;
4828 if (ifslastp->endoff > endoff)
4829 ifslastp->endoff = endoff;
4833 #ifdef ASH_MATH_SUPPORT
4835 * Expand arithmetic expression. Backup to start of expression,
4836 * evaluate, place result in (backed up) result, adjust string position.
4844 int quotes = flag & (EXP_FULL | EXP_CASE);
4850 * This routine is slightly over-complicated for
4851 * efficiency. First we make sure there is
4852 * enough space for the result, which may be bigger
4853 * than the expression if we add exponentation. Next we
4854 * scan backwards looking for the start of arithmetic. If the
4855 * next previous character is a CTLESC character, then we
4856 * have to rescan starting from the beginning since CTLESC
4857 * characters have to be processed left to right.
4859 CHECKSTRSPACE(10, expdest);
4860 USTPUTC('\0', expdest);
4861 start = stackblock();
4863 while (*p != CTLARI && p >= start)
4866 error("missing CTLARI (shouldn't happen)");
4867 if (p > start && *(p-1) == CTLESC)
4868 for (p = start; *p != CTLARI; p++)
4877 removerecordregions(begoff);
4880 result = arith(p+2);
4882 error("arith: syntax error: \"%s\"\n", p+2);
4883 snprintf(p, 12, "%d", result);
4889 recordregion(begoff, p - 1 - start, 0);
4890 result = expdest - p + 1;
4891 STADJUST(-result, expdest);
4896 * Expand stuff in backwards quotes.
4900 expbackq(cmd, quoted, flag)
4905 volatile struct backcmd in;
4909 char *dest = expdest;
4910 volatile struct ifsregion saveifs;
4911 struct ifsregion *volatile savelastp;
4912 struct nodelist *volatile saveargbackq;
4914 int startloc = dest - stackblock();
4915 char const *syntax = quoted? DQSYNTAX : BASESYNTAX;
4916 volatile int saveherefd;
4917 int quotes = flag & (EXP_FULL | EXP_CASE);
4918 struct jmploc jmploc;
4919 struct jmploc *volatile savehandler;
4923 /* Avoid longjmp clobbering */
4934 savelastp = ifslastp;
4935 saveargbackq = argbackq;
4936 saveherefd = herefd;
4938 if ((ex = setjmp(jmploc.loc))) {
4941 savehandler = handler;
4944 p = grabstackstr(dest);
4945 evalbackcmd(cmd, (struct backcmd *) &in);
4946 ungrabstackstr(p, dest);
4950 ifslastp = savelastp;
4951 argbackq = saveargbackq;
4952 herefd = saveherefd;
4960 if (--in.nleft < 0) {
4963 i = safe_read(in.fd, buf, sizeof buf);
4964 TRACE(("expbackq: read returns %d\n", i));
4971 if (lastc != '\0') {
4972 if (quotes && syntax[(int)lastc] == CCTL)
4973 STPUTC(CTLESC, dest);
4974 STPUTC(lastc, dest);
4978 /* Eat all trailing newlines */
4979 for (; dest > stackblock() && dest[-1] == '\n';)
4988 exitstatus = waitforjob(in.jp);
4989 handler = savehandler;
4991 longjmp(handler->loc, 1);
4994 recordregion(startloc, dest - stackblock(), 0);
4995 TRACE(("evalbackq: size=%d: \"%.*s\"\n",
4996 (dest - stackblock()) - startloc,
4997 (dest - stackblock()) - startloc,
4998 stackblock() + startloc));
5004 subevalvar(p, str, strloc, subtype, startloc, varflags, quotes)
5017 int saveherefd = herefd;
5018 struct nodelist *saveargbackq = argbackq;
5022 argstr(p, subtype != VSASSIGN && subtype != VSQUESTION ? EXP_CASE : 0);
5023 STACKSTRNUL(expdest);
5024 herefd = saveherefd;
5025 argbackq = saveargbackq;
5026 startp = stackblock() + startloc;
5028 str = stackblock() + strloc;
5032 setvar(str, startp, 0);
5033 amount = startp - expdest;
5034 STADJUST(amount, expdest);
5041 if (*p != CTLENDVAR) {
5042 out2fmt(snlfmt, startp);
5043 error((char *)NULL);
5045 error("%.*s: parameter %snot set", p - str - 1,
5046 str, (varflags & VSNUL) ? "null or "
5051 for (loc = startp; loc < str; loc++) {
5054 if (patmatch2(str, startp, quotes))
5057 if (quotes && *loc == CTLESC)
5063 for (loc = str - 1; loc >= startp;) {
5066 if (patmatch2(str, startp, quotes))
5070 if (quotes && loc > startp && *(loc - 1) == CTLESC) {
5071 for (q = startp; q < loc; q++)
5081 for (loc = str - 1; loc >= startp;) {
5082 if (patmatch2(str, loc, quotes))
5085 if (quotes && loc > startp && *(loc - 1) == CTLESC) {
5086 for (q = startp; q < loc; q++)
5095 case VSTRIMRIGHTMAX:
5096 for (loc = startp; loc < str - 1; loc++) {
5097 if (patmatch2(str, loc, quotes))
5099 if (quotes && *loc == CTLESC)
5112 amount = ((str - 1) - (loc - startp)) - expdest;
5113 STADJUST(amount, expdest);
5114 while (loc != str - 1)
5119 amount = loc - expdest;
5120 STADJUST(amount, expdest);
5121 STPUTC('\0', expdest);
5122 STADJUST(-1, expdest);
5128 * Test whether a specialized variable is set.
5132 varisset(name, nulok)
5137 return backgndpid != -1;
5138 else if (*name == '@' || *name == '*') {
5139 if (*shellparam.p == NULL)
5145 for (av = shellparam.p; *av; av++)
5150 } else if (is_digit(*name)) {
5152 int num = atoi(name);
5154 if (num > shellparam.nparam)
5160 ap = shellparam.p[num - 1];
5162 if (nulok && (ap == NULL || *ap == '\0'))
5169 * Put a string on the stack.
5173 strtodest(p, syntax, quotes)
5179 if (quotes && syntax[(int) *p] == CCTL)
5180 STPUTC(CTLESC, expdest);
5181 STPUTC(*p++, expdest);
5186 * Add the value of a specialized variable to the stack string.
5190 varvalue(name, quoted, flags)
5202 int allow_split = flags & EXP_FULL;
5203 int quotes = flags & (EXP_FULL | EXP_CASE);
5205 syntax = quoted ? DQSYNTAX : BASESYNTAX;
5214 num = shellparam.nparam;
5219 expdest = cvtnum(num, expdest);
5222 for (i = 0 ; i < NOPTS ; i++) {
5224 STPUTC(optent_letter(optlist[i]), expdest);
5228 if (allow_split && quoted) {
5229 sep = 1 << CHAR_BIT;
5234 sep = ifsset() ? ifsval()[0] : ' ';
5236 sepq = syntax[(int) sep] == CCTL;
5239 for (ap = shellparam.p ; (p = *ap++) != NULL ; ) {
5240 strtodest(p, syntax, quotes);
5243 STPUTC(CTLESC, expdest);
5244 STPUTC(sep, expdest);
5249 strtodest(arg0, syntax, quotes);
5253 if (num > 0 && num <= shellparam.nparam) {
5254 strtodest(shellparam.p[num - 1], syntax, quotes);
5262 * Record the fact that we have to scan this region of the
5263 * string for IFS characters.
5267 recordregion(start, end, nulonly)
5272 struct ifsregion *ifsp;
5274 if (ifslastp == NULL) {
5278 ifsp = (struct ifsregion *)ckmalloc(sizeof (struct ifsregion));
5280 ifslastp->next = ifsp;
5284 ifslastp->begoff = start;
5285 ifslastp->endoff = end;
5286 ifslastp->nulonly = nulonly;
5292 * Break the argument string into pieces based upon IFS and add the
5293 * strings to the argument list. The regions of the string to be
5294 * searched for IFS characters have been stored by recordregion.
5297 ifsbreakup(string, arglist)
5299 struct arglist *arglist;
5301 struct ifsregion *ifsp;
5306 const char *ifs, *realifs;
5314 realifs = ifsset() ? ifsval() : defifs;
5315 if (ifslastp != NULL) {
5318 p = string + ifsp->begoff;
5319 nulonly = ifsp->nulonly;
5320 ifs = nulonly ? nullstr : realifs;
5322 while (p < string + ifsp->endoff) {
5326 if (strchr(ifs, *p)) {
5328 ifsspc = (strchr(defifs, *p) != NULL);
5329 /* Ignore IFS whitespace at start */
5330 if (q == start && ifsspc) {
5336 sp = (struct strlist *)stalloc(sizeof *sp);
5338 *arglist->lastp = sp;
5339 arglist->lastp = &sp->next;
5343 if (p >= string + ifsp->endoff) {
5349 if (strchr(ifs, *p) == NULL ) {
5352 } else if (strchr(defifs, *p) == NULL) {
5368 } while ((ifsp = ifsp->next) != NULL);
5369 if (!(*start || (!ifsspc && start > string && nulonly))) {
5374 sp = (struct strlist *)stalloc(sizeof *sp);
5376 *arglist->lastp = sp;
5377 arglist->lastp = &sp->next;
5383 while (ifsfirst.next != NULL) {
5384 struct ifsregion *ifsp;
5386 ifsp = ifsfirst.next->next;
5387 ckfree(ifsfirst.next);
5388 ifsfirst.next = ifsp;
5392 ifsfirst.next = NULL;
5396 * Add a file name to the list.
5400 addfname(const char *name)
5406 sp = (struct strlist *)stalloc(sizeof *sp);
5409 exparg.lastp = &sp->next;
5413 * Expand shell metacharacters. At this point, the only control characters
5414 * should be escapes. The results are stored in the list exparg.
5417 #if defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN)
5419 expandmeta(str, flag)
5420 struct strlist *str;
5425 /* TODO - EXP_REDIR */
5430 p = preglob(str->text);
5432 switch (glob(p, GLOB_NOMAGIC, 0, &pglob)) {
5434 if (!(pglob.gl_flags & GLOB_MAGCHAR))
5445 *exparg.lastp = str;
5446 rmescapes(str->text);
5447 exparg.lastp = &str->next;
5449 default: /* GLOB_NOSPACE */
5450 error("Out of space");
5458 * Add the result of glob(3) to the list.
5463 const glob_t *pglob;
5465 char **p = pglob->gl_pathv;
5473 #else /* defined(__GLIBC__) && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN) */
5474 static char *expdir;
5478 expandmeta(str, flag)
5479 struct strlist *str;
5483 struct strlist **savelastp;
5486 /* TODO - EXP_REDIR */
5492 for (;;) { /* fast check for meta chars */
5493 if ((c = *p++) == '\0')
5495 if (c == '*' || c == '?' || c == '[' || c == '!')
5498 savelastp = exparg.lastp;
5500 if (expdir == NULL) {
5501 int i = strlen(str->text);
5502 expdir = ckmalloc(i < 2048 ? 2048 : i); /* XXX */
5505 expmeta(expdir, str->text);
5509 if (exparg.lastp == savelastp) {
5514 *exparg.lastp = str;
5515 rmescapes(str->text);
5516 exparg.lastp = &str->next;
5518 *exparg.lastp = NULL;
5519 *savelastp = sp = expsort(*savelastp);
5520 while (sp->next != NULL)
5522 exparg.lastp = &sp->next;
5530 * Do metacharacter (i.e. *, ?, [...]) expansion.
5534 expmeta(enddir, name)
5552 for (p = name ; ; p++) {
5553 if (*p == '*' || *p == '?')
5555 else if (*p == '[') {
5560 while (*q == CTLQUOTEMARK)
5564 if (*q == '/' || *q == '\0')
5571 } else if (*p == '!' && p[1] == '!' && (p == name || p[-1] == '/')) {
5573 } else if (*p == '\0')
5575 else if (*p == CTLQUOTEMARK)
5577 else if (*p == CTLESC)
5585 if (metaflag == 0) { /* we've reached the end of the file name */
5586 if (enddir != expdir)
5588 for (p = name ; ; p++) {
5589 if (*p == CTLQUOTEMARK)
5597 if (metaflag == 0 || lstat(expdir, &statb) >= 0)
5602 if (start != name) {
5605 while (*p == CTLQUOTEMARK)
5612 if (enddir == expdir) {
5614 } else if (enddir == expdir + 1 && *expdir == '/') {
5620 if ((dirp = opendir(cp)) == NULL)
5622 if (enddir != expdir)
5624 if (*endname == 0) {
5632 while (*p == CTLQUOTEMARK)
5638 while (! int_pending() && (dp = readdir(dirp)) != NULL) {
5639 if (dp->d_name[0] == '.' && ! matchdot)
5641 if (patmatch(start, dp->d_name, 0)) {
5643 strcpy(enddir, dp->d_name);
5646 for (p = enddir, cp = dp->d_name;
5647 (*p++ = *cp++) != '\0';)
5650 expmeta(p, endname);
5658 #endif /* defined(__GLIBC__) && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN) */
5662 #if !(defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN))
5664 * Sort the results of file name expansion. It calculates the number of
5665 * strings to sort and then calls msort (short for merge sort) to do the
5669 static struct strlist *
5671 struct strlist *str;
5677 for (sp = str ; sp ; sp = sp->next)
5679 return msort(str, len);
5683 static struct strlist *
5685 struct strlist *list;
5688 struct strlist *p, *q = NULL;
5689 struct strlist **lpp;
5697 for (n = half ; --n >= 0 ; ) {
5701 q->next = NULL; /* terminate first half of list */
5702 q = msort(list, half); /* sort first half of list */
5703 p = msort(p, len - half); /* sort second half */
5706 if (strcmp(p->text, q->text) < 0) {
5709 if ((p = *lpp) == NULL) {
5716 if ((q = *lpp) == NULL) {
5729 * Returns true if the pattern matches the string.
5732 #if defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN)
5733 /* squoted: string might have quote chars */
5735 patmatch(char *pattern, char *string, int squoted)
5740 p = preglob(pattern);
5741 q = squoted ? _rmescapes(string, RMESCAPE_ALLOC) : string;
5743 return !fnmatch(p, q, 0);
5748 patmatch2(char *pattern, char *string, int squoted)
5754 p = grabstackstr(expdest);
5755 res = patmatch(pattern, string, squoted);
5756 ungrabstackstr(p, expdest);
5761 patmatch(char *pattern, char *string, int squoted) {
5762 return pmatch(pattern, string, squoted);
5767 pmatch(char *pattern, char *string, int squoted)
5779 if (squoted && *q == CTLESC)
5787 if (squoted && *q == CTLESC)
5794 while (c == CTLQUOTEMARK || c == '*')
5796 if (c != CTLESC && c != CTLQUOTEMARK &&
5797 c != '?' && c != '*' && c != '[') {
5799 if (squoted && *q == CTLESC &&
5804 if (squoted && *q == CTLESC)
5810 if (pmatch(p, q, squoted))
5812 if (squoted && *q == CTLESC)
5814 } while (*q++ != '\0');
5825 while (*endp == CTLQUOTEMARK)
5828 goto dft; /* no matching ] */
5829 if (*endp == CTLESC)
5841 if (squoted && chr == CTLESC)
5847 if (c == CTLQUOTEMARK)
5851 if (*p == '-' && p[1] != ']') {
5853 while (*p == CTLQUOTEMARK)
5857 if (chr >= c && chr <= *p)
5864 } while ((c = *p++) != ']');
5865 if (found == invert)
5870 if (squoted && *q == CTLESC)
5887 * Remove any CTLESC characters from a string.
5890 #if defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN)
5892 _rmescapes(char *str, int flag)
5895 static const char qchars[] = { CTLESC, CTLQUOTEMARK, 0 };
5897 p = strpbrk(str, qchars);
5903 if (flag & RMESCAPE_ALLOC) {
5904 size_t len = p - str;
5905 q = r = stalloc(strlen(p) + len + 1);
5907 memcpy(q, str, len);
5912 if (*p == CTLQUOTEMARK) {
5918 if (flag & RMESCAPE_GLOB && *p != '/') {
5935 while (*p != CTLESC && *p != CTLQUOTEMARK) {
5941 if (*p == CTLQUOTEMARK) {
5956 * See if a pattern matches in a case statement.
5960 casematch(union node *pattern, const char *val)
5962 struct stackmark smark;
5966 setstackmark(&smark);
5967 argbackq = pattern->narg.backquote;
5968 STARTSTACKSTR(expdest);
5970 argstr(pattern->narg.text, EXP_TILDE | EXP_CASE);
5971 STPUTC('\0', expdest);
5972 p = grabstackstr(expdest);
5973 result = patmatch(p, (char *)val, 0);
5974 popstackmark(&smark);
5989 CHECKSTRSPACE(32, buf);
5990 len = sprintf(buf, "%d", num);
5995 * Editline and history functions (and glue).
5997 static int histcmd(argc, argv)
6001 error("not compiled with history support");
6007 struct redirtab *next;
6008 short renamed[10]; /* Current ash support only 0-9 descriptors */
6009 /* char renamed[10]; */ /* char on arm (and others) can't be negative */
6012 static struct redirtab *redirlist;
6014 extern char **environ;
6019 * Initialization code.
6032 basepf.nextc = basepf.buf = basebuf;
6041 for (envp = environ ; *envp ; envp++) {
6042 if (strchr(*envp, '=')) {
6043 setvareq(*envp, VEXPORT|VTEXTFIXED);
6047 snprintf(ppid, sizeof(ppid), "%d", (int) getppid());
6048 setvar("PPID", ppid, 0);
6055 * This routine is called when an error or an interrupt occurs in an
6056 * interactive shell and control is returned to the main command loop.
6059 /* 1 == check for aliases, 2 == also check for assignments */
6060 static int checkalias; /* also used in no alias mode for check assignments */
6074 if (exception != EXSHELLPROC)
6075 parselleft = parsenleft = 0; /* clear input buffer */
6079 /* from parser.c: */
6097 * This file implements the input routines used by the parser.
6100 #ifdef BB_FEATURE_COMMAND_EDITING
6101 static const char * cmdedit_prompt;
6102 static inline void putprompt(const char *s) {
6106 static inline void putprompt(const char *s) {
6111 #define EOF_NLEFT -99 /* value of parsenleft when EOF pushed back */
6116 * Same as pgetc(), but ignores PEOA.
6126 } while (c == PEOA);
6130 static inline int pgetc2() { return pgetc_macro(); }
6134 * Read a line from the script.
6137 static inline char *
6138 pfgets(char *line, int len)
6144 while (--nleft > 0) {
6163 char *buf = parsefile->buf;
6167 #ifdef BB_FEATURE_COMMAND_EDITING
6170 nr = safe_read(parsefile->fd, buf, BUFSIZ - 1);
6172 nr = cmdedit_read_input((char*)cmdedit_prompt, buf);
6176 nr = safe_read(parsefile->fd, buf, BUFSIZ - 1);
6180 if (parsefile->fd == 0 && errno == EWOULDBLOCK) {
6181 int flags = fcntl(0, F_GETFL, 0);
6182 if (flags >= 0 && flags & O_NONBLOCK) {
6183 flags &=~ O_NONBLOCK;
6184 if (fcntl(0, F_SETFL, flags) >= 0) {
6185 out2str("sh: turning off NDELAY mode\n");
6197 struct strpush *sp = parsefile->strpush;
6202 if (parsenextc[-1] == ' ' || parsenextc[-1] == '\t') {
6207 if (sp->string != sp->ap->val) {
6211 sp->ap->flag &= ~ALIASINUSE;
6212 if (sp->ap->flag & ALIASDEAD) {
6213 unalias(sp->ap->name);
6217 parsenextc = sp->prevstring;
6218 parsenleft = sp->prevnleft;
6219 /*dprintf("*** calling popstring: restoring to '%s'\n", parsenextc);*/
6220 parsefile->strpush = sp->prev;
6221 if (sp != &(parsefile->basestrpush))
6228 * Refill the input buffer and return the next input character:
6230 * 1) If a string was pushed back on the input, pop it;
6231 * 2) If an EOF was pushed back (parsenleft == EOF_NLEFT) or we are reading
6232 * from a string so we can't refill the buffer, return EOF.
6233 * 3) If the is more stuff in this buffer, use it else call read to fill it.
6234 * 4) Process input up to the next newline, deleting nul characters.
6244 while (parsefile->strpush) {
6246 if (parsenleft == -1 && parsefile->strpush->ap &&
6247 parsenextc[-1] != ' ' && parsenextc[-1] != '\t') {
6252 if (--parsenleft >= 0)
6253 return (*parsenextc++);
6255 if (parsenleft == EOF_NLEFT || parsefile->buf == NULL)
6260 if (parselleft <= 0) {
6261 if ((parselleft = preadfd()) <= 0) {
6262 parselleft = parsenleft = EOF_NLEFT;
6269 /* delete nul characters */
6270 for (more = 1; more;) {
6278 parsenleft = q - parsenextc;
6279 more = 0; /* Stop processing here */
6285 if (--parselleft <= 0 && more) {
6286 parsenleft = q - parsenextc - 1;
6297 out2str(parsenextc);
6302 return *parsenextc++;
6307 * Push a string back onto the input at this current parsefile level.
6308 * We handle aliases this way.
6311 pushstring(char *s, int len, void *ap)
6316 /*dprintf("*** calling pushstring: %s, %d\n", s, len);*/
6317 if (parsefile->strpush) {
6318 sp = ckmalloc(sizeof (struct strpush));
6319 sp->prev = parsefile->strpush;
6320 parsefile->strpush = sp;
6322 sp = parsefile->strpush = &(parsefile->basestrpush);
6323 sp->prevstring = parsenextc;
6324 sp->prevnleft = parsenleft;
6326 sp->ap = (struct alias *)ap;
6328 ((struct alias *)ap)->flag |= ALIASINUSE;
6339 * Like setinputfile, but takes input from a string.
6343 setinputstring(char *string)
6347 parsenextc = string;
6348 parsenleft = strlen(string);
6349 parsefile->buf = NULL;
6357 * To handle the "." command, a stack of input files is used. Pushfile
6358 * adds a new entry to the stack and popfile restores the previous level.
6363 struct parsefile *pf;
6365 parsefile->nleft = parsenleft;
6366 parsefile->lleft = parselleft;
6367 parsefile->nextc = parsenextc;
6368 parsefile->linno = plinno;
6369 pf = (struct parsefile *)ckmalloc(sizeof (struct parsefile));
6370 pf->prev = parsefile;
6373 pf->basestrpush.prev = NULL;
6378 static void restartjob (struct job *);
6380 static void freejob (struct job *);
6381 static struct job *getjob (const char *);
6382 static int dowait (int, struct job *);
6383 static void waitonint(int);
6387 * We keep track of whether or not fd0 has been redirected. This is for
6388 * background commands, where we want to redirect fd0 to /dev/null only
6389 * if it hasn't already been redirected.
6391 static int fd0_redirected = 0;
6393 /* Return true if fd 0 has already been redirected at least once. */
6395 fd0_redirected_p () {
6396 return fd0_redirected != 0;
6399 static void dupredirect (const union node *, int, int fd1dup);
6403 * Turn job control on and off.
6405 * Note: This code assumes that the third arg to ioctl is a character
6406 * pointer, which is true on Berkeley systems but not System V. Since
6407 * System V doesn't have job control yet, this isn't a problem now.
6412 static void setjobctl(int enable)
6414 #ifdef OLD_TTY_DRIVER
6418 if (enable == jobctl || rootshell == 0)
6421 do { /* while we are in the background */
6422 #ifdef OLD_TTY_DRIVER
6423 if (ioctl(2, TIOCGPGRP, (char *)&initialpgrp) < 0) {
6425 initialpgrp = tcgetpgrp(2);
6426 if (initialpgrp < 0) {
6428 out2str("sh: can't access tty; job control turned off\n");
6432 if (initialpgrp == -1)
6433 initialpgrp = getpgrp();
6434 else if (initialpgrp != getpgrp()) {
6435 killpg(initialpgrp, SIGTTIN);
6439 #ifdef OLD_TTY_DRIVER
6440 if (ioctl(2, TIOCGETD, (char *)&ldisc) < 0 || ldisc != NTTYDISC) {
6441 out2str("sh: need new tty driver to run job control; job control turned off\n");
6449 setpgid(0, rootpid);
6450 #ifdef OLD_TTY_DRIVER
6451 ioctl(2, TIOCSPGRP, (char *)&rootpid);
6453 tcsetpgrp(2, rootpid);
6455 } else { /* turning job control off */
6456 setpgid(0, initialpgrp);
6457 #ifdef OLD_TTY_DRIVER
6458 ioctl(2, TIOCSPGRP, (char *)&initialpgrp);
6460 tcsetpgrp(2, initialpgrp);
6471 /* A translation list so we can be polite to our users. */
6472 static char *signal_names[NSIG + 2] = {
6560 "Usage: kill [-s sigspec | -signum | -sigspec] [pid | job]... or\n"
6561 "kill -l [exitstatus]"
6565 if (*argv[1] == '-') {
6566 signo = decode_signal(argv[1] + 1, 1);
6570 while ((c = nextopt("ls:")) != '\0')
6576 signo = decode_signal(optionarg, 1);
6579 "invalid signal number or name: %s",
6587 "nextopt returned character code 0%o", c);
6594 if (!list && signo < 0)
6597 if ((signo < 0 || !*argptr) ^ list) {
6604 for (i = 1; i < NSIG; i++) {
6605 printf(snlfmt, signal_names[i] + 3);
6609 signo = atoi(*argptr);
6612 if (0 < signo && signo < NSIG)
6613 printf(snlfmt, signal_names[signo] + 3);
6615 error("invalid signal number or exit status: %s",
6621 if (**argptr == '%') {
6622 jp = getjob(*argptr);
6623 if (jp->jobctl == 0)
6624 error("job %s not created under job control",
6626 pid = -jp->ps[0].pid;
6628 pid = atoi(*argptr);
6629 if (kill(pid, signo) != 0)
6630 error("%s: %m", *argptr);
6631 } while (*++argptr);
6645 jp = getjob(argv[1]);
6646 if (jp->jobctl == 0)
6647 error("job not created under job control");
6648 pgrp = jp->ps[0].pid;
6649 #ifdef OLD_TTY_DRIVER
6650 ioctl(2, TIOCSPGRP, (char *)&pgrp);
6656 status = waitforjob(jp);
6670 jp = getjob(*++argv);
6671 if (jp->jobctl == 0)
6672 error("job not created under job control");
6674 } while (--argc > 1);
6683 struct procstat *ps;
6686 if (jp->state == JOBDONE)
6689 killpg(jp->ps[0].pid, SIGCONT);
6690 for (ps = jp->ps, i = jp->nprocs ; --i >= 0 ; ps++) {
6691 if (WIFSTOPPED(ps->status)) {
6700 static void showjobs(int change);
6714 * Print a list of jobs. If "change" is nonzero, only print jobs whose
6715 * statuses have changed since the last call to showjobs.
6717 * If the shell is interrupted in the process of creating a job, the
6718 * result may be a job structure containing zero processes. Such structures
6719 * will be freed here.
6730 struct procstat *ps;
6734 TRACE(("showjobs(%d) called\n", change));
6735 while (dowait(0, (struct job *)NULL) > 0);
6736 for (jobno = 1, jp = jobtab ; jobno <= njobs ; jobno++, jp++) {
6739 if (jp->nprocs == 0) {
6743 if (change && ! jp->changed)
6745 procno = jp->nprocs;
6746 for (ps = jp->ps ; ; ps++) { /* for each process */
6748 snprintf(s, 64, "[%d] %ld ", jobno,
6751 snprintf(s, 64, " %ld ",
6756 if (ps->status == -1) {
6757 /* don't print anything */
6758 } else if (WIFEXITED(ps->status)) {
6759 snprintf(s, 64, "Exit %d",
6760 WEXITSTATUS(ps->status));
6763 if (WIFSTOPPED(ps->status))
6764 i = WSTOPSIG(ps->status);
6765 else /* WIFSIGNALED(ps->status) */
6767 i = WTERMSIG(ps->status);
6768 if ((i & 0x7F) < NSIG && sys_siglist[i & 0x7F])
6769 strcpy(s, sys_siglist[i & 0x7F]);
6771 snprintf(s, 64, "Signal %d", i & 0x7F);
6772 if (WCOREDUMP(ps->status))
6773 strcat(s, " (core dumped)");
6778 "%*c%s\n", 30 - col >= 0 ? 30 - col : 0, ' ',
6785 if (jp->state == JOBDONE) {
6793 * Mark a job structure as unused.
6797 freejob(struct job *jp)
6799 const struct procstat *ps;
6803 for (i = jp->nprocs, ps = jp->ps ; --i >= 0 ; ps++) {
6804 if (ps->cmd != nullstr)
6807 if (jp->ps != &jp->ps0)
6811 if (curjob == jp - jobtab + 1)
6830 job = getjob(*++argv);
6834 for (;;) { /* loop until process terminated or stopped */
6837 status = job->ps[job->nprocs - 1].status;
6843 if (WIFEXITED(status))
6844 retval = WEXITSTATUS(status);
6846 else if (WIFSTOPPED(status))
6847 retval = WSTOPSIG(status) + 128;
6850 /* XXX: limits number of signals */
6851 retval = WTERMSIG(status) + 128;
6856 for (jp = jobtab ; ; jp++) {
6857 if (jp >= jobtab + njobs) { /* no running procs */
6860 if (jp->used && jp->state == 0)
6864 if (dowait(2, 0) < 0 && errno == EINTR) {
6873 * Convert a job name to a job structure.
6877 getjob(const char *name)
6887 if ((jobno = curjob) == 0 || jobtab[jobno - 1].used == 0)
6888 error("No current job");
6889 return &jobtab[jobno - 1];
6891 error("No current job");
6893 } else if (name[0] == '%') {
6894 if (is_digit(name[1])) {
6895 jobno = number(name + 1);
6896 if (jobno > 0 && jobno <= njobs
6897 && jobtab[jobno - 1].used != 0)
6898 return &jobtab[jobno - 1];
6900 } else if (name[1] == '%' && name[2] == '\0') {
6904 struct job *found = NULL;
6905 for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) {
6906 if (jp->used && jp->nprocs > 0
6907 && prefix(name + 1, jp->ps[0].cmd)) {
6909 error("%s: ambiguous", name);
6916 } else if (is_number(name, &pid)) {
6917 for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) {
6918 if (jp->used && jp->nprocs > 0
6919 && jp->ps[jp->nprocs - 1].pid == pid)
6923 error("No such job: %s", name);
6930 * Return a new job structure,
6934 makejob(const union node *node, int nprocs)
6939 for (i = njobs, jp = jobtab ; ; jp++) {
6943 jobtab = ckmalloc(4 * sizeof jobtab[0]);
6945 jp = ckmalloc((njobs + 4) * sizeof jobtab[0]);
6946 memcpy(jp, jobtab, njobs * sizeof jp[0]);
6947 /* Relocate `ps' pointers */
6948 for (i = 0; i < njobs; i++)
6949 if (jp[i].ps == &jobtab[i].ps0)
6950 jp[i].ps = &jp[i].ps0;
6954 jp = jobtab + njobs;
6955 for (i = 4 ; --i >= 0 ; jobtab[njobs++].used = 0);
6968 jp->jobctl = jobctl;
6971 jp->ps = ckmalloc(nprocs * sizeof (struct procstat));
6976 TRACE(("makejob(0x%lx, %d) returns %%%d\n", (long)node, nprocs,
6983 * Fork of a subshell. If we are doing job control, give the subshell its
6984 * own process group. Jp is a job structure that the job is to be added to.
6985 * N is the command that will be evaluated by the child. Both jp and n may
6986 * be NULL. The mode parameter can be one of the following:
6987 * FORK_FG - Fork off a foreground process.
6988 * FORK_BG - Fork off a background process.
6989 * FORK_NOJOB - Like FORK_FG, but don't give the process its own
6990 * process group even if job control is on.
6992 * When job control is turned off, background processes have their standard
6993 * input redirected to /dev/null (except for the second and later processes
7000 forkshell(struct job *jp, const union node *n, int mode)
7006 const char *devnull = _PATH_DEVNULL;
7007 const char *nullerr = "Can't open %s";
7009 TRACE(("forkshell(%%%d, 0x%lx, %d) called\n", jp - jobtab, (long)n,
7014 TRACE(("Fork failed, errno=%d\n", errno));
7016 error("Cannot fork");
7023 TRACE(("Child shell %d\n", getpid()));
7024 wasroot = rootshell;
7030 jobctl = 0; /* do job control only in root shell */
7031 if (wasroot && mode != FORK_NOJOB && mflag) {
7032 if (jp == NULL || jp->nprocs == 0)
7035 pgrp = jp->ps[0].pid;
7037 if (mode == FORK_FG) {
7038 /*** this causes superfluous TIOCSPGRPS ***/
7039 #ifdef OLD_TTY_DRIVER
7040 if (ioctl(2, TIOCSPGRP, (char *)&pgrp) < 0)
7041 error("TIOCSPGRP failed, errno=%d", errno);
7043 if (tcsetpgrp(2, pgrp) < 0)
7044 error("tcsetpgrp failed, errno=%d", errno);
7049 } else if (mode == FORK_BG) {
7052 if ((jp == NULL || jp->nprocs == 0) &&
7053 ! fd0_redirected_p ()) {
7055 if (open(devnull, O_RDONLY) != 0)
7056 error(nullerr, devnull);
7060 if (mode == FORK_BG) {
7063 if ((jp == NULL || jp->nprocs == 0) &&
7064 ! fd0_redirected_p ()) {
7066 if (open(devnull, O_RDONLY) != 0)
7067 error(nullerr, devnull);
7071 for (i = njobs, p = jobtab ; --i >= 0 ; p++)
7074 if (wasroot && iflag) {
7082 if (rootshell && mode != FORK_NOJOB && mflag) {
7083 if (jp == NULL || jp->nprocs == 0)
7086 pgrp = jp->ps[0].pid;
7090 if (mode == FORK_BG)
7091 backgndpid = pid; /* set $! */
7093 struct procstat *ps = &jp->ps[jp->nprocs++];
7097 if (iflag && rootshell && n)
7098 ps->cmd = commandtext(n);
7101 TRACE(("In parent shell: child = %d\n", pid));
7108 * Wait for job to finish.
7110 * Under job control we have the problem that while a child process is
7111 * running interrupts generated by the user are sent to the child but not
7112 * to the shell. This means that an infinite loop started by an inter-
7113 * active user may be hard to kill. With job control turned off, an
7114 * interactive user may place an interactive program inside a loop. If
7115 * the interactive program catches interrupts, the user doesn't want
7116 * these interrupts to also abort the loop. The approach we take here
7117 * is to have the shell ignore interrupt signals while waiting for a
7118 * forground process to terminate, and then send itself an interrupt
7119 * signal if the child process was terminated by an interrupt signal.
7120 * Unfortunately, some programs want to do a bit of cleanup and then
7121 * exit on interrupt; unless these processes terminate themselves by
7122 * sending a signal to themselves (instead of calling exit) they will
7123 * confuse this approach.
7127 waitforjob(struct job *jp)
7130 int mypgrp = getpgrp();
7134 struct sigaction act, oact;
7143 sigaction(SIGINT, 0, &act);
7144 act.sa_handler = waitonint;
7145 sigaction(SIGINT, &act, &oact);
7147 TRACE(("waitforjob(%%%d) called\n", jp - jobtab + 1));
7148 while (jp->state == 0) {
7156 sigaction(SIGINT, &oact, 0);
7157 if (intreceived && trap[SIGINT]) kill(getpid(), SIGINT);
7161 #ifdef OLD_TTY_DRIVER
7162 if (ioctl(2, TIOCSPGRP, (char *)&mypgrp) < 0)
7163 error("TIOCSPGRP failed, errno=%d\n", errno);
7165 if (tcsetpgrp(2, mypgrp) < 0)
7166 error("tcsetpgrp failed, errno=%d\n", errno);
7169 if (jp->state == JOBSTOPPED)
7170 curjob = jp - jobtab + 1;
7172 status = jp->ps[jp->nprocs - 1].status;
7173 /* convert to 8 bits */
7174 if (WIFEXITED(status))
7175 st = WEXITSTATUS(status);
7177 else if (WIFSTOPPED(status))
7178 st = WSTOPSIG(status) + 128;
7181 st = WTERMSIG(status) + 128;
7185 * This is truly gross.
7186 * If we're doing job control, then we did a TIOCSPGRP which
7187 * caused us (the shell) to no longer be in the controlling
7188 * session -- so we wouldn't have seen any ^C/SIGINT. So, we
7189 * intuit from the subprocess exit status whether a SIGINT
7190 * occured, and if so interrupt ourselves. Yuck. - mycroft
7192 if (WIFSIGNALED(status) && WTERMSIG(status) == SIGINT)
7195 if (jp->state == JOBDONE)
7206 * Wait for a process to terminate.
7210 * Do a wait system call. If job control is compiled in, we accept
7211 * stopped processes. If block is zero, we return a value of zero
7212 * rather than blocking.
7214 * System V doesn't have a non-blocking wait system call. It does
7215 * have a SIGCLD signal that is sent to a process when one of it's
7216 * children dies. The obvious way to use SIGCLD would be to install
7217 * a handler for SIGCLD which simply bumped a counter when a SIGCLD
7218 * was received, and have waitproc bump another counter when it got
7219 * the status of a process. Waitproc would then know that a wait
7220 * system call would not block if the two counters were different.
7221 * This approach doesn't work because if a process has children that
7222 * have not been waited for, System V will send it a SIGCLD when it
7223 * installs a signal handler for SIGCLD. What this means is that when
7224 * a child exits, the shell will be sent SIGCLD signals continuously
7225 * until is runs out of stack space, unless it does a wait call before
7226 * restoring the signal handler. The code below takes advantage of
7227 * this (mis)feature by installing a signal handler for SIGCLD and
7228 * then checking to see whether it was called. If there are any
7229 * children to be waited for, it will be.
7234 waitproc(int block, int *status)
7245 return wait3(status, flags, (struct rusage *)NULL);
7249 dowait(int block, struct job *job)
7253 struct procstat *sp;
7255 struct job *thisjob;
7261 TRACE(("dowait(%d) called\n", block));
7263 pid = waitproc(block, &status);
7264 TRACE(("wait returns %d, status=%d\n", pid, status));
7265 } while (!(block & 2) && pid == -1 && errno == EINTR);
7270 for (jp = jobtab ; jp < jobtab + njobs ; jp++) {
7274 for (sp = jp->ps ; sp < jp->ps + jp->nprocs ; sp++) {
7277 if (sp->pid == pid) {
7278 TRACE(("Changing status of proc %d from 0x%x to 0x%x\n", pid, sp->status, status));
7279 sp->status = status;
7282 if (sp->status == -1)
7284 else if (WIFSTOPPED(sp->status))
7287 if (stopped) { /* stopped or done */
7288 int state = done? JOBDONE : JOBSTOPPED;
7289 if (jp->state != state) {
7290 TRACE(("Job %d: changing state from %d to %d\n", jp - jobtab + 1, jp->state, state));
7293 if (done && curjob == jp - jobtab + 1)
7294 curjob = 0; /* no current job */
7301 if (! rootshell || ! iflag || (job && thisjob == job)) {
7302 core = WCOREDUMP(status);
7304 if (WIFSTOPPED(status)) sig = WSTOPSIG(status);
7307 if (WIFEXITED(status)) sig = 0;
7308 else sig = WTERMSIG(status);
7310 if (sig != 0 && sig != SIGINT && sig != SIGPIPE) {
7312 out2fmt("%d: ", pid);
7314 if (sig == SIGTSTP && rootshell && iflag)
7316 (long)(job - jobtab + 1));
7318 if (sig < NSIG && sys_siglist[sig])
7319 out2str(sys_siglist[sig]);
7321 out2fmt("Signal %d", sig);
7323 out2str(" - core dumped");
7326 TRACE(("Not printing status: status=%d, sig=%d\n",
7330 TRACE(("Not printing status, rootshell=%d, job=0x%x\n", rootshell, job));
7332 thisjob->changed = 1;
7341 * return 1 if there are stopped jobs, otherwise 0
7351 for (jobno = 1, jp = jobtab; jobno <= njobs; jobno++, jp++) {
7354 if (jp->state == JOBSTOPPED) {
7355 out2str("You have stopped jobs.\n");
7365 * Return a string identifying a command (to be printed by the
7369 static char *cmdnextc;
7370 static int cmdnleft;
7371 #define MAXCMDTEXT 200
7374 cmdputs(const char *s)
7385 while ((c = *p++) != '\0') {
7388 else if (c == CTLVAR) {
7393 } else if (c == '=' && subtype != 0) {
7394 *q++ = "}-+?="[(subtype & VSTYPE) - VSNORMAL];
7396 } else if (c == CTLENDVAR) {
7398 } else if (c == CTLBACKQ || c == CTLBACKQ+CTLQUOTE)
7399 cmdnleft++; /* ignore it */
7402 if (--cmdnleft <= 0) {
7414 cmdtxt(const union node *n)
7417 struct nodelist *lp;
7426 cmdtxt(n->nbinary.ch1);
7428 cmdtxt(n->nbinary.ch2);
7431 cmdtxt(n->nbinary.ch1);
7433 cmdtxt(n->nbinary.ch2);
7436 cmdtxt(n->nbinary.ch1);
7438 cmdtxt(n->nbinary.ch2);
7441 for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
7449 cmdtxt(n->nredir.n);
7454 cmdtxt(n->nredir.n);
7458 cmdtxt(n->nif.test);
7460 cmdtxt(n->nif.ifpart);
7469 cmdtxt(n->nbinary.ch1);
7471 cmdtxt(n->nbinary.ch2);
7476 cmdputs(n->nfor.var);
7481 cmdputs(n->ncase.expr->narg.text);
7485 cmdputs(n->narg.text);
7489 for (np = n->ncmd.args ; np ; np = np->narg.next) {
7494 for (np = n->ncmd.redirect ; np ; np = np->nfile.next) {
7500 cmdputs(n->narg.text);
7503 p = ">"; i = 1; goto redir;
7505 p = ">>"; i = 1; goto redir;
7507 p = ">&"; i = 1; goto redir;
7509 p = ">|"; i = 1; goto redir;
7511 p = "<"; i = 0; goto redir;
7513 p = "<&"; i = 0; goto redir;
7515 p = "<>"; i = 0; goto redir;
7517 if (n->nfile.fd != i) {
7518 s[0] = n->nfile.fd + '0';
7523 if (n->type == NTOFD || n->type == NFROMFD) {
7524 s[0] = n->ndup.dupfd + '0';
7528 cmdtxt(n->nfile.fname);
7543 commandtext(const union node *n)
7547 cmdnextc = name = ckmalloc(MAXCMDTEXT);
7548 cmdnleft = MAXCMDTEXT - 4;
7555 static void waitonint(int sig) {
7560 * Routines to check for mail. (Perhaps make part of main.c?)
7564 #define MAXMBOXES 10
7567 static int nmboxes; /* number of mailboxes */
7568 static time_t mailtime[MAXMBOXES]; /* times of mailboxes */
7573 * Print appropriate message(s) if mail has arrived. If the argument is
7574 * nozero, then the value of MAIL has changed, so we just update the
7585 struct stackmark smark;
7592 setstackmark(&smark);
7593 mpath = mpathset()? mpathval() : mailval();
7594 for (i = 0 ; i < nmboxes ; i++) {
7595 p = padvance(&mpath, nullstr);
7600 for (q = p ; *q ; q++);
7605 q[-1] = '\0'; /* delete trailing '/' */
7606 if (stat(p, &statb) < 0)
7608 if (statb.st_size > mailtime[i] && ! silent) {
7610 pathopt? pathopt : "you have mail");
7612 mailtime[i] = statb.st_size;
7615 popstackmark(&smark);
7621 static short profile_buf[16384];
7625 static void read_profile (const char *);
7626 static void cmdloop (int);
7627 static void options (int);
7628 static void setoption (int, int);
7629 static void procargs (int, char **);
7633 * Main routine. We initialize things, parse the arguments, execute
7634 * profiles if we're a login shell, and then call cmdloop to execute
7635 * commands. The setjmp call sets up the location to jump to when an
7636 * exception occurs. When an exception occurs the variable "state"
7637 * is used to figure out how far we had gotten.
7641 shell_main(argc, argv)
7645 struct jmploc jmploc;
7646 struct stackmark smark;
7650 BLTINCMD = find_builtin("builtin");
7651 EXECCMD = find_builtin("exec");
7652 EVALCMD = find_builtin("eval");
7654 #ifndef BB_FEATURE_SH_FANCY_PROMPT
7660 monitor(4, etext, profile_buf, sizeof profile_buf, 50);
7662 #if defined(linux) || defined(__GNU__)
7663 signal(SIGCHLD, SIG_DFL);
7666 if (setjmp(jmploc.loc)) {
7669 * When a shell procedure is executed, we raise the
7670 * exception EXSHELLPROC to clean up before executing
7671 * the shell procedure.
7673 switch (exception) {
7682 exitstatus = exerrno;
7693 if (exception != EXSHELLPROC) {
7694 if (state == 0 || iflag == 0 || ! rootshell)
7695 exitshell(exitstatus);
7698 if (exception == EXINT) {
7701 popstackmark(&smark);
7702 FORCEINTON; /* enable interrupts */
7705 else if (state == 2)
7707 else if (state == 3)
7715 trputs("Shell args: "); trargs(argv);
7720 setstackmark(&smark);
7721 procargs(argc, argv);
7722 if (argv[0] && argv[0][0] == '-') {
7724 read_profile("/etc/profile");
7727 read_profile(".profile");
7732 if (getuid() == geteuid() && getgid() == getegid()) {
7734 if ((shinit = lookupvar("ENV")) != NULL && *shinit != '\0') {
7736 read_profile(shinit);
7743 if (sflag == 0 || minusc) {
7744 static int sigs[] = {
7745 SIGINT, SIGQUIT, SIGHUP,
7751 #define SIGSSIZE (sizeof(sigs)/sizeof(sigs[0]))
7754 for (i = 0; i < SIGSSIZE; i++)
7759 evalstring(minusc, 0);
7761 if (sflag || minusc == NULL) {
7762 state4: /* XXX ??? - why isn't this before the "if" statement */
7768 exitshell(exitstatus);
7774 * Read and execute commands. "Top" is nonzero for the top level command
7775 * loop; it turns on prompting if the shell is interactive.
7782 struct stackmark smark;
7786 TRACE(("cmdloop(%d) called\n", top));
7787 setstackmark(&smark);
7798 n = parsecmd(inter);
7799 /* showtree(n); DEBUG */
7801 if (!top || numeof >= 50)
7803 if (!stoppedjobs()) {
7806 out2str("\nUse \"exit\" to leave shell.\n");
7809 } else if (n != NULL && nflag == 0) {
7810 job_warning = (job_warning == 2) ? 1 : 0;
7814 popstackmark(&smark);
7815 setstackmark(&smark);
7816 if (evalskip == SKIPFILE) {
7821 popstackmark(&smark);
7827 * Read /etc/profile or .profile. Return on error.
7839 if ((fd = open(name, O_RDONLY)) >= 0)
7844 /* -q turns off -x and -v just when executing init files */
7847 xflag = 0, xflag_set = 1;
7849 vflag = 0, vflag_set = 1;
7864 * Read a file containing shell functions.
7868 readcmdfile(const char *name)
7873 if ((fd = open(name, O_RDONLY)) >= 0)
7876 error("Can't open %s", name);
7885 * Take commands from a file. To be compatable we should do a path
7886 * search for the file, which is necessary to find sub-commands.
7890 static inline char *
7891 find_dot_file(mybasename)
7895 const char *path = pathval();
7898 /* don't try this for absolute or relative paths */
7899 if (strchr(mybasename, '/'))
7902 while ((fullname = padvance(&path, mybasename)) != NULL) {
7903 if ((stat(fullname, &statb) == 0) && S_ISREG(statb.st_mode)) {
7905 * Don't bother freeing here, since it will
7906 * be freed by the caller.
7910 stunalloc(fullname);
7913 /* not found in the PATH */
7914 error("%s: not found", mybasename);
7926 for (sp = cmdenviron; sp ; sp = sp->next)
7927 setvareq(savestr(sp->text), VSTRFIXED|VTEXTFIXED);
7929 if (argc >= 2) { /* That's what SVR2 does */
7931 struct stackmark smark;
7933 setstackmark(&smark);
7934 fullname = find_dot_file(argv[1]);
7935 setinputfile(fullname, 1);
7936 commandname = fullname;
7939 popstackmark(&smark);
7953 exitstatus = number(argv[1]);
7955 exitstatus = oexitstatus;
7956 exitshell(exitstatus);
7965 nbytes = ALIGN(nbytes);
7966 if (nbytes > stacknleft) {
7968 struct stack_block *sp;
7971 if (blocksize < MINSIZE)
7972 blocksize = MINSIZE;
7974 sp = ckmalloc(sizeof(struct stack_block) - MINSIZE + blocksize);
7976 stacknxt = sp->space;
7977 stacknleft = blocksize;
7983 stacknleft -= nbytes;
7989 stunalloc(pointer p)
7992 if (p == NULL) { /*DEBUG */
7993 write(2, "stunalloc\n", 10);
7997 if (!(stacknxt >= (char *)p && (char *)p >= stackp->space)) {
8000 stacknleft += stacknxt - (char *)p;
8006 setstackmark(struct stackmark *mark)
8008 mark->stackp = stackp;
8009 mark->stacknxt = stacknxt;
8010 mark->stacknleft = stacknleft;
8011 mark->marknext = markp;
8017 popstackmark(struct stackmark *mark)
8019 struct stack_block *sp;
8022 markp = mark->marknext;
8023 while (stackp != mark->stackp) {
8028 stacknxt = mark->stacknxt;
8029 stacknleft = mark->stacknleft;
8035 * When the parser reads in a string, it wants to stick the string on the
8036 * stack and only adjust the stack pointer when it knows how big the
8037 * string is. Stackblock (defined in stack.h) returns a pointer to a block
8038 * of space on top of the stack and stackblocklen returns the length of
8039 * this block. Growstackblock will grow this space by at least one byte,
8040 * possibly moving it (like realloc). Grabstackblock actually allocates the
8041 * part of the block that has been used.
8045 growstackblock(void) {
8047 int newlen = ALIGN(stacknleft * 2 + 100);
8048 char *oldspace = stacknxt;
8049 int oldlen = stacknleft;
8050 struct stack_block *sp;
8051 struct stack_block *oldstackp;
8053 if (stacknxt == stackp->space && stackp != &stackbase) {
8058 sp = ckrealloc((pointer)sp, sizeof(struct stack_block) - MINSIZE + newlen);
8061 stacknxt = sp->space;
8062 stacknleft = newlen;
8064 /* Stack marks pointing to the start of the old block
8065 * must be relocated to point to the new block
8067 struct stackmark *xmark;
8069 while (xmark != NULL && xmark->stackp == oldstackp) {
8070 xmark->stackp = stackp;
8071 xmark->stacknxt = stacknxt;
8072 xmark->stacknleft = stacknleft;
8073 xmark = xmark->marknext;
8078 p = stalloc(newlen);
8079 memcpy(p, oldspace, oldlen);
8080 stacknxt = p; /* free the space */
8081 stacknleft += newlen; /* we just allocated */
8088 grabstackblock(int len)
8098 * The following routines are somewhat easier to use that the above.
8099 * The user declares a variable of type STACKSTR, which may be declared
8100 * to be a register. The macro STARTSTACKSTR initializes things. Then
8101 * the user uses the macro STPUTC to add characters to the string. In
8102 * effect, STPUTC(c, p) is the same as *p++ = c except that the stack is
8103 * grown as necessary. When the user is done, she can just leave the
8104 * string there and refer to it using stackblock(). Or she can allocate
8105 * the space for it using grabstackstr(). If it is necessary to allow
8106 * someone else to use the stack temporarily and then continue to grow
8107 * the string, the user should use grabstack to allocate the space, and
8108 * then call ungrabstr(p) to return to the previous mode of operation.
8110 * USTPUTC is like STPUTC except that it doesn't check for overflow.
8111 * CHECKSTACKSPACE can be called before USTPUTC to ensure that there
8112 * is space for at least one character.
8117 growstackstr(void) {
8118 int len = stackblocksize();
8119 if (herefd >= 0 && len >= 1024) {
8120 xwrite(herefd, stackblock(), len);
8121 sstrnleft = len - 1;
8122 return stackblock();
8125 sstrnleft = stackblocksize() - len - 1;
8126 return stackblock() + len;
8131 * Called from CHECKSTRSPACE.
8135 makestrspace(size_t newlen) {
8136 int len = stackblocksize() - sstrnleft;
8139 sstrnleft = stackblocksize() - len;
8140 } while (sstrnleft < newlen);
8141 return stackblock() + len;
8147 ungrabstackstr(char *s, char *p)
8149 stacknleft += stacknxt - s;
8151 sstrnleft = stacknleft - (p - s);
8154 * Miscelaneous builtins.
8161 static mode_t getmode(const void *, mode_t);
8162 static void *setmode(const char *);
8165 #if !defined(__GLIBC__) || __GLIBC__ == 2 && __GLIBC_MINOR__ < 1
8166 typedef long rlim_t;
8172 * The read builtin. The -e option causes backslashes to escape the
8173 * following character.
8175 * This uses unbuffered input, which may be avoidable in some cases.
8196 while ((i = nextopt("p:r")) != '\0') {
8202 if (prompt && isatty(0)) {
8206 if (*(ap = argptr) == NULL)
8208 if ((ifs = bltinlookup("IFS")) == NULL)
8215 if (read(0, &c, 1) != 1) {
8227 if (!rflag && c == '\\') {
8233 if (startword && *ifs == ' ' && strchr(ifs, c)) {
8237 if (backslash && c == '\\') {
8238 if (read(0, &c, 1) != 1) {
8243 } else if (ap[1] != NULL && strchr(ifs, c) != NULL) {
8245 setvar(*ap, stackblock(), 0);
8254 /* Remove trailing blanks */
8255 while (stackblock() <= --p && strchr(ifs, *p) != NULL)
8257 setvar(*ap, stackblock(), 0);
8258 while (*++ap != NULL)
8259 setvar(*ap, nullstr, 0);
8266 umaskcmd(argc, argv)
8273 int symbolic_mode = 0;
8275 while (nextopt("S") != '\0') {
8284 if ((ap = *argptr) == NULL) {
8285 if (symbolic_mode) {
8286 char u[4], g[4], o[4];
8289 if ((mask & S_IRUSR) == 0)
8291 if ((mask & S_IWUSR) == 0)
8293 if ((mask & S_IXUSR) == 0)
8298 if ((mask & S_IRGRP) == 0)
8300 if ((mask & S_IWGRP) == 0)
8302 if ((mask & S_IXGRP) == 0)
8307 if ((mask & S_IROTH) == 0)
8309 if ((mask & S_IWOTH) == 0)
8311 if ((mask & S_IXOTH) == 0)
8315 printf("u=%s,g=%s,o=%s\n", u, g, o);
8317 printf("%.4o\n", mask);
8320 if (is_digit((unsigned char)*ap)) {
8323 if (*ap >= '8' || *ap < '0')
8324 error("Illegal number: %s", argv[1]);
8325 mask = (mask << 3) + (*ap - '0');
8326 } while (*++ap != '\0');
8332 if ((set = setmode(ap)) != 0) {
8333 mask = getmode(set, ~mask & 0777);
8338 error("Illegal mode: %s", ap);
8340 umask(~mask & 0777);
8349 * This code, originally by Doug Gwyn, Doug Kingston, Eric Gisin, and
8350 * Michael Rendell was ripped from pdksh 5.0.8 and hacked for use with
8351 * ash by J.T. Conklin.
8359 int factor; /* multiply by to get rlim_{cur,max} values */
8363 static const struct limits limits[] = {
8365 { "time(seconds)", RLIMIT_CPU, 1, 't' },
8368 { "file(blocks)", RLIMIT_FSIZE, 512, 'f' },
8371 { "data(kbytes)", RLIMIT_DATA, 1024, 'd' },
8374 { "stack(kbytes)", RLIMIT_STACK, 1024, 's' },
8377 { "coredump(blocks)", RLIMIT_CORE, 512, 'c' },
8380 { "memory(kbytes)", RLIMIT_RSS, 1024, 'm' },
8382 #ifdef RLIMIT_MEMLOCK
8383 { "locked memory(kbytes)", RLIMIT_MEMLOCK, 1024, 'l' },
8386 { "process(processes)", RLIMIT_NPROC, 1, 'p' },
8388 #ifdef RLIMIT_NOFILE
8389 { "nofiles(descriptors)", RLIMIT_NOFILE, 1, 'n' },
8392 { "vmemory(kbytes)", RLIMIT_VMEM, 1024, 'v' },
8395 { "swap(kbytes)", RLIMIT_SWAP, 1024, 'w' },
8397 { (char *) 0, 0, 0, '\0' }
8401 ulimitcmd(argc, argv)
8407 enum { SOFT = 0x1, HARD = 0x2 }
8409 const struct limits *l;
8412 struct rlimit limit;
8415 while ((optc = nextopt("HSatfdsmcnpl")) != '\0')
8430 for (l = limits; l->name && l->option != what; l++)
8433 error("internal error (%c)", what);
8435 set = *argptr ? 1 : 0;
8439 if (all || argptr[1])
8440 error("too many arguments");
8441 if (strcmp(p, "unlimited") == 0)
8442 val = RLIM_INFINITY;
8446 while ((c = *p++) >= '0' && c <= '9')
8448 val = (val * 10) + (long)(c - '0');
8449 if (val < (rlim_t) 0)
8453 error("bad number");
8458 for (l = limits; l->name; l++) {
8459 getrlimit(l->cmd, &limit);
8461 val = limit.rlim_cur;
8462 else if (how & HARD)
8463 val = limit.rlim_max;
8465 printf("%-20s ", l->name);
8466 if (val == RLIM_INFINITY)
8467 printf("unlimited\n");
8471 printf("%lld\n", (long long) val);
8477 getrlimit(l->cmd, &limit);
8480 limit.rlim_max = val;
8482 limit.rlim_cur = val;
8483 if (setrlimit(l->cmd, &limit) < 0)
8484 error("error setting limit (%m)");
8487 val = limit.rlim_cur;
8488 else if (how & HARD)
8489 val = limit.rlim_max;
8491 if (val == RLIM_INFINITY)
8492 printf("unlimited\n");
8496 printf("%lld\n", (long long) val);
8502 * prefix -- see if pfx is a prefix of string.
8506 prefix(char const *pfx, char const *string)
8509 if (*pfx++ != *string++)
8516 * Return true if s is a string of digits, and save munber in intptr
8521 is_number(const char *p, int *intptr)
8529 ret += digit_val(*p);
8531 } while (*p != '\0');
8538 * Convert a string of digits to an integer, printing an error message on
8543 number(const char *s)
8546 if (! is_number(s, &i))
8547 error("Illegal number: %s", s);
8552 * Produce a possibly single quoted string suitable as input to the shell.
8553 * The return string is allocated on the stack.
8557 single_quote(const char *s) {
8564 size_t len1, len1p, len2, len2p;
8566 len1 = strcspn(s, "'");
8567 len2 = strspn(s + len1, "'");
8569 len1p = len1 ? len1 + 2 : len1;
8581 CHECKSTRSPACE(len1p + len2p + 1, p);
8586 memcpy(p + 1, s, len1);
8602 memcpy(q + 1, s, len2);
8607 STADJUST(len1p + len2p, p);
8612 return grabstackstr(p);
8616 * Like strdup but works with the ash stack.
8620 sstrdup(const char *p)
8622 size_t len = strlen(p) + 1;
8623 return memcpy(stalloc(len), p, len);
8628 * Routine for dealing with parsed shell commands.
8632 static void sizenodelist (const struct nodelist *);
8633 static struct nodelist *copynodelist (const struct nodelist *);
8634 static char *nodesavestr (const char *);
8637 calcsize(const union node *n)
8641 funcblocksize += nodesize[n->type];
8648 calcsize(n->nbinary.ch2);
8649 calcsize(n->nbinary.ch1);
8652 calcsize(n->ncmd.redirect);
8653 calcsize(n->ncmd.args);
8654 calcsize(n->ncmd.assign);
8657 sizenodelist(n->npipe.cmdlist);
8662 calcsize(n->nredir.redirect);
8663 calcsize(n->nredir.n);
8666 calcsize(n->nif.elsepart);
8667 calcsize(n->nif.ifpart);
8668 calcsize(n->nif.test);
8671 funcstringsize += strlen(n->nfor.var) + 1;
8672 calcsize(n->nfor.body);
8673 calcsize(n->nfor.args);
8676 calcsize(n->ncase.cases);
8677 calcsize(n->ncase.expr);
8680 calcsize(n->nclist.body);
8681 calcsize(n->nclist.pattern);
8682 calcsize(n->nclist.next);
8686 sizenodelist(n->narg.backquote);
8687 funcstringsize += strlen(n->narg.text) + 1;
8688 calcsize(n->narg.next);
8695 calcsize(n->nfile.fname);
8696 calcsize(n->nfile.next);
8700 calcsize(n->ndup.vname);
8701 calcsize(n->ndup.next);
8705 calcsize(n->nhere.doc);
8706 calcsize(n->nhere.next);
8709 calcsize(n->nnot.com);
8715 sizenodelist(const struct nodelist *lp)
8718 funcblocksize += ALIGN(sizeof(struct nodelist));
8726 copynode(const union node *n)
8733 funcblock = (char *) funcblock + nodesize[n->type];
8740 new->nbinary.ch2 = copynode(n->nbinary.ch2);
8741 new->nbinary.ch1 = copynode(n->nbinary.ch1);
8744 new->ncmd.redirect = copynode(n->ncmd.redirect);
8745 new->ncmd.args = copynode(n->ncmd.args);
8746 new->ncmd.assign = copynode(n->ncmd.assign);
8747 new->ncmd.backgnd = n->ncmd.backgnd;
8750 new->npipe.cmdlist = copynodelist(n->npipe.cmdlist);
8751 new->npipe.backgnd = n->npipe.backgnd;
8756 new->nredir.redirect = copynode(n->nredir.redirect);
8757 new->nredir.n = copynode(n->nredir.n);
8760 new->nif.elsepart = copynode(n->nif.elsepart);
8761 new->nif.ifpart = copynode(n->nif.ifpart);
8762 new->nif.test = copynode(n->nif.test);
8765 new->nfor.var = nodesavestr(n->nfor.var);
8766 new->nfor.body = copynode(n->nfor.body);
8767 new->nfor.args = copynode(n->nfor.args);
8770 new->ncase.cases = copynode(n->ncase.cases);
8771 new->ncase.expr = copynode(n->ncase.expr);
8774 new->nclist.body = copynode(n->nclist.body);
8775 new->nclist.pattern = copynode(n->nclist.pattern);
8776 new->nclist.next = copynode(n->nclist.next);
8780 new->narg.backquote = copynodelist(n->narg.backquote);
8781 new->narg.text = nodesavestr(n->narg.text);
8782 new->narg.next = copynode(n->narg.next);
8789 new->nfile.fname = copynode(n->nfile.fname);
8790 new->nfile.fd = n->nfile.fd;
8791 new->nfile.next = copynode(n->nfile.next);
8795 new->ndup.vname = copynode(n->ndup.vname);
8796 new->ndup.dupfd = n->ndup.dupfd;
8797 new->ndup.fd = n->ndup.fd;
8798 new->ndup.next = copynode(n->ndup.next);
8802 new->nhere.doc = copynode(n->nhere.doc);
8803 new->nhere.fd = n->nhere.fd;
8804 new->nhere.next = copynode(n->nhere.next);
8807 new->nnot.com = copynode(n->nnot.com);
8810 new->type = n->type;
8815 static struct nodelist *
8816 copynodelist(const struct nodelist *lp)
8818 struct nodelist *start;
8819 struct nodelist **lpp;
8824 funcblock = (char *) funcblock + ALIGN(sizeof(struct nodelist));
8825 (*lpp)->n = copynode(lp->n);
8827 lpp = &(*lpp)->next;
8835 nodesavestr(const char *s)
8838 char *rtn = funcstring;
8840 funcstring = stpcpy(funcstring, s) + 1;
8844 char *q = funcstring;
8845 char *rtn = funcstring;
8847 while ((*q++ = *p++) != '\0')
8855 static int getopts (char *, char *, char **, int *, int *);
8860 * Process the shell command line arguments.
8864 procargs(argc, argv)
8873 for (i = 0; i < NOPTS; i++)
8876 if (*argptr == NULL && minusc == NULL)
8878 if (iflag == 2 && sflag == 1 && isatty(0) && isatty(1))
8882 for (i = 0; i < NOPTS; i++)
8883 if (optent_val(i) == 2)
8886 if (sflag == 0 && minusc == NULL) {
8887 commandname = argv[0];
8889 setinputfile(arg0, 0);
8892 /* POSIX 1003.2: first arg after -c cmd is $0, remainder $1... */
8893 if (argptr && minusc && *argptr)
8896 shellparam.p = argptr;
8897 shellparam.optind = 1;
8898 shellparam.optoff = -1;
8899 /* assert(shellparam.malloc == 0 && shellparam.nparam == 0); */
8901 shellparam.nparam++;
8910 * Process shell options. The global variable argptr contains a pointer
8911 * to the argument list; we advance it past the options.
8915 minus_o(const char *name, int val)
8920 out1str("Current option settings\n");
8921 for (i = 0; i < NOPTS; i++)
8922 printf("%-16s%s\n", optent_name(optlist[i]),
8923 optent_val(i) ? "on" : "off");
8925 for (i = 0; i < NOPTS; i++)
8926 if (equal(name, optent_name(optlist[i]))) {
8927 setoption(optent_letter(optlist[i]), val);
8930 error("Illegal option -o %s", name);
8936 options(int cmdline)
8944 while ((p = *argptr) != NULL) {
8946 if ((c = *p++) == '-') {
8948 if (p[0] == '\0' || (p[0] == '-' && p[1] == '\0')) {
8950 /* "-" means turn off -x and -v */
8953 /* "--" means reset params */
8954 else if (*argptr == NULL)
8957 break; /* "-" or "--" terminates options */
8959 } else if (c == '+') {
8965 while ((c = *p++) != '\0') {
8966 if (c == 'c' && cmdline) {
8968 #ifdef NOHACK /* removing this code allows sh -ce 'foo' for compat */
8972 if (q == NULL || minusc != NULL)
8973 error("Bad -c option");
8978 } else if (c == 'o') {
8979 minus_o(*argptr, val);
8991 setoption(int flag, int val)
8995 for (i = 0; i < NOPTS; i++)
8996 if (optent_letter(optlist[i]) == flag) {
8997 optent_val(i) = val;
8999 /* #%$ hack for ksh semantics */
9002 else if (flag == 'E')
9007 error("Illegal option -%c", flag);
9014 * Set the shell parameters.
9018 setparam(char **argv)
9024 for (nparam = 0 ; argv[nparam] ; nparam++);
9025 ap = newparam = ckmalloc((nparam + 1) * sizeof *ap);
9027 *ap++ = savestr(*argv++);
9030 freeparam(&shellparam);
9031 shellparam.malloc = 1;
9032 shellparam.nparam = nparam;
9033 shellparam.p = newparam;
9034 shellparam.optind = 1;
9035 shellparam.optoff = -1;
9040 * Free the list of positional parameters.
9044 freeparam(volatile struct shparam *param)
9048 if (param->malloc) {
9049 for (ap = param->p ; *ap ; ap++)
9058 * The shift builtin command.
9062 shiftcmd(argc, argv)
9071 n = number(argv[1]);
9072 if (n > shellparam.nparam)
9073 error("can't shift that many");
9075 shellparam.nparam -= n;
9076 for (ap1 = shellparam.p ; --n >= 0 ; ap1++) {
9077 if (shellparam.malloc)
9081 while ((*ap2++ = *ap1++) != NULL);
9082 shellparam.optind = 1;
9083 shellparam.optoff = -1;
9091 * The set command builtin.
9100 return showvarscmd(argc, argv);
9104 if (*argptr != NULL) {
9113 getoptsreset(const char *value)
9115 shellparam.optind = number(value);
9116 shellparam.optoff = -1;
9119 #ifdef BB_LOCALE_SUPPORT
9120 static void change_lc_all(const char *value)
9122 if(value != 0 && *value != 0)
9123 setlocale(LC_ALL, value);
9126 static void change_lc_ctype(const char *value)
9128 if(value != 0 && *value != 0)
9129 setlocale(LC_CTYPE, value);
9136 * The getopts builtin. Shellparam.optnext points to the next argument
9137 * to be processed. Shellparam.optptr points to the next character to
9138 * be processed in the current argument. If shellparam.optnext is NULL,
9139 * then it's the first time getopts has been called.
9143 getoptscmd(argc, argv)
9150 error("Usage: getopts optstring var [arg]");
9151 else if (argc == 3) {
9152 optbase = shellparam.p;
9153 if (shellparam.optind > shellparam.nparam + 1) {
9154 shellparam.optind = 1;
9155 shellparam.optoff = -1;
9160 if (shellparam.optind > argc - 2) {
9161 shellparam.optind = 1;
9162 shellparam.optoff = -1;
9166 return getopts(argv[1], argv[2], optbase, &shellparam.optind,
9167 &shellparam.optoff);
9171 * Safe version of setvar, returns 1 on success 0 on failure.
9175 setvarsafe(name, val, flags)
9176 const char *name, *val;
9179 struct jmploc jmploc;
9180 struct jmploc *volatile savehandler = handler;
9186 if (setjmp(jmploc.loc))
9190 setvar(name, val, flags);
9192 handler = savehandler;
9197 getopts(optstr, optvar, optfirst, myoptind, optoff)
9209 char **optnext = optfirst + *myoptind - 1;
9211 if (*myoptind <= 1 || *optoff < 0 || !(*(optnext - 1)) ||
9212 strlen(*(optnext - 1)) < *optoff)
9215 p = *(optnext - 1) + *optoff;
9216 if (p == NULL || *p == '\0') {
9217 /* Current word is done, advance */
9218 if (optnext == NULL)
9221 if (p == NULL || *p != '-' || *++p == '\0') {
9223 *myoptind = optnext - optfirst + 1;
9229 if (p[0] == '-' && p[1] == '\0') /* check for "--" */
9234 for (q = optstr; *q != c; ) {
9236 if (optstr[0] == ':') {
9239 err |= setvarsafe("OPTARG", s, 0);
9242 out2fmt("Illegal option -%c\n", c);
9243 (void) unsetvar("OPTARG");
9253 if (*p == '\0' && (p = *optnext) == NULL) {
9254 if (optstr[0] == ':') {
9257 err |= setvarsafe("OPTARG", s, 0);
9261 out2fmt("No arg for -%c option\n", c);
9262 (void) unsetvar("OPTARG");
9270 setvarsafe("OPTARG", p, 0);
9274 setvarsafe("OPTARG", "", 0);
9275 *myoptind = optnext - optfirst + 1;
9282 *optoff = p ? p - *(optnext - 1) : -1;
9283 snprintf(s, sizeof(s), "%d", *myoptind);
9284 err |= setvarsafe("OPTIND", s, VNOFUNC);
9287 err |= setvarsafe(optvar, s, 0);
9298 * XXX - should get rid of. have all builtins use getopt(3). the
9299 * library getopt must have the BSD extension static variable "optreset"
9300 * otherwise it can't be used within the shell safely.
9302 * Standard option processing (a la getopt) for builtin routines. The
9303 * only argument that is passed to nextopt is the option string; the
9304 * other arguments are unnecessary. It return the character, or '\0' on
9309 nextopt(const char *optstring)
9315 if ((p = optptr) == NULL || *p == '\0') {
9317 if (p == NULL || *p != '-' || *++p == '\0')
9320 if (p[0] == '-' && p[1] == '\0') /* check for "--" */
9324 for (q = optstring ; *q != c ; ) {
9326 error("Illegal option -%c", c);
9331 if (*p == '\0' && (p = *argptr++) == NULL)
9332 error("No arg for -%c option", c);
9349 out2fmt(const char *fmt, ...)
9353 vfprintf(stderr, fmt, ap);
9358 * Version of write which resumes after a signal is caught.
9362 xwrite(int fd, const char *buf, int nbytes)
9371 i = write(fd, buf, n);
9377 } else if (i == 0) {
9380 } else if (errno != EINTR) {
9388 * Shell command parser.
9391 #define EOFMARKLEN 79
9396 struct heredoc *next; /* next here document in list */
9397 union node *here; /* redirection node */
9398 char *eofmark; /* string indicating end of input */
9399 int striptabs; /* if set, strip leading tabs */
9402 static struct heredoc *heredoclist; /* list of here documents to read */
9403 static int parsebackquote; /* nonzero if we are inside backquotes */
9404 static int doprompt; /* if set, prompt the user */
9405 static int needprompt; /* true if interactive and at start of line */
9406 static int lasttoken; /* last token read */
9408 static char *wordtext; /* text of last word returned by readtoken */
9410 static struct nodelist *backquotelist;
9411 static union node *redirnode;
9412 static struct heredoc *heredoc;
9413 static int quoteflag; /* set if (part of) last token was quoted */
9414 static int startlinno; /* line # where last token started */
9417 static union node *list (int);
9418 static union node *andor (void);
9419 static union node *pipeline (void);
9420 static union node *command (void);
9421 static union node *simplecmd (void);
9422 static void parsefname (void);
9423 static void parseheredoc (void);
9424 static int peektoken (void);
9425 static int readtoken (void);
9426 static int xxreadtoken (void);
9427 static int readtoken1 (int, char const *, char *, int);
9428 static int noexpand (char *);
9429 static void synexpect (int) __attribute__((noreturn));
9430 static void synerror (const char *) __attribute__((noreturn));
9431 static void setprompt (int);
9435 * Read and parse a command. Returns NEOF on end of file. (NULL is a
9436 * valid parse tree indicating a blank line.)
9440 parsecmd(int interact)
9445 doprompt = interact;
9465 union node *n1, *n2, *n3;
9469 if (nlflag == 0 && tokendlist[peektoken()])
9475 if (tok == TBACKGND) {
9476 if (n2->type == NCMD || n2->type == NPIPE) {
9477 n2->ncmd.backgnd = 1;
9478 } else if (n2->type == NREDIR) {
9479 n2->type = NBACKGND;
9481 n3 = (union node *)stalloc(sizeof (struct nredir));
9482 n3->type = NBACKGND;
9484 n3->nredir.redirect = NULL;
9492 n3 = (union node *)stalloc(sizeof (struct nbinary));
9494 n3->nbinary.ch1 = n1;
9495 n3->nbinary.ch2 = n2;
9512 if (tokendlist[peektoken()])
9519 pungetc(); /* push back EOF on input */
9534 union node *n1, *n2, *n3;
9540 if ((t = readtoken()) == TAND) {
9542 } else if (t == TOR) {
9550 n3 = (union node *)stalloc(sizeof (struct nbinary));
9552 n3->nbinary.ch1 = n1;
9553 n3->nbinary.ch2 = n2;
9562 union node *n1, *n2, *pipenode;
9563 struct nodelist *lp, *prev;
9567 TRACE(("pipeline: entered\n"));
9568 if (readtoken() == TNOT) {
9574 if (readtoken() == TPIPE) {
9575 pipenode = (union node *)stalloc(sizeof (struct npipe));
9576 pipenode->type = NPIPE;
9577 pipenode->npipe.backgnd = 0;
9578 lp = (struct nodelist *)stalloc(sizeof (struct nodelist));
9579 pipenode->npipe.cmdlist = lp;
9583 lp = (struct nodelist *)stalloc(sizeof (struct nodelist));
9587 } while (readtoken() == TPIPE);
9593 n2 = (union node *)stalloc(sizeof (struct nnot));
9605 union node *n1, *n2;
9606 union node *ap, **app;
9607 union node *cp, **cpp;
9608 union node *redir, **rpp;
9615 switch (readtoken()) {
9617 n1 = (union node *)stalloc(sizeof (struct nif));
9619 n1->nif.test = list(0);
9620 if (readtoken() != TTHEN)
9622 n1->nif.ifpart = list(0);
9624 while (readtoken() == TELIF) {
9625 n2->nif.elsepart = (union node *)stalloc(sizeof (struct nif));
9626 n2 = n2->nif.elsepart;
9628 n2->nif.test = list(0);
9629 if (readtoken() != TTHEN)
9631 n2->nif.ifpart = list(0);
9633 if (lasttoken == TELSE)
9634 n2->nif.elsepart = list(0);
9636 n2->nif.elsepart = NULL;
9639 if (readtoken() != TFI)
9646 n1 = (union node *)stalloc(sizeof (struct nbinary));
9647 n1->type = (lasttoken == TWHILE)? NWHILE : NUNTIL;
9648 n1->nbinary.ch1 = list(0);
9649 if ((got=readtoken()) != TDO) {
9650 TRACE(("expecting DO got %s %s\n", tokname[got], got == TWORD ? wordtext : ""));
9653 n1->nbinary.ch2 = list(0);
9654 if (readtoken() != TDONE)
9660 if (readtoken() != TWORD || quoteflag || ! goodname(wordtext))
9661 synerror("Bad for loop variable");
9662 n1 = (union node *)stalloc(sizeof (struct nfor));
9664 n1->nfor.var = wordtext;
9666 if (readtoken() == TIN) {
9668 while (readtoken() == TWORD) {
9669 n2 = (union node *)stalloc(sizeof (struct narg));
9671 n2->narg.text = wordtext;
9672 n2->narg.backquote = backquotelist;
9674 app = &n2->narg.next;
9678 if (lasttoken != TNL && lasttoken != TSEMI)
9681 static char argvars[5] = {CTLVAR, VSNORMAL|VSQUOTE,
9683 n2 = (union node *)stalloc(sizeof (struct narg));
9685 n2->narg.text = argvars;
9686 n2->narg.backquote = NULL;
9687 n2->narg.next = NULL;
9690 * Newline or semicolon here is optional (but note
9691 * that the original Bourne shell only allowed NL).
9693 if (lasttoken != TNL && lasttoken != TSEMI)
9697 if (readtoken() != TDO)
9699 n1->nfor.body = list(0);
9700 if (readtoken() != TDONE)
9705 n1 = (union node *)stalloc(sizeof (struct ncase));
9707 if (readtoken() != TWORD)
9709 n1->ncase.expr = n2 = (union node *)stalloc(sizeof (struct narg));
9711 n2->narg.text = wordtext;
9712 n2->narg.backquote = backquotelist;
9713 n2->narg.next = NULL;
9716 } while (readtoken() == TNL);
9717 if (lasttoken != TIN)
9718 synerror("expecting \"in\"");
9719 cpp = &n1->ncase.cases;
9720 checkkwd = 2, readtoken();
9722 if (lasttoken == TLP)
9724 *cpp = cp = (union node *)stalloc(sizeof (struct nclist));
9726 app = &cp->nclist.pattern;
9728 *app = ap = (union node *)stalloc(sizeof (struct narg));
9730 ap->narg.text = wordtext;
9731 ap->narg.backquote = backquotelist;
9732 if (checkkwd = 2, readtoken() != TPIPE)
9734 app = &ap->narg.next;
9737 ap->narg.next = NULL;
9738 if (lasttoken != TRP)
9740 cp->nclist.body = list(0);
9743 if ((t = readtoken()) != TESAC) {
9745 synexpect(TENDCASE);
9747 checkkwd = 2, readtoken();
9749 cpp = &cp->nclist.next;
9750 } while(lasttoken != TESAC);
9755 n1 = (union node *)stalloc(sizeof (struct nredir));
9756 n1->type = NSUBSHELL;
9757 n1->nredir.n = list(0);
9758 n1->nredir.redirect = NULL;
9759 if (readtoken() != TRP)
9765 if (readtoken() != TEND)
9769 /* Handle an empty command like other simple commands. */
9778 * An empty command before a ; doesn't make much sense, and
9779 * should certainly be disallowed in the case of `if ;'.
9793 /* Now check for redirection which may follow command */
9794 while (readtoken() == TREDIR) {
9795 *rpp = n2 = redirnode;
9796 rpp = &n2->nfile.next;
9802 if (n1->type != NSUBSHELL) {
9803 n2 = (union node *)stalloc(sizeof (struct nredir));
9808 n1->nredir.redirect = redir;
9817 union node *args, **app;
9818 union node *n = NULL;
9819 union node *vars, **vpp;
9820 union node **rpp, *redir;
9831 switch (readtoken()) {
9834 n = (union node *)stalloc(sizeof (struct narg));
9836 n->narg.text = wordtext;
9837 n->narg.backquote = backquotelist;
9838 if (lasttoken == TWORD) {
9840 app = &n->narg.next;
9843 vpp = &n->narg.next;
9847 *rpp = n = redirnode;
9848 rpp = &n->nfile.next;
9849 parsefname(); /* read name of redirection file */
9853 args && app == &args->narg.next &&
9856 /* We have a function */
9857 if (readtoken() != TRP)
9861 n->narg.next = command();
9874 n = (union node *)stalloc(sizeof (struct ncmd));
9876 n->ncmd.backgnd = 0;
9877 n->ncmd.args = args;
9878 n->ncmd.assign = vars;
9879 n->ncmd.redirect = redir;
9887 n = (union node *)stalloc(sizeof (struct narg));
9889 n->narg.next = NULL;
9890 n->narg.text = wordtext;
9891 n->narg.backquote = backquotelist;
9895 static void fixredir(union node *n, const char *text, int err)
9897 TRACE(("Fix redir %s %d\n", text, err));
9899 n->ndup.vname = NULL;
9901 if (is_digit(text[0]) && text[1] == '\0')
9902 n->ndup.dupfd = digit_val(text[0]);
9903 else if (text[0] == '-' && text[1] == '\0')
9908 synerror("Bad fd number");
9910 n->ndup.vname = makename();
9917 union node *n = redirnode;
9919 if (readtoken() != TWORD)
9921 if (n->type == NHERE) {
9922 struct heredoc *here = heredoc;
9928 TRACE(("Here document %d\n", n->type));
9929 if (here->striptabs) {
9930 while (*wordtext == '\t')
9933 if (! noexpand(wordtext) || (i = strlen(wordtext)) == 0 || i > EOFMARKLEN)
9934 synerror("Illegal eof marker for << redirection");
9935 rmescapes(wordtext);
9936 here->eofmark = wordtext;
9938 if (heredoclist == NULL)
9941 for (p = heredoclist ; p->next ; p = p->next);
9944 } else if (n->type == NTOFD || n->type == NFROMFD) {
9945 fixredir(n, wordtext, 0);
9947 n->nfile.fname = makename();
9953 * Input any here documents.
9958 struct heredoc *here;
9961 while (heredoclist) {
9963 heredoclist = here->next;
9968 readtoken1(pgetc(), here->here->type == NHERE? SQSYNTAX : DQSYNTAX,
9969 here->eofmark, here->striptabs);
9970 n = (union node *)stalloc(sizeof (struct narg));
9971 n->narg.type = NARG;
9972 n->narg.next = NULL;
9973 n->narg.text = wordtext;
9974 n->narg.backquote = backquotelist;
9975 here->here->nhere.doc = n;
9993 int savecheckalias = checkalias;
9994 int savecheckkwd = checkkwd;
9999 int alreadyseen = tokpushback;
10009 checkalias = savecheckalias;
10016 if (checkkwd == 2) {
10025 * check for keywords
10027 if (t == TWORD && !quoteflag)
10029 const char *const *pp;
10031 if ((pp = findkwd(wordtext))) {
10032 lasttoken = t = pp - parsekwd + KWDOFFSET;
10033 TRACE(("keyword %s recognized\n", tokname[t]));
10044 } else if (checkalias == 2 && isassignment(wordtext)) {
10045 lasttoken = t = TASSIGN;
10047 } else if (checkalias) {
10048 if (!quoteflag && (ap = lookupalias(wordtext, 1)) != NULL) {
10050 pushstring(ap->val, strlen(ap->val), ap);
10052 checkkwd = savecheckkwd;
10061 TRACE(("token %s %s\n", tokname[t], t == TWORD || t == TASSIGN ? wordtext : ""));
10063 TRACE(("reread token %s %s\n", tokname[t], t == TWORD || t == TASSIGN ? wordtext : ""));
10070 * Read the next input token.
10071 * If the token is a word, we set backquotelist to the list of cmds in
10072 * backquotes. We set quoteflag to true if any part of the word was
10074 * If the token is TREDIR, then we set redirnode to a structure containing
10076 * In all cases, the variable startlinno is set to the number of the line
10077 * on which the token starts.
10079 * [Change comment: here documents and internal procedures]
10080 * [Readtoken shouldn't have any arguments. Perhaps we should make the
10081 * word parsing code into a separate routine. In this case, readtoken
10082 * doesn't need to have any internal procedures, but parseword does.
10083 * We could also make parseoperator in essence the main routine, and
10084 * have parseword (readtoken1?) handle both words and redirection.]
10087 #define RETURN(token) return lasttoken = token
10101 startlinno = plinno;
10102 for (;;) { /* until token or start of word found */
10105 case ' ': case '\t':
10111 while ((c = pgetc()) != '\n' && c != PEOF);
10115 if (pgetc() == '\n') {
10116 startlinno = ++plinno;
10127 needprompt = doprompt;
10132 if (pgetc() == '&')
10137 if (pgetc() == '|')
10142 if (pgetc() == ';')
10155 return readtoken1(c, BASESYNTAX, (char *)NULL, 0);
10162 * If eofmark is NULL, read a word or a redirection symbol. If eofmark
10163 * is not NULL, read a here document. In the latter case, eofmark is the
10164 * word which marks the end of the document and striptabs is true if
10165 * leading tabs should be stripped from the document. The argument firstc
10166 * is the first character of the input token or document.
10168 * Because C does not have internal subroutines, I have simulated them
10169 * using goto's to implement the subroutine linkage. The following macros
10170 * will run code that appears at the end of readtoken1.
10173 #define CHECKEND() {goto checkend; checkend_return:;}
10174 #define PARSEREDIR() {goto parseredir; parseredir_return:;}
10175 #define PARSESUB() {goto parsesub; parsesub_return:;}
10176 #define PARSEBACKQOLD() {oldstyle = 1; goto parsebackq; parsebackq_oldreturn:;}
10177 #define PARSEBACKQNEW() {oldstyle = 0; goto parsebackq; parsebackq_newreturn:;}
10178 #define PARSEARITH() {goto parsearith; parsearith_return:;}
10181 readtoken1(firstc, syntax, eofmark, striptabs)
10183 char const *syntax;
10190 char line[EOFMARKLEN + 1];
10191 struct nodelist *bqlist;
10194 int varnest; /* levels of variables expansion */
10195 int arinest; /* levels of arithmetic expansion */
10196 int parenlevel; /* levels of parens in arithmetic */
10197 int dqvarnest; /* levels of variables expansion within double quotes */
10199 char const *prevsyntax; /* syntax before arithmetic */
10201 /* Avoid longjmp clobbering */
10207 (void) &parenlevel;
10210 (void) &prevsyntax;
10214 startlinno = plinno;
10216 if (syntax == DQSYNTAX)
10225 STARTSTACKSTR(out);
10226 loop: { /* for each line, until end of word */
10227 CHECKEND(); /* set c to PEOF if at end of here document */
10228 for (;;) { /* until end of line or end of word */
10229 CHECKSTRSPACE(3, out); /* permit 3 calls to USTPUTC */
10230 switch(syntax[c]) {
10231 case CNL: /* '\n' */
10232 if (syntax == BASESYNTAX)
10233 goto endword; /* exit outer loop */
10241 goto loop; /* continue outer loop */
10246 if ((eofmark == NULL || dblquote) &&
10248 USTPUTC(CTLESC, out);
10251 case CBACK: /* backslash */
10254 USTPUTC('\\', out);
10256 } else if (c == '\n') {
10262 if (dblquote && c != '\\' && c != '`' && c != '$'
10263 && (c != '"' || eofmark != NULL))
10264 USTPUTC('\\', out);
10265 if (SQSYNTAX[c] == CCTL)
10266 USTPUTC(CTLESC, out);
10267 else if (eofmark == NULL)
10268 USTPUTC(CTLQUOTEMARK, out);
10274 if (eofmark == NULL)
10275 USTPUTC(CTLQUOTEMARK, out);
10279 if (eofmark == NULL)
10280 USTPUTC(CTLQUOTEMARK, out);
10285 if (eofmark != NULL && arinest == 0 &&
10290 syntax = ARISYNTAX;
10292 } else if (eofmark == NULL &&
10294 syntax = BASESYNTAX;
10300 case CVAR: /* '$' */
10301 PARSESUB(); /* parse substitution */
10303 case CENDVAR: /* '}' */
10306 if (dqvarnest > 0) {
10309 USTPUTC(CTLENDVAR, out);
10314 #ifdef ASH_MATH_SUPPORT
10315 case CLP: /* '(' in arithmetic */
10319 case CRP: /* ')' in arithmetic */
10320 if (parenlevel > 0) {
10324 if (pgetc() == ')') {
10325 if (--arinest == 0) {
10326 USTPUTC(CTLENDARI, out);
10327 syntax = prevsyntax;
10328 if (syntax == DQSYNTAX)
10336 * unbalanced parens
10337 * (don't 2nd guess - no error)
10345 case CBQUOTE: /* '`' */
10349 goto endword; /* exit outer loop */
10354 goto endword; /* exit outer loop */
10365 if (syntax == ARISYNTAX)
10366 synerror("Missing '))'");
10367 if (syntax != BASESYNTAX && ! parsebackquote && eofmark == NULL)
10368 synerror("Unterminated quoted string");
10369 if (varnest != 0) {
10370 startlinno = plinno;
10371 synerror("Missing '}'");
10373 USTPUTC('\0', out);
10374 len = out - stackblock();
10375 out = stackblock();
10376 if (eofmark == NULL) {
10377 if ((c == '>' || c == '<')
10380 && (*out == '\0' || is_digit(*out))) {
10382 return lasttoken = TREDIR;
10387 quoteflag = quotef;
10388 backquotelist = bqlist;
10389 grabstackblock(len);
10391 return lasttoken = TWORD;
10392 /* end of readtoken routine */
10397 * Check to see whether we are at the end of the here document. When this
10398 * is called, c is set to the first character of the next input line. If
10399 * we are at the end of the here document, this routine sets the c to PEOF.
10410 while (c == '\t') {
10414 if (c == *eofmark) {
10415 if (pfgets(line, sizeof line) != NULL) {
10419 for (q = eofmark + 1 ; *q && *p == *q ; p++, q++);
10420 if (*p == '\n' && *q == '\0') {
10423 needprompt = doprompt;
10425 pushstring(line, strlen(line), NULL);
10430 goto checkend_return;
10435 * Parse a redirection operator. The variable "out" points to a string
10436 * specifying the fd to be redirected. The variable "c" contains the
10437 * first character of the redirection operator.
10444 np = (union node *)stalloc(sizeof (struct nfile));
10449 np->type = NAPPEND;
10458 } else { /* c == '<' */
10460 switch (c = pgetc()) {
10462 if (sizeof (struct nfile) != sizeof (struct nhere)) {
10463 np = (union node *)stalloc(sizeof (struct nhere));
10467 heredoc = (struct heredoc *)stalloc(sizeof (struct heredoc));
10468 heredoc->here = np;
10469 if ((c = pgetc()) == '-') {
10470 heredoc->striptabs = 1;
10472 heredoc->striptabs = 0;
10478 np->type = NFROMFD;
10482 np->type = NFROMTO;
10492 np->nfile.fd = digit_val(fd);
10494 goto parseredir_return;
10499 * Parse a substitution. At this point, we have read the dollar sign
10500 * and nothing else.
10508 static const char types[] = "}-+?=";
10513 (c != '(' && c != '{' && !is_name(c) && !is_special(c))
10517 } else if (c == '(') { /* $(command) or $((arith)) */
10518 if (pgetc() == '(') {
10525 USTPUTC(CTLVAR, out);
10526 typeloc = out - stackblock();
10527 USTPUTC(VSNORMAL, out);
10528 subtype = VSNORMAL;
10532 if ((c = pgetc()) == '}')
10535 subtype = VSLENGTH;
10540 if (c > PEOA && is_name(c)) {
10544 } while (c > PEOA && is_in_name(c));
10545 } else if (is_digit(c)) {
10549 } while (is_digit(c));
10551 else if (is_special(c)) {
10556 badsub: synerror("Bad substitution");
10560 if (subtype == 0) {
10567 p = strchr(types, c);
10570 subtype = p - types + VSNORMAL;
10576 subtype = c == '#' ? VSTRIMLEFT :
10589 if (dblquote || arinest)
10591 *(stackblock() + typeloc) = subtype | flags;
10592 if (subtype != VSNORMAL) {
10599 goto parsesub_return;
10604 * Called to parse command substitutions. Newstyle is set if the command
10605 * is enclosed inside $(...); nlpp is a pointer to the head of the linked
10606 * list of commands (passed by reference), and savelen is the number of
10607 * characters on the top of the stack which must be preserved.
10611 struct nodelist **nlpp;
10614 char *volatile str;
10615 struct jmploc jmploc;
10616 struct jmploc *volatile savehandler;
10620 (void) &saveprompt;
10623 savepbq = parsebackquote;
10624 if (setjmp(jmploc.loc)) {
10627 parsebackquote = 0;
10628 handler = savehandler;
10629 longjmp(handler->loc, 1);
10633 savelen = out - stackblock();
10635 str = ckmalloc(savelen);
10636 memcpy(str, stackblock(), savelen);
10638 savehandler = handler;
10642 /* We must read until the closing backquote, giving special
10643 treatment to some slashes, and then push the string and
10644 reread it as input, interpreting it normally. */
10651 STARTSTACKSTR(pout);
10657 switch (pc = pgetc()) {
10662 if ((pc = pgetc()) == '\n') {
10669 * If eating a newline, avoid putting
10670 * the newline into the new character
10671 * stream (via the STPUTC after the
10676 if (pc != '\\' && pc != '`' && pc != '$'
10677 && (!dblquote || pc != '"'))
10678 STPUTC('\\', pout);
10688 startlinno = plinno;
10689 synerror("EOF in backquote substitution");
10693 needprompt = doprompt;
10702 STPUTC('\0', pout);
10703 psavelen = pout - stackblock();
10704 if (psavelen > 0) {
10705 pstr = grabstackstr(pout);
10706 setinputstring(pstr);
10711 nlpp = &(*nlpp)->next;
10712 *nlpp = (struct nodelist *)stalloc(sizeof (struct nodelist));
10713 (*nlpp)->next = NULL;
10714 parsebackquote = oldstyle;
10717 saveprompt = doprompt;
10724 doprompt = saveprompt;
10726 if (readtoken() != TRP)
10733 * Start reading from old file again, ignoring any pushed back
10734 * tokens left from the backquote parsing
10739 while (stackblocksize() <= savelen)
10741 STARTSTACKSTR(out);
10743 memcpy(out, str, savelen);
10744 STADJUST(savelen, out);
10750 parsebackquote = savepbq;
10751 handler = savehandler;
10752 if (arinest || dblquote)
10753 USTPUTC(CTLBACKQ | CTLQUOTE, out);
10755 USTPUTC(CTLBACKQ, out);
10757 goto parsebackq_oldreturn;
10759 goto parsebackq_newreturn;
10763 * Parse an arithmetic expansion (indicate start of one and set state)
10767 if (++arinest == 1) {
10768 prevsyntax = syntax;
10769 syntax = ARISYNTAX;
10770 USTPUTC(CTLARI, out);
10777 * we collapse embedded arithmetic expansion to
10778 * parenthesis, which should be equivalent
10782 goto parsearith_return;
10785 } /* end of readtoken */
10789 * Returns true if the text contains nothing to expand (no dollar signs
10801 while ((c = *p++) != '\0') {
10802 if (c == CTLQUOTEMARK)
10806 else if (BASESYNTAX[(int)c] == CCTL)
10814 * Return true if the argument is a legal variable name (a letter or
10815 * underscore followed by zero or more letters, underscores, and digits).
10819 goodname(const char *name)
10827 if (! is_in_name(*p))
10835 * Called when an unexpected token is read during the parse. The argument
10836 * is the token that is expected, or -1 if more than one type of token can
10837 * occur at this point.
10847 snprintf(msg, 64, "%s unexpected (expecting %s)",
10848 tokname[lasttoken], tokname[token]);
10850 snprintf(msg, 64, "%s unexpected", tokname[lasttoken]);
10858 synerror(const char *msg)
10861 out2fmt("%s: %d: ", commandname, startlinno);
10862 out2fmt("Syntax error: %s\n", msg);
10863 error((char *)NULL);
10869 * called by editline -- any expansions to the prompt
10870 * should be added here.
10873 setprompt(int whichprompt)
10876 switch (whichprompt) {
10891 * Code for dealing with input/output redirection.
10894 #define EMPTY -2 /* marks an unused slot in redirtab */
10896 # define PIPESIZE 4096 /* amount of buffering in a pipe */
10898 # define PIPESIZE PIPE_BUF
10903 * Open a file in noclobber mode.
10904 * The code was copied from bash.
10907 noclobberopen(const char *fname)
10910 struct stat finfo, finfo2;
10913 * If the file exists and is a regular file, return an error
10916 r = stat(fname, &finfo);
10917 if (r == 0 && S_ISREG(finfo.st_mode)) {
10923 * If the file was not present (r != 0), make sure we open it
10924 * exclusively so that if it is created before we open it, our open
10925 * will fail. Make sure that we do not truncate an existing file.
10926 * Note that we don't turn on O_EXCL unless the stat failed -- if the
10927 * file was not a regular file, we leave O_EXCL off.
10930 return open(fname, O_WRONLY|O_CREAT|O_EXCL, 0666);
10931 fd = open(fname, O_WRONLY|O_CREAT, 0666);
10933 /* If the open failed, return the file descriptor right away. */
10938 * OK, the open succeeded, but the file may have been changed from a
10939 * non-regular file to a regular file between the stat and the open.
10940 * We are assuming that the O_EXCL open handles the case where FILENAME
10941 * did not exist and is symlinked to an existing file between the stat
10946 * If we can open it and fstat the file descriptor, and neither check
10947 * revealed that it was a regular file, and the file has not been
10948 * replaced, return the file descriptor.
10950 if (fstat(fd, &finfo2) == 0 && !S_ISREG(finfo2.st_mode) &&
10951 finfo.st_dev == finfo2.st_dev && finfo.st_ino == finfo2.st_ino)
10954 /* The file has been replaced. badness. */
10961 * Handle here documents. Normally we fork off a process to write the
10962 * data to a pipe. If the document is short, we can stuff the data in
10963 * the pipe without forking.
10967 openhere(const union node *redir)
10973 error("Pipe call failed");
10974 if (redir->type == NHERE) {
10975 len = strlen(redir->nhere.doc->narg.text);
10976 if (len <= PIPESIZE) {
10977 xwrite(pip[1], redir->nhere.doc->narg.text, len);
10981 if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) {
10983 signal(SIGINT, SIG_IGN);
10984 signal(SIGQUIT, SIG_IGN);
10985 signal(SIGHUP, SIG_IGN);
10987 signal(SIGTSTP, SIG_IGN);
10989 signal(SIGPIPE, SIG_DFL);
10990 if (redir->type == NHERE)
10991 xwrite(pip[1], redir->nhere.doc->narg.text, len);
10993 expandhere(redir->nhere.doc, pip[1]);
11003 openredirect(const union node *redir)
11008 switch (redir->nfile.type) {
11010 fname = redir->nfile.expfname;
11011 if ((f = open(fname, O_RDONLY)) < 0)
11015 fname = redir->nfile.expfname;
11016 if ((f = open(fname, O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0)
11020 /* Take care of noclobber mode. */
11022 fname = redir->nfile.expfname;
11023 if ((f = noclobberopen(fname)) < 0)
11028 fname = redir->nfile.expfname;
11030 if ((f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
11033 if ((f = creat(fname, 0666)) < 0)
11038 fname = redir->nfile.expfname;
11040 if ((f = open(fname, O_WRONLY|O_CREAT|O_APPEND, 0666)) < 0)
11043 if ((f = open(fname, O_WRONLY)) < 0
11044 && (f = creat(fname, 0666)) < 0)
11046 lseek(f, (off_t)0, 2);
11053 /* Fall through to eliminate warning. */
11060 f = openhere(redir);
11066 error("cannot create %s: %s", fname, errmsg(errno, E_CREAT));
11068 error("cannot open %s: %s", fname, errmsg(errno, E_OPEN));
11073 * Process a list of redirection commands. If the REDIR_PUSH flag is set,
11074 * old file descriptors are stashed away so that the redirection can be
11075 * undone by calling popredir. If the REDIR_BACKQ flag is set, then the
11076 * standard output, and the standard error if it becomes a duplicate of
11081 redirect(union node *redir, int flags)
11084 struct redirtab *sv = NULL;
11089 int fd1dup = flags & REDIR_BACKQ;; /* stdout `cmd` redir to pipe */
11091 if (flags & REDIR_PUSH) {
11092 sv = ckmalloc(sizeof (struct redirtab));
11093 for (i = 0 ; i < 10 ; i++)
11094 sv->renamed[i] = EMPTY;
11095 sv->next = redirlist;
11098 for (n = redir ; n ; n = n->nfile.next) {
11101 if ((n->nfile.type == NTOFD || n->nfile.type == NFROMFD) &&
11102 n->ndup.dupfd == fd)
11103 continue; /* redirect from/to same file descriptor */
11106 newfd = openredirect(n);
11107 if ((flags & REDIR_PUSH) && sv->renamed[fd] == EMPTY) {
11110 } else if ((i = fcntl(fd, F_DUPFD, 10)) == -1) {
11114 dupredirect(n, newfd, fd1dup);
11124 error("%d: %m", fd);
11130 if (flags & REDIR_PUSH) {
11131 sv->renamed[fd] = i;
11134 } else if (fd != newfd) {
11140 dupredirect(n, newfd, fd1dup);
11147 dupredirect(const union node *redir, int f, int fd1dup)
11149 int fd = redir->nfile.fd;
11153 if (redir->nfile.type == NTOFD || redir->nfile.type == NFROMFD) {
11154 if (redir->ndup.dupfd >= 0) { /* if not ">&-" */
11155 if (redir->ndup.dupfd!=1 || fd1dup!=1)
11156 dup_as_newfd(redir->ndup.dupfd, fd);
11162 dup_as_newfd(f, fd);
11171 * Undo the effects of the last redirection.
11177 struct redirtab *rp = redirlist;
11181 for (i = 0 ; i < 10 ; i++) {
11182 if (rp->renamed[i] != EMPTY) {
11186 if (rp->renamed[i] >= 0) {
11187 dup_as_newfd(rp->renamed[i], i);
11188 close(rp->renamed[i]);
11192 redirlist = rp->next;
11198 * Discard all saved file descriptors.
11203 struct redirtab *rp;
11206 for (rp = redirlist ; rp ; rp = rp->next) {
11207 for (i = 0 ; i < 10 ; i++) {
11208 if (rp->renamed[i] >= 0) {
11209 close(rp->renamed[i]);
11211 rp->renamed[i] = EMPTY;
11218 * Copy a file descriptor to be >= to. Returns -1
11219 * if the source file descriptor is closed, EMPTY if there are no unused
11220 * file descriptors left.
11224 dup_as_newfd(from, to)
11230 newfd = fcntl(from, F_DUPFD, to);
11232 if (errno == EMFILE)
11235 error("%d: %m", from);
11240 /*#ifdef __weak_alias
11241 __weak_alias(getmode,_getmode)
11242 __weak_alias(setmode,_setmode)
11246 #if defined(__GLIBC__) && __GLIBC__ >= 2
11247 #define S_ISTXT __S_ISVTX
11249 #define S_ISTXT S_ISVTX
11253 #define SET_LEN 6 /* initial # of bitcmd struct to malloc */
11254 #define SET_LEN_INCR 4 /* # of bitcmd structs to add as needed */
11256 typedef struct bitcmd {
11262 #define CMD2_CLR 0x01
11263 #define CMD2_SET 0x02
11264 #define CMD2_GBITS 0x04
11265 #define CMD2_OBITS 0x08
11266 #define CMD2_UBITS 0x10
11268 static BITCMD *addcmd (BITCMD *, int, int, int, u_int);
11269 static void compress_mode (BITCMD *);
11270 #ifdef SETMODE_DEBUG
11271 static void dumpmode (BITCMD *);
11275 * Given the old mode and an array of bitcmd structures, apply the operations
11276 * described in the bitcmd structures to the old mode, and return the new mode.
11277 * Note that there is no '=' command; a strict assignment is just a '-' (clear
11278 * bits) followed by a '+' (set bits).
11281 getmode(bbox, omode)
11286 mode_t clrval, newmode, value;
11288 _DIAGASSERT(bbox != NULL);
11290 set = (const BITCMD *)bbox;
11292 for (value = 0;; set++)
11295 * When copying the user, group or other bits around, we "know"
11296 * where the bits are in the mode so that we can do shifts to
11297 * copy them around. If we don't use shifts, it gets real
11298 * grundgy with lots of single bit checks and bit sets.
11301 value = (newmode & S_IRWXU) >> 6;
11305 value = (newmode & S_IRWXG) >> 3;
11309 value = newmode & S_IRWXO;
11310 common: if (set->cmd2 & CMD2_CLR) {
11312 (set->cmd2 & CMD2_SET) ? S_IRWXO : value;
11313 if (set->cmd2 & CMD2_UBITS)
11314 newmode &= ~((clrval<<6) & set->bits);
11315 if (set->cmd2 & CMD2_GBITS)
11316 newmode &= ~((clrval<<3) & set->bits);
11317 if (set->cmd2 & CMD2_OBITS)
11318 newmode &= ~(clrval & set->bits);
11320 if (set->cmd2 & CMD2_SET) {
11321 if (set->cmd2 & CMD2_UBITS)
11322 newmode |= (value<<6) & set->bits;
11323 if (set->cmd2 & CMD2_GBITS)
11324 newmode |= (value<<3) & set->bits;
11325 if (set->cmd2 & CMD2_OBITS)
11326 newmode |= value & set->bits;
11331 newmode |= set->bits;
11335 newmode &= ~set->bits;
11339 if (omode & (S_IFDIR|S_IXUSR|S_IXGRP|S_IXOTH))
11340 newmode |= set->bits;
11345 #ifdef SETMODE_DEBUG
11346 (void)printf("getmode:%04o -> %04o\n", omode, newmode);
11352 #define ADDCMD(a, b, c, d) do { \
11353 if (set >= endset) { \
11355 setlen += SET_LEN_INCR; \
11356 newset = realloc(saveset, sizeof(BITCMD) * setlen); \
11357 if (newset == NULL) { \
11361 set = newset + (set - saveset); \
11362 saveset = newset; \
11363 endset = newset + (setlen - 2); \
11365 set = addcmd(set, (a), (b), (c), (d)); \
11366 } while (/*CONSTCOND*/0)
11368 #define STANDARD_BITS (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO)
11376 BITCMD *set, *saveset, *endset;
11377 sigset_t mysigset, sigoset;
11379 int equalopdone = 0; /* pacify gcc */
11380 int permXbits, setlen;
11386 * Get a copy of the mask for the permissions that are mask relative.
11387 * Flip the bits, we want what's not set. Since it's possible that
11388 * the caller is opening files inside a signal handler, protect them
11391 sigfillset(&mysigset);
11392 (void)sigprocmask(SIG_BLOCK, &mysigset, &sigoset);
11393 (void)umask(mask = umask(0));
11395 (void)sigprocmask(SIG_SETMASK, &sigoset, NULL);
11397 setlen = SET_LEN + 2;
11399 if ((set = malloc((u_int)(sizeof(BITCMD) * setlen))) == NULL)
11402 endset = set + (setlen - 2);
11405 * If an absolute number, get it and return; disallow non-octal digits
11408 if (is_digit((unsigned char)*p)) {
11409 perm = (mode_t)strtol(p, &ep, 8);
11410 if (*ep || perm & ~(STANDARD_BITS|S_ISTXT)) {
11414 ADDCMD('=', (STANDARD_BITS|S_ISTXT), perm, mask);
11420 * Build list of structures to set/clear/copy bits as described by
11421 * each clause of the symbolic mode.
11424 /* First, find out which bits might be modified. */
11425 for (who = 0;; ++p) {
11428 who |= STANDARD_BITS;
11431 who |= S_ISUID|S_IRWXU;
11434 who |= S_ISGID|S_IRWXG;
11444 getop: if ((op = *p++) != '+' && op != '-' && op != '=') {
11452 for (perm = 0, permXbits = 0;; ++p) {
11455 perm |= S_IRUSR|S_IRGRP|S_IROTH;
11459 * If specific bits where requested and
11460 * only "other" bits ignore set-id.
11462 if (who == 0 || (who & ~S_IRWXO))
11463 perm |= S_ISUID|S_ISGID;
11467 * If specific bits where requested and
11468 * only "other" bits ignore set-id.
11470 if (who == 0 || (who & ~S_IRWXO)) {
11476 perm |= S_IWUSR|S_IWGRP|S_IWOTH;
11479 permXbits = S_IXUSR|S_IXGRP|S_IXOTH;
11482 perm |= S_IXUSR|S_IXGRP|S_IXOTH;
11488 * When ever we hit 'u', 'g', or 'o', we have
11489 * to flush out any partial mode that we have,
11490 * and then do the copying of the mode bits.
11493 ADDCMD(op, who, perm, mask);
11498 if (op == '+' && permXbits) {
11499 ADDCMD('X', who, permXbits, mask);
11502 ADDCMD(*p, who, op, mask);
11507 * Add any permissions that we haven't already
11510 if (perm || (op == '=' && !equalopdone)) {
11513 ADDCMD(op, who, perm, mask);
11517 ADDCMD('X', who, permXbits, mask);
11531 #ifdef SETMODE_DEBUG
11532 (void)printf("Before compress_mode()\n");
11535 compress_mode(saveset);
11536 #ifdef SETMODE_DEBUG
11537 (void)printf("After compress_mode()\n");
11544 addcmd(set, op, who, oparg, mask)
11551 _DIAGASSERT(set != NULL);
11556 set->bits = who ? who : STANDARD_BITS;
11565 set->bits = (who ? who : mask) & oparg;
11573 set->cmd2 = ((who & S_IRUSR) ? CMD2_UBITS : 0) |
11574 ((who & S_IRGRP) ? CMD2_GBITS : 0) |
11575 ((who & S_IROTH) ? CMD2_OBITS : 0);
11576 set->bits = (mode_t)~0;
11578 set->cmd2 = CMD2_UBITS | CMD2_GBITS | CMD2_OBITS;
11583 set->cmd2 |= CMD2_SET;
11584 else if (oparg == '-')
11585 set->cmd2 |= CMD2_CLR;
11586 else if (oparg == '=')
11587 set->cmd2 |= CMD2_SET|CMD2_CLR;
11593 #ifdef SETMODE_DEBUG
11599 _DIAGASSERT(set != NULL);
11601 for (; set->cmd; ++set)
11602 (void)printf("cmd: '%c' bits %04o%s%s%s%s%s%s\n",
11603 set->cmd, set->bits, set->cmd2 ? " cmd2:" : "",
11604 set->cmd2 & CMD2_CLR ? " CLR" : "",
11605 set->cmd2 & CMD2_SET ? " SET" : "",
11606 set->cmd2 & CMD2_UBITS ? " UBITS" : "",
11607 set->cmd2 & CMD2_GBITS ? " GBITS" : "",
11608 set->cmd2 & CMD2_OBITS ? " OBITS" : "");
11613 * Given an array of bitcmd structures, compress by compacting consecutive
11614 * '+', '-' and 'X' commands into at most 3 commands, one of each. The 'u',
11615 * 'g' and 'o' commands continue to be separate. They could probably be
11616 * compacted, but it's not worth the effort.
11623 int setbits, clrbits, Xbits, op;
11625 _DIAGASSERT(set != NULL);
11627 for (nset = set;;) {
11628 /* Copy over any 'u', 'g' and 'o' commands. */
11629 while ((op = nset->cmd) != '+' && op != '-' && op != 'X') {
11635 for (setbits = clrbits = Xbits = 0;; nset++) {
11636 if ((op = nset->cmd) == '-') {
11637 clrbits |= nset->bits;
11638 setbits &= ~nset->bits;
11639 Xbits &= ~nset->bits;
11640 } else if (op == '+') {
11641 setbits |= nset->bits;
11642 clrbits &= ~nset->bits;
11643 Xbits &= ~nset->bits;
11644 } else if (op == 'X')
11645 Xbits |= nset->bits & ~setbits;
11652 set->bits = clrbits;
11658 set->bits = setbits;
11670 static void shtree (union node *, int, char *, FILE*);
11671 static void shcmd (union node *, FILE *);
11672 static void sharg (union node *, FILE *);
11673 static void indent (int, char *, FILE *);
11674 static void trstring (char *);
11681 trputs("showtree called\n");
11682 shtree(n, 1, NULL, stdout);
11687 shtree(n, ind, pfx, fp)
11693 struct nodelist *lp;
11699 indent(ind, pfx, fp);
11710 shtree(n->nbinary.ch1, ind, NULL, fp);
11713 shtree(n->nbinary.ch2, ind, NULL, fp);
11721 for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
11726 if (n->npipe.backgnd)
11732 fprintf(fp, "<node type %d>", n->type);
11752 for (np = cmd->ncmd.args ; np ; np = np->narg.next) {
11758 for (np = cmd->ncmd.redirect ; np ; np = np->nfile.next) {
11761 switch (np->nfile.type) {
11762 case NTO: s = ">"; dftfd = 1; break;
11763 case NAPPEND: s = ">>"; dftfd = 1; break;
11764 case NTOFD: s = ">&"; dftfd = 1; break;
11765 case NTOOV: s = ">|"; dftfd = 1; break;
11766 case NFROM: s = "<"; dftfd = 0; break;
11767 case NFROMFD: s = "<&"; dftfd = 0; break;
11768 case NFROMTO: s = "<>"; dftfd = 0; break;
11769 default: s = "*error*"; dftfd = 0; break;
11771 if (np->nfile.fd != dftfd)
11772 fprintf(fp, "%d", np->nfile.fd);
11774 if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) {
11775 fprintf(fp, "%d", np->ndup.dupfd);
11777 sharg(np->nfile.fname, fp);
11791 struct nodelist *bqlist;
11794 if (arg->type != NARG) {
11795 printf("<node type %d>\n", arg->type);
11799 bqlist = arg->narg.backquote;
11800 for (p = arg->narg.text ; *p ; p++) {
11809 if (subtype == VSLENGTH)
11815 if (subtype & VSNUL)
11818 switch (subtype & VSTYPE) {
11837 case VSTRIMLEFTMAX:
11844 case VSTRIMRIGHTMAX:
11851 printf("<subtype %d>", subtype);
11858 case CTLBACKQ|CTLQUOTE:
11861 shtree(bqlist->n, -1, NULL, fp);
11873 indent(amount, pfx, fp)
11880 for (i = 0 ; i < amount ; i++) {
11881 if (pfx && i == amount - 1)
11899 static int debug = 1;
11901 static int debug = 0;
11909 if (tracefile == NULL)
11911 putc(c, tracefile);
11917 trace(const char *fmt, ...)
11921 if (tracefile != NULL) {
11922 (void) vfprintf(tracefile, fmt, va);
11923 if (strchr(fmt, '\n'))
11924 (void) fflush(tracefile);
11934 if (tracefile == NULL)
11936 fputs(s, tracefile);
11937 if (strchr(s, '\n'))
11949 if (tracefile == NULL)
11951 putc('"', tracefile);
11952 for (p = s ; *p ; p++) {
11954 case '\n': c = 'n'; goto backslash;
11955 case '\t': c = 't'; goto backslash;
11956 case '\r': c = 'r'; goto backslash;
11957 case '"': c = '"'; goto backslash;
11958 case '\\': c = '\\'; goto backslash;
11959 case CTLESC: c = 'e'; goto backslash;
11960 case CTLVAR: c = 'v'; goto backslash;
11961 case CTLVAR+CTLQUOTE: c = 'V'; goto backslash;
11962 case CTLBACKQ: c = 'q'; goto backslash;
11963 case CTLBACKQ+CTLQUOTE: c = 'Q'; goto backslash;
11964 backslash: putc('\\', tracefile);
11965 putc(c, tracefile);
11968 if (*p >= ' ' && *p <= '~')
11969 putc(*p, tracefile);
11971 putc('\\', tracefile);
11972 putc(*p >> 6 & 03, tracefile);
11973 putc(*p >> 3 & 07, tracefile);
11974 putc(*p & 07, tracefile);
11979 putc('"', tracefile);
11987 if (tracefile == NULL)
11992 putc(' ', tracefile);
11994 putc('\n', tracefile);
12009 #ifdef not_this_way
12012 if ((p = getenv("HOME")) == NULL) {
12013 if (geteuid() == 0)
12019 strcat(s, "/trace");
12022 strcpy(s, "./trace");
12023 #endif /* not_this_way */
12024 if ((tracefile = fopen(s, "a")) == NULL) {
12025 fprintf(stderr, "Can't open %s\n", s);
12029 if ((flags = fcntl(fileno(tracefile), F_GETFL, 0)) >= 0)
12030 fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND);
12032 fputs("\nTracing started.\n", tracefile);
12039 * The trap builtin.
12043 trapcmd(argc, argv)
12052 for (signo = 0 ; signo < NSIG ; signo++) {
12053 if (trap[signo] != NULL) {
12056 p = single_quote(trap[signo]);
12057 printf("trap -- %s %s\n", p,
12058 signal_names[signo] + (signo ? 3 : 0)
12071 if ((signo = decode_signal(*ap, 0)) < 0)
12072 error("%s: bad trap", *ap);
12075 if (action[0] == '-' && action[1] == '\0')
12078 action = savestr(action);
12081 ckfree(trap[signo]);
12082 trap[signo] = action;
12097 * Set the signal handler for the specified signal. The routine figures
12098 * out what it should be set to.
12102 setsignal(int signo)
12106 struct sigaction act;
12108 if ((t = trap[signo]) == NULL)
12110 else if (*t != '\0')
12114 if (rootshell && action == S_DFL) {
12117 if (iflag || minusc || sflag == 0)
12143 t = &sigmode[signo - 1];
12146 * current setting unknown
12148 if (sigaction(signo, 0, &act) == -1) {
12150 * Pretend it worked; maybe we should give a warning
12151 * here, but other shells don't. We don't alter
12152 * sigmode, so that we retry every time.
12156 if (act.sa_handler == SIG_IGN) {
12157 if (mflag && (signo == SIGTSTP ||
12158 signo == SIGTTIN || signo == SIGTTOU)) {
12159 *t = S_IGN; /* don't hard ignore these */
12163 *t = S_RESET; /* force to be set */
12166 if (*t == S_HARD_IGN || *t == action)
12170 act.sa_handler = onsig;
12173 act.sa_handler = SIG_IGN;
12176 act.sa_handler = SIG_DFL;
12180 sigemptyset(&act.sa_mask);
12181 sigaction(signo, &act, 0);
12192 if (sigmode[signo - 1] != S_IGN && sigmode[signo - 1] != S_HARD_IGN) {
12193 signal(signo, SIG_IGN);
12195 sigmode[signo - 1] = S_HARD_IGN;
12206 if (signo == SIGINT && trap[SIGINT] == NULL) {
12210 gotsig[signo - 1] = 1;
12216 * Called to execute a trap. Perhaps we should avoid entering new trap
12217 * handlers while we are executing a trap handler.
12227 for (i = 1 ; ; i++) {
12234 savestatus=exitstatus;
12235 evalstring(trap[i], 0);
12236 exitstatus=savestatus;
12243 * Called to exit the shell.
12247 exitshell(int status)
12249 struct jmploc loc1, loc2;
12252 TRACE(("exitshell(%d) pid=%d\n", status, getpid()));
12253 if (setjmp(loc1.loc)) {
12256 if (setjmp(loc2.loc)) {
12260 if ((p = trap[0]) != NULL && *p != '\0') {
12264 l1: handler = &loc2; /* probably unnecessary */
12273 static int decode_signal(const char *string, int minsig)
12277 if (is_number(string, &signo)) {
12278 if (signo >= NSIG) {
12288 for (; signo < NSIG; signo++) {
12289 if (!strcasecmp(string, &(signal_names[signo])[3])) {
12293 if (!strcasecmp(string, signal_names[signo])) {
12300 static struct var **hashvar (const char *);
12301 static void showvars (const char *, int, int);
12302 static struct var **findvar (struct var **, const char *);
12305 * Initialize the varable symbol tables and import the environment
12309 * This routine initializes the builtin variables. It is called when the
12310 * shell is initialized and again when a shell procedure is spawned.
12315 const struct varinit *ip;
12319 for (ip = varinit ; (vp = ip->var) != NULL ; ip++) {
12320 if ((vp->flags & VEXPORT) == 0) {
12321 vpp = hashvar(ip->text);
12324 vp->text = strdup(ip->text);
12325 vp->flags = ip->flags;
12326 vp->func = ip->func;
12330 * PS1 depends on uid
12332 if ((vps1.flags & VEXPORT) == 0) {
12333 vpp = hashvar("PS1=");
12336 vps1.text = strdup(geteuid() ? "PS1=$ " : "PS1=# ");
12337 vps1.flags = VSTRFIXED|VTEXTFIXED;
12342 * Set the value of a variable. The flags argument is ored with the
12343 * flags of the variable. If val is NULL, the variable is unset.
12347 setvar(name, val, flags)
12348 const char *name, *val;
12364 if (! is_in_name(*p)) {
12365 if (*p == '\0' || *p == '=')
12371 namelen = p - name;
12373 error("%.*s: bad variable name", namelen, name);
12374 len = namelen + 2; /* 2 is space for '=' and '\0' */
12378 len += vallen = strlen(val);
12381 nameeq = ckmalloc(len);
12382 memcpy(nameeq, name, namelen);
12383 nameeq[namelen] = '=';
12385 memcpy(nameeq + namelen + 1, val, vallen + 1);
12387 nameeq[namelen + 1] = '\0';
12389 setvareq(nameeq, flags);
12396 * Same as setvar except that the variable and value are passed in
12397 * the first argument as name=value. Since the first argument will
12398 * be actually stored in the table, it should not be a string that
12407 struct var *vp, **vpp;
12410 flags |= (VEXPORT & (((unsigned) (1 - aflag)) - 1));
12411 if ((vp = *findvar(vpp, s))) {
12412 if (vp->flags & VREADONLY) {
12413 size_t len = strchr(s, '=') - s;
12414 error("%.*s: is read only", len, s);
12418 if (vp->func && (flags & VNOFUNC) == 0)
12419 (*vp->func)(strchr(s, '=') + 1);
12421 if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0)
12424 vp->flags &= ~(VTEXTFIXED|VSTACK|VUNSET);
12425 vp->flags |= flags;
12429 * We could roll this to a function, to handle it as
12430 * a regular variable function callback, but why bother?
12432 if (iflag && (vp == &vmpath || (vp == &vmail && !mpathset())))
12438 vp = ckmalloc(sizeof (*vp));
12449 * Process a linked list of variable assignments.
12454 struct strlist *mylist;
12456 struct strlist *lp;
12459 for (lp = mylist ; lp ; lp = lp->next) {
12460 setvareq(savestr(lp->text), 0);
12468 * Find the value of a variable. Returns NULL if not set.
12471 static const char *
12477 if ((v = *findvar(hashvar(name), name)) && !(v->flags & VUNSET)) {
12478 return strchr(v->text, '=') + 1;
12486 * Search the environment of a builtin command.
12489 static const char *
12490 bltinlookup(const char *name)
12492 const struct strlist *sp;
12494 for (sp = cmdenviron ; sp ; sp = sp->next) {
12495 if (varequal(sp->text, name))
12496 return strchr(sp->text, '=') + 1;
12498 return lookupvar(name);
12504 * Generate a list of exported variables. This routine is used to construct
12505 * the third argument to execve when executing a program.
12517 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
12518 for (vp = *vpp ; vp ; vp = vp->next)
12519 if (vp->flags & VEXPORT)
12522 ep = env = stalloc((nenv + 1) * sizeof *env);
12523 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
12524 for (vp = *vpp ; vp ; vp = vp->next)
12525 if (vp->flags & VEXPORT)
12534 * Called when a shell procedure is invoked to clear out nonexported
12535 * variables. It is also necessary to reallocate variables of with
12536 * VSTACK set since these are currently allocated on the stack.
12542 struct var *vp, **prev;
12544 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
12545 for (prev = vpp ; (vp = *prev) != NULL ; ) {
12546 if ((vp->flags & VEXPORT) == 0) {
12548 if ((vp->flags & VTEXTFIXED) == 0)
12550 if ((vp->flags & VSTRFIXED) == 0)
12553 if (vp->flags & VSTACK) {
12554 vp->text = savestr(vp->text);
12555 vp->flags &=~ VSTACK;
12567 * Command to list all variables which are set. Currently this command
12568 * is invoked from the set command when the set command is called without
12573 showvarscmd(argc, argv)
12577 showvars(nullstr, VUNSET, VUNSET);
12584 * The export and readonly commands.
12588 exportcmd(argc, argv)
12595 int flag = argv[0][0] == 'r'? VREADONLY : VEXPORT;
12598 listsetvar(cmdenviron);
12599 pflag = (nextopt("p") == 'p');
12600 if (argc > 1 && !pflag) {
12601 while ((name = *argptr++) != NULL) {
12602 if ((p = strchr(name, '=')) != NULL) {
12605 if ((vp = *findvar(hashvar(name), name))) {
12610 setvar(name, p, flag);
12614 showvars(argv[0], flag, 0);
12620 * The "local" command.
12623 /* funcnest nonzero if we are currently evaluating a function */
12626 localcmd(argc, argv)
12633 error("Not in a function");
12634 while ((name = *argptr++) != NULL) {
12642 * Make a variable a local variable. When a variable is made local, it's
12643 * value and flags are saved in a localvar structure. The saved values
12644 * will be restored when the shell function returns. We handle the name
12645 * "-" as a special case.
12652 struct localvar *lvp;
12657 lvp = ckmalloc(sizeof (struct localvar));
12658 if (name[0] == '-' && name[1] == '\0') {
12660 p = ckmalloc(sizeof optet_vals);
12661 lvp->text = memcpy(p, optet_vals, sizeof optet_vals);
12664 vpp = hashvar(name);
12665 vp = *findvar(vpp, name);
12667 if (strchr(name, '='))
12668 setvareq(savestr(name), VSTRFIXED);
12670 setvar(name, NULL, VSTRFIXED);
12671 vp = *vpp; /* the new variable */
12673 lvp->flags = VUNSET;
12675 lvp->text = vp->text;
12676 lvp->flags = vp->flags;
12677 vp->flags |= VSTRFIXED|VTEXTFIXED;
12678 if (strchr(name, '='))
12679 setvareq(savestr(name), 0);
12683 lvp->next = localvars;
12690 * Called after a function returns.
12695 struct localvar *lvp;
12698 while ((lvp = localvars) != NULL) {
12699 localvars = lvp->next;
12701 if (vp == NULL) { /* $- saved */
12702 memcpy(optet_vals, lvp->text, sizeof optet_vals);
12704 } else if ((lvp->flags & (VUNSET|VSTRFIXED)) == VUNSET) {
12705 (void)unsetvar(vp->text);
12707 if ((vp->flags & VTEXTFIXED) == 0)
12709 vp->flags = lvp->flags;
12710 vp->text = lvp->text;
12718 setvarcmd(argc, argv)
12723 return unsetcmd(argc, argv);
12724 else if (argc == 3)
12725 setvar(argv[1], argv[2], 0);
12727 error("List assignment not implemented");
12733 * The unset builtin command. We unset the function before we unset the
12734 * variable to allow a function to be unset when there is a readonly variable
12735 * with the same name.
12739 unsetcmd(argc, argv)
12749 while ((i = nextopt("vf")) != '\0') {
12755 if (flg_func == 0 && flg_var == 0)
12758 for (ap = argptr; *ap ; ap++) {
12762 ret |= unsetvar(*ap);
12769 * Unset the specified variable.
12773 unsetvar(const char *s)
12778 vpp = findvar(hashvar(s), s);
12781 if (vp->flags & VREADONLY)
12784 if (*(strchr(vp->text, '=') + 1) != '\0')
12785 setvar(s, nullstr, 0);
12786 vp->flags &= ~VEXPORT;
12787 vp->flags |= VUNSET;
12788 if ((vp->flags & VSTRFIXED) == 0) {
12789 if ((vp->flags & VTEXTFIXED) == 0)
12804 * Find the appropriate entry in the hash table from the name.
12807 static struct var **
12808 hashvar(const char *p)
12810 unsigned int hashval;
12812 hashval = ((unsigned char) *p) << 4;
12813 while (*p && *p != '=')
12814 hashval += (unsigned char) *p++;
12815 return &vartab[hashval % VTABSIZE];
12821 * Returns true if the two strings specify the same varable. The first
12822 * variable name is terminated by '='; the second may be terminated by
12823 * either '=' or '\0'.
12827 varequal(const char *p, const char *q)
12829 while (*p == *q++) {
12833 if (*p == '=' && *(q - 1) == '\0')
12839 showvars(const char *myprefix, int mask, int xor)
12843 const char *sep = myprefix == nullstr ? myprefix : spcstr;
12845 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
12846 for (vp = *vpp ; vp ; vp = vp->next) {
12847 if ((vp->flags & mask) ^ xor) {
12851 p = strchr(vp->text, '=') + 1;
12852 len = p - vp->text;
12853 p = single_quote(p);
12855 printf("%s%s%.*s%s\n", myprefix, sep, len,
12863 static struct var **
12864 findvar(struct var **vpp, const char *name)
12866 for (; *vpp; vpp = &(*vpp)->next) {
12867 if (varequal((*vpp)->text, name)) {
12875 * Copyright (c) 1999 Herbert Xu <herbert@debian.org>
12876 * This file contains code for the times builtin.
12877 * $Id: ash.c,v 1.15 2001/07/31 21:38:23 andersen Exp $
12879 static int timescmd (int argc, char **argv)
12882 long int clk_tck = sysconf(_SC_CLK_TCK);
12885 printf("%dm%fs %dm%fs\n%dm%fs %dm%fs\n",
12886 (int) (buf.tms_utime / clk_tck / 60),
12887 ((double) buf.tms_utime) / clk_tck,
12888 (int) (buf.tms_stime / clk_tck / 60),
12889 ((double) buf.tms_stime) / clk_tck,
12890 (int) (buf.tms_cutime / clk_tck / 60),
12891 ((double) buf.tms_cutime) / clk_tck,
12892 (int) (buf.tms_cstime / clk_tck / 60),
12893 ((double) buf.tms_cstime) / clk_tck);
12898 #ifdef ASH_MATH_SUPPORT
12899 /* The let builtin. */
12900 int letcmd(int argc, char **argv)
12904 char *tmp, *expression, p[13];
12905 expression = strchr(argv[1], '=');
12907 out2fmt("sh: let: syntax error: \"%s\"\n", argv[1]);
12910 *expression = '\0';
12911 tmp = ++expression;
12912 result = arith(tmp);
12914 out2fmt("sh: let: syntax error: \"%s=%s\"\n", argv[1], expression);
12917 snprintf(p, 12, "%ld", result);
12918 setvar(argv[1], savestr(p), 0);
12919 } else if (argc >= 3)
12920 synerror("invalid operand");
12928 * Copyright (c) 1989, 1991, 1993, 1994
12929 * The Regents of the University of California. All rights reserved.
12931 * This code is derived from software contributed to Berkeley by
12932 * Kenneth Almquist.
12934 * Redistribution and use in source and binary forms, with or without
12935 * modification, are permitted provided that the following conditions
12937 * 1. Redistributions of source code must retain the above copyright
12938 * notice, this list of conditions and the following disclaimer.
12939 * 2. Redistributions in binary form must reproduce the above copyright
12940 * notice, this list of conditions and the following disclaimer in the
12941 * documentation and/or other materials provided with the distribution.
12943 * 3. <BSD Advertising Clause omitted per the July 22, 1999 licensing change
12944 * ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change>
12946 * 4. Neither the name of the University nor the names of its contributors
12947 * may be used to endorse or promote products derived from this software
12948 * without specific prior written permission.
12950 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
12951 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
12952 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
12953 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
12954 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
12955 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
12956 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
12957 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
12958 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
12959 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF