xref: /plan9-contrib/sys/src/cmd/fossil/Ccons.c (revision d7aba6c3b511bc618cf0c53345848188fc02611a)
15e96a66cSDavid du Colombier #include "stdinc.h"
25e96a66cSDavid du Colombier 
35e96a66cSDavid du Colombier #include "9.h"
45e96a66cSDavid du Colombier 
55e96a66cSDavid du Colombier enum {
65e96a66cSDavid du Colombier 	Nl	= 256,			/* max. command line length */
75e96a66cSDavid du Colombier 	Nq	= 8*1024,		/* amount of I/O buffered */
85e96a66cSDavid du Colombier };
95e96a66cSDavid du Colombier 
105e96a66cSDavid du Colombier typedef struct Q {
11*d7aba6c3SDavid du Colombier 	QLock	lock;
12*d7aba6c3SDavid du Colombier 	Rendez	full;
13*d7aba6c3SDavid du Colombier 	Rendez	empty;
145e96a66cSDavid du Colombier 
155e96a66cSDavid du Colombier 	char	q[Nq];
165e96a66cSDavid du Colombier 	int	n;
175e96a66cSDavid du Colombier 	int	r;
185e96a66cSDavid du Colombier 	int	w;
195e96a66cSDavid du Colombier } Q;
205e96a66cSDavid du Colombier 
215e96a66cSDavid du Colombier typedef struct Cons {
22*d7aba6c3SDavid du Colombier 	QLock	lock;
235e96a66cSDavid du Colombier 	int	ref;
245e96a66cSDavid du Colombier 	int	closed;
255e96a66cSDavid du Colombier 	int	fd;
265e96a66cSDavid du Colombier 	int	srvfd;
275e96a66cSDavid du Colombier 	int	ctlfd;
285e96a66cSDavid du Colombier 	Q*	iq;		/* points to console.iq */
295e96a66cSDavid du Colombier 	Q*	oq;		/* points to console.oq */
305e96a66cSDavid du Colombier } Cons;
315e96a66cSDavid du Colombier 
32b8a11165SDavid du Colombier char *currfsysname;
33b8a11165SDavid du Colombier 
345e96a66cSDavid du Colombier static struct {
355e96a66cSDavid du Colombier 	Q*	iq;		/* input */
365e96a66cSDavid du Colombier 	Q*	oq;		/* output */
375e96a66cSDavid du Colombier 	char	l[Nl];		/* command line assembly */
385e96a66cSDavid du Colombier 	int	nl;		/* current line length */
39dc5a79c1SDavid du Colombier 	int	nopens;
405e96a66cSDavid du Colombier 
415e96a66cSDavid du Colombier 	char*	prompt;
425e96a66cSDavid du Colombier 	int	np;
435e96a66cSDavid du Colombier } console;
445e96a66cSDavid du Colombier 
455e96a66cSDavid du Colombier static void
consClose(Cons * cons)465e96a66cSDavid du Colombier consClose(Cons* cons)
475e96a66cSDavid du Colombier {
48*d7aba6c3SDavid du Colombier 	qlock(&cons->lock);
495e96a66cSDavid du Colombier 	cons->closed = 1;
505e96a66cSDavid du Colombier 
515e96a66cSDavid du Colombier 	cons->ref--;
525e96a66cSDavid du Colombier 	if(cons->ref > 0){
53*d7aba6c3SDavid du Colombier 		qlock(&cons->iq->lock);
54*d7aba6c3SDavid du Colombier 		rwakeup(&cons->iq->full);
55*d7aba6c3SDavid du Colombier 		qunlock(&cons->iq->lock);
56*d7aba6c3SDavid du Colombier 		qlock(&cons->oq->lock);
57*d7aba6c3SDavid du Colombier 		rwakeup(&cons->oq->empty);
58*d7aba6c3SDavid du Colombier 		qunlock(&cons->oq->lock);
59*d7aba6c3SDavid du Colombier 		qunlock(&cons->lock);
605e96a66cSDavid du Colombier 		return;
615e96a66cSDavid du Colombier 	}
625e96a66cSDavid du Colombier 
635e96a66cSDavid du Colombier 	if(cons->ctlfd != -1){
645e96a66cSDavid du Colombier 		close(cons->ctlfd);
655e96a66cSDavid du Colombier 		cons->srvfd = -1;
665e96a66cSDavid du Colombier 	}
675e96a66cSDavid du Colombier 	if(cons->srvfd != -1){
685e96a66cSDavid du Colombier 		close(cons->srvfd);
695e96a66cSDavid du Colombier 		cons->srvfd = -1;
705e96a66cSDavid du Colombier 	}
715e96a66cSDavid du Colombier 	if(cons->fd != -1){
725e96a66cSDavid du Colombier 		close(cons->fd);
735e96a66cSDavid du Colombier 		cons->fd = -1;
745e96a66cSDavid du Colombier 	}
75*d7aba6c3SDavid du Colombier 	qunlock(&cons->lock);
76*d7aba6c3SDavid du Colombier 	vtfree(cons);
77dc5a79c1SDavid du Colombier 	console.nopens--;
785e96a66cSDavid du Colombier }
795e96a66cSDavid du Colombier 
805e96a66cSDavid du Colombier static void
consIProc(void * v)815e96a66cSDavid du Colombier consIProc(void* v)
825e96a66cSDavid du Colombier {
835e96a66cSDavid du Colombier 	Q *q;
845e96a66cSDavid du Colombier 	Cons *cons;
855e96a66cSDavid du Colombier 	int n, w;
865e96a66cSDavid du Colombier 	char buf[Nq/4];
875e96a66cSDavid du Colombier 
88*d7aba6c3SDavid du Colombier 	threadsetname("consI");
895e96a66cSDavid du Colombier 
905e96a66cSDavid du Colombier 	cons = v;
915e96a66cSDavid du Colombier 	q = cons->iq;
925e96a66cSDavid du Colombier 	for(;;){
935e96a66cSDavid du Colombier 		/*
945e96a66cSDavid du Colombier 		 * Can't tell the difference between zero-length read
955e96a66cSDavid du Colombier 		 * and eof, so keep calling read until we get an error.
965e96a66cSDavid du Colombier 		 */
975e96a66cSDavid du Colombier 		if(cons->closed || (n = read(cons->fd, buf, Nq/4)) < 0)
985e96a66cSDavid du Colombier 			break;
99*d7aba6c3SDavid du Colombier 		qlock(&q->lock);
1005e96a66cSDavid du Colombier 		while(Nq - q->n < n && !cons->closed)
101*d7aba6c3SDavid du Colombier 			rsleep(&q->full);
1025e96a66cSDavid du Colombier 		w = Nq - q->w;
1035e96a66cSDavid du Colombier 		if(w < n){
1045e96a66cSDavid du Colombier 			memmove(&q->q[q->w], buf, w);
1055e96a66cSDavid du Colombier 			memmove(&q->q[0], buf + w, n - w);
1065e96a66cSDavid du Colombier 		}
1075e96a66cSDavid du Colombier 		else
1085e96a66cSDavid du Colombier 			memmove(&q->q[q->w], buf, n);
1095e96a66cSDavid du Colombier 		q->w = (q->w + n) % Nq;
1105e96a66cSDavid du Colombier 		q->n += n;
111*d7aba6c3SDavid du Colombier 		rwakeup(&q->empty);
112*d7aba6c3SDavid du Colombier 		qunlock(&q->lock);
1135e96a66cSDavid du Colombier 	}
1145e96a66cSDavid du Colombier 	consClose(cons);
1155e96a66cSDavid du Colombier }
1165e96a66cSDavid du Colombier 
1175e96a66cSDavid du Colombier static void
consOProc(void * v)1185e96a66cSDavid du Colombier consOProc(void* v)
1195e96a66cSDavid du Colombier {
1205e96a66cSDavid du Colombier 	Q *q;
1215e96a66cSDavid du Colombier 	Cons *cons;
1225e96a66cSDavid du Colombier 	char buf[Nq];
1235e96a66cSDavid du Colombier 	int lastn, n, r;
1245e96a66cSDavid du Colombier 
125*d7aba6c3SDavid du Colombier 	threadsetname("consO");
1265e96a66cSDavid du Colombier 
1275e96a66cSDavid du Colombier 	cons = v;
1285e96a66cSDavid du Colombier 	q = cons->oq;
129*d7aba6c3SDavid du Colombier 	qlock(&q->lock);
1305e96a66cSDavid du Colombier 	lastn = 0;
1315e96a66cSDavid du Colombier 	for(;;){
1325e96a66cSDavid du Colombier 		while(lastn == q->n && !cons->closed)
133*d7aba6c3SDavid du Colombier 			rsleep(&q->empty);
1345e96a66cSDavid du Colombier 		if((n = q->n - lastn) > Nq)
1355e96a66cSDavid du Colombier 			n = Nq;
1365e96a66cSDavid du Colombier 		if(n > q->w){
1375e96a66cSDavid du Colombier 			r = n - q->w;
1385e96a66cSDavid du Colombier 			memmove(buf, &q->q[Nq - r], r);
1395e96a66cSDavid du Colombier 			memmove(buf+r, &q->q[0], n - r);
1405e96a66cSDavid du Colombier 		}
1415e96a66cSDavid du Colombier 		else
1425e96a66cSDavid du Colombier 			memmove(buf, &q->q[q->w - n], n);
1435e96a66cSDavid du Colombier 		lastn = q->n;
144*d7aba6c3SDavid du Colombier 		qunlock(&q->lock);
1455e96a66cSDavid du Colombier 		if(cons->closed || write(cons->fd, buf, n) < 0)
1465e96a66cSDavid du Colombier 			break;
147*d7aba6c3SDavid du Colombier 		qlock(&q->lock);
148*d7aba6c3SDavid du Colombier 		rwakeup(&q->empty);
1495e96a66cSDavid du Colombier 	}
1505e96a66cSDavid du Colombier 	consClose(cons);
1515e96a66cSDavid du Colombier }
1525e96a66cSDavid du Colombier 
1535e96a66cSDavid du Colombier int
consOpen(int fd,int srvfd,int ctlfd)1545e96a66cSDavid du Colombier consOpen(int fd, int srvfd, int ctlfd)
1555e96a66cSDavid du Colombier {
1565e96a66cSDavid du Colombier 	Cons *cons;
1575e96a66cSDavid du Colombier 
158*d7aba6c3SDavid du Colombier 	cons = vtmallocz(sizeof(Cons));
1595e96a66cSDavid du Colombier 	cons->fd = fd;
1605e96a66cSDavid du Colombier 	cons->srvfd = srvfd;
1615e96a66cSDavid du Colombier 	cons->ctlfd = ctlfd;
1625e96a66cSDavid du Colombier 	cons->iq = console.iq;
1635e96a66cSDavid du Colombier 	cons->oq = console.oq;
164dc5a79c1SDavid du Colombier 	console.nopens++;
1655e96a66cSDavid du Colombier 
166*d7aba6c3SDavid du Colombier 	qlock(&cons->lock);
1675e96a66cSDavid du Colombier 	cons->ref = 2;
1685e96a66cSDavid du Colombier 	cons->closed = 0;
169*d7aba6c3SDavid du Colombier 	if(proccreate(consOProc, cons, STACK) < 0){
1705e96a66cSDavid du Colombier 		cons->ref--;
171*d7aba6c3SDavid du Colombier 		qunlock(&cons->lock);
1725e96a66cSDavid du Colombier 		consClose(cons);
1735e96a66cSDavid du Colombier 		return 0;
1745e96a66cSDavid du Colombier 	}
175*d7aba6c3SDavid du Colombier 	qunlock(&cons->lock);
1765e96a66cSDavid du Colombier 
1775e96a66cSDavid du Colombier 	if(ctlfd >= 0)
1785e96a66cSDavid du Colombier 		consIProc(cons);
179*d7aba6c3SDavid du Colombier 	else if(proccreate(consIProc, cons, STACK) < 0){
1805e96a66cSDavid du Colombier 		consClose(cons);
1815e96a66cSDavid du Colombier 		return 0;
1825e96a66cSDavid du Colombier 	}
1835e96a66cSDavid du Colombier 
1845e96a66cSDavid du Colombier 	return 1;
1855e96a66cSDavid du Colombier }
1865e96a66cSDavid du Colombier 
1875e96a66cSDavid du Colombier static int
qWrite(Q * q,char * p,int n)1885e96a66cSDavid du Colombier qWrite(Q* q, char* p, int n)
1895e96a66cSDavid du Colombier {
1905e96a66cSDavid du Colombier 	int w;
1915e96a66cSDavid du Colombier 
192*d7aba6c3SDavid du Colombier 	qlock(&q->lock);
1935e96a66cSDavid du Colombier 	if(n > Nq - q->w){
1945e96a66cSDavid du Colombier 		w = Nq - q->w;
1955e96a66cSDavid du Colombier 		memmove(&q->q[q->w], p, w);
1965e96a66cSDavid du Colombier 		memmove(&q->q[0], p + w, n - w);
1975e96a66cSDavid du Colombier 		q->w = n - w;
1985e96a66cSDavid du Colombier 	}
1995e96a66cSDavid du Colombier 	else{
2005e96a66cSDavid du Colombier 		memmove(&q->q[q->w], p, n);
2015e96a66cSDavid du Colombier 		q->w += n;
2025e96a66cSDavid du Colombier 	}
2035e96a66cSDavid du Colombier 	q->n += n;
204*d7aba6c3SDavid du Colombier 	rwakeup(&q->empty);
205*d7aba6c3SDavid du Colombier 	qunlock(&q->lock);
2065e96a66cSDavid du Colombier 
2075e96a66cSDavid du Colombier 	return n;
2085e96a66cSDavid du Colombier }
2095e96a66cSDavid du Colombier 
2105e96a66cSDavid du Colombier static Q*
qAlloc(void)2115e96a66cSDavid du Colombier qAlloc(void)
2125e96a66cSDavid du Colombier {
2135e96a66cSDavid du Colombier 	Q *q;
2145e96a66cSDavid du Colombier 
215*d7aba6c3SDavid du Colombier 	q = vtmallocz(sizeof(Q));
216*d7aba6c3SDavid du Colombier 	q->full.l = &q->lock;
217*d7aba6c3SDavid du Colombier 	q->empty.l = &q->lock;
2185e96a66cSDavid du Colombier 	q->n = q->r = q->w = 0;
2195e96a66cSDavid du Colombier 
2205e96a66cSDavid du Colombier 	return q;
2215e96a66cSDavid du Colombier }
2225e96a66cSDavid du Colombier 
2235e96a66cSDavid du Colombier static void
consProc(void *)2245e96a66cSDavid du Colombier consProc(void*)
2255e96a66cSDavid du Colombier {
2265e96a66cSDavid du Colombier 	Q *q;
2275e96a66cSDavid du Colombier 	int argc, i, n, r;
2285e96a66cSDavid du Colombier 	char *argv[20], buf[Nq], *lp, *wbuf;
229b8a11165SDavid du Colombier 	char procname[64];
2305e96a66cSDavid du Colombier 
231b8a11165SDavid du Colombier 	snprint(procname, sizeof procname, "cons %s", currfsysname);
232*d7aba6c3SDavid du Colombier 	threadsetname(procname);
2335e96a66cSDavid du Colombier 
2345e96a66cSDavid du Colombier 	q = console.iq;
2355e96a66cSDavid du Colombier 	qWrite(console.oq, console.prompt, console.np);
236*d7aba6c3SDavid du Colombier 	qlock(&q->lock);
2375e96a66cSDavid du Colombier 	for(;;){
2385e96a66cSDavid du Colombier 		while((n = q->n) == 0)
239*d7aba6c3SDavid du Colombier 			rsleep(&q->empty);
2405e96a66cSDavid du Colombier 		r = Nq - q->r;
2415e96a66cSDavid du Colombier 		if(r < n){
2425e96a66cSDavid du Colombier 			memmove(buf, &q->q[q->r], r);
2435e96a66cSDavid du Colombier 			memmove(buf + r, &q->q[0], n - r);
2445e96a66cSDavid du Colombier 		}
2455e96a66cSDavid du Colombier 		else
2465e96a66cSDavid du Colombier 			memmove(buf, &q->q[q->r], n);
2475e96a66cSDavid du Colombier 		q->r = (q->r + n) % Nq;
2485e96a66cSDavid du Colombier 		q->n -= n;
249*d7aba6c3SDavid du Colombier 		rwakeup(&q->full);
250*d7aba6c3SDavid du Colombier 		qunlock(&q->lock);
2515e96a66cSDavid du Colombier 
2525e96a66cSDavid du Colombier 		for(i = 0; i < n; i++){
2535e96a66cSDavid du Colombier 			switch(buf[i]){
2545e96a66cSDavid du Colombier 			case '\004':				/* ^D */
2555e96a66cSDavid du Colombier 				if(console.nl == 0){
2565e96a66cSDavid du Colombier 					qWrite(console.oq, "\n", 1);
2575e96a66cSDavid du Colombier 					break;
2585e96a66cSDavid du Colombier 				}
2595e96a66cSDavid du Colombier 				/*FALLTHROUGH*/
2605e96a66cSDavid du Colombier 			default:
2615e96a66cSDavid du Colombier 				if(console.nl < Nl-1){
2625e96a66cSDavid du Colombier 					qWrite(console.oq, &buf[i], 1);
2635e96a66cSDavid du Colombier 					console.l[console.nl++] = buf[i];
2645e96a66cSDavid du Colombier 				}
2655e96a66cSDavid du Colombier 				continue;
2665e96a66cSDavid du Colombier 			case '\b':
2675e96a66cSDavid du Colombier 				if(console.nl != 0){
2685e96a66cSDavid du Colombier 					qWrite(console.oq, &buf[i], 1);
2695e96a66cSDavid du Colombier 					console.nl--;
2705e96a66cSDavid du Colombier 				}
2715e96a66cSDavid du Colombier 				continue;
2725e96a66cSDavid du Colombier 			case '\n':
2735e96a66cSDavid du Colombier 				qWrite(console.oq, &buf[i], 1);
2745e96a66cSDavid du Colombier 				break;
2755e96a66cSDavid du Colombier 			case '\025':				/* ^U */
2765e96a66cSDavid du Colombier 				qWrite(console.oq, "^U\n", 3);
2775e96a66cSDavid du Colombier 				console.nl = 0;
2785e96a66cSDavid du Colombier 				break;
2795e96a66cSDavid du Colombier 			case '\027':				/* ^W */
2805e96a66cSDavid du Colombier 				console.l[console.nl] = '\0';
281*d7aba6c3SDavid du Colombier 				wbuf = vtmalloc(console.nl+1);
2825e96a66cSDavid du Colombier 				memmove(wbuf, console.l, console.nl+1);
2835e96a66cSDavid du Colombier 				argc = tokenize(wbuf, argv, nelem(argv));
2845e96a66cSDavid du Colombier 				if(argc > 0)
2855e96a66cSDavid du Colombier 					argc--;
2865e96a66cSDavid du Colombier 				console.nl = 0;
2875e96a66cSDavid du Colombier 				lp = console.l;
2885e96a66cSDavid du Colombier 				for(i = 0; i < argc; i++)
2895e96a66cSDavid du Colombier 					lp += sprint(lp, "%q ", argv[i]);
2905e96a66cSDavid du Colombier 				console.nl = lp - console.l;
291*d7aba6c3SDavid du Colombier 				vtfree(wbuf);
2925e96a66cSDavid du Colombier 				qWrite(console.oq, "^W\n", 3);
2935e96a66cSDavid du Colombier 				if(console.nl == 0)
2945e96a66cSDavid du Colombier 					break;
2955e96a66cSDavid du Colombier 				qWrite(console.oq, console.l, console.nl);
2965e96a66cSDavid du Colombier 				continue;
2975e96a66cSDavid du Colombier 			case '\177':
2985e96a66cSDavid du Colombier 				qWrite(console.oq, "\n", 1);
2995e96a66cSDavid du Colombier 				console.nl = 0;
3005e96a66cSDavid du Colombier 				break;
3015e96a66cSDavid du Colombier 			}
3025e96a66cSDavid du Colombier 
3035e96a66cSDavid du Colombier 			console.l[console.nl] = '\0';
3045e96a66cSDavid du Colombier 			if(console.nl != 0)
3055e96a66cSDavid du Colombier 				cliExec(console.l);
3065e96a66cSDavid du Colombier 
3075e96a66cSDavid du Colombier 			console.nl = 0;
3085e96a66cSDavid du Colombier 			qWrite(console.oq, console.prompt, console.np);
3095e96a66cSDavid du Colombier 		}
3105e96a66cSDavid du Colombier 
311*d7aba6c3SDavid du Colombier 		qlock(&q->lock);
3125e96a66cSDavid du Colombier 	}
3135e96a66cSDavid du Colombier }
3145e96a66cSDavid du Colombier 
3155e96a66cSDavid du Colombier int
consWrite(char * buf,int len)3165e96a66cSDavid du Colombier consWrite(char* buf, int len)
3175e96a66cSDavid du Colombier {
3185e96a66cSDavid du Colombier 	if(console.oq == nil)
319dc5a79c1SDavid du Colombier 		return write(2, buf, len);
320dc5a79c1SDavid du Colombier 	if(console.nopens == 0)
321dc5a79c1SDavid du Colombier 		write(2, buf, len);
3225e96a66cSDavid du Colombier 	return qWrite(console.oq, buf, len);
3235e96a66cSDavid du Colombier }
3245e96a66cSDavid du Colombier 
3255e96a66cSDavid du Colombier int
consPrompt(char * prompt)3265e96a66cSDavid du Colombier consPrompt(char* prompt)
3275e96a66cSDavid du Colombier {
3285e96a66cSDavid du Colombier 	char buf[ERRMAX];
3295e96a66cSDavid du Colombier 
3305e96a66cSDavid du Colombier 	if(prompt == nil)
3315e96a66cSDavid du Colombier 		prompt = "prompt";
3325e96a66cSDavid du Colombier 
333*d7aba6c3SDavid du Colombier 	vtfree(console.prompt);
3345e96a66cSDavid du Colombier 	console.np = snprint(buf, sizeof(buf), "%s: ", prompt);
335*d7aba6c3SDavid du Colombier 	console.prompt = vtstrdup(buf);
3365e96a66cSDavid du Colombier 
3375e96a66cSDavid du Colombier 	return console.np;
3385e96a66cSDavid du Colombier }
3395e96a66cSDavid du Colombier 
3405e96a66cSDavid du Colombier int
consTTY(void)3415e96a66cSDavid du Colombier consTTY(void)
3425e96a66cSDavid du Colombier {
3435e96a66cSDavid du Colombier 	int ctl, fd;
3445e96a66cSDavid du Colombier 	char *name, *p;
3455e96a66cSDavid du Colombier 
3465e96a66cSDavid du Colombier 	name = "/dev/cons";
3475e96a66cSDavid du Colombier 	if((fd = open(name, ORDWR)) < 0){
3485e96a66cSDavid du Colombier 		name = "#c/cons";
3495e96a66cSDavid du Colombier 		if((fd = open(name, ORDWR)) < 0){
350*d7aba6c3SDavid du Colombier 			werrstr("consTTY: open %s: %r", name);
3515e96a66cSDavid du Colombier 			return 0;
3525e96a66cSDavid du Colombier 		}
3535e96a66cSDavid du Colombier 	}
3545e96a66cSDavid du Colombier 
3555e96a66cSDavid du Colombier 	p = smprint("%sctl", name);
3565e96a66cSDavid du Colombier 	if((ctl = open(p, OWRITE)) < 0){
3575e96a66cSDavid du Colombier 		close(fd);
358*d7aba6c3SDavid du Colombier 		werrstr("consTTY: open %s: %r", p);
3595e96a66cSDavid du Colombier 		free(p);
3605e96a66cSDavid du Colombier 		return 0;
3615e96a66cSDavid du Colombier 	}
3625e96a66cSDavid du Colombier 	if(write(ctl, "rawon", 5) < 0){
3635e96a66cSDavid du Colombier 		close(ctl);
3645e96a66cSDavid du Colombier 		close(fd);
365*d7aba6c3SDavid du Colombier 		werrstr("consTTY: write %s: %r", p);
3665e96a66cSDavid du Colombier 		free(p);
3675e96a66cSDavid du Colombier 		return 0;
3685e96a66cSDavid du Colombier 	}
3695e96a66cSDavid du Colombier 	free(p);
3705e96a66cSDavid du Colombier 
3715e96a66cSDavid du Colombier 	if(consOpen(fd, fd, ctl) == 0){
3725e96a66cSDavid du Colombier 		close(ctl);
3735e96a66cSDavid du Colombier 		close(fd);
3745e96a66cSDavid du Colombier 		return 0;
3755e96a66cSDavid du Colombier 	}
3765e96a66cSDavid du Colombier 
3775e96a66cSDavid du Colombier 	return 1;
3785e96a66cSDavid du Colombier }
3795e96a66cSDavid du Colombier 
3805e96a66cSDavid du Colombier int
consInit(void)3815e96a66cSDavid du Colombier consInit(void)
3825e96a66cSDavid du Colombier {
3835e96a66cSDavid du Colombier 	console.iq = qAlloc();
3845e96a66cSDavid du Colombier 	console.oq = qAlloc();
3855e96a66cSDavid du Colombier 	console.nl = 0;
3865e96a66cSDavid du Colombier 
3875e96a66cSDavid du Colombier 	consPrompt(nil);
3885e96a66cSDavid du Colombier 
389*d7aba6c3SDavid du Colombier 	if(proccreate(consProc, nil, STACK) < 0){
390*d7aba6c3SDavid du Colombier 		sysfatal("can't start console proc");
3915e96a66cSDavid du Colombier 		return 0;
3925e96a66cSDavid du Colombier 	}
3935e96a66cSDavid du Colombier 
3945e96a66cSDavid du Colombier 	return 1;
3955e96a66cSDavid du Colombier }
396