subr_log.c revision 41087
16562Sphk/* 237421Scharnier * Copyright (c) 1982, 1986, 1993 36562Sphk * The Regents of the University of California. All rights reserved. 46562Sphk * 53995Spst * Redistribution and use in source and binary forms, with or without 63995Spst * modification, are permitted provided that the following conditions 76562Sphk * are met: 86562Sphk * 1. Redistributions of source code must retain the above copyright 96562Sphk * notice, this list of conditions and the following disclaimer. 106562Sphk * 2. Redistributions in binary form must reproduce the above copyright 116562Sphk * notice, this list of conditions and the following disclaimer in the 126562Sphk * documentation and/or other materials provided with the distribution. 136562Sphk * 3. All advertising materials mentioning features or use of this software 146562Sphk * must display the following acknowledgement: 156562Sphk * This product includes software developed by the University of 166562Sphk * California, Berkeley and its contributors. 176562Sphk * 4. Neither the name of the University nor the names of its contributors 183995Spst * may be used to endorse or promote products derived from this software 193995Spst * without specific prior written permission. 2037421Scharnier * 2137421Scharnier * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2250476Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2337421Scharnier * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2437421Scharnier * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2519168Sbde * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2637421Scharnier * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2719168Sbde * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 283995Spst * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2978949Sdes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3078949Sdes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 313995Spst * SUCH DAMAGE. 3232074Ssteve * 3319168Sbde * @(#)subr_log.c 8.1 (Berkeley) 6/10/93 346562Sphk * $Id: subr_log.c,v 1.31 1998/11/11 10:03:55 truckman Exp $ 356562Sphk */ 363995Spst 3746226Skris/* 3846226Skris * Error log buffer for kernel printf's. 393995Spst */ 4054109Sobrien 4152949Sobrien#include "opt_devfs.h" 4288226Sphk 4352949Sobrien#include <sys/param.h> 4476988Sru#include <sys/systm.h> 4576988Sru#include <sys/conf.h> 4676988Sru#include <sys/proc.h> 4776988Sru#include <sys/vnode.h> 4876988Sru#include <sys/filio.h> 493995Spst#include <sys/ttycom.h> 503995Spst#include <sys/msgbuf.h> 513995Spst#include <sys/signalvar.h> 523995Spst#include <sys/kernel.h> 533995Spst#include <sys/poll.h> 543995Spst#include <sys/filedesc.h> 553995Spst#ifdef DEVFS 563995Spst#include <sys/devfsext.h> 573995Spst#endif /*DEVFS*/ 583995Spst 596562Sphk#define LOG_RDPRI (PZERO + 1) 6076988Sru 613995Spst#define LOG_ASYNC 0x04 6232086Ssteve#define LOG_RDWAIT 0x08 636562Sphk 649489Sphkstatic d_open_t logopen; 653995Spststatic d_close_t logclose; 6678756Srustatic d_read_t logread; 6776988Srustatic d_ioctl_t logioctl; 6876988Srustatic d_poll_t logpoll; 6976988Sru 7076988Sru#define CDEV_MAJOR 7 7176988Srustatic struct cdevsw log_cdevsw = 7276988Sru { logopen, logclose, logread, nowrite, /*7*/ 7376988Sru logioctl, nostop, nullreset, nodevtotty,/* klog */ 7476988Sru logpoll, nommap, NULL, "log", NULL, -1 }; 7576988Sru 7676988Srustatic struct logsoftc { 7776988Sru int sc_state; /* see above for possibilities */ 7888226Sphk struct selinfo sc_selp; /* process waiting on select call */ 7976988Sru struct sigio *sc_sigio; /* information for async I/O */ 8076988Sru} logsoftc; 8176988Sru 8276988Sruint log_open; /* also used in log() */ 8376988Sru 8476988Sru/*ARGSUSED*/ 8576988Srustatic int 8676988Srulogopen(dev, flags, mode, p) 8776988Sru dev_t dev; 8876988Sru int flags, mode; 8932074Ssteve struct proc *p; 9076988Sru{ 9176988Sru if (log_open) 9276988Sru return (EBUSY); 9376988Sru log_open = 1; 9476988Sru fsetown(p->p_pid, &logsoftc.sc_sigio); /* signal process only */ 9576988Sru return (0); 9632074Ssteve} 9776988Sru 9832074Ssteve/*ARGSUSED*/ 9954109Sobrienstatic int 10054109Sobrienlogclose(dev, flag, mode, p) 10154109Sobrien dev_t dev; 10276988Sru int flag, mode; 10352949Sobrien struct proc *p; 10476988Sru{ 10576988Sru 10688226Sphk log_open = 0; 1076725Sphk logsoftc.sc_state = 0; 1083995Spst funsetown(logsoftc.sc_sigio); 1096562Sphk return (0); 1103995Spst} 1116562Sphk 1126562Sphk/*ARGSUSED*/ 1133995Spststatic int 1146562Sphklogread(dev, uio, flag) 11576988Sru dev_t dev; 1163995Spst struct uio *uio; 11748953Sbillf int flag; 1189489Sphk{ 1193995Spst register struct msgbuf *mbp = msgbufp; 12054109Sobrien register long l; 12154109Sobrien register int s; 12254109Sobrien int error = 0; 12353092Sobrien 12452949Sobrien s = splhigh(); 12552949Sobrien while (mbp->msg_bufr == mbp->msg_bufx) { 1263995Spst if (flag & IO_NDELAY) { 1276562Sphk splx(s); 1286562Sphk return (EWOULDBLOCK); 1293995Spst } 1306562Sphk logsoftc.sc_state |= LOG_RDWAIT; 13176988Sru if ((error = tsleep((caddr_t)mbp, LOG_RDPRI | PCATCH, 1323995Spst "klog", 0))) { 1336562Sphk splx(s); 1346562Sphk return (error); 1356725Sphk } 1366562Sphk } 1379489Sphk splx(s); 1383995Spst logsoftc.sc_state &= ~LOG_RDWAIT; 1396562Sphk 1406562Sphk while (uio->uio_resid > 0) { 14121763Sphk l = mbp->msg_bufx - mbp->msg_bufr; 14246226Skris if (l < 0) 1433995Spst l = mbp->msg_size - mbp->msg_bufr; 1446562Sphk l = min(l, uio->uio_resid); 1456562Sphk if (l == 0) 1466562Sphk break; 1473995Spst error = uiomove((caddr_t)msgbufp->msg_ptr + mbp->msg_bufr, 1486562Sphk (int)l, uio); 1496562Sphk if (error) 1503995Spst break; 1516562Sphk mbp->msg_bufr += l; 1526562Sphk if (mbp->msg_bufr >= mbp->msg_size) 1536562Sphk mbp->msg_bufr = 0; 1546562Sphk } 1559489Sphk return (error); 1563995Spst} 1576562Sphk 1586562Sphk/*ARGSUSED*/ 1593995Spststatic int 1606562Sphklogpoll(dev, events, p) 1616562Sphk dev_t dev; 1626562Sphk int events; 1636562Sphk struct proc *p; 1646562Sphk{ 1656562Sphk int s; 1666562Sphk int revents = 0; 16785611Sdillon 1683995Spst s = splhigh(); 1696562Sphk 1706562Sphk if (events & (POLLIN | POLLRDNORM)) 1713995Spst if (msgbufp->msg_bufr != msgbufp->msg_bufx) 172109870Ssilby revents |= events & (POLLIN | POLLRDNORM); 173109870Ssilby else 174109870Ssilby selrecord(p, &logsoftc.sc_selp); 175109870Ssilby 176109870Ssilby splx(s); 177109870Ssilby return (revents); 178109870Ssilby} 179109870Ssilby 180109870Ssilbyvoid 181109870Ssilbylogwakeup() 182109870Ssilby{ 183109870Ssilby struct proc *p; 184109870Ssilby 185109870Ssilby if (!log_open) 186109870Ssilby return; 187109870Ssilby selwakeup(&logsoftc.sc_selp); 188109870Ssilby if ((logsoftc.sc_state & LOG_ASYNC) && logsoftc.sc_sigio != NULL) 189109870Ssilby pgsigio(logsoftc.sc_sigio, SIGIO, 0); 190109870Ssilby if (logsoftc.sc_state & LOG_RDWAIT) { 191109870Ssilby wakeup((caddr_t)msgbufp); 192109870Ssilby logsoftc.sc_state &= ~LOG_RDWAIT; 193109870Ssilby } 194109870Ssilby} 195109870Ssilby 196109870Ssilby/*ARGSUSED*/ 1976562Sphkstatic int 19876988Srulogioctl(dev, com, data, flag, p) 1993995Spst dev_t dev; 200109870Ssilby u_long com; 201109870Ssilby caddr_t data; 20232086Ssteve int flag; 2036562Sphk struct proc *p; 204109870Ssilby{ 205109870Ssilby long l; 206109870Ssilby int s; 207109870Ssilby 208109870Ssilby switch (com) { 209109870Ssilby 210109870Ssilby /* return number of characters immediately available */ 211109870Ssilby case FIONREAD: 2123995Spst s = splhigh(); 2133995Spst l = msgbufp->msg_bufx - msgbufp->msg_bufr; 2146562Sphk splx(s); 2156562Sphk if (l < 0) 2163995Spst l += msgbufp->msg_size; 2176562Sphk *(int *)data = l; 21876988Sru break; 2193995Spst 2206562Sphk case FIONBIO: 22176988Sru break; 22232074Ssteve 2239489Sphk case FIOASYNC: 2243995Spst if (*(int *)data) 2256562Sphk logsoftc.sc_state |= LOG_ASYNC; 22632074Ssteve else 22776988Sru logsoftc.sc_state &= ~LOG_ASYNC; 22837421Scharnier break; 2296562Sphk 2306725Sphk case FIOSETOWN: 2319489Sphk return (fsetown(*(int *)data, &logsoftc.sc_sigio)); 2323995Spst 23332074Ssteve case FIOGETOWN: 23432074Ssteve *(int *)data = fgetown(logsoftc.sc_sigio); 23576988Sru break; 23632074Ssteve 23732086Ssteve /* This is deprecated, FIOSETOWN should be used instead. */ 23868503Sobrien case TIOCSPGRP: 23932074Ssteve return (fsetown(-(*(int *)data), &logsoftc.sc_sigio)); 24032074Ssteve 241 /* This is deprecated, FIOGETOWN should be used instead */ 242 case TIOCGPGRP: 243 *(int *)data = -fgetown(logsoftc.sc_sigio); 244 break; 245 246 default: 247 return (ENOTTY); 248 } 249 return (0); 250} 251 252static int log_devsw_installed; 253#ifdef DEVFS 254static void *log_devfs_token; 255#endif 256 257static void log_drvinit __P((void *unused)); 258static void 259log_drvinit(unused) 260 void *unused; 261{ 262 dev_t dev; 263 264 if( ! log_devsw_installed ) { 265 dev = makedev(CDEV_MAJOR,0); 266 cdevsw_add(&dev,&log_cdevsw,NULL); 267 log_devsw_installed = 1; 268#ifdef DEVFS 269 log_devfs_token = devfs_add_devswf(&log_cdevsw, 0, DV_CHR, 270 UID_ROOT, GID_WHEEL, 0600, 271 "klog"); 272#endif 273 } 274} 275 276SYSINIT(logdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,log_drvinit,NULL) 277