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*39563Smarc * @(#)subr_log.c 7.4 (Berkeley) 11/20/89 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_NBIO 0x02 2416723Sralph #define LOG_ASYNC 0x04 2516723Sralph #define LOG_RDWAIT 0x08 2616723Sralph 2716723Sralph struct logsoftc { 2816723Sralph int sc_state; /* see above for possibilities */ 2916723Sralph struct proc *sc_selp; /* process waiting on select call */ 30*39563Smarc struct pgrp *sc_pgrp; /* process group for async I/O */ 3116723Sralph } logsoftc; 3216723Sralph 3318365Skarels int log_open; /* also used in log() */ 3418365Skarels 3524524Sbloom /*ARGSUSED*/ 3616723Sralph logopen(dev) 3716723Sralph dev_t dev; 3816723Sralph { 3916723Sralph 4018365Skarels if (log_open) 4116725Sralph return (EBUSY); 4218365Skarels log_open = 1; 4316723Sralph logsoftc.sc_selp = 0; 44*39563Smarc logsoftc.sc_pgrp = u.u_procp->p_pgrp; 4516723Sralph /* 4616723Sralph * Potential race here with putchar() but since putchar should be 4716723Sralph * called by autoconf, msg_magic should be initialized by the time 4816723Sralph * we get here. 4916723Sralph */ 5016723Sralph if (msgbuf.msg_magic != MSG_MAGIC) { 5116723Sralph register int i; 5216723Sralph 5316723Sralph msgbuf.msg_magic = MSG_MAGIC; 5416723Sralph msgbuf.msg_bufx = msgbuf.msg_bufr = 0; 5516723Sralph for (i=0; i < MSG_BSIZE; i++) 5616723Sralph msgbuf.msg_bufc[i] = 0; 5716723Sralph } 5816725Sralph return (0); 5916723Sralph } 6016723Sralph 6124524Sbloom /*ARGSUSED*/ 6216723Sralph logclose(dev, flag) 6316723Sralph dev_t dev; 6416723Sralph { 6518365Skarels log_open = 0; 6616723Sralph logsoftc.sc_state = 0; 6716723Sralph logsoftc.sc_selp = 0; 68*39563Smarc logsoftc.sc_pgrp = NULL; 6916723Sralph } 7016723Sralph 7124524Sbloom /*ARGSUSED*/ 7216723Sralph logread(dev, uio) 7316723Sralph dev_t dev; 7416723Sralph struct uio *uio; 7516723Sralph { 7616723Sralph register long l; 7716723Sralph register int s; 7816723Sralph int error = 0; 7916723Sralph 8016723Sralph s = splhigh(); 8116723Sralph while (msgbuf.msg_bufr == msgbuf.msg_bufx) { 8216723Sralph if (logsoftc.sc_state & LOG_NBIO) { 8316723Sralph splx(s); 8416725Sralph return (EWOULDBLOCK); 8516723Sralph } 8616723Sralph logsoftc.sc_state |= LOG_RDWAIT; 8716723Sralph sleep((caddr_t)&msgbuf, LOG_RDPRI); 8816723Sralph } 8916723Sralph splx(s); 9016723Sralph logsoftc.sc_state &= ~LOG_RDWAIT; 9116723Sralph 9216723Sralph while (uio->uio_resid > 0) { 9316723Sralph l = msgbuf.msg_bufx - msgbuf.msg_bufr; 9416723Sralph if (l < 0) 9516723Sralph l = MSG_BSIZE - msgbuf.msg_bufr; 9626356Skarels l = MIN(l, uio->uio_resid); 9726249Skarels if (l == 0) 9816725Sralph break; 9916723Sralph error = uiomove((caddr_t)&msgbuf.msg_bufc[msgbuf.msg_bufr], 10037728Smckusick (int)l, uio); 10116723Sralph if (error) 10216723Sralph break; 10326249Skarels msgbuf.msg_bufr += l; 10416723Sralph if (msgbuf.msg_bufr < 0 || msgbuf.msg_bufr >= MSG_BSIZE) 10516723Sralph msgbuf.msg_bufr = 0; 10616723Sralph } 10716725Sralph return (error); 10816723Sralph } 10916723Sralph 11024524Sbloom /*ARGSUSED*/ 11116723Sralph logselect(dev, rw) 11216723Sralph dev_t dev; 11316723Sralph int rw; 11416723Sralph { 11516723Sralph int s = splhigh(); 11616723Sralph 11716723Sralph switch (rw) { 11816723Sralph 11916723Sralph case FREAD: 12026249Skarels if (msgbuf.msg_bufr != msgbuf.msg_bufx) { 12126249Skarels splx(s); 12226249Skarels return (1); 12326249Skarels } 12416723Sralph logsoftc.sc_selp = u.u_procp; 12516723Sralph break; 12616723Sralph } 12716723Sralph splx(s); 12816725Sralph return (0); 12916723Sralph } 13016723Sralph 13116723Sralph logwakeup() 13216723Sralph { 13316723Sralph 13418365Skarels if (!log_open) 13518365Skarels return; 13616723Sralph if (logsoftc.sc_selp) { 13716723Sralph selwakeup(logsoftc.sc_selp, 0); 13816723Sralph logsoftc.sc_selp = 0; 13916723Sralph } 14016723Sralph if (logsoftc.sc_state & LOG_ASYNC) 141*39563Smarc pgsignal(logsoftc.sc_pgrp, SIGIO); 14216723Sralph if (logsoftc.sc_state & LOG_RDWAIT) { 14316723Sralph wakeup((caddr_t)&msgbuf); 14416723Sralph logsoftc.sc_state &= ~LOG_RDWAIT; 14516723Sralph } 14616723Sralph } 14716723Sralph 14816723Sralph /*ARGSUSED*/ 14916723Sralph logioctl(com, data, flag) 15016723Sralph caddr_t data; 15116723Sralph { 15216723Sralph long l; 15316723Sralph int s; 15416723Sralph 15516723Sralph switch (com) { 15616723Sralph 15716723Sralph /* return number of characters immediately available */ 15816723Sralph case FIONREAD: 15916723Sralph s = splhigh(); 16016723Sralph l = msgbuf.msg_bufx - msgbuf.msg_bufr; 16116723Sralph splx(s); 16216723Sralph if (l < 0) 16316723Sralph l += MSG_BSIZE; 16416723Sralph *(off_t *)data = l; 16516723Sralph break; 16616723Sralph 16716723Sralph case FIONBIO: 16816723Sralph if (*(int *)data) 16916723Sralph logsoftc.sc_state |= LOG_NBIO; 17016723Sralph else 17116723Sralph logsoftc.sc_state &= ~LOG_NBIO; 17216723Sralph break; 17316723Sralph 17416723Sralph case FIOASYNC: 17516723Sralph if (*(int *)data) 17616723Sralph logsoftc.sc_state |= LOG_ASYNC; 17716723Sralph else 17816723Sralph logsoftc.sc_state &= ~LOG_ASYNC; 17916723Sralph break; 18016723Sralph 181*39563Smarc #ifdef notdef /* XXX remove -- a single open device doesn't need this */ 18235810Smarc case TIOCSPGRP: { 18335810Smarc logsoftc.sc_pgid = *(int *)data; 18416723Sralph break; 18535810Smarc } 186*39563Smarc #endif 18716723Sralph 18816723Sralph case TIOCGPGRP: 189*39563Smarc *(int *)data = logsoftc.sc_pgrp->pg_id; 19016723Sralph break; 19116723Sralph 19216723Sralph default: 19316725Sralph return (-1); 19416723Sralph } 19516725Sralph return (0); 19616723Sralph } 197