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

Annotation of src/sys/miscfs/fdesc/fdesc_vnops.c, Revision 1.106

1.106   ! cegger      1: /*     $NetBSD: fdesc_vnops.c,v 1.105 2009/03/14 15:36:22 dsl Exp $    */
1.15      cgd         2:
1.1       cgd         3: /*
1.14      mycroft     4:  * Copyright (c) 1992, 1993
                      5:  *     The Regents of the University of California.  All rights reserved.
1.1       cgd         6:  *
1.8       cgd         7:  * This code is derived from software donated to Berkeley by
1.1       cgd         8:  * Jan-Simon Pendry.
                      9:  *
1.2       cgd        10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
1.78      agc        18:  * 3. Neither the name of the University nor the names of its contributors
1.2       cgd        19:  *    may be used to endorse or promote products derived from this software
                     20:  *    without specific prior written permission.
1.1       cgd        21:  *
1.2       cgd        22:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     23:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     24:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     25:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     26:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     27:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     28:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     29:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     30:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     31:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     32:  * SUCH DAMAGE.
1.1       cgd        33:  *
1.44      fvdl       34:  *     @(#)fdesc_vnops.c       8.17 (Berkeley) 5/22/95
1.22      mycroft    35:  *
                     36:  * #Id: fdesc_vnops.c,v 1.12 1993/04/06 16:17:17 jsp Exp #
1.1       cgd        37:  */
                     38:
                     39: /*
                     40:  * /dev/fd Filesystem
                     41:  */
1.65      lukem      42:
                     43: #include <sys/cdefs.h>
1.106   ! cegger     44: __KERNEL_RCSID(0, "$NetBSD: fdesc_vnops.c,v 1.105 2009/03/14 15:36:22 dsl Exp $");
1.1       cgd        45:
1.8       cgd        46: #include <sys/param.h>
                     47: #include <sys/systm.h>
                     48: #include <sys/time.h>
                     49: #include <sys/proc.h>
                     50: #include <sys/kernel.h>        /* boottime */
                     51: #include <sys/resourcevar.h>
1.30      christos   52: #include <sys/socketvar.h>
1.8       cgd        53: #include <sys/filedesc.h>
                     54: #include <sys/vnode.h>
1.14      mycroft    55: #include <sys/malloc.h>
1.32      mrg        56: #include <sys/conf.h>
1.8       cgd        57: #include <sys/file.h>
                     58: #include <sys/stat.h>
                     59: #include <sys/mount.h>
                     60: #include <sys/namei.h>
                     61: #include <sys/buf.h>
1.14      mycroft    62: #include <sys/dirent.h>
1.30      christos   63: #include <sys/tty.h>
1.92      elad       64: #include <sys/kauth.h>
1.102     ad         65: #include <sys/atomic.h>
1.34      mycroft    66:
1.8       cgd        67: #include <miscfs/fdesc/fdesc.h>
1.34      mycroft    68: #include <miscfs/genfs/genfs.h>
1.8       cgd        69:
1.96      ad         70: #define cttyvp(p) ((p)->p_lflag & PL_CONTROLT ? (p)->p_session->s_ttyvp : NULL)
1.8       cgd        71:
                     72: #define FDL_WANT       0x01
                     73: #define FDL_LOCKED     0x02
1.14      mycroft    74: static int fdcache_lock;
                     75:
                     76: dev_t devctty;
1.8       cgd        77:
                     78: #if (FD_STDIN != FD_STDOUT-1) || (FD_STDOUT != FD_STDERR-1)
                     79: FD_STDIN, FD_STDOUT, FD_STDERR must be a sequence n, n+1, n+2
                     80: #endif
                     81:
1.16      mycroft    82: #define        NFDCACHE 4
1.14      mycroft    83:
1.17      mycroft    84: #define FD_NHASH(ix) \
                     85:        (&fdhashtbl[(ix) & fdhash])
                     86: LIST_HEAD(fdhashhead, fdescnode) *fdhashtbl;
                     87: u_long fdhash;
1.14      mycroft    88:
1.86      xtraeme    89: int    fdesc_lookup(void *);
1.74      jdolecek   90: #define        fdesc_create    genfs_eopnotsupp
                     91: #define        fdesc_mknod     genfs_eopnotsupp
1.86      xtraeme    92: int    fdesc_open(void *);
1.34      mycroft    93: #define        fdesc_close     genfs_nullop
                     94: #define        fdesc_access    genfs_nullop
1.86      xtraeme    95: int    fdesc_getattr(void *);
                     96: int    fdesc_setattr(void *);
                     97: int    fdesc_read(void *);
                     98: int    fdesc_write(void *);
                     99: int    fdesc_ioctl(void *);
                    100: int    fdesc_poll(void *);
                    101: int    fdesc_kqfilter(void *);
1.34      mycroft   102: #define        fdesc_mmap      genfs_eopnotsupp
1.50      wrstuden  103: #define        fdesc_fcntl     genfs_fcntl
1.34      mycroft   104: #define        fdesc_fsync     genfs_nullop
1.40      fvdl      105: #define        fdesc_seek      genfs_seek
1.74      jdolecek  106: #define        fdesc_remove    genfs_eopnotsupp
1.86      xtraeme   107: int    fdesc_link(void *);
1.74      jdolecek  108: #define        fdesc_rename    genfs_eopnotsupp
                    109: #define        fdesc_mkdir     genfs_eopnotsupp
                    110: #define        fdesc_rmdir     genfs_eopnotsupp
1.86      xtraeme   111: int    fdesc_symlink(void *);
                    112: int    fdesc_readdir(void *);
                    113: int    fdesc_readlink(void *);
1.34      mycroft   114: #define        fdesc_abortop   genfs_abortop
1.86      xtraeme   115: int    fdesc_inactive(void *);
                    116: int    fdesc_reclaim(void *);
1.48      wrstuden  117: #define        fdesc_lock      genfs_lock
                    118: #define        fdesc_unlock    genfs_unlock
1.34      mycroft   119: #define        fdesc_bmap      genfs_badop
                    120: #define        fdesc_strategy  genfs_badop
1.86      xtraeme   121: int    fdesc_print(void *);
                    122: int    fdesc_pathconf(void *);
