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

📄 sh5.c

📁 minix软件源代码
💻 C
字号:
#define Extern extern#include <sys/types.h>#include <signal.h>#include <errno.h>#include <setjmp.h>#include "sh.h"/* -------- io.c -------- *//* #include "sh.h" *//* * shell IO */static struct iobuf sharedbuf = {AFID_NOBUF};static struct iobuf mainbuf = {AFID_NOBUF};static unsigned bufid = AFID_ID;	/* buffer id counter */struct ioarg temparg = {0, 0, 0, AFID_NOBUF, 0};_PROTOTYPE(static void readhere, (char **name, char *s, int ec ));_PROTOTYPE(void pushio, (struct ioarg *argp, int (*fn)()));_PROTOTYPE(static int xxchar, (struct ioarg *ap ));_PROTOTYPE(void tempname, (char *tname ));intgetc(ec)register int ec;{	register int c;	if(e.linep > elinep) {		while((c=readc()) != '\n' && c)			;		err("input line too long");		gflg++;		return(c);	}	c = readc(); 	if (ec != '\'' && e.iop->task != XGRAVE) {		if(c == '\\') {			c = readc();			if (c == '\n' && ec != '\"')				return(getc(ec));			c |= QUOTE;		}	}	return(c);}voidunget(c)int c;{	if (e.iop >= e.iobase)		e.iop->peekc = c;}inteofc(){  return e.iop < e.iobase || (e.iop->peekc == 0 && e.iop->prev == 0);}intreadc(){	register c;	for (; e.iop >= e.iobase; e.iop--)		if ((c = e.iop->peekc) != '\0') {			e.iop->peekc = 0;			return(c);		}		else {		    if (e.iop->prev != 0) {		        if ((c = (*e.iop->iofn)(e.iop->argp, e.iop)) != '\0') {			        if (c == -1) {				        e.iop++;				        continue;			        }			        if (e.iop == iostack)				        ioecho(c);			        return(e.iop->prev = c);		        }		        else if (e.iop->task == XIO && e.iop->prev != '\n') {			        e.iop->prev = 0;				if (e.iop == iostack)					ioecho('\n');			        return '\n';		        }		    }		    if (e.iop->task == XIO) {			if (multiline)			    return e.iop->prev = 0;			if (talking && e.iop == iostack+1)			    prs(prompt->value);		    }		}	if (e.iop >= iostack)		return(0);	leave();	/* NOTREACHED */}voidioecho(c)char c;{	if (flag['v'])		write(2, &c, sizeof c);}voidpushio(argp, fn)struct ioarg *argp;int (*fn)();{	if (++e.iop >= &iostack[NPUSH]) {		e.iop--;		err("Shell input nested too deeply");		gflg++;		return;	}	e.iop->iofn = fn;	if (argp->afid != AFID_NOBUF)	  e.iop->argp = argp;	else {	  e.iop->argp  = ioargstack + (e.iop - iostack);	  *e.iop->argp = *argp;	  e.iop->argp->afbuf = e.iop == &iostack[0] ? &mainbuf : &sharedbuf;	  if (isatty(e.iop->argp->afile) == 0 &&	      (e.iop == &iostack[0] ||	       lseek(e.iop->argp->afile, 0L, 1) != -1)) {	    if (++bufid == AFID_NOBUF)	      bufid = AFID_ID;	    e.iop->argp->afid  = bufid;	  }	}	e.iop->prev  = ~'\n';	e.iop->peekc = 0;	e.iop->xchar = 0;	e.iop->nlcount = 0;	if (fn == filechar || fn == linechar)		e.iop->task = XIO;	else if (fn == gravechar || fn == qgravechar)		e.iop->task = XGRAVE;	else		e.iop->task = XOTHER;}struct io *setbase(ip)struct io *ip;{	register struct io *xp;	xp = e.iobase;	e.iobase = ip;	return(xp);}/* * Input generating functions *//* * Produce the characters of a string, then a newline, then EOF. */intnlchar(ap)register struct ioarg *ap;{	register int c;	if (ap->aword == NULL)		return(0);	if ((c = *ap->aword++) == 0) {		ap->aword = NULL;		return('\n');	}	return(c);}/* * Given a list of words, produce the characters * in them, with a space after each word. */intwdchar(ap)register struct ioarg *ap;{	register char c;	register char **wl;	if ((wl = ap->awordlist) == NULL)		return(0);	if (*wl != NULL) {		if ((c = *(*wl)++) != 0)			return(c & 0177);		ap->awordlist++;		return(' ');	}	ap->awordlist = NULL;	return('\n');}/* * Return the characters of a list of words, * producing a space between them. */intdolchar(ap)register struct ioarg *ap;{	register char *wp;	if ((wp = *ap->awordlist++) != NULL) {		PUSHIO(aword, wp, *ap->awordlist == NULL? strchar: xxchar);		return(-1);	}	return(0);}static intxxchar(ap)register struct ioarg *ap;{	register int c;	if (ap->aword == NULL)		return(0);	if ((c = *ap->aword++) == '\0') {		ap->aword = NULL;		return(' ');	}	return(c);}/* * Produce the characters from a single word (string). */intstrchar(ap)register struct ioarg *ap;{	register int c;	if (ap->aword == NULL || (c = *ap->aword++) == 0)		return(0);	return(c);}/* * Produce quoted characters from a single word (string). */intqstrchar(ap)register struct ioarg *ap;{	register int c;	if (ap->aword == NULL || (c = *ap->aword++) == 0)		return(0);	return(c|QUOTE);}/* * Return the characters from a file. */intfilechar(ap)register struct ioarg *ap;{	register int i;	char c;	struct iobuf *bp = ap->afbuf;	if (ap->afid != AFID_NOBUF) {	  if ((i = ap->afid != bp->id) || bp->bufp == bp->ebufp) {	    if (i)	      lseek(ap->afile, ap->afpos, 0);	    do {	      i = read(ap->afile, bp->buf, sizeof(bp->buf));	    } while (i < 0 && errno == EINTR);	    if (i <= 0) {	      closef(ap->afile);	      return 0;	    }	    bp->id = ap->afid;	    bp->ebufp = (bp->bufp  = bp->buf) + i;	  }	  ap->afpos++;	  return *bp->bufp++ & 0177;	}	do {		i = read(ap->afile, &c, sizeof(c));	} while (i < 0 && errno == EINTR);	return(i == sizeof(c)? c&0177: (closef(ap->afile), 0));}/* * Return the characters from a here temp file. */intherechar(ap)register struct ioarg *ap;{	char c;	if (read(ap->afile, &c, sizeof(c)) != sizeof(c)) {		close(ap->afile);		c = 0;	}	return (c);}/* * Return the characters produced by a process (`...`). * Quote them if required, and remove any trailing newline characters. */intgravechar(ap, iop)struct ioarg *ap;struct io *iop;{	register int c;	if ((c = qgravechar(ap, iop)&~QUOTE) == '\n')		c = ' ';	return(c);}intqgravechar(ap, iop)register struct ioarg *ap;struct io *iop;{	register int c;	if (iop->xchar) {		if (iop->nlcount) {			iop->nlcount--;			return('\n'|QUOTE);		}		c = iop->xchar;		iop->xchar = 0;	} else if ((c = filechar(ap)) == '\n') {		iop->nlcount = 1;		while ((c = filechar(ap)) == '\n')			iop->nlcount++;		iop->xchar = c;		if (c == 0)			return(c);		iop->nlcount--;		c = '\n';	}	return(c!=0? c|QUOTE: 0);}/* * Return a single command (usually the first line) from a file. */intlinechar(ap)register struct ioarg *ap;{	register int c;	if ((c = filechar(ap)) == '\n') {		if (!multiline) {			closef(ap->afile);			ap->afile = -1;	/* illegal value */		}	}	return(c);}voidprs(s)register char *s;{	if (*s)		write(2, s, strlen(s));}voidputc(c)char c;{	write(2, &c, sizeof c);}voidprn(u)unsigned u;{	prs(itoa(u, 0));}voidclosef(i)register int i;{	if (i > 2)		close(i);}voidcloseall(){	register u;	for (u=NUFILE; u<NOFILE;)		close(u++);}/* * remap fd into Shell's fd space */intremap(fd)register int fd;{	register int i;	int map[NOFILE];	if (fd < e.iofd) {		for (i=0; i<NOFILE; i++)			map[i] = 0;		do {			map[fd] = 1;			fd = dup(fd);		} while (fd >= 0 && fd < e.iofd);		for (i=0; i<NOFILE; i++)			if (map[i])				close(i);		if (fd < 0)			err("too many files open in shell");	}	return(fd);}intopenpipe(pv)register int *pv;{	register int i;	if ((i = pipe(pv)) < 0)		err("can't create pipe - try again");	return(i);}voidclosepipe(pv)register int *pv;{	if (pv != NULL) {		close(*pv++);		close(*pv);	}}/* -------- here.c -------- *//* #include "sh.h" *//* * here documents */struct	here {	char	*h_tag;	int	h_dosub;	struct	ioword *h_iop;	struct	here	*h_next;};static	struct here *inhere;		/* list of hear docs while parsing */static	struct here *acthere;		/* list of active here documents */voidmarkhere(s, iop)register char *s;struct ioword *iop;{	register struct here *h, *lh;	h = (struct here *) space(sizeof(struct here));	if (h == 0)		return;	h->h_tag = evalstr(s, DOSUB);	if (h->h_tag == 0)		return;	h->h_iop = iop;	iop->io_name = 0;	h->h_next = NULL;	if (inhere == 0)		inhere = h;	else		for (lh = inhere; lh!=NULL; lh = lh->h_next)			if (lh->h_next == 0) {				lh->h_next = h;				break;			}	iop->io_flag |= IOHERE|IOXHERE;	for (s = h->h_tag; *s; s++)		if (*s & QUOTE) {			iop->io_flag &= ~ IOXHERE;			*s &= ~ QUOTE;		}	h->h_dosub = iop->io_flag & IOXHERE;}voidgethere(){	register struct here *h, *hp;	/* Scan here files first leaving inhere list in place */	for (hp = h = inhere; h != NULL; hp = h, h = h->h_next)	  readhere(&h->h_iop->io_name, h->h_tag, h->h_dosub? 0: '\'');	/* Make inhere list active - keep list intact for scraphere */	if (hp != NULL) {	  hp->h_next = acthere;	  acthere    = inhere;	  inhere     = NULL;	}}static voidreadhere(name, s, ec)char **name;register char *s;int ec;{	int tf;	char tname[30];	register c;	jmp_buf ev;	char line [LINELIM+1];	char *next;	tempname(tname);	*name = strsave(tname, areanum);	tf = creat(tname, 0600);	if (tf < 0)		return;	if (newenv(setjmp(errpt = ev)) != 0)		unlink(tname);	else {		pushio(e.iop->argp, e.iop->iofn);		e.iobase = e.iop;		for (;;) {			if (talking && e.iop <= iostack)				prs(cprompt->value);			next = line;			while ((c = getc(ec)) != '\n' && c) {				if (ec == '\'')					c &= ~ QUOTE;				if (next >= &line[LINELIM]) {					c = 0;					break;				}				*next++ = c;			}			*next = 0;			if (strcmp(s, line) == 0 || c == 0)				break;			*next++ = '\n';			write (tf, line, (int)(next-line));		}		if (c == 0) {			prs("here document `"); prs(s); err("' unclosed");		}		quitenv();	}	close(tf);}/* * open here temp file. * if unquoted here, expand here temp file into second temp file. */intherein(hname, xdoll)char *hname;int xdoll;{	register hf, tf;	if (hname == 0)		return(-1);	hf = open(hname, 0);	if (hf < 0)		return (-1);	if (xdoll) {		char c;		char tname[30];		jmp_buf ev;		tempname(tname);		if ((tf = creat(tname, 0600)) < 0)			return (-1);		if (newenv(setjmp(errpt = ev)) == 0) {			PUSHIO(afile, hf, herechar);			setbase(e.iop);			while ((c = subgetc(0, 0)) != 0) {				c &= ~ QUOTE;				write(tf, &c, sizeof c);			}			quitenv();		} else			unlink(tname);		close(tf);		tf = open(tname, 0);		unlink(tname);		return (tf);	} else		return (hf);}voidscraphere(){	register struct here *h;	for (h = inhere; h != NULL; h = h->h_next) {		if (h->h_iop && h->h_iop->io_name)		  unlink(h->h_iop->io_name);	}	inhere = NULL;}/* unlink here temp files before a freearea(area) */voidfreehere(area)int area;{	register struct here *h, *hl;	hl = NULL;	for (h = acthere; h != NULL; h = h->h_next)		if (getarea((char *) h) >= area) {			if (h->h_iop->io_name != NULL)				unlink(h->h_iop->io_name);			if (hl == NULL)				acthere = h->h_next;			else				hl->h_next = h->h_next;		} else			hl = h;}voidtempname(tname)char *tname;{	static int inc;	register char *cp, *lp;	for (cp = tname, lp = "/tmp/shtm"; (*cp = *lp++) != '\0'; cp++)		;	lp = putn(getpid()*1000 + inc++);	for (; (*cp = *lp++) != '\0'; cp++)		;}

⌨️ 快捷键说明

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