123379Smckusick /* 229099Smckusick * Copyright (c) 1982, 1986 Regents of the University of California. 345732Smckusick * All rights reserved. 423379Smckusick * 545732Smckusick * %sccs.include.redist.c% 645732Smckusick * 7*52419Storek * @(#)subr_log.c 7.12 (Berkeley) 02/05/92 823379Smckusick */ 916723Sralph 1016723Sralph /* 1116723Sralph * Error log buffer for kernel printf's. 1216723Sralph */ 1316723Sralph 1417093Sbloom #include "param.h" 1517093Sbloom #include "proc.h" 1643691Smckusick #include "vnode.h" 1717093Sbloom #include "ioctl.h" 1817093Sbloom #include "msgbuf.h" 1917093Sbloom #include "file.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 */ 2943661Skarels int sc_pgid; /* process/group for async I/O */ 3016723Sralph } logsoftc; 3116723Sralph 3218365Skarels int log_open; /* also used in log() */ 3318365Skarels 3424524Sbloom /*ARGSUSED*/ 3547540Skarels logopen(dev, flags, mode, p) 3616723Sralph dev_t dev; 3747540Skarels int flags, mode; 3847540Skarels struct proc *p; 3916723Sralph { 4045732Smckusick register struct msgbuf *mbp = msgbufp; 4116723Sralph 4218365Skarels if (log_open) 4316725Sralph return (EBUSY); 4418365Skarels log_open = 1; 4547540Skarels logsoftc.sc_pgid = p->p_pid; /* signal process only */ 4616723Sralph /* 4716723Sralph * Potential race here with putchar() but since putchar should be 4816723Sralph * called by autoconf, msg_magic should be initialized by the time 4916723Sralph * we get here. 5016723Sralph */ 5145732Smckusick if (mbp->msg_magic != MSG_MAGIC) { 5216723Sralph register int i; 5316723Sralph 5445732Smckusick mbp->msg_magic = MSG_MAGIC; 5545732Smckusick mbp->msg_bufx = mbp->msg_bufr = 0; 5616723Sralph for (i=0; i < MSG_BSIZE; i++) 5745732Smckusick mbp->msg_bufc[i] = 0; 5816723Sralph } 5916725Sralph return (0); 6016723Sralph } 6116723Sralph 6224524Sbloom /*ARGSUSED*/ 63*52419Storek logclose(dev, flag, mode, p) 6416723Sralph dev_t dev; 65*52419Storek int flag, mode; 66*52419Storek struct proc *p; 6716723Sralph { 6818365Skarels log_open = 0; 6916723Sralph logsoftc.sc_state = 0; 7016723Sralph logsoftc.sc_selp = 0; 7116723Sralph } 7216723Sralph 7324524Sbloom /*ARGSUSED*/ 7443661Skarels logread(dev, uio, flag) 7516723Sralph dev_t dev; 7616723Sralph struct uio *uio; 7743661Skarels int flag; 7816723Sralph { 7945732Smckusick register struct msgbuf *mbp = msgbufp; 8016723Sralph register long l; 8116723Sralph register int s; 8216723Sralph int error = 0; 8316723Sralph 8416723Sralph s = splhigh(); 8545732Smckusick while (mbp->msg_bufr == mbp->msg_bufx) { 8643661Skarels if (flag & IO_NDELAY) { 8716723Sralph splx(s); 8816725Sralph return (EWOULDBLOCK); 8916723Sralph } 9016723Sralph logsoftc.sc_state |= LOG_RDWAIT; 9145732Smckusick if (error = tsleep((caddr_t)mbp, LOG_RDPRI | PCATCH, 9240811Smarc "klog", 0)) { 9340811Smarc splx(s); 9440811Smarc return (error); 9540811Smarc } 9616723Sralph } 9716723Sralph splx(s); 9816723Sralph logsoftc.sc_state &= ~LOG_RDWAIT; 9916723Sralph 10016723Sralph while (uio->uio_resid > 0) { 10145732Smckusick l = mbp->msg_bufx - mbp->msg_bufr; 10216723Sralph if (l < 0) 10345732Smckusick l = MSG_BSIZE - mbp->msg_bufr; 10426356Skarels l = MIN(l, uio->uio_resid); 10526249Skarels if (l == 0) 10616725Sralph break; 10745732Smckusick error = uiomove((caddr_t)&mbp->msg_bufc[mbp->msg_bufr], 10837728Smckusick (int)l, uio); 10916723Sralph if (error) 11016723Sralph break; 11145732Smckusick mbp->msg_bufr += l; 11245732Smckusick if (mbp->msg_bufr < 0 || mbp->msg_bufr >= MSG_BSIZE) 11345732Smckusick mbp->msg_bufr = 0; 11416723Sralph } 11516725Sralph return (error); 11616723Sralph } 11716723Sralph 11824524Sbloom /*ARGSUSED*/ 11947540Skarels logselect(dev, rw, p) 12016723Sralph dev_t dev; 12116723Sralph int rw; 12247540Skarels struct proc *p; 12316723Sralph { 12416723Sralph int s = splhigh(); 12516723Sralph 12616723Sralph switch (rw) { 12716723Sralph 12816723Sralph case FREAD: 12945732Smckusick if (msgbufp->msg_bufr != msgbufp->msg_bufx) { 13026249Skarels splx(s); 13126249Skarels return (1); 13226249Skarels } 13347540Skarels logsoftc.sc_selp = p; 13416723Sralph break; 13516723Sralph } 13616723Sralph splx(s); 13716725Sralph return (0); 13816723Sralph } 13916723Sralph 14016723Sralph logwakeup() 14116723Sralph { 14243661Skarels struct proc *p; 14316723Sralph 14418365Skarels if (!log_open) 14518365Skarels return; 14616723Sralph if (logsoftc.sc_selp) { 14716723Sralph selwakeup(logsoftc.sc_selp, 0); 14816723Sralph logsoftc.sc_selp = 0; 14916723Sralph } 15043661Skarels if (logsoftc.sc_state & LOG_ASYNC) { 15143661Skarels if (logsoftc.sc_pgid < 0) 15244986Smarc gsignal(-logsoftc.sc_pgid, SIGIO); 15343661Skarels else if (p = pfind(logsoftc.sc_pgid)) 15443661Skarels psignal(p, SIGIO); 15543661Skarels } 15616723Sralph if (logsoftc.sc_state & LOG_RDWAIT) { 15745732Smckusick wakeup((caddr_t)msgbufp); 15816723Sralph logsoftc.sc_state &= ~LOG_RDWAIT; 15916723Sralph } 16016723Sralph } 16116723Sralph 16216723Sralph /*ARGSUSED*/ 163*52419Storek logioctl(dev, com, data, flag, p) 164*52419Storek dev_t dev; 165*52419Storek int com; 16616723Sralph caddr_t data; 167*52419Storek int flag; 168*52419Storek struct proc *p; 16916723Sralph { 17016723Sralph long l; 17116723Sralph int s; 17216723Sralph 17316723Sralph switch (com) { 17416723Sralph 17516723Sralph /* return number of characters immediately available */ 17616723Sralph case FIONREAD: 17716723Sralph s = splhigh(); 17845732Smckusick l = msgbufp->msg_bufx - msgbufp->msg_bufr; 17916723Sralph splx(s); 18016723Sralph if (l < 0) 18116723Sralph l += MSG_BSIZE; 18216723Sralph *(off_t *)data = l; 18316723Sralph break; 18416723Sralph 18516723Sralph case FIONBIO: 18616723Sralph break; 18716723Sralph 18816723Sralph case FIOASYNC: 18916723Sralph if (*(int *)data) 19016723Sralph logsoftc.sc_state |= LOG_ASYNC; 19116723Sralph else 19216723Sralph logsoftc.sc_state &= ~LOG_ASYNC; 19316723Sralph break; 19416723Sralph 19543661Skarels case TIOCSPGRP: 19635810Smarc logsoftc.sc_pgid = *(int *)data; 19716723Sralph break; 19816723Sralph 19916723Sralph case TIOCGPGRP: 20043661Skarels *(int *)data = logsoftc.sc_pgid; 20116723Sralph break; 20216723Sralph 20316723Sralph default: 20416725Sralph return (-1); 20516723Sralph } 20616725Sralph return (0); 20716723Sralph } 208