plan 9 kernel history: overview | file list | diff list

1991/0607/port/devcons.c (diff list | history)

1991/0427/sys/src/9/port/devcons.c:8,971991/0607/sys/src/9/port/devcons.c:8,42 (short | long | prev | next)
1990/0227    
 
#include	"devtab.h" 
 
static struct 
{ 
	Lock; 
	uchar	buf[4000]; 
	uchar	*in; 
	uchar	*out; 
	int	printing; 
	int	c; 
}printq; 
1991/0607    
struct { 
	IOQ;			/* lock to klogputs */ 
	QLock;			/* qlock to getc */ 
}	klogq; 
1990/0227    
 
typedef struct IOQ	IOQ; 
1991/0607    
IOQ	lineq;			/* lock to getc; interrupt putc's */ 
IOQ	printq; 
IOQ	mouseq; 
KIOQ	kbdq; 
1990/0227    
 
#define	NQ	4096 
struct IOQ{ 
	union{ 
		Lock; 
		QLock; 
	}; 
	uchar	buf[NQ]; 
	uchar	*in; 
	uchar	*out; 
	int	state; 
	Rendez	r; 
}; 
1991/0607    
Ref	raw;		/* whether kbd i/o is raw (rcons is open) */ 
1990/0227    
 
IOQ	kbdq;		/* qlock to getc; interrupt putc's */ 
IOQ	lineq;		/* lock to getc; interrupt putc's */ 
                 
1990/1018    
#define SYSLOGMAGIC	0xdeadbeaf 
#define SYSLOG		((Syslog *)(UNCACHED | 0x1B00)) 
1990/0928    
typedef struct Syslog	Syslog; 
struct Syslog 
{ 
	ulong	magic; 
1990/1018    
	int	wrapped; 
1990/0928    
	char	*next; 
1990/1018    
	char	buf[2*1024]; 
1990/0928    
}; 
                 
                 
1990/0227    
void 
printinit(void) 
{ 
                 
	printq.in = printq.buf; 
	printq.out = printq.buf; 
	lock(&printq);		/* allocate lock */ 
	unlock(&printq); 
                 
	kbdq.in = kbdq.buf; 
	kbdq.out = kbdq.buf; 
	lineq.in = lineq.buf; 
	lineq.out = lineq.buf; 
	qlock(&kbdq);		/* allocate qlock */ 
	qunlock(&kbdq); 
	lock(&lineq);		/* allocate lock */ 
	unlock(&lineq); 
                 
	duartinit(); 
} 
                 
/* 
 * Put a string on the console. 
 * n bytes of s are guaranteed to fit in the buffer and is ready to print. 
 * Must be called splhi() and with printq locked. 
1991/0607    
 *  init the queues and set the output routine 
1990/0227    
 */ 
void 
puts(char *s, int n) 
1991/0607    
printinit(void) 
1990/0227    
{ 
	if(!printq.printing){ 
		printq.printing = 1; 
		printq.c = *s++; 
		n--; 
	} 
1991/0318    
	memmove(printq.in, s, n); 
1990/0227    
	printq.in += n; 
	if(printq.in >= printq.buf+sizeof(printq.buf)) 
		printq.in = printq.buf; 
1991/0607    
	initq(&printq); 
	initq(&lineq); 
	initq(&kbdq); 
	kbdq.putc = kbdputc; 
	initq(&klogq); 
	initq(&mouseq); 
	mouseq.putc = mouseputc; 
1990/0227    
} 
 
/* 
 * Print a string on the console.  This is the high level routine 
 * with a queue to the interrupt handler.  BUG: There is no check against 
 * overflow. 
1991/0607    
 *   Print a string on the console.  Convert \n to \r\n 
1990/0227    
 */ 
void 
putstrn(char *str, int n) 
1991/0427/sys/src/9/port/devcons.c:99,1371991/0607/sys/src/9/port/devcons.c:44,102
1990/0227    
	int s, c, m; 
	char *t; 
 
	s = splhi(); 
	lock(&printq); 
