Charles.Forsyth20060303644188019 years agoHistory
1274 lines · 19.7 KB · C
RawDownload
#include	"u.h"#include	"../port/lib.h"#include	"mem.h"#include	"dat.h"#include	"fns.h"#include	"../port/error.h"#include	<version.h>#include	"mp.h"#include	"libsec.h"#include	"keyboard.h" extern int cflag;extern int keepbroken; void	(*serwrite)(char *, int); Queue*	kscanq;			/* keyboard raw scancodes (when needed) */char*	kscanid;		/* name of raw scan format (if defined) */Queue*	kbdq;			/* unprocessed console input */Queue*	lineq;			/* processed console input */Queue*	printq;			/* console output */Queue*	klogq;			/* kernel print (log) output */int	iprintscreenputs; static struct{	RWlock;	Queue*	q;} kprintq; static struct{	QLock; 	int	raw;		/* true if we shouldn't process input */	int	ctl;		/* number of opens to the control file */	int	kbdr;		/* number of open reads to the keyboard */	int	scan;		/* true if reading raw scancodes */	int	x;		/* index into line */	char	line[1024];	/* current input line */ 	char	c;	int	count;	int	repeat;} kbd; char*	sysname;char*	eve; enum{	CMreboot,	CMhalt,	CMpanic,	CMbroken,	CMnobroken,	CMconsole,}; static Cmdtab sysctlcmd[] ={	CMreboot,	"reboot",	0,	CMhalt,	"halt", 0,	CMpanic,	"panic", 0,	CMconsole,	"console", 1,	CMbroken,	"broken", 0,	CMnobroken,	"nobroken", 0,}; voidprintinit(void){	lineq = qopen(2*1024, 0, nil, nil);	if(lineq == nil)		panic("printinit");	qnoblock(lineq, 1);} /* *  return true if current user is eve */intiseve(void){	Osenv *o; 	o = up->env;	return strcmp(eve, o->user) == 0;} static intconsactive(void){	if(printq)		return qlen(printq) > 0;	return 0;} static voidprflush(void){	ulong now; 	now = m->ticks;	while(serwrite==nil && 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){	int m;	char *t;	char buf[PRINTSIZE+2]; 	/*	 *  if kprint is open, put the message there, otherwise	 *  if there's an attached bit mapped display,	 *  put the message there.	 */	m = consoleprint;	if(canrlock(&kprintq)){		if(kprintq.q != nil){			if(waserror()){				runlock(&kprintq);				nexterror();			}			if(usewrite)				qwrite(kprintq.q, str, n);			else				qiwrite(kprintq.q, str, n);			poperror();			m = 0;		}		runlock(&kprintq);	}	if(m && screenputs != nil)		screenputs(str, n); 	/*	 *  if there's a serial line being used as a console,	 *  put the message there.	 */	if(serwrite != nil) {		serwrite(str, n);		return;	} 	if(printq == 0)		return; 	while(n > 0) {		t = memchr(str, '\n', n);		if(t && !kbd.raw) {			m = t - str;			if(m > sizeof(buf)-2)				m = sizeof(buf)-2;			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 = vseprint(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 = vseprint(s, s+PRINTSIZE, fmt, arg) - s;	va_end(arg); 	return n;} intprint(char *fmt, ...){	int n;	va_list arg;	char buf[PRINTSIZE]; 	va_start(arg, fmt);	n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf;	va_end(arg);	putstrn(buf, n); 	return n;} intfprint(int fd, char *fmt, ...){	int n;	va_list arg;	char buf[PRINTSIZE]; 	USED(fd);	va_start(arg, fmt);	n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf;	va_end(arg);	putstrn(buf, n); 	return n;} intkprint(char *fmt, ...){	va_list arg;	char buf[PRINTSIZE];	int n; 	va_start(arg, fmt);	n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf;	va_end(arg);	if(qfull(klogq))		qflush(klogq);	return qproduce(klogq, buf, 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);	uartputs(buf, n);	splx(s); 	return n;} voidpanic(char *fmt, ...){	int n;	va_list arg;	char buf[PRINTSIZE]; 	setpanic();	kprintq.q = nil;	strcpy(buf, "panic: ");	va_start(arg, fmt);	n = vseprint(buf+strlen(buf), buf+sizeof(buf)-1, fmt, arg) - buf;	va_end(arg);	buf[n] = '\n';	putstrn(buf, n+1);	spllo();	dumpstack(); 	exit(1);} void_assert(char *fmt){	panic("assert failed: %s", fmt);} voidsysfatal(char *fmt, ...){	va_list arg;	char buf[64]; 	va_start(arg, fmt);	vsnprint(buf, sizeof(buf), fmt, arg);	va_end(arg);	panic("sysfatal: %s", buf);} intpprint(char *fmt, ...){	int n;	Chan *c;	Osenv *o;	va_list arg;	char buf[2*PRINTSIZE]; 	n = sprint(buf, "%s %ld: ", up->text, up->pid);	va_start(arg, fmt);	n = vseprint(buf+n, buf+sizeof(buf), fmt, arg) - buf;	va_end(arg); 	o = up->env;	if(o->fgrp == 0) {		print("%s", buf);		return 0;	}	c = o->fgrp->fd[2];	if(c==0 || (c->mode!=OWRITE && c->mode!=ORDWR)) {		print("%s", buf);		return 0;	} 	if(waserror()) {		print("%s", buf);		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){	if(kbd.raw)		return; 	if(r == '\n'){		if(printq)			qiwrite(printq, "\r", 1);	} else if(r == 0x15){		buf = "^U\n";		n = 3;	}	if(consoleprint && screenputs != nil)		screenputs(buf, n);	if(printq)		qiwrite(printq, buf, n);} /* *	Debug key support.  Allows other parts of the kernel to register debug *	key handlers, instead of devcons.c having to know whatever's out there. *	A kproc is used to invoke most handlers, rather than tying up the CPU at *	splhi, which can choke some device drivers (eg softmodem). */typedef struct {	Rune	r;	char	*m;	void	(*f)(Rune);	int	i;	/* function called at interrupt time */} Dbgkey; static struct {	Rendez;	Dbgkey	*work;	Dbgkey	keys[50];	int	nkeys;	int	on;} dbg; static Dbgkey *finddbgkey(Rune r){	int i;	Dbgkey *dp; 	for(dp = dbg.keys, i = 0; i < dbg.nkeys; i++, dp++)		if(dp->r == r)			return dp;	return nil;} static intdbgwork(void *){	return dbg.work != 0;} static voiddbgproc(void *){	Dbgkey *dp; 	setpri(PriRealtime);	for(;;) {		do {			sleep(&dbg, dbgwork, 0);			dp = dbg.work;		} while(dp == nil);		dp->f(dp->r);		dbg.work = nil;	}} voiddebugkey(Rune r, char *msg, void (*fcn)(), int iflag){	Dbgkey *dp; 	if(dbg.nkeys >= nelem(dbg.keys))		return;	if(finddbgkey(r) != nil)		return;	for(dp = &dbg.keys[dbg.nkeys++] - 1; dp >= dbg.keys; dp--) {		if(strcmp(dp->m, msg) < 0)			break;		dp[1] = dp[0];	}	dp++;	dp->r = r;	dp->m = msg;	dp->f = fcn;	dp->i = iflag;} static intisdbgkey(Rune r){	static int ctrlt;	Dbgkey *dp;	int echoctrlt = ctrlt; 	/*	 * ^t hack BUG	 */	if(dbg.on || (ctrlt >= 2)) {		if(r == 0x14 || r == 0x05) {			ctrlt++;			return 0;		}		if(dp = finddbgkey(r)) {			if(dp->i || ctrlt > 2)				dp->f(r);			else {				dbg.work = dp;				wakeup(&dbg);			}			ctrlt = 0;			return 1;		}		ctrlt = 0;	}	else if(r == 0x14){		ctrlt++;		return 1;	}	else		ctrlt = 0;	if(echoctrlt){		char buf[3]; 		buf[0] = 0x14;		while(--echoctrlt >= 0){			echo(buf[0], buf, 1);			qproduce(kbdq, buf, 1);		}	}	return 0;} static voiddbgtoggle(Rune){

Lines 1–500 of 1274.