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