|
|
1.1 root 1: /*
2: * Copyright (c) 1982, 1986 Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms, with or without
6: * modification, are permitted provided that the following conditions
7: * are met:
8: * 1. Redistributions of source code must retain the above copyright
9: * notice, this list of conditions and the following disclaimer.
10: * 2. Redistributions in binary form must reproduce the above copyright
11: * notice, this list of conditions and the following disclaimer in the
12: * documentation and/or other materials provided with the distribution.
13: * 3. All advertising materials mentioning features or use of this software
14: * must display the following acknowledgement:
15: * This product includes software developed by the University of
16: * California, Berkeley and its contributors.
17: * 4. Neither the name of the University nor the names of its contributors
18: * may be used to endorse or promote products derived from this software
19: * without specific prior written permission.
20: *
21: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31: * SUCH DAMAGE.
32: *
33: * @(#)subr_log.c 7.11 (Berkeley) 3/17/91
34: */
35:
36: /*
37: * Error log buffer for kernel printf's.
38: */
39:
40: #include "param.h"
41: #include "proc.h"
42: #include "vnode.h"
43: #include "ioctl.h"
44: #include "msgbuf.h"
45: #include "file.h"
46:
47: #define LOG_RDPRI (PZERO + 1)
48:
49: #define LOG_ASYNC 0x04
50: #define LOG_RDWAIT 0x08
51:
52: struct logsoftc {
53: int sc_state; /* see above for possibilities */
54: struct proc *sc_selp; /* process waiting on select call */
55: int sc_pgid; /* process/group for async I/O */
56: } logsoftc;
57:
58: int log_open; /* also used in log() */
59:
60: /*ARGSUSED*/
61: logopen(dev, flags, mode, p)
62: dev_t dev;
63: int flags, mode;
64: struct proc *p;
65: {
66: register struct msgbuf *mbp = msgbufp;
67:
68: if (log_open)
69: return (EBUSY);
70: log_open = 1;
71: logsoftc.sc_pgid = p->p_pid; /* signal process only */
72: /*
73: * Potential race here with putchar() but since putchar should be
74: * called by autoconf, msg_magic should be initialized by the time
75: * we get here.
76: */
77: if (mbp->msg_magic != MSG_MAGIC) {
78: register int i;
79:
80: mbp->msg_magic = MSG_MAGIC;
81: mbp->msg_bufx = mbp->msg_bufr = 0;
82: for (i=0; i < MSG_BSIZE; i++)
83: mbp->msg_bufc[i] = 0;
84: }
85: return (0);
86: }
87:
88: /*ARGSUSED*/
89: logclose(dev, flag)
90: dev_t dev;
91: {
92: log_open = 0;
93: logsoftc.sc_state = 0;
94: logsoftc.sc_selp = 0;
95: }
96:
97: /*ARGSUSED*/
98: logread(dev, uio, flag)
99: dev_t dev;
100: struct uio *uio;
101: int flag;
102: {
103: register struct msgbuf *mbp = msgbufp;
104: register long l;
105: register int s;
106: int error = 0;
107:
108: s = splhigh();
109: while (mbp->msg_bufr == mbp->msg_bufx) {
110: if (flag & IO_NDELAY) {
111: splx(s);
112: return (EWOULDBLOCK);
113: }
114: logsoftc.sc_state |= LOG_RDWAIT;
115: if (error = tsleep((caddr_t)mbp, LOG_RDPRI | PCATCH,
116: "klog", 0)) {
117: splx(s);
118: return (error);
119: }
120: }
121: splx(s);
122: logsoftc.sc_state &= ~LOG_RDWAIT;
123:
124: while (uio->uio_resid > 0) {
125: l = mbp->msg_bufx - mbp->msg_bufr;
126: if (l < 0)
127: l = MSG_BSIZE - mbp->msg_bufr;
128: l = MIN(l, uio->uio_resid);
129: if (l == 0)
130: break;
131: error = uiomove((caddr_t)&mbp->msg_bufc[mbp->msg_bufr],
132: (int)l, uio);
133: if (error)
134: break;
135: mbp->msg_bufr += l;
136: if (mbp->msg_bufr < 0 || mbp->msg_bufr >= MSG_BSIZE)
137: mbp->msg_bufr = 0;
138: }
139: return (error);
140: }
141:
142: /*ARGSUSED*/
143: logselect(dev, rw, p)
144: dev_t dev;
145: int rw;
146: struct proc *p;
147: {
148: int s = splhigh();
149:
150: switch (rw) {
151:
152: case FREAD:
153: if (msgbufp->msg_bufr != msgbufp->msg_bufx) {
154: splx(s);
155: return (1);
156: }
157: logsoftc.sc_selp = p;
158: break;
159: }
160: splx(s);
161: return (0);
162: }
163:
164: logwakeup()
165: {
166: struct proc *p;
167:
168: if (!log_open)
169: return;
170: if (logsoftc.sc_selp) {
171: selwakeup(logsoftc.sc_selp, 0);
172: logsoftc.sc_selp = 0;
173: }
174: if (logsoftc.sc_state & LOG_ASYNC) {
175: if (logsoftc.sc_pgid < 0)
176: gsignal(-logsoftc.sc_pgid, SIGIO);
177: else if (p = pfind(logsoftc.sc_pgid))
178: psignal(p, SIGIO);
179: }
180: if (logsoftc.sc_state & LOG_RDWAIT) {
181: wakeup((caddr_t)msgbufp);
182: logsoftc.sc_state &= ~LOG_RDWAIT;
183: }
184: }
185:
186: /*ARGSUSED*/
187: logioctl(dev, com, data, flag)
188: caddr_t data;
189: {
190: long l;
191: int s;
192:
193: switch (com) {
194:
195: /* return number of characters immediately available */
196: case FIONREAD:
197: s = splhigh();
198: l = msgbufp->msg_bufx - msgbufp->msg_bufr;
199: splx(s);
200: if (l < 0)
201: l += MSG_BSIZE;
202: *(off_t *)data = l;
203: break;
204:
205: case FIONBIO:
206: break;
207:
208: case FIOASYNC:
209: if (*(int *)data)
210: logsoftc.sc_state |= LOG_ASYNC;
211: else
212: logsoftc.sc_state &= ~LOG_ASYNC;
213: break;
214:
215: case TIOCSPGRP:
216: logsoftc.sc_pgid = *(int *)data;
217: break;
218:
219: case TIOCGPGRP:
220: *(int *)data = logsoftc.sc_pgid;
221: break;
222:
223: default:
224: return (-1);
225: }
226: return (0);
227: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.