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