The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/subr_log.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 1982, 1986, 1993
    3  *      The Regents of the University of California.  All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  * 3. All advertising materials mentioning features or use of this software
   14  *    must display the following acknowledgement:
   15  *      This product includes software developed by the University of
   16  *      California, Berkeley and its contributors.
   17  * 4. Neither the name of the University nor the names of its contributors
   18  *    may be used to endorse or promote products derived from this software
   19  *    without specific prior written permission.
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   31  * SUCH DAMAGE.
   32  *
   33  *      @(#)subr_log.c  8.1 (Berkeley) 6/10/93
   34  * $FreeBSD: src/sys/kern/subr_log.c,v 1.18.2.2 1999/09/05 08:15:12 peter Exp $
   35  */
   36 
   37 /*
   38  * Error log buffer for kernel printf's.
   39  */
   40 
   41 #include <sys/param.h>
   42 #include <sys/systm.h>
   43 #include <sys/conf.h>
   44 #include <sys/proc.h>
   45 #include <sys/vnode.h>
   46 #include <sys/ioctl.h>
   47 #include <sys/msgbuf.h>
   48 #include <sys/file.h>
   49 #include <sys/signalvar.h>
   50 #include <sys/kernel.h>
   51 #ifdef DEVFS
   52 #include <sys/devfsext.h>
   53 #endif /*DEVFS*/
   54 
   55 #define LOG_RDPRI       (PZERO + 1)
   56 
   57 #define LOG_ASYNC       0x04
   58 #define LOG_RDWAIT      0x08
   59 
   60 static  d_open_t        logopen;
   61 static  d_close_t       logclose;
   62 static  d_read_t        logread;
   63 static  d_ioctl_t       logioctl;
   64 static  d_select_t      logselect;
   65 
   66 #define CDEV_MAJOR 7
   67 static struct cdevsw log_cdevsw = 
   68         { logopen,      logclose,       logread,        nowrite,        /*7*/
   69           logioctl,     nostop,         nullreset,      nodevtotty,/* klog */
   70           logselect,    nommap,         NULL,   "log",  NULL,   -1 };
   71 
   72 static struct logsoftc {
   73         int     sc_state;               /* see above for possibilities */
   74         struct  selinfo sc_selp;        /* process waiting on select call */
   75         int     sc_pgid;                /* process/group for async I/O */
   76 } logsoftc;
   77 
   78 int     log_open;                       /* also used in log() */
   79 
   80 /*ARGSUSED*/
   81 static  int
   82 logopen(dev, flags, mode, p)
   83         dev_t dev;
   84         int flags, mode;
   85         struct proc *p;
   86 {
   87         if (log_open)
   88                 return (EBUSY);
   89         log_open = 1;
   90         logsoftc.sc_pgid = p->p_pid;            /* signal process only */
   91         return (0);
   92 }
   93 
   94 /*ARGSUSED*/
   95 static  int
   96 logclose(dev, flag, mode, p)
   97         dev_t dev;
   98         int flag, mode;
   99         struct proc *p;
  100 {
  101 
  102         log_open = 0;
  103         logsoftc.sc_state = 0;
  104         return (0);
  105 }
  106 
  107 /*ARGSUSED*/
  108 static  int
  109 logread(dev, uio, flag)
  110         dev_t dev;
  111         struct uio *uio;
  112         int flag;
  113 {
  114         register struct msgbuf *mbp = msgbufp;
  115         register long l;
  116         register int s;
  117         int error = 0;
  118 
  119         s = splhigh();
  120         while (mbp->msg_bufr == mbp->msg_bufx) {
  121                 if (flag & IO_NDELAY) {
  122                         splx(s);
  123                         return (EWOULDBLOCK);
  124                 }
  125                 logsoftc.sc_state |= LOG_RDWAIT;
  126                 if ((error = tsleep((caddr_t)mbp, LOG_RDPRI | PCATCH,
  127                     "klog", 0))) {
  128                         splx(s);
  129                         return (error);
  130                 }
  131         }
  132         splx(s);
  133         logsoftc.sc_state &= ~LOG_RDWAIT;
  134 
  135         while (uio->uio_resid > 0) {
  136                 l = mbp->msg_bufx - mbp->msg_bufr;
  137                 if (l < 0)
  138                         l = mbp->msg_size - mbp->msg_bufr;
  139                 l = min(l, uio->uio_resid);
  140                 if (l == 0)
  141                         break;
  142                 error = uiomove((caddr_t)msgbufp->msg_ptr + mbp->msg_bufr,
  143                     (int)l, uio);
  144                 if (error)
  145                         break;
  146                 mbp->msg_bufr += l;
  147                 if (mbp->msg_bufr >= mbp->msg_size)
  148                         mbp->msg_bufr = 0;
  149         }
  150         return (error);
  151 }
  152 
  153 /*ARGSUSED*/
  154 static  int
  155 logselect(dev, rw, p)
  156         dev_t dev;
  157         int rw;
  158         struct proc *p;
  159 {
  160         int s = splhigh();
  161 
  162         switch (rw) {
  163 
  164         case FREAD:
  165                 if (msgbufp->msg_bufr != msgbufp->msg_bufx) {
  166                         splx(s);
  167                         return (1);
  168                 }
  169                 selrecord(p, &logsoftc.sc_selp);
  170                 break;
  171         }
  172         splx(s);
  173         return (0);
  174 }
  175 
  176 void
  177 logwakeup()
  178 {
  179         struct proc *p;
  180 
  181         if (!log_open)
  182                 return;
  183         selwakeup(&logsoftc.sc_selp);
  184         if (logsoftc.sc_state & LOG_ASYNC) {
  185                 if (logsoftc.sc_pgid < 0)
  186                         gsignal(-logsoftc.sc_pgid, SIGIO);
  187                 else if ((p = pfind(logsoftc.sc_pgid)))
  188                         psignal(p, SIGIO);
  189         }
  190         if (logsoftc.sc_state & LOG_RDWAIT) {
  191                 wakeup((caddr_t)msgbufp);
  192                 logsoftc.sc_state &= ~LOG_RDWAIT;
  193         }
  194 }
  195 
  196 /*ARGSUSED*/
  197 static  int
  198 logioctl(dev, com, data, flag, p)
  199         dev_t dev;
  200         int com;
  201         caddr_t data;
  202         int flag;
  203         struct proc *p;
  204 {
  205         long l;
  206         int s;
  207 
  208         switch (com) {
  209 
  210         /* return number of characters immediately available */
  211         case FIONREAD:
  212                 s = splhigh();
  213                 l = msgbufp->msg_bufx - msgbufp->msg_bufr;
  214                 splx(s);
  215                 if (l < 0)
  216                         l += msgbufp->msg_size;
  217                 *(int *)data = l;
  218                 break;
  219 
  220         case FIONBIO:
  221                 break;
  222 
  223         case FIOASYNC:
  224                 if (*(int *)data)
  225                         logsoftc.sc_state |= LOG_ASYNC;
  226                 else
  227                         logsoftc.sc_state &= ~LOG_ASYNC;
  228                 break;
  229 
  230         case TIOCSPGRP:
  231                 logsoftc.sc_pgid = *(int *)data;
  232                 break;
  233 
  234         case TIOCGPGRP:
  235                 *(int *)data = logsoftc.sc_pgid;
  236                 break;
  237 
  238         default:
  239                 return (ENOTTY);
  240         }
  241         return (0);
  242 }
  243 
  244 static log_devsw_installed = 0;
  245 #ifdef DEVFS
  246 static  void    *log_devfs_token;
  247 #endif
  248 
  249 static void
  250 log_drvinit(void *unused)
  251 {
  252         dev_t dev;
  253 
  254         if( ! log_devsw_installed ) {
  255                 dev = makedev(CDEV_MAJOR,0);
  256                 cdevsw_add(&dev,&log_cdevsw,NULL);
  257                 log_devsw_installed = 1;
  258 #ifdef DEVFS
  259                 log_devfs_token = devfs_add_devswf(&log_cdevsw, 0, DV_CHR,
  260                                                    UID_ROOT, GID_WHEEL, 0600,
  261                                                    "klog");
  262 #endif
  263         }
  264 }
  265 
  266 SYSINIT(logdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,log_drvinit,NULL)
  267 
  268 

Cache object: 9dcc90e2f02a4e10f49556726c0f05c2


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.