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: releng/5.1/sys/kern/subr_log.c 111815 2003-03-03 12:15:54Z phk $
   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/filio.h>
   47 #include <sys/ttycom.h>
   48 #include <sys/msgbuf.h>
   49 #include <sys/signalvar.h>
   50 #include <sys/kernel.h>
   51 #include <sys/poll.h>
   52 #include <sys/filedesc.h>
   53 #include <sys/sysctl.h>
   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_poll_t        logpoll;
   65 
   66 static  void logtimeout(void *arg);
   67 
   68 #define CDEV_MAJOR 7
   69 static struct cdevsw log_cdevsw = {
   70         .d_open =       logopen,
   71         .d_close =      logclose,
   72         .d_read =       logread,
   73         .d_ioctl =      logioctl,
   74         .d_poll =       logpoll,
   75         .d_name =       "log",
   76         .d_maj =        CDEV_MAJOR,
   77 };
   78 
   79 static struct logsoftc {
   80         int     sc_state;               /* see above for possibilities */
   81         struct  selinfo sc_selp;        /* process waiting on select call */
   82         struct  sigio *sc_sigio;        /* information for async I/O */
   83         struct  callout sc_callout;     /* callout to wakeup syslog  */
   84 } logsoftc;
   85 
   86 int     log_open;                       /* also used in log() */
   87 
   88 /* Times per second to check for a pending syslog wakeup. */
   89 static int      log_wakeups_per_second = 5;
   90 SYSCTL_INT(_kern, OID_AUTO, log_wakeups_per_second, CTLFLAG_RW,
   91     &log_wakeups_per_second, 0, "");
   92 
   93 /*ARGSUSED*/
   94 static  int
   95 logopen(dev_t dev, int flags, int mode, struct thread *td)
   96 {
   97         if (log_open)
   98                 return (EBUSY);
   99         log_open = 1;
  100         callout_init(&logsoftc.sc_callout, 0);
  101         fsetown(td->td_proc->p_pid, &logsoftc.sc_sigio);        /* signal process only */
  102         callout_reset(&logsoftc.sc_callout, hz / log_wakeups_per_second,
  103             logtimeout, NULL);
  104         return (0);
  105 }
  106 
  107 /*ARGSUSED*/
  108 static  int
  109 logclose(dev_t dev, int flag, int mode, struct thread *td)
  110 {
  111 
  112         log_open = 0;
  113         callout_stop(&logsoftc.sc_callout);
  114         logsoftc.sc_state = 0;
  115         funsetown(&logsoftc.sc_sigio);
  116         return (0);
  117 }
  118 
  119 /*ARGSUSED*/
  120 static  int
  121 logread(dev_t dev, struct uio *uio, int flag)
  122 {
  123         struct msgbuf *mbp = msgbufp;
  124         int error = 0, l, s;
  125 
  126         s = splhigh();
  127         while (mbp->msg_bufr == mbp->msg_bufx) {
  128                 if (flag & IO_NDELAY) {
  129                         splx(s);
  130                         return (EWOULDBLOCK);
  131                 }
  132                 logsoftc.sc_state |= LOG_RDWAIT;
  133                 if ((error = tsleep(mbp, LOG_RDPRI | PCATCH, "klog", 0))) {
  134                         splx(s);
  135                         return (error);
  136                 }
  137         }
  138         splx(s);
  139         logsoftc.sc_state &= ~LOG_RDWAIT;
  140 
  141         while (uio->uio_resid > 0) {
  142                 l = mbp->msg_bufx - mbp->msg_bufr;
  143                 if (l < 0)
  144                         l = mbp->msg_size - mbp->msg_bufr;
  145                 l = imin(l, uio->uio_resid);
  146                 if (l == 0)
  147                         break;
  148                 error = uiomove((char *)msgbufp->msg_ptr + mbp->msg_bufr,
  149                     l, uio);
  150                 if (error)
  151                         break;
  152                 mbp->msg_bufr += l;
  153                 if (mbp->msg_bufr >= mbp->msg_size)
  154                         mbp->msg_bufr = 0;
  155         }
  156         return (error);
  157 }
  158 
  159 /*ARGSUSED*/
  160 static  int
  161 logpoll(dev_t dev, int events, struct thread *td)
  162 {
  163         int s;
  164         int revents = 0;
  165 
  166         s = splhigh();
  167 
  168         if (events & (POLLIN | POLLRDNORM)) {
  169                 if (msgbufp->msg_bufr != msgbufp->msg_bufx)
  170                         revents |= events & (POLLIN | POLLRDNORM);
  171                 else
  172                         selrecord(td, &logsoftc.sc_selp);
  173         }
  174         splx(s);
  175         return (revents);
  176 }
  177 
  178 static void
  179 logtimeout(void *arg)
  180 {
  181 
  182         if (!log_open)
  183                 return;
  184         if (msgbuftrigger == 0) {
  185                 callout_reset(&logsoftc.sc_callout,
  186                     hz / log_wakeups_per_second, logtimeout, NULL);
  187                 return;
  188         }
  189         msgbuftrigger = 0;
  190         selwakeup(&logsoftc.sc_selp);
  191         if ((logsoftc.sc_state & LOG_ASYNC) && logsoftc.sc_sigio != NULL)
  192                 pgsigio(&logsoftc.sc_sigio, SIGIO, 0);
  193         if (logsoftc.sc_state & LOG_RDWAIT) {
  194                 wakeup(msgbufp);
  195                 logsoftc.sc_state &= ~LOG_RDWAIT;
  196         }
  197         callout_reset(&logsoftc.sc_callout, hz / log_wakeups_per_second,
  198             logtimeout, NULL);
  199 }
  200 
  201 /*ARGSUSED*/
  202 static  int
  203 logioctl(dev_t dev, u_long com, caddr_t data, int flag, struct thread *td)
  204 {
  205         int l, s;
  206 
  207         switch (com) {
  208 
  209         /* return number of characters immediately available */
  210         case FIONREAD:
  211                 s = splhigh();
  212                 l = msgbufp->msg_bufx - msgbufp->msg_bufr;
  213                 splx(s);
  214                 if (l < 0)
  215                         l += msgbufp->msg_size;
  216                 *(int *)data = l;
  217                 break;
  218 
  219         case FIONBIO:
  220                 break;
  221 
  222         case FIOASYNC:
  223                 if (*(int *)data)
  224                         logsoftc.sc_state |= LOG_ASYNC;
  225                 else
  226                         logsoftc.sc_state &= ~LOG_ASYNC;
  227                 break;
  228 
  229         case FIOSETOWN:
  230                 return (fsetown(*(int *)data, &logsoftc.sc_sigio));
  231 
  232         case FIOGETOWN:
  233                 *(int *)data = fgetown(&logsoftc.sc_sigio);
  234                 break;
  235 
  236         /* This is deprecated, FIOSETOWN should be used instead. */
  237         case TIOCSPGRP:
  238                 return (fsetown(-(*(int *)data), &logsoftc.sc_sigio));
  239 
  240         /* This is deprecated, FIOGETOWN should be used instead */
  241         case TIOCGPGRP:
  242                 *(int *)data = -fgetown(&logsoftc.sc_sigio);
  243                 break;
  244 
  245         default:
  246                 return (ENOTTY);
  247         }
  248         return (0);
  249 }
  250 
  251 static void
  252 log_drvinit(void *unused)
  253 {
  254 
  255         make_dev(&log_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, "klog");
  256 }
  257 
  258 SYSINIT(logdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,log_drvinit,NULL)

Cache object: 69510d524b4bac0ebf013842c07b87c0


[ 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.