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