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