aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2004-08-04 19:19:10 +0000
committerEric Andersen <andersen@codepoet.org>2004-08-04 19:19:10 +0000
commit12de6cf0d791bff627a6071519b71c19240aa1ce (patch)
treef8b59eaf6b8fcc9f0013de8da8debe5cb250db5b
parent8401eeafd654d447053036cdd1dfbca9a0e297a8 (diff)
downloadbusybox-w32-12de6cf0d791bff627a6071519b71c19240aa1ce.tar.gz
busybox-w32-12de6cf0d791bff627a6071519b71c19240aa1ce.tar.bz2
busybox-w32-12de6cf0d791bff627a6071519b71c19240aa1ce.zip
Michael Leibow, MichaelLe at belkin.com writes:
A question was posted a month ago by Mark Alamo to see if others had problems with sourcing subscripts within msh. We asked his firm to fix the msh.c bug he described because we didn't have enough time to do it ourselves. When msh.c is executing a compound statement and there is a . command to source another script file, msh.c will not execute the subscript until it's completed executing the rest of the compound statement. His example was this: Echo "Start" ; . ./subA; echo "mid" ; . ./subB ; echo "end" subA and subB execute AFTER end is printed in reverse order. The same is true if the sourced files are inside an if else fi, case esac, or any compound statement. Attached is a patch to msh.c. It fixes the problem. Cd to the root of your busybox tree and execute "patch -p1 < msh.c.patch" Unfortunately, I won't have more time to work on this so I hope that there aren't any problems! Michael Leibow Senior Software Engineer Belkin Corporation
-rw-r--r--shell/msh.c1431
1 files changed, 1056 insertions, 375 deletions
diff --git a/shell/msh.c b/shell/msh.c
index 722d90d57..22a617095 100644
--- a/shell/msh.c
+++ b/shell/msh.c
@@ -49,24 +49,68 @@
49#include "busybox.h" 49#include "busybox.h"
50 50
51 51
52/* Conditional use of "register" keyword */
53#define REGISTER register
54
55
56/*#define MSHDEBUG 1*/
57
58#ifdef MSHDEBUG
59int mshdbg = 0;
60
61#define DBGPRINTF(x) if(mshdbg>0)printf x
62#define DBGPRINTF0(x) if(mshdbg>0)printf x
63#define DBGPRINTF1(x) if(mshdbg>1)printf x
64#define DBGPRINTF2(x) if(mshdbg>2)printf x
65#define DBGPRINTF3(x) if(mshdbg>3)printf x
66#define DBGPRINTF4(x) if(mshdbg>4)printf x
67#define DBGPRINTF5(x) if(mshdbg>5)printf x
68#define DBGPRINTF6(x) if(mshdbg>6)printf x
69#define DBGPRINTF7(x) if(mshdbg>7)printf x
70#define DBGPRINTF8(x) if(mshdbg>8)printf x
71#define DBGPRINTF9(x) if(mshdbg>9)printf x
72
73int mshdbg_rc = 0;
74
75#define RCPRINTF(x) if(mshdbg_rc)printf x
76
77#else
78
79#define DBGPRINTF(x)
80#define DBGPRINTF0(x)
81#define DBGPRINTF1(x)
82#define DBGPRINTF2(x)
83#define DBGPRINTF3(x)
84#define DBGPRINTF4(x)
85#define DBGPRINTF5(x)
86#define DBGPRINTF6(x)
87#define DBGPRINTF7(x)
88#define DBGPRINTF8(x)
89#define DBGPRINTF9(x)
90
91#define RCPRINTF(x)
92
93#endif /* MSHDEBUG */
94
95
52/* -------- sh.h -------- */ 96/* -------- sh.h -------- */
53/* 97/*
54 * shell 98 * shell
55 */ 99 */
56 100
57#define LINELIM 2100 101#define LINELIM 2100
58#define NPUSH 8 /* limit to input nesting */ 102#define NPUSH 8 /* limit to input nesting */
59 103
60#undef NOFILE 104#undef NOFILE
61#define NOFILE 20 /* Number of open files */ 105#define NOFILE 20 /* Number of open files */
62#define NUFILE 10 /* Number of user-accessible files */ 106#define NUFILE 10 /* Number of user-accessible files */
63#define FDBASE 10 /* First file usable by Shell */ 107#define FDBASE 10 /* First file usable by Shell */
64 108
65/* 109/*
66 * values returned by wait 110 * values returned by wait
67 */ 111 */
68#define WAITSIG(s) ((s)&0177) 112#define WAITSIG(s) ((s)&0177)
69#define WAITVAL(s) (((s)>>8)&0377) 113#define WAITVAL(s) (((s)>>8)&0377)
70#define WAITCORE(s) (((s)&0200)!=0) 114#define WAITCORE(s) (((s)&0200)!=0)
71 115
72/* 116/*
@@ -102,18 +146,43 @@ struct op {
102#define TPAREN 2 /* (c-list) */ 146#define TPAREN 2 /* (c-list) */
103#define TPIPE 3 /* a | b */ 147#define TPIPE 3 /* a | b */
104#define TLIST 4 /* a [&;] b */ 148#define TLIST 4 /* a [&;] b */
105#define TOR 5 /* || */ 149#define TOR 5 /* || */
106#define TAND 6 /* && */ 150#define TAND 6 /* && */
107#define TFOR 7 151#define TFOR 7
108#define TDO 8 152#define TDO 8
109#define TCASE 9 153#define TCASE 9
110#define TIF 10 154#define TIF 10
111#define TWHILE 11 155#define TWHILE 11
112#define TUNTIL 12 156#define TUNTIL 12
113#define TELIF 13 157#define TELIF 13
114#define TPAT 14 /* pattern in case */ 158#define TPAT 14 /* pattern in case */
115#define TBRACE 15 /* {c-list} */ 159#define TBRACE 15 /* {c-list} */
116#define TASYNC 16 /* c & */ 160#define TASYNC 16 /* c & */
161/* Added to support "." file expansion */
162#define TDOT 17
163
164/* Strings for names to make debug easier */
165char *T_CMD_NAMES[] = {
166 "PLACEHOLDER",
167 "TCOM",
168 "TPAREN",
169 "TPIPE",
170 "TLIST",
171 "TOR",
172 "TAND",
173 "TFOR",
174 "TDO",
175 "TCASE",
176 "TIF",
177 "TWHILE",
178 "TUNTIL",
179 "TELIF",
180 "TPAT",
181 "TBRACE",
182 "TASYNC",
183 "TDOT",
184};
185
117 186
118/* 187/*
119 * actions determining the environment of a process 188 * actions determining the environment of a process
@@ -121,30 +190,25 @@ struct op {
121#define BIT(i) (1<<(i)) 190#define BIT(i) (1<<(i))
122#define FEXEC BIT(0) /* execute without forking */ 191#define FEXEC BIT(0) /* execute without forking */
123 192
193#if 0 /* Original value */
194#define AREASIZE (65000)
195#else
196#define AREASIZE (90000)
197#endif
198
124/* 199/*
125 * flags to control evaluation of words 200 * flags to control evaluation of words
126 */ 201 */
127#define DOSUB 1 /* interpret $, `, and quotes */ 202#define DOSUB 1 /* interpret $, `, and quotes */
128#define DOBLANK 2 /* perform blank interpretation */ 203#define DOBLANK 2 /* perform blank interpretation */
129#define DOGLOB 4 /* interpret [?* */ 204#define DOGLOB 4 /* interpret [?* */
130#define DOKEY 8 /* move words with `=' to 2nd arg. list */ 205#define DOKEY 8 /* move words with `=' to 2nd arg. list */
131#define DOTRIM 16 /* trim resulting string */ 206#define DOTRIM 16 /* trim resulting string */
132 207
133#define DOALL (DOSUB|DOBLANK|DOGLOB|DOKEY|DOTRIM) 208#define DOALL (DOSUB|DOBLANK|DOGLOB|DOKEY|DOTRIM)
134 209
135static char **dolv;
136static int dolc;
137static int exstat;
138static char gflg;
139static int interactive; /* Is this an interactive shell */
140static int execflg;
141static int multiline; /* \n changed to ; */
142static struct op *outtree; /* result from parser */
143 210
144static xint *failpt; 211/* PROTOTYPES */
145static xint *errpt;
146static struct brkcon *brklist;
147static int isbreak;
148static int newfile(char *s); 212static int newfile(char *s);
149static char *findeq(char *cp); 213static char *findeq(char *cp);
150static char *cclass(char *p, int sub); 214static char *cclass(char *p, int sub);
@@ -157,6 +221,7 @@ struct brkcon {
157 struct brkcon *nextlev; 221 struct brkcon *nextlev;
158}; 222};
159 223
224
160/* 225/*
161 * redirection 226 * redirection
162 */ 227 */
@@ -166,18 +231,17 @@ struct ioword {
166 char *io_name; /* file name */ 231 char *io_name; /* file name */
167}; 232};
168 233
169#define IOREAD 1 /* < */ 234#define IOREAD 1 /* < */
170#define IOHERE 2 /* << (here file) */ 235#define IOHERE 2 /* << (here file) */
171#define IOWRITE 4 /* > */ 236#define IOWRITE 4 /* > */
172#define IOCAT 8 /* >> */ 237#define IOCAT 8 /* >> */
173#define IOXHERE 16 /* ${}, ` in << */ 238#define IOXHERE 16 /* ${}, ` in << */
174#define IODUP 32 /* >&digit */ 239#define IODUP 32 /* >&digit */
175#define IOCLOSE 64 /* >&- */ 240#define IOCLOSE 64 /* >&- */
176 241
177#define IODEFAULT (-1) /* token for default IO unit */ 242#define IODEFAULT (-1) /* token for default IO unit */
178 243
179static struct wdblock *wdlist; 244
180static struct wdblock *iolist;
181 245
182/* 246/*
183 * parsing & execution environment 247 * parsing & execution environment
@@ -186,7 +250,7 @@ static struct env {
186 char *linep; 250 char *linep;
187 struct io *iobase; 251 struct io *iobase;
188 struct io *iop; 252 struct io *iop;
189 xint *errpt; 253 xint *errpt; /* void * */
190 int iofd; 254 int iofd;
191 struct env *oenv; 255 struct env *oenv;
192} e; 256} e;
@@ -217,12 +281,12 @@ static int yynerrs; /* yacc */
217static char line[LINELIM]; 281static char line[LINELIM];
218static char *elinep; 282static char *elinep;
219 283
284
220/* 285/*
221 * other functions 286 * other functions
222 */ 287 */
223static int (*inbuilt(char *s)) (struct op *); 288static int (*inbuilt(char *s)) (struct op *);
224 289
225
226static char *rexecve(char *c, char **v, char **envp); 290static char *rexecve(char *c, char **v, char **envp);
227static char *space(int n); 291static char *space(int n);
228static char *strsave(char *s, int a); 292static char *strsave(char *s, int a);
@@ -235,7 +299,7 @@ static int rlookup(char *n);
235static struct wdblock *glob(char *cp, struct wdblock *wb); 299static struct wdblock *glob(char *cp, struct wdblock *wb);
236static int my_getc(int ec); 300static int my_getc(int ec);
237static int subgetc(int ec, int quoted); 301static int subgetc(int ec, int quoted);
238static char **makenv(void); 302static char **makenv(int all);
239static char **eval(char **ap, int f); 303static char **eval(char **ap, int f);
240static int setstatus(int s); 304static int setstatus(int s);
241static int waitfor(int lastpid, int canintr); 305static int waitfor(int lastpid, int canintr);
@@ -253,6 +317,7 @@ static void onecommand(void);
253static void runtrap(int i); 317static void runtrap(int i);
254static int gmatch(char *s, char *p); 318static int gmatch(char *s, char *p);
255 319
320
256/* 321/*
257 * error handling 322 * error handling
258 */ 323 */
@@ -265,13 +330,13 @@ static void sig(int i); /* default signal handler */
265 330
266/* -------- area stuff -------- */ 331/* -------- area stuff -------- */
267 332
268#define REGSIZE sizeof(struct region) 333#define REGSIZE sizeof(struct region)
269#define GROWBY 256 334#define GROWBY (256)
270//#define SHRINKBY 64 335/* #define SHRINKBY (64) */
271#undef SHRINKBY 336#undef SHRINKBY
272#define FREE 32767 337#define FREE (32767)
273#define BUSY 0 338#define BUSY (0)
274#define ALIGN (sizeof(int)-1) 339#define ALIGN (sizeof(int)-1)
275 340
276 341
277struct region { 342struct region {
@@ -293,25 +358,29 @@ typedef union {
293#define LOGAND 257 358#define LOGAND 257
294#define LOGOR 258 359#define LOGOR 258
295#define BREAK 259 360#define BREAK 259
296#define IF 260 361#define IF 260
297#define THEN 261 362#define THEN 261
298#define ELSE 262 363#define ELSE 262
299#define ELIF 263 364#define ELIF 263
300#define FI 264 365#define FI 264
301#define CASE 265 366#define CASE 265
302#define ESAC 266 367#define ESAC 266
303#define FOR 267 368#define FOR 267
304#define WHILE 268 369#define WHILE 268
305#define UNTIL 269 370#define UNTIL 269
306#define DO 270 371#define DO 270
307#define DONE 271 372#define DONE 271
308#define IN 272 373#define IN 272
374/* Added for "." file expansion */
375#define DOT 273
376
309#define YYERRCODE 300 377#define YYERRCODE 300
310 378
311/* flags to yylex */ 379/* flags to yylex */
312#define CONTIN 01 /* skip new lines to complete command */ 380#define CONTIN 01 /* skip new lines to complete command */
313 381
314#define SYNTAXERR zzerr() 382#define SYNTAXERR zzerr()
383
315static struct op *pipeline(int cf); 384static struct op *pipeline(int cf);
316static struct op *andor(void); 385static struct op *andor(void);
317static struct op *c_list(void); 386static struct op *c_list(void);
@@ -357,15 +426,6 @@ struct var {
357#define EXPORT 02 /* variable is to be exported */ 426#define EXPORT 02 /* variable is to be exported */
358#define GETCELL 04 /* name & value space was got with getcell */ 427#define GETCELL 04 /* name & value space was got with getcell */
359 428
360static struct var *vlist; /* dictionary */
361
362static struct var *homedir; /* home directory */
363static struct var *prompt; /* main prompt */
364static struct var *cprompt; /* continuation prompt */
365static struct var *path; /* search path for commands */
366static struct var *shell; /* shell to interpret command files */
367static struct var *ifs; /* field separators */
368
369static int yyparse(void); 429static int yyparse(void);
370static struct var *lookup(char *n); 430static struct var *lookup(char *n);
371static void setval(struct var *vp, char *val); 431static void setval(struct var *vp, char *val);
@@ -380,6 +440,7 @@ static int eqname(char *n1, char *n2);
380 440
381static int execute(struct op *t, int *pin, int *pout, int act); 441static int execute(struct op *t, int *pin, int *pout, int act);
382 442
443
383/* -------- io.h -------- */ 444/* -------- io.h -------- */
384/* io buffer */ 445/* io buffer */
385struct iobuf { 446struct iobuf {
@@ -423,6 +484,7 @@ struct io {
423/* in substitution */ 484/* in substitution */
424#define INSUB() (e.iop->task == XGRAVE || e.iop->task == XDOLL) 485#define INSUB() (e.iop->task == XGRAVE || e.iop->task == XDOLL)
425 486
487
426/* 488/*
427 * input generators for IO structure 489 * input generators for IO structure
428 */ 490 */
@@ -443,6 +505,7 @@ static void markhere(char *s, struct ioword *iop);
443static int herein(char *hname, int xdoll); 505static int herein(char *hname, int xdoll);
444static int run(struct ioarg *argp, int (*f) (struct ioarg *)); 506static int run(struct ioarg *argp, int (*f) (struct ioarg *));
445 507
508
446/* 509/*
447 * IO functions 510 * IO functions
448 */ 511 */
@@ -455,6 +518,7 @@ static void prn(unsigned u);
455static void closef(int i); 518static void closef(int i);
456static void closeall(void); 519static void closeall(void);
457 520
521
458/* 522/*
459 * IO control 523 * IO control
460 */ 524 */
@@ -464,8 +528,6 @@ static int openpipe(int *pv);
464static void closepipe(int *pv); 528static void closepipe(int *pv);
465static struct io *setbase(struct io *ip); 529static struct io *setbase(struct io *ip);
466 530
467static struct ioarg temparg; /* temporary for PUSHIO */
468
469#define PUSHIO(what,arg,gen) ((temparg.what = (arg)),pushio(&temparg,(gen))) 531#define PUSHIO(what,arg,gen) ((temparg.what = (arg)),pushio(&temparg,(gen)))
470#define RUN(what,arg,gen) ((temparg.what = (arg)), run(&temparg,(gen))) 532#define RUN(what,arg,gen) ((temparg.what = (arg)), run(&temparg,(gen)))
471 533
@@ -497,14 +559,13 @@ static void freearea(int a);
497static void freecell(char *cp); 559static void freecell(char *cp);
498static int areanum; /* current allocation area */ 560static int areanum; /* current allocation area */
499 561
500#define NEW(type) (type *)getcell(sizeof(type)) 562#define NEW(type) (type *)getcell(sizeof(type))
501#define DELETE(obj) freecell((char *)obj) 563#define DELETE(obj) freecell((char *)obj)
502 564
503 565
504/* -------- misc stuff -------- */ 566/* -------- misc stuff -------- */
505 567
506static int forkexec(struct op *t, int *pin, int *pout, int act, char **wp, 568static int forkexec(struct op *t, int *pin, int *pout, int act, char **wp);
507 int *pforked);
508static int iosetup(struct ioword *iop, int pipein, int pipeout); 569static int iosetup(struct ioword *iop, int pipein, int pipeout);
509static void echo(char **wp); 570static void echo(char **wp);
510static struct op **find1case(struct op *t, char *w); 571static struct op **find1case(struct op *t, char *w);
@@ -599,12 +660,12 @@ static struct res restab[] = {
599 {"elif", ELIF}, 660 {"elif", ELIF},
600 {"until", UNTIL}, 661 {"until", UNTIL},
601 {"fi", FI}, 662 {"fi", FI},
602
603 {";;", BREAK}, 663 {";;", BREAK},
604 {"||", LOGOR}, 664 {"||", LOGOR},
605 {"&&", LOGAND}, 665 {"&&", LOGAND},
606 {"{", '{'}, 666 {"{", '{'},
607 {"}", '}'}, 667 {"}", '}'},
668 {".", DOT},
608 {0, 0}, 669 {0, 0},
609}; 670};
610 671
@@ -637,13 +698,18 @@ static const struct builtincmd builtincmds[] = {
637 {0, 0} 698 {0, 0}
638}; 699};
639 700
701static int expand_dotnode(struct op *);
702struct op *scantree(struct op *);
703static struct op *dowholefile(int, int);
704
640/* Globals */ 705/* Globals */
641extern char **environ; /* environment pointer */ 706extern char **environ; /* environment pointer */
707
642static char **dolv; 708static char **dolv;
643static int dolc; 709static int dolc;
644static int exstat; 710static int exstat;
645static char gflg; 711static char gflg;
646static int interactive; /* Is this an interactive shell */ 712static int interactive = 0; /* Is this an interactive shell */
647static int execflg; 713static int execflg;
648static int multiline; /* \n changed to ; */ 714static int multiline; /* \n changed to ; */
649static struct op *outtree; /* result from parser */ 715static struct op *outtree; /* result from parser */
@@ -658,6 +724,10 @@ static char ourtrap[_NSIG + 1];
658static int trapset; /* trap pending */ 724static int trapset; /* trap pending */
659static int yynerrs; /* yacc */ 725static int yynerrs; /* yacc */
660static char line[LINELIM]; 726static char line[LINELIM];
727
728#ifdef MSHDEBUG
729static struct var *mshdbg_var;
730#endif
661static struct var *vlist; /* dictionary */ 731static struct var *vlist; /* dictionary */
662static struct var *homedir; /* home directory */ 732static struct var *homedir; /* home directory */
663static struct var *prompt; /* main prompt */ 733static struct var *prompt; /* main prompt */
@@ -665,29 +735,29 @@ static struct var *cprompt; /* continuation prompt */
665static struct var *path; /* search path for commands */ 735static struct var *path; /* search path for commands */
666static struct var *shell; /* shell to interpret command files */ 736static struct var *shell; /* shell to interpret command files */
667static struct var *ifs; /* field separators */ 737static struct var *ifs; /* field separators */
668static struct ioarg ioargstack[NPUSH]; 738
669static struct io iostack[NPUSH];
670static int areanum; /* current allocation area */ 739static int areanum; /* current allocation area */
671static int intr; 740static int intr;
672static int inparse; 741static int inparse;
673static char flags['z' - 'a' + 1]; 742static char flags['z' - 'a' + 1];
674static char *flag = flags - 'a'; 743static char *flag = flags - 'a';
675static char *elinep = line + sizeof(line) - 5;
676static char *null = ""; 744static char *null = "";
677static int heedint = 1; 745static int heedint = 1;
678static struct env e =
679 { line, iostack, iostack - 1, (xint *) NULL, FDBASE,
680(struct env *) NULL };
681static void (*qflag) (int) = SIG_IGN; 746static void (*qflag) (int) = SIG_IGN;
682static int startl; 747static int startl;
683static int peeksym; 748static int peeksym;
684static int nlseen; 749static int nlseen;
685static int iounit = IODEFAULT; 750static int iounit = IODEFAULT;
686static YYSTYPE yylval; 751static YYSTYPE yylval;
752static char *elinep = line + sizeof(line) - 5;
753
754static struct ioarg temparg = { 0, 0, 0, AFID_NOBUF, 0 }; /* temporary for PUSHIO */
755static struct ioarg ioargstack[NPUSH];
756static struct io iostack[NPUSH];
687static struct iobuf sharedbuf = { AFID_NOBUF }; 757static struct iobuf sharedbuf = { AFID_NOBUF };
688static struct iobuf mainbuf = { AFID_NOBUF }; 758static struct iobuf mainbuf = { AFID_NOBUF };
689static unsigned bufid = AFID_ID; /* buffer id counter */ 759static unsigned bufid = AFID_ID; /* buffer id counter */
690static struct ioarg temparg = { 0, 0, 0, AFID_NOBUF, 0 }; 760
691static struct here *inhere; /* list of hear docs while parsing */ 761static struct here *inhere; /* list of hear docs while parsing */
692static struct here *acthere; /* list of active here documents */ 762static struct here *acthere; /* list of active here documents */
693static struct region *areabot; /* bottom of area */ 763static struct region *areabot; /* bottom of area */
@@ -696,6 +766,48 @@ static struct region *areanxt; /* starting point of scan */
696static void *brktop; 766static void *brktop;
697static void *brkaddr; 767static void *brkaddr;
698 768
769static struct env e = {
770 line, /* linep: char ptr */
771 iostack, /* iobase: struct io ptr */
772 iostack - 1, /* iop: struct io ptr */
773 (xint *) NULL, /* errpt: void ptr for errors? */
774 FDBASE, /* iofd: file desc */
775 (struct env *) NULL /* oenv: struct env ptr */
776};
777
778#ifdef MSHDEBUG
779void print_t(struct op *t)
780{
781 DBGPRINTF(("T: t=0x%x, type %s, words=0x%x, IOword=0x%x\n", t,
782 T_CMD_NAMES[t->type], t->words, t->ioact));
783
784 if (t->words) {
785 DBGPRINTF(("T: W1: %s", t->words[0]));
786 }
787
788 return;
789}
790
791void print_tree(struct op *head)
792{
793 if (head == NULL) {
794 DBGPRINTF(("PRINT_TREE: no tree\n"));
795 return;
796 }
797
798 DBGPRINTF(("NODE: 0x%x, left 0x%x, right 0x%x\n", head, head->left,
799 head->right));
800
801 if (head->left)
802 print_tree(head->left);
803
804 if (head->right)
805 print_tree(head->right);
806
807 return;
808}
809#endif /* MSHDEBUG */
810
699 811
700#ifdef CONFIG_FEATURE_COMMAND_EDITING 812#ifdef CONFIG_FEATURE_COMMAND_EDITING
701static char *current_prompt; 813static char *current_prompt;
@@ -709,12 +821,14 @@ static char *current_prompt;
709 821
710extern int msh_main(int argc, char **argv) 822extern int msh_main(int argc, char **argv)
711{ 823{
712 register int f; 824 REGISTER int f;
713 register char *s; 825 REGISTER char *s;
714 int cflag; 826 int cflag;
715 char *name, **ap; 827 char *name, **ap;
716 int (*iof) (struct ioarg *); 828 int (*iof) (struct ioarg *);
717 829
830 DBGPRINTF(("MSH_MAIN: argc %d, environ 0x%x\n", argc, environ));
831
718 initarea(); 832 initarea();
719 if ((ap = environ) != NULL) { 833 if ((ap = environ) != NULL) {
720 while (*ap) 834 while (*ap)
@@ -750,6 +864,13 @@ extern int msh_main(int argc, char **argv)
750 if (ifs->value == null) 864 if (ifs->value == null)
751 setval(ifs, " \t\n"); 865 setval(ifs, " \t\n");
752 866
867#ifdef MSHDEBUG
868 mshdbg_var = lookup("MSHDEBUG");
869 if (mshdbg_var->value == null)
870 setval(mshdbg_var, "0");
871#endif
872
873
753 prompt = lookup("PS1"); 874 prompt = lookup("PS1");
754#ifdef CONFIG_FEATURE_SH_FANCY_PROMPT 875#ifdef CONFIG_FEATURE_SH_FANCY_PROMPT
755 if (prompt->value == null) 876 if (prompt->value == null)
@@ -806,26 +927,44 @@ extern int msh_main(int argc, char **argv)
806 argv--; 927 argv--;
807 argc++; 928 argc++;
808 } 929 }
930
809 if (iof == filechar && --argc > 0) { 931 if (iof == filechar && --argc > 0) {
810 setval(prompt, ""); 932 setval(prompt, "");
811 setval(cprompt, ""); 933 setval(cprompt, "");
812 prompt->status &= ~EXPORT; 934 prompt->status &= ~EXPORT;
813 cprompt->status &= ~EXPORT; 935 cprompt->status &= ~EXPORT;
936
937/* Shell is non-interactive, activate printf-based debug */
938#ifdef MSHDEBUG
939 mshdbg = (int) (((char) (mshdbg_var->value[0])) - '0');
940 if (mshdbg < 0)
941 mshdbg = 0;
942#endif
943 DBGPRINTF(("MSH_MAIN: calling newfile()\n"));
944
814 if (newfile(name = *++argv)) 945 if (newfile(name = *++argv))
815 exit(1); 946 exit(1); /* Exit on error */
816 } 947 }
817 } 948 }
949
818 setdash(); 950 setdash();
951
952 /* This won't be true if PUSHIO has been called, say from newfile() above */
819 if (e.iop < iostack) { 953 if (e.iop < iostack) {
820 PUSHIO(afile, 0, iof); 954 PUSHIO(afile, 0, iof);
821 if (isatty(0) && isatty(1) && !cflag) { 955 if (isatty(0) && isatty(1) && !cflag) {
822 interactive++; 956 interactive++;
823#ifndef CONFIG_FEATURE_SH_EXTRA_QUIET 957#ifndef CONFIG_FEATURE_SH_EXTRA_QUIET
958#ifdef MSHDEBUG
959 printf("\n\n" BB_BANNER " Built-in shell (msh with debug)\n");
960#else
824 printf("\n\n" BB_BANNER " Built-in shell (msh)\n"); 961 printf("\n\n" BB_BANNER " Built-in shell (msh)\n");
962#endif
825 printf("Enter 'help' for a list of built-in commands.\n\n"); 963 printf("Enter 'help' for a list of built-in commands.\n\n");
826#endif 964#endif
827 } 965 }
828 } 966 }
967
829 signal(SIGQUIT, qflag); 968 signal(SIGQUIT, qflag);
830 if (name && name[0] == '-') { 969 if (name && name[0] == '-') {
831 interactive++; 970 interactive++;
@@ -836,6 +975,7 @@ extern int msh_main(int argc, char **argv)
836 } 975 }
837 if (interactive) 976 if (interactive)
838 signal(SIGTERM, sig); 977 signal(SIGTERM, sig);
978
839 if (signal(SIGINT, SIG_IGN) != SIG_IGN) 979 if (signal(SIGINT, SIG_IGN) != SIG_IGN)
840 signal(SIGINT, onintr); 980 signal(SIGINT, onintr);
841 dolv = argv; 981 dolv = argv;
@@ -852,6 +992,8 @@ extern int msh_main(int argc, char **argv)
852 } 992 }
853 setval(lookup("#"), putn((--dolc < 0) ? (dolc = 0) : dolc)); 993 setval(lookup("#"), putn((--dolc < 0) ? (dolc = 0) : dolc));
854 994
995 DBGPRINTF(("MSH_MAIN: begin FOR loop, interactive %d, e.iop 0x%x, iostack 0x%x\n", interactive, e.iop, iostack));
996
855 for (;;) { 997 for (;;) {
856 if (interactive && e.iop <= iostack) { 998 if (interactive && e.iop <= iostack) {
857#ifdef CONFIG_FEATURE_COMMAND_EDITING 999#ifdef CONFIG_FEATURE_COMMAND_EDITING
@@ -864,12 +1006,14 @@ extern int msh_main(int argc, char **argv)
864 /* Ensure that getenv("PATH") stays current */ 1006 /* Ensure that getenv("PATH") stays current */
865 setenv("PATH", path->value, 1); 1007 setenv("PATH", path->value, 1);
866 } 1008 }
1009
1010 DBGPRINTF(("MSH_MAIN: returning.\n"));
867} 1011}
868 1012
869static void setdash() 1013static void setdash()
870{ 1014{
871 register char *cp; 1015 REGISTER char *cp;
872 register int c; 1016 REGISTER int c;
873 char m['z' - 'a' + 1]; 1017 char m['z' - 'a' + 1];
874 1018
875 cp = m; 1019 cp = m;
@@ -881,11 +1025,14 @@ static void setdash()
881} 1025}
882 1026
883static int newfile(s) 1027static int newfile(s)
884register char *s; 1028REGISTER char *s;
885{ 1029{
886 register int f; 1030 REGISTER int f;
1031
1032 DBGPRINTF7(("NEWFILE: opening %s\n", s));
887 1033
888 if (strcmp(s, "-") != 0) { 1034 if (strcmp(s, "-") != 0) {
1035 DBGPRINTF(("NEWFILE: s is %s\n", s));
889 f = open(s, 0); 1036 f = open(s, 0);
890 if (f < 0) { 1037 if (f < 0) {
891 prs(s); 1038 prs(s);
@@ -894,17 +1041,73 @@ register char *s;
894 } 1041 }
895 } else 1042 } else
896 f = 0; 1043 f = 0;
1044
897 next(remap(f)); 1045 next(remap(f));
898 return (0); 1046 return (0);
899} 1047}
900 1048
1049
1050static int expand_dotnode(node)
1051struct op *node;
1052{
1053 struct op *outtree_save = outtree;
1054
1055 node->type = TDOT;
1056 newfile(node->words[1]);
1057
1058 node->left = dowholefile(TDOT, 0);
1059
1060 node->right = NULL;
1061
1062 outtree = outtree_save;
1063
1064 return (1);
1065}
1066
1067struct op *scantree(head)
1068struct op *head;
1069{
1070 struct op *dotnode;
1071
1072 if (head == NULL)
1073 return (NULL);
1074
1075 if (head->left != NULL) {
1076 dotnode = scantree(head->left);
1077 if (dotnode)
1078 return (dotnode);
1079 }
1080
1081 if (head->right != NULL) {
1082 dotnode = scantree(head->right);
1083 if (dotnode)
1084 return (dotnode);
1085 }
1086
1087 if (head->words == NULL)
1088 return (NULL);
1089
1090 DBGPRINTF5(("SCANTREE: checking node 0x%x\n", head));
1091
1092 if ((head->type != TDOT) && (strcmp(".", head->words[0]) == 0)) {
1093 DBGPRINTF5(("SCANTREE: dot found in node 0x%x\n", head));
1094 return (head);
1095 }
1096
1097 return (NULL);
1098}
1099
1100
901static void onecommand() 1101static void onecommand()
902{ 1102{
903 register int i; 1103 REGISTER int i;
904 jmp_buf m1; 1104 jmp_buf m1;
905 1105
1106 DBGPRINTF(("ONECOMMAND: enter, outtree=0x%x\n", outtree));
1107
906 while (e.oenv) 1108 while (e.oenv)
907 quitenv(); 1109 quitenv();
1110
908 areanum = 1; 1111 areanum = 1;
909 freehere(areanum); 1112 freehere(areanum);
910 freearea(areanum); 1113 freearea(areanum);
@@ -918,8 +1121,12 @@ static void onecommand()
918 inparse = 1; 1121 inparse = 1;
919 intr = 0; 1122 intr = 0;
920 execflg = 0; 1123 execflg = 0;
1124
921 setjmp(failpt = m1); /* Bruce Evans' fix */ 1125 setjmp(failpt = m1); /* Bruce Evans' fix */
922 if (setjmp(failpt = m1) || yyparse() || intr) { 1126 if (setjmp(failpt = m1) || yyparse() || intr) {
1127
1128 DBGPRINTF(("ONECOMMAND: this is not good.\n"));
1129
923 while (e.oenv) 1130 while (e.oenv)
924 quitenv(); 1131 quitenv();
925 scraphere(); 1132 scraphere();
@@ -929,16 +1136,23 @@ static void onecommand()
929 intr = 0; 1136 intr = 0;
930 return; 1137 return;
931 } 1138 }
1139
932 inparse = 0; 1140 inparse = 0;
933 brklist = 0; 1141 brklist = 0;
934 intr = 0; 1142 intr = 0;
935 execflg = 0; 1143 execflg = 0;
936 if (!flag['n']) 1144
1145 if (!flag['n']) {
1146 DBGPRINTF(("ONECOMMAND: calling execute, t=outtree=0x%x\n",
1147 outtree));
937 execute(outtree, NOPIPE, NOPIPE, 0); 1148 execute(outtree, NOPIPE, NOPIPE, 0);
1149 }
1150
938 if (!interactive && intr) { 1151 if (!interactive && intr) {
939 execflg = 0; 1152 execflg = 0;
940 leave(); 1153 leave();
941 } 1154 }
1155
942 if ((i = trapset) != 0) { 1156 if ((i = trapset) != 0) {
943 trapset = 0; 1157 trapset = 0;
944 runtrap(i); 1158 runtrap(i);
@@ -953,17 +1167,19 @@ static void fail()
953 1167
954static void leave() 1168static void leave()
955{ 1169{
1170 DBGPRINTF(("LEAVE: leave called!\n"));
1171
956 if (execflg) 1172 if (execflg)
957 fail(); 1173 fail();
958 scraphere(); 1174 scraphere();
959 freehere(1); 1175 freehere(1);
960 runtrap(0); 1176 runtrap(0);
961 exit(exstat); 1177 _exit(exstat);
962 /* NOTREACHED */ 1178 /* NOTREACHED */
963} 1179}
964 1180
965static void warn(s) 1181static void warn(s)
966register char *s; 1182REGISTER char *s;
967{ 1183{
968 if (*s) { 1184 if (*s) {
969 prs(s); 1185 prs(s);
@@ -991,12 +1207,15 @@ char *s;
991static int newenv(f) 1207static int newenv(f)
992int f; 1208int f;
993{ 1209{
994 register struct env *ep; 1210 REGISTER struct env *ep;
1211
1212 DBGPRINTF(("NEWENV: f=%d (indicates quitenv and return)\n", f));
995 1213
996 if (f) { 1214 if (f) {
997 quitenv(); 1215 quitenv();
998 return (1); 1216 return (1);
999 } 1217 }
1218
1000 ep = (struct env *) space(sizeof(*ep)); 1219 ep = (struct env *) space(sizeof(*ep));
1001 if (ep == NULL) { 1220 if (ep == NULL) {
1002 while (e.oenv) 1221 while (e.oenv)
@@ -1006,13 +1225,16 @@ int f;
1006 *ep = e; 1225 *ep = e;
1007 e.oenv = ep; 1226 e.oenv = ep;
1008 e.errpt = errpt; 1227 e.errpt = errpt;
1228
1009 return (0); 1229 return (0);
1010} 1230}
1011 1231
1012static void quitenv() 1232static void quitenv()
1013{ 1233{
1014 register struct env *ep; 1234 REGISTER struct env *ep;
1015 register int fd; 1235 REGISTER int fd;
1236
1237 DBGPRINTF(("QUITENV: e.oenv=0x%x\n", e.oenv));
1016 1238
1017 if ((ep = e.oenv) != NULL) { 1239 if ((ep = e.oenv) != NULL) {
1018 fd = e.iofd; 1240 fd = e.iofd;
@@ -1028,7 +1250,7 @@ static void quitenv()
1028 * Is any character from s1 in s2? 1250 * Is any character from s1 in s2?
1029 */ 1251 */
1030static int anys(s1, s2) 1252static int anys(s1, s2)
1031register char *s1, *s2; 1253REGISTER char *s1, *s2;
1032{ 1254{
1033 while (*s1) 1255 while (*s1)
1034 if (any(*s1++, s2)) 1256 if (any(*s1++, s2))
@@ -1040,8 +1262,8 @@ register char *s1, *s2;
1040 * Is character c in s? 1262 * Is character c in s?
1041 */ 1263 */
1042static int any(c, s) 1264static int any(c, s)
1043register int c; 1265REGISTER int c;
1044register char *s; 1266REGISTER char *s;
1045{ 1267{
1046 while (*s) 1268 while (*s)
1047 if (*s++ == c) 1269 if (*s++ == c)
@@ -1050,13 +1272,13 @@ register char *s;
1050} 1272}
1051 1273
1052static char *putn(n) 1274static char *putn(n)
1053register int n; 1275REGISTER int n;
1054{ 1276{
1055 return (itoa(n)); 1277 return (itoa(n));
1056} 1278}
1057 1279
1058static char *itoa(n) 1280static char *itoa(n)
1059register int n; 1281REGISTER int n;
1060{ 1282{
1061 static char s[20]; 1283 static char s[20];
1062 1284
@@ -1064,6 +1286,7 @@ register int n;
1064 return (s); 1286 return (s);
1065} 1287}
1066 1288
1289
1067static void next(int f) 1290static void next(int f)
1068{ 1291{
1069 PUSHIO(afile, f, filechar); 1292 PUSHIO(afile, f, filechar);
@@ -1088,7 +1311,7 @@ int s; /* ANSI C requires a parameter */
1088static char *space(n) 1311static char *space(n)
1089int n; 1312int n;
1090{ 1313{
1091 register char *cp; 1314 REGISTER char *cp;
1092 1315
1093 if ((cp = getcell(n)) == 0) 1316 if ((cp = getcell(n)) == 0)
1094 err("out of string space"); 1317 err("out of string space");
@@ -1096,10 +1319,10 @@ int n;
1096} 1319}
1097 1320
1098static char *strsave(s, a) 1321static char *strsave(s, a)
1099register char *s; 1322REGISTER char *s;
1100int a; 1323int a;
1101{ 1324{
1102 register char *cp, *xp; 1325 REGISTER char *cp, *xp;
1103 1326
1104 if ((cp = space(strlen(s) + 1)) != NULL) { 1327 if ((cp = space(strlen(s) + 1)) != NULL) {
1105 setarea((char *) cp, a); 1328 setarea((char *) cp, a);
@@ -1113,7 +1336,7 @@ int a;
1113 * trap handling 1336 * trap handling
1114 */ 1337 */
1115static void sig(i) 1338static void sig(i)
1116register int i; 1339REGISTER int i;
1117{ 1340{
1118 trapset = i; 1341 trapset = i;
1119 signal(i, sig); 1342 signal(i, sig);
@@ -1126,8 +1349,10 @@ int i;
1126 1349
1127 if ((trapstr = trap[i]) == NULL) 1350 if ((trapstr = trap[i]) == NULL)
1128 return; 1351 return;
1352
1129 if (i == 0) 1353 if (i == 0)
1130 trap[i] = 0; 1354 trap[i] = 0;
1355
1131 RUN(aword, trapstr, nlchar); 1356 RUN(aword, trapstr, nlchar);
1132} 1357}
1133 1358
@@ -1140,11 +1365,11 @@ int i;
1140 * return a null value. 1365 * return a null value.
1141 */ 1366 */
1142static struct var *lookup(n) 1367static struct var *lookup(n)
1143register char *n; 1368REGISTER char *n;
1144{ 1369{
1145 register struct var *vp; 1370 REGISTER struct var *vp;
1146 register char *cp; 1371 REGISTER char *cp;
1147 register int c; 1372 REGISTER int c;
1148 static struct var dummy; 1373 static struct var dummy;
1149 1374
1150 if (isdigit(*n)) { 1375 if (isdigit(*n)) {
@@ -1195,10 +1420,10 @@ char *val;
1195 * values is reasonably painless. 1420 * values is reasonably painless.
1196 */ 1421 */
1197static void nameval(vp, val, name) 1422static void nameval(vp, val, name)
1198register struct var *vp; 1423REGISTER struct var *vp;
1199char *val, *name; 1424char *val, *name;
1200{ 1425{
1201 register char *cp, *xp; 1426 REGISTER char *cp, *xp;
1202 char *nv; 1427 char *nv;
1203 int fl; 1428 int fl;
1204 1429
@@ -1245,23 +1470,28 @@ struct var *vp;
1245} 1470}
1246 1471
1247static int isassign(s) 1472static int isassign(s)
1248register char *s; 1473REGISTER char *s;
1249{ 1474{
1475 DBGPRINTF7(("ISASSIGN: enter, s=%s\n", s));
1476
1250 if (!isalpha((int) *s) && *s != '_') 1477 if (!isalpha((int) *s) && *s != '_')
1251 return (0); 1478 return (0);
1252 for (; *s != '='; s++) 1479 for (; *s != '='; s++)
1253 if (*s == 0 || (!isalnum(*s) && *s != '_')) 1480 if (*s == 0 || (!isalnum(*s) && *s != '_'))
1254 return (0); 1481 return (0);
1482
1255 return (1); 1483 return (1);
1256} 1484}
1257 1485
1258static int assign(s, cf) 1486static int assign(s, cf)
1259register char *s; 1487REGISTER char *s;
1260int cf; 1488int cf;
1261{ 1489{
1262 register char *cp; 1490 REGISTER char *cp;
1263 struct var *vp; 1491 struct var *vp;
1264 1492
1493 DBGPRINTF7(("ASSIGN: enter, s=%s, cf=%d\n", s, cf));
1494
1265 if (!isalpha(*s) && *s != '_') 1495 if (!isalpha(*s) && *s != '_')
1266 return (0); 1496 return (0);
1267 for (cp = s; *cp != '='; cp++) 1497 for (cp = s; *cp != '='; cp++)
@@ -1275,8 +1505,10 @@ int cf;
1275} 1505}
1276 1506
1277static int checkname(cp) 1507static int checkname(cp)
1278register char *cp; 1508REGISTER char *cp;
1279{ 1509{
1510 DBGPRINTF7(("CHECKNAME: enter, cp=%s\n", cp));
1511
1280 if (!isalpha(*cp++) && *(cp - 1) != '_') 1512 if (!isalpha(*cp++) && *(cp - 1) != '_')
1281 return (0); 1513 return (0);
1282 while (*cp) 1514 while (*cp)
@@ -1286,9 +1518,9 @@ register char *cp;
1286} 1518}
1287 1519
1288static void putvlist(f, out) 1520static void putvlist(f, out)
1289register int f, out; 1521REGISTER int f, out;
1290{ 1522{
1291 register struct var *vp; 1523 REGISTER struct var *vp;
1292 1524
1293 for (vp = vlist; vp; vp = vp->next) 1525 for (vp = vlist; vp; vp = vp->next)
1294 if (vp->status & f && (isalpha(*vp->name) || *vp->name == '_')) { 1526 if (vp->status & f && (isalpha(*vp->name) || *vp->name == '_')) {
@@ -1302,7 +1534,7 @@ register int f, out;
1302} 1534}
1303 1535
1304static int eqname(n1, n2) 1536static int eqname(n1, n2)
1305register char *n1, *n2; 1537REGISTER char *n1, *n2;
1306{ 1538{
1307 for (; *n1 != '=' && *n1 != 0; n1++) 1539 for (; *n1 != '=' && *n1 != 0; n1++)
1308 if (*n2++ != *n1) 1540 if (*n2++ != *n1)
@@ -1311,7 +1543,7 @@ register char *n1, *n2;
1311} 1543}
1312 1544
1313static char *findeq(cp) 1545static char *findeq(cp)
1314register char *cp; 1546REGISTER char *cp;
1315{ 1547{
1316 while (*cp != '\0' && *cp != '=') 1548 while (*cp != '\0' && *cp != '=')
1317 cp++; 1549 cp++;
@@ -1332,9 +1564,9 @@ register char *cp;
1332#define NOT '!' /* might use ^ */ 1564#define NOT '!' /* might use ^ */
1333 1565
1334static int gmatch(s, p) 1566static int gmatch(s, p)
1335register char *s, *p; 1567REGISTER char *s, *p;
1336{ 1568{
1337 register int sc, pc; 1569 REGISTER int sc, pc;
1338 1570
1339 if (s == NULL || p == NULL) 1571 if (s == NULL || p == NULL)
1340 return (0); 1572 return (0);
@@ -1368,10 +1600,10 @@ register char *s, *p;
1368} 1600}
1369 1601
1370static char *cclass(p, sub) 1602static char *cclass(p, sub)
1371register char *p; 1603REGISTER char *p;
1372register int sub; 1604REGISTER int sub;
1373{ 1605{
1374 register int c, d, not, found; 1606 REGISTER int c, d, not, found;
1375 1607
1376 if ((not = *p == NOT) != 0) 1608 if ((not = *p == NOT) != 0)
1377 p++; 1609 p++;
@@ -1404,8 +1636,8 @@ register int sub;
1404 1636
1405static void initarea() 1637static void initarea()
1406{ 1638{
1407 brkaddr = malloc(65000); 1639 brkaddr = malloc(AREASIZE);
1408 brktop = brkaddr + 65000; 1640 brktop = brkaddr + AREASIZE;
1409 1641
1410 while ((int) sbrk(0) & ALIGN) 1642 while ((int) sbrk(0) & ALIGN)
1411 sbrk(1); 1643 sbrk(1);
@@ -1420,9 +1652,9 @@ static void initarea()
1420char *getcell(nbytes) 1652char *getcell(nbytes)
1421unsigned nbytes; 1653unsigned nbytes;
1422{ 1654{
1423 register int nregio; 1655 REGISTER int nregio;
1424 register struct region *p, *q; 1656 REGISTER struct region *p, *q;
1425 register int i; 1657 REGISTER int i;
1426 1658
1427 if (nbytes == 0) { 1659 if (nbytes == 0) {
1428 puts("getcell(0)"); 1660 puts("getcell(0)");
@@ -1489,7 +1721,7 @@ unsigned nbytes;
1489static void freecell(cp) 1721static void freecell(cp)
1490char *cp; 1722char *cp;
1491{ 1723{
1492 register struct region *p; 1724 REGISTER struct region *p;
1493 1725
1494 if ((p = (struct region *) cp) != NULL) { 1726 if ((p = (struct region *) cp) != NULL) {
1495 p--; 1727 p--;
@@ -1500,9 +1732,9 @@ char *cp;
1500} 1732}
1501 1733
1502static void freearea(a) 1734static void freearea(a)
1503register int a; 1735REGISTER int a;
1504{ 1736{
1505 register struct region *p, *top; 1737 REGISTER struct region *p, *top;
1506 1738
1507 top = areatop; 1739 top = areatop;
1508 for (p = areabot; p != top; p = p->next) 1740 for (p = areabot; p != top; p = p->next)
@@ -1514,7 +1746,7 @@ static void setarea(cp, a)
1514char *cp; 1746char *cp;
1515int a; 1747int a;
1516{ 1748{
1517 register struct region *p; 1749 REGISTER struct region *p;
1518 1750
1519 if ((p = (struct region *) cp) != NULL) 1751 if ((p = (struct region *) cp) != NULL)
1520 (p - 1)->area = a; 1752 (p - 1)->area = a;
@@ -1528,7 +1760,7 @@ char *cp;
1528 1760
1529static void garbage() 1761static void garbage()
1530{ 1762{
1531 register struct region *p, *q, *top; 1763 REGISTER struct region *p, *q, *top;
1532 1764
1533 top = areatop; 1765 top = areatop;
1534 for (p = areabot; p != top; p = p->next) { 1766 for (p = areabot; p != top; p = p->next) {
@@ -1553,9 +1785,10 @@ static void garbage()
1553 * shell: syntax (C version) 1785 * shell: syntax (C version)
1554 */ 1786 */
1555 1787
1556
1557int yyparse() 1788int yyparse()
1558{ 1789{
1790 DBGPRINTF7(("YYPARSE: enter...\n"));
1791
1559 startl = 1; 1792 startl = 1;
1560 peeksym = 0; 1793 peeksym = 0;
1561 yynerrs = 0; 1794 yynerrs = 0;
@@ -1567,96 +1800,136 @@ int yyparse()
1567static struct op *pipeline(cf) 1800static struct op *pipeline(cf)
1568int cf; 1801int cf;
1569{ 1802{
1570 register struct op *t, *p; 1803 REGISTER struct op *t, *p;
1571 register int c; 1804 REGISTER int c;
1805
1806 DBGPRINTF7(("PIPELINE: enter, cf=%d\n", cf));
1572 1807
1573 t = command(cf); 1808 t = command(cf);
1809
1810 DBGPRINTF9(("PIPELINE: t=0x%x\n", t));
1811
1574 if (t != NULL) { 1812 if (t != NULL) {
1575 while ((c = yylex(0)) == '|') { 1813 while ((c = yylex(0)) == '|') {
1576 if ((p = command(CONTIN)) == NULL) 1814 if ((p = command(CONTIN)) == NULL) {
1815 DBGPRINTF8(("PIPELINE: error!\n"));
1577 SYNTAXERR; 1816 SYNTAXERR;
1817 }
1818
1578 if (t->type != TPAREN && t->type != TCOM) { 1819 if (t->type != TPAREN && t->type != TCOM) {
1579 /* shell statement */ 1820 /* shell statement */
1580 t = block(TPAREN, t, NOBLOCK, NOWORDS); 1821 t = block(TPAREN, t, NOBLOCK, NOWORDS);
1581 } 1822 }
1823
1582 t = block(TPIPE, t, p, NOWORDS); 1824 t = block(TPIPE, t, p, NOWORDS);
1583 } 1825 }
1584 peeksym = c; 1826 peeksym = c;
1585 } 1827 }
1828
1829 DBGPRINTF7(("PIPELINE: returning t=0x%x\n", t));
1586 return (t); 1830 return (t);
1587} 1831}
1588 1832
1589static struct op *andor() 1833static struct op *andor()
1590{ 1834{
1591 register struct op *t, *p; 1835 REGISTER struct op *t, *p;
1592 register int c; 1836 REGISTER int c;
1837
1838 DBGPRINTF7(("ANDOR: enter...\n"));
1593 1839
1594 t = pipeline(0); 1840 t = pipeline(0);
1841
1842 DBGPRINTF9(("ANDOR: t=0x%x\n", t));
1843
1595 if (t != NULL) { 1844 if (t != NULL) {
1596 while ((c = yylex(0)) == LOGAND || c == LOGOR) { 1845 while ((c = yylex(0)) == LOGAND || c == LOGOR) {
1597 if ((p = pipeline(CONTIN)) == NULL) 1846 if ((p = pipeline(CONTIN)) == NULL) {
1847 DBGPRINTF8(("ANDOR: error!\n"));
1598 SYNTAXERR; 1848 SYNTAXERR;
1849 }
1850
1599 t = block(c == LOGAND ? TAND : TOR, t, p, NOWORDS); 1851 t = block(c == LOGAND ? TAND : TOR, t, p, NOWORDS);
1600 } 1852 } /* WHILE */
1853
1601 peeksym = c; 1854 peeksym = c;
1602 } 1855 }
1856
1857 DBGPRINTF7(("ANDOR: returning t=0x%x\n", t));
1603 return (t); 1858 return (t);
1604} 1859}
1605 1860
1606static struct op *c_list() 1861static struct op *c_list()
1607{ 1862{
1608 register struct op *t, *p; 1863 REGISTER struct op *t, *p;
1609 register int c; 1864 REGISTER int c;
1865
1866 DBGPRINTF7(("C_LIST: enter...\n"));
1610 1867
1611 t = andor(); 1868 t = andor();
1869
1612 if (t != NULL) { 1870 if (t != NULL) {
1613 if ((peeksym = yylex(0)) == '&') 1871 if ((peeksym = yylex(0)) == '&')
1614 t = block(TASYNC, t, NOBLOCK, NOWORDS); 1872 t = block(TASYNC, t, NOBLOCK, NOWORDS);
1873
1615 while ((c = yylex(0)) == ';' || c == '&' 1874 while ((c = yylex(0)) == ';' || c == '&'
1616 || (multiline && c == '\n')) { 1875 || (multiline && c == '\n')) {
1876
1617 if ((p = andor()) == NULL) 1877 if ((p = andor()) == NULL)
1618 return (t); 1878 return (t);
1879
1619 if ((peeksym = yylex(0)) == '&') 1880 if ((peeksym = yylex(0)) == '&')
1620 p = block(TASYNC, p, NOBLOCK, NOWORDS); 1881 p = block(TASYNC, p, NOBLOCK, NOWORDS);
1882
1621 t = list(t, p); 1883 t = list(t, p);
1622 } 1884 } /* WHILE */
1885
1623 peeksym = c; 1886 peeksym = c;
1624 } 1887 }
1888 /* IF */
1889 DBGPRINTF7(("C_LIST: returning t=0x%x\n", t));
1625 return (t); 1890 return (t);
1626} 1891}
1627 1892
1628
1629static int synio(cf) 1893static int synio(cf)
1630int cf; 1894int cf;
1631{ 1895{
1632 register struct ioword *iop; 1896 REGISTER struct ioword *iop;
1633 register int i; 1897 REGISTER int i;
1634 register int c; 1898 REGISTER int c;
1899
1900 DBGPRINTF7(("SYNIO: enter, cf=%d\n", cf));
1635 1901
1636 if ((c = yylex(cf)) != '<' && c != '>') { 1902 if ((c = yylex(cf)) != '<' && c != '>') {
1637 peeksym = c; 1903 peeksym = c;
1638 return (0); 1904 return (0);
1639 } 1905 }
1906
1640 i = yylval.i; 1907 i = yylval.i;
1641 musthave(WORD, 0); 1908 musthave(WORD, 0);
1642 iop = io(iounit, i, yylval.cp); 1909 iop = io(iounit, i, yylval.cp);
1643 iounit = IODEFAULT; 1910 iounit = IODEFAULT;
1911
1644 if (i & IOHERE) 1912 if (i & IOHERE)
1645 markhere(yylval.cp, iop); 1913 markhere(yylval.cp, iop);
1914
1915 DBGPRINTF7(("SYNIO: returning 1\n"));
1646 return (1); 1916 return (1);
1647} 1917}
1648 1918
1649static void musthave(c, cf) 1919static void musthave(c, cf)
1650int c, cf; 1920int c, cf;
1651{ 1921{
1652 if ((peeksym = yylex(cf)) != c) 1922 if ((peeksym = yylex(cf)) != c) {
1923 DBGPRINTF7(("MUSTHAVE: error!\n"));
1653 SYNTAXERR; 1924 SYNTAXERR;
1925 }
1926
1654 peeksym = 0; 1927 peeksym = 0;
1655} 1928}
1656 1929
1657static struct op *simple() 1930static struct op *simple()
1658{ 1931{
1659 register struct op *t; 1932 REGISTER struct op *t;
1660 1933
1661 t = NULL; 1934 t = NULL;
1662 for (;;) { 1935 for (;;) {
@@ -1684,7 +1957,9 @@ static struct op *simple()
1684static struct op *nested(type, mark) 1957static struct op *nested(type, mark)
1685int type, mark; 1958int type, mark;
1686{ 1959{
1687 register struct op *t; 1960 REGISTER struct op *t;
1961
1962 DBGPRINTF3(("NESTED: enter, type=%d, mark=%d\n", type, mark));
1688 1963
1689 multiline++; 1964 multiline++;
1690 t = c_list(); 1965 t = c_list();
@@ -1696,17 +1971,24 @@ int type, mark;
1696static struct op *command(cf) 1971static struct op *command(cf)
1697int cf; 1972int cf;
1698{ 1973{
1699 register struct op *t; 1974 REGISTER struct op *t;
1700 struct wdblock *iosave; 1975 struct wdblock *iosave;
1701 register int c; 1976 REGISTER int c;
1977
1978 DBGPRINTF(("COMMAND: enter, cf=%d\n", cf));
1702 1979
1703 iosave = iolist; 1980 iosave = iolist;
1704 iolist = NULL; 1981 iolist = NULL;
1982
1705 if (multiline) 1983 if (multiline)
1706 cf |= CONTIN; 1984 cf |= CONTIN;
1985
1707 while (synio(cf)) 1986 while (synio(cf))
1708 cf = 0; 1987 cf = 0;
1709 switch (c = yylex(cf)) { 1988
1989 c = yylex(cf);
1990
1991 switch (c) {
1710 default: 1992 default:
1711 peeksym = c; 1993 peeksym = c;
1712 if ((t = simple()) == NULL) { 1994 if ((t = simple()) == NULL) {
@@ -1759,7 +2041,9 @@ int cf;
1759 multiline++; 2041 multiline++;
1760 musthave(IN, CONTIN); 2042 musthave(IN, CONTIN);
1761 startl++; 2043 startl++;
2044
1762 t->left = caselist(); 2045 t->left = caselist();
2046
1763 musthave(ESAC, 0); 2047 musthave(ESAC, 0);
1764 multiline--; 2048 multiline--;
1765 break; 2049 break;
@@ -1773,18 +2057,52 @@ int cf;
1773 musthave(FI, 0); 2057 musthave(FI, 0);
1774 multiline--; 2058 multiline--;
1775 break; 2059 break;
2060
2061 case DOT:
2062 t = newtp();
2063 t->type = TDOT;
2064
2065 musthave(WORD, 0); /* gets name of file */
2066 DBGPRINTF7(("COMMAND: DOT clause, yylval.cp is %s\n", yylval.cp));
2067
2068 word(yylval.cp); /* add word to wdlist */
2069 word(NOWORD); /* terminate wdlist */
2070 t->words = copyw(); /* dup wdlist */
2071 break;
2072
1776 } 2073 }
2074
1777 while (synio(0)); 2075 while (synio(0));
2076
1778 t = namelist(t); 2077 t = namelist(t);
1779 iolist = iosave; 2078 iolist = iosave;
2079
2080 DBGPRINTF(("COMMAND: returning 0x%x\n", t));
2081
2082 return (t);
2083}
2084
2085static struct op *dowholefile(type, mark)
2086int type;
2087int mark;
2088{
2089 REGISTER struct op *t;
2090
2091 DBGPRINTF(("DOWHOLEFILE: enter, type=%d, mark=%d\n", type, mark));
2092
2093 multiline++;
2094 t = c_list();
2095 multiline--;
2096 t = block(type, t, NOBLOCK, NOWORDS);
2097 DBGPRINTF(("DOWHOLEFILE: return t=0x%x\n", t));
1780 return (t); 2098 return (t);
1781} 2099}
1782 2100
1783static struct op *dogroup(onlydone) 2101static struct op *dogroup(onlydone)
1784int onlydone; 2102int onlydone;
1785{ 2103{
1786 register int c; 2104 REGISTER int c;
1787 register struct op *mylist; 2105 REGISTER struct op *mylist;
1788 2106
1789 c = yylex(CONTIN); 2107 c = yylex(CONTIN);
1790 if (c == DONE && onlydone) 2108 if (c == DONE && onlydone)
@@ -1798,8 +2116,8 @@ int onlydone;
1798 2116
1799static struct op *thenpart() 2117static struct op *thenpart()
1800{ 2118{
1801 register int c; 2119 REGISTER int c;
1802 register struct op *t; 2120 REGISTER struct op *t;
1803 2121
1804 if ((c = yylex(0)) != THEN) { 2122 if ((c = yylex(0)) != THEN) {
1805 peeksym = c; 2123 peeksym = c;
@@ -1816,8 +2134,8 @@ static struct op *thenpart()
1816 2134
1817static struct op *elsepart() 2135static struct op *elsepart()
1818{ 2136{
1819 register int c; 2137 REGISTER int c;
1820 register struct op *t; 2138 REGISTER struct op *t;
1821 2139
1822 switch (c = yylex(0)) { 2140 switch (c = yylex(0)) {
1823 case ELSE: 2141 case ELSE:
@@ -1840,17 +2158,23 @@ static struct op *elsepart()
1840 2158
1841static struct op *caselist() 2159static struct op *caselist()
1842{ 2160{
1843 register struct op *t; 2161 REGISTER struct op *t;
1844 2162
1845 t = NULL; 2163 t = NULL;
1846 while ((peeksym = yylex(CONTIN)) != ESAC) 2164 while ((peeksym = yylex(CONTIN)) != ESAC) {
2165 DBGPRINTF(("CASELIST, doing yylex, peeksym=%d\n", peeksym));
1847 t = list(t, casepart()); 2166 t = list(t, casepart());
2167 }
2168
2169 DBGPRINTF(("CASELIST, returning t=0x%x\n", t));
1848 return (t); 2170 return (t);
1849} 2171}
1850 2172
1851static struct op *casepart() 2173static struct op *casepart()
1852{ 2174{
1853 register struct op *t; 2175 REGISTER struct op *t;
2176
2177 DBGPRINTF7(("CASEPART: enter...\n"));
1854 2178
1855 t = newtp(); 2179 t = newtp();
1856 t->type = TPAT; 2180 t->type = TPAT;
@@ -1859,12 +2183,15 @@ static struct op *casepart()
1859 t->left = c_list(); 2183 t->left = c_list();
1860 if ((peeksym = yylex(CONTIN)) != ESAC) 2184 if ((peeksym = yylex(CONTIN)) != ESAC)
1861 musthave(BREAK, CONTIN); 2185 musthave(BREAK, CONTIN);
2186
2187 DBGPRINTF7(("CASEPART: made newtp(TPAT, t=0x%x)\n", t));
2188
1862 return (t); 2189 return (t);
1863} 2190}
1864 2191
1865static char **pattern() 2192static char **pattern()
1866{ 2193{
1867 register int c, cf; 2194 REGISTER int c, cf;
1868 2195
1869 cf = CONTIN; 2196 cf = CONTIN;
1870 do { 2197 do {
@@ -1874,12 +2201,13 @@ static char **pattern()
1874 } while ((c = yylex(0)) == '|'); 2201 } while ((c = yylex(0)) == '|');
1875 peeksym = c; 2202 peeksym = c;
1876 word(NOWORD); 2203 word(NOWORD);
2204
1877 return (copyw()); 2205 return (copyw());
1878} 2206}
1879 2207
1880static char **wordlist() 2208static char **wordlist()
1881{ 2209{
1882 register int c; 2210 REGISTER int c;
1883 2211
1884 if ((c = yylex(0)) != IN) { 2212 if ((c = yylex(0)) != IN) {
1885 peeksym = c; 2213 peeksym = c;
@@ -1897,12 +2225,15 @@ static char **wordlist()
1897 * supporting functions 2225 * supporting functions
1898 */ 2226 */
1899static struct op *list(t1, t2) 2227static struct op *list(t1, t2)
1900register struct op *t1, *t2; 2228REGISTER struct op *t1, *t2;
1901{ 2229{
2230 DBGPRINTF7(("LIST: enter, t1=0x%x, t2=0x%x\n", t1, t2));
2231
1902 if (t1 == NULL) 2232 if (t1 == NULL)
1903 return (t2); 2233 return (t2);
1904 if (t2 == NULL) 2234 if (t2 == NULL)
1905 return (t1); 2235 return (t1);
2236
1906 return (block(TLIST, t1, t2, NOWORDS)); 2237 return (block(TLIST, t1, t2, NOWORDS));
1907} 2238}
1908 2239
@@ -1911,30 +2242,43 @@ int type;
1911struct op *t1, *t2; 2242struct op *t1, *t2;
1912char **wp; 2243char **wp;
1913{ 2244{
1914 register struct op *t; 2245 REGISTER struct op *t;
2246
2247 DBGPRINTF7(("BLOCK: enter, type=%d (%s)\n", type, T_CMD_NAMES[type]));
1915 2248
1916 t = newtp(); 2249 t = newtp();
1917 t->type = type; 2250 t->type = type;
1918 t->left = t1; 2251 t->left = t1;
1919 t->right = t2; 2252 t->right = t2;
1920 t->words = wp; 2253 t->words = wp;
2254
2255 DBGPRINTF7(("BLOCK: inserted 0x%x between 0x%x and 0x%x\n", t, t1,
2256 t2));
2257
1921 return (t); 2258 return (t);
1922} 2259}
1923 2260
2261/* See if given string is a shell multiline (FOR, IF, etc) */
1924static int rlookup(n) 2262static int rlookup(n)
1925register char *n; 2263REGISTER char *n;
1926{ 2264{
1927 register struct res *rp; 2265 REGISTER struct res *rp;
2266
2267 DBGPRINTF7(("RLOOKUP: enter, n is %s\n", n));
1928 2268
1929 for (rp = restab; rp->r_name; rp++) 2269 for (rp = restab; rp->r_name; rp++)
1930 if (strcmp(rp->r_name, n) == 0) 2270 if (strcmp(rp->r_name, n) == 0) {
1931 return (rp->r_val); 2271 DBGPRINTF7(("RLOOKUP: match, returning %d\n", rp->r_val));
1932 return (0); 2272 return (rp->r_val); /* Return numeric code for shell multiline */
2273 }
2274
2275 DBGPRINTF7(("RLOOKUP: NO match, returning 0\n"));
2276 return (0); /* Not a shell multiline */
1933} 2277}
1934 2278
1935static struct op *newtp() 2279static struct op *newtp()
1936{ 2280{
1937 register struct op *t; 2281 REGISTER struct op *t;
1938 2282
1939 t = (struct op *) tree(sizeof(*t)); 2283 t = (struct op *) tree(sizeof(*t));
1940 t->type = 0; 2284 t->type = 0;
@@ -1943,17 +2287,25 @@ static struct op *newtp()
1943 t->left = NULL; 2287 t->left = NULL;
1944 t->right = NULL; 2288 t->right = NULL;
1945 t->str = NULL; 2289 t->str = NULL;
2290
2291 DBGPRINTF3(("NEWTP: allocated 0x%x\n", t));
2292
1946 return (t); 2293 return (t);
1947} 2294}
1948 2295
1949static struct op *namelist(t) 2296static struct op *namelist(t)
1950register struct op *t; 2297REGISTER struct op *t;
1951{ 2298{
2299
2300 DBGPRINTF7(("NAMELIST: enter, t=0x%x, type %s, iolist=0x%x\n", t,
2301 T_CMD_NAMES[t->type], iolist));
2302
1952 if (iolist) { 2303 if (iolist) {
1953 iolist = addword((char *) NULL, iolist); 2304 iolist = addword((char *) NULL, iolist);
1954 t->ioact = copyio(); 2305 t->ioact = copyio();
1955 } else 2306 } else
1956 t->ioact = NULL; 2307 t->ioact = NULL;
2308
1957 if (t->type != TCOM) { 2309 if (t->type != TCOM) {
1958 if (t->type != TPAREN && t->ioact != NULL) { 2310 if (t->type != TPAREN && t->ioact != NULL) {
1959 t = block(TPAREN, t, NOBLOCK, NOWORDS); 2311 t = block(TPAREN, t, NOBLOCK, NOWORDS);
@@ -1962,14 +2314,17 @@ register struct op *t;
1962 } 2314 }
1963 return (t); 2315 return (t);
1964 } 2316 }
2317
1965 word(NOWORD); 2318 word(NOWORD);
1966 t->words = copyw(); 2319 t->words = copyw();
2320
2321
1967 return (t); 2322 return (t);
1968} 2323}
1969 2324
1970static char **copyw() 2325static char **copyw()
1971{ 2326{
1972 register char **wd; 2327 REGISTER char **wd;
1973 2328
1974 wd = getwords(wdlist); 2329 wd = getwords(wdlist);
1975 wdlist = 0; 2330 wdlist = 0;
@@ -1984,7 +2339,7 @@ char *cp;
1984 2339
1985static struct ioword **copyio() 2340static struct ioword **copyio()
1986{ 2341{
1987 register struct ioword **iop; 2342 REGISTER struct ioword **iop;
1988 2343
1989 iop = (struct ioword **) getwords(iolist); 2344 iop = (struct ioword **) getwords(iolist);
1990 iolist = 0; 2345 iolist = 0;
@@ -1996,7 +2351,7 @@ int u;
1996int f; 2351int f;
1997char *cp; 2352char *cp;
1998{ 2353{
1999 register struct ioword *iop; 2354 REGISTER struct ioword *iop;
2000 2355
2001 iop = (struct ioword *) tree(sizeof(*iop)); 2356 iop = (struct ioword *) tree(sizeof(*iop));
2002 iop->io_unit = u; 2357 iop->io_unit = u;
@@ -2026,7 +2381,7 @@ char *s;
2026static int yylex(cf) 2381static int yylex(cf)
2027int cf; 2382int cf;
2028{ 2383{
2029 register int c, c1; 2384 REGISTER int c, c1;
2030 int atstart; 2385 int atstart;
2031 2386
2032 if ((c = peeksym) > 0) { 2387 if ((c = peeksym) > 0) {
@@ -2035,14 +2390,21 @@ int cf;
2035 startl = 1; 2390 startl = 1;
2036 return (c); 2391 return (c);
2037 } 2392 }
2393
2394
2038 nlseen = 0; 2395 nlseen = 0;
2039 e.linep = line;
2040 atstart = startl; 2396 atstart = startl;
2041 startl = 0; 2397 startl = 0;
2042 yylval.i = 0; 2398 yylval.i = 0;
2399 e.linep = line;
2400
2401/* MALAMO */
2402 line[LINELIM - 1] = '\0';
2043 2403
2044 loop: 2404 loop:
2045 while ((c = my_getc(0)) == ' ' || c == '\t'); 2405 while ((c = my_getc(0)) == ' ' || c == '\t') /* Skip whitespace */
2406 ;
2407
2046 switch (c) { 2408 switch (c) {
2047 default: 2409 default:
2048 if (any(c, "0123456789")) { 2410 if (any(c, "0123456789")) {
@@ -2056,15 +2418,17 @@ int cf;
2056 } 2418 }
2057 break; 2419 break;
2058 2420
2059 case '#': 2421 case '#': /* Comment, skip to next newline or End-of-string */
2060 while ((c = my_getc(0)) != 0 && c != '\n'); 2422 while ((c = my_getc(0)) != 0 && c != '\n');
2061 unget(c); 2423 unget(c);
2062 goto loop; 2424 goto loop;
2063 2425
2064 case 0: 2426 case 0:
2427 DBGPRINTF5(("YYLEX: return 0, c=%d\n", c));
2065 return (c); 2428 return (c);
2066 2429
2067 case '$': 2430 case '$':
2431 DBGPRINTF9(("YYLEX: found $\n"));
2068 *e.linep++ = c; 2432 *e.linep++ = c;
2069 if ((c = my_getc(0)) == '{') { 2433 if ((c = my_getc(0)) == '{') {
2070 if ((c = collect(c, '}')) != '\0') 2434 if ((c = collect(c, '}')) != '\0')
@@ -2083,12 +2447,13 @@ int cf;
2083 case '|': 2447 case '|':
2084 case '&': 2448 case '&':
2085 case ';': 2449 case ';':
2086 if ((c1 = dual(c)) != '\0') {
2087 startl = 1;
2088 return (c1);
2089 }
2090 startl = 1; 2450 startl = 1;
2091 return (c); 2451 /* If more chars process them, else return NULL char */
2452 if ((c1 = dual(c)) != '\0')
2453 return (c1);
2454 else
2455 return (c);
2456
2092 case '^': 2457 case '^':
2093 startl = 1; 2458 startl = 1;
2094 return ('|'); 2459 return ('|');
@@ -2123,28 +2488,37 @@ int cf;
2123 unget(c); 2488 unget(c);
2124 2489
2125 pack: 2490 pack:
2126 while ((c = my_getc(0)) != 0 && !any(c, "`$ '\"\t;&<>()|^\n")) 2491 while ((c = my_getc(0)) != 0 && !any(c, "`$ '\"\t;&<>()|^\n")) {
2127 if (e.linep >= elinep) 2492 if (e.linep >= elinep)
2128 err("word too long"); 2493 err("word too long");
2129 else 2494 else
2130 *e.linep++ = c; 2495 *e.linep++ = c;
2496 };
2497
2131 unget(c); 2498 unget(c);
2499
2132 if (any(c, "\"'`$")) 2500 if (any(c, "\"'`$"))
2133 goto loop; 2501 goto loop;
2502
2134 *e.linep++ = '\0'; 2503 *e.linep++ = '\0';
2504
2135 if (atstart && (c = rlookup(line)) != 0) { 2505 if (atstart && (c = rlookup(line)) != 0) {
2136 startl = 1; 2506 startl = 1;
2137 return (c); 2507 return (c);
2138 } 2508 }
2509
2139 yylval.cp = strsave(line, areanum); 2510 yylval.cp = strsave(line, areanum);
2140 return (WORD); 2511 return (WORD);
2141} 2512}
2142 2513
2514
2143static int collect(c, c1) 2515static int collect(c, c1)
2144register int c, c1; 2516REGISTER int c, c1;
2145{ 2517{
2146 char s[2]; 2518 char s[2];
2147 2519
2520 DBGPRINTF8(("COLLECT: enter, c=%d, c1=%d\n", c, c1));
2521
2148 *e.linep++ = c; 2522 *e.linep++ = c;
2149 while ((c = my_getc(c1)) != c1) { 2523 while ((c = my_getc(c1)) != c1) {
2150 if (c == 0) { 2524 if (c == 0) {
@@ -2164,28 +2538,41 @@ register int c, c1;
2164 } 2538 }
2165 *e.linep++ = c; 2539 *e.linep++ = c;
2166 } 2540 }
2541
2167 *e.linep++ = c; 2542 *e.linep++ = c;
2543
2544 DBGPRINTF8(("COLLECT: return 0, line is %s\n", line));
2545
2168 return (0); 2546 return (0);
2169} 2547}
2170 2548
2549/* "multiline commands" helper func */
2550/* see if next 2 chars form a shell multiline */
2171static int dual(c) 2551static int dual(c)
2172register int c; 2552REGISTER int c;
2173{ 2553{
2174 char s[3]; 2554 char s[3];
2175 register char *cp = s; 2555 REGISTER char *cp = s;
2176 2556
2177 *cp++ = c; 2557 DBGPRINTF8(("DUAL: enter, c=%d\n", c));
2178 *cp++ = my_getc(0); 2558
2179 *cp = 0; 2559 *cp++ = c; /* c is the given "peek" char */
2180 if ((c = rlookup(s)) == 0) 2560 *cp++ = my_getc(0); /* get next char of input */
2181 unget(*--cp); 2561 *cp = 0; /* add EOS marker */
2182 return (c); 2562
2563 c = rlookup(s); /* see if 2 chars form a shell multiline */
2564 if (c == 0)
2565 unget(*--cp); /* String is not a shell multiline, put peek char back */
2566
2567 return (c); /* String is multiline, return numeric multiline (restab) code */
2183} 2568}
2184 2569
2185static void diag(ec) 2570static void diag(ec)
2186register int ec; 2571REGISTER int ec;
2187{ 2572{
2188 register int c; 2573 REGISTER int c;
2574
2575 DBGPRINTF8(("DIAG: enter, ec=%d\n", ec));
2189 2576
2190 c = my_getc(0); 2577 c = my_getc(0);
2191 if (c == '>' || c == '<') { 2578 if (c == '>' || c == '<') {
@@ -2204,9 +2591,10 @@ register int ec;
2204static char *tree(size) 2591static char *tree(size)
2205unsigned size; 2592unsigned size;
2206{ 2593{
2207 register char *t; 2594 REGISTER char *t;
2208 2595
2209 if ((t = getcell(size)) == NULL) { 2596 if ((t = getcell(size)) == NULL) {
2597 DBGPRINTF2(("TREE: getcell(%d) failed!\n", size));
2210 prs("command line too complicated\n"); 2598 prs("command line too complicated\n");
2211 fail(); 2599 fail();
2212 /* NOTREACHED */ 2600 /* NOTREACHED */
@@ -2225,14 +2613,15 @@ unsigned size;
2225 2613
2226 2614
2227static int execute(t, pin, pout, act) 2615static int execute(t, pin, pout, act)
2228register struct op *t; 2616REGISTER struct op *t;
2229int *pin, *pout; 2617int *pin, *pout;
2230int act; 2618int act;
2231{ 2619{
2232 register struct op *t1; 2620 REGISTER struct op *t1;
2233 volatile int i, rv, a; 2621 volatile int i, rv, a;
2234 char *cp, **wp, **wp2; 2622 char *cp, **wp, **wp2;
2235 struct var *vp; 2623 struct var *vp;
2624 struct op *outtree_save;
2236 struct brkcon bc; 2625 struct brkcon bc;
2237 2626
2238#if __GNUC__ 2627#if __GNUC__
@@ -2240,29 +2629,59 @@ int act;
2240 (void) &wp; 2629 (void) &wp;
2241#endif 2630#endif
2242 2631
2243 2632 if (t == NULL) {
2244 if (t == NULL) 2633 DBGPRINTF4(("EXECUTE: enter, t==null, returning.\n"));
2245 return (0); 2634 return (0);
2635 }
2636
2637 DBGPRINTF(("EXECUTE: t=0x%x, t->type=%d (%s), t->words is %s\n", t,
2638 t->type, T_CMD_NAMES[t->type],
2639 ((t->words == NULL) ? "NULL" : t->words[0])));
2640
2246 rv = 0; 2641 rv = 0;
2247 a = areanum++; 2642 a = areanum++;
2248 wp = (wp2 = t->words) != NULL 2643 wp = (wp2 = t->words) != NULL
2249 ? eval(wp2, t->type == TCOM ? DOALL : DOALL & ~DOKEY) 2644 ? eval(wp2, t->type == TCOM ? DOALL : DOALL & ~DOKEY)
2250 : NULL; 2645 : NULL;
2251 2646
2647/* Hard to know how many words there are, be careful of garbage pointer values */
2648/* They are likely to cause "PCI bus fault" errors */
2649#if 0
2650 DBGPRINTF(("EXECUTE: t->left=0x%x, t->right=0x%x, t->words[1] is %s\n",
2651 t->left, t->right,
2652 ((t->words[1] == NULL) ? "NULL" : t->words[1])));
2653 DBGPRINTF7(("EXECUTE: t->words[2] is %s, t->words[3] is %s\n",
2654 ((t->words[2] == NULL) ? "NULL" : t->words[2]),
2655 ((t->words[3] == NULL) ? "NULL" : t->words[3])));
2656#endif
2657
2658
2252 switch (t->type) { 2659 switch (t->type) {
2660 case TDOT:
2661 DBGPRINTF3(("EXECUTE: TDOT\n"));
2662
2663 outtree_save = outtree;
2664
2665 newfile(evalstr(t->words[0], DOALL));
2666
2667 t->left = dowholefile(TLIST, 0);
2668 t->right = NULL;
2669
2670 outtree = outtree_save;
2671
2672 if (t->left)
2673 rv = execute(t->left, pin, pout, 0);
2674 if (t->right)
2675 rv = execute(t->right, pin, pout, 0);
2676 break;
2677
2253 case TPAREN: 2678 case TPAREN:
2254 rv = execute(t->left, pin, pout, 0); 2679 rv = execute(t->left, pin, pout, 0);
2255 break; 2680 break;
2256 2681
2257 case TCOM: 2682 case TCOM:
2258 { 2683 {
2259 int child; 2684 rv = forkexec(t, pin, pout, act, wp);
2260
2261 rv = forkexec(t, pin, pout, act, wp, &child);
2262 if (child) {
2263 exstat = rv;
2264 leave();
2265 }
2266 } 2685 }
2267 break; 2686 break;
2268 2687
@@ -2288,6 +2707,8 @@ int act;
2288 { 2707 {
2289 int hinteractive = interactive; 2708 int hinteractive = interactive;
2290 2709
2710 DBGPRINTF7(("EXECUTE: TASYNC clause, calling vfork()...\n"));
2711
2291 i = vfork(); 2712 i = vfork();
2292 if (i != 0) { 2713 if (i != 0) {
2293 interactive = hinteractive; 2714 interactive = hinteractive;
@@ -2312,7 +2733,7 @@ int act;
2312 close(0); 2733 close(0);
2313 open("/dev/null", 0); 2734 open("/dev/null", 0);
2314 } 2735 }
2315 exit(execute(t->left, pin, pout, FEXEC)); 2736 _exit(execute(t->left, pin, pout, FEXEC));
2316 } 2737 }
2317 } 2738 }
2318 break; 2739 break;
@@ -2369,8 +2790,16 @@ int act;
2369 case TCASE: 2790 case TCASE:
2370 if ((cp = evalstr(t->str, DOSUB | DOTRIM)) == 0) 2791 if ((cp = evalstr(t->str, DOSUB | DOTRIM)) == 0)
2371 cp = ""; 2792 cp = "";
2372 if ((t1 = findcase(t->left, cp)) != NULL) 2793
2794 DBGPRINTF7(("EXECUTE: TCASE, t->str is %s, cp is %s\n",
2795 ((t->str == NULL) ? "NULL" : t->str),
2796 ((cp == NULL) ? "NULL" : cp)));
2797
2798 if ((t1 = findcase(t->left, cp)) != NULL) {
2799 DBGPRINTF7(("EXECUTE: TCASE, calling execute(t=0x%x, t1=0x%x)...\n", t, t1));
2373 rv = execute(t1, pin, pout, 0); 2800 rv = execute(t1, pin, pout, 0);
2801 DBGPRINTF7(("EXECUTE: TCASE, back from execute(t=0x%x, t1=0x%x)...\n", t, t1));
2802 }
2374 break; 2803 break;
2375 2804
2376 case TBRACE: 2805 case TBRACE:
@@ -2385,7 +2814,8 @@ int act;
2385 if (rv >= 0 && (t1 = t->left)) 2814 if (rv >= 0 && (t1 = t->left))
2386 rv = execute(t1, pin, pout, 0); 2815 rv = execute(t1, pin, pout, 0);
2387 break; 2816 break;
2388 } 2817
2818 };
2389 2819
2390 broken: 2820 broken:
2391 t->words = wp2; 2821 t->words = wp2;
@@ -2397,28 +2827,31 @@ int act;
2397 closeall(); 2827 closeall();
2398 fail(); 2828 fail();
2399 } 2829 }
2830
2400 if ((i = trapset) != 0) { 2831 if ((i = trapset) != 0) {
2401 trapset = 0; 2832 trapset = 0;
2402 runtrap(i); 2833 runtrap(i);
2403 } 2834 }
2835
2836 DBGPRINTF(("EXECUTE: returning from t=0x%x, rv=%d\n", t, rv));
2404 return (rv); 2837 return (rv);
2405} 2838}
2406 2839
2407static int 2840static int
2408forkexec(register struct op *t, int *pin, int *pout, int act, char **wp, 2841forkexec(REGISTER struct op *t, int *pin, int *pout, int act, char **wp)
2409 int *pforked)
2410{ 2842{
2843 pid_t newpid;
2411 int i, rv; 2844 int i, rv;
2412 int (*shcom) (struct op *) = NULL; 2845 int (*shcom) (struct op *) = NULL;
2413 register int f; 2846 REGISTER int f;
2414 char *cp = NULL; 2847 char *cp = NULL;
2415 struct ioword **iopp; 2848 struct ioword **iopp;
2416 int resetsig; 2849 int resetsig;
2417 char **owp; 2850 char **owp;
2851 int forked = 0;
2418 2852
2419 int *hpin = pin; 2853 int *hpin = pin;
2420 int *hpout = pout; 2854 int *hpout = pout;
2421 int hforked;
2422 char *hwp; 2855 char *hwp;
2423 int hinteractive; 2856 int hinteractive;
2424 int hintr; 2857 int hintr;
@@ -2436,9 +2869,28 @@ forkexec(register struct op *t, int *pin, int *pout, int act, char **wp,
2436 (void) &owp; 2869 (void) &owp;
2437#endif 2870#endif
2438 2871
2872 DBGPRINTF(("FORKEXEC: t=0x%x, pin 0x%x, pout 0x%x, act %d\n", t, pin,
2873 pout, act));
2874 DBGPRINTF7(("FORKEXEC: t->words is %s\n",
2875 ((t->words == NULL) ? "NULL" : t->words[0])));
2876
2877/* Hard to know how many words there are, be careful of garbage pointer values */
2878/* They are likely to cause "PCI bus fault" errors */
2879#if 0
2880 DBGPRINTF7(("FORKEXEC: t->words is %s, t->words[1] is %s\n",
2881 ((t->words == NULL) ? "NULL" : t->words[0]),
2882 ((t->words == NULL) ? "NULL" : t->words[1])));
2883 DBGPRINTF7(("FORKEXEC: wp is %s, wp[1] is %s\n",
2884 ((wp == NULL) ? "NULL" : wp[0]),
2885 ((wp[1] == NULL) ? "NULL" : wp[1])));
2886 DBGPRINTF7(("FORKEXEC: wp2 is %s, wp[3] is %s\n",
2887 ((wp[2] == NULL) ? "NULL" : wp[2]),
2888 ((wp[3] == NULL) ? "NULL" : wp[3])));
2889#endif
2890
2891
2439 owp = wp; 2892 owp = wp;
2440 resetsig = 0; 2893 resetsig = 0;
2441 *pforked = 0;
2442 rv = -1; /* system-detected error */ 2894 rv = -1; /* system-detected error */
2443 if (t->type == TCOM) { 2895 if (t->type == TCOM) {
2444 while ((cp = *wp++) != NULL); 2896 while ((cp = *wp++) != NULL);
@@ -2446,47 +2898,85 @@ forkexec(register struct op *t, int *pin, int *pout, int act, char **wp,
2446 2898
2447 /* strip all initial assignments */ 2899 /* strip all initial assignments */
2448 /* not correct wrt PATH=yyy command etc */ 2900 /* not correct wrt PATH=yyy command etc */
2449 if (flag['x']) 2901 if (flag['x']) {
2902 DBGPRINTF9(("FORKEXEC: echo'ing, cp=0x%x, wp=0x%x, owp=0x%x\n",
2903 cp, wp, owp));
2450 echo(cp ? wp : owp); 2904 echo(cp ? wp : owp);
2905 }
2906#if 0
2907 DBGPRINTF9(("FORKEXEC: t->words is %s, t->words[1] is %s\n",
2908 ((t->words == NULL) ? "NULL" : t->words[0]),
2909 ((t->words == NULL) ? "NULL" : t->words[1])));
2910 DBGPRINTF9(("FORKEXEC: wp is %s, wp[1] is %s\n",
2911 ((wp == NULL) ? "NULL" : wp[0]),
2912 ((wp == NULL) ? "NULL" : wp[1])));
2913#endif
2914
2451 if (cp == NULL && t->ioact == NULL) { 2915 if (cp == NULL && t->ioact == NULL) {
2452 while ((cp = *owp++) != NULL && assign(cp, COPYV)); 2916 while ((cp = *owp++) != NULL && assign(cp, COPYV));
2917 DBGPRINTF(("FORKEXEC: returning setstatus()\n"));
2453 return (setstatus(0)); 2918 return (setstatus(0));
2454 } else if (cp != NULL) 2919 } else if (cp != NULL) {
2455 shcom = inbuilt(cp); 2920 shcom = inbuilt(cp);
2921 }
2456 } 2922 }
2923
2457 t->words = wp; 2924 t->words = wp;
2458 f = act; 2925 f = act;
2459 if (shcom == NULL && (f & FEXEC) == 0) {
2460 2926
2927#if 0
2928 DBGPRINTF3(("FORKEXEC: t->words is %s, t->words[1] is %s\n",
2929 ((t->words == NULL) ? "NULL" : t->words[0]),
2930 ((t->words == NULL) ? "NULL" : t->words[1])));
2931#endif
2932 DBGPRINTF(("FORKEXEC: shcom 0x%x, f&FEXEC 0x%x, owp 0x%x\n", shcom,
2933 f & FEXEC, owp));
2934
2935 if (shcom == NULL && (f & FEXEC) == 0) {
2936 /* Save values in case the child process alters them */
2461 hpin = pin; 2937 hpin = pin;
2462 hpout = pout; 2938 hpout = pout;
2463 hforked = *pforked;
2464 hwp = *wp; 2939 hwp = *wp;
2465 hinteractive = interactive; 2940 hinteractive = interactive;
2466 hintr = intr; 2941 hintr = intr;
2467 hbrklist = brklist; 2942 hbrklist = brklist;
2468 hexecflg = execflg; 2943 hexecflg = execflg;
2469 2944
2470 i = vfork(); 2945 DBGPRINTF3(("FORKEXEC: calling vfork()...\n"));
2471 if (i != 0) { 2946
2472 /* who wrote this crappy non vfork safe shit? */ 2947 newpid = vfork();
2948
2949 if (newpid == -1) {
2950 DBGPRINTF(("FORKEXEC: ERROR, unable to vfork()!\n"));
2951 return (-1);
2952 }
2953
2954
2955 if (newpid > 0) { /* Parent */
2956
2957 /* Restore values */
2473 pin = hpin; 2958 pin = hpin;
2474 pout = hpout; 2959 pout = hpout;
2475 *pforked = hforked;
2476 *wp = hwp; 2960 *wp = hwp;
2477 interactive = hinteractive; 2961 interactive = hinteractive;
2478 intr = hintr; 2962 intr = hintr;
2479 brklist = hbrklist; 2963 brklist = hbrklist;
2480 execflg = hexecflg; 2964 execflg = hexecflg;
2481 2965
2482 *pforked = 0; 2966/* moved up
2483 if (i == -1) 2967 if (i == -1)
2484 return (rv); 2968 return(rv);
2969*/
2970
2485 if (pin != NULL) 2971 if (pin != NULL)
2486 closepipe(pin); 2972 closepipe(pin);
2487 return (pout == NULL ? setstatus(waitfor(i, 0)) : 0); 2973
2974 return (pout == NULL ? setstatus(waitfor(newpid, 0)) : 0);
2488 } 2975 }
2489 2976
2977 /* Must be the child process, pid should be 0 */
2978 DBGPRINTF(("FORKEXEC: child process, shcom=0x%x\n", shcom));
2979
2490 if (interactive) { 2980 if (interactive) {
2491 signal(SIGINT, SIG_IGN); 2981 signal(SIGINT, SIG_IGN);
2492 signal(SIGQUIT, SIG_IGN); 2982 signal(SIGQUIT, SIG_IGN);
@@ -2494,20 +2984,26 @@ forkexec(register struct op *t, int *pin, int *pout, int act, char **wp,
2494 } 2984 }
2495 interactive = 0; 2985 interactive = 0;
2496 intr = 0; 2986 intr = 0;
2497 (*pforked)++; 2987 forked = 1;
2498 brklist = 0; 2988 brklist = 0;
2499 execflg = 0; 2989 execflg = 0;
2500 } 2990 }
2991
2992
2501 if (owp != NULL) 2993 if (owp != NULL)
2502 while ((cp = *owp++) != NULL && assign(cp, COPYV)) 2994 while ((cp = *owp++) != NULL && assign(cp, COPYV))
2503 if (shcom == NULL) 2995 if (shcom == NULL)
2504 export(lookup(cp)); 2996 export(lookup(cp));
2997
2505#ifdef COMPIPE 2998#ifdef COMPIPE
2506 if ((pin != NULL || pout != NULL) && shcom != NULL && shcom != doexec) { 2999 if ((pin != NULL || pout != NULL) && shcom != NULL && shcom != doexec) {
2507 err("piping to/from shell builtins not yet done"); 3000 err("piping to/from shell builtins not yet done");
3001 if (forked)
3002 _exit(-1);
2508 return (-1); 3003 return (-1);
2509 } 3004 }
2510#endif 3005#endif
3006
2511 if (pin != NULL) { 3007 if (pin != NULL) {
2512 dup2(pin[0], 0); 3008 dup2(pin[0], 0);
2513 closepipe(pin); 3009 closepipe(pin);
@@ -2516,18 +3012,31 @@ forkexec(register struct op *t, int *pin, int *pout, int act, char **wp,
2516 dup2(pout[1], 1); 3012 dup2(pout[1], 1);
2517 closepipe(pout); 3013 closepipe(pout);
2518 } 3014 }
3015
2519 if ((iopp = t->ioact) != NULL) { 3016 if ((iopp = t->ioact) != NULL) {
2520 if (shcom != NULL && shcom != doexec) { 3017 if (shcom != NULL && shcom != doexec) {
2521 prs(cp); 3018 prs(cp);
2522 err(": cannot redirect shell command"); 3019 err(": cannot redirect shell command");
3020 if (forked)
3021 _exit(-1);
2523 return (-1); 3022 return (-1);
2524 } 3023 }
2525 while (*iopp) 3024 while (*iopp)
2526 if (iosetup(*iopp++, pin != NULL, pout != NULL)) 3025 if (iosetup(*iopp++, pin != NULL, pout != NULL)) {
3026 if (forked)
3027 _exit(rv);
2527 return (rv); 3028 return (rv);
3029 }
3030 }
3031
3032 if (shcom) {
3033 i = setstatus((*shcom) (t));
3034 if (forked)
3035 _exit(i);
3036 DBGPRINTF(("FORKEXEC: returning i=%d\n", i));
3037 return (i);
2528 } 3038 }
2529 if (shcom) 3039
2530 return (setstatus((*shcom) (t)));
2531 /* should use FIOCEXCL */ 3040 /* should use FIOCEXCL */
2532 for (i = FDBASE; i < NOFILE; i++) 3041 for (i = FDBASE; i < NOFILE; i++)
2533 close(i); 3042 close(i);
@@ -2535,20 +3044,24 @@ forkexec(register struct op *t, int *pin, int *pout, int act, char **wp,
2535 signal(SIGINT, SIG_DFL); 3044 signal(SIGINT, SIG_DFL);
2536 signal(SIGQUIT, SIG_DFL); 3045 signal(SIGQUIT, SIG_DFL);
2537 } 3046 }
3047
2538 if (t->type == TPAREN) 3048 if (t->type == TPAREN)
2539 exit(execute(t->left, NOPIPE, NOPIPE, FEXEC)); 3049 _exit(execute(t->left, NOPIPE, NOPIPE, FEXEC));
2540 if (wp[0] == NULL) 3050 if (wp[0] == NULL)
2541 exit(0); 3051 _exit(0);
2542 3052
2543 cp = rexecve(wp[0], wp, makenv()); 3053 cp = rexecve(wp[0], wp, makenv(0));
2544 prs(wp[0]); 3054 prs(wp[0]);
2545 prs(": "); 3055 prs(": ");
2546 warn(cp); 3056 err(cp);
2547 if (!execflg) 3057 if (!execflg)
2548 trap[0] = NULL; 3058 trap[0] = NULL;
3059
3060 DBGPRINTF(("FORKEXEC: calling leave(), pid=%d\n", newpid));
3061
2549 leave(); 3062 leave();
2550 /* NOTREACHED */ 3063 /* NOTREACHED */
2551 exit(1); 3064 _exit(1);
2552} 3065}
2553 3066
2554/* 3067/*
@@ -2556,24 +3069,31 @@ forkexec(register struct op *t, int *pin, int *pout, int act, char **wp,
2556 * within pipelines. 3069 * within pipelines.
2557 */ 3070 */
2558static int iosetup(iop, pipein, pipeout) 3071static int iosetup(iop, pipein, pipeout)
2559register struct ioword *iop; 3072REGISTER struct ioword *iop;
2560int pipein, pipeout; 3073int pipein, pipeout;
2561{ 3074{
2562 register int u = -1; 3075 REGISTER int u = -1;
2563 char *cp = NULL, *msg; 3076 char *cp = NULL, *msg;
2564 3077
3078 DBGPRINTF(("IOSETUP: iop 0x%x, pipein 0x%x, pipeout 0x%x\n", iop,
3079 pipein, pipeout));
3080
2565 if (iop->io_unit == IODEFAULT) /* take default */ 3081 if (iop->io_unit == IODEFAULT) /* take default */
2566 iop->io_unit = iop->io_flag & (IOREAD | IOHERE) ? 0 : 1; 3082 iop->io_unit = iop->io_flag & (IOREAD | IOHERE) ? 0 : 1;
3083
2567 if (pipein && iop->io_unit == 0) 3084 if (pipein && iop->io_unit == 0)
2568 return (0); 3085 return (0);
3086
2569 if (pipeout && iop->io_unit == 1) 3087 if (pipeout && iop->io_unit == 1)
2570 return (0); 3088 return (0);
3089
2571 msg = iop->io_flag & (IOREAD | IOHERE) ? "open" : "create"; 3090 msg = iop->io_flag & (IOREAD | IOHERE) ? "open" : "create";
2572 if ((iop->io_flag & IOHERE) == 0) { 3091 if ((iop->io_flag & IOHERE) == 0) {
2573 cp = iop->io_name; 3092 cp = iop->io_name;
2574 if ((cp = evalstr(cp, DOSUB | DOTRIM)) == NULL) 3093 if ((cp = evalstr(cp, DOSUB | DOTRIM)) == NULL)
2575 return (1); 3094 return (1);
2576 } 3095 }
3096
2577 if (iop->io_flag & IODUP) { 3097 if (iop->io_flag & IODUP) {
2578 if (cp[1] || (!isdigit(*cp) && *cp != '-')) { 3098 if (cp[1] || (!isdigit(*cp) && *cp != '-')) {
2579 prs(cp); 3099 prs(cp);
@@ -2627,9 +3147,9 @@ int pipein, pipeout;
2627} 3147}
2628 3148
2629static void echo(wp) 3149static void echo(wp)
2630register char **wp; 3150REGISTER char **wp;
2631{ 3151{
2632 register int i; 3152 REGISTER int i;
2633 3153
2634 prs("+"); 3154 prs("+");
2635 for (i = 0; wp[i]; i++) { 3155 for (i = 0; wp[i]; i++) {
@@ -2644,21 +3164,36 @@ static struct op **find1case(t, w)
2644struct op *t; 3164struct op *t;
2645char *w; 3165char *w;
2646{ 3166{
2647 register struct op *t1; 3167 REGISTER struct op *t1;
2648 struct op **tp; 3168 struct op **tp;
2649 register char **wp, *cp; 3169 REGISTER char **wp, *cp;
3170
2650 3171
2651 if (t == NULL) 3172 if (t == NULL) {
3173 DBGPRINTF3(("FIND1CASE: enter, t==NULL, returning.\n"));
2652 return ((struct op **) NULL); 3174 return ((struct op **) NULL);
3175 }
3176
3177 DBGPRINTF3(("FIND1CASE: enter, t->type=%d (%s)\n", t->type,
3178 T_CMD_NAMES[t->type]));
3179
2653 if (t->type == TLIST) { 3180 if (t->type == TLIST) {
2654 if ((tp = find1case(t->left, w)) != NULL) 3181 if ((tp = find1case(t->left, w)) != NULL) {
3182 DBGPRINTF3(("FIND1CASE: found one to the left, returning tp=0x%x\n", tp));
2655 return (tp); 3183 return (tp);
3184 }
2656 t1 = t->right; /* TPAT */ 3185 t1 = t->right; /* TPAT */
2657 } else 3186 } else
2658 t1 = t; 3187 t1 = t;
3188
2659 for (wp = t1->words; *wp;) 3189 for (wp = t1->words; *wp;)
2660 if ((cp = evalstr(*wp++, DOSUB)) && gmatch(w, cp)) 3190 if ((cp = evalstr(*wp++, DOSUB)) && gmatch(w, cp)) {
3191 DBGPRINTF3(("FIND1CASE: returning &t1->left= 0x%x.\n",
3192 &t1->left));
2661 return (&t1->left); 3193 return (&t1->left);
3194 }
3195
3196 DBGPRINTF(("FIND1CASE: returning NULL\n"));
2662 return ((struct op **) NULL); 3197 return ((struct op **) NULL);
2663} 3198}
2664 3199
@@ -2666,7 +3201,7 @@ static struct op *findcase(t, w)
2666struct op *t; 3201struct op *t;
2667char *w; 3202char *w;
2668{ 3203{
2669 register struct op **tp; 3204 REGISTER struct op **tp;
2670 3205
2671 return ((tp = find1case(t, w)) != NULL ? *tp : (struct op *) NULL); 3206 return ((tp = find1case(t, w)) != NULL ? *tp : (struct op *) NULL);
2672} 3207}
@@ -2689,10 +3224,10 @@ struct brkcon *bc;
2689 * unless `canintr' is true. 3224 * unless `canintr' is true.
2690 */ 3225 */
2691static int waitfor(lastpid, canintr) 3226static int waitfor(lastpid, canintr)
2692register int lastpid; 3227REGISTER int lastpid;
2693int canintr; 3228int canintr;
2694{ 3229{
2695 register int pid, rv; 3230 REGISTER int pid, rv;
2696 int s; 3231 int s;
2697 int oheedint = heedint; 3232 int oheedint = heedint;
2698 3233
@@ -2746,7 +3281,7 @@ int canintr;
2746} 3281}
2747 3282
2748static int setstatus(s) 3283static int setstatus(s)
2749register int s; 3284REGISTER int s;
2750{ 3285{
2751 exstat = s; 3286 exstat = s;
2752 setval(lookup("?"), putn(s)); 3287 setval(lookup("?"), putn(s));
@@ -2761,8 +3296,8 @@ register int s;
2761static char *rexecve(c, v, envp) 3296static char *rexecve(c, v, envp)
2762char *c, **v, **envp; 3297char *c, **v, **envp;
2763{ 3298{
2764 register int i; 3299 REGISTER int i;
2765 register char *sp, *tp; 3300 REGISTER char *sp, *tp;
2766 int eacces = 0, asis = 0; 3301 int eacces = 0, asis = 0;
2767 3302
2768#ifdef CONFIG_FEATURE_SH_STANDALONE_SHELL 3303#ifdef CONFIG_FEATURE_SH_STANDALONE_SHELL
@@ -2778,6 +3313,8 @@ char *c, **v, **envp;
2778 } 3313 }
2779#endif 3314#endif
2780 3315
3316 DBGPRINTF(("REXECVE: c=0x%x, v=0x%x, envp=0x%x\n", c, v, envp));
3317
2781 sp = any('/', c) ? "" : path->value; 3318 sp = any('/', c) ? "" : path->value;
2782 asis = *sp == '\0'; 3319 asis = *sp == '\0';
2783 while (asis || *sp != '\0') { 3320 while (asis || *sp != '\0') {
@@ -2792,7 +3329,10 @@ char *c, **v, **envp;
2792 *tp++ = '/'; 3329 *tp++ = '/';
2793 for (i = 0; (*tp++ = c[i++]) != '\0';); 3330 for (i = 0; (*tp++ = c[i++]) != '\0';);
2794 3331
3332 DBGPRINTF3(("REXECVE: e.linep is %s\n", e.linep));
3333
2795 execve(e.linep, v, envp); 3334 execve(e.linep, v, envp);
3335
2796 switch (errno) { 3336 switch (errno) {
2797 case ENOEXEC: 3337 case ENOEXEC:
2798 *v = e.linep; 3338 *v = e.linep;
@@ -2834,12 +3374,16 @@ static int run(struct ioarg *argp, int (*f) (struct ioarg *))
2834 (void) &rv; 3374 (void) &rv;
2835#endif 3375#endif
2836 3376
3377 DBGPRINTF(("RUN: enter, areanum %d, outtree 0x%x, failpt 0x%x\n",
3378 areanum, outtree, failpt));
3379
2837 areanum++; 3380 areanum++;
2838 swdlist = wdlist; 3381 swdlist = wdlist;
2839 siolist = iolist; 3382 siolist = iolist;
2840 otree = outtree; 3383 otree = outtree;
2841 ofail = failpt; 3384 ofail = failpt;
2842 rv = -1; 3385 rv = -1;
3386
2843 if (newenv(setjmp(errpt = ev)) == 0) { 3387 if (newenv(setjmp(errpt = ev)) == 0) {
2844 wdlist = 0; 3388 wdlist = 0;
2845 iolist = 0; 3389 iolist = 0;
@@ -2849,12 +3393,16 @@ static int run(struct ioarg *argp, int (*f) (struct ioarg *))
2849 if (setjmp(failpt = rt) == 0 && yyparse() == 0) 3393 if (setjmp(failpt = rt) == 0 && yyparse() == 0)
2850 rv = execute(outtree, NOPIPE, NOPIPE, 0); 3394 rv = execute(outtree, NOPIPE, NOPIPE, 0);
2851 quitenv(); 3395 quitenv();
3396 } else {
3397 DBGPRINTF(("RUN: error from newenv()!\n"));
2852 } 3398 }
3399
2853 wdlist = swdlist; 3400 wdlist = swdlist;
2854 iolist = siolist; 3401 iolist = siolist;
2855 failpt = ofail; 3402 failpt = ofail;
2856 outtree = otree; 3403 outtree = otree;
2857 freearea(areanum--); 3404 freearea(areanum--);
3405
2858 return (rv); 3406 return (rv);
2859} 3407}
2860 3408
@@ -2912,9 +3460,9 @@ static int dolabel(struct op *t)
2912} 3460}
2913 3461
2914static int dochdir(t) 3462static int dochdir(t)
2915register struct op *t; 3463REGISTER struct op *t;
2916{ 3464{
2917 register char *cp, *er; 3465 REGISTER char *cp, *er;
2918 3466
2919 if ((cp = t->words[1]) == NULL && (cp = homedir->value) == NULL) 3467 if ((cp = t->words[1]) == NULL && (cp = homedir->value) == NULL)
2920 er = ": no home directory"; 3468 er = ": no home directory";
@@ -2928,9 +3476,9 @@ register struct op *t;
2928} 3476}
2929 3477
2930static int doshift(t) 3478static int doshift(t)
2931register struct op *t; 3479REGISTER struct op *t;
2932{ 3480{
2933 register int n; 3481 REGISTER int n;
2934 3482
2935 n = t->words[1] ? getn(t->words[1]) : 1; 3483 n = t->words[1] ? getn(t->words[1]) : 1;
2936 if (dolc < n) { 3484 if (dolc < n) {
@@ -2950,13 +3498,13 @@ register struct op *t;
2950static int dologin(t) 3498static int dologin(t)
2951struct op *t; 3499struct op *t;
2952{ 3500{
2953 register char *cp; 3501 REGISTER char *cp;
2954 3502
2955 if (interactive) { 3503 if (interactive) {
2956 signal(SIGINT, SIG_DFL); 3504 signal(SIGINT, SIG_DFL);
2957 signal(SIGQUIT, SIG_DFL); 3505 signal(SIGQUIT, SIG_DFL);
2958 } 3506 }
2959 cp = rexecve(t->words[0], t->words, makenv()); 3507 cp = rexecve(t->words[0], t->words, makenv(0));
2960 prs(t->words[0]); 3508 prs(t->words[0]);
2961 prs(": "); 3509 prs(": ");
2962 err(cp); 3510 err(cp);
@@ -2964,10 +3512,10 @@ struct op *t;
2964} 3512}
2965 3513
2966static int doumask(t) 3514static int doumask(t)
2967register struct op *t; 3515REGISTER struct op *t;
2968{ 3516{
2969 register int i, n; 3517 REGISTER int i, n;
2970 register char *cp; 3518 REGISTER char *cp;
2971 3519
2972 if ((cp = t->words[1]) == NULL) { 3520 if ((cp = t->words[1]) == NULL) {
2973 i = umask(0); 3521 i = umask(0);
@@ -2984,9 +3532,9 @@ register struct op *t;
2984} 3532}
2985 3533
2986static int doexec(t) 3534static int doexec(t)
2987register struct op *t; 3535REGISTER struct op *t;
2988{ 3536{
2989 register int i; 3537 REGISTER int i;
2990 jmp_buf ex; 3538 jmp_buf ex;
2991 xint *ofail; 3539 xint *ofail;
2992 3540
@@ -3006,36 +3554,61 @@ register struct op *t;
3006static int dodot(t) 3554static int dodot(t)
3007struct op *t; 3555struct op *t;
3008{ 3556{
3009 register int i; 3557 REGISTER int i;
3010 register char *sp, *tp; 3558 REGISTER char *sp, *tp;
3011 char *cp; 3559 char *cp;
3560 int maltmp;
3012 3561
3013 if ((cp = t->words[1]) == NULL) 3562 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)));
3563
3564 if ((cp = t->words[1]) == NULL) {
3565 DBGPRINTF(("DODOT: bad args, ret 0\n"));
3014 return (0); 3566 return (0);
3567 } else {
3568 DBGPRINTF(("DODOT: cp is %s\n", cp));
3569 }
3570
3015 sp = any('/', cp) ? ":" : path->value; 3571 sp = any('/', cp) ? ":" : path->value;
3572
3573 DBGPRINTF(("DODOT: sp is %s, e.linep is %s\n",
3574 ((sp == NULL) ? "NULL" : sp),
3575 ((e.linep == NULL) ? "NULL" : e.linep)));
3576
3016 while (*sp) { 3577 while (*sp) {
3017 tp = e.linep; 3578 tp = e.linep;
3018 while (*sp && (*tp = *sp++) != ':') 3579 while (*sp && (*tp = *sp++) != ':')
3019 tp++; 3580 tp++;
3020 if (tp != e.linep) 3581 if (tp != e.linep)
3021 *tp++ = '/'; 3582 *tp++ = '/';
3583
3022 for (i = 0; (*tp++ = cp[i++]) != '\0';); 3584 for (i = 0; (*tp++ = cp[i++]) != '\0';);
3585
3586 /* Original code */
3023 if ((i = open(e.linep, 0)) >= 0) { 3587 if ((i = open(e.linep, 0)) >= 0) {
3024 exstat = 0; 3588 exstat = 0;
3025 next(remap(i)); 3589 maltmp = remap(i);
3590 DBGPRINTF(("DODOT: remap=%d, exstat=%d, e.iofd %d, i %d, e.linep is %s\n", maltmp, exstat, e.iofd, i, e.linep));
3591
3592 next(maltmp); /* Basically a PUSHIO */
3593
3594 DBGPRINTF(("DODOT: returning exstat=%d\n", exstat));
3595
3026 return (exstat); 3596 return (exstat);
3027 } 3597 }
3028 } 3598
3599 } /* While */
3600
3029 prs(cp); 3601 prs(cp);
3030 err(": not found"); 3602 err(": not found");
3603
3031 return (-1); 3604 return (-1);
3032} 3605}
3033 3606
3034static int dowait(t) 3607static int dowait(t)
3035struct op *t; 3608struct op *t;
3036{ 3609{
3037 register int i; 3610 REGISTER int i;
3038 register char *cp; 3611 REGISTER char *cp;
3039 3612
3040 if ((cp = t->words[1]) != NULL) { 3613 if ((cp = t->words[1]) != NULL) {
3041 i = getn(cp); 3614 i = getn(cp);
@@ -3050,9 +3623,9 @@ struct op *t;
3050static int doread(t) 3623static int doread(t)
3051struct op *t; 3624struct op *t;
3052{ 3625{
3053 register char *cp, **wp; 3626 REGISTER char *cp, **wp;
3054 register int nb = 0; 3627 REGISTER int nb = 0;
3055 register int nl = 0; 3628 REGISTER int nl = 0;
3056 3629
3057 if (t->words[1] == NULL) { 3630 if (t->words[1] == NULL) {
3058 err("Usage: read name ..."); 3631 err("Usage: read name ...");
@@ -3072,16 +3645,16 @@ struct op *t;
3072} 3645}
3073 3646
3074static int doeval(t) 3647static int doeval(t)
3075register struct op *t; 3648REGISTER struct op *t;
3076{ 3649{
3077 return (RUN(awordlist, t->words + 1, wdchar)); 3650 return (RUN(awordlist, t->words + 1, wdchar));
3078} 3651}
3079 3652
3080static int dotrap(t) 3653static int dotrap(t)
3081register struct op *t; 3654REGISTER struct op *t;
3082{ 3655{
3083 register int n, i; 3656 REGISTER int n, i;
3084 register int resetsig; 3657 REGISTER int resetsig;
3085 3658
3086 if (t->words[1] == NULL) { 3659 if (t->words[1] == NULL) {
3087 for (i = 0; i <= _NSIG; i++) 3660 for (i = 0; i <= _NSIG; i++)
@@ -3120,7 +3693,7 @@ register struct op *t;
3120static int getsig(s) 3693static int getsig(s)
3121char *s; 3694char *s;
3122{ 3695{
3123 register int n; 3696 REGISTER int n;
3124 3697
3125 if ((n = getn(s)) < 0 || n > _NSIG) { 3698 if ((n = getn(s)) < 0 || n > _NSIG) {
3126 err("trap: bad signal number"); 3699 err("trap: bad signal number");
@@ -3129,7 +3702,7 @@ char *s;
3129 return (n); 3702 return (n);
3130} 3703}
3131 3704
3132static void setsig(register int n, sighandler_t f) 3705static void setsig(REGISTER int n, sighandler_t f)
3133{ 3706{
3134 if (n == 0) 3707 if (n == 0)
3135 return; 3708 return;
@@ -3142,8 +3715,8 @@ static void setsig(register int n, sighandler_t f)
3142static int getn(as) 3715static int getn(as)
3143char *as; 3716char *as;
3144{ 3717{
3145 register char *s; 3718 REGISTER char *s;
3146 register int n, m; 3719 REGISTER int n, m;
3147 3720
3148 s = as; 3721 s = as;
3149 m = 1; 3722 m = 1;
@@ -3173,11 +3746,11 @@ struct op *t;
3173} 3746}
3174 3747
3175static int brkcontin(cp, val) 3748static int brkcontin(cp, val)
3176register char *cp; 3749REGISTER char *cp;
3177int val; 3750int val;
3178{ 3751{
3179 register struct brkcon *bc; 3752 REGISTER struct brkcon *bc;
3180 register int nl; 3753 REGISTER int nl;
3181 3754
3182 nl = cp == NULL ? 1 : getn(cp); 3755 nl = cp == NULL ? 1 : getn(cp);
3183 if (nl <= 0) 3756 if (nl <= 0)
@@ -3199,11 +3772,14 @@ int val;
3199static int doexit(t) 3772static int doexit(t)
3200struct op *t; 3773struct op *t;
3201{ 3774{
3202 register char *cp; 3775 REGISTER char *cp;
3203 3776
3204 execflg = 0; 3777 execflg = 0;
3205 if ((cp = t->words[1]) != NULL) 3778 if ((cp = t->words[1]) != NULL)
3206 setstatus(getn(cp)); 3779 setstatus(getn(cp));
3780
3781 DBGPRINTF(("DOEXIT: calling leave(), t=0x%x\n", t));
3782
3207 leave(); 3783 leave();
3208 /* NOTREACHED */ 3784 /* NOTREACHED */
3209 return (0); 3785 return (0);
@@ -3225,6 +3801,9 @@ struct op *t;
3225 3801
3226static void rdexp(char **wp, void (*f) (struct var *), int key) 3802static void rdexp(char **wp, void (*f) (struct var *), int key)
3227{ 3803{
3804 DBGPRINTF6(("RDEXP: enter, wp=0x%x, func=0x%x, key=%d\n", wp, f, key));
3805 DBGPRINTF6(("RDEXP: *wp=%s\n", *wp));
3806
3228 if (*wp != NULL) { 3807 if (*wp != NULL) {
3229 for (; *wp != NULL; wp++) { 3808 for (; *wp != NULL; wp++) {
3230 if (isassign(*wp)) { 3809 if (isassign(*wp)) {
@@ -3244,18 +3823,18 @@ static void rdexp(char **wp, void (*f) (struct var *), int key)
3244} 3823}
3245 3824
3246static void badid(s) 3825static void badid(s)
3247register char *s; 3826REGISTER char *s;
3248{ 3827{
3249 prs(s); 3828 prs(s);
3250 err(": bad identifier"); 3829 err(": bad identifier");
3251} 3830}
3252 3831
3253static int doset(t) 3832static int doset(t)
3254register struct op *t; 3833REGISTER struct op *t;
3255{ 3834{
3256 register struct var *vp; 3835 REGISTER struct var *vp;
3257 register char *cp; 3836 REGISTER char *cp;
3258 register int n; 3837 REGISTER int n;
3259 3838
3260 if ((cp = t->words[1]) == NULL) { 3839 if ((cp = t->words[1]) == NULL) {
3261 for (vp = vlist; vp; vp = vp->next) 3840 for (vp = vlist; vp; vp = vp->next)
@@ -3295,7 +3874,7 @@ register struct op *t;
3295} 3874}
3296 3875
3297static void varput(s, out) 3876static void varput(s, out)
3298register char *s; 3877REGISTER char *s;
3299int out; 3878int out;
3300{ 3879{
3301 if (isalnum(*s) || *s == '_') { 3880 if (isalnum(*s) || *s == '_') {
@@ -3360,6 +3939,9 @@ static char **eval(char **ap, int f)
3360 (void) &wp; 3939 (void) &wp;
3361 (void) &ap; 3940 (void) &ap;
3362#endif 3941#endif
3942
3943 DBGPRINTF4(("EVAL: enter, f=%d\n", f));
3944
3363 wp = NULL; 3945 wp = NULL;
3364 wb = NULL; 3946 wb = NULL;
3365 wf = NULL; 3947 wf = NULL;
@@ -3381,6 +3963,7 @@ static char **eval(char **ap, int f)
3381 quitenv(); 3963 quitenv();
3382 } else 3964 } else
3383 gflg = 1; 3965 gflg = 1;
3966
3384 return (gflg ? (char **) NULL : wp); 3967 return (gflg ? (char **) NULL : wp);
3385} 3968}
3386 3969
@@ -3389,25 +3972,29 @@ static char **eval(char **ap, int f)
3389 * names in the dictionary. Keyword assignments 3972 * names in the dictionary. Keyword assignments
3390 * will already have been done. 3973 * will already have been done.
3391 */ 3974 */
3392static char **makenv() 3975static char **makenv(int all)
3393{ 3976{
3394 register struct wdblock *wb; 3977 REGISTER struct wdblock *wb;
3395 register struct var *vp; 3978 REGISTER struct var *vp;
3979
3980 DBGPRINTF5(("MAKENV: enter, all=%d\n", all));
3396 3981
3397 wb = NULL; 3982 wb = NULL;
3398 for (vp = vlist; vp; vp = vp->next) 3983 for (vp = vlist; vp; vp = vp->next)
3399 if (vp->status & EXPORT) 3984 if (all || vp->status & EXPORT)
3400 wb = addword(vp->name, wb); 3985 wb = addword(vp->name, wb);
3401 wb = addword((char *) 0, wb); 3986 wb = addword((char *) 0, wb);
3402 return (getwords(wb)); 3987 return (getwords(wb));
3403} 3988}
3404 3989
3405static char *evalstr(cp, f) 3990static char *evalstr(cp, f)
3406register char *cp; 3991REGISTER char *cp;
3407int f; 3992int f;
3408{ 3993{
3409 struct wdblock *wb; 3994 struct wdblock *wb;
3410 3995
3996 DBGPRINTF6(("EVALSTR: enter, cp=0x%x, f=%d\n", cp, f));
3997
3411 wb = NULL; 3998 wb = NULL;
3412 if (expand(cp, &wb, f)) { 3999 if (expand(cp, &wb, f)) {
3413 if (wb == NULL || wb->w_nword == 0 4000 if (wb == NULL || wb->w_nword == 0
@@ -3419,7 +4006,7 @@ int f;
3419 return (cp); 4006 return (cp);
3420} 4007}
3421 4008
3422static int expand(char *cp, register struct wdblock **wbp, int f) 4009static int expand(char *cp, REGISTER struct wdblock **wbp, int f)
3423{ 4010{
3424 jmp_buf ev; 4011 jmp_buf ev;
3425 4012
@@ -3427,9 +4014,14 @@ static int expand(char *cp, register struct wdblock **wbp, int f)
3427 /* Avoid longjmp clobbering */ 4014 /* Avoid longjmp clobbering */
3428 (void) &cp; 4015 (void) &cp;
3429#endif 4016#endif
4017
4018 DBGPRINTF3(("EXPAND: enter, f=%d\n", f));
4019
3430 gflg = 0; 4020 gflg = 0;
4021
3431 if (cp == NULL) 4022 if (cp == NULL)
3432 return (0); 4023 return (0);
4024
3433 if (!anys("$`'\"", cp) && 4025 if (!anys("$`'\"", cp) &&
3434 !anys(ifs->value, cp) && ((f & DOGLOB) == 0 || !anys("[*?", cp))) { 4026 !anys(ifs->value, cp) && ((f & DOGLOB) == 0 || !anys("[*?", cp))) {
3435 cp = strsave(cp, areanum); 4027 cp = strsave(cp, areanum);
@@ -3463,10 +4055,12 @@ static int expand(char *cp, register struct wdblock **wbp, int f)
3463static char *blank(f) 4055static char *blank(f)
3464int f; 4056int f;
3465{ 4057{
3466 register int c, c1; 4058 REGISTER int c, c1;
3467 register char *sp; 4059 REGISTER char *sp;
3468 int scanequals, foundequals; 4060 int scanequals, foundequals;
3469 4061
4062 DBGPRINTF3(("BLANK: enter, f=%d\n", f));
4063
3470 sp = e.linep; 4064 sp = e.linep;
3471 scanequals = f & DOKEY; 4065 scanequals = f & DOKEY;
3472 foundequals = 0; 4066 foundequals = 0;
@@ -3529,10 +4123,12 @@ int f;
3529 * Get characters, substituting for ` and $ 4123 * Get characters, substituting for ` and $
3530 */ 4124 */
3531static int subgetc(ec, quoted) 4125static int subgetc(ec, quoted)
3532register char ec; 4126REGISTER char ec;
3533int quoted; 4127int quoted;
3534{ 4128{
3535 register char c; 4129 REGISTER char c;
4130
4131 DBGPRINTF3(("SUBGETC: enter, quoted=%d\n", quoted));
3536 4132
3537 again: 4133 again:
3538 c = my_getc(ec); 4134 c = my_getc(ec);
@@ -3560,9 +4156,11 @@ int quoted;
3560 int otask; 4156 int otask;
3561 struct io *oiop; 4157 struct io *oiop;
3562 char *dolp; 4158 char *dolp;
3563 register char *s, c, *cp = NULL; 4159 REGISTER char *s, c, *cp = NULL;
3564 struct var *vp; 4160 struct var *vp;
3565 4161
4162 DBGPRINTF3(("DOLLAR: enter, quoted=%d\n", quoted));
4163
3566 c = readc(); 4164 c = readc();
3567 s = e.linep; 4165 s = e.linep;
3568 if (c != '{') { 4166 if (c != '{') {
@@ -3577,6 +4175,7 @@ int quoted;
3577 } else { 4175 } else {
3578 oiop = e.iop; 4176 oiop = e.iop;
3579 otask = e.iop->task; 4177 otask = e.iop->task;
4178
3580 e.iop->task = XOTHER; 4179 e.iop->task = XOTHER;
3581 while ((c = subgetc('"', 0)) != 0 && c != '}' && c != '\n') 4180 while ((c = subgetc('"', 0)) != 0 && c != '}' && c != '\n')
3582 if (e.linep < elinep) 4181 if (e.linep < elinep)
@@ -3660,7 +4259,7 @@ static int grave(quoted)
3660int quoted; 4259int quoted;
3661{ 4260{
3662 char *cp; 4261 char *cp;
3663 register int i; 4262 REGISTER int i;
3664 int j; 4263 int j;
3665 int pf[2]; 4264 int pf[2];
3666 static char child_cmd[LINELIM]; 4265 static char child_cmd[LINELIM];
@@ -3769,7 +4368,11 @@ int quoted;
3769 4368
3770 if (openpipe(pf) < 0) 4369 if (openpipe(pf) < 0)
3771 return (0); 4370 return (0);
4371
3772 while ((i = vfork()) == -1 && errno == EAGAIN); 4372 while ((i = vfork()) == -1 && errno == EAGAIN);
4373
4374 DBGPRINTF3(("GRAVE: i is %d\n", io));
4375
3773 if (i < 0) { 4376 if (i < 0) {
3774 closepipe(pf); 4377 closepipe(pf);
3775 err((char *) bb_msg_memory_exhausted); 4378 err((char *) bb_msg_memory_exhausted);
@@ -3798,15 +4401,18 @@ int quoted;
3798 argument_list[2] = child_cmd; 4401 argument_list[2] = child_cmd;
3799 argument_list[3] = 0; 4402 argument_list[3] = 0;
3800 4403
3801 prs(rexecve(argument_list[0], argument_list, makenv())); 4404 cp = rexecve(argument_list[0], argument_list, makenv(1));
4405 prs(argument_list[0]);
4406 prs(": ");
4407 err(cp);
3802 _exit(1); 4408 _exit(1);
3803} 4409}
3804 4410
3805 4411
3806static char *unquote(as) 4412static char *unquote(as)
3807register char *as; 4413REGISTER char *as;
3808{ 4414{
3809 register char *s; 4415 REGISTER char *s;
3810 4416
3811 if ((s = as) != NULL) 4417 if ((s = as) != NULL)
3812 while (*s) 4418 while (*s)
@@ -3831,8 +4437,8 @@ static struct wdblock *glob(cp, wb)
3831char *cp; 4437char *cp;
3832struct wdblock *wb; 4438struct wdblock *wb;
3833{ 4439{
3834 register int i; 4440 REGISTER int i;
3835 register char *pp; 4441 REGISTER char *pp;
3836 4442
3837 if (cp == 0) 4443 if (cp == 0)
3838 return (wb); 4444 return (wb);
@@ -3875,9 +4481,9 @@ struct wdblock *wb;
3875 4481
3876static void globname(we, pp) 4482static void globname(we, pp)
3877char *we; 4483char *we;
3878register char *pp; 4484REGISTER char *pp;
3879{ 4485{
3880 register char *np, *cp; 4486 REGISTER char *np, *cp;
3881 char *name, *gp, *dp; 4487 char *name, *gp, *dp;
3882 int k; 4488 int k;
3883 DIR *dirp; 4489 DIR *dirp;
@@ -3938,11 +4544,11 @@ register char *pp;
3938 */ 4544 */
3939static char *generate(start1, end1, middle, end) 4545static char *generate(start1, end1, middle, end)
3940char *start1; 4546char *start1;
3941register char *end1; 4547REGISTER char *end1;
3942char *middle, *end; 4548char *middle, *end;
3943{ 4549{
3944 char *p; 4550 char *p;
3945 register char *op, *xp; 4551 REGISTER char *op, *xp;
3946 4552
3947 p = op = 4553 p = op =
3948 space((int) (end1 - start1) + strlen(middle) + strlen(end) + 2); 4554 space((int) (end1 - start1) + strlen(middle) + strlen(end) + 2);
@@ -3955,10 +4561,10 @@ char *middle, *end;
3955} 4561}
3956 4562
3957static int anyspcl(wb) 4563static int anyspcl(wb)
3958register struct wdblock *wb; 4564REGISTER struct wdblock *wb;
3959{ 4565{
3960 register int i; 4566 REGISTER int i;
3961 register char **wd; 4567 REGISTER char **wd;
3962 4568
3963 wd = wb->w_words; 4569 wd = wb->w_words;
3964 for (i = 0; i < wb->w_nword; i++) 4570 for (i = 0; i < wb->w_nword; i++)
@@ -3976,9 +4582,9 @@ char *p1, *p2;
3976/* -------- word.c -------- */ 4582/* -------- word.c -------- */
3977 4583
3978static struct wdblock *newword(nw) 4584static struct wdblock *newword(nw)
3979register int nw; 4585REGISTER int nw;
3980{ 4586{
3981 register struct wdblock *wb; 4587 REGISTER struct wdblock *wb;
3982 4588
3983 wb = (struct wdblock *) space(sizeof(*wb) + nw * sizeof(char *)); 4589 wb = (struct wdblock *) space(sizeof(*wb) + nw * sizeof(char *));
3984 wb->w_bsize = nw; 4590 wb->w_bsize = nw;
@@ -3988,10 +4594,10 @@ register int nw;
3988 4594
3989static struct wdblock *addword(wd, wb) 4595static struct wdblock *addword(wd, wb)
3990char *wd; 4596char *wd;
3991register struct wdblock *wb; 4597REGISTER struct wdblock *wb;
3992{ 4598{
3993 register struct wdblock *wb2; 4599 REGISTER struct wdblock *wb2;
3994 register int nw; 4600 REGISTER int nw;
3995 4601
3996 if (wb == NULL) 4602 if (wb == NULL)
3997 wb = newword(NSTART); 4603 wb = newword(NSTART);
@@ -4009,10 +4615,10 @@ register struct wdblock *wb;
4009 4615
4010static 4616static
4011char **getwords(wb) 4617char **getwords(wb)
4012register struct wdblock *wb; 4618REGISTER struct wdblock *wb;
4013{ 4619{
4014 register char **wd; 4620 REGISTER char **wd;
4015 register int nb; 4621 REGISTER int nb;
4016 4622
4017 if (wb == NULL) 4623 if (wb == NULL)
4018 return ((char **) NULL); 4624 return ((char **) NULL);
@@ -4043,7 +4649,7 @@ int (*a3) (char *, char *);
4043static void glob1(base, lim) 4649static void glob1(base, lim)
4044char *base, *lim; 4650char *base, *lim;
4045{ 4651{
4046 register char *i, *j; 4652 REGISTER char *i, *j;
4047 int v2; 4653 int v2;
4048 char *lptr, *hptr; 4654 char *lptr, *hptr;
4049 int c; 4655 int c;
@@ -4113,7 +4719,7 @@ char *base, *lim;
4113static void glob2(i, j) 4719static void glob2(i, j)
4114char *i, *j; 4720char *i, *j;
4115{ 4721{
4116 register char *index1, *index2, c; 4722 REGISTER char *index1, *index2, c;
4117 int m; 4723 int m;
4118 4724
4119 m = globv; 4725 m = globv;
@@ -4129,7 +4735,7 @@ char *i, *j;
4129static void glob3(i, j, k) 4735static void glob3(i, j, k)
4130char *i, *j, *k; 4736char *i, *j, *k;
4131{ 4737{
4132 register char *index1, *index2, *index3; 4738 REGISTER char *index1, *index2, *index3;
4133 int c; 4739 int c;
4134 int m; 4740 int m;
4135 4741
@@ -4153,7 +4759,7 @@ char *i, *j, *k;
4153 4759
4154static int my_getc(int ec) 4760static int my_getc(int ec)
4155{ 4761{
4156 register int c; 4762 REGISTER int c;
4157 4763
4158 if (e.linep > elinep) { 4764 if (e.linep > elinep) {
4159 while ((c = readc()) != '\n' && c); 4765 while ((c = readc()) != '\n' && c);
@@ -4187,9 +4793,12 @@ static int eofc()
4187 4793
4188static int readc() 4794static int readc()
4189{ 4795{
4190 register int c; 4796 REGISTER int c;
4191 4797
4192 for (; e.iop >= e.iobase; e.iop--) 4798 RCPRINTF(("READC: e.iop 0x%x, e.iobase 0x%x\n", e.iop, e.iobase));
4799
4800 for (; e.iop >= e.iobase; e.iop--) {
4801 RCPRINTF(("READC: e.iop 0x%x, peekc 0x%x\n", e.iop, e.iop->peekc));
4193 if ((c = e.iop->peekc) != '\0') { 4802 if ((c = e.iop->peekc) != '\0') {
4194 e.iop->peekc = 0; 4803 e.iop->peekc = 0;
4195 return (c); 4804 return (c);
@@ -4211,8 +4820,9 @@ static int readc()
4211 } 4820 }
4212 } 4821 }
4213 if (e.iop->task == XIO) { 4822 if (e.iop->task == XIO) {
4214 if (multiline) 4823 if (multiline) {
4215 return e.iop->prev = 0; 4824 return e.iop->prev = 0;
4825 }
4216 if (interactive && e.iop == iostack + 1) { 4826 if (interactive && e.iop == iostack + 1) {
4217#ifdef CONFIG_FEATURE_COMMAND_EDITING 4827#ifdef CONFIG_FEATURE_COMMAND_EDITING
4218 current_prompt = prompt->value; 4828 current_prompt = prompt->value;
@@ -4222,9 +4832,17 @@ static int readc()
4222 } 4832 }
4223 } 4833 }
4224 } 4834 }
4225 if (e.iop >= iostack) 4835
4836 } /* FOR */
4837
4838 if (e.iop >= iostack) {
4839 RCPRINTF(("READC: return 0, e.iop 0x%x\n", e.iop));
4226 return (0); 4840 return (0);
4841 }
4842
4843 DBGPRINTF(("READC: leave()...\n"));
4227 leave(); 4844 leave();
4845
4228 /* NOTREACHED */ 4846 /* NOTREACHED */
4229 return (0); 4847 return (0);
4230} 4848}
@@ -4236,35 +4854,61 @@ char c;
4236 write(2, &c, sizeof c); 4854 write(2, &c, sizeof c);
4237} 4855}
4238 4856
4857
4239static void pushio(struct ioarg *argp, int (*fn) (struct ioarg *)) 4858static void pushio(struct ioarg *argp, int (*fn) (struct ioarg *))
4240{ 4859{
4860 DBGPRINTF(("PUSHIO: argp 0x%x, argp->afid 0x%x, e.iop 0x%x\n", argp,
4861 argp->afid, e.iop));
4862
4863 /* Set env ptr for io source to next array spot and check for array overflow */
4241 if (++e.iop >= &iostack[NPUSH]) { 4864 if (++e.iop >= &iostack[NPUSH]) {
4242 e.iop--; 4865 e.iop--;
4243 err("Shell input nested too deeply"); 4866 err("Shell input nested too deeply");
4244 gflg++; 4867 gflg++;
4245 return; 4868 return;
4246 } 4869 }
4247 e.iop->iofn = (int (*)(struct ioarg *, struct io *)) fn; 4870
4871 /* We did not overflow the NPUSH array spots so setup data structs */
4872
4873 e.iop->iofn = (int (*)(struct ioarg *, struct io *)) fn; /* Store data source func ptr */
4248 4874
4249 if (argp->afid != AFID_NOBUF) 4875 if (argp->afid != AFID_NOBUF)
4250 e.iop->argp = argp; 4876 e.iop->argp = argp;
4251 else { 4877 else {
4252 e.iop->argp = ioargstack + (e.iop - iostack); 4878
4253 *e.iop->argp = *argp; 4879 e.iop->argp = ioargstack + (e.iop - iostack); /* MAL - index into stack */
4254 e.iop->argp->afbuf = e.iop == &iostack[0] ? &mainbuf : &sharedbuf; 4880 *e.iop->argp = *argp; /* copy data from temp area into stack spot */
4255 if (isatty(e.iop->argp->afile) == 0 && 4881
4256 (e.iop == &iostack[0] || 4882 /* MAL - mainbuf is for 1st data source (command line?) and all nested use a single shared buffer? */
4257 lseek(e.iop->argp->afile, 0L, 1) != -1)) { 4883
4258 if (++bufid == AFID_NOBUF) 4884 if (e.iop == &iostack[0])
4259 bufid = AFID_ID; 4885 e.iop->argp->afbuf = &mainbuf;
4260 e.iop->argp->afid = bufid; 4886 else
4887 e.iop->argp->afbuf = &sharedbuf;
4888
4889 /* MAL - if not a termimal AND (commandline OR readable file) then give it a buffer id? */
4890 /* This line appears to be active when running scripts from command line */
4891 if ((isatty(e.iop->argp->afile) == 0)
4892 && (e.iop == &iostack[0]
4893 || lseek(e.iop->argp->afile, 0L, 1) != -1)) {
4894 if (++bufid == AFID_NOBUF) /* counter rollover check, AFID_NOBUF = 11111111 */
4895 bufid = AFID_ID; /* AFID_ID = 0 */
4896
4897 e.iop->argp->afid = bufid; /* assign buffer id */
4261 } 4898 }
4899
4900 DBGPRINTF(("PUSHIO: iostack 0x%x, e.iop 0x%x, afbuf 0x%x\n",
4901 iostack, e.iop, e.iop->argp->afbuf));
4902 DBGPRINTF(("PUSHIO: mbuf 0x%x, sbuf 0x%x, bid %d, e.iop 0x%x\n",
4903 &mainbuf, &sharedbuf, bufid, e.iop));
4904
4262 } 4905 }
4263 4906
4264 e.iop->prev = ~'\n'; 4907 e.iop->prev = ~'\n';
4265 e.iop->peekc = 0; 4908 e.iop->peekc = 0;
4266 e.iop->xchar = 0; 4909 e.iop->xchar = 0;
4267 e.iop->nlcount = 0; 4910 e.iop->nlcount = 0;
4911
4268 if (fn == filechar || fn == linechar) 4912 if (fn == filechar || fn == linechar)
4269 e.iop->task = XIO; 4913 e.iop->task = XIO;
4270 else if (fn == (int (*)(struct ioarg *)) gravechar 4914 else if (fn == (int (*)(struct ioarg *)) gravechar
@@ -4272,12 +4916,14 @@ static void pushio(struct ioarg *argp, int (*fn) (struct ioarg *))
4272 e.iop->task = XGRAVE; 4916 e.iop->task = XGRAVE;
4273 else 4917 else
4274 e.iop->task = XOTHER; 4918 e.iop->task = XOTHER;
4919
4920 return;
4275} 4921}
4276 4922
4277static struct io *setbase(ip) 4923static struct io *setbase(ip)
4278struct io *ip; 4924struct io *ip;
4279{ 4925{
4280 register struct io *xp; 4926 REGISTER struct io *xp;
4281 4927
4282 xp = e.iobase; 4928 xp = e.iobase;
4283 e.iobase = ip; 4929 e.iobase = ip;
@@ -4292,9 +4938,9 @@ struct io *ip;
4292 * Produce the characters of a string, then a newline, then EOF. 4938 * Produce the characters of a string, then a newline, then EOF.
4293 */ 4939 */
4294static int nlchar(ap) 4940static int nlchar(ap)
4295register struct ioarg *ap; 4941REGISTER struct ioarg *ap;
4296{ 4942{
4297 register int c; 4943 REGISTER int c;
4298 4944
4299 if (ap->aword == NULL) 4945 if (ap->aword == NULL)
4300 return (0); 4946 return (0);
@@ -4310,10 +4956,10 @@ register struct ioarg *ap;
4310 * in them, with a space after each word. 4956 * in them, with a space after each word.
4311 */ 4957 */
4312static int wdchar(ap) 4958static int wdchar(ap)
4313register struct ioarg *ap; 4959REGISTER struct ioarg *ap;
4314{ 4960{
4315 register char c; 4961 REGISTER char c;
4316 register char **wl; 4962 REGISTER char **wl;
4317 4963
4318 if ((wl = ap->awordlist) == NULL) 4964 if ((wl = ap->awordlist) == NULL)
4319 return (0); 4965 return (0);
@@ -4332,9 +4978,9 @@ register struct ioarg *ap;
4332 * producing a space between them. 4978 * producing a space between them.
4333 */ 4979 */
4334static int dolchar(ap) 4980static int dolchar(ap)
4335register struct ioarg *ap; 4981REGISTER struct ioarg *ap;
4336{ 4982{
4337 register char *wp; 4983 REGISTER char *wp;
4338 4984
4339 if ((wp = *ap->awordlist++) != NULL) { 4985 if ((wp = *ap->awordlist++) != NULL) {
4340 PUSHIO(aword, wp, *ap->awordlist == NULL ? strchar : xxchar); 4986 PUSHIO(aword, wp, *ap->awordlist == NULL ? strchar : xxchar);
@@ -4344,9 +4990,9 @@ register struct ioarg *ap;
4344} 4990}
4345 4991
4346static int xxchar(ap) 4992static int xxchar(ap)
4347register struct ioarg *ap; 4993REGISTER struct ioarg *ap;
4348{ 4994{
4349 register int c; 4995 REGISTER int c;
4350 4996
4351 if (ap->aword == NULL) 4997 if (ap->aword == NULL)
4352 return (0); 4998 return (0);
@@ -4361,9 +5007,9 @@ register struct ioarg *ap;
4361 * Produce the characters from a single word (string). 5007 * Produce the characters from a single word (string).
4362 */ 5008 */
4363static int strchar(ap) 5009static int strchar(ap)
4364register struct ioarg *ap; 5010REGISTER struct ioarg *ap;
4365{ 5011{
4366 register int c; 5012 REGISTER int c;
4367 5013
4368 if (ap->aword == NULL || (c = *ap->aword++) == 0) 5014 if (ap->aword == NULL || (c = *ap->aword++) == 0)
4369 return (0); 5015 return (0);
@@ -4374,9 +5020,9 @@ register struct ioarg *ap;
4374 * Produce quoted characters from a single word (string). 5020 * Produce quoted characters from a single word (string).
4375 */ 5021 */
4376static int qstrchar(ap) 5022static int qstrchar(ap)
4377register struct ioarg *ap; 5023REGISTER struct ioarg *ap;
4378{ 5024{
4379 register int c; 5025 REGISTER int c;
4380 5026
4381 if (ap->aword == NULL || (c = *ap->aword++) == 0) 5027 if (ap->aword == NULL || (c = *ap->aword++) == 0)
4382 return (0); 5028 return (0);
@@ -4387,24 +5033,29 @@ register struct ioarg *ap;
4387 * Return the characters from a file. 5033 * Return the characters from a file.
4388 */ 5034 */
4389static int filechar(ap) 5035static int filechar(ap)
4390register struct ioarg *ap; 5036REGISTER struct ioarg *ap;
4391{ 5037{
4392 register int i; 5038 REGISTER int i;
4393 char c; 5039 char c;
4394 struct iobuf *bp = ap->afbuf; 5040 struct iobuf *bp = ap->afbuf;
4395 5041
4396 if (ap->afid != AFID_NOBUF) { 5042 if (ap->afid != AFID_NOBUF) {
4397 if ((i = ap->afid != bp->id) || bp->bufp == bp->ebufp) { 5043 if ((i = ap->afid != bp->id) || bp->bufp == bp->ebufp) {
5044
4398 if (i) 5045 if (i)
4399 lseek(ap->afile, ap->afpos, 0); 5046 lseek(ap->afile, ap->afpos, 0);
5047
4400 i = safe_read(ap->afile, bp->buf, sizeof(bp->buf)); 5048 i = safe_read(ap->afile, bp->buf, sizeof(bp->buf));
5049
4401 if (i <= 0) { 5050 if (i <= 0) {
4402 closef(ap->afile); 5051 closef(ap->afile);
4403 return 0; 5052 return 0;
4404 } 5053 }
5054
4405 bp->id = ap->afid; 5055 bp->id = ap->afid;
4406 bp->ebufp = (bp->bufp = bp->buf) + i; 5056 bp->ebufp = (bp->bufp = bp->buf) + i;
4407 } 5057 }
5058
4408 ap->afpos++; 5059 ap->afpos++;
4409 return *bp->bufp++ & 0177; 5060 return *bp->bufp++ & 0177;
4410 } 5061 }
@@ -4423,9 +5074,10 @@ register struct ioarg *ap;
4423 return (c); 5074 return (c);
4424 } else 5075 } else
4425#endif 5076#endif
5077
4426 { 5078 {
4427 i = safe_read(ap->afile, &c, sizeof(c)); 5079 i = safe_read(ap->afile, &c, sizeof(c));
4428 return (i == sizeof(c) ? c & 0177 : (closef(ap->afile), 0)); 5080 return (i == sizeof(c) ? (c & 0x7f) : (closef(ap->afile), 0));
4429 } 5081 }
4430} 5082}
4431 5083
@@ -4433,7 +5085,7 @@ register struct ioarg *ap;
4433 * Return the characters from a here temp file. 5085 * Return the characters from a here temp file.
4434 */ 5086 */
4435static int herechar(ap) 5087static int herechar(ap)
4436register struct ioarg *ap; 5088REGISTER struct ioarg *ap;
4437{ 5089{
4438 char c; 5090 char c;
4439 5091
@@ -4454,7 +5106,7 @@ static int gravechar(ap, iop)
4454struct ioarg *ap; 5106struct ioarg *ap;
4455struct io *iop; 5107struct io *iop;
4456{ 5108{
4457 register int c; 5109 REGISTER int c;
4458 5110
4459 if ((c = qgravechar(ap, iop) & ~QUOTE) == '\n') 5111 if ((c = qgravechar(ap, iop) & ~QUOTE) == '\n')
4460 c = ' '; 5112 c = ' ';
@@ -4462,10 +5114,12 @@ struct io *iop;
4462} 5114}
4463 5115
4464static int qgravechar(ap, iop) 5116static int qgravechar(ap, iop)
4465register struct ioarg *ap; 5117REGISTER struct ioarg *ap;
4466struct io *iop; 5118struct io *iop;
4467{ 5119{
4468 register int c; 5120 REGISTER int c;
5121
5122 DBGPRINTF3(("QGRAVECHAR: enter, ap=0x%x, iop=0x%x\n", ap, iop));
4469 5123
4470 if (iop->xchar) { 5124 if (iop->xchar) {
4471 if (iop->nlcount) { 5125 if (iop->nlcount) {
@@ -4491,9 +5145,9 @@ struct io *iop;
4491 * Return a single command (usually the first line) from a file. 5145 * Return a single command (usually the first line) from a file.
4492 */ 5146 */
4493static int linechar(ap) 5147static int linechar(ap)
4494register struct ioarg *ap; 5148REGISTER struct ioarg *ap;
4495{ 5149{
4496 register int c; 5150 REGISTER int c;
4497 5151
4498 if ((c = filechar(ap)) == '\n') { 5152 if ((c = filechar(ap)) == '\n') {
4499 if (!multiline) { 5153 if (!multiline) {
@@ -4505,7 +5159,7 @@ register struct ioarg *ap;
4505} 5159}
4506 5160
4507static void prs(s) 5161static void prs(s)
4508register char *s; 5162REGISTER char *s;
4509{ 5163{
4510 if (*s) 5164 if (*s)
4511 write(2, s, strlen(s)); 5165 write(2, s, strlen(s));
@@ -4518,7 +5172,7 @@ unsigned u;
4518} 5172}
4519 5173
4520static void closef(i) 5174static void closef(i)
4521register int i; 5175REGISTER int i;
4522{ 5176{
4523 if (i > 2) 5177 if (i > 2)
4524 close(i); 5178 close(i);
@@ -4526,41 +5180,51 @@ register int i;
4526 5180
4527static void closeall() 5181static void closeall()
4528{ 5182{
4529 register int u; 5183 REGISTER int u;
4530 5184
4531 for (u = NUFILE; u < NOFILE;) 5185 for (u = NUFILE; u < NOFILE;)
4532 close(u++); 5186 close(u++);
4533} 5187}
4534 5188
5189
4535/* 5190/*
4536 * remap fd into Shell's fd space 5191 * remap fd into Shell's fd space
4537 */ 5192 */
4538static int remap(fd) 5193static int remap(fd)
4539register int fd; 5194REGISTER int fd;
4540{ 5195{
4541 register int i; 5196 REGISTER int i;
4542 int map[NOFILE]; 5197 int map[NOFILE];
5198 int newfd;
5199
5200
5201 DBGPRINTF(("REMAP: fd=%d, e.iofd=%d\n", fd, e.iofd));
4543 5202
4544 if (fd < e.iofd) { 5203 if (fd < e.iofd) {
4545 for (i = 0; i < NOFILE; i++) 5204 for (i = 0; i < NOFILE; i++)
4546 map[i] = 0; 5205 map[i] = 0;
5206
4547 do { 5207 do {
4548 map[fd] = 1; 5208 map[fd] = 1;
4549 fd = dup(fd); 5209 newfd = dup(fd);
5210 fd = newfd;
4550 } while (fd >= 0 && fd < e.iofd); 5211 } while (fd >= 0 && fd < e.iofd);
5212
4551 for (i = 0; i < NOFILE; i++) 5213 for (i = 0; i < NOFILE; i++)
4552 if (map[i]) 5214 if (map[i])
4553 close(i); 5215 close(i);
5216
4554 if (fd < 0) 5217 if (fd < 0)
4555 err("too many files open in shell"); 5218 err("too many files open in shell");
4556 } 5219 }
5220
4557 return (fd); 5221 return (fd);
4558} 5222}
4559 5223
4560static int openpipe(pv) 5224static int openpipe(pv)
4561register int *pv; 5225REGISTER int *pv;
4562{ 5226{
4563 register int i; 5227 REGISTER int i;
4564 5228
4565 if ((i = pipe(pv)) < 0) 5229 if ((i = pipe(pv)) < 0)
4566 err("can't create pipe - try again"); 5230 err("can't create pipe - try again");
@@ -4568,7 +5232,7 @@ register int *pv;
4568} 5232}
4569 5233
4570static void closepipe(pv) 5234static void closepipe(pv)
4571register int *pv; 5235REGISTER int *pv;
4572{ 5236{
4573 if (pv != NULL) { 5237 if (pv != NULL) {
4574 close(*pv++); 5238 close(*pv++);
@@ -4583,17 +5247,21 @@ register int *pv;
4583 */ 5247 */
4584 5248
4585static void markhere(s, iop) 5249static void markhere(s, iop)
4586register char *s; 5250REGISTER char *s;
4587struct ioword *iop; 5251struct ioword *iop;
4588{ 5252{
4589 register struct here *h, *lh; 5253 REGISTER struct here *h, *lh;
5254
5255 DBGPRINTF7(("MARKHERE: enter, s=0x%x\n", s));
4590 5256
4591 h = (struct here *) space(sizeof(struct here)); 5257 h = (struct here *) space(sizeof(struct here));
4592 if (h == 0) 5258 if (h == 0)
4593 return; 5259 return;
5260
4594 h->h_tag = evalstr(s, DOSUB); 5261 h->h_tag = evalstr(s, DOSUB);
4595 if (h->h_tag == 0) 5262 if (h->h_tag == 0)
4596 return; 5263 return;
5264
4597 h->h_iop = iop; 5265 h->h_iop = iop;
4598 iop->io_name = 0; 5266 iop->io_name = 0;
4599 h->h_next = NULL; 5267 h->h_next = NULL;
@@ -4616,7 +5284,9 @@ struct ioword *iop;
4616 5284
4617static void gethere() 5285static void gethere()
4618{ 5286{
4619 register struct here *h, *hp; 5287 REGISTER struct here *h, *hp;
5288
5289 DBGPRINTF7(("GETHERE: enter...\n"));
4620 5290
4621 /* Scan here files first leaving inhere list in place */ 5291 /* Scan here files first leaving inhere list in place */
4622 for (hp = h = inhere; h != NULL; hp = h, h = h->h_next) 5292 for (hp = h = inhere; h != NULL; hp = h, h = h->h_next)
@@ -4632,19 +5302,22 @@ static void gethere()
4632 5302
4633static void readhere(name, s, ec) 5303static void readhere(name, s, ec)
4634char **name; 5304char **name;
4635register char *s; 5305REGISTER char *s;
4636int ec; 5306int ec;
4637{ 5307{
4638 int tf; 5308 int tf;
4639 char tname[30] = ".msh_XXXXXX"; 5309 char tname[30] = ".msh_XXXXXX";
4640 register int c; 5310 REGISTER int c;
4641 jmp_buf ev; 5311 jmp_buf ev;
4642 char myline[LINELIM + 1]; 5312 char myline[LINELIM + 1];
4643 char *thenext; 5313 char *thenext;
4644 5314
5315 DBGPRINTF7(("READHERE: enter, name=0x%x, s=0x%x\n", name, s));
5316
4645 tf = mkstemp(tname); 5317 tf = mkstemp(tname);
4646 if (tf < 0) 5318 if (tf < 0)
4647 return; 5319 return;
5320
4648 *name = strsave(tname, areanum); 5321 *name = strsave(tname, areanum);
4649 if (newenv(setjmp(errpt = ev)) != 0) 5322 if (newenv(setjmp(errpt = ev)) != 0)
4650 unlink(tname); 5323 unlink(tname);
@@ -4693,18 +5366,22 @@ static int herein(hname, xdoll)
4693char *hname; 5366char *hname;
4694int xdoll; 5367int xdoll;
4695{ 5368{
4696 register int hf; 5369 REGISTER int hf;
4697 int tf; 5370 int tf;
4698 5371
4699#if __GNUC__ 5372#if __GNUC__
4700 /* Avoid longjmp clobbering */ 5373 /* Avoid longjmp clobbering */
4701 (void) &tf; 5374 (void) &tf;
4702#endif 5375#endif
4703 if (hname == 0) 5376 if (hname == NULL)
4704 return (-1); 5377 return (-1);
5378
5379 DBGPRINTF7(("HEREIN: hname is %s, xdoll=%d\n", hname, xdoll));
5380
4705 hf = open(hname, 0); 5381 hf = open(hname, 0);
4706 if (hf < 0) 5382 if (hf < 0)
4707 return (-1); 5383 return (-1);
5384
4708 if (xdoll) { 5385 if (xdoll) {
4709 char c; 5386 char c;
4710 char tname[30] = ".msh_XXXXXX"; 5387 char tname[30] = ".msh_XXXXXX";
@@ -4733,7 +5410,9 @@ int xdoll;
4733 5410
4734static void scraphere() 5411static void scraphere()
4735{ 5412{
4736 register struct here *h; 5413 REGISTER struct here *h;
5414
5415 DBGPRINTF7(("SCRAPHERE: enter...\n"));
4737 5416
4738 for (h = inhere; h != NULL; h = h->h_next) { 5417 for (h = inhere; h != NULL; h = h->h_next) {
4739 if (h->h_iop && h->h_iop->io_name) 5418 if (h->h_iop && h->h_iop->io_name)
@@ -4746,7 +5425,9 @@ static void scraphere()
4746static void freehere(area) 5425static void freehere(area)
4747int area; 5426int area;
4748{ 5427{
4749 register struct here *h, *hl; 5428 REGISTER struct here *h, *hl;
5429
5430 DBGPRINTF6(("FREEHERE: enter, area=%d\n", area));
4750 5431
4751 hl = NULL; 5432 hl = NULL;
4752 for (h = acthere; h != NULL; h = h->h_next) 5433 for (h = acthere; h != NULL; h = h->h_next)