diff options
author | Eric Andersen <andersen@codepoet.org> | 2004-08-04 19:19:10 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2004-08-04 19:19:10 +0000 |
commit | 12de6cf0d791bff627a6071519b71c19240aa1ce (patch) | |
tree | f8b59eaf6b8fcc9f0013de8da8debe5cb250db5b | |
parent | 8401eeafd654d447053036cdd1dfbca9a0e297a8 (diff) | |
download | busybox-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.c | 1431 |
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 | ||
59 | int 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 | |||
73 | int 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 */ | ||
165 | char *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 | ||
135 | static char **dolv; | ||
136 | static int dolc; | ||
137 | static int exstat; | ||
138 | static char gflg; | ||
139 | static int interactive; /* Is this an interactive shell */ | ||
140 | static int execflg; | ||
141 | static int multiline; /* \n changed to ; */ | ||
142 | static struct op *outtree; /* result from parser */ | ||
143 | 210 | ||
144 | static xint *failpt; | 211 | /* PROTOTYPES */ |
145 | static xint *errpt; | ||
146 | static struct brkcon *brklist; | ||
147 | static int isbreak; | ||
148 | static int newfile(char *s); | 212 | static int newfile(char *s); |
149 | static char *findeq(char *cp); | 213 | static char *findeq(char *cp); |
150 | static char *cclass(char *p, int sub); | 214 | static 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 | ||
179 | static struct wdblock *wdlist; | 244 | |
180 | static 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 */ | |||
217 | static char line[LINELIM]; | 281 | static char line[LINELIM]; |
218 | static char *elinep; | 282 | static char *elinep; |
219 | 283 | ||
284 | |||
220 | /* | 285 | /* |
221 | * other functions | 286 | * other functions |
222 | */ | 287 | */ |
223 | static int (*inbuilt(char *s)) (struct op *); | 288 | static int (*inbuilt(char *s)) (struct op *); |
224 | 289 | ||
225 | |||
226 | static char *rexecve(char *c, char **v, char **envp); | 290 | static char *rexecve(char *c, char **v, char **envp); |
227 | static char *space(int n); | 291 | static char *space(int n); |
228 | static char *strsave(char *s, int a); | 292 | static char *strsave(char *s, int a); |
@@ -235,7 +299,7 @@ static int rlookup(char *n); | |||
235 | static struct wdblock *glob(char *cp, struct wdblock *wb); | 299 | static struct wdblock *glob(char *cp, struct wdblock *wb); |
236 | static int my_getc(int ec); | 300 | static int my_getc(int ec); |
237 | static int subgetc(int ec, int quoted); | 301 | static int subgetc(int ec, int quoted); |
238 | static char **makenv(void); | 302 | static char **makenv(int all); |
239 | static char **eval(char **ap, int f); | 303 | static char **eval(char **ap, int f); |
240 | static int setstatus(int s); | 304 | static int setstatus(int s); |
241 | static int waitfor(int lastpid, int canintr); | 305 | static int waitfor(int lastpid, int canintr); |
@@ -253,6 +317,7 @@ static void onecommand(void); | |||
253 | static void runtrap(int i); | 317 | static void runtrap(int i); |
254 | static int gmatch(char *s, char *p); | 318 | static 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 | ||
277 | struct region { | 342 | struct 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 | |||
315 | static struct op *pipeline(int cf); | 384 | static struct op *pipeline(int cf); |
316 | static struct op *andor(void); | 385 | static struct op *andor(void); |
317 | static struct op *c_list(void); | 386 | static 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 | ||
360 | static struct var *vlist; /* dictionary */ | ||
361 | |||
362 | static struct var *homedir; /* home directory */ | ||
363 | static struct var *prompt; /* main prompt */ | ||
364 | static struct var *cprompt; /* continuation prompt */ | ||
365 | static struct var *path; /* search path for commands */ | ||
366 | static struct var *shell; /* shell to interpret command files */ | ||
367 | static struct var *ifs; /* field separators */ | ||
368 | |||
369 | static int yyparse(void); | 429 | static int yyparse(void); |
370 | static struct var *lookup(char *n); | 430 | static struct var *lookup(char *n); |
371 | static void setval(struct var *vp, char *val); | 431 | static void setval(struct var *vp, char *val); |
@@ -380,6 +440,7 @@ static int eqname(char *n1, char *n2); | |||
380 | 440 | ||
381 | static int execute(struct op *t, int *pin, int *pout, int act); | 441 | static 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 */ |
385 | struct iobuf { | 446 | struct 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); | |||
443 | static int herein(char *hname, int xdoll); | 505 | static int herein(char *hname, int xdoll); |
444 | static int run(struct ioarg *argp, int (*f) (struct ioarg *)); | 506 | static 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); | |||
455 | static void closef(int i); | 518 | static void closef(int i); |
456 | static void closeall(void); | 519 | static 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); | |||
464 | static void closepipe(int *pv); | 528 | static void closepipe(int *pv); |
465 | static struct io *setbase(struct io *ip); | 529 | static struct io *setbase(struct io *ip); |
466 | 530 | ||
467 | static 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); | |||
497 | static void freecell(char *cp); | 559 | static void freecell(char *cp); |
498 | static int areanum; /* current allocation area */ | 560 | static 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 | ||
506 | static int forkexec(struct op *t, int *pin, int *pout, int act, char **wp, | 568 | static int forkexec(struct op *t, int *pin, int *pout, int act, char **wp); |
507 | int *pforked); | ||
508 | static int iosetup(struct ioword *iop, int pipein, int pipeout); | 569 | static int iosetup(struct ioword *iop, int pipein, int pipeout); |
509 | static void echo(char **wp); | 570 | static void echo(char **wp); |
510 | static struct op **find1case(struct op *t, char *w); | 571 | static 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 | ||
701 | static int expand_dotnode(struct op *); | ||
702 | struct op *scantree(struct op *); | ||
703 | static struct op *dowholefile(int, int); | ||
704 | |||
640 | /* Globals */ | 705 | /* Globals */ |
641 | extern char **environ; /* environment pointer */ | 706 | extern char **environ; /* environment pointer */ |
707 | |||
642 | static char **dolv; | 708 | static char **dolv; |
643 | static int dolc; | 709 | static int dolc; |
644 | static int exstat; | 710 | static int exstat; |
645 | static char gflg; | 711 | static char gflg; |
646 | static int interactive; /* Is this an interactive shell */ | 712 | static int interactive = 0; /* Is this an interactive shell */ |
647 | static int execflg; | 713 | static int execflg; |
648 | static int multiline; /* \n changed to ; */ | 714 | static int multiline; /* \n changed to ; */ |
649 | static struct op *outtree; /* result from parser */ | 715 | static struct op *outtree; /* result from parser */ |
@@ -658,6 +724,10 @@ static char ourtrap[_NSIG + 1]; | |||
658 | static int trapset; /* trap pending */ | 724 | static int trapset; /* trap pending */ |
659 | static int yynerrs; /* yacc */ | 725 | static int yynerrs; /* yacc */ |
660 | static char line[LINELIM]; | 726 | static char line[LINELIM]; |
727 | |||
728 | #ifdef MSHDEBUG | ||
729 | static struct var *mshdbg_var; | ||
730 | #endif | ||
661 | static struct var *vlist; /* dictionary */ | 731 | static struct var *vlist; /* dictionary */ |
662 | static struct var *homedir; /* home directory */ | 732 | static struct var *homedir; /* home directory */ |
663 | static struct var *prompt; /* main prompt */ | 733 | static struct var *prompt; /* main prompt */ |
@@ -665,29 +735,29 @@ static struct var *cprompt; /* continuation prompt */ | |||
665 | static struct var *path; /* search path for commands */ | 735 | static struct var *path; /* search path for commands */ |
666 | static struct var *shell; /* shell to interpret command files */ | 736 | static struct var *shell; /* shell to interpret command files */ |
667 | static struct var *ifs; /* field separators */ | 737 | static struct var *ifs; /* field separators */ |
668 | static struct ioarg ioargstack[NPUSH]; | 738 | |
669 | static struct io iostack[NPUSH]; | ||
670 | static int areanum; /* current allocation area */ | 739 | static int areanum; /* current allocation area */ |
671 | static int intr; | 740 | static int intr; |
672 | static int inparse; | 741 | static int inparse; |
673 | static char flags['z' - 'a' + 1]; | 742 | static char flags['z' - 'a' + 1]; |
674 | static char *flag = flags - 'a'; | 743 | static char *flag = flags - 'a'; |
675 | static char *elinep = line + sizeof(line) - 5; | ||
676 | static char *null = ""; | 744 | static char *null = ""; |
677 | static int heedint = 1; | 745 | static int heedint = 1; |
678 | static struct env e = | ||
679 | { line, iostack, iostack - 1, (xint *) NULL, FDBASE, | ||
680 | (struct env *) NULL }; | ||
681 | static void (*qflag) (int) = SIG_IGN; | 746 | static void (*qflag) (int) = SIG_IGN; |
682 | static int startl; | 747 | static int startl; |
683 | static int peeksym; | 748 | static int peeksym; |
684 | static int nlseen; | 749 | static int nlseen; |
685 | static int iounit = IODEFAULT; | 750 | static int iounit = IODEFAULT; |
686 | static YYSTYPE yylval; | 751 | static YYSTYPE yylval; |
752 | static char *elinep = line + sizeof(line) - 5; | ||
753 | |||
754 | static struct ioarg temparg = { 0, 0, 0, AFID_NOBUF, 0 }; /* temporary for PUSHIO */ | ||
755 | static struct ioarg ioargstack[NPUSH]; | ||
756 | static struct io iostack[NPUSH]; | ||
687 | static struct iobuf sharedbuf = { AFID_NOBUF }; | 757 | static struct iobuf sharedbuf = { AFID_NOBUF }; |
688 | static struct iobuf mainbuf = { AFID_NOBUF }; | 758 | static struct iobuf mainbuf = { AFID_NOBUF }; |
689 | static unsigned bufid = AFID_ID; /* buffer id counter */ | 759 | static unsigned bufid = AFID_ID; /* buffer id counter */ |
690 | static struct ioarg temparg = { 0, 0, 0, AFID_NOBUF, 0 }; | 760 | |
691 | static struct here *inhere; /* list of hear docs while parsing */ | 761 | static struct here *inhere; /* list of hear docs while parsing */ |
692 | static struct here *acthere; /* list of active here documents */ | 762 | static struct here *acthere; /* list of active here documents */ |
693 | static struct region *areabot; /* bottom of area */ | 763 | static struct region *areabot; /* bottom of area */ |
@@ -696,6 +766,48 @@ static struct region *areanxt; /* starting point of scan */ | |||
696 | static void *brktop; | 766 | static void *brktop; |
697 | static void *brkaddr; | 767 | static void *brkaddr; |
698 | 768 | ||
769 | static 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 | ||
779 | void 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 | |||
791 | void 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 |
701 | static char *current_prompt; | 813 | static char *current_prompt; |
@@ -709,12 +821,14 @@ static char *current_prompt; | |||
709 | 821 | ||
710 | extern int msh_main(int argc, char **argv) | 822 | extern 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 | ||
869 | static void setdash() | 1013 | static 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 | ||
883 | static int newfile(s) | 1027 | static int newfile(s) |
884 | register char *s; | 1028 | REGISTER 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 | |||
1050 | static int expand_dotnode(node) | ||
1051 | struct 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 | |||
1067 | struct op *scantree(head) | ||
1068 | struct 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 | |||
901 | static void onecommand() | 1101 | static 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 | ||
954 | static void leave() | 1168 | static 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 | ||
965 | static void warn(s) | 1181 | static void warn(s) |
966 | register char *s; | 1182 | REGISTER char *s; |
967 | { | 1183 | { |
968 | if (*s) { | 1184 | if (*s) { |
969 | prs(s); | 1185 | prs(s); |
@@ -991,12 +1207,15 @@ char *s; | |||
991 | static int newenv(f) | 1207 | static int newenv(f) |
992 | int f; | 1208 | int 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 | ||
1012 | static void quitenv() | 1232 | static 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 | */ |
1030 | static int anys(s1, s2) | 1252 | static int anys(s1, s2) |
1031 | register char *s1, *s2; | 1253 | REGISTER 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 | */ |
1042 | static int any(c, s) | 1264 | static int any(c, s) |
1043 | register int c; | 1265 | REGISTER int c; |
1044 | register char *s; | 1266 | REGISTER 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 | ||
1052 | static char *putn(n) | 1274 | static char *putn(n) |
1053 | register int n; | 1275 | REGISTER int n; |
1054 | { | 1276 | { |
1055 | return (itoa(n)); | 1277 | return (itoa(n)); |
1056 | } | 1278 | } |
1057 | 1279 | ||
1058 | static char *itoa(n) | 1280 | static char *itoa(n) |
1059 | register int n; | 1281 | REGISTER 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 | |||
1067 | static void next(int f) | 1290 | static 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 */ | |||
1088 | static char *space(n) | 1311 | static char *space(n) |
1089 | int n; | 1312 | int 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 | ||
1098 | static char *strsave(s, a) | 1321 | static char *strsave(s, a) |
1099 | register char *s; | 1322 | REGISTER char *s; |
1100 | int a; | 1323 | int 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 | */ |
1115 | static void sig(i) | 1338 | static void sig(i) |
1116 | register int i; | 1339 | REGISTER 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 | */ |
1142 | static struct var *lookup(n) | 1367 | static struct var *lookup(n) |
1143 | register char *n; | 1368 | REGISTER 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 | */ |
1197 | static void nameval(vp, val, name) | 1422 | static void nameval(vp, val, name) |
1198 | register struct var *vp; | 1423 | REGISTER struct var *vp; |
1199 | char *val, *name; | 1424 | char *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 | ||
1247 | static int isassign(s) | 1472 | static int isassign(s) |
1248 | register char *s; | 1473 | REGISTER 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 | ||
1258 | static int assign(s, cf) | 1486 | static int assign(s, cf) |
1259 | register char *s; | 1487 | REGISTER char *s; |
1260 | int cf; | 1488 | int 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 | ||
1277 | static int checkname(cp) | 1507 | static int checkname(cp) |
1278 | register char *cp; | 1508 | REGISTER 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 | ||
1288 | static void putvlist(f, out) | 1520 | static void putvlist(f, out) |
1289 | register int f, out; | 1521 | REGISTER 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 | ||
1304 | static int eqname(n1, n2) | 1536 | static int eqname(n1, n2) |
1305 | register char *n1, *n2; | 1537 | REGISTER 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 | ||
1313 | static char *findeq(cp) | 1545 | static char *findeq(cp) |
1314 | register char *cp; | 1546 | REGISTER 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 | ||
1334 | static int gmatch(s, p) | 1566 | static int gmatch(s, p) |
1335 | register char *s, *p; | 1567 | REGISTER 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 | ||
1370 | static char *cclass(p, sub) | 1602 | static char *cclass(p, sub) |
1371 | register char *p; | 1603 | REGISTER char *p; |
1372 | register int sub; | 1604 | REGISTER 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 | ||
1405 | static void initarea() | 1637 | static 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() | |||
1420 | char *getcell(nbytes) | 1652 | char *getcell(nbytes) |
1421 | unsigned nbytes; | 1653 | unsigned 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; | |||
1489 | static void freecell(cp) | 1721 | static void freecell(cp) |
1490 | char *cp; | 1722 | char *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 | ||
1502 | static void freearea(a) | 1734 | static void freearea(a) |
1503 | register int a; | 1735 | REGISTER 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) | |||
1514 | char *cp; | 1746 | char *cp; |
1515 | int a; | 1747 | int 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 | ||
1529 | static void garbage() | 1761 | static 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 | |||
1557 | int yyparse() | 1788 | int 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() | |||
1567 | static struct op *pipeline(cf) | 1800 | static struct op *pipeline(cf) |
1568 | int cf; | 1801 | int 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 | ||
1589 | static struct op *andor() | 1833 | static 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 | ||
1606 | static struct op *c_list() | 1861 | static 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 | |||
1629 | static int synio(cf) | 1893 | static int synio(cf) |
1630 | int cf; | 1894 | int 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 | ||
1649 | static void musthave(c, cf) | 1919 | static void musthave(c, cf) |
1650 | int c, cf; | 1920 | int 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 | ||
1657 | static struct op *simple() | 1930 | static 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() | |||
1684 | static struct op *nested(type, mark) | 1957 | static struct op *nested(type, mark) |
1685 | int type, mark; | 1958 | int 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; | |||
1696 | static struct op *command(cf) | 1971 | static struct op *command(cf) |
1697 | int cf; | 1972 | int 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 | |||
2085 | static struct op *dowholefile(type, mark) | ||
2086 | int type; | ||
2087 | int 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 | ||
1783 | static struct op *dogroup(onlydone) | 2101 | static struct op *dogroup(onlydone) |
1784 | int onlydone; | 2102 | int 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 | ||
1799 | static struct op *thenpart() | 2117 | static 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 | ||
1817 | static struct op *elsepart() | 2135 | static 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 | ||
1841 | static struct op *caselist() | 2159 | static 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 | ||
1851 | static struct op *casepart() | 2173 | static 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 | ||
1865 | static char **pattern() | 2192 | static 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 | ||
1880 | static char **wordlist() | 2208 | static 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 | */ |
1899 | static struct op *list(t1, t2) | 2227 | static struct op *list(t1, t2) |
1900 | register struct op *t1, *t2; | 2228 | REGISTER 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; | |||
1911 | struct op *t1, *t2; | 2242 | struct op *t1, *t2; |
1912 | char **wp; | 2243 | char **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) */ | ||
1924 | static int rlookup(n) | 2262 | static int rlookup(n) |
1925 | register char *n; | 2263 | REGISTER 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 | ||
1935 | static struct op *newtp() | 2279 | static 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 | ||
1949 | static struct op *namelist(t) | 2296 | static struct op *namelist(t) |
1950 | register struct op *t; | 2297 | REGISTER 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 | ||
1970 | static char **copyw() | 2325 | static 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 | ||
1985 | static struct ioword **copyio() | 2340 | static 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; | |||
1996 | int f; | 2351 | int f; |
1997 | char *cp; | 2352 | char *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; | |||
2026 | static int yylex(cf) | 2381 | static int yylex(cf) |
2027 | int cf; | 2382 | int 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 | |||
2143 | static int collect(c, c1) | 2515 | static int collect(c, c1) |
2144 | register int c, c1; | 2516 | REGISTER 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 */ | ||
2171 | static int dual(c) | 2551 | static int dual(c) |
2172 | register int c; | 2552 | REGISTER 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 | ||
2185 | static void diag(ec) | 2570 | static void diag(ec) |
2186 | register int ec; | 2571 | REGISTER 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; | |||
2204 | static char *tree(size) | 2591 | static char *tree(size) |
2205 | unsigned size; | 2592 | unsigned 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 | ||
2227 | static int execute(t, pin, pout, act) | 2615 | static int execute(t, pin, pout, act) |
2228 | register struct op *t; | 2616 | REGISTER struct op *t; |
2229 | int *pin, *pout; | 2617 | int *pin, *pout; |
2230 | int act; | 2618 | int 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) ℘ | 2629 | (void) ℘ |
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 | ||
2407 | static int | 2840 | static int |
2408 | forkexec(register struct op *t, int *pin, int *pout, int act, char **wp, | 2841 | forkexec(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 | */ |
2558 | static int iosetup(iop, pipein, pipeout) | 3071 | static int iosetup(iop, pipein, pipeout) |
2559 | register struct ioword *iop; | 3072 | REGISTER struct ioword *iop; |
2560 | int pipein, pipeout; | 3073 | int 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 | ||
2629 | static void echo(wp) | 3149 | static void echo(wp) |
2630 | register char **wp; | 3150 | REGISTER 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) | |||
2644 | struct op *t; | 3164 | struct op *t; |
2645 | char *w; | 3165 | char *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) | |||
2666 | struct op *t; | 3201 | struct op *t; |
2667 | char *w; | 3202 | char *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 | */ |
2691 | static int waitfor(lastpid, canintr) | 3226 | static int waitfor(lastpid, canintr) |
2692 | register int lastpid; | 3227 | REGISTER int lastpid; |
2693 | int canintr; | 3228 | int 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 | ||
2748 | static int setstatus(s) | 3283 | static int setstatus(s) |
2749 | register int s; | 3284 | REGISTER 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; | |||
2761 | static char *rexecve(c, v, envp) | 3296 | static char *rexecve(c, v, envp) |
2762 | char *c, **v, **envp; | 3297 | char *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 | ||
2914 | static int dochdir(t) | 3462 | static int dochdir(t) |
2915 | register struct op *t; | 3463 | REGISTER 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 | ||
2930 | static int doshift(t) | 3478 | static int doshift(t) |
2931 | register struct op *t; | 3479 | REGISTER 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; | |||
2950 | static int dologin(t) | 3498 | static int dologin(t) |
2951 | struct op *t; | 3499 | struct 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 | ||
2966 | static int doumask(t) | 3514 | static int doumask(t) |
2967 | register struct op *t; | 3515 | REGISTER 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 | ||
2986 | static int doexec(t) | 3534 | static int doexec(t) |
2987 | register struct op *t; | 3535 | REGISTER 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; | |||
3006 | static int dodot(t) | 3554 | static int dodot(t) |
3007 | struct op *t; | 3555 | struct 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 | ||
3034 | static int dowait(t) | 3607 | static int dowait(t) |
3035 | struct op *t; | 3608 | struct 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; | |||
3050 | static int doread(t) | 3623 | static int doread(t) |
3051 | struct op *t; | 3624 | struct 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 | ||
3074 | static int doeval(t) | 3647 | static int doeval(t) |
3075 | register struct op *t; | 3648 | REGISTER 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 | ||
3080 | static int dotrap(t) | 3653 | static int dotrap(t) |
3081 | register struct op *t; | 3654 | REGISTER 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; | |||
3120 | static int getsig(s) | 3693 | static int getsig(s) |
3121 | char *s; | 3694 | char *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 | ||
3132 | static void setsig(register int n, sighandler_t f) | 3705 | static 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) | |||
3142 | static int getn(as) | 3715 | static int getn(as) |
3143 | char *as; | 3716 | char *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 | ||
3175 | static int brkcontin(cp, val) | 3748 | static int brkcontin(cp, val) |
3176 | register char *cp; | 3749 | REGISTER char *cp; |
3177 | int val; | 3750 | int 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; | |||
3199 | static int doexit(t) | 3772 | static int doexit(t) |
3200 | struct op *t; | 3773 | struct 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 | ||
3226 | static void rdexp(char **wp, void (*f) (struct var *), int key) | 3802 | static 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 | ||
3246 | static void badid(s) | 3825 | static void badid(s) |
3247 | register char *s; | 3826 | REGISTER char *s; |
3248 | { | 3827 | { |
3249 | prs(s); | 3828 | prs(s); |
3250 | err(": bad identifier"); | 3829 | err(": bad identifier"); |
3251 | } | 3830 | } |
3252 | 3831 | ||
3253 | static int doset(t) | 3832 | static int doset(t) |
3254 | register struct op *t; | 3833 | REGISTER 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 | ||
3297 | static void varput(s, out) | 3876 | static void varput(s, out) |
3298 | register char *s; | 3877 | REGISTER char *s; |
3299 | int out; | 3878 | int 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) ℘ | 3939 | (void) ℘ |
3361 | (void) ≈ | 3940 | (void) ≈ |
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 | */ |
3392 | static char **makenv() | 3975 | static 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 | ||
3405 | static char *evalstr(cp, f) | 3990 | static char *evalstr(cp, f) |
3406 | register char *cp; | 3991 | REGISTER char *cp; |
3407 | int f; | 3992 | int 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 | ||
3422 | static int expand(char *cp, register struct wdblock **wbp, int f) | 4009 | static 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) | |||
3463 | static char *blank(f) | 4055 | static char *blank(f) |
3464 | int f; | 4056 | int 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 | */ |
3531 | static int subgetc(ec, quoted) | 4125 | static int subgetc(ec, quoted) |
3532 | register char ec; | 4126 | REGISTER char ec; |
3533 | int quoted; | 4127 | int 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) | |||
3660 | int quoted; | 4259 | int 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 | ||
3806 | static char *unquote(as) | 4412 | static char *unquote(as) |
3807 | register char *as; | 4413 | REGISTER 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) | |||
3831 | char *cp; | 4437 | char *cp; |
3832 | struct wdblock *wb; | 4438 | struct 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 | ||
3876 | static void globname(we, pp) | 4482 | static void globname(we, pp) |
3877 | char *we; | 4483 | char *we; |
3878 | register char *pp; | 4484 | REGISTER 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 | */ |
3939 | static char *generate(start1, end1, middle, end) | 4545 | static char *generate(start1, end1, middle, end) |
3940 | char *start1; | 4546 | char *start1; |
3941 | register char *end1; | 4547 | REGISTER char *end1; |
3942 | char *middle, *end; | 4548 | char *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 | ||
3957 | static int anyspcl(wb) | 4563 | static int anyspcl(wb) |
3958 | register struct wdblock *wb; | 4564 | REGISTER 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 | ||
3978 | static struct wdblock *newword(nw) | 4584 | static struct wdblock *newword(nw) |
3979 | register int nw; | 4585 | REGISTER 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 | ||
3989 | static struct wdblock *addword(wd, wb) | 4595 | static struct wdblock *addword(wd, wb) |
3990 | char *wd; | 4596 | char *wd; |
3991 | register struct wdblock *wb; | 4597 | REGISTER 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 | ||
4010 | static | 4616 | static |
4011 | char **getwords(wb) | 4617 | char **getwords(wb) |
4012 | register struct wdblock *wb; | 4618 | REGISTER 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 *); | |||
4043 | static void glob1(base, lim) | 4649 | static void glob1(base, lim) |
4044 | char *base, *lim; | 4650 | char *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; | |||
4113 | static void glob2(i, j) | 4719 | static void glob2(i, j) |
4114 | char *i, *j; | 4720 | char *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; | |||
4129 | static void glob3(i, j, k) | 4735 | static void glob3(i, j, k) |
4130 | char *i, *j, *k; | 4736 | char *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 | ||
4154 | static int my_getc(int ec) | 4760 | static 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 | ||
4188 | static int readc() | 4794 | static 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 | |||
4239 | static void pushio(struct ioarg *argp, int (*fn) (struct ioarg *)) | 4858 | static 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 | ||
4277 | static struct io *setbase(ip) | 4923 | static struct io *setbase(ip) |
4278 | struct io *ip; | 4924 | struct 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 | */ |
4294 | static int nlchar(ap) | 4940 | static int nlchar(ap) |
4295 | register struct ioarg *ap; | 4941 | REGISTER 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 | */ |
4312 | static int wdchar(ap) | 4958 | static int wdchar(ap) |
4313 | register struct ioarg *ap; | 4959 | REGISTER 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 | */ |
4334 | static int dolchar(ap) | 4980 | static int dolchar(ap) |
4335 | register struct ioarg *ap; | 4981 | REGISTER 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 | ||
4346 | static int xxchar(ap) | 4992 | static int xxchar(ap) |
4347 | register struct ioarg *ap; | 4993 | REGISTER 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 | */ |
4363 | static int strchar(ap) | 5009 | static int strchar(ap) |
4364 | register struct ioarg *ap; | 5010 | REGISTER 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 | */ |
4376 | static int qstrchar(ap) | 5022 | static int qstrchar(ap) |
4377 | register struct ioarg *ap; | 5023 | REGISTER 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 | */ |
4389 | static int filechar(ap) | 5035 | static int filechar(ap) |
4390 | register struct ioarg *ap; | 5036 | REGISTER 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 | */ |
4435 | static int herechar(ap) | 5087 | static int herechar(ap) |
4436 | register struct ioarg *ap; | 5088 | REGISTER struct ioarg *ap; |
4437 | { | 5089 | { |
4438 | char c; | 5090 | char c; |
4439 | 5091 | ||
@@ -4454,7 +5106,7 @@ static int gravechar(ap, iop) | |||
4454 | struct ioarg *ap; | 5106 | struct ioarg *ap; |
4455 | struct io *iop; | 5107 | struct 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 | ||
4464 | static int qgravechar(ap, iop) | 5116 | static int qgravechar(ap, iop) |
4465 | register struct ioarg *ap; | 5117 | REGISTER struct ioarg *ap; |
4466 | struct io *iop; | 5118 | struct 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 | */ |
4493 | static int linechar(ap) | 5147 | static int linechar(ap) |
4494 | register struct ioarg *ap; | 5148 | REGISTER 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 | ||
4507 | static void prs(s) | 5161 | static void prs(s) |
4508 | register char *s; | 5162 | REGISTER 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 | ||
4520 | static void closef(i) | 5174 | static void closef(i) |
4521 | register int i; | 5175 | REGISTER 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 | ||
4527 | static void closeall() | 5181 | static 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 | */ |
4538 | static int remap(fd) | 5193 | static int remap(fd) |
4539 | register int fd; | 5194 | REGISTER 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 | ||
4560 | static int openpipe(pv) | 5224 | static int openpipe(pv) |
4561 | register int *pv; | 5225 | REGISTER 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 | ||
4570 | static void closepipe(pv) | 5234 | static void closepipe(pv) |
4571 | register int *pv; | 5235 | REGISTER 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 | ||
4585 | static void markhere(s, iop) | 5249 | static void markhere(s, iop) |
4586 | register char *s; | 5250 | REGISTER char *s; |
4587 | struct ioword *iop; | 5251 | struct 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 | ||
4617 | static void gethere() | 5285 | static 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 | ||
4633 | static void readhere(name, s, ec) | 5303 | static void readhere(name, s, ec) |
4634 | char **name; | 5304 | char **name; |
4635 | register char *s; | 5305 | REGISTER char *s; |
4636 | int ec; | 5306 | int 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) | |||
4693 | char *hname; | 5366 | char *hname; |
4694 | int xdoll; | 5367 | int 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 | ||
4734 | static void scraphere() | 5411 | static 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() | |||
4746 | static void freehere(area) | 5425 | static void freehere(area) |
4747 | int area; | 5426 | int 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) |