1.48      wrstuden  123: #define        fdesc_islocked  genfs_islocked
1.47      kleink    124: #define        fdesc_advlock   genfs_einval
1.34      mycroft   125: #define        fdesc_bwrite    genfs_eopnotsupp
1.44      fvdl      126: #define fdesc_revoke   genfs_revoke
1.67      chs       127: #define fdesc_putpages genfs_null_putpages
1.30      christos  128:
1.102     ad        129: static int fdesc_attr(int, struct vattr *, kauth_cred_t);
1.30      christos  130:
1.86      xtraeme   131: int (**fdesc_vnodeop_p)(void *);
1.58      jdolecek  132: const struct vnodeopv_entry_desc fdesc_vnodeop_entries[] = {
1.30      christos  133:        { &vop_default_desc, vn_default_error },
1.34      mycroft   134:        { &vop_lookup_desc, fdesc_lookup },             /* lookup */
                    135:        { &vop_create_desc, fdesc_create },             /* create */
                    136:        { &vop_mknod_desc, fdesc_mknod },               /* mknod */
                    137:        { &vop_open_desc, fdesc_open },                 /* open */
                    138:        { &vop_close_desc, fdesc_close },               /* close */
                    139:        { &vop_access_desc, fdesc_access },             /* access */
                    140:        { &vop_getattr_desc, fdesc_getattr },           /* getattr */
                    141:        { &vop_setattr_desc, fdesc_setattr },           /* setattr */
                    142:        { &vop_read_desc, fdesc_read },                 /* read */
                    143:        { &vop_write_desc, fdesc_write },               /* write */
                    144:        { &vop_ioctl_desc, fdesc_ioctl },               /* ioctl */
1.50      wrstuden  145:        { &vop_fcntl_desc, fdesc_fcntl },               /* fcntl */
1.35      mycroft   146:        { &vop_poll_desc, fdesc_poll },                 /* poll */
1.71      jdolecek  147:        { &vop_kqfilter_desc, fdesc_kqfilter },         /* kqfilter */
1.44      fvdl      148:        { &vop_revoke_desc, fdesc_revoke },             /* revoke */
1.34      mycroft   149:        { &vop_mmap_desc, fdesc_mmap },                 /* mmap */
                    150:        { &vop_fsync_desc, fdesc_fsync },               /* fsync */
                    151:        { &vop_seek_desc, fdesc_seek },                 /* seek */
                    152:        { &vop_remove_desc, fdesc_remove },             /* remove */
                    153:        { &vop_link_desc, fdesc_link },                 /* link */
                    154:        { &vop_rename_desc, fdesc_rename },             /* rename */
                    155:        { &vop_mkdir_desc, fdesc_mkdir },               /* mkdir */
                    156:        { &vop_rmdir_desc, fdesc_rmdir },               /* rmdir */
                    157:        { &vop_symlink_desc, fdesc_symlink },           /* symlink */
                    158:        { &vop_readdir_desc, fdesc_readdir },           /* readdir */
                    159:        { &vop_readlink_desc, fdesc_readlink },         /* readlink */
                    160:        { &vop_abortop_desc, fdesc_abortop },           /* abortop */
                    161:        { &vop_inactive_desc, fdesc_inactive },         /* inactive */
                    162:        { &vop_reclaim_desc, fdesc_reclaim },           /* reclaim */
                    163:        { &vop_lock_desc, fdesc_lock },                 /* lock */
                    164:        { &vop_unlock_desc, fdesc_unlock },             /* unlock */
                    165:        { &vop_bmap_desc, fdesc_bmap },                 /* bmap */
                    166:        { &vop_strategy_desc, fdesc_strategy },         /* strategy */
                    167:        { &vop_print_desc, fdesc_print },               /* print */
                    168:        { &vop_islocked_desc, fdesc_islocked },         /* islocked */
                    169:        { &vop_pathconf_desc, fdesc_pathconf },         /* pathconf */
                    170:        { &vop_advlock_desc, fdesc_advlock },           /* advlock */
                    171:        { &vop_bwrite_desc, fdesc_bwrite },             /* bwrite */
1.67      chs       172:        { &vop_putpages_desc, fdesc_putpages },         /* putpages */
                    173:        { NULL, NULL }
1.30      christos  174: };
                    175:
1.58      jdolecek  176: const struct vnodeopv_desc fdesc_vnodeop_opv_desc =
1.30      christos  177:        { &fdesc_vnodeop_p, fdesc_vnodeop_entries };
                    178:
1.70      gehenna   179: extern const struct cdevsw ctty_cdevsw;
                    180:
1.14      mycroft   181: /*
                    182:  * Initialise cache headers
                    183:  */
1.30      christos  184: void
1.106   ! cegger    185: fdesc_init(void)
1.14      mycroft   186: {
1.32      mrg       187:        int cttymajor;
1.14      mycroft   188:
1.32      mrg       189:        /* locate the major number */
1.70      gehenna   190:        cttymajor = cdevsw_lookup_major(&ctty_cdevsw);
1.32      mrg       191:        devctty = makedev(cttymajor, 0);
1.103     ad        192:        fdhashtbl = hashinit(NFDCACHE, HASH_LIST, true, &fdhash);
1.54      jdolecek  193: }
                    194:
                    195: /*
                    196:  * Free hash table.
                    197:  */
                    198: void
1.106   ! cegger    199: fdesc_done(void)
1.54      jdolecek  200: {
1.103     ad        201:        hashdone(fdhashtbl, HASH_LIST, fdhash);
1.14      mycroft   202: }
                    203:
1.48      wrstuden  204: /*
                    205:  * Return a locked vnode of the correct type.
                    206:  */
