1*16723Sralph /* subr_log.c 6.1 84/07/16 */ 2*16723Sralph 3*16723Sralph /* 4*16723Sralph * Error log buffer for kernel printf's. 5*16723Sralph */ 6*16723Sralph 7*16723Sralph #include "../h/param.h" 8*16723Sralph #include "../h/dir.h" 9*16723Sralph #include "../h/user.h" 10*16723Sralph #include "../h/proc.h" 11*16723Sralph #include "../h/ioctl.h" 12*16723Sralph #include "../h/msgbuf.h" 13*16723Sralph #include "../h/file.h" 14*16723Sralph #include "../h/errno.h" 15*16723Sralph 16*16723Sralph #define LOG_RDPRI (PZERO + 1) 17*16723Sralph 18*16723Sralph #define LOG_OPEN 0x01 19*16723Sralph #define LOG_NBIO 0x02 20*16723Sralph #define LOG_ASYNC 0x04 21*16723Sralph #define LOG_RDWAIT 0x08 22*16723Sralph 23*16723Sralph struct logsoftc { 24*16723Sralph int sc_state; /* see above for possibilities */ 25*16723Sralph struct proc *sc_selp; /* process waiting on select call */ 26*16723Sralph int sc_pgrp; /* process group for async I/O */ 27*16723Sralph } logsoftc; 28*16723Sralph 29*16723Sralph logopen(dev) 30*16723Sralph dev_t dev; 31*16723Sralph { 32*16723Sralph 33*16723Sralph #ifdef LOGDEBUG 34*16723Sralph printf("logopen: dev=0x%x\n", dev); 35*16723Sralph #endif 36*16723Sralph if (logsoftc.sc_state & LOG_OPEN) 37*16723Sralph return(EBUSY); 38*16723Sralph logsoftc.sc_state |= LOG_OPEN; 39*16723Sralph logsoftc.sc_selp = 0; 40*16723Sralph logsoftc.sc_pgrp = u.u_procp->p_pgrp; 41*16723Sralph /* 42*16723Sralph * Potential race here with putchar() but since putchar should be 43*16723Sralph * called by autoconf, msg_magic should be initialized by the time 44*16723Sralph * we get here. 45*16723Sralph */ 46*16723Sralph if (msgbuf.msg_magic != MSG_MAGIC) { 47*16723Sralph register int i; 48*16723Sralph 49*16723Sralph msgbuf.msg_magic = MSG_MAGIC; 50*16723Sralph msgbuf.msg_bufx = msgbuf.msg_bufr = 0; 51*16723Sralph for (i=0; i < MSG_BSIZE; i++) 52*16723Sralph msgbuf.msg_bufc[i] = 0; 53*16723Sralph } 54*16723Sralph return(0); 55*16723Sralph } 56*16723Sralph 57*16723Sralph logclose(dev, flag) 58*16723Sralph dev_t dev; 59*16723Sralph { 60*16723Sralph logsoftc.sc_state = 0; 61*16723Sralph logsoftc.sc_selp = 0; 62*16723Sralph logsoftc.sc_pgrp = 0; 63*16723Sralph #ifdef LOGDEBUG 64*16723Sralph printf("logclose: dev=0x%x\n", dev); 65*16723Sralph #endif 66*16723Sralph } 67*16723Sralph 68*16723Sralph logread(dev, uio) 69*16723Sralph dev_t dev; 70*16723Sralph struct uio *uio; 71*16723Sralph { 72*16723Sralph register long l; 73*16723Sralph register u_int c; 74*16723Sralph register struct iovec *iov; 75*16723Sralph register int s; 76*16723Sralph int error = 0; 77*16723Sralph 78*16723Sralph #ifdef LOGDEBUG 79*16723Sralph printf("logread: dev=0x%x\n", dev); 80*16723Sralph #endif 81*16723Sralph 82*16723Sralph s = splhigh(); 83*16723Sralph while (msgbuf.msg_bufr == msgbuf.msg_bufx) { 84*16723Sralph if (logsoftc.sc_state & LOG_NBIO) { 85*16723Sralph splx(s); 86*16723Sralph return(EWOULDBLOCK); 87*16723Sralph } 88*16723Sralph logsoftc.sc_state |= LOG_RDWAIT; 89*16723Sralph sleep((caddr_t)&msgbuf, LOG_RDPRI); 90*16723Sralph } 91*16723Sralph splx(s); 92*16723Sralph logsoftc.sc_state &= ~LOG_RDWAIT; 93*16723Sralph 94*16723Sralph while (uio->uio_resid > 0) { 95*16723Sralph l = msgbuf.msg_bufx - msgbuf.msg_bufr; 96*16723Sralph if (l < 0) 97*16723Sralph l = MSG_BSIZE - msgbuf.msg_bufr; 98*16723Sralph c = min((u_int) l, (u_int)uio->uio_resid); 99*16723Sralph error = uiomove((caddr_t)&msgbuf.msg_bufc[msgbuf.msg_bufr], 100*16723Sralph (int)c, UIO_READ, uio); 101*16723Sralph if (error) 102*16723Sralph break; 103*16723Sralph msgbuf.msg_bufr += c; 104*16723Sralph if (msgbuf.msg_bufr < 0 || msgbuf.msg_bufr >= MSG_BSIZE) 105*16723Sralph msgbuf.msg_bufr = 0; 106*16723Sralph } 107*16723Sralph return(error); 108*16723Sralph } 109*16723Sralph 110*16723Sralph logselect(dev, rw) 111*16723Sralph dev_t dev; 112*16723Sralph int rw; 113*16723Sralph { 114*16723Sralph int s = splhigh(); 115*16723Sralph 116*16723Sralph switch (rw) { 117*16723Sralph 118*16723Sralph case FREAD: 119*16723Sralph if (msgbuf.msg_bufr != msgbuf.msg_bufx) 120*16723Sralph goto win; 121*16723Sralph #ifdef LOGDEBUG 122*16723Sralph if (logsoftc.sc_selp) 123*16723Sralph printf("logselect: collision\n"); 124*16723Sralph #endif 125*16723Sralph logsoftc.sc_selp = u.u_procp; 126*16723Sralph break; 127*16723Sralph 128*16723Sralph case FWRITE: 129*16723Sralph #ifdef LOGDEBUG 130*16723Sralph printf("logselect: FWRITE\n"); 131*16723Sralph #endif 132*16723Sralph break; 133*16723Sralph } 134*16723Sralph splx(s); 135*16723Sralph return(0); 136*16723Sralph win: 137*16723Sralph splx(s); 138*16723Sralph return(1); 139*16723Sralph } 140*16723Sralph 141*16723Sralph logwakeup() 142*16723Sralph { 143*16723Sralph 144*16723Sralph if (logsoftc.sc_selp) { 145*16723Sralph selwakeup(logsoftc.sc_selp, 0); 146*16723Sralph logsoftc.sc_selp = 0; 147*16723Sralph } 148*16723Sralph if (logsoftc.sc_state & LOG_ASYNC) 149*16723Sralph gsignal(logsoftc.sc_pgrp, SIGIO); 150*16723Sralph if (logsoftc.sc_state & LOG_RDWAIT) { 151*16723Sralph wakeup((caddr_t)&msgbuf); 152*16723Sralph logsoftc.sc_state &= ~LOG_RDWAIT; 153*16723Sralph } 154*16723Sralph } 155*16723Sralph 156*16723Sralph /*ARGSUSED*/ 157*16723Sralph logioctl(com, data, flag) 158*16723Sralph caddr_t data; 159*16723Sralph { 160*16723Sralph long l; 161*16723Sralph int s; 162*16723Sralph 163*16723Sralph switch (com) { 164*16723Sralph 165*16723Sralph /* return number of characters immediately available */ 166*16723Sralph case FIONREAD: 167*16723Sralph s = splhigh(); 168*16723Sralph l = msgbuf.msg_bufx - msgbuf.msg_bufr; 169*16723Sralph splx(s); 170*16723Sralph if (l < 0) 171*16723Sralph l += MSG_BSIZE; 172*16723Sralph *(off_t *)data = l; 173*16723Sralph break; 174*16723Sralph 175*16723Sralph case FIONBIO: 176*16723Sralph if (*(int *)data) 177*16723Sralph logsoftc.sc_state |= LOG_NBIO; 178*16723Sralph else 179*16723Sralph logsoftc.sc_state &= ~LOG_NBIO; 180*16723Sralph break; 181*16723Sralph 182*16723Sralph case FIOASYNC: 183*16723Sralph if (*(int *)data) 184*16723Sralph logsoftc.sc_state |= LOG_ASYNC; 185*16723Sralph else 186*16723Sralph logsoftc.sc_state &= ~LOG_ASYNC; 187*16723Sralph break; 188*16723Sralph 189*16723Sralph case TIOCSPGRP: 190*16723Sralph logsoftc.sc_pgrp = *(int *)data; 191*16723Sralph break; 192*16723Sralph 193*16723Sralph case TIOCGPGRP: 194*16723Sralph *(int *)data = logsoftc.sc_pgrp; 195*16723Sralph break; 196*16723Sralph 197*16723Sralph default: 198*16723Sralph return(-1); 199*16723Sralph } 200*16723Sralph return(0); 201*16723Sralph } 202