1 /* vi: set sw=4 ts=4: */
3 * ash shell port for busybox
5 * Copyright (c) 1989, 1991, 1993, 1994
6 * The Regents of the University of California. All rights reserved.
8 * This code is derived from software contributed to Berkeley by
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 * This version of ash is adapted from the source in Debian's ash 0.3.8-5
28 * Modified by Erik Andersen <andersee@debian.org> and
29 * Vladimir Oleynik <vodz@usa.net> to be used in busybox
32 * Original copyright notice is retained at the end of this file.
36 /* These defines allow you to adjust the feature set to be compiled
37 * into the ash shell. As a rule, enabling these options will make
38 * ash get bigger... With all of these options off, ash adds about
39 * 62k to busybox on an x86 system.*/
43 /* Enable job control. This allows you to run jobs in the background,
44 * which is great when ash is being used as an interactive shell, but
45 * it completely useless for is all you are doing is running scripts.
46 * This adds about 2.5k on an x86 system. */
49 /* This enables alias support in ash. If you want to support things
50 * like "alias ls='ls -l'" with ash, enable this. This is only useful
51 * when ash is used as an intractive shell. This adds about 1.5k */
54 /* If you need ash to act as a full Posix shell, with full math
55 * support, enable this. This option needs some work, since it
56 * doesn't compile right now... */
57 #undef ASH_MATH_SUPPORT
59 /* This shell builtin is used to indicate how the shell would interpret
60 * what you give it. This command is only useful when debugging, and
61 * is obsolete anyways. Adds about 670 bytes... You probably want to
62 * leave this disabled. */
65 /* Getopts is used by shell procedures to parse positional parameters.
66 * You probably want to leave this disabled, and use the busybox getopt
67 * applet if you want to do this sort of thing. There are some scripts
68 * out there that use it, so it you need it, enable. Most people will
69 * leave this disabled. This adds 1k on an x86 system. */
72 /* This allows you to override shell builtins and use whatever is on
73 * the filesystem. This is most useful when ash is acting as a
74 * standalone shell. Adds about 320 bytes. */
77 /* This makes a few common apps that are usually part of busybox
78 * anyways to be used as builtins. This may cause these builtins to be
79 * a little bit faster, but leaving this disabled will save you 2k. */
80 #undef ASH_BBAPPS_AS_BUILTINS
82 /* Optimize size vs speed as size */
83 #define ASH_OPTIMIZE_FOR_SIZE
85 /* Enable this to compile in extra debugging noise. When debugging is
86 * on, debugging info will be written to $HOME/trace and a quit signal
87 * will generate a core dump. */
92 /* These are here to work with glibc -- Don't change these... */
112 #include <sysexits.h>
114 #include <sys/stat.h>
115 #include <sys/cdefs.h>
116 #include <sys/ioctl.h>
117 #include <sys/param.h>
118 #include <sys/resource.h>
119 #include <sys/time.h>
120 #include <sys/times.h>
121 #include <sys/types.h>
122 #include <sys/wait.h>
125 #if !defined(FNMATCH_BROKEN)
128 #if !defined(GLOB_BROKEN)
140 * This file was generated by the mksyntax program.
144 #define CWORD 0 /* character is nothing special */
145 #define CNL 1 /* newline character */
146 #define CBACK 2 /* a backslash character */
147 #define CSQUOTE 3 /* single quote */
148 #define CDQUOTE 4 /* double quote */
149 #define CENDQUOTE 5 /* a terminating quote */
150 #define CBQUOTE 6 /* backwards single quote */
151 #define CVAR 7 /* a dollar sign */
152 #define CENDVAR 8 /* a '}' character */
153 #define CLP 9 /* a left paren in arithmetic */
154 #define CRP 10 /* a right paren in arithmetic */
155 #define CENDFILE 11 /* end of file */
156 #define CCTL 12 /* like CWORD, except it must be escaped */
157 #define CSPCL 13 /* these terminate a word */
158 #define CIGN 14 /* character should be ignored */
160 /* Syntax classes for is_ functions */
161 #define ISDIGIT 01 /* a digit */
162 #define ISUPPER 02 /* an upper case letter */
163 #define ISLOWER 04 /* a lower case letter */
164 #define ISUNDER 010 /* an underscore */
165 #define ISSPECL 020 /* the name of a special parameter */
182 #define TENDBQUOTE 10
204 #define BASESYNTAX (basesyntax + SYNBASE)
205 #define DQSYNTAX (dqsyntax + SYNBASE)
206 #define SQSYNTAX (sqsyntax + SYNBASE)
207 #define ARISYNTAX (arisyntax + SYNBASE)
209 /* control characters in argument strings */
210 #define CTLESC '\201'
211 #define CTLVAR '\202'
212 #define CTLENDVAR '\203'
213 #define CTLBACKQ '\204'
214 #define CTLQUOTE 01 /* ored with CTLBACKQ code if in quotes */
215 /* CTLBACKQ | CTLQUOTE == '\205' */
216 #define CTLARI '\206'
217 #define CTLENDARI '\207'
218 #define CTLQUOTEMARK '\210'
220 #define is_digit(c) ((((unsigned char)(c)) - '0') <= 9)
221 #define is_alpha(c) (((c) < CTLESC || (c) > CTLENDARI) && isalpha((unsigned char) (c)))
222 #define is_name(c) (((c) < CTLESC || (c) > CTLENDARI) && ((c) == '_' || isalpha((unsigned char) (c))))
223 #define is_in_name(c) (((c) < CTLESC || (c) > CTLENDARI) && ((c) == '_' || isalnum((unsigned char) (c))))
224 #define is_special(c) ((is_type+SYNBASE)[c] & (ISSPECL|ISDIGIT))
225 #define digit_val(c) ((c) - '0')
228 #define _DIAGASSERT(x)
232 #define S_DFL 1 /* default signal handling (SIG_DFL) */
233 #define S_CATCH 2 /* signal is caught */
234 #define S_IGN 3 /* signal is ignored (SIG_IGN) */
235 #define S_HARD_IGN 4 /* signal is ignored permenantly */
236 #define S_RESET 5 /* temporary - to reset a hard ignored sig */
239 /* variable substitution byte (follows CTLVAR) */
240 #define VSTYPE 0x0f /* type of variable substitution */
241 #define VSNUL 0x10 /* colon--treat the empty string as unset */
242 #define VSQUOTE 0x80 /* inside double quotes--suppress splitting */
244 /* values of VSTYPE field */
245 #define VSNORMAL 0x1 /* normal variable: $var or ${var} */
246 #define VSMINUS 0x2 /* ${var-text} */
247 #define VSPLUS 0x3 /* ${var+text} */
248 #define VSQUESTION 0x4 /* ${var?message} */
249 #define VSASSIGN 0x5 /* ${var=text} */
250 #define VSTRIMLEFT 0x6 /* ${var#pattern} */
251 #define VSTRIMLEFTMAX 0x7 /* ${var##pattern} */
252 #define VSTRIMRIGHT 0x8 /* ${var%pattern} */
253 #define VSTRIMRIGHTMAX 0x9 /* ${var%%pattern} */
254 #define VSLENGTH 0xa /* ${#var} */
256 /* flags passed to redirect */
257 #define REDIR_PUSH 01 /* save previous values of file descriptors */
258 #define REDIR_BACKQ 02 /* save the command output to pipe */
261 * BSD setjmp saves the signal mask, which violates ANSI C and takes time,
262 * so we use _setjmp instead.
265 #if !defined(__GLIBC__)
266 #define setjmp(jmploc) _setjmp(jmploc)
267 #define longjmp(jmploc, val) _longjmp(jmploc, val)
271 * Most machines require the value returned from malloc to be aligned
272 * in some way. The following macro will get this right on many machines.
281 #define ALIGN(nbytes) (((nbytes) + sizeof(union align) - 1) & ~(sizeof(union align) - 1))
284 #ifdef BB_LOCALE_SUPPORT
286 static void change_lc_all(const char *value);
287 static void change_lc_ctype(const char *value);
291 * These macros allow the user to suspend the handling of interrupt signals
292 * over a period of time. This is similar to SIGHOLD to or sigblock, but
293 * much more efficient and portable. (But hacking the kernel is so much
294 * more fun than worrying about efficiency and portability. :-))
297 static void onint (void);
298 static volatile int suppressint;
299 static volatile int intpending;
301 #define INTOFF suppressint++
302 #ifndef ASH_OPTIMIZE_FOR_SIZE
303 #define INTON { if (--suppressint == 0 && intpending) onint(); }
304 #define FORCEINTON {suppressint = 0; if (intpending) onint();}
306 static void __inton (void);
307 static void forceinton (void);
308 #define INTON __inton()
309 #define FORCEINTON forceinton()
312 #define CLEAR_PENDING_INT intpending = 0
313 #define int_pending() intpending
316 typedef void *pointer;
318 #define NULL (void *)0
321 static inline pointer ckmalloc (int sz) { return xmalloc(sz); }
322 static inline pointer ckrealloc(void *p, int sz) { return xrealloc(p, sz); }
323 static inline char * savestr (const char *s) { return xstrdup(s); }
325 static pointer stalloc (int);
326 static void stunalloc (pointer);
327 static void ungrabstackstr (char *, char *);
328 static char * growstackstr(void);
329 static char * makestrspace(size_t newlen);
330 static char *sstrdup (const char *);
333 * Parse trees for commands are allocated in lifo order, so we use a stack
334 * to make this more efficient, and also to avoid all sorts of exception
335 * handling code to handle interrupts in the middle of a parse.
337 * The size 504 was chosen because the Ultrix malloc handles that size
341 #define MINSIZE 504 /* minimum size of a block */
345 struct stack_block *prev;
349 static struct stack_block stackbase;
350 static struct stack_block *stackp = &stackbase;
351 static struct stackmark *markp;
352 static char *stacknxt = stackbase.space;
353 static int stacknleft = MINSIZE;
356 #define equal(s1, s2) (strcmp(s1, s2) == 0)
358 #define stackblock() stacknxt
359 #define stackblocksize() stacknleft
360 #define STARTSTACKSTR(p) p = stackblock(), sstrnleft = stackblocksize()
362 #define STPUTC(c, p) (--sstrnleft >= 0? (*p++ = (c)) : (p = growstackstr(), *p++ = (c)))
363 #define CHECKSTRSPACE(n, p) { if (sstrnleft < n) p = makestrspace(n); }
364 #define STACKSTRNUL(p) (sstrnleft == 0? (p = growstackstr(), *p = '\0') : (*p = '\0'))
367 #define USTPUTC(c, p) (--sstrnleft, *p++ = (c))
368 #define STUNPUTC(p) (++sstrnleft, --p)
369 #define STTOPC(p) p[-1]
370 #define STADJUST(amount, p) (p += (amount), sstrnleft -= (amount))
371 #define grabstackstr(p) stalloc(stackblocksize() - sstrnleft)
373 #define ckfree(p) free((pointer)(p))
377 #define TRACE(param) trace param
378 static void trace (const char *, ...);
379 static void trargs (char **);
380 static void showtree (union node *);
381 static void trputc (int);
382 static void trputs (const char *);
383 static void opentrace (void);
418 #define EXP_FULL 0x1 /* perform word splitting & file globbing */
419 #define EXP_TILDE 0x2 /* do normal tilde expansion */
420 #define EXP_VARTILDE 0x4 /* expand tildes in an assignment */
421 #define EXP_REDIR 0x8 /* file glob for a redirection (1 match only) */
422 #define EXP_CASE 0x10 /* keeps quotes around for CASE pattern */
423 #define EXP_RECORD 0x20 /* need to record arguments for ifs breakup */
428 static char optet_vals[NOPTS];
430 static const char * const optlist[NOPTS] = {
449 #define optent_name(optent) (optent+1)
450 #define optent_letter(optent) optent[0]
451 #define optent_val(optent) optet_vals[optent]
453 #define eflag optent_val(0)
454 #define fflag optent_val(1)
455 #define Iflag optent_val(2)
456 #define iflag optent_val(3)
457 #define mflag optent_val(4)
458 #define nflag optent_val(5)
459 #define sflag optent_val(6)
460 #define xflag optent_val(7)
461 #define vflag optent_val(8)
462 #define Vflag optent_val(9)
463 #define Eflag optent_val(10)
464 #define Cflag optent_val(11)
465 #define aflag optent_val(12)
466 #define bflag optent_val(13)
467 #define uflag optent_val(14)
468 #define qflag optent_val(15)
471 /* Mode argument to forkshell. Don't change FORK_FG or FORK_BG. */
489 union node *redirect;
496 struct nodelist *cmdlist;
503 union node *redirect;
511 union node *elsepart;
542 struct nodelist *backquote;
580 struct nbinary nbinary;
583 struct nredir nredir;
587 struct nclist nclist;
597 struct nodelist *next;
601 struct backcmd { /* result of evalbackcmd */
602 int fd; /* file descriptor to read from */
603 char *buf; /* buffer */
604 int nleft; /* number of chars in buffer */
605 struct job *jp; /* job structure for command */
613 const struct builtincmd *cmd;
618 struct strlist *next;
624 struct strlist *list;
625 struct strlist **lastp;
629 struct strpush *prev; /* preceding string on stack */
633 struct alias *ap; /* if push was associated with an alias */
635 char *string; /* remember the string since it may change */
639 struct parsefile *prev; /* preceding file on stack */
640 int linno; /* current line */
641 int fd; /* file descriptor (or -1 if string) */
642 int nleft; /* number of chars left in this line */
643 int lleft; /* number of chars left in this buffer */
644 char *nextc; /* next char in buffer */
645 char *buf; /* input buffer */
646 struct strpush *strpush; /* for pushing strings at this level */
647 struct strpush basestrpush; /* so pushing one is fast */
651 struct stack_block *stackp;
654 struct stackmark *marknext;
658 int nparam; /* # of positional parameters (without $0) */
659 unsigned char malloc; /* if parameter list dynamically allocated */
660 char **p; /* parameter list */
661 int optind; /* next parameter to be processed by getopts */
662 int optoff; /* used by getopts */
665 static void flushall (void);
666 static void out2fmt (const char *, ...)
667 __attribute__((__format__(__printf__,1,2)));
668 static void out1fmt (const char *, ...)
669 __attribute__((__format__(__printf__,1,2)));
670 static int xwrite (int, const char *, int);
672 static void outstr (const char *p, FILE *file) { fputs(p, file); }
673 static void out1str(const char *p) { outstr(p, stdout); }
674 static void out2str(const char *p) { outstr(p, stderr); }
676 #define out2c(c) putc((c), stderr)
678 /* syntax table used when not in quotes */
679 static const char basesyntax[257] = {
680 CENDFILE, CSPCL, CWORD, CCTL,
681 CCTL, CCTL, CCTL, CCTL,
682 CCTL, CCTL, CCTL, CWORD,
683 CWORD, CWORD, CWORD, CWORD,
684 CWORD, CWORD, CWORD, CWORD,
685 CWORD, CWORD, CWORD, CWORD,
686 CWORD, CWORD, CWORD, CWORD,
687 CWORD, CWORD, CWORD, CWORD,
688 CWORD, CWORD, CWORD, CWORD,
689 CWORD, CWORD, CWORD, CWORD,
690 CWORD, CWORD, CWORD, CWORD,
691 CWORD, CWORD, CWORD, CWORD,
692 CWORD, CWORD, CWORD, CWORD,
693 CWORD, CWORD, CWORD, CWORD,
694 CWORD, CWORD, CWORD, CWORD,
695 CWORD, CWORD, CWORD, CWORD,
696 CWORD, CWORD, CWORD, CWORD,
697 CWORD, CWORD, CWORD, CWORD,
698 CWORD, CWORD, CWORD, CWORD,
699 CWORD, CWORD, CWORD, CWORD,
700 CWORD, CWORD, CWORD, CWORD,
701 CWORD, CWORD, CWORD, CWORD,
702 CWORD, CWORD, CWORD, CWORD,
703 CWORD, CWORD, CWORD, CWORD,
704 CWORD, CWORD, CWORD, CWORD,
705 CWORD, CWORD, CWORD, 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, CSPCL,
715 CNL, 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, CSPCL, CWORD,
721 CDQUOTE, CWORD, CVAR, CWORD,
722 CSPCL, CSQUOTE, CSPCL, CSPCL,
723 CWORD, CWORD, CWORD, CWORD,
724 CWORD, CWORD, CWORD, CWORD,
725 CWORD, CWORD, CWORD, CWORD,
726 CWORD, CWORD, CWORD, CWORD,
727 CWORD, CSPCL, CSPCL, CWORD,
728 CSPCL, 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, CBACK, CWORD,
736 CWORD, CWORD, CBQUOTE, CWORD,
737 CWORD, CWORD, CWORD, CWORD,
738 CWORD, 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, CENDVAR,
747 /* syntax table used when in double quotes */
748 static const char dqsyntax[257] = {
749 CENDFILE, CIGN, CWORD, CCTL,
750 CCTL, CCTL, CCTL, CCTL,
751 CCTL, CCTL, CCTL, 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, CWORD, CWORD,
759 CWORD, CWORD, CWORD, 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, CWORD, CWORD,
767 CWORD, CWORD, CWORD, CWORD,
768 CWORD, CWORD, CWORD, CWORD,
769 CWORD, CWORD, CWORD, CWORD,
770 CWORD, CWORD, CWORD, CWORD,
771 CWORD, CWORD, CWORD, CWORD,
772 CWORD, CWORD, CWORD, CWORD,
773 CWORD, CWORD, CWORD, CWORD,
774 CWORD, CWORD, CWORD, 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 CNL, 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, CCTL,
790 CENDQUOTE,CWORD, CVAR, CWORD,
791 CWORD, CWORD, CWORD, CWORD,
792 CCTL, CWORD, CWORD, CCTL,
793 CWORD, CCTL, CWORD, CWORD,
794 CWORD, CWORD, CWORD, CWORD,
795 CWORD, CWORD, CWORD, CWORD,
796 CCTL, CWORD, CWORD, CCTL,
797 CWORD, CCTL, 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, CCTL, CBACK, CCTL,
805 CWORD, CWORD, CBQUOTE, CWORD,
806 CWORD, CWORD, CWORD, CWORD,
807 CWORD, 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, CENDVAR,
816 /* syntax table used when in single quotes */
817 static const char sqsyntax[257] = {
818 CENDFILE, CIGN, CWORD, CCTL,
819 CCTL, CCTL, CCTL, CCTL,
820 CCTL, CCTL, CCTL, 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, CWORD, CWORD, CWORD,
828 CWORD, CWORD, CWORD, 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, CWORD,
836 CWORD, CWORD, CWORD, CWORD,
837 CWORD, CWORD, CWORD, CWORD,
838 CWORD, CWORD, CWORD, CWORD,
839 CWORD, CWORD, CWORD, CWORD,
840 CWORD, CWORD, CWORD, CWORD,
841 CWORD, CWORD, CWORD, CWORD,
842 CWORD, CWORD, CWORD, CWORD,
843 CWORD, CWORD, CWORD, 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 CNL, 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, CCTL,
859 CWORD, CWORD, CWORD, CWORD,
860 CWORD, CENDQUOTE,CWORD, CWORD,
861 CCTL, CWORD, CWORD, CCTL,
862 CWORD, CCTL, CWORD, CWORD,
863 CWORD, CWORD, CWORD, CWORD,
864 CWORD, CWORD, CWORD, CWORD,
865 CCTL, CWORD, CWORD, CCTL,
866 CWORD, CCTL, 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, CCTL, CCTL, CCTL,
874 CWORD, CWORD, CWORD, CWORD,
875 CWORD, CWORD, CWORD, CWORD,
876 CWORD, 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, CWORD,
885 /* syntax table used when in arithmetic */
886 static const char arisyntax[257] = {
887 CENDFILE, CIGN, CWORD, CCTL,
888 CCTL, CCTL, CCTL, CCTL,
889 CCTL, CCTL, CCTL, 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, CWORD, CWORD, CWORD,
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,
905 CWORD, CWORD, CWORD, CWORD,
906 CWORD, CWORD, CWORD, CWORD,
907 CWORD, CWORD, CWORD, CWORD,
908 CWORD, CWORD, CWORD, CWORD,
909 CWORD, CWORD, CWORD, CWORD,
910 CWORD, CWORD, CWORD, CWORD,
911 CWORD, CWORD, CWORD, CWORD,
912 CWORD, CWORD, CWORD, 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 CNL, 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 CDQUOTE, CWORD, CVAR, CWORD,
929 CWORD, CSQUOTE, CLP, CRP,
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, CBACK, CWORD,
943 CWORD, CWORD, CBQUOTE, CWORD,
944 CWORD, CWORD, CWORD, CWORD,
945 CWORD, 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, CENDVAR,
954 /* character classification table */
955 static const char is_type[257] = {
997 0, ISSPECL, ISSPECL, 0,
999 ISSPECL, 0, 0, ISSPECL,
1000 0, 0, ISDIGIT, ISDIGIT,
1001 ISDIGIT, ISDIGIT, ISDIGIT, ISDIGIT,
1002 ISDIGIT, ISDIGIT, ISDIGIT, ISDIGIT,
1004 0, ISSPECL, ISSPECL, ISUPPER,
1005 ISUPPER, ISUPPER, ISUPPER, ISUPPER,
1006 ISUPPER, ISUPPER, ISUPPER, ISUPPER,
1007 ISUPPER, ISUPPER, ISUPPER, ISUPPER,
1008 ISUPPER, ISUPPER, ISUPPER, ISUPPER,
1009 ISUPPER, ISUPPER, ISUPPER, ISUPPER,
1010 ISUPPER, ISUPPER, ISUPPER, ISUPPER,
1012 0, ISUNDER, 0, ISLOWER,
1013 ISLOWER, ISLOWER, ISLOWER, ISLOWER,
1014 ISLOWER, ISLOWER, ISLOWER, ISLOWER,
1015 ISLOWER, ISLOWER, ISLOWER, ISLOWER,
1016 ISLOWER, ISLOWER, ISLOWER, ISLOWER,
1017 ISLOWER, ISLOWER, ISLOWER, ISLOWER,
1018 ISLOWER, ISLOWER, ISLOWER, ISLOWER,
1023 /* Array indicating which tokens mark the end of a list */
1024 static const char tokendlist[] = {
1057 static const char *const tokname[] = {
1090 #define KWDOFFSET 14
1092 static const char *const parsekwd[] = {
1112 static int plinno = 1; /* input line number */
1114 static int parselleft; /* copy of parsefile->lleft */
1116 static struct parsefile basepf; /* top level input file */
1117 static char basebuf[BUFSIZ]; /* buffer for top level input file */
1118 static struct parsefile *parsefile = &basepf; /* current input file */
1121 * NEOF is returned by parsecmd when it encounters an end of file. It
1122 * must be distinct from NULL, so we use the address of a variable that
1123 * happens to be handy.
1126 static int tokpushback; /* last token pushed back */
1127 #define NEOF ((union node *)&tokpushback)
1128 static int checkkwd; /* 1 == check for kwds, 2 == also eat newlines */
1131 static void error (const char *, ...) __attribute__((__noreturn__));
1132 static void exerror (int, const char *, ...) __attribute__((__noreturn__));
1133 static void shellexec (char **, char **, const char *, int)
1134 __attribute__((noreturn));
1135 static void exitshell (int) __attribute__((noreturn));
1137 static int goodname(const char *);
1138 static void ignoresig (int);
1139 static void onsig (int);
1140 static void dotrap (void);
1141 static int decode_signal (const char *, int);
1143 static void shprocvar(void);
1144 static void deletefuncs(void);
1145 static void setparam (char **);
1146 static void freeparam (volatile struct shparam *);
1148 /* reasons for skipping commands (see comment on breakcmd routine) */
1154 /* values of cmdtype */
1155 #define CMDUNKNOWN -1 /* no entry in table for command */
1156 #define CMDNORMAL 0 /* command is an executable program */
1157 #define CMDBUILTIN 1 /* command is a shell builtin */
1158 #define CMDFUNCTION 2 /* command is a shell function */
1160 #define DO_ERR 1 /* find_command prints errors */
1161 #define DO_ABS 2 /* find_command checks absolute paths */
1162 #define DO_NOFUN 4 /* find_command ignores functions */
1163 #define DO_BRUTE 8 /* find_command ignores hash table */
1170 #define VEXPORT 0x01 /* variable is exported */
1171 #define VREADONLY 0x02 /* variable cannot be modified */
1172 #define VSTRFIXED 0x04 /* variable struct is staticly allocated */
1173 #define VTEXTFIXED 0x08 /* text is staticly allocated */
1174 #define VSTACK 0x10 /* text is allocated on the stack */
1175 #define VUNSET 0x20 /* the variable is not set */
1176 #define VNOFUNC 0x40 /* don't call the callback function */
1180 struct var *next; /* next entry in hash list */
1181 int flags; /* flags are defined above */
1182 char *text; /* name=value */
1183 void (*func) (const char *);
1184 /* function to be called when */
1185 /* the variable gets set/unset */
1189 struct localvar *next; /* next local variable in list */
1190 struct var *vp; /* the variable that was made local */
1191 int flags; /* saved flags */
1192 char *text; /* saved text */
1196 #if defined(__GLIBC__) && !defined(FNMATCH_BROKEN)
1197 #define rmescapes(p) _rmescapes((p), 0)
1198 static char *_rmescapes (char *, int);
1200 static void rmescapes (char *);
1203 static int casematch (union node *, const char *);
1204 static void clearredir(void);
1205 static void popstring(void);
1206 static void readcmdfile (const char *);
1208 static int number (const char *);
1209 static int is_number (const char *, int *num);
1210 static char *single_quote (const char *);
1211 static int nextopt (const char *);
1213 static void redirect (union node *, int);
1214 static void popredir (void);
1215 static int dup_as_newfd (int, int);
1217 static void changepath(const char *newval);
1218 static void getoptsreset(const char *value);
1221 static int parsenleft; /* copy of parsefile->nleft */
1222 static char *parsenextc; /* copy of parsefile->nextc */
1223 static int rootpid; /* pid of main shell */
1224 static int rootshell; /* true if we aren't a child of the main shell */
1226 static const char spcstr[] = " ";
1227 static const char snlfmt[] = "%s\n";
1229 static int sstrnleft;
1230 static int herefd = -1;
1232 static struct localvar *localvars;
1234 static struct var vifs;
1235 static struct var vmail;
1236 static struct var vmpath;
1237 static struct var vpath;
1238 static struct var vps1;
1239 static struct var vps2;
1240 static struct var voptind;
1241 #ifdef BB_LOCALE_SUPPORT
1242 static struct var vlc_all;
1243 static struct var vlc_ctype;
1250 void (*func) (const char *);
1253 static const char defpathvar[] =
1254 "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin";
1255 #define defpath (defpathvar + 5)
1258 static const char defifsvar[] = "IFS= \t\n";
1259 #define defifs (defifsvar + 4)
1261 static const char defifs[] = " \t\n";
1264 static const struct varinit varinit[] = {
1266 { &vifs, VSTRFIXED|VTEXTFIXED, defifsvar,
1268 { &vifs, VSTRFIXED|VTEXTFIXED|VUNSET, "IFS=",
1271 { &vmail, VSTRFIXED|VTEXTFIXED|VUNSET, "MAIL=",
1273 { &vmpath, VSTRFIXED|VTEXTFIXED|VUNSET, "MAILPATH=",
1275 { &vpath, VSTRFIXED|VTEXTFIXED, defpathvar,
1278 * vps1 depends on uid
1280 { &vps2, VSTRFIXED|VTEXTFIXED, "PS2=> ",
1282 { &voptind, VSTRFIXED|VTEXTFIXED, "OPTIND=1",
1284 #ifdef BB_LOCALE_SUPPORT
1285 { &vlc_all, VSTRFIXED|VTEXTFIXED|VUNSET, "LC_ALL=",
1287 { &vlc_ctype, VSTRFIXED|VTEXTFIXED|VUNSET, "LC_CTYPE=",
1296 static struct var *vartab[VTABSIZE];
1299 * The following macros access the values of the above variables.
1300 * They have to skip over the name. They return the null string
1301 * for unset variables.
1304 #define ifsval() (vifs.text + 4)
1305 #define ifsset() ((vifs.flags & VUNSET) == 0)
1306 #define mailval() (vmail.text + 5)
1307 #define mpathval() (vmpath.text + 9)
1308 #define pathval() (vpath.text + 5)
1309 #define ps1val() (vps1.text + 4)
1310 #define ps2val() (vps2.text + 4)
1311 #define optindval() (voptind.text + 7)
1313 #define mpathset() ((vmpath.flags & VUNSET) == 0)
1315 static void initvar (void);
1316 static void setvar (const char *, const char *, int);
1317 static void setvareq (char *, int);
1318 static void listsetvar (struct strlist *);
1319 static char *lookupvar (const char *);
1320 static char *bltinlookup (const char *);
1321 static char **environment (void);
1322 static int showvarscmd (int, char **);
1323 static void mklocal (char *);
1324 static void poplocalvars (void);
1325 static int unsetvar (const char *);
1326 static int varequal (const char *, const char *);
1329 static char *arg0; /* value of $0 */
1330 static struct shparam shellparam; /* current positional parameters */
1331 static char **argptr; /* argument list for builtin commands */
1332 static char *optionarg; /* set by nextopt (like getopt) */
1333 static char *optptr; /* used by nextopt */
1334 static char *minusc; /* argument to -c option */
1339 #define ALIASINUSE 1
1351 static struct alias *atab[ATABSIZE];
1353 static void setalias (char *, char *);
1354 static struct alias **hashalias (const char *);
1355 static struct alias *freealias (struct alias *);
1356 static struct alias **__lookupalias (const char *);
1362 struct alias *ap, **app;
1364 app = __lookupalias(name);
1368 if (!(ap->flag & ALIASINUSE)) {
1371 ap->val = savestr(val);
1372 ap->flag &= ~ALIASDEAD;
1375 ap = ckmalloc(sizeof (struct alias));
1376 ap->name = savestr(name);
1377 ap->val = savestr(val);
1390 app = __lookupalias(name);
1394 *app = freealias(*app);
1405 struct alias *ap, **app;
1409 for (i = 0; i < ATABSIZE; i++) {
1411 for (ap = *app; ap; ap = *app) {
1412 *app = freealias(*app);
1421 static struct alias *
1422 lookupalias(const char *name, int check)
1424 struct alias *ap = *__lookupalias(name);
1426 if (check && ap && (ap->flag & ALIASINUSE))
1432 printalias(const struct alias *ap) {
1435 p = single_quote(ap->val);
1436 out1fmt("alias %s=%s\n", ap->name, p);
1442 * TODO - sort output
1445 aliascmd(int argc, char **argv)
1454 for (i = 0; i < ATABSIZE; i++)
1455 for (ap = atab[i]; ap; ap = ap->next) {
1460 while ((n = *++argv) != NULL) {
1461 if ((v = strchr(n+1, '=')) == NULL) { /* n+1: funny ksh stuff */
1462 if ((ap = *__lookupalias(n)) == NULL) {
1463 out2fmt("%s: %s not found\n", "alias", n);
1478 unaliascmd(int argc, char **argv)
1482 while ((i = nextopt("a")) != '\0') {
1488 for (i = 0; *argptr; argptr++) {
1489 if (unalias(*argptr)) {
1490 out2fmt("%s: %s not found\n", "unalias", *argptr);
1498 static struct alias **
1502 unsigned int hashval;
1507 return &atab[hashval % ATABSIZE];
1510 static struct alias *
1511 freealias(struct alias *ap) {
1514 if (ap->flag & ALIASINUSE) {
1515 ap->flag |= ALIASDEAD;
1527 static struct alias **
1528 __lookupalias(const char *name) {
1529 struct alias **app = hashalias(name);
1531 for (; *app; app = &(*app)->next) {
1532 if (equal(name, (*app)->name)) {
1541 #ifdef ASH_MATH_SUPPORT
1542 /* The generated file arith.c has been snipped. If you want this
1543 * stuff back in, feel free to add it to your own copy. */
1544 #define ARITH_NUM 257
1545 #define ARITH_LPAREN 258
1546 #define ARITH_RPAREN 259
1547 #define ARITH_OR 260
1548 #define ARITH_AND 261
1549 #define ARITH_BOR 262
1550 #define ARITH_BXOR 263
1551 #define ARITH_BAND 264
1552 #define ARITH_EQ 265
1553 #define ARITH_NE 266
1554 #define ARITH_LT 267
1555 #define ARITH_GT 268
1556 #define ARITH_GE 269
1557 #define ARITH_LE 270
1558 #define ARITH_LSHIFT 271
1559 #define ARITH_RSHIFT 272
1560 #define ARITH_ADD 273
1561 #define ARITH_SUB 274
1562 #define ARITH_MUL 275
1563 #define ARITH_DIV 276
1564 #define ARITH_REM 277
1565 #define ARITH_UNARYMINUS 278
1566 #define ARITH_UNARYPLUS 279
1567 #define ARITH_NOT 280
1568 #define ARITH_BNOT 281
1570 static void expari (int);
1572 static int arith (const char *);
1573 static int expcmd (int , char **);
1574 static void arith_lex_reset (void);
1575 static int yylex (void);
1579 static char *trap[NSIG]; /* trap handler commands */
1580 static char sigmode[NSIG - 1]; /* current value of signal */
1581 static char gotsig[NSIG - 1]; /* indicates specified signal received */
1582 static int pendingsigs; /* indicates some signal received */
1585 * This file was generated by the mkbuiltins program.
1589 static int bgcmd (int, char **);
1590 static int fgcmd (int, char **);
1591 static int killcmd (int, char **);
1593 static int bltincmd (int, char **);
1594 static int cdcmd (int, char **);
1595 static int breakcmd (int, char **);
1597 static int commandcmd (int, char **);
1599 static int dotcmd (int, char **);
1600 static int evalcmd (int, char **);
1601 static int execcmd (int, char **);
1602 static int exitcmd (int, char **);
1603 static int exportcmd (int, char **);
1604 static int histcmd (int, char **);
1605 static int hashcmd (int, char **);
1606 static int jobscmd (int, char **);
1607 static int localcmd (int, char **);
1609 static int pwdcmd (int, char **);
1611 static int readcmd (int, char **);
1612 static int returncmd (int, char **);
1613 static int setcmd (int, char **);
1614 static int setvarcmd (int, char **);
1615 static int shiftcmd (int, char **);
1616 static int trapcmd (int, char **);
1617 static int umaskcmd (int, char **);
1619 static int aliascmd (int, char **);
1620 static int unaliascmd (int, char **);
1622 static int unsetcmd (int, char **);
1623 static int waitcmd (int, char **);
1624 static int ulimitcmd (int, char **);
1625 static int timescmd (int, char **);
1626 #ifdef ASH_MATH_SUPPORT
1627 static int expcmd (int, char **);
1630 static int typecmd (int, char **);
1633 static int getoptscmd (int, char **);
1636 #ifndef BB_TRUE_FALSE
1637 # ifdef ASH_BBAPPS_AS_BUILTINS
1638 static int true_main (int, char **);
1639 static int false_main (int, char **);
1643 static void setpwd (const char *, int);
1646 #define BUILTIN_NOSPEC "0"
1647 #define BUILTIN_SPECIAL "1"
1648 #define BUILTIN_REGULAR "2"
1649 #define BUILTIN_ASSIGN "4"
1650 #define BUILTIN_SPEC_ASSG "5"
1651 #define BUILTIN_REG_ASSG "6"
1653 #define IS_BUILTIN_SPECIAL(builtincmd) ((builtincmd)->name[0] & 1)
1654 #define IS_BUILTIN_REGULAR(builtincmd) ((builtincmd)->name[0] & 2)
1655 #define IS_BUILTIN_ASSIGN(builtincmd) ((builtincmd)->name[0] & 4)
1659 int (*const builtinfunc) (int, char **);
1664 /* It is CRUCIAL that this listing be kept in ascii order, otherwise
1665 * the binary search in find_builtin() will stop working. If you value
1666 * your kneecaps, you'll be sure to *make sure* that any changes made
1667 * to this array result in the listing remaining in ascii order. You
1670 static const struct builtincmd builtincmds[] = {
1671 { BUILTIN_SPECIAL ".", dotcmd },
1672 { BUILTIN_SPECIAL ":", true_main },
1674 { BUILTIN_REG_ASSG "alias", aliascmd },
1677 { BUILTIN_REGULAR "bg", bgcmd },
1679 { BUILTIN_SPECIAL "break", breakcmd },
1680 { BUILTIN_SPECIAL "builtin", bltincmd },
1681 { BUILTIN_REGULAR "cd", cdcmd },
1682 #ifdef ASH_BBAPPS_AS_BUILTINS
1683 { BUILTIN_NOSPEC "chdir", cdcmd },
1686 { BUILTIN_REGULAR "command", commandcmd },
1688 { BUILTIN_SPECIAL "continue", breakcmd },
1689 { BUILTIN_SPECIAL "eval", evalcmd },
1690 { BUILTIN_SPECIAL "exec", execcmd },
1691 { BUILTIN_SPECIAL "exit", exitcmd },
1692 #ifdef ASH_MATH_SUPPORT
1693 { BUILTIN_NOSPEC "exp", expcmd },
1695 { BUILTIN_SPEC_ASSG "export", exportcmd },
1696 #ifdef ASH_BBAPPS_AS_BUILTINS
1697 { BUILTIN_REGULAR "false", false_main },
1699 { BUILTIN_REGULAR "fc", histcmd },
1701 { BUILTIN_REGULAR "fg", fgcmd },
1704 { BUILTIN_REGULAR "getopts", getoptscmd },
1706 { BUILTIN_NOSPEC "hash", hashcmd },
1707 { BUILTIN_REGULAR "jobs", jobscmd },
1709 { BUILTIN_REGULAR "kill", killcmd },
1711 #ifdef ASH_MATH_SUPPORT
1712 { BUILTIN_NOSPEC "let", expcmd },
1714 { BUILTIN_ASSIGN "local", localcmd },
1716 { BUILTIN_NOSPEC "pwd", pwdcmd },
1718 { BUILTIN_REGULAR "read", readcmd },
1719 { BUILTIN_SPEC_ASSG "readonly", exportcmd },
1720 { BUILTIN_SPECIAL "return", returncmd },
1721 { BUILTIN_SPECIAL "set", setcmd },
1722 { BUILTIN_NOSPEC "setvar", setvarcmd },
1723 { BUILTIN_SPECIAL "shift", shiftcmd },
1724 { BUILTIN_SPECIAL "times", timescmd },
1725 { BUILTIN_SPECIAL "trap", trapcmd },
1726 #ifdef ASH_BBAPPS_AS_BUILTINS
1727 { BUILTIN_REGULAR "true", true_main },
1730 { BUILTIN_NOSPEC "type", typecmd },
1732 { BUILTIN_NOSPEC "ulimit", ulimitcmd },
1733 { BUILTIN_REGULAR "umask", umaskcmd },
1735 { BUILTIN_REGULAR "unalias", unaliascmd },
1737 { BUILTIN_SPECIAL "unset", unsetcmd },
1738 { BUILTIN_REGULAR "wait", waitcmd },
1740 #define NUMBUILTINS (sizeof (builtincmds) / sizeof (struct builtincmd) )
1742 static const struct builtincmd *DOTCMD = &builtincmds[0];
1743 static struct builtincmd *BLTINCMD;
1744 static struct builtincmd *EXECCMD;
1745 static struct builtincmd *EVALCMD;
1748 #define JOBSTOPPED 1 /* all procs are stopped */
1749 #define JOBDONE 2 /* all procs are completed */
1752 * A job structure contains information about a job. A job is either a
1753 * single process or a set of processes contained in a pipeline. In the
1754 * latter case, pidlist will be non-NULL, and will point to a -1 terminated
1759 pid_t pid; /* process id */
1760 int status; /* status flags (defined above) */
1761 char *cmd; /* text of command being run */
1765 static int job_warning; /* user was warned about stopped jobs */
1768 static void setjobctl(int enable);
1770 #define setjobctl(on) /* do nothing */
1775 struct procstat ps0; /* status of process */
1776 struct procstat *ps; /* status or processes when more than one */
1777 short nprocs; /* number of processes */
1778 short pgrp; /* process group of this job */
1779 char state; /* true if job is finished */
1780 char used; /* true if this entry is in used */
1781 char changed; /* true if status has changed */
1783 char jobctl; /* job running under job control */
1787 static struct job *jobtab; /* array of jobs */
1788 static int njobs; /* size of array */
1789 static int backgndpid = -1; /* pid of last background process */
1791 static int initialpgrp; /* pgrp of shell on invocation */
1792 static int curjob; /* current job */
1795 static int intreceived;
1797 static struct job *makejob (union node *, int);
1798 static int forkshell (struct job *, union node *, int);
1799 static int waitforjob (struct job *);
1801 static int docd (char *, int);
1802 static char *getcomponent (void);
1803 static void updatepwd (const char *);
1804 static void getpwd (void);
1806 static char *padvance (const char **, const char *);
1808 static char nullstr[1]; /* zero length string */
1809 static char *curdir = nullstr; /* current working directory */
1810 static char *cdcomppath;
1824 if ((dest = *argptr) == NULL && (dest = bltinlookup("HOME")) == NULL)
1825 error("HOME not set");
1828 if (dest[0] == '-' && dest[1] == '\0') {
1829 dest = bltinlookup("OLDPWD");
1830 if (!dest || !*dest) {
1839 if (*dest == '/' || (path = bltinlookup("CDPATH")) == NULL)
1841 while ((p = padvance(&path, dest)) != NULL) {
1842 if (stat(p, &statb) >= 0 && S_ISDIR(statb.st_mode)) {
1847 if (p[0] == '.' && p[1] == '/' && p[2] != '\0')
1849 print = strcmp(p, dest);
1851 if (docd(p, print) >= 0)
1856 error("can't cd to %s", dest);
1862 * Actually do the chdir. In an interactive shell, print the
1863 * directory name if "print" is nonzero.
1878 TRACE(("docd(\"%s\", %d) called\n", dest, print));
1881 * Check each component of the path. If we find a symlink or
1882 * something we can't stat, clear curdir to force a getcwd()
1883 * next time we get the value of the current directory.
1886 cdcomppath = sstrdup(dest);
1893 while ((q = getcomponent()) != NULL) {
1894 if (q[0] == '\0' || (q[0] == '.' && q[1] == '\0'))
1902 if (equal(component, ".."))
1905 if ((lstat(stackblock(), &statb) < 0)
1906 || (S_ISLNK(statb.st_mode))) {
1914 if (chdir(dest) < 0) {
1918 updatepwd(badstat ? NULL : dest);
1921 out1fmt(snlfmt, curdir);
1927 * Get the next component of the path name pointed to by cdcomppath.
1928 * This routine overwrites the string pointed to by cdcomppath.
1936 if ((p = cdcomppath) == NULL)
1939 while (*p != '/' && *p != '\0')
1953 * Update curdir (the name of the current directory) in response to a
1954 * cd command. We also call hashcd to let the routines in exec.c know
1955 * that the current directory has changed.
1958 static void hashcd (void);
1961 updatepwd(const char *dir)
1967 hashcd(); /* update command hash table */
1970 * If our argument is NULL, we don't know the current directory
1971 * any more because we traversed a symbolic link or something
1972 * we couldn't stat().
1974 if (dir == NULL || curdir == nullstr) {
1979 cdcomppath = sstrdup(dir);
1988 while ((p = getcomponent()) != NULL) {
1989 if (equal(p, "..")) {
1990 while (new > stackblock() && (STUNPUTC(new), *new) != '/');
1991 } else if (*p != '\0' && ! equal(p, ".")) {
1997 if (new == stackblock())
2000 setpwd(stackblock(), 1);
2010 out1fmt(snlfmt, curdir);
2016 * Find out what the current directory is. If we already know the current
2017 * directory, this routine returns immediately.
2022 curdir = xgetcwd(0);
2028 setpwd(const char *val, int setold)
2031 setvar("OLDPWD", curdir, VEXPORT);
2034 if (curdir != nullstr) {
2041 curdir = savestr(val);
2044 setvar("PWD", curdir, VEXPORT);
2048 * Errors and exceptions.
2052 * Code to handle exceptions in C.
2056 * We enclose jmp_buf in a structure so that we can declare pointers to
2057 * jump locations. The global variable handler contains the location to
2058 * jump to when an exception occurs, and the global variable exception
2059 * contains a code identifying the exeception. To implement nested
2060 * exception handlers, the user should save the value of handler on entry
2061 * to an inner scope, set handler to point to a jmploc structure for the
2062 * inner scope, and restore handler on exit from the scope.
2070 #define EXINT 0 /* SIGINT received */
2071 #define EXERROR 1 /* a generic error */
2072 #define EXSHELLPROC 2 /* execute a shell procedure */
2073 #define EXEXEC 3 /* command execution failed */
2075 static struct jmploc *handler;
2076 static int exception;
2078 static void exverror (int, const char *, va_list)
2079 __attribute__((__noreturn__));
2082 * Called to raise an exception. Since C doesn't include exceptions, we
2083 * just do a longjmp to the exception handler. The type of exception is
2084 * stored in the global variable "exception".
2087 static void exraise (int) __attribute__((__noreturn__));
2093 if (handler == NULL)
2097 longjmp(handler->loc, 1);
2102 * Called from trap.c when a SIGINT is received. (If the user specifies
2103 * that SIGINT is to be trapped or ignored using the trap builtin, then
2104 * this routine is not called.) Suppressint is nonzero when interrupts
2105 * are held using the INTOFF macro. The call to _exit is necessary because
2106 * there is a short period after a fork before the signal handlers are
2107 * set to the appropriate value for the child. (The test for iflag is
2108 * just defensive programming.)
2120 sigemptyset(&mysigset);
2121 sigprocmask(SIG_SETMASK, &mysigset, NULL);
2122 if (rootshell && iflag)
2125 signal(SIGINT, SIG_DFL);
2132 static char *commandname; /* currently executing command */
2135 * Exverror is called to raise the error exception. If the first argument
2136 * is not NULL then error prints an error message using printf style
2137 * formatting. It then raises the error exception.
2140 exverror(int cond, const char *msg, va_list ap)
2147 TRACE(("exverror(%d, \"%s\") pid=%d\n", cond, msg, getpid()));
2149 TRACE(("exverror(%d, NULL) pid=%d\n", cond, getpid()));
2153 out2fmt("%s: ", commandname);
2154 vfprintf(stderr, msg, ap);
2165 error(const char *msg, ...)
2180 msg = va_arg(ap, const char *);
2182 exverror(EXERROR, msg, ap);
2190 exerror(int cond, const char *msg, ...)
2206 cond = va_arg(ap, int);
2207 msg = va_arg(ap, const char *);
2209 exverror(cond, msg, ap);
2217 * Table of error messages.
2221 short errcode; /* error number */
2222 short action; /* operation which encountered the error */
2226 * Types of operations (passed to the errmsg routine).
2229 #define E_OPEN 01 /* opening a file */
2230 #define E_CREAT 02 /* creating a file */
2231 #define E_EXEC 04 /* executing a program */
2233 #define ALL (E_OPEN|E_CREAT|E_EXEC)
2235 static const struct errname errormsg[] = {
2240 { ENOENT, E_CREAT },
2242 { ENOTDIR, E_OPEN },
2243 { ENOTDIR, E_CREAT },
2244 { ENOTDIR, E_EXEC },
2246 { EEXIST, E_CREAT },
2285 { ELIBACC, E_EXEC },
2289 #define ERRNAME_SIZE (sizeof(errormsg)/sizeof(struct errname))
2292 * Return a string describing an error. The returned string may be a
2293 * pointer to a static buffer that will be overwritten on the next call.
2294 * Action describes the operation that got the error.
2298 errmsg(int e, int action)
2300 struct errname const *ep;
2301 static char buf[12];
2303 for (ep = errormsg ; ep < errormsg+ERRNAME_SIZE; ep++) {
2304 if (ep->errcode == e && (ep->action & action) != 0)
2308 snprintf(buf, sizeof buf, "error %d", e);
2313 #ifdef ASH_OPTIMIZE_FOR_SIZE
2316 if (--suppressint == 0 && intpending) {
2320 static void forceinton (void) {
2327 /* flags in argument to evaltree */
2328 #define EV_EXIT 01 /* exit after evaluating tree */
2329 #define EV_TESTED 02 /* exit status is checked; ignore -e flag */
2330 #define EV_BACKCMD 04 /* command executing within back quotes */
2332 static int evalskip; /* set if we are skipping commands */
2333 static int skipcount; /* number of levels to skip */
2334 static int loopnest; /* current loop nesting level */
2335 static int funcnest; /* depth of function calls */
2339 static struct strlist *cmdenviron; /* environment for builtin command */
2340 static int exitstatus; /* exit status of last command */
2341 static int oexitstatus; /* saved exit status */
2344 static void evalloop (union node *, int);
2345 static void evalfor (union node *, int);
2346 static void evalcase (union node *, int);
2347 static void evalsubshell (union node *, int);
2348 static void expredir (union node *);
2349 static void evalpipe (union node *);
2350 static void evalcommand (union node *, int);
2351 static void prehash (union node *);
2352 static void eprintlist (struct strlist *);
2354 static union node *parsecmd(int);
2356 * Called to reset things after an exception.
2360 * The eval commmand.
2362 static void evalstring (char *, int);
2376 STARTSTACKSTR(concat);
2380 STPUTC(*p++, concat);
2381 if ((p = *ap++) == NULL)
2383 STPUTC(' ', concat);
2385 STPUTC('\0', concat);
2386 p = grabstackstr(concat);
2388 evalstring(p, EV_TESTED);
2394 * Execute a command or commands contained in a string.
2397 static void evaltree (union node *, int);
2398 static void setinputstring (char *);
2399 static void popfile (void);
2400 static void setstackmark(struct stackmark *mark);
2401 static void popstackmark(struct stackmark *mark);
2405 evalstring(char *s, int flag)
2408 struct stackmark smark;
2410 setstackmark(&smark);
2412 while ((n = parsecmd(0)) != NEOF) {
2414 popstackmark(&smark);
2417 popstackmark(&smark);
2421 * Evaluate a parse tree. The value is left in the global variable
2424 static struct builtincmd *find_builtin (const char *);
2425 static void defun (char *, union node *);
2434 TRACE(("evaltree(NULL) called\n"));
2437 TRACE(("evaltree(0x%lx: %d) called\n", (long)n, n->type));
2440 evaltree(n->nbinary.ch1, flags & EV_TESTED);
2443 evaltree(n->nbinary.ch2, flags);
2446 evaltree(n->nbinary.ch1, EV_TESTED);
2447 if (evalskip || exitstatus != 0)
2449 evaltree(n->nbinary.ch2, flags);
2452 evaltree(n->nbinary.ch1, EV_TESTED);
2453 if (evalskip || exitstatus == 0)
2455 evaltree(n->nbinary.ch2, flags);
2458 expredir(n->nredir.redirect);
2459 redirect(n->nredir.redirect, REDIR_PUSH);
2460 evaltree(n->nredir.n, flags);
2464 evalsubshell(n, flags);
2467 evalsubshell(n, flags);
2470 evaltree(n->nif.test, EV_TESTED);
2473 if (exitstatus == 0)
2474 evaltree(n->nif.ifpart, flags);
2475 else if (n->nif.elsepart)
2476 evaltree(n->nif.elsepart, flags);
2492 struct builtincmd *bcmd;
2494 (bcmd = find_builtin(n->narg.text)) &&
2495 IS_BUILTIN_SPECIAL(bcmd)
2497 out2fmt("%s is a special built-in\n", n->narg.text);
2501 defun(n->narg.text, n->narg.next);
2506 evaltree(n->nnot.com, EV_TESTED);
2507 exitstatus = !exitstatus;
2515 evalcommand(n, flags);
2520 out1fmt("Node type = %d\n", n->type);
2529 (checkexit && eflag && exitstatus && !(flags & EV_TESTED))
2531 exitshell(exitstatus);
2545 evaltree(n->nbinary.ch1, EV_TESTED);
2547 skipping: if (evalskip == SKIPCONT && --skipcount <= 0) {
2551 if (evalskip == SKIPBREAK && --skipcount <= 0)
2555 if (n->type == NWHILE) {
2556 if (exitstatus != 0)
2559 if (exitstatus == 0)
2562 evaltree(n->nbinary.ch2, flags & EV_TESTED);
2563 status = exitstatus;
2568 exitstatus = status;
2571 static void expandarg (union node *, struct arglist *, int);
2572 static void fixredir(union node *n, const char *text, int err);
2579 struct arglist arglist;
2582 struct stackmark smark;
2584 setstackmark(&smark);
2585 arglist.lastp = &arglist.list;
2586 for (argp = n->nfor.args ; argp ; argp = argp->narg.next) {
2587 oexitstatus = exitstatus;
2588 expandarg(argp, &arglist, EXP_FULL | EXP_TILDE | EXP_RECORD);
2592 *arglist.lastp = NULL;
2596 for (sp = arglist.list ; sp ; sp = sp->next) {
2597 setvar(n->nfor.var, sp->text, 0);
2598 evaltree(n->nfor.body, flags & EV_TESTED);
2600 if (evalskip == SKIPCONT && --skipcount <= 0) {
2604 if (evalskip == SKIPBREAK && --skipcount <= 0)
2611 popstackmark(&smark);
2622 struct arglist arglist;
2623 struct stackmark smark;
2625 setstackmark(&smark);
2626 arglist.lastp = &arglist.list;
2627 oexitstatus = exitstatus;
2628 expandarg(n->ncase.expr, &arglist, EXP_TILDE);
2629 for (cp = n->ncase.cases ; cp && evalskip == 0 ; cp = cp->nclist.next) {
2630 for (patp = cp->nclist.pattern ; patp ; patp = patp->narg.next) {
2631 if (casematch(patp, arglist.list->text)) {
2632 if (evalskip == 0) {
2633 evaltree(cp->nclist.body, flags);
2640 popstackmark(&smark);
2644 * Kick off a subshell to evaluate a tree.
2648 evalsubshell(n, flags)
2653 int backgnd = (n->type == NBACKGND);
2655 expredir(n->nredir.redirect);
2657 if (forkshell(jp, n, backgnd) == 0) {
2659 flags &=~ EV_TESTED;
2660 redirect(n->nredir.redirect, 0);
2661 evaltree(n->nredir.n, flags | EV_EXIT); /* never returns */
2665 exitstatus = waitforjob(jp);
2672 * Compute the names of the files in a redirection list.
2681 for (redir = n ; redir ; redir = redir->nfile.next) {
2683 fn.lastp = &fn.list;
2684 oexitstatus = exitstatus;
2685 switch (redir->type) {
2691 expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR);
2692 redir->nfile.expfname = fn.list->text;
2696 if (redir->ndup.vname) {
2697 expandarg(redir->ndup.vname, &fn, EXP_FULL | EXP_TILDE);
2698 fixredir(redir, fn.list->text, 1);
2706 * Evaluate a pipeline. All the processes in the pipeline are children
2707 * of the process creating the pipeline. (This differs from some versions
2708 * of the shell, which make the last process in a pipeline the parent
2717 struct nodelist *lp;
2722 TRACE(("evalpipe(0x%lx) called\n", (long)n));
2724 for (lp = n->npipe.cmdlist ; lp ; lp = lp->next)
2727 jp = makejob(n, pipelen);
2729 for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
2733 if (pipe(pip) < 0) {
2735 error("Pipe call failed");
2738 if (forkshell(jp, lp->n, n->npipe.backgnd) == 0) {
2742 dup_as_newfd(prevfd, 0);
2754 dup_as_newfd(pip[1], 1);
2758 evaltree(lp->n, EV_EXIT);
2766 if (n->npipe.backgnd == 0) {
2768 exitstatus = waitforjob(jp);
2769 TRACE(("evalpipe: job done exit status %d\n", exitstatus));
2777 * Execute a command inside back quotes. If it's a builtin command, we
2778 * want to save its output in a block obtained from malloc. Otherwise
2779 * we fork off a subprocess and get the output of the command via a pipe.
2780 * Should be called with interrupts off.
2784 evalbackcmd(union node *n, struct backcmd *result)
2788 struct stackmark smark; /* unnecessary */
2790 setstackmark(&smark);
2801 error("Pipe call failed");
2803 if (forkshell(jp, n, FORK_NOJOB) == 0) {
2808 dup_as_newfd(pip[1], 1);
2812 evaltree(n, EV_EXIT);
2815 result->fd = pip[0];
2818 popstackmark(&smark);
2819 TRACE(("evalbackcmd done: fd=%d buf=0x%x nleft=%d jp=0x%x\n",
2820 result->fd, result->buf, result->nleft, result->jp));
2826 * Execute a simple command.
2829 static void find_command (const char *, struct cmdentry *, int, const char *);
2832 isassignment(const char *word) {
2833 if (!is_name(*word)) {
2838 } while (is_in_name(*word));
2839 return *word == '=';
2843 evalcommand(union node *cmd, int flags)
2845 struct stackmark smark;
2847 struct arglist arglist;
2848 struct arglist varlist;
2854 struct cmdentry cmdentry;
2856 char *volatile savecmdname;
2857 volatile struct shparam saveparam;
2858 struct localvar *volatile savelocalvars;
2862 const struct builtincmd *firstbltin;
2863 struct jmploc *volatile savehandler;
2864 struct jmploc jmploc;
2866 /* Avoid longjmp clobbering */
2873 /* First expand the arguments. */
2874 TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags));
2875 setstackmark(&smark);
2876 arglist.lastp = &arglist.list;
2877 varlist.lastp = &varlist.list;
2879 oexitstatus = exitstatus;
2882 for (argp = cmd->ncmd.assign; argp; argp = argp->narg.next) {
2883 expandarg(argp, &varlist, EXP_VARTILDE);
2886 argp = cmd->ncmd.args; argp && !arglist.list;
2887 argp = argp->narg.next
2889 expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
2892 struct builtincmd *bcmd;
2894 bcmd = find_builtin(arglist.list->text);
2895 pseudovarflag = bcmd && IS_BUILTIN_ASSIGN(bcmd);
2896 for (; argp; argp = argp->narg.next) {
2897 if (pseudovarflag && isassignment(argp->narg.text)) {
2898 expandarg(argp, &arglist, EXP_VARTILDE);
2901 expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
2904 *arglist.lastp = NULL;
2905 *varlist.lastp = NULL;
2906 expredir(cmd->ncmd.redirect);
2908 for (sp = arglist.list ; sp ; sp = sp->next)
2910 argv = stalloc(sizeof (char *) * (argc + 1));
2912 for (sp = arglist.list ; sp ; sp = sp->next) {
2913 TRACE(("evalcommand arg: %s\n", sp->text));
2918 if (iflag && funcnest == 0 && argc > 0)
2922 /* Print the command if xflag is set. */
2925 eprintlist(varlist.list);
2926 eprintlist(arglist.list);
2930 /* Now locate the command. */
2932 cmdentry.cmdtype = CMDBUILTIN;
2933 firstbltin = cmdentry.u.cmd = BLTINCMD;
2935 const char *oldpath;
2936 int findflag = DO_ERR;
2940 * Modify the command lookup path, if a PATH= assignment
2943 for (sp = varlist.list ; sp ; sp = sp->next)
2944 if (varequal(sp->text, defpathvar)) {
2945 path = sp->text + 5;
2946 findflag |= DO_BRUTE;
2949 oldfindflag = findflag;
2952 find_command(argv[0], &cmdentry, findflag, path);
2953 if (cmdentry.cmdtype == CMDUNKNOWN) { /* command not found */
2957 /* implement bltin and command here */
2958 if (cmdentry.cmdtype != CMDBUILTIN) {
2962 firstbltin = cmdentry.u.cmd;
2964 if (cmdentry.u.cmd == BLTINCMD) {
2966 struct builtincmd *bcmd;
2971 if (!(bcmd = find_builtin(*argv))) {
2972 out2fmt("%s: not found\n", *argv);
2976 cmdentry.u.cmd = bcmd;
2977 if (bcmd != BLTINCMD)
2981 if (cmdentry.u.cmd == find_builtin("command")) {
2986 if (*argv[0] == '-') {
2987 if (!equal(argv[0], "-p")) {
2997 findflag |= DO_BRUTE;
3000 findflag = oldfindflag;
3002 findflag |= DO_NOFUN;
3010 /* Fork off a child process if necessary. */
3011 if (cmd->ncmd.backgnd
3012 || (cmdentry.cmdtype == CMDNORMAL && (flags & EV_EXIT) == 0)
3014 jp = makejob(cmd, 1);
3015 mode = cmd->ncmd.backgnd;
3016 if (forkshell(jp, cmd, mode) != 0)
3017 goto parent; /* at end of routine */
3021 /* This is the child process if a fork occurred. */
3022 /* Execute the command. */
3023 if (cmdentry.cmdtype == CMDFUNCTION) {
3025 trputs("Shell function: "); trargs(argv);
3027 exitstatus = oexitstatus;
3028 redirect(cmd->ncmd.redirect, REDIR_PUSH);
3029 saveparam = shellparam;
3030 shellparam.malloc = 0;
3031 shellparam.nparam = argc - 1;
3032 shellparam.p = argv + 1;
3034 savelocalvars = localvars;
3037 if (setjmp(jmploc.loc)) {
3038 if (exception == EXSHELLPROC) {
3039 freeparam((volatile struct shparam *)
3042 saveparam.optind = shellparam.optind;
3043 saveparam.optoff = shellparam.optoff;
3044 freeparam(&shellparam);
3045 shellparam = saveparam;
3048 localvars = savelocalvars;
3049 handler = savehandler;
3050 longjmp(handler->loc, 1);
3052 savehandler = handler;
3054 for (sp = varlist.list ; sp ; sp = sp->next)
3057 evaltree(cmdentry.u.func, flags & EV_TESTED);
3061 localvars = savelocalvars;
3062 saveparam.optind = shellparam.optind;
3063 saveparam.optoff = shellparam.optoff;
3064 freeparam(&shellparam);
3065 shellparam = saveparam;
3066 handler = savehandler;
3069 if (evalskip == SKIPFUNC) {
3073 if (flags & EV_EXIT)
3074 exitshell(exitstatus);
3075 } else if (cmdentry.cmdtype == CMDBUILTIN) {
3077 trputs("builtin command: "); trargs(argv);
3079 mode = (cmdentry.u.cmd == EXECCMD)? 0 : REDIR_PUSH;
3080 redirect(cmd->ncmd.redirect, mode);
3081 savecmdname = commandname;
3082 if (IS_BUILTIN_SPECIAL(firstbltin)) {
3083 listsetvar(varlist.list);
3085 cmdenviron = varlist.list;
3088 if (setjmp(jmploc.loc)) {
3090 exitstatus = (e == EXINT)? SIGINT+128 : 2;
3093 savehandler = handler;
3095 commandname = argv[0];
3097 optptr = NULL; /* initialize nextopt */
3098 exitstatus = (*cmdentry.u.cmd->builtinfunc)(argc, argv);
3102 if (e != EXSHELLPROC) {
3103 commandname = savecmdname;
3104 if (flags & EV_EXIT)
3105 exitshell(exitstatus);
3107 handler = savehandler;
3109 if ((e != EXERROR && e != EXEXEC)
3110 || cmdentry.u.cmd == BLTINCMD
3111 || cmdentry.u.cmd == DOTCMD
3112 || cmdentry.u.cmd == EVALCMD
3113 || cmdentry.u.cmd == EXECCMD)
3117 if (cmdentry.u.cmd != EXECCMD)
3121 trputs("normal command: "); trargs(argv);
3123 redirect(cmd->ncmd.redirect, 0);
3125 for (sp = varlist.list ; sp ; sp = sp->next)
3126 setvareq(sp->text, VEXPORT|VSTACK);
3127 envp = environment();
3128 shellexec(argv, envp, path, cmdentry.u.index);
3132 parent: /* parent process gets here (if we forked) */
3133 if (mode == 0) { /* argument to fork */
3135 exitstatus = waitforjob(jp);
3141 setvar("_", lastarg, 0);
3142 popstackmark(&smark);
3148 * Search for a command. This is called before we fork so that the
3149 * location of the command will be available in the parent as well as
3150 * the child. The check for "goodname" is an overly conservative
3151 * check that the name will not be subject to expansion.
3158 struct cmdentry entry;
3160 if (n->type == NCMD && n->ncmd.args)
3161 if (goodname(n->ncmd.args->narg.text))
3162 find_command(n->ncmd.args->narg.text, &entry, 0,
3169 * Builtin commands. Builtin commands whose functions are closely
3170 * tied to evaluation are implemented here.
3174 * No command given, or a bltin command with no arguments. Set the
3175 * specified variables.
3179 bltincmd(argc, argv)
3184 * Preserve exitstatus of a previous possible redirection
3192 * Handle break and continue commands. Break, continue, and return are
3193 * all handled by setting the evalskip flag. The evaluation routines
3194 * above all check this flag, and if it is set they start skipping
3195 * commands rather than executing them. The variable skipcount is
3196 * the number of loops to break/continue, or the number of function
3197 * levels to return. (The latter is always 1.) It should probably
3198 * be an error to break out of more loops than exist, but it isn't
3199 * in the standard shell so we don't make it one here.
3203 breakcmd(argc, argv)
3207 int n = argc > 1 ? number(argv[1]) : 1;
3212 evalskip = (**argv == 'c')? SKIPCONT : SKIPBREAK;
3220 * The return command.
3224 returncmd(argc, argv)
3228 int ret = argc > 1 ? number(argv[1]) : oexitstatus;
3231 evalskip = SKIPFUNC;
3236 /* Do what ksh does; skip the rest of the file */
3237 evalskip = SKIPFILE;
3244 #ifndef BB_TRUE_FALSE
3245 #ifdef ASH_BBAPPS_AS_BUILTINS
3247 false_main(argc, argv)
3256 true_main(argc, argv)
3266 * Controls whether the shell is interactive or not.
3269 static void setsignal(int signo);
3270 static void chkmail(int silent);
3274 setinteractive(int on)
3276 static int is_interactive;
3278 if (on == is_interactive)
3284 is_interactive = on;
3290 setinteractive(iflag);
3303 iflag = 0; /* exit on error */
3306 for (sp = cmdenviron; sp ; sp = sp->next)
3307 setvareq(sp->text, VEXPORT|VSTACK);
3308 shellexec(argv + 1, environment(), pathval(), 0);
3314 eprintlist(struct strlist *sp)
3316 for (; sp; sp = sp->next) {
3317 out2fmt(" %s",sp->text);
3321 * When commands are first encountered, they are entered in a hash table.
3322 * This ensures that a full path search will not have to be done for them
3323 * on each invocation.
3325 * We should investigate converting to a linear search, even though that
3326 * would make the command name "hash" a misnomer.
3328 #define CMDTABLESIZE 31 /* should be prime */
3329 #define ARB 1 /* actual size determined at run time */
3334 struct tblentry *next; /* next entry in hash chain */
3335 union param param; /* definition of builtin function */
3336 short cmdtype; /* index identifying command */
3337 char rehash; /* if set, cd done since entry created */
3338 char cmdname[ARB]; /* name of command */
3342 static struct tblentry *cmdtable[CMDTABLESIZE];
3343 static int builtinloc = -1; /* index in path of %builtin, or -1 */
3344 static int exerrno = 0; /* Last exec error */
3347 static void tryexec (char *, char **, char **);
3348 static void printentry (struct tblentry *, int);
3349 static void clearcmdentry (int);
3350 static struct tblentry *cmdlookup (const char *, int);
3351 static void delete_cmd_entry (void);
3353 static int describe_command (char *, int);
3355 static int path_change (const char *, int *);
3359 * Exec a program. Never returns. If you change this routine, you may
3360 * have to change the find_command routine as well.
3363 static const char *pathopt; /* set by padvance */
3366 shellexec(argv, envp, path, idx)
3367 char **argv, **envp;
3374 if (strchr(argv[0], '/') != NULL) {
3375 tryexec(argv[0], argv, envp);
3379 while ((cmdname = padvance(&path, argv[0])) != NULL) {
3380 if (--idx < 0 && pathopt == NULL) {
3381 tryexec(cmdname, argv, envp);
3382 if (errno != ENOENT && errno != ENOTDIR)
3389 /* Map to POSIX errors */
3401 exerror(EXEXEC, "%s: %s", argv[0], errmsg(e, E_EXEC));
3406 * Clear traps on a fork.
3412 for (tp = trap ; tp < &trap[NSIG] ; tp++) {
3413 if (*tp && **tp) { /* trap not NULL or SIG_IGN */
3418 setsignal(tp - trap);
3426 initshellproc(void) {
3452 /* from options.c: */
3456 for (i = 0; i < NOPTS; i++)
3472 for (sm = sigmode ; sm < sigmode + NSIG - 1; sm++) {
3484 static int preadbuffer(void);
3485 static void pushfile (void);
3486 static int preadfd (void);
3489 * Read a character from the script, returning PEOF on end of file.
3490 * Nul characters in the input are silently discarded.
3493 #ifndef ASH_OPTIMIZE_FOR_SIZE
3494 #define pgetc_macro() (--parsenleft >= 0? *parsenextc++ : preadbuffer())
3498 return pgetc_macro();
3504 return --parsenleft >= 0? *parsenextc++ : preadbuffer();
3510 return pgetc_macro();
3516 * Undo the last call to pgetc. Only one character may be pushed back.
3517 * PEOF may be pushed back.
3529 struct parsefile *pf = parsefile;
3538 parsefile = pf->prev;
3540 parsenleft = parsefile->nleft;
3541 parselleft = parsefile->lleft;
3542 parsenextc = parsefile->nextc;
3543 plinno = parsefile->linno;
3549 * Return to top level.
3554 while (parsefile != &basepf)
3559 * Close the file(s) that the shell is reading commands from. Called
3560 * after a fork is done.
3566 if (parsefile->fd > 0) {
3567 close(parsefile->fd);
3574 * Like setinputfile, but takes an open file descriptor. Call this with
3579 setinputfd(fd, push)
3582 (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
3588 while (parsefile->strpush)
3592 if (parsefile->buf == NULL)
3593 parsefile->buf = ckmalloc(BUFSIZ);
3594 parselleft = parsenleft = 0;
3600 * Set the input to take input from a file. If push is set, push the
3601 * old input onto the stack first.
3605 setinputfile(const char *fname, int push)
3611 if ((fd = open(fname, O_RDONLY)) < 0)
3612 error("Can't open %s", fname);
3614 myfileno2 = dup_as_newfd(fd, 10);
3617 error("Out of file descriptors");
3620 setinputfd(fd, push);
3626 tryexec(cmd, argv, envp)
3633 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
3637 #ifdef BB_FEATURE_SH_APPLETS_ALWAYS_WIN
3638 name = get_last_path_component(name);
3641 for(argc_l=0;*argv_l!=NULL; argv_l++, argc_l++)
3644 for(argc_l=0;*argv_l!=NULL; argv_l++, argc_l++);
3646 run_applet_by_name(name, argc_l, argv);
3648 execve(cmd, argv, envp);
3653 setinputfile(cmd, 0);
3654 commandname = arg0 = savestr(argv[0]);
3656 exraise(EXSHELLPROC);
3661 static char *commandtext (const union node *);
3664 * Do a path search. The variable path (passed by reference) should be
3665 * set to the start of the path before the first call; padvance will update
3666 * this value as it proceeds. Successive calls to padvance will return
3667 * the possible path expansions in sequence. If an option (indicated by
3668 * a percent sign) appears in the path entry then the global variable
3669 * pathopt will be set to point to it; otherwise pathopt will be set to
3673 static const char *pathopt;
3675 static void growstackblock(void);
3679 padvance(const char **path, const char *name)
3689 for (p = start ; *p && *p != ':' && *p != '%' ; p++);
3690 len = p - start + strlen(name) + 2; /* "2" is for '/' and '\0' */
3691 while (stackblocksize() < len)
3695 memcpy(q, start, p - start);
3703 while (*p && *p != ':') p++;
3709 return stalloc(len);
3714 /*** Command hashing code ***/
3722 struct tblentry **pp;
3723 struct tblentry *cmdp;
3726 struct cmdentry entry;
3730 while ((c = nextopt("rv")) != '\0') {
3734 } else if (c == 'v') {
3738 if (*argptr == NULL) {
3739 for (pp = cmdtable ; pp < &cmdtable[CMDTABLESIZE] ; pp++) {
3740 for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) {
3741 if (cmdp->cmdtype != CMDBUILTIN) {
3742 printentry(cmdp, verbose);
3749 while ((name = *argptr) != NULL) {
3750 if ((cmdp = cmdlookup(name, 0)) != NULL
3751 && (cmdp->cmdtype == CMDNORMAL
3752 || (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0)))
3754 find_command(name, &entry, DO_ERR, pathval());
3755 if (entry.cmdtype == CMDUNKNOWN) c = 1;
3757 cmdp = cmdlookup(name, 0);
3758 if (cmdp) printentry(cmdp, verbose);
3768 printentry(cmdp, verbose)
3769 struct tblentry *cmdp;
3776 if (cmdp->cmdtype == CMDNORMAL) {
3777 idx = cmdp->param.index;
3780 name = padvance(&path, cmdp->cmdname);
3782 } while (--idx >= 0);
3784 } else if (cmdp->cmdtype == CMDBUILTIN) {
3785 out1fmt("builtin %s", cmdp->cmdname);
3786 } else if (cmdp->cmdtype == CMDFUNCTION) {
3787 out1fmt("function %s", cmdp->cmdname);
3790 name = commandtext(cmdp->param.func);
3791 out1fmt(" %s", name);
3797 error("internal error: cmdtype %d", cmdp->cmdtype);
3800 out1fmt(snlfmt, cmdp->rehash ? "*" : nullstr);
3806 * Resolve a command name. If you change this routine, you may have to
3807 * change the shellexec routine as well.
3810 static int prefix (const char *, const char *);
3813 find_command(const char *name, struct cmdentry *entry, int act, const char *path)
3815 struct tblentry *cmdp;
3825 struct builtincmd *bcmd;
3827 /* If name contains a slash, don't use the hash table */
3828 if (strchr(name, '/') != NULL) {
3830 while (stat(name, &statb) < 0) {
3831 if (errno != ENOENT && errno != ENOTDIR)
3833 entry->cmdtype = CMDUNKNOWN;
3834 entry->u.index = -1;
3837 entry->cmdtype = CMDNORMAL;
3838 entry->u.index = -1;
3841 entry->cmdtype = CMDNORMAL;
3847 if (act & DO_BRUTE) {
3848 firstchange = path_change(path, &bltin);
3854 /* If name is in the table, and not invalidated by cd, we're done */
3855 if ((cmdp = cmdlookup(name, 0)) != NULL && cmdp->rehash == 0) {
3856 if (cmdp->cmdtype == CMDFUNCTION) {
3857 if (act & DO_NOFUN) {
3862 } else if (act & DO_BRUTE) {
3863 if ((cmdp->cmdtype == CMDNORMAL &&
3864 cmdp->param.index >= firstchange) ||
3865 (cmdp->cmdtype == CMDBUILTIN &&
3866 ((builtinloc < 0 && bltin >= 0) ?
3867 bltin : builtinloc) >= firstchange)) {
3868 /* need to recompute the entry */
3877 bcmd = find_builtin(name);
3878 regular = bcmd && IS_BUILTIN_REGULAR(bcmd);
3881 if (cmdp && (cmdp->cmdtype == CMDBUILTIN)) {
3884 } else if (act & DO_BRUTE) {
3885 if (firstchange == 0) {
3890 /* If %builtin not in path, check for builtin next */
3891 if (regular || (bltin < 0 && bcmd)) {
3894 entry->cmdtype = CMDBUILTIN;
3895 entry->u.cmd = bcmd;
3899 cmdp = cmdlookup(name, 1);
3900 cmdp->cmdtype = CMDBUILTIN;
3901 cmdp->param.cmd = bcmd;
3906 /* We have to search path. */
3907 prev = -1; /* where to start */
3908 if (cmdp && cmdp->rehash) { /* doing a rehash */
3909 if (cmdp->cmdtype == CMDBUILTIN)
3912 prev = cmdp->param.index;
3918 while ((fullname = padvance(&path, name)) != NULL) {
3919 stunalloc(fullname);
3921 if (idx >= firstchange) {
3925 if (prefix("builtin", pathopt)) {
3926 if ((bcmd = find_builtin(name))) {
3930 } else if (!(act & DO_NOFUN) &&
3931 prefix("func", pathopt)) {
3934 continue; /* ignore unimplemented options */
3937 /* if rehash, don't redo absolute path names */
3938 if (fullname[0] == '/' && idx <= prev &&
3939 idx < firstchange) {
3942 TRACE(("searchexec \"%s\": no change\n", name));
3945 while (stat(fullname, &statb) < 0) {
3946 if (errno != ENOENT && errno != ENOTDIR)
3950 e = EACCES; /* if we fail, this will be the error */
3951 if (!S_ISREG(statb.st_mode))
3953 if (pathopt) { /* this is a %func directory */
3954 stalloc(strlen(fullname) + 1);
3955 readcmdfile(fullname);
3956 if ((cmdp = cmdlookup(name, 0)) == NULL || cmdp->cmdtype != CMDFUNCTION)
3957 error("%s not defined in %s", name, fullname);
3958 stunalloc(fullname);
3961 TRACE(("searchexec \"%s\" returns \"%s\"\n", name, fullname));
3962 /* If we aren't called with DO_BRUTE and cmdp is set, it must
3963 be a function and we're being called with DO_NOFUN */
3965 entry->cmdtype = CMDNORMAL;
3966 entry->u.index = idx;
3970 cmdp = cmdlookup(name, 1);
3971 cmdp->cmdtype = CMDNORMAL;
3972 cmdp->param.index = idx;
3977 /* We failed. If there was an entry for this command, delete it */
3978 if (cmdp && updatetbl)
3981 out2fmt("%s: %s\n", name, errmsg(e, E_EXEC));
3982 entry->cmdtype = CMDUNKNOWN;
3987 entry->cmdtype = cmdp->cmdtype;
3988 entry->u = cmdp->param;
3994 * Search the table of builtin commands.
3998 bstrcmp(const void *name, const void *b)
4000 return strcmp((const char *)name, (*(const char *const *) b)+1);
4003 static struct builtincmd *
4004 find_builtin(const char *name)
4006 struct builtincmd *bp;
4008 bp = bsearch(name, builtincmds, NUMBUILTINS, sizeof(struct builtincmd),
4016 * Called when a cd is done. Marks all commands so the next time they
4017 * are executed they will be rehashed.
4022 struct tblentry **pp;
4023 struct tblentry *cmdp;
4025 for (pp = cmdtable ; pp < &cmdtable[CMDTABLESIZE] ; pp++) {
4026 for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) {
4027 if (cmdp->cmdtype == CMDNORMAL
4028 || (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0))
4037 * Called before PATH is changed. The argument is the new value of PATH;
4038 * pathval() still returns the old value at this point. Called with
4043 changepath(const char *newval)
4048 firstchange = path_change(newval, &bltin);
4049 if (builtinloc < 0 && bltin >= 0)
4050 builtinloc = bltin; /* zap builtins */
4051 clearcmdentry(firstchange);
4057 * Clear out command entries. The argument specifies the first entry in
4058 * PATH which has changed.
4062 clearcmdentry(firstchange)
4065 struct tblentry **tblp;
4066 struct tblentry **pp;
4067 struct tblentry *cmdp;
4070 for (tblp = cmdtable ; tblp < &cmdtable[CMDTABLESIZE] ; tblp++) {
4072 while ((cmdp = *pp) != NULL) {
4073 if ((cmdp->cmdtype == CMDNORMAL &&
4074 cmdp->param.index >= firstchange)
4075 || (cmdp->cmdtype == CMDBUILTIN &&
4076 builtinloc >= firstchange)) {
4088 * Free a parse tree.
4092 freefunc(union node *n)
4100 * Delete all functions.
4105 struct tblentry **tblp;
4106 struct tblentry **pp;
4107 struct tblentry *cmdp;
4110 for (tblp = cmdtable ; tblp < &cmdtable[CMDTABLESIZE] ; tblp++) {
4112 while ((cmdp = *pp) != NULL) {
4113 if (cmdp->cmdtype == CMDFUNCTION) {
4115 freefunc(cmdp->param.func);
4128 * Locate a command in the command hash table. If "add" is nonzero,
4129 * add the command to the table if it is not already present. The
4130 * variable "lastcmdentry" is set to point to the address of the link
4131 * pointing to the entry, so that delete_cmd_entry can delete the
4135 static struct tblentry **lastcmdentry;
4137 static struct tblentry *
4138 cmdlookup(const char *name, int add)
4142 struct tblentry *cmdp;
4143 struct tblentry **pp;
4150 pp = &cmdtable[hashval % CMDTABLESIZE];
4151 for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) {
4152 if (equal(cmdp->cmdname, name))
4156 if (add && cmdp == NULL) {
4158 cmdp = *pp = ckmalloc(sizeof (struct tblentry) - ARB
4159 + strlen(name) + 1);
4161 cmdp->cmdtype = CMDUNKNOWN;
4163 strcpy(cmdp->cmdname, name);
4171 * Delete the command entry returned on the last lookup.
4175 delete_cmd_entry() {
4176 struct tblentry *cmdp;
4179 cmdp = *lastcmdentry;
4180 *lastcmdentry = cmdp->next;
4188 * Add a new command entry, replacing any existing command entry for
4193 addcmdentry(char *name, struct cmdentry *entry)
4195 struct tblentry *cmdp;
4198 cmdp = cmdlookup(name, 1);
4199 if (cmdp->cmdtype == CMDFUNCTION) {
4200 freefunc(cmdp->param.func);
4202 cmdp->cmdtype = entry->cmdtype;
4203 cmdp->param = entry->u;
4209 * Define a shell function.
4212 static union node *copyfunc(union node *);
4215 defun(char *name, union node *func)
4217 struct cmdentry entry;
4219 entry.cmdtype = CMDFUNCTION;
4220 entry.u.func = copyfunc(func);
4221 addcmdentry(name, &entry);
4226 * Delete a function if it exists.
4230 unsetfunc(char *name)
4232 struct tblentry *cmdp;
4234 if ((cmdp = cmdlookup(name, 0)) != NULL && cmdp->cmdtype == CMDFUNCTION) {
4235 freefunc(cmdp->param.func);
4241 * Wrapper around strcmp for qsort/bsearch/...
4244 pstrcmp(const void *a, const void *b)
4246 return strcmp((const char *) a, *(const char *const *) b);
4250 * Find a keyword is in a sorted array.
4253 static const char *const *
4254 findkwd(const char *s)
4256 return bsearch(s, parsekwd, sizeof(parsekwd) / sizeof(const char *),
4257 sizeof(const char *), pstrcmp);
4262 * Locate and print what a word is...
4273 for (i = 1; i < argc; i++) {
4274 err |= describe_command(argv[i], 1);
4280 describe_command(char *command, int verbose)
4282 struct cmdentry entry;
4283 struct tblentry *cmdp;
4285 const struct alias *ap;
4287 const char *path = pathval();
4293 /* First look at the keywords */
4294 if (findkwd(command)) {
4295 out1str(verbose ? " is a shell keyword" : command);
4300 /* Then look at the aliases */
4301 if ((ap = lookupalias(command, 0)) != NULL) {
4303 out1fmt(" is an alias for %s", ap->val);
4310 /* Then check if it is a tracked alias */
4311 if ((cmdp = cmdlookup(command, 0)) != NULL) {
4312 entry.cmdtype = cmdp->cmdtype;
4313 entry.u = cmdp->param;
4315 /* Finally use brute force */
4316 find_command(command, &entry, DO_ABS, path);
4319 switch (entry.cmdtype) {
4321 int j = entry.u.index;
4327 p = padvance(&path, command);
4334 cmdp ? " a tracked alias for" : nullstr, p
4344 out1str(" is a shell function");
4353 " is a %sshell builtin",
4354 IS_BUILTIN_SPECIAL(entry.u.cmd) ?
4355 "special " : nullstr
4364 out1str(": not found\n");
4377 commandcmd(argc, argv)
4382 int default_path = 0;
4383 int verify_only = 0;
4384 int verbose_verify_only = 0;
4386 while ((c = nextopt("pvV")) != '\0')
4395 verbose_verify_only = 1;
4399 "command: nextopt returned character code 0%o\n", c);
4403 if (default_path + verify_only + verbose_verify_only > 1 ||
4406 "command [-p] command [arg ...]\n");
4408 "command {-v|-V} command\n");
4413 if (verify_only || verbose_verify_only) {
4414 return describe_command(*argptr, verbose_verify_only);
4423 path_change(newval, bltin)
4427 const char *old, *new;
4433 firstchange = 9999; /* assume no change */
4439 if ((*old == '\0' && *new == ':')
4440 || (*old == ':' && *new == '\0'))
4442 old = new; /* ignore subsequent differences */
4446 if (*new == '%' && *bltin < 0 && prefix("builtin", new + 1))
4453 if (builtinloc >= 0 && *bltin < 0)
4458 * Routines to expand arguments to commands. We have to deal with
4459 * backquotes, shell variables, and file metacharacters.
4464 #define RMESCAPE_ALLOC 0x1 /* Allocate a new string */
4465 #define RMESCAPE_GLOB 0x2 /* Add backslashes for glob */
4468 * Structure specifying which parts of the string should be searched
4469 * for IFS characters.
4473 struct ifsregion *next; /* next region in list */
4474 int begoff; /* offset of start of region */
4475 int endoff; /* offset of end of region */
4476 int nulonly; /* search for nul bytes only */
4480 static char *expdest; /* output of current string */
4481 static struct nodelist *argbackq; /* list of back quote expressions */
4482 static struct ifsregion ifsfirst; /* first struct in list of ifs regions */
4483 static struct ifsregion *ifslastp; /* last struct in list */
4484 static struct arglist exparg; /* holds expanded arg list */
4486 static void argstr (char *, int);
4487 static char *exptilde (char *, int);
4488 static void expbackq (union node *, int, int);
4489 static int subevalvar (char *, char *, int, int, int, int, int);
4490 static char *evalvar (char *, int);
4491 static int varisset (char *, int);
4492 static void strtodest (const char *, const char *, int);
4493 static void varvalue (char *, int, int);
4494 static void recordregion (int, int, int);
4495 static void removerecordregions (int);
4496 static void ifsbreakup (char *, struct arglist *);
4497 static void ifsfree (void);
4498 static void expandmeta (struct strlist *, int);
4499 #if defined(__GLIBC__) && !defined(FNMATCH_BROKEN)
4500 #define preglob(p) _rmescapes((p), RMESCAPE_ALLOC | RMESCAPE_GLOB)
4501 #if !defined(GLOB_BROKEN)
4502 static void addglob (const glob_t *);
4505 #if !(defined(__GLIBC__) && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN))
4506 static void expmeta (char *, char *);
4508 #if !(defined(__GLIBC__) && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN))
4509 static struct strlist *expsort (struct strlist *);
4510 static struct strlist *msort (struct strlist *, int);
4512 #if defined(__GLIBC__) && !defined(FNMATCH_BROKEN)
4513 static int patmatch (char *, char *, int);
4514 static int patmatch2 (char *, char *, int);
4516 static int pmatch (char *, char *, int);
4517 #define patmatch2 patmatch
4519 static char *cvtnum (int, char *);
4522 * Expand shell variables and backquotes inside a here document.
4525 /* arg: the document, fd: where to write the expanded version */
4527 expandhere(union node *arg, int fd)
4530 expandarg(arg, (struct arglist *)NULL, 0);
4531 xwrite(fd, stackblock(), expdest - stackblock());
4536 * Perform variable substitution and command substitution on an argument,
4537 * placing the resulting list of arguments in arglist. If EXP_FULL is true,
4538 * perform splitting and file name expansion. When arglist is NULL, perform
4539 * here document expansion.
4543 expandarg(arg, arglist, flag)
4545 struct arglist *arglist;
4551 argbackq = arg->narg.backquote;
4552 STARTSTACKSTR(expdest);
4553 ifsfirst.next = NULL;
4555 argstr(arg->narg.text, flag);
4556 if (arglist == NULL) {
4557 return; /* here document expanded */
4559 STPUTC('\0', expdest);
4560 p = grabstackstr(expdest);
4561 exparg.lastp = &exparg.list;
4565 if (flag & EXP_FULL) {
4566 ifsbreakup(p, &exparg);
4567 *exparg.lastp = NULL;
4568 exparg.lastp = &exparg.list;
4569 expandmeta(exparg.list, flag);
4571 if (flag & EXP_REDIR) /*XXX - for now, just remove escapes */
4573 sp = (struct strlist *)stalloc(sizeof (struct strlist));
4576 exparg.lastp = &sp->next;
4579 *exparg.lastp = NULL;
4581 *arglist->lastp = exparg.list;
4582 arglist->lastp = exparg.lastp;
4589 * Perform variable and command substitution. If EXP_FULL is set, output CTLESC
4590 * characters to allow for further processing. Otherwise treat
4591 * $@ like $* since no splitting will be performed.
4600 int quotes = flag & (EXP_FULL | EXP_CASE); /* do CTLESC */
4603 if (*p == '~' && (flag & (EXP_TILDE | EXP_VARTILDE)))
4604 p = exptilde(p, flag);
4608 case CTLENDVAR: /* ??? */
4611 /* "$@" syntax adherence hack */
4612 if (p[0] == CTLVAR && p[2] == '@' && p[3] == '=')
4614 if ((flag & EXP_FULL) != 0)
4624 p = evalvar(p, flag);
4627 case CTLBACKQ|CTLQUOTE:
4628 expbackq(argbackq->n, c & CTLQUOTE, flag);
4629 argbackq = argbackq->next;
4631 #ifdef ASH_MATH_SUPPORT
4639 * sort of a hack - expand tildes in variable
4640 * assignments (after the first '=' and after ':'s).
4643 if (flag & EXP_VARTILDE && *p == '~') {
4650 p = exptilde(p, flag);
4666 char c, *startp = p;
4669 int quotes = flag & (EXP_FULL | EXP_CASE);
4671 while ((c = *p) != '\0') {
4678 if (flag & EXP_VARTILDE)
4688 if (*(startp+1) == '\0') {
4689 if ((home = lookupvar("HOME")) == NULL)
4692 if ((pw = getpwnam(startp+1)) == NULL)
4699 strtodest(home, SQSYNTAX, quotes);
4708 removerecordregions(int endoff)
4710 if (ifslastp == NULL)
4713 if (ifsfirst.endoff > endoff) {
4714 while (ifsfirst.next != NULL) {
4715 struct ifsregion *ifsp;
4717 ifsp = ifsfirst.next->next;
4718 ckfree(ifsfirst.next);
4719 ifsfirst.next = ifsp;
4722 if (ifsfirst.begoff > endoff)
4725 ifslastp = &ifsfirst;
4726 ifsfirst.endoff = endoff;
4731 ifslastp = &ifsfirst;
4732 while (ifslastp->next && ifslastp->next->begoff < endoff)
4733 ifslastp=ifslastp->next;
4734 while (ifslastp->next != NULL) {
4735 struct ifsregion *ifsp;
4737 ifsp = ifslastp->next->next;
4738 ckfree(ifslastp->next);
4739 ifslastp->next = ifsp;
4742 if (ifslastp->endoff > endoff)
4743 ifslastp->endoff = endoff;
4747 #ifdef ASH_MATH_SUPPORT
4749 * Expand arithmetic expression. Backup to start of expression,
4750 * evaluate, place result in (backed up) result, adjust string position.
4758 int quotes = flag & (EXP_FULL | EXP_CASE);
4764 * This routine is slightly over-complicated for
4765 * efficiency. First we make sure there is
4766 * enough space for the result, which may be bigger
4767 * than the expression if we add exponentation. Next we
4768 * scan backwards looking for the start of arithmetic. If the
4769 * next previous character is a CTLESC character, then we
4770 * have to rescan starting from the beginning since CTLESC
4771 * characters have to be processed left to right.
4773 CHECKSTRSPACE(10, expdest);
4774 USTPUTC('\0', expdest);
4775 start = stackblock();
4777 while (*p != CTLARI && p >= start)
4780 error("missing CTLARI (shouldn't happen)");
4781 if (p > start && *(p-1) == CTLESC)
4782 for (p = start; *p != CTLARI; p++)
4791 removerecordregions(begoff);
4794 result = arith(p+2);
4795 snprintf(p, 12, "%d", result);
4801 recordregion(begoff, p - 1 - start, 0);
4802 result = expdest - p + 1;
4803 STADJUST(-result, expdest);
4808 * Expand stuff in backwards quotes.
4812 expbackq(cmd, quoted, flag)
4817 volatile struct backcmd in;
4821 char *dest = expdest;
4822 volatile struct ifsregion saveifs;
4823 struct ifsregion *volatile savelastp;
4824 struct nodelist *volatile saveargbackq;
4826 int startloc = dest - stackblock();
4827 char const *syntax = quoted? DQSYNTAX : BASESYNTAX;
4828 volatile int saveherefd;
4829 int quotes = flag & (EXP_FULL | EXP_CASE);
4830 struct jmploc jmploc;
4831 struct jmploc *volatile savehandler;
4835 /* Avoid longjmp clobbering */
4846 savelastp = ifslastp;
4847 saveargbackq = argbackq;
4848 saveherefd = herefd;
4850 if ((ex = setjmp(jmploc.loc))) {
4853 savehandler = handler;
4856 p = grabstackstr(dest);
4857 evalbackcmd(cmd, (struct backcmd *) &in);
4858 ungrabstackstr(p, dest);
4862 ifslastp = savelastp;
4863 argbackq = saveargbackq;
4864 herefd = saveherefd;
4872 if (--in.nleft < 0) {
4875 while ((i = read(in.fd, buf, sizeof buf)) < 0 && errno == EINTR);
4876 TRACE(("expbackq: read returns %d\n", i));
4883 if (lastc != '\0') {
4884 if (quotes && syntax[(int)lastc] == CCTL)
4885 STPUTC(CTLESC, dest);
4886 STPUTC(lastc, dest);
4890 /* Eat all trailing newlines */
4891 for (; dest > stackblock() && dest[-1] == '\n';)
4900 exitstatus = waitforjob(in.jp);
4901 handler = savehandler;
4903 longjmp(handler->loc, 1);
4906 recordregion(startloc, dest - stackblock(), 0);
4907 TRACE(("evalbackq: size=%d: \"%.*s\"\n",
4908 (dest - stackblock()) - startloc,
4909 (dest - stackblock()) - startloc,
4910 stackblock() + startloc));
4916 subevalvar(p, str, strloc, subtype, startloc, varflags, quotes)
4929 int saveherefd = herefd;
4930 struct nodelist *saveargbackq = argbackq;
4934 argstr(p, subtype != VSASSIGN && subtype != VSQUESTION ? EXP_CASE : 0);
4935 STACKSTRNUL(expdest);
4936 herefd = saveherefd;
4937 argbackq = saveargbackq;
4938 startp = stackblock() + startloc;
4940 str = stackblock() + strloc;
4944 setvar(str, startp, 0);
4945 amount = startp - expdest;
4946 STADJUST(amount, expdest);
4953 if (*p != CTLENDVAR) {
4954 out2fmt(snlfmt, startp);
4955 error((char *)NULL);
4957 error("%.*s: parameter %snot set", p - str - 1,
4958 str, (varflags & VSNUL) ? "null or "
4963 for (loc = startp; loc < str; loc++) {
4966 if (patmatch2(str, startp, quotes))
4969 if (quotes && *loc == CTLESC)
4975 for (loc = str - 1; loc >= startp;) {
4978 if (patmatch2(str, startp, quotes))
4982 if (quotes && loc > startp && *(loc - 1) == CTLESC) {
4983 for (q = startp; q < loc; q++)
4993 for (loc = str - 1; loc >= startp;) {
4994 if (patmatch2(str, loc, quotes))
4997 if (quotes && loc > startp && *(loc - 1) == CTLESC) {
4998 for (q = startp; q < loc; q++)
5007 case VSTRIMRIGHTMAX:
5008 for (loc = startp; loc < str - 1; loc++) {
5009 if (patmatch2(str, loc, quotes))
5011 if (quotes && *loc == CTLESC)
5024 amount = ((str - 1) - (loc - startp)) - expdest;
5025 STADJUST(amount, expdest);
5026 while (loc != str - 1)
5031 amount = loc - expdest;
5032 STADJUST(amount, expdest);
5033 STPUTC('\0', expdest);
5034 STADJUST(-1, expdest);
5040 * Expand a variable, and return a pointer to the next character in the
5060 int quotes = flag & (EXP_FULL | EXP_CASE);
5063 subtype = varflags & VSTYPE;
5068 p = strchr(p, '=') + 1;
5069 again: /* jump here after setting a variable with ${var=text} */
5071 set = varisset(var, varflags & VSNUL);
5074 val = lookupvar(var);
5075 if (val == NULL || ((varflags & VSNUL) && val[0] == '\0')) {
5082 startloc = expdest - stackblock();
5083 if (set && subtype != VSPLUS) {
5084 /* insert the value of the variable */
5086 varvalue(var, varflags & VSQUOTE, flag);
5087 if (subtype == VSLENGTH) {
5088 varlen = expdest - stackblock() - startloc;
5089 STADJUST(-varlen, expdest);
5092 if (subtype == VSLENGTH) {
5093 varlen = strlen(val);
5097 varflags & VSQUOTE ?
5098 DQSYNTAX : BASESYNTAX,
5105 if (subtype == VSPLUS)
5108 easy = ((varflags & VSQUOTE) == 0 ||
5109 (*var == '@' && shellparam.nparam != 1));
5114 expdest = cvtnum(varlen, expdest);
5121 recordregion(startloc, expdest - stackblock(),
5122 varflags & VSQUOTE);
5138 case VSTRIMRIGHTMAX:
5142 * Terminate the string and start recording the pattern
5145 STPUTC('\0', expdest);
5146 patloc = expdest - stackblock();
5147 if (subevalvar(p, NULL, patloc, subtype,
5148 startloc, varflags, quotes) == 0) {
5149 int amount = (expdest - stackblock() - patloc) + 1;
5150 STADJUST(-amount, expdest);
5152 /* Remove any recorded regions beyond start of variable */
5153 removerecordregions(startloc);
5159 if (subevalvar(p, var, 0, subtype, startloc,
5160 varflags, quotes)) {
5163 * Remove any recorded regions beyond
5166 removerecordregions(startloc);
5181 if (subtype != VSNORMAL) { /* skip to end of alternative */
5184 if ((c = *p++) == CTLESC)
5186 else if (c == CTLBACKQ || c == (CTLBACKQ|CTLQUOTE)) {
5188 argbackq = argbackq->next;
5189 } else if (c == CTLVAR) {
5190 if ((*p++ & VSTYPE) != VSNORMAL)
5192 } else if (c == CTLENDVAR) {
5202 * Test whether a specialized variable is set.
5206 varisset(name, nulok)
5211 return backgndpid != -1;
5212 else if (*name == '@' || *name == '*') {
5213 if (*shellparam.p == NULL)
5219 for (av = shellparam.p; *av; av++)
5224 } else if (is_digit(*name)) {
5226 int num = atoi(name);
5228 if (num > shellparam.nparam)
5234 ap = shellparam.p[num - 1];
5236 if (nulok && (ap == NULL || *ap == '\0'))
5243 * Put a string on the stack.
5247 strtodest(p, syntax, quotes)
5253 if (quotes && syntax[(int) *p] == CCTL)
5254 STPUTC(CTLESC, expdest);
5255 STPUTC(*p++, expdest);
5260 * Add the value of a specialized variable to the stack string.
5264 varvalue(name, quoted, flags)
5276 int allow_split = flags & EXP_FULL;
5277 int quotes = flags & (EXP_FULL | EXP_CASE);
5279 syntax = quoted ? DQSYNTAX : BASESYNTAX;
5288 num = shellparam.nparam;
5293 expdest = cvtnum(num, expdest);
5296 for (i = 0 ; i < NOPTS ; i++) {
5298 STPUTC(optent_letter(optlist[i]), expdest);
5302 if (allow_split && quoted) {
5303 sep = 1 << CHAR_BIT;
5308 sep = ifsset() ? ifsval()[0] : ' ';
5310 sepq = syntax[(int) sep] == CCTL;
5313 for (ap = shellparam.p ; (p = *ap++) != NULL ; ) {
5314 strtodest(p, syntax, quotes);
5317 STPUTC(CTLESC, expdest);
5318 STPUTC(sep, expdest);
5323 strtodest(arg0, syntax, quotes);
5327 if (num > 0 && num <= shellparam.nparam) {
5328 strtodest(shellparam.p[num - 1], syntax, quotes);
5336 * Record the fact that we have to scan this region of the
5337 * string for IFS characters.
5341 recordregion(start, end, nulonly)
5346 struct ifsregion *ifsp;
5348 if (ifslastp == NULL) {
5352 ifsp = (struct ifsregion *)ckmalloc(sizeof (struct ifsregion));
5354 ifslastp->next = ifsp;
5358 ifslastp->begoff = start;
5359 ifslastp->endoff = end;
5360 ifslastp->nulonly = nulonly;
5366 * Break the argument string into pieces based upon IFS and add the
5367 * strings to the argument list. The regions of the string to be
5368 * searched for IFS characters have been stored by recordregion.
5371 ifsbreakup(string, arglist)
5373 struct arglist *arglist;
5375 struct ifsregion *ifsp;
5380 const char *ifs, *realifs;
5388 realifs = ifsset() ? ifsval() : defifs;
5389 if (ifslastp != NULL) {
5392 p = string + ifsp->begoff;
5393 nulonly = ifsp->nulonly;
5394 ifs = nulonly ? nullstr : realifs;
5396 while (p < string + ifsp->endoff) {
5400 if (strchr(ifs, *p)) {
5402 ifsspc = (strchr(defifs, *p) != NULL);
5403 /* Ignore IFS whitespace at start */
5404 if (q == start && ifsspc) {
5410 sp = (struct strlist *)stalloc(sizeof *sp);
5412 *arglist->lastp = sp;
5413 arglist->lastp = &sp->next;
5417 if (p >= string + ifsp->endoff) {
5423 if (strchr(ifs, *p) == NULL ) {
5426 } else if (strchr(defifs, *p) == NULL) {
5442 } while ((ifsp = ifsp->next) != NULL);
5443 if (!(*start || (!ifsspc && start > string && nulonly))) {
5448 sp = (struct strlist *)stalloc(sizeof *sp);
5450 *arglist->lastp = sp;
5451 arglist->lastp = &sp->next;
5457 while (ifsfirst.next != NULL) {
5458 struct ifsregion *ifsp;
5460 ifsp = ifsfirst.next->next;
5461 ckfree(ifsfirst.next);
5462 ifsfirst.next = ifsp;
5466 ifsfirst.next = NULL;
5470 * Add a file name to the list.
5474 addfname(const char *name)
5480 sp = (struct strlist *)stalloc(sizeof *sp);
5483 exparg.lastp = &sp->next;
5487 * Expand shell metacharacters. At this point, the only control characters
5488 * should be escapes. The results are stored in the list exparg.
5491 #if defined(__GLIBC__) && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN)
5493 expandmeta(str, flag)
5494 struct strlist *str;
5499 /* TODO - EXP_REDIR */
5504 p = preglob(str->text);
5506 switch (glob(p, GLOB_NOMAGIC, 0, &pglob)) {
5508 if (!(pglob.gl_flags & GLOB_MAGCHAR))
5519 *exparg.lastp = str;
5520 rmescapes(str->text);
5521 exparg.lastp = &str->next;
5523 default: /* GLOB_NOSPACE */
5524 error("Out of space");
5532 * Add the result of glob(3) to the list.
5537 const glob_t *pglob;
5539 char **p = pglob->gl_pathv;
5547 #else /* defined(__GLIBC__) && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN) */
5548 static char *expdir;
5552 expandmeta(str, flag)
5553 struct strlist *str;
5557 struct strlist **savelastp;
5560 /* TODO - EXP_REDIR */
5566 for (;;) { /* fast check for meta chars */
5567 if ((c = *p++) == '\0')
5569 if (c == '*' || c == '?' || c == '[' || c == '!')
5572 savelastp = exparg.lastp;
5574 if (expdir == NULL) {
5575 int i = strlen(str->text);
5576 expdir = ckmalloc(i < 2048 ? 2048 : i); /* XXX */
5579 expmeta(expdir, str->text);
5583 if (exparg.lastp == savelastp) {
5588 *exparg.lastp = str;
5589 rmescapes(str->text);
5590 exparg.lastp = &str->next;
5592 *exparg.lastp = NULL;
5593 *savelastp = sp = expsort(*savelastp);
5594 while (sp->next != NULL)
5596 exparg.lastp = &sp->next;
5604 * Do metacharacter (i.e. *, ?, [...]) expansion.
5608 expmeta(enddir, name)
5626 for (p = name ; ; p++) {
5627 if (*p == '*' || *p == '?')
5629 else if (*p == '[') {
5634 while (*q == CTLQUOTEMARK)
5638 if (*q == '/' || *q == '\0')
5645 } else if (*p == '!' && p[1] == '!' && (p == name || p[-1] == '/')) {
5647 } else if (*p == '\0')
5649 else if (*p == CTLQUOTEMARK)
5651 else if (*p == CTLESC)
5659 if (metaflag == 0) { /* we've reached the end of the file name */
5660 if (enddir != expdir)
5662 for (p = name ; ; p++) {
5663 if (*p == CTLQUOTEMARK)
5671 if (metaflag == 0 || lstat(expdir, &statb) >= 0)
5676 if (start != name) {
5679 while (*p == CTLQUOTEMARK)
5686 if (enddir == expdir) {
5688 } else if (enddir == expdir + 1 && *expdir == '/') {
5694 if ((dirp = opendir(cp)) == NULL)
5696 if (enddir != expdir)
5698 if (*endname == 0) {
5706 while (*p == CTLQUOTEMARK)
5712 while (! int_pending() && (dp = readdir(dirp)) != NULL) {
5713 if (dp->d_name[0] == '.' && ! matchdot)
5715 if (patmatch(start, dp->d_name, 0)) {
5717 strcpy(enddir, dp->d_name);
5720 for (p = enddir, cp = dp->d_name;
5721 (*p++ = *cp++) != '\0';)
5724 expmeta(p, endname);
5732 #endif /* defined(__GLIBC__) && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN) */
5736 #if !(defined(__GLIBC__) && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN))
5738 * Sort the results of file name expansion. It calculates the number of
5739 * strings to sort and then calls msort (short for merge sort) to do the
5743 static struct strlist *
5745 struct strlist *str;
5751 for (sp = str ; sp ; sp = sp->next)
5753 return msort(str, len);
5757 static struct strlist *
5759 struct strlist *list;
5762 struct strlist *p, *q = NULL;
5763 struct strlist **lpp;
5771 for (n = half ; --n >= 0 ; ) {
5775 q->next = NULL; /* terminate first half of list */
5776 q = msort(list, half); /* sort first half of list */
5777 p = msort(p, len - half); /* sort second half */
5780 if (strcmp(p->text, q->text) < 0) {
5783 if ((p = *lpp) == NULL) {
5790 if ((q = *lpp) == NULL) {
5803 * Returns true if the pattern matches the string.
5806 #if defined(__GLIBC__) && !defined(FNMATCH_BROKEN)
5807 /* squoted: string might have quote chars */
5809 patmatch(char *pattern, char *string, int squoted)
5814 p = preglob(pattern);
5815 q = squoted ? _rmescapes(string, RMESCAPE_ALLOC) : string;
5817 return !fnmatch(p, q, 0);
5822 patmatch2(char *pattern, char *string, int squoted)
5828 p = grabstackstr(expdest);
5829 res = patmatch(pattern, string, squoted);
5830 ungrabstackstr(p, expdest);
5835 patmatch(char *pattern, char *string, int squoted) {
5836 return pmatch(pattern, string, squoted);
5841 pmatch(char *pattern, char *string, int squoted)
5853 if (squoted && *q == CTLESC)
5861 if (squoted && *q == CTLESC)
5868 while (c == CTLQUOTEMARK || c == '*')
5870 if (c != CTLESC && c != CTLQUOTEMARK &&
5871 c != '?' && c != '*' && c != '[') {
5873 if (squoted && *q == CTLESC &&
5878 if (squoted && *q == CTLESC)
5884 if (pmatch(p, q, squoted))
5886 if (squoted && *q == CTLESC)
5888 } while (*q++ != '\0');
5899 while (*endp == CTLQUOTEMARK)
5902 goto dft; /* no matching ] */
5903 if (*endp == CTLESC)
5915 if (squoted && chr == CTLESC)
5921 if (c == CTLQUOTEMARK)
5925 if (*p == '-' && p[1] != ']') {
5927 while (*p == CTLQUOTEMARK)
5931 if (chr >= c && chr <= *p)
5938 } while ((c = *p++) != ']');
5939 if (found == invert)
5944 if (squoted && *q == CTLESC)
5961 * Remove any CTLESC characters from a string.
5964 #if defined(__GLIBC__) && !defined(FNMATCH_BROKEN)
5966 _rmescapes(char *str, int flag)
5969 static const char qchars[] = { CTLESC, CTLQUOTEMARK, 0 };
5971 p = strpbrk(str, qchars);
5977 if (flag & RMESCAPE_ALLOC) {
5978 size_t len = p - str;
5979 q = r = stalloc(strlen(p) + len + 1);
5982 q = mempcpy(q, str, len);
5984 memcpy(q, str, len);
5990 if (*p == CTLQUOTEMARK) {
5996 if (flag & RMESCAPE_GLOB && *p != '/') {
6013 while (*p != CTLESC && *p != CTLQUOTEMARK) {
6019 if (*p == CTLQUOTEMARK) {
6034 * See if a pattern matches in a case statement.
6038 casematch(union node *pattern, const char *val)
6040 struct stackmark smark;
6044 setstackmark(&smark);
6045 argbackq = pattern->narg.backquote;
6046 STARTSTACKSTR(expdest);
6048 argstr(pattern->narg.text, EXP_TILDE | EXP_CASE);
6049 STPUTC('\0', expdest);
6050 p = grabstackstr(expdest);
6051 result = patmatch(p, (char *)val, 0);
6052 popstackmark(&smark);
6067 CHECKSTRSPACE(32, buf);
6068 len = sprintf(buf, "%d", num);
6073 * Editline and history functions (and glue).
6075 static int histcmd(argc, argv)
6079 error("not compiled with history support");
6084 static int whichprompt; /* 1 == PS1, 2 == PS2 */
6088 struct redirtab *next;
6092 static struct redirtab *redirlist;
6094 extern char **environ;
6099 * Initialization code.
6112 basepf.nextc = basepf.buf = basebuf;
6121 for (envp = environ ; *envp ; envp++) {
6122 if (strchr(*envp, '=')) {
6123 setvareq(*envp, VEXPORT|VTEXTFIXED);
6127 snprintf(ppid, sizeof(ppid), "%d", (int) getppid());
6128 setvar("PPID", ppid, 0);
6135 * This routine is called when an error or an interrupt occurs in an
6136 * interactive shell and control is returned to the main command loop.
6140 /* 1 == check for aliases, 2 == also check for assignments */
6141 static int checkalias;
6156 if (exception != EXSHELLPROC)
6157 parselleft = parsenleft = 0; /* clear input buffer */
6161 /* from parser.c: */
6181 * This file implements the input routines used by the parser.
6184 #ifdef BB_FEATURE_COMMAND_EDITING
6185 unsigned int shell_context;
6186 static const char * cmdedit_prompt;
6187 static inline void putprompt(const char *s) {
6191 static inline void putprompt(const char *s) {
6196 #define EOF_NLEFT -99 /* value of parsenleft when EOF pushed back */
6201 * Same as pgetc(), but ignores PEOA.
6211 } while (c == PEOA);
6215 static inline int pgetc2() { return pgetc_macro(); }
6219 * Read a line from the script.
6223 pfgets(char *line, int len)
6229 while (--nleft > 0) {
6248 char *buf = parsefile->buf;
6252 #ifdef BB_FEATURE_COMMAND_EDITING
6255 nr = read(parsefile->fd, buf, BUFSIZ - 1);
6258 cmdedit_read_input((char*)cmdedit_prompt, buf);
6260 } while (nr <=0 || shell_context);
6261 cmdedit_terminate();
6265 nr = read(parsefile->fd, buf, BUFSIZ - 1);
6271 if (parsefile->fd == 0 && errno == EWOULDBLOCK) {
6272 int flags = fcntl(0, F_GETFL, 0);
6273 if (flags >= 0 && flags & O_NONBLOCK) {
6274 flags &=~ O_NONBLOCK;
6275 if (fcntl(0, F_SETFL, flags) >= 0) {
6276 out2str("sh: turning off NDELAY mode\n");
6288 struct strpush *sp = parsefile->strpush;
6293 if (parsenextc[-1] == ' ' || parsenextc[-1] == '\t') {
6298 if (sp->string != sp->ap->val) {
6302 sp->ap->flag &= ~ALIASINUSE;
6303 if (sp->ap->flag & ALIASDEAD) {
6304 unalias(sp->ap->name);
6308 parsenextc = sp->prevstring;
6309 parsenleft = sp->prevnleft;
6310 /*dprintf("*** calling popstring: restoring to '%s'\n", parsenextc);*/
6311 parsefile->strpush = sp->prev;
6312 if (sp != &(parsefile->basestrpush))
6319 * Refill the input buffer and return the next input character:
6321 * 1) If a string was pushed back on the input, pop it;
6322 * 2) If an EOF was pushed back (parsenleft == EOF_NLEFT) or we are reading
6323 * from a string so we can't refill the buffer, return EOF.
6324 * 3) If the is more stuff in this buffer, use it else call read to fill it.
6325 * 4) Process input up to the next newline, deleting nul characters.
6335 while (parsefile->strpush) {
6337 if (parsenleft == -1 && parsefile->strpush->ap &&
6338 parsenextc[-1] != ' ' && parsenextc[-1] != '\t') {
6343 if (--parsenleft >= 0)
6344 return (*parsenextc++);
6346 if (parsenleft == EOF_NLEFT || parsefile->buf == NULL)
6351 if (parselleft <= 0) {
6352 if ((parselleft = preadfd()) <= 0) {
6353 parselleft = parsenleft = EOF_NLEFT;
6360 /* delete nul characters */
6361 for (more = 1; more;) {
6369 parsenleft = q - parsenextc;
6370 more = 0; /* Stop processing here */
6376 if (--parselleft <= 0 && more) {
6377 parsenleft = q - parsenextc - 1;
6388 out2str(parsenextc);
6393 return *parsenextc++;
6398 * Push a string back onto the input at this current parsefile level.
6399 * We handle aliases this way.
6402 pushstring(char *s, int len, void *ap)
6407 /*dprintf("*** calling pushstring: %s, %d\n", s, len);*/
6408 if (parsefile->strpush) {
6409 sp = ckmalloc(sizeof (struct strpush));
6410 sp->prev = parsefile->strpush;
6411 parsefile->strpush = sp;
6413 sp = parsefile->strpush = &(parsefile->basestrpush);
6414 sp->prevstring = parsenextc;
6415 sp->prevnleft = parsenleft;
6417 sp->ap = (struct alias *)ap;
6419 ((struct alias *)ap)->flag |= ALIASINUSE;
6432 * Like setinputfile, but takes input from a string.
6436 setinputstring(string)
6441 parsenextc = string;
6442 parsenleft = strlen(string);
6443 parsefile->buf = NULL;
6451 * To handle the "." command, a stack of input files is used. Pushfile
6452 * adds a new entry to the stack and popfile restores the previous level.
6457 struct parsefile *pf;
6459 parsefile->nleft = parsenleft;
6460 parsefile->lleft = parselleft;
6461 parsefile->nextc = parsenextc;
6462 parsefile->linno = plinno;
6463 pf = (struct parsefile *)ckmalloc(sizeof (struct parsefile));
6464 pf->prev = parsefile;
6467 pf->basestrpush.prev = NULL;
6472 static void restartjob (struct job *);
6474 static void freejob (struct job *);
6475 static struct job *getjob (const char *);
6476 static int dowait (int, struct job *);
6477 static int waitproc (int, int *);
6478 static void waitonint(int);
6482 * We keep track of whether or not fd0 has been redirected. This is for
6483 * background commands, where we want to redirect fd0 to /dev/null only
6484 * if it hasn't already been redirected.
6486 static int fd0_redirected = 0;
6488 /* Return true if fd 0 has already been redirected at least once. */
6490 fd0_redirected_p () {
6491 return fd0_redirected != 0;
6494 static int openredirect (union node *);
6495 static void dupredirect (union node *, int, char[10 ]);
6496 static int openhere (union node *);
6497 static int noclobberopen (const char *);
6503 * Turn job control on and off.
6505 * Note: This code assumes that the third arg to ioctl is a character
6506 * pointer, which is true on Berkeley systems but not System V. Since
6507 * System V doesn't have job control yet, this isn't a problem now.
6512 static void setjobctl(int enable)
6514 #ifdef OLD_TTY_DRIVER
6518 if (enable == jobctl || rootshell == 0)
6521 do { /* while we are in the background */
6522 #ifdef OLD_TTY_DRIVER
6523 if (ioctl(2, TIOCGPGRP, (char *)&initialpgrp) < 0) {
6525 initialpgrp = tcgetpgrp(2);
6526 if (initialpgrp < 0) {
6528 out2str("sh: can't access tty; job cenabletrol turned off\n");
6532 if (initialpgrp == -1)
6533 initialpgrp = getpgrp();
6534 else if (initialpgrp != getpgrp()) {
6535 killpg(initialpgrp, SIGTTIN);
6539 #ifdef OLD_TTY_DRIVER
6540 if (ioctl(2, TIOCGETD, (char *)&ldisc) < 0 || ldisc != NTTYDISC) {
6541 out2str("sh: need new tty driver to run job cenabletrol; job cenabletrol turned off\n");
6549 setpgid(0, rootpid);
6550 #ifdef OLD_TTY_DRIVER
6551 ioctl(2, TIOCSPGRP, (char *)&rootpid);
6553 tcsetpgrp(2, rootpid);
6555 } else { /* turning job cenabletrol off */
6556 setpgid(0, initialpgrp);
6557 #ifdef OLD_TTY_DRIVER
6558 ioctl(2, TIOCSPGRP, (char *)&initialpgrp);
6560 tcsetpgrp(2, initialpgrp);
6571 /* A translation list so we can be polite to our users. */
6572 static char *signal_names[NSIG + 2] = {
6658 "Usage: kill [-s sigspec | -signum | -sigspec] [pid | job]... or\n"
6659 "kill -l [exitstatus]"
6663 if (*argv[1] == '-') {
6664 signo = decode_signal(argv[1] + 1, 1);
6668 while ((c = nextopt("ls:")) != '\0')
6674 signo = decode_signal(optionarg, 1);
6677 "invalid signal number or name: %s",
6685 "nextopt returned character code 0%o", c);
6692 if (!list && signo < 0)
6695 if ((signo < 0 || !*argptr) ^ list) {
6702 for (i = 1; i < NSIG; i++) {
6703 out1fmt(snlfmt, signal_names[i] + 3);
6707 signo = atoi(*argptr);
6710 if (0 < signo && signo < NSIG)
6711 out1fmt(snlfmt, signal_names[signo] + 3);
6713 error("invalid signal number or exit status: %s",
6719 if (**argptr == '%') {
6720 jp = getjob(*argptr);
6721 if (jp->jobctl == 0)
6722 error("job %s not created under job control",
6724 pid = -jp->ps[0].pid;
6726 pid = atoi(*argptr);
6727 if (kill(pid, signo) != 0)
6728 error("%s: %m", *argptr);
6729 } while (*++argptr);
6743 jp = getjob(argv[1]);
6744 if (jp->jobctl == 0)
6745 error("job not created under job control");
6746 pgrp = jp->ps[0].pid;
6747 #ifdef OLD_TTY_DRIVER
6748 ioctl(2, TIOCSPGRP, (char *)&pgrp);
6754 status = waitforjob(jp);
6768 jp = getjob(*++argv);
6769 if (jp->jobctl == 0)
6770 error("job not created under job control");
6772 } while (--argc > 1);
6781 struct procstat *ps;
6784 if (jp->state == JOBDONE)
6787 killpg(jp->ps[0].pid, SIGCONT);
6788 for (ps = jp->ps, i = jp->nprocs ; --i >= 0 ; ps++) {
6789 if (WIFSTOPPED(ps->status)) {
6798 static void showjobs(int change);
6812 * Print a list of jobs. If "change" is nonzero, only print jobs whose
6813 * statuses have changed since the last call to showjobs.
6815 * If the shell is interrupted in the process of creating a job, the
6816 * result may be a job structure containing zero processes. Such structures
6817 * will be freed here.
6828 struct procstat *ps;
6832 TRACE(("showjobs(%d) called\n", change));
6833 while (dowait(0, (struct job *)NULL) > 0);
6834 for (jobno = 1, jp = jobtab ; jobno <= njobs ; jobno++, jp++) {
6837 if (jp->nprocs == 0) {
6841 if (change && ! jp->changed)
6843 procno = jp->nprocs;
6844 for (ps = jp->ps ; ; ps++) { /* for each process */
6846 snprintf(s, 64, "[%d] %ld ", jobno,
6849 snprintf(s, 64, " %ld ",
6854 if (ps->status == -1) {
6855 /* don't print anything */
6856 } else if (WIFEXITED(ps->status)) {
6857 snprintf(s, 64, "Exit %d",
6858 WEXITSTATUS(ps->status));
6861 if (WIFSTOPPED(ps->status))
6862 i = WSTOPSIG(ps->status);
6863 else /* WIFSIGNALED(ps->status) */
6865 i = WTERMSIG(ps->status);
6866 if ((i & 0x7F) < NSIG && sys_siglist[i & 0x7F])
6867 strcpy(s, sys_siglist[i & 0x7F]);
6869 snprintf(s, 64, "Signal %d", i & 0x7F);
6870 if (WCOREDUMP(ps->status))
6871 strcat(s, " (core dumped)");
6876 "%*c%s\n", 30 - col >= 0 ? 30 - col : 0, ' ',
6883 if (jp->state == JOBDONE) {
6891 * Mark a job structure as unused.
6898 struct procstat *ps;
6902 for (i = jp->nprocs, ps = jp->ps ; --i >= 0 ; ps++) {
6903 if (ps->cmd != nullstr)
6906 if (jp->ps != &jp->ps0)
6910 if (curjob == jp - jobtab + 1)
6929 job = getjob(*++argv);
6933 for (;;) { /* loop until process terminated or stopped */
6936 status = job->ps[job->nprocs - 1].status;
6942 if (WIFEXITED(status))
6943 retval = WEXITSTATUS(status);
6945 else if (WIFSTOPPED(status))
6946 retval = WSTOPSIG(status) + 128;
6949 /* XXX: limits number of signals */
6950 retval = WTERMSIG(status) + 128;
6955 for (jp = jobtab ; ; jp++) {
6956 if (jp >= jobtab + njobs) { /* no running procs */
6959 if (jp->used && jp->state == 0)
6963 if (dowait(2, 0) < 0 && errno == EINTR) {
6972 * Convert a job name to a job structure.
6976 getjob(const char *name)
6986 if ((jobno = curjob) == 0 || jobtab[jobno - 1].used == 0)
6987 error("No current job");
6988 return &jobtab[jobno - 1];
6990 error("No current job");
6992 } else if (name[0] == '%') {
6993 if (is_digit(name[1])) {
6994 jobno = number(name + 1);
6995 if (jobno > 0 && jobno <= njobs
6996 && jobtab[jobno - 1].used != 0)
6997 return &jobtab[jobno - 1];
6999 } else if (name[1] == '%' && name[2] == '\0') {
7003 struct job *found = NULL;
7004 for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) {
7005 if (jp->used && jp->nprocs > 0
7006 && prefix(name + 1, jp->ps[0].cmd)) {
7008 error("%s: ambiguous", name);
7015 } else if (is_number(name, &pid)) {
7016 for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) {
7017 if (jp->used && jp->nprocs > 0
7018 && jp->ps[jp->nprocs - 1].pid == pid)
7022 error("No such job: %s", name);
7029 * Return a new job structure,
7033 makejob(node, nprocs)
7040 for (i = njobs, jp = jobtab ; ; jp++) {
7044 jobtab = ckmalloc(4 * sizeof jobtab[0]);
7046 jp = ckmalloc((njobs + 4) * sizeof jobtab[0]);
7047 memcpy(jp, jobtab, njobs * sizeof jp[0]);
7048 /* Relocate `ps' pointers */
7049 for (i = 0; i < njobs; i++)
7050 if (jp[i].ps == &jobtab[i].ps0)
7051 jp[i].ps = &jp[i].ps0;
7055 jp = jobtab + njobs;
7056 for (i = 4 ; --i >= 0 ; jobtab[njobs++].used = 0);
7069 jp->jobctl = jobctl;
7072 jp->ps = ckmalloc(nprocs * sizeof (struct procstat));
7077 TRACE(("makejob(0x%lx, %d) returns %%%d\n", (long)node, nprocs,
7084 * Fork of a subshell. If we are doing job control, give the subshell its
7085 * own process group. Jp is a job structure that the job is to be added to.
7086 * N is the command that will be evaluated by the child. Both jp and n may
7087 * be NULL. The mode parameter can be one of the following:
7088 * FORK_FG - Fork off a foreground process.
7089 * FORK_BG - Fork off a background process.
7090 * FORK_NOJOB - Like FORK_FG, but don't give the process its own
7091 * process group even if job control is on.
7093 * When job control is turned off, background processes have their standard
7094 * input redirected to /dev/null (except for the second and later processes
7101 forkshell(struct job *jp, union node *n, int mode)
7105 const char *devnull = _PATH_DEVNULL;
7106 const char *nullerr = "Can't open %s";
7108 TRACE(("forkshell(%%%d, 0x%lx, %d) called\n", jp - jobtab, (long)n,
7113 TRACE(("Fork failed, errno=%d\n", errno));
7115 error("Cannot fork");
7122 TRACE(("Child shell %d\n", getpid()));
7123 wasroot = rootshell;
7129 jobctl = 0; /* do job control only in root shell */
7130 if (wasroot && mode != FORK_NOJOB && mflag) {
7131 if (jp == NULL || jp->nprocs == 0)
7134 pgrp = jp->ps[0].pid;
7136 if (mode == FORK_FG) {
7137 /*** this causes superfluous TIOCSPGRPS ***/
7138 #ifdef OLD_TTY_DRIVER
7139 if (ioctl(2, TIOCSPGRP, (char *)&pgrp) < 0)
7140 error("TIOCSPGRP failed, errno=%d", errno);
7142 if (tcsetpgrp(2, pgrp) < 0)
7143 error("tcsetpgrp failed, errno=%d", errno);
7148 } else if (mode == FORK_BG) {
7151 if ((jp == NULL || jp->nprocs == 0) &&
7152 ! fd0_redirected_p ()) {
7154 if (open(devnull, O_RDONLY) != 0)
7155 error(nullerr, devnull);
7159 if (mode == FORK_BG) {
7162 if ((jp == NULL || jp->nprocs == 0) &&
7163 ! fd0_redirected_p ()) {
7165 if (open(devnull, O_RDONLY) != 0)
7166 error(nullerr, devnull);
7170 for (i = njobs, p = jobtab ; --i >= 0 ; p++)
7173 if (wasroot && iflag) {
7180 if (rootshell && mode != FORK_NOJOB && mflag) {
7181 if (jp == NULL || jp->nprocs == 0)
7184 pgrp = jp->ps[0].pid;
7187 if (mode == FORK_BG)
7188 backgndpid = pid; /* set $! */
7190 struct procstat *ps = &jp->ps[jp->nprocs++];
7194 if (iflag && rootshell && n)
7195 ps->cmd = commandtext(n);
7198 TRACE(("In parent shell: child = %d\n", pid));
7205 * Wait for job to finish.
7207 * Under job control we have the problem that while a child process is
7208 * running interrupts generated by the user are sent to the child but not
7209 * to the shell. This means that an infinite loop started by an inter-
7210 * active user may be hard to kill. With job control turned off, an
7211 * interactive user may place an interactive program inside a loop. If
7212 * the interactive program catches interrupts, the user doesn't want
7213 * these interrupts to also abort the loop. The approach we take here
7214 * is to have the shell ignore interrupt signals while waiting for a
7215 * forground process to terminate, and then send itself an interrupt
7216 * signal if the child process was terminated by an interrupt signal.
7217 * Unfortunately, some programs want to do a bit of cleanup and then
7218 * exit on interrupt; unless these processes terminate themselves by
7219 * sending a signal to themselves (instead of calling exit) they will
7220 * confuse this approach.
7228 int mypgrp = getpgrp();
7232 struct sigaction act, oact;
7241 sigaction(SIGINT, 0, &act);
7242 act.sa_handler = waitonint;
7243 sigaction(SIGINT, &act, &oact);
7245 TRACE(("waitforjob(%%%d) called\n", jp - jobtab + 1));
7246 while (jp->state == 0) {
7254 sigaction(SIGINT, &oact, 0);
7255 if (intreceived && trap[SIGINT]) kill(getpid(), SIGINT);
7259 #ifdef OLD_TTY_DRIVER
7260 if (ioctl(2, TIOCSPGRP, (char *)&mypgrp) < 0)
7261 error("TIOCSPGRP failed, errno=%d\n", errno);
7263 if (tcsetpgrp(2, mypgrp) < 0)
7264 error("tcsetpgrp failed, errno=%d\n", errno);
7267 if (jp->state == JOBSTOPPED)
7268 curjob = jp - jobtab + 1;
7270 status = jp->ps[jp->nprocs - 1].status;
7271 /* convert to 8 bits */
7272 if (WIFEXITED(status))
7273 st = WEXITSTATUS(status);
7275 else if (WIFSTOPPED(status))
7276 st = WSTOPSIG(status) + 128;
7279 st = WTERMSIG(status) + 128;
7283 * This is truly gross.
7284 * If we're doing job control, then we did a TIOCSPGRP which
7285 * caused us (the shell) to no longer be in the controlling
7286 * session -- so we wouldn't have seen any ^C/SIGINT. So, we
7287 * intuit from the subprocess exit status whether a SIGINT
7288 * occured, and if so interrupt ourselves. Yuck. - mycroft
7290 if (WIFSIGNALED(status) && WTERMSIG(status) == SIGINT)
7293 if (jp->state == JOBDONE)
7304 * Wait for a process to terminate.
7314 struct procstat *sp;
7316 struct job *thisjob;
7322 TRACE(("dowait(%d) called\n", block));
7324 pid = waitproc(block, &status);
7325 TRACE(("wait returns %d, status=%d\n", pid, status));
7326 } while (!(block & 2) && pid == -1 && errno == EINTR);
7331 for (jp = jobtab ; jp < jobtab + njobs ; jp++) {
7335 for (sp = jp->ps ; sp < jp->ps + jp->nprocs ; sp++) {
7338 if (sp->pid == pid) {
7339 TRACE(("Changing status of proc %d from 0x%x to 0x%x\n", pid, sp->status, status));
7340 sp->status = status;
7343 if (sp->status == -1)
7345 else if (WIFSTOPPED(sp->status))
7348 if (stopped) { /* stopped or done */
7349 int state = done? JOBDONE : JOBSTOPPED;
7350 if (jp->state != state) {
7351 TRACE(("Job %d: changing state from %d to %d\n", jp - jobtab + 1, jp->state, state));
7354 if (done && curjob == jp - jobtab + 1)
7355 curjob = 0; /* no current job */
7362 if (! rootshell || ! iflag || (job && thisjob == job)) {
7363 core = WCOREDUMP(status);
7365 if (WIFSTOPPED(status)) sig = WSTOPSIG(status);
7368 if (WIFEXITED(status)) sig = 0;
7369 else sig = WTERMSIG(status);
7371 if (sig != 0 && sig != SIGINT && sig != SIGPIPE) {
7373 out2fmt("%d: ", pid);
7375 if (sig == SIGTSTP && rootshell && iflag)
7377 (long)(job - jobtab + 1));
7379 if (sig < NSIG && sys_siglist[sig])
7380 out2str(sys_siglist[sig]);
7382 out2fmt("Signal %d", sig);
7384 out2str(" - core dumped");
7387 TRACE(("Not printing status: status=%d, sig=%d\n",
7391 TRACE(("Not printing status, rootshell=%d, job=0x%x\n", rootshell, job));
7393 thisjob->changed = 1;
7401 * Do a wait system call. If job control is compiled in, we accept
7402 * stopped processes. If block is zero, we return a value of zero
7403 * rather than blocking.
7405 * System V doesn't have a non-blocking wait system call. It does
7406 * have a SIGCLD signal that is sent to a process when one of it's
7407 * children dies. The obvious way to use SIGCLD would be to install
7408 * a handler for SIGCLD which simply bumped a counter when a SIGCLD
7409 * was received, and have waitproc bump another counter when it got
7410 * the status of a process. Waitproc would then know that a wait
7411 * system call would not block if the two counters were different.
7412 * This approach doesn't work because if a process has children that
7413 * have not been waited for, System V will send it a SIGCLD when it
7414 * installs a signal handler for SIGCLD. What this means is that when
7415 * a child exits, the shell will be sent SIGCLD signals continuously
7416 * until is runs out of stack space, unless it does a wait call before
7417 * restoring the signal handler. The code below takes advantage of
7418 * this (mis)feature by installing a signal handler for SIGCLD and
7419 * then checking to see whether it was called. If there are any
7420 * children to be waited for, it will be.
7425 waitproc(block, status)
7438 return wait3(status, flags, (struct rusage *)NULL);
7442 * return 1 if there are stopped jobs, otherwise 0
7452 for (jobno = 1, jp = jobtab; jobno <= njobs; jobno++, jp++) {
7455 if (jp->state == JOBSTOPPED) {
7456 out2str("You have stopped jobs.\n");
7466 * Return a string identifying a command (to be printed by the
7470 static char *cmdnextc;
7471 static int cmdnleft;
7472 #define MAXCMDTEXT 200
7475 cmdputs(const char *s)
7486 while ((c = *p++) != '\0') {
7489 else if (c == CTLVAR) {
7494 } else if (c == '=' && subtype != 0) {
7495 *q++ = "}-+?="[(subtype & VSTYPE) - VSNORMAL];
7497 } else if (c == CTLENDVAR) {
7499 } else if (c == CTLBACKQ || c == CTLBACKQ+CTLQUOTE)
7500 cmdnleft++; /* ignore it */
7503 if (--cmdnleft <= 0) {
7515 cmdtxt(const union node *n)
7518 struct nodelist *lp;
7527 cmdtxt(n->nbinary.ch1);
7529 cmdtxt(n->nbinary.ch2);
7532 cmdtxt(n->nbinary.ch1);
7534 cmdtxt(n->nbinary.ch2);
7537 cmdtxt(n->nbinary.ch1);
7539 cmdtxt(n->nbinary.ch2);
7542 for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
7550 cmdtxt(n->nredir.n);
7555 cmdtxt(n->nredir.n);
7559 cmdtxt(n->nif.test);
7561 cmdtxt(n->nif.ifpart);
7570 cmdtxt(n->nbinary.ch1);
7572 cmdtxt(n->nbinary.ch2);
7577 cmdputs(n->nfor.var);
7582 cmdputs(n->ncase.expr->narg.text);
7586 cmdputs(n->narg.text);
7590 for (np = n->ncmd.args ; np ; np = np->narg.next) {
7595 for (np = n->ncmd.redirect ; np ; np = np->nfile.next) {
7601 cmdputs(n->narg.text);
7604 p = ">"; i = 1; goto redir;
7606 p = ">>"; i = 1; goto redir;
7608 p = ">&"; i = 1; goto redir;
7610 p = ">|"; i = 1; goto redir;
7612 p = "<"; i = 0; goto redir;
7614 p = "<&"; i = 0; goto redir;
7616 p = "<>"; i = 0; goto redir;
7618 if (n->nfile.fd != i) {
7619 s[0] = n->nfile.fd + '0';
7624 if (n->type == NTOFD || n->type == NFROMFD) {
7625 s[0] = n->ndup.dupfd + '0';
7629 cmdtxt(n->nfile.fname);
7644 commandtext(const union node *n)
7648 cmdnextc = name = ckmalloc(MAXCMDTEXT);
7649 cmdnleft = MAXCMDTEXT - 4;
7656 static void waitonint(int sig) {
7661 * Routines to check for mail. (Perhaps make part of main.c?)
7665 #define MAXMBOXES 10
7668 static int nmboxes; /* number of mailboxes */
7669 static time_t mailtime[MAXMBOXES]; /* times of mailboxes */
7674 * Print appropriate message(s) if mail has arrived. If the argument is
7675 * nozero, then the value of MAIL has changed, so we just update the
7686 struct stackmark smark;
7693 setstackmark(&smark);
7694 mpath = mpathset()? mpathval() : mailval();
7695 for (i = 0 ; i < nmboxes ; i++) {
7696 p = padvance(&mpath, nullstr);
7701 for (q = p ; *q ; q++);
7706 q[-1] = '\0'; /* delete trailing '/' */
7707 if (stat(p, &statb) < 0)
7709 if (statb.st_size > mailtime[i] && ! silent) {
7711 pathopt? pathopt : "you have mail");
7713 mailtime[i] = statb.st_size;
7716 popstackmark(&smark);
7722 static short profile_buf[16384];
7726 static void read_profile (const char *);
7727 static char *find_dot_file (char *);
7728 static void cmdloop (int);
7729 static void options (int);
7730 static void minus_o (char *, int);
7731 static void setoption (int, int);
7732 static void procargs (int, char **);
7736 * Main routine. We initialize things, parse the arguments, execute
7737 * profiles if we're a login shell, and then call cmdloop to execute
7738 * commands. The setjmp call sets up the location to jump to when an
7739 * exception occurs. When an exception occurs the variable "state"
7740 * is used to figure out how far we had gotten.
7744 shell_main(argc, argv)
7748 struct jmploc jmploc;
7749 struct stackmark smark;
7753 DOTCMD = find_builtin(".");
7754 BLTINCMD = find_builtin("builtin");
7755 EXECCMD = find_builtin("exec");
7756 EVALCMD = find_builtin("eval");
7759 monitor(4, etext, profile_buf, sizeof profile_buf, 50);
7761 #if defined(linux) || defined(__GNU__)
7762 signal(SIGCHLD, SIG_DFL);
7765 if (setjmp(jmploc.loc)) {
7768 * When a shell procedure is executed, we raise the
7769 * exception EXSHELLPROC to clean up before executing
7770 * the shell procedure.
7772 switch (exception) {
7781 exitstatus = exerrno;
7792 if (exception != EXSHELLPROC) {
7793 if (state == 0 || iflag == 0 || ! rootshell)
7794 exitshell(exitstatus);
7797 if (exception == EXINT) {
7800 popstackmark(&smark);
7801 FORCEINTON; /* enable interrupts */
7804 else if (state == 2)
7806 else if (state == 3)
7814 trputs("Shell args: "); trargs(argv);
7819 setstackmark(&smark);
7820 procargs(argc, argv);
7821 if (argv[0] && argv[0][0] == '-') {
7823 read_profile("/etc/profile");
7826 read_profile(".profile");
7831 if (getuid() == geteuid() && getgid() == getegid()) {
7833 if ((shinit = lookupvar("ENV")) != NULL && *shinit != '\0') {
7835 read_profile(shinit);
7842 if (sflag == 0 || minusc) {
7843 static int sigs[] = {
7844 SIGINT, SIGQUIT, SIGHUP,
7850 #define SIGSSIZE (sizeof(sigs)/sizeof(sigs[0]))
7853 for (i = 0; i < SIGSSIZE; i++)
7858 evalstring(minusc, 0);
7860 if (sflag || minusc == NULL) {
7861 state4: /* XXX ??? - why isn't this before the "if" statement */
7867 exitshell(exitstatus);
7873 * Read and execute commands. "Top" is nonzero for the top level command
7874 * loop; it turns on prompting if the shell is interactive.
7881 struct stackmark smark;
7885 TRACE(("cmdloop(%d) called\n", top));
7886 setstackmark(&smark);
7897 n = parsecmd(inter);
7898 /* showtree(n); DEBUG */
7900 if (!top || numeof >= 50)
7902 if (!stoppedjobs()) {
7905 out2str("\nUse \"exit\" to leave shell.\n");
7908 } else if (n != NULL && nflag == 0) {
7909 job_warning = (job_warning == 2) ? 1 : 0;
7913 popstackmark(&smark);
7914 setstackmark(&smark);
7915 if (evalskip == SKIPFILE) {
7920 popstackmark(&smark);
7926 * Read /etc/profile or .profile. Return on error.
7938 if ((fd = open(name, O_RDONLY)) >= 0)
7943 /* -q turns off -x and -v just when executing init files */
7946 xflag = 0, xflag_set = 1;
7948 vflag = 0, vflag_set = 1;
7963 * Read a file containing shell functions.
7967 readcmdfile(const char *name)
7972 if ((fd = open(name, O_RDONLY)) >= 0)
7975 error("Can't open %s", name);
7984 * Take commands from a file. To be compatable we should do a path
7985 * search for the file, which is necessary to find sub-commands.
7990 find_dot_file(mybasename)
7994 const char *path = pathval();
7997 /* don't try this for absolute or relative paths */
7998 if (strchr(mybasename, '/'))
8001 while ((fullname = padvance(&path, mybasename)) != NULL) {
8002 if ((stat(fullname, &statb) == 0) && S_ISREG(statb.st_mode)) {
8004 * Don't bother freeing here, since it will
8005 * be freed by the caller.
8009 stunalloc(fullname);
8012 /* not found in the PATH */
8013 error("%s: not found", mybasename);
8025 for (sp = cmdenviron; sp ; sp = sp->next)
8026 setvareq(savestr(sp->text), VSTRFIXED|VTEXTFIXED);
8028 if (argc >= 2) { /* That's what SVR2 does */
8030 struct stackmark smark;
8032 setstackmark(&smark);
8033 fullname = find_dot_file(argv[1]);
8034 setinputfile(fullname, 1);
8035 commandname = fullname;
8038 popstackmark(&smark);
8052 exitstatus = number(argv[1]);
8054 exitstatus = oexitstatus;
8055 exitshell(exitstatus);
8063 nbytes = ALIGN(nbytes);
8064 if (nbytes > stacknleft) {
8066 struct stack_block *sp;
8069 if (blocksize < MINSIZE)
8070 blocksize = MINSIZE;
8072 sp = ckmalloc(sizeof(struct stack_block) - MINSIZE + blocksize);
8074 stacknxt = sp->space;
8075 stacknleft = blocksize;
8081 stacknleft -= nbytes;
8087 stunalloc(pointer p)
8090 if (p == NULL) { /*DEBUG */
8091 write(2, "stunalloc\n", 10);
8095 if (!(stacknxt >= (char *)p && (char *)p >= stackp->space)) {
8098 stacknleft += stacknxt - (char *)p;
8104 setstackmark(struct stackmark *mark)
8106 mark->stackp = stackp;
8107 mark->stacknxt = stacknxt;
8108 mark->stacknleft = stacknleft;
8109 mark->marknext = markp;
8115 popstackmark(struct stackmark *mark)
8117 struct stack_block *sp;
8120 markp = mark->marknext;
8121 while (stackp != mark->stackp) {
8126 stacknxt = mark->stacknxt;
8127 stacknleft = mark->stacknleft;
8133 * When the parser reads in a string, it wants to stick the string on the
8134 * stack and only adjust the stack pointer when it knows how big the
8135 * string is. Stackblock (defined in stack.h) returns a pointer to a block
8136 * of space on top of the stack and stackblocklen returns the length of
8137 * this block. Growstackblock will grow this space by at least one byte,
8138 * possibly moving it (like realloc). Grabstackblock actually allocates the
8139 * part of the block that has been used.
8143 growstackblock(void) {
8145 int newlen = ALIGN(stacknleft * 2 + 100);
8146 char *oldspace = stacknxt;
8147 int oldlen = stacknleft;
8148 struct stack_block *sp;
8149 struct stack_block *oldstackp;
8151 if (stacknxt == stackp->space && stackp != &stackbase) {
8156 sp = ckrealloc((pointer)sp, sizeof(struct stack_block) - MINSIZE + newlen);
8159 stacknxt = sp->space;
8160 stacknleft = newlen;
8162 /* Stack marks pointing to the start of the old block
8163 * must be relocated to point to the new block
8165 struct stackmark *xmark;
8167 while (xmark != NULL && xmark->stackp == oldstackp) {
8168 xmark->stackp = stackp;
8169 xmark->stacknxt = stacknxt;
8170 xmark->stacknleft = stacknleft;
8171 xmark = xmark->marknext;
8176 p = stalloc(newlen);
8177 memcpy(p, oldspace, oldlen);
8178 stacknxt = p; /* free the space */
8179 stacknleft += newlen; /* we just allocated */
8186 grabstackblock(int len)
8196 * The following routines are somewhat easier to use that the above.
8197 * The user declares a variable of type STACKSTR, which may be declared
8198 * to be a register. The macro STARTSTACKSTR initializes things. Then
8199 * the user uses the macro STPUTC to add characters to the string. In
8200 * effect, STPUTC(c, p) is the same as *p++ = c except that the stack is
8201 * grown as necessary. When the user is done, she can just leave the
8202 * string there and refer to it using stackblock(). Or she can allocate
8203 * the space for it using grabstackstr(). If it is necessary to allow
8204 * someone else to use the stack temporarily and then continue to grow
8205 * the string, the user should use grabstack to allocate the space, and
8206 * then call ungrabstr(p) to return to the previous mode of operation.
8208 * USTPUTC is like STPUTC except that it doesn't check for overflow.
8209 * CHECKSTACKSPACE can be called before USTPUTC to ensure that there
8210 * is space for at least one character.
8215 growstackstr(void) {
8216 int len = stackblocksize();
8217 if (herefd >= 0 && len >= 1024) {
8218 xwrite(herefd, stackblock(), len);
8219 sstrnleft = len - 1;
8220 return stackblock();
8223 sstrnleft = stackblocksize() - len - 1;
8224 return stackblock() + len;
8229 * Called from CHECKSTRSPACE.
8233 makestrspace(size_t newlen) {
8234 int len = stackblocksize() - sstrnleft;
8237 sstrnleft = stackblocksize() - len;
8238 } while (sstrnleft < newlen);
8239 return stackblock() + len;
8245 ungrabstackstr(char *s, char *p)
8247 stacknleft += stacknxt - s;
8249 sstrnleft = stacknleft - (p - s);
8252 * Miscelaneous builtins.
8259 static mode_t getmode(const void *, mode_t);
8260 static void *setmode(const char *);
8262 #if !defined(__GLIBC__) || __GLIBC__ == 2 && __GLIBC_MINOR__ < 1
8263 typedef enum __rlimit_resource rlim_t;
8270 * The read builtin. The -e option causes backslashes to escape the
8271 * following character.
8273 * This uses unbuffered input, which may be avoidable in some cases.
8294 while ((i = nextopt("p:r")) != '\0') {
8300 if (prompt && isatty(0)) {
8304 if (*(ap = argptr) == NULL)
8306 if ((ifs = bltinlookup("IFS")) == NULL)
8313 if (read(0, &c, 1) != 1) {
8325 if (!rflag && c == '\\') {
8331 if (startword && *ifs == ' ' && strchr(ifs, c)) {
8335 if (backslash && c == '\\') {
8336 if (read(0, &c, 1) != 1) {
8341 } else if (ap[1] != NULL && strchr(ifs, c) != NULL) {
8343 setvar(*ap, stackblock(), 0);
8352 /* Remove trailing blanks */
8353 while (stackblock() <= --p && strchr(ifs, *p) != NULL)
8355 setvar(*ap, stackblock(), 0);
8356 while (*++ap != NULL)
8357 setvar(*ap, nullstr, 0);
8364 umaskcmd(argc, argv)
8371 int symbolic_mode = 0;
8373 while ((i = nextopt("S")) != '\0') {
8382 if ((ap = *argptr) == NULL) {
8383 if (symbolic_mode) {
8384 char u[4], g[4], o[4];
8387 if ((mask & S_IRUSR) == 0)
8389 if ((mask & S_IWUSR) == 0)
8391 if ((mask & S_IXUSR) == 0)
8396 if ((mask & S_IRGRP) == 0)
8398 if ((mask & S_IWGRP) == 0)
8400 if ((mask & S_IXGRP) == 0)
8405 if ((mask & S_IROTH) == 0)
8407 if ((mask & S_IWOTH) == 0)
8409 if ((mask & S_IXOTH) == 0)
8413 out1fmt("u=%s,g=%s,o=%s\n", u, g, o);
8415 out1fmt("%.4o\n", mask);
8418 if (isdigit((unsigned char)*ap)) {
8421 if (*ap >= '8' || *ap < '0')
8422 error("Illegal number: %s", argv[1]);
8423 mask = (mask << 3) + (*ap - '0');
8424 } while (*++ap != '\0');
8430 if ((set = setmode(ap)) != 0) {
8431 mask = getmode(set, ~mask & 0777);
8436 error("Illegal mode: %s", ap);
8438 umask(~mask & 0777);
8447 * This code, originally by Doug Gwyn, Doug Kingston, Eric Gisin, and
8448 * Michael Rendell was ripped from pdksh 5.0.8 and hacked for use with
8449 * ash by J.T. Conklin.
8457 int factor; /* multiply by to get rlim_{cur,max} values */
8461 static const struct limits limits[] = {
8463 { "time(seconds)", RLIMIT_CPU, 1, 't' },
8466 { "file(blocks)", RLIMIT_FSIZE, 512, 'f' },
8469 { "data(kbytes)", RLIMIT_DATA, 1024, 'd' },
8472 { "stack(kbytes)", RLIMIT_STACK, 1024, 's' },
8475 { "coredump(blocks)", RLIMIT_CORE, 512, 'c' },
8478 { "memory(kbytes)", RLIMIT_RSS, 1024, 'm' },
8480 #ifdef RLIMIT_MEMLOCK
8481 { "locked memory(kbytes)", RLIMIT_MEMLOCK, 1024, 'l' },
8484 { "process(processes)", RLIMIT_NPROC, 1, 'p' },
8486 #ifdef RLIMIT_NOFILE
8487 { "nofiles(descriptors)", RLIMIT_NOFILE, 1, 'n' },
8490 { "vmemory(kbytes)", RLIMIT_VMEM, 1024, 'v' },
8493 { "swap(kbytes)", RLIMIT_SWAP, 1024, 'w' },
8495 { (char *) 0, 0, 0, '\0' }
8499 ulimitcmd(argc, argv)
8505 enum { SOFT = 0x1, HARD = 0x2 }
8507 const struct limits *l;
8510 struct rlimit limit;
8513 while ((optc = nextopt("HSatfdsmcnpl")) != '\0')
8528 for (l = limits; l->name && l->option != what; l++)
8531 error("internal error (%c)", what);
8533 set = *argptr ? 1 : 0;
8537 if (all || argptr[1])
8538 error("too many arguments");
8539 if (strcmp(p, "unlimited") == 0)
8540 val = RLIM_INFINITY;
8544 while ((c = *p++) >= '0' && c <= '9')
8546 val = (val * 10) + (long)(c - '0');
8547 if (val < (rlim_t) 0)
8551 error("bad number");
8556 for (l = limits; l->name; l++) {
8557 getrlimit(l->cmd, &limit);
8559 val = limit.rlim_cur;
8560 else if (how & HARD)
8561 val = limit.rlim_max;
8563 out1fmt("%-20s ", l->name);
8564 if (val == RLIM_INFINITY)
8565 out1fmt("unlimited\n");
8569 out1fmt("%lld\n", (long long) val);
8575 getrlimit(l->cmd, &limit);
8578 limit.rlim_max = val;
8580 limit.rlim_cur = val;
8581 if (setrlimit(l->cmd, &limit) < 0)
8582 error("error setting limit (%m)");
8585 val = limit.rlim_cur;
8586 else if (how & HARD)
8587 val = limit.rlim_max;
8589 if (val == RLIM_INFINITY)
8590 out1fmt("unlimited\n");
8594 out1fmt("%lld\n", (long long) val);
8600 * prefix -- see if pfx is a prefix of string.
8609 if (*pfx++ != *string++)
8616 * Return true if s is a string of digits, and save munber in intptr
8621 is_number(const char *p, int *intptr)
8629 ret += digit_val(*p);
8631 } while (*p != '\0');
8638 * Convert a string of digits to an integer, printing an error message on
8643 number(const char *s)
8646 if (! is_number(s, &i))
8647 error("Illegal number: %s", s);
8652 * Produce a possibly single quoted string suitable as input to the shell.
8653 * The return string is allocated on the stack.
8657 single_quote(const char *s) {
8664 size_t len1, len1p, len2, len2p;
8666 len1 = strcspn(s, "'");
8667 len2 = strspn(s + len1, "'");
8669 len1p = len1 ? len1 + 2 : len1;
8681 CHECKSTRSPACE(len1p + len2p + 1, p);
8686 q = mempcpy(p + 1, s, len1);
8689 memcpy(p + 1, s, len1);
8706 *(char *) mempcpy(q + 1, s, len2) = '"';
8709 memcpy(q + 1, s, len2);
8715 STADJUST(len1p + len2p, p);
8720 return grabstackstr(p);
8724 * Like strdup but works with the ash stack.
8728 sstrdup(const char *p)
8730 size_t len = strlen(p) + 1;
8731 return memcpy(stalloc(len), p, len);
8736 * This file was generated by the mknodes program.
8740 * Routine for dealing with parsed shell commands.
8744 static int funcblocksize; /* size of structures in function */
8745 static int funcstringsize; /* size of strings in node */
8746 static pointer funcblock; /* block to allocate function from */
8747 static char *funcstring; /* block to allocate strings from */
8749 static const short nodesize[26] = {
8750 ALIGN(sizeof (struct nbinary)),
8751 ALIGN(sizeof (struct ncmd)),
8752 ALIGN(sizeof (struct npipe)),
8753 ALIGN(sizeof (struct nredir)),
8754 ALIGN(sizeof (struct nredir)),
8755 ALIGN(sizeof (struct nredir)),
8756 ALIGN(sizeof (struct nbinary)),
8757 ALIGN(sizeof (struct nbinary)),
8758 ALIGN(sizeof (struct nif)),
8759 ALIGN(sizeof (struct nbinary)),
8760 ALIGN(sizeof (struct nbinary)),
8761 ALIGN(sizeof (struct nfor)),
8762 ALIGN(sizeof (struct ncase)),
8763 ALIGN(sizeof (struct nclist)),
8764 ALIGN(sizeof (struct narg)),
8765 ALIGN(sizeof (struct narg)),
8766 ALIGN(sizeof (struct nfile)),
8767 ALIGN(sizeof (struct nfile)),
8768 ALIGN(sizeof (struct nfile)),
8769 ALIGN(sizeof (struct nfile)),
8770 ALIGN(sizeof (struct nfile)),
8771 ALIGN(sizeof (struct ndup)),
8772 ALIGN(sizeof (struct ndup)),
8773 ALIGN(sizeof (struct nhere)),
8774 ALIGN(sizeof (struct nhere)),
8775 ALIGN(sizeof (struct nnot)),
8779 static void calcsize (union node *);
8780 static void sizenodelist (struct nodelist *);
8781 static union node *copynode (union node *);
8782 static struct nodelist *copynodelist (struct nodelist *);
8783 static char *nodesavestr (char *);
8788 * Make a copy of a parse tree.
8792 copyfunc(union node *n)
8799 funcblock = ckmalloc(funcblocksize + funcstringsize);
8800 funcstring = (char *) funcblock + funcblocksize;
8812 funcblocksize += nodesize[n->type];
8819 calcsize(n->nbinary.ch2);
8820 calcsize(n->nbinary.ch1);
8823 calcsize(n->ncmd.redirect);
8824 calcsize(n->ncmd.args);
8825 calcsize(n->ncmd.assign);
8828 sizenodelist(n->npipe.cmdlist);
8833 calcsize(n->nredir.redirect);
8834 calcsize(n->nredir.n);
8837 calcsize(n->nif.elsepart);
8838 calcsize(n->nif.ifpart);
8839 calcsize(n->nif.test);
8842 funcstringsize += strlen(n->nfor.var) + 1;
8843 calcsize(n->nfor.body);
8844 calcsize(n->nfor.args);
8847 calcsize(n->ncase.cases);
8848 calcsize(n->ncase.expr);
8851 calcsize(n->nclist.body);
8852 calcsize(n->nclist.pattern);
8853 calcsize(n->nclist.next);
8857 sizenodelist(n->narg.backquote);
8858 funcstringsize += strlen(n->narg.text) + 1;
8859 calcsize(n->narg.next);
8866 calcsize(n->nfile.fname);
8867 calcsize(n->nfile.next);
8871 calcsize(n->ndup.vname);
8872 calcsize(n->ndup.next);
8876 calcsize(n->nhere.doc);
8877 calcsize(n->nhere.next);
8880 calcsize(n->nnot.com);
8889 struct nodelist *lp;
8892 funcblocksize += ALIGN(sizeof(struct nodelist));
8909 funcblock = (char *) funcblock + nodesize[n->type];
8916 new->nbinary.ch2 = copynode(n->nbinary.ch2);
8917 new->nbinary.ch1 = copynode(n->nbinary.ch1);
8920 new->ncmd.redirect = copynode(n->ncmd.redirect);
8921 new->ncmd.args = copynode(n->ncmd.args);
8922 new->ncmd.assign = copynode(n->ncmd.assign);
8923 new->ncmd.backgnd = n->ncmd.backgnd;
8926 new->npipe.cmdlist = copynodelist(n->npipe.cmdlist);
8927 new->npipe.backgnd = n->npipe.backgnd;
8932 new->nredir.redirect = copynode(n->nredir.redirect);
8933 new->nredir.n = copynode(n->nredir.n);
8936 new->nif.elsepart = copynode(n->nif.elsepart);
8937 new->nif.ifpart = copynode(n->nif.ifpart);
8938 new->nif.test = copynode(n->nif.test);
8941 new->nfor.var = nodesavestr(n->nfor.var);
8942 new->nfor.body = copynode(n->nfor.body);
8943 new->nfor.args = copynode(n->nfor.args);
8946 new->ncase.cases = copynode(n->ncase.cases);
8947 new->ncase.expr = copynode(n->ncase.expr);
8950 new->nclist.body = copynode(n->nclist.body);
8951 new->nclist.pattern = copynode(n->nclist.pattern);
8952 new->nclist.next = copynode(n->nclist.next);
8956 new->narg.backquote = copynodelist(n->narg.backquote);
8957 new->narg.text = nodesavestr(n->narg.text);
8958 new->narg.next = copynode(n->narg.next);
8965 new->nfile.fname = copynode(n->nfile.fname);
8966 new->nfile.fd = n->nfile.fd;
8967 new->nfile.next = copynode(n->nfile.next);
8971 new->ndup.vname = copynode(n->ndup.vname);
8972 new->ndup.dupfd = n->ndup.dupfd;
8973 new->ndup.fd = n->ndup.fd;
8974 new->ndup.next = copynode(n->ndup.next);
8978 new->nhere.doc = copynode(n->nhere.doc);
8979 new->nhere.fd = n->nhere.fd;
8980 new->nhere.next = copynode(n->nhere.next);
8983 new->nnot.com = copynode(n->nnot.com);
8986 new->type = n->type;
8991 static struct nodelist *
8993 struct nodelist *lp;
8995 struct nodelist *start;
8996 struct nodelist **lpp;
9001 funcblock = (char *) funcblock + ALIGN(sizeof(struct nodelist));
9002 (*lpp)->n = copynode(lp->n);
9004 lpp = &(*lpp)->next;
9017 char *rtn = funcstring;
9019 funcstring = stpcpy(funcstring, s) + 1;
9022 register char *p = s;
9023 register char *q = funcstring;
9024 char *rtn = funcstring;
9026 while ((*q++ = *p++) != '\0')
9034 static int getopts (char *, char *, char **, int *, int *);
9039 * Process the shell command line arguments.
9043 procargs(argc, argv)
9052 for (i = 0; i < NOPTS; i++)
9055 if (*argptr == NULL && minusc == NULL)
9057 if (iflag == 2 && sflag == 1 && isatty(0) && isatty(1))
9061 for (i = 0; i < NOPTS; i++)
9062 if (optent_val(i) == 2)
9065 if (sflag == 0 && minusc == NULL) {
9066 commandname = argv[0];
9068 setinputfile(arg0, 0);
9071 /* POSIX 1003.2: first arg after -c cmd is $0, remainder $1... */
9072 if (argptr && minusc && *argptr)
9075 shellparam.p = argptr;
9076 shellparam.optind = 1;
9077 shellparam.optoff = -1;
9078 /* assert(shellparam.malloc == 0 && shellparam.nparam == 0); */
9080 shellparam.nparam++;
9089 * Process shell options. The global variable argptr contains a pointer
9090 * to the argument list; we advance it past the options.
9103 while ((p = *argptr) != NULL) {
9105 if ((c = *p++) == '-') {
9107 if (p[0] == '\0' || (p[0] == '-' && p[1] == '\0')) {
9109 /* "-" means turn off -x and -v */
9112 /* "--" means reset params */
9113 else if (*argptr == NULL)
9116 break; /* "-" or "--" terminates options */
9118 } else if (c == '+') {
9124 while ((c = *p++) != '\0') {
9125 if (c == 'c' && cmdline) {
9127 #ifdef NOHACK /* removing this code allows sh -ce 'foo' for compat */
9131 if (q == NULL || minusc != NULL)
9132 error("Bad -c option");
9137 } else if (c == 'o') {
9138 minus_o(*argptr, val);
9156 out1str("Current option settings\n");
9157 for (i = 0; i < NOPTS; i++)
9158 out1fmt("%-16s%s\n", optent_name(optlist[i]),
9159 optent_val(i) ? "on" : "off");
9161 for (i = 0; i < NOPTS; i++)
9162 if (equal(name, optent_name(optlist[i]))) {
9163 setoption(optent_letter(optlist[i]), val);
9166 error("Illegal option -o %s", name);
9172 setoption(int flag, int val)
9176 for (i = 0; i < NOPTS; i++)
9177 if (optent_letter(optlist[i]) == flag) {
9178 optent_val(i) = val;
9180 /* #%$ hack for ksh semantics */
9183 else if (flag == 'E')
9188 error("Illegal option -%c", flag);
9195 * Set the shell parameters.
9199 setparam(char **argv)
9205 for (nparam = 0 ; argv[nparam] ; nparam++);
9206 ap = newparam = ckmalloc((nparam + 1) * sizeof *ap);
9208 *ap++ = savestr(*argv++);
9211 freeparam(&shellparam);
9212 shellparam.malloc = 1;
9213 shellparam.nparam = nparam;
9214 shellparam.p = newparam;
9215 shellparam.optind = 1;
9216 shellparam.optoff = -1;
9221 * Free the list of positional parameters.
9225 freeparam(volatile struct shparam *param)
9229 if (param->malloc) {
9230 for (ap = param->p ; *ap ; ap++)
9239 * The shift builtin command.
9243 shiftcmd(argc, argv)
9252 n = number(argv[1]);
9253 if (n > shellparam.nparam)
9254 error("can't shift that many");
9256 shellparam.nparam -= n;
9257 for (ap1 = shellparam.p ; --n >= 0 ; ap1++) {
9258 if (shellparam.malloc)
9262 while ((*ap2++ = *ap1++) != NULL);
9263 shellparam.optind = 1;
9264 shellparam.optoff = -1;
9272 * The set command builtin.
9281 return showvarscmd(argc, argv);
9285 if (*argptr != NULL) {
9294 getoptsreset(const char *value)
9296 shellparam.optind = number(value);
9297 shellparam.optoff = -1;
9300 #ifdef BB_LOCALE_SUPPORT
9301 static void change_lc_all(const char *value)
9303 if(value != 0 && *value != 0)
9304 setlocale(LC_ALL, value);
9307 static void change_lc_ctype(const char *value)
9309 if(value != 0 && *value != 0)
9310 setlocale(LC_CTYPE, value);
9317 * The getopts builtin. Shellparam.optnext points to the next argument
9318 * to be processed. Shellparam.optptr points to the next character to
9319 * be processed in the current argument. If shellparam.optnext is NULL,
9320 * then it's the first time getopts has been called.
9324 getoptscmd(argc, argv)
9331 error("Usage: getopts optstring var [arg]");
9332 else if (argc == 3) {
9333 optbase = shellparam.p;
9334 if (shellparam.optind > shellparam.nparam + 1) {
9335 shellparam.optind = 1;
9336 shellparam.optoff = -1;
9341 if (shellparam.optind > argc - 2) {
9342 shellparam.optind = 1;
9343 shellparam.optoff = -1;
9347 return getopts(argv[1], argv[2], optbase, &shellparam.optind,
9348 &shellparam.optoff);
9352 * Safe version of setvar, returns 1 on success 0 on failure.
9356 setvarsafe(name, val, flags)
9357 const char *name, *val;
9360 struct jmploc jmploc;
9361 struct jmploc *volatile savehandler = handler;
9367 if (setjmp(jmploc.loc))
9371 setvar(name, val, flags);
9373 handler = savehandler;
9378 getopts(optstr, optvar, optfirst, myoptind, optoff)
9390 char **optnext = optfirst + *myoptind - 1;
9392 if (*myoptind <= 1 || *optoff < 0 || !(*(optnext - 1)) ||
9393 strlen(*(optnext - 1)) < *optoff)
9396 p = *(optnext - 1) + *optoff;
9397 if (p == NULL || *p == '\0') {
9398 /* Current word is done, advance */
9399 if (optnext == NULL)
9402 if (p == NULL || *p != '-' || *++p == '\0') {
9404 *myoptind = optnext - optfirst + 1;
9410 if (p[0] == '-' && p[1] == '\0') /* check for "--" */
9415 for (q = optstr; *q != c; ) {
9417 if (optstr[0] == ':') {
9420 err |= setvarsafe("OPTARG", s, 0);
9423 out2fmt("Illegal option -%c\n", c);
9424 (void) unsetvar("OPTARG");
9434 if (*p == '\0' && (p = *optnext) == NULL) {
9435 if (optstr[0] == ':') {
9438 err |= setvarsafe("OPTARG", s, 0);
9442 out2fmt("No arg for -%c option\n", c);
9443 (void) unsetvar("OPTARG");
9451 setvarsafe("OPTARG", p, 0);
9455 setvarsafe("OPTARG", "", 0);
9456 *myoptind = optnext - optfirst + 1;
9463 *optoff = p ? p - *(optnext - 1) : -1;
9464 snprintf(s, sizeof(s), "%d", *myoptind);
9465 err |= setvarsafe("OPTIND", s, VNOFUNC);
9468 err |= setvarsafe(optvar, s, 0);
9480 * XXX - should get rid of. have all builtins use getopt(3). the
9481 * library getopt must have the BSD extension static variable "optreset"
9482 * otherwise it can't be used within the shell safely.
9484 * Standard option processing (a la getopt) for builtin routines. The
9485 * only argument that is passed to nextopt is the option string; the
9486 * other arguments are unnecessary. It return the character, or '\0' on
9492 const char *optstring;
9498 if ((p = optptr) == NULL || *p == '\0') {
9500 if (p == NULL || *p != '-' || *++p == '\0')
9503 if (p[0] == '-' && p[1] == '\0') /* check for "--" */
9507 for (q = optstring ; *q != c ; ) {
9509 error("Illegal option -%c", c);
9514 if (*p == '\0' && (p = *argptr++) == NULL)
9515 error("No arg for -%c option", c);
9532 out2fmt(const char *fmt, ...)
9536 vfprintf(stderr, fmt, ap);
9542 out1fmt(const char *fmt, ...)
9546 vfprintf(stdout, fmt, ap);
9551 * Version of write which resumes after a signal is caught.
9555 xwrite(int fd, const char *buf, int nbytes)
9564 i = write(fd, buf, n);
9570 } else if (i == 0) {
9573 } else if (errno != EINTR) {
9581 * Shell command parser.
9584 #define EOFMARKLEN 79
9589 struct heredoc *next; /* next here document in list */
9590 union node *here; /* redirection node */
9591 char *eofmark; /* string indicating end of input */
9592 int striptabs; /* if set, strip leading tabs */
9595 static struct heredoc *heredoclist; /* list of here documents to read */
9596 static int parsebackquote; /* nonzero if we are inside backquotes */
9597 static int doprompt; /* if set, prompt the user */
9598 static int needprompt; /* true if interactive and at start of line */
9599 static int lasttoken; /* last token read */
9601 static char *wordtext; /* text of last word returned by readtoken */
9603 static struct nodelist *backquotelist;
9604 static union node *redirnode;
9605 struct heredoc *heredoc;
9606 static int quoteflag; /* set if (part of) last token was quoted */
9607 static int startlinno; /* line # where last token started */
9610 static union node *list (int);
9611 static union node *andor (void);
9612 static union node *pipeline (void);
9613 static union node *command (void);
9614 static union node *simplecmd (void);
9615 static void parsefname (void);
9616 static void parseheredoc (void);
9617 static int peektoken (void);
9618 static int readtoken (void);
9619 static int xxreadtoken (void);
9620 static int readtoken1 (int, char const *, char *, int);
9621 static int noexpand (char *);
9622 static void synexpect (int) __attribute__((noreturn));
9623 static void synerror (const char *) __attribute__((noreturn));
9624 static void setprompt (int);
9628 * Read and parse a command. Returns NEOF on end of file. (NULL is a
9629 * valid parse tree indicating a blank line.)
9633 parsecmd(int interact)
9638 doprompt = interact;
9658 union node *n1, *n2, *n3;
9662 if (nlflag == 0 && tokendlist[peektoken()])
9668 if (tok == TBACKGND) {
9669 if (n2->type == NCMD || n2->type == NPIPE) {
9670 n2->ncmd.backgnd = 1;
9671 } else if (n2->type == NREDIR) {
9672 n2->type = NBACKGND;
9674 n3 = (union node *)stalloc(sizeof (struct nredir));
9675 n3->type = NBACKGND;
9677 n3->nredir.redirect = NULL;
9685 n3 = (union node *)stalloc(sizeof (struct nbinary));
9687 n3->nbinary.ch1 = n1;
9688 n3->nbinary.ch2 = n2;
9705 if (tokendlist[peektoken()])
9712 pungetc(); /* push back EOF on input */
9727 union node *n1, *n2, *n3;
9733 if ((t = readtoken()) == TAND) {
9735 } else if (t == TOR) {
9743 n3 = (union node *)stalloc(sizeof (struct nbinary));
9745 n3->nbinary.ch1 = n1;
9746 n3->nbinary.ch2 = n2;
9755 union node *n1, *n2, *pipenode;
9756 struct nodelist *lp, *prev;
9760 TRACE(("pipeline: entered\n"));
9761 if (readtoken() == TNOT) {
9767 if (readtoken() == TPIPE) {
9768 pipenode = (union node *)stalloc(sizeof (struct npipe));
9769 pipenode->type = NPIPE;
9770 pipenode->npipe.backgnd = 0;
9771 lp = (struct nodelist *)stalloc(sizeof (struct nodelist));
9772 pipenode->npipe.cmdlist = lp;
9776 lp = (struct nodelist *)stalloc(sizeof (struct nodelist));
9780 } while (readtoken() == TPIPE);
9786 n2 = (union node *)stalloc(sizeof (struct nnot));
9798 union node *n1, *n2;
9799 union node *ap, **app;
9800 union node *cp, **cpp;
9801 union node *redir, **rpp;
9808 switch (readtoken()) {
9810 n1 = (union node *)stalloc(sizeof (struct nif));
9812 n1->nif.test = list(0);
9813 if (readtoken() != TTHEN)
9815 n1->nif.ifpart = list(0);
9817 while (readtoken() == TELIF) {
9818 n2->nif.elsepart = (union node *)stalloc(sizeof (struct nif));
9819 n2 = n2->nif.elsepart;
9821 n2->nif.test = list(0);
9822 if (readtoken() != TTHEN)
9824 n2->nif.ifpart = list(0);
9826 if (lasttoken == TELSE)
9827 n2->nif.elsepart = list(0);
9829 n2->nif.elsepart = NULL;
9832 if (readtoken() != TFI)
9839 n1 = (union node *)stalloc(sizeof (struct nbinary));
9840 n1->type = (lasttoken == TWHILE)? NWHILE : NUNTIL;
9841 n1->nbinary.ch1 = list(0);
9842 if ((got=readtoken()) != TDO) {
9843 TRACE(("expecting DO got %s %s\n", tokname[got], got == TWORD ? wordtext : ""));
9846 n1->nbinary.ch2 = list(0);
9847 if (readtoken() != TDONE)
9853 if (readtoken() != TWORD || quoteflag || ! goodname(wordtext))
9854 synerror("Bad for loop variable");
9855 n1 = (union node *)stalloc(sizeof (struct nfor));
9857 n1->nfor.var = wordtext;
9859 if (readtoken() == TIN) {
9861 while (readtoken() == TWORD) {
9862 n2 = (union node *)stalloc(sizeof (struct narg));
9864 n2->narg.text = wordtext;
9865 n2->narg.backquote = backquotelist;
9867 app = &n2->narg.next;
9871 if (lasttoken != TNL && lasttoken != TSEMI)
9874 static char argvars[5] = {CTLVAR, VSNORMAL|VSQUOTE,
9876 n2 = (union node *)stalloc(sizeof (struct narg));
9878 n2->narg.text = argvars;
9879 n2->narg.backquote = NULL;
9880 n2->narg.next = NULL;
9883 * Newline or semicolon here is optional (but note
9884 * that the original Bourne shell only allowed NL).
9886 if (lasttoken != TNL && lasttoken != TSEMI)
9890 if (readtoken() != TDO)
9892 n1->nfor.body = list(0);
9893 if (readtoken() != TDONE)
9898 n1 = (union node *)stalloc(sizeof (struct ncase));
9900 if (readtoken() != TWORD)
9902 n1->ncase.expr = n2 = (union node *)stalloc(sizeof (struct narg));
9904 n2->narg.text = wordtext;
9905 n2->narg.backquote = backquotelist;
9906 n2->narg.next = NULL;
9909 } while (readtoken() == TNL);
9910 if (lasttoken != TIN)
9911 synerror("expecting \"in\"");
9912 cpp = &n1->ncase.cases;
9913 checkkwd = 2, readtoken();
9915 if (lasttoken == TLP)
9917 *cpp = cp = (union node *)stalloc(sizeof (struct nclist));
9919 app = &cp->nclist.pattern;
9921 *app = ap = (union node *)stalloc(sizeof (struct narg));
9923 ap->narg.text = wordtext;
9924 ap->narg.backquote = backquotelist;
9925 if (checkkwd = 2, readtoken() != TPIPE)
9927 app = &ap->narg.next;
9930 ap->narg.next = NULL;
9931 if (lasttoken != TRP)
9933 cp->nclist.body = list(0);
9936 if ((t = readtoken()) != TESAC) {
9938 synexpect(TENDCASE);
9940 checkkwd = 2, readtoken();
9942 cpp = &cp->nclist.next;
9943 } while(lasttoken != TESAC);
9948 n1 = (union node *)stalloc(sizeof (struct nredir));
9949 n1->type = NSUBSHELL;
9950 n1->nredir.n = list(0);
9951 n1->nredir.redirect = NULL;
9952 if (readtoken() != TRP)
9958 if (readtoken() != TEND)
9962 /* Handle an empty command like other simple commands. */
9971 * An empty command before a ; doesn't make much sense, and
9972 * should certainly be disallowed in the case of `if ;'.
9986 /* Now check for redirection which may follow command */
9987 while (readtoken() == TREDIR) {
9988 *rpp = n2 = redirnode;
9989 rpp = &n2->nfile.next;
9995 if (n1->type != NSUBSHELL) {
9996 n2 = (union node *)stalloc(sizeof (struct nredir));
10001 n1->nredir.redirect = redir;
10008 static union node *
10010 union node *args, **app;
10011 union node *n = NULL;
10012 union node *vars, **vpp;
10013 union node **rpp, *redir;
10026 switch (readtoken()) {
10029 n = (union node *)stalloc(sizeof (struct narg));
10031 n->narg.text = wordtext;
10032 n->narg.backquote = backquotelist;
10033 if (lasttoken == TWORD) {
10035 app = &n->narg.next;
10038 vpp = &n->narg.next;
10042 *rpp = n = redirnode;
10043 rpp = &n->nfile.next;
10044 parsefname(); /* read name of redirection file */
10048 args && app == &args->narg.next &&
10051 /* We have a function */
10052 if (readtoken() != TRP)
10056 n->narg.next = command();
10069 n = (union node *)stalloc(sizeof (struct ncmd));
10071 n->ncmd.backgnd = 0;
10072 n->ncmd.args = args;
10073 n->ncmd.assign = vars;
10074 n->ncmd.redirect = redir;
10078 static union node *
10082 n = (union node *)stalloc(sizeof (struct narg));
10084 n->narg.next = NULL;
10085 n->narg.text = wordtext;
10086 n->narg.backquote = backquotelist;
10090 static void fixredir(union node *n, const char *text, int err)
10092 TRACE(("Fix redir %s %d\n", text, err));
10094 n->ndup.vname = NULL;
10096 if (is_digit(text[0]) && text[1] == '\0')
10097 n->ndup.dupfd = digit_val(text[0]);
10098 else if (text[0] == '-' && text[1] == '\0')
10099 n->ndup.dupfd = -1;
10103 synerror("Bad fd number");
10105 n->ndup.vname = makename();
10112 union node *n = redirnode;
10114 if (readtoken() != TWORD)
10116 if (n->type == NHERE) {
10117 struct heredoc *here = heredoc;
10121 if (quoteflag == 0)
10123 TRACE(("Here document %d\n", n->type));
10124 if (here->striptabs) {
10125 while (*wordtext == '\t')
10128 if (! noexpand(wordtext) || (i = strlen(wordtext)) == 0 || i > EOFMARKLEN)
10129 synerror("Illegal eof marker for << redirection");
10130 rmescapes(wordtext);
10131 here->eofmark = wordtext;
10133 if (heredoclist == NULL)
10134 heredoclist = here;
10136 for (p = heredoclist ; p->next ; p = p->next);
10139 } else if (n->type == NTOFD || n->type == NFROMFD) {
10140 fixredir(n, wordtext, 0);
10142 n->nfile.fname = makename();
10148 * Input any here documents.
10153 struct heredoc *here;
10156 while (heredoclist) {
10157 here = heredoclist;
10158 heredoclist = here->next;
10163 readtoken1(pgetc(), here->here->type == NHERE? SQSYNTAX : DQSYNTAX,
10164 here->eofmark, here->striptabs);
10165 n = (union node *)stalloc(sizeof (struct narg));
10166 n->narg.type = NARG;
10167 n->narg.next = NULL;
10168 n->narg.text = wordtext;
10169 n->narg.backquote = backquotelist;
10170 here->here->nhere.doc = n;
10187 int savecheckkwd = checkkwd;
10188 int savecheckalias = checkalias;
10193 int alreadyseen = tokpushback;
10203 checkalias = savecheckalias;
10210 if (checkkwd == 2) {
10219 * check for keywords
10221 if (t == TWORD && !quoteflag)
10223 const char *const *pp;
10225 if ((pp = findkwd(wordtext))) {
10226 lasttoken = t = pp - parsekwd + KWDOFFSET;
10227 TRACE(("keyword %s recognized\n", tokname[t]));
10238 } else if (checkalias == 2 && isassignment(wordtext)) {
10239 lasttoken = t = TASSIGN;
10240 } else if (checkalias) {
10241 if (!quoteflag && (ap = lookupalias(wordtext, 1)) != NULL) {
10243 pushstring(ap->val, strlen(ap->val), ap);
10245 checkkwd = savecheckkwd;
10254 TRACE(("token %s %s\n", tokname[t], t == TWORD || t == TASSIGN ? wordtext : ""));
10256 TRACE(("reread token %s %s\n", tokname[t], t == TWORD || t == TASSIGN ? wordtext : ""));
10263 * Read the next input token.
10264 * If the token is a word, we set backquotelist to the list of cmds in
10265 * backquotes. We set quoteflag to true if any part of the word was
10267 * If the token is TREDIR, then we set redirnode to a structure containing
10269 * In all cases, the variable startlinno is set to the number of the line
10270 * on which the token starts.
10272 * [Change comment: here documents and internal procedures]
10273 * [Readtoken shouldn't have any arguments. Perhaps we should make the
10274 * word parsing code into a separate routine. In this case, readtoken
10275 * doesn't need to have any internal procedures, but parseword does.
10276 * We could also make parseoperator in essence the main routine, and
10277 * have parseword (readtoken1?) handle both words and redirection.]
10280 #define RETURN(token) return lasttoken = token
10294 startlinno = plinno;
10295 for (;;) { /* until token or start of word found */
10298 case ' ': case '\t':
10304 while ((c = pgetc()) != '\n' && c != PEOF);
10308 if (pgetc() == '\n') {
10309 startlinno = ++plinno;
10320 needprompt = doprompt;
10325 if (pgetc() == '&')
10330 if (pgetc() == '|')
10335 if (pgetc() == ';')
10348 return readtoken1(c, BASESYNTAX, (char *)NULL, 0);
10355 * If eofmark is NULL, read a word or a redirection symbol. If eofmark
10356 * is not NULL, read a here document. In the latter case, eofmark is the
10357 * word which marks the end of the document and striptabs is true if
10358 * leading tabs should be stripped from the document. The argument firstc
10359 * is the first character of the input token or document.
10361 * Because C does not have internal subroutines, I have simulated them
10362 * using goto's to implement the subroutine linkage. The following macros
10363 * will run code that appears at the end of readtoken1.
10366 #define CHECKEND() {goto checkend; checkend_return:;}
10367 #define PARSEREDIR() {goto parseredir; parseredir_return:;}
10368 #define PARSESUB() {goto parsesub; parsesub_return:;}
10369 #define PARSEBACKQOLD() {oldstyle = 1; goto parsebackq; parsebackq_oldreturn:;}
10370 #define PARSEBACKQNEW() {oldstyle = 0; goto parsebackq; parsebackq_newreturn:;}
10371 #define PARSEARITH() {goto parsearith; parsearith_return:;}
10374 readtoken1(firstc, syntax, eofmark, striptabs)
10376 char const *syntax;
10383 char line[EOFMARKLEN + 1];
10384 struct nodelist *bqlist;
10387 int varnest; /* levels of variables expansion */
10388 int arinest; /* levels of arithmetic expansion */
10389 int parenlevel; /* levels of parens in arithmetic */
10390 int dqvarnest; /* levels of variables expansion within double quotes */
10392 char const *prevsyntax; /* syntax before arithmetic */
10394 /* Avoid longjmp clobbering */
10400 (void) &parenlevel;
10403 (void) &prevsyntax;
10407 startlinno = plinno;
10409 if (syntax == DQSYNTAX)
10418 STARTSTACKSTR(out);
10419 loop: { /* for each line, until end of word */
10420 CHECKEND(); /* set c to PEOF if at end of here document */
10421 for (;;) { /* until end of line or end of word */
10422 CHECKSTRSPACE(3, out); /* permit 3 calls to USTPUTC */
10423 switch(syntax[c]) {
10424 case CNL: /* '\n' */
10425 if (syntax == BASESYNTAX)
10426 goto endword; /* exit outer loop */
10434 goto loop; /* continue outer loop */
10439 if ((eofmark == NULL || dblquote) &&
10441 USTPUTC(CTLESC, out);
10444 case CBACK: /* backslash */
10447 USTPUTC('\\', out);
10449 } else if (c == '\n') {
10455 if (dblquote && c != '\\' && c != '`' && c != '$'
10456 && (c != '"' || eofmark != NULL))
10457 USTPUTC('\\', out);
10458 if (SQSYNTAX[c] == CCTL)
10459 USTPUTC(CTLESC, out);
10460 else if (eofmark == NULL)
10461 USTPUTC(CTLQUOTEMARK, out);
10467 if (eofmark == NULL)
10468 USTPUTC(CTLQUOTEMARK, out);
10472 if (eofmark == NULL)
10473 USTPUTC(CTLQUOTEMARK, out);
10478 if (eofmark != NULL && arinest == 0 &&
10483 syntax = ARISYNTAX;
10485 } else if (eofmark == NULL &&
10487 syntax = BASESYNTAX;
10493 case CVAR: /* '$' */
10494 PARSESUB(); /* parse substitution */
10496 case CENDVAR: /* '}' */
10499 if (dqvarnest > 0) {
10502 USTPUTC(CTLENDVAR, out);
10507 #ifdef ASH_MATH_SUPPORT
10508 case CLP: /* '(' in arithmetic */
10512 case CRP: /* ')' in arithmetic */
10513 if (parenlevel > 0) {
10517 if (pgetc() == ')') {
10518 if (--arinest == 0) {
10519 USTPUTC(CTLENDARI, out);
10520 syntax = prevsyntax;
10521 if (syntax == DQSYNTAX)
10529 * unbalanced parens
10530 * (don't 2nd guess - no error)
10538 case CBQUOTE: /* '`' */
10542 goto endword; /* exit outer loop */
10547 goto endword; /* exit outer loop */
10558 if (syntax == ARISYNTAX)
10559 synerror("Missing '))'");
10560 if (syntax != BASESYNTAX && ! parsebackquote && eofmark == NULL)
10561 synerror("Unterminated quoted string");
10562 if (varnest != 0) {
10563 startlinno = plinno;
10564 synerror("Missing '}'");
10566 USTPUTC('\0', out);
10567 len = out - stackblock();
10568 out = stackblock();
10569 if (eofmark == NULL) {
10570 if ((c == '>' || c == '<')
10573 && (*out == '\0' || is_digit(*out))) {
10575 return lasttoken = TREDIR;
10580 quoteflag = quotef;
10581 backquotelist = bqlist;
10582 grabstackblock(len);
10584 return lasttoken = TWORD;
10585 /* end of readtoken routine */
10590 * Check to see whether we are at the end of the here document. When this
10591 * is called, c is set to the first character of the next input line. If
10592 * we are at the end of the here document, this routine sets the c to PEOF.
10603 while (c == '\t') {
10607 if (c == *eofmark) {
10608 if (pfgets(line, sizeof line) != NULL) {
10612 for (q = eofmark + 1 ; *q && *p == *q ; p++, q++);
10613 if (*p == '\n' && *q == '\0') {
10616 needprompt = doprompt;
10618 pushstring(line, strlen(line), NULL);
10623 goto checkend_return;
10628 * Parse a redirection operator. The variable "out" points to a string
10629 * specifying the fd to be redirected. The variable "c" contains the
10630 * first character of the redirection operator.
10637 np = (union node *)stalloc(sizeof (struct nfile));
10642 np->type = NAPPEND;
10651 } else { /* c == '<' */
10653 switch (c = pgetc()) {
10655 if (sizeof (struct nfile) != sizeof (struct nhere)) {
10656 np = (union node *)stalloc(sizeof (struct nhere));
10660 heredoc = (struct heredoc *)stalloc(sizeof (struct heredoc));
10661 heredoc->here = np;
10662 if ((c = pgetc()) == '-') {
10663 heredoc->striptabs = 1;
10665 heredoc->striptabs = 0;
10671 np->type = NFROMFD;
10675 np->type = NFROMTO;
10685 np->nfile.fd = digit_val(fd);
10687 goto parseredir_return;
10692 * Parse a substitution. At this point, we have read the dollar sign
10693 * and nothing else.
10701 static const char types[] = "}-+?=";
10706 (c != '(' && c != '{' && !is_name(c) && !is_special(c))
10710 } else if (c == '(') { /* $(command) or $((arith)) */
10711 if (pgetc() == '(') {
10718 USTPUTC(CTLVAR, out);
10719 typeloc = out - stackblock();
10720 USTPUTC(VSNORMAL, out);
10721 subtype = VSNORMAL;
10725 if ((c = pgetc()) == '}')
10728 subtype = VSLENGTH;
10733 if (c > PEOA && is_name(c)) {
10737 } while (c > PEOA && is_in_name(c));
10738 } else if (is_digit(c)) {
10742 } while (is_digit(c));
10744 else if (is_special(c)) {
10749 badsub: synerror("Bad substitution");
10753 if (subtype == 0) {
10760 p = strchr(types, c);
10763 subtype = p - types + VSNORMAL;
10769 subtype = c == '#' ? VSTRIMLEFT :
10782 if (dblquote || arinest)
10784 *(stackblock() + typeloc) = subtype | flags;
10785 if (subtype != VSNORMAL) {
10792 goto parsesub_return;
10797 * Called to parse command substitutions. Newstyle is set if the command
10798 * is enclosed inside $(...); nlpp is a pointer to the head of the linked
10799 * list of commands (passed by reference), and savelen is the number of
10800 * characters on the top of the stack which must be preserved.
10804 struct nodelist **nlpp;
10807 char *volatile str;
10808 struct jmploc jmploc;
10809 struct jmploc *volatile savehandler;
10813 (void) &saveprompt;
10816 savepbq = parsebackquote;
10817 if (setjmp(jmploc.loc)) {
10820 parsebackquote = 0;
10821 handler = savehandler;
10822 longjmp(handler->loc, 1);
10826 savelen = out - stackblock();
10828 str = ckmalloc(savelen);
10829 memcpy(str, stackblock(), savelen);
10831 savehandler = handler;
10835 /* We must read until the closing backquote, giving special
10836 treatment to some slashes, and then push the string and
10837 reread it as input, interpreting it normally. */
10844 STARTSTACKSTR(pout);
10850 switch (pc = pgetc()) {
10855 if ((pc = pgetc()) == '\n') {
10862 * If eating a newline, avoid putting
10863 * the newline into the new character
10864 * stream (via the STPUTC after the
10869 if (pc != '\\' && pc != '`' && pc != '$'
10870 && (!dblquote || pc != '"'))
10871 STPUTC('\\', pout);
10881 startlinno = plinno;
10882 synerror("EOF in backquote substitution");
10886 needprompt = doprompt;
10895 STPUTC('\0', pout);
10896 psavelen = pout - stackblock();
10897 if (psavelen > 0) {
10898 pstr = grabstackstr(pout);
10899 setinputstring(pstr);
10904 nlpp = &(*nlpp)->next;
10905 *nlpp = (struct nodelist *)stalloc(sizeof (struct nodelist));
10906 (*nlpp)->next = NULL;
10907 parsebackquote = oldstyle;
10910 saveprompt = doprompt;
10917 doprompt = saveprompt;
10919 if (readtoken() != TRP)
10926 * Start reading from old file again, ignoring any pushed back
10927 * tokens left from the backquote parsing
10932 while (stackblocksize() <= savelen)
10934 STARTSTACKSTR(out);
10936 memcpy(out, str, savelen);
10937 STADJUST(savelen, out);
10943 parsebackquote = savepbq;
10944 handler = savehandler;
10945 if (arinest || dblquote)
10946 USTPUTC(CTLBACKQ | CTLQUOTE, out);
10948 USTPUTC(CTLBACKQ, out);
10950 goto parsebackq_oldreturn;
10952 goto parsebackq_newreturn;
10956 * Parse an arithmetic expansion (indicate start of one and set state)
10960 if (++arinest == 1) {
10961 prevsyntax = syntax;
10962 syntax = ARISYNTAX;
10963 USTPUTC(CTLARI, out);
10970 * we collapse embedded arithmetic expansion to
10971 * parenthesis, which should be equivalent
10975 goto parsearith_return;
10978 } /* end of readtoken */
10982 * Returns true if the text contains nothing to expand (no dollar signs
10994 while ((c = *p++) != '\0') {
10995 if (c == CTLQUOTEMARK)
10999 else if (BASESYNTAX[(int)c] == CCTL)
11007 * Return true if the argument is a legal variable name (a letter or
11008 * underscore followed by zero or more letters, underscores, and digits).
11012 goodname(const char *name)
11020 if (! is_in_name(*p))
11028 * Called when an unexpected token is read during the parse. The argument
11029 * is the token that is expected, or -1 if more than one type of token can
11030 * occur at this point.
11040 snprintf(msg, 64, "%s unexpected (expecting %s)",
11041 tokname[lasttoken], tokname[token]);
11043 snprintf(msg, 64, "%s unexpected", tokname[lasttoken]);
11051 synerror(const char *msg)
11054 out2fmt("%s: %d: ", commandname, startlinno);
11055 out2fmt("Syntax error: %s\n", msg);
11056 error((char *)NULL);
11062 * called by editline -- any expansions to the prompt
11063 * should be added here.
11065 static inline const char *
11066 getprompt(void *unused)
11068 switch (whichprompt) {
11076 return "<internal prompt error>";
11081 setprompt(int which)
11083 whichprompt = which;
11084 putprompt(getprompt(NULL));
11089 * Code for dealing with input/output redirection.
11092 #define EMPTY -2 /* marks an unused slot in redirtab */
11094 # define PIPESIZE 4096 /* amount of buffering in a pipe */
11096 # define PIPESIZE PIPE_BUF
11102 * Process a list of redirection commands. If the REDIR_PUSH flag is set,
11103 * old file descriptors are stashed away so that the redirection can be
11104 * undone by calling popredir. If the REDIR_BACKQ flag is set, then the
11105 * standard output, and the standard error if it becomes a duplicate of
11110 redirect(redir, flags)
11115 struct redirtab *sv = NULL;
11120 char memory[10]; /* file descriptors to write to memory */
11122 for (i = 10 ; --i >= 0 ; )
11124 memory[1] = flags & REDIR_BACKQ;
11125 if (flags & REDIR_PUSH) {
11126 sv = ckmalloc(sizeof (struct redirtab));
11127 for (i = 0 ; i < 10 ; i++)
11128 sv->renamed[i] = EMPTY;
11129 sv->next = redirlist;
11132 for (n = redir ; n ; n = n->nfile.next) {
11135 if ((n->nfile.type == NTOFD || n->nfile.type == NFROMFD) &&
11136 n->ndup.dupfd == fd)
11137 continue; /* redirect from/to same file descriptor */
11140 newfd = openredirect(n);
11141 if ((flags & REDIR_PUSH) && sv->renamed[fd] == EMPTY) {
11144 } else if ((i = fcntl(fd, F_DUPFD, 10)) == -1) {
11148 dupredirect(n, newfd, memory);
11158 error("%d: %m", fd);
11164 if (flags & REDIR_PUSH) {
11165 sv->renamed[fd] = i;
11168 } else if (fd != newfd) {
11174 dupredirect(n, newfd, memory);
11181 openredirect(redir)
11187 switch (redir->nfile.type) {
11189 fname = redir->nfile.expfname;
11190 if ((f = open(fname, O_RDONLY)) < 0)
11194 fname = redir->nfile.expfname;
11195 if ((f = open(fname, O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0)
11199 /* Take care of noclobber mode. */
11201 fname = redir->nfile.expfname;
11202 if ((f = noclobberopen(fname)) < 0)
11207 fname = redir->nfile.expfname;
11209 if ((f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
11212 if ((f = creat(fname, 0666)) < 0)
11217 fname = redir->nfile.expfname;
11219 if ((f = open(fname, O_WRONLY|O_CREAT|O_APPEND, 0666)) < 0)
11222 if ((f = open(fname, O_WRONLY)) < 0
11223 && (f = creat(fname, 0666)) < 0)
11225 lseek(f, (off_t)0, 2);
11232 /* Fall through to eliminate warning. */
11239 f = openhere(redir);
11245 error("cannot create %s: %s", fname, errmsg(errno, E_CREAT));
11247 error("cannot open %s: %s", fname, errmsg(errno, E_OPEN));
11252 dupredirect(union node *redir, int f, char memory[10])
11254 int fd = redir->nfile.fd;
11257 if (redir->nfile.type == NTOFD || redir->nfile.type == NFROMFD) {
11258 if (redir->ndup.dupfd >= 0) { /* if not ">&-" */
11259 if (memory[redir->ndup.dupfd])
11262 dup_as_newfd(redir->ndup.dupfd, fd);
11268 dup_as_newfd(f, fd);
11276 * Handle here documents. Normally we fork off a process to write the
11277 * data to a pipe. If the document is short, we can stuff the data in
11278 * the pipe without forking.
11289 error("Pipe call failed");
11290 if (redir->type == NHERE) {
11291 len = strlen(redir->nhere.doc->narg.text);
11292 if (len <= PIPESIZE) {
11293 xwrite(pip[1], redir->nhere.doc->narg.text, len);
11297 if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) {
11299 signal(SIGINT, SIG_IGN);
11300 signal(SIGQUIT, SIG_IGN);
11301 signal(SIGHUP, SIG_IGN);
11303 signal(SIGTSTP, SIG_IGN);
11305 signal(SIGPIPE, SIG_DFL);
11306 if (redir->type == NHERE)
11307 xwrite(pip[1], redir->nhere.doc->narg.text, len);
11309 expandhere(redir->nhere.doc, pip[1]);
11319 * Undo the effects of the last redirection.
11325 struct redirtab *rp = redirlist;
11329 for (i = 0 ; i < 10 ; i++) {
11330 if (rp->renamed[i] != EMPTY) {
11334 if (rp->renamed[i] >= 0) {
11335 dup_as_newfd(rp->renamed[i], i);
11336 close(rp->renamed[i]);
11340 redirlist = rp->next;
11346 * Discard all saved file descriptors.
11351 struct redirtab *rp;
11354 for (rp = redirlist ; rp ; rp = rp->next) {
11355 for (i = 0 ; i < 10 ; i++) {
11356 if (rp->renamed[i] >= 0) {
11357 close(rp->renamed[i]);
11359 rp->renamed[i] = EMPTY;
11366 * Copy a file descriptor to be >= to. Returns -1
11367 * if the source file descriptor is closed, EMPTY if there are no unused
11368 * file descriptors left.
11372 dup_as_newfd(from, to)
11378 newfd = fcntl(from, F_DUPFD, to);
11380 if (errno == EMFILE)
11383 error("%d: %m", from);
11389 * Open a file in noclobber mode.
11390 * The code was copied from bash.
11393 noclobberopen(const char *fname)
11396 struct stat finfo, finfo2;
11399 * If the file exists and is a regular file, return an error
11402 r = stat(fname, &finfo);
11403 if (r == 0 && S_ISREG(finfo.st_mode)) {
11409 * If the file was not present (r != 0), make sure we open it
11410 * exclusively so that if it is created before we open it, our open
11411 * will fail. Make sure that we do not truncate an existing file.
11412 * Note that we don't turn on O_EXCL unless the stat failed -- if the
11413 * file was not a regular file, we leave O_EXCL off.
11416 return open(fname, O_WRONLY|O_CREAT|O_EXCL, 0666);
11417 fd = open(fname, O_WRONLY|O_CREAT, 0666);
11419 /* If the open failed, return the file descriptor right away. */
11424 * OK, the open succeeded, but the file may have been changed from a
11425 * non-regular file to a regular file between the stat and the open.
11426 * We are assuming that the O_EXCL open handles the case where FILENAME
11427 * did not exist and is symlinked to an existing file between the stat
11432 * If we can open it and fstat the file descriptor, and neither check
11433 * revealed that it was a regular file, and the file has not been
11434 * replaced, return the file descriptor.
11436 if (fstat(fd, &finfo2) == 0 && !S_ISREG(finfo2.st_mode) &&
11437 finfo.st_dev == finfo2.st_dev && finfo.st_ino == finfo2.st_ino)
11440 /* The file has been replaced. badness. */
11445 /*#ifdef __weak_alias
11446 __weak_alias(getmode,_getmode)
11447 __weak_alias(setmode,_setmode)
11451 #define S_ISTXT __S_ISVTX
11454 #define SET_LEN 6 /* initial # of bitcmd struct to malloc */
11455 #define SET_LEN_INCR 4 /* # of bitcmd structs to add as needed */
11457 typedef struct bitcmd {
11463 #define CMD2_CLR 0x01
11464 #define CMD2_SET 0x02
11465 #define CMD2_GBITS 0x04
11466 #define CMD2_OBITS 0x08
11467 #define CMD2_UBITS 0x10
11469 static BITCMD *addcmd (BITCMD *, int, int, int, u_int);
11470 static void compress_mode (BITCMD *);
11471 #ifdef SETMODE_DEBUG
11472 static void dumpmode (BITCMD *);
11476 * Given the old mode and an array of bitcmd structures, apply the operations
11477 * described in the bitcmd structures to the old mode, and return the new mode.
11478 * Note that there is no '=' command; a strict assignment is just a '-' (clear
11479 * bits) followed by a '+' (set bits).
11482 getmode(bbox, omode)
11487 mode_t clrval, newmode, value;
11489 _DIAGASSERT(bbox != NULL);
11491 set = (const BITCMD *)bbox;
11493 for (value = 0;; set++)
11496 * When copying the user, group or other bits around, we "know"
11497 * where the bits are in the mode so that we can do shifts to
11498 * copy them around. If we don't use shifts, it gets real
11499 * grundgy with lots of single bit checks and bit sets.
11502 value = (newmode & S_IRWXU) >> 6;
11506 value = (newmode & S_IRWXG) >> 3;
11510 value = newmode & S_IRWXO;
11511 common: if (set->cmd2 & CMD2_CLR) {
11513 (set->cmd2 & CMD2_SET) ? S_IRWXO : value;
11514 if (set->cmd2 & CMD2_UBITS)
11515 newmode &= ~((clrval<<6) & set->bits);
11516 if (set->cmd2 & CMD2_GBITS)
11517 newmode &= ~((clrval<<3) & set->bits);
11518 if (set->cmd2 & CMD2_OBITS)
11519 newmode &= ~(clrval & set->bits);
11521 if (set->cmd2 & CMD2_SET) {
11522 if (set->cmd2 & CMD2_UBITS)
11523 newmode |= (value<<6) & set->bits;
11524 if (set->cmd2 & CMD2_GBITS)
11525 newmode |= (value<<3) & set->bits;
11526 if (set->cmd2 & CMD2_OBITS)
11527 newmode |= value & set->bits;
11532 newmode |= set->bits;
11536 newmode &= ~set->bits;
11540 if (omode & (S_IFDIR|S_IXUSR|S_IXGRP|S_IXOTH))
11541 newmode |= set->bits;
11546 #ifdef SETMODE_DEBUG
11547 (void)printf("getmode:%04o -> %04o\n", omode, newmode);
11553 #define ADDCMD(a, b, c, d) do { \
11554 if (set >= endset) { \
11556 setlen += SET_LEN_INCR; \
11557 newset = realloc(saveset, sizeof(BITCMD) * setlen); \
11558 if (newset == NULL) { \
11562 set = newset + (set - saveset); \
11563 saveset = newset; \
11564 endset = newset + (setlen - 2); \
11566 set = addcmd(set, (a), (b), (c), (d)); \
11567 } while (/*CONSTCOND*/0)
11569 #define STANDARD_BITS (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO)
11577 BITCMD *set, *saveset, *endset;
11578 sigset_t mysigset, sigoset;
11580 int equalopdone = 0; /* pacify gcc */
11581 int permXbits, setlen;
11587 * Get a copy of the mask for the permissions that are mask relative.
11588 * Flip the bits, we want what's not set. Since it's possible that
11589 * the caller is opening files inside a signal handler, protect them
11592 sigfillset(&mysigset);
11593 (void)sigprocmask(SIG_BLOCK, &mysigset, &sigoset);
11594 (void)umask(mask = umask(0));
11596 (void)sigprocmask(SIG_SETMASK, &sigoset, NULL);
11598 setlen = SET_LEN + 2;
11600 if ((set = malloc((u_int)(sizeof(BITCMD) * setlen))) == NULL)
11603 endset = set + (setlen - 2);
11606 * If an absolute number, get it and return; disallow non-octal digits
11609 if (isdigit((unsigned char)*p)) {
11610 perm = (mode_t)strtol(p, &ep, 8);
11611 if (*ep || perm & ~(STANDARD_BITS|S_ISTXT)) {
11615 ADDCMD('=', (STANDARD_BITS|S_ISTXT), perm, mask);
11621 * Build list of structures to set/clear/copy bits as described by
11622 * each clause of the symbolic mode.
11625 /* First, find out which bits might be modified. */
11626 for (who = 0;; ++p) {
11629 who |= STANDARD_BITS;
11632 who |= S_ISUID|S_IRWXU;
11635 who |= S_ISGID|S_IRWXG;
11645 getop: if ((op = *p++) != '+' && op != '-' && op != '=') {
11653 for (perm = 0, permXbits = 0;; ++p) {
11656 perm |= S_IRUSR|S_IRGRP|S_IROTH;
11660 * If specific bits where requested and
11661 * only "other" bits ignore set-id.
11663 if (who == 0 || (who & ~S_IRWXO))
11664 perm |= S_ISUID|S_ISGID;
11668 * If specific bits where requested and
11669 * only "other" bits ignore set-id.
11671 if (who == 0 || (who & ~S_IRWXO)) {
11677 perm |= S_IWUSR|S_IWGRP|S_IWOTH;
11680 permXbits = S_IXUSR|S_IXGRP|S_IXOTH;
11683 perm |= S_IXUSR|S_IXGRP|S_IXOTH;
11689 * When ever we hit 'u', 'g', or 'o', we have
11690 * to flush out any partial mode that we have,
11691 * and then do the copying of the mode bits.
11694 ADDCMD(op, who, perm, mask);
11699 if (op == '+' && permXbits) {
11700 ADDCMD('X', who, permXbits, mask);
11703 ADDCMD(*p, who, op, mask);
11708 * Add any permissions that we haven't already
11711 if (perm || (op == '=' && !equalopdone)) {
11714 ADDCMD(op, who, perm, mask);
11718 ADDCMD('X', who, permXbits, mask);
11732 #ifdef SETMODE_DEBUG
11733 (void)printf("Before compress_mode()\n");
11736 compress_mode(saveset);
11737 #ifdef SETMODE_DEBUG
11738 (void)printf("After compress_mode()\n");
11745 addcmd(set, op, who, oparg, mask)
11752 _DIAGASSERT(set != NULL);
11757 set->bits = who ? who : STANDARD_BITS;
11766 set->bits = (who ? who : mask) & oparg;
11774 set->cmd2 = ((who & S_IRUSR) ? CMD2_UBITS : 0) |
11775 ((who & S_IRGRP) ? CMD2_GBITS : 0) |
11776 ((who & S_IROTH) ? CMD2_OBITS : 0);
11777 set->bits = (mode_t)~0;
11779 set->cmd2 = CMD2_UBITS | CMD2_GBITS | CMD2_OBITS;
11784 set->cmd2 |= CMD2_SET;
11785 else if (oparg == '-')
11786 set->cmd2 |= CMD2_CLR;
11787 else if (oparg == '=')
11788 set->cmd2 |= CMD2_SET|CMD2_CLR;
11794 #ifdef SETMODE_DEBUG
11800 _DIAGASSERT(set != NULL);
11802 for (; set->cmd; ++set)
11803 (void)printf("cmd: '%c' bits %04o%s%s%s%s%s%s\n",
11804 set->cmd, set->bits, set->cmd2 ? " cmd2:" : "",
11805 set->cmd2 & CMD2_CLR ? " CLR" : "",
11806 set->cmd2 & CMD2_SET ? " SET" : "",
11807 set->cmd2 & CMD2_UBITS ? " UBITS" : "",
11808 set->cmd2 & CMD2_GBITS ? " GBITS" : "",
11809 set->cmd2 & CMD2_OBITS ? " OBITS" : "");
11814 * Given an array of bitcmd structures, compress by compacting consecutive
11815 * '+', '-' and 'X' commands into at most 3 commands, one of each. The 'u',
11816 * 'g' and 'o' commands continue to be separate. They could probably be
11817 * compacted, but it's not worth the effort.
11824 int setbits, clrbits, Xbits, op;
11826 _DIAGASSERT(set != NULL);
11828 for (nset = set;;) {
11829 /* Copy over any 'u', 'g' and 'o' commands. */
11830 while ((op = nset->cmd) != '+' && op != '-' && op != 'X') {
11836 for (setbits = clrbits = Xbits = 0;; nset++) {
11837 if ((op = nset->cmd) == '-') {
11838 clrbits |= nset->bits;
11839 setbits &= ~nset->bits;
11840 Xbits &= ~nset->bits;
11841 } else if (op == '+') {
11842 setbits |= nset->bits;
11843 clrbits &= ~nset->bits;
11844 Xbits &= ~nset->bits;
11845 } else if (op == 'X')
11846 Xbits |= nset->bits & ~setbits;
11853 set->bits = clrbits;
11859 set->bits = setbits;
11871 static void shtree (union node *, int, char *, FILE*);
11872 static void shcmd (union node *, FILE *);
11873 static void sharg (union node *, FILE *);
11874 static void indent (int, char *, FILE *);
11875 static void trstring (char *);
11882 trputs("showtree called\n");
11883 shtree(n, 1, NULL, stdout);
11888 shtree(n, ind, pfx, fp)
11894 struct nodelist *lp;
11900 indent(ind, pfx, fp);
11911 shtree(n->nbinary.ch1, ind, NULL, fp);
11914 shtree(n->nbinary.ch2, ind, NULL, fp);
11922 for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
11927 if (n->npipe.backgnd)
11933 fprintf(fp, "<node type %d>", n->type);
11953 for (np = cmd->ncmd.args ; np ; np = np->narg.next) {
11959 for (np = cmd->ncmd.redirect ; np ; np = np->nfile.next) {
11962 switch (np->nfile.type) {
11963 case NTO: s = ">"; dftfd = 1; break;
11964 case NAPPEND: s = ">>"; dftfd = 1; break;
11965 case NTOFD: s = ">&"; dftfd = 1; break;
11966 case NTOOV: s = ">|"; dftfd = 1; break;
11967 case NFROM: s = "<"; dftfd = 0; break;
11968 case NFROMFD: s = "<&"; dftfd = 0; break;
11969 case NFROMTO: s = "<>"; dftfd = 0; break;
11970 default: s = "*error*"; dftfd = 0; break;
11972 if (np->nfile.fd != dftfd)
11973 fprintf(fp, "%d", np->nfile.fd);
11975 if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) {
11976 fprintf(fp, "%d", np->ndup.dupfd);
11978 sharg(np->nfile.fname, fp);
11992 struct nodelist *bqlist;
11995 if (arg->type != NARG) {
11996 printf("<node type %d>\n", arg->type);
12000 bqlist = arg->narg.backquote;
12001 for (p = arg->narg.text ; *p ; p++) {
12010 if (subtype == VSLENGTH)
12016 if (subtype & VSNUL)
12019 switch (subtype & VSTYPE) {
12038 case VSTRIMLEFTMAX:
12045 case VSTRIMRIGHTMAX:
12052 printf("<subtype %d>", subtype);
12059 case CTLBACKQ|CTLQUOTE:
12062 shtree(bqlist->n, -1, NULL, fp);
12074 indent(amount, pfx, fp)
12081 for (i = 0 ; i < amount ; i++) {
12082 if (pfx && i == amount - 1)
12100 static int debug = 1;
12102 static int debug = 0;
12110 if (tracefile == NULL)
12112 putc(c, tracefile);
12118 trace(const char *fmt, ...)
12126 fmt = va_arg(va, char *);
12128 if (tracefile != NULL) {
12129 (void) vfprintf(tracefile, fmt, va);
12130 if (strchr(fmt, '\n'))
12131 (void) fflush(tracefile);
12141 if (tracefile == NULL)
12143 fputs(s, tracefile);
12144 if (strchr(s, '\n'))
12156 if (tracefile == NULL)
12158 putc('"', tracefile);
12159 for (p = s ; *p ; p++) {
12161 case '\n': c = 'n'; goto backslash;
12162 case '\t': c = 't'; goto backslash;
12163 case '\r': c = 'r'; goto backslash;
12164 case '"': c = '"'; goto backslash;
12165 case '\\': c = '\\'; goto backslash;
12166 case CTLESC: c = 'e'; goto backslash;
12167 case CTLVAR: c = 'v'; goto backslash;
12168 case CTLVAR+CTLQUOTE: c = 'V'; goto backslash;
12169 case CTLBACKQ: c = 'q'; goto backslash;
12170 case CTLBACKQ+CTLQUOTE: c = 'Q'; goto backslash;
12171 backslash: putc('\\', tracefile);
12172 putc(c, tracefile);
12175 if (*p >= ' ' && *p <= '~')
12176 putc(*p, tracefile);
12178 putc('\\', tracefile);
12179 putc(*p >> 6 & 03, tracefile);
12180 putc(*p >> 3 & 07, tracefile);
12181 putc(*p & 07, tracefile);
12186 putc('"', tracefile);
12194 if (tracefile == NULL)
12199 putc(' ', tracefile);
12201 putc('\n', tracefile);
12216 #ifdef not_this_way
12219 if ((p = getenv("HOME")) == NULL) {
12220 if (geteuid() == 0)
12226 strcat(s, "/trace");
12229 strcpy(s, "./trace");
12230 #endif /* not_this_way */
12231 if ((tracefile = fopen(s, "a")) == NULL) {
12232 fprintf(stderr, "Can't open %s\n", s);
12236 if ((flags = fcntl(fileno(tracefile), F_GETFL, 0)) >= 0)
12237 fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND);
12239 fputs("\nTracing started.\n", tracefile);
12246 * The trap builtin.
12250 trapcmd(argc, argv)
12259 for (signo = 0 ; signo < NSIG ; signo++) {
12260 if (trap[signo] != NULL) {
12263 p = single_quote(trap[signo]);
12264 out1fmt("trap -- %s %s\n", p,
12265 signal_names[signo] + (signo ? 3 : 0)
12278 if ((signo = decode_signal(*ap, 0)) < 0)
12279 error("%s: bad trap", *ap);
12282 if (action[0] == '-' && action[1] == '\0')
12285 action = savestr(action);
12288 ckfree(trap[signo]);
12289 trap[signo] = action;
12304 * Set the signal handler for the specified signal. The routine figures
12305 * out what it should be set to.
12309 setsignal(int signo)
12313 struct sigaction act;
12315 if ((t = trap[signo]) == NULL)
12317 else if (*t != '\0')
12321 if (rootshell && action == S_DFL) {
12324 if (iflag || minusc || sflag == 0)
12350 t = &sigmode[signo - 1];
12353 * current setting unknown
12355 if (sigaction(signo, 0, &act) == -1) {
12357 * Pretend it worked; maybe we should give a warning
12358 * here, but other shells don't. We don't alter
12359 * sigmode, so that we retry every time.
12363 if (act.sa_handler == SIG_IGN) {
12364 if (mflag && (signo == SIGTSTP ||
12365 signo == SIGTTIN || signo == SIGTTOU)) {
12366 *t = S_IGN; /* don't hard ignore these */
12370 *t = S_RESET; /* force to be set */
12373 if (*t == S_HARD_IGN || *t == action)
12377 act.sa_handler = onsig;
12380 act.sa_handler = SIG_IGN;
12383 act.sa_handler = SIG_DFL;
12387 sigemptyset(&act.sa_mask);
12388 sigaction(signo, &act, 0);
12399 if (sigmode[signo - 1] != S_IGN && sigmode[signo - 1] != S_HARD_IGN) {
12400 signal(signo, SIG_IGN);
12402 sigmode[signo - 1] = S_HARD_IGN;
12413 if (signo == SIGINT && trap[SIGINT] == NULL) {
12417 gotsig[signo - 1] = 1;
12423 * Called to execute a trap. Perhaps we should avoid entering new trap
12424 * handlers while we are executing a trap handler.
12434 for (i = 1 ; ; i++) {
12441 savestatus=exitstatus;
12442 evalstring(trap[i], 0);
12443 exitstatus=savestatus;
12450 * Called to exit the shell.
12454 exitshell(int status)
12456 struct jmploc loc1, loc2;
12459 TRACE(("exitshell(%d) pid=%d\n", status, getpid()));
12460 if (setjmp(loc1.loc)) {
12463 if (setjmp(loc2.loc)) {
12467 if ((p = trap[0]) != NULL && *p != '\0') {
12471 l1: handler = &loc2; /* probably unnecessary */
12480 static int decode_signal(const char *string, int minsig)
12484 if (is_number(string, &signo)) {
12485 if (signo >= NSIG) {
12495 for (; signo < NSIG; signo++) {
12496 if (!strcasecmp(string, &(signal_names[signo])[3])) {
12500 if (!strcasecmp(string, signal_names[signo])) {
12507 static struct var **hashvar (const char *);
12508 static void showvars (const char *, int, int);
12509 static struct var **findvar (struct var **, const char *);
12512 * Initialize the varable symbol tables and import the environment
12516 * This routine initializes the builtin variables. It is called when the
12517 * shell is initialized and again when a shell procedure is spawned.
12522 const struct varinit *ip;
12526 for (ip = varinit ; (vp = ip->var) != NULL ; ip++) {
12527 if ((vp->flags & VEXPORT) == 0) {
12528 vpp = hashvar(ip->text);
12531 vp->text = strdup(ip->text);
12532 vp->flags = ip->flags;
12533 vp->func = ip->func;
12537 * PS1 depends on uid
12539 if ((vps1.flags & VEXPORT) == 0) {
12540 vpp = hashvar("PS1=");
12543 vps1.text = strdup(geteuid() ? "PS1=$ " : "PS1=# ");
12544 vps1.flags = VSTRFIXED|VTEXTFIXED;
12549 * Set the value of a variable. The flags argument is ored with the
12550 * flags of the variable. If val is NULL, the variable is unset.
12554 setvar(name, val, flags)
12555 const char *name, *val;
12571 if (! is_in_name(*p)) {
12572 if (*p == '\0' || *p == '=')
12578 namelen = p - name;
12580 error("%.*s: bad variable name", namelen, name);
12581 len = namelen + 2; /* 2 is space for '=' and '\0' */
12585 len += vallen = strlen(val);
12588 nameeq = ckmalloc(len);
12589 memcpy(nameeq, name, namelen);
12590 nameeq[namelen] = '=';
12592 memcpy(nameeq + namelen + 1, val, vallen + 1);
12594 nameeq[namelen + 1] = '\0';
12596 setvareq(nameeq, flags);
12603 * Same as setvar except that the variable and value are passed in
12604 * the first argument as name=value. Since the first argument will
12605 * be actually stored in the table, it should not be a string that
12614 struct var *vp, **vpp;
12617 flags |= (VEXPORT & (((unsigned) (1 - aflag)) - 1));
12618 if ((vp = *findvar(vpp, s))) {
12619 if (vp->flags & VREADONLY) {
12620 size_t len = strchr(s, '=') - s;
12621 error("%.*s: is read only", len, s);
12625 if (vp->func && (flags & VNOFUNC) == 0)
12626 (*vp->func)(strchr(s, '=') + 1);
12628 if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0)
12631 vp->flags &= ~(VTEXTFIXED|VSTACK|VUNSET);
12632 vp->flags |= flags;
12636 * We could roll this to a function, to handle it as
12637 * a regular variable function callback, but why bother?
12639 if (iflag && (vp == &vmpath || (vp == &vmail && !mpathset())))
12645 vp = ckmalloc(sizeof (*vp));
12656 * Process a linked list of variable assignments.
12661 struct strlist *mylist;
12663 struct strlist *lp;
12666 for (lp = mylist ; lp ; lp = lp->next) {
12667 setvareq(savestr(lp->text), 0);
12675 * Find the value of a variable. Returns NULL if not set.
12684 if ((v = *findvar(hashvar(name), name)) && !(v->flags & VUNSET)) {
12685 return strchr(v->text, '=') + 1;
12693 * Search the environment of a builtin command.
12700 struct strlist *sp;
12702 for (sp = cmdenviron ; sp ; sp = sp->next) {
12703 if (varequal(sp->text, name))
12704 return strchr(sp->text, '=') + 1;
12706 return lookupvar(name);
12712 * Generate a list of exported variables. This routine is used to construct
12713 * the third argument to execve when executing a program.
12725 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
12726 for (vp = *vpp ; vp ; vp = vp->next)
12727 if (vp->flags & VEXPORT)
12730 ep = env = stalloc((nenv + 1) * sizeof *env);
12731 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
12732 for (vp = *vpp ; vp ; vp = vp->next)
12733 if (vp->flags & VEXPORT)
12742 * Called when a shell procedure is invoked to clear out nonexported
12743 * variables. It is also necessary to reallocate variables of with
12744 * VSTACK set since these are currently allocated on the stack.
12750 struct var *vp, **prev;
12752 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
12753 for (prev = vpp ; (vp = *prev) != NULL ; ) {
12754 if ((vp->flags & VEXPORT) == 0) {
12756 if ((vp->flags & VTEXTFIXED) == 0)
12758 if ((vp->flags & VSTRFIXED) == 0)
12761 if (vp->flags & VSTACK) {
12762 vp->text = savestr(vp->text);
12763 vp->flags &=~ VSTACK;
12775 * Command to list all variables which are set. Currently this command
12776 * is invoked from the set command when the set command is called without
12781 showvarscmd(argc, argv)
12785 showvars(nullstr, VUNSET, VUNSET);
12792 * The export and readonly commands.
12796 exportcmd(argc, argv)
12803 int flag = argv[0][0] == 'r'? VREADONLY : VEXPORT;
12806 listsetvar(cmdenviron);
12807 pflag = (nextopt("p") == 'p');
12808 if (argc > 1 && !pflag) {
12809 while ((name = *argptr++) != NULL) {
12810 if ((p = strchr(name, '=')) != NULL) {
12813 if ((vp = *findvar(hashvar(name), name))) {
12818 setvar(name, p, flag);
12822 showvars(argv[0], flag, 0);
12829 * The "local" command.
12832 /* funcnest nonzero if we are currently evaluating a function */
12835 localcmd(argc, argv)
12842 error("Not in a function");
12843 while ((name = *argptr++) != NULL) {
12851 * Make a variable a local variable. When a variable is made local, it's
12852 * value and flags are saved in a localvar structure. The saved values
12853 * will be restored when the shell function returns. We handle the name
12854 * "-" as a special case.
12861 struct localvar *lvp;
12866 lvp = ckmalloc(sizeof (struct localvar));
12867 if (name[0] == '-' && name[1] == '\0') {
12869 p = ckmalloc(sizeof optet_vals);
12870 lvp->text = memcpy(p, optet_vals, sizeof optet_vals);
12873 vpp = hashvar(name);
12874 vp = *findvar(vpp, name);
12876 if (strchr(name, '='))
12877 setvareq(savestr(name), VSTRFIXED);
12879 setvar(name, NULL, VSTRFIXED);
12880 vp = *vpp; /* the new variable */
12882 lvp->flags = VUNSET;
12884 lvp->text = vp->text;
12885 lvp->flags = vp->flags;
12886 vp->flags |= VSTRFIXED|VTEXTFIXED;
12887 if (strchr(name, '='))
12888 setvareq(savestr(name), 0);
12892 lvp->next = localvars;
12899 * Called after a function returns.
12904 struct localvar *lvp;
12907 while ((lvp = localvars) != NULL) {
12908 localvars = lvp->next;
12910 if (vp == NULL) { /* $- saved */
12911 memcpy(optet_vals, lvp->text, sizeof optet_vals);
12913 } else if ((lvp->flags & (VUNSET|VSTRFIXED)) == VUNSET) {
12914 (void)unsetvar(vp->text);
12916 if ((vp->flags & VTEXTFIXED) == 0)
12918 vp->flags = lvp->flags;
12919 vp->text = lvp->text;
12927 setvarcmd(argc, argv)
12932 return unsetcmd(argc, argv);
12933 else if (argc == 3)
12934 setvar(argv[1], argv[2], 0);
12936 error("List assignment not implemented");
12942 * The unset builtin command. We unset the function before we unset the
12943 * variable to allow a function to be unset when there is a readonly variable
12944 * with the same name.
12948 unsetcmd(argc, argv)
12958 while ((i = nextopt("vf")) != '\0') {
12964 if (flg_func == 0 && flg_var == 0)
12967 for (ap = argptr; *ap ; ap++) {
12971 ret |= unsetvar(*ap);
12978 * Unset the specified variable.
12988 vpp = findvar(hashvar(s), s);
12991 if (vp->flags & VREADONLY)
12994 if (*(strchr(vp->text, '=') + 1) != '\0')
12995 setvar(s, nullstr, 0);
12996 vp->flags &= ~VEXPORT;
12997 vp->flags |= VUNSET;
12998 if ((vp->flags & VSTRFIXED) == 0) {
12999 if ((vp->flags & VTEXTFIXED) == 0)
13014 * Find the appropriate entry in the hash table from the name.
13017 static struct var **
13021 unsigned int hashval;
13023 hashval = ((unsigned char) *p) << 4;
13024 while (*p && *p != '=')
13025 hashval += (unsigned char) *p++;
13026 return &vartab[hashval % VTABSIZE];
13032 * Returns true if the two strings specify the same varable. The first
13033 * variable name is terminated by '='; the second may be terminated by
13034 * either '=' or '\0'.
13041 while (*p == *q++) {
13045 if (*p == '=' && *(q - 1) == '\0')
13051 showvars(const char *myprefix, int mask, int xor)
13055 const char *sep = myprefix == nullstr ? myprefix : spcstr;
13057 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
13058 for (vp = *vpp ; vp ; vp = vp->next) {
13059 if ((vp->flags & mask) ^ xor) {
13063 p = strchr(vp->text, '=') + 1;
13064 len = p - vp->text;
13065 p = single_quote(p);
13068 "%s%s%.*s%s\n", myprefix, sep, len,
13077 static struct var **
13078 findvar(struct var **vpp, const char *name)
13080 for (; *vpp; vpp = &(*vpp)->next) {
13081 if (varequal((*vpp)->text, name)) {
13089 * Copyright (c) 1999 Herbert Xu <herbert@debian.org>
13090 * This file contains code for the times builtin.
13091 * $Id: ash.c,v 1.6 2001/07/06 04:26:23 andersen Exp $
13093 static int timescmd (int argc, char **argv)
13096 long int clk_tck = sysconf(_SC_CLK_TCK);
13099 printf("%dm%fs %dm%fs\n%dm%fs %dm%fs\n",
13100 (int) (buf.tms_utime / clk_tck / 60),
13101 ((double) buf.tms_utime) / clk_tck,
13102 (int) (buf.tms_stime / clk_tck / 60),
13103 ((double) buf.tms_stime) / clk_tck,
13104 (int) (buf.tms_cutime / clk_tck / 60),
13105 ((double) buf.tms_cutime) / clk_tck,
13106 (int) (buf.tms_cstime / clk_tck / 60),
13107 ((double) buf.tms_cstime) / clk_tck);
13113 * Copyright (c) 1989, 1991, 1993, 1994
13114 * The Regents of the University of California. All rights reserved.
13116 * This code is derived from software contributed to Berkeley by
13117 * Kenneth Almquist.
13119 * Redistribution and use in source and binary forms, with or without
13120 * modification, are permitted provided that the following conditions
13122 * 1. Redistributions of source code must retain the above copyright
13123 * notice, this list of conditions and the following disclaimer.
13124 * 2. Redistributions in binary form must reproduce the above copyright
13125 * notice, this list of conditions and the following disclaimer in the
13126 * documentation and/or other materials provided with the distribution.
13128 * 3. <BSD Advertising Clause omitted per the July 22, 1999 licensing change
13129 * ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change>
13131 * 4. Neither the name of the University nor the names of its contributors
13132 * may be used to endorse or promote products derived from this software
13133 * without specific prior written permission.
13135 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
13136 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
13137 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
13138 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
13139 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
13140 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
13141 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
13142 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
13143 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
13144 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF