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

📄 devcons.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
#include	"u.h"#include	"lib.h"#include	"dat.h"#include	"fns.h"#include	"error.h"#include 	"keyboard.h"void	(*consdebug)(void) = 0;void	(*screenputs)(char*, int) = 0;Queue*	kbdq;			/* unprocessed console input */Queue*	lineq;			/* processed console input */Queue*	serialoq;		/* serial console output */Queue*	kprintoq;		/* console output, for /dev/kprint */long	kprintinuse;		/* test and set whether /dev/kprint is open */int	iprintscreenputs = 0;int	panicking;struct{	int exiting;	int machs;} active;static struct{	QLock lk;	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 */	int	count;	int	ctlpoff;	/* a place to save up characters at interrupt time before dumping them in the queue */	Lock	lockputc;	char	istage[1024];	char	*iw;	char	*ir;	char	*ie;} kbd = {	{ 0 },	0,	0,	0,	{ 0 },	0,	0,	{ 0 },	{ 0 },	kbd.istage,	kbd.istage,	kbd.istage + sizeof(kbd.istage),};char	*sysname;vlong	fasthz;static int	readtime(ulong, char*, int);static int	readbintime(char*, int);static int	writetime(char*, int);static int	writebintime(char*, int);enum{	CMreboot,	CMpanic,};Cmdtab rebootmsg[] ={	CMreboot,	"reboot",	0,	CMpanic,	"panic",	0,};intreturn0(void *v){	return 0;}voidprintinit(void){	lineq = qopen(2*1024, 0, 0, nil);	if(lineq == nil)		panic("printinit");	qnoblock(lineq, 1);	kbdq = qopen(4*1024, 0, 0, 0);	if(kbdq == nil)		panic("kbdinit");	qnoblock(kbdq, 1);}intconsactive(void){	if(serialoq)		return qlen(serialoq) > 0;	return 0;}voidprflush(void){/*	ulong now;	now = m->ticks;	while(consactive())		if(m->ticks - now >= HZ)			break;*/}/* *   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){	/*	 *  if someone is reading /dev/kprint,	 *  put the message there.	 *  if not and there's an attached bit mapped display,	 *  put the message there.	 *	 *  if there's a serial line being used as a console,	 *  put the message there.	 */	if(kprintoq != nil && !qisclosed(kprintoq)){		if(usewrite)			qwrite(kprintoq, str, n);		else			qiwrite(kprintoq, str, n);	}else if(screenputs != nil)		screenputs(str, n);}voidputstrn(char *str, int n){	putstrn0(str, n, 0);}int noprint;intprint(char *fmt, ...){	int n;	va_list arg;	char buf[PRINTSIZE];	if(noprint)		return -1;	va_start(arg, fmt);	n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf;	va_end(arg);	putstrn(buf, n);	return n;}voidpanic(char *fmt, ...){	int n;	va_list arg;	char buf[PRINTSIZE];	kprintoq = nil;	/* don't try to write to /dev/kprint */	if(panicking)		for(;;);	panicking = 1;	splhi();	strcpy(buf, "panic: ");	va_start(arg, fmt);	n = vseprint(buf+strlen(buf), buf+sizeof(buf), fmt, arg) - buf;	va_end(arg);	buf[n] = '\n';	uartputs(buf, n+1);	if(consdebug)		(*consdebug)();	spllo();	prflush();	putstrn(buf, n+1);	dumpstack();	exit(1);}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 = vseprint(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->ref.lk);	c->offset += n;	unlock(&c->ref.lk);	return n;}static voidechoscreen(char *buf, int n){	char *e, *p;	char ebuf[128];	int x;	p = ebuf;	e = ebuf + sizeof(ebuf) - 4;	while(n-- > 0){		if(p >= e){			screenputs(ebuf, p - ebuf);			p = ebuf;		}		x = *buf++;		if(x == 0x15){			*p++ = '^';			*p++ = 'U';			*p++ = '\n';		} else			*p++ = x;	}	if(p != ebuf)		screenputs(ebuf, p - ebuf);}static voidechoserialoq(char *buf, int n){	char *e, *p;	char ebuf[128];	int x;	p = ebuf;	e = ebuf + sizeof(ebuf) - 4;	while(n-- > 0){		if(p >= e){			qiwrite(serialoq, ebuf, p - ebuf);			p = ebuf;		}		x = *buf++;		if(x == '\n'){			*p++ = '\r';			*p++ = '\n';		} else if(x == 0x15){			*p++ = '^';			*p++ = 'U';			*p++ = '\n';		} else			*p++ = x;	}	if(p != ebuf)		qiwrite(serialoq, ebuf, p - ebuf);}static voidecho(char *buf, int n){	static int ctrlt;	int x;	char *e, *p;	e = buf+n;	for(p = buf; p < e; p++){		switch(*p){		case 0x10:	/* ^P */			if(cpuserver && !kbd.ctlpoff){				active.exiting = 1;				return;			}			break;		case 0x14:	/* ^T */			ctrlt++;			if(ctrlt > 2)				ctrlt = 2;			continue;		}		if(ctrlt != 2)			continue;		/* ^T escapes */		ctrlt = 0;		switch(*p){		case 'S':			x = splhi();			dumpstack();			procdump();			splx(x);			return;		case 's':			dumpstack();			return;		case 'x':			xsummary();			ixsummary();			mallocsummary();			pagersummary();			return;		case 'd':			if(consdebug == 0)				consdebug = rdb;			else				consdebug = 0;			print("consdebug now 0x%p\n", consdebug);			return;		case 'D':			if(consdebug == 0)				consdebug = rdb;			consdebug();			return;		case 'p':			x = spllo();			procdump();			splx(x);			return;		case 'q':			scheddump();			return;		case 'k':			killbig();			return;		case 'r':			exit(0);			return;		}	}	qproduce(kbdq, buf, n);	if(kbd.raw)		return;	if(screenputs != 0)		echoscreen(buf, n);	if(serialoq)		echoserialoq(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){	char *next;	USED(q);	ilock(&kbd.lockputc);		/* just a mutex */	if(ch == '\r' && !kbd.raw)		ch = '\n';	next = kbd.iw+1;	if(next >= kbd.ie)		next = kbd.istage;	if(next != kbd.ir){		*kbd.iw = ch;		kbd.iw = next;	}	iunlock(&kbd.lockputc);	return 0;}staticvoid_kbdputc(int c){	Rune r;	char buf[UTFmax];	int n;	r = c;	n = runetochar(buf, &r);	if(n == 0)		return;	echo(buf, n);//	kbd.c = r;//	qproduce(kbdq, buf, n);}/* _kbdputc, but with compose translation */intkbdputc(Queue *q, int c){	int	i;	static int collecting, nk;	static Rune kc[5];	 if(c == Kalt){		 collecting = 1;		 nk = 0;		 return 0;	 }	 if(!collecting){		 _kbdputc(c);		 return 0;	 }	kc[nk++] = c;	c = latin1(kc, nk);	if(c < -1)  /* need more keystrokes */		return 0;	if(c != -1) /* valid sequence */		_kbdputc(c);	else		for(i=0; i<nk; i++)		 	_kbdputc(kc[i]);	nk = 0;	collecting = 0;	return 0;}enum{	Qdir,	Qbintime,	Qcons,	Qconsctl,	Qcpunote,	Qcputime,	Qdrivers,	Qkprint,	Qhostdomain,	Qhostowner,	Qnull,	Qosversion,	Qpgrpid,	Qpid,	Qppid,	Qrandom,	Qreboot,	Qsecstore,	Qshowfile,	Qsnarf,	Qswap,	Qsysname,	Qsysstat,	Qtime,	Quser,	Qzero,};enum{	VLNUMSIZE=	22,};static Dirtab consdir[]={	".",	{Qdir, 0, QTDIR},	0,		DMDIR|0555,	"bintime",	{Qbintime},	24,		0664,	"cons",		{Qcons},	0,		0660,	"consctl",	{Qconsctl},	0,		0220,	"cpunote",	{Qcpunote},	0,		0444,	"cputime",	{Qcputime},	6*NUMSIZE,	0444,	"drivers",	{Qdrivers},	0,		0444,	"hostdomain",	{Qhostdomain},	DOMLEN,		0664,	"hostowner",	{Qhostowner},	0,	0664,	"kprint",		{Qkprint, 0, QTEXCL},	0,	DMEXCL|0440,	"null",		{Qnull},	0,		0666,	"osversion",	{Qosversion},	0,		0444,	"pgrpid",	{Qpgrpid},	NUMSIZE,	0444,	"pid",		{Qpid},		NUMSIZE,	0444,	"ppid",		{Qppid},	NUMSIZE,	0444,	"random",	{Qrandom},	0,		0444,	"reboot",	{Qreboot},	0,		0664,	"secstore",	{Qsecstore},	0,		0666,	"showfile",	{Qshowfile},	0,	0220,	"snarf",	{Qsnarf},		0,		0666,	"swap",		{Qswap},	0,		0664,	"sysname",	{Qsysname},	0,		0664,	"sysstat",	{Qsysstat},	0,		0666,	"time",		{Qtime},	NUMSIZE+3*VLNUMSIZE,	0664,	"user",		{Quser},	0,	0666,	"zero",		{Qzero},	0,		0444,};char secstorebuf[65536];Dirtab *secstoretab = &consdir[Qsecstore];Dirtab *snarftab = &consdir[Qsnarf];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();	/*	 * at 115200 baud, the 1024 char buffer takes 56 ms to process,	 * processing it every 22 ms should be fine	 *//*	addclock0link(kbdputcclock, 22); */}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:		qlock(&kbd.lk);		kbd.ctl++;		qunlock(&kbd.lk);		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);

⌨️ 快捷键说明

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