Annotation of 43BSDReno/sys/kern/fifo_vnops.c, revision 1.1.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.