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

1.116   ! hannken     1: /*     $NetBSD: fdesc_vnops.c,v 1.115 2014/01/17 10:55:02 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.116   ! hannken    44: __KERNEL_RCSID(0, "$NetBSD: fdesc_vnops.c,v 1.115 2014/01/17 10:55:02 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.48      wrstuden  252:        VOP_LOCK(*vpp, LK_EXCLUSIVE);
1.17      mycroft   253:        LIST_INSERT_HEAD(fc, fd, fd_hash);
1.111     hannken   254:        mutex_exit(&fdcache_lock);
1.8       cgd       255:
1.111     hannken   256:        return 0;
1.8       cgd       257: }
1.1       cgd       258:
                    259: /*
                    260:  * vp is the current namei directory
                    261:  * ndp is the name to locate in that directory...
                    262:  */
1.14      mycroft   263: int
1.105     dsl       264: fdesc_lookup(void *v)
1.30      christos  265: {
1.14      mycroft   266:        struct vop_lookup_args /* {
                    267:                struct vnode * a_dvp;
                    268:                struct vnode ** a_vpp;
                    269:                struct componentname * a_cnp;
1.30      christos  270:        } */ *ap = v;
1.14      mycroft   271:        struct vnode **vpp = ap->a_vpp;
                    272:        struct vnode *dvp = ap->a_dvp;
1.44      fvdl      273:        struct componentname *cnp = ap->a_cnp;
1.101     pooka     274:        struct lwp *l = curlwp;
1.44      fvdl      275:        const char *pname = cnp->cn_nameptr;
1.89      christos  276:        struct proc *p = l->l_proc;
1.30      christos  277:        unsigned fd = 0;
1.1       cgd       278:        int error;
                    279:        struct vnode *fvp;
1.84      christos  280:        const char *ln;
1.107     ad        281:        fdtab_t *dt;
                    282:
                    283:        dt = curlwp->l_fd->fd_dt;
1.1       cgd       284:
1.44      fvdl      285:        if (cnp->cn_namelen == 1 && *pname == '.') {
1.14      mycroft   286:                *vpp = dvp;
1.109     pooka     287:                vref(dvp);
1.1       cgd       288:                return (0);
                    289:        }
                    290:
1.8       cgd       291:        switch (VTOFDESC(dvp)->fd_type) {
                    292:        default:
                    293:        case Flink:
                    294:        case Fdesc:
                    295:        case Fctty:
                    296:                error = ENOTDIR;
                    297:                goto bad;
                    298:
                    299:        case Froot:
1.46      perry     300:                if (cnp->cn_namelen == 2 && memcmp(pname, "fd", 2) == 0) {
1.8       cgd       301:                        error = fdesc_allocvp(Fdevfd, FD_DEVFD, dvp->v_mount, &fvp);
                    302:                        if (error)
                    303:                                goto bad;
1.14      mycroft   304:                        *vpp = fvp;
1.8       cgd       305:                        fvp->v_type = VDIR;
1.48      wrstuden  306:                        goto good;
1.8       cgd       307:                }
                    308:
1.46      perry     309:                if (cnp->cn_namelen == 3 && memcmp(pname, "tty", 3) == 0) {
1.8       cgd       310:                        struct vnode *ttyvp = cttyvp(p);
                    311:                        if (ttyvp == NULL) {
                    312:                                error = ENXIO;
                    313:                                goto bad;
                    314:                        }
                    315:                        error = fdesc_allocvp(Fctty, FD_CTTY, dvp->v_mount, &fvp);
                    316:                        if (error)
                    317:                                goto bad;
1.14      mycroft   318:                        *vpp = fvp;
1.32      mrg       319:                        fvp->v_type = VCHR;
1.48      wrstuden  320:                        goto good;
1.8       cgd       321:                }
                    322:
                    323:                ln = 0;
1.44      fvdl      324:                switch (cnp->cn_namelen) {
1.8       cgd       325:                case 5:
1.46      perry     326:                        if (memcmp(pname, "stdin", 5) == 0) {
1.8       cgd       327:                                ln = "fd/0";
                    328:                                fd = FD_STDIN;
                    329:                        }
1.1       cgd       330:                        break;
1.8       cgd       331:                case 6:
1.46      perry     332:                        if (memcmp(pname, "stdout", 6) == 0) {
1.8       cgd       333:                                ln = "fd/1";
                    334:                                fd = FD_STDOUT;
                    335:                        } else
1.46      perry     336:                        if (memcmp(pname, "stderr", 6) == 0) {
1.8       cgd       337:                                ln = "fd/2";
                    338:                                fd = FD_STDERR;
                    339:                        }
                    340:                        break;
                    341:                }
                    342:
                    343:                if (ln) {
                    344:                        error = fdesc_allocvp(Flink, fd, dvp->v_mount, &fvp);
                    345:                        if (error)
                    346:                                goto bad;
1.84      christos  347:                        /* XXXUNCONST */
                    348:                        VTOFDESC(fvp)->fd_link = __UNCONST(ln);
1.14      mycroft   349:                        *vpp = fvp;
1.8       cgd       350:                        fvp->v_type = VLNK;
1.48      wrstuden  351:                        goto good;
1.8       cgd       352:                } else {
                    353:                        error = ENOENT;
                    354:                        goto bad;
                    355:                }
                    356:
1.14      mycroft   357:                /* FALL THROUGH */
1.8       cgd       358:
                    359:        case Fdevfd:
1.46      perry     360:                if (cnp->cn_namelen == 2 && memcmp(pname, "..", 2) == 0) {
1.110     hannken   361:                        VOP_UNLOCK(dvp);
1.76      thorpej   362:                        error = fdesc_root(dvp->v_mount, vpp);
1.95      chs       363:                        vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
1.44      fvdl      364:                        if (error)
                    365:                                goto bad;
1.48      wrstuden  366:                        return (error);
1.8       cgd       367:                }
                    368:
                    369:                fd = 0;
                    370:                while (*pname >= '0' && *pname <= '9') {
                    371:                        fd = 10 * fd + *pname++ - '0';
1.107     ad        372:                        if (fd >= dt->dt_nfiles)
1.8       cgd       373:                                break;
                    374:                }
1.1       cgd       375:
1.8       cgd       376:                if (*pname != '\0') {
                    377:                        error = ENOENT;
                    378:                        goto bad;
                    379:                }
1.1       cgd       380:
1.107     ad        381:                if (fd >= dt->dt_nfiles || dt->dt_ff[fd] == NULL ||
                    382:                    dt->dt_ff[fd]->ff_file == NULL) {
1.8       cgd       383:                        error = EBADF;
                    384:                        goto bad;
                    385:                }
1.1       cgd       386:
1.8       cgd       387:                error = fdesc_allocvp(Fdesc, FD_DESC+fd, dvp->v_mount, &fvp);
                    388:                if (error)
                    389:                        goto bad;
                    390:                VTOFDESC(fvp)->fd_fd = fd;
1.14      mycroft   391:                *vpp = fvp;
1.48      wrstuden  392:                goto good;
1.8       cgd       393:        }
1.1       cgd       394:
1.95      chs       395: bad:
1.14      mycroft   396:        *vpp = NULL;
1.1       cgd       397:        return (error);
1.48      wrstuden  398:
1.95      chs       399: good:
1.48      wrstuden  400:        return (0);
1.1       cgd       401: }
                    402:
1.14      mycroft   403: int
1.105     dsl       404: fdesc_open(void *v)
1.30      christos  405: {
1.14      mycroft   406:        struct vop_open_args /* {
                    407:                struct vnode *a_vp;
                    408:                int  a_mode;
1.92      elad      409:                kauth_cred_t a_cred;
1.30      christos  410:        } */ *ap = v;
1.14      mycroft   411:        struct vnode *vp = ap->a_vp;
1.8       cgd       412:
                    413:        switch (VTOFDESC(vp)->fd_type) {
                    414:        case Fdesc:
1.23      mycroft   415:                /*
1.79      jdolecek  416:                 * XXX Kludge: set dupfd to contain the value of the
1.83      perry     417:                 * the file descriptor being sought for duplication. The error
1.23      mycroft   418:                 * return ensures that the vnode for this device will be
                    419:                 * released by vn_open. Open will detect this special error and
                    420:                 * take the actions in dupfdopen.  Other callers of vn_open or
                    421:                 * VOP_OPEN will simply report the error.
                    422:                 */
1.79      jdolecek  423:                curlwp->l_dupfd = VTOFDESC(vp)->fd_fd;  /* XXX */
1.82      christos  424:                return EDUPFD;
1.1       cgd       425:
1.8       cgd       426:        case Fctty:
1.100     pooka     427:                return cdev_open(devctty, ap->a_mode, 0, curlwp);
1.30      christos  428:        case Froot:
                    429:        case Fdevfd:
                    430:        case Flink:
                    431:                break;
1.8       cgd       432:        }
1.1       cgd       433:
1.21      mycroft   434:        return (0);
1.1       cgd       435: }
                    436:
                    437: static int
