123379Smckusick /* 229099Smckusick * Copyright (c) 1982, 1986 Regents of the University of California. 345732Smckusick * All rights reserved. 423379Smckusick * 545732Smckusick * %sccs.include.redist.c% 645732Smckusick * 7*56517Sbostic * @(#)subr_log.c 7.18 (Berkeley) 10/11/92 823379Smckusick */ 916723Sralph 1016723Sralph /* 1116723Sralph * Error log buffer for kernel printf's. 1216723Sralph */ 1316723Sralph 14*56517Sbostic #include <sys/param.h> 15*56517Sbostic #include <sys/systm.h> 16*56517Sbostic #include <sys/proc.h> 17*56517Sbostic #include <sys/vnode.h> 18*56517Sbostic #include <sys/ioctl.h> 19*56517Sbostic #include <sys/msgbuf.h> 20*56517Sbostic #include <sys/file.h> 2116723Sralph 2216723Sralph #define LOG_RDPRI (PZERO + 1) 2316723Sralph 2416723Sralph #define LOG_ASYNC 0x04 2516723Sralph #define LOG_RDWAIT 0x08 2616723Sralph 2716723Sralph struct logsoftc { 2816723Sralph int sc_state; /* see above for possibilities */ 2952521Smckusick struct selinfo sc_selp; /* process waiting on select call */ 3043661Skarels int sc_pgid; /* process/group for async I/O */ 3116723Sralph } logsoftc; 3216723Sralph 3318365Skarels int log_open; /* also used in log() */ 3418365Skarels 3524524Sbloom /*ARGSUSED*/ 3647540Skarels logopen(dev, flags, mode, p) 3716723Sralph dev_t dev; 3847540Skarels int flags, mode; 3947540Skarels struct proc *p; 4016723Sralph { 4145732Smckusick register struct msgbuf *mbp = msgbufp; 4216723Sralph 4318365Skarels if (log_open) 4416725Sralph return (EBUSY); 4518365Skarels log_open = 1; 4647540Skarels logsoftc.sc_pgid = p->p_pid; /* signal process only */ 4716723Sralph /* 4816723Sralph * Potential race here with putchar() but since putchar should be 4916723Sralph * called by autoconf, msg_magic should be initialized by the time 5016723Sralph * we get here. 5116723Sralph */ 5245732Smckusick if (mbp->msg_magic != MSG_MAGIC) { 5316723Sralph register int i; 5416723Sralph 5545732Smckusick mbp->msg_magic = MSG_MAGIC; 5645732Smckusick mbp->msg_bufx = mbp->msg_bufr = 0; 5716723Sralph for (i=0; i < MSG_BSIZE; i++) 5845732Smckusick mbp->msg_bufc[i] = 0; 5916723Sralph } 6016725Sralph return (0); 6116723Sralph } 6216723Sralph 6324524Sbloom /*ARGSUSED*/ 6452419Storek logclose(dev, flag, mode, p) 6516723Sralph dev_t dev; 6652419Storek int flag, mode; 6752419Storek struct proc *p; 6816723Sralph { 6952521Smckusick 7018365Skarels log_open = 0; 7116723Sralph logsoftc.sc_state = 0; 7253647Sbostic return (0); 7316723Sralph } 7416723Sralph 7524524Sbloom /*ARGSUSED*/ 7643661Skarels logread(dev, uio, flag) 7716723Sralph dev_t dev; 7816723Sralph struct uio *uio; 7943661Skarels int flag; 8016723Sralph { 8145732Smckusick register struct msgbuf *mbp = msgbufp; 8216723Sralph register long l; 8316723Sralph register int s; 8416723Sralph int error = 0; 8516723Sralph 8616723Sralph s = splhigh(); 8745732Smckusick while (mbp->msg_bufr == mbp->msg_bufx) { 8843661Skarels if (flag & IO_NDELAY) { 8916723Sralph splx(s); 9016725Sralph return (EWOULDBLOCK); 9116723Sralph } 9216723Sralph logsoftc.sc_state |= LOG_RDWAIT; 9345732Smckusick if (error = tsleep((caddr_t)mbp, LOG_RDPRI | PCATCH, 9440811Smarc "klog", 0)) { 9540811Smarc splx(s); 9640811Smarc return (error); 9740811Smarc } 9816723Sralph } 9916723Sralph splx(s); 10016723Sralph logsoftc.sc_state &= ~LOG_RDWAIT; 10116723Sralph 10216723Sralph while (uio->uio_resid > 0) { 10345732Smckusick l = mbp->msg_bufx - mbp->msg_bufr; 10416723Sralph if (l < 0) 10545732Smckusick l = MSG_BSIZE - mbp->msg_bufr; 10655058Spendry l = min(l, uio->uio_resid); 10726249Skarels if (l == 0) 10816725Sralph break; 10945732Smckusick error = uiomove((caddr_t)&mbp->msg_bufc[mbp->msg_bufr], 11037728Smckusick (int)l, uio); 11116723Sralph if (error) 11216723Sralph break; 11345732Smckusick mbp->msg_bufr += l; 11445732Smckusick if (mbp->msg_bufr < 0 || mbp->msg_bufr >= MSG_BSIZE) 11545732Smckusick mbp->msg_bufr = 0; 11616723Sralph } 11716725Sralph return (error); 11816723Sralph } 11916723Sralph 12024524Sbloom /*ARGSUSED*/ 12147540Skarels logselect(dev, rw, p) 12216723Sralph dev_t dev; 12316723Sralph int rw; 12447540Skarels struct proc *p; 12516723Sralph { 12616723Sralph int s = splhigh(); 12716723Sralph 12816723Sralph switch (rw) { 12916723Sralph 13016723Sralph case FREAD: 13145732Smckusick if (msgbufp->msg_bufr != msgbufp->msg_bufx) { 13226249Skarels splx(s); 13326249Skarels return (1); 13426249Skarels } 13552521Smckusick selrecord(p, &logsoftc.sc_selp); 13616723Sralph break; 13716723Sralph } 13816723Sralph splx(s); 13916725Sralph return (0); 14016723Sralph } 14116723Sralph 14216723Sralph logwakeup() 14316723Sralph { 14443661Skarels struct proc *p; 14516723Sralph 14618365Skarels if (!log_open) 14718365Skarels return; 14852521Smckusick selwakeup(&logsoftc.sc_selp); 14943661Skarels if (logsoftc.sc_state & LOG_ASYNC) { 15043661Skarels if (logsoftc.sc_pgid < 0) 15144986Smarc gsignal(-logsoftc.sc_pgid, SIGIO); 15243661Skarels else if (p = pfind(logsoftc.sc_pgid)) 15343661Skarels psignal(p, SIGIO); 15443661Skarels } 15516723Sralph if (logsoftc.sc_state & LOG_RDWAIT) { 15645732Smckusick wakeup((caddr_t)msgbufp); 15716723Sralph logsoftc.sc_state &= ~LOG_RDWAIT; 15816723Sralph } 15916723Sralph } 16016723Sralph 16116723Sralph /*ARGSUSED*/ 16252419Storek logioctl(dev, com, data, flag, p) 16352419Storek dev_t dev; 16452419Storek int com; 16516723Sralph caddr_t data; 16652419Storek int flag; 16752419Storek struct proc *p; 16816723Sralph { 16916723Sralph long l; 17016723Sralph int s; 17116723Sralph 17216723Sralph switch (com) { 17316723Sralph 17416723Sralph /* return number of characters immediately available */ 17516723Sralph case FIONREAD: 17616723Sralph s = splhigh(); 17745732Smckusick l = msgbufp->msg_bufx - msgbufp->msg_bufr; 17816723Sralph splx(s); 17916723Sralph if (l < 0) 18016723Sralph l += MSG_BSIZE; 18154773Storek *(int *)data = l; 18216723Sralph break; 18316723Sralph 18416723Sralph case FIONBIO: 18516723Sralph break; 18616723Sralph 18716723Sralph case FIOASYNC: 18816723Sralph if (*(int *)data) 18916723Sralph logsoftc.sc_state |= LOG_ASYNC; 19016723Sralph else 19116723Sralph logsoftc.sc_state &= ~LOG_ASYNC; 19216723Sralph break; 19316723Sralph 19443661Skarels case TIOCSPGRP: 19535810Smarc logsoftc.sc_pgid = *(int *)data; 19616723Sralph break; 19716723Sralph 19816723Sralph case TIOCGPGRP: 19943661Skarels *(int *)data = logsoftc.sc_pgid; 20016723Sralph break; 20116723Sralph 20216723Sralph default: 20316725Sralph return (-1); 20416723Sralph } 20516725Sralph return (0); 20616723Sralph } 207