Commit | Line | Data |
---|---|---|
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 | ||
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 | ||
18c9b20d RC |
29 | #ifdef LOGDEBUG |
30 | /*VARARGS1*/ | |
31 | xprintf(fmt, x1) | |
32 | char *fmt; | |
33 | unsigned x1; | |
34 | { | |
35 | ||
36 | prf(fmt, &x1, 1, (struct tty *)0); | |
37 | } | |
38 | #endif | |
39 | ||
c45816fa RC |
40 | logopen(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 | ||
71 | logclose(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 | ||
82 | logread(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 | ||
130 | logselect(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 |
156 | win: |
157 | splx(s); | |
18c9b20d | 158 | return (1); |
c45816fa RC |
159 | } |
160 | ||
161 | logwakeup() | |
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*/ | |
177 | logioctl(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 | } |