123379Smckusick /* 229099Smckusick * Copyright (c) 1982, 1986 Regents of the University of California. 323379Smckusick * All rights reserved. The Berkeley software License Agreement 423379Smckusick * specifies the terms and conditions for redistribution. 523379Smckusick * 6*43661Skarels * @(#)subr_log.c 7.7 (Berkeley) 06/24/90 723379Smckusick */ 816723Sralph 916723Sralph /* 1016723Sralph * Error log buffer for kernel printf's. 1116723Sralph */ 1216723Sralph 1317093Sbloom #include "param.h" 1417093Sbloom #include "user.h" 1517093Sbloom #include "proc.h" 1617093Sbloom #include "ioctl.h" 1717093Sbloom #include "msgbuf.h" 1817093Sbloom #include "file.h" 1917093Sbloom #include "errno.h" 2016723Sralph 2116723Sralph #define LOG_RDPRI (PZERO + 1) 2216723Sralph 2316723Sralph #define LOG_ASYNC 0x04 2416723Sralph #define LOG_RDWAIT 0x08 2516723Sralph 2616723Sralph struct logsoftc { 2716723Sralph int sc_state; /* see above for possibilities */ 2816723Sralph struct proc *sc_selp; /* process waiting on select call */ 29*43661Skarels int sc_pgid; /* process/group for async I/O */ 3016723Sralph } logsoftc; 3116723Sralph 3218365Skarels int log_open; /* also used in log() */ 3318365Skarels 3424524Sbloom /*ARGSUSED*/ 3516723Sralph logopen(dev) 3616723Sralph dev_t dev; 3716723Sralph { 3816723Sralph 3918365Skarels if (log_open) 4016725Sralph return (EBUSY); 4118365Skarels log_open = 1; 42*43661Skarels logsoftc.sc_pgid = u.u_procp->p_pid; /* signal process only */ 4316723Sralph /* 4416723Sralph * Potential race here with putchar() but since putchar should be 4516723Sralph * called by autoconf, msg_magic should be initialized by the time 4616723Sralph * we get here. 4716723Sralph */ 4816723Sralph if (msgbuf.msg_magic != MSG_MAGIC) { 4916723Sralph register int i; 5016723Sralph 5116723Sralph msgbuf.msg_magic = MSG_MAGIC; 5216723Sralph msgbuf.msg_bufx = msgbuf.msg_bufr = 0; 5316723Sralph for (i=0; i < MSG_BSIZE; i++) 5416723Sralph msgbuf.msg_bufc[i] = 0; 5516723Sralph } 5616725Sralph return (0); 5716723Sralph } 5816723Sralph 5924524Sbloom /*ARGSUSED*/ 6016723Sralph logclose(dev, flag) 6116723Sralph dev_t dev; 6216723Sralph { 6318365Skarels log_open = 0; 6416723Sralph logsoftc.sc_state = 0; 6516723Sralph logsoftc.sc_selp = 0; 6616723Sralph } 6716723Sralph 6824524Sbloom /*ARGSUSED*/ 69*43661Skarels logread(dev, uio, flag) 7016723Sralph dev_t dev; 7116723Sralph struct uio *uio; 72*43661Skarels int flag; 7316723Sralph { 7416723Sralph register long l; 7516723Sralph register int s; 7616723Sralph int error = 0; 7716723Sralph 7816723Sralph s = splhigh(); 7916723Sralph while (msgbuf.msg_bufr == msgbuf.msg_bufx) { 80*43661Skarels if (flag & IO_NDELAY) { 8116723Sralph splx(s); 8216725Sralph return (EWOULDBLOCK); 8316723Sralph } 8416723Sralph logsoftc.sc_state |= LOG_RDWAIT; 8540811Smarc if (error = tsleep((caddr_t)&msgbuf, LOG_RDPRI | PCATCH, 8640811Smarc "klog", 0)) { 8740811Smarc splx(s); 8840811Smarc return (error); 8940811Smarc } 9016723Sralph } 9116723Sralph splx(s); 9216723Sralph logsoftc.sc_state &= ~LOG_RDWAIT; 9316723Sralph 9416723Sralph while (uio->uio_resid > 0) { 9516723Sralph l = msgbuf.msg_bufx - msgbuf.msg_bufr; 9616723Sralph if (l < 0) 9716723Sralph l = MSG_BSIZE - msgbuf.msg_bufr; 9826356Skarels l = MIN(l, uio->uio_resid); 9926249Skarels if (l == 0) 10016725Sralph break; 10116723Sralph error = uiomove((caddr_t)&msgbuf.msg_bufc[msgbuf.msg_bufr], 10237728Smckusick (int)l, uio); 10316723Sralph if (error) 10416723Sralph break; 10526249Skarels msgbuf.msg_bufr += l; 10616723Sralph if (msgbuf.msg_bufr < 0 || msgbuf.msg_bufr >= MSG_BSIZE) 10716723Sralph msgbuf.msg_bufr = 0; 10816723Sralph } 10916725Sralph return (error); 11016723Sralph } 11116723Sralph 11224524Sbloom /*ARGSUSED*/ 11316723Sralph logselect(dev, rw) 11416723Sralph dev_t dev; 11516723Sralph int rw; 11616723Sralph { 11716723Sralph int s = splhigh(); 11816723Sralph 11916723Sralph switch (rw) { 12016723Sralph 12116723Sralph case FREAD: 12226249Skarels if (msgbuf.msg_bufr != msgbuf.msg_bufx) { 12326249Skarels splx(s); 12426249Skarels return (1); 12526249Skarels } 12616723Sralph logsoftc.sc_selp = u.u_procp; 12716723Sralph break; 12816723Sralph } 12916723Sralph splx(s); 13016725Sralph return (0); 13116723Sralph } 13216723Sralph 13316723Sralph logwakeup() 13416723Sralph { 135*43661Skarels struct proc *p; 13616723Sralph 13718365Skarels if (!log_open) 13818365Skarels return; 13916723Sralph if (logsoftc.sc_selp) { 14016723Sralph selwakeup(logsoftc.sc_selp, 0); 14116723Sralph logsoftc.sc_selp = 0; 14216723Sralph } 143*43661Skarels if (logsoftc.sc_state & LOG_ASYNC) { 144*43661Skarels if (logsoftc.sc_pgid < 0) 145*43661Skarels gsignal(logsoftc.sc_pgid, SIGIO); 146*43661Skarels else if (p = pfind(logsoftc.sc_pgid)) 147*43661Skarels psignal(p, SIGIO); 148*43661Skarels } 14916723Sralph if (logsoftc.sc_state & LOG_RDWAIT) { 15016723Sralph wakeup((caddr_t)&msgbuf); 15116723Sralph logsoftc.sc_state &= ~LOG_RDWAIT; 15216723Sralph } 15316723Sralph } 15416723Sralph 15516723Sralph /*ARGSUSED*/ 156*43661Skarels logioctl(dev, com, data, flag) 15716723Sralph caddr_t data; 15816723Sralph { 15916723Sralph long l; 16016723Sralph int s; 16116723Sralph 16216723Sralph switch (com) { 16316723Sralph 16416723Sralph /* return number of characters immediately available */ 16516723Sralph case FIONREAD: 16616723Sralph s = splhigh(); 16716723Sralph l = msgbuf.msg_bufx - msgbuf.msg_bufr; 16816723Sralph splx(s); 16916723Sralph if (l < 0) 17016723Sralph l += MSG_BSIZE; 17116723Sralph *(off_t *)data = l; 17216723Sralph break; 17316723Sralph 17416723Sralph case FIONBIO: 17516723Sralph break; 17616723Sralph 17716723Sralph case FIOASYNC: 17816723Sralph if (*(int *)data) 17916723Sralph logsoftc.sc_state |= LOG_ASYNC; 18016723Sralph else 18116723Sralph logsoftc.sc_state &= ~LOG_ASYNC; 18216723Sralph break; 18316723Sralph 184*43661Skarels case TIOCSPGRP: 18535810Smarc logsoftc.sc_pgid = *(int *)data; 18616723Sralph break; 18716723Sralph 18816723Sralph case TIOCGPGRP: 189*43661Skarels *(int *)data = logsoftc.sc_pgid; 19016723Sralph break; 19116723Sralph 19216723Sralph default: 19316725Sralph return (-1); 19416723Sralph } 19516725Sralph return (0); 19616723Sralph } 197