Annotation of kernel/bsd/kern/subr_log.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
                      7:  * Reserved.  This file contains Original Code and/or Modifications of
                      8:  * Original Code as defined in and that are subject to the Apple Public
                      9:  * Source License Version 1.1 (the "License").  You may not use this file
                     10:  * except in compliance with the License.  Please obtain a copy of the
                     11:  * License at http://www.apple.com/publicsource and read it before using
                     12:  * this file.
                     13:  * 
                     14:  * The Original Code and all software distributed under the License are
                     15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     19:  * License for the specific language governing rights and limitations
                     20:  * under the License.
                     21:  * 
                     22:  * @APPLE_LICENSE_HEADER_END@
                     23:  */
                     24: 
                     25: /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
                     26: /*
                     27:  * Copyright (c) 1982, 1986, 1993
                     28:  *     The Regents of the University of California.  All rights reserved.
                     29:  *
                     30:  * Redistribution and use in source and binary forms, with or without
                     31:  * modification, are permitted provided that the following conditions
                     32:  * are met:
                     33:  * 1. Redistributions of source code must retain the above copyright
                     34:  *    notice, this list of conditions and the following disclaimer.
                     35:  * 2. Redistributions in binary form must reproduce the above copyright
                     36:  *    notice, this list of conditions and the following disclaimer in the
                     37:  *    documentation and/or other materials provided with the distribution.
                     38:  * 3. All advertising materials mentioning features or use of this software
                     39:  *    must display the following acknowledgement:
                     40:  *     This product includes software developed by the University of
                     41:  *     California, Berkeley and its contributors.
                     42:  * 4. Neither the name of the University nor the names of its contributors
                     43:  *    may be used to endorse or promote products derived from this software
                     44:  *    without specific prior written permission.
                     45:  *
                     46:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     47:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     48:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     49:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     50:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     51:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     52:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     53:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     54:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     55:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     56:  * SUCH DAMAGE.
                     57:  *
                     58:  *     @(#)subr_log.c  8.3 (Berkeley) 2/14/95
                     59:  */
                     60: 
                     61: /*
                     62:  * Error log buffer for kernel printf's.
                     63:  */
                     64: 
                     65: #include <sys/param.h>
                     66: #include <sys/systm.h>
                     67: #include <sys/proc.h>
                     68: #include <sys/vnode.h>
                     69: #include <sys/ioctl.h>
                     70: #include <sys/msgbuf.h>
                     71: #include <sys/file.h>
                     72: #include <sys/errno.h>
                     73: #include <sys/select.h>
                     74: #include <kern/thread.h>
                     75: #include <kern/sched_prim.h>
                     76: #include <kern/parallel.h>
                     77: 
                     78: #define LOG_RDPRI      (PZERO + 1)
                     79: 
                     80: #define LOG_NBIO       0x02
                     81: #define LOG_ASYNC      0x04
                     82: #define LOG_RDWAIT     0x08
                     83: 
                     84: struct logsoftc {
                     85:        int     sc_state;               /* see above for possibilities */
                     86:        struct  selinfo sc_selp;        /* thread waiting for select */
                     87:        int     sc_pgid;                /* process/group for async I/O */
                     88: } logsoftc;
                     89: 
                     90: int    log_open;                       /* also used in log() */
                     91: struct msgbuf *msgbufp;
                     92: 
                     93: /*
                     94:  * Serialize log access.  Note that the log can be written at interrupt level,
                     95:  * so any log manipulations that can be done from, or affect, another processor
                     96:  * at interrupt level must be guarded with a spin lock.
                     97:  */
                     98: decl_simple_lock_data(,log_lock);      /* stop races dead in their tracks */
                     99: #define        LOG_LOCK()      simple_lock(&log_lock)
                    100: #define        LOG_UNLOCK()    simple_unlock(&log_lock)
                    101: #define        LOG_LOCK_INIT() simple_lock_init(&log_lock)
                    102: 
                    103: /*ARGSUSED*/
                    104: logopen(dev, flags, mode, p)
                    105:        dev_t dev;
                    106:        int flags, mode;
                    107:        struct proc *p;
                    108: {
                    109:        unix_master();                  /* for pg_id, sigh */
                    110:        LOG_LOCK();
                    111:        if (log_open) {
                    112:                LOG_UNLOCK();
                    113:                return (EBUSY);
                    114:        }
                    115:        log_open = 1;
                    116:        logsoftc.sc_pgid = p->p_pid;            /* signal process only */
                    117:        /*
                    118:         * Potential race here with putchar() but since putchar should be
                    119:         * called by autoconf, msg_magic should be initialized by the time
                    120:         * we get here.
                    121:         */
                    122:        if (msgbufp->msg_magic != MSG_MAGIC) {
                    123:                register int i;
                    124: 
                    125:                msgbufp->msg_magic = MSG_MAGIC;
                    126:                msgbufp->msg_bufx = msgbufp->msg_bufr = 0;
                    127:                for (i=0; i < MSG_BSIZE; i++)
                    128:                        msgbufp->msg_bufc[i] = 0;
                    129:        }
                    130:        LOG_UNLOCK();
                    131:        unix_release();
                    132:        return (0);
                    133: }
                    134: 
                    135: /*ARGSUSED*/
                    136: int
                    137: logclose(dev, flag)
                    138:        dev_t dev;
                    139: {
                    140:        int oldpri;
                    141:        LOG_LOCK();
                    142:        log_open = 0;
                    143:        selwakeup(&logsoftc.sc_selp);
                    144:        oldpri = splhigh();
                    145:        selthreadclear(&logsoftc.sc_selp);
                    146:        splx(oldpri);
                    147:        LOG_UNLOCK();
                    148:        return (0);
                    149: }
                    150: 
                    151: /*ARGSUSED*/
                    152: int
                    153: logread(dev, uio, flag)
                    154:        dev_t dev;
                    155:        struct uio *uio;
                    156:        int flag;
                    157: {
                    158:        register long l;
                    159:        register int s;
                    160:        int error = 0;
                    161: 
                    162:        s = splhigh();
                    163:        while (msgbufp->msg_bufr == msgbufp->msg_bufx) {
                    164:                if (flag & IO_NDELAY) {
                    165:                        splx(s);
                    166:                        return (EWOULDBLOCK);
                    167:                }
                    168:                if (logsoftc.sc_state & LOG_NBIO) {
                    169:                        splx(s);
                    170:                        return (EWOULDBLOCK);
                    171:                }
                    172:                logsoftc.sc_state |= LOG_RDWAIT;
                    173:                if (error = tsleep((caddr_t)msgbufp, LOG_RDPRI | PCATCH,
                    174:                                "klog", 0)) {
                    175:                        splx(s);
                    176:                        return (error);
                    177:                }
                    178:        }
                    179:        splx(s);
                    180:        logsoftc.sc_state &= ~LOG_RDWAIT;
                    181: 
                    182:        while (uio->uio_resid > 0) {
                    183:                l = msgbufp->msg_bufx - msgbufp->msg_bufr;
                    184:                if (l < 0)
                    185:                        l = MSG_BSIZE - msgbufp->msg_bufr;
                    186:                l = min(l, uio->uio_resid);
                    187:                if (l == 0)
                    188:                        break;
                    189:                error = uiomove((caddr_t)&msgbufp->msg_bufc[msgbufp->msg_bufr],
                    190:                        (int)l, uio);
                    191:                if (error)
                    192:                        break;
                    193:                msgbufp->msg_bufr += l;
                    194:                if (msgbufp->msg_bufr < 0 || msgbufp->msg_bufr >= MSG_BSIZE)
                    195:                        msgbufp->msg_bufr = 0;
                    196:        }
                    197:        return (error);
                    198: }
                    199: 
                    200: /*ARGSUSED*/
                    201: int
                    202: logselect(dev, rw, p)
                    203:        dev_t dev;
                    204:        int rw;
                    205:        struct proc *p;
                    206: {
                    207:        int s = splhigh();
                    208: 
                    209:        switch (rw) {
                    210: 
                    211:        case FREAD:
                    212:                if (msgbufp->msg_bufr != msgbufp->msg_bufx) {
                    213:                        splx(s);
                    214:                        return (1);
                    215:                }
                    216:                selrecord(p, &logsoftc.sc_selp);
                    217:                break;
                    218:        }
                    219:        splx(s);
                    220:        return (0);
                    221: }
                    222: 
                    223: void
                    224: logwakeup()
                    225: {
                    226:        struct proc *p;
                    227:        int pgid;
                    228: 
                    229:        if (!log_open)
                    230:                return;
                    231:        selwakeup(&logsoftc.sc_selp);
                    232:        if (logsoftc.sc_state & LOG_ASYNC) {
                    233:                unix_master();
                    234:                LOG_LOCK();
                    235:                pgid = logsoftc.sc_pgid;
                    236:                LOG_UNLOCK();
                    237:                if (pgid < 0)
                    238:                        gsignal(-pgid, SIGIO); 
                    239:                else if (p = pfind(pgid))
                    240:                        psignal(p, SIGIO);
                    241:                unix_release();
                    242:        }
                    243:        if (logsoftc.sc_state & LOG_RDWAIT) {
                    244:                wakeup((caddr_t)msgbufp);
                    245:                logsoftc.sc_state &= ~LOG_RDWAIT;
                    246:        }
                    247: }
                    248: 
                    249: /*ARGSUSED*/
                    250: int
                    251: logioctl(com, data, flag)
                    252:        caddr_t data;
                    253: {
                    254:        long l;
                    255:        int s;
                    256: 
                    257:        switch (com) {
                    258: 
                    259:        /* return number of characters immediately available */
                    260:        case FIONREAD:
                    261:                s = splhigh();
                    262:                l = msgbufp->msg_bufx - msgbufp->msg_bufr;
                    263:                splx(s);
                    264:                if (l < 0)
                    265:                        l += MSG_BSIZE;
                    266:                *(off_t *)data = l;
                    267:                break;
                    268: 
                    269:        case FIONBIO:
                    270:                if (*(int *)data)
                    271:                        logsoftc.sc_state |= LOG_NBIO;
                    272:                else
                    273:                        logsoftc.sc_state &= ~LOG_NBIO;
                    274:                break;
                    275: 
                    276:        case FIOASYNC:
                    277:                if (*(int *)data)
                    278:                        logsoftc.sc_state |= LOG_ASYNC;
                    279:                else
                    280:                        logsoftc.sc_state &= ~LOG_ASYNC;
                    281:                break;
                    282: 
                    283:        case TIOCSPGRP:
                    284:                LOG_LOCK();
                    285:                logsoftc.sc_pgid = *(int *)data;
                    286:                LOG_UNLOCK();
                    287:                break;
                    288: 
                    289:        case TIOCGPGRP:
                    290:                LOG_LOCK();
                    291:                *(int *)data = logsoftc.sc_pgid;
                    292:                LOG_UNLOCK();
                    293:                break;
                    294: 
                    295:        default:
                    296:                return (-1);
                    297:        }
                    298:        return (0);
                    299: }
                    300: 
                    301: void
                    302: log_init()
                    303: {
                    304:        LOG_LOCK_INIT();
                    305: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.