1990/0718    
	syslog(str, n); 
1990/0227    
	while(n > 0){ 
		if(*str == '\n') 
			puts("\r", 1); 
		m = printq.buf+sizeof(printq.buf) - printq.in; 
		if(n < m) 
			m = n; 
1991/0607    
		if(printq.puts && *str=='\n') 
			(*printq.puts)(&printq, "\r", 1); 
		m = n; 
1990/0227    
		t = memchr(str+1, '\n', m-1); 
		if(t) 
			if(t-str < m) 
				m = t - str; 
		puts(str, m); 
1991/0607    
		if(printq.puts) 
			(*printq.puts)(&printq, str, m); 
		screenputs(str, m); 
1990/0227    
		n -= m; 
		str += m; 
	} 
	unlock(&printq); 
	splx(s); 
} 
 
int 
cangetc(IOQ *q) 
1991/0607    
/* 
 *   Print a string in the kernel log.  Ignore overflow. 
 */ 
void 
klogputs(char *str, long n) 
1990/0227    
{ 
	return q->in != q->out; 
1991/0607    
	int s, m; 
	uchar *nextin; 
 
	s = splhi(); 
	lock(&klogq); 
	while(n){ 
		m = &klogq.buf[NQ] - klogq.in; 
		if(m > n) 
			m = n; 
		memmove(klogq.in, str, m); 
		n -= m; 
		str += m; 
		nextin = klogq.in + m; 
		if(nextin >= &klogq.buf[NQ]) 
			klogq.in = klogq.buf; 
		else 
			klogq.in = nextin; 
	} 
	unlock(&klogq); 
	splx(s); 
	wakeup(&klogq.r); 
1990/0227    
} 
 
