Annotation of 43BSDReno/sys/kern/fifo_vnops.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1990 The Regents of the University of California.
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * Redistribution is only permitted until one year after the first shipment
        !             6:  * of 4.4BSD by the Regents.  Otherwise, redistribution and use in source and
        !             7:  * binary forms are permitted provided that: (1) source distributions retain
        !             8:  * this entire copyright notice and comment, and (2) distributions including
        !             9:  * binaries display the following acknowledgement:  This product includes
        !            10:  * software developed by the University of California, Berkeley and its
        !            11:  * contributors'' in the documentation or other materials provided with the
        !            12:  * distribution and in all advertising materials mentioning features or use
        !            13:  * of this software.  Neither the name of the University nor the names of
        !            14:  * its contributors may be used to endorse or promote products derived from
        !            15:  * this software without specific prior written permission.
        !            16:  * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
        !            17:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
        !            18:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            19:  *
        !            20:  *     @(#)fifo_vnops.c        7.4 (Berkeley) 6/28/90
        !            21:  */
        !            22: 
        !            23: #include "param.h"
        !            24: #include "time.h"
        !            25: #include "namei.h"
        !            26: #include "vnode.h"
        !            27: #include "socket.h"
        !            28: #include "socketvar.h"
        !            29: #include "stat.h"
        !            30: #include "ioctl.h"
        !            31: #include "file.h"
        !            32: #include "errno.h"
        !            33: #include "malloc.h"
        !            34: 
        !            35: /*
        !            36:  * This structure is associated with the FIFO vnode and stores
        !            37:  * the state associated with the FIFO.
        !            38:  */
        !            39: struct fifoinfo {
        !            40:        struct socket   *fi_readsock;
        !            41:        struct socket   *fi_writesock;
        !            42:        long            fi_readers;
        !            43:        long            fi_writers;
        !            44: };
        !            45: 
        !            46: int    fifo_lookup(),
        !            47:        fifo_open(),
        !            48:        fifo_read(),
        !            49:        fifo_write(),
        !            50:        fifo_strategy(),
        !            51:        fifo_bmap(),
        !            52:        fifo_ioctl(),
        !            53:        fifo_select(),
        !            54:        fifo_lock(),
        !            55:        fifo_unlock(),
        !            56:        fifo_close(),
        !            57:        fifo_print(),
        !            58:        fifo_ebadf(),
        !            59:        fifo_badop(),
        !            60:        fifo_nullop();
        !            61: 
        !            62: struct vnodeops fifo_vnodeops = {
        !            63:        fifo_lookup,            /* lookup */
        !            64:        fifo_badop,             /* create */
        !            65:        fifo_badop,             /* mknod */
        !            66:        fifo_open,              /* open */
        !            67:        fifo_close,             /* close */
        !            68:        fifo_ebadf,             /* access */
        !            69:        fifo_ebadf,             /* getattr */
        !            70:        fifo_ebadf,             /* setattr */
        !            71:        fifo_read,              /* read */
        !            72:        fifo_write,             /* write */
        !            73:        fifo_ioctl,             /* ioctl */
        !            74:        fifo_select,            /* select */
        !            75:        fifo_badop,             /* mmap */
        !            76:        fifo_nullop,            /* fsync */
        !            77:        fifo_badop,             /* seek */
        !            78:        fifo_badop,             /* remove */
        !            79:        fifo_badop,             /* link */
        !            80:        fifo_badop,             /* rename */
        !            81:        fifo_badop,             /* mkdir */
        !            82:        fifo_badop,             /* rmdir */
        !            83:        fifo_badop,             /* symlink */
        !            84:        fifo_badop,             /* readdir */
        !            85:        fifo_badop,             /* readlink */
        !            86:        fifo_badop,             /* abortop */
        !            87:        fifo_nullop,            /* inactive */
        !            88:        fifo_nullop,            /* reclaim */
        !            89:        fifo_lock,              /* lock */
        !            90:        fifo_unlock,            /* unlock */
        !            91:        fifo_bmap,              /* bmap */
        !            92:        fifo_badop,             /* strategy */
        !            93:        fifo_print,             /* print */
        !            94:        fifo_nullop,            /* islocked */
        !            95: };
        !            96: 
        !            97: /*
        !            98:  * Trivial lookup routine that always fails.
        !            99:  */
        !           100: fifo_lookup(vp, ndp)
        !           101:        struct vnode *vp;
        !           102:        struct nameidata *ndp;
        !           103: {
        !           104: 
        !           105:        ndp->ni_dvp = vp;
        !           106:        ndp->ni_vp = NULL;
        !           107:        return (ENOTDIR);
        !           108: }
        !           109: 
        !           110: /*
        !           111:  * Open called to set up a new instance of a fifo or
        !           112:  * to find an active instance of a fifo.
        !           113:  */
        !           114: /* ARGSUSED */
        !           115: fifo_open(vp, mode, cred)
        !           116:        register struct vnode *vp;
        !           117:        int mode;
        !           118:        struct ucred *cred;
        !           119: {
        !           120:        register struct fifoinfo *fip;
        !           121:        struct socket *rso, *wso;
        !           122:        int error;
        !           123:        static char openstr[] = "fifo";
        !           124: 
        !           125:        if ((mode & (FREAD|FWRITE)) == (FREAD|FWRITE))
        !           126:                return (EINVAL);
        !           127:        if ((fip = vp->v_fifoinfo) == NULL) {
        !           128:                MALLOC(fip, struct fifoinfo *, sizeof(*fip), M_VNODE, M_WAITOK);
        !           129:                vp->v_fifoinfo = fip;
        !           130:                if (error = socreate(AF_UNIX, &rso, SOCK_STREAM, 0)) {
        !           131:                        free(fip, M_VNODE);
        !           132:                        vp->v_fifoinfo = NULL;
        !           133:                        return (error);
        !           134:                }
        !           135:                fip->fi_readsock = rso;
        !           136:                if (error = socreate(AF_UNIX, &wso, SOCK_STREAM, 0)) {
        !           137:                        (void)soclose(rso);
        !           138:                        free(fip, M_VNODE);
        !           139:                        vp->v_fifoinfo = NULL;
        !           140:                        return (error);
        !           141:                }
        !           142:                fip->fi_writesock = wso;
        !           143:                if (error = unp_connect2(wso, rso)) {
        !           144:                        (void)soclose(wso);
        !           145:                        (void)soclose(rso);
        !           146:                        free(fip, M_VNODE);
        !           147:                        vp->v_fifoinfo = NULL;
        !           148:                        return (error);
        !           149:                }
        !           150:                wso->so_state |= SS_CANTRCVMORE;
        !           151:                rso->so_state |= SS_CANTSENDMORE;
        !           152:        }
        !           153:        error = 0;
        !           154:        if (mode & FREAD) {
        !           155:                fip->fi_readers++;
        !           156:                if (fip->fi_readers == 1) {
        !           157:                        fip->fi_writesock->so_state &= ~SS_CANTSENDMORE;
        !           158:                        if (fip->fi_writers > 0)
        !           159:                                wakeup((caddr_t)&fip->fi_writers);
        !           160:                }
        !           161:                if (mode & O_NONBLOCK)
        !           162:                        return (0);
        !           163:                while (fip->fi_writers == 0)
        !           164:                        if (error = tsleep((caddr_t)&fip->fi_readers, PSOCK,
        !           165:                            openstr, 0))
        !           166:                                break;
        !           167:        } else {
        !           168:                fip->fi_writers++;
        !           169:                if (fip->fi_readers == 0 && (mode & O_NONBLOCK)) {
        !           170:                        error = ENXIO;
        !           171:                } else {
        !           172:                        if (fip->fi_writers == 1) {
        !           173:                                fip->fi_readsock->so_state &= ~SS_CANTRCVMORE;
        !           174:                                if (fip->fi_readers > 0)
        !           175:                                        wakeup((caddr_t)&fip->fi_readers);
        !           176:                        }
        !           177:                        while (fip->fi_readers == 0)
        !           178:                                if (error = tsleep((caddr_t)&fip->fi_writers,
        !           179:                                    PSOCK, openstr, 0))
        !           180:                                        break;
        !           181:                }
        !           182:        }
        !           183:        if (error)
        !           184:                fifo_close(vp, mode, cred);
        !           185:        return (error);
        !           186: }
        !           187: 
        !           188: /*
        !           189:  * Vnode op for read
        !           190:  */
        !           191: /* ARGSUSED */
        !           192: fifo_read(vp, uio, ioflag, cred)
        !           193:        struct vnode *vp;
        !           194:        register struct uio *uio;
        !           195:        int ioflag;
        !           196:        struct ucred *cred;
        !           197: {
        !           198:        register struct socket *rso = vp->v_fifoinfo->fi_readsock;
        !           199:        int error, startresid;
        !           200: 
        !           201:        if (uio->uio_rw != UIO_READ)
        !           202:                panic("fifo_read mode");
        !           203:        if (uio->uio_resid == 0)
        !           204:                return (0);
        !           205:        if (ioflag & IO_NDELAY)
        !           206:                rso->so_state |= SS_NBIO;
        !           207:        startresid = uio->uio_resid;
        !           208:        VOP_UNLOCK(vp);
        !           209:        error = soreceive(rso, (struct mbuf **)0, uio, (int *)0,
        !           210:                (struct mbuf **)0, (struct mbuf **)0);
        !           211:        VOP_LOCK(vp);
        !           212:        /*
        !           213:         * Clear EOF indication after first such return.
        !           214:         */
        !           215:        if (uio->uio_resid == startresid)
        !           216:                rso->so_state &= ~SS_CANTRCVMORE;
        !           217:        if (ioflag & IO_NDELAY)
        !           218:                rso->so_state &= ~SS_NBIO;
        !           219:        return (error);
        !           220: }
        !           221: 
        !           222: /*
        !           223:  * Vnode op for write
        !           224:  */
        !           225: /* ARGSUSED */
        !           226: fifo_write(vp, uio, ioflag, cred)
        !           227:        struct vnode *vp;
        !           228:        register struct uio *uio;
        !           229:        int ioflag;
        !           230:        struct ucred *cred;
        !           231: {
        !           232:        struct socket *wso = vp->v_fifoinfo->fi_writesock;
        !           233:        int error;
        !           234: 
        !           235:        if (uio->uio_rw != UIO_WRITE)
        !           236:                panic("fifo_write mode");
        !           237:        if (ioflag & IO_NDELAY)
        !           238:                wso->so_state |= SS_NBIO;
        !           239:        VOP_UNLOCK(vp);
        !           240:        error = sosend(wso, (struct mbuf *)0, uio, 0, (struct mbuf *)0);
        !           241:        VOP_LOCK(vp);
        !           242:        if (ioflag & IO_NDELAY)
        !           243:                wso->so_state &= ~SS_NBIO;
        !           244:        return (error);
        !           245: }
        !           246: 
        !           247: /*
        !           248:  * Device ioctl operation.
        !           249:  */
        !           250: /* ARGSUSED */
        !           251: fifo_ioctl(vp, com, data, fflag, cred)
        !           252:        struct vnode *vp;
        !           253:        int com;
        !           254:        caddr_t data;
        !           255:        int fflag;
        !           256:        struct ucred *cred;
        !           257: {
        !           258:        struct file filetmp;
        !           259:        int error;
        !           260: 
        !           261:        if (com == FIONBIO)
        !           262:                return (0);
        !           263:        if (fflag & FREAD)
        !           264:                filetmp.f_data = (caddr_t)vp->v_fifoinfo->fi_readsock;
        !           265:        else
        !           266:                filetmp.f_data = (caddr_t)vp->v_fifoinfo->fi_writesock;
        !           267:        return (soo_ioctl(&filetmp, com, data));
        !           268: }
        !           269: 
        !           270: /* ARGSUSED */
        !           271: fifo_select(vp, which, fflag, cred)
        !           272:        struct vnode *vp;
        !           273:        int which, fflag;
        !           274:        struct ucred *cred;
        !           275: {
        !           276:        struct file filetmp;
        !           277:        int error;
        !           278: 
        !           279:        if (fflag & FREAD)
        !           280:                filetmp.f_data = (caddr_t)vp->v_fifoinfo->fi_readsock;
        !           281:        else
        !           282:                filetmp.f_data = (caddr_t)vp->v_fifoinfo->fi_writesock;
        !           283:        return (soo_select(&filetmp, which));
        !           284: }
        !           285: 
        !           286: /*
        !           287:  * This is a noop, simply returning what one has been given.
        !           288:  */
        !           289: fifo_bmap(vp, bn, vpp, bnp)
        !           290:        struct vnode *vp;
        !           291:        daddr_t bn;
        !           292:        struct vnode **vpp;
        !           293:        daddr_t *bnp;
        !           294: {
        !           295: 
        !           296:        if (vpp != NULL)
        !           297:                *vpp = vp;
        !           298:        if (bnp != NULL)
        !           299:                *bnp = bn;
        !           300:        return (0);
        !           301: }
        !           302: 
        !           303: /*
        !           304:  * At the moment we do not do any locking.
        !           305:  */
        !           306: /* ARGSUSED */
        !           307: fifo_lock(vp)
        !           308:        struct vnode *vp;
        !           309: {
        !           310: 
        !           311:        return (0);
        !           312: }
        !           313: 
        !           314: /* ARGSUSED */
        !           315: fifo_unlock(vp)
        !           316:        struct vnode *vp;
        !           317: {
        !           318: 
        !           319:        return (0);
        !           320: }
        !           321: 
        !           322: /*
        !           323:  * Device close routine
        !           324:  */
        !           325: /* ARGSUSED */
        !           326: fifo_close(vp, fflag, cred)
        !           327:        register struct vnode *vp;
        !           328:        int fflag;
        !           329:        struct ucred *cred;
        !           330: {
        !           331:        register struct fifoinfo *fip = vp->v_fifoinfo;
        !           332:        int error1, error2;
        !           333: 
        !           334:        if (fflag & FWRITE) {
        !           335:                fip->fi_writers--;
        !           336:                if (fip->fi_writers == 0)
        !           337:                        socantrcvmore(fip->fi_readsock);
        !           338:        } else {
        !           339:                fip->fi_readers--;
        !           340:                if (fip->fi_readers == 0)
        !           341:                        socantsendmore(fip->fi_writesock);
        !           342:        }
        !           343:        if (vp->v_usecount > 1)
        !           344:                return (0);
        !           345:        error1 = soclose(fip->fi_readsock);
        !           346:        error2 = soclose(fip->fi_writesock);
        !           347:        FREE(fip, M_VNODE);
        !           348:        vp->v_fifoinfo = NULL;
        !           349:        if (error1)
        !           350:                return (error1);
        !           351:        return (error2);
        !           352: }
        !           353: 
        !           354: /*
        !           355:  * Print out the contents of a fifo vnode.
        !           356:  */
        !           357: fifo_print(vp)
        !           358:        struct vnode *vp;
        !           359: {
        !           360: 
        !           361:        printf("tag VT_NON");
        !           362:        fifo_printinfo(vp);
        !           363:        printf("\n");
        !           364: }
        !           365: 
        !           366: /*
        !           367:  * Print out internal contents of a fifo vnode.
        !           368:  */
        !           369: fifo_printinfo(vp)
        !           370:        struct vnode *vp;
        !           371: {
        !           372:        register struct fifoinfo *fip = vp->v_fifoinfo;
        !           373: 
        !           374:        printf(", fifo with %d readers and %d writers",
        !           375:                fip->fi_readers, fip->fi_writers);
        !           376: }
        !           377: 
        !           378: /*
        !           379:  * Fifo failed operation
        !           380:  */
        !           381: fifo_ebadf()
        !           382: {
        !           383: 
        !           384:        return (EBADF);
        !           385: }
        !           386: 
        !           387: /*
        !           388:  * Fifo bad operation
        !           389:  */
        !           390: fifo_badop()
        !           391: {
        !           392: 
        !           393:        panic("fifo_badop called");
        !           394:        /* NOTREACHED */
        !           395: }
        !           396: 
        !           397: /*
        !           398:  * Fifo null operation
        !           399:  */
        !           400: fifo_nullop()
        !           401: {
        !           402: 
        !           403:        return (0);
        !           404: }

unix.superglobalmegacorp.com

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