|
|
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.