xref: /freebsd/sys/kern/kern_descrip.c (revision 4cf49a43559ed9fdad601bdcccd2c55963008675)
1 /*
2  * Copyright (c) 1982, 1986, 1989, 1991, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  * (c) UNIX System Laboratories, Inc.
5  * All or some portions of this file are derived from material licensed
6  * to the University of California by American Telephone and Telegraph
7  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8  * the permission of UNIX System Laboratories, Inc.
9  *
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.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *	This product includes software developed by the University of
21  *	California, Berkeley and its contributors.
22  * 4. Neither the name of the University nor the names of its contributors
23  *    may be used to endorse or promote products derived from this software
24  *    without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36  * SUCH DAMAGE.
37  *
38  *	@(#)kern_descrip.c	8.6 (Berkeley) 4/19/94
39  * $FreeBSD$
40  */
41 
42 #include "opt_compat.h"
43 #include <sys/param.h>
44 #include <sys/systm.h>
45 #include <sys/sysproto.h>
46 #include <sys/conf.h>
47 #include <sys/filedesc.h>
48 #include <sys/kernel.h>
49 #include <sys/sysctl.h>
50 #include <sys/vnode.h>
51 #include <sys/proc.h>
52 #include <sys/file.h>
53 #include <sys/socketvar.h>
54 #include <sys/stat.h>
55 #include <sys/filio.h>
56 #include <sys/fcntl.h>
57 #include <sys/malloc.h>
58 #include <sys/unistd.h>
59 #include <sys/resourcevar.h>
60 #include <sys/pipe.h>
61 
62 #include <vm/vm.h>
63 #include <vm/vm_extern.h>
64 
65 static MALLOC_DEFINE(M_FILEDESC, "file desc", "Open file descriptor table");
66 MALLOC_DEFINE(M_FILE, "file", "Open file structure");
67 static MALLOC_DEFINE(M_SIGIO, "sigio", "sigio structures");
68 
69 
70 static	 d_open_t  fdopen;
71 #define NUMFDESC 64
72 
73 #define CDEV_MAJOR 22
74 static struct cdevsw fildesc_cdevsw = {
75 	/* open */	fdopen,
76 	/* close */	noclose,
77 	/* read */	noread,
78 	/* write */	nowrite,
79 	/* ioctl */	noioctl,
80 	/* poll */	nopoll,
81 	/* mmap */	nommap,
82 	/* strategy */	nostrategy,
83 	/* name */	"FD",
84 	/* maj */	CDEV_MAJOR,
85 	/* dump */	nodump,
86 	/* psize */	nopsize,
87 	/* flags */	0,
88 	/* bmaj */	-1
89 };
90 
91 static int finishdup __P((struct filedesc *fdp, int old, int new, register_t *retval));
92 static int badfo_readwrite __P((struct file *fp, struct uio *uio,
93     struct ucred *cred, int flags, struct proc *p));
94 static int badfo_ioctl __P((struct file *fp, u_long com, caddr_t data,
95     struct proc *p));
96 static int badfo_poll __P((struct file *fp, int events,
97     struct ucred *cred, struct proc *p));
98 static int badfo_close __P((struct file *fp, struct proc *p));
99 /*
100  * Descriptor management.
101  */
102 struct filelist filehead;	/* head of list of open files */
103 int nfiles;			/* actual number of open files */
104 extern int cmask;
105 
106 /*
107  * System calls on descriptors.
108  */
109 #ifndef _SYS_SYSPROTO_H_
110 struct getdtablesize_args {
111 	int	dummy;
112 };
113 #endif
114 /* ARGSUSED */
115 int
116 getdtablesize(p, uap)
117 	struct proc *p;
118 	struct getdtablesize_args *uap;
119 {
120 
121 	p->p_retval[0] =
122 	    min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfilesperproc);
123 	return (0);
124 }
125 
126 /*
127  * Duplicate a file descriptor to a particular value.
128  */
129 #ifndef _SYS_SYSPROTO_H_
130 struct dup2_args {
131 	u_int	from;
132 	u_int	to;
133 };
134 #endif
135 /* ARGSUSED */
136 int
137 dup2(p, uap)
138 	struct proc *p;
139 	struct dup2_args *uap;
140 {
141 	register struct filedesc *fdp = p->p_fd;
142 	register u_int old = uap->from, new = uap->to;
143 	int i, error;
144 
145 	if (old >= fdp->fd_nfiles ||
146 	    fdp->fd_ofiles[old] == NULL ||
147 	    new >= p->p_rlimit[RLIMIT_NOFILE].rlim_cur ||
148 	    new >= maxfilesperproc)
149 		return (EBADF);
150 	if (old == new) {
151 		p->p_retval[0] = new;
152 		return (0);
153 	}
154 	if (new >= fdp->fd_nfiles) {
155 		if ((error = fdalloc(p, new, &i)))
156 			return (error);
157 		if (new != i)
158 			panic("dup2: fdalloc");
159 	} else if (fdp->fd_ofiles[new]) {
160 		if (fdp->fd_ofileflags[new] & UF_MAPPED)
161 			(void) munmapfd(p, new);
162 		/*
163 		 * dup2() must succeed even if the close has an error.
164 		 */
165 		(void) closef(fdp->fd_ofiles[new], p);
166 	}
167 	return (finishdup(fdp, (int)old, (int)new, p->p_retval));
168 }
169 
170 /*
171  * Duplicate a file descriptor.
172  */
173 #ifndef _SYS_SYSPROTO_H_
174 struct dup_args {
175 	u_int	fd;
176 };
177 #endif
178 /* ARGSUSED */
179 int
180 dup(p, uap)
181 	struct proc *p;
182 	struct dup_args *uap;
183 {
184 	register struct filedesc *fdp;
185 	u_int old;
186 	int new, error;
187 
188 	old = uap->fd;
189 
190 #if 0
191 	/*
192 	 * XXX Compatibility
193 	 */
194 	if (old &~ 077) { uap->fd &= 077; return (dup2(p, uap, p->p_retval)); }
195 #endif
196 
197 	fdp = p->p_fd;
198 	if (old >= fdp->fd_nfiles || fdp->fd_ofiles[old] == NULL)
199 		return (EBADF);
200 	if ((error = fdalloc(p, 0, &new)))
201 		return (error);
202 	return (finishdup(fdp, (int)old, new, p->p_retval));
203 }
204 
205 /*
206  * The file control system call.
207  */
208 #ifndef _SYS_SYSPROTO_H_
209 struct fcntl_args {
210 	int	fd;
211 	int	cmd;
212 	long	arg;
213 };
214 #endif
215 /* ARGSUSED */
216 int
217 fcntl(p, uap)
218 	struct proc *p;
219 	register struct fcntl_args *uap;
220 {
221 	register struct filedesc *fdp = p->p_fd;
222 	register struct file *fp;
223 	register char *pop;
224 	struct vnode *vp;
225 	int i, tmp, error, flg = F_POSIX;
226 	struct flock fl;
227 	u_int newmin;
228 
229 	if ((unsigned)uap->fd >= fdp->fd_nfiles ||
230 	    (fp = fdp->fd_ofiles[uap->fd]) == NULL)
231 		return (EBADF);
232 	pop = &fdp->fd_ofileflags[uap->fd];
233 	switch (uap->cmd) {
234 
235 	case F_DUPFD:
236 		newmin = uap->arg;
237 		if (newmin >= p->p_rlimit[RLIMIT_NOFILE].rlim_cur ||
238 		    newmin >= maxfilesperproc)
239 			return (EINVAL);
240 		if ((error = fdalloc(p, newmin, &i)))
241 			return (error);
242 		return (finishdup(fdp, uap->fd, i, p->p_retval));
243 
244 	case F_GETFD:
245 		p->p_retval[0] = *pop & 1;
246 		return (0);
247 
248 	case F_SETFD:
249 		*pop = (*pop &~ 1) | (uap->arg & 1);
250 		return (0);
251 
252 	case F_GETFL:
253 		p->p_retval[0] = OFLAGS(fp->f_flag);
254 		return (0);
255 
256 	case F_SETFL:
257 		fp->f_flag &= ~FCNTLFLAGS;
258 		fp->f_flag |= FFLAGS(uap->arg & ~O_ACCMODE) & FCNTLFLAGS;
259 		tmp = fp->f_flag & FNONBLOCK;
260 		error = fo_ioctl(fp, FIONBIO, (caddr_t)&tmp, p);
261 		if (error)
262 			return (error);
263 		tmp = fp->f_flag & FASYNC;
264 		error = fo_ioctl(fp, FIOASYNC, (caddr_t)&tmp, p);
265 		if (!error)
266 			return (0);
267 		fp->f_flag &= ~FNONBLOCK;
268 		tmp = 0;
269 		(void)fo_ioctl(fp, FIONBIO, (caddr_t)&tmp, p);
270 		return (error);
271 
272 	case F_GETOWN:
273 		return (fo_ioctl(fp, FIOGETOWN, (caddr_t)p->p_retval, p));
274 
275 	case F_SETOWN:
276 		return (fo_ioctl(fp, FIOSETOWN, (caddr_t)&uap->arg, p));
277 
278 	case F_SETLKW:
279 		flg |= F_WAIT;
280 		/* Fall into F_SETLK */
281 
282 	case F_SETLK:
283 		if (fp->f_type != DTYPE_VNODE)
284 			return (EBADF);
285 		vp = (struct vnode *)fp->f_data;
286 		/* Copy in the lock structure */
287 		error = copyin((caddr_t)(intptr_t)uap->arg, (caddr_t)&fl,
288 		    sizeof(fl));
289 		if (error)
290 			return (error);
291 		if (fl.l_whence == SEEK_CUR)
292 			fl.l_start += fp->f_offset;
293 		switch (fl.l_type) {
294 
295 		case F_RDLCK:
296 			if ((fp->f_flag & FREAD) == 0)
297 				return (EBADF);
298 			p->p_flag |= P_ADVLOCK;
299 			return (VOP_ADVLOCK(vp, (caddr_t)p->p_leader, F_SETLK, &fl, flg));
300 
301 		case F_WRLCK:
302 			if ((fp->f_flag & FWRITE) == 0)
303 				return (EBADF);
304 			p->p_flag |= P_ADVLOCK;
305 			return (VOP_ADVLOCK(vp, (caddr_t)p->p_leader, F_SETLK, &fl, flg));
306 
307 		case F_UNLCK:
308 			return (VOP_ADVLOCK(vp, (caddr_t)p->p_leader, F_UNLCK, &fl,
309 				F_POSIX));
310 
311 		default:
312 			return (EINVAL);
313 		}
314 
315 	case F_GETLK:
316 		if (fp->f_type != DTYPE_VNODE)
317 			return (EBADF);
318 		vp = (struct vnode *)fp->f_data;
319 		/* Copy in the lock structure */
320 		error = copyin((caddr_t)(intptr_t)uap->arg, (caddr_t)&fl,
321 		    sizeof(fl));
322 		if (error)
323 			return (error);
324 		if (fl.l_type != F_RDLCK && fl.l_type != F_WRLCK &&
325 		    fl.l_type != F_UNLCK)
326 			return (EINVAL);
327 		if (fl.l_whence == SEEK_CUR)
328 			fl.l_start += fp->f_offset;
329 		if ((error = VOP_ADVLOCK(vp,(caddr_t)p->p_leader,F_GETLK,&fl,F_POSIX)))
330 			return (error);
331 		return (copyout((caddr_t)&fl, (caddr_t)(intptr_t)uap->arg,
332 		    sizeof(fl)));
333 
334 	default:
335 		return (EINVAL);
336 	}
337 	/* NOTREACHED */
338 }
339 
340 /*
341  * Common code for dup, dup2, and fcntl(F_DUPFD).
342  */
343 static int
344 finishdup(fdp, old, new, retval)
345 	register struct filedesc *fdp;
346 	register int old, new;
347 	register_t *retval;
348 {
349 	register struct file *fp;
350 
351 	fp = fdp->fd_ofiles[old];
352 	fdp->fd_ofiles[new] = fp;
353 	fdp->fd_ofileflags[new] = fdp->fd_ofileflags[old] &~ UF_EXCLOSE;
354 	fhold(fp);
355 	if (new > fdp->fd_lastfile)
356 		fdp->fd_lastfile = new;
357 	*retval = new;
358 	return (0);
359 }
360 
361 /*
362  * If sigio is on the list associated with a process or process group,
363  * disable signalling from the device, remove sigio from the list and
364  * free sigio.
365  */
366 void
367 funsetown(sigio)
368 	struct sigio *sigio;
369 {
370 	int s;
371 
372 	if (sigio == NULL)
373 		return;
374 	s = splhigh();
375 	*(sigio->sio_myref) = NULL;
376 	splx(s);
377 	if (sigio->sio_pgid < 0) {
378 		SLIST_REMOVE(&sigio->sio_pgrp->pg_sigiolst, sigio,
379 			     sigio, sio_pgsigio);
380 	} else /* if ((*sigiop)->sio_pgid > 0) */ {
381 		SLIST_REMOVE(&sigio->sio_proc->p_sigiolst, sigio,
382 			     sigio, sio_pgsigio);
383 	}
384 	crfree(sigio->sio_ucred);
385 	FREE(sigio, M_SIGIO);
386 }
387 
388 /* Free a list of sigio structures. */
389 void
390 funsetownlst(sigiolst)
391 	struct sigiolst *sigiolst;
392 {
393 	struct sigio *sigio;
394 
395 	while ((sigio = sigiolst->slh_first) != NULL)
396 		funsetown(sigio);
397 }
398 
399 /*
400  * This is common code for FIOSETOWN ioctl called by fcntl(fd, F_SETOWN, arg).
401  *
402  * After permission checking, add a sigio structure to the sigio list for
403  * the process or process group.
404  */
405 int
406 fsetown(pgid, sigiop)
407 	pid_t pgid;
408 	struct sigio **sigiop;
409 {
410 	struct proc *proc;
411 	struct pgrp *pgrp;
412 	struct sigio *sigio;
413 	int s;
414 
415 	if (pgid == 0) {
416 		funsetown(*sigiop);
417 		return (0);
418 	}
419 	if (pgid > 0) {
420 		proc = pfind(pgid);
421 		if (proc == NULL)
422 			return (ESRCH);
423 		/*
424 		 * Policy - Don't allow a process to FSETOWN a process
425 		 * in another session.
426 		 *
427 		 * Remove this test to allow maximum flexibility or
428 		 * restrict FSETOWN to the current process or process
429 		 * group for maximum safety.
430 		 */
431 		else if (proc->p_session != curproc->p_session)
432 			return (EPERM);
433 		pgrp = NULL;
434 	} else /* if (pgid < 0) */ {
435 		pgrp = pgfind(-pgid);
436 		if (pgrp == NULL)
437 			return (ESRCH);
438 		/*
439 		 * Policy - Don't allow a process to FSETOWN a process
440 		 * in another session.
441 		 *
442 		 * Remove this test to allow maximum flexibility or
443 		 * restrict FSETOWN to the current process or process
444 		 * group for maximum safety.
445 		 */
446 		else if (pgrp->pg_session != curproc->p_session)
447 			return (EPERM);
448 		proc = NULL;
449 	}
450 	funsetown(*sigiop);
451 	MALLOC(sigio, struct sigio *, sizeof(struct sigio), M_SIGIO,
452 	       M_WAITOK);
453 	if (pgid > 0) {
454 		SLIST_INSERT_HEAD(&proc->p_sigiolst, sigio, sio_pgsigio);
455 		sigio->sio_proc = proc;
456 	} else {
457 		SLIST_INSERT_HEAD(&pgrp->pg_sigiolst, sigio, sio_pgsigio);
458 		sigio->sio_pgrp = pgrp;
459 	}
460 	sigio->sio_pgid = pgid;
461 	crhold(curproc->p_ucred);
462 	sigio->sio_ucred = curproc->p_ucred;
463 	/* It would be convenient if p_ruid was in ucred. */
464 	sigio->sio_ruid = curproc->p_cred->p_ruid;
465 	sigio->sio_myref = sigiop;
466 	s = splhigh();
467 	*sigiop = sigio;
468 	splx(s);
469 	return (0);
470 }
471 
472 /*
473  * This is common code for FIOGETOWN ioctl called by fcntl(fd, F_GETOWN, arg).
474  */
475 pid_t
476 fgetown(sigio)
477 	struct sigio *sigio;
478 {
479 	return (sigio != NULL ? sigio->sio_pgid : 0);
480 }
481 
482 /*
483  * Close a file descriptor.
484  */
485 #ifndef _SYS_SYSPROTO_H_
486 struct close_args {
487         int     fd;
488 };
489 #endif
490 /* ARGSUSED */
491 int
492 close(p, uap)
493 	struct proc *p;
494 	struct close_args *uap;
495 {
496 	register struct filedesc *fdp = p->p_fd;
497 	register struct file *fp;
498 	register int fd = uap->fd;
499 	register u_char *pf;
500 
501 	if ((unsigned)fd >= fdp->fd_nfiles ||
502 	    (fp = fdp->fd_ofiles[fd]) == NULL)
503 		return (EBADF);
504 	pf = (u_char *)&fdp->fd_ofileflags[fd];
505 	if (*pf & UF_MAPPED)
506 		(void) munmapfd(p, fd);
507 	fdp->fd_ofiles[fd] = NULL;
508 	while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL)
509 		fdp->fd_lastfile--;
510 	if (fd < fdp->fd_freefile)
511 		fdp->fd_freefile = fd;
512 	*pf = 0;
513 	return (closef(fp, p));
514 }
515 
516 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
517 /*
518  * Return status information about a file descriptor.
519  */
520 #ifndef _SYS_SYSPROTO_H_
521 struct ofstat_args {
522 	int	fd;
523 	struct	ostat *sb;
524 };
525 #endif
526 /* ARGSUSED */
527 int
528 ofstat(p, uap)
529 	struct proc *p;
530 	register struct ofstat_args *uap;
531 {
532 	register struct filedesc *fdp = p->p_fd;
533 	register struct file *fp;
534 	struct stat ub;
535 	struct ostat oub;
536 	int error;
537 
538 	if ((unsigned)uap->fd >= fdp->fd_nfiles ||
539 	    (fp = fdp->fd_ofiles[uap->fd]) == NULL)
540 		return (EBADF);
541 	switch (fp->f_type) {
542 
543 	case DTYPE_FIFO:
544 	case DTYPE_VNODE:
545 		error = vn_stat((struct vnode *)fp->f_data, &ub, p);
546 		break;
547 
548 	case DTYPE_SOCKET:
549 		error = soo_stat((struct socket *)fp->f_data, &ub);
550 		break;
551 
552 	case DTYPE_PIPE:
553 		error = pipe_stat((struct pipe *)fp->f_data, &ub);
554 		break;
555 
556 	default:
557 		panic("ofstat");
558 		/*NOTREACHED*/
559 	}
560 	cvtstat(&ub, &oub);
561 	if (error == 0)
562 		error = copyout((caddr_t)&oub, (caddr_t)uap->sb, sizeof (oub));
563 	return (error);
564 }
565 #endif /* COMPAT_43 || COMPAT_SUNOS */
566 
567 /*
568  * Return status information about a file descriptor.
569  */
570 #ifndef _SYS_SYSPROTO_H_
571 struct fstat_args {
572 	int	fd;
573 	struct	stat *sb;
574 };
575 #endif
576 /* ARGSUSED */
577 int
578 fstat(p, uap)
579 	struct proc *p;
580 	register struct fstat_args *uap;
581 {
582 	register struct filedesc *fdp = p->p_fd;
583 	register struct file *fp;
584 	struct stat ub;
585 	int error;
586 
587 	if ((unsigned)uap->fd >= fdp->fd_nfiles ||
588 	    (fp = fdp->fd_ofiles[uap->fd]) == NULL)
589 		return (EBADF);
590 	switch (fp->f_type) {
591 
592 	case DTYPE_FIFO:
593 	case DTYPE_VNODE:
594 		error = vn_stat((struct vnode *)fp->f_data, &ub, p);
595 		break;
596 
597 	case DTYPE_SOCKET:
598 		error = soo_stat((struct socket *)fp->f_data, &ub);
599 		break;
600 
601 	case DTYPE_PIPE:
602 		error = pipe_stat((struct pipe *)fp->f_data, &ub);
603 		break;
604 
605 	default:
606 		panic("fstat");
607 		/*NOTREACHED*/
608 	}
609 	if (error == 0)
610 		error = copyout((caddr_t)&ub, (caddr_t)uap->sb, sizeof (ub));
611 	return (error);
612 }
613 
614 /*
615  * Return status information about a file descriptor.
616  */
617 #ifndef _SYS_SYSPROTO_H_
618 struct nfstat_args {
619 	int	fd;
620 	struct	nstat *sb;
621 };
622 #endif
623 /* ARGSUSED */
624 int
625 nfstat(p, uap)
626 	struct proc *p;
627 	register struct nfstat_args *uap;
628 {
629 	register struct filedesc *fdp = p->p_fd;
630 	register struct file *fp;
631 	struct stat ub;
632 	struct nstat nub;
633 	int error;
634 
635 	if ((unsigned)uap->fd >= fdp->fd_nfiles ||
636 	    (fp = fdp->fd_ofiles[uap->fd]) == NULL)
637 		return (EBADF);
638 	switch (fp->f_type) {
639 
640 	case DTYPE_FIFO:
641 	case DTYPE_VNODE:
642 		error = vn_stat((struct vnode *)fp->f_data, &ub, p);
643 		break;
644 
645 	case DTYPE_SOCKET:
646 		error = soo_stat((struct socket *)fp->f_data, &ub);
647 		break;
648 
649 	case DTYPE_PIPE:
650 		error = pipe_stat((struct pipe *)fp->f_data, &ub);
651 		break;
652 
653 	default:
654 		panic("fstat");
655 		/*NOTREACHED*/
656 	}
657 	if (error == 0) {
658 		cvtnstat(&ub, &nub);
659 		error = copyout((caddr_t)&nub, (caddr_t)uap->sb, sizeof (nub));
660 	}
661 	return (error);
662 }
663 
664 /*
665  * Return pathconf information about a file descriptor.
666  */
667 #ifndef _SYS_SYSPROTO_H_
668 struct fpathconf_args {
669 	int	fd;
670 	int	name;
671 };
672 #endif
673 /* ARGSUSED */
674 int
675 fpathconf(p, uap)
676 	struct proc *p;
677 	register struct fpathconf_args *uap;
678 {
679 	struct filedesc *fdp = p->p_fd;
680 	struct file *fp;
681 	struct vnode *vp;
682 
683 	if ((unsigned)uap->fd >= fdp->fd_nfiles ||
684 	    (fp = fdp->fd_ofiles[uap->fd]) == NULL)
685 		return (EBADF);
686 	switch (fp->f_type) {
687 
688 	case DTYPE_PIPE:
689 	case DTYPE_SOCKET:
690 		if (uap->name != _PC_PIPE_BUF)
691 			return (EINVAL);
692 		p->p_retval[0] = PIPE_BUF;
693 		return (0);
694 
695 	case DTYPE_FIFO:
696 	case DTYPE_VNODE:
697 		vp = (struct vnode *)fp->f_data;
698 		return (VOP_PATHCONF(vp, uap->name, p->p_retval));
699 
700 	default:
701 		panic("fpathconf");
702 	}
703 	/*NOTREACHED*/
704 }
705 
706 /*
707  * Allocate a file descriptor for the process.
708  */
709 static int fdexpand;
710 SYSCTL_INT(_debug, OID_AUTO, fdexpand, CTLFLAG_RD, &fdexpand, 0, "");
711 
712 int
713 fdalloc(p, want, result)
714 	struct proc *p;
715 	int want;
716 	int *result;
717 {
718 	register struct filedesc *fdp = p->p_fd;
719 	register int i;
720 	int lim, last, nfiles;
721 	struct file **newofile;
722 	char *newofileflags;
723 
724 	/*
725 	 * Search for a free descriptor starting at the higher
726 	 * of want or fd_freefile.  If that fails, consider
727 	 * expanding the ofile array.
728 	 */
729 	lim = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfilesperproc);
730 	for (;;) {
731 		last = min(fdp->fd_nfiles, lim);
732 		if ((i = want) < fdp->fd_freefile)
733 			i = fdp->fd_freefile;
734 		for (; i < last; i++) {
735 			if (fdp->fd_ofiles[i] == NULL) {
736 				fdp->fd_ofileflags[i] = 0;
737 				if (i > fdp->fd_lastfile)
738 					fdp->fd_lastfile = i;
739 				if (want <= fdp->fd_freefile)
740 					fdp->fd_freefile = i;
741 				*result = i;
742 				return (0);
743 			}
744 		}
745 
746 		/*
747 		 * No space in current array.  Expand?
748 		 */
749 		if (fdp->fd_nfiles >= lim)
750 			return (EMFILE);
751 		if (fdp->fd_nfiles < NDEXTENT)
752 			nfiles = NDEXTENT;
753 		else
754 			nfiles = 2 * fdp->fd_nfiles;
755 		MALLOC(newofile, struct file **, nfiles * OFILESIZE,
756 		    M_FILEDESC, M_WAITOK);
757 		newofileflags = (char *) &newofile[nfiles];
758 		/*
759 		 * Copy the existing ofile and ofileflags arrays
760 		 * and zero the new portion of each array.
761 		 */
762 		bcopy(fdp->fd_ofiles, newofile,
763 			(i = sizeof(struct file *) * fdp->fd_nfiles));
764 		bzero((char *)newofile + i, nfiles * sizeof(struct file *) - i);
765 		bcopy(fdp->fd_ofileflags, newofileflags,
766 			(i = sizeof(char) * fdp->fd_nfiles));
767 		bzero(newofileflags + i, nfiles * sizeof(char) - i);
768 		if (fdp->fd_nfiles > NDFILE)
769 			FREE(fdp->fd_ofiles, M_FILEDESC);
770 		fdp->fd_ofiles = newofile;
771 		fdp->fd_ofileflags = newofileflags;
772 		fdp->fd_nfiles = nfiles;
773 		fdexpand++;
774 	}
775 	return (0);
776 }
777 
778 /*
779  * Check to see whether n user file descriptors
780  * are available to the process p.
781  */
782 int
783 fdavail(p, n)
784 	struct proc *p;
785 	register int n;
786 {
787 	register struct filedesc *fdp = p->p_fd;
788 	register struct file **fpp;
789 	register int i, lim, last;
790 
791 	lim = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfilesperproc);
792 	if ((i = lim - fdp->fd_nfiles) > 0 && (n -= i) <= 0)
793 		return (1);
794 
795 	last = min(fdp->fd_nfiles, lim);
796 	fpp = &fdp->fd_ofiles[fdp->fd_freefile];
797 	for (i = last - fdp->fd_freefile; --i >= 0; fpp++)
798 		if (*fpp == NULL && --n <= 0)
799 			return (1);
800 	return (0);
801 }
802 
803 /*
804  * Create a new open file structure and allocate
805  * a file decriptor for the process that refers to it.
806  */
807 int
808 falloc(p, resultfp, resultfd)
809 	register struct proc *p;
810 	struct file **resultfp;
811 	int *resultfd;
812 {
813 	register struct file *fp, *fq;
814 	int error, i;
815 
816 	if ((error = fdalloc(p, 0, &i)))
817 		return (error);
818 	if (nfiles >= maxfiles) {
819 		tablefull("file");
820 		return (ENFILE);
821 	}
822 	/*
823 	 * Allocate a new file descriptor.
824 	 * If the process has file descriptor zero open, add to the list
825 	 * of open files at that point, otherwise put it at the front of
826 	 * the list of open files.
827 	 */
828 	nfiles++;
829 	MALLOC(fp, struct file *, sizeof(struct file), M_FILE, M_WAITOK);
830 	bzero(fp, sizeof(struct file));
831 	fp->f_count = 1;
832 	fp->f_cred = p->p_ucred;
833 	fp->f_ops = &badfileops;
834 	fp->f_seqcount = 1;
835 	crhold(fp->f_cred);
836 	if ((fq = p->p_fd->fd_ofiles[0])) {
837 		LIST_INSERT_AFTER(fq, fp, f_list);
838 	} else {
839 		LIST_INSERT_HEAD(&filehead, fp, f_list);
840 	}
841 	p->p_fd->fd_ofiles[i] = fp;
842 	if (resultfp)
843 		*resultfp = fp;
844 	if (resultfd)
845 		*resultfd = i;
846 	return (0);
847 }
848 
849 /*
850  * Free a file descriptor.
851  */
852 void
853 ffree(fp)
854 	register struct file *fp;
855 {
856 	LIST_REMOVE(fp, f_list);
857 	crfree(fp->f_cred);
858 #if defined(DIAGNOSTIC) || defined(INVARIANTS)
859 	fp->f_count = 0;
860 #endif
861 	nfiles--;
862 	FREE(fp, M_FILE);
863 }
864 
865 /*
866  * Build a new filedesc structure.
867  */
868 struct filedesc *
869 fdinit(p)
870 	struct proc *p;
871 {
872 	register struct filedesc0 *newfdp;
873 	register struct filedesc *fdp = p->p_fd;
874 
875 	MALLOC(newfdp, struct filedesc0 *, sizeof(struct filedesc0),
876 	    M_FILEDESC, M_WAITOK);
877 	bzero(newfdp, sizeof(struct filedesc0));
878 	newfdp->fd_fd.fd_cdir = fdp->fd_cdir;
879 	VREF(newfdp->fd_fd.fd_cdir);
880 	newfdp->fd_fd.fd_rdir = fdp->fd_rdir;
881 	VREF(newfdp->fd_fd.fd_rdir);
882 	newfdp->fd_fd.fd_jdir = fdp->fd_jdir;
883 	if (newfdp->fd_fd.fd_jdir)
884 		VREF(newfdp->fd_fd.fd_jdir);
885 
886 	/* Create the file descriptor table. */
887 	newfdp->fd_fd.fd_refcnt = 1;
888 	newfdp->fd_fd.fd_cmask = cmask;
889 	newfdp->fd_fd.fd_ofiles = newfdp->fd_dfiles;
890 	newfdp->fd_fd.fd_ofileflags = newfdp->fd_dfileflags;
891 	newfdp->fd_fd.fd_nfiles = NDFILE;
892 
893 	newfdp->fd_fd.fd_freefile = 0;
894 	newfdp->fd_fd.fd_lastfile = 0;
895 
896 	return (&newfdp->fd_fd);
897 }
898 
899 /*
900  * Share a filedesc structure.
901  */
902 struct filedesc *
903 fdshare(p)
904 	struct proc *p;
905 {
906 	p->p_fd->fd_refcnt++;
907 	return (p->p_fd);
908 }
909 
910 /*
911  * Copy a filedesc structure.
912  */
913 struct filedesc *
914 fdcopy(p)
915 	struct proc *p;
916 {
917 	register struct filedesc *newfdp, *fdp = p->p_fd;
918 	register struct file **fpp;
919 	register int i;
920 
921 /*
922  * Certain daemons might not have file descriptors
923  */
924 	if (fdp == NULL)
925 		return NULL;
926 
927 	MALLOC(newfdp, struct filedesc *, sizeof(struct filedesc0),
928 	    M_FILEDESC, M_WAITOK);
929 	bcopy(fdp, newfdp, sizeof(struct filedesc));
930 	VREF(newfdp->fd_cdir);
931 	VREF(newfdp->fd_rdir);
932 	if (newfdp->fd_jdir)
933 		VREF(newfdp->fd_jdir);
934 	newfdp->fd_refcnt = 1;
935 
936 	/*
937 	 * If the number of open files fits in the internal arrays
938 	 * of the open file structure, use them, otherwise allocate
939 	 * additional memory for the number of descriptors currently
940 	 * in use.
941 	 */
942 	if (newfdp->fd_lastfile < NDFILE) {
943 		newfdp->fd_ofiles = ((struct filedesc0 *) newfdp)->fd_dfiles;
944 		newfdp->fd_ofileflags =
945 		    ((struct filedesc0 *) newfdp)->fd_dfileflags;
946 		i = NDFILE;
947 	} else {
948 		/*
949 		 * Compute the smallest multiple of NDEXTENT needed
950 		 * for the file descriptors currently in use,
951 		 * allowing the table to shrink.
952 		 */
953 		i = newfdp->fd_nfiles;
954 		while (i > 2 * NDEXTENT && i > newfdp->fd_lastfile * 2)
955 			i /= 2;
956 		MALLOC(newfdp->fd_ofiles, struct file **, i * OFILESIZE,
957 		    M_FILEDESC, M_WAITOK);
958 		newfdp->fd_ofileflags = (char *) &newfdp->fd_ofiles[i];
959 	}
960 	newfdp->fd_nfiles = i;
961 	bcopy(fdp->fd_ofiles, newfdp->fd_ofiles, i * sizeof(struct file **));
962 	bcopy(fdp->fd_ofileflags, newfdp->fd_ofileflags, i * sizeof(char));
963 	fpp = newfdp->fd_ofiles;
964 	for (i = newfdp->fd_lastfile; i-- >= 0; fpp++)
965 		if (*fpp != NULL)
966 			fhold(*fpp);
967 	return (newfdp);
968 }
969 
970 /*
971  * Release a filedesc structure.
972  */
973 void
974 fdfree(p)
975 	struct proc *p;
976 {
977 	register struct filedesc *fdp = p->p_fd;
978 	struct file **fpp;
979 	register int i;
980 
981 /*
982  * Certain daemons might not have file descriptors
983  */
984 	if (fdp == NULL)
985 		return;
986 
987 	if (--fdp->fd_refcnt > 0)
988 		return;
989 	fpp = fdp->fd_ofiles;
990 	for (i = fdp->fd_lastfile; i-- >= 0; fpp++)
991 		if (*fpp)
992 			(void) closef(*fpp, p);
993 	if (fdp->fd_nfiles > NDFILE)
994 		FREE(fdp->fd_ofiles, M_FILEDESC);
995 	vrele(fdp->fd_cdir);
996 	vrele(fdp->fd_rdir);
997 	if(fdp->fd_jdir)
998 		vrele(fdp->fd_jdir);
999 	FREE(fdp, M_FILEDESC);
1000 }
1001 
1002 /*
1003  * Close any files on exec?
1004  */
1005 void
1006 fdcloseexec(p)
1007 	struct proc *p;
1008 {
1009 	struct filedesc *fdp = p->p_fd;
1010 	struct file **fpp;
1011 	char *fdfp;
1012 	register int i;
1013 
1014 /*
1015  * Certain daemons might not have file descriptors
1016  */
1017 	if (fdp == NULL)
1018 		return;
1019 
1020 	fpp = fdp->fd_ofiles;
1021 	fdfp = fdp->fd_ofileflags;
1022 	for (i = 0; i <= fdp->fd_lastfile; i++, fpp++, fdfp++)
1023 		if (*fpp != NULL && (*fdfp & UF_EXCLOSE)) {
1024 			if (*fdfp & UF_MAPPED)
1025 				(void) munmapfd(p, i);
1026 			(void) closef(*fpp, p);
1027 			*fpp = NULL;
1028 			*fdfp = 0;
1029 			if (i < fdp->fd_freefile)
1030 				fdp->fd_freefile = i;
1031 		}
1032 	while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL)
1033 		fdp->fd_lastfile--;
1034 }
1035 
1036 /*
1037  * Internal form of close.
1038  * Decrement reference count on file structure.
1039  * Note: p may be NULL when closing a file
1040  * that was being passed in a message.
1041  */
1042 int
1043 closef(fp, p)
1044 	register struct file *fp;
1045 	register struct proc *p;
1046 {
1047 	struct vnode *vp;
1048 	struct flock lf;
1049 
1050 	if (fp == NULL)
1051 		return (0);
1052 	/*
1053 	 * POSIX record locking dictates that any close releases ALL
1054 	 * locks owned by this process.  This is handled by setting
1055 	 * a flag in the unlock to free ONLY locks obeying POSIX
1056 	 * semantics, and not to free BSD-style file locks.
1057 	 * If the descriptor was in a message, POSIX-style locks
1058 	 * aren't passed with the descriptor.
1059 	 */
1060 	if (p && (p->p_flag & P_ADVLOCK) && fp->f_type == DTYPE_VNODE) {
1061 		lf.l_whence = SEEK_SET;
1062 		lf.l_start = 0;
1063 		lf.l_len = 0;
1064 		lf.l_type = F_UNLCK;
1065 		vp = (struct vnode *)fp->f_data;
1066 		(void) VOP_ADVLOCK(vp, (caddr_t)p->p_leader, F_UNLCK, &lf, F_POSIX);
1067 	}
1068 	if ((fp->f_flag & FHASLOCK) && fp->f_type == DTYPE_VNODE) {
1069 		lf.l_whence = SEEK_SET;
1070 		lf.l_start = 0;
1071 		lf.l_len = 0;
1072 		lf.l_type = F_UNLCK;
1073 		vp = (struct vnode *)fp->f_data;
1074 		(void) VOP_ADVLOCK(vp, (caddr_t)fp, F_UNLCK, &lf, F_FLOCK);
1075 	}
1076 	return (fdrop(fp, p));
1077 }
1078 
1079 int
1080 fdrop(fp, p)
1081 	struct file *fp;
1082 	struct proc *p;
1083 {
1084 	int error;
1085 
1086 	if (--fp->f_count > 0)
1087 		return (0);
1088 	if (fp->f_count < 0)
1089 		panic("fdrop: count < 0");
1090 	if (fp->f_ops != &badfileops)
1091 		error = fo_close(fp, p);
1092 	else
1093 		error = 0;
1094 	ffree(fp);
1095 	return (error);
1096 }
1097 
1098 /*
1099  * Apply an advisory lock on a file descriptor.
1100  *
1101  * Just attempt to get a record lock of the requested type on
1102  * the entire file (l_whence = SEEK_SET, l_start = 0, l_len = 0).
1103  */
1104 #ifndef _SYS_SYSPROTO_H_
1105 struct flock_args {
1106 	int	fd;
1107 	int	how;
1108 };
1109 #endif
1110 /* ARGSUSED */
1111 int
1112 flock(p, uap)
1113 	struct proc *p;
1114 	register struct flock_args *uap;
1115 {
1116 	register struct filedesc *fdp = p->p_fd;
1117 	register struct file *fp;
1118 	struct vnode *vp;
1119 	struct flock lf;
1120 
1121 	if ((unsigned)uap->fd >= fdp->fd_nfiles ||
1122 	    (fp = fdp->fd_ofiles[uap->fd]) == NULL)
1123 		return (EBADF);
1124 	if (fp->f_type != DTYPE_VNODE)
1125 		return (EOPNOTSUPP);
1126 	vp = (struct vnode *)fp->f_data;
1127 	lf.l_whence = SEEK_SET;
1128 	lf.l_start = 0;
1129 	lf.l_len = 0;
1130 	if (uap->how & LOCK_UN) {
1131 		lf.l_type = F_UNLCK;
1132 		fp->f_flag &= ~FHASLOCK;
1133 		return (VOP_ADVLOCK(vp, (caddr_t)fp, F_UNLCK, &lf, F_FLOCK));
1134 	}
1135 	if (uap->how & LOCK_EX)
1136 		lf.l_type = F_WRLCK;
1137 	else if (uap->how & LOCK_SH)
1138 		lf.l_type = F_RDLCK;
1139 	else
1140 		return (EBADF);
1141 	fp->f_flag |= FHASLOCK;
1142 	if (uap->how & LOCK_NB)
1143 		return (VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, F_FLOCK));
1144 	return (VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, F_FLOCK|F_WAIT));
1145 }
1146 
1147 /*
1148  * File Descriptor pseudo-device driver (/dev/fd/).
1149  *
1150  * Opening minor device N dup()s the file (if any) connected to file
1151  * descriptor N belonging to the calling process.  Note that this driver
1152  * consists of only the ``open()'' routine, because all subsequent
1153  * references to this file will be direct to the other driver.
1154  */
1155 /* ARGSUSED */
1156 static int
1157 fdopen(dev, mode, type, p)
1158 	dev_t dev;
1159 	int mode, type;
1160 	struct proc *p;
1161 {
1162 
1163 	/*
1164 	 * XXX Kludge: set curproc->p_dupfd to contain the value of the
1165 	 * the file descriptor being sought for duplication. The error
1166 	 * return ensures that the vnode for this device will be released
1167 	 * by vn_open. Open will detect this special error and take the
1168 	 * actions in dupfdopen below. Other callers of vn_open or VOP_OPEN
1169 	 * will simply report the error.
1170 	 */
1171 	p->p_dupfd = minor(dev);
1172 	return (ENODEV);
1173 }
1174 
1175 /*
1176  * Duplicate the specified descriptor to a free descriptor.
1177  */
1178 int
1179 dupfdopen(fdp, indx, dfd, mode, error)
1180 	register struct filedesc *fdp;
1181 	register int indx, dfd;
1182 	int mode;
1183 	int error;
1184 {
1185 	register struct file *wfp;
1186 	struct file *fp;
1187 
1188 	/*
1189 	 * If the to-be-dup'd fd number is greater than the allowed number
1190 	 * of file descriptors, or the fd to be dup'd has already been
1191 	 * closed, reject.  Note, check for new == old is necessary as
1192 	 * falloc could allocate an already closed to-be-dup'd descriptor
1193 	 * as the new descriptor.
1194 	 */
1195 	fp = fdp->fd_ofiles[indx];
1196 	if ((u_int)dfd >= fdp->fd_nfiles ||
1197 	    (wfp = fdp->fd_ofiles[dfd]) == NULL || fp == wfp)
1198 		return (EBADF);
1199 
1200 	/*
1201 	 * There are two cases of interest here.
1202 	 *
1203 	 * For ENODEV simply dup (dfd) to file descriptor
1204 	 * (indx) and return.
1205 	 *
1206 	 * For ENXIO steal away the file structure from (dfd) and
1207 	 * store it in (indx).  (dfd) is effectively closed by
1208 	 * this operation.
1209 	 *
1210 	 * Any other error code is just returned.
1211 	 */
1212 	switch (error) {
1213 	case ENODEV:
1214 		/*
1215 		 * Check that the mode the file is being opened for is a
1216 		 * subset of the mode of the existing descriptor.
1217 		 */
1218 		if (((mode & (FREAD|FWRITE)) | wfp->f_flag) != wfp->f_flag)
1219 			return (EACCES);
1220 		fdp->fd_ofiles[indx] = wfp;
1221 		fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd];
1222 		fhold(wfp);
1223 		if (indx > fdp->fd_lastfile)
1224 			fdp->fd_lastfile = indx;
1225 		return (0);
1226 
1227 	case ENXIO:
1228 		/*
1229 		 * Steal away the file pointer from dfd, and stuff it into indx.
1230 		 */
1231 		fdp->fd_ofiles[indx] = fdp->fd_ofiles[dfd];
1232 		fdp->fd_ofiles[dfd] = NULL;
1233 		fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd];
1234 		fdp->fd_ofileflags[dfd] = 0;
1235 		/*
1236 		 * Complete the clean up of the filedesc structure by
1237 		 * recomputing the various hints.
1238 		 */
1239 		if (indx > fdp->fd_lastfile)
1240 			fdp->fd_lastfile = indx;
1241 		else
1242 			while (fdp->fd_lastfile > 0 &&
1243 			       fdp->fd_ofiles[fdp->fd_lastfile] == NULL)
1244 				fdp->fd_lastfile--;
1245 			if (dfd < fdp->fd_freefile)
1246 				fdp->fd_freefile = dfd;
1247 		return (0);
1248 
1249 	default:
1250 		return (error);
1251 	}
1252 	/* NOTREACHED */
1253 }
1254 
1255 /*
1256  * Get file structures.
1257  */
1258 static int
1259 sysctl_kern_file SYSCTL_HANDLER_ARGS
1260 {
1261 	int error;
1262 	struct file *fp;
1263 
1264 	if (!req->oldptr) {
1265 		/*
1266 		 * overestimate by 10 files
1267 		 */
1268 		return (SYSCTL_OUT(req, 0, sizeof(filehead) +
1269 				(nfiles + 10) * sizeof(struct file)));
1270 	}
1271 
1272 	error = SYSCTL_OUT(req, (caddr_t)&filehead, sizeof(filehead));
1273 	if (error)
1274 		return (error);
1275 
1276 	/*
1277 	 * followed by an array of file structures
1278 	 */
1279 	for (fp = filehead.lh_first; fp != NULL; fp = fp->f_list.le_next) {
1280 		error = SYSCTL_OUT(req, (caddr_t)fp, sizeof (struct file));
1281 		if (error)
1282 			return (error);
1283 	}
1284 	return (0);
1285 }
1286 
1287 SYSCTL_PROC(_kern, KERN_FILE, file, CTLTYPE_OPAQUE|CTLFLAG_RD,
1288     0, 0, sysctl_kern_file, "S,file", "Entire file table");
1289 
1290 SYSCTL_INT(_kern, KERN_MAXFILESPERPROC, maxfilesperproc, CTLFLAG_RW,
1291     &maxfilesperproc, 0, "Maximum files allowed open per process");
1292 
1293 SYSCTL_INT(_kern, KERN_MAXFILES, maxfiles, CTLFLAG_RW,
1294     &maxfiles, 0, "Maximum number of files");
1295 
1296 static void
1297 fildesc_drvinit(void *unused)
1298 {
1299 	int fd;
1300 
1301 	cdevsw_add(&fildesc_cdevsw);
1302 	for (fd = 0; fd < NUMFDESC; fd++)
1303 		make_dev(&fildesc_cdevsw, fd,
1304 		    UID_BIN, GID_BIN, 0666, "fd/%d", fd);
1305 	make_dev(&fildesc_cdevsw, 0, UID_ROOT, GID_WHEEL, 0666, "stdin");
1306 	make_dev(&fildesc_cdevsw, 1, UID_ROOT, GID_WHEEL, 0666, "stdout");
1307 	make_dev(&fildesc_cdevsw, 2, UID_ROOT, GID_WHEEL, 0666, "stderr");
1308 }
1309 
1310 struct fileops badfileops = {
1311 	badfo_readwrite,
1312 	badfo_readwrite,
1313 	badfo_ioctl,
1314 	badfo_poll,
1315 	badfo_close
1316 };
1317 
1318 static int
1319 badfo_readwrite(fp, uio, cred, flags, p)
1320 	struct file *fp;
1321 	struct uio *uio;
1322 	struct ucred *cred;
1323 	struct proc *p;
1324 	int flags;
1325 {
1326 
1327 	return (EBADF);
1328 }
1329 
1330 static int
1331 badfo_ioctl(fp, com, data, p)
1332 	struct file *fp;
1333 	u_long com;
1334 	caddr_t data;
1335 	struct proc *p;
1336 {
1337 
1338 	return (EBADF);
1339 }
1340 
1341 static int
1342 badfo_poll(fp, events, cred, p)
1343 	struct file *fp;
1344 	int events;
1345 	struct ucred *cred;
1346 	struct proc *p;
1347 {
1348 
1349 	return (0);
1350 }
1351 
1352 static int
1353 badfo_close(fp, p)
1354 	struct file *fp;
1355 	struct proc *p;
1356 {
1357 
1358 	return (EBADF);
1359 }
1360 
1361 SYSINIT(fildescdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,
1362 					fildesc_drvinit,NULL)
1363 
1364 
1365