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

📄 devcons.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
			}			qnoblock(kprintoq, 1);		}else			qreopen(kprintoq);		c->iounit = qiomaxatomic;		break;	case Qsecstore:		if(omode == ORDWR)			error(Eperm);		if(omode != OREAD)			memset(secstorebuf, 0, sizeof secstorebuf);		break;	case Qsnarf:		if(omode == ORDWR)			error(Eperm);		if(omode == OREAD)			c->aux = strdup("");		else			c->aux = mallocz(SnarfSize, 1);		break;	}	return c;}static voidconsclose(Chan *c){	switch((ulong)c->qid.path){	/* last close of control file turns off raw */	case Qconsctl:		if(c->flag&COPEN){			qlock(&kbd.lk);			if(--kbd.ctl == 0)				kbd.raw = 0;			qunlock(&kbd.lk);		}		break;	/* close of kprint allows other opens */	case Qkprint:		if(c->flag & COPEN){			kprintinuse = 0;			qhangup(kprintoq, nil);		}		break;	case Qsnarf:		if(c->mode == OWRITE)			clipwrite(c->aux);		free(c->aux);		break;	}}static longconsread(Chan *c, void *buf, long n, vlong off){	char *b;	char tmp[128];		/* must be >= 6*NUMSIZE */	char *cbuf = buf;	int ch, i, eol;	vlong offset = off;	if(n <= 0)		return n;	switch((ulong)c->qid.path){	case Qdir:		return devdirread(c, buf, n, consdir, nelem(consdir), devgen);	case Qcons:		qlock(&kbd.lk);		if(waserror()) {			qunlock(&kbd.lk);			nexterror();		}		if(kbd.raw) {			if(qcanread(lineq))				n = qread(lineq, buf, n);			else {				/* read as much as possible */				do {					i = qread(kbdq, cbuf, n);					cbuf += i;					n -= i;				} while (n>0 && qcanread(kbdq));				n = cbuf - (char*)buf;			}		} else {			while(!qcanread(lineq)) {				qread(kbdq, &kbd.line[kbd.x], 1);				ch = kbd.line[kbd.x];				eol = 0;				switch(ch){				case '\b':					if(kbd.x)						kbd.x--;					break;				case 0x15:					kbd.x = 0;					break;				case '\n':				case 0x04:					eol = 1;				default:					kbd.line[kbd.x++] = ch;					break;				}				if(kbd.x == sizeof(kbd.line) || eol){					if(ch == 0x04)						kbd.x--;					qwrite(lineq, kbd.line, kbd.x);					kbd.x = 0;				}			}			n = qread(lineq, buf, n);		}		qunlock(&kbd.lk);		poperror();		return n;	case Qcpunote:		sleep(&up->sleep, return0, nil);	case Qcputime:		return 0;	case Qkprint:		return qread(kprintoq, buf, n);	case Qpgrpid:		return readnum((ulong)offset, buf, n, up->pgrp->pgrpid, NUMSIZE);	case Qpid:		return readnum((ulong)offset, buf, n, up->pid, NUMSIZE);	case Qppid:		return readnum((ulong)offset, buf, n, up->parentpid, NUMSIZE);	case Qtime:		return readtime((ulong)offset, buf, n);	case Qbintime:		return readbintime(buf, n);	case Qhostowner:		return readstr((ulong)offset, buf, n, eve);	case Qhostdomain:		return readstr((ulong)offset, buf, n, hostdomain);	case Quser:		return readstr((ulong)offset, buf, n, up->user);	case Qnull:		return 0;	case Qsnarf:		if(offset == 0){			free(c->aux);			c->aux = clipread();		}		if(c->aux == nil)			return 0;		return readstr(offset, buf, n, c->aux);	case Qsecstore:		return readstr(offset, buf, n, secstorebuf);	case Qsysstat:		return 0;	case Qswap:		return 0;	case Qsysname:		if(sysname == nil)			return 0;		return readstr((ulong)offset, buf, n, sysname);	case Qrandom:		return randomread(buf, n);	case Qdrivers:		b = malloc(READSTR);		if(b == nil)			error(Enomem);		n = 0;		for(i = 0; devtab[i] != nil; i++)			n += snprint(b+n, READSTR-n, "#%C %s\n", devtab[i]->dc,  devtab[i]->name);		if(waserror()){			free(b);			nexterror();		}		n = readstr((ulong)offset, buf, n, b);		free(b);		poperror();		return n;	case Qzero:		memset(buf, 0, n);		return n;	case Qosversion:		snprint(tmp, sizeof tmp, "2000");		n = readstr((ulong)offset, buf, n, tmp);		return n;	default:		print("consread 0x%llux\n", c->qid.path);		error(Egreg);	}	return -1;		/* never reached */}static longconswrite(Chan *c, void *va, long n, vlong off){	char buf[256];	long l, bp;	char *a = va;	int fd;	Chan *swc;	ulong offset = off;	Cmdbuf *cb;	Cmdtab *ct;	switch((ulong)c->qid.path){	case Qcons:		/*		 * Can't page fault in putstrn, so copy the data locally.		 */		l = n;		while(l > 0){			bp = l;			if(bp > sizeof buf)				bp = sizeof buf;			memmove(buf, a, bp);			putstrn0(buf, bp, 1);			a += bp;			l -= bp;		}		break;	case Qconsctl:		if(n >= sizeof(buf))			n = sizeof(buf)-1;		strncpy(buf, a, n);		buf[n] = 0;		for(a = buf; a;){			if(strncmp(a, "rawon", 5) == 0){				qlock(&kbd.lk);				if(kbd.x){					qwrite(kbdq, kbd.line, kbd.x);					kbd.x = 0;				}				kbd.raw = 1;				qunlock(&kbd.lk);			} else if(strncmp(a, "rawoff", 6) == 0){				qlock(&kbd.lk);				kbd.raw = 0;				kbd.x = 0;				qunlock(&kbd.lk);			} else if(strncmp(a, "ctlpon", 6) == 0){				kbd.ctlpoff = 0;			} else if(strncmp(a, "ctlpoff", 7) == 0){				kbd.ctlpoff = 1;			}			if((a = strchr(a, ' ')))				a++;		}		break;	case Qtime:		if(!iseve())			error(Eperm);		return writetime(a, n);	case Qbintime:		if(!iseve())			error(Eperm);		return writebintime(a, n);	case Qhostowner:		return hostownerwrite(a, n);	case Qhostdomain:		return hostdomainwrite(a, n);	case Quser:		return userwrite(a, n);	case Qnull:		break;	case Qreboot:		if(!iseve())			error(Eperm);		cb = parsecmd(a, n);		if(waserror()) {			free(cb);			nexterror();		}		ct = lookupcmd(cb, rebootmsg, nelem(rebootmsg));		switch(ct->index) {		case CMreboot:			rebootcmd(cb->nf-1, cb->f+1);			break;		case CMpanic:			panic("/dev/reboot");		}		poperror();		free(cb);		break;	case Qsecstore:		if(offset >= sizeof secstorebuf || offset+n+1 >= sizeof secstorebuf)			error(Etoobig);		secstoretab->qid.vers++;		memmove(secstorebuf+offset, va, n);		return n;	case Qshowfile:		return showfilewrite(a, n);	case Qsnarf:		if(offset >= SnarfSize || offset+n >= SnarfSize)			error(Etoobig);		snarftab->qid.vers++;		memmove((uchar*)c->aux+offset, va, n);		return n;	case Qsysstat:		n = 0;		break;	case Qswap:		if(n >= sizeof buf)			error(Egreg);		memmove(buf, va, n);	/* so we can NUL-terminate */		buf[n] = 0;		/* start a pager if not already started */		if(strncmp(buf, "start", 5) == 0){			kickpager();			break;		}		if(cpuserver && !iseve())			error(Eperm);		if(buf[0]<'0' || '9'<buf[0])			error(Ebadarg);		fd = strtoul(buf, 0, 0);		swc = fdtochan(fd, -1, 1, 1);		setswapchan(swc);		break;	case Qsysname:		if(offset != 0)			error(Ebadarg);		if(n <= 0 || n >= sizeof buf)			error(Ebadarg);		strncpy(buf, a, n);		buf[n] = 0;		if(buf[n-1] == '\n')			buf[n-1] = 0;		kstrdup(&sysname, buf);		break;	default:		print("conswrite: 0x%llux\n", c->qid.path);		error(Egreg);	}	return n;}Dev consdevtab = {	'c',	"cons",	devreset,	consinit,	devshutdown,	consattach,	conswalk,	consstat,	consopen,	devcreate,	consclose,	consread,	devbread,	conswrite,	devbwrite,	devremove,	devwstat,};static uvlong uvorder = (uvlong) 0x0001020304050607ULL;static uchar*le2vlong(vlong *to, uchar *f){	uchar *t, *o;	int i;	t = (uchar*)to;	o = (uchar*)&uvorder;	for(i = 0; i < sizeof(vlong); i++)		t[o[i]] = f[i];	return f+sizeof(vlong);}static uchar*vlong2le(uchar *t, vlong from){	uchar *f, *o;	int i;	f = (uchar*)&from;	o = (uchar*)&uvorder;	for(i = 0; i < sizeof(vlong); i++)		t[i] = f[o[i]];	return t+sizeof(vlong);}static long order = 0x00010203;static uchar*le2long(long *to, uchar *f){	uchar *t, *o;	int i;	t = (uchar*)to;	o = (uchar*)&order;	for(i = 0; i < sizeof(long); i++)		t[o[i]] = f[i];	return f+sizeof(long);}/*static uchar*long2le(uchar *t, long from){	uchar *f, *o;	int i;	f = (uchar*)&from;	o = (uchar*)&order;	for(i = 0; i < sizeof(long); i++)		t[i] = f[o[i]];	return t+sizeof(long);}*/char *Ebadtimectl = "bad time control";/* *  like the old #c/time but with added info.  Return * *	secs	nanosecs	fastticks	fasthz */static intreadtime(ulong off, char *buf, int n){	vlong	nsec, ticks;	long sec;	char str[7*NUMSIZE];	nsec = todget(&ticks);	if(fasthz == (vlong)0)		fastticks((uvlong*)&fasthz);	sec = nsec/((uvlong) 1000000000);	snprint(str, sizeof(str), "%*.0lud %*.0llud %*.0llud %*.0llud ",		NUMSIZE-1, sec,		VLNUMSIZE-1, nsec,		VLNUMSIZE-1, ticks,		VLNUMSIZE-1, fasthz);	return readstr(off, buf, n, str);}/* *  set the time in seconds */static intwritetime(char *buf, int n){	char b[13];	long i;	vlong now;	if(n >= sizeof(b))		error(Ebadtimectl);	strncpy(b, buf, n);	b[n] = 0;	i = strtol(b, 0, 0);	if(i <= 0)		error(Ebadtimectl);	now = i*((vlong) 1000000000);	todset(now, 0, 0);	return n;}/* *  read binary time info.  all numbers are little endian. *  ticks and nsec are syncronized. */static intreadbintime(char *buf, int n){	int i;	vlong nsec, ticks;	uchar *b = (uchar*)buf;	i = 0;	if(fasthz == (vlong)0)		fastticks((uvlong*)&fasthz);	nsec = todget(&ticks);	if(n >= 3*sizeof(uvlong)){		vlong2le(b+2*sizeof(uvlong), fasthz);		i += sizeof(uvlong);	}	if(n >= 2*sizeof(uvlong)){		vlong2le(b+sizeof(uvlong), ticks);		i += sizeof(uvlong);	}	if(n >= 8){		vlong2le(b, nsec);		i += sizeof(vlong);	}	return i;}/* *  set any of the following *	- time in nsec *	- nsec trim applied over some seconds *	- clock frequency */static intwritebintime(char *buf, int n){	uchar *p;	vlong delta;	long period;	n--;	p = (uchar*)buf + 1;	switch(*buf){	case 'n':		if(n < sizeof(vlong))			error(Ebadtimectl);		le2vlong(&delta, p);		todset(delta, 0, 0);		break;	case 'd':		if(n < sizeof(vlong)+sizeof(long))			error(Ebadtimectl);		p = le2vlong(&delta, p);		le2long(&period, p);		todset(-1, delta, period);		break;	case 'f':		if(n < sizeof(uvlong))			error(Ebadtimectl);		le2vlong(&fasthz, p);		todsetfreq(fasthz);		break;	}	return n;}intiprint(char *fmt, ...){	int n, s;	va_list arg;	char buf[PRINTSIZE];	s = splhi();	va_start(arg, fmt);	n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf;	va_end(arg);	if(screenputs != nil && iprintscreenputs)		screenputs(buf, n);#undef write	write(2, buf, n);	splx(s);	return n;}

⌨️ 快捷键说明

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