[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.119

1.119   ! christos    1: /*     $NetBSD: fdesc_vnops.c,v 1.118 2014/02/27 16:51:38 hannken 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.119   ! christos   44: __KERNEL_RCSID(0, "$NetBSD: fdesc_vnops.c,v 1.118 2014/02/27 16:51:38 hannken 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:
1.111     hannken    72: static kmutex_t fdcache_lock;
1.14      mycroft    73:
                     74: dev_t devctty;
1.8       cgd        75:
                     76: #if (FD_STDIN != FD_STDOUT-1) || (FD_STDOUT != FD_STDERR-1)
                     77: FD_STDIN, FD_STDOUT, FD_STDERR must be a sequence n, n+1, n+2
                     78: #endif
                     79:
1.16      mycroft    80: #define        NFDCACHE 4
1.14      mycroft    81:
1.17      mycroft    82: #define FD_NHASH(ix) \
                     83:        (&fdhashtbl[(ix) & fdhash])
                     84: LIST_HEAD(fdhashhead, fdescnode) *fdhashtbl;
                     85: u_long fdhash;
1.14      mycroft    86:
1.86      xtraeme    87: int    fdesc_lookup(void *);
1.74      jdolecek   88: #define        fdesc_create    genfs_eopnotsupp
                     89: #define        fdesc_mknod     genfs_eopnotsupp
1.86      xtraeme    90: int    fdesc_open(void *);
1.34      mycroft    91: #define        fdesc_close     genfs_nullop
                     92: #define        fdesc_access    genfs_nullop
1.86      xtraeme    93: int    fdesc_getattr(void *);
                     94: int    fdesc_setattr(void *);
                     95: int    fdesc_read(void *);
                     96: int    fdesc_write(void *);
                     97: int    fdesc_ioctl(void *);
                     98: int    fdesc_poll(void *);
                     99: int    fdesc_kqfilter(void *);
1.34      mycroft   100: #define        fdesc_mmap      genfs_eopnotsupp
1.50      wrstuden  101: #define        fdesc_fcntl     genfs_fcntl
1.34      mycroft   102: #define        fdesc_fsync     genfs_nullop
1.40      fvdl      103: #define        fdesc_seek      genfs_seek
1.74      jdolecek  104: #define        fdesc_remove    genfs_eopnotsupp
1.86      xtraeme   105: int    fdesc_link(void *);
1.74      jdolecek  106: #define        fdesc_rename    genfs_eopnotsupp
                    107: #define        fdesc_mkdir     genfs_eopnotsupp
                    108: #define        fdesc_rmdir     genfs_eopnotsupp
1.86      xtraeme   109: int    fdesc_symlink(void *);
                    110: int    fdesc_readdir(void *);
                    111: int    fdesc_readlink(void *);
1.34      mycroft   112: #define        fdesc_abortop   genfs_abortop
1.86      xtraeme   113: int    fdesc_inactive(void *);
                    114: int    fdesc_reclaim(void *);
1.48      wrstuden  115: #define        fdesc_lock      genfs_lock
                    116: #define        fdesc_unlock    genfs_unlock
1.34      mycroft   117: #define        fdesc_bmap      genfs_badop
                    118: #define        fdesc_strategy  genfs_badop
1.86      xtraeme   119: int    fdesc_print(void *);
                    120: int    fdesc_pathconf(void *);
1.48      wrstuden  121: #define        fdesc_islocked  genfs_islocked
1.47      kleink    122: #define        fdesc_advlock   genfs_einval
1.34      mycroft   123: #define        fdesc_bwrite    genfs_eopnotsupp
1.44      fvdl      124: #define fdesc_revoke   genfs_revoke
1.67      chs       125: #define fdesc_putpages genfs_null_putpages
1.30      christos  126:
1.102     ad        127: static int fdesc_attr(int, struct vattr *, kauth_cred_t);
1.30      christos  128:
1.86      xtraeme   129: int (**fdesc_vnodeop_p)(void *);
1.58      jdolecek  130: const struct vnodeopv_entry_desc fdesc_vnodeop_entries[] = {
1.30      christos  131:        { &vop_default_desc, vn_default_error },
1.34      mycroft   132:        { &vop_lookup_desc, fdesc_lookup },             /* lookup */
                    133:        { &vop_create_desc, fdesc_create },             /* create */
                    134:        { &vop_mknod_desc, fdesc_mknod },               /* mknod */
                    135:        { &vop_open_desc, fdesc_open },                 /* open */
                    136:        { &vop_close_desc, fdesc_close },               /* close */
                    137:        { &vop_access_desc, fdesc_access },             /* access */
                    138:        { &vop_getattr_desc, fdesc_getattr },           /* getattr */
                    139:        { &vop_setattr_desc, fdesc_setattr },           /* setattr */
                    140:        { &vop_read_desc, fdesc_read },                 /* read */
                    141:        { &vop_write_desc, fdesc_write },               /* write */
                    142:        { &vop_ioctl_desc, fdesc_ioctl },               /* ioctl */
1.50      wrstuden  143:        { &vop_fcntl_desc, fdesc_fcntl },               /* fcntl */
1.35      mycroft   144:        { &vop_poll_desc, fdesc_poll },                 /* poll */
1.71      jdolecek  145:        { &vop_kqfilter_desc, fdesc_kqfilter },         /* kqfilter */
1.44      fvdl      146:        { &vop_revoke_desc, fdesc_revoke },             /* revoke */
1.34      mycroft   147:        { &vop_mmap_desc, fdesc_mmap },                 /* mmap */
                    148:        { &vop_fsync_desc, fdesc_fsync },               /* fsync */
                    149:        { &vop_seek_desc, fdesc_seek },                 /* seek */
                    150:        { &vop_remove_desc, fdesc_remove },             /* remove */
                    151:        { &vop_link_desc, fdesc_link },                 /* link */
                    152:        { &vop_rename_desc, fdesc_rename },             /* rename */
                    153:        { &vop_mkdir_desc, fdesc_mkdir },               /* mkdir */
                    154:        { &vop_rmdir_desc, fdesc_rmdir },               /* rmdir */
                    155:        { &vop_symlink_desc, fdesc_symlink },           /* symlink */
                    156:        { &vop_readdir_desc, fdesc_readdir },           /* readdir */
                    157:        { &vop_readlink_desc, fdesc_readlink },         /* readlink */
                    158:        { &vop_abortop_desc, fdesc_abortop },           /* abortop */
                    159:        { &vop_inactive_desc, fdesc_inactive },         /* inactive */
                    160:        { &vop_reclaim_desc, fdesc_reclaim },           /* reclaim */
                    161:        { &vop_lock_desc, fdesc_lock },                 /* lock */
                    162:        { &vop_unlock_desc, fdesc_unlock },             /* unlock */
                    163:        { &vop_bmap_desc, fdesc_bmap },                 /* bmap */
                    164:        { &vop_strategy_desc, fdesc_strategy },         /* strategy */
                    165:        { &vop_print_desc, fdesc_print },               /* print */
                    166:        { &vop_islocked_desc, fdesc_islocked },         /* islocked */
                    167:        { &vop_pathconf_desc, fdesc_pathconf },         /* pathconf */
                    168:        { &vop_advlock_desc, fdesc_advlock },           /* advlock */
                    169:        { &vop_bwrite_desc, fdesc_bwrite },             /* bwrite */
1.67      chs       170:        { &vop_putpages_desc, fdesc_putpages },         /* putpages */
                    171:        { NULL, NULL }
1.30      christos  172: };
                    173:
1.58      jdolecek  174: const struct vnodeopv_desc fdesc_vnodeop_opv_desc =
1.30      christos  175:        { &fdesc_vnodeop_p, fdesc_vnodeop_entries };
                    176:
1.14      mycroft   177: /*
                    178:  * Initialise cache headers
                    179:  */
1.30      christos  180: void
1.106     cegger    181: fdesc_init(void)
1.14      mycroft   182: {
1.32      mrg       183:        int cttymajor;
1.14      mycroft   184:
1.32      mrg       185:        /* locate the major number */
1.108     pooka     186:        cttymajor = devsw_name2chr("ctty", NULL, 0);
1.32      mrg       187:        devctty = makedev(cttymajor, 0);
1.111     hannken   188:        mutex_init(&fdcache_lock, MUTEX_DEFAULT, IPL_NONE);
1.103     ad        189:        fdhashtbl = hashinit(NFDCACHE, HASH_LIST, true, &fdhash);
1.54      jdolecek  190: }
                    191:
                    192: /*
                    193:  * Free hash table.
                    194:  */
                    195: void
1.106     cegger    196: fdesc_done(void)
1.54      jdolecek  197: {
1.103     ad        198:        hashdone(fdhashtbl, HASH_LIST, fdhash);
1.111     hannken   199:        mutex_destroy(&fdcache_lock);
1.14      mycroft   200: }
                    201:
1.48      wrstuden  202: /*
                    203:  * Return a locked vnode of the correct type.
                    204:  */
1.14      mycroft   205: int
1.105     dsl       206: fdesc_allocvp(fdntype ftype, int ix, struct mount *mp, struct vnode **vpp)
1.8       cgd       207: {
1.17      mycroft   208:        struct fdhashhead *fc;
1.14      mycroft   209:        struct fdescnode *fd;
1.8       cgd       210:        int error = 0;
                    211:
1.17      mycroft   212:        fc = FD_NHASH(ix);
1.8       cgd       213: loop:
1.111     hannken   214:        mutex_enter(&fdcache_lock);
                    215:        LIST_FOREACH(fd, fc, fd_hash) {
1.14      mycroft   216:                if (fd->fd_ix == ix && fd->fd_vnode->v_mount == mp) {
1.113     rmind     217:                        mutex_enter(fd->fd_vnode->v_interlock);
1.111     hannken   218:                        mutex_exit(&fdcache_lock);
1.112     hannken   219:                        if (vget(fd->fd_vnode, LK_EXCLUSIVE))
1.8       cgd       220:                                goto loop;
1.14      mycroft   221:                        *vpp = fd->fd_vnode;
1.111     hannken   222:                        return 0;
1.8       cgd       223:                }
                    224:        }
1.111     hannken   225:        mutex_exit(&fdcache_lock);
                    226:
1.113     rmind     227:        error = getnewvnode(VT_FDESC, mp, fdesc_vnodeop_p, NULL, vpp);
1.111     hannken   228:        if (error)
                    229:                return error;
1.8       cgd       230:
1.111     hannken   231:        mutex_enter(&fdcache_lock);
                    232:        LIST_FOREACH(fd, fc, fd_hash) {
                    233:                if (fd->fd_ix == ix && fd->fd_vnode->v_mount == mp) {
                    234:                        /*
                    235:                         * Another thread beat us, push back freshly
                    236:                         * allocated vnode and retry.
                    237:                         */
                    238:                        mutex_exit(&fdcache_lock);
                    239:                        ungetnewvnode(*vpp);
                    240:                        goto loop;
                    241:                }
1.8       cgd       242:        }
1.1       cgd       243:
1.104     cegger    244:        fd = malloc(sizeof(struct fdescnode), M_TEMP, M_WAITOK);
1.14      mycroft   245:        (*vpp)->v_data = fd;
                    246:        fd->fd_vnode = *vpp;
                    247:        fd->fd_type = ftype;
                    248:        fd->fd_fd = -1;
                    249:        fd->fd_link = 0;
                    250:        fd->fd_ix = ix;
1.98      pooka     251:        uvm_vnp_setsize(*vpp, 0);
1.118     hannken   252:        error = VOP_LOCK(*vpp, LK_EXCLUSIVE);
                    253:        KASSERT(error == 0);
1.17      mycroft   254:        LIST_INSERT_HEAD(fc, fd, fd_hash);
1.111     hannken   255:        mutex_exit(&fdcache_lock);
1.8       cgd       256:
1.111     hannken   257:        return 0;
1.8       cgd       258: }
1.1       cgd       259:
                    260: /*
                    261:  * vp is the current namei directory
                    262:  * ndp is the name to locate in that directory...
                    263:  */
1.14      mycroft   264: int
1.105     dsl       265: fdesc_lookup(void *v)
1.30      christos  266: {
1.117     hannken   267:        struct vop_lookup_v2_args /* {
1.14      mycroft   268:                struct vnode * a_dvp;
                    269:                struct vnode ** a_vpp;
                    270:                struct componentname * a_cnp;
1.30      christos  271:        } */ *ap = v;
1.14      mycroft   272:        struct vnode **vpp = ap->a_vpp;
                    273:        struct vnode *dvp = ap->a_dvp;
1.44      fvdl      274:        struct componentname *cnp = ap->a_cnp;
1.101     pooka     275:        struct lwp *l = curlwp;
1.44      fvdl      276:        const char *pname = cnp->cn_nameptr;
1.89      christos  277:        struct proc *p = l->l_proc;
1.30      christos  278:        unsigned fd = 0;
1.1       cgd       279:        int error;
                    280:        struct vnode *fvp;
1.84      christos  281:        const char *ln;
1.107     ad        282:        fdtab_t *dt;
                    283:
                    284:        dt = curlwp->l_fd->fd_dt;
1.1       cgd       285:
1.44      fvdl      286:        if (cnp->cn_namelen == 1 && *pname == '.') {
1.14      mycroft   287:                *vpp = dvp;
1.109     pooka     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.110     hannken   362:                        VOP_UNLOCK(dvp);
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.107     ad        373:                        if (fd >= dt->dt_nfiles)
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.107     ad        382:                if (fd >= dt->dt_nfiles || dt->dt_ff[fd] == NULL ||
                    383:                    dt->dt_ff[fd]->ff_file == NULL) {
1.8       cgd       384:                        error = EBADF;
                    385:                        goto bad;
                    386:                }
1.1       cgd       387:
1.8       cgd       388:                error = fdesc_allocvp(Fdesc, FD_DESC+fd, dvp->v_mount, &fvp);
                    389:                if (error)
                    390:                        goto bad;
                    391:                VTOFDESC(fvp)->fd_fd = fd;
1.14      mycroft   392:                *vpp = fvp;
1.48      wrstuden  393:                goto good;
1.8       cgd       394:        }
1.1       cgd       395:
1.95      chs       396: bad:
1.14      mycroft   397:        *vpp = NULL;
1.1       cgd       398:        return (error);
1.48      wrstuden  399:
1.95      chs       400: good:
1.117     hannken   401:        VOP_UNLOCK(*vpp);
1.48      wrstuden  402:        return (0);
1.1       cgd       403: }
                    404:
1.14      mycroft   405: int
1.105     dsl       406: fdesc_open(void *v)
1.30      christos  407: {
1.14      mycroft   408:        struct vop_open_args /* {
                    409:                struct vnode *a_vp;
                    410:                int  a_mode;
1.92      elad      411:                kauth_cred_t a_cred;
1.30      christos  412:        } */ *ap = v;
1.14      mycroft   413:        struct vnode *vp = ap->a_vp;
1.8       cgd       414:
                    415:        switch (VTOFDESC(vp)->fd_type) {
                    416:        case Fdesc:
1.23      mycroft   417:                /*
1.79      jdolecek  418:                 * XXX Kludge: set dupfd to contain the value of the
1.83      perry     419:                 * the file descriptor being sought for duplication. The error
1.23      mycroft   420:                 * return ensures that the vnode for this device will be
                    421:                 * released by vn_open. Open will detect this special error and
                    422:                 * take the actions in dupfdopen.  Other callers of vn_open or
                    423:                 * VOP_OPEN will simply report the error.
                    424:                 */
1.79      jdolecek  425:                curlwp->l_dupfd = VTOFDESC(vp)->fd_fd;  /* XXX */
1.82      christos  426:                return EDUPFD;
1.1       cgd       427:
1.8       cgd       428:        case Fctty:
1.100     pooka     429:                return cdev_open(devctty, ap->a_mode, 0, curlwp);
1.30      christos  430:        case Froot:
                    431:        case Fdevfd:
                    432:        case Flink:
                    433:                break;
1.8       cgd       434:        }
1.1       cgd       435:
1.21      mycroft   436:        return (0);
1.1       cgd       437: }
                    438:
                    439: static int
