]> git.saurik.com Git - apple/xnu.git/blame - bsd/miscfs/fdesc/fdesc_vnops.c
xnu-517.12.7.tar.gz
[apple/xnu.git] / bsd / miscfs / fdesc / fdesc_vnops.c
CommitLineData
1c79356b 1/*
55e303ae 2 * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
1c79356b
A
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
e5568f75
A
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
1c79356b 11 *
e5568f75
A
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
1c79356b
A
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
e5568f75
A
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
1c79356b
A
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22/* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
23/*
24 * Copyright (c) 1992, 1993
25 * The Regents of the University of California. All rights reserved.
26 *
27 * This code is derived from software donated to Berkeley by
28 * Jan-Simon Pendry.
29 *
30 * Redistribution and use in source and binary forms, with or without
31 * modification, are permitted provided that the following conditions
32 * are met:
33 * 1. Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * 2. Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in the
37 * documentation and/or other materials provided with the distribution.
38 * 3. All advertising materials mentioning features or use of this software
39 * must display the following acknowledgement:
40 * This product includes software developed by the University of
41 * California, Berkeley and its contributors.
42 * 4. Neither the name of the University nor the names of its contributors
43 * may be used to endorse or promote products derived from this software
44 * without specific prior written permission.
45 *
46 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
47 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
48 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
49 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
50 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
51 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
52 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
54 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
55 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56 * SUCH DAMAGE.
57 *
58 * @(#)fdesc_vnops.c 8.17 (Berkeley) 5/22/95
59 *
60 */
61
62/*
63 * /dev/fd Filesystem
64 */
65
66#include <sys/param.h>
67#include <sys/systm.h>
68#include <sys/types.h>
69#include <sys/time.h>
70#include <sys/proc.h>
71#include <sys/kernel.h> /* boottime */
72#include <sys/resourcevar.h>
73#include <sys/filedesc.h>
74#include <sys/vnode.h>
75#include <sys/malloc.h>
76#include <sys/file.h>
77#include <sys/stat.h>
78#include <sys/mount.h>
79#include <sys/namei.h>
80#include <sys/buf.h>
81#include <sys/dirent.h>
82#include <sys/ubc.h>
83#include <miscfs/fdesc/fdesc.h>
84#include <vfs/vfs_support.h>
85
1c79356b
A
86#define FDL_WANT 0x01
87#define FDL_LOCKED 0x02
88static int fdcache_lock;
89
1c79356b
A
90
91#if (FD_STDIN != FD_STDOUT-1) || (FD_STDOUT != FD_STDERR-1)
92FD_STDIN, FD_STDOUT, FD_STDERR must be a sequence n, n+1, n+2
93#endif
94
9bccf70c 95#define NFDCACHE 3
1c79356b
A
96
97#define FD_NHASH(ix) \
98 (&fdhashtbl[(ix) & fdhash])
99LIST_HEAD(fdhashhead, fdescnode) *fdhashtbl;
100u_long fdhash;
101
102/*
103 * Initialise cache headers
104 */
105fdesc_init(vfsp)
106 struct vfsconf *vfsp;
107{
108
1c79356b
A
109 fdhashtbl = hashinit(NFDCACHE, M_CACHE, &fdhash);
110}
111
112int
113fdesc_allocvp(ftype, ix, mp, vpp)
114 fdntype ftype;
115 int ix;
116 struct mount *mp;
117 struct vnode **vpp;
118{
119 struct proc *p = current_proc(); /* XXX */
120 struct fdhashhead *fc;
121 struct fdescnode *fd;
122 int error = 0;
123
124 fc = FD_NHASH(ix);
125loop:
126 for (fd = fc->lh_first; fd != 0; fd = fd->fd_hash.le_next) {
127 if (fd->fd_ix == ix && fd->fd_vnode->v_mount == mp) {
128 if (vget(fd->fd_vnode, 0, p))
129 goto loop;
130 *vpp = fd->fd_vnode;
131 return (error);
132 }
133 }
134
135 /*
136 * otherwise lock the array while we call getnewvnode
137 * since that can block.
138 */
139 if (fdcache_lock & FDL_LOCKED) {
140 fdcache_lock |= FDL_WANT;
141 sleep((caddr_t) &fdcache_lock, PINOD);
142 goto loop;
143 }
144 fdcache_lock |= FDL_LOCKED;
145
146 MALLOC(fd, void *, sizeof(struct fdescnode), M_TEMP, M_WAITOK);
147 error = getnewvnode(VT_FDESC, mp, fdesc_vnodeop_p, vpp);
148 if (error) {
149 FREE(fd, M_TEMP);
150 goto out;
151 }
152 (*vpp)->v_data = fd;
153 fd->fd_vnode = *vpp;
154 fd->fd_type = ftype;
155 fd->fd_fd = -1;
156 fd->fd_link = 0;
157 fd->fd_ix = ix;
158 LIST_INSERT_HEAD(fc, fd, fd_hash);
159
160out:
161 fdcache_lock &= ~FDL_LOCKED;
162
163 if (fdcache_lock & FDL_WANT) {
164 fdcache_lock &= ~FDL_WANT;
165 wakeup((caddr_t) &fdcache_lock);
166 }
167
168 return (error);
169}
170
171/*
172 * vp is the current namei directory
173 * ndp is the name to locate in that directory...
174 */
175int
176fdesc_lookup(ap)
177 struct vop_lookup_args /* {
178 struct vnode * a_dvp;
179 struct vnode ** a_vpp;
180 struct componentname * a_cnp;
181 } */ *ap;
182{
183 struct vnode **vpp = ap->a_vpp;
184 struct vnode *dvp = ap->a_dvp;
185 struct componentname *cnp = ap->a_cnp;
186 char *pname = cnp->cn_nameptr;
187 struct proc *p = cnp->cn_proc;
188 int nfiles = p->p_fd->fd_nfiles;
189 unsigned fd;
190 int error;
191 struct vnode *fvp;
192 char *ln;
193
194 VOP_UNLOCK(dvp, 0, p);
195 if (cnp->cn_namelen == 1 && *pname == '.') {
196 *vpp = dvp;
197 VREF(dvp);
198 vn_lock(dvp, LK_SHARED | LK_RETRY, p);
199 return (0);
200 }
201
202 switch (VTOFDESC(dvp)->fd_type) {
203 default:
204 case Flink:
205 case Fdesc:
1c79356b
A
206 error = ENOTDIR;
207 goto bad;
208
209 case Froot:
210 if (cnp->cn_namelen == 2 && bcmp(pname, "fd", 2) == 0) {
211 error = fdesc_allocvp(Fdevfd, FD_DEVFD, dvp->v_mount, &fvp);
212 if (error)
213 goto bad;
214 *vpp = fvp;
215 fvp->v_type = VDIR;
216 vn_lock(fvp, LK_SHARED | LK_RETRY, p);
217 return (0);
218 }
219
1c79356b
A
220 ln = 0;
221 switch (cnp->cn_namelen) {
222 case 5:
223 if (bcmp(pname, "stdin", 5) == 0) {
224 ln = "fd/0";
225 fd = FD_STDIN;
226 }
227 break;
228 case 6:
229 if (bcmp(pname, "stdout", 6) == 0) {
230 ln = "fd/1";
231 fd = FD_STDOUT;
232 } else
233 if (bcmp(pname, "stderr", 6) == 0) {
234 ln = "fd/2";
235 fd = FD_STDERR;
236 }
237 break;
238 }
239
240 if (ln) {
241 error = fdesc_allocvp(Flink, fd, dvp->v_mount, &fvp);
242 if (error)
243 goto bad;
244 VTOFDESC(fvp)->fd_link = ln;
245 *vpp = fvp;
246 fvp->v_type = VLNK;
247 vn_lock(fvp, LK_SHARED | LK_RETRY, p);
248 return (0);
249 } else {
250 error = ENOENT;
251 goto bad;
252 }
253
254 /* FALL THROUGH */
255
256 case Fdevfd:
257 if (cnp->cn_namelen == 2 && bcmp(pname, "..", 2) == 0) {
258 if (error = fdesc_root(dvp->v_mount, vpp))
259 goto bad;
260 return (0);
261 }
262
263 fd = 0;
264 while (*pname >= '0' && *pname <= '9') {
265 fd = 10 * fd + *pname++ - '0';
266 if (fd >= nfiles)
267 break;
268 }
269
270 if (*pname != '\0') {
271 error = ENOENT;
272 goto bad;
273 }
274
275 if (fd >= nfiles ||
276 *fdfile(p, fd) == NULL ||
277 (*fdflags(p, fd) & UF_RESERVED)) {
278 error = EBADF;
279 goto bad;
280 }
281
282 error = fdesc_allocvp(Fdesc, FD_DESC+fd, dvp->v_mount, &fvp);
283 if (error)
284 goto bad;
285 VTOFDESC(fvp)->fd_fd = fd;
286 vn_lock(fvp, LK_SHARED | LK_RETRY, p);
287 *vpp = fvp;
288 return (0);
289 }
290
291bad:;
292 vn_lock(dvp, LK_SHARED | LK_RETRY, p);
293 *vpp = NULL;
294 return (error);
295}
296
297int
298fdesc_open(ap)
299 struct vop_open_args /* {
300 struct vnode *a_vp;
301 int a_mode;
302 struct ucred *a_cred;
303 struct proc *a_p;
304 } */ *ap;
305{
306 struct vnode *vp = ap->a_vp;
307 int error = 0;
308
309 switch (VTOFDESC(vp)->fd_type) {
310 case Fdesc:
311 /*
312 * XXX Kludge: set p->p_dupfd to contain the value of the
313 * the file descriptor being sought for duplication. The error
314 * return ensures that the vnode for this device will be
315 * released by vn_open. Open will detect this special error and
316 * take the actions in dupfdopen. Other callers of vn_open or
317 * VOP_OPEN will simply report the error.
318 */
319 ap->a_p->p_dupfd = VTOFDESC(vp)->fd_fd; /* XXX */
320 error = ENODEV;
321 break;
322
1c79356b
A
323 }
324
325 return (error);
326}
327
328static int
329fdesc_attr(fd, vap, cred, p)
330 int fd;
331 struct vattr *vap;
332 struct ucred *cred;
333 struct proc *p;
334{
335 struct file *fp;
336 struct stat stb;
337 int error;
338
339 if (error = fdgetf(p, fd, &fp))
340 return (error);
341 switch (fp->f_type) {
342 case DTYPE_VNODE:
343 error = VOP_GETATTR((struct vnode *) fp->f_data, vap, cred, p);
344 if (error == 0 && vap->va_type == VDIR) {
345 /*
346 * directories can cause loops in the namespace,
347 * so turn off the 'x' bits to avoid trouble.
348 */
349 vap->va_mode &= ~((VEXEC)|(VEXEC>>3)|(VEXEC>>6));
350 }
351 break;
352
353 case DTYPE_SOCKET:
354 error = soo_stat((struct socket *)fp->f_data, &stb);
355 if (error == 0) {
356 vattr_null(vap);
357 vap->va_type = VSOCK;
358 vap->va_mode = stb.st_mode;
359 vap->va_nlink = stb.st_nlink;
360 vap->va_uid = stb.st_uid;
361 vap->va_gid = stb.st_gid;
362 vap->va_fsid = stb.st_dev;
363 vap->va_fileid = stb.st_ino;
364 vap->va_size = stb.st_size;
365 vap->va_blocksize = stb.st_blksize;
366 vap->va_atime = stb.st_atimespec;
367 vap->va_mtime = stb.st_mtimespec;
368 vap->va_ctime = stb.st_ctimespec;
369 vap->va_gen = stb.st_gen;
370 vap->va_flags = stb.st_flags;
371 vap->va_rdev = stb.st_rdev;
372 vap->va_bytes = stb.st_blocks * stb.st_blksize;
373 }
374 break;
375
376 default:
9bccf70c 377 return (EBADF);
1c79356b
A
378 break;
379 }
380
381 return (error);
382}
383
384int
385fdesc_getattr(ap)
386 struct vop_getattr_args /* {
387 struct vnode *a_vp;
388 struct vattr *a_vap;
389 struct ucred *a_cred;
390 struct proc *a_p;
391 } */ *ap;
392{
393 struct vnode *vp = ap->a_vp;
394 struct vattr *vap = ap->a_vap;
395 unsigned fd;
396 int error = 0;
397
398 switch (VTOFDESC(vp)->fd_type) {
399 case Froot:
400 case Fdevfd:
401 case Flink:
1c79356b
A
402 bzero((caddr_t) vap, sizeof(*vap));
403 vattr_null(vap);
404 vap->va_fileid = VTOFDESC(vp)->fd_ix;
405
406 vap->va_uid = 0;
407 vap->va_gid = 0;
408 vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0];
409 vap->va_blocksize = DEV_BSIZE;
410 vap->va_atime.tv_sec = boottime.tv_sec;
411 vap->va_atime.tv_nsec = 0;
412 vap->va_mtime = vap->va_atime;
413 vap->va_ctime = vap->va_mtime;
414 vap->va_gen = 0;
415 vap->va_flags = 0;
416 vap->va_rdev = 0;
417 vap->va_bytes = 0;
418
419 switch (VTOFDESC(vp)->fd_type) {
420 case Flink:
421 vap->va_mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
422 vap->va_type = VLNK;
423 vap->va_nlink = 1;
424 vap->va_size = strlen(VTOFDESC(vp)->fd_link);
425 break;
426
1c79356b
A
427 default:
428 vap->va_mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
429 vap->va_type = VDIR;
430 vap->va_nlink = 2;
431 vap->va_size = DEV_BSIZE;
432 break;
433 }
434 break;
435
436 case Fdesc:
437 fd = VTOFDESC(vp)->fd_fd;
438 error = fdesc_attr(fd, vap, ap->a_cred, ap->a_p);
439 break;
440
441 default:
9bccf70c 442 return (EBADF);
1c79356b
A
443 break;
444 }
445
446 if (error == 0) {
447 vp->v_type = vap->va_type;
448 }
449
450 return (error);
451}
452
453int
454fdesc_setattr(ap)
455 struct vop_setattr_args /* {
456 struct vnode *a_vp;
457 struct vattr *a_vap;
458 struct ucred *a_cred;
459 struct proc *a_p;
460 } */ *ap;
461{
462 struct file *fp;
463 unsigned fd;
464 int error;
465
466 /*
467 * Can't mess with the root vnode
468 */
469 switch (VTOFDESC(ap->a_vp)->fd_type) {
470 case Fdesc:
471 break;
472
1c79356b
A
473 default:
474 return (EACCES);
475 }
476
477 fd = VTOFDESC(ap->a_vp)->fd_fd;
478 if (error = fdgetf(ap->a_p, fd, &fp))
479 return (error);
480
481 /*
482 * Can setattr the underlying vnode, but not sockets!
483 */
484 switch (fp->f_type) {
485 case DTYPE_VNODE:
486 error = VOP_SETATTR((struct vnode *) fp->f_data, ap->a_vap, ap->a_cred, ap->a_p);
487 break;
488
489 case DTYPE_SOCKET:
490 error = 0;
491 break;
492
493 default:
494 kprintf("fp->f_type = %d\n", fp->f_type);
495 error = EBADF;
496 break;
497 }
498
499 return (error);
500}
501
502#define UIO_MX 16
503
504static struct dirtmp {
505 u_long d_fileno;
506 u_short d_reclen;
507 u_short d_namlen;
508 char d_name[8];
509} rootent[] = {
510 { FD_DEVFD, UIO_MX, 2, "fd" },
511 { FD_STDIN, UIO_MX, 5, "stdin" },
512 { FD_STDOUT, UIO_MX, 6, "stdout" },
513 { FD_STDERR, UIO_MX, 6, "stderr" },
1c79356b
A
514 { 0 }
515};
516
517int
518fdesc_readdir(ap)
519 struct vop_readdir_args /* {
520 struct vnode *a_vp;
521 struct uio *a_uio;
522 struct ucred *a_cred;
523 int *a_eofflag;
524 u_long *a_cookies;
525 int a_ncookies;
526 } */ *ap;
527{
528 struct uio *uio = ap->a_uio;
529 struct proc *p = uio->uio_procp;
530 int i, error;
531
532 /*
533 * We don't allow exporting fdesc mounts, and currently local
534 * requests do not need cookies.
535 */
536 if (ap->a_ncookies)
9bccf70c 537 return (EINVAL);
1c79356b
A
538
539 switch (VTOFDESC(ap->a_vp)->fd_type) {
1c79356b
A
540 case Fdesc:
541 return (ENOTDIR);
542
543 default:
544 break;
545 }
546
547 if (VTOFDESC(ap->a_vp)->fd_type == Froot) {
548 struct dirent d;
549 struct dirent *dp = &d;
550 struct dirtmp *dt;
551 int fd;
552
553 i = uio->uio_offset / UIO_MX;
554 error = 0;
555
556 while (uio->uio_resid > 0) {
557 dt = &rootent[i];
558 if (dt->d_fileno == 0) {
559 /**eofflagp = 1;*/
560 break;
561 }
562 i++;
563
564 switch (dt->d_fileno) {
1c79356b
A
565 case FD_STDIN:
566 case FD_STDOUT:
567 case FD_STDERR:
568 fd = dt->d_fileno - FD_STDIN;
569 if (fd >= p->p_fd->fd_nfiles)
570 continue;
571 if (*fdfile(p, fd) == NULL &&
572 !(*fdflags(p, fd) &
573 UF_RESERVED))
574 continue;
575 break;
576 }
577 bzero((caddr_t) dp, UIO_MX);
578 dp->d_fileno = dt->d_fileno;
579 dp->d_namlen = dt->d_namlen;
580 dp->d_type = DT_UNKNOWN;
581 dp->d_reclen = dt->d_reclen;
582 bcopy(dt->d_name, dp->d_name, dp->d_namlen+1);
583 error = uiomove((caddr_t) dp, UIO_MX, uio);
584 if (error)
585 break;
586 }
587 uio->uio_offset = i * UIO_MX;
588 return (error);
589 }
590
591 i = uio->uio_offset / UIO_MX;
592 error = 0;
593 while (uio->uio_resid > 0) {
594 if (i >= p->p_fd->fd_nfiles)
595 break;
596
597 if (*fdfile(p, i) != NULL && !(*fdflags(p, i) & UF_RESERVED)) {
598 struct dirent d;
599 struct dirent *dp = &d;
600
601 bzero((caddr_t) dp, UIO_MX);
602
603 dp->d_namlen = sprintf(dp->d_name, "%d", i);
604 dp->d_reclen = UIO_MX;
605 dp->d_type = DT_UNKNOWN;
606 dp->d_fileno = i + FD_STDIN;
607 /*
608 * And ship to userland
609 */
610 error = uiomove((caddr_t) dp, UIO_MX, uio);
611 if (error)
612 break;
613 }
614 i++;
615 }
616
617 uio->uio_offset = i * UIO_MX;
618 return (error);
619}
620
621int
622fdesc_readlink(ap)
623 struct vop_readlink_args /* {
624 struct vnode *a_vp;
625 struct uio *a_uio;
626 struct ucred *a_cred;
627 } */ *ap;
628{
629 struct vnode *vp = ap->a_vp;
630 int error;
631
632 if (vp->v_type != VLNK)
633 return (EPERM);
634
635 if (VTOFDESC(vp)->fd_type == Flink) {
636 char *ln = VTOFDESC(vp)->fd_link;
637 error = uiomove(ln, strlen(ln), ap->a_uio);
638 } else {
639 error = EOPNOTSUPP;
640 }
641
642 return (error);
643}
644
645int
646fdesc_read(ap)
647 struct vop_read_args /* {
648 struct vnode *a_vp;
649 struct uio *a_uio;
650 int a_ioflag;
651 struct ucred *a_cred;
652 } */ *ap;
653{
1c79356b 654
9bccf70c 655 return (EOPNOTSUPP);
1c79356b
A
656}
657
658int
659fdesc_write(ap)
660 struct vop_write_args /* {
661 struct vnode *a_vp;
662 struct uio *a_uio;
663 int a_ioflag;
664 struct ucred *a_cred;
665 } */ *ap;
666{
9bccf70c 667 return (EOPNOTSUPP);
1c79356b
A
668}
669
670int
671fdesc_ioctl(ap)
672 struct vop_ioctl_args /* {
673 struct vnode *a_vp;
674 int a_command;
675 caddr_t a_data;
676 int a_fflag;
677 struct ucred *a_cred;
678 struct proc *a_p;
679 } */ *ap;
680{
9bccf70c 681 return (EOPNOTSUPP);
1c79356b
A
682}
683
684int
685fdesc_select(ap)
686 struct vop_select_args /* {
687 struct vnode *a_vp;
688 int a_which;
689 int a_fflags;
690 struct ucred *a_cred;
0b4e3aa0 691 void *a_wql;
1c79356b
A
692 struct proc *a_p;
693 } */ *ap;
694{
9bccf70c 695 return (EOPNOTSUPP);
1c79356b
A
696}
697
698int
699fdesc_inactive(ap)
700 struct vop_inactive_args /* {
701 struct vnode *a_vp;
702 struct proc *a_p;
703 } */ *ap;
704{
705 struct vnode *vp = ap->a_vp;
706
707 /*
708 * Clear out the v_type field to avoid
709 * nasty things happening in vgone().
710 */
711 VOP_UNLOCK(vp, 0, ap->a_p);
712 vp->v_type = VNON;
713 return (0);
714}
715
716int
717fdesc_reclaim(ap)
718 struct vop_reclaim_args /* {
719 struct vnode *a_vp;
720 } */ *ap;
721{
722 struct vnode *vp = ap->a_vp;
723 struct fdescnode *fd = VTOFDESC(vp);
724
725 LIST_REMOVE(fd, fd_hash);
726 FREE(vp->v_data, M_TEMP);
727 vp->v_data = 0;
728
729 return (0);
730}
731
732/*
733 * Return POSIX pathconf information applicable to special devices.
734 */
735fdesc_pathconf(ap)
736 struct vop_pathconf_args /* {
737 struct vnode *a_vp;
738 int a_name;
739 int *a_retval;
740 } */ *ap;
741{
742
743 switch (ap->a_name) {
744 case _PC_LINK_MAX:
745 *ap->a_retval = LINK_MAX;
746 return (0);
747 case _PC_MAX_CANON:
748 *ap->a_retval = MAX_CANON;
749 return (0);
750 case _PC_MAX_INPUT:
751 *ap->a_retval = MAX_INPUT;
752 return (0);
753 case _PC_PIPE_BUF:
754 *ap->a_retval = PIPE_BUF;
755 return (0);
756 case _PC_CHOWN_RESTRICTED:
757 *ap->a_retval = 1;
758 return (0);
759 case _PC_VDISABLE:
760 *ap->a_retval = _POSIX_VDISABLE;
761 return (0);
762 default:
763 return (EINVAL);
764 }
765 /* NOTREACHED */
766}
767
768/*
769 * Print out the contents of a /dev/fd vnode.
770 */
771/* ARGSUSED */
772int
773fdesc_print(ap)
774 struct vop_print_args /* {
775 struct vnode *a_vp;
776 } */ *ap;
777{
778
779 printf("tag VT_NON, fdesc vnode\n");
780 return (0);
781}
782
783/*void*/
784int
785fdesc_vfree(ap)
786 struct vop_vfree_args /* {
787 struct vnode *a_pvp;
788 ino_t a_ino;
789 int a_mode;
790 } */ *ap;
791{
792
793 return (0);
794}
795
796/*
797 * /dev/fd "should never get here" operation
798 */
799int
800fdesc_badop()
801{
802
9bccf70c 803 return (ENOTSUP);
1c79356b
A
804 /* NOTREACHED */
805}
806
807#define VOPFUNC int (*)(void *)
808
809#define fdesc_create ((int (*) __P((struct vop_create_args *)))eopnotsupp)
810#define fdesc_mknod ((int (*) __P((struct vop_mknod_args *)))eopnotsupp)
811#define fdesc_close ((int (*) __P((struct vop_close_args *)))nullop)
812#define fdesc_access ((int (*) __P((struct vop_access_args *)))nullop)
813#define fdesc_mmap ((int (*) __P((struct vop_mmap_args *)))eopnotsupp)
814#define fdesc_revoke vop_revoke
815#define fdesc_fsync ((int (*) __P((struct vop_fsync_args *)))nullop)
816#define fdesc_seek ((int (*) __P((struct vop_seek_args *)))nullop)
817#define fdesc_remove ((int (*) __P((struct vop_remove_args *)))eopnotsupp)
818#define fdesc_link ((int (*) __P((struct vop_link_args *)))eopnotsupp)
819#define fdesc_rename ((int (*) __P((struct vop_rename_args *)))eopnotsupp)
820#define fdesc_mkdir ((int (*) __P((struct vop_mkdir_args *)))eopnotsupp)
821#define fdesc_rmdir ((int (*) __P((struct vop_rmdir_args *)))eopnotsupp)
822#define fdesc_symlink ((int (*) __P((struct vop_symlink_args *)))eopnotsupp)
55e303ae 823#define fdesc_abortop ((int (*) __P((struct vop_abortop_args *)))nop_abortop)
1c79356b
A
824#define fdesc_lock ((int (*) __P((struct vop_lock_args *)))vop_nolock)
825#define fdesc_unlock ((int (*) __P((struct vop_unlock_args *)))vop_nounlock)
826#define fdesc_bmap ((int (*) __P((struct vop_bmap_args *)))fdesc_badop)
827#define fdesc_strategy ((int (*) __P((struct vop_strategy_args *)))fdesc_badop)
828#define fdesc_islocked \
829 ((int (*) __P((struct vop_islocked_args *)))vop_noislocked)
830#define fdesc_advlock ((int (*) __P((struct vop_advlock_args *)))eopnotsupp)
831#define fdesc_blkatoff \
832 ((int (*) __P((struct vop_blkatoff_args *)))eopnotsupp)
833#define fdesc_valloc ((int(*) __P(( \
834 struct vnode *pvp, \
835 int mode, \
836 struct ucred *cred, \
837 struct vnode **vpp))) eopnotsupp)
838#define fdesc_truncate \
839 ((int (*) __P((struct vop_truncate_args *)))eopnotsupp)
840#define fdesc_update ((int (*) __P((struct vop_update_args *)))eopnotsupp)
841#define fdesc_bwrite ((int (*) __P((struct vop_bwrite_args *)))eopnotsupp)
842#define fdesc_blktooff ((int (*) __P((struct vop_blktooff_args *)))eopnotsupp)
843#define fdesc_offtoblk ((int (*) __P((struct vop_offtoblk_args *)))eopnotsupp)
844#define fdesc_cmap ((int (*) __P((struct vop_cmap_args *)))eopnotsupp)
845
846int (**fdesc_vnodeop_p)(void *);
847struct vnodeopv_entry_desc fdesc_vnodeop_entries[] = {
848 { &vop_default_desc, (VOPFUNC)vn_default_error },
849 { &vop_lookup_desc, (VOPFUNC)fdesc_lookup }, /* lookup */
850 { &vop_create_desc, (VOPFUNC)fdesc_create }, /* create */
851 { &vop_mknod_desc, (VOPFUNC)fdesc_mknod }, /* mknod */
852 { &vop_open_desc, (VOPFUNC)fdesc_open }, /* open */
853 { &vop_close_desc, (VOPFUNC)fdesc_close }, /* close */
854 { &vop_access_desc, (VOPFUNC)fdesc_access }, /* access */
855 { &vop_getattr_desc, (VOPFUNC)fdesc_getattr }, /* getattr */
856 { &vop_setattr_desc, (VOPFUNC)fdesc_setattr }, /* setattr */
857 { &vop_read_desc, (VOPFUNC)fdesc_read }, /* read */
858 { &vop_write_desc, (VOPFUNC)fdesc_write }, /* write */
859 { &vop_ioctl_desc, (VOPFUNC)fdesc_ioctl }, /* ioctl */
860 { &vop_select_desc, (VOPFUNC)fdesc_select }, /* select */
861 { &vop_revoke_desc, (VOPFUNC)fdesc_revoke }, /* revoke */
862 { &vop_mmap_desc, (VOPFUNC)fdesc_mmap }, /* mmap */
863 { &vop_fsync_desc, (VOPFUNC)fdesc_fsync }, /* fsync */
864 { &vop_seek_desc, (VOPFUNC)fdesc_seek }, /* seek */
865 { &vop_remove_desc, (VOPFUNC)fdesc_remove }, /* remove */
866 { &vop_link_desc, (VOPFUNC)fdesc_link }, /* link */
867 { &vop_rename_desc, (VOPFUNC)fdesc_rename }, /* rename */
868 { &vop_mkdir_desc, (VOPFUNC)fdesc_mkdir }, /* mkdir */
869 { &vop_rmdir_desc, (VOPFUNC)fdesc_rmdir }, /* rmdir */
870 { &vop_symlink_desc, (VOPFUNC)fdesc_symlink }, /* symlink */
871 { &vop_readdir_desc, (VOPFUNC)fdesc_readdir }, /* readdir */
872 { &vop_readlink_desc, (VOPFUNC)fdesc_readlink },/* readlink */
873 { &vop_abortop_desc, (VOPFUNC)fdesc_abortop }, /* abortop */
874 { &vop_inactive_desc, (VOPFUNC)fdesc_inactive },/* inactive */
875 { &vop_reclaim_desc, (VOPFUNC)fdesc_reclaim }, /* reclaim */
876 { &vop_lock_desc, (VOPFUNC)fdesc_lock }, /* lock */
877 { &vop_unlock_desc, (VOPFUNC)fdesc_unlock }, /* unlock */
878 { &vop_bmap_desc, (VOPFUNC)fdesc_bmap }, /* bmap */
879 { &vop_strategy_desc, (VOPFUNC)fdesc_strategy }, /* strategy */
880 { &vop_print_desc, (VOPFUNC)fdesc_print }, /* print */
881 { &vop_islocked_desc, (VOPFUNC)fdesc_islocked }, /* islocked */
882 { &vop_pathconf_desc, (VOPFUNC)fdesc_pathconf }, /* pathconf */
883 { &vop_advlock_desc, (VOPFUNC)fdesc_advlock }, /* advlock */
884 { &vop_blkatoff_desc, (VOPFUNC)fdesc_blkatoff }, /* blkatoff */
885 { &vop_valloc_desc, (VOPFUNC)fdesc_valloc }, /* valloc */
886 { &vop_vfree_desc, (VOPFUNC)fdesc_vfree }, /* vfree */
887 { &vop_truncate_desc, (VOPFUNC)fdesc_truncate }, /* truncate */
888 { &vop_update_desc, (VOPFUNC)fdesc_update }, /* update */
889 { &vop_bwrite_desc, (VOPFUNC)fdesc_bwrite }, /* bwrite */
890 { &vop_pagein_desc, (VOPFUNC)err_pagein }, /* pagein */
891 { &vop_pageout_desc, (VOPFUNC)err_pageout }, /* pageout */
892 { &vop_copyfile_desc, (VOPFUNC)err_copyfile }, /* Copyfile */
893 { &vop_blktooff_desc, (VOPFUNC)fdesc_blktooff }, /* blktooff */
894 { &vop_blktooff_desc, (VOPFUNC)fdesc_offtoblk }, /* offtoblk */
895 { &vop_cmap_desc, (VOPFUNC)fdesc_cmap }, /* cmap */
896 { (struct vnodeop_desc*)NULL, (VOPFUNC)NULL }
897};
898struct vnodeopv_desc fdesc_vnodeop_opv_desc =
899 { &fdesc_vnodeop_p, fdesc_vnodeop_entries };