1.14      mycroft   207: int
1.105     dsl       208: fdesc_allocvp(fdntype ftype, int ix, struct mount *mp, struct vnode **vpp)
1.8       cgd       209: {
1.17      mycroft   210:        struct fdhashhead *fc;
1.14      mycroft   211:        struct fdescnode *fd;
1.8       cgd       212:        int error = 0;
                    213:
1.17      mycroft   214:        fc = FD_NHASH(ix);
1.8       cgd       215: loop:
1.17      mycroft   216:        for (fd = fc->lh_first; fd != 0; fd = fd->fd_hash.le_next) {
1.14      mycroft   217:                if (fd->fd_ix == ix && fd->fd_vnode->v_mount == mp) {
1.76      thorpej   218:                        if (vget(fd->fd_vnode, LK_EXCLUSIVE))
1.8       cgd       219:                                goto loop;
1.14      mycroft   220:                        *vpp = fd->fd_vnode;
1.8       cgd       221:                        return (error);
                    222:                }
                    223:        }
                    224:
                    225:        /*
                    226:         * otherwise lock the array while we call getnewvnode
                    227:         * since that can block.
1.83      perry     228:         */
1.14      mycroft   229:        if (fdcache_lock & FDL_LOCKED) {
                    230:                fdcache_lock |= FDL_WANT;
1.55      thorpej   231:                (void) tsleep(&fdcache_lock, PINOD, "fdcache", 0);
1.8       cgd       232:                goto loop;
                    233:        }
1.14      mycroft   234:        fdcache_lock |= FDL_LOCKED;
1.1       cgd       235:
1.14      mycroft   236:        error = getnewvnode(VT_FDESC, mp, fdesc_vnodeop_p, vpp);
1.8       cgd       237:        if (error)
                    238:                goto out;
1.104     cegger    239:        fd = malloc(sizeof(struct fdescnode), M_TEMP, M_WAITOK);
1.14      mycroft   240:        (*vpp)->v_data = fd;
                    241:        fd->fd_vnode = *vpp;
                    242:        fd->fd_type = ftype;
                    243:        fd->fd_fd = -1;
                    244:        fd->fd_link = 0;
                    245:        fd->fd_ix = ix;
1.98      pooka     246:        uvm_vnp_setsize(*vpp, 0);
1.48      wrstuden  247:        VOP_LOCK(*vpp, LK_EXCLUSIVE);
1.17      mycroft   248:        LIST_INSERT_HEAD(fc, fd, fd_hash);
1.8       cgd       249:
                    250: out:;
1.14      mycroft   251:        fdcache_lock &= ~FDL_LOCKED;
1.8       cgd       252:
1.14      mycroft   253:        if (fdcache_lock & FDL_WANT) {
                    254:                fdcache_lock &= ~FDL_WANT;
1.81      jrf       255:                wakeup(&fdcache_lock);
1.8       cgd       256:        }
                    257:
                    258:        return (error);
                    259: }
1.1       cgd       260:
                    261: /*
                    262:  * vp is the current namei directory
                    263:  * ndp is the name to locate in that directory...
                    264:  */
1.14      mycroft   265: int
1.105     dsl       266: fdesc_lookup(void *v)
1.30      christos  267: {
1.14      mycroft   268:        struct vop_lookup_args /* {
                    269:                struct vnode * a_dvp;
                    270:                struct vnode ** a_vpp;
                    271:                struct componentname * a_cnp;
1.30      christos  272:        } */ *ap = v;
1.14      mycroft   273:        struct vnode **vpp = ap->a_vpp;
                    274:        struct vnode *dvp = ap->a_dvp;
1.44      fvdl      275:        struct componentname *cnp = ap->a_cnp;
1.101     pooka     276:        struct lwp *l = curlwp;
1.44      fvdl      277:        const char *pname = cnp->cn_nameptr;
1.89      christos  278:        struct proc *p = l->l_proc;
1.102     ad        279:        filedesc_t *fdp = p->p_fd;
                    280:        int numfiles = fdp->fd_nfiles;
1.30      christos  281:        unsigned fd = 0;
1.1       cgd       282:        int error;
                    283:        struct vnode *fvp;
1.84      christos  284:        const char *ln;
1.1       cgd       285:
1.44      fvdl      286:        if (cnp->cn_namelen == 1 && *pname == '.') {
1.14      mycroft   287:                *vpp = dvp;
1.44      fvdl      288:                VREF(dvp);
1.1       cgd       289:                return (0);
                    290:        }
                    291:
1.8       cgd       292:        switch (VTOFDESC(dvp)->fd_type) {
                    293:        default:
                    294:        case Flink:
                    295:        case Fdesc:
                    296:        case Fctty:
                    297:                error = ENOTDIR;
                    298:                goto bad;
                    299:
                    300:        case Froot:
1.46      perry     301:                if (cnp->cn_namelen == 2 && memcmp(pname, "fd", 2) == 0) {
1.8       cgd       302:                        error = fdesc_allocvp(Fdevfd, FD_DEVFD, dvp->v_mount, &fvp);
                    303:                        if (error)
                    304:                                goto bad;
1.14      mycroft   305:                        *vpp = fvp;
1.8       cgd       306:                        fvp->v_type = VDIR;
1.48      wrstuden  307:                        goto good;
1.8       cgd       308:                }
                    309:
1.46      perry     310:                if (cnp->cn_namelen == 3 && memcmp(pname, "tty", 3) == 0) {
1.8       cgd       311:                        struct vnode *ttyvp = cttyvp(p);
                    312:                        if (ttyvp == NULL) {
                    313:                                error = ENXIO;
                    314:                                goto bad;
                    315:                        }
                    316:                        error = fdesc_allocvp(Fctty, FD_CTTY, dvp->v_mount, &fvp);
                    317:                        if (error)
                    318:                                goto bad;
1.14      mycroft   319:                        *vpp = fvp;
1.32      mrg       320:                        fvp->v_type = VCHR;
1.48      wrstuden  321:                        goto good;
1.8       cgd       322:                }
                    323:
                    324:                ln = 0;
1.44      fvdl      325:                switch (cnp->cn_namelen) {
1.8       cgd       326:                case 5:
1.46      perry     327:                        if (memcmp(pname, "stdin", 5) == 0) {
1.8       cgd       328:                                ln = "fd/0";
                    329:                                fd = FD_STDIN;
                    330:                        }
1.1       cgd       331:                        break;
1.8       cgd       332:                case 6:
1.46      perry     333:                        if (memcmp(pname, "stdout", 6) == 0) {
1.8       cgd       334:                                ln = "fd/1";
                    335:                                fd = FD_STDOUT;
                    336:                        } else
1.46      perry     337:                        if (memcmp(pname, "stderr", 6) == 0) {
1.8       cgd       338:                                ln = "fd/2";
                    339:                                fd = FD_STDERR;
                    340:                        }
                    341:                        break;
                    342:                }
                    343:
                    344:                if (ln) {
                    345:                        error = fdesc_allocvp(Flink, fd, dvp->v_mount, &fvp);
                    346:                        if (error)
                    347:                                goto bad;
1.84      christos  348:                        /* XXXUNCONST */
                    349:                        VTOFDESC(fvp)->fd_link = __UNCONST(ln);
1.14      mycroft   350:                        *vpp = fvp;
1.8       cgd       351:                        fvp->v_type = VLNK;
1.48      wrstuden  352:                        goto good;
1.8       cgd       353:                } else {
                    354:                        error = ENOENT;
                    355:                        goto bad;
                    356:                }
                    357:
1.14      mycroft   358:                /* FALL THROUGH */
1.8       cgd       359:
                    360:        case Fdevfd:
1.46      perry     361:                if (cnp->cn_namelen == 2 && memcmp(pname, "..", 2) == 0) {
1.48      wrstuden  362:                        VOP_UNLOCK(dvp, 0);
1.76      thorpej   363:                        error = fdesc_root(dvp->v_mount, vpp);
1.95      chs       364:                        vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
1.44      fvdl      365:                        if (error)
                    366:                                goto bad;
1.48      wrstuden  367:                        return (error);
1.8       cgd       368:                }
                    369:
                    370:                fd = 0;
                    371:                while (*pname >= '0' && *pname <= '9') {
                    372:                        fd = 10 * fd + *pname++ - '0';
1.84      christos  373:                        if (fd >= numfiles)
1.8       cgd       374:                                break;
                    375:                }
1.1       cgd       376:
1.8       cgd       377:                if (*pname != '\0') {
                    378:                        error = ENOENT;
                    379:                        goto bad;
                    380:                }
1.1       cgd       381:
1.102     ad        382:                mutex_enter(&fdp->fd_lock);
                    383:                if (fd >= numfiles ||fdp->fd_ofiles[fd] == NULL ||
                    384:                    fdp->fd_ofiles[fd]->ff_file == NULL) {
                    385:                        mutex_exit(&fdp->fd_lock);
1.8       cgd       386:                        error = EBADF;
                    387:                        goto bad;
                    388:                }
1.102     ad        389:                mutex_exit(&fdp->fd_lock);
1.1       cgd       390:
1.8       cgd       391:                error = fdesc_allocvp(Fdesc, FD_DESC+fd, dvp->v_mount, &fvp);
                    392:                if (error)
                    393:                        goto bad;
                    394:                VTOFDESC(fvp)->fd_fd = fd;
1.14      mycroft   395:                *vpp = fvp;
1.48      wrstuden  396:                goto good;
1.8       cgd       397:        }
1.1       cgd       398:
1.95      chs       399: bad:
1.14      mycroft   400:        *vpp = NULL;
1.1       cgd       401:        return (error);
1.48      wrstuden  402:
1.95      chs       403: good:
1.48      wrstuden  404:        return (0);
1.1       cgd       405: }
                    406:
1.14      mycroft   407: int
1.105     dsl       408: fdesc_open(void *v)
1.30      christos  409: {
1.14      mycroft   410:        struct vop_open_args /* {
                    411:                struct vnode *a_vp;
                    412:                int  a_mode;
1.92      elad      413:                kauth_cred_t a_cred;
1.30      christos  414:        } */ *ap = v;
1.14      mycroft   415:        struct vnode *vp = ap->a_vp;
1.8       cgd       416:
                    417:        switch (VTOFDESC(vp)->fd_type) {
                    418:        case Fdesc:
1.23      mycroft   419:                /*
1.79      jdolecek  420:                 * XXX Kludge: set dupfd to contain the value of the
1.83      perry     421:                 * the file descriptor being sought for duplication. The error
1.23      mycroft   422:                 * return ensures that the vnode for this device will be
                    423:                 * released by vn_open. Open will detect this special error and
                    424:                 * take the actions in dupfdopen.  Other callers of vn_open or
                    425:                 * VOP_OPEN will simply report the error.
                    426:                 */
1.79      jdolecek  427:                curlwp->l_dupfd = VTOFDESC(vp)->fd_fd;  /* XXX */
1.82      christos  428:                return EDUPFD;
1.1       cgd       429:
1.8       cgd       430:        case Fctty:
1.100     pooka     431:                return cdev_open(devctty, ap->a_mode, 0, curlwp);
1.30      christos  432:        case Froot:
                    433:        case Fdevfd:
                    434:        case Flink:
                    435:                break;
1.8       cgd       436:        }
1.1       cgd       437:
1.21      mycroft   438:        return (0);
1.1       cgd       439: }
                    440:
                    441: static int
1.105     dsl       442: fdesc_attr(int fd, struct vattr *vap, kauth_cred_t cred)
1.1       cgd       443: {
1.102     ad        444:        file_t *fp;
1.8       cgd       445:        struct stat stb;
1.1       cgd       446:        int error;
                    447:
1.102     ad        448:        if ((fp = fd_getfile(fd)) == NULL)
1.1       cgd       449:                return (EBADF);
                    450:
                    451:        switch (fp->f_type) {
                    452:        case DTYPE_VNODE:
1.100     pooka     453:                error = VOP_GETATTR((struct vnode *) fp->f_data, vap, cred);
1.8       cgd       454:                if (error == 0 && vap->va_type == VDIR) {
                    455:                        /*
1.22      mycroft   456:                         * directories can cause loops in the namespace,
                    457:                         * so turn off the 'x' bits to avoid trouble.
1.8       cgd       458:                         */
1.41      mycroft   459:                        vap->va_mode &= ~(S_IXUSR|S_IXGRP|S_IXOTH);
1.8       cgd       460:                }
1.1       cgd       461:                break;
                    462:
1.69      jdolecek  463:        default:
                    464:                memset(&stb, 0, sizeof(stb));
1.102     ad        465:                error = (*fp->f_ops->fo_stat)(fp, &stb);
1.69      jdolecek  466:                if (error)
                    467:                        break;
                    468:
                    469:                vattr_null(vap);
                    470:                switch(fp->f_type) {
                    471:                case DTYPE_SOCKET:
                    472:                        vap->va_type = VSOCK;
                    473:                        break;
                    474:                case DTYPE_PIPE:
                    475:                        vap->va_type = VFIFO;
                    476:                        break;
                    477:                default:
                    478:                        /* use VNON perhaps? */
                    479:                        vap->va_type = VBAD;
                    480:                        break;
1.8       cgd       481:                }
1.69      jdolecek  482:                vap->va_mode = stb.st_mode;
                    483:                vap->va_nlink = stb.st_nlink;
                    484:                vap->va_uid = stb.st_uid;
                    485:                vap->va_gid = stb.st_gid;
                    486:                vap->va_fsid = stb.st_dev;
                    487:                vap->va_fileid = stb.st_ino;
                    488:                vap->va_size = stb.st_size;
                    489:                vap->va_blocksize = stb.st_blksize;
                    490:                vap->va_atime = stb.st_atimespec;
                    491:                vap->va_mtime = stb.st_mtimespec;
                    492:                vap->va_ctime = stb.st_ctimespec;
                    493:                vap->va_gen = stb.st_gen;
                    494:                vap->va_flags = stb.st_flags;
                    495:                vap->va_rdev = stb.st_rdev;
                    496:                vap->va_bytes = stb.st_blocks * stb.st_blksize;
1.1       cgd       497:                break;
                    498:        }
                    499:
1.102     ad        500:        fd_putfile(fd);
1.1       cgd       501:        return (error);
                    502: }
                    503:
