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);
1597 static long ash_arith(const char *p);
1598 static int expcmd (int , char **);
1601 static char *trap[NSIG]; /* trap handler commands */
1602 static char sigmode[NSIG - 1]; /* current value of signal */
1603 static char gotsig[NSIG - 1]; /* indicates specified signal received */
1604 static int pendingsigs; /* indicates some signal received */
1607 * This file was generated by the mkbuiltins program.
1611 static int bgcmd (int, char **);
1612 static int fgcmd (int, char **);
1613 static int killcmd (int, char **);
1615 static int bltincmd (int, char **);
1616 static int cdcmd (int, char **);
1617 static int breakcmd (int, char **);
1619 static int commandcmd (int, char **);
1621 static int dotcmd (int, char **);
1622 static int evalcmd (int, char **);
1623 static int execcmd (int, char **);
1624 static int exitcmd (int, char **);
1625 static int exportcmd (int, char **);
1626 static int histcmd (int, char **);
1627 static int hashcmd (int, char **);
1628 static int helpcmd (int, char **);
1629 static int jobscmd (int, char **);
1630 static int localcmd (int, char **);
1632 static int pwdcmd (int, char **);
1634 static int readcmd (int, char **);
1635 static int returncmd (int, char **);
1636 static int setcmd (int, char **);
1637 static int setvarcmd (int, char **);
1638 static int shiftcmd (int, char **);
1639 static int trapcmd (int, char **);
1640 static int umaskcmd (int, char **);
1642 static int aliascmd (int, char **);
1643 static int unaliascmd (int, char **);
1645 static int unsetcmd (int, char **);
1646 static int waitcmd (int, char **);
1647 static int ulimitcmd (int, char **);
1648 static int timescmd (int, char **);
1649 #ifdef ASH_MATH_SUPPORT
1650 static int expcmd (int, char **);
1652 static int typecmd (int, char **);
1654 static int getoptscmd (int, char **);
1657 #ifndef BB_TRUE_FALSE
1658 static int true_main (int, char **);
1659 static int false_main (int, char **);
1662 static void setpwd (const char *, int);
1665 #define BUILTIN_NOSPEC "0"
1666 #define BUILTIN_SPECIAL "1"
1667 #define BUILTIN_REGULAR "2"
1668 #define BUILTIN_ASSIGN "4"
1669 #define BUILTIN_SPEC_ASSG "5"
1670 #define BUILTIN_REG_ASSG "6"
1672 #define IS_BUILTIN_SPECIAL(builtincmd) ((builtincmd)->name[0] & 1)
1673 #define IS_BUILTIN_REGULAR(builtincmd) ((builtincmd)->name[0] & 2)
1674 #define IS_BUILTIN_ASSIGN(builtincmd) ((builtincmd)->name[0] & 4)
1678 int (*const builtinfunc) (int, char **);
1683 /* It is CRUCIAL that this listing be kept in ascii order, otherwise
1684 * the binary search in find_builtin() will stop working. If you value
1685 * your kneecaps, you'll be sure to *make sure* that any changes made
1686 * to this array result in the listing remaining in ascii order. You
1689 static const struct builtincmd builtincmds[] = {
1690 { BUILTIN_SPECIAL ".", dotcmd }, /* first, see declare DOTCMD */
1691 { BUILTIN_SPECIAL ":", true_main },
1693 { BUILTIN_REG_ASSG "alias", aliascmd },
1696 { BUILTIN_REGULAR "bg", bgcmd },
1698 { BUILTIN_SPECIAL "break", breakcmd },
1699 { BUILTIN_SPECIAL "builtin", bltincmd },
1700 { BUILTIN_REGULAR "cd", cdcmd },
1701 { BUILTIN_NOSPEC "chdir", cdcmd },
1703 { BUILTIN_REGULAR "command", commandcmd },
1705 { BUILTIN_SPECIAL "continue", breakcmd },
1706 { BUILTIN_SPECIAL "eval", evalcmd },
1707 { BUILTIN_SPECIAL "exec", execcmd },
1708 { BUILTIN_SPECIAL "exit", exitcmd },
1709 #ifdef ASH_MATH_SUPPORT
1710 { BUILTIN_NOSPEC "exp", expcmd },
1712 { BUILTIN_SPEC_ASSG "export", exportcmd },
1713 { BUILTIN_REGULAR "false", false_main },
1714 { BUILTIN_REGULAR "fc", histcmd },
1716 { BUILTIN_REGULAR "fg", fgcmd },
1719 { BUILTIN_REGULAR "getopts", getoptscmd },
1721 { BUILTIN_NOSPEC "hash", hashcmd },
1722 { BUILTIN_NOSPEC "help", helpcmd },
1723 { BUILTIN_REGULAR "jobs", jobscmd },
1725 { BUILTIN_REGULAR "kill", killcmd },
1727 #ifdef ASH_MATH_SUPPORT
1728 { BUILTIN_NOSPEC "let", expcmd },
1730 { BUILTIN_ASSIGN "local", localcmd },
1732 { BUILTIN_NOSPEC "pwd", pwdcmd },
1734 { BUILTIN_REGULAR "read", readcmd },
1735 { BUILTIN_SPEC_ASSG "readonly", exportcmd },
1736 { BUILTIN_SPECIAL "return", returncmd },
1737 { BUILTIN_SPECIAL "set", setcmd },
1738 { BUILTIN_NOSPEC "setvar", setvarcmd },
1739 { BUILTIN_SPECIAL "shift", shiftcmd },
1740 { BUILTIN_SPECIAL "times", timescmd },
1741 { BUILTIN_SPECIAL "trap", trapcmd },
1742 { BUILTIN_REGULAR "true", true_main },
1743 { BUILTIN_NOSPEC "type", typecmd },
1744 { BUILTIN_NOSPEC "ulimit", ulimitcmd },
1745 { BUILTIN_REGULAR "umask", umaskcmd },
1747 { BUILTIN_REGULAR "unalias", unaliascmd },
1749 { BUILTIN_SPECIAL "unset", unsetcmd },
1750 { BUILTIN_REGULAR "wait", waitcmd },
1752 #define NUMBUILTINS (sizeof (builtincmds) / sizeof (struct builtincmd) )
1754 static const struct builtincmd *DOTCMD = &builtincmds[0];
1755 static struct builtincmd *BLTINCMD;
1756 static struct builtincmd *EXECCMD;
1757 static struct builtincmd *EVALCMD;
1760 #define JOBSTOPPED 1 /* all procs are stopped */
1761 #define JOBDONE 2 /* all procs are completed */
1764 * A job structure contains information about a job. A job is either a
1765 * single process or a set of processes contained in a pipeline. In the
1766 * latter case, pidlist will be non-NULL, and will point to a -1 terminated
1771 pid_t pid; /* process id */
1772 int status; /* status flags (defined above) */
1773 char *cmd; /* text of command being run */
1777 static int job_warning; /* user was warned about stopped jobs */
1780 static void setjobctl(int enable);
1782 #define setjobctl(on) /* do nothing */
1787 struct procstat ps0; /* status of process */
1788 struct procstat *ps; /* status or processes when more than one */
1789 short nprocs; /* number of processes */
1790 short pgrp; /* process group of this job */
1791 char state; /* true if job is finished */
1792 char used; /* true if this entry is in used */
1793 char changed; /* true if status has changed */
1795 char jobctl; /* job running under job control */
1799 static struct job *jobtab; /* array of jobs */
1800 static int njobs; /* size of array */
1801 static int backgndpid = -1; /* pid of last background process */
1803 static int initialpgrp; /* pgrp of shell on invocation */
1804 static int curjob; /* current job */
1807 static int intreceived;
1809 static struct job *makejob (const union node *, int);
1810 static int forkshell (struct job *, const union node *, int);
1811 static int waitforjob (struct job *);
1813 static int docd (char *, int);
1814 static char *getcomponent (void);
1815 static void updatepwd (const char *);
1816 static void getpwd (void);
1818 static char *padvance (const char **, const char *);
1820 static char nullstr[1]; /* zero length string */
1821 static char *curdir = nullstr; /* current working directory */
1822 static char *cdcomppath;
1836 if ((dest = *argptr) == NULL && (dest = bltinlookup("HOME")) == NULL)
1837 error("HOME not set");
1840 if (dest[0] == '-' && dest[1] == '\0') {
1841 dest = bltinlookup("OLDPWD");
1842 if (!dest || !*dest) {
1851 if (*dest == '/' || (path = bltinlookup("CDPATH")) == NULL)
1853 while ((p = padvance(&path, dest)) != NULL) {
1854 if (stat(p, &statb) >= 0 && S_ISDIR(statb.st_mode)) {
1859 if (p[0] == '.' && p[1] == '/' && p[2] != '\0')
1861 print = strcmp(p, dest);
1863 if (docd(p, print) >= 0)
1868 error("can't cd to %s", dest);
1874 * Actually do the chdir. In an interactive shell, print the
1875 * directory name if "print" is nonzero.
1890 TRACE(("docd(\"%s\", %d) called\n", dest, print));
1893 * Check each component of the path. If we find a symlink or
1894 * something we can't stat, clear curdir to force a getcwd()
1895 * next time we get the value of the current directory.
1898 cdcomppath = sstrdup(dest);
1905 while ((q = getcomponent()) != NULL) {
1906 if (q[0] == '\0' || (q[0] == '.' && q[1] == '\0'))
1914 if (equal(component, ".."))
1917 if ((lstat(stackblock(), &statb) < 0)
1918 || (S_ISLNK(statb.st_mode))) {
1926 if (chdir(dest) < 0) {
1930 updatepwd(badstat ? NULL : dest);
1933 printf(snlfmt, curdir);
1939 * Get the next component of the path name pointed to by cdcomppath.
1940 * This routine overwrites the string pointed to by cdcomppath.
1948 if ((p = cdcomppath) == NULL)
1951 while (*p != '/' && *p != '\0')
1965 * Update curdir (the name of the current directory) in response to a
1966 * cd command. We also call hashcd to let the routines in exec.c know
1967 * that the current directory has changed.
1970 static void hashcd (void);
1973 updatepwd(const char *dir)
1979 hashcd(); /* update command hash table */
1982 * If our argument is NULL, we don't know the current directory
1983 * any more because we traversed a symbolic link or something
1984 * we couldn't stat().
1986 if (dir == NULL || curdir == nullstr) {
1991 cdcomppath = sstrdup(dir);
2000 while ((p = getcomponent()) != NULL) {
2001 if (equal(p, "..")) {
2002 while (new > stackblock() && (STUNPUTC(new), *new) != '/');
2003 } else if (*p != '\0' && ! equal(p, ".")) {
2009 if (new == stackblock())
2012 setpwd(stackblock(), 1);
2022 printf(snlfmt, curdir);
2028 * Find out what the current directory is. If we already know the current
2029 * directory, this routine returns immediately.
2034 curdir = xgetcwd(0);
2040 setpwd(const char *val, int setold)
2043 setvar("OLDPWD", curdir, VEXPORT);
2046 if (curdir != nullstr) {
2053 curdir = savestr(val);
2056 setvar("PWD", curdir, VEXPORT);
2060 * Errors and exceptions.
2064 * Code to handle exceptions in C.
2068 * We enclose jmp_buf in a structure so that we can declare pointers to
2069 * jump locations. The global variable handler contains the location to
2070 * jump to when an exception occurs, and the global variable exception
2071 * contains a code identifying the exeception. To implement nested
2072 * exception handlers, the user should save the value of handler on entry
2073 * to an inner scope, set handler to point to a jmploc structure for the
2074 * inner scope, and restore handler on exit from the scope.
2082 #define EXINT 0 /* SIGINT received */
2083 #define EXERROR 1 /* a generic error */
2084 #define EXSHELLPROC 2 /* execute a shell procedure */
2085 #define EXEXEC 3 /* command execution failed */
2087 static struct jmploc *handler;
2088 static int exception;
2090 static void exverror (int, const char *, va_list)
2091 __attribute__((__noreturn__));
2094 * Called to raise an exception. Since C doesn't include exceptions, we
2095 * just do a longjmp to the exception handler. The type of exception is
2096 * stored in the global variable "exception".
2099 static void exraise (int) __attribute__((__noreturn__));
2105 if (handler == NULL)
2110 longjmp(handler->loc, 1);
2115 * Called from trap.c when a SIGINT is received. (If the user specifies
2116 * that SIGINT is to be trapped or ignored using the trap builtin, then
2117 * this routine is not called.) Suppressint is nonzero when interrupts
2118 * are held using the INTOFF macro. The call to _exit is necessary because
2119 * there is a short period after a fork before the signal handlers are
2120 * set to the appropriate value for the child. (The test for iflag is
2121 * just defensive programming.)
2133 sigemptyset(&mysigset);
2134 sigprocmask(SIG_SETMASK, &mysigset, NULL);
2135 if (rootshell && iflag)
2138 signal(SIGINT, SIG_DFL);
2145 static char *commandname; /* currently executing command */
2148 * Exverror is called to raise the error exception. If the first argument
2149 * is not NULL then error prints an error message using printf style
2150 * formatting. It then raises the error exception.
2153 exverror(int cond, const char *msg, va_list ap)
2160 TRACE(("exverror(%d, \"%s\") pid=%d\n", cond, msg, getpid()));
2162 TRACE(("exverror(%d, NULL) pid=%d\n", cond, getpid()));
2166 out2fmt("%s: ", commandname);
2167 vfprintf(stderr, msg, ap);
2176 error(const char *msg, ...)
2180 exverror(EXERROR, msg, ap);
2187 exerror(int cond, const char *msg, ...)
2191 exverror(cond, msg, ap);
2199 * Table of error messages.
2203 short errcode; /* error number */
2204 char action; /* operation which encountered the error */
2208 * Types of operations (passed to the errmsg routine).
2211 #define E_OPEN 01 /* opening a file */
2212 #define E_CREAT 02 /* creating a file */
2213 #define E_EXEC 04 /* executing a program */
2215 #define ALL (E_OPEN|E_CREAT|E_EXEC)
2217 static const struct errname errormsg[] = {
2222 { ENOENT, E_CREAT },
2224 { ENOTDIR, E_OPEN },
2225 { ENOTDIR, E_CREAT },
2226 { ENOTDIR, E_EXEC },
2228 { EEXIST, E_CREAT },
2267 { ELIBACC, E_EXEC },
2271 #define ERRNAME_SIZE (sizeof(errormsg)/sizeof(struct errname))
2274 * Return a string describing an error. The returned string may be a
2275 * pointer to a static buffer that will be overwritten on the next call.
2276 * Action describes the operation that got the error.
2280 errmsg(int e, int action)
2282 struct errname const *ep;
2283 static char buf[12];
2285 for (ep = errormsg ; ep < errormsg+ERRNAME_SIZE; ep++) {
2286 if (ep->errcode == e && (ep->action & action) != 0)
2290 snprintf(buf, sizeof buf, "error %d", e);
2295 #ifdef ASH_OPTIMIZE_FOR_SIZE
2298 if (--suppressint == 0 && intpending) {
2302 static void forceinton (void) {
2309 /* flags in argument to evaltree */
2310 #define EV_EXIT 01 /* exit after evaluating tree */
2311 #define EV_TESTED 02 /* exit status is checked; ignore -e flag */
2312 #define EV_BACKCMD 04 /* command executing within back quotes */
2314 static int evalskip; /* set if we are skipping commands */
2315 static int skipcount; /* number of levels to skip */
2316 static int loopnest; /* current loop nesting level */
2317 static int funcnest; /* depth of function calls */
2320 static struct strlist *cmdenviron; /* environment for builtin command */
2321 static int exitstatus; /* exit status of last command */
2322 static int oexitstatus; /* saved exit status */
2324 static void evalsubshell (const union node *, int);
2325 static void expredir (union node *);
2326 static void prehash (union node *);
2327 static void eprintlist (struct strlist *);
2329 static union node *parsecmd(int);
2331 * Called to reset things after an exception.
2335 * The eval commmand.
2337 static void evalstring (char *, int);
2351 STARTSTACKSTR(concat);
2355 STPUTC(*p++, concat);
2356 if ((p = *ap++) == NULL)
2358 STPUTC(' ', concat);
2360 STPUTC('\0', concat);
2361 p = grabstackstr(concat);
2363 evalstring(p, EV_TESTED);
2369 * Execute a command or commands contained in a string.
2372 static void evaltree (union node *, int);
2373 static void setinputstring (char *);
2374 static void popfile (void);
2375 static void setstackmark(struct stackmark *mark);
2376 static void popstackmark(struct stackmark *mark);
2380 evalstring(char *s, int flag)
2383 struct stackmark smark;
2385 setstackmark(&smark);
2387 while ((n = parsecmd(0)) != NEOF) {
2389 popstackmark(&smark);
2392 popstackmark(&smark);
2395 static struct builtincmd *find_builtin (const char *);
2396 static void expandarg (union node *, struct arglist *, int);
2397 static void calcsize (const union node *);
2398 static union node *copynode (const union node *);
2401 * Make a copy of a parse tree.
2404 static int funcblocksize; /* size of structures in function */
2405 static int funcstringsize; /* size of strings in node */
2406 static pointer funcblock; /* block to allocate function from */
2407 static char *funcstring; /* block to allocate strings from */
2410 static inline union node *
2411 copyfunc(union node *n)
2418 funcblock = ckmalloc(funcblocksize + funcstringsize);
2419 funcstring = (char *) funcblock + funcblocksize;
2424 * Free a parse tree.
2428 freefunc(union node *n)
2436 * Add a new command entry, replacing any existing command entry for
2441 addcmdentry(char *name, struct cmdentry *entry)
2443 struct tblentry *cmdp;
2446 cmdp = cmdlookup(name, 1);
2447 if (cmdp->cmdtype == CMDFUNCTION) {
2448 freefunc(cmdp->param.func);
2450 cmdp->cmdtype = entry->cmdtype;
2451 cmdp->param = entry->u;
2456 evalloop(const union node *n, int flags)
2463 evaltree(n->nbinary.ch1, EV_TESTED);
2465 skipping: if (evalskip == SKIPCONT && --skipcount <= 0) {
2469 if (evalskip == SKIPBREAK && --skipcount <= 0)
2473 if (n->type == NWHILE) {
2474 if (exitstatus != 0)
2477 if (exitstatus == 0)
2480 evaltree(n->nbinary.ch2, flags & EV_TESTED);
2481 status = exitstatus;
2486 exitstatus = status;
2490 evalfor(const union node *n, int flags)
2492 struct arglist arglist;
2495 struct stackmark smark;
2497 setstackmark(&smark);
2498 arglist.lastp = &arglist.list;
2499 for (argp = n->nfor.args ; argp ; argp = argp->narg.next) {
2500 oexitstatus = exitstatus;
2501 expandarg(argp, &arglist, EXP_FULL | EXP_TILDE | EXP_RECORD);
2505 *arglist.lastp = NULL;
2509 for (sp = arglist.list ; sp ; sp = sp->next) {
2510 setvar(n->nfor.var, sp->text, 0);
2511 evaltree(n->nfor.body, flags & EV_TESTED);
2513 if (evalskip == SKIPCONT && --skipcount <= 0) {
2517 if (evalskip == SKIPBREAK && --skipcount <= 0)
2524 popstackmark(&smark);
2528 evalcase(const union node *n, int flags)
2532 struct arglist arglist;
2533 struct stackmark smark;
2535 setstackmark(&smark);
2536 arglist.lastp = &arglist.list;
2537 oexitstatus = exitstatus;
2538 expandarg(n->ncase.expr, &arglist, EXP_TILDE);
2539 for (cp = n->ncase.cases ; cp && evalskip == 0 ; cp = cp->nclist.next) {
2540 for (patp = cp->nclist.pattern ; patp ; patp = patp->narg.next) {
2541 if (casematch(patp, arglist.list->text)) {
2542 if (evalskip == 0) {
2543 evaltree(cp->nclist.body, flags);
2550 popstackmark(&smark);
2554 * Evaluate a pipeline. All the processes in the pipeline are children
2555 * of the process creating the pipeline. (This differs from some versions
2556 * of the shell, which make the last process in a pipeline the parent
2565 struct nodelist *lp;
2570 TRACE(("evalpipe(0x%lx) called\n", (long)n));
2572 for (lp = n->npipe.cmdlist ; lp ; lp = lp->next)
2575 jp = makejob(n, pipelen);
2577 for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
2581 if (pipe(pip) < 0) {
2583 error("Pipe call failed");
2586 if (forkshell(jp, lp->n, n->npipe.backgnd) == 0) {
2590 dup_as_newfd(prevfd, 0);
2602 dup_as_newfd(pip[1], 1);
2606 evaltree(lp->n, EV_EXIT);
2614 if (n->npipe.backgnd == 0) {
2616 exitstatus = waitforjob(jp);
2617 TRACE(("evalpipe: job done exit status %d\n", exitstatus));
2622 static void find_command (const char *, struct cmdentry *, int, const char *);
2625 isassignment(const char *word) {
2626 if (!is_name(*word)) {
2631 } while (is_in_name(*word));
2632 return *word == '=';
2637 evalcommand(union node *cmd, int flags)
2639 struct stackmark smark;
2641 struct arglist arglist;
2642 struct arglist varlist;
2648 struct cmdentry cmdentry;
2650 char *volatile savecmdname;
2651 volatile struct shparam saveparam;
2652 struct localvar *volatile savelocalvars;
2656 const struct builtincmd *firstbltin;
2657 struct jmploc *volatile savehandler;
2658 struct jmploc jmploc;
2660 /* Avoid longjmp clobbering */
2667 /* First expand the arguments. */
2668 TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags));
2669 setstackmark(&smark);
2670 arglist.lastp = &arglist.list;
2671 varlist.lastp = &varlist.list;
2673 oexitstatus = exitstatus;
2676 for (argp = cmd->ncmd.assign; argp; argp = argp->narg.next) {
2677 expandarg(argp, &varlist, EXP_VARTILDE);
2680 argp = cmd->ncmd.args; argp && !arglist.list;
2681 argp = argp->narg.next
2683 expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
2686 struct builtincmd *bcmd;
2688 bcmd = find_builtin(arglist.list->text);
2689 pseudovarflag = bcmd && IS_BUILTIN_ASSIGN(bcmd);
2690 for (; argp; argp = argp->narg.next) {
2691 if (pseudovarflag && isassignment(argp->narg.text)) {
2692 expandarg(argp, &arglist, EXP_VARTILDE);
2695 expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
2698 *arglist.lastp = NULL;
2699 *varlist.lastp = NULL;
2700 expredir(cmd->ncmd.redirect);
2702 for (sp = arglist.list ; sp ; sp = sp->next)
2704 argv = stalloc(sizeof (char *) * (argc + 1));
2706 for (sp = arglist.list ; sp ; sp = sp->next) {
2707 TRACE(("evalcommand arg: %s\n", sp->text));
2712 if (iflag && funcnest == 0 && argc > 0)
2716 /* Print the command if xflag is set. */
2719 eprintlist(varlist.list);
2720 eprintlist(arglist.list);
2724 /* Now locate the command. */
2726 cmdentry.cmdtype = CMDBUILTIN;
2727 firstbltin = cmdentry.u.cmd = BLTINCMD;
2729 const char *oldpath;
2730 int findflag = DO_ERR;
2734 * Modify the command lookup path, if a PATH= assignment
2737 for (sp = varlist.list ; sp ; sp = sp->next)
2738 if (varequal(sp->text, defpathvar)) {
2739 path = sp->text + 5;
2740 findflag |= DO_BRUTE;
2743 oldfindflag = findflag;
2746 find_command(argv[0], &cmdentry, findflag, path);
2747 if (cmdentry.cmdtype == CMDUNKNOWN) { /* command not found */
2751 /* implement bltin and command here */
2752 if (cmdentry.cmdtype != CMDBUILTIN) {
2756 firstbltin = cmdentry.u.cmd;
2758 if (cmdentry.u.cmd == BLTINCMD) {
2760 struct builtincmd *bcmd;
2765 if (!(bcmd = find_builtin(*argv))) {
2766 out2fmt("%s: not found\n", *argv);
2770 cmdentry.u.cmd = bcmd;
2771 if (bcmd != BLTINCMD)
2775 if (cmdentry.u.cmd == find_builtin("command")) {
2780 if (*argv[0] == '-') {
2781 if (!equal(argv[0], "-p")) {
2791 findflag |= DO_BRUTE;
2794 findflag = oldfindflag;
2796 findflag |= DO_NOFUN;
2804 /* Fork off a child process if necessary. */
2805 if (cmd->ncmd.backgnd
2806 || (cmdentry.cmdtype == CMDNORMAL && (flags & EV_EXIT) == 0)
2808 jp = makejob(cmd, 1);
2809 mode = cmd->ncmd.backgnd;
2810 if (forkshell(jp, cmd, mode) != 0)
2811 goto parent; /* at end of routine */
2815 /* This is the child process if a fork occurred. */
2816 /* Execute the command. */
2817 if (cmdentry.cmdtype == CMDFUNCTION) {
2819 trputs("Shell function: "); trargs(argv);
2821 exitstatus = oexitstatus;
2822 redirect(cmd->ncmd.redirect, REDIR_PUSH);
2823 saveparam = shellparam;
2824 shellparam.malloc = 0;
2825 shellparam.nparam = argc - 1;
2826 shellparam.p = argv + 1;
2828 savelocalvars = localvars;
2831 if (setjmp(jmploc.loc)) {
2832 if (exception == EXSHELLPROC) {
2833 freeparam((volatile struct shparam *)
2836 saveparam.optind = shellparam.optind;
2837 saveparam.optoff = shellparam.optoff;
2838 freeparam(&shellparam);
2839 shellparam = saveparam;
2842 localvars = savelocalvars;
2843 handler = savehandler;
2844 longjmp(handler->loc, 1);
2846 savehandler = handler;
2848 for (sp = varlist.list ; sp ; sp = sp->next)
2851 evaltree(cmdentry.u.func, flags & EV_TESTED);
2855 localvars = savelocalvars;
2856 saveparam.optind = shellparam.optind;
2857 saveparam.optoff = shellparam.optoff;
2858 freeparam(&shellparam);
2859 shellparam = saveparam;
2860 handler = savehandler;
2863 if (evalskip == SKIPFUNC) {
2867 if (flags & EV_EXIT)
2868 exitshell(exitstatus);
2869 } else if (cmdentry.cmdtype == CMDBUILTIN) {
2871 trputs("builtin command: "); trargs(argv);
2873 mode = (cmdentry.u.cmd == EXECCMD)? 0 : REDIR_PUSH;
2874 redirect(cmd->ncmd.redirect, mode);
2875 savecmdname = commandname;
2876 if (IS_BUILTIN_SPECIAL(firstbltin)) {
2877 listsetvar(varlist.list);
2879 cmdenviron = varlist.list;
2882 if (setjmp(jmploc.loc)) {
2884 exitstatus = (e == EXINT)? SIGINT+128 : 2;
2887 savehandler = handler;
2889 commandname = argv[0];
2891 optptr = NULL; /* initialize nextopt */
2892 exitstatus = (*cmdentry.u.cmd->builtinfunc)(argc, argv);
2896 if (e != EXSHELLPROC) {
2897 commandname = savecmdname;
2898 if (flags & EV_EXIT)
2899 exitshell(exitstatus);
2901 handler = savehandler;
2903 if ((e != EXERROR && e != EXEXEC)
2904 || cmdentry.u.cmd == BLTINCMD
2905 || cmdentry.u.cmd == DOTCMD
2906 || cmdentry.u.cmd == EVALCMD
2907 || cmdentry.u.cmd == EXECCMD)
2911 if (cmdentry.u.cmd != EXECCMD)
2915 trputs("normal command: "); trargs(argv);
2917 redirect(cmd->ncmd.redirect, 0);
2919 for (sp = varlist.list ; sp ; sp = sp->next)
2920 setvareq(sp->text, VEXPORT|VSTACK);
2921 envp = environment();
2922 shellexec(argv, envp, path, cmdentry.u.index);
2926 parent: /* parent process gets here (if we forked) */
2927 if (mode == 0) { /* argument to fork */
2929 exitstatus = waitforjob(jp);
2935 setvar("_", lastarg, 0);
2936 popstackmark(&smark);
2940 * Evaluate a parse tree. The value is left in the global variable
2950 TRACE(("evaltree(NULL) called\n"));
2953 TRACE(("evaltree(0x%lx: %d) called\n", (long)n, n->type));
2956 evaltree(n->nbinary.ch1, flags & EV_TESTED);
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 evaltree(n->nbinary.ch1, EV_TESTED);
2969 if (evalskip || exitstatus == 0)
2971 evaltree(n->nbinary.ch2, flags);
2974 expredir(n->nredir.redirect);
2975 redirect(n->nredir.redirect, REDIR_PUSH);
2976 evaltree(n->nredir.n, flags);
2980 evalsubshell(n, flags);
2983 evalsubshell(n, flags);
2986 evaltree(n->nif.test, EV_TESTED);
2989 if (exitstatus == 0)
2990 evaltree(n->nif.ifpart, flags);
2991 else if (n->nif.elsepart)
2992 evaltree(n->nif.elsepart, flags);
3008 struct builtincmd *bcmd;
3009 struct cmdentry entry;
3011 (bcmd = find_builtin(n->narg.text)) &&
3012 IS_BUILTIN_SPECIAL(bcmd)
3014 out2fmt("%s is a special built-in\n", n->narg.text);
3018 entry.cmdtype = CMDFUNCTION;
3019 entry.u.func = copyfunc(n->narg.next);
3020 addcmdentry(n->narg.text, &entry);
3025 evaltree(n->nnot.com, EV_TESTED);
3026 exitstatus = !exitstatus;
3034 evalcommand(n, flags);
3039 printf("Node type = %d\n", n->type);
3048 (checkexit && eflag && exitstatus && !(flags & EV_TESTED))
3050 exitshell(exitstatus);
3054 * Kick off a subshell to evaluate a tree.
3058 evalsubshell(const union node *n, int flags)
3061 int backgnd = (n->type == NBACKGND);
3063 expredir(n->nredir.redirect);
3065 if (forkshell(jp, n, backgnd) == 0) {
3067 flags &=~ EV_TESTED;
3068 redirect(n->nredir.redirect, 0);
3069 evaltree(n->nredir.n, flags | EV_EXIT); /* never returns */
3073 exitstatus = waitforjob(jp);
3079 * Compute the names of the files in a redirection list.
3082 static void fixredir(union node *n, const char *text, int err);
3085 expredir(union node *n)
3089 for (redir = n ; redir ; redir = redir->nfile.next) {
3091 fn.lastp = &fn.list;
3092 oexitstatus = exitstatus;
3093 switch (redir->type) {
3099 expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR);
3100 redir->nfile.expfname = fn.list->text;
3104 if (redir->ndup.vname) {
3105 expandarg(redir->ndup.vname, &fn, EXP_FULL | EXP_TILDE);
3106 fixredir(redir, fn.list->text, 1);
3115 * Execute a command inside back quotes. If it's a builtin command, we
3116 * want to save its output in a block obtained from malloc. Otherwise
3117 * we fork off a subprocess and get the output of the command via a pipe.
3118 * Should be called with interrupts off.
3122 evalbackcmd(union node *n, struct backcmd *result)
3126 struct stackmark smark; /* unnecessary */
3128 setstackmark(&smark);
3139 error("Pipe call failed");
3141 if (forkshell(jp, n, FORK_NOJOB) == 0) {
3146 dup_as_newfd(pip[1], 1);
3150 evaltree(n, EV_EXIT);
3153 result->fd = pip[0];
3156 popstackmark(&smark);
3157 TRACE(("evalbackcmd done: fd=%d buf=0x%x nleft=%d jp=0x%x\n",
3158 result->fd, result->buf, result->nleft, result->jp));
3163 * Execute a simple command.
3167 * Search for a command. This is called before we fork so that the
3168 * location of the command will be available in the parent as well as
3169 * the child. The check for "goodname" is an overly conservative
3170 * check that the name will not be subject to expansion.
3177 struct cmdentry entry;
3179 if (n->type == NCMD && n->ncmd.args)
3180 if (goodname(n->ncmd.args->narg.text))
3181 find_command(n->ncmd.args->narg.text, &entry, 0,
3187 * Builtin commands. Builtin commands whose functions are closely
3188 * tied to evaluation are implemented here.
3192 * No command given, or a bltin command with no arguments. Set the
3193 * specified variables.
3197 bltincmd(argc, argv)
3202 * Preserve exitstatus of a previous possible redirection
3210 * Handle break and continue commands. Break, continue, and return are
3211 * all handled by setting the evalskip flag. The evaluation routines
3212 * above all check this flag, and if it is set they start skipping
3213 * commands rather than executing them. The variable skipcount is
3214 * the number of loops to break/continue, or the number of function
3215 * levels to return. (The latter is always 1.) It should probably
3216 * be an error to break out of more loops than exist, but it isn't
3217 * in the standard shell so we don't make it one here.
3221 breakcmd(argc, argv)
3225 int n = argc > 1 ? number(argv[1]) : 1;
3230 evalskip = (**argv == 'c')? SKIPCONT : SKIPBREAK;
3238 * The return command.
3242 returncmd(argc, argv)
3246 int ret = argc > 1 ? number(argv[1]) : oexitstatus;
3249 evalskip = SKIPFUNC;
3254 /* Do what ksh does; skip the rest of the file */
3255 evalskip = SKIPFILE;
3262 #ifndef BB_TRUE_FALSE
3264 false_main(argc, argv)
3273 true_main(argc, argv)
3282 * Controls whether the shell is interactive or not.
3285 static void setsignal(int signo);
3286 static void chkmail(int silent);
3290 setinteractive(int on)
3292 static int is_interactive;
3293 static int do_banner=0;
3295 if (on == is_interactive)
3301 is_interactive = on;
3302 if (do_banner==0 && is_interactive) {
3303 /* Looks like they want an interactive shell */
3304 printf( "\n\n" BB_BANNER " Built-in shell (ash)\n");
3305 printf( "Enter 'help' for a list of built-in commands.\n\n");
3313 setinteractive(iflag);
3326 iflag = 0; /* exit on error */
3329 for (sp = cmdenviron; sp ; sp = sp->next)
3330 setvareq(sp->text, VEXPORT|VSTACK);
3331 shellexec(argv + 1, environment(), pathval(), 0);
3337 eprintlist(struct strlist *sp)
3339 for (; sp; sp = sp->next) {
3340 out2fmt(" %s",sp->text);
3345 * Exec a program. Never returns. If you change this routine, you may
3346 * have to change the find_command routine as well.
3349 static const char *pathopt; /* set by padvance */
3352 shellexec(argv, envp, path, idx)
3353 char **argv, **envp;
3360 if (strchr(argv[0], '/') != NULL) {
3361 tryexec(argv[0], argv, envp);
3365 while ((cmdname = padvance(&path, argv[0])) != NULL) {
3366 if (--idx < 0 && pathopt == NULL) {
3367 tryexec(cmdname, argv, envp);
3368 if (errno != ENOENT && errno != ENOTDIR)
3375 /* Map to POSIX errors */
3387 exerror(EXEXEC, "%s: %s", argv[0], errmsg(e, E_EXEC));
3392 * Clear traps on a fork.
3398 for (tp = trap ; tp < &trap[NSIG] ; tp++) {
3399 if (*tp && **tp) { /* trap not NULL or SIG_IGN */
3404 setsignal(tp - trap);
3412 initshellproc(void) {
3438 /* from options.c: */
3442 for (i = 0; i < NOPTS; i++)
3458 for (sm = sigmode ; sm < sigmode + NSIG - 1; sm++) {
3470 static int preadbuffer(void);
3471 static void pushfile (void);
3474 * Read a character from the script, returning PEOF on end of file.
3475 * Nul characters in the input are silently discarded.
3478 #ifndef ASH_OPTIMIZE_FOR_SIZE
3479 #define pgetc_macro() (--parsenleft >= 0? *parsenextc++ : preadbuffer())
3483 return pgetc_macro();
3489 return --parsenleft >= 0? *parsenextc++ : preadbuffer();
3495 return pgetc_macro();
3501 * Undo the last call to pgetc. Only one character may be pushed back.
3502 * PEOF may be pushed back.
3514 struct parsefile *pf = parsefile;
3523 parsefile = pf->prev;
3525 parsenleft = parsefile->nleft;
3526 parselleft = parsefile->lleft;
3527 parsenextc = parsefile->nextc;
3528 plinno = parsefile->linno;
3534 * Return to top level.
3539 while (parsefile != &basepf)
3544 * Close the file(s) that the shell is reading commands from. Called
3545 * after a fork is done.
3551 if (parsefile->fd > 0) {
3552 close(parsefile->fd);
3559 * Like setinputfile, but takes an open file descriptor. Call this with
3564 setinputfd(fd, push)
3567 (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
3573 while (parsefile->strpush)
3577 if (parsefile->buf == NULL)
3578 parsefile->buf = ckmalloc(BUFSIZ);
3579 parselleft = parsenleft = 0;
3585 * Set the input to take input from a file. If push is set, push the
3586 * old input onto the stack first.
3590 setinputfile(const char *fname, int push)
3596 if ((fd = open(fname, O_RDONLY)) < 0)
3597 error("Can't open %s", fname);
3599 myfileno2 = dup_as_newfd(fd, 10);
3602 error("Out of file descriptors");
3605 setinputfd(fd, push);
3611 tryexec(char *cmd, char **argv, char **envp)
3615 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
3619 #ifdef BB_FEATURE_SH_APPLETS_ALWAYS_WIN
3620 name = get_last_path_component(name);
3623 for(argc_l=0;*argv_l!=NULL; argv_l++, argc_l++)
3626 for(argc_l=0;*argv_l!=NULL; argv_l++, argc_l++)
3628 run_applet_by_name(name, argc_l, argv);
3630 execve(cmd, argv, envp);
3635 setinputfile(cmd, 0);
3636 commandname = arg0 = savestr(argv[0]);
3638 exraise(EXSHELLPROC);
3643 static char *commandtext (const union node *);
3646 * Do a path search. The variable path (passed by reference) should be
3647 * set to the start of the path before the first call; padvance will update
3648 * this value as it proceeds. Successive calls to padvance will return
3649 * the possible path expansions in sequence. If an option (indicated by
3650 * a percent sign) appears in the path entry then the global variable
3651 * pathopt will be set to point to it; otherwise pathopt will be set to
3655 static const char *pathopt;
3657 static void growstackblock(void);
3661 padvance(const char **path, const char *name)
3671 for (p = start ; *p && *p != ':' && *p != '%' ; p++);
3672 len = p - start + strlen(name) + 2; /* "2" is for '/' and '\0' */
3673 while (stackblocksize() < len)
3677 memcpy(q, start, p - start);
3685 while (*p && *p != ':') p++;
3691 return stalloc(len);
3695 * Wrapper around strcmp for qsort/bsearch/...
3698 pstrcmp(const void *a, const void *b)
3700 return strcmp((const char *) a, *(const char *const *) b);
3704 * Find a keyword is in a sorted array.
3707 static const char *const *
3708 findkwd(const char *s)
3710 return bsearch(s, parsekwd, sizeof(parsekwd) / sizeof(const char *),
3711 sizeof(const char *), pstrcmp);
3715 /*** Command hashing code ***/
3723 struct tblentry **pp;
3724 struct tblentry *cmdp;
3727 struct cmdentry entry;
3730 const struct alias *ap;
3734 while ((c = nextopt("rvV")) != '\0') {
3738 } else if (c == 'v' || c == 'V') {
3742 if (*argptr == NULL) {
3743 for (pp = cmdtable ; pp < &cmdtable[CMDTABLESIZE] ; pp++) {
3744 for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) {
3745 if (cmdp->cmdtype != CMDBUILTIN) {
3746 printentry(cmdp, verbose);
3753 while ((name = *argptr++) != NULL) {
3754 if ((cmdp = cmdlookup(name, 0)) != NULL
3755 && (cmdp->cmdtype == CMDNORMAL
3756 || (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0)))
3759 /* Then look at the aliases */
3760 if ((ap = lookupalias(name, 0)) != NULL) {
3762 printf("%s is an alias for %s\n", name, ap->val);
3768 /* First look at the keywords */
3769 if (findkwd(name)!=0) {
3771 printf("%s is a shell keyword\n", name);
3773 printf(snlfmt, name);
3777 find_command(name, &entry, DO_ERR, pathval());
3778 if (entry.cmdtype == CMDUNKNOWN) c = 1;
3780 cmdp = cmdlookup(name, 0);
3781 if (cmdp) printentry(cmdp, verbose=='v');
3789 printentry(cmdp, verbose)
3790 struct tblentry *cmdp;
3797 printf("%s%s", cmdp->cmdname, (verbose ? " is " : ""));
3798 if (cmdp->cmdtype == CMDNORMAL) {
3799 idx = cmdp->param.index;
3802 name = padvance(&path, cmdp->cmdname);
3804 } while (--idx >= 0);
3807 } else if (cmdp->cmdtype == CMDBUILTIN) {
3809 out1str("a shell builtin");
3810 } else if (cmdp->cmdtype == CMDFUNCTION) {
3813 out1str("a function\n");
3814 name = commandtext(cmdp->param.func);
3815 printf("%s() {\n %s\n}", cmdp->cmdname, name);
3821 error("internal error: cmdtype %d", cmdp->cmdtype);
3824 printf(snlfmt, cmdp->rehash ? "*" : nullstr);
3829 /*** List the available builtins ***/
3832 static int helpcmd(int argc, char** argv)
3836 printf("\nBuilt-in commands:\n-------------------\n");
3837 for (col=0, i=0; i < NUMBUILTINS; i++) {
3838 col += printf("%c%s", ((col == 0) ? '\t' : ' '),
3839 builtincmds[i].name+1);
3845 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
3847 extern const struct BB_applet applets[];
3848 extern const size_t NUM_APPLETS;
3850 for (i=0; i < NUM_APPLETS; i++) {
3852 col += printf("%c%s", ((col == 0) ? '\t' : ' '),
3862 return EXIT_SUCCESS;
3866 * Resolve a command name. If you change this routine, you may have to
3867 * change the shellexec routine as well.
3870 static int prefix (const char *, const char *);
3873 find_command(const char *name, struct cmdentry *entry, int act, const char *path)
3875 struct tblentry *cmdp;
3885 struct builtincmd *bcmd;
3887 /* If name contains a slash, don't use the hash table */
3888 if (strchr(name, '/') != NULL) {
3890 while (stat(name, &statb) < 0) {
3891 if (errno != ENOENT && errno != ENOTDIR)
3893 entry->cmdtype = CMDUNKNOWN;
3894 entry->u.index = -1;
3897 entry->cmdtype = CMDNORMAL;
3898 entry->u.index = -1;
3901 entry->cmdtype = CMDNORMAL;
3907 if (act & DO_BRUTE) {
3908 firstchange = path_change(path, &bltin);
3914 /* If name is in the table, and not invalidated by cd, we're done */
3915 if ((cmdp = cmdlookup(name, 0)) != NULL && cmdp->rehash == 0) {
3916 if (cmdp->cmdtype == CMDFUNCTION) {
3917 if (act & DO_NOFUN) {
3922 } else if (act & DO_BRUTE) {
3923 if ((cmdp->cmdtype == CMDNORMAL &&
3924 cmdp->param.index >= firstchange) ||
3925 (cmdp->cmdtype == CMDBUILTIN &&
3926 ((builtinloc < 0 && bltin >= 0) ?
3927 bltin : builtinloc) >= firstchange)) {
3928 /* need to recompute the entry */
3937 bcmd = find_builtin(name);
3938 regular = bcmd && IS_BUILTIN_REGULAR(bcmd);
3941 if (cmdp && (cmdp->cmdtype == CMDBUILTIN)) {
3944 } else if (act & DO_BRUTE) {
3945 if (firstchange == 0) {
3950 /* If %builtin not in path, check for builtin next */
3951 if (regular || (bltin < 0 && bcmd)) {
3954 entry->cmdtype = CMDBUILTIN;
3955 entry->u.cmd = bcmd;
3959 cmdp = cmdlookup(name, 1);
3960 cmdp->cmdtype = CMDBUILTIN;
3961 cmdp->param.cmd = bcmd;
3966 /* We have to search path. */
3967 prev = -1; /* where to start */
3968 if (cmdp && cmdp->rehash) { /* doing a rehash */
3969 if (cmdp->cmdtype == CMDBUILTIN)
3972 prev = cmdp->param.index;
3978 while ((fullname = padvance(&path, name)) != NULL) {
3979 stunalloc(fullname);
3981 if (idx >= firstchange) {
3985 if (prefix("builtin", pathopt)) {
3986 if ((bcmd = find_builtin(name))) {
3990 } else if (!(act & DO_NOFUN) &&
3991 prefix("func", pathopt)) {
3994 continue; /* ignore unimplemented options */
3997 /* if rehash, don't redo absolute path names */
3998 if (fullname[0] == '/' && idx <= prev &&
3999 idx < firstchange) {
4002 TRACE(("searchexec \"%s\": no change\n", name));
4005 while (stat(fullname, &statb) < 0) {
4006 if (errno != ENOENT && errno != ENOTDIR)
4010 e = EACCES; /* if we fail, this will be the error */
4011 if (!S_ISREG(statb.st_mode))
4013 if (pathopt) { /* this is a %func directory */
4014 stalloc(strlen(fullname) + 1);
4015 readcmdfile(fullname);
4016 if ((cmdp = cmdlookup(name, 0)) == NULL || cmdp->cmdtype != CMDFUNCTION)
4017 error("%s not defined in %s", name, fullname);
4018 stunalloc(fullname);
4021 TRACE(("searchexec \"%s\" returns \"%s\"\n", name, fullname));
4022 /* If we aren't called with DO_BRUTE and cmdp is set, it must
4023 be a function and we're being called with DO_NOFUN */
4025 entry->cmdtype = CMDNORMAL;
4026 entry->u.index = idx;
4030 cmdp = cmdlookup(name, 1);
4031 cmdp->cmdtype = CMDNORMAL;
4032 cmdp->param.index = idx;
4037 /* We failed. If there was an entry for this command, delete it */
4038 if (cmdp && updatetbl)
4041 out2fmt("%s: %s\n", name, errmsg(e, E_EXEC));
4042 entry->cmdtype = CMDUNKNOWN;
4047 entry->cmdtype = cmdp->cmdtype;
4048 entry->u = cmdp->param;
4054 * Search the table of builtin commands.
4058 bstrcmp(const void *name, const void *b)
4060 return strcmp((const char *)name, (*(const char *const *) b)+1);
4063 static struct builtincmd *
4064 find_builtin(const char *name)
4066 struct builtincmd *bp;
4068 bp = bsearch(name, builtincmds, NUMBUILTINS, sizeof(struct builtincmd),
4076 * Called when a cd is done. Marks all commands so the next time they
4077 * are executed they will be rehashed.
4082 struct tblentry **pp;
4083 struct tblentry *cmdp;
4085 for (pp = cmdtable ; pp < &cmdtable[CMDTABLESIZE] ; pp++) {
4086 for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) {
4087 if (cmdp->cmdtype == CMDNORMAL
4088 || (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0))
4097 * Called before PATH is changed. The argument is the new value of PATH;
4098 * pathval() still returns the old value at this point. Called with
4103 changepath(const char *newval)
4108 firstchange = path_change(newval, &bltin);
4109 if (builtinloc < 0 && bltin >= 0)
4110 builtinloc = bltin; /* zap builtins */
4111 clearcmdentry(firstchange);
4117 * Clear out command entries. The argument specifies the first entry in
4118 * PATH which has changed.
4122 clearcmdentry(firstchange)
4125 struct tblentry **tblp;
4126 struct tblentry **pp;
4127 struct tblentry *cmdp;
4130 for (tblp = cmdtable ; tblp < &cmdtable[CMDTABLESIZE] ; tblp++) {
4132 while ((cmdp = *pp) != NULL) {
4133 if ((cmdp->cmdtype == CMDNORMAL &&
4134 cmdp->param.index >= firstchange)
4135 || (cmdp->cmdtype == CMDBUILTIN &&
4136 builtinloc >= firstchange)) {
4149 * Delete all functions.
4154 struct tblentry **tblp;
4155 struct tblentry **pp;
4156 struct tblentry *cmdp;
4159 for (tblp = cmdtable ; tblp < &cmdtable[CMDTABLESIZE] ; tblp++) {
4161 while ((cmdp = *pp) != NULL) {
4162 if (cmdp->cmdtype == CMDFUNCTION) {
4164 freefunc(cmdp->param.func);
4177 * Locate a command in the command hash table. If "add" is nonzero,
4178 * add the command to the table if it is not already present. The
4179 * variable "lastcmdentry" is set to point to the address of the link
4180 * pointing to the entry, so that delete_cmd_entry can delete the
4184 static struct tblentry **lastcmdentry;
4186 static struct tblentry *
4187 cmdlookup(const char *name, int add)
4191 struct tblentry *cmdp;
4192 struct tblentry **pp;
4199 pp = &cmdtable[hashval % CMDTABLESIZE];
4200 for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) {
4201 if (equal(cmdp->cmdname, name))
4205 if (add && cmdp == NULL) {
4207 cmdp = *pp = ckmalloc(sizeof (struct tblentry) - ARB
4208 + strlen(name) + 1);
4210 cmdp->cmdtype = CMDUNKNOWN;
4212 strcpy(cmdp->cmdname, name);
4220 * Delete the command entry returned on the last lookup.
4224 delete_cmd_entry() {
4225 struct tblentry *cmdp;
4228 cmdp = *lastcmdentry;
4229 *lastcmdentry = cmdp->next;
4238 static const short nodesize[26] = {
4239 ALIGN(sizeof (struct nbinary)),
4240 ALIGN(sizeof (struct ncmd)),
4241 ALIGN(sizeof (struct npipe)),
4242 ALIGN(sizeof (struct nredir)),
4243 ALIGN(sizeof (struct nredir)),
4244 ALIGN(sizeof (struct nredir)),
4245 ALIGN(sizeof (struct nbinary)),
4246 ALIGN(sizeof (struct nbinary)),
4247 ALIGN(sizeof (struct nif)),
4248 ALIGN(sizeof (struct nbinary)),
4249 ALIGN(sizeof (struct nbinary)),
4250 ALIGN(sizeof (struct nfor)),
4251 ALIGN(sizeof (struct ncase)),
4252 ALIGN(sizeof (struct nclist)),
4253 ALIGN(sizeof (struct narg)),
4254 ALIGN(sizeof (struct narg)),
4255 ALIGN(sizeof (struct nfile)),
4256 ALIGN(sizeof (struct nfile)),
4257 ALIGN(sizeof (struct nfile)),
4258 ALIGN(sizeof (struct nfile)),
4259 ALIGN(sizeof (struct nfile)),
4260 ALIGN(sizeof (struct ndup)),
4261 ALIGN(sizeof (struct ndup)),
4262 ALIGN(sizeof (struct nhere)),
4263 ALIGN(sizeof (struct nhere)),
4264 ALIGN(sizeof (struct nnot)),
4270 * Delete a function if it exists.
4274 unsetfunc(char *name)
4276 struct tblentry *cmdp;
4278 if ((cmdp = cmdlookup(name, 0)) != NULL && cmdp->cmdtype == CMDFUNCTION) {
4279 freefunc(cmdp->param.func);
4286 * Locate and print what a word is...
4290 typecmd(int argc, char **argv)
4298 for (i = 1; i < argc; i++) {
4299 argv_a[0] = argv[i];
4302 err |= hashcmd(argc, argv);
4309 commandcmd(argc, argv)
4314 int default_path = 0;
4315 int verify_only = 0;
4316 int verbose_verify_only = 0;
4318 while ((c = nextopt("pvV")) != '\0')
4327 verbose_verify_only = 1;
4331 if (default_path + verify_only + verbose_verify_only > 1 ||
4334 "command [-p] command [arg ...]\n"
4335 "command {-v|-V} command\n");
4339 if (verify_only || verbose_verify_only) {
4343 argv_a[0] = *argptr;
4345 optptr = verbose_verify_only ? "v" : "V"; /* reverse special */
4346 return hashcmd(argc, argv);
4354 path_change(newval, bltin)
4358 const char *old, *new;
4364 firstchange = 9999; /* assume no change */
4370 if ((*old == '\0' && *new == ':')
4371 || (*old == ':' && *new == '\0'))
4373 old = new; /* ignore subsequent differences */
4377 if (*new == '%' && *bltin < 0 && prefix("builtin", new + 1))
4384 if (builtinloc >= 0 && *bltin < 0)
4389 * Routines to expand arguments to commands. We have to deal with
4390 * backquotes, shell variables, and file metacharacters.
4395 #define RMESCAPE_ALLOC 0x1 /* Allocate a new string */
4396 #define RMESCAPE_GLOB 0x2 /* Add backslashes for glob */
4399 * Structure specifying which parts of the string should be searched
4400 * for IFS characters.
4404 struct ifsregion *next; /* next region in list */
4405 int begoff; /* offset of start of region */
4406 int endoff; /* offset of end of region */
4407 int nulonly; /* search for nul bytes only */
4411 static char *expdest; /* output of current string */
4412 static struct nodelist *argbackq; /* list of back quote expressions */
4413 static struct ifsregion ifsfirst; /* first struct in list of ifs regions */
4414 static struct ifsregion *ifslastp; /* last struct in list */
4415 static struct arglist exparg; /* holds expanded arg list */
4417 static void argstr (char *, int);
4418 static char *exptilde (char *, int);
4419 static void expbackq (union node *, int, int);
4420 static int subevalvar (char *, char *, int, int, int, int, int);
4421 static int varisset (char *, int);
4422 static void strtodest (const char *, const char *, int);
4423 static void varvalue (char *, int, int);
4424 static void recordregion (int, int, int);
4425 static void removerecordregions (int);
4426 static void ifsbreakup (char *, struct arglist *);
4427 static void ifsfree (void);
4428 static void expandmeta (struct strlist *, int);
4429 #if defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN)
4430 #define preglob(p) _rmescapes((p), RMESCAPE_ALLOC | RMESCAPE_GLOB)
4431 #if !defined(GLOB_BROKEN)
4432 static void addglob (const glob_t *);
4435 #if !(defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN))
4436 static void expmeta (char *, char *);
4438 #if !(defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN))
4439 static struct strlist *expsort (struct strlist *);
4440 static struct strlist *msort (struct strlist *, int);
4442 static int patmatch (char *, char *, int);
4443 #if defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN)
4444 static int patmatch2 (char *, char *, int);
4446 static int pmatch (char *, char *, int);
4447 #define patmatch2 patmatch
4449 static char *cvtnum (int, char *);
4452 * Expand shell variables and backquotes inside a here document.
4455 /* arg: the document, fd: where to write the expanded version */
4457 expandhere(union node *arg, int fd)
4460 expandarg(arg, (struct arglist *)NULL, 0);
4461 xwrite(fd, stackblock(), expdest - stackblock());
4466 * Perform variable substitution and command substitution on an argument,
4467 * placing the resulting list of arguments in arglist. If EXP_FULL is true,
4468 * perform splitting and file name expansion. When arglist is NULL, perform
4469 * here document expansion.
4473 expandarg(arg, arglist, flag)
4475 struct arglist *arglist;
4481 argbackq = arg->narg.backquote;
4482 STARTSTACKSTR(expdest);
4483 ifsfirst.next = NULL;
4485 argstr(arg->narg.text, flag);
4486 if (arglist == NULL) {
4487 return; /* here document expanded */
4489 STPUTC('\0', expdest);
4490 p = grabstackstr(expdest);
4491 exparg.lastp = &exparg.list;
4495 if (flag & EXP_FULL) {
4496 ifsbreakup(p, &exparg);
4497 *exparg.lastp = NULL;
4498 exparg.lastp = &exparg.list;
4499 expandmeta(exparg.list, flag);
4501 if (flag & EXP_REDIR) /*XXX - for now, just remove escapes */
4503 sp = (struct strlist *)stalloc(sizeof (struct strlist));
4506 exparg.lastp = &sp->next;
4509 *exparg.lastp = NULL;
4511 *arglist->lastp = exparg.list;
4512 arglist->lastp = exparg.lastp;
4518 * Expand a variable, and return a pointer to the next character in the
4522 static inline char *
4538 int quotes = flag & (EXP_FULL | EXP_CASE);
4541 subtype = varflags & VSTYPE;
4546 p = strchr(p, '=') + 1;
4547 again: /* jump here after setting a variable with ${var=text} */
4549 set = varisset(var, varflags & VSNUL);
4552 val = lookupvar(var);
4553 if (val == NULL || ((varflags & VSNUL) && val[0] == '\0')) {
4560 startloc = expdest - stackblock();
4561 if (set && subtype != VSPLUS) {
4562 /* insert the value of the variable */
4564 varvalue(var, varflags & VSQUOTE, flag);
4565 if (subtype == VSLENGTH) {
4566 varlen = expdest - stackblock() - startloc;
4567 STADJUST(-varlen, expdest);
4570 if (subtype == VSLENGTH) {
4571 varlen = strlen(val);
4575 varflags & VSQUOTE ?
4576 DQSYNTAX : BASESYNTAX,
4583 if (subtype == VSPLUS)
4586 easy = ((varflags & VSQUOTE) == 0 ||
4587 (*var == '@' && shellparam.nparam != 1));
4592 expdest = cvtnum(varlen, expdest);
4599 recordregion(startloc, expdest - stackblock(),
4600 varflags & VSQUOTE);
4616 case VSTRIMRIGHTMAX:
4620 * Terminate the string and start recording the pattern
4623 STPUTC('\0', expdest);
4624 patloc = expdest - stackblock();
4625 if (subevalvar(p, NULL, patloc, subtype,
4626 startloc, varflags, quotes) == 0) {
4627 int amount = (expdest - stackblock() - patloc) + 1;
4628 STADJUST(-amount, expdest);
4630 /* Remove any recorded regions beyond start of variable */
4631 removerecordregions(startloc);
4637 if (subevalvar(p, var, 0, subtype, startloc,
4638 varflags, quotes)) {
4641 * Remove any recorded regions beyond
4644 removerecordregions(startloc);
4659 if (subtype != VSNORMAL) { /* skip to end of alternative */
4662 if ((c = *p++) == CTLESC)
4664 else if (c == CTLBACKQ || c == (CTLBACKQ|CTLQUOTE)) {
4666 argbackq = argbackq->next;
4667 } else if (c == CTLVAR) {
4668 if ((*p++ & VSTYPE) != VSNORMAL)
4670 } else if (c == CTLENDVAR) {
4681 * Perform variable and command substitution. If EXP_FULL is set, output CTLESC
4682 * characters to allow for further processing. Otherwise treat
4683 * $@ like $* since no splitting will be performed.
4692 int quotes = flag & (EXP_FULL | EXP_CASE); /* do CTLESC */
4695 if (*p == '~' && (flag & (EXP_TILDE | EXP_VARTILDE)))
4696 p = exptilde(p, flag);
4700 case CTLENDVAR: /* ??? */
4703 /* "$@" syntax adherence hack */
4704 if (p[0] == CTLVAR && p[2] == '@' && p[3] == '=')
4706 if ((flag & EXP_FULL) != 0)
4716 p = evalvar(p, flag);
4719 case CTLBACKQ|CTLQUOTE:
4720 expbackq(argbackq->n, c & CTLQUOTE, flag);
4721 argbackq = argbackq->next;
4723 #ifdef ASH_MATH_SUPPORT
4731 * sort of a hack - expand tildes in variable
4732 * assignments (after the first '=' and after ':'s).
4735 if (flag & EXP_VARTILDE && *p == '~') {
4742 p = exptilde(p, flag);
4758 char c, *startp = p;
4761 int quotes = flag & (EXP_FULL | EXP_CASE);
4763 while ((c = *p) != '\0') {
4770 if (flag & EXP_VARTILDE)
4780 if (*(startp+1) == '\0') {
4781 if ((home = lookupvar("HOME")) == NULL)
4784 if ((pw = getpwnam(startp+1)) == NULL)
4791 strtodest(home, SQSYNTAX, quotes);
4800 removerecordregions(int endoff)
4802 if (ifslastp == NULL)
4805 if (ifsfirst.endoff > endoff) {
4806 while (ifsfirst.next != NULL) {
4807 struct ifsregion *ifsp;
4809 ifsp = ifsfirst.next->next;
4810 ckfree(ifsfirst.next);
4811 ifsfirst.next = ifsp;
4814 if (ifsfirst.begoff > endoff)
4817 ifslastp = &ifsfirst;
4818 ifsfirst.endoff = endoff;
4823 ifslastp = &ifsfirst;
4824 while (ifslastp->next && ifslastp->next->begoff < endoff)
4825 ifslastp=ifslastp->next;
4826 while (ifslastp->next != NULL) {
4827 struct ifsregion *ifsp;
4829 ifsp = ifslastp->next->next;
4830 ckfree(ifslastp->next);
4831 ifslastp->next = ifsp;
4834 if (ifslastp->endoff > endoff)
4835 ifslastp->endoff = endoff;
4839 #ifdef ASH_MATH_SUPPORT
4841 * Expand arithmetic expression. Backup to start of expression,
4842 * evaluate, place result in (backed up) result, adjust string position.
4850 int quotes = flag & (EXP_FULL | EXP_CASE);
4856 * This routine is slightly over-complicated for
4857 * efficiency. First we make sure there is
4858 * enough space for the result, which may be bigger
4859 * than the expression if we add exponentation. Next we
4860 * scan backwards looking for the start of arithmetic. If the
4861 * next previous character is a CTLESC character, then we
4862 * have to rescan starting from the beginning since CTLESC
4863 * characters have to be processed left to right.
4865 CHECKSTRSPACE(10, expdest);
4866 USTPUTC('\0', expdest);
4867 start = stackblock();
4869 while (*p != CTLARI && p >= start)
4872 error("missing CTLARI (shouldn't happen)");
4873 if (p > start && *(p-1) == CTLESC)
4874 for (p = start; *p != CTLARI; p++)
4883 removerecordregions(begoff);
4886 result = ash_arith(p+2);
4887 snprintf(p, 12, "%d", result);
4893 recordregion(begoff, p - 1 - start, 0);
4894 result = expdest - p + 1;
4895 STADJUST(-result, expdest);
4900 * Expand stuff in backwards quotes.
4904 expbackq(cmd, quoted, flag)
4909 volatile struct backcmd in;
4913 char *dest = expdest;
4914 volatile struct ifsregion saveifs;
4915 struct ifsregion *volatile savelastp;
4916 struct nodelist *volatile saveargbackq;
4918 int startloc = dest - stackblock();
4919 char const *syntax = quoted? DQSYNTAX : BASESYNTAX;
4920 volatile int saveherefd;
4921 int quotes = flag & (EXP_FULL | EXP_CASE);
4922 struct jmploc jmploc;
4923 struct jmploc *volatile savehandler;
4927 /* Avoid longjmp clobbering */
4938 savelastp = ifslastp;
4939 saveargbackq = argbackq;
4940 saveherefd = herefd;
4942 if ((ex = setjmp(jmploc.loc))) {
4945 savehandler = handler;
4948 p = grabstackstr(dest);
4949 evalbackcmd(cmd, (struct backcmd *) &in);
4950 ungrabstackstr(p, dest);
4954 ifslastp = savelastp;
4955 argbackq = saveargbackq;
4956 herefd = saveherefd;
4964 if (--in.nleft < 0) {
4967 i = safe_read(in.fd, buf, sizeof buf);
4968 TRACE(("expbackq: read returns %d\n", i));
4975 if (lastc != '\0') {
4976 if (quotes && syntax[(int)lastc] == CCTL)
4977 STPUTC(CTLESC, dest);
4978 STPUTC(lastc, dest);
4982 /* Eat all trailing newlines */
4983 for (; dest > stackblock() && dest[-1] == '\n';)
4992 exitstatus = waitforjob(in.jp);
4993 handler = savehandler;
4995 longjmp(handler->loc, 1);
4998 recordregion(startloc, dest - stackblock(), 0);
4999 TRACE(("evalbackq: size=%d: \"%.*s\"\n",
5000 (dest - stackblock()) - startloc,
5001 (dest - stackblock()) - startloc,
5002 stackblock() + startloc));
5008 subevalvar(p, str, strloc, subtype, startloc, varflags, quotes)
5021 int saveherefd = herefd;
5022 struct nodelist *saveargbackq = argbackq;
5026 argstr(p, subtype != VSASSIGN && subtype != VSQUESTION ? EXP_CASE : 0);
5027 STACKSTRNUL(expdest);
5028 herefd = saveherefd;
5029 argbackq = saveargbackq;
5030 startp = stackblock() + startloc;
5032 str = stackblock() + strloc;
5036 setvar(str, startp, 0);
5037 amount = startp - expdest;
5038 STADJUST(amount, expdest);
5045 if (*p != CTLENDVAR) {
5046 out2fmt(snlfmt, startp);
5047 error((char *)NULL);
5049 error("%.*s: parameter %snot set", p - str - 1,
5050 str, (varflags & VSNUL) ? "null or "
5055 for (loc = startp; loc < str; loc++) {
5058 if (patmatch2(str, startp, quotes))
5061 if (quotes && *loc == CTLESC)
5067 for (loc = str - 1; loc >= startp;) {
5070 if (patmatch2(str, startp, quotes))
5074 if (quotes && loc > startp && *(loc - 1) == CTLESC) {
5075 for (q = startp; q < loc; q++)
5085 for (loc = str - 1; loc >= startp;) {
5086 if (patmatch2(str, loc, quotes))
5089 if (quotes && loc > startp && *(loc - 1) == CTLESC) {
5090 for (q = startp; q < loc; q++)
5099 case VSTRIMRIGHTMAX:
5100 for (loc = startp; loc < str - 1; loc++) {
5101 if (patmatch2(str, loc, quotes))
5103 if (quotes && *loc == CTLESC)
5116 amount = ((str - 1) - (loc - startp)) - expdest;
5117 STADJUST(amount, expdest);
5118 while (loc != str - 1)
5123 amount = loc - expdest;
5124 STADJUST(amount, expdest);
5125 STPUTC('\0', expdest);
5126 STADJUST(-1, expdest);
5132 * Test whether a specialized variable is set.
5136 varisset(name, nulok)
5141 return backgndpid != -1;
5142 else if (*name == '@' || *name == '*') {
5143 if (*shellparam.p == NULL)
5149 for (av = shellparam.p; *av; av++)
5154 } else if (is_digit(*name)) {
5156 int num = atoi(name);
5158 if (num > shellparam.nparam)
5164 ap = shellparam.p[num - 1];
5166 if (nulok && (ap == NULL || *ap == '\0'))
5173 * Put a string on the stack.
5177 strtodest(p, syntax, quotes)
5183 if (quotes && syntax[(int) *p] == CCTL)
5184 STPUTC(CTLESC, expdest);
5185 STPUTC(*p++, expdest);
5190 * Add the value of a specialized variable to the stack string.
5194 varvalue(name, quoted, flags)
5206 int allow_split = flags & EXP_FULL;
5207 int quotes = flags & (EXP_FULL | EXP_CASE);
5209 syntax = quoted ? DQSYNTAX : BASESYNTAX;
5218 num = shellparam.nparam;
5223 expdest = cvtnum(num, expdest);
5226 for (i = 0 ; i < NOPTS ; i++) {
5228 STPUTC(optent_letter(optlist[i]), expdest);
5232 if (allow_split && quoted) {
5233 sep = 1 << CHAR_BIT;
5238 sep = ifsset() ? ifsval()[0] : ' ';
5240 sepq = syntax[(int) sep] == CCTL;
5243 for (ap = shellparam.p ; (p = *ap++) != NULL ; ) {
5244 strtodest(p, syntax, quotes);
5247 STPUTC(CTLESC, expdest);
5248 STPUTC(sep, expdest);
5253 strtodest(arg0, syntax, quotes);
5257 if (num > 0 && num <= shellparam.nparam) {
5258 strtodest(shellparam.p[num - 1], syntax, quotes);
5266 * Record the fact that we have to scan this region of the
5267 * string for IFS characters.
5271 recordregion(start, end, nulonly)
5276 struct ifsregion *ifsp;
5278 if (ifslastp == NULL) {
5282 ifsp = (struct ifsregion *)ckmalloc(sizeof (struct ifsregion));
5284 ifslastp->next = ifsp;
5288 ifslastp->begoff = start;
5289 ifslastp->endoff = end;
5290 ifslastp->nulonly = nulonly;
5296 * Break the argument string into pieces based upon IFS and add the
5297 * strings to the argument list. The regions of the string to be
5298 * searched for IFS characters have been stored by recordregion.
5301 ifsbreakup(string, arglist)
5303 struct arglist *arglist;
5305 struct ifsregion *ifsp;
5310 const char *ifs, *realifs;
5318 realifs = ifsset() ? ifsval() : defifs;
5319 if (ifslastp != NULL) {
5322 p = string + ifsp->begoff;
5323 nulonly = ifsp->nulonly;
5324 ifs = nulonly ? nullstr : realifs;
5326 while (p < string + ifsp->endoff) {
5330 if (strchr(ifs, *p)) {
5332 ifsspc = (strchr(defifs, *p) != NULL);
5333 /* Ignore IFS whitespace at start */
5334 if (q == start && ifsspc) {
5340 sp = (struct strlist *)stalloc(sizeof *sp);
5342 *arglist->lastp = sp;
5343 arglist->lastp = &sp->next;
5347 if (p >= string + ifsp->endoff) {
5353 if (strchr(ifs, *p) == NULL ) {
5356 } else if (strchr(defifs, *p) == NULL) {
5372 } while ((ifsp = ifsp->next) != NULL);
5373 if (!(*start || (!ifsspc && start > string && nulonly))) {
5378 sp = (struct strlist *)stalloc(sizeof *sp);
5380 *arglist->lastp = sp;
5381 arglist->lastp = &sp->next;
5387 while (ifsfirst.next != NULL) {
5388 struct ifsregion *ifsp;
5390 ifsp = ifsfirst.next->next;
5391 ckfree(ifsfirst.next);
5392 ifsfirst.next = ifsp;
5396 ifsfirst.next = NULL;
5400 * Add a file name to the list.
5404 addfname(const char *name)
5410 sp = (struct strlist *)stalloc(sizeof *sp);
5413 exparg.lastp = &sp->next;
5417 * Expand shell metacharacters. At this point, the only control characters
5418 * should be escapes. The results are stored in the list exparg.
5421 #if defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN)
5423 expandmeta(str, flag)
5424 struct strlist *str;
5429 /* TODO - EXP_REDIR */
5434 p = preglob(str->text);
5436 switch (glob(p, GLOB_NOMAGIC, 0, &pglob)) {
5438 if (!(pglob.gl_flags & GLOB_MAGCHAR))
5449 *exparg.lastp = str;
5450 rmescapes(str->text);
5451 exparg.lastp = &str->next;
5453 default: /* GLOB_NOSPACE */
5454 error("Out of space");
5462 * Add the result of glob(3) to the list.
5467 const glob_t *pglob;
5469 char **p = pglob->gl_pathv;
5477 #else /* defined(__GLIBC__) && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN) */
5478 static char *expdir;
5482 expandmeta(str, flag)
5483 struct strlist *str;
5487 struct strlist **savelastp;
5490 /* TODO - EXP_REDIR */
5496 for (;;) { /* fast check for meta chars */
5497 if ((c = *p++) == '\0')
5499 if (c == '*' || c == '?' || c == '[' || c == '!')
5502 savelastp = exparg.lastp;
5504 if (expdir == NULL) {
5505 int i = strlen(str->text);
5506 expdir = ckmalloc(i < 2048 ? 2048 : i); /* XXX */
5509 expmeta(expdir, str->text);
5513 if (exparg.lastp == savelastp) {
5518 *exparg.lastp = str;
5519 rmescapes(str->text);
5520 exparg.lastp = &str->next;
5522 *exparg.lastp = NULL;
5523 *savelastp = sp = expsort(*savelastp);
5524 while (sp->next != NULL)
5526 exparg.lastp = &sp->next;
5534 * Do metacharacter (i.e. *, ?, [...]) expansion.
5538 expmeta(enddir, name)
5556 for (p = name ; ; p++) {
5557 if (*p == '*' || *p == '?')
5559 else if (*p == '[') {
5564 while (*q == CTLQUOTEMARK)
5568 if (*q == '/' || *q == '\0')
5575 } else if (*p == '!' && p[1] == '!' && (p == name || p[-1] == '/')) {
5577 } else if (*p == '\0')
5579 else if (*p == CTLQUOTEMARK)
5581 else if (*p == CTLESC)
5589 if (metaflag == 0) { /* we've reached the end of the file name */
5590 if (enddir != expdir)
5592 for (p = name ; ; p++) {
5593 if (*p == CTLQUOTEMARK)
5601 if (metaflag == 0 || lstat(expdir, &statb) >= 0)
5606 if (start != name) {
5609 while (*p == CTLQUOTEMARK)
5616 if (enddir == expdir) {
5618 } else if (enddir == expdir + 1 && *expdir == '/') {
5624 if ((dirp = opendir(cp)) == NULL)
5626 if (enddir != expdir)
5628 if (*endname == 0) {
5636 while (*p == CTLQUOTEMARK)
5642 while (! int_pending() && (dp = readdir(dirp)) != NULL) {
5643 if (dp->d_name[0] == '.' && ! matchdot)
5645 if (patmatch(start, dp->d_name, 0)) {
5647 strcpy(enddir, dp->d_name);
5650 for (p = enddir, cp = dp->d_name;
5651 (*p++ = *cp++) != '\0';)
5654 expmeta(p, endname);
5662 #endif /* defined(__GLIBC__) && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN) */
5666 #if !(defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN))
5668 * Sort the results of file name expansion. It calculates the number of
5669 * strings to sort and then calls msort (short for merge sort) to do the
5673 static struct strlist *
5675 struct strlist *str;
5681 for (sp = str ; sp ; sp = sp->next)
5683 return msort(str, len);
5687 static struct strlist *
5689 struct strlist *list;
5692 struct strlist *p, *q = NULL;
5693 struct strlist **lpp;
5701 for (n = half ; --n >= 0 ; ) {
5705 q->next = NULL; /* terminate first half of list */
5706 q = msort(list, half); /* sort first half of list */
5707 p = msort(p, len - half); /* sort second half */
5710 if (strcmp(p->text, q->text) < 0) {
5713 if ((p = *lpp) == NULL) {
5720 if ((q = *lpp) == NULL) {
5733 * Returns true if the pattern matches the string.
5736 #if defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN)
5737 /* squoted: string might have quote chars */
5739 patmatch(char *pattern, char *string, int squoted)
5744 p = preglob(pattern);
5745 q = squoted ? _rmescapes(string, RMESCAPE_ALLOC) : string;
5747 return !fnmatch(p, q, 0);
5752 patmatch2(char *pattern, char *string, int squoted)
5758 p = grabstackstr(expdest);
5759 res = patmatch(pattern, string, squoted);
5760 ungrabstackstr(p, expdest);
5765 patmatch(char *pattern, char *string, int squoted) {
5766 return pmatch(pattern, string, squoted);
5771 pmatch(char *pattern, char *string, int squoted)
5783 if (squoted && *q == CTLESC)
5791 if (squoted && *q == CTLESC)
5798 while (c == CTLQUOTEMARK || c == '*')
5800 if (c != CTLESC && c != CTLQUOTEMARK &&
5801 c != '?' && c != '*' && c != '[') {
5803 if (squoted && *q == CTLESC &&
5808 if (squoted && *q == CTLESC)
5814 if (pmatch(p, q, squoted))
5816 if (squoted && *q == CTLESC)
5818 } while (*q++ != '\0');
5829 while (*endp == CTLQUOTEMARK)
5832 goto dft; /* no matching ] */
5833 if (*endp == CTLESC)
5845 if (squoted && chr == CTLESC)
5851 if (c == CTLQUOTEMARK)
5855 if (*p == '-' && p[1] != ']') {
5857 while (*p == CTLQUOTEMARK)
5861 if (chr >= c && chr <= *p)
5868 } while ((c = *p++) != ']');
5869 if (found == invert)
5874 if (squoted && *q == CTLESC)
5891 * Remove any CTLESC characters from a string.
5894 #if defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN)
5896 _rmescapes(char *str, int flag)
5899 static const char qchars[] = { CTLESC, CTLQUOTEMARK, 0 };
5901 p = strpbrk(str, qchars);
5907 if (flag & RMESCAPE_ALLOC) {
5908 size_t len = p - str;
5909 q = r = stalloc(strlen(p) + len + 1);
5911 memcpy(q, str, len);
5916 if (*p == CTLQUOTEMARK) {
5922 if (flag & RMESCAPE_GLOB && *p != '/') {
5939 while (*p != CTLESC && *p != CTLQUOTEMARK) {
5945 if (*p == CTLQUOTEMARK) {
5960 * See if a pattern matches in a case statement.
5964 casematch(union node *pattern, const char *val)
5966 struct stackmark smark;
5970 setstackmark(&smark);
5971 argbackq = pattern->narg.backquote;
5972 STARTSTACKSTR(expdest);
5974 argstr(pattern->narg.text, EXP_TILDE | EXP_CASE);
5975 STPUTC('\0', expdest);
5976 p = grabstackstr(expdest);
5977 result = patmatch(p, (char *)val, 0);
5978 popstackmark(&smark);
5993 CHECKSTRSPACE(32, buf);
5994 len = sprintf(buf, "%d", num);
5999 * Editline and history functions (and glue).
6001 static int histcmd(argc, argv)
6005 error("not compiled with history support");
6011 struct redirtab *next;
6012 short renamed[10]; /* Current ash support only 0-9 descriptors */
6013 /* char renamed[10]; */ /* char on arm (and others) can't be negative */
6016 static struct redirtab *redirlist;
6018 extern char **environ;
6023 * Initialization code.
6036 basepf.nextc = basepf.buf = basebuf;
6045 for (envp = environ ; *envp ; envp++) {
6046 if (strchr(*envp, '=')) {
6047 setvareq(*envp, VEXPORT|VTEXTFIXED);
6051 snprintf(ppid, sizeof(ppid), "%d", (int) getppid());
6052 setvar("PPID", ppid, 0);
6059 * This routine is called when an error or an interrupt occurs in an
6060 * interactive shell and control is returned to the main command loop.
6063 /* 1 == check for aliases, 2 == also check for assignments */
6064 static int checkalias; /* also used in no alias mode for check assignments */
6078 if (exception != EXSHELLPROC)
6079 parselleft = parsenleft = 0; /* clear input buffer */
6083 /* from parser.c: */
6101 * This file implements the input routines used by the parser.
6104 #ifdef BB_FEATURE_COMMAND_EDITING
6105 static const char * cmdedit_prompt;
6106 static inline void putprompt(const char *s) {
6110 static inline void putprompt(const char *s) {
6115 #define EOF_NLEFT -99 /* value of parsenleft when EOF pushed back */
6120 * Same as pgetc(), but ignores PEOA.
6130 } while (c == PEOA);
6134 static inline int pgetc2() { return pgetc_macro(); }
6138 * Read a line from the script.
6141 static inline char *
6142 pfgets(char *line, int len)
6148 while (--nleft > 0) {
6167 char *buf = parsefile->buf;
6171 #ifdef BB_FEATURE_COMMAND_EDITING
6174 nr = safe_read(parsefile->fd, buf, BUFSIZ - 1);
6176 nr = cmdedit_read_input((char*)cmdedit_prompt, buf);
6180 nr = safe_read(parsefile->fd, buf, BUFSIZ - 1);
6184 if (parsefile->fd == 0 && errno == EWOULDBLOCK) {
6185 int flags = fcntl(0, F_GETFL, 0);
6186 if (flags >= 0 && flags & O_NONBLOCK) {
6187 flags &=~ O_NONBLOCK;
6188 if (fcntl(0, F_SETFL, flags) >= 0) {
6189 out2str("sh: turning off NDELAY mode\n");
6201 struct strpush *sp = parsefile->strpush;
6206 if (parsenextc[-1] == ' ' || parsenextc[-1] == '\t') {
6211 if (sp->string != sp->ap->val) {
6215 sp->ap->flag &= ~ALIASINUSE;
6216 if (sp->ap->flag & ALIASDEAD) {
6217 unalias(sp->ap->name);
6221 parsenextc = sp->prevstring;
6222 parsenleft = sp->prevnleft;
6223 /*dprintf("*** calling popstring: restoring to '%s'\n", parsenextc);*/
6224 parsefile->strpush = sp->prev;
6225 if (sp != &(parsefile->basestrpush))
6232 * Refill the input buffer and return the next input character:
6234 * 1) If a string was pushed back on the input, pop it;
6235 * 2) If an EOF was pushed back (parsenleft == EOF_NLEFT) or we are reading
6236 * from a string so we can't refill the buffer, return EOF.
6237 * 3) If the is more stuff in this buffer, use it else call read to fill it.
6238 * 4) Process input up to the next newline, deleting nul characters.
6248 while (parsefile->strpush) {
6250 if (parsenleft == -1 && parsefile->strpush->ap &&
6251 parsenextc[-1] != ' ' && parsenextc[-1] != '\t') {
6256 if (--parsenleft >= 0)
6257 return (*parsenextc++);
6259 if (parsenleft == EOF_NLEFT || parsefile->buf == NULL)
6264 if (parselleft <= 0) {
6265 if ((parselleft = preadfd()) <= 0) {
6266 parselleft = parsenleft = EOF_NLEFT;
6273 /* delete nul characters */
6274 for (more = 1; more;) {
6282 parsenleft = q - parsenextc;
6283 more = 0; /* Stop processing here */
6289 if (--parselleft <= 0 && more) {
6290 parsenleft = q - parsenextc - 1;
6301 out2str(parsenextc);
6306 return *parsenextc++;
6311 * Push a string back onto the input at this current parsefile level.
6312 * We handle aliases this way.
6315 pushstring(char *s, int len, void *ap)
6320 /*dprintf("*** calling pushstring: %s, %d\n", s, len);*/
6321 if (parsefile->strpush) {
6322 sp = ckmalloc(sizeof (struct strpush));
6323 sp->prev = parsefile->strpush;
6324 parsefile->strpush = sp;
6326 sp = parsefile->strpush = &(parsefile->basestrpush);
6327 sp->prevstring = parsenextc;
6328 sp->prevnleft = parsenleft;
6330 sp->ap = (struct alias *)ap;
6332 ((struct alias *)ap)->flag |= ALIASINUSE;
6343 * Like setinputfile, but takes input from a string.
6347 setinputstring(char *string)
6351 parsenextc = string;
6352 parsenleft = strlen(string);
6353 parsefile->buf = NULL;
6361 * To handle the "." command, a stack of input files is used. Pushfile
6362 * adds a new entry to the stack and popfile restores the previous level.
6367 struct parsefile *pf;
6369 parsefile->nleft = parsenleft;
6370 parsefile->lleft = parselleft;
6371 parsefile->nextc = parsenextc;
6372 parsefile->linno = plinno;
6373 pf = (struct parsefile *)ckmalloc(sizeof (struct parsefile));
6374 pf->prev = parsefile;
6377 pf->basestrpush.prev = NULL;
6382 static void restartjob (struct job *);
6384 static void freejob (struct job *);
6385 static struct job *getjob (const char *);
6386 static int dowait (int, struct job *);
6387 static void waitonint(int);
6391 * We keep track of whether or not fd0 has been redirected. This is for
6392 * background commands, where we want to redirect fd0 to /dev/null only
6393 * if it hasn't already been redirected.
6395 static int fd0_redirected = 0;
6397 /* Return true if fd 0 has already been redirected at least once. */
6399 fd0_redirected_p () {
6400 return fd0_redirected != 0;
6403 static void dupredirect (const union node *, int, int fd1dup);
6407 * Turn job control on and off.
6409 * Note: This code assumes that the third arg to ioctl is a character
6410 * pointer, which is true on Berkeley systems but not System V. Since
6411 * System V doesn't have job control yet, this isn't a problem now.
6416 static void setjobctl(int enable)
6418 #ifdef OLD_TTY_DRIVER
6422 if (enable == jobctl || rootshell == 0)
6425 do { /* while we are in the background */
6426 #ifdef OLD_TTY_DRIVER
6427 if (ioctl(2, TIOCGPGRP, (char *)&initialpgrp) < 0) {
6429 initialpgrp = tcgetpgrp(2);
6430 if (initialpgrp < 0) {
6432 out2str("sh: can't access tty; job control turned off\n");
6436 if (initialpgrp == -1)
6437 initialpgrp = getpgrp();
6438 else if (initialpgrp != getpgrp()) {
6439 killpg(initialpgrp, SIGTTIN);
6443 #ifdef OLD_TTY_DRIVER
6444 if (ioctl(2, TIOCGETD, (char *)&ldisc) < 0 || ldisc != NTTYDISC) {
6445 out2str("sh: need new tty driver to run job control; job control turned off\n");
6453 setpgid(0, rootpid);
6454 #ifdef OLD_TTY_DRIVER
6455 ioctl(2, TIOCSPGRP, (char *)&rootpid);
6457 tcsetpgrp(2, rootpid);
6459 } else { /* turning job control off */
6460 setpgid(0, initialpgrp);
6461 #ifdef OLD_TTY_DRIVER
6462 ioctl(2, TIOCSPGRP, (char *)&initialpgrp);
6464 tcsetpgrp(2, initialpgrp);
6475 /* A translation list so we can be polite to our users. */
6476 static char *signal_names[NSIG + 2] = {
6564 "Usage: kill [-s sigspec | -signum | -sigspec] [pid | job]... or\n"
6565 "kill -l [exitstatus]"
6569 if (*argv[1] == '-') {
6570 signo = decode_signal(argv[1] + 1, 1);
6574 while ((c = nextopt("ls:")) != '\0')
6580 signo = decode_signal(optionarg, 1);
6583 "invalid signal number or name: %s",
6591 "nextopt returned character code 0%o", c);
6598 if (!list && signo < 0)
6601 if ((signo < 0 || !*argptr) ^ list) {
6608 for (i = 1; i < NSIG; i++) {
6609 printf(snlfmt, signal_names[i] + 3);
6613 signo = atoi(*argptr);
6616 if (0 < signo && signo < NSIG)
6617 printf(snlfmt, signal_names[signo] + 3);
6619 error("invalid signal number or exit status: %s",
6625 if (**argptr == '%') {
6626 jp = getjob(*argptr);
6627 if (jp->jobctl == 0)
6628 error("job %s not created under job control",
6630 pid = -jp->ps[0].pid;
6632 pid = atoi(*argptr);
6633 if (kill(pid, signo) != 0)
6634 error("%s: %m", *argptr);
6635 } while (*++argptr);
6649 jp = getjob(argv[1]);
6650 if (jp->jobctl == 0)
6651 error("job not created under job control");
6652 pgrp = jp->ps[0].pid;
6653 #ifdef OLD_TTY_DRIVER
6654 ioctl(2, TIOCSPGRP, (char *)&pgrp);
6660 status = waitforjob(jp);
6674 jp = getjob(*++argv);
6675 if (jp->jobctl == 0)
6676 error("job not created under job control");
6678 } while (--argc > 1);
6687 struct procstat *ps;
6690 if (jp->state == JOBDONE)
6693 killpg(jp->ps[0].pid, SIGCONT);
6694 for (ps = jp->ps, i = jp->nprocs ; --i >= 0 ; ps++) {
6695 if (WIFSTOPPED(ps->status)) {
6704 static void showjobs(int change);
6718 * Print a list of jobs. If "change" is nonzero, only print jobs whose
6719 * statuses have changed since the last call to showjobs.
6721 * If the shell is interrupted in the process of creating a job, the
6722 * result may be a job structure containing zero processes. Such structures
6723 * will be freed here.
6734 struct procstat *ps;
6738 TRACE(("showjobs(%d) called\n", change));
6739 while (dowait(0, (struct job *)NULL) > 0);
6740 for (jobno = 1, jp = jobtab ; jobno <= njobs ; jobno++, jp++) {
6743 if (jp->nprocs == 0) {
6747 if (change && ! jp->changed)
6749 procno = jp->nprocs;
6750 for (ps = jp->ps ; ; ps++) { /* for each process */
6752 snprintf(s, 64, "[%d] %ld ", jobno,
6755 snprintf(s, 64, " %ld ",
6760 if (ps->status == -1) {
6761 /* don't print anything */
6762 } else if (WIFEXITED(ps->status)) {
6763 snprintf(s, 64, "Exit %d",
6764 WEXITSTATUS(ps->status));
6767 if (WIFSTOPPED(ps->status))
6768 i = WSTOPSIG(ps->status);
6769 else /* WIFSIGNALED(ps->status) */
6771 i = WTERMSIG(ps->status);
6772 if ((i & 0x7F) < NSIG && sys_siglist[i & 0x7F])
6773 strcpy(s, sys_siglist[i & 0x7F]);
6775 snprintf(s, 64, "Signal %d", i & 0x7F);
6776 if (WCOREDUMP(ps->status))
6777 strcat(s, " (core dumped)");
6782 "%*c%s\n", 30 - col >= 0 ? 30 - col : 0, ' ',
6789 if (jp->state == JOBDONE) {
6797 * Mark a job structure as unused.
6801 freejob(struct job *jp)
6803 const struct procstat *ps;
6807 for (i = jp->nprocs, ps = jp->ps ; --i >= 0 ; ps++) {
6808 if (ps->cmd != nullstr)
6811 if (jp->ps != &jp->ps0)
6815 if (curjob == jp - jobtab + 1)
6834 job = getjob(*++argv);
6838 for (;;) { /* loop until process terminated or stopped */
6841 status = job->ps[job->nprocs - 1].status;
6847 if (WIFEXITED(status))
6848 retval = WEXITSTATUS(status);
6850 else if (WIFSTOPPED(status))
6851 retval = WSTOPSIG(status) + 128;
6854 /* XXX: limits number of signals */
6855 retval = WTERMSIG(status) + 128;
6860 for (jp = jobtab ; ; jp++) {
6861 if (jp >= jobtab + njobs) { /* no running procs */
6864 if (jp->used && jp->state == 0)
6868 if (dowait(2, 0) < 0 && errno == EINTR) {
6877 * Convert a job name to a job structure.
6881 getjob(const char *name)
6891 if ((jobno = curjob) == 0 || jobtab[jobno - 1].used == 0)
6892 error("No current job");
6893 return &jobtab[jobno - 1];
6895 error("No current job");
6897 } else if (name[0] == '%') {
6898 if (is_digit(name[1])) {
6899 jobno = number(name + 1);
6900 if (jobno > 0 && jobno <= njobs
6901 && jobtab[jobno - 1].used != 0)
6902 return &jobtab[jobno - 1];
6904 } else if (name[1] == '%' && name[2] == '\0') {
6908 struct job *found = NULL;
6909 for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) {
6910 if (jp->used && jp->nprocs > 0
6911 && prefix(name + 1, jp->ps[0].cmd)) {
6913 error("%s: ambiguous", name);
6920 } else if (is_number(name, &pid)) {
6921 for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) {
6922 if (jp->used && jp->nprocs > 0
6923 && jp->ps[jp->nprocs - 1].pid == pid)
6927 error("No such job: %s", name);
6934 * Return a new job structure,
6938 makejob(const union node *node, int nprocs)
6943 for (i = njobs, jp = jobtab ; ; jp++) {
6947 jobtab = ckmalloc(4 * sizeof jobtab[0]);
6949 jp = ckmalloc((njobs + 4) * sizeof jobtab[0]);
6950 memcpy(jp, jobtab, njobs * sizeof jp[0]);
6951 /* Relocate `ps' pointers */
6952 for (i = 0; i < njobs; i++)
6953 if (jp[i].ps == &jobtab[i].ps0)
6954 jp[i].ps = &jp[i].ps0;
6958 jp = jobtab + njobs;
6959 for (i = 4 ; --i >= 0 ; jobtab[njobs++].used = 0);
6972 jp->jobctl = jobctl;
6975 jp->ps = ckmalloc(nprocs * sizeof (struct procstat));
6980 TRACE(("makejob(0x%lx, %d) returns %%%d\n", (long)node, nprocs,
6987 * Fork of a subshell. If we are doing job control, give the subshell its
6988 * own process group. Jp is a job structure that the job is to be added to.
6989 * N is the command that will be evaluated by the child. Both jp and n may
6990 * be NULL. The mode parameter can be one of the following:
6991 * FORK_FG - Fork off a foreground process.
6992 * FORK_BG - Fork off a background process.
6993 * FORK_NOJOB - Like FORK_FG, but don't give the process its own
6994 * process group even if job control is on.
6996 * When job control is turned off, background processes have their standard
6997 * input redirected to /dev/null (except for the second and later processes
7004 forkshell(struct job *jp, const union node *n, int mode)
7010 const char *devnull = _PATH_DEVNULL;
7011 const char *nullerr = "Can't open %s";
7013 TRACE(("forkshell(%%%d, 0x%lx, %d) called\n", jp - jobtab, (long)n,
7018 TRACE(("Fork failed, errno=%d\n", errno));
7020 error("Cannot fork");
7027 TRACE(("Child shell %d\n", getpid()));
7028 wasroot = rootshell;
7034 jobctl = 0; /* do job control only in root shell */
7035 if (wasroot && mode != FORK_NOJOB && mflag) {
7036 if (jp == NULL || jp->nprocs == 0)
7039 pgrp = jp->ps[0].pid;
7041 if (mode == FORK_FG) {
7042 /*** this causes superfluous TIOCSPGRPS ***/
7043 #ifdef OLD_TTY_DRIVER
7044 if (ioctl(2, TIOCSPGRP, (char *)&pgrp) < 0)
7045 error("TIOCSPGRP failed, errno=%d", errno);
7047 if (tcsetpgrp(2, pgrp) < 0)
7048 error("tcsetpgrp failed, errno=%d", errno);
7053 } else if (mode == FORK_BG) {
7056 if ((jp == NULL || jp->nprocs == 0) &&
7057 ! fd0_redirected_p ()) {
7059 if (open(devnull, O_RDONLY) != 0)
7060 error(nullerr, devnull);
7064 if (mode == FORK_BG) {
7067 if ((jp == NULL || jp->nprocs == 0) &&
7068 ! fd0_redirected_p ()) {
7070 if (open(devnull, O_RDONLY) != 0)
7071 error(nullerr, devnull);
7075 for (i = njobs, p = jobtab ; --i >= 0 ; p++)
7078 if (wasroot && iflag) {
7086 if (rootshell && mode != FORK_NOJOB && mflag) {
7087 if (jp == NULL || jp->nprocs == 0)
7090 pgrp = jp->ps[0].pid;
7094 if (mode == FORK_BG)
7095 backgndpid = pid; /* set $! */
7097 struct procstat *ps = &jp->ps[jp->nprocs++];
7101 if (iflag && rootshell && n)
7102 ps->cmd = commandtext(n);
7105 TRACE(("In parent shell: child = %d\n", pid));
7112 * Wait for job to finish.
7114 * Under job control we have the problem that while a child process is
7115 * running interrupts generated by the user are sent to the child but not
7116 * to the shell. This means that an infinite loop started by an inter-
7117 * active user may be hard to kill. With job control turned off, an
7118 * interactive user may place an interactive program inside a loop. If
7119 * the interactive program catches interrupts, the user doesn't want
7120 * these interrupts to also abort the loop. The approach we take here
7121 * is to have the shell ignore interrupt signals while waiting for a
7122 * forground process to terminate, and then send itself an interrupt
7123 * signal if the child process was terminated by an interrupt signal.
7124 * Unfortunately, some programs want to do a bit of cleanup and then
7125 * exit on interrupt; unless these processes terminate themselves by
7126 * sending a signal to themselves (instead of calling exit) they will
7127 * confuse this approach.
7131 waitforjob(struct job *jp)
7134 int mypgrp = getpgrp();
7138 struct sigaction act, oact;
7147 sigaction(SIGINT, 0, &act);
7148 act.sa_handler = waitonint;
7149 sigaction(SIGINT, &act, &oact);
7151 TRACE(("waitforjob(%%%d) called\n", jp - jobtab + 1));
7152 while (jp->state == 0) {
7160 sigaction(SIGINT, &oact, 0);
7161 if (intreceived && trap[SIGINT]) kill(getpid(), SIGINT);
7165 #ifdef OLD_TTY_DRIVER
7166 if (ioctl(2, TIOCSPGRP, (char *)&mypgrp) < 0)
7167 error("TIOCSPGRP failed, errno=%d\n", errno);
7169 if (tcsetpgrp(2, mypgrp) < 0)
7170 error("tcsetpgrp failed, errno=%d\n", errno);
7173 if (jp->state == JOBSTOPPED)
7174 curjob = jp - jobtab + 1;
7176 status = jp->ps[jp->nprocs - 1].status;
7177 /* convert to 8 bits */
7178 if (WIFEXITED(status))
7179 st = WEXITSTATUS(status);
7181 else if (WIFSTOPPED(status))
7182 st = WSTOPSIG(status) + 128;
7185 st = WTERMSIG(status) + 128;
7189 * This is truly gross.
7190 * If we're doing job control, then we did a TIOCSPGRP which
7191 * caused us (the shell) to no longer be in the controlling
7192 * session -- so we wouldn't have seen any ^C/SIGINT. So, we
7193 * intuit from the subprocess exit status whether a SIGINT
7194 * occured, and if so interrupt ourselves. Yuck. - mycroft
7196 if (WIFSIGNALED(status) && WTERMSIG(status) == SIGINT)
7199 if (jp->state == JOBDONE)
7210 * Wait for a process to terminate.
7214 * Do a wait system call. If job control is compiled in, we accept
7215 * stopped processes. If block is zero, we return a value of zero
7216 * rather than blocking.
7218 * System V doesn't have a non-blocking wait system call. It does
7219 * have a SIGCLD signal that is sent to a process when one of it's
7220 * children dies. The obvious way to use SIGCLD would be to install
7221 * a handler for SIGCLD which simply bumped a counter when a SIGCLD
7222 * was received, and have waitproc bump another counter when it got
7223 * the status of a process. Waitproc would then know that a wait
7224 * system call would not block if the two counters were different.
7225 * This approach doesn't work because if a process has children that
7226 * have not been waited for, System V will send it a SIGCLD when it
7227 * installs a signal handler for SIGCLD. What this means is that when
7228 * a child exits, the shell will be sent SIGCLD signals continuously
7229 * until is runs out of stack space, unless it does a wait call before
7230 * restoring the signal handler. The code below takes advantage of
7231 * this (mis)feature by installing a signal handler for SIGCLD and
7232 * then checking to see whether it was called. If there are any
7233 * children to be waited for, it will be.
7238 waitproc(int block, int *status)
7249 return wait3(status, flags, (struct rusage *)NULL);
7253 dowait(int block, struct job *job)
7257 struct procstat *sp;
7259 struct job *thisjob;
7265 TRACE(("dowait(%d) called\n", block));
7267 pid = waitproc(block, &status);
7268 TRACE(("wait returns %d, status=%d\n", pid, status));
7269 } while (!(block & 2) && pid == -1 && errno == EINTR);
7274 for (jp = jobtab ; jp < jobtab + njobs ; jp++) {
7278 for (sp = jp->ps ; sp < jp->ps + jp->nprocs ; sp++) {
7281 if (sp->pid == pid) {
7282 TRACE(("Changing status of proc %d from 0x%x to 0x%x\n", pid, sp->status, status));
7283 sp->status = status;
7286 if (sp->status == -1)
7288 else if (WIFSTOPPED(sp->status))
7291 if (stopped) { /* stopped or done */
7292 int state = done? JOBDONE : JOBSTOPPED;
7293 if (jp->state != state) {
7294 TRACE(("Job %d: changing state from %d to %d\n", jp - jobtab + 1, jp->state, state));
7297 if (done && curjob == jp - jobtab + 1)
7298 curjob = 0; /* no current job */
7305 if (! rootshell || ! iflag || (job && thisjob == job)) {
7306 core = WCOREDUMP(status);
7308 if (WIFSTOPPED(status)) sig = WSTOPSIG(status);
7311 if (WIFEXITED(status)) sig = 0;
7312 else sig = WTERMSIG(status);
7314 if (sig != 0 && sig != SIGINT && sig != SIGPIPE) {
7316 out2fmt("%d: ", pid);
7318 if (sig == SIGTSTP && rootshell && iflag)
7320 (long)(job - jobtab + 1));
7322 if (sig < NSIG && sys_siglist[sig])
7323 out2str(sys_siglist[sig]);
7325 out2fmt("Signal %d", sig);
7327 out2str(" - core dumped");
7330 TRACE(("Not printing status: status=%d, sig=%d\n",
7334 TRACE(("Not printing status, rootshell=%d, job=0x%x\n", rootshell, job));
7336 thisjob->changed = 1;
7345 * return 1 if there are stopped jobs, otherwise 0
7355 for (jobno = 1, jp = jobtab; jobno <= njobs; jobno++, jp++) {
7358 if (jp->state == JOBSTOPPED) {
7359 out2str("You have stopped jobs.\n");
7369 * Return a string identifying a command (to be printed by the
7373 static char *cmdnextc;
7374 static int cmdnleft;
7375 #define MAXCMDTEXT 200
7378 cmdputs(const char *s)
7389 while ((c = *p++) != '\0') {
7392 else if (c == CTLVAR) {
7397 } else if (c == '=' && subtype != 0) {
7398 *q++ = "}-+?="[(subtype & VSTYPE) - VSNORMAL];
7400 } else if (c == CTLENDVAR) {
7402 } else if (c == CTLBACKQ || c == CTLBACKQ+CTLQUOTE)
7403 cmdnleft++; /* ignore it */
7406 if (--cmdnleft <= 0) {
7418 cmdtxt(const union node *n)
7421 struct nodelist *lp;
7430 cmdtxt(n->nbinary.ch1);
7432 cmdtxt(n->nbinary.ch2);
7435 cmdtxt(n->nbinary.ch1);
7437 cmdtxt(n->nbinary.ch2);
7440 cmdtxt(n->nbinary.ch1);
7442 cmdtxt(n->nbinary.ch2);
7445 for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
7453 cmdtxt(n->nredir.n);
7458 cmdtxt(n->nredir.n);
7462 cmdtxt(n->nif.test);
7464 cmdtxt(n->nif.ifpart);
7473 cmdtxt(n->nbinary.ch1);
7475 cmdtxt(n->nbinary.ch2);
7480 cmdputs(n->nfor.var);
7485 cmdputs(n->ncase.expr->narg.text);
7489 cmdputs(n->narg.text);
7493 for (np = n->ncmd.args ; np ; np = np->narg.next) {
7498 for (np = n->ncmd.redirect ; np ; np = np->nfile.next) {
7504 cmdputs(n->narg.text);
7507 p = ">"; i = 1; goto redir;
7509 p = ">>"; i = 1; goto redir;
7511 p = ">&"; i = 1; goto redir;
7513 p = ">|"; i = 1; goto redir;
7515 p = "<"; i = 0; goto redir;
7517 p = "<&"; i = 0; goto redir;
7519 p = "<>"; i = 0; goto redir;
7521 if (n->nfile.fd != i) {
7522 s[0] = n->nfile.fd + '0';
7527 if (n->type == NTOFD || n->type == NFROMFD) {
7528 s[0] = n->ndup.dupfd + '0';
7532 cmdtxt(n->nfile.fname);
7547 commandtext(const union node *n)
7551 cmdnextc = name = ckmalloc(MAXCMDTEXT);
7552 cmdnleft = MAXCMDTEXT - 4;
7559 static void waitonint(int sig) {
7564 * Routines to check for mail. (Perhaps make part of main.c?)
7568 #define MAXMBOXES 10
7571 static int nmboxes; /* number of mailboxes */
7572 static time_t mailtime[MAXMBOXES]; /* times of mailboxes */
7577 * Print appropriate message(s) if mail has arrived. If the argument is
7578 * nozero, then the value of MAIL has changed, so we just update the
7589 struct stackmark smark;
7596 setstackmark(&smark);
7597 mpath = mpathset()? mpathval() : mailval();
7598 for (i = 0 ; i < nmboxes ; i++) {
7599 p = padvance(&mpath, nullstr);
7604 for (q = p ; *q ; q++);
7609 q[-1] = '\0'; /* delete trailing '/' */
7610 if (stat(p, &statb) < 0)
7612 if (statb.st_size > mailtime[i] && ! silent) {
7614 pathopt? pathopt : "you have mail");
7616 mailtime[i] = statb.st_size;
7619 popstackmark(&smark);
7625 static short profile_buf[16384];
7629 static void read_profile (const char *);
7630 static void cmdloop (int);
7631 static void options (int);
7632 static void setoption (int, int);
7633 static void procargs (int, char **);
7637 * Main routine. We initialize things, parse the arguments, execute
7638 * profiles if we're a login shell, and then call cmdloop to execute
7639 * commands. The setjmp call sets up the location to jump to when an
7640 * exception occurs. When an exception occurs the variable "state"
7641 * is used to figure out how far we had gotten.
7645 shell_main(argc, argv)
7649 struct jmploc jmploc;
7650 struct stackmark smark;
7654 BLTINCMD = find_builtin("builtin");
7655 EXECCMD = find_builtin("exec");
7656 EVALCMD = find_builtin("eval");
7658 #ifndef BB_FEATURE_SH_FANCY_PROMPT
7664 monitor(4, etext, profile_buf, sizeof profile_buf, 50);
7666 #if defined(linux) || defined(__GNU__)
7667 signal(SIGCHLD, SIG_DFL);
7670 if (setjmp(jmploc.loc)) {
7673 * When a shell procedure is executed, we raise the
7674 * exception EXSHELLPROC to clean up before executing
7675 * the shell procedure.
7677 switch (exception) {
7686 exitstatus = exerrno;
7697 if (exception != EXSHELLPROC) {
7698 if (state == 0 || iflag == 0 || ! rootshell)
7699 exitshell(exitstatus);
7702 if (exception == EXINT) {
7705 popstackmark(&smark);
7706 FORCEINTON; /* enable interrupts */
7709 else if (state == 2)
7711 else if (state == 3)
7719 trputs("Shell args: "); trargs(argv);
7724 setstackmark(&smark);
7725 procargs(argc, argv);
7726 if (argv[0] && argv[0][0] == '-') {
7728 read_profile("/etc/profile");
7731 read_profile(".profile");
7736 if (getuid() == geteuid() && getgid() == getegid()) {
7738 if ((shinit = lookupvar("ENV")) != NULL && *shinit != '\0') {
7740 read_profile(shinit);
7747 if (sflag == 0 || minusc) {
7748 static int sigs[] = {
7749 SIGINT, SIGQUIT, SIGHUP,
7755 #define SIGSSIZE (sizeof(sigs)/sizeof(sigs[0]))
7758 for (i = 0; i < SIGSSIZE; i++)
7763 evalstring(minusc, 0);
7765 if (sflag || minusc == NULL) {
7766 state4: /* XXX ??? - why isn't this before the "if" statement */
7772 exitshell(exitstatus);
7778 * Read and execute commands. "Top" is nonzero for the top level command
7779 * loop; it turns on prompting if the shell is interactive.
7786 struct stackmark smark;
7790 TRACE(("cmdloop(%d) called\n", top));
7791 setstackmark(&smark);
7802 n = parsecmd(inter);
7803 /* showtree(n); DEBUG */
7805 if (!top || numeof >= 50)
7807 if (!stoppedjobs()) {
7810 out2str("\nUse \"exit\" to leave shell.\n");
7813 } else if (n != NULL && nflag == 0) {
7814 job_warning = (job_warning == 2) ? 1 : 0;
7818 popstackmark(&smark);
7819 setstackmark(&smark);
7820 if (evalskip == SKIPFILE) {
7825 popstackmark(&smark);
7831 * Read /etc/profile or .profile. Return on error.
7843 if ((fd = open(name, O_RDONLY)) >= 0)
7848 /* -q turns off -x and -v just when executing init files */
7851 xflag = 0, xflag_set = 1;
7853 vflag = 0, vflag_set = 1;
7868 * Read a file containing shell functions.
7872 readcmdfile(const char *name)
7877 if ((fd = open(name, O_RDONLY)) >= 0)
7880 error("Can't open %s", name);
7889 * Take commands from a file. To be compatable we should do a path
7890 * search for the file, which is necessary to find sub-commands.
7894 static inline char *
7895 find_dot_file(mybasename)
7899 const char *path = pathval();
7902 /* don't try this for absolute or relative paths */
7903 if (strchr(mybasename, '/'))
7906 while ((fullname = padvance(&path, mybasename)) != NULL) {
7907 if ((stat(fullname, &statb) == 0) && S_ISREG(statb.st_mode)) {
7909 * Don't bother freeing here, since it will
7910 * be freed by the caller.
7914 stunalloc(fullname);
7917 /* not found in the PATH */
7918 error("%s: not found", mybasename);
7930 for (sp = cmdenviron; sp ; sp = sp->next)
7931 setvareq(savestr(sp->text), VSTRFIXED|VTEXTFIXED);
7933 if (argc >= 2) { /* That's what SVR2 does */
7935 struct stackmark smark;
7937 setstackmark(&smark);
7938 fullname = find_dot_file(argv[1]);
7939 setinputfile(fullname, 1);
7940 commandname = fullname;
7943 popstackmark(&smark);
7957 exitstatus = number(argv[1]);
7959 exitstatus = oexitstatus;
7960 exitshell(exitstatus);
7969 nbytes = ALIGN(nbytes);
7970 if (nbytes > stacknleft) {
7972 struct stack_block *sp;
7975 if (blocksize < MINSIZE)
7976 blocksize = MINSIZE;
7978 sp = ckmalloc(sizeof(struct stack_block) - MINSIZE + blocksize);
7980 stacknxt = sp->space;
7981 stacknleft = blocksize;
7987 stacknleft -= nbytes;
7993 stunalloc(pointer p)
7996 if (p == NULL) { /*DEBUG */
7997 write(2, "stunalloc\n", 10);
8001 if (!(stacknxt >= (char *)p && (char *)p >= stackp->space)) {
8004 stacknleft += stacknxt - (char *)p;
8010 setstackmark(struct stackmark *mark)
8012 mark->stackp = stackp;
8013 mark->stacknxt = stacknxt;
8014 mark->stacknleft = stacknleft;
8015 mark->marknext = markp;
8021 popstackmark(struct stackmark *mark)
8023 struct stack_block *sp;
8026 markp = mark->marknext;
8027 while (stackp != mark->stackp) {
8032 stacknxt = mark->stacknxt;
8033 stacknleft = mark->stacknleft;
8039 * When the parser reads in a string, it wants to stick the string on the
8040 * stack and only adjust the stack pointer when it knows how big the
8041 * string is. Stackblock (defined in stack.h) returns a pointer to a block
8042 * of space on top of the stack and stackblocklen returns the length of
8043 * this block. Growstackblock will grow this space by at least one byte,
8044 * possibly moving it (like realloc). Grabstackblock actually allocates the
8045 * part of the block that has been used.
8049 growstackblock(void) {
8051 int newlen = ALIGN(stacknleft * 2 + 100);
8052 char *oldspace = stacknxt;
8053 int oldlen = stacknleft;
8054 struct stack_block *sp;
8055 struct stack_block *oldstackp;
8057 if (stacknxt == stackp->space && stackp != &stackbase) {
8062 sp = ckrealloc((pointer)sp, sizeof(struct stack_block) - MINSIZE + newlen);
8065 stacknxt = sp->space;
8066 stacknleft = newlen;
8068 /* Stack marks pointing to the start of the old block
8069 * must be relocated to point to the new block
8071 struct stackmark *xmark;
8073 while (xmark != NULL && xmark->stackp == oldstackp) {
8074 xmark->stackp = stackp;
8075 xmark->stacknxt = stacknxt;
8076 xmark->stacknleft = stacknleft;
8077 xmark = xmark->marknext;
8082 p = stalloc(newlen);
8083 memcpy(p, oldspace, oldlen);
8084 stacknxt = p; /* free the space */
8085 stacknleft += newlen; /* we just allocated */
8092 grabstackblock(int len)
8102 * The following routines are somewhat easier to use that the above.
8103 * The user declares a variable of type STACKSTR, which may be declared
8104 * to be a register. The macro STARTSTACKSTR initializes things. Then
8105 * the user uses the macro STPUTC to add characters to the string. In
8106 * effect, STPUTC(c, p) is the same as *p++ = c except that the stack is
8107 * grown as necessary. When the user is done, she can just leave the
8108 * string there and refer to it using stackblock(). Or she can allocate
8109 * the space for it using grabstackstr(). If it is necessary to allow
8110 * someone else to use the stack temporarily and then continue to grow
8111 * the string, the user should use grabstack to allocate the space, and
8112 * then call ungrabstr(p) to return to the previous mode of operation.
8114 * USTPUTC is like STPUTC except that it doesn't check for overflow.
8115 * CHECKSTACKSPACE can be called before USTPUTC to ensure that there
8116 * is space for at least one character.
8121 growstackstr(void) {
8122 int len = stackblocksize();
8123 if (herefd >= 0 && len >= 1024) {
8124 xwrite(herefd, stackblock(), len);
8125 sstrnleft = len - 1;
8126 return stackblock();
8129 sstrnleft = stackblocksize() - len - 1;
8130 return stackblock() + len;
8135 * Called from CHECKSTRSPACE.
8139 makestrspace(size_t newlen) {
8140 int len = stackblocksize() - sstrnleft;
8143 sstrnleft = stackblocksize() - len;
8144 } while (sstrnleft < newlen);
8145 return stackblock() + len;
8151 ungrabstackstr(char *s, char *p)
8153 stacknleft += stacknxt - s;
8155 sstrnleft = stacknleft - (p - s);
8158 * Miscelaneous builtins.
8165 static mode_t getmode(const void *, mode_t);
8166 static void *setmode(const char *);
8169 #if !defined(__GLIBC__) || __GLIBC__ == 2 && __GLIBC_MINOR__ < 1
8170 typedef long rlim_t;
8176 * The read builtin. The -e option causes backslashes to escape the
8177 * following character.
8179 * This uses unbuffered input, which may be avoidable in some cases.
8200 while ((i = nextopt("p:r")) != '\0') {
8206 if (prompt && isatty(0)) {
8210 if (*(ap = argptr) == NULL)
8212 if ((ifs = bltinlookup("IFS")) == NULL)
8219 if (read(0, &c, 1) != 1) {
8231 if (!rflag && c == '\\') {
8237 if (startword && *ifs == ' ' && strchr(ifs, c)) {
8241 if (backslash && c == '\\') {
8242 if (read(0, &c, 1) != 1) {
8247 } else if (ap[1] != NULL && strchr(ifs, c) != NULL) {
8249 setvar(*ap, stackblock(), 0);
8258 /* Remove trailing blanks */
8259 while (stackblock() <= --p && strchr(ifs, *p) != NULL)
8261 setvar(*ap, stackblock(), 0);
8262 while (*++ap != NULL)
8263 setvar(*ap, nullstr, 0);
8270 umaskcmd(argc, argv)
8277 int symbolic_mode = 0;
8279 while (nextopt("S") != '\0') {
8288 if ((ap = *argptr) == NULL) {
8289 if (symbolic_mode) {
8290 char u[4], g[4], o[4];
8293 if ((mask & S_IRUSR) == 0)
8295 if ((mask & S_IWUSR) == 0)
8297 if ((mask & S_IXUSR) == 0)
8302 if ((mask & S_IRGRP) == 0)
8304 if ((mask & S_IWGRP) == 0)
8306 if ((mask & S_IXGRP) == 0)
8311 if ((mask & S_IROTH) == 0)
8313 if ((mask & S_IWOTH) == 0)
8315 if ((mask & S_IXOTH) == 0)
8319 printf("u=%s,g=%s,o=%s\n", u, g, o);
8321 printf("%.4o\n", mask);
8324 if (is_digit((unsigned char)*ap)) {
8327 if (*ap >= '8' || *ap < '0')
8328 error("Illegal number: %s", argv[1]);
8329 mask = (mask << 3) + (*ap - '0');
8330 } while (*++ap != '\0');
8336 if ((set = setmode(ap)) != 0) {
8337 mask = getmode(set, ~mask & 0777);
8342 error("Illegal mode: %s", ap);
8344 umask(~mask & 0777);
8353 * This code, originally by Doug Gwyn, Doug Kingston, Eric Gisin, and
8354 * Michael Rendell was ripped from pdksh 5.0.8 and hacked for use with
8355 * ash by J.T. Conklin.
8363 int factor; /* multiply by to get rlim_{cur,max} values */
8367 static const struct limits limits[] = {
8369 { "time(seconds)", RLIMIT_CPU, 1, 't' },
8372 { "file(blocks)", RLIMIT_FSIZE, 512, 'f' },
8375 { "data(kbytes)", RLIMIT_DATA, 1024, 'd' },
8378 { "stack(kbytes)", RLIMIT_STACK, 1024, 's' },
8381 { "coredump(blocks)", RLIMIT_CORE, 512, 'c' },
8384 { "memory(kbytes)", RLIMIT_RSS, 1024, 'm' },
8386 #ifdef RLIMIT_MEMLOCK
8387 { "locked memory(kbytes)", RLIMIT_MEMLOCK, 1024, 'l' },
8390 { "process(processes)", RLIMIT_NPROC, 1, 'p' },
8392 #ifdef RLIMIT_NOFILE
8393 { "nofiles(descriptors)", RLIMIT_NOFILE, 1, 'n' },
8396 { "vmemory(kbytes)", RLIMIT_VMEM, 1024, 'v' },
8399 { "swap(kbytes)", RLIMIT_SWAP, 1024, 'w' },
8401 { (char *) 0, 0, 0, '\0' }
8405 ulimitcmd(argc, argv)
8411 enum { SOFT = 0x1, HARD = 0x2 }
8413 const struct limits *l;
8416 struct rlimit limit;
8419 while ((optc = nextopt("HSatfdsmcnpl")) != '\0')
8434 for (l = limits; l->name && l->option != what; l++)
8437 error("internal error (%c)", what);
8439 set = *argptr ? 1 : 0;
8443 if (all || argptr[1])
8444 error("too many arguments");
8445 if (strcmp(p, "unlimited") == 0)
8446 val = RLIM_INFINITY;
8450 while ((c = *p++) >= '0' && c <= '9')
8452 val = (val * 10) + (long)(c - '0');
8453 if (val < (rlim_t) 0)
8457 error("bad number");
8462 for (l = limits; l->name; l++) {
8463 getrlimit(l->cmd, &limit);
8465 val = limit.rlim_cur;
8466 else if (how & HARD)
8467 val = limit.rlim_max;
8469 printf("%-20s ", l->name);
8470 if (val == RLIM_INFINITY)
8471 printf("unlimited\n");
8475 printf("%lld\n", (long long) val);
8481 getrlimit(l->cmd, &limit);
8484 limit.rlim_max = val;
8486 limit.rlim_cur = val;
8487 if (setrlimit(l->cmd, &limit) < 0)
8488 error("error setting limit (%m)");
8491 val = limit.rlim_cur;
8492 else if (how & HARD)
8493 val = limit.rlim_max;
8495 if (val == RLIM_INFINITY)
8496 printf("unlimited\n");
8500 printf("%lld\n", (long long) val);
8506 * prefix -- see if pfx is a prefix of string.
8510 prefix(char const *pfx, char const *string)
8513 if (*pfx++ != *string++)
8520 * Return true if s is a string of digits, and save munber in intptr
8525 is_number(const char *p, int *intptr)
8533 ret += digit_val(*p);
8535 } while (*p != '\0');
8542 * Convert a string of digits to an integer, printing an error message on
8547 number(const char *s)
8550 if (! is_number(s, &i))
8551 error("Illegal number: %s", s);
8556 * Produce a possibly single quoted string suitable as input to the shell.
8557 * The return string is allocated on the stack.
8561 single_quote(const char *s) {
8568 size_t len1, len1p, len2, len2p;
8570 len1 = strcspn(s, "'");
8571 len2 = strspn(s + len1, "'");
8573 len1p = len1 ? len1 + 2 : len1;
8585 CHECKSTRSPACE(len1p + len2p + 1, p);
8590 memcpy(p + 1, s, len1);
8606 memcpy(q + 1, s, len2);
8611 STADJUST(len1p + len2p, p);
8616 return grabstackstr(p);
8620 * Like strdup but works with the ash stack.
8624 sstrdup(const char *p)
8626 size_t len = strlen(p) + 1;
8627 return memcpy(stalloc(len), p, len);
8632 * Routine for dealing with parsed shell commands.
8636 static void sizenodelist (const struct nodelist *);
8637 static struct nodelist *copynodelist (const struct nodelist *);
8638 static char *nodesavestr (const char *);
8641 calcsize(const union node *n)
8645 funcblocksize += nodesize[n->type];
8652 calcsize(n->nbinary.ch2);
8653 calcsize(n->nbinary.ch1);
8656 calcsize(n->ncmd.redirect);
8657 calcsize(n->ncmd.args);
8658 calcsize(n->ncmd.assign);
8661 sizenodelist(n->npipe.cmdlist);
8666 calcsize(n->nredir.redirect);
8667 calcsize(n->nredir.n);
8670 calcsize(n->nif.elsepart);
8671 calcsize(n->nif.ifpart);
8672 calcsize(n->nif.test);
8675 funcstringsize += strlen(n->nfor.var) + 1;
8676 calcsize(n->nfor.body);
8677 calcsize(n->nfor.args);
8680 calcsize(n->ncase.cases);
8681 calcsize(n->ncase.expr);
8684 calcsize(n->nclist.body);
8685 calcsize(n->nclist.pattern);
8686 calcsize(n->nclist.next);
8690 sizenodelist(n->narg.backquote);
8691 funcstringsize += strlen(n->narg.text) + 1;
8692 calcsize(n->narg.next);
8699 calcsize(n->nfile.fname);
8700 calcsize(n->nfile.next);
8704 calcsize(n->ndup.vname);
8705 calcsize(n->ndup.next);
8709 calcsize(n->nhere.doc);
8710 calcsize(n->nhere.next);
8713 calcsize(n->nnot.com);
8719 sizenodelist(const struct nodelist *lp)
8722 funcblocksize += ALIGN(sizeof(struct nodelist));
8730 copynode(const union node *n)
8737 funcblock = (char *) funcblock + nodesize[n->type];
8744 new->nbinary.ch2 = copynode(n->nbinary.ch2);
8745 new->nbinary.ch1 = copynode(n->nbinary.ch1);
8748 new->ncmd.redirect = copynode(n->ncmd.redirect);
8749 new->ncmd.args = copynode(n->ncmd.args);
8750 new->ncmd.assign = copynode(n->ncmd.assign);
8751 new->ncmd.backgnd = n->ncmd.backgnd;
8754 new->npipe.cmdlist = copynodelist(n->npipe.cmdlist);
8755 new->npipe.backgnd = n->npipe.backgnd;
8760 new->nredir.redirect = copynode(n->nredir.redirect);
8761 new->nredir.n = copynode(n->nredir.n);
8764 new->nif.elsepart = copynode(n->nif.elsepart);
8765 new->nif.ifpart = copynode(n->nif.ifpart);
8766 new->nif.test = copynode(n->nif.test);
8769 new->nfor.var = nodesavestr(n->nfor.var);
8770 new->nfor.body = copynode(n->nfor.body);
8771 new->nfor.args = copynode(n->nfor.args);
8774 new->ncase.cases = copynode(n->ncase.cases);
8775 new->ncase.expr = copynode(n->ncase.expr);
8778 new->nclist.body = copynode(n->nclist.body);
8779 new->nclist.pattern = copynode(n->nclist.pattern);
8780 new->nclist.next = copynode(n->nclist.next);
8784 new->narg.backquote = copynodelist(n->narg.backquote);
8785 new->narg.text = nodesavestr(n->narg.text);
8786 new->narg.next = copynode(n->narg.next);
8793 new->nfile.fname = copynode(n->nfile.fname);
8794 new->nfile.fd = n->nfile.fd;
8795 new->nfile.next = copynode(n->nfile.next);
8799 new->ndup.vname = copynode(n->ndup.vname);
8800 new->ndup.dupfd = n->ndup.dupfd;
8801 new->ndup.fd = n->ndup.fd;
8802 new->ndup.next = copynode(n->ndup.next);
8806 new->nhere.doc = copynode(n->nhere.doc);
8807 new->nhere.fd = n->nhere.fd;
8808 new->nhere.next = copynode(n->nhere.next);
8811 new->nnot.com = copynode(n->nnot.com);
8814 new->type = n->type;
8819 static struct nodelist *
8820 copynodelist(const struct nodelist *lp)
8822 struct nodelist *start;
8823 struct nodelist **lpp;
8828 funcblock = (char *) funcblock + ALIGN(sizeof(struct nodelist));
8829 (*lpp)->n = copynode(lp->n);
8831 lpp = &(*lpp)->next;
8839 nodesavestr(const char *s)
8842 char *rtn = funcstring;
8844 funcstring = stpcpy(funcstring, s) + 1;
8848 char *q = funcstring;
8849 char *rtn = funcstring;
8851 while ((*q++ = *p++) != '\0')
8859 static int getopts (char *, char *, char **, int *, int *);
8864 * Process the shell command line arguments.
8868 procargs(argc, argv)
8877 for (i = 0; i < NOPTS; i++)
8880 if (*argptr == NULL && minusc == NULL)
8882 if (iflag == 2 && sflag == 1 && isatty(0) && isatty(1))
8886 for (i = 0; i < NOPTS; i++)
8887 if (optent_val(i) == 2)
8890 if (sflag == 0 && minusc == NULL) {
8891 commandname = argv[0];
8893 setinputfile(arg0, 0);
8896 /* POSIX 1003.2: first arg after -c cmd is $0, remainder $1... */
8897 if (argptr && minusc && *argptr)
8900 shellparam.p = argptr;
8901 shellparam.optind = 1;
8902 shellparam.optoff = -1;
8903 /* assert(shellparam.malloc == 0 && shellparam.nparam == 0); */
8905 shellparam.nparam++;
8914 * Process shell options. The global variable argptr contains a pointer
8915 * to the argument list; we advance it past the options.
8919 minus_o(const char *name, int val)
8924 out1str("Current option settings\n");
8925 for (i = 0; i < NOPTS; i++)
8926 printf("%-16s%s\n", optent_name(optlist[i]),
8927 optent_val(i) ? "on" : "off");
8929 for (i = 0; i < NOPTS; i++)
8930 if (equal(name, optent_name(optlist[i]))) {
8931 setoption(optent_letter(optlist[i]), val);
8934 error("Illegal option -o %s", name);
8940 options(int cmdline)
8948 while ((p = *argptr) != NULL) {
8950 if ((c = *p++) == '-') {
8952 if (p[0] == '\0' || (p[0] == '-' && p[1] == '\0')) {
8954 /* "-" means turn off -x and -v */
8957 /* "--" means reset params */
8958 else if (*argptr == NULL)
8961 break; /* "-" or "--" terminates options */
8963 } else if (c == '+') {
8969 while ((c = *p++) != '\0') {
8970 if (c == 'c' && cmdline) {
8972 #ifdef NOHACK /* removing this code allows sh -ce 'foo' for compat */
8976 if (q == NULL || minusc != NULL)
8977 error("Bad -c option");
8982 } else if (c == 'o') {
8983 minus_o(*argptr, val);
8995 setoption(int flag, int val)
8999 for (i = 0; i < NOPTS; i++)
9000 if (optent_letter(optlist[i]) == flag) {
9001 optent_val(i) = val;
9003 /* #%$ hack for ksh semantics */
9006 else if (flag == 'E')
9011 error("Illegal option -%c", flag);
9018 * Set the shell parameters.
9022 setparam(char **argv)
9028 for (nparam = 0 ; argv[nparam] ; nparam++);
9029 ap = newparam = ckmalloc((nparam + 1) * sizeof *ap);
9031 *ap++ = savestr(*argv++);
9034 freeparam(&shellparam);
9035 shellparam.malloc = 1;
9036 shellparam.nparam = nparam;
9037 shellparam.p = newparam;
9038 shellparam.optind = 1;
9039 shellparam.optoff = -1;
9044 * Free the list of positional parameters.
9048 freeparam(volatile struct shparam *param)
9052 if (param->malloc) {
9053 for (ap = param->p ; *ap ; ap++)
9062 * The shift builtin command.
9066 shiftcmd(argc, argv)
9075 n = number(argv[1]);
9076 if (n > shellparam.nparam)
9077 error("can't shift that many");
9079 shellparam.nparam -= n;
9080 for (ap1 = shellparam.p ; --n >= 0 ; ap1++) {
9081 if (shellparam.malloc)
9085 while ((*ap2++ = *ap1++) != NULL);
9086 shellparam.optind = 1;
9087 shellparam.optoff = -1;
9095 * The set command builtin.
9104 return showvarscmd(argc, argv);
9108 if (*argptr != NULL) {
9117 getoptsreset(const char *value)
9119 shellparam.optind = number(value);
9120 shellparam.optoff = -1;
9123 #ifdef BB_LOCALE_SUPPORT
9124 static void change_lc_all(const char *value)
9126 if(value != 0 && *value != 0)
9127 setlocale(LC_ALL, value);
9130 static void change_lc_ctype(const char *value)
9132 if(value != 0 && *value != 0)
9133 setlocale(LC_CTYPE, value);
9140 * The getopts builtin. Shellparam.optnext points to the next argument
9141 * to be processed. Shellparam.optptr points to the next character to
9142 * be processed in the current argument. If shellparam.optnext is NULL,
9143 * then it's the first time getopts has been called.
9147 getoptscmd(argc, argv)
9154 error("Usage: getopts optstring var [arg]");
9155 else if (argc == 3) {
9156 optbase = shellparam.p;
9157 if (shellparam.optind > shellparam.nparam + 1) {
9158 shellparam.optind = 1;
9159 shellparam.optoff = -1;
9164 if (shellparam.optind > argc - 2) {
9165 shellparam.optind = 1;
9166 shellparam.optoff = -1;
9170 return getopts(argv[1], argv[2], optbase, &shellparam.optind,
9171 &shellparam.optoff);
9175 * Safe version of setvar, returns 1 on success 0 on failure.
9179 setvarsafe(name, val, flags)
9180 const char *name, *val;
9183 struct jmploc jmploc;
9184 struct jmploc *volatile savehandler = handler;
9190 if (setjmp(jmploc.loc))
9194 setvar(name, val, flags);
9196 handler = savehandler;
9201 getopts(optstr, optvar, optfirst, myoptind, optoff)
9213 char **optnext = optfirst + *myoptind - 1;
9215 if (*myoptind <= 1 || *optoff < 0 || !(*(optnext - 1)) ||
9216 strlen(*(optnext - 1)) < *optoff)
9219 p = *(optnext - 1) + *optoff;
9220 if (p == NULL || *p == '\0') {
9221 /* Current word is done, advance */
9222 if (optnext == NULL)
9225 if (p == NULL || *p != '-' || *++p == '\0') {
9227 *myoptind = optnext - optfirst + 1;
9233 if (p[0] == '-' && p[1] == '\0') /* check for "--" */
9238 for (q = optstr; *q != c; ) {
9240 if (optstr[0] == ':') {
9243 err |= setvarsafe("OPTARG", s, 0);
9246 out2fmt("Illegal option -%c\n", c);
9247 (void) unsetvar("OPTARG");
9257 if (*p == '\0' && (p = *optnext) == NULL) {
9258 if (optstr[0] == ':') {
9261 err |= setvarsafe("OPTARG", s, 0);
9265 out2fmt("No arg for -%c option\n", c);
9266 (void) unsetvar("OPTARG");
9274 setvarsafe("OPTARG", p, 0);
9278 setvarsafe("OPTARG", "", 0);
9279 *myoptind = optnext - optfirst + 1;
9286 *optoff = p ? p - *(optnext - 1) : -1;
9287 snprintf(s, sizeof(s), "%d", *myoptind);
9288 err |= setvarsafe("OPTIND", s, VNOFUNC);
9291 err |= setvarsafe(optvar, s, 0);
9302 * XXX - should get rid of. have all builtins use getopt(3). the
9303 * library getopt must have the BSD extension static variable "optreset"
9304 * otherwise it can't be used within the shell safely.
9306 * Standard option processing (a la getopt) for builtin routines. The
9307 * only argument that is passed to nextopt is the option string; the
9308 * other arguments are unnecessary. It return the character, or '\0' on
9313 nextopt(const char *optstring)
9319 if ((p = optptr) == NULL || *p == '\0') {
9321 if (p == NULL || *p != '-' || *++p == '\0')
9324 if (p[0] == '-' && p[1] == '\0') /* check for "--" */
9328 for (q = optstring ; *q != c ; ) {
9330 error("Illegal option -%c", c);
9335 if (*p == '\0' && (p = *argptr++) == NULL)
9336 error("No arg for -%c option", c);
9353 out2fmt(const char *fmt, ...)
9357 vfprintf(stderr, fmt, ap);
9362 * Version of write which resumes after a signal is caught.
9366 xwrite(int fd, const char *buf, int nbytes)
9375 i = write(fd, buf, n);
9381 } else if (i == 0) {
9384 } else if (errno != EINTR) {
9392 * Shell command parser.
9395 #define EOFMARKLEN 79
9400 struct heredoc *next; /* next here document in list */
9401 union node *here; /* redirection node */
9402 char *eofmark; /* string indicating end of input */
9403 int striptabs; /* if set, strip leading tabs */
9406 static struct heredoc *heredoclist; /* list of here documents to read */
9407 static int parsebackquote; /* nonzero if we are inside backquotes */
9408 static int doprompt; /* if set, prompt the user */
9409 static int needprompt; /* true if interactive and at start of line */
9410 static int lasttoken; /* last token read */
9412 static char *wordtext; /* text of last word returned by readtoken */
9414 static struct nodelist *backquotelist;
9415 static union node *redirnode;
9416 static struct heredoc *heredoc;
9417 static int quoteflag; /* set if (part of) last token was quoted */
9418 static int startlinno; /* line # where last token started */
9421 static union node *list (int);
9422 static union node *andor (void);
9423 static union node *pipeline (void);
9424 static union node *command (void);
9425 static union node *simplecmd (void);
9426 static void parsefname (void);
9427 static void parseheredoc (void);
9428 static int peektoken (void);
9429 static int readtoken (void);
9430 static int xxreadtoken (void);
9431 static int readtoken1 (int, char const *, char *, int);
9432 static int noexpand (char *);
9433 static void synexpect (int) __attribute__((noreturn));
9434 static void synerror (const char *) __attribute__((noreturn));
9435 static void setprompt (int);
9439 * Read and parse a command. Returns NEOF on end of file. (NULL is a
9440 * valid parse tree indicating a blank line.)
9444 parsecmd(int interact)
9449 doprompt = interact;
9469 union node *n1, *n2, *n3;
9473 if (nlflag == 0 && tokendlist[peektoken()])
9479 if (tok == TBACKGND) {
9480 if (n2->type == NCMD || n2->type == NPIPE) {
9481 n2->ncmd.backgnd = 1;
9482 } else if (n2->type == NREDIR) {
9483 n2->type = NBACKGND;
9485 n3 = (union node *)stalloc(sizeof (struct nredir));
9486 n3->type = NBACKGND;
9488 n3->nredir.redirect = NULL;
9496 n3 = (union node *)stalloc(sizeof (struct nbinary));
9498 n3->nbinary.ch1 = n1;
9499 n3->nbinary.ch2 = n2;
9516 if (tokendlist[peektoken()])
9523 pungetc(); /* push back EOF on input */
9538 union node *n1, *n2, *n3;
9544 if ((t = readtoken()) == TAND) {
9546 } else if (t == TOR) {
9554 n3 = (union node *)stalloc(sizeof (struct nbinary));
9556 n3->nbinary.ch1 = n1;
9557 n3->nbinary.ch2 = n2;
9566 union node *n1, *n2, *pipenode;
9567 struct nodelist *lp, *prev;
9571 TRACE(("pipeline: entered\n"));
9572 if (readtoken() == TNOT) {
9578 if (readtoken() == TPIPE) {
9579 pipenode = (union node *)stalloc(sizeof (struct npipe));
9580 pipenode->type = NPIPE;
9581 pipenode->npipe.backgnd = 0;
9582 lp = (struct nodelist *)stalloc(sizeof (struct nodelist));
9583 pipenode->npipe.cmdlist = lp;
9587 lp = (struct nodelist *)stalloc(sizeof (struct nodelist));
9591 } while (readtoken() == TPIPE);
9597 n2 = (union node *)stalloc(sizeof (struct nnot));
9609 union node *n1, *n2;
9610 union node *ap, **app;
9611 union node *cp, **cpp;
9612 union node *redir, **rpp;
9619 switch (readtoken()) {
9621 n1 = (union node *)stalloc(sizeof (struct nif));
9623 n1->nif.test = list(0);
9624 if (readtoken() != TTHEN)
9626 n1->nif.ifpart = list(0);
9628 while (readtoken() == TELIF) {
9629 n2->nif.elsepart = (union node *)stalloc(sizeof (struct nif));
9630 n2 = n2->nif.elsepart;
9632 n2->nif.test = list(0);
9633 if (readtoken() != TTHEN)
9635 n2->nif.ifpart = list(0);
9637 if (lasttoken == TELSE)
9638 n2->nif.elsepart = list(0);
9640 n2->nif.elsepart = NULL;
9643 if (readtoken() != TFI)
9650 n1 = (union node *)stalloc(sizeof (struct nbinary));
9651 n1->type = (lasttoken == TWHILE)? NWHILE : NUNTIL;
9652 n1->nbinary.ch1 = list(0);
9653 if ((got=readtoken()) != TDO) {
9654 TRACE(("expecting DO got %s %s\n", tokname[got], got == TWORD ? wordtext : ""));
9657 n1->nbinary.ch2 = list(0);
9658 if (readtoken() != TDONE)
9664 if (readtoken() != TWORD || quoteflag || ! goodname(wordtext))
9665 synerror("Bad for loop variable");
9666 n1 = (union node *)stalloc(sizeof (struct nfor));
9668 n1->nfor.var = wordtext;
9670 if (readtoken() == TIN) {
9672 while (readtoken() == TWORD) {
9673 n2 = (union node *)stalloc(sizeof (struct narg));
9675 n2->narg.text = wordtext;
9676 n2->narg.backquote = backquotelist;
9678 app = &n2->narg.next;
9682 if (lasttoken != TNL && lasttoken != TSEMI)
9685 static char argvars[5] = {CTLVAR, VSNORMAL|VSQUOTE,
9687 n2 = (union node *)stalloc(sizeof (struct narg));
9689 n2->narg.text = argvars;
9690 n2->narg.backquote = NULL;
9691 n2->narg.next = NULL;
9694 * Newline or semicolon here is optional (but note
9695 * that the original Bourne shell only allowed NL).
9697 if (lasttoken != TNL && lasttoken != TSEMI)
9701 if (readtoken() != TDO)
9703 n1->nfor.body = list(0);
9704 if (readtoken() != TDONE)
9709 n1 = (union node *)stalloc(sizeof (struct ncase));
9711 if (readtoken() != TWORD)
9713 n1->ncase.expr = n2 = (union node *)stalloc(sizeof (struct narg));
9715 n2->narg.text = wordtext;
9716 n2->narg.backquote = backquotelist;
9717 n2->narg.next = NULL;
9720 } while (readtoken() == TNL);
9721 if (lasttoken != TIN)
9722 synerror("expecting \"in\"");
9723 cpp = &n1->ncase.cases;
9724 checkkwd = 2, readtoken();
9726 if (lasttoken == TLP)
9728 *cpp = cp = (union node *)stalloc(sizeof (struct nclist));
9730 app = &cp->nclist.pattern;
9732 *app = ap = (union node *)stalloc(sizeof (struct narg));
9734 ap->narg.text = wordtext;
9735 ap->narg.backquote = backquotelist;
9736 if (checkkwd = 2, readtoken() != TPIPE)
9738 app = &ap->narg.next;
9741 ap->narg.next = NULL;
9742 if (lasttoken != TRP)
9744 cp->nclist.body = list(0);
9747 if ((t = readtoken()) != TESAC) {
9749 synexpect(TENDCASE);
9751 checkkwd = 2, readtoken();
9753 cpp = &cp->nclist.next;
9754 } while(lasttoken != TESAC);
9759 n1 = (union node *)stalloc(sizeof (struct nredir));
9760 n1->type = NSUBSHELL;
9761 n1->nredir.n = list(0);
9762 n1->nredir.redirect = NULL;
9763 if (readtoken() != TRP)
9769 if (readtoken() != TEND)
9773 /* Handle an empty command like other simple commands. */
9782 * An empty command before a ; doesn't make much sense, and
9783 * should certainly be disallowed in the case of `if ;'.
9797 /* Now check for redirection which may follow command */
9798 while (readtoken() == TREDIR) {
9799 *rpp = n2 = redirnode;
9800 rpp = &n2->nfile.next;
9806 if (n1->type != NSUBSHELL) {
9807 n2 = (union node *)stalloc(sizeof (struct nredir));
9812 n1->nredir.redirect = redir;
9821 union node *args, **app;
9822 union node *n = NULL;
9823 union node *vars, **vpp;
9824 union node **rpp, *redir;
9835 switch (readtoken()) {
9838 n = (union node *)stalloc(sizeof (struct narg));
9840 n->narg.text = wordtext;
9841 n->narg.backquote = backquotelist;
9842 if (lasttoken == TWORD) {
9844 app = &n->narg.next;
9847 vpp = &n->narg.next;
9851 *rpp = n = redirnode;
9852 rpp = &n->nfile.next;
9853 parsefname(); /* read name of redirection file */
9857 args && app == &args->narg.next &&
9860 /* We have a function */
9861 if (readtoken() != TRP)
9865 n->narg.next = command();
9878 n = (union node *)stalloc(sizeof (struct ncmd));
9880 n->ncmd.backgnd = 0;
9881 n->ncmd.args = args;
9882 n->ncmd.assign = vars;
9883 n->ncmd.redirect = redir;
9891 n = (union node *)stalloc(sizeof (struct narg));
9893 n->narg.next = NULL;
9894 n->narg.text = wordtext;
9895 n->narg.backquote = backquotelist;
9899 static void fixredir(union node *n, const char *text, int err)
9901 TRACE(("Fix redir %s %d\n", text, err));
9903 n->ndup.vname = NULL;
9905 if (is_digit(text[0]) && text[1] == '\0')
9906 n->ndup.dupfd = digit_val(text[0]);
9907 else if (text[0] == '-' && text[1] == '\0')
9912 synerror("Bad fd number");
9914 n->ndup.vname = makename();
9921 union node *n = redirnode;
9923 if (readtoken() != TWORD)
9925 if (n->type == NHERE) {
9926 struct heredoc *here = heredoc;
9932 TRACE(("Here document %d\n", n->type));
9933 if (here->striptabs) {
9934 while (*wordtext == '\t')
9937 if (! noexpand(wordtext) || (i = strlen(wordtext)) == 0 || i > EOFMARKLEN)
9938 synerror("Illegal eof marker for << redirection");
9939 rmescapes(wordtext);
9940 here->eofmark = wordtext;
9942 if (heredoclist == NULL)
9945 for (p = heredoclist ; p->next ; p = p->next);
9948 } else if (n->type == NTOFD || n->type == NFROMFD) {
9949 fixredir(n, wordtext, 0);
9951 n->nfile.fname = makename();
9957 * Input any here documents.
9962 struct heredoc *here;
9965 while (heredoclist) {
9967 heredoclist = here->next;
9972 readtoken1(pgetc(), here->here->type == NHERE? SQSYNTAX : DQSYNTAX,
9973 here->eofmark, here->striptabs);
9974 n = (union node *)stalloc(sizeof (struct narg));
9975 n->narg.type = NARG;
9976 n->narg.next = NULL;
9977 n->narg.text = wordtext;
9978 n->narg.backquote = backquotelist;
9979 here->here->nhere.doc = n;
9997 int savecheckalias = checkalias;
9998 int savecheckkwd = checkkwd;
10003 int alreadyseen = tokpushback;
10013 checkalias = savecheckalias;
10020 if (checkkwd == 2) {
10029 * check for keywords
10031 if (t == TWORD && !quoteflag)
10033 const char *const *pp;
10035 if ((pp = findkwd(wordtext))) {
10036 lasttoken = t = pp - parsekwd + KWDOFFSET;
10037 TRACE(("keyword %s recognized\n", tokname[t]));
10048 } else if (checkalias == 2 && isassignment(wordtext)) {
10049 lasttoken = t = TASSIGN;
10051 } else if (checkalias) {
10052 if (!quoteflag && (ap = lookupalias(wordtext, 1)) != NULL) {
10054 pushstring(ap->val, strlen(ap->val), ap);
10056 checkkwd = savecheckkwd;
10065 TRACE(("token %s %s\n", tokname[t], t == TWORD || t == TASSIGN ? wordtext : ""));
10067 TRACE(("reread token %s %s\n", tokname[t], t == TWORD || t == TASSIGN ? wordtext : ""));
10074 * Read the next input token.
10075 * If the token is a word, we set backquotelist to the list of cmds in
10076 * backquotes. We set quoteflag to true if any part of the word was
10078 * If the token is TREDIR, then we set redirnode to a structure containing
10080 * In all cases, the variable startlinno is set to the number of the line
10081 * on which the token starts.
10083 * [Change comment: here documents and internal procedures]
10084 * [Readtoken shouldn't have any arguments. Perhaps we should make the
10085 * word parsing code into a separate routine. In this case, readtoken
10086 * doesn't need to have any internal procedures, but parseword does.
10087 * We could also make parseoperator in essence the main routine, and
10088 * have parseword (readtoken1?) handle both words and redirection.]
10091 #define RETURN(token) return lasttoken = token
10105 startlinno = plinno;
10106 for (;;) { /* until token or start of word found */
10109 case ' ': case '\t':
10115 while ((c = pgetc()) != '\n' && c != PEOF);
10119 if (pgetc() == '\n') {
10120 startlinno = ++plinno;
10131 needprompt = doprompt;
10136 if (pgetc() == '&')
10141 if (pgetc() == '|')
10146 if (pgetc() == ';')
10159 return readtoken1(c, BASESYNTAX, (char *)NULL, 0);
10166 * If eofmark is NULL, read a word or a redirection symbol. If eofmark
10167 * is not NULL, read a here document. In the latter case, eofmark is the
10168 * word which marks the end of the document and striptabs is true if
10169 * leading tabs should be stripped from the document. The argument firstc
10170 * is the first character of the input token or document.
10172 * Because C does not have internal subroutines, I have simulated them
10173 * using goto's to implement the subroutine linkage. The following macros
10174 * will run code that appears at the end of readtoken1.
10177 #define CHECKEND() {goto checkend; checkend_return:;}
10178 #define PARSEREDIR() {goto parseredir; parseredir_return:;}
10179 #define PARSESUB() {goto parsesub; parsesub_return:;}
10180 #define PARSEBACKQOLD() {oldstyle = 1; goto parsebackq; parsebackq_oldreturn:;}
10181 #define PARSEBACKQNEW() {oldstyle = 0; goto parsebackq; parsebackq_newreturn:;}
10182 #define PARSEARITH() {goto parsearith; parsearith_return:;}
10185 readtoken1(firstc, syntax, eofmark, striptabs)
10187 char const *syntax;
10194 char line[EOFMARKLEN + 1];
10195 struct nodelist *bqlist;
10198 int varnest; /* levels of variables expansion */
10199 int arinest; /* levels of arithmetic expansion */
10200 int parenlevel; /* levels of parens in arithmetic */
10201 int dqvarnest; /* levels of variables expansion within double quotes */
10203 char const *prevsyntax; /* syntax before arithmetic */
10205 /* Avoid longjmp clobbering */
10211 (void) &parenlevel;
10214 (void) &prevsyntax;
10218 startlinno = plinno;
10220 if (syntax == DQSYNTAX)
10229 STARTSTACKSTR(out);
10230 loop: { /* for each line, until end of word */
10231 CHECKEND(); /* set c to PEOF if at end of here document */
10232 for (;;) { /* until end of line or end of word */
10233 CHECKSTRSPACE(3, out); /* permit 3 calls to USTPUTC */
10234 switch(syntax[c]) {
10235 case CNL: /* '\n' */
10236 if (syntax == BASESYNTAX)
10237 goto endword; /* exit outer loop */
10245 goto loop; /* continue outer loop */
10250 if ((eofmark == NULL || dblquote) &&
10252 USTPUTC(CTLESC, out);
10255 case CBACK: /* backslash */
10258 USTPUTC('\\', out);
10260 } else if (c == '\n') {
10266 if (dblquote && c != '\\' && c != '`' && c != '$'
10267 && (c != '"' || eofmark != NULL))
10268 USTPUTC('\\', out);
10269 if (SQSYNTAX[c] == CCTL)
10270 USTPUTC(CTLESC, out);
10271 else if (eofmark == NULL)
10272 USTPUTC(CTLQUOTEMARK, out);
10278 if (eofmark == NULL)
10279 USTPUTC(CTLQUOTEMARK, out);
10283 if (eofmark == NULL)
10284 USTPUTC(CTLQUOTEMARK, out);
10289 if (eofmark != NULL && arinest == 0 &&
10294 syntax = ARISYNTAX;
10296 } else if (eofmark == NULL &&
10298 syntax = BASESYNTAX;
10304 case CVAR: /* '$' */
10305 PARSESUB(); /* parse substitution */
10307 case CENDVAR: /* '}' */
10310 if (dqvarnest > 0) {
10313 USTPUTC(CTLENDVAR, out);
10318 #ifdef ASH_MATH_SUPPORT
10319 case CLP: /* '(' in arithmetic */
10323 case CRP: /* ')' in arithmetic */
10324 if (parenlevel > 0) {
10328 if (pgetc() == ')') {
10329 if (--arinest == 0) {
10330 USTPUTC(CTLENDARI, out);
10331 syntax = prevsyntax;
10332 if (syntax == DQSYNTAX)
10340 * unbalanced parens
10341 * (don't 2nd guess - no error)
10349 case CBQUOTE: /* '`' */
10353 goto endword; /* exit outer loop */
10358 goto endword; /* exit outer loop */
10369 if (syntax == ARISYNTAX)
10370 synerror("Missing '))'");
10371 if (syntax != BASESYNTAX && ! parsebackquote && eofmark == NULL)
10372 synerror("Unterminated quoted string");
10373 if (varnest != 0) {
10374 startlinno = plinno;
10375 synerror("Missing '}'");
10377 USTPUTC('\0', out);
10378 len = out - stackblock();
10379 out = stackblock();
10380 if (eofmark == NULL) {
10381 if ((c == '>' || c == '<')
10384 && (*out == '\0' || is_digit(*out))) {
10386 return lasttoken = TREDIR;
10391 quoteflag = quotef;
10392 backquotelist = bqlist;
10393 grabstackblock(len);
10395 return lasttoken = TWORD;
10396 /* end of readtoken routine */
10401 * Check to see whether we are at the end of the here document. When this
10402 * is called, c is set to the first character of the next input line. If
10403 * we are at the end of the here document, this routine sets the c to PEOF.
10414 while (c == '\t') {
10418 if (c == *eofmark) {
10419 if (pfgets(line, sizeof line) != NULL) {
10423 for (q = eofmark + 1 ; *q && *p == *q ; p++, q++);
10424 if (*p == '\n' && *q == '\0') {
10427 needprompt = doprompt;
10429 pushstring(line, strlen(line), NULL);
10434 goto checkend_return;
10439 * Parse a redirection operator. The variable "out" points to a string
10440 * specifying the fd to be redirected. The variable "c" contains the
10441 * first character of the redirection operator.
10448 np = (union node *)stalloc(sizeof (struct nfile));
10453 np->type = NAPPEND;
10462 } else { /* c == '<' */
10464 switch (c = pgetc()) {
10466 if (sizeof (struct nfile) != sizeof (struct nhere)) {
10467 np = (union node *)stalloc(sizeof (struct nhere));
10471 heredoc = (struct heredoc *)stalloc(sizeof (struct heredoc));
10472 heredoc->here = np;
10473 if ((c = pgetc()) == '-') {
10474 heredoc->striptabs = 1;
10476 heredoc->striptabs = 0;
10482 np->type = NFROMFD;
10486 np->type = NFROMTO;
10496 np->nfile.fd = digit_val(fd);
10498 goto parseredir_return;
10503 * Parse a substitution. At this point, we have read the dollar sign
10504 * and nothing else.
10512 static const char types[] = "}-+?=";
10517 (c != '(' && c != '{' && !is_name(c) && !is_special(c))
10521 } else if (c == '(') { /* $(command) or $((arith)) */
10522 if (pgetc() == '(') {
10529 USTPUTC(CTLVAR, out);
10530 typeloc = out - stackblock();
10531 USTPUTC(VSNORMAL, out);
10532 subtype = VSNORMAL;
10536 if ((c = pgetc()) == '}')
10539 subtype = VSLENGTH;
10544 if (c > PEOA && is_name(c)) {
10548 } while (c > PEOA && is_in_name(c));
10549 } else if (is_digit(c)) {
10553 } while (is_digit(c));
10555 else if (is_special(c)) {
10560 badsub: synerror("Bad substitution");
10564 if (subtype == 0) {
10571 p = strchr(types, c);
10574 subtype = p - types + VSNORMAL;
10580 subtype = c == '#' ? VSTRIMLEFT :
10593 if (dblquote || arinest)
10595 *(stackblock() + typeloc) = subtype | flags;
10596 if (subtype != VSNORMAL) {
10603 goto parsesub_return;
10608 * Called to parse command substitutions. Newstyle is set if the command
10609 * is enclosed inside $(...); nlpp is a pointer to the head of the linked
10610 * list of commands (passed by reference), and savelen is the number of
10611 * characters on the top of the stack which must be preserved.
10615 struct nodelist **nlpp;
10618 char *volatile str;
10619 struct jmploc jmploc;
10620 struct jmploc *volatile savehandler;
10624 (void) &saveprompt;
10627 savepbq = parsebackquote;
10628 if (setjmp(jmploc.loc)) {
10631 parsebackquote = 0;
10632 handler = savehandler;
10633 longjmp(handler->loc, 1);
10637 savelen = out - stackblock();
10639 str = ckmalloc(savelen);
10640 memcpy(str, stackblock(), savelen);
10642 savehandler = handler;
10646 /* We must read until the closing backquote, giving special
10647 treatment to some slashes, and then push the string and
10648 reread it as input, interpreting it normally. */
10655 STARTSTACKSTR(pout);
10661 switch (pc = pgetc()) {
10666 if ((pc = pgetc()) == '\n') {
10673 * If eating a newline, avoid putting
10674 * the newline into the new character
10675 * stream (via the STPUTC after the
10680 if (pc != '\\' && pc != '`' && pc != '$'
10681 && (!dblquote || pc != '"'))
10682 STPUTC('\\', pout);
10692 startlinno = plinno;
10693 synerror("EOF in backquote substitution");
10697 needprompt = doprompt;
10706 STPUTC('\0', pout);
10707 psavelen = pout - stackblock();
10708 if (psavelen > 0) {
10709 pstr = grabstackstr(pout);
10710 setinputstring(pstr);
10715 nlpp = &(*nlpp)->next;
10716 *nlpp = (struct nodelist *)stalloc(sizeof (struct nodelist));
10717 (*nlpp)->next = NULL;
10718 parsebackquote = oldstyle;
10721 saveprompt = doprompt;
10728 doprompt = saveprompt;
10730 if (readtoken() != TRP)
10737 * Start reading from old file again, ignoring any pushed back
10738 * tokens left from the backquote parsing
10743 while (stackblocksize() <= savelen)
10745 STARTSTACKSTR(out);
10747 memcpy(out, str, savelen);
10748 STADJUST(savelen, out);
10754 parsebackquote = savepbq;
10755 handler = savehandler;
10756 if (arinest || dblquote)
10757 USTPUTC(CTLBACKQ | CTLQUOTE, out);
10759 USTPUTC(CTLBACKQ, out);
10761 goto parsebackq_oldreturn;
10763 goto parsebackq_newreturn;
10767 * Parse an arithmetic expansion (indicate start of one and set state)
10771 if (++arinest == 1) {
10772 prevsyntax = syntax;
10773 syntax = ARISYNTAX;
10774 USTPUTC(CTLARI, out);
10781 * we collapse embedded arithmetic expansion to
10782 * parenthesis, which should be equivalent
10786 goto parsearith_return;
10789 } /* end of readtoken */
10793 * Returns true if the text contains nothing to expand (no dollar signs
10805 while ((c = *p++) != '\0') {
10806 if (c == CTLQUOTEMARK)
10810 else if (BASESYNTAX[(int)c] == CCTL)
10818 * Return true if the argument is a legal variable name (a letter or
10819 * underscore followed by zero or more letters, underscores, and digits).
10823 goodname(const char *name)
10831 if (! is_in_name(*p))
10839 * Called when an unexpected token is read during the parse. The argument
10840 * is the token that is expected, or -1 if more than one type of token can
10841 * occur at this point.
10851 snprintf(msg, 64, "%s unexpected (expecting %s)",
10852 tokname[lasttoken], tokname[token]);
10854 snprintf(msg, 64, "%s unexpected", tokname[lasttoken]);
10862 synerror(const char *msg)
10865 out2fmt("%s: %d: ", commandname, startlinno);
10866 out2fmt("Syntax error: %s\n", msg);
10867 error((char *)NULL);
10873 * called by editline -- any expansions to the prompt
10874 * should be added here.
10877 setprompt(int whichprompt)
10880 switch (whichprompt) {
10895 * Code for dealing with input/output redirection.
10898 #define EMPTY -2 /* marks an unused slot in redirtab */
10900 # define PIPESIZE 4096 /* amount of buffering in a pipe */
10902 # define PIPESIZE PIPE_BUF
10907 * Open a file in noclobber mode.
10908 * The code was copied from bash.
10911 noclobberopen(const char *fname)
10914 struct stat finfo, finfo2;
10917 * If the file exists and is a regular file, return an error
10920 r = stat(fname, &finfo);
10921 if (r == 0 && S_ISREG(finfo.st_mode)) {
10927 * If the file was not present (r != 0), make sure we open it
10928 * exclusively so that if it is created before we open it, our open
10929 * will fail. Make sure that we do not truncate an existing file.
10930 * Note that we don't turn on O_EXCL unless the stat failed -- if the
10931 * file was not a regular file, we leave O_EXCL off.
10934 return open(fname, O_WRONLY|O_CREAT|O_EXCL, 0666);
10935 fd = open(fname, O_WRONLY|O_CREAT, 0666);
10937 /* If the open failed, return the file descriptor right away. */
10942 * OK, the open succeeded, but the file may have been changed from a
10943 * non-regular file to a regular file between the stat and the open.
10944 * We are assuming that the O_EXCL open handles the case where FILENAME
10945 * did not exist and is symlinked to an existing file between the stat
10950 * If we can open it and fstat the file descriptor, and neither check
10951 * revealed that it was a regular file, and the file has not been
10952 * replaced, return the file descriptor.
10954 if (fstat(fd, &finfo2) == 0 && !S_ISREG(finfo2.st_mode) &&
10955 finfo.st_dev == finfo2.st_dev && finfo.st_ino == finfo2.st_ino)
10958 /* The file has been replaced. badness. */
10965 * Handle here documents. Normally we fork off a process to write the
10966 * data to a pipe. If the document is short, we can stuff the data in
10967 * the pipe without forking.
10971 openhere(const union node *redir)
10977 error("Pipe call failed");
10978 if (redir->type == NHERE) {
10979 len = strlen(redir->nhere.doc->narg.text);
10980 if (len <= PIPESIZE) {
10981 xwrite(pip[1], redir->nhere.doc->narg.text, len);
10985 if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) {
10987 signal(SIGINT, SIG_IGN);
10988 signal(SIGQUIT, SIG_IGN);
10989 signal(SIGHUP, SIG_IGN);
10991 signal(SIGTSTP, SIG_IGN);
10993 signal(SIGPIPE, SIG_DFL);
10994 if (redir->type == NHERE)
10995 xwrite(pip[1], redir->nhere.doc->narg.text, len);
10997 expandhere(redir->nhere.doc, pip[1]);
11007 openredirect(const union node *redir)
11012 switch (redir->nfile.type) {
11014 fname = redir->nfile.expfname;
11015 if ((f = open(fname, O_RDONLY)) < 0)
11019 fname = redir->nfile.expfname;
11020 if ((f = open(fname, O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0)
11024 /* Take care of noclobber mode. */
11026 fname = redir->nfile.expfname;
11027 if ((f = noclobberopen(fname)) < 0)
11032 fname = redir->nfile.expfname;
11034 if ((f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
11037 if ((f = creat(fname, 0666)) < 0)
11042 fname = redir->nfile.expfname;
11044 if ((f = open(fname, O_WRONLY|O_CREAT|O_APPEND, 0666)) < 0)
11047 if ((f = open(fname, O_WRONLY)) < 0
11048 && (f = creat(fname, 0666)) < 0)
11050 lseek(f, (off_t)0, 2);
11057 /* Fall through to eliminate warning. */
11064 f = openhere(redir);
11070 error("cannot create %s: %s", fname, errmsg(errno, E_CREAT));
11072 error("cannot open %s: %s", fname, errmsg(errno, E_OPEN));
11077 * Process a list of redirection commands. If the REDIR_PUSH flag is set,
11078 * old file descriptors are stashed away so that the redirection can be
11079 * undone by calling popredir. If the REDIR_BACKQ flag is set, then the
11080 * standard output, and the standard error if it becomes a duplicate of
11085 redirect(union node *redir, int flags)
11088 struct redirtab *sv = NULL;
11093 int fd1dup = flags & REDIR_BACKQ;; /* stdout `cmd` redir to pipe */
11095 if (flags & REDIR_PUSH) {
11096 sv = ckmalloc(sizeof (struct redirtab));
11097 for (i = 0 ; i < 10 ; i++)
11098 sv->renamed[i] = EMPTY;
11099 sv->next = redirlist;
11102 for (n = redir ; n ; n = n->nfile.next) {
11105 if ((n->nfile.type == NTOFD || n->nfile.type == NFROMFD) &&
11106 n->ndup.dupfd == fd)
11107 continue; /* redirect from/to same file descriptor */
11110 newfd = openredirect(n);
11111 if ((flags & REDIR_PUSH) && sv->renamed[fd] == EMPTY) {
11114 } else if ((i = fcntl(fd, F_DUPFD, 10)) == -1) {
11118 dupredirect(n, newfd, fd1dup);
11128 error("%d: %m", fd);
11134 if (flags & REDIR_PUSH) {
11135 sv->renamed[fd] = i;
11138 } else if (fd != newfd) {
11144 dupredirect(n, newfd, fd1dup);
11151 dupredirect(const union node *redir, int f, int fd1dup)
11153 int fd = redir->nfile.fd;
11157 if (redir->nfile.type == NTOFD || redir->nfile.type == NFROMFD) {
11158 if (redir->ndup.dupfd >= 0) { /* if not ">&-" */
11159 if (redir->ndup.dupfd!=1 || fd1dup!=1)
11160 dup_as_newfd(redir->ndup.dupfd, fd);
11166 dup_as_newfd(f, fd);
11175 * Undo the effects of the last redirection.
11181 struct redirtab *rp = redirlist;
11185 for (i = 0 ; i < 10 ; i++) {
11186 if (rp->renamed[i] != EMPTY) {
11190 if (rp->renamed[i] >= 0) {
11191 dup_as_newfd(rp->renamed[i], i);
11192 close(rp->renamed[i]);
11196 redirlist = rp->next;
11202 * Discard all saved file descriptors.
11207 struct redirtab *rp;
11210 for (rp = redirlist ; rp ; rp = rp->next) {
11211 for (i = 0 ; i < 10 ; i++) {
11212 if (rp->renamed[i] >= 0) {
11213 close(rp->renamed[i]);
11215 rp->renamed[i] = EMPTY;
11222 * Copy a file descriptor to be >= to. Returns -1
11223 * if the source file descriptor is closed, EMPTY if there are no unused
11224 * file descriptors left.
11228 dup_as_newfd(from, to)
11234 newfd = fcntl(from, F_DUPFD, to);
11236 if (errno == EMFILE)
11239 error("%d: %m", from);
11244 /*#ifdef __weak_alias
11245 __weak_alias(getmode,_getmode)
11246 __weak_alias(setmode,_setmode)
11250 #if defined(__GLIBC__) && __GLIBC__ >= 2
11251 #define S_ISTXT __S_ISVTX
11253 #define S_ISTXT S_ISVTX
11257 #define SET_LEN 6 /* initial # of bitcmd struct to malloc */
11258 #define SET_LEN_INCR 4 /* # of bitcmd structs to add as needed */
11260 typedef struct bitcmd {
11266 #define CMD2_CLR 0x01
11267 #define CMD2_SET 0x02
11268 #define CMD2_GBITS 0x04
11269 #define CMD2_OBITS 0x08
11270 #define CMD2_UBITS 0x10
11272 static BITCMD *addcmd (BITCMD *, int, int, int, u_int);
11273 static void compress_mode (BITCMD *);
11274 #ifdef SETMODE_DEBUG
11275 static void dumpmode (BITCMD *);
11279 * Given the old mode and an array of bitcmd structures, apply the operations
11280 * described in the bitcmd structures to the old mode, and return the new mode.
11281 * Note that there is no '=' command; a strict assignment is just a '-' (clear
11282 * bits) followed by a '+' (set bits).
11285 getmode(bbox, omode)
11290 mode_t clrval, newmode, value;
11292 _DIAGASSERT(bbox != NULL);
11294 set = (const BITCMD *)bbox;
11296 for (value = 0;; set++)
11299 * When copying the user, group or other bits around, we "know"
11300 * where the bits are in the mode so that we can do shifts to
11301 * copy them around. If we don't use shifts, it gets real
11302 * grundgy with lots of single bit checks and bit sets.
11305 value = (newmode & S_IRWXU) >> 6;
11309 value = (newmode & S_IRWXG) >> 3;
11313 value = newmode & S_IRWXO;
11314 common: if (set->cmd2 & CMD2_CLR) {
11316 (set->cmd2 & CMD2_SET) ? S_IRWXO : value;
11317 if (set->cmd2 & CMD2_UBITS)
11318 newmode &= ~((clrval<<6) & set->bits);
11319 if (set->cmd2 & CMD2_GBITS)
11320 newmode &= ~((clrval<<3) & set->bits);
11321 if (set->cmd2 & CMD2_OBITS)
11322 newmode &= ~(clrval & set->bits);
11324 if (set->cmd2 & CMD2_SET) {
11325 if (set->cmd2 & CMD2_UBITS)
11326 newmode |= (value<<6) & set->bits;
11327 if (set->cmd2 & CMD2_GBITS)
11328 newmode |= (value<<3) & set->bits;
11329 if (set->cmd2 & CMD2_OBITS)
11330 newmode |= value & set->bits;
11335 newmode |= set->bits;
11339 newmode &= ~set->bits;
11343 if (omode & (S_IFDIR|S_IXUSR|S_IXGRP|S_IXOTH))
11344 newmode |= set->bits;
11349 #ifdef SETMODE_DEBUG
11350 (void)printf("getmode:%04o -> %04o\n", omode, newmode);
11356 #define ADDCMD(a, b, c, d) do { \
11357 if (set >= endset) { \
11359 setlen += SET_LEN_INCR; \
11360 newset = realloc(saveset, sizeof(BITCMD) * setlen); \
11361 if (newset == NULL) { \
11365 set = newset + (set - saveset); \
11366 saveset = newset; \
11367 endset = newset + (setlen - 2); \
11369 set = addcmd(set, (a), (b), (c), (d)); \
11370 } while (/*CONSTCOND*/0)
11372 #define STANDARD_BITS (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO)
11380 BITCMD *set, *saveset, *endset;
11381 sigset_t mysigset, sigoset;
11383 int equalopdone = 0; /* pacify gcc */
11384 int permXbits, setlen;
11390 * Get a copy of the mask for the permissions that are mask relative.
11391 * Flip the bits, we want what's not set. Since it's possible that
11392 * the caller is opening files inside a signal handler, protect them
11395 sigfillset(&mysigset);
11396 (void)sigprocmask(SIG_BLOCK, &mysigset, &sigoset);
11397 (void)umask(mask = umask(0));
11399 (void)sigprocmask(SIG_SETMASK, &sigoset, NULL);
11401 setlen = SET_LEN + 2;
11403 if ((set = malloc((u_int)(sizeof(BITCMD) * setlen))) == NULL)
11406 endset = set + (setlen - 2);
11409 * If an absolute number, get it and return; disallow non-octal digits
11412 if (is_digit((unsigned char)*p)) {
11413 perm = (mode_t)strtol(p, &ep, 8);
11414 if (*ep || perm & ~(STANDARD_BITS|S_ISTXT)) {
11418 ADDCMD('=', (STANDARD_BITS|S_ISTXT), perm, mask);
11424 * Build list of structures to set/clear/copy bits as described by
11425 * each clause of the symbolic mode.
11428 /* First, find out which bits might be modified. */
11429 for (who = 0;; ++p) {
11432 who |= STANDARD_BITS;
11435 who |= S_ISUID|S_IRWXU;
11438 who |= S_ISGID|S_IRWXG;
11448 getop: if ((op = *p++) != '+' && op != '-' && op != '=') {
11456 for (perm = 0, permXbits = 0;; ++p) {
11459 perm |= S_IRUSR|S_IRGRP|S_IROTH;
11463 * If specific bits where requested and
11464 * only "other" bits ignore set-id.
11466 if (who == 0 || (who & ~S_IRWXO))
11467 perm |= S_ISUID|S_ISGID;
11471 * If specific bits where requested and
11472 * only "other" bits ignore set-id.
11474 if (who == 0 || (who & ~S_IRWXO)) {
11480 perm |= S_IWUSR|S_IWGRP|S_IWOTH;
11483 permXbits = S_IXUSR|S_IXGRP|S_IXOTH;
11486 perm |= S_IXUSR|S_IXGRP|S_IXOTH;
11492 * When ever we hit 'u', 'g', or 'o', we have
11493 * to flush out any partial mode that we have,
11494 * and then do the copying of the mode bits.
11497 ADDCMD(op, who, perm, mask);
11502 if (op == '+' && permXbits) {
11503 ADDCMD('X', who, permXbits, mask);
11506 ADDCMD(*p, who, op, mask);
11511 * Add any permissions that we haven't already
11514 if (perm || (op == '=' && !equalopdone)) {
11517 ADDCMD(op, who, perm, mask);
11521 ADDCMD('X', who, permXbits, mask);
11535 #ifdef SETMODE_DEBUG
11536 (void)printf("Before compress_mode()\n");
11539 compress_mode(saveset);
11540 #ifdef SETMODE_DEBUG
11541 (void)printf("After compress_mode()\n");
11548 addcmd(set, op, who, oparg, mask)
11555 _DIAGASSERT(set != NULL);
11560 set->bits = who ? who : STANDARD_BITS;
11569 set->bits = (who ? who : mask) & oparg;
11577 set->cmd2 = ((who & S_IRUSR) ? CMD2_UBITS : 0) |
11578 ((who & S_IRGRP) ? CMD2_GBITS : 0) |
11579 ((who & S_IROTH) ? CMD2_OBITS : 0);
11580 set->bits = (mode_t)~0;
11582 set->cmd2 = CMD2_UBITS | CMD2_GBITS | CMD2_OBITS;
11587 set->cmd2 |= CMD2_SET;
11588 else if (oparg == '-')
11589 set->cmd2 |= CMD2_CLR;
11590 else if (oparg == '=')
11591 set->cmd2 |= CMD2_SET|CMD2_CLR;
11597 #ifdef SETMODE_DEBUG
11603 _DIAGASSERT(set != NULL);
11605 for (; set->cmd; ++set)
11606 (void)printf("cmd: '%c' bits %04o%s%s%s%s%s%s\n",
11607 set->cmd, set->bits, set->cmd2 ? " cmd2:" : "",
11608 set->cmd2 & CMD2_CLR ? " CLR" : "",
11609 set->cmd2 & CMD2_SET ? " SET" : "",
11610 set->cmd2 & CMD2_UBITS ? " UBITS" : "",
11611 set->cmd2 & CMD2_GBITS ? " GBITS" : "",
11612 set->cmd2 & CMD2_OBITS ? " OBITS" : "");
11617 * Given an array of bitcmd structures, compress by compacting consecutive
11618 * '+', '-' and 'X' commands into at most 3 commands, one of each. The 'u',
11619 * 'g' and 'o' commands continue to be separate. They could probably be
11620 * compacted, but it's not worth the effort.
11627 int setbits, clrbits, Xbits, op;
11629 _DIAGASSERT(set != NULL);
11631 for (nset = set;;) {
11632 /* Copy over any 'u', 'g' and 'o' commands. */
11633 while ((op = nset->cmd) != '+' && op != '-' && op != 'X') {
11639 for (setbits = clrbits = Xbits = 0;; nset++) {
11640 if ((op = nset->cmd) == '-') {
11641 clrbits |= nset->bits;
11642 setbits &= ~nset->bits;
11643 Xbits &= ~nset->bits;
11644 } else if (op == '+') {
11645 setbits |= nset->bits;
11646 clrbits &= ~nset->bits;
11647 Xbits &= ~nset->bits;
11648 } else if (op == 'X')
11649 Xbits |= nset->bits & ~setbits;
11656 set->bits = clrbits;
11662 set->bits = setbits;
11674 static void shtree (union node *, int, char *, FILE*);
11675 static void shcmd (union node *, FILE *);
11676 static void sharg (union node *, FILE *);
11677 static void indent (int, char *, FILE *);
11678 static void trstring (char *);
11685 trputs("showtree called\n");
11686 shtree(n, 1, NULL, stdout);
11691 shtree(n, ind, pfx, fp)
11697 struct nodelist *lp;
11703 indent(ind, pfx, fp);
11714 shtree(n->nbinary.ch1, ind, NULL, fp);
11717 shtree(n->nbinary.ch2, ind, NULL, fp);
11725 for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
11730 if (n->npipe.backgnd)
11736 fprintf(fp, "<node type %d>", n->type);
11756 for (np = cmd->ncmd.args ; np ; np = np->narg.next) {
11762 for (np = cmd->ncmd.redirect ; np ; np = np->nfile.next) {
11765 switch (np->nfile.type) {
11766 case NTO: s = ">"; dftfd = 1; break;
11767 case NAPPEND: s = ">>"; dftfd = 1; break;
11768 case NTOFD: s = ">&"; dftfd = 1; break;
11769 case NTOOV: s = ">|"; dftfd = 1; break;
11770 case NFROM: s = "<"; dftfd = 0; break;
11771 case NFROMFD: s = "<&"; dftfd = 0; break;
11772 case NFROMTO: s = "<>"; dftfd = 0; break;
11773 default: s = "*error*"; dftfd = 0; break;
11775 if (np->nfile.fd != dftfd)
11776 fprintf(fp, "%d", np->nfile.fd);
11778 if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) {
11779 fprintf(fp, "%d", np->ndup.dupfd);
11781 sharg(np->nfile.fname, fp);
11795 struct nodelist *bqlist;
11798 if (arg->type != NARG) {
11799 printf("<node type %d>\n", arg->type);
11803 bqlist = arg->narg.backquote;
11804 for (p = arg->narg.text ; *p ; p++) {
11813 if (subtype == VSLENGTH)
11819 if (subtype & VSNUL)
11822 switch (subtype & VSTYPE) {
11841 case VSTRIMLEFTMAX:
11848 case VSTRIMRIGHTMAX:
11855 printf("<subtype %d>", subtype);
11862 case CTLBACKQ|CTLQUOTE:
11865 shtree(bqlist->n, -1, NULL, fp);
11877 indent(amount, pfx, fp)
11884 for (i = 0 ; i < amount ; i++) {
11885 if (pfx && i == amount - 1)
11903 static int debug = 1;
11905 static int debug = 0;
11913 if (tracefile == NULL)
11915 putc(c, tracefile);
11921 trace(const char *fmt, ...)
11925 if (tracefile != NULL) {
11926 (void) vfprintf(tracefile, fmt, va);
11927 if (strchr(fmt, '\n'))
11928 (void) fflush(tracefile);
11938 if (tracefile == NULL)
11940 fputs(s, tracefile);
11941 if (strchr(s, '\n'))
11953 if (tracefile == NULL)
11955 putc('"', tracefile);
11956 for (p = s ; *p ; p++) {
11958 case '\n': c = 'n'; goto backslash;
11959 case '\t': c = 't'; goto backslash;
11960 case '\r': c = 'r'; goto backslash;
11961 case '"': c = '"'; goto backslash;
11962 case '\\': c = '\\'; goto backslash;
11963 case CTLESC: c = 'e'; goto backslash;
11964 case CTLVAR: c = 'v'; goto backslash;
11965 case CTLVAR+CTLQUOTE: c = 'V'; goto backslash;
11966 case CTLBACKQ: c = 'q'; goto backslash;
11967 case CTLBACKQ+CTLQUOTE: c = 'Q'; goto backslash;
11968 backslash: putc('\\', tracefile);
11969 putc(c, tracefile);
11972 if (*p >= ' ' && *p <= '~')
11973 putc(*p, tracefile);
11975 putc('\\', tracefile);
11976 putc(*p >> 6 & 03, tracefile);
11977 putc(*p >> 3 & 07, tracefile);
11978 putc(*p & 07, tracefile);
11983 putc('"', tracefile);
11991 if (tracefile == NULL)
11996 putc(' ', tracefile);
11998 putc('\n', tracefile);
12013 #ifdef not_this_way
12016 if ((p = getenv("HOME")) == NULL) {
12017 if (geteuid() == 0)
12023 strcat(s, "/trace");
12026 strcpy(s, "./trace");
12027 #endif /* not_this_way */
12028 if ((tracefile = fopen(s, "a")) == NULL) {
12029 fprintf(stderr, "Can't open %s\n", s);
12033 if ((flags = fcntl(fileno(tracefile), F_GETFL, 0)) >= 0)
12034 fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND);
12036 fputs("\nTracing started.\n", tracefile);
12043 * The trap builtin.
12047 trapcmd(argc, argv)
12056 for (signo = 0 ; signo < NSIG ; signo++) {
12057 if (trap[signo] != NULL) {
12060 p = single_quote(trap[signo]);
12061 printf("trap -- %s %s\n", p,
12062 signal_names[signo] + (signo ? 3 : 0)
12075 if ((signo = decode_signal(*ap, 0)) < 0)
12076 error("%s: bad trap", *ap);
12079 if (action[0] == '-' && action[1] == '\0')
12082 action = savestr(action);
12085 ckfree(trap[signo]);
12086 trap[signo] = action;
12101 * Set the signal handler for the specified signal. The routine figures
12102 * out what it should be set to.
12106 setsignal(int signo)
12110 struct sigaction act;
12112 if ((t = trap[signo]) == NULL)
12114 else if (*t != '\0')
12118 if (rootshell && action == S_DFL) {
12121 if (iflag || minusc || sflag == 0)
12147 t = &sigmode[signo - 1];
12150 * current setting unknown
12152 if (sigaction(signo, 0, &act) == -1) {
12154 * Pretend it worked; maybe we should give a warning
12155 * here, but other shells don't. We don't alter
12156 * sigmode, so that we retry every time.
12160 if (act.sa_handler == SIG_IGN) {
12161 if (mflag && (signo == SIGTSTP ||
12162 signo == SIGTTIN || signo == SIGTTOU)) {
12163 *t = S_IGN; /* don't hard ignore these */
12167 *t = S_RESET; /* force to be set */
12170 if (*t == S_HARD_IGN || *t == action)
12174 act.sa_handler = onsig;
12177 act.sa_handler = SIG_IGN;
12180 act.sa_handler = SIG_DFL;
12184 sigemptyset(&act.sa_mask);
12185 sigaction(signo, &act, 0);
12196 if (sigmode[signo - 1] != S_IGN && sigmode[signo - 1] != S_HARD_IGN) {
12197 signal(signo, SIG_IGN);
12199 sigmode[signo - 1] = S_HARD_IGN;
12210 if (signo == SIGINT && trap[SIGINT] == NULL) {
12214 gotsig[signo - 1] = 1;
12220 * Called to execute a trap. Perhaps we should avoid entering new trap
12221 * handlers while we are executing a trap handler.
12231 for (i = 1 ; ; i++) {
12238 savestatus=exitstatus;
12239 evalstring(trap[i], 0);
12240 exitstatus=savestatus;
12247 * Called to exit the shell.
12251 exitshell(int status)
12253 struct jmploc loc1, loc2;
12256 TRACE(("exitshell(%d) pid=%d\n", status, getpid()));
12257 if (setjmp(loc1.loc)) {
12260 if (setjmp(loc2.loc)) {
12264 if ((p = trap[0]) != NULL && *p != '\0') {
12268 l1: handler = &loc2; /* probably unnecessary */
12277 static int decode_signal(const char *string, int minsig)
12281 if (is_number(string, &signo)) {
12282 if (signo >= NSIG) {
12292 for (; signo < NSIG; signo++) {
12293 if (!strcasecmp(string, &(signal_names[signo])[3])) {
12297 if (!strcasecmp(string, signal_names[signo])) {
12304 static struct var **hashvar (const char *);
12305 static void showvars (const char *, int, int);
12306 static struct var **findvar (struct var **, const char *);
12309 * Initialize the varable symbol tables and import the environment
12313 * This routine initializes the builtin variables. It is called when the
12314 * shell is initialized and again when a shell procedure is spawned.
12319 const struct varinit *ip;
12323 for (ip = varinit ; (vp = ip->var) != NULL ; ip++) {
12324 if ((vp->flags & VEXPORT) == 0) {
12325 vpp = hashvar(ip->text);
12328 vp->text = strdup(ip->text);
12329 vp->flags = ip->flags;
12330 vp->func = ip->func;
12334 * PS1 depends on uid
12336 if ((vps1.flags & VEXPORT) == 0) {
12337 vpp = hashvar("PS1=");
12340 vps1.text = strdup(geteuid() ? "PS1=$ " : "PS1=# ");
12341 vps1.flags = VSTRFIXED|VTEXTFIXED;
12346 * Set the value of a variable. The flags argument is ored with the
12347 * flags of the variable. If val is NULL, the variable is unset.
12351 setvar(name, val, flags)
12352 const char *name, *val;
12368 if (! is_in_name(*p)) {
12369 if (*p == '\0' || *p == '=')
12375 namelen = p - name;
12377 error("%.*s: bad variable name", namelen, name);
12378 len = namelen + 2; /* 2 is space for '=' and '\0' */
12382 len += vallen = strlen(val);
12385 nameeq = ckmalloc(len);
12386 memcpy(nameeq, name, namelen);
12387 nameeq[namelen] = '=';
12389 memcpy(nameeq + namelen + 1, val, vallen + 1);
12391 nameeq[namelen + 1] = '\0';
12393 setvareq(nameeq, flags);
12400 * Same as setvar except that the variable and value are passed in
12401 * the first argument as name=value. Since the first argument will
12402 * be actually stored in the table, it should not be a string that
12411 struct var *vp, **vpp;
12414 flags |= (VEXPORT & (((unsigned) (1 - aflag)) - 1));
12415 if ((vp = *findvar(vpp, s))) {
12416 if (vp->flags & VREADONLY) {
12417 size_t len = strchr(s, '=') - s;
12418 error("%.*s: is read only", len, s);
12422 if (vp->func && (flags & VNOFUNC) == 0)
12423 (*vp->func)(strchr(s, '=') + 1);
12425 if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0)
12428 vp->flags &= ~(VTEXTFIXED|VSTACK|VUNSET);
12429 vp->flags |= flags;
12433 * We could roll this to a function, to handle it as
12434 * a regular variable function callback, but why bother?
12436 if (iflag && (vp == &vmpath || (vp == &vmail && !mpathset())))
12442 vp = ckmalloc(sizeof (*vp));
12453 * Process a linked list of variable assignments.
12458 struct strlist *mylist;
12460 struct strlist *lp;
12463 for (lp = mylist ; lp ; lp = lp->next) {
12464 setvareq(savestr(lp->text), 0);
12472 * Find the value of a variable. Returns NULL if not set.
12475 static const char *
12481 if ((v = *findvar(hashvar(name), name)) && !(v->flags & VUNSET)) {
12482 return strchr(v->text, '=') + 1;
12490 * Search the environment of a builtin command.
12493 static const char *
12494 bltinlookup(const char *name)
12496 const struct strlist *sp;
12498 for (sp = cmdenviron ; sp ; sp = sp->next) {
12499 if (varequal(sp->text, name))
12500 return strchr(sp->text, '=') + 1;
12502 return lookupvar(name);
12508 * Generate a list of exported variables. This routine is used to construct
12509 * the third argument to execve when executing a program.
12521 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
12522 for (vp = *vpp ; vp ; vp = vp->next)
12523 if (vp->flags & VEXPORT)
12526 ep = env = stalloc((nenv + 1) * sizeof *env);
12527 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
12528 for (vp = *vpp ; vp ; vp = vp->next)
12529 if (vp->flags & VEXPORT)
12538 * Called when a shell procedure is invoked to clear out nonexported
12539 * variables. It is also necessary to reallocate variables of with
12540 * VSTACK set since these are currently allocated on the stack.
12546 struct var *vp, **prev;
12548 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
12549 for (prev = vpp ; (vp = *prev) != NULL ; ) {
12550 if ((vp->flags & VEXPORT) == 0) {
12552 if ((vp->flags & VTEXTFIXED) == 0)
12554 if ((vp->flags & VSTRFIXED) == 0)
12557 if (vp->flags & VSTACK) {
12558 vp->text = savestr(vp->text);
12559 vp->flags &=~ VSTACK;
12571 * Command to list all variables which are set. Currently this command
12572 * is invoked from the set command when the set command is called without
12577 showvarscmd(argc, argv)
12581 showvars(nullstr, VUNSET, VUNSET);
12588 * The export and readonly commands.
12592 exportcmd(argc, argv)
12599 int flag = argv[0][0] == 'r'? VREADONLY : VEXPORT;
12602 listsetvar(cmdenviron);
12603 pflag = (nextopt("p") == 'p');
12604 if (argc > 1 && !pflag) {
12605 while ((name = *argptr++) != NULL) {
12606 if ((p = strchr(name, '=')) != NULL) {
12609 if ((vp = *findvar(hashvar(name), name))) {
12614 setvar(name, p, flag);
12618 showvars(argv[0], flag, 0);
12624 * The "local" command.
12627 /* funcnest nonzero if we are currently evaluating a function */
12630 localcmd(argc, argv)
12637 error("Not in a function");
12638 while ((name = *argptr++) != NULL) {
12646 * Make a variable a local variable. When a variable is made local, it's
12647 * value and flags are saved in a localvar structure. The saved values
12648 * will be restored when the shell function returns. We handle the name
12649 * "-" as a special case.
12656 struct localvar *lvp;
12661 lvp = ckmalloc(sizeof (struct localvar));
12662 if (name[0] == '-' && name[1] == '\0') {
12664 p = ckmalloc(sizeof optet_vals);
12665 lvp->text = memcpy(p, optet_vals, sizeof optet_vals);
12668 vpp = hashvar(name);
12669 vp = *findvar(vpp, name);
12671 if (strchr(name, '='))
12672 setvareq(savestr(name), VSTRFIXED);
12674 setvar(name, NULL, VSTRFIXED);
12675 vp = *vpp; /* the new variable */
12677 lvp->flags = VUNSET;
12679 lvp->text = vp->text;
12680 lvp->flags = vp->flags;
12681 vp->flags |= VSTRFIXED|VTEXTFIXED;
12682 if (strchr(name, '='))
12683 setvareq(savestr(name), 0);
12687 lvp->next = localvars;
12694 * Called after a function returns.
12699 struct localvar *lvp;
12702 while ((lvp = localvars) != NULL) {
12703 localvars = lvp->next;
12705 if (vp == NULL) { /* $- saved */
12706 memcpy(optet_vals, lvp->text, sizeof optet_vals);
12708 } else if ((lvp->flags & (VUNSET|VSTRFIXED)) == VUNSET) {
12709 (void)unsetvar(vp->text);
12711 if ((vp->flags & VTEXTFIXED) == 0)
12713 vp->flags = lvp->flags;
12714 vp->text = lvp->text;
12722 setvarcmd(argc, argv)
12727 return unsetcmd(argc, argv);
12728 else if (argc == 3)
12729 setvar(argv[1], argv[2], 0);
12731 error("List assignment not implemented");
12737 * The unset builtin command. We unset the function before we unset the
12738 * variable to allow a function to be unset when there is a readonly variable
12739 * with the same name.
12743 unsetcmd(argc, argv)
12753 while ((i = nextopt("vf")) != '\0') {
12759 if (flg_func == 0 && flg_var == 0)
12762 for (ap = argptr; *ap ; ap++) {
12766 ret |= unsetvar(*ap);
12773 * Unset the specified variable.
12777 unsetvar(const char *s)
12782 vpp = findvar(hashvar(s), s);
12785 if (vp->flags & VREADONLY)
12788 if (*(strchr(vp->text, '=') + 1) != '\0')
12789 setvar(s, nullstr, 0);
12790 vp->flags &= ~VEXPORT;
12791 vp->flags |= VUNSET;
12792 if ((vp->flags & VSTRFIXED) == 0) {
12793 if ((vp->flags & VTEXTFIXED) == 0)
12808 * Find the appropriate entry in the hash table from the name.
12811 static struct var **
12812 hashvar(const char *p)
12814 unsigned int hashval;
12816 hashval = ((unsigned char) *p) << 4;
12817 while (*p && *p != '=')
12818 hashval += (unsigned char) *p++;
12819 return &vartab[hashval % VTABSIZE];
12825 * Returns true if the two strings specify the same varable. The first
12826 * variable name is terminated by '='; the second may be terminated by
12827 * either '=' or '\0'.
12831 varequal(const char *p, const char *q)
12833 while (*p == *q++) {
12837 if (*p == '=' && *(q - 1) == '\0')
12843 showvars(const char *myprefix, int mask, int xor)
12847 const char *sep = myprefix == nullstr ? myprefix : spcstr;
12849 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
12850 for (vp = *vpp ; vp ; vp = vp->next) {
12851 if ((vp->flags & mask) ^ xor) {
12855 p = strchr(vp->text, '=') + 1;
12856 len = p - vp->text;
12857 p = single_quote(p);
12859 printf("%s%s%.*s%s\n", myprefix, sep, len,
12867 static struct var **
12868 findvar(struct var **vpp, const char *name)
12870 for (; *vpp; vpp = &(*vpp)->next) {
12871 if (varequal((*vpp)->text, name)) {
12879 * Copyright (c) 1999 Herbert Xu <herbert@debian.org>
12880 * This file contains code for the times builtin.
12881 * $Id: ash.c,v 1.14 2001/07/30 21:41:37 andersen Exp $
12883 static int timescmd (int argc, char **argv)
12886 long int clk_tck = sysconf(_SC_CLK_TCK);
12889 printf("%dm%fs %dm%fs\n%dm%fs %dm%fs\n",
12890 (int) (buf.tms_utime / clk_tck / 60),
12891 ((double) buf.tms_utime) / clk_tck,
12892 (int) (buf.tms_stime / clk_tck / 60),
12893 ((double) buf.tms_stime) / clk_tck,
12894 (int) (buf.tms_cutime / clk_tck / 60),
12895 ((double) buf.tms_cutime) / clk_tck,
12896 (int) (buf.tms_cstime / clk_tck / 60),
12897 ((double) buf.tms_cstime) / clk_tck);
12902 #ifdef ASH_MATH_SUPPORT
12903 /* The exp(1) builtin. */
12904 int expcmd(int argc, char **argv)
12914 /* concatenate arguments */
12915 STARTSTACKSTR(concat);
12919 STPUTC(*p++, concat);
12920 if ((p = *ap++) == NULL)
12922 STPUTC(' ', concat);
12924 STPUTC('\0', concat);
12925 p = grabstackstr(concat);
12932 printf("%ld\n", i);
12936 static long ash_arith(const char *p)
12940 error("arith: syntax error: \"%s\"\n", p);
12948 * Copyright (c) 1989, 1991, 1993, 1994
12949 * The Regents of the University of California. All rights reserved.
12951 * This code is derived from software contributed to Berkeley by
12952 * Kenneth Almquist.
12954 * Redistribution and use in source and binary forms, with or without
12955 * modification, are permitted provided that the following conditions
12957 * 1. Redistributions of source code must retain the above copyright
12958 * notice, this list of conditions and the following disclaimer.
12959 * 2. Redistributions in binary form must reproduce the above copyright
12960 * notice, this list of conditions and the following disclaimer in the
12961 * documentation and/or other materials provided with the distribution.
12963 * 3. <BSD Advertising Clause omitted per the July 22, 1999 licensing change
12964 * ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change>
12966 * 4. Neither the name of the University nor the names of its contributors
12967 * may be used to endorse or promote products derived from this software
12968 * without specific prior written permission.
12970 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
12971 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
12972 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
12973 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
12974 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
12975 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
12976 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
12977 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
12978 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
12979 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF