u. is gone, pcb is at p_addr; aston => signotify
[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 *
8429d022 7 * @(#)subr_log.c 7.11 (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 */
28 struct proc *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*/
c45816fa
RC
63logclose(dev, flag)
64 dev_t dev;
65{
bd10af3f 66 log_open = 0;
c45816fa
RC
67 logsoftc.sc_state = 0;
68 logsoftc.sc_selp = 0;
c45816fa
RC
69}
70
0b355a6e 71/*ARGSUSED*/
f9b02bae 72logread(dev, uio, flag)
c45816fa
RC
73 dev_t dev;
74 struct uio *uio;
f9b02bae 75 int flag;
c45816fa 76{
9db58063 77 register struct msgbuf *mbp = msgbufp;
c45816fa 78 register long l;
c45816fa
RC
79 register int s;
80 int error = 0;
81
c45816fa 82 s = splhigh();
9db58063 83 while (mbp->msg_bufr == mbp->msg_bufx) {
f9b02bae 84 if (flag & IO_NDELAY) {
c45816fa 85 splx(s);
18c9b20d 86 return (EWOULDBLOCK);
c45816fa
RC
87 }
88 logsoftc.sc_state |= LOG_RDWAIT;
9db58063 89 if (error = tsleep((caddr_t)mbp, LOG_RDPRI | PCATCH,
86f4eb6e
MT
90 "klog", 0)) {
91 splx(s);
92 return (error);
93 }
c45816fa
RC
94 }
95 splx(s);
96 logsoftc.sc_state &= ~LOG_RDWAIT;
97
98 while (uio->uio_resid > 0) {
9db58063 99 l = mbp->msg_bufx - mbp->msg_bufr;
c45816fa 100 if (l < 0)
9db58063 101 l = MSG_BSIZE - mbp->msg_bufr;
8011f5df 102 l = MIN(l, uio->uio_resid);
b52a4e53 103 if (l == 0)
18c9b20d 104 break;
9db58063 105 error = uiomove((caddr_t)&mbp->msg_bufc[mbp->msg_bufr],
c4ec2128 106 (int)l, uio);
c45816fa
RC
107 if (error)
108 break;
9db58063
KM
109 mbp->msg_bufr += l;
110 if (mbp->msg_bufr < 0 || mbp->msg_bufr >= MSG_BSIZE)
111 mbp->msg_bufr = 0;
c45816fa 112 }
18c9b20d 113 return (error);
c45816fa
RC
114}
115
0b355a6e 116/*ARGSUSED*/
8429d022 117logselect(dev, rw, p)
c45816fa
RC
118 dev_t dev;
119 int rw;
8429d022 120 struct proc *p;
c45816fa
RC
121{
122 int s = splhigh();
123
124 switch (rw) {
125
126 case FREAD:
9db58063 127 if (msgbufp->msg_bufr != msgbufp->msg_bufx) {
b52a4e53
MK
128 splx(s);
129 return (1);
130 }
8429d022 131 logsoftc.sc_selp = p;
c45816fa 132 break;
c45816fa
RC
133 }
134 splx(s);
18c9b20d 135 return (0);
c45816fa
RC
136}
137
138logwakeup()
139{
f9b02bae 140 struct proc *p;
c45816fa 141
bd10af3f
MK
142 if (!log_open)
143 return;
c45816fa
RC
144 if (logsoftc.sc_selp) {
145 selwakeup(logsoftc.sc_selp, 0);
146 logsoftc.sc_selp = 0;
147 }
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*/
f9b02bae 161logioctl(dev, com, data, flag)
c45816fa
RC
162 caddr_t data;
163{
164 long l;
165 int s;
166
167 switch (com) {
168
169 /* return number of characters immediately available */
170 case FIONREAD:
171 s = splhigh();
9db58063 172 l = msgbufp->msg_bufx - msgbufp->msg_bufr;
c45816fa
RC
173 splx(s);
174 if (l < 0)
175 l += MSG_BSIZE;
176 *(off_t *)data = l;
177 break;
178
179 case FIONBIO:
c45816fa
RC
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
f9b02bae 189 case TIOCSPGRP:
8fe87cbb 190 logsoftc.sc_pgid = *(int *)data;
c45816fa
RC
191 break;
192
193 case TIOCGPGRP:
f9b02bae 194 *(int *)data = logsoftc.sc_pgid;
c45816fa
RC
195 break;
196
197 default:
18c9b20d 198 return (-1);
c45816fa 199 }
18c9b20d 200 return (0);
c45816fa 201}