1.14      mycroft   504: int
1.105     dsl       505: fdesc_getattr(void *v)
1.30      christos  506: {
1.14      mycroft   507:        struct vop_getattr_args /* {
                    508:                struct vnode *a_vp;
                    509:                struct vattr *a_vap;
1.92      elad      510:                kauth_cred_t a_cred;
1.89      christos  511:                struct lwp *a_l;
1.30      christos  512:        } */ *ap = v;
1.14      mycroft   513:        struct vnode *vp = ap->a_vp;
                    514:        struct vattr *vap = ap->a_vap;
1.1       cgd       515:        unsigned fd;
1.8       cgd       516:        int error = 0;
1.1       cgd       517:
1.8       cgd       518:        switch (VTOFDESC(vp)->fd_type) {
                    519:        case Froot:
                    520:        case Fdevfd:
                    521:        case Flink:
                    522:        case Fctty:
1.33      mrg       523:                VATTR_NULL(vap);
1.8       cgd       524:                vap->va_fileid = VTOFDESC(vp)->fd_ix;
                    525:
1.30      christos  526: #define R_ALL (S_IRUSR|S_IRGRP|S_IROTH)
                    527: #define W_ALL (S_IWUSR|S_IWGRP|S_IWOTH)
                    528: #define X_ALL (S_IXUSR|S_IXGRP|S_IXOTH)
                    529:
1.8       cgd       530:                switch (VTOFDESC(vp)->fd_type) {
                    531:                case Flink:
1.30      christos  532:                        vap->va_mode = R_ALL|X_ALL;
1.8       cgd       533:                        vap->va_type = VLNK;
1.32      mrg       534:                        vap->va_rdev = 0;
1.8       cgd       535:                        vap->va_nlink = 1;
                    536:                        vap->va_size = strlen(VTOFDESC(vp)->fd_link);
                    537:                        break;
                    538:
                    539:                case Fctty:
1.30      christos  540:                        vap->va_mode = R_ALL|W_ALL;
1.32      mrg       541:                        vap->va_type = VCHR;
                    542:                        vap->va_rdev = devctty;
1.8       cgd       543:                        vap->va_nlink = 1;
                    544:                        vap->va_size = 0;
                    545:                        break;
                    546:
                    547:                default:
1.30      christos  548:                        vap->va_mode = R_ALL|X_ALL;
1.8       cgd       549:                        vap->va_type = VDIR;
1.32      mrg       550:                        vap->va_rdev = 0;
1.8       cgd       551:                        vap->va_nlink = 2;
                    552:                        vap->va_size = DEV_BSIZE;
                    553:                        break;
                    554:                }
1.1       cgd       555:                vap->va_uid = 0;
                    556:                vap->va_gid = 0;
1.80      christos  557:                vap->va_fsid = vp->v_mount->mnt_stat.f_fsidx.__fsid_val[0];
1.1       cgd       558:                vap->va_blocksize = DEV_BSIZE;
1.28      jtc       559:                vap->va_atime.tv_sec = boottime.tv_sec;
                    560:                vap->va_atime.tv_nsec = 0;
1.1       cgd       561:                vap->va_mtime = vap->va_atime;
1.14      mycroft   562:                vap->va_ctime = vap->va_mtime;
1.1       cgd       563:                vap->va_gen = 0;
                    564:                vap->va_flags = 0;
                    565:                vap->va_bytes = 0;
1.8       cgd       566:                break;
                    567:
                    568:        case Fdesc:
                    569:                fd = VTOFDESC(vp)->fd_fd;
1.102     ad        570:                error = fdesc_attr(fd, vap, ap->a_cred);
1.8       cgd       571:                break;
                    572:
                    573:        default:
                    574:                panic("fdesc_getattr");
1.83      perry     575:                break;
1.1       cgd       576:        }
                    577:
                    578:        if (error == 0)
                    579:                vp->v_type = vap->va_type;
1.8       cgd       580:
1.1       cgd       581:        return (error);
                    582: }
                    583:
1.14      mycroft   584: int
1.105     dsl       585: fdesc_setattr(void *v)
1.30      christos  586: {
1.14      mycroft   587:        struct vop_setattr_args /* {
                    588:                struct vnode *a_vp;
                    589:                struct vattr *a_vap;
1.92      elad      590:                kauth_cred_t a_cred;
1.30      christos  591:        } */ *ap = v;
1.102     ad        592:        file_t *fp;
1.1       cgd       593:        unsigned fd;
                    594:
                    595:        /*
                    596:         * Can't mess with the root vnode
                    597:         */
1.14      mycroft   598:        switch (VTOFDESC(ap->a_vp)->fd_type) {
1.8       cgd       599:        case Fdesc:
                    600:                break;
                    601:
                    602:        case Fctty:
                    603:                return (0);
                    604:
                    605:        default:
1.1       cgd       606:                return (EACCES);
1.8       cgd       607:        }
1.1       cgd       608:
1.14      mycroft   609:        fd = VTOFDESC(ap->a_vp)->fd_fd;
1.102     ad        610:        if ((fp = fd_getfile(fd)) == NULL)
1.1       cgd       611:                return (EBADF);
                    612:
                    613:        /*
1.68      jmc       614:         * XXX: Can't reasonably set the attr's on any types currently.
                    615:         *      On vnode's this will cause truncation and socket/pipes make
                    616:         *      no sense.
1.1       cgd       617:         */
1.102     ad        618:        fd_putfile(fd);
1.69      jdolecek  619:        return (0);
1.1       cgd       620: }
                    621:
1.8       cgd       622:
1.25      mycroft   623: struct fdesc_target {
                    624:        ino_t ft_fileno;
                    625:        u_char ft_type;
                    626:        u_char ft_namlen;
1.84      christos  627:        const char *ft_name;
1.25      mycroft   628: } fdesc_targets[] = {
                    629: #define N(s) sizeof(s)-1, s
                    630:        { FD_DEVFD,  DT_DIR,     N("fd")     },
1.27      mycroft   631:        { FD_STDIN,  DT_LNK,     N("stdin")  },
                    632:        { FD_STDOUT, DT_LNK,     N("stdout") },
                    633:        { FD_STDERR, DT_LNK,     N("stderr") },
1.25      mycroft   634:        { FD_CTTY,   DT_UNKNOWN, N("tty")    },
                    635: #undef N
1.85      christos  636: #define UIO_MX _DIRENT_RECLEN((struct dirent *)NULL, sizeof("stderr") - 1)
1.8       cgd       637: };
1.25      mycroft   638: static int nfdesc_targets = sizeof(fdesc_targets) / sizeof(fdesc_targets[0]);
1.8       cgd       639:
1.14      mycroft   640: int
1.105     dsl       641: fdesc_readdir(void *v)
1.30      christos  642: {
1.14      mycroft   643:        struct vop_readdir_args /* {
                    644:                struct vnode *a_vp;
                    645:                struct uio *a_uio;
1.92      elad      646:                kauth_cred_t a_cred;
1.22      mycroft   647:                int *a_eofflag;
1.44      fvdl      648:                off_t **a_cookies;
                    649:                int *a_ncookies;
1.30      christos  650:        } */ *ap = v;
1.14      mycroft   651:        struct uio *uio = ap->a_uio;
1.25      mycroft   652:        struct dirent d;
1.102     ad        653:        filedesc_t *fdp;
1.53      sommerfe  654:        off_t i;
1.87      christos  655:        int j;
1.1       cgd       656:        int error;
1.44      fvdl      657:        off_t *cookies = NULL;
1.87      christos  658:        int ncookies;
1.11      ws        659:
1.14      mycroft   660:        switch (VTOFDESC(ap->a_vp)->fd_type) {
1.8       cgd       661:        case Fctty:
1.87      christos  662:                return 0;
1.8       cgd       663:
                    664:        case Fdesc:
1.87      christos  665:                return ENOTDIR;
1.30      christos  666:
                    667:        default:
                    668:                break;
1.8       cgd       669:        }
1.1       cgd       670:
1.90      yamt      671:        fdp = curproc->p_fd;
1.8       cgd       672:
1.25      mycroft   673:        if (uio->uio_resid < UIO_MX)
1.87      christos  674:                return EINVAL;
1.26      mycroft   675:        if (uio->uio_offset < 0)
1.87      christos  676:                return EINVAL;
1.25      mycroft   677:
                    678:        error = 0;
1.26      mycroft   679:        i = uio->uio_offset;
1.87      christos  680:        (void)memset(&d, 0, UIO_MX);
1.25      mycroft   681:        d.d_reclen = UIO_MX;
1.44      fvdl      682:        if (ap->a_ncookies)
1.87      christos  683:                ncookies = uio->uio_resid / UIO_MX;
                    684:        else
                    685:                ncookies = 0;
1.25      mycroft   686:
1.14      mycroft   687:        if (VTOFDESC(ap->a_vp)->fd_type == Froot) {
1.25      mycroft   688:                struct fdesc_target *ft;
1.51      christos  689:
                    690:                if (i >= nfdesc_targets)
1.52      sommerfe  691:                        return 0;
1.3       cgd       692:
1.44      fvdl      693:                if (ap->a_ncookies) {
                    694:                        ncookies = min(ncookies, (nfdesc_targets - i));
1.56      thorpej   695:                        cookies = malloc(ncookies * sizeof(off_t),
1.44      fvdl      696:                            M_TEMP, M_WAITOK);
                    697:                        *ap->a_cookies = cookies;
                    698:                        *ap->a_ncookies = ncookies;
                    699:                }
                    700:
1.87      christos  701:                for (ft = &fdesc_targets[i]; uio->uio_resid >= UIO_MX &&
                    702:                    i < nfdesc_targets; ft++, i++) {
1.25      mycroft   703:                        switch (ft->ft_fileno) {
1.8       cgd       704:                        case FD_CTTY:
1.90      yamt      705:                                if (cttyvp(curproc) == NULL)
1.8       cgd       706:                                        continue;
                    707:                                break;
                    708:
                    709:                        case FD_STDIN:
                    710:                        case FD_STDOUT:
                    711:                        case FD_STDERR:
1.87      christos  712:                                if (fdp == NULL)
1.8       cgd       713:                                        continue;
1.87      christos  714:                                if ((ft->ft_fileno - FD_STDIN) >=
                    715:                                    fdp->fd_nfiles)
                    716:                                        continue;
1.102     ad        717:                                membar_consumer();
1.87      christos  718:                                if (fdp->fd_ofiles[ft->ft_fileno - FD_STDIN]
1.102     ad        719:                                    == NULL || fdp->fd_ofiles[ft->ft_fileno -
                    720:                                    FD_STDIN]->ff_file == NULL)
1.8       cgd       721:                                        continue;
                    722:                                break;
                    723:                        }
1.25      mycroft   724:
                    725:                        d.d_fileno = ft->ft_fileno;
                    726:                        d.d_namlen = ft->ft_namlen;
1.87      christos  727:                        (void)memcpy(d.d_name, ft->ft_name, ft->ft_namlen + 1);
1.25      mycroft   728:                        d.d_type = ft->ft_type;
                    729:
1.81      jrf       730:                        if ((error = uiomove(&d, UIO_MX, uio)) != 0)
1.8       cgd       731:                                break;
1.44      fvdl      732:                        if (cookies)
1.26      mycroft   733:                                *cookies++ = i + 1;
1.3       cgd       734:                }
1.25      mycroft   735:        } else {
1.87      christos  736:                int nfdp = fdp ? fdp->fd_nfiles : 0;
1.102     ad        737:                membar_consumer();
1.44      fvdl      738:                if (ap->a_ncookies) {
1.87      christos  739:                        ncookies = min(ncookies, nfdp + 2);
1.56      thorpej   740:                        cookies = malloc(ncookies * sizeof(off_t),
                    741:                            M_TEMP, M_WAITOK);
1.44      fvdl      742:                        *ap->a_cookies = cookies;
                    743:                        *ap->a_ncookies = ncookies;
                    744:                }
1.87      christos  745:                for (; i - 2 < nfdp && uio->uio_resid >= UIO_MX; i++) {
1.25      mycroft   746:                        switch (i) {
                    747:                        case 0:
                    748:                        case 1:
                    749:                                d.d_fileno = FD_ROOT;           /* XXX */
                    750:                                d.d_namlen = i + 1;
1.87      christos  751:                                (void)memcpy(d.d_name, "..", d.d_namlen);
1.25      mycroft   752:                                d.d_name[i + 1] = '\0';
                    753:                                d.d_type = DT_DIR;
                    754:                                break;
1.83      perry     755:
1.25      mycroft   756:                        default:
1.87      christos  757:                                KASSERT(fdp != NULL);
                    758:                                j = (int)i - 2;
1.91      christos  759:                                if (fdp == NULL || fdp->fd_ofiles[j] == NULL ||
1.102     ad        760:                                    fdp->fd_ofiles[j]->ff_file == NULL)
1.25      mycroft   761:                                        continue;
1.87      christos  762:                                d.d_fileno = j + FD_STDIN;
                    763:                                d.d_namlen = sprintf(d.d_name, "%d", j);
1.25      mycroft   764:                                d.d_type = DT_UNKNOWN;
                    765:                                break;
                    766:                        }
1.8       cgd       767:
1.81      jrf       768:                        if ((error = uiomove(&d, UIO_MX, uio)) != 0)
1.1       cgd       769:                                break;
1.44      fvdl      770:                        if (cookies)
1.26      mycroft   771:                                *cookies++ = i + 1;
1.1       cgd       772:                }
1.8       cgd       773:        }
                    774:
1.44      fvdl      775:        if (ap->a_ncookies && error) {
1.56      thorpej   776:                free(*ap->a_cookies, M_TEMP);
1.44      fvdl      777:                *ap->a_ncookies = 0;
                    778:                *ap->a_cookies = NULL;
                    779:        }
                    780:
1.26      mycroft   781:        uio->uio_offset = i;
1.87      christos  782:        return error;
1.8       cgd       783: }
                    784:
1.14      mycroft   785: int
1.105     dsl       786: fdesc_readlink(void *v)
1.30      christos  787: {
1.14      mycroft   788:        struct vop_readlink_args /* {
                    789:                struct vnode *a_vp;
                    790:                struct uio *a_uio;
1.92      elad      791:                kauth_cred_t a_cred;
1.30      christos  792:        } */ *ap = v;
1.14      mycroft   793:        struct vnode *vp = ap->a_vp;
1.8       cgd       794:        int error;
                    795:
1.14      mycroft   796:        if (vp->v_type != VLNK)
                    797:                return (EPERM);
                    798:
1.8       cgd       799:        if (VTOFDESC(vp)->fd_type == Flink) {
                    800:                char *ln = VTOFDESC(vp)->fd_link;
1.14      mycroft   801:                error = uiomove(ln, strlen(ln), ap->a_uio);
1.8       cgd       802:        } else {
                    803:                error = EOPNOTSUPP;
                    804:        }
                    805:
                    806:        return (error);
                    807: }
                    808:
1.14      mycroft   809: int
1.105     dsl       810: fdesc_read(void *v)
1.30      christos  811: {
1.14      mycroft   812:        struct vop_read_args /* {
                    813:                struct vnode *a_vp;
                    814:                struct uio *a_uio;
                    815:                int  a_ioflag;
1.92      elad      816:                kauth_cred_t a_cred;
1.30      christos  817:        } */ *ap = v;
1.8       cgd       818:        int error = EOPNOTSUPP;
1.49      thorpej   819:        struct vnode *vp = ap->a_vp;
1.8       cgd       820:
1.49      thorpej   821:        switch (VTOFDESC(vp)->fd_type) {
1.8       cgd       822:        case Fctty:
1.49      thorpej   823:                VOP_UNLOCK(vp, 0);
1.97      ad        824:                error = cdev_read(devctty, ap->a_uio, ap->a_ioflag);
1.49      thorpej   825:                vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
1.8       cgd       826:                break;
                    827:
                    828:        default:
                    829:                error = EOPNOTSUPP;
                    830:                break;
                    831:        }
1.83      perry     832:
1.8       cgd       833:        return (error);
                    834: }
                    835:
1.14      mycroft   836: int
1.105     dsl       837: fdesc_write(void *v)
1.30      christos  838: {
1.14      mycroft   839:        struct vop_write_args /* {
                    840:                struct vnode *a_vp;
                    841:                struct uio *a_uio;
                    842:                int  a_ioflag;
1.92      elad      843:                kauth_cred_t a_cred;
1.30      christos  844:        } */ *ap = v;
1.8       cgd       845:        int error = EOPNOTSUPP;
1.49      thorpej   846:        struct vnode *vp = ap->a_vp;
1.8       cgd       847:
1.49      thorpej   848:        switch (VTOFDESC(vp)->fd_type) {
1.8       cgd       849:        case Fctty:
1.49      thorpej   850:                VOP_UNLOCK(vp, 0);
1.97      ad        851:                error = cdev_write(devctty, ap->a_uio, ap->a_ioflag);
1.49      thorpej   852:                vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
1.8       cgd       853:                break;
                    854:
                    855:        default:
                    856:                error = EOPNOTSUPP;
                    857:                break;
                    858:        }
1.83      perry     859:
1.8       cgd       860:        return (error);
                    861: }
                    862:
1.14      mycroft   863: int
1.105     dsl       864: fdesc_ioctl(void *v)
1.30      christos  865: {
1.14      mycroft   866:        struct vop_ioctl_args /* {
                    867:                struct vnode *a_vp;
1.19      cgd       868:                u_long a_command;
1.81      jrf       869:                void *a_data;
1.14      mycroft   870:                int  a_fflag;
1.92      elad      871:                kauth_cred_t a_cred;
1.30      christos  872:        } */ *ap = v;
1.8       cgd       873:        int error = EOPNOTSUPP;
                    874:
1.14      mycroft   875:        switch (VTOFDESC(ap->a_vp)->fd_type) {
1.8       cgd       876:        case Fctty:
1.97      ad        877:                error = cdev_ioctl(devctty, ap->a_command, ap->a_data,
1.100     pooka     878:                    ap->a_fflag, curlwp);
1.8       cgd       879:                break;
                    880:
                    881:        default:
                    882:                error = EOPNOTSUPP;
                    883:                break;
1.1       cgd       884:        }
1.83      perry     885:
1.8       cgd       886:        return (error);
                    887: }
                    888:
1.14      mycroft   889: int
1.105     dsl       890: fdesc_poll(void *v)
1.30      christos  891: {
1.35      mycroft   892:        struct vop_poll_args /* {
1.14      mycroft   893:                struct vnode *a_vp;
1.35      mycroft   894:                int a_events;
1.30      christos  895:        } */ *ap = v;
1.35      mycroft   896:        int revents;
1.8       cgd       897:
1.14      mycroft   898:        switch (VTOFDESC(ap->a_vp)->fd_type) {
1.8       cgd       899:        case Fctty:
1.100     pooka     900:                revents = cdev_poll(devctty, ap->a_events, curlwp);
1.8       cgd       901:                break;
1.1       cgd       902:
1.8       cgd       903:        default:
1.35      mycroft   904:                revents = genfs_poll(v);
1.8       cgd       905:                break;
                    906:        }
1.34      mycroft   907:
1.35      mycroft   908:        return (revents);
1.71      jdolecek  909: }
                    910:
                    911: int
