1: /*
2: * Copyright (c) 1982, 1986 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: *
6: * @(#)subr_log.c 7.1 (Berkeley) 6/5/86
7: */
8:
9: /*
10: * Error log buffer for kernel printf's.
11: */
12:
13: #include "param.h"
14: #include "dir.h"
15: #include "user.h"
16: #include "proc.h"
17: #include "ioctl.h"
18: #include "msgbuf.h"
19: #include "file.h"
20: #include "errno.h"
21:
22: #define LOG_RDPRI (PZERO + 1)
23:
24: #define LOG_NBIO 0x02
25: #define LOG_ASYNC 0x04
26: #define LOG_RDWAIT 0x08
27:
28: struct logsoftc {
29: int sc_state; /* see above for possibilities */
30: struct proc *sc_selp; /* process waiting on select call */
31: int sc_pgrp; /* process group for async I/O */
32: } logsoftc;
33:
34: int log_open; /* also used in log() */
35:
36: /*ARGSUSED*/
37: logopen(dev)
38: dev_t dev;
39: {
40:
41: if (log_open)
42: return (EBUSY);
43: log_open = 1;
44: logsoftc.sc_selp = 0;
45: logsoftc.sc_pgrp = u.u_procp->p_pgrp;
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: */
51: if (msgbuf.msg_magic != MSG_MAGIC) {
52: register int i;
53:
54: msgbuf.msg_magic = MSG_MAGIC;
55: msgbuf.msg_bufx = msgbuf.msg_bufr = 0;
56: for (i=0; i < MSG_BSIZE; i++)
57: msgbuf.msg_bufc[i] = 0;
58: }
59: return (0);
60: }
61:
62: /*ARGSUSED*/
63: logclose(dev, flag)
64: dev_t dev;
65: {
66: log_open = 0;
67: logsoftc.sc_state = 0;
68: logsoftc.sc_selp = 0;
69: logsoftc.sc_pgrp = 0;
70: }
71:
72: /*ARGSUSED*/
73: logread(dev, uio)
74: dev_t dev;
75: struct uio *uio;
76: {
77: register long l;
78: register int s;
79: int error = 0;
80:
81: s = splhigh();
82: while (msgbuf.msg_bufr == msgbuf.msg_bufx) {
83: if (logsoftc.sc_state & LOG_NBIO) {
84: splx(s);
85: return (EWOULDBLOCK);
86: }
87: logsoftc.sc_state |= LOG_RDWAIT;
88: sleep((caddr_t)&msgbuf, LOG_RDPRI);
89: }
90: splx(s);
91: logsoftc.sc_state &= ~LOG_RDWAIT;
92:
93: while (uio->uio_resid > 0) {
94: l = msgbuf.msg_bufx - msgbuf.msg_bufr;
95: if (l < 0)
96: l = MSG_BSIZE - msgbuf.msg_bufr;
97: l = MIN(l, uio->uio_resid);
98: if (l == 0)
99: break;
100: error = uiomove((caddr_t)&msgbuf.msg_bufc[msgbuf.msg_bufr],
101: (int)l, UIO_READ, uio);
102: if (error)
103: break;
104: msgbuf.msg_bufr += l;
105: if (msgbuf.msg_bufr < 0 || msgbuf.msg_bufr >= MSG_BSIZE)
106: msgbuf.msg_bufr = 0;
107: }
108: return (error);
109: }
110:
111: /*ARGSUSED*/
112: logselect(dev, rw)
113: dev_t dev;
114: int rw;
115: {
116: int s = splhigh();
117:
118: switch (rw) {
119:
120: case FREAD:
121: if (msgbuf.msg_bufr != msgbuf.msg_bufx) {
122: splx(s);
123: return (1);
124: }
125: logsoftc.sc_selp = u.u_procp;
126: break;
127: }
128: splx(s);
129: return (0);
130: }
131:
132: logwakeup()
133: {
134:
135: if (!log_open)
136: return;
137: if (logsoftc.sc_selp) {
138: selwakeup(logsoftc.sc_selp, 0);
139: logsoftc.sc_selp = 0;
140: }
141: if (logsoftc.sc_state & LOG_ASYNC)
142: gsignal(logsoftc.sc_pgrp, SIGIO);
143: if (logsoftc.sc_state & LOG_RDWAIT) {
144: wakeup((caddr_t)&msgbuf);
145: logsoftc.sc_state &= ~LOG_RDWAIT;
146: }
147: }
148:
149: /*ARGSUSED*/
150: logioctl(com, data, flag)
151: caddr_t data;
152: {
153: long l;
154: int s;
155:
156: switch (com) {
157:
158: /* return number of characters immediately available */
159: case FIONREAD:
160: s = splhigh();
161: l = msgbuf.msg_bufx - msgbuf.msg_bufr;
162: splx(s);
163: if (l < 0)
164: l += MSG_BSIZE;
165: *(off_t *)data = l;
166: break;
167:
168: case FIONBIO:
169: if (*(int *)data)
170: logsoftc.sc_state |= LOG_NBIO;
171: else
172: logsoftc.sc_state &= ~LOG_NBIO;
173: break;
174:
175: case FIOASYNC:
176: if (*(int *)data)
177: logsoftc.sc_state |= LOG_ASYNC;
178: else
179: logsoftc.sc_state &= ~LOG_ASYNC;
180: break;
181:
182: case TIOCSPGRP:
183: logsoftc.sc_pgrp = *(int *)data;
184: break;
185:
186: case TIOCGPGRP:
187: *(int *)data = logsoftc.sc_pgrp;
188: break;
189:
190: default:
191: return (-1);
192: }
193: return (0);
194: }
Defined functions
Defined variables
Defined struct's
Defined macros