Change to includes. no more ../h
[unix-history] / usr / src / sys / kern / subr_log.c
CommitLineData
94368568 1/* subr_log.c 6.3 84/08/29 */
c45816fa
RC
2
3/*
4 * Error log buffer for kernel printf's.
5 */
6
94368568
JB
7#include "param.h"
8#include "dir.h"
9#include "user.h"
10#include "proc.h"
11#include "ioctl.h"
12#include "msgbuf.h"
13#include "file.h"
14#include "errno.h"
c45816fa
RC
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
23struct 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
18c9b20d
RC
29#ifdef LOGDEBUG
30/*VARARGS1*/
31xprintf(fmt, x1)
32 char *fmt;
33 unsigned x1;
34{
35
36 prf(fmt, &x1, 1, (struct tty *)0);
37}
38#endif
39
c45816fa
RC
40logopen(dev)
41 dev_t dev;
42{
43
44#ifdef LOGDEBUG
18c9b20d 45 xprintf("logopen: dev=0x%x\n", dev);
c45816fa
RC
46#endif
47 if (logsoftc.sc_state & LOG_OPEN)
18c9b20d 48 return (EBUSY);
c45816fa
RC
49 logsoftc.sc_state |= LOG_OPEN;
50 logsoftc.sc_selp = 0;
51 logsoftc.sc_pgrp = u.u_procp->p_pgrp;
52 /*
53 * Potential race here with putchar() but since putchar should be
54 * called by autoconf, msg_magic should be initialized by the time
55 * we get here.
56 */
57 if (msgbuf.msg_magic != MSG_MAGIC) {
58 register int i;
59
60 msgbuf.msg_magic = MSG_MAGIC;
61 msgbuf.msg_bufx = msgbuf.msg_bufr = 0;
62 for (i=0; i < MSG_BSIZE; i++)
63 msgbuf.msg_bufc[i] = 0;
64 }
18c9b20d
RC
65#ifdef LOGDEBUG
66 xprintf("logopen: bufx=%d, bufr=%d\n", msgbuf.msg_bufx, msgbuf.msg_bufr);
67#endif
68 return (0);
c45816fa
RC
69}
70
71logclose(dev, flag)
72 dev_t dev;
73{
74 logsoftc.sc_state = 0;
75 logsoftc.sc_selp = 0;
76 logsoftc.sc_pgrp = 0;
77#ifdef LOGDEBUG
18c9b20d 78 xprintf("logclose: dev=0x%x\n", dev);
c45816fa
RC
79#endif
80}
81
82logread(dev, uio)
83 dev_t dev;
84 struct uio *uio;
85{
86 register long l;
87 register u_int c;
88 register struct iovec *iov;
89 register int s;
90 int error = 0;
91
92#ifdef LOGDEBUG
18c9b20d 93 xprintf("logread: dev=0x%x\n", dev);
c45816fa
RC
94#endif
95
96 s = splhigh();
97 while (msgbuf.msg_bufr == msgbuf.msg_bufx) {
98 if (logsoftc.sc_state & LOG_NBIO) {
99 splx(s);
18c9b20d 100 return (EWOULDBLOCK);
c45816fa
RC
101 }
102 logsoftc.sc_state |= LOG_RDWAIT;
103 sleep((caddr_t)&msgbuf, LOG_RDPRI);
104 }
105 splx(s);
106 logsoftc.sc_state &= ~LOG_RDWAIT;
107
108 while (uio->uio_resid > 0) {
109 l = msgbuf.msg_bufx - msgbuf.msg_bufr;
110 if (l < 0)
111 l = MSG_BSIZE - msgbuf.msg_bufr;
112 c = min((u_int) l, (u_int)uio->uio_resid);
18c9b20d
RC
113#ifdef LOGDEBUG
114 xprintf("logread: bufx=%d, bufr=%d, l=%d, c=%d\n",
115 msgbuf.msg_bufx, msgbuf.msg_bufr, l, c);
116#endif
117 if (c <= 0)
118 break;
c45816fa
RC
119 error = uiomove((caddr_t)&msgbuf.msg_bufc[msgbuf.msg_bufr],
120 (int)c, UIO_READ, uio);
121 if (error)
122 break;
123 msgbuf.msg_bufr += c;
124 if (msgbuf.msg_bufr < 0 || msgbuf.msg_bufr >= MSG_BSIZE)
125 msgbuf.msg_bufr = 0;
126 }
18c9b20d 127 return (error);
c45816fa
RC
128}
129
130logselect(dev, rw)
131 dev_t dev;
132 int rw;
133{
134 int s = splhigh();
135
136 switch (rw) {
137
138 case FREAD:
139 if (msgbuf.msg_bufr != msgbuf.msg_bufx)
140 goto win;
141#ifdef LOGDEBUG
142 if (logsoftc.sc_selp)
18c9b20d 143 xprintf("logselect: collision\n");
c45816fa
RC
144#endif
145 logsoftc.sc_selp = u.u_procp;
146 break;
147
148 case FWRITE:
149#ifdef LOGDEBUG
18c9b20d 150 xprintf("logselect: FWRITE\n");
c45816fa
RC
151#endif
152 break;
153 }
154 splx(s);
18c9b20d 155 return (0);
c45816fa
RC
156win:
157 splx(s);
18c9b20d 158 return (1);
c45816fa
RC
159}
160
161logwakeup()
162{
163
164 if (logsoftc.sc_selp) {
165 selwakeup(logsoftc.sc_selp, 0);
166 logsoftc.sc_selp = 0;
167 }
168 if (logsoftc.sc_state & LOG_ASYNC)
169 gsignal(logsoftc.sc_pgrp, SIGIO);
170 if (logsoftc.sc_state & LOG_RDWAIT) {
171 wakeup((caddr_t)&msgbuf);
172 logsoftc.sc_state &= ~LOG_RDWAIT;
173 }
174}
175
176/*ARGSUSED*/
177logioctl(com, data, flag)
178 caddr_t data;
179{
180 long l;
181 int s;
182
183 switch (com) {
184
185 /* return number of characters immediately available */
186 case FIONREAD:
187 s = splhigh();
188 l = msgbuf.msg_bufx - msgbuf.msg_bufr;
189 splx(s);
190 if (l < 0)
191 l += MSG_BSIZE;
192 *(off_t *)data = l;
193 break;
194
195 case FIONBIO:
196 if (*(int *)data)
197 logsoftc.sc_state |= LOG_NBIO;
198 else
199 logsoftc.sc_state &= ~LOG_NBIO;
200 break;
201
202 case FIOASYNC:
203 if (*(int *)data)
204 logsoftc.sc_state |= LOG_ASYNC;
205 else
206 logsoftc.sc_state &= ~LOG_ASYNC;
207 break;
208
209 case TIOCSPGRP:
210 logsoftc.sc_pgrp = *(int *)data;
211 break;
212
213 case TIOCGPGRP:
214 *(int *)data = logsoftc.sc_pgrp;
215 break;
216
217 default:
18c9b20d 218 return (-1);
c45816fa 219 }
18c9b20d 220 return (0);
c45816fa 221}