1.105     dsl       438: fdesc_attr(int fd, struct vattr *vap, kauth_cred_t cred)
1.1       cgd       439: {
1.102     ad        440:        file_t *fp;
1.8       cgd       441:        struct stat stb;
1.1       cgd       442:        int error;
                    443:
1.102     ad        444:        if ((fp = fd_getfile(fd)) == NULL)
1.1       cgd       445:                return (EBADF);
                    446:
                    447:        switch (fp->f_type) {
                    448:        case DTYPE_VNODE:
1.114     hannken   449:                vn_lock((struct vnode *) fp->f_data, LK_SHARED | LK_RETRY);
1.100     pooka     450:                error = VOP_GETATTR((struct vnode *) fp->f_data, vap, cred);
1.114     hannken   451:                VOP_UNLOCK((struct vnode *) fp->f_data);
1.8       cgd       452:                if (error == 0 && vap->va_type == VDIR) {
                    453:                        /*
1.22      mycroft   454:                         * directories can cause loops in the namespace,
                    455:                         * so turn off the 'x' bits to avoid trouble.
1.8       cgd       456:                         */
1.41      mycroft   457:                        vap->va_mode &= ~(S_IXUSR|S_IXGRP|S_IXOTH);
1.8       cgd       458:                }
1.1       cgd       459:                break;
                    460:
1.69      jdolecek  461:        default:
                    462:                memset(&stb, 0, sizeof(stb));
1.102     ad        463:                error = (*fp->f_ops->fo_stat)(fp, &stb);
1.69      jdolecek  464:                if (error)
                    465:                        break;
                    466:
                    467:                vattr_null(vap);
                    468:                switch(fp->f_type) {
                    469:                case DTYPE_SOCKET:
                    470:                        vap->va_type = VSOCK;
                    471:                        break;
                    472:                case DTYPE_PIPE:
                    473:                        vap->va_type = VFIFO;
                    474:                        break;
                    475:                default:
                    476:                        /* use VNON perhaps? */
                    477:                        vap->va_type = VBAD;
                    478:                        break;
1.8       cgd       479:                }
1.69      jdolecek  480:                vap->va_mode = stb.st_mode;
                    481:                vap->va_nlink = stb.st_nlink;
                    482:                vap->va_uid = stb.st_uid;
                    483:                vap->va_gid = stb.st_gid;
                    484:                vap->va_fsid = stb.st_dev;
                    485:                vap->va_fileid = stb.st_ino;
                    486:                vap->va_size = stb.st_size;
                    487:                vap->va_blocksize = stb.st_blksize;
                    488:                vap->va_atime = stb.st_atimespec;
                    489:                vap->va_mtime = stb.st_mtimespec;
                    490:                vap->va_ctime = stb.st_ctimespec;
                    491:                vap->va_gen = stb.st_gen;
                    492:                vap->va_flags = stb.st_flags;
                    493:                vap->va_rdev = stb.st_rdev;
                    494:                vap->va_bytes = stb.st_blocks * stb.st_blksize;
1.1       cgd       495:                break;
                    496:        }
                    497:
1.102     ad        498:        fd_putfile(fd);
1.1       cgd       499:        return (error);
                    500: }
                    501:
1.14      mycroft   502: int
1.105     dsl       503: fdesc_getattr(void *v)
1.30      christos  504: {
1.14      mycroft   505:        struct vop_getattr_args /* {
                    506:                struct vnode *a_vp;
                    507:                struct vattr *a_vap;
1.92      elad      508:                kauth_cred_t a_cred;
1.89      christos  509:                struct lwp *a_l;
1.30      christos  510:        } */ *ap = v;
1.14      mycroft   511:        struct vnode *vp = ap->a_vp;
                    512:        struct vattr *vap = ap->a_vap;
1.1       cgd       513:        unsigned fd;
1.8       cgd       514:        int error = 0;
1.1       cgd       515:
1.8       cgd       516:        switch (VTOFDESC(vp)->fd_type) {
                    517:        case Froot:
                    518:        case Fdevfd:
                    519:        case Flink:
                    520:        case Fctty:
1.109     pooka     521:                vattr_null(vap);
1.8       cgd       522:                vap->va_fileid = VTOFDESC(vp)->fd_ix;
                    523:
1.30      christos  524: #define R_ALL (S_IRUSR|S_IRGRP|S_IROTH)
                    525: #define W_ALL (S_IWUSR|S_IWGRP|S_IWOTH)
                    526: #define X_ALL (S_IXUSR|S_IXGRP|S_IXOTH)
                    527:
1.8       cgd       528:                switch (VTOFDESC(vp)->fd_type) {
                    529:                case Flink:
1.30      christos  530:                        vap->va_mode = R_ALL|X_ALL;
1.8       cgd       531:                        vap->va_type = VLNK;
1.32      mrg       532:                        vap->va_rdev = 0;
1.8       cgd       533:                        vap->va_nlink = 1;
                    534:                        vap->va_size = strlen(VTOFDESC(vp)->fd_link);
                    535:                        break;
                    536:
                    537:                case Fctty:
1.30      christos  538:                        vap->va_mode = R_ALL|W_ALL;
1.32      mrg       539:                        vap->va_type = VCHR;
                    540:                        vap->va_rdev = devctty;
1.8       cgd       541:                        vap->va_nlink = 1;
                    542:                        vap->va_size = 0;
                    543:                        break;
                    544:
                    545:                default:
1.30      christos  546:                        vap->va_mode = R_ALL|X_ALL;
1.8       cgd       547:                        vap->va_type = VDIR;
1.32      mrg       548:                        vap->va_rdev = 0;
1.8       cgd       549:                        vap->va_nlink = 2;
                    550:                        vap->va_size = DEV_BSIZE;
                    551:                        break;
                    552:                }
1.1       cgd       553:                vap->va_uid = 0;
                    554:                vap->va_gid = 0;
1.80      christos  555:                vap->va_fsid = vp->v_mount->mnt_stat.f_fsidx.__fsid_val[0];
1.1       cgd       556:                vap->va_blocksize = DEV_BSIZE;
1.28      jtc       557:                vap->va_atime.tv_sec = boottime.tv_sec;
                    558:                vap->va_atime.tv_nsec = 0;
1.1       cgd       559:                vap->va_mtime = vap->va_atime;
1.14      mycroft   560:                vap->va_ctime = vap->va_mtime;
1.1       cgd       561:                vap->va_gen = 0;
                    562:                vap->va_flags = 0;
                    563:                vap->va_bytes = 0;
1.8       cgd       564:                break;
                    565:
                    566:        case Fdesc:
                    567:                fd = VTOFDESC(vp)->fd_fd;
1.102     ad        568:                error = fdesc_attr(fd, vap, ap->a_cred);
1.8       cgd       569:                break;
                    570:
                    571:        default:
                    572:                panic("fdesc_getattr");
1.83      perry     573:                break;
1.1       cgd       574:        }
                    575:
                    576:        if (error == 0)
                    577:                vp->v_type = vap->va_type;
1.8       cgd       578:
1.1       cgd       579:        return (error);
                    580: }
                    581:
1.14      mycroft   582: int
1.105     dsl       583: fdesc_setattr(void *v)
1.30      christos  584: {
1.14      mycroft   585:        struct vop_setattr_args /* {
                    586:                struct vnode *a_vp;
                    587:                struct vattr *a_vap;
1.92      elad      588:                kauth_cred_t a_cred;
1.30      christos  589:        } */ *ap = v;
1.102     ad        590:        file_t *fp;
1.1       cgd       591:        unsigned fd;
                    592:
                    593:        /*
                    594:         * Can't mess with the root vnode
                    595:         */
1.14      mycroft   596:        switch (VTOFDESC(ap->a_vp)->fd_type) {
1.8       cgd       597:        case Fdesc:
                    598:                break;
                    599:
                    600:        case Fctty:
                    601:                return (0);
                    602:
                    603:        default:
1.1       cgd       604:                return (EACCES);
1.8       cgd       605:        }
1.1       cgd       606:
1.14      mycroft   607:        fd = VTOFDESC(ap->a_vp)->fd_fd;
1.102     ad        608:        if ((fp = fd_getfile(fd)) == NULL)
1.1       cgd       609:                return (EBADF);
                    610:
                    611:        /*
1.68      jmc       612:         * XXX: Can't reasonably set the attr's on any types currently.
                    613:         *      On vnode's this will cause truncation and socket/pipes make
                    614:         *      no sense.
1.1       cgd       615:         */
1.102     ad        616:        fd_putfile(fd);
1.69      jdolecek  617:        return (0);
1.1       cgd       618: }
                    619:
1.8       cgd       620:
1.25      mycroft   621: struct fdesc_target {
                    622:        ino_t ft_fileno;
                    623:        u_char ft_type;
                    624:        u_char ft_namlen;
1.84      christos  625:        const char *ft_name;
1.25      mycroft   626: } fdesc_targets[] = {
                    627: #define N(s) sizeof(s)-1, s
                    628:        { FD_DEVFD,  DT_DIR,     N("fd")     },
1.27      mycroft   629:        { FD_STDIN,  DT_LNK,     N("stdin")  },
                    630:        { FD_STDOUT, DT_LNK,     N("stdout") },
                    631:        { FD_STDERR, DT_LNK,     N("stderr") },
1.25      mycroft   632:        { FD_CTTY,   DT_UNKNOWN, N("tty")    },
                    633: #undef N
1.85      christos  634: #define UIO_MX _DIRENT_RECLEN((struct dirent *)NULL, sizeof("stderr") - 1)
1.8       cgd       635: };
1.25      mycroft   636: static int nfdesc_targets = sizeof(fdesc_targets) / sizeof(fdesc_targets[0]);
1.8       cgd       637:
1.14      mycroft   638: int
1.105     dsl       639: fdesc_readdir(void *v)
1.30      christos  640: {
1.14      mycroft   641:        struct vop_readdir_args /* {
                    642:                struct vnode *a_vp;
                    643:                struct uio *a_uio;
1.92      elad      644:                kauth_cred_t a_cred;
1.22      mycroft   645:                int *a_eofflag;
1.44      fvdl      646:                off_t **a_cookies;
                    647:                int *a_ncookies;
1.30      christos  648:        } */ *ap = v;
1.14      mycroft   649:        struct uio *uio = ap->a_uio;
1.25      mycroft   650:        struct dirent d;
1.53      sommerfe  651:        off_t i;
1.87      christos  652:        int j;
1.1       cgd       653:        int error;
1.44      fvdl      654:        off_t *cookies = NULL;
1.87      christos  655:        int ncookies;
1.107     ad        656:        fdtab_t *dt;
1.11      ws        657:
1.14      mycroft   658:        switch (VTOFDESC(ap->a_vp)->fd_type) {
1.8       cgd       659:        case Fctty:
1.87      christos  660:                return 0;
1.8       cgd       661:
                    662:        case Fdesc:
1.87      christos  663:                return ENOTDIR;
1.30      christos  664:
                    665:        default:
                    666:                break;
1.8       cgd       667:        }
1.1       cgd       668:
1.107     ad        669:        dt = curlwp->l_fd->fd_dt;
1.8       cgd       670:
1.25      mycroft   671:        if (uio->uio_resid < UIO_MX)
1.87      christos  672:                return EINVAL;
1.26      mycroft   673:        if (uio->uio_offset < 0)
1.87      christos  674:                return EINVAL;
1.25      mycroft   675:
                    676:        error = 0;
1.26      mycroft   677:        i = uio->uio_offset;
1.87      christos  678:        (void)memset(&d, 0, UIO_MX);
1.25      mycroft   679:        d.d_reclen = UIO_MX;
1.44      fvdl      680:        if (ap->a_ncookies)
1.87      christos  681:                ncookies = uio->uio_resid / UIO_MX;
                    682:        else
                    683:                ncookies = 0;
1.25      mycroft   684:
1.14      mycroft   685:        if (VTOFDESC(ap->a_vp)->fd_type == Froot) {
1.25      mycroft   686:                struct fdesc_target *ft;
1.51      christos  687:
                    688:                if (i >= nfdesc_targets)
1.52      sommerfe  689:                        return 0;
1.3       cgd       690:
1.44      fvdl      691:                if (ap->a_ncookies) {
                    692:                        ncookies = min(ncookies, (nfdesc_targets - i));
1.56      thorpej   693:                        cookies = malloc(ncookies * sizeof(off_t),
1.44      fvdl      694:                            M_TEMP, M_WAITOK);
                    695:                        *ap->a_cookies = cookies;
                    696:                        *ap->a_ncookies = ncookies;
                    697:                }
                    698:
1.87      christos  699:                for (ft = &fdesc_targets[i]; uio->uio_resid >= UIO_MX &&
                    700:                    i < nfdesc_targets; ft++, i++) {
1.25      mycroft   701:                        switch (ft->ft_fileno) {
1.8       cgd       702:                        case FD_CTTY:
1.90      yamt      703:                                if (cttyvp(curproc) == NULL)
1.8       cgd       704:                                        continue;
                    705:                                break;
                    706:
                    707:                        case FD_STDIN:
                    708:                        case FD_STDOUT:
                    709:                        case FD_STDERR:
1.87      christos  710:                                if ((ft->ft_fileno - FD_STDIN) >=
1.107     ad        711:                                    dt->dt_nfiles)
1.87      christos  712:                                        continue;
1.107     ad        713:                                if (dt->dt_ff[ft->ft_fileno - FD_STDIN]
                    714:                                    == NULL || dt->dt_ff[ft->ft_fileno -
1.102     ad        715:                                    FD_STDIN]->ff_file == NULL)
1.8       cgd       716:                                        continue;
                    717:                                break;
                    718:                        }
1.25      mycroft   719:
                    720:                        d.d_fileno = ft->ft_fileno;
                    721:                        d.d_namlen = ft->ft_namlen;
1.87      christos  722:                        (void)memcpy(d.d_name, ft->ft_name, ft->ft_namlen + 1);
1.25      mycroft   723:                        d.d_type = ft->ft_type;
                    724:
1.81      jrf       725:                        if ((error = uiomove(&d, UIO_MX, uio)) != 0)
1.8       cgd       726:                                break;
1.44      fvdl      727:                        if (cookies)
1.26      mycroft   728:                                *cookies++ = i + 1;
1.3       cgd       729:                }
1.25      mycroft   730:        } else {
1.102     ad        731:                membar_consumer();
1.44      fvdl      732:                if (ap->a_ncookies) {
1.107     ad        733:                        ncookies = min(ncookies, dt->dt_nfiles + 2);
1.56      thorpej   734:                        cookies = malloc(ncookies * sizeof(off_t),
                    735:                            M_TEMP, M_WAITOK);
1.44      fvdl      736:                        *ap->a_cookies = cookies;
                    737:                        *ap->a_ncookies = ncookies;
                    738:                }
1.107     ad        739:                for (; i - 2 < dt->dt_nfiles && uio->uio_resid >= UIO_MX; i++) {
1.25      mycroft   740:                        switch (i) {
                    741:                        case 0:
                    742:                        case 1:
                    743:                                d.d_fileno = FD_ROOT;           /* XXX */
                    744:                                d.d_namlen = i + 1;
1.87      christos  745:                                (void)memcpy(d.d_name, "..", d.d_namlen);
1.25      mycroft   746:                                d.d_name[i + 1] = '\0';
                    747:                                d.d_type = DT_DIR;
                    748:                                break;
1.83      perry     749:
1.25      mycroft   750:                        default:
1.87      christos  751:                                j = (int)i - 2;
1.107     ad        752:                                if (dt->dt_ff[j] == NULL ||
                    753:                                    dt->dt_ff[j]->ff_file == NULL)
1.25      mycroft   754:                                        continue;
1.87      christos  755:                                d.d_fileno = j + FD_STDIN;
                    756:                                d.d_namlen = sprintf(d.d_name, "%d", j);
1.25      mycroft   757:                                d.d_type = DT_UNKNOWN;
                    758:                                break;
                    759:                        }
1.8       cgd       760:
1.81      jrf       761:                        if ((error = uiomove(&d, UIO_MX, uio)) != 0)
1.1       cgd       762:                                break;
1.44      fvdl      763:                        if (cookies)
1.26      mycroft   764:                                *cookies++ = i + 1;
1.1       cgd       765:                }
1.8       cgd       766:        }
                    767:
1.44      fvdl      768:        if (ap->a_ncookies && error) {
1.56      thorpej   769:                free(*ap->a_cookies, M_TEMP);
1.44      fvdl      770:                *ap->a_ncookies = 0;
                    771:                *ap->a_cookies = NULL;
                    772:        }
                    773:
1.26      mycroft   774:        uio->uio_offset = i;
1.87      christos  775:        return error;
1.8       cgd       776: }
                    777:
