aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorvda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2007-02-23 01:04:50 +0000
committervda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2007-02-23 01:04:50 +0000
commit487a5f166d47cbc76877bb58240c1609bfcd8319 (patch)
treeb115c56533abb69ddac5f790835322a705678ede /shell
parent79702e13b401e175c385384c51c5b8524370d227 (diff)
downloadbusybox-w32-487a5f166d47cbc76877bb58240c1609bfcd8319.tar.gz
busybox-w32-487a5f166d47cbc76877bb58240c1609bfcd8319.tar.bz2
busybox-w32-487a5f166d47cbc76877bb58240c1609bfcd8319.zip
ash: cleanup part 4
git-svn-id: svn://busybox.net/trunk/busybox@17956 69ca8d6d-28ef-0310-b511-8ec308f3f277
Diffstat (limited to 'shell')
-rw-r--r--shell/ash.c1244
1 files changed, 597 insertions, 647 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 3107181a6..7ffecf43d 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -65,36 +65,6 @@
65#error "Do not even bother, ash will not run on uClinux" 65#error "Do not even bother, ash will not run on uClinux"
66#endif 66#endif
67 67
68#if DEBUG
69#define TRACE(param) trace param
70#define TRACEV(param) tracev param
71#else
72#define TRACE(param)
73#define TRACEV(param)
74#endif
75
76#ifdef __GLIBC__
77/* glibc sucks */
78static int *dash_errno;
79#undef errno
80#define errno (*dash_errno)
81#endif
82
83
84#if ENABLE_ASH_ALIAS
85#define ALIASINUSE 1
86#define ALIASDEAD 2
87struct alias {
88 struct alias *next;
89 char *name;
90 char *val;
91 int flag;
92};
93static int aliascmd(int, char **);
94static int unaliascmd(int, char **);
95static void printalias(const struct alias *);
96#endif
97
98 68
99/* ============ Shell options */ 69/* ============ Shell options */
100 70
@@ -148,6 +118,13 @@ static char optlist[NOPTS];
148 118
149/* ============ Misc data */ 119/* ============ Misc data */
150 120
121#ifdef __GLIBC__
122/* glibc sucks */
123static int *dash_errno;
124#undef errno
125#define errno (*dash_errno)
126#endif
127
151static char nullstr[1]; /* zero length string */ 128static char nullstr[1]; /* zero length string */
152static const char homestr[] = "HOME"; 129static const char homestr[] = "HOME";
153static const char snlfmt[] = "%s\n"; 130static const char snlfmt[] = "%s\n";
@@ -256,14 +233,16 @@ raise_interrupt(void)
256} 233}
257 234
258#if ENABLE_ASH_OPTIMIZE_FOR_SIZE 235#if ENABLE_ASH_OPTIMIZE_FOR_SIZE
259static void int_on(void) 236static void
237int_on(void)
260{ 238{
261 if (--suppressint == 0 && intpending) { 239 if (--suppressint == 0 && intpending) {
262 raise_interrupt(); 240 raise_interrupt();
263 } 241 }
264} 242}
265#define INT_ON int_on() 243#define INT_ON int_on()
266static void force_int_on(void) 244static void
245force_int_on(void)
267{ 246{
268 suppressint = 0; 247 suppressint = 0;
269 if (intpending) 248 if (intpending)
@@ -387,6 +366,485 @@ out2str(const char *p)
387} 366}
388 367
389 368
369/* ============ Parsing structures */
370#define NCMD 0
371#define NPIPE 1
372#define NREDIR 2
373#define NBACKGND 3
374#define NSUBSHELL 4
375#define NAND 5
376#define NOR 6
377#define NSEMI 7
378#define NIF 8
379#define NWHILE 9
380#define NUNTIL 10
381#define NFOR 11
382#define NCASE 12
383#define NCLIST 13
384#define NDEFUN 14
385#define NARG 15
386#define NTO 16
387#define NCLOBBER 17
388#define NFROM 18
389#define NFROMTO 19
390#define NAPPEND 20
391#define NTOFD 21
392#define NFROMFD 22
393#define NHERE 23
394#define NXHERE 24
395#define NNOT 25
396
397union node;
398
399struct ncmd {
400 int type;
401 union node *assign;
402 union node *args;
403 union node *redirect;
404};
405
406struct npipe {
407 int type;
408 int backgnd;
409 struct nodelist *cmdlist;
410};
411
412struct nredir {
413 int type;
414 union node *n;
415 union node *redirect;
416};
417
418struct nbinary {
419 int type;
420 union node *ch1;
421 union node *ch2;
422};
423
424struct nif {
425 int type;
426 union node *test;
427 union node *ifpart;
428 union node *elsepart;
429};
430
431struct nfor {
432 int type;
433 union node *args;
434 union node *body;
435 char *var;
436};
437
438struct ncase {
439 int type;
440 union node *expr;
441 union node *cases;
442};
443
444struct nclist {
445 int type;
446 union node *next;
447 union node *pattern;
448 union node *body;
449};
450
451struct narg {
452 int type;
453 union node *next;
454 char *text;
455 struct nodelist *backquote;
456};
457
458struct nfile {
459 int type;
460 union node *next;
461 int fd;
462 union node *fname;
463 char *expfname;
464};
465
466struct ndup {
467 int type;
468 union node *next;
469 int fd;
470 int dupfd;
471 union node *vname;
472};
473
474struct nhere {
475 int type;
476 union node *next;
477 int fd;
478 union node *doc;
479};
480
481struct nnot {
482 int type;
483 union node *com;
484};
485
486union node {
487 int type;
488 struct ncmd ncmd;
489 struct npipe npipe;
490 struct nredir nredir;
491 struct nbinary nbinary;
492 struct nif nif;
493 struct nfor nfor;
494 struct ncase ncase;
495 struct nclist nclist;
496 struct narg narg;
497 struct nfile nfile;
498 struct ndup ndup;
499 struct nhere nhere;
500 struct nnot nnot;
501};
502
503struct nodelist {
504 struct nodelist *next;
505 union node *n;
506};
507
508struct funcnode {
509 int count;
510 union node n;
511};
512
513
514/* ============ Debugging output */
515
516#if DEBUG
517
518static FILE *tracefile;
519
520static void
521trace_printf(const char *fmt, ...)
522{
523 va_list va;
524
525 if (debug != 1)
526 return;
527 va_start(va, fmt);
528 vfprintf(tracefile, fmt, va);
529 va_end(va);
530}
531
532static void
533trace_vprintf(const char *fmt, va_list va)
534{
535 if (debug != 1)
536 return;
537 vfprintf(tracefile, fmt, va);
538}
539
540static void
541trace_puts(const char *s)
542{
543 if (debug != 1)
544 return;
545 fputs(s, tracefile);
546}
547
548static void
549trace_puts_quoted(char *s)
550{
551 char *p;
552 char c;
553
554 if (debug != 1)
555 return;
556 putc('"', tracefile);
557 for (p = s; *p; p++) {
558 switch (*p) {
559 case '\n': c = 'n'; goto backslash;
560 case '\t': c = 't'; goto backslash;
561 case '\r': c = 'r'; goto backslash;
562 case '"': c = '"'; goto backslash;
563 case '\\': c = '\\'; goto backslash;
564 case CTLESC: c = 'e'; goto backslash;
565 case CTLVAR: c = 'v'; goto backslash;
566 case CTLVAR+CTLQUOTE: c = 'V'; goto backslash;
567 case CTLBACKQ: c = 'q'; goto backslash;
568 case CTLBACKQ+CTLQUOTE: c = 'Q'; goto backslash;
569 backslash:
570 putc('\\', tracefile);
571 putc(c, tracefile);
572 break;
573 default:
574 if (*p >= ' ' && *p <= '~')
575 putc(*p, tracefile);
576 else {
577 putc('\\', tracefile);
578 putc(*p >> 6 & 03, tracefile);
579 putc(*p >> 3 & 07, tracefile);
580 putc(*p & 07, tracefile);
581 }
582 break;
583 }
584 }
585 putc('"', tracefile);
586}
587
588static void
589trace_puts_args(char **ap)
590{
591 if (debug != 1)
592 return;
593 if (!*ap)
594 return;
595 while (1) {
596 trace_puts_quoted(*ap);
597 if (!*++ap) {
598 putc('\n', tracefile);
599 break;
600 }
601 putc(' ', tracefile);
602 }
603}
604
605static void
606opentrace(void)
607{
608 char s[100];
609#ifdef O_APPEND
610 int flags;
611#endif
612
613 if (debug != 1) {
614 if (tracefile)
615 fflush(tracefile);
616 /* leave open because libedit might be using it */
617 return;
618 }
619 strcpy(s, "./trace");
620 if (tracefile) {
621 if (!freopen(s, "a", tracefile)) {
622 fprintf(stderr, "Can't re-open %s\n", s);
623 debug = 0;
624 return;
625 }
626 } else {
627 tracefile = fopen(s, "a");
628 if (tracefile == NULL) {
629 fprintf(stderr, "Can't open %s\n", s);
630 debug = 0;
631 return;
632 }
633 }
634#ifdef O_APPEND
635 flags = fcntl(fileno(tracefile), F_GETFL, 0);
636 if (flags >= 0)
637 fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND);
638#endif
639 setlinebuf(tracefile);
640 fputs("\nTracing started.\n", tracefile);
641}
642
643static void
644indent(int amount, char *pfx, FILE *fp)
645{
646 int i;
647
648 for (i = 0; i < amount; i++) {
649 if (pfx && i == amount - 1)
650 fputs(pfx, fp);
651 putc('\t', fp);
652 }
653}
654
655/* little circular references here... */
656static void shtree(union node *n, int ind, char *pfx, FILE *fp);
657
658static void
659sharg(union node *arg, FILE *fp)
660{
661 char *p;
662 struct nodelist *bqlist;
663 int subtype;
664
665 if (arg->type != NARG) {
666 out1fmt("<node type %d>\n", arg->type);
667 abort();
668 }
669 bqlist = arg->narg.backquote;
670 for (p = arg->narg.text; *p; p++) {
671 switch (*p) {
672 case CTLESC:
673 putc(*++p, fp);
674 break;
675 case CTLVAR:
676 putc('$', fp);
677 putc('{', fp);
678 subtype = *++p;
679 if (subtype == VSLENGTH)
680 putc('#', fp);
681
682 while (*p != '=')
683 putc(*p++, fp);
684
685 if (subtype & VSNUL)
686 putc(':', fp);
687
688 switch (subtype & VSTYPE) {
689 case VSNORMAL:
690 putc('}', fp);
691 break;
692 case VSMINUS:
693 putc('-', fp);
694 break;
695 case VSPLUS:
696 putc('+', fp);
697 break;
698 case VSQUESTION:
699 putc('?', fp);
700 break;
701 case VSASSIGN:
702 putc('=', fp);
703 break;
704 case VSTRIMLEFT:
705 putc('#', fp);
706 break;
707 case VSTRIMLEFTMAX:
708 putc('#', fp);
709 putc('#', fp);
710 break;
711 case VSTRIMRIGHT:
712 putc('%', fp);
713 break;
714 case VSTRIMRIGHTMAX:
715 putc('%', fp);
716 putc('%', fp);
717 break;
718 case VSLENGTH:
719 break;
720 default:
721 out1fmt("<subtype %d>", subtype);
722 }
723 break;
724 case CTLENDVAR:
725 putc('}', fp);
726 break;
727 case CTLBACKQ:
728 case CTLBACKQ|CTLQUOTE:
729 putc('$', fp);
730 putc('(', fp);
731 shtree(bqlist->n, -1, NULL, fp);
732 putc(')', fp);
733 break;
734 default:
735 putc(*p, fp);
736 break;
737 }
738 }
739}
740
741static void
742shcmd(union node *cmd, FILE *fp)
743{
744 union node *np;
745 int first;
746 const char *s;
747 int dftfd;
748
749 first = 1;
750 for (np = cmd->ncmd.args; np; np = np->narg.next) {
751 if (! first)
752 putchar(' ');
753 sharg(np, fp);
754 first = 0;
755 }
756 for (np = cmd->ncmd.redirect; np; np = np->nfile.next) {
757 if (! first)
758 putchar(' ');
759 switch (np->nfile.type) {
760 case NTO: s = ">"; dftfd = 1; break;
761 case NCLOBBER: s = ">|"; dftfd = 1; break;
762 case NAPPEND: s = ">>"; dftfd = 1; break;
763 case NTOFD: s = ">&"; dftfd = 1; break;
764 case NFROM: s = "<"; dftfd = 0; break;
765 case NFROMFD: s = "<&"; dftfd = 0; break;
766 case NFROMTO: s = "<>"; dftfd = 0; break;
767 default: s = "*error*"; dftfd = 0; break;
768 }
769 if (np->nfile.fd != dftfd)
770 fprintf(fp, "%d", np->nfile.fd);
771 fputs(s, fp);
772 if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) {
773 fprintf(fp, "%d", np->ndup.dupfd);
774 } else {
775 sharg(np->nfile.fname, fp);
776 }
777 first = 0;
778 }
779}
780
781static void
782shtree(union node *n, int ind, char *pfx, FILE *fp)
783{
784 struct nodelist *lp;
785 const char *s;
786
787 if (n == NULL)
788 return;
789
790 indent(ind, pfx, fp);
791 switch (n->type) {
792 case NSEMI:
793 s = "; ";
794 goto binop;
795 case NAND:
796 s = " && ";
797 goto binop;
798 case NOR:
799 s = " || ";
800 binop:
801 shtree(n->nbinary.ch1, ind, NULL, fp);
802 /* if (ind < 0) */
803 fputs(s, fp);
804 shtree(n->nbinary.ch2, ind, NULL, fp);
805 break;
806 case NCMD:
807 shcmd(n, fp);
808 if (ind >= 0)
809 putc('\n', fp);
810 break;
811 case NPIPE:
812 for (lp = n->npipe.cmdlist; lp; lp = lp->next) {
813 shcmd(lp->n, fp);
814 if (lp->next)
815 fputs(" | ", fp);
816 }
817 if (n->npipe.backgnd)
818 fputs(" &", fp);
819 if (ind >= 0)
820 putc('\n', fp);
821 break;
822 default:
823 fprintf(fp, "<node type %d>", n->type);
824 if (ind >= 0)
825 putc('\n', fp);
826 break;
827 }
828}
829
830static void
831showtree(union node *n)
832{
833 trace_puts("showtree called\n");
834 shtree(n, 1, NULL, stdout);
835}
836
837#define TRACE(param) trace_printf param
838#define TRACEV(param) trace_vprintf param
839
840#else
841
842#define TRACE(param)
843#define TRACEV(param)
844
845#endif /* DEBUG */
846
847
390/* ============ Parser data 848/* ============ Parser data
391 * 849 *
392 * ash_vmsg() needs parsefile->fd, hence parsefile definition is moved up. 850 * ash_vmsg() needs parsefile->fd, hence parsefile definition is moved up.
@@ -397,6 +855,15 @@ struct strlist {
397 char *text; 855 char *text;
398}; 856};
399 857
858#if ENABLE_ASH_ALIAS
859#define ALIASINUSE 1
860#define ALIASDEAD 2
861struct alias;
862static int aliascmd(int, char **);
863static int unaliascmd(int, char **);
864static void printalias(const struct alias *);
865#endif
866
400struct strpush { 867struct strpush {
401 struct strpush *prev; /* preceding string on stack */ 868 struct strpush *prev; /* preceding string on stack */
402 char *prevstring; 869 char *prevstring;
@@ -1882,7 +2349,6 @@ struct arglist {
1882#define EXP_QWORD 0x100 /* expand word in quoted parameter expansion */ 2349#define EXP_QWORD 0x100 /* expand word in quoted parameter expansion */
1883 2350
1884 2351
1885union node;
1886static void expandarg(union node *, struct arglist *, int); 2352static void expandarg(union node *, struct arglist *, int);
1887#define rmescapes(p) _rmescapes((p), 0) 2353#define rmescapes(p) _rmescapes((p), 0)
1888static char *_rmescapes(char *, int); 2354static char *_rmescapes(char *, int);
@@ -1903,152 +2369,6 @@ struct backcmd { /* result of evalbackcmd */
1903 struct job *jp; /* job structure for command */ 2369 struct job *jp; /* job structure for command */
1904}; 2370};
1905 2371
1906/*
1907 * This file was generated by the mknodes program.
1908 */
1909
1910#define NCMD 0
1911#define NPIPE 1
1912#define NREDIR 2
1913#define NBACKGND 3
1914#define NSUBSHELL 4
1915#define NAND 5
1916#define NOR 6
1917#define NSEMI 7
1918#define NIF 8
1919#define NWHILE 9
1920#define NUNTIL 10
1921#define NFOR 11
1922#define NCASE 12
1923#define NCLIST 13
1924#define NDEFUN 14
1925#define NARG 15
1926#define NTO 16
1927#define NCLOBBER 17
1928#define NFROM 18
1929#define NFROMTO 19
1930#define NAPPEND 20
1931#define NTOFD 21
1932#define NFROMFD 22
1933#define NHERE 23
1934#define NXHERE 24
1935#define NNOT 25
1936
1937
1938struct ncmd {
1939 int type;
1940 union node *assign;
1941 union node *args;
1942 union node *redirect;
1943};
1944
1945struct npipe {
1946 int type;
1947 int backgnd;
1948 struct nodelist *cmdlist;
1949};
1950
1951struct nredir {
1952 int type;
1953 union node *n;
1954 union node *redirect;
1955};
1956
1957struct nbinary {
1958 int type;
1959 union node *ch1;
1960 union node *ch2;
1961};
1962
1963struct nif {
1964 int type;
1965 union node *test;
1966 union node *ifpart;
1967 union node *elsepart;
1968};
1969
1970struct nfor {
1971 int type;
1972 union node *args;
1973 union node *body;
1974 char *var;
1975};
1976
1977struct ncase {
1978 int type;
1979 union node *expr;
1980 union node *cases;
1981};
1982
1983struct nclist {
1984 int type;
1985 union node *next;
1986 union node *pattern;
1987 union node *body;
1988};
1989
1990struct narg {
1991 int type;
1992 union node *next;
1993 char *text;
1994 struct nodelist *backquote;
1995};
1996
1997struct nfile {
1998 int type;
1999 union node *next;
2000 int fd;
2001 union node *fname;
2002 char *expfname;
2003};
2004
2005struct ndup {
2006 int type;
2007 union node *next;
2008 int fd;
2009 int dupfd;
2010 union node *vname;
2011};
2012
2013struct nhere {
2014 int type;
2015 union node *next;
2016 int fd;
2017 union node *doc;
2018};
2019
2020struct nnot {
2021 int type;
2022 union node *com;
2023};
2024
2025union node {
2026 int type;
2027 struct ncmd ncmd;
2028 struct npipe npipe;
2029 struct nredir nredir;
2030 struct nbinary nbinary;
2031 struct nif nif;
2032 struct nfor nfor;
2033 struct ncase ncase;
2034 struct nclist nclist;
2035 struct narg narg;
2036 struct nfile nfile;
2037 struct ndup ndup;
2038 struct nhere nhere;
2039 struct nnot nnot;
2040};
2041
2042struct nodelist {
2043 struct nodelist *next;
2044 union node *n;
2045};
2046
2047struct funcnode {
2048 int count;
2049 union node n;
2050};
2051
2052 2372
2053static void freefunc(struct funcnode *); 2373static void freefunc(struct funcnode *);
2054/* parser.h */ 2374/* parser.h */
@@ -2736,7 +3056,7 @@ static int funcnest; /* depth of function calls */
2736 */ 3056 */
2737 3057
2738#if JOBS 3058#if JOBS
2739static int bgcmd(int, char **); 3059static int fg_bgcmd(int, char **);
2740#endif 3060#endif
2741static int breakcmd(int, char **); 3061static int breakcmd(int, char **);
2742static int cdcmd(int, char **); 3062static int cdcmd(int, char **);
@@ -2755,9 +3075,6 @@ static int execcmd(int, char **);
2755static int exitcmd(int, char **); 3075static int exitcmd(int, char **);
2756static int exportcmd(int, char **); 3076static int exportcmd(int, char **);
2757static int falsecmd(int, char **); 3077static int falsecmd(int, char **);
2758#if JOBS
2759static int fgcmd(int, char **);
2760#endif
2761#if ENABLE_ASH_GETOPTS 3078#if ENABLE_ASH_GETOPTS
2762static int getoptscmd(int, char **); 3079static int getoptscmd(int, char **);
2763#endif 3080#endif
@@ -2840,7 +3157,7 @@ static const struct builtincmd builtincmd[] = {
2840 { BUILTIN_REG_ASSG "alias", aliascmd }, 3157 { BUILTIN_REG_ASSG "alias", aliascmd },
2841#endif 3158#endif
2842#if JOBS 3159#if JOBS
2843 { BUILTIN_REGULAR "bg", bgcmd }, 3160 { BUILTIN_REGULAR "bg", fg_bgcmd },
2844#endif 3161#endif
2845 { BUILTIN_SPEC_REG "break", breakcmd }, 3162 { BUILTIN_SPEC_REG "break", breakcmd },
2846 { BUILTIN_REGULAR "cd", cdcmd }, 3163 { BUILTIN_REGULAR "cd", cdcmd },
@@ -2858,7 +3175,7 @@ static const struct builtincmd builtincmd[] = {
2858 { BUILTIN_SPEC_REG_ASSG "export", exportcmd }, 3175 { BUILTIN_SPEC_REG_ASSG "export", exportcmd },
2859 { BUILTIN_REGULAR "false", falsecmd }, 3176 { BUILTIN_REGULAR "false", falsecmd },
2860#if JOBS 3177#if JOBS
2861 { BUILTIN_REGULAR "fg", fgcmd }, 3178 { BUILTIN_REGULAR "fg", fg_bgcmd },
2862#endif 3179#endif
2863#if ENABLE_ASH_GETOPTS 3180#if ENABLE_ASH_GETOPTS
2864 { BUILTIN_REGULAR "getopts", getoptscmd }, 3181 { BUILTIN_REGULAR "getopts", getoptscmd },
@@ -3033,25 +3350,12 @@ static void setjobctl(int);
3033static void showjobs(FILE *, int); 3350static void showjobs(FILE *, int);
3034#endif 3351#endif
3035 3352
3036/* main.h */
3037 3353
3354/* main.h */
3038 3355
3039static void readcmdfile(char *); 3356static void readcmdfile(char *);
3040 3357
3041 3358
3042/* mystring.h */
3043
3044
3045#define DOLATSTRLEN 4
3046
3047static char *prefix(const char *, const char *);
3048static int number(const char *);
3049static int is_number(const char *);
3050static char *single_quote(const char *);
3051
3052#define equal(s1, s2) (strcmp(s1, s2) == 0)
3053#define scopy(s1, s2) ((void)strcpy(s2, s1))
3054
3055/* options.h */ 3359/* options.h */
3056 3360
3057static char *minusc; /* argument to -c option */ 3361static char *minusc; /* argument to -c option */
@@ -3076,22 +3380,8 @@ static void clearredir(int);
3076static int copyfd(int, int); 3380static int copyfd(int, int);
3077static int redirectsafe(union node *, int); 3381static int redirectsafe(union node *, int);
3078 3382
3079/* show.h */
3080
3081
3082#if DEBUG
3083static void showtree(union node *);
3084static void trace(const char *, ...);
3085static void tracev(const char *, va_list);
3086static void trargs(char **);
3087static void trputc(int);
3088static void trputs(const char *);
3089static void opentrace(void);
3090#endif
3091
3092/* trap.h */ 3383/* trap.h */
3093 3384
3094
3095static void clear_traps(void); 3385static void clear_traps(void);
3096static void setsignal(int); 3386static void setsignal(int);
3097static void ignoresig(int); 3387static void ignoresig(int);
@@ -3137,11 +3427,67 @@ static int is_safe_applet(char *name)
3137 3427
3138 3428
3139#if ENABLE_ASH_ALIAS 3429#if ENABLE_ASH_ALIAS
3430struct alias {
3431 struct alias *next;
3432 char *name;
3433 char *val;
3434 int flag;
3435};
3436
3140static struct alias *atab[ATABSIZE]; 3437static struct alias *atab[ATABSIZE];
3141 3438
3142static void setalias(const char *, const char *); 3439static struct alias **
3143static struct alias *freealias(struct alias *); 3440__lookupalias(const char *name) {
3144static struct alias **__lookupalias(const char *); 3441 unsigned int hashval;
3442 struct alias **app;
3443 const char *p;
3444 unsigned int ch;
3445
3446 p = name;
3447
3448 ch = (unsigned char)*p;
3449 hashval = ch << 4;
3450 while (ch) {
3451 hashval += ch;
3452 ch = (unsigned char)*++p;
3453 }
3454 app = &atab[hashval % ATABSIZE];
3455
3456 for (; *app; app = &(*app)->next) {
3457 if (strcmp(name, (*app)->name) == 0) {
3458 break;
3459 }
3460 }
3461
3462 return app;
3463}
3464
3465static struct alias *
3466lookupalias(const char *name, int check)
3467{
3468 struct alias *ap = *__lookupalias(name);
3469
3470 if (check && ap && (ap->flag & ALIASINUSE))
3471 return NULL;
3472 return ap;
3473}
3474
3475static struct alias *
3476freealias(struct alias *ap)
3477{
3478 struct alias *next;
3479
3480 if (ap->flag & ALIASINUSE) {
3481 ap->flag |= ALIASDEAD;
3482 return ap;
3483 }
3484
3485 next = ap->next;
3486 free(ap->name);
3487 free(ap->val);
3488 free(ap);
3489 return next;
3490}
3145 3491
3146static void 3492static void
3147setalias(const char *name, const char *val) 3493setalias(const char *name, const char *val)
@@ -3205,16 +3551,6 @@ rmaliases(void)
3205 INT_ON; 3551 INT_ON;
3206} 3552}
3207 3553
3208static struct alias *
3209lookupalias(const char *name, int check)
3210{
3211 struct alias *ap = *__lookupalias(name);
3212
3213 if (check && ap && (ap->flag & ALIASINUSE))
3214 return NULL;
3215 return ap;
3216}
3217
3218/* 3554/*
3219 * TODO - sort output 3555 * TODO - sort output
3220 */ 3556 */
@@ -3273,54 +3609,11 @@ unaliascmd(int argc, char **argv)
3273 return i; 3609 return i;
3274} 3610}
3275 3611
3276static struct alias *
3277freealias(struct alias *ap)
3278{
3279 struct alias *next;
3280
3281 if (ap->flag & ALIASINUSE) {
3282 ap->flag |= ALIASDEAD;
3283 return ap;
3284 }
3285
3286 next = ap->next;
3287 free(ap->name);
3288 free(ap->val);
3289 free(ap);
3290 return next;
3291}
3292
3293static void 3612static void
3294printalias(const struct alias *ap) 3613printalias(const struct alias *ap)
3295{ 3614{
3296 out1fmt("%s=%s\n", ap->name, single_quote(ap->val)); 3615 out1fmt("%s=%s\n", ap->name, single_quote(ap->val));
3297} 3616}
3298
3299static struct alias **
3300__lookupalias(const char *name) {
3301 unsigned int hashval;
3302 struct alias **app;
3303 const char *p;
3304 unsigned int ch;
3305
3306 p = name;
3307
3308 ch = (unsigned char)*p;
3309 hashval = ch << 4;
3310 while (ch) {
3311 hashval += ch;
3312 ch = (unsigned char)*++p;
3313 }
3314 app = &atab[hashval % ATABSIZE];
3315
3316 for (; *app; app = &(*app)->next) {
3317 if (equal(name, (*app)->name)) {
3318 break;
3319 }
3320 }
3321
3322 return app;
3323}
3324#endif /* ASH_ALIAS */ 3617#endif /* ASH_ALIAS */
3325 3618
3326/* eval.c */ 3619/* eval.c */
@@ -3602,7 +3895,7 @@ evalsubshell(union node *n, int flags)
3602 flags |= EV_EXIT; 3895 flags |= EV_EXIT;
3603 if (backgnd) 3896 if (backgnd)
3604 flags &=~ EV_TESTED; 3897 flags &=~ EV_TESTED;
3605nofork: 3898 nofork:
3606 redirect(n->nredir.redirect, 0); 3899 redirect(n->nredir.redirect, 0);
3607 evaltreenr(n->nredir.n, flags); 3900 evaltreenr(n->nredir.n, flags);
3608 /* never returns */ 3901 /* never returns */
@@ -4789,7 +5082,7 @@ cmdlookup(const char *name, int add)
4789 hashval &= 0x7FFF; 5082 hashval &= 0x7FFF;
4790 pp = &cmdtable[hashval % CMDTABLESIZE]; 5083 pp = &cmdtable[hashval % CMDTABLESIZE];
4791 for (cmdp = *pp; cmdp; cmdp = cmdp->next) { 5084 for (cmdp = *pp; cmdp; cmdp = cmdp->next) {
4792 if (equal(cmdp->cmdname, name)) 5085 if (strcmp(cmdp->cmdname, name) == 0)
4793 break; 5086 break;
4794 pp = &cmdp->next; 5087 pp = &cmdp->next;
4795 } 5088 }
@@ -5292,7 +5585,7 @@ argstr(char *p, int flag)
5292 /* "$@" syntax adherence hack */ 5585 /* "$@" syntax adherence hack */
5293 if ( 5586 if (
5294 !inquotes && 5587 !inquotes &&
5295 !memcmp(p, dolatstr, DOLATSTRLEN) && 5588 !memcmp(p, dolatstr, 4) &&
5296 (p[4] == CTLQUOTEMARK || ( 5589 (p[4] == CTLQUOTEMARK || (
5297 p[4] == CTLENDVAR && 5590 p[4] == CTLENDVAR &&
5298 p[5] == CTLQUOTEMARK 5591 p[5] == CTLQUOTEMARK
@@ -6274,7 +6567,7 @@ expmeta(char *enddir, char *name)
6274 continue; 6567 continue;
6275 if (pmatch(start, dp->d_name)) { 6568 if (pmatch(start, dp->d_name)) {
6276 if (atend) { 6569 if (atend) {
6277 scopy(dp->d_name, enddir); 6570 strcpy(enddir, dp->d_name);
6278 addfname(expdir); 6571 addfname(expdir);
6279 } else { 6572 } else {
6280 for (p = enddir, cp = dp->d_name; (*p++ = *cp++) != '\0';) 6573 for (p = enddir, cp = dp->d_name; (*p++ = *cp++) != '\0';)
@@ -7186,7 +7479,7 @@ jobno(const struct job *jp)
7186 7479
7187#if JOBS 7480#if JOBS
7188static int 7481static int
7189fgcmd(int argc, char **argv) 7482fg_bgcmd(int argc, char **argv)
7190{ 7483{
7191 struct job *jp; 7484 struct job *jp;
7192 FILE *out; 7485 FILE *out;
@@ -7210,9 +7503,6 @@ fgcmd(int argc, char **argv)
7210 return retval; 7503 return retval;
7211} 7504}
7212 7505
7213static int bgcmd(int, char **) __attribute__((__alias__("fgcmd")));
7214
7215
7216static int 7506static int
7217restartjob(struct job *jp, int mode) 7507restartjob(struct job *jp, int mode)
7218{ 7508{
@@ -7313,8 +7603,8 @@ showjob(FILE *out, struct job *jp, int mode)
7313 psend = ps + jp->nprocs; 7603 psend = ps + jp->nprocs;
7314 7604
7315 if (jp->state == JOBRUNNING) { 7605 if (jp->state == JOBRUNNING) {
7316 scopy("Running", s + col); 7606 strcpy(s + col, "Running");
7317 col += strlen("Running"); 7607 col += sizeof("Running") - 1;
7318 } else { 7608 } else {
7319 int status = psend[-1].status; 7609 int status = psend[-1].status;
7320#if JOBS 7610#if JOBS
@@ -7359,19 +7649,20 @@ jobscmd(int argc, char **argv)
7359 FILE *out; 7649 FILE *out;
7360 7650
7361 mode = 0; 7651 mode = 0;
7362 while ((m = nextopt("lp"))) 7652 while ((m = nextopt("lp"))) {
7363 if (m == 'l') 7653 if (m == 'l')
7364 mode = SHOW_PID; 7654 mode = SHOW_PID;
7365 else 7655 else
7366 mode = SHOW_PGID; 7656 mode = SHOW_PGID;
7657 }
7367 7658
7368 out = stdout; 7659 out = stdout;
7369 argv = argptr; 7660 argv = argptr;
7370 if (*argv) 7661 if (*argv) {
7371 do 7662 do
7372 showjob(out, getjob(*argv,0), mode); 7663 showjob(out, getjob(*argv,0), mode);
7373 while (*++argv); 7664 while (*++argv);
7374 else 7665 } else
7375 showjobs(out, mode); 7666 showjobs(out, mode);
7376 7667
7377 return 0; 7668 return 0;
@@ -7515,7 +7806,8 @@ getjob(const char *name, int getctl)
7515 currentjob: 7806 currentjob:
7516 err_msg = "No current job"; 7807 err_msg = "No current job";
7517 goto check; 7808 goto check;
7518 } else if (c == '-') { 7809 }
7810 if (c == '-') {
7519 if (jp) 7811 if (jp)
7520 jp = jp->prev_job; 7812 jp = jp->prev_job;
7521 err_msg = "No previous job"; 7813 err_msg = "No previous job";
@@ -7571,7 +7863,6 @@ getjob(const char *name, int getctl)
7571 * Return a new job structure. 7863 * Return a new job structure.
7572 * Called with interrupts off. 7864 * Called with interrupts off.
7573 */ 7865 */
7574
7575static struct job * 7866static struct job *
7576makejob(union node *node, int nprocs) 7867makejob(union node *node, int nprocs)
7577{ 7868{
@@ -7720,7 +8011,7 @@ static void forkchild(struct job *jp, union node *n, int mode)
7720 8011
7721static void forkparent(struct job *jp, union node *n, int mode, pid_t pid) 8012static void forkparent(struct job *jp, union node *n, int mode, pid_t pid)
7722{ 8013{
7723 TRACE(("In parent shell: child = %d\n", pid)); 8014 TRACE(("In parent shell: child = %d\n", pid));
7724 if (!jp) { 8015 if (!jp) {
7725 while (jobless && dowait(DOWAIT_NORMAL, 0) > 0); 8016 while (jobless && dowait(DOWAIT_NORMAL, 0) > 0);
7726 jobless++; 8017 jobless++;
@@ -7735,7 +8026,7 @@ static void forkparent(struct job *jp, union node *n, int mode, pid_t pid)
7735 else 8026 else
7736 pgrp = jp->ps[0].pid; 8027 pgrp = jp->ps[0].pid;
7737 /* This can fail because we are doing it in the child also */ 8028 /* This can fail because we are doing it in the child also */
7738 (void)setpgid(pid, pgrp); 8029 setpgid(pid, pgrp);
7739 } 8030 }
7740#endif 8031#endif
7741 if (mode == FORK_BG) { 8032 if (mode == FORK_BG) {
@@ -7854,7 +8145,8 @@ waitforjob(struct job *jp)
7854 * (as opposed to running a builtin command or just typing return), 8145 * (as opposed to running a builtin command or just typing return),
7855 * and the jobs command may give out of date information. 8146 * and the jobs command may give out of date information.
7856 */ 8147 */
7857static int waitproc(int block, int *status) 8148static int
8149waitproc(int block, int *status)
7858{ 8150{
7859 int flags = 0; 8151 int flags = 0;
7860 8152
@@ -8147,10 +8439,9 @@ cmdtxt(union node *n)
8147 s[0] = n->ndup.dupfd + '0'; 8439 s[0] = n->ndup.dupfd + '0';
8148 p = s; 8440 p = s;
8149 goto dotail2; 8441 goto dotail2;
8150 } else {
8151 n = n->nfile.fname;
8152 goto donode;
8153 } 8442 }
8443 n = n->nfile.fname;
8444 goto donode;
8154 } 8445 }
8155} 8446}
8156 8447
@@ -8178,6 +8469,7 @@ cmdputs(const char *s)
8178 "", "}", "-", "+", "?", "=", 8469 "", "}", "-", "+", "?", "=",
8179 "%", "%%", "#", "##" 8470 "%", "%%", "#", "##"
8180 }; 8471 };
8472
8181 nextc = makestrspace((strlen(s) + 1) * 8, cmdnextc); 8473 nextc = makestrspace((strlen(s) + 1) * 8, cmdnextc);
8182 p = s; 8474 p = s;
8183 while ((c = *p++) != 0) { 8475 while ((c = *p++) != 0) {
@@ -8192,11 +8484,10 @@ cmdputs(const char *s)
8192 str = "${#"; 8484 str = "${#";
8193 else 8485 else
8194 str = "${"; 8486 str = "${";
8195 if (!(subtype & VSQUOTE) != !(quoted & 1)) { 8487 if (!(subtype & VSQUOTE) == !(quoted & 1))
8196 quoted ^= 1;
8197 c = '"';
8198 } else
8199 goto dostr; 8488 goto dostr;
8489 quoted ^= 1;
8490 c = '"';
8200 break; 8491 break;
8201 case CTLENDVAR: 8492 case CTLENDVAR:
8202 str = "\"}" + !(quoted & 1); 8493 str = "\"}" + !(quoted & 1);
@@ -8650,7 +8941,7 @@ minus_o(char *name, int val)
8650 8941
8651 if (name) { 8942 if (name) {
8652 for (i = 0; i < NOPTS; i++) { 8943 for (i = 0; i < NOPTS; i++) {
8653 if (equal(name, optnames(i))) { 8944 if (strcmp(name, optnames(i)) == 0) {
8654 optlist[i] = val; 8945 optlist[i] = val;
8655 return; 8946 return;
8656 } 8947 }
@@ -8859,13 +9150,15 @@ setcmd(int argc, char **argv)
8859 9150
8860 9151
8861#if ENABLE_LOCALE_SUPPORT 9152#if ENABLE_LOCALE_SUPPORT
8862static void change_lc_all(const char *value) 9153static void
9154change_lc_all(const char *value)
8863{ 9155{
8864 if (value && *value != '\0') 9156 if (value && *value != '\0')
8865 setlocale(LC_ALL, value); 9157 setlocale(LC_ALL, value);
8866} 9158}
8867 9159
8868static void change_lc_ctype(const char *value) 9160static void
9161change_lc_ctype(const char *value)
8869{ 9162{
8870 if (value && *value != '\0') 9163 if (value && *value != '\0')
8871 setlocale(LC_CTYPE, value); 9164 setlocale(LC_CTYPE, value);
@@ -8874,7 +9167,8 @@ static void change_lc_ctype(const char *value)
8874 9167
8875#if ENABLE_ASH_RANDOM_SUPPORT 9168#if ENABLE_ASH_RANDOM_SUPPORT
8876/* Roughly copied from bash.. */ 9169/* Roughly copied from bash.. */
8877static void change_random(const char *value) 9170static void
9171change_random(const char *value)
8878{ 9172{
8879 if (value == NULL) { 9173 if (value == NULL) {
8880 /* "get", generate */ 9174 /* "get", generate */
@@ -11036,349 +11330,6 @@ redirectsafe(union node *redir, int flags)
11036 return err; 11330 return err;
11037} 11331}
11038 11332
11039/* show.c */
11040
11041#if DEBUG
11042static void shtree(union node *, int, char *, FILE*);
11043static void shcmd(union node *, FILE *);
11044static void sharg(union node *, FILE *);
11045static void indent(int, char *, FILE *);
11046static void trstring(char *);
11047
11048static void
11049showtree(union node *n)
11050{
11051 trputs("showtree called\n");
11052 shtree(n, 1, NULL, stdout);
11053}
11054
11055static void
11056shtree(union node *n, int ind, char *pfx, FILE *fp)
11057{
11058 struct nodelist *lp;
11059 const char *s;
11060
11061 if (n == NULL)
11062 return;
11063
11064 indent(ind, pfx, fp);
11065 switch (n->type) {
11066 case NSEMI:
11067 s = "; ";
11068 goto binop;
11069 case NAND:
11070 s = " && ";
11071 goto binop;
11072 case NOR:
11073 s = " || ";
11074 binop:
11075 shtree(n->nbinary.ch1, ind, NULL, fp);
11076 /* if (ind < 0) */
11077 fputs(s, fp);
11078 shtree(n->nbinary.ch2, ind, NULL, fp);
11079 break;
11080 case NCMD:
11081 shcmd(n, fp);
11082 if (ind >= 0)
11083 putc('\n', fp);
11084 break;
11085 case NPIPE:
11086 for (lp = n->npipe.cmdlist; lp; lp = lp->next) {
11087 shcmd(lp->n, fp);
11088 if (lp->next)
11089 fputs(" | ", fp);
11090 }
11091 if (n->npipe.backgnd)
11092 fputs(" &", fp);
11093 if (ind >= 0)
11094 putc('\n', fp);
11095 break;
11096 default:
11097 fprintf(fp, "<node type %d>", n->type);
11098 if (ind >= 0)
11099 putc('\n', fp);
11100 break;
11101 }
11102}
11103
11104static void
11105shcmd(union node *cmd, FILE *fp)
11106{
11107 union node *np;
11108 int first;
11109 const char *s;
11110 int dftfd;
11111
11112 first = 1;
11113 for (np = cmd->ncmd.args; np; np = np->narg.next) {
11114 if (! first)
11115 putchar(' ');
11116 sharg(np, fp);
11117 first = 0;
11118 }
11119 for (np = cmd->ncmd.redirect; np; np = np->nfile.next) {
11120 if (! first)
11121 putchar(' ');
11122 switch (np->nfile.type) {
11123 case NTO: s = ">"; dftfd = 1; break;
11124 case NCLOBBER: s = ">|"; dftfd = 1; break;
11125 case NAPPEND: s = ">>"; dftfd = 1; break;
11126 case NTOFD: s = ">&"; dftfd = 1; break;
11127 case NFROM: s = "<"; dftfd = 0; break;
11128 case NFROMFD: s = "<&"; dftfd = 0; break;
11129 case NFROMTO: s = "<>"; dftfd = 0; break;
11130 default: s = "*error*"; dftfd = 0; break;
11131 }
11132 if (np->nfile.fd != dftfd)
11133 fprintf(fp, "%d", np->nfile.fd);
11134 fputs(s, fp);
11135 if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) {
11136 fprintf(fp, "%d", np->ndup.dupfd);
11137 } else {
11138 sharg(np->nfile.fname, fp);
11139 }
11140 first = 0;
11141 }
11142}
11143
11144static void
11145sharg(union node *arg, FILE *fp)
11146{
11147 char *p;
11148 struct nodelist *bqlist;
11149 int subtype;
11150
11151 if (arg->type != NARG) {
11152 out1fmt("<node type %d>\n", arg->type);
11153 abort();
11154 }
11155 bqlist = arg->narg.backquote;
11156 for (p = arg->narg.text; *p; p++) {
11157 switch (*p) {
11158 case CTLESC:
11159 putc(*++p, fp);
11160 break;
11161 case CTLVAR:
11162 putc('$', fp);
11163 putc('{', fp);
11164 subtype = *++p;
11165 if (subtype == VSLENGTH)
11166 putc('#', fp);
11167
11168 while (*p != '=')
11169 putc(*p++, fp);
11170
11171 if (subtype & VSNUL)
11172 putc(':', fp);
11173
11174 switch (subtype & VSTYPE) {
11175 case VSNORMAL:
11176 putc('}', fp);
11177 break;
11178 case VSMINUS:
11179 putc('-', fp);
11180 break;
11181 case VSPLUS:
11182 putc('+', fp);
11183 break;
11184 case VSQUESTION:
11185 putc('?', fp);
11186 break;
11187 case VSASSIGN:
11188 putc('=', fp);
11189 break;
11190 case VSTRIMLEFT:
11191 putc('#', fp);
11192 break;
11193 case VSTRIMLEFTMAX:
11194 putc('#', fp);
11195 putc('#', fp);
11196 break;
11197 case VSTRIMRIGHT:
11198 putc('%', fp);
11199 break;
11200 case VSTRIMRIGHTMAX:
11201 putc('%', fp);
11202 putc('%', fp);
11203 break;
11204 case VSLENGTH:
11205 break;
11206 default:
11207 out1fmt("<subtype %d>", subtype);
11208 }
11209 break;
11210 case CTLENDVAR:
11211 putc('}', fp);
11212 break;
11213 case CTLBACKQ:
11214 case CTLBACKQ|CTLQUOTE:
11215 putc('$', fp);
11216 putc('(', fp);
11217 shtree(bqlist->n, -1, NULL, fp);
11218 putc(')', fp);
11219 break;
11220 default:
11221 putc(*p, fp);
11222 break;
11223 }
11224 }
11225}
11226
11227
11228static void
11229indent(int amount, char *pfx, FILE *fp)
11230{
11231 int i;
11232
11233 for (i = 0; i < amount; i++) {
11234 if (pfx && i == amount - 1)
11235 fputs(pfx, fp);
11236 putc('\t', fp);
11237 }
11238}
11239
11240
11241/*
11242 * Debugging stuff.
11243 */
11244
11245
11246static FILE *tracefile;
11247
11248
11249static void
11250trputc(int c)
11251{
11252 if (debug != 1)
11253 return;
11254 putc(c, tracefile);
11255}
11256
11257static void
11258trace(const char *fmt, ...)
11259{
11260 va_list va;
11261
11262 if (debug != 1)
11263 return;
11264 va_start(va, fmt);
11265 (void) vfprintf(tracefile, fmt, va);
11266 va_end(va);
11267}
11268
11269static void
11270tracev(const char *fmt, va_list va)
11271{
11272 if (debug != 1)
11273 return;
11274 (void) vfprintf(tracefile, fmt, va);
11275}
11276
11277
11278static void
11279trputs(const char *s)
11280{
11281 if (debug != 1)
11282 return;
11283 fputs(s, tracefile);
11284}
11285
11286
11287static void
11288trstring(char *s)
11289{
11290 char *p;
11291 char c;
11292
11293 if (debug != 1)
11294 return;
11295 putc('"', tracefile);
11296 for (p = s; *p; p++) {
11297 switch (*p) {
11298 case '\n': c = 'n'; goto backslash;
11299 case '\t': c = 't'; goto backslash;
11300 case '\r': c = 'r'; goto backslash;
11301 case '"': c = '"'; goto backslash;
11302 case '\\': c = '\\'; goto backslash;
11303 case CTLESC: c = 'e'; goto backslash;
11304 case CTLVAR: c = 'v'; goto backslash;
11305 case CTLVAR+CTLQUOTE: c = 'V'; goto backslash;
11306 case CTLBACKQ: c = 'q'; goto backslash;
11307 case CTLBACKQ+CTLQUOTE: c = 'Q'; goto backslash;
11308 backslash:
11309 putc('\\', tracefile);
11310 putc(c, tracefile);
11311 break;
11312 default:
11313 if (*p >= ' ' && *p <= '~')
11314 putc(*p, tracefile);
11315 else {
11316 putc('\\', tracefile);
11317 putc(*p >> 6 & 03, tracefile);
11318 putc(*p >> 3 & 07, tracefile);
11319 putc(*p & 07, tracefile);
11320 }
11321 break;
11322 }
11323 }
11324 putc('"', tracefile);
11325}
11326
11327
11328static void
11329trargs(char **ap)
11330{
11331 if (debug != 1)
11332 return;
11333 while (*ap) {
11334 trstring(*ap++);
11335 if (*ap)
11336 putc(' ', tracefile);
11337 else
11338 putc('\n', tracefile);
11339 }
11340}
11341
11342
11343static void
11344opentrace(void)
11345{
11346 char s[100];
11347#ifdef O_APPEND
11348 int flags;
11349#endif
11350
11351 if (debug != 1) {
11352 if (tracefile)
11353 fflush(tracefile);
11354 /* leave open because libedit might be using it */
11355 return;
11356 }
11357 scopy("./trace", s);
11358 if (tracefile) {
11359 if (!freopen(s, "a", tracefile)) {
11360 fprintf(stderr, "Can't re-open %s\n", s);
11361 debug = 0;
11362 return;
11363 }
11364 } else {
11365 tracefile = fopen(s, "a");
11366 if (tracefile == NULL) {
11367 fprintf(stderr, "Can't open %s\n", s);
11368 debug = 0;
11369 return;
11370 }
11371 }
11372#ifdef O_APPEND
11373 flags = fcntl(fileno(tracefile), F_GETFL, 0);
11374 if (flags >= 0)
11375 fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND);
11376#endif
11377 setlinebuf(tracefile);
11378 fputs("\nTracing started.\n", tracefile);
11379}
11380#endif /* DEBUG */
11381
11382 11333
11383/* trap.c */ 11334/* trap.c */
11384 11335
@@ -13215,18 +13166,17 @@ int ash_main(int argc, char **argv)
13215 FORCE_INT_ON; /* enable interrupts */ 13166 FORCE_INT_ON; /* enable interrupts */
13216 if (s == 1) 13167 if (s == 1)
13217 goto state1; 13168 goto state1;
13218 else if (s == 2) 13169 if (s == 2)
13219 goto state2; 13170 goto state2;
13220 else if (s == 3) 13171 if (s == 3)
13221 goto state3; 13172 goto state3;
13222 else 13173 goto state4;
13223 goto state4;
13224 } 13174 }
13225 exception_handler = &jmploc; 13175 exception_handler = &jmploc;
13226#if DEBUG 13176#if DEBUG
13227 opentrace(); 13177 opentrace();
13228 trputs("Shell args: "); 13178 trace_puts("Shell args: ");
13229 trargs(argv); 13179 trace_puts_args(argv);
13230#endif 13180#endif
13231 rootpid = getpid(); 13181 rootpid = getpid();
13232 13182