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

1993/0601/port/devcons.c (diff list | history)

1993/0506/sys/src/9/port/devcons.c:8,421993/0601/sys/src/9/port/devcons.c:8,41 (short | long | prev | next)
1990/0227    
 
#include	"devtab.h" 
 
1991/0607    
struct { 
	IOQ;			/* lock to klogputs */ 
	QLock;			/* qlock to getc */ 
1991/0723    
}klogq; 
1993/0601    
Queue	*mouseq; 
Queue	*kbdq;		/* unprocessed console input */ 
Queue	*lineq;		/* processed console input */ 
Queue	*printq;	/* console output */ 
Queue	*klogq; 
1990/0227    
 
1992/0409    
IOQ	mouseq; 
1991/0607    
IOQ	lineq;			/* lock to getc; interrupt putc's */ 
IOQ	printq; 
KIOQ	kbdq; 
1993/0601    
static struct 
{ 
	QLock; 
1990/0227    
 
1993/0501    
static Ref	ctl;		/* number of opens to the control file */ 
static int	raw;		/* true if ctl file is raw */ 
1993/0601    
	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 */ 
1990/0227    
 
1993/0601    
	char	c; 
	int	count; 
	int	repeat; 
} kbd; 
 
 
1992/0321    
char	sysname[NAMELEN]; 
1991/1109    
 
1990/0227    
/* 
1991/0607    
 *  init the queues and set the output routine 
1990/0227    
 */ 
void 
1991/0607    
printinit(void) 
1990/0227    
{ 
1991/0607    
	initq(&printq); 
1991/0608    
	printq.puts = 0; 
1991/0607    
	initq(&lineq); 
	initq(&kbdq); 
	kbdq.putc = kbdputc; 
	initq(&klogq); 
	initq(&mouseq); 
	mouseq.putc = mouseputc; 
1993/0601    
	klogq = qopen(32*1024, 0, 0, 0); 
	lineq = qopen(2*1024, 0, 0, 0); 
1990/0227    
} 
 
/* 
1993/0506/sys/src/9/port/devcons.c:65,711993/0601/sys/src/9/port/devcons.c:64,70
1991/0809    
	 *  put the message there.  Tack a carriage return 
	 *  before new lines. 
	 */ 
	if(printq.puts == 0) 
1993/0601    
	if(printq == 0) 
1991/0809    
		return; 
1990/0227    
	while(n > 0){ 
1991/0809    
		t = memchr(str, '\n', n); 
1993/0506/sys/src/9/port/devcons.c:74,1361993/0601/sys/src/9/port/devcons.c:73,89
1991/0809    
			memmove(buf, str, m); 
			buf[m] = '\r'; 
			buf[m+1] = '\n'; 
			(*printq.puts)(&printq, buf, m+2); 
1993/0601    
			qwrite(printq, buf, m+2, 1); 
1991/0809    
			str = t + 1; 
			n -= m + 1; 
		} else { 
			(*printq.puts)(&printq, str, n); 
1993/0601    
			qwrite(printq, str, n, 1); 
1991/0809    
			break; 
		} 
1990/0227    
	} 
} 
 
1991/0607    
/* 
 *   Print a string in the kernel log.  Ignore overflow. 
 */ 
void 
klogputs(char *str, long n) 
1990/0227    
{ 
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 
1991/0607    
isbrkc(KIOQ *q) 
1990/0227    
{ 
	uchar *p; 
                 
	for(p=q->out; p!=q->in; ){ 
1991/1224    
		if(raw) 
1991/0607    
			return 1; 
1990/0227    
		if(*p==0x04 || *p=='\n') 
			return 1; 
		p++; 
		if(p >= q->buf+sizeof(q->buf)) 
			p = q->buf; 
	} 
	return 0; 
} 
                 
int 
sprint(char *s, char *fmt, ...) 
{ 
1990/06111    
	return doprint(s, s+PRINTSIZE, fmt, (&fmt+1)) - s; 
1993/0506/sys/src/9/port/devcons.c:154,1601993/0601/sys/src/9/port/devcons.c:107,113
1991/0607    
	int n; 
 
	n = doprint(buf, buf+sizeof(buf), fmt, (&fmt+1)) - buf; 
	klogputs(buf, n); 
1993/0601    
	qwrite(klogq, buf, n, 1); 
1991/0607    
	return n; 
} 
 
1993/0506/sys/src/9/port/devcons.c:202,2081993/0601/sys/src/9/port/devcons.c:155,161
1990/0227    
void 
prflush(void) 
{ 
1991/0607    
	while(printq.in != printq.out) ; 
1993/0601    
	while(qlen(printq) > 0) ; 
1990/0227    
} 
 
void 
1993/0506/sys/src/9/port/devcons.c:245,2521993/0601/sys/src/9/port/devcons.c:198,209
1991/0607    
		return; 
	} 
	ctrlt = 0; 
1991/1224    
	if(raw) 
1993/0601    
	if(kbd.raw) 
1991/0607    
		return; 
