⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sh3.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
#define Extern extern#include <sys/types.h>#include <signal.h>#include <errno.h>#include <setjmp.h>#include <stddef.h>#include <time.h>#include <sys/times.h>#include <sys/stat.h>#include <sys/wait.h>#undef NULL#include "sh.h"/* -------- exec.c -------- *//* #include "sh.h" *//* * execute tree */static	char	*signame[] = {	"Signal 0",	"Hangup",	(char *)NULL,	/* interrupt */	"Quit",	"Illegal instruction",	"Trace/BPT trap",	"Abort",	"EMT trap",	"Floating exception",	"Killed",	"Bus error",	"Memory fault",	"Bad system call",	(char *)NULL,	/* broken pipe */	"Alarm clock",	"Terminated",};#define	NSIGNAL (sizeof(signame)/sizeof(signame[0]))_PROTOTYPE(static int forkexec, (struct op *t, int *pin, int *pout, int act, char **wp, int *pforked ));_PROTOTYPE(static int parent, (void));_PROTOTYPE(int iosetup, (struct ioword *iop, int pipein, int pipeout ));_PROTOTYPE(static void echo, (char **wp ));_PROTOTYPE(static struct op **find1case, (struct op *t, char *w ));_PROTOTYPE(static struct op *findcase, (struct op *t, char *w ));_PROTOTYPE(static void brkset, (struct brkcon *bc ));_PROTOTYPE(int dolabel, (void));_PROTOTYPE(int dochdir, (struct op *t ));_PROTOTYPE(int doshift, (struct op *t ));_PROTOTYPE(int dologin, (struct op *t ));_PROTOTYPE(int doumask, (struct op *t ));_PROTOTYPE(int doexec, (struct op *t ));_PROTOTYPE(int dodot, (struct op *t ));_PROTOTYPE(int dowait, (struct op *t ));_PROTOTYPE(int doread, (struct op *t ));_PROTOTYPE(int doeval, (struct op *t ));_PROTOTYPE(int dotrap, (struct op *t ));_PROTOTYPE(int getsig, (char *s ));_PROTOTYPE(void setsig, (int n, void (*f)()));_PROTOTYPE(int getn, (char *as ));_PROTOTYPE(int dobreak, (struct op *t ));_PROTOTYPE(int docontinue, (struct op *t ));_PROTOTYPE(static int brkcontin, (char *cp, int val ));_PROTOTYPE(int doexit, (struct op *t ));_PROTOTYPE(int doexport, (struct op *t ));_PROTOTYPE(int doreadonly, (struct op *t ));_PROTOTYPE(static void rdexp, (char **wp, void (*f)(), int key));_PROTOTYPE(static void badid, (char *s ));_PROTOTYPE(int doset, (struct op *t ));_PROTOTYPE(void varput, (char *s, int out ));_PROTOTYPE(int dotimes, (void));intexecute(t, pin, pout, act)register struct op *t;int *pin, *pout;int act;{	register struct op *t1;	int i, pv[2], rv, child, a;	char *cp, **wp, **wp2;	struct var *vp;	struct brkcon bc;	if (t == NULL)		return(0);	rv = 0;	a = areanum++;	wp = (wp2 = t->words) != NULL	     ? eval(wp2, t->type == TCOM ? DOALL : DOALL & ~DOKEY)	     : NULL;	switch(t->type) {	case TPAREN:	case TCOM:		rv = forkexec(t, pin, pout, act, wp, &child);		if (child) {			exstat = rv;			leave();		}		break;	case TPIPE:		if ((rv = openpipe(pv)) < 0)			break;		pv[0] = remap(pv[0]);		pv[1] = remap(pv[1]);		(void) execute(t->left, pin, pv, 0);		rv = execute(t->right, pv, pout, 0);		break;	case TLIST:		(void) execute(t->left, pin, pout, 0);		rv = execute(t->right, pin, pout, 0);		break;	case TASYNC:		i = parent();		if (i != 0) {			if (i != -1) {				setval(lookup("!"), putn(i));				if (pin != NULL)					closepipe(pin);				if (talking) {					prs(putn(i));					prs("\n");				}			} else				rv = -1;			setstatus(rv);		} else {			signal(SIGINT, SIG_IGN);			signal(SIGQUIT, SIG_IGN);			if (talking)				signal(SIGTERM, SIG_DFL);			talking = 0;			if (pin == NULL) {				close(0);				open("/dev/null", 0);			}			exit(execute(t->left, pin, pout, FEXEC));		}		break;	case TOR:	case TAND:		rv = execute(t->left, pin, pout, 0);		if ((t1 = t->right)!=NULL && (rv == 0) == (t->type == TAND))			rv = execute(t1, pin, pout, 0);		break;	case TFOR:		if (wp == NULL) {			wp = dolv+1;			if ((i = dolc) < 0)				i = 0;		} else {			i = -1;			while (*wp++ != NULL)				;					}		vp = lookup(t->str);		while (setjmp(bc.brkpt))			if (isbreak)				goto broken;		brkset(&bc);		for (t1 = t->left; i-- && *wp != NULL;) {			setval(vp, *wp++);			rv = execute(t1, pin, pout, 0);		}		brklist = brklist->nextlev;		break;	case TWHILE:	case TUNTIL:		while (setjmp(bc.brkpt))			if (isbreak)				goto broken;		brkset(&bc);		t1 = t->left;		while ((execute(t1, pin, pout, 0) == 0) == (t->type == TWHILE))			rv = execute(t->right, pin, pout, 0);		brklist = brklist->nextlev;		break;	case TIF:	case TELIF:	 	if (t->right != NULL) {		rv = !execute(t->left, pin, pout, 0) ?			execute(t->right->left, pin, pout, 0):			execute(t->right->right, pin, pout, 0);		}		break;	case TCASE:		if ((cp = evalstr(t->str, DOSUB|DOTRIM)) == 0)			cp = "";		if ((t1 = findcase(t->left, cp)) != NULL)			rv = execute(t1, pin, pout, 0);		break;	case TBRACE:/*		if (iopp = t->ioact)			while (*iopp)				if (iosetup(*iopp++, pin!=NULL, pout!=NULL)) {					rv = -1;					break;				}*/		if (rv >= 0 && (t1 = t->left))			rv = execute(t1, pin, pout, 0);		break;	}broken:	t->words = wp2;	isbreak = 0;	freehere(areanum);	freearea(areanum);	areanum = a;	if (talking && intr) {		closeall();		fail();	}	if ((i = trapset) != 0) {		trapset = 0;		runtrap(i);	}	return(rv);}static intforkexec(t, pin, pout, act, wp, pforked)register struct op *t;int *pin, *pout;int act;char **wp;int *pforked;{	int i, rv, (*shcom)();	register int f;	char *cp;	struct ioword **iopp;	int resetsig;	char **owp;	owp = wp;	resetsig = 0;	*pforked = 0;	shcom = NULL;	rv = -1;	/* system-detected error */	if (t->type == TCOM) {		while ((cp = *wp++) != NULL)			;		cp = *wp;		/* strip all initial assignments */		/* not correct wrt PATH=yyy command  etc */		if (flag['x'])			echo (cp ? wp: owp);		if (cp == NULL && t->ioact == NULL) {			while ((cp = *owp++) != NULL && assign(cp, COPYV))				;			return(setstatus(0));		}		else if (cp != NULL)			shcom = inbuilt(cp);	}	t->words = wp;	f = act;	if (shcom == NULL && (f & FEXEC) == 0) {		i = parent();		if (i != 0) {			if (i == -1)				return(rv);			if (pin != NULL)				closepipe(pin);			return(pout==NULL? setstatus(waitfor(i,0)): 0);		}		if (talking) {			signal(SIGINT, SIG_IGN);			signal(SIGQUIT, SIG_IGN);			resetsig = 1;		}		talking = 0;		intr = 0;		(*pforked)++;		brklist = 0;		execflg = 0;	}	if (owp != NULL)		while ((cp = *owp++) != NULL && assign(cp, COPYV))			if (shcom == NULL)				export(lookup(cp));#ifdef COMPIPE	if ((pin != NULL || pout != NULL) && shcom != NULL && shcom != doexec) {		err("piping to/from shell builtins not yet done");		return(-1);	}#endif	if (pin != NULL) {		dup2(pin[0], 0);		closepipe(pin);	}	if (pout != NULL) {		dup2(pout[1], 1);		closepipe(pout);	}	if ((iopp = t->ioact) != NULL) {		if (shcom != NULL && shcom != doexec) {			prs(cp);			err(": cannot redirect shell command");			return(-1);		}		while (*iopp)			if (iosetup(*iopp++, pin!=NULL, pout!=NULL))				return(rv);	}	if (shcom)		return(setstatus((*shcom)(t)));	/* should use FIOCEXCL */	for (i=FDBASE; i<NOFILE; i++)		close(i);	if (resetsig) {		signal(SIGINT, SIG_DFL);		signal(SIGQUIT, SIG_DFL);	}	if (t->type == TPAREN)		exit(execute(t->left, NOPIPE, NOPIPE, FEXEC));	if (wp[0] == NULL)		exit(0);	cp = rexecve(wp[0], wp, makenv());	prs(wp[0]); prs(": "); warn(cp);	if (!execflg)		trap[0] = NULL;	leave();	/* NOTREACHED */}/* * common actions when creating a new child */static intparent(){	register int i;	i = fork();	if (i != 0) {		if (i == -1)			warn("try again");	}	return(i);}/* * 0< 1> are ignored as required * within pipelines. */intiosetup(iop, pipein, pipeout)register struct ioword *iop;int pipein, pipeout;{	register u;	char *cp, *msg;	if (iop->io_unit == IODEFAULT)	/* take default */		iop->io_unit = iop->io_flag&(IOREAD|IOHERE)? 0: 1;	if (pipein && iop->io_unit == 0)		return(0);	if (pipeout && iop->io_unit == 1)		return(0);	msg = iop->io_flag&(IOREAD|IOHERE)? "open": "create";	if ((iop->io_flag & IOHERE) == 0) {		cp = iop->io_name;		if ((cp = evalstr(cp, DOSUB|DOTRIM)) == NULL)			return(1);	}	if (iop->io_flag & IODUP) {		if (cp[1] || (!digit(*cp) && *cp != '-')) {			prs(cp);			err(": illegal >& argument");			return(1);		}		if (*cp == '-')			iop->io_flag = IOCLOSE;		iop->io_flag &= ~(IOREAD|IOWRITE);	}	switch (iop->io_flag) {	case IOREAD:		u = open(cp, 0);		break;	case IOHERE:	case IOHERE|IOXHERE:		u = herein(iop->io_name, iop->io_flag&IOXHERE);		cp = "here file";		break;	case IOWRITE|IOCAT:		if ((u = open(cp, 1)) >= 0) {			lseek(u, (long)0, 2);			break;		}	case IOWRITE:		u = creat(cp, 0666);		break;	case IODUP:		u = dup2(*cp-'0', iop->io_unit);		break;	case IOCLOSE:		close(iop->io_unit);		return(0);	}	if (u < 0) {		prs(cp);		prs(": cannot ");		warn(msg);		return(1);	} else {		if (u != iop->io_unit) {			dup2(u, iop->io_unit);			close(u);		}	}	return(0);}static voidecho(wp)register char **wp;{	register i;	prs("+");	for (i=0; wp[i]; i++) {		if (i)			prs(" ");		prs(wp[i]);	}	prs("\n");}static struct op **find1case(t, w)struct op *t;char *w;{	register struct op *t1;	struct op **tp;	register char **wp, *cp;	if (t == NULL)		return((struct op **)NULL);	if (t->type == TLIST) {		if ((tp = find1case(t->left, w)) != NULL)			return(tp);		t1 = t->right;	/* TPAT */	} else		t1 = t;	for (wp = t1->words; *wp;)		if ((cp = evalstr(*wp++, DOSUB)) && gmatch(w, cp))			return(&t1->left);	return((struct op **)NULL);}static struct op *findcase(t, w)struct op *t;char *w;{	register struct op **tp;	return((tp = find1case(t, w)) != NULL? *tp: (struct op *)NULL);}/* * Enter a new loop level (marked for break/continue). */static voidbrkset(bc)struct brkcon *bc;{	bc->nextlev = brklist;	brklist = bc;}/* * Wait for the last process created. * Print a message for each process found * that was killed by a signal. * Ignore interrupt signals while waiting * unless `canintr' is true. */intwaitfor(lastpid, canintr)register int lastpid;int canintr;{	register int pid, rv;	int s;	int oheedint = heedint;	heedint = 0;	rv = 0;	do {		pid = wait(&s);		if (pid == -1) {			if (errno != EINTR || canintr)				break;		} else {			if ((rv = WAITSIG(s)) != 0) {				if (rv < NSIGNAL) {					if (signame[rv] != NULL) {						if (pid != lastpid) {							prn(pid);							prs(": ");						}						prs(signame[rv]);					}				} else {					if (pid != lastpid) {						prn(pid);						prs(": ");					}					prs("Signal "); prn(rv); prs(" ");				}				if (WAITCORE(s))					prs(" - core dumped");				if (rv >= NSIGNAL || signame[rv])					prs("\n");				rv = -1;			} else				rv = WAITVAL(s);		}	} while (pid != lastpid);	heedint = oheedint;	if (intr)		if (talking) {			if (canintr)				intr = 0;		} else {			if (exstat == 0) exstat = rv;			onintr(0);		}	return(rv);}intsetstatus(s)register int s;{	exstat = s;	setval(lookup("?"), putn(s));	return(s);}/* * PATH-searching interface to execve. * If getenv("PATH") were kept up-to-date, * execvp might be used. */char *rexecve(c, v, envp)char *c, **v, **envp;{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -