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

📄 devcons.c

📁 著名操作系统Plan 9的第三版的部分核心源代码。现在很难找到了。Plan 9是bell实验室开发的Unix后继者。
💻 C
📖 第 1 页 / 共 2 页
字号:
#include	"u.h"#include	"../port/lib.h"#include	"mem.h"#include	"dat.h"#include	"fns.h"#include	"../port/error.h"void	(*consdebug)(void) = nil;Queue*	kbdq;			/* unprocessed console input */Queue*	lineq;			/* processed console input */Queue*	printq;			/* console output */static struct{	QLock;	int	raw;		/* true if we shouldn't process input */	int	ctl;		/* number of opens to the control file */	int	x;		/* index into line */	char	line[1024];	/* current input line */	Rune	c;	int	count;	int	repeat;	int	ctlpoff;} kbd;char	sysname[NAMELEN];vlong	fasthz;static ulong	randomread(void*, ulong);static void	randominit(void);static void	seedrand(void);static int	readtime(ulong, char*, int);static int	readbintime(char*, int);static int	writetime(char*, int);static int	writebintime(char*, int);voidprintinit(void){	lineq = qopen(2*1024, 0, 0, 0);	if(lineq == nil)		panic("printinit");	qnoblock(lineq, 1);}intconsactive(void){	if(printq)		return qlen(printq) > 0;	return 0;}voidprflush(void){	while(consactive())		;}/* *   Print a string on the console.  Convert \n to \r\n for serial *   line consoles.  Locking of the queues is left up to the screen *   or uart code.  Multi-line messages to serial consoles may get *   interspersed with other messages. */static voidputstrn0(char *str, int n, int usewrite){	int m;	char *t;	char buf[PRINTSIZE+2];	/*	 *  if there's an attached bit mapped display,	 *  put the message there.  screenputs is defined	 *  as a null macro for systems that have no such	 *  display.	 */	screenputs(str, n);	/*	 *  if there's a serial line being used as a console,	 *  put the message there.	 */	if(printq == 0)		return;	while(n > 0) {		t = memchr(str, '\n', n);		if(t) {			m = t - str;			memmove(buf, str, m);			buf[m] = '\r';			buf[m+1] = '\n';			if(usewrite)				qwrite(printq, buf, m+2);			else				qiwrite(printq, buf, m+2);			str = t + 1;			n -= m + 1;		} else {			if(usewrite)				qwrite(printq, str, n);			else				qiwrite(printq, str, n);			break;		}	}}voidputstrn(char *str, int n){	putstrn0(str, n, 0);}intsnprint(char *s, int n, char *fmt, ...){	va_list arg;	va_start(arg, fmt);	n = doprint(s, s+n, fmt, arg) - s;	va_end(arg);	return n;}intsprint(char *s, char *fmt, ...){	int n;	va_list arg;	va_start(arg, fmt);	n = doprint(s, s+PRINTSIZE, fmt, arg) - s;	va_end(arg);	return n;}int noprint;intprint(char *fmt, ...){	int n;	va_list arg;	char buf[PRINTSIZE];	if(noprint)		return -1;	va_start(arg, fmt);	n = doprint(buf, buf+sizeof(buf), fmt, arg) - buf;	va_end(arg);	putstrn(buf, n);	return n;}intiprint(char *fmt, ...){	int n, s;	va_list arg;	char buf[PRINTSIZE];	s = splhi();	va_start(arg, fmt);	n = doprint(buf, buf+sizeof(buf), fmt, arg) - buf;	va_end(arg);	serialputs(buf, n);//	screenputs(buf, n);	splx(s);	return n;}voidpanic(char *fmt, ...){	int n;	va_list arg;	char buf[PRINTSIZE];	splhi();	strcpy(buf, "panic: ");	va_start(arg, fmt);	n = doprint(buf+strlen(buf), buf+sizeof(buf), fmt, arg) - buf;	va_end(arg);	buf[n] = '\n';	serialputs(buf, n+1);	if(consdebug)		consdebug();	putstrn(buf, n+1);	spllo();	prflush();	dumpstack();	exit(1);}void_assert(char *fmt){	panic("assert failed: %s", fmt);}intpprint(char *fmt, ...){	int n;	Chan *c;	va_list arg;	char buf[2*PRINTSIZE];	if(up == nil || up->fgrp == nil)		return 0;	c = up->fgrp->fd[2];	if(c==0 || (c->mode!=OWRITE && c->mode!=ORDWR))		return 0;	n = sprint(buf, "%s %lud: ", up->text, up->pid);	va_start(arg, fmt);	n = doprint(buf+n, buf+sizeof(buf), fmt, arg) - buf;	va_end(arg);	if(waserror())		return 0;	devtab[c->type]->write(c, buf, n, c->offset);	poperror();	lock(c);	c->offset += n;	unlock(c);	return n;}voidecho(Rune r, char *buf, int n){	static int ctrlt, pid;	extern ulong etext;	int x;	/*	 * ^p hack	 */	if(r==0x10 && cpuserver && !kbd.ctlpoff){		lock(&active);		active.exiting = 1;		unlock(&active);	}	/*	 * ^t hack BUG	 */	if(ctrlt == 2){		ctrlt = 0;		switch(r){		case 0x14:			break;	/* pass it on */		case 's':			dumpstack();			break;		case 'x':			xsummary();			ixsummary();			mallocsummary();			pagersummary();			break;		case 'd':			if(consdebug == nil)				consdebug = rdb;			else				consdebug = nil;			print("consdebug now 0x%p\n", consdebug);			return;		case 'D':			if(consdebug == nil)				consdebug = rdb;			consdebug();			return;		case 'p':			x = spllo();			procdump();			splx(x);			return;		case 'q':			scheddump();			break;		case 'k':			if(!cpuserver)				killbig();			break;		case 'r':			exit(0);			break;		}	}	else if(r == 0x14){		ctrlt++;		return;	}	ctrlt = 0;	if(kbd.raw)		return;	/*	 *  finally, the actual echoing	 */	if(r == '\n'){		if(printq)			qiwrite(printq, "\r", 1);	} else if(r == 0x15){		buf = "^U\n";		n = 3;	}	screenputs(buf, n);	if(printq)		qiwrite(printq, buf, n);}/* *  Called by a uart interrupt for console input. * *  turn '\r' into '\n' before putting it into the queue. */intkbdcr2nl(Queue *q, int ch){	if(ch == '\r')		ch = '\n';	return kbdputc(q, ch);}/* *  Put character, possibly a rune, into read queue at interrupt time. *  Called at interrupt time to process a character. */intkbdputc(Queue*, int ch){	int n;	char buf[3];	Rune r;	r = ch;	n = runetochar(buf, &r);	if(n == 0)		return 0;	echo(r, buf, n);	kbd.c = r;	qproduce(kbdq, buf, n);	return 0;}voidkbdrepeat(int rep){	kbd.repeat = rep;	kbd.count = 0;}voidkbdclock(void){	if(kbd.repeat == 0)		return;	if(kbd.repeat==1 && ++kbd.count>HZ){		kbd.repeat = 2;		kbd.count = 0;		return;	}	if(++kbd.count&1)		kbdputc(kbdq, kbd.c);}enum{	Qdir,	Qauth,	Qauthcheck,	Qauthent,	Qbintime,	Qcons,	Qconsctl,	Qcputime,	Qdrivers,	Qkey,	Qhostdomain,	Qhostowner,	Qnull,	Qpgrpid,	Qpid,	Qppid,	Qrandom,	Qreboot,	Qswap,	Qsysname,	Qsysstat,	Qtime,	Quser,	Qzero,};enum{	VLNUMSIZE=	22,};static Dirtab consdir[]={	"authenticate",	{Qauth},	0,		0666,	"authcheck",	{Qauthcheck},	0,		0666,	"authenticator", {Qauthent},	0,		0666,	"bintime",	{Qbintime},	24,		0664,	"cons",		{Qcons},	0,		0660,	"consctl",	{Qconsctl},	0,		0220,	"cputime",	{Qcputime},	6*NUMSIZE,	0444,	"drivers",	{Qdrivers},	0,		0644,	"hostdomain",	{Qhostdomain},	DOMLEN,		0664,	"hostowner",	{Qhostowner},	NAMELEN,	0664,	"key",		{Qkey},		DESKEYLEN,	0622,	"null",		{Qnull},	0,		0666,	"pgrpid",	{Qpgrpid},	NUMSIZE,	0444,	"pid",		{Qpid},		NUMSIZE,	0444,	"ppid",		{Qppid},	NUMSIZE,	0444,	"random",	{Qrandom},	0,		0664,	"reboot",	{Qreboot},	0,		0664,	"swap",		{Qswap},	0,		0664,	"sysname",	{Qsysname},	0,		0664,	"sysstat",	{Qsysstat},	0,		0666,	"time",		{Qtime},	NUMSIZE+3*VLNUMSIZE,	0664,	"user",		{Quser},	NAMELEN,	0666,	"zero",		{Qzero},	0,		0444,};intreadnum(ulong off, char *buf, ulong n, ulong val, int size){	char tmp[64];	snprint(tmp, sizeof(tmp), "%*.0lud", size-1, val);	tmp[size-1] = ' ';	if(off >= size)		return 0;	if(off+n > size)		n = size-off;	memmove(buf, tmp+off, n);	return n;}intreadstr(ulong off, char *buf, ulong n, char *str){	int size;	size = strlen(str);	if(off >= size)		return 0;	if(off+n > size)		n = size-off;	memmove(buf, str+off, n);	return n;}static voidconsinit(void){	todinit();	randominit();}static Chan*consattach(char *spec){	return devattach('c', spec);}static intconswalk(Chan *c, char *name){	return devwalk(c, name, consdir, nelem(consdir), devgen);}static voidconsstat(Chan *c, char *dp){	devstat(c, dp, consdir, nelem(consdir), devgen);}static Chan*consopen(Chan *c, int omode){	c->aux = 0;	switch(c->qid.path){	case Qconsctl:		if(!iseve())			error(Eperm);		qlock(&kbd);		kbd.ctl++;		qunlock(&kbd);		break;	}	return devopen(c, omode, consdir, nelem(consdir), devgen);}static voidconsclose(Chan *c){	/* last close of control file turns off raw */	switch(c->qid.path){	case Qconsctl:		if(c->flag&COPEN){			qlock(&kbd);			if(--kbd.ctl == 0)				kbd.raw = 0;			qunlock(&kbd);		}		break;	case Qauth:	case Qauthcheck:	case Qauthent:		authclose(c);	}}static longconsread(Chan *c, void *buf, long n, vlong off){	ulong l;	Mach *mp;	char *b, *bp;	char tmp[128];		/* must be >= 6*NUMSIZE */	char *cbuf = buf;	int ch, i, k, id, eol;	vlong offset = off;	if(n <= 0)		return n;	switch(c->qid.path & ~CHDIR){	case Qdir:		return devdirread(c, buf, n, consdir, nelem(consdir), devgen);	case Qcons:		qlock(&kbd);		if(waserror()) {			qunlock(&kbd);			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];				if(kbd.raw){					qiwrite(lineq, kbd.line, kbd.x+1);					kbd.x = 0;					continue;				}				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);		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 = MACHP(0)->ticks - l;			l = TK2MS(l);			readnum(0, tmp+NUMSIZE*i, NUMSIZE, l, NUMSIZE);		}		memmove(buf, tmp+k, n);		return n;	case Qpgrpid:

⌨️ 快捷键说明

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