1993/0601    
 
	/* 
	 *  finally, the actual echoing 
	 */ 
1991/1223    
	if(r == 0x15) 
1990/0227    
		putstrn("^U\n", 3); 
1991/1223    
	else 
1993/0506/sys/src/9/port/devcons.c:254,2631993/0601/sys/src/9/port/devcons.c:211,222
1990/0227    
} 
 
/* 
1991/1206    
 *  turn '\r' into '\n' before putting it into the queue 
1993/0601    
 *  Called by a uart interrupt for console input. 
 * 
 *  turn '\r' into '\n' before putting it into the queue. 
1991/0727    
 */ 
int 
kbdcr2nl(IOQ *q, int ch) 
1993/0601    
kbdcr2nl(Queue *q, int ch) 
1991/0727    
{ 
	if(ch == '\r') 
		ch = '\n'; 
1993/0506/sys/src/9/port/devcons.c:267,2771993/0601/sys/src/9/port/devcons.c:226,238
1991/0727    
/* 
1991/1223    
 *  Put character, possibly a rune, into read queue at interrupt time. 
1991/1206    
 *  Always called splhi from processor 0. 
1993/0601    
 * 
 *  Called at interrupt time to process a character. 
1990/0227    
 */ 
1991/0607    
int 
kbdputc(IOQ *q, int ch) 
1993/0601    
kbdputc(Queue *q, int ch) 
1990/0227    
{ 
1991/1223    
	int i, n; 
1993/0601    
	int n; 
1991/1223    
	char buf[3]; 
	Rune r; 
 
1993/0506/sys/src/9/port/devcons.c:281,2941993/0601/sys/src/9/port/devcons.c:242,248
1991/1223    
	if(n == 0) 
		return 0; 
	echo(r, buf, n); 
	kbdq.c = r; 
	for(i=0; i<n; i++){ 
		*kbdq.in++ = buf[i]; 
		if(kbdq.in == kbdq.buf+sizeof(kbdq.buf)) 
			kbdq.in = kbdq.buf; 
	} 
1991/1224    
	if(raw || r=='\n' || r==0x04) 
1990/0227    
		wakeup(&kbdq.r); 
1993/0601    
	qproduce(kbdq, buf, n); 
1991/0607    
	return 0; 
1990/0227    
} 
 
1993/0506/sys/src/9/port/devcons.c:295,3221993/0601/sys/src/9/port/devcons.c:249,276
1990/0227    
void 
1991/0607    
kbdrepeat(int rep) 
1990/0227    
{ 
1991/0607    
	kbdq.repeat = rep; 
	kbdq.count = 0; 
1993/0601    
	kbd.repeat = rep; 
	kbd.count = 0; 
1991/0607    
} 
1990/0227    
 
1991/0607    
void 
kbdclock(void) 
{ 
	if(kbdq.repeat == 0) 
1993/0601    
	if(kbd.repeat == 0) 
1991/0607    
		return; 
	if(kbdq.repeat==1 && ++kbdq.count>HZ){ 
		kbdq.repeat = 2; 
		kbdq.count = 0; 
1993/0601    
	if(kbd.repeat==1 && ++kbd.count>HZ){ 
		kbd.repeat = 2; 
		kbd.count = 0; 
1991/0607    
		return; 
1990/0227    
	} 
1991/0607    
	if(++kbdq.count&1) 
		kbdputc(&kbdq, kbdq.c); 
1993/0601    
	if(++kbd.count&1) 
		kbdputc(kbdq, kbd.c); 
1990/0227    
} 
 
int 
consactive(void) 
{ 
	return printq.in != printq.out; 
1993/0601    
	return qlen(printq) > 0; 
1990/0227    
} 
 
enum{ 
1993/0506/sys/src/9/port/devcons.c:456,4621993/0601/sys/src/9/port/devcons.c:410,418
1991/1224    
	case Qconsctl: 
1993/0330    
		if(!iseve()) 
1991/0620    
			error(Eperm); 
1991/1224    
		incref(&ctl); 
1993/0601    
		qlock(&kbd); 
		kbd.ctl++; 
		qunlock(&kbd); 
1991/0607    
		break; 
1990/0227    
	} 
	return devopen(c, omode, consdir, NCONS, devgen); 
1993/0506/sys/src/9/port/devcons.c:476,4851993/0601/sys/src/9/port/devcons.c:432,441
1993/0330    
	switch(c->qid.path){ 
	case Qconsctl: 
		if(c->flag&COPEN){ 
			lock(&ctl); 
			if(--ctl.ref == 0) 
				raw = 0; 
			unlock(&ctl); 
1993/0601    
			qlock(&kbd); 
			if(--kbd.ctl == 0) 
				kbd.raw = 0; 
			qunlock(&kbd); 
1993/0330    
		} 
	case Qauth: 
	case Qauthcheck: 
1993/0506/sys/src/9/port/devcons.c:504,5551993/0601/sys/src/9/port/devcons.c:460,500
1990/0227    
		return devdirread(c, buf, n, consdir, NCONS, devgen); 
 
	case Qcons: 
		qlock(&kbdq); 
1993/0601    
		qlock(&kbd); 
1990/0617    
		if(waserror()){ 
			qunlock(&kbdq); 
1993/0601    
			qunlock(&kbd); 
1990/0617    
			nexterror(); 
		} 
1990/0227    
		while(!cangetc(&lineq)){ 
1991/0607    
			sleep(&kbdq.r, isbrkc, &kbdq); 
1990/0227    
			do{ 
1991/0607    
				lock(&lineq); 
1990/0227    
				ch = getc(&kbdq); 
1992/0602    
				if(raw) 
1991/0607    
					goto Default; 
1990/0227    
				switch(ch){ 
				case '\b': 
					if(lineq.in != lineq.out){ 
						if(lineq.in == lineq.buf) 
							lineq.in = lineq.buf+sizeof(lineq.buf); 
						lineq.in--; 
					} 
					break; 
				case 0x15: 
					lineq.in = lineq.out; 
					break; 
1991/0607    
				Default: 
1990/0227    
				default: 
1991/0607    
					*lineq.in = ch; 
					if(lineq.in >= lineq.buf+sizeof(lineq.buf)-1) 
						lineq.in = lineq.buf; 
					else 
						lineq.in++; 
1990/0227    
				} 
1991/0607    
				unlock(&lineq); 
1991/1224    
			}while(raw==0 && ch!='\n' && ch!=0x04); 
1990/0227    
		} 
		i = 0; 
1991/0607    
		while(n > 0){ 
1990/0227    
			ch = getc(&lineq); 
1991/1224    
			if(ch==-1 || (raw==0 && ch==0x04)) 
1993/0601    
		while(!qcanread(lineq)){ 
			qread(kbdq, &kbd.line[kbd.x], 1); 
			ch = kbd.line[kbd.x]; 
			if(kbd.raw){ 
				i = splhi(); 
				qproduce(lineq, &kbd.line[kbd.x], 1); 
				splx(i); 
				continue; 
			} 
			switch(ch){ 
			case '\b': 
				if(kbd.x) 
					kbd.x--; 
1990/0227    
				break; 
			i++; 
			*cbuf++ = ch; 
			--n; 
1993/0601    
			case 0x15: 
				kbd.x = 0; 
				break; 
			default: 
				kbd.line[kbd.x++] = ch; 
				break; 
			} 
			if(kbd.x == sizeof(kbd.line) || ch == '\n' || ch == 0x04){ 
				if(ch == 0x04) 
					kbd.x--; 
				qwrite(lineq, kbd.line, kbd.x, 1); 
			} 
1990/0227    
		} 
1991/0614    
		poperror(); 
1990/0227    
		qunlock(&kbdq); 
		return i; 
1993/0601    
		n = qread(lineq, buf, n); 
		qunlock(&kbd); 
		return n; 
1990/0227    
 
	case Qcputime: 
1991/0411    
		k = offset; 
1993/0506/sys/src/9/port/devcons.c:613,6331993/0601/sys/src/9/port/devcons.c:558,564
1991/0607    
		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; 
1993/0601    
		return qread(klogq, buf, n); 
1991/0607    
 
	case Qmsec: 
		return readnum(offset, buf, n, TK2MS(MACHP(0)->ticks), NUMSIZE); 
1993/0506/sys/src/9/port/devcons.c:730,7361993/0601/sys/src/9/port/devcons.c:661,667
1991/1116    
	long l, bp; 
1993/0330    
	char *a = va; 
1991/0425    
	Mach *mp; 
1991/1224    
	int id, fd, ch; 
1993/0601    
	int id, fd; 
1991/0705    
	Chan *swc; 
1990/0227    
 
1990/11211    
	switch(c->qid.path){ 
1993/0506/sys/src/9/port/devcons.c:757,7761993/0601/sys/src/9/port/devcons.c:688,702
1991/1224    
		buf[n] = 0; 
		for(a = buf; a;){ 
			if(strncmp(a, "rawon", 5) == 0){ 
				lock(&lineq); 
				while((ch=getc(&kbdq)) != -1){ 
					*lineq.in++ = ch; 
					if(lineq.in == lineq.buf+sizeof(lineq.buf)) 
						lineq.in = lineq.buf; 
1993/0601    
				qlock(&kbd); 
				if(kbd.x){ 
					qwrite(kbdq, kbd.line, kbd.x, 1); 
					kbd.x = 0; 
1991/1224    
				} 
				unlock(&lineq); 
				lock(&ctl); 
				raw = 1; 
				unlock(&ctl); 
1993/0601    
				kbd.raw = 1; 
				qunlock(&kbd); 
1991/1224    
			} else if(strncmp(a, "rawoff", 6) == 0){ 
				lock(&ctl); 
				raw = 0; 
				unlock(&ctl); 
1993/0601    
				kbd.raw = 0; 
1991/1224    
			} 
			if(a = strchr(a, ' ')) 
				a++; 


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