Initial import from FreeBSD RELENG_4:
[dragonfly.git] / sys / kern / kern_descrip.c
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: src/sys/kern/kern_descrip.c,v 1.81.2.17 2003/06/06 20:21:32 tegge Exp $
40  */
41
42 #include "opt_compat.h"
43 #include <sys/param.h>
44 #include <sys/systm.h>
45 #include <sys/malloc.h>
46 #include <sys/sysproto.h>
47 #include <sys/conf.h>
48 #include <sys/filedesc.h>
49 #include <sys/kernel.h>
50 #include <sys/sysctl.h>
51 #include <sys/vnode.h>
52 #include <sys/proc.h>
53 #include <sys/namei.h>
54 #include <sys/file.h>
55 #include <sys/stat.h>
56 #include <sys/filio.h>
57 #include <sys/fcntl.h>
58 #include <sys/unistd.h>
59 #include <sys/resourcevar.h>
60 #include <sys/event.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 static MALLOC_DEFINE(M_FILEDESC_TO_LEADER, "file desc to leader",
67                      "file desc to leader structures");
68 MALLOC_DEFINE(M_FILE, "file", "Open file structure");
69 static MALLOC_DEFINE(M_SIGIO, "sigio", "sigio structures");
70
71 static   d_open_t  fdopen;
72 #define NUMFDESC 64
73
74 #define CDEV_MAJOR 22
75 static struct cdevsw fildesc_cdevsw = {
76         /* open */      fdopen,
77         /* close */     noclose,
78         /* read */      noread,
79         /* write */     nowrite,
80         /* ioctl */     noioctl,
81         /* poll */      nopoll,
82         /* mmap */      nommap,
83         /* strategy */  nostrategy,
84         /* name */      "FD",
85         /* maj */       CDEV_MAJOR,
86         /* dump */      nodump,
87         /* psize */     nopsize,
88         /* flags */     0,
89         /* bmaj */      -1
90 };
91
92 static int do_dup __P((struct filedesc *fdp, int old, int new, register_t *retval, struct proc *p));
93 static int badfo_readwrite __P((struct file *fp, struct uio *uio,
94     struct ucred *cred, int flags, struct proc *p));
95 static int badfo_ioctl __P((struct file *fp, u_long com, caddr_t data,
96     struct proc *p));
97 static int badfo_poll __P((struct file *fp, int events,
98     struct ucred *cred, struct proc *p));
99 static int badfo_kqfilter __P((struct file *fp, struct knote *kn));
100 static int badfo_stat __P((struct file *fp, struct stat *sb, struct proc *p));
101 static int badfo_close __P((struct file *fp, struct proc *p));
102
103 /*
104  * Descriptor management.
105  */
106 struct filelist filehead;       /* head of list of open files */
107 int nfiles;                     /* actual number of open files */
108 extern int cmask;       
109
110 /*
111  * System calls on descriptors.
112  */
113 #ifndef _SYS_SYSPROTO_H_
114 struct getdtablesize_args {
115         int     dummy;
116 };
117 #endif
118 /* ARGSUSED */
119 int
120 getdtablesize(p, uap)
121         struct proc *p;
122         struct getdtablesize_args *uap;
123 {
124
125         p->p_retval[0] = 
126             min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfilesperproc);
127         return (0);
128 }
129
130 /*
131  * Duplicate a file descriptor to a particular value.
132  *
133  * note: keep in mind that a potential race condition exists when closing
134  * descriptors from a shared descriptor table (via rfork).
135  */
136 #ifndef _SYS_SYSPROTO_H_
137 struct dup2_args {
138         u_int   from;
139         u_int   to;
140 };
141 #endif
142 /* ARGSUSED */
143 int
144 dup2(p, uap)
145         struct proc *p;
146         struct dup2_args *uap;
147 {
148         register struct filedesc *fdp = p->p_fd;
149         register u_int old = uap->from, new = uap->to;
150         int i, error;
151
152 retry:
153         if (old >= fdp->fd_nfiles ||
154             fdp->fd_ofiles[old] == NULL ||
155             new >= p->p_rlimit[RLIMIT_NOFILE].rlim_cur ||
156             new >= maxfilesperproc) {
157                 return (EBADF);
158         }
159         if (old == new) {
160                 p->p_retval[0] = new;
161                 return (0);
162         }
163         if (new >= fdp->fd_nfiles) {
164                 if ((error = fdalloc(p, new, &i)))
165                         return (error);
166                 /*
167                  * fdalloc() may block, retest everything.
168                  */
169                 goto retry;
170         }
171         return (do_dup(fdp, (int)old, (int)new, p->p_retval, p));
172 }
173
174 /*
175  * Duplicate a file descriptor.
176  */
177 #ifndef _SYS_SYSPROTO_H_
178 struct dup_args {
179         u_int   fd;
180 };
181 #endif
182 /* ARGSUSED */
183 int
184 dup(p, uap)
185         struct proc *p;
186         struct dup_args *uap;
187 {
188         register struct filedesc *fdp;
189         u_int old;
190         int new, error;
191
192         old = uap->fd;
193         fdp = p->p_fd;
194         if (old >= fdp->fd_nfiles || fdp->fd_ofiles[old] == NULL)
195                 return (EBADF);
196         if ((error = fdalloc(p, 0, &new)))
197                 return (error);
198         return (do_dup(fdp, (int)old, new, p->p_retval, p));
199 }
200
201 /*
202  * The file control system call.
203  */
204 #ifndef _SYS_SYSPROTO_H_
205 struct fcntl_args {
206         int     fd;
207         int     cmd;
208         long    arg;
209 };
210 #endif
211 /* ARGSUSED */
212 int
213 fcntl(p, uap)
214         struct proc *p;
215         register struct fcntl_args *uap;
216 {
217         register struct filedesc *fdp = p->p_fd;
218         register struct file *fp;
219         register char *pop;
220         struct vnode *vp;
221         int i, tmp, error, flg = F_POSIX;
222         struct flock fl;
223         u_int newmin;
224
225         if ((unsigned)uap->fd >= fdp->fd_nfiles ||
226             (fp = fdp->fd_ofiles[uap->fd]) == NULL)
227                 return (EBADF);
228         pop = &fdp->fd_ofileflags[uap->fd];
229
230         switch (uap->cmd) {
231         case F_DUPFD:
232                 newmin = uap->arg;
233                 if (newmin >= p->p_rlimit[RLIMIT_NOFILE].rlim_cur ||
234                     newmin >= maxfilesperproc)
235                         return (EINVAL);
236                 if ((error = fdalloc(p, newmin, &i)))
237                         return (error);
238                 return (do_dup(fdp, uap->fd, i, p->p_retval, p));
239
240         case F_GETFD:
241                 p->p_retval[0] = (*pop & UF_EXCLOSE) ? FD_CLOEXEC : 0;
242                 return (0);
243
244         case F_SETFD:
245                 *pop = (*pop &~ UF_EXCLOSE) |
246                     (uap->arg & FD_CLOEXEC ? UF_EXCLOSE : 0);
247                 return (0);
248
249         case F_GETFL:
250                 p->p_retval[0] = OFLAGS(fp->f_flag);
251                 return (0);
252
253         case F_SETFL:
254                 fhold(fp);
255                 fp->f_flag &= ~FCNTLFLAGS;
256                 fp->f_flag |= FFLAGS(uap->arg & ~O_ACCMODE) & FCNTLFLAGS;
257                 tmp = fp->f_flag & FNONBLOCK;
258                 error = fo_ioctl(fp, FIONBIO, (caddr_t)&tmp, p);
259                 if (error) {
260                         fdrop(fp, p);
261                         return (error);
262                 }
263                 tmp = fp->f_flag & FASYNC;
264                 error = fo_ioctl(fp, FIOASYNC, (caddr_t)&tmp, p);
265                 if (!error) {
266                         fdrop(fp, p);
267                         return (0);
268                 }
269                 fp->f_flag &= ~FNONBLOCK;
270                 tmp = 0;
271                 (void)fo_ioctl(fp, FIONBIO, (caddr_t)&tmp, p);
272                 fdrop(fp, p);
273                 return (error);
274
275         case F_GETOWN:
276                 fhold(fp);
277                 error = fo_ioctl(fp, FIOGETOWN, (caddr_t)p->p_retval, p);
278                 fdrop(fp, p);
279                 return(error);
280
281         case F_SETOWN:
282                 fhold(fp);
283                 error = fo_ioctl(fp, FIOSETOWN, (caddr_t)&uap->arg, p);
284                 fdrop(fp, p);
285                 return(error);
286
287         case F_SETLKW:
288                 flg |= F_WAIT;
289                 /* Fall into F_SETLK */
290
291         case F_SETLK:
292                 if (fp->f_type != DTYPE_VNODE)
293                         return (EBADF);
294                 vp = (struct vnode *)fp->f_data;
295
296                 /*
297                  * copyin/lockop may block
298                  */
299                 fhold(fp);
300                 /* Copy in the lock structure */
301                 error = copyin((caddr_t)(intptr_t)uap->arg, (caddr_t)&fl,
302                     sizeof(fl));
303                 if (error) {
304                         fdrop(fp, p);
305                         return (error);
306                 }
307                 if (fl.l_whence == SEEK_CUR)
308                         fl.l_start += fp->f_offset;
309
310                 switch (fl.l_type) {
311                 case F_RDLCK:
312                         if ((fp->f_flag & FREAD) == 0) {
313                                 error = EBADF;
314                                 break;
315                         }
316                         p->p_leader->p_flag |= P_ADVLOCK;
317                         error = VOP_ADVLOCK(vp, (caddr_t)p->p_leader, F_SETLK,
318                             &fl, flg);
319                         break;
320                 case F_WRLCK:
321                         if ((fp->f_flag & FWRITE) == 0) {
322                                 error = EBADF;
323                                 break;
324                         }
325                         p->p_leader->p_flag |= P_ADVLOCK;
326                         error = VOP_ADVLOCK(vp, (caddr_t)p->p_leader, F_SETLK,
327                             &fl, flg);
328                         break;
329                 case F_UNLCK:
330                         error = VOP_ADVLOCK(vp, (caddr_t)p->p_leader, F_UNLCK,
331                                 &fl, F_POSIX);
332                         break;
333                 default:
334                         error = EINVAL;
335                         break;
336                 }
337                 /* Check for race with close */
338                 if ((unsigned) uap->fd >= fdp->fd_nfiles ||
339                     fp != fdp->fd_ofiles[uap->fd]) {
340                         fl.l_whence = SEEK_SET;
341                         fl.l_start = 0;
342                         fl.l_len = 0;
343                         fl.l_type = F_UNLCK;
344                         (void) VOP_ADVLOCK(vp, (caddr_t)p->p_leader,
345                                            F_UNLCK, &fl, F_POSIX);
346                 }
347                 fdrop(fp, p);
348                 return(error);
349
350         case F_GETLK:
351                 if (fp->f_type != DTYPE_VNODE)
352                         return (EBADF);
353                 vp = (struct vnode *)fp->f_data;
354                 /*
355                  * copyin/lockop may block
356                  */
357                 fhold(fp);
358                 /* Copy in the lock structure */
359                 error = copyin((caddr_t)(intptr_t)uap->arg, (caddr_t)&fl,
360                     sizeof(fl));
361                 if (error) {
362                         fdrop(fp, p);
363                         return (error);
364                 }
365                 if (fl.l_type != F_RDLCK && fl.l_type != F_WRLCK &&
366                     fl.l_type != F_UNLCK) {
367                         fdrop(fp, p);
368                         return (EINVAL);
369                 }
370                 if (fl.l_whence == SEEK_CUR)
371                         fl.l_start += fp->f_offset;
372                 error = VOP_ADVLOCK(vp, (caddr_t)p->p_leader, F_GETLK,
373                             &fl, F_POSIX);
374                 fdrop(fp, p);
375                 if (error == 0) {
376                         error = copyout((caddr_t)&fl,
377                                     (caddr_t)(intptr_t)uap->arg, sizeof(fl));
378                 }
379                 return(error);
380         default:
381                 return (EINVAL);
382         }
383         /* NOTREACHED */
384 }
385
386 /*
387  * Common code for dup, dup2, and fcntl(F_DUPFD).
388  */
389 static int
390 do_dup(fdp, old, new, retval, p)
391         register struct filedesc *fdp;
392         register int old, new;
393         register_t *retval;
394         struct proc *p;
395 {
396         struct file *fp;
397         struct file *delfp;
398         int holdleaders;
399
400         /*
401          * Save info on the descriptor being overwritten.  We have
402          * to do the unmap now, but we cannot close it without
403          * introducing an ownership race for the slot.
404          */
405         delfp = fdp->fd_ofiles[new];
406         if (delfp != NULL && p->p_fdtol != NULL) {
407                 /*
408                  * Ask fdfree() to sleep to ensure that all relevant
409                  * process leaders can be traversed in closef().
410                  */
411                 fdp->fd_holdleaderscount++;
412                 holdleaders = 1;
413         } else
414                 holdleaders = 0;
415 #if 0
416         if (delfp && (fdp->fd_ofileflags[new] & UF_MAPPED))
417                 (void) munmapfd(p, new);
418 #endif
419
420         /*
421          * Duplicate the source descriptor, update lastfile
422          */
423         fp = fdp->fd_ofiles[old];
424         fdp->fd_ofiles[new] = fp;
425         fdp->fd_ofileflags[new] = fdp->fd_ofileflags[old] &~ UF_EXCLOSE;
426         fhold(fp);
427         if (new > fdp->fd_lastfile)
428                 fdp->fd_lastfile = new;
429         *retval = new;
430
431         /*
432          * If we dup'd over a valid file, we now own the reference to it
433          * and must dispose of it using closef() semantics (as if a
434          * close() were performed on it).
435          */
436         if (delfp) {
437                 (void) closef(delfp, p);
438                 if (holdleaders) {
439                         fdp->fd_holdleaderscount--;
440                         if (fdp->fd_holdleaderscount == 0 &&
441                             fdp->fd_holdleaderswakeup != 0) {
442                                 fdp->fd_holdleaderswakeup = 0;
443                                 wakeup(&fdp->fd_holdleaderscount);
444                         }
445                 }
446         }
447         return (0);
448 }
449
450 /*
451  * If sigio is on the list associated with a process or process group,
452  * disable signalling from the device, remove sigio from the list and
453  * free sigio.
454  */
455 void
456 funsetown(sigio)
457         struct sigio *sigio;
458 {
459         int s;
460
461         if (sigio == NULL)
462                 return;
463         s = splhigh();
464         *(sigio->sio_myref) = NULL;
465         splx(s);
466         if (sigio->sio_pgid < 0) {
467                 SLIST_REMOVE(&sigio->sio_pgrp->pg_sigiolst, sigio,
468                              sigio, sio_pgsigio);
469         } else /* if ((*sigiop)->sio_pgid > 0) */ {
470                 SLIST_REMOVE(&sigio->sio_proc->p_sigiolst, sigio,
471                              sigio, sio_pgsigio);
472         }
473         crfree(sigio->sio_ucred);
474         FREE(sigio, M_SIGIO);
475 }
476
477 /* Free a list of sigio structures. */
478 void
479 funsetownlst(sigiolst)
480         struct sigiolst *sigiolst;
481 {
482         struct sigio *sigio;
483
484         while ((sigio = SLIST_FIRST(sigiolst)) != NULL)
485                 funsetown(sigio);
486 }
487
488 /*
489  * This is common code for FIOSETOWN ioctl called by fcntl(fd, F_SETOWN, arg).
490  *
491  * After permission checking, add a sigio structure to the sigio list for
492  * the process or process group.
493  */
494 int
495 fsetown(pgid, sigiop)
496         pid_t pgid;
497         struct sigio **sigiop;
498 {
499         struct proc *proc;
500         struct pgrp *pgrp;
501         struct sigio *sigio;
502         int s;
503
504         if (pgid == 0) {
505                 funsetown(*sigiop);
506                 return (0);
507         }
508         if (pgid > 0) {
509                 proc = pfind(pgid);
510                 if (proc == NULL)
511                         return (ESRCH);
512
513                 /*
514                  * Policy - Don't allow a process to FSETOWN a process
515                  * in another session.
516                  *
517                  * Remove this test to allow maximum flexibility or
518                  * restrict FSETOWN to the current process or process
519                  * group for maximum safety.
520                  */
521                 if (proc->p_session != curproc->p_session)
522                         return (EPERM);
523
524                 pgrp = NULL;
525         } else /* if (pgid < 0) */ {
526                 pgrp = pgfind(-pgid);
527                 if (pgrp == NULL)
528                         return (ESRCH);
529
530                 /*
531                  * Policy - Don't allow a process to FSETOWN a process
532                  * in another session.
533                  *
534                  * Remove this test to allow maximum flexibility or
535                  * restrict FSETOWN to the current process or process
536                  * group for maximum safety.
537                  */
538                 if (pgrp->pg_session != curproc->p_session)
539                         return (EPERM);
540
541                 proc = NULL;
542         }
543         funsetown(*sigiop);
544         MALLOC(sigio, struct sigio *, sizeof(struct sigio), M_SIGIO, M_WAITOK);
545         if (pgid > 0) {
546                 SLIST_INSERT_HEAD(&proc->p_sigiolst, sigio, sio_pgsigio);
547                 sigio->sio_proc = proc;
548         } else {
549                 SLIST_INSERT_HEAD(&pgrp->pg_sigiolst, sigio, sio_pgsigio);
550                 sigio->sio_pgrp = pgrp;
551         }
552         sigio->sio_pgid = pgid;
553         crhold(curproc->p_ucred);
554         sigio->sio_ucred = curproc->p_ucred;
555         /* It would be convenient if p_ruid was in ucred. */
556         sigio->sio_ruid = curproc->p_cred->p_ruid;
557         sigio->sio_myref = sigiop;
558         s = splhigh();
559         *sigiop = sigio;
560         splx(s);
561         return (0);
562 }
563
564 /*
565  * This is common code for FIOGETOWN ioctl called by fcntl(fd, F_GETOWN, arg).
566  */
567 pid_t
568 fgetown(sigio)
569         struct sigio *sigio;
570 {
571         return (sigio != NULL ? sigio->sio_pgid : 0);
572 }
573
574 /*
575  * Close a file descriptor.
576  */
577 #ifndef _SYS_SYSPROTO_H_
578 struct close_args {
579         int     fd;
580 };
581 #endif
582 /* ARGSUSED */
583 int
584 close(p, uap)
585         struct proc *p;
586         struct close_args *uap;
587 {
588         register struct filedesc *fdp = p->p_fd;
589         register struct file *fp;
590         register int fd = uap->fd;
591         int error;
592         int holdleaders;
593
594         if ((unsigned)fd >= fdp->fd_nfiles ||
595             (fp = fdp->fd_ofiles[fd]) == NULL)
596                 return (EBADF);
597 #if 0
598         if (fdp->fd_ofileflags[fd] & UF_MAPPED)
599                 (void) munmapfd(p, fd);
600 #endif
601         fdp->fd_ofiles[fd] = NULL;
602         fdp->fd_ofileflags[fd] = 0;
603         holdleaders = 0;
604         if (p->p_fdtol != NULL) {
605                 /*
606                  * Ask fdfree() to sleep to ensure that all relevant
607                  * process leaders can be traversed in closef().
608                  */
609                 fdp->fd_holdleaderscount++;
610                 holdleaders = 1;
611         }
612
613         /*
614          * we now hold the fp reference that used to be owned by the descriptor
615          * array.
616          */
617         while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL)
618                 fdp->fd_lastfile--;
619         if (fd < fdp->fd_freefile)
620                 fdp->fd_freefile = fd;
621         if (fd < fdp->fd_knlistsize)
622                 knote_fdclose(p, fd);
623         error = closef(fp, p);
624         if (holdleaders) {
625                 fdp->fd_holdleaderscount--;
626                 if (fdp->fd_holdleaderscount == 0 &&
627                     fdp->fd_holdleaderswakeup != 0) {
628                         fdp->fd_holdleaderswakeup = 0;
629                         wakeup(&fdp->fd_holdleaderscount);
630                 }
631         }
632         return (error);
633 }
634
635 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
636 /*
637  * Return status information about a file descriptor.
638  */
639 #ifndef _SYS_SYSPROTO_H_
640 struct ofstat_args {
641         int     fd;
642         struct  ostat *sb;
643 };
644 #endif
645 /* ARGSUSED */
646 int
647 ofstat(p, uap)
648         struct proc *p;
649         register struct ofstat_args *uap;
650 {
651         register struct filedesc *fdp = p->p_fd;
652         register struct file *fp;
653         struct stat ub;
654         struct ostat oub;
655         int error;
656
657         if ((unsigned)uap->fd >= fdp->fd_nfiles ||
658             (fp = fdp->fd_ofiles[uap->fd]) == NULL)
659                 return (EBADF);
660         fhold(fp);
661         error = fo_stat(fp, &ub, p);
662         if (error == 0) {
663                 cvtstat(&ub, &oub);
664                 error = copyout((caddr_t)&oub, (caddr_t)uap->sb, sizeof (oub));
665         }
666         fdrop(fp, p);
667         return (error);
668 }
669 #endif /* COMPAT_43 || COMPAT_SUNOS */
670
671 /*
672  * Return status information about a file descriptor.
673  */
674 #ifndef _SYS_SYSPROTO_H_
675 struct fstat_args {
676         int     fd;
677         struct  stat *sb;
678 };
679 #endif
680 /* ARGSUSED */
681 int
682 fstat(p, uap)
683         struct proc *p;
684         register struct fstat_args *uap;
685 {
686         register struct filedesc *fdp = p->p_fd;
687         register struct file *fp;
688         struct stat ub;
689         int error;
690
691         if ((unsigned)uap->fd >= fdp->fd_nfiles ||
692             (fp = fdp->fd_ofiles[uap->fd]) == NULL)
693                 return (EBADF);
694         fhold(fp);
695         error = fo_stat(fp, &ub, p);
696         if (error == 0)
697                 error = copyout((caddr_t)&ub, (caddr_t)uap->sb, sizeof (ub));
698         fdrop(fp, p);
699         return (error);
700 }
701
702 /*
703  * Return status information about a file descriptor.
704  */
705 #ifndef _SYS_SYSPROTO_H_
706 struct nfstat_args {
707         int     fd;
708         struct  nstat *sb;
709 };
710 #endif
711 /* ARGSUSED */
712 int
713 nfstat(p, uap)
714         struct proc *p;
715         register struct nfstat_args *uap;
716 {
717         register struct filedesc *fdp = p->p_fd;
718         register struct file *fp;
719         struct stat ub;
720         struct nstat nub;
721         int error;
722
723         if ((unsigned)uap->fd >= fdp->fd_nfiles ||
724             (fp = fdp->fd_ofiles[uap->fd]) == NULL)
725                 return (EBADF);
726         fhold(fp);
727         error = fo_stat(fp, &ub, p);
728         if (error == 0) {
729                 cvtnstat(&ub, &nub);
730                 error = copyout((caddr_t)&nub, (caddr_t)uap->sb, sizeof (nub));
731         }
732         fdrop(fp, p);
733         return (error);
734 }
735
736 /*
737  * Return pathconf information about a file descriptor.
738  */
739 #ifndef _SYS_SYSPROTO_H_
740 struct fpathconf_args {
741         int     fd;
742         int     name;
743 };
744 #endif
745 /* ARGSUSED */
746 int
747 fpathconf(p, uap)
748         struct proc *p;
749         register struct fpathconf_args *uap;
750 {
751         struct filedesc *fdp = p->p_fd;
752         struct file *fp;
753         struct vnode *vp;
754         int error = 0;
755
756         if ((unsigned)uap->fd >= fdp->fd_nfiles ||
757             (fp = fdp->fd_ofiles[uap->fd]) == NULL)
758                 return (EBADF);
759
760         fhold(fp);
761
762         switch (fp->f_type) {
763         case DTYPE_PIPE:
764         case DTYPE_SOCKET:
765                 if (uap->name != _PC_PIPE_BUF) {
766                         error = EINVAL;
767                 } else {
768                         p->p_retval[0] = PIPE_BUF;
769                         error = 0;
770                 }
771                 break;
772         case DTYPE_FIFO:
773         case DTYPE_VNODE:
774                 vp = (struct vnode *)fp->f_data;
775                 error = VOP_PATHCONF(vp, uap->name, p->p_retval);
776                 break;
777         default:
778                 error = EOPNOTSUPP;
779                 break;
780         }
781         fdrop(fp, p);
782         return(error);
783 }
784
785 /*
786  * Allocate a file descriptor for the process.
787  */
788 static int fdexpand;
789 SYSCTL_INT(_debug, OID_AUTO, fdexpand, CTLFLAG_RD, &fdexpand, 0, "");
790
791 int
792 fdalloc(p, want, result)
793         struct proc *p;
794         int want;
795         int *result;
796 {
797         register struct filedesc *fdp = p->p_fd;
798         register int i;
799         int lim, last, nfiles;
800         struct file **newofile;
801         char *newofileflags;
802
803         /*
804          * Search for a free descriptor starting at the higher
805          * of want or fd_freefile.  If that fails, consider
806          * expanding the ofile array.
807          */
808         lim = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfilesperproc);
809         for (;;) {
810                 last = min(fdp->fd_nfiles, lim);
811                 if ((i = want) < fdp->fd_freefile)
812                         i = fdp->fd_freefile;
813                 for (; i < last; i++) {
814                         if (fdp->fd_ofiles[i] == NULL) {
815                                 fdp->fd_ofileflags[i] = 0;
816                                 if (i > fdp->fd_lastfile)
817                                         fdp->fd_lastfile = i;
818                                 if (want <= fdp->fd_freefile)
819                                         fdp->fd_freefile = i;
820                                 *result = i;
821                                 return (0);
822                         }
823                 }
824
825                 /*
826                  * No space in current array.  Expand?
827                  */
828                 if (fdp->fd_nfiles >= lim)
829                         return (EMFILE);
830                 if (fdp->fd_nfiles < NDEXTENT)
831                         nfiles = NDEXTENT;
832                 else
833                         nfiles = 2 * fdp->fd_nfiles;
834                 MALLOC(newofile, struct file **, nfiles * OFILESIZE,
835                     M_FILEDESC, M_WAITOK);
836
837                 /*
838                  * deal with file-table extend race that might have occured
839                  * when malloc was blocked.
840                  */
841                 if (fdp->fd_nfiles >= nfiles) {
842                         FREE(newofile, M_FILEDESC);
843                         continue;
844                 }
845                 newofileflags = (char *) &newofile[nfiles];
846                 /*
847                  * Copy the existing ofile and ofileflags arrays
848                  * and zero the new portion of each array.
849                  */
850                 bcopy(fdp->fd_ofiles, newofile,
851                         (i = sizeof(struct file *) * fdp->fd_nfiles));
852                 bzero((char *)newofile + i, nfiles * sizeof(struct file *) - i);
853                 bcopy(fdp->fd_ofileflags, newofileflags,
854                         (i = sizeof(char) * fdp->fd_nfiles));
855                 bzero(newofileflags + i, nfiles * sizeof(char) - i);
856                 if (fdp->fd_nfiles > NDFILE)
857                         FREE(fdp->fd_ofiles, M_FILEDESC);
858                 fdp->fd_ofiles = newofile;
859                 fdp->fd_ofileflags = newofileflags;
860                 fdp->fd_nfiles = nfiles;
861                 fdexpand++;
862         }
863         return (0);
864 }
865
866 /*
867  * Check to see whether n user file descriptors
868  * are available to the process p.
869  */
870 int
871 fdavail(p, n)
872         struct proc *p;
873         register int n;
874 {
875         register struct filedesc *fdp = p->p_fd;
876         register struct file **fpp;
877         register int i, lim, last;
878
879         lim = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfilesperproc);
880         if ((i = lim - fdp->fd_nfiles) > 0 && (n -= i) <= 0)
881                 return (1);
882
883         last = min(fdp->fd_nfiles, lim);
884         fpp = &fdp->fd_ofiles[fdp->fd_freefile];
885         for (i = last - fdp->fd_freefile; --i >= 0; fpp++) {
886                 if (*fpp == NULL && --n <= 0)
887                         return (1);
888         }
889         return (0);
890 }
891
892 /*
893  * Create a new open file structure and allocate
894  * a file decriptor for the process that refers to it.
895  */
896 int
897 falloc(p, resultfp, resultfd)
898         register struct proc *p;
899         struct file **resultfp;
900         int *resultfd;
901 {
902         register struct file *fp, *fq;
903         int error, i;
904
905         if (nfiles >= maxfiles) {
906                 tablefull("file");
907                 return (ENFILE);
908         }
909         /*
910          * Allocate a new file descriptor.
911          * If the process has file descriptor zero open, add to the list
912          * of open files at that point, otherwise put it at the front of
913          * the list of open files.
914          */
915         nfiles++;
916         MALLOC(fp, struct file *, sizeof(struct file), M_FILE, M_WAITOK);
917         bzero(fp, sizeof(struct file));
918
919         /*
920          * wait until after malloc (which may have blocked) returns before
921          * allocating the slot, else a race might have shrunk it if we had
922          * allocated it before the malloc.
923          */
924         if ((error = fdalloc(p, 0, &i))) {
925                 nfiles--;
926                 FREE(fp, M_FILE);
927                 return (error);
928         }
929         fp->f_count = 1;
930         fp->f_cred = p->p_ucred;
931         fp->f_ops = &badfileops;
932         fp->f_seqcount = 1;
933         crhold(fp->f_cred);
934         if ((fq = p->p_fd->fd_ofiles[0])) {
935                 LIST_INSERT_AFTER(fq, fp, f_list);
936         } else {
937                 LIST_INSERT_HEAD(&filehead, fp, f_list);
938         }
939         p->p_fd->fd_ofiles[i] = fp;
940         if (resultfp)
941                 *resultfp = fp;
942         if (resultfd)
943                 *resultfd = i;
944         return (0);
945 }
946
947 /*
948  * Free a file descriptor.
949  */
950 void
951 ffree(fp)
952         register struct file *fp;
953 {
954         KASSERT((fp->f_count == 0), ("ffree: fp_fcount not 0!"));
955         LIST_REMOVE(fp, f_list);
956         crfree(fp->f_cred);
957         nfiles--;
958         FREE(fp, M_FILE);
959 }
960
961 /*
962  * Build a new filedesc structure.
963  */
964 struct filedesc *
965 fdinit(p)
966         struct proc *p;
967 {
968         register struct filedesc0 *newfdp;
969         register struct filedesc *fdp = p->p_fd;
970
971         MALLOC(newfdp, struct filedesc0 *, sizeof(struct filedesc0),
972             M_FILEDESC, M_WAITOK);
973         bzero(newfdp, sizeof(struct filedesc0));
974         newfdp->fd_fd.fd_cdir = fdp->fd_cdir;
975         if (newfdp->fd_fd.fd_cdir)
976                 VREF(newfdp->fd_fd.fd_cdir);
977         newfdp->fd_fd.fd_rdir = fdp->fd_rdir;
978         if (newfdp->fd_fd.fd_rdir)
979                 VREF(newfdp->fd_fd.fd_rdir);
980         newfdp->fd_fd.fd_jdir = fdp->fd_jdir;
981         if (newfdp->fd_fd.fd_jdir)
982                 VREF(newfdp->fd_fd.fd_jdir);
983
984         /* Create the file descriptor table. */
985         newfdp->fd_fd.fd_refcnt = 1;
986         newfdp->fd_fd.fd_cmask = cmask;
987         newfdp->fd_fd.fd_ofiles = newfdp->fd_dfiles;
988         newfdp->fd_fd.fd_ofileflags = newfdp->fd_dfileflags;
989         newfdp->fd_fd.fd_nfiles = NDFILE;
990         newfdp->fd_fd.fd_knlistsize = -1;
991
992         return (&newfdp->fd_fd);
993 }
994
995 /*
996  * Share a filedesc structure.
997  */
998 struct filedesc *
999 fdshare(p)
1000         struct proc *p;
1001 {
1002         p->p_fd->fd_refcnt++;
1003         return (p->p_fd);
1004 }
1005
1006 /*
1007  * Copy a filedesc structure.
1008  */
1009 struct filedesc *
1010 fdcopy(p)
1011         struct proc *p;
1012 {
1013         register struct filedesc *newfdp, *fdp = p->p_fd;
1014         register struct file **fpp;
1015         register int i;
1016
1017         /* Certain daemons might not have file descriptors. */
1018         if (fdp == NULL)
1019                 return (NULL);
1020
1021         MALLOC(newfdp, struct filedesc *, sizeof(struct filedesc0),
1022             M_FILEDESC, M_WAITOK);
1023         bcopy(fdp, newfdp, sizeof(struct filedesc));
1024         if (newfdp->fd_cdir)
1025                 VREF(newfdp->fd_cdir);
1026         if (newfdp->fd_rdir)
1027                 VREF(newfdp->fd_rdir);
1028         if (newfdp->fd_jdir)
1029                 VREF(newfdp->fd_jdir);
1030         newfdp->fd_refcnt = 1;
1031
1032         /*
1033          * If the number of open files fits in the internal arrays
1034          * of the open file structure, use them, otherwise allocate
1035          * additional memory for the number of descriptors currently
1036          * in use.
1037          */
1038         if (newfdp->fd_lastfile < NDFILE) {
1039                 newfdp->fd_ofiles = ((struct filedesc0 *) newfdp)->fd_dfiles;
1040                 newfdp->fd_ofileflags =
1041                     ((struct filedesc0 *) newfdp)->fd_dfileflags;
1042                 i = NDFILE;
1043         } else {
1044                 /*
1045                  * Compute the smallest multiple of NDEXTENT needed
1046                  * for the file descriptors currently in use,
1047                  * allowing the table to shrink.
1048                  */
1049                 i = newfdp->fd_nfiles;
1050                 while (i > 2 * NDEXTENT && i > newfdp->fd_lastfile * 2)
1051                         i /= 2;
1052                 MALLOC(newfdp->fd_ofiles, struct file **, i * OFILESIZE,
1053                     M_FILEDESC, M_WAITOK);
1054                 newfdp->fd_ofileflags = (char *) &newfdp->fd_ofiles[i];
1055         }
1056         newfdp->fd_nfiles = i;
1057         bcopy(fdp->fd_ofiles, newfdp->fd_ofiles, i * sizeof(struct file **));
1058         bcopy(fdp->fd_ofileflags, newfdp->fd_ofileflags, i * sizeof(char));
1059
1060         /*
1061          * kq descriptors cannot be copied.
1062          */
1063         if (newfdp->fd_knlistsize != -1) {
1064                 fpp = &newfdp->fd_ofiles[newfdp->fd_lastfile];
1065                 for (i = newfdp->fd_lastfile; i >= 0; i--, fpp--) {
1066                         if (*fpp != NULL && (*fpp)->f_type == DTYPE_KQUEUE) {
1067                                 *fpp = NULL;
1068                                 if (i < newfdp->fd_freefile)
1069                                         newfdp->fd_freefile = i;
1070                         }
1071                         if (*fpp == NULL && i == newfdp->fd_lastfile && i > 0)
1072                                 newfdp->fd_lastfile--;
1073                 }
1074                 newfdp->fd_knlist = NULL;
1075                 newfdp->fd_knlistsize = -1;
1076                 newfdp->fd_knhash = NULL;
1077                 newfdp->fd_knhashmask = 0;
1078         }
1079
1080         fpp = newfdp->fd_ofiles;
1081         for (i = newfdp->fd_lastfile; i-- >= 0; fpp++) {
1082                 if (*fpp != NULL)
1083                         fhold(*fpp);
1084         }
1085         return (newfdp);
1086 }
1087
1088 /*
1089  * Release a filedesc structure.
1090  */
1091 void
1092 fdfree(p)
1093         struct proc *p;
1094 {
1095         register struct filedesc *fdp = p->p_fd;
1096         struct file **fpp;
1097         register int i;
1098         struct filedesc_to_leader *fdtol;
1099         struct file *fp;
1100         struct vnode *vp;
1101         struct flock lf;
1102
1103         /* Certain daemons might not have file descriptors. */
1104         if (fdp == NULL)
1105                 return;
1106
1107         /* Check for special need to clear POSIX style locks */
1108         fdtol = p->p_fdtol;
1109         if (fdtol != NULL) {
1110                 KASSERT(fdtol->fdl_refcount > 0,
1111                         ("filedesc_to_refcount botch: fdl_refcount=%d",
1112                          fdtol->fdl_refcount));
1113                 if (fdtol->fdl_refcount == 1 &&
1114                     (p->p_leader->p_flag & P_ADVLOCK) != 0) {
1115                         i = 0;
1116                         fpp = fdp->fd_ofiles;
1117                         for (i = 0, fpp = fdp->fd_ofiles;
1118                              i < fdp->fd_lastfile;
1119                              i++, fpp++) {
1120                                 if (*fpp == NULL ||
1121                                     (*fpp)->f_type != DTYPE_VNODE)
1122                                         continue;
1123                                 fp = *fpp;
1124                                 fhold(fp);
1125                                 lf.l_whence = SEEK_SET;
1126                                 lf.l_start = 0;
1127                                 lf.l_len = 0;
1128                                 lf.l_type = F_UNLCK;
1129                                 vp = (struct vnode *)fp->f_data;
1130                                 (void) VOP_ADVLOCK(vp,
1131                                                    (caddr_t)p->p_leader,
1132                                                    F_UNLCK,
1133                                                    &lf,
1134                                                    F_POSIX);
1135                                 fdrop(fp, p);
1136                                 fpp = fdp->fd_ofiles + i;
1137                         }
1138                 }
1139         retry:
1140                 if (fdtol->fdl_refcount == 1) {
1141                         if (fdp->fd_holdleaderscount > 0 &&
1142                             (p->p_leader->p_flag & P_ADVLOCK) != 0) {
1143                                 /*
1144                                  * close() or do_dup() has cleared a reference
1145                                  * in a shared file descriptor table.
1146                                  */
1147                                 fdp->fd_holdleaderswakeup = 1;
1148                                 tsleep(&fdp->fd_holdleaderscount,
1149                                        PLOCK, "fdlhold", 0);
1150                                 goto retry;
1151                         }
1152                         if (fdtol->fdl_holdcount > 0) {
1153                                 /* 
1154                                  * Ensure that fdtol->fdl_leader
1155                                  * remains valid in closef().
1156                                  */
1157                                 fdtol->fdl_wakeup = 1;
1158                                 tsleep(fdtol, PLOCK, "fdlhold", 0);
1159                                 goto retry;
1160                         }
1161                 }
1162                 fdtol->fdl_refcount--;
1163                 if (fdtol->fdl_refcount == 0 &&
1164                     fdtol->fdl_holdcount == 0) {
1165                         fdtol->fdl_next->fdl_prev = fdtol->fdl_prev;
1166                         fdtol->fdl_prev->fdl_next = fdtol->fdl_next;
1167                 } else
1168                         fdtol = NULL;
1169                 p->p_fdtol = NULL;
1170                 if (fdtol != NULL)
1171                         FREE(fdtol, M_FILEDESC_TO_LEADER);
1172         }
1173         if (--fdp->fd_refcnt > 0)
1174                 return;
1175         /*
1176          * we are the last reference to the structure, we can
1177          * safely assume it will not change out from under us.
1178          */
1179         fpp = fdp->fd_ofiles;
1180         for (i = fdp->fd_lastfile; i-- >= 0; fpp++) {
1181                 if (*fpp)
1182                         (void) closef(*fpp, p);
1183         }
1184         if (fdp->fd_nfiles > NDFILE)
1185                 FREE(fdp->fd_ofiles, M_FILEDESC);
1186         if (fdp->fd_cdir)
1187                 vrele(fdp->fd_cdir);
1188         if (fdp->fd_rdir)
1189                 vrele(fdp->fd_rdir);
1190         if (fdp->fd_jdir)
1191                 vrele(fdp->fd_jdir);
1192         if (fdp->fd_knlist)
1193                 FREE(fdp->fd_knlist, M_KQUEUE);
1194         if (fdp->fd_knhash)
1195                 FREE(fdp->fd_knhash, M_KQUEUE);
1196         FREE(fdp, M_FILEDESC);
1197 }
1198
1199 /*
1200  * For setugid programs, we don't want to people to use that setugidness
1201  * to generate error messages which write to a file which otherwise would
1202  * otherwise be off-limits to the process.
1203  *
1204  * This is a gross hack to plug the hole.  A better solution would involve
1205  * a special vop or other form of generalized access control mechanism.  We
1206  * go ahead and just reject all procfs file systems accesses as dangerous.
1207  *
1208  * Since setugidsafety calls this only for fd 0, 1 and 2, this check is
1209  * sufficient.  We also don't for check setugidness since we know we are.
1210  */
1211 static int
1212 is_unsafe(struct file *fp)
1213 {
1214         if (fp->f_type == DTYPE_VNODE && 
1215             ((struct vnode *)(fp->f_data))->v_tag == VT_PROCFS)
1216                 return (1);
1217         return (0);
1218 }
1219
1220 /*
1221  * Make this setguid thing safe, if at all possible.
1222  */
1223 void
1224 setugidsafety(p)
1225         struct proc *p;
1226 {
1227         struct filedesc *fdp = p->p_fd;
1228         register int i;
1229
1230         /* Certain daemons might not have file descriptors. */
1231         if (fdp == NULL)
1232                 return;
1233
1234         /*
1235          * note: fdp->fd_ofiles may be reallocated out from under us while
1236          * we are blocked in a close.  Be careful!
1237          */
1238         for (i = 0; i <= fdp->fd_lastfile; i++) {
1239                 if (i > 2)
1240                         break;
1241                 if (fdp->fd_ofiles[i] && is_unsafe(fdp->fd_ofiles[i])) {
1242                         struct file *fp;
1243
1244 #if 0
1245                         if ((fdp->fd_ofileflags[i] & UF_MAPPED) != 0)
1246                                 (void) munmapfd(p, i);
1247 #endif
1248                         if (i < fdp->fd_knlistsize)
1249                                 knote_fdclose(p, i);
1250                         /*
1251                          * NULL-out descriptor prior to close to avoid
1252                          * a race while close blocks.
1253                          */
1254                         fp = fdp->fd_ofiles[i];
1255                         fdp->fd_ofiles[i] = NULL;
1256                         fdp->fd_ofileflags[i] = 0;
1257                         if (i < fdp->fd_freefile)
1258                                 fdp->fd_freefile = i;
1259                         (void) closef(fp, p);
1260                 }
1261         }
1262         while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL)
1263                 fdp->fd_lastfile--;
1264 }
1265
1266 /*
1267  * Close any files on exec?
1268  */
1269 void
1270 fdcloseexec(p)
1271         struct proc *p;
1272 {
1273         struct filedesc *fdp = p->p_fd;
1274         register int i;
1275
1276         /* Certain daemons might not have file descriptors. */
1277         if (fdp == NULL)
1278                 return;
1279
1280         /*
1281          * We cannot cache fd_ofiles or fd_ofileflags since operations
1282          * may block and rip them out from under us.
1283          */
1284         for (i = 0; i <= fdp->fd_lastfile; i++) {
1285                 if (fdp->fd_ofiles[i] != NULL &&
1286                     (fdp->fd_ofileflags[i] & UF_EXCLOSE)) {
1287                         struct file *fp;
1288
1289 #if 0
1290                         if (fdp->fd_ofileflags[i] & UF_MAPPED)
1291                                 (void) munmapfd(p, i);
1292 #endif
1293                         if (i < fdp->fd_knlistsize)
1294                                 knote_fdclose(p, i);
1295                         /*
1296                          * NULL-out descriptor prior to close to avoid
1297                          * a race while close blocks.
1298                          */
1299                         fp = fdp->fd_ofiles[i];
1300                         fdp->fd_ofiles[i] = NULL;
1301                         fdp->fd_ofileflags[i] = 0;
1302                         if (i < fdp->fd_freefile)
1303                                 fdp->fd_freefile = i;
1304                         (void) closef(fp, p);
1305                 }
1306         }
1307         while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL)
1308                 fdp->fd_lastfile--;
1309 }
1310
1311 /*
1312  * It is unsafe for set[ug]id processes to be started with file
1313  * descriptors 0..2 closed, as these descriptors are given implicit
1314  * significance in the Standard C library.  fdcheckstd() will create a
1315  * descriptor referencing /dev/null for each of stdin, stdout, and
1316  * stderr that is not already open.
1317  */
1318 int
1319 fdcheckstd(p)
1320        struct proc *p;
1321 {
1322        struct nameidata nd;
1323        struct filedesc *fdp;
1324        struct file *fp;
1325        register_t retval;
1326        int fd, i, error, flags, devnull;
1327
1328        fdp = p->p_fd;
1329        if (fdp == NULL)
1330                return (0);
1331        devnull = -1;
1332        error = 0;
1333        for (i = 0; i < 3; i++) {
1334                if (fdp->fd_ofiles[i] != NULL)
1335                        continue;
1336                if (devnull < 0) {
1337                        error = falloc(p, &fp, &fd);
1338                        if (error != 0)
1339                                break;
1340                        NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, "/dev/null",
1341                            p);
1342                        flags = FREAD | FWRITE;
1343                        error = vn_open(&nd, flags, 0);
1344                        if (error != 0) {
1345                                fdp->fd_ofiles[i] = NULL;
1346                                fdrop(fp, p);
1347                                break;
1348                        }
1349                        NDFREE(&nd, NDF_ONLY_PNBUF);
1350                        fp->f_data = (caddr_t)nd.ni_vp;
1351                        fp->f_flag = flags;
1352                        fp->f_ops = &vnops;
1353                        fp->f_type = DTYPE_VNODE;
1354                        VOP_UNLOCK(nd.ni_vp, 0, p);
1355                        devnull = fd;
1356                } else {
1357                        error = fdalloc(p, 0, &fd);
1358                        if (error != 0)
1359                                break;
1360                        error = do_dup(fdp, devnull, fd, &retval, p);
1361                        if (error != 0)
1362                                break;
1363                }
1364        }
1365        return (error);
1366 }
1367
1368 /*
1369  * Internal form of close.
1370  * Decrement reference count on file structure.
1371  * Note: p may be NULL when closing a file
1372  * that was being passed in a message.
1373  */
1374 int
1375 closef(fp, p)
1376         register struct file *fp;
1377         register struct proc *p;
1378 {
1379         struct vnode *vp;
1380         struct flock lf;
1381         struct filedesc_to_leader *fdtol;
1382
1383         if (fp == NULL)
1384                 return (0);
1385         /*
1386          * POSIX record locking dictates that any close releases ALL
1387          * locks owned by this process.  This is handled by setting
1388          * a flag in the unlock to free ONLY locks obeying POSIX
1389          * semantics, and not to free BSD-style file locks.
1390          * If the descriptor was in a message, POSIX-style locks
1391          * aren't passed with the descriptor.
1392          */
1393         if (p != NULL && 
1394             fp->f_type == DTYPE_VNODE) {
1395                 if ((p->p_leader->p_flag & P_ADVLOCK) != 0) {
1396                         lf.l_whence = SEEK_SET;
1397                         lf.l_start = 0;
1398                         lf.l_len = 0;
1399                         lf.l_type = F_UNLCK;
1400                         vp = (struct vnode *)fp->f_data;
1401                         (void) VOP_ADVLOCK(vp, (caddr_t)p->p_leader, F_UNLCK,
1402                                            &lf, F_POSIX);
1403                 }
1404                 fdtol = p->p_fdtol;
1405                 if (fdtol != NULL) {
1406                         /*
1407                          * Handle special case where file descriptor table
1408                          * is shared between multiple process leaders.
1409                          */
1410                         for (fdtol = fdtol->fdl_next;
1411                              fdtol != p->p_fdtol;
1412                              fdtol = fdtol->fdl_next) {
1413                                 if ((fdtol->fdl_leader->p_flag &
1414                                      P_ADVLOCK) == 0)
1415                                         continue;
1416                                 fdtol->fdl_holdcount++;
1417                                 lf.l_whence = SEEK_SET;
1418                                 lf.l_start = 0;
1419                                 lf.l_len = 0;
1420                                 lf.l_type = F_UNLCK;
1421                                 vp = (struct vnode *)fp->f_data;
1422                                 (void) VOP_ADVLOCK(vp,
1423                                                    (caddr_t)p->p_leader,
1424                                                    F_UNLCK, &lf, F_POSIX);
1425                                 fdtol->fdl_holdcount--;
1426                                 if (fdtol->fdl_holdcount == 0 &&
1427                                     fdtol->fdl_wakeup != 0) {
1428                                         fdtol->fdl_wakeup = 0;
1429                                         wakeup(fdtol);
1430                                 }
1431                         }
1432                 }
1433         }
1434         return (fdrop(fp, p));
1435 }
1436
1437 int
1438 fdrop(fp, p)
1439         struct file *fp;
1440         struct proc *p;
1441 {
1442         struct flock lf;
1443         struct vnode *vp;
1444         int error;
1445
1446         if (--fp->f_count > 0)
1447                 return (0);
1448         if (fp->f_count < 0)
1449                 panic("fdrop: count < 0");
1450         if ((fp->f_flag & FHASLOCK) && fp->f_type == DTYPE_VNODE) {
1451                 lf.l_whence = SEEK_SET;
1452                 lf.l_start = 0;
1453                 lf.l_len = 0;
1454                 lf.l_type = F_UNLCK;
1455                 vp = (struct vnode *)fp->f_data;
1456                 (void) VOP_ADVLOCK(vp, (caddr_t)fp, F_UNLCK, &lf, F_FLOCK);
1457         }
1458         if (fp->f_ops != &badfileops)
1459                 error = fo_close(fp, p);
1460         else
1461                 error = 0;
1462         ffree(fp);
1463         return (error);
1464 }
1465
1466 /*
1467  * Apply an advisory lock on a file descriptor.
1468  *
1469  * Just attempt to get a record lock of the requested type on
1470  * the entire file (l_whence = SEEK_SET, l_start = 0, l_len = 0).
1471  */
1472 #ifndef _SYS_SYSPROTO_H_
1473 struct flock_args {
1474         int     fd;
1475         int     how;
1476 };
1477 #endif
1478 /* ARGSUSED */
1479 int
1480 flock(p, uap)
1481         struct proc *p;
1482         register struct flock_args *uap;
1483 {
1484         register struct filedesc *fdp = p->p_fd;
1485         register struct file *fp;
1486         struct vnode *vp;
1487         struct flock lf;
1488
1489         if ((unsigned)uap->fd >= fdp->fd_nfiles ||
1490             (fp = fdp->fd_ofiles[uap->fd]) == NULL)
1491                 return (EBADF);
1492         if (fp->f_type != DTYPE_VNODE)
1493                 return (EOPNOTSUPP);
1494         vp = (struct vnode *)fp->f_data;
1495         lf.l_whence = SEEK_SET;
1496         lf.l_start = 0;
1497         lf.l_len = 0;
1498         if (uap->how & LOCK_UN) {
1499                 lf.l_type = F_UNLCK;
1500                 fp->f_flag &= ~FHASLOCK;
1501                 return (VOP_ADVLOCK(vp, (caddr_t)fp, F_UNLCK, &lf, F_FLOCK));
1502         }
1503         if (uap->how & LOCK_EX)
1504                 lf.l_type = F_WRLCK;
1505         else if (uap->how & LOCK_SH)
1506                 lf.l_type = F_RDLCK;
1507         else
1508                 return (EBADF);
1509         fp->f_flag |= FHASLOCK;
1510         if (uap->how & LOCK_NB)
1511                 return (VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, F_FLOCK));
1512         return (VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, F_FLOCK|F_WAIT));
1513 }
1514
1515 /*
1516  * File Descriptor pseudo-device driver (/dev/fd/).
1517  *
1518  * Opening minor device N dup()s the file (if any) connected to file
1519  * descriptor N belonging to the calling process.  Note that this driver
1520  * consists of only the ``open()'' routine, because all subsequent
1521  * references to this file will be direct to the other driver.
1522  */
1523 /* ARGSUSED */
1524 static int
1525 fdopen(dev, mode, type, p)
1526         dev_t dev;
1527         int mode, type;
1528         struct proc *p;
1529 {
1530
1531         /*
1532          * XXX Kludge: set curproc->p_dupfd to contain the value of the
1533          * the file descriptor being sought for duplication. The error
1534          * return ensures that the vnode for this device will be released
1535          * by vn_open. Open will detect this special error and take the
1536          * actions in dupfdopen below. Other callers of vn_open or VOP_OPEN
1537          * will simply report the error.
1538          */
1539         p->p_dupfd = minor(dev);
1540         return (ENODEV);
1541 }
1542
1543 /*
1544  * Duplicate the specified descriptor to a free descriptor.
1545  */
1546 int
1547 dupfdopen(p, fdp, indx, dfd, mode, error)
1548         struct proc *p;
1549         struct filedesc *fdp;
1550         int indx, dfd;
1551         int mode;
1552         int error;
1553 {
1554         register struct file *wfp;
1555         struct file *fp;
1556
1557         /*
1558          * If the to-be-dup'd fd number is greater than the allowed number
1559          * of file descriptors, or the fd to be dup'd has already been
1560          * closed, then reject.
1561          */
1562         if ((u_int)dfd >= fdp->fd_nfiles ||
1563             (wfp = fdp->fd_ofiles[dfd]) == NULL) {
1564                 return (EBADF);
1565         }
1566
1567         /*
1568          * There are two cases of interest here.
1569          *
1570          * For ENODEV simply dup (dfd) to file descriptor
1571          * (indx) and return.
1572          *
1573          * For ENXIO steal away the file structure from (dfd) and
1574          * store it in (indx).  (dfd) is effectively closed by
1575          * this operation.
1576          *
1577          * Any other error code is just returned.
1578          */
1579         switch (error) {
1580         case ENODEV:
1581                 /*
1582                  * Check that the mode the file is being opened for is a
1583                  * subset of the mode of the existing descriptor.
1584                  */
1585                 if (((mode & (FREAD|FWRITE)) | wfp->f_flag) != wfp->f_flag)
1586                         return (EACCES);
1587                 fp = fdp->fd_ofiles[indx];
1588 #if 0
1589                 if (fp && fdp->fd_ofileflags[indx] & UF_MAPPED)
1590                         (void) munmapfd(p, indx);
1591 #endif
1592                 fdp->fd_ofiles[indx] = wfp;
1593                 fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd];
1594                 fhold(wfp);
1595                 if (indx > fdp->fd_lastfile)
1596                         fdp->fd_lastfile = indx;
1597                 /*
1598                  * we now own the reference to fp that the ofiles[] array
1599                  * used to own.  Release it.
1600                  */
1601                 if (fp)
1602                         fdrop(fp, p);
1603                 return (0);
1604
1605         case ENXIO:
1606                 /*
1607                  * Steal away the file pointer from dfd, and stuff it into indx.
1608                  */
1609                 fp = fdp->fd_ofiles[indx];
1610 #if 0
1611                 if (fp && fdp->fd_ofileflags[indx] & UF_MAPPED)
1612                         (void) munmapfd(p, indx);
1613 #endif
1614                 fdp->fd_ofiles[indx] = fdp->fd_ofiles[dfd];
1615                 fdp->fd_ofiles[dfd] = NULL;
1616                 fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd];
1617                 fdp->fd_ofileflags[dfd] = 0;
1618
1619                 /*
1620                  * we now own the reference to fp that the ofiles[] array
1621                  * used to own.  Release it.
1622                  */
1623                 if (fp)
1624                         fdrop(fp, p);
1625                 /*
1626                  * Complete the clean up of the filedesc structure by
1627                  * recomputing the various hints.
1628                  */
1629                 if (indx > fdp->fd_lastfile) {
1630                         fdp->fd_lastfile = indx;
1631                 } else {
1632                         while (fdp->fd_lastfile > 0 &&
1633                            fdp->fd_ofiles[fdp->fd_lastfile] == NULL) {
1634                                 fdp->fd_lastfile--;
1635                         }
1636                         if (dfd < fdp->fd_freefile)
1637                                 fdp->fd_freefile = dfd;
1638                 }
1639                 return (0);
1640
1641         default:
1642                 return (error);
1643         }
1644         /* NOTREACHED */
1645 }
1646
1647
1648 struct filedesc_to_leader *
1649 filedesc_to_leader_alloc(struct filedesc_to_leader *old,
1650                          struct proc *leader)
1651 {
1652         struct filedesc_to_leader *fdtol;
1653         
1654         MALLOC(fdtol, struct filedesc_to_leader *,
1655                sizeof(struct filedesc_to_leader),
1656                M_FILEDESC_TO_LEADER,
1657                M_WAITOK);
1658         fdtol->fdl_refcount = 1;
1659         fdtol->fdl_holdcount = 0;
1660         fdtol->fdl_wakeup = 0;
1661         fdtol->fdl_leader = leader;
1662         if (old != NULL) {
1663                 fdtol->fdl_next = old->fdl_next;
1664                 fdtol->fdl_prev = old;
1665                 old->fdl_next = fdtol;
1666                 fdtol->fdl_next->fdl_prev = fdtol;
1667         } else {
1668                 fdtol->fdl_next = fdtol;
1669                 fdtol->fdl_prev = fdtol;
1670         }
1671         return fdtol;
1672 }
1673
1674 /*
1675  * Get file structures.
1676  */
1677 static int
1678 sysctl_kern_file(SYSCTL_HANDLER_ARGS)
1679 {
1680         int error;
1681         struct file *fp;
1682
1683         if (!req->oldptr) {
1684                 /*
1685                  * overestimate by 10 files
1686                  */
1687                 return (SYSCTL_OUT(req, 0, sizeof(filehead) + 
1688                                 (nfiles + 10) * sizeof(struct file)));
1689         }
1690
1691         error = SYSCTL_OUT(req, (caddr_t)&filehead, sizeof(filehead));
1692         if (error)
1693                 return (error);
1694
1695         /*
1696          * followed by an array of file structures
1697          */
1698         LIST_FOREACH(fp, &filehead, f_list) {
1699                 error = SYSCTL_OUT(req, (caddr_t)fp, sizeof (struct file));
1700                 if (error)
1701                         return (error);
1702         }
1703         return (0);
1704 }
1705
1706 SYSCTL_PROC(_kern, KERN_FILE, file, CTLTYPE_OPAQUE|CTLFLAG_RD,
1707     0, 0, sysctl_kern_file, "S,file", "Entire file table");
1708
1709 SYSCTL_INT(_kern, KERN_MAXFILESPERPROC, maxfilesperproc, CTLFLAG_RW, 
1710     &maxfilesperproc, 0, "Maximum files allowed open per process");
1711
1712 SYSCTL_INT(_kern, KERN_MAXFILES, maxfiles, CTLFLAG_RW, 
1713     &maxfiles, 0, "Maximum number of files");
1714
1715 SYSCTL_INT(_kern, OID_AUTO, openfiles, CTLFLAG_RD, 
1716         &nfiles, 0, "System-wide number of open files");
1717
1718 static void
1719 fildesc_drvinit(void *unused)
1720 {
1721         int fd;
1722
1723         for (fd = 0; fd < NUMFDESC; fd++)
1724                 make_dev(&fildesc_cdevsw, fd,
1725                     UID_BIN, GID_BIN, 0666, "fd/%d", fd);
1726         make_dev(&fildesc_cdevsw, 0, UID_ROOT, GID_WHEEL, 0666, "stdin");
1727         make_dev(&fildesc_cdevsw, 1, UID_ROOT, GID_WHEEL, 0666, "stdout");
1728         make_dev(&fildesc_cdevsw, 2, UID_ROOT, GID_WHEEL, 0666, "stderr");
1729 }
1730
1731 struct fileops badfileops = {
1732         badfo_readwrite,
1733         badfo_readwrite,
1734         badfo_ioctl,
1735         badfo_poll,
1736         badfo_kqfilter,
1737         badfo_stat,
1738         badfo_close
1739 };
1740
1741 static int
1742 badfo_readwrite(fp, uio, cred, flags, p)
1743         struct file *fp;
1744         struct uio *uio;
1745         struct ucred *cred;
1746         struct proc *p;
1747         int flags;
1748 {
1749
1750         return (EBADF);
1751 }
1752
1753 static int
1754 badfo_ioctl(fp, com, data, p)
1755         struct file *fp;
1756         u_long com;
1757         caddr_t data;
1758         struct proc *p;
1759 {
1760
1761         return (EBADF);
1762 }
1763
1764 static int
1765 badfo_poll(fp, events, cred, p)
1766         struct file *fp;
1767         int events;
1768         struct ucred *cred;
1769         struct proc *p;
1770 {
1771
1772         return (0);
1773 }
1774
1775 static int
1776 badfo_kqfilter(fp, kn)
1777         struct file *fp;
1778         struct knote *kn;
1779 {
1780
1781         return (0);
1782 }
1783
1784 static int
1785 badfo_stat(fp, sb, p)
1786         struct file *fp;
1787         struct stat *sb;
1788         struct proc *p;
1789 {
1790
1791         return (EBADF);
1792 }
1793
1794 static int
1795 badfo_close(fp, p)
1796         struct file *fp;
1797         struct proc *p;
1798 {
1799
1800         return (EBADF);
1801 }
1802
1803 SYSINIT(fildescdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,
1804                                         fildesc_drvinit,NULL)