home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / sys / kern / subr_log.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-09  |  5.1 KB  |  228 lines

  1. /*
  2.  * Copyright (c) 1982, 1986 Regents of the University of California.
  3.  * 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    7.11 (Berkeley) 3/17/91
  34.  */
  35.  
  36. /*
  37.  * Error log buffer for kernel printf's.
  38.  */
  39.  
  40. #include "param.h"
  41. #include "proc.h"
  42. #include "vnode.h"
  43. #include "ioctl.h"
  44. #include "msgbuf.h"
  45. #include "file.h"
  46.  
  47. #define LOG_RDPRI    (PZERO + 1)
  48.  
  49. #define LOG_ASYNC    0x04
  50. #define LOG_RDWAIT    0x08
  51.  
  52. struct logsoftc {
  53.     int    sc_state;        /* see above for possibilities */
  54.     struct    proc *sc_selp;        /* process waiting on select call */
  55.     int    sc_pgid;        /* process/group for async I/O */
  56. } logsoftc;
  57.  
  58. int    log_open;            /* also used in log() */
  59.  
  60. /*ARGSUSED*/
  61. logopen(dev, flags, mode, p)
  62.     dev_t dev;
  63.     int flags, mode;
  64.     struct proc *p;
  65. {
  66.     register struct msgbuf *mbp = msgbufp;
  67.  
  68.     if (log_open)
  69.         return (EBUSY);
  70.     log_open = 1;
  71.     logsoftc.sc_pgid = p->p_pid;        /* signal process only */
  72.     /*
  73.      * Potential race here with putchar() but since putchar should be
  74.      * called by autoconf, msg_magic should be initialized by the time
  75.      * we get here.
  76.      */
  77.     if (mbp->msg_magic != MSG_MAGIC) {
  78.         register int i;
  79.  
  80.         mbp->msg_magic = MSG_MAGIC;
  81.         mbp->msg_bufx = mbp->msg_bufr = 0;
  82.         for (i=0; i < MSG_BSIZE; i++)
  83.             mbp->msg_bufc[i] = 0;
  84.     }
  85.     return (0);
  86. }
  87.  
  88. /*ARGSUSED*/
  89. logclose(dev, flag)
  90.     dev_t dev;
  91. {
  92.     log_open = 0;
  93.     logsoftc.sc_state = 0;
  94.     logsoftc.sc_selp = 0;
  95. }
  96.  
  97. /*ARGSUSED*/
  98. logread(dev, uio, flag)
  99.     dev_t dev;
  100.     struct uio *uio;
  101.     int flag;
  102. {
  103.     register struct msgbuf *mbp = msgbufp;
  104.     register long l;
  105.     register int s;
  106.     int error = 0;
  107.  
  108.     s = splhigh();
  109.     while (mbp->msg_bufr == mbp->msg_bufx) {
  110.         if (flag & IO_NDELAY) {
  111.             splx(s);
  112.             return (EWOULDBLOCK);
  113.         }
  114.         logsoftc.sc_state |= LOG_RDWAIT;
  115.         if (error = tsleep((caddr_t)mbp, LOG_RDPRI | PCATCH,
  116.             "klog", 0)) {
  117.             splx(s);
  118.             return (error);
  119.         }
  120.     }
  121.     splx(s);
  122.     logsoftc.sc_state &= ~LOG_RDWAIT;
  123.  
  124.     while (uio->uio_resid > 0) {
  125.         l = mbp->msg_bufx - mbp->msg_bufr;
  126.         if (l < 0)
  127.             l = MSG_BSIZE - mbp->msg_bufr;
  128.         l = MIN(l, uio->uio_resid);
  129.         if (l == 0)
  130.             break;
  131.         error = uiomove((caddr_t)&mbp->msg_bufc[mbp->msg_bufr],
  132.             (int)l, uio);
  133.         if (error)
  134.             break;
  135.         mbp->msg_bufr += l;
  136.         if (mbp->msg_bufr < 0 || mbp->msg_bufr >= MSG_BSIZE)
  137.             mbp->msg_bufr = 0;
  138.     }
  139.     return (error);
  140. }
  141.  
  142. /*ARGSUSED*/
  143. logselect(dev, rw, p)
  144.     dev_t dev;
  145.     int rw;
  146.     struct proc *p;
  147. {
  148.     int s = splhigh();
  149.  
  150.     switch (rw) {
  151.  
  152.     case FREAD:
  153.         if (msgbufp->msg_bufr != msgbufp->msg_bufx) {
  154.             splx(s);
  155.             return (1);
  156.         }
  157.         logsoftc.sc_selp = p;
  158.         break;
  159.     }
  160.     splx(s);
  161.     return (0);
  162. }
  163.  
  164. logwakeup()
  165. {
  166.     struct proc *p;
  167.  
  168.     if (!log_open)
  169.         return;
  170.     if (logsoftc.sc_selp) {
  171.         selwakeup(logsoftc.sc_selp, 0);
  172.         logsoftc.sc_selp = 0;
  173.     }
  174.     if (logsoftc.sc_state & LOG_ASYNC) {
  175.         if (logsoftc.sc_pgid < 0)
  176.             gsignal(-logsoftc.sc_pgid, SIGIO); 
  177.         else if (p = pfind(logsoftc.sc_pgid))
  178.             psignal(p, SIGIO);
  179.     }
  180.     if (logsoftc.sc_state & LOG_RDWAIT) {
  181.         wakeup((caddr_t)msgbufp);
  182.         logsoftc.sc_state &= ~LOG_RDWAIT;
  183.     }
  184. }
  185.  
  186. /*ARGSUSED*/
  187. logioctl(dev, com, data, flag)
  188.     caddr_t data;
  189. {
  190.     long l;
  191.     int s;
  192.  
  193.     switch (com) {
  194.  
  195.     /* return number of characters immediately available */
  196.     case FIONREAD:
  197.         s = splhigh();
  198.         l = msgbufp->msg_bufx - msgbufp->msg_bufr;
  199.         splx(s);
  200.         if (l < 0)
  201.             l += MSG_BSIZE;
  202.         *(off_t *)data = l;
  203.         break;
  204.  
  205.     case FIONBIO:
  206.         break;
  207.  
  208.     case FIOASYNC:
  209.         if (*(int *)data)
  210.             logsoftc.sc_state |= LOG_ASYNC;
  211.         else
  212.             logsoftc.sc_state &= ~LOG_ASYNC;
  213.         break;
  214.  
  215.     case TIOCSPGRP:
  216.         logsoftc.sc_pgid = *(int *)data;
  217.         break;
  218.  
  219.     case TIOCGPGRP:
  220.         *(int *)data = logsoftc.sc_pgid;
  221.         break;
  222.  
  223.     default:
  224.         return (-1);
  225.     }
  226.     return (0);
  227. }
  228.