msh.c
来自「手机嵌入式Linux下可用的busybox源码」· C语言 代码 · 共 3,606 行 · 第 1/5 页
C
3,606 行
fail(); scraphere(); freehere(1); runtrap(0); _exit(exstat); /* NOTREACHED */}void warn(s)register char *s;{ if (*s) { prs(s); exstat = -1; } prs("\n"); if (flag['e']) leave();}void err(s)char *s;{ warn(s); if (flag['n']) return; if (!interactive) leave(); if (e.errpt) longjmp(e.errpt, 1); closeall(); e.iop = e.iobase = iostack;}int newenv(f)int f;{ register struct env *ep; if (f) { quitenv(); return (1); } ep = (struct env *) space(sizeof(*ep)); if (ep == NULL) { while (e.oenv) quitenv(); fail(); } *ep = e; e.oenv = ep; e.errpt = errpt; return (0);}void quitenv(){ register struct env *ep; int fd; if ((ep = e.oenv) != NULL) { fd = e.iofd; e = *ep; /* should close `'d files */ freecell(ep); while (--fd >= e.iofd) close(fd); }}/* * Is any character from s1 in s2? */int anys(s1, s2)register char *s1, *s2;{ while (*s1) if (any(*s1++, s2)) return (1); return (0);}/* * Is character c in s? */int any(c, s)register int c;register char *s;{ while (*s) if (*s++ == c) return (1); return (0);}char *putn(n)register int n;{ return (itoa(n, -1));}char *itoa(u, n)register unsigned u;int n;{ register char *cp; static char s[20]; int m; m = 0; if (n < 0 && (int) u < 0) { m++; u = -u; } cp = s + sizeof(s); *--cp = 0; do { *--cp = u % 10 + '0'; u /= 10; } while (--n > 0 || u); if (m) *--cp = '-'; return (cp);}void next(f)int f;{ PUSHIO(afile, f, filechar);}void onintr(s)int s; /* ANSI C requires a parameter */{ signal(SIGINT, onintr); intr = 1; if (interactive) { if (inparse) { prs("\n"); fail(); } } else if (heedint) { execflg = 0; leave(); }}int letter(c)int c;{ return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_');}int digit(c)int c;{ return (c >= '0' && c <= '9');}int letnum(c)int c;{ return (letter(c) || digit(c));}char *space(n)int n;{ register char *cp; if ((cp = getcell(n)) == 0) err("out of string space"); return (cp);}char *strsave(s, a)register char *s;int a;{ register char *cp, *xp; if ((cp = space(strlen(s) + 1)) != NULL) { setarea((char *) cp, a); for (xp = cp; (*xp++ = *s++) != '\0';); return (cp); } return ("");}/* * trap handling */void sig(i)register int i;{ trapset = i; signal(i, sig);}void runtrap(i)int i;{ char *trapstr; if ((trapstr = trap[i]) == NULL) return; if (i == 0) trap[i] = 0; RUN(aword, trapstr, nlchar);}/* -------- var.c -------- *//* * Find the given name in the dictionary * and return its value. If the name was * not previously there, enter it now and * return a null value. */struct var *lookup(n)register char *n;{ register struct var *vp; register char *cp; register int c; static struct var dummy; if (digit(*n)) { dummy.name = n; for (c = 0; digit(*n) && c < 1000; n++) c = c * 10 + *n - '0'; dummy.status = RONLY; dummy.value = c <= dolc ? dolv[c] : null; return (&dummy); } for (vp = vlist; vp; vp = vp->next) if (eqname(vp->name, n)) return (vp); cp = findeq(n); vp = (struct var *) space(sizeof(*vp)); if (vp == 0 || (vp->name = space((int) (cp - n) + 2)) == 0) { dummy.name = dummy.value = ""; return (&dummy); } for (cp = vp->name; (*cp = *n++) && *cp != '='; cp++); if (*cp == 0) *cp = '='; *++cp = 0; setarea((char *) vp, 0); setarea((char *) vp->name, 0); vp->value = null; vp->next = vlist; vp->status = GETCELL; vlist = vp; return (vp);}/* * give variable at `vp' the value `val'. */void setval(vp, val)struct var *vp;char *val;{ nameval(vp, val, (char *) NULL);}/* * if name is not NULL, it must be * a prefix of the space `val', * and end with `='. * this is all so that exporting * values is reasonably painless. */void nameval(vp, val, name)register struct var *vp;char *val, *name;{ register char *cp, *xp; char *nv; int fl; if (vp->status & RONLY) { for (xp = vp->name; *xp && *xp != '=';) put1c(*xp++); err(" is read-only"); return; } fl = 0; if (name == NULL) { xp = space(strlen(vp->name) + strlen(val) + 2); if (xp == 0) return; /* make string: name=value */ setarea((char *) xp, 0); name = xp; for (cp = vp->name; (*xp = *cp++) && *xp != '='; xp++); if (*xp++ == 0) xp[-1] = '='; nv = xp; for (cp = val; (*xp++ = *cp++) != '\0';); val = nv; fl = GETCELL; } if (vp->status & GETCELL) freecell(vp->name); /* form new string `name=value' */ vp->name = name; vp->value = val; vp->status |= fl;}void export(vp)struct var *vp;{ vp->status |= EXPORT;}void ronly(vp)struct var *vp;{ if (letter(vp->name[0])) /* not an internal symbol ($# etc) */ vp->status |= RONLY;}int isassign(s)register char *s;{ if (!letter((int) *s)) return (0); for (; *s != '='; s++) if (*s == 0 || !letnum(*s)) return (0); return (1);}int assign(s, cf)register char *s;int cf;{ register char *cp; struct var *vp; if (!letter(*s)) return (0); for (cp = s; *cp != '='; cp++) if (*cp == 0 || !letnum(*cp)) return (0); vp = lookup(s); nameval(vp, ++cp, cf == COPYV ? (char *) NULL : s); if (cf != COPYV) vp->status &= ~GETCELL; return (1);}int checkname(cp)register char *cp;{ if (!letter(*cp++)) return (0); while (*cp) if (!letnum(*cp++)) return (0); return (1);}void putvlist(f, out)register int f, out;{ register struct var *vp; for (vp = vlist; vp; vp = vp->next) if (vp->status & f && letter(*vp->name)) { if (vp->status & EXPORT) write(out, "export ", 7); if (vp->status & RONLY) write(out, "readonly ", 9); write(out, vp->name, (int) (findeq(vp->name) - vp->name)); write(out, "\n", 1); }}int eqname(n1, n2)register char *n1, *n2;{ for (; *n1 != '=' && *n1 != 0; n1++) if (*n2++ != *n1) return (0); return (*n2 == 0 || *n2 == '=');}static char *findeq(cp)register char *cp;{ while (*cp != '\0' && *cp != '=') cp++; return (cp);}/* -------- gmatch.c -------- *//* * int gmatch(string, pattern) * char *string, *pattern; * * Match a pattern as in sh(1). */#define CMASK 0377#define QUOTE 0200#define QMASK (CMASK&~QUOTE)#define NOT '!' /* might use ^ */int gmatch(s, p)register char *s, *p;{ register int sc, pc; if (s == NULL || p == NULL) return (0); while ((pc = *p++ & CMASK) != '\0') { sc = *s++ & QMASK; switch (pc) { case '[': if ((p = cclass(p, sc)) == NULL) return (0); break; case '?': if (sc == 0) return (0); break; case '*': s--; do { if (*p == '\0' || gmatch(s, p)) return (1); } while (*s++ != '\0'); return (0); default: if (sc != (pc & ~QUOTE)) return (0); } } return (*s == 0);}static char *cclass(p, sub)register char *p;register int sub;{ register int c, d, not, found; if ((not = *p == NOT) != 0) p++; found = not; do { if (*p == '\0') return ((char *) NULL); c = *p & CMASK; if (p[1] == '-' && p[2] != ']') { d = p[2] & CMASK; p++; } else d = c; if (c == sub || (c <= sub && sub <= d)) found = !not; } while (*++p != ']'); return (found ? p + 1 : (char *) NULL);}/* -------- area.c -------- */#define REGSIZE sizeof(struct region)#define GROWBY 256#define FREE 32767#define BUSY 0#define ALIGN (sizeof(int)-1)/* #include "area.h" */struct region { struct region *next; int area;};/* * All memory between (char *)areabot and (char *)(areatop+1) is * exclusively administered by the area management routines. */#define sbrk(X) ({ void * __q = (void *)-1; if (brkaddr + (int)(X) < brktop) { __q = brkaddr; brkaddr+=(int)(X); } __q;})static struct region *areabot; /* bottom of area */static struct region *areatop; /* top of area */static struct region *areanxt; /* starting point of scan */static void *brktop;static void *brkaddr;static void initarea(){ brkaddr = malloc(65000); brktop = brkaddr + 65000; while ((int) sbrk(0) & ALIGN) sbrk(1); areabot = (struct region *) sbrk(REGSIZE); areabot->next = areabot; areabot->area = BUSY; areatop = areabot; areanxt = areabot;}char *getcell(nbytes)unsigned nbytes;{ int nregio; register struct region *p, *q; int i; if (nbytes == 0) /* silly and defeats the algorithm */ Abort(); /* * round upwards and add administration area */ nregio = (nbytes + (REGSIZE - 1)) / REGSIZE + 1; for (p = areanxt;;) { if (p->area > areanum) { /* * merge free cells */ while ((q = p->next)->area > areanum && q != areanxt) p->next = q->next; /* * exit loop if cell big enough */ if (q >= p + nregio) goto found; } p = p->next; if (p == areanxt) break; } i = nregio >= GROWBY ? nregio : GROWBY; p = (struct region *) sbrk(i * REGSIZE); if (p == (struct region *) -1) return ((char *) NULL); p--; if (p != areatop) /* allocated areas are contiguous */ Abort(); q = p + i; p->next = q; p->area = FREE; q->next = areabot; q->area = BUSY; areatop = q; found: /* * we found a FREE area big enough, pointed to by 'p', and up to 'q' */ areanxt = p + nregio; if (areanxt < q) { /* * split into requested area and rest */ if (areanxt + 1 > q) /* insufficient space left for admin */ Abort(); areanxt->next = q; areanxt->area = FREE; p->next = areanxt; } p->area = areanum; return ((char *) (p + 1));}void freecell(void *cp){ register struct region *p; if ((p = (struct region *) cp) != NULL) { p--; if (p < areanxt) areanxt = p; p->area = FREE; }}void freearea(a)register int a;{ register struct region *p, *top; top = areatop; for (p = areabot; p != top; p = p->next) if (p->area >= a) p->area = FREE;}void setarea(cp, a)char *cp;int a;{ register struct region *p; if ((p = (struct region *) cp) != NULL) (p - 1)->area = a;}int getarea(cp)char *cp;{ return ((struct region *) cp - 1)->area;}void garbage(){ register struct region *p, *q, *top; top = areatop; for (p = areabot; p != top; p = p->next) { if (p->area > areanum) { while ((q = p->next)->area > areanum) p->next = q->next; areanxt = p; } }}/* -------- csyn.c -------- *//* * shell: syntax (C version) */typedef union { char *cp; char **wp; int i; struct op *o;} YYSTYPE;#define WORD 256#define LOGAND 257#define LOGOR 258#define BREAK 259#define IF 260#define THEN 261#define ELSE 262#define ELIF 263#define FI 264#define CASE 265#define ESAC 266#define FOR 267#define WHILE 268#define UNTIL 269#define DO 270#define DONE 271#define IN 272#define YYERRCODE 300/* flags to yylex */#define CONTIN 01 /* skip new lines to complete command */#define SYNTAXERR zzerr()static int startl;static int peeksym;static int nlseen;static int iounit = IODEFAULT;static YYSTYPE yylval;static struct op *pipeline(int cf);static struct op *andor(void);static struct op *c_list(void);static int synio(int cf);static void musthave(int c, int cf);static struct op *simple(void);static struct op *nested(int type, int mark);static struct op *command(int cf);static struct op *dogroup(int onlydone);static struct op *thenpart(void);static struct op *elsepart(void);static struct op *caselist(void);static struct op *casepart(void);static char **pattern(void);static char **wordlist(void);static struct op *list(struct op *t1, struct op *t2);static struct op *block(int type, struct op *t1, struct op *t2, char **wp);static struct op *newtp(void);static struct op *namelist(struct op *t);static char **copyw(void);static void word(char *cp);static struct ioword **copyio(void);static struct ioword *io(int u, int f, char *cp);static void zzerr(void);static void yyerror(char *s);static int yylex(int cf);static int collect(int c, int c1);static int dual(int c);static void diag(int ec);static char *tree(unsigned size);int yyparse(){ startl = 1; peeksym = 0; yynerrs = 0; outtree = c_list(); musthave('\n', 0); return (yynerrs != 0);}static struct op *pipeline(cf)int cf;{ register struct op *t, *p; register int c; t = command(cf);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?