Commit | Line | Data |
---|---|---|
da7c5cc6 | 1 | /* |
0880b18e | 2 | * Copyright (c) 1982, 1986 Regents of the University of California. |
9db58063 | 3 | * All rights reserved. |
da7c5cc6 | 4 | * |
9db58063 KM |
5 | * %sccs.include.redist.c% |
6 | * | |
deb31817 | 7 | * @(#)subr_log.c 7.17 (Berkeley) %G% |
da7c5cc6 | 8 | */ |
c45816fa RC |
9 | |
10 | /* | |
11 | * Error log buffer for kernel printf's. | |
12 | */ | |
13 | ||
94368568 | 14 | #include "param.h" |
deb31817 | 15 | #include "systm.h" |
94368568 | 16 | #include "proc.h" |
0a23a89f | 17 | #include "vnode.h" |
94368568 JB |
18 | #include "ioctl.h" |
19 | #include "msgbuf.h" | |
20 | #include "file.h" | |
c45816fa RC |
21 | |
22 | #define LOG_RDPRI (PZERO + 1) | |
23 | ||
c45816fa RC |
24 | #define LOG_ASYNC 0x04 |
25 | #define LOG_RDWAIT 0x08 | |
26 | ||
27 | struct logsoftc { | |
28 | int sc_state; /* see above for possibilities */ | |
77f9c500 | 29 | struct selinfo sc_selp; /* process waiting on select call */ |
f9b02bae | 30 | int sc_pgid; /* process/group for async I/O */ |
c45816fa RC |
31 | } logsoftc; |
32 | ||
bd10af3f MK |
33 | int log_open; /* also used in log() */ |
34 | ||
0b355a6e | 35 | /*ARGSUSED*/ |
8429d022 | 36 | logopen(dev, flags, mode, p) |
c45816fa | 37 | dev_t dev; |
8429d022 MK |
38 | int flags, mode; |
39 | struct proc *p; | |
c45816fa | 40 | { |
9db58063 | 41 | register struct msgbuf *mbp = msgbufp; |
c45816fa | 42 | |
bd10af3f | 43 | if (log_open) |
18c9b20d | 44 | return (EBUSY); |
bd10af3f | 45 | log_open = 1; |
8429d022 | 46 | logsoftc.sc_pgid = p->p_pid; /* signal process only */ |
c45816fa RC |
47 | /* |
48 | * Potential race here with putchar() but since putchar should be | |
49 | * called by autoconf, msg_magic should be initialized by the time | |
50 | * we get here. | |
51 | */ | |
9db58063 | 52 | if (mbp->msg_magic != MSG_MAGIC) { |
c45816fa RC |
53 | register int i; |
54 | ||
9db58063 KM |
55 | mbp->msg_magic = MSG_MAGIC; |
56 | mbp->msg_bufx = mbp->msg_bufr = 0; | |
c45816fa | 57 | for (i=0; i < MSG_BSIZE; i++) |
9db58063 | 58 | mbp->msg_bufc[i] = 0; |
c45816fa | 59 | } |
18c9b20d | 60 | return (0); |
c45816fa RC |
61 | } |
62 | ||
0b355a6e | 63 | /*ARGSUSED*/ |
1a2bdfeb | 64 | logclose(dev, flag, mode, p) |
c45816fa | 65 | dev_t dev; |
1a2bdfeb CT |
66 | int flag, mode; |
67 | struct proc *p; | |
c45816fa | 68 | { |
77f9c500 | 69 | |
bd10af3f | 70 | log_open = 0; |
c45816fa | 71 | logsoftc.sc_state = 0; |
1a77c6b4 | 72 | return (0); |
c45816fa RC |
73 | } |
74 | ||
0b355a6e | 75 | /*ARGSUSED*/ |
f9b02bae | 76 | logread(dev, uio, flag) |
c45816fa RC |
77 | dev_t dev; |
78 | struct uio *uio; | |
f9b02bae | 79 | int flag; |
c45816fa | 80 | { |
9db58063 | 81 | register struct msgbuf *mbp = msgbufp; |
c45816fa | 82 | register long l; |
c45816fa RC |
83 | register int s; |
84 | int error = 0; | |
85 | ||
c45816fa | 86 | s = splhigh(); |
9db58063 | 87 | while (mbp->msg_bufr == mbp->msg_bufx) { |
f9b02bae | 88 | if (flag & IO_NDELAY) { |
c45816fa | 89 | splx(s); |
18c9b20d | 90 | return (EWOULDBLOCK); |
c45816fa RC |
91 | } |
92 | logsoftc.sc_state |= LOG_RDWAIT; | |
9db58063 | 93 | if (error = tsleep((caddr_t)mbp, LOG_RDPRI | PCATCH, |
86f4eb6e MT |
94 | "klog", 0)) { |
95 | splx(s); | |
96 | return (error); | |
97 | } | |
c45816fa RC |
98 | } |
99 | splx(s); | |
100 | logsoftc.sc_state &= ~LOG_RDWAIT; | |
101 | ||
102 | while (uio->uio_resid > 0) { | |
9db58063 | 103 | l = mbp->msg_bufx - mbp->msg_bufr; |
c45816fa | 104 | if (l < 0) |
9db58063 | 105 | l = MSG_BSIZE - mbp->msg_bufr; |
65ae7af4 | 106 | l = min(l, uio->uio_resid); |
b52a4e53 | 107 | if (l == 0) |
18c9b20d | 108 | break; |
9db58063 | 109 | error = uiomove((caddr_t)&mbp->msg_bufc[mbp->msg_bufr], |
c4ec2128 | 110 | (int)l, uio); |
c45816fa RC |
111 | if (error) |
112 | break; | |
9db58063 KM |
113 | mbp->msg_bufr += l; |
114 | if (mbp->msg_bufr < 0 || mbp->msg_bufr >= MSG_BSIZE) | |
115 | mbp->msg_bufr = 0; | |
c45816fa | 116 | } |
18c9b20d | 117 | return (error); |
c45816fa RC |
118 | } |
119 | ||
0b355a6e | 120 | /*ARGSUSED*/ |
8429d022 | 121 | logselect(dev, rw, p) |
c45816fa RC |
122 | dev_t dev; |
123 | int rw; | |
8429d022 | 124 | struct proc *p; |
c45816fa RC |
125 | { |
126 | int s = splhigh(); | |
127 | ||
128 | switch (rw) { | |
129 | ||
130 | case FREAD: | |
9db58063 | 131 | if (msgbufp->msg_bufr != msgbufp->msg_bufx) { |
b52a4e53 MK |
132 | splx(s); |
133 | return (1); | |
134 | } | |
77f9c500 | 135 | selrecord(p, &logsoftc.sc_selp); |
c45816fa | 136 | break; |
c45816fa RC |
137 | } |
138 | splx(s); | |
18c9b20d | 139 | return (0); |
c45816fa RC |
140 | } |
141 | ||
142 | logwakeup() | |
143 | { | |
f9b02bae | 144 | struct proc *p; |
c45816fa | 145 | |
bd10af3f MK |
146 | if (!log_open) |
147 | return; | |
77f9c500 | 148 | selwakeup(&logsoftc.sc_selp); |
f9b02bae MK |
149 | if (logsoftc.sc_state & LOG_ASYNC) { |
150 | if (logsoftc.sc_pgid < 0) | |
fa1aff05 | 151 | gsignal(-logsoftc.sc_pgid, SIGIO); |
f9b02bae MK |
152 | else if (p = pfind(logsoftc.sc_pgid)) |
153 | psignal(p, SIGIO); | |
154 | } | |
c45816fa | 155 | if (logsoftc.sc_state & LOG_RDWAIT) { |
9db58063 | 156 | wakeup((caddr_t)msgbufp); |
c45816fa RC |
157 | logsoftc.sc_state &= ~LOG_RDWAIT; |
158 | } | |
159 | } | |
160 | ||
161 | /*ARGSUSED*/ | |
1a2bdfeb CT |
162 | logioctl(dev, com, data, flag, p) |
163 | dev_t dev; | |
164 | int com; | |
c45816fa | 165 | caddr_t data; |
1a2bdfeb CT |
166 | int flag; |
167 | struct proc *p; | |
c45816fa RC |
168 | { |
169 | long l; | |
170 | int s; | |
171 | ||
172 | switch (com) { | |
173 | ||
174 | /* return number of characters immediately available */ | |
175 | case FIONREAD: | |
176 | s = splhigh(); | |
9db58063 | 177 | l = msgbufp->msg_bufx - msgbufp->msg_bufr; |
c45816fa RC |
178 | splx(s); |
179 | if (l < 0) | |
180 | l += MSG_BSIZE; | |
a85f307a | 181 | *(int *)data = l; |
c45816fa RC |
182 | break; |
183 | ||
184 | case FIONBIO: | |
c45816fa RC |
185 | break; |
186 | ||
187 | case FIOASYNC: | |
188 | if (*(int *)data) | |
189 | logsoftc.sc_state |= LOG_ASYNC; | |
190 | else | |
191 | logsoftc.sc_state &= ~LOG_ASYNC; | |
192 | break; | |
193 | ||
f9b02bae | 194 | case TIOCSPGRP: |
8fe87cbb | 195 | logsoftc.sc_pgid = *(int *)data; |
c45816fa RC |
196 | break; |
197 | ||
198 | case TIOCGPGRP: | |
f9b02bae | 199 | *(int *)data = logsoftc.sc_pgid; |
c45816fa RC |
200 | break; |
201 | ||
202 | default: | |
18c9b20d | 203 | return (-1); |
c45816fa | 204 | } |
18c9b20d | 205 | return (0); |
c45816fa | 206 | } |