xref: /csrg-svn/sys/kern/subr_log.c (revision 16723)
1*16723Sralph /*	subr_log.c	6.1	84/07/16	*/
2*16723Sralph 
3*16723Sralph /*
4*16723Sralph  * Error log buffer for kernel printf's.
5*16723Sralph  */
6*16723Sralph 
7*16723Sralph #include "../h/param.h"
8*16723Sralph #include "../h/dir.h"
9*16723Sralph #include "../h/user.h"
10*16723Sralph #include "../h/proc.h"
11*16723Sralph #include "../h/ioctl.h"
12*16723Sralph #include "../h/msgbuf.h"
13*16723Sralph #include "../h/file.h"
14*16723Sralph #include "../h/errno.h"
15*16723Sralph 
16*16723Sralph #define LOG_RDPRI	(PZERO + 1)
17*16723Sralph 
18*16723Sralph #define LOG_OPEN	0x01
19*16723Sralph #define LOG_NBIO	0x02
20*16723Sralph #define LOG_ASYNC	0x04
21*16723Sralph #define LOG_RDWAIT	0x08
22*16723Sralph 
23*16723Sralph struct logsoftc {
24*16723Sralph 	int	sc_state;		/* see above for possibilities */
25*16723Sralph 	struct	proc *sc_selp;		/* process waiting on select call */
26*16723Sralph 	int	sc_pgrp;		/* process group for async I/O */
27*16723Sralph } logsoftc;
28*16723Sralph 
29*16723Sralph logopen(dev)
30*16723Sralph 	dev_t dev;
31*16723Sralph {
32*16723Sralph 
33*16723Sralph #ifdef LOGDEBUG
34*16723Sralph 	printf("logopen: dev=0x%x\n", dev);
35*16723Sralph #endif
36*16723Sralph 	if (logsoftc.sc_state & LOG_OPEN)
37*16723Sralph 		return(EBUSY);
38*16723Sralph 	logsoftc.sc_state |= LOG_OPEN;
39*16723Sralph 	logsoftc.sc_selp = 0;
40*16723Sralph 	logsoftc.sc_pgrp = u.u_procp->p_pgrp;
41*16723Sralph 	/*
42*16723Sralph 	 * Potential race here with putchar() but since putchar should be
43*16723Sralph 	 * called by autoconf, msg_magic should be initialized by the time
44*16723Sralph 	 * we get here.
45*16723Sralph 	 */
46*16723Sralph 	if (msgbuf.msg_magic != MSG_MAGIC) {
47*16723Sralph 		register int i;
48*16723Sralph 
49*16723Sralph 		msgbuf.msg_magic = MSG_MAGIC;
50*16723Sralph 		msgbuf.msg_bufx = msgbuf.msg_bufr = 0;
51*16723Sralph 		for (i=0; i < MSG_BSIZE; i++)
52*16723Sralph 			msgbuf.msg_bufc[i] = 0;
53*16723Sralph 	}
54*16723Sralph 	return(0);
55*16723Sralph }
56*16723Sralph 
57*16723Sralph logclose(dev, flag)
58*16723Sralph 	dev_t dev;
59*16723Sralph {
60*16723Sralph 	logsoftc.sc_state = 0;
61*16723Sralph 	logsoftc.sc_selp = 0;
62*16723Sralph 	logsoftc.sc_pgrp = 0;
63*16723Sralph #ifdef LOGDEBUG
64*16723Sralph 	printf("logclose: dev=0x%x\n", dev);
65*16723Sralph #endif
66*16723Sralph }
67*16723Sralph 
68*16723Sralph logread(dev, uio)
69*16723Sralph 	dev_t dev;
70*16723Sralph 	struct uio *uio;
71*16723Sralph {
72*16723Sralph 	register long l;
73*16723Sralph 	register u_int c;
74*16723Sralph 	register struct iovec *iov;
75*16723Sralph 	register int s;
76*16723Sralph 	int error = 0;
77*16723Sralph 
78*16723Sralph #ifdef LOGDEBUG
79*16723Sralph 	printf("logread: dev=0x%x\n", dev);
80*16723Sralph #endif
81*16723Sralph 
82*16723Sralph 	s = splhigh();
83*16723Sralph 	while (msgbuf.msg_bufr == msgbuf.msg_bufx) {
84*16723Sralph 		if (logsoftc.sc_state & LOG_NBIO) {
85*16723Sralph 			splx(s);
86*16723Sralph 			return(EWOULDBLOCK);
87*16723Sralph 		}
88*16723Sralph 		logsoftc.sc_state |= LOG_RDWAIT;
89*16723Sralph 		sleep((caddr_t)&msgbuf, LOG_RDPRI);
90*16723Sralph 	}
91*16723Sralph 	splx(s);
92*16723Sralph 	logsoftc.sc_state &= ~LOG_RDWAIT;
93*16723Sralph 
94*16723Sralph 	while (uio->uio_resid > 0) {
95*16723Sralph 		l = msgbuf.msg_bufx - msgbuf.msg_bufr;
96*16723Sralph 		if (l < 0)
97*16723Sralph 			l = MSG_BSIZE - msgbuf.msg_bufr;
98*16723Sralph 		c = min((u_int) l, (u_int)uio->uio_resid);
99*16723Sralph 		error = uiomove((caddr_t)&msgbuf.msg_bufc[msgbuf.msg_bufr],
100*16723Sralph 			(int)c, UIO_READ, uio);
101*16723Sralph 		if (error)
102*16723Sralph 			break;
103*16723Sralph 		msgbuf.msg_bufr += c;
104*16723Sralph 		if (msgbuf.msg_bufr < 0 || msgbuf.msg_bufr >= MSG_BSIZE)
105*16723Sralph 			msgbuf.msg_bufr = 0;
106*16723Sralph 	}
107*16723Sralph 	return(error);
108*16723Sralph }
109*16723Sralph 
110*16723Sralph logselect(dev, rw)
111*16723Sralph 	dev_t dev;
112*16723Sralph 	int rw;
113*16723Sralph {
114*16723Sralph 	int s = splhigh();
115*16723Sralph 
116*16723Sralph 	switch (rw) {
117*16723Sralph 
118*16723Sralph 	case FREAD:
119*16723Sralph 		if (msgbuf.msg_bufr != msgbuf.msg_bufx)
120*16723Sralph 			goto win;
121*16723Sralph #ifdef LOGDEBUG
122*16723Sralph 		if (logsoftc.sc_selp)
123*16723Sralph 			printf("logselect: collision\n");
124*16723Sralph #endif
125*16723Sralph 		logsoftc.sc_selp = u.u_procp;
126*16723Sralph 		break;
127*16723Sralph 
128*16723Sralph 	case FWRITE:
129*16723Sralph #ifdef LOGDEBUG
130*16723Sralph 		printf("logselect: FWRITE\n");
131*16723Sralph #endif
132*16723Sralph 		break;
133*16723Sralph 	}
134*16723Sralph 	splx(s);
135*16723Sralph 	return(0);
136*16723Sralph win:
137*16723Sralph 	splx(s);
138*16723Sralph 	return(1);
139*16723Sralph }
140*16723Sralph 
141*16723Sralph logwakeup()
142*16723Sralph {
143*16723Sralph 
144*16723Sralph 	if (logsoftc.sc_selp) {
145*16723Sralph 		selwakeup(logsoftc.sc_selp, 0);
146*16723Sralph 		logsoftc.sc_selp = 0;
147*16723Sralph 	}
148*16723Sralph 	if (logsoftc.sc_state & LOG_ASYNC)
149*16723Sralph 		gsignal(logsoftc.sc_pgrp, SIGIO);
150*16723Sralph 	if (logsoftc.sc_state & LOG_RDWAIT) {
151*16723Sralph 		wakeup((caddr_t)&msgbuf);
152*16723Sralph 		logsoftc.sc_state &= ~LOG_RDWAIT;
153*16723Sralph 	}
154*16723Sralph }
155*16723Sralph 
156*16723Sralph /*ARGSUSED*/
157*16723Sralph logioctl(com, data, flag)
158*16723Sralph 	caddr_t data;
159*16723Sralph {
160*16723Sralph 	long l;
161*16723Sralph 	int s;
162*16723Sralph 
163*16723Sralph 	switch (com) {
164*16723Sralph 
165*16723Sralph 	/* return number of characters immediately available */
166*16723Sralph 	case FIONREAD:
167*16723Sralph 		s = splhigh();
168*16723Sralph 		l = msgbuf.msg_bufx - msgbuf.msg_bufr;
169*16723Sralph 		splx(s);
170*16723Sralph 		if (l < 0)
171*16723Sralph 			l += MSG_BSIZE;
172*16723Sralph 		*(off_t *)data = l;
173*16723Sralph 		break;
174*16723Sralph 
175*16723Sralph 	case FIONBIO:
176*16723Sralph 		if (*(int *)data)
177*16723Sralph 			logsoftc.sc_state |= LOG_NBIO;
178*16723Sralph 		else
179*16723Sralph 			logsoftc.sc_state &= ~LOG_NBIO;
180*16723Sralph 		break;
181*16723Sralph 
182*16723Sralph 	case FIOASYNC:
183*16723Sralph 		if (*(int *)data)
184*16723Sralph 			logsoftc.sc_state |= LOG_ASYNC;
185*16723Sralph 		else
186*16723Sralph 			logsoftc.sc_state &= ~LOG_ASYNC;
187*16723Sralph 		break;
188*16723Sralph 
189*16723Sralph 	case TIOCSPGRP:
190*16723Sralph 		logsoftc.sc_pgrp = *(int *)data;
191*16723Sralph 		break;
192*16723Sralph 
193*16723Sralph 	case TIOCGPGRP:
194*16723Sralph 		*(int *)data = logsoftc.sc_pgrp;
195*16723Sralph 		break;
196*16723Sralph 
197*16723Sralph 	default:
198*16723Sralph 		return(-1);
199*16723Sralph 	}
200*16723Sralph 	return(0);
201*16723Sralph }
202