1.14      mycroft   778: int
1.105     dsl       779: fdesc_readlink(void *v)
1.30      christos  780: {
1.14      mycroft   781:        struct vop_readlink_args /* {
                    782:                struct vnode *a_vp;
                    783:                struct uio *a_uio;
1.92      elad      784:                kauth_cred_t a_cred;
1.30      christos  785:        } */ *ap = v;
1.14      mycroft   786:        struct vnode *vp = ap->a_vp;
1.8       cgd       787:        int error;
                    788:
1.14      mycroft   789:        if (vp->v_type != VLNK)
                    790:                return (EPERM);
                    791:
1.8       cgd       792:        if (VTOFDESC(vp)->fd_type == Flink) {
                    793:                char *ln = VTOFDESC(vp)->fd_link;
1.14      mycroft   794:                error = uiomove(ln, strlen(ln), ap->a_uio);
1.8       cgd       795:        } else {
                    796:                error = EOPNOTSUPP;
                    797:        }
                    798:
                    799:        return (error);
                    800: }
                    801:
1.14      mycroft   802: int
1.105     dsl       803: fdesc_read(void *v)
1.30      christos  804: {
1.14      mycroft   805:        struct vop_read_args /* {
                    806:                struct vnode *a_vp;
                    807:                struct uio *a_uio;
                    808:                int  a_ioflag;
1.92      elad      809:                kauth_cred_t a_cred;
1.30      christos  810:        } */ *ap = v;
1.8       cgd       811:        int error = EOPNOTSUPP;
1.49      thorpej   812:        struct vnode *vp = ap->a_vp;
1.8       cgd       813:
1.49      thorpej   814:        switch (VTOFDESC(vp)->fd_type) {
1.8       cgd       815:        case Fctty:
1.110     hannken   816:                VOP_UNLOCK(vp);
1.97      ad        817:                error = cdev_read(devctty, ap->a_uio, ap->a_ioflag);
1.49      thorpej   818:                vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
1.8       cgd       819:                break;
                    820:
                    821:        default:
                    822:                error = EOPNOTSUPP;
                    823:                break;
                    824:        }
1.83      perry     825:
1.8       cgd       826:        return (error);
                    827: }
                    828:
1.14      mycroft   829: int
1.105     dsl       830: fdesc_write(void *v)
1.30      christos  831: {
1.14      mycroft   832:        struct vop_write_args /* {
                    833:                struct vnode *a_vp;
                    834:                struct uio *a_uio;
                    835:                int  a_ioflag;
1.92      elad      836:                kauth_cred_t a_cred;
1.30      christos  837:        } */ *ap = v;
1.8       cgd       838:        int error = EOPNOTSUPP;
1.49      thorpej   839:        struct vnode *vp = ap->a_vp;
1.8       cgd       840:
1.49      thorpej   841:        switch (VTOFDESC(vp)->fd_type) {
1.8       cgd       842:        case Fctty:
1.110     hannken   843:                VOP_UNLOCK(vp);
1.97      ad        844:                error = cdev_write(devctty, ap->a_uio, ap->a_ioflag);
1.49      thorpej   845:                vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
1.8       cgd       846:                break;
                    847:
                    848:        default:
                    849:                error = EOPNOTSUPP;
                    850:                break;
                    851:        }
1.83      perry     852:
1.8       cgd       853:        return (error);
                    854: }
                    855:
1.14      mycroft   856: int
1.105     dsl       857: fdesc_ioctl(void *v)
1.30      christos  858: {
1.14      mycroft   859:        struct vop_ioctl_args /* {
                    860:                struct vnode *a_vp;
1.19      cgd       861:                u_long a_command;
1.81      jrf       862:                void *a_data;
1.14      mycroft   863:                int  a_fflag;
1.92      elad      864:                kauth_cred_t a_cred;
1.30      christos  865:        } */ *ap = v;
1.8       cgd       866:        int error = EOPNOTSUPP;
                    867:
1.14      mycroft   868:        switch (VTOFDESC(ap->a_vp)->fd_type) {
1.8       cgd       869:        case Fctty:
1.97      ad        870:                error = cdev_ioctl(devctty, ap->a_command, ap->a_data,
1.100     pooka     871:                    ap->a_fflag, curlwp);
1.8       cgd       872:                break;
                    873:
                    874:        default:
                    875:                error = EOPNOTSUPP;
                    876:                break;
1.1       cgd       877:        }
1.83      perry     878:
1.8       cgd       879:        return (error);
                    880: }
                    881:
1.14      mycroft   882: int
1.105     dsl       883: fdesc_poll(void *v)
1.30      christos  884: {
1.35      mycroft   885:        struct vop_poll_args /* {
1.14      mycroft   886:                struct vnode *a_vp;
1.35      mycroft   887:                int a_events;
1.30      christos  888:        } */ *ap = v;
1.35      mycroft   889:        int revents;
1.8       cgd       890:
1.14      mycroft   891:        switch (VTOFDESC(ap->a_vp)->fd_type) {
1.8       cgd       892:        case Fctty:
1.100     pooka     893:                revents = cdev_poll(devctty, ap->a_events, curlwp);
1.8       cgd       894:                break;
1.1       cgd       895:
1.8       cgd       896:        default:
1.35      mycroft   897:                revents = genfs_poll(v);
1.8       cgd       898:                break;
                    899:        }
1.34      mycroft   900:
1.35      mycroft   901:        return (revents);
1.71      jdolecek  902: }
                    903:
                    904: int
1.105     dsl       905: fdesc_kqfilter(void *v)
1.71      jdolecek  906: {
                    907:        struct vop_kqfilter_args /* {
                    908:                struct vnode *a_vp;
                    909:                struct knote *a_kn;
                    910:        } */ *ap = v;
1.102     ad        911:        int error, fd;
                    912:        file_t *fp;
1.71      jdolecek  913:
                    914:        switch (VTOFDESC(ap->a_vp)->fd_type) {
                    915:        case Fctty:
1.97      ad        916:                error = cdev_kqfilter(devctty, ap->a_kn);
1.71      jdolecek  917:                break;
                    918:
                    919:        case Fdesc:
                    920:                /* just invoke kqfilter for the underlying descriptor */
1.102     ad        921:                fd = VTOFDESC(ap->a_vp)->fd_fd;
                    922:                if ((fp = fd_getfile(fd)) == NULL)
1.71      jdolecek  923:                        return (1);
                    924:                error = (*fp->f_ops->fo_kqfilter)(fp, ap->a_kn);
1.102     ad        925:                fd_putfile(fd);
1.71      jdolecek  926:                break;
                    927:
                    928:        default:
                    929:                return (genfs_kqfilter(v));
                    930:        }
                    931:
                    932:        return (error);
1.1       cgd       933: }
                    934:
1.14      mycroft   935: int
1.105     dsl       936: fdesc_inactive(void *v)
1.30      christos  937: {
1.14      mycroft   938:        struct vop_inactive_args /* {
                    939:                struct vnode *a_vp;
1.30      christos  940:        } */ *ap = v;
1.14      mycroft   941:        struct vnode *vp = ap->a_vp;
                    942:
1.1       cgd       943:        /*
                    944:         * Clear out the v_type field to avoid
                    945:         * nasty things happening in vgone().
                    946:         */
1.110     hannken   947:        VOP_UNLOCK(vp);
1.1       cgd       948:        vp->v_type = VNON;
                    949:        return (0);
                    950: }
                    951:
1.14      mycroft   952: int
1.105     dsl       953: fdesc_reclaim(void *v)
1.30      christos  954: {
1.14      mycroft   955:        struct vop_reclaim_args /* {
                    956:                struct vnode *a_vp;
1.30      christos  957:        } */ *ap = v;
1.14      mycroft   958:        struct vnode *vp = ap->a_vp;
1.17      mycroft   959:        struct fdescnode *fd = VTOFDESC(vp);
1.14      mycroft   960:
1.111     hannken   961:        mutex_enter(&fdcache_lock);
1.17      mycroft   962:        LIST_REMOVE(fd, fd_hash);
1.104     cegger    963:        free(vp->v_data, M_TEMP);
1.14      mycroft   964:        vp->v_data = 0;
1.111     hannken   965:        mutex_exit(&fdcache_lock);
1.14      mycroft   966:
                    967:        return (0);
                    968: }
                    969:
                    970: /*
                    971:  * Return POSIX pathconf information applicable to special devices.
                    972:  */
1.30      christos  973: int
1.105     dsl       974: fdesc_pathconf(void *v)
1.30      christos  975: {
1.14      mycroft   976:        struct vop_pathconf_args /* {
                    977:                struct vnode *a_vp;
                    978:                int a_name;
1.18      cgd       979:                register_t *a_retval;
1.30      christos  980:        } */ *ap = v;
1.8       cgd       981:
1.14      mycroft   982:        switch (ap->a_name) {
                    983:        case _PC_LINK_MAX:
                    984:                *ap->a_retval = LINK_MAX;
                    985:                return (0);
                    986:        case _PC_MAX_CANON:
                    987:                *ap->a_retval = MAX_CANON;
                    988:                return (0);
                    989:        case _PC_MAX_INPUT:
                    990:                *ap->a_retval = MAX_INPUT;
                    991:                return (0);
                    992:        case _PC_PIPE_BUF:
                    993:                *ap->a_retval = PIPE_BUF;
                    994:                return (0);
                    995:        case _PC_CHOWN_RESTRICTED:
                    996:                *ap->a_retval = 1;
                    997:                return (0);
                    998:        case _PC_VDISABLE:
                    999:                *ap->a_retval = _POSIX_VDISABLE;
1.45      kleink   1000:                return (0);
                   1001:        case _PC_SYNC_IO:
                   1002:                *ap->a_retval = 1;
1.14      mycroft  1003:                return (0);
                   1004:        default:
                   1005:                return (EINVAL);
1.8       cgd      1006:        }
1.14      mycroft  1007:        /* NOTREACHED */
1.8       cgd      1008: }
                   1009:
1.1       cgd      1010: /*
                   1011:  * Print out the contents of a /dev/fd vnode.
                   1012:  */
                   1013: /* ARGSUSED */
1.14      mycroft  1014: int
1.94      christos 1015: fdesc_print(void *v)
1.1       cgd      1016: {
1.37      christos 1017:        printf("tag VT_NON, fdesc vnode\n");
1.14      mycroft  1018:        return (0);
                   1019: }
                   1020:
                   1021: int
1.105     dsl      1022: fdesc_link(void *v)
1.30      christos 1023: {
1.29      mycroft  1024:        struct vop_link_args /* {
                   1025:                struct vnode *a_dvp;
1.83      perry    1026:                struct vnode *a_vp;
1.29      mycroft  1027:                struct componentname *a_cnp;
1.30      christos 1028:        } */ *ap = v;
1.83      perry    1029:
1.29      mycroft  1030:        VOP_ABORTOP(ap->a_dvp, ap->a_cnp);
                   1031:        vput(ap->a_dvp);
                   1032:        return (EROFS);
                   1033: }
                   1034:
                   1035: int
1.105     dsl      1036: fdesc_symlink(void *v)
1.30      christos 1037: {
1.116   ! hannken  1038:        struct vop_symlink_v3_args /* {
1.29      mycroft  1039:                struct vnode *a_dvp;
                   1040:                struct vnode **a_vpp;
                   1041:                struct componentname *a_cnp;
                   1042:                struct vattr *a_vap;
                   1043:                char *a_target;
1.30      christos 1044:        } */ *ap = v;
1.83      perry    1045:
1.29      mycroft  1046:        VOP_ABORTOP(ap->a_dvp, ap->a_cnp);
                   1047:        return (EROFS);
1.1       cgd      1048: }

CVSweb <webmaster@jp.NetBSD.org>