henesyinit from p9fd787fda5 years agoHistory
1210 lines · 20.1 KB · C
RawDownload
#include	"u.h"#include	"../port/lib.h"#include	"mem.h"#include	"dat.h"#include	"fns.h"#include	"../port/error.h" #include	<authsrv.h> void	(*consdebug)(void) = nil;void	(*screenputs)(char*, int) = nil; Queue*	kbdq;			/* unprocessed console input */Queue*	lineq;			/* processed console input */Queue*	serialoq;		/* serial console output */Queue*	kprintoq;		/* console output, for /dev/kprint */ulong	kprintinuse;		/* test and set whether /dev/kprint is open */int		iprintscreenputs = 1; 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 */ 	int	count;	int	ctlpoff; 	/* a place to save up characters at interrupt time before dumping them in the queue */	Lock	lockputc;	char	istage[512];	char	*iw;	char	*ir;	char	*ie;} kbd = {	.iw	= kbd.istage,	.ir	= kbd.istage,	.ie	= kbd.istage + sizeof(kbd.istage),}; char	*sysname;vlong	fasthz; 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); enum{	CMreboot,	CMpanic,}; Cmdtab rebootmsg[] ={	CMreboot,	"reboot",	0,	CMpanic,	"panic",	0,}; voidprintinit(void){	lineq = qopen(2*1024, 0, 0, 0);	if(lineq == nil)		panic("printinit");	qnoblock(lineq, 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){	int m;	char *t; 	/*	 *  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); 	if(serialoq == nil){		uartputs(str, n);		return;	} 	while(n > 0) {		t = memchr(str, '\n', n);		if(t && !kbd.raw) {			m = t-str;			if(usewrite){				qwrite(serialoq, str, m);				qwrite(serialoq, "\r\n", 2);			} else {				qiwrite(serialoq, str, m);				qiwrite(serialoq, "\r\n", 2);			}			n -= m+1;			str = t+1;		} else {			if(usewrite)				qwrite(serialoq, str, n);			else				qiwrite(serialoq, str, n);			break;		}	}} 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;} 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];	static int panicking; 	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);} 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 = 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);	c->offset += n;	unlock(c); 	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);} voidecho(char *buf, int n){	static int ctrlt, pid;	extern ulong etext;	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 == 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();			return;		case 'k':			if(!cpuserver)				killbig();			return;		case 'r':			exit(0);			return;		}	} 	qproduce(kbdq, buf, n);	if(kbd.raw)		return;	if(screenputs != nil)		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*, int ch){	char *next; 	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;} /* *  Put character, possibly a rune, into read queue at interrupt time. *  Called at interrupt time to process a character. */intkbdputc(Queue*, int ch){	int i, n;	char buf[3];	Rune r;	char *next; 	if(kbd.ir == nil)		return 0;		/* in case we're not inited yet */		ilock(&kbd.lockputc);		/* just a mutex */	r = ch;	n = runetochar(buf, &r);	for(i = 0; i < n; i++){		next = kbd.iw+1;		if(next >= kbd.ie)			next = kbd.istage;		if(next == kbd.ir)			break;		*kbd.iw = buf[i];		kbd.iw = next;	}	iunlock(&kbd.lockputc);	return 0;} /* *  we save up input characters till clock time to reduce *  per character interrupt overhead. */static voidkbdputcclock(void){	char *iw; 	/* this amortizes cost of qproduce */	if(kbd.iw != kbd.ir){		iw = kbd.iw;		if(iw < kbd.ir){			echo(kbd.ir, kbd.ie-kbd.ir);			kbd.ir = kbd.istage;		}		echo(kbd.ir, iw-kbd.ir);		kbd.ir = iw;	}} enum{	Qdir,	Qbintime,	Qcons,	Qconsctl,	Qcputime,	Qdrivers,	Qkprint,	Qhostdomain,	Qhostowner,	Qnull,	Qosversion,	Qpgrpid,	Qpid,	Qppid,	Qrandom,	Qreboot,	Qswap,	Qsysname,	Qsysstat,	Qtime,	Quser,	Qzero,

Lines 1–500 of 1210.