1.105     dsl       912: fdesc_kqfilter(void *v)
1.71      jdolecek  913: {
                    914:        struct vop_kqfilter_args /* {
                    915:                struct vnode *a_vp;
                    916:                struct knote *a_kn;
                    917:        } */ *ap = v;
1.102     ad        918:        int error, fd;
                    919:        file_t *fp;
1.71      jdolecek  920:
                    921:        switch (VTOFDESC(ap->a_vp)->fd_type) {
                    922:        case Fctty:
1.97      ad        923:                error = cdev_kqfilter(devctty, ap->a_kn);
1.71      jdolecek  924:                break;
                    925:
                    926:        case Fdesc:
                    927:                /* just invoke kqfilter for the underlying descriptor */
1.102     ad        928:                fd = VTOFDESC(ap->a_vp)->fd_fd;
                    929:                if ((fp = fd_getfile(fd)) == NULL)
1.71      jdolecek  930:                        return (1);
                    931:                error = (*fp->f_ops->fo_kqfilter)(fp, ap->a_kn);
1.102     ad        932:                fd_putfile(fd);
1.71      jdolecek  933:                break;
                    934:
                    935:        default:
                    936:                return (genfs_kqfilter(v));
                    937:        }
                    938:
                    939:        return (error);
1.1       cgd       940: }
                    941:
1.14      mycroft   942: int
1.105     dsl       943: fdesc_inactive(void *v)
1.30      christos  944: {
1.14      mycroft   945:        struct vop_inactive_args /* {
                    946:                struct vnode *a_vp;
1.30      christos  947:        } */ *ap = v;
1.14      mycroft   948:        struct vnode *vp = ap->a_vp;
                    949:
1.1       cgd       950:        /*
                    951:         * Clear out the v_type field to avoid
                    952:         * nasty things happening in vgone().
                    953:         */
1.44      fvdl      954:        VOP_UNLOCK(vp, 0);
1.1       cgd       955:        vp->v_type = VNON;
                    956:        return (0);
                    957: }
                    958:
1.14      mycroft   959: int
1.105     dsl       960: fdesc_reclaim(void *v)
1.30      christos  961: {
1.14      mycroft   962:        struct vop_reclaim_args /* {
                    963:                struct vnode *a_vp;
1.30      christos  964:        } */ *ap = v;
1.14      mycroft   965:        struct vnode *vp = ap->a_vp;
1.17      mycroft   966:        struct fdescnode *fd = VTOFDESC(vp);
1.14      mycroft   967:
1.17      mycroft   968:        LIST_REMOVE(fd, fd_hash);
1.104     cegger    969:        free(vp->v_data, M_TEMP);
1.14      mycroft   970:        vp->v_data = 0;
                    971:
                    972:        return (0);
                    973: }
                    974:
                    975: /*
                    976:  * Return POSIX pathconf information applicable to special devices.
                    977:  */
1.30      christos  978: int
1.105     dsl       979: fdesc_pathconf(void *v)
1.30      christos  980: {
1.14      mycroft   981:        struct vop_pathconf_args /* {
                    982:                struct vnode *a_vp;
                    983:                int a_name;
1.18      cgd       984:                register_t *a_retval;
1.30      christos  985:        } */ *ap = v;
1.8       cgd       986:
1.14      mycroft   987:        switch (ap->a_name) {
                    988:        case _PC_LINK_MAX:
                    989:                *ap->a_retval = LINK_MAX;
                    990:                return (0);
                    991:        case _PC_MAX_CANON:
                    992:                *ap->a_retval = MAX_CANON;
                    993:                return (0);
                    994:        case _PC_MAX_INPUT:
                    995:                *ap->a_retval = MAX_INPUT;
                    996:                return (0);
                    997:        case _PC_PIPE_BUF:
                    998:                *ap->a_retval = PIPE_BUF;
                    999:                return (0);
                   1000:        case _PC_CHOWN_RESTRICTED:
                   1001:                *ap->a_retval = 1;
                   1002:                return (0);
                   1003:        case _PC_VDISABLE:
                   1004:                *ap->a_retval = _POSIX_VDISABLE;
1.45      kleink   1005:                return (0);
                   1006:        case _PC_SYNC_IO:
                   1007:                *ap->a_retval = 1;
1.14      mycroft  1008:                return (0);
                   1009:        default:
                   1010:                return (EINVAL);
1.8       cgd      1011:        }
1.14      mycroft  1012:        /* NOTREACHED */
1.8       cgd      1013: }
                   1014:
1.1       cgd      1015: /*
                   1016:  * Print out the contents of a /dev/fd vnode.
                   1017:  */
                   1018: /* ARGSUSED */
1.14      mycroft  1019: int
1.94      christos 1020: fdesc_print(void *v)
1.1       cgd      1021: {
1.37      christos 1022:        printf("tag VT_NON, fdesc vnode\n");
1.14      mycroft  1023:        return (0);
                   1024: }
                   1025:
                   1026: int
1.105     dsl      1027: fdesc_link(void *v)
1.30      christos 1028: {
1.29      mycroft  1029:        struct vop_link_args /* {
                   1030:                struct vnode *a_dvp;
1.83      perry    1031:                struct vnode *a_vp;
1.29      mycroft  1032:                struct componentname *a_cnp;
1.30      christos 1033:        } */ *ap = v;
1.83      perry    1034:
1.29      mycroft  1035:        VOP_ABORTOP(ap->a_dvp, ap->a_cnp);
                   1036:        vput(ap->a_dvp);
                   1037:        return (EROFS);
                   1038: }
                   1039:
                   1040: int
1.105     dsl      1041: fdesc_symlink(void *v)
1.30      christos 1042: {
1.29      mycroft  1043:        struct vop_symlink_args /* {
                   1044:                struct vnode *a_dvp;
                   1045:                struct vnode **a_vpp;
                   1046:                struct componentname *a_cnp;
                   1047:                struct vattr *a_vap;
                   1048:                char *a_target;
1.30      christos 1049:        } */ *ap = v;
1.83      perry    1050:
1.29      mycroft  1051:        VOP_ABORTOP(ap->a_dvp, ap->a_cnp);
                   1052:        vput(ap->a_dvp);
                   1053:        return (EROFS);
1.1       cgd      1054: }

CVSweb <webmaster@jp.NetBSD.org>