int 
isbrkc(IOQ *q) 
1991/0607    
isbrkc(KIOQ *q) 
1990/0227    
{ 
	uchar *p; 
 
	for(p=q->out; p!=q->in; ){ 
1991/0607    
		if(raw.ref) 
			return 1; 
1990/0227    
		if(*p==0x04 || *p=='\n') 
			return 1; 
		p++; 
1991/0427/sys/src/9/port/devcons.c:142,1601991/0607/sys/src/9/port/devcons.c:107,112
1990/0227    
} 
 
int 
getc(IOQ *q) 
{ 
	int c; 
                 
	if(q->in == q->out) 
		return -1; 
	c = *q->out++; 
	if(q->out == q->buf+sizeof(q->buf)) 
		q->out = q->buf; 
	return c; 
} 
                 
int 
sprint(char *s, char *fmt, ...) 
{ 
1990/06111    
	return doprint(s, s+PRINTSIZE, fmt, (&fmt+1)) - s; 
1991/0427/sys/src/9/port/devcons.c:171,1761991/0607/sys/src/9/port/devcons.c:123,139
1990/0227    
	return n; 
} 
 
1991/0607    
int 
kprint(char *fmt, ...) 
{ 
	char buf[PRINTSIZE]; 
	int n; 
 
	n = doprint(buf, buf+sizeof(buf), fmt, (&fmt+1)) - buf; 
	klogputs(buf, n); 
	return n; 
} 
 
1990/0227    
void 
panic(char *fmt, ...) 
{ 
1991/0427/sys/src/9/port/devcons.c:212,2661991/0607/sys/src/9/port/devcons.c:175,224
1990/0227    
void 
prflush(void) 
{ 
	while(printq.printing) 
		delay(100); 
1991/0607    
	while(printq.in != printq.out) ; 
1990/0227    
} 
 
/* 
 * Get character to print at interrupt time. 
 * Always called splhi from proc 0. 
 */ 
int 
conschar(void) 
{ 
	uchar *p; 
	int c; 
                 
	lock(&printq); 
	p = printq.out; 
	if(p == printq.in){ 
		printq.printing = 0; 
		c = -1; 
	}else{ 
		c = *p++; 
		if(p >= printq.buf+sizeof(printq.buf)) 
			p = printq.buf; 
		printq.out = p; 
	} 
	unlock(&printq); 
	return c; 
} 
                 
void 
echo(int c) 
{ 
	char ch; 
1991/0607    
	static int ctrlt; 
1990/03091    
 
1990/0227    
	/* 
	 * ^t hack BUG 
1991/0607    
	 * ^p hack 
1990/0227    
	 */ 
1991/0421    
	if(c == 0x10) 
1991/0327    
		panic("^p"); 
1990/0227    
	if(c == 0x14) 
		DEBUG(); 
1991/0607    
	/* 
	 * ^t hack BUG 
	 */ 
	if(ctrlt == 2){ 
		ctrlt = 0; 
		switch(c){ 
		case 0x14: 
			break;	/* pass it on */ 
		case 'm': 
			mntdump(); 
			return; 
		case 'p': 
			DEBUG(); 
			return; 
		case 'q': 
			dumpqueues(); 
			return; 
		case 'r': 
			exit(); 
			break; 
		} 
	}else if(c == 0x14){ 
		ctrlt++; 
		return; 
	} 
	ctrlt = 0; 
	if(raw.ref) 
		return; 
1990/0227    
	if(c == 0x15) 
		putstrn("^U\n", 3); 
1990/0504    
	if(c == 0x16) 
1990/0707    
		dumpqueues(); 
1990/1231    
	if(c == 0xe) 
		nonettoggle(); 
	if(c == 0xc) 
		lancetoggle(); 
1990/0227    
	else{ 
		ch = c; 
		putstrn(&ch, 1); 
1991/0427/sys/src/9/port/devcons.c:271,3011991/0607/sys/src/9/port/devcons.c:229,266
1990/0227    
 * Put character into read queue at interrupt time. 
 * Always called splhi from proc 0. 
 */ 
void 
kbdchar(int c) 
1991/0607    
int 
kbdputc(IOQ *q, int ch) 
1990/0227    
{ 
1991/0327    
	if(c == 0)	/* NULs cause trouble */ 
		return; 
1990/0227    
	if(c == '\r') 
		c = '\n'; 
	echo(c); 
	*kbdq.in++ = c; 
1991/0607    
	echo(ch); 
	kbdq.c = ch; 
	*kbdq.in++ = ch; 
1990/0227    
	if(kbdq.in == kbdq.buf+sizeof(kbdq.buf)) 
		kbdq.in = kbdq.buf; 
	if(c=='\n' || c==0x04) 
1991/0607    
	if(raw.ref || ch=='\n' || ch==0x04) 
1990/0227    
		wakeup(&kbdq.r); 
1991/0607    
	return 0; 
1990/0227    
} 
 
void 
printslave(void) 
1991/0607    
kbdrepeat(int rep) 
1990/0227    
{ 
	int c; 
1991/0607    
	kbdq.repeat = rep; 
	kbdq.count = 0; 
} 
1990/0227    
 
	c = printq.c; 
	if(c){ 
		printq.c = 0; 
		duartxmit(c); 
1991/0607    
void 
kbdclock(void) 
{ 
	if(kbdq.repeat == 0) 
		return; 
	if(kbdq.repeat==1 && ++kbdq.count>HZ){ 
		kbdq.repeat = 2; 
		kbdq.count = 0; 
		return; 
1990/0227    
	} 
1991/0607    
	if(++kbdq.count&1) 
		kbdputc(&kbdq, kbdq.c); 
1990/0227    
} 
 
int 
1991/0427/sys/src/9/port/devcons.c:311,3411991/0607/sys/src/9/port/devcons.c:276,312
1990/0227    
	Qdir, 
	Qcons, 
	Qcputime, 
1990/0720    
	Qlog, 
1991/0607    
	Qlights, 
	Qnoise, 
1990/0227    
	Qnull, 
1990/1018    
/*	Qpanic, /**/ 
1990/0227    
	Qpgrpid, 
	Qpid, 
	Qppid, 
1991/0607    
	Qrcons, 
1990/0227    
	Qtime, 
	Quser, 
1990/11161    
	Qvmereset, 
1991/0607    
	Qklog, 
	Qmsec, 
	Qclock, 
1991/0425    
	Qsysstat, 
1990/0227    
}; 
 
Dirtab consdir[]={ 
1990/11211    
	"cons",		{Qcons},	0,	0600, 
	"cputime",	{Qcputime},	72,	0600, 
	"log",		{Qlog},		BY2PG-8,	0600, 
	"null",		{Qnull},	0,	0600, 
/*	"panic",	{Qpanic},	0,	0666, /**/ 
	"pgrpid",	{Qpgrpid},	12,	0600, 
	"pid",		{Qpid},		12,	0600, 
	"ppid",		{Qppid},	12,	0600, 
	"time",		{Qtime},	12,	0600, 
	"user",		{Quser},	0,	0600, 
	"vmereset",	{Qvmereset},	0,	0600, 
1991/0425    
	"sysstat",	{Qsysstat},	0,	0600, 
1991/0607    
	"cons",		{Qcons},	0,		0600, 
	"cputime",	{Qcputime},	6*NUMSIZE,	0600, 
	"lights",	{Qlights},	0,		0600, 
	"noise",	{Qnoise},	0,		0600, 
	"null",		{Qnull},	0,		0600, 
	"pgrpid",	{Qpgrpid},	NUMSIZE,	0600, 
	"pid",		{Qpid},		NUMSIZE,	0600, 
	"ppid",		{Qppid},	NUMSIZE,	0600, 
	"rcons",	{Qrcons},	0,		0600, 
	"time",		{Qtime},	NUMSIZE,	0600, 
	"user",		{Quser},	0,		0600, 
	"klog",		{Qklog},	0,		0400, 
	"msec",		{Qmsec},	NUMSIZE,	0400, 
	"clock",	{Qclock},	2*NUMSIZE,	0400, 
	"sysstat",	{Qsysstat},	0,		0600, 
1990/0227    
}; 
 
#define	NCONS	(sizeof consdir/sizeof(Dirtab)) 
1991/0427/sys/src/9/port/devcons.c:415,4261991/0607/sys/src/9/port/devcons.c:386,414
1990/0227    
Chan* 
consopen(Chan *c, int omode) 
{ 
1990/11211    
	if(c->qid.path==Quser && omode==(OWRITE|OTRUNC)){ 
1990/0227    
		/* truncate? */ 
		if(strcmp(u->p->pgrp->user, "bootes") == 0)	/* BUG */ 
			u->p->pgrp->user[0] = 0; 
		else 
1990/11211    
			error(Eperm); 
1991/0607    
	int ch; 
 
	switch(c->qid.path){ 
	case Quser: 
		if(omode==(OWRITE|OTRUNC)){ 
			/* truncate? */ 
			if(strcmp(u->p->pgrp->user, "bootes") == 0)	/* BUG */ 
				u->p->pgrp->user[0] = 0; 
			else 
				error(Eperm); 
		} 
		break; 
	case Qrcons: 
		if(incref(&raw) == 1){ 
			lock(&lineq); 
			while((ch=getc(&kbdq)) != -1){ 
				*lineq.in++ = ch; 
				if(lineq.in == lineq.buf+sizeof(lineq.buf)) 
					lineq.in = lineq.buf; 
			} 
			unlock(&lineq); 
		} 
		break; 
1990/0227    
	} 
	return devopen(c, omode, consdir, NCONS, devgen); 
} 
1991/0427/sys/src/9/port/devcons.c:434,4411991/0607/sys/src/9/port/devcons.c:422,432
1990/0227    
void 
consclose(Chan *c) 
{ 
1991/0607    
	if(c->qid.path==Qrcons && (c->flag&COPEN)) 
		decref(&raw); 
1990/0227    
} 
 
1991/0607    
 
1990/0227    
long 
1991/0411    
consread(Chan *c, void *buf, long n, ulong offset) 
1990/0227    
{ 
1991/0427/sys/src/9/port/devcons.c:445,4511991/0607/sys/src/9/port/devcons.c:436,442
1990/0227    
	char *cbuf = buf; 
	char *user; 
	int userlen; 
1991/0425    
	char tmp[6*NUMSIZE], xbuf[512]; 
1991/0607    
	char tmp[6*NUMSIZE], xbuf[1024]; 
1991/0425    
	Mach *mp; 
1990/0227    
 
	if(n <= 0) 
1991/0427/sys/src/9/port/devcons.c:454,4591991/0607/sys/src/9/port/devcons.c:445,451
1990/0227    
	case Qdir: 
		return devdirread(c, buf, n, consdir, NCONS, devgen); 
 
1991/0607    
	case Qrcons: 
1990/0227    
	case Qcons: 
		qlock(&kbdq); 
1990/0617    
		if(waserror()){ 
1991/0427/sys/src/9/port/devcons.c:461,4691991/0607/sys/src/9/port/devcons.c:453,466
1990/0617    
			nexterror(); 
		} 
1990/0227    
		while(!cangetc(&lineq)){ 
			sleep(&kbdq.r, (int(*)(void*))isbrkc, &kbdq); 
1991/0607    
			sleep(&kbdq.r, isbrkc, &kbdq); 
1990/0227    
			do{ 
1991/0607    
				lock(&lineq); 
1990/0227    
				ch = getc(&kbdq); 
1991/0607    
				if(raw.ref){ 
					unlock(&lineq); 
					goto Default; 
				} 
1990/0227    
				switch(ch){ 
				case '\b': 
					if(lineq.in != lineq.out){ 
1991/0427/sys/src/9/port/devcons.c:475,4911991/0607/sys/src/9/port/devcons.c:472,492
1990/0227    
				case 0x15: 
					lineq.in = lineq.out; 
					break; 
1991/0607    
				Default: 
1990/0227    
				default: 
					*lineq.in++ = ch; 
					if(lineq.in == lineq.buf+sizeof(lineq.buf)) 
					lineq.in = lineq.buf; 
1991/0607    
					*lineq.in = ch; 
					if(lineq.in >= lineq.buf+sizeof(lineq.buf)-1) 
						lineq.in = lineq.buf; 
					else 
						lineq.in++; 
1990/0227    
				} 
			}while(ch!='\n' && ch!=0x04); 
1991/0607    
				unlock(&lineq); 
			}while(raw.ref==0 && ch!='\n' && ch!=0x04); 
1990/0227    
		} 
		i = 0; 
		while(n>0){ 
1991/0607    
		while(n > 0){ 
1990/0227    
			ch = getc(&lineq); 
			if(ch == 0x04 || ch == -1) 
1991/0607    
			if(ch==-1 || (raw.ref==0 && ch==0x04)) 
1990/0227    
				break; 
			i++; 
			*cbuf++ = ch; 
1991/0427/sys/src/9/port/devcons.c:523,5341991/0607/sys/src/9/port/devcons.c:524,566
1990/0227    
	case Qtime: 
1991/0411    
		return readnum(offset, buf, n, boottime+TK2SEC(MACHP(0)->ticks), 12); 
1990/0227    
 
1991/0607    
	case Qclock: 
		k = offset; 
		if(k >= 2*NUMSIZE) 
			return 0; 
		if(k+n > 2*NUMSIZE) 
			n = 2*NUMSIZE - k; 
		readnum(0, tmp, NUMSIZE, MACHP(0)->ticks, NUMSIZE); 
		readnum(0, tmp+NUMSIZE, NUMSIZE, HZ, NUMSIZE); 
		memmove(buf, tmp+k, n); 
		return n; 
 
1990/0227    
	case Quser: 
1991/0411    
		return readstr(offset, buf, n, u->p->pgrp->user); 
1990/0227    
 
1990/0720    
	case Qlog: 
1991/0411    
		return readlog(offset, buf, n); 
1991/0607    
	case Qnull: 
		return 0; 
1990/0720    
 
1991/0607    
	case Qklog: 
		qlock(&klogq); 
		if(waserror()){ 
			qunlock(&klogq); 
			nexterror(); 
		} 
		while(!cangetc(&klogq)) 
			sleep(&klogq.r, cangetc, &klogq); 
		for(i=0; i<n; i++){ 
			if((ch=getc(&klogq)) == -1) 
				break; 
			*cbuf++ = ch; 
		} 
		poperror(); 
		qunlock(&klogq); 
		return i; 
 
	case Qmsec: 
		return readnum(offset, buf, n, TK2MS(MACHP(0)->ticks), NUMSIZE); 
 
1991/0425    
	case Qsysstat: 
		j = 0; 
		for(id = 0; id < 32; id++) { 
1991/0427/sys/src/9/port/devcons.c:536,5481991/0607/sys/src/9/port/devcons.c:568,577
1991/0425    
				mp = MACHP(id); 
				j += sprint(&xbuf[j], "%d %d %d %d %d %d %d %d\n", 
					id, mp->cs, mp->intr, mp->syscall, mp->pfault, 
					    mp->tlbfault, mp->tlbpurge, mp->spinlock); 
1991/0607    
					    mp->tlbfault, mp->tlbpurge, m->spinlock); 
1991/0425    
			} 
		} 
                 
		return readstr(offset, buf, n, xbuf); 
1990/0227    
	case Qnull: 
		return 0; 
 
	default: 
		panic("consread %lux\n", c->qid); 
1991/0427/sys/src/9/port/devcons.c:550,5551991/0607/sys/src/9/port/devcons.c:579,626
1990/0227    
	} 
} 
 
1991/0607    
void 
conslights(char *a, int n) 
{ 
	int l; 
	char line[128]; 
	char *lp; 
	int c; 
 
	lp = line; 
	while(n--){ 
		*lp++ = c = *a++; 
		if(c=='\n' || n==0 || lp==&line[sizeof(line)-1]) 
			break; 
	} 
	*lp = 0; 
	lights(strtoul(line, 0, 0)); 
} 
 
void 
consnoise(char *a, int n) 
{ 
	int freq; 
	int duration; 
	char line[128]; 
	char *lp; 
	int c; 
 
	lp = line; 
	while(n--){ 
		*lp++ = c = *a++; 
		if(c=='\n' || n==0 || lp==&line[sizeof(line)-1]){ 
			*lp = 0; 
			freq = strtoul(line, &lp, 0); 
			while(*lp==' ' || *lp=='\t') 
				lp++; 
			duration = strtoul(lp, &lp, 0); 
			buzz(freq, duration); 
			lp = line; 
		} 
	} 
} 
 
1990/0227    
long 
1991/0411    
conswrite(Chan *c, void *va, long n, ulong offset) 
1990/0227    
{ 
1991/0427/sys/src/9/port/devcons.c:556,5661991/0607/sys/src/9/port/devcons.c:627,638
1990/0227    
	char cbuf[64]; 
	char buf[256]; 
	long l, m; 
1991/0425    
	int id; 
1990/0227    
	char *a = va; 
1991/0425    
	Mach *mp; 
1991/0607    
	int id; 
1990/0227    
 
1990/11211    
	switch(c->qid.path){ 
1991/0607    
	case Qrcons: 
1990/0227    
	case Qcons: 
		/* 
		 * Damn. Can't page fault in putstrn, so copy the data locally. 
1991/0427/sys/src/9/port/devcons.c:607,6171991/0607/sys/src/9/port/devcons.c:679,692
1990/0227    
	case Qnull: 
		break; 
1990/11161    
 
	case Qvmereset: 
		if(strcmp(u->p->pgrp->user, "bootes") != 0) 
1990/11211    
			error(Eperm); 
1990/11161    
		vmereset(); 
1991/0607    
	case Qnoise: 
		consnoise(a, n); 
1990/11161    
		break; 
1991/0607    
 
	case Qlights: 
		conslights(a, n); 
		break; 
 
1991/0425    
	case Qsysstat: 
		for(id = 0; id < 32; id++) { 
			if(active.machs & (1<<id)) { 
1991/0427/sys/src/9/port/devcons.c:625,6321991/0607/sys/src/9/port/devcons.c:700,707
1991/0425    
				mp->spinlock = 0; 
			} 
		} 
1990/11161    
                 
1991/0425    
		break; 
1991/0607    
 
1990/0227    
	default: 
1990/11211    
		error(Egreg); 
1990/0227    
	} 
1991/0427/sys/src/9/port/devcons.c:643,7621991/0607/sys/src/9/port/devcons.c:718,721
1990/0227    
conswstat(Chan *c, char *dp) 
{ 
1990/11211    
	error(Eperm); 
1990/0720    
} 
                 
/* 
1990/0912    
 *  kernel based system log, passed between crashes 
1990/0720    
 */ 
void 
sysloginit(void) 
{ 
	Syslog *s; 
1990/1018    
	int i; 
1990/0720    
                 
	s = SYSLOG; 
1990/1018    
	if(s->magic!=SYSLOGMAGIC || s->next>=&s->buf[sizeof(s->buf)] || s->next<s->buf){ 
		s->wrapped = 0; 
1990/0720    
		s->next = s->buf; 
		s->magic = SYSLOGMAGIC; 
	} 
} 
                 
void 
syslog(char *p, int n) 
{ 
	Syslog *s; 
	char *end; 
1990/1018    
	int m; 
1990/0720    
                 
1990/1018    
	sysloginit(); 
1990/0720    
	s = SYSLOG; 
	end = &s->buf[sizeof(s->buf)]; 
1990/1018    
	while(n){ 
		if(s->next + n > end) 
			m = end - s->next; 
		else 
			m = n; 
1991/0318    
		memmove(s->next, p, m); 
1990/1018    
		s->next += m; 
		p += m; 
		n -= m; 
		if(s->next >= end){ 
			s->wrapped = 1; 
1990/0720    
			s->next = s->buf; 
1990/1018    
		} 
1990/0720    
	} 
1990/0912    
	wbflush(); 
1990/0720    
} 
                 
long 
1990/1018    
readlog(ulong off, char *buf, ulong len) 
1990/0720    
{ 
	Syslog *s; 
	char *end; 
1990/1018    
	char *start; 
	int n, m; 
	char *p; 
1990/0720    
                 
1990/1018    
	n = len; 
	p = buf; 
                 
	sysloginit(); 
1990/0720    
	s = SYSLOG; 
1990/1018    
	end = &s->buf[sizeof(s->buf)]; 
1990/0720    
                 
1990/1018    
	if(s->wrapped){ 
		start = s->next; 
		m = sizeof(s->buf); 
	} else { 
		start = s->buf; 
		m = s->next - start; 
	} 
                 
	if(off > m) 
1990/0720    
		return 0; 
1990/1018    
	if(off + n > m) 
		n = m - off; 
	start += off; 
	if(start > end) 
		start -= sizeof(s->buf); 
1990/0720    
                 
1990/1018    
	while(n > 0){ 
		if(start + n > end) 
			m = end - start; 
		else 
			m = n; 
1991/0318    
		memmove(p, start, m); 
1990/1018    
		start += m; 
		p += m; 
		n -= m; 
		if(start >= end) 
			start = s->buf; 
	} 
                 
	return p-buf; 
} 
                 
/* 
 *  Read and write every byte of the log.  This seems to ensure that 
 *  on reboot, the bytes will really be in memory.  I don't understand -- presotto 
 */ 
void 
flushsyslog(void) 
{ 
	Syslog *s; 
	char *p, *end; 
	int x; 
                 
	s = SYSLOG; 
1990/0720    
	end = &s->buf[sizeof(s->buf)]; 
                 
1990/1018    
	x = splhi(); 
	lock(&printq); 
	for(p = s->buf; p < end; p++) 
		*p = *p; 
	unlock(&printq); 
	splx(x); 
1990/0912    
                 
1990/1018    
	wbflush(); 
1990/0227    
} 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)