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 + -
显示快捷键?