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

📄 devcons.c

📁 在x86平台上运行不可信任代码的sandbox。
💻 C
📖 第 1 页 / 共 2 页
字号:
	randominit();#if 0 // Plan 9 VX	/*	 * at 115200 baud, the 1024 char buffer takes 56 ms to process,	 * processing it every 22 ms should be fine	 */	addclock0link(kbdputcclock, 22);#endif}static Chan*consattach(char *spec){	return devattach('c', spec);}static Walkqid*conswalk(Chan *c, Chan *nc, char **name, int nname){	return devwalk(c, nc, name,nname, consdir, nelem(consdir), devgen);}static intconsstat(Chan *c, uchar *dp, int n){	return devstat(c, dp, n, consdir, nelem(consdir), devgen);}static Chan*consopen(Chan *c, int omode){	c->aux = nil;	c = devopen(c, omode, consdir, nelem(consdir), devgen);	switch((ulong)c->qid.path){	case Qconsctl:		incref(&kbd.ctl);		break;	case Qkprint:		if(tas(&kprintinuse) != 0){			c->flag &= ~COPEN;			error(Einuse);		}		if(kprintoq == nil){			kprintoq = qopen(8*1024, Qcoalesce, 0, 0);			if(kprintoq == nil){				c->flag &= ~COPEN;				error(Enomem);			}			qnoblock(kprintoq, 1);		}else			qreopen(kprintoq);		c->iounit = qiomaxatomic;		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){			if(decref(&kbd.ctl) == 0)				kbd.raw = 0;		}		break;	/* close of kprint allows other opens */	case Qkprint:		if(c->flag & COPEN){			kprintinuse = 0;			qhangup(kprintoq, nil);		}		break;	}}static longconsread(Chan *c, void *buf, long n, vlong off){	ulong l;	Mach *mp;	char *b, *bp, ch;	char tmp[256];		/* must be >= 18*NUMSIZE (Qswap) */	int i, k, id, send;	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();		}		while(!qcanread(lineq)){			if(qread(kbdq, &ch, 1) == 0)				continue;			send = 0;			if(ch == 0){				/* flush output on rawoff -> rawon */				if(kbd.x > 0)					send = !qcanread(kbdq);			}else if(kbd.raw){				kbd.line[kbd.x++] = ch;				send = !qcanread(kbdq);			}else{				switch(ch){				case '\b':					if(kbd.x > 0)						kbd.x--;					break;				case 0x15:	/* ^U */					kbd.x = 0;					break;				case '\n':				case 0x04:	/* ^D */					send = 1;				default:					if(ch != 0x04)						kbd.line[kbd.x++] = ch;					break;				}			}			if(send || kbd.x == sizeof kbd.line){				qwrite(lineq, kbd.line, kbd.x);				kbd.x = 0;			}		}		n = qread(lineq, buf, n);		qunlock(&kbd.lk);		poperror();		return n;	case Qcputime:		k = offset;		if(k >= 6*NUMSIZE)			return 0;		if(k+n > 6*NUMSIZE)			n = 6*NUMSIZE - k;		/* easiest to format in a separate buffer and copy out */		for(i=0; i<6 && NUMSIZE*i<k+n; i++){			l = up->time[i];			if(i == TReal)				l = msec() - l;			l = TK2MS(l);			readnum(0, tmp+NUMSIZE*i, NUMSIZE, l, NUMSIZE);		}		memmove(buf, tmp+k, n);		return n;	case Qkmesg:		/*		 * This is unlocked to avoid tying up a process		 * that's writing to the buffer.  kmesg.n never 		 * gets smaller, so worst case the reader will		 * see a slurred buffer.		 */		if(off >= kmesg.n)			n = 0;		else{			if(off+n > kmesg.n)				n = kmesg.n - off;			memmove(buf, kmesg.buf+off, n);		}		return n;			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 Qsysstat:		b = smalloc(conf.nmach*(NUMSIZE*11+1) + 1);	/* +1 for NUL */		bp = b;		for(id = 0; id < 32; id++) {			if(active.machs & (1<<id)) {				mp = MACHP(id);				readnum(0, bp, NUMSIZE, id, NUMSIZE);				bp += NUMSIZE;				readnum(0, bp, NUMSIZE, mp->cs, NUMSIZE);				bp += NUMSIZE;				readnum(0, bp, NUMSIZE, mp->intr, NUMSIZE);				bp += NUMSIZE;				readnum(0, bp, NUMSIZE, mp->syscall, NUMSIZE);				bp += NUMSIZE;				readnum(0, bp, NUMSIZE, mp->pfault, NUMSIZE);				bp += NUMSIZE;				readnum(0, bp, NUMSIZE, mp->tlbfault, NUMSIZE);				bp += NUMSIZE;				readnum(0, bp, NUMSIZE, mp->tlbpurge, NUMSIZE);				bp += NUMSIZE;				readnum(0, bp, NUMSIZE, mp->load, NUMSIZE);				bp += NUMSIZE;				readnum(0, bp, NUMSIZE,					(mp->perf.avg_inidle*100)/mp->perf.period,					NUMSIZE);				bp += NUMSIZE;				readnum(0, bp, NUMSIZE,					(mp->perf.avg_inintr*100)/mp->perf.period,					NUMSIZE);				bp += NUMSIZE;				*bp++ = '\n';			}		}		if(waserror()){			free(b);			nexterror();		}		n = readstr((ulong)offset, buf, n, b);		free(b);		poperror();		return n;	case Qswap:		tmp[0] = 0;		return readstr((ulong)offset, buf, n, tmp);	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], ch;	long l, bp;	char *a;	Mach *mp;	int id, fd;	Chan *swc;	ulong offset;	Cmdbuf *cb;	Cmdtab *ct;	a = va;	offset = off;	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){				kbd.raw = 1;				/* clumsy hack - wake up reader */				ch = 0;				qwrite(kbdq, &ch, 1);						} else if(strncmp(a, "rawoff", 6) == 0){				kbd.raw = 0;			} 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 CMhalt:			reboot(nil, 0, 0);			break;		case CMreboot:			rebootcmd(cb->nf-1, cb->f+1);			break;		case CMpanic:			*(ulong*)0=0;			panic("/dev/reboot");		}		poperror();		free(cb);		break;	case Qsysstat:		for(id = 0; id < 32; id++) {			if(active.machs & (1<<id)) {				mp = MACHP(id);				mp->cs = 0;				mp->intr = 0;				mp->syscall = 0;				mp->pfault = 0;				mp->tlbfault = 0;				mp->tlbpurge = 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(!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	ulong	randn;static voidseedrand(void){	if(!waserror()){		randomread((void*)&randn, sizeof(randn));		poperror();	}}intnrand(int n){	if(randn == 0)		seedrand();	randn = randn*1103515245 + 12345 + msec();	return (randn>>16) % n;}intrand(void){	nrand(1);	return randn;}static uvlong uvorder = 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 == 0LL)		fastticks((uvlong*)&fasthz);	sec = nsec/1000000000ULL;	snprint(str, sizeof(str), "%*lud %*llud %*llud %*llud ",		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*1000000000LL;	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 == 0LL)		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;}// Plan 9 VXinttailkmesg(char *a, int n){	ilock(&kmesg.lk);	if(n > kmesg.n)		n = kmesg.n;	memmove(a, kmesg.buf+kmesg.n-n, n);	iunlock(&kmesg.lk);	return n;}

⌨️ 快捷键说明

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