1.105     dsl       440: fdesc_attr(int fd, struct vattr *vap, kauth_cred_t cred)
1.1       cgd       441: {
1.102     ad        442:        file_t *fp;
1.8       cgd       443:        struct stat stb;
1.1       cgd       444:        int error;
                    445:
1.102     ad        446:        if ((fp = fd_getfile(fd)) == NULL)
1.1       cgd       447:                return (EBADF);
                    448:
                    449:        switch (fp->f_type) {
                    450:        case DTYPE_VNODE:
1.114     hannken   451:                vn_lock((struct vnode *) fp->f_data, LK_SHARED | LK_RETRY);
1.100     pooka     452:                error = VOP_GETATTR((struct vnode *) fp->f_data, vap, cred);
1.114     hannken   453:                VOP_UNLOCK((struct vnode *) fp->f_data);
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.109     pooka     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.53      sommerfe  653:        off_t i;
1.87      christos  654:        int j;
1.1       cgd       655:        int error;
1.44      fvdl      656:        off_t *cookies = NULL;
1.87      christos  657:        int ncookies;
1.107     ad        658:        fdtab_t *dt;
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.107     ad        671:        dt = curlwp->l_fd->fd_dt;
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 ((ft->ft_fileno - FD_STDIN) >=
1.107     ad        713:                                    dt->dt_nfiles)
1.87      christos  714:                                        continue;
1.107     ad        715:                                if (dt->dt_ff[ft->ft_fileno - FD_STDIN]
                    716:                                    == NULL || dt->dt_ff[ft->ft_fileno -
1.102     ad        717:                                    FD_STDIN]->ff_file == NULL)
1.8       cgd       718:                                        continue;
                    719:                                break;
                    720:                        }
1.25      mycroft   721:
                    722:                        d.d_fileno = ft->ft_fileno;
                    723:                        d.d_namlen = ft->ft_namlen;
1.87      christos  724:                        (void)memcpy(d.d_name, ft->ft_name, ft->ft_namlen + 1);
1.25      mycroft   725:                        d.d_type = ft->ft_type;
                    726:
1.81      jrf       727:                        if ((error = uiomove(&d, UIO_MX, uio)) != 0)
1.8       cgd       728:                                break;
1.44      fvdl      729:                        if (cookies)
1.26      mycroft   730:                                *cookies++ = i + 1;
1.3       cgd       731:                }
1.25      mycroft   732:        } else {
1.102     ad        733:                membar_consumer();
1.44      fvdl      734:                if (ap->a_ncookies) {
1.107     ad        735:                        ncookies = min(ncookies, dt->dt_nfiles + 2);
1.56      thorpej   736:                        cookies = malloc(ncookies * sizeof(off_t),
                    737:                            M_TEMP, M_WAITOK);
1.44      fvdl      738:                        *ap->a_cookies = cookies;
                    739:                        *ap->a_ncookies = ncookies;
                    740:                }
1.107     ad        741:                for (; i - 2 < dt->dt_nfiles && uio->uio_resid >= UIO_MX; i++) {
1.25      mycroft   742:                        switch (i) {
                    743:                        case 0:
                    744:                        case 1:
                    745:                                d.d_fileno = FD_ROOT;           /* XXX */
                    746:                                d.d_namlen = i + 1;
1.87      christos  747:                                (void)memcpy(d.d_name, "..", d.d_namlen);
1.25      mycroft   748:                                d.d_name[i + 1] = '\0';
                    749:                                d.d_type = DT_DIR;
                    750:                                break;
1.83      perry     751:
1.25      mycroft   752:                        default:
1.87      christos  753:                                j = (int)i - 2;
1.107     ad        754:                                if (dt->dt_ff[j] == NULL ||
                    755:                                    dt->dt_ff[j]->ff_file == NULL)
1.25      mycroft   756:                                        continue;
1.87      christos  757:                                d.d_fileno = j + FD_STDIN;
1.119   ! christos  758:                                d.d_namlen = snprintf(d.d_name,
        !           759:                                    sizeof(d.d_name), "%d", j);
1.25      mycroft   760:                                d.d_type = DT_UNKNOWN;
                    761:                                break;
                    762:                        }
1.8       cgd       763:
1.81      jrf       764:                        if ((error = uiomove(&d, UIO_MX, uio)) != 0)
1.1       cgd       765:                                break;
1.44      fvdl      766:                        if (cookies)
1.26      mycroft   767:                                *cookies++ = i + 1;
1.1       cgd       768:                }
1.8       cgd       769:        }
                    770:
1.44      fvdl      771:        if (ap->a_ncookies && error) {
1.56      thorpej   772:                free(*ap->a_cookies, M_TEMP);
1.44      fvdl      773:                *ap->a_ncookies = 0;
                    774:                *ap->a_cookies = NULL;
                    775:        }
                    776:
1.26      mycroft   777:        uio->uio_offset = i;
1.87      christos  778:        return error;
1.8       cgd       779: }
                    780:
1.14      mycroft   781: int
1.105     dsl       782: fdesc_readlink(void *v)
1.30      christos  783: {
1.14      mycroft   784:        struct vop_readlink_args /* {
                    785:                struct vnode *a_vp;
                    786:                struct uio *a_uio;
1.92      elad      787:                kauth_cred_t a_cred;
1.30      christos  788:        } */ *ap = v;
1.14      mycroft   789:        struct vnode *vp = ap->a_vp;
1.8       cgd       790:        int error;
                    791:
1.14      mycroft   792:        if (vp->v_type != VLNK)
                    793:                return (EPERM);
                    794:
1.8       cgd       795:        if (VTOFDESC(vp)->fd_type == Flink) {
                    796:                char *ln = VTOFDESC(vp)->fd_link;
1.14      mycroft   797:                error = uiomove(ln, strlen(ln), ap->a_uio);
1.8       cgd       798:        } else {
                    799:                error = EOPNOTSUPP;
                    800:        }
                    801:
                    802:        return (error);
                    803: }
                    804:
1.14      mycroft   805: int
1.105     dsl       806: fdesc_read(void *v)
1.30      christos  807: {
1.14      mycroft   808:        struct vop_read_args /* {
                    809:                struct vnode *a_vp;
                    810:                struct uio *a_uio;
                    811:                int  a_ioflag;
1.92      elad      812:                kauth_cred_t a_cred;
1.30      christos  813:        } */ *ap = v;
1.8       cgd       814:        int error = EOPNOTSUPP;
1.49      thorpej   815:        struct vnode *vp = ap->a_vp;
1.8       cgd       816:
1.49      thorpej   817:        switch (VTOFDESC(vp)->fd_type) {
1.8       cgd       818:        case Fctty:
1.110     hannken   819:                VOP_UNLOCK(vp);
1.97      ad        820:                error = cdev_read(devctty, ap->a_uio, ap->a_ioflag);
1.49      thorpej   821:                vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
1.8       cgd       822:                break;
                    823:
                    824:        default:
                    825:                error = EOPNOTSUPP;
                    826:                break;
                    827:        }
1.83      perry     828:
1.8       cgd       829:        return (error);
                    830: }
                    831:
1.14      mycroft   832: int
1.105     dsl       833: fdesc_write(void *v)
1.30      christos  834: {
1.14      mycroft   835:        struct vop_write_args /* {
                    836:                struct vnode *a_vp;
                    837:                struct uio *a_uio;
                    838:                int  a_ioflag;
1.92      elad      839:                kauth_cred_t a_cred;
1.30      christos  840:        } */ *ap = v;
1.8       cgd       841:        int error = EOPNOTSUPP;
1.49      thorpej   842:        struct vnode *vp = ap->a_vp;
1.8       cgd       843:
1.49      thorpej   844:        switch (VTOFDESC(vp)->fd_type) {
1.8       cgd       845:        case Fctty:
1.110     hannken   846:                VOP_UNLOCK(vp);
1.97      ad        847:                error = cdev_write(devctty, ap->a_uio, ap->a_ioflag);
1.49      thorpej   848:                vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
1.8       cgd       849:                break;
                    850:
                    851:        default:
                    852:                error = EOPNOTSUPP;
                    853:                break;
                    854:        }
1.83      perry     855:
1.8       cgd       856:        return (error);
                    857: }
                    858:
1.14      mycroft   859: int
1.105     dsl       860: fdesc_ioctl(void *v)
1.30      christos  861: {
1.14      mycroft   862:        struct vop_ioctl_args /* {
                    863:                struct vnode *a_vp;
1.19      cgd       864:                u_long a_command;
1.81      jrf       865:                void *a_data;
1.14      mycroft   866:                int  a_fflag;
1.92      elad      867:                kauth_cred_t a_cred;
1.30      christos  868:        } */ *ap = v;
1.8       cgd       869:        int error = EOPNOTSUPP;
                    870:
1.14      mycroft   871:        switch (VTOFDESC(ap->a_vp)->fd_type) {
1.8       cgd       872:        case Fctty:
1.97      ad        873:                error = cdev_ioctl(devctty, ap->a_command, ap->a_data,
1.100     pooka     874:                    ap->a_fflag, curlwp);
1.8       cgd       875:                break;
                    876:
                    877:        default:
                    878:                error = EOPNOTSUPP;
                    879:                break;
1.1       cgd       880:        }
1.83      perry     881:
1.8       cgd       882:        return (error);
                    883: }
                    884:
1.14      mycroft   885: int
1.105     dsl       886: fdesc_poll(void *v)
1.30      christos  887: {
1.35      mycroft   888:        struct vop_poll_args /* {
1.14      mycroft   889:                struct vnode *a_vp;
1.35      mycroft   890:                int a_events;
1.30      christos  891:        } */ *ap = v;
1.35      mycroft   892:        int revents;
1.8       cgd       893:
1.14      mycroft   894:        switch (VTOFDESC(ap->a_vp)->fd_type) {
1.8       cgd       895:        case Fctty:
1.100     pooka     896:                revents = cdev_poll(devctty, ap->a_events, curlwp);
1.8       cgd       897:                break;
1.1       cgd       898:
1.8       cgd       899:        default:
1.35      mycroft   900:                revents = genfs_poll(v);
1.8       cgd       901:                break;
                    902:        }
1.34      mycroft   903:
1.35      mycroft   904:        return (revents);
1.71      jdolecek  905: }
                    906:
                    907: int
1.105     dsl       908: fdesc_kqfilter(void *v)
1.71      jdolecek  909: {
                    910:        struct vop_kqfilter_args /* {
                    911:                struct vnode *a_vp;
                    912:                struct knote *a_kn;
                    913:        } */ *ap = v;
1.102     ad        914:        int error, fd;
                    915:        file_t *fp;
1.71      jdolecek  916:
                    917:        switch (VTOFDESC(ap->a_vp)->fd_type) {
                    918:        case Fctty:
1.97      ad        919:                error = cdev_kqfilter(devctty, ap->a_kn);
1.71      jdolecek  920:                break;
                    921:
                    922:        case Fdesc:
                    923:                /* just invoke kqfilter for the underlying descriptor */
1.102     ad        924:                fd = VTOFDESC(ap->a_vp)->fd_fd;
                    925:                if ((fp = fd_getfile(fd)) == NULL)
1.71      jdolecek  926:                        return (1);
                    927:                error = (*fp->f_ops->fo_kqfilter)(fp, ap->a_kn);
1.102     ad        928:                fd_putfile(fd);
1.71      jdolecek  929:                break;
                    930:
                    931:        default:
                    932:                return (genfs_kqfilter(v));
                    933:        }
                    934:
                    935:        return (error);
1.1       cgd       936: }
                    937:
1.14      mycroft   938: int
1.105     dsl       939: fdesc_inactive(void *v)
1.30      christos  940: {
1.14      mycroft   941:        struct vop_inactive_args /* {
                    942:                struct vnode *a_vp;
1.30      christos  943:        } */ *ap = v;
1.14      mycroft   944:        struct vnode *vp = ap->a_vp;
                    945:
1.1       cgd       946:        /*
                    947:         * Clear out the v_type field to avoid
                    948:         * nasty things happening in vgone().
                    949:         */
1.110     hannken   950:        VOP_UNLOCK(vp);
1.1       cgd       951:        vp->v_type = VNON;
                    952:        return (0);
                    953: }
                    954:
1.14      mycroft   955: int
1.105     dsl       956: fdesc_reclaim(void *v)
1.30      christos  957: {
1.14      mycroft   958:        struct vop_reclaim_args /* {
                    959:                struct vnode *a_vp;
1.30      christos  960:        } */ *ap = v;
1.14      mycroft   961:        struct vnode *vp = ap->a_vp;
1.17      mycroft   962:        struct fdescnode *fd = VTOFDESC(vp);
1.14      mycroft   963:
1.111     hannken   964:        mutex_enter(&fdcache_lock);
1.17      mycroft   965:        LIST_REMOVE(fd, fd_hash);
1.104     cegger    966:        free(vp->v_data, M_TEMP);
1.14      mycroft   967:        vp->v_data = 0;
1.111     hannken   968:        mutex_exit(&fdcache_lock);
1.14      mycroft   969:
                    970:        return (0);
                    971: }
                    972:
                    973: /*
                    974:  * Return POSIX pathconf information applicable to special devices.
                    975:  */
1.30      christos  976: int
1.105     dsl       977: fdesc_pathconf(void *v)
1.30      christos  978: {
1.14      mycroft   979:        struct vop_pathconf_args /* {
                    980:                struct vnode *a_vp;
                    981:                int a_name;
1.18      cgd       982:                register_t *a_retval;
1.30      christos  983:        } */ *ap = v;
1.8       cgd       984:
1.14      mycroft   985:        switch (ap->a_name) {
                    986:        case _PC_LINK_MAX:
                    987:                *ap->a_retval = LINK_MAX;
                    988:                return (0);
                    989:        case _PC_MAX_CANON:
                    990:                *ap->a_retval = MAX_CANON;
                    991:                return (0);
                    992:        case _PC_MAX_INPUT:
                    993:                *ap->a_retval = MAX_INPUT;
                    994:                return (0);
                    995:        case _PC_PIPE_BUF:
                    996:                *ap->a_retval = PIPE_BUF;
                    997:                return (0);
                    998:        case _PC_CHOWN_RESTRICTED:
                    999:                *ap->a_retval = 1;
                   1000:                return (0);
                   1001:        case _PC_VDISABLE:
                   1002:                *ap->a_retval = _POSIX_VDISABLE;
1.45      kleink   1003:                return (0);
                   1004:        case _PC_SYNC_IO:
                   1005:                *ap->a_retval = 1;
1.14      mycroft  1006:                return (0);
                   1007:        default:
                   1008:                return (EINVAL);
1.8       cgd      1009:        }
1.14      mycroft  1010:        /* NOTREACHED */
1.8       cgd      1011: }
                   1012:
1.1       cgd      1013: /*
                   1014:  * Print out the contents of a /dev/fd vnode.
                   1015:  */
                   1016: /* ARGSUSED */
1.14      mycroft  1017: int
1.94      christos 1018: fdesc_print(void *v)
1.1       cgd      1019: {
1.37      christos 1020:        printf("tag VT_NON, fdesc vnode\n");
1.14      mycroft  1021:        return (0);
                   1022: }
                   1023:
                   1024: int
1.105     dsl      1025: fdesc_link(void *v)
1.30      christos 1026: {
1.29      mycroft  1027:        struct vop_link_args /* {
                   1028:                struct vnode *a_dvp;
1.83      perry    1029:                struct vnode *a_vp;
1.29      mycroft  1030:                struct componentname *a_cnp;
1.30      christos 1031:        } */ *ap = v;
1.83      perry    1032:
1.29      mycroft  1033:        VOP_ABORTOP(ap->a_dvp, ap->a_cnp);
                   1034:        vput(ap->a_dvp);
                   1035:        return (EROFS);
                   1036: }
                   1037:
                   1038: int
1.105     dsl      1039: fdesc_symlink(void *v)
1.30      christos 1040: {
1.116     hannken  1041:        struct vop_symlink_v3_args /* {
1.29      mycroft  1042:                struct vnode *a_dvp;
                   1043:                struct vnode **a_vpp;
                   1044:                struct componentname *a_cnp;
                   1045:                struct vattr *a_vap;
                   1046:                char *a_target;
1.30      christos 1047:        } */ *ap = v;
1.83      perry    1048:
1.29      mycroft  1049:        VOP_ABORTOP(ap->a_dvp, ap->a_cnp);
                   1050:        return (EROFS);
1.1       cgd      1051: }

CVSweb <webmaster@jp.NetBSD.org>