copyright typo
[unix-history] / usr / src / sys / miscfs / fdesc / fdesc_vnops.c
CommitLineData
e2e9adba 1/*
5f0f7060
KB
2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
e2e9adba
JSP
4 *
5 * This code is derived from software donated to Berkeley by
6 * Jan-Simon Pendry.
7 *
8 * %sccs.include.redist.c%
9 *
1611db1e 10 * @(#)fdesc_vnops.c 8.9 (Berkeley) %G%
e2e9adba 11 *
01936f59 12 * $Id: fdesc_vnops.c,v 1.12 1993/04/06 16:17:17 jsp Exp $
e2e9adba
JSP
13 */
14
15/*
16 * /dev/fd Filesystem
17 */
18
19#include <sys/param.h>
20#include <sys/systm.h>
21#include <sys/types.h>
22#include <sys/time.h>
23#include <sys/proc.h>
01936f59 24#include <sys/kernel.h> /* boottime */
e2e9adba
JSP
25#include <sys/resourcevar.h>
26#include <sys/filedesc.h>
27#include <sys/vnode.h>
28#include <sys/malloc.h>
29#include <sys/file.h>
30#include <sys/stat.h>
31#include <sys/mount.h>
32#include <sys/namei.h>
33#include <sys/buf.h>
13ef814e 34#include <sys/dirent.h>
5e3f92c4 35#include <miscfs/fdesc/fdesc.h>
e2e9adba 36
cf5ef508 37#define cttyvp(p) ((p)->p_flag & P_CONTROLT ? (p)->p_session->s_ttyvp : NULL)
01936f59
JSP
38
39#define FDL_WANT 0x01
40#define FDL_LOCKED 0x02
43ec9518
JSP
41static int fdcache_lock;
42
43dev_t devctty;
01936f59
JSP
44
45#if (FD_STDIN != FD_STDOUT-1) || (FD_STDOUT != FD_STDERR-1)
46FD_STDIN, FD_STDOUT, FD_STDERR must be a sequence n, n+1, n+2
47#endif
48
43ec9518
JSP
49#define NFDCACHE 3
50#define FD_NHASH(ix) ((ix) & NFDCACHE)
51
52/*
53 * Cache head
54 */
55struct fdcache {
56 struct fdescnode *fc_forw;
57 struct fdescnode *fc_back;
58};
59
60static struct fdcache fdcache[NFDCACHE];
61
62/*
63 * Initialise cache headers
64 */
65fdesc_init()
66{
67 struct fdcache *fc;
68
69 devctty = makedev(nchrdev, 0);
70
71 for (fc = fdcache; fc < fdcache + NFDCACHE; fc++)
72 fc->fc_forw = fc->fc_back = (struct fdescnode *) fc;
73}
74
75/*
76 * Compute hash list for given target vnode
77 */
78static struct fdcache *
79fdesc_hash(ix)
80 int ix;
81{
82
83 return (&fdcache[FD_NHASH(ix)]);
84}
85
86int
01936f59
JSP
87fdesc_allocvp(ftype, ix, mp, vpp)
88 fdntype ftype;
89 int ix;
90 struct mount *mp;
91 struct vnode **vpp;
92{
43ec9518
JSP
93 struct fdcache *fc;
94 struct fdescnode *fd;
01936f59
JSP
95 int error = 0;
96
a6382592 97loop:
43ec9518
JSP
98 fc = fdesc_hash(ix);
99 for (fd = fc->fc_forw; fd != (struct fdescnode *) fc; fd = fd->fd_forw) {
100 if (fd->fd_ix == ix && fd->fd_vnode->v_mount == mp) {
101 if (vget(fd->fd_vnode, 0))
a6382592 102 goto loop;
43ec9518 103 *vpp = fd->fd_vnode;
01936f59
JSP
104 return (error);
105 }
106 }
107
108 /*
109 * otherwise lock the array while we call getnewvnode
110 * since that can block.
111 */
43ec9518
JSP
112 if (fdcache_lock & FDL_LOCKED) {
113 fdcache_lock |= FDL_WANT;
114 sleep((caddr_t) &fdcache_lock, PINOD);
a6382592 115 goto loop;
01936f59 116 }
43ec9518 117 fdcache_lock |= FDL_LOCKED;
01936f59 118
46a14367 119 error = getnewvnode(VT_FDESC, mp, fdesc_vnodeop_p, vpp);
01936f59
JSP
120 if (error)
121 goto out;
43ec9518
JSP
122 MALLOC(fd, void *, sizeof(struct fdescnode), M_TEMP, M_WAITOK);
123 (*vpp)->v_data = fd;
124 fd->fd_vnode = *vpp;
125 fd->fd_type = ftype;
126 fd->fd_fd = -1;
127 fd->fd_link = 0;
128 fd->fd_ix = ix;
129 fc = fdesc_hash(ix);
130 insque(fd, fc);
01936f59
JSP
131
132out:;
43ec9518 133 fdcache_lock &= ~FDL_LOCKED;
01936f59 134
43ec9518
JSP
135 if (fdcache_lock & FDL_WANT) {
136 fdcache_lock &= ~FDL_WANT;
137 wakeup((caddr_t) &fdcache_lock);
01936f59
JSP
138 }
139
140 return (error);
141}
142
e2e9adba
JSP
143/*
144 * vp is the current namei directory
145 * ndp is the name to locate in that directory...
146 */
43ec9518 147int
5e3f92c4
KM
148fdesc_lookup(ap)
149 struct vop_lookup_args /* {
150 struct vnode * a_dvp;
151 struct vnode ** a_vpp;
152 struct componentname * a_cnp;
153 } */ *ap;
e2e9adba 154{
a02db9dd
JSP
155 struct vnode **vpp = ap->a_vpp;
156 struct vnode *dvp = ap->a_dvp;
e2e9adba
JSP
157 char *pname;
158 struct proc *p;
159 int nfiles;
160 unsigned fd;
161 int error;
162 struct vnode *fvp;
01936f59 163 char *ln;
e2e9adba 164
e2e9adba 165 pname = ap->a_cnp->cn_nameptr;
e2e9adba 166 if (ap->a_cnp->cn_namelen == 1 && *pname == '.') {
a02db9dd
JSP
167 *vpp = dvp;
168 VREF(dvp);
01936f59 169 VOP_LOCK(dvp);
e2e9adba
JSP
170 return (0);
171 }
172
173 p = ap->a_cnp->cn_proc;
174 nfiles = p->p_fd->fd_nfiles;
175
01936f59
JSP
176 switch (VTOFDESC(dvp)->fd_type) {
177 default:
178 case Flink:
179 case Fdesc:
180 case Fctty:
181 error = ENOTDIR;
182 goto bad;
183
184 case Froot:
185 if (ap->a_cnp->cn_namelen == 2 && bcmp(pname, "fd", 2) == 0) {
186 error = fdesc_allocvp(Fdevfd, FD_DEVFD, dvp->v_mount, &fvp);
187 if (error)
188 goto bad;
189 *vpp = fvp;
190 fvp->v_type = VDIR;
191 VOP_LOCK(fvp);
01936f59
JSP
192 return (0);
193 }
194
195 if (ap->a_cnp->cn_namelen == 3 && bcmp(pname, "tty", 3) == 0) {
196 struct vnode *ttyvp = cttyvp(p);
197 if (ttyvp == NULL) {
198 error = ENXIO;
199 goto bad;
200 }
201 error = fdesc_allocvp(Fctty, FD_CTTY, dvp->v_mount, &fvp);
202 if (error)
203 goto bad;
204 *vpp = fvp;
205 fvp->v_type = VFIFO;
206 VOP_LOCK(fvp);
01936f59
JSP
207 return (0);
208 }
209
210 ln = 0;
211 switch (ap->a_cnp->cn_namelen) {
212 case 5:
213 if (bcmp(pname, "stdin", 5) == 0) {
214 ln = "fd/0";
215 fd = FD_STDIN;
216 }
e2e9adba 217 break;
01936f59
JSP
218 case 6:
219 if (bcmp(pname, "stdout", 6) == 0) {
220 ln = "fd/1";
221 fd = FD_STDOUT;
222 } else
223 if (bcmp(pname, "stderr", 6) == 0) {
224 ln = "fd/2";
225 fd = FD_STDERR;
226 }
227 break;
228 }
e2e9adba 229
01936f59 230 if (ln) {
01936f59
JSP
231 error = fdesc_allocvp(Flink, fd, dvp->v_mount, &fvp);
232 if (error)
233 goto bad;
234 VTOFDESC(fvp)->fd_link = ln;
235 *vpp = fvp;
236 fvp->v_type = VLNK;
237 VOP_LOCK(fvp);
01936f59
JSP
238 return (0);
239 } else {
240 error = ENOENT;
241 goto bad;
242 }
e2e9adba 243
43ec9518 244 /* FALL THROUGH */
01936f59
JSP
245
246 case Fdevfd:
247 if (ap->a_cnp->cn_namelen == 2 && bcmp(pname, "..", 2) == 0) {
248 error = fdesc_root(dvp->v_mount, vpp);
249 return (error);
250 }
251
252 fd = 0;
253 while (*pname >= '0' && *pname <= '9') {
254 fd = 10 * fd + *pname++ - '0';
255 if (fd >= nfiles)
256 break;
257 }
e2e9adba 258
01936f59
JSP
259 if (*pname != '\0') {
260 error = ENOENT;
261 goto bad;
262 }
263
264 if (fd >= nfiles || p->p_fd->fd_ofiles[fd] == NULL) {
265 error = EBADF;
266 goto bad;
267 }
268
01936f59
JSP
269 error = fdesc_allocvp(Fdesc, FD_DESC+fd, dvp->v_mount, &fvp);
270 if (error)
271 goto bad;
272 VTOFDESC(fvp)->fd_fd = fd;
273 *vpp = fvp;
01936f59
JSP
274 return (0);
275 }
e2e9adba
JSP
276
277bad:;
a02db9dd 278 *vpp = NULL;
e2e9adba
JSP
279 return (error);
280}
281
43ec9518 282int
5e3f92c4
KM
283fdesc_open(ap)
284 struct vop_open_args /* {
285 struct vnode *a_vp;
286 int a_mode;
287 struct ucred *a_cred;
288 struct proc *a_p;
289 } */ *ap;
e2e9adba 290{
a02db9dd 291 struct vnode *vp = ap->a_vp;
01936f59
JSP
292 int error = 0;
293
294 switch (VTOFDESC(vp)->fd_type) {
295 case Fdesc:
296 /*
297 * XXX Kludge: set p->p_dupfd to contain the value of the
298 * the file descriptor being sought for duplication. The error
299 * return ensures that the vnode for this device will be
300 * released by vn_open. Open will detect this special error and
301 * take the actions in dupfdopen. Other callers of vn_open or
302 * VOP_OPEN will simply report the error.
303 */
304 ap->a_p->p_dupfd = VTOFDESC(vp)->fd_fd; /* XXX */
305 error = ENODEV;
306 break;
a02db9dd 307
01936f59
JSP
308 case Fctty:
309 error = cttyopen(devctty, ap->a_mode, 0, ap->a_p);
310 break;
311 }
e2e9adba 312
01936f59 313 return (error);
e2e9adba
JSP
314}
315
316static int
317fdesc_attr(fd, vap, cred, p)
318 int fd;
319 struct vattr *vap;
320 struct ucred *cred;
321 struct proc *p;
322{
e2e9adba
JSP
323 struct filedesc *fdp = p->p_fd;
324 struct file *fp;
7e204c1b 325 struct stat stb;
e2e9adba
JSP
326 int error;
327
43ec9518 328 if (fd >= fdp->fd_nfiles || (fp = fdp->fd_ofiles[fd]) == NULL)
e2e9adba 329 return (EBADF);
e2e9adba 330
e2e9adba
JSP
331 switch (fp->f_type) {
332 case DTYPE_VNODE:
333 error = VOP_GETATTR((struct vnode *) fp->f_data, vap, cred, p);
52e93dd0
JSP
334 if (error == 0 && vap->va_type == VDIR) {
335 /*
336 * don't allow directories to show up because
337 * that causes loops in the namespace.
338 */
339 vap->va_type = VFIFO;
340 }
e2e9adba
JSP
341 break;
342
343 case DTYPE_SOCKET:
7e204c1b
JSP
344 error = soo_stat((struct socket *)fp->f_data, &stb);
345 if (error == 0) {
346 vattr_null(vap);
347 vap->va_type = VSOCK;
348 vap->va_mode = stb.st_mode;
349 vap->va_nlink = stb.st_nlink;
350 vap->va_uid = stb.st_uid;
351 vap->va_gid = stb.st_gid;
352 vap->va_fsid = stb.st_dev;
353 vap->va_fileid = stb.st_ino;
354 vap->va_size = stb.st_size;
355 vap->va_blocksize = stb.st_blksize;
356 vap->va_atime = stb.st_atimespec;
357 vap->va_mtime = stb.st_mtimespec;
358 vap->va_ctime = stb.st_ctimespec;
359 vap->va_gen = stb.st_gen;
360 vap->va_flags = stb.st_flags;
361 vap->va_rdev = stb.st_rdev;
362 vap->va_bytes = stb.st_blocks * stb.st_blksize;
363 }
e2e9adba
JSP
364 break;
365
366 default:
367 panic("fdesc attr");
368 break;
369 }
370
e2e9adba
JSP
371 return (error);
372}
373
43ec9518 374int
5e3f92c4
KM
375fdesc_getattr(ap)
376 struct vop_getattr_args /* {
377 struct vnode *a_vp;
378 struct vattr *a_vap;
379 struct ucred *a_cred;
380 struct proc *a_p;
381 } */ *ap;
e2e9adba 382{
a02db9dd
JSP
383 struct vnode *vp = ap->a_vp;
384 struct vattr *vap = ap->a_vap;
e2e9adba 385 unsigned fd;
6a6b2974 386 int error = 0;
e2e9adba 387
01936f59
JSP
388 switch (VTOFDESC(vp)->fd_type) {
389 case Froot:
390 case Fdevfd:
391 case Flink:
392 case Fctty:
a02db9dd
JSP
393 bzero((caddr_t) vap, sizeof(*vap));
394 vattr_null(vap);
01936f59
JSP
395 vap->va_fileid = VTOFDESC(vp)->fd_ix;
396
397 switch (VTOFDESC(vp)->fd_type) {
398 case Flink:
399 vap->va_mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
400 vap->va_type = VLNK;
401 vap->va_nlink = 1;
01936f59
JSP
402 vap->va_size = strlen(VTOFDESC(vp)->fd_link);
403 break;
404
405 case Fctty:
406 vap->va_mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH;
407 vap->va_type = VFIFO;
408 vap->va_nlink = 1;
01936f59
JSP
409 vap->va_size = 0;
410 break;
411
412 default:
413 vap->va_mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
414 vap->va_type = VDIR;
415 vap->va_nlink = 2;
01936f59
JSP
416 vap->va_size = DEV_BSIZE;
417 break;
418 }
a02db9dd
JSP
419 vap->va_uid = 0;
420 vap->va_gid = 0;
421 vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0];
a02db9dd 422 vap->va_blocksize = DEV_BSIZE;
01936f59
JSP
423 vap->va_atime.ts_sec = boottime.tv_sec;
424 vap->va_atime.ts_nsec = 0;
a02db9dd 425 vap->va_mtime = vap->va_atime;
ede11b31 426 vap->va_ctime = vap->va_mtime;
a02db9dd
JSP
427 vap->va_gen = 0;
428 vap->va_flags = 0;
429 vap->va_rdev = 0;
a02db9dd 430 vap->va_bytes = 0;
01936f59
JSP
431 break;
432
433 case Fdesc:
01936f59
JSP
434 fd = VTOFDESC(vp)->fd_fd;
435 error = fdesc_attr(fd, vap, ap->a_cred, ap->a_p);
436 break;
437
438 default:
439 panic("fdesc_getattr");
440 break;
e2e9adba
JSP
441 }
442
e2e9adba 443 if (error == 0)
a02db9dd 444 vp->v_type = vap->va_type;
01936f59 445
e2e9adba
JSP
446 return (error);
447}
448
43ec9518 449int
5e3f92c4
KM
450fdesc_setattr(ap)
451 struct vop_setattr_args /* {
452 struct vnode *a_vp;
453 struct vattr *a_vap;
454 struct ucred *a_cred;
455 struct proc *a_p;
456 } */ *ap;
e2e9adba 457{
e2e9adba
JSP
458 struct filedesc *fdp = ap->a_p->p_fd;
459 struct file *fp;
460 unsigned fd;
461 int error;
462
463 /*
464 * Can't mess with the root vnode
465 */
01936f59
JSP
466 switch (VTOFDESC(ap->a_vp)->fd_type) {
467 case Fdesc:
468 break;
469
470 case Fctty:
471 return (0);
472
473 default:
e2e9adba 474 return (EACCES);
01936f59 475 }
e2e9adba 476
01936f59 477 fd = VTOFDESC(ap->a_vp)->fd_fd;
e2e9adba 478 if (fd >= fdp->fd_nfiles || (fp = fdp->fd_ofiles[fd]) == NULL) {
e2e9adba
JSP
479 return (EBADF);
480 }
481
482 /*
483 * Can setattr the underlying vnode, but not sockets!
484 */
485 switch (fp->f_type) {
486 case DTYPE_VNODE:
487 error = VOP_SETATTR((struct vnode *) fp->f_data, ap->a_vap, ap->a_cred, ap->a_p);
488 break;
489
490 case DTYPE_SOCKET:
d5ef2099 491 error = 0;
e2e9adba
JSP
492 break;
493
494 default:
495 panic("fdesc setattr");
496 break;
497 }
498
e2e9adba
JSP
499 return (error);
500}
501
01936f59
JSP
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" },
514 { FD_CTTY, UIO_MX, 3, "tty" },
515 { 0 }
516};
517
43ec9518 518int
5e3f92c4
KM
519fdesc_readdir(ap)
520 struct vop_readdir_args /* {
521 struct vnode *a_vp;
522 struct uio *a_uio;
523 struct ucred *a_cred;
524 } */ *ap;
e2e9adba 525{
a02db9dd 526 struct uio *uio = ap->a_uio;
e2e9adba
JSP
527 struct filedesc *fdp;
528 int i;
529 int error;
530
01936f59
JSP
531 switch (VTOFDESC(ap->a_vp)->fd_type) {
532 case Fctty:
533 return (0);
534
535 case Fdesc:
536 return (ENOTDIR);
537
538 default:
539 break;
540 }
e2e9adba 541
a02db9dd 542 fdp = uio->uio_procp->p_fd;
01936f59
JSP
543
544 if (VTOFDESC(ap->a_vp)->fd_type == Froot) {
545 struct dirent d;
546 struct dirent *dp = &d;
547 struct dirtmp *dt;
548
549 i = uio->uio_offset / UIO_MX;
550 error = 0;
551
552 while (uio->uio_resid > 0) {
553 dt = &rootent[i];
554 if (dt->d_fileno == 0) {
555 /**eofflagp = 1;*/
556 break;
557 }
558 i++;
559
560 switch (dt->d_fileno) {
561 case FD_CTTY:
562 if (cttyvp(uio->uio_procp) == NULL)
563 continue;
564 break;
565
566 case FD_STDIN:
567 case FD_STDOUT:
568 case FD_STDERR:
ede11b31 569 if ((dt->d_fileno-FD_STDIN) >= fdp->fd_nfiles)
01936f59 570 continue;
ede11b31 571 if (fdp->fd_ofiles[dt->d_fileno-FD_STDIN] == NULL)
01936f59
JSP
572 continue;
573 break;
574 }
ede11b31 575 bzero((caddr_t) dp, UIO_MX);
01936f59
JSP
576 dp->d_fileno = dt->d_fileno;
577 dp->d_namlen = dt->d_namlen;
578 dp->d_type = DT_UNKNOWN;
579 dp->d_reclen = dt->d_reclen;
580 bcopy(dt->d_name, dp->d_name, dp->d_namlen+1);
581 error = uiomove((caddr_t) dp, UIO_MX, uio);
582 if (error)
583 break;
584 }
585 uio->uio_offset = i * UIO_MX;
586 return (error);
587 }
588
a02db9dd 589 i = uio->uio_offset / UIO_MX;
e2e9adba 590 error = 0;
a02db9dd 591 while (uio->uio_resid > 0) {
43ec9518 592 if (i >= fdp->fd_nfiles)
e2e9adba 593 break;
43ec9518 594
e2e9adba 595 if (fdp->fd_ofiles[i] != NULL) {
13ef814e
JSP
596 struct dirent d;
597 struct dirent *dp = &d;
43ec9518 598
e2e9adba
JSP
599 bzero((caddr_t) dp, UIO_MX);
600
601 dp->d_namlen = sprintf(dp->d_name, "%d", i);
e2e9adba 602 dp->d_reclen = UIO_MX;
13ef814e 603 dp->d_type = DT_UNKNOWN;
01936f59 604 dp->d_fileno = i + FD_STDIN;
e2e9adba
JSP
605 /*
606 * And ship to userland
607 */
a02db9dd 608 error = uiomove((caddr_t) dp, UIO_MX, uio);
e2e9adba
JSP
609 if (error)
610 break;
611 }
612 i++;
613 }
614
a02db9dd 615 uio->uio_offset = i * UIO_MX;
e2e9adba
JSP
616 return (error);
617}
618
01936f59
JSP
619int
620fdesc_readlink(ap)
621 struct vop_readlink_args /* {
622 struct vnode *a_vp;
623 struct uio *a_uio;
624 struct ucred *a_cred;
625 } */ *ap;
626{
43ec9518 627 struct vnode *vp = ap->a_vp;
01936f59
JSP
628 int error;
629
630 if (vp->v_type != VLNK)
631 return (EPERM);
632
633 if (VTOFDESC(vp)->fd_type == Flink) {
634 char *ln = VTOFDESC(vp)->fd_link;
635 error = uiomove(ln, strlen(ln), ap->a_uio);
636 } else {
637 error = EOPNOTSUPP;
638 }
639
640 return (error);
641}
642
43ec9518 643int
01936f59
JSP
644fdesc_read(ap)
645 struct vop_read_args /* {
646 struct vnode *a_vp;
647 struct uio *a_uio;
648 int a_ioflag;
649 struct ucred *a_cred;
650 } */ *ap;
651{
652 int error = EOPNOTSUPP;
653
654 switch (VTOFDESC(ap->a_vp)->fd_type) {
655 case Fctty:
656 error = cttyread(devctty, ap->a_uio, ap->a_ioflag);
657 break;
658
659 default:
660 error = EOPNOTSUPP;
661 break;
662 }
663
664 return (error);
665}
666
43ec9518 667int
01936f59
JSP
668fdesc_write(ap)
669 struct vop_write_args /* {
670 struct vnode *a_vp;
671 struct uio *a_uio;
672 int a_ioflag;
673 struct ucred *a_cred;
674 } */ *ap;
675{
676 int error = EOPNOTSUPP;
677
678 switch (VTOFDESC(ap->a_vp)->fd_type) {
679 case Fctty:
680 error = cttywrite(devctty, ap->a_uio, ap->a_ioflag);
681 break;
682
683 default:
684 error = EOPNOTSUPP;
685 break;
686 }
687
688 return (error);
689}
690
43ec9518 691int
01936f59
JSP
692fdesc_ioctl(ap)
693 struct vop_ioctl_args /* {
694 struct vnode *a_vp;
695 int a_command;
696 caddr_t a_data;
697 int a_fflag;
698 struct ucred *a_cred;
699 struct proc *a_p;
700 } */ *ap;
701{
702 int error = EOPNOTSUPP;
703
01936f59
JSP
704 switch (VTOFDESC(ap->a_vp)->fd_type) {
705 case Fctty:
706 error = cttyioctl(devctty, ap->a_command, ap->a_data,
707 ap->a_fflag, ap->a_p);
708 break;
709
710 default:
711 error = EOPNOTSUPP;
712 break;
713 }
714
715 return (error);
716}
717
43ec9518 718int
01936f59
JSP
719fdesc_select(ap)
720 struct vop_select_args /* {
721 struct vnode *a_vp;
722 int a_which;
723 int a_fflags;
724 struct ucred *a_cred;
725 struct proc *a_p;
726 } */ *ap;
727{
728 int error = EOPNOTSUPP;
729
730 switch (VTOFDESC(ap->a_vp)->fd_type) {
731 case Fctty:
732 error = cttyselect(devctty, ap->a_fflags, ap->a_p);
733 break;
734
735 default:
736 error = EOPNOTSUPP;
737 break;
738 }
739
740 return (error);
741}
742
43ec9518 743int
5e3f92c4
KM
744fdesc_inactive(ap)
745 struct vop_inactive_args /* {
746 struct vnode *a_vp;
747 } */ *ap;
e2e9adba 748{
a02db9dd
JSP
749 struct vnode *vp = ap->a_vp;
750
e2e9adba
JSP
751 /*
752 * Clear out the v_type field to avoid
753 * nasty things happening in vgone().
754 */
a02db9dd 755 vp->v_type = VNON;
e2e9adba
JSP
756 return (0);
757}
758
43ec9518 759int
5e3f92c4
KM
760fdesc_reclaim(ap)
761 struct vop_reclaim_args /* {
762 struct vnode *a_vp;
763 } */ *ap;
e2e9adba
JSP
764{
765 struct vnode *vp = ap->a_vp;
01936f59 766
43ec9518
JSP
767 remque(VTOFDESC(vp));
768 FREE(vp->v_data, M_TEMP);
769 vp->v_data = 0;
770
e2e9adba
JSP
771 return (0);
772}
773
0020ca6e
JSP
774/*
775 * Return POSIX pathconf information applicable to special devices.
776 */
777fdesc_pathconf(ap)
778 struct vop_pathconf_args /* {
779 struct vnode *a_vp;
780 int a_name;
781 int *a_retval;
782 } */ *ap;
783{
784
785 switch (ap->a_name) {
786 case _PC_LINK_MAX:
787 *ap->a_retval = LINK_MAX;
788 return (0);
789 case _PC_MAX_CANON:
790 *ap->a_retval = MAX_CANON;
791 return (0);
792 case _PC_MAX_INPUT:
793 *ap->a_retval = MAX_INPUT;
794 return (0);
795 case _PC_PIPE_BUF:
796 *ap->a_retval = PIPE_BUF;
797 return (0);
798 case _PC_CHOWN_RESTRICTED:
799 *ap->a_retval = 1;
800 return (0);
801 case _PC_VDISABLE:
802 *ap->a_retval = _POSIX_VDISABLE;
803 return (0);
804 default:
805 return (EINVAL);
806 }
807 /* NOTREACHED */
808}
809
e2e9adba
JSP
810/*
811 * Print out the contents of a /dev/fd vnode.
812 */
813/* ARGSUSED */
43ec9518 814int
5e3f92c4
KM
815fdesc_print(ap)
816 struct vop_print_args /* {
817 struct vnode *a_vp;
818 } */ *ap;
e2e9adba 819{
5e3f92c4 820
e2e9adba 821 printf("tag VT_NON, fdesc vnode\n");
5e3f92c4 822 return (0);
e2e9adba
JSP
823}
824
825/*void*/
43ec9518 826int
5e3f92c4
KM
827fdesc_vfree(ap)
828 struct vop_vfree_args /* {
829 struct vnode *a_pvp;
830 ino_t a_ino;
831 int a_mode;
832 } */ *ap;
e2e9adba
JSP
833{
834
5e3f92c4 835 return (0);
e2e9adba
JSP
836}
837
838/*
839 * /dev/fd vnode unsupported operation
840 */
43ec9518 841int
e2e9adba
JSP
842fdesc_enotsupp()
843{
5e3f92c4 844
e2e9adba
JSP
845 return (EOPNOTSUPP);
846}
847
848/*
849 * /dev/fd "should never get here" operation
850 */
43ec9518 851int
e2e9adba
JSP
852fdesc_badop()
853{
5e3f92c4 854
e2e9adba
JSP
855 panic("fdesc: bad op");
856 /* NOTREACHED */
857}
858
859/*
860 * /dev/fd vnode null operation
861 */
43ec9518 862int
e2e9adba
JSP
863fdesc_nullop()
864{
5e3f92c4 865
e2e9adba
JSP
866 return (0);
867}
868
869#define fdesc_create ((int (*) __P((struct vop_create_args *)))fdesc_enotsupp)
870#define fdesc_mknod ((int (*) __P((struct vop_mknod_args *)))fdesc_enotsupp)
871#define fdesc_close ((int (*) __P((struct vop_close_args *)))nullop)
872#define fdesc_access ((int (*) __P((struct vop_access_args *)))nullop)
e2e9adba
JSP
873#define fdesc_mmap ((int (*) __P((struct vop_mmap_args *)))fdesc_enotsupp)
874#define fdesc_fsync ((int (*) __P((struct vop_fsync_args *)))nullop)
875#define fdesc_seek ((int (*) __P((struct vop_seek_args *)))nullop)
876#define fdesc_remove ((int (*) __P((struct vop_remove_args *)))fdesc_enotsupp)
877#define fdesc_link ((int (*) __P((struct vop_link_args *)))fdesc_enotsupp)
878#define fdesc_rename ((int (*) __P((struct vop_rename_args *)))fdesc_enotsupp)
879#define fdesc_mkdir ((int (*) __P((struct vop_mkdir_args *)))fdesc_enotsupp)
880#define fdesc_rmdir ((int (*) __P((struct vop_rmdir_args *)))fdesc_enotsupp)
5e3f92c4 881#define fdesc_symlink ((int (*) __P((struct vop_symlink_args *)))fdesc_enotsupp)
e2e9adba
JSP
882#define fdesc_abortop ((int (*) __P((struct vop_abortop_args *)))nullop)
883#define fdesc_lock ((int (*) __P((struct vop_lock_args *)))nullop)
884#define fdesc_unlock ((int (*) __P((struct vop_unlock_args *)))nullop)
885#define fdesc_bmap ((int (*) __P((struct vop_bmap_args *)))fdesc_badop)
886#define fdesc_strategy ((int (*) __P((struct vop_strategy_args *)))fdesc_badop)
887#define fdesc_islocked ((int (*) __P((struct vop_islocked_args *)))nullop)
5e3f92c4 888#define fdesc_advlock ((int (*) __P((struct vop_advlock_args *)))fdesc_enotsupp)
b076d1ce 889#define fdesc_blkatoff \
5e3f92c4 890 ((int (*) __P((struct vop_blkatoff_args *)))fdesc_enotsupp)
e2e9adba
JSP
891#define fdesc_vget ((int (*) __P((struct vop_vget_args *)))fdesc_enotsupp)
892#define fdesc_valloc ((int(*) __P(( \
893 struct vnode *pvp, \
894 int mode, \
895 struct ucred *cred, \
896 struct vnode **vpp))) fdesc_enotsupp)
b076d1ce 897#define fdesc_truncate \
5e3f92c4 898 ((int (*) __P((struct vop_truncate_args *)))fdesc_enotsupp)
e2e9adba
JSP
899#define fdesc_update ((int (*) __P((struct vop_update_args *)))fdesc_enotsupp)
900#define fdesc_bwrite ((int (*) __P((struct vop_bwrite_args *)))fdesc_enotsupp)
901
902int (**fdesc_vnodeop_p)();
903struct vnodeopv_entry_desc fdesc_vnodeop_entries[] = {
904 { &vop_default_desc, vn_default_error },
905 { &vop_lookup_desc, fdesc_lookup }, /* lookup */
906 { &vop_create_desc, fdesc_create }, /* create */
907 { &vop_mknod_desc, fdesc_mknod }, /* mknod */
5e3f92c4 908 { &vop_open_desc, fdesc_open }, /* open */
e2e9adba
JSP
909 { &vop_close_desc, fdesc_close }, /* close */
910 { &vop_access_desc, fdesc_access }, /* access */
911 { &vop_getattr_desc, fdesc_getattr }, /* getattr */
912 { &vop_setattr_desc, fdesc_setattr }, /* setattr */
5e3f92c4 913 { &vop_read_desc, fdesc_read }, /* read */
e2e9adba
JSP
914 { &vop_write_desc, fdesc_write }, /* write */
915 { &vop_ioctl_desc, fdesc_ioctl }, /* ioctl */
916 { &vop_select_desc, fdesc_select }, /* select */
5e3f92c4 917 { &vop_mmap_desc, fdesc_mmap }, /* mmap */
e2e9adba 918 { &vop_fsync_desc, fdesc_fsync }, /* fsync */
5e3f92c4 919 { &vop_seek_desc, fdesc_seek }, /* seek */
e2e9adba 920 { &vop_remove_desc, fdesc_remove }, /* remove */
5e3f92c4 921 { &vop_link_desc, fdesc_link }, /* link */
e2e9adba
JSP
922 { &vop_rename_desc, fdesc_rename }, /* rename */
923 { &vop_mkdir_desc, fdesc_mkdir }, /* mkdir */
924 { &vop_rmdir_desc, fdesc_rmdir }, /* rmdir */
925 { &vop_symlink_desc, fdesc_symlink }, /* symlink */
926 { &vop_readdir_desc, fdesc_readdir }, /* readdir */
927 { &vop_readlink_desc, fdesc_readlink }, /* readlink */
928 { &vop_abortop_desc, fdesc_abortop }, /* abortop */
929 { &vop_inactive_desc, fdesc_inactive }, /* inactive */
930 { &vop_reclaim_desc, fdesc_reclaim }, /* reclaim */
5e3f92c4 931 { &vop_lock_desc, fdesc_lock }, /* lock */
e2e9adba 932 { &vop_unlock_desc, fdesc_unlock }, /* unlock */
5e3f92c4 933 { &vop_bmap_desc, fdesc_bmap }, /* bmap */
e2e9adba
JSP
934 { &vop_strategy_desc, fdesc_strategy }, /* strategy */
935 { &vop_print_desc, fdesc_print }, /* print */
936 { &vop_islocked_desc, fdesc_islocked }, /* islocked */
0020ca6e 937 { &vop_pathconf_desc, fdesc_pathconf }, /* pathconf */
e2e9adba
JSP
938 { &vop_advlock_desc, fdesc_advlock }, /* advlock */
939 { &vop_blkatoff_desc, fdesc_blkatoff }, /* blkatoff */
e2e9adba
JSP
940 { &vop_valloc_desc, fdesc_valloc }, /* valloc */
941 { &vop_vfree_desc, fdesc_vfree }, /* vfree */
942 { &vop_truncate_desc, fdesc_truncate }, /* truncate */
943 { &vop_update_desc, fdesc_update }, /* update */
944 { &vop_bwrite_desc, fdesc_bwrite }, /* bwrite */
945 { (struct vnodeop_desc*)NULL, (int(*)())NULL }
946};
947struct vnodeopv_desc fdesc_vnodeop_opv_desc =
948 { &fdesc_vnodeop_p, fdesc_vnodeop_entries };