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