diff options
author | Glenn L McGrath <bug1@ihug.co.nz> | 2002-08-22 18:41:20 +0000 |
---|---|---|
committer | Glenn L McGrath <bug1@ihug.co.nz> | 2002-08-22 18:41:20 +0000 |
commit | 9fef17dec333e17b1f24bc729d3b16725f4ccc75 (patch) | |
tree | 87eca9d8c978b9ea4736e05e4c480d51097e0319 /shell | |
parent | 7c58e9be69b2a3f52977879b1a300579c9914b29 (diff) | |
download | busybox-w32-9fef17dec333e17b1f24bc729d3b16725f4ccc75.tar.gz busybox-w32-9fef17dec333e17b1f24bc729d3b16725f4ccc75.tar.bz2 busybox-w32-9fef17dec333e17b1f24bc729d3b16725f4ccc75.zip |
Run through indent, fix comments
Diffstat (limited to 'shell')
-rw-r--r-- | shell/ash.c | 5495 |
1 files changed, 2705 insertions, 2790 deletions
diff --git a/shell/ash.c b/shell/ash.c index 09975198d..15ec04380 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -90,21 +90,21 @@ | |||
90 | */ | 90 | */ |
91 | 91 | ||
92 | /* Syntax classes */ | 92 | /* Syntax classes */ |
93 | #define CWORD 0 /* character is nothing special */ | 93 | #define CWORD 0 /* character is nothing special */ |
94 | #define CNL 1 /* newline character */ | 94 | #define CNL 1 /* newline character */ |
95 | #define CBACK 2 /* a backslash character */ | 95 | #define CBACK 2 /* a backslash character */ |
96 | #define CSQUOTE 3 /* single quote */ | 96 | #define CSQUOTE 3 /* single quote */ |
97 | #define CDQUOTE 4 /* double quote */ | 97 | #define CDQUOTE 4 /* double quote */ |
98 | #define CENDQUOTE 5 /* a terminating quote */ | 98 | #define CENDQUOTE 5 /* a terminating quote */ |
99 | #define CBQUOTE 6 /* backwards single quote */ | 99 | #define CBQUOTE 6 /* backwards single quote */ |
100 | #define CVAR 7 /* a dollar sign */ | 100 | #define CVAR 7 /* a dollar sign */ |
101 | #define CENDVAR 8 /* a '}' character */ | 101 | #define CENDVAR 8 /* a '}' character */ |
102 | #define CLP 9 /* a left paren in arithmetic */ | 102 | #define CLP 9 /* a left paren in arithmetic */ |
103 | #define CRP 10 /* a right paren in arithmetic */ | 103 | #define CRP 10 /* a right paren in arithmetic */ |
104 | #define CENDFILE 11 /* end of file */ | 104 | #define CENDFILE 11 /* end of file */ |
105 | #define CCTL 12 /* like CWORD, except it must be escaped */ | 105 | #define CCTL 12 /* like CWORD, except it must be escaped */ |
106 | #define CSPCL 13 /* these terminate a word */ | 106 | #define CSPCL 13 /* these terminate a word */ |
107 | #define CIGN 14 /* character should be ignored */ | 107 | #define CIGN 14 /* character should be ignored */ |
108 | 108 | ||
109 | #define SYNBASE 130 | 109 | #define SYNBASE 130 |
110 | #define PEOF -130 | 110 | #define PEOF -130 |
@@ -149,7 +149,7 @@ | |||
149 | #define CTLVAR '\202' | 149 | #define CTLVAR '\202' |
150 | #define CTLENDVAR '\203' | 150 | #define CTLENDVAR '\203' |
151 | #define CTLBACKQ '\204' | 151 | #define CTLBACKQ '\204' |
152 | #define CTLQUOTE 01 /* ored with CTLBACKQ code if in quotes */ | 152 | #define CTLQUOTE 01 /* ored with CTLBACKQ code if in quotes */ |
153 | /* CTLBACKQ | CTLQUOTE == '\205' */ | 153 | /* CTLBACKQ | CTLQUOTE == '\205' */ |
154 | #define CTLARI '\206' | 154 | #define CTLARI '\206' |
155 | #define CTLENDARI '\207' | 155 | #define CTLENDARI '\207' |
@@ -171,33 +171,33 @@ | |||
171 | #define digit_val(c) ((c) - '0') | 171 | #define digit_val(c) ((c) - '0') |
172 | 172 | ||
173 | 173 | ||
174 | #define S_DFL 1 /* default signal handling (SIG_DFL) */ | 174 | #define S_DFL 1 /* default signal handling (SIG_DFL) */ |
175 | #define S_CATCH 2 /* signal is caught */ | 175 | #define S_CATCH 2 /* signal is caught */ |
176 | #define S_IGN 3 /* signal is ignored (SIG_IGN) */ | 176 | #define S_IGN 3 /* signal is ignored (SIG_IGN) */ |
177 | #define S_HARD_IGN 4 /* signal is ignored permenantly */ | 177 | #define S_HARD_IGN 4 /* signal is ignored permenantly */ |
178 | #define S_RESET 5 /* temporary - to reset a hard ignored sig */ | 178 | #define S_RESET 5 /* temporary - to reset a hard ignored sig */ |
179 | 179 | ||
180 | 180 | ||
181 | /* variable substitution byte (follows CTLVAR) */ | 181 | /* variable substitution byte (follows CTLVAR) */ |
182 | #define VSTYPE 0x0f /* type of variable substitution */ | 182 | #define VSTYPE 0x0f /* type of variable substitution */ |
183 | #define VSNUL 0x10 /* colon--treat the empty string as unset */ | 183 | #define VSNUL 0x10 /* colon--treat the empty string as unset */ |
184 | #define VSQUOTE 0x80 /* inside double quotes--suppress splitting */ | 184 | #define VSQUOTE 0x80 /* inside double quotes--suppress splitting */ |
185 | 185 | ||
186 | /* values of VSTYPE field */ | 186 | /* values of VSTYPE field */ |
187 | #define VSNORMAL 0x1 /* normal variable: $var or ${var} */ | 187 | #define VSNORMAL 0x1 /* normal variable: $var or ${var} */ |
188 | #define VSMINUS 0x2 /* ${var-text} */ | 188 | #define VSMINUS 0x2 /* ${var-text} */ |
189 | #define VSPLUS 0x3 /* ${var+text} */ | 189 | #define VSPLUS 0x3 /* ${var+text} */ |
190 | #define VSQUESTION 0x4 /* ${var?message} */ | 190 | #define VSQUESTION 0x4 /* ${var?message} */ |
191 | #define VSASSIGN 0x5 /* ${var=text} */ | 191 | #define VSASSIGN 0x5 /* ${var=text} */ |
192 | #define VSTRIMLEFT 0x6 /* ${var#pattern} */ | 192 | #define VSTRIMLEFT 0x6 /* ${var#pattern} */ |
193 | #define VSTRIMLEFTMAX 0x7 /* ${var##pattern} */ | 193 | #define VSTRIMLEFTMAX 0x7 /* ${var##pattern} */ |
194 | #define VSTRIMRIGHT 0x8 /* ${var%pattern} */ | 194 | #define VSTRIMRIGHT 0x8 /* ${var%pattern} */ |
195 | #define VSTRIMRIGHTMAX 0x9 /* ${var%%pattern} */ | 195 | #define VSTRIMRIGHTMAX 0x9 /* ${var%%pattern} */ |
196 | #define VSLENGTH 0xa /* ${#var} */ | 196 | #define VSLENGTH 0xa /* ${#var} */ |
197 | 197 | ||
198 | /* flags passed to redirect */ | 198 | /* flags passed to redirect */ |
199 | #define REDIR_PUSH 01 /* save previous values of file descriptors */ | 199 | #define REDIR_PUSH 01 /* save previous values of file descriptors */ |
200 | #define REDIR_BACKQ 02 /* save the command output to pipe */ | 200 | #define REDIR_BACKQ 02 /* save the command output to pipe */ |
201 | 201 | ||
202 | /* | 202 | /* |
203 | * BSD setjmp saves the signal mask, which violates ANSI C and takes time, | 203 | * BSD setjmp saves the signal mask, which violates ANSI C and takes time, |
@@ -236,7 +236,7 @@ static void change_lc_ctype(const char *value); | |||
236 | * more fun than worrying about efficiency and portability. :-)) | 236 | * more fun than worrying about efficiency and portability. :-)) |
237 | */ | 237 | */ |
238 | 238 | ||
239 | static void onint (void); | 239 | static void onint(void); |
240 | static volatile int suppressint; | 240 | static volatile int suppressint; |
241 | static volatile int intpending; | 241 | static volatile int intpending; |
242 | 242 | ||
@@ -245,8 +245,9 @@ static volatile int intpending; | |||
245 | #define INTON { if (--suppressint == 0 && intpending) onint(); } | 245 | #define INTON { if (--suppressint == 0 && intpending) onint(); } |
246 | #define FORCEINTON {suppressint = 0; if (intpending) onint();} | 246 | #define FORCEINTON {suppressint = 0; if (intpending) onint();} |
247 | #else | 247 | #else |
248 | static void __inton (void); | 248 | static void __inton(void); |
249 | static void forceinton (void); | 249 | static void forceinton(void); |
250 | |||
250 | #define INTON __inton() | 251 | #define INTON __inton() |
251 | #define FORCEINTON forceinton() | 252 | #define FORCEINTON forceinton() |
252 | #endif | 253 | #endif |
@@ -256,16 +257,17 @@ static void forceinton (void); | |||
256 | 257 | ||
257 | 258 | ||
258 | typedef void *pointer; | 259 | typedef void *pointer; |
260 | |||
259 | #ifndef NULL | 261 | #ifndef NULL |
260 | #define NULL (void *)0 | 262 | #define NULL (void *)0 |
261 | #endif | 263 | #endif |
262 | 264 | ||
263 | static pointer stalloc (int); | 265 | static pointer stalloc(int); |
264 | static void stunalloc (pointer); | 266 | static void stunalloc(pointer); |
265 | static void ungrabstackstr (char *, char *); | 267 | static void ungrabstackstr(char *, char *); |
266 | static char * growstackstr(void); | 268 | static char *growstackstr(void); |
267 | static char * makestrspace(size_t newlen); | 269 | static char *makestrspace(size_t newlen); |
268 | static char *sstrdup (const char *); | 270 | static char *sstrdup(const char *); |
269 | 271 | ||
270 | /* | 272 | /* |
271 | * Parse trees for commands are allocated in lifo order, so we use a stack | 273 | * Parse trees for commands are allocated in lifo order, so we use a stack |
@@ -276,7 +278,7 @@ static char *sstrdup (const char *); | |||
276 | * well. | 278 | * well. |
277 | */ | 279 | */ |
278 | 280 | ||
279 | #define MINSIZE 504 /* minimum size of a block */ | 281 | #define MINSIZE 504 /* minimum size of a block */ |
280 | 282 | ||
281 | 283 | ||
282 | struct stack_block { | 284 | struct stack_block { |
@@ -313,12 +315,12 @@ static int stacknleft = MINSIZE; | |||
313 | #ifdef DEBUG | 315 | #ifdef DEBUG |
314 | #define TRACE(param) trace param | 316 | #define TRACE(param) trace param |
315 | typedef union node unode; | 317 | typedef union node unode; |
316 | static void trace (const char *, ...); | 318 | static void trace(const char *, ...); |
317 | static void trargs (char **); | 319 | static void trargs(char **); |
318 | static void showtree (unode *); | 320 | static void showtree(unode *); |
319 | static void trputc (int); | 321 | static void trputc(int); |
320 | static void trputs (const char *); | 322 | static void trputs(const char *); |
321 | static void opentrace (void); | 323 | static void opentrace(void); |
322 | #else | 324 | #else |
323 | #define TRACE(param) | 325 | #define TRACE(param) |
324 | #endif | 326 | #endif |
@@ -353,19 +355,19 @@ static void opentrace (void); | |||
353 | /* | 355 | /* |
354 | * expandarg() flags | 356 | * expandarg() flags |
355 | */ | 357 | */ |
356 | #define EXP_FULL 0x1 /* perform word splitting & file globbing */ | 358 | #define EXP_FULL 0x1 /* perform word splitting & file globbing */ |
357 | #define EXP_TILDE 0x2 /* do normal tilde expansion */ | 359 | #define EXP_TILDE 0x2 /* do normal tilde expansion */ |
358 | #define EXP_VARTILDE 0x4 /* expand tildes in an assignment */ | 360 | #define EXP_VARTILDE 0x4 /* expand tildes in an assignment */ |
359 | #define EXP_REDIR 0x8 /* file glob for a redirection (1 match only) */ | 361 | #define EXP_REDIR 0x8 /* file glob for a redirection (1 match only) */ |
360 | #define EXP_CASE 0x10 /* keeps quotes around for CASE pattern */ | 362 | #define EXP_CASE 0x10 /* keeps quotes around for CASE pattern */ |
361 | #define EXP_RECORD 0x20 /* need to record arguments for ifs breakup */ | 363 | #define EXP_RECORD 0x20 /* need to record arguments for ifs breakup */ |
362 | 364 | ||
363 | 365 | ||
364 | #define NOPTS 16 | 366 | #define NOPTS 16 |
365 | 367 | ||
366 | static char optet_vals[NOPTS]; | 368 | static char optet_vals[NOPTS]; |
367 | 369 | ||
368 | static const char * const optlist[NOPTS] = { | 370 | static const char *const optlist[NOPTS] = { |
369 | "e" "errexit", | 371 | "e" "errexit", |
370 | "f" "noglob", | 372 | "f" "noglob", |
371 | "I" "ignoreeof", | 373 | "I" "ignoreeof", |
@@ -413,121 +415,121 @@ static const char * const optlist[NOPTS] = { | |||
413 | 415 | ||
414 | 416 | ||
415 | struct nbinary { | 417 | struct nbinary { |
416 | int type; | 418 | int type; |
417 | union node *ch1; | 419 | union node *ch1; |
418 | union node *ch2; | 420 | union node *ch2; |
419 | }; | 421 | }; |
420 | 422 | ||
421 | 423 | ||
422 | struct ncmd { | 424 | struct ncmd { |
423 | int type; | 425 | int type; |
424 | int backgnd; | 426 | int backgnd; |
425 | union node *assign; | 427 | union node *assign; |
426 | union node *args; | 428 | union node *args; |
427 | union node *redirect; | 429 | union node *redirect; |
428 | }; | 430 | }; |
429 | 431 | ||
430 | 432 | ||
431 | struct npipe { | 433 | struct npipe { |
432 | int type; | 434 | int type; |
433 | int backgnd; | 435 | int backgnd; |
434 | struct nodelist *cmdlist; | 436 | struct nodelist *cmdlist; |
435 | }; | 437 | }; |
436 | 438 | ||
437 | 439 | ||
438 | struct nredir { | 440 | struct nredir { |
439 | int type; | 441 | int type; |
440 | union node *n; | 442 | union node *n; |
441 | union node *redirect; | 443 | union node *redirect; |
442 | }; | 444 | }; |
443 | 445 | ||
444 | 446 | ||
445 | struct nif { | 447 | struct nif { |
446 | int type; | 448 | int type; |
447 | union node *test; | 449 | union node *test; |
448 | union node *ifpart; | 450 | union node *ifpart; |
449 | union node *elsepart; | 451 | union node *elsepart; |
450 | }; | 452 | }; |
451 | 453 | ||
452 | 454 | ||
453 | struct nfor { | 455 | struct nfor { |
454 | int type; | 456 | int type; |
455 | union node *args; | 457 | union node *args; |
456 | union node *body; | 458 | union node *body; |
457 | char *var; | 459 | char *var; |
458 | }; | 460 | }; |
459 | 461 | ||
460 | 462 | ||
461 | struct ncase { | 463 | struct ncase { |
462 | int type; | 464 | int type; |
463 | union node *expr; | 465 | union node *expr; |
464 | union node *cases; | 466 | union node *cases; |
465 | }; | 467 | }; |
466 | 468 | ||
467 | 469 | ||
468 | struct nclist { | 470 | struct nclist { |
469 | int type; | 471 | int type; |
470 | union node *next; | 472 | union node *next; |
471 | union node *pattern; | 473 | union node *pattern; |
472 | union node *body; | 474 | union node *body; |
473 | }; | 475 | }; |
474 | 476 | ||
475 | 477 | ||
476 | struct narg { | 478 | struct narg { |
477 | int type; | 479 | int type; |
478 | union node *next; | 480 | union node *next; |
479 | char *text; | 481 | char *text; |
480 | struct nodelist *backquote; | 482 | struct nodelist *backquote; |
481 | }; | 483 | }; |
482 | 484 | ||
483 | 485 | ||
484 | struct nfile { | 486 | struct nfile { |
485 | int type; | 487 | int type; |
486 | union node *next; | 488 | union node *next; |
487 | int fd; | 489 | int fd; |
488 | union node *fname; | 490 | union node *fname; |
489 | char *expfname; | 491 | char *expfname; |
490 | }; | 492 | }; |
491 | 493 | ||
492 | 494 | ||
493 | struct ndup { | 495 | struct ndup { |
494 | int type; | 496 | int type; |
495 | union node *next; | 497 | union node *next; |
496 | int fd; | 498 | int fd; |
497 | int dupfd; | 499 | int dupfd; |
498 | union node *vname; | 500 | union node *vname; |
499 | }; | 501 | }; |
500 | 502 | ||
501 | 503 | ||
502 | struct nhere { | 504 | struct nhere { |
503 | int type; | 505 | int type; |
504 | union node *next; | 506 | union node *next; |
505 | int fd; | 507 | int fd; |
506 | union node *doc; | 508 | union node *doc; |
507 | }; | 509 | }; |
508 | 510 | ||
509 | 511 | ||
510 | struct nnot { | 512 | struct nnot { |
511 | int type; | 513 | int type; |
512 | union node *com; | 514 | union node *com; |
513 | }; | 515 | }; |
514 | 516 | ||
515 | 517 | ||
516 | union node { | 518 | union node { |
517 | int type; | 519 | int type; |
518 | struct nbinary nbinary; | 520 | struct nbinary nbinary; |
519 | struct ncmd ncmd; | 521 | struct ncmd ncmd; |
520 | struct npipe npipe; | 522 | struct npipe npipe; |
521 | struct nredir nredir; | 523 | struct nredir nredir; |
522 | struct nif nif; | 524 | struct nif nif; |
523 | struct nfor nfor; | 525 | struct nfor nfor; |
524 | struct ncase ncase; | 526 | struct ncase ncase; |
525 | struct nclist nclist; | 527 | struct nclist nclist; |
526 | struct narg narg; | 528 | struct narg narg; |
527 | struct nfile nfile; | 529 | struct nfile nfile; |
528 | struct ndup ndup; | 530 | struct ndup ndup; |
529 | struct nhere nhere; | 531 | struct nhere nhere; |
530 | struct nnot nnot; | 532 | struct nnot nnot; |
531 | }; | 533 | }; |
532 | 534 | ||
533 | 535 | ||
@@ -536,11 +538,11 @@ struct nodelist { | |||
536 | union node *n; | 538 | union node *n; |
537 | }; | 539 | }; |
538 | 540 | ||
539 | struct backcmd { /* result of evalbackcmd */ | 541 | struct backcmd { /* result of evalbackcmd */ |
540 | int fd; /* file descriptor to read from */ | 542 | int fd; /* file descriptor to read from */ |
541 | char *buf; /* buffer */ | 543 | char *buf; /* buffer */ |
542 | int nleft; /* number of chars in buffer */ | 544 | int nleft; /* number of chars in buffer */ |
543 | struct job *jp; /* job structure for command */ | 545 | struct job *jp; /* job structure for command */ |
544 | }; | 546 | }; |
545 | 547 | ||
546 | struct cmdentry { | 548 | struct cmdentry { |
@@ -564,25 +566,25 @@ struct arglist { | |||
564 | }; | 566 | }; |
565 | 567 | ||
566 | struct strpush { | 568 | struct strpush { |
567 | struct strpush *prev; /* preceding string on stack */ | 569 | struct strpush *prev; /* preceding string on stack */ |
568 | char *prevstring; | 570 | char *prevstring; |
569 | int prevnleft; | 571 | int prevnleft; |
570 | #ifdef CONFIG_ASH_ALIAS | 572 | #ifdef CONFIG_ASH_ALIAS |
571 | struct alias *ap; /* if push was associated with an alias */ | 573 | struct alias *ap; /* if push was associated with an alias */ |
572 | #endif | 574 | #endif |
573 | char *string; /* remember the string since it may change */ | 575 | char *string; /* remember the string since it may change */ |
574 | }; | 576 | }; |
575 | 577 | ||
576 | struct parsefile { | 578 | struct parsefile { |
577 | struct parsefile *prev; /* preceding file on stack */ | 579 | struct parsefile *prev; /* preceding file on stack */ |
578 | int linno; /* current line */ | 580 | int linno; /* current line */ |
579 | int fd; /* file descriptor (or -1 if string) */ | 581 | int fd; /* file descriptor (or -1 if string) */ |
580 | int nleft; /* number of chars left in this line */ | 582 | int nleft; /* number of chars left in this line */ |
581 | int lleft; /* number of chars left in this buffer */ | 583 | int lleft; /* number of chars left in this buffer */ |
582 | char *nextc; /* next char in buffer */ | 584 | char *nextc; /* next char in buffer */ |
583 | char *buf; /* input buffer */ | 585 | char *buf; /* input buffer */ |
584 | struct strpush *strpush; /* for pushing strings at this level */ | 586 | struct strpush *strpush; /* for pushing strings at this level */ |
585 | struct strpush basestrpush; /* so pushing one is fast */ | 587 | struct strpush basestrpush; /* so pushing one is fast */ |
586 | }; | 588 | }; |
587 | 589 | ||
588 | struct stackmark { | 590 | struct stackmark { |
@@ -593,11 +595,11 @@ struct stackmark { | |||
593 | }; | 595 | }; |
594 | 596 | ||
595 | struct shparam { | 597 | struct shparam { |
596 | int nparam; /* # of positional parameters (without $0) */ | 598 | int nparam; /* # of positional parameters (without $0) */ |
597 | unsigned char malloc; /* if parameter list dynamically allocated */ | 599 | unsigned char malloc; /* if parameter list dynamically allocated */ |
598 | char **p; /* parameter list */ | 600 | char **p; /* parameter list */ |
599 | int optind; /* next parameter to be processed by getopts */ | 601 | int optind; /* next parameter to be processed by getopts */ |
600 | int optoff; /* used by getopts */ | 602 | int optoff; /* used by getopts */ |
601 | }; | 603 | }; |
602 | 604 | ||
603 | /* | 605 | /* |
@@ -608,46 +610,58 @@ struct shparam { | |||
608 | * We should investigate converting to a linear search, even though that | 610 | * We should investigate converting to a linear search, even though that |
609 | * would make the command name "hash" a misnomer. | 611 | * would make the command name "hash" a misnomer. |
610 | */ | 612 | */ |
611 | #define CMDTABLESIZE 31 /* should be prime */ | 613 | #define CMDTABLESIZE 31 /* should be prime */ |
612 | #define ARB 1 /* actual size determined at run time */ | 614 | #define ARB 1 /* actual size determined at run time */ |
613 | 615 | ||
614 | 616 | ||
615 | 617 | ||
616 | struct tblentry { | 618 | struct tblentry { |
617 | struct tblentry *next; /* next entry in hash chain */ | 619 | struct tblentry *next; /* next entry in hash chain */ |
618 | union param param; /* definition of builtin function */ | 620 | union param param; /* definition of builtin function */ |
619 | short cmdtype; /* index identifying command */ | 621 | short cmdtype; /* index identifying command */ |
620 | char rehash; /* if set, cd done since entry created */ | 622 | char rehash; /* if set, cd done since entry created */ |
621 | char cmdname[ARB]; /* name of command */ | 623 | char cmdname[ARB]; /* name of command */ |
622 | }; | 624 | }; |
623 | 625 | ||
624 | 626 | ||
625 | static struct tblentry *cmdtable[CMDTABLESIZE]; | 627 | static struct tblentry *cmdtable[CMDTABLESIZE]; |
626 | static int builtinloc = -1; /* index in path of %builtin, or -1 */ | 628 | static int builtinloc = -1; /* index in path of %builtin, or -1 */ |
627 | static int exerrno = 0; /* Last exec error */ | 629 | static int exerrno = 0; /* Last exec error */ |
628 | 630 | ||
629 | 631 | ||
630 | static void tryexec (char *, char **, char **); | 632 | static void tryexec(char *, char **, char **); |
631 | static void printentry (struct tblentry *, int); | 633 | static void printentry(struct tblentry *, int); |
632 | static void clearcmdentry (int); | 634 | static void clearcmdentry(int); |
633 | static struct tblentry *cmdlookup (const char *, int); | 635 | static struct tblentry *cmdlookup(const char *, int); |
634 | static void delete_cmd_entry (void); | 636 | static void delete_cmd_entry(void); |
635 | static int path_change (const char *, int *); | 637 | static int path_change(const char *, int *); |
636 | 638 | ||
637 | 639 | ||
638 | static void flushall (void); | 640 | static void flushall(void); |
639 | static void out2fmt (const char *, ...) | 641 | static void out2fmt(const char *, ...) |
640 | __attribute__((__format__(__printf__,1,2))); | 642 | __attribute__ ((__format__(__printf__, 1, 2))); |
641 | static int xwrite (int, const char *, int); | 643 | static int xwrite(int, const char *, int); |
642 | 644 | ||
643 | static inline void outstr (const char *p, FILE *file) { fputs(p, file); } | 645 | static inline void outstr(const char *p, FILE * file) |
644 | static void out1str(const char *p) { outstr(p, stdout); } | 646 | { |
645 | static void out2str(const char *p) { outstr(p, stderr); } | 647 | fputs(p, file); |
648 | } | ||
649 | static void out1str(const char *p) | ||
650 | { | ||
651 | outstr(p, stdout); | ||
652 | } | ||
653 | static void out2str(const char *p) | ||
654 | { | ||
655 | outstr(p, stderr); | ||
656 | } | ||
646 | 657 | ||
647 | #ifndef CONFIG_ASH_OPTIMIZE_FOR_SIZE | 658 | #ifndef CONFIG_ASH_OPTIMIZE_FOR_SIZE |
648 | #define out2c(c) putc((c), stderr) | 659 | #define out2c(c) putc((c), stderr) |
649 | #else | 660 | #else |
650 | static void out2c(int c) { putc(c, stderr); } | 661 | static void out2c(int c) |
662 | { | ||
663 | putc(c, stderr); | ||
664 | } | ||
651 | #endif | 665 | #endif |
652 | 666 | ||
653 | 667 | ||
@@ -656,28 +670,43 @@ static void out2c(int c) { putc(c, stderr); } | |||
656 | #endif | 670 | #endif |
657 | 671 | ||
658 | /* number syntax index */ | 672 | /* number syntax index */ |
659 | #define BASESYNTAX 0 /* not in quotes */ | 673 | #define BASESYNTAX 0 /* not in quotes */ |
660 | #define DQSYNTAX 1 /* in double quotes */ | 674 | #define DQSYNTAX 1 /* in double quotes */ |
661 | #define SQSYNTAX 2 /* in single quotes */ | 675 | #define SQSYNTAX 2 /* in single quotes */ |
662 | #define ARISYNTAX 3 /* in arithmetic */ | 676 | #define ARISYNTAX 3 /* in arithmetic */ |
663 | 677 | ||
664 | static const char S_I_T[][4] = { | 678 | static const char S_I_T[][4] = { |
665 | /* 0 */ { CSPCL, CIGN, CIGN, CIGN }, /* PEOA */ | 679 | /* 0 */ {CSPCL, CIGN, CIGN, CIGN}, |
666 | /* 1 */ { CSPCL, CWORD, CWORD, CWORD }, /* ' ' */ | 680 | /* PEOA */ |
667 | /* 2 */ { CNL, CNL, CNL, CNL }, /* \n */ | 681 | /* 1 */ {CSPCL, CWORD, CWORD, CWORD}, |
668 | /* 3 */ { CWORD, CCTL, CCTL, CWORD }, /* !*-/:=?[]~ */ | 682 | /* ' ' */ |
669 | /* 4 */ { CDQUOTE, CENDQUOTE, CWORD, CDQUOTE }, /* '"' */ | 683 | /* 2 */ {CNL, CNL, CNL, CNL}, |
670 | /* 5 */ { CVAR, CVAR, CWORD, CVAR }, /* $ */ | 684 | /* \n */ |
671 | /* 6 */ { CSQUOTE, CWORD, CENDQUOTE, CSQUOTE }, /* "'" */ | 685 | /* 3 */ {CWORD, CCTL, CCTL, CWORD}, |
672 | /* 7 */ { CSPCL, CWORD, CWORD, CLP }, /* ( */ | 686 | /* !*-/:=?[]~ */ |
673 | /* 8 */ { CSPCL, CWORD, CWORD, CRP }, /* ) */ | 687 | /* 4 */ {CDQUOTE, CENDQUOTE, CWORD, CDQUOTE}, |
674 | /* 9 */ { CBACK, CBACK, CCTL, CBACK }, /* \ */ | 688 | /* '"' */ |
675 | /* 10 */ { CBQUOTE, CBQUOTE, CWORD, CBQUOTE }, /* ` */ | 689 | /* 5 */ {CVAR, CVAR, CWORD, CVAR}, |
676 | /* 11 */ { CENDVAR, CENDVAR, CWORD, CENDVAR }, /* } */ | 690 | /* $ */ |
691 | /* 6 */ {CSQUOTE, CWORD, CENDQUOTE, CSQUOTE}, | ||
692 | /* "'" */ | ||
693 | /* 7 */ {CSPCL, CWORD, CWORD, CLP}, | ||
694 | /* ( */ | ||
695 | /* 8 */ {CSPCL, CWORD, CWORD, CRP}, | ||
696 | /* ) */ | ||
697 | /* 9 */ {CBACK, CBACK, CCTL, CBACK}, | ||
698 | /* \ */ | ||
699 | /* 10 */ {CBQUOTE, CBQUOTE, CWORD, CBQUOTE}, | ||
700 | /* ` */ | ||
701 | /* 11 */ {CENDVAR, CENDVAR, CWORD, CENDVAR}, | ||
702 | /* } */ | ||
677 | #ifndef USE_SIT_FUNCTION | 703 | #ifndef USE_SIT_FUNCTION |
678 | /* 12 */ { CENDFILE, CENDFILE, CENDFILE, CENDFILE }, /* PEOF */ | 704 | /* 12 */ {CENDFILE, CENDFILE, CENDFILE, CENDFILE}, |
679 | /* 13 */ { CWORD, CWORD, CWORD, CWORD }, /* 0-9A-Za-z */ | 705 | /* PEOF */ |
680 | /* 14 */ { CCTL, CCTL, CCTL, CCTL } /* CTLESC ... */ | 706 | /* 13 */ {CWORD, CWORD, CWORD, CWORD}, |
707 | /* 0-9A-Za-z */ | ||
708 | /* 14 */ {CCTL, CCTL, CCTL, CCTL} | ||
709 | /* CTLESC ... */ | ||
681 | #endif | 710 | #endif |
682 | }; | 711 | }; |
683 | 712 | ||
@@ -687,31 +716,32 @@ static const char S_I_T[][4] = { | |||
687 | 716 | ||
688 | static int SIT(int c, int syntax) | 717 | static int SIT(int c, int syntax) |
689 | { | 718 | { |
690 | static const char spec_symbls[]="\t\n !\"$&'()*-/:;<=>?[\\]`|}~"; | 719 | static const char spec_symbls[] = "\t\n !\"$&'()*-/:;<=>?[\\]`|}~"; |
691 | static const char syntax_index_table [] = { | 720 | static const char syntax_index_table[] = { |
692 | 1, 2, 1, 3, 4, 5, 1, 6, /* "\t\n !\"$&'" */ | 721 | 1, 2, 1, 3, 4, 5, 1, 6, /* "\t\n !\"$&'" */ |
693 | 7, 8, 3, 3, 3, 3, 1, 1, /* "()*-/:;<" */ | 722 | 7, 8, 3, 3, 3, 3, 1, 1, /* "()*-/:;<" */ |
694 | 3, 1, 3, 3, 9, 3,10, 1, /* "=>?[\\]`|" */ | 723 | 3, 1, 3, 3, 9, 3, 10, 1, /* "=>?[\\]`|" */ |
695 | 11,3 }; /* "}~" */ | 724 | 11, 3 |
725 | }; /* "}~" */ | ||
696 | const char *s; | 726 | const char *s; |
697 | int indx; | 727 | int indx; |
698 | 728 | ||
699 | if(c==PEOF) /* 2^8+2 */ | 729 | if (c == PEOF) /* 2^8+2 */ |
700 | return CENDFILE; | 730 | return CENDFILE; |
701 | if(c==PEOA) /* 2^8+1 */ | 731 | if (c == PEOA) /* 2^8+1 */ |
702 | indx = 0; | 732 | indx = 0; |
703 | else if(U_C(c)>=U_C(CTLESC) && U_C(c)<=U_C(CTLQUOTEMARK)) | 733 | else if (U_C(c) >= U_C(CTLESC) && U_C(c) <= U_C(CTLQUOTEMARK)) |
704 | return CCTL; | 734 | return CCTL; |
705 | else { | 735 | else { |
706 | s = strchr(spec_symbls, c); | 736 | s = strchr(spec_symbls, c); |
707 | if(s==0) | 737 | if (s == 0) |
708 | return CWORD; | 738 | return CWORD; |
709 | indx = syntax_index_table[(s-spec_symbls)]; | 739 | indx = syntax_index_table[(s - spec_symbls)]; |
710 | } | 740 | } |
711 | return S_I_T[indx][syntax]; | 741 | return S_I_T[indx][syntax]; |
712 | } | 742 | } |
713 | 743 | ||
714 | #else /* USE_SIT_FUNCTION */ | 744 | #else /* USE_SIT_FUNCTION */ |
715 | 745 | ||
716 | #define SIT(c, syntax) S_I_T[(int)syntax_index_table[((int)c)+SYNBASE]][syntax] | 746 | #define SIT(c, syntax) S_I_T[(int)syntax_index_table[((int)c)+SYNBASE]][syntax] |
717 | 747 | ||
@@ -732,268 +762,270 @@ static int SIT(int c, int syntax) | |||
732 | #define CCTL_CCTL_CCTL_CCTL 14 | 762 | #define CCTL_CCTL_CCTL_CCTL 14 |
733 | 763 | ||
734 | static const char syntax_index_table[258] = { | 764 | static const char syntax_index_table[258] = { |
735 | /* BASESYNTAX_DQSYNTAX_SQSYNTAX_ARISYNTAX */ | 765 | /* BASESYNTAX_DQSYNTAX_SQSYNTAX_ARISYNTAX */ |
736 | /* 0 -130 PEOF */ CENDFILE_CENDFILE_CENDFILE_CENDFILE, | 766 | /* 0 -130 PEOF */ CENDFILE_CENDFILE_CENDFILE_CENDFILE, |
737 | /* 1 -129 PEOA */ CSPCL_CIGN_CIGN_CIGN, | 767 | /* 1 -129 PEOA */ CSPCL_CIGN_CIGN_CIGN, |
738 | /* 2 -128 0xff */ CWORD_CWORD_CWORD_CWORD, | 768 | /* 2 -128 0xff */ CWORD_CWORD_CWORD_CWORD, |
739 | /* 3 -127 */ CCTL_CCTL_CCTL_CCTL, /* CTLQUOTEMARK */ | 769 | /* 3 -127 */ CCTL_CCTL_CCTL_CCTL, |
740 | /* 4 -126 */ CCTL_CCTL_CCTL_CCTL, | 770 | /* CTLQUOTEMARK */ |
741 | /* 5 -125 */ CCTL_CCTL_CCTL_CCTL, | 771 | /* 4 -126 */ CCTL_CCTL_CCTL_CCTL, |
742 | /* 6 -124 */ CCTL_CCTL_CCTL_CCTL, | 772 | /* 5 -125 */ CCTL_CCTL_CCTL_CCTL, |
743 | /* 7 -123 */ CCTL_CCTL_CCTL_CCTL, | 773 | /* 6 -124 */ CCTL_CCTL_CCTL_CCTL, |
744 | /* 8 -122 */ CCTL_CCTL_CCTL_CCTL, | 774 | /* 7 -123 */ CCTL_CCTL_CCTL_CCTL, |
745 | /* 9 -121 */ CCTL_CCTL_CCTL_CCTL, | 775 | /* 8 -122 */ CCTL_CCTL_CCTL_CCTL, |
746 | /* 10 -120 */ CCTL_CCTL_CCTL_CCTL, /* CTLESC */ | 776 | /* 9 -121 */ CCTL_CCTL_CCTL_CCTL, |
747 | /* 11 -119 */ CWORD_CWORD_CWORD_CWORD, | 777 | /* 10 -120 */ CCTL_CCTL_CCTL_CCTL, |
748 | /* 12 -118 */ CWORD_CWORD_CWORD_CWORD, | 778 | /* CTLESC */ |
749 | /* 13 -117 */ CWORD_CWORD_CWORD_CWORD, | 779 | /* 11 -119 */ CWORD_CWORD_CWORD_CWORD, |
750 | /* 14 -116 */ CWORD_CWORD_CWORD_CWORD, | 780 | /* 12 -118 */ CWORD_CWORD_CWORD_CWORD, |
751 | /* 15 -115 */ CWORD_CWORD_CWORD_CWORD, | 781 | /* 13 -117 */ CWORD_CWORD_CWORD_CWORD, |
752 | /* 16 -114 */ CWORD_CWORD_CWORD_CWORD, | 782 | /* 14 -116 */ CWORD_CWORD_CWORD_CWORD, |
753 | /* 17 -113 */ CWORD_CWORD_CWORD_CWORD, | 783 | /* 15 -115 */ CWORD_CWORD_CWORD_CWORD, |
754 | /* 18 -112 */ CWORD_CWORD_CWORD_CWORD, | 784 | /* 16 -114 */ CWORD_CWORD_CWORD_CWORD, |
755 | /* 19 -111 */ CWORD_CWORD_CWORD_CWORD, | 785 | /* 17 -113 */ CWORD_CWORD_CWORD_CWORD, |
756 | /* 20 -110 */ CWORD_CWORD_CWORD_CWORD, | 786 | /* 18 -112 */ CWORD_CWORD_CWORD_CWORD, |
757 | /* 21 -109 */ CWORD_CWORD_CWORD_CWORD, | 787 | /* 19 -111 */ CWORD_CWORD_CWORD_CWORD, |
758 | /* 22 -108 */ CWORD_CWORD_CWORD_CWORD, | 788 | /* 20 -110 */ CWORD_CWORD_CWORD_CWORD, |
759 | /* 23 -107 */ CWORD_CWORD_CWORD_CWORD, | 789 | /* 21 -109 */ CWORD_CWORD_CWORD_CWORD, |
760 | /* 24 -106 */ CWORD_CWORD_CWORD_CWORD, | 790 | /* 22 -108 */ CWORD_CWORD_CWORD_CWORD, |
761 | /* 25 -105 */ CWORD_CWORD_CWORD_CWORD, | 791 | /* 23 -107 */ CWORD_CWORD_CWORD_CWORD, |
762 | /* 26 -104 */ CWORD_CWORD_CWORD_CWORD, | 792 | /* 24 -106 */ CWORD_CWORD_CWORD_CWORD, |
763 | /* 27 -103 */ CWORD_CWORD_CWORD_CWORD, | 793 | /* 25 -105 */ CWORD_CWORD_CWORD_CWORD, |
764 | /* 28 -102 */ CWORD_CWORD_CWORD_CWORD, | 794 | /* 26 -104 */ CWORD_CWORD_CWORD_CWORD, |
765 | /* 29 -101 */ CWORD_CWORD_CWORD_CWORD, | 795 | /* 27 -103 */ CWORD_CWORD_CWORD_CWORD, |
766 | /* 30 -100 */ CWORD_CWORD_CWORD_CWORD, | 796 | /* 28 -102 */ CWORD_CWORD_CWORD_CWORD, |
767 | /* 31 -99 */ CWORD_CWORD_CWORD_CWORD, | 797 | /* 29 -101 */ CWORD_CWORD_CWORD_CWORD, |
768 | /* 32 -98 */ CWORD_CWORD_CWORD_CWORD, | 798 | /* 30 -100 */ CWORD_CWORD_CWORD_CWORD, |
769 | /* 33 -97 */ CWORD_CWORD_CWORD_CWORD, | 799 | /* 31 -99 */ CWORD_CWORD_CWORD_CWORD, |
770 | /* 34 -96 */ CWORD_CWORD_CWORD_CWORD, | 800 | /* 32 -98 */ CWORD_CWORD_CWORD_CWORD, |
771 | /* 35 -95 */ CWORD_CWORD_CWORD_CWORD, | 801 | /* 33 -97 */ CWORD_CWORD_CWORD_CWORD, |
772 | /* 36 -94 */ CWORD_CWORD_CWORD_CWORD, | 802 | /* 34 -96 */ CWORD_CWORD_CWORD_CWORD, |
773 | /* 37 -93 */ CWORD_CWORD_CWORD_CWORD, | 803 | /* 35 -95 */ CWORD_CWORD_CWORD_CWORD, |
774 | /* 38 -92 */ CWORD_CWORD_CWORD_CWORD, | 804 | /* 36 -94 */ CWORD_CWORD_CWORD_CWORD, |
775 | /* 39 -91 */ CWORD_CWORD_CWORD_CWORD, | 805 | /* 37 -93 */ CWORD_CWORD_CWORD_CWORD, |
776 | /* 40 -90 */ CWORD_CWORD_CWORD_CWORD, | 806 | /* 38 -92 */ CWORD_CWORD_CWORD_CWORD, |
777 | /* 41 -89 */ CWORD_CWORD_CWORD_CWORD, | 807 | /* 39 -91 */ CWORD_CWORD_CWORD_CWORD, |
778 | /* 42 -88 */ CWORD_CWORD_CWORD_CWORD, | 808 | /* 40 -90 */ CWORD_CWORD_CWORD_CWORD, |
779 | /* 43 -87 */ CWORD_CWORD_CWORD_CWORD, | 809 | /* 41 -89 */ CWORD_CWORD_CWORD_CWORD, |
780 | /* 44 -86 */ CWORD_CWORD_CWORD_CWORD, | 810 | /* 42 -88 */ CWORD_CWORD_CWORD_CWORD, |
781 | /* 45 -85 */ CWORD_CWORD_CWORD_CWORD, | 811 | /* 43 -87 */ CWORD_CWORD_CWORD_CWORD, |
782 | /* 46 -84 */ CWORD_CWORD_CWORD_CWORD, | 812 | /* 44 -86 */ CWORD_CWORD_CWORD_CWORD, |
783 | /* 47 -83 */ CWORD_CWORD_CWORD_CWORD, | 813 | /* 45 -85 */ CWORD_CWORD_CWORD_CWORD, |
784 | /* 48 -82 */ CWORD_CWORD_CWORD_CWORD, | 814 | /* 46 -84 */ CWORD_CWORD_CWORD_CWORD, |
785 | /* 49 -81 */ CWORD_CWORD_CWORD_CWORD, | 815 | /* 47 -83 */ CWORD_CWORD_CWORD_CWORD, |
786 | /* 50 -80 */ CWORD_CWORD_CWORD_CWORD, | 816 | /* 48 -82 */ CWORD_CWORD_CWORD_CWORD, |
787 | /* 51 -79 */ CWORD_CWORD_CWORD_CWORD, | 817 | /* 49 -81 */ CWORD_CWORD_CWORD_CWORD, |
788 | /* 52 -78 */ CWORD_CWORD_CWORD_CWORD, | 818 | /* 50 -80 */ CWORD_CWORD_CWORD_CWORD, |
789 | /* 53 -77 */ CWORD_CWORD_CWORD_CWORD, | 819 | /* 51 -79 */ CWORD_CWORD_CWORD_CWORD, |
790 | /* 54 -76 */ CWORD_CWORD_CWORD_CWORD, | 820 | /* 52 -78 */ CWORD_CWORD_CWORD_CWORD, |
791 | /* 55 -75 */ CWORD_CWORD_CWORD_CWORD, | 821 | /* 53 -77 */ CWORD_CWORD_CWORD_CWORD, |
792 | /* 56 -74 */ CWORD_CWORD_CWORD_CWORD, | 822 | /* 54 -76 */ CWORD_CWORD_CWORD_CWORD, |
793 | /* 57 -73 */ CWORD_CWORD_CWORD_CWORD, | 823 | /* 55 -75 */ CWORD_CWORD_CWORD_CWORD, |
794 | /* 58 -72 */ CWORD_CWORD_CWORD_CWORD, | 824 | /* 56 -74 */ CWORD_CWORD_CWORD_CWORD, |
795 | /* 59 -71 */ CWORD_CWORD_CWORD_CWORD, | 825 | /* 57 -73 */ CWORD_CWORD_CWORD_CWORD, |
796 | /* 60 -70 */ CWORD_CWORD_CWORD_CWORD, | 826 | /* 58 -72 */ CWORD_CWORD_CWORD_CWORD, |
797 | /* 61 -69 */ CWORD_CWORD_CWORD_CWORD, | 827 | /* 59 -71 */ CWORD_CWORD_CWORD_CWORD, |
798 | /* 62 -68 */ CWORD_CWORD_CWORD_CWORD, | 828 | /* 60 -70 */ CWORD_CWORD_CWORD_CWORD, |
799 | /* 63 -67 */ CWORD_CWORD_CWORD_CWORD, | 829 | /* 61 -69 */ CWORD_CWORD_CWORD_CWORD, |
800 | /* 64 -66 */ CWORD_CWORD_CWORD_CWORD, | 830 | /* 62 -68 */ CWORD_CWORD_CWORD_CWORD, |
801 | /* 65 -65 */ CWORD_CWORD_CWORD_CWORD, | 831 | /* 63 -67 */ CWORD_CWORD_CWORD_CWORD, |
802 | /* 66 -64 */ CWORD_CWORD_CWORD_CWORD, | 832 | /* 64 -66 */ CWORD_CWORD_CWORD_CWORD, |
803 | /* 67 -63 */ CWORD_CWORD_CWORD_CWORD, | 833 | /* 65 -65 */ CWORD_CWORD_CWORD_CWORD, |
804 | /* 68 -62 */ CWORD_CWORD_CWORD_CWORD, | 834 | /* 66 -64 */ CWORD_CWORD_CWORD_CWORD, |
805 | /* 69 -61 */ CWORD_CWORD_CWORD_CWORD, | 835 | /* 67 -63 */ CWORD_CWORD_CWORD_CWORD, |
806 | /* 70 -60 */ CWORD_CWORD_CWORD_CWORD, | 836 | /* 68 -62 */ CWORD_CWORD_CWORD_CWORD, |
807 | /* 71 -59 */ CWORD_CWORD_CWORD_CWORD, | 837 | /* 69 -61 */ CWORD_CWORD_CWORD_CWORD, |
808 | /* 72 -58 */ CWORD_CWORD_CWORD_CWORD, | 838 | /* 70 -60 */ CWORD_CWORD_CWORD_CWORD, |
809 | /* 73 -57 */ CWORD_CWORD_CWORD_CWORD, | 839 | /* 71 -59 */ CWORD_CWORD_CWORD_CWORD, |
810 | /* 74 -56 */ CWORD_CWORD_CWORD_CWORD, | 840 | /* 72 -58 */ CWORD_CWORD_CWORD_CWORD, |
811 | /* 75 -55 */ CWORD_CWORD_CWORD_CWORD, | 841 | /* 73 -57 */ CWORD_CWORD_CWORD_CWORD, |
812 | /* 76 -54 */ CWORD_CWORD_CWORD_CWORD, | 842 | /* 74 -56 */ CWORD_CWORD_CWORD_CWORD, |
813 | /* 77 -53 */ CWORD_CWORD_CWORD_CWORD, | 843 | /* 75 -55 */ CWORD_CWORD_CWORD_CWORD, |
814 | /* 78 -52 */ CWORD_CWORD_CWORD_CWORD, | 844 | /* 76 -54 */ CWORD_CWORD_CWORD_CWORD, |
815 | /* 79 -51 */ CWORD_CWORD_CWORD_CWORD, | 845 | /* 77 -53 */ CWORD_CWORD_CWORD_CWORD, |
816 | /* 80 -50 */ CWORD_CWORD_CWORD_CWORD, | 846 | /* 78 -52 */ CWORD_CWORD_CWORD_CWORD, |
817 | /* 81 -49 */ CWORD_CWORD_CWORD_CWORD, | 847 | /* 79 -51 */ CWORD_CWORD_CWORD_CWORD, |
818 | /* 82 -48 */ CWORD_CWORD_CWORD_CWORD, | 848 | /* 80 -50 */ CWORD_CWORD_CWORD_CWORD, |
819 | /* 83 -47 */ CWORD_CWORD_CWORD_CWORD, | 849 | /* 81 -49 */ CWORD_CWORD_CWORD_CWORD, |
820 | /* 84 -46 */ CWORD_CWORD_CWORD_CWORD, | 850 | /* 82 -48 */ CWORD_CWORD_CWORD_CWORD, |
821 | /* 85 -45 */ CWORD_CWORD_CWORD_CWORD, | 851 | /* 83 -47 */ CWORD_CWORD_CWORD_CWORD, |
822 | /* 86 -44 */ CWORD_CWORD_CWORD_CWORD, | 852 | /* 84 -46 */ CWORD_CWORD_CWORD_CWORD, |
823 | /* 87 -43 */ CWORD_CWORD_CWORD_CWORD, | 853 | /* 85 -45 */ CWORD_CWORD_CWORD_CWORD, |
824 | /* 88 -42 */ CWORD_CWORD_CWORD_CWORD, | 854 | /* 86 -44 */ CWORD_CWORD_CWORD_CWORD, |
825 | /* 89 -41 */ CWORD_CWORD_CWORD_CWORD, | 855 | /* 87 -43 */ CWORD_CWORD_CWORD_CWORD, |
826 | /* 90 -40 */ CWORD_CWORD_CWORD_CWORD, | 856 | /* 88 -42 */ CWORD_CWORD_CWORD_CWORD, |
827 | /* 91 -39 */ CWORD_CWORD_CWORD_CWORD, | 857 | /* 89 -41 */ CWORD_CWORD_CWORD_CWORD, |
828 | /* 92 -38 */ CWORD_CWORD_CWORD_CWORD, | 858 | /* 90 -40 */ CWORD_CWORD_CWORD_CWORD, |
829 | /* 93 -37 */ CWORD_CWORD_CWORD_CWORD, | 859 | /* 91 -39 */ CWORD_CWORD_CWORD_CWORD, |
830 | /* 94 -36 */ CWORD_CWORD_CWORD_CWORD, | 860 | /* 92 -38 */ CWORD_CWORD_CWORD_CWORD, |
831 | /* 95 -35 */ CWORD_CWORD_CWORD_CWORD, | 861 | /* 93 -37 */ CWORD_CWORD_CWORD_CWORD, |
832 | /* 96 -34 */ CWORD_CWORD_CWORD_CWORD, | 862 | /* 94 -36 */ CWORD_CWORD_CWORD_CWORD, |
833 | /* 97 -33 */ CWORD_CWORD_CWORD_CWORD, | 863 | /* 95 -35 */ CWORD_CWORD_CWORD_CWORD, |
834 | /* 98 -32 */ CWORD_CWORD_CWORD_CWORD, | 864 | /* 96 -34 */ CWORD_CWORD_CWORD_CWORD, |
835 | /* 99 -31 */ CWORD_CWORD_CWORD_CWORD, | 865 | /* 97 -33 */ CWORD_CWORD_CWORD_CWORD, |
836 | /* 100 -30 */ CWORD_CWORD_CWORD_CWORD, | 866 | /* 98 -32 */ CWORD_CWORD_CWORD_CWORD, |
837 | /* 101 -29 */ CWORD_CWORD_CWORD_CWORD, | 867 | /* 99 -31 */ CWORD_CWORD_CWORD_CWORD, |
838 | /* 102 -28 */ CWORD_CWORD_CWORD_CWORD, | 868 | /* 100 -30 */ CWORD_CWORD_CWORD_CWORD, |
839 | /* 103 -27 */ CWORD_CWORD_CWORD_CWORD, | 869 | /* 101 -29 */ CWORD_CWORD_CWORD_CWORD, |
840 | /* 104 -26 */ CWORD_CWORD_CWORD_CWORD, | 870 | /* 102 -28 */ CWORD_CWORD_CWORD_CWORD, |
841 | /* 105 -25 */ CWORD_CWORD_CWORD_CWORD, | 871 | /* 103 -27 */ CWORD_CWORD_CWORD_CWORD, |
842 | /* 106 -24 */ CWORD_CWORD_CWORD_CWORD, | 872 | /* 104 -26 */ CWORD_CWORD_CWORD_CWORD, |
843 | /* 107 -23 */ CWORD_CWORD_CWORD_CWORD, | 873 | /* 105 -25 */ CWORD_CWORD_CWORD_CWORD, |
844 | /* 108 -22 */ CWORD_CWORD_CWORD_CWORD, | 874 | /* 106 -24 */ CWORD_CWORD_CWORD_CWORD, |
845 | /* 109 -21 */ CWORD_CWORD_CWORD_CWORD, | 875 | /* 107 -23 */ CWORD_CWORD_CWORD_CWORD, |
846 | /* 110 -20 */ CWORD_CWORD_CWORD_CWORD, | 876 | /* 108 -22 */ CWORD_CWORD_CWORD_CWORD, |
847 | /* 111 -19 */ CWORD_CWORD_CWORD_CWORD, | 877 | /* 109 -21 */ CWORD_CWORD_CWORD_CWORD, |
848 | /* 112 -18 */ CWORD_CWORD_CWORD_CWORD, | 878 | /* 110 -20 */ CWORD_CWORD_CWORD_CWORD, |
849 | /* 113 -17 */ CWORD_CWORD_CWORD_CWORD, | 879 | /* 111 -19 */ CWORD_CWORD_CWORD_CWORD, |
850 | /* 114 -16 */ CWORD_CWORD_CWORD_CWORD, | 880 | /* 112 -18 */ CWORD_CWORD_CWORD_CWORD, |
851 | /* 115 -15 */ CWORD_CWORD_CWORD_CWORD, | 881 | /* 113 -17 */ CWORD_CWORD_CWORD_CWORD, |
852 | /* 116 -14 */ CWORD_CWORD_CWORD_CWORD, | 882 | /* 114 -16 */ CWORD_CWORD_CWORD_CWORD, |
853 | /* 117 -13 */ CWORD_CWORD_CWORD_CWORD, | 883 | /* 115 -15 */ CWORD_CWORD_CWORD_CWORD, |
854 | /* 118 -12 */ CWORD_CWORD_CWORD_CWORD, | 884 | /* 116 -14 */ CWORD_CWORD_CWORD_CWORD, |
855 | /* 119 -11 */ CWORD_CWORD_CWORD_CWORD, | 885 | /* 117 -13 */ CWORD_CWORD_CWORD_CWORD, |
856 | /* 120 -10 */ CWORD_CWORD_CWORD_CWORD, | 886 | /* 118 -12 */ CWORD_CWORD_CWORD_CWORD, |
857 | /* 121 -9 */ CWORD_CWORD_CWORD_CWORD, | 887 | /* 119 -11 */ CWORD_CWORD_CWORD_CWORD, |
858 | /* 122 -8 */ CWORD_CWORD_CWORD_CWORD, | 888 | /* 120 -10 */ CWORD_CWORD_CWORD_CWORD, |
859 | /* 123 -7 */ CWORD_CWORD_CWORD_CWORD, | 889 | /* 121 -9 */ CWORD_CWORD_CWORD_CWORD, |
860 | /* 124 -6 */ CWORD_CWORD_CWORD_CWORD, | 890 | /* 122 -8 */ CWORD_CWORD_CWORD_CWORD, |
861 | /* 125 -5 */ CWORD_CWORD_CWORD_CWORD, | 891 | /* 123 -7 */ CWORD_CWORD_CWORD_CWORD, |
862 | /* 126 -4 */ CWORD_CWORD_CWORD_CWORD, | 892 | /* 124 -6 */ CWORD_CWORD_CWORD_CWORD, |
863 | /* 127 -3 */ CWORD_CWORD_CWORD_CWORD, | 893 | /* 125 -5 */ CWORD_CWORD_CWORD_CWORD, |
864 | /* 128 -2 */ CWORD_CWORD_CWORD_CWORD, | 894 | /* 126 -4 */ CWORD_CWORD_CWORD_CWORD, |
865 | /* 129 -1 */ CWORD_CWORD_CWORD_CWORD, | 895 | /* 127 -3 */ CWORD_CWORD_CWORD_CWORD, |
866 | /* 130 0 */ CWORD_CWORD_CWORD_CWORD, | 896 | /* 128 -2 */ CWORD_CWORD_CWORD_CWORD, |
867 | /* 131 1 */ CWORD_CWORD_CWORD_CWORD, | 897 | /* 129 -1 */ CWORD_CWORD_CWORD_CWORD, |
868 | /* 132 2 */ CWORD_CWORD_CWORD_CWORD, | 898 | /* 130 0 */ CWORD_CWORD_CWORD_CWORD, |
869 | /* 133 3 */ CWORD_CWORD_CWORD_CWORD, | 899 | /* 131 1 */ CWORD_CWORD_CWORD_CWORD, |
870 | /* 134 4 */ CWORD_CWORD_CWORD_CWORD, | 900 | /* 132 2 */ CWORD_CWORD_CWORD_CWORD, |
871 | /* 135 5 */ CWORD_CWORD_CWORD_CWORD, | 901 | /* 133 3 */ CWORD_CWORD_CWORD_CWORD, |
872 | /* 136 6 */ CWORD_CWORD_CWORD_CWORD, | 902 | /* 134 4 */ CWORD_CWORD_CWORD_CWORD, |
873 | /* 137 7 */ CWORD_CWORD_CWORD_CWORD, | 903 | /* 135 5 */ CWORD_CWORD_CWORD_CWORD, |
874 | /* 138 8 */ CWORD_CWORD_CWORD_CWORD, | 904 | /* 136 6 */ CWORD_CWORD_CWORD_CWORD, |
875 | /* 139 9 "\t" */ CSPCL_CWORD_CWORD_CWORD, | 905 | /* 137 7 */ CWORD_CWORD_CWORD_CWORD, |
876 | /* 140 10 "\n" */ CNL_CNL_CNL_CNL, | 906 | /* 138 8 */ CWORD_CWORD_CWORD_CWORD, |
877 | /* 141 11 */ CWORD_CWORD_CWORD_CWORD, | 907 | /* 139 9 "\t" */ CSPCL_CWORD_CWORD_CWORD, |
878 | /* 142 12 */ CWORD_CWORD_CWORD_CWORD, | 908 | /* 140 10 "\n" */ CNL_CNL_CNL_CNL, |
879 | /* 143 13 */ CWORD_CWORD_CWORD_CWORD, | 909 | /* 141 11 */ CWORD_CWORD_CWORD_CWORD, |
880 | /* 144 14 */ CWORD_CWORD_CWORD_CWORD, | 910 | /* 142 12 */ CWORD_CWORD_CWORD_CWORD, |
881 | /* 145 15 */ CWORD_CWORD_CWORD_CWORD, | 911 | /* 143 13 */ CWORD_CWORD_CWORD_CWORD, |
882 | /* 146 16 */ CWORD_CWORD_CWORD_CWORD, | 912 | /* 144 14 */ CWORD_CWORD_CWORD_CWORD, |
883 | /* 147 17 */ CWORD_CWORD_CWORD_CWORD, | 913 | /* 145 15 */ CWORD_CWORD_CWORD_CWORD, |
884 | /* 148 18 */ CWORD_CWORD_CWORD_CWORD, | 914 | /* 146 16 */ CWORD_CWORD_CWORD_CWORD, |
885 | /* 149 19 */ CWORD_CWORD_CWORD_CWORD, | 915 | /* 147 17 */ CWORD_CWORD_CWORD_CWORD, |
886 | /* 150 20 */ CWORD_CWORD_CWORD_CWORD, | 916 | /* 148 18 */ CWORD_CWORD_CWORD_CWORD, |
887 | /* 151 21 */ CWORD_CWORD_CWORD_CWORD, | 917 | /* 149 19 */ CWORD_CWORD_CWORD_CWORD, |
888 | /* 152 22 */ CWORD_CWORD_CWORD_CWORD, | 918 | /* 150 20 */ CWORD_CWORD_CWORD_CWORD, |
889 | /* 153 23 */ CWORD_CWORD_CWORD_CWORD, | 919 | /* 151 21 */ CWORD_CWORD_CWORD_CWORD, |
890 | /* 154 24 */ CWORD_CWORD_CWORD_CWORD, | 920 | /* 152 22 */ CWORD_CWORD_CWORD_CWORD, |
891 | /* 155 25 */ CWORD_CWORD_CWORD_CWORD, | 921 | /* 153 23 */ CWORD_CWORD_CWORD_CWORD, |
892 | /* 156 26 */ CWORD_CWORD_CWORD_CWORD, | 922 | /* 154 24 */ CWORD_CWORD_CWORD_CWORD, |
893 | /* 157 27 */ CWORD_CWORD_CWORD_CWORD, | 923 | /* 155 25 */ CWORD_CWORD_CWORD_CWORD, |
894 | /* 158 28 */ CWORD_CWORD_CWORD_CWORD, | 924 | /* 156 26 */ CWORD_CWORD_CWORD_CWORD, |
895 | /* 159 29 */ CWORD_CWORD_CWORD_CWORD, | 925 | /* 157 27 */ CWORD_CWORD_CWORD_CWORD, |
896 | /* 160 30 */ CWORD_CWORD_CWORD_CWORD, | 926 | /* 158 28 */ CWORD_CWORD_CWORD_CWORD, |
897 | /* 161 31 */ CWORD_CWORD_CWORD_CWORD, | 927 | /* 159 29 */ CWORD_CWORD_CWORD_CWORD, |
898 | /* 162 32 " " */ CSPCL_CWORD_CWORD_CWORD, | 928 | /* 160 30 */ CWORD_CWORD_CWORD_CWORD, |
899 | /* 163 33 "!" */ CWORD_CCTL_CCTL_CWORD, | 929 | /* 161 31 */ CWORD_CWORD_CWORD_CWORD, |
900 | /* 164 34 """ */ CDQUOTE_CENDQUOTE_CWORD_CDQUOTE, | 930 | /* 162 32 " " */ CSPCL_CWORD_CWORD_CWORD, |
901 | /* 165 35 "#" */ CWORD_CWORD_CWORD_CWORD, | 931 | /* 163 33 "!" */ CWORD_CCTL_CCTL_CWORD, |
902 | /* 166 36 "$" */ CVAR_CVAR_CWORD_CVAR, | 932 | /* 164 34 """ */ CDQUOTE_CENDQUOTE_CWORD_CDQUOTE, |
903 | /* 167 37 "%" */ CWORD_CWORD_CWORD_CWORD, | 933 | /* 165 35 "#" */ CWORD_CWORD_CWORD_CWORD, |
904 | /* 168 38 "&" */ CSPCL_CWORD_CWORD_CWORD, | 934 | /* 166 36 "$" */ CVAR_CVAR_CWORD_CVAR, |
905 | /* 169 39 "'" */ CSQUOTE_CWORD_CENDQUOTE_CSQUOTE, | 935 | /* 167 37 "%" */ CWORD_CWORD_CWORD_CWORD, |
906 | /* 170 40 "(" */ CSPCL_CWORD_CWORD_CLP, | 936 | /* 168 38 "&" */ CSPCL_CWORD_CWORD_CWORD, |
907 | /* 171 41 ")" */ CSPCL_CWORD_CWORD_CRP, | 937 | /* 169 39 "'" */ CSQUOTE_CWORD_CENDQUOTE_CSQUOTE, |
908 | /* 172 42 "*" */ CWORD_CCTL_CCTL_CWORD, | 938 | /* 170 40 "(" */ CSPCL_CWORD_CWORD_CLP, |
909 | /* 173 43 "+" */ CWORD_CWORD_CWORD_CWORD, | 939 | /* 171 41 ")" */ CSPCL_CWORD_CWORD_CRP, |
910 | /* 174 44 "," */ CWORD_CWORD_CWORD_CWORD, | 940 | /* 172 42 "*" */ CWORD_CCTL_CCTL_CWORD, |
911 | /* 175 45 "-" */ CWORD_CCTL_CCTL_CWORD, | 941 | /* 173 43 "+" */ CWORD_CWORD_CWORD_CWORD, |
912 | /* 176 46 "." */ CWORD_CWORD_CWORD_CWORD, | 942 | /* 174 44 "," */ CWORD_CWORD_CWORD_CWORD, |
913 | /* 177 47 "/" */ CWORD_CCTL_CCTL_CWORD, | 943 | /* 175 45 "-" */ CWORD_CCTL_CCTL_CWORD, |
914 | /* 178 48 "0" */ CWORD_CWORD_CWORD_CWORD, | 944 | /* 176 46 "." */ CWORD_CWORD_CWORD_CWORD, |
915 | /* 179 49 "1" */ CWORD_CWORD_CWORD_CWORD, | 945 | /* 177 47 "/" */ CWORD_CCTL_CCTL_CWORD, |
916 | /* 180 50 "2" */ CWORD_CWORD_CWORD_CWORD, | 946 | /* 178 48 "0" */ CWORD_CWORD_CWORD_CWORD, |
917 | /* 181 51 "3" */ CWORD_CWORD_CWORD_CWORD, | 947 | /* 179 49 "1" */ CWORD_CWORD_CWORD_CWORD, |
918 | /* 182 52 "4" */ CWORD_CWORD_CWORD_CWORD, | 948 | /* 180 50 "2" */ CWORD_CWORD_CWORD_CWORD, |
919 | /* 183 53 "5" */ CWORD_CWORD_CWORD_CWORD, | 949 | /* 181 51 "3" */ CWORD_CWORD_CWORD_CWORD, |
920 | /* 184 54 "6" */ CWORD_CWORD_CWORD_CWORD, | 950 | /* 182 52 "4" */ CWORD_CWORD_CWORD_CWORD, |
921 | /* 185 55 "7" */ CWORD_CWORD_CWORD_CWORD, | 951 | /* 183 53 "5" */ CWORD_CWORD_CWORD_CWORD, |
922 | /* 186 56 "8" */ CWORD_CWORD_CWORD_CWORD, | 952 | /* 184 54 "6" */ CWORD_CWORD_CWORD_CWORD, |
923 | /* 187 57 "9" */ CWORD_CWORD_CWORD_CWORD, | 953 | /* 185 55 "7" */ CWORD_CWORD_CWORD_CWORD, |
924 | /* 188 58 ":" */ CWORD_CCTL_CCTL_CWORD, | 954 | /* 186 56 "8" */ CWORD_CWORD_CWORD_CWORD, |
925 | /* 189 59 ";" */ CSPCL_CWORD_CWORD_CWORD, | 955 | /* 187 57 "9" */ CWORD_CWORD_CWORD_CWORD, |
926 | /* 190 60 "<" */ CSPCL_CWORD_CWORD_CWORD, | 956 | /* 188 58 ":" */ CWORD_CCTL_CCTL_CWORD, |
927 | /* 191 61 "=" */ CWORD_CCTL_CCTL_CWORD, | 957 | /* 189 59 ";" */ CSPCL_CWORD_CWORD_CWORD, |
928 | /* 192 62 ">" */ CSPCL_CWORD_CWORD_CWORD, | 958 | /* 190 60 "<" */ CSPCL_CWORD_CWORD_CWORD, |
929 | /* 193 63 "?" */ CWORD_CCTL_CCTL_CWORD, | 959 | /* 191 61 "=" */ CWORD_CCTL_CCTL_CWORD, |
930 | /* 194 64 "@" */ CWORD_CWORD_CWORD_CWORD, | 960 | /* 192 62 ">" */ CSPCL_CWORD_CWORD_CWORD, |
931 | /* 195 65 "A" */ CWORD_CWORD_CWORD_CWORD, | 961 | /* 193 63 "?" */ CWORD_CCTL_CCTL_CWORD, |
932 | /* 196 66 "B" */ CWORD_CWORD_CWORD_CWORD, | 962 | /* 194 64 "@" */ CWORD_CWORD_CWORD_CWORD, |
933 | /* 197 67 "C" */ CWORD_CWORD_CWORD_CWORD, | 963 | /* 195 65 "A" */ CWORD_CWORD_CWORD_CWORD, |
934 | /* 198 68 "D" */ CWORD_CWORD_CWORD_CWORD, | 964 | /* 196 66 "B" */ CWORD_CWORD_CWORD_CWORD, |
935 | /* 199 69 "E" */ CWORD_CWORD_CWORD_CWORD, | 965 | /* 197 67 "C" */ CWORD_CWORD_CWORD_CWORD, |
936 | /* 200 70 "F" */ CWORD_CWORD_CWORD_CWORD, | 966 | /* 198 68 "D" */ CWORD_CWORD_CWORD_CWORD, |
937 | /* 201 71 "G" */ CWORD_CWORD_CWORD_CWORD, | 967 | /* 199 69 "E" */ CWORD_CWORD_CWORD_CWORD, |
938 | /* 202 72 "H" */ CWORD_CWORD_CWORD_CWORD, | 968 | /* 200 70 "F" */ CWORD_CWORD_CWORD_CWORD, |
939 | /* 203 73 "I" */ CWORD_CWORD_CWORD_CWORD, | 969 | /* 201 71 "G" */ CWORD_CWORD_CWORD_CWORD, |
940 | /* 204 74 "J" */ CWORD_CWORD_CWORD_CWORD, | 970 | /* 202 72 "H" */ CWORD_CWORD_CWORD_CWORD, |
941 | /* 205 75 "K" */ CWORD_CWORD_CWORD_CWORD, | 971 | /* 203 73 "I" */ CWORD_CWORD_CWORD_CWORD, |
942 | /* 206 76 "L" */ CWORD_CWORD_CWORD_CWORD, | 972 | /* 204 74 "J" */ CWORD_CWORD_CWORD_CWORD, |
943 | /* 207 77 "M" */ CWORD_CWORD_CWORD_CWORD, | 973 | /* 205 75 "K" */ CWORD_CWORD_CWORD_CWORD, |
944 | /* 208 78 "N" */ CWORD_CWORD_CWORD_CWORD, | 974 | /* 206 76 "L" */ CWORD_CWORD_CWORD_CWORD, |
945 | /* 209 79 "O" */ CWORD_CWORD_CWORD_CWORD, | 975 | /* 207 77 "M" */ CWORD_CWORD_CWORD_CWORD, |
946 | /* 210 80 "P" */ CWORD_CWORD_CWORD_CWORD, | 976 | /* 208 78 "N" */ CWORD_CWORD_CWORD_CWORD, |
947 | /* 211 81 "Q" */ CWORD_CWORD_CWORD_CWORD, | 977 | /* 209 79 "O" */ CWORD_CWORD_CWORD_CWORD, |
948 | /* 212 82 "R" */ CWORD_CWORD_CWORD_CWORD, | 978 | /* 210 80 "P" */ CWORD_CWORD_CWORD_CWORD, |
949 | /* 213 83 "S" */ CWORD_CWORD_CWORD_CWORD, | 979 | /* 211 81 "Q" */ CWORD_CWORD_CWORD_CWORD, |
950 | /* 214 84 "T" */ CWORD_CWORD_CWORD_CWORD, | 980 | /* 212 82 "R" */ CWORD_CWORD_CWORD_CWORD, |
951 | /* 215 85 "U" */ CWORD_CWORD_CWORD_CWORD, | 981 | /* 213 83 "S" */ CWORD_CWORD_CWORD_CWORD, |
952 | /* 216 86 "V" */ CWORD_CWORD_CWORD_CWORD, | 982 | /* 214 84 "T" */ CWORD_CWORD_CWORD_CWORD, |
953 | /* 217 87 "W" */ CWORD_CWORD_CWORD_CWORD, | 983 | /* 215 85 "U" */ CWORD_CWORD_CWORD_CWORD, |
954 | /* 218 88 "X" */ CWORD_CWORD_CWORD_CWORD, | 984 | /* 216 86 "V" */ CWORD_CWORD_CWORD_CWORD, |
955 | /* 219 89 "Y" */ CWORD_CWORD_CWORD_CWORD, | 985 | /* 217 87 "W" */ CWORD_CWORD_CWORD_CWORD, |
956 | /* 220 90 "Z" */ CWORD_CWORD_CWORD_CWORD, | 986 | /* 218 88 "X" */ CWORD_CWORD_CWORD_CWORD, |
957 | /* 221 91 "[" */ CWORD_CCTL_CCTL_CWORD, | 987 | /* 219 89 "Y" */ CWORD_CWORD_CWORD_CWORD, |
958 | /* 222 92 "\" */ CBACK_CBACK_CCTL_CBACK, | 988 | /* 220 90 "Z" */ CWORD_CWORD_CWORD_CWORD, |
959 | /* 223 93 "]" */ CWORD_CCTL_CCTL_CWORD, | 989 | /* 221 91 "[" */ CWORD_CCTL_CCTL_CWORD, |
960 | /* 224 94 "^" */ CWORD_CWORD_CWORD_CWORD, | 990 | /* 222 92 "\" */ CBACK_CBACK_CCTL_CBACK, |
961 | /* 225 95 "_" */ CWORD_CWORD_CWORD_CWORD, | 991 | /* 223 93 "]" */ CWORD_CCTL_CCTL_CWORD, |
962 | /* 226 96 "`" */ CBQUOTE_CBQUOTE_CWORD_CBQUOTE, | 992 | /* 224 94 "^" */ CWORD_CWORD_CWORD_CWORD, |
963 | /* 227 97 "a" */ CWORD_CWORD_CWORD_CWORD, | 993 | /* 225 95 "_" */ CWORD_CWORD_CWORD_CWORD, |
964 | /* 228 98 "b" */ CWORD_CWORD_CWORD_CWORD, | 994 | /* 226 96 "`" */ CBQUOTE_CBQUOTE_CWORD_CBQUOTE, |
965 | /* 229 99 "c" */ CWORD_CWORD_CWORD_CWORD, | 995 | /* 227 97 "a" */ CWORD_CWORD_CWORD_CWORD, |
966 | /* 230 100 "d" */ CWORD_CWORD_CWORD_CWORD, | 996 | /* 228 98 "b" */ CWORD_CWORD_CWORD_CWORD, |
967 | /* 231 101 "e" */ CWORD_CWORD_CWORD_CWORD, | 997 | /* 229 99 "c" */ CWORD_CWORD_CWORD_CWORD, |
968 | /* 232 102 "f" */ CWORD_CWORD_CWORD_CWORD, | 998 | /* 230 100 "d" */ CWORD_CWORD_CWORD_CWORD, |
969 | /* 233 103 "g" */ CWORD_CWORD_CWORD_CWORD, | 999 | /* 231 101 "e" */ CWORD_CWORD_CWORD_CWORD, |
970 | /* 234 104 "h" */ CWORD_CWORD_CWORD_CWORD, | 1000 | /* 232 102 "f" */ CWORD_CWORD_CWORD_CWORD, |
971 | /* 235 105 "i" */ CWORD_CWORD_CWORD_CWORD, | 1001 | /* 233 103 "g" */ CWORD_CWORD_CWORD_CWORD, |
972 | /* 236 106 "j" */ CWORD_CWORD_CWORD_CWORD, | 1002 | /* 234 104 "h" */ CWORD_CWORD_CWORD_CWORD, |
973 | /* 237 107 "k" */ CWORD_CWORD_CWORD_CWORD, | 1003 | /* 235 105 "i" */ CWORD_CWORD_CWORD_CWORD, |
974 | /* 238 108 "l" */ CWORD_CWORD_CWORD_CWORD, | 1004 | /* 236 106 "j" */ CWORD_CWORD_CWORD_CWORD, |
975 | /* 239 109 "m" */ CWORD_CWORD_CWORD_CWORD, | 1005 | /* 237 107 "k" */ CWORD_CWORD_CWORD_CWORD, |
976 | /* 240 110 "n" */ CWORD_CWORD_CWORD_CWORD, | 1006 | /* 238 108 "l" */ CWORD_CWORD_CWORD_CWORD, |
977 | /* 241 111 "o" */ CWORD_CWORD_CWORD_CWORD, | 1007 | /* 239 109 "m" */ CWORD_CWORD_CWORD_CWORD, |
978 | /* 242 112 "p" */ CWORD_CWORD_CWORD_CWORD, | 1008 | /* 240 110 "n" */ CWORD_CWORD_CWORD_CWORD, |
979 | /* 243 113 "q" */ CWORD_CWORD_CWORD_CWORD, | 1009 | /* 241 111 "o" */ CWORD_CWORD_CWORD_CWORD, |
980 | /* 244 114 "r" */ CWORD_CWORD_CWORD_CWORD, | 1010 | /* 242 112 "p" */ CWORD_CWORD_CWORD_CWORD, |
981 | /* 245 115 "s" */ CWORD_CWORD_CWORD_CWORD, | 1011 | /* 243 113 "q" */ CWORD_CWORD_CWORD_CWORD, |
982 | /* 246 116 "t" */ CWORD_CWORD_CWORD_CWORD, | 1012 | /* 244 114 "r" */ CWORD_CWORD_CWORD_CWORD, |
983 | /* 247 117 "u" */ CWORD_CWORD_CWORD_CWORD, | 1013 | /* 245 115 "s" */ CWORD_CWORD_CWORD_CWORD, |
984 | /* 248 118 "v" */ CWORD_CWORD_CWORD_CWORD, | 1014 | /* 246 116 "t" */ CWORD_CWORD_CWORD_CWORD, |
985 | /* 249 119 "w" */ CWORD_CWORD_CWORD_CWORD, | 1015 | /* 247 117 "u" */ CWORD_CWORD_CWORD_CWORD, |
986 | /* 250 120 "x" */ CWORD_CWORD_CWORD_CWORD, | 1016 | /* 248 118 "v" */ CWORD_CWORD_CWORD_CWORD, |
987 | /* 251 121 "y" */ CWORD_CWORD_CWORD_CWORD, | 1017 | /* 249 119 "w" */ CWORD_CWORD_CWORD_CWORD, |
988 | /* 252 122 "z" */ CWORD_CWORD_CWORD_CWORD, | 1018 | /* 250 120 "x" */ CWORD_CWORD_CWORD_CWORD, |
989 | /* 253 123 "{" */ CWORD_CWORD_CWORD_CWORD, | 1019 | /* 251 121 "y" */ CWORD_CWORD_CWORD_CWORD, |
990 | /* 254 124 "|" */ CSPCL_CWORD_CWORD_CWORD, | 1020 | /* 252 122 "z" */ CWORD_CWORD_CWORD_CWORD, |
991 | /* 255 125 "}" */ CENDVAR_CENDVAR_CWORD_CENDVAR, | 1021 | /* 253 123 "{" */ CWORD_CWORD_CWORD_CWORD, |
992 | /* 256 126 "~" */ CWORD_CCTL_CCTL_CWORD, | 1022 | /* 254 124 "|" */ CSPCL_CWORD_CWORD_CWORD, |
993 | /* 257 127 */ CWORD_CWORD_CWORD_CWORD, | 1023 | /* 255 125 "}" */ CENDVAR_CENDVAR_CWORD_CENDVAR, |
1024 | /* 256 126 "~" */ CWORD_CCTL_CCTL_CWORD, | ||
1025 | /* 257 127 */ CWORD_CWORD_CWORD_CWORD, | ||
994 | }; | 1026 | }; |
995 | 1027 | ||
996 | #endif /* USE_SIT_FUNCTION */ | 1028 | #endif /* USE_SIT_FUNCTION */ |
997 | 1029 | ||
998 | 1030 | ||
999 | /* first char is indicating which tokens mark the end of a list */ | 1031 | /* first char is indicating which tokens mark the end of a list */ |
@@ -1036,20 +1068,20 @@ static const char *tokname(int tok) | |||
1036 | { | 1068 | { |
1037 | static char buf[16]; | 1069 | static char buf[16]; |
1038 | 1070 | ||
1039 | if(tok>=TSEMI) | 1071 | if (tok >= TSEMI) |
1040 | buf[0] = '"'; | 1072 | buf[0] = '"'; |
1041 | sprintf(buf+(tok>=TSEMI), "%s%c", | 1073 | sprintf(buf + (tok >= TSEMI), "%s%c", |
1042 | tokname_array[tok]+1, (tok>=TSEMI ? '"' : 0)); | 1074 | tokname_array[tok] + 1, (tok >= TSEMI ? '"' : 0)); |
1043 | return buf; | 1075 | return buf; |
1044 | } | 1076 | } |
1045 | 1077 | ||
1046 | static int plinno = 1; /* input line number */ | 1078 | static int plinno = 1; /* input line number */ |
1047 | 1079 | ||
1048 | static int parselleft; /* copy of parsefile->lleft */ | 1080 | static int parselleft; /* copy of parsefile->lleft */ |
1049 | 1081 | ||
1050 | static struct parsefile basepf; /* top level input file */ | 1082 | static struct parsefile basepf; /* top level input file */ |
1051 | static char basebuf[BUFSIZ]; /* buffer for top level input file */ | 1083 | static char basebuf[BUFSIZ]; /* buffer for top level input file */ |
1052 | static struct parsefile *parsefile = &basepf; /* current input file */ | 1084 | static struct parsefile *parsefile = &basepf; /* current input file */ |
1053 | 1085 | ||
1054 | /* | 1086 | /* |
1055 | * NEOF is returned by parsecmd when it encounters an end of file. It | 1087 | * NEOF is returned by parsecmd when it encounters an end of file. It |
@@ -1057,31 +1089,32 @@ static struct parsefile *parsefile = &basepf; /* current input file */ | |||
1057 | * happens to be handy. | 1089 | * happens to be handy. |
1058 | */ | 1090 | */ |
1059 | 1091 | ||
1060 | static int tokpushback; /* last token pushed back */ | 1092 | static int tokpushback; /* last token pushed back */ |
1093 | |||
1061 | #define NEOF ((union node *)&tokpushback) | 1094 | #define NEOF ((union node *)&tokpushback) |
1062 | static int checkkwd; /* 1 == check for kwds, 2 == also eat newlines */ | 1095 | static int checkkwd; /* 1 == check for kwds, 2 == also eat newlines */ |
1063 | 1096 | ||
1064 | 1097 | ||
1065 | static void error (const char *, ...) __attribute__((__noreturn__)); | 1098 | static void error(const char *, ...) __attribute__ ((__noreturn__)); |
1066 | static void exerror (int, const char *, ...) __attribute__((__noreturn__)); | 1099 | static void exerror(int, const char *, ...) __attribute__ ((__noreturn__)); |
1067 | static void shellexec (char **, char **, const char *, int) | 1100 | static void shellexec(char **, char **, const char *, int) |
1068 | __attribute__((noreturn)); | 1101 | __attribute__ ((noreturn)); |
1069 | static void exitshell (int) __attribute__((noreturn)); | 1102 | static void exitshell(int) __attribute__ ((noreturn)); |
1070 | 1103 | ||
1071 | static int goodname(const char *); | 1104 | static int goodname(const char *); |
1072 | static void ignoresig (int); | 1105 | static void ignoresig(int); |
1073 | static void onsig (int); | 1106 | static void onsig(int); |
1074 | static void dotrap (void); | 1107 | static void dotrap(void); |
1075 | static int decode_signal (const char *, int); | 1108 | static int decode_signal(const char *, int); |
1076 | 1109 | ||
1077 | static void shprocvar(void); | 1110 | static void shprocvar(void); |
1078 | static void deletefuncs(void); | 1111 | static void deletefuncs(void); |
1079 | static void setparam (char **); | 1112 | static void setparam(char **); |
1080 | static void freeparam (volatile struct shparam *); | 1113 | static void freeparam(volatile struct shparam *); |
1081 | 1114 | ||
1082 | static void find_command (const char *, struct cmdentry *, int, const char *); | 1115 | static void find_command(const char *, struct cmdentry *, int, const char *); |
1083 | 1116 | ||
1084 | static inline void hashcd (void); | 1117 | static inline void hashcd(void); |
1085 | 1118 | ||
1086 | /* reasons for skipping commands (see comment on breakcmd routine) */ | 1119 | /* reasons for skipping commands (see comment on breakcmd routine) */ |
1087 | #define SKIPBREAK 1 | 1120 | #define SKIPBREAK 1 |
@@ -1090,76 +1123,76 @@ static inline void hashcd (void); | |||
1090 | #define SKIPFILE 4 | 1123 | #define SKIPFILE 4 |
1091 | 1124 | ||
1092 | /* values of cmdtype */ | 1125 | /* values of cmdtype */ |
1093 | #define CMDUNKNOWN -1 /* no entry in table for command */ | 1126 | #define CMDUNKNOWN -1 /* no entry in table for command */ |
1094 | #define CMDNORMAL 0 /* command is an executable program */ | 1127 | #define CMDNORMAL 0 /* command is an executable program */ |
1095 | #define CMDBUILTIN 1 /* command is a shell builtin */ | 1128 | #define CMDBUILTIN 1 /* command is a shell builtin */ |
1096 | #define CMDFUNCTION 2 /* command is a shell function */ | 1129 | #define CMDFUNCTION 2 /* command is a shell function */ |
1097 | 1130 | ||
1098 | #define DO_ERR 1 /* find_command prints errors */ | 1131 | #define DO_ERR 1 /* find_command prints errors */ |
1099 | #define DO_ABS 2 /* find_command checks absolute paths */ | 1132 | #define DO_ABS 2 /* find_command checks absolute paths */ |
1100 | #define DO_NOFUN 4 /* find_command ignores functions */ | 1133 | #define DO_NOFUN 4 /* find_command ignores functions */ |
1101 | #define DO_BRUTE 8 /* find_command ignores hash table */ | 1134 | #define DO_BRUTE 8 /* find_command ignores hash table */ |
1102 | 1135 | ||
1103 | /* | 1136 | /* |
1104 | * Shell variables. | 1137 | * Shell variables. |
1105 | */ | 1138 | */ |
1106 | 1139 | ||
1107 | /* flags */ | 1140 | /* flags */ |
1108 | #define VEXPORT 0x01 /* variable is exported */ | 1141 | #define VEXPORT 0x01 /* variable is exported */ |
1109 | #define VREADONLY 0x02 /* variable cannot be modified */ | 1142 | #define VREADONLY 0x02 /* variable cannot be modified */ |
1110 | #define VSTRFIXED 0x04 /* variable struct is staticly allocated */ | 1143 | #define VSTRFIXED 0x04 /* variable struct is staticly allocated */ |
1111 | #define VTEXTFIXED 0x08 /* text is staticly allocated */ | 1144 | #define VTEXTFIXED 0x08 /* text is staticly allocated */ |
1112 | #define VSTACK 0x10 /* text is allocated on the stack */ | 1145 | #define VSTACK 0x10 /* text is allocated on the stack */ |
1113 | #define VUNSET 0x20 /* the variable is not set */ | 1146 | #define VUNSET 0x20 /* the variable is not set */ |
1114 | #define VNOFUNC 0x40 /* don't call the callback function */ | 1147 | #define VNOFUNC 0x40 /* don't call the callback function */ |
1115 | 1148 | ||
1116 | 1149 | ||
1117 | struct var { | 1150 | struct var { |
1118 | struct var *next; /* next entry in hash list */ | 1151 | struct var *next; /* next entry in hash list */ |
1119 | int flags; /* flags are defined above */ | 1152 | int flags; /* flags are defined above */ |
1120 | char *text; /* name=value */ | 1153 | char *text; /* name=value */ |
1121 | void (*func) (const char *); | 1154 | void (*func) (const char *); |
1122 | /* function to be called when */ | 1155 | /* function to be called when */ |
1123 | /* the variable gets set/unset */ | 1156 | /* the variable gets set/unset */ |
1124 | }; | 1157 | }; |
1125 | 1158 | ||
1126 | struct localvar { | 1159 | struct localvar { |
1127 | struct localvar *next; /* next local variable in list */ | 1160 | struct localvar *next; /* next local variable in list */ |
1128 | struct var *vp; /* the variable that was made local */ | 1161 | struct var *vp; /* the variable that was made local */ |
1129 | int flags; /* saved flags */ | 1162 | int flags; /* saved flags */ |
1130 | char *text; /* saved text */ | 1163 | char *text; /* saved text */ |
1131 | }; | 1164 | }; |
1132 | 1165 | ||
1133 | 1166 | ||
1134 | #if defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN) | 1167 | #if defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN) |
1135 | #define rmescapes(p) _rmescapes((p), 0) | 1168 | #define rmescapes(p) _rmescapes((p), 0) |
1136 | static char *_rmescapes (char *, int); | 1169 | static char *_rmescapes(char *, int); |
1137 | #else | 1170 | #else |
1138 | static void rmescapes (char *); | 1171 | static void rmescapes(char *); |
1139 | #endif | 1172 | #endif |
1140 | 1173 | ||
1141 | static int casematch (union node *, const char *); | 1174 | static int casematch(union node *, const char *); |
1142 | static void clearredir(void); | 1175 | static void clearredir(void); |
1143 | static void popstring(void); | 1176 | static void popstring(void); |
1144 | static void readcmdfile (const char *); | 1177 | static void readcmdfile(const char *); |
1145 | 1178 | ||
1146 | static int number (const char *); | 1179 | static int number(const char *); |
1147 | static int is_number (const char *, int *num); | 1180 | static int is_number(const char *, int *num); |
1148 | static char *single_quote (const char *); | 1181 | static char *single_quote(const char *); |
1149 | static int nextopt (const char *); | 1182 | static int nextopt(const char *); |
1150 | 1183 | ||
1151 | static void redirect (union node *, int); | 1184 | static void redirect(union node *, int); |
1152 | static void popredir (void); | 1185 | static void popredir(void); |
1153 | static int dup_as_newfd (int, int); | 1186 | static int dup_as_newfd(int, int); |
1154 | 1187 | ||
1155 | static void changepath(const char *newval); | 1188 | static void changepath(const char *newval); |
1156 | static void getoptsreset(const char *value); | 1189 | static void getoptsreset(const char *value); |
1157 | 1190 | ||
1158 | 1191 | ||
1159 | static int parsenleft; /* copy of parsefile->nleft */ | 1192 | static int parsenleft; /* copy of parsefile->nleft */ |
1160 | static char *parsenextc; /* copy of parsefile->nextc */ | 1193 | static char *parsenextc; /* copy of parsefile->nextc */ |
1161 | static int rootpid; /* pid of main shell */ | 1194 | static int rootpid; /* pid of main shell */ |
1162 | static int rootshell; /* true if we aren't a child of the main shell */ | 1195 | static int rootshell; /* true if we aren't a child of the main shell */ |
1163 | 1196 | ||
1164 | static const char spcstr[] = " "; | 1197 | static const char spcstr[] = " "; |
1165 | static const char snlfmt[] = "%s\n"; | 1198 | static const char snlfmt[] = "%s\n"; |
@@ -1176,6 +1209,7 @@ static struct var vpath; | |||
1176 | static struct var vps1; | 1209 | static struct var vps1; |
1177 | static struct var vps2; | 1210 | static struct var vps2; |
1178 | static struct var voptind; | 1211 | static struct var voptind; |
1212 | |||
1179 | #ifdef CONFIG_LOCALE_SUPPORT | 1213 | #ifdef CONFIG_LOCALE_SUPPORT |
1180 | static struct var vlc_all; | 1214 | static struct var vlc_all; |
1181 | static struct var vlc_ctype; | 1215 | static struct var vlc_ctype; |
@@ -1194,6 +1228,7 @@ static const char defpathvar[] = | |||
1194 | 1228 | ||
1195 | #ifdef IFS_BROKEN | 1229 | #ifdef IFS_BROKEN |
1196 | static const char defifsvar[] = "IFS= \t\n"; | 1230 | static const char defifsvar[] = "IFS= \t\n"; |
1231 | |||
1197 | #define defifs (defifsvar + 4) | 1232 | #define defifs (defifsvar + 4) |
1198 | #else | 1233 | #else |
1199 | static const char defifs[] = " \t\n"; | 1234 | static const char defifs[] = " \t\n"; |
@@ -1201,33 +1236,33 @@ static const char defifs[] = " \t\n"; | |||
1201 | 1236 | ||
1202 | static const struct varinit varinit[] = { | 1237 | static const struct varinit varinit[] = { |
1203 | #ifdef IFS_BROKEN | 1238 | #ifdef IFS_BROKEN |
1204 | { &vifs, VSTRFIXED|VTEXTFIXED, defifsvar, | 1239 | {&vifs, VSTRFIXED | VTEXTFIXED, defifsvar, |
1205 | #else | 1240 | #else |
1206 | { &vifs, VSTRFIXED|VTEXTFIXED|VUNSET, "IFS=", | 1241 | {&vifs, VSTRFIXED | VTEXTFIXED | VUNSET, "IFS=", |
1207 | #endif | 1242 | #endif |
1208 | NULL }, | 1243 | NULL}, |
1209 | { &vmail, VSTRFIXED|VTEXTFIXED|VUNSET, "MAIL=", | 1244 | {&vmail, VSTRFIXED | VTEXTFIXED | VUNSET, "MAIL=", |
1210 | NULL }, | 1245 | NULL}, |
1211 | { &vmpath, VSTRFIXED|VTEXTFIXED|VUNSET, "MAILPATH=", | 1246 | {&vmpath, VSTRFIXED | VTEXTFIXED | VUNSET, "MAILPATH=", |
1212 | NULL }, | 1247 | NULL}, |
1213 | { &vpath, VSTRFIXED|VTEXTFIXED, defpathvar, | 1248 | {&vpath, VSTRFIXED | VTEXTFIXED, defpathvar, |
1214 | changepath }, | 1249 | changepath}, |
1215 | #if defined(CONFIG_FEATURE_COMMAND_EDITING) && defined(CONFIG_FEATURE_SH_FANCY_PROMPT) | 1250 | #if defined(CONFIG_FEATURE_COMMAND_EDITING) && defined(CONFIG_FEATURE_SH_FANCY_PROMPT) |
1216 | { &vps1, VSTRFIXED|VTEXTFIXED, "PS1=\\w \\$ ", | 1251 | {&vps1, VSTRFIXED | VTEXTFIXED, "PS1=\\w \\$ ", |
1217 | NULL }, | 1252 | NULL}, |
1218 | #endif /* else vps1 depends on uid */ | 1253 | #endif /* else vps1 depends on uid */ |
1219 | { &vps2, VSTRFIXED|VTEXTFIXED, "PS2=> ", | 1254 | {&vps2, VSTRFIXED | VTEXTFIXED, "PS2=> ", |
1220 | NULL }, | 1255 | NULL}, |
1221 | { &voptind, VSTRFIXED|VTEXTFIXED, "OPTIND=1", | 1256 | {&voptind, VSTRFIXED | VTEXTFIXED, "OPTIND=1", |
1222 | getoptsreset }, | 1257 | getoptsreset}, |
1223 | #ifdef CONFIG_LOCALE_SUPPORT | 1258 | #ifdef CONFIG_LOCALE_SUPPORT |
1224 | { &vlc_all, VSTRFIXED|VTEXTFIXED|VUNSET, "LC_ALL=", | 1259 | {&vlc_all, VSTRFIXED | VTEXTFIXED | VUNSET, "LC_ALL=", |
1225 | change_lc_all }, | 1260 | change_lc_all}, |
1226 | { &vlc_ctype, VSTRFIXED|VTEXTFIXED|VUNSET, "LC_CTYPE=", | 1261 | {&vlc_ctype, VSTRFIXED | VTEXTFIXED | VUNSET, "LC_CTYPE=", |
1227 | change_lc_ctype }, | 1262 | change_lc_ctype}, |
1228 | #endif | 1263 | #endif |
1229 | { NULL, 0, NULL, | 1264 | {NULL, 0, NULL, |
1230 | NULL } | 1265 | NULL} |
1231 | }; | 1266 | }; |
1232 | 1267 | ||
1233 | #define VTABSIZE 39 | 1268 | #define VTABSIZE 39 |
@@ -1251,26 +1286,26 @@ static struct var *vartab[VTABSIZE]; | |||
1251 | 1286 | ||
1252 | #define mpathset() ((vmpath.flags & VUNSET) == 0) | 1287 | #define mpathset() ((vmpath.flags & VUNSET) == 0) |
1253 | 1288 | ||
1254 | static void initvar (void); | 1289 | static void initvar(void); |
1255 | static void setvar (const char *, const char *, int); | 1290 | static void setvar(const char *, const char *, int); |
1256 | static void setvareq (char *, int); | 1291 | static void setvareq(char *, int); |
1257 | static void listsetvar (struct strlist *); | 1292 | static void listsetvar(struct strlist *); |
1258 | static const char *lookupvar (const char *); | 1293 | static const char *lookupvar(const char *); |
1259 | static const char *bltinlookup (const char *); | 1294 | static const char *bltinlookup(const char *); |
1260 | static char **environment (void); | 1295 | static char **environment(void); |
1261 | static int showvarscmd (int, char **); | 1296 | static int showvarscmd(int, char **); |
1262 | static void mklocal (char *); | 1297 | static void mklocal(char *); |
1263 | static void poplocalvars (void); | 1298 | static void poplocalvars(void); |
1264 | static int unsetvar (const char *); | 1299 | static int unsetvar(const char *); |
1265 | static int varequal (const char *, const char *); | 1300 | static int varequal(const char *, const char *); |
1266 | 1301 | ||
1267 | 1302 | ||
1268 | static char *arg0; /* value of $0 */ | 1303 | static char *arg0; /* value of $0 */ |
1269 | static struct shparam shellparam; /* current positional parameters */ | 1304 | static struct shparam shellparam; /* current positional parameters */ |
1270 | static char **argptr; /* argument list for builtin commands */ | 1305 | static char **argptr; /* argument list for builtin commands */ |
1271 | static char *optionarg; /* set by nextopt (like getopt) */ | 1306 | static char *optionarg; /* set by nextopt (like getopt) */ |
1272 | static char *optptr; /* used by nextopt */ | 1307 | static char *optptr; /* used by nextopt */ |
1273 | static char *minusc; /* argument to -c option */ | 1308 | static char *minusc; /* argument to -c option */ |
1274 | 1309 | ||
1275 | 1310 | ||
1276 | #ifdef CONFIG_ASH_ALIAS | 1311 | #ifdef CONFIG_ASH_ALIAS |
@@ -1289,13 +1324,12 @@ struct alias { | |||
1289 | 1324 | ||
1290 | static struct alias *atab[ATABSIZE]; | 1325 | static struct alias *atab[ATABSIZE]; |
1291 | 1326 | ||
1292 | static void setalias (char *, char *); | 1327 | static void setalias(char *, char *); |
1293 | static struct alias **hashalias (const char *); | 1328 | static struct alias **hashalias(const char *); |
1294 | static struct alias *freealias (struct alias *); | 1329 | static struct alias *freealias(struct alias *); |
1295 | static struct alias **__lookupalias (const char *); | 1330 | static struct alias **__lookupalias(const char *); |
1296 | 1331 | ||
1297 | static void | 1332 | static void setalias(char *name, char *val) |
1298 | setalias(char *name, char *val) | ||
1299 | { | 1333 | { |
1300 | struct alias *ap, **app; | 1334 | struct alias *ap, **app; |
1301 | 1335 | ||
@@ -1310,7 +1344,7 @@ setalias(char *name, char *val) | |||
1310 | ap->flag &= ~ALIASDEAD; | 1344 | ap->flag &= ~ALIASDEAD; |
1311 | } else { | 1345 | } else { |
1312 | /* not found */ | 1346 | /* not found */ |
1313 | ap = xmalloc(sizeof (struct alias)); | 1347 | ap = xmalloc(sizeof(struct alias)); |
1314 | ap->name = xstrdup(name); | 1348 | ap->name = xstrdup(name); |
1315 | ap->val = xstrdup(val); | 1349 | ap->val = xstrdup(val); |
1316 | ap->flag = 0; | 1350 | ap->flag = 0; |
@@ -1320,8 +1354,7 @@ setalias(char *name, char *val) | |||
1320 | INTON; | 1354 | INTON; |
1321 | } | 1355 | } |
1322 | 1356 | ||
1323 | static int | 1357 | static int unalias(char *name) |
1324 | unalias(char *name) | ||
1325 | { | 1358 | { |
1326 | struct alias **app; | 1359 | struct alias **app; |
1327 | 1360 | ||
@@ -1337,8 +1370,7 @@ unalias(char *name) | |||
1337 | return (1); | 1370 | return (1); |
1338 | } | 1371 | } |
1339 | 1372 | ||
1340 | static void | 1373 | static void rmaliases(void) |
1341 | rmaliases(void) | ||
1342 | { | 1374 | { |
1343 | struct alias *ap, **app; | 1375 | struct alias *ap, **app; |
1344 | int i; | 1376 | int i; |
@@ -1356,8 +1388,8 @@ rmaliases(void) | |||
1356 | INTON; | 1388 | INTON; |
1357 | } | 1389 | } |
1358 | 1390 | ||
1359 | static void | 1391 | static void printalias(const struct alias *ap) |
1360 | printalias(const struct alias *ap) { | 1392 | { |
1361 | char *p; | 1393 | char *p; |
1362 | 1394 | ||
1363 | p = single_quote(ap->val); | 1395 | p = single_quote(ap->val); |
@@ -1369,8 +1401,7 @@ printalias(const struct alias *ap) { | |||
1369 | /* | 1401 | /* |
1370 | * TODO - sort output | 1402 | * TODO - sort output |
1371 | */ | 1403 | */ |
1372 | static int | 1404 | static int aliascmd(int argc, char **argv) |
1373 | aliascmd(int argc, char **argv) | ||
1374 | { | 1405 | { |
1375 | char *n, *v; | 1406 | char *n, *v; |
1376 | int ret = 0; | 1407 | int ret = 0; |
@@ -1386,14 +1417,13 @@ aliascmd(int argc, char **argv) | |||
1386 | return (0); | 1417 | return (0); |
1387 | } | 1418 | } |
1388 | while ((n = *++argv) != NULL) { | 1419 | while ((n = *++argv) != NULL) { |
1389 | if ((v = strchr(n+1, '=')) == NULL) { /* n+1: funny ksh stuff */ | 1420 | if ((v = strchr(n + 1, '=')) == NULL) { /* n+1: funny ksh stuff */ |
1390 | if ((ap = *__lookupalias(n)) == NULL) { | 1421 | if ((ap = *__lookupalias(n)) == NULL) { |
1391 | out2fmt("%s: %s not found\n", "alias", n); | 1422 | out2fmt("%s: %s not found\n", "alias", n); |
1392 | ret = 1; | 1423 | ret = 1; |
1393 | } else | 1424 | } else |
1394 | printalias(ap); | 1425 | printalias(ap); |
1395 | } | 1426 | } else { |
1396 | else { | ||
1397 | *v++ = '\0'; | 1427 | *v++ = '\0'; |
1398 | setalias(n, v); | 1428 | setalias(n, v); |
1399 | } | 1429 | } |
@@ -1402,8 +1432,7 @@ aliascmd(int argc, char **argv) | |||
1402 | return (ret); | 1432 | return (ret); |
1403 | } | 1433 | } |
1404 | 1434 | ||
1405 | static int | 1435 | static int unaliascmd(int argc, char **argv) |
1406 | unaliascmd(int argc, char **argv) | ||
1407 | { | 1436 | { |
1408 | int i; | 1437 | int i; |
1409 | 1438 | ||
@@ -1423,19 +1452,17 @@ unaliascmd(int argc, char **argv) | |||
1423 | return (i); | 1452 | return (i); |
1424 | } | 1453 | } |
1425 | 1454 | ||
1426 | static struct alias ** | 1455 | static struct alias **hashalias(const char *p) |
1427 | hashalias(const char *p) | ||
1428 | { | 1456 | { |
1429 | unsigned int hashval; | 1457 | unsigned int hashval; |
1430 | 1458 | ||
1431 | hashval = *p << 4; | 1459 | hashval = *p << 4; |
1432 | while (*p) | 1460 | while (*p) |
1433 | hashval+= *p++; | 1461 | hashval += *p++; |
1434 | return &atab[hashval % ATABSIZE]; | 1462 | return &atab[hashval % ATABSIZE]; |
1435 | } | 1463 | } |
1436 | 1464 | ||
1437 | static struct alias * | 1465 | static struct alias *freealias(struct alias *ap) |
1438 | freealias(struct alias *ap) | ||
1439 | { | 1466 | { |
1440 | struct alias *next; | 1467 | struct alias *next; |
1441 | 1468 | ||
@@ -1452,8 +1479,7 @@ freealias(struct alias *ap) | |||
1452 | } | 1479 | } |
1453 | 1480 | ||
1454 | 1481 | ||
1455 | static struct alias ** | 1482 | static struct alias **__lookupalias(const char *name) |
1456 | __lookupalias(const char *name) | ||
1457 | { | 1483 | { |
1458 | struct alias **app = hashalias(name); | 1484 | struct alias **app = hashalias(name); |
1459 | 1485 | ||
@@ -1472,71 +1498,75 @@ __lookupalias(const char *name) | |||
1472 | * written implementation written by Aaron Lehmann <aaronl@vitelus.com>. | 1498 | * written implementation written by Aaron Lehmann <aaronl@vitelus.com>. |
1473 | * This is now part of libbb, so that it can be used by all the shells | 1499 | * This is now part of libbb, so that it can be used by all the shells |
1474 | * in busybox. */ | 1500 | * in busybox. */ |
1475 | static void expari (int); | 1501 | static void expari(int); |
1476 | #endif | 1502 | #endif |
1477 | 1503 | ||
1478 | static char *trap[NSIG]; /* trap handler commands */ | 1504 | static char *trap[NSIG]; /* trap handler commands */ |
1479 | static char sigmode[NSIG - 1]; /* current value of signal */ | 1505 | static char sigmode[NSIG - 1]; /* current value of signal */ |
1480 | static char gotsig[NSIG - 1]; /* indicates specified signal received */ | 1506 | static char gotsig[NSIG - 1]; /* indicates specified signal received */ |
1481 | static int pendingsigs; /* indicates some signal received */ | 1507 | static int pendingsigs; /* indicates some signal received */ |
1482 | 1508 | ||
1483 | /* | 1509 | /* |
1484 | * This file was generated by the mkbuiltins program. | 1510 | * This file was generated by the mkbuiltins program. |
1485 | */ | 1511 | */ |
1486 | 1512 | ||
1487 | #ifdef CONFIG_ASH_JOB_CONTROL | 1513 | #ifdef CONFIG_ASH_JOB_CONTROL |
1488 | static int bgcmd (int, char **); | 1514 | static int bgcmd(int, char **); |
1489 | static int fgcmd (int, char **); | 1515 | static int fgcmd(int, char **); |
1490 | static int killcmd (int, char **); | 1516 | static int killcmd(int, char **); |
1491 | #endif | 1517 | #endif |
1492 | static int bltincmd (int, char **); | 1518 | static int bltincmd(int, char **); |
1493 | static int cdcmd (int, char **); | 1519 | static int cdcmd(int, char **); |
1494 | static int breakcmd (int, char **); | 1520 | static int breakcmd(int, char **); |
1521 | |||
1495 | #ifdef CONFIG_ASH_CMDCMD | 1522 | #ifdef CONFIG_ASH_CMDCMD |
1496 | static int commandcmd (int, char **); | 1523 | static int commandcmd(int, char **); |
1497 | #endif | 1524 | #endif |
1498 | static int dotcmd (int, char **); | 1525 | static int dotcmd(int, char **); |
1499 | static int evalcmd (int, char **); | 1526 | static int evalcmd(int, char **); |
1500 | static int execcmd (int, char **); | 1527 | static int execcmd(int, char **); |
1501 | static int exitcmd (int, char **); | 1528 | static int exitcmd(int, char **); |
1502 | static int exportcmd (int, char **); | 1529 | static int exportcmd(int, char **); |
1503 | static int histcmd (int, char **); | 1530 | static int histcmd(int, char **); |
1504 | static int hashcmd (int, char **); | 1531 | static int hashcmd(int, char **); |
1505 | static int helpcmd (int, char **); | 1532 | static int helpcmd(int, char **); |
1506 | static int jobscmd (int, char **); | 1533 | static int jobscmd(int, char **); |
1507 | static int localcmd (int, char **); | 1534 | static int localcmd(int, char **); |
1508 | static int pwdcmd (int, char **); | 1535 | static int pwdcmd(int, char **); |
1509 | static int readcmd (int, char **); | 1536 | static int readcmd(int, char **); |
1510 | static int returncmd (int, char **); | 1537 | static int returncmd(int, char **); |
1511 | static int setcmd (int, char **); | 1538 | static int setcmd(int, char **); |
1512 | static int setvarcmd (int, char **); | 1539 | static int setvarcmd(int, char **); |
1513 | static int shiftcmd (int, char **); | 1540 | static int shiftcmd(int, char **); |
1514 | static int trapcmd (int, char **); | 1541 | static int trapcmd(int, char **); |
1515 | static int umaskcmd (int, char **); | 1542 | static int umaskcmd(int, char **); |
1543 | |||
1516 | #ifdef CONFIG_ASH_ALIAS | 1544 | #ifdef CONFIG_ASH_ALIAS |
1517 | static int aliascmd (int, char **); | 1545 | static int aliascmd(int, char **); |
1518 | static int unaliascmd (int, char **); | 1546 | static int unaliascmd(int, char **); |
1519 | #endif | 1547 | #endif |
1520 | static int unsetcmd (int, char **); | 1548 | static int unsetcmd(int, char **); |
1521 | static int waitcmd (int, char **); | 1549 | static int waitcmd(int, char **); |
1522 | static int ulimitcmd (int, char **); | 1550 | static int ulimitcmd(int, char **); |
1523 | static int timescmd (int, char **); | 1551 | static int timescmd(int, char **); |
1552 | |||
1524 | #ifdef CONFIG_ASH_MATH_SUPPORT | 1553 | #ifdef CONFIG_ASH_MATH_SUPPORT |
1525 | static int letcmd (int, char **); | 1554 | static int letcmd(int, char **); |
1526 | #endif | 1555 | #endif |
1527 | static int typecmd (int, char **); | 1556 | static int typecmd(int, char **); |
1557 | |||
1528 | #ifdef CONFIG_ASH_GETOPTS | 1558 | #ifdef CONFIG_ASH_GETOPTS |
1529 | static int getoptscmd (int, char **); | 1559 | static int getoptscmd(int, char **); |
1530 | #endif | 1560 | #endif |
1531 | 1561 | ||
1532 | #ifndef CONFIG_TRUE | 1562 | #ifndef CONFIG_TRUE |
1533 | static int true_main (int, char **); | 1563 | static int true_main(int, char **); |
1534 | #endif | 1564 | #endif |
1535 | #ifndef CONFIG_FALSE | 1565 | #ifndef CONFIG_FALSE |
1536 | static int false_main (int, char **); | 1566 | static int false_main(int, char **); |
1537 | #endif | 1567 | #endif |
1538 | 1568 | ||
1539 | static void setpwd (const char *, int); | 1569 | static void setpwd(const char *, int); |
1540 | 1570 | ||
1541 | 1571 | ||
1542 | #define BUILTIN_NOSPEC "0" | 1572 | #define BUILTIN_NOSPEC "0" |
@@ -1553,7 +1583,7 @@ static void setpwd (const char *, int); | |||
1553 | struct builtincmd { | 1583 | struct builtincmd { |
1554 | const char *name; | 1584 | const char *name; |
1555 | int (*const builtinfunc) (int, char **); | 1585 | int (*const builtinfunc) (int, char **); |
1556 | //unsigned flags; | 1586 | /* unsigned flags; */ |
1557 | }; | 1587 | }; |
1558 | 1588 | ||
1559 | 1589 | ||
@@ -1564,63 +1594,64 @@ struct builtincmd { | |||
1564 | * have been warned. | 1594 | * have been warned. |
1565 | */ | 1595 | */ |
1566 | static const struct builtincmd builtincmds[] = { | 1596 | static const struct builtincmd builtincmds[] = { |
1567 | { BUILTIN_SPECIAL ".", dotcmd }, /* first, see declare DOTCMD */ | 1597 | {BUILTIN_SPECIAL ".", dotcmd}, /* first, see declare DOTCMD */ |
1568 | { BUILTIN_SPECIAL ":", true_main }, | 1598 | {BUILTIN_SPECIAL ":", true_main}, |
1569 | #ifdef CONFIG_ASH_ALIAS | 1599 | #ifdef CONFIG_ASH_ALIAS |
1570 | { BUILTIN_REG_ASSG "alias", aliascmd }, | 1600 | {BUILTIN_REG_ASSG "alias", aliascmd}, |
1571 | #endif | 1601 | #endif |
1572 | #ifdef CONFIG_ASH_JOB_CONTROL | 1602 | #ifdef CONFIG_ASH_JOB_CONTROL |
1573 | { BUILTIN_REGULAR "bg", bgcmd }, | 1603 | {BUILTIN_REGULAR "bg", bgcmd}, |
1574 | #endif | 1604 | #endif |
1575 | { BUILTIN_SPECIAL "break", breakcmd }, | 1605 | {BUILTIN_SPECIAL "break", breakcmd}, |
1576 | { BUILTIN_SPECIAL "builtin", bltincmd }, | 1606 | {BUILTIN_SPECIAL "builtin", bltincmd}, |
1577 | { BUILTIN_REGULAR "cd", cdcmd }, | 1607 | {BUILTIN_REGULAR "cd", cdcmd}, |
1578 | { BUILTIN_NOSPEC "chdir", cdcmd }, | 1608 | {BUILTIN_NOSPEC "chdir", cdcmd}, |
1579 | #ifdef CONFIG_ASH_CMDCMD | 1609 | #ifdef CONFIG_ASH_CMDCMD |
1580 | { BUILTIN_REGULAR "command", commandcmd }, | 1610 | {BUILTIN_REGULAR "command", commandcmd}, |
1581 | #endif | 1611 | #endif |
1582 | { BUILTIN_SPECIAL "continue", breakcmd }, | 1612 | {BUILTIN_SPECIAL "continue", breakcmd}, |
1583 | { BUILTIN_SPECIAL "eval", evalcmd }, | 1613 | {BUILTIN_SPECIAL "eval", evalcmd}, |
1584 | { BUILTIN_SPECIAL "exec", execcmd }, | 1614 | {BUILTIN_SPECIAL "exec", execcmd}, |
1585 | { BUILTIN_SPECIAL "exit", exitcmd }, | 1615 | {BUILTIN_SPECIAL "exit", exitcmd}, |
1586 | { BUILTIN_SPEC_ASSG "export", exportcmd }, | 1616 | {BUILTIN_SPEC_ASSG "export", exportcmd}, |
1587 | { BUILTIN_REGULAR "false", false_main }, | 1617 | {BUILTIN_REGULAR "false", false_main}, |
1588 | { BUILTIN_REGULAR "fc", histcmd }, | 1618 | {BUILTIN_REGULAR "fc", histcmd}, |
1589 | #ifdef CONFIG_ASH_JOB_CONTROL | 1619 | #ifdef CONFIG_ASH_JOB_CONTROL |
1590 | { BUILTIN_REGULAR "fg", fgcmd }, | 1620 | {BUILTIN_REGULAR "fg", fgcmd}, |
1591 | #endif | 1621 | #endif |
1592 | #ifdef CONFIG_ASH_GETOPTS | 1622 | #ifdef CONFIG_ASH_GETOPTS |
1593 | { BUILTIN_REGULAR "getopts", getoptscmd }, | 1623 | {BUILTIN_REGULAR "getopts", getoptscmd}, |
1594 | #endif | 1624 | #endif |
1595 | { BUILTIN_NOSPEC "hash", hashcmd }, | 1625 | {BUILTIN_NOSPEC "hash", hashcmd}, |
1596 | { BUILTIN_NOSPEC "help", helpcmd }, | 1626 | {BUILTIN_NOSPEC "help", helpcmd}, |
1597 | { BUILTIN_REGULAR "jobs", jobscmd }, | 1627 | {BUILTIN_REGULAR "jobs", jobscmd}, |
1598 | #ifdef CONFIG_ASH_JOB_CONTROL | 1628 | #ifdef CONFIG_ASH_JOB_CONTROL |
1599 | { BUILTIN_REGULAR "kill", killcmd }, | 1629 | {BUILTIN_REGULAR "kill", killcmd}, |
1600 | #endif | 1630 | #endif |
1601 | #ifdef CONFIG_ASH_MATH_SUPPORT | 1631 | #ifdef CONFIG_ASH_MATH_SUPPORT |
1602 | { BUILTIN_REGULAR "let", letcmd }, | 1632 | {BUILTIN_REGULAR "let", letcmd}, |
1603 | #endif | 1633 | #endif |
1604 | { BUILTIN_ASSIGN "local", localcmd }, | 1634 | {BUILTIN_ASSIGN "local", localcmd}, |
1605 | { BUILTIN_NOSPEC "pwd", pwdcmd }, | 1635 | {BUILTIN_NOSPEC "pwd", pwdcmd}, |
1606 | { BUILTIN_REGULAR "read", readcmd }, | 1636 | {BUILTIN_REGULAR "read", readcmd}, |
1607 | { BUILTIN_SPEC_ASSG "readonly", exportcmd }, | 1637 | {BUILTIN_SPEC_ASSG "readonly", exportcmd}, |
1608 | { BUILTIN_SPECIAL "return", returncmd }, | 1638 | {BUILTIN_SPECIAL "return", returncmd}, |
1609 | { BUILTIN_SPECIAL "set", setcmd }, | 1639 | {BUILTIN_SPECIAL "set", setcmd}, |
1610 | { BUILTIN_NOSPEC "setvar", setvarcmd }, | 1640 | {BUILTIN_NOSPEC "setvar", setvarcmd}, |
1611 | { BUILTIN_SPECIAL "shift", shiftcmd }, | 1641 | {BUILTIN_SPECIAL "shift", shiftcmd}, |
1612 | { BUILTIN_SPECIAL "times", timescmd }, | 1642 | {BUILTIN_SPECIAL "times", timescmd}, |
1613 | { BUILTIN_SPECIAL "trap", trapcmd }, | 1643 | {BUILTIN_SPECIAL "trap", trapcmd}, |
1614 | { BUILTIN_REGULAR "true", true_main }, | 1644 | {BUILTIN_REGULAR "true", true_main}, |
1615 | { BUILTIN_NOSPEC "type", typecmd }, | 1645 | {BUILTIN_NOSPEC "type", typecmd}, |
1616 | { BUILTIN_NOSPEC "ulimit", ulimitcmd }, | 1646 | {BUILTIN_NOSPEC "ulimit", ulimitcmd}, |
1617 | { BUILTIN_REGULAR "umask", umaskcmd }, | 1647 | {BUILTIN_REGULAR "umask", umaskcmd}, |
1618 | #ifdef CONFIG_ASH_ALIAS | 1648 | #ifdef CONFIG_ASH_ALIAS |
1619 | { BUILTIN_REGULAR "unalias", unaliascmd }, | 1649 | {BUILTIN_REGULAR "unalias", unaliascmd}, |
1620 | #endif | 1650 | #endif |
1621 | { BUILTIN_SPECIAL "unset", unsetcmd }, | 1651 | {BUILTIN_SPECIAL "unset", unsetcmd}, |
1622 | { BUILTIN_REGULAR "wait", waitcmd }, | 1652 | {BUILTIN_REGULAR "wait", waitcmd}, |
1623 | }; | 1653 | }; |
1654 | |||
1624 | #define NUMBUILTINS (sizeof (builtincmds) / sizeof (struct builtincmd) ) | 1655 | #define NUMBUILTINS (sizeof (builtincmds) / sizeof (struct builtincmd) ) |
1625 | 1656 | ||
1626 | #define DOTCMD &builtincmds[0] | 1657 | #define DOTCMD &builtincmds[0] |
@@ -1629,8 +1660,8 @@ static struct builtincmd *EXECCMD; | |||
1629 | static struct builtincmd *EVALCMD; | 1660 | static struct builtincmd *EVALCMD; |
1630 | 1661 | ||
1631 | /* states */ | 1662 | /* states */ |
1632 | #define CONFIG_ASH_JOB_CONTROLTOPPED 1 /* all procs are stopped */ | 1663 | #define CONFIG_ASH_JOB_CONTROLTOPPED 1 /* all procs are stopped */ |
1633 | #define JOBDONE 2 /* all procs are completed */ | 1664 | #define JOBDONE 2 /* all procs are completed */ |
1634 | 1665 | ||
1635 | /* | 1666 | /* |
1636 | * A job structure contains information about a job. A job is either a | 1667 | * A job structure contains information about a job. A job is either a |
@@ -1640,58 +1671,58 @@ static struct builtincmd *EVALCMD; | |||
1640 | */ | 1671 | */ |
1641 | 1672 | ||
1642 | struct procstat { | 1673 | struct procstat { |
1643 | pid_t pid; /* process id */ | 1674 | pid_t pid; /* process id */ |
1644 | int status; /* status flags (defined above) */ | 1675 | int status; /* status flags (defined above) */ |
1645 | char *cmd; /* text of command being run */ | 1676 | char *cmd; /* text of command being run */ |
1646 | }; | 1677 | }; |
1647 | 1678 | ||
1648 | 1679 | ||
1649 | static int job_warning; /* user was warned about stopped jobs */ | 1680 | static int job_warning; /* user was warned about stopped jobs */ |
1650 | 1681 | ||
1651 | #ifdef CONFIG_ASH_JOB_CONTROL | 1682 | #ifdef CONFIG_ASH_JOB_CONTROL |
1652 | static void setjobctl(int enable); | 1683 | static void setjobctl(int enable); |
1653 | #else | 1684 | #else |
1654 | #define setjobctl(on) /* do nothing */ | 1685 | #define setjobctl(on) /* do nothing */ |
1655 | #endif | 1686 | #endif |
1656 | 1687 | ||
1657 | 1688 | ||
1658 | struct job { | 1689 | struct job { |
1659 | struct procstat ps0; /* status of process */ | 1690 | struct procstat ps0; /* status of process */ |
1660 | struct procstat *ps; /* status or processes when more than one */ | 1691 | struct procstat *ps; /* status or processes when more than one */ |
1661 | short nprocs; /* number of processes */ | 1692 | short nprocs; /* number of processes */ |
1662 | short pgrp; /* process group of this job */ | 1693 | short pgrp; /* process group of this job */ |
1663 | char state; /* true if job is finished */ | 1694 | char state; /* true if job is finished */ |
1664 | char used; /* true if this entry is in used */ | 1695 | char used; /* true if this entry is in used */ |
1665 | char changed; /* true if status has changed */ | 1696 | char changed; /* true if status has changed */ |
1666 | #ifdef CONFIG_ASH_JOB_CONTROL | 1697 | #ifdef CONFIG_ASH_JOB_CONTROL |
1667 | char jobctl; /* job running under job control */ | 1698 | char jobctl; /* job running under job control */ |
1668 | #endif | 1699 | #endif |
1669 | }; | 1700 | }; |
1670 | 1701 | ||
1671 | static struct job *jobtab; /* array of jobs */ | 1702 | static struct job *jobtab; /* array of jobs */ |
1672 | static int njobs; /* size of array */ | 1703 | static int njobs; /* size of array */ |
1673 | static int backgndpid = -1; /* pid of last background process */ | 1704 | static int backgndpid = -1; /* pid of last background process */ |
1705 | |||
1674 | #ifdef CONFIG_ASH_JOB_CONTROL | 1706 | #ifdef CONFIG_ASH_JOB_CONTROL |
1675 | static int initialpgrp; /* pgrp of shell on invocation */ | 1707 | static int initialpgrp; /* pgrp of shell on invocation */ |
1676 | static int curjob; /* current job */ | 1708 | static int curjob; /* current job */ |
1677 | static int jobctl; | 1709 | static int jobctl; |
1678 | #endif | 1710 | #endif |
1679 | static int intreceived; | 1711 | static int intreceived; |
1680 | 1712 | ||
1681 | static struct job *makejob (const union node *, int); | 1713 | static struct job *makejob(const union node *, int); |
1682 | static int forkshell (struct job *, const union node *, int); | 1714 | static int forkshell(struct job *, const union node *, int); |
1683 | static int waitforjob (struct job *); | 1715 | static int waitforjob(struct job *); |
1684 | 1716 | ||
1685 | static int docd (char *, int); | 1717 | static int docd(char *, int); |
1686 | static void getpwd (void); | 1718 | static void getpwd(void); |
1687 | 1719 | ||
1688 | static char *padvance (const char **, const char *); | 1720 | static char *padvance(const char **, const char *); |
1689 | 1721 | ||
1690 | static char nullstr[1]; /* zero length string */ | 1722 | static char nullstr[1]; /* zero length string */ |
1691 | static char *curdir = nullstr; /* current working directory */ | 1723 | static char *curdir = nullstr; /* current working directory */ |
1692 | 1724 | ||
1693 | static int | 1725 | static int cdcmd(int argc, char **argv) |
1694 | cdcmd(int argc, char **argv) | ||
1695 | { | 1726 | { |
1696 | const char *dest; | 1727 | const char *dest; |
1697 | const char *path; | 1728 | const char *path; |
@@ -1742,8 +1773,7 @@ cdcmd(int argc, char **argv) | |||
1742 | * directory name if "print" is nonzero. | 1773 | * directory name if "print" is nonzero. |
1743 | */ | 1774 | */ |
1744 | 1775 | ||
1745 | static int | 1776 | static int docd(char *dest, int print) |
1746 | docd(char *dest, int print) | ||
1747 | { | 1777 | { |
1748 | TRACE(("docd(\"%s\", %d) called\n", dest, print)); | 1778 | TRACE(("docd(\"%s\", %d) called\n", dest, print)); |
1749 | INTOFF; | 1779 | INTOFF; |
@@ -1770,24 +1800,21 @@ docd(char *dest, int print) | |||
1770 | } | 1800 | } |
1771 | 1801 | ||
1772 | 1802 | ||
1773 | static int | 1803 | static int pwdcmd(int argc, char **argv) |
1774 | pwdcmd(int argc, char **argv) | ||
1775 | { | 1804 | { |
1776 | puts(curdir); | 1805 | puts(curdir); |
1777 | return 0; | 1806 | return 0; |
1778 | } | 1807 | } |
1779 | 1808 | ||
1780 | /* Ask system the current directory */ | 1809 | /* Ask system the current directory */ |
1781 | static void | 1810 | static void getpwd(void) |
1782 | getpwd(void) | ||
1783 | { | 1811 | { |
1784 | curdir = xgetcwd(0); | 1812 | curdir = xgetcwd(0); |
1785 | if(curdir==0) | 1813 | if (curdir == 0) |
1786 | curdir = nullstr; | 1814 | curdir = nullstr; |
1787 | } | 1815 | } |
1788 | 1816 | ||
1789 | static void | 1817 | static void setpwd(const char *val, int setold) |
1790 | setpwd(const char *val, int setold) | ||
1791 | { | 1818 | { |
1792 | char *cated = NULL; | 1819 | char *cated = NULL; |
1793 | 1820 | ||
@@ -1796,13 +1823,13 @@ setpwd(const char *val, int setold) | |||
1796 | } | 1823 | } |
1797 | INTOFF; | 1824 | INTOFF; |
1798 | if (curdir != nullstr) { | 1825 | if (curdir != nullstr) { |
1799 | if(val!=NULL && *val != '/') | 1826 | if (val != NULL && *val != '/') |
1800 | val = cated = concat_path_file(curdir, val); | 1827 | val = cated = concat_path_file(curdir, val); |
1801 | free(curdir); | 1828 | free(curdir); |
1802 | } | 1829 | } |
1803 | if (!val) | 1830 | if (!val) |
1804 | getpwd(); | 1831 | getpwd(); |
1805 | else | 1832 | else |
1806 | curdir = simplify_path(val); | 1833 | curdir = simplify_path(val); |
1807 | free(cated); | 1834 | free(cated); |
1808 | INTON; | 1835 | INTON; |
@@ -1832,16 +1859,16 @@ struct jmploc { | |||
1832 | }; | 1859 | }; |
1833 | 1860 | ||
1834 | /* exceptions */ | 1861 | /* exceptions */ |
1835 | #define EXINT 0 /* SIGINT received */ | 1862 | #define EXINT 0 /* SIGINT received */ |
1836 | #define EXERROR 1 /* a generic error */ | 1863 | #define EXERROR 1 /* a generic error */ |
1837 | #define EXSHELLPROC 2 /* execute a shell procedure */ | 1864 | #define EXSHELLPROC 2 /* execute a shell procedure */ |
1838 | #define EXEXEC 3 /* command execution failed */ | 1865 | #define EXEXEC 3 /* command execution failed */ |
1839 | 1866 | ||
1840 | static struct jmploc *handler; | 1867 | static struct jmploc *handler; |
1841 | static int exception; | 1868 | static int exception; |
1842 | 1869 | ||
1843 | static void exverror (int, const char *, va_list) | 1870 | static void exverror(int, const char *, va_list) |
1844 | __attribute__((__noreturn__)); | 1871 | __attribute__ ((__noreturn__)); |
1845 | 1872 | ||
1846 | /* | 1873 | /* |
1847 | * Called to raise an exception. Since C doesn't include exceptions, we | 1874 | * Called to raise an exception. Since C doesn't include exceptions, we |
@@ -1849,10 +1876,9 @@ static void exverror (int, const char *, va_list) | |||
1849 | * stored in the global variable "exception". | 1876 | * stored in the global variable "exception". |
1850 | */ | 1877 | */ |
1851 | 1878 | ||
1852 | static void exraise (int) __attribute__((__noreturn__)); | 1879 | static void exraise(int) __attribute__ ((__noreturn__)); |
1853 | 1880 | ||
1854 | static void | 1881 | static void exraise(int e) |
1855 | exraise(int e) | ||
1856 | { | 1882 | { |
1857 | #ifdef DEBUG | 1883 | #ifdef DEBUG |
1858 | if (handler == NULL) | 1884 | if (handler == NULL) |
@@ -1874,8 +1900,8 @@ exraise(int e) | |||
1874 | * just defensive programming.) | 1900 | * just defensive programming.) |
1875 | */ | 1901 | */ |
1876 | 1902 | ||
1877 | static void | 1903 | static void onint(void) |
1878 | onint(void) { | 1904 | { |
1879 | sigset_t mysigset; | 1905 | sigset_t mysigset; |
1880 | 1906 | ||
1881 | if (suppressint) { | 1907 | if (suppressint) { |
@@ -1895,15 +1921,14 @@ onint(void) { | |||
1895 | } | 1921 | } |
1896 | 1922 | ||
1897 | 1923 | ||
1898 | static char *commandname; /* currently executing command */ | 1924 | static char *commandname; /* currently executing command */ |
1899 | 1925 | ||
1900 | /* | 1926 | /* |
1901 | * Exverror is called to raise the error exception. If the first argument | 1927 | * Exverror is called to raise the error exception. If the first argument |
1902 | * is not NULL then error prints an error message using printf style | 1928 | * is not NULL then error prints an error message using printf style |
1903 | * formatting. It then raises the error exception. | 1929 | * formatting. It then raises the error exception. |
1904 | */ | 1930 | */ |
1905 | static void | 1931 | static void exverror(int cond, const char *msg, va_list ap) |
1906 | exverror(int cond, const char *msg, va_list ap) | ||
1907 | { | 1932 | { |
1908 | CLEAR_PENDING_INT; | 1933 | CLEAR_PENDING_INT; |
1909 | INTOFF; | 1934 | INTOFF; |
@@ -1925,10 +1950,10 @@ exverror(int cond, const char *msg, va_list ap) | |||
1925 | } | 1950 | } |
1926 | 1951 | ||
1927 | 1952 | ||
1928 | static void | 1953 | static void error(const char *msg, ...) |
1929 | error(const char *msg, ...) | ||
1930 | { | 1954 | { |
1931 | va_list ap; | 1955 | va_list ap; |
1956 | |||
1932 | va_start(ap, msg); | 1957 | va_start(ap, msg); |
1933 | exverror(EXERROR, msg, ap); | 1958 | exverror(EXERROR, msg, ap); |
1934 | /* NOTREACHED */ | 1959 | /* NOTREACHED */ |
@@ -1936,10 +1961,10 @@ error(const char *msg, ...) | |||
1936 | } | 1961 | } |
1937 | 1962 | ||
1938 | 1963 | ||
1939 | static void | 1964 | static void exerror(int cond, const char *msg, ...) |
1940 | exerror(int cond, const char *msg, ...) | ||
1941 | { | 1965 | { |
1942 | va_list ap; | 1966 | va_list ap; |
1967 | |||
1943 | va_start(ap, msg); | 1968 | va_start(ap, msg); |
1944 | exverror(cond, msg, ap); | 1969 | exverror(cond, msg, ap); |
1945 | /* NOTREACHED */ | 1970 | /* NOTREACHED */ |
@@ -1953,71 +1978,71 @@ exerror(int cond, const char *msg, ...) | |||
1953 | */ | 1978 | */ |
1954 | 1979 | ||
1955 | struct errname { | 1980 | struct errname { |
1956 | short errcode; /* error number */ | 1981 | short errcode; /* error number */ |
1957 | short action; /* operation which encountered the error */ | 1982 | short action; /* operation which encountered the error */ |
1958 | }; | 1983 | }; |
1959 | 1984 | ||
1960 | /* | 1985 | /* |
1961 | * Types of operations (passed to the errmsg routine). | 1986 | * Types of operations (passed to the errmsg routine). |
1962 | */ | 1987 | */ |
1963 | 1988 | ||
1964 | #define E_OPEN 01 /* opening a file */ | 1989 | #define E_OPEN 01 /* opening a file */ |
1965 | #define E_CREAT 02 /* creating a file */ | 1990 | #define E_CREAT 02 /* creating a file */ |
1966 | #define E_EXEC 04 /* executing a program */ | 1991 | #define E_EXEC 04 /* executing a program */ |
1967 | 1992 | ||
1968 | #define ALL (E_OPEN|E_CREAT|E_EXEC) | 1993 | #define ALL (E_OPEN|E_CREAT|E_EXEC) |
1969 | 1994 | ||
1970 | static const struct errname errormsg[] = { | 1995 | static const struct errname errormsg[] = { |
1971 | { EINTR, ALL }, | 1996 | {EINTR, ALL}, |
1972 | { EACCES, ALL }, | 1997 | {EACCES, ALL}, |
1973 | { EIO, ALL }, | 1998 | {EIO, ALL}, |
1974 | { ENOENT, E_OPEN }, | 1999 | {ENOENT, E_OPEN}, |
1975 | { ENOENT, E_CREAT }, | 2000 | {ENOENT, E_CREAT}, |
1976 | { ENOENT, E_EXEC }, | 2001 | {ENOENT, E_EXEC}, |
1977 | { ENOTDIR, E_OPEN }, | 2002 | {ENOTDIR, E_OPEN}, |
1978 | { ENOTDIR, E_CREAT }, | 2003 | {ENOTDIR, E_CREAT}, |
1979 | { ENOTDIR, E_EXEC }, | 2004 | {ENOTDIR, E_EXEC}, |
1980 | { EISDIR, ALL }, | 2005 | {EISDIR, ALL}, |
1981 | { EEXIST, E_CREAT }, | 2006 | {EEXIST, E_CREAT}, |
1982 | #ifdef EMFILE | 2007 | #ifdef EMFILE |
1983 | { EMFILE, ALL }, | 2008 | {EMFILE, ALL}, |
1984 | #endif | 2009 | #endif |
1985 | { ENFILE, ALL }, | 2010 | {ENFILE, ALL}, |
1986 | { ENOSPC, ALL }, | 2011 | {ENOSPC, ALL}, |
1987 | #ifdef EDQUOT | 2012 | #ifdef EDQUOT |
1988 | { EDQUOT, ALL }, | 2013 | {EDQUOT, ALL}, |
1989 | #endif | 2014 | #endif |
1990 | #ifdef ENOSR | 2015 | #ifdef ENOSR |
1991 | { ENOSR, ALL }, | 2016 | {ENOSR, ALL}, |
1992 | #endif | 2017 | #endif |
1993 | { ENXIO, ALL }, | 2018 | {ENXIO, ALL}, |
1994 | { EROFS, ALL }, | 2019 | {EROFS, ALL}, |
1995 | { ETXTBSY, ALL }, | 2020 | {ETXTBSY, ALL}, |
1996 | #ifdef EAGAIN | 2021 | #ifdef EAGAIN |
1997 | { EAGAIN, E_EXEC }, | 2022 | {EAGAIN, E_EXEC}, |
1998 | #endif | 2023 | #endif |
1999 | { ENOMEM, ALL }, | 2024 | {ENOMEM, ALL}, |
2000 | #ifdef ENOLINK | 2025 | #ifdef ENOLINK |
2001 | { ENOLINK, ALL }, | 2026 | {ENOLINK, ALL}, |
2002 | #endif | 2027 | #endif |
2003 | #ifdef EMULTIHOP | 2028 | #ifdef EMULTIHOP |
2004 | { EMULTIHOP, ALL }, | 2029 | {EMULTIHOP, ALL}, |
2005 | #endif | 2030 | #endif |
2006 | #ifdef ECOMM | 2031 | #ifdef ECOMM |
2007 | { ECOMM, ALL }, | 2032 | {ECOMM, ALL}, |
2008 | #endif | 2033 | #endif |
2009 | #ifdef ESTALE | 2034 | #ifdef ESTALE |
2010 | { ESTALE, ALL }, | 2035 | {ESTALE, ALL}, |
2011 | #endif | 2036 | #endif |
2012 | #ifdef ETIMEDOUT | 2037 | #ifdef ETIMEDOUT |
2013 | { ETIMEDOUT, ALL }, | 2038 | {ETIMEDOUT, ALL}, |
2014 | #endif | 2039 | #endif |
2015 | #ifdef ELOOP | 2040 | #ifdef ELOOP |
2016 | { ELOOP, ALL }, | 2041 | {ELOOP, ALL}, |
2017 | #endif | 2042 | #endif |
2018 | { E2BIG, E_EXEC }, | 2043 | {E2BIG, E_EXEC}, |
2019 | #ifdef ELIBACC | 2044 | #ifdef ELIBACC |
2020 | { ELIBACC, E_EXEC }, | 2045 | {ELIBACC, E_EXEC}, |
2021 | #endif | 2046 | #endif |
2022 | }; | 2047 | }; |
2023 | 2048 | ||
@@ -2029,13 +2054,12 @@ static const struct errname errormsg[] = { | |||
2029 | * Action describes the operation that got the error. | 2054 | * Action describes the operation that got the error. |
2030 | */ | 2055 | */ |
2031 | 2056 | ||
2032 | static const char * | 2057 | static const char *errmsg(int e, int action) |
2033 | errmsg(int e, int action) | ||
2034 | { | 2058 | { |
2035 | struct errname const *ep; | 2059 | struct errname const *ep; |
2036 | static char buf[12]; | 2060 | static char buf[12]; |
2037 | 2061 | ||
2038 | for (ep = errormsg ; ep < errormsg+ERRNAME_SIZE; ep++) { | 2062 | for (ep = errormsg; ep < errormsg + ERRNAME_SIZE; ep++) { |
2039 | if (ep->errcode == e && (ep->action & action) != 0) | 2063 | if (ep->errcode == e && (ep->action & action) != 0) |
2040 | return strerror(e); | 2064 | return strerror(e); |
2041 | } | 2065 | } |
@@ -2046,13 +2070,14 @@ errmsg(int e, int action) | |||
2046 | 2070 | ||
2047 | 2071 | ||
2048 | #ifdef CONFIG_ASH_OPTIMIZE_FOR_SIZE | 2072 | #ifdef CONFIG_ASH_OPTIMIZE_FOR_SIZE |
2049 | static void | 2073 | static void __inton() |
2050 | __inton() { | 2074 | { |
2051 | if (--suppressint == 0 && intpending) { | 2075 | if (--suppressint == 0 && intpending) { |
2052 | onint(); | 2076 | onint(); |
2053 | } | 2077 | } |
2054 | } | 2078 | } |
2055 | static void forceinton (void) { | 2079 | static void forceinton(void) |
2080 | { | ||
2056 | suppressint = 0; | 2081 | suppressint = 0; |
2057 | if (intpending) | 2082 | if (intpending) |
2058 | onint(); | 2083 | onint(); |
@@ -2060,25 +2085,26 @@ static void forceinton (void) { | |||
2060 | #endif | 2085 | #endif |
2061 | 2086 | ||
2062 | /* flags in argument to evaltree */ | 2087 | /* flags in argument to evaltree */ |
2063 | #define EV_EXIT 01 /* exit after evaluating tree */ | 2088 | #define EV_EXIT 01 /* exit after evaluating tree */ |
2064 | #define EV_TESTED 02 /* exit status is checked; ignore -e flag */ | 2089 | #define EV_TESTED 02 /* exit status is checked; ignore -e flag */ |
2065 | #define EV_BACKCMD 04 /* command executing within back quotes */ | 2090 | #define EV_BACKCMD 04 /* command executing within back quotes */ |
2066 | 2091 | ||
2067 | static int evalskip; /* set if we are skipping commands */ | 2092 | static int evalskip; /* set if we are skipping commands */ |
2068 | static int skipcount; /* number of levels to skip */ | 2093 | static int skipcount; /* number of levels to skip */ |
2069 | static int loopnest; /* current loop nesting level */ | 2094 | static int loopnest; /* current loop nesting level */ |
2070 | static int funcnest; /* depth of function calls */ | 2095 | static int funcnest; /* depth of function calls */ |
2071 | 2096 | ||
2072 | 2097 | ||
2073 | static struct strlist *cmdenviron; /* environment for builtin command */ | 2098 | static struct strlist *cmdenviron; /* environment for builtin command */ |
2074 | static int exitstatus; /* exit status of last command */ | 2099 | static int exitstatus; /* exit status of last command */ |
2075 | static int oexitstatus; /* saved exit status */ | 2100 | static int oexitstatus; /* saved exit status */ |
2076 | 2101 | ||
2077 | static void evalsubshell (const union node *, int); | 2102 | static void evalsubshell(const union node *, int); |
2078 | static void expredir (union node *); | 2103 | static void expredir(union node *); |
2079 | static void eprintlist (struct strlist *); | 2104 | static void eprintlist(struct strlist *); |
2080 | 2105 | ||
2081 | static union node *parsecmd(int); | 2106 | static union node *parsecmd(int); |
2107 | |||
2082 | /* | 2108 | /* |
2083 | * Called to reset things after an exception. | 2109 | * Called to reset things after an exception. |
2084 | */ | 2110 | */ |
@@ -2086,10 +2112,9 @@ static union node *parsecmd(int); | |||
2086 | /* | 2112 | /* |
2087 | * The eval commmand. | 2113 | * The eval commmand. |
2088 | */ | 2114 | */ |
2089 | static void evalstring (char *, int); | 2115 | static void evalstring(char *, int); |
2090 | 2116 | ||
2091 | static int | 2117 | static int evalcmd(int argc, char **argv) |
2092 | evalcmd(int argc, char **argv) | ||
2093 | { | 2118 | { |
2094 | char *p; | 2119 | char *p; |
2095 | char *concat; | 2120 | char *concat; |
@@ -2119,15 +2144,14 @@ evalcmd(int argc, char **argv) | |||
2119 | * Execute a command or commands contained in a string. | 2144 | * Execute a command or commands contained in a string. |
2120 | */ | 2145 | */ |
2121 | 2146 | ||
2122 | static void evaltree (union node *, int); | 2147 | static void evaltree(union node *, int); |
2123 | static void setinputstring (char *); | 2148 | static void setinputstring(char *); |
2124 | static void popfile (void); | 2149 | static void popfile(void); |
2125 | static void setstackmark(struct stackmark *mark); | 2150 | static void setstackmark(struct stackmark *mark); |
2126 | static void popstackmark(struct stackmark *mark); | 2151 | static void popstackmark(struct stackmark *mark); |
2127 | 2152 | ||
2128 | 2153 | ||
2129 | static void | 2154 | static void evalstring(char *s, int flag) |
2130 | evalstring(char *s, int flag) | ||
2131 | { | 2155 | { |
2132 | union node *n; | 2156 | union node *n; |
2133 | struct stackmark smark; | 2157 | struct stackmark smark; |
@@ -2142,23 +2166,22 @@ evalstring(char *s, int flag) | |||
2142 | popstackmark(&smark); | 2166 | popstackmark(&smark); |
2143 | } | 2167 | } |
2144 | 2168 | ||
2145 | static struct builtincmd *find_builtin (const char *); | 2169 | static struct builtincmd *find_builtin(const char *); |
2146 | static void expandarg (union node *, struct arglist *, int); | 2170 | static void expandarg(union node *, struct arglist *, int); |
2147 | static void calcsize (const union node *); | 2171 | static void calcsize(const union node *); |
2148 | static union node *copynode (const union node *); | 2172 | static union node *copynode(const union node *); |
2149 | 2173 | ||
2150 | /* | 2174 | /* |
2151 | * Make a copy of a parse tree. | 2175 | * Make a copy of a parse tree. |
2152 | */ | 2176 | */ |
2153 | 2177 | ||
2154 | static int funcblocksize; /* size of structures in function */ | 2178 | static int funcblocksize; /* size of structures in function */ |
2155 | static int funcstringsize; /* size of strings in node */ | 2179 | static int funcstringsize; /* size of strings in node */ |
2156 | static pointer funcblock; /* block to allocate function from */ | 2180 | static pointer funcblock; /* block to allocate function from */ |
2157 | static char *funcstring; /* block to allocate strings from */ | 2181 | static char *funcstring; /* block to allocate strings from */ |
2158 | 2182 | ||
2159 | 2183 | ||
2160 | static inline union node * | 2184 | static inline union node *copyfunc(union node *n) |
2161 | copyfunc(union node *n) | ||
2162 | { | 2185 | { |
2163 | if (n == NULL) | 2186 | if (n == NULL) |
2164 | return NULL; | 2187 | return NULL; |
@@ -2175,8 +2198,7 @@ copyfunc(union node *n) | |||
2175 | * the same name. | 2198 | * the same name. |
2176 | */ | 2199 | */ |
2177 | 2200 | ||
2178 | static inline void | 2201 | static inline void addcmdentry(char *name, struct cmdentry *entry) |
2179 | addcmdentry(char *name, struct cmdentry *entry) | ||
2180 | { | 2202 | { |
2181 | struct tblentry *cmdp; | 2203 | struct tblentry *cmdp; |
2182 | 2204 | ||
@@ -2190,8 +2212,7 @@ addcmdentry(char *name, struct cmdentry *entry) | |||
2190 | INTON; | 2212 | INTON; |
2191 | } | 2213 | } |
2192 | 2214 | ||
2193 | static inline void | 2215 | static inline void evalloop(const union node *n, int flags) |
2194 | evalloop(const union node *n, int flags) | ||
2195 | { | 2216 | { |
2196 | int status; | 2217 | int status; |
2197 | 2218 | ||
@@ -2200,7 +2221,7 @@ evalloop(const union node *n, int flags) | |||
2200 | for (;;) { | 2221 | for (;;) { |
2201 | evaltree(n->nbinary.ch1, EV_TESTED); | 2222 | evaltree(n->nbinary.ch1, EV_TESTED); |
2202 | if (evalskip) { | 2223 | if (evalskip) { |
2203 | skipping: if (evalskip == SKIPCONT && --skipcount <= 0) { | 2224 | skipping:if (evalskip == SKIPCONT && --skipcount <= 0) { |
2204 | evalskip = 0; | 2225 | evalskip = 0; |
2205 | continue; | 2226 | continue; |
2206 | } | 2227 | } |
@@ -2224,8 +2245,7 @@ skipping: if (evalskip == SKIPCONT && --skipcount <= 0) { | |||
2224 | exitstatus = status; | 2245 | exitstatus = status; |
2225 | } | 2246 | } |
2226 | 2247 | ||
2227 | static void | 2248 | static void evalfor(const union node *n, int flags) |
2228 | evalfor(const union node *n, int flags) | ||
2229 | { | 2249 | { |
2230 | struct arglist arglist; | 2250 | struct arglist arglist; |
2231 | union node *argp; | 2251 | union node *argp; |
@@ -2234,7 +2254,7 @@ evalfor(const union node *n, int flags) | |||
2234 | 2254 | ||
2235 | setstackmark(&smark); | 2255 | setstackmark(&smark); |
2236 | arglist.lastp = &arglist.list; | 2256 | arglist.lastp = &arglist.list; |
2237 | for (argp = n->nfor.args ; argp ; argp = argp->narg.next) { | 2257 | for (argp = n->nfor.args; argp; argp = argp->narg.next) { |
2238 | oexitstatus = exitstatus; | 2258 | oexitstatus = exitstatus; |
2239 | expandarg(argp, &arglist, EXP_FULL | EXP_TILDE | EXP_RECORD); | 2259 | expandarg(argp, &arglist, EXP_FULL | EXP_TILDE | EXP_RECORD); |
2240 | if (evalskip) | 2260 | if (evalskip) |
@@ -2244,7 +2264,7 @@ evalfor(const union node *n, int flags) | |||
2244 | 2264 | ||
2245 | exitstatus = 0; | 2265 | exitstatus = 0; |
2246 | loopnest++; | 2266 | loopnest++; |
2247 | for (sp = arglist.list ; sp ; sp = sp->next) { | 2267 | for (sp = arglist.list; sp; sp = sp->next) { |
2248 | setvar(n->nfor.var, sp->text, 0); | 2268 | setvar(n->nfor.var, sp->text, 0); |
2249 | evaltree(n->nfor.body, flags & EV_TESTED); | 2269 | evaltree(n->nfor.body, flags & EV_TESTED); |
2250 | if (evalskip) { | 2270 | if (evalskip) { |
@@ -2258,12 +2278,11 @@ evalfor(const union node *n, int flags) | |||
2258 | } | 2278 | } |
2259 | } | 2279 | } |
2260 | loopnest--; | 2280 | loopnest--; |
2261 | out: | 2281 | out: |
2262 | popstackmark(&smark); | 2282 | popstackmark(&smark); |
2263 | } | 2283 | } |
2264 | 2284 | ||
2265 | static inline void | 2285 | static inline void evalcase(const union node *n, int flags) |
2266 | evalcase(const union node *n, int flags) | ||
2267 | { | 2286 | { |
2268 | union node *cp; | 2287 | union node *cp; |
2269 | union node *patp; | 2288 | union node *patp; |
@@ -2274,8 +2293,8 @@ evalcase(const union node *n, int flags) | |||
2274 | arglist.lastp = &arglist.list; | 2293 | arglist.lastp = &arglist.list; |
2275 | oexitstatus = exitstatus; | 2294 | oexitstatus = exitstatus; |
2276 | expandarg(n->ncase.expr, &arglist, EXP_TILDE); | 2295 | expandarg(n->ncase.expr, &arglist, EXP_TILDE); |
2277 | for (cp = n->ncase.cases ; cp && evalskip == 0 ; cp = cp->nclist.next) { | 2296 | for (cp = n->ncase.cases; cp && evalskip == 0; cp = cp->nclist.next) { |
2278 | for (patp = cp->nclist.pattern ; patp ; patp = patp->narg.next) { | 2297 | for (patp = cp->nclist.pattern; patp; patp = patp->narg.next) { |
2279 | if (casematch(patp, arglist.list->text)) { | 2298 | if (casematch(patp, arglist.list->text)) { |
2280 | if (evalskip == 0) { | 2299 | if (evalskip == 0) { |
2281 | evaltree(cp->nclist.body, flags); | 2300 | evaltree(cp->nclist.body, flags); |
@@ -2284,7 +2303,7 @@ evalcase(const union node *n, int flags) | |||
2284 | } | 2303 | } |
2285 | } | 2304 | } |
2286 | } | 2305 | } |
2287 | out: | 2306 | out: |
2288 | popstackmark(&smark); | 2307 | popstackmark(&smark); |
2289 | } | 2308 | } |
2290 | 2309 | ||
@@ -2303,14 +2322,14 @@ static inline void evalpipe(union node *n) | |||
2303 | int prevfd; | 2322 | int prevfd; |
2304 | int pip[2]; | 2323 | int pip[2]; |
2305 | 2324 | ||
2306 | TRACE(("evalpipe(0x%lx) called\n", (long)n)); | 2325 | TRACE(("evalpipe(0x%lx) called\n", (long) n)); |
2307 | pipelen = 0; | 2326 | pipelen = 0; |
2308 | for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) | 2327 | for (lp = n->npipe.cmdlist; lp; lp = lp->next) |
2309 | pipelen++; | 2328 | pipelen++; |
2310 | INTOFF; | 2329 | INTOFF; |
2311 | jp = makejob(n, pipelen); | 2330 | jp = makejob(n, pipelen); |
2312 | prevfd = -1; | 2331 | prevfd = -1; |
2313 | for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) { | 2332 | for (lp = n->npipe.cmdlist; lp; lp = lp->next) { |
2314 | /* | 2333 | /* |
2315 | * Search for a command. This is called before we fork so that the | 2334 | * Search for a command. This is called before we fork so that the |
2316 | * location of the command will be available in the parent as well as | 2335 | * location of the command will be available in the parent as well as |
@@ -2320,7 +2339,9 @@ static inline void evalpipe(union node *n) | |||
2320 | 2339 | ||
2321 | struct cmdentry entry; | 2340 | struct cmdentry entry; |
2322 | union node *lpn = lp->n; | 2341 | union node *lpn = lp->n; |
2323 | if (lpn->type == NCMD && lpn->ncmd.args && goodname(lpn->ncmd.args->narg.text)) | 2342 | |
2343 | if (lpn->type == NCMD && lpn->ncmd.args | ||
2344 | && goodname(lpn->ncmd.args->narg.text)) | ||
2324 | find_command(lpn->ncmd.args->narg.text, &entry, 0, pathval()); | 2345 | find_command(lpn->ncmd.args->narg.text, &entry, 0, pathval()); |
2325 | 2346 | ||
2326 | pip[1] = -1; | 2347 | pip[1] = -1; |
@@ -2366,8 +2387,8 @@ static inline void evalpipe(union node *n) | |||
2366 | } | 2387 | } |
2367 | } | 2388 | } |
2368 | 2389 | ||
2369 | static int | 2390 | static int isassignment(const char *word) |
2370 | isassignment(const char *word) { | 2391 | { |
2371 | if (!is_name(*word)) { | 2392 | if (!is_name(*word)) { |
2372 | return 0; | 2393 | return 0; |
2373 | } | 2394 | } |
@@ -2378,8 +2399,7 @@ isassignment(const char *word) { | |||
2378 | } | 2399 | } |
2379 | 2400 | ||
2380 | 2401 | ||
2381 | static void | 2402 | static void evalcommand(union node *cmd, int flags) |
2382 | evalcommand(union node *cmd, int flags) | ||
2383 | { | 2403 | { |
2384 | struct stackmark smark; | 2404 | struct stackmark smark; |
2385 | union node *argp; | 2405 | union node *argp; |
@@ -2401,6 +2421,7 @@ evalcommand(union node *cmd, int flags) | |||
2401 | const struct builtincmd *firstbltin; | 2421 | const struct builtincmd *firstbltin; |
2402 | struct jmploc *volatile savehandler; | 2422 | struct jmploc *volatile savehandler; |
2403 | struct jmploc jmploc; | 2423 | struct jmploc jmploc; |
2424 | |||
2404 | #if __GNUC__ | 2425 | #if __GNUC__ |
2405 | /* Avoid longjmp clobbering */ | 2426 | /* Avoid longjmp clobbering */ |
2406 | (void) &argv; | 2427 | (void) &argv; |
@@ -2410,7 +2431,7 @@ evalcommand(union node *cmd, int flags) | |||
2410 | #endif | 2431 | #endif |
2411 | 2432 | ||
2412 | /* First expand the arguments. */ | 2433 | /* First expand the arguments. */ |
2413 | TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags)); | 2434 | TRACE(("evalcommand(0x%lx, %d) called\n", (long) cmd, flags)); |
2414 | setstackmark(&smark); | 2435 | setstackmark(&smark); |
2415 | arglist.lastp = &arglist.list; | 2436 | arglist.lastp = &arglist.list; |
2416 | varlist.lastp = &varlist.list; | 2437 | varlist.lastp = &varlist.list; |
@@ -2421,15 +2442,13 @@ evalcommand(union node *cmd, int flags) | |||
2421 | for (argp = cmd->ncmd.assign; argp; argp = argp->narg.next) { | 2442 | for (argp = cmd->ncmd.assign; argp; argp = argp->narg.next) { |
2422 | expandarg(argp, &varlist, EXP_VARTILDE); | 2443 | expandarg(argp, &varlist, EXP_VARTILDE); |
2423 | } | 2444 | } |
2424 | for ( | 2445 | for (argp = cmd->ncmd.args; argp && !arglist.list; argp = argp->narg.next) { |
2425 | argp = cmd->ncmd.args; argp && !arglist.list; | ||
2426 | argp = argp->narg.next | ||
2427 | ) { | ||
2428 | expandarg(argp, &arglist, EXP_FULL | EXP_TILDE); | 2446 | expandarg(argp, &arglist, EXP_FULL | EXP_TILDE); |
2429 | } | 2447 | } |
2430 | if (argp) { | 2448 | if (argp) { |
2431 | struct builtincmd *bcmd; | 2449 | struct builtincmd *bcmd; |
2432 | int pseudovarflag; | 2450 | int pseudovarflag; |
2451 | |||
2433 | bcmd = find_builtin(arglist.list->text); | 2452 | bcmd = find_builtin(arglist.list->text); |
2434 | pseudovarflag = bcmd && IS_BUILTIN_ASSIGN(bcmd); | 2453 | pseudovarflag = bcmd && IS_BUILTIN_ASSIGN(bcmd); |
2435 | for (; argp; argp = argp->narg.next) { | 2454 | for (; argp; argp = argp->narg.next) { |
@@ -2444,11 +2463,11 @@ evalcommand(union node *cmd, int flags) | |||
2444 | *varlist.lastp = NULL; | 2463 | *varlist.lastp = NULL; |
2445 | expredir(cmd->ncmd.redirect); | 2464 | expredir(cmd->ncmd.redirect); |
2446 | argc = 0; | 2465 | argc = 0; |
2447 | for (sp = arglist.list ; sp ; sp = sp->next) | 2466 | for (sp = arglist.list; sp; sp = sp->next) |
2448 | argc++; | 2467 | argc++; |
2449 | argv = stalloc(sizeof (char *) * (argc + 1)); | 2468 | argv = stalloc(sizeof(char *) * (argc + 1)); |
2450 | 2469 | ||
2451 | for (sp = arglist.list ; sp ; sp = sp->next) { | 2470 | for (sp = arglist.list; sp; sp = sp->next) { |
2452 | TRACE(("evalcommand arg: %s\n", sp->text)); | 2471 | TRACE(("evalcommand arg: %s\n", sp->text)); |
2453 | *argv++ = sp->text; | 2472 | *argv++ = sp->text; |
2454 | } | 2473 | } |
@@ -2479,7 +2498,7 @@ evalcommand(union node *cmd, int flags) | |||
2479 | * Modify the command lookup path, if a PATH= assignment | 2498 | * Modify the command lookup path, if a PATH= assignment |
2480 | * is present | 2499 | * is present |
2481 | */ | 2500 | */ |
2482 | for (sp = varlist.list ; sp ; sp = sp->next) | 2501 | for (sp = varlist.list; sp; sp = sp->next) |
2483 | if (varequal(sp->text, defpathvar)) { | 2502 | if (varequal(sp->text, defpathvar)) { |
2484 | path = sp->text + 5; | 2503 | path = sp->text + 5; |
2485 | findflag |= DO_BRUTE; | 2504 | findflag |= DO_BRUTE; |
@@ -2487,9 +2506,9 @@ evalcommand(union node *cmd, int flags) | |||
2487 | oldpath = path; | 2506 | oldpath = path; |
2488 | oldfindflag = findflag; | 2507 | oldfindflag = findflag; |
2489 | firstbltin = 0; | 2508 | firstbltin = 0; |
2490 | for(;;) { | 2509 | for (;;) { |
2491 | find_command(argv[0], &cmdentry, findflag, path); | 2510 | find_command(argv[0], &cmdentry, findflag, path); |
2492 | if (cmdentry.cmdtype == CMDUNKNOWN) { /* command not found */ | 2511 | if (cmdentry.cmdtype == CMDUNKNOWN) { /* command not found */ |
2493 | exitstatus = 127; | 2512 | exitstatus = 127; |
2494 | goto out; | 2513 | goto out; |
2495 | } | 2514 | } |
@@ -2501,7 +2520,7 @@ evalcommand(union node *cmd, int flags) | |||
2501 | firstbltin = cmdentry.u.cmd; | 2520 | firstbltin = cmdentry.u.cmd; |
2502 | } | 2521 | } |
2503 | if (cmdentry.u.cmd == BLTINCMD) { | 2522 | if (cmdentry.u.cmd == BLTINCMD) { |
2504 | for(;;) { | 2523 | for (;;) { |
2505 | struct builtincmd *bcmd; | 2524 | struct builtincmd *bcmd; |
2506 | 2525 | ||
2507 | argv++; | 2526 | argv++; |
@@ -2541,19 +2560,19 @@ evalcommand(union node *cmd, int flags) | |||
2541 | findflag |= DO_NOFUN; | 2560 | findflag |= DO_NOFUN; |
2542 | continue; | 2561 | continue; |
2543 | } | 2562 | } |
2544 | found: | 2563 | found: |
2545 | break; | 2564 | break; |
2546 | } | 2565 | } |
2547 | } | 2566 | } |
2548 | 2567 | ||
2549 | /* Fork off a child process if necessary. */ | 2568 | /* Fork off a child process if necessary. */ |
2550 | if (cmd->ncmd.backgnd | 2569 | if (cmd->ncmd.backgnd |
2551 | || (cmdentry.cmdtype == CMDNORMAL && (flags & EV_EXIT) == 0) | 2570 | || (cmdentry.cmdtype == CMDNORMAL && (flags & EV_EXIT) == 0) |
2552 | ) { | 2571 | ) { |
2553 | jp = makejob(cmd, 1); | 2572 | jp = makejob(cmd, 1); |
2554 | mode = cmd->ncmd.backgnd; | 2573 | mode = cmd->ncmd.backgnd; |
2555 | if (forkshell(jp, cmd, mode) != 0) | 2574 | if (forkshell(jp, cmd, mode) != 0) |
2556 | goto parent; /* at end of routine */ | 2575 | goto parent; /* at end of routine */ |
2557 | flags |= EV_EXIT; | 2576 | flags |= EV_EXIT; |
2558 | } | 2577 | } |
2559 | 2578 | ||
@@ -2561,7 +2580,8 @@ found: | |||
2561 | /* Execute the command. */ | 2580 | /* Execute the command. */ |
2562 | if (cmdentry.cmdtype == CMDFUNCTION) { | 2581 | if (cmdentry.cmdtype == CMDFUNCTION) { |
2563 | #ifdef DEBUG | 2582 | #ifdef DEBUG |
2564 | trputs("Shell function: "); trargs(argv); | 2583 | trputs("Shell function: "); |
2584 | trargs(argv); | ||
2565 | #endif | 2585 | #endif |
2566 | exitstatus = oexitstatus; | 2586 | exitstatus = oexitstatus; |
2567 | redirect(cmd->ncmd.redirect, REDIR_PUSH); | 2587 | redirect(cmd->ncmd.redirect, REDIR_PUSH); |
@@ -2576,7 +2596,7 @@ found: | |||
2576 | if (setjmp(jmploc.loc)) { | 2596 | if (setjmp(jmploc.loc)) { |
2577 | if (exception == EXSHELLPROC) { | 2597 | if (exception == EXSHELLPROC) { |
2578 | freeparam((volatile struct shparam *) | 2598 | freeparam((volatile struct shparam *) |
2579 | &saveparam); | 2599 | &saveparam); |
2580 | } else { | 2600 | } else { |
2581 | saveparam.optind = shellparam.optind; | 2601 | saveparam.optind = shellparam.optind; |
2582 | saveparam.optoff = shellparam.optoff; | 2602 | saveparam.optoff = shellparam.optoff; |
@@ -2590,7 +2610,7 @@ found: | |||
2590 | } | 2610 | } |
2591 | savehandler = handler; | 2611 | savehandler = handler; |
2592 | handler = &jmploc; | 2612 | handler = &jmploc; |
2593 | for (sp = varlist.list ; sp ; sp = sp->next) | 2613 | for (sp = varlist.list; sp; sp = sp->next) |
2594 | mklocal(sp->text); | 2614 | mklocal(sp->text); |
2595 | funcnest++; | 2615 | funcnest++; |
2596 | evaltree(cmdentry.u.func, flags & EV_TESTED); | 2616 | evaltree(cmdentry.u.func, flags & EV_TESTED); |
@@ -2613,9 +2633,10 @@ found: | |||
2613 | exitshell(exitstatus); | 2633 | exitshell(exitstatus); |
2614 | } else if (cmdentry.cmdtype == CMDBUILTIN) { | 2634 | } else if (cmdentry.cmdtype == CMDBUILTIN) { |
2615 | #ifdef DEBUG | 2635 | #ifdef DEBUG |
2616 | trputs("builtin command: "); trargs(argv); | 2636 | trputs("builtin command: "); |
2637 | trargs(argv); | ||
2617 | #endif | 2638 | #endif |
2618 | mode = (cmdentry.u.cmd == EXECCMD)? 0 : REDIR_PUSH; | 2639 | mode = (cmdentry.u.cmd == EXECCMD) ? 0 : REDIR_PUSH; |
2619 | redirect(cmd->ncmd.redirect, mode); | 2640 | redirect(cmd->ncmd.redirect, mode); |
2620 | savecmdname = commandname; | 2641 | savecmdname = commandname; |
2621 | if (IS_BUILTIN_SPECIAL(firstbltin)) { | 2642 | if (IS_BUILTIN_SPECIAL(firstbltin)) { |
@@ -2626,17 +2647,17 @@ found: | |||
2626 | e = -1; | 2647 | e = -1; |
2627 | if (setjmp(jmploc.loc)) { | 2648 | if (setjmp(jmploc.loc)) { |
2628 | e = exception; | 2649 | e = exception; |
2629 | exitstatus = (e == EXINT)? SIGINT+128 : 2; | 2650 | exitstatus = (e == EXINT) ? SIGINT + 128 : 2; |
2630 | goto cmddone; | 2651 | goto cmddone; |
2631 | } | 2652 | } |
2632 | savehandler = handler; | 2653 | savehandler = handler; |
2633 | handler = &jmploc; | 2654 | handler = &jmploc; |
2634 | commandname = argv[0]; | 2655 | commandname = argv[0]; |
2635 | argptr = argv + 1; | 2656 | argptr = argv + 1; |
2636 | optptr = NULL; /* initialize nextopt */ | 2657 | optptr = NULL; /* initialize nextopt */ |
2637 | exitstatus = (*cmdentry.u.cmd->builtinfunc)(argc, argv); | 2658 | exitstatus = (*cmdentry.u.cmd->builtinfunc) (argc, argv); |
2638 | flushall(); | 2659 | flushall(); |
2639 | cmddone: | 2660 | cmddone: |
2640 | cmdenviron = NULL; | 2661 | cmdenviron = NULL; |
2641 | if (e != EXSHELLPROC) { | 2662 | if (e != EXSHELLPROC) { |
2642 | commandname = savecmdname; | 2663 | commandname = savecmdname; |
@@ -2646,10 +2667,9 @@ cmddone: | |||
2646 | handler = savehandler; | 2667 | handler = savehandler; |
2647 | if (e != -1) { | 2668 | if (e != -1) { |
2648 | if ((e != EXERROR && e != EXEXEC) | 2669 | if ((e != EXERROR && e != EXEXEC) |
2649 | || cmdentry.u.cmd == BLTINCMD | 2670 | || cmdentry.u.cmd == BLTINCMD |
2650 | || cmdentry.u.cmd == DOTCMD | 2671 | || cmdentry.u.cmd == DOTCMD |
2651 | || cmdentry.u.cmd == EVALCMD | 2672 | || cmdentry.u.cmd == EVALCMD || cmdentry.u.cmd == EXECCMD) |
2652 | || cmdentry.u.cmd == EXECCMD) | ||
2653 | exraise(e); | 2673 | exraise(e); |
2654 | FORCEINTON; | 2674 | FORCEINTON; |
2655 | } | 2675 | } |
@@ -2657,25 +2677,26 @@ cmddone: | |||
2657 | popredir(); | 2677 | popredir(); |
2658 | } else { | 2678 | } else { |
2659 | #ifdef DEBUG | 2679 | #ifdef DEBUG |
2660 | trputs("normal command: "); trargs(argv); | 2680 | trputs("normal command: "); |
2681 | trargs(argv); | ||
2661 | #endif | 2682 | #endif |
2662 | redirect(cmd->ncmd.redirect, 0); | 2683 | redirect(cmd->ncmd.redirect, 0); |
2663 | clearredir(); | 2684 | clearredir(); |
2664 | for (sp = varlist.list ; sp ; sp = sp->next) | 2685 | for (sp = varlist.list; sp; sp = sp->next) |
2665 | setvareq(sp->text, VEXPORT|VSTACK); | 2686 | setvareq(sp->text, VEXPORT | VSTACK); |
2666 | envp = environment(); | 2687 | envp = environment(); |
2667 | shellexec(argv, envp, path, cmdentry.u.index); | 2688 | shellexec(argv, envp, path, cmdentry.u.index); |
2668 | } | 2689 | } |
2669 | goto out; | 2690 | goto out; |
2670 | 2691 | ||
2671 | parent: /* parent process gets here (if we forked) */ | 2692 | parent: /* parent process gets here (if we forked) */ |
2672 | if (mode == 0) { /* argument to fork */ | 2693 | if (mode == 0) { /* argument to fork */ |
2673 | INTOFF; | 2694 | INTOFF; |
2674 | exitstatus = waitforjob(jp); | 2695 | exitstatus = waitforjob(jp); |
2675 | INTON; | 2696 | INTON; |
2676 | } | 2697 | } |
2677 | 2698 | ||
2678 | out: | 2699 | out: |
2679 | if (lastarg) | 2700 | if (lastarg) |
2680 | setvar("_", lastarg, 0); | 2701 | setvar("_", lastarg, 0); |
2681 | popstackmark(&smark); | 2702 | popstackmark(&smark); |
@@ -2685,15 +2706,15 @@ out: | |||
2685 | * Evaluate a parse tree. The value is left in the global variable | 2706 | * Evaluate a parse tree. The value is left in the global variable |
2686 | * exitstatus. | 2707 | * exitstatus. |
2687 | */ | 2708 | */ |
2688 | static void | 2709 | static void evaltree(union node *n, int flags) |
2689 | evaltree(union node *n, int flags) | ||
2690 | { | 2710 | { |
2691 | int checkexit = 0; | 2711 | int checkexit = 0; |
2712 | |||
2692 | if (n == NULL) { | 2713 | if (n == NULL) { |
2693 | TRACE(("evaltree(NULL) called\n")); | 2714 | TRACE(("evaltree(NULL) called\n")); |
2694 | goto out; | 2715 | goto out; |
2695 | } | 2716 | } |
2696 | TRACE(("evaltree(0x%lx: %d) called\n", (long)n, n->type)); | 2717 | TRACE(("evaltree(0x%lx: %d) called\n", (long) n, n->type)); |
2697 | switch (n->type) { | 2718 | switch (n->type) { |
2698 | case NSEMI: | 2719 | case NSEMI: |
2699 | evaltree(n->nbinary.ch1, flags & EV_TESTED); | 2720 | evaltree(n->nbinary.ch1, flags & EV_TESTED); |
@@ -2725,7 +2746,7 @@ evaltree(union node *n, int flags) | |||
2725 | case NBACKGND: | 2746 | case NBACKGND: |
2726 | evalsubshell(n, flags); | 2747 | evalsubshell(n, flags); |
2727 | break; | 2748 | break; |
2728 | case NIF: { | 2749 | case NIF:{ |
2729 | evaltree(n->nif.test, EV_TESTED); | 2750 | evaltree(n->nif.test, EV_TESTED); |
2730 | if (evalskip) | 2751 | if (evalskip) |
2731 | goto out; | 2752 | goto out; |
@@ -2747,13 +2768,12 @@ evaltree(union node *n, int flags) | |||
2747 | case NCASE: | 2768 | case NCASE: |
2748 | evalcase(n, flags); | 2769 | evalcase(n, flags); |
2749 | break; | 2770 | break; |
2750 | case NDEFUN: { | 2771 | case NDEFUN:{ |
2751 | struct builtincmd *bcmd; | 2772 | struct builtincmd *bcmd; |
2752 | struct cmdentry entry; | 2773 | struct cmdentry entry; |
2753 | if ( | 2774 | |
2754 | (bcmd = find_builtin(n->narg.text)) && | 2775 | if ((bcmd = find_builtin(n->narg.text)) && IS_BUILTIN_SPECIAL(bcmd) |
2755 | IS_BUILTIN_SPECIAL(bcmd) | 2776 | ) { |
2756 | ) { | ||
2757 | out2fmt("%s is a special built-in\n", n->narg.text); | 2777 | out2fmt("%s is a special built-in\n", n->narg.text); |
2758 | exitstatus = 1; | 2778 | exitstatus = 1; |
2759 | break; | 2779 | break; |
@@ -2783,13 +2803,12 @@ evaltree(union node *n, int flags) | |||
2783 | break; | 2803 | break; |
2784 | #endif | 2804 | #endif |
2785 | } | 2805 | } |
2786 | out: | 2806 | out: |
2787 | if (pendingsigs) | 2807 | if (pendingsigs) |
2788 | dotrap(); | 2808 | dotrap(); |
2789 | if ( | 2809 | if (flags & EV_EXIT || |
2790 | flags & EV_EXIT || | ||
2791 | (checkexit && eflag && exitstatus && !(flags & EV_TESTED)) | 2810 | (checkexit && eflag && exitstatus && !(flags & EV_TESTED)) |
2792 | ) | 2811 | ) |
2793 | exitshell(exitstatus); | 2812 | exitshell(exitstatus); |
2794 | } | 2813 | } |
2795 | 2814 | ||
@@ -2797,8 +2816,7 @@ out: | |||
2797 | * Kick off a subshell to evaluate a tree. | 2816 | * Kick off a subshell to evaluate a tree. |
2798 | */ | 2817 | */ |
2799 | 2818 | ||
2800 | static void | 2819 | static void evalsubshell(const union node *n, int flags) |
2801 | evalsubshell(const union node *n, int flags) | ||
2802 | { | 2820 | { |
2803 | struct job *jp; | 2821 | struct job *jp; |
2804 | int backgnd = (n->type == NBACKGND); | 2822 | int backgnd = (n->type == NBACKGND); |
@@ -2807,11 +2825,11 @@ evalsubshell(const union node *n, int flags) | |||
2807 | jp = makejob(n, 1); | 2825 | jp = makejob(n, 1); |
2808 | if (forkshell(jp, n, backgnd) == 0) { | 2826 | if (forkshell(jp, n, backgnd) == 0) { |
2809 | if (backgnd) | 2827 | if (backgnd) |
2810 | flags &=~ EV_TESTED; | 2828 | flags &= ~EV_TESTED; |
2811 | redirect(n->nredir.redirect, 0); | 2829 | redirect(n->nredir.redirect, 0); |
2812 | evaltree(n->nredir.n, flags | EV_EXIT); /* never returns */ | 2830 | evaltree(n->nredir.n, flags | EV_EXIT); /* never returns */ |
2813 | } | 2831 | } |
2814 | if (! backgnd) { | 2832 | if (!backgnd) { |
2815 | INTOFF; | 2833 | INTOFF; |
2816 | exitstatus = waitforjob(jp); | 2834 | exitstatus = waitforjob(jp); |
2817 | INTON; | 2835 | INTON; |
@@ -2824,13 +2842,13 @@ evalsubshell(const union node *n, int flags) | |||
2824 | 2842 | ||
2825 | static void fixredir(union node *n, const char *text, int err); | 2843 | static void fixredir(union node *n, const char *text, int err); |
2826 | 2844 | ||
2827 | static void | 2845 | static void expredir(union node *n) |
2828 | expredir(union node *n) | ||
2829 | { | 2846 | { |
2830 | union node *redir; | 2847 | union node *redir; |
2831 | 2848 | ||
2832 | for (redir = n ; redir ; redir = redir->nfile.next) { | 2849 | for (redir = n; redir; redir = redir->nfile.next) { |
2833 | struct arglist fn; | 2850 | struct arglist fn; |
2851 | |||
2834 | fn.lastp = &fn.list; | 2852 | fn.lastp = &fn.list; |
2835 | oexitstatus = exitstatus; | 2853 | oexitstatus = exitstatus; |
2836 | switch (redir->type) { | 2854 | switch (redir->type) { |
@@ -2861,12 +2879,11 @@ expredir(union node *n) | |||
2861 | * Should be called with interrupts off. | 2879 | * Should be called with interrupts off. |
2862 | */ | 2880 | */ |
2863 | 2881 | ||
2864 | static void | 2882 | static void evalbackcmd(union node *n, struct backcmd *result) |
2865 | evalbackcmd(union node *n, struct backcmd *result) | ||
2866 | { | 2883 | { |
2867 | int pip[2]; | 2884 | int pip[2]; |
2868 | struct job *jp; | 2885 | struct job *jp; |
2869 | struct stackmark smark; /* unnecessary */ | 2886 | struct stackmark smark; /* unnecessary */ |
2870 | 2887 | ||
2871 | setstackmark(&smark); | 2888 | setstackmark(&smark); |
2872 | result->fd = -1; | 2889 | result->fd = -1; |
@@ -2895,10 +2912,10 @@ evalbackcmd(union node *n, struct backcmd *result) | |||
2895 | close(pip[1]); | 2912 | close(pip[1]); |
2896 | result->fd = pip[0]; | 2913 | result->fd = pip[0]; |
2897 | result->jp = jp; | 2914 | result->jp = jp; |
2898 | out: | 2915 | out: |
2899 | popstackmark(&smark); | 2916 | popstackmark(&smark); |
2900 | TRACE(("evalbackcmd done: fd=%d buf=0x%x nleft=%d jp=0x%x\n", | 2917 | TRACE(("evalbackcmd done: fd=%d buf=0x%x nleft=%d jp=0x%x\n", |
2901 | result->fd, result->buf, result->nleft, result->jp)); | 2918 | result->fd, result->buf, result->nleft, result->jp)); |
2902 | } | 2919 | } |
2903 | 2920 | ||
2904 | 2921 | ||
@@ -2917,8 +2934,7 @@ out: | |||
2917 | * specified variables. | 2934 | * specified variables. |
2918 | */ | 2935 | */ |
2919 | 2936 | ||
2920 | int | 2937 | int bltincmd(int argc, char **argv) |
2921 | bltincmd(int argc, char **argv) | ||
2922 | { | 2938 | { |
2923 | /* | 2939 | /* |
2924 | * Preserve exitstatus of a previous possible redirection | 2940 | * Preserve exitstatus of a previous possible redirection |
@@ -2939,8 +2955,7 @@ bltincmd(int argc, char **argv) | |||
2939 | * in the standard shell so we don't make it one here. | 2955 | * in the standard shell so we don't make it one here. |
2940 | */ | 2956 | */ |
2941 | 2957 | ||
2942 | static int | 2958 | static int breakcmd(int argc, char **argv) |
2943 | breakcmd(int argc, char **argv) | ||
2944 | { | 2959 | { |
2945 | int n = argc > 1 ? number(argv[1]) : 1; | 2960 | int n = argc > 1 ? number(argv[1]) : 1; |
2946 | 2961 | ||
@@ -2949,7 +2964,7 @@ breakcmd(int argc, char **argv) | |||
2949 | if (n > loopnest) | 2964 | if (n > loopnest) |
2950 | n = loopnest; | 2965 | n = loopnest; |
2951 | if (n > 0) { | 2966 | if (n > 0) { |
2952 | evalskip = (**argv == 'c')? SKIPCONT : SKIPBREAK; | 2967 | evalskip = (**argv == 'c') ? SKIPCONT : SKIPBREAK; |
2953 | skipcount = n; | 2968 | skipcount = n; |
2954 | } | 2969 | } |
2955 | return 0; | 2970 | return 0; |
@@ -2960,8 +2975,7 @@ breakcmd(int argc, char **argv) | |||
2960 | * The return command. | 2975 | * The return command. |
2961 | */ | 2976 | */ |
2962 | 2977 | ||
2963 | static int | 2978 | static int returncmd(int argc, char **argv) |
2964 | returncmd(int argc, char **argv) | ||
2965 | { | 2979 | { |
2966 | int ret = argc > 1 ? number(argv[1]) : oexitstatus; | 2980 | int ret = argc > 1 ? number(argv[1]) : oexitstatus; |
2967 | 2981 | ||
@@ -2969,8 +2983,7 @@ returncmd(int argc, char **argv) | |||
2969 | evalskip = SKIPFUNC; | 2983 | evalskip = SKIPFUNC; |
2970 | skipcount = 1; | 2984 | skipcount = 1; |
2971 | return ret; | 2985 | return ret; |
2972 | } | 2986 | } else { |
2973 | else { | ||
2974 | /* Do what ksh does; skip the rest of the file */ | 2987 | /* Do what ksh does; skip the rest of the file */ |
2975 | evalskip = SKIPFILE; | 2988 | evalskip = SKIPFILE; |
2976 | skipcount = 1; | 2989 | skipcount = 1; |
@@ -2980,16 +2993,14 @@ returncmd(int argc, char **argv) | |||
2980 | 2993 | ||
2981 | 2994 | ||
2982 | #ifndef CONFIG_FALSE | 2995 | #ifndef CONFIG_FALSE |
2983 | static int | 2996 | static int false_main(int argc, char **argv) |
2984 | false_main(int argc, char **argv) | ||
2985 | { | 2997 | { |
2986 | return 1; | 2998 | return 1; |
2987 | } | 2999 | } |
2988 | #endif | 3000 | #endif |
2989 | 3001 | ||
2990 | #ifndef CONFIG_TRUE | 3002 | #ifndef CONFIG_TRUE |
2991 | static int | 3003 | static int true_main(int argc, char **argv) |
2992 | true_main(int argc, char **argv) | ||
2993 | { | 3004 | { |
2994 | return 0; | 3005 | return 0; |
2995 | } | 3006 | } |
@@ -3005,11 +3016,10 @@ static void setsignal(int signo); | |||
3005 | static void chkmail(int silent); | 3016 | static void chkmail(int silent); |
3006 | #endif | 3017 | #endif |
3007 | 3018 | ||
3008 | static void | 3019 | static void setinteractive(int on) |
3009 | setinteractive(int on) | ||
3010 | { | 3020 | { |
3011 | static int is_interactive; | 3021 | static int is_interactive; |
3012 | static int do_banner=0; | 3022 | static int do_banner = 0; |
3013 | 3023 | ||
3014 | if (on == is_interactive) | 3024 | if (on == is_interactive) |
3015 | return; | 3025 | return; |
@@ -3020,45 +3030,42 @@ setinteractive(int on) | |||
3020 | chkmail(1); | 3030 | chkmail(1); |
3021 | #endif | 3031 | #endif |
3022 | is_interactive = on; | 3032 | is_interactive = on; |
3023 | if (do_banner==0 && is_interactive) { | 3033 | if (do_banner == 0 && is_interactive) { |
3024 | /* Looks like they want an interactive shell */ | 3034 | /* Looks like they want an interactive shell */ |
3025 | #ifndef CONFIG_FEATURE_SH_EXTRA_QUIET | 3035 | #ifndef CONFIG_FEATURE_SH_EXTRA_QUIET |
3026 | printf( "\n\n" BB_BANNER " Built-in shell (ash)\n"); | 3036 | printf("\n\n" BB_BANNER " Built-in shell (ash)\n"); |
3027 | printf( "Enter 'help' for a list of built-in commands.\n\n"); | 3037 | printf("Enter 'help' for a list of built-in commands.\n\n"); |
3028 | #endif | 3038 | #endif |
3029 | do_banner=1; | 3039 | do_banner = 1; |
3030 | } | 3040 | } |
3031 | } | 3041 | } |
3032 | 3042 | ||
3033 | static void | 3043 | static void optschanged(void) |
3034 | optschanged(void) | ||
3035 | { | 3044 | { |
3036 | setinteractive(iflag); | 3045 | setinteractive(iflag); |
3037 | setjobctl(mflag); | 3046 | setjobctl(mflag); |
3038 | } | 3047 | } |
3039 | 3048 | ||
3040 | 3049 | ||
3041 | static int | 3050 | static int execcmd(int argc, char **argv) |
3042 | execcmd(int argc, char **argv) | ||
3043 | { | 3051 | { |
3044 | if (argc > 1) { | 3052 | if (argc > 1) { |
3045 | struct strlist *sp; | 3053 | struct strlist *sp; |
3046 | 3054 | ||
3047 | iflag = 0; /* exit on error */ | 3055 | iflag = 0; /* exit on error */ |
3048 | mflag = 0; | 3056 | mflag = 0; |
3049 | optschanged(); | 3057 | optschanged(); |
3050 | for (sp = cmdenviron; sp ; sp = sp->next) | 3058 | for (sp = cmdenviron; sp; sp = sp->next) |
3051 | setvareq(sp->text, VEXPORT|VSTACK); | 3059 | setvareq(sp->text, VEXPORT | VSTACK); |
3052 | shellexec(argv + 1, environment(), pathval(), 0); | 3060 | shellexec(argv + 1, environment(), pathval(), 0); |
3053 | } | 3061 | } |
3054 | return 0; | 3062 | return 0; |
3055 | } | 3063 | } |
3056 | 3064 | ||
3057 | static void | 3065 | static void eprintlist(struct strlist *sp) |
3058 | eprintlist(struct strlist *sp) | ||
3059 | { | 3066 | { |
3060 | for (; sp; sp = sp->next) { | 3067 | for (; sp; sp = sp->next) { |
3061 | out2fmt(" %s",sp->text); | 3068 | out2fmt(" %s", sp->text); |
3062 | } | 3069 | } |
3063 | } | 3070 | } |
3064 | 3071 | ||
@@ -3067,10 +3074,9 @@ eprintlist(struct strlist *sp) | |||
3067 | * have to change the find_command routine as well. | 3074 | * have to change the find_command routine as well. |
3068 | */ | 3075 | */ |
3069 | 3076 | ||
3070 | static const char *pathopt; /* set by padvance */ | 3077 | static const char *pathopt; /* set by padvance */ |
3071 | 3078 | ||
3072 | static void | 3079 | static void shellexec(char **argv, char **envp, const char *path, int idx) |
3073 | shellexec(char **argv, char **envp, const char *path, int idx) | ||
3074 | { | 3080 | { |
3075 | char *cmdname; | 3081 | char *cmdname; |
3076 | int e; | 3082 | int e; |
@@ -3109,13 +3115,12 @@ shellexec(char **argv, char **envp, const char *path, int idx) | |||
3109 | /* | 3115 | /* |
3110 | * Clear traps on a fork. | 3116 | * Clear traps on a fork. |
3111 | */ | 3117 | */ |
3112 | static void | 3118 | static void clear_traps(void) |
3113 | clear_traps(void) | ||
3114 | { | 3119 | { |
3115 | char **tp; | 3120 | char **tp; |
3116 | 3121 | ||
3117 | for (tp = trap ; tp < &trap[NSIG] ; tp++) { | 3122 | for (tp = trap; tp < &trap[NSIG]; tp++) { |
3118 | if (*tp && **tp) { /* trap not NULL or SIG_IGN */ | 3123 | if (*tp && **tp) { /* trap not NULL or SIG_IGN */ |
3119 | INTOFF; | 3124 | INTOFF; |
3120 | free(*tp); | 3125 | free(*tp); |
3121 | *tp = NULL; | 3126 | *tp = NULL; |
@@ -3127,68 +3132,67 @@ clear_traps(void) | |||
3127 | } | 3132 | } |
3128 | 3133 | ||
3129 | 3134 | ||
3130 | static void | 3135 | static void initshellproc(void) |
3131 | initshellproc(void) | ||
3132 | { | 3136 | { |
3133 | 3137 | ||
3134 | #ifdef CONFIG_ASH_ALIAS | 3138 | #ifdef CONFIG_ASH_ALIAS |
3135 | /* from alias.c: */ | 3139 | /* from alias.c: */ |
3136 | { | 3140 | { |
3137 | rmaliases(); | 3141 | rmaliases(); |
3138 | } | 3142 | } |
3139 | #endif | 3143 | #endif |
3140 | /* from eval.c: */ | 3144 | /* from eval.c: */ |
3141 | { | 3145 | { |
3142 | exitstatus = 0; | 3146 | exitstatus = 0; |
3143 | } | 3147 | } |
3144 | 3148 | ||
3145 | /* from exec.c: */ | 3149 | /* from exec.c: */ |
3146 | { | 3150 | { |
3147 | deletefuncs(); | 3151 | deletefuncs(); |
3148 | } | 3152 | } |
3149 | 3153 | ||
3150 | /* from jobs.c: */ | 3154 | /* from jobs.c: */ |
3151 | { | 3155 | { |
3152 | backgndpid = -1; | 3156 | backgndpid = -1; |
3153 | #ifdef CONFIG_ASH_JOB_CONTROL | 3157 | #ifdef CONFIG_ASH_JOB_CONTROL |
3154 | jobctl = 0; | 3158 | jobctl = 0; |
3155 | #endif | 3159 | #endif |
3156 | } | 3160 | } |
3157 | 3161 | ||
3158 | /* from options.c: */ | 3162 | /* from options.c: */ |
3159 | { | 3163 | { |
3160 | int i; | 3164 | int i; |
3161 | 3165 | ||
3162 | for (i = 0; i < NOPTS; i++) | 3166 | for (i = 0; i < NOPTS; i++) |
3163 | optent_val(i) = 0; | 3167 | optent_val(i) = 0; |
3164 | optschanged(); | 3168 | optschanged(); |
3165 | 3169 | ||
3166 | } | 3170 | } |
3167 | 3171 | ||
3168 | /* from redir.c: */ | 3172 | /* from redir.c: */ |
3169 | { | 3173 | { |
3170 | clearredir(); | 3174 | clearredir(); |
3171 | } | 3175 | } |
3172 | 3176 | ||
3173 | /* from trap.c: */ | 3177 | /* from trap.c: */ |
3174 | { | 3178 | { |
3175 | char *sm; | 3179 | char *sm; |
3176 | 3180 | ||
3177 | clear_traps(); | 3181 | clear_traps(); |
3178 | for (sm = sigmode ; sm < sigmode + NSIG - 1; sm++) { | 3182 | for (sm = sigmode; sm < sigmode + NSIG - 1; sm++) { |
3179 | if (*sm == S_IGN) | 3183 | if (*sm == S_IGN) |
3180 | *sm = S_HARD_IGN; | 3184 | *sm = S_HARD_IGN; |
3181 | } | 3185 | } |
3182 | } | 3186 | } |
3183 | 3187 | ||
3184 | /* from var.c: */ | 3188 | /* from var.c: */ |
3185 | { | 3189 | { |
3186 | shprocvar(); | 3190 | shprocvar(); |
3187 | } | 3191 | } |
3188 | } | 3192 | } |
3189 | 3193 | ||
3190 | static int preadbuffer(void); | 3194 | static int preadbuffer(void); |
3191 | static void pushfile (void); | 3195 | static void pushfile(void); |
3192 | 3196 | ||
3193 | /* | 3197 | /* |
3194 | * Read a character from the script, returning PEOF on end of file. | 3198 | * Read a character from the script, returning PEOF on end of file. |
@@ -3197,20 +3201,17 @@ static void pushfile (void); | |||
3197 | 3201 | ||
3198 | #ifndef CONFIG_ASH_OPTIMIZE_FOR_SIZE | 3202 | #ifndef CONFIG_ASH_OPTIMIZE_FOR_SIZE |
3199 | #define pgetc_macro() (--parsenleft >= 0? *parsenextc++ : preadbuffer()) | 3203 | #define pgetc_macro() (--parsenleft >= 0? *parsenextc++ : preadbuffer()) |
3200 | static int | 3204 | static int pgetc(void) |
3201 | pgetc(void) | ||
3202 | { | 3205 | { |
3203 | return pgetc_macro(); | 3206 | return pgetc_macro(); |
3204 | } | 3207 | } |
3205 | #else | 3208 | #else |
3206 | static int | 3209 | static int pgetc_macro(void) |
3207 | pgetc_macro(void) | ||
3208 | { | 3210 | { |
3209 | return --parsenleft >= 0? *parsenextc++ : preadbuffer(); | 3211 | return --parsenleft >= 0 ? *parsenextc++ : preadbuffer(); |
3210 | } | 3212 | } |
3211 | 3213 | ||
3212 | static inline int | 3214 | static inline int pgetc(void) |
3213 | pgetc(void) | ||
3214 | { | 3215 | { |
3215 | return pgetc_macro(); | 3216 | return pgetc_macro(); |
3216 | } | 3217 | } |
@@ -3222,15 +3223,14 @@ pgetc(void) | |||
3222 | * PEOF may be pushed back. | 3223 | * PEOF may be pushed back. |
3223 | */ | 3224 | */ |
3224 | 3225 | ||
3225 | static void pungetc(void) | 3226 | static void pungetc(void) |
3226 | { | 3227 | { |
3227 | parsenleft++; | 3228 | parsenleft++; |
3228 | parsenextc--; | 3229 | parsenextc--; |
3229 | } | 3230 | } |
3230 | 3231 | ||
3231 | 3232 | ||
3232 | static void | 3233 | static void popfile(void) |
3233 | popfile(void) | ||
3234 | { | 3234 | { |
3235 | struct parsefile *pf = parsefile; | 3235 | struct parsefile *pf = parsefile; |
3236 | 3236 | ||
@@ -3254,8 +3254,7 @@ popfile(void) | |||
3254 | * Return to top level. | 3254 | * Return to top level. |
3255 | */ | 3255 | */ |
3256 | 3256 | ||
3257 | static void | 3257 | static void popallfiles(void) |
3258 | popallfiles(void) | ||
3259 | { | 3258 | { |
3260 | while (parsefile != &basepf) | 3259 | while (parsefile != &basepf) |
3261 | popfile(); | 3260 | popfile(); |
@@ -3266,7 +3265,7 @@ popallfiles(void) | |||
3266 | * after a fork is done. | 3265 | * after a fork is done. |
3267 | */ | 3266 | */ |
3268 | 3267 | ||
3269 | static void closescript(void) | 3268 | static void closescript(void) |
3270 | { | 3269 | { |
3271 | popallfiles(); | 3270 | popallfiles(); |
3272 | if (parsefile->fd > 0) { | 3271 | if (parsefile->fd > 0) { |
@@ -3305,8 +3304,7 @@ static void setinputfd(int fd, int push) | |||
3305 | * old input onto the stack first. | 3304 | * old input onto the stack first. |
3306 | */ | 3305 | */ |
3307 | 3306 | ||
3308 | static void | 3307 | static void setinputfile(const char *fname, int push) |
3309 | setinputfile(const char *fname, int push) | ||
3310 | { | 3308 | { |
3311 | int fd; | 3309 | int fd; |
3312 | int myfileno2; | 3310 | int myfileno2; |
@@ -3326,24 +3324,24 @@ setinputfile(const char *fname, int push) | |||
3326 | } | 3324 | } |
3327 | 3325 | ||
3328 | 3326 | ||
3329 | static void | 3327 | static void tryexec(char *cmd, char **argv, char **envp) |
3330 | tryexec(char *cmd, char **argv, char **envp) | ||
3331 | { | 3328 | { |
3332 | int e; | 3329 | int e; |
3333 | 3330 | ||
3334 | #ifdef CONFIG_FEATURE_SH_STANDALONE_SHELL | 3331 | #ifdef CONFIG_FEATURE_SH_STANDALONE_SHELL |
3335 | char *name = cmd; | 3332 | char *name = cmd; |
3336 | char** argv_l=argv; | 3333 | char **argv_l = argv; |
3337 | int argc_l; | 3334 | int argc_l; |
3335 | |||
3338 | #ifdef CONFIG_FEATURE_SH_APPLETS_ALWAYS_WIN | 3336 | #ifdef CONFIG_FEATURE_SH_APPLETS_ALWAYS_WIN |
3339 | name = get_last_path_component(name); | 3337 | name = get_last_path_component(name); |
3340 | #endif | 3338 | #endif |
3341 | argv_l=envp; | 3339 | argv_l = envp; |
3342 | for(argc_l=0;*argv_l!=NULL; argv_l++, argc_l++) | 3340 | for (argc_l = 0; *argv_l != NULL; argv_l++, argc_l++) |
3343 | putenv(*argv_l); | 3341 | putenv(*argv_l); |
3344 | argv_l=argv; | 3342 | argv_l = argv; |
3345 | for(argc_l=0;*argv_l!=NULL; argv_l++, argc_l++) | 3343 | for (argc_l = 0; *argv_l != NULL; argv_l++, argc_l++) |
3346 | optind = 1; | 3344 | optind = 1; |
3347 | run_applet_by_name(name, argc_l, argv); | 3345 | run_applet_by_name(name, argc_l, argv); |
3348 | #endif | 3346 | #endif |
3349 | execve(cmd, argv, envp); | 3347 | execve(cmd, argv, envp); |
@@ -3359,7 +3357,7 @@ tryexec(char *cmd, char **argv, char **envp) | |||
3359 | errno = e; | 3357 | errno = e; |
3360 | } | 3358 | } |
3361 | 3359 | ||
3362 | static char *commandtext (const union node *); | 3360 | static char *commandtext(const union node *); |
3363 | 3361 | ||
3364 | /* | 3362 | /* |
3365 | * Do a path search. The variable path (passed by reference) should be | 3363 | * Do a path search. The variable path (passed by reference) should be |
@@ -3376,8 +3374,7 @@ static const char *pathopt; | |||
3376 | static void growstackblock(void); | 3374 | static void growstackblock(void); |
3377 | 3375 | ||
3378 | 3376 | ||
3379 | static char * | 3377 | static char *padvance(const char **path, const char *name) |
3380 | padvance(const char **path, const char *name) | ||
3381 | { | 3378 | { |
3382 | const char *p; | 3379 | const char *p; |
3383 | char *q; | 3380 | char *q; |
@@ -3387,8 +3384,8 @@ padvance(const char **path, const char *name) | |||
3387 | if (*path == NULL) | 3384 | if (*path == NULL) |
3388 | return NULL; | 3385 | return NULL; |
3389 | start = *path; | 3386 | start = *path; |
3390 | for (p = start ; *p && *p != ':' && *p != '%' ; p++); | 3387 | for (p = start; *p && *p != ':' && *p != '%'; p++); |
3391 | len = p - start + strlen(name) + 2; /* "2" is for '/' and '\0' */ | 3388 | len = p - start + strlen(name) + 2; /* "2" is for '/' and '\0' */ |
3392 | while (stackblocksize() < len) | 3389 | while (stackblocksize() < len) |
3393 | growstackblock(); | 3390 | growstackblock(); |
3394 | q = stackblock(); | 3391 | q = stackblock(); |
@@ -3401,7 +3398,8 @@ padvance(const char **path, const char *name) | |||
3401 | pathopt = NULL; | 3398 | pathopt = NULL; |
3402 | if (*p == '%') { | 3399 | if (*p == '%') { |
3403 | pathopt = ++p; | 3400 | pathopt = ++p; |
3404 | while (*p && *p != ':') p++; | 3401 | while (*p && *p != ':') |
3402 | p++; | ||
3405 | } | 3403 | } |
3406 | if (*p == ':') | 3404 | if (*p == ':') |
3407 | *path = p + 1; | 3405 | *path = p + 1; |
@@ -3413,8 +3411,7 @@ padvance(const char **path, const char *name) | |||
3413 | /* | 3411 | /* |
3414 | * Wrapper around strcmp for qsort/bsearch/... | 3412 | * Wrapper around strcmp for qsort/bsearch/... |
3415 | */ | 3413 | */ |
3416 | static int | 3414 | static int pstrcmp(const void *a, const void *b) |
3417 | pstrcmp(const void *a, const void *b) | ||
3418 | { | 3415 | { |
3419 | return strcmp((const char *) a, (*(const char *const *) b) + 1); | 3416 | return strcmp((const char *) a, (*(const char *const *) b) + 1); |
3420 | } | 3417 | } |
@@ -3423,20 +3420,18 @@ pstrcmp(const void *a, const void *b) | |||
3423 | * Find a keyword is in a sorted array. | 3420 | * Find a keyword is in a sorted array. |
3424 | */ | 3421 | */ |
3425 | 3422 | ||
3426 | static const char *const * | 3423 | static const char *const *findkwd(const char *s) |
3427 | findkwd(const char *s) | ||
3428 | { | 3424 | { |
3429 | return bsearch(s, tokname_array + KWDOFFSET, | 3425 | return bsearch(s, tokname_array + KWDOFFSET, |
3430 | (sizeof(tokname_array)/sizeof(const char *)) - KWDOFFSET, | 3426 | (sizeof(tokname_array) / sizeof(const char *)) - KWDOFFSET, |
3431 | sizeof(const char *), pstrcmp); | 3427 | sizeof(const char *), pstrcmp); |
3432 | } | 3428 | } |
3433 | 3429 | ||
3434 | 3430 | ||
3435 | /*** Command hashing code ***/ | 3431 | /*** Command hashing code ***/ |
3436 | 3432 | ||
3437 | 3433 | ||
3438 | static int | 3434 | static int hashcmd(int argc, char **argv) |
3439 | hashcmd(int argc, char **argv) | ||
3440 | { | 3435 | { |
3441 | struct tblentry **pp; | 3436 | struct tblentry **pp; |
3442 | struct tblentry *cmdp; | 3437 | struct tblentry *cmdp; |
@@ -3444,6 +3439,7 @@ hashcmd(int argc, char **argv) | |||
3444 | int verbose; | 3439 | int verbose; |
3445 | struct cmdentry entry; | 3440 | struct cmdentry entry; |
3446 | char *name; | 3441 | char *name; |
3442 | |||
3447 | #ifdef CONFIG_ASH_ALIAS | 3443 | #ifdef CONFIG_ASH_ALIAS |
3448 | const struct alias *ap; | 3444 | const struct alias *ap; |
3449 | #endif | 3445 | #endif |
@@ -3458,8 +3454,8 @@ hashcmd(int argc, char **argv) | |||
3458 | } | 3454 | } |
3459 | } | 3455 | } |
3460 | if (*argptr == NULL) { | 3456 | if (*argptr == NULL) { |
3461 | for (pp = cmdtable ; pp < &cmdtable[CMDTABLESIZE] ; pp++) { | 3457 | for (pp = cmdtable; pp < &cmdtable[CMDTABLESIZE]; pp++) { |
3462 | for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) { | 3458 | for (cmdp = *pp; cmdp; cmdp = cmdp->next) { |
3463 | if (cmdp->cmdtype != CMDBUILTIN) { | 3459 | if (cmdp->cmdtype != CMDBUILTIN) { |
3464 | printentry(cmdp, verbose); | 3460 | printentry(cmdp, verbose); |
3465 | } | 3461 | } |
@@ -3470,22 +3466,22 @@ hashcmd(int argc, char **argv) | |||
3470 | c = 0; | 3466 | c = 0; |
3471 | while ((name = *argptr++) != NULL) { | 3467 | while ((name = *argptr++) != NULL) { |
3472 | if ((cmdp = cmdlookup(name, 0)) != NULL | 3468 | if ((cmdp = cmdlookup(name, 0)) != NULL |
3473 | && (cmdp->cmdtype == CMDNORMAL | 3469 | && (cmdp->cmdtype == CMDNORMAL |
3474 | || (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0))) | 3470 | || (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0))) |
3475 | delete_cmd_entry(); | 3471 | delete_cmd_entry(); |
3476 | #ifdef CONFIG_ASH_ALIAS | 3472 | #ifdef CONFIG_ASH_ALIAS |
3477 | /* Then look at the aliases */ | 3473 | /* Then look at the aliases */ |
3478 | if ((ap = *__lookupalias(name)) != NULL) { | 3474 | if ((ap = *__lookupalias(name)) != NULL) { |
3479 | if (verbose=='v') | 3475 | if (verbose == 'v') |
3480 | printf("%s is an alias for %s\n", name, ap->val); | 3476 | printf("%s is an alias for %s\n", name, ap->val); |
3481 | else | 3477 | else |
3482 | printalias(ap); | 3478 | printalias(ap); |
3483 | continue; | 3479 | continue; |
3484 | } | 3480 | } |
3485 | #endif | 3481 | #endif |
3486 | /* First look at the keywords */ | 3482 | /* First look at the keywords */ |
3487 | if (findkwd(name)!=0) { | 3483 | if (findkwd(name) != 0) { |
3488 | if (verbose=='v') | 3484 | if (verbose == 'v') |
3489 | printf("%s is a shell keyword\n", name); | 3485 | printf("%s is a shell keyword\n", name); |
3490 | else | 3486 | else |
3491 | puts(name); | 3487 | puts(name); |
@@ -3493,18 +3489,19 @@ hashcmd(int argc, char **argv) | |||
3493 | } | 3489 | } |
3494 | 3490 | ||
3495 | find_command(name, &entry, DO_ERR, pathval()); | 3491 | find_command(name, &entry, DO_ERR, pathval()); |
3496 | if (entry.cmdtype == CMDUNKNOWN) c = 1; | 3492 | if (entry.cmdtype == CMDUNKNOWN) |
3493 | c = 1; | ||
3497 | else if (verbose) { | 3494 | else if (verbose) { |
3498 | cmdp = cmdlookup(name, 0); | 3495 | cmdp = cmdlookup(name, 0); |
3499 | if (cmdp) printentry(cmdp, verbose=='v'); | 3496 | if (cmdp) |
3497 | printentry(cmdp, verbose == 'v'); | ||
3500 | flushall(); | 3498 | flushall(); |
3501 | } | 3499 | } |
3502 | } | 3500 | } |
3503 | return c; | 3501 | return c; |
3504 | } | 3502 | } |
3505 | 3503 | ||
3506 | static void | 3504 | static void printentry(struct tblentry *cmdp, int verbose) |
3507 | printentry(struct tblentry *cmdp, int verbose) | ||
3508 | { | 3505 | { |
3509 | int idx; | 3506 | int idx; |
3510 | const char *path; | 3507 | const char *path; |
@@ -3518,10 +3515,10 @@ printentry(struct tblentry *cmdp, int verbose) | |||
3518 | name = padvance(&path, cmdp->cmdname); | 3515 | name = padvance(&path, cmdp->cmdname); |
3519 | stunalloc(name); | 3516 | stunalloc(name); |
3520 | } while (--idx >= 0); | 3517 | } while (--idx >= 0); |
3521 | if(verbose) | 3518 | if (verbose) |
3522 | out1str(name); | 3519 | out1str(name); |
3523 | } else if (cmdp->cmdtype == CMDBUILTIN) { | 3520 | } else if (cmdp->cmdtype == CMDBUILTIN) { |
3524 | if(verbose) | 3521 | if (verbose) |
3525 | out1str("a shell builtin"); | 3522 | out1str("a shell builtin"); |
3526 | } else if (cmdp->cmdtype == CMDFUNCTION) { | 3523 | } else if (cmdp->cmdtype == CMDFUNCTION) { |
3527 | if (verbose) { | 3524 | if (verbose) { |
@@ -3545,14 +3542,14 @@ printentry(struct tblentry *cmdp, int verbose) | |||
3545 | /*** List the available builtins ***/ | 3542 | /*** List the available builtins ***/ |
3546 | 3543 | ||
3547 | 3544 | ||
3548 | static int helpcmd(int argc, char** argv) | 3545 | static int helpcmd(int argc, char **argv) |
3549 | { | 3546 | { |
3550 | int col, i; | 3547 | int col, i; |
3551 | 3548 | ||
3552 | printf("\nBuilt-in commands:\n-------------------\n"); | 3549 | printf("\nBuilt-in commands:\n-------------------\n"); |
3553 | for (col=0, i=0; i < NUMBUILTINS; i++) { | 3550 | for (col = 0, i = 0; i < NUMBUILTINS; i++) { |
3554 | col += printf("%c%s", ((col == 0) ? '\t' : ' '), | 3551 | col += printf("%c%s", ((col == 0) ? '\t' : ' '), |
3555 | builtincmds[i].name+1); | 3552 | builtincmds[i].name + 1); |
3556 | if (col > 60) { | 3553 | if (col > 60) { |
3557 | printf("\n"); | 3554 | printf("\n"); |
3558 | col = 0; | 3555 | col = 0; |
@@ -3563,10 +3560,9 @@ static int helpcmd(int argc, char** argv) | |||
3563 | extern const struct BB_applet applets[]; | 3560 | extern const struct BB_applet applets[]; |
3564 | extern const size_t NUM_APPLETS; | 3561 | extern const size_t NUM_APPLETS; |
3565 | 3562 | ||
3566 | for (i=0; i < NUM_APPLETS; i++) { | 3563 | for (i = 0; i < NUM_APPLETS; i++) { |
3567 | 3564 | ||
3568 | col += printf("%c%s", ((col == 0) ? '\t' : ' '), | 3565 | col += printf("%c%s", ((col == 0) ? '\t' : ' '), applets[i].name); |
3569 | applets[i].name); | ||
3570 | if (col > 60) { | 3566 | if (col > 60) { |
3571 | printf("\n"); | 3567 | printf("\n"); |
3572 | col = 0; | 3568 | col = 0; |
@@ -3583,10 +3579,11 @@ static int helpcmd(int argc, char** argv) | |||
3583 | * change the shellexec routine as well. | 3579 | * change the shellexec routine as well. |
3584 | */ | 3580 | */ |
3585 | 3581 | ||
3586 | static int prefix (const char *, const char *); | 3582 | static int prefix(const char *, const char *); |
3587 | 3583 | ||
3588 | static void | 3584 | static void |
3589 | find_command(const char *name, struct cmdentry *entry, int act, const char *path) | 3585 | find_command(const char *name, struct cmdentry *entry, int act, |
3586 | const char *path) | ||
3590 | { | 3587 | { |
3591 | struct tblentry *cmdp; | 3588 | struct tblentry *cmdp; |
3592 | int idx; | 3589 | int idx; |
@@ -3637,10 +3634,10 @@ find_command(const char *name, struct cmdentry *entry, int act, const char *path | |||
3637 | } | 3634 | } |
3638 | } else if (act & DO_BRUTE) { | 3635 | } else if (act & DO_BRUTE) { |
3639 | if ((cmdp->cmdtype == CMDNORMAL && | 3636 | if ((cmdp->cmdtype == CMDNORMAL && |
3640 | cmdp->param.index >= firstchange) || | 3637 | cmdp->param.index >= firstchange) || |
3641 | (cmdp->cmdtype == CMDBUILTIN && | 3638 | (cmdp->cmdtype == CMDBUILTIN && |
3642 | ((builtinloc < 0 && bltin >= 0) ? | 3639 | ((builtinloc < 0 && bltin >= 0) ? |
3643 | bltin : builtinloc) >= firstchange)) { | 3640 | bltin : builtinloc) >= firstchange)) { |
3644 | /* need to recompute the entry */ | 3641 | /* need to recompute the entry */ |
3645 | } else { | 3642 | } else { |
3646 | goto success; | 3643 | goto success; |
@@ -3665,7 +3662,7 @@ find_command(const char *name, struct cmdentry *entry, int act, const char *path | |||
3665 | 3662 | ||
3666 | /* If %builtin not in path, check for builtin next */ | 3663 | /* If %builtin not in path, check for builtin next */ |
3667 | if (regular || (bltin < 0 && bcmd)) { | 3664 | if (regular || (bltin < 0 && bcmd)) { |
3668 | builtin: | 3665 | builtin: |
3669 | if (!updatetbl) { | 3666 | if (!updatetbl) { |
3670 | entry->cmdtype = CMDBUILTIN; | 3667 | entry->cmdtype = CMDBUILTIN; |
3671 | entry->u.cmd = bcmd; | 3668 | entry->u.cmd = bcmd; |
@@ -3680,8 +3677,8 @@ builtin: | |||
3680 | } | 3677 | } |
3681 | 3678 | ||
3682 | /* We have to search path. */ | 3679 | /* We have to search path. */ |
3683 | prev = -1; /* where to start */ | 3680 | prev = -1; /* where to start */ |
3684 | if (cmdp && cmdp->rehash) { /* doing a rehash */ | 3681 | if (cmdp && cmdp->rehash) { /* doing a rehash */ |
3685 | if (cmdp->cmdtype == CMDBUILTIN) | 3682 | if (cmdp->cmdtype == CMDBUILTIN) |
3686 | prev = builtinloc; | 3683 | prev = builtinloc; |
3687 | else | 3684 | else |
@@ -3690,7 +3687,7 @@ builtin: | |||
3690 | 3687 | ||
3691 | e = ENOENT; | 3688 | e = ENOENT; |
3692 | idx = -1; | 3689 | idx = -1; |
3693 | loop: | 3690 | loop: |
3694 | while ((fullname = padvance(&path, name)) != NULL) { | 3691 | while ((fullname = padvance(&path, name)) != NULL) { |
3695 | stunalloc(fullname); | 3692 | stunalloc(fullname); |
3696 | idx++; | 3693 | idx++; |
@@ -3703,16 +3700,14 @@ loop: | |||
3703 | goto builtin; | 3700 | goto builtin; |
3704 | } | 3701 | } |
3705 | continue; | 3702 | continue; |
3706 | } else if (!(act & DO_NOFUN) && | 3703 | } else if (!(act & DO_NOFUN) && prefix("func", pathopt)) { |
3707 | prefix("func", pathopt)) { | ||
3708 | /* handled below */ | 3704 | /* handled below */ |
3709 | } else { | 3705 | } else { |
3710 | continue; /* ignore unimplemented options */ | 3706 | continue; /* ignore unimplemented options */ |
3711 | } | 3707 | } |
3712 | } | 3708 | } |
3713 | /* if rehash, don't redo absolute path names */ | 3709 | /* if rehash, don't redo absolute path names */ |
3714 | if (fullname[0] == '/' && idx <= prev && | 3710 | if (fullname[0] == '/' && idx <= prev && idx < firstchange) { |
3715 | idx < firstchange) { | ||
3716 | if (idx < prev) | 3711 | if (idx < prev) |
3717 | continue; | 3712 | continue; |
3718 | TRACE(("searchexec \"%s\": no change\n", name)); | 3713 | TRACE(("searchexec \"%s\": no change\n", name)); |
@@ -3723,13 +3718,14 @@ loop: | |||
3723 | e = errno; | 3718 | e = errno; |
3724 | goto loop; | 3719 | goto loop; |
3725 | } | 3720 | } |
3726 | e = EACCES; /* if we fail, this will be the error */ | 3721 | e = EACCES; /* if we fail, this will be the error */ |
3727 | if (!S_ISREG(statb.st_mode)) | 3722 | if (!S_ISREG(statb.st_mode)) |
3728 | continue; | 3723 | continue; |
3729 | if (pathopt) { /* this is a %func directory */ | 3724 | if (pathopt) { /* this is a %func directory */ |
3730 | stalloc(strlen(fullname) + 1); | 3725 | stalloc(strlen(fullname) + 1); |
3731 | readcmdfile(fullname); | 3726 | readcmdfile(fullname); |
3732 | if ((cmdp = cmdlookup(name, 0)) == NULL || cmdp->cmdtype != CMDFUNCTION) | 3727 | if ((cmdp = cmdlookup(name, 0)) == NULL |
3728 | || cmdp->cmdtype != CMDFUNCTION) | ||
3733 | error("%s not defined in %s", name, fullname); | 3729 | error("%s not defined in %s", name, fullname); |
3734 | stunalloc(fullname); | 3730 | stunalloc(fullname); |
3735 | goto success; | 3731 | goto success; |
@@ -3758,7 +3754,7 @@ loop: | |||
3758 | entry->cmdtype = CMDUNKNOWN; | 3754 | entry->cmdtype = CMDUNKNOWN; |
3759 | return; | 3755 | return; |
3760 | 3756 | ||
3761 | success: | 3757 | success: |
3762 | cmdp->rehash = 0; | 3758 | cmdp->rehash = 0; |
3763 | entry->cmdtype = cmdp->cmdtype; | 3759 | entry->cmdtype = cmdp->cmdtype; |
3764 | entry->u = cmdp->param; | 3760 | entry->u = cmdp->param; |
@@ -3770,20 +3766,17 @@ success: | |||
3770 | * Search the table of builtin commands. | 3766 | * Search the table of builtin commands. |
3771 | */ | 3767 | */ |
3772 | 3768 | ||
3773 | static int | 3769 | static int bstrcmp(const void *name, const void *b) |
3774 | bstrcmp(const void *name, const void *b) | ||
3775 | { | 3770 | { |
3776 | return strcmp((const char *)name, (*(const char *const *) b)+1); | 3771 | return strcmp((const char *) name, (*(const char *const *) b) + 1); |
3777 | } | 3772 | } |
3778 | 3773 | ||
3779 | static struct builtincmd * | 3774 | static struct builtincmd *find_builtin(const char *name) |
3780 | find_builtin(const char *name) | ||
3781 | { | 3775 | { |
3782 | struct builtincmd *bp; | 3776 | struct builtincmd *bp; |
3783 | 3777 | ||
3784 | bp = bsearch(name, builtincmds, NUMBUILTINS, sizeof(struct builtincmd), | 3778 | bp = bsearch(name, builtincmds, NUMBUILTINS, sizeof(struct builtincmd), |
3785 | bstrcmp | 3779 | bstrcmp); |
3786 | ); | ||
3787 | return bp; | 3780 | return bp; |
3788 | } | 3781 | } |
3789 | 3782 | ||
@@ -3793,16 +3786,15 @@ find_builtin(const char *name) | |||
3793 | * are executed they will be rehashed. | 3786 | * are executed they will be rehashed. |
3794 | */ | 3787 | */ |
3795 | 3788 | ||
3796 | static inline void | 3789 | static inline void hashcd(void) |
3797 | hashcd(void) | ||
3798 | { | 3790 | { |
3799 | struct tblentry **pp; | 3791 | struct tblentry **pp; |
3800 | struct tblentry *cmdp; | 3792 | struct tblentry *cmdp; |
3801 | 3793 | ||
3802 | for (pp = cmdtable ; pp < &cmdtable[CMDTABLESIZE] ; pp++) { | 3794 | for (pp = cmdtable; pp < &cmdtable[CMDTABLESIZE]; pp++) { |
3803 | for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) { | 3795 | for (cmdp = *pp; cmdp; cmdp = cmdp->next) { |
3804 | if (cmdp->cmdtype == CMDNORMAL | 3796 | if (cmdp->cmdtype == CMDNORMAL |
3805 | || (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0)) | 3797 | || (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0)) |
3806 | cmdp->rehash = 1; | 3798 | cmdp->rehash = 1; |
3807 | } | 3799 | } |
3808 | } | 3800 | } |
@@ -3816,15 +3808,14 @@ hashcd(void) | |||
3816 | * interrupts off. | 3808 | * interrupts off. |
3817 | */ | 3809 | */ |
3818 | 3810 | ||
3819 | static void | 3811 | static void changepath(const char *newval) |
3820 | changepath(const char *newval) | ||
3821 | { | 3812 | { |
3822 | int firstchange; | 3813 | int firstchange; |
3823 | int bltin; | 3814 | int bltin; |
3824 | 3815 | ||
3825 | firstchange = path_change(newval, &bltin); | 3816 | firstchange = path_change(newval, &bltin); |
3826 | if (builtinloc < 0 && bltin >= 0) | 3817 | if (builtinloc < 0 && bltin >= 0) |
3827 | builtinloc = bltin; /* zap builtins */ | 3818 | builtinloc = bltin; /* zap builtins */ |
3828 | clearcmdentry(firstchange); | 3819 | clearcmdentry(firstchange); |
3829 | builtinloc = bltin; | 3820 | builtinloc = bltin; |
3830 | /* Ensure that getenv("PATH") stays current */ | 3821 | /* Ensure that getenv("PATH") stays current */ |
@@ -3837,21 +3828,19 @@ changepath(const char *newval) | |||
3837 | * PATH which has changed. | 3828 | * PATH which has changed. |
3838 | */ | 3829 | */ |
3839 | 3830 | ||
3840 | static void | 3831 | static void clearcmdentry(int firstchange) |
3841 | clearcmdentry(int firstchange) | ||
3842 | { | 3832 | { |
3843 | struct tblentry **tblp; | 3833 | struct tblentry **tblp; |
3844 | struct tblentry **pp; | 3834 | struct tblentry **pp; |
3845 | struct tblentry *cmdp; | 3835 | struct tblentry *cmdp; |
3846 | 3836 | ||
3847 | INTOFF; | 3837 | INTOFF; |
3848 | for (tblp = cmdtable ; tblp < &cmdtable[CMDTABLESIZE] ; tblp++) { | 3838 | for (tblp = cmdtable; tblp < &cmdtable[CMDTABLESIZE]; tblp++) { |
3849 | pp = tblp; | 3839 | pp = tblp; |
3850 | while ((cmdp = *pp) != NULL) { | 3840 | while ((cmdp = *pp) != NULL) { |
3851 | if ((cmdp->cmdtype == CMDNORMAL && | 3841 | if ((cmdp->cmdtype == CMDNORMAL && |
3852 | cmdp->param.index >= firstchange) | 3842 | cmdp->param.index >= firstchange) |
3853 | || (cmdp->cmdtype == CMDBUILTIN && | 3843 | || (cmdp->cmdtype == CMDBUILTIN && builtinloc >= firstchange)) { |
3854 | builtinloc >= firstchange)) { | ||
3855 | *pp = cmdp->next; | 3844 | *pp = cmdp->next; |
3856 | free(cmdp); | 3845 | free(cmdp); |
3857 | } else { | 3846 | } else { |
@@ -3867,15 +3856,14 @@ clearcmdentry(int firstchange) | |||
3867 | * Delete all functions. | 3856 | * Delete all functions. |
3868 | */ | 3857 | */ |
3869 | 3858 | ||
3870 | static void | 3859 | static void deletefuncs(void) |
3871 | deletefuncs(void) | ||
3872 | { | 3860 | { |
3873 | struct tblentry **tblp; | 3861 | struct tblentry **tblp; |
3874 | struct tblentry **pp; | 3862 | struct tblentry **pp; |
3875 | struct tblentry *cmdp; | 3863 | struct tblentry *cmdp; |
3876 | 3864 | ||
3877 | INTOFF; | 3865 | INTOFF; |
3878 | for (tblp = cmdtable ; tblp < &cmdtable[CMDTABLESIZE] ; tblp++) { | 3866 | for (tblp = cmdtable; tblp < &cmdtable[CMDTABLESIZE]; tblp++) { |
3879 | pp = tblp; | 3867 | pp = tblp; |
3880 | while ((cmdp = *pp) != NULL) { | 3868 | while ((cmdp = *pp) != NULL) { |
3881 | if (cmdp->cmdtype == CMDFUNCTION) { | 3869 | if (cmdp->cmdtype == CMDFUNCTION) { |
@@ -3902,8 +3890,7 @@ deletefuncs(void) | |||
3902 | 3890 | ||
3903 | static struct tblentry **lastcmdentry; | 3891 | static struct tblentry **lastcmdentry; |
3904 | 3892 | ||
3905 | static struct tblentry * | 3893 | static struct tblentry *cmdlookup(const char *name, int add) |
3906 | cmdlookup(const char *name, int add) | ||
3907 | { | 3894 | { |
3908 | int hashval; | 3895 | int hashval; |
3909 | const char *p; | 3896 | const char *p; |
@@ -3916,15 +3903,15 @@ cmdlookup(const char *name, int add) | |||
3916 | hashval += *p++; | 3903 | hashval += *p++; |
3917 | hashval &= 0x7FFF; | 3904 | hashval &= 0x7FFF; |
3918 | pp = &cmdtable[hashval % CMDTABLESIZE]; | 3905 | pp = &cmdtable[hashval % CMDTABLESIZE]; |
3919 | for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) { | 3906 | for (cmdp = *pp; cmdp; cmdp = cmdp->next) { |
3920 | if (equal(cmdp->cmdname, name)) | 3907 | if (equal(cmdp->cmdname, name)) |
3921 | break; | 3908 | break; |
3922 | pp = &cmdp->next; | 3909 | pp = &cmdp->next; |
3923 | } | 3910 | } |
3924 | if (add && cmdp == NULL) { | 3911 | if (add && cmdp == NULL) { |
3925 | INTOFF; | 3912 | INTOFF; |
3926 | cmdp = *pp = xmalloc(sizeof (struct tblentry) - ARB | 3913 | cmdp = *pp = xmalloc(sizeof(struct tblentry) - ARB |
3927 | + strlen(name) + 1); | 3914 | + strlen(name) + 1); |
3928 | cmdp->next = NULL; | 3915 | cmdp->next = NULL; |
3929 | cmdp->cmdtype = CMDUNKNOWN; | 3916 | cmdp->cmdtype = CMDUNKNOWN; |
3930 | cmdp->rehash = 0; | 3917 | cmdp->rehash = 0; |
@@ -3939,8 +3926,7 @@ cmdlookup(const char *name, int add) | |||
3939 | * Delete the command entry returned on the last lookup. | 3926 | * Delete the command entry returned on the last lookup. |
3940 | */ | 3927 | */ |
3941 | 3928 | ||
3942 | static void | 3929 | static void delete_cmd_entry() |
3943 | delete_cmd_entry() | ||
3944 | { | 3930 | { |
3945 | struct tblentry *cmdp; | 3931 | struct tblentry *cmdp; |
3946 | 3932 | ||
@@ -3956,32 +3942,32 @@ delete_cmd_entry() | |||
3956 | 3942 | ||
3957 | 3943 | ||
3958 | static const unsigned char nodesize[26] = { | 3944 | static const unsigned char nodesize[26] = { |
3959 | ALIGN(sizeof (struct nbinary)), | 3945 | ALIGN(sizeof(struct nbinary)), |
3960 | ALIGN(sizeof (struct ncmd)), | 3946 | ALIGN(sizeof(struct ncmd)), |
3961 | ALIGN(sizeof (struct npipe)), | 3947 | ALIGN(sizeof(struct npipe)), |
3962 | ALIGN(sizeof (struct nredir)), | 3948 | ALIGN(sizeof(struct nredir)), |
3963 | ALIGN(sizeof (struct nredir)), | 3949 | ALIGN(sizeof(struct nredir)), |
3964 | ALIGN(sizeof (struct nredir)), | 3950 | ALIGN(sizeof(struct nredir)), |
3965 | ALIGN(sizeof (struct nbinary)), | 3951 | ALIGN(sizeof(struct nbinary)), |
3966 | ALIGN(sizeof (struct nbinary)), | 3952 | ALIGN(sizeof(struct nbinary)), |
3967 | ALIGN(sizeof (struct nif)), | 3953 | ALIGN(sizeof(struct nif)), |
3968 | ALIGN(sizeof (struct nbinary)), | 3954 | ALIGN(sizeof(struct nbinary)), |
3969 | ALIGN(sizeof (struct nbinary)), | 3955 | ALIGN(sizeof(struct nbinary)), |
3970 | ALIGN(sizeof (struct nfor)), | 3956 | ALIGN(sizeof(struct nfor)), |
3971 | ALIGN(sizeof (struct ncase)), | 3957 | ALIGN(sizeof(struct ncase)), |
3972 | ALIGN(sizeof (struct nclist)), | 3958 | ALIGN(sizeof(struct nclist)), |
3973 | ALIGN(sizeof (struct narg)), | 3959 | ALIGN(sizeof(struct narg)), |
3974 | ALIGN(sizeof (struct narg)), | 3960 | ALIGN(sizeof(struct narg)), |
3975 | ALIGN(sizeof (struct nfile)), | 3961 | ALIGN(sizeof(struct nfile)), |
3976 | ALIGN(sizeof (struct nfile)), | 3962 | ALIGN(sizeof(struct nfile)), |
3977 | ALIGN(sizeof (struct nfile)), | 3963 | ALIGN(sizeof(struct nfile)), |
3978 | ALIGN(sizeof (struct nfile)), | 3964 | ALIGN(sizeof(struct nfile)), |
3979 | ALIGN(sizeof (struct nfile)), | 3965 | ALIGN(sizeof(struct nfile)), |
3980 | ALIGN(sizeof (struct ndup)), | 3966 | ALIGN(sizeof(struct ndup)), |
3981 | ALIGN(sizeof (struct ndup)), | 3967 | ALIGN(sizeof(struct ndup)), |
3982 | ALIGN(sizeof (struct nhere)), | 3968 | ALIGN(sizeof(struct nhere)), |
3983 | ALIGN(sizeof (struct nhere)), | 3969 | ALIGN(sizeof(struct nhere)), |
3984 | ALIGN(sizeof (struct nnot)), | 3970 | ALIGN(sizeof(struct nnot)), |
3985 | }; | 3971 | }; |
3986 | 3972 | ||
3987 | 3973 | ||
@@ -3990,8 +3976,7 @@ static const unsigned char nodesize[26] = { | |||
3990 | * Delete a function if it exists. | 3976 | * Delete a function if it exists. |
3991 | */ | 3977 | */ |
3992 | 3978 | ||
3993 | static void | 3979 | static void unsetfunc(char *name) |
3994 | unsetfunc(char *name) | ||
3995 | { | 3980 | { |
3996 | struct tblentry *cmdp; | 3981 | struct tblentry *cmdp; |
3997 | 3982 | ||
@@ -4006,8 +3991,7 @@ unsetfunc(char *name) | |||
4006 | * Locate and print what a word is... | 3991 | * Locate and print what a word is... |
4007 | */ | 3992 | */ |
4008 | 3993 | ||
4009 | static int | 3994 | static int typecmd(int argc, char **argv) |
4010 | typecmd(int argc, char **argv) | ||
4011 | { | 3995 | { |
4012 | int i; | 3996 | int i; |
4013 | int err = 0; | 3997 | int err = 0; |
@@ -4025,8 +4009,7 @@ typecmd(int argc, char **argv) | |||
4025 | } | 4009 | } |
4026 | 4010 | ||
4027 | #ifdef CONFIG_ASH_CMDCMD | 4011 | #ifdef CONFIG_ASH_CMDCMD |
4028 | static int | 4012 | static int commandcmd(int argc, char **argv) |
4029 | commandcmd(int argc, char **argv) | ||
4030 | { | 4013 | { |
4031 | int c; | 4014 | int c; |
4032 | int default_path = 0; | 4015 | int default_path = 0; |
@@ -4046,12 +4029,10 @@ commandcmd(int argc, char **argv) | |||
4046 | break; | 4029 | break; |
4047 | } | 4030 | } |
4048 | 4031 | ||
4049 | if (default_path + verify_only + verbose_verify_only > 1 || | 4032 | if (default_path + verify_only + verbose_verify_only > 1 || !*argptr) { |
4050 | !*argptr) { | 4033 | out2str("command [-p] command [arg ...]\n" |
4051 | out2str( | ||
4052 | "command [-p] command [arg ...]\n" | ||
4053 | "command {-v|-V} command\n"); | 4034 | "command {-v|-V} command\n"); |
4054 | return EX_USAGE; | 4035 | return EX_USAGE; |
4055 | } | 4036 | } |
4056 | 4037 | ||
4057 | if (verify_only || verbose_verify_only) { | 4038 | if (verify_only || verbose_verify_only) { |
@@ -4060,7 +4041,7 @@ commandcmd(int argc, char **argv) | |||
4060 | argv_a[1] = 0; | 4041 | argv_a[1] = 0; |
4061 | argv_a[0] = *argptr; | 4042 | argv_a[0] = *argptr; |
4062 | argptr = argv_a; | 4043 | argptr = argv_a; |
4063 | optptr = verbose_verify_only ? "v" : "V"; /* reverse special */ | 4044 | optptr = verbose_verify_only ? "v" : "V"; /* reverse special */ |
4064 | return hashcmd(argc, argv); | 4045 | return hashcmd(argc, argv); |
4065 | } | 4046 | } |
4066 | 4047 | ||
@@ -4068,8 +4049,7 @@ commandcmd(int argc, char **argv) | |||
4068 | } | 4049 | } |
4069 | #endif | 4050 | #endif |
4070 | 4051 | ||
4071 | static int | 4052 | static int path_change(const char *newval, int *bltin) |
4072 | path_change(const char *newval, int *bltin) | ||
4073 | { | 4053 | { |
4074 | const char *old, *new; | 4054 | const char *old, *new; |
4075 | int idx; | 4055 | int idx; |
@@ -4077,16 +4057,16 @@ path_change(const char *newval, int *bltin) | |||
4077 | 4057 | ||
4078 | old = pathval(); | 4058 | old = pathval(); |
4079 | new = newval; | 4059 | new = newval; |
4080 | firstchange = 9999; /* assume no change */ | 4060 | firstchange = 9999; /* assume no change */ |
4081 | idx = 0; | 4061 | idx = 0; |
4082 | *bltin = -1; | 4062 | *bltin = -1; |
4083 | for (;;) { | 4063 | for (;;) { |
4084 | if (*old != *new) { | 4064 | if (*old != *new) { |
4085 | firstchange = idx; | 4065 | firstchange = idx; |
4086 | if ((*old == '\0' && *new == ':') | 4066 | if ((*old == '\0' && *new == ':') |
4087 | || (*old == ':' && *new == '\0')) | 4067 | || (*old == ':' && *new == '\0')) |
4088 | firstchange++; | 4068 | firstchange++; |
4089 | old = new; /* ignore subsequent differences */ | 4069 | old = new; /* ignore subsequent differences */ |
4090 | } | 4070 | } |
4091 | if (*new == '\0') | 4071 | if (*new == '\0') |
4092 | break; | 4072 | break; |
@@ -4101,6 +4081,7 @@ path_change(const char *newval, int *bltin) | |||
4101 | firstchange = 0; | 4081 | firstchange = 0; |
4102 | return firstchange; | 4082 | return firstchange; |
4103 | } | 4083 | } |
4084 | |||
4104 | /* | 4085 | /* |
4105 | * Routines to expand arguments to commands. We have to deal with | 4086 | * Routines to expand arguments to commands. We have to deal with |
4106 | * backquotes, shell variables, and file metacharacters. | 4087 | * backquotes, shell variables, and file metacharacters. |
@@ -4108,8 +4089,8 @@ path_change(const char *newval, int *bltin) | |||
4108 | /* | 4089 | /* |
4109 | * _rmescape() flags | 4090 | * _rmescape() flags |
4110 | */ | 4091 | */ |
4111 | #define RMESCAPE_ALLOC 0x1 /* Allocate a new string */ | 4092 | #define RMESCAPE_ALLOC 0x1 /* Allocate a new string */ |
4112 | #define RMESCAPE_GLOB 0x2 /* Add backslashes for glob */ | 4093 | #define RMESCAPE_GLOB 0x2 /* Add backslashes for glob */ |
4113 | 4094 | ||
4114 | /* | 4095 | /* |
4115 | * Structure specifying which parts of the string should be searched | 4096 | * Structure specifying which parts of the string should be searched |
@@ -4117,63 +4098,65 @@ path_change(const char *newval, int *bltin) | |||
4117 | */ | 4098 | */ |
4118 | 4099 | ||
4119 | struct ifsregion { | 4100 | struct ifsregion { |
4120 | struct ifsregion *next; /* next region in list */ | 4101 | struct ifsregion *next; /* next region in list */ |
4121 | int begoff; /* offset of start of region */ | 4102 | int begoff; /* offset of start of region */ |
4122 | int endoff; /* offset of end of region */ | 4103 | int endoff; /* offset of end of region */ |
4123 | int nulonly; /* search for nul bytes only */ | 4104 | int nulonly; /* search for nul bytes only */ |
4124 | }; | 4105 | }; |
4125 | 4106 | ||
4126 | 4107 | ||
4127 | static char *expdest; /* output of current string */ | 4108 | static char *expdest; /* output of current string */ |
4128 | static struct nodelist *argbackq; /* list of back quote expressions */ | 4109 | static struct nodelist *argbackq; /* list of back quote expressions */ |
4129 | static struct ifsregion ifsfirst; /* first struct in list of ifs regions */ | 4110 | static struct ifsregion ifsfirst; /* first struct in list of ifs regions */ |
4130 | static struct ifsregion *ifslastp; /* last struct in list */ | 4111 | static struct ifsregion *ifslastp; /* last struct in list */ |
4131 | static struct arglist exparg; /* holds expanded arg list */ | 4112 | static struct arglist exparg; /* holds expanded arg list */ |
4132 | 4113 | ||
4133 | static void argstr (char *, int); | 4114 | static void argstr(char *, int); |
4134 | static char *exptilde (char *, int); | 4115 | static char *exptilde(char *, int); |
4135 | static void expbackq (union node *, int, int); | 4116 | static void expbackq(union node *, int, int); |
4136 | static int subevalvar (char *, char *, int, int, int, int, int); | 4117 | static int subevalvar(char *, char *, int, int, int, int, int); |
4137 | static int varisset (char *, int); | 4118 | static int varisset(char *, int); |
4138 | static void strtodest (const char *, int, int); | 4119 | static void strtodest(const char *, int, int); |
4139 | static inline void varvalue (char *, int, int); | 4120 | static inline void varvalue(char *, int, int); |
4140 | static void recordregion (int, int, int); | 4121 | static void recordregion(int, int, int); |
4141 | static void removerecordregions (int); | 4122 | static void removerecordregions(int); |
4142 | static void ifsbreakup (char *, struct arglist *); | 4123 | static void ifsbreakup(char *, struct arglist *); |
4143 | static void ifsfree (void); | 4124 | static void ifsfree(void); |
4144 | static void expandmeta (struct strlist *, int); | 4125 | static void expandmeta(struct strlist *, int); |
4126 | |||
4145 | #if defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN) | 4127 | #if defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN) |
4146 | #define preglob(p) _rmescapes((p), RMESCAPE_ALLOC | RMESCAPE_GLOB) | 4128 | #define preglob(p) _rmescapes((p), RMESCAPE_ALLOC | RMESCAPE_GLOB) |
4147 | #if !defined(GLOB_BROKEN) | 4129 | #if !defined(GLOB_BROKEN) |
4148 | static inline void addglob (const glob_t *); | 4130 | static inline void addglob(const glob_t *); |
4149 | #endif | 4131 | #endif |
4150 | #endif | 4132 | #endif |
4151 | #if !(defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN)) | 4133 | #if !(defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN)) |
4152 | static void expmeta (char *, char *); | 4134 | static void expmeta(char *, char *); |
4153 | #endif | 4135 | #endif |
4154 | #if !(defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN)) | 4136 | #if !(defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN)) |
4155 | static struct strlist *expsort (struct strlist *); | 4137 | static struct strlist *expsort(struct strlist *); |
4156 | static struct strlist *msort (struct strlist *, int); | 4138 | static struct strlist *msort(struct strlist *, int); |
4157 | #endif | 4139 | #endif |
4158 | static int patmatch (char *, char *, int); | 4140 | static int patmatch(char *, char *, int); |
4141 | |||
4159 | #if defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN) | 4142 | #if defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN) |
4160 | static int patmatch2 (char *, char *, int); | 4143 | static int patmatch2(char *, char *, int); |
4161 | #else | 4144 | #else |
4162 | static int pmatch (char *, char *, int); | 4145 | static int pmatch(char *, char *, int); |
4146 | |||
4163 | #define patmatch2 patmatch | 4147 | #define patmatch2 patmatch |
4164 | #endif | 4148 | #endif |
4165 | static char *cvtnum (int, char *); | 4149 | static char *cvtnum(int, char *); |
4166 | 4150 | ||
4167 | /* | 4151 | /* |
4168 | * Expand shell variables and backquotes inside a here document. | 4152 | * Expand shell variables and backquotes inside a here document. |
4169 | */ | 4153 | */ |
4170 | 4154 | ||
4171 | /* arg: the document, fd: where to write the expanded version */ | 4155 | /* arg: the document, fd: where to write the expanded version */ |
4172 | static inline void | 4156 | static inline void expandhere(union node *arg, int fd) |
4173 | expandhere(union node *arg, int fd) | ||
4174 | { | 4157 | { |
4175 | herefd = fd; | 4158 | herefd = fd; |
4176 | expandarg(arg, (struct arglist *)NULL, 0); | 4159 | expandarg(arg, (struct arglist *) NULL, 0); |
4177 | xwrite(fd, stackblock(), expdest - stackblock()); | 4160 | xwrite(fd, stackblock(), expdest - stackblock()); |
4178 | } | 4161 | } |
4179 | 4162 | ||
@@ -4185,8 +4168,7 @@ expandhere(union node *arg, int fd) | |||
4185 | * here document expansion. | 4168 | * here document expansion. |
4186 | */ | 4169 | */ |
4187 | 4170 | ||
4188 | static void | 4171 | static void expandarg(union node *arg, struct arglist *arglist, int flag) |
4189 | expandarg(union node *arg, struct arglist *arglist, int flag) | ||
4190 | { | 4172 | { |
4191 | struct strlist *sp; | 4173 | struct strlist *sp; |
4192 | char *p; | 4174 | char *p; |
@@ -4197,7 +4179,7 @@ expandarg(union node *arg, struct arglist *arglist, int flag) | |||
4197 | ifslastp = NULL; | 4179 | ifslastp = NULL; |
4198 | argstr(arg->narg.text, flag); | 4180 | argstr(arg->narg.text, flag); |
4199 | if (arglist == NULL) { | 4181 | if (arglist == NULL) { |
4200 | return; /* here document expanded */ | 4182 | return; /* here document expanded */ |
4201 | } | 4183 | } |
4202 | STPUTC('\0', expdest); | 4184 | STPUTC('\0', expdest); |
4203 | p = grabstackstr(expdest); | 4185 | p = grabstackstr(expdest); |
@@ -4211,9 +4193,9 @@ expandarg(union node *arg, struct arglist *arglist, int flag) | |||
4211 | exparg.lastp = &exparg.list; | 4193 | exparg.lastp = &exparg.list; |
4212 | expandmeta(exparg.list, flag); | 4194 | expandmeta(exparg.list, flag); |
4213 | } else { | 4195 | } else { |
4214 | if (flag & EXP_REDIR) /*XXX - for now, just remove escapes */ | 4196 | if (flag & EXP_REDIR) /*XXX - for now, just remove escapes */ |
4215 | rmescapes(p); | 4197 | rmescapes(p); |
4216 | sp = (struct strlist *)stalloc(sizeof (struct strlist)); | 4198 | sp = (struct strlist *) stalloc(sizeof(struct strlist)); |
4217 | sp->text = p; | 4199 | sp->text = p; |
4218 | *exparg.lastp = sp; | 4200 | *exparg.lastp = sp; |
4219 | exparg.lastp = &sp->next; | 4201 | exparg.lastp = &sp->next; |
@@ -4232,7 +4214,7 @@ expandarg(union node *arg, struct arglist *arglist, int flag) | |||
4232 | * input string. | 4214 | * input string. |
4233 | */ | 4215 | */ |
4234 | 4216 | ||
4235 | static inline char * evalvar(char *p, int flag) | 4217 | static inline char *evalvar(char *p, int flag) |
4236 | { | 4218 | { |
4237 | int subtype; | 4219 | int subtype; |
4238 | int varflags; | 4220 | int varflags; |
@@ -4251,10 +4233,10 @@ static inline char * evalvar(char *p, int flag) | |||
4251 | subtype = varflags & VSTYPE; | 4233 | subtype = varflags & VSTYPE; |
4252 | var = p; | 4234 | var = p; |
4253 | special = 0; | 4235 | special = 0; |
4254 | if (! is_name(*p)) | 4236 | if (!is_name(*p)) |
4255 | special = 1; | 4237 | special = 1; |
4256 | p = strchr(p, '=') + 1; | 4238 | p = strchr(p, '=') + 1; |
4257 | again: /* jump here after setting a variable with ${var=text} */ | 4239 | again: /* jump here after setting a variable with ${var=text} */ |
4258 | if (special) { | 4240 | if (special) { |
4259 | set = varisset(var, varflags & VSNUL); | 4241 | set = varisset(var, varflags & VSNUL); |
4260 | val = NULL; | 4242 | val = NULL; |
@@ -4280,21 +4262,17 @@ again: /* jump here after setting a variable with ${var=text} */ | |||
4280 | if (subtype == VSLENGTH) { | 4262 | if (subtype == VSLENGTH) { |
4281 | varlen = strlen(val); | 4263 | varlen = strlen(val); |
4282 | } else { | 4264 | } else { |
4283 | strtodest( | 4265 | strtodest(val, |
4284 | val, | 4266 | varflags & VSQUOTE ? DQSYNTAX : BASESYNTAX, quotes); |
4285 | varflags & VSQUOTE ? | ||
4286 | DQSYNTAX : BASESYNTAX, | ||
4287 | quotes | ||
4288 | ); | ||
4289 | } | 4267 | } |
4290 | } | 4268 | } |
4291 | } | 4269 | } |
4292 | 4270 | ||
4293 | if (subtype == VSPLUS) | 4271 | if (subtype == VSPLUS) |
4294 | set = ! set; | 4272 | set = !set; |
4295 | 4273 | ||
4296 | easy = ((varflags & VSQUOTE) == 0 || | 4274 | easy = ((varflags & VSQUOTE) == 0 || |
4297 | (*var == '@' && shellparam.nparam != 1)); | 4275 | (*var == '@' && shellparam.nparam != 1)); |
4298 | 4276 | ||
4299 | 4277 | ||
4300 | switch (subtype) { | 4278 | switch (subtype) { |
@@ -4305,9 +4283,8 @@ again: /* jump here after setting a variable with ${var=text} */ | |||
4305 | case VSNORMAL: | 4283 | case VSNORMAL: |
4306 | if (!easy) | 4284 | if (!easy) |
4307 | break; | 4285 | break; |
4308 | record: | 4286 | record: |
4309 | recordregion(startloc, expdest - stackblock(), | 4287 | recordregion(startloc, expdest - stackblock(), varflags & VSQUOTE); |
4310 | varflags & VSQUOTE); | ||
4311 | break; | 4288 | break; |
4312 | 4289 | ||
4313 | case VSPLUS: | 4290 | case VSPLUS: |
@@ -4333,8 +4310,9 @@ record: | |||
4333 | STPUTC('\0', expdest); | 4310 | STPUTC('\0', expdest); |
4334 | patloc = expdest - stackblock(); | 4311 | patloc = expdest - stackblock(); |
4335 | if (subevalvar(p, NULL, patloc, subtype, | 4312 | if (subevalvar(p, NULL, patloc, subtype, |
4336 | startloc, varflags, quotes) == 0) { | 4313 | startloc, varflags, quotes) == 0) { |
4337 | int amount = (expdest - stackblock() - patloc) + 1; | 4314 | int amount = (expdest - stackblock() - patloc) + 1; |
4315 | |||
4338 | STADJUST(-amount, expdest); | 4316 | STADJUST(-amount, expdest); |
4339 | } | 4317 | } |
4340 | /* Remove any recorded regions beyond start of variable */ | 4318 | /* Remove any recorded regions beyond start of variable */ |
@@ -4344,8 +4322,7 @@ record: | |||
4344 | case VSASSIGN: | 4322 | case VSASSIGN: |
4345 | case VSQUESTION: | 4323 | case VSQUESTION: |
4346 | if (!set) { | 4324 | if (!set) { |
4347 | if (subevalvar(p, var, 0, subtype, startloc, | 4325 | if (subevalvar(p, var, 0, subtype, startloc, varflags, quotes)) { |
4348 | varflags, quotes)) { | ||
4349 | varflags &= ~VSNUL; | 4326 | varflags &= ~VSNUL; |
4350 | /* | 4327 | /* |
4351 | * Remove any recorded regions beyond | 4328 | * Remove any recorded regions beyond |
@@ -4366,12 +4343,13 @@ record: | |||
4366 | #endif | 4343 | #endif |
4367 | } | 4344 | } |
4368 | 4345 | ||
4369 | if (subtype != VSNORMAL) { /* skip to end of alternative */ | 4346 | if (subtype != VSNORMAL) { /* skip to end of alternative */ |
4370 | int nesting = 1; | 4347 | int nesting = 1; |
4348 | |||
4371 | for (;;) { | 4349 | for (;;) { |
4372 | if ((c = *p++) == CTLESC) | 4350 | if ((c = *p++) == CTLESC) |
4373 | p++; | 4351 | p++; |
4374 | else if (c == CTLBACKQ || c == (CTLBACKQ|CTLQUOTE)) { | 4352 | else if (c == CTLBACKQ || c == (CTLBACKQ | CTLQUOTE)) { |
4375 | if (set) | 4353 | if (set) |
4376 | argbackq = argbackq->next; | 4354 | argbackq = argbackq->next; |
4377 | } else if (c == CTLVAR) { | 4355 | } else if (c == CTLVAR) { |
@@ -4393,11 +4371,10 @@ record: | |||
4393 | * $@ like $* since no splitting will be performed. | 4371 | * $@ like $* since no splitting will be performed. |
4394 | */ | 4372 | */ |
4395 | 4373 | ||
4396 | static void | 4374 | static void argstr(char *p, int flag) |
4397 | argstr(char *p, int flag) | ||
4398 | { | 4375 | { |
4399 | char c; | 4376 | char c; |
4400 | int quotes = flag & (EXP_FULL | EXP_CASE); /* do CTLESC */ | 4377 | int quotes = flag & (EXP_FULL | EXP_CASE); /* do CTLESC */ |
4401 | int firsteq = 1; | 4378 | int firsteq = 1; |
4402 | 4379 | ||
4403 | if (*p == '~' && (flag & (EXP_TILDE | EXP_VARTILDE))) | 4380 | if (*p == '~' && (flag & (EXP_TILDE | EXP_VARTILDE))) |
@@ -4405,7 +4382,7 @@ argstr(char *p, int flag) | |||
4405 | for (;;) { | 4382 | for (;;) { |
4406 | switch (c = *p++) { | 4383 | switch (c = *p++) { |
4407 | case '\0': | 4384 | case '\0': |
4408 | case CTLENDVAR: /* ??? */ | 4385 | case CTLENDVAR: /* ??? */ |
4409 | return; | 4386 | return; |
4410 | case CTLQUOTEMARK: | 4387 | case CTLQUOTEMARK: |
4411 | /* "$@" syntax adherence hack */ | 4388 | /* "$@" syntax adherence hack */ |
@@ -4424,7 +4401,7 @@ argstr(char *p, int flag) | |||
4424 | p = evalvar(p, flag); | 4401 | p = evalvar(p, flag); |
4425 | break; | 4402 | break; |
4426 | case CTLBACKQ: | 4403 | case CTLBACKQ: |
4427 | case CTLBACKQ|CTLQUOTE: | 4404 | case CTLBACKQ | CTLQUOTE: |
4428 | expbackq(argbackq->n, c & CTLQUOTE, flag); | 4405 | expbackq(argbackq->n, c & CTLQUOTE, flag); |
4429 | argbackq = argbackq->next; | 4406 | argbackq = argbackq->next; |
4430 | break; | 4407 | break; |
@@ -4457,8 +4434,7 @@ argstr(char *p, int flag) | |||
4457 | return; | 4434 | return; |
4458 | } | 4435 | } |
4459 | 4436 | ||
4460 | static char * | 4437 | static char *exptilde(char *p, int flag) |
4461 | exptilde(char *p, int flag) | ||
4462 | { | 4438 | { |
4463 | char c, *startp = p; | 4439 | char c, *startp = p; |
4464 | struct passwd *pw; | 4440 | struct passwd *pw; |
@@ -4466,7 +4442,7 @@ exptilde(char *p, int flag) | |||
4466 | int quotes = flag & (EXP_FULL | EXP_CASE); | 4442 | int quotes = flag & (EXP_FULL | EXP_CASE); |
4467 | 4443 | ||
4468 | while ((c = *p) != '\0') { | 4444 | while ((c = *p) != '\0') { |
4469 | switch(c) { | 4445 | switch (c) { |
4470 | case CTLESC: | 4446 | case CTLESC: |
4471 | return (startp); | 4447 | return (startp); |
4472 | case CTLQUOTEMARK: | 4448 | case CTLQUOTEMARK: |
@@ -4480,13 +4456,13 @@ exptilde(char *p, int flag) | |||
4480 | } | 4456 | } |
4481 | p++; | 4457 | p++; |
4482 | } | 4458 | } |
4483 | done: | 4459 | done: |
4484 | *p = '\0'; | 4460 | *p = '\0'; |
4485 | if (*(startp+1) == '\0') { | 4461 | if (*(startp + 1) == '\0') { |
4486 | if ((home = lookupvar("HOME")) == NULL) | 4462 | if ((home = lookupvar("HOME")) == NULL) |
4487 | goto lose; | 4463 | goto lose; |
4488 | } else { | 4464 | } else { |
4489 | if ((pw = getpwnam(startp+1)) == NULL) | 4465 | if ((pw = getpwnam(startp + 1)) == NULL) |
4490 | goto lose; | 4466 | goto lose; |
4491 | home = pw->pw_dir; | 4467 | home = pw->pw_dir; |
4492 | } | 4468 | } |
@@ -4495,14 +4471,13 @@ done: | |||
4495 | *p = c; | 4471 | *p = c; |
4496 | strtodest(home, SQSYNTAX, quotes); | 4472 | strtodest(home, SQSYNTAX, quotes); |
4497 | return (p); | 4473 | return (p); |
4498 | lose: | 4474 | lose: |
4499 | *p = c; | 4475 | *p = c; |
4500 | return (startp); | 4476 | return (startp); |
4501 | } | 4477 | } |
4502 | 4478 | ||
4503 | 4479 | ||
4504 | static void | 4480 | static void removerecordregions(int endoff) |
4505 | removerecordregions(int endoff) | ||
4506 | { | 4481 | { |
4507 | if (ifslastp == NULL) | 4482 | if (ifslastp == NULL) |
4508 | return; | 4483 | return; |
@@ -4510,6 +4485,7 @@ removerecordregions(int endoff) | |||
4510 | if (ifsfirst.endoff > endoff) { | 4485 | if (ifsfirst.endoff > endoff) { |
4511 | while (ifsfirst.next != NULL) { | 4486 | while (ifsfirst.next != NULL) { |
4512 | struct ifsregion *ifsp; | 4487 | struct ifsregion *ifsp; |
4488 | |||
4513 | INTOFF; | 4489 | INTOFF; |
4514 | ifsp = ifsfirst.next->next; | 4490 | ifsp = ifsfirst.next->next; |
4515 | free(ifsfirst.next); | 4491 | free(ifsfirst.next); |
@@ -4527,9 +4503,10 @@ removerecordregions(int endoff) | |||
4527 | 4503 | ||
4528 | ifslastp = &ifsfirst; | 4504 | ifslastp = &ifsfirst; |
4529 | while (ifslastp->next && ifslastp->next->begoff < endoff) | 4505 | while (ifslastp->next && ifslastp->next->begoff < endoff) |
4530 | ifslastp=ifslastp->next; | 4506 | ifslastp = ifslastp->next; |
4531 | while (ifslastp->next != NULL) { | 4507 | while (ifslastp->next != NULL) { |
4532 | struct ifsregion *ifsp; | 4508 | struct ifsregion *ifsp; |
4509 | |||
4533 | INTOFF; | 4510 | INTOFF; |
4534 | ifsp = ifslastp->next->next; | 4511 | ifsp = ifslastp->next->next; |
4535 | free(ifslastp->next); | 4512 | free(ifslastp->next); |
@@ -4546,8 +4523,7 @@ removerecordregions(int endoff) | |||
4546 | * Expand arithmetic expression. Backup to start of expression, | 4523 | * Expand arithmetic expression. Backup to start of expression, |
4547 | * evaluate, place result in (backed up) result, adjust string position. | 4524 | * evaluate, place result in (backed up) result, adjust string position. |
4548 | */ | 4525 | */ |
4549 | static void | 4526 | static void expari(int flag) |
4550 | expari(int flag) | ||
4551 | { | 4527 | { |
4552 | char *p, *start; | 4528 | char *p, *start; |
4553 | int errcode; | 4529 | int errcode; |
@@ -4576,30 +4552,29 @@ expari(int flag) | |||
4576 | --p; | 4552 | --p; |
4577 | if (*p != CTLARI) | 4553 | if (*p != CTLARI) |
4578 | error("missing CTLARI (shouldn't happen)"); | 4554 | error("missing CTLARI (shouldn't happen)"); |
4579 | if (p > start && *(p-1) == CTLESC) | 4555 | if (p > start && *(p - 1) == CTLESC) |
4580 | for (p = start; *p != CTLARI; p++) | 4556 | for (p = start; *p != CTLARI; p++) |
4581 | if (*p == CTLESC) | 4557 | if (*p == CTLESC) |
4582 | p++; | 4558 | p++; |
4583 | 4559 | ||
4584 | if (p[1] == '"') | 4560 | if (p[1] == '"') |
4585 | quoted=1; | 4561 | quoted = 1; |
4586 | else | 4562 | else |
4587 | quoted=0; | 4563 | quoted = 0; |
4588 | begoff = p - start; | 4564 | begoff = p - start; |
4589 | removerecordregions(begoff); | 4565 | removerecordregions(begoff); |
4590 | if (quotes) | 4566 | if (quotes) |
4591 | rmescapes(p+2); | 4567 | rmescapes(p + 2); |
4592 | result = arith(p+2, &errcode); | 4568 | result = arith(p + 2, &errcode); |
4593 | if (errcode < 0) { | 4569 | if (errcode < 0) { |
4594 | if(errcode == -2) | 4570 | if (errcode == -2) |
4595 | error("divide by zero"); | 4571 | error("divide by zero"); |
4596 | else | 4572 | else |
4597 | error("syntax error: \"%s\"\n", p+2); | 4573 | error("syntax error: \"%s\"\n", p + 2); |
4598 | } | 4574 | } |
4599 | snprintf(p, 12, "%d", result); | 4575 | snprintf(p, 12, "%d", result); |
4600 | 4576 | ||
4601 | while (*p++) | 4577 | while (*p++); |
4602 | ; | ||
4603 | 4578 | ||
4604 | if (quoted == 0) | 4579 | if (quoted == 0) |
4605 | recordregion(begoff, p - 1 - start, 0); | 4580 | recordregion(begoff, p - 1 - start, 0); |
@@ -4612,8 +4587,7 @@ expari(int flag) | |||
4612 | * Expand stuff in backwards quotes. | 4587 | * Expand stuff in backwards quotes. |
4613 | */ | 4588 | */ |
4614 | 4589 | ||
4615 | static void | 4590 | static void expbackq(union node *cmd, int quoted, int flag) |
4616 | expbackq(union node *cmd, int quoted, int flag) | ||
4617 | { | 4591 | { |
4618 | volatile struct backcmd in; | 4592 | volatile struct backcmd in; |
4619 | int i; | 4593 | int i; |
@@ -4657,7 +4631,7 @@ expbackq(union node *cmd, int quoted, int flag) | |||
4657 | p = grabstackstr(dest); | 4631 | p = grabstackstr(dest); |
4658 | evalbackcmd(cmd, (struct backcmd *) &in); | 4632 | evalbackcmd(cmd, (struct backcmd *) &in); |
4659 | ungrabstackstr(p, dest); | 4633 | ungrabstackstr(p, dest); |
4660 | err1: | 4634 | err1: |
4661 | INTOFF; | 4635 | INTOFF; |
4662 | ifsfirst = saveifs; | 4636 | ifsfirst = saveifs; |
4663 | ifslastp = savelastp; | 4637 | ifslastp = savelastp; |
@@ -4692,7 +4666,7 @@ err1: | |||
4692 | for (; dest > stackblock() && dest[-1] == '\n';) | 4666 | for (; dest > stackblock() && dest[-1] == '\n';) |
4693 | STUNPUTC(dest); | 4667 | STUNPUTC(dest); |
4694 | 4668 | ||
4695 | err2: | 4669 | err2: |
4696 | if (in.fd >= 0) | 4670 | if (in.fd >= 0) |
4697 | close(in.fd); | 4671 | close(in.fd); |
4698 | free(in.buf); | 4672 | free(in.buf); |
@@ -4705,15 +4679,15 @@ err2: | |||
4705 | if (quoted == 0) | 4679 | if (quoted == 0) |
4706 | recordregion(startloc, dest - stackblock(), 0); | 4680 | recordregion(startloc, dest - stackblock(), 0); |
4707 | TRACE(("evalbackq: size=%d: \"%.*s\"\n", | 4681 | TRACE(("evalbackq: size=%d: \"%.*s\"\n", |
4708 | (dest - stackblock()) - startloc, | 4682 | (dest - stackblock()) - startloc, |
4709 | (dest - stackblock()) - startloc, | 4683 | (dest - stackblock()) - startloc, stackblock() + startloc)); |
4710 | stackblock() + startloc)); | ||
4711 | expdest = dest; | 4684 | expdest = dest; |
4712 | INTON; | 4685 | INTON; |
4713 | } | 4686 | } |
4714 | 4687 | ||
4715 | static int | 4688 | static int |
4716 | subevalvar(char *p, char *str, int strloc, int subtype, int startloc, int varflags, int quotes) | 4689 | subevalvar(char *p, char *str, int strloc, int subtype, int startloc, |
4690 | int varflags, int quotes) | ||
4717 | { | 4691 | { |
4718 | char *startp; | 4692 | char *startp; |
4719 | char *loc = NULL; | 4693 | char *loc = NULL; |
@@ -4730,7 +4704,7 @@ subevalvar(char *p, char *str, int strloc, int subtype, int startloc, int varfla | |||
4730 | argbackq = saveargbackq; | 4704 | argbackq = saveargbackq; |
4731 | startp = stackblock() + startloc; | 4705 | startp = stackblock() + startloc; |
4732 | if (str == NULL) | 4706 | if (str == NULL) |
4733 | str = stackblock() + strloc; | 4707 | str = stackblock() + strloc; |
4734 | 4708 | ||
4735 | switch (subtype) { | 4709 | switch (subtype) { |
4736 | case VSASSIGN: | 4710 | case VSASSIGN: |
@@ -4745,11 +4719,10 @@ subevalvar(char *p, char *str, int strloc, int subtype, int startloc, int varfla | |||
4745 | case VSQUESTION: | 4719 | case VSQUESTION: |
4746 | if (*p != CTLENDVAR) { | 4720 | if (*p != CTLENDVAR) { |
4747 | out2fmt(snlfmt, startp); | 4721 | out2fmt(snlfmt, startp); |
4748 | error((char *)NULL); | 4722 | error((char *) NULL); |
4749 | } | 4723 | } |
4750 | error("%.*s: parameter %snot set", p - str - 1, | 4724 | error("%.*s: parameter %snot set", p - str - 1, |
4751 | str, (varflags & VSNUL) ? "null or " | 4725 | str, (varflags & VSNUL) ? "null or " : nullstr); |
4752 | : nullstr); | ||
4753 | /* NOTREACHED */ | 4726 | /* NOTREACHED */ |
4754 | 4727 | ||
4755 | case VSTRIMLEFT: | 4728 | case VSTRIMLEFT: |
@@ -4812,7 +4785,7 @@ subevalvar(char *p, char *str, int strloc, int subtype, int startloc, int varfla | |||
4812 | #endif | 4785 | #endif |
4813 | } | 4786 | } |
4814 | 4787 | ||
4815 | recordleft: | 4788 | recordleft: |
4816 | *loc = c; | 4789 | *loc = c; |
4817 | amount = ((str - 1) - (loc - startp)) - expdest; | 4790 | amount = ((str - 1) - (loc - startp)) - expdest; |
4818 | STADJUST(amount, expdest); | 4791 | STADJUST(amount, expdest); |
@@ -4820,7 +4793,7 @@ recordleft: | |||
4820 | *startp++ = *loc++; | 4793 | *startp++ = *loc++; |
4821 | return 1; | 4794 | return 1; |
4822 | 4795 | ||
4823 | recordright: | 4796 | recordright: |
4824 | amount = loc - expdest; | 4797 | amount = loc - expdest; |
4825 | STADJUST(amount, expdest); | 4798 | STADJUST(amount, expdest); |
4826 | STPUTC('\0', expdest); | 4799 | STPUTC('\0', expdest); |
@@ -4833,8 +4806,7 @@ recordright: | |||
4833 | * Test whether a specialized variable is set. | 4806 | * Test whether a specialized variable is set. |
4834 | */ | 4807 | */ |
4835 | 4808 | ||
4836 | static int | 4809 | static int varisset(char *name, int nulok) |
4837 | varisset(char *name, int nulok) | ||
4838 | { | 4810 | { |
4839 | if (*name == '!') | 4811 | if (*name == '!') |
4840 | return backgndpid != -1; | 4812 | return backgndpid != -1; |
@@ -4872,11 +4844,10 @@ varisset(char *name, int nulok) | |||
4872 | * Put a string on the stack. | 4844 | * Put a string on the stack. |
4873 | */ | 4845 | */ |
4874 | 4846 | ||
4875 | static void | 4847 | static void strtodest(const char *p, int syntax, int quotes) |
4876 | strtodest(const char *p, int syntax, int quotes) | ||
4877 | { | 4848 | { |
4878 | while (*p) { | 4849 | while (*p) { |
4879 | if (quotes && SIT(*p,syntax) == CCTL) | 4850 | if (quotes && SIT(*p, syntax) == CCTL) |
4880 | STPUTC(CTLESC, expdest); | 4851 | STPUTC(CTLESC, expdest); |
4881 | STPUTC(*p++, expdest); | 4852 | STPUTC(*p++, expdest); |
4882 | } | 4853 | } |
@@ -4886,8 +4857,7 @@ strtodest(const char *p, int syntax, int quotes) | |||
4886 | * Add the value of a specialized variable to the stack string. | 4857 | * Add the value of a specialized variable to the stack string. |
4887 | */ | 4858 | */ |
4888 | 4859 | ||
4889 | static inline void | 4860 | static inline void varvalue(char *name, int quoted, int flags) |
4890 | varvalue(char *name, int quoted, int flags) | ||
4891 | { | 4861 | { |
4892 | int num; | 4862 | int num; |
4893 | char *p; | 4863 | char *p; |
@@ -4912,11 +4882,11 @@ varvalue(char *name, int quoted, int flags) | |||
4912 | goto numvar; | 4882 | goto numvar; |
4913 | case '!': | 4883 | case '!': |
4914 | num = backgndpid; | 4884 | num = backgndpid; |
4915 | numvar: | 4885 | numvar: |
4916 | expdest = cvtnum(num, expdest); | 4886 | expdest = cvtnum(num, expdest); |
4917 | break; | 4887 | break; |
4918 | case '-': | 4888 | case '-': |
4919 | for (i = 0 ; i < NOPTS ; i++) { | 4889 | for (i = 0; i < NOPTS; i++) { |
4920 | if (optent_val(i)) | 4890 | if (optent_val(i)) |
4921 | STPUTC(optent_letter(optlist[i]), expdest); | 4891 | STPUTC(optent_letter(optlist[i]), expdest); |
4922 | } | 4892 | } |
@@ -4928,12 +4898,12 @@ numvar: | |||
4928 | } | 4898 | } |
4929 | /* fall through */ | 4899 | /* fall through */ |
4930 | case '*': | 4900 | case '*': |
4931 | sep = ifsset() ? ifsval()[0] : ' '; | 4901 | sep = ifsset()? ifsval()[0] : ' '; |
4932 | if (quotes) { | 4902 | if (quotes) { |
4933 | sepq = SIT(sep,syntax) == CCTL; | 4903 | sepq = SIT(sep, syntax) == CCTL; |
4934 | } | 4904 | } |
4935 | param: | 4905 | param: |
4936 | for (ap = shellparam.p ; (p = *ap++) != NULL ; ) { | 4906 | for (ap = shellparam.p; (p = *ap++) != NULL;) { |
4937 | strtodest(p, syntax, quotes); | 4907 | strtodest(p, syntax, quotes); |
4938 | if (*ap && sep) { | 4908 | if (*ap && sep) { |
4939 | if (sepq) | 4909 | if (sepq) |
@@ -4960,8 +4930,7 @@ param: | |||
4960 | * string for IFS characters. | 4930 | * string for IFS characters. |
4961 | */ | 4931 | */ |
4962 | 4932 | ||
4963 | static void | 4933 | static void recordregion(int start, int end, int nulonly) |
4964 | recordregion(int start, int end, int nulonly) | ||
4965 | { | 4934 | { |
4966 | struct ifsregion *ifsp; | 4935 | struct ifsregion *ifsp; |
4967 | 4936 | ||
@@ -4969,7 +4938,7 @@ recordregion(int start, int end, int nulonly) | |||
4969 | ifsp = &ifsfirst; | 4938 | ifsp = &ifsfirst; |
4970 | } else { | 4939 | } else { |
4971 | INTOFF; | 4940 | INTOFF; |
4972 | ifsp = (struct ifsregion *)xmalloc(sizeof (struct ifsregion)); | 4941 | ifsp = (struct ifsregion *) xmalloc(sizeof(struct ifsregion)); |
4973 | ifsp->next = NULL; | 4942 | ifsp->next = NULL; |
4974 | ifslastp->next = ifsp; | 4943 | ifslastp->next = ifsp; |
4975 | INTON; | 4944 | INTON; |
@@ -4987,8 +4956,7 @@ recordregion(int start, int end, int nulonly) | |||
4987 | * strings to the argument list. The regions of the string to be | 4956 | * strings to the argument list. The regions of the string to be |
4988 | * searched for IFS characters have been stored by recordregion. | 4957 | * searched for IFS characters have been stored by recordregion. |
4989 | */ | 4958 | */ |
4990 | static void | 4959 | static void ifsbreakup(char *string, struct arglist *arglist) |
4991 | ifsbreakup(char *string, struct arglist *arglist) | ||
4992 | { | 4960 | { |
4993 | struct ifsregion *ifsp; | 4961 | struct ifsregion *ifsp; |
4994 | struct strlist *sp; | 4962 | struct strlist *sp; |
@@ -5003,7 +4971,7 @@ ifsbreakup(char *string, struct arglist *arglist) | |||
5003 | start = string; | 4971 | start = string; |
5004 | ifsspc = 0; | 4972 | ifsspc = 0; |
5005 | nulonly = 0; | 4973 | nulonly = 0; |
5006 | realifs = ifsset() ? ifsval() : defifs; | 4974 | realifs = ifsset()? ifsval() : defifs; |
5007 | if (ifslastp != NULL) { | 4975 | if (ifslastp != NULL) { |
5008 | ifsp = &ifsfirst; | 4976 | ifsp = &ifsfirst; |
5009 | do { | 4977 | do { |
@@ -5025,7 +4993,7 @@ ifsbreakup(char *string, struct arglist *arglist) | |||
5025 | continue; | 4993 | continue; |
5026 | } | 4994 | } |
5027 | *q = '\0'; | 4995 | *q = '\0'; |
5028 | sp = (struct strlist *)stalloc(sizeof *sp); | 4996 | sp = (struct strlist *) stalloc(sizeof *sp); |
5029 | sp->text = start; | 4997 | sp->text = start; |
5030 | *arglist->lastp = sp; | 4998 | *arglist->lastp = sp; |
5031 | arglist->lastp = &sp->next; | 4999 | arglist->lastp = &sp->next; |
@@ -5038,7 +5006,7 @@ ifsbreakup(char *string, struct arglist *arglist) | |||
5038 | q = p; | 5006 | q = p; |
5039 | if (*p == CTLESC) | 5007 | if (*p == CTLESC) |
5040 | p++; | 5008 | p++; |
5041 | if (strchr(ifs, *p) == NULL ) { | 5009 | if (strchr(ifs, *p) == NULL) { |
5042 | p = q; | 5010 | p = q; |
5043 | break; | 5011 | break; |
5044 | } else if (strchr(defifs, *p) == NULL) { | 5012 | } else if (strchr(defifs, *p) == NULL) { |
@@ -5063,17 +5031,17 @@ ifsbreakup(char *string, struct arglist *arglist) | |||
5063 | } | 5031 | } |
5064 | } | 5032 | } |
5065 | 5033 | ||
5066 | sp = (struct strlist *)stalloc(sizeof *sp); | 5034 | sp = (struct strlist *) stalloc(sizeof *sp); |
5067 | sp->text = start; | 5035 | sp->text = start; |
5068 | *arglist->lastp = sp; | 5036 | *arglist->lastp = sp; |
5069 | arglist->lastp = &sp->next; | 5037 | arglist->lastp = &sp->next; |
5070 | } | 5038 | } |
5071 | 5039 | ||
5072 | static void | 5040 | static void ifsfree(void) |
5073 | ifsfree(void) | ||
5074 | { | 5041 | { |
5075 | while (ifsfirst.next != NULL) { | 5042 | while (ifsfirst.next != NULL) { |
5076 | struct ifsregion *ifsp; | 5043 | struct ifsregion *ifsp; |
5044 | |||
5077 | INTOFF; | 5045 | INTOFF; |
5078 | ifsp = ifsfirst.next->next; | 5046 | ifsp = ifsfirst.next->next; |
5079 | free(ifsfirst.next); | 5047 | free(ifsfirst.next); |
@@ -5088,12 +5056,11 @@ ifsfree(void) | |||
5088 | * Add a file name to the list. | 5056 | * Add a file name to the list. |
5089 | */ | 5057 | */ |
5090 | 5058 | ||
5091 | static void | 5059 | static void addfname(const char *name) |
5092 | addfname(const char *name) | ||
5093 | { | 5060 | { |
5094 | struct strlist *sp; | 5061 | struct strlist *sp; |
5095 | 5062 | ||
5096 | sp = (struct strlist *)stalloc(sizeof *sp); | 5063 | sp = (struct strlist *) stalloc(sizeof *sp); |
5097 | sp->text = sstrdup(name); | 5064 | sp->text = sstrdup(name); |
5098 | *exparg.lastp = sp; | 5065 | *exparg.lastp = sp; |
5099 | exparg.lastp = &sp->next; | 5066 | exparg.lastp = &sp->next; |
@@ -5105,11 +5072,11 @@ addfname(const char *name) | |||
5105 | */ | 5072 | */ |
5106 | 5073 | ||
5107 | #if defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN) | 5074 | #if defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN) |
5108 | static void | 5075 | static void expandmeta(struct strlist *str, int flag) |
5109 | expandmeta(struct strlist *str, int flag) | ||
5110 | { | 5076 | { |
5111 | const char *p; | 5077 | const char *p; |
5112 | glob_t pglob; | 5078 | glob_t pglob; |
5079 | |||
5113 | /* TODO - EXP_REDIR */ | 5080 | /* TODO - EXP_REDIR */ |
5114 | 5081 | ||
5115 | while (str) { | 5082 | while (str) { |
@@ -5119,22 +5086,22 @@ expandmeta(struct strlist *str, int flag) | |||
5119 | INTOFF; | 5086 | INTOFF; |
5120 | switch (glob(p, 0, 0, &pglob)) { | 5087 | switch (glob(p, 0, 0, &pglob)) { |
5121 | case 0: | 5088 | case 0: |
5122 | if(pglob.gl_pathv[1]==0 && !strcmp(p, pglob.gl_pathv[0])) | 5089 | if (pglob.gl_pathv[1] == 0 && !strcmp(p, pglob.gl_pathv[0])) |
5123 | goto nometa2; | 5090 | goto nometa2; |
5124 | addglob(&pglob); | 5091 | addglob(&pglob); |
5125 | globfree(&pglob); | 5092 | globfree(&pglob); |
5126 | INTON; | 5093 | INTON; |
5127 | break; | 5094 | break; |
5128 | case GLOB_NOMATCH: | 5095 | case GLOB_NOMATCH: |
5129 | nometa2: | 5096 | nometa2: |
5130 | globfree(&pglob); | 5097 | globfree(&pglob); |
5131 | INTON; | 5098 | INTON; |
5132 | nometa: | 5099 | nometa: |
5133 | *exparg.lastp = str; | 5100 | *exparg.lastp = str; |
5134 | rmescapes(str->text); | 5101 | rmescapes(str->text); |
5135 | exparg.lastp = &str->next; | 5102 | exparg.lastp = &str->next; |
5136 | break; | 5103 | break; |
5137 | default: /* GLOB_NOSPACE */ | 5104 | default: /* GLOB_NOSPACE */ |
5138 | error("Out of space"); | 5105 | error("Out of space"); |
5139 | } | 5106 | } |
5140 | str = str->next; | 5107 | str = str->next; |
@@ -5146,8 +5113,7 @@ nometa: | |||
5146 | * Add the result of glob(3) to the list. | 5113 | * Add the result of glob(3) to the list. |
5147 | */ | 5114 | */ |
5148 | 5115 | ||
5149 | static inline void | 5116 | static inline void addglob(const glob_t * pglob) |
5150 | addglob(const glob_t *pglob) | ||
5151 | { | 5117 | { |
5152 | char **p = pglob->gl_pathv; | 5118 | char **p = pglob->gl_pathv; |
5153 | 5119 | ||
@@ -5157,24 +5123,24 @@ addglob(const glob_t *pglob) | |||
5157 | } | 5123 | } |
5158 | 5124 | ||
5159 | 5125 | ||
5160 | #else /* defined(__GLIBC__) && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN) */ | 5126 | #else /* defined(__GLIBC__) && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN) */ |
5161 | static char *expdir; | 5127 | static char *expdir; |
5162 | 5128 | ||
5163 | 5129 | ||
5164 | static void | 5130 | static void expandmeta(struct strlist *str, int flag) |
5165 | expandmeta(struct strlist *str, int flag) | ||
5166 | { | 5131 | { |
5167 | char *p; | 5132 | char *p; |
5168 | struct strlist **savelastp; | 5133 | struct strlist **savelastp; |
5169 | struct strlist *sp; | 5134 | struct strlist *sp; |
5170 | char c; | 5135 | char c; |
5136 | |||
5171 | /* TODO - EXP_REDIR */ | 5137 | /* TODO - EXP_REDIR */ |
5172 | 5138 | ||
5173 | while (str) { | 5139 | while (str) { |
5174 | if (fflag) | 5140 | if (fflag) |
5175 | goto nometa; | 5141 | goto nometa; |
5176 | p = str->text; | 5142 | p = str->text; |
5177 | for (;;) { /* fast check for meta chars */ | 5143 | for (;;) { /* fast check for meta chars */ |
5178 | if ((c = *p++) == '\0') | 5144 | if ((c = *p++) == '\0') |
5179 | goto nometa; | 5145 | goto nometa; |
5180 | if (c == '*' || c == '?' || c == '[' || c == '!') | 5146 | if (c == '*' || c == '?' || c == '[' || c == '!') |
@@ -5184,7 +5150,8 @@ expandmeta(struct strlist *str, int flag) | |||
5184 | INTOFF; | 5150 | INTOFF; |
5185 | if (expdir == NULL) { | 5151 | if (expdir == NULL) { |
5186 | int i = strlen(str->text); | 5152 | int i = strlen(str->text); |
5187 | expdir = xmalloc(i < 2048 ? 2048 : i); /* XXX */ | 5153 | |
5154 | expdir = xmalloc(i < 2048 ? 2048 : i); /* XXX */ | ||
5188 | } | 5155 | } |
5189 | 5156 | ||
5190 | expmeta(expdir, str->text); | 5157 | expmeta(expdir, str->text); |
@@ -5195,7 +5162,7 @@ expandmeta(struct strlist *str, int flag) | |||
5195 | /* | 5162 | /* |
5196 | * no matches | 5163 | * no matches |
5197 | */ | 5164 | */ |
5198 | nometa: | 5165 | nometa: |
5199 | *exparg.lastp = str; | 5166 | *exparg.lastp = str; |
5200 | rmescapes(str->text); | 5167 | rmescapes(str->text); |
5201 | exparg.lastp = &str->next; | 5168 | exparg.lastp = &str->next; |
@@ -5215,8 +5182,7 @@ nometa: | |||
5215 | * Do metacharacter (i.e. *, ?, [...]) expansion. | 5182 | * Do metacharacter (i.e. *, ?, [...]) expansion. |
5216 | */ | 5183 | */ |
5217 | 5184 | ||
5218 | static void | 5185 | static void expmeta(char *enddir, char *name) |
5219 | expmeta(char *enddir, char *name) | ||
5220 | { | 5186 | { |
5221 | char *p; | 5187 | char *p; |
5222 | const char *cp; | 5188 | const char *cp; |
@@ -5232,7 +5198,7 @@ expmeta(char *enddir, char *name) | |||
5232 | 5198 | ||
5233 | metaflag = 0; | 5199 | metaflag = 0; |
5234 | start = name; | 5200 | start = name; |
5235 | for (p = name ; ; p++) { | 5201 | for (p = name;; p++) { |
5236 | if (*p == '*' || *p == '?') | 5202 | if (*p == '*' || *p == '?') |
5237 | metaflag = 1; | 5203 | metaflag = 1; |
5238 | else if (*p == '[') { | 5204 | else if (*p == '[') { |
@@ -5265,10 +5231,10 @@ expmeta(char *enddir, char *name) | |||
5265 | start = p + 1; | 5231 | start = p + 1; |
5266 | } | 5232 | } |
5267 | } | 5233 | } |
5268 | if (metaflag == 0) { /* we've reached the end of the file name */ | 5234 | if (metaflag == 0) { /* we've reached the end of the file name */ |
5269 | if (enddir != expdir) | 5235 | if (enddir != expdir) |
5270 | metaflag++; | 5236 | metaflag++; |
5271 | for (p = name ; ; p++) { | 5237 | for (p = name;; p++) { |
5272 | if (*p == CTLQUOTEMARK) | 5238 | if (*p == CTLQUOTEMARK) |
5273 | continue; | 5239 | continue; |
5274 | if (*p == CTLESC) | 5240 | if (*p == CTLESC) |
@@ -5318,16 +5284,15 @@ expmeta(char *enddir, char *name) | |||
5318 | p++; | 5284 | p++; |
5319 | if (*p == '.') | 5285 | if (*p == '.') |
5320 | matchdot++; | 5286 | matchdot++; |
5321 | while (! int_pending() && (dp = readdir(dirp)) != NULL) { | 5287 | while (!int_pending() && (dp = readdir(dirp)) != NULL) { |
5322 | if (dp->d_name[0] == '.' && ! matchdot) | 5288 | if (dp->d_name[0] == '.' && !matchdot) |
5323 | continue; | 5289 | continue; |
5324 | if (patmatch(start, dp->d_name, 0)) { | 5290 | if (patmatch(start, dp->d_name, 0)) { |
5325 | if (atend) { | 5291 | if (atend) { |
5326 | strcpy(enddir, dp->d_name); | 5292 | strcpy(enddir, dp->d_name); |
5327 | addfname(expdir); | 5293 | addfname(expdir); |
5328 | } else { | 5294 | } else { |
5329 | for (p = enddir, cp = dp->d_name; | 5295 | for (p = enddir, cp = dp->d_name; (*p++ = *cp++) != '\0';) |
5330 | (*p++ = *cp++) != '\0';) | ||
5331 | continue; | 5296 | continue; |
5332 | p[-1] = '/'; | 5297 | p[-1] = '/'; |
5333 | expmeta(p, endname); | 5298 | expmeta(p, endname); |
@@ -5335,10 +5300,10 @@ expmeta(char *enddir, char *name) | |||
5335 | } | 5300 | } |
5336 | } | 5301 | } |
5337 | closedir(dirp); | 5302 | closedir(dirp); |
5338 | if (! atend) | 5303 | if (!atend) |
5339 | endname[-1] = '/'; | 5304 | endname[-1] = '/'; |
5340 | } | 5305 | } |
5341 | #endif /* defined(__GLIBC__) && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN) */ | 5306 | #endif /* defined(__GLIBC__) && !defined(FNMATCH_BROKEN) && !defined(GLOB_BROKEN) */ |
5342 | 5307 | ||
5343 | 5308 | ||
5344 | 5309 | ||
@@ -5349,21 +5314,19 @@ expmeta(char *enddir, char *name) | |||
5349 | * work. | 5314 | * work. |
5350 | */ | 5315 | */ |
5351 | 5316 | ||
5352 | static struct strlist * | 5317 | static struct strlist *expsort(struct strlist *str) |
5353 | expsort(struct strlist *str) | ||
5354 | { | 5318 | { |
5355 | int len; | 5319 | int len; |
5356 | struct strlist *sp; | 5320 | struct strlist *sp; |
5357 | 5321 | ||
5358 | len = 0; | 5322 | len = 0; |
5359 | for (sp = str ; sp ; sp = sp->next) | 5323 | for (sp = str; sp; sp = sp->next) |
5360 | len++; | 5324 | len++; |
5361 | return msort(str, len); | 5325 | return msort(str, len); |
5362 | } | 5326 | } |
5363 | 5327 | ||
5364 | 5328 | ||
5365 | static struct strlist * | 5329 | static struct strlist *msort(struct strlist *list, int len) |
5366 | msort(struct strlist *list, int len) | ||
5367 | { | 5330 | { |
5368 | struct strlist *p, *q = NULL; | 5331 | struct strlist *p, *q = NULL; |
5369 | struct strlist **lpp; | 5332 | struct strlist **lpp; |
@@ -5374,13 +5337,13 @@ msort(struct strlist *list, int len) | |||
5374 | return list; | 5337 | return list; |
5375 | half = len >> 1; | 5338 | half = len >> 1; |
5376 | p = list; | 5339 | p = list; |
5377 | for (n = half ; --n >= 0 ; ) { | 5340 | for (n = half; --n >= 0;) { |
5378 | q = p; | 5341 | q = p; |
5379 | p = p->next; | 5342 | p = p->next; |
5380 | } | 5343 | } |
5381 | q->next = NULL; /* terminate first half of list */ | 5344 | q->next = NULL; /* terminate first half of list */ |
5382 | q = msort(list, half); /* sort first half of list */ | 5345 | q = msort(list, half); /* sort first half of list */ |
5383 | p = msort(p, len - half); /* sort second half */ | 5346 | p = msort(p, len - half); /* sort second half */ |
5384 | lpp = &list; | 5347 | lpp = &list; |
5385 | for (;;) { | 5348 | for (;;) { |
5386 | if (strcmp(p->text, q->text) < 0) { | 5349 | if (strcmp(p->text, q->text) < 0) { |
@@ -5411,8 +5374,7 @@ msort(struct strlist *list, int len) | |||
5411 | 5374 | ||
5412 | #if defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN) | 5375 | #if defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN) |
5413 | /* squoted: string might have quote chars */ | 5376 | /* squoted: string might have quote chars */ |
5414 | static int | 5377 | static int patmatch(char *pattern, char *string, int squoted) |
5415 | patmatch(char *pattern, char *string, int squoted) | ||
5416 | { | 5378 | { |
5417 | const char *p; | 5379 | const char *p; |
5418 | char *q; | 5380 | char *q; |
@@ -5424,8 +5386,7 @@ patmatch(char *pattern, char *string, int squoted) | |||
5424 | } | 5386 | } |
5425 | 5387 | ||
5426 | 5388 | ||
5427 | static int | 5389 | static int patmatch2(char *pattern, char *string, int squoted) |
5428 | patmatch2(char *pattern, char *string, int squoted) | ||
5429 | { | 5390 | { |
5430 | char *p; | 5391 | char *p; |
5431 | int res; | 5392 | int res; |
@@ -5437,14 +5398,13 @@ patmatch2(char *pattern, char *string, int squoted) | |||
5437 | return res; | 5398 | return res; |
5438 | } | 5399 | } |
5439 | #else | 5400 | #else |
5440 | static int | 5401 | static int patmatch(char *pattern, char *string, int squoted) |
5441 | patmatch(char *pattern, char *string, int squoted) { | 5402 | { |
5442 | return pmatch(pattern, string, squoted); | 5403 | return pmatch(pattern, string, squoted); |
5443 | } | 5404 | } |
5444 | 5405 | ||
5445 | 5406 | ||
5446 | static int | 5407 | static int pmatch(char *pattern, char *string, int squoted) |
5447 | pmatch(char *pattern, char *string, int squoted) | ||
5448 | { | 5408 | { |
5449 | char *p, *q; | 5409 | char *p, *q; |
5450 | char c; | 5410 | char c; |
@@ -5473,11 +5433,10 @@ pmatch(char *pattern, char *string, int squoted) | |||
5473 | c = *p; | 5433 | c = *p; |
5474 | while (c == CTLQUOTEMARK || c == '*') | 5434 | while (c == CTLQUOTEMARK || c == '*') |
5475 | c = *++p; | 5435 | c = *++p; |
5476 | if (c != CTLESC && c != CTLQUOTEMARK && | 5436 | if (c != CTLESC && c != CTLQUOTEMARK && |
5477 | c != '?' && c != '*' && c != '[') { | 5437 | c != '?' && c != '*' && c != '[') { |
5478 | while (*q != c) { | 5438 | while (*q != c) { |
5479 | if (squoted && *q == CTLESC && | 5439 | if (squoted && *q == CTLESC && q[1] == c) |
5480 | q[1] == c) | ||
5481 | break; | 5440 | break; |
5482 | if (*q == '\0') | 5441 | if (*q == '\0') |
5483 | return 0; | 5442 | return 0; |
@@ -5493,7 +5452,7 @@ pmatch(char *pattern, char *string, int squoted) | |||
5493 | q++; | 5452 | q++; |
5494 | } while (*q++ != '\0'); | 5453 | } while (*q++ != '\0'); |
5495 | return 0; | 5454 | return 0; |
5496 | case '[': { | 5455 | case '[':{ |
5497 | char *endp; | 5456 | char *endp; |
5498 | int invert, found; | 5457 | int invert, found; |
5499 | char chr; | 5458 | char chr; |
@@ -5505,7 +5464,7 @@ pmatch(char *pattern, char *string, int squoted) | |||
5505 | while (*endp == CTLQUOTEMARK) | 5464 | while (*endp == CTLQUOTEMARK) |
5506 | endp++; | 5465 | endp++; |
5507 | if (*endp == '\0') | 5466 | if (*endp == '\0') |
5508 | goto dft; /* no matching ] */ | 5467 | goto dft; /* no matching ] */ |
5509 | if (*endp == CTLESC) | 5468 | if (*endp == CTLESC) |
5510 | endp++; | 5469 | endp++; |
5511 | if (*++endp == ']') | 5470 | if (*++endp == ']') |
@@ -5546,7 +5505,7 @@ pmatch(char *pattern, char *string, int squoted) | |||
5546 | return 0; | 5505 | return 0; |
5547 | break; | 5506 | break; |
5548 | } | 5507 | } |
5549 | dft: default: | 5508 | dft: default: |
5550 | if (squoted && *q == CTLESC) | 5509 | if (squoted && *q == CTLESC) |
5551 | q++; | 5510 | q++; |
5552 | if (*q++ != c) | 5511 | if (*q++ != c) |
@@ -5554,7 +5513,7 @@ dft: default: | |||
5554 | break; | 5513 | break; |
5555 | } | 5514 | } |
5556 | } | 5515 | } |
5557 | breakloop: | 5516 | breakloop: |
5558 | if (*q != '\0') | 5517 | if (*q != '\0') |
5559 | return 0; | 5518 | return 0; |
5560 | return 1; | 5519 | return 1; |
@@ -5568,8 +5527,7 @@ breakloop: | |||
5568 | */ | 5527 | */ |
5569 | 5528 | ||
5570 | #if defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN) | 5529 | #if defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN) |
5571 | static char * | 5530 | static char *_rmescapes(char *str, int flag) |
5572 | _rmescapes(char *str, int flag) | ||
5573 | { | 5531 | { |
5574 | char *p, *q, *r; | 5532 | char *p, *q, *r; |
5575 | static const char qchars[] = { CTLESC, CTLQUOTEMARK, 0 }; | 5533 | static const char qchars[] = { CTLESC, CTLQUOTEMARK, 0 }; |
@@ -5582,6 +5540,7 @@ _rmescapes(char *str, int flag) | |||
5582 | r = str; | 5540 | r = str; |
5583 | if (flag & RMESCAPE_ALLOC) { | 5541 | if (flag & RMESCAPE_ALLOC) { |
5584 | size_t len = p - str; | 5542 | size_t len = p - str; |
5543 | |||
5585 | q = r = stalloc(strlen(p) + len + 1); | 5544 | q = r = stalloc(strlen(p) + len + 1); |
5586 | if (len > 0) { | 5545 | if (len > 0) { |
5587 | memcpy(q, str, len); | 5546 | memcpy(q, str, len); |
@@ -5605,8 +5564,7 @@ _rmescapes(char *str, int flag) | |||
5605 | return r; | 5564 | return r; |
5606 | } | 5565 | } |
5607 | #else | 5566 | #else |
5608 | static void | 5567 | static void rmescapes(char *str) |
5609 | rmescapes(char *str) | ||
5610 | { | 5568 | { |
5611 | char *p, *q; | 5569 | char *p, *q; |
5612 | 5570 | ||
@@ -5635,8 +5593,7 @@ rmescapes(char *str) | |||
5635 | * See if a pattern matches in a case statement. | 5593 | * See if a pattern matches in a case statement. |
5636 | */ | 5594 | */ |
5637 | 5595 | ||
5638 | static int | 5596 | static int casematch(union node *pattern, const char *val) |
5639 | casematch(union node *pattern, const char *val) | ||
5640 | { | 5597 | { |
5641 | struct stackmark smark; | 5598 | struct stackmark smark; |
5642 | int result; | 5599 | int result; |
@@ -5649,7 +5606,7 @@ casematch(union node *pattern, const char *val) | |||
5649 | argstr(pattern->narg.text, EXP_TILDE | EXP_CASE); | 5606 | argstr(pattern->narg.text, EXP_TILDE | EXP_CASE); |
5650 | STPUTC('\0', expdest); | 5607 | STPUTC('\0', expdest); |
5651 | p = grabstackstr(expdest); | 5608 | p = grabstackstr(expdest); |
5652 | result = patmatch(p, (char *)val, 0); | 5609 | result = patmatch(p, (char *) val, 0); |
5653 | popstackmark(&smark); | 5610 | popstackmark(&smark); |
5654 | return result; | 5611 | return result; |
5655 | } | 5612 | } |
@@ -5658,8 +5615,7 @@ casematch(union node *pattern, const char *val) | |||
5658 | * Our own itoa(). | 5615 | * Our own itoa(). |
5659 | */ | 5616 | */ |
5660 | 5617 | ||
5661 | static char * | 5618 | static char *cvtnum(int num, char *buf) |
5662 | cvtnum(int num, char *buf) | ||
5663 | { | 5619 | { |
5664 | int len; | 5620 | int len; |
5665 | 5621 | ||
@@ -5668,6 +5624,7 @@ cvtnum(int num, char *buf) | |||
5668 | STADJUST(len, buf); | 5624 | STADJUST(len, buf); |
5669 | return buf; | 5625 | return buf; |
5670 | } | 5626 | } |
5627 | |||
5671 | /* | 5628 | /* |
5672 | * Editline and history functions (and glue). | 5629 | * Editline and history functions (and glue). |
5673 | */ | 5630 | */ |
@@ -5680,7 +5637,7 @@ static int histcmd(int argc, char **argv) | |||
5680 | 5637 | ||
5681 | struct redirtab { | 5638 | struct redirtab { |
5682 | struct redirtab *next; | 5639 | struct redirtab *next; |
5683 | short renamed[10]; /* Current ash support only 0-9 descriptors */ | 5640 | short renamed[10]; /* Current ash support only 0-9 descriptors */ |
5684 | /* char on arm (and others) can't be negative */ | 5641 | /* char on arm (and others) can't be negative */ |
5685 | }; | 5642 | }; |
5686 | 5643 | ||
@@ -5694,35 +5651,35 @@ extern char **environ; | |||
5694 | * Initialization code. | 5651 | * Initialization code. |
5695 | */ | 5652 | */ |
5696 | 5653 | ||
5697 | static void | 5654 | static void init(void) |
5698 | init(void) { | 5655 | { |
5699 | 5656 | ||
5700 | /* from cd.c: */ | 5657 | /* from cd.c: */ |
5701 | { | 5658 | { |
5702 | curdir = nullstr; | 5659 | curdir = nullstr; |
5703 | setpwd(0, 0); | 5660 | setpwd(0, 0); |
5704 | } | 5661 | } |
5705 | 5662 | ||
5706 | /* from input.c: */ | 5663 | /* from input.c: */ |
5707 | { | 5664 | { |
5708 | basepf.nextc = basepf.buf = basebuf; | 5665 | basepf.nextc = basepf.buf = basebuf; |
5709 | } | 5666 | } |
5710 | 5667 | ||
5711 | /* from var.c: */ | 5668 | /* from var.c: */ |
5712 | { | 5669 | { |
5713 | char **envp; | 5670 | char **envp; |
5714 | char ppid[32]; | 5671 | char ppid[32]; |
5715 | 5672 | ||
5716 | initvar(); | 5673 | initvar(); |
5717 | for (envp = environ ; *envp ; envp++) { | 5674 | for (envp = environ; *envp; envp++) { |
5718 | if (strchr(*envp, '=')) { | 5675 | if (strchr(*envp, '=')) { |
5719 | setvareq(*envp, VEXPORT|VTEXTFIXED); | 5676 | setvareq(*envp, VEXPORT | VTEXTFIXED); |
5720 | } | 5677 | } |
5721 | } | 5678 | } |
5722 | 5679 | ||
5723 | snprintf(ppid, sizeof(ppid), "%d", (int) getppid()); | 5680 | snprintf(ppid, sizeof(ppid), "%d", (int) getppid()); |
5724 | setvar("PPID", ppid, 0); | 5681 | setvar("PPID", ppid, 0); |
5725 | } | 5682 | } |
5726 | } | 5683 | } |
5727 | 5684 | ||
5728 | 5685 | ||
@@ -5733,37 +5690,37 @@ init(void) { | |||
5733 | */ | 5690 | */ |
5734 | 5691 | ||
5735 | /* 1 == check for aliases, 2 == also check for assignments */ | 5692 | /* 1 == check for aliases, 2 == also check for assignments */ |
5736 | static int checkalias; /* also used in no alias mode for check assignments */ | 5693 | static int checkalias; /* also used in no alias mode for check assignments */ |
5737 | 5694 | ||
5738 | static void | 5695 | static void reset(void) |
5739 | reset(void) { | 5696 | { |
5740 | 5697 | ||
5741 | /* from eval.c: */ | 5698 | /* from eval.c: */ |
5742 | { | 5699 | { |
5743 | evalskip = 0; | 5700 | evalskip = 0; |
5744 | loopnest = 0; | 5701 | loopnest = 0; |
5745 | funcnest = 0; | 5702 | funcnest = 0; |
5746 | } | 5703 | } |
5747 | 5704 | ||
5748 | /* from input.c: */ | 5705 | /* from input.c: */ |
5749 | { | 5706 | { |
5750 | if (exception != EXSHELLPROC) | 5707 | if (exception != EXSHELLPROC) |
5751 | parselleft = parsenleft = 0; /* clear input buffer */ | 5708 | parselleft = parsenleft = 0; /* clear input buffer */ |
5752 | popallfiles(); | 5709 | popallfiles(); |
5753 | } | 5710 | } |
5754 | 5711 | ||
5755 | /* from parser.c: */ | 5712 | /* from parser.c: */ |
5756 | { | 5713 | { |
5757 | tokpushback = 0; | 5714 | tokpushback = 0; |
5758 | checkkwd = 0; | 5715 | checkkwd = 0; |
5759 | checkalias = 0; | 5716 | checkalias = 0; |
5760 | } | 5717 | } |
5761 | 5718 | ||
5762 | /* from redir.c: */ | 5719 | /* from redir.c: */ |
5763 | { | 5720 | { |
5764 | while (redirlist) | 5721 | while (redirlist) |
5765 | popredir(); | 5722 | popredir(); |
5766 | } | 5723 | } |
5767 | 5724 | ||
5768 | } | 5725 | } |
5769 | 5726 | ||
@@ -5774,17 +5731,19 @@ reset(void) { | |||
5774 | */ | 5731 | */ |
5775 | 5732 | ||
5776 | #ifdef CONFIG_FEATURE_COMMAND_EDITING | 5733 | #ifdef CONFIG_FEATURE_COMMAND_EDITING |
5777 | static const char * cmdedit_prompt; | 5734 | static const char *cmdedit_prompt; |
5778 | static inline void putprompt(const char *s) { | 5735 | static inline void putprompt(const char *s) |
5779 | cmdedit_prompt = s; | 5736 | { |
5737 | cmdedit_prompt = s; | ||
5780 | } | 5738 | } |
5781 | #else | 5739 | #else |
5782 | static inline void putprompt(const char *s) { | 5740 | static inline void putprompt(const char *s) |
5783 | out2str(s); | 5741 | { |
5742 | out2str(s); | ||
5784 | } | 5743 | } |
5785 | #endif | 5744 | #endif |
5786 | 5745 | ||
5787 | #define EOF_NLEFT -99 /* value of parsenleft when EOF pushed back */ | 5746 | #define EOF_NLEFT -99 /* value of parsenleft when EOF pushed back */ |
5788 | 5747 | ||
5789 | 5748 | ||
5790 | 5749 | ||
@@ -5793,25 +5752,27 @@ static inline void putprompt(const char *s) { | |||
5793 | */ | 5752 | */ |
5794 | 5753 | ||
5795 | #ifdef CONFIG_ASH_ALIAS | 5754 | #ifdef CONFIG_ASH_ALIAS |
5796 | static int | 5755 | static int pgetc2(void) |
5797 | pgetc2(void) | ||
5798 | { | 5756 | { |
5799 | int c; | 5757 | int c; |
5758 | |||
5800 | do { | 5759 | do { |
5801 | c = pgetc_macro(); | 5760 | c = pgetc_macro(); |
5802 | } while (c == PEOA); | 5761 | } while (c == PEOA); |
5803 | return c; | 5762 | return c; |
5804 | } | 5763 | } |
5805 | #else | 5764 | #else |
5806 | static inline int pgetc2(void) { return pgetc_macro(); } | 5765 | static inline int pgetc2(void) |
5766 | { | ||
5767 | return pgetc_macro(); | ||
5768 | } | ||
5807 | #endif | 5769 | #endif |
5808 | 5770 | ||
5809 | /* | 5771 | /* |
5810 | * Read a line from the script. | 5772 | * Read a line from the script. |
5811 | */ | 5773 | */ |
5812 | 5774 | ||
5813 | static inline char * | 5775 | static inline char *pfgets(char *line, int len) |
5814 | pfgets(char *line, int len) | ||
5815 | { | 5776 | { |
5816 | char *p = line; | 5777 | char *p = line; |
5817 | int nleft = len; | 5778 | int nleft = len; |
@@ -5832,21 +5793,21 @@ pfgets(char *line, int len) | |||
5832 | return line; | 5793 | return line; |
5833 | } | 5794 | } |
5834 | 5795 | ||
5835 | static inline int | 5796 | static inline int preadfd(void) |
5836 | preadfd(void) | ||
5837 | { | 5797 | { |
5838 | int nr; | 5798 | int nr; |
5839 | char *buf = parsefile->buf; | 5799 | char *buf = parsefile->buf; |
5840 | parsenextc = buf; | ||
5841 | 5800 | ||
5842 | retry: | 5801 | parsenextc = buf; |
5802 | |||
5803 | retry: | ||
5843 | #ifdef CONFIG_FEATURE_COMMAND_EDITING | 5804 | #ifdef CONFIG_FEATURE_COMMAND_EDITING |
5844 | { | 5805 | { |
5845 | if (!iflag || parsefile->fd) | 5806 | if (!iflag || parsefile->fd) |
5846 | nr = safe_read(parsefile->fd, buf, BUFSIZ - 1); | 5807 | nr = safe_read(parsefile->fd, buf, BUFSIZ - 1); |
5847 | else { | 5808 | else { |
5848 | nr = cmdedit_read_input((char*)cmdedit_prompt, buf); | 5809 | nr = cmdedit_read_input((char *) cmdedit_prompt, buf); |
5849 | } | 5810 | } |
5850 | } | 5811 | } |
5851 | #else | 5812 | #else |
5852 | nr = safe_read(parsefile->fd, buf, BUFSIZ - 1); | 5813 | nr = safe_read(parsefile->fd, buf, BUFSIZ - 1); |
@@ -5855,8 +5816,9 @@ retry: | |||
5855 | if (nr < 0) { | 5816 | if (nr < 0) { |
5856 | if (parsefile->fd == 0 && errno == EWOULDBLOCK) { | 5817 | if (parsefile->fd == 0 && errno == EWOULDBLOCK) { |
5857 | int flags = fcntl(0, F_GETFL, 0); | 5818 | int flags = fcntl(0, F_GETFL, 0); |
5819 | |||
5858 | if (flags >= 0 && flags & O_NONBLOCK) { | 5820 | if (flags >= 0 && flags & O_NONBLOCK) { |
5859 | flags &=~ O_NONBLOCK; | 5821 | flags &= ~O_NONBLOCK; |
5860 | if (fcntl(0, F_SETFL, flags) >= 0) { | 5822 | if (fcntl(0, F_SETFL, flags) >= 0) { |
5861 | out2str("sh: turning off NDELAY mode\n"); | 5823 | out2str("sh: turning off NDELAY mode\n"); |
5862 | goto retry; | 5824 | goto retry; |
@@ -5867,8 +5829,7 @@ retry: | |||
5867 | return nr; | 5829 | return nr; |
5868 | } | 5830 | } |
5869 | 5831 | ||
5870 | static void | 5832 | static void popstring(void) |
5871 | popstring(void) | ||
5872 | { | 5833 | { |
5873 | struct strpush *sp = parsefile->strpush; | 5834 | struct strpush *sp = parsefile->strpush; |
5874 | 5835 | ||
@@ -5910,8 +5871,7 @@ popstring(void) | |||
5910 | * 4) Process input up to the next newline, deleting nul characters. | 5871 | * 4) Process input up to the next newline, deleting nul characters. |
5911 | */ | 5872 | */ |
5912 | 5873 | ||
5913 | static int | 5874 | static int preadbuffer(void) |
5914 | preadbuffer(void) | ||
5915 | { | 5875 | { |
5916 | char *p, *q; | 5876 | char *p, *q; |
5917 | int more; | 5877 | int more; |
@@ -5932,7 +5892,7 @@ preadbuffer(void) | |||
5932 | return PEOF; | 5892 | return PEOF; |
5933 | flushall(); | 5893 | flushall(); |
5934 | 5894 | ||
5935 | again: | 5895 | again: |
5936 | if (parselleft <= 0) { | 5896 | if (parselleft <= 0) { |
5937 | if ((parselleft = preadfd()) <= 0) { | 5897 | if ((parselleft = preadfd()) <= 0) { |
5938 | parselleft = parsenleft = EOF_NLEFT; | 5898 | parselleft = parsenleft = EOF_NLEFT; |
@@ -5946,18 +5906,18 @@ again: | |||
5946 | for (more = 1; more;) { | 5906 | for (more = 1; more;) { |
5947 | switch (*p) { | 5907 | switch (*p) { |
5948 | case '\0': | 5908 | case '\0': |
5949 | p++; /* Skip nul */ | 5909 | p++; /* Skip nul */ |
5950 | goto check; | 5910 | goto check; |
5951 | 5911 | ||
5952 | 5912 | ||
5953 | case '\n': | 5913 | case '\n': |
5954 | parsenleft = q - parsenextc; | 5914 | parsenleft = q - parsenextc; |
5955 | more = 0; /* Stop processing here */ | 5915 | more = 0; /* Stop processing here */ |
5956 | break; | 5916 | break; |
5957 | } | 5917 | } |
5958 | 5918 | ||
5959 | *q++ = *p++; | 5919 | *q++ = *p++; |
5960 | check: | 5920 | check: |
5961 | if (--parselleft <= 0 && more) { | 5921 | if (--parselleft <= 0 && more) { |
5962 | parsenleft = q - parsenextc - 1; | 5922 | parsenleft = q - parsenextc - 1; |
5963 | if (parsenleft < 0) | 5923 | if (parsenleft < 0) |
@@ -5983,15 +5943,14 @@ check: | |||
5983 | * Push a string back onto the input at this current parsefile level. | 5943 | * Push a string back onto the input at this current parsefile level. |
5984 | * We handle aliases this way. | 5944 | * We handle aliases this way. |
5985 | */ | 5945 | */ |
5986 | static void | 5946 | static void pushstring(char *s, int len, void *ap) |
5987 | pushstring(char *s, int len, void *ap) | ||
5988 | { | 5947 | { |
5989 | struct strpush *sp; | 5948 | struct strpush *sp; |
5990 | 5949 | ||
5991 | INTOFF; | 5950 | INTOFF; |
5992 | /*dprintf("*** calling pushstring: %s, %d\n", s, len);*/ | 5951 | /*dprintf("*** calling pushstring: %s, %d\n", s, len);*/ |
5993 | if (parsefile->strpush) { | 5952 | if (parsefile->strpush) { |
5994 | sp = xmalloc(sizeof (struct strpush)); | 5953 | sp = xmalloc(sizeof(struct strpush)); |
5995 | sp->prev = parsefile->strpush; | 5954 | sp->prev = parsefile->strpush; |
5996 | parsefile->strpush = sp; | 5955 | parsefile->strpush = sp; |
5997 | } else | 5956 | } else |
@@ -5999,9 +5958,9 @@ pushstring(char *s, int len, void *ap) | |||
5999 | sp->prevstring = parsenextc; | 5958 | sp->prevstring = parsenextc; |
6000 | sp->prevnleft = parsenleft; | 5959 | sp->prevnleft = parsenleft; |
6001 | #ifdef CONFIG_ASH_ALIAS | 5960 | #ifdef CONFIG_ASH_ALIAS |
6002 | sp->ap = (struct alias *)ap; | 5961 | sp->ap = (struct alias *) ap; |
6003 | if (ap) { | 5962 | if (ap) { |
6004 | ((struct alias *)ap)->flag |= ALIASINUSE; | 5963 | ((struct alias *) ap)->flag |= ALIASINUSE; |
6005 | sp->string = s; | 5964 | sp->string = s; |
6006 | } | 5965 | } |
6007 | #endif | 5966 | #endif |
@@ -6015,8 +5974,7 @@ pushstring(char *s, int len, void *ap) | |||
6015 | * Like setinputfile, but takes input from a string. | 5974 | * Like setinputfile, but takes input from a string. |
6016 | */ | 5975 | */ |
6017 | 5976 | ||
6018 | static void | 5977 | static void setinputstring(char *string) |
6019 | setinputstring(char *string) | ||
6020 | { | 5978 | { |
6021 | INTOFF; | 5979 | INTOFF; |
6022 | pushfile(); | 5980 | pushfile(); |
@@ -6034,8 +5992,7 @@ setinputstring(char *string) | |||
6034 | * adds a new entry to the stack and popfile restores the previous level. | 5992 | * adds a new entry to the stack and popfile restores the previous level. |
6035 | */ | 5993 | */ |
6036 | 5994 | ||
6037 | static void | 5995 | static void pushfile(void) |
6038 | pushfile(void) | ||
6039 | { | 5996 | { |
6040 | struct parsefile *pf; | 5997 | struct parsefile *pf; |
6041 | 5998 | ||
@@ -6043,7 +6000,7 @@ pushfile(void) | |||
6043 | parsefile->lleft = parselleft; | 6000 | parsefile->lleft = parselleft; |
6044 | parsefile->nextc = parsenextc; | 6001 | parsefile->nextc = parsenextc; |
6045 | parsefile->linno = plinno; | 6002 | parsefile->linno = plinno; |
6046 | pf = (struct parsefile *)xmalloc(sizeof (struct parsefile)); | 6003 | pf = (struct parsefile *) xmalloc(sizeof(struct parsefile)); |
6047 | pf->prev = parsefile; | 6004 | pf->prev = parsefile; |
6048 | pf->fd = -1; | 6005 | pf->fd = -1; |
6049 | pf->strpush = NULL; | 6006 | pf->strpush = NULL; |
@@ -6052,11 +6009,11 @@ pushfile(void) | |||
6052 | } | 6009 | } |
6053 | 6010 | ||
6054 | #ifdef CONFIG_ASH_JOB_CONTROL | 6011 | #ifdef CONFIG_ASH_JOB_CONTROL |
6055 | static void restartjob (struct job *); | 6012 | static void restartjob(struct job *); |
6056 | #endif | 6013 | #endif |
6057 | static void freejob (struct job *); | 6014 | static void freejob(struct job *); |
6058 | static struct job *getjob (const char *); | 6015 | static struct job *getjob(const char *); |
6059 | static int dowait (int, struct job *); | 6016 | static int dowait(int, struct job *); |
6060 | static void waitonint(int); | 6017 | static void waitonint(int); |
6061 | 6018 | ||
6062 | 6019 | ||
@@ -6068,13 +6025,12 @@ static void waitonint(int); | |||
6068 | static int fd0_redirected = 0; | 6025 | static int fd0_redirected = 0; |
6069 | 6026 | ||
6070 | /* Return true if fd 0 has already been redirected at least once. */ | 6027 | /* Return true if fd 0 has already been redirected at least once. */ |
6071 | static inline int | 6028 | static inline int fd0_redirected_p(void) |
6072 | fd0_redirected_p (void) | ||
6073 | { | 6029 | { |
6074 | return fd0_redirected != 0; | 6030 | return fd0_redirected != 0; |
6075 | } | 6031 | } |
6076 | 6032 | ||
6077 | static void dupredirect (const union node *, int, int fd1dup); | 6033 | static void dupredirect(const union node *, int, int fd1dup); |
6078 | 6034 | ||
6079 | #ifdef CONFIG_ASH_JOB_CONTROL | 6035 | #ifdef CONFIG_ASH_JOB_CONTROL |
6080 | /* | 6036 | /* |
@@ -6096,9 +6052,9 @@ static void setjobctl(int enable) | |||
6096 | if (enable == jobctl || rootshell == 0) | 6052 | if (enable == jobctl || rootshell == 0) |
6097 | return; | 6053 | return; |
6098 | if (enable) { | 6054 | if (enable) { |
6099 | do { /* while we are in the background */ | 6055 | do { /* while we are in the background */ |
6100 | #ifdef OLD_TTY_DRIVER | 6056 | #ifdef OLD_TTY_DRIVER |
6101 | if (ioctl(2, TIOCGPGRP, (char *)&initialpgrp) < 0) { | 6057 | if (ioctl(2, TIOCGPGRP, (char *) &initialpgrp) < 0) { |
6102 | #else | 6058 | #else |
6103 | initialpgrp = tcgetpgrp(2); | 6059 | initialpgrp = tcgetpgrp(2); |
6104 | if (initialpgrp < 0) { | 6060 | if (initialpgrp < 0) { |
@@ -6115,8 +6071,9 @@ static void setjobctl(int enable) | |||
6115 | } | 6071 | } |
6116 | } while (0); | 6072 | } while (0); |
6117 | #ifdef OLD_TTY_DRIVER | 6073 | #ifdef OLD_TTY_DRIVER |
6118 | if (ioctl(2, TIOCGETD, (char *)&ldisc) < 0 || ldisc != NTTYDISC) { | 6074 | if (ioctl(2, TIOCGETD, (char *) &ldisc) < 0 || ldisc != NTTYDISC) { |
6119 | out2str("sh: need new tty driver to run job control; job control turned off\n"); | 6075 | out2str |
6076 | ("sh: need new tty driver to run job control; job control turned off\n"); | ||
6120 | mflag = 0; | 6077 | mflag = 0; |
6121 | return; | 6078 | return; |
6122 | } | 6079 | } |
@@ -6126,14 +6083,14 @@ static void setjobctl(int enable) | |||
6126 | setsignal(SIGTTIN); | 6083 | setsignal(SIGTTIN); |
6127 | setpgid(0, rootpid); | 6084 | setpgid(0, rootpid); |
6128 | #ifdef OLD_TTY_DRIVER | 6085 | #ifdef OLD_TTY_DRIVER |
6129 | ioctl(2, TIOCSPGRP, (char *)&rootpid); | 6086 | ioctl(2, TIOCSPGRP, (char *) &rootpid); |
6130 | #else | 6087 | #else |
6131 | tcsetpgrp(2, rootpid); | 6088 | tcsetpgrp(2, rootpid); |
6132 | #endif | 6089 | #endif |
6133 | } else { /* turning job control off */ | 6090 | } else { /* turning job control off */ |
6134 | setpgid(0, initialpgrp); | 6091 | setpgid(0, initialpgrp); |
6135 | #ifdef OLD_TTY_DRIVER | 6092 | #ifdef OLD_TTY_DRIVER |
6136 | ioctl(2, TIOCSPGRP, (char *)&initialpgrp); | 6093 | ioctl(2, TIOCSPGRP, (char *) &initialpgrp); |
6137 | #else | 6094 | #else |
6138 | tcsetpgrp(2, initialpgrp); | 6095 | tcsetpgrp(2, initialpgrp); |
6139 | #endif | 6096 | #endif |
@@ -6147,8 +6104,7 @@ static void setjobctl(int enable) | |||
6147 | 6104 | ||
6148 | 6105 | ||
6149 | #ifdef CONFIG_ASH_JOB_CONTROL | 6106 | #ifdef CONFIG_ASH_JOB_CONTROL |
6150 | static int | 6107 | static int killcmd(int argc, char **argv) |
6151 | killcmd(int argc, char **argv) | ||
6152 | { | 6108 | { |
6153 | int signo = -1; | 6109 | int signo = -1; |
6154 | int list = 0; | 6110 | int list = 0; |
@@ -6157,11 +6113,10 @@ killcmd(int argc, char **argv) | |||
6157 | struct job *jp; | 6113 | struct job *jp; |
6158 | 6114 | ||
6159 | if (argc <= 1) { | 6115 | if (argc <= 1) { |
6160 | usage: | 6116 | usage: |
6161 | error( | 6117 | error |
6162 | "Usage: kill [-s sigspec | -signum | -sigspec] [pid | job]... or\n" | 6118 | ("Usage: kill [-s sigspec | -signum | -sigspec] [pid | job]... or\n" |
6163 | "kill -l [exitstatus]" | 6119 | "kill -l [exitstatus]"); |
6164 | ); | ||
6165 | } | 6120 | } |
6166 | 6121 | ||
6167 | if (*argv[1] == '-') { | 6122 | if (*argv[1] == '-') { |
@@ -6177,18 +6132,14 @@ usage: | |||
6177 | case 's': | 6132 | case 's': |
6178 | signo = decode_signal(optionarg, 1); | 6133 | signo = decode_signal(optionarg, 1); |
6179 | if (signo < 0) { | 6134 | if (signo < 0) { |
6180 | error( | 6135 | error("invalid signal number or name: %s", optionarg); |
6181 | "invalid signal number or name: %s", | ||
6182 | optionarg | ||
6183 | ); | ||
6184 | } | 6136 | } |
6185 | break; | 6137 | break; |
6186 | #ifdef DEBUG | 6138 | #ifdef DEBUG |
6187 | default: | 6139 | default: |
6188 | error( | 6140 | error("nextopt returned character code 0%o", c); |
6189 | "nextopt returned character code 0%o", c); | ||
6190 | #endif | 6141 | #endif |
6191 | } | 6142 | } |
6192 | } else | 6143 | } else |
6193 | argptr++; | 6144 | argptr++; |
6194 | } | 6145 | } |
@@ -6207,7 +6158,7 @@ usage: | |||
6207 | out1str("0\n"); | 6158 | out1str("0\n"); |
6208 | for (i = 1; i < NSIG; i++) { | 6159 | for (i = 1; i < NSIG; i++) { |
6209 | name = u_signal_names(0, &i, 1); | 6160 | name = u_signal_names(0, &i, 1); |
6210 | if(name) | 6161 | if (name) |
6211 | puts(name); | 6162 | puts(name); |
6212 | } | 6163 | } |
6213 | return 0; | 6164 | return 0; |
@@ -6216,8 +6167,7 @@ usage: | |||
6216 | if (name) | 6167 | if (name) |
6217 | puts(name); | 6168 | puts(name); |
6218 | else | 6169 | else |
6219 | error("invalid signal number or exit status: %s", | 6170 | error("invalid signal number or exit status: %s", *argptr); |
6220 | *argptr); | ||
6221 | return 0; | 6171 | return 0; |
6222 | } | 6172 | } |
6223 | 6173 | ||
@@ -6225,8 +6175,7 @@ usage: | |||
6225 | if (**argptr == '%') { | 6175 | if (**argptr == '%') { |
6226 | jp = getjob(*argptr); | 6176 | jp = getjob(*argptr); |
6227 | if (jp->jobctl == 0) | 6177 | if (jp->jobctl == 0) |
6228 | error("job %s not created under job control", | 6178 | error("job %s not created under job control", *argptr); |
6229 | *argptr); | ||
6230 | pid = -jp->ps[0].pid; | 6179 | pid = -jp->ps[0].pid; |
6231 | } else | 6180 | } else |
6232 | pid = atoi(*argptr); | 6181 | pid = atoi(*argptr); |
@@ -6237,8 +6186,7 @@ usage: | |||
6237 | return 0; | 6186 | return 0; |
6238 | } | 6187 | } |
6239 | 6188 | ||
6240 | static int | 6189 | static int fgcmd(int argc, char **argv) |
6241 | fgcmd(int argc, char **argv) | ||
6242 | { | 6190 | { |
6243 | struct job *jp; | 6191 | struct job *jp; |
6244 | int pgrp; | 6192 | int pgrp; |
@@ -6249,7 +6197,7 @@ fgcmd(int argc, char **argv) | |||
6249 | error("job not created under job control"); | 6197 | error("job not created under job control"); |
6250 | pgrp = jp->ps[0].pid; | 6198 | pgrp = jp->ps[0].pid; |
6251 | #ifdef OLD_TTY_DRIVER | 6199 | #ifdef OLD_TTY_DRIVER |
6252 | ioctl(2, TIOCSPGRP, (char *)&pgrp); | 6200 | ioctl(2, TIOCSPGRP, (char *) &pgrp); |
6253 | #else | 6201 | #else |
6254 | tcsetpgrp(2, pgrp); | 6202 | tcsetpgrp(2, pgrp); |
6255 | #endif | 6203 | #endif |
@@ -6259,8 +6207,7 @@ fgcmd(int argc, char **argv) | |||
6259 | } | 6207 | } |
6260 | 6208 | ||
6261 | 6209 | ||
6262 | static int | 6210 | static int bgcmd(int argc, char **argv) |
6263 | bgcmd(int argc, char **argv) | ||
6264 | { | 6211 | { |
6265 | struct job *jp; | 6212 | struct job *jp; |
6266 | 6213 | ||
@@ -6274,8 +6221,7 @@ bgcmd(int argc, char **argv) | |||
6274 | } | 6221 | } |
6275 | 6222 | ||
6276 | 6223 | ||
6277 | static void | 6224 | static void restartjob(struct job *jp) |
6278 | restartjob(struct job *jp) | ||
6279 | { | 6225 | { |
6280 | struct procstat *ps; | 6226 | struct procstat *ps; |
6281 | int i; | 6227 | int i; |
@@ -6284,7 +6230,7 @@ restartjob(struct job *jp) | |||
6284 | return; | 6230 | return; |
6285 | INTOFF; | 6231 | INTOFF; |
6286 | killpg(jp->ps[0].pid, SIGCONT); | 6232 | killpg(jp->ps[0].pid, SIGCONT); |
6287 | for (ps = jp->ps, i = jp->nprocs ; --i >= 0 ; ps++) { | 6233 | for (ps = jp->ps, i = jp->nprocs; --i >= 0; ps++) { |
6288 | if (WIFSTOPPED(ps->status)) { | 6234 | if (WIFSTOPPED(ps->status)) { |
6289 | ps->status = -1; | 6235 | ps->status = -1; |
6290 | jp->state = 0; | 6236 | jp->state = 0; |
@@ -6297,8 +6243,7 @@ restartjob(struct job *jp) | |||
6297 | static void showjobs(int change); | 6243 | static void showjobs(int change); |
6298 | 6244 | ||
6299 | 6245 | ||
6300 | static int | 6246 | static int jobscmd(int argc, char **argv) |
6301 | jobscmd(int argc, char **argv) | ||
6302 | { | 6247 | { |
6303 | showjobs(0); | 6248 | showjobs(0); |
6304 | return 0; | 6249 | return 0; |
@@ -6314,8 +6259,7 @@ jobscmd(int argc, char **argv) | |||
6314 | * will be freed here. | 6259 | * will be freed here. |
6315 | */ | 6260 | */ |
6316 | 6261 | ||
6317 | static void | 6262 | static void showjobs(int change) |
6318 | showjobs(int change) | ||
6319 | { | 6263 | { |
6320 | int jobno; | 6264 | int jobno; |
6321 | int procno; | 6265 | int procno; |
@@ -6326,37 +6270,34 @@ showjobs(int change) | |||
6326 | char s[64]; | 6270 | char s[64]; |
6327 | 6271 | ||
6328 | TRACE(("showjobs(%d) called\n", change)); | 6272 | TRACE(("showjobs(%d) called\n", change)); |
6329 | while (dowait(0, (struct job *)NULL) > 0); | 6273 | while (dowait(0, (struct job *) NULL) > 0); |
6330 | for (jobno = 1, jp = jobtab ; jobno <= njobs ; jobno++, jp++) { | 6274 | for (jobno = 1, jp = jobtab; jobno <= njobs; jobno++, jp++) { |
6331 | if (! jp->used) | 6275 | if (!jp->used) |
6332 | continue; | 6276 | continue; |
6333 | if (jp->nprocs == 0) { | 6277 | if (jp->nprocs == 0) { |
6334 | freejob(jp); | 6278 | freejob(jp); |
6335 | continue; | 6279 | continue; |
6336 | } | 6280 | } |
6337 | if (change && ! jp->changed) | 6281 | if (change && !jp->changed) |
6338 | continue; | 6282 | continue; |
6339 | procno = jp->nprocs; | 6283 | procno = jp->nprocs; |
6340 | for (ps = jp->ps ; ; ps++) { /* for each process */ | 6284 | for (ps = jp->ps;; ps++) { /* for each process */ |
6341 | if (ps == jp->ps) | 6285 | if (ps == jp->ps) |
6342 | snprintf(s, 64, "[%d] %ld ", jobno, | 6286 | snprintf(s, 64, "[%d] %ld ", jobno, (long) ps->pid); |
6343 | (long)ps->pid); | ||
6344 | else | 6287 | else |
6345 | snprintf(s, 64, " %ld ", | 6288 | snprintf(s, 64, " %ld ", (long) ps->pid); |
6346 | (long)ps->pid); | ||
6347 | out1str(s); | 6289 | out1str(s); |
6348 | col = strlen(s); | 6290 | col = strlen(s); |
6349 | s[0] = '\0'; | 6291 | s[0] = '\0'; |
6350 | if (ps->status == -1) { | 6292 | if (ps->status == -1) { |
6351 | /* don't print anything */ | 6293 | /* don't print anything */ |
6352 | } else if (WIFEXITED(ps->status)) { | 6294 | } else if (WIFEXITED(ps->status)) { |
6353 | snprintf(s, 64, "Exit %d", | 6295 | snprintf(s, 64, "Exit %d", WEXITSTATUS(ps->status)); |
6354 | WEXITSTATUS(ps->status)); | ||
6355 | } else { | 6296 | } else { |
6356 | #ifdef CONFIG_ASH_JOB_CONTROL | 6297 | #ifdef CONFIG_ASH_JOB_CONTROL |
6357 | if (WIFSTOPPED(ps->status)) | 6298 | if (WIFSTOPPED(ps->status)) |
6358 | i = WSTOPSIG(ps->status); | 6299 | i = WSTOPSIG(ps->status); |
6359 | else /* WIFSIGNALED(ps->status) */ | 6300 | else /* WIFSIGNALED(ps->status) */ |
6360 | #endif | 6301 | #endif |
6361 | i = WTERMSIG(ps->status); | 6302 | i = WTERMSIG(ps->status); |
6362 | if ((i & 0x7F) < NSIG && sys_siglist[i & 0x7F]) | 6303 | if ((i & 0x7F) < NSIG && sys_siglist[i & 0x7F]) |
@@ -6368,10 +6309,7 @@ showjobs(int change) | |||
6368 | } | 6309 | } |
6369 | out1str(s); | 6310 | out1str(s); |
6370 | col += strlen(s); | 6311 | col += strlen(s); |
6371 | printf( | 6312 | printf("%*c%s\n", 30 - col >= 0 ? 30 - col : 0, ' ', ps->cmd); |
6372 | "%*c%s\n", 30 - col >= 0 ? 30 - col : 0, ' ', | ||
6373 | ps->cmd | ||
6374 | ); | ||
6375 | if (--procno <= 0) | 6313 | if (--procno <= 0) |
6376 | break; | 6314 | break; |
6377 | } | 6315 | } |
@@ -6387,14 +6325,13 @@ showjobs(int change) | |||
6387 | * Mark a job structure as unused. | 6325 | * Mark a job structure as unused. |
6388 | */ | 6326 | */ |
6389 | 6327 | ||
6390 | static void | 6328 | static void freejob(struct job *jp) |
6391 | freejob(struct job *jp) | ||
6392 | { | 6329 | { |
6393 | const struct procstat *ps; | 6330 | const struct procstat *ps; |
6394 | int i; | 6331 | int i; |
6395 | 6332 | ||
6396 | INTOFF; | 6333 | INTOFF; |
6397 | for (i = jp->nprocs, ps = jp->ps ; --i >= 0 ; ps++) { | 6334 | for (i = jp->nprocs, ps = jp->ps; --i >= 0; ps++) { |
6398 | if (ps->cmd != nullstr) | 6335 | if (ps->cmd != nullstr) |
6399 | free(ps->cmd); | 6336 | free(ps->cmd); |
6400 | } | 6337 | } |
@@ -6410,24 +6347,23 @@ freejob(struct job *jp) | |||
6410 | 6347 | ||
6411 | 6348 | ||
6412 | 6349 | ||
6413 | static int | 6350 | static int waitcmd(int argc, char **argv) |
6414 | waitcmd(int argc, char **argv) | ||
6415 | { | 6351 | { |
6416 | struct job *job; | 6352 | struct job *job; |
6417 | int status, retval; | 6353 | int status, retval; |
6418 | struct job *jp; | 6354 | struct job *jp; |
6419 | 6355 | ||
6420 | if (--argc > 0) { | 6356 | if (--argc > 0) { |
6421 | start: | 6357 | start: |
6422 | job = getjob(*++argv); | 6358 | job = getjob(*++argv); |
6423 | } else { | 6359 | } else { |
6424 | job = NULL; | 6360 | job = NULL; |
6425 | } | 6361 | } |
6426 | for (;;) { /* loop until process terminated or stopped */ | 6362 | for (;;) { /* loop until process terminated or stopped */ |
6427 | if (job != NULL) { | 6363 | if (job != NULL) { |
6428 | if (job->state) { | 6364 | if (job->state) { |
6429 | status = job->ps[job->nprocs - 1].status; | 6365 | status = job->ps[job->nprocs - 1].status; |
6430 | if (! iflag) | 6366 | if (!iflag) |
6431 | freejob(job); | 6367 | freejob(job); |
6432 | if (--argc) { | 6368 | if (--argc) { |
6433 | goto start; | 6369 | goto start; |
@@ -6445,8 +6381,8 @@ start: | |||
6445 | return retval; | 6381 | return retval; |
6446 | } | 6382 | } |
6447 | } else { | 6383 | } else { |
6448 | for (jp = jobtab ; ; jp++) { | 6384 | for (jp = jobtab;; jp++) { |
6449 | if (jp >= jobtab + njobs) { /* no running procs */ | 6385 | if (jp >= jobtab + njobs) { /* no running procs */ |
6450 | return 0; | 6386 | return 0; |
6451 | } | 6387 | } |
6452 | if (jp->used && jp->state == 0) | 6388 | if (jp->used && jp->state == 0) |
@@ -6465,8 +6401,7 @@ start: | |||
6465 | * Convert a job name to a job structure. | 6401 | * Convert a job name to a job structure. |
6466 | */ | 6402 | */ |
6467 | 6403 | ||
6468 | static struct job * | 6404 | static struct job *getjob(const char *name) |
6469 | getjob(const char *name) | ||
6470 | { | 6405 | { |
6471 | int jobno; | 6406 | int jobno; |
6472 | struct job *jp; | 6407 | struct job *jp; |
@@ -6475,7 +6410,7 @@ getjob(const char *name) | |||
6475 | 6410 | ||
6476 | if (name == NULL) { | 6411 | if (name == NULL) { |
6477 | #ifdef CONFIG_ASH_JOB_CONTROL | 6412 | #ifdef CONFIG_ASH_JOB_CONTROL |
6478 | currentjob: | 6413 | currentjob: |
6479 | if ((jobno = curjob) == 0 || jobtab[jobno - 1].used == 0) | 6414 | if ((jobno = curjob) == 0 || jobtab[jobno - 1].used == 0) |
6480 | error("No current job"); | 6415 | error("No current job"); |
6481 | return &jobtab[jobno - 1]; | 6416 | return &jobtab[jobno - 1]; |
@@ -6485,8 +6420,7 @@ currentjob: | |||
6485 | } else if (name[0] == '%') { | 6420 | } else if (name[0] == '%') { |
6486 | if (is_digit(name[1])) { | 6421 | if (is_digit(name[1])) { |
6487 | jobno = number(name + 1); | 6422 | jobno = number(name + 1); |
6488 | if (jobno > 0 && jobno <= njobs | 6423 | if (jobno > 0 && jobno <= njobs && jobtab[jobno - 1].used != 0) |
6489 | && jobtab[jobno - 1].used != 0) | ||
6490 | return &jobtab[jobno - 1]; | 6424 | return &jobtab[jobno - 1]; |
6491 | #ifdef CONFIG_ASH_JOB_CONTROL | 6425 | #ifdef CONFIG_ASH_JOB_CONTROL |
6492 | } else if (name[1] == '%' && name[2] == '\0') { | 6426 | } else if (name[1] == '%' && name[2] == '\0') { |
@@ -6494,9 +6428,10 @@ currentjob: | |||
6494 | #endif | 6428 | #endif |
6495 | } else { | 6429 | } else { |
6496 | struct job *found = NULL; | 6430 | struct job *found = NULL; |
6497 | for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) { | 6431 | |
6432 | for (jp = jobtab, i = njobs; --i >= 0; jp++) { | ||
6498 | if (jp->used && jp->nprocs > 0 | 6433 | if (jp->used && jp->nprocs > 0 |
6499 | && prefix(name + 1, jp->ps[0].cmd)) { | 6434 | && prefix(name + 1, jp->ps[0].cmd)) { |
6500 | if (found) | 6435 | if (found) |
6501 | error("%s: ambiguous", name); | 6436 | error("%s: ambiguous", name); |
6502 | found = jp; | 6437 | found = jp; |
@@ -6506,9 +6441,9 @@ currentjob: | |||
6506 | return found; | 6441 | return found; |
6507 | } | 6442 | } |
6508 | } else if (is_number(name, &pid)) { | 6443 | } else if (is_number(name, &pid)) { |
6509 | for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) { | 6444 | for (jp = jobtab, i = njobs; --i >= 0; jp++) { |
6510 | if (jp->used && jp->nprocs > 0 | 6445 | if (jp->used && jp->nprocs > 0 |
6511 | && jp->ps[jp->nprocs - 1].pid == pid) | 6446 | && jp->ps[jp->nprocs - 1].pid == pid) |
6512 | return jp; | 6447 | return jp; |
6513 | } | 6448 | } |
6514 | } | 6449 | } |
@@ -6522,13 +6457,12 @@ currentjob: | |||
6522 | * Return a new job structure, | 6457 | * Return a new job structure, |
6523 | */ | 6458 | */ |
6524 | 6459 | ||
6525 | static struct job * | 6460 | static struct job *makejob(const union node *node, int nprocs) |
6526 | makejob(const union node *node, int nprocs) | ||
6527 | { | 6461 | { |
6528 | int i; | 6462 | int i; |
6529 | struct job *jp; | 6463 | struct job *jp; |
6530 | 6464 | ||
6531 | for (i = njobs, jp = jobtab ; ; jp++) { | 6465 | for (i = njobs, jp = jobtab;; jp++) { |
6532 | if (--i < 0) { | 6466 | if (--i < 0) { |
6533 | INTOFF; | 6467 | INTOFF; |
6534 | if (njobs == 0) { | 6468 | if (njobs == 0) { |
@@ -6544,7 +6478,7 @@ makejob(const union node *node, int nprocs) | |||
6544 | jobtab = jp; | 6478 | jobtab = jp; |
6545 | } | 6479 | } |
6546 | jp = jobtab + njobs; | 6480 | jp = jobtab + njobs; |
6547 | for (i = 4 ; --i >= 0 ; jobtab[njobs++].used = 0); | 6481 | for (i = 4; --i >= 0; jobtab[njobs++].used = 0); |
6548 | INTON; | 6482 | INTON; |
6549 | break; | 6483 | break; |
6550 | } | 6484 | } |
@@ -6560,13 +6494,13 @@ makejob(const union node *node, int nprocs) | |||
6560 | jp->jobctl = jobctl; | 6494 | jp->jobctl = jobctl; |
6561 | #endif | 6495 | #endif |
6562 | if (nprocs > 1) { | 6496 | if (nprocs > 1) { |
6563 | jp->ps = xmalloc(nprocs * sizeof (struct procstat)); | 6497 | jp->ps = xmalloc(nprocs * sizeof(struct procstat)); |
6564 | } else { | 6498 | } else { |
6565 | jp->ps = &jp->ps0; | 6499 | jp->ps = &jp->ps0; |
6566 | } | 6500 | } |
6567 | INTON; | 6501 | INTON; |
6568 | TRACE(("makejob(0x%lx, %d) returns %%%d\n", (long)node, nprocs, | 6502 | TRACE(("makejob(0x%lx, %d) returns %%%d\n", (long) node, nprocs, |
6569 | jp - jobtab + 1)); | 6503 | jp - jobtab + 1)); |
6570 | return jp; | 6504 | return jp; |
6571 | } | 6505 | } |
6572 | 6506 | ||
@@ -6588,18 +6522,18 @@ makejob(const union node *node, int nprocs) | |||
6588 | 6522 | ||
6589 | 6523 | ||
6590 | 6524 | ||
6591 | static int | 6525 | static int forkshell(struct job *jp, const union node *n, int mode) |
6592 | forkshell(struct job *jp, const union node *n, int mode) | ||
6593 | { | 6526 | { |
6594 | int pid; | 6527 | int pid; |
6528 | |||
6595 | #ifdef CONFIG_ASH_JOB_CONTROL | 6529 | #ifdef CONFIG_ASH_JOB_CONTROL |
6596 | int pgrp; | 6530 | int pgrp; |
6597 | #endif | 6531 | #endif |
6598 | const char *devnull = _PATH_DEVNULL; | 6532 | const char *devnull = _PATH_DEVNULL; |
6599 | const char *nullerr = "Can't open %s"; | 6533 | const char *nullerr = "Can't open %s"; |
6600 | 6534 | ||
6601 | TRACE(("forkshell(%%%d, 0x%lx, %d) called\n", jp - jobtab, (long)n, | 6535 | TRACE(("forkshell(%%%d, 0x%lx, %d) called\n", jp - jobtab, (long) n, |
6602 | mode)); | 6536 | mode)); |
6603 | INTOFF; | 6537 | INTOFF; |
6604 | #if !defined(__UCLIBC__) || defined(__UCLIBC_HAS_MMU__) | 6538 | #if !defined(__UCLIBC__) || defined(__UCLIBC_HAS_MMU__) |
6605 | pid = fork(); | 6539 | pid = fork(); |
@@ -6623,7 +6557,7 @@ forkshell(struct job *jp, const union node *n, int mode) | |||
6623 | INTON; | 6557 | INTON; |
6624 | clear_traps(); | 6558 | clear_traps(); |
6625 | #ifdef CONFIG_ASH_JOB_CONTROL | 6559 | #ifdef CONFIG_ASH_JOB_CONTROL |
6626 | jobctl = 0; /* do job control only in root shell */ | 6560 | jobctl = 0; /* do job control only in root shell */ |
6627 | if (wasroot && mode != FORK_NOJOB && mflag) { | 6561 | if (wasroot && mode != FORK_NOJOB && mflag) { |
6628 | if (jp == NULL || jp->nprocs == 0) | 6562 | if (jp == NULL || jp->nprocs == 0) |
6629 | pgrp = getpid(); | 6563 | pgrp = getpid(); |
@@ -6633,7 +6567,7 @@ forkshell(struct job *jp, const union node *n, int mode) | |||
6633 | if (mode == FORK_FG) { | 6567 | if (mode == FORK_FG) { |
6634 | /*** this causes superfluous TIOCSPGRPS ***/ | 6568 | /*** this causes superfluous TIOCSPGRPS ***/ |
6635 | #ifdef OLD_TTY_DRIVER | 6569 | #ifdef OLD_TTY_DRIVER |
6636 | if (ioctl(2, TIOCSPGRP, (char *)&pgrp) < 0) | 6570 | if (ioctl(2, TIOCSPGRP, (char *) &pgrp) < 0) |
6637 | error("TIOCSPGRP failed, errno=%d", errno); | 6571 | error("TIOCSPGRP failed, errno=%d", errno); |
6638 | #else | 6572 | #else |
6639 | if (tcsetpgrp(2, pgrp) < 0) | 6573 | if (tcsetpgrp(2, pgrp) < 0) |
@@ -6648,14 +6582,13 @@ forkshell(struct job *jp, const union node *n, int mode) | |||
6648 | #endif | 6582 | #endif |
6649 | ignoresig(SIGINT); | 6583 | ignoresig(SIGINT); |
6650 | ignoresig(SIGQUIT); | 6584 | ignoresig(SIGQUIT); |
6651 | if ((jp == NULL || jp->nprocs == 0) && | 6585 | if ((jp == NULL || jp->nprocs == 0) && !fd0_redirected_p()) { |
6652 | ! fd0_redirected_p ()) { | ||
6653 | close(0); | 6586 | close(0); |
6654 | if (open(devnull, O_RDONLY) != 0) | 6587 | if (open(devnull, O_RDONLY) != 0) |
6655 | error(nullerr, devnull); | 6588 | error(nullerr, devnull); |
6656 | } | 6589 | } |
6657 | } | 6590 | } |
6658 | for (i = njobs, p = jobtab ; --i >= 0 ; p++) | 6591 | for (i = njobs, p = jobtab; --i >= 0; p++) |
6659 | if (p->used) | 6592 | if (p->used) |
6660 | freejob(p); | 6593 | freejob(p); |
6661 | if (wasroot && iflag) { | 6594 | if (wasroot && iflag) { |
@@ -6675,9 +6608,10 @@ forkshell(struct job *jp, const union node *n, int mode) | |||
6675 | } | 6608 | } |
6676 | #endif | 6609 | #endif |
6677 | if (mode == FORK_BG) | 6610 | if (mode == FORK_BG) |
6678 | backgndpid = pid; /* set $! */ | 6611 | backgndpid = pid; /* set $! */ |
6679 | if (jp) { | 6612 | if (jp) { |
6680 | struct procstat *ps = &jp->ps[jp->nprocs++]; | 6613 | struct procstat *ps = &jp->ps[jp->nprocs++]; |
6614 | |||
6681 | ps->pid = pid; | 6615 | ps->pid = pid; |
6682 | ps->status = -1; | 6616 | ps->status = -1; |
6683 | ps->cmd = nullstr; | 6617 | ps->cmd = nullstr; |
@@ -6710,8 +6644,7 @@ forkshell(struct job *jp, const union node *n, int mode) | |||
6710 | * confuse this approach. | 6644 | * confuse this approach. |
6711 | */ | 6645 | */ |
6712 | 6646 | ||
6713 | static int | 6647 | static int waitforjob(struct job *jp) |
6714 | waitforjob(struct job *jp) | ||
6715 | { | 6648 | { |
6716 | #ifdef CONFIG_ASH_JOB_CONTROL | 6649 | #ifdef CONFIG_ASH_JOB_CONTROL |
6717 | int mypgrp = getpgrp(); | 6650 | int mypgrp = getpgrp(); |
@@ -6741,12 +6674,13 @@ waitforjob(struct job *jp) | |||
6741 | if (!iflag) { | 6674 | if (!iflag) { |
6742 | #endif | 6675 | #endif |
6743 | sigaction(SIGINT, &oact, 0); | 6676 | sigaction(SIGINT, &oact, 0); |
6744 | if (intreceived) kill(getpid(), SIGINT); | 6677 | if (intreceived) |
6678 | kill(getpid(), SIGINT); | ||
6745 | } | 6679 | } |
6746 | #ifdef CONFIG_ASH_JOB_CONTROL | 6680 | #ifdef CONFIG_ASH_JOB_CONTROL |
6747 | if (jp->jobctl) { | 6681 | if (jp->jobctl) { |
6748 | #ifdef OLD_TTY_DRIVER | 6682 | #ifdef OLD_TTY_DRIVER |
6749 | if (ioctl(2, TIOCSPGRP, (char *)&mypgrp) < 0) | 6683 | if (ioctl(2, TIOCSPGRP, (char *) &mypgrp) < 0) |
6750 | error("TIOCSPGRP failed, errno=%d\n", errno); | 6684 | error("TIOCSPGRP failed, errno=%d\n", errno); |
6751 | #else | 6685 | #else |
6752 | if (tcsetpgrp(2, mypgrp) < 0) | 6686 | if (tcsetpgrp(2, mypgrp) < 0) |
@@ -6780,7 +6714,6 @@ waitforjob(struct job *jp) | |||
6780 | raise(SIGINT); | 6714 | raise(SIGINT); |
6781 | } | 6715 | } |
6782 | if (jp->state == JOBDONE) | 6716 | if (jp->state == JOBDONE) |
6783 | |||
6784 | #endif | 6717 | #endif |
6785 | freejob(jp); | 6718 | freejob(jp); |
6786 | INTON; | 6719 | INTON; |
@@ -6817,8 +6750,7 @@ waitforjob(struct job *jp) | |||
6817 | * | 6750 | * |
6818 | */ | 6751 | */ |
6819 | 6752 | ||
6820 | static inline int | 6753 | static inline int waitproc(int block, int *status) |
6821 | waitproc(int block, int *status) | ||
6822 | { | 6754 | { |
6823 | int flags; | 6755 | int flags; |
6824 | 6756 | ||
@@ -6829,11 +6761,10 @@ waitproc(int block, int *status) | |||
6829 | #endif | 6761 | #endif |
6830 | if (block == 0) | 6762 | if (block == 0) |
6831 | flags |= WNOHANG; | 6763 | flags |= WNOHANG; |
6832 | return wait3(status, flags, (struct rusage *)NULL); | 6764 | return wait3(status, flags, (struct rusage *) NULL); |
6833 | } | 6765 | } |
6834 | 6766 | ||
6835 | static int | 6767 | static int dowait(int block, struct job *job) |
6836 | dowait(int block, struct job *job) | ||
6837 | { | 6768 | { |
6838 | int pid; | 6769 | int pid; |
6839 | int status; | 6770 | int status; |
@@ -6854,15 +6785,16 @@ dowait(int block, struct job *job) | |||
6854 | return pid; | 6785 | return pid; |
6855 | INTOFF; | 6786 | INTOFF; |
6856 | thisjob = NULL; | 6787 | thisjob = NULL; |
6857 | for (jp = jobtab ; jp < jobtab + njobs ; jp++) { | 6788 | for (jp = jobtab; jp < jobtab + njobs; jp++) { |
6858 | if (jp->used) { | 6789 | if (jp->used) { |
6859 | done = 1; | 6790 | done = 1; |
6860 | stopped = 1; | 6791 | stopped = 1; |
6861 | for (sp = jp->ps ; sp < jp->ps + jp->nprocs ; sp++) { | 6792 | for (sp = jp->ps; sp < jp->ps + jp->nprocs; sp++) { |
6862 | if (sp->pid == -1) | 6793 | if (sp->pid == -1) |
6863 | continue; | 6794 | continue; |
6864 | if (sp->pid == pid) { | 6795 | if (sp->pid == pid) { |
6865 | TRACE(("Changing status of proc %d from 0x%x to 0x%x\n", pid, sp->status, status)); | 6796 | TRACE(("Changing status of proc %d from 0x%x to 0x%x\n", |
6797 | pid, sp->status, status)); | ||
6866 | sp->status = status; | 6798 | sp->status = status; |
6867 | thisjob = jp; | 6799 | thisjob = jp; |
6868 | } | 6800 | } |
@@ -6871,36 +6803,40 @@ dowait(int block, struct job *job) | |||
6871 | else if (WIFSTOPPED(sp->status)) | 6803 | else if (WIFSTOPPED(sp->status)) |
6872 | done = 0; | 6804 | done = 0; |
6873 | } | 6805 | } |
6874 | if (stopped) { /* stopped or done */ | 6806 | if (stopped) { /* stopped or done */ |
6875 | int state = done? JOBDONE : CONFIG_ASH_JOB_CONTROLTOPPED; | 6807 | int state = done ? JOBDONE : CONFIG_ASH_JOB_CONTROLTOPPED; |
6808 | |||
6876 | if (jp->state != state) { | 6809 | if (jp->state != state) { |
6877 | TRACE(("Job %d: changing state from %d to %d\n", jp - jobtab + 1, jp->state, state)); | 6810 | TRACE(("Job %d: changing state from %d to %d\n", |
6811 | jp - jobtab + 1, jp->state, state)); | ||
6878 | jp->state = state; | 6812 | jp->state = state; |
6879 | #ifdef CONFIG_ASH_JOB_CONTROL | 6813 | #ifdef CONFIG_ASH_JOB_CONTROL |
6880 | if (done && curjob == jp - jobtab + 1) | 6814 | if (done && curjob == jp - jobtab + 1) |
6881 | curjob = 0; /* no current job */ | 6815 | curjob = 0; /* no current job */ |
6882 | #endif | 6816 | #endif |
6883 | } | 6817 | } |
6884 | } | 6818 | } |
6885 | } | 6819 | } |
6886 | } | 6820 | } |
6887 | INTON; | 6821 | INTON; |
6888 | if (! rootshell || ! iflag || (job && thisjob == job)) { | 6822 | if (!rootshell || !iflag || (job && thisjob == job)) { |
6889 | core = WCOREDUMP(status); | 6823 | core = WCOREDUMP(status); |
6890 | #ifdef CONFIG_ASH_JOB_CONTROL | 6824 | #ifdef CONFIG_ASH_JOB_CONTROL |
6891 | if (WIFSTOPPED(status)) sig = WSTOPSIG(status); | 6825 | if (WIFSTOPPED(status)) |
6826 | sig = WSTOPSIG(status); | ||
6892 | else | 6827 | else |
6893 | #endif | 6828 | #endif |
6894 | if (WIFEXITED(status)) sig = 0; | 6829 | if (WIFEXITED(status)) |
6895 | else sig = WTERMSIG(status); | 6830 | sig = 0; |
6831 | else | ||
6832 | sig = WTERMSIG(status); | ||
6896 | 6833 | ||
6897 | if (sig != 0 && sig != SIGINT && sig != SIGPIPE) { | 6834 | if (sig != 0 && sig != SIGINT && sig != SIGPIPE) { |
6898 | if (thisjob != job) | 6835 | if (thisjob != job) |
6899 | out2fmt("%d: ", pid); | 6836 | out2fmt("%d: ", pid); |
6900 | #ifdef CONFIG_ASH_JOB_CONTROL | 6837 | #ifdef CONFIG_ASH_JOB_CONTROL |
6901 | if (sig == SIGTSTP && rootshell && iflag) | 6838 | if (sig == SIGTSTP && rootshell && iflag) |
6902 | out2fmt("%%%ld ", | 6839 | out2fmt("%%%ld ", (long) (job - jobtab + 1)); |
6903 | (long)(job - jobtab + 1)); | ||
6904 | #endif | 6840 | #endif |
6905 | if (sig < NSIG && sys_siglist[sig]) | 6841 | if (sig < NSIG && sys_siglist[sig]) |
6906 | out2str(sys_siglist[sig]); | 6842 | out2str(sys_siglist[sig]); |
@@ -6910,11 +6846,11 @@ dowait(int block, struct job *job) | |||
6910 | out2str(" - core dumped"); | 6846 | out2str(" - core dumped"); |
6911 | out2c('\n'); | 6847 | out2c('\n'); |
6912 | } else { | 6848 | } else { |
6913 | TRACE(("Not printing status: status=%d, sig=%d\n", | 6849 | TRACE(("Not printing status: status=%d, sig=%d\n", status, sig)); |
6914 | status, sig)); | ||
6915 | } | 6850 | } |
6916 | } else { | 6851 | } else { |
6917 | TRACE(("Not printing status, rootshell=%d, job=0x%x\n", rootshell, job)); | 6852 | TRACE(("Not printing status, rootshell=%d, job=0x%x\n", rootshell, |
6853 | job)); | ||
6918 | if (thisjob) | 6854 | if (thisjob) |
6919 | thisjob->changed = 1; | 6855 | thisjob->changed = 1; |
6920 | } | 6856 | } |
@@ -6927,8 +6863,7 @@ dowait(int block, struct job *job) | |||
6927 | /* | 6863 | /* |
6928 | * return 1 if there are stopped jobs, otherwise 0 | 6864 | * return 1 if there are stopped jobs, otherwise 0 |
6929 | */ | 6865 | */ |
6930 | static int | 6866 | static int stoppedjobs(void) |
6931 | stoppedjobs(void) | ||
6932 | { | 6867 | { |
6933 | int jobno; | 6868 | int jobno; |
6934 | struct job *jp; | 6869 | struct job *jp; |
@@ -6955,10 +6890,10 @@ stoppedjobs(void) | |||
6955 | 6890 | ||
6956 | static char *cmdnextc; | 6891 | static char *cmdnextc; |
6957 | static int cmdnleft; | 6892 | static int cmdnleft; |
6893 | |||
6958 | #define MAXCMDTEXT 200 | 6894 | #define MAXCMDTEXT 200 |
6959 | 6895 | ||
6960 | static void | 6896 | static void cmdputs(const char *s) |
6961 | cmdputs(const char *s) | ||
6962 | { | 6897 | { |
6963 | const char *p; | 6898 | const char *p; |
6964 | char *q; | 6899 | char *q; |
@@ -6982,8 +6917,8 @@ cmdputs(const char *s) | |||
6982 | subtype = 0; | 6917 | subtype = 0; |
6983 | } else if (c == CTLENDVAR) { | 6918 | } else if (c == CTLENDVAR) { |
6984 | *q++ = '}'; | 6919 | *q++ = '}'; |
6985 | } else if (c == CTLBACKQ || c == CTLBACKQ+CTLQUOTE) | 6920 | } else if (c == CTLBACKQ || c == CTLBACKQ + CTLQUOTE) |
6986 | cmdnleft++; /* ignore it */ | 6921 | cmdnleft++; /* ignore it */ |
6987 | else | 6922 | else |
6988 | *q++ = c; | 6923 | *q++ = c; |
6989 | if (--cmdnleft <= 0) { | 6924 | if (--cmdnleft <= 0) { |
@@ -7019,30 +6954,30 @@ cmdputs(const char *s) | |||
7019 | * end-of-instructions flag in bit 0. | 6954 | * end-of-instructions flag in bit 0. |
7020 | */ | 6955 | */ |
7021 | 6956 | ||
7022 | #define CMDTXT_NOMORE 0x01 /* NOTE: no offset should be odd */ | 6957 | #define CMDTXT_NOMORE 0x01 /* NOTE: no offset should be odd */ |
7023 | #define CMDTXT_CHARPTR 0x40 | 6958 | #define CMDTXT_CHARPTR 0x40 |
7024 | #define CMDTXT_STRING 0x80 | 6959 | #define CMDTXT_STRING 0x80 |
7025 | #define CMDTXT_SPECIAL 0xC0 | 6960 | #define CMDTXT_SPECIAL 0xC0 |
7026 | #define CMDTXT_OFFSETMASK 0x3E | 6961 | #define CMDTXT_OFFSETMASK 0x3E |
7027 | 6962 | ||
7028 | static const char * const cmdtxt_strings[] = { | 6963 | static const char *const cmdtxt_strings[] = { |
7029 | /* 0 1 2 3 4 5 6 7 */ | 6964 | /* 0 1 2 3 4 5 6 7 */ |
7030 | "; ", "(", ")", " && ", " || ", "if ", "; then ", "...", | 6965 | "; ", "(", ")", " && ", " || ", "if ", "; then ", "...", |
7031 | /* 8 9 10 11 12 13 */ | 6966 | /* 8 9 10 11 12 13 */ |
7032 | "while ", "; do ", "; done", "until ", "for ", " in ...", | 6967 | "while ", "; do ", "; done", "until ", "for ", " in ...", |
7033 | /* 14 15 16 17 */ | 6968 | /* 14 15 16 17 */ |
7034 | "case ", "???", "() ...", "<<..." | 6969 | "case ", "???", "() ...", "<<..." |
7035 | }; | 6970 | }; |
7036 | 6971 | ||
7037 | static const char * const redir_strings[] = { | 6972 | static const char *const redir_strings[] = { |
7038 | ">", "<", "<>", ">>", ">|", ">&", "<&" | 6973 | ">", "<", "<>", ">>", ">|", ">&", "<&" |
7039 | }; | 6974 | }; |
7040 | 6975 | ||
7041 | static const unsigned char cmdtxt_ops[] = { | 6976 | static const unsigned char cmdtxt_ops[] = { |
7042 | #define CMDTXT_NSEMI 0 | 6977 | #define CMDTXT_NSEMI 0 |
7043 | offsetof(union node, nbinary.ch1), | 6978 | offsetof(union node, nbinary.ch1), |
7044 | 0|CMDTXT_STRING, | 6979 | 0 | CMDTXT_STRING, |
7045 | offsetof(union node, nbinary.ch2)|CMDTXT_NOMORE, | 6980 | offsetof(union node, nbinary.ch2) | CMDTXT_NOMORE, |
7046 | #define CMDTXT_NCMD (CMDTXT_NSEMI + 3) | 6981 | #define CMDTXT_NCMD (CMDTXT_NSEMI + 3) |
7047 | #define CMDTXT_NPIPE (CMDTXT_NCMD) | 6982 | #define CMDTXT_NPIPE (CMDTXT_NCMD) |
7048 | #define CMDTXT_NCASE (CMDTXT_NCMD) | 6983 | #define CMDTXT_NCASE (CMDTXT_NCMD) |
@@ -7056,52 +6991,52 @@ static const unsigned char cmdtxt_ops[] = { | |||
7056 | CMDTXT_SPECIAL, | 6991 | CMDTXT_SPECIAL, |
7057 | #define CMDTXT_NREDIR (CMDTXT_NPIPE + 1) | 6992 | #define CMDTXT_NREDIR (CMDTXT_NPIPE + 1) |
7058 | #define CMDTXT_NBACKGND (CMDTXT_NREDIR) | 6993 | #define CMDTXT_NBACKGND (CMDTXT_NREDIR) |
7059 | offsetof(union node, nredir.n)|CMDTXT_NOMORE, | 6994 | offsetof(union node, nredir.n) | CMDTXT_NOMORE, |
7060 | #define CMDTXT_NSUBSHELL (CMDTXT_NBACKGND + 1) | 6995 | #define CMDTXT_NSUBSHELL (CMDTXT_NBACKGND + 1) |
7061 | (1*2)|CMDTXT_STRING, | 6996 | (1 * 2) | CMDTXT_STRING, |
7062 | offsetof(union node, nredir.n), | 6997 | offsetof(union node, nredir.n), |
7063 | (2*2)|CMDTXT_STRING|CMDTXT_NOMORE, | 6998 | (2 * 2) | CMDTXT_STRING | CMDTXT_NOMORE, |
7064 | #define CMDTXT_NAND (CMDTXT_NSUBSHELL + 3) | 6999 | #define CMDTXT_NAND (CMDTXT_NSUBSHELL + 3) |
7065 | offsetof(union node, nbinary.ch1), | 7000 | offsetof(union node, nbinary.ch1), |
7066 | (3*2)|CMDTXT_STRING, | 7001 | (3 * 2) | CMDTXT_STRING, |
7067 | offsetof(union node, nbinary.ch2)|CMDTXT_NOMORE, | 7002 | offsetof(union node, nbinary.ch2) | CMDTXT_NOMORE, |
7068 | #define CMDTXT_NOR (CMDTXT_NAND + 3) | 7003 | #define CMDTXT_NOR (CMDTXT_NAND + 3) |
7069 | offsetof(union node, nbinary.ch1), | 7004 | offsetof(union node, nbinary.ch1), |
7070 | (4*2)|CMDTXT_STRING, | 7005 | (4 * 2) | CMDTXT_STRING, |
7071 | offsetof(union node, nbinary.ch2)|CMDTXT_NOMORE, | 7006 | offsetof(union node, nbinary.ch2) | CMDTXT_NOMORE, |
7072 | #define CMDTXT_NIF (CMDTXT_NOR + 3) | 7007 | #define CMDTXT_NIF (CMDTXT_NOR + 3) |
7073 | (5*2)|CMDTXT_STRING, | 7008 | (5 * 2) | CMDTXT_STRING, |
7074 | offsetof(union node, nif.test), | 7009 | offsetof(union node, nif.test), |
7075 | (6*2)|CMDTXT_STRING, | 7010 | (6 * 2) | CMDTXT_STRING, |
7076 | offsetof(union node, nif.ifpart), | 7011 | offsetof(union node, nif.ifpart), |
7077 | (7*2)|CMDTXT_STRING|CMDTXT_NOMORE, | 7012 | (7 * 2) | CMDTXT_STRING | CMDTXT_NOMORE, |
7078 | #define CMDTXT_NWHILE (CMDTXT_NIF + 5) | 7013 | #define CMDTXT_NWHILE (CMDTXT_NIF + 5) |
7079 | (8*2)|CMDTXT_STRING, | 7014 | (8 * 2) | CMDTXT_STRING, |
7080 | offsetof(union node, nbinary.ch1), | 7015 | offsetof(union node, nbinary.ch1), |
7081 | (9*2)|CMDTXT_STRING, | 7016 | (9 * 2) | CMDTXT_STRING, |
7082 | offsetof(union node, nbinary.ch2), | 7017 | offsetof(union node, nbinary.ch2), |
7083 | (10*2)|CMDTXT_STRING|CMDTXT_NOMORE, | 7018 | (10 * 2) | CMDTXT_STRING | CMDTXT_NOMORE, |
7084 | #define CMDTXT_NUNTIL (CMDTXT_NWHILE + 5) | 7019 | #define CMDTXT_NUNTIL (CMDTXT_NWHILE + 5) |
7085 | (11*2)|CMDTXT_STRING, | 7020 | (11 * 2) | CMDTXT_STRING, |
7086 | offsetof(union node, nbinary.ch1), | 7021 | offsetof(union node, nbinary.ch1), |
7087 | (9*2)|CMDTXT_STRING, | 7022 | (9 * 2) | CMDTXT_STRING, |
7088 | offsetof(union node, nbinary.ch2), | 7023 | offsetof(union node, nbinary.ch2), |
7089 | (10*2)|CMDTXT_STRING|CMDTXT_NOMORE, | 7024 | (10 * 2) | CMDTXT_STRING | CMDTXT_NOMORE, |
7090 | #define CMDTXT_NFOR (CMDTXT_NUNTIL + 5) | 7025 | #define CMDTXT_NFOR (CMDTXT_NUNTIL + 5) |
7091 | (12*2)|CMDTXT_STRING, | 7026 | (12 * 2) | CMDTXT_STRING, |
7092 | offsetof(union node, nfor.var)|CMDTXT_CHARPTR, | 7027 | offsetof(union node, nfor.var) | CMDTXT_CHARPTR, |
7093 | (13*2)|CMDTXT_STRING|CMDTXT_NOMORE, | 7028 | (13 * 2) | CMDTXT_STRING | CMDTXT_NOMORE, |
7094 | #define CMDTXT_NCLIST (CMDTXT_NFOR + 3) /* TODO: IS THIS CORRECT??? */ | 7029 | #define CMDTXT_NCLIST (CMDTXT_NFOR + 3) /* TODO: IS THIS CORRECT??? */ |
7095 | #define CMDTXT_NNOT (CMDTXT_NCLIST) /* TODO: IS THIS CORRECT??? */ | 7030 | #define CMDTXT_NNOT (CMDTXT_NCLIST) /* TODO: IS THIS CORRECT??? */ |
7096 | (15*2)|CMDTXT_STRING|CMDTXT_NOMORE, | 7031 | (15 * 2) | CMDTXT_STRING | CMDTXT_NOMORE, |
7097 | #define CMDTXT_NDEFUN (CMDTXT_NCLIST + 1) | 7032 | #define CMDTXT_NDEFUN (CMDTXT_NCLIST + 1) |
7098 | offsetof(union node, narg.text)|CMDTXT_CHARPTR, | 7033 | offsetof(union node, narg.text) | CMDTXT_CHARPTR, |
7099 | (16*2)|CMDTXT_STRING|CMDTXT_NOMORE, | 7034 | (16 * 2) | CMDTXT_STRING | CMDTXT_NOMORE, |
7100 | #define CMDTXT_NARG (CMDTXT_NDEFUN + 2) | 7035 | #define CMDTXT_NARG (CMDTXT_NDEFUN + 2) |
7101 | offsetof(union node, narg.text)|CMDTXT_CHARPTR|CMDTXT_NOMORE, | 7036 | offsetof(union node, narg.text) | CMDTXT_CHARPTR | CMDTXT_NOMORE, |
7102 | #define CMDTXT_NHERE (CMDTXT_NARG + 1) | 7037 | #define CMDTXT_NHERE (CMDTXT_NARG + 1) |
7103 | #define CMDTXT_NXHERE (CMDTXT_NHERE) | 7038 | #define CMDTXT_NXHERE (CMDTXT_NHERE) |
7104 | (17*2)|CMDTXT_STRING|CMDTXT_NOMORE, | 7039 | (17 * 2) | CMDTXT_STRING | CMDTXT_NOMORE, |
7105 | }; | 7040 | }; |
7106 | 7041 | ||
7107 | #if CMDTXT_NXHERE != 36 | 7042 | #if CMDTXT_NXHERE != 36 |
@@ -7137,8 +7072,7 @@ static const unsigned char cmdtxt_ops_index[26] = { | |||
7137 | CMDTXT_NNOT, | 7072 | CMDTXT_NNOT, |
7138 | }; | 7073 | }; |
7139 | 7074 | ||
7140 | static void | 7075 | static void cmdtxt(const union node *n) |
7141 | cmdtxt(const union node *n) | ||
7142 | { | 7076 | { |
7143 | const char *p; | 7077 | const char *p; |
7144 | 7078 | ||
@@ -7146,34 +7080,38 @@ cmdtxt(const union node *n) | |||
7146 | return; | 7080 | return; |
7147 | 7081 | ||
7148 | p = cmdtxt_ops + (int) cmdtxt_ops_index[n->type]; | 7082 | p = cmdtxt_ops + (int) cmdtxt_ops_index[n->type]; |
7149 | if ((*p & CMDTXT_SPECIAL) != CMDTXT_SPECIAL) { /* normal case */ | 7083 | if ((*p & CMDTXT_SPECIAL) != CMDTXT_SPECIAL) { /* normal case */ |
7150 | do { | 7084 | do { |
7151 | if (*p & CMDTXT_STRING) { /* output fixed string */ | 7085 | if (*p & CMDTXT_STRING) { /* output fixed string */ |
7152 | cmdputs(cmdtxt_strings[((int)(*p & CMDTXT_OFFSETMASK) >> 1)]); | 7086 | cmdputs(cmdtxt_strings |
7087 | [((int) (*p & CMDTXT_OFFSETMASK) >> 1)]); | ||
7153 | } else { | 7088 | } else { |
7154 | const char *pf = ((const char *) n) | 7089 | const char *pf = ((const char *) n) |
7155 | + ((int)(*p & CMDTXT_OFFSETMASK)); | 7090 | + ((int) (*p & CMDTXT_OFFSETMASK)); |
7156 | if (*p & CMDTXT_CHARPTR) { /* output dynamic string */ | 7091 | |
7092 | if (*p & CMDTXT_CHARPTR) { /* output dynamic string */ | ||
7157 | cmdputs(*((const char **) pf)); | 7093 | cmdputs(*((const char **) pf)); |
7158 | } else { /* output field */ | 7094 | } else { /* output field */ |
7159 | cmdtxt(*((const union node **) pf)); | 7095 | cmdtxt(*((const union node **) pf)); |
7160 | } | 7096 | } |
7161 | } | 7097 | } |
7162 | } while (!(*p++ & CMDTXT_NOMORE)); | 7098 | } while (!(*p++ & CMDTXT_NOMORE)); |
7163 | } else if (n->type == NCMD) { | 7099 | } else if (n->type == NCMD) { |
7164 | union node *np; | 7100 | union node *np; |
7165 | for (np = n->ncmd.args ; np ; np = np->narg.next) { | 7101 | |
7102 | for (np = n->ncmd.args; np; np = np->narg.next) { | ||
7166 | cmdtxt(np); | 7103 | cmdtxt(np); |
7167 | if (np->narg.next) | 7104 | if (np->narg.next) |
7168 | cmdputs(spcstr); | 7105 | cmdputs(spcstr); |
7169 | } | 7106 | } |
7170 | for (np = n->ncmd.redirect ; np ; np = np->nfile.next) { | 7107 | for (np = n->ncmd.redirect; np; np = np->nfile.next) { |
7171 | cmdputs(spcstr); | 7108 | cmdputs(spcstr); |
7172 | cmdtxt(np); | 7109 | cmdtxt(np); |
7173 | } | 7110 | } |
7174 | } else if (n->type == NPIPE) { | 7111 | } else if (n->type == NPIPE) { |
7175 | struct nodelist *lp; | 7112 | struct nodelist *lp; |
7176 | for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) { | 7113 | |
7114 | for (lp = n->npipe.cmdlist; lp; lp = lp->next) { | ||
7177 | cmdtxt(lp->n); | 7115 | cmdtxt(lp->n); |
7178 | if (lp->next) | 7116 | if (lp->next) |
7179 | cmdputs(" | "); | 7117 | cmdputs(" | "); |
@@ -7208,9 +7146,8 @@ cmdtxt(const union node *n) | |||
7208 | } | 7146 | } |
7209 | } | 7147 | } |
7210 | } | 7148 | } |
7211 | #else /* CMDTXT_TABLE */ | 7149 | #else /* CMDTXT_TABLE */ |
7212 | static void | 7150 | static void cmdtxt(const union node *n) |
7213 | cmdtxt(const union node *n) | ||
7214 | { | 7151 | { |
7215 | union node *np; | 7152 | union node *np; |
7216 | struct nodelist *lp; | 7153 | struct nodelist *lp; |
@@ -7237,7 +7174,7 @@ cmdtxt(const union node *n) | |||
7237 | cmdtxt(n->nbinary.ch2); | 7174 | cmdtxt(n->nbinary.ch2); |
7238 | break; | 7175 | break; |
7239 | case NPIPE: | 7176 | case NPIPE: |
7240 | for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) { | 7177 | for (lp = n->npipe.cmdlist; lp; lp = lp->next) { |
7241 | cmdtxt(lp->n); | 7178 | cmdtxt(lp->n); |
7242 | if (lp->next) | 7179 | if (lp->next) |
7243 | cmdputs(" | "); | 7180 | cmdputs(" | "); |
@@ -7264,7 +7201,7 @@ cmdtxt(const union node *n) | |||
7264 | goto until; | 7201 | goto until; |
7265 | case NUNTIL: | 7202 | case NUNTIL: |
7266 | cmdputs("until "); | 7203 | cmdputs("until "); |
7267 | until: | 7204 | until: |
7268 | cmdtxt(n->nbinary.ch1); | 7205 | cmdtxt(n->nbinary.ch1); |
7269 | cmdputs("; do "); | 7206 | cmdputs("; do "); |
7270 | cmdtxt(n->nbinary.ch2); | 7207 | cmdtxt(n->nbinary.ch2); |
@@ -7285,12 +7222,12 @@ until: | |||
7285 | cmdputs("() ..."); | 7222 | cmdputs("() ..."); |
7286 | break; | 7223 | break; |
7287 | case NCMD: | 7224 | case NCMD: |
7288 | for (np = n->ncmd.args ; np ; np = np->narg.next) { | 7225 | for (np = n->ncmd.args; np; np = np->narg.next) { |
7289 | cmdtxt(np); | 7226 | cmdtxt(np); |
7290 | if (np->narg.next) | 7227 | if (np->narg.next) |
7291 | cmdputs(spcstr); | 7228 | cmdputs(spcstr); |
7292 | } | 7229 | } |
7293 | for (np = n->ncmd.redirect ; np ; np = np->nfile.next) { | 7230 | for (np = n->ncmd.redirect; np; np = np->nfile.next) { |
7294 | cmdputs(spcstr); | 7231 | cmdputs(spcstr); |
7295 | cmdtxt(np); | 7232 | cmdtxt(np); |
7296 | } | 7233 | } |
@@ -7299,20 +7236,34 @@ until: | |||
7299 | cmdputs(n->narg.text); | 7236 | cmdputs(n->narg.text); |
7300 | break; | 7237 | break; |
7301 | case NTO: | 7238 | case NTO: |
7302 | p = ">"; i = 1; goto redir; | 7239 | p = ">"; |
7240 | i = 1; | ||
7241 | goto redir; | ||
7303 | case NAPPEND: | 7242 | case NAPPEND: |
7304 | p = ">>"; i = 1; goto redir; | 7243 | p = ">>"; |
7244 | i = 1; | ||
7245 | goto redir; | ||
7305 | case NTOFD: | 7246 | case NTOFD: |
7306 | p = ">&"; i = 1; goto redir; | 7247 | p = ">&"; |
7248 | i = 1; | ||
7249 | goto redir; | ||
7307 | case NTOOV: | 7250 | case NTOOV: |
7308 | p = ">|"; i = 1; goto redir; | 7251 | p = ">|"; |
7252 | i = 1; | ||
7253 | goto redir; | ||
7309 | case NFROM: | 7254 | case NFROM: |
7310 | p = "<"; i = 0; goto redir; | 7255 | p = "<"; |
7256 | i = 0; | ||
7257 | goto redir; | ||
7311 | case NFROMFD: | 7258 | case NFROMFD: |
7312 | p = "<&"; i = 0; goto redir; | 7259 | p = "<&"; |
7260 | i = 0; | ||
7261 | goto redir; | ||
7313 | case NFROMTO: | 7262 | case NFROMTO: |
7314 | p = "<>"; i = 0; goto redir; | 7263 | p = "<>"; |
7315 | redir: | 7264 | i = 0; |
7265 | goto redir; | ||
7266 | redir: | ||
7316 | if (n->nfile.fd != i) { | 7267 | if (n->nfile.fd != i) { |
7317 | s[0] = n->nfile.fd + '0'; | 7268 | s[0] = n->nfile.fd + '0'; |
7318 | s[1] = '\0'; | 7269 | s[1] = '\0'; |
@@ -7336,10 +7287,9 @@ redir: | |||
7336 | break; | 7287 | break; |
7337 | } | 7288 | } |
7338 | } | 7289 | } |
7339 | #endif /* CMDTXT_TABLE */ | 7290 | #endif /* CMDTXT_TABLE */ |
7340 | 7291 | ||
7341 | static char * | 7292 | static char *commandtext(const union node *n) |
7342 | commandtext(const union node *n) | ||
7343 | { | 7293 | { |
7344 | char *name; | 7294 | char *name; |
7345 | 7295 | ||
@@ -7351,7 +7301,8 @@ commandtext(const union node *n) | |||
7351 | } | 7301 | } |
7352 | 7302 | ||
7353 | 7303 | ||
7354 | static void waitonint(int sig) { | 7304 | static void waitonint(int sig) |
7305 | { | ||
7355 | intreceived = 1; | 7306 | intreceived = 1; |
7356 | } | 7307 | } |
7357 | 7308 | ||
@@ -7365,8 +7316,8 @@ static void waitonint(int sig) { | |||
7365 | #define MAXMBOXES 10 | 7316 | #define MAXMBOXES 10 |
7366 | 7317 | ||
7367 | 7318 | ||
7368 | static int nmboxes; /* number of mailboxes */ | 7319 | static int nmboxes; /* number of mailboxes */ |
7369 | static time_t mailtime[MAXMBOXES]; /* times of mailboxes */ | 7320 | static time_t mailtime[MAXMBOXES]; /* times of mailboxes */ |
7370 | 7321 | ||
7371 | 7322 | ||
7372 | 7323 | ||
@@ -7376,8 +7327,7 @@ static time_t mailtime[MAXMBOXES]; /* times of mailboxes */ | |||
7376 | * values. | 7327 | * values. |
7377 | */ | 7328 | */ |
7378 | 7329 | ||
7379 | static void | 7330 | static void chkmail(int silent) |
7380 | chkmail(int silent) | ||
7381 | { | 7331 | { |
7382 | int i; | 7332 | int i; |
7383 | const char *mpath; | 7333 | const char *mpath; |
@@ -7392,23 +7342,22 @@ chkmail(int silent) | |||
7392 | return; | 7342 | return; |
7393 | setstackmark(&smark); | 7343 | setstackmark(&smark); |
7394 | mpath = mpathset()? mpathval() : mailval(); | 7344 | mpath = mpathset()? mpathval() : mailval(); |
7395 | for (i = 0 ; i < nmboxes ; i++) { | 7345 | for (i = 0; i < nmboxes; i++) { |
7396 | p = padvance(&mpath, nullstr); | 7346 | p = padvance(&mpath, nullstr); |
7397 | if (p == NULL) | 7347 | if (p == NULL) |
7398 | break; | 7348 | break; |
7399 | if (*p == '\0') | 7349 | if (*p == '\0') |
7400 | continue; | 7350 | continue; |
7401 | for (q = p ; *q ; q++); | 7351 | for (q = p; *q; q++); |
7402 | #ifdef DEBUG | 7352 | #ifdef DEBUG |
7403 | if (q[-1] != '/') | 7353 | if (q[-1] != '/') |
7404 | abort(); | 7354 | abort(); |
7405 | #endif | 7355 | #endif |
7406 | q[-1] = '\0'; /* delete trailing '/' */ | 7356 | q[-1] = '\0'; /* delete trailing '/' */ |
7407 | if (stat(p, &statb) < 0) | 7357 | if (stat(p, &statb) < 0) |
7408 | statb.st_size = 0; | 7358 | statb.st_size = 0; |
7409 | if (statb.st_size > mailtime[i] && ! silent) { | 7359 | if (statb.st_size > mailtime[i] && !silent) { |
7410 | out2fmt(snlfmt, | 7360 | out2fmt(snlfmt, pathopt ? pathopt : "you have mail"); |
7411 | pathopt? pathopt : "you have mail"); | ||
7412 | } | 7361 | } |
7413 | mailtime[i] = statb.st_size; | 7362 | mailtime[i] = statb.st_size; |
7414 | } | 7363 | } |
@@ -7416,7 +7365,7 @@ chkmail(int silent) | |||
7416 | popstackmark(&smark); | 7365 | popstackmark(&smark); |
7417 | } | 7366 | } |
7418 | 7367 | ||
7419 | #endif /* CONFIG_ASH_MAIL */ | 7368 | #endif /* CONFIG_ASH_MAIL */ |
7420 | 7369 | ||
7421 | #define PROFILE 0 | 7370 | #define PROFILE 0 |
7422 | 7371 | ||
@@ -7427,11 +7376,11 @@ extern int etext(); | |||
7427 | 7376 | ||
7428 | static int isloginsh = 0; | 7377 | static int isloginsh = 0; |
7429 | 7378 | ||
7430 | static void read_profile (const char *); | 7379 | static void read_profile(const char *); |
7431 | static void cmdloop (int); | 7380 | static void cmdloop(int); |
7432 | static void options (int); | 7381 | static void options(int); |
7433 | static void setoption (int, int); | 7382 | static void setoption(int, int); |
7434 | static void procargs (int, char **); | 7383 | static void procargs(int, char **); |
7435 | 7384 | ||
7436 | 7385 | ||
7437 | /* | 7386 | /* |
@@ -7442,8 +7391,7 @@ static void procargs (int, char **); | |||
7442 | * is used to figure out how far we had gotten. | 7391 | * is used to figure out how far we had gotten. |
7443 | */ | 7392 | */ |
7444 | 7393 | ||
7445 | int | 7394 | int ash_main(int argc, char **argv) |
7446 | ash_main(int argc, char **argv) | ||
7447 | { | 7395 | { |
7448 | struct jmploc jmploc; | 7396 | struct jmploc jmploc; |
7449 | struct stackmark smark; | 7397 | struct stackmark smark; |
@@ -7484,15 +7432,15 @@ ash_main(int argc, char **argv) | |||
7484 | } else if (exception == EXERROR) { | 7432 | } else if (exception == EXERROR) { |
7485 | exitstatus = 2; | 7433 | exitstatus = 2; |
7486 | } | 7434 | } |
7487 | if (state == 0 || iflag == 0 || ! rootshell) | 7435 | if (state == 0 || iflag == 0 || !rootshell) |
7488 | exitshell(exitstatus); | 7436 | exitshell(exitstatus); |
7489 | } | 7437 | } |
7490 | reset(); | 7438 | reset(); |
7491 | if (exception == EXINT) { | 7439 | if (exception == EXINT) { |
7492 | out2c('\n'); | 7440 | out2c('\n'); |
7493 | } | 7441 | } |
7494 | popstackmark(&smark); | 7442 | popstackmark(&smark); |
7495 | FORCEINTON; /* enable interrupts */ | 7443 | FORCEINTON; /* enable interrupts */ |
7496 | if (state == 1) | 7444 | if (state == 1) |
7497 | goto state1; | 7445 | goto state1; |
7498 | else if (state == 2) | 7446 | else if (state == 2) |
@@ -7505,7 +7453,8 @@ ash_main(int argc, char **argv) | |||
7505 | handler = &jmploc; | 7453 | handler = &jmploc; |
7506 | #ifdef DEBUG | 7454 | #ifdef DEBUG |
7507 | opentrace(); | 7455 | opentrace(); |
7508 | trputs("Shell args: "); trargs(argv); | 7456 | trputs("Shell args: "); |
7457 | trargs(argv); | ||
7509 | #endif | 7458 | #endif |
7510 | rootpid = getpid(); | 7459 | rootpid = getpid(); |
7511 | rootshell = 1; | 7460 | rootshell = 1; |
@@ -7517,11 +7466,11 @@ ash_main(int argc, char **argv) | |||
7517 | if (isloginsh) { | 7466 | if (isloginsh) { |
7518 | state = 1; | 7467 | state = 1; |
7519 | read_profile("/etc/profile"); | 7468 | read_profile("/etc/profile"); |
7520 | state1: | 7469 | state1: |
7521 | state = 2; | 7470 | state = 2; |
7522 | read_profile(".profile"); | 7471 | read_profile(".profile"); |
7523 | } | 7472 | } |
7524 | state2: | 7473 | state2: |
7525 | state = 3; | 7474 | state = 3; |
7526 | #ifndef linux | 7475 | #ifndef linux |
7527 | if (getuid() == geteuid() && getgid() == getegid()) { | 7476 | if (getuid() == geteuid() && getgid() == getegid()) { |
@@ -7533,28 +7482,29 @@ state2: | |||
7533 | #ifndef linux | 7482 | #ifndef linux |
7534 | } | 7483 | } |
7535 | #endif | 7484 | #endif |
7536 | state3: | 7485 | state3: |
7537 | state = 4; | 7486 | state = 4; |
7538 | if (sflag == 0 || minusc) { | 7487 | if (sflag == 0 || minusc) { |
7539 | static const char sigs[] = { | 7488 | static const char sigs[] = { |
7540 | SIGINT, SIGQUIT, SIGHUP, | 7489 | SIGINT, SIGQUIT, SIGHUP, |
7541 | #ifdef SIGTSTP | 7490 | #ifdef SIGTSTP |
7542 | SIGTSTP, | 7491 | SIGTSTP, |
7543 | #endif | 7492 | #endif |
7544 | SIGPIPE | 7493 | SIGPIPE |
7545 | }; | 7494 | }; |
7546 | #define SIGSSIZE ((sizeof(sigs)/sizeof(sigs[0])) - 1) /* trailing nul */ | 7495 | |
7496 | #define SIGSSIZE ((sizeof(sigs)/sizeof(sigs[0])) - 1) /* trailing nul */ | ||
7547 | int i; | 7497 | int i; |
7548 | 7498 | ||
7549 | for (i = 0; i < SIGSSIZE; i++) | 7499 | for (i = 0; i < SIGSSIZE; i++) |
7550 | setsignal(sigs[i]); | 7500 | setsignal(sigs[i]); |
7551 | } | 7501 | } |
7552 | 7502 | ||
7553 | if (minusc) | 7503 | if (minusc) |
7554 | evalstring(minusc, 0); | 7504 | evalstring(minusc, 0); |
7555 | 7505 | ||
7556 | if (sflag || minusc == NULL) { | 7506 | if (sflag || minusc == NULL) { |
7557 | state4: /* XXX ??? - why isn't this before the "if" statement */ | 7507 | state4: /* XXX ??? - why isn't this before the "if" statement */ |
7558 | cmdloop(1); | 7508 | cmdloop(1); |
7559 | } | 7509 | } |
7560 | #if PROFILE | 7510 | #if PROFILE |
@@ -7570,8 +7520,7 @@ state4: /* XXX ??? - why isn't this before the "if" statement */ | |||
7570 | * loop; it turns on prompting if the shell is interactive. | 7520 | * loop; it turns on prompting if the shell is interactive. |
7571 | */ | 7521 | */ |
7572 | 7522 | ||
7573 | static void | 7523 | static void cmdloop(int top) |
7574 | cmdloop(int top) | ||
7575 | { | 7524 | { |
7576 | union node *n; | 7525 | union node *n; |
7577 | struct stackmark smark; | 7526 | struct stackmark smark; |
@@ -7624,8 +7573,7 @@ cmdloop(int top) | |||
7624 | * Read /etc/profile or .profile. Return on error. | 7573 | * Read /etc/profile or .profile. Return on error. |
7625 | */ | 7574 | */ |
7626 | 7575 | ||
7627 | static void | 7576 | static void read_profile(const char *name) |
7628 | read_profile(const char *name) | ||
7629 | { | 7577 | { |
7630 | int fd; | 7578 | int fd; |
7631 | int xflag_save; | 7579 | int xflag_save; |
@@ -7641,7 +7589,7 @@ read_profile(const char *name) | |||
7641 | /* Note: Might do a little redundant work, but reduces code size. */ | 7589 | /* Note: Might do a little redundant work, but reduces code size. */ |
7642 | xflag_save = xflag; | 7590 | xflag_save = xflag; |
7643 | vflag_save = vflag; | 7591 | vflag_save = vflag; |
7644 | if (qflag) { | 7592 | if (qflag) { |
7645 | vflag = xflag = 0; | 7593 | vflag = xflag = 0; |
7646 | } | 7594 | } |
7647 | cmdloop(0); | 7595 | cmdloop(0); |
@@ -7656,8 +7604,7 @@ read_profile(const char *name) | |||
7656 | * Read a file containing shell functions. | 7604 | * Read a file containing shell functions. |
7657 | */ | 7605 | */ |
7658 | 7606 | ||
7659 | static void | 7607 | static void readcmdfile(const char *name) |
7660 | readcmdfile(const char *name) | ||
7661 | { | 7608 | { |
7662 | int fd; | 7609 | int fd; |
7663 | 7610 | ||
@@ -7678,8 +7625,7 @@ readcmdfile(const char *name) | |||
7678 | * search for the file, which is necessary to find sub-commands. | 7625 | * search for the file, which is necessary to find sub-commands. |
7679 | */ | 7626 | */ |
7680 | 7627 | ||
7681 | static inline char * | 7628 | static inline char *find_dot_file(char *mybasename) |
7682 | find_dot_file(char *mybasename) | ||
7683 | { | 7629 | { |
7684 | char *fullname; | 7630 | char *fullname; |
7685 | const char *path = pathval(); | 7631 | const char *path = pathval(); |
@@ -7705,24 +7651,24 @@ find_dot_file(char *mybasename) | |||
7705 | /* NOTREACHED */ | 7651 | /* NOTREACHED */ |
7706 | } | 7652 | } |
7707 | 7653 | ||
7708 | static int | 7654 | static int dotcmd(int argc, char **argv) |
7709 | dotcmd(int argc, char **argv) | ||
7710 | { | 7655 | { |
7711 | struct strlist *sp; | 7656 | struct strlist *sp; |
7712 | volatile struct shparam saveparam; | 7657 | volatile struct shparam saveparam; |
7658 | |||
7713 | exitstatus = 0; | 7659 | exitstatus = 0; |
7714 | 7660 | ||
7715 | for (sp = cmdenviron; sp ; sp = sp->next) | 7661 | for (sp = cmdenviron; sp; sp = sp->next) |
7716 | setvareq(xstrdup(sp->text), VSTRFIXED|VTEXTFIXED); | 7662 | setvareq(xstrdup(sp->text), VSTRFIXED | VTEXTFIXED); |
7717 | 7663 | ||
7718 | if (argc >= 2) { /* That's what SVR2 does */ | 7664 | if (argc >= 2) { /* That's what SVR2 does */ |
7719 | char *fullname; | 7665 | char *fullname; |
7720 | struct stackmark smark; | 7666 | struct stackmark smark; |
7721 | 7667 | ||
7722 | setstackmark(&smark); | 7668 | setstackmark(&smark); |
7723 | fullname = find_dot_file(argv[1]); | 7669 | fullname = find_dot_file(argv[1]); |
7724 | 7670 | ||
7725 | if (argc>2) { | 7671 | if (argc > 2) { |
7726 | saveparam = shellparam; | 7672 | saveparam = shellparam; |
7727 | shellparam.malloc = 0; | 7673 | shellparam.malloc = 0; |
7728 | shellparam.nparam = argc - 2; | 7674 | shellparam.nparam = argc - 2; |
@@ -7734,7 +7680,7 @@ dotcmd(int argc, char **argv) | |||
7734 | cmdloop(0); | 7680 | cmdloop(0); |
7735 | popfile(); | 7681 | popfile(); |
7736 | 7682 | ||
7737 | if (argc>2) { | 7683 | if (argc > 2) { |
7738 | freeparam(&shellparam); | 7684 | freeparam(&shellparam); |
7739 | shellparam = saveparam; | 7685 | shellparam = saveparam; |
7740 | }; | 7686 | }; |
@@ -7745,8 +7691,7 @@ dotcmd(int argc, char **argv) | |||
7745 | } | 7691 | } |
7746 | 7692 | ||
7747 | 7693 | ||
7748 | static int | 7694 | static int exitcmd(int argc, char **argv) |
7749 | exitcmd(int argc, char **argv) | ||
7750 | { | 7695 | { |
7751 | if (stoppedjobs()) | 7696 | if (stoppedjobs()) |
7752 | return 0; | 7697 | return 0; |
@@ -7758,8 +7703,7 @@ exitcmd(int argc, char **argv) | |||
7758 | /* NOTREACHED */ | 7703 | /* NOTREACHED */ |
7759 | } | 7704 | } |
7760 | 7705 | ||
7761 | static pointer | 7706 | static pointer stalloc(int nbytes) |
7762 | stalloc(int nbytes) | ||
7763 | { | 7707 | { |
7764 | char *p; | 7708 | char *p; |
7765 | 7709 | ||
@@ -7786,25 +7730,23 @@ stalloc(int nbytes) | |||
7786 | } | 7730 | } |
7787 | 7731 | ||
7788 | 7732 | ||
7789 | static void | 7733 | static void stunalloc(pointer p) |
7790 | stunalloc(pointer p) | ||
7791 | { | 7734 | { |
7792 | #ifdef DEBUG | 7735 | #ifdef DEBUG |
7793 | if (p == NULL) { /*DEBUG */ | 7736 | if (p == NULL) { /*DEBUG */ |
7794 | write(2, "stunalloc\n", 10); | 7737 | write(2, "stunalloc\n", 10); |
7795 | abort(); | 7738 | abort(); |
7796 | } | 7739 | } |
7797 | #endif | 7740 | #endif |
7798 | if (!(stacknxt >= (char *)p && (char *)p >= stackp->space)) { | 7741 | if (!(stacknxt >= (char *) p && (char *) p >= stackp->space)) { |
7799 | p = stackp->space; | 7742 | p = stackp->space; |
7800 | } | 7743 | } |
7801 | stacknleft += stacknxt - (char *)p; | 7744 | stacknleft += stacknxt - (char *) p; |
7802 | stacknxt = p; | 7745 | stacknxt = p; |
7803 | } | 7746 | } |
7804 | 7747 | ||
7805 | 7748 | ||
7806 | static void | 7749 | static void setstackmark(struct stackmark *mark) |
7807 | setstackmark(struct stackmark *mark) | ||
7808 | { | 7750 | { |
7809 | mark->stackp = stackp; | 7751 | mark->stackp = stackp; |
7810 | mark->stacknxt = stacknxt; | 7752 | mark->stacknxt = stacknxt; |
@@ -7814,8 +7756,7 @@ setstackmark(struct stackmark *mark) | |||
7814 | } | 7756 | } |
7815 | 7757 | ||
7816 | 7758 | ||
7817 | static void | 7759 | static void popstackmark(struct stackmark *mark) |
7818 | popstackmark(struct stackmark *mark) | ||
7819 | { | 7760 | { |
7820 | struct stack_block *sp; | 7761 | struct stack_block *sp; |
7821 | 7762 | ||
@@ -7842,8 +7783,8 @@ popstackmark(struct stackmark *mark) | |||
7842 | * part of the block that has been used. | 7783 | * part of the block that has been used. |
7843 | */ | 7784 | */ |
7844 | 7785 | ||
7845 | static void | 7786 | static void growstackblock(void) |
7846 | growstackblock(void) { | 7787 | { |
7847 | char *p; | 7788 | char *p; |
7848 | int newlen = ALIGN(stacknleft * 2 + 100); | 7789 | int newlen = ALIGN(stacknleft * 2 + 100); |
7849 | char *oldspace = stacknxt; | 7790 | char *oldspace = stacknxt; |
@@ -7856,37 +7797,38 @@ growstackblock(void) { | |||
7856 | oldstackp = stackp; | 7797 | oldstackp = stackp; |
7857 | sp = stackp; | 7798 | sp = stackp; |
7858 | stackp = sp->prev; | 7799 | stackp = sp->prev; |
7859 | sp = xrealloc((pointer)sp, sizeof(struct stack_block) - MINSIZE + newlen); | 7800 | sp = xrealloc((pointer) sp, |
7801 | sizeof(struct stack_block) - MINSIZE + newlen); | ||
7860 | sp->prev = stackp; | 7802 | sp->prev = stackp; |
7861 | stackp = sp; | 7803 | stackp = sp; |
7862 | stacknxt = sp->space; | 7804 | stacknxt = sp->space; |
7863 | stacknleft = newlen; | 7805 | stacknleft = newlen; |
7864 | { | 7806 | { |
7865 | /* Stack marks pointing to the start of the old block | 7807 | /* Stack marks pointing to the start of the old block |
7866 | * must be relocated to point to the new block | 7808 | * must be relocated to point to the new block |
7867 | */ | 7809 | */ |
7868 | struct stackmark *xmark; | 7810 | struct stackmark *xmark; |
7869 | xmark = markp; | 7811 | |
7870 | while (xmark != NULL && xmark->stackp == oldstackp) { | 7812 | xmark = markp; |
7871 | xmark->stackp = stackp; | 7813 | while (xmark != NULL && xmark->stackp == oldstackp) { |
7872 | xmark->stacknxt = stacknxt; | 7814 | xmark->stackp = stackp; |
7873 | xmark->stacknleft = stacknleft; | 7815 | xmark->stacknxt = stacknxt; |
7874 | xmark = xmark->marknext; | 7816 | xmark->stacknleft = stacknleft; |
7875 | } | 7817 | xmark = xmark->marknext; |
7818 | } | ||
7876 | } | 7819 | } |
7877 | INTON; | 7820 | INTON; |
7878 | } else { | 7821 | } else { |
7879 | p = stalloc(newlen); | 7822 | p = stalloc(newlen); |
7880 | memcpy(p, oldspace, oldlen); | 7823 | memcpy(p, oldspace, oldlen); |
7881 | stacknxt = p; /* free the space */ | 7824 | stacknxt = p; /* free the space */ |
7882 | stacknleft += newlen; /* we just allocated */ | 7825 | stacknleft += newlen; /* we just allocated */ |
7883 | } | 7826 | } |
7884 | } | 7827 | } |
7885 | 7828 | ||
7886 | 7829 | ||
7887 | 7830 | ||
7888 | static inline void | 7831 | static inline void grabstackblock(int len) |
7889 | grabstackblock(int len) | ||
7890 | { | 7832 | { |
7891 | len = ALIGN(len); | 7833 | len = ALIGN(len); |
7892 | stacknxt += len; | 7834 | stacknxt += len; |
@@ -7914,9 +7856,10 @@ grabstackblock(int len) | |||
7914 | */ | 7856 | */ |
7915 | 7857 | ||
7916 | 7858 | ||
7917 | static char * | 7859 | static char *growstackstr(void) |
7918 | growstackstr(void) { | 7860 | { |
7919 | int len = stackblocksize(); | 7861 | int len = stackblocksize(); |
7862 | |||
7920 | if (herefd >= 0 && len >= 1024) { | 7863 | if (herefd >= 0 && len >= 1024) { |
7921 | xwrite(herefd, stackblock(), len); | 7864 | xwrite(herefd, stackblock(), len); |
7922 | sstrnleft = len - 1; | 7865 | sstrnleft = len - 1; |
@@ -7932,9 +7875,10 @@ growstackstr(void) { | |||
7932 | * Called from CHECKSTRSPACE. | 7875 | * Called from CHECKSTRSPACE. |
7933 | */ | 7876 | */ |
7934 | 7877 | ||
7935 | static char * | 7878 | static char *makestrspace(size_t newlen) |
7936 | makestrspace(size_t newlen) { | 7879 | { |
7937 | int len = stackblocksize() - sstrnleft; | 7880 | int len = stackblocksize() - sstrnleft; |
7881 | |||
7938 | do { | 7882 | do { |
7939 | growstackblock(); | 7883 | growstackblock(); |
7940 | sstrnleft = stackblocksize() - len; | 7884 | sstrnleft = stackblocksize() - len; |
@@ -7944,13 +7888,13 @@ makestrspace(size_t newlen) { | |||
7944 | 7888 | ||
7945 | 7889 | ||
7946 | 7890 | ||
7947 | static void | 7891 | static void ungrabstackstr(char *s, char *p) |
7948 | ungrabstackstr(char *s, char *p) | ||
7949 | { | 7892 | { |
7950 | stacknleft += stacknxt - s; | 7893 | stacknleft += stacknxt - s; |
7951 | stacknxt = s; | 7894 | stacknxt = s; |
7952 | sstrnleft = stacknleft - (p - s); | 7895 | sstrnleft = stacknleft - (p - s); |
7953 | } | 7896 | } |
7897 | |||
7954 | /* | 7898 | /* |
7955 | * Miscelaneous builtins. | 7899 | * Miscelaneous builtins. |
7956 | */ | 7900 | */ |
@@ -7971,8 +7915,7 @@ typedef long rlim_t; | |||
7971 | * This uses unbuffered input, which may be avoidable in some cases. | 7915 | * This uses unbuffered input, which may be avoidable in some cases. |
7972 | */ | 7916 | */ |
7973 | 7917 | ||
7974 | static int | 7918 | static int readcmd(int argc, char **argv) |
7975 | readcmd(int argc, char **argv) | ||
7976 | { | 7919 | { |
7977 | char **ap; | 7920 | char **ap; |
7978 | int backslash; | 7921 | int backslash; |
@@ -7994,7 +7937,7 @@ readcmd(int argc, char **argv) | |||
7994 | rflag = 1; | 7937 | rflag = 1; |
7995 | } | 7938 | } |
7996 | if (prompt && isatty(0)) { | 7939 | if (prompt && isatty(0)) { |
7997 | out2str(prompt); /* read without cmdedit */ | 7940 | out2str(prompt); /* read without cmdedit */ |
7998 | flushall(); | 7941 | flushall(); |
7999 | } | 7942 | } |
8000 | if (*(ap = argptr) == NULL) | 7943 | if (*(ap = argptr) == NULL) |
@@ -8056,8 +7999,7 @@ readcmd(int argc, char **argv) | |||
8056 | 7999 | ||
8057 | 8000 | ||
8058 | 8001 | ||
8059 | static int | 8002 | static int umaskcmd(int argc, char **argv) |
8060 | umaskcmd(int argc, char **argv) | ||
8061 | { | 8003 | { |
8062 | static const char permuser[3] = "ugo"; | 8004 | static const char permuser[3] = "ugo"; |
8063 | static const char permmode[3] = "rwx"; | 8005 | static const char permmode[3] = "rwx"; |
@@ -8085,12 +8027,14 @@ umaskcmd(int argc, char **argv) | |||
8085 | if (symbolic_mode) { | 8027 | if (symbolic_mode) { |
8086 | char buf[18]; | 8028 | char buf[18]; |
8087 | char *p = buf; | 8029 | char *p = buf; |
8088 | for (i=0 ; i<3 ; i++) { | 8030 | |
8031 | for (i = 0; i < 3; i++) { | ||
8089 | int j; | 8032 | int j; |
8033 | |||
8090 | *p++ = permuser[i]; | 8034 | *p++ = permuser[i]; |
8091 | *p++ = '='; | 8035 | *p++ = '='; |
8092 | for (j=0 ; j<3 ; j++) { | 8036 | for (j = 0; j < 3; j++) { |
8093 | if ((mask & permmask[3*i+j]) == 0) { | 8037 | if ((mask & permmask[3 * i + j]) == 0) { |
8094 | *p++ = permmode[j]; | 8038 | *p++ = permmode[j]; |
8095 | } | 8039 | } |
8096 | } | 8040 | } |
@@ -8102,7 +8046,7 @@ umaskcmd(int argc, char **argv) | |||
8102 | printf("%.4o\n", mask); | 8046 | printf("%.4o\n", mask); |
8103 | } | 8047 | } |
8104 | } else { | 8048 | } else { |
8105 | if (is_digit((unsigned char)*ap)) { | 8049 | if (is_digit((unsigned char) *ap)) { |
8106 | mask = 0; | 8050 | mask = 0; |
8107 | do { | 8051 | do { |
8108 | if (*ap >= '8' || *ap < '0') | 8052 | if (*ap >= '8' || *ap < '0') |
@@ -8112,7 +8056,7 @@ umaskcmd(int argc, char **argv) | |||
8112 | umask(mask); | 8056 | umask(mask); |
8113 | } else { | 8057 | } else { |
8114 | mask = ~mask & 0777; | 8058 | mask = ~mask & 0777; |
8115 | if (! parse_mode(ap, &mask)) { | 8059 | if (!parse_mode(ap, &mask)) { |
8116 | error("Illegal mode: %s", ap); | 8060 | error("Illegal mode: %s", ap); |
8117 | } | 8061 | } |
8118 | umask(~mask & 0777); | 8062 | umask(~mask & 0777); |
@@ -8133,97 +8077,95 @@ umaskcmd(int argc, char **argv) | |||
8133 | 8077 | ||
8134 | struct limits { | 8078 | struct limits { |
8135 | const char *name; | 8079 | const char *name; |
8136 | short cmd; | 8080 | short cmd; |
8137 | short factor; /* multiply by to get rlim_{cur,max} values */ | 8081 | short factor; /* multiply by to get rlim_{cur,max} values */ |
8138 | }; | 8082 | }; |
8139 | 8083 | ||
8140 | static const struct limits limits[] = { | 8084 | static const struct limits limits[] = { |
8141 | #ifdef RLIMIT_CPU | 8085 | #ifdef RLIMIT_CPU |
8142 | { "time(seconds)", RLIMIT_CPU, 1 }, | 8086 | {"time(seconds)", RLIMIT_CPU, 1}, |
8143 | #endif | 8087 | #endif |
8144 | #ifdef RLIMIT_FSIZE | 8088 | #ifdef RLIMIT_FSIZE |
8145 | { "file(blocks)", RLIMIT_FSIZE, 512 }, | 8089 | {"file(blocks)", RLIMIT_FSIZE, 512}, |
8146 | #endif | 8090 | #endif |
8147 | #ifdef RLIMIT_DATA | 8091 | #ifdef RLIMIT_DATA |
8148 | { "data(kbytes)", RLIMIT_DATA, 1024 }, | 8092 | {"data(kbytes)", RLIMIT_DATA, 1024}, |
8149 | #endif | 8093 | #endif |
8150 | #ifdef RLIMIT_STACK | 8094 | #ifdef RLIMIT_STACK |
8151 | { "stack(kbytes)", RLIMIT_STACK, 1024 }, | 8095 | {"stack(kbytes)", RLIMIT_STACK, 1024}, |
8152 | #endif | 8096 | #endif |
8153 | #ifdef RLIMIT_CORE | 8097 | #ifdef RLIMIT_CORE |
8154 | { "coredump(blocks)", RLIMIT_CORE, 512 }, | 8098 | {"coredump(blocks)", RLIMIT_CORE, 512}, |
8155 | #endif | 8099 | #endif |
8156 | #ifdef RLIMIT_RSS | 8100 | #ifdef RLIMIT_RSS |
8157 | { "memory(kbytes)", RLIMIT_RSS, 1024 }, | 8101 | {"memory(kbytes)", RLIMIT_RSS, 1024}, |
8158 | #endif | 8102 | #endif |
8159 | #ifdef RLIMIT_MEMLOCK | 8103 | #ifdef RLIMIT_MEMLOCK |
8160 | { "locked memory(kbytes)", RLIMIT_MEMLOCK, 1024 }, | 8104 | {"locked memory(kbytes)", RLIMIT_MEMLOCK, 1024}, |
8161 | #endif | 8105 | #endif |
8162 | #ifdef RLIMIT_NPROC | 8106 | #ifdef RLIMIT_NPROC |
8163 | { "process(processes)", RLIMIT_NPROC, 1 }, | 8107 | {"process(processes)", RLIMIT_NPROC, 1}, |
8164 | #endif | 8108 | #endif |
8165 | #ifdef RLIMIT_NOFILE | 8109 | #ifdef RLIMIT_NOFILE |
8166 | { "nofiles(descriptors)", RLIMIT_NOFILE, 1 }, | 8110 | {"nofiles(descriptors)", RLIMIT_NOFILE, 1}, |
8167 | #endif | 8111 | #endif |
8168 | #ifdef RLIMIT_VMEM | 8112 | #ifdef RLIMIT_VMEM |
8169 | { "vmemory(kbytes)", RLIMIT_VMEM, 1024 }, | 8113 | {"vmemory(kbytes)", RLIMIT_VMEM, 1024}, |
8170 | #endif | 8114 | #endif |
8171 | #ifdef RLIMIT_SWAP | 8115 | #ifdef RLIMIT_SWAP |
8172 | { "swap(kbytes)", RLIMIT_SWAP, 1024 }, | 8116 | {"swap(kbytes)", RLIMIT_SWAP, 1024}, |
8173 | #endif | 8117 | #endif |
8174 | { NULL, 0, 0 } | 8118 | {NULL, 0, 0} |
8175 | }; | 8119 | }; |
8176 | 8120 | ||
8177 | static int | 8121 | static int ulimitcmd(int argc, char **argv) |
8178 | ulimitcmd(int argc, char **argv) | ||
8179 | { | 8122 | { |
8180 | static const char unlimited_string[] = "unlimited"; | 8123 | static const char unlimited_string[] = "unlimited"; |
8181 | int c; | 8124 | int c; |
8182 | rlim_t val = 0; | 8125 | rlim_t val = 0; |
8183 | enum { SOFT = 0x1, HARD = 0x2 } | 8126 | enum { SOFT = 0x1, HARD = 0x2 } how = SOFT | HARD; |
8184 | how = SOFT | HARD; | 8127 | const struct limits *l; |
8185 | const struct limits *l; | 8128 | int set, all = 0; |
8186 | int set, all = 0; | 8129 | int optc, what; |
8187 | int optc, what; | 8130 | struct rlimit limit; |
8188 | struct rlimit limit; | ||
8189 | 8131 | ||
8190 | what = 'f'; | 8132 | what = 'f'; |
8191 | 8133 | ||
8192 | while ((optc = nextopt("HSa" | 8134 | while ((optc = nextopt("HSa" |
8193 | #ifdef RLIMIT_CPU | 8135 | #ifdef RLIMIT_CPU |
8194 | "t" | 8136 | "t" |
8195 | #endif | 8137 | #endif |
8196 | #ifdef RLIMIT_FSIZE | 8138 | #ifdef RLIMIT_FSIZE |
8197 | "f" | 8139 | "f" |
8198 | #endif | 8140 | #endif |
8199 | #ifdef RLIMIT_DATA | 8141 | #ifdef RLIMIT_DATA |
8200 | "d" | 8142 | "d" |
8201 | #endif | 8143 | #endif |
8202 | #ifdef RLIMIT_STACK | 8144 | #ifdef RLIMIT_STACK |
8203 | "s" | 8145 | "s" |
8204 | #endif | 8146 | #endif |
8205 | #ifdef RLIMIT_CORE | 8147 | #ifdef RLIMIT_CORE |
8206 | "c" | 8148 | "c" |
8207 | #endif | 8149 | #endif |
8208 | #ifdef RLIMIT_RSS | 8150 | #ifdef RLIMIT_RSS |
8209 | "m" | 8151 | "m" |
8210 | #endif | 8152 | #endif |
8211 | #ifdef RLIMIT_MEMLOCK | 8153 | #ifdef RLIMIT_MEMLOCK |
8212 | "l" | 8154 | "l" |
8213 | #endif | 8155 | #endif |
8214 | #ifdef RLIMIT_NPROC | 8156 | #ifdef RLIMIT_NPROC |
8215 | "p" | 8157 | "p" |
8216 | #endif | 8158 | #endif |
8217 | #ifdef RLIMIT_NOFILE | 8159 | #ifdef RLIMIT_NOFILE |
8218 | "n" | 8160 | "n" |
8219 | #endif | 8161 | #endif |
8220 | #ifdef RLIMIT_VMEM | 8162 | #ifdef RLIMIT_VMEM |
8221 | "v" | 8163 | "v" |
8222 | #endif | 8164 | #endif |
8223 | #ifdef RLIMIT_SWAP | 8165 | #ifdef RLIMIT_SWAP |
8224 | "w" | 8166 | "w" |
8225 | #endif | 8167 | #endif |
8226 | )) != '\0') { | 8168 | )) != '\0') { |
8227 | if (optc == 'H') { | 8169 | if (optc == 'H') { |
8228 | how = HARD; | 8170 | how = HARD; |
8229 | } else if (optc == 'S') { | 8171 | } else if (optc == 'S') { |
@@ -8236,9 +8178,9 @@ ulimitcmd(int argc, char **argv) | |||
8236 | } | 8178 | } |
8237 | 8179 | ||
8238 | for (l = limits; l->name; l++) { | 8180 | for (l = limits; l->name; l++) { |
8239 | if(l->name[0] == what) | 8181 | if (l->name[0] == what) |
8240 | break; | 8182 | break; |
8241 | if(l->name[1]=='w' && what=='w') | 8183 | if (l->name[1] == 'w' && what == 'w') |
8242 | break; | 8184 | break; |
8243 | } | 8185 | } |
8244 | 8186 | ||
@@ -8253,9 +8195,8 @@ ulimitcmd(int argc, char **argv) | |||
8253 | else { | 8195 | else { |
8254 | val = (rlim_t) 0; | 8196 | val = (rlim_t) 0; |
8255 | 8197 | ||
8256 | while ((c = *p++) >= '0' && c <= '9') | 8198 | while ((c = *p++) >= '0' && c <= '9') { |
8257 | { | 8199 | val = (val * 10) + (long) (c - '0'); |
8258 | val = (val * 10) + (long)(c - '0'); | ||
8259 | if (val < (rlim_t) 0) | 8200 | if (val < (rlim_t) 0) |
8260 | break; | 8201 | break; |
8261 | } | 8202 | } |
@@ -8269,7 +8210,7 @@ ulimitcmd(int argc, char **argv) | |||
8269 | for (l = limits; l->name; l++) { | 8210 | for (l = limits; l->name; l++) { |
8270 | printf("%-20s ", l->name); | 8211 | printf("%-20s ", l->name); |
8271 | getrlimit(l->cmd, &limit); | 8212 | getrlimit(l->cmd, &limit); |
8272 | OUTPUT_LIMIT: | 8213 | OUTPUT_LIMIT: |
8273 | if (how & SOFT) | 8214 | if (how & SOFT) |
8274 | val = limit.rlim_cur; | 8215 | val = limit.rlim_cur; |
8275 | else if (how & HARD) | 8216 | else if (how & HARD) |
@@ -8277,8 +8218,7 @@ ulimitcmd(int argc, char **argv) | |||
8277 | 8218 | ||
8278 | if (val == RLIM_INFINITY) | 8219 | if (val == RLIM_INFINITY) |
8279 | puts(unlimited_string); | 8220 | puts(unlimited_string); |
8280 | else | 8221 | else { |
8281 | { | ||
8282 | val /= l->factor; | 8222 | val /= l->factor; |
8283 | printf("%lld\n", (long long) val); | 8223 | printf("%lld\n", (long long) val); |
8284 | } | 8224 | } |
@@ -8302,12 +8242,12 @@ ulimitcmd(int argc, char **argv) | |||
8302 | error("error setting limit (%m)"); | 8242 | error("error setting limit (%m)"); |
8303 | return 0; | 8243 | return 0; |
8304 | } | 8244 | } |
8245 | |||
8305 | /* | 8246 | /* |
8306 | * prefix -- see if pfx is a prefix of string. | 8247 | * prefix -- see if pfx is a prefix of string. |
8307 | */ | 8248 | */ |
8308 | 8249 | ||
8309 | static int | 8250 | static int prefix(char const *pfx, char const *string) |
8310 | prefix(char const *pfx, char const *string) | ||
8311 | { | 8251 | { |
8312 | while (*pfx) { | 8252 | while (*pfx) { |
8313 | if (*pfx++ != *string++) | 8253 | if (*pfx++ != *string++) |
@@ -8321,13 +8261,12 @@ prefix(char const *pfx, char const *string) | |||
8321 | * nagative is bad | 8261 | * nagative is bad |
8322 | */ | 8262 | */ |
8323 | 8263 | ||
8324 | static int | 8264 | static int is_number(const char *p, int *intptr) |
8325 | is_number(const char *p, int *intptr) | ||
8326 | { | 8265 | { |
8327 | int ret = 0; | 8266 | int ret = 0; |
8328 | 8267 | ||
8329 | do { | 8268 | do { |
8330 | if (! is_digit(*p)) | 8269 | if (!is_digit(*p)) |
8331 | return 0; | 8270 | return 0; |
8332 | ret *= 10; | 8271 | ret *= 10; |
8333 | ret += digit_val(*p); | 8272 | ret += digit_val(*p); |
@@ -8343,11 +8282,11 @@ is_number(const char *p, int *intptr) | |||
8343 | * failure. | 8282 | * failure. |
8344 | */ | 8283 | */ |
8345 | 8284 | ||
8346 | static int | 8285 | static int number(const char *s) |
8347 | number(const char *s) | ||
8348 | { | 8286 | { |
8349 | int i; | 8287 | int i; |
8350 | if (! is_number(s, &i)) | 8288 | |
8289 | if (!is_number(s, &i)) | ||
8351 | error("Illegal number: %s", s); | 8290 | error("Illegal number: %s", s); |
8352 | return i; | 8291 | return i; |
8353 | } | 8292 | } |
@@ -8357,8 +8296,7 @@ number(const char *s) | |||
8357 | * The return string is allocated on the stack. | 8296 | * The return string is allocated on the stack. |
8358 | */ | 8297 | */ |
8359 | 8298 | ||
8360 | static char * | 8299 | static char *single_quote(const char *s) |
8361 | single_quote(const char *s) | ||
8362 | { | 8300 | { |
8363 | char *p; | 8301 | char *p; |
8364 | 8302 | ||
@@ -8408,10 +8346,10 @@ single_quote(const char *s) | |||
8408 | * Like strdup but works with the ash stack. | 8346 | * Like strdup but works with the ash stack. |
8409 | */ | 8347 | */ |
8410 | 8348 | ||
8411 | static char * | 8349 | static char *sstrdup(const char *p) |
8412 | sstrdup(const char *p) | ||
8413 | { | 8350 | { |
8414 | size_t len = strlen(p) + 1; | 8351 | size_t len = strlen(p) + 1; |
8352 | |||
8415 | return memcpy(stalloc(len), p, len); | 8353 | return memcpy(stalloc(len), p, len); |
8416 | } | 8354 | } |
8417 | 8355 | ||
@@ -8421,9 +8359,9 @@ sstrdup(const char *p) | |||
8421 | */ | 8359 | */ |
8422 | 8360 | ||
8423 | 8361 | ||
8424 | static void sizenodelist (const struct nodelist *); | 8362 | static void sizenodelist(const struct nodelist *); |
8425 | static struct nodelist *copynodelist (const struct nodelist *); | 8363 | static struct nodelist *copynodelist(const struct nodelist *); |
8426 | static char *nodexstrdup (const char *); | 8364 | static char *nodexstrdup(const char *); |
8427 | 8365 | ||
8428 | #define CALCSIZE_TABLE | 8366 | #define CALCSIZE_TABLE |
8429 | #define COPYNODE_TABLE | 8367 | #define COPYNODE_TABLE |
@@ -8451,59 +8389,59 @@ static char *nodexstrdup (const char *); | |||
8451 | #define NODE_INTEGER 0x40 | 8389 | #define NODE_INTEGER 0x40 |
8452 | #define NODE_NODELIST 0x80 | 8390 | #define NODE_NODELIST 0x80 |
8453 | #define NODE_CHARPTR 0xC0 | 8391 | #define NODE_CHARPTR 0xC0 |
8454 | #define NODE_NOMORE 0x01 /* Note: no offset should be odd (aligned)*/ | 8392 | #define NODE_NOMORE 0x01 /* Note: no offset should be odd (aligned) */ |
8455 | #define NODE_MBRMASK 0xC0 | 8393 | #define NODE_MBRMASK 0xC0 |
8456 | #define NODE_OFFSETMASK 0x3E | 8394 | #define NODE_OFFSETMASK 0x3E |
8457 | 8395 | ||
8458 | static const unsigned char copynode_ops[35] = { | 8396 | static const unsigned char copynode_ops[35] = { |
8459 | #define COPYNODE_OPS0 0 | 8397 | #define COPYNODE_OPS0 0 |
8460 | offsetof(union node, nbinary.ch2), | 8398 | offsetof(union node, nbinary.ch2), |
8461 | offsetof(union node, nbinary.ch1)|NODE_NOMORE, | 8399 | offsetof(union node, nbinary.ch1) | NODE_NOMORE, |
8462 | #define COPYNODE_OPS1 (COPYNODE_OPS0 + 2) | 8400 | #define COPYNODE_OPS1 (COPYNODE_OPS0 + 2) |
8463 | offsetof(union node, ncmd.redirect), | 8401 | offsetof(union node, ncmd.redirect), |
8464 | offsetof(union node, ncmd.args), | 8402 | offsetof(union node, ncmd.args), |
8465 | offsetof(union node, ncmd.assign), | 8403 | offsetof(union node, ncmd.assign), |
8466 | offsetof(union node, ncmd.backgnd)|NODE_INTEGER|NODE_NOMORE, | 8404 | offsetof(union node, ncmd.backgnd) | NODE_INTEGER | NODE_NOMORE, |
8467 | #define COPYNODE_OPS2 (COPYNODE_OPS1 + 4) | 8405 | #define COPYNODE_OPS2 (COPYNODE_OPS1 + 4) |
8468 | offsetof(union node, npipe.cmdlist)|NODE_NODELIST, | 8406 | offsetof(union node, npipe.cmdlist) | NODE_NODELIST, |
8469 | offsetof(union node, npipe.backgnd)|NODE_INTEGER|NODE_NOMORE, | 8407 | offsetof(union node, npipe.backgnd) | NODE_INTEGER | NODE_NOMORE, |
8470 | #define COPYNODE_OPS3 (COPYNODE_OPS2 + 2) | 8408 | #define COPYNODE_OPS3 (COPYNODE_OPS2 + 2) |
8471 | offsetof(union node, nredir.redirect), | 8409 | offsetof(union node, nredir.redirect), |
8472 | offsetof(union node, nredir.n)|NODE_NOMORE, | 8410 | offsetof(union node, nredir.n) | NODE_NOMORE, |
8473 | #define COPYNODE_OPS4 (COPYNODE_OPS3 + 2) | 8411 | #define COPYNODE_OPS4 (COPYNODE_OPS3 + 2) |
8474 | offsetof(union node, nif.elsepart), | 8412 | offsetof(union node, nif.elsepart), |
8475 | offsetof(union node, nif.ifpart), | 8413 | offsetof(union node, nif.ifpart), |
8476 | offsetof(union node, nif.test)|NODE_NOMORE, | 8414 | offsetof(union node, nif.test) | NODE_NOMORE, |
8477 | #define COPYNODE_OPS5 (COPYNODE_OPS4 + 3) | 8415 | #define COPYNODE_OPS5 (COPYNODE_OPS4 + 3) |
8478 | offsetof(union node, nfor.var)|NODE_CHARPTR, | 8416 | offsetof(union node, nfor.var) | NODE_CHARPTR, |
8479 | offsetof(union node, nfor.body), | 8417 | offsetof(union node, nfor.body), |
8480 | offsetof(union node, nfor.args)|NODE_NOMORE, | 8418 | offsetof(union node, nfor.args) | NODE_NOMORE, |
8481 | #define COPYNODE_OPS6 (COPYNODE_OPS5 + 3) | 8419 | #define COPYNODE_OPS6 (COPYNODE_OPS5 + 3) |
8482 | offsetof(union node, ncase.cases), | 8420 | offsetof(union node, ncase.cases), |
8483 | offsetof(union node, ncase.expr)|NODE_NOMORE, | 8421 | offsetof(union node, ncase.expr) | NODE_NOMORE, |
8484 | #define COPYNODE_OPS7 (COPYNODE_OPS6 + 2) | 8422 | #define COPYNODE_OPS7 (COPYNODE_OPS6 + 2) |
8485 | offsetof(union node, nclist.body), | 8423 | offsetof(union node, nclist.body), |
8486 | offsetof(union node, nclist.pattern), | 8424 | offsetof(union node, nclist.pattern), |
8487 | offsetof(union node, nclist.next)|NODE_NOMORE, | 8425 | offsetof(union node, nclist.next) | NODE_NOMORE, |
8488 | #define COPYNODE_OPS8 (COPYNODE_OPS7 + 3) | 8426 | #define COPYNODE_OPS8 (COPYNODE_OPS7 + 3) |
8489 | offsetof(union node, narg.backquote)|NODE_NODELIST, | 8427 | offsetof(union node, narg.backquote) | NODE_NODELIST, |
8490 | offsetof(union node, narg.text)|NODE_CHARPTR, | 8428 | offsetof(union node, narg.text) | NODE_CHARPTR, |
8491 | offsetof(union node, narg.next)|NODE_NOMORE, | 8429 | offsetof(union node, narg.next) | NODE_NOMORE, |
8492 | #define COPYNODE_OPS9 (COPYNODE_OPS8 + 3) | 8430 | #define COPYNODE_OPS9 (COPYNODE_OPS8 + 3) |
8493 | offsetof(union node, nfile.fname), | 8431 | offsetof(union node, nfile.fname), |
8494 | offsetof(union node, nfile.fd)|NODE_INTEGER, | 8432 | offsetof(union node, nfile.fd) | NODE_INTEGER, |
8495 | offsetof(union node, nfile.next)|NODE_NOMORE, | 8433 | offsetof(union node, nfile.next) | NODE_NOMORE, |
8496 | #define COPYNODE_OPS10 (COPYNODE_OPS9 + 3) | 8434 | #define COPYNODE_OPS10 (COPYNODE_OPS9 + 3) |
8497 | offsetof(union node, ndup.vname), | 8435 | offsetof(union node, ndup.vname), |
8498 | offsetof(union node, ndup.dupfd)|NODE_INTEGER, | 8436 | offsetof(union node, ndup.dupfd) | NODE_INTEGER, |
8499 | offsetof(union node, ndup.fd)|NODE_INTEGER, | 8437 | offsetof(union node, ndup.fd) | NODE_INTEGER, |
8500 | offsetof(union node, ndup.next)|NODE_NOMORE, | 8438 | offsetof(union node, ndup.next) | NODE_NOMORE, |
8501 | #define COPYNODE_OPS11 (COPYNODE_OPS10 + 4) | 8439 | #define COPYNODE_OPS11 (COPYNODE_OPS10 + 4) |
8502 | offsetof(union node, nhere.doc), | 8440 | offsetof(union node, nhere.doc), |
8503 | offsetof(union node, nhere.fd)|NODE_INTEGER, | 8441 | offsetof(union node, nhere.fd) | NODE_INTEGER, |
8504 | offsetof(union node, nhere.next)|NODE_NOMORE, | 8442 | offsetof(union node, nhere.next) | NODE_NOMORE, |
8505 | #define COPYNODE_OPS12 (COPYNODE_OPS11 + 3) | 8443 | #define COPYNODE_OPS12 (COPYNODE_OPS11 + 3) |
8506 | offsetof(union node, nnot.com)|NODE_NOMORE, | 8444 | offsetof(union node, nnot.com) | NODE_NOMORE, |
8507 | }; | 8445 | }; |
8508 | 8446 | ||
8509 | #if COPYNODE_OPS12 != 34 | 8447 | #if COPYNODE_OPS12 != 34 |
@@ -8511,266 +8449,261 @@ static const unsigned char copynode_ops[35] = { | |||
8511 | #endif | 8449 | #endif |
8512 | 8450 | ||
8513 | static const unsigned char copynode_ops_index[26] = { | 8451 | static const unsigned char copynode_ops_index[26] = { |
8514 | COPYNODE_OPS0, /* NSEMI */ | 8452 | COPYNODE_OPS0, /* NSEMI */ |
8515 | COPYNODE_OPS1, /* NCMD */ | 8453 | COPYNODE_OPS1, /* NCMD */ |
8516 | COPYNODE_OPS2, /* NPIPE */ | 8454 | COPYNODE_OPS2, /* NPIPE */ |
8517 | COPYNODE_OPS3, /* NREDIR */ | 8455 | COPYNODE_OPS3, /* NREDIR */ |
8518 | COPYNODE_OPS3, /* NBACKGND */ | 8456 | COPYNODE_OPS3, /* NBACKGND */ |
8519 | COPYNODE_OPS3, /* NSUBSHELL */ | 8457 | COPYNODE_OPS3, /* NSUBSHELL */ |
8520 | COPYNODE_OPS0, /* NAND */ | 8458 | COPYNODE_OPS0, /* NAND */ |
8521 | COPYNODE_OPS0, /* NOR */ | 8459 | COPYNODE_OPS0, /* NOR */ |
8522 | COPYNODE_OPS4, /* NIF */ | 8460 | COPYNODE_OPS4, /* NIF */ |
8523 | COPYNODE_OPS0, /* NWHILE */ | 8461 | COPYNODE_OPS0, /* NWHILE */ |
8524 | COPYNODE_OPS0, /* NUNTIL */ | 8462 | COPYNODE_OPS0, /* NUNTIL */ |
8525 | COPYNODE_OPS5, /* NFOR */ | 8463 | COPYNODE_OPS5, /* NFOR */ |
8526 | COPYNODE_OPS6, /* NCASE */ | 8464 | COPYNODE_OPS6, /* NCASE */ |
8527 | COPYNODE_OPS7, /* NCLIST */ | 8465 | COPYNODE_OPS7, /* NCLIST */ |
8528 | COPYNODE_OPS8, /* NDEFUN */ | 8466 | COPYNODE_OPS8, /* NDEFUN */ |
8529 | COPYNODE_OPS8, /* NARG */ | 8467 | COPYNODE_OPS8, /* NARG */ |
8530 | COPYNODE_OPS9, /* NTO */ | 8468 | COPYNODE_OPS9, /* NTO */ |
8531 | COPYNODE_OPS9, /* NFROM */ | 8469 | COPYNODE_OPS9, /* NFROM */ |
8532 | COPYNODE_OPS9, /* NFROMTO */ | 8470 | COPYNODE_OPS9, /* NFROMTO */ |
8533 | COPYNODE_OPS9, /* NAPPEND */ | 8471 | COPYNODE_OPS9, /* NAPPEND */ |
8534 | COPYNODE_OPS9, /* NTOOV */ | 8472 | COPYNODE_OPS9, /* NTOOV */ |
8535 | COPYNODE_OPS10, /* NTOFD */ | 8473 | COPYNODE_OPS10, /* NTOFD */ |
8536 | COPYNODE_OPS10, /* NFROMFD */ | 8474 | COPYNODE_OPS10, /* NFROMFD */ |
8537 | COPYNODE_OPS11, /* NHERE */ | 8475 | COPYNODE_OPS11, /* NHERE */ |
8538 | COPYNODE_OPS11, /* NXHERE */ | 8476 | COPYNODE_OPS11, /* NXHERE */ |
8539 | COPYNODE_OPS12, /* NNOT */ | 8477 | COPYNODE_OPS12, /* NNOT */ |
8540 | }; | 8478 | }; |
8541 | 8479 | ||
8542 | #if NODE_CHARPTR != NODE_MBRMASK | 8480 | #if NODE_CHARPTR != NODE_MBRMASK |
8543 | #error NODE_CHARPTR != NODE_MBRMASK!!! | 8481 | #error NODE_CHARPTR != NODE_MBRMASK!!! |
8544 | #endif | 8482 | #endif |
8545 | #endif /* defined(CALCSIZE_TABLE) || defined(COPYNODE_TABLE) */ | 8483 | #endif /* defined(CALCSIZE_TABLE) || defined(COPYNODE_TABLE) */ |
8546 | 8484 | ||
8547 | #ifdef COPYNODE_TABLE | 8485 | #ifdef COPYNODE_TABLE |
8548 | static union node * | 8486 | static union node *copynode(const union node *n) |
8549 | copynode(const union node *n) | 8487 | { |
8550 | { | 8488 | union node *new; |
8551 | union node *new; | 8489 | const unsigned char *p; |
8552 | const unsigned char *p; | 8490 | |
8553 | 8491 | if (n == NULL) { | |
8554 | if (n == NULL) { | 8492 | return NULL; |
8555 | return NULL; | 8493 | } |
8556 | } | 8494 | new = funcblock; |
8557 | new = funcblock; | 8495 | new->type = n->type; |
8558 | new->type = n->type; | 8496 | funcblock = (char *) funcblock + (int) nodesize[n->type]; |
8559 | funcblock = (char *) funcblock + (int) nodesize[n->type]; | 8497 | p = copynode_ops + (int) copynode_ops_index[n->type]; |
8560 | p = copynode_ops + (int) copynode_ops_index[n->type]; | 8498 | do { |
8561 | do { | 8499 | char *nn = ((char *) new) + ((int) (*p & NODE_OFFSETMASK)); |
8562 | char *nn = ((char *) new) + ((int)(*p & NODE_OFFSETMASK)); | 8500 | const char *no = ((const char *) n) + ((int) (*p & NODE_OFFSETMASK)); |
8563 | const char *no = ((const char *) n) + ((int)(*p & NODE_OFFSETMASK)); | 8501 | |
8564 | 8502 | if (!(*p & NODE_MBRMASK)) { /* standard node */ | |
8565 | if (!(*p & NODE_MBRMASK)) { /* standard node */ | 8503 | *((union node **) nn) = copynode(*((const union node **) no)); |
8566 | *((union node **)nn) = copynode(*((const union node **) no)); | 8504 | } else if ((*p & NODE_MBRMASK) == NODE_CHARPTR) { /* string */ |
8567 | } else if ((*p & NODE_MBRMASK) == NODE_CHARPTR) { /* string */ | 8505 | *((const char **) nn) = nodexstrdup(*((const char **) no)); |
8568 | *((const char **)nn) = nodexstrdup(*((const char **)no)); | 8506 | } else if (*p & NODE_NODELIST) { /* nodelist */ |
8569 | } else if (*p & NODE_NODELIST) { /* nodelist */ | 8507 | *((struct nodelist **) nn) |
8570 | *((struct nodelist **)nn) | 8508 | = copynodelist(*((const struct nodelist **) no)); |
8571 | = copynodelist(*((const struct nodelist **) no)); | 8509 | } else { /* integer */ |
8572 | } else { /* integer */ | 8510 | *((int *) nn) = *((int *) no); |
8573 | *((int *) nn) = *((int *) no); | 8511 | } |
8574 | } | 8512 | } while (!(*p++ & NODE_NOMORE)); |
8575 | } while (!(*p++ & NODE_NOMORE)); | 8513 | return new; |
8576 | return new; | 8514 | } |
8577 | } | 8515 | #else /* COPYNODE_TABLE */ |
8578 | #else /* COPYNODE_TABLE */ | 8516 | static union node *copynode(const union node *n) |
8579 | static union node * | 8517 | { |
8580 | copynode(const union node *n) | 8518 | union node *new; |
8581 | { | 8519 | |
8582 | union node *new; | 8520 | if (n == NULL) |
8583 | 8521 | return NULL; | |
8584 | if (n == NULL) | 8522 | new = funcblock; |
8585 | return NULL; | 8523 | funcblock = (char *) funcblock + nodesize[n->type]; |
8586 | new = funcblock; | 8524 | switch (n->type) { |
8587 | funcblock = (char *) funcblock + nodesize[n->type]; | 8525 | case NSEMI: |
8588 | switch (n->type) { | 8526 | case NAND: |
8589 | case NSEMI: | 8527 | case NOR: |
8590 | case NAND: | 8528 | case NWHILE: |
8591 | case NOR: | 8529 | case NUNTIL: |
8592 | case NWHILE: | 8530 | new->nbinary.ch2 = copynode(n->nbinary.ch2); |
8593 | case NUNTIL: | 8531 | new->nbinary.ch1 = copynode(n->nbinary.ch1); |
8594 | new->nbinary.ch2 = copynode(n->nbinary.ch2); | 8532 | break; |
8595 | new->nbinary.ch1 = copynode(n->nbinary.ch1); | 8533 | case NCMD: |
8596 | break; | 8534 | new->ncmd.redirect = copynode(n->ncmd.redirect); |
8597 | case NCMD: | 8535 | new->ncmd.args = copynode(n->ncmd.args); |
8598 | new->ncmd.redirect = copynode(n->ncmd.redirect); | 8536 | new->ncmd.assign = copynode(n->ncmd.assign); |
8599 | new->ncmd.args = copynode(n->ncmd.args); | 8537 | new->ncmd.backgnd = n->ncmd.backgnd; |
8600 | new->ncmd.assign = copynode(n->ncmd.assign); | 8538 | break; |
8601 | new->ncmd.backgnd = n->ncmd.backgnd; | 8539 | case NPIPE: |
8602 | break; | 8540 | new->npipe.cmdlist = copynodelist(n->npipe.cmdlist); |
8603 | case NPIPE: | 8541 | new->npipe.backgnd = n->npipe.backgnd; |
8604 | new->npipe.cmdlist = copynodelist(n->npipe.cmdlist); | 8542 | break; |
8605 | new->npipe.backgnd = n->npipe.backgnd; | 8543 | case NREDIR: |
8606 | break; | 8544 | case NBACKGND: |
8607 | case NREDIR: | 8545 | case NSUBSHELL: |
8608 | case NBACKGND: | 8546 | new->nredir.redirect = copynode(n->nredir.redirect); |
8609 | case NSUBSHELL: | 8547 | new->nredir.n = copynode(n->nredir.n); |
8610 | new->nredir.redirect = copynode(n->nredir.redirect); | 8548 | break; |
8611 | new->nredir.n = copynode(n->nredir.n); | 8549 | case NIF: |
8612 | break; | 8550 | new->nif.elsepart = copynode(n->nif.elsepart); |
8613 | case NIF: | 8551 | new->nif.ifpart = copynode(n->nif.ifpart); |
8614 | new->nif.elsepart = copynode(n->nif.elsepart); | 8552 | new->nif.test = copynode(n->nif.test); |
8615 | new->nif.ifpart = copynode(n->nif.ifpart); | 8553 | break; |
8616 | new->nif.test = copynode(n->nif.test); | 8554 | case NFOR: |
8617 | break; | 8555 | new->nfor.var = nodexstrdup(n->nfor.var); |
8618 | case NFOR: | 8556 | new->nfor.body = copynode(n->nfor.body); |
8619 | new->nfor.var = nodexstrdup(n->nfor.var); | 8557 | new->nfor.args = copynode(n->nfor.args); |
8620 | new->nfor.body = copynode(n->nfor.body); | 8558 | break; |
8621 | new->nfor.args = copynode(n->nfor.args); | 8559 | case NCASE: |
8622 | break; | 8560 | new->ncase.cases = copynode(n->ncase.cases); |
8623 | case NCASE: | 8561 | new->ncase.expr = copynode(n->ncase.expr); |
8624 | new->ncase.cases = copynode(n->ncase.cases); | 8562 | break; |
8625 | new->ncase.expr = copynode(n->ncase.expr); | 8563 | case NCLIST: |
8626 | break; | 8564 | new->nclist.body = copynode(n->nclist.body); |
8627 | case NCLIST: | 8565 | new->nclist.pattern = copynode(n->nclist.pattern); |
8628 | new->nclist.body = copynode(n->nclist.body); | 8566 | new->nclist.next = copynode(n->nclist.next); |
8629 | new->nclist.pattern = copynode(n->nclist.pattern); | 8567 | break; |
8630 | new->nclist.next = copynode(n->nclist.next); | 8568 | case NDEFUN: |
8631 | break; | 8569 | case NARG: |
8632 | case NDEFUN: | 8570 | new->narg.backquote = copynodelist(n->narg.backquote); |
8633 | case NARG: | 8571 | new->narg.text = nodexstrdup(n->narg.text); |
8634 | new->narg.backquote = copynodelist(n->narg.backquote); | 8572 | new->narg.next = copynode(n->narg.next); |
8635 | new->narg.text = nodexstrdup(n->narg.text); | 8573 | break; |
8636 | new->narg.next = copynode(n->narg.next); | 8574 | case NTO: |
8637 | break; | 8575 | case NFROM: |
8638 | case NTO: | 8576 | case NFROMTO: |
8639 | case NFROM: | 8577 | case NAPPEND: |
8640 | case NFROMTO: | 8578 | case NTOOV: |
8641 | case NAPPEND: | 8579 | new->nfile.fname = copynode(n->nfile.fname); |
8642 | case NTOOV: | 8580 | new->nfile.fd = n->nfile.fd; |
8643 | new->nfile.fname = copynode(n->nfile.fname); | 8581 | new->nfile.next = copynode(n->nfile.next); |
8644 | new->nfile.fd = n->nfile.fd; | 8582 | break; |
8645 | new->nfile.next = copynode(n->nfile.next); | 8583 | case NTOFD: |
8646 | break; | 8584 | case NFROMFD: |
8647 | case NTOFD: | 8585 | new->ndup.vname = copynode(n->ndup.vname); |
8648 | case NFROMFD: | 8586 | new->ndup.dupfd = n->ndup.dupfd; |
8649 | new->ndup.vname = copynode(n->ndup.vname); | 8587 | new->ndup.fd = n->ndup.fd; |
8650 | new->ndup.dupfd = n->ndup.dupfd; | 8588 | new->ndup.next = copynode(n->ndup.next); |
8651 | new->ndup.fd = n->ndup.fd; | 8589 | break; |
8652 | new->ndup.next = copynode(n->ndup.next); | 8590 | case NHERE: |
8653 | break; | 8591 | case NXHERE: |
8654 | case NHERE: | 8592 | new->nhere.doc = copynode(n->nhere.doc); |
8655 | case NXHERE: | 8593 | new->nhere.fd = n->nhere.fd; |
8656 | new->nhere.doc = copynode(n->nhere.doc); | 8594 | new->nhere.next = copynode(n->nhere.next); |
8657 | new->nhere.fd = n->nhere.fd; | 8595 | break; |
8658 | new->nhere.next = copynode(n->nhere.next); | 8596 | case NNOT: |
8659 | break; | 8597 | new->nnot.com = copynode(n->nnot.com); |
8660 | case NNOT: | 8598 | break; |
8661 | new->nnot.com = copynode(n->nnot.com); | 8599 | }; |
8662 | break; | 8600 | new->type = n->type; |
8663 | }; | 8601 | return new; |
8664 | new->type = n->type; | 8602 | } |
8665 | return new; | 8603 | #endif /* COPYNODE_TABLE */ |
8666 | } | ||
8667 | #endif /* COPYNODE_TABLE */ | ||
8668 | 8604 | ||
8669 | #ifdef CALCSIZE_TABLE | 8605 | #ifdef CALCSIZE_TABLE |
8670 | static void | 8606 | static void calcsize(const union node *n) |
8671 | calcsize(const union node *n) | ||
8672 | { | 8607 | { |
8673 | const unsigned char *p; | 8608 | const unsigned char *p; |
8674 | 8609 | ||
8675 | if (n == NULL) | 8610 | if (n == NULL) |
8676 | return; | 8611 | return; |
8677 | funcblocksize += (int) nodesize[n->type]; | 8612 | funcblocksize += (int) nodesize[n->type]; |
8678 | 8613 | ||
8679 | p = copynode_ops + (int) copynode_ops_index[n->type]; | 8614 | p = copynode_ops + (int) copynode_ops_index[n->type]; |
8680 | do { | 8615 | do { |
8681 | const char *no = ((const char *) n) + ((int)(*p & NODE_OFFSETMASK)); | 8616 | const char *no = ((const char *) n) + ((int) (*p & NODE_OFFSETMASK)); |
8682 | 8617 | ||
8683 | if (!(*p & NODE_MBRMASK)) { /* standard node */ | 8618 | if (!(*p & NODE_MBRMASK)) { /* standard node */ |
8684 | calcsize(*((const union node **) no)); | 8619 | calcsize(*((const union node **) no)); |
8685 | } else if ((*p & NODE_MBRMASK) == NODE_CHARPTR) { /* string */ | 8620 | } else if ((*p & NODE_MBRMASK) == NODE_CHARPTR) { /* string */ |
8686 | funcstringsize += strlen(*((const char **)no)) + 1; | 8621 | funcstringsize += strlen(*((const char **) no)) + 1; |
8687 | } else if (*p & NODE_NODELIST) { /* nodelist */ | 8622 | } else if (*p & NODE_NODELIST) { /* nodelist */ |
8688 | sizenodelist(*((const struct nodelist **) no)); | 8623 | sizenodelist(*((const struct nodelist **) no)); |
8689 | } /* else integer -- ignore */ | 8624 | } /* else integer -- ignore */ |
8690 | } while (!(*p++ & NODE_NOMORE)); | 8625 | } while (!(*p++ & NODE_NOMORE)); |
8691 | } | 8626 | } |
8692 | #else /* CALCSIZE_TABLE */ | 8627 | #else /* CALCSIZE_TABLE */ |
8693 | static void | 8628 | static void calcsize(const union node *n) |
8694 | calcsize(const union node *n) | 8629 | { |
8695 | { | 8630 | if (n == NULL) |
8696 | if (n == NULL) | 8631 | return; |
8697 | return; | 8632 | funcblocksize += nodesize[n->type]; |
8698 | funcblocksize += nodesize[n->type]; | 8633 | switch (n->type) { |
8699 | switch (n->type) { | 8634 | case NSEMI: |
8700 | case NSEMI: | 8635 | case NAND: |
8701 | case NAND: | 8636 | case NOR: |
8702 | case NOR: | 8637 | case NWHILE: |
8703 | case NWHILE: | 8638 | case NUNTIL: |
8704 | case NUNTIL: | 8639 | calcsize(n->nbinary.ch2); |
8705 | calcsize(n->nbinary.ch2); | 8640 | calcsize(n->nbinary.ch1); |
8706 | calcsize(n->nbinary.ch1); | 8641 | break; |
8707 | break; | 8642 | case NCMD: |
8708 | case NCMD: | 8643 | calcsize(n->ncmd.redirect); |
8709 | calcsize(n->ncmd.redirect); | 8644 | calcsize(n->ncmd.args); |
8710 | calcsize(n->ncmd.args); | 8645 | calcsize(n->ncmd.assign); |
8711 | calcsize(n->ncmd.assign); | 8646 | break; |
8712 | break; | 8647 | case NPIPE: |
8713 | case NPIPE: | 8648 | sizenodelist(n->npipe.cmdlist); |
8714 | sizenodelist(n->npipe.cmdlist); | 8649 | break; |
8715 | break; | 8650 | case NREDIR: |
8716 | case NREDIR: | 8651 | case NBACKGND: |
8717 | case NBACKGND: | 8652 | case NSUBSHELL: |
8718 | case NSUBSHELL: | 8653 | calcsize(n->nredir.redirect); |
8719 | calcsize(n->nredir.redirect); | 8654 | calcsize(n->nredir.n); |
8720 | calcsize(n->nredir.n); | 8655 | break; |
8721 | break; | 8656 | case NIF: |
8722 | case NIF: | 8657 | calcsize(n->nif.elsepart); |
8723 | calcsize(n->nif.elsepart); | 8658 | calcsize(n->nif.ifpart); |
8724 | calcsize(n->nif.ifpart); | 8659 | calcsize(n->nif.test); |
8725 | calcsize(n->nif.test); | 8660 | break; |
8726 | break; | 8661 | case NFOR: |
8727 | case NFOR: | 8662 | funcstringsize += strlen(n->nfor.var) + 1; |
8728 | funcstringsize += strlen(n->nfor.var) + 1; | 8663 | calcsize(n->nfor.body); |
8729 | calcsize(n->nfor.body); | 8664 | calcsize(n->nfor.args); |
8730 | calcsize(n->nfor.args); | 8665 | break; |
8731 | break; | 8666 | case NCASE: |
8732 | case NCASE: | 8667 | calcsize(n->ncase.cases); |
8733 | calcsize(n->ncase.cases); | 8668 | calcsize(n->ncase.expr); |
8734 | calcsize(n->ncase.expr); | 8669 | break; |
8735 | break; | 8670 | case NCLIST: |
8736 | case NCLIST: | 8671 | calcsize(n->nclist.body); |
8737 | calcsize(n->nclist.body); | 8672 | calcsize(n->nclist.pattern); |
8738 | calcsize(n->nclist.pattern); | 8673 | calcsize(n->nclist.next); |
8739 | calcsize(n->nclist.next); | 8674 | break; |
8740 | break; | 8675 | case NDEFUN: |
8741 | case NDEFUN: | 8676 | case NARG: |
8742 | case NARG: | 8677 | sizenodelist(n->narg.backquote); |
8743 | sizenodelist(n->narg.backquote); | 8678 | funcstringsize += strlen(n->narg.text) + 1; |
8744 | funcstringsize += strlen(n->narg.text) + 1; | 8679 | calcsize(n->narg.next); |
8745 | calcsize(n->narg.next); | 8680 | break; |
8746 | break; | 8681 | case NTO: |
8747 | case NTO: | 8682 | case NFROM: |
8748 | case NFROM: | 8683 | case NFROMTO: |
8749 | case NFROMTO: | 8684 | case NAPPEND: |
8750 | case NAPPEND: | 8685 | case NTOOV: |
8751 | case NTOOV: | 8686 | calcsize(n->nfile.fname); |
8752 | calcsize(n->nfile.fname); | 8687 | calcsize(n->nfile.next); |
8753 | calcsize(n->nfile.next); | 8688 | break; |
8754 | break; | 8689 | case NTOFD: |
8755 | case NTOFD: | 8690 | case NFROMFD: |
8756 | case NFROMFD: | 8691 | calcsize(n->ndup.vname); |
8757 | calcsize(n->ndup.vname); | 8692 | calcsize(n->ndup.next); |
8758 | calcsize(n->ndup.next); | 8693 | break; |
8759 | break; | 8694 | case NHERE: |
8760 | case NHERE: | 8695 | case NXHERE: |
8761 | case NXHERE: | 8696 | calcsize(n->nhere.doc); |
8762 | calcsize(n->nhere.doc); | 8697 | calcsize(n->nhere.next); |
8763 | calcsize(n->nhere.next); | 8698 | break; |
8764 | break; | 8699 | case NNOT: |
8765 | case NNOT: | 8700 | calcsize(n->nnot.com); |
8766 | calcsize(n->nnot.com); | 8701 | break; |
8767 | break; | 8702 | }; |
8768 | }; | 8703 | } |
8769 | } | 8704 | #endif /* CALCSIZE_TABLE */ |
8770 | #endif /* CALCSIZE_TABLE */ | ||
8771 | 8705 | ||
8772 | static void | 8706 | static void sizenodelist(const struct nodelist *lp) |
8773 | sizenodelist(const struct nodelist *lp) | ||
8774 | { | 8707 | { |
8775 | while (lp) { | 8708 | while (lp) { |
8776 | funcblocksize += ALIGN(sizeof(struct nodelist)); | 8709 | funcblocksize += ALIGN(sizeof(struct nodelist)); |
@@ -8780,8 +8713,7 @@ sizenodelist(const struct nodelist *lp) | |||
8780 | } | 8713 | } |
8781 | 8714 | ||
8782 | 8715 | ||
8783 | static struct nodelist * | 8716 | static struct nodelist *copynodelist(const struct nodelist *lp) |
8784 | copynodelist(const struct nodelist *lp) | ||
8785 | { | 8717 | { |
8786 | struct nodelist *start; | 8718 | struct nodelist *start; |
8787 | struct nodelist **lpp; | 8719 | struct nodelist **lpp; |
@@ -8799,12 +8731,11 @@ copynodelist(const struct nodelist *lp) | |||
8799 | } | 8731 | } |
8800 | 8732 | ||
8801 | 8733 | ||
8802 | static char * | 8734 | static char *nodexstrdup(const char *s) |
8803 | nodexstrdup(const char *s) | ||
8804 | { | 8735 | { |
8805 | const char *p = s; | 8736 | const char *p = s; |
8806 | char *q = funcstring; | 8737 | char *q = funcstring; |
8807 | char *rtn = funcstring; | 8738 | char *rtn = funcstring; |
8808 | 8739 | ||
8809 | while ((*q++ = *p++) != '\0') | 8740 | while ((*q++ = *p++) != '\0') |
8810 | continue; | 8741 | continue; |
@@ -8813,15 +8744,14 @@ nodexstrdup(const char *s) | |||
8813 | } | 8744 | } |
8814 | 8745 | ||
8815 | #ifdef CONFIG_ASH_GETOPTS | 8746 | #ifdef CONFIG_ASH_GETOPTS |
8816 | static int getopts (char *, char *, char **, int *, int *); | 8747 | static int getopts(char *, char *, char **, int *, int *); |
8817 | #endif | 8748 | #endif |
8818 | 8749 | ||
8819 | /* | 8750 | /* |
8820 | * Process the shell command line arguments. | 8751 | * Process the shell command line arguments. |
8821 | */ | 8752 | */ |
8822 | 8753 | ||
8823 | static void | 8754 | static void procargs(int argc, char **argv) |
8824 | procargs(int argc, char **argv) | ||
8825 | { | 8755 | { |
8826 | int i; | 8756 | int i; |
8827 | 8757 | ||
@@ -8869,8 +8799,7 @@ procargs(int argc, char **argv) | |||
8869 | * to the argument list; we advance it past the options. | 8799 | * to the argument list; we advance it past the options. |
8870 | */ | 8800 | */ |
8871 | 8801 | ||
8872 | static inline void | 8802 | static inline void minus_o(const char *name, int val) |
8873 | minus_o(const char *name, int val) | ||
8874 | { | 8803 | { |
8875 | int i; | 8804 | int i; |
8876 | 8805 | ||
@@ -8878,7 +8807,7 @@ minus_o(const char *name, int val) | |||
8878 | out1str("Current option settings\n"); | 8807 | out1str("Current option settings\n"); |
8879 | for (i = 0; i < NOPTS; i++) | 8808 | for (i = 0; i < NOPTS; i++) |
8880 | printf("%-16s%s\n", optent_name(optlist[i]), | 8809 | printf("%-16s%s\n", optent_name(optlist[i]), |
8881 | optent_val(i) ? "on" : "off"); | 8810 | optent_val(i) ? "on" : "off"); |
8882 | } else { | 8811 | } else { |
8883 | for (i = 0; i < NOPTS; i++) | 8812 | for (i = 0; i < NOPTS; i++) |
8884 | if (equal(name, optent_name(optlist[i]))) { | 8813 | if (equal(name, optent_name(optlist[i]))) { |
@@ -8890,8 +8819,7 @@ minus_o(const char *name, int val) | |||
8890 | } | 8819 | } |
8891 | 8820 | ||
8892 | 8821 | ||
8893 | static void | 8822 | static void options(int cmdline) |
8894 | options(int cmdline) | ||
8895 | { | 8823 | { |
8896 | char *p; | 8824 | char *p; |
8897 | int val; | 8825 | int val; |
@@ -8912,7 +8840,7 @@ options(int cmdline) | |||
8912 | else if (*argptr == NULL) | 8840 | else if (*argptr == NULL) |
8913 | setparam(argptr); | 8841 | setparam(argptr); |
8914 | } | 8842 | } |
8915 | break; /* "-" or "--" terminates options */ | 8843 | break; /* "-" or "--" terminates options */ |
8916 | } | 8844 | } |
8917 | } else if (c == '+') { | 8845 | } else if (c == '+') { |
8918 | val = 0; | 8846 | val = 0; |
@@ -8923,7 +8851,8 @@ options(int cmdline) | |||
8923 | while ((c = *p++) != '\0') { | 8851 | while ((c = *p++) != '\0') { |
8924 | if (c == 'c' && cmdline) { | 8852 | if (c == 'c' && cmdline) { |
8925 | char *q; | 8853 | char *q; |
8926 | #ifdef NOHACK /* removing this code allows sh -ce 'foo' for compat */ | 8854 | |
8855 | #ifdef NOHACK /* removing this code allows sh -ce 'foo' for compat */ | ||
8927 | if (*p == '\0') | 8856 | if (*p == '\0') |
8928 | #endif | 8857 | #endif |
8929 | q = *argptr++; | 8858 | q = *argptr++; |
@@ -8937,8 +8866,8 @@ options(int cmdline) | |||
8937 | minus_o(*argptr, val); | 8866 | minus_o(*argptr, val); |
8938 | if (*argptr) | 8867 | if (*argptr) |
8939 | argptr++; | 8868 | argptr++; |
8940 | } else if (cmdline && (c == '-')) { // long options | 8869 | } else if (cmdline && (c == '-')) { /* long options */ |
8941 | if ( strcmp ( p, "login" ) == 0 ) | 8870 | if (strcmp(p, "login") == 0) |
8942 | isloginsh = 1; | 8871 | isloginsh = 1; |
8943 | break; | 8872 | break; |
8944 | } else { | 8873 | } else { |
@@ -8949,8 +8878,7 @@ options(int cmdline) | |||
8949 | } | 8878 | } |
8950 | 8879 | ||
8951 | 8880 | ||
8952 | static void | 8881 | static void setoption(int flag, int val) |
8953 | setoption(int flag, int val) | ||
8954 | { | 8882 | { |
8955 | int i; | 8883 | int i; |
8956 | 8884 | ||
@@ -8976,14 +8904,13 @@ setoption(int flag, int val) | |||
8976 | * Set the shell parameters. | 8904 | * Set the shell parameters. |
8977 | */ | 8905 | */ |
8978 | 8906 | ||
8979 | static void | 8907 | static void setparam(char **argv) |
8980 | setparam(char **argv) | ||
8981 | { | 8908 | { |
8982 | char **newparam; | 8909 | char **newparam; |
8983 | char **ap; | 8910 | char **ap; |
8984 | int nparam; | 8911 | int nparam; |
8985 | 8912 | ||
8986 | for (nparam = 0 ; argv[nparam] ; nparam++); | 8913 | for (nparam = 0; argv[nparam]; nparam++); |
8987 | ap = newparam = xmalloc((nparam + 1) * sizeof *ap); | 8914 | ap = newparam = xmalloc((nparam + 1) * sizeof *ap); |
8988 | while (*argv) { | 8915 | while (*argv) { |
8989 | *ap++ = xstrdup(*argv++); | 8916 | *ap++ = xstrdup(*argv++); |
@@ -9002,13 +8929,12 @@ setparam(char **argv) | |||
9002 | * Free the list of positional parameters. | 8929 | * Free the list of positional parameters. |
9003 | */ | 8930 | */ |
9004 | 8931 | ||
9005 | static void | 8932 | static void freeparam(volatile struct shparam *param) |
9006 | freeparam(volatile struct shparam *param) | ||
9007 | { | 8933 | { |
9008 | char **ap; | 8934 | char **ap; |
9009 | 8935 | ||
9010 | if (param->malloc) { | 8936 | if (param->malloc) { |
9011 | for (ap = param->p ; *ap ; ap++) | 8937 | for (ap = param->p; *ap; ap++) |
9012 | free(*ap); | 8938 | free(*ap); |
9013 | free(param->p); | 8939 | free(param->p); |
9014 | } | 8940 | } |
@@ -9020,8 +8946,7 @@ freeparam(volatile struct shparam *param) | |||
9020 | * The shift builtin command. | 8946 | * The shift builtin command. |
9021 | */ | 8947 | */ |
9022 | 8948 | ||
9023 | static int | 8949 | static int shiftcmd(int argc, char **argv) |
9024 | shiftcmd(int argc, char **argv) | ||
9025 | { | 8950 | { |
9026 | int n; | 8951 | int n; |
9027 | char **ap1, **ap2; | 8952 | char **ap1, **ap2; |
@@ -9033,7 +8958,7 @@ shiftcmd(int argc, char **argv) | |||
9033 | error("can't shift that many"); | 8958 | error("can't shift that many"); |
9034 | INTOFF; | 8959 | INTOFF; |
9035 | shellparam.nparam -= n; | 8960 | shellparam.nparam -= n; |
9036 | for (ap1 = shellparam.p ; --n >= 0 ; ap1++) { | 8961 | for (ap1 = shellparam.p; --n >= 0; ap1++) { |
9037 | if (shellparam.malloc) | 8962 | if (shellparam.malloc) |
9038 | free(*ap1); | 8963 | free(*ap1); |
9039 | } | 8964 | } |
@@ -9051,8 +8976,7 @@ shiftcmd(int argc, char **argv) | |||
9051 | * The set command builtin. | 8976 | * The set command builtin. |
9052 | */ | 8977 | */ |
9053 | 8978 | ||
9054 | static int | 8979 | static int setcmd(int argc, char **argv) |
9055 | setcmd(int argc, char **argv) | ||
9056 | { | 8980 | { |
9057 | if (argc == 1) | 8981 | if (argc == 1) |
9058 | return showvarscmd(argc, argv); | 8982 | return showvarscmd(argc, argv); |
@@ -9067,8 +8991,7 @@ setcmd(int argc, char **argv) | |||
9067 | } | 8991 | } |
9068 | 8992 | ||
9069 | 8993 | ||
9070 | static void | 8994 | static void getoptsreset(const char *value) |
9071 | getoptsreset(const char *value) | ||
9072 | { | 8995 | { |
9073 | shellparam.optind = number(value); | 8996 | shellparam.optind = number(value); |
9074 | shellparam.optoff = -1; | 8997 | shellparam.optoff = -1; |
@@ -9077,13 +9000,13 @@ getoptsreset(const char *value) | |||
9077 | #ifdef CONFIG_LOCALE_SUPPORT | 9000 | #ifdef CONFIG_LOCALE_SUPPORT |
9078 | static void change_lc_all(const char *value) | 9001 | static void change_lc_all(const char *value) |
9079 | { | 9002 | { |
9080 | if(value != 0 && *value != 0) | 9003 | if (value != 0 && *value != 0) |
9081 | setlocale(LC_ALL, value); | 9004 | setlocale(LC_ALL, value); |
9082 | } | 9005 | } |
9083 | 9006 | ||
9084 | static void change_lc_ctype(const char *value) | 9007 | static void change_lc_ctype(const char *value) |
9085 | { | 9008 | { |
9086 | if(value != 0 && *value != 0) | 9009 | if (value != 0 && *value != 0) |
9087 | setlocale(LC_CTYPE, value); | 9010 | setlocale(LC_CTYPE, value); |
9088 | } | 9011 | } |
9089 | 9012 | ||
@@ -9097,8 +9020,7 @@ static void change_lc_ctype(const char *value) | |||
9097 | * then it's the first time getopts has been called. | 9020 | * then it's the first time getopts has been called. |
9098 | */ | 9021 | */ |
9099 | 9022 | ||
9100 | static int | 9023 | static int getoptscmd(int argc, char **argv) |
9101 | getoptscmd(int argc, char **argv) | ||
9102 | { | 9024 | { |
9103 | char **optbase; | 9025 | char **optbase; |
9104 | 9026 | ||
@@ -9110,8 +9032,7 @@ getoptscmd(int argc, char **argv) | |||
9110 | shellparam.optind = 1; | 9032 | shellparam.optind = 1; |
9111 | shellparam.optoff = -1; | 9033 | shellparam.optoff = -1; |
9112 | } | 9034 | } |
9113 | } | 9035 | } else { |
9114 | else { | ||
9115 | optbase = &argv[3]; | 9036 | optbase = &argv[3]; |
9116 | if (shellparam.optind > argc - 2) { | 9037 | if (shellparam.optind > argc - 2) { |
9117 | shellparam.optind = 1; | 9038 | shellparam.optind = 1; |
@@ -9120,19 +9041,19 @@ getoptscmd(int argc, char **argv) | |||
9120 | } | 9041 | } |
9121 | 9042 | ||
9122 | return getopts(argv[1], argv[2], optbase, &shellparam.optind, | 9043 | return getopts(argv[1], argv[2], optbase, &shellparam.optind, |
9123 | &shellparam.optoff); | 9044 | &shellparam.optoff); |
9124 | } | 9045 | } |
9125 | 9046 | ||
9126 | /* | 9047 | /* |
9127 | * Safe version of setvar, returns 1 on success 0 on failure. | 9048 | * Safe version of setvar, returns 1 on success 0 on failure. |
9128 | */ | 9049 | */ |
9129 | 9050 | ||
9130 | static int | 9051 | static int setvarsafe(const char *name, const char *val, int flags) |
9131 | setvarsafe(const char *name, const char *val, int flags) | ||
9132 | { | 9052 | { |
9133 | struct jmploc jmploc; | 9053 | struct jmploc jmploc; |
9134 | struct jmploc *volatile savehandler = handler; | 9054 | struct jmploc *volatile savehandler = handler; |
9135 | int err = 0; | 9055 | int err = 0; |
9056 | |||
9136 | #ifdef __GNUC__ | 9057 | #ifdef __GNUC__ |
9137 | (void) &err; | 9058 | (void) &err; |
9138 | #endif | 9059 | #endif |
@@ -9148,7 +9069,8 @@ setvarsafe(const char *name, const char *val, int flags) | |||
9148 | } | 9069 | } |
9149 | 9070 | ||
9150 | static int | 9071 | static int |
9151 | getopts(char *optstr, char *optvar, char **optfirst, int *myoptind, int *optoff) | 9072 | getopts(char *optstr, char *optvar, char **optfirst, int *myoptind, |
9073 | int *optoff) | ||
9152 | { | 9074 | { |
9153 | char *p, *q; | 9075 | char *p, *q; |
9154 | char c = '?'; | 9076 | char c = '?'; |
@@ -9158,7 +9080,7 @@ getopts(char *optstr, char *optvar, char **optfirst, int *myoptind, int *optoff) | |||
9158 | char **optnext = optfirst + *myoptind - 1; | 9080 | char **optnext = optfirst + *myoptind - 1; |
9159 | 9081 | ||
9160 | if (*myoptind <= 1 || *optoff < 0 || !(*(optnext - 1)) || | 9082 | if (*myoptind <= 1 || *optoff < 0 || !(*(optnext - 1)) || |
9161 | strlen(*(optnext - 1)) < *optoff) | 9083 | strlen(*(optnext - 1)) < *optoff) |
9162 | p = NULL; | 9084 | p = NULL; |
9163 | else | 9085 | else |
9164 | p = *(optnext - 1) + *optoff; | 9086 | p = *(optnext - 1) + *optoff; |
@@ -9168,26 +9090,25 @@ getopts(char *optstr, char *optvar, char **optfirst, int *myoptind, int *optoff) | |||
9168 | return 1; | 9090 | return 1; |
9169 | p = *optnext; | 9091 | p = *optnext; |
9170 | if (p == NULL || *p != '-' || *++p == '\0') { | 9092 | if (p == NULL || *p != '-' || *++p == '\0') { |
9171 | atend: | 9093 | atend: |
9172 | *myoptind = optnext - optfirst + 1; | 9094 | *myoptind = optnext - optfirst + 1; |
9173 | p = NULL; | 9095 | p = NULL; |
9174 | done = 1; | 9096 | done = 1; |
9175 | goto out; | 9097 | goto out; |
9176 | } | 9098 | } |
9177 | optnext++; | 9099 | optnext++; |
9178 | if (p[0] == '-' && p[1] == '\0') /* check for "--" */ | 9100 | if (p[0] == '-' && p[1] == '\0') /* check for "--" */ |
9179 | goto atend; | 9101 | goto atend; |
9180 | } | 9102 | } |
9181 | 9103 | ||
9182 | c = *p++; | 9104 | c = *p++; |
9183 | for (q = optstr; *q != c; ) { | 9105 | for (q = optstr; *q != c;) { |
9184 | if (*q == '\0') { | 9106 | if (*q == '\0') { |
9185 | if (optstr[0] == ':') { | 9107 | if (optstr[0] == ':') { |
9186 | s[0] = c; | 9108 | s[0] = c; |
9187 | s[1] = '\0'; | 9109 | s[1] = '\0'; |
9188 | err |= setvarsafe("OPTARG", s, 0); | 9110 | err |= setvarsafe("OPTARG", s, 0); |
9189 | } | 9111 | } else { |
9190 | else { | ||
9191 | out2fmt("Illegal option -%c\n", c); | 9112 | out2fmt("Illegal option -%c\n", c); |
9192 | (void) unsetvar("OPTARG"); | 9113 | (void) unsetvar("OPTARG"); |
9193 | } | 9114 | } |
@@ -9205,8 +9126,7 @@ atend: | |||
9205 | s[1] = '\0'; | 9126 | s[1] = '\0'; |
9206 | err |= setvarsafe("OPTARG", s, 0); | 9127 | err |= setvarsafe("OPTARG", s, 0); |
9207 | c = ':'; | 9128 | c = ':'; |
9208 | } | 9129 | } else { |
9209 | else { | ||
9210 | out2fmt("No arg for -%c option\n", c); | 9130 | out2fmt("No arg for -%c option\n", c); |
9211 | (void) unsetvar("OPTARG"); | 9131 | (void) unsetvar("OPTARG"); |
9212 | c = '?'; | 9132 | c = '?'; |
@@ -9218,16 +9138,15 @@ atend: | |||
9218 | optnext++; | 9138 | optnext++; |
9219 | setvarsafe("OPTARG", p, 0); | 9139 | setvarsafe("OPTARG", p, 0); |
9220 | p = NULL; | 9140 | p = NULL; |
9221 | } | 9141 | } else |
9222 | else | ||
9223 | setvarsafe("OPTARG", "", 0); | 9142 | setvarsafe("OPTARG", "", 0); |
9224 | *myoptind = optnext - optfirst + 1; | 9143 | *myoptind = optnext - optfirst + 1; |
9225 | goto out; | 9144 | goto out; |
9226 | 9145 | ||
9227 | bad: | 9146 | bad: |
9228 | *myoptind = 1; | 9147 | *myoptind = 1; |
9229 | p = NULL; | 9148 | p = NULL; |
9230 | out: | 9149 | out: |
9231 | *optoff = p ? p - *(optnext - 1) : -1; | 9150 | *optoff = p ? p - *(optnext - 1) : -1; |
9232 | snprintf(s, sizeof(s), "%d", *myoptind); | 9151 | snprintf(s, sizeof(s), "%d", *myoptind); |
9233 | err |= setvarsafe("OPTIND", s, VNOFUNC); | 9152 | err |= setvarsafe("OPTIND", s, VNOFUNC); |
@@ -9254,8 +9173,7 @@ out: | |||
9254 | * end of input. | 9173 | * end of input. |
9255 | */ | 9174 | */ |
9256 | 9175 | ||
9257 | static int | 9176 | static int nextopt(const char *optstring) |
9258 | nextopt(const char *optstring) | ||
9259 | { | 9177 | { |
9260 | char *p; | 9178 | char *p; |
9261 | const char *q; | 9179 | const char *q; |
@@ -9266,11 +9184,11 @@ nextopt(const char *optstring) | |||
9266 | if (p == NULL || *p != '-' || *++p == '\0') | 9184 | if (p == NULL || *p != '-' || *++p == '\0') |
9267 | return '\0'; | 9185 | return '\0'; |
9268 | argptr++; | 9186 | argptr++; |
9269 | if (p[0] == '-' && p[1] == '\0') /* check for "--" */ | 9187 | if (p[0] == '-' && p[1] == '\0') /* check for "--" */ |
9270 | return '\0'; | 9188 | return '\0'; |
9271 | } | 9189 | } |
9272 | c = *p++; | 9190 | c = *p++; |
9273 | for (q = optstring ; *q != c ; ) { | 9191 | for (q = optstring; *q != c;) { |
9274 | if (*q == '\0') | 9192 | if (*q == '\0') |
9275 | error("Illegal option -%c", c); | 9193 | error("Illegal option -%c", c); |
9276 | if (*++q == ':') | 9194 | if (*++q == ':') |
@@ -9286,18 +9204,18 @@ nextopt(const char *optstring) | |||
9286 | return c; | 9204 | return c; |
9287 | } | 9205 | } |
9288 | 9206 | ||
9289 | static void | 9207 | static void flushall() |
9290 | flushall() { | 9208 | { |
9291 | INTOFF; | 9209 | INTOFF; |
9292 | fflush(stdout); | 9210 | fflush(stdout); |
9293 | INTON; | 9211 | INTON; |
9294 | } | 9212 | } |
9295 | 9213 | ||
9296 | 9214 | ||
9297 | static void | 9215 | static void out2fmt(const char *fmt, ...) |
9298 | out2fmt(const char *fmt, ...) | ||
9299 | { | 9216 | { |
9300 | va_list ap; | 9217 | va_list ap; |
9218 | |||
9301 | va_start(ap, fmt); | 9219 | va_start(ap, fmt); |
9302 | vfprintf(stderr, fmt, ap); | 9220 | vfprintf(stderr, fmt, ap); |
9303 | va_end(ap); | 9221 | va_end(ap); |
@@ -9307,8 +9225,7 @@ out2fmt(const char *fmt, ...) | |||
9307 | * Version of write which resumes after a signal is caught. | 9225 | * Version of write which resumes after a signal is caught. |
9308 | */ | 9226 | */ |
9309 | 9227 | ||
9310 | static int | 9228 | static int xwrite(int fd, const char *buf, int nbytes) |
9311 | xwrite(int fd, const char *buf, int nbytes) | ||
9312 | { | 9229 | { |
9313 | int ntry; | 9230 | int ntry; |
9314 | int i; | 9231 | int i; |
@@ -9342,42 +9259,42 @@ xwrite(int fd, const char *buf, int nbytes) | |||
9342 | 9259 | ||
9343 | 9260 | ||
9344 | struct heredoc { | 9261 | struct heredoc { |
9345 | struct heredoc *next; /* next here document in list */ | 9262 | struct heredoc *next; /* next here document in list */ |
9346 | union node *here; /* redirection node */ | 9263 | union node *here; /* redirection node */ |
9347 | char *eofmark; /* string indicating end of input */ | 9264 | char *eofmark; /* string indicating end of input */ |
9348 | int striptabs; /* if set, strip leading tabs */ | 9265 | int striptabs; /* if set, strip leading tabs */ |
9349 | }; | 9266 | }; |
9350 | 9267 | ||
9351 | static struct heredoc *heredoclist; /* list of here documents to read */ | 9268 | static struct heredoc *heredoclist; /* list of here documents to read */ |
9352 | static int parsebackquote; /* nonzero if we are inside backquotes */ | 9269 | static int parsebackquote; /* nonzero if we are inside backquotes */ |
9353 | static int doprompt; /* if set, prompt the user */ | 9270 | static int doprompt; /* if set, prompt the user */ |
9354 | static int needprompt; /* true if interactive and at start of line */ | 9271 | static int needprompt; /* true if interactive and at start of line */ |
9355 | static int lasttoken; /* last token read */ | 9272 | static int lasttoken; /* last token read */ |
9356 | 9273 | ||
9357 | static char *wordtext; /* text of last word returned by readtoken */ | 9274 | static char *wordtext; /* text of last word returned by readtoken */ |
9358 | 9275 | ||
9359 | static struct nodelist *backquotelist; | 9276 | static struct nodelist *backquotelist; |
9360 | static union node *redirnode; | 9277 | static union node *redirnode; |
9361 | static struct heredoc *heredoc; | 9278 | static struct heredoc *heredoc; |
9362 | static int quoteflag; /* set if (part of) last token was quoted */ | 9279 | static int quoteflag; /* set if (part of) last token was quoted */ |
9363 | static int startlinno; /* line # where last token started */ | 9280 | static int startlinno; /* line # where last token started */ |
9364 | 9281 | ||
9365 | 9282 | ||
9366 | static union node *list (int); | 9283 | static union node *list(int); |
9367 | static union node *andor (void); | 9284 | static union node *andor(void); |
9368 | static union node *pipeline (void); | 9285 | static union node *pipeline(void); |
9369 | static union node *command (void); | 9286 | static union node *command(void); |
9370 | static union node *simplecmd(union node **rpp, union node *redir); | 9287 | static union node *simplecmd(union node **rpp, union node *redir); |
9371 | static void parsefname (void); | 9288 | static void parsefname(void); |
9372 | static void parseheredoc (void); | 9289 | static void parseheredoc(void); |
9373 | static char peektoken (void); | 9290 | static char peektoken(void); |
9374 | static int readtoken (void); | 9291 | static int readtoken(void); |
9375 | static int xxreadtoken (void); | 9292 | static int xxreadtoken(void); |
9376 | static int readtoken1 (int, int, const char *, int); | 9293 | static int readtoken1(int, int, const char *, int); |
9377 | static int noexpand (char *); | 9294 | static int noexpand(char *); |
9378 | static void synexpect (int) __attribute__((noreturn)); | 9295 | static void synexpect(int) __attribute__ ((noreturn)); |
9379 | static void synerror (const char *) __attribute__((noreturn)); | 9296 | static void synerror(const char *) __attribute__ ((noreturn)); |
9380 | static void setprompt (int); | 9297 | static void setprompt(int); |
9381 | 9298 | ||
9382 | 9299 | ||
9383 | /* | 9300 | /* |
@@ -9385,8 +9302,7 @@ static void setprompt (int); | |||
9385 | * valid parse tree indicating a blank line.) | 9302 | * valid parse tree indicating a blank line.) |
9386 | */ | 9303 | */ |
9387 | 9304 | ||
9388 | static union node * | 9305 | static union node *parsecmd(int interact) |
9389 | parsecmd(int interact) | ||
9390 | { | 9306 | { |
9391 | int t; | 9307 | int t; |
9392 | 9308 | ||
@@ -9407,8 +9323,7 @@ parsecmd(int interact) | |||
9407 | } | 9323 | } |
9408 | 9324 | ||
9409 | 9325 | ||
9410 | static union node * | 9326 | static union node *list(int nlflag) |
9411 | list(int nlflag) | ||
9412 | { | 9327 | { |
9413 | union node *n1, *n2, *n3; | 9328 | union node *n1, *n2, *n3; |
9414 | int tok; | 9329 | int tok; |
@@ -9426,7 +9341,7 @@ list(int nlflag) | |||
9426 | } else if (n2->type == NREDIR) { | 9341 | } else if (n2->type == NREDIR) { |
9427 | n2->type = NBACKGND; | 9342 | n2->type = NBACKGND; |
9428 | } else { | 9343 | } else { |
9429 | n3 = (union node *)stalloc(sizeof (struct nredir)); | 9344 | n3 = (union node *) stalloc(sizeof(struct nredir)); |
9430 | n3->type = NBACKGND; | 9345 | n3->type = NBACKGND; |
9431 | n3->nredir.n = n2; | 9346 | n3->nredir.n = n2; |
9432 | n3->nredir.redirect = NULL; | 9347 | n3->nredir.redirect = NULL; |
@@ -9435,9 +9350,8 @@ list(int nlflag) | |||
9435 | } | 9350 | } |
9436 | if (n1 == NULL) { | 9351 | if (n1 == NULL) { |
9437 | n1 = n2; | 9352 | n1 = n2; |
9438 | } | 9353 | } else { |
9439 | else { | 9354 | n3 = (union node *) stalloc(sizeof(struct nbinary)); |
9440 | n3 = (union node *)stalloc(sizeof (struct nbinary)); | ||
9441 | n3->type = NSEMI; | 9355 | n3->type = NSEMI; |
9442 | n3->nbinary.ch1 = n1; | 9356 | n3->nbinary.ch1 = n1; |
9443 | n3->nbinary.ch2 = n2; | 9357 | n3->nbinary.ch2 = n2; |
@@ -9464,7 +9378,7 @@ list(int nlflag) | |||
9464 | if (heredoclist) | 9378 | if (heredoclist) |
9465 | parseheredoc(); | 9379 | parseheredoc(); |
9466 | else | 9380 | else |
9467 | pungetc(); /* push back EOF on input */ | 9381 | pungetc(); /* push back EOF on input */ |
9468 | return n1; | 9382 | return n1; |
9469 | default: | 9383 | default: |
9470 | if (nlflag) | 9384 | if (nlflag) |
@@ -9477,8 +9391,8 @@ list(int nlflag) | |||
9477 | 9391 | ||
9478 | 9392 | ||
9479 | 9393 | ||
9480 | static union node * | 9394 | static union node *andor() |
9481 | andor() { | 9395 | { |
9482 | union node *n1, *n2, *n3; | 9396 | union node *n1, *n2, *n3; |
9483 | int t; | 9397 | int t; |
9484 | 9398 | ||
@@ -9495,7 +9409,7 @@ andor() { | |||
9495 | } | 9409 | } |
9496 | checkkwd = 2; | 9410 | checkkwd = 2; |
9497 | n2 = pipeline(); | 9411 | n2 = pipeline(); |
9498 | n3 = (union node *)stalloc(sizeof (struct nbinary)); | 9412 | n3 = (union node *) stalloc(sizeof(struct nbinary)); |
9499 | n3->type = t; | 9413 | n3->type = t; |
9500 | n3->nbinary.ch1 = n1; | 9414 | n3->nbinary.ch1 = n1; |
9501 | n3->nbinary.ch2 = n2; | 9415 | n3->nbinary.ch2 = n2; |
@@ -9505,8 +9419,8 @@ andor() { | |||
9505 | 9419 | ||
9506 | 9420 | ||
9507 | 9421 | ||
9508 | static union node * | 9422 | static union node *pipeline() |
9509 | pipeline() { | 9423 | { |
9510 | union node *n1, *n2, *pipenode; | 9424 | union node *n1, *n2, *pipenode; |
9511 | struct nodelist *lp, *prev; | 9425 | struct nodelist *lp, *prev; |
9512 | int negate; | 9426 | int negate; |
@@ -9520,15 +9434,15 @@ pipeline() { | |||
9520 | tokpushback++; | 9434 | tokpushback++; |
9521 | n1 = command(); | 9435 | n1 = command(); |
9522 | if (readtoken() == TPIPE) { | 9436 | if (readtoken() == TPIPE) { |
9523 | pipenode = (union node *)stalloc(sizeof (struct npipe)); | 9437 | pipenode = (union node *) stalloc(sizeof(struct npipe)); |
9524 | pipenode->type = NPIPE; | 9438 | pipenode->type = NPIPE; |
9525 | pipenode->npipe.backgnd = 0; | 9439 | pipenode->npipe.backgnd = 0; |
9526 | lp = (struct nodelist *)stalloc(sizeof (struct nodelist)); | 9440 | lp = (struct nodelist *) stalloc(sizeof(struct nodelist)); |
9527 | pipenode->npipe.cmdlist = lp; | 9441 | pipenode->npipe.cmdlist = lp; |
9528 | lp->n = n1; | 9442 | lp->n = n1; |
9529 | do { | 9443 | do { |
9530 | prev = lp; | 9444 | prev = lp; |
9531 | lp = (struct nodelist *)stalloc(sizeof (struct nodelist)); | 9445 | lp = (struct nodelist *) stalloc(sizeof(struct nodelist)); |
9532 | checkkwd = 2; | 9446 | checkkwd = 2; |
9533 | lp->n = command(); | 9447 | lp->n = command(); |
9534 | prev->next = lp; | 9448 | prev->next = lp; |
@@ -9538,7 +9452,7 @@ pipeline() { | |||
9538 | } | 9452 | } |
9539 | tokpushback++; | 9453 | tokpushback++; |
9540 | if (negate) { | 9454 | if (negate) { |
9541 | n2 = (union node *)stalloc(sizeof (struct nnot)); | 9455 | n2 = (union node *) stalloc(sizeof(struct nnot)); |
9542 | n2->type = NNOT; | 9456 | n2->type = NNOT; |
9543 | n2->nnot.com = n1; | 9457 | n2->nnot.com = n1; |
9544 | return n2; | 9458 | return n2; |
@@ -9548,8 +9462,8 @@ pipeline() { | |||
9548 | 9462 | ||
9549 | 9463 | ||
9550 | 9464 | ||
9551 | static union node * | 9465 | static union node *command(void) |
9552 | command(void) { | 9466 | { |
9553 | union node *n1, *n2; | 9467 | union node *n1, *n2; |
9554 | union node *ap, **app; | 9468 | union node *ap, **app; |
9555 | union node *cp, **cpp; | 9469 | union node *cp, **cpp; |
@@ -9570,7 +9484,7 @@ command(void) { | |||
9570 | 9484 | ||
9571 | switch (readtoken()) { | 9485 | switch (readtoken()) { |
9572 | case TIF: | 9486 | case TIF: |
9573 | n1 = (union node *)stalloc(sizeof (struct nif)); | 9487 | n1 = (union node *) stalloc(sizeof(struct nif)); |
9574 | n1->type = NIF; | 9488 | n1->type = NIF; |
9575 | n1->nif.test = list(0); | 9489 | n1->nif.test = list(0); |
9576 | if (readtoken() != TTHEN) | 9490 | if (readtoken() != TTHEN) |
@@ -9578,7 +9492,7 @@ command(void) { | |||
9578 | n1->nif.ifpart = list(0); | 9492 | n1->nif.ifpart = list(0); |
9579 | n2 = n1; | 9493 | n2 = n1; |
9580 | while (readtoken() == TELIF) { | 9494 | while (readtoken() == TELIF) { |
9581 | n2->nif.elsepart = (union node *)stalloc(sizeof (struct nif)); | 9495 | n2->nif.elsepart = (union node *) stalloc(sizeof(struct nif)); |
9582 | n2 = n2->nif.elsepart; | 9496 | n2 = n2->nif.elsepart; |
9583 | n2->type = NIF; | 9497 | n2->type = NIF; |
9584 | n2->nif.test = list(0); | 9498 | n2->nif.test = list(0); |
@@ -9597,13 +9511,14 @@ command(void) { | |||
9597 | checkkwd = 1; | 9511 | checkkwd = 1; |
9598 | break; | 9512 | break; |
9599 | case TWHILE: | 9513 | case TWHILE: |
9600 | case TUNTIL: { | 9514 | case TUNTIL:{ |
9601 | int got; | 9515 | int got; |
9602 | n1 = (union node *)stalloc(sizeof (struct nbinary)); | 9516 | n1 = (union node *) stalloc(sizeof(struct nbinary)); |
9603 | n1->type = (lasttoken == TWHILE)? NWHILE : NUNTIL; | 9517 | n1->type = (lasttoken == TWHILE) ? NWHILE : NUNTIL; |
9604 | n1->nbinary.ch1 = list(0); | 9518 | n1->nbinary.ch1 = list(0); |
9605 | if ((got=readtoken()) != TDO) { | 9519 | if ((got = readtoken()) != TDO) { |
9606 | TRACE(("expecting DO got %s %s\n", tokname(got), got == TWORD ? wordtext : "")); | 9520 | TRACE(("expecting DO got %s %s\n", tokname(got), |
9521 | got == TWORD ? wordtext : "")); | ||
9607 | synexpect(TDO); | 9522 | synexpect(TDO); |
9608 | } | 9523 | } |
9609 | n1->nbinary.ch2 = list(0); | 9524 | n1->nbinary.ch2 = list(0); |
@@ -9613,16 +9528,16 @@ TRACE(("expecting DO got %s %s\n", tokname(got), got == TWORD ? wordtext : "")); | |||
9613 | break; | 9528 | break; |
9614 | } | 9529 | } |
9615 | case TFOR: | 9530 | case TFOR: |
9616 | if (readtoken() != TWORD || quoteflag || ! goodname(wordtext)) | 9531 | if (readtoken() != TWORD || quoteflag || !goodname(wordtext)) |
9617 | synerror("Bad for loop variable"); | 9532 | synerror("Bad for loop variable"); |
9618 | n1 = (union node *)stalloc(sizeof (struct nfor)); | 9533 | n1 = (union node *) stalloc(sizeof(struct nfor)); |
9619 | n1->type = NFOR; | 9534 | n1->type = NFOR; |
9620 | n1->nfor.var = wordtext; | 9535 | n1->nfor.var = wordtext; |
9621 | checkkwd = 1; | 9536 | checkkwd = 1; |
9622 | if (readtoken() == TIN) { | 9537 | if (readtoken() == TIN) { |
9623 | app = ≈ | 9538 | app = ≈ |
9624 | while (readtoken() == TWORD) { | 9539 | while (readtoken() == TWORD) { |
9625 | n2 = (union node *)stalloc(sizeof (struct narg)); | 9540 | n2 = (union node *) stalloc(sizeof(struct narg)); |
9626 | n2->type = NARG; | 9541 | n2->type = NARG; |
9627 | n2->narg.text = wordtext; | 9542 | n2->narg.text = wordtext; |
9628 | n2->narg.backquote = backquotelist; | 9543 | n2->narg.backquote = backquotelist; |
@@ -9634,9 +9549,10 @@ TRACE(("expecting DO got %s %s\n", tokname(got), got == TWORD ? wordtext : "")); | |||
9634 | if (lasttoken != TNL && lasttoken != TSEMI) | 9549 | if (lasttoken != TNL && lasttoken != TSEMI) |
9635 | synexpect(-1); | 9550 | synexpect(-1); |
9636 | } else { | 9551 | } else { |
9637 | static char argvars[5] = {CTLVAR, VSNORMAL|VSQUOTE, | 9552 | static char argvars[5] = { CTLVAR, VSNORMAL | VSQUOTE, |
9638 | '@', '=', '\0'}; | 9553 | '@', '=', '\0' |
9639 | n2 = (union node *)stalloc(sizeof (struct narg)); | 9554 | }; |
9555 | n2 = (union node *) stalloc(sizeof(struct narg)); | ||
9640 | n2->type = NARG; | 9556 | n2->type = NARG; |
9641 | n2->narg.text = argvars; | 9557 | n2->narg.text = argvars; |
9642 | n2->narg.backquote = NULL; | 9558 | n2->narg.backquote = NULL; |
@@ -9658,11 +9574,11 @@ TRACE(("expecting DO got %s %s\n", tokname(got), got == TWORD ? wordtext : "")); | |||
9658 | checkkwd = 1; | 9574 | checkkwd = 1; |
9659 | break; | 9575 | break; |
9660 | case TCASE: | 9576 | case TCASE: |
9661 | n1 = (union node *)stalloc(sizeof (struct ncase)); | 9577 | n1 = (union node *) stalloc(sizeof(struct ncase)); |
9662 | n1->type = NCASE; | 9578 | n1->type = NCASE; |
9663 | if (readtoken() != TWORD) | 9579 | if (readtoken() != TWORD) |
9664 | synexpect(TWORD); | 9580 | synexpect(TWORD); |
9665 | n1->ncase.expr = n2 = (union node *)stalloc(sizeof (struct narg)); | 9581 | n1->ncase.expr = n2 = (union node *) stalloc(sizeof(struct narg)); |
9666 | n2->type = NARG; | 9582 | n2->type = NARG; |
9667 | n2->narg.text = wordtext; | 9583 | n2->narg.text = wordtext; |
9668 | n2->narg.backquote = backquotelist; | 9584 | n2->narg.backquote = backquotelist; |
@@ -9677,11 +9593,11 @@ TRACE(("expecting DO got %s %s\n", tokname(got), got == TWORD ? wordtext : "")); | |||
9677 | do { | 9593 | do { |
9678 | if (lasttoken == TLP) | 9594 | if (lasttoken == TLP) |
9679 | readtoken(); | 9595 | readtoken(); |
9680 | *cpp = cp = (union node *)stalloc(sizeof (struct nclist)); | 9596 | *cpp = cp = (union node *) stalloc(sizeof(struct nclist)); |
9681 | cp->type = NCLIST; | 9597 | cp->type = NCLIST; |
9682 | app = &cp->nclist.pattern; | 9598 | app = &cp->nclist.pattern; |
9683 | for (;;) { | 9599 | for (;;) { |
9684 | *app = ap = (union node *)stalloc(sizeof (struct narg)); | 9600 | *app = ap = (union node *) stalloc(sizeof(struct narg)); |
9685 | ap->type = NARG; | 9601 | ap->type = NARG; |
9686 | ap->narg.text = wordtext; | 9602 | ap->narg.text = wordtext; |
9687 | ap->narg.backquote = backquotelist; | 9603 | ap->narg.backquote = backquotelist; |
@@ -9703,12 +9619,12 @@ TRACE(("expecting DO got %s %s\n", tokname(got), got == TWORD ? wordtext : "")); | |||
9703 | checkkwd = 2, readtoken(); | 9619 | checkkwd = 2, readtoken(); |
9704 | } | 9620 | } |
9705 | cpp = &cp->nclist.next; | 9621 | cpp = &cp->nclist.next; |
9706 | } while(lasttoken != TESAC); | 9622 | } while (lasttoken != TESAC); |
9707 | *cpp = NULL; | 9623 | *cpp = NULL; |
9708 | checkkwd = 1; | 9624 | checkkwd = 1; |
9709 | break; | 9625 | break; |
9710 | case TLP: | 9626 | case TLP: |
9711 | n1 = (union node *)stalloc(sizeof (struct nredir)); | 9627 | n1 = (union node *) stalloc(sizeof(struct nredir)); |
9712 | n1->type = NSUBSHELL; | 9628 | n1->type = NSUBSHELL; |
9713 | n1->nredir.n = list(0); | 9629 | n1->nredir.n = list(0); |
9714 | n1->nredir.redirect = NULL; | 9630 | n1->nredir.redirect = NULL; |
@@ -9722,7 +9638,7 @@ TRACE(("expecting DO got %s %s\n", tokname(got), got == TWORD ? wordtext : "")); | |||
9722 | synexpect(TEND); | 9638 | synexpect(TEND); |
9723 | checkkwd = 1; | 9639 | checkkwd = 1; |
9724 | break; | 9640 | break; |
9725 | /* Handle an empty command like other simple commands. */ | 9641 | /* Handle an empty command like other simple commands. */ |
9726 | case TSEMI: | 9642 | case TSEMI: |
9727 | case TAND: | 9643 | case TAND: |
9728 | case TOR: | 9644 | case TOR: |
@@ -9755,7 +9671,7 @@ TRACE(("expecting DO got %s %s\n", tokname(got), got == TWORD ? wordtext : "")); | |||
9755 | *rpp = NULL; | 9671 | *rpp = NULL; |
9756 | if (redir) { | 9672 | if (redir) { |
9757 | if (n1->type != NSUBSHELL) { | 9673 | if (n1->type != NSUBSHELL) { |
9758 | n2 = (union node *)stalloc(sizeof (struct nredir)); | 9674 | n2 = (union node *) stalloc(sizeof(struct nredir)); |
9759 | n2->type = NREDIR; | 9675 | n2->type = NREDIR; |
9760 | n2->nredir.n = n1; | 9676 | n2->nredir.n = n1; |
9761 | n1 = n2; | 9677 | n1 = n2; |
@@ -9767,8 +9683,8 @@ TRACE(("expecting DO got %s %s\n", tokname(got), got == TWORD ? wordtext : "")); | |||
9767 | } | 9683 | } |
9768 | 9684 | ||
9769 | 9685 | ||
9770 | static union node * | 9686 | static union node *simplecmd(union node **rpp, union node *redir) |
9771 | simplecmd(union node **rpp, union node *redir) { | 9687 | { |
9772 | union node *args, **app; | 9688 | union node *args, **app; |
9773 | union node *n = NULL; | 9689 | union node *n = NULL; |
9774 | union node *vars, **vpp; | 9690 | union node *vars, **vpp; |
@@ -9780,12 +9696,12 @@ simplecmd(union node **rpp, union node *redir) { | |||
9780 | vpp = &vars; | 9696 | vpp = &vars; |
9781 | 9697 | ||
9782 | /* If we don't have any redirections already, then we must reset | 9698 | /* If we don't have any redirections already, then we must reset |
9783 | rpp to be the address of the local redir variable. */ | 9699 | rpp to be the address of the local redir variable. */ |
9784 | if (redir == 0) | 9700 | if (redir == 0) |
9785 | rpp = &redir; | 9701 | rpp = &redir; |
9786 | /* We save the incoming value, because we need this for shell | 9702 | /* We save the incoming value, because we need this for shell |
9787 | functions. There can not be a redirect or an argument between | 9703 | functions. There can not be a redirect or an argument between |
9788 | the function name and the open parenthesis. */ | 9704 | the function name and the open parenthesis. */ |
9789 | orig_rpp = rpp; | 9705 | orig_rpp = rpp; |
9790 | 9706 | ||
9791 | checkalias = 2; | 9707 | checkalias = 2; |
@@ -9793,7 +9709,7 @@ simplecmd(union node **rpp, union node *redir) { | |||
9793 | switch (readtoken()) { | 9709 | switch (readtoken()) { |
9794 | case TWORD: | 9710 | case TWORD: |
9795 | case TASSIGN: | 9711 | case TASSIGN: |
9796 | n = (union node *)stalloc(sizeof (struct narg)); | 9712 | n = (union node *) stalloc(sizeof(struct narg)); |
9797 | n->type = NARG; | 9713 | n->type = NARG; |
9798 | n->narg.text = wordtext; | 9714 | n->narg.text = wordtext; |
9799 | n->narg.backquote = backquotelist; | 9715 | n->narg.backquote = backquotelist; |
@@ -9808,13 +9724,10 @@ simplecmd(union node **rpp, union node *redir) { | |||
9808 | case TREDIR: | 9724 | case TREDIR: |
9809 | *rpp = n = redirnode; | 9725 | *rpp = n = redirnode; |
9810 | rpp = &n->nfile.next; | 9726 | rpp = &n->nfile.next; |
9811 | parsefname(); /* read name of redirection file */ | 9727 | parsefname(); /* read name of redirection file */ |
9812 | break; | 9728 | break; |
9813 | case TLP: | 9729 | case TLP: |
9814 | if ( | 9730 | if (args && app == &args->narg.next && !vars && rpp == orig_rpp) { |
9815 | args && app == &args->narg.next && | ||
9816 | !vars && rpp == orig_rpp | ||
9817 | ) { | ||
9818 | /* We have a function */ | 9731 | /* We have a function */ |
9819 | if (readtoken() != TRP) | 9732 | if (readtoken() != TRP) |
9820 | synexpect(TRP); | 9733 | synexpect(TRP); |
@@ -9829,11 +9742,11 @@ simplecmd(union node **rpp, union node *redir) { | |||
9829 | goto out; | 9742 | goto out; |
9830 | } | 9743 | } |
9831 | } | 9744 | } |
9832 | out: | 9745 | out: |
9833 | *app = NULL; | 9746 | *app = NULL; |
9834 | *vpp = NULL; | 9747 | *vpp = NULL; |
9835 | *rpp = NULL; | 9748 | *rpp = NULL; |
9836 | n = (union node *)stalloc(sizeof (struct ncmd)); | 9749 | n = (union node *) stalloc(sizeof(struct ncmd)); |
9837 | n->type = NCMD; | 9750 | n->type = NCMD; |
9838 | n->ncmd.backgnd = 0; | 9751 | n->ncmd.backgnd = 0; |
9839 | n->ncmd.args = args; | 9752 | n->ncmd.args = args; |
@@ -9842,11 +9755,11 @@ out: | |||
9842 | return n; | 9755 | return n; |
9843 | } | 9756 | } |
9844 | 9757 | ||
9845 | static union node * | 9758 | static union node *makename(void) |
9846 | makename(void) { | 9759 | { |
9847 | union node *n; | 9760 | union node *n; |
9848 | 9761 | ||
9849 | n = (union node *)stalloc(sizeof (struct narg)); | 9762 | n = (union node *) stalloc(sizeof(struct narg)); |
9850 | n->type = NARG; | 9763 | n->type = NARG; |
9851 | n->narg.next = NULL; | 9764 | n->narg.next = NULL; |
9852 | n->narg.text = wordtext; | 9765 | n->narg.text = wordtext; |
@@ -9874,8 +9787,8 @@ static void fixredir(union node *n, const char *text, int err) | |||
9874 | } | 9787 | } |
9875 | 9788 | ||
9876 | 9789 | ||
9877 | static void | 9790 | static void parsefname(void) |
9878 | parsefname(void) { | 9791 | { |
9879 | union node *n = redirnode; | 9792 | union node *n = redirnode; |
9880 | 9793 | ||
9881 | if (readtoken() != TWORD) | 9794 | if (readtoken() != TWORD) |
@@ -9892,7 +9805,8 @@ parsefname(void) { | |||
9892 | while (*wordtext == '\t') | 9805 | while (*wordtext == '\t') |
9893 | wordtext++; | 9806 | wordtext++; |
9894 | } | 9807 | } |
9895 | if (! noexpand(wordtext) || (i = strlen(wordtext)) == 0 || i > EOFMARKLEN) | 9808 | if (!noexpand(wordtext) || (i = strlen(wordtext)) == 0 |
9809 | || i > EOFMARKLEN) | ||
9896 | synerror("Illegal eof marker for << redirection"); | 9810 | synerror("Illegal eof marker for << redirection"); |
9897 | rmescapes(wordtext); | 9811 | rmescapes(wordtext); |
9898 | here->eofmark = wordtext; | 9812 | here->eofmark = wordtext; |
@@ -9900,7 +9814,7 @@ parsefname(void) { | |||
9900 | if (heredoclist == NULL) | 9814 | if (heredoclist == NULL) |
9901 | heredoclist = here; | 9815 | heredoclist = here; |
9902 | else { | 9816 | else { |
9903 | for (p = heredoclist ; p->next ; p = p->next); | 9817 | for (p = heredoclist; p->next; p = p->next); |
9904 | p->next = here; | 9818 | p->next = here; |
9905 | } | 9819 | } |
9906 | } else if (n->type == NTOFD || n->type == NFROMFD) { | 9820 | } else if (n->type == NTOFD || n->type == NFROMFD) { |
@@ -9915,8 +9829,8 @@ parsefname(void) { | |||
9915 | * Input any here documents. | 9829 | * Input any here documents. |
9916 | */ | 9830 | */ |
9917 | 9831 | ||
9918 | static void | 9832 | static void parseheredoc() |
9919 | parseheredoc() { | 9833 | { |
9920 | struct heredoc *here; | 9834 | struct heredoc *here; |
9921 | union node *n; | 9835 | union node *n; |
9922 | 9836 | ||
@@ -9927,9 +9841,9 @@ parseheredoc() { | |||
9927 | setprompt(2); | 9841 | setprompt(2); |
9928 | needprompt = 0; | 9842 | needprompt = 0; |
9929 | } | 9843 | } |
9930 | readtoken1(pgetc(), here->here->type == NHERE? SQSYNTAX : DQSYNTAX, | 9844 | readtoken1(pgetc(), here->here->type == NHERE ? SQSYNTAX : DQSYNTAX, |
9931 | here->eofmark, here->striptabs); | 9845 | here->eofmark, here->striptabs); |
9932 | n = (union node *)stalloc(sizeof (struct narg)); | 9846 | n = (union node *) stalloc(sizeof(struct narg)); |
9933 | n->narg.type = NARG; | 9847 | n->narg.type = NARG; |
9934 | n->narg.next = NULL; | 9848 | n->narg.next = NULL; |
9935 | n->narg.text = wordtext; | 9849 | n->narg.text = wordtext; |
@@ -9938,8 +9852,8 @@ parseheredoc() { | |||
9938 | } | 9852 | } |
9939 | } | 9853 | } |
9940 | 9854 | ||
9941 | static char | 9855 | static char peektoken() |
9942 | peektoken() { | 9856 | { |
9943 | int t; | 9857 | int t; |
9944 | 9858 | ||
9945 | t = readtoken(); | 9859 | t = readtoken(); |
@@ -9947,11 +9861,12 @@ peektoken() { | |||
9947 | return tokname_array[t][0]; | 9861 | return tokname_array[t][0]; |
9948 | } | 9862 | } |
9949 | 9863 | ||
9950 | static int | 9864 | static int readtoken() |
9951 | readtoken() { | 9865 | { |
9952 | int t; | 9866 | int t; |
9953 | 9867 | ||
9954 | int savecheckalias = checkalias; | 9868 | int savecheckalias = checkalias; |
9869 | |||
9955 | #ifdef CONFIG_ASH_ALIAS | 9870 | #ifdef CONFIG_ASH_ALIAS |
9956 | int savecheckkwd = checkkwd; | 9871 | int savecheckkwd = checkkwd; |
9957 | struct alias *ap; | 9872 | struct alias *ap; |
@@ -9962,7 +9877,7 @@ readtoken() { | |||
9962 | #endif | 9877 | #endif |
9963 | 9878 | ||
9964 | #ifdef CONFIG_ASH_ALIAS | 9879 | #ifdef CONFIG_ASH_ALIAS |
9965 | top: | 9880 | top: |
9966 | #endif | 9881 | #endif |
9967 | 9882 | ||
9968 | t = xxreadtoken(); | 9883 | t = xxreadtoken(); |
@@ -9984,8 +9899,7 @@ top: | |||
9984 | /* | 9899 | /* |
9985 | * check for keywords | 9900 | * check for keywords |
9986 | */ | 9901 | */ |
9987 | if (t == TWORD && !quoteflag) | 9902 | if (t == TWORD && !quoteflag) { |
9988 | { | ||
9989 | const char *const *pp; | 9903 | const char *const *pp; |
9990 | 9904 | ||
9991 | if ((pp = findkwd(wordtext))) { | 9905 | if ((pp = findkwd(wordtext))) { |
@@ -10005,7 +9919,8 @@ top: | |||
10005 | lasttoken = t = TASSIGN; | 9919 | lasttoken = t = TASSIGN; |
10006 | } else if (checkalias) { | 9920 | } else if (checkalias) { |
10007 | #ifdef CONFIG_ASH_ALIAS | 9921 | #ifdef CONFIG_ASH_ALIAS |
10008 | if (!quoteflag && (ap = *__lookupalias(wordtext)) != NULL && !(ap->flag & ALIASINUSE)) { | 9922 | if (!quoteflag && (ap = *__lookupalias(wordtext)) != NULL |
9923 | && !(ap->flag & ALIASINUSE)) { | ||
10009 | if (*ap->val) { | 9924 | if (*ap->val) { |
10010 | pushstring(ap->val, strlen(ap->val), ap); | 9925 | pushstring(ap->val, strlen(ap->val), ap); |
10011 | } | 9926 | } |
@@ -10015,12 +9930,14 @@ top: | |||
10015 | #endif | 9930 | #endif |
10016 | checkalias = 0; | 9931 | checkalias = 0; |
10017 | } | 9932 | } |
10018 | out: | 9933 | out: |
10019 | #ifdef DEBUG | 9934 | #ifdef DEBUG |
10020 | if (!alreadyseen) | 9935 | if (!alreadyseen) |
10021 | TRACE(("token %s %s\n", tokname(t), t == TWORD || t == TASSIGN ? wordtext : "")); | 9936 | TRACE(("token %s %s\n", tokname(t), t == TWORD |
9937 | || t == TASSIGN ? wordtext : "")); | ||
10022 | else | 9938 | else |
10023 | TRACE(("reread token %s %s\n", tokname(t), t == TWORD || t == TASSIGN ? wordtext : "")); | 9939 | TRACE(("reread token %s %s\n", tokname(t), t == TWORD |
9940 | || t == TASSIGN ? wordtext : "")); | ||
10024 | #endif | 9941 | #endif |
10025 | return (t); | 9942 | return (t); |
10026 | } | 9943 | } |
@@ -10047,12 +9964,12 @@ out: | |||
10047 | #define NEW_xxreadtoken | 9964 | #define NEW_xxreadtoken |
10048 | #ifdef NEW_xxreadtoken | 9965 | #ifdef NEW_xxreadtoken |
10049 | 9966 | ||
10050 | static const char xxreadtoken_chars[] = "\n()&|;"; /* singles must be first! */ | 9967 | static const char xxreadtoken_chars[] = "\n()&|;"; /* singles must be first! */ |
10051 | static const char xxreadtoken_tokens[] = { | 9968 | static const char xxreadtoken_tokens[] = { |
10052 | TNL, TLP, TRP, /* only single occurrence allowed */ | 9969 | TNL, TLP, TRP, /* only single occurrence allowed */ |
10053 | TBACKGND, TPIPE, TSEMI, /* if single occurrence */ | 9970 | TBACKGND, TPIPE, TSEMI, /* if single occurrence */ |
10054 | TEOF, /* corresponds to trailing nul */ | 9971 | TEOF, /* corresponds to trailing nul */ |
10055 | TAND, TOR, TENDCASE, /* if double occurrence */ | 9972 | TAND, TOR, TENDCASE, /* if double occurrence */ |
10056 | }; | 9973 | }; |
10057 | 9974 | ||
10058 | #define xxreadtoken_doubles \ | 9975 | #define xxreadtoken_doubles \ |
@@ -10060,8 +9977,8 @@ static const char xxreadtoken_tokens[] = { | |||
10060 | #define xxreadtoken_singles \ | 9977 | #define xxreadtoken_singles \ |
10061 | (sizeof(xxreadtoken_chars) - xxreadtoken_doubles - 1) | 9978 | (sizeof(xxreadtoken_chars) - xxreadtoken_doubles - 1) |
10062 | 9979 | ||
10063 | static int | 9980 | static int xxreadtoken() |
10064 | xxreadtoken() { | 9981 | { |
10065 | int c; | 9982 | int c; |
10066 | 9983 | ||
10067 | if (tokpushback) { | 9984 | if (tokpushback) { |
@@ -10073,18 +9990,18 @@ xxreadtoken() { | |||
10073 | needprompt = 0; | 9990 | needprompt = 0; |
10074 | } | 9991 | } |
10075 | startlinno = plinno; | 9992 | startlinno = plinno; |
10076 | for (;;) { /* until token or start of word found */ | 9993 | for (;;) { /* until token or start of word found */ |
10077 | c = pgetc_macro(); | 9994 | c = pgetc_macro(); |
10078 | 9995 | ||
10079 | if ((c!=' ') && (c!='\t') | 9996 | if ((c != ' ') && (c != '\t') |
10080 | #ifdef CONFIG_ASH_ALIAS | 9997 | #ifdef CONFIG_ASH_ALIAS |
10081 | && (c!=PEOA) | 9998 | && (c != PEOA) |
10082 | #endif | 9999 | #endif |
10083 | ) { | 10000 | ) { |
10084 | if (c=='#') { | 10001 | if (c == '#') { |
10085 | while ((c = pgetc()) != '\n' && c != PEOF); | 10002 | while ((c = pgetc()) != '\n' && c != PEOF); |
10086 | pungetc(); | 10003 | pungetc(); |
10087 | } else if (c=='\\') { | 10004 | } else if (c == '\\') { |
10088 | if (pgetc() != '\n') { | 10005 | if (pgetc() != '\n') { |
10089 | pungetc(); | 10006 | pungetc(); |
10090 | goto READTOKEN1; | 10007 | goto READTOKEN1; |
@@ -10095,20 +10012,20 @@ xxreadtoken() { | |||
10095 | const char *p | 10012 | const char *p |
10096 | = xxreadtoken_chars + sizeof(xxreadtoken_chars) - 1; | 10013 | = xxreadtoken_chars + sizeof(xxreadtoken_chars) - 1; |
10097 | 10014 | ||
10098 | if (c!=PEOF) { | 10015 | if (c != PEOF) { |
10099 | if (c=='\n') { | 10016 | if (c == '\n') { |
10100 | plinno++; | 10017 | plinno++; |
10101 | needprompt = doprompt; | 10018 | needprompt = doprompt; |
10102 | } | 10019 | } |
10103 | 10020 | ||
10104 | p = strchr(xxreadtoken_chars, c); | 10021 | p = strchr(xxreadtoken_chars, c); |
10105 | if (p == NULL) { | 10022 | if (p == NULL) { |
10106 | READTOKEN1: | 10023 | READTOKEN1: |
10107 | return readtoken1(c, BASESYNTAX, (char *)NULL, 0); | 10024 | return readtoken1(c, BASESYNTAX, (char *) NULL, 0); |
10108 | } | 10025 | } |
10109 | 10026 | ||
10110 | if (p-xxreadtoken_chars >= xxreadtoken_singles) { | 10027 | if (p - xxreadtoken_chars >= xxreadtoken_singles) { |
10111 | if (pgetc() == *p) { /* double occurrence? */ | 10028 | if (pgetc() == *p) { /* double occurrence? */ |
10112 | p += xxreadtoken_doubles + 1; | 10029 | p += xxreadtoken_doubles + 1; |
10113 | } else { | 10030 | } else { |
10114 | pungetc(); | 10031 | pungetc(); |
@@ -10116,7 +10033,7 @@ xxreadtoken() { | |||
10116 | } | 10033 | } |
10117 | } | 10034 | } |
10118 | 10035 | ||
10119 | return lasttoken = xxreadtoken_tokens[p-xxreadtoken_chars]; | 10036 | return lasttoken = xxreadtoken_tokens[p - xxreadtoken_chars]; |
10120 | } | 10037 | } |
10121 | } | 10038 | } |
10122 | } | 10039 | } |
@@ -10126,8 +10043,8 @@ xxreadtoken() { | |||
10126 | #else | 10043 | #else |
10127 | #define RETURN(token) return lasttoken = token | 10044 | #define RETURN(token) return lasttoken = token |
10128 | 10045 | ||
10129 | static int | 10046 | static int xxreadtoken() |
10130 | xxreadtoken() { | 10047 | { |
10131 | int c; | 10048 | int c; |
10132 | 10049 | ||
10133 | if (tokpushback) { | 10050 | if (tokpushback) { |
@@ -10139,10 +10056,11 @@ xxreadtoken() { | |||
10139 | needprompt = 0; | 10056 | needprompt = 0; |
10140 | } | 10057 | } |
10141 | startlinno = plinno; | 10058 | startlinno = plinno; |
10142 | for (;;) { /* until token or start of word found */ | 10059 | for (;;) { /* until token or start of word found */ |
10143 | c = pgetc_macro(); | 10060 | c = pgetc_macro(); |
10144 | switch (c) { | 10061 | switch (c) { |
10145 | case ' ': case '\t': | 10062 | case ' ': |
10063 | case '\t': | ||
10146 | #ifdef CONFIG_ASH_ALIAS | 10064 | #ifdef CONFIG_ASH_ALIAS |
10147 | case PEOA: | 10065 | case PEOA: |
10148 | #endif | 10066 | #endif |
@@ -10191,8 +10109,8 @@ xxreadtoken() { | |||
10191 | goto breakloop; | 10109 | goto breakloop; |
10192 | } | 10110 | } |
10193 | } | 10111 | } |
10194 | breakloop: | 10112 | breakloop: |
10195 | return readtoken1(c, BASESYNTAX, (char *)NULL, 0); | 10113 | return readtoken1(c, BASESYNTAX, (char *) NULL, 0); |
10196 | #undef RETURN | 10114 | #undef RETURN |
10197 | } | 10115 | } |
10198 | #endif | 10116 | #endif |
@@ -10226,12 +10144,13 @@ readtoken1(int firstc, int syntax, const char *eofmark, int striptabs) | |||
10226 | struct nodelist *bqlist; | 10144 | struct nodelist *bqlist; |
10227 | int quotef; | 10145 | int quotef; |
10228 | int dblquote; | 10146 | int dblquote; |
10229 | int varnest; /* levels of variables expansion */ | 10147 | int varnest; /* levels of variables expansion */ |
10230 | int arinest; /* levels of arithmetic expansion */ | 10148 | int arinest; /* levels of arithmetic expansion */ |
10231 | int parenlevel; /* levels of parens in arithmetic */ | 10149 | int parenlevel; /* levels of parens in arithmetic */ |
10232 | int dqvarnest; /* levels of variables expansion within double quotes */ | 10150 | int dqvarnest; /* levels of variables expansion within double quotes */ |
10233 | int oldstyle; | 10151 | int oldstyle; |
10234 | int prevsyntax; /* syntax before arithmetic */ | 10152 | int prevsyntax; /* syntax before arithmetic */ |
10153 | |||
10235 | #if __GNUC__ | 10154 | #if __GNUC__ |
10236 | /* Avoid longjmp clobbering */ | 10155 | /* Avoid longjmp clobbering */ |
10237 | (void) &out; | 10156 | (void) &out; |
@@ -10258,14 +10177,14 @@ readtoken1(int firstc, int syntax, const char *eofmark, int striptabs) | |||
10258 | dqvarnest = 0; | 10177 | dqvarnest = 0; |
10259 | 10178 | ||
10260 | STARTSTACKSTR(out); | 10179 | STARTSTACKSTR(out); |
10261 | loop: { /* for each line, until end of word */ | 10180 | loop:{ /* for each line, until end of word */ |
10262 | CHECKEND(); /* set c to PEOF if at end of here document */ | 10181 | CHECKEND(); /* set c to PEOF if at end of here document */ |
10263 | for (;;) { /* until end of line or end of word */ | 10182 | for (;;) { /* until end of line or end of word */ |
10264 | CHECKSTRSPACE(3, out); /* permit 3 calls to USTPUTC */ | 10183 | CHECKSTRSPACE(3, out); /* permit 3 calls to USTPUTC */ |
10265 | switch(SIT(c,syntax)) { | 10184 | switch (SIT(c, syntax)) { |
10266 | case CNL: /* '\n' */ | 10185 | case CNL: /* '\n' */ |
10267 | if (syntax == BASESYNTAX) | 10186 | if (syntax == BASESYNTAX) |
10268 | goto endword; /* exit outer loop */ | 10187 | goto endword; /* exit outer loop */ |
10269 | USTPUTC(c, out); | 10188 | USTPUTC(c, out); |
10270 | plinno++; | 10189 | plinno++; |
10271 | if (doprompt) | 10190 | if (doprompt) |
@@ -10273,17 +10192,16 @@ readtoken1(int firstc, int syntax, const char *eofmark, int striptabs) | |||
10273 | else | 10192 | else |
10274 | setprompt(0); | 10193 | setprompt(0); |
10275 | c = pgetc(); | 10194 | c = pgetc(); |
10276 | goto loop; /* continue outer loop */ | 10195 | goto loop; /* continue outer loop */ |
10277 | case CWORD: | 10196 | case CWORD: |
10278 | USTPUTC(c, out); | 10197 | USTPUTC(c, out); |
10279 | break; | 10198 | break; |
10280 | case CCTL: | 10199 | case CCTL: |
10281 | if ((eofmark == NULL || dblquote) && | 10200 | if ((eofmark == NULL || dblquote) && dqvarnest == 0) |
10282 | dqvarnest == 0) | ||
10283 | USTPUTC(CTLESC, out); | 10201 | USTPUTC(CTLESC, out); |
10284 | USTPUTC(c, out); | 10202 | USTPUTC(c, out); |
10285 | break; | 10203 | break; |
10286 | case CBACK: /* backslash */ | 10204 | case CBACK: /* backslash */ |
10287 | c = pgetc2(); | 10205 | c = pgetc2(); |
10288 | if (c == PEOF) { | 10206 | if (c == PEOF) { |
10289 | USTPUTC('\\', out); | 10207 | USTPUTC('\\', out); |
@@ -10295,9 +10213,9 @@ readtoken1(int firstc, int syntax, const char *eofmark, int striptabs) | |||
10295 | setprompt(0); | 10213 | setprompt(0); |
10296 | } else { | 10214 | } else { |
10297 | if (dblquote && c != '\\' && c != '`' && c != '$' | 10215 | if (dblquote && c != '\\' && c != '`' && c != '$' |
10298 | && (c != '"' || eofmark != NULL)) | 10216 | && (c != '"' || eofmark != NULL)) |
10299 | USTPUTC('\\', out); | 10217 | USTPUTC('\\', out); |
10300 | if (SIT(c,SQSYNTAX) == CCTL) | 10218 | if (SIT(c, SQSYNTAX) == CCTL) |
10301 | USTPUTC(CTLESC, out); | 10219 | USTPUTC(CTLESC, out); |
10302 | else if (eofmark == NULL) | 10220 | else if (eofmark == NULL) |
10303 | USTPUTC(CTLQUOTEMARK, out); | 10221 | USTPUTC(CTLQUOTEMARK, out); |
@@ -10317,25 +10235,23 @@ readtoken1(int firstc, int syntax, const char *eofmark, int striptabs) | |||
10317 | dblquote = 1; | 10235 | dblquote = 1; |
10318 | break; | 10236 | break; |
10319 | case CENDQUOTE: | 10237 | case CENDQUOTE: |
10320 | if (eofmark != NULL && arinest == 0 && | 10238 | if (eofmark != NULL && arinest == 0 && varnest == 0) { |
10321 | varnest == 0) { | ||
10322 | USTPUTC(c, out); | 10239 | USTPUTC(c, out); |
10323 | } else { | 10240 | } else { |
10324 | if (arinest) { | 10241 | if (arinest) { |
10325 | syntax = ARISYNTAX; | 10242 | syntax = ARISYNTAX; |
10326 | dblquote = 0; | 10243 | dblquote = 0; |
10327 | } else if (eofmark == NULL && | 10244 | } else if (eofmark == NULL && dqvarnest == 0) { |
10328 | dqvarnest == 0) { | ||
10329 | syntax = BASESYNTAX; | 10245 | syntax = BASESYNTAX; |
10330 | dblquote = 0; | 10246 | dblquote = 0; |
10331 | } | 10247 | } |
10332 | quotef++; | 10248 | quotef++; |
10333 | } | 10249 | } |
10334 | break; | 10250 | break; |
10335 | case CVAR: /* '$' */ | 10251 | case CVAR: /* '$' */ |
10336 | PARSESUB(); /* parse substitution */ | 10252 | PARSESUB(); /* parse substitution */ |
10337 | break; | 10253 | break; |
10338 | case CENDVAR: /* '}' */ | 10254 | case CENDVAR: /* '}' */ |
10339 | if (varnest > 0) { | 10255 | if (varnest > 0) { |
10340 | varnest--; | 10256 | varnest--; |
10341 | if (dqvarnest > 0) { | 10257 | if (dqvarnest > 0) { |
@@ -10347,11 +10263,11 @@ readtoken1(int firstc, int syntax, const char *eofmark, int striptabs) | |||
10347 | } | 10263 | } |
10348 | break; | 10264 | break; |
10349 | #ifdef CONFIG_ASH_MATH_SUPPORT | 10265 | #ifdef CONFIG_ASH_MATH_SUPPORT |
10350 | case CLP: /* '(' in arithmetic */ | 10266 | case CLP: /* '(' in arithmetic */ |
10351 | parenlevel++; | 10267 | parenlevel++; |
10352 | USTPUTC(c, out); | 10268 | USTPUTC(c, out); |
10353 | break; | 10269 | break; |
10354 | case CRP: /* ')' in arithmetic */ | 10270 | case CRP: /* ')' in arithmetic */ |
10355 | if (parenlevel > 0) { | 10271 | if (parenlevel > 0) { |
10356 | USTPUTC(c, out); | 10272 | USTPUTC(c, out); |
10357 | --parenlevel; | 10273 | --parenlevel; |
@@ -10377,16 +10293,16 @@ readtoken1(int firstc, int syntax, const char *eofmark, int striptabs) | |||
10377 | } | 10293 | } |
10378 | break; | 10294 | break; |
10379 | #endif | 10295 | #endif |
10380 | case CBQUOTE: /* '`' */ | 10296 | case CBQUOTE: /* '`' */ |
10381 | PARSEBACKQOLD(); | 10297 | PARSEBACKQOLD(); |
10382 | break; | 10298 | break; |
10383 | case CENDFILE: | 10299 | case CENDFILE: |
10384 | goto endword; /* exit outer loop */ | 10300 | goto endword; /* exit outer loop */ |
10385 | case CIGN: | 10301 | case CIGN: |
10386 | break; | 10302 | break; |
10387 | default: | 10303 | default: |
10388 | if (varnest == 0) | 10304 | if (varnest == 0) |
10389 | goto endword; /* exit outer loop */ | 10305 | goto endword; /* exit outer loop */ |
10390 | #ifdef CONFIG_ASH_ALIAS | 10306 | #ifdef CONFIG_ASH_ALIAS |
10391 | if (c != PEOA) | 10307 | if (c != PEOA) |
10392 | #endif | 10308 | #endif |
@@ -10396,10 +10312,10 @@ readtoken1(int firstc, int syntax, const char *eofmark, int striptabs) | |||
10396 | c = pgetc_macro(); | 10312 | c = pgetc_macro(); |
10397 | } | 10313 | } |
10398 | } | 10314 | } |
10399 | endword: | 10315 | endword: |
10400 | if (syntax == ARISYNTAX) | 10316 | if (syntax == ARISYNTAX) |
10401 | synerror("Missing '))'"); | 10317 | synerror("Missing '))'"); |
10402 | if (syntax != BASESYNTAX && ! parsebackquote && eofmark == NULL) | 10318 | if (syntax != BASESYNTAX && !parsebackquote && eofmark == NULL) |
10403 | synerror("Unterminated quoted string"); | 10319 | synerror("Unterminated quoted string"); |
10404 | if (varnest != 0) { | 10320 | if (varnest != 0) { |
10405 | startlinno = plinno; | 10321 | startlinno = plinno; |
@@ -10410,9 +10326,7 @@ endword: | |||
10410 | out = stackblock(); | 10326 | out = stackblock(); |
10411 | if (eofmark == NULL) { | 10327 | if (eofmark == NULL) { |
10412 | if ((c == '>' || c == '<') | 10328 | if ((c == '>' || c == '<') |
10413 | && quotef == 0 | 10329 | && quotef == 0 && len <= 2 && (*out == '\0' || is_digit(*out))) { |
10414 | && len <= 2 | ||
10415 | && (*out == '\0' || is_digit(*out))) { | ||
10416 | PARSEREDIR(); | 10330 | PARSEREDIR(); |
10417 | return lasttoken = TREDIR; | 10331 | return lasttoken = TREDIR; |
10418 | } else { | 10332 | } else { |
@@ -10434,36 +10348,36 @@ endword: | |||
10434 | * we are at the end of the here document, this routine sets the c to PEOF. | 10348 | * we are at the end of the here document, this routine sets the c to PEOF. |
10435 | */ | 10349 | */ |
10436 | 10350 | ||
10437 | checkend: { | 10351 | checkend:{ |
10438 | if (eofmark) { | 10352 | if (eofmark) { |
10439 | #ifdef CONFIG_ASH_ALIAS | 10353 | #ifdef CONFIG_ASH_ALIAS |
10440 | if (c == PEOA) { | 10354 | if (c == PEOA) { |
10441 | c = pgetc2(); | ||
10442 | } | ||
10443 | #endif | ||
10444 | if (striptabs) { | ||
10445 | while (c == '\t') { | ||
10446 | c = pgetc2(); | 10355 | c = pgetc2(); |
10447 | } | 10356 | } |
10448 | } | 10357 | #endif |
10449 | if (c == *eofmark) { | 10358 | if (striptabs) { |
10450 | if (pfgets(line, sizeof line) != NULL) { | 10359 | while (c == '\t') { |
10451 | const char *p, *q; | 10360 | c = pgetc2(); |
10452 | 10361 | } | |
10453 | p = line; | 10362 | } |
10454 | for (q = eofmark + 1 ; *q && *p == *q ; p++, q++); | 10363 | if (c == *eofmark) { |
10455 | if (*p == '\n' && *q == '\0') { | 10364 | if (pfgets(line, sizeof line) != NULL) { |
10456 | c = PEOF; | 10365 | const char *p, *q; |
10457 | plinno++; | 10366 | |
10458 | needprompt = doprompt; | 10367 | p = line; |
10459 | } else { | 10368 | for (q = eofmark + 1; *q && *p == *q; p++, q++); |
10460 | pushstring(line, strlen(line), NULL); | 10369 | if (*p == '\n' && *q == '\0') { |
10370 | c = PEOF; | ||
10371 | plinno++; | ||
10372 | needprompt = doprompt; | ||
10373 | } else { | ||
10374 | pushstring(line, strlen(line), NULL); | ||
10375 | } | ||
10461 | } | 10376 | } |
10462 | } | 10377 | } |
10463 | } | 10378 | } |
10379 | goto checkend_return; | ||
10464 | } | 10380 | } |
10465 | goto checkend_return; | ||
10466 | } | ||
10467 | 10381 | ||
10468 | 10382 | ||
10469 | /* | 10383 | /* |
@@ -10472,62 +10386,62 @@ checkend: { | |||
10472 | * first character of the redirection operator. | 10386 | * first character of the redirection operator. |
10473 | */ | 10387 | */ |
10474 | 10388 | ||
10475 | parseredir: { | 10389 | parseredir:{ |
10476 | char fd = *out; | 10390 | char fd = *out; |
10477 | union node *np; | 10391 | union node *np; |
10478 | 10392 | ||
10479 | np = (union node *)stalloc(sizeof (struct nfile)); | 10393 | np = (union node *) stalloc(sizeof(struct nfile)); |
10480 | if (c == '>') { | 10394 | if (c == '>') { |
10481 | np->nfile.fd = 1; | 10395 | np->nfile.fd = 1; |
10482 | c = pgetc(); | 10396 | c = pgetc(); |
10483 | if (c == '>') | 10397 | if (c == '>') |
10484 | np->type = NAPPEND; | 10398 | np->type = NAPPEND; |
10485 | else if (c == '&') | 10399 | else if (c == '&') |
10486 | np->type = NTOFD; | 10400 | np->type = NTOFD; |
10487 | else if (c == '|') | 10401 | else if (c == '|') |
10488 | np->type = NTOOV; | 10402 | np->type = NTOOV; |
10489 | else { | 10403 | else { |
10490 | np->type = NTO; | 10404 | np->type = NTO; |
10491 | pungetc(); | ||
10492 | } | ||
10493 | } else { /* c == '<' */ | ||
10494 | np->nfile.fd = 0; | ||
10495 | switch (c = pgetc()) { | ||
10496 | case '<': | ||
10497 | if (sizeof (struct nfile) != sizeof (struct nhere)) { | ||
10498 | np = (union node *)stalloc(sizeof (struct nhere)); | ||
10499 | np->nfile.fd = 0; | ||
10500 | } | ||
10501 | np->type = NHERE; | ||
10502 | heredoc = (struct heredoc *)stalloc(sizeof (struct heredoc)); | ||
10503 | heredoc->here = np; | ||
10504 | if ((c = pgetc()) == '-') { | ||
10505 | heredoc->striptabs = 1; | ||
10506 | } else { | ||
10507 | heredoc->striptabs = 0; | ||
10508 | pungetc(); | 10405 | pungetc(); |
10509 | } | 10406 | } |
10510 | break; | 10407 | } else { /* c == '<' */ |
10408 | np->nfile.fd = 0; | ||
10409 | switch (c = pgetc()) { | ||
10410 | case '<': | ||
10411 | if (sizeof(struct nfile) != sizeof(struct nhere)) { | ||
10412 | np = (union node *) stalloc(sizeof(struct nhere)); | ||
10413 | np->nfile.fd = 0; | ||
10414 | } | ||
10415 | np->type = NHERE; | ||
10416 | heredoc = (struct heredoc *) stalloc(sizeof(struct heredoc)); | ||
10417 | heredoc->here = np; | ||
10418 | if ((c = pgetc()) == '-') { | ||
10419 | heredoc->striptabs = 1; | ||
10420 | } else { | ||
10421 | heredoc->striptabs = 0; | ||
10422 | pungetc(); | ||
10423 | } | ||
10424 | break; | ||
10511 | 10425 | ||
10512 | case '&': | 10426 | case '&': |
10513 | np->type = NFROMFD; | 10427 | np->type = NFROMFD; |
10514 | break; | 10428 | break; |
10515 | 10429 | ||
10516 | case '>': | 10430 | case '>': |
10517 | np->type = NFROMTO; | 10431 | np->type = NFROMTO; |
10518 | break; | 10432 | break; |
10519 | 10433 | ||
10520 | default: | 10434 | default: |
10521 | np->type = NFROM; | 10435 | np->type = NFROM; |
10522 | pungetc(); | 10436 | pungetc(); |
10523 | break; | 10437 | break; |
10438 | } | ||
10524 | } | 10439 | } |
10440 | if (fd != '\0') | ||
10441 | np->nfile.fd = digit_val(fd); | ||
10442 | redirnode = np; | ||
10443 | goto parseredir_return; | ||
10525 | } | 10444 | } |
10526 | if (fd != '\0') | ||
10527 | np->nfile.fd = digit_val(fd); | ||
10528 | redirnode = np; | ||
10529 | goto parseredir_return; | ||
10530 | } | ||
10531 | 10445 | ||
10532 | 10446 | ||
10533 | /* | 10447 | /* |
@@ -10535,81 +10449,76 @@ parseredir: { | |||
10535 | * and nothing else. | 10449 | * and nothing else. |
10536 | */ | 10450 | */ |
10537 | 10451 | ||
10538 | parsesub: { | 10452 | parsesub:{ |
10539 | int subtype; | 10453 | int subtype; |
10540 | int typeloc; | 10454 | int typeloc; |
10541 | int flags; | 10455 | int flags; |
10542 | char *p; | 10456 | char *p; |
10543 | static const char types[] = "}-+?="; | 10457 | static const char types[] = "}-+?="; |
10544 | 10458 | ||
10545 | c = pgetc(); | 10459 | c = pgetc(); |
10546 | if ( | 10460 | if (c <= PEOA || |
10547 | c <= PEOA || | 10461 | (c != '(' && c != '{' && !is_name(c) && !is_special(c)) |
10548 | (c != '(' && c != '{' && !is_name(c) && !is_special(c)) | 10462 | ) { |
10549 | ) { | 10463 | USTPUTC('$', out); |
10550 | USTPUTC('$', out); | ||
10551 | pungetc(); | ||
10552 | } else if (c == '(') { /* $(command) or $((arith)) */ | ||
10553 | if (pgetc() == '(') { | ||
10554 | PARSEARITH(); | ||
10555 | } else { | ||
10556 | pungetc(); | 10464 | pungetc(); |
10557 | PARSEBACKQNEW(); | 10465 | } else if (c == '(') { /* $(command) or $((arith)) */ |
10558 | } | 10466 | if (pgetc() == '(') { |
10559 | } else { | 10467 | PARSEARITH(); |
10560 | USTPUTC(CTLVAR, out); | 10468 | } else { |
10561 | typeloc = out - stackblock(); | 10469 | pungetc(); |
10562 | USTPUTC(VSNORMAL, out); | 10470 | PARSEBACKQNEW(); |
10563 | subtype = VSNORMAL; | ||
10564 | if (c == '{') { | ||
10565 | c = pgetc(); | ||
10566 | if (c == '#') { | ||
10567 | if ((c = pgetc()) == '}') | ||
10568 | c = '#'; | ||
10569 | else | ||
10570 | subtype = VSLENGTH; | ||
10571 | } | 10471 | } |
10572 | else | 10472 | } else { |
10573 | subtype = 0; | 10473 | USTPUTC(CTLVAR, out); |
10574 | } | 10474 | typeloc = out - stackblock(); |
10575 | if (c > PEOA && is_name(c)) { | 10475 | USTPUTC(VSNORMAL, out); |
10576 | do { | 10476 | subtype = VSNORMAL; |
10577 | STPUTC(c, out); | 10477 | if (c == '{') { |
10578 | c = pgetc(); | 10478 | c = pgetc(); |
10579 | } while (c > PEOA && is_in_name(c)); | 10479 | if (c == '#') { |
10580 | } else if (is_digit(c)) { | 10480 | if ((c = pgetc()) == '}') |
10581 | do { | 10481 | c = '#'; |
10482 | else | ||
10483 | subtype = VSLENGTH; | ||
10484 | } else | ||
10485 | subtype = 0; | ||
10486 | } | ||
10487 | if (c > PEOA && is_name(c)) { | ||
10488 | do { | ||
10489 | STPUTC(c, out); | ||
10490 | c = pgetc(); | ||
10491 | } while (c > PEOA && is_in_name(c)); | ||
10492 | } else if (is_digit(c)) { | ||
10493 | do { | ||
10494 | USTPUTC(c, out); | ||
10495 | c = pgetc(); | ||
10496 | } while (is_digit(c)); | ||
10497 | } else if (is_special(c)) { | ||
10582 | USTPUTC(c, out); | 10498 | USTPUTC(c, out); |
10583 | c = pgetc(); | 10499 | c = pgetc(); |
10584 | } while (is_digit(c)); | 10500 | } else |
10585 | } | 10501 | badsub:synerror("Bad substitution"); |
10586 | else if (is_special(c)) { | 10502 | |
10587 | USTPUTC(c, out); | 10503 | STPUTC('=', out); |
10588 | c = pgetc(); | 10504 | flags = 0; |
10589 | } | 10505 | if (subtype == 0) { |
10590 | else | 10506 | switch (c) { |
10591 | badsub: synerror("Bad substitution"); | 10507 | case ':': |
10592 | 10508 | flags = VSNUL; | |
10593 | STPUTC('=', out); | 10509 | c = pgetc(); |
10594 | flags = 0; | 10510 | /*FALLTHROUGH*/ default: |
10595 | if (subtype == 0) { | 10511 | p = strchr(types, c); |
10596 | switch (c) { | 10512 | if (p == NULL) |
10597 | case ':': | 10513 | goto badsub; |
10598 | flags = VSNUL; | 10514 | subtype = p - types + VSNORMAL; |
10599 | c = pgetc(); | 10515 | break; |
10600 | /*FALLTHROUGH*/ | 10516 | case '%': |
10601 | default: | 10517 | case '#': |
10602 | p = strchr(types, c); | ||
10603 | if (p == NULL) | ||
10604 | goto badsub; | ||
10605 | subtype = p - types + VSNORMAL; | ||
10606 | break; | ||
10607 | case '%': | ||
10608 | case '#': | ||
10609 | { | 10518 | { |
10610 | int cc = c; | 10519 | int cc = c; |
10611 | subtype = c == '#' ? VSTRIMLEFT : | 10520 | |
10612 | VSTRIMRIGHT; | 10521 | subtype = c == '#' ? VSTRIMLEFT : VSTRIMRIGHT; |
10613 | c = pgetc(); | 10522 | c = pgetc(); |
10614 | if (c == cc) | 10523 | if (c == cc) |
10615 | subtype++; | 10524 | subtype++; |
@@ -10617,22 +10526,22 @@ badsub: synerror("Bad substitution"); | |||
10617 | pungetc(); | 10526 | pungetc(); |
10618 | break; | 10527 | break; |
10619 | } | 10528 | } |
10529 | } | ||
10530 | } else { | ||
10531 | pungetc(); | ||
10620 | } | 10532 | } |
10621 | } else { | 10533 | if (dblquote || arinest) |
10622 | pungetc(); | 10534 | flags |= VSQUOTE; |
10623 | } | 10535 | *(stackblock() + typeloc) = subtype | flags; |
10624 | if (dblquote || arinest) | 10536 | if (subtype != VSNORMAL) { |
10625 | flags |= VSQUOTE; | 10537 | varnest++; |
10626 | *(stackblock() + typeloc) = subtype | flags; | 10538 | if (dblquote) { |
10627 | if (subtype != VSNORMAL) { | 10539 | dqvarnest++; |
10628 | varnest++; | 10540 | } |
10629 | if (dblquote) { | ||
10630 | dqvarnest++; | ||
10631 | } | 10541 | } |
10632 | } | 10542 | } |
10543 | goto parsesub_return; | ||
10633 | } | 10544 | } |
10634 | goto parsesub_return; | ||
10635 | } | ||
10636 | 10545 | ||
10637 | 10546 | ||
10638 | /* | 10547 | /* |
@@ -10642,181 +10551,182 @@ badsub: synerror("Bad substitution"); | |||
10642 | * characters on the top of the stack which must be preserved. | 10551 | * characters on the top of the stack which must be preserved. |
10643 | */ | 10552 | */ |
10644 | 10553 | ||
10645 | parsebackq: { | 10554 | parsebackq:{ |
10646 | struct nodelist **nlpp; | 10555 | struct nodelist **nlpp; |
10647 | int savepbq; | 10556 | int savepbq; |
10648 | union node *n; | 10557 | union node *n; |
10649 | char *volatile str; | 10558 | char *volatile str; |
10650 | struct jmploc jmploc; | 10559 | struct jmploc jmploc; |
10651 | struct jmploc *volatile savehandler; | 10560 | struct jmploc *volatile savehandler; |
10652 | int savelen; | 10561 | int savelen; |
10653 | int saveprompt; | 10562 | int saveprompt; |
10563 | |||
10654 | #ifdef __GNUC__ | 10564 | #ifdef __GNUC__ |
10655 | (void) &saveprompt; | 10565 | (void) &saveprompt; |
10656 | #endif | 10566 | #endif |
10657 | 10567 | ||
10658 | savepbq = parsebackquote; | 10568 | savepbq = parsebackquote; |
10659 | if (setjmp(jmploc.loc)) { | 10569 | if (setjmp(jmploc.loc)) { |
10660 | free(str); | 10570 | free(str); |
10661 | parsebackquote = 0; | 10571 | parsebackquote = 0; |
10662 | handler = savehandler; | 10572 | handler = savehandler; |
10663 | longjmp(handler->loc, 1); | 10573 | longjmp(handler->loc, 1); |
10664 | } | 10574 | } |
10665 | INTOFF; | 10575 | INTOFF; |
10666 | str = NULL; | 10576 | str = NULL; |
10667 | savelen = out - stackblock(); | 10577 | savelen = out - stackblock(); |
10668 | if (savelen > 0) { | 10578 | if (savelen > 0) { |
10669 | str = xmalloc(savelen); | 10579 | str = xmalloc(savelen); |
10670 | memcpy(str, stackblock(), savelen); | 10580 | memcpy(str, stackblock(), savelen); |
10671 | } | 10581 | } |
10672 | savehandler = handler; | 10582 | savehandler = handler; |
10673 | handler = &jmploc; | 10583 | handler = &jmploc; |
10674 | INTON; | 10584 | INTON; |
10675 | if (oldstyle) { | 10585 | if (oldstyle) { |
10676 | /* We must read until the closing backquote, giving special | 10586 | /* We must read until the closing backquote, giving special |
10677 | treatment to some slashes, and then push the string and | 10587 | treatment to some slashes, and then push the string and |
10678 | reread it as input, interpreting it normally. */ | 10588 | reread it as input, interpreting it normally. */ |
10679 | char *pout; | 10589 | char *pout; |
10680 | int pc; | 10590 | int pc; |
10681 | int psavelen; | 10591 | int psavelen; |
10682 | char *pstr; | 10592 | char *pstr; |
10683 | |||
10684 | 10593 | ||
10685 | STARTSTACKSTR(pout); | ||
10686 | for (;;) { | ||
10687 | if (needprompt) { | ||
10688 | setprompt(2); | ||
10689 | needprompt = 0; | ||
10690 | } | ||
10691 | switch (pc = pgetc()) { | ||
10692 | case '`': | ||
10693 | goto done; | ||
10694 | 10594 | ||
10695 | case '\\': | 10595 | STARTSTACKSTR(pout); |
10696 | if ((pc = pgetc()) == '\n') { | 10596 | for (;;) { |
10697 | plinno++; | 10597 | if (needprompt) { |
10698 | if (doprompt) | 10598 | setprompt(2); |
10699 | setprompt(2); | 10599 | needprompt = 0; |
10700 | else | ||
10701 | setprompt(0); | ||
10702 | /* | ||
10703 | * If eating a newline, avoid putting | ||
10704 | * the newline into the new character | ||
10705 | * stream (via the STPUTC after the | ||
10706 | * switch). | ||
10707 | */ | ||
10708 | continue; | ||
10709 | } | ||
10710 | if (pc != '\\' && pc != '`' && pc != '$' | ||
10711 | && (!dblquote || pc != '"')) | ||
10712 | STPUTC('\\', pout); | ||
10713 | if (pc > PEOA) { | ||
10714 | break; | ||
10715 | } | 10600 | } |
10716 | /* fall through */ | 10601 | switch (pc = pgetc()) { |
10602 | case '`': | ||
10603 | goto done; | ||
10604 | |||
10605 | case '\\': | ||
10606 | if ((pc = pgetc()) == '\n') { | ||
10607 | plinno++; | ||
10608 | if (doprompt) | ||
10609 | setprompt(2); | ||
10610 | else | ||
10611 | setprompt(0); | ||
10612 | /* | ||
10613 | * If eating a newline, avoid putting | ||
10614 | * the newline into the new character | ||
10615 | * stream (via the STPUTC after the | ||
10616 | * switch). | ||
10617 | */ | ||
10618 | continue; | ||
10619 | } | ||
10620 | if (pc != '\\' && pc != '`' && pc != '$' | ||
10621 | && (!dblquote || pc != '"')) | ||
10622 | STPUTC('\\', pout); | ||
10623 | if (pc > PEOA) { | ||
10624 | break; | ||
10625 | } | ||
10626 | /* fall through */ | ||
10717 | 10627 | ||
10718 | case PEOF: | 10628 | case PEOF: |
10719 | #ifdef CONFIG_ASH_ALIAS | 10629 | #ifdef CONFIG_ASH_ALIAS |
10720 | case PEOA: | 10630 | case PEOA: |
10721 | #endif | 10631 | #endif |
10722 | startlinno = plinno; | 10632 | startlinno = plinno; |
10723 | synerror("EOF in backquote substitution"); | 10633 | synerror("EOF in backquote substitution"); |
10724 | 10634 | ||
10725 | case '\n': | 10635 | case '\n': |
10726 | plinno++; | 10636 | plinno++; |
10727 | needprompt = doprompt; | 10637 | needprompt = doprompt; |
10728 | break; | 10638 | break; |
10729 | 10639 | ||
10730 | default: | 10640 | default: |
10731 | break; | 10641 | break; |
10642 | } | ||
10643 | STPUTC(pc, pout); | ||
10644 | } | ||
10645 | done: | ||
10646 | STPUTC('\0', pout); | ||
10647 | psavelen = pout - stackblock(); | ||
10648 | if (psavelen > 0) { | ||
10649 | pstr = grabstackstr(pout); | ||
10650 | setinputstring(pstr); | ||
10732 | } | 10651 | } |
10733 | STPUTC(pc, pout); | ||
10734 | } | ||
10735 | done: | ||
10736 | STPUTC('\0', pout); | ||
10737 | psavelen = pout - stackblock(); | ||
10738 | if (psavelen > 0) { | ||
10739 | pstr = grabstackstr(pout); | ||
10740 | setinputstring(pstr); | ||
10741 | } | 10652 | } |
10742 | } | 10653 | nlpp = &bqlist; |
10743 | nlpp = &bqlist; | 10654 | while (*nlpp) |
10744 | while (*nlpp) | 10655 | nlpp = &(*nlpp)->next; |
10745 | nlpp = &(*nlpp)->next; | 10656 | *nlpp = (struct nodelist *) stalloc(sizeof(struct nodelist)); |
10746 | *nlpp = (struct nodelist *)stalloc(sizeof (struct nodelist)); | 10657 | (*nlpp)->next = NULL; |
10747 | (*nlpp)->next = NULL; | 10658 | parsebackquote = oldstyle; |
10748 | parsebackquote = oldstyle; | ||
10749 | 10659 | ||
10750 | if (oldstyle) { | 10660 | if (oldstyle) { |
10751 | saveprompt = doprompt; | 10661 | saveprompt = doprompt; |
10752 | doprompt = 0; | 10662 | doprompt = 0; |
10753 | } | 10663 | } |
10754 | 10664 | ||
10755 | n = list(0); | 10665 | n = list(0); |
10756 | 10666 | ||
10757 | if (oldstyle) | 10667 | if (oldstyle) |
10758 | doprompt = saveprompt; | 10668 | doprompt = saveprompt; |
10759 | else { | 10669 | else { |
10760 | if (readtoken() != TRP) | 10670 | if (readtoken() != TRP) |
10761 | synexpect(TRP); | 10671 | synexpect(TRP); |
10762 | } | 10672 | } |
10763 | 10673 | ||
10764 | (*nlpp)->n = n; | 10674 | (*nlpp)->n = n; |
10765 | if (oldstyle) { | 10675 | if (oldstyle) { |
10766 | /* | 10676 | /* |
10767 | * Start reading from old file again, ignoring any pushed back | 10677 | * Start reading from old file again, ignoring any pushed back |
10768 | * tokens left from the backquote parsing | 10678 | * tokens left from the backquote parsing |
10769 | */ | 10679 | */ |
10770 | popfile(); | 10680 | popfile(); |
10771 | tokpushback = 0; | 10681 | tokpushback = 0; |
10772 | } | 10682 | } |
10773 | while (stackblocksize() <= savelen) | 10683 | while (stackblocksize() <= savelen) |
10774 | growstackblock(); | 10684 | growstackblock(); |
10775 | STARTSTACKSTR(out); | 10685 | STARTSTACKSTR(out); |
10776 | if (str) { | 10686 | if (str) { |
10777 | memcpy(out, str, savelen); | 10687 | memcpy(out, str, savelen); |
10778 | STADJUST(savelen, out); | 10688 | STADJUST(savelen, out); |
10779 | INTOFF; | 10689 | INTOFF; |
10780 | free(str); | 10690 | free(str); |
10781 | str = NULL; | 10691 | str = NULL; |
10782 | INTON; | 10692 | INTON; |
10693 | } | ||
10694 | parsebackquote = savepbq; | ||
10695 | handler = savehandler; | ||
10696 | if (arinest || dblquote) | ||
10697 | USTPUTC(CTLBACKQ | CTLQUOTE, out); | ||
10698 | else | ||
10699 | USTPUTC(CTLBACKQ, out); | ||
10700 | if (oldstyle) | ||
10701 | goto parsebackq_oldreturn; | ||
10702 | else | ||
10703 | goto parsebackq_newreturn; | ||
10783 | } | 10704 | } |
10784 | parsebackquote = savepbq; | ||
10785 | handler = savehandler; | ||
10786 | if (arinest || dblquote) | ||
10787 | USTPUTC(CTLBACKQ | CTLQUOTE, out); | ||
10788 | else | ||
10789 | USTPUTC(CTLBACKQ, out); | ||
10790 | if (oldstyle) | ||
10791 | goto parsebackq_oldreturn; | ||
10792 | else | ||
10793 | goto parsebackq_newreturn; | ||
10794 | } | ||
10795 | 10705 | ||
10796 | /* | 10706 | /* |
10797 | * Parse an arithmetic expansion (indicate start of one and set state) | 10707 | * Parse an arithmetic expansion (indicate start of one and set state) |
10798 | */ | 10708 | */ |
10799 | parsearith: { | 10709 | parsearith:{ |
10800 | 10710 | ||
10801 | if (++arinest == 1) { | 10711 | if (++arinest == 1) { |
10802 | prevsyntax = syntax; | 10712 | prevsyntax = syntax; |
10803 | syntax = ARISYNTAX; | 10713 | syntax = ARISYNTAX; |
10804 | USTPUTC(CTLARI, out); | 10714 | USTPUTC(CTLARI, out); |
10805 | if (dblquote) | 10715 | if (dblquote) |
10806 | USTPUTC('"',out); | 10716 | USTPUTC('"', out); |
10807 | else | 10717 | else |
10808 | USTPUTC(' ',out); | 10718 | USTPUTC(' ', out); |
10809 | } else { | 10719 | } else { |
10810 | /* | 10720 | /* |
10811 | * we collapse embedded arithmetic expansion to | 10721 | * we collapse embedded arithmetic expansion to |
10812 | * parenthesis, which should be equivalent | 10722 | * parenthesis, which should be equivalent |
10813 | */ | 10723 | */ |
10814 | USTPUTC('(', out); | 10724 | USTPUTC('(', out); |
10725 | } | ||
10726 | goto parsearith_return; | ||
10815 | } | 10727 | } |
10816 | goto parsearith_return; | ||
10817 | } | ||
10818 | 10728 | ||
10819 | } /* end of readtoken */ | 10729 | } /* end of readtoken */ |
10820 | 10730 | ||
10821 | 10731 | ||
10822 | /* | 10732 | /* |
@@ -10824,8 +10734,7 @@ parsearith: { | |||
10824 | * or backquotes). | 10734 | * or backquotes). |
10825 | */ | 10735 | */ |
10826 | 10736 | ||
10827 | static int | 10737 | static int noexpand(char *text) |
10828 | noexpand(char *text) | ||
10829 | { | 10738 | { |
10830 | char *p; | 10739 | char *p; |
10831 | char c; | 10740 | char c; |
@@ -10836,7 +10745,7 @@ noexpand(char *text) | |||
10836 | continue; | 10745 | continue; |
10837 | if (c == CTLESC) | 10746 | if (c == CTLESC) |
10838 | p++; | 10747 | p++; |
10839 | else if (SIT(c,BASESYNTAX) == CCTL) | 10748 | else if (SIT(c, BASESYNTAX) == CCTL) |
10840 | return 0; | 10749 | return 0; |
10841 | } | 10750 | } |
10842 | return 1; | 10751 | return 1; |
@@ -10848,16 +10757,15 @@ noexpand(char *text) | |||
10848 | * underscore followed by zero or more letters, underscores, and digits). | 10757 | * underscore followed by zero or more letters, underscores, and digits). |
10849 | */ | 10758 | */ |
10850 | 10759 | ||
10851 | static int | 10760 | static int goodname(const char *name) |
10852 | goodname(const char *name) | ||
10853 | { | 10761 | { |
10854 | const char *p; | 10762 | const char *p; |
10855 | 10763 | ||
10856 | p = name; | 10764 | p = name; |
10857 | if (! is_name(*p)) | 10765 | if (!is_name(*p)) |
10858 | return 0; | 10766 | return 0; |
10859 | while (*++p) { | 10767 | while (*++p) { |
10860 | if (! is_in_name(*p)) | 10768 | if (!is_in_name(*p)) |
10861 | return 0; | 10769 | return 0; |
10862 | } | 10770 | } |
10863 | return 1; | 10771 | return 1; |
@@ -10870,27 +10778,25 @@ goodname(const char *name) | |||
10870 | * occur at this point. | 10778 | * occur at this point. |
10871 | */ | 10779 | */ |
10872 | 10780 | ||
10873 | static void | 10781 | static void synexpect(int token) |
10874 | synexpect(int token) | ||
10875 | { | 10782 | { |
10876 | char msg[64]; | 10783 | char msg[64]; |
10877 | int l; | 10784 | int l; |
10878 | 10785 | ||
10879 | l = sprintf(msg, "%s unexpected", tokname(lasttoken)); | 10786 | l = sprintf(msg, "%s unexpected", tokname(lasttoken)); |
10880 | if (token >= 0) | 10787 | if (token >= 0) |
10881 | sprintf(msg+l, " (expecting %s)", tokname(token)); | 10788 | sprintf(msg + l, " (expecting %s)", tokname(token)); |
10882 | synerror(msg); | 10789 | synerror(msg); |
10883 | /* NOTREACHED */ | 10790 | /* NOTREACHED */ |
10884 | } | 10791 | } |
10885 | 10792 | ||
10886 | 10793 | ||
10887 | static void | 10794 | static void synerror(const char *msg) |
10888 | synerror(const char *msg) | ||
10889 | { | 10795 | { |
10890 | if (commandname) | 10796 | if (commandname) |
10891 | out2fmt("%s: %d: ", commandname, startlinno); | 10797 | out2fmt("%s: %d: ", commandname, startlinno); |
10892 | out2fmt("Syntax error: %s\n", msg); | 10798 | out2fmt("Syntax error: %s\n", msg); |
10893 | error((char *)NULL); | 10799 | error((char *) NULL); |
10894 | /* NOTREACHED */ | 10800 | /* NOTREACHED */ |
10895 | } | 10801 | } |
10896 | 10802 | ||
@@ -10899,21 +10805,21 @@ synerror(const char *msg) | |||
10899 | * called by editline -- any expansions to the prompt | 10805 | * called by editline -- any expansions to the prompt |
10900 | * should be added here. | 10806 | * should be added here. |
10901 | */ | 10807 | */ |
10902 | static void | 10808 | static void setprompt(int whichprompt) |
10903 | setprompt(int whichprompt) | ||
10904 | { | 10809 | { |
10905 | char *prompt; | 10810 | char *prompt; |
10906 | switch (whichprompt) { | 10811 | |
10812 | switch (whichprompt) { | ||
10907 | case 1: | 10813 | case 1: |
10908 | prompt = ps1val(); | 10814 | prompt = ps1val(); |
10909 | break; | 10815 | break; |
10910 | case 2: | 10816 | case 2: |
10911 | prompt = ps2val(); | 10817 | prompt = ps2val(); |
10912 | break; | 10818 | break; |
10913 | default: /* 0 */ | 10819 | default: /* 0 */ |
10914 | prompt = ""; | 10820 | prompt = ""; |
10915 | } | 10821 | } |
10916 | putprompt(prompt); | 10822 | putprompt(prompt); |
10917 | } | 10823 | } |
10918 | 10824 | ||
10919 | 10825 | ||
@@ -10921,9 +10827,9 @@ setprompt(int whichprompt) | |||
10921 | * Code for dealing with input/output redirection. | 10827 | * Code for dealing with input/output redirection. |
10922 | */ | 10828 | */ |
10923 | 10829 | ||
10924 | #define EMPTY -2 /* marks an unused slot in redirtab */ | 10830 | #define EMPTY -2 /* marks an unused slot in redirtab */ |
10925 | #ifndef PIPE_BUF | 10831 | #ifndef PIPE_BUF |
10926 | # define PIPESIZE 4096 /* amount of buffering in a pipe */ | 10832 | # define PIPESIZE 4096 /* amount of buffering in a pipe */ |
10927 | #else | 10833 | #else |
10928 | # define PIPESIZE PIPE_BUF | 10834 | # define PIPESIZE PIPE_BUF |
10929 | #endif | 10835 | #endif |
@@ -10933,8 +10839,7 @@ setprompt(int whichprompt) | |||
10933 | * Open a file in noclobber mode. | 10839 | * Open a file in noclobber mode. |
10934 | * The code was copied from bash. | 10840 | * The code was copied from bash. |
10935 | */ | 10841 | */ |
10936 | static inline int | 10842 | static inline int noclobberopen(const char *fname) |
10937 | noclobberopen(const char *fname) | ||
10938 | { | 10843 | { |
10939 | int r, fd; | 10844 | int r, fd; |
10940 | struct stat finfo, finfo2; | 10845 | struct stat finfo, finfo2; |
@@ -10957,8 +10862,8 @@ noclobberopen(const char *fname) | |||
10957 | * file was not a regular file, we leave O_EXCL off. | 10862 | * file was not a regular file, we leave O_EXCL off. |
10958 | */ | 10863 | */ |
10959 | if (r != 0) | 10864 | if (r != 0) |
10960 | return open(fname, O_WRONLY|O_CREAT|O_EXCL, 0666); | 10865 | return open(fname, O_WRONLY | O_CREAT | O_EXCL, 0666); |
10961 | fd = open(fname, O_WRONLY|O_CREAT, 0666); | 10866 | fd = open(fname, O_WRONLY | O_CREAT, 0666); |
10962 | 10867 | ||
10963 | /* If the open failed, return the file descriptor right away. */ | 10868 | /* If the open failed, return the file descriptor right away. */ |
10964 | if (fd < 0) | 10869 | if (fd < 0) |
@@ -10977,8 +10882,8 @@ noclobberopen(const char *fname) | |||
10977 | * revealed that it was a regular file, and the file has not been | 10882 | * revealed that it was a regular file, and the file has not been |
10978 | * replaced, return the file descriptor. | 10883 | * replaced, return the file descriptor. |
10979 | */ | 10884 | */ |
10980 | if (fstat(fd, &finfo2) == 0 && !S_ISREG(finfo2.st_mode) && | 10885 | if (fstat(fd, &finfo2) == 0 && !S_ISREG(finfo2.st_mode) && |
10981 | finfo.st_dev == finfo2.st_dev && finfo.st_ino == finfo2.st_ino) | 10886 | finfo.st_dev == finfo2.st_dev && finfo.st_ino == finfo2.st_ino) |
10982 | return fd; | 10887 | return fd; |
10983 | 10888 | ||
10984 | /* The file has been replaced. badness. */ | 10889 | /* The file has been replaced. badness. */ |
@@ -10993,8 +10898,7 @@ noclobberopen(const char *fname) | |||
10993 | * the pipe without forking. | 10898 | * the pipe without forking. |
10994 | */ | 10899 | */ |
10995 | 10900 | ||
10996 | static inline int | 10901 | static inline int openhere(const union node *redir) |
10997 | openhere(const union node *redir) | ||
10998 | { | 10902 | { |
10999 | int pip[2]; | 10903 | int pip[2]; |
11000 | int len = 0; | 10904 | int len = 0; |
@@ -11008,7 +10912,7 @@ openhere(const union node *redir) | |||
11008 | goto out; | 10912 | goto out; |
11009 | } | 10913 | } |
11010 | } | 10914 | } |
11011 | if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) { | 10915 | if (forkshell((struct job *) NULL, (union node *) NULL, FORK_NOJOB) == 0) { |
11012 | close(pip[0]); | 10916 | close(pip[0]); |
11013 | signal(SIGINT, SIG_IGN); | 10917 | signal(SIGINT, SIG_IGN); |
11014 | signal(SIGQUIT, SIG_IGN); | 10918 | signal(SIGQUIT, SIG_IGN); |
@@ -11023,14 +10927,13 @@ openhere(const union node *redir) | |||
11023 | expandhere(redir->nhere.doc, pip[1]); | 10927 | expandhere(redir->nhere.doc, pip[1]); |
11024 | _exit(0); | 10928 | _exit(0); |
11025 | } | 10929 | } |
11026 | out: | 10930 | out: |
11027 | close(pip[1]); | 10931 | close(pip[1]); |
11028 | return pip[0]; | 10932 | return pip[0]; |
11029 | } | 10933 | } |
11030 | 10934 | ||
11031 | 10935 | ||
11032 | static inline int | 10936 | static inline int openredirect(const union node *redir) |
11033 | openredirect(const union node *redir) | ||
11034 | { | 10937 | { |
11035 | char *fname; | 10938 | char *fname; |
11036 | int f; | 10939 | int f; |
@@ -11043,7 +10946,7 @@ openredirect(const union node *redir) | |||
11043 | break; | 10946 | break; |
11044 | case NFROMTO: | 10947 | case NFROMTO: |
11045 | fname = redir->nfile.expfname; | 10948 | fname = redir->nfile.expfname; |
11046 | if ((f = open(fname, O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0) | 10949 | if ((f = open(fname, O_RDWR | O_CREAT | O_TRUNC, 0666)) < 0) |
11047 | goto ecreate; | 10950 | goto ecreate; |
11048 | break; | 10951 | break; |
11049 | case NTO: | 10952 | case NTO: |
@@ -11057,7 +10960,7 @@ openredirect(const union node *redir) | |||
11057 | case NTOOV: | 10960 | case NTOOV: |
11058 | fname = redir->nfile.expfname; | 10961 | fname = redir->nfile.expfname; |
11059 | #ifdef O_CREAT | 10962 | #ifdef O_CREAT |
11060 | if ((f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0) | 10963 | if ((f = open(fname, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0) |
11061 | goto ecreate; | 10964 | goto ecreate; |
11062 | #else | 10965 | #else |
11063 | if ((f = creat(fname, 0666)) < 0) | 10966 | if ((f = creat(fname, 0666)) < 0) |
@@ -11067,13 +10970,12 @@ openredirect(const union node *redir) | |||
11067 | case NAPPEND: | 10970 | case NAPPEND: |
11068 | fname = redir->nfile.expfname; | 10971 | fname = redir->nfile.expfname; |
11069 | #ifdef O_APPEND | 10972 | #ifdef O_APPEND |
11070 | if ((f = open(fname, O_WRONLY|O_CREAT|O_APPEND, 0666)) < 0) | 10973 | if ((f = open(fname, O_WRONLY | O_CREAT | O_APPEND, 0666)) < 0) |
11071 | goto ecreate; | 10974 | goto ecreate; |
11072 | #else | 10975 | #else |
11073 | if ((f = open(fname, O_WRONLY)) < 0 | 10976 | if ((f = open(fname, O_WRONLY)) < 0 && (f = creat(fname, 0666)) < 0) |
11074 | && (f = creat(fname, 0666)) < 0) | ||
11075 | goto ecreate; | 10977 | goto ecreate; |
11076 | lseek(f, (off_t)0, 2); | 10978 | lseek(f, (off_t) 0, 2); |
11077 | #endif | 10979 | #endif |
11078 | break; | 10980 | break; |
11079 | default: | 10981 | default: |
@@ -11092,9 +10994,9 @@ openredirect(const union node *redir) | |||
11092 | } | 10994 | } |
11093 | 10995 | ||
11094 | return f; | 10996 | return f; |
11095 | ecreate: | 10997 | ecreate: |
11096 | error("cannot create %s: %s", fname, errmsg(errno, E_CREAT)); | 10998 | error("cannot create %s: %s", fname, errmsg(errno, E_CREAT)); |
11097 | eopen: | 10999 | eopen: |
11098 | error("cannot open %s: %s", fname, errmsg(errno, E_OPEN)); | 11000 | error("cannot open %s: %s", fname, errmsg(errno, E_OPEN)); |
11099 | } | 11001 | } |
11100 | 11002 | ||
@@ -11107,8 +11009,7 @@ eopen: | |||
11107 | * stdout. | 11009 | * stdout. |
11108 | */ | 11010 | */ |
11109 | 11011 | ||
11110 | static void | 11012 | static void redirect(union node *redir, int flags) |
11111 | redirect(union node *redir, int flags) | ||
11112 | { | 11013 | { |
11113 | union node *n; | 11014 | union node *n; |
11114 | struct redirtab *sv = NULL; | 11015 | struct redirtab *sv = NULL; |
@@ -11116,21 +11017,21 @@ redirect(union node *redir, int flags) | |||
11116 | int fd; | 11017 | int fd; |
11117 | int newfd; | 11018 | int newfd; |
11118 | int try; | 11019 | int try; |
11119 | int fd1dup = flags & REDIR_BACKQ;; /* stdout `cmd` redir to pipe */ | 11020 | int fd1dup = flags & REDIR_BACKQ;; /* stdout `cmd` redir to pipe */ |
11120 | 11021 | ||
11121 | if (flags & REDIR_PUSH) { | 11022 | if (flags & REDIR_PUSH) { |
11122 | sv = xmalloc(sizeof (struct redirtab)); | 11023 | sv = xmalloc(sizeof(struct redirtab)); |
11123 | for (i = 0 ; i < 10 ; i++) | 11024 | for (i = 0; i < 10; i++) |
11124 | sv->renamed[i] = EMPTY; | 11025 | sv->renamed[i] = EMPTY; |
11125 | sv->next = redirlist; | 11026 | sv->next = redirlist; |
11126 | redirlist = sv; | 11027 | redirlist = sv; |
11127 | } | 11028 | } |
11128 | for (n = redir ; n ; n = n->nfile.next) { | 11029 | for (n = redir; n; n = n->nfile.next) { |
11129 | fd = n->nfile.fd; | 11030 | fd = n->nfile.fd; |
11130 | try = 0; | 11031 | try = 0; |
11131 | if ((n->nfile.type == NTOFD || n->nfile.type == NFROMFD) && | 11032 | if ((n->nfile.type == NTOFD || n->nfile.type == NFROMFD) && |
11132 | n->ndup.dupfd == fd) | 11033 | n->ndup.dupfd == fd) |
11133 | continue; /* redirect from/to same file descriptor */ | 11034 | continue; /* redirect from/to same file descriptor */ |
11134 | 11035 | ||
11135 | INTOFF; | 11036 | INTOFF; |
11136 | newfd = openredirect(n); | 11037 | newfd = openredirect(n); |
@@ -11145,7 +11046,7 @@ redirect(union node *redir, int flags) | |||
11145 | try++; | 11046 | try++; |
11146 | break; | 11047 | break; |
11147 | } | 11048 | } |
11148 | /* FALLTHROUGH*/ | 11049 | /* FALLTHROUGH */ |
11149 | default: | 11050 | default: |
11150 | if (newfd >= 0) { | 11051 | if (newfd >= 0) { |
11151 | close(newfd); | 11052 | close(newfd); |
@@ -11173,16 +11074,15 @@ redirect(union node *redir, int flags) | |||
11173 | } | 11074 | } |
11174 | 11075 | ||
11175 | 11076 | ||
11176 | static void | 11077 | static void dupredirect(const union node *redir, int f, int fd1dup) |
11177 | dupredirect(const union node *redir, int f, int fd1dup) | ||
11178 | { | 11078 | { |
11179 | int fd = redir->nfile.fd; | 11079 | int fd = redir->nfile.fd; |
11180 | 11080 | ||
11181 | if(fd==1) | 11081 | if (fd == 1) |
11182 | fd1dup = 0; | 11082 | fd1dup = 0; |
11183 | if (redir->nfile.type == NTOFD || redir->nfile.type == NFROMFD) { | 11083 | if (redir->nfile.type == NTOFD || redir->nfile.type == NFROMFD) { |
11184 | if (redir->ndup.dupfd >= 0) { /* if not ">&-" */ | 11084 | if (redir->ndup.dupfd >= 0) { /* if not ">&-" */ |
11185 | if (redir->ndup.dupfd!=1 || fd1dup!=1) | 11085 | if (redir->ndup.dupfd != 1 || fd1dup != 1) |
11186 | dup_as_newfd(redir->ndup.dupfd, fd); | 11086 | dup_as_newfd(redir->ndup.dupfd, fd); |
11187 | } | 11087 | } |
11188 | return; | 11088 | return; |
@@ -11201,14 +11101,13 @@ dupredirect(const union node *redir, int f, int fd1dup) | |||
11201 | * Undo the effects of the last redirection. | 11101 | * Undo the effects of the last redirection. |
11202 | */ | 11102 | */ |
11203 | 11103 | ||
11204 | static void | 11104 | static void popredir(void) |
11205 | popredir(void) | ||
11206 | { | 11105 | { |
11207 | struct redirtab *rp = redirlist; | 11106 | struct redirtab *rp = redirlist; |
11208 | int i; | 11107 | int i; |
11209 | 11108 | ||
11210 | INTOFF; | 11109 | INTOFF; |
11211 | for (i = 0 ; i < 10 ; i++) { | 11110 | for (i = 0; i < 10; i++) { |
11212 | if (rp->renamed[i] != EMPTY) { | 11111 | if (rp->renamed[i] != EMPTY) { |
11213 | if (i == 0) | 11112 | if (i == 0) |
11214 | fd0_redirected--; | 11113 | fd0_redirected--; |
@@ -11228,13 +11127,13 @@ popredir(void) | |||
11228 | * Discard all saved file descriptors. | 11127 | * Discard all saved file descriptors. |
11229 | */ | 11128 | */ |
11230 | 11129 | ||
11231 | static void | 11130 | static void clearredir(void) |
11232 | clearredir(void) { | 11131 | { |
11233 | struct redirtab *rp; | 11132 | struct redirtab *rp; |
11234 | int i; | 11133 | int i; |
11235 | 11134 | ||
11236 | for (rp = redirlist ; rp ; rp = rp->next) { | 11135 | for (rp = redirlist; rp; rp = rp->next) { |
11237 | for (i = 0 ; i < 10 ; i++) { | 11136 | for (i = 0; i < 10; i++) { |
11238 | if (rp->renamed[i] >= 0) { | 11137 | if (rp->renamed[i] >= 0) { |
11239 | close(rp->renamed[i]); | 11138 | close(rp->renamed[i]); |
11240 | } | 11139 | } |
@@ -11250,8 +11149,7 @@ clearredir(void) { | |||
11250 | * file descriptors left. | 11149 | * file descriptors left. |
11251 | */ | 11150 | */ |
11252 | 11151 | ||
11253 | static int | 11152 | static int dup_as_newfd(int from, int to) |
11254 | dup_as_newfd(int from, int to) | ||
11255 | { | 11153 | { |
11256 | int newfd; | 11154 | int newfd; |
11257 | 11155 | ||
@@ -11269,15 +11167,14 @@ dup_as_newfd(int from, int to) | |||
11269 | /* | 11167 | /* |
11270 | * Debugging stuff. | 11168 | * Debugging stuff. |
11271 | */ | 11169 | */ |
11272 | static void shtree (union node *, int, char *, FILE*); | 11170 | static void shtree(union node *, int, char *, FILE *); |
11273 | static void shcmd (union node *, FILE *); | 11171 | static void shcmd(union node *, FILE *); |
11274 | static void sharg (union node *, FILE *); | 11172 | static void sharg(union node *, FILE *); |
11275 | static void indent (int, char *, FILE *); | 11173 | static void indent(int, char *, FILE *); |
11276 | static void trstring (char *); | 11174 | static void trstring(char *); |
11277 | 11175 | ||
11278 | 11176 | ||
11279 | static void | 11177 | static void showtree(n) |
11280 | showtree(n) | ||
11281 | unode *n; | 11178 | unode *n; |
11282 | { | 11179 | { |
11283 | trputs("showtree called\n"); | 11180 | trputs("showtree called\n"); |
@@ -11285,8 +11182,7 @@ showtree(n) | |||
11285 | } | 11182 | } |
11286 | 11183 | ||
11287 | 11184 | ||
11288 | static void | 11185 | static void shtree(union node *n, int ind, char *pfx, FILE * fp) |
11289 | shtree(union node *n, int ind, char *pfx, FILE *fp) | ||
11290 | { | 11186 | { |
11291 | struct nodelist *lp; | 11187 | struct nodelist *lp; |
11292 | const char *s; | 11188 | const char *s; |
@@ -11295,7 +11191,7 @@ shtree(union node *n, int ind, char *pfx, FILE *fp) | |||
11295 | return; | 11191 | return; |
11296 | 11192 | ||
11297 | indent(ind, pfx, fp); | 11193 | indent(ind, pfx, fp); |
11298 | switch(n->type) { | 11194 | switch (n->type) { |
11299 | case NSEMI: | 11195 | case NSEMI: |
11300 | s = "; "; | 11196 | s = "; "; |
11301 | goto binop; | 11197 | goto binop; |
@@ -11304,10 +11200,10 @@ shtree(union node *n, int ind, char *pfx, FILE *fp) | |||
11304 | goto binop; | 11200 | goto binop; |
11305 | case NOR: | 11201 | case NOR: |
11306 | s = " || "; | 11202 | s = " || "; |
11307 | binop: | 11203 | binop: |
11308 | shtree(n->nbinary.ch1, ind, NULL, fp); | 11204 | shtree(n->nbinary.ch1, ind, NULL, fp); |
11309 | /* if (ind < 0) */ | 11205 | /* if (ind < 0) */ |
11310 | fputs(s, fp); | 11206 | fputs(s, fp); |
11311 | shtree(n->nbinary.ch2, ind, NULL, fp); | 11207 | shtree(n->nbinary.ch2, ind, NULL, fp); |
11312 | break; | 11208 | break; |
11313 | case NCMD: | 11209 | case NCMD: |
@@ -11316,7 +11212,7 @@ binop: | |||
11316 | putc('\n', fp); | 11212 | putc('\n', fp); |
11317 | break; | 11213 | break; |
11318 | case NPIPE: | 11214 | case NPIPE: |
11319 | for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) { | 11215 | for (lp = n->npipe.cmdlist; lp; lp = lp->next) { |
11320 | shcmd(lp->n, fp); | 11216 | shcmd(lp->n, fp); |
11321 | if (lp->next) | 11217 | if (lp->next) |
11322 | fputs(" | ", fp); | 11218 | fputs(" | ", fp); |
@@ -11336,8 +11232,7 @@ binop: | |||
11336 | 11232 | ||
11337 | 11233 | ||
11338 | 11234 | ||
11339 | static void | 11235 | static void shcmd(union node *cmd, FILE * fp) |
11340 | shcmd(union node *cmd, FILE *fp) | ||
11341 | { | 11236 | { |
11342 | union node *np; | 11237 | union node *np; |
11343 | int first; | 11238 | int first; |
@@ -11345,14 +11240,14 @@ shcmd(union node *cmd, FILE *fp) | |||
11345 | int dftfd; | 11240 | int dftfd; |
11346 | 11241 | ||
11347 | first = 1; | 11242 | first = 1; |
11348 | for (np = cmd->ncmd.args ; np ; np = np->narg.next) { | 11243 | for (np = cmd->ncmd.args; np; np = np->narg.next) { |
11349 | if (! first) | 11244 | if (!first) |
11350 | putchar(' '); | 11245 | putchar(' '); |
11351 | sharg(np, fp); | 11246 | sharg(np, fp); |
11352 | first = 0; | 11247 | first = 0; |
11353 | } | 11248 | } |
11354 | for (np = cmd->ncmd.redirect ; np ; np = np->nfile.next) { | 11249 | for (np = cmd->ncmd.redirect; np; np = np->nfile.next) { |
11355 | if (! first) | 11250 | if (!first) |
11356 | putchar(' '); | 11251 | putchar(' '); |
11357 | #if 1 | 11252 | #if 1 |
11358 | s = "*error*"; | 11253 | s = "*error*"; |
@@ -11365,14 +11260,38 @@ shcmd(union node *cmd, FILE *fp) | |||
11365 | } | 11260 | } |
11366 | #else | 11261 | #else |
11367 | switch (np->nfile.type) { | 11262 | switch (np->nfile.type) { |
11368 | case NTO: s = ">"; dftfd = 1; break; | 11263 | case NTO: |
11369 | case NAPPEND: s = ">>"; dftfd = 1; break; | 11264 | s = ">"; |
11370 | case NTOFD: s = ">&"; dftfd = 1; break; | 11265 | dftfd = 1; |
11371 | case NTOOV: s = ">|"; dftfd = 1; break; | 11266 | break; |
11372 | case NFROM: s = "<"; dftfd = 0; break; | 11267 | case NAPPEND: |
11373 | case NFROMFD: s = "<&"; dftfd = 0; break; | 11268 | s = ">>"; |
11374 | case NFROMTO: s = "<>"; dftfd = 0; break; | 11269 | dftfd = 1; |
11375 | default: s = "*error*"; dftfd = 0; break; | 11270 | break; |
11271 | case NTOFD: | ||
11272 | s = ">&"; | ||
11273 | dftfd = 1; | ||
11274 | break; | ||
11275 | case NTOOV: | ||
11276 | s = ">|"; | ||
11277 | dftfd = 1; | ||
11278 | break; | ||
11279 | case NFROM: | ||
11280 | s = "<"; | ||
11281 | dftfd = 0; | ||
11282 | break; | ||
11283 | case NFROMFD: | ||
11284 | s = "<&"; | ||
11285 | dftfd = 0; | ||
11286 | break; | ||
11287 | case NFROMTO: | ||
11288 | s = "<>"; | ||
11289 | dftfd = 0; | ||
11290 | break; | ||
11291 | default: | ||
11292 | s = "*error*"; | ||
11293 | dftfd = 0; | ||
11294 | break; | ||
11376 | } | 11295 | } |
11377 | #endif | 11296 | #endif |
11378 | if (np->nfile.fd != dftfd) | 11297 | if (np->nfile.fd != dftfd) |
@@ -11387,8 +11306,7 @@ shcmd(union node *cmd, FILE *fp) | |||
11387 | } | 11306 | } |
11388 | } | 11307 | } |
11389 | 11308 | ||
11390 | static void | 11309 | static void sharg(union node *arg, FILE * fp) |
11391 | sharg(union node *arg, FILE *fp) | ||
11392 | { | 11310 | { |
11393 | char *p; | 11311 | char *p; |
11394 | struct nodelist *bqlist; | 11312 | struct nodelist *bqlist; |
@@ -11400,7 +11318,7 @@ sharg(union node *arg, FILE *fp) | |||
11400 | abort(); | 11318 | abort(); |
11401 | } | 11319 | } |
11402 | bqlist = arg->narg.backquote; | 11320 | bqlist = arg->narg.backquote; |
11403 | for (p = arg->narg.text ; *p ; p++) { | 11321 | for (p = arg->narg.text; *p; p++) { |
11404 | switch (*p) { | 11322 | switch (*p) { |
11405 | case CTLESC: | 11323 | case CTLESC: |
11406 | putc(*++p, fp); | 11324 | putc(*++p, fp); |
@@ -11455,10 +11373,10 @@ sharg(union node *arg, FILE *fp) | |||
11455 | } | 11373 | } |
11456 | break; | 11374 | break; |
11457 | case CTLENDVAR: | 11375 | case CTLENDVAR: |
11458 | putc('}', fp); | 11376 | putc('}', fp); |
11459 | break; | 11377 | break; |
11460 | case CTLBACKQ: | 11378 | case CTLBACKQ: |
11461 | case CTLBACKQ|CTLQUOTE: | 11379 | case CTLBACKQ | CTLQUOTE: |
11462 | putc('$', fp); | 11380 | putc('$', fp); |
11463 | putc('(', fp); | 11381 | putc('(', fp); |
11464 | shtree(bqlist->n, -1, NULL, fp); | 11382 | shtree(bqlist->n, -1, NULL, fp); |
@@ -11472,12 +11390,11 @@ sharg(union node *arg, FILE *fp) | |||
11472 | } | 11390 | } |
11473 | 11391 | ||
11474 | 11392 | ||
11475 | static void | 11393 | static void indent(int amount, char *pfx, FILE * fp) |
11476 | indent(int amount, char *pfx, FILE *fp) | ||
11477 | { | 11394 | { |
11478 | int i; | 11395 | int i; |
11479 | 11396 | ||
11480 | for (i = 0 ; i < amount ; i++) { | 11397 | for (i = 0; i < amount; i++) { |
11481 | if (pfx && i == amount - 1) | 11398 | if (pfx && i == amount - 1) |
11482 | fputs(pfx, fp); | 11399 | fputs(pfx, fp); |
11483 | putc('\t', fp); | 11400 | putc('\t', fp); |
@@ -11494,8 +11411,7 @@ static int debug = 0; | |||
11494 | #endif | 11411 | #endif |
11495 | 11412 | ||
11496 | 11413 | ||
11497 | static void | 11414 | static void trputc(int c) |
11498 | trputc(int c) | ||
11499 | { | 11415 | { |
11500 | if (tracefile == NULL) | 11416 | if (tracefile == NULL) |
11501 | return; | 11417 | return; |
@@ -11504,10 +11420,10 @@ trputc(int c) | |||
11504 | fflush(tracefile); | 11420 | fflush(tracefile); |
11505 | } | 11421 | } |
11506 | 11422 | ||
11507 | static void | 11423 | static void trace(const char *fmt, ...) |
11508 | trace(const char *fmt, ...) | ||
11509 | { | 11424 | { |
11510 | va_list va; | 11425 | va_list va; |
11426 | |||
11511 | va_start(va, fmt); | 11427 | va_start(va, fmt); |
11512 | if (tracefile != NULL) { | 11428 | if (tracefile != NULL) { |
11513 | (void) vfprintf(tracefile, fmt, va); | 11429 | (void) vfprintf(tracefile, fmt, va); |
@@ -11518,8 +11434,7 @@ trace(const char *fmt, ...) | |||
11518 | } | 11434 | } |
11519 | 11435 | ||
11520 | 11436 | ||
11521 | static void | 11437 | static void trputs(const char *s) |
11522 | trputs(const char *s) | ||
11523 | { | 11438 | { |
11524 | if (tracefile == NULL) | 11439 | if (tracefile == NULL) |
11525 | return; | 11440 | return; |
@@ -11529,8 +11444,7 @@ trputs(const char *s) | |||
11529 | } | 11444 | } |
11530 | 11445 | ||
11531 | 11446 | ||
11532 | static void | 11447 | static void trstring(char *s) |
11533 | trstring(char *s) | ||
11534 | { | 11448 | { |
11535 | char *p; | 11449 | char *p; |
11536 | char c; | 11450 | char c; |
@@ -11538,19 +11452,39 @@ trstring(char *s) | |||
11538 | if (tracefile == NULL) | 11452 | if (tracefile == NULL) |
11539 | return; | 11453 | return; |
11540 | putc('"', tracefile); | 11454 | putc('"', tracefile); |
11541 | for (p = s ; *p ; p++) { | 11455 | for (p = s; *p; p++) { |
11542 | switch (*p) { | 11456 | switch (*p) { |
11543 | case '\n': c = 'n'; goto backslash; | 11457 | case '\n': |
11544 | case '\t': c = 't'; goto backslash; | 11458 | c = 'n'; |
11545 | case '\r': c = 'r'; goto backslash; | 11459 | goto backslash; |
11546 | case '"': c = '"'; goto backslash; | 11460 | case '\t': |
11547 | case '\\': c = '\\'; goto backslash; | 11461 | c = 't'; |
11548 | case CTLESC: c = 'e'; goto backslash; | 11462 | goto backslash; |
11549 | case CTLVAR: c = 'v'; goto backslash; | 11463 | case '\r': |
11550 | case CTLVAR+CTLQUOTE: c = 'V'; goto backslash; | 11464 | c = 'r'; |
11551 | case CTLBACKQ: c = 'q'; goto backslash; | 11465 | goto backslash; |
11552 | case CTLBACKQ+CTLQUOTE: c = 'Q'; goto backslash; | 11466 | case '"': |
11553 | backslash: putc('\\', tracefile); | 11467 | c = '"'; |
11468 | goto backslash; | ||
11469 | case '\\': | ||
11470 | c = '\\'; | ||
11471 | goto backslash; | ||
11472 | case CTLESC: | ||
11473 | c = 'e'; | ||
11474 | goto backslash; | ||
11475 | case CTLVAR: | ||
11476 | c = 'v'; | ||
11477 | goto backslash; | ||
11478 | case CTLVAR + CTLQUOTE: | ||
11479 | c = 'V'; | ||
11480 | goto backslash; | ||
11481 | case CTLBACKQ: | ||
11482 | c = 'q'; | ||
11483 | goto backslash; | ||
11484 | case CTLBACKQ + CTLQUOTE: | ||
11485 | c = 'Q'; | ||
11486 | goto backslash; | ||
11487 | backslash:putc('\\', tracefile); | ||
11554 | putc(c, tracefile); | 11488 | putc(c, tracefile); |
11555 | break; | 11489 | break; |
11556 | default: | 11490 | default: |
@@ -11569,8 +11503,7 @@ backslash: putc('\\', tracefile); | |||
11569 | } | 11503 | } |
11570 | 11504 | ||
11571 | 11505 | ||
11572 | static void | 11506 | static void trargs(char **ap) |
11573 | trargs(char **ap) | ||
11574 | { | 11507 | { |
11575 | if (tracefile == NULL) | 11508 | if (tracefile == NULL) |
11576 | return; | 11509 | return; |
@@ -11585,10 +11518,10 @@ trargs(char **ap) | |||
11585 | } | 11518 | } |
11586 | 11519 | ||
11587 | 11520 | ||
11588 | static void | 11521 | static void opentrace() |
11589 | opentrace() | ||
11590 | { | 11522 | { |
11591 | char s[100]; | 11523 | char s[100]; |
11524 | |||
11592 | #ifdef O_APPEND | 11525 | #ifdef O_APPEND |
11593 | int flags; | 11526 | int flags; |
11594 | #endif | 11527 | #endif |
@@ -11598,6 +11531,7 @@ opentrace() | |||
11598 | #ifdef not_this_way | 11531 | #ifdef not_this_way |
11599 | { | 11532 | { |
11600 | char *p; | 11533 | char *p; |
11534 | |||
11601 | if ((p = getenv("HOME")) == NULL) { | 11535 | if ((p = getenv("HOME")) == NULL) { |
11602 | if (geteuid() == 0) | 11536 | if (geteuid() == 0) |
11603 | p = "/"; | 11537 | p = "/"; |
@@ -11609,7 +11543,7 @@ opentrace() | |||
11609 | } | 11543 | } |
11610 | #else | 11544 | #else |
11611 | strcpy(s, "./trace"); | 11545 | strcpy(s, "./trace"); |
11612 | #endif /* not_this_way */ | 11546 | #endif /* not_this_way */ |
11613 | if ((tracefile = wfopen(s, "a")) == NULL) | 11547 | if ((tracefile = wfopen(s, "a")) == NULL) |
11614 | return; | 11548 | return; |
11615 | #ifdef O_APPEND | 11549 | #ifdef O_APPEND |
@@ -11619,31 +11553,30 @@ opentrace() | |||
11619 | fputs("\nTracing started.\n", tracefile); | 11553 | fputs("\nTracing started.\n", tracefile); |
11620 | fflush(tracefile); | 11554 | fflush(tracefile); |
11621 | } | 11555 | } |
11622 | #endif /* DEBUG */ | 11556 | #endif /* DEBUG */ |
11623 | 11557 | ||
11624 | 11558 | ||
11625 | /* | 11559 | /* |
11626 | * The trap builtin. | 11560 | * The trap builtin. |
11627 | */ | 11561 | */ |
11628 | 11562 | ||
11629 | static int | 11563 | static int trapcmd(int argc, char **argv) |
11630 | trapcmd(int argc, char **argv) | ||
11631 | { | 11564 | { |
11632 | char *action; | 11565 | char *action; |
11633 | char **ap; | 11566 | char **ap; |
11634 | int signo; | 11567 | int signo; |
11635 | 11568 | ||
11636 | if (argc <= 1) { | 11569 | if (argc <= 1) { |
11637 | for (signo = 0 ; signo < NSIG ; signo++) { | 11570 | for (signo = 0; signo < NSIG; signo++) { |
11638 | if (trap[signo] != NULL) { | 11571 | if (trap[signo] != NULL) { |
11639 | char *p; | 11572 | char *p; |
11640 | const char *sn; | 11573 | const char *sn; |
11641 | 11574 | ||
11642 | p = single_quote(trap[signo]); | 11575 | p = single_quote(trap[signo]); |
11643 | sn = sys_siglist[signo]; | 11576 | sn = sys_siglist[signo]; |
11644 | if(sn==NULL) | 11577 | if (sn == NULL) |
11645 | sn = u_signal_names(0, &signo, 0); | 11578 | sn = u_signal_names(0, &signo, 0); |
11646 | if(sn==NULL) | 11579 | if (sn == NULL) |
11647 | sn = "???"; | 11580 | sn = "???"; |
11648 | printf("trap -- %s %s\n", p, sn); | 11581 | printf("trap -- %s %s\n", p, sn); |
11649 | stunalloc(p); | 11582 | stunalloc(p); |
@@ -11686,8 +11619,7 @@ trapcmd(int argc, char **argv) | |||
11686 | * out what it should be set to. | 11619 | * out what it should be set to. |
11687 | */ | 11620 | */ |
11688 | 11621 | ||
11689 | static void | 11622 | static void setsignal(int signo) |
11690 | setsignal(int signo) | ||
11691 | { | 11623 | { |
11692 | int action; | 11624 | int action; |
11693 | char *t; | 11625 | char *t; |
@@ -11707,11 +11639,11 @@ setsignal(int signo) | |||
11707 | break; | 11639 | break; |
11708 | case SIGQUIT: | 11640 | case SIGQUIT: |
11709 | #ifdef DEBUG | 11641 | #ifdef DEBUG |
11710 | { | 11642 | { |
11711 | 11643 | ||
11712 | if (debug) | 11644 | if (debug) |
11713 | break; | 11645 | break; |
11714 | } | 11646 | } |
11715 | #endif | 11647 | #endif |
11716 | /* FALLTHROUGH */ | 11648 | /* FALLTHROUGH */ |
11717 | case SIGTERM: | 11649 | case SIGTERM: |
@@ -11743,12 +11675,12 @@ setsignal(int signo) | |||
11743 | } | 11675 | } |
11744 | if (act.sa_handler == SIG_IGN) { | 11676 | if (act.sa_handler == SIG_IGN) { |
11745 | if (mflag && (signo == SIGTSTP || | 11677 | if (mflag && (signo == SIGTSTP || |
11746 | signo == SIGTTIN || signo == SIGTTOU)) { | 11678 | signo == SIGTTIN || signo == SIGTTOU)) { |
11747 | *t = S_IGN; /* don't hard ignore these */ | 11679 | *t = S_IGN; /* don't hard ignore these */ |
11748 | } else | 11680 | } else |
11749 | *t = S_HARD_IGN; | 11681 | *t = S_HARD_IGN; |
11750 | } else { | 11682 | } else { |
11751 | *t = S_RESET; /* force to be set */ | 11683 | *t = S_RESET; /* force to be set */ |
11752 | } | 11684 | } |
11753 | } | 11685 | } |
11754 | if (*t == S_HARD_IGN || *t == action) | 11686 | if (*t == S_HARD_IGN || *t == action) |
@@ -11765,8 +11697,7 @@ setsignal(int signo) | |||
11765 | * Ignore a signal. | 11697 | * Ignore a signal. |
11766 | */ | 11698 | */ |
11767 | 11699 | ||
11768 | static void | 11700 | static void ignoresig(int signo) |
11769 | ignoresig(int signo) | ||
11770 | { | 11701 | { |
11771 | if (sigmode[signo - 1] != S_IGN && sigmode[signo - 1] != S_HARD_IGN) { | 11702 | if (sigmode[signo - 1] != S_IGN && sigmode[signo - 1] != S_HARD_IGN) { |
11772 | signal(signo, SIG_IGN); | 11703 | signal(signo, SIG_IGN); |
@@ -11779,8 +11710,7 @@ ignoresig(int signo) | |||
11779 | * Signal handler. | 11710 | * Signal handler. |
11780 | */ | 11711 | */ |
11781 | 11712 | ||
11782 | static void | 11713 | static void onsig(int signo) |
11783 | onsig(int signo) | ||
11784 | { | 11714 | { |
11785 | if (signo == SIGINT && trap[SIGINT] == NULL) { | 11715 | if (signo == SIGINT && trap[SIGINT] == NULL) { |
11786 | onint(); | 11716 | onint(); |
@@ -11796,25 +11726,24 @@ onsig(int signo) | |||
11796 | * handlers while we are executing a trap handler. | 11726 | * handlers while we are executing a trap handler. |
11797 | */ | 11727 | */ |
11798 | 11728 | ||
11799 | static void | 11729 | static void dotrap(void) |
11800 | dotrap(void) | ||
11801 | { | 11730 | { |
11802 | int i; | 11731 | int i; |
11803 | int savestatus; | 11732 | int savestatus; |
11804 | 11733 | ||
11805 | for (;;) { | 11734 | for (;;) { |
11806 | for (i = 1 ; ; i++) { | 11735 | for (i = 1;; i++) { |
11807 | if (gotsig[i - 1]) | 11736 | if (gotsig[i - 1]) |
11808 | break; | 11737 | break; |
11809 | if (i >= NSIG - 1) | 11738 | if (i >= NSIG - 1) |
11810 | goto done; | 11739 | goto done; |
11811 | } | 11740 | } |
11812 | gotsig[i - 1] = 0; | 11741 | gotsig[i - 1] = 0; |
11813 | savestatus=exitstatus; | 11742 | savestatus = exitstatus; |
11814 | evalstring(trap[i], 0); | 11743 | evalstring(trap[i], 0); |
11815 | exitstatus=savestatus; | 11744 | exitstatus = savestatus; |
11816 | } | 11745 | } |
11817 | done: | 11746 | done: |
11818 | pendingsigs = 0; | 11747 | pendingsigs = 0; |
11819 | } | 11748 | } |
11820 | 11749 | ||
@@ -11822,8 +11751,7 @@ done: | |||
11822 | * Called to exit the shell. | 11751 | * Called to exit the shell. |
11823 | */ | 11752 | */ |
11824 | 11753 | ||
11825 | static void | 11754 | static void exitshell(int status) |
11826 | exitshell(int status) | ||
11827 | { | 11755 | { |
11828 | struct jmploc loc1, loc2; | 11756 | struct jmploc loc1, loc2; |
11829 | char *p; | 11757 | char *p; |
@@ -11840,12 +11768,12 @@ exitshell(int status) | |||
11840 | trap[0] = NULL; | 11768 | trap[0] = NULL; |
11841 | evalstring(p, 0); | 11769 | evalstring(p, 0); |
11842 | } | 11770 | } |
11843 | l1: handler = &loc2; /* probably unnecessary */ | 11771 | l1:handler = &loc2; /* probably unnecessary */ |
11844 | flushall(); | 11772 | flushall(); |
11845 | #ifdef CONFIG_ASH_JOB_CONTROL | 11773 | #ifdef CONFIG_ASH_JOB_CONTROL |
11846 | setjobctl(0); | 11774 | setjobctl(0); |
11847 | #endif | 11775 | #endif |
11848 | l2: _exit(status); | 11776 | l2:_exit(status); |
11849 | /* NOTREACHED */ | 11777 | /* NOTREACHED */ |
11850 | } | 11778 | } |
11851 | 11779 | ||
@@ -11857,9 +11785,9 @@ static int decode_signal(const char *string, int minsig) | |||
11857 | return name ? signo : -1; | 11785 | return name ? signo : -1; |
11858 | } | 11786 | } |
11859 | 11787 | ||
11860 | static struct var **hashvar (const char *); | 11788 | static struct var **hashvar(const char *); |
11861 | static void showvars (const char *, int, int); | 11789 | static void showvars(const char *, int, int); |
11862 | static struct var **findvar (struct var **, const char *); | 11790 | static struct var **findvar(struct var **, const char *); |
11863 | 11791 | ||
11864 | /* | 11792 | /* |
11865 | * Initialize the varable symbol tables and import the environment | 11793 | * Initialize the varable symbol tables and import the environment |
@@ -11870,13 +11798,13 @@ static struct var **findvar (struct var **, const char *); | |||
11870 | * shell is initialized and again when a shell procedure is spawned. | 11798 | * shell is initialized and again when a shell procedure is spawned. |
11871 | */ | 11799 | */ |
11872 | 11800 | ||
11873 | static void | 11801 | static void initvar() |
11874 | initvar() { | 11802 | { |
11875 | const struct varinit *ip; | 11803 | const struct varinit *ip; |
11876 | struct var *vp; | 11804 | struct var *vp; |
11877 | struct var **vpp; | 11805 | struct var **vpp; |
11878 | 11806 | ||
11879 | for (ip = varinit ; (vp = ip->var) != NULL ; ip++) { | 11807 | for (ip = varinit; (vp = ip->var) != NULL; ip++) { |
11880 | if ((vp->flags & VEXPORT) == 0) { | 11808 | if ((vp->flags & VEXPORT) == 0) { |
11881 | vpp = hashvar(ip->text); | 11809 | vpp = hashvar(ip->text); |
11882 | vp->next = *vpp; | 11810 | vp->next = *vpp; |
@@ -11894,8 +11822,8 @@ initvar() { | |||
11894 | vpp = hashvar("PS1=$"); | 11822 | vpp = hashvar("PS1=$"); |
11895 | vps1.next = *vpp; | 11823 | vps1.next = *vpp; |
11896 | *vpp = &vps1; | 11824 | *vpp = &vps1; |
11897 | vps1.text = xstrdup(geteuid() ? "PS1=$ " : "PS1=# "); | 11825 | vps1.text = xstrdup(geteuid()? "PS1=$ " : "PS1=# "); |
11898 | vps1.flags = VSTRFIXED|VTEXTFIXED; | 11826 | vps1.flags = VSTRFIXED | VTEXTFIXED; |
11899 | } | 11827 | } |
11900 | #endif | 11828 | #endif |
11901 | } | 11829 | } |
@@ -11905,8 +11833,7 @@ initvar() { | |||
11905 | * flags of the variable. If val is NULL, the variable is unset. | 11833 | * flags of the variable. If val is NULL, the variable is unset. |
11906 | */ | 11834 | */ |
11907 | 11835 | ||
11908 | static void | 11836 | static void setvar(const char *name, const char *val, int flags) |
11909 | setvar(const char *name, const char *val, int flags) | ||
11910 | { | 11837 | { |
11911 | const char *p; | 11838 | const char *p; |
11912 | int len; | 11839 | int len; |
@@ -11917,11 +11844,11 @@ setvar(const char *name, const char *val, int flags) | |||
11917 | 11844 | ||
11918 | isbad = 0; | 11845 | isbad = 0; |
11919 | p = name; | 11846 | p = name; |
11920 | if (! is_name(*p)) | 11847 | if (!is_name(*p)) |
11921 | isbad = 1; | 11848 | isbad = 1; |
11922 | p++; | 11849 | p++; |
11923 | for (;;) { | 11850 | for (;;) { |
11924 | if (! is_in_name(*p)) { | 11851 | if (!is_in_name(*p)) { |
11925 | if (*p == '\0' || *p == '=') | 11852 | if (*p == '\0' || *p == '=') |
11926 | break; | 11853 | break; |
11927 | isbad = 1; | 11854 | isbad = 1; |
@@ -11931,7 +11858,7 @@ setvar(const char *name, const char *val, int flags) | |||
11931 | namelen = p - name; | 11858 | namelen = p - name; |
11932 | if (isbad) | 11859 | if (isbad) |
11933 | error("%.*s: bad variable name", namelen, name); | 11860 | error("%.*s: bad variable name", namelen, name); |
11934 | len = namelen + 2; /* 2 is space for '=' and '\0' */ | 11861 | len = namelen + 2; /* 2 is space for '=' and '\0' */ |
11935 | if (val == NULL) { | 11862 | if (val == NULL) { |
11936 | flags |= VUNSET; | 11863 | flags |= VUNSET; |
11937 | } else { | 11864 | } else { |
@@ -11959,8 +11886,7 @@ setvar(const char *name, const char *val, int flags) | |||
11959 | * will go away. | 11886 | * will go away. |
11960 | */ | 11887 | */ |
11961 | 11888 | ||
11962 | static void | 11889 | static void setvareq(char *s, int flags) |
11963 | setvareq(char *s, int flags) | ||
11964 | { | 11890 | { |
11965 | struct var *vp, **vpp; | 11891 | struct var *vp, **vpp; |
11966 | 11892 | ||
@@ -11969,17 +11895,18 @@ setvareq(char *s, int flags) | |||
11969 | if ((vp = *findvar(vpp, s))) { | 11895 | if ((vp = *findvar(vpp, s))) { |
11970 | if (vp->flags & VREADONLY) { | 11896 | if (vp->flags & VREADONLY) { |
11971 | size_t len = strchr(s, '=') - s; | 11897 | size_t len = strchr(s, '=') - s; |
11898 | |||
11972 | error("%.*s: is read only", len, s); | 11899 | error("%.*s: is read only", len, s); |
11973 | } | 11900 | } |
11974 | INTOFF; | 11901 | INTOFF; |
11975 | 11902 | ||
11976 | if (vp->func && (flags & VNOFUNC) == 0) | 11903 | if (vp->func && (flags & VNOFUNC) == 0) |
11977 | (*vp->func)(strchr(s, '=') + 1); | 11904 | (*vp->func) (strchr(s, '=') + 1); |
11978 | 11905 | ||
11979 | if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0) | 11906 | if ((vp->flags & (VTEXTFIXED | VSTACK)) == 0) |
11980 | free(vp->text); | 11907 | free(vp->text); |
11981 | 11908 | ||
11982 | vp->flags &= ~(VTEXTFIXED|VSTACK|VUNSET); | 11909 | vp->flags &= ~(VTEXTFIXED | VSTACK | VUNSET); |
11983 | vp->flags |= flags; | 11910 | vp->flags |= flags; |
11984 | vp->text = s; | 11911 | vp->text = s; |
11985 | 11912 | ||
@@ -11995,7 +11922,7 @@ setvareq(char *s, int flags) | |||
11995 | return; | 11922 | return; |
11996 | } | 11923 | } |
11997 | /* not found */ | 11924 | /* not found */ |
11998 | vp = xmalloc(sizeof (*vp)); | 11925 | vp = xmalloc(sizeof(*vp)); |
11999 | vp->flags = flags; | 11926 | vp->flags = flags; |
12000 | vp->text = s; | 11927 | vp->text = s; |
12001 | vp->next = *vpp; | 11928 | vp->next = *vpp; |
@@ -12009,13 +11936,12 @@ setvareq(char *s, int flags) | |||
12009 | * Process a linked list of variable assignments. | 11936 | * Process a linked list of variable assignments. |
12010 | */ | 11937 | */ |
12011 | 11938 | ||
12012 | static void | 11939 | static void listsetvar(struct strlist *mylist) |
12013 | listsetvar(struct strlist *mylist) | ||
12014 | { | 11940 | { |
12015 | struct strlist *lp; | 11941 | struct strlist *lp; |
12016 | 11942 | ||
12017 | INTOFF; | 11943 | INTOFF; |
12018 | for (lp = mylist ; lp ; lp = lp->next) { | 11944 | for (lp = mylist; lp; lp = lp->next) { |
12019 | setvareq(xstrdup(lp->text), 0); | 11945 | setvareq(xstrdup(lp->text), 0); |
12020 | } | 11946 | } |
12021 | INTON; | 11947 | INTON; |
@@ -12027,8 +11953,7 @@ listsetvar(struct strlist *mylist) | |||
12027 | * Find the value of a variable. Returns NULL if not set. | 11953 | * Find the value of a variable. Returns NULL if not set. |
12028 | */ | 11954 | */ |
12029 | 11955 | ||
12030 | static const char * | 11956 | static const char *lookupvar(const char *name) |
12031 | lookupvar(const char *name) | ||
12032 | { | 11957 | { |
12033 | struct var *v; | 11958 | struct var *v; |
12034 | 11959 | ||
@@ -12044,12 +11969,11 @@ lookupvar(const char *name) | |||
12044 | * Search the environment of a builtin command. | 11969 | * Search the environment of a builtin command. |
12045 | */ | 11970 | */ |
12046 | 11971 | ||
12047 | static const char * | 11972 | static const char *bltinlookup(const char *name) |
12048 | bltinlookup(const char *name) | ||
12049 | { | 11973 | { |
12050 | const struct strlist *sp; | 11974 | const struct strlist *sp; |
12051 | 11975 | ||
12052 | for (sp = cmdenviron ; sp ; sp = sp->next) { | 11976 | for (sp = cmdenviron; sp; sp = sp->next) { |
12053 | if (varequal(sp->text, name)) | 11977 | if (varequal(sp->text, name)) |
12054 | return strchr(sp->text, '=') + 1; | 11978 | return strchr(sp->text, '=') + 1; |
12055 | } | 11979 | } |
@@ -12063,8 +11987,8 @@ bltinlookup(const char *name) | |||
12063 | * the third argument to execve when executing a program. | 11987 | * the third argument to execve when executing a program. |
12064 | */ | 11988 | */ |
12065 | 11989 | ||
12066 | static char ** | 11990 | static char **environment() |
12067 | environment() { | 11991 | { |
12068 | int nenv; | 11992 | int nenv; |
12069 | struct var **vpp; | 11993 | struct var **vpp; |
12070 | struct var *vp; | 11994 | struct var *vp; |
@@ -12072,14 +11996,14 @@ environment() { | |||
12072 | char **ep; | 11996 | char **ep; |
12073 | 11997 | ||
12074 | nenv = 0; | 11998 | nenv = 0; |
12075 | for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) { | 11999 | for (vpp = vartab; vpp < vartab + VTABSIZE; vpp++) { |
12076 | for (vp = *vpp ; vp ; vp = vp->next) | 12000 | for (vp = *vpp; vp; vp = vp->next) |
12077 | if (vp->flags & VEXPORT) | 12001 | if (vp->flags & VEXPORT) |
12078 | nenv++; | 12002 | nenv++; |
12079 | } | 12003 | } |
12080 | ep = env = stalloc((nenv + 1) * sizeof *env); | 12004 | ep = env = stalloc((nenv + 1) * sizeof *env); |
12081 | for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) { | 12005 | for (vpp = vartab; vpp < vartab + VTABSIZE; vpp++) { |
12082 | for (vp = *vpp ; vp ; vp = vp->next) | 12006 | for (vp = *vpp; vp; vp = vp->next) |
12083 | if (vp->flags & VEXPORT) | 12007 | if (vp->flags & VEXPORT) |
12084 | *ep++ = vp->text; | 12008 | *ep++ = vp->text; |
12085 | } | 12009 | } |
@@ -12094,13 +12018,13 @@ environment() { | |||
12094 | * VSTACK set since these are currently allocated on the stack. | 12018 | * VSTACK set since these are currently allocated on the stack. |
12095 | */ | 12019 | */ |
12096 | 12020 | ||
12097 | static void | 12021 | static void shprocvar(void) |
12098 | shprocvar(void) { | 12022 | { |
12099 | struct var **vpp; | 12023 | struct var **vpp; |
12100 | struct var *vp, **prev; | 12024 | struct var *vp, **prev; |
12101 | 12025 | ||
12102 | for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) { | 12026 | for (vpp = vartab; vpp < vartab + VTABSIZE; vpp++) { |
12103 | for (prev = vpp ; (vp = *prev) != NULL ; ) { | 12027 | for (prev = vpp; (vp = *prev) != NULL;) { |
12104 | if ((vp->flags & VEXPORT) == 0) { | 12028 | if ((vp->flags & VEXPORT) == 0) { |
12105 | *prev = vp->next; | 12029 | *prev = vp->next; |
12106 | if ((vp->flags & VTEXTFIXED) == 0) | 12030 | if ((vp->flags & VTEXTFIXED) == 0) |
@@ -12110,7 +12034,7 @@ shprocvar(void) { | |||
12110 | } else { | 12034 | } else { |
12111 | if (vp->flags & VSTACK) { | 12035 | if (vp->flags & VSTACK) { |
12112 | vp->text = xstrdup(vp->text); | 12036 | vp->text = xstrdup(vp->text); |
12113 | vp->flags &=~ VSTACK; | 12037 | vp->flags &= ~VSTACK; |
12114 | } | 12038 | } |
12115 | prev = &vp->next; | 12039 | prev = &vp->next; |
12116 | } | 12040 | } |
@@ -12127,8 +12051,7 @@ shprocvar(void) { | |||
12127 | * any variables. | 12051 | * any variables. |
12128 | */ | 12052 | */ |
12129 | 12053 | ||
12130 | static int | 12054 | static int showvarscmd(int argc, char **argv) |
12131 | showvarscmd(int argc, char **argv) | ||
12132 | { | 12055 | { |
12133 | showvars(nullstr, VUNSET, VUNSET); | 12056 | showvars(nullstr, VUNSET, VUNSET); |
12134 | return 0; | 12057 | return 0; |
@@ -12140,13 +12063,12 @@ showvarscmd(int argc, char **argv) | |||
12140 | * The export and readonly commands. | 12063 | * The export and readonly commands. |
12141 | */ | 12064 | */ |
12142 | 12065 | ||
12143 | static int | 12066 | static int exportcmd(int argc, char **argv) |
12144 | exportcmd(int argc, char **argv) | ||
12145 | { | 12067 | { |
12146 | struct var *vp; | 12068 | struct var *vp; |
12147 | char *name; | 12069 | char *name; |
12148 | const char *p; | 12070 | const char *p; |
12149 | int flag = argv[0][0] == 'r'? VREADONLY : VEXPORT; | 12071 | int flag = argv[0][0] == 'r' ? VREADONLY : VEXPORT; |
12150 | int pflag; | 12072 | int pflag; |
12151 | 12073 | ||
12152 | listsetvar(cmdenviron); | 12074 | listsetvar(cmdenviron); |
@@ -12162,7 +12084,7 @@ exportcmd(int argc, char **argv) | |||
12162 | } | 12084 | } |
12163 | } | 12085 | } |
12164 | setvar(name, p, flag); | 12086 | setvar(name, p, flag); |
12165 | found:; | 12087 | found:; |
12166 | } | 12088 | } |
12167 | } else { | 12089 | } else { |
12168 | showvars(argv[0], flag, 0); | 12090 | showvars(argv[0], flag, 0); |
@@ -12177,12 +12099,11 @@ found:; | |||
12177 | 12099 | ||
12178 | /* funcnest nonzero if we are currently evaluating a function */ | 12100 | /* funcnest nonzero if we are currently evaluating a function */ |
12179 | 12101 | ||
12180 | static int | 12102 | static int localcmd(int argc, char **argv) |
12181 | localcmd(int argc, char **argv) | ||
12182 | { | 12103 | { |
12183 | char *name; | 12104 | char *name; |
12184 | 12105 | ||
12185 | if (! funcnest) | 12106 | if (!funcnest) |
12186 | error("Not in a function"); | 12107 | error("Not in a function"); |
12187 | while ((name = *argptr++) != NULL) { | 12108 | while ((name = *argptr++) != NULL) { |
12188 | mklocal(name); | 12109 | mklocal(name); |
@@ -12198,17 +12119,17 @@ localcmd(int argc, char **argv) | |||
12198 | * "-" as a special case. | 12119 | * "-" as a special case. |
12199 | */ | 12120 | */ |
12200 | 12121 | ||
12201 | static void | 12122 | static void mklocal(char *name) |
12202 | mklocal(char *name) | ||
12203 | { | 12123 | { |
12204 | struct localvar *lvp; | 12124 | struct localvar *lvp; |
12205 | struct var **vpp; | 12125 | struct var **vpp; |
12206 | struct var *vp; | 12126 | struct var *vp; |
12207 | 12127 | ||
12208 | INTOFF; | 12128 | INTOFF; |
12209 | lvp = xmalloc(sizeof (struct localvar)); | 12129 | lvp = xmalloc(sizeof(struct localvar)); |
12210 | if (name[0] == '-' && name[1] == '\0') { | 12130 | if (name[0] == '-' && name[1] == '\0') { |
12211 | char *p; | 12131 | char *p; |
12132 | |||
12212 | p = xmalloc(sizeof optet_vals); | 12133 | p = xmalloc(sizeof optet_vals); |
12213 | lvp->text = memcpy(p, optet_vals, sizeof optet_vals); | 12134 | lvp->text = memcpy(p, optet_vals, sizeof optet_vals); |
12214 | vp = NULL; | 12135 | vp = NULL; |
@@ -12220,13 +12141,13 @@ mklocal(char *name) | |||
12220 | setvareq(xstrdup(name), VSTRFIXED); | 12141 | setvareq(xstrdup(name), VSTRFIXED); |
12221 | else | 12142 | else |
12222 | setvar(name, NULL, VSTRFIXED); | 12143 | setvar(name, NULL, VSTRFIXED); |
12223 | vp = *vpp; /* the new variable */ | 12144 | vp = *vpp; /* the new variable */ |
12224 | lvp->text = NULL; | 12145 | lvp->text = NULL; |
12225 | lvp->flags = VUNSET; | 12146 | lvp->flags = VUNSET; |
12226 | } else { | 12147 | } else { |
12227 | lvp->text = vp->text; | 12148 | lvp->text = vp->text; |
12228 | lvp->flags = vp->flags; | 12149 | lvp->flags = vp->flags; |
12229 | vp->flags |= VSTRFIXED|VTEXTFIXED; | 12150 | vp->flags |= VSTRFIXED | VTEXTFIXED; |
12230 | if (strchr(name, '=')) | 12151 | if (strchr(name, '=')) |
12231 | setvareq(xstrdup(name), 0); | 12152 | setvareq(xstrdup(name), 0); |
12232 | } | 12153 | } |
@@ -12242,19 +12163,19 @@ mklocal(char *name) | |||
12242 | * Called after a function returns. | 12163 | * Called after a function returns. |
12243 | */ | 12164 | */ |
12244 | 12165 | ||
12245 | static void | 12166 | static void poplocalvars() |
12246 | poplocalvars() { | 12167 | { |
12247 | struct localvar *lvp; | 12168 | struct localvar *lvp; |
12248 | struct var *vp; | 12169 | struct var *vp; |
12249 | 12170 | ||
12250 | while ((lvp = localvars) != NULL) { | 12171 | while ((lvp = localvars) != NULL) { |
12251 | localvars = lvp->next; | 12172 | localvars = lvp->next; |
12252 | vp = lvp->vp; | 12173 | vp = lvp->vp; |
12253 | if (vp == NULL) { /* $- saved */ | 12174 | if (vp == NULL) { /* $- saved */ |
12254 | memcpy(optet_vals, lvp->text, sizeof optet_vals); | 12175 | memcpy(optet_vals, lvp->text, sizeof optet_vals); |
12255 | free(lvp->text); | 12176 | free(lvp->text); |
12256 | } else if ((lvp->flags & (VUNSET|VSTRFIXED)) == VUNSET) { | 12177 | } else if ((lvp->flags & (VUNSET | VSTRFIXED)) == VUNSET) { |
12257 | (void)unsetvar(vp->text); | 12178 | (void) unsetvar(vp->text); |
12258 | } else { | 12179 | } else { |
12259 | if ((vp->flags & VTEXTFIXED) == 0) | 12180 | if ((vp->flags & VTEXTFIXED) == 0) |
12260 | free(vp->text); | 12181 | free(vp->text); |
@@ -12266,8 +12187,7 @@ poplocalvars() { | |||
12266 | } | 12187 | } |
12267 | 12188 | ||
12268 | 12189 | ||
12269 | static int | 12190 | static int setvarcmd(int argc, char **argv) |
12270 | setvarcmd(int argc, char **argv) | ||
12271 | { | 12191 | { |
12272 | if (argc <= 2) | 12192 | if (argc <= 2) |
12273 | return unsetcmd(argc, argv); | 12193 | return unsetcmd(argc, argv); |
@@ -12285,8 +12205,7 @@ setvarcmd(int argc, char **argv) | |||
12285 | * with the same name. | 12205 | * with the same name. |
12286 | */ | 12206 | */ |
12287 | 12207 | ||
12288 | static int | 12208 | static int unsetcmd(int argc, char **argv) |
12289 | unsetcmd(int argc, char **argv) | ||
12290 | { | 12209 | { |
12291 | char **ap; | 12210 | char **ap; |
12292 | int i; | 12211 | int i; |
@@ -12303,7 +12222,7 @@ unsetcmd(int argc, char **argv) | |||
12303 | if (flg_func == 0 && flg_var == 0) | 12222 | if (flg_func == 0 && flg_var == 0) |
12304 | flg_var = 1; | 12223 | flg_var = 1; |
12305 | 12224 | ||
12306 | for (ap = argptr; *ap ; ap++) { | 12225 | for (ap = argptr; *ap; ap++) { |
12307 | if (flg_func) | 12226 | if (flg_func) |
12308 | unsetfunc(*ap); | 12227 | unsetfunc(*ap); |
12309 | if (flg_var) | 12228 | if (flg_var) |
@@ -12317,8 +12236,7 @@ unsetcmd(int argc, char **argv) | |||
12317 | * Unset the specified variable. | 12236 | * Unset the specified variable. |
12318 | */ | 12237 | */ |
12319 | 12238 | ||
12320 | static int | 12239 | static int unsetvar(const char *s) |
12321 | unsetvar(const char *s) | ||
12322 | { | 12240 | { |
12323 | struct var **vpp; | 12241 | struct var **vpp; |
12324 | struct var *vp; | 12242 | struct var *vp; |
@@ -12352,8 +12270,7 @@ unsetvar(const char *s) | |||
12352 | * Find the appropriate entry in the hash table from the name. | 12270 | * Find the appropriate entry in the hash table from the name. |
12353 | */ | 12271 | */ |
12354 | 12272 | ||
12355 | static struct var ** | 12273 | static struct var **hashvar(const char *p) |
12356 | hashvar(const char *p) | ||
12357 | { | 12274 | { |
12358 | unsigned int hashval; | 12275 | unsigned int hashval; |
12359 | 12276 | ||
@@ -12371,8 +12288,7 @@ hashvar(const char *p) | |||
12371 | * either '=' or '\0'. | 12288 | * either '=' or '\0'. |
12372 | */ | 12289 | */ |
12373 | 12290 | ||
12374 | static int | 12291 | static int varequal(const char *p, const char *q) |
12375 | varequal(const char *p, const char *q) | ||
12376 | { | 12292 | { |
12377 | while (*p == *q++) { | 12293 | while (*p == *q++) { |
12378 | if (*p++ == '=') | 12294 | if (*p++ == '=') |
@@ -12383,15 +12299,14 @@ varequal(const char *p, const char *q) | |||
12383 | return 0; | 12299 | return 0; |
12384 | } | 12300 | } |
12385 | 12301 | ||
12386 | static void | 12302 | static void showvars(const char *myprefix, int mask, int xor) |
12387 | showvars(const char *myprefix, int mask, int xor) | ||
12388 | { | 12303 | { |
12389 | struct var **vpp; | 12304 | struct var **vpp; |
12390 | struct var *vp; | 12305 | struct var *vp; |
12391 | const char *sep = myprefix == nullstr ? myprefix : spcstr; | 12306 | const char *sep = myprefix == nullstr ? myprefix : spcstr; |
12392 | 12307 | ||
12393 | for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) { | 12308 | for (vpp = vartab; vpp < vartab + VTABSIZE; vpp++) { |
12394 | for (vp = *vpp ; vp ; vp = vp->next) { | 12309 | for (vp = *vpp; vp; vp = vp->next) { |
12395 | if ((vp->flags & mask) ^ xor) { | 12310 | if ((vp->flags & mask) ^ xor) { |
12396 | char *p; | 12311 | char *p; |
12397 | int len; | 12312 | int len; |
@@ -12400,16 +12315,14 @@ showvars(const char *myprefix, int mask, int xor) | |||
12400 | len = p - vp->text; | 12315 | len = p - vp->text; |
12401 | p = single_quote(p); | 12316 | p = single_quote(p); |
12402 | 12317 | ||
12403 | printf("%s%s%.*s%s\n", myprefix, sep, len, | 12318 | printf("%s%s%.*s%s\n", myprefix, sep, len, vp->text, p); |
12404 | vp->text, p); | ||
12405 | stunalloc(p); | 12319 | stunalloc(p); |
12406 | } | 12320 | } |
12407 | } | 12321 | } |
12408 | } | 12322 | } |
12409 | } | 12323 | } |
12410 | 12324 | ||
12411 | static struct var ** | 12325 | static struct var **findvar(struct var **vpp, const char *name) |
12412 | findvar(struct var **vpp, const char *name) | ||
12413 | { | 12326 | { |
12414 | for (; *vpp; vpp = &(*vpp)->next) { | 12327 | for (; *vpp; vpp = &(*vpp)->next) { |
12415 | if (varequal((*vpp)->text, name)) { | 12328 | if (varequal((*vpp)->text, name)) { |
@@ -12422,23 +12335,23 @@ findvar(struct var **vpp, const char *name) | |||
12422 | /* | 12335 | /* |
12423 | * Copyright (c) 1999 Herbert Xu <herbert@debian.org> | 12336 | * Copyright (c) 1999 Herbert Xu <herbert@debian.org> |
12424 | * This file contains code for the times builtin. | 12337 | * This file contains code for the times builtin. |
12425 | * $Id: ash.c,v 1.56 2002/08/02 06:39:47 aaronl Exp $ | 12338 | * $Id: ash.c,v 1.57 2002/08/22 18:30:15 bug1 Exp $ |
12426 | */ | 12339 | */ |
12427 | static int timescmd (int argc, char **argv) | 12340 | static int timescmd(int argc, char **argv) |
12428 | { | 12341 | { |
12429 | struct tms buf; | 12342 | struct tms buf; |
12430 | long int clk_tck = sysconf(_SC_CLK_TCK); | 12343 | long int clk_tck = sysconf(_SC_CLK_TCK); |
12431 | 12344 | ||
12432 | times(&buf); | 12345 | times(&buf); |
12433 | printf("%dm%fs %dm%fs\n%dm%fs %dm%fs\n", | 12346 | printf("%dm%fs %dm%fs\n%dm%fs %dm%fs\n", |
12434 | (int) (buf.tms_utime / clk_tck / 60), | 12347 | (int) (buf.tms_utime / clk_tck / 60), |
12435 | ((double) buf.tms_utime) / clk_tck, | 12348 | ((double) buf.tms_utime) / clk_tck, |
12436 | (int) (buf.tms_stime / clk_tck / 60), | 12349 | (int) (buf.tms_stime / clk_tck / 60), |
12437 | ((double) buf.tms_stime) / clk_tck, | 12350 | ((double) buf.tms_stime) / clk_tck, |
12438 | (int) (buf.tms_cutime / clk_tck / 60), | 12351 | (int) (buf.tms_cutime / clk_tck / 60), |
12439 | ((double) buf.tms_cutime) / clk_tck, | 12352 | ((double) buf.tms_cutime) / clk_tck, |
12440 | (int) (buf.tms_cstime / clk_tck / 60), | 12353 | (int) (buf.tms_cstime / clk_tck / 60), |
12441 | ((double) buf.tms_cstime) / clk_tck); | 12354 | ((double) buf.tms_cstime) / clk_tck); |
12442 | return 0; | 12355 | return 0; |
12443 | } | 12356 | } |
12444 | 12357 | ||
@@ -12447,9 +12360,11 @@ static int timescmd (int argc, char **argv) | |||
12447 | int letcmd(int argc, char **argv) | 12360 | int letcmd(int argc, char **argv) |
12448 | { | 12361 | { |
12449 | int errcode; | 12362 | int errcode; |
12450 | long result=0; | 12363 | long result = 0; |
12364 | |||
12451 | if (argc == 2) { | 12365 | if (argc == 2) { |
12452 | char *tmp, *expression, p[13]; | 12366 | char *tmp, *expression, p[13]; |
12367 | |||
12453 | expression = strchr(argv[1], '='); | 12368 | expression = strchr(argv[1], '='); |
12454 | if (!expression) { | 12369 | if (!expression) { |
12455 | /* Cannot use 'error()' here, or the return code | 12370 | /* Cannot use 'error()' here, or the return code |
@@ -12464,7 +12379,7 @@ int letcmd(int argc, char **argv) | |||
12464 | /* Cannot use 'error()' here, or the return code | 12379 | /* Cannot use 'error()' here, or the return code |
12465 | * will be incorrect */ | 12380 | * will be incorrect */ |
12466 | out2fmt("sh: let: "); | 12381 | out2fmt("sh: let: "); |
12467 | if(errcode == -2) | 12382 | if (errcode == -2) |
12468 | out2fmt("divide by zero"); | 12383 | out2fmt("divide by zero"); |
12469 | else | 12384 | else |
12470 | out2fmt("syntax error: \"%s=%s\"\n", argv[1], expression); | 12385 | out2fmt("syntax error: \"%s=%s\"\n", argv[1], expression); |