|
|
1.1 ! root 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.8 (Berkeley) 6/24/90 ! 7: */ ! 8: ! 9: /* ! 10: * Error log buffer for kernel printf's. ! 11: */ ! 12: ! 13: #include "param.h" ! 14: #include "user.h" ! 15: #include "proc.h" ! 16: #include "vnode.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_ASYNC 0x04 ! 25: #define LOG_RDWAIT 0x08 ! 26: ! 27: struct logsoftc { ! 28: int sc_state; /* see above for possibilities */ ! 29: struct proc *sc_selp; /* process waiting on select call */ ! 30: int sc_pgid; /* process/group for async I/O */ ! 31: } logsoftc; ! 32: ! 33: int log_open; /* also used in log() */ ! 34: ! 35: /*ARGSUSED*/ ! 36: logopen(dev) ! 37: dev_t dev; ! 38: { ! 39: ! 40: if (log_open) ! 41: return (EBUSY); ! 42: log_open = 1; ! 43: logsoftc.sc_pgid = u.u_procp->p_pid; /* signal process only */ ! 44: /* ! 45: * Potential race here with putchar() but since putchar should be ! 46: * called by autoconf, msg_magic should be initialized by the time ! 47: * we get here. ! 48: */ ! 49: if (msgbuf.msg_magic != MSG_MAGIC) { ! 50: register int i; ! 51: ! 52: msgbuf.msg_magic = MSG_MAGIC; ! 53: msgbuf.msg_bufx = msgbuf.msg_bufr = 0; ! 54: for (i=0; i < MSG_BSIZE; i++) ! 55: msgbuf.msg_bufc[i] = 0; ! 56: } ! 57: return (0); ! 58: } ! 59: ! 60: /*ARGSUSED*/ ! 61: logclose(dev, flag) ! 62: dev_t dev; ! 63: { ! 64: log_open = 0; ! 65: logsoftc.sc_state = 0; ! 66: logsoftc.sc_selp = 0; ! 67: } ! 68: ! 69: /*ARGSUSED*/ ! 70: logread(dev, uio, flag) ! 71: dev_t dev; ! 72: struct uio *uio; ! 73: int flag; ! 74: { ! 75: register long l; ! 76: register int s; ! 77: int error = 0; ! 78: ! 79: s = splhigh(); ! 80: while (msgbuf.msg_bufr == msgbuf.msg_bufx) { ! 81: if (flag & IO_NDELAY) { ! 82: splx(s); ! 83: return (EWOULDBLOCK); ! 84: } ! 85: logsoftc.sc_state |= LOG_RDWAIT; ! 86: if (error = tsleep((caddr_t)&msgbuf, LOG_RDPRI | PCATCH, ! 87: "klog", 0)) { ! 88: splx(s); ! 89: return (error); ! 90: } ! 91: } ! 92: splx(s); ! 93: logsoftc.sc_state &= ~LOG_RDWAIT; ! 94: ! 95: while (uio->uio_resid > 0) { ! 96: l = msgbuf.msg_bufx - msgbuf.msg_bufr; ! 97: if (l < 0) ! 98: l = MSG_BSIZE - msgbuf.msg_bufr; ! 99: l = MIN(l, uio->uio_resid); ! 100: if (l == 0) ! 101: break; ! 102: error = uiomove((caddr_t)&msgbuf.msg_bufc[msgbuf.msg_bufr], ! 103: (int)l, uio); ! 104: if (error) ! 105: break; ! 106: msgbuf.msg_bufr += l; ! 107: if (msgbuf.msg_bufr < 0 || msgbuf.msg_bufr >= MSG_BSIZE) ! 108: msgbuf.msg_bufr = 0; ! 109: } ! 110: return (error); ! 111: } ! 112: ! 113: /*ARGSUSED*/ ! 114: logselect(dev, rw) ! 115: dev_t dev; ! 116: int rw; ! 117: { ! 118: int s = splhigh(); ! 119: ! 120: switch (rw) { ! 121: ! 122: case FREAD: ! 123: if (msgbuf.msg_bufr != msgbuf.msg_bufx) { ! 124: splx(s); ! 125: return (1); ! 126: } ! 127: logsoftc.sc_selp = u.u_procp; ! 128: break; ! 129: } ! 130: splx(s); ! 131: return (0); ! 132: } ! 133: ! 134: logwakeup() ! 135: { ! 136: struct proc *p; ! 137: ! 138: if (!log_open) ! 139: return; ! 140: if (logsoftc.sc_selp) { ! 141: selwakeup(logsoftc.sc_selp, 0); ! 142: logsoftc.sc_selp = 0; ! 143: } ! 144: if (logsoftc.sc_state & LOG_ASYNC) { ! 145: if (logsoftc.sc_pgid < 0) ! 146: gsignal(logsoftc.sc_pgid, SIGIO); ! 147: else if (p = pfind(logsoftc.sc_pgid)) ! 148: psignal(p, SIGIO); ! 149: } ! 150: if (logsoftc.sc_state & LOG_RDWAIT) { ! 151: wakeup((caddr_t)&msgbuf); ! 152: logsoftc.sc_state &= ~LOG_RDWAIT; ! 153: } ! 154: } ! 155: ! 156: /*ARGSUSED*/ ! 157: logioctl(dev, com, data, flag) ! 158: caddr_t data; ! 159: { ! 160: long l; ! 161: int s; ! 162: ! 163: switch (com) { ! 164: ! 165: /* return number of characters immediately available */ ! 166: case FIONREAD: ! 167: s = splhigh(); ! 168: l = msgbuf.msg_bufx - msgbuf.msg_bufr; ! 169: splx(s); ! 170: if (l < 0) ! 171: l += MSG_BSIZE; ! 172: *(off_t *)data = l; ! 173: break; ! 174: ! 175: case FIONBIO: ! 176: break; ! 177: ! 178: case FIOASYNC: ! 179: if (*(int *)data) ! 180: logsoftc.sc_state |= LOG_ASYNC; ! 181: else ! 182: logsoftc.sc_state &= ~LOG_ASYNC; ! 183: break; ! 184: ! 185: case TIOCSPGRP: ! 186: logsoftc.sc_pgid = *(int *)data; ! 187: break; ! 188: ! 189: case TIOCGPGRP: ! 190: *(int *)data = logsoftc.sc_pgid; ! 191: break; ! 192: ! 193: default: ! 194: return (-1); ! 195: } ! 196: return (0); ! 197: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.