[BACK]Return to fifo_vnops.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / miscfs / fifofs

Annotation of src/sys/miscfs/fifofs/fifo_vnops.c, Revision 1.53

1.53    ! yamt        1: /*     $NetBSD: fifo_vnops.c,v 1.52 2005/08/30 20:08:01 xtraeme Exp $  */
1.9       cgd         2:
1.1       cgd         3: /*
1.25      fvdl        4:  * Copyright (c) 1990, 1993, 1995
1.8       mycroft     5:  *     The Regents of the University of California.  All rights reserved.
1.1       cgd         6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
1.42      agc        15:  * 3. Neither the name of the University nor the names of its contributors
1.1       cgd        16:  *    may be used to endorse or promote products derived from this software
                     17:  *    without specific prior written permission.
                     18:  *
                     19:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     20:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     21:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     22:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     23:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     24:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     25:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     26:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     27:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     28:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     29:  * SUCH DAMAGE.
                     30:  *
1.25      fvdl       31:  *     @(#)fifo_vnops.c        8.10 (Berkeley) 5/27/95
1.1       cgd        32:  */
1.32      lukem      33:
                     34: #include <sys/cdefs.h>
1.53    ! yamt       35: __KERNEL_RCSID(0, "$NetBSD: fifo_vnops.c,v 1.52 2005/08/30 20:08:01 xtraeme Exp $");
1.1       cgd        36:
1.6       mycroft    37: #include <sys/param.h>
1.25      fvdl       38: #include <sys/systm.h>
1.8       mycroft    39: #include <sys/proc.h>
1.6       mycroft    40: #include <sys/time.h>
                     41: #include <sys/namei.h>
                     42: #include <sys/vnode.h>
                     43: #include <sys/socket.h>
1.45      matt       44: #include <sys/protosw.h>
1.6       mycroft    45: #include <sys/socketvar.h>
                     46: #include <sys/stat.h>
                     47: #include <sys/ioctl.h>
                     48: #include <sys/file.h>
                     49: #include <sys/errno.h>
                     50: #include <sys/malloc.h>
1.17      christos   51: #include <sys/un.h>
1.20      mycroft    52: #include <sys/poll.h>
1.36      jdolecek   53: #include <sys/event.h>
1.19      mycroft    54:
1.6       mycroft    55: #include <miscfs/fifofs/fifo.h>
1.19      mycroft    56: #include <miscfs/genfs/genfs.h>
1.1       cgd        57:
                     58: /*
                     59:  * This structure is associated with the FIFO vnode and stores
                     60:  * the state associated with the FIFO.
                     61:  */
                     62: struct fifoinfo {
                     63:        struct socket   *fi_readsock;
                     64:        struct socket   *fi_writesock;
                     65:        long            fi_readers;
                     66:        long            fi_writers;
                     67: };
                     68:
1.52      xtraeme    69: int (**fifo_vnodeop_p)(void *);
1.29      jdolecek   70: const struct vnodeopv_entry_desc fifo_vnodeop_entries[] = {
1.8       mycroft    71:        { &vop_default_desc, vn_default_error },
                     72:        { &vop_lookup_desc, fifo_lookup },              /* lookup */
                     73:        { &vop_create_desc, fifo_create },              /* create */
                     74:        { &vop_mknod_desc, fifo_mknod },                /* mknod */
                     75:        { &vop_open_desc, fifo_open },                  /* open */
                     76:        { &vop_close_desc, fifo_close },                /* close */
                     77:        { &vop_access_desc, fifo_access },              /* access */
                     78:        { &vop_getattr_desc, fifo_getattr },            /* getattr */
                     79:        { &vop_setattr_desc, fifo_setattr },            /* setattr */
                     80:        { &vop_read_desc, fifo_read },                  /* read */
                     81:        { &vop_write_desc, fifo_write },                /* write */
1.13      mycroft    82:        { &vop_lease_desc, fifo_lease_check },          /* lease */
1.8       mycroft    83:        { &vop_ioctl_desc, fifo_ioctl },                /* ioctl */
1.20      mycroft    84:        { &vop_poll_desc, fifo_poll },                  /* poll */
1.36      jdolecek   85:        { &vop_kqfilter_desc, fifo_kqfilter },          /* kqfilter */
1.25      fvdl       86:        { &vop_revoke_desc, fifo_revoke },              /* revoke */
1.8       mycroft    87:        { &vop_mmap_desc, fifo_mmap },                  /* mmap */
                     88:        { &vop_fsync_desc, fifo_fsync },                /* fsync */
                     89:        { &vop_seek_desc, fifo_seek },                  /* seek */
                     90:        { &vop_remove_desc, fifo_remove },              /* remove */
                     91:        { &vop_link_desc, fifo_link },                  /* link */
                     92:        { &vop_rename_desc, fifo_rename },              /* rename */
                     93:        { &vop_mkdir_desc, fifo_mkdir },                /* mkdir */
                     94:        { &vop_rmdir_desc, fifo_rmdir },                /* rmdir */
                     95:        { &vop_symlink_desc, fifo_symlink },            /* symlink */
                     96:        { &vop_readdir_desc, fifo_readdir },            /* readdir */
                     97:        { &vop_readlink_desc, fifo_readlink },          /* readlink */
                     98:        { &vop_abortop_desc, fifo_abortop },            /* abortop */
                     99:        { &vop_inactive_desc, fifo_inactive },          /* inactive */
                    100:        { &vop_reclaim_desc, fifo_reclaim },            /* reclaim */
                    101:        { &vop_lock_desc, fifo_lock },                  /* lock */
                    102:        { &vop_unlock_desc, fifo_unlock },              /* unlock */
                    103:        { &vop_bmap_desc, fifo_bmap },                  /* bmap */
                    104:        { &vop_strategy_desc, fifo_strategy },          /* strategy */
                    105:        { &vop_print_desc, fifo_print },                /* print */
                    106:        { &vop_islocked_desc, fifo_islocked },          /* islocked */
                    107:        { &vop_pathconf_desc, fifo_pathconf },          /* pathconf */
                    108:        { &vop_advlock_desc, fifo_advlock },            /* advlock */
                    109:        { &vop_bwrite_desc, fifo_bwrite },              /* bwrite */
1.31      sommerfe  110:        { &vop_putpages_desc, fifo_putpages },          /* putpages */
1.52      xtraeme   111:        { (struct vnodeop_desc*)NULL, (int(*)(void *))NULL }
1.1       cgd       112: };
1.29      jdolecek  113: const struct vnodeopv_desc fifo_vnodeop_opv_desc =
1.8       mycroft   114:        { &fifo_vnodeop_p, fifo_vnodeop_entries };
1.1       cgd       115:
                    116: /*
                    117:  * Trivial lookup routine that always fails.
                    118:  */
                    119: /* ARGSUSED */
1.17      christos  120: int
1.30      lukem     121: fifo_lookup(void *v)
1.17      christos  122: {
1.8       mycroft   123:        struct vop_lookup_args /* {
1.30      lukem     124:                struct vnode            *a_dvp;
                    125:                struct vnode            **a_vpp;
                    126:                struct componentname    *a_cnp;
1.17      christos  127:        } */ *ap = v;
1.51      perry     128:
1.8       mycroft   129:        *ap->a_vpp = NULL;
1.1       cgd       130:        return (ENOTDIR);
                    131: }
                    132:
                    133: /*
                    134:  * Open called to set up a new instance of a fifo or
                    135:  * to find an active instance of a fifo.
                    136:  */
                    137: /* ARGSUSED */
1.17      christos  138: int
1.30      lukem     139: fifo_open(void *v)
1.17      christos  140: {
1.8       mycroft   141:        struct vop_open_args /* {
1.30      lukem     142:                struct vnode    *a_vp;
                    143:                int             a_mode;
                    144:                struct ucred    *a_cred;
1.41      fvdl      145:                struct proc     *a_p;
1.17      christos  146:        } */ *ap = v;
1.30      lukem     147:        struct vnode    *vp;
                    148:        struct fifoinfo *fip;
                    149:        struct proc     *p;
                    150:        struct socket   *rso, *wso;
                    151:        int             error;
1.1       cgd       152:
1.30      lukem     153:        vp = ap->a_vp;
1.41      fvdl      154:        p = ap->a_p;
1.30      lukem     155:
1.1       cgd       156:        if ((fip = vp->v_fifoinfo) == NULL) {
                    157:                MALLOC(fip, struct fifoinfo *, sizeof(*fip), M_VNODE, M_WAITOK);
                    158:                vp->v_fifoinfo = fip;
1.49      jonathan  159:                error = socreate(AF_LOCAL, &rso, SOCK_STREAM, 0, p);
                    160:                if (error != 0) {
1.1       cgd       161:                        free(fip, M_VNODE);
                    162:                        vp->v_fifoinfo = NULL;
                    163:                        return (error);
                    164:                }
                    165:                fip->fi_readsock = rso;
1.49      jonathan  166:                error = socreate(AF_LOCAL, &wso, SOCK_STREAM, 0, p);
                    167:                if (error != 0) {
1.1       cgd       168:                        (void)soclose(rso);
                    169:                        free(fip, M_VNODE);
                    170:                        vp->v_fifoinfo = NULL;
                    171:                        return (error);
                    172:                }
                    173:                fip->fi_writesock = wso;
1.45      matt      174:                if ((error = unp_connect2(wso, rso, PRU_CONNECT2)) != 0) {
1.1       cgd       175:                        (void)soclose(wso);
                    176:                        (void)soclose(rso);
                    177:                        free(fip, M_VNODE);
                    178:                        vp->v_fifoinfo = NULL;
                    179:                        return (error);
                    180:                }
1.8       mycroft   181:                fip->fi_readers = fip->fi_writers = 0;
1.1       cgd       182:                wso->so_state |= SS_CANTRCVMORE;
                    183:                rso->so_state |= SS_CANTSENDMORE;
                    184:        }
1.8       mycroft   185:        if (ap->a_mode & FREAD) {
1.16      mycroft   186:                if (fip->fi_readers++ == 0) {
1.1       cgd       187:                        fip->fi_writesock->so_state &= ~SS_CANTSENDMORE;
                    188:                        if (fip->fi_writers > 0)
1.47      jrf       189:                                wakeup(&fip->fi_writers);
1.1       cgd       190:                }
1.16      mycroft   191:        }
                    192:        if (ap->a_mode & FWRITE) {
                    193:                if (fip->fi_writers++ == 0) {
                    194:                        fip->fi_readsock->so_state &= ~SS_CANTRCVMORE;
                    195:                        if (fip->fi_readers > 0)
1.47      jrf       196:                                wakeup(&fip->fi_readers);
1.2       cgd       197:                }
1.16      mycroft   198:        }
                    199:        if (ap->a_mode & FREAD) {
                    200:                if (ap->a_mode & O_NONBLOCK) {
1.1       cgd       201:                } else {
1.39      martin    202:                        while (!soreadable(fip->fi_readsock) && fip->fi_writers == 0) {
1.25      fvdl      203:                                VOP_UNLOCK(vp, 0);
1.47      jrf       204:                                error = tsleep(&fip->fi_readers,
1.38      jdolecek  205:                                    PCATCH | PSOCK, "fifor", 0);
1.25      fvdl      206:                                vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
1.16      mycroft   207:                                if (error)
                    208:                                        goto bad;
1.1       cgd       209:                        }
1.16      mycroft   210:                }
                    211:        }
                    212:        if (ap->a_mode & FWRITE) {
                    213:                if (ap->a_mode & O_NONBLOCK) {
                    214:                        if (fip->fi_readers == 0) {
                    215:                                error = ENXIO;
                    216:                                goto bad;
                    217:                        }
                    218:                } else {
1.2       cgd       219:                        while (fip->fi_readers == 0) {
1.25      fvdl      220:                                VOP_UNLOCK(vp, 0);
1.47      jrf       221:                                error = tsleep(&fip->fi_writers,
1.38      jdolecek  222:                                    PCATCH | PSOCK, "fifow", 0);
1.25      fvdl      223:                                vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
1.8       mycroft   224:                                if (error)
1.16      mycroft   225:                                        goto bad;
1.2       cgd       226:                        }
1.1       cgd       227:                }
                    228:        }
1.16      mycroft   229:        return (0);
1.30      lukem     230:  bad:
1.41      fvdl      231:        VOP_CLOSE(vp, ap->a_mode, ap->a_cred, p);
1.1       cgd       232:        return (error);
                    233: }
                    234:
                    235: /*
                    236:  * Vnode op for read
                    237:  */
                    238: /* ARGSUSED */
1.17      christos  239: int
1.30      lukem     240: fifo_read(void *v)
1.17      christos  241: {
1.8       mycroft   242:        struct vop_read_args /* {
1.30      lukem     243:                struct vnode    *a_vp;
                    244:                struct uio      *a_uio;
                    245:                int             a_ioflag;
                    246:                struct ucred    *a_cred;
1.17      christos  247:        } */ *ap = v;
1.30      lukem     248:        struct uio      *uio;
                    249:        struct socket   *rso;
1.35      thorpej   250:        int             error;
                    251:        size_t          startresid;
1.1       cgd       252:
1.30      lukem     253:        uio = ap->a_uio;
                    254:        rso = ap->a_vp->v_fifoinfo->fi_readsock;
1.1       cgd       255: #ifdef DIAGNOSTIC
                    256:        if (uio->uio_rw != UIO_READ)
                    257:                panic("fifo_read mode");
                    258: #endif
                    259:        if (uio->uio_resid == 0)
                    260:                return (0);
1.8       mycroft   261:        if (ap->a_ioflag & IO_NDELAY)
1.1       cgd       262:                rso->so_state |= SS_NBIO;
                    263:        startresid = uio->uio_resid;
1.25      fvdl      264:        VOP_UNLOCK(ap->a_vp, 0);
1.27      matt      265:        error = (*rso->so_receive)(rso, (struct mbuf **)0, uio,
                    266:            (struct mbuf **)0, (struct mbuf **)0, (int *)0);
1.25      fvdl      267:        vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY);
1.1       cgd       268:        /*
                    269:         * Clear EOF indication after first such return.
                    270:         */
                    271:        if (uio->uio_resid == startresid)
                    272:                rso->so_state &= ~SS_CANTRCVMORE;
1.23      kleink    273:        if (ap->a_ioflag & IO_NDELAY) {
1.1       cgd       274:                rso->so_state &= ~SS_NBIO;
1.23      kleink    275:                if (error == EWOULDBLOCK &&
                    276:                    ap->a_vp->v_fifoinfo->fi_writers == 0)
                    277:                        error = 0;
                    278:        }
1.1       cgd       279:        return (error);
                    280: }
                    281:
                    282: /*
                    283:  * Vnode op for write
                    284:  */
                    285: /* ARGSUSED */
1.17      christos  286: int
1.30      lukem     287: fifo_write(void *v)
1.17      christos  288: {
1.8       mycroft   289:        struct vop_write_args /* {
1.30      lukem     290:                struct vnode    *a_vp;
                    291:                struct uio      *a_uio;
                    292:                int             a_ioflag;
                    293:                struct ucred    *a_cred;
1.17      christos  294:        } */ *ap = v;
1.30      lukem     295:        struct socket   *wso;
                    296:        int             error;
1.1       cgd       297:
1.30      lukem     298:        wso = ap->a_vp->v_fifoinfo->fi_writesock;
1.1       cgd       299: #ifdef DIAGNOSTIC
1.8       mycroft   300:        if (ap->a_uio->uio_rw != UIO_WRITE)
1.1       cgd       301:                panic("fifo_write mode");
                    302: #endif
1.8       mycroft   303:        if (ap->a_ioflag & IO_NDELAY)
1.1       cgd       304:                wso->so_state |= SS_NBIO;
1.25      fvdl      305:        VOP_UNLOCK(ap->a_vp, 0);
1.27      matt      306:        error = (*wso->so_send)(wso, (struct mbuf *)0, ap->a_uio, 0,
1.49      jonathan  307:            (struct mbuf *)0, 0, curproc /*XXX*/);
1.25      fvdl      308:        vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY);
1.8       mycroft   309:        if (ap->a_ioflag & IO_NDELAY)
1.1       cgd       310:                wso->so_state &= ~SS_NBIO;
                    311:        return (error);
                    312: }
                    313:
                    314: /*
                    315:  * Device ioctl operation.
                    316:  */
                    317: /* ARGSUSED */
1.17      christos  318: int
1.30      lukem     319: fifo_ioctl(void *v)
1.17      christos  320: {
1.8       mycroft   321:        struct vop_ioctl_args /* {
1.30      lukem     322:                struct vnode    *a_vp;
                    323:                u_long          a_command;
1.48      jrf       324:                void            *a_data;
1.30      lukem     325:                int             a_fflag;
                    326:                struct ucred    *a_cred;
1.41      fvdl      327:                struct proc     *a_p;
1.17      christos  328:        } */ *ap = v;
1.30      lukem     329:        struct file     filetmp;
                    330:        int             error;
1.1       cgd       331:
1.8       mycroft   332:        if (ap->a_command == FIONBIO)
1.1       cgd       333:                return (0);
1.16      mycroft   334:        if (ap->a_fflag & FREAD) {
1.48      jrf       335:                filetmp.f_data = ap->a_vp->v_fifoinfo->fi_readsock;
1.41      fvdl      336:                error = soo_ioctl(&filetmp, ap->a_command, ap->a_data, ap->a_p);
1.16      mycroft   337:                if (error)
                    338:                        return (error);
                    339:        }
                    340:        if (ap->a_fflag & FWRITE) {
1.48      jrf       341:                filetmp.f_data = ap->a_vp->v_fifoinfo->fi_writesock;
1.41      fvdl      342:                error = soo_ioctl(&filetmp, ap->a_command, ap->a_data, ap->a_p);
1.16      mycroft   343:                if (error)
                    344:                        return (error);
                    345:        }
                    346:        return (0);
1.1       cgd       347: }
                    348:
                    349: /* ARGSUSED */
1.17      christos  350: int
1.30      lukem     351: fifo_poll(void *v)
1.17      christos  352: {
1.20      mycroft   353:        struct vop_poll_args /* {
1.30      lukem     354:                struct vnode    *a_vp;
                    355:                int             a_events;
1.41      fvdl      356:                struct proc     *a_p;
1.17      christos  357:        } */ *ap = v;
1.30      lukem     358:        struct file     filetmp;
                    359:        int             revents;
1.1       cgd       360:
1.30      lukem     361:        revents = 0;
1.20      mycroft   362:        if (ap->a_events & (POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND)) {
1.48      jrf       363:                filetmp.f_data = ap->a_vp->v_fifoinfo->fi_readsock;
1.20      mycroft   364:                if (filetmp.f_data)
1.41      fvdl      365:                        revents |= soo_poll(&filetmp, ap->a_events, ap->a_p);
1.16      mycroft   366:        }
1.20      mycroft   367:        if (ap->a_events & (POLLOUT | POLLWRNORM | POLLWRBAND)) {
1.48      jrf       368:                filetmp.f_data = ap->a_vp->v_fifoinfo->fi_writesock;
1.20      mycroft   369:                if (filetmp.f_data)
1.41      fvdl      370:                        revents |= soo_poll(&filetmp, ap->a_events, ap->a_p);
1.16      mycroft   371:        }
1.20      mycroft   372:
                    373:        return (revents);
1.1       cgd       374: }
                    375:
1.25      fvdl      376: int
1.30      lukem     377: fifo_inactive(void *v)
1.25      fvdl      378: {
                    379:        struct vop_inactive_args /* {
1.30      lukem     380:                struct vnode    *a_vp;
1.41      fvdl      381:                struct proc     *a_p;
1.25      fvdl      382:        } */ *ap = v;
                    383:
                    384:        VOP_UNLOCK(ap->a_vp, 0);
                    385:        return (0);
                    386: }
                    387:
1.1       cgd       388: /*
                    389:  * This is a noop, simply returning what one has been given.
                    390:  */
1.17      christos  391: int
1.30      lukem     392: fifo_bmap(void *v)
1.17      christos  393: {
1.8       mycroft   394:        struct vop_bmap_args /* {
1.30      lukem     395:                struct vnode    *a_vp;
                    396:                daddr_t         a_bn;
                    397:                struct vnode    **a_vpp;
                    398:                daddr_t         *a_bnp;
                    399:                int             *a_runp;
1.17      christos  400:        } */ *ap = v;
1.1       cgd       401:
1.8       mycroft   402:        if (ap->a_vpp != NULL)
                    403:                *ap->a_vpp = ap->a_vp;
                    404:        if (ap->a_bnp != NULL)
                    405:                *ap->a_bnp = ap->a_bn;
1.25      fvdl      406:        if (ap->a_runp != NULL)
                    407:                *ap->a_runp = 0;
1.1       cgd       408:        return (0);
                    409: }
                    410:
                    411: /*
                    412:  * Device close routine
                    413:  */
                    414: /* ARGSUSED */
1.17      christos  415: int
1.30      lukem     416: fifo_close(void *v)
1.17      christos  417: {
1.8       mycroft   418:        struct vop_close_args /* {
1.30      lukem     419:                struct vnode    *a_vp;
                    420:                int             a_fflag;
                    421:                struct ucred    *a_cred;
1.41      fvdl      422:                struct proc     *a_p;
1.17      christos  423:        } */ *ap = v;
1.30      lukem     424:        struct vnode    *vp;
                    425:        struct fifoinfo *fip;
1.50      mycroft   426:        int isrevoke;
1.1       cgd       427:
1.30      lukem     428:        vp = ap->a_vp;
                    429:        fip = vp->v_fifoinfo;
1.50      mycroft   430:        isrevoke = (ap->a_fflag & (FREAD | FWRITE | FNONBLOCK)) == FNONBLOCK;
                    431:        if (isrevoke) {
                    432:                if (fip->fi_readers != 0) {
                    433:                        fip->fi_readers = 0;
                    434:                        socantsendmore(fip->fi_writesock);
                    435:                }
                    436:                if (fip->fi_writers != 0) {
                    437:                        fip->fi_writers = 0;
                    438:                        socantrcvmore(fip->fi_readsock);
                    439:                }
                    440:        } else {
                    441:                if ((ap->a_fflag & FREAD) && --fip->fi_readers == 0)
1.16      mycroft   442:                        socantsendmore(fip->fi_writesock);
1.50      mycroft   443:                if ((ap->a_fflag & FWRITE) && --fip->fi_writers == 0)
1.1       cgd       444:                        socantrcvmore(fip->fi_readsock);
                    445:        }
1.50      mycroft   446:        /* Shut down if all readers and writers are gone. */
                    447:        if ((fip->fi_readers + fip->fi_writers) == 0) {
1.34      chs       448:                (void) soclose(fip->fi_readsock);
                    449:                (void) soclose(fip->fi_writesock);
                    450:                FREE(fip, M_VNODE);
                    451:                vp->v_fifoinfo = NULL;
                    452:        }
                    453:        return (0);
1.1       cgd       454: }
                    455:
                    456: /*
                    457:  * Print out the contents of a fifo vnode.
                    458:  */
1.17      christos  459: int
1.30      lukem     460: fifo_print(void *v)
1.17      christos  461: {
1.8       mycroft   462:        struct vop_print_args /* {
1.30      lukem     463:                struct vnode    *a_vp;
1.17      christos  464:        } */ *ap = v;
1.1       cgd       465:
1.22      christos  466:        printf("tag VT_NON");
1.8       mycroft   467:        fifo_printinfo(ap->a_vp);
1.22      christos  468:        printf("\n");
1.17      christos  469:        return 0;
1.1       cgd       470: }
                    471:
                    472: /*
                    473:  * Print out internal contents of a fifo vnode.
                    474:  */
1.17      christos  475: void
1.30      lukem     476: fifo_printinfo(struct vnode *vp)
1.1       cgd       477: {
1.30      lukem     478:        struct fifoinfo *fip;
1.1       cgd       479:
1.30      lukem     480:        fip = vp->v_fifoinfo;
1.22      christos  481:        printf(", fifo with %ld readers and %ld writers",
1.21      christos  482:            fip->fi_readers, fip->fi_writers);
1.1       cgd       483: }
                    484:
                    485: /*
1.8       mycroft   486:  * Return POSIX pathconf information applicable to fifo's.
                    487:  */
1.17      christos  488: int
1.30      lukem     489: fifo_pathconf(void *v)
1.17      christos  490: {
1.8       mycroft   491:        struct vop_pathconf_args /* {
1.30      lukem     492:                struct vnode    *a_vp;
                    493:                int             a_name;
                    494:                register_t      *a_retval;
1.17      christos  495:        } */ *ap = v;
1.8       mycroft   496:
                    497:        switch (ap->a_name) {
                    498:        case _PC_LINK_MAX:
                    499:                *ap->a_retval = LINK_MAX;
                    500:                return (0);
                    501:        case _PC_PIPE_BUF:
                    502:                *ap->a_retval = PIPE_BUF;
                    503:                return (0);
                    504:        case _PC_CHOWN_RESTRICTED:
1.26      kleink    505:                *ap->a_retval = 1;
                    506:                return (0);
                    507:        case _PC_SYNC_IO:
1.8       mycroft   508:                *ap->a_retval = 1;
                    509:                return (0);
                    510:        default:
                    511:                return (EINVAL);
                    512:        }
1.1       cgd       513:        /* NOTREACHED */
1.36      jdolecek  514: }
                    515:
                    516: static void
                    517: filt_fifordetach(struct knote *kn)
                    518: {
                    519:        struct socket *so;
                    520:
                    521:        so = (struct socket *)kn->kn_hook;
1.37      christos  522:        SLIST_REMOVE(&so->so_rcv.sb_sel.sel_klist, kn, knote, kn_selnext);
                    523:        if (SLIST_EMPTY(&so->so_rcv.sb_sel.sel_klist))
1.36      jdolecek  524:                so->so_rcv.sb_flags &= ~SB_KNOTE;
                    525: }
                    526:
                    527: static int
                    528: filt_fiforead(struct knote *kn, long hint)
                    529: {
                    530:        struct socket *so;
                    531:
                    532:        so = (struct socket *)kn->kn_hook;
                    533:        kn->kn_data = so->so_rcv.sb_cc;
                    534:        if (so->so_state & SS_CANTRCVMORE) {
                    535:                kn->kn_flags |= EV_EOF;
                    536:                return (1);
                    537:        }
                    538:        kn->kn_flags &= ~EV_EOF;
                    539:        return (kn->kn_data > 0);
                    540: }
                    541:
                    542: static void
                    543: filt_fifowdetach(struct knote *kn)
                    544: {
                    545:        struct socket *so;
                    546:
                    547:        so = (struct socket *)kn->kn_hook;
1.37      christos  548:        SLIST_REMOVE(&so->so_snd.sb_sel.sel_klist, kn, knote, kn_selnext);
                    549:        if (SLIST_EMPTY(&so->so_snd.sb_sel.sel_klist))
1.36      jdolecek  550:                so->so_snd.sb_flags &= ~SB_KNOTE;
                    551: }
                    552:
                    553: static int
                    554: filt_fifowrite(struct knote *kn, long hint)
                    555: {
                    556:        struct socket *so;
                    557:
                    558:        so = (struct socket *)kn->kn_hook;
                    559:        kn->kn_data = sbspace(&so->so_snd);
                    560:        if (so->so_state & SS_CANTSENDMORE) {
                    561:                kn->kn_flags |= EV_EOF;
                    562:                return (1);
                    563:        }
                    564:        kn->kn_flags &= ~EV_EOF;
                    565:        return (kn->kn_data >= so->so_snd.sb_lowat);
                    566: }
                    567:
                    568: static const struct filterops fiforead_filtops =
                    569:        { 1, NULL, filt_fifordetach, filt_fiforead };
                    570: static const struct filterops fifowrite_filtops =
                    571:        { 1, NULL, filt_fifowdetach, filt_fifowrite };
                    572:
                    573: /* ARGSUSED */
                    574: int
                    575: fifo_kqfilter(void *v)
                    576: {
                    577:        struct vop_kqfilter_args /* {
                    578:                struct vnode *a_vp;
                    579:                struct knote *a_kn;
                    580:        } */ *ap = v;
                    581:        struct socket   *so;
                    582:        struct sockbuf  *sb;
                    583:
                    584:        so = (struct socket *)ap->a_vp->v_fifoinfo->fi_readsock;
                    585:        switch (ap->a_kn->kn_filter) {
                    586:        case EVFILT_READ:
                    587:                ap->a_kn->kn_fop = &fiforead_filtops;
                    588:                sb = &so->so_rcv;
                    589:                break;
                    590:        case EVFILT_WRITE:
                    591:                ap->a_kn->kn_fop = &fifowrite_filtops;
                    592:                sb = &so->so_snd;
                    593:                break;
                    594:        default:
                    595:                return (1);
                    596:        }
                    597:
                    598:        ap->a_kn->kn_hook = so;
                    599:
1.37      christos  600:        SLIST_INSERT_HEAD(&sb->sb_sel.sel_klist, ap->a_kn, kn_selnext);
1.36      jdolecek  601:        sb->sb_flags |= SB_KNOTE;
                    602:        return (0);
1.1       cgd       603: }

CVSweb <webmaster@jp.NetBSD.org>