123379Smckusick /* 229099Smckusick * Copyright (c) 1982, 1986 Regents of the University of California. 3*45732Smckusick * All rights reserved. 423379Smckusick * 5*45732Smckusick * %sccs.include.redist.c% 6*45732Smckusick * 7*45732Smckusick * @(#)subr_log.c 7.10 (Berkeley) 12/05/90 823379Smckusick */ 916723Sralph 1016723Sralph /* 1116723Sralph * Error log buffer for kernel printf's. 1216723Sralph */ 1316723Sralph 1417093Sbloom #include "param.h" 1517093Sbloom #include "user.h" 1617093Sbloom #include "proc.h" 1743691Smckusick #include "vnode.h" 1817093Sbloom #include "ioctl.h" 1917093Sbloom #include "msgbuf.h" 2017093Sbloom #include "file.h" 2117093Sbloom #include "errno.h" 2216723Sralph 2316723Sralph #define LOG_RDPRI (PZERO + 1) 2416723Sralph 2516723Sralph #define LOG_ASYNC 0x04 2616723Sralph #define LOG_RDWAIT 0x08 2716723Sralph 2816723Sralph struct logsoftc { 2916723Sralph int sc_state; /* see above for possibilities */ 3016723Sralph struct proc *sc_selp; /* process waiting on select call */ 3143661Skarels int sc_pgid; /* process/group for async I/O */ 3216723Sralph } logsoftc; 3316723Sralph 3418365Skarels int log_open; /* also used in log() */ 3518365Skarels 3624524Sbloom /*ARGSUSED*/ 3716723Sralph logopen(dev) 3816723Sralph dev_t dev; 3916723Sralph { 40*45732Smckusick register struct msgbuf *mbp = msgbufp; 4116723Sralph 4218365Skarels if (log_open) 4316725Sralph return (EBUSY); 4418365Skarels log_open = 1; 4543661Skarels logsoftc.sc_pgid = u.u_procp->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 */ 51*45732Smckusick if (mbp->msg_magic != MSG_MAGIC) { 5216723Sralph register int i; 5316723Sralph 54*45732Smckusick mbp->msg_magic = MSG_MAGIC; 55*45732Smckusick mbp->msg_bufx = mbp->msg_bufr = 0; 5616723Sralph for (i=0; i < MSG_BSIZE; i++) 57*45732Smckusick mbp->msg_bufc[i] = 0; 5816723Sralph } 5916725Sralph return (0); 6016723Sralph } 6116723Sralph 6224524Sbloom /*ARGSUSED*/ 6316723Sralph logclose(dev, flag) 6416723Sralph dev_t dev; 6516723Sralph { 6618365Skarels log_open = 0; 6716723Sralph logsoftc.sc_state = 0; 6816723Sralph logsoftc.sc_selp = 0; 6916723Sralph } 7016723Sralph 7124524Sbloom /*ARGSUSED*/ 7243661Skarels logread(dev, uio, flag) 7316723Sralph dev_t dev; 7416723Sralph struct uio *uio; 7543661Skarels int flag; 7616723Sralph { 77*45732Smckusick register struct msgbuf *mbp = msgbufp; 7816723Sralph register long l; 7916723Sralph register int s; 8016723Sralph int error = 0; 8116723Sralph 8216723Sralph s = splhigh(); 83*45732Smckusick while (mbp->msg_bufr == mbp->msg_bufx) { 8443661Skarels if (flag & IO_NDELAY) { 8516723Sralph splx(s); 8616725Sralph return (EWOULDBLOCK); 8716723Sralph } 8816723Sralph logsoftc.sc_state |= LOG_RDWAIT; 89*45732Smckusick if (error = tsleep((caddr_t)mbp, LOG_RDPRI | PCATCH, 9040811Smarc "klog", 0)) { 9140811Smarc splx(s); 9240811Smarc return (error); 9340811Smarc } 9416723Sralph } 9516723Sralph splx(s); 9616723Sralph logsoftc.sc_state &= ~LOG_RDWAIT; 9716723Sralph 9816723Sralph while (uio->uio_resid > 0) { 99*45732Smckusick l = mbp->msg_bufx - mbp->msg_bufr; 10016723Sralph if (l < 0) 101*45732Smckusick l = MSG_BSIZE - mbp->msg_bufr; 10226356Skarels l = MIN(l, uio->uio_resid); 10326249Skarels if (l == 0) 10416725Sralph break; 105*45732Smckusick error = uiomove((caddr_t)&mbp->msg_bufc[mbp->msg_bufr], 10637728Smckusick (int)l, uio); 10716723Sralph if (error) 10816723Sralph break; 109*45732Smckusick mbp->msg_bufr += l; 110*45732Smckusick if (mbp->msg_bufr < 0 || mbp->msg_bufr >= MSG_BSIZE) 111*45732Smckusick mbp->msg_bufr = 0; 11216723Sralph } 11316725Sralph return (error); 11416723Sralph } 11516723Sralph 11624524Sbloom /*ARGSUSED*/ 11716723Sralph logselect(dev, rw) 11816723Sralph dev_t dev; 11916723Sralph int rw; 12016723Sralph { 12116723Sralph int s = splhigh(); 12216723Sralph 12316723Sralph switch (rw) { 12416723Sralph 12516723Sralph case FREAD: 126*45732Smckusick if (msgbufp->msg_bufr != msgbufp->msg_bufx) { 12726249Skarels splx(s); 12826249Skarels return (1); 12926249Skarels } 13016723Sralph logsoftc.sc_selp = u.u_procp; 13116723Sralph break; 13216723Sralph } 13316723Sralph splx(s); 13416725Sralph return (0); 13516723Sralph } 13616723Sralph 13716723Sralph logwakeup() 13816723Sralph { 13943661Skarels struct proc *p; 14016723Sralph 14118365Skarels if (!log_open) 14218365Skarels return; 14316723Sralph if (logsoftc.sc_selp) { 14416723Sralph selwakeup(logsoftc.sc_selp, 0); 14516723Sralph logsoftc.sc_selp = 0; 14616723Sralph } 14743661Skarels if (logsoftc.sc_state & LOG_ASYNC) { 14843661Skarels if (logsoftc.sc_pgid < 0) 14944986Smarc gsignal(-logsoftc.sc_pgid, SIGIO); 15043661Skarels else if (p = pfind(logsoftc.sc_pgid)) 15143661Skarels psignal(p, SIGIO); 15243661Skarels } 15316723Sralph if (logsoftc.sc_state & LOG_RDWAIT) { 154*45732Smckusick wakeup((caddr_t)msgbufp); 15516723Sralph logsoftc.sc_state &= ~LOG_RDWAIT; 15616723Sralph } 15716723Sralph } 15816723Sralph 15916723Sralph /*ARGSUSED*/ 16043661Skarels logioctl(dev, com, data, flag) 16116723Sralph caddr_t data; 16216723Sralph { 16316723Sralph long l; 16416723Sralph int s; 16516723Sralph 16616723Sralph switch (com) { 16716723Sralph 16816723Sralph /* return number of characters immediately available */ 16916723Sralph case FIONREAD: 17016723Sralph s = splhigh(); 171*45732Smckusick l = msgbufp->msg_bufx - msgbufp->msg_bufr; 17216723Sralph splx(s); 17316723Sralph if (l < 0) 17416723Sralph l += MSG_BSIZE; 17516723Sralph *(off_t *)data = l; 17616723Sralph break; 17716723Sralph 17816723Sralph case FIONBIO: 17916723Sralph break; 18016723Sralph 18116723Sralph case FIOASYNC: 18216723Sralph if (*(int *)data) 18316723Sralph logsoftc.sc_state |= LOG_ASYNC; 18416723Sralph else 18516723Sralph logsoftc.sc_state &= ~LOG_ASYNC; 18616723Sralph break; 18716723Sralph 18843661Skarels case TIOCSPGRP: 18935810Smarc logsoftc.sc_pgid = *(int *)data; 19016723Sralph break; 19116723Sralph 19216723Sralph case TIOCGPGRP: 19343661Skarels *(int *)data = logsoftc.sc_pgid; 19416723Sralph break; 19516723Sralph 19616723Sralph default: 19716725Sralph return (-1); 19816723Sralph } 19916725Sralph return (0); 20016723Sralph } 201