1*16725Sralph /* subr_log.c 6.2 84/07/17 */ 216723Sralph 316723Sralph /* 416723Sralph * Error log buffer for kernel printf's. 516723Sralph */ 616723Sralph 716723Sralph #include "../h/param.h" 816723Sralph #include "../h/dir.h" 916723Sralph #include "../h/user.h" 1016723Sralph #include "../h/proc.h" 1116723Sralph #include "../h/ioctl.h" 1216723Sralph #include "../h/msgbuf.h" 1316723Sralph #include "../h/file.h" 1416723Sralph #include "../h/errno.h" 1516723Sralph 1616723Sralph #define LOG_RDPRI (PZERO + 1) 1716723Sralph 1816723Sralph #define LOG_OPEN 0x01 1916723Sralph #define LOG_NBIO 0x02 2016723Sralph #define LOG_ASYNC 0x04 2116723Sralph #define LOG_RDWAIT 0x08 2216723Sralph 2316723Sralph struct logsoftc { 2416723Sralph int sc_state; /* see above for possibilities */ 2516723Sralph struct proc *sc_selp; /* process waiting on select call */ 2616723Sralph int sc_pgrp; /* process group for async I/O */ 2716723Sralph } logsoftc; 2816723Sralph 29*16725Sralph #ifdef LOGDEBUG 30*16725Sralph /*VARARGS1*/ 31*16725Sralph xprintf(fmt, x1) 32*16725Sralph char *fmt; 33*16725Sralph unsigned x1; 34*16725Sralph { 35*16725Sralph 36*16725Sralph prf(fmt, &x1, 1, (struct tty *)0); 37*16725Sralph } 38*16725Sralph #endif 39*16725Sralph 4016723Sralph logopen(dev) 4116723Sralph dev_t dev; 4216723Sralph { 4316723Sralph 4416723Sralph #ifdef LOGDEBUG 45*16725Sralph xprintf("logopen: dev=0x%x\n", dev); 4616723Sralph #endif 4716723Sralph if (logsoftc.sc_state & LOG_OPEN) 48*16725Sralph return (EBUSY); 4916723Sralph logsoftc.sc_state |= LOG_OPEN; 5016723Sralph logsoftc.sc_selp = 0; 5116723Sralph logsoftc.sc_pgrp = u.u_procp->p_pgrp; 5216723Sralph /* 5316723Sralph * Potential race here with putchar() but since putchar should be 5416723Sralph * called by autoconf, msg_magic should be initialized by the time 5516723Sralph * we get here. 5616723Sralph */ 5716723Sralph if (msgbuf.msg_magic != MSG_MAGIC) { 5816723Sralph register int i; 5916723Sralph 6016723Sralph msgbuf.msg_magic = MSG_MAGIC; 6116723Sralph msgbuf.msg_bufx = msgbuf.msg_bufr = 0; 6216723Sralph for (i=0; i < MSG_BSIZE; i++) 6316723Sralph msgbuf.msg_bufc[i] = 0; 6416723Sralph } 65*16725Sralph #ifdef LOGDEBUG 66*16725Sralph xprintf("logopen: bufx=%d, bufr=%d\n", msgbuf.msg_bufx, msgbuf.msg_bufr); 67*16725Sralph #endif 68*16725Sralph return (0); 6916723Sralph } 7016723Sralph 7116723Sralph logclose(dev, flag) 7216723Sralph dev_t dev; 7316723Sralph { 7416723Sralph logsoftc.sc_state = 0; 7516723Sralph logsoftc.sc_selp = 0; 7616723Sralph logsoftc.sc_pgrp = 0; 7716723Sralph #ifdef LOGDEBUG 78*16725Sralph xprintf("logclose: dev=0x%x\n", dev); 7916723Sralph #endif 8016723Sralph } 8116723Sralph 8216723Sralph logread(dev, uio) 8316723Sralph dev_t dev; 8416723Sralph struct uio *uio; 8516723Sralph { 8616723Sralph register long l; 8716723Sralph register u_int c; 8816723Sralph register struct iovec *iov; 8916723Sralph register int s; 9016723Sralph int error = 0; 9116723Sralph 9216723Sralph #ifdef LOGDEBUG 93*16725Sralph xprintf("logread: dev=0x%x\n", dev); 9416723Sralph #endif 9516723Sralph 9616723Sralph s = splhigh(); 9716723Sralph while (msgbuf.msg_bufr == msgbuf.msg_bufx) { 9816723Sralph if (logsoftc.sc_state & LOG_NBIO) { 9916723Sralph splx(s); 100*16725Sralph return (EWOULDBLOCK); 10116723Sralph } 10216723Sralph logsoftc.sc_state |= LOG_RDWAIT; 10316723Sralph sleep((caddr_t)&msgbuf, LOG_RDPRI); 10416723Sralph } 10516723Sralph splx(s); 10616723Sralph logsoftc.sc_state &= ~LOG_RDWAIT; 10716723Sralph 10816723Sralph while (uio->uio_resid > 0) { 10916723Sralph l = msgbuf.msg_bufx - msgbuf.msg_bufr; 11016723Sralph if (l < 0) 11116723Sralph l = MSG_BSIZE - msgbuf.msg_bufr; 11216723Sralph c = min((u_int) l, (u_int)uio->uio_resid); 113*16725Sralph #ifdef LOGDEBUG 114*16725Sralph xprintf("logread: bufx=%d, bufr=%d, l=%d, c=%d\n", 115*16725Sralph msgbuf.msg_bufx, msgbuf.msg_bufr, l, c); 116*16725Sralph #endif 117*16725Sralph if (c <= 0) 118*16725Sralph break; 11916723Sralph error = uiomove((caddr_t)&msgbuf.msg_bufc[msgbuf.msg_bufr], 12016723Sralph (int)c, UIO_READ, uio); 12116723Sralph if (error) 12216723Sralph break; 12316723Sralph msgbuf.msg_bufr += c; 12416723Sralph if (msgbuf.msg_bufr < 0 || msgbuf.msg_bufr >= MSG_BSIZE) 12516723Sralph msgbuf.msg_bufr = 0; 12616723Sralph } 127*16725Sralph return (error); 12816723Sralph } 12916723Sralph 13016723Sralph logselect(dev, rw) 13116723Sralph dev_t dev; 13216723Sralph int rw; 13316723Sralph { 13416723Sralph int s = splhigh(); 13516723Sralph 13616723Sralph switch (rw) { 13716723Sralph 13816723Sralph case FREAD: 13916723Sralph if (msgbuf.msg_bufr != msgbuf.msg_bufx) 14016723Sralph goto win; 14116723Sralph #ifdef LOGDEBUG 14216723Sralph if (logsoftc.sc_selp) 143*16725Sralph xprintf("logselect: collision\n"); 14416723Sralph #endif 14516723Sralph logsoftc.sc_selp = u.u_procp; 14616723Sralph break; 14716723Sralph 14816723Sralph case FWRITE: 14916723Sralph #ifdef LOGDEBUG 150*16725Sralph xprintf("logselect: FWRITE\n"); 15116723Sralph #endif 15216723Sralph break; 15316723Sralph } 15416723Sralph splx(s); 155*16725Sralph return (0); 15616723Sralph win: 15716723Sralph splx(s); 158*16725Sralph return (1); 15916723Sralph } 16016723Sralph 16116723Sralph logwakeup() 16216723Sralph { 16316723Sralph 16416723Sralph if (logsoftc.sc_selp) { 16516723Sralph selwakeup(logsoftc.sc_selp, 0); 16616723Sralph logsoftc.sc_selp = 0; 16716723Sralph } 16816723Sralph if (logsoftc.sc_state & LOG_ASYNC) 16916723Sralph gsignal(logsoftc.sc_pgrp, SIGIO); 17016723Sralph if (logsoftc.sc_state & LOG_RDWAIT) { 17116723Sralph wakeup((caddr_t)&msgbuf); 17216723Sralph logsoftc.sc_state &= ~LOG_RDWAIT; 17316723Sralph } 17416723Sralph } 17516723Sralph 17616723Sralph /*ARGSUSED*/ 17716723Sralph logioctl(com, data, flag) 17816723Sralph caddr_t data; 17916723Sralph { 18016723Sralph long l; 18116723Sralph int s; 18216723Sralph 18316723Sralph switch (com) { 18416723Sralph 18516723Sralph /* return number of characters immediately available */ 18616723Sralph case FIONREAD: 18716723Sralph s = splhigh(); 18816723Sralph l = msgbuf.msg_bufx - msgbuf.msg_bufr; 18916723Sralph splx(s); 19016723Sralph if (l < 0) 19116723Sralph l += MSG_BSIZE; 19216723Sralph *(off_t *)data = l; 19316723Sralph break; 19416723Sralph 19516723Sralph case FIONBIO: 19616723Sralph if (*(int *)data) 19716723Sralph logsoftc.sc_state |= LOG_NBIO; 19816723Sralph else 19916723Sralph logsoftc.sc_state &= ~LOG_NBIO; 20016723Sralph break; 20116723Sralph 20216723Sralph case FIOASYNC: 20316723Sralph if (*(int *)data) 20416723Sralph logsoftc.sc_state |= LOG_ASYNC; 20516723Sralph else 20616723Sralph logsoftc.sc_state &= ~LOG_ASYNC; 20716723Sralph break; 20816723Sralph 20916723Sralph case TIOCSPGRP: 21016723Sralph logsoftc.sc_pgrp = *(int *)data; 21116723Sralph break; 21216723Sralph 21316723Sralph case TIOCGPGRP: 21416723Sralph *(int *)data = logsoftc.sc_pgrp; 21516723Sralph break; 21616723Sralph 21716723Sralph default: 218*16725Sralph return (-1); 21916723Sralph } 220*16725Sralph return (0); 22116723Sralph } 222