X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=shell%2Fmsh.c;h=2fb0df739fd5cb3b3c918d8c076bff07f8894b23;hb=627814bdc3ef9b405a77686d73e7b53ebd767a07;hp=31dd04f3e4350028b20b9c5946c59f58cbb6b8b3;hpb=dc4e75ef7ca135c836d22e380847672cf5b3773b;p=oweals%2Fbusybox.git diff --git a/shell/msh.c b/shell/msh.c index 31dd04f3e..2fb0df739 100644 --- a/shell/msh.c +++ b/shell/msh.c @@ -23,7 +23,7 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * * Original copyright notice is retained at the end of this file. */ @@ -49,30 +49,74 @@ #include "busybox.h" +/* Conditional use of "register" keyword */ +#define REGISTER register + + +/*#define MSHDEBUG 1*/ + +#ifdef MSHDEBUG +int mshdbg = 0; + +#define DBGPRINTF(x) if(mshdbg>0)printf x +#define DBGPRINTF0(x) if(mshdbg>0)printf x +#define DBGPRINTF1(x) if(mshdbg>1)printf x +#define DBGPRINTF2(x) if(mshdbg>2)printf x +#define DBGPRINTF3(x) if(mshdbg>3)printf x +#define DBGPRINTF4(x) if(mshdbg>4)printf x +#define DBGPRINTF5(x) if(mshdbg>5)printf x +#define DBGPRINTF6(x) if(mshdbg>6)printf x +#define DBGPRINTF7(x) if(mshdbg>7)printf x +#define DBGPRINTF8(x) if(mshdbg>8)printf x +#define DBGPRINTF9(x) if(mshdbg>9)printf x + +int mshdbg_rc = 0; + +#define RCPRINTF(x) if(mshdbg_rc)printf x + +#else + +#define DBGPRINTF(x) +#define DBGPRINTF0(x) +#define DBGPRINTF1(x) +#define DBGPRINTF2(x) +#define DBGPRINTF3(x) +#define DBGPRINTF4(x) +#define DBGPRINTF5(x) +#define DBGPRINTF6(x) +#define DBGPRINTF7(x) +#define DBGPRINTF8(x) +#define DBGPRINTF9(x) + +#define RCPRINTF(x) + +#endif /* MSHDEBUG */ + + /* -------- sh.h -------- */ /* * shell */ -#define LINELIM 2100 -#define NPUSH 8 /* limit to input nesting */ +#define LINELIM 2100 +#define NPUSH 8 /* limit to input nesting */ #undef NOFILE -#define NOFILE 20 /* Number of open files */ -#define NUFILE 10 /* Number of user-accessible files */ -#define FDBASE 10 /* First file usable by Shell */ +#define NOFILE 20 /* Number of open files */ +#define NUFILE 10 /* Number of user-accessible files */ +#define FDBASE 10 /* First file usable by Shell */ /* * values returned by wait */ -#define WAITSIG(s) ((s)&0177) -#define WAITVAL(s) (((s)>>8)&0377) +#define WAITSIG(s) ((s)&0177) +#define WAITVAL(s) (((s)>>8)&0377) #define WAITCORE(s) (((s)&0200)!=0) /* - * library and system defintions + * library and system definitions */ -typedef void xint; /* base type of jmp_buf, for not broken compilers */ +typedef void xint; /* base type of jmp_buf, for not broken compilers */ /* * shell components @@ -90,61 +134,81 @@ typedef void xint; /* base type of jmp_buf, for not broken compilers */ * Might eventually use a union. */ struct op { - int type; /* operation type, see below */ - char **words; /* arguments to a command */ - struct ioword **ioact; /* IO actions (eg, < > >>) */ + int type; /* operation type, see below */ + char **words; /* arguments to a command */ + struct ioword **ioact; /* IO actions (eg, < > >>) */ struct op *left; struct op *right; - char *str; /* identifier for case and for */ + char *str; /* identifier for case and for */ }; -#define TCOM 1 /* command */ -#define TPAREN 2 /* (c-list) */ -#define TPIPE 3 /* a | b */ -#define TLIST 4 /* a [&;] b */ -#define TOR 5 /* || */ -#define TAND 6 /* && */ +#define TCOM 1 /* command */ +#define TPAREN 2 /* (c-list) */ +#define TPIPE 3 /* a | b */ +#define TLIST 4 /* a [&;] b */ +#define TOR 5 /* || */ +#define TAND 6 /* && */ #define TFOR 7 -#define TDO 8 +#define TDO 8 #define TCASE 9 -#define TIF 10 +#define TIF 10 #define TWHILE 11 #define TUNTIL 12 #define TELIF 13 -#define TPAT 14 /* pattern in case */ -#define TBRACE 15 /* {c-list} */ -#define TASYNC 16 /* c & */ +#define TPAT 14 /* pattern in case */ +#define TBRACE 15 /* {c-list} */ +#define TASYNC 16 /* c & */ +/* Added to support "." file expansion */ +#define TDOT 17 + +/* Strings for names to make debug easier */ +char *T_CMD_NAMES[] = { + "PLACEHOLDER", + "TCOM", + "TPAREN", + "TPIPE", + "TLIST", + "TOR", + "TAND", + "TFOR", + "TDO", + "TCASE", + "TIF", + "TWHILE", + "TUNTIL", + "TELIF", + "TPAT", + "TBRACE", + "TASYNC", + "TDOT", +}; + /* * actions determining the environment of a process */ #define BIT(i) (1<<(i)) -#define FEXEC BIT(0) /* execute without forking */ +#define FEXEC BIT(0) /* execute without forking */ + +#if 0 /* Original value */ +#define AREASIZE (65000) +#else +#define AREASIZE (90000) +#endif /* * flags to control evaluation of words */ -#define DOSUB 1 /* interpret $, `, and quotes */ -#define DOBLANK 2 /* perform blank interpretation */ -#define DOGLOB 4 /* interpret [?* */ -#define DOKEY 8 /* move words with `=' to 2nd arg. list */ -#define DOTRIM 16 /* trim resulting string */ +#define DOSUB 1 /* interpret $, `, and quotes */ +#define DOBLANK 2 /* perform blank interpretation */ +#define DOGLOB 4 /* interpret [?* */ +#define DOKEY 8 /* move words with `=' to 2nd arg. list */ +#define DOTRIM 16 /* trim resulting string */ #define DOALL (DOSUB|DOBLANK|DOGLOB|DOKEY|DOTRIM) -static char **dolv; -static int dolc; -static int exstat; -static char gflg; -static int interactive; /* Is this an interactive shell */ -static int execflg; -static int multiline; /* \n changed to ; */ -static struct op *outtree; /* result from parser */ - -static xint *failpt; -static xint *errpt; -static struct brkcon *brklist; -static int isbreak; + +/* PROTOTYPES */ static int newfile(char *s); static char *findeq(char *cp); static char *cclass(char *p, int sub); @@ -152,42 +216,43 @@ static void initarea(void); extern int msh_main(int argc, char **argv); -struct brkcon { - jmp_buf brkpt; - struct brkcon *nextlev; -} ; +struct brkcon { + jmp_buf brkpt; + struct brkcon *nextlev; +}; + /* * redirection */ struct ioword { - short io_unit; /* unit affected */ - short io_flag; /* action (below) */ - char *io_name; /* file name */ + short io_unit; /* unit affected */ + short io_flag; /* action (below) */ + char *io_name; /* file name */ }; -#define IOREAD 1 /* < */ -#define IOHERE 2 /* << (here file) */ -#define IOWRITE 4 /* > */ -#define IOCAT 8 /* >> */ -#define IOXHERE 16 /* ${}, ` in << */ -#define IODUP 32 /* >&digit */ -#define IOCLOSE 64 /* >&- */ -#define IODEFAULT (-1) /* token for default IO unit */ +#define IOREAD 1 /* < */ +#define IOHERE 2 /* << (here file) */ +#define IOWRITE 4 /* > */ +#define IOCAT 8 /* >> */ +#define IOXHERE 16 /* ${}, ` in << */ +#define IODUP 32 /* >&digit */ +#define IOCLOSE 64 /* >&- */ + +#define IODEFAULT (-1) /* token for default IO unit */ + -static struct wdblock *wdlist; -static struct wdblock *iolist; /* * parsing & execution environment */ -static struct env { - char *linep; - struct io *iobase; - struct io *iop; - xint *errpt; - int iofd; - struct env *oenv; +static struct env { + char *linep; + struct io *iobase; + struct io *iop; + xint *errpt; /* void * */ + int iofd; + struct env *oenv; } e; /* @@ -200,362 +265,366 @@ static struct env { * -x: trace * -u: unset variables net diagnostic */ -static char *flag; +static char *flag; -static char *null; /* null value for variable */ -static int intr; /* interrupt pending */ +static char *null; /* null value for variable */ +static int intr; /* interrupt pending */ -static char *trap[_NSIG+1]; -static char ourtrap[_NSIG+1]; -static int trapset; /* trap pending */ +static char *trap[_NSIG + 1]; +static char ourtrap[_NSIG + 1]; +static int trapset; /* trap pending */ -static int heedint; /* heed interrupt signals */ +static int heedint; /* heed interrupt signals */ -static int yynerrs; /* yacc */ +static int yynerrs; /* yacc */ + +static char line[LINELIM]; +static char *elinep; -static char line[LINELIM]; -static char *elinep; /* * other functions */ -static int(*inbuilt(char *s))(struct op *); - - -static char *rexecve (char *c , char **v, char **envp ); -static char *space (int n ); -static char *strsave (char *s, int a ); -static char *evalstr (char *cp, int f ); -static char *putn (int n ); -static char *itoa (int n ); -static char *unquote (char *as ); -static struct var *lookup (char *n ); -static int rlookup (char *n ); -static struct wdblock *glob (char *cp, struct wdblock *wb ); -static int my_getc( int ec); -static int subgetc (int ec, int quoted ); -static char **makenv (void); -static char **eval (char **ap, int f ); -static int setstatus (int s ); -static int waitfor (int lastpid, int canintr ); - -static void onintr (int s ); /* SIGINT handler */ - -static int newenv (int f ); -static void quitenv (void); -static void err (char *s ); -static int anys (char *s1, char *s2 ); -static int any (int c, char *s ); -static void next (int f ); -static void setdash (void); -static void onecommand (void); -static void runtrap (int i ); -static int gmatch (char *s, char *p ); +static int (*inbuilt(char *s)) (struct op *); + +static char *rexecve(char *c, char **v, char **envp); +static char *space(int n); +static char *strsave(char *s, int a); +static char *evalstr(char *cp, int f); +static char *putn(int n); +static char *itoa(int n); +static char *unquote(char *as); +static struct var *lookup(char *n); +static int rlookup(char *n); +static struct wdblock *glob(char *cp, struct wdblock *wb); +static int my_getc(int ec); +static int subgetc(int ec, int quoted); +static char **makenv(int all, struct wdblock *wb); +static char **eval(char **ap, int f); +static int setstatus(int s); +static int waitfor(int lastpid, int canintr); + +static void onintr(int s); /* SIGINT handler */ + +static int newenv(int f); +static void quitenv(void); +static void err(char *s); +static int anys(char *s1, char *s2); +static int any(int c, char *s); +static void next(int f); +static void setdash(void); +static void onecommand(void); +static void runtrap(int i); +static int gmatch(char *s, char *p); + /* * error handling */ -static void leave (void); /* abort shell (or fail in subshell) */ -static void fail (void); /* fail but return to process next command */ -static void warn (char *s ); -static void sig (int i ); /* default signal handler */ +static void leave(void); /* abort shell (or fail in subshell) */ +static void fail(void); /* fail but return to process next command */ +static void warn(char *s); +static void sig(int i); /* default signal handler */ /* -------- area stuff -------- */ -#define REGSIZE sizeof(struct region) -#define GROWBY 256 -//#define SHRINKBY 64 +#define REGSIZE sizeof(struct region) +#define GROWBY (256) +/* #define SHRINKBY (64) */ #undef SHRINKBY -#define FREE 32767 -#define BUSY 0 -#define ALIGN (sizeof(int)-1) +#define FREE (32767) +#define BUSY (0) +#define ALIGN (sizeof(int)-1) struct region { - struct region *next; - int area; + struct region *next; + int area; }; /* -------- grammar stuff -------- */ typedef union { - char *cp; - char **wp; - int i; - struct op *o; + char *cp; + char **wp; + int i; + struct op *o; } YYSTYPE; + #define WORD 256 #define LOGAND 257 #define LOGOR 258 #define BREAK 259 -#define IF 260 +#define IF 260 #define THEN 261 #define ELSE 262 #define ELIF 263 -#define FI 264 +#define FI 264 #define CASE 265 #define ESAC 266 -#define FOR 267 +#define FOR 267 #define WHILE 268 #define UNTIL 269 -#define DO 270 +#define DO 270 #define DONE 271 -#define IN 272 +#define IN 272 +/* Added for "." file expansion */ +#define DOT 273 + #define YYERRCODE 300 /* flags to yylex */ -#define CONTIN 01 /* skip new lines to complete command */ +#define CONTIN 01 /* skip new lines to complete command */ #define SYNTAXERR zzerr() -static struct op *pipeline(int cf ); + +static struct op *pipeline(int cf); static struct op *andor(void); static struct op *c_list(void); -static int synio(int cf ); -static void musthave (int c, int cf ); +static int synio(int cf); +static void musthave(int c, int cf); static struct op *simple(void); -static struct op *nested(int type, int mark ); -static struct op *command(int cf ); -static struct op *dogroup(int onlydone ); +static struct op *nested(int type, int mark); +static struct op *command(int cf); +static struct op *dogroup(int onlydone); static struct op *thenpart(void); static struct op *elsepart(void); static struct op *caselist(void); static struct op *casepart(void); static char **pattern(void); static char **wordlist(void); -static struct op *list(struct op *t1, struct op *t2 ); -static struct op *block(int type, struct op *t1, struct op *t2, char **wp ); +static struct op *list(struct op *t1, struct op *t2); +static struct op *block(int type, struct op *t1, struct op *t2, char **wp); static struct op *newtp(void); -static struct op *namelist(struct op *t ); +static struct op *namelist(struct op *t); static char **copyw(void); -static void word(char *cp ); +static void word(char *cp); static struct ioword **copyio(void); -static struct ioword *io (int u, int f, char *cp ); +static struct ioword *io(int u, int f, char *cp); static void zzerr(void); -static void yyerror(char *s ); -static int yylex(int cf ); -static int collect(int c, int c1 ); -static int dual(int c ); -static void diag(int ec ); -static char *tree(unsigned size ); +static void yyerror(char *s); +static int yylex(int cf); +static int collect(int c, int c1); +static int dual(int c); +static void diag(int ec); +static char *tree(unsigned size); /* -------- var.h -------- */ -struct var { - char *value; - char *name; - struct var *next; - char status; +struct var { + char *value; + char *name; + struct var *next; + char status; }; -#define COPYV 1 /* flag to setval, suggesting copy */ -#define RONLY 01 /* variable is read-only */ -#define EXPORT 02 /* variable is to be exported */ -#define GETCELL 04 /* name & value space was got with getcell */ - -static struct var *vlist; /* dictionary */ - -static struct var *homedir; /* home directory */ -static struct var *prompt; /* main prompt */ -static struct var *cprompt; /* continuation prompt */ -static struct var *path; /* search path for commands */ -static struct var *shell; /* shell to interpret command files */ -static struct var *ifs; /* field separators */ - -static int yyparse (void); -static struct var *lookup (char *n ); -static void setval (struct var *vp, char *val ); -static void nameval (struct var *vp, char *val, char *name ); -static void export (struct var *vp ); -static void ronly (struct var *vp ); -static int isassign (char *s ); -static int checkname (char *cp ); -static int assign (char *s, int cf ); -static void putvlist (int f, int out ); -static int eqname (char *n1, char *n2 ); - -static int execute (struct op *t, int *pin, int *pout, int act ); + +#define COPYV 1 /* flag to setval, suggesting copy */ +#define RONLY 01 /* variable is read-only */ +#define EXPORT 02 /* variable is to be exported */ +#define GETCELL 04 /* name & value space was got with getcell */ + +static int yyparse(void); +static struct var *lookup(char *n); +static void setval(struct var *vp, char *val); +static void nameval(struct var *vp, char *val, char *name); +static void export(struct var *vp); +static void ronly(struct var *vp); +static int isassign(char *s); +static int checkname(char *cp); +static int assign(char *s, int cf); +static void putvlist(int f, int out); +static int eqname(char *n1, char *n2); + +static int execute(struct op *t, int *pin, int *pout, int act); + /* -------- io.h -------- */ /* io buffer */ struct iobuf { - unsigned id; /* buffer id */ - char buf[512]; /* buffer */ - char *bufp; /* pointer into buffer */ - char *ebufp; /* pointer to end of buffer */ + unsigned id; /* buffer id */ + char buf[512]; /* buffer */ + char *bufp; /* pointer into buffer */ + char *ebufp; /* pointer to end of buffer */ }; /* possible arguments to an IO function */ struct ioarg { - char *aword; - char **awordlist; - int afile; /* file descriptor */ - unsigned afid; /* buffer id */ - long afpos; /* file position */ - struct iobuf *afbuf; /* buffer for this file */ + char *aword; + char **awordlist; + int afile; /* file descriptor */ + unsigned afid; /* buffer id */ + long afpos; /* file position */ + struct iobuf *afbuf; /* buffer for this file */ }; + //static struct ioarg ioargstack[NPUSH]; #define AFID_NOBUF (~0) #define AFID_ID 0 /* an input generator's state */ -struct io { - int (*iofn)(struct ioarg *, struct io *); - struct ioarg *argp; - int peekc; - char prev; /* previous character read by readc() */ - char nlcount; /* for `'s */ - char xchar; /* for `'s */ - char task; /* reason for pushed IO */ +struct io { + int (*iofn) (struct ioarg *, struct io *); + struct ioarg *argp; + int peekc; + char prev; /* previous character read by readc() */ + char nlcount; /* for `'s */ + char xchar; /* for `'s */ + char task; /* reason for pushed IO */ }; -//static struct io iostack[NPUSH]; -#define XOTHER 0 /* none of the below */ -#define XDOLL 1 /* expanding ${} */ -#define XGRAVE 2 /* expanding `'s */ -#define XIO 3 /* file IO */ + +//static struct io iostack[NPUSH]; +#define XOTHER 0 /* none of the below */ +#define XDOLL 1 /* expanding ${} */ +#define XGRAVE 2 /* expanding `'s */ +#define XIO 3 /* file IO */ /* in substitution */ #define INSUB() (e.iop->task == XGRAVE || e.iop->task == XDOLL) + /* * input generators for IO structure */ -static int nlchar (struct ioarg *ap ); -static int strchar (struct ioarg *ap ); -static int qstrchar (struct ioarg *ap ); -static int filechar (struct ioarg *ap ); -static int herechar (struct ioarg *ap ); -static int linechar (struct ioarg *ap ); -static int gravechar (struct ioarg *ap, struct io *iop ); -static int qgravechar (struct ioarg *ap, struct io *iop ); -static int dolchar (struct ioarg *ap ); -static int wdchar (struct ioarg *ap ); -static void scraphere (void); -static void freehere (int area ); -static void gethere (void); -static void markhere (char *s, struct ioword *iop ); -static int herein (char *hname, int xdoll ); -static int run (struct ioarg *argp, int (*f)(struct ioarg *)); +static int nlchar(struct ioarg *ap); +static int strchar(struct ioarg *ap); +static int qstrchar(struct ioarg *ap); +static int filechar(struct ioarg *ap); +static int herechar(struct ioarg *ap); +static int linechar(struct ioarg *ap); +static int gravechar(struct ioarg *ap, struct io *iop); +static int qgravechar(struct ioarg *ap, struct io *iop); +static int dolchar(struct ioarg *ap); +static int wdchar(struct ioarg *ap); +static void scraphere(void); +static void freehere(int area); +static void gethere(void); +static void markhere(char *s, struct ioword *iop); +static int herein(char *hname, int xdoll); +static int run(struct ioarg *argp, int (*f) (struct ioarg *)); + /* * IO functions */ -static int eofc (void); -static int readc (void); -static void unget (int c ); -static void ioecho (int c ); -static void prs (char *s ); -static void prn (unsigned u ); -static void closef (int i ); -static void closeall (void); +static int eofc(void); +static int readc(void); +static void unget(int c); +static void ioecho(int c); +static void prs(char *s); +static void prn(unsigned u); +static void closef(int i); +static void closeall(void); + /* * IO control */ -static void pushio (struct ioarg *argp, int (*f)(struct ioarg *)); -static int remap (int fd ); -static int openpipe (int *pv ); -static void closepipe (int *pv ); -static struct io *setbase (struct io *ip ); +static void pushio(struct ioarg *argp, int (*f) (struct ioarg *)); +static int remap(int fd); +static int openpipe(int *pv); +static void closepipe(int *pv); +static struct io *setbase(struct io *ip); -static struct ioarg temparg; /* temporary for PUSHIO */ #define PUSHIO(what,arg,gen) ((temparg.what = (arg)),pushio(&temparg,(gen))) #define RUN(what,arg,gen) ((temparg.what = (arg)), run(&temparg,(gen))) /* -------- word.h -------- */ -#define NSTART 16 /* default number of words to allow for initially */ +#define NSTART 16 /* default number of words to allow for initially */ -struct wdblock { - short w_bsize; - short w_nword; +struct wdblock { + short w_bsize; + short w_nword; /* bounds are arbitrary */ - char *w_words[1]; + char *w_words[1]; }; -static struct wdblock *addword (char *wd, struct wdblock *wb ); -static struct wdblock *newword (int nw ); -static char **getwords (struct wdblock *wb ); +static struct wdblock *addword(char *wd, struct wdblock *wb); +static struct wdblock *newword(int nw); +static char **getwords(struct wdblock *wb); /* -------- area.h -------- */ /* * storage allocation */ -static char *getcell (unsigned nbytes ); -static void garbage (void); -static void setarea (char *cp, int a ); -static int getarea (char *cp ); -static void freearea (int a ); -static void freecell (char *cp ); -static int areanum; /* current allocation area */ - -#define NEW(type) (type *)getcell(sizeof(type)) +static char *getcell(unsigned nbytes); +static void garbage(void); +static void setarea(char *cp, int a); +static int getarea(char *cp); +static void freearea(int a); +static void freecell(char *cp); +static int areanum; /* current allocation area */ + +#define NEW(type) (type *)getcell(sizeof(type)) #define DELETE(obj) freecell((char *)obj) /* -------- misc stuff -------- */ -static int forkexec (struct op *t, int *pin, int *pout, int act, char **wp, int *pforked ); -static int iosetup (struct ioword *iop, int pipein, int pipeout ); -static void echo(char **wp ); -static struct op **find1case (struct op *t, char *w ); -static struct op *findcase (struct op *t, char *w ); -static void brkset(struct brkcon *bc ); -static int dolabel(struct op *t ); -static int dohelp(struct op *t ); -static int dochdir(struct op *t ); -static int doshift(struct op *t ); -static int dologin(struct op *t ); -static int doumask(struct op *t ); -static int doexec(struct op *t ); -static int dodot(struct op *t ); -static int dowait(struct op *t ); -static int doread(struct op *t ); -static int doeval(struct op *t ); -static int dotrap(struct op *t ); -static int getsig(char *s ); -static void setsig (int n, sighandler_t f); -static int getn(char *as ); -static int dobreak(struct op *t ); -static int docontinue(struct op *t ); -static int brkcontin (char *cp, int val ); -static int doexit(struct op *t ); -static int doexport(struct op *t ); -static int doreadonly(struct op *t ); -static void rdexp (char **wp, void (*f)(struct var *), int key); -static void badid(char *s ); -static int doset(struct op *t ); -static void varput (char *s, int out ); -static int dotimes(struct op *t ); -static int expand (char *cp, struct wdblock **wbp, int f ); -static char *blank(int f ); -static int dollar(int quoted ); -static int grave(int quoted ); -static void globname (char *we, char *pp ); -static char *generate (char *start1, char *end1, char *middle, char *end ); -static int anyspcl(struct wdblock *wb ); -static int xstrcmp (char *p1, char *p2 ); -static void glob0 (char *a0, unsigned int a1, int a2, int (*a3)(char *, char *)); -static void glob1 (char *base, char *lim ); -static void glob2 (char *i, char *j ); -static void glob3 (char *i, char *j, char *k ); -static void readhere (char **name, char *s, int ec ); -static void pushio (struct ioarg *argp, int (*f)(struct ioarg *)); -static int xxchar(struct ioarg *ap ); - -struct here { - char *h_tag; - int h_dosub; - struct ioword *h_iop; - struct here *h_next; +static int forkexec(struct op *t, int *pin, int *pout, int act, char **wp); +static int iosetup(struct ioword *iop, int pipein, int pipeout); +static void echo(char **wp); +static struct op **find1case(struct op *t, char *w); +static struct op *findcase(struct op *t, char *w); +static void brkset(struct brkcon *bc); +static int dolabel(struct op *t); +static int dohelp(struct op *t); +static int dochdir(struct op *t); +static int doshift(struct op *t); +static int dologin(struct op *t); +static int doumask(struct op *t); +static int doexec(struct op *t); +static int dodot(struct op *t); +static int dowait(struct op *t); +static int doread(struct op *t); +static int doeval(struct op *t); +static int dotrap(struct op *t); +static int getsig(char *s); +static void setsig(int n, sighandler_t f); +static int getn(char *as); +static int dobreak(struct op *t); +static int docontinue(struct op *t); +static int brkcontin(char *cp, int val); +static int doexit(struct op *t); +static int doexport(struct op *t); +static int doreadonly(struct op *t); +static void rdexp(char **wp, void (*f) (struct var *), int key); +static void badid(char *s); +static int doset(struct op *t); +static void varput(char *s, int out); +static int dotimes(struct op *t); +static int expand(char *cp, struct wdblock **wbp, int f); +static char *blank(int f); +static int dollar(int quoted); +static int grave(int quoted); +static void globname(char *we, char *pp); +static char *generate(char *start1, char *end1, char *middle, char *end); +static int anyspcl(struct wdblock *wb); +static int xstrcmp(char *p1, char *p2); +static void glob0(char *a0, unsigned int a1, int a2, + int (*a3) (char *, char *)); +static void glob1(char *base, char *lim); +static void glob2(char *i, char *j); +static void glob3(char *i, char *j, char *k); +static void readhere(char **name, char *s, int ec); +static void pushio(struct ioarg *argp, int (*f) (struct ioarg *)); +static int xxchar(struct ioarg *ap); + +struct here { + char *h_tag; + int h_dosub; + struct ioword *h_iop; + struct here *h_next; }; -static char *signame[] = { +static char *signame[] = { "Signal 0", "Hangup", - (char *)NULL, /* interrupt */ + (char *) NULL, /* interrupt */ "Quit", "Illegal instruction", "Trace/BPT trap", @@ -566,128 +635,181 @@ static char *signame[] = { "SIGUSR1", "SIGSEGV", "SIGUSR2", - (char *)NULL, /* broken pipe */ + (char *) NULL, /* broken pipe */ "Alarm clock", "Terminated", }; + #define NSIGNAL (sizeof(signame)/sizeof(signame[0])) struct res { char *r_name; - int r_val; + int r_val; }; static struct res restab[] = { - {"for", FOR}, - {"case", CASE}, - {"esac", ESAC}, - {"while", WHILE}, - {"do", DO}, - {"done", DONE}, - {"if", IF}, - {"in", IN}, - {"then", THEN}, - {"else", ELSE}, - {"elif", ELIF}, - {"until", UNTIL}, - {"fi", FI}, - - {";;", BREAK}, - {"||", LOGOR}, - {"&&", LOGAND}, - {"{", '{'}, - {"}", '}'}, - {0, 0}, + {"for", FOR}, + {"case", CASE}, + {"esac", ESAC}, + {"while", WHILE}, + {"do", DO}, + {"done", DONE}, + {"if", IF}, + {"in", IN}, + {"then", THEN}, + {"else", ELSE}, + {"elif", ELIF}, + {"until", UNTIL}, + {"fi", FI}, + {";;", BREAK}, + {"||", LOGOR}, + {"&&", LOGAND}, + {"{", '{'}, + {"}", '}'}, + {".", DOT}, + {0, 0}, }; struct builtincmd { const char *name; - int (*builtinfunc)(struct op *t); + int (*builtinfunc) (struct op * t); }; -static const struct builtincmd builtincmds[] = { - {".", dodot}, - {":", dolabel}, - {"break", dobreak}, - {"cd", dochdir}, - {"continue",docontinue}, - {"eval", doeval}, - {"exec", doexec}, - {"exit", doexit}, - {"export", doexport}, - {"help", dohelp}, - {"login", dologin}, - {"newgrp", dologin}, - {"read", doread}, - {"readonly",doreadonly}, - {"set", doset}, - {"shift", doshift}, - {"times", dotimes}, - {"trap", dotrap}, - {"umask", doumask}, - {"wait", dowait}, - {0,0} +static const struct builtincmd builtincmds[] = { + {".", dodot}, + {":", dolabel}, + {"break", dobreak}, + {"cd", dochdir}, + {"continue", docontinue}, + {"eval", doeval}, + {"exec", doexec}, + {"exit", doexit}, + {"export", doexport}, + {"help", dohelp}, + {"login", dologin}, + {"newgrp", dologin}, + {"read", doread}, + {"readonly", doreadonly}, + {"set", doset}, + {"shift", doshift}, + {"times", dotimes}, + {"trap", dotrap}, + {"umask", doumask}, + {"wait", dowait}, + {0, 0} }; +struct op *scantree(struct op *); +static struct op *dowholefile(int, int); + /* Globals */ -extern char **environ; /* environment pointer */ -static char **dolv; -static int dolc; -static int exstat; -static char gflg; -static int interactive; /* Is this an interactive shell */ -static int execflg; -static int multiline; /* \n changed to ; */ -static struct op *outtree; /* result from parser */ -static xint *failpt; -static xint *errpt; -static struct brkcon *brklist; -static int isbreak; -static struct wdblock *wdlist; -static struct wdblock *iolist; -static char *trap[_NSIG+1]; -static char ourtrap[_NSIG+1]; -static int trapset; /* trap pending */ -static int yynerrs; /* yacc */ -static char line[LINELIM]; -static struct var *vlist; /* dictionary */ -static struct var *homedir; /* home directory */ -static struct var *prompt; /* main prompt */ -static struct var *cprompt; /* continuation prompt */ -static struct var *path; /* search path for commands */ -static struct var *shell; /* shell to interpret command files */ -static struct var *ifs; /* field separators */ -static struct ioarg ioargstack[NPUSH]; -static struct io iostack[NPUSH]; -static int areanum; /* current allocation area */ -static int intr; -static int inparse; -static char flags['z'-'a'+1]; -static char *flag = flags-'a'; -static char *elinep = line+sizeof(line)-5; -static char *null = ""; -static int heedint =1; -static struct env e ={line, iostack, iostack-1, (xint *)NULL, FDBASE, (struct env *)NULL}; -static void (*qflag)(int) = SIG_IGN; -static int startl; -static int peeksym; -static int nlseen; -static int iounit = IODEFAULT; -static YYSTYPE yylval; -static struct iobuf sharedbuf = {AFID_NOBUF}; -static struct iobuf mainbuf = {AFID_NOBUF}; +extern char **environ; /* environment pointer */ + +static char **dolv; +static int dolc; +static int exstat; +static char gflg; +static int interactive = 0; /* Is this an interactive shell */ +static int execflg; +static int multiline; /* \n changed to ; */ +static struct op *outtree; /* result from parser */ +static xint *failpt; +static xint *errpt; +static struct brkcon *brklist; +static int isbreak; +static struct wdblock *wdlist; +static struct wdblock *iolist; +static char *trap[_NSIG + 1]; +static char ourtrap[_NSIG + 1]; +static int trapset; /* trap pending */ +static int yynerrs; /* yacc */ +static char line[LINELIM]; + +#ifdef MSHDEBUG +static struct var *mshdbg_var; +#endif +static struct var *vlist; /* dictionary */ +static struct var *homedir; /* home directory */ +static struct var *prompt; /* main prompt */ +static struct var *cprompt; /* continuation prompt */ +static struct var *path; /* search path for commands */ +static struct var *shell; /* shell to interpret command files */ +static struct var *ifs; /* field separators */ + +static int areanum; /* current allocation area */ +static int intr; +static int inparse; +static char flags['z' - 'a' + 1]; +static char *flag = flags - 'a'; +static char *null = ""; +static int heedint = 1; +static void (*qflag) (int) = SIG_IGN; +static int startl; +static int peeksym; +static int nlseen; +static int iounit = IODEFAULT; +static YYSTYPE yylval; +static char *elinep = line + sizeof(line) - 5; + +static struct ioarg temparg = { 0, 0, 0, AFID_NOBUF, 0 }; /* temporary for PUSHIO */ +static struct ioarg ioargstack[NPUSH]; +static struct io iostack[NPUSH]; +static struct iobuf sharedbuf = { AFID_NOBUF }; +static struct iobuf mainbuf = { AFID_NOBUF }; static unsigned bufid = AFID_ID; /* buffer id counter */ -static struct ioarg temparg = {0, 0, 0, AFID_NOBUF, 0}; -static struct here *inhere; /* list of hear docs while parsing */ -static struct here *acthere; /* list of active here documents */ -static struct region *areabot; /* bottom of area */ -static struct region *areatop; /* top of area */ -static struct region *areanxt; /* starting point of scan */ -static void * brktop; -static void * brkaddr; + +static struct here *inhere; /* list of hear docs while parsing */ +static struct here *acthere; /* list of active here documents */ +static struct region *areabot; /* bottom of area */ +static struct region *areatop; /* top of area */ +static struct region *areanxt; /* starting point of scan */ +static void *brktop; +static void *brkaddr; + +static struct env e = { + line, /* linep: char ptr */ + iostack, /* iobase: struct io ptr */ + iostack - 1, /* iop: struct io ptr */ + (xint *) NULL, /* errpt: void ptr for errors? */ + FDBASE, /* iofd: file desc */ + (struct env *) NULL /* oenv: struct env ptr */ +}; + +#ifdef MSHDEBUG +void print_t(struct op *t) +{ + DBGPRINTF(("T: t=0x%x, type %s, words=0x%x, IOword=0x%x\n", t, + T_CMD_NAMES[t->type], t->words, t->ioact)); + + if (t->words) { + DBGPRINTF(("T: W1: %s", t->words[0])); + } + + return; +} + +void print_tree(struct op *head) +{ + if (head == NULL) { + DBGPRINTF(("PRINT_TREE: no tree\n")); + return; + } + + DBGPRINTF(("NODE: 0x%x, left 0x%x, right 0x%x\n", head, head->left, + head->right)); + + if (head->left) + print_tree(head->left); + + if (head->right) + print_tree(head->right); + + return; +} +#endif /* MSHDEBUG */ #ifdef CONFIG_FEATURE_COMMAND_EDITING -static char * current_prompt; +static char *current_prompt; #endif /* -------- sh.c -------- */ @@ -698,11 +820,13 @@ static char * current_prompt; extern int msh_main(int argc, char **argv) { - register int f; - register char *s; + REGISTER int f; + REGISTER char *s; int cflag; char *name, **ap; - int (*iof)(struct ioarg *); + int (*iof) (struct ioarg *); + + DBGPRINTF(("MSH_MAIN: argc %d, environ 0x%x\n", argc, environ)); initarea(); if ((ap = environ) != NULL) { @@ -716,7 +840,7 @@ extern int msh_main(int argc, char **argv) shell = lookup("SHELL"); if (shell->value == null) - setval(shell, DEFAULT_SHELL); + setval(shell, (char *)DEFAULT_SHELL); export(shell); homedir = lookup("HOME"); @@ -739,6 +863,13 @@ extern int msh_main(int argc, char **argv) if (ifs->value == null) setval(ifs, " \t\n"); +#ifdef MSHDEBUG + mshdbg_var = lookup("MSHDEBUG"); + if (mshdbg_var->value == null) + setval(mshdbg_var, "0"); +#endif + + prompt = lookup("PS1"); #ifdef CONFIG_FEATURE_SH_FANCY_PROMPT if (prompt->value == null) @@ -758,8 +889,8 @@ extern int msh_main(int argc, char **argv) cflag = 0; name = *argv++; if (--argc >= 1) { - if(argv[0][0] == '-' && argv[0][1] != '\0') { - for (s = argv[0]+1; *s; s++) + if (argv[0][0] == '-' && argv[0][1] != '\0') { + for (s = argv[0] + 1; *s; s++) switch (*s) { case 'c': prompt->status &= ~EXPORT; @@ -770,7 +901,7 @@ extern int msh_main(int argc, char **argv) if (--argc > 0) PUSHIO(aword, *++argv, iof = nlchar); break; - + case 'q': qflag = SIG_DFL; break; @@ -784,37 +915,55 @@ extern int msh_main(int argc, char **argv) setval(prompt, ""); iof = linechar; break; - + case 'i': interactive++; default: - if (*s>='a' && *s<='z') - flag[(int)*s]++; + if (*s >= 'a' && *s <= 'z') + flag[(int) *s]++; } } else { argv--; argc++; } + if (iof == filechar && --argc > 0) { setval(prompt, ""); setval(cprompt, ""); prompt->status &= ~EXPORT; cprompt->status &= ~EXPORT; + +/* Shell is non-interactive, activate printf-based debug */ +#ifdef MSHDEBUG + mshdbg = (int) (((char) (mshdbg_var->value[0])) - '0'); + if (mshdbg < 0) + mshdbg = 0; +#endif + DBGPRINTF(("MSH_MAIN: calling newfile()\n")); + if (newfile(name = *++argv)) - exit(1); + exit(1); /* Exit on error */ } } + setdash(); + + /* This won't be true if PUSHIO has been called, say from newfile() above */ if (e.iop < iostack) { PUSHIO(afile, 0, iof); if (isatty(0) && isatty(1) && !cflag) { interactive++; -#ifndef CONFIG_FEATURE_SH_EXTRA_QUIET - printf( "\n\n" BB_BANNER " Built-in shell (msh)\n"); - printf( "Enter 'help' for a list of built-in commands.\n\n"); +#ifndef CONFIG_FEATURE_SH_EXTRA_QUIET +#ifdef MSHDEBUG + printf("\n\n" BB_BANNER " Built-in shell (msh with debug)\n"); +#else + printf("\n\n" BB_BANNER " Built-in shell (msh)\n"); +#endif + printf("Enter 'help' for a list of built-in commands.\n\n"); #endif } } + signal(SIGQUIT, qflag); if (name && name[0] == '-') { interactive++; @@ -825,6 +974,7 @@ extern int msh_main(int argc, char **argv) } if (interactive) signal(SIGTERM, sig); + if (signal(SIGINT, SIG_IGN) != SIG_IGN) signal(SIGINT, onintr); dolv = argv; @@ -833,18 +983,20 @@ extern int msh_main(int argc, char **argv) if (dolc > 1) { for (ap = ++argv; --argc > 0;) { if (assign(*ap = *argv++, !COPYV)) { - dolc--; /* keyword */ + dolc--; /* keyword */ } else { ap++; } } - } + } setval(lookup("#"), putn((--dolc < 0) ? (dolc = 0) : dolc)); + DBGPRINTF(("MSH_MAIN: begin FOR loop, interactive %d, e.iop 0x%x, iostack 0x%x\n", interactive, e.iop, iostack)); + for (;;) { if (interactive && e.iop <= iostack) { #ifdef CONFIG_FEATURE_COMMAND_EDITING - current_prompt=prompt->value; + current_prompt = prompt->value; #else prs(prompt->value); #endif @@ -853,50 +1005,91 @@ extern int msh_main(int argc, char **argv) /* Ensure that getenv("PATH") stays current */ setenv("PATH", path->value, 1); } + + DBGPRINTF(("MSH_MAIN: returning.\n")); } -static void -setdash() +static void setdash() { - register char *cp; - register int c; - char m['z'-'a'+1]; + REGISTER char *cp; + REGISTER int c; + char m['z' - 'a' + 1]; cp = m; - for (c='a'; c<='z'; c++) - if (flag[(int)c]) + for (c = 'a'; c <= 'z'; c++) + if (flag[(int) c]) *cp++ = c; *cp = 0; setval(lookup("-"), m); } -static int -newfile(s) -register char *s; +static int newfile(s) +REGISTER char *s; { - register int f; + REGISTER int f; + + DBGPRINTF7(("NEWFILE: opening %s\n", s)); if (strcmp(s, "-") != 0) { + DBGPRINTF(("NEWFILE: s is %s\n", s)); f = open(s, 0); if (f < 0) { prs(s); err(": cannot open"); - return(1); + return (1); } } else f = 0; + next(remap(f)); - return(0); + return (0); +} + + +struct op *scantree(head) +struct op *head; +{ + struct op *dotnode; + + if (head == NULL) + return (NULL); + + if (head->left != NULL) { + dotnode = scantree(head->left); + if (dotnode) + return (dotnode); + } + + if (head->right != NULL) { + dotnode = scantree(head->right); + if (dotnode) + return (dotnode); + } + + if (head->words == NULL) + return (NULL); + + DBGPRINTF5(("SCANTREE: checking node 0x%x\n", head)); + + if ((head->type != TDOT) && (strcmp(".", head->words[0]) == 0)) { + DBGPRINTF5(("SCANTREE: dot found in node 0x%x\n", head)); + return (head); + } + + return (NULL); } -static void -onecommand() + +static void onecommand() { - register int i; + REGISTER int i; jmp_buf m1; + DBGPRINTF(("ONECOMMAND: enter, outtree=0x%x\n", outtree)); + while (e.oenv) quitenv(); + areanum = 1; freehere(areanum); freearea(areanum); @@ -910,8 +1103,12 @@ onecommand() inparse = 1; intr = 0; execflg = 0; - setjmp(failpt = m1); /* Bruce Evans' fix */ + + setjmp(failpt = m1); /* Bruce Evans' fix */ if (setjmp(failpt = m1) || yyparse() || intr) { + + DBGPRINTF(("ONECOMMAND: this is not good.\n")); + while (e.oenv) quitenv(); scraphere(); @@ -921,46 +1118,52 @@ onecommand() intr = 0; return; } + inparse = 0; brklist = 0; intr = 0; execflg = 0; - if (!flag['n']) + + if (!flag['n']) { + DBGPRINTF(("ONECOMMAND: calling execute, t=outtree=0x%x\n", + outtree)); execute(outtree, NOPIPE, NOPIPE, 0); + } + if (!interactive && intr) { execflg = 0; leave(); } + if ((i = trapset) != 0) { trapset = 0; runtrap(i); } } -static void -fail() +static void fail() { longjmp(failpt, 1); /* NOTREACHED */ } -static void -leave() +static void leave() { + DBGPRINTF(("LEAVE: leave called!\n")); + if (execflg) fail(); scraphere(); freehere(1); runtrap(0); - exit(exstat); + _exit(exstat); /* NOTREACHED */ } -static void -warn(s) -register char *s; +static void warn(s) +REGISTER char *s; { - if(*s) { + if (*s) { prs(s); exstat = -1; } @@ -969,8 +1172,7 @@ register char *s; leave(); } -static void -err(s) +static void err(s) char *s; { warn(s); @@ -984,16 +1186,18 @@ char *s; e.iop = e.iobase = iostack; } -static int -newenv(f) +static int newenv(f) int f; { - register struct env *ep; + REGISTER struct env *ep; + + DBGPRINTF(("NEWENV: f=%d (indicates quitenv and return)\n", f)); if (f) { quitenv(); - return(1); + return (1); } + ep = (struct env *) space(sizeof(*ep)); if (ep == NULL) { while (e.oenv) @@ -1003,14 +1207,16 @@ int f; *ep = e; e.oenv = ep; e.errpt = errpt; - return(0); + + return (0); } -static void -quitenv() +static void quitenv() { - register struct env *ep; - register int fd; + REGISTER struct env *ep; + REGISTER int fd; + + DBGPRINTF(("QUITENV: e.oenv=0x%x\n", e.oenv)); if ((ep = e.oenv) != NULL) { fd = e.iofd; @@ -1025,55 +1231,51 @@ quitenv() /* * Is any character from s1 in s2? */ -static int -anys(s1, s2) -register char *s1, *s2; +static int anys(s1, s2) +REGISTER char *s1, *s2; { while (*s1) if (any(*s1++, s2)) - return(1); - return(0); + return (1); + return (0); } /* * Is character c in s? */ -static int -any(c, s) -register int c; -register char *s; +static int any(c, s) +REGISTER int c; +REGISTER char *s; { while (*s) if (*s++ == c) - return(1); - return(0); + return (1); + return (0); } -static char * -putn(n) -register int n; +static char *putn(n) +REGISTER int n; { - return(itoa(n)); + return (itoa(n)); } -static char * -itoa(n) -register int n; +static char *itoa(n) +REGISTER int n; { static char s[20]; + snprintf(s, sizeof(s), "%u", n); - return(s); + return (s); } -static void -next(int f) + +static void next(int f) { PUSHIO(afile, f, filechar); } -static void -onintr(s) -int s; /* ANSI C requires a parameter */ +static void onintr(s) +int s; /* ANSI C requires a parameter */ { signal(SIGINT, onintr); intr = 1; @@ -1082,46 +1284,41 @@ int s; /* ANSI C requires a parameter */ prs("\n"); fail(); } - } - else if (heedint) { + } else if (heedint) { execflg = 0; leave(); } } -static char * -space(n) +static char *space(n) int n; { - register char *cp; + REGISTER char *cp; if ((cp = getcell(n)) == 0) err("out of string space"); - return(cp); + return (cp); } -static char * -strsave(s, a) -register char *s; +static char *strsave(s, a) +REGISTER char *s; int a; { - register char *cp, *xp; + REGISTER char *cp, *xp; - if ((cp = space(strlen(s)+1)) != NULL) { - setarea((char *)cp, a); - for (xp = cp; (*xp++ = *s++) != '\0';) - ; - return(cp); + if ((cp = space(strlen(s) + 1)) != NULL) { + setarea((char *) cp, a); + for (xp = cp; (*xp++ = *s++) != '\0';); + return (cp); } - return(""); + return (""); } /* * trap handling */ -static void -sig(i) -register int i; +static void sig(i) +REGISTER int i; { trapset = i; signal(i, sig); @@ -1134,8 +1331,10 @@ int i; if ((trapstr = trap[i]) == NULL) return; + if (i == 0) trap[i] = 0; + RUN(aword, trapstr, nlchar); } @@ -1147,55 +1346,52 @@ int i; * not previously there, enter it now and * return a null value. */ -static struct var * -lookup(n) -register char *n; +static struct var *lookup(n) +REGISTER char *n; { - register struct var *vp; - register char *cp; - register int c; + REGISTER struct var *vp; + REGISTER char *cp; + REGISTER int c; static struct var dummy; if (isdigit(*n)) { dummy.name = n; for (c = 0; isdigit(*n) && c < 1000; n++) - c = c*10 + *n-'0'; + c = c * 10 + *n - '0'; dummy.status = RONLY; - dummy.value = c <= dolc? dolv[c]: null; - return(&dummy); + dummy.value = c <= dolc ? dolv[c] : null; + return (&dummy); } for (vp = vlist; vp; vp = vp->next) if (eqname(vp->name, n)) - return(vp); + return (vp); cp = findeq(n); - vp = (struct var *)space(sizeof(*vp)); - if (vp == 0 || (vp->name = space((int)(cp-n)+2)) == 0) { + vp = (struct var *) space(sizeof(*vp)); + if (vp == 0 || (vp->name = space((int) (cp - n) + 2)) == 0) { dummy.name = dummy.value = ""; - return(&dummy); + return (&dummy); } - for (cp = vp->name; (*cp = *n++) && *cp != '='; cp++) - ; + for (cp = vp->name; (*cp = *n++) && *cp != '='; cp++); if (*cp == 0) *cp = '='; *++cp = 0; - setarea((char *)vp, 0); - setarea((char *)vp->name, 0); + setarea((char *) vp, 0); + setarea((char *) vp->name, 0); vp->value = null; vp->next = vlist; vp->status = GETCELL; vlist = vp; - return(vp); + return (vp); } /* * give variable at `vp' the value `val'. */ -static void -setval(vp, val) +static void setval(vp, val) struct var *vp; char *val; { - nameval(vp, val, (char *)NULL); + nameval(vp, val, (char *) NULL); } /* @@ -1205,12 +1401,11 @@ char *val; * this is all so that exporting * values is reasonably painless. */ -static void -nameval(vp, val, name) -register struct var *vp; +static void nameval(vp, val, name) +REGISTER struct var *vp; char *val, *name; { - register char *cp, *xp; + REGISTER char *cp, *xp; char *nv; int fl; @@ -1222,93 +1417,92 @@ char *val, *name; } fl = 0; if (name == NULL) { - xp = space(strlen(vp->name)+strlen(val)+2); + xp = space(strlen(vp->name) + strlen(val) + 2); if (xp == 0) return; /* make string: name=value */ - setarea((char *)xp, 0); + setarea((char *) xp, 0); name = xp; - for (cp = vp->name; (*xp = *cp++) && *xp!='='; xp++) - ; + for (cp = vp->name; (*xp = *cp++) && *xp != '='; xp++); if (*xp++ == 0) xp[-1] = '='; nv = xp; - for (cp = val; (*xp++ = *cp++) != '\0';) - ; + for (cp = val; (*xp++ = *cp++) != '\0';); val = nv; fl = GETCELL; } if (vp->status & GETCELL) - freecell(vp->name); /* form new string `name=value' */ + freecell(vp->name); /* form new string `name=value' */ vp->name = name; vp->value = val; vp->status |= fl; } -static void -export(vp) +static void export(vp) struct var *vp; { vp->status |= EXPORT; } -static void -ronly(vp) +static void ronly(vp) struct var *vp; { if (isalpha(vp->name[0]) || vp->name[0] == '_') /* not an internal symbol */ vp->status |= RONLY; } -static int -isassign(s) -register char *s; +static int isassign(s) +REGISTER char *s; { - if (!isalpha((int)*s) && *s != '_') - return(0); + DBGPRINTF7(("ISASSIGN: enter, s=%s\n", s)); + + if (!isalpha((int) *s) && *s != '_') + return (0); for (; *s != '='; s++) if (*s == 0 || (!isalnum(*s) && *s != '_')) - return(0); - return(1); + return (0); + + return (1); } -static int -assign(s, cf) -register char *s; +static int assign(s, cf) +REGISTER char *s; int cf; { - register char *cp; + REGISTER char *cp; struct var *vp; + DBGPRINTF7(("ASSIGN: enter, s=%s, cf=%d\n", s, cf)); + if (!isalpha(*s) && *s != '_') - return(0); + return (0); for (cp = s; *cp != '='; cp++) if (*cp == 0 || (!isalnum(*cp) && *cp != '_')) - return(0); + return (0); vp = lookup(s); - nameval(vp, ++cp, cf == COPYV? (char *)NULL: s); + nameval(vp, ++cp, cf == COPYV ? (char *) NULL : s); if (cf != COPYV) vp->status &= ~GETCELL; - return(1); + return (1); } -static int -checkname(cp) -register char *cp; +static int checkname(cp) +REGISTER char *cp; { - if (!isalpha(*cp++) && *(cp-1) != '_') - return(0); + DBGPRINTF7(("CHECKNAME: enter, cp=%s\n", cp)); + + if (!isalpha(*cp++) && *(cp - 1) != '_') + return (0); while (*cp) - if (!isalnum(*cp++) && *(cp-1) != '_') - return(0); - return(1); + if (!isalnum(*cp++) && *(cp - 1) != '_') + return (0); + return (1); } -static void -putvlist(f, out) -register int f, out; +static void putvlist(f, out) +REGISTER int f, out; { - register struct var *vp; + REGISTER struct var *vp; for (vp = vlist; vp; vp = vp->next) if (vp->status & f && (isalpha(*vp->name) || *vp->name == '_')) { @@ -1316,28 +1510,26 @@ register int f, out; write(out, "export ", 7); if (vp->status & RONLY) write(out, "readonly ", 9); - write(out, vp->name, (int)(findeq(vp->name) - vp->name)); + write(out, vp->name, (int) (findeq(vp->name) - vp->name)); write(out, "\n", 1); } } -static int -eqname(n1, n2) -register char *n1, *n2; +static int eqname(n1, n2) +REGISTER char *n1, *n2; { for (; *n1 != '=' && *n1 != 0; n1++) if (*n2++ != *n1) - return(0); - return(*n2 == 0 || *n2 == '='); + return (0); + return (*n2 == 0 || *n2 == '='); } -static char * -findeq(cp) -register char *cp; +static char *findeq(cp) +REGISTER char *cp; { while (*cp != '\0' && *cp != '=') cp++; - return(cp); + return (cp); } /* -------- gmatch.c -------- */ @@ -1351,58 +1543,56 @@ register char *cp; #define CMASK 0377 #define QUOTE 0200 #define QMASK (CMASK&~QUOTE) -#define NOT '!' /* might use ^ */ +#define NOT '!' /* might use ^ */ -static int -gmatch(s, p) -register char *s, *p; +static int gmatch(s, p) +REGISTER char *s, *p; { - register int sc, pc; + REGISTER int sc, pc; if (s == NULL || p == NULL) - return(0); + return (0); while ((pc = *p++ & CMASK) != '\0') { sc = *s++ & QMASK; switch (pc) { case '[': if ((p = cclass(p, sc)) == NULL) - return(0); + return (0); break; case '?': if (sc == 0) - return(0); + return (0); break; case '*': s--; do { if (*p == '\0' || gmatch(s, p)) - return(1); + return (1); } while (*s++ != '\0'); - return(0); + return (0); default: - if (sc != (pc&~QUOTE)) - return(0); + if (sc != (pc & ~QUOTE)) + return (0); } } - return(*s == 0); + return (*s == 0); } -static char * -cclass(p, sub) -register char *p; -register int sub; +static char *cclass(p, sub) +REGISTER char *p; +REGISTER int sub; { - register int c, d, not, found; + REGISTER int c, d, not, found; if ((not = *p == NOT) != 0) p++; found = not; do { if (*p == '\0') - return((char *)NULL); + return ((char *) NULL); c = *p & CMASK; if (p[1] == '-' && p[2] != ']') { d = p[2] & CMASK; @@ -1412,7 +1602,7 @@ register int sub; if (c == sub || (c <= sub && sub <= d)) found = !not; } while (*++p != ']'); - return(found? p+1: (char *)NULL); + return (found ? p + 1 : (char *) NULL); } @@ -1426,15 +1616,14 @@ register int sub; #define sbrk(X) ({ void * __q = (void *)-1; if (brkaddr + (int)(X) < brktop) { __q = brkaddr; brkaddr+=(int)(X); } __q;}) -static void -initarea() +static void initarea() { - brkaddr = malloc(65000); - brktop = brkaddr + 65000; + brkaddr = malloc(AREASIZE); + brktop = brkaddr + AREASIZE; - while ((int)sbrk(0) & ALIGN) + while ((int) sbrk(0) & ALIGN) sbrk(1); - areabot = (struct region *)sbrk(REGSIZE); + areabot = (struct region *) sbrk(REGSIZE); areabot->next = areabot; areabot->area = BUSY; @@ -1442,22 +1631,22 @@ initarea() areanxt = areabot; } -char * -getcell(nbytes) +char *getcell(nbytes) unsigned nbytes; { - register int nregio; - register struct region *p, *q; - register int i; + REGISTER int nregio; + REGISTER struct region *p, *q; + REGISTER int i; if (nbytes == 0) { puts("getcell(0)"); abort(); - } /* silly and defeats the algorithm */ + } + /* silly and defeats the algorithm */ /* * round upwards and add administration area */ - nregio = (nbytes+(REGSIZE-1))/REGSIZE + 1; + nregio = (nbytes + (REGSIZE - 1)) / REGSIZE + 1; for (p = areanxt;;) { if (p->area > areanum) { /* @@ -1476,13 +1665,13 @@ unsigned nbytes; break; } i = nregio >= GROWBY ? nregio : GROWBY; - p = (struct region *)sbrk(i * REGSIZE); - if (p == (struct region *)-1) - return((char *)NULL); + p = (struct region *) sbrk(i * REGSIZE); + if (p == (struct region *) -1) + return ((char *) NULL); p--; if (p != areatop) { puts("not contig"); - abort(); /* allocated areas are contiguous */ + abort(); /* allocated areas are contiguous */ } q = p + i; p->next = q; @@ -1490,7 +1679,7 @@ unsigned nbytes; q->next = areabot; q->area = BUSY; areatop = q; -found: + found: /* * we found a FREE area big enough, pointed to by 'p', and up to 'q' */ @@ -1499,25 +1688,24 @@ found: /* * split into requested area and rest */ - if (areanxt+1 > q) { + if (areanxt + 1 > q) { puts("OOM"); - abort(); /* insufficient space left for admin */ + abort(); /* insufficient space left for admin */ } areanxt->next = q; areanxt->area = FREE; p->next = areanxt; } p->area = areanum; - return((char *)(p+1)); + return ((char *) (p + 1)); } -static void -freecell(cp) +static void freecell(cp) char *cp; { - register struct region *p; + REGISTER struct region *p; - if ((p = (struct region *)cp) != NULL) { + if ((p = (struct region *) cp) != NULL) { p--; if (p < areanxt) areanxt = p; @@ -1525,11 +1713,10 @@ char *cp; } } -static void -freearea(a) -register int a; +static void freearea(a) +REGISTER int a; { - register struct region *p, *top; + REGISTER struct region *p, *top; top = areatop; for (p = areabot; p != top; p = p->next) @@ -1537,28 +1724,25 @@ register int a; p->area = FREE; } -static void -setarea(cp,a) +static void setarea(cp, a) char *cp; int a; { - register struct region *p; + REGISTER struct region *p; - if ((p = (struct region *)cp) != NULL) - (p-1)->area = a; + if ((p = (struct region *) cp) != NULL) + (p - 1)->area = a; } -int -getarea(cp) +int getarea(cp) char *cp; { - return ((struct region*)cp-1)->area; + return ((struct region *) cp - 1)->area; } -static void -garbage() +static void garbage() { - register struct region *p, *q, *top; + REGISTER struct region *p, *q, *top; top = areatop; for (p = areabot; p != top; p = p->next) { @@ -1570,7 +1754,7 @@ garbage() } #ifdef SHRINKBY if (areatop >= q + SHRINKBY && q->area > areanum) { - brk((char *)(q+1)); + brk((char *) (q + 1)); q->next = areabot; q->area = BUSY; areatop = q; @@ -1583,116 +1767,151 @@ garbage() * shell: syntax (C version) */ - -int -yyparse() +int yyparse() { - startl = 1; + DBGPRINTF7(("YYPARSE: enter...\n")); + + startl = 1; peeksym = 0; yynerrs = 0; outtree = c_list(); musthave('\n', 0); - return(yynerrs!=0); + return (yynerrs != 0); } -static struct op * -pipeline(cf) +static struct op *pipeline(cf) int cf; { - register struct op *t, *p; - register int c; + REGISTER struct op *t, *p; + REGISTER int c; + + DBGPRINTF7(("PIPELINE: enter, cf=%d\n", cf)); t = command(cf); + + DBGPRINTF9(("PIPELINE: t=0x%x\n", t)); + if (t != NULL) { while ((c = yylex(0)) == '|') { - if ((p = command(CONTIN)) == NULL) + if ((p = command(CONTIN)) == NULL) { + DBGPRINTF8(("PIPELINE: error!\n")); SYNTAXERR; + } + if (t->type != TPAREN && t->type != TCOM) { /* shell statement */ t = block(TPAREN, t, NOBLOCK, NOWORDS); } + t = block(TPIPE, t, p, NOWORDS); } peeksym = c; } - return(t); + + DBGPRINTF7(("PIPELINE: returning t=0x%x\n", t)); + return (t); } -static struct op * -andor() +static struct op *andor() { - register struct op *t, *p; - register int c; + REGISTER struct op *t, *p; + REGISTER int c; + + DBGPRINTF7(("ANDOR: enter...\n")); t = pipeline(0); + + DBGPRINTF9(("ANDOR: t=0x%x\n", t)); + if (t != NULL) { while ((c = yylex(0)) == LOGAND || c == LOGOR) { - if ((p = pipeline(CONTIN)) == NULL) + if ((p = pipeline(CONTIN)) == NULL) { + DBGPRINTF8(("ANDOR: error!\n")); SYNTAXERR; - t = block(c == LOGAND? TAND: TOR, t, p, NOWORDS); - } + } + + t = block(c == LOGAND ? TAND : TOR, t, p, NOWORDS); + } /* WHILE */ + peeksym = c; } - return(t); + + DBGPRINTF7(("ANDOR: returning t=0x%x\n", t)); + return (t); } -static struct op * -c_list() +static struct op *c_list() { - register struct op *t, *p; - register int c; + REGISTER struct op *t, *p; + REGISTER int c; + + DBGPRINTF7(("C_LIST: enter...\n")); t = andor(); + if (t != NULL) { - if((peeksym = yylex(0)) == '&') + if ((peeksym = yylex(0)) == '&') t = block(TASYNC, t, NOBLOCK, NOWORDS); - while ((c = yylex(0)) == ';' || c == '&' || (multiline && c == '\n')) { + + while ((c = yylex(0)) == ';' || c == '&' + || (multiline && c == '\n')) { + if ((p = andor()) == NULL) - return(t); - if((peeksym = yylex(0)) == '&') + return (t); + + if ((peeksym = yylex(0)) == '&') p = block(TASYNC, p, NOBLOCK, NOWORDS); + t = list(t, p); - } + } /* WHILE */ + peeksym = c; } - return(t); + /* IF */ + DBGPRINTF7(("C_LIST: returning t=0x%x\n", t)); + return (t); } - -static int -synio(cf) +static int synio(cf) int cf; { - register struct ioword *iop; - register int i; - register int c; + REGISTER struct ioword *iop; + REGISTER int i; + REGISTER int c; + + DBGPRINTF7(("SYNIO: enter, cf=%d\n", cf)); if ((c = yylex(cf)) != '<' && c != '>') { peeksym = c; - return(0); + return (0); } + i = yylval.i; musthave(WORD, 0); iop = io(iounit, i, yylval.cp); iounit = IODEFAULT; + if (i & IOHERE) markhere(yylval.cp, iop); - return(1); + + DBGPRINTF7(("SYNIO: returning 1\n")); + return (1); } -static void -musthave(c, cf) +static void musthave(c, cf) int c, cf; { - if ((peeksym = yylex(cf)) != c) + if ((peeksym = yylex(cf)) != c) { + DBGPRINTF7(("MUSTHAVE: error!\n")); SYNTAXERR; + } + peeksym = 0; } -static struct op * -simple() +static struct op *simple() { - register struct op *t; + REGISTER struct op *t; t = NULL; for (;;) { @@ -1712,44 +1931,51 @@ simple() break; default: - return(t); + return (t); } } } -static struct op * -nested(type, mark) +static struct op *nested(type, mark) int type, mark; { - register struct op *t; + REGISTER struct op *t; + + DBGPRINTF3(("NESTED: enter, type=%d, mark=%d\n", type, mark)); multiline++; t = c_list(); musthave(mark, 0); multiline--; - return(block(type, t, NOBLOCK, NOWORDS)); + return (block(type, t, NOBLOCK, NOWORDS)); } -static struct op * -command(cf) +static struct op *command(cf) int cf; { - register struct op *t; + REGISTER struct op *t; struct wdblock *iosave; - register int c; + REGISTER int c; + + DBGPRINTF(("COMMAND: enter, cf=%d\n", cf)); iosave = iolist; iolist = NULL; + if (multiline) cf |= CONTIN; + while (synio(cf)) cf = 0; - switch (c = yylex(cf)) { + + c = yylex(cf); + + switch (c) { default: peeksym = c; if ((t = simple()) == NULL) { if (iolist == NULL) - return((struct op *)NULL); + return ((struct op *) NULL); t = newtp(); t->type = TCOM; } @@ -1781,7 +2007,7 @@ int cf; case UNTIL: multiline++; t = newtp(); - t->type = c == WHILE? TWHILE: TUNTIL; + t->type = c == WHILE ? TWHILE : TUNTIL; t->left = c_list(); t->right = dogroup(1); t->words = NULL; @@ -1797,7 +2023,9 @@ int cf; multiline++; musthave(IN, CONTIN); startl++; + t->left = caselist(); + musthave(ESAC, 0); multiline--; break; @@ -1811,40 +2039,71 @@ int cf; musthave(FI, 0); multiline--; break; + + case DOT: + t = newtp(); + t->type = TDOT; + + musthave(WORD, 0); /* gets name of file */ + DBGPRINTF7(("COMMAND: DOT clause, yylval.cp is %s\n", yylval.cp)); + + word(yylval.cp); /* add word to wdlist */ + word(NOWORD); /* terminate wdlist */ + t->words = copyw(); /* dup wdlist */ + break; + } - while (synio(0)) - ; + + while (synio(0)); + t = namelist(t); iolist = iosave; - return(t); + + DBGPRINTF(("COMMAND: returning 0x%x\n", t)); + + return (t); +} + +static struct op *dowholefile(type, mark) +int type; +int mark; +{ + REGISTER struct op *t; + + DBGPRINTF(("DOWHOLEFILE: enter, type=%d, mark=%d\n", type, mark)); + + multiline++; + t = c_list(); + multiline--; + t = block(type, t, NOBLOCK, NOWORDS); + DBGPRINTF(("DOWHOLEFILE: return t=0x%x\n", t)); + return (t); } -static struct op * -dogroup(onlydone) +static struct op *dogroup(onlydone) int onlydone; { - register int c; - register struct op *mylist; + REGISTER int c; + REGISTER struct op *mylist; c = yylex(CONTIN); if (c == DONE && onlydone) - return((struct op *)NULL); + return ((struct op *) NULL); if (c != DO) SYNTAXERR; mylist = c_list(); musthave(DONE, 0); - return(mylist); + return (mylist); } -static struct op * -thenpart() +static struct op *thenpart() { - register int c; - register struct op *t; + REGISTER int c; + REGISTER struct op *t; if ((c = yylex(0)) != THEN) { peeksym = c; - return((struct op *)NULL); + return ((struct op *) NULL); } t = newtp(); t->type = 0; @@ -1852,49 +2111,52 @@ thenpart() if (t->left == NULL) SYNTAXERR; t->right = elsepart(); - return(t); + return (t); } -static struct op * -elsepart() +static struct op *elsepart() { - register int c; - register struct op *t; + REGISTER int c; + REGISTER struct op *t; switch (c = yylex(0)) { case ELSE: if ((t = c_list()) == NULL) SYNTAXERR; - return(t); + return (t); case ELIF: t = newtp(); t->type = TELIF; t->left = c_list(); t->right = thenpart(); - return(t); + return (t); default: peeksym = c; - return((struct op *)NULL); + return ((struct op *) NULL); } } -static struct op * -caselist() +static struct op *caselist() { - register struct op *t; + REGISTER struct op *t; t = NULL; - while ((peeksym = yylex(CONTIN)) != ESAC) + while ((peeksym = yylex(CONTIN)) != ESAC) { + DBGPRINTF(("CASELIST, doing yylex, peeksym=%d\n", peeksym)); t = list(t, casepart()); - return(t); + } + + DBGPRINTF(("CASELIST, returning t=0x%x\n", t)); + return (t); } -static struct op * -casepart() +static struct op *casepart() { - register struct op *t; + REGISTER struct op *t; + + DBGPRINTF7(("CASEPART: enter...\n")); t = newtp(); t->type = TPAT; @@ -1903,13 +2165,15 @@ casepart() t->left = c_list(); if ((peeksym = yylex(CONTIN)) != ESAC) musthave(BREAK, CONTIN); - return(t); + + DBGPRINTF7(("CASEPART: made newtp(TPAT, t=0x%x)\n", t)); + + return (t); } -static char ** -pattern() +static char **pattern() { - register int c, cf; + REGISTER int c, cf; cf = CONTIN; do { @@ -1919,190 +2183,210 @@ pattern() } while ((c = yylex(0)) == '|'); peeksym = c; word(NOWORD); - return(copyw()); + + return (copyw()); } -static char ** -wordlist() +static char **wordlist() { - register int c; + REGISTER int c; if ((c = yylex(0)) != IN) { peeksym = c; - return((char **)NULL); + return ((char **) NULL); } startl = 0; while ((c = yylex(0)) == WORD) word(yylval.cp); word(NOWORD); peeksym = c; - return(copyw()); + return (copyw()); } /* * supporting functions */ -static struct op * -list(t1, t2) -register struct op *t1, *t2; +static struct op *list(t1, t2) +REGISTER struct op *t1, *t2; { + DBGPRINTF7(("LIST: enter, t1=0x%x, t2=0x%x\n", t1, t2)); + if (t1 == NULL) - return(t2); + return (t2); if (t2 == NULL) - return(t1); - return(block(TLIST, t1, t2, NOWORDS)); + return (t1); + + return (block(TLIST, t1, t2, NOWORDS)); } -static struct op * -block(type, t1, t2, wp) +static struct op *block(type, t1, t2, wp) int type; struct op *t1, *t2; char **wp; { - register struct op *t; + REGISTER struct op *t; + + DBGPRINTF7(("BLOCK: enter, type=%d (%s)\n", type, T_CMD_NAMES[type])); t = newtp(); t->type = type; t->left = t1; t->right = t2; t->words = wp; - return(t); + + DBGPRINTF7(("BLOCK: inserted 0x%x between 0x%x and 0x%x\n", t, t1, + t2)); + + return (t); } -static int -rlookup(n) -register char *n; +/* See if given string is a shell multiline (FOR, IF, etc) */ +static int rlookup(n) +REGISTER char *n; { - register struct res *rp; + REGISTER struct res *rp; + + DBGPRINTF7(("RLOOKUP: enter, n is %s\n", n)); for (rp = restab; rp->r_name; rp++) - if (strcmp(rp->r_name, n) == 0) - return(rp->r_val); - return(0); + if (strcmp(rp->r_name, n) == 0) { + DBGPRINTF7(("RLOOKUP: match, returning %d\n", rp->r_val)); + return (rp->r_val); /* Return numeric code for shell multiline */ + } + + DBGPRINTF7(("RLOOKUP: NO match, returning 0\n")); + return (0); /* Not a shell multiline */ } -static struct op * -newtp() +static struct op *newtp() { - register struct op *t; + REGISTER struct op *t; - t = (struct op *)tree(sizeof(*t)); + t = (struct op *) tree(sizeof(*t)); t->type = 0; t->words = NULL; t->ioact = NULL; t->left = NULL; t->right = NULL; t->str = NULL; - return(t); + + DBGPRINTF3(("NEWTP: allocated 0x%x\n", t)); + + return (t); } -static struct op * -namelist(t) -register struct op *t; +static struct op *namelist(t) +REGISTER struct op *t; { + + DBGPRINTF7(("NAMELIST: enter, t=0x%x, type %s, iolist=0x%x\n", t, + T_CMD_NAMES[t->type], iolist)); + if (iolist) { - iolist = addword((char *)NULL, iolist); + iolist = addword((char *) NULL, iolist); t->ioact = copyio(); } else t->ioact = NULL; + if (t->type != TCOM) { if (t->type != TPAREN && t->ioact != NULL) { t = block(TPAREN, t, NOBLOCK, NOWORDS); t->ioact = t->left->ioact; t->left->ioact = NULL; } - return(t); + return (t); } + word(NOWORD); t->words = copyw(); - return(t); + + + return (t); } -static char ** -copyw() +static char **copyw() { - register char **wd; + REGISTER char **wd; wd = getwords(wdlist); wdlist = 0; - return(wd); + return (wd); } -static void -word(cp) +static void word(cp) char *cp; { wdlist = addword(cp, wdlist); } -static struct ioword ** -copyio() +static struct ioword **copyio() { - register struct ioword **iop; + REGISTER struct ioword **iop; iop = (struct ioword **) getwords(iolist); iolist = 0; - return(iop); + return (iop); } -static struct ioword * -io(u, f, cp) +static struct ioword *io(u, f, cp) int u; int f; char *cp; { - register struct ioword *iop; + REGISTER struct ioword *iop; iop = (struct ioword *) tree(sizeof(*iop)); iop->io_unit = u; iop->io_flag = f; iop->io_name = cp; - iolist = addword((char *)iop, iolist); - return(iop); + iolist = addword((char *) iop, iolist); + return (iop); } -static void -zzerr() +static void zzerr() { yyerror("syntax error"); } -static void -yyerror(s) +static void yyerror(s) char *s; { yynerrs++; if (interactive && e.iop <= iostack) { multiline = 0; - while (eofc() == 0 && yylex(0) != '\n') - ; + while (eofc() == 0 && yylex(0) != '\n'); } err(s); fail(); } -static int -yylex(cf) +static int yylex(cf) int cf; { - register int c, c1; + REGISTER int c, c1; int atstart; if ((c = peeksym) > 0) { peeksym = 0; if (c == '\n') startl = 1; - return(c); + return (c); } + + nlseen = 0; - e.linep = line; atstart = startl; startl = 0; yylval.i = 0; + e.linep = line; + +/* MALAMO */ + line[LINELIM - 1] = '\0'; -loop: - while ((c = my_getc(0)) == ' ' || c == '\t') + loop: + while ((c = my_getc(0)) == ' ' || c == '\t') /* Skip whitespace */ ; + switch (c) { default: if (any(c, "0123456789")) { @@ -2116,20 +2400,21 @@ loop: } break; - case '#': - while ((c = my_getc(0)) != 0 && c != '\n') - ; + case '#': /* Comment, skip to next newline or End-of-string */ + while ((c = my_getc(0)) != 0 && c != '\n'); unget(c); goto loop; case 0: - return(c); + DBGPRINTF5(("YYLEX: return 0, c=%d\n", c)); + return (c); case '$': + DBGPRINTF9(("YYLEX: found $\n")); *e.linep++ = c; if ((c = my_getc(0)) == '{') { if ((c = collect(c, '}')) != '\0') - return(c); + return (c); goto pack; } break; @@ -2138,25 +2423,26 @@ loop: case '\'': case '"': if ((c = collect(c, c)) != '\0') - return(c); + return (c); goto pack; case '|': case '&': case ';': - if ((c1 = dual(c)) != '\0') { - startl = 1; - return(c1); - } startl = 1; - return(c); + /* If more chars process them, else return NULL char */ + if ((c1 = dual(c)) != '\0') + return (c1); + else + return (c); + case '^': startl = 1; - return('|'); + return ('|'); case '>': case '<': diag(c); - return(c); + return (c); case '\n': nlseen++; @@ -2165,117 +2451,137 @@ loop: if (multiline || cf & CONTIN) { if (interactive && e.iop <= iostack) { #ifdef CONFIG_FEATURE_COMMAND_EDITING - current_prompt=cprompt->value; + current_prompt = cprompt->value; #else - prs(cprompt->value); + prs(cprompt->value); #endif } if (cf & CONTIN) goto loop; } - return(c); + return (c); case '(': case ')': startl = 1; - return(c); + return (c); } unget(c); -pack: - while ((c = my_getc(0)) != 0 && !any(c, "`$ '\"\t;&<>()|^\n")) + pack: + while ((c = my_getc(0)) != 0 && !any(c, "`$ '\"\t;&<>()|^\n")) { if (e.linep >= elinep) err("word too long"); else *e.linep++ = c; + }; + unget(c); - if(any(c, "\"'`$")) + + if (any(c, "\"'`$")) goto loop; + *e.linep++ = '\0'; - if (atstart && (c = rlookup(line))!=0) { + + if (atstart && (c = rlookup(line)) != 0) { startl = 1; - return(c); + return (c); } + yylval.cp = strsave(line, areanum); - return(WORD); + return (WORD); } -static int -collect(c, c1) -register int c, c1; + +static int collect(c, c1) +REGISTER int c, c1; { char s[2]; + DBGPRINTF8(("COLLECT: enter, c=%d, c1=%d\n", c, c1)); + *e.linep++ = c; while ((c = my_getc(c1)) != c1) { if (c == 0) { unget(c); s[0] = c1; s[1] = 0; - prs("no closing "); yyerror(s); - return(YYERRCODE); + prs("no closing "); + yyerror(s); + return (YYERRCODE); } if (interactive && c == '\n' && e.iop <= iostack) { #ifdef CONFIG_FEATURE_COMMAND_EDITING - current_prompt=cprompt->value; + current_prompt = cprompt->value; #else - prs(cprompt->value); + prs(cprompt->value); #endif } *e.linep++ = c; } + *e.linep++ = c; - return(0); + + DBGPRINTF8(("COLLECT: return 0, line is %s\n", line)); + + return (0); } -static int -dual(c) -register int c; +/* "multiline commands" helper func */ +/* see if next 2 chars form a shell multiline */ +static int dual(c) +REGISTER int c; { char s[3]; - register char *cp = s; + REGISTER char *cp = s; - *cp++ = c; - *cp++ = my_getc(0); - *cp = 0; - if ((c = rlookup(s)) == 0) - unget(*--cp); - return(c); + DBGPRINTF8(("DUAL: enter, c=%d\n", c)); + + *cp++ = c; /* c is the given "peek" char */ + *cp++ = my_getc(0); /* get next char of input */ + *cp = 0; /* add EOS marker */ + + c = rlookup(s); /* see if 2 chars form a shell multiline */ + if (c == 0) + unget(*--cp); /* String is not a shell multiline, put peek char back */ + + return (c); /* String is multiline, return numeric multiline (restab) code */ } -static void -diag(ec) -register int ec; +static void diag(ec) +REGISTER int ec; { - register int c; + REGISTER int c; + + DBGPRINTF8(("DIAG: enter, ec=%d\n", ec)); c = my_getc(0); if (c == '>' || c == '<') { if (c != ec) zzerr(); - yylval.i = ec == '>'? IOWRITE|IOCAT: IOHERE; + yylval.i = ec == '>' ? IOWRITE | IOCAT : IOHERE; c = my_getc(0); } else - yylval.i = ec == '>'? IOWRITE: IOREAD; + yylval.i = ec == '>' ? IOWRITE : IOREAD; if (c != '&' || yylval.i == IOHERE) unget(c); else yylval.i |= IODUP; } -static char * -tree(size) +static char *tree(size) unsigned size; { - register char *t; + REGISTER char *t; if ((t = getcell(size)) == NULL) { + DBGPRINTF2(("TREE: getcell(%d) failed!\n", size)); prs("command line too complicated\n"); fail(); /* NOTREACHED */ } - return(t); + return (t); } /* VARARGS1 */ @@ -2288,57 +2594,89 @@ unsigned size; */ -static int -execute(t, pin, pout, act) -register struct op *t; +static int execute(t, pin, pout, act) +REGISTER struct op *t; int *pin, *pout; int act; { - register struct op *t1; + REGISTER struct op *t1; volatile int i, rv, a; char *cp, **wp, **wp2; struct var *vp; + struct op *outtree_save; struct brkcon bc; #if __GNUC__ /* Avoid longjmp clobbering */ (void) ℘ -#endif +#endif + if (t == NULL) { + DBGPRINTF4(("EXECUTE: enter, t==null, returning.\n")); + return (0); + } + + DBGPRINTF(("EXECUTE: t=0x%x, t->type=%d (%s), t->words is %s\n", t, + t->type, T_CMD_NAMES[t->type], + ((t->words == NULL) ? "NULL" : t->words[0]))); - if (t == NULL) - return(0); rv = 0; a = areanum++; wp = (wp2 = t->words) != NULL - ? eval(wp2, t->type == TCOM ? DOALL : DOALL & ~DOKEY) - : NULL; + ? eval(wp2, t->type == TCOM ? DOALL : DOALL & ~DOKEY) + : NULL; + +/* Hard to know how many words there are, be careful of garbage pointer values */ +/* They are likely to cause "PCI bus fault" errors */ +#if 0 + DBGPRINTF(("EXECUTE: t->left=0x%x, t->right=0x%x, t->words[1] is %s\n", + t->left, t->right, + ((t->words[1] == NULL) ? "NULL" : t->words[1]))); + DBGPRINTF7(("EXECUTE: t->words[2] is %s, t->words[3] is %s\n", + ((t->words[2] == NULL) ? "NULL" : t->words[2]), + ((t->words[3] == NULL) ? "NULL" : t->words[3]))); +#endif + + + switch (t->type) { + case TDOT: + DBGPRINTF3(("EXECUTE: TDOT\n")); + + outtree_save = outtree; + + newfile(evalstr(t->words[0], DOALL)); + + t->left = dowholefile(TLIST, 0); + t->right = NULL; + + outtree = outtree_save; + + if (t->left) + rv = execute(t->left, pin, pout, 0); + if (t->right) + rv = execute(t->right, pin, pout, 0); + break; - switch(t->type) { case TPAREN: rv = execute(t->left, pin, pout, 0); break; - + case TCOM: { - int child; - rv = forkexec(t, pin, pout, act, wp, &child); - if (child) { - exstat = rv; - leave(); - } + rv = forkexec(t, pin, pout, act, wp); } break; case TPIPE: { - int pv[2]; - if ((rv = openpipe(pv)) < 0) - break; - pv[0] = remap(pv[0]); - pv[1] = remap(pv[1]); - (void) execute(t->left, pin, pv, 0); - rv = execute(t->right, pv, pout, 0); + int pv[2]; + + if ((rv = openpipe(pv)) < 0) + break; + pv[0] = remap(pv[0]); + pv[1] = remap(pv[1]); + (void) execute(t->left, pin, pv, 0); + rv = execute(t->right, pv, pout, 0); } break; @@ -2348,54 +2686,55 @@ int act; break; case TASYNC: - { - int hinteractive = interactive; - - i = vfork(); - if (i != 0) { - interactive = hinteractive; - if (i != -1) { - setval(lookup("!"), putn(i)); - if (pin != NULL) - closepipe(pin); - if (interactive) { - prs(putn(i)); - prs("\n"); + { + int hinteractive = interactive; + + DBGPRINTF7(("EXECUTE: TASYNC clause, calling vfork()...\n")); + + i = vfork(); + if (i != 0) { + interactive = hinteractive; + if (i != -1) { + setval(lookup("!"), putn(i)); + if (pin != NULL) + closepipe(pin); + if (interactive) { + prs(putn(i)); + prs("\n"); + } + } else + rv = -1; + setstatus(rv); + } else { + signal(SIGINT, SIG_IGN); + signal(SIGQUIT, SIG_IGN); + if (interactive) + signal(SIGTERM, SIG_DFL); + interactive = 0; + if (pin == NULL) { + close(0); + open("/dev/null", 0); } - } else - rv = -1; - setstatus(rv); - } else { - signal(SIGINT, SIG_IGN); - signal(SIGQUIT, SIG_IGN); - if (interactive) - signal(SIGTERM, SIG_DFL); - interactive = 0; - if (pin == NULL) { - close(0); - open("/dev/null", 0); + _exit(execute(t->left, pin, pout, FEXEC)); } - exit(execute(t->left, pin, pout, FEXEC)); } - } break; case TOR: case TAND: rv = execute(t->left, pin, pout, 0); - if ((t1 = t->right)!=NULL && (rv == 0) == (t->type == TAND)) + if ((t1 = t->right) != NULL && (rv == 0) == (t->type == TAND)) rv = execute(t1, pin, pout, 0); break; case TFOR: if (wp == NULL) { - wp = dolv+1; + wp = dolv + 1; if ((i = dolc) < 0) i = 0; } else { i = -1; - while (*wp++ != NULL) - ; + while (*wp++ != NULL); } vp = lookup(t->str); while (setjmp(bc.brkpt)) @@ -2423,18 +2762,26 @@ int act; case TIF: case TELIF: - if (t->right != NULL) { - rv = !execute(t->left, pin, pout, 0) ? - execute(t->right->left, pin, pout, 0): - execute(t->right->right, pin, pout, 0); + if (t->right != NULL) { + rv = !execute(t->left, pin, pout, 0) ? + execute(t->right->left, pin, pout, 0) : + execute(t->right->right, pin, pout, 0); } break; case TCASE: - if ((cp = evalstr(t->str, DOSUB|DOTRIM)) == 0) + if ((cp = evalstr(t->str, DOSUB | DOTRIM)) == 0) cp = ""; - if ((t1 = findcase(t->left, cp)) != NULL) + + DBGPRINTF7(("EXECUTE: TCASE, t->str is %s, cp is %s\n", + ((t->str == NULL) ? "NULL" : t->str), + ((cp == NULL) ? "NULL" : cp))); + + if ((t1 = findcase(t->left, cp)) != NULL) { + DBGPRINTF7(("EXECUTE: TCASE, calling execute(t=0x%x, t1=0x%x)...\n", t, t1)); rv = execute(t1, pin, pout, 0); + DBGPRINTF7(("EXECUTE: TCASE, back from execute(t=0x%x, t1=0x%x)...\n", t, t1)); + } break; case TBRACE: @@ -2449,9 +2796,10 @@ int act; if (rv >= 0 && (t1 = t->left)) rv = execute(t1, pin, pout, 0); break; - } -broken: + }; + + broken: t->words = wp2; isbreak = 0; freehere(areanum); @@ -2461,31 +2809,35 @@ broken: closeall(); fail(); } + if ((i = trapset) != 0) { trapset = 0; runtrap(i); } - return(rv); + + DBGPRINTF(("EXECUTE: returning from t=0x%x, rv=%d\n", t, rv)); + return (rv); } static int -forkexec( register struct op *t, int *pin, int *pout, int act, char **wp, int *pforked) +forkexec(REGISTER struct op *t, int *pin, int *pout, int act, char **wp) { + pid_t newpid; int i, rv; - int (*shcom)(struct op *) = NULL; - register int f; + int (*shcom) (struct op *) = NULL; + REGISTER int f; char *cp = NULL; struct ioword **iopp; int resetsig; char **owp; + int forked = 0; int *hpin = pin; int *hpout = pout; - int hforked; char *hwp; int hinteractive; int hintr; - struct brkcon * hbrklist; + struct brkcon *hbrklist; int hexecflg; #if __GNUC__ @@ -2497,62 +2849,116 @@ forkexec( register struct op *t, int *pin, int *pout, int act, char **wp, int *p (void) &cp; (void) &resetsig; (void) &owp; -#endif +#endif + + DBGPRINTF(("FORKEXEC: t=0x%x, pin 0x%x, pout 0x%x, act %d\n", t, pin, + pout, act)); + DBGPRINTF7(("FORKEXEC: t->words is %s\n", + ((t->words == NULL) ? "NULL" : t->words[0]))); + +/* Hard to know how many words there are, be careful of garbage pointer values */ +/* They are likely to cause "PCI bus fault" errors */ +#if 0 + DBGPRINTF7(("FORKEXEC: t->words is %s, t->words[1] is %s\n", + ((t->words == NULL) ? "NULL" : t->words[0]), + ((t->words == NULL) ? "NULL" : t->words[1]))); + DBGPRINTF7(("FORKEXEC: wp is %s, wp[1] is %s\n", + ((wp == NULL) ? "NULL" : wp[0]), + ((wp[1] == NULL) ? "NULL" : wp[1]))); + DBGPRINTF7(("FORKEXEC: wp2 is %s, wp[3] is %s\n", + ((wp[2] == NULL) ? "NULL" : wp[2]), + ((wp[3] == NULL) ? "NULL" : wp[3]))); +#endif + owp = wp; resetsig = 0; - *pforked = 0; - rv = -1; /* system-detected error */ + rv = -1; /* system-detected error */ if (t->type == TCOM) { - while ((cp = *wp++) != NULL) - ; + while ((cp = *wp++) != NULL); cp = *wp; /* strip all initial assignments */ /* not correct wrt PATH=yyy command etc */ - if (flag['x']) - echo (cp ? wp: owp); - if (cp == NULL && t->ioact == NULL) { - while ((cp = *owp++) != NULL && assign(cp, COPYV)) - ; - return(setstatus(0)); + if (flag['x']) { + DBGPRINTF9(("FORKEXEC: echo'ing, cp=0x%x, wp=0x%x, owp=0x%x\n", + cp, wp, owp)); + echo(cp ? wp : owp); } - else if (cp != NULL) +#if 0 + DBGPRINTF9(("FORKEXEC: t->words is %s, t->words[1] is %s\n", + ((t->words == NULL) ? "NULL" : t->words[0]), + ((t->words == NULL) ? "NULL" : t->words[1]))); + DBGPRINTF9(("FORKEXEC: wp is %s, wp[1] is %s\n", + ((wp == NULL) ? "NULL" : wp[0]), + ((wp == NULL) ? "NULL" : wp[1]))); +#endif + + if (cp == NULL && t->ioact == NULL) { + while ((cp = *owp++) != NULL && assign(cp, COPYV)); + DBGPRINTF(("FORKEXEC: returning setstatus()\n")); + return (setstatus(0)); + } else if (cp != NULL) { shcom = inbuilt(cp); + } } + t->words = wp; f = act; - if (shcom == NULL && (f & FEXEC) == 0) { +#if 0 + DBGPRINTF3(("FORKEXEC: t->words is %s, t->words[1] is %s\n", + ((t->words == NULL) ? "NULL" : t->words[0]), + ((t->words == NULL) ? "NULL" : t->words[1]))); +#endif + DBGPRINTF(("FORKEXEC: shcom 0x%x, f&FEXEC 0x%x, owp 0x%x\n", shcom, + f & FEXEC, owp)); + + if (shcom == NULL && (f & FEXEC) == 0) { + /* Save values in case the child process alters them */ hpin = pin; hpout = pout; - hforked = *pforked; hwp = *wp; hinteractive = interactive; hintr = intr; hbrklist = brklist; hexecflg = execflg; - - i = vfork(); - if (i != 0) { - /* who wrote this crappy non vfork safe shit? */ + + DBGPRINTF3(("FORKEXEC: calling vfork()...\n")); + + newpid = vfork(); + + if (newpid == -1) { + DBGPRINTF(("FORKEXEC: ERROR, unable to vfork()!\n")); + return (-1); + } + + + if (newpid > 0) { /* Parent */ + + /* Restore values */ pin = hpin; pout = hpout; - *pforked = hforked; *wp = hwp; interactive = hinteractive; intr = hintr; brklist = hbrklist; execflg = hexecflg; - *pforked = 0; +/* moved up if (i == -1) return(rv); +*/ + if (pin != NULL) closepipe(pin); - return(pout==NULL? setstatus(waitfor(i,0)): 0); + + return (pout == NULL ? setstatus(waitfor(newpid, 0)) : 0); } + /* Must be the child process, pid should be 0 */ + DBGPRINTF(("FORKEXEC: child process, shcom=0x%x\n", shcom)); + if (interactive) { signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); @@ -2560,20 +2966,26 @@ forkexec( register struct op *t, int *pin, int *pout, int act, char **wp, int *p } interactive = 0; intr = 0; - (*pforked)++; + forked = 1; brklist = 0; execflg = 0; - } + } + + if (owp != NULL) while ((cp = *owp++) != NULL && assign(cp, COPYV)) if (shcom == NULL) export(lookup(cp)); + #ifdef COMPIPE if ((pin != NULL || pout != NULL) && shcom != NULL && shcom != doexec) { err("piping to/from shell builtins not yet done"); - return(-1); + if (forked) + _exit(-1); + return (-1); } #endif + if (pin != NULL) { dup2(pin[0], 0); closepipe(pin); @@ -2582,72 +2994,97 @@ forkexec( register struct op *t, int *pin, int *pout, int act, char **wp, int *p dup2(pout[1], 1); closepipe(pout); } + if ((iopp = t->ioact) != NULL) { if (shcom != NULL && shcom != doexec) { prs(cp); err(": cannot redirect shell command"); - return(-1); + if (forked) + _exit(-1); + return (-1); } while (*iopp) - if (iosetup(*iopp++, pin!=NULL, pout!=NULL)) - return(rv); + if (iosetup(*iopp++, pin != NULL, pout != NULL)) { + if (forked) + _exit(rv); + return (rv); + } + } + + if (shcom) { + i = setstatus((*shcom) (t)); + if (forked) + _exit(i); + DBGPRINTF(("FORKEXEC: returning i=%d\n", i)); + return (i); } - if (shcom) - return(setstatus((*shcom)(t))); + /* should use FIOCEXCL */ - for (i=FDBASE; itype == TPAREN) - exit(execute(t->left, NOPIPE, NOPIPE, FEXEC)); + _exit(execute(t->left, NOPIPE, NOPIPE, FEXEC)); if (wp[0] == NULL) - exit(0); + _exit(0); - cp = rexecve(wp[0], wp, makenv()); - prs(wp[0]); prs(": "); warn(cp); + cp = rexecve(wp[0], wp, makenv(0, NULL)); + prs(wp[0]); + prs(": "); + err(cp); if (!execflg) trap[0] = NULL; + + DBGPRINTF(("FORKEXEC: calling leave(), pid=%d\n", newpid)); + leave(); /* NOTREACHED */ - exit(1); + _exit(1); } /* * 0< 1> are ignored as required * within pipelines. */ -static int -iosetup(iop, pipein, pipeout) -register struct ioword *iop; +static int iosetup(iop, pipein, pipeout) +REGISTER struct ioword *iop; int pipein, pipeout; { - register int u = -1; - char *cp=NULL, *msg; + REGISTER int u = -1; + char *cp = NULL, *msg; + + DBGPRINTF(("IOSETUP: iop 0x%x, pipein 0x%x, pipeout 0x%x\n", iop, + pipein, pipeout)); if (iop->io_unit == IODEFAULT) /* take default */ - iop->io_unit = iop->io_flag&(IOREAD|IOHERE)? 0: 1; + iop->io_unit = iop->io_flag & (IOREAD | IOHERE) ? 0 : 1; + if (pipein && iop->io_unit == 0) - return(0); + return (0); + if (pipeout && iop->io_unit == 1) - return(0); - msg = iop->io_flag&(IOREAD|IOHERE)? "open": "create"; + return (0); + + msg = iop->io_flag & (IOREAD | IOHERE) ? "open" : "create"; if ((iop->io_flag & IOHERE) == 0) { cp = iop->io_name; - if ((cp = evalstr(cp, DOSUB|DOTRIM)) == NULL) - return(1); + if ((cp = evalstr(cp, DOSUB | DOTRIM)) == NULL) + return (1); } + if (iop->io_flag & IODUP) { if (cp[1] || (!isdigit(*cp) && *cp != '-')) { prs(cp); err(": illegal >& argument"); - return(1); + return (1); } if (*cp == '-') iop->io_flag = IOCLOSE; - iop->io_flag &= ~(IOREAD|IOWRITE); + iop->io_flag &= ~(IOREAD | IOWRITE); } switch (iop->io_flag) { case IOREAD: @@ -2655,14 +3092,14 @@ int pipein, pipeout; break; case IOHERE: - case IOHERE|IOXHERE: - u = herein(iop->io_name, iop->io_flag&IOXHERE); + case IOHERE | IOXHERE: + u = herein(iop->io_name, iop->io_flag & IOXHERE); cp = "here file"; break; - case IOWRITE|IOCAT: + case IOWRITE | IOCAT: if ((u = open(cp, 1)) >= 0) { - lseek(u, (long)0, 2); + lseek(u, (long) 0, 2); break; } case IOWRITE: @@ -2670,35 +3107,34 @@ int pipein, pipeout; break; case IODUP: - u = dup2(*cp-'0', iop->io_unit); + u = dup2(*cp - '0', iop->io_unit); break; case IOCLOSE: close(iop->io_unit); - return(0); + return (0); } if (u < 0) { prs(cp); prs(": cannot "); warn(msg); - return(1); + return (1); } else { if (u != iop->io_unit) { dup2(u, iop->io_unit); close(u); } } - return(0); + return (0); } -static void -echo(wp) -register char **wp; +static void echo(wp) +REGISTER char **wp; { - register int i; + REGISTER int i; prs("+"); - for (i=0; wp[i]; i++) { + for (i = 0; wp[i]; i++) { if (i) prs(" "); prs(wp[i]); @@ -2706,44 +3142,56 @@ register char **wp; prs("\n"); } -static struct op ** -find1case(t, w) +static struct op **find1case(t, w) struct op *t; char *w; { - register struct op *t1; + REGISTER struct op *t1; struct op **tp; - register char **wp, *cp; + REGISTER char **wp, *cp; + + + if (t == NULL) { + DBGPRINTF3(("FIND1CASE: enter, t==NULL, returning.\n")); + return ((struct op **) NULL); + } + + DBGPRINTF3(("FIND1CASE: enter, t->type=%d (%s)\n", t->type, + T_CMD_NAMES[t->type])); - if (t == NULL) - return((struct op **)NULL); if (t->type == TLIST) { - if ((tp = find1case(t->left, w)) != NULL) - return(tp); - t1 = t->right; /* TPAT */ + if ((tp = find1case(t->left, w)) != NULL) { + DBGPRINTF3(("FIND1CASE: found one to the left, returning tp=0x%x\n", tp)); + return (tp); + } + t1 = t->right; /* TPAT */ } else t1 = t; + for (wp = t1->words; *wp;) - if ((cp = evalstr(*wp++, DOSUB)) && gmatch(w, cp)) - return(&t1->left); - return((struct op **)NULL); + if ((cp = evalstr(*wp++, DOSUB)) && gmatch(w, cp)) { + DBGPRINTF3(("FIND1CASE: returning &t1->left= 0x%x.\n", + &t1->left)); + return (&t1->left); + } + + DBGPRINTF(("FIND1CASE: returning NULL\n")); + return ((struct op **) NULL); } -static struct op * -findcase(t, w) +static struct op *findcase(t, w) struct op *t; char *w; { - register struct op **tp; + REGISTER struct op **tp; - return((tp = find1case(t, w)) != NULL? *tp: (struct op *)NULL); + return ((tp = find1case(t, w)) != NULL ? *tp : (struct op *) NULL); } /* * Enter a new loop level (marked for break/continue). */ -static void -brkset(bc) +static void brkset(bc) struct brkcon *bc; { bc->nextlev = brklist; @@ -2757,12 +3205,11 @@ struct brkcon *bc; * Ignore interrupt signals while waiting * unless `canintr' is true. */ -static int -waitfor(lastpid, canintr) -register int lastpid; +static int waitfor(lastpid, canintr) +REGISTER int lastpid; int canintr; { - register int pid, rv; + REGISTER int pid, rv; int s; int oheedint = heedint; @@ -2788,7 +3235,9 @@ int canintr; prn(pid); prs(": "); } - prs("Signal "); prn(rv); prs(" "); + prs("Signal "); + prn(rv); + prs(" "); } if (WAITCORE(s)) prs(" - core dumped"); @@ -2805,20 +3254,20 @@ int canintr; if (canintr) intr = 0; } else { - if (exstat == 0) exstat = rv; + if (exstat == 0) + exstat = rv; onintr(0); } } - return(rv); + return (rv); } -static int -setstatus(s) -register int s; +static int setstatus(s) +REGISTER int s; { exstat = s; setval(lookup("?"), putn(s)); - return(s); + return (s); } /* @@ -2826,22 +3275,19 @@ register int s; * If getenv("PATH") were kept up-to-date, * execvp might be used. */ -static char * -rexecve(c, v, envp) +static char *rexecve(c, v, envp) char *c, **v, **envp; { - register int i; - register char *sp, *tp; + REGISTER int i; + REGISTER char *sp, *tp; int eacces = 0, asis = 0; #ifdef CONFIG_FEATURE_SH_STANDALONE_SHELL char *name = c; -#ifdef CONFIG_FEATURE_SH_APPLETS_ALWAYS_WIN - name = bb_get_last_path_component(name); -#endif + optind = 1; if (find_applet_by_name(name)) { - /* We have to exec here since we vforked. Running + /* We have to exec here since we vforked. Running * run_applet_by_name() won't work and bad things * will happen. */ execve("/proc/self/exe", v, envp); @@ -2849,7 +3295,9 @@ char *c, **v, **envp; } #endif - sp = any('/', c)? "": path->value; + DBGPRINTF(("REXECVE: c=0x%x, v=0x%x, envp=0x%x\n", c, v, envp)); + + sp = any('/', c) ? "" : path->value; asis = *sp == '\0'; while (asis || *sp != '\0') { asis = 0; @@ -2861,10 +3309,12 @@ char *c, **v, **envp; } if (tp != e.linep) *tp++ = '/'; - for (i = 0; (*tp++ = c[i++]) != '\0';) - ; + for (i = 0; (*tp++ = c[i++]) != '\0';); + + DBGPRINTF3(("REXECVE: e.linep is %s\n", e.linep)); execve(e.linep, v, envp); + switch (errno) { case ENOEXEC: *v = e.linep; @@ -2872,28 +3322,27 @@ char *c, **v, **envp; *v = e.linep; execve(DEFAULT_SHELL, v, envp); *v = tp; - return("no Shell"); + return ("no Shell"); case ENOMEM: - return((char*)bb_msg_memory_exhausted); + return ((char *) bb_msg_memory_exhausted); case E2BIG: - return("argument list too long"); + return ("argument list too long"); case EACCES: eacces++; break; } } - return(errno==ENOENT ? "not found" : "cannot execute"); + return (errno == ENOENT ? "not found" : "cannot execute"); } /* * Run the command produced by generator `f' * applied to stream `arg'. */ -static int -run(struct ioarg *argp, int (*f)(struct ioarg *)) +static int run(struct ioarg *argp, int (*f) (struct ioarg *)) { struct op *otree; struct wdblock *swdlist; @@ -2907,12 +3356,16 @@ run(struct ioarg *argp, int (*f)(struct ioarg *)) (void) &rv; #endif + DBGPRINTF(("RUN: enter, areanum %d, outtree 0x%x, failpt 0x%x\n", + areanum, outtree, failpt)); + areanum++; swdlist = wdlist; siolist = iolist; otree = outtree; ofail = failpt; rv = -1; + if (newenv(setjmp(errpt = ev)) == 0) { wdlist = 0; iolist = 0; @@ -2922,13 +3375,17 @@ run(struct ioarg *argp, int (*f)(struct ioarg *)) if (setjmp(failpt = rt) == 0 && yyparse() == 0) rv = execute(outtree, NOPIPE, NOPIPE, 0); quitenv(); + } else { + DBGPRINTF(("RUN: error from newenv()!\n")); } + wdlist = swdlist; iolist = siolist; failpt = ofail; outtree = otree; freearea(areanum--); - return(rv); + + return (rv); } /* -------- do.c -------- */ @@ -2937,7 +3394,7 @@ run(struct ioarg *argp, int (*f)(struct ioarg *)) * built-in commands: doX */ -static int dohelp(struct op *t ) +static int dohelp(struct op *t) { int col; const struct builtincmd *x; @@ -2945,7 +3402,7 @@ static int dohelp(struct op *t ) printf("\nBuilt-in commands:\n"); printf("-------------------\n"); - for (col=0, x = builtincmds; x->builtinfunc != NULL; x++) { + for (col = 0, x = builtincmds; x->builtinfunc != NULL; x++) { if (!x->name) continue; col += printf("%s%s", ((col == 0) ? "\t" : " "), x->name); @@ -2961,12 +3418,11 @@ static int dohelp(struct op *t ) extern const struct BB_applet applets[]; extern const size_t NUM_APPLETS; - for (i=0, applet = applets; i < NUM_APPLETS; applet++, i++) { + for (i = 0, applet = applets; i < NUM_APPLETS; applet++, i++) { if (!applet->name) continue; - - col += printf("%s%s", ((col == 0) ? "\t" : " "), - applet->name); + + col += printf("%s%s", ((col == 0) ? "\t" : " "), applet->name); if (col > 60) { printf("\n"); col = 0; @@ -2980,203 +3436,217 @@ static int dohelp(struct op *t ) -static int dolabel(struct op *t ) +static int dolabel(struct op *t) { - return(0); + return (0); } -static int -dochdir(t) -register struct op *t; +static int dochdir(t) +REGISTER struct op *t; { - register char *cp, *er; + REGISTER char *cp, *er; if ((cp = t->words[1]) == NULL && (cp = homedir->value) == NULL) er = ": no home directory"; - else if(chdir(cp) < 0) + else if (chdir(cp) < 0) er = ": bad directory"; else - return(0); - prs(cp != NULL? cp: "cd"); + return (0); + prs(cp != NULL ? cp : "cd"); err(er); - return(1); + return (1); } -static int -doshift(t) -register struct op *t; +static int doshift(t) +REGISTER struct op *t; { - register int n; + REGISTER int n; - n = t->words[1]? getn(t->words[1]): 1; - if(dolc < n) { + n = t->words[1] ? getn(t->words[1]) : 1; + if (dolc < n) { err("nothing to shift"); - return(1); + return (1); } dolv[n] = dolv[0]; dolv += n; dolc -= n; setval(lookup("#"), putn(dolc)); - return(0); + return (0); } /* * execute login and newgrp directly */ -static int -dologin(t) +static int dologin(t) struct op *t; { - register char *cp; + REGISTER char *cp; if (interactive) { signal(SIGINT, SIG_DFL); signal(SIGQUIT, SIG_DFL); } - cp = rexecve(t->words[0], t->words, makenv()); - prs(t->words[0]); prs(": "); err(cp); - return(1); + cp = rexecve(t->words[0], t->words, makenv(0, NULL)); + prs(t->words[0]); + prs(": "); + err(cp); + return (1); } -static int -doumask(t) -register struct op *t; +static int doumask(t) +REGISTER struct op *t; { - register int i, n; - register char *cp; + REGISTER int i, n; + REGISTER char *cp; if ((cp = t->words[1]) == NULL) { i = umask(0); umask(i); - for (n=3*4; (n-=3) >= 0;) - putc('0'+((i>>n)&07), stderr); + for (n = 3 * 4; (n -= 3) >= 0;) + putc('0' + ((i >> n) & 07), stderr); putc('\n', stderr); } else { - for (n=0; *cp>='0' && *cp<='9'; cp++) - n = n*8 + (*cp-'0'); + for (n = 0; *cp >= '0' && *cp <= '9'; cp++) + n = n * 8 + (*cp - '0'); umask(n); } - return(0); + return (0); } -static int -doexec(t) -register struct op *t; +static int doexec(t) +REGISTER struct op *t; { - register int i; + REGISTER int i; jmp_buf ex; xint *ofail; t->ioact = NULL; - for(i = 0; (t->words[i]=t->words[i+1]) != NULL; i++) - ; + for (i = 0; (t->words[i] = t->words[i + 1]) != NULL; i++); if (i == 0) - return(1); + return (1); execflg = 1; ofail = failpt; if (setjmp(failpt = ex) == 0) execute(t, NOPIPE, NOPIPE, FEXEC); failpt = ofail; execflg = 0; - return(1); + return (1); } -static int -dodot(t) +static int dodot(t) struct op *t; { - register int i; - register char *sp, *tp; + REGISTER int i; + REGISTER char *sp, *tp; char *cp; + int maltmp; + + DBGPRINTF(("DODOT: enter, t=0x%x, tleft 0x%x, tright 0x%x, e.linep is %s\n", t, t->left, t->right, ((e.linep == NULL) ? "NULL" : e.linep))); + + if ((cp = t->words[1]) == NULL) { + DBGPRINTF(("DODOT: bad args, ret 0\n")); + return (0); + } else { + DBGPRINTF(("DODOT: cp is %s\n", cp)); + } + + sp = any('/', cp) ? ":" : path->value; + + DBGPRINTF(("DODOT: sp is %s, e.linep is %s\n", + ((sp == NULL) ? "NULL" : sp), + ((e.linep == NULL) ? "NULL" : e.linep))); - if ((cp = t->words[1]) == NULL) - return(0); - sp = any('/', cp)? ":": path->value; while (*sp) { tp = e.linep; while (*sp && (*tp = *sp++) != ':') tp++; if (tp != e.linep) *tp++ = '/'; - for (i = 0; (*tp++ = cp[i++]) != '\0';) - ; + + for (i = 0; (*tp++ = cp[i++]) != '\0';); + + /* Original code */ if ((i = open(e.linep, 0)) >= 0) { exstat = 0; - next(remap(i)); - return(exstat); + maltmp = remap(i); + DBGPRINTF(("DODOT: remap=%d, exstat=%d, e.iofd %d, i %d, e.linep is %s\n", maltmp, exstat, e.iofd, i, e.linep)); + + next(maltmp); /* Basically a PUSHIO */ + + DBGPRINTF(("DODOT: returning exstat=%d\n", exstat)); + + return (exstat); } - } + + } /* While */ + prs(cp); err(": not found"); - return(-1); + + return (-1); } -static int -dowait(t) +static int dowait(t) struct op *t; { - register int i; - register char *cp; + REGISTER int i; + REGISTER char *cp; if ((cp = t->words[1]) != NULL) { i = getn(cp); if (i == 0) - return(0); + return (0); } else i = -1; setstatus(waitfor(i, 1)); - return(0); + return (0); } -static int -doread(t) +static int doread(t) struct op *t; { - register char *cp, **wp; - register int nb = 0; - register int nl = 0; + REGISTER char *cp, **wp; + REGISTER int nb = 0; + REGISTER int nl = 0; if (t->words[1] == NULL) { err("Usage: read name ..."); - return(1); + return (1); } - for (wp = t->words+1; *wp; wp++) { - for (cp = e.linep; !nl && cp < elinep-1; cp++) + for (wp = t->words + 1; *wp; wp++) { + for (cp = e.linep; !nl && cp < elinep - 1; cp++) if ((nb = read(0, cp, sizeof(*cp))) != sizeof(*cp) || - (nl = (*cp == '\n')) || - (wp[1] && any(*cp, ifs->value))) + (nl = (*cp == '\n')) || (wp[1] && any(*cp, ifs->value))) break; *cp = 0; if (nb <= 0) break; setval(lookup(*wp), e.linep); } - return(nb <= 0); + return (nb <= 0); } -static int -doeval(t) -register struct op *t; +static int doeval(t) +REGISTER struct op *t; { - return(RUN(awordlist, t->words+1, wdchar)); + return (RUN(awordlist, t->words + 1, wdchar)); } -static int -dotrap(t) -register struct op *t; +static int dotrap(t) +REGISTER struct op *t; { - register int n, i; - register int resetsig; + REGISTER int n, i; + REGISTER int resetsig; if (t->words[1] == NULL) { - for (i=0; i<=_NSIG; i++) + for (i = 0; i <= _NSIG; i++) if (trap[i]) { prn(i); prs(": "); prs(trap[i]); prs("\n"); } - return(0); + return (0); } resetsig = isdigit(*t->words[1]); for (i = resetsig ? 1 : 2; t->words[i] != NULL; ++i) { @@ -3194,30 +3664,27 @@ register struct op *t; if (n == SIGINT) setsig(n, onintr); else - setsig(n, n == SIGQUIT ? SIG_IGN - : SIG_DFL); + setsig(n, n == SIGQUIT ? SIG_IGN : SIG_DFL); else setsig(n, SIG_DFL); } } - return(0); + return (0); } -static int -getsig(s) +static int getsig(s) char *s; { - register int n; + REGISTER int n; if ((n = getn(s)) < 0 || n > _NSIG) { err("trap: bad signal number"); n = 0; } - return(n); + return (n); } -static void -setsig( register int n, sighandler_t f) +static void setsig(REGISTER int n, sighandler_t f) { if (n == 0) return; @@ -3227,12 +3694,11 @@ setsig( register int n, sighandler_t f) } } -static int -getn(as) +static int getn(as) char *as; { - register char *s; - register int n, m; + REGISTER char *s; + REGISTER int n, m; s = as; m = 1; @@ -3241,37 +3707,34 @@ char *as; s++; } for (n = 0; isdigit(*s); s++) - n = (n*10) + (*s-'0'); + n = (n * 10) + (*s - '0'); if (*s) { prs(as); err(": bad number"); } - return(n*m); + return (n * m); } -static int -dobreak(t) +static int dobreak(t) struct op *t; { - return(brkcontin(t->words[1], 1)); + return (brkcontin(t->words[1], 1)); } -static int -docontinue(t) +static int docontinue(t) struct op *t; { - return(brkcontin(t->words[1], 0)); + return (brkcontin(t->words[1], 0)); } -static int -brkcontin(cp, val) -register char *cp; +static int brkcontin(cp, val) +REGISTER char *cp; int val; { - register struct brkcon *bc; - register int nl; + REGISTER struct brkcon *bc; + REGISTER int nl; - nl = cp == NULL? 1: getn(cp); + nl = cp == NULL ? 1 : getn(cp); if (nl <= 0) nl = 999; do { @@ -3281,56 +3744,59 @@ int val; } while (--nl); if (nl) { err("bad break/continue level"); - return(1); + return (1); } isbreak = val; longjmp(bc->brkpt, 1); /* NOTREACHED */ } -static int -doexit(t) +static int doexit(t) struct op *t; { - register char *cp; + REGISTER char *cp; execflg = 0; if ((cp = t->words[1]) != NULL) setstatus(getn(cp)); + + DBGPRINTF(("DOEXIT: calling leave(), t=0x%x\n", t)); + leave(); /* NOTREACHED */ - return(0); + return (0); } -static int -doexport(t) +static int doexport(t) struct op *t; { - rdexp(t->words+1, export, EXPORT); - return(0); + rdexp(t->words + 1, export, EXPORT); + return (0); } -static int -doreadonly(t) +static int doreadonly(t) struct op *t; { - rdexp(t->words+1, ronly, RONLY); - return(0); + rdexp(t->words + 1, ronly, RONLY); + return (0); } -static void rdexp (char **wp, void (*f)(struct var *), int key) +static void rdexp(char **wp, void (*f) (struct var *), int key) { + DBGPRINTF6(("RDEXP: enter, wp=0x%x, func=0x%x, key=%d\n", wp, f, key)); + DBGPRINTF6(("RDEXP: *wp=%s\n", *wp)); + if (*wp != NULL) { for (; *wp != NULL; wp++) { if (isassign(*wp)) { char *cp; + assign(*wp, COPYV); - for (cp = *wp; *cp != '='; cp++) - ; + for (cp = *wp; *cp != '='; cp++); *cp = '\0'; } if (checkname(*wp)) - (*f)(lookup(*wp)); + (*f) (lookup(*wp)); else badid(*wp); } @@ -3338,31 +3804,28 @@ static void rdexp (char **wp, void (*f)(struct var *), int key) putvlist(key, 1); } -static void -badid(s) -register char *s; +static void badid(s) +REGISTER char *s; { prs(s); err(": bad identifier"); } -static int -doset(t) -register struct op *t; +static int doset(t) +REGISTER struct op *t; { - register struct var *vp; - register char *cp; - register int n; + REGISTER struct var *vp; + REGISTER char *cp; + REGISTER int n; if ((cp = t->words[1]) == NULL) { for (vp = vlist; vp; vp = vp->next) varput(vp->name, 1); - return(0); + return (0); } if (*cp == '-') { /* bad: t->words++; */ - for(n = 0; (t->words[n]=t->words[n+1]) != NULL; n++) - ; + for (n = 0; (t->words[n] = t->words[n + 1]) != NULL; n++); if (*++cp == 0) flag['x'] = flag['v'] = 0; else @@ -3374,27 +3837,26 @@ register struct op *t; break; default: - if (*cp>='a' && *cp<='z') - flag[(int)*cp]++; + if (*cp >= 'a' && *cp <= 'z') + flag[(int) *cp]++; break; } setdash(); } if (t->words[1]) { t->words[0] = dolv[0]; - for (n=1; t->words[n]; n++) - setarea((char *)t->words[n], 0); - dolc = n-1; + for (n = 1; t->words[n]; n++) + setarea((char *) t->words[n], 0); + dolc = n - 1; dolv = t->words; setval(lookup("#"), putn(dolc)); - setarea((char *)(dolv-1), 0); + setarea((char *) (dolv - 1), 0); } - return(0); + return (0); } -static void -varput(s, out) -register char *s; +static void varput(s, out) +REGISTER char *s; int out; { if (isalnum(*s) || *s == '_') { @@ -3408,34 +3870,33 @@ int out; * Copyright (c) 1999 Herbert Xu * This file contains code for the times builtin. */ -static int dotimes(struct op *t ) +static int dotimes(struct op *t) { struct tms buf; long int clk_tck = sysconf(_SC_CLK_TCK); times(&buf); printf("%dm%fs %dm%fs\n%dm%fs %dm%fs\n", - (int) (buf.tms_utime / clk_tck / 60), - ((double) buf.tms_utime) / clk_tck, - (int) (buf.tms_stime / clk_tck / 60), - ((double) buf.tms_stime) / clk_tck, - (int) (buf.tms_cutime / clk_tck / 60), - ((double) buf.tms_cutime) / clk_tck, - (int) (buf.tms_cstime / clk_tck / 60), - ((double) buf.tms_cstime) / clk_tck); + (int) (buf.tms_utime / clk_tck / 60), + ((double) buf.tms_utime) / clk_tck, + (int) (buf.tms_stime / clk_tck / 60), + ((double) buf.tms_stime) / clk_tck, + (int) (buf.tms_cutime / clk_tck / 60), + ((double) buf.tms_cutime) / clk_tck, + (int) (buf.tms_cstime / clk_tck / 60), + ((double) buf.tms_cstime) / clk_tck); return 0; } -static int(*inbuilt(char *s))(struct op *) -{ +static int (*inbuilt(char *s)) (struct op *) { const struct builtincmd *bp; for (bp = builtincmds; bp->name != NULL; bp++) if (strcmp(bp->name, s) == 0) - return(bp->builtinfunc); + return (bp->builtinfunc); - return(NULL); + return (NULL); } /* -------- eval.c -------- */ @@ -3448,7 +3909,7 @@ static int(*inbuilt(char *s))(struct op *) * glob */ -static char ** eval( char **ap, int f) +static char **eval(char **ap, int f) { struct wdblock *wb; char **wp; @@ -3460,6 +3921,9 @@ static char ** eval( char **ap, int f) (void) ℘ (void) ≈ #endif + + DBGPRINTF4(("EVAL: enter, f=%d\n", f)); + wp = NULL; wb = NULL; wf = NULL; @@ -3472,16 +3936,17 @@ static char ** eval( char **ap, int f) expand(*wf, &wb, f & ~DOGLOB); } } - for (wb = addword((char *)0, wb); *ap; ap++) { + for (wb = addword((char *) 0, wb); *ap; ap++) { if (!flag['k'] || !isassign(*ap)) expand(*ap, &wb, f & ~DOKEY); } - wb = addword((char *)0, wb); + wb = addword((char *) 0, wb); wp = getwords(wb); quitenv(); } else gflg = 1; - return(gflg? (char **)NULL: wp); + + return (gflg ? (char **) NULL : wp); } /* @@ -3489,40 +3954,39 @@ static char ** eval( char **ap, int f) * names in the dictionary. Keyword assignments * will already have been done. */ -static char ** -makenv() - +static char **makenv(int all, struct wdblock *wb) { - register struct wdblock *wb; - register struct var *vp; + REGISTER struct var *vp; + + DBGPRINTF5(("MAKENV: enter, all=%d\n", all)); - wb = NULL; for (vp = vlist; vp; vp = vp->next) - if (vp->status & EXPORT) + if (all || vp->status & EXPORT) wb = addword(vp->name, wb); - wb = addword((char *)0, wb); - return(getwords(wb)); + wb = addword((char *) 0, wb); + return (getwords(wb)); } -static char * -evalstr(cp, f) -register char *cp; +static char *evalstr(cp, f) +REGISTER char *cp; int f; { struct wdblock *wb; + DBGPRINTF6(("EVALSTR: enter, cp=0x%x, f=%d\n", cp, f)); + wb = NULL; if (expand(cp, &wb, f)) { - if (wb == NULL || wb->w_nword == 0 || (cp = wb->w_words[0]) == NULL) + if (wb == NULL || wb->w_nword == 0 + || (cp = wb->w_words[0]) == NULL) cp = ""; DELETE(wb); } else cp = NULL; - return(cp); + return (cp); } -static int -expand( char *cp, register struct wdblock **wbp, int f) +static int expand(char *cp, REGISTER struct wdblock **wbp, int f) { jmp_buf ev; @@ -3530,17 +3994,21 @@ expand( char *cp, register struct wdblock **wbp, int f) /* Avoid longjmp clobbering */ (void) &cp; #endif + + DBGPRINTF3(("EXPAND: enter, f=%d\n", f)); + gflg = 0; + if (cp == NULL) - return(0); + return (0); + if (!anys("$`'\"", cp) && - !anys(ifs->value, cp) && - ((f&DOGLOB)==0 || !anys("[*?", cp))) { + !anys(ifs->value, cp) && ((f & DOGLOB) == 0 || !anys("[*?", cp))) { cp = strsave(cp, areanum); if (f & DOTRIM) unquote(cp); *wbp = addword(cp, *wbp); - return(1); + return (1); } if (newenv(setjmp(errpt = ev)) == 0) { PUSHIO(aword, cp, strchar); @@ -3548,7 +4016,7 @@ expand( char *cp, register struct wdblock **wbp, int f) while ((cp = blank(f)) && gflg == 0) { e.linep = cp; cp = strsave(cp, areanum); - if ((f&DOGLOB) == 0) { + if ((f & DOGLOB) == 0) { if (f & DOTRIM) unquote(cp); *wbp = addword(cp, *wbp); @@ -3558,31 +4026,32 @@ expand( char *cp, register struct wdblock **wbp, int f) quitenv(); } else gflg = 1; - return(gflg == 0); + return (gflg == 0); } /* * Blank interpretation and quoting */ -static char * -blank(f) +static char *blank(f) int f; { - register int c, c1; - register char *sp; + REGISTER int c, c1; + REGISTER char *sp; int scanequals, foundequals; + DBGPRINTF3(("BLANK: enter, f=%d\n", f)); + sp = e.linep; scanequals = f & DOKEY; foundequals = 0; -loop: + loop: switch (c = subgetc('"', foundequals)) { case 0: if (sp == e.linep) - return(0); + return (0); *e.linep++ = 0; - return(sp); + return (sp); default: if (f & DOBLANK && any(c, ifs->value)) @@ -3609,9 +4078,9 @@ loop: for (;;) { c = subgetc('"', foundequals); if (c == 0 || - f & (DOBLANK && any(c, ifs->value)) || - (!INSUB() && any(c, "\"'"))) { - scanequals = 0; + f & (DOBLANK && any(c, ifs->value)) || + (!INSUB() && any(c, "\"'"))) { + scanequals = 0; unget(c); if (any(c, "\"'")) goto loop; @@ -3620,33 +4089,33 @@ loop: if (scanequals) { if (c == '=') { foundequals = 1; - scanequals = 0; - } - else if (!isalnum(c) && c != '_') + scanequals = 0; + } else if (!isalnum(c) && c != '_') scanequals = 0; } *e.linep++ = c; } *e.linep++ = 0; - return(sp); + return (sp); } /* * Get characters, substituting for ` and $ */ -static int -subgetc(ec, quoted) -register char ec; +static int subgetc(ec, quoted) +REGISTER char ec; int quoted; { - register char c; + REGISTER char c; -again: + DBGPRINTF3(("SUBGETC: enter, quoted=%d\n", quoted)); + + again: c = my_getc(ec); if (!INSUB() && ec != '\'') { if (c == '`') { if (grave(quoted) == 0) - return(0); + return (0); e.iop->task = XGRAVE; goto again; } @@ -3655,28 +4124,29 @@ again: goto again; } } - return(c); + return (c); } /* * Prepare to generate the string returned by ${} substitution. */ -static int -dollar(quoted) +static int dollar(quoted) int quoted; { int otask; struct io *oiop; char *dolp; - register char *s, c, *cp=NULL; + REGISTER char *s, c, *cp = NULL; struct var *vp; + DBGPRINTF3(("DOLLAR: enter, quoted=%d\n", quoted)); + c = readc(); s = e.linep; if (c != '{') { *e.linep++ = c; if (isalpha(c) || c == '_') { - while ((c = readc())!=0 && (isalnum(c) || c == '_')) + while ((c = readc()) != 0 && (isalnum(c) || c == '_')) if (e.linep < elinep) *e.linep++ = c; unget(c); @@ -3685,8 +4155,9 @@ int quoted; } else { oiop = e.iop; otask = e.iop->task; + e.iop->task = XOTHER; - while ((c = subgetc('"', 0))!=0 && c!='}' && c!='\n') + while ((c = subgetc('"', 0)) != 0 && c != '}' && c != '\n') if (e.linep < elinep) *e.linep++ = c; if (oiop == e.iop) @@ -3694,7 +4165,7 @@ int quoted; if (c != '}') { err("unclosed ${"); gflg++; - return(c); + return (c); } } if (e.linep >= elinep) { @@ -3704,7 +4175,7 @@ int quoted; } *e.linep = 0; if (*s) - for (cp = s+1; *cp; cp++) + for (cp = s + 1; *cp; cp++) if (any(*cp, "=-+?")) { c = *cp; *cp++ = 0; @@ -3715,9 +4186,9 @@ int quoted; /* currently this does not distinguish $* and $@ */ /* should check dollar */ e.linep = s; - PUSHIO(awordlist, dolv+1, dolchar); - return(0); - } else { /* trap the nasty ${=} */ + PUSHIO(awordlist, dolv + 1, dolchar); + return (0); + } else { /* trap the nasty ${=} */ s[0] = '1'; s[1] = 0; } @@ -3757,19 +4228,18 @@ int quoted; } e.linep = s; PUSHIO(aword, dolp, quoted ? qstrchar : strchar); - return(0); + return (0); } /* * Run the command in `...` and read its output. */ -static int -grave(quoted) +static int grave(quoted) int quoted; { char *cp; - register int i; + REGISTER int i; int j; int pf[2]; static char child_cmd[LINELIM]; @@ -3779,16 +4249,17 @@ int quoted; int ignore; int ignore_once; char *argument_list[4]; + struct wdblock *wb = NULL; #if __GNUC__ /* Avoid longjmp clobbering */ (void) &cp; #endif - + for (cp = e.iop->argp->aword; *cp != '`'; cp++) if (*cp == 0) { err("no closing `"); - return(0); + return (0); } /* string copy with dollar expansion */ @@ -3831,13 +4302,13 @@ int quoted; case '=': case '+': case '?': - operator = *src; + operator = * src; break; default: err("unclosed ${\n"); - return(0); + return (0); } - if (operator) { + if (operator) { src++; while (*src && (*src != '}')) { alt_value[alt_index++] = *src++; @@ -3845,28 +4316,53 @@ int quoted; alt_value[alt_index] = 0; if (*src != '}') { err("unclosed ${\n"); - return(0); + return (0); } } src++; } - vp = lookup(var_name); - if (vp->value != null) - value = (operator == '+')? alt_value : vp->value; - else if (operator == '?') { - err(alt_value); - return(0); - } else if (alt_index && (operator != '+')) { - value = alt_value; - if (operator == '=') - setval(vp, value); - } else - continue; + if (isalpha(*var_name)) { + /* let subshell handle it instead */ + + char *namep = var_name; + + *dest++ = '$'; + if (braces) + *dest++ = '{'; + while (*namep) + *dest++ = *namep++; + if (operator) { + char *altp = alt_value; + *dest++ = operator; + while (*altp) + *dest++ = *altp++; + } + if (braces) + *dest++ = '}'; + + wb = addword(lookup(var_name)->name, wb); + } else { + /* expand */ + + vp = lookup(var_name); + if (vp->value != null) + value = (operator == '+') ? + alt_value : vp->value; + else if (operator == '?') { + err(alt_value); + return (0); + } else if (alt_index && (operator != '+')) { + value = alt_value; + if (operator == '=') + setval(vp, value); + } else + continue; - while (*value && (count < LINELIM)) { - *dest++ = *value++; - count++; + while (*value && (count < LINELIM)) { + *dest++ = *value++; + count++; + } } } else { *dest++ = *src++; @@ -3875,52 +4371,59 @@ int quoted; } } *dest = '\0'; - + if (openpipe(pf) < 0) - return(0); - while ((i = vfork()) == -1 && errno == EAGAIN) - ; + return (0); + + while ((i = vfork()) == -1 && errno == EAGAIN); + + DBGPRINTF3(("GRAVE: i is %d\n", io)); + if (i < 0) { closepipe(pf); - err((char*)bb_msg_memory_exhausted); - return(0); + err((char *) bb_msg_memory_exhausted); + return (0); } if (i != 0) { waitpid(i, NULL, 0); e.iop->argp->aword = ++cp; close(pf[1]); - PUSHIO(afile, remap(pf[0]), (int(*)(struct ioarg *))((quoted)? qgravechar: gravechar)); - return(1); + PUSHIO(afile, remap(pf[0]), + (int (*)(struct ioarg *)) ((quoted) ? qgravechar : + gravechar)); + return (1); } /* allow trapped signals */ /* XXX - Maybe this signal stuff should go as well? */ - for (j=0; j<=_NSIG; j++) + for (j = 0; j <= _NSIG; j++) if (ourtrap[j] && signal(j, SIG_IGN) != SIG_IGN) signal(j, SIG_DFL); - + dup2(pf[1], 1); closepipe(pf); - argument_list[0] = (char *)DEFAULT_SHELL; + argument_list[0] = (char *) DEFAULT_SHELL; argument_list[1] = "-c"; argument_list[2] = child_cmd; argument_list[3] = 0; - prs(rexecve(argument_list[0], argument_list, makenv())); + cp = rexecve(argument_list[0], argument_list, makenv(1, wb)); + prs(argument_list[0]); + prs(": "); + err(cp); _exit(1); } -static char * -unquote(as) -register char *as; +static char *unquote(as) +REGISTER char *as; { - register char *s; + REGISTER char *s; if ((s = as) != NULL) while (*s) *s++ &= ~QUOTE; - return(as); + return (as); } /* -------- glob.c -------- */ @@ -3933,19 +4436,18 @@ register char *as; #define BLKSIZ 512 #define NDENT ((BLKSIZ+sizeof(struct dirent)-1)/sizeof(struct dirent)) -static struct wdblock *cl, *nl; -static char spcl[] = "[?*"; +static struct wdblock *cl, *nl; +static char spcl[] = "[?*"; -static struct wdblock * -glob(cp, wb) +static struct wdblock *glob(cp, wb) char *cp; struct wdblock *wb; { - register int i; - register char *pp; + REGISTER int i; + REGISTER char *pp; if (cp == 0) - return(wb); + return (wb); i = 0; for (pp = cp; *pp; pp++) if (any(*pp, spcl)) @@ -3953,9 +4455,10 @@ struct wdblock *wb; else if (!any(*pp & ~QUOTE, spcl)) *pp &= ~QUOTE; if (i != 0) { - for (cl = addword(scopy(cp), (struct wdblock *)0); anyspcl(cl); cl = nl) { - nl = newword(cl->w_nword*2); - for(i=0; iw_nword; i++) { /* for each argument */ + for (cl = addword(scopy(cp), (struct wdblock *) 0); anyspcl(cl); + cl = nl) { + nl = newword(cl->w_nword * 2); + for (i = 0; i < cl->w_nword; i++) { /* for each argument */ for (pp = cl->w_words[i]; *pp; pp++) if (any(*pp, spcl)) { globname(cl->w_words[i], pp); @@ -3964,45 +4467,44 @@ struct wdblock *wb; if (*pp == '\0') nl = addword(scopy(cl->w_words[i]), nl); } - for(i=0; iw_nword; i++) + for (i = 0; i < cl->w_nword; i++) DELETE(cl->w_words[i]); DELETE(cl); } - for(i=0; iw_nword; i++) + for (i = 0; i < cl->w_nword; i++) unquote(cl->w_words[i]); - glob0((char *)cl->w_words, cl->w_nword, sizeof(char *), xstrcmp); + glob0((char *) cl->w_words, cl->w_nword, sizeof(char *), xstrcmp); if (cl->w_nword) { - for (i=0; iw_nword; i++) + for (i = 0; i < cl->w_nword; i++) wb = addword(cl->w_words[i], wb); DELETE(cl); - return(wb); + return (wb); } } wb = addword(unquote(cp), wb); - return(wb); + return (wb); } -static void -globname(we, pp) +static void globname(we, pp) char *we; -register char *pp; +REGISTER char *pp; { - register char *np, *cp; + REGISTER char *np, *cp; char *name, *gp, *dp; int k; DIR *dirp; struct dirent *de; - char dname[NAME_MAX+1]; + char dname[NAME_MAX + 1]; struct stat dbuf; for (np = we; np != pp; pp--) if (pp[-1] == '/') break; - for (dp = cp = space((int)(pp-np)+3); np < pp;) + for (dp = cp = space((int) (pp - np) + 3); np < pp;) *cp++ = *np++; *cp++ = '.'; *cp = '\0'; - for (gp = cp = space(strlen(pp)+1); *np && *np != '/';) + for (gp = cp = space(strlen(pp) + 1); *np && *np != '/';) *cp++ = *np++; *cp = '\0'; dirp = opendir(dp); @@ -4012,29 +4514,29 @@ register char *pp; return; } dname[NAME_MAX] = '\0'; - while ((de=readdir(dirp))!=NULL) { + while ((de = readdir(dirp)) != NULL) { /* XXX Hmmm... What this could be? (abial) */ /* - if (ent[j].d_ino == 0) - continue; - */ + if (ent[j].d_ino == 0) + continue; + */ strncpy(dname, de->d_name, NAME_MAX); - if (dname[0] == '.') - if (*gp != '.') + if (dname[0] == '.') + if (*gp != '.') + continue; + for (k = 0; k < NAME_MAX; k++) + if (any(dname[k], spcl)) + dname[k] |= QUOTE; + if (gmatch(dname, gp)) { + name = generate(we, pp, dname, np); + if (*np && !anys(np, spcl)) { + if (stat(name, &dbuf)) { + DELETE(name); continue; - for(k=0; kw_words; - for (i=0; iw_nword; i++) + for (i = 0; i < wb->w_nword; i++) if (anys(spcl, *wd++)) - return(1); - return(0); + return (1); + return (0); } -static int -xstrcmp(p1, p2) +static int xstrcmp(p1, p2) char *p1, *p2; { - return(strcmp(*(char **)p1, *(char **)p2)); + return (strcmp(*(char **) p1, *(char **) p2)); } /* -------- word.c -------- */ -static struct wdblock * -newword(nw) -register int nw; +static struct wdblock *newword(nw) +REGISTER int nw; { - register struct wdblock *wb; + REGISTER struct wdblock *wb; - wb = (struct wdblock *) space(sizeof(*wb) + nw*sizeof(char *)); + wb = (struct wdblock *) space(sizeof(*wb) + nw * sizeof(char *)); wb->w_bsize = nw; wb->w_nword = 0; - return(wb); + return (wb); } -static struct wdblock * -addword(wd, wb) +static struct wdblock *addword(wd, wb) char *wd; -register struct wdblock *wb; +REGISTER struct wdblock *wb; { - register struct wdblock *wb2; - register int nw; + REGISTER struct wdblock *wb2; + REGISTER int nw; if (wb == NULL) wb = newword(NSTART); if ((nw = wb->w_nword) >= wb->w_bsize) { wb2 = newword(nw * 2); - memcpy((char *)wb2->w_words, (char *)wb->w_words, nw*sizeof(char *)); + memcpy((char *) wb2->w_words, (char *) wb->w_words, + nw * sizeof(char *)); wb2->w_nword = nw; DELETE(wb); wb = wb2; } wb->w_words[wb->w_nword++] = wd; - return(wb); + return (wb); } -static -char ** -getwords(wb) -register struct wdblock *wb; + +static +char **getwords(wb) +REGISTER struct wdblock *wb; { - register char **wd; - register int nb; + REGISTER char **wd; + REGISTER int nb; if (wb == NULL) - return((char **)NULL); + return ((char **) NULL); if (wb->w_nword == 0) { DELETE(wb); - return((char **)NULL); + return ((char **) NULL); } wd = (char **) space(nb = sizeof(*wd) * wb->w_nword); - memcpy((char *)wd, (char *)wb->w_words, nb); - DELETE(wb); /* perhaps should done by caller */ - return(wd); + memcpy((char *) wd, (char *) wb->w_words, nb); + DELETE(wb); /* perhaps should done by caller */ + return (wd); } -int (*func)(char *, char *); -int globv; +int (*func) (char *, char *); +int globv; -static void -glob0(a0, a1, a2, a3) +static void glob0(a0, a1, a2, a3) char *a0; unsigned a1; int a2; @@ -4156,11 +4652,10 @@ int (*a3) (char *, char *); glob1(a0, a0 + a1 * a2); } -static void -glob1(base, lim) +static void glob1(base, lim) char *base, *lim; { - register char *i, *j; + REGISTER char *i, *j; int v2; char *lptr, *hptr; int c; @@ -4169,16 +4664,16 @@ char *base, *lim; v2 = globv; -top: - if ((n=(int)(lim-base)) <= v2) + top: + if ((n = (int) (lim - base)) <= v2) return; - n = v2 * (n / (2*v2)); - hptr = lptr = base+n; + n = v2 * (n / (2 * v2)); + hptr = lptr = base + n; i = base; - j = lim-v2; - for(;;) { + j = lim - v2; + for (;;) { if (i < lptr) { - if ((c = (*func)(i, lptr)) == 0) { + if ((c = (*func) (i, lptr)) == 0) { glob2(i, lptr -= v2); continue; } @@ -4188,9 +4683,9 @@ top: } } -begin: + begin: if (j > hptr) { - if ((c = (*func)(hptr, j)) == 0) { + if ((c = (*func) (hptr, j)) == 0) { glob2(hptr += v2, j); goto begin; } @@ -4211,12 +4706,12 @@ begin: if (i == lptr) { - if (lptr-base >= lim-hptr) { - glob1(hptr+v2, lim); + if (lptr - base >= lim - hptr) { + glob1(hptr + v2, lim); lim = lptr; } else { glob1(base, lptr); - base = hptr+v2; + base = hptr + v2; } goto top; } @@ -4227,11 +4722,10 @@ begin: } } -static void -glob2(i, j) +static void glob2(i, j) char *i, *j; { - register char *index1, *index2, c; + REGISTER char *index1, *index2, c; int m; m = globv; @@ -4241,14 +4735,13 @@ char *i, *j; c = *index1; *index1++ = *index2; *index2++ = c; - } while(--m); + } while (--m); } -static void -glob3(i, j, k) +static void glob3(i, j, k) char *i, *j, *k; { - register char *index1, *index2, *index3; + REGISTER char *index1, *index2, *index3; int c; int m; @@ -4261,7 +4754,7 @@ char *i, *j, *k; *index1++ = *index3; *index3++ = *index2; *index2++ = c; - } while(--m); + } while (--m); } /* -------- io.c -------- */ @@ -4270,146 +4763,177 @@ char *i, *j, *k; * shell IO */ -static int my_getc( int ec) +static int my_getc(int ec) { - register int c; + REGISTER int c; - if(e.linep > elinep) { - while((c=readc()) != '\n' && c) - ; + if (e.linep > elinep) { + while ((c = readc()) != '\n' && c); err("input line too long"); gflg++; - return(c); + return (c); } c = readc(); if ((ec != '\'') && (ec != '`') && (e.iop->task != XGRAVE)) { - if(c == '\\') { + if (c == '\\') { c = readc(); if (c == '\n' && ec != '\"') - return(my_getc(ec)); + return (my_getc(ec)); c |= QUOTE; } } - return(c); + return (c); } -static void -unget(c) +static void unget(c) int c; { if (e.iop >= e.iobase) e.iop->peekc = c; } -static int -eofc() - +static int eofc() { - return e.iop < e.iobase || (e.iop->peekc == 0 && e.iop->prev == 0); + return e.iop < e.iobase || (e.iop->peekc == 0 && e.iop->prev == 0); } -static int -readc() +static int readc() { - register int c; + REGISTER int c; - for (; e.iop >= e.iobase; e.iop--) + RCPRINTF(("READC: e.iop 0x%x, e.iobase 0x%x\n", e.iop, e.iobase)); + + for (; e.iop >= e.iobase; e.iop--) { + RCPRINTF(("READC: e.iop 0x%x, peekc 0x%x\n", e.iop, e.iop->peekc)); if ((c = e.iop->peekc) != '\0') { e.iop->peekc = 0; - return(c); - } - else { - if (e.iop->prev != 0) { - if ((c = (*e.iop->iofn)(e.iop->argp, e.iop)) != '\0') { - if (c == -1) { - e.iop++; - continue; - } - if (e.iop == iostack) - ioecho(c); - return(e.iop->prev = c); - } - else if (e.iop->task == XIO && e.iop->prev != '\n') { - e.iop->prev = 0; - if (e.iop == iostack) - ioecho('\n'); - return '\n'; - } - } - if (e.iop->task == XIO) { - if (multiline) - return e.iop->prev = 0; - if (interactive && e.iop == iostack+1) { + return (c); + } else { + if (e.iop->prev != 0) { + if ((c = (*e.iop->iofn) (e.iop->argp, e.iop)) != '\0') { + if (c == -1) { + e.iop++; + continue; + } + if (e.iop == iostack) + ioecho(c); + return (e.iop->prev = c); + } else if (e.iop->task == XIO && e.iop->prev != '\n') { + e.iop->prev = 0; + if (e.iop == iostack) + ioecho('\n'); + return '\n'; + } + } + if (e.iop->task == XIO) { + if (multiline) { + return e.iop->prev = 0; + } + if (interactive && e.iop == iostack + 1) { #ifdef CONFIG_FEATURE_COMMAND_EDITING - current_prompt=prompt->value; + current_prompt = prompt->value; #else - prs(prompt->value); + prs(prompt->value); #endif + } } - } } - if (e.iop >= iostack) - return(0); + + } /* FOR */ + + if (e.iop >= iostack) { + RCPRINTF(("READC: return 0, e.iop 0x%x\n", e.iop)); + return (0); + } + + DBGPRINTF(("READC: leave()...\n")); leave(); + /* NOTREACHED */ - return(0); + return (0); } -static void -ioecho(c) +static void ioecho(c) char c; { if (flag['v']) write(2, &c, sizeof c); } -static void -pushio(struct ioarg *argp, int (*fn)(struct ioarg *)) + +static void pushio(struct ioarg *argp, int (*fn) (struct ioarg *)) { + DBGPRINTF(("PUSHIO: argp 0x%x, argp->afid 0x%x, e.iop 0x%x\n", argp, + argp->afid, e.iop)); + + /* Set env ptr for io source to next array spot and check for array overflow */ if (++e.iop >= &iostack[NPUSH]) { e.iop--; err("Shell input nested too deeply"); gflg++; return; } - e.iop->iofn = (int (*)(struct ioarg *, struct io *))fn; + + /* We did not overflow the NPUSH array spots so setup data structs */ + + e.iop->iofn = (int (*)(struct ioarg *, struct io *)) fn; /* Store data source func ptr */ if (argp->afid != AFID_NOBUF) - e.iop->argp = argp; + e.iop->argp = argp; else { - e.iop->argp = ioargstack + (e.iop - iostack); - *e.iop->argp = *argp; - e.iop->argp->afbuf = e.iop == &iostack[0] ? &mainbuf : &sharedbuf; - if (isatty(e.iop->argp->afile) == 0 && - (e.iop == &iostack[0] || - lseek(e.iop->argp->afile, 0L, 1) != -1)) { - if (++bufid == AFID_NOBUF) - bufid = AFID_ID; - e.iop->argp->afid = bufid; - } - } - - e.iop->prev = ~'\n'; + + e.iop->argp = ioargstack + (e.iop - iostack); /* MAL - index into stack */ + *e.iop->argp = *argp; /* copy data from temp area into stack spot */ + + /* MAL - mainbuf is for 1st data source (command line?) and all nested use a single shared buffer? */ + + if (e.iop == &iostack[0]) + e.iop->argp->afbuf = &mainbuf; + else + e.iop->argp->afbuf = &sharedbuf; + + /* MAL - if not a termimal AND (commandline OR readable file) then give it a buffer id? */ + /* This line appears to be active when running scripts from command line */ + if ((isatty(e.iop->argp->afile) == 0) + && (e.iop == &iostack[0] + || lseek(e.iop->argp->afile, 0L, 1) != -1)) { + if (++bufid == AFID_NOBUF) /* counter rollover check, AFID_NOBUF = 11111111 */ + bufid = AFID_ID; /* AFID_ID = 0 */ + + e.iop->argp->afid = bufid; /* assign buffer id */ + } + + DBGPRINTF(("PUSHIO: iostack 0x%x, e.iop 0x%x, afbuf 0x%x\n", + iostack, e.iop, e.iop->argp->afbuf)); + DBGPRINTF(("PUSHIO: mbuf 0x%x, sbuf 0x%x, bid %d, e.iop 0x%x\n", + &mainbuf, &sharedbuf, bufid, e.iop)); + + } + + e.iop->prev = ~'\n'; e.iop->peekc = 0; e.iop->xchar = 0; e.iop->nlcount = 0; + if (fn == filechar || fn == linechar) e.iop->task = XIO; - else if (fn == (int(*)(struct ioarg *))gravechar || fn == (int(*)(struct ioarg *))qgravechar) + else if (fn == (int (*)(struct ioarg *)) gravechar + || fn == (int (*)(struct ioarg *)) qgravechar) e.iop->task = XGRAVE; else e.iop->task = XOTHER; + + return; } -static struct io * -setbase(ip) +static struct io *setbase(ip) struct io *ip; { - register struct io *xp; + REGISTER struct io *xp; xp = e.iobase; e.iobase = ip; - return(xp); + return (xp); } /* @@ -4419,158 +4943,155 @@ struct io *ip; /* * Produce the characters of a string, then a newline, then EOF. */ -static int -nlchar(ap) -register struct ioarg *ap; +static int nlchar(ap) +REGISTER struct ioarg *ap; { - register int c; + REGISTER int c; if (ap->aword == NULL) - return(0); + return (0); if ((c = *ap->aword++) == 0) { ap->aword = NULL; - return('\n'); + return ('\n'); } - return(c); + return (c); } /* * Given a list of words, produce the characters * in them, with a space after each word. */ -static int -wdchar(ap) -register struct ioarg *ap; +static int wdchar(ap) +REGISTER struct ioarg *ap; { - register char c; - register char **wl; + REGISTER char c; + REGISTER char **wl; if ((wl = ap->awordlist) == NULL) - return(0); + return (0); if (*wl != NULL) { if ((c = *(*wl)++) != 0) - return(c & 0177); + return (c & 0177); ap->awordlist++; - return(' '); + return (' '); } ap->awordlist = NULL; - return('\n'); + return ('\n'); } /* * Return the characters of a list of words, * producing a space between them. */ -static int -dolchar(ap) -register struct ioarg *ap; +static int dolchar(ap) +REGISTER struct ioarg *ap; { - register char *wp; + REGISTER char *wp; if ((wp = *ap->awordlist++) != NULL) { - PUSHIO(aword, wp, *ap->awordlist == NULL? strchar: xxchar); - return(-1); + PUSHIO(aword, wp, *ap->awordlist == NULL ? strchar : xxchar); + return (-1); } - return(0); + return (0); } -static int -xxchar(ap) -register struct ioarg *ap; +static int xxchar(ap) +REGISTER struct ioarg *ap; { - register int c; + REGISTER int c; if (ap->aword == NULL) - return(0); + return (0); if ((c = *ap->aword++) == '\0') { ap->aword = NULL; - return(' '); + return (' '); } - return(c); + return (c); } /* * Produce the characters from a single word (string). */ -static int -strchar(ap) -register struct ioarg *ap; +static int strchar(ap) +REGISTER struct ioarg *ap; { - register int c; + REGISTER int c; if (ap->aword == NULL || (c = *ap->aword++) == 0) - return(0); - return(c); + return (0); + return (c); } /* * Produce quoted characters from a single word (string). */ -static int -qstrchar(ap) -register struct ioarg *ap; +static int qstrchar(ap) +REGISTER struct ioarg *ap; { - register int c; + REGISTER int c; if (ap->aword == NULL || (c = *ap->aword++) == 0) - return(0); - return(c|QUOTE); + return (0); + return (c | QUOTE); } /* * Return the characters from a file. */ -static int -filechar(ap) -register struct ioarg *ap; +static int filechar(ap) +REGISTER struct ioarg *ap; { - register int i; + REGISTER int i; char c; struct iobuf *bp = ap->afbuf; if (ap->afid != AFID_NOBUF) { - if ((i = ap->afid != bp->id) || bp->bufp == bp->ebufp) { - if (i) - lseek(ap->afile, ap->afpos, 0); - i = safe_read(ap->afile, bp->buf, sizeof(bp->buf)); - if (i <= 0) { - closef(ap->afile); - return 0; - } - bp->id = ap->afid; - bp->ebufp = (bp->bufp = bp->buf) + i; - } - ap->afpos++; - return *bp->bufp++ & 0177; - } + if ((i = ap->afid != bp->id) || bp->bufp == bp->ebufp) { + + if (i) + lseek(ap->afile, ap->afpos, 0); + i = safe_read(ap->afile, bp->buf, sizeof(bp->buf)); + + if (i <= 0) { + closef(ap->afile); + return 0; + } + + bp->id = ap->afid; + bp->ebufp = (bp->bufp = bp->buf) + i; + } + + ap->afpos++; + return *bp->bufp++ & 0177; + } #ifdef CONFIG_FEATURE_COMMAND_EDITING if (interactive && isatty(ap->afile)) { - static char mycommand[BUFSIZ]; - static int position = 0, size = 0; - - while (size == 0 || position >= size) { - cmdedit_read_input(current_prompt, mycommand); - size = strlen(mycommand); - position = 0; - } - c = mycommand[position]; - position++; - return(c); - } else + static char mycommand[BUFSIZ]; + static int position = 0, size = 0; + + while (size == 0 || position >= size) { + cmdedit_read_input(current_prompt, mycommand); + size = strlen(mycommand); + position = 0; + } + c = mycommand[position]; + position++; + return (c); + } else #endif + { i = safe_read(ap->afile, &c, sizeof(c)); - return(i == sizeof(c)? c&0177: (closef(ap->afile), 0)); + return (i == sizeof(c) ? (c & 0x7f) : (closef(ap->afile), 0)); } } /* * Return the characters from a here temp file. */ -static int -herechar(ap) -register struct ioarg *ap; +static int herechar(ap) +REGISTER struct ioarg *ap; { char c; @@ -4587,29 +5108,29 @@ register struct ioarg *ap; * Return the characters produced by a process (`...`). * Quote them if required, and remove any trailing newline characters. */ -static int -gravechar(ap, iop) +static int gravechar(ap, iop) struct ioarg *ap; struct io *iop; { - register int c; + REGISTER int c; - if ((c = qgravechar(ap, iop)&~QUOTE) == '\n') + if ((c = qgravechar(ap, iop) & ~QUOTE) == '\n') c = ' '; - return(c); + return (c); } -static int -qgravechar(ap, iop) -register struct ioarg *ap; +static int qgravechar(ap, iop) +REGISTER struct ioarg *ap; struct io *iop; { - register int c; + REGISTER int c; + + DBGPRINTF3(("QGRAVECHAR: enter, ap=0x%x, iop=0x%x\n", ap, iop)); if (iop->xchar) { if (iop->nlcount) { iop->nlcount--; - return('\n'|QUOTE); + return ('\n' | QUOTE); } c = iop->xchar; iop->xchar = 0; @@ -4619,103 +5140,105 @@ struct io *iop; iop->nlcount++; iop->xchar = c; if (c == 0) - return(c); + return (c); iop->nlcount--; c = '\n'; } - return(c!=0? c|QUOTE: 0); + return (c != 0 ? c | QUOTE : 0); } /* * Return a single command (usually the first line) from a file. */ -static int -linechar(ap) -register struct ioarg *ap; +static int linechar(ap) +REGISTER struct ioarg *ap; { - register int c; + REGISTER int c; if ((c = filechar(ap)) == '\n') { if (!multiline) { closef(ap->afile); - ap->afile = -1; /* illegal value */ + ap->afile = -1; /* illegal value */ } } - return(c); + return (c); } -static void -prs(s) -register char *s; +static void prs(s) +REGISTER char *s; { if (*s) write(2, s, strlen(s)); } -static void -prn(u) +static void prn(u) unsigned u; { prs(itoa(u)); } -static void -closef(i) -register int i; +static void closef(i) +REGISTER int i; { if (i > 2) close(i); } -static void -closeall() +static void closeall() { - register int u; + REGISTER int u; - for (u=NUFILE; u= 0 && fd < e.iofd); - for (i=0; ih_tag = evalstr(s, DOSUB); if (h->h_tag == 0) return; + h->h_iop = iop; iop->io_name = 0; h->h_next = NULL; if (inhere == 0) inhere = h; else - for (lh = inhere; lh!=NULL; lh = lh->h_next) + for (lh = inhere; lh != NULL; lh = lh->h_next) if (lh->h_next == 0) { lh->h_next = h; break; } - iop->io_flag |= IOHERE|IOXHERE; + iop->io_flag |= IOHERE | IOXHERE; for (s = h->h_tag; *s; s++) if (*s & QUOTE) { - iop->io_flag &= ~ IOXHERE; - *s &= ~ QUOTE; + iop->io_flag &= ~IOXHERE; + *s &= ~QUOTE; } h->h_dosub = iop->io_flag & IOXHERE; } -static void -gethere() +static void gethere() { - register struct here *h, *hp; + REGISTER struct here *h, *hp; + + DBGPRINTF7(("GETHERE: enter...\n")); /* Scan here files first leaving inhere list in place */ for (hp = h = inhere; h != NULL; hp = h, h = h->h_next) - readhere(&h->h_iop->io_name, h->h_tag, h->h_dosub? 0: '\''); + readhere(&h->h_iop->io_name, h->h_tag, h->h_dosub ? 0 : '\''); /* Make inhere list active - keep list intact for scraphere */ if (hp != NULL) { - hp->h_next = acthere; - acthere = inhere; - inhere = NULL; + hp->h_next = acthere; + acthere = inhere; + inhere = NULL; } } -static void -readhere(name, s, ec) +static void readhere(name, s, ec) char **name; -register char *s; +REGISTER char *s; int ec; { int tf; char tname[30] = ".msh_XXXXXX"; - register int c; + REGISTER int c; jmp_buf ev; - char myline [LINELIM+1]; + char myline[LINELIM + 1]; char *thenext; + DBGPRINTF7(("READHERE: enter, name=0x%x, s=0x%x\n", name, s)); + tf = mkstemp(tname); if (tf < 0) return; + *name = strsave(tname, areanum); if (newenv(setjmp(errpt = ev)) != 0) unlink(tname); else { - pushio(e.iop->argp, (int(*)(struct ioarg *))e.iop->iofn); + pushio(e.iop->argp, (int (*)(struct ioarg *)) e.iop->iofn); e.iobase = e.iop; for (;;) { - if (interactive && e.iop <= iostack) { + if (interactive && e.iop <= iostack) { #ifdef CONFIG_FEATURE_COMMAND_EDITING - current_prompt=cprompt->value; + current_prompt = cprompt->value; #else - prs(cprompt->value); + prs(cprompt->value); #endif } thenext = myline; while ((c = my_getc(ec)) != '\n' && c) { if (ec == '\'') - c &= ~ QUOTE; + c &= ~QUOTE; if (thenext >= &myline[LINELIM]) { c = 0; break; @@ -4823,10 +5352,12 @@ int ec; if (strcmp(s, myline) == 0 || c == 0) break; *thenext++ = '\n'; - write (tf, myline, (int)(thenext-myline)); + write(tf, myline, (int) (thenext - myline)); } if (c == 0) { - prs("here document `"); prs(s); err("' unclosed"); + prs("here document `"); + prs(s); + err("' unclosed"); } quitenv(); } @@ -4837,28 +5368,31 @@ int ec; * open here temp file. * if unquoted here, expand here temp file into second temp file. */ -static int -herein(hname, xdoll) +static int herein(hname, xdoll) char *hname; int xdoll; { - register int hf; + REGISTER int hf; int tf; #if __GNUC__ /* Avoid longjmp clobbering */ (void) &tf; #endif - if (hname == 0) - return(-1); + if (hname == NULL) + return (-1); + + DBGPRINTF7(("HEREIN: hname is %s, xdoll=%d\n", hname, xdoll)); + hf = open(hname, 0); if (hf < 0) return (-1); + if (xdoll) { char c; char tname[30] = ".msh_XXXXXX"; jmp_buf ev; - + tf = mkstemp(tname); if (tf < 0) return (-1); @@ -4866,7 +5400,7 @@ int xdoll; PUSHIO(afile, hf, herechar); setbase(e.iop); while ((c = subgetc(0, 0)) != 0) { - c &= ~ QUOTE; + c &= ~QUOTE; write(tf, &c, sizeof c); } quitenv(); @@ -4880,24 +5414,26 @@ int xdoll; return (hf); } -static void -scraphere() +static void scraphere() { - register struct here *h; + REGISTER struct here *h; + + DBGPRINTF7(("SCRAPHERE: enter...\n")); for (h = inhere; h != NULL; h = h->h_next) { if (h->h_iop && h->h_iop->io_name) - unlink(h->h_iop->io_name); + unlink(h->h_iop->io_name); } inhere = NULL; } /* unlink here temp files before a freearea(area) */ -static void -freehere(area) +static void freehere(area) int area; { - register struct here *h, *hl; + REGISTER struct here *h, *hl; + + DBGPRINTF6(("FREEHERE: enter, area=%d\n", area)); hl = NULL; for (h = acthere; h != NULL; h = h->h_next) @@ -4917,24 +5453,24 @@ int area; /* * Copyright (c) 1987,1997, Prentice Hall * All rights reserved. - * + * * Redistribution and use of the MINIX operating system in source and * binary forms, with or without modification, are permitted provided * that the following conditions are met: - * + * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. - * + * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. - * + * * Neither the name of Prentice Hall nor the names of the software * authors or contributors may be used to endorse or promote * products derived from this software without specific prior * written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS, AUTHORS, AND * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF @@ -4949,4 +5485,3 @@ int area; * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ -