1*18365Skarels /* subr_log.c 6.4 85/03/18 */ 216723Sralph 316723Sralph /* 416723Sralph * Error log buffer for kernel printf's. 516723Sralph */ 616723Sralph 717093Sbloom #include "param.h" 817093Sbloom #include "dir.h" 917093Sbloom #include "user.h" 1017093Sbloom #include "proc.h" 1117093Sbloom #include "ioctl.h" 1217093Sbloom #include "msgbuf.h" 1317093Sbloom #include "file.h" 1417093Sbloom #include "errno.h" 1516723Sralph 1616723Sralph #define LOG_RDPRI (PZERO + 1) 1716723Sralph 1816723Sralph #define LOG_NBIO 0x02 1916723Sralph #define LOG_ASYNC 0x04 2016723Sralph #define LOG_RDWAIT 0x08 2116723Sralph 2216723Sralph struct logsoftc { 2316723Sralph int sc_state; /* see above for possibilities */ 2416723Sralph struct proc *sc_selp; /* process waiting on select call */ 2516723Sralph int sc_pgrp; /* process group for async I/O */ 2616723Sralph } logsoftc; 2716723Sralph 28*18365Skarels int log_open; /* also used in log() */ 29*18365Skarels 3016725Sralph #ifdef LOGDEBUG 3116725Sralph /*VARARGS1*/ 3216725Sralph xprintf(fmt, x1) 3316725Sralph char *fmt; 3416725Sralph unsigned x1; 3516725Sralph { 3616725Sralph 3716725Sralph prf(fmt, &x1, 1, (struct tty *)0); 3816725Sralph } 3916725Sralph #endif 4016725Sralph 4116723Sralph logopen(dev) 4216723Sralph dev_t dev; 4316723Sralph { 4416723Sralph 4516723Sralph #ifdef LOGDEBUG 4616725Sralph xprintf("logopen: dev=0x%x\n", dev); 4716723Sralph #endif 48*18365Skarels if (log_open) 4916725Sralph return (EBUSY); 50*18365Skarels log_open = 1; 5116723Sralph logsoftc.sc_selp = 0; 5216723Sralph logsoftc.sc_pgrp = u.u_procp->p_pgrp; 5316723Sralph /* 5416723Sralph * Potential race here with putchar() but since putchar should be 5516723Sralph * called by autoconf, msg_magic should be initialized by the time 5616723Sralph * we get here. 5716723Sralph */ 5816723Sralph if (msgbuf.msg_magic != MSG_MAGIC) { 5916723Sralph register int i; 6016723Sralph 6116723Sralph msgbuf.msg_magic = MSG_MAGIC; 6216723Sralph msgbuf.msg_bufx = msgbuf.msg_bufr = 0; 6316723Sralph for (i=0; i < MSG_BSIZE; i++) 6416723Sralph msgbuf.msg_bufc[i] = 0; 6516723Sralph } 6616725Sralph #ifdef LOGDEBUG 6716725Sralph xprintf("logopen: bufx=%d, bufr=%d\n", msgbuf.msg_bufx, msgbuf.msg_bufr); 6816725Sralph #endif 6916725Sralph return (0); 7016723Sralph } 7116723Sralph 7216723Sralph logclose(dev, flag) 7316723Sralph dev_t dev; 7416723Sralph { 75*18365Skarels log_open = 0; 7616723Sralph logsoftc.sc_state = 0; 7716723Sralph logsoftc.sc_selp = 0; 7816723Sralph logsoftc.sc_pgrp = 0; 7916723Sralph #ifdef LOGDEBUG 8016725Sralph xprintf("logclose: dev=0x%x\n", dev); 8116723Sralph #endif 8216723Sralph } 8316723Sralph 8416723Sralph logread(dev, uio) 8516723Sralph dev_t dev; 8616723Sralph struct uio *uio; 8716723Sralph { 8816723Sralph register long l; 8916723Sralph register u_int c; 9016723Sralph register struct iovec *iov; 9116723Sralph register int s; 9216723Sralph int error = 0; 9316723Sralph 9416723Sralph #ifdef LOGDEBUG 9516725Sralph xprintf("logread: dev=0x%x\n", dev); 9616723Sralph #endif 9716723Sralph 9816723Sralph s = splhigh(); 9916723Sralph while (msgbuf.msg_bufr == msgbuf.msg_bufx) { 10016723Sralph if (logsoftc.sc_state & LOG_NBIO) { 10116723Sralph splx(s); 10216725Sralph return (EWOULDBLOCK); 10316723Sralph } 10416723Sralph logsoftc.sc_state |= LOG_RDWAIT; 10516723Sralph sleep((caddr_t)&msgbuf, LOG_RDPRI); 10616723Sralph } 10716723Sralph splx(s); 10816723Sralph logsoftc.sc_state &= ~LOG_RDWAIT; 10916723Sralph 11016723Sralph while (uio->uio_resid > 0) { 11116723Sralph l = msgbuf.msg_bufx - msgbuf.msg_bufr; 11216723Sralph if (l < 0) 11316723Sralph l = MSG_BSIZE - msgbuf.msg_bufr; 11416723Sralph c = min((u_int) l, (u_int)uio->uio_resid); 11516725Sralph #ifdef LOGDEBUG 11616725Sralph xprintf("logread: bufx=%d, bufr=%d, l=%d, c=%d\n", 11716725Sralph msgbuf.msg_bufx, msgbuf.msg_bufr, l, c); 11816725Sralph #endif 11916725Sralph if (c <= 0) 12016725Sralph break; 12116723Sralph error = uiomove((caddr_t)&msgbuf.msg_bufc[msgbuf.msg_bufr], 12216723Sralph (int)c, UIO_READ, uio); 12316723Sralph if (error) 12416723Sralph break; 12516723Sralph msgbuf.msg_bufr += c; 12616723Sralph if (msgbuf.msg_bufr < 0 || msgbuf.msg_bufr >= MSG_BSIZE) 12716723Sralph msgbuf.msg_bufr = 0; 12816723Sralph } 12916725Sralph return (error); 13016723Sralph } 13116723Sralph 13216723Sralph logselect(dev, rw) 13316723Sralph dev_t dev; 13416723Sralph int rw; 13516723Sralph { 13616723Sralph int s = splhigh(); 13716723Sralph 13816723Sralph switch (rw) { 13916723Sralph 14016723Sralph case FREAD: 14116723Sralph if (msgbuf.msg_bufr != msgbuf.msg_bufx) 14216723Sralph goto win; 14316723Sralph #ifdef LOGDEBUG 14416723Sralph if (logsoftc.sc_selp) 14516725Sralph xprintf("logselect: collision\n"); 14616723Sralph #endif 14716723Sralph logsoftc.sc_selp = u.u_procp; 14816723Sralph break; 14916723Sralph 15016723Sralph case FWRITE: 15116723Sralph #ifdef LOGDEBUG 15216725Sralph xprintf("logselect: FWRITE\n"); 15316723Sralph #endif 15416723Sralph break; 15516723Sralph } 15616723Sralph splx(s); 15716725Sralph return (0); 15816723Sralph win: 15916723Sralph splx(s); 16016725Sralph return (1); 16116723Sralph } 16216723Sralph 16316723Sralph logwakeup() 16416723Sralph { 16516723Sralph 166*18365Skarels if (!log_open) 167*18365Skarels return; 16816723Sralph if (logsoftc.sc_selp) { 16916723Sralph selwakeup(logsoftc.sc_selp, 0); 17016723Sralph logsoftc.sc_selp = 0; 17116723Sralph } 17216723Sralph if (logsoftc.sc_state & LOG_ASYNC) 17316723Sralph gsignal(logsoftc.sc_pgrp, SIGIO); 17416723Sralph if (logsoftc.sc_state & LOG_RDWAIT) { 17516723Sralph wakeup((caddr_t)&msgbuf); 17616723Sralph logsoftc.sc_state &= ~LOG_RDWAIT; 17716723Sralph } 17816723Sralph } 17916723Sralph 18016723Sralph /*ARGSUSED*/ 18116723Sralph logioctl(com, data, flag) 18216723Sralph caddr_t data; 18316723Sralph { 18416723Sralph long l; 18516723Sralph int s; 18616723Sralph 18716723Sralph switch (com) { 18816723Sralph 18916723Sralph /* return number of characters immediately available */ 19016723Sralph case FIONREAD: 19116723Sralph s = splhigh(); 19216723Sralph l = msgbuf.msg_bufx - msgbuf.msg_bufr; 19316723Sralph splx(s); 19416723Sralph if (l < 0) 19516723Sralph l += MSG_BSIZE; 19616723Sralph *(off_t *)data = l; 19716723Sralph break; 19816723Sralph 19916723Sralph case FIONBIO: 20016723Sralph if (*(int *)data) 20116723Sralph logsoftc.sc_state |= LOG_NBIO; 20216723Sralph else 20316723Sralph logsoftc.sc_state &= ~LOG_NBIO; 20416723Sralph break; 20516723Sralph 20616723Sralph case FIOASYNC: 20716723Sralph if (*(int *)data) 20816723Sralph logsoftc.sc_state |= LOG_ASYNC; 20916723Sralph else 21016723Sralph logsoftc.sc_state &= ~LOG_ASYNC; 21116723Sralph break; 21216723Sralph 21316723Sralph case TIOCSPGRP: 21416723Sralph logsoftc.sc_pgrp = *(int *)data; 21516723Sralph break; 21616723Sralph 21716723Sralph case TIOCGPGRP: 21816723Sralph *(int *)data = logsoftc.sc_pgrp; 21916723Sralph break; 22016723Sralph 22116723Sralph default: 22216725Sralph return (-1); 22316723Sralph } 22416725Sralph return (0); 